1ae115bc7Smrj /* 2ae115bc7Smrj * CDDL HEADER START 3ae115bc7Smrj * 4ae115bc7Smrj * The contents of this file are subject to the terms of the 5ae115bc7Smrj * Common Development and Distribution License (the "License"). 6ae115bc7Smrj * You may not use this file except in compliance with the License. 7ae115bc7Smrj * 8ae115bc7Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9ae115bc7Smrj * or http://www.opensolaris.org/os/licensing. 10ae115bc7Smrj * See the License for the specific language governing permissions 11ae115bc7Smrj * and limitations under the License. 12ae115bc7Smrj * 13ae115bc7Smrj * When distributing Covered Code, include this CDDL HEADER in each 14ae115bc7Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15ae115bc7Smrj * If applicable, add the following below this CDDL HEADER, with the 16ae115bc7Smrj * fields enclosed by brackets "[]" replaced with your own identifying 17ae115bc7Smrj * information: Portions Copyright [yyyy] [name of copyright owner] 18ae115bc7Smrj * 19ae115bc7Smrj * CDDL HEADER END 20ae115bc7Smrj */ 21ae115bc7Smrj 22ae115bc7Smrj /* 23ae115bc7Smrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24ae115bc7Smrj * Use is subject to license terms. 25ae115bc7Smrj */ 26ae115bc7Smrj 27ae115bc7Smrj #pragma ident "%Z%%M% %I% %E% SMI" 28ae115bc7Smrj 29ae115bc7Smrj /* 30ae115bc7Smrj * Miniature VGA driver for bootstrap. 31ae115bc7Smrj */ 32ae115bc7Smrj 33ae115bc7Smrj #include <sys/archsystm.h> 34ae115bc7Smrj #include <sys/vgareg.h> 35ae115bc7Smrj 36ae115bc7Smrj #include "boot_vga.h" 37ae115bc7Smrj 38ae115bc7Smrj #if defined(_BOOT) 39*843e1988Sjohnlev #include "../dboot/dboot_asm.h" 40ae115bc7Smrj #include "../dboot/dboot_xboot.h" 41ae115bc7Smrj #endif 42ae115bc7Smrj 43ae115bc7Smrj #define VGA_COLOR_CRTC_INDEX 0x3d4 44ae115bc7Smrj #define VGA_COLOR_CRTC_DATA 0x3d5 45*843e1988Sjohnlev 46*843e1988Sjohnlev #if defined(__xpv) && defined(_BOOT) 47*843e1988Sjohnlev 48*843e1988Sjohnlev /* 49*843e1988Sjohnlev * Device memory address 50*843e1988Sjohnlev * 51*843e1988Sjohnlev * In dboot under the hypervisor we don't have any memory mappings 52*843e1988Sjohnlev * for the first meg of low memory so we can't access devices there. 53*843e1988Sjohnlev * Intead we've mapped the device memory that we need to access into 54*843e1988Sjohnlev * a local variable within dboot so we can access the device memory 55*843e1988Sjohnlev * there. 56*843e1988Sjohnlev */ 57*843e1988Sjohnlev extern unsigned short *video_fb; 58*843e1988Sjohnlev #define VGA_SCREEN ((unsigned short *)video_fb) 59*843e1988Sjohnlev 60*843e1988Sjohnlev #else /* __xpv && _BOOT */ 61*843e1988Sjohnlev 62*843e1988Sjohnlev /* Device memory address */ 63ae115bc7Smrj #define VGA_SCREEN ((unsigned short *)0xb8000) 64ae115bc7Smrj 65*843e1988Sjohnlev #endif /* __xpv && _BOOT */ 66*843e1988Sjohnlev 67*843e1988Sjohnlev 68ae115bc7Smrj static void vga_set_crtc(int index, unsigned char val); 69ae115bc7Smrj static unsigned char vga_get_crtc(int index); 70ae115bc7Smrj 71ae115bc7Smrj void 72*843e1988Sjohnlev vga_cursor_display(void) 73*843e1988Sjohnlev { 74*843e1988Sjohnlev unsigned char val, msl; 75*843e1988Sjohnlev 76*843e1988Sjohnlev /* 77*843e1988Sjohnlev * Figure out the maximum scan line value. We need this to set the 78*843e1988Sjohnlev * cursor size. 79*843e1988Sjohnlev */ 80*843e1988Sjohnlev msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f; 81*843e1988Sjohnlev 82*843e1988Sjohnlev /* 83*843e1988Sjohnlev * Enable the cursor and set it's size. Preserve the upper two 84*843e1988Sjohnlev * bits of the control register. 85*843e1988Sjohnlev * - Bits 0-4 are the starting scan line of the cursor. 86*843e1988Sjohnlev * Scanning is done from top-to-bottom. The top-most scan 87*843e1988Sjohnlev * line is 0 and the bottom most scan line is the maximum scan 88*843e1988Sjohnlev * line value. 89*843e1988Sjohnlev * - Bit 5 is the cursor disable bit. 90*843e1988Sjohnlev */ 91*843e1988Sjohnlev val = vga_get_crtc(VGA_CRTC_CSSL); 92*843e1988Sjohnlev vga_set_crtc(VGA_CRTC_CSSL, (val & 0xc) | ((msl - 2) & 0x1f)); 93*843e1988Sjohnlev 94*843e1988Sjohnlev /* 95*843e1988Sjohnlev * Continue setting the cursors size. 96*843e1988Sjohnlev * - Bits 0-4 are the ending scan line of the cursor. 97*843e1988Sjohnlev * Scanning is done from top-to-bottom. The top-most scan 98*843e1988Sjohnlev * line is 0 and the bottom most scan line is the maximum scan 99*843e1988Sjohnlev * line value. 100*843e1988Sjohnlev * - Bits 5-6 are the cursor skew. 101*843e1988Sjohnlev */ 102*843e1988Sjohnlev vga_set_crtc(VGA_CRTC_CESL, msl); 103*843e1988Sjohnlev } 104*843e1988Sjohnlev 105*843e1988Sjohnlev 106*843e1988Sjohnlev void 107ae115bc7Smrj vga_clear(int color) 108ae115bc7Smrj { 109ae115bc7Smrj unsigned short val; 110ae115bc7Smrj int i; 111ae115bc7Smrj 112ae115bc7Smrj val = (color << 8) | ' '; 113ae115bc7Smrj 114ae115bc7Smrj for (i = 0; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) { 115ae115bc7Smrj VGA_SCREEN[i] = val; 116ae115bc7Smrj } 117ae115bc7Smrj } 118ae115bc7Smrj 119ae115bc7Smrj void 120ae115bc7Smrj vga_drawc(int c, int color) 121ae115bc7Smrj { 122ae115bc7Smrj int row; 123ae115bc7Smrj int col; 124ae115bc7Smrj 125ae115bc7Smrj vga_getpos(&row, &col); 126ae115bc7Smrj VGA_SCREEN[row*VGA_TEXT_COLS + col] = (color << 8) | c; 127ae115bc7Smrj } 128ae115bc7Smrj 129ae115bc7Smrj void 130ae115bc7Smrj vga_scroll(int color) 131ae115bc7Smrj { 132ae115bc7Smrj unsigned short val; 133ae115bc7Smrj int i; 134ae115bc7Smrj 135ae115bc7Smrj val = (color << 8) | ' '; 136ae115bc7Smrj 137ae115bc7Smrj for (i = 0; i < (VGA_TEXT_ROWS-1)*VGA_TEXT_COLS; i++) { 138ae115bc7Smrj VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS]; 139ae115bc7Smrj } 140ae115bc7Smrj for (; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) { 141ae115bc7Smrj VGA_SCREEN[i] = val; 142ae115bc7Smrj } 143ae115bc7Smrj } 144ae115bc7Smrj 145ae115bc7Smrj void 146ae115bc7Smrj vga_setpos(int row, int col) 147ae115bc7Smrj { 148ae115bc7Smrj int off; 149ae115bc7Smrj 150ae115bc7Smrj off = row * VGA_TEXT_COLS + col; 151ae115bc7Smrj vga_set_crtc(VGA_CRTC_CLAH, off >> 8); 152ae115bc7Smrj vga_set_crtc(VGA_CRTC_CLAL, off & 0xff); 153ae115bc7Smrj } 154ae115bc7Smrj 155ae115bc7Smrj void 156ae115bc7Smrj vga_getpos(int *row, int *col) 157ae115bc7Smrj { 158ae115bc7Smrj int off; 159ae115bc7Smrj 160*843e1988Sjohnlev off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL); 161ae115bc7Smrj *row = off / VGA_TEXT_COLS; 162ae115bc7Smrj *col = off % VGA_TEXT_COLS; 163ae115bc7Smrj } 164ae115bc7Smrj 165ae115bc7Smrj static void 166ae115bc7Smrj vga_set_crtc(int index, unsigned char val) 167ae115bc7Smrj { 168ae115bc7Smrj outb(VGA_COLOR_CRTC_INDEX, index); 169ae115bc7Smrj outb(VGA_COLOR_CRTC_DATA, val); 170ae115bc7Smrj } 171ae115bc7Smrj 172ae115bc7Smrj static unsigned char 173ae115bc7Smrj vga_get_crtc(int index) 174ae115bc7Smrj { 175ae115bc7Smrj outb(VGA_COLOR_CRTC_INDEX, index); 176ae115bc7Smrj return (inb(VGA_COLOR_CRTC_DATA)); 177ae115bc7Smrj } 178