/** * Find the value of a variable. * @param *name name of variable to find * @return pointer to requested tuple struct */ char *nvramGet(char *name) { struct nvram_tuple *tuple; uint hash; if (OK != nvramInit() || NULL == name) { return NULL; } /* hash the name */ hash = nvramHash(name); /* iterate until name == name */ tuple = nvram_tuples[hash]; while ((tuple != NULL) && (strncmp(name, tuple->pair, strnlen(name, NVRAM_STRMAX)) != 0)) { tuple = tuple->next; } /* make sure a valid string was found, if not return NULL */ if (NULL == tuple) { return NULL; } /* return pointer to start of value name=value pair */ return tuple->pair + strnlen(name, NVRAM_STRMAX) + 1; }
/*------------------------------------------------------------------------ * xsh_nvram - shell command to list all items in NVRAM (Flash) or to * display one item *------------------------------------------------------------------------ */ shellcmd xsh_nvram(int nargs, char *args[]) { char *value; /* value to print */ uint16 n; /* iterates through items */ uint16 count; /* counts items found */ struct nvram_tuple *tuple; /* insure nvram can be initialized */ if (nvramInit() == SYSERR) { fprintf(stderr, "error: device does not appear to have nvram.\n"); return 1; } /* For argument '--help', emit help about the 'nvram' command */ if (nargs == 2 && strncmp(args[1], "--help", 7) == 0) { printf("Use: %s OPTION \n\n", args[0]); printf("Description:\n"); printf("%s,%s\n", "\tDisplays a list of items in NVRAM ", "or the value of an item"); printf("Options:\n"); printf("\tlist\t\t\tdisplay all <NAME>=<VALUE> tuples\n"); printf("\tget <NAME>\t\tdisplay the value of <NAME>\n"); printf("\t--help\t display this help and exit\n"); return 0; } if ( (nargs==2) && (strncmp(args[1], "list", 5)==0) ) { count = 0; for (n = 0; n < NVRAM_NHASH; n++) { tuple = nvram_tuples[n]; if (tuple == NULL) { continue; } do { printf("%s\n", tuple->pair); count++; } while ((tuple = tuple->next) != NULL); } printf("%d pairs occupt %d bytes (%d bytes remain unused)\n", count, nvram_header->length, NVRAM_SIZE - nvram_header->length); return 0; } else if ( (nargs == 3) && (strncmp(args[1], "get", 4) == 0) ) { value = nvramGet(args[2]); if (value != 0) { printf("%s\n", nvramGet(args[2])); return 0; } else { fprintf(stderr, "error: no NVRAM binding\n"); return 1; } } fprintf(stderr, "%s: incorrect arguments\n", args[0]); fprintf(stderr, "Try '%s --help' for more information\n", args[0]); return 1; }
/** * Remove a setting from nvram. * @param *name name to remove from nvram settings * @return OK on success, SYSERR on failure */ devcall nvramUnset(char *name) { struct nvram_tuple *tuple, *prev; long index; uint length; if (OK != nvramInit()) { return SYSERR; } /* find the pointer to the pair */ if (SYSERR == (index = nvramHash(name))) { return SYSERR; } tuple = prev = nvram_tuples[index]; while (tuple != NULL && strncmp(tuple->pair, name, strnlen(name, NVRAM_STRMAX))) { prev = tuple; tuple = tuple->next; } if (NULL == tuple) { return SYSERR; } if (nvram_tuples[index] == tuple) { nvram_tuples[index] = tuple->next; } else { prev->next = tuple->next; } /* decrease length of nvram variables in header */ length = strnlen(tuple->pair, NVRAM_STRMAX) + 1; nvram_header->length -= length; /* free memory node */ if (SYSERR == memfree((void *)tuple, length)) { return SYSERR; } return OK; }
/** * Change the variable name to value. If name does not exist, create it, * otherwise replace the old value with the new. * @param *name name to modify * @param *value value to set name * @return OK on successful change, SYSERR on failure */ devcall nvramSet(char *name, char *value) { struct nvram_tuple *tuple; ulong length, offset; if (OK != nvramInit()) { return SYSERR; } length = sizeof(struct nvram_tuple) + strnlen(name, NVRAM_STRMAX) + 1 + strnlen(value, NVRAM_STRMAX); /* check if name is already defined somewhere */ /* if so unset, so we can reset */ if (nvramGet(name) != NULL) { nvramUnset(name); } /* get enough space for both to be rounded up with \0 stored */ if (NULL == (tuple = (struct nvram_tuple *)memget(length))) { return SYSERR; } /* copy name into memory */ offset = 0; strncpy(tuple->pair, name, strnlen(name, NVRAM_STRMAX)); offset += strnlen(name, NVRAM_STRMAX); strncpy(tuple->pair + offset, "=", 1); offset += 1; strncpy(tuple->pair + offset, value, strnlen(value, NVRAM_STRMAX)); offset += strnlen(value, NVRAM_STRMAX); strncpy(tuple->pair + offset, "\0", 1); /* store pointer to name in nvram_tuple struct */ nvramInsert(tuple); return OK; }
/** * Intializes all Xinu data structures and devices. * @return OK if everything is initialized successfully */ static int sysinit(void) { int i; struct thrent *thrptr; /* thread control block pointer */ struct memblock *pmblock; /* memory block pointer */ /* Initialize system variables */ /* Count this NULLTHREAD as the first thread in the system. */ thrcount = 1; /* Initialize free memory list */ memheap = roundmb(memheap); platform.maxaddr = truncmb(platform.maxaddr); memlist.next = pmblock = (struct memblock *)memheap; memlist.length = (uint)(platform.maxaddr - memheap); pmblock->next = NULL; pmblock->length = (uint)(platform.maxaddr - memheap); /* Initialize thread table */ for (i = 0; i < NTHREAD; i++) { thrtab[i].state = THRFREE; } /* initialize null thread entry */ thrptr = &thrtab[NULLTHREAD]; thrptr->state = THRCURR; thrptr->prio = 0; strlcpy(thrptr->name, "prnull", TNMLEN); thrptr->stkbase = (void *)&_end; thrptr->stklen = (ulong)memheap - (ulong)&_end; thrptr->stkptr = 0; thrptr->memlist.next = NULL; thrptr->memlist.length = 0; thrcurrent = NULLTHREAD; /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semtab[i].state = SFREE; semtab[i].queue = queinit(); } /* Initialize monitors */ for (i = 0; i < NMON; i++) { montab[i].state = MFREE; } /* Initialize buffer pools */ for (i = 0; i < NPOOL; i++) { bfptab[i].state = BFPFREE; } /* initialize thread ready list */ readylist = queinit(); #if SB_BUS backplaneInit(NULL); #endif /* SB_BUS */ #if RTCLOCK /* initialize real time clock */ clkinit(); #endif /* RTCLOCK */ #ifdef UHEAP_SIZE /* Initialize user memory manager */ { void *userheap; /* pointer to user memory heap */ userheap = stkget(UHEAP_SIZE); if (SYSERR != (int)userheap) { userheap = (void *)((uint)userheap - UHEAP_SIZE + sizeof(int)); memRegionInit(userheap, UHEAP_SIZE); /* initialize memory protection */ safeInit(); /* initialize kernel page mappings */ safeKmapInit(); } } #endif #if USE_TLB /* initialize TLB */ tlbInit(); /* register system call handler */ exceptionVector[EXC_SYS] = syscall_entry; #endif /* USE_TLB */ #if NMAILBOX /* intialize mailboxes */ mailboxInit(); #endif #if NDEVS for (i = 0; i < NDEVS; i++) { devtab[i].init((device*)&devtab[i]); } #endif #ifdef WITH_USB usbinit(); #endif #if NVRAM nvramInit(); #endif #if NNETIF netInit(); #endif #if GPIO gpioLEDOn(GPIO_LED_CISCOWHT); #endif return OK; }
static void sysinit(void) { int32 i; struct procent *prptr; /* ptr to process table entry */ struct sentry *semptr; /* prr to semaphore table entry */ struct memblk *memptr; /* ptr to memory block */ /* Initialize system variables */ /* Count the Null process as the first process in the system */ prcount = 1; /* Scheduling is not currently blocked */ Defer.ndefers = 0; /* Initialize the free memory list */ maxheap = (void *)addressp2k(MAXADDR); memlist.mnext = (struct memblk *)minheap; /* Overlay memblk structure on free memory and set fields */ memptr = (struct memblk *)minheap; memptr->mnext = NULL; memptr->mlength = memlist.mlength = (uint32)(maxheap - minheap); /* Initialize process table entries free */ for (i = 0; i < NPROC; i++) { prptr = &proctab[i]; prptr->prstate = PR_FREE; prptr->prname[0] = NULLCH; prptr->prstkbase = NULL; prptr->prprio = 0; } /* Initialize the Null process entry */ prptr = &proctab[NULLPROC]; prptr->prstate = PR_CURR; prptr->prprio = 0; strncpy(prptr->prname, "prnull", 7); prptr->prstkbase = minheap; prptr->prstklen = NULLSTK; prptr->prstkptr = 0; currpid = NULLPROC; /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semptr = &semtab[i]; semptr->sstate = S_FREE; semptr->scount = 0; semptr->squeue = newqueue(); } /* Initialize buffer pools */ bufinit(); /* Create a ready list for processes */ readylist = newqueue(); /* Initialize real time clock */ clkinit(); /* Initialize non-volative RAM storage */ #if 0 nvramInit(); #endif /* Initialize devices */ for (i = 0; i < NDEVS; i++) { init(i); } return; }
/** * Commit nvram settings to memory. Due to the nature of nvram settings * writing to memory everytime would greatly reduce the life of flash, so * after making changes you must commit them to memory. * @return OK on success, SYSERR on failure */ devcall nvramCommit() { struct dentry *devptr = NULL; struct flash *flash = NULL; struct nvram_tuple *tuple; struct flash_block block, test_block; uchar *buffer; ulong n, offset, pos; if (OK != nvramInit()) { return SYSERR; } #if FLASH devptr = (device *)&devtab[FLASH]; #endif if (NULL == devptr) { return SYSERR; } flash = &flashtab[devptr->minor]; /* length is maintained length + 2 (null string buffers) */ /* and + 3 & ~0x03 to force word alignment */ nvram_header->length = (nvram_header->length + 2 + 3) & ~0x03; /* prepare a buffer to store all settings in */ buffer = (uchar *)memget(nvram_header->length); if (SYSERR == (int)buffer) { return SYSERR; } bzero(buffer, nvram_header->length); /* clear header crc */ nvram_header->crc_ver_init &= ~NVRAM_CRC_MASK; /* copy header into block */ memcpy(buffer, nvram_header, sizeof(struct nvram_header)); offset = sizeof(struct nvram_header); /* start at offset in block and write byte for byte */ for (n = 0; n < NVRAM_NHASH; n++) { tuple = nvram_tuples[n]; if (NULL == tuple) { continue; } do { /* copy tuple into buffer */ memcpy(buffer + offset, tuple->pair, strnlen(tuple->pair, NVRAM_STRMAX)); /* next position + 1 for null-terminiation */ offset += strnlen(tuple->pair, NVRAM_STRMAX) + 1; /* optionally, free the tuple memory */ //memfree((void *)tuple); } while ((tuple = tuple->next) != NULL); } /* calculate crc */ nvram_header->crc_ver_init |= ((uchar)nvramCrc(buffer)); /* write new crc into block */ memcpy(buffer, nvram_header, sizeof(struct nvram_header)); /* to maintain data integrity check if the last block is being used */ block = logicalMap(flash, NVRAM_MIN_BLOCK); for (n = 0; n < MAX_LIVE_BLOCKS; n++) { pos = (flash->curr_block + n) % MAX_LIVE_BLOCKS; test_block = flash->erase_blocks[pos]; if (test_block.start_pos == block.start_pos) { if (FLASH_BLOCK_FREE != block.state) { block = test_block; break; } } } if (MAX_LIVE_BLOCKS <= n) { /* it is not cached in main memory */ /* evict a block */ physicalWrite(flash, &(flash->erase_blocks[flash->curr_block])); block.state = FLASH_BLOCK_FREE; /* read in block with nvram settings */ physicalRead(flash, &block); } /* write the settings */ offset = block.size - NVRAM_SIZE; memcpy(block.buffer + offset, buffer, nvram_header->length); block.state = FLASH_BLOCK_DIRTY; /* force a sync */ #if FLASH control(FLASH, FLASH_SYNC, FLASH_BLOCK, (long)&block); #endif /* finally, free the block and return */ memfree((void *)buffer, nvram_header->length); return OK; }
/** * Intializes all Xinu data structures and devices. * @return OK if everything is initialized successfully */ static int sysinit(void) { int i; void *userheap; /* pointer to user memory heap */ struct thrent *thrptr; /* thread control block pointer */ device *devptr; /* device entry pointer */ struct sement *semptr; /* semaphore entry pointer */ struct memblock *pmblock; /* memory block pointer */ struct bfpentry *bfpptr; /* Initialize system variables */ /* Count this NULLTHREAD as the first thread in the system. */ thrcount = 1; kprintf("variable i in this function is at 0x%x\r\n", &i); kprintf("this function sysinit is at 0x%x\r\n", &sysinit); kprintf("_start is at 0x%x\r\n", _start); kprintf("_end is at (the end) at 0x%x\r\n", &_end); kprintf("readylist is at 0x%x\r\n", &readylist); kprintf("kputc is at 0x%x\r\n", &kputc); kprintf("NTHREAD is %d\r\n", NTHREAD); kprintf("memheap is 0x%x\r\n", memheap); /* Initialize free memory list */ memheap = roundmb(memheap); platform.maxaddr = truncmb(platform.maxaddr); kprintf("platform.maxaddr is 0x%x\r\n", platform.maxaddr); memlist.next = pmblock = (struct memblock *)memheap; memlist.length = (uint)(platform.maxaddr - memheap); pmblock->next = NULL; pmblock->length = (uint)(platform.maxaddr - memheap); /* Initialize thread table */ for (i = 0; i < NTHREAD; i++) { thrtab[i].state = THRFREE; } kprintf("thrtab is at 0x%x, size %d\r\n", thrtab, sizeof(thrtab)); /* initialize null thread entry */ thrptr = &thrtab[NULLTHREAD]; thrptr->state = THRCURR; thrptr->prio = 0; strncpy(thrptr->name, "prnull", 7); thrptr->stkbase = (void *)&_end; thrptr->stklen = (ulong)memheap - (ulong)&_end; thrptr->stkptr = 0; thrptr->memlist.next = NULL; thrptr->memlist.length = 0; thrcurrent = NULLTHREAD; kprintf("&_end is 0x%x\n", &_end); /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semptr = &semtab[i]; semptr->state = SFREE; semptr->count = 0; semptr->queue = queinit(); } kprintf("NPOOL is %d\n", NPOOL); /* Initialize buffer pools */ for (i = 0; i < NPOOL; i++) { bfpptr = &bfptab[i]; bfpptr->state = BFPFREE; } kprintf("calling queinit() for readylist\r\n"); /* initialize thread ready list */ readylist = queinit(); #if SB_BUS backplaneInit(NULL); #endif /* SB_BUS */ #if RTCLOCK /* initialize real time clock */ kprintf("Clock being initialized.\r\n" ); clkinit(); #endif /* RTCLOCK */ #ifdef UHEAP_SIZE /* Initialize user memory manager */ userheap = stkget(UHEAP_SIZE); if (SYSERR != (int)userheap) { userheap = (void *)((uint)userheap - UHEAP_SIZE + sizeof(int)); memRegionInit(userheap, UHEAP_SIZE); /* initialize memory protection */ safeInit(); /* initialize kernel page mappings */ safeKmapInit(); } #else userheap = NULL; #endif /* UHEAP_SIZE */ #if USE_TLB /* initialize TLB */ tlbInit(); /* register system call handler */ exceptionVector[EXC_SYS] = syscall_entry; #endif /* USE_TLB */ #if NMAILBOX /* intialize mailboxes */ mailboxInit(); #endif #if NDEVS for (i = 0; i < NDEVS; i++) { if (!isbaddev(i)) { devptr = (device *)&devtab[i]; (devptr->init) (devptr); } } #endif #if 0 #if NVRAM nvramInit(); #endif kprintf("SO MUCH MORE NOT done with sysinit()\r\n"); #if NNETIF netInit(); #endif kprintf("NOT done with sysinit()\r\n"); #if GPIO gpioLEDOn(GPIO_LED_CISCOWHT); #endif #endif kprintf("done with sysinit()\r\n"); return OK; }
static void sysinit(void) { int32 i; struct procent *prptr; /* ptr to process table entry */ struct dentry *devptr; /* ptr to device table entry */ struct sentry *semptr; /* prr to semaphore table entry */ struct memblk *memptr; /* ptr to memory block */ /* Initialize system variables */ /* Count the Null process as the first process in the system */ prcount = 1; /* Scheduling is not currently blocked */ Defer.ndefers = 0; /* Initialize the free memory list */ maxheap = (void *)addressp2k(MAXADDR); memlist.mnext = (struct memblk *)minheap; /* Overlay memblk structure on free memory and set fields */ memptr = (struct memblk *)minheap; memptr->mnext = NULL; memptr->mlength = memlist.mlength = (uint32)(maxheap - minheap); /* Initialize process table entries free */ for (i = 0; i < NPROC; i++) { prptr = &proctab[i]; prptr->prstate = PR_FREE; prptr->prname[0] = NULLCH; prptr->prstkbase = NULL; prptr->prprio = 0; } /* Initialize the Null process entry */ prptr = &proctab[NULLPROC]; prptr->prstate = PR_CURR; prptr->prprio = 0; strncpy(prptr->prname, "prnull", 7); prptr->prstkbase = minheap; prptr->prstklen = NULLSTK; prptr->prstkptr = 0; currpid = NULLPROC; /* Initialize semaphores */ for (i = 0; i < NSEM; i++) { semptr = &semtab[i]; semptr->sstate = S_FREE; semptr->scount = 0; semptr->squeue = newqueue(); } /* Initialize buffer pools */ bufinit(); /* Create a ready list for processes */ readylist = newqueue(); /* Initialize real time clock */ clkinit(); /* Initialize non-volative RAM storage */ nvramInit(); for (i = 0; i < NDEVS; i++) { if (! isbaddev(i)) { devptr = (struct dentry *) &devtab[i]; (devptr->dvinit) (devptr); } } /** * Initialize the last two entries in lflcblk used for * directory manipulation. */ struct dentry dircblk; dircblk.dvminor = Nlfl; lflInit(&dircblk); dircblk.dvminor = Nlfl+1; lflInit(&dircblk); lfDirCblkMutex = semcreate(1); open(ETHER0,NULL, NULL); /* Create a process to handle network packets */ resume((create(netin, 8192, 500, "netin", 0)) ); return; }