/* * workaround for USB keyboard: * USB DMA activity has been known to corrupt kernel pages while cprboot * is restoring them. to quiesce the USB chip, we craft a "null" device * and temporarily use that as the prom's input device. this effectively * disables the USB keyboard until the cpr module restores the original * prom and a kernel driver re-inits and takes-over control of USB. * * may set globals: * reset_input */ int cb_usb_setup(void) { char sp[OBP_MAXPATHLEN]; static char cb_nulldev[] = { "\" /\" select-dev " "new-device " "\" nulldev\" device-name " ": read 2drop -2 ; " ": open true ; " ": close ; " ": install-abort ; " ": remove-abort ; " ": write 2drop 0 ; " ": restore ; " "finish-device " "unselect-dev" }; CB_VENTRY(cb_usb_setup); bzero(sp, sizeof (sp)); prom_interpret("stdin @ ihandle>devname swap -rot move", (uintptr_t)sp, 0, 0, 0, 0); if (prom_strstr(sp, "usb") && prom_strstr(sp, "keyboard")) { prom_interpret(cb_nulldev, 0, 0, 0, 0, 0); reset_input = 1; cb_set_idev(null_input); } return (0); }
/* ARGSUSED */ static int polled_io_take_console( polled_io_console_type_t type, int flags ) { #ifdef sun4v if (domaining_enabled()) return (DDI_SUCCESS); #endif switch (type) { case POLLED_IO_CONSOLE_INPUT: /* * Call into firmware to switch to the kernel I/O handling. * We will save the old value of stdin so that we can * restore it if the device is released. */ #ifdef DEBUG_OBP /* * This code is useful to trace through * what the prom is doing */ prom_interpret( "stdin @ swap ! trace-on \" /os-io\" input trace-off", (uintptr_t)&polled_input_device.polled_old_handle, 0, 0, 0, 0); #endif prom_interpret( "stdin @ swap ! \" /os-io\" open-dev stdin !", (uintptr_t)&polled_input_device.polled_old_handle, 0, 0, 0, 0); break; case POLLED_IO_CONSOLE_OUTPUT: /* * Call into firmware to switch to the kernel I/O handling. * We will save the old value of stdout so that we can * restore it if the device is released. */ prom_interpret("stdout @ swap ! \" /os-io\" open-dev stdout !", (uintptr_t)&polled_output_device.polled_old_handle, 0, 0, 0, 0); break; } return (DDI_SUCCESS); }
static void starfire_system_claim(void) { lbolt_debug_entry(); prom_interpret("sigb-sig! my-sigb-sig!", OBP_SIG, OBP_SIG, 0, 0, 0); }
int mmu_init(void) { if (CPU_ISSUN4 || CPU_ISSUN4C) { pmap_map = pmap_map4; pmap_extract = pmap_extract4; if (CPU_ISSUN4) { /* Find out if we're on a 3-lvl sun4 MMU. */ struct idprom *idp = prom_getidprom(); if (idp->id_machine == ID_SUN4_400) sun4_mmu3l = 1; } /* * XXX - we just guess which MMU cookies are free: * region 0 maps [0-16MB] * segment 0-16 map [0-4MB] * the PROM mappings use high-valued cookies. */ rcookie = 2; scookie = 17; } else if (CPU_ISSUN4M || CPU_ISSUN4D) { char buf[32]; pmap_map = pmap_map_srmmu; pmap_extract = pmap_extract_srmmu; snprintf(buf, sizeof buf, "obmem %lx L!", (u_long)&obmem); prom_interpret(buf); } else return (ENOTSUP); return (0); }
static void starfire_system_release(void) { prom_interpret("sigb-sig! my-sigb-sig!", OS_SIG, OS_SIG, 0, 0, 0); lbolt_debug_return(); }
static void cb_set_idev(char *istr) { if (reset_input) { prom_interpret(istr, 0, 0, 0, 0, 0); CB_VPRINTF(("\ncb_set_idev: reset with [%s]\n", istr)); } }
/* * get current cursor position from the stdout handle, which * containing the instance handle of the OBP console output device. */ void prom_get_tem_pos(uint32_t *row, uint32_t *col) { prom_interpret( "my-self >r stdout @ is my-self " "line# swap l! column# swap l! " "r> is my-self", (uintptr_t)row, (uintptr_t)col, 0, 0, 0); }
/* Clear the spining "|" character and hide the PROM cursor. */ void prom_hide_cursor(void) { prom_interpret( "my-self >r stdout @ is my-self " "toggle-cursor " "1 delete-characters " "r> is my-self", 0, 0, 0, 0, 0); }
/* * get the font size and the start window top of * OBP terminal emulator */ void prom_get_term_font_size(int *charheight, int *window_top) { prom_interpret( "my-self >r stdout @ is my-self " "char-height swap l! window-top swap l! " "r> is my-self", (uintptr_t)charheight, (uintptr_t)window_top, 0, 0, 0); }
/* * install remap definition in /virtual-memory node; * used for replacing a virt->phys mapping in one promif call; * this needs to be atomic from the client's perspective to * avoid faults while relocating client text. */ void install_remap(void) { static char remap_def[] = "\" /virtual-memory\" find-device " ": remap ( phys.lo virt size -- )" " 2dup unmap ( phys.lo virt size )" " 0 -rot -1 map ( ) ; " "device-end"; prom_interpret(remap_def, 0, 0, 0, 0, 0); }
/* * Power down the system. */ int i_cpr_power_down(int sleeptype) { int is_defined = 0; char *wordexists = "p\" power-off\" find nip swap l! "; char *req = "power-off"; ASSERT(sleeptype == CPR_TODISK); /* * is_defined has value -1 when defined */ prom_interpret(wordexists, (uintptr_t)&is_defined, 0, 0, 0, 0); if (is_defined) { CPR_DEBUG(CPR_DEBUG1, "\ncpr: %s...\n", req); prom_interpret(req, 0, 0, 0, 0, 0); } /* * Only returns if failed */ return (EIO); }
/* * Ask prom to open a disk file given either the OBP device path, or the * device path representing the target drive/partition and the fs-relative * path of the file. Handle file pathnames with or without leading '/'. * if fs points to a null char, it indicates that we are opening a device. */ int cpr_statefile_open(char *path, char *fs_dev) { int plen, dlen; int handle; char fs_pkg[OBP_MAXPATHLEN]; char fs_name[OBP_MAXDRVNAME]; /* * instead of using specialstate, we use fs as the flag */ if (*fs_dev == '\0') { /* device open */ statefile_special = 1; handle = prom_open(path); /* IEEE1275 prom_open returns 0 on failure; we return -1 */ return (handle ? handle : -1); } /* * No cif for $open-package, so we have to use interpret */ if (prom_getprop(chosen, "fs-package", fs_pkg) == -1) { prom_printf("Missing fs-package name\n"); return (-1); } plen = prom_strlen(fs_pkg); dlen = prom_strlen(fs_dev); prom_interpret("$open-package swap l!", plen, (uintptr_t)fs_pkg, dlen, (uintptr_t)fs_dev, (uintptr_t)&cb_rih); if (cb_rih == OBP_BADNODE || cb_rih == 0) { prom_printf("Can't open %s\n", fs_pkg); return (-1); } if (volname) { return (cpr_fs_volopen(volname)); } /* * Prepend '/' if it's not there already */ if (*path != '/') { (void) prom_sprintf(fs_name, "/%s", path); return (cpr_fs_open(fs_name)); } else return (cpr_fs_open(path)); }
void set_platform_defaults(void) { extern char *tod_module_name; extern int ts_dispatch_extended; extern void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int); uint32_t revlevel; char buf[20]; #ifdef DEBUG ce_verbose_memory = 2; ce_verbose_other = 2; #endif /* * Check to see if we have the right firmware * We simply do a prom_test to see if * "SUNW,UE10000-prom-version" interface exist. */ if (prom_test("SUNW,UE10000-prom-version") != 0) { halt("Firmware upgrade is required to boot this OS!"); } else { /* * Versions 5 to 50 and 150 or above can support this OS */ (void) sprintf(buf, "cpu-prom-version swap l!"); prom_interpret(buf, (uintptr_t)&revlevel, 0, 0, 0, 0); if ((revlevel < 5) || ((revlevel > 50) && (revlevel < 150))) halt("Firmware upgrade is required to boot this OS!"); } /* Set the CPU signature function pointer */ cpu_sgn_func = cpu_sgn_update; /* Set appropriate tod module for starfire */ ASSERT(tod_module_name == NULL); tod_module_name = "todstarfire"; /* * Use the alternate TS dispatch table, which is better * tuned for large servers. */ if (ts_dispatch_extended == -1) /* use platform default */ ts_dispatch_extended = 1; }
void kmdb_prom_interpret(const char *str) { prom_interpret((char *)str, 0, 0, 0, 0, 0); }
/* * Attach a display. We need to notice if it is the console, too. */ static void genfb_attach_sbus(device_t parent, device_t self, void *args) { struct genfb_sbus_softc *sc = device_private(self); struct sbus_attach_args *sa = args; static const struct genfb_ops zero_ops; struct genfb_ops ops = zero_ops; prop_dictionary_t dict; bus_space_handle_t bh; paddr_t fbpa; vaddr_t fbva; int node = sa->sa_node; int isconsole; aprint_normal("\n"); sc->sc_gen.sc_dev = self; /* Remember cookies for genfb_mmap_sbus() */ sc->sc_tag = sa->sa_bustag; sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); /* read geometry information from the device tree */ sc->sc_gen.sc_width = prom_getpropint(sa->sa_node, "width", 1152); sc->sc_gen.sc_height = prom_getpropint(sa->sa_node, "height", 900); sc->sc_gen.sc_depth = prom_getpropint(sa->sa_node, "depth", 8); sc->sc_gen.sc_stride = prom_getpropint(sa->sa_node, "linebytes", (sc->sc_gen.sc_width * sc->sc_gen.sc_depth + 7) >> 3 ); sc->sc_gen.sc_fbsize = sc->sc_gen.sc_height * sc->sc_gen.sc_stride; fbva = (uint32_t)prom_getpropint(sa->sa_node, "address", 0); if (fbva == 0) panic("this fb has no address property\n"); aprint_normal_dev(self, "%d x %d at %d bit\n", sc->sc_gen.sc_width, sc->sc_gen.sc_height, sc->sc_gen.sc_depth); pmap_extract(pmap_kernel(), fbva, &fbpa); sc->sc_gen.sc_fboffset = (fbpa & 0x01ffffff) - (sc->sc_paddr & 0x01ffffff); aprint_normal_dev(self, "framebuffer at offset 0x%x\n", (uint32_t)sc->sc_gen.sc_fboffset); #if notyet if (sc->sc_gen.sc_depth <= 8) { /* setup some ANSIish colour map */ char boo[256]; snprintf(boo, 256, "\" pal!\" %x %x %x %x %x call", sa->sa_node, 0, 0xa0, 0xa0, 0); prom_interpret(boo); } #endif isconsole = fb_is_console(node); dict = device_properties(self); prop_dictionary_set_bool(dict, "is_console", isconsole); if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset + sc->sc_gen.sc_fboffset, sc->sc_gen.sc_fbsize, BUS_SPACE_MAP_LINEAR, &bh) != 0) { aprint_error_dev(self, "cannot map framebuffer\n"); return; } sc->sc_gen.sc_fbaddr = (void *)bus_space_vaddr(sa->sa_bustag, bh); ops.genfb_ioctl = genfb_ioctl_sbus; ops.genfb_mmap = genfb_mmap_sbus; genfb_attach(&sc->sc_gen, &ops); }
static quik_err_t cmd_of_interp(char *args) { prom_interpret(args); return ERR_NONE; }
static quik_err_t load_config(void) { length_t len; char *buf; char *endp; char *p; path_t path; unsigned n = 0; quik_err_t err = ERR_NONE; char *attempts[] = { bi->config_file, "/boot/iquik.conf", "/boot/quik.conf", "/boot/iquik.conf", "/quik.conf", NULL }; err = env_dev_is_valid(&bi->default_dev); if (err != ERR_NONE) { if (err == ERR_ENV_CURRENT_BAD) { err = ERR_ENV_DEFAULT_BAD; } return err; } path.device = bi->default_dev.device; path.part = bi->default_dev.part; while (attempts[n] != NULL) { path.path = attempts[n]; printk("Trying configuration file @ '%P'\n", &path); err = file_len(&path, &len); if (err == ERR_NONE) { break; } n++; } /* Set by file_len. */ if (err != ERR_NONE) { return ERR_CONFIG_NOT_FOUND; } buf = malloc(len); if (buf == NULL) { return ERR_NO_MEM; } err = file_load(&path, buf); if (err != ERR_NONE) { printk("\nCouldn't load '%P': %r\n", &path, err); free(buf); return err; } if (cfg_parse(bi->config_file, buf, len) < 0) { printk ("Syntax error or read error in '%P'\n", &path); } free(buf); bi->flags |= CONFIG_VALID; p = cfg_get_strg(0, "init-code"); if (p) { prom_interpret(p); } p = cfg_get_strg(0, "init-message"); if (p) { printk("%s\n", p); } if(cfg_get_strg(0, "device") != NULL) { bi->default_dev.device = cfg_get_strg(0, "device"); } p = cfg_get_strg(0, "partition"); if (p) { n = strtol(p, &endp, 10); if (endp != p && *endp == 0) { env_dev_set_part(&bi->default_dev, n); } } p = cfg_get_strg(0, "pause-message"); if (p) { bi->pause_message = p; } p = cfg_get_strg(0, "message"); if (p) { file_cmd_cat(p); } return ERR_NONE; }