xref: /onnv-gate/usr/src/uts/i86pc/boot/boot_vga.c (revision 5084:7d838c5c0eed)
13446Smrj /*
23446Smrj  * CDDL HEADER START
33446Smrj  *
43446Smrj  * The contents of this file are subject to the terms of the
53446Smrj  * Common Development and Distribution License (the "License").
63446Smrj  * You may not use this file except in compliance with the License.
73446Smrj  *
83446Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93446Smrj  * or http://www.opensolaris.org/os/licensing.
103446Smrj  * See the License for the specific language governing permissions
113446Smrj  * and limitations under the License.
123446Smrj  *
133446Smrj  * When distributing Covered Code, include this CDDL HEADER in each
143446Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153446Smrj  * If applicable, add the following below this CDDL HEADER, with the
163446Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
173446Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
183446Smrj  *
193446Smrj  * CDDL HEADER END
203446Smrj  */
213446Smrj 
223446Smrj /*
233446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
243446Smrj  * Use is subject to license terms.
253446Smrj  */
263446Smrj 
273446Smrj #pragma ident	"%Z%%M%	%I%	%E% SMI"
283446Smrj 
293446Smrj /*
303446Smrj  * Miniature VGA driver for bootstrap.
313446Smrj  */
323446Smrj 
333446Smrj #include <sys/archsystm.h>
343446Smrj #include <sys/vgareg.h>
353446Smrj 
363446Smrj #include "boot_vga.h"
373446Smrj 
383446Smrj #if defined(_BOOT)
39*5084Sjohnlev #include "../dboot/dboot_asm.h"
403446Smrj #include "../dboot/dboot_xboot.h"
413446Smrj #endif
423446Smrj 
433446Smrj #define	VGA_COLOR_CRTC_INDEX	0x3d4
443446Smrj #define	VGA_COLOR_CRTC_DATA	0x3d5
45*5084Sjohnlev 
46*5084Sjohnlev #if defined(__xpv) && defined(_BOOT)
47*5084Sjohnlev 
48*5084Sjohnlev /*
49*5084Sjohnlev  * Device memory address
50*5084Sjohnlev  *
51*5084Sjohnlev  * In dboot under the hypervisor we don't have any memory mappings
52*5084Sjohnlev  * for the first meg of low memory so we can't access devices there.
53*5084Sjohnlev  * Intead we've mapped the device memory that we need to access into
54*5084Sjohnlev  * a local variable within dboot so we can access the device memory
55*5084Sjohnlev  * there.
56*5084Sjohnlev  */
57*5084Sjohnlev extern unsigned short *video_fb;
58*5084Sjohnlev #define	VGA_SCREEN		((unsigned short *)video_fb)
59*5084Sjohnlev 
60*5084Sjohnlev #else /* __xpv && _BOOT */
61*5084Sjohnlev 
62*5084Sjohnlev /* Device memory address */
633446Smrj #define	VGA_SCREEN		((unsigned short *)0xb8000)
643446Smrj 
65*5084Sjohnlev #endif /* __xpv && _BOOT */
66*5084Sjohnlev 
67*5084Sjohnlev 
683446Smrj static void vga_set_crtc(int index, unsigned char val);
693446Smrj static unsigned char vga_get_crtc(int index);
703446Smrj 
713446Smrj void
vga_cursor_display(void)72*5084Sjohnlev vga_cursor_display(void)
73*5084Sjohnlev {
74*5084Sjohnlev 	unsigned char val, msl;
75*5084Sjohnlev 
76*5084Sjohnlev 	/*
77*5084Sjohnlev 	 * Figure out the maximum scan line value.  We need this to set the
78*5084Sjohnlev 	 * cursor size.
79*5084Sjohnlev 	 */
80*5084Sjohnlev 	msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f;
81*5084Sjohnlev 
82*5084Sjohnlev 	/*
83*5084Sjohnlev 	 * Enable the cursor and set it's size.  Preserve the upper two
84*5084Sjohnlev 	 * bits of the control register.
85*5084Sjohnlev 	 * - Bits 0-4 are the starting scan line of the cursor.
86*5084Sjohnlev 	 *   Scanning is done from top-to-bottom.  The top-most scan
87*5084Sjohnlev 	 *   line is 0 and the bottom most scan line is the maximum scan
88*5084Sjohnlev 	 *   line value.
89*5084Sjohnlev 	 * - Bit 5 is the cursor disable bit.
90*5084Sjohnlev 	 */
91*5084Sjohnlev 	val = vga_get_crtc(VGA_CRTC_CSSL);
92*5084Sjohnlev 	vga_set_crtc(VGA_CRTC_CSSL, (val & 0xc) | ((msl - 2) & 0x1f));
93*5084Sjohnlev 
94*5084Sjohnlev 	/*
95*5084Sjohnlev 	 * Continue setting the cursors size.
96*5084Sjohnlev 	 * - Bits 0-4 are the ending scan line of the cursor.
97*5084Sjohnlev 	 *   Scanning is done from top-to-bottom.  The top-most scan
98*5084Sjohnlev 	 *   line is 0 and the bottom most scan line is the maximum scan
99*5084Sjohnlev 	 *   line value.
100*5084Sjohnlev 	 * - Bits 5-6 are the cursor skew.
101*5084Sjohnlev 	 */
102*5084Sjohnlev 	vga_set_crtc(VGA_CRTC_CESL, msl);
103*5084Sjohnlev }
104*5084Sjohnlev 
105*5084Sjohnlev 
106*5084Sjohnlev void
vga_clear(int color)1073446Smrj vga_clear(int color)
1083446Smrj {
1093446Smrj 	unsigned short val;
1103446Smrj 	int i;
1113446Smrj 
1123446Smrj 	val = (color << 8) | ' ';
1133446Smrj 
1143446Smrj 	for (i = 0; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
1153446Smrj 		VGA_SCREEN[i] = val;
1163446Smrj 	}
1173446Smrj }
1183446Smrj 
1193446Smrj void
vga_drawc(int c,int color)1203446Smrj vga_drawc(int c, int color)
1213446Smrj {
1223446Smrj 	int row;
1233446Smrj 	int col;
1243446Smrj 
1253446Smrj 	vga_getpos(&row, &col);
1263446Smrj 	VGA_SCREEN[row*VGA_TEXT_COLS + col] = (color << 8) | c;
1273446Smrj }
1283446Smrj 
1293446Smrj void
vga_scroll(int color)1303446Smrj vga_scroll(int color)
1313446Smrj {
1323446Smrj 	unsigned short val;
1333446Smrj 	int i;
1343446Smrj 
1353446Smrj 	val = (color << 8) | ' ';
1363446Smrj 
1373446Smrj 	for (i = 0; i < (VGA_TEXT_ROWS-1)*VGA_TEXT_COLS; i++) {
1383446Smrj 		VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS];
1393446Smrj 	}
1403446Smrj 	for (; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
1413446Smrj 		VGA_SCREEN[i] = val;
1423446Smrj 	}
1433446Smrj }
1443446Smrj 
1453446Smrj void
vga_setpos(int row,int col)1463446Smrj vga_setpos(int row, int col)
1473446Smrj {
1483446Smrj 	int off;
1493446Smrj 
1503446Smrj 	off = row * VGA_TEXT_COLS + col;
1513446Smrj 	vga_set_crtc(VGA_CRTC_CLAH, off >> 8);
1523446Smrj 	vga_set_crtc(VGA_CRTC_CLAL, off & 0xff);
1533446Smrj }
1543446Smrj 
1553446Smrj void
vga_getpos(int * row,int * col)1563446Smrj vga_getpos(int *row, int *col)
1573446Smrj {
1583446Smrj 	int off;
1593446Smrj 
160*5084Sjohnlev 	off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL);
1613446Smrj 	*row = off / VGA_TEXT_COLS;
1623446Smrj 	*col = off % VGA_TEXT_COLS;
1633446Smrj }
1643446Smrj 
1653446Smrj static void
vga_set_crtc(int index,unsigned char val)1663446Smrj vga_set_crtc(int index, unsigned char val)
1673446Smrj {
1683446Smrj 	outb(VGA_COLOR_CRTC_INDEX, index);
1693446Smrj 	outb(VGA_COLOR_CRTC_DATA, val);
1703446Smrj }
1713446Smrj 
1723446Smrj static unsigned char
vga_get_crtc(int index)1733446Smrj vga_get_crtc(int index)
1743446Smrj {
1753446Smrj 	outb(VGA_COLOR_CRTC_INDEX, index);
1763446Smrj 	return (inb(VGA_COLOR_CRTC_DATA));
1773446Smrj }
178