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>


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 /*
  30  * Miniature VGA driver for bootstrap.
  31  */
  32 
  33 #include <sys/archsystm.h>
  34 #include <sys/vgareg.h>




  35 
  36 #include "boot_vga.h"
  37 
  38 #if defined(_BOOT)
  39 #include "../dboot/dboot_asm.h"
  40 #include "../dboot/dboot_xboot.h"
  41 #endif
  42 
  43 #define VGA_COLOR_CRTC_INDEX    0x3d4
  44 #define VGA_COLOR_CRTC_DATA     0x3d5
  45 
  46 #if defined(__xpv) && defined(_BOOT)
  47 
  48 /*
  49  * Device memory address
  50  *
  51  * In dboot under the hypervisor we don't have any memory mappings
  52  * for the first meg of low memory so we can't access devices there.
  53  * Intead we've mapped the device memory that we need to access into
  54  * a local variable within dboot so we can access the device memory
  55  * there.
  56  */
  57 extern unsigned short *video_fb;
  58 #define VGA_SCREEN              ((unsigned short *)video_fb)
  59 
  60 #else /* __xpv && _BOOT */
  61 
  62 /* Device memory address */
  63 #define VGA_SCREEN              ((unsigned short *)0xb8000)
  64 
  65 #endif /* __xpv && _BOOT */
  66 

  67 










  68 static void vga_set_crtc(int index, unsigned char val);
  69 static unsigned char vga_get_crtc(int index);


  70 

































  71 void
  72 vga_cursor_display(void)
  73 {







































  74         unsigned char val, msl;
  75 



  76         /*
  77          * Figure out the maximum scan line value.  We need this to set the
  78          * cursor size.
  79          */
  80         msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f;
  81 
  82         /*
  83          * Enable the cursor and set it's size.  Preserve the upper two
  84          * bits of the control register.
  85          * - Bits 0-4 are the starting scan line of the cursor.
  86          *   Scanning is done from top-to-bottom.  The top-most scan
  87          *   line is 0 and the bottom most scan line is the maximum scan
  88          *   line value.
  89          * - Bit 5 is the cursor disable bit.
  90          */
  91         val = vga_get_crtc(VGA_CRTC_CSSL);
  92         vga_set_crtc(VGA_CRTC_CSSL, (val & 0xc) | ((msl - 2) & 0x1f));
  93 





  94         /*
  95          * Continue setting the cursors size.
  96          * - Bits 0-4 are the ending scan line of the cursor.
  97          *   Scanning is done from top-to-bottom.  The top-most scan
  98          *   line is 0 and the bottom most scan line is the maximum scan
  99          *   line value.
 100          * - Bits 5-6 are the cursor skew.
 101          */
 102         vga_set_crtc(VGA_CRTC_CESL, msl);
 103 }
 104 
 105 
 106 void
 107 vga_clear(int color)
 108 {
 109         unsigned short val;
 110         int i;
 111 

 112         val = (color << 8) | ' ';



 113 
 114         for (i = 0; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
 115                 VGA_SCREEN[i] = val;






























 116         }
 117 }
 118 
 119 void
 120 vga_drawc(int c, int color)
 121 {









 122         int row;
 123         int col;
 124 
 125         vga_getpos(&row, &col);
 126         VGA_SCREEN[row*VGA_TEXT_COLS + col] = (color << 8) | c;


















 127 }
 128 
 129 void
 130 vga_scroll(int color)
 131 {
 132         unsigned short val;
 133         int i;
 134 
 135         val = (color << 8) | ' ';
 136 
 137         for (i = 0; i < (VGA_TEXT_ROWS-1)*VGA_TEXT_COLS; i++) {
 138                 VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS];
 139         }
 140         for (; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
 141                 VGA_SCREEN[i] = val;
 142         }
 143 }
 144 
 145 void
 146 vga_setpos(int row, int col)
 147 {
 148         int off;
 149 









 150         off = row * VGA_TEXT_COLS + col;
 151         vga_set_crtc(VGA_CRTC_CLAH, off >> 8);
 152         vga_set_crtc(VGA_CRTC_CLAL, off & 0xff);



 153 }
 154 
 155 void
 156 vga_getpos(int *row, int *col)
 157 {
 158         int off;
 159 
 160         off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL);
 161         *row = off / VGA_TEXT_COLS;
 162         *col = off % VGA_TEXT_COLS;
 163 }
 164 
 165 static void


























 166 vga_set_crtc(int index, unsigned char val)
 167 {
 168         outb(VGA_COLOR_CRTC_INDEX, index);
 169         outb(VGA_COLOR_CRTC_DATA, val);
 170 }
 171 
 172 static unsigned char
 173 vga_get_crtc(int index)
 174 {
 175         outb(VGA_COLOR_CRTC_INDEX, index);
 176         return (inb(VGA_COLOR_CRTC_DATA));
 177 }


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 


  27 /*
  28  * Miniature VGA driver for bootstrap.
  29  */
  30 
  31 #include <sys/archsystm.h>
  32 #include <sys/vgareg.h>
  33 #include <sys/framebuffer.h>
  34 #include <sys/boot_console.h>
  35 #include <sys/tem_impl.h>
  36 #include "boot_console_impl.h"
  37 
  38 #include "boot_vga.h"
  39 
  40 #if defined(_BOOT)
  41 #include "../dboot/dboot_asm.h"
  42 #include "../dboot/dboot_xboot.h"
  43 #endif
  44 



  45 #if defined(__xpv) && defined(_BOOT)
  46 
  47 /*
  48  * Device memory address
  49  *
  50  * In dboot under the hypervisor we don't have any memory mappings
  51  * for the first meg of low memory so we can't access devices there.
  52  * Intead we've mapped the device memory that we need to access into
  53  * a local variable within dboot so we can access the device memory
  54  * there.
  55  */
  56 extern unsigned short *video_fb;
  57 #define VGA_SCREEN              (video_fb)
  58 
  59 #else /* __xpv && _BOOT */
  60 
  61 /* Device memory address */
  62 #define VGA_SCREEN              ((unsigned short *)0xb8000)
  63 
  64 #endif /* __xpv && _BOOT */
  65 
  66 static int cons_color = CONS_COLOR;
  67 
  68 static void vga_init(void);
  69 static void vga_drawc(int);
  70 static void vga_setpos(int, int);
  71 static void vga_getpos(int *, int *);
  72 static void vga_scroll(int);
  73 static void vga_clear(int);
  74 static void vga_shiftline(int);
  75 static void vga_eraseline(void);
  76 static void vga_cursor_display(boolean_t);
  77 
  78 static void vga_set_crtc(int index, unsigned char val);
  79 static unsigned char vga_get_crtc(int index);
  80 static void vga_set_atr(int index, unsigned char val);
  81 static unsigned char vga_get_atr(int index);
  82 
  83 static int
  84 set_vga_color(void)
  85 {
  86         int color;
  87         uint8_t tmp;
  88 
  89         /*
  90          * Now we have two principal cases, black on white and white on black.
  91          * And we have possible inverse to switch them, and we want to
  92          * follow the tem logic.. to set VGA TEXT color. FB will take care
  93          * of itself in boot_fb.c
  94          */
  95         if (fb_info.inverse == B_TRUE ||
  96             fb_info.inverse_screen == B_TRUE) {
  97                 tmp = dim_xlate[fb_info.fg_color];
  98                 color = solaris_color_to_pc_color[tmp] << 4;
  99                 tmp = brt_xlate[fb_info.bg_color];
 100                 color |= solaris_color_to_pc_color[tmp];
 101                 return (color);
 102         }
 103 
 104         /* use bright white for background */
 105         if (fb_info.bg_color == 7)
 106                 tmp = brt_xlate[fb_info.bg_color];
 107         else
 108                 tmp = dim_xlate[fb_info.bg_color];
 109 
 110         color = solaris_color_to_pc_color[tmp] << 4;
 111         tmp = dim_xlate[fb_info.fg_color];
 112         color |= solaris_color_to_pc_color[tmp];
 113         return (color);
 114 }
 115 
 116 void
 117 boot_vga_init(bcons_dev_t *bcons_dev)
 118 {
 119         fb_info.terminal.x = VGA_TEXT_COLS;
 120         fb_info.terminal.y = VGA_TEXT_ROWS;
 121         cons_color = set_vga_color();
 122 
 123 #if defined(_BOOT)
 124         /* Note that we have to enable the cursor before clearing the
 125          * screen since the cursor position is dependant upon the cursor
 126          * skew, which is initialized by vga_cursor_display()
 127         */
 128         vga_init();
 129         fb_info.cursor.visible = B_FALSE;
 130         vga_cursor_display(B_TRUE);
 131 
 132         if (fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0)
 133                 vga_clear(cons_color);
 134 #endif /* _BOOT */
 135 
 136         bcons_dev->bd_putchar = vga_drawc;
 137         bcons_dev->bd_eraseline = vga_eraseline;
 138         bcons_dev->bd_cursor = vga_cursor_display;
 139         bcons_dev->bd_setpos = vga_setpos;
 140         bcons_dev->bd_shift = vga_shiftline;
 141 }
 142 
 143 static void
 144 vga_init(void)
 145 {
 146         unsigned char val;
 147 
 148         /* set 16bit colors */
 149         val = vga_get_atr(VGA_ATR_MODE);
 150         val &= ~VGA_ATR_MODE_BLINK;
 151         val &= ~VGA_ATR_MODE_9WIDE;
 152         vga_set_atr(VGA_ATR_MODE, val);
 153 }
 154 
 155 void
 156 vga_cursor_display(boolean_t visible)
 157 {
 158         unsigned char val, msl;
 159 
 160         if (fb_info.cursor.visible == visible)
 161                 return;
 162 
 163         /*
 164          * Figure out the maximum scan line value.  We need this to set the
 165          * cursor size.
 166          */
 167         msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f;
 168 
 169         /*
 170          * Enable the cursor and set it's size.  Preserve the upper two
 171          * bits of the control register.
 172          * - Bits 0-4 are the starting scan line of the cursor.
 173          *   Scanning is done from top-to-bottom.  The top-most scan
 174          *   line is 0 and the bottom most scan line is the maximum scan
 175          *   line value.
 176          * - Bit 5 is the cursor disable bit.
 177          */
 178         val = vga_get_crtc(VGA_CRTC_CSSL) & 0xc0;

 179 
 180         if (visible == B_FALSE)
 181                 val |= (1 << 5);
 182 
 183         vga_set_crtc(VGA_CRTC_CSSL, val);
 184 
 185         /*
 186          * Continue setting the cursors size.
 187          * - Bits 0-4 are the ending scan line of the cursor.
 188          *   Scanning is done from top-to-bottom.  The top-most scan
 189          *   line is 0 and the bottom most scan line is the maximum scan
 190          *   line value.
 191          * - Bits 5-6 are the cursor skew.
 192          */
 193         vga_set_crtc(VGA_CRTC_CESL, msl);
 194 }
 195 
 196 static void
 197 vga_eraseline_impl(int x, int y, int color)

 198 {
 199         unsigned short val, *buf;
 200         int i;
 201 
 202         buf = VGA_SCREEN + x + y * VGA_TEXT_COLS;
 203         val = (color << 8) | ' ';
 204         for (i = x; i < VGA_TEXT_COLS; i++)
 205                 buf[i] = val;
 206 }
 207 
 208 static void
 209 vga_eraseline(void)
 210 {
 211         int x, y;
 212 
 213         x = fb_info.cursor.pos.x;
 214         y = fb_info.cursor.pos.y;
 215         vga_eraseline_impl(x, y, cons_color);
 216 }
 217 
 218 static void
 219 vga_shiftline(int chars)
 220 {
 221         unsigned short *src, *dst;
 222         int x, y, len;
 223 
 224         x = fb_info.cursor.pos.x;
 225         y = fb_info.cursor.pos.y;
 226         len = VGA_TEXT_COLS - x - chars;
 227 
 228         src = VGA_SCREEN + x + y * VGA_TEXT_COLS;
 229         dst = src + chars;
 230         if (dst <= src) {
 231                 do {
 232                         *dst++ = *src++;
 233                 } while (--len != 0);
 234         } else {
 235                 dst += len;
 236                 src += len;
 237                 do {
 238                         *--dst = *--src;
 239                 } while (--len != 0);
 240         }
 241 }
 242 
 243 static void
 244 vga_clear(int color)
 245 {
 246         int i;
 247 
 248         for (i = 0; i < VGA_TEXT_ROWS; i++)
 249                 vga_eraseline_impl(0, i, color);
 250 }
 251 
 252 static void
 253 vga_drawc(int c)
 254 {
 255         int row;
 256         int col;
 257 
 258         vga_getpos(&row, &col);
 259 
 260         if (c == '\n') {
 261                 if (row < fb_info.terminal.y - 1)
 262                         vga_setpos(row + 1, col);
 263                 else
 264                         vga_scroll(cons_color);
 265                 return;
 266         }
 267 
 268         VGA_SCREEN[row*VGA_TEXT_COLS + col] = (cons_color << 8) | c;
 269 
 270         if (col < VGA_TEXT_COLS - 1)
 271                 vga_setpos(row, col + 1);
 272         else if (row < VGA_TEXT_ROWS - 1)
 273                 vga_setpos(row + 1, 0);
 274         else {
 275                 vga_setpos(row, 0);
 276                 vga_scroll(cons_color);
 277         }
 278 }
 279 
 280 static void
 281 vga_scroll(int color)
 282 {

 283         int i;
 284 
 285         for (i = 0; i < (VGA_TEXT_ROWS - 1) * VGA_TEXT_COLS; i++) {


 286                 VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS];
 287         }
 288         vga_eraseline_impl(0, VGA_TEXT_ROWS - 1, color);


 289 }
 290 
 291 static void
 292 vga_setpos(int row, int col)
 293 {
 294         int off;
 295 
 296         if (row < 0)
 297                 row = 0;
 298         if (row >= fb_info.terminal.y)
 299                 row = fb_info.terminal.y - 1;
 300         if (col < 0)
 301                 col = 0;
 302         if (col >= fb_info.terminal.x)
 303                 col = fb_info.terminal.x - 1;
 304 
 305         off = row * VGA_TEXT_COLS + col;
 306         vga_set_crtc(VGA_CRTC_CLAH, off >> 8);
 307         vga_set_crtc(VGA_CRTC_CLAL, off & 0xff);
 308 
 309         fb_info.cursor.pos.y = row;
 310         fb_info.cursor.pos.x = col;
 311 }
 312 
 313 static void
 314 vga_getpos(int *row, int *col)
 315 {
 316         int off;
 317 
 318         off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL);
 319         *row = off / VGA_TEXT_COLS;
 320         *col = off % VGA_TEXT_COLS;
 321 }
 322 
 323 static void
 324 vga_set_atr(int index, unsigned char val)
 325 {
 326         (void) inb(VGA_REG_ADDR + CGA_STAT);
 327         outb(VGA_REG_ADDR + VGA_ATR_AD, index);
 328         outb(VGA_REG_ADDR + VGA_ATR_AD, val);
 329 
 330         (void) inb(VGA_REG_ADDR + CGA_STAT);
 331         outb(VGA_REG_ADDR + VGA_ATR_AD, VGA_ATR_ENB_PLT);
 332 }
 333 
 334 static unsigned char
 335 vga_get_atr(int index)
 336 {
 337         unsigned char val;
 338 
 339         (void) inb(VGA_REG_ADDR + CGA_STAT);
 340         outb(VGA_REG_ADDR + VGA_ATR_AD, index);
 341         val = inb(VGA_REG_ADDR + VGA_ATR_DATA);
 342 
 343         (void) inb(VGA_REG_ADDR + CGA_STAT);
 344         outb(VGA_REG_ADDR + VGA_ATR_AD, VGA_ATR_ENB_PLT);
 345 
 346         return (val);
 347 }
 348 
 349 static void
 350 vga_set_crtc(int index, unsigned char val)
 351 {
 352         outb(VGA_REG_ADDR + VGA_CRTC_ADR, index);
 353         outb(VGA_REG_ADDR + VGA_CRTC_DATA, val);
 354 }
 355 
 356 static unsigned char
 357 vga_get_crtc(int index)
 358 {
 359         outb(VGA_REG_ADDR + VGA_CRTC_ADR, index);
 360         return (inb(VGA_REG_ADDR + VGA_CRTC_DATA));
 361 }