1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 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 } 178