Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

*** 46,55 **** --- 46,56 ---- #include <sys/vgasubr.h> #include <sys/pci.h> #include <sys/kd.h> #include <sys/ddi_impldefs.h> #include <sys/sunldi.h> + #include <sys/gfx_private.h> #define MYNAME "vgatext" /* * Each instance of this driver has 2 minor nodes:
*** 60,88 **** #define AGPMASTER_MINOR 1 #define MY_NBITSMINOR 1 #define DEV2INST(dev) (getminor(dev) >> MY_NBITSMINOR) #define DEV2MINOR(dev) (getminor(dev) & ((1 << MY_NBITSMINOR) - 1)) ! #define INST2NODE1(inst) ((inst) << MY_NBITSMINOR + GFX_MINOR) #define INST2NODE2(inst) (((inst) << MY_NBITSMINOR) + AGPMASTER_MINOR) - /* I don't know exactly where these should be defined, but this is a */ - /* heck of a lot better than constants in the code. */ - #define TEXT_ROWS 25 - #define TEXT_COLS 80 - - #define VGA_BRIGHT_WHITE 0x0f - #define VGA_BLACK 0x00 - - #define VGA_REG_ADDR 0x3c0 - #define VGA_REG_SIZE 0x20 - - #define VGA_MEM_ADDR 0xa0000 - #define VGA_MEM_SIZE 0x20000 - - #define VGA_MMAP_FB_BASE VGA_MEM_ADDR - /* * This variable allows for this driver to suspend even if it * shouldn't. Note that by setting it, the framebuffer will probably * not come back. So use it with a serial console, or with serial * line debugging (say, for example, if this driver is being modified --- 61,73 ---- #define AGPMASTER_MINOR 1 #define MY_NBITSMINOR 1 #define DEV2INST(dev) (getminor(dev) >> MY_NBITSMINOR) #define DEV2MINOR(dev) (getminor(dev) & ((1 << MY_NBITSMINOR) - 1)) ! #define INST2NODE1(inst) (((inst) << MY_NBITSMINOR) + GFX_MINOR) #define INST2NODE2(inst) (((inst) << MY_NBITSMINOR) + AGPMASTER_MINOR) /* * This variable allows for this driver to suspend even if it * shouldn't. Note that by setting it, the framebuffer will probably * not come back. So use it with a serial console, or with serial * line debugging (say, for example, if this driver is being modified
*** 117,128 **** static int vgatext_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result); static int vgatext_attach(dev_info_t *, ddi_attach_cmd_t); static int vgatext_detach(dev_info_t *, ddi_detach_cmd_t); - static struct vis_identifier text_ident = { "SUNWtext" }; - static struct dev_ops vgatext_ops = { DEVO_REV, /* devo_rev */ 0, /* devo_refcnt */ vgatext_info, /* devo_getinfo */ nulldev, /* devo_identify */ --- 102,111 ----
*** 135,206 **** NULL, /* power */ ddi_quiesce_not_needed, /* quiesce */ }; struct vgatext_softc { ! struct vgaregmap regs; ! struct vgaregmap fb; ! off_t fb_size; ! int fb_regno; dev_info_t *devi; - int mode; /* KD_TEXT or KD_GRAPHICS */ - caddr_t text_base; /* hardware text base */ - char shadow[TEXT_ROWS*TEXT_COLS*2]; - caddr_t current_base; /* hardware or shadow */ - struct { - boolean_t visible; - int row; - int col; - } cursor; - struct vis_polledio polledio; - struct { - unsigned char red; - unsigned char green; - unsigned char blue; - } colormap[VGA8_CMAP_ENTRIES]; - unsigned char attrib_palette[VGA_ATR_NUM_PLT]; - unsigned int flags; - kmutex_t lock; }; - #define VGATEXT_FLAG_CONSOLE 0x00000001 - #define VGATEXT_IS_CONSOLE(softc) ((softc)->flags & VGATEXT_FLAG_CONSOLE) - - static int vgatext_devinit(struct vgatext_softc *, struct vis_devinit *data); - static void vgatext_cons_copy(struct vgatext_softc *, - struct vis_conscopy *); - static void vgatext_cons_display(struct vgatext_softc *, - struct vis_consdisplay *); - static void vgatext_cons_cursor(struct vgatext_softc *, - struct vis_conscursor *); - static void vgatext_polled_copy(struct vis_polledio_arg *, - struct vis_conscopy *); - static void vgatext_polled_display(struct vis_polledio_arg *, - struct vis_consdisplay *); - static void vgatext_polled_cursor(struct vis_polledio_arg *, - struct vis_conscursor *); - static void vgatext_init(struct vgatext_softc *); - static void vgatext_set_text(struct vgatext_softc *); - #if defined(USE_BORDERS) - static void vgatext_init_graphics(struct vgatext_softc *); - #endif - static int vgatext_kdsetmode(struct vgatext_softc *softc, int mode); - static void vgatext_setfont(struct vgatext_softc *softc); - static void vgatext_get_cursor(struct vgatext_softc *softc, - screen_pos_t *row, screen_pos_t *col); - static void vgatext_set_cursor(struct vgatext_softc *softc, int row, int col); - static void vgatext_hide_cursor(struct vgatext_softc *softc); - static void vgatext_save_colormap(struct vgatext_softc *softc); - static void vgatext_restore_colormap(struct vgatext_softc *softc); - static int vgatext_get_pci_reg_index(dev_info_t *const devi, - unsigned long himask, unsigned long hival, unsigned long addr, - off_t *offset); - static int vgatext_get_isa_reg_index(dev_info_t *const devi, - unsigned long hival, unsigned long addr, off_t *offset); static void *vgatext_softc_head; - static char vgatext_silent; - static char happyface_boot; /* Loadable Driver stuff */ static struct modldrv modldrv = { &mod_driverops, /* Type of module. This one is a driver */ --- 118,132 ---- NULL, /* power */ ddi_quiesce_not_needed, /* quiesce */ }; struct vgatext_softc { ! gfxp_fb_softc_ptr_t gfxp_state; dev_info_t *devi; }; static void *vgatext_softc_head; /* Loadable Driver stuff */ static struct modldrv modldrv = { &mod_driverops, /* Type of module. This one is a driver */
*** 210,269 **** static struct modlinkage modlinkage = { MODREV_1, (void *) &modldrv, NULL }; - typedef enum pc_colors { - pc_black = 0, - pc_blue = 1, - pc_green = 2, - pc_cyan = 3, - pc_red = 4, - pc_magenta = 5, - pc_brown = 6, - pc_white = 7, - pc_grey = 8, - pc_brt_blue = 9, - pc_brt_green = 10, - pc_brt_cyan = 11, - pc_brt_red = 12, - pc_brt_magenta = 13, - pc_yellow = 14, - pc_brt_white = 15 - } pc_colors_t; - - static const unsigned char solaris_color_to_pc_color[16] = { - pc_brt_white, /* 0 - brt_white */ - pc_black, /* 1 - black */ - pc_blue, /* 2 - blue */ - pc_green, /* 3 - green */ - pc_cyan, /* 4 - cyan */ - pc_red, /* 5 - red */ - pc_magenta, /* 6 - magenta */ - pc_brown, /* 7 - brown */ - pc_white, /* 8 - white */ - pc_grey, /* 9 - gery */ - pc_brt_blue, /* 10 - brt_blue */ - pc_brt_green, /* 11 - brt_green */ - pc_brt_cyan, /* 12 - brt_cyan */ - pc_brt_red, /* 13 - brt_red */ - pc_brt_magenta, /* 14 - brt_magenta */ - pc_yellow /* 15 - yellow */ - }; - - static ddi_device_acc_attr_t i8xx_dev_access = { - DDI_DEVICE_ATTR_V0, - DDI_NEVERSWAP_ACC, - DDI_STRICTORDER_ACC - }; - - static ddi_device_acc_attr_t dev_attr = { - DDI_DEVICE_ATTR_V0, - DDI_NEVERSWAP_ACC, - DDI_STRICTORDER_ACC, - }; - int _init(void) { int e; --- 136,145 ----
*** 297,443 **** _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } - /* default structure for FBIOGATTR ioctl */ - static struct fbgattr vgatext_attr = { - /* real_type owner */ - FBTYPE_SUNFAST_COLOR, 0, - /* fbtype: type h w depth cms size */ - { FBTYPE_SUNFAST_COLOR, TEXT_ROWS, TEXT_COLS, 1, 256, 0 }, - /* fbsattr: flags emu_type dev_specific */ - { 0, FBTYPE_SUN4COLOR, { 0 } }, - /* emu_types */ - { -1 } - }; - /* * handy macros */ #define getsoftc(instance) ((struct vgatext_softc *) \ ddi_get_soft_state(vgatext_softc_head, (instance))) #define STREQ(a, b) (strcmp((a), (b)) == 0) - /* - * NOTE: this function is duplicated here and in gfx_private/vgatext while - * we work on a set of commitable interfaces to sunpci.c. - * - * Use the class code to determine if the device is a PCI-to-PCI bridge. - * Returns: B_TRUE if the device is a bridge. - * B_FALSE if the device is not a bridge or the property cannot be - * retrieved. - */ - static boolean_t - is_pci_bridge(dev_info_t *dip) - { - uint32_t class_code; - - class_code = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "class-code", 0xffffffff); - - if (class_code == 0xffffffff || class_code == DDI_PROP_NOT_FOUND) - return (B_FALSE); - - class_code &= 0x00ffff00; - if (class_code == ((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8))) - return (B_TRUE); - - return (B_FALSE); - } - - static void - vgatext_check_for_console(dev_info_t *devi, struct vgatext_softc *softc, - int pci_pcie_bus) - { - ddi_acc_handle_t pci_conf; - dev_info_t *pdevi; - uint16_t data16; - - /* - * Based on Section 11.3, "PCI Display Subsystem Initialization", - * of the 1.1 PCI-to-PCI Bridge Architecture Specification - * determine if this is the boot console device. First, see - * if the SBIOS has turned on PCI I/O for this device. Then if - * this is PCI/PCI-E, verify the parent bridge has VGAEnable set. - */ - - if (pci_config_setup(devi, &pci_conf) != DDI_SUCCESS) { - cmn_err(CE_WARN, - MYNAME ": can't get PCI conf handle"); - return; - } - - data16 = pci_config_get16(pci_conf, PCI_CONF_COMM); - if (data16 & PCI_COMM_IO) - softc->flags |= VGATEXT_FLAG_CONSOLE; - - pci_config_teardown(&pci_conf); - - /* If IO not enabled or ISA/EISA, just return */ - if (!(softc->flags & VGATEXT_FLAG_CONSOLE) || !pci_pcie_bus) - return; - - /* - * Check for VGA Enable in the Bridge Control register for all - * PCI/PCIEX parents. If not set all the way up the chain, - * this cannot be the boot console. - */ - - pdevi = devi; - while (pdevi = ddi_get_parent(pdevi)) { - int error; - ddi_acc_handle_t ppci_conf; - char *parent_type = NULL; - - error = ddi_prop_lookup_string(DDI_DEV_T_ANY, pdevi, - DDI_PROP_DONTPASS, "device_type", &parent_type); - if (error != DDI_SUCCESS) { - return; - } - - /* Verify still on the PCI/PCIEX parent tree */ - if (!STREQ(parent_type, "pci") && - !STREQ(parent_type, "pciex")) { - ddi_prop_free(parent_type); - return; - } - - ddi_prop_free(parent_type); - parent_type = NULL; - - /* VGAEnable is set only for PCI-to-PCI bridges. */ - if (is_pci_bridge(pdevi) == B_FALSE) - continue; - - if (pci_config_setup(pdevi, &ppci_conf) != DDI_SUCCESS) - continue; - - data16 = pci_config_get16(ppci_conf, PCI_BCNF_BCNTRL); - pci_config_teardown(&ppci_conf); - - if (!(data16 & PCI_BCNF_BCNTRL_VGA_ENABLE)) { - softc->flags &= ~VGATEXT_FLAG_CONSOLE; - return; - } - } - } - static int vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) { struct vgatext_softc *softc; int unit = ddi_get_instance(devi); int error; ! char *parent_type = NULL; ! int reg_rnumber; ! off_t reg_offset; ! off_t mem_offset; ! char buf[80], *cons; ! int pci_pcie_bus = 0; switch (cmd) { case DDI_ATTACH: break; --- 173,198 ---- _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } /* * handy macros */ #define getsoftc(instance) ((struct vgatext_softc *) \ ddi_get_soft_state(vgatext_softc_head, (instance))) #define STREQ(a, b) (strcmp((a), (b)) == 0) static int vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) { struct vgatext_softc *softc; int unit = ddi_get_instance(devi); int error; ! char name[80]; switch (cmd) { case DDI_ATTACH: break;
*** 447,457 **** * Though vgatext doesn't really know how to resume * on a generic framebuffer, we should succeed, as * it is far better to have no console, than potentiall * have no machine. */ ! return (DDI_SUCCESS); default: return (DDI_FAILURE); } /* DDI_ATTACH */ --- 202,213 ---- * Though vgatext doesn't really know how to resume * on a generic framebuffer, we should succeed, as * it is far better to have no console, than potentiall * have no machine. */ ! softc = getsoftc(unit); ! return (gfxp_fb_attach(devi, cmd, softc->gfxp_state)); default: return (DDI_FAILURE); } /* DDI_ATTACH */
*** 459,596 **** /* Allocate softc struct */ if (ddi_soft_state_zalloc(vgatext_softc_head, unit) != DDI_SUCCESS) { return (DDI_FAILURE); } softc = getsoftc(unit); /* link it in */ softc->devi = devi; ddi_set_driver_private(devi, softc); ! softc->polledio.arg = (struct vis_polledio_arg *)softc; ! softc->polledio.display = vgatext_polled_display; ! softc->polledio.copy = vgatext_polled_copy; ! softc->polledio.cursor = vgatext_polled_cursor; ! ! mutex_init(&(softc->lock), NULL, MUTEX_DRIVER, NULL); ! ! error = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(devi), ! DDI_PROP_DONTPASS, "device_type", &parent_type); ! if (error != DDI_SUCCESS) { ! cmn_err(CE_WARN, MYNAME ": can't determine parent type."); ! goto fail; ! } ! ! if (STREQ(parent_type, "isa") || STREQ(parent_type, "eisa")) { ! reg_rnumber = vgatext_get_isa_reg_index(devi, 1, VGA_REG_ADDR, ! &reg_offset); ! if (reg_rnumber < 0) { ! cmn_err(CE_WARN, ! MYNAME ": can't find reg entry for registers"); ! error = DDI_FAILURE; ! goto fail; ! } ! softc->fb_regno = vgatext_get_isa_reg_index(devi, 0, ! VGA_MEM_ADDR, &mem_offset); ! if (softc->fb_regno < 0) { ! cmn_err(CE_WARN, ! MYNAME ": can't find reg entry for memory"); ! error = DDI_FAILURE; ! goto fail; ! } ! } else if (STREQ(parent_type, "pci") || STREQ(parent_type, "pciex")) { ! pci_pcie_bus = 1; ! reg_rnumber = vgatext_get_pci_reg_index(devi, ! PCI_REG_ADDR_M|PCI_REG_REL_M, ! PCI_ADDR_IO|PCI_RELOCAT_B, VGA_REG_ADDR, ! &reg_offset); ! if (reg_rnumber < 0) { ! cmn_err(CE_WARN, ! MYNAME ": can't find reg entry for registers"); ! error = DDI_FAILURE; ! goto fail; ! } ! softc->fb_regno = vgatext_get_pci_reg_index(devi, ! PCI_REG_ADDR_M|PCI_REG_REL_M, ! PCI_ADDR_MEM32|PCI_RELOCAT_B, VGA_MEM_ADDR, ! &mem_offset); ! if (softc->fb_regno < 0) { ! cmn_err(CE_WARN, ! MYNAME ": can't find reg entry for memory"); ! error = DDI_FAILURE; ! goto fail; ! } ! } else { ! cmn_err(CE_WARN, MYNAME ": unknown parent type \"%s\".", ! parent_type); ! error = DDI_FAILURE; ! goto fail; ! } ! ddi_prop_free(parent_type); ! parent_type = NULL; ! ! error = ddi_regs_map_setup(devi, reg_rnumber, ! (caddr_t *)&softc->regs.addr, reg_offset, VGA_REG_SIZE, ! &dev_attr, &softc->regs.handle); ! if (error != DDI_SUCCESS) ! goto fail; ! softc->regs.mapped = B_TRUE; ! ! softc->fb_size = VGA_MEM_SIZE; ! ! error = ddi_regs_map_setup(devi, softc->fb_regno, ! (caddr_t *)&softc->fb.addr, ! mem_offset, softc->fb_size, ! &dev_attr, &softc->fb.handle); ! if (error != DDI_SUCCESS) ! goto fail; ! softc->fb.mapped = B_TRUE; ! ! if (ddi_get8(softc->regs.handle, ! softc->regs.addr + VGA_MISC_R) & VGA_MISC_IOA_SEL) ! softc->text_base = (caddr_t)softc->fb.addr + VGA_COLOR_BASE; ! else ! softc->text_base = (caddr_t)softc->fb.addr + VGA_MONO_BASE; ! ! if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), ! DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) { ! if (strcmp(cons, "graphics") == 0) { ! happyface_boot = 1; ! vgatext_silent = 1; ! softc->current_base = softc->shadow; ! } else { ! softc->current_base = softc->text_base; ! } ! ddi_prop_free(cons); ! } else { ! softc->current_base = softc->text_base; ! } ! ! (void) sprintf(buf, "text-%d", unit); ! error = ddi_create_minor_node(devi, buf, S_IFCHR, INST2NODE1(unit), DDI_NT_DISPLAY, NULL); ! if (error != DDI_SUCCESS) ! goto fail; ! ! error = ddi_prop_create(makedevice(DDI_MAJOR_T_UNKNOWN, unit), ! devi, DDI_PROP_CANSLEEP, DDI_KERNEL_IOCTL, NULL, 0); ! if (error != DDI_SUCCESS) ! goto fail; ! ! vgatext_check_for_console(devi, softc, pci_pcie_bus); ! ! /* only do this if not in graphics mode */ ! if ((vgatext_silent == 0) && (VGATEXT_IS_CONSOLE(softc))) { ! vgatext_init(softc); ! vgatext_save_colormap(softc); ! } ! return (DDI_SUCCESS); - fail: - if (parent_type != NULL) - ddi_prop_free(parent_type); (void) vgatext_detach(devi, DDI_DETACH); return (error); } static int --- 215,246 ---- /* Allocate softc struct */ if (ddi_soft_state_zalloc(vgatext_softc_head, unit) != DDI_SUCCESS) { return (DDI_FAILURE); } softc = getsoftc(unit); + softc->gfxp_state = gfxp_fb_softc_alloc(); + if (softc->gfxp_state == NULL) { + (void) ddi_soft_state_free(vgatext_softc_head, unit); + return (DDI_FAILURE); + } + if (gfxp_fb_attach(devi, cmd, softc->gfxp_state) != DDI_SUCCESS) { + gfxp_fb_softc_free(softc->gfxp_state); + (void) ddi_soft_state_free(vgatext_softc_head, unit); + return (DDI_FAILURE); + } + /* link it in */ softc->devi = devi; ddi_set_driver_private(devi, softc); ! (void) snprintf(name, sizeof (name), "text-%d", unit); ! error = ddi_create_minor_node(devi, name, S_IFCHR, INST2NODE1(unit), DDI_NT_DISPLAY, NULL); ! if (error == DDI_SUCCESS) return (DDI_SUCCESS); (void) vgatext_detach(devi, DDI_DETACH); return (error); } static int
*** 600,614 **** struct vgatext_softc *softc = getsoftc(instance); switch (cmd) { case DDI_DETACH: ! if (softc->fb.mapped) ! ddi_regs_map_free(&softc->fb.handle); ! if (softc->regs.mapped) ! ddi_regs_map_free(&softc->regs.handle); ! mutex_destroy(&(softc->lock)); ddi_remove_minor_node(devi, NULL); (void) ddi_soft_state_free(vgatext_softc_head, instance); return (DDI_SUCCESS); case DDI_SUSPEND: --- 250,263 ---- struct vgatext_softc *softc = getsoftc(instance); switch (cmd) { case DDI_DETACH: ! (void) gfxp_fb_detach(devi, cmd, softc->gfxp_state); ! ! if (softc->gfxp_state != NULL) ! gfxp_fb_softc_free(softc->gfxp_state); ddi_remove_minor_node(devi, NULL); (void) ddi_soft_state_free(vgatext_softc_head, instance); return (DDI_SUCCESS); case DDI_SUSPEND:
*** 627,637 **** * and resume. Therefore, we have this module tunable * (purposely using a long name) that will allow for * suspend it it is set. Otherwise we fail. */ if (vgatext_force_suspend != 0) ! return (DDI_SUCCESS); else return (DDI_FAILURE); default: cmn_err(CE_WARN, "vgatext_detach: unknown cmd 0x%x\n", cmd); --- 276,286 ---- * and resume. Therefore, we have this module tunable * (purposely using a long name) that will allow for * suspend it it is set. Otherwise we fail. */ if (vgatext_force_suspend != 0) ! return (gfxp_fb_detach(devi, cmd, softc->gfxp_state)); else return (DDI_FAILURE); default: cmn_err(CE_WARN, "vgatext_detach: unknown cmd 0x%x\n", cmd);
*** 673,811 **** } return (error); } - /*ARGSUSED*/ static int vgatext_open(dev_t *devp, int flag, int otyp, cred_t *cred) { struct vgatext_softc *softc = getsoftc(DEV2INST(*devp)); ! if (softc == NULL || otyp == OTYP_BLK) return (ENXIO); ! return (0); } - /*ARGSUSED*/ static int vgatext_close(dev_t devp, int flag, int otyp, cred_t *cred) { ! return (0); ! } ! static int ! do_gfx_ioctl(int cmd, intptr_t data, int mode, struct vgatext_softc *softc) ! { ! static char kernel_only[] = ! "do_gfx_ioctl: %s is a kernel only ioctl"; ! int err; ! int kd_mode; ! ! switch (cmd) { ! case KDSETMODE: ! return (vgatext_kdsetmode(softc, (int)data)); ! ! case KDGETMODE: ! kd_mode = softc->mode; ! if (ddi_copyout(&kd_mode, (void *)data, sizeof (int), mode)) ! return (EFAULT); ! break; ! ! case VIS_GETIDENTIFIER: ! if (ddi_copyout(&text_ident, (void *)data, ! sizeof (struct vis_identifier), mode)) ! return (EFAULT); ! break; ! ! case VIS_DEVINIT: ! ! if (!(mode & FKIOCTL)) { ! cmn_err(CE_CONT, kernel_only, "VIS_DEVINIT"); return (ENXIO); - } ! err = vgatext_devinit(softc, (struct vis_devinit *)data); ! if (err != 0) { ! cmn_err(CE_WARN, ! "vgatext_ioctl: could not initialize console"); ! return (err); ! } ! break; ! ! case VIS_CONSCOPY: /* move */ ! { ! struct vis_conscopy pma; ! ! if (ddi_copyin((void *)data, &pma, ! sizeof (struct vis_conscopy), mode)) ! return (EFAULT); ! ! vgatext_cons_copy(softc, &pma); ! break; ! } ! ! case VIS_CONSDISPLAY: /* display */ ! { ! struct vis_consdisplay display_request; ! ! if (ddi_copyin((void *)data, &display_request, ! sizeof (display_request), mode)) ! return (EFAULT); ! ! vgatext_cons_display(softc, &display_request); ! break; ! } ! ! case VIS_CONSCURSOR: ! { ! struct vis_conscursor cursor_request; ! ! if (ddi_copyin((void *)data, &cursor_request, ! sizeof (cursor_request), mode)) ! return (EFAULT); ! ! vgatext_cons_cursor(softc, &cursor_request); ! ! if (cursor_request.action == VIS_GET_CURSOR && ! ddi_copyout(&cursor_request, (void *)data, ! sizeof (cursor_request), mode)) ! return (EFAULT); ! break; ! } ! ! case VIS_GETCMAP: ! case VIS_PUTCMAP: ! case FBIOPUTCMAP: ! case FBIOGETCMAP: ! /* ! * At the moment, text mode is not considered to have ! * a color map. ! */ ! return (EINVAL); ! ! case FBIOGATTR: ! if (copyout(&vgatext_attr, (void *)data, ! sizeof (struct fbgattr))) ! return (EFAULT); ! break; ! ! case FBIOGTYPE: ! if (copyout(&vgatext_attr.fbtype, (void *)data, ! sizeof (struct fbtype))) ! return (EFAULT); ! break; ! ! default: ! return (ENXIO); ! } ! return (0); } - - /*ARGSUSED*/ static int vgatext_ioctl( dev_t dev, int cmd, intptr_t data, --- 322,353 ---- } return (error); } static int vgatext_open(dev_t *devp, int flag, int otyp, cred_t *cred) { struct vgatext_softc *softc = getsoftc(DEV2INST(*devp)); ! if (softc == NULL) return (ENXIO); ! return (gfxp_fb_open(devp, flag, otyp, cred, softc->gfxp_state)); } static int vgatext_close(dev_t devp, int flag, int otyp, cred_t *cred) { ! struct vgatext_softc *softc = getsoftc(DEV2INST(devp)); ! if (softc == NULL) return (ENXIO); ! return (gfxp_fb_close(devp, flag, otyp, cred, softc->gfxp_state)); } static int vgatext_ioctl( dev_t dev, int cmd, intptr_t data,
*** 816,828 **** struct vgatext_softc *softc = getsoftc(DEV2INST(dev)); int err; switch (DEV2MINOR(dev)) { case GFX_MINOR: ! mutex_enter(&(softc->lock)); ! err = do_gfx_ioctl(cmd, data, mode, softc); ! mutex_exit(&(softc->lock)); break; case AGPMASTER_MINOR: /* * This is apparently not used anymore. Let's log a --- 358,369 ---- struct vgatext_softc *softc = getsoftc(DEV2INST(dev)); int err; switch (DEV2MINOR(dev)) { case GFX_MINOR: ! err = gfxp_fb_ioctl(dev, cmd, data, mode, cred, rval, ! softc->gfxp_state); break; case AGPMASTER_MINOR: /* * This is apparently not used anymore. Let's log a
*** 840,1518 **** return (EBADF); } return (err); } - static void - vgatext_save_text(struct vgatext_softc *softc) - { - unsigned i; - - for (i = 0; i < sizeof (softc->shadow); i++) - softc->shadow[i] = softc->current_base[i]; - } - - static void - vgatext_progressbar_stop() - { - extern void progressbar_stop(void); - - if (vgatext_silent == 1) { - vgatext_silent = 0; - progressbar_stop(); - } - } - - static void - vgatext_kdsettext(struct vgatext_softc *softc) - { - int i; - - vgatext_init(softc); - for (i = 0; i < sizeof (softc->shadow); i++) { - softc->text_base[i] = softc->shadow[i]; - } - softc->current_base = softc->text_base; - if (softc->cursor.visible) { - vgatext_set_cursor(softc, - softc->cursor.row, softc->cursor.col); - } - vgatext_restore_colormap(softc); - } - - static void - vgatext_kdsetgraphics(struct vgatext_softc *softc) - { - vgatext_progressbar_stop(); - vgatext_save_text(softc); - softc->current_base = softc->shadow; - #if defined(USE_BORDERS) - vgatext_init_graphics(softc); - #endif - } - static int - vgatext_kdsetmode(struct vgatext_softc *softc, int mode) - { - if ((mode == softc->mode) || (!VGATEXT_IS_CONSOLE(softc))) - return (0); - - switch (mode) { - case KD_TEXT: - vgatext_kdsettext(softc); - break; - - case KD_GRAPHICS: - vgatext_kdsetgraphics(softc); - break; - - case KD_RESETTEXT: - /* - * In order to avoid racing with a starting X server, - * this needs to be a test and set that is performed in - * a single (softc->lock protected) ioctl into this driver. - */ - if (softc->mode == KD_TEXT && vgatext_silent == 1) { - vgatext_progressbar_stop(); - vgatext_kdsettext(softc); - } - break; - - default: - return (EINVAL); - } - softc->mode = mode; - return (0); - } - - /*ARGSUSED*/ - static int vgatext_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len, size_t *maplen, uint_t model) { struct vgatext_softc *softc; - int err; - size_t length; - softc = getsoftc(DEV2INST(dev)); if (softc == NULL) { cmn_err(CE_WARN, "vgatext: Can't find softstate"); return (-1); } ! if (!(off >= VGA_MMAP_FB_BASE && ! off < VGA_MMAP_FB_BASE + softc->fb_size)) { ! cmn_err(CE_WARN, "vgatext: Can't map offset 0x%llx", off); ! return (-1); ! } ! ! if (off + len > VGA_MMAP_FB_BASE + softc->fb_size) ! length = VGA_MMAP_FB_BASE + softc->fb_size - off; ! else ! length = len; ! ! if ((err = devmap_devmem_setup(dhp, softc->devi, NULL, softc->fb_regno, ! off - VGA_MMAP_FB_BASE, ! length, PROT_ALL, 0, &dev_attr)) < 0) { ! return (err); ! } ! ! ! *maplen = length; ! return (0); ! } ! ! ! static int ! vgatext_devinit(struct vgatext_softc *softc, struct vis_devinit *data) ! { ! /* initialize console instance */ ! data->version = VIS_CONS_REV; ! data->width = TEXT_COLS; ! data->height = TEXT_ROWS; ! data->linebytes = TEXT_COLS; ! data->depth = 4; ! data->mode = VIS_TEXT; ! data->polledio = &softc->polledio; ! ! return (0); ! } ! ! /* ! * display a string on the screen at (row, col) ! * assume it has been cropped to fit. ! */ ! ! static void ! vgatext_cons_display(struct vgatext_softc *softc, struct vis_consdisplay *da) ! { ! unsigned char *string; ! int i; ! unsigned char attr; ! struct cgatext { ! unsigned char ch; ! unsigned char attr; ! }; ! struct cgatext *addr; ! ! /* ! * Sanity checks. This is a last-ditch effort to avoid damage ! * from brokenness or maliciousness above. ! */ ! if (da->row < 0 || da->row >= TEXT_ROWS || ! da->col < 0 || da->col >= TEXT_COLS || ! da->col + da->width > TEXT_COLS) ! return; ! ! /* ! * To be fully general, we should copyin the data. This is not ! * really relevant for this text-only driver, but a graphical driver ! * should support these ioctls from userland to enable simple ! * system startup graphics. ! */ ! attr = (solaris_color_to_pc_color[da->bg_color & 0xf] << 4) ! | solaris_color_to_pc_color[da->fg_color & 0xf]; ! string = da->data; ! addr = (struct cgatext *)softc->current_base ! + (da->row * TEXT_COLS + da->col); ! for (i = 0; i < da->width; i++) { ! addr->ch = string[i]; ! addr->attr = attr; ! addr++; ! } ! } ! ! static void ! vgatext_polled_display( ! struct vis_polledio_arg *arg, ! struct vis_consdisplay *da) ! { ! vgatext_cons_display((struct vgatext_softc *)arg, da); ! } ! ! /* ! * screen-to-screen copy ! */ ! ! static void ! vgatext_cons_copy(struct vgatext_softc *softc, struct vis_conscopy *ma) ! { ! unsigned short *from; ! unsigned short *to; ! int cnt; ! screen_size_t chars_per_row; ! unsigned short *to_row_start; ! unsigned short *from_row_start; ! screen_size_t rows_to_move; ! unsigned short *base; ! ! /* ! * Sanity checks. Note that this is a last-ditch effort to avoid ! * damage caused by broken-ness or maliciousness above. ! */ ! if (ma->s_col < 0 || ma->s_col >= TEXT_COLS || ! ma->s_row < 0 || ma->s_row >= TEXT_ROWS || ! ma->e_col < 0 || ma->e_col >= TEXT_COLS || ! ma->e_row < 0 || ma->e_row >= TEXT_ROWS || ! ma->t_col < 0 || ma->t_col >= TEXT_COLS || ! ma->t_row < 0 || ma->t_row >= TEXT_ROWS || ! ma->s_col > ma->e_col || ! ma->s_row > ma->e_row) ! return; ! ! /* ! * Remember we're going to copy shorts because each ! * character/attribute pair is 16 bits. ! */ ! chars_per_row = ma->e_col - ma->s_col + 1; ! rows_to_move = ma->e_row - ma->s_row + 1; ! ! /* More sanity checks. */ ! if (ma->t_row + rows_to_move > TEXT_ROWS || ! ma->t_col + chars_per_row > TEXT_COLS) ! return; ! ! base = (unsigned short *)softc->current_base; ! ! to_row_start = base + ((ma->t_row * TEXT_COLS) + ma->t_col); ! from_row_start = base + ((ma->s_row * TEXT_COLS) + ma->s_col); ! ! if (to_row_start < from_row_start) { ! while (rows_to_move-- > 0) { ! to = to_row_start; ! from = from_row_start; ! to_row_start += TEXT_COLS; ! from_row_start += TEXT_COLS; ! for (cnt = chars_per_row; cnt-- > 0; ) ! *to++ = *from++; ! } ! } else { ! /* ! * Offset to the end of the region and copy backwards. ! */ ! cnt = rows_to_move * TEXT_COLS + chars_per_row; ! to_row_start += cnt; ! from_row_start += cnt; ! ! while (rows_to_move-- > 0) { ! to_row_start -= TEXT_COLS; ! from_row_start -= TEXT_COLS; ! to = to_row_start; ! from = from_row_start; ! for (cnt = chars_per_row; cnt-- > 0; ) ! *--to = *--from; ! } ! } ! } ! ! static void ! vgatext_polled_copy( ! struct vis_polledio_arg *arg, ! struct vis_conscopy *ca) ! { ! vgatext_cons_copy((struct vgatext_softc *)arg, ca); ! } ! ! ! static void ! vgatext_cons_cursor(struct vgatext_softc *softc, struct vis_conscursor *ca) ! { ! if (vgatext_silent) ! return; ! ! switch (ca->action) { ! case VIS_HIDE_CURSOR: ! softc->cursor.visible = B_FALSE; ! if (softc->current_base == softc->text_base) ! vgatext_hide_cursor(softc); ! break; ! case VIS_DISPLAY_CURSOR: ! /* ! * Sanity check. This is a last-ditch effort to avoid ! * damage from brokenness or maliciousness above. ! */ ! if (ca->col < 0 || ca->col >= TEXT_COLS || ! ca->row < 0 || ca->row >= TEXT_ROWS) ! return; ! ! softc->cursor.visible = B_TRUE; ! softc->cursor.col = ca->col; ! softc->cursor.row = ca->row; ! if (softc->current_base == softc->text_base) ! vgatext_set_cursor(softc, ca->row, ca->col); ! break; ! case VIS_GET_CURSOR: ! if (softc->current_base == softc->text_base) { ! vgatext_get_cursor(softc, &ca->row, &ca->col); ! } ! break; ! } ! } ! ! static void ! vgatext_polled_cursor( ! struct vis_polledio_arg *arg, ! struct vis_conscursor *ca) ! { ! vgatext_cons_cursor((struct vgatext_softc *)arg, ca); ! } ! ! ! ! /*ARGSUSED*/ ! static void ! vgatext_hide_cursor(struct vgatext_softc *softc) ! { ! /* Nothing at present */ ! } ! ! static void ! vgatext_set_cursor(struct vgatext_softc *softc, int row, int col) ! { ! short addr; ! ! if (vgatext_silent) ! return; ! ! addr = row * TEXT_COLS + col; ! ! vga_set_crtc(&softc->regs, VGA_CRTC_CLAH, addr >> 8); ! vga_set_crtc(&softc->regs, VGA_CRTC_CLAL, addr & 0xff); ! } ! ! static int vga_row, vga_col; ! ! static void ! vgatext_get_cursor(struct vgatext_softc *softc, ! screen_pos_t *row, screen_pos_t *col) ! { ! short addr; ! ! addr = (vga_get_crtc(&softc->regs, VGA_CRTC_CLAH) << 8) + ! vga_get_crtc(&softc->regs, VGA_CRTC_CLAL); ! ! vga_row = *row = addr / TEXT_COLS; ! vga_col = *col = addr % TEXT_COLS; ! } ! ! /* ! * This code is experimental. It's only enabled if console is ! * set to graphics, a preliminary implementation of happyface boot. ! */ ! static void ! vgatext_set_text(struct vgatext_softc *softc) ! { ! int i; ! ! if (happyface_boot == 0) ! return; ! ! /* we are in graphics mode, set to text 80X25 mode */ ! ! /* set misc registers */ ! vga_set_reg(&softc->regs, VGA_MISC_W, VGA_MISC_TEXT); ! ! /* set sequencer registers */ ! vga_set_seq(&softc->regs, VGA_SEQ_RST_SYN, ! (vga_get_seq(&softc->regs, VGA_SEQ_RST_SYN) & ! ~VGA_SEQ_RST_SYN_NO_SYNC_RESET)); ! for (i = 1; i < NUM_SEQ_REG; i++) { ! vga_set_seq(&softc->regs, i, VGA_SEQ_TEXT[i]); ! } ! vga_set_seq(&softc->regs, VGA_SEQ_RST_SYN, ! (vga_get_seq(&softc->regs, VGA_SEQ_RST_SYN) | ! VGA_SEQ_RST_SYN_NO_ASYNC_RESET | ! VGA_SEQ_RST_SYN_NO_SYNC_RESET)); ! ! /* set crt controller registers */ ! vga_set_crtc(&softc->regs, VGA_CRTC_VRE, ! (vga_get_crtc(&softc->regs, VGA_CRTC_VRE) & ! ~VGA_CRTC_VRE_LOCK)); ! for (i = 0; i < NUM_CRTC_REG; i++) { ! vga_set_crtc(&softc->regs, i, VGA_CRTC_TEXT[i]); ! } ! ! /* set graphics controller registers */ ! for (i = 0; i < NUM_GRC_REG; i++) { ! vga_set_grc(&softc->regs, i, VGA_GRC_TEXT[i]); ! } ! ! /* set attribute registers */ ! for (i = 0; i < NUM_ATR_REG; i++) { ! vga_set_atr(&softc->regs, i, VGA_ATR_TEXT[i]); ! } ! ! /* set palette */ ! for (i = 0; i < VGA_TEXT_CMAP_ENTRIES; i++) { ! vga_put_cmap(&softc->regs, i, VGA_TEXT_PALETTES[i][0] << 2, ! VGA_TEXT_PALETTES[i][1] << 2, ! VGA_TEXT_PALETTES[i][2] << 2); ! } ! for (i = VGA_TEXT_CMAP_ENTRIES; i < VGA8_CMAP_ENTRIES; i++) { ! vga_put_cmap(&softc->regs, i, 0, 0, 0); ! } ! ! vgatext_save_colormap(softc); ! } ! ! static void ! vgatext_init(struct vgatext_softc *softc) ! { ! unsigned char atr_mode; ! ! atr_mode = vga_get_atr(&softc->regs, VGA_ATR_MODE); ! if (atr_mode & VGA_ATR_MODE_GRAPH) ! vgatext_set_text(softc); ! atr_mode = vga_get_atr(&softc->regs, VGA_ATR_MODE); ! atr_mode &= ~VGA_ATR_MODE_BLINK; ! atr_mode &= ~VGA_ATR_MODE_9WIDE; ! vga_set_atr(&softc->regs, VGA_ATR_MODE, atr_mode); ! #if defined(USE_BORDERS) ! vga_set_atr(&softc->regs, VGA_ATR_BDR_CLR, ! vga_get_atr(&softc->regs, VGA_BRIGHT_WHITE)); ! #else ! vga_set_atr(&softc->regs, VGA_ATR_BDR_CLR, ! vga_get_atr(&softc->regs, VGA_BLACK)); ! #endif ! vgatext_setfont(softc); /* need selectable font? */ ! } ! ! #if defined(USE_BORDERS) ! static void ! vgatext_init_graphics(struct vgatext_softc *softc) ! { ! vga_set_atr(&softc->regs, VGA_ATR_BDR_CLR, ! vga_get_atr(&softc->regs, VGA_BLACK)); ! } ! #endif ! ! static char vga_fontslot = 0; ! ! static void ! vgatext_setfont(struct vgatext_softc *softc) ! { ! static uchar_t fsreg[8] = {0x0, 0x30, 0x5, 0x35, 0xa, 0x3a, 0xf, 0x3f}; ! ! uchar_t *from; ! uchar_t volatile *to; ! int i, j, s; ! int bpc, f_offset; ! ! /* Sync-reset the sequencer registers */ ! vga_set_seq(&softc->regs, 0x00, 0x01); ! /* ! * enable write to plane2, since fonts ! * could only be loaded into plane2 ! */ ! vga_set_seq(&softc->regs, 0x02, 0x04); ! /* ! * sequentially access data in the bit map being ! * selected by MapMask register (index 0x02) ! */ ! vga_set_seq(&softc->regs, 0x04, 0x07); ! /* Sync-reset ended, and allow the sequencer to operate */ ! vga_set_seq(&softc->regs, 0x00, 0x03); ! ! /* ! * select plane 2 on Read Mode 0 ! */ ! vga_set_grc(&softc->regs, 0x04, 0x02); ! /* ! * system addresses sequentially access data, follow ! * Memory Mode register bit 2 in the sequencer ! */ ! vga_set_grc(&softc->regs, 0x05, 0x00); ! /* ! * set range of host memory addresses decoded by VGA ! * hardware -- A0000h-BFFFFh (128K region) ! */ ! vga_set_grc(&softc->regs, 0x06, 0x00); ! ! /* ! * This assumes 8x16 characters, which yield the traditional 80x25 ! * screen. It really should support other character heights. ! */ ! bpc = 16; ! s = vga_fontslot; ! f_offset = s * 8 * 1024; ! for (i = 0; i < 256; i++) { ! from = font_data_8x16.encoding[i]; ! to = (unsigned char *)softc->fb.addr + f_offset + i * 0x20; ! for (j = 0; j < bpc; j++) ! *to++ = *from++; ! } ! ! /* Sync-reset the sequencer registers */ ! vga_set_seq(&softc->regs, 0x00, 0x01); ! /* enable write to plane 0 and 1 */ ! vga_set_seq(&softc->regs, 0x02, 0x03); ! /* ! * enable character map selection ! * and odd/even addressing ! */ ! vga_set_seq(&softc->regs, 0x04, 0x03); ! /* ! * select font map ! */ ! vga_set_seq(&softc->regs, 0x03, fsreg[s]); ! /* Sync-reset ended, and allow the sequencer to operate */ ! vga_set_seq(&softc->regs, 0x00, 0x03); ! ! /* restore graphic registers */ ! ! /* select plane 0 */ ! vga_set_grc(&softc->regs, 0x04, 0x00); ! /* enable odd/even addressing mode */ ! vga_set_grc(&softc->regs, 0x05, 0x10); ! /* ! * range of host memory addresses decoded by VGA ! * hardware -- B8000h-BFFFFh (32K region) ! */ ! vga_set_grc(&softc->regs, 0x06, 0x0e); ! /* enable all color plane */ ! vga_set_atr(&softc->regs, 0x12, 0x0f); ! ! } ! ! static void ! vgatext_save_colormap(struct vgatext_softc *softc) ! { ! int i; ! ! for (i = 0; i < VGA_ATR_NUM_PLT; i++) { ! softc->attrib_palette[i] = vga_get_atr(&softc->regs, i); ! } ! for (i = 0; i < VGA8_CMAP_ENTRIES; i++) { ! vga_get_cmap(&softc->regs, i, ! &softc->colormap[i].red, ! &softc->colormap[i].green, ! &softc->colormap[i].blue); ! } ! } ! ! static void ! vgatext_restore_colormap(struct vgatext_softc *softc) ! { ! int i; ! ! for (i = 0; i < VGA_ATR_NUM_PLT; i++) { ! vga_set_atr(&softc->regs, i, softc->attrib_palette[i]); ! } ! for (i = 0; i < VGA8_CMAP_ENTRIES; i++) { ! vga_put_cmap(&softc->regs, i, ! softc->colormap[i].red, ! softc->colormap[i].green, ! softc->colormap[i].blue); ! } ! } ! ! /* ! * search the entries of the "reg" property for one which has the desired ! * combination of phys_hi bits and contains the desired address. ! * ! * This version searches a PCI-style "reg" property. It was prompted by ! * issues surrounding the presence or absence of an entry for the ROM: ! * (a) a transition problem with PowerPC Virtual Open Firmware ! * (b) uncertainty as to whether an entry will be included on a device ! * with ROM support (and so an "active" ROM base address register), ! * but no ROM actually installed. ! * ! * See the note below on vgatext_get_isa_reg_index for the reasons for ! * returning the offset. ! * ! * Note that this routine may not be fully general; it is intended for the ! * specific purpose of finding a couple of particular VGA reg entries and ! * may not be suitable for all reg-searching purposes. ! */ ! static int ! vgatext_get_pci_reg_index( ! dev_info_t *const devi, ! unsigned long himask, ! unsigned long hival, ! unsigned long addr, ! off_t *offset) ! { ! ! int length, index; ! pci_regspec_t *reg; ! ! if (ddi_getlongprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, ! "reg", (caddr_t)&reg, &length) != DDI_PROP_SUCCESS) { ! return (-1); ! } ! ! for (index = 0; index < length / sizeof (pci_regspec_t); index++) { ! if ((reg[index].pci_phys_hi & himask) != hival) ! continue; ! if (reg[index].pci_size_hi != 0) ! continue; ! if (reg[index].pci_phys_mid != 0) ! continue; ! if (reg[index].pci_phys_low > addr) ! continue; ! if (reg[index].pci_phys_low + reg[index].pci_size_low <= addr) ! continue; ! ! *offset = addr - reg[index].pci_phys_low; ! kmem_free(reg, (size_t)length); ! return (index); ! } ! kmem_free(reg, (size_t)length); ! ! return (-1); ! } ! ! /* ! * search the entries of the "reg" property for one which has the desired ! * combination of phys_hi bits and contains the desired address. ! * ! * This version searches a ISA-style "reg" property. It was prompted by ! * issues surrounding 8514/A support. By IEEE 1275 compatibility conventions, ! * 8514/A registers should have been added after all standard VGA registers. ! * Unfortunately, the Solaris/Intel device configuration framework ! * (a) lists the 8514/A registers before the video memory, and then ! * (b) also sorts the entries so that I/O entries come before memory ! * entries. ! * ! * It returns the "reg" index and offset into that register set. ! * The offset is needed because there exist (broken?) BIOSes that ! * report larger ranges enclosing the standard ranges. One reports ! * 0x3bf for 0x21 instead of 0x3c0 for 0x20, for instance. Using the ! * offset adjusts for this difference in the base of the register set. ! * ! * Note that this routine may not be fully general; it is intended for the ! * specific purpose of finding a couple of particular VGA reg entries and ! * may not be suitable for all reg-searching purposes. ! */ ! static int ! vgatext_get_isa_reg_index( ! dev_info_t *const devi, ! unsigned long hival, ! unsigned long addr, ! off_t *offset) ! { ! ! int length, index; ! struct regspec *reg; ! ! if (ddi_getlongprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, ! "reg", (caddr_t)&reg, &length) != DDI_PROP_SUCCESS) { ! return (-1); ! } ! ! for (index = 0; index < length / sizeof (struct regspec); index++) { ! if (reg[index].regspec_bustype != hival) ! continue; ! if (reg[index].regspec_addr > addr) ! continue; ! if (reg[index].regspec_addr + reg[index].regspec_size <= addr) ! continue; ! ! *offset = addr - reg[index].regspec_addr; ! kmem_free(reg, (size_t)length); ! return (index); ! } ! kmem_free(reg, (size_t)length); ! ! return (-1); } --- 381,400 ---- return (EBADF); } return (err); } static int vgatext_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len, size_t *maplen, uint_t model) { struct vgatext_softc *softc; softc = getsoftc(DEV2INST(dev)); if (softc == NULL) { cmn_err(CE_WARN, "vgatext: Can't find softstate"); return (-1); } ! return (gfxp_fb_devmap(dev, dhp, off, len, maplen, model, ! softc->gfxp_state)); }