void device_register(struct device *dev, void *aux) { struct cfdata *cf = dev->dv_cfdata; const char *name = cf->cf_name; struct aubus_attach_args *aa = aux; /* * We don't ever know the boot device. But that's because the * firmware only loads from the network. */ /* Fetch the MAC addresses from YAMON. */ if (strcmp(name, "aumac") == 0) { uint8_t ethaddr[ETHER_ADDR_LEN]; const char *cp; char *cp0; int i; /* Get the Ethernet address of the first on-board Ethernet. */ #if defined(ETHADDR) cp = ETHADDR; #else cp = yamon_getenv("ethaddr"); #endif if (cp != NULL) { for (i = 0; i < ETHER_ADDR_LEN; i++) { ethaddr[i] = strtoul(cp, &cp0, 16); cp = cp0 + 1; } if (aa->aa_addr != MAC0_BASE && aa->aa_addr != AU1500_MAC0_BASE) { /* XXX * The PROM has a variable for the MAC address * of the first interface. For now, just add * 0x10 to the second last octet(!) for the * second interface (Linux does the same). */ ethaddr[4] += 0x10; } if (prop_set(dev_propdb, dev, "mac-addr", ethaddr, sizeof(ethaddr), 0, 0) != 0) { printf("WARNING: unable to set mac-addr " "property for %s\n", dev->dv_xname); } } } }
void mach_init(int argc, char **argv, yamon_env_var *envp, u_long memsize) { bus_space_handle_t sh; void *kernend; const char *cp; u_long first, last; void *v; 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(); /* * 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. */ 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 message buffer (at end of core). */ mips_init_msgbuf(); /* * Initialize the virtual memory system. */ pmap_bootstrap(); /* * Init mapping for u page(s) for proc0. */ v = (void *) uvm_pageboot_alloc(USPACE); lwp0.l_addr = proc0paddr = (struct user *)v; lwp0.l_md.md_regs = (struct frame *)((char *)v + USPACE) - 1; proc0paddr->u_pcb.pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ /* * Initialize debuggers, and break into them, if appropriate. */ #if NKSYMS || defined(DDB) || defined(LKM) ksyms_init(0, 0, 0); #endif #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif }