status rpl_sim_init(){ //int i = 0; rpl_sim_read_sem = semcreate(0); rpl_sim_write_sem = semcreate(RPL_SIM_RECV_QUEUE_LEN); return OK; }
/*------------------------------------------------------------------------ * netiface_init - initialize the network interface data structures *------------------------------------------------------------------------ */ void netiface_init (void) { struct ifentry *ifptr = &if_tab[0]; /* ptr to interface table entry */ /* Initialize interface data structures */ ifptr->if_state = IF_DOWN; /* interface is down */ ifptr->if_ip6valid = FALSE; /* IP fields are invalid*/ /* radio address */ memcpy(ifptr->if_macucast, radiotab[0].radio_long_addr, 8); /* ULA prefix */ memcpy(ifptr->if_ip6prefix, ula_prefix, 16); /* Build global address from ULA prefix */ memcpy(ifptr->if_ip6ucast[0], ifptr->if_ip6prefix, 8); memcpy(&ifptr->if_ip6ucast[0][8], radiotab[0].radio_long_addr, 8); /* Build link-scoped address */ memcpy(ifptr->if_ip6ucast[1], ll_prefix, 8); memcpy(&ifptr->if_ip6ucast[1][8], radiotab[0].radio_long_addr, 8); /* No default router */ memcpy(ifptr->if_ip6router, unspec, 16); /* create the input buffer queue synchronization semaphore */ ifptr->if_isem = semcreate(0); /* no packets in buffer */ if (ifptr->if_isem == SYSERR) { panic("netiface_init: cannot create interface input queue semaphore"); } /* head and tail of queue are at 0 */ ifptr->if_ihead = ifptr->if_itail = 0; /* buffer holds a netpacket */ ifptr->if_ipool = mkbufpool(sizeof(struct netpacket), 3); /* create the buffer synchronization semaphore */ ifptr->if_osem = semcreate(0); /* no packets in buffer */ if (ifptr->if_osem == SYSERR) { panic("netiface_init: cannot create semaphore"); } /* head and tail of queue are at 0 */ ifptr->if_ohead = ifptr->if_otail = 0; /* buffer holds a netpacket */ ifptr->if_opool = mkbufpool(sizeof(struct netpacket), 3); /* Enable radio interface */ ifptr->if_state = IF_UP; ifptr->if_ip6valid = TRUE; return; }
/*------------------------------------------------------------------------ * main -- example of unsynchronized producer and consumer processes *------------------------------------------------------------------------ */ void producer_consumer(void) { int produced, consumed; consumed= semcreate(0); produced= semcreate(1); resume( create(consume, 1024, 20, "cons", 2, consumed, produced) ); resume( create(produce, 1024, 20, "prod", 2, consumed, produced) ); }
/** * Initialize UART control and status registers and buffers. * @param devptr pointer to a uart device */ devcall uartInit(device *devptr) { struct uart *uartptr; struct uart_csreg *regptr; /* Initialize structure pointers */ uartptr = &uarttab[devptr->minor]; uartptr->dev = devptr; uartptr->csr = devptr->csr; regptr = (struct uart_csreg *)uartptr->csr; /* Initialize statistical counts */ uartptr->cout = 0; uartptr->cin = 0; uartptr->lserr = 0; uartptr->ovrrn = 0; uartptr->iirq = 0; uartptr->oirq = 0; /* Initialize input buffer */ uartptr->isema = semcreate(0); uartptr->iflags = 0; uartptr->istart = 0; uartptr->icount = 0; /* Initialize output buffer */ uartptr->osema = semcreate(UART_OBLEN); uartptr->oflags = 0; uartptr->ostart = 0; uartptr->ocount = 0; uartptr->oidle = 1; /* Set baud rate */ regptr->lcr = UART_LCR_DLAB; /* Set Divisor Latch Access Bit */ regptr->dll = platform.uart_dll; /* Set Divisor Latch Low Byte */ regptr->dlm = 0x00; /* Set Divisor Latch High Byte */ regptr->lcr = UART_LCR_8N1; /* 8 bit, No Parity, 1 Stop */ regptr->fcr = 0x00; /* Disable FIFO for now */ /* OUT2 is used to control the board's interrupt tri-state */ /* buffer. It should be set high to generate interrupts properly. */ regptr->mcr = UART_MCR_OUT2; /* Turn on user-defined OUT2. */ /* Enable interrupts */ regptr->ier = UART_IER_ERBFI | UART_IER_ETBEI | UART_IER_ELSI; /* Enable UART FIFOs, clear and set interrupt trigger level */ regptr->fcr = UART_FCR_EFIFO | UART_FCR_RRESET | UART_FCR_TRESET | UART_FCR_TRIG2; /* Enable processor handling of UART interrupt requests */ interruptVector[devptr->irq] = devptr->intr; enable_irq(devptr->irq); return OK; }
/** * @ingroup telnet * * Associate TELNET with a hardware device. * @param devptr TELNET device table entry * @param ap 2nd argument is the device number for the hardware device * @return OK if TELNET is opened properly, otherwise SYSERR */ devcall telnetOpen(device *devptr, va_list ap) { struct telnet *tntptr = NULL; int dvnum = 0; irqmask im; im = disable(); /* Second arg should be device index for physical hardware */ dvnum = va_arg(ap, int); TELNET_TRACE("Open(%d) dvnum = %d", devptr->minor, dvnum); if (isbaddev(dvnum)) { restore(im); return SYSERR; } /* Setup pointer to telnet */ tntptr = &telnettab[devptr->minor]; /* Check if TELNET is already open */ if ((TELNET_STATE_FREE != tntptr->state) && (TELNET_STATE_ALLOC != tntptr->state)) { TELNET_TRACE("state = %d", tntptr->state); restore(im); return SYSERR; } tntptr->state = TELNET_STATE_OPEN; /* Initialize input buffer */ tntptr->istart = 0; tntptr->icount = 0; tntptr->idelim = FALSE; /* Initialize output buffer */ tntptr->ocount = 0; tntptr->ostart = 0; /* Initialize flags */ tntptr->flags = 0; tntptr->ieof = FALSE; tntptr->phw = (device *)&devtab[dvnum]; /* Initialize states and mutex semaphoress */ tntptr->echoState = TELNET_ECHO_SENT_WILL; tntptr->isem = semcreate(1); tntptr->osem = semcreate(1); /* Restore interrupts after making changes to telnet device structure */ restore(im); return OK; }
/** * Open an ethloop device. * @param devptr ethloop device table entry * @return OK if ethloop is opened properly, otherwise SYSERR */ devcall ethloopOpen(device *devptr) { struct ethloop *elpptr = NULL; irqmask im; elpptr = &elooptab[devptr->minor]; /* Check if ethloop is already open */ im = disable(); if (ELOOP_STATE_FREE != elpptr->state) { restore(im); return SYSERR; } elpptr->state = ELOOP_STATE_ALLOC; /* Link ethloop record with device table entry */ elpptr->dev = devptr; /* Clear flags and stats */ elpptr->flags = 0; elpptr->nout = 0; /* Create new semaphore */ elpptr->sem = semcreate(0); elpptr->hsem = semcreate(0); if ((SYSERR == (int)elpptr->sem) || (SYSERR == (int)elpptr->hsem)) { restore(im); return SYSERR; } /* Zero out the buffer */ bzero(elpptr->buffer, ELOOP_NBUF); bzero(elpptr->pktlen, ELOOP_NBUF); elpptr->index = 0; elpptr->hold = NULL; elpptr->holdlen = 0; elpptr->count = 0; /* Allocate a buffer pool */ elpptr->poolid = bfpalloc(ELOOP_BUFSIZE, ELOOP_NBUF); if (SYSERR == elpptr->poolid) { restore(im); return SYSERR; } restore(im); return OK; }
/*------------------------------------------------------------------------ * rfsInit - initialize the remote file system master device *------------------------------------------------------------------------ */ devcall rfsInit( struct dentry *devptr /* entry in device switch table */ ) { /* Choose an initial message sequence number */ Rf_data.rf_seq = 1; /* Set the server IP address, server port, and local port */ if ( dot2ip(RF_SERVER_IP, &Rf_data.rf_ser_ip) == SYSERR ) { panic("invalid IP address for remote file server"); } Rf_data.rf_ser_port = RF_SERVER_PORT; Rf_data.rf_loc_port = RF_LOC_PORT; /* Create a mutual exclusion semaphore */ if ( (Rf_data.rf_mutex = semcreate(1)) == SYSERR ) { panic("Cannot create remote file system semaphore"); } /* Specify that the server port is not yet registered */ Rf_data.rf_registered = FALSE; return OK; }
/*------------------------------------------------------------------------ * lflInit - initialize control blocks for local file pseudo-devices *------------------------------------------------------------------------ */ devcall lflInit ( struct dentry *devptr /* Entry in device switch table */ ) { struct lflcblk *lfptr; /* Ptr. to control block entry */ int32 i; /* Walks through name array */ lfptr = &lfltab[ devptr->dvminor ]; /* Initialize control block entry */ lfptr->lfstate = LF_FREE; /* Device is currently unused */ lfptr->lfdev = devptr->dvnum; /* Set device ID */ lfptr->lfmutex = semcreate(1); lfptr->lffilptr = LF_INULL; lfptr->lfpos = 0; for (i=0; i<LF_NAME_LEN; i++) { lfptr->lfname[i] = NULLCH; } lfptr->lfinum = LF_INULL; memset((char *) &lfptr->lfiblock, NULLCH, sizeof(struct lfiblk)); lfptr->lfdnum = 0; memset((char *) &lfptr->lfdblock, NULLCH, LF_BLKSIZ); lfptr->lfbyte = &lfptr->lfdblock[LF_BLKSIZ]; /* beyond lfdblock */ lfptr->lfibdirty = lfptr->lfdbdirty = FALSE; return OK; }
shellcmd xsh_prodconssync(int nargs, char *args[]) { int len=0,j,num=0,digit,k=1; int count = 2000; //local varible to hold count //Argument verifications and validations sid32 produced, consumed; consumed = semcreate(0); produced = semcreate(1); if(nargs==2){ if (strncmp(args[1], "--help", 7) == 0) { printf("Usage: %s <count>\n\n", args[0]); printf("Description:\n"); printf("\tRuns the producer-consumer problem for user-specified number of times. Default value is 2000\n"); printf("Options (one per invocation):\n"); printf("\t--help\tdisplay this help and exit\n"); return 0; } else { len=strlen(args[1]); for(j=len-1;j>=0;j--){ if(args[1][j]>='0'&&args[1][j]<='9'){ digit=args[1][j]-'0'; num=num+k*digit; k=k*10; } else { fprintf(stderr,"Invalid argument. Enter --help for more information\n"); return 0; } } count=num; } } if(nargs>2){ fprintf(stderr,"Too many arguments. Enter --help option for more information\n"); return 0; } //check args[1] if present assign value to count //create the process producer and consumer and put them in ready queue. //Look at the definations of function create and resume in exinu/system folder for reference. resume( create(prodsync, 1024, 20, "producer", 2,consumed,produced) ); resume( create(conssync, 1024, 20, "consumer", 2,consumed,produced) ); }
void net_init (void) { int32 nbufs; /* Total no of buffers */ /* Initialize the network data structure */ memset((char *)&NetData, NULLCH, sizeof(struct network)); /* Obtain the Ethernet MAC address */ control(ETHER0, ETH_CTRL_GET_MAC, (int32)NetData.ethucast, 0); memset((char *)NetData.ethbcast, 0xFF, ETH_ADDR_LEN); /* Initialize the random port seed */ netportseed = getticks(); /* Create the network buffer pool */ nbufs = UDP_SLOTS * UDP_QSIZ + ICMP_SLOTS * ICMP_QSIZ + 1; netbufpool = mkbufpool(PACKLEN, nbufs); /* Initialize the ARP cache */ arp_init(); /* Initialize UDP */ udp_init(); /* Initialize ICMP */ icmp_init(); /* Initialize the IP output queue */ ipoqueue.iqhead = 0; ipoqueue.iqtail = 0; ipoqueue.iqsem = semcreate(0); if((int32)ipoqueue.iqsem == SYSERR) { panic("Cannot create ip output queue semaphore"); return; } /* Create the IP output process */ resume(create(ipout, NETSTK, NETPRIO, "ipout", 0, NULL)); /* Create a network input process */ resume(create(netin, NETSTK, NETPRIO, "netin", 0, NULL)); }
void net_init (void) { int32 iface; /* index into interface table */ char str[16]; /* string to hold process name */ /* Initialize interface data structures */ netiface_init(); /* Initialize ARP cache for each interface */ for (iface=0; iface<NIFACES; iface++) { arp_init(iface); } /* Initialize UDP */ udp_init(); /* Initialize ICMP */ icmp_init(); /* Create a network input process for each interface */ for (iface=0; iface<NIFACES; iface++) { sprintf(str, "net%d_input", iface); resume(create(netin, 4196, 5000, str, 1, iface)); } /* Initialize the IP output queue */ ipoqueue.iqtail = ipoqueue.iqhead = 0; ipoqueue.iqsem = semcreate(0); /* Create an IP output process */ resume(create(ipout, 2048, 6000, "ip_output", 0)); /* Create a low-level input process that reads raw frames and */ /* demultiplexes them to the correct interface */ resume(create(rawin, 2048, 8000, "raw_input", 0)); }
shellcmd xsh_gen(int nargs, char *args[]) { pipid32 pip; pid32 rdpid,wrtpid; /* For argument '--help', emit help about the 'gen' command */ if (nargs == 2 && (strncmp(args[1], "--help", 7) == 0)) { printf("Use: %s\n\n", args[0]); printf("Description:\n"); printf("\tGenerates a word from wordlist and prints the count of words starting with vowel\n"); printf("Options:\n"); printf("\t | search\t it will print the number of words generated in 5 sec and count the number of words starting with vowels read from the pipe\n"); return 0; } if (nargs < 3) { fprintf(stderr, "%s: too few arguments\n", args[0]); fprintf(stderr, "Try '%s --help' for more information\n", args[0]); return 1; } else { if ((nargs == 3) && (strncmp(args[1], "|", 1) == 0) && (strncmp(args[2], "search", 6) == 0)) { //kprintf("correct usage \n\r"); if((pip = pipcreate()) == SYSERR) { kprintf("pipe creation unsuccessful \n\r"); return 0; } printsem = semcreate(1); rdpid = create(searchpipe, SHELL_CMDSTK, SHELL_CMDPRIO,"search", 2, pip, &printsem); wrtpid = getpid(); if(pipconnect(pip,wrtpid,rdpid) == SYSERR) { kprintf("pip connection failed \n\r"); return 0; } else { //kprintf("before resuming reader and writing\n\r"); resume(rdpid); writepip(pip); //resume(rdpid); kprintf("after writing\n\r"); } } } return 0; }
/** * @ingroup mailbox * * Initialize mailbox structures. * * @return * ::OK if all mailboxes were initialized successfully, otherwise ::SYSERR. */ syscall mailboxInit(void) { uint i; /* set all mailbox states to MAILBOX_FREE */ for (i = 0; i < NMAILBOX; i++) { mboxtab[i].state = MAILBOX_FREE; } mboxtabsem = semcreate(1); if (SYSERR == mboxtabsem) { pi_printf("error: fail to mailbox Init\r\n"); return SYSERR; } return OK; }
/** * Initialize virtual ethernet device structures. * @param devptr TTY device table entry * @return OK if device is intialized successfully */ devcall vlanInit(device *devptr) { struct ether *ethptr; /* Initialize structure pointers */ ethptr = ðertab[devptr->minor]; bzero(ethptr, sizeof(struct ether)); ethptr->dev = devptr; ethptr->csr = (struct bcm4713 *)devptr->csr; /* Physical ethernet device to which the VLAN attaches */ ethptr->phy = (device *)&devtab[ETH0]; ethptr->errors = 0; ethptr->state = ETH_STATE_DOWN; ethptr->rxRingSize = ETH_RX_RING_ENTRIES; ethptr->txRingSize = ETH_TX_RING_ENTRIES; ethptr->mtu = ETH_MTU; ethptr->isema = semcreate(0); ethptr->istart = 0; ethptr->icount = 0; ethptr->ovrrun = 0; ethptr->rxOffset = sizeof(struct rxHeader); /* Lookup MAC in NVRAM, and store it in ether dev struct. */ /* Modify first octet with device minor and set local admin bit */ colon2mac(nvramGet("et0macaddr"), ethptr->devAddress); ethptr->devAddress[0] |= ((uchar)devptr->minor << 2) | ETH_LOCAL_MAC; ethptr->interruptMask = IMASK_DEF; /* As there is only one DMA ring for the physical ethernet, and * none for virtual interfaces, certain values in the ether struct * are set to invalid */ ethptr->rxBufs = (struct ethPktBuffer **)ETH_INVALID; ethptr->txBufs = (struct ethPktBuffer **)ETH_INVALID; ethptr->rxRing = (struct dmaDescriptor *)ETH_INVALID; ethptr->txRing = (struct dmaDescriptor *)ETH_INVALID; return OK; }
future *future_alloc(int future_flags) { future *f = (future*) memget(sizeof(future)); if (f == (void*)SYSERR) { return NULL; } f->value = NULL; f->flag = future_flags; f->state = FUTURE_EMPTY; f->tid = -1; /* initially we're allowing threads to read and write `state` field */ f->s = semcreate(1); /* initially queues are empty */ f->set_queue = queinit(); f->get_queue = queinit(); return f; }
/*------------------------------------------------------------------------ * lfsInit -- initialize the local file system master device *------------------------------------------------------------------------ */ devcall lfsInit ( struct dentry *devptr /* entry in device switch table */ ) { /* Assign ID of disk device that will be used */ Lf_data.lf_dskdev = LF_DISK_DEV; /* Create a mutual exclusion semaphore */ Lf_data.lf_mutex = semcreate(1); /* Zero directory area (for debugging) */ memset((char *)&Lf_data.lf_dir, NULLCH, sizeof(struct lfdir)); /* Initialize directory to "not present" in memory */ Lf_data.lf_dirpresent = Lf_data.lf_dirdirty = FALSE; return OK; }
/** * Initialized the flash device located beginning at the value of * this devices CSR. * @param *devptr pointer to device entry * @return OK on success, SYSERR on failure */ devcall flashInit(device *devptr) { struct flash *flash; struct flash_region r; uchar n; ulong position; flash = &flashtab[devptr->minor]; bzero((void *)flash, sizeof(struct flash)); flash->device = devptr; flash->base = (ulong)devptr->csr; flash->lock = semcreate(1); /* Change to CFI query mode */ CFI_PUT_8(flash->base, CFI_QUERY_ADDR, CFI_QUERY_MODE); /* XINU only supports valid CFI devices */ if (!(CFI_GET_8(flash->base, CFI_SIGNATURE + 0) == 'Q' && CFI_GET_8(flash->base, CFI_SIGNATURE + 1) == 'R' && CFI_GET_8(flash->base, CFI_SIGNATURE + 2) == 'Y')) { /* Not a CFI flash device, it may still be flash */ /* but XINU will not support those */ CFI_PUT_8(flash->base, CFI_QUERY_ADDR, CFI_QUERY_EXIT); return SYSERR; } /* We know it is a valid CFI device, now get some data */ /* what command set does it use */ flash->commands = CFI_GET_8(flash->base, CFI_COMMAND_SET); /* XINU might support both Intel and AMD's Standard Command Set */ if (!(flash->commands == FLASH_INTEL_SCS || flash->commands == FLASH_AMD_SCS)) { return SYSERR; } /* total device size (2^n) */ flash->size = 1 << CFI_GET_8(flash->base, CFI_DEV_SIZE); /* number of erase-block regions */ flash->nregions = CFI_GET_8(flash->base, CFI_REGION_COUNT); if (flash->nregions >= MAX_REGIONS) { return SYSERR; } /* get information about each region */ position = 0; for (n = 0; n < flash->nregions; n++) { r = flash->regions[n]; /* find the offset in flash */ r.region_start = position; /* number of erase-blocks in region */ r.nblocks = 1 + CFI_GET_8(flash->base, CFI_REGION_TAB + n * 4 + 0) + (CFI_GET_8(flash->base, CFI_REGION_TAB + n * 4 + 1) << 8); /* size of erase-blocks within region */ r.block_size = (CFI_GET_8(flash->base, CFI_REGION_TAB + n * 4 + 2) + (CFI_GET_8 (flash->base, CFI_REGION_TAB + n * 4 + 3) << 8)); r.block_size *= 256; /* store the size of this region */ r.region_size = r.nblocks * r.block_size; /* iterate for the position of the next region */ position += r.region_size; /* store the updated region in struct flash */ flash->regions[n] = r; } /* Dumb check to make sure all regions are counted */ if (position != flash->size) { return SYSERR; } /* Set the size of logical blocks for this disk */ flash->log_size = FLASH_BLK_SIZE; /* Determine how many logical blocks exist */ flash->nlog_blocks = flash->size / flash->log_size; /* Return to read mode */ CFI_PUT_8(flash->base, CFI_QUERY_ADDR, CFI_QUERY_EXIT); flash->mode = INTEL_READ; #ifdef DETAIL kprintf("Found CFI (Flash) device at 0x%08x\r\n", flash->base); kprintf(" Using 0x%04x command set\r\n", flash->commands); kprintf(" Size: %d bytes (split into %d blocks of %d bytes)\r\n", flash->size, flash->nlog_blocks, flash->log_size); kprintf(" Physically split into %d erase-regions\r\n", flash->nregions); for (n = 0; n < flash->nregions; n++) { r = flash->regions[n]; kprintf(" Region %d at offset 0x%08x\r\n", n, r.region_start); kprintf(" %d blocks of %d bytes, totaling %d bytes\r\n", r.nblocks, r.block_size, r.region_size); } kprintf("\n"); #endif return OK; }
thread test_semaphore3(bool verbose) { #if NSEM tid_typ atid, btid; bool passed = TRUE; semaphore s; uchar testResult = 0; char msg[50]; testPrint(verbose, "Semaphore creation: "); s = semcreate(1); if (isbadsem(s)) { passed = FALSE; sprintf(msg, "%d", s); testFail(verbose, msg); } else if (test_checkSemCount(s, 1)) { testPass(verbose, ""); } else { passed = FALSE; } /* We use a higher priority for thread A to ensure it is not rescheduled to * thread B before it is even able to wait on the semaphore. */ ready(atid = create((void *)test_semWaiter, INITSTK, 32, "SEMAPHORE-A", 3, s, 1, &testResult), RESCHED_NO); ready(btid = create((void *)test_semWaiter, INITSTK, 31, "SEMAPHORE-B", 3, s, 1, &testResult), RESCHED_YES); testPrint(verbose, "Wait on semaphore: "); /* Process A should be admitted, but B should wait. */ if (test_checkProcState(atid, THRFREE) && test_checkProcState(btid, THRWAIT) && test_checkSemCount(s, -1) && test_checkResult(testResult, 1)) { testPass(verbose, ""); } else { passed = FALSE; } signal(s); /* Process B waited, so signal should release it. */ testPrint(verbose, "Signal waiting semaphore: "); if (test_checkProcState(btid, THRFREE) && test_checkSemCount(s, 0) && test_checkResult(testResult, 2)) { testPass(verbose, ""); } else { passed = FALSE; } if (TRUE == passed) { testPass(TRUE, ""); } else { testFail(TRUE, ""); } /* Processes should be dead, but in case the test failed. */ kill(atid); kill(btid); semfree(s); #else /* NSEM */ testSkip(TRUE, ""); #endif /* NSEM == 0 */ return OK; }
/*------------------------------------------------------------------------ * rdsinit - Initialize the remote disk system device *------------------------------------------------------------------------ */ devcall rdsinit ( struct dentry *devptr /* Entry in device switch table */ ) { struct rdscblk *rdptr; /* Ptr to device contol block */ struct rdbuff *bptr; /* Ptr to buffer in memory */ /* used to form linked list */ struct rdbuff *pptr; /* Ptr to previous buff on list */ struct rdbuff *buffend; /* Last address in buffer memory*/ uint32 size; /* Total size of memory needed */ /* buffers */ /* Obtain address of control block */ rdptr = &rdstab[devptr->dvminor]; /* Set control block to unused */ rdptr->rd_state = RD_FREE; rdptr->rd_id[0] = NULLCH; /* Set initial message sequence number */ rdptr->rd_seq = 1; /* Initialize request queue and cache to empty */ rdptr->rd_rhnext = (struct rdbuff *) &rdptr->rd_rtnext; rdptr->rd_rhprev = (struct rdbuff *)NULL; rdptr->rd_rtnext = (struct rdbuff *)NULL; rdptr->rd_rtprev = (struct rdbuff *) &rdptr->rd_rhnext; rdptr->rd_chnext = (struct rdbuff *) &rdptr->rd_ctnext; rdptr->rd_chprev = (struct rdbuff *)NULL; rdptr->rd_ctnext = (struct rdbuff *)NULL; rdptr->rd_ctprev = (struct rdbuff *) &rdptr->rd_chnext; /* Allocate memory for a set of buffers (actually request */ /* blocks and link them to form the initial free list */ size = sizeof(struct rdbuff) * RD_BUFFS; bptr = (struct rdbuff *)getmem(size); rdptr->rd_free = bptr; if ((int32)bptr == SYSERR) { panic("Cannot allocate memory for remote disk buffers"); } buffend = (struct rdbuff *) ((char *)bptr + size); while (bptr < buffend) { /* walk through memory */ pptr = bptr; bptr = (struct rdbuff *) (sizeof(struct rdbuff)+ (char *)bptr); pptr->rd_status = RD_INVALID; /* Buffer is empty */ pptr->rd_next = bptr; /* Point to next buffer */ } pptr->rd_next = (struct rdbuff *) NULL; /* Last buffer on list */ /* Create the request list and available buffer semaphores */ rdptr->rd_availsem = semcreate(RD_BUFFS); rdptr->rd_reqsem = semcreate(0); /* Set the server IP address, server port, and local port */ if ( dot2ip(RD_SERVER_IP, &rdptr->rd_ser_ip) == SYSERR ) { panic("invalid IP address for remote disk server"); } /* Set the port numbers */ rdptr->rd_ser_port = RD_SERVER_PORT; rdptr->rd_loc_port = RD_LOC_PORT + devptr->dvminor; /* Specify that the server port is not yet registered */ rdptr->rd_registered = FALSE; /* Create a communication process */ rdptr->rd_comproc = -1; /* rdptr->rd_comproc = create(rdsprocess, RD_STACK, RD_PRIO, "rdsproc", 1, rdptr); if (rdptr->rd_comproc == SYSERR) { panic("Cannot create remote disk process"); } resume(rdptr->rd_comproc); */ return OK; }
process test_semaphore(bool8 verbose) { pid32 apid; bool8 passed = TRUE; sid32 s; byte testResult = 0; char msg[50]; /* Single semaphore tests */ testPrint(verbose, "Semaphore creation: "); s = semcreate(0); if (isbadsem(s)) { passed = FALSE; sprintf(msg, "%d", s); testFail(verbose, msg); } else if (test_checkSemCount(s, 0, verbose)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Wait on semaphore: "); if ((SYSERR != resume(apid = create((void *)test_semWaiter, INITSTK, 31, "SEMAPHORE-A", 3, s, 1, &testResult))) && test_checkProcState(apid, PR_WAIT, verbose) && test_checkSemCount(s, -1, verbose) && test_checkResult(testResult, 0, verbose)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signal semaphore: "); if ((OK == signal(s)) && test_checkProcState(apid, PR_FREE, verbose) && test_checkSemCount(s, 0, verbose) && test_checkResult(testResult, 1, verbose)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signaln semaphore (valid count): "); if ((OK == signaln(s, 5)) && test_checkProcState(apid, PR_FREE, verbose) && test_checkSemCount(s, 5, verbose) && test_checkResult(testResult, 1, verbose)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signaln semaphore (invalid count): "); if (SYSERR == signaln(s, -5)) { testPass(verbose, ""); } else { passed = FALSE; } /* Free semaphore, single semaphore tests */ testPrint(verbose, "Delete valid semaphore: "); if ((OK == semdelete(s)) && (semtab[s].sstate == S_FREE) && isempty(semtab[s].squeue)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Delete invalid semaphore: "); if (SYSERR == semdelete(-1)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Delete free semaphore: "); if (SYSERR == semdelete(s)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signal bad semaphore id: "); if (SYSERR == signal(-1)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signal free semaphore: "); if (SYSERR == signal(s)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signaln bad semaphore id: "); if (SYSERR == signaln(-1, 4)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Signaln free semaphore: "); if (SYSERR == signaln(s, 4)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Wait on bad semaphore id: "); if (SYSERR == wait(-1)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Wait on free semaphore: "); if (SYSERR == wait(s)) { testPass(verbose, ""); } else { passed = FALSE; } /* Process A should be dead, but in case the test failed. */ kill(apid); /* General semaphore pass/fail */ if (TRUE == passed) { testPass(TRUE, ""); } else { testFail(TRUE, ""); } return OK; }
process test_semaphore5(bool8 verbose) { pid32 atid; bool8 passed = TRUE; sid32 s; byte testResult = 0; char msg[50]; testPrint(verbose, "Semaphore creation: "); s = semcreate(0); if (isbadsem(s)) { passed = FALSE; sprintf(msg, "%d", s); testFail(verbose, msg); } else if (test_checkSemCount(s, 0)) { testPass(verbose, ""); } else { passed = FALSE; } ready(atid = create((void *)test_semWaiter, INITSTK, getprio(getpid()) + 10, "SEMAPHORE-A", 3, s, 1, &testResult), RESCHED_YES); testPrint(verbose, "Wait on semaphore: "); if (test_checkProcState(atid, PR_WAIT) && test_checkSemCount(s, -1) && test_checkResult(testResult, 0)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Reset semaphore: "); if ((OK == semreset(s, 0)) && test_checkProcState(atid, PR_FREE) && test_checkSemCount(s, 0) && test_checkResult(testResult, 1)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Reset semaphore (invalid count): "); if (SYSERR == semreset(s, -5)) { testPass(verbose, ""); } else { passed = FALSE; } testPrint(verbose, "Reset invalid semaphore: "); if (SYSERR == semreset(-1, 0)) { testPass(verbose, ""); } else { passed = FALSE; } semdelete(s); testPrint(verbose, "Reset free semaphore: "); if (SYSERR == semreset(s, 0)) { testPass(verbose, ""); } else { passed = FALSE; } if (TRUE == passed) { testPass(TRUE, ""); } else { testFail(TRUE, ""); } return OK; }
/*------------------------------------------------------------------------ * sdmcopen - open an SD memory card *------------------------------------------------------------------------ */ devcall sdmcopen ( struct dentry *devptr, /* entry in device switch table */ char *name, /* name to open */ char *mode /* mode argument */ ) { volatile struct sdmc_csreg *csrptr; /* address of SD controller's CSR */ struct sdmcblk *sdmcptr; /* Pointer to sdmctab entry */ uint16 error_sts = 0; /* SDMC command error status */ uint32 cmd_arg = 0; /* Value of argument register */ byte first_ACMD41 = 1; /* Set for the first ACMD41 */ /* Initialize structure pointers */ sdmcptr = &sdmctab[devptr->dvminor]; csrptr = (struct sdmc_csreg *) devptr->dvcsr; /* Initialize card identifiers */ sdmcptr->rca = 0; memset(sdmcptr->cid, 0x00, sizeof(sdmcptr->cid)); sdmcptr->cmd8 = 1; /* assume card supports CMD8 */ sdmcptr->sdio = 0; /* assume not an SDIO card */ /* Set the clock speed */ sdmc_set_clock(csrptr); /* Set the bus voltage */ sdmc_set_bus_power(csrptr); /* Set the data line timeout value */ sdmc_set_dat_timeout(csrptr); /* Issue card reset command (CMD0) */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD0, 0x00000000, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD0: %04X %04X\n", SDMC_CMD0, error_sts); return SYSERR; } /* Issue voltage check command (CMD8) */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD8, 0x000001AA, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD8: %04X %04X\n", SDMC_CMD8, error_sts); return SYSERR; } /* Error in CMD8 - card must not support it */ if(error_sts & SDMC_ERR_INT_CMD_TIMEOUT_ERR || csrptr->response0 != 0x000001AA) { sdmcptr->cmd8 = 0; } /* Issue inquiry voltage state (ACMD41) */ /* To send an application command (ACMD) a CMD55 must first be sent */ /* to tell the controller to expect an application command */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD55, 0x00000000, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD55: %04X %04X\n", SDMC_CMD55, error_sts); return SYSERR; } if(sdmc_issue_cmd_sync(csrptr, SDMC_ACMD41, 0x40FF8000, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in ACMD41: %04X %04X\n", SDMC_ACMD41, error_sts); return SYSERR; } /* Issue initialize card command (ACMD41) */ cmd_arg = SDMC_OCR_MASK & csrptr->response0; /* Set OCR */ if(csrptr->response0 & SDMC_R3_S18A) { /* Set switch to 1.8V if card supports */ cmd_arg |= SDMC_ACMD41_S18R; } cmd_arg |= SDMC_ACMD41_XPC | SDMC_ACMD41_HCS; /* Set high capacity support */ /* and extended performance control */ /* The card initialization command (ACMD41) must be continuously sent until */ /* unitialization has completed */ do { if(!first_ACMD41) { DELAY(SDMC_CMD_DELAY); } /* To send an application command (ACMD) a CMD55 must first be sent */ /* to tell the controller to expect an application command */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD55, 0x00000000, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD55: %04X %04X\n", SDMC_CMD55, error_sts); return SYSERR; } /* Send the card initialization command */ if(sdmc_issue_cmd_sync(csrptr, SDMC_ACMD41, cmd_arg, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in ACMD41: %04X %04X\n", SDMC_ACMD41, error_sts); return SYSERR; } first_ACMD41 = 0; } while(!(csrptr->response0 & SDMC_R3_BUSY)); /* TODO run voltage switch procedure if the card supports 1.8V signaling */ /* Retrieve the card's card identifier (CID) */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD2, 0, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD2: %04X %04X\n", SDMC_CMD2, error_sts); return SYSERR; } memcpy(sdmcptr->cid, (char*)&csrptr->response0, 16); /* Retrieve the card's relative card address (RCA) */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD3, 0, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD3: %04X %04X\n", SDMC_CMD3, error_sts); return SYSERR; } sdmcptr->rca = csrptr->response0 & SDMC_R6_RCA_MASK; /* Retrieve the card specific data (CSD) */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD9, sdmcptr->rca, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD9: %04X %04X\n", SDMC_CMD9, error_sts); return SYSERR; } /* Select the card */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD7, sdmcptr->rca, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD7: %04X %04X\n", SDMC_CMD7, error_sts); return SYSERR; } if(csrptr->response0 & SDMC_R1_ANY_ERROR) { kprintf("[SDMC] Error in CMD7 response: %04X %04X\n", SDMC_CMD7, csrptr->response0); return SYSERR; } /* Set the block size */ uint32 block_size_to_set = SDMC_BLK_SIZE; if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD16, block_size_to_set, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD16: %04X %04X\n", SDMC_CMD16, error_sts); return SYSERR; } if(csrptr->response0 & SDMC_R1_ANY_ERROR) { kprintf("[SDMC] Error in CMD16 response: %04X %04X\n", SDMC_CMD16, csrptr->response0); return SYSERR; } csrptr->blk_size = SDMC_BLK_SIZE; /* To send an application command (ACMD) a CMD55 must first be sent */ /* to tell the controller to expect an application command */ if(sdmc_issue_cmd_sync(csrptr, SDMC_CMD55, sdmcptr->rca, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in CMD55: %04X %04X\n", SDMC_CMD55, error_sts); return SYSERR; } /* Set the bus width */ if(sdmc_issue_cmd_sync(csrptr, SDMC_ACMD6, 2, &error_sts, SDMC_CMD_NO_FLAGS) != SDMC_RC_OK) { kprintf("[SDMC] Error in ACMD6: %04X %04X\n", SDMC_ACMD6, error_sts); return SYSERR; } csrptr->host_ctl |= SDMC_HOST_DAT_TX_4BIT; sdmcptr->cmd_sem = semcreate(0); if((int)sdmcptr->cmd_sem == SYSERR) { return SYSERR; } return devptr->dvnum; }
/** * Associate a UDP socket with a hardware device. * @param devptr UDP device table entry * @param ap 2nd argument is the local IP address * 3rd argument is the remote IP address * 4th argument is the local port (auto-assigned if zero) * 5th argument is the remote port * @return OK if UDP is opened properly, otherwise SYSERR */ devcall udpOpen(device *devptr, va_list ap) { struct udp *udpptr = NULL; ushort localpt = 0; ushort remotept = 0; struct netaddr *localip = NULL; struct netaddr *remoteip = NULL; irqmask im; udpptr = &udptab[devptr->minor]; im = disable(); /* Check if UDP is already open */ if (UDP_OPEN == udpptr->state) { UDP_TRACE("udp%d has already been opened.", devptr->minor); restore(im); return SYSERR; } udpptr->state = UDP_OPEN; udpptr->dev = devptr; /* Initialize incoming packet buffer */ udpptr->icount = 0; udpptr->istart = 0; /* Initialize the semaphore */ udpptr->isem = semcreate(0); /* Parse arguments */ localip = va_arg(ap, struct netaddr *); remoteip = va_arg(ap, struct netaddr *); localpt = va_arg(ap, int); remotept = va_arg(ap, int); /* Allocate a local port if none is specified */ if (NULL == localpt) { localpt = allocPort(); } /* Set remote port to 0 if none is specified */ if (NULL == remotept) { remotept = 0; } /* Local IP is required */ if (NULL == localip) { restore(im); return SYSERR; } if (NULL == remoteip) { bzero(&(udpptr->remoteip), sizeof(struct netaddr)); } /* Initialize ports and addresses */ udpptr->localpt = (ushort)localpt; udpptr->remotept = (ushort)remotept; if (NULL != localip) { netaddrcpy(&(udpptr->localip), localip); } if (NULL != remoteip) { netaddrcpy(&(udpptr->remoteip), remoteip); } /* Allocate received UDP packet buffer pool */ udpptr->inPool = bfpalloc(NET_MAX_PKTLEN, UDP_MAX_PKTS); UDP_TRACE("udp%d inPool has been assigned pool ID %d.\r\n", devptr->minor, udpptr->inPool); udpptr->flags = 0; restore(im); return OK; }
int main(int argc, char * argv[]) { int idblocom; //Identificador do Bloco de memória int fifod; //fifo file descriptor pthread_t tidSecr, tidReS; pthread_t *tidMec, *tidEle, *tidCha, *tidPin; int duracao,nMec, nEle, nCha, nPin; int i; Qmec = CreateQueue(15); // queue mecanico Qele = CreateQueue(15); // queue electricista Qcha = CreateQueue(15); // queue chapeiro Qpin = CreateQueue(15); // queue pintor Qdone = CreateQueue(15); //queue final if(argc!=6){ // verificação do input printf("\nUso: %s [TempodeFuncionamento] [nrMecanicos] [nrElectricistas] [nrChapeiros] [nrPintores]\n", argv[0]); return -1; } // guarda os argumentos do programa duracao = atoi(argv[1]); nMec = atoi(argv[2]); nEle = atoi(argv[3]); nCha = atoi(argv[4]); nPin = atoi(argv[5]); //abertura/Criação do ficheiro registos.dat if((registos = fopen(REGISTO, "wt"))==NULL){ printf("Failled to create file: registos.dat .\n"); return 1; } pthread_mutex_lock(&mutexRegis); regista(CHEFE, NULL, "Abriu a Oficina"); pthread_mutex_unlock(&mutexRegis); //Criação do FIFO if(mkfifo(FIFO, 0660)!=0){ perror(FIFO); } else fprintf(registos, "FIFO Criado\n"); //Alocar memoria if((idblocom = aloca_mem(argv[0]))==1){ return 1; } //Criar o Semaforo com key SEMKEY semid=semcreate(SEMKEY,0); if (semid==-1) { printf("Chefe: Erro na criacao do semaforo c/key = %d\n",SEMKEY); exit(1); } // Inicia o funcionamento da oficina!! work = 1; if(pthread_create(&tidSecr,NULL, recepcionista_C, (void *) &fifod)!=0){ perror("Recepcionista C"); } tidMec = (pthread_t *)calloc(nMec, sizeof(pthread_t)); for(i=0; i<nMec; i++){ //Multi-thread if(pthread_create(&tidMec[i],NULL, mecanico, (void*)(i+1))!=0){ perror("Mecanico"); } } tidEle = (pthread_t *)calloc(nEle, sizeof(pthread_t)); for(i=0; i<nEle; i++){ //Multi-thread if(pthread_create(&tidEle[i],NULL, electricista, (void*)(i+1))!=0){ perror("Electricista"); } } tidCha = (pthread_t *)calloc(nCha, sizeof(pthread_t)); for(i=0; i<nCha; i++){ //Multi-thread if(pthread_create(&tidCha[i],NULL, chapeiro, (void*)(i+1))!=0){ perror("Chapeiro"); } } tidPin = (pthread_t *)calloc(nPin, sizeof(pthread_t)); for(i=0; i<nPin; i++){ //Multi-thread if(pthread_create(&tidPin[i],NULL, pintor, (void*)(i+1))!=0){ perror("Pintor"); } } if(pthread_create(&tidReS,NULL, recepcionista_S,NULL)!=0){ perror("Recepcionista S"); } //O chefe pos a malta a trabalhar e agora vai tirar uma sesta... pthread_mutex_lock(&mutexRegis); regista(CHEFE, NULL, "Agora vou trabalhar... bem, dormir..."); pthread_mutex_unlock(&mutexRegis); sleep(duracao); pthread_mutex_lock(&mutexRegis); regista(CHEFE,NULL, "Dei sinal para fechar a oficina! Bam'bora!"); pthread_mutex_unlock(&mutexRegis); work = 2; //printf("CHEFE: Dei sinal de terminar\n"); sleep(60); // aguarda 60 unidades de tempo feito = 1; // encerra o funcionamento // aguarda que os threads terminem pthread_join(tidSecr,NULL); pthread_join(tidReS,NULL); for(i=0; i<nMec; i++) { pthread_join(tidMec[i],NULL); } for(i=0; i<nEle; i++) { pthread_join(tidEle[i],NULL); } for(i=0; i<nCha; i++) { pthread_join(tidCha[i],NULL); } for(i=0; i<nPin; i++) { pthread_join(tidPin[i],NULL); } //desalocar a memoria if(desaloca_mem(idblocom) ==1){ return 1; } else{ pthread_mutex_lock(&mutexRegis); regista(CHEFE, NULL, "Parque fechado"); pthread_mutex_unlock(&mutexRegis); } //elimina as filas //printf("Dispose of the queue...\n"); DisposeQueue(Qmec); DisposeQueue(Qele); DisposeQueue(Qcha); DisposeQueue(Qpin); DisposeQueue(Qdone); //destroi os mutexes //printf("Destruir os mutexes\n"); pthread_mutex_destroy(&mutexRegis); pthread_mutex_destroy(&mutexMec); pthread_mutex_destroy(&mutexEle); pthread_mutex_destroy(&mutexCha); pthread_mutex_destroy(&mutexPin); pthread_mutex_destroy(&mutexDone); //Destroi o semaforo //printf("Destruir o Semaforo\n"); semremove(semid); unlink(FIFO); return 1; //adeus e boa viagem! }
/*------------------------------------------------------------------------ * i8255x_open - allocate resources and prepare hardware for transmit and * receive *------------------------------------------------------------------------ */ status i8255x_open( struct ether *ethptr ) { struct i82559_tx_desc* txRingptr; struct i82559_rx_desc* rxRingptr; int32 i; // uint32 bufptr; /* Initialize structure pointers */ ethptr->rxRingSize = I8255X_RX_RING_SIZE; ethptr->txRingSize = I8255X_TX_RING_SIZE; ethptr->isem = semcreate(0); ethptr->osem = semcreate(ethptr->txRingSize); /* * Rings must be aligned on a 4-byte boundary for I82559 * Only Simplified Frame descriptors can be used, as that is the only one supported. * */ ethptr->stats = getmem(I82559_DUMP_STATS_SIZE + 4); /*4 extra bytes assigned to make sure the address is dword alligned*/ ethptr->rxRing = (void *)getmem((ethptr->rxRingSize + 1) * ( I82559_RFDSIZE + ETH_BUF_SIZE ) ); ethptr->txRing = (void *)getmem((ethptr->txRingSize + 1) * ( I82559_TFDSIZE + ETH_BUF_SIZE )); if ( (SYSERR == (uint32)ethptr->rxRing) || (SYSERR == (uint32)ethptr->txRing) || SYSERR == (uint32) ethptr->stats ) { //kprintf("i8255x_open: fail to allocate tx/rx Bufs\n\r"); return SYSERR; } /*16-byte allignment. Not needed, but to be on safe side*/ ethptr->rxRing = (void *)(((uint32)ethptr->rxRing + 0xf) & ~0xf); ethptr->txRing = (void *)(((uint32)ethptr->txRing + 0xf) & ~0xf); ethptr->stats = (void *) (((uint32)ethptr->stats + 3) & ~0x3); /*D-word alligned*/ ethptr->rxBufs = NULL; ethptr->txBufs = NULL; //kprintf("The rings are tx : %u rx: %u \r\n", ethptr->txRing, ethptr->rxRing); /* Set buffer pointers and rings to zero */ memset(ethptr->rxRing, '\0', ( I82559_RFDSIZE + ETH_BUF_SIZE )* ethptr->rxRingSize); memset(ethptr->txRing, '\0', ( I82559_TFDSIZE + ETH_BUF_SIZE )* ethptr->txRingSize); txRingptr = (struct i82559_tx_desc *)ethptr->txRing; for(i=0; i < ethptr->txRingSize; ++i ){ txRingptr = (struct i82559_tx_desc *)((char *)(ethptr->txRing)+i*(I82559_TFDSIZE + ETH_BUF_SIZE)); /*NOTE: The following statment assumes that segmented addressing mode is used*/ /* Set the link to the next CB in the ring */ txRingptr->link_addr = ((i+1)%ethptr->txRingSize)*(I82559_TFDSIZE + ETH_BUF_SIZE); /* Set the entire status word to 0x0000 , FIXME, check if this is OK */ txRingptr->status = 0x0000; /** * Command Word Description(from Bit 16-31) : * Command = 100 (Transmit Command) * SF = 0 (Simplified Mode) * NC = 0 (CRC and address inserted by device) * 000 (Reserved and set to zeros) * CID = 00000 (Delay for CNA Interrupt, set to 0 for now, TODO more work required) * I = 1 (Generate interrupt after the execution of CB is complete) * S = 1 (Put CU to sleep after execution of CB and more .. Check manual) * EL = 1 (Indicates this CB is the last one in the CBL, is set to 1 for all CBs initially) * Command Word : 1110000000000100 / E004 */ //txRingptr->command = 0xA030; txRingptr->command = 0xE004; txRingptr->tbd_addr = 0xFFFFFFFF; /* Transmit threshold, represents the number of bytes in the * transmit FIFO for transmission to happen, is multiplied by * 8 to give the bytes, should be between 1 and 0E0h */ /* 16 bytes required in the trasnmit FIFO */ txRingptr->tx_treshold = 0x02; /* This is not used in the simplified structure, set it to 0, TBD number */ txRingptr->tbd_no = 0x00; /*These parameters should be changed when packet is ready to be transmitted * Also, EL bit should be unset*/ txRingptr->byte_count = 0; } /* RFA initialization */ rxRingptr = (struct i82559_rx_desc *)ethptr->rxRing; for(i=0; i < ethptr->rxRingSize; ++i){ rxRingptr = (struct i82559_rx_desc *)((char *)(ethptr->rxRing)+i*(I82559_RFDSIZE + ETH_BUF_SIZE)); /* Set the pointer to the next Receive frame.*/ rxRingptr->link_addr = ((i+1)%ethptr->rxRingSize)*(I82559_RFDSIZE + ETH_BUF_SIZE); //kprintf("Set link address to %u for [%d]\r\n", rxRingptr->link_addr, i); /* Set the entire status word to 0x0000 since this is set by the device later FIXME*/ rxRingptr->status = 0x0000; /* * Command Word Description( from Bit 16-31): * Command = 000 (command opcode for receive) * SF = 0 (for simplified mode) * H = 0 (decides if the RFD is a header RFD or not, is disregarded if load HDS was not run before * 000000000 (Reserved) * S = 0 ( Suspend the RU after receiving the frame) * EL = 0 (Indicates this is the last RFD in the RFA, set to 0 for all RFDs initially, except the last RFD) * Command Word : 1000000000000000 / 8000 */ rxRingptr->command = 0x0000; /*FIXME : Change these later */ /* Set the actual count to 0x0000 (this will set the EOF and F bits too) */ rxRingptr->ac_count = 0x0000; /* * Set the size to ETH_BUF_SIZE Later */ rxRingptr->size = ETH_BUF_SIZE; } /* * For the last RFD in the ring, we need to set the EL Bit and the S bit for the last block * this changes the command word to 0xC000 */ rxRingptr->command = 0x4000; /* Reset the NIC to bring it into a known state and initialize it */ if (OK != i8255x_reset(ethptr)) { //kprintf("i8255x_open: fail to reset I8255X device\n"); return SYSERR; } /* Configure the NIC */ if (OK != i8255x_configure(ethptr)) { //kprintf("i8255x_open: fail to configure I8255X device\n"); return SYSERR; } /* Enable interrupt */ set_evec(ethptr->dev->dvirq + IRQBASE, (uint32)ethDispatch); //kprintf("Calling the first IRQ Enable \r\n"); //kprintf("The interrupt mask is : %x\r\n", inw(ethptr->iobase +I8255X_SCB_COMMAND_LOW)); i8255x_irq_enable(ethptr); /* Start the receive unit */ i8255x_exec_ru(ethptr, (uint32) ethptr->rxHead*(I82559_RFDSIZE + ETH_BUF_SIZE)); //kprintf("All user processes have completed \r\n"); return OK; }
/** * Initialize ethernet device structures. * @param devptr ETH device table entry * @return OK if device is intialized successfully, otherwise SYSERR */ devcall etherInit(device *devptr) { struct ether *ethptr; struct ag71xx *nicptr; uint *rstptr; uint rstbit; /* Initialize structure pointers */ ethptr = ðertab[devptr->minor]; bzero(ethptr, sizeof(struct ether)); ethptr->dev = devptr; ethptr->csr = devptr->csr; nicptr = (struct ag71xx *)devptr->csr; rstptr = (uint *)RESET_CORE; if (0 == devptr->minor) { rstbit = RESET_E0_MAC; } else { rstbit = RESET_E1_MAC; } ethptr->state = ETH_STATE_DOWN; ethptr->rxRingSize = ETH_RX_RING_ENTRIES; ethptr->txRingSize = ETH_TX_RING_ENTRIES; ethptr->mtu = ETH_MTU; ethptr->interruptMask = IRQ_TX_PKTSENT | IRQ_TX_BUSERR | IRQ_RX_PKTRECV | IRQ_RX_OVERFLOW | IRQ_RX_BUSERR; ethptr->errors = 0; ethptr->isema = semcreate(0); ethptr->istart = 0; ethptr->icount = 0; ethptr->ovrrun = 0; ethptr->rxOffset = ETH_PKT_RESERVE; // FIXME: Actual MAC lookup in nvram. /* Lookup canonical MAC in NVRAM, and store in ether struct */ // colon2mac(nvramGet("et0macaddr"), ethptr->devAddress); char mac[] = { 0x00, 0x01, 0x36, 0x22, 0x7e, 0xf1 }; memcpy(ethptr->devAddress, mac, ETH_ADDR_LEN); ethptr->addressLength = ETH_ADDR_LEN; // Reset the device. nicptr->macConfig1 |= MAC_CFG1_SOFTRESET; udelay(20); *rstptr |= rstbit; mdelay(100); *rstptr &= ~rstbit; mdelay(100); // Enable Tx and Rx. nicptr->macConfig1 = MAC_CFG1_TX | MAC_CFG1_SYNC_TX | MAC_CFG1_RX | MAC_CFG1_SYNC_RX; // Configure full duplex, auto padding CRC, and interface mode. nicptr->macConfig2 |= MAC_CFG2_FDX | MAC_CFG2_PAD | MAC_CFG2_LEN_CHECK | MAC_CFG2_IMNIBBLE; // Enable FIFO modules. nicptr->fifoConfig0 = FIFO_CFG0_WTMENREQ | FIFO_CFG0_SRFENREQ | FIFO_CFG0_FRFENREQ | FIFO_CFG0_STFENREQ | FIFO_CFG0_FTFENREQ; // FIXME // -> ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); // Stores a '1' in 0x18070000 (MII mode) // Stores a '1' in 0x18070004 (RMII mode) // FRRD may be asserted only after the completion of the input frame. nicptr->fifoConfig1 = 0x0FFF0000; // Max out number of words to store in Rx RAM; nicptr->fifoConfig2 = 0x00001FFF; // Drop anything with errors in the Rx stats vector. nicptr->fifoConfig4 = 0x0003FFFF; // Drop short packets, set "don't care" on Rx stats vector bits. nicptr->fifoConfig5 = 0x0003FFFF; /* NOTE: because device initialization runs early in the system, */ /* we are assured that this stkget() call will return */ /* page-aligned (and cache-aligned) boundaries. */ ethptr->rxBufs = stkget(PAGE_SIZE); ethptr->txBufs = stkget(PAGE_SIZE); ethptr->rxRing = stkget(PAGE_SIZE); ethptr->txRing = stkget(PAGE_SIZE); if ((SYSERR == (int)ethptr->rxBufs) || (SYSERR == (int)ethptr->txBufs) || (SYSERR == (int)ethptr->rxRing) || (SYSERR == (int)ethptr->txRing)) { #ifdef DETAIL kprintf("eth%d ring buffer allocation error.\r\n", devptr->minor); #endif /* DETAIL */ return SYSERR; } /* bump buffer pointers/rings to KSEG1 */ ethptr->rxBufs = (struct ethPktBuffer **)(((ulong)ethptr->rxBufs - PAGE_SIZE + sizeof(int)) | KSEG1_BASE); ethptr->txBufs = (struct ethPktBuffer **)(((ulong)ethptr->txBufs - PAGE_SIZE + sizeof(int)) | KSEG1_BASE); ethptr->rxRing = (struct dmaDescriptor *)(((ulong)ethptr->rxRing - PAGE_SIZE + sizeof(int)) | KSEG1_BASE); ethptr->txRing = (struct dmaDescriptor *)(((ulong)ethptr->txRing - PAGE_SIZE + sizeof(int)) | KSEG1_BASE); /* Zero out the buffer pointers and rings */ bzero(ethptr->rxBufs, PAGE_SIZE); bzero(ethptr->txBufs, PAGE_SIZE); bzero(ethptr->rxRing, PAGE_SIZE); bzero(ethptr->txRing, PAGE_SIZE); register_irq(devptr->irq, devptr->intr); enable_irq(devptr->irq); return OK; }
/*------------------------------------------------------------------------ * ttyInit - initialize buffers and modes for a tty line *------------------------------------------------------------------------ */ devcall ttyInit( struct dentry *devptr /* entry in device switch table */ ) { struct ttycblk *typtr; /* pointer to ttytab entry */ struct uart_csreg *uptr; /* address of UART's CSRs */ typtr = &ttytab[ devptr->dvminor ]; /* Initialize values in the tty control block */ typtr->tyihead = typtr->tyitail = /* set up input queue */ &typtr->tyibuff[0]; /* as empty */ typtr->tyisem = semcreate(0); /* input semaphore */ typtr->tyohead = typtr->tyotail = /* set up output queue */ &typtr->tyobuff[0]; /* as empty */ typtr->tyosem = semcreate(TY_OBUFLEN); /* output semaphore */ typtr->tyehead = typtr->tyetail = /* set up echo queue */ &typtr->tyebuff[0]; /* as empty */ typtr->tyimode = TY_IMCOOKED; /* start in cooked mode */ typtr->tyiecho = TRUE; /* echo console input */ typtr->tyieback = TRUE; /* honor erasing bksp */ typtr->tyevis = TRUE; /* visual control chars */ typtr->tyecrlf = TRUE; /* echo CRLF for NEWLINE*/ typtr->tyicrlf = TRUE; /* map CR to NEWLINE */ typtr->tyierase = TRUE; /* do erasing backspace */ typtr->tyierasec = TY_BACKSP; /* erase char is ^H */ typtr->tyeof = TRUE; /* honor eof on input */ typtr->tyeofch = TY_EOFCH; /* end-of-file character*/ typtr->tyikill = TRUE; /* allow line kill */ typtr->tyikillc = TY_KILLCH; /* set line kill to ^U */ typtr->tyicursor = 0; /* start of input line */ typtr->tyoflow = TRUE; /* handle flow control */ typtr->tyoheld = FALSE; /* output not held */ typtr->tyostop = TY_STOPCH; /* stop char is ^S */ typtr->tyostart = TY_STRTCH; /* start char is ^Q */ typtr->tyocrlf = TRUE; /* send CRLF for NEWLINE*/ typtr->tyifullc = TY_FULLCH; /* send ^G when buffer */ /* is full */ /* Initialize the UART */ uptr = (struct uart_csreg *)devptr->dvcsr; /* Set baud rate */ outb((int)&uptr->lcr, UART_LCR_DLAB); outb((int)&uptr->dlm, 0x00); outb((int)&uptr->dll, 0x0c); outb((int)&uptr->lcr, UART_LCR_8N1); /* 8 bit char, No Parity*/ /* and 1 Stop bit */ outb((int)&uptr->fcr, 0x00); /* Disable FIFO for now */ /* OUT2 value is used to control the onboard interrupt tri-state*/ /* buffer. It should be set high to generate interrupts */ outb((int)&uptr->mcr, UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); /* Enbale user-def. OUT2*/ /* Register the interrupt dispatcher for the tty device */ set_evec( devptr->dvirq, (uint32)devptr->dvintr ); /* Enable interrupts on the device */ /* Enable UART FIFOs, clear and set interrupt trigger level */ outb((int)&uptr->fcr, UART_FCR_EFIFO | UART_FCR_RRESET | UART_FCR_TRESET | UART_FCR_TRIG2); ttyKickOut(typtr, uptr); (void)inb((int)&uptr->iir); (void)inb((int)&uptr->lsr); (void)inb((int)&uptr->msr); (void)inb((int)&uptr->buffer); return OK; }
/** * @ingroup udpexternal * * Associate a UDP socket with local and remote IP addresses and ports, and * prepare it for receiving and sending data with udpRead() and udpWrite(). * * @param devptr * Device table entry for the UDP device. * * @param ap Four additional arguments, specifying the following in order: * - The local IP address. * - The remote IP address. May be @c NULL to create an initially * unbound socket. * - The local port. May be 0 to auto-assign a port number. * - The remote port. May be 0 if creating an initially unbound socket. * * @return ::OK if the UDP device was opened successfully; otherwise ::SYSERR. */ devcall udpOpen(device *devptr, va_list ap) { irqmask im; int retval; struct udp *udpptr; const struct netaddr *localip; const struct netaddr *remoteip; ushort localpt; ushort remotept; udpptr = &udptab[devptr->minor]; im = disable(); /* Check if UDP is already open */ if (UDP_OPEN == udpptr->state) { UDP_TRACE("udp%d has already been opened.", devptr->minor); retval = SYSERR; goto out_restore; } udpptr->state = UDP_OPEN; udpptr->dev = devptr; /* Initialize incoming packet buffer */ udpptr->icount = 0; udpptr->istart = 0; /* Initialize the semaphore */ udpptr->isem = semcreate(0); if (SYSERR == (int)udpptr->isem) { retval = SYSERR; goto out_udp_close; } /* Retrieve port and address arguments */ localip = va_arg(ap, const struct netaddr *); remoteip = va_arg(ap, const struct netaddr *); localpt = va_arg(ap, int); remotept = va_arg(ap, int); /* Initialize ports and addresses */ /* Local IP address is required */ if (NULL == localip) { retval = SYSERR; goto out_free_sem; } netaddrcpy(&udpptr->localip, localip); /* Remote IP address is not required */ if (NULL == remoteip) { bzero(&udpptr->remoteip, sizeof(struct netaddr)); } else { netaddrcpy(&udpptr->remoteip, remoteip); } /* Allocate a local port if none is specified */ if (0 == localpt) { localpt = allocPort(); } udpptr->localpt = localpt; udpptr->remotept = remotept; /* Allocate received UDP packet buffer pool */ udpptr->inPool = bfpalloc(NET_MAX_PKTLEN, UDP_MAX_PKTS); if (SYSERR == (int)udpptr->inPool) { retval = SYSERR; goto out_release_port; } UDP_TRACE("udp%d inPool has been assigned pool ID %d.\r\n", devptr->minor, udpptr->inPool); udpptr->flags = 0; retval = OK; goto out_restore; out_release_port: udpptr->localpt = 0; out_free_sem: semfree(udpptr->isem); out_udp_close: udpptr->state = UDP_FREE; out_restore: restore(im); return retval; }
/** * Replies to ARP requests destined for our router, and handles replies * from our router */ void arpDaemon(void) { //arpTab = malloc(sizeof(struct arpTable)); //arpTab.arr = malloc(sizeof(struct arp)*MAX_ARP_TABLE); arpTab.size = 0; arpSem = semcreate(1); bzero(packet,PKTSZ); int pid; struct arpPkt *arpPkt; uchar *mac = malloc(ETH_ADDR_LEN); uchar *brdcast = malloc(ETH_ADDR_LEN); struct ethergram *eg = (struct ethergram*) packet; //bzero(packet, PKTSZ); control(ETH0, ETH_CTRL_GET_MAC, (long)mac, 0); brdcast[0] = 0xFF; brdcast[1] = 0xFF; brdcast[2] = 0xFF; brdcast[3] = 0xFF; brdcast[4] = 0xFF; brdcast[5] = 0xFF; while (1) { //printf("arpDaemon started loop\n"); //bzero(packet, PKTSZ); read(ETH0, packet, PKTSZ); // printPacket(packet); if (memcmp(eg->dst, mac, sizeof(mac)) != 0 && memcmp(eg->dst, brdcast, sizeof(brdcast)) != 0) /* Not our packet, drop */ continue; //printf("arpDaemon We received a packet for our mac\n"); arpPkt = (struct arpPkt *)&eg->data[0]; //printf("eg->type=%d arpPkt->hwtype=%d arpPkt->prtype=%08x\n",ntohs(eg->type), ntohs(arpPkt->hwtype), ntohs(arpPkt->prtype)); if (ntohs(eg->type)!=ETYPE_ARP||ntohs(arpPkt->hwtype) != 1 || ntohs(arpPkt->prtype) != ETYPE_IPv4 || arpPkt->hwalen != ETH_ADDR_LEN || arpPkt->pralen != IPv4_ADDR_LEN) continue; //printf("arpDaemon Got past first check\n"); if (memcmp(myipaddr, &arpPkt->addrs[ARP_ADDR_DPA], sizeof(myipaddr)) != 0) continue; //printf("arpDaemon We received a packet for our mac and ip\n"); if (arpPkt->op == ntohs(ARP_OP_RQST)) /* ARP Request */ { //printf("arpDaemon ARP Request recveid\n"); memcpy(eg->dst, eg->src, sizeof(eg->src)); memcpy(eg->src, mac, sizeof(mac)); eg->type = htons(ETYPE_ARP); arpPkt->prtype = htons(ETYPE_IPv4); arpPkt->op = htons(ARP_OP_REPLY); memcpy(&arpPkt->addrs[ARP_ADDR_DHA], &arpPkt->addrs[ARP_ADDR_SHA], ETH_ADDR_LEN); memcpy(&arpPkt->addrs[ARP_ADDR_DPA], &arpPkt->addrs[ARP_ADDR_SPA], IPv4_ADDR_LEN); memcpy(&arpPkt->addrs[ARP_ADDR_SHA], mac, ETH_ADDR_LEN); memcpy(&arpPkt->addrs[ARP_ADDR_SPA], myipaddr, IPv4_ADDR_LEN); write(ETH0, packet,ETHER_SIZE+ETHER_MINPAYLOAD);//(uchar*)((struct arpPkt *)((struct ethergram *)packet)->data)-packet); }else if (arpPkt->op == ntohs(ARP_OP_REPLY)) /* ARP Reply */ { //printf("\narpDaemon Mac address recveived thee mac address %02x:%02x:%02x:%02x:%02x:%02x\n",arpPkt->addrs[ARP_ADDR_SHA],arpPkt->addrs[ARP_ADDR_SHA+1],arpPkt->addrs[ARP_ADDR_SHA+2],arpPkt->addrs[ARP_ADDR_SHA+3],arpPkt->addrs[ARP_ADDR_SHA+4],arpPkt->addrs[ARP_ADDR_SHA+5]); pid = recvtime(CLKTICKS_PER_SEC*10); //printf("arpDaemon recved succ, sending\n"); if (pid == TIMEOUT) continue; sendMacAddress(pid, &arpPkt->addrs[ARP_ADDR_SHA]); }else /* Some other op type, drop */ continue; } }
shellcmd xsh_prodcons(int nargs, char *args[]) { //Argument verifications and validations if(nargs > 2){ printf("Too many arguments.\nType prodcons --help for details.\n"); return 0; } //initialize count to default value int count = MAX_COUNT; /*if there are command line args check if user has asked for help *if not check if user has provided valid input ((int) count and greater than 0) *else terminate execution */ if (nargs == 2) { if(strncmp(args[1], "--help", 7) == 0){ printf("Description:\n"); printf("\t--help\t display this help and exit\n"); printf("\t-f \t execute futures\n"); printf("\t\t by default it will execute producer-consumer.\n"); printf("Arguments in case of producer-consumer:\n"); printf("\tmax value of shared variable (integer){default value is 2000}\n"); return 0; } if(strncmp(args[1], "-n", 3) == 0){ printf("Inside N Args"); f_exclusive = future_alloc(FUTURE_EXCLUSIVE); resume( create(nw_cons, 1024, 20, "fcons1", 1, f_exclusive) ); resume( create(nw_prods, 1024, 20, "fprod1", 1, f_exclusive) ); return 0; } else if(strncmp(args[1], "-f", 3) == 0){ f_exclusive = future_alloc(FUTURE_EXCLUSIVE); f_shared = future_alloc(FUTURE_SHARED); f_queue = future_alloc(FUTURE_QUEUE); // Test FUTURE_EXCLUSIVE resume( create(future_cons, 1024, 20, "fcons1", 1, f_exclusive) ); resume( create(future_prod, 1024, 20, "fprod1", 1, f_exclusive) ); sleep(1); // Test FUTURE_SHARED resume( create(future_cons, 1024, 20, "fcons2", 1, f_shared) ); resume( create(future_cons, 1024, 20, "fcons3", 1, f_shared) ); resume( create(future_cons, 1024, 20, "fcons4", 1, f_shared) ); resume( create(future_cons, 1024, 20, "fcons5", 1, f_shared) ); resume( create(future_prod, 1024, 20, "fprod2", 1, f_shared) ); sleep(1); // Test FUTURE_QUEUE resume( create(future_cons, 1024, 20, "fcons6", 1, f_queue) ); resume( create(future_cons, 1024, 20, "fcons7", 1, f_queue) ); resume( create(future_cons, 1024, 20, "fcons7", 1, f_queue) ); resume( create(future_cons, 1024, 20, "fcons7", 1, f_queue) ); resume( create(future_prod, 1024, 20, "fprod3", 1, f_queue) ); resume( create(future_prod, 1024, 20, "fprod4", 1, f_queue) ); resume( create(future_prod, 1024, 20, "fprod5", 1, f_queue) ); resume( create(future_prod, 1024, 20, "fprod6", 1, f_queue) ); return 0; }else{ //check args[1](integer) if present assign value to count if(!isNumeric(args[1])){ printf("Invalid argument.\nType prodcons --help for details.\n"); return 0; } count = (atoi)(args[1]); //if command line count is 0 terminate. if(count == 0){ printf("Nothing to produce.\n"); return 0; } } } n=0; /*Initialise semaphores*/ produced = semcreate(0); consumed = semcreate(1); //create the process produer and consumer and put them in ready queue. //Look at the definations of function create and resume in exinu/system folder for reference. resume( create(producer, 1024, 20, "producer", 1, count) ); resume( create(consumer, 1024, 20, "consumer", 1, count) ); return 0; }