/* * Prepare the console tty; called on first open of /dev/console */ static void kd_init(struct kd_softc *kd) { struct tty *tp; tp = tty_alloc(); callout_setfunc(&tp->t_rstrt_ch, kd_later, tp); tp->t_oproc = kdstart; tp->t_param = kdparam; tp->t_dev = makedev(cdevsw_lookup_major(&kd_cdevsw), 0); tty_attach(tp); kd->kd_tty = tp; /* * Get the console struct winsize. */ #if defined(RASTERCONSOLE) && NFB > 0 /* If the raster console driver is attached, copy its size */ kd->rows = fbrcons_rows(); kd->cols = fbrcons_cols(); rcons_ttyinit(tp); #endif /* else, consult the PROM */ switch (prom_version()) { char prop[6+1]; /* Enough for six digits */ struct eeprom *ep; case PROM_OLDMON: if ((ep = (struct eeprom *)eeprom_va) == NULL) break; if (kd->rows == 0) kd->rows = (u_short)ep->eeTtyRows; if (kd->cols == 0) kd->cols = (u_short)ep->eeTtyCols; break; case PROM_OBP_V0: case PROM_OBP_V2: case PROM_OBP_V3: case PROM_OPENFIRM: if (kd->rows == 0 && prom_getoption("screen-#rows", prop, sizeof prop) == 0) kd->rows = strtoul(prop, NULL, 10); if (kd->cols == 0 && prom_getoption("screen-#columns", prop, sizeof prop) == 0) kd->cols = strtoul(prop, NULL, 10); break; } return; }
int pconsprobe(void) { switch (prom_version()) { #ifdef PROM_OLDMON case PROM_OLDMON: case PROM_OBP_V0: return 1; #endif /* PROM_OLDMON */ #ifdef PROM_OBP_V2 case PROM_OBP_V2: case PROM_OBP_V3: case PROM_OPENFIRM: return prom_stdin() && prom_stdout(); #endif /* PROM_OBP_V2 */ default: break; } return 0; }
void consinit(void) { #if 0 int inSource, outSink; #endif switch (prom_version()) { #if 0 case PROM_OLDMON: case PROM_OBP_V0: /* The stdio handles identify the device type */ inSource = prom_stdin(); outSink = prom_stdout(); break; // XXXMRG should these just set prom_stdin_node / prom_stdout_node? #endif case PROM_OBP_V2: case PROM_OBP_V3: case PROM_OPENFIRM: /* Save PROM arguments for device matching */ prom_get_device_args("stdin-path", prom_stdin_args, sizeof(prom_stdin_args)); prom_get_device_args("stdout-path", prom_stdout_args, sizeof(prom_stdout_args)); /* * Translate the STDIO package instance (`ihandle') -- that * the PROM has already opened for us -- to a device tree * node (i.e. a `phandle'). */ prom_stdin_node = prom_instance_to_package(prom_stdin()); if (prom_stdin_node == 0) printf("consinit: cannot convert stdin ihandle\n"); prom_stdout_node = prom_instance_to_package(prom_stdout()); if (prom_stdout_node == 0) { printf("consinit: cannot convert stdout ihandle\n"); break; } break; default: break; } /* Wire up /dev/console */ cn_tab->cn_dev = makedev(cdevsw_lookup_major(&kd_cdevsw), 0); cn_tab->cn_pri = CN_INTERNAL; /* Set up initial PROM input channel for /dev/console */ cons_attach_input(&prom_cons_channel, cn_tab); #ifdef KGDB zs_kgdb_init(); /* XXX */ #endif }
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 } } }
int main(void) { int error, i; char kernel[MAX_PROM_PATH]; const char *k; u_long marks[MARK_MAX], bootinfo; struct btinfo_symtab bi_sym; struct btinfo_boothowto bi_howto; void *arg; #ifdef HEAP_VARIABLE { extern char end[]; setheap((void *)ALIGN(end), (void *)0xffffffff); } #endif prom_init(); mmu_init(); printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); /* massage machine prom */ prom_patch(); /* * get default kernel. */ k = prom_getbootfile(); if (k != NULL && *k != '\0') { i = -1; /* not using the kernels */ strcpy(kernel, k); } else { i = 0; strcpy(kernel, kernels[i]); } k = prom_getbootpath(); if (k && *k) strcpy(prom_bootdevice, k); boothowto = bootoptions(prom_getbootargs()); for (;;) { /* * ask for a kernel first .. */ if (boothowto & RB_ASKNAME) { printf("device[%s] (\"halt\" to halt): ", prom_bootdevice); gets(dbuf); if (strcmp(dbuf, "halt") == 0) _rtt(); if (dbuf[0]) strcpy(prom_bootdevice, dbuf); printf("boot (press RETURN to try default list): "); gets(fbuf); if (fbuf[0]) strcpy(kernel, fbuf); else { boothowto &= ~RB_ASKNAME; i = 0; strcpy(kernel, kernels[i]); } } printf("Booting %s\n", kernel); if ((error = loadk(kernel, marks)) == 0) break; if (error != ENOENT) { printf("Cannot load %s: error=%d\n", kernel, error); boothowto |= RB_ASKNAME; } /* * if we have are not in askname mode, and we aren't using the * prom bootfile, try the next one (if it exits). otherwise, * go into askname mode. */ if ((boothowto & RB_ASKNAME) == 0 && i != -1 && kernels[++i]) { strcpy(kernel, kernels[i]); printf(": trying %s...\n", kernel); } else { printf("\n"); boothowto |= RB_ASKNAME; } } marks[MARK_END] = (((u_long)marks[MARK_END] + sizeof(u_long) - 1)) & (-sizeof(u_long)); arg = (prom_version() == PROM_OLDMON) ? (void *)PROM_LOADADDR : romp; /* Setup boot info structure at the end of the kernel image */ bootinfo = bi_init(marks[MARK_END] & loadaddrmask); /* Add kernel symbols to bootinfo */ bi_sym.nsym = marks[MARK_NSYM] & loadaddrmask; bi_sym.ssym = marks[MARK_SYM] & loadaddrmask; bi_sym.esym = marks[MARK_END] & loadaddrmask; bi_add(&bi_sym, BTINFO_SYMTAB, sizeof(bi_sym)); /* Add boothowto */ bi_howto.boothowto = boothowto; bi_add(&bi_howto, BTINFO_BOOTHOWTO, sizeof(bi_howto)); /* Add kernel path to bootinfo */ i = sizeof(struct btinfo_common) + strlen(kernel) + 1; /* Impose limit (somewhat arbitrary) */ if (i < BOOTINFO_SIZE / 2) { union { struct btinfo_kernelfile bi_file; char x[i]; } U; strcpy(U.bi_file.name, kernel); bi_add(&U.bi_file, BTINFO_KERNELFILE, i); } (*(entry_t)marks[MARK_ENTRY])(arg, 0, 0, 0, bootinfo, DDB_MAGIC2); _rtt(); }