static int cfe_nvram_chk() { char *name, *value, *end, *eq; unsigned int i; int ret, name_head, nvram_len; unsigned char *ptr; if(cfe_buf == NULL||cfe_mtd == NULL) if((ret = cfe_init())) return ret; /* printk("cfe_nvram_chk: dump data\n"); printk("\n####################\n"); for(i=0, ptr=(unsigned char *)cfe_nvram_header; i< cfe_embedded_size; i++, ptr++) { if(i%16==0) printk("%04x: %02x ", i, *ptr); else if(i%16==15) printk("%02x\n", *ptr); else if(i%16==7) printk("%02x - ", *ptr); else printk("%02x ", *ptr); } printk("\n####################\n"); printk("\ncfe_nvram_chk: cfe_nvram_header(%08x)\n", (unsigned int)cfe_nvram_header); printk("cfe_nvram_chk: cfe_nvram_header->len=%d(0x%08x)\n", cfe_nvram_header->len, cfe_nvram_header->len); */ nvram_len = cfe_nvram_header->len; name = (char *) &cfe_nvram_header[1]; end = (char *) cfe_nvram_header + nvram_len - 2; end[0] = end[1] = '\0'; name_head = (int)name; i = 0; for (; *name; name = value + strlen(value) + 1) { // printk("%04x: %s\n",i, name); if (!(eq = strchr(name, '='))) { printk("*** Illegal nvram format at %04x: %s !!!!\n", i, name); return 0; } *eq = '\0'; value = eq + 1; *eq = '='; i += strlen(name)+1; } if(((int)name - name_head) < 0x0f4b) { printk("Unexpect \\0 inside nvram: %04x\n", ((int)name -name_head)); return 0; } return 1; }
void cfe_update(const char *keyword, const char *value) { unsigned long i, offset; struct nvram_header tmp, *header; uint8 crc; // int ret; int found = 0; if(!cfe_buf||!cfe_mtd) cfe_init(); if (!cfe_buf||!cfe_mtd) return; header = cfe_nvram_header; printk("before: %x %x\n", header->len, cfe_nvram_header->crc_ver_init&0xff); for(i=CFE_NVRAM_START;i<=CFE_NVRAM_END;i++) { if(strncmp(&cfe_buf[i], keyword, strlen(keyword))==0) { printk("before: %s\n", cfe_buf+i); offset=strlen(keyword); memcpy(cfe_buf+i+offset+1, value, strlen(value)); printk("after: %s\n", cfe_buf+i); found = 1; } } if(!found) { char *tmp_buf = (char *)cfe_nvram_header; /* printk("header len: %x\n", header->len); */ sprintf(tmp_buf+header->len, "%s=%s", keyword, value); header->len = header->len + strlen(keyword) + strlen(value) + 2; /* printk("header len: %x\n", header->len); */ } tmp.crc_ver_init = htol32(header->crc_ver_init); tmp.config_refresh = htol32(header->config_refresh); tmp.config_ncdl = htol32(header->config_ncdl); crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE); /* Continue CRC8 over data bytes */ crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc); header->crc_ver_init = (header->crc_ver_init&0xFFFFFF00)|crc; printk("after: %x %x\n", header->crc_ver_init&0xFF, crc); }
int main(long fwhandle,long evector,long fwentry,long fwseal) { struct stat sb; const char *reason; int fd; /* Init prom callback vector. */ cfe_init(fwhandle,fwentry); init_console(); putstr("\nNetBSD/sbmips " NETBSD_VERS " " BOOTXX_FS_NAME " Primary Bootstrap\n"); if (!booted_dev_open()) { reason = "Can't open boot device."; goto fail; } fd = open("boot", 0); if (fd == -1 || (fstat(fd, &sb) == -1)) { reason = "Can't open /boot."; goto failclose; } if (sb.st_size > SECONDARY_MAX_LOAD) { reason = "/boot too large."; goto failclose; } if (read(fd, (void*)SECONDARY_LOAD_ADDRESS, sb.st_size) != sb.st_size) { reason = "/boot load failed."; goto failclose; } cfe_flushcache(0); putstr("Jumping to entry point...\n"); (*((void(*)(long,long,long))SECONDARY_LOAD_ADDRESS))(fwhandle,booted_dev_fd,fwentry); reason = "Secondary boot returned!"; failclose: booted_dev_close(); fail: putstr(reason); putstr("\n\nPRIMARY BOOTSTRAP FAILED!\n"); return 1; }
static int cfe_dump(void) { unsigned int i; int ret; unsigned char *ptr; if(cfe_buf == NULL||cfe_mtd == NULL) if((ret = cfe_init())) return ret; printk("cfe_dump: cfe_buf(%08x), dump 1024 byte\n", (unsigned int)cfe_buf); for(i=0, ptr=(unsigned char *)cfe_nvram_header - 1024; ptr < (unsigned char *)cfe_nvram_header; i++, ptr++) { if(i%16==0) printk("%04x: %02x ", i, *ptr); else if(i%16==15) printk("%02x\n", *ptr); else if(i%16==7) printk("%02x - ", *ptr); else printk("%02x ", *ptr); } printk("\ncfe_dump: cfe_nvram_header(%08x)\n", (unsigned int)cfe_nvram_header); printk("cfe_dump: cfe_nvram_header->len(0x%08x)\n", cfe_nvram_header->len); printk("\n####################\n"); for(i=0, ptr=(unsigned char *)cfe_nvram_header; i< cfe_embedded_size; i++, ptr++) { if(i%16==0) printk("%04x: %02x ", i, *ptr); else if(i%16==15) printk("%02x\n", *ptr); else if(i%16==7) printk("%02x - ", *ptr); else printk("%02x ", *ptr); } printk("\n####################\n"); ptr = (unsigned char *)&cfe_nvram_header[1]; while(*ptr) { printk("%s\n", ptr); ptr += strlen(ptr) + 1; } printk("\n####################\n"); for(i=0, ptr=((unsigned char *)cfe_nvram_header) + cfe_embedded_size; i<16; i++, ptr++) { if(i%16==0) printk("%04x: %02x ", i, *ptr); else if(i%16==15) printk("%02x\n", *ptr); else if(i%16==7) printk("%02x - ", *ptr); else printk("%02x ", *ptr); } return 0; }
void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { vm_offset_t kernend; uint64_t platform_counter_freq; int error; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); /* Initialize pcpu stuff */ mips_pcpu0_init(); #ifdef CFE /* * Initialize CFE firmware trampolines. This must be done * before any CFE APIs are called, including writing * to the CFE console. * * CFE passes the following values in registers: * a0: firmware handle * a2: firmware entry point * a3: entry point seal */ if (a3 == CFE_EPTSEAL) cfe_init(a0, a2); #endif /* Init BCM platform data */ if ((error = bcm_init_platform_data(&bcm_platform_data))) panic("bcm_init_platform_data() failed: %d", error); platform_counter_freq = bcm_get_cpufreq(bcm_get_platform()); /* CP0 ticks every two cycles */ mips_timer_early_init(platform_counter_freq / 2); cninit(); mips_init(); mips_timer_init_params(platform_counter_freq, 1); }
static __init void prom_init_cfe(void) { uint32_t cfe_ept; uint32_t cfe_handle; uint32_t cfe_eptseal; int argc = fw_arg0; char **envp = (char **) fw_arg2; int *prom_vec = (int *) fw_arg3; /* * Check if a loader was used; if NOT, the 4 arguments are * what CFE gives us (handle, 0, EPT and EPTSEAL) */ if (argc < 0) { cfe_handle = (uint32_t)argc; cfe_ept = (uint32_t)envp; cfe_eptseal = (uint32_t)prom_vec; } else { if ((int)prom_vec < 0) { /* * Old loader; all it gives us is the handle, * so use the "known" entrypoint and assume * the seal. */ cfe_handle = (uint32_t)prom_vec; cfe_ept = 0xBFC00500; cfe_eptseal = CFE_EPTSEAL; } else { /* * Newer loaders bundle the handle/ept/eptseal * Note: prom_vec is in the loader's useg * which is still alive in the TLB. */ cfe_handle = prom_vec[0]; cfe_ept = prom_vec[2]; cfe_eptseal = prom_vec[3]; } } if (cfe_eptseal != CFE_EPTSEAL) { /* too early for panic to do any good */ printk(KERN_ERR "CFE's entrypoint seal doesn't match."); while (1) ; } cfe_init(cfe_handle, cfe_ept); }
void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { vm_offset_t kernend; uint64_t platform_counter_freq; struct bcm_socinfo *socinfo; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); /* Initialize pcpu stuff */ mips_pcpu0_init(); socinfo = bcm_get_socinfo(); platform_counter_freq = socinfo->cpurate * 1000 * 1000; /* BCM4718 is 480MHz */ mips_timer_early_init(platform_counter_freq); #ifdef CFE /* * Initialize CFE firmware trampolines before * we initialize the low-level console. * * CFE passes the following values in registers: * a0: firmware handle * a2: firmware entry point * a3: entry point seal */ if (a3 == CFE_EPTSEAL) cfe_init(a0, a2); #endif cninit(); mips_init(); /* BCM471x timer is 1/2 of Clk */ mips_timer_init_params(platform_counter_freq, 1); }
void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { /* * Make sure that kseg0 is mapped cacheable-coherent */ kseg0_map_coherent(); /* clear the BSS and SBSS segments */ memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); mips_postboot_fixup(); sb_intr_init(0); sb_timecounter_init(); /* Initialize pcpu stuff */ mips_pcpu0_init(); #ifdef CFE /* * Initialize CFE firmware trampolines before * we initialize the low-level console. * * CFE passes the following values in registers: * a0: firmware handle * a2: firmware entry point * a3: entry point seal */ if (a3 == CFE_EPTSEAL) cfe_init(a0, a2); #endif cninit(); mips_init(); mips_timer_init_params(sb_cpu_speed(), 0); }
void prom_init(void) { uint32_t cfe_ept, cfe_handle; unsigned int cfe_eptseal; int argc = fw_arg0; char **envp = (char **) fw_arg2; int *prom_vec = (int *) fw_arg3; /* * Check if a loader was used; if NOT, the 4 arguments are * what CFE gives us (handle, 0, EPT and EPTSEAL) */ cfe_handle = (uint32_t)(long)argc; cfe_ept = (long)envp; cfe_eptseal = (uint32_t)(unsigned long)prom_vec; if (cfe_eptseal != CFE_EPTSEAL) { /* too early for panic to do any good */ return; } cfe_init(cfe_handle, cfe_ept); }
static int cfe_update(const char *keyword, const char *value) { struct nvram_header *header; uint8 crc; int ret; int found = 0; char *str, *end, *mv_target = NULL, *mv_start = NULL; if(keyword == NULL || *keyword == 0) return 0; if(cfe_buf == NULL||cfe_mtd == NULL) if((ret = cfe_init())) return ret; header = cfe_nvram_header; printk("cfe_update: before %x %x\n", header->len, cfe_nvram_header->crc_ver_init&0xff); str = (char *) &header[1]; end = (char *) header + cfe_embedded_size - 2; end[0] = end[1] = '\0'; for (; *str; str += strlen(str) + 1) { if(!found) { if(strncmp(str, keyword, strlen(keyword)) == 0 && str[strlen(keyword)] == '=') { printk("cfe_update: !!!! found !!!!\n"); found = 1; if(value != NULL && strlen(str) == strlen(keyword) + 1 + strlen(value)) {//string length is the same strcpy(str+strlen(keyword)+1, value); } else { mv_target = str; mv_start = str + strlen(str) + 1; } } } } /* str point to the end of all embedded nvram settings */ if(mv_target != NULL) { /* need to move string */ int str_len = strlen(mv_target); //printk("cfe_update: mv_target(%08x) mv_start(%08x) str(%08x) str_len(%d)\n", (unsigned int)mv_target, (unsigned int)mv_start, (unsigned int)str, str_len); if(value != NULL && (str + strlen(keyword) + 1 + strlen(value) + 1 - (str_len + 1)) > end) return -ENOSPC; memmove(mv_target, mv_start, str - mv_start); //printk("cfe_update: memmove done\n"); str -= (str_len + 1); /* /set str to the end for placing incoming keyword and value there */ } if(value == NULL) { //printk("cfe_update: do unset\n"); } else if(!found || mv_target != NULL) /*new or movement */ { /* append the keyword and value here */ //printk("cfe_update: str(%08x)\n", (unsigned int) str); if((str + strlen(keyword) + 1 + strlen(value) + 1) > end) return -ENOSPC; str += sprintf(str, "%s=%s", keyword, value) + 1; //printk("cfe_update: append string\n"); } /* calc length */ memset(str, 0, cfe_embedded_size+(char *)header - str); str += 2; header->len = ROUNDUP(str - (char *) header, 4); //printk("cfe_update: header len: %x\n", header->len); /*/calc crc */ crc = nvram_calc_crc(header); //printk("cfe_update: nvram_calc_crc(header) = 0x%02x\n", crc); header->crc_ver_init = (header->crc_ver_init & NVRAM_CRC_VER_MASK)|crc; //printk("cfe_update: after %x %x\n", header->crc_ver_init&0xFF, crc); return 0; }
/* * Do all the stuff that locore normally does before calling main(). */ void mach_init(long fwhandle, long magic, long bootdata, long reserved) { void *kernend, *p0; u_long first, last; extern char edata[], end[]; int i; uint32_t config; /* XXX this code must run on the target CPU */ config = mips3_cp0_config_read(); config &= ~MIPS3_CONFIG_K0_MASK; config |= 0x05; /* XXX. cacheable coherent */ mips3_cp0_config_write(config); /* Zero BSS. XXXCGD: uh, is this really necessary still? */ memset(edata, 0, end - edata); /* * Copy the bootinfo structure from the boot loader. * this has to be done before mips_vector_init is * called because we may need CFE's TLB handler */ if (magic == BOOTINFO_MAGIC) memcpy(&bootinfo, (struct bootinfo_v1 *)bootdata, sizeof bootinfo); else if (reserved == CFE_EPTSEAL) { magic = BOOTINFO_MAGIC; bzero(&bootinfo, sizeof bootinfo); bootinfo.version = BOOTINFO_VERSION; bootinfo.fwhandle = fwhandle; bootinfo.fwentry = bootdata; bootinfo.ssym = (vaddr_t)end; bootinfo.esym = (vaddr_t)end; } kernend = (void *)mips_round_page(end); #if NKSYMS || defined(DDB) || defined(LKM) if (magic == BOOTINFO_MAGIC) { ksym_start = (void *)bootinfo.ssym; ksym_end = (void *)bootinfo.esym; kernend = (void *)mips_round_page((vaddr_t)ksym_end); } #endif consinit(); uvm_setpagesize(); /* * Copy exception-dispatch code down to exception vector. * Initialize locore-function vector. * Clear out the I and D caches. */ mips_vector_init(); #ifdef DEBUG printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n", (u_int)fwhandle, (u_int)magic, (u_int)bootdata, (u_int)reserved); #endif strcpy(cpu_model, "sb1250"); if (magic == BOOTINFO_MAGIC) { int idx; int added; uint64_t start, len, type; cfe_init(bootinfo.fwhandle, bootinfo.fwentry); cfe_present = 1; idx = 0; physmem = 0; mem_cluster_cnt = 0; while (cfe_enummem(idx, 0, &start, &len, &type) == 0) { added = 0; printf("Memory Block #%d start %08"PRIx64"X len %08"PRIx64"X: %s: ", idx, start, len, (type == CFE_MI_AVAILABLE) ? "Available" : "Reserved"); if ((type == CFE_MI_AVAILABLE) && (mem_cluster_cnt < VM_PHYSSEG_MAX)) { /* * XXX Ignore memory above 256MB for now, it * XXX needs special handling. */ if (start < (256*1024*1024)) { physmem += btoc(((int) len)); mem_clusters[mem_cluster_cnt].start = (long) start; mem_clusters[mem_cluster_cnt].size = (long) len; mem_cluster_cnt++; added = 1; } } if (added) printf("added to map\n"); else printf("not added to map\n"); idx++; } } else { /* * Handle the case of not being called from the firmware. */ /* XXX hardwire to 32MB; should be kernel config option */ physmem = 32 * 1024 * 1024 / 4096; mem_clusters[0].start = 0; mem_clusters[0].size = ctob(physmem); mem_cluster_cnt = 1; } for (i = 0; i < sizeof(bootinfo.boot_flags); i++) { switch (bootinfo.boot_flags[i]) { case '\0': break; case ' ': continue; case '-': while (bootinfo.boot_flags[i] != ' ' && bootinfo.boot_flags[i] != '\0') { switch (bootinfo.boot_flags[i]) { case 'a': boothowto |= RB_ASKNAME; break; case 'd': boothowto |= RB_KDB; break; case 's': boothowto |= RB_SINGLE; break; } i++; } } } /* * Load the rest of the available pages into the VM system. * The first chunk is tricky because we have to avoid the * kernel, but the rest are easy. */ first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); last = mem_clusters[0].start + mem_clusters[0].size; uvm_page_physload(atop(first), atop(last), atop(first), atop(last), VM_FREELIST_DEFAULT); for (i = 1; i < mem_cluster_cnt; i++) { first = round_page(mem_clusters[i].start); last = mem_clusters[i].start + mem_clusters[i].size; uvm_page_physload(atop(first), atop(last), atop(first), atop(last), VM_FREELIST_DEFAULT); } /* * Initialize error message buffer (at end of core). */ mips_init_msgbuf(); /* * Allocate space for proc0's USPACE */ p0 = (void *)pmap_steal_memory(USPACE, NULL, NULL); lwp0.l_addr = proc0paddr = (struct user *)p0; lwp0.l_md.md_regs = (struct frame *)((char *)p0 + USPACE) - 1; proc0paddr->u_pcb.pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ pmap_bootstrap(); /* * Initialize debuggers, and break into them, if appropriate. */ #if NKSYMS || defined(DDB) || defined(LKM) ksyms_init(((uintptr_t)ksym_end - (uintptr_t)ksym_start), ksym_start, ksym_end); #endif if (boothowto & RB_KDB) { #if defined(DDB) Debugger(); #endif } }
/* * prom_init is called just after the cpu type is determined, from setup_arch() */ void __init prom_init(void) { uint64_t cfe_ept, cfe_handle; unsigned int cfe_eptseal; int argc = fw_arg0; char **envp = (char **) fw_arg2; int *prom_vec = (int *) fw_arg3; _machine_restart = cfe_linux_restart; _machine_halt = cfe_linux_halt; _machine_power_off = cfe_linux_halt; /* * Check if a loader was used; if NOT, the 4 arguments are * what CFE gives us (handle, 0, EPT and EPTSEAL) */ if (argc < 0) { cfe_handle = (uint64_t)(long)argc; cfe_ept = (long)envp; cfe_eptseal = (uint32_t)(unsigned long)prom_vec; } else { if ((int32_t)(long)prom_vec < 0) { /* * Old loader; all it gives us is the handle, * so use the "known" entrypoint and assume * the seal. */ cfe_handle = (uint64_t)(long)prom_vec; cfe_ept = (uint64_t)((int32_t)0x9fc00500); cfe_eptseal = CFE_EPTSEAL; } else { /* * Newer loaders bundle the handle/ept/eptseal * Note: prom_vec is in the loader's useg * which is still alive in the TLB. */ cfe_handle = (uint64_t)((int32_t *)prom_vec)[0]; cfe_ept = (uint64_t)((int32_t *)prom_vec)[2]; cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3]; } } if (cfe_eptseal != CFE_EPTSEAL) { /* too early for panic to do any good */ prom_printf("CFE's entrypoint seal doesn't match. Spinning."); while (1) ; } cfe_init(cfe_handle, cfe_ept); /* * Get the handle for (at least) prom_putchar, possibly for * boot console */ cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) { if (argc < 0) { /* * It's OK for direct boot to not provide a * command line */ strcpy(arcs_cmdline, "root=/dev/ram0 "); #ifdef CONFIG_SIBYTE_PTSWARM strcat(arcs_cmdline, "console=ttyS0,115200 "); #endif } else { /* The loader should have set the command line */ /* too early for panic to do any good */ prom_printf("LINUX_CMDLINE not defined in cfe."); while (1) ; } } #ifdef CONFIG_BLK_DEV_INITRD { char *ptr; /* Need to find out early whether we've got an initrd. So scan the list looking now */ for (ptr = arcs_cmdline; *ptr; ptr++) { while (*ptr == ' ') { ptr++; } if (!strncmp(ptr, "initrd=", 7)) { initrd_setup(ptr+7); break; } else { while (*ptr && (*ptr != ' ')) { ptr++; } } } } #endif /* CONFIG_BLK_DEV_INITRD */ /* Not sure this is needed, but it's the safe way. */ arcs_cmdline[CL_SIZE-1] = 0; mips_machgroup = MACH_GROUP_SIBYTE; prom_meminit(); }
extern "C" void start(uint64 cfeHandle, uint64 cfeEntry) { char bootargs[512]; // stage2 args - might be set via the command line one day stage2_args args; args.heap_size = HEAP_SIZE; args.arguments = NULL; cfe_init(cfeHandle, cfeEntry); // check for arguments #if 0//OF if (of_getprop(gChosen, "bootargs", bootargs, sizeof(bootargs)) != OF_FAILED) { static const char *sArgs[] = { NULL, NULL }; sArgs[0] = (const char *)bootargs; args.arguments = sArgs; args.arguments_count = 1; } #endif #if 0//OF determine_machine(); #endif console_init(); // XXX:FIXME: doesn't even land here. dprintf("testing...\n"); while (true); #if 0//OF if ((gMachine & MACHINE_QEMU) != 0) dprintf("OpenBIOS (QEMU?) OpenFirmware machine detected\n"); else if ((gMachine & MACHINE_PEGASOS) != 0) dprintf("Pegasos PowerPC machine detected\n"); else dprintf("Apple PowerPC machine assumed\n"); #endif // Initialize and take over MMU and set the OpenFirmware callbacks - it // will ask us for memory after that instead of maintaining it itself // (the kernel will need to adjust the callback later on as well) arch_mmu_init(); if (boot_arch_cpu_init() != B_OK) cfe_exit(CFE_FLG_WARMSTART, 1); #if 0//OF FIXME if (init_real_time_clock() != B_OK) cfe_exit(CFE_FLG_WARMSTART, 1); #endif // check for key presses once sBootOptions = 0; int key = console_check_for_key(); if (key == 32) { // space bar: option menu sBootOptions |= BOOT_OPTION_MENU; } else if (key == 27) { // ESC: debug output sBootOptions |= BOOT_OPTION_DEBUG_OUTPUT; } gKernelArgs.platform_args.cfe_entry = cfeEntry; main(&args); // if everything goes fine, main() never returns cfe_exit(CFE_FLG_WARMSTART, 1); }
/* Initialize hardware. Called from crt0. */ void hardware_init_hook(void) { cfe_init (__cfe_handle, __cfe_entrypt); cfe_conshandle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); }
int cfe_commit(void) { DECLARE_WAITQUEUE(wait, current); wait_queue_head_t wait_q; struct erase_info erase; // unsigned int i; int ret; size_t erasesize, len; u_int32_t offset; // char *buf; if(!cfe_buf||!cfe_mtd) cfe_init(); if(!cfe_mtd||!cfe_buf) { ret = - ENOMEM; goto done; } /* Backup sector blocks to be erased */ erasesize = ROUNDUP(CFE_NVRAM_SPACE, cfe_mtd->erasesize); down(&nvram_sem); /* Erase sector blocks */ init_waitqueue_head(&wait_q); for (offset=CFE_NVRAM_START;offset <= CFE_NVRAM_END;offset += cfe_mtd->erasesize) { erase.mtd = cfe_mtd; erase.addr = offset; erase.len = cfe_mtd->erasesize; erase.callback = erase_callback; erase.priv = (u_long) &wait_q; set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&wait_q, &wait); /* Unlock sector blocks */ if (cfe_mtd->unlock) cfe_mtd->unlock(cfe_mtd, offset, cfe_mtd->erasesize); if ((ret = cfe_mtd->erase(cfe_mtd, &erase))) { set_current_state(TASK_RUNNING); remove_wait_queue(&wait_q, &wait); printk("cfe_commit: erase error\n"); goto done; } /* Wait for erase to finish */ schedule(); remove_wait_queue(&wait_q, &wait); } ret = cfe_mtd->write(cfe_mtd, CFE_NVRAM_START, erasesize, &len, cfe_buf); /* printk("Write offset: %x %x %x\n", ret, len, erasesize); */ if (ret || len != erasesize) { printk("cfe_commit: write error\n"); ret = -EIO; } done: up(&nvram_sem); if (cfe_mtd) { put_mtd_device(cfe_mtd); cfe_mtd=NULL; } if(cfe_buf) { kfree(cfe_buf); cfe_buf=NULL; } /* printk("commit: %d\n", ret); */ return ret; }
/* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)boot.c 8.1 (Berkeley) 6/10/93 */ #include <lib/libsa/stand.h> #include <lib/libkern/libkern.h> #include <lib/libsa/loadfile.h> #include <sys/param.h> #include <sys/exec.h> #include <sys/exec_ecoff.h> #include "stand/common/common.h" #include "stand/common/cfe_api.h" #include <machine/autoconf.h> #if !defined(UNIFIED_BOOTBLOCK) && !defined(SECONDARY_BOOTBLOCK) #error not UNIFIED_BOOTBLOCK and not SECONDARY_BOOTBLOCK #endif char boot_file[128]; char boot_flags[128]; extern int debug; struct bootinfo_v1 bootinfo; paddr_t ffp_save, ptbr_save; int debug; char *kernelnames[] = { "netbsd", "netbsd.gz", "netbsd.bak", "netbsd.bak.gz", "netbsd.old", "netbsd.old.gz", "onetbsd", "onetbsd.gz", "netbsd.mips", "netbsd.mips.gz", NULL }; int #if defined(UNIFIED_BOOTBLOCK) main(long fwhandle,long evector,long fwentry,long fwseal) #else /* defined(SECONDARY_BOOTBLOCK) */ main(long fwhandle,long fd,long fwentry) #endif { char *name, **namep; u_long marks[MARK_MAX]; u_int32_t entry; int win; /* Init prom callback vector. */ cfe_init(fwhandle,fwentry); /* Init the console device */ init_console(); /* print a banner */ printf("\n"); printf("NetBSD/sbmips " NETBSD_VERS " " BOOT_TYPE_NAME " Bootstrap, Revision %s\n", bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); printf("\n"); /* set up the booted device descriptor */ #if defined(UNIFIED_BOOTBLOCK) if (!booted_dev_open()) { printf("Boot device (%s) open failed.\n", booted_dev_name[0] ? booted_dev_name : "unknown"); goto fail; } #else /* defined(SECONDARY_BOOTBLOCK) */ booted_dev_setfd(fd); #endif printf("\n"); boot_file[0] = 0; cfe_getenv("KERNEL_FILE",boot_file,sizeof(boot_file)); boot_flags[0] = 0; cfe_getenv("BOOT_FLAGS",boot_flags,sizeof(boot_flags)); if (boot_file[0] != 0) (void)printf("Boot file: %s\n", boot_file); (void)printf("Boot flags: %s\n", boot_flags); if (strchr(boot_flags, 'i') || strchr(boot_flags, 'I')) { printf("Boot file: "); gets(boot_file); } memset(marks, 0, sizeof marks); if (boot_file[0] != '\0') win = loadfile(name = boot_file, marks, LOAD_KERNEL) == 0; else for (namep = kernelnames, win = 0; *namep != NULL && !win; namep++) win = loadfile(name = *namep, marks, LOAD_KERNEL) == 0; entry = marks[MARK_ENTRY]; booted_dev_close(); printf("\n"); if (!win) goto fail; (void)printf("Entering %s at 0x%lx...\n", name, (long)entry); cfe_flushcache(0); bzero(&bootinfo,sizeof(bootinfo)); bootinfo.version = BOOTINFO_VERSION; bootinfo.reserved = 0; bootinfo.ssym = marks[MARK_SYM]; bootinfo.esym = marks[MARK_END]; strncpy(bootinfo.boot_flags,boot_flags,sizeof(bootinfo.boot_flags)); strncpy(bootinfo.booted_kernel,name,sizeof(bootinfo.booted_kernel)); bootinfo.fwhandle = fwhandle; bootinfo.fwentry = fwentry; (*(void (*)(long,long,long,long))entry)(fwhandle, BOOTINFO_MAGIC, (long)&bootinfo, fwentry); (void)printf("KERNEL RETURNED!\n"); fail: (void)printf("Boot failed! Halting...\n"); halt(); return 1; }
void __init prom_init(void) { char *ptr; cfe_init(cfe_handle, cfe_entry); bchip_check_compat(); board_pinmux_setup(); bchip_mips_setup(); set_board_nmi_handler(); /* default to SATA (where available) or MTD rootfs */ #ifdef CONFIG_BRCM_HAS_SATA ROOT_DEV = Root_SDA1; #else ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0); #endif root_mountflags &= ~MS_RDONLY; bchip_set_features(); #if defined(CONFIG_BRCM_IKOS_DEBUG) strcpy(arcs_cmdline, "debug initcall_debug"); #elif !defined(CONFIG_BRCM_IKOS) cfe_read_configuration(); #endif brcm_setup_early_printk(); #ifdef CONFIG_CMDLINE_BOOL #ifdef CONFIG_CMDLINE_OVERRIDE strlcpy(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE); #else if (builtin_cmdline[0]) { strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE); } #endif #endif /* provide "ubiroot" alias to reduce typing */ if (strstr(arcs_cmdline, "ubiroot")) strcat(arcs_cmdline, " ubi.mtd=rootfs rootfstype=ubifs " "root=ubi0:rootfs"); ptr = strstr(arcs_cmdline, "memc1="); if (ptr) brcm_dram1_linux_mb = memparse(ptr + 6, &ptr) >> 20; printk(KERN_INFO "Options: enet_en=%d enet0_mii=%d enet_no_mdio=%d " "enet1_en=%d moca=%d\n", brcm_enet_enabled, brcm_enet0_force_ext_mii, brcm_enet_no_mdio, brcm_enet1_enabled, brcm_moca_enabled); printk(KERN_INFO " sata=%d docsis=%d pci=%d pcie=%d smp=%d " "usb=%d\n", brcm_sata_enabled, brcm_docsis_platform, brcm_pci_enabled, brcm_pcie_enabled, brcm_smp_enabled, brcm_usb_enabled); bchip_early_setup(); board_get_ram_size(&brcm_dram0_size_mb, &brcm_dram1_size_mb); do { unsigned long dram0_mb = brcm_dram0_size_mb, mb; mb = min(dram0_mb, BRCM_MAX_LOWER_MB); dram0_mb -= mb; add_memory_region(0, mb << 20, BOOT_MEM_RAM); if (!dram0_mb) break; #ifdef CONFIG_BRCM_UPPER_MEMORY mb = min(dram0_mb, BRCM_MAX_UPPER_MB); dram0_mb -= mb; brcm_upper_tlb_setup(); add_memory_region(UPPERMEM_START, mb << 20, BOOT_MEM_RAM); if (!dram0_mb) break; #endif #if defined(CONFIG_HIGHMEM) add_memory_region(HIGHMEM_START, dram0_mb << 20, BOOT_MEM_RAM); break; #endif /* * We wound up here because the chip's architecture cannot * make use of all MEMC0 RAM in Linux. i.e. no suitable * HIGHMEM or upper memory options are supported by the CPU. * * But we can still report the excess memory as a "bonus" * reserved (bmem) region, so the application can manage it. */ mb = brcm_dram0_size_mb - dram0_mb; /* Linux memory */ if (!brcm_dram1_size_mb && mb == 256) { printk(KERN_INFO "MEMC0 split: %lu MB -> Linux; " "%lu MB -> extra bmem\n", mb, dram0_mb); brcm_dram1_size_mb = dram0_mb; brcm_dram1_start = UPPERMEM_START; } } while (0); #if defined(CONFIG_HIGHMEM) && defined(CONFIG_BRCM_HAS_1GB_MEMC1) if (brcm_dram1_linux_mb > brcm_dram1_size_mb) { printk(KERN_WARNING "warning: 'memc1=%luM' exceeds " "available memory (%lu MB); ignoring\n", brcm_dram1_linux_mb, brcm_dram1_size_mb); brcm_dram1_linux_mb = 0; } else if (brcm_dram1_linux_mb) { /* Since the bootloader can only map the first 256M of memc1 * when it boots, if we get memc1= request from bootloader, we * should try to pull the memory from the end to avoid crossing * over the memory that is allocated for boot logo image by * bootloader. */ unsigned long start_mb, start_b, size, splash_bound = 0; if (0 == parse_splash_mem(arcs_cmdline, &splash_bound, &size)) { splash_bound += size; } start_mb = brcm_dram1_size_mb - brcm_dram1_linux_mb; start_b = start_mb << 20; if (splash_bound > start_b) { unsigned long orig_dram1 = brcm_dram1_linux_mb; start_mb = (splash_bound + 0x000FFFFF) >> 20; start_b = start_mb << 20; brcm_dram1_linux_mb = brcm_dram1_size_mb - start_mb; printk(KERN_WARNING "warning: 'memc1=%luM' starts " " before splash memory bound (0x%lx);" " adjusting to (memc1=%luM)\n", orig_dram1, splash_bound, brcm_dram1_linux_mb); } printk(KERN_INFO "memc1: adding %luMB at %luMB " "(0x%08lx@0x%08lx)", brcm_dram1_linux_mb, (MEMC1_START >> 20) + start_mb, brcm_dram1_linux_mb << 20, MEMC1_START + start_b); add_memory_region(MEMC1_START + start_b, brcm_dram1_linux_mb << 20, BOOT_MEM_RAM); }