int bi_getboothowto(char *kargs) { char *cp; int howto; int active; int i; /* Parse kargs */ howto = 0; if (kargs != NULL) { cp = kargs; active = 0; while (*cp != 0) { if (!active && (*cp == '-')) { active = 1; } else if (active) BOOT_FLAG(*cp, howto); cp++; } } /* get equivalents from the environment */ for (i = 0; howto_names[i].ev != NULL; i++) if (getenv(howto_names[i].ev) != NULL) howto |= howto_names[i].mask; return(howto); }
/* * Early initialization, before main() is called. */ void luna68k_init() { volatile unsigned char *pio0 = (void *)0x49000000; int sw1, i; char *cp; extern char bootarg[64]; extern paddr_t avail_start, avail_end; /* * Tell the VM system about available physical memory. The * luna68k only has one segment. */ uvm_page_physload(atop(avail_start), atop(avail_end), atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT); /* * Initialize error message buffer (at end of core). * avail_end was pre-decremented in pmap_bootstrap to compensate. */ for (i = 0; i < btoc(MSGBUFSIZE); i++) pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE, avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); pmap_update(pmap_kernel()); initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); pio0[3] = 0xb6; pio0[2] = 1 << 6; /* enable parity check */ pio0[3] = 0xb6; sw1 = pio0[0]; /* dipssw1 value */ sw1 ^= 0xff; sysconsole = !(sw1 & 0x2); /* console selection */ boothowto = 0; i = 0; /* * 'bootarg' has; * "<args of x command> ENADDR=<addr> HOST=<host> SERVER=<name>" * where <addr> is MAC address of which network loader used (not * necessarily same as one at 0x4101.FFE0), <host> and <name> * are the values of HOST and SERVER environment variables, * * NetBSD/luna68k cares only the first argment; any of "sda". */ for (cp = bootarg; *cp != ' '; cp++) { BOOT_FLAG(*cp, boothowto); if (i++ >= sizeof(bootarg)) break; } #if 0 /* overload 1:sw1, which now means 'go ROM monitor' after poweron */ if (boothowto == 0) boothowto = (sw1 & 0x1) ? RB_SINGLE : 0; #endif }
void decode_bootstring(void) { char *work; char *equ; int i; /* break apart bootstring on ' ' boundries and itterate */ work = strtok_light(bootstring, ' '); while (work != '\0') { /* if starts with '-', we got options, walk its decode */ if (work[0] == '-') { i = 1; while (work[i] != ' ' && work[i] != '\0') { BOOT_FLAG(work[i], boothowto); i++; } } else /* if it has a '=' its an assignment, switch and set */ if ((equ = strchr(work, '=')) != '\0') { if (memcmp("nfsroot=", work, 8) == 0) { nfsroot_bstr = (equ + 1); } else if (memcmp("root=", work, 5) == 0) { root_bstr = (equ + 1); } } else /* else it a single value, switch and process */ if (memcmp("single", work, 5) == 0) { boothowto |= RB_SINGLE; } else if (memcmp("ro", work, 2) == 0) { /* this is also inserted by the firmware */ } /* grab next token */ work = strtok_light(NULL, ' '); } if (root_bstr != NULL) { /* this should be of the form "/dev/hda1" */ /* [abcd][1234] drive partition linux probe order */ if ((memcmp("/dev/hd", root_bstr, 7) == 0) && (strlen(root_bstr) == 9) ){ bootunit = root_bstr[7] - 'a'; bootpart = root_bstr[8] - '1'; } } if (nfsroot_bstr != NULL) netboot = 1; }
/* * Set the PROM vector handler (for g0, g4, etc.) * and set boothowto from the PROM arg strings. * * Note, args are always: * argv[0] = boot_device (i.e. "sd(0,0,0)") * argv[1] = options (i.e. "-ds" or NULL) * argv[2] = NULL */ void sunmon_init(void) { struct sunromvec *rvec; struct bootparam *bp; char **argp; char *p; rvec = romVectorPtr; bp = *rvec->bootParam; /* Save the PROM monitor Vector Base Register (VBR). */ sunmon_vbr = getvbr(); /* Arrange for "trap #14" to cause a PROM abort. */ sunmon_vbr[32+14] = romVectorPtr->abortEntry; /* Save and replace the "v command" handler. */ sunmon_vcmd = *rvec->vector_cmd; if (rvec->romvecVersion >= 2) *rvec->vector_cmd = v_handler; /* Set boothowto flags from PROM args. */ argp = bp->argPtr; /* Skip argp[0] (the device string) */ argp++; /* Have options? */ if (*argp == NULL) return; p = *argp; if (*p == '-') { /* yes, parse options */ #ifdef DEBUG mon_printf("boot option: %s\n", p); #endif for (++p; *p; p++) BOOT_FLAG(*p, boothowto); argp++; } #ifdef DEBUG /* Have init name? */ if (*argp == NULL) return; p = *argp; mon_printf("boot initpath: %s\n", p); #endif }
int bootoptions(const char *ap) { int v = 0; if (ap == NULL || *ap++ != '-') return (0); while (*ap != '\0' && *ap != ' ' && *ap != '\t' && *ap != '\n') { BOOT_FLAG(*ap, v); if (*ap == 'C') compatmode = 1; ap++; } if ((v & RB_KDB) != 0) debug = 1; return (v); }
static int parseopts(const char *opts, int *howto) { int r, tmpopt = 0; opts++; /* skip - */ while (*opts && *opts != ' ') { r = 0; BOOT_FLAG(*opts, r); if (r == 0) { printf("-%c: unknown flag\n", *opts); bootcmd_help(NULL); return (0); } tmpopt |= r; opts++; } *howto = tmpopt; return (1); }
static void parseargs(char *str, int *howtop) { char *cp; /* Allow user to drop back to the PROM. */ if (strcmp(str, "exit") == 0) OF_exit(); *howtop = 0; for (cp = str; *cp; cp++) if (*cp == ' ' || *cp == '-') goto found; return; found: *cp++ = '\0'; while (*cp) BOOT_FLAG(*cp++, *howtop); }
static void get_bootpath_from_prom(void) { struct btinfo_bootdev *bdev = NULL; char sbuf[OFPATHLEN], *cp; int chosen; /* * Grab boot path from PROM */ if ((chosen = OF_finddevice("/chosen")) == -1) return; bdev = lookup_bootinfo(BTINFO_BOOTDEV); if (bdev != NULL) { strcpy(ofbootpath, bdev->name); } else { if (OF_getprop(chosen, "bootpath", sbuf, sizeof(sbuf)) < 0) return; strcpy(ofbootpath, sbuf); } DPRINTF(ACDB_BOOTDEV, ("bootpath: %s\n", ofbootpath)); ofbootpackage = prom_finddevice(ofbootpath); /* * Strip partition or boot protocol */ cp = strrchr(ofbootpath, ':'); if (cp) { *cp = '\0'; ofbootpartition = cp+1; } cp = strrchr(ofbootpath, '@'); if (cp) { for (; cp != ofbootpath; cp--) { if (*cp == '/') { ofboottarget = cp+1; break; } } } DPRINTF(ACDB_BOOTDEV, ("bootpath phandle: 0x%x\n", ofbootpackage)); DPRINTF(ACDB_BOOTDEV, ("boot target: %s\n", ofboottarget ? ofboottarget : "<none>")); DPRINTF(ACDB_BOOTDEV, ("boot partition: %s\n", ofbootpartition ? ofbootpartition : "<none>")); /* Setup pointer to boot flags */ if (OF_getprop(chosen, "bootargs", sbuf, sizeof(sbuf)) == -1) return; strcpy(ofbootargs, sbuf); cp = ofbootargs; /* Find start of boot flags */ while (*cp) { while(*cp == ' ' || *cp == '\t') cp++; if (*cp == '-' || *cp == '\0') break; while(*cp != ' ' && *cp != '\t' && *cp != '\0') cp++; if (*cp != '\0') *cp++ = '\0'; } if (cp != ofbootargs) ofbootfile = ofbootargs; ofbootflags = cp; if (*cp != '-') return; for (;*++cp;) { int fl; fl = 0; BOOT_FLAG(*cp, fl); if (!fl) { printf("unknown option `%c'\n", *cp); continue; } boothowto |= fl; /* specialties */ if (*cp == 'd') { #if defined(KGDB) kgdb_break_at_attach = 1; #elif defined(DDB) Debugger(); #else printf("kernel has no debugger\n"); #endif } else if (*cp == 't') { /* turn on traptrace w/o breaking into kdb */ extern int trap_trace_dis; trap_trace_dis = 0; } } }
/* * Extract NetBSD boot specification */ static int get_bsdbootname(char **dev, char **kname, int *howtop) { int len; int bootunit, bootpart; char *bootstr_dev, *bootstr_kname; char *prompt_dev, *prompt_kname; char *ptr, *spec; char c, namebuf[PATH_MAX]; static char bootdev[] = "wd0a"; static char nfsbootdev[] = "nfs"; bootstr_dev = prompt_dev = NULL; bootstr_kname = prompt_kname = NULL; /* first, get root device specified by the firmware */ spec = bootstring; /* assume the last one is valid */ while ((spec = strstr(spec, "root=")) != NULL) { spec += 5; /* skip 'root=' */ ptr = strchr(spec, ' '); len = (ptr == NULL) ? strlen(spec) : ptr - spec; /* decode unit and part from "/dev/hd[ab][1-4]" strings */ if (len == 9 && memcmp("/dev/hd", spec, 7) == 0) { bootunit = spec[7] - 'a'; bootpart = spec[8] - '1'; if (bootunit >= 0 && bootunit < 2 && bootpart >= 0 && bootpart < 4) { bootdev[sizeof(bootdev) - 3] = '0' + bootunit; #if 0 /* bootpart is fdisk partition of Linux root */ bootdev[sizeof(bootdev) - 2] = 'a' + bootpart; #endif bootstr_dev = bootdev; } } spec += len; } /* second, get bootname from bootstrings */ if ((spec = strstr(bootstring, "nbsd=")) != NULL) { ptr = strchr(spec, ' '); spec += 5; /* skip 'nbsd=' */ len = (ptr == NULL) ? strlen(spec) : ptr - spec; if (len > 0) { if (parse_bootname(spec, len, &bootstr_dev, &bootstr_kname)) return 1; } } /* third, check if netboot */ if (strstr(bootstring, "nfsroot=") != NULL) { bootstr_dev = nfsbootdev; } DPRINTF(("bootstr_dev = %s, bootstr_kname = %s\n", bootstr_dev ? bootstr_dev : "<NULL>", bootstr_kname ? bootstr_kname : "<NULL>")); spec = NULL; len = 0; memset(namebuf, 0, sizeof namebuf); printf("Boot [%s:%s]: ", bootstr_dev ? bootstr_dev : DEFBOOTDEV, bootstr_kname ? bootstr_kname : DEFKERNELNAME); if (tgets(namebuf) == -1) printf("\n"); ptr = namebuf; while ((c = *ptr) != '\0') { while (c == ' ') c = *++ptr; if (c == '\0') break; if (c == '-') { while ((c = *++ptr) && c != ' ') BOOT_FLAG(c, *howtop); } else { spec = ptr; while ((c = *++ptr) && c != ' ') ; if (c) *ptr++ = '\0'; len = strlen(spec); } } if (len > 0) { if (parse_bootname(spec, len, &prompt_dev, &prompt_kname)) return 1; } DPRINTF(("prompt_dev = %s, prompt_kname = %s\n", prompt_dev ? prompt_dev : "<NULL>", prompt_kname ? prompt_kname : "<NULL>")); if (prompt_dev) *dev = prompt_dev; else *dev = bootstr_dev; if (prompt_kname) *kname = prompt_kname; else *kname = bootstr_kname; DPRINTF(("dev = %s, kname = %s\n", *dev ? *dev : "<NULL>", *kname ? *kname : "<NULL>")); return 0; }
int usr_info(osdsc_t *od) { static char line[800]; char c, *p = line; printf("\nEnter os-type [.%s] root-fs [:a] kernel [%s]" " options [none]:\n\033e", od->ostype, od->osname); gets(p); printf("\033f"); for (;;) { while (isspace(*p)) *p++ = '\0'; switch (*p++) { case '\0': goto done; case ':': if ((c = *p) >= 'a' && c <= 'z') od->rootfs = c - 'a'; else if (c >= 'A' && c <= 'Z') od->rootfs = c - ('A' - 27); else return -1; if (!od->rootfs) break; *p = 'b'; /* FALLTHROUGH */ case '-': if ((c = *p) == 'a') od->boothowto &= ~RB_SINGLE; else if (c == 'b') od->boothowto |= RB_ASKNAME; else BOOT_FLAG(c, od->boothowto); break; case '.': od->ostype = p; break; case '/': od->osname = --p; break; default: return -1; } while ((c = *p) && !isspace(c)) p += 1; } done: c = od->ostype[0]; if (isupper(c)) c = tolower(c); switch (c) { case 'n': /* NetBSD */ return 0; case 'l': /* Linux */ return 0x10; case 'a': /* ASV */ return 0x40; case 't': /* TOS */ return 0x80; default: return -1; } }
static int bootoptions(const char *ap, char *loaddev, char *kernel, char *options) { int v = 0; const char *start1 = NULL, *end1 = NULL, *start2 = NULL, *end2 = NULL; const char *path; char partition, *pp; *kernel = '\0'; *options = '\0'; if (ap == NULL) { return (0); } while (*ap == ' ') { ap++; } if (*ap != '-') { start1 = ap; while (*ap != '\0' && *ap != ' ') { ap++; } end1 = ap; while (*ap == ' ') { ap++; } if (*ap != '-') { start2 = ap; while (*ap != '\0' && *ap != ' ') { ap++; } end2 = ap; while (*ap != '\0' && *ap == ' ') { ap++; } } } if (end2 == start2) { start2 = end2 = NULL; } if (end1 == start1) { start1 = end1 = NULL; } if (start1 == NULL) { /* only options */ } else if (start2 == NULL) { memcpy(kernel, start1, (end1 - start1)); kernel[end1 - start1] = '\0'; path = filename(kernel, &partition); if (path == NULL) { strcpy(loaddev, kernel); kernel[0] = '\0'; } else if (path != kernel) { /* copy device part */ memcpy(loaddev, kernel, path-kernel); loaddev[path-kernel] = '\0'; if (partition) { pp = loaddev + strlen(loaddev); pp[0] = ':'; pp[1] = partition; pp[2] = '\0'; } /* and kernel path */ strcpy(kernel, path); } } else { memcpy(loaddev, start1, (end1-start1)); loaddev[end1-start1] = '\0'; memcpy(kernel, start2, (end2 - start2)); kernel[end2 - start2] = '\0'; } twiddle_toggle = 1; strcpy(options, ap); while (*ap != '\0' && *ap != ' ' && *ap != '\t' && *ap != '\n') { BOOT_FLAG(*ap, v); switch(*ap++) { case 'D': debug = 2; break; case 'C': compatmode = 1; break; case 'T': twiddle_toggle = 1 - twiddle_toggle; break; default: break; } } if (((v & RB_KDB) != 0) && (debug == 0)) { debug = 1; } DPRINTF(("bootoptions: device='%s', kernel='%s', options='%s'\n", loaddev, kernel, options)); return (v); }
/* * Early initialization, before main() is called. */ void luna68k_init(void) { volatile uint8_t *pio0 = (void *)0x49000000; int sw1, i; char *cp; extern char bootarg[64]; extern paddr_t avail_start, avail_end; /* initialize cn_tab for early console */ #if 1 cn_tab = &syscons; #else cn_tab = &romcons; #endif /* * Tell the VM system about available physical memory. The * luna68k only has one segment. */ uvm_page_physload(atop(avail_start), atop(avail_end), atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT); /* * Initialize error message buffer (at end of core). * avail_end was pre-decremented in pmap_bootstrap to compensate. */ for (i = 0; i < btoc(MSGBUFSIZE); i++) pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE, avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 0); pmap_update(pmap_kernel()); initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); pio0[3] = 0xb6; pio0[2] = 1 << 6; /* enable parity check */ pio0[3] = 0xb6; sw1 = pio0[0]; /* dip sw1 value */ sw1 ^= 0xff; sysconsole = !(sw1 & 0x2); /* console selection */ /* * Check if boothowto and bootdev values are passed by our bootloader. */ if ((bootdev & B_MAGICMASK) == B_DEVMAGIC) { /* Valid value is set; no need to parse bootarg. */ return; } /* * No valid bootdev value is set. * Assume we are booted by ROM monitor directly using a.out kernel * and we have to parse bootarg passed from the monitor to set * proper boothowto and check netboot. */ /* set default to "sd0a" with no howto flags */ bootdev = MAKEBOOTDEV(0, LUNA68K_BOOTADPT_SPC, 0, 0, 0); boothowto = 0; /* * 'bootarg' on LUNA has: * "<args of x command> ENADDR=<addr> HOST=<host> SERVER=<name>" * where <addr> is MAC address of which network loader used (not * necessarily same as one at 0x4101.FFE0), <host> and <name> * are the values of HOST and SERVER environment variables. * * 'bootarg' on LUNA-II has "<args of x command>" only. * * NetBSD/luna68k cares only the first argment; any of "sda". */ bootarg[63] = '\0'; for (cp = bootarg; *cp != '\0'; cp++) { if (*cp == '-') { char c; while ((c = *cp) != '\0' && c != ' ') { BOOT_FLAG(c, boothowto); cp++; } } else if (*cp == 'E' && memcmp("ENADDR=", cp, 7) == 0) { bootdev = MAKEBOOTDEV(0, LUNA68K_BOOTADPT_LANCE, 0, 0, 0); } } }
static void bootpath_build(void) { const char *cp; char *pp; struct bootpath *bp; int fl; /* * Grab boot path from PROM and split into `bootpath' components. */ memset(bootpath, 0, sizeof(bootpath)); bp = bootpath; cp = prom_getbootpath(); switch (prom_version()) { case PROM_OLDMON: case PROM_OBP_V0: /* * Build fake bootpath. */ if (cp != NULL) bootpath_fake(bp, cp); break; case PROM_OBP_V2: case PROM_OBP_V3: case PROM_OPENFIRM: while (cp != NULL && *cp == '/') { /* Step over '/' */ ++cp; /* Extract name */ pp = bp->name; while (*cp != '@' && *cp != '/' && *cp != '\0') *pp++ = *cp++; *pp = '\0'; #if defined(SUN4M) /* * JS1/OF does not have iommu node in the device * tree, so bootpath will start with the sbus entry. * Add entry for iommu to match attachment. See also * mainbus_attach and iommu_attach. */ if (CPU_ISSUN4M && bp == bootpath && strcmp(bp->name, "sbus") == 0) { printf("bootpath_build: inserting iommu entry\n"); strcpy(bootpath[0].name, "iommu"); bootpath[0].val[0] = 0; bootpath[0].val[1] = 0x10000000; bootpath[0].val[2] = 0; ++nbootpath; strcpy(bootpath[1].name, "sbus"); if (*cp == '/') { /* complete sbus entry */ bootpath[1].val[0] = 0; bootpath[1].val[1] = 0x10001000; bootpath[1].val[2] = 0; ++nbootpath; bp = &bootpath[2]; continue; } else bp = &bootpath[1]; } #endif /* SUN4M */ if (*cp == '@') { cp = str2hex(++cp, &bp->val[0]); if (*cp == ',') cp = str2hex(++cp, &bp->val[1]); if (*cp == ':') { /* XXX - we handle just one char */ /* skip remainder of paths */ /* like "ledma@f,400010:tpe" */ bp->val[2] = *++cp - 'a'; while (*++cp != '/' && *cp != '\0') /*void*/; } } else { bp->val[0] = -1; /* no #'s: assume unit 0, no sbus offset/address */ } ++bp; ++nbootpath; } bp->name[0] = 0; break; } bootpath_print(bootpath); /* Setup pointer to boot flags */ cp = prom_getbootargs(); if (cp == NULL) return; /* Skip any whitespace */ while (*cp != '-') if (*cp++ == '\0') return; for (;*++cp;) { fl = 0; BOOT_FLAG(*cp, fl); if (!fl) { printf("unknown option `%c'\n", *cp); continue; } boothowto |= fl; /* specialties */ if (*cp == 'd') { #if defined(KGDB) kgdb_debug_panic = 1; kgdb_connect(1); #elif defined(DDB) Debugger(); #else printf("kernel has no debugger\n"); #endif } } }
void machine_startup(int argc, char *argv[], struct bootinfo *bi) { extern char edata[], end[]; vaddr_t kernend; size_t symbolsize; int i; char *p; /* * this routines stack is never polluted since stack pointer * is lower than kernel text segment, and at exiting, stack pointer * is changed to proc0. */ struct kloader_bootinfo kbi; /* Symbol table size */ symbolsize = 0; if (memcmp(&end, ELFMAG, SELFMAG) == 0) { Elf_Ehdr *eh = (void *)end; Elf_Shdr *sh = (void *)(end + eh->e_shoff); for(i = 0; i < eh->e_shnum; i++, sh++) if (sh->sh_offset > 0 && (sh->sh_offset + sh->sh_size) > symbolsize) symbolsize = sh->sh_offset + sh->sh_size; } /* Clear BSS */ memset(edata, 0, end - edata); /* Setup bootinfo */ bootinfo = &kbi.bootinfo; memcpy(bootinfo, bi, sizeof(struct bootinfo)); if (bootinfo->magic == BOOTINFO_MAGIC) { platid.dw.dw0 = bootinfo->platid_cpu; platid.dw.dw1 = bootinfo->platid_machine; } /* CPU initialize */ if (platid_match(&platid, &platid_mask_CPU_SH_3)) sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A); else if (platid_match(&platid, &platid_mask_CPU_SH_4)) sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750); /* Start to determine heap area */ kernend = (vaddr_t)sh3_round_page(end + symbolsize); /* Setup bootstrap options */ makebootdev("wd0"); /* default boot device */ boothowto = 0; for (i = 1; i < argc; i++) { /* skip 1st arg (kernel name). */ char *cp = argv[i]; switch (*cp) { case 'b': /* boot device: -b=sd0 etc. */ p = cp + 2; #ifdef NFS if (strcmp(p, "nfs") == 0) mountroot = nfs_mountroot; else makebootdev(p); #else /* NFS */ makebootdev(p); #endif /* NFS */ break; default: BOOT_FLAG(*cp, boothowto); break; } } #ifdef MFS /* * 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) { size_t fssz; fssz = sh3_round_page(mfs_initminiroot((void *)kernend)); #ifdef MEMORY_DISK_DYNAMIC md_root_setconf((caddr_t)kernend, fssz); #endif kernend += fssz; } #endif /* MFS */ /* Console */ consinit(); #ifdef HPC_DEBUG_LCD dbg_lcd_test(); #endif /* copy boot parameter for kloader */ kloader_bootinfo_set(&kbi, argc, argv, bi, TRUE); /* Find memory cluster. and load to UVM */ physmem = mem_cluster_init(SH3_P1SEG_TO_PHYS(kernend)); _DPRINTF("total memory = %dMbyte\n", (int)(sh3_ptob(physmem) >> 20)); mem_cluster_load(); /* Initialize proc0 u-area */ sh_proc0_init(); /* Initialize pmap and start to address translation */ pmap_bootstrap(); /* Debugger. */ #ifdef DDB if (symbolsize) { ddb_init(symbolsize, &end, end + symbolsize); _DPRINTF("symbol size = %d byte\n", symbolsize); } if (boothowto & RB_KDB) Debugger(); #endif /* DDB */ #ifdef KGDB if (boothowto & RB_KDB) { if (kgdb_dev == NODEV) { printf("no kgdb console.\n"); } else { kgdb_debug_init = 1; kgdb_connect(1); } } #endif /* KGDB */ /* Jump to main */ __asm__ __volatile__( "jmp @%0;" "mov %1, sp" :: "r"(main),"r"(proc0.p_md.md_pcb->pcb_sf.sf_r7_bank)); /* NOTREACHED */ while (1) ; }
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 }
/* * Do all the stuff that locore normally does before calling main(). */ void mach_init(int argc, char **argv, yamon_env_var *envp, u_long memsize) { struct malta_config *mcp = &malta_configuration; bus_space_handle_t sh; caddr_t kernend, v; u_long first, last; vsize_t size; char *cp; int i, howto; uint8_t *brkres = (uint8_t *)MIPS_PHYS_TO_KSEG1(MALTA_BRKRES); extern char edata[], end[]; *brkres = 0; /* Disable BREAK==reset on console */ /* Get the propaganda in early! */ led_display_str("NetBSD"); /* * Clear the BSS segment. */ kernend = (caddr_t)mips_round_page(end); memset(edata, 0, kernend - edata); /* 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). * Also clears the I+D caches. */ mips_vector_init(); uvm_setpagesize(); physmem = btoc(memsize); gt_pci_init(&mcp->mc_pc, &mcp->mc_gt); malta_bus_io_init(&mcp->mc_iot, mcp); malta_bus_mem_init(&mcp->mc_memt, mcp); malta_dma_init(mcp); /* * Calibrate the timer, delay() relies on this. */ bus_space_map(&mcp->mc_iot, MALTA_RTCADR, 2, 0, &sh); malta_cal_timer(&mcp->mc_iot, sh); bus_space_unmap(&mcp->mc_iot, sh, 2); #if NCOM > 0 /* * Delay to allow firmware putchars to complete. * FIFO depth * character time. * character time = (1000000 / (defaultrate / 10)) */ delay(160000000 / comcnrate); if (comcnattach(&mcp->mc_iot, MALTA_UART0ADR, comcnrate, COM_FREQ, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) panic("malta: unable to initialize serial console"); #else panic("malta: not configured to use serial console"); #endif /* NCOM > 0 */ consinit(); mem_clusters[0].start = 0; mem_clusters[0].size = ctob(physmem); mem_cluster_cnt = 1; /* * XXX: check argv[0] - do something if "gdb"??? */ /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_AUTOBOOT; 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; } } /* * 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(); /* * Compute the size of system data structures. pmap_bootstrap() * needs some of this information. */ size = (vsize_t)allocsys(NULL, NULL); pmap_bootstrap(); /* * Allocate space for proc0's USPACE. */ v = (caddr_t)uvm_pageboot_alloc(USPACE); proc0.p_addr = proc0paddr = (struct user *)v; proc0.p_md.md_regs = (struct frame *)(v + USPACE) - 1; curpcb = &proc0.p_addr->u_pcb; curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ /* * Allocate space for system data structures. These data structures * are allocated here instead of cpu_startup() because physical * memory is directly addressable. We don't have to map these into * virtual address space. */ v = (caddr_t)uvm_pageboot_alloc(size); if ((allocsys(v, NULL) - v) != size) panic("mach_init: table size inconsistency"); /* * Initialize debuggers, and break into them, if appropriate. */ #ifdef DDB ddb_init(0, 0, 0); #endif if (boothowto & RB_KDB) #if defined(DDB) Debugger(); #endif }