static int xboxfb_init(struct vt_device *vd) { struct fb_info *info; int i; if (!arch_i386_is_xbox) return (CN_DEAD); info = &xboxfb_info; /* * We must make a mapping from video framebuffer memory * to real. This is very crude: we map the entire * videomemory to PAGE_SIZE! Since our kernel lives at * it's relocated address range (0xc0xxxxxx), it won't * care. * * We use address PAGE_SIZE and up so we can still trap * NULL pointers. Once the real init is called, the * mapping will be done via the OS and stored in a more * sensible location ... but since we're not fully * initialized, this is our only way to go :-( */ for (i = 0; i < (XBOX_FB_SIZE / PAGE_SIZE); i++) { pmap_kenter(((i + 1) * PAGE_SIZE), XBOX_FB_START + (i * PAGE_SIZE)); } pmap_kenter((i + 1) * PAGE_SIZE, XBOX_FB_START_PTR - XBOX_FB_START_PTR % PAGE_SIZE); /* Ensure the framebuffer is where we want it to be. */ *(uint32_t *)((i + 1) * PAGE_SIZE + XBOX_FB_START_PTR % PAGE_SIZE) = XBOX_FB_START; /* Initialize fb_info. */ info = vd->vd_softc; info->fb_width = VT_XBOX_WIDTH; info->fb_height = VT_XBOX_HEIGHT; info->fb_size = XBOX_FB_SIZE; info->fb_stride = VT_XBOX_WIDTH * 4; /* 32bits per pixel. */ info->fb_vbase = PAGE_SIZE; info->fb_pbase = XBOX_FB_START_PTR; /* Get pixel storage size. */ info->fb_bpp = 32; /* Get color depth. */ info->fb_depth = 24; vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); fb_probe(info); vt_fb_init(vd); return (CN_INTERNAL); }
static int vt_efb_init(struct vt_device *vd) { struct ofw_pci_register pciaddrs[8]; struct fb_info *info; int i, len, n_pciaddrs; phandle_t chosen, node; ihandle_t stdout; char type[64]; info = vd->vd_softc; chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); node = OF_instance_to_package(stdout); if (node == -1) { /* * The "/chosen/stdout" does not exist try * using "screen" directly. */ node = OF_finddevice("screen"); } OF_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, "display") != 0) return (CN_DEAD); #define GET(name, var) \ if (OF_getproplen(node, (name)) != sizeof(info->fb_##var)) \ return (CN_DEAD); \ OF_getencprop(node, (name), &info->fb_##var, sizeof(info->fb_##var)); \ if (info->fb_##var == 0) \ return (CN_DEAD); GET("height", height) GET("width", width) GET("depth", depth) GET("linebytes", stride) #undef GET info->fb_size = info->fb_height * info->fb_stride; /* * Get the PCI addresses of the adapter, if present. The node may be the * child of the PCI device: in that case, try the parent for * the assigned-addresses property. */ len = OF_getprop(node, "assigned-addresses", pciaddrs, sizeof(pciaddrs)); if (len == -1) { len = OF_getprop(OF_parent(node), "assigned-addresses", pciaddrs, sizeof(pciaddrs)); } if (len == -1) len = 0; n_pciaddrs = len / sizeof(struct ofw_pci_register); /* * Grab the physical address of the framebuffer, and then map it * into our memory space. If the MMU is not yet up, it will be * remapped for us when relocation turns on. */ if (OF_getproplen(node, "address") == sizeof(info->fb_pbase)) { /* XXX We assume #address-cells is 1 at this point. */ OF_getencprop(node, "address", &info->fb_pbase, sizeof(info->fb_pbase)); #if defined(__powerpc__) sc->sc_memt = &bs_be_tag; bus_space_map(sc->sc_memt, info->fb_pbase, info->fb_size, BUS_SPACE_MAP_PREFETCHABLE, &info->fb_vbase); #elif defined(__sparc64__) OF_decode_addr(node, 0, &space, &phys); sc->sc_memt = &vt_efb_memt[0]; info->addr = sparc64_fake_bustag(space, fb_phys, sc->sc_memt); #else bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size, BUS_SPACE_MAP_PREFETCHABLE, (bus_space_handle_t *)&info->fb_vbase); #endif } else { /* * Some IBM systems don't have an address property. Try to * guess the framebuffer region from the assigned addresses. * This is ugly, but there doesn't seem to be an alternative. * Linux does the same thing. */ info->fb_pbase = n_pciaddrs; for (i = 0; i < n_pciaddrs; i++) { /* If it is too small, not the framebuffer */ if (pciaddrs[i].size_lo < info->fb_size) continue; /* If it is not memory, it isn't either */ if (!(pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_SPACE_MEM32)) continue; /* This could be the framebuffer */ info->fb_pbase = i; /* If it is prefetchable, it certainly is */ if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) break; } if (info->fb_pbase == n_pciaddrs) /* No candidates found */ return (CN_DEAD); #if defined(__powerpc__) OF_decode_addr(node, info->fb_pbase, &sc->sc_memt, &info->fb_vbase); #elif defined(__sparc64__) OF_decode_addr(node, info->fb_pbase, &space, &info->fb_pbase); sc->sc_memt = &vt_efb_memt[0]; info->fb_vbase = sparc64_fake_bustag(space, info->fb_pbase, sc->sc_memt); #else bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size, BUS_SPACE_MAP_PREFETCHABLE, (bus_space_handle_t *)&info->fb_vbase); #endif } /* blank full size */ len = info->fb_size / 4; for (i = 0; i < len; i++) { ((uint32_t *)info->fb_vbase)[i] = 0; } /* Get pixel storage size. */ info->fb_bpp = info->fb_stride / info->fb_width * 8; /* * Early FB driver work with static window buffer 80x25, so reduce * size to 640x480. */ info->fb_width = VT_FB_DEFAULT_WIDTH; info->fb_height = VT_FB_DEFAULT_HEIGHT; #ifdef FDT vt_efb_initialize(info, node); #else vt_efb_initialize(info); #endif fb_probe(info); vt_fb_init(vd); return (CN_INTERNAL); }
static int vt_efb_init(struct vt_device *vd) { int depth, d, disable, i, len; struct fb_info *info; struct efi_fb *efifb; caddr_t kmdp; info = vd->vd_softc; disable = 0; TUNABLE_INT_FETCH("hw.syscons.disable", &disable); if (disable != 0) return (CN_DEAD); kmdp = preload_search_by_type("elf kernel"); if (kmdp == NULL) kmdp = preload_search_by_type("elf64 kernel"); efifb = (struct efi_fb *)preload_search_info(kmdp, MODINFO_METADATA | MODINFOMD_EFI_FB); if (efifb == NULL) return (CN_DEAD); info->fb_height = efifb->fb_height; info->fb_width = efifb->fb_width; depth = fls(efifb->fb_mask_red); d = fls(efifb->fb_mask_green); depth = d > depth ? d : depth; d = fls(efifb->fb_mask_blue); depth = d > depth ? d : depth; d = fls(efifb->fb_mask_reserved); depth = d > depth ? d : depth; info->fb_depth = depth; info->fb_stride = efifb->fb_stride * (depth / 8); vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB, efifb->fb_mask_red, ffs(efifb->fb_mask_red) - 1, efifb->fb_mask_green, ffs(efifb->fb_mask_green) - 1, efifb->fb_mask_blue, ffs(efifb->fb_mask_blue) - 1); info->fb_size = info->fb_height * info->fb_stride; info->fb_pbase = efifb->fb_addr; /* * We could use pmap_mapdev here except that the kernel pmap * hasn't been created yet and hence any attempt to lock it will * fail. */ info->fb_vbase = PHYS_TO_DMAP(efifb->fb_addr); /* blank full size */ len = info->fb_size / 4; for (i = 0; i < len; i++) { ((uint32_t *)info->fb_vbase)[i] = 0; } /* Get pixel storage size. */ info->fb_bpp = info->fb_stride / info->fb_width * 8; /* * Early FB driver work with static window buffer, so reduce to minimal * size, buffer or screen. */ info->fb_width = MIN(info->fb_width, VT_FB_DEFAULT_WIDTH); info->fb_height = MIN(info->fb_height, VT_FB_DEFAULT_HEIGHT); fb_probe(info); vt_fb_init(vd); return (CN_INTERNAL); }