xref: /illumos-gate/usr/src/uts/i86pc/boot/boot_vga.c (revision 843e1988)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * 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.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21ae115bc7Smrj 
227c478bd9Sstevel@tonic-gate /*
23ae115bc7Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Miniature VGA driver for bootstrap.
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/archsystm.h>
347c478bd9Sstevel@tonic-gate #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
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #define	VGA_COLOR_CRTC_INDEX	0x3d4
447c478bd9Sstevel@tonic-gate #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 */
637c478bd9Sstevel@tonic-gate #define	VGA_SCREEN		((unsigned short *)0xb8000)
647c478bd9Sstevel@tonic-gate 
65*843e1988Sjohnlev #endif /* __xpv && _BOOT */
66*843e1988Sjohnlev 
67*843e1988Sjohnlev 
687c478bd9Sstevel@tonic-gate static void vga_set_crtc(int index, unsigned char val);
697c478bd9Sstevel@tonic-gate static unsigned char vga_get_crtc(int index);
707c478bd9Sstevel@tonic-gate 
71*843e1988Sjohnlev 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 
1067c478bd9Sstevel@tonic-gate void
1077c478bd9Sstevel@tonic-gate vga_clear(int color)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	unsigned short val;
1107c478bd9Sstevel@tonic-gate 	int i;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	val = (color << 8) | ' ';
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	for (i = 0; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
1157c478bd9Sstevel@tonic-gate 		VGA_SCREEN[i] = val;
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate void
1207c478bd9Sstevel@tonic-gate vga_drawc(int c, int color)
1217c478bd9Sstevel@tonic-gate {
1227c478bd9Sstevel@tonic-gate 	int row;
1237c478bd9Sstevel@tonic-gate 	int col;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	vga_getpos(&row, &col);
1267c478bd9Sstevel@tonic-gate 	VGA_SCREEN[row*VGA_TEXT_COLS + col] = (color << 8) | c;
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate void
1307c478bd9Sstevel@tonic-gate vga_scroll(int color)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	unsigned short val;
1337c478bd9Sstevel@tonic-gate 	int i;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	val = (color << 8) | ' ';
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	for (i = 0; i < (VGA_TEXT_ROWS-1)*VGA_TEXT_COLS; i++) {
1387c478bd9Sstevel@tonic-gate 		VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS];
1397c478bd9Sstevel@tonic-gate 	}
1407c478bd9Sstevel@tonic-gate 	for (; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
1417c478bd9Sstevel@tonic-gate 		VGA_SCREEN[i] = val;
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate void
1467c478bd9Sstevel@tonic-gate vga_setpos(int row, int col)
1477c478bd9Sstevel@tonic-gate {
1487c478bd9Sstevel@tonic-gate 	int off;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	off = row * VGA_TEXT_COLS + col;
1517c478bd9Sstevel@tonic-gate 	vga_set_crtc(VGA_CRTC_CLAH, off >> 8);
1527c478bd9Sstevel@tonic-gate 	vga_set_crtc(VGA_CRTC_CLAL, off & 0xff);
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate void
1567c478bd9Sstevel@tonic-gate vga_getpos(int *row, int *col)
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate 	int off;
1597c478bd9Sstevel@tonic-gate 
160*843e1988Sjohnlev 	off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL);
1617c478bd9Sstevel@tonic-gate 	*row = off / VGA_TEXT_COLS;
1627c478bd9Sstevel@tonic-gate 	*col = off % VGA_TEXT_COLS;
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate static void
1667c478bd9Sstevel@tonic-gate vga_set_crtc(int index, unsigned char val)
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate 	outb(VGA_COLOR_CRTC_INDEX, index);
1697c478bd9Sstevel@tonic-gate 	outb(VGA_COLOR_CRTC_DATA, val);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate static unsigned char
1737c478bd9Sstevel@tonic-gate vga_get_crtc(int index)
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate 	outb(VGA_COLOR_CRTC_INDEX, index);
1767c478bd9Sstevel@tonic-gate 	return (inb(VGA_COLOR_CRTC_DATA));
1777c478bd9Sstevel@tonic-gate }
178