int rascons_cnattach(void) { struct rasops_info *ri = &rascons_console_screen.scr_ri; long defattr; int crow = 0; /* get current cursor position */ OF_interpret("line#", 0, 1, &crow); /* move (rom monitor) cursor to the lowest line - 1 */ OF_interpret("#lines 2 - to line#", 0, 0); wsfont_init(); if (copy_rom_font() == 0) { romfont_loaded = 1; } /* set up rasops */ rascons_init_rasops(console_node, ri); /* * no need to clear the screen here when we're mimicing firmware * output anyway */ #if 0 if (ri->ri_width >= 1024 && ri->ri_height >= 768) { int i, screenbytes = ri->ri_stride * ri->ri_height; for (i = 0; i < screenbytes; i += sizeof(u_int32_t)) *(u_int32_t *)(fbaddr + i) = 0xffffffff; crow = 0; } #endif rascons_stdscreen.nrows = ri->ri_rows; rascons_stdscreen.ncols = ri->ri_cols; rascons_stdscreen.textops = &ri->ri_ops; rascons_stdscreen.capabilities = ri->ri_caps; ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr); wsdisplay_preattach(&rascons_stdscreen, ri, 0, max(0, min(crow, ri->ri_rows - 1)), defattr); #if notyet rascons_init_cmap(NULL); #endif return 0; }
void copy_disp_props(struct device *dev, int node, prop_dictionary_t dict) { uint32_t temp; char typestr[32]; memset(typestr, 0, sizeof(typestr)); OF_getprop(console_node, "device_type", typestr, sizeof(typestr)); if (strcmp(typestr, "serial") != 0) { /* this is our console, when we don't have a serial console */ prop_dictionary_set_bool(dict, "is_console", 1); } if (!of_to_uint32_prop(dict, node, "width", "width")) { OF_interpret("screen-width", 0, 1, &temp); prop_dictionary_set_uint32(dict, "width", temp); } if (!of_to_uint32_prop(dict, node, "height", "height")) { OF_interpret("screen-height", 0, 1, &temp); prop_dictionary_set_uint32(dict, "height", temp); } of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } if (!of_to_uint32_prop(dict, node, "address", "address")) { uint32_t fbaddr = 0; OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); if (fbaddr != 0) prop_dictionary_set_uint32(dict, "address", fbaddr); } }
static int copy_rom_font() { u_char *romfont; int char_width, char_height; int chosen, mmu, m, e; /* Get ROM FONT address. */ OF_interpret("font-adr", 0, 1, &romfont); if (romfont == NULL) return -1; chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "mmu", &mmu, 4); /* * Convert to physcal address. We cannot access to Open Firmware's * virtual address space. */ OF_call_method("translate", mmu, 1, 3, romfont, &romfont, &m, &e); /* Get character size */ OF_interpret("char-width", 0, 1, &char_width); OF_interpret("char-height", 0, 1, &char_height); openfirm6x11.name = "Open Firmware"; openfirm6x11.firstchar = 32; openfirm6x11.numchars = 96; openfirm6x11.encoding = WSDISPLAY_FONTENC_ISO; openfirm6x11.fontwidth = char_width; openfirm6x11.fontheight = char_height; openfirm6x11.stride = 1; openfirm6x11.bitorder = WSDISPLAY_FONTORDER_L2R; openfirm6x11.byteorder = WSDISPLAY_FONTORDER_L2R; openfirm6x11.data = romfont; return 0; }
/* * Try to figure out where the PROM stores the cursor row & column * variables. Returns nonzero on error. */ int romgetcursoraddr(int **rowp, int **colp) { cell_t row = 0UL, col = 0UL; OF_interpret("stdout @ is my-self addr line# addr column# ", 0, 2, &col, &row); /* * We are running on a 64-bit machine, so these things point to * 64-bit values. To convert them to pointers to integers, add * 4 to the address. */ *rowp = (int *)(intptr_t)(row+4); *colp = (int *)(intptr_t)(col+4); return (row == 0UL || col == 0UL); }
int prtc_gettime(todr_chip_handle_t handle, struct timeval *tv) { u_int32_t tod = 0; char buf[32]; if (OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && strcmp(buf, "SUNW,SPARC-Enterprise") == 0) { tv->tv_sec = prom_opl_get_tod(); tv->tv_usec = 0; return (0); } snprintf(buf, sizeof(buf), "h# %08lx unix-gettod", (long)&tod); OF_interpret(buf, 0); tv->tv_sec = tod; tv->tv_usec = 0; return (0); }
int rascons_init_rasops(int node, struct rasops_info *ri) { int32_t width, height, linebytes, depth; /* XXX /chaos/control doesn't have "width", "height", ... */ width = height = -1; if (OF_getprop(node, "width", &width, 4) != 4) OF_interpret("screen-width", 0, 1, &width); if (OF_getprop(node, "height", &height, 4) != 4) OF_interpret("screen-height", 0, 1, &height); if (OF_getprop(node, "linebytes", &linebytes, 4) != 4) linebytes = width; /* XXX */ if (OF_getprop(node, "depth", &depth, 4) != 4) depth = 8; /* XXX */ if (OF_getprop(node, "address", &fbaddr, 4) != 4) OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); if (width == -1 || height == -1 || fbaddr == 0 || fbaddr == -1) return false; /* Enable write-through cache. */ #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE) if (rascons_enable_cache) { vaddr_t va; /* * Let's try to find an empty BAT to use */ for (va = SEGMENT_LENGTH; va < (USER_SR << ADDR_SR_SHFT); va += SEGMENT_LENGTH) { if (battable[va >> ADDR_SR_SHFT].batu == 0) { battable[va >> ADDR_SR_SHFT].batl = BATL(fbaddr & 0xf0000000, BAT_G | BAT_W | BAT_M, BAT_PP_RW); battable[va >> ADDR_SR_SHFT].batu = BATL(va, BAT_BL_256M, BAT_Vs); fbaddr &= 0x0fffffff; fbaddr |= va; break; } } } #endif /* PPC_OEA64 */ /* initialize rasops */ ri->ri_width = width; ri->ri_height = height; ri->ri_depth = depth; ri->ri_stride = linebytes; ri->ri_bits = (char *)fbaddr; ri->ri_flg = RI_CENTER | RI_FULLCLEAR; /* mimic firmware output if we can find the ROM font */ if (romfont_loaded) { int cols, rows; /* * XXX this assumes we're the console which may or may not * be the case */ OF_interpret("#lines", 0, 1, &rows); OF_interpret("#columns", 0, 1, &cols); ri->ri_font = &openfirm6x11; ri->ri_wsfcookie = -1; /* not using wsfont */ rasops_init(ri, rows, cols); ri->ri_xorigin = (width - cols * ri->ri_font->fontwidth) >> 1; ri->ri_yorigin = (height - rows * ri->ri_font->fontheight) >> 1; ri->ri_bits = (char *)fbaddr + ri->ri_xorigin + ri->ri_stride * ri->ri_yorigin; } else {
static void copyprops(struct device *busdev, int node, prop_dictionary_t dict) { struct device *cntrlr; prop_dictionary_t psycho; paddr_t fbpa, mem_base = 0; uint32_t temp, fboffset; uint32_t fbaddr = 0; int options; char output_device[256]; char *pos; cntrlr = device_parent(busdev); if (cntrlr != NULL) { psycho = device_properties(cntrlr); prop_dictionary_get_uint64(psycho, "mem_base", &mem_base); } prop_dictionary_set_bool(dict, "is_console", 1); if (!of_to_uint32_prop(dict, node, "width", "width")) { OF_interpret("screen-width", 0, 1, &temp); prop_dictionary_set_uint32(dict, "width", temp); } if (!of_to_uint32_prop(dict, console_node, "height", "height")) { OF_interpret("screen-height", 0, 1, &temp); prop_dictionary_set_uint32(dict, "height", temp); } of_to_uint32_prop(dict, console_node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, console_node, "depth", "depth") && /* Some cards have an extra space in the property name */ !of_to_uint32_prop(dict, console_node, "depth ", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } OF_getprop(console_node, "address", &fbaddr, sizeof(fbaddr)); if (fbaddr == 0) OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); if (fbaddr != 0) { pmap_extract(pmap_kernel(), fbaddr, &fbpa); #ifdef DEBUG printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base, (unsigned long)fbpa); #endif if (mem_base == 0) { /* XXX this is guesswork */ fboffset = (uint32_t)(fbpa & 0xffffffff); } fboffset = (uint32_t)(fbpa - mem_base); prop_dictionary_set_uint32(dict, "address", fboffset); } of_to_dataprop(dict, console_node, "EDID", "EDID"); temp = 0; if (OF_getprop(console_node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { OF_getprop(OF_parent(console_node), "ATY,RefCLK", &temp, sizeof(temp)); } if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); /* * finally, let's see if there's a video mode specified in * output-device and pass it on so drivers like radeonfb * can do their thing */ options = OF_finddevice("/options"); if ((options == 0) || (options == -1)) return; if (OF_getprop(options, "output-device", output_device, 256) == 0) return; printf("output-device: %s\n", output_device); /* find the mode string if there is one */ pos = strstr(output_device, ":r"); if (pos == NULL) return; prop_dictionary_set_cstring(dict, "videomode", pos + 2); }
void copy_disp_props(struct device *dev, int node, prop_dictionary_t dict) { uint32_t temp; uint64_t cmap_cb; if (node != console_node) { /* * see if any child matches since OF attaches nodes for * each head and /chosen/stdout points to the head * rather than the device itself in this case */ int sub; sub = OF_child(node); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub != console_node) return; node = sub; } prop_dictionary_set_bool(dict, "is_console", 1); if (!of_to_uint32_prop(dict, node, "width", "width")) { OF_interpret("screen-width", 0, 1, &temp); prop_dictionary_set_uint32(dict, "width", temp); } if (!of_to_uint32_prop(dict, node, "height", "height")) { OF_interpret("screen-height", 0, 1, &temp); prop_dictionary_set_uint32(dict, "height", temp); } of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } if (!of_to_uint32_prop(dict, node, "address", "address")) { uint32_t fbaddr = 0; OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); if (fbaddr != 0) prop_dictionary_set_uint32(dict, "address", fbaddr); } of_to_dataprop(dict, node, "EDID", "EDID"); add_model_specifics(dict); temp = 0; if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, sizeof(temp)); } if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); gfb_cb.gcc_cookie = (void *)console_instance; gfb_cb.gcc_set_mapreg = of_set_palette; cmap_cb = (uint64_t)&gfb_cb; prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); }
static void ofbattach(device_t parent, device_t self, void *aux) { struct ofb_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct wsemuldisplaydev_attach_args a; struct rasops_info *ri = &rascons_console_screen.scr_ri; long defattr; int console, node, sub; char devinfo[256]; sc->sc_dev = self; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s\n", devinfo); if (console_node == 0) return; node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag); console = (node == console_node); if (!console) { /* check if any of the childs matches */ sub = OF_child(node); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } sc->sc_memt = pa->pa_memt; sc->sc_iot = pa->pa_iot; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; if (!console) return; vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops); sc->vd.init_screen = ofb_init_screen; sc->sc_node = console_node; sc->sc_ih = console_instance; vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr); rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; printf("%s: %d x %d, %dbpp\n", device_xname(self), ri->ri_width, ri->ri_height, ri->ri_depth); sc->sc_fbaddr = 0; if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4) OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr); if (sc->sc_fbaddr == 0) { printf("%s: Unable to find the framebuffer address.\n", device_xname(sc->sc_dev)); return; } sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height); /* XXX */ if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)) == -1) { sc->sc_node = OF_parent(sc->sc_node); OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)); } ofb_init_cmap(sc); a.console = console; a.scrdata = &ofb_screenlist; a.accessops = &ofb_accessops; a.accesscookie = &sc->vd; config_found(self, &a, wsemuldisplaydevprint); config_found_ia(self, "drm", aux, ofb_drm_print); }
/* perform model-specific actions at initppc() */ void model_init(void) { int qhandle, phandle, j; memset(&modeldata, 0, sizeof(struct model_data)); /* provide sane defaults */ for (j=0; j < MAX_PCI_BUSSES; j++) { modeldata.pciiodata[j].start = 0x00008000; modeldata.pciiodata[j].limit = 0x0000ffff; } modeldata.ranges_offset = 1; if (strncmp(model_name, "FirePower,", 10) == 0) { modeldata.ranges_offset = 0; } if (strcmp(model_name, "MOT,PowerStack_II_Pro4000") == 0) { modeldata.ranges_offset = 0; } /* 7044-270 and 7044-170 */ if (strncmp(model_name, "IBM,7044", 8) == 0) { for (j=0; j < MAX_PCI_BUSSES; j++) { modeldata.pciiodata[j].start = 0x00fff000; modeldata.pciiodata[j].limit = 0x00ffffff; } } /* Pegasos1, Pegasos2 */ if (strncmp(model_name, "Pegasos", 7) == 0) { static uint16_t modew[] = { 640, 800, 1024, 1280, 0 }; static uint16_t modeh[] = { 480, 600, 768, 1024, 0 }; uint32_t width, height, mode, fbaddr; char buf[32]; int i; modeldata.ranges_offset = 1; modeldata.pciiodata[0].start = 0x00001400; modeldata.pciiodata[0].limit = 0x0000ffff; /* the pegasos doesn't bother to set the L2 cache up*/ l2cr_config = L2CR_L2PE; /* fix the device_type property of a graphics card */ for (qhandle = OF_peer(0); qhandle; qhandle = phandle) { if (OF_getprop(qhandle, "name", buf, sizeof buf) > 0 && strncmp(buf, "display", 7) == 0) { OF_setprop(qhandle, "device_type", "display", 8); break; } if ((phandle = OF_child(qhandle))) continue; while (qhandle) { if ((phandle = OF_peer(qhandle))) break; qhandle = OF_parent(qhandle); } } /* * Get screen width/height and switch to framebuffer mode. * The default dimensions are: 800 x 600 */ OF_interpret("screen-width", 0, 1, &width); if (width == 0) width = 800; OF_interpret("screen-height", 0, 1, &height); if (height == 0) height = 600; /* find VESA mode */ for (i = 0, mode = 0; modew[i] != 0; i++) { if (modew[i] == width && modeh[i] == height) { mode = 0x101 + 2 * i; break; } } if (!mode) { mode = 0x102; width = 800; height = 600; } /* init frame buffer mode */ sprintf(buf, "%x vesa-set-mode", mode); OF_interpret(buf, 0, 0); /* set dimensions and frame buffer address in OFW */ sprintf(buf, "%x to screen-width", width); OF_interpret(buf, 0, 0); sprintf(buf, "%x to screen-height", height); OF_interpret(buf, 0, 0); OF_interpret("vesa-frame-buffer-adr", 0, 1, &fbaddr); if (fbaddr != 0) { sprintf(buf, "%x to frame-buffer-adr", fbaddr); OF_interpret(buf, 0, 0); } } }