/* * Do all the stuff that locore normally does before calling main(). * Process arguments passed to us by the prom monitor. * Return the first page address following the system. */ void mach_init(int x_boothowto, int x_bootdev, int x_bootname, int x_maxmem) { u_long first, last; char *kernend; struct btinfo_magic *bi_magic; struct btinfo_bootarg *bi_arg; struct btinfo_systype *bi_systype; #if NKSYMS || defined(DDB) || defined(MODULAR) struct btinfo_symtab *bi_sym; int nsym = 0; char *ssym, *esym; ssym = esym = NULL; /* XXX: gcc */ #endif bi_arg = NULL; bootinfo = (void *)BOOTINFO_ADDR; /* XXX */ bi_magic = lookup_bootinfo(BTINFO_MAGIC); if (bi_magic && bi_magic->magic == BOOTINFO_MAGIC) { bi_arg = lookup_bootinfo(BTINFO_BOOTARG); if (bi_arg) { x_boothowto = bi_arg->howto; x_bootdev = bi_arg->bootdev; x_maxmem = bi_arg->maxmem; } #if NKSYMS || defined(DDB) || defined(MODULAR) bi_sym = lookup_bootinfo(BTINFO_SYMTAB); if (bi_sym) { nsym = bi_sym->nsym; ssym = (void *)bi_sym->ssym; esym = (void *)bi_sym->esym; } #endif bi_systype = lookup_bootinfo(BTINFO_SYSTYPE); if (bi_systype) systype = bi_systype->type; } else { /* * Running kernel is loaded by non-native loader; * clear the BSS segment here. */ memset(edata, 0, end - edata); } if (systype == 0) systype = NEWS3400; /* XXX compatibility for old boot */ #ifdef news5000 if (systype == NEWS5000) { int i; char *bootspec = (char *)x_bootdev; if (bi_arg == NULL) panic("news5000 requires BTINFO_BOOTARG to boot"); _sip = (void *)bi_arg->sip; x_maxmem = _sip->apbsi_memsize; x_maxmem -= 0x00100000; /* reserve 1MB for ROM monitor */ if (strncmp(bootspec, "scsi", 4) == 0) { x_bootdev = (5 << 28) | 0; /* magic, sd */ bootspec += 4; if (*bootspec != '(' /*)*/) goto bootspec_end; i = strtoul(bootspec + 1, &bootspec, 10); x_bootdev |= (i << 24); /* bus */ if (*bootspec != ',') goto bootspec_end; i = strtoul(bootspec + 1, &bootspec, 10); x_bootdev |= (i / 10) << 20; /* controller */ x_bootdev |= (i % 10) << 16; /* unit */ if (*bootspec != ',') goto bootspec_end; i = strtoul(bootspec + 1, &bootspec, 10); x_bootdev |= (i << 8); /* partition */ } bootspec_end: consinit(); } #endif /* * Save parameters into kernel work area. */ *(int *)(MIPS_PHYS_TO_KSEG1(MACH_MAXMEMSIZE_ADDR)) = x_maxmem; *(int *)(MIPS_PHYS_TO_KSEG1(MACH_BOOTDEV_ADDR)) = x_bootdev; *(int *)(MIPS_PHYS_TO_KSEG1(MACH_BOOTSW_ADDR)) = x_boothowto; kernend = (char *)mips_round_page(end); #if NKSYMS || defined(DDB) || defined(MODULAR) if (nsym) kernend = (char *)mips_round_page(esym); #endif /* * Set the VM page size. */ uvm_setpagesize(); boothowto = x_boothowto; bootdev = x_bootdev; physmem = btoc(x_maxmem); /* * Now that we know how much memory we have, initialize the * mem cluster array. */ mem_clusters[0].start = 0; /* XXX is this correct? */ mem_clusters[0].size = ctob(physmem); mem_cluster_cnt = 1; /* * Copy exception-dispatch code down to exception vector. * Initialize locore-function vector. * Clear out the I and D caches. */ mips_vector_init(NULL, false); /* * We know the CPU type now. Initialize our DMA tags (might * need this early). */ newsmips_bus_dma_init(); #if NKSYMS || defined(DDB) || defined(MODULAR) if (nsym) ksyms_addsyms_elf(esym - ssym, ssym, esym); #endif #ifdef KADB boothowto |= RB_KDB; #endif /* * Check to see if a mini-root was loaded into memory. It resides * at the start of the next page just after the end of BSS. */ if (boothowto & RB_MINIROOT) kernend += round_page(mfs_initminiroot(kernend)); /* * Load the rest of the available pages into the VM system. */ 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); /* * Initialize error message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Allocate uarea page for lwp0 and set it. */ mips_init_lwp0_uarea(); /* * Determine what model of computer we are running on. */ switch (systype) { #ifdef news3400 case NEWS3400: news3400_init(); strcpy(cpu_model, idrom.id_machine); if (strcmp(cpu_model, "news3400") == 0 || strcmp(cpu_model, "news3200") == 0 || strcmp(cpu_model, "news3700") == 0) { /* * Set up interrupt handling and I/O addresses. */ hardware_intr = news3400_intr; cpuspeed = 10; } else { printf("kernel not configured for machine %s\n", cpu_model); } break; #endif #ifdef news5000 case NEWS5000: news5000_init(); strcpy(cpu_model, idrom.id_machine); if (strcmp(cpu_model, "news5000") == 0 || strcmp(cpu_model, "news5900") == 0) { /* * Set up interrupt handling and I/O addresses. */ hardware_intr = news5000_intr; cpuspeed = 50; /* ??? XXX */ } else { printf("kernel not configured for machine %s\n", cpu_model); } break; #endif default: printf("kernel not configured for systype %d\n", systype); break; } }
/* * Do all the stuff that locore normally does before calling main(). */ void mach_init(int32_t memsize32, u_int bim, int32_t bip32) { intptr_t memsize = (int32_t)memsize32; char *kernend; char *bip = (char *)(intptr_t)(int32_t)bip32; u_long first, last; extern char edata[], end[]; const char *bi_msg; #if NKSYMS || defined(DDB) || defined(MODULAR) char *ssym = 0; struct btinfo_symtab *bi_syms; #endif struct btinfo_howto *bi_howto; /* * Clear the BSS segment (if needed). */ if (memcmp(((Elf_Ehdr *)end)->e_ident, ELFMAG, SELFMAG) == 0 && ((Elf_Ehdr *)end)->e_ident[EI_CLASS] == ELFCLASS) { esym = end; #if NKSYMS || defined(DDB) || defined(MODULAR) esym += ((Elf_Ehdr *)end)->e_entry; #endif kernend = (char *)mips_round_page(esym); /* * We don't have to clear BSS here * since our bootloader already does it. */ #if 0 memset(edata, 0, end - edata); #endif } else { kernend = (void *)mips_round_page(end); /* * No symbol table, so assume we are loaded by * the firmware directly with "bfd" command. * The firmware loader doesn't clear BSS of * a loaded kernel, so do it here. */ memset(edata, 0, kernend - edata); } /* * Copy exception-dispatch code down to exception vector. * Initialize locore-function vector. * Clear out the I and D caches. */ mips_vector_init(NULL, false); /* Check for valid bootinfo passed from bootstrap */ if (bim == BOOTINFO_MAGIC) { struct btinfo_magic *bi_magic; bootinfo = bip; bi_magic = lookup_bootinfo(BTINFO_MAGIC); if (bi_magic == NULL) { bi_msg = "missing bootinfo structure"; bim = (uintptr_t)bip; } else if (bi_magic->magic != BOOTINFO_MAGIC) { bi_msg = "invalid bootinfo structure"; bim = bi_magic->magic; } else bi_msg = NULL; } else { bi_msg = "invalid bootinfo (standalone boot?)"; } #if NKSYMS || defined(DDB) || defined(MODULAR) bi_syms = lookup_bootinfo(BTINFO_SYMTAB); /* Load symbol table if present */ if (bi_syms != NULL) { ssym = (void *)(intptr_t)bi_syms->ssym; esym = (void *)(intptr_t)bi_syms->esym; kernend = (void *)mips_round_page(esym); } #endif bi_howto = lookup_bootinfo(BTINFO_HOWTO); if (bi_howto != NULL) boothowto = bi_howto->bi_howto; cobalt_id = read_board_id(); if (cobalt_id >= COBALT_MODELS || cobalt_model[cobalt_id] == NULL) cpu_setmodel("Cobalt unknown model (board ID %u)", cobalt_id); else cpu_setmodel("%s", cobalt_model[cobalt_id]); switch (cobalt_id) { case COBALT_ID_QUBE2700: case COBALT_ID_RAQ: cpuspeed = 150; /* MHz */ break; case COBALT_ID_QUBE2: case COBALT_ID_RAQ2: cpuspeed = 250; /* MHz */ break; default: /* assume the fastest, so that delay(9) works */ cpuspeed = 250; break; } curcpu()->ci_cpu_freq = cpuspeed * 1000 * 1000; curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; curcpu()->ci_divisor_delay = ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000); /* all models have Rm5200, which is CPU_MIPS_DOUBLE_COUNT */ curcpu()->ci_cycles_per_hz /= 2; curcpu()->ci_divisor_delay /= 2; physmem = btoc(memsize - MIPS_KSEG0_START); consinit(); KASSERT(&lwp0 == curlwp); if (bi_msg != NULL) printf("%s: magic=%#x bip=%p\n", bi_msg, bim, bip); uvm_setpagesize(); /* * The boot command is passed in the top 512 bytes, * so don't clobber that. */ mem_clusters[0].start = 0; mem_clusters[0].size = ctob(physmem) - 512; mem_cluster_cnt = 1; memcpy(bootstring, (char *)(memsize - 512), 512); memset((char *)(memsize - 512), 0, 512); bootstring[511] = '\0'; decode_bootstring(); #if NKSYMS || defined(DDB) || defined(MODULAR) /* init symbols if present */ if ((bi_syms != NULL) && (esym != NULL)) ksyms_addsyms_elf(esym - ssym, ssym, esym); #endif KASSERT(&lwp0 == curlwp); #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif #ifdef KGDB if (boothowto & RB_KDB) kgdb_connect(0); #endif /* * Load the rest of the available pages into the VM system. */ 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); /* * Initialize error message buffer (at end of core). */ mips_init_msgbuf(); pmap_bootstrap(); /* * Allocate space for proc0's USPACE. */ mips_init_lwp0_uarea(); }
void mach_init(void) { void *kernend; uint32_t memsize; extern char edata[], end[]; /* XXX */ /* clear the BSS segment */ kernend = (void *)mips_round_page(end); memset(edata, 0, (char *)kernend - edata); /* setup early console */ atheros_set_platformsw(); /* set CPU model info for sysctl_hw */ snprintf(cpu_model, 64, "Atheros %s", atheros_get_cpuname()); /* * Set up the exception vectors and CPU-specific function * vectors early on. We need the wbflush() vector set up * before comcnattach() is called (or at least before the * first printf() after that is called). * Sets up mips_cpu_flags that may be queried by other * functions called during startup. * Also clears the I+D caches. */ mips_vector_init(NULL, false); /* * Calibrate timers. */ cal_timer(); /* * Set the VM page size. */ uvm_setpagesize(); /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_AUTOBOOT; #ifdef KADB boothowto |= RB_KDB; #endif /* * This would be a good place to parse a boot command line, if * we got one from the bootloader. Right now we have no way to * get one from e.g. vxworks. */ /* * Determine the memory size. * * Note: Reserve the first page! That's where the trap * vectors are located. */ memsize = atheros_get_memsize(); printf("Memory size: 0x%08x\n", memsize); physmem = btoc(memsize); mem_clusters[mem_cluster_cnt].start = PAGE_SIZE; mem_clusters[mem_cluster_cnt].size = memsize - mem_clusters[mem_cluster_cnt].start; mem_cluster_cnt++; /* * Load the available pages into the VM system. */ mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, mem_clusters, mem_cluster_cnt, NULL, 0); /* * Initialize message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Allocate uarea page for lwp0 and set it. */ mips_init_lwp0_uarea(); /* * Initialize busses. */ atheros_bus_init(); /* * Turn off (ignore) the hardware watchdog. If we got this * far, then we shouldn't need it anymore. */ atheros_wdog_reload(0); /* * Turn off watchpoint that may have been enabled by the * PROM. VxWorks bootloader seems to leave one set. */ __asm volatile ( "mtc0 $0, $%0\n\t" "nop\n\t" "nop\n\t" :: "n"(MIPS_COP_0_WATCH_LO)); /* * Initialize debuggers, and break into them, if appropriate. */ #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif }
void mach_init(void) { void *kernend; uint32_t memsize; extern char edata[], end[]; /* XXX */ /* clear the BSS segment */ kernend = (void *)mips_round_page(end); memset(edata, 0, (char *)kernend - edata); /* setup early console */ ingenic_putchar_init(); /* set CPU model info for sysctl_hw */ cpu_setmodel("Ingenic XBurst"); mips_vector_init(NULL, false); cal_timer(); uvm_setpagesize(); /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_AUTOBOOT; #ifdef KADB boothowto |= RB_KDB; #endif /* * Determine the memory size. * * Note: Reserve the first page! That's where the trap * vectors are located. */ memsize = 0x40000000; printf("Memory size: 0x%08x\n", memsize); physmem = btoc(memsize); /* * memory is at 0x20000000 with first 256MB mirrored to 0x00000000 so * we can see them through KSEG* * assume 1GB for now, the SoC can theoretically support up to 3GB */ mem_clusters[0].start = PAGE_SIZE; mem_clusters[0].size = 0x10000000 - PAGE_SIZE; mem_clusters[1].start = 0x30000000; mem_clusters[1].size = 0x30000000; mem_cluster_cnt = 2; /* * Load the available pages into the VM system. */ mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, mem_clusters, mem_cluster_cnt, NULL, 0); /* * Initialize message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Allocate uarea page for lwp0 and set it. */ mips_init_lwp0_uarea(); #ifdef MULTIPROCESSOR mutex_init(&ingenic_ipi_lock, MUTEX_DEFAULT, IPL_HIGH); mips_locoresw.lsw_send_ipi = ingenic_send_ipi; mips_locoresw.lsw_cpu_init = ingenic_cpu_init; #endif apbus_init(); /* * Initialize debuggers, and break into them, if appropriate. */ #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif }
void mach_init(void) { vaddr_t kernend; psize_t memsize; extern char kernel_text[]; extern char edata[], end[]; /* From Linker */ /* clear the BSS segment */ kernend = mips_round_page(end); memset(edata, 0, kernend - (vaddr_t)edata); #ifdef RALINK_CONSOLE_EARLY /* * set up early console * cannot printf until sometime (?) in mips_vector_init * meanwhile can use the ra_console_putc primitive if necessary */ ralink_console_early(); #endif /* set CPU model info for sysctl_hw */ uint32_t tmp1, tmp2; char id1[5], id2[5]; tmp1 = sysctl_read(RA_SYSCTL_ID0); memcpy(id1, &tmp1, sizeof(tmp1)); tmp2 = sysctl_read(RA_SYSCTL_ID1); memcpy(id2, &tmp2, sizeof(tmp2)); id2[4] = id1[4] = '\0'; if (id2[2] == ' ') { id2[2] = '\0'; } else if (id2[3] == ' ') { id2[3] = '\0'; } else { id2[4] = '\0'; } cpu_setmodel("%s%s", id1, id2); /* * Set up the exception vectors and CPU-specific function * vectors early on. We need the wbflush() vector set up * before comcnattach() is called (or at least before the * first printf() after that is called). * Sets up mips_cpu_flags that may be queried by other * functions called during startup. * Also clears the I+D caches. */ mips_vector_init(NULL, false); /* * Calibrate timers. */ cal_timer(); /* * Set the VM page size. */ uvm_setpagesize(); /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_AUTOBOOT; #ifdef KADB boothowto |= RB_KDB; #endif /* * Determine the memory size. */ #if defined(MT7620) memsize = 128 << 20; #else memsize = *(volatile uint32_t *) MIPS_PHYS_TO_KSEG1(RA_SYSCTL_BASE + RA_SYSCTL_CFG0); memsize = __SHIFTOUT(memsize, SYSCTL_CFG0_DRAM_SIZE); if (__predict_false(memsize == 0)) { memsize = 2 << 20; } else { memsize = 4 << (20 + memsize); } #endif physmem = btoc(memsize); mem_clusters[mem_cluster_cnt].start = 0; mem_clusters[mem_cluster_cnt].size = memsize; mem_cluster_cnt++; /* * Load the memory into the VM system */ mips_page_physload((vaddr_t)kernel_text, kernend, mem_clusters, mem_cluster_cnt, NULL, 0); /* * Initialize message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Init mapping for u page(s) for proc0. */ mips_init_lwp0_uarea(); /* * Initialize busses. */ ra_bus_init(); #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif }
void mach_init(int argc, char **argv, yamon_env_var *envp, u_long memsize) { bus_space_handle_t sh; void *kernend; const char *cp; int freqok, howto, i; const struct alchemy_board *board; extern char edata[], end[]; /* XXX */ board = board_info(); KASSERT(board != NULL); /* clear the BSS segment */ kernend = (void *)mips_round_page(end); memset(edata, 0, (char *)kernend - edata); /* set CPU model info for sysctl_hw */ strcpy(cpu_model, board->ab_name); /* save the yamon environment pointer */ yamon_envp = envp; /* Use YAMON callbacks for early console I/O */ cn_tab = &yamon_promcd; /* * Set up the exception vectors and CPU-specific function * vectors early on. We need the wbflush() vector set up * before comcnattach() is called (or at least before the * first printf() after that is called). * Sets up mips_cpu_flags that may be queried by other * functions called during startup. * Also clears the I+D caches. */ mips_vector_init(NULL, false); /* * Set the VM page size. */ uvm_setpagesize(); /* * Use YAMON's CPU frequency if available. */ freqok = yamon_setcpufreq(1); /* * Initialize bus space tags. */ au_cpureg_bus_mem_init(&alchemy_cpuregt, &alchemy_cpuregt); aubus_st = &alchemy_cpuregt; /* * Calibrate the timer if YAMON failed to tell us. */ if (!freqok) { bus_space_map(aubus_st, PC_BASE, PC_SIZE, 0, &sh); au_cal_timers(aubus_st, sh); bus_space_unmap(aubus_st, sh, PC_SIZE); } /* * Perform board-specific initialization. */ board->ab_init(); /* * Bring up the console. */ #if NCOM > 0 #ifdef CONSPEED if (aucomcnrate == 0) aucomcnrate = CONSPEED; #else /* !CONSPEED */ /* * Learn default console speed. We use the YAMON environment, * though we could probably also figure it out by checking the * aucom registers directly. */ if ((aucomcnrate == 0) && ((cp = yamon_getenv("modetty0")) != NULL)) aucomcnrate = strtoul(cp, NULL, 0); if (aucomcnrate == 0) { printf("FATAL: `modetty0' YAMON variable not set. Set it\n"); printf(" to the speed of the console and try again.\n"); printf(" Or, build a kernel with the `CONSPEED' " "option.\n"); panic("mach_init"); } #endif /* CONSPEED */ /* * Delay to allow firmware putchars to complete. * FIFO depth * character time. * character time = (1000000 / (defaultrate / 10)) */ delay(160000000 / aucomcnrate); if (com_aubus_cnattach(UART0_BASE, aucomcnrate) != 0) panic("mach_init: unable to initialize serial console"); #else /* NCOM > 0 */ panic("mach_init: not configured to use serial console"); #endif /* NAUCOM > 0 */ /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_AUTOBOOT; #ifdef KADB boothowto |= RB_KDB; #endif for (i = 1; i < argc; i++) { for (cp = argv[i]; *cp; cp++) { /* Ignore superfluous '-', if there is one */ if (*cp == '-') continue; howto = 0; BOOT_FLAG(*cp, howto); if (! howto) printf("bootflag '%c' not recognised\n", *cp); else boothowto |= howto; } } /* * Determine the memory size. Use the `memsize' PMON * variable. If that's not available, panic. * * Note: Reserve the first page! That's where the trap * vectors are located. */ #if defined(MEMSIZE) memsize = MEMSIZE; #else if (memsize == 0) { if ((cp = yamon_getenv("memsize")) != NULL) memsize = strtoul(cp, NULL, 0); else { printf("FATAL: `memsize' YAMON variable not set. Set it to\n"); printf(" the amount of memory (in MB) and try again.\n"); printf(" Or, build a kernel with the `MEMSIZE' " "option.\n"); panic("mach_init"); } } #endif /* MEMSIZE */ printf("Memory size: 0x%08lx\n", memsize); physmem = btoc(memsize); mem_clusters[mem_cluster_cnt].start = PAGE_SIZE; mem_clusters[mem_cluster_cnt].size = memsize - mem_clusters[mem_cluster_cnt].start; mem_cluster_cnt++; /* * Load the rest of the available pages into the VM system. */ mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, mem_clusters, mem_cluster_cnt, NULL, 0); /* * Initialize message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Allocate uarea page for lwp0 and set it. */ mips_init_lwp0_uarea(); /* * Initialize debuggers, and break into them, if appropriate. */ #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif }
void mach_init(void) { void *kernend; uint32_t memsize; extern char edata[], end[]; /* XXX */ /* clear the BSS segment */ kernend = (void *)mips_round_page(end); memset(edata, 0, (char *)kernend - edata); /* setup early console */ ingenic_putchar_init(); /* set CPU model info for sysctl_hw */ cpu_setmodel("Ingenic XBurst"); mips_vector_init(NULL, false); cal_timer(); uvm_setpagesize(); /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_AUTOBOOT; #ifdef KADB boothowto |= RB_KDB; #endif /* * Determine the memory size. * * Note: Reserve the first page! That's where the trap * vectors are located. */ memsize = 0x40000000; printf("Memory size: 0x%08x\n", memsize); physmem = btoc(memsize); /* XXX this is CI20 specific */ mem_clusters[0].start = PAGE_SIZE; mem_clusters[0].size = 0x10000000 - PAGE_SIZE; mem_clusters[1].start = 0x30000000; mem_clusters[1].size = 0x30000000; mem_cluster_cnt = 2; /* * Load the available pages into the VM system. */ mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, mem_clusters, mem_cluster_cnt, NULL, 0); /* * Initialize message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Allocate uarea page for lwp0 and set it. */ mips_init_lwp0_uarea(); apbus_init(); /* * Initialize debuggers, and break into them, if appropriate. */ #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif }