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