/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Miniature VGA driver for bootstrap. */ #include #include #include "boot_vga.h" #if defined(_BOOT) #include "../dboot/dboot_asm.h" #include "../dboot/dboot_xboot.h" #endif #define VGA_COLOR_CRTC_INDEX 0x3d4 #define VGA_COLOR_CRTC_DATA 0x3d5 #if defined(__xpv) && defined(_BOOT) /* * Device memory address * * In dboot under the hypervisor we don't have any memory mappings * for the first meg of low memory so we can't access devices there. * Intead we've mapped the device memory that we need to access into * a local variable within dboot so we can access the device memory * there. */ extern unsigned short *video_fb; #define VGA_SCREEN ((unsigned short *)video_fb) #else /* __xpv && _BOOT */ /* Device memory address */ #define VGA_SCREEN ((unsigned short *)0xb8000) #endif /* __xpv && _BOOT */ static void vga_set_crtc(int index, unsigned char val); static unsigned char vga_get_crtc(int index); void vga_cursor_display(void) { unsigned char val, msl; /* * Figure out the maximum scan line value. We need this to set the * cursor size. */ msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f; /* * Enable the cursor and set it's size. Preserve the upper two * bits of the control register. * - Bits 0-4 are the starting scan line of the cursor. * Scanning is done from top-to-bottom. The top-most scan * line is 0 and the bottom most scan line is the maximum scan * line value. * - Bit 5 is the cursor disable bit. */ val = vga_get_crtc(VGA_CRTC_CSSL); vga_set_crtc(VGA_CRTC_CSSL, (val & 0xc) | ((msl - 2) & 0x1f)); /* * Continue setting the cursors size. * - Bits 0-4 are the ending scan line of the cursor. * Scanning is done from top-to-bottom. The top-most scan * line is 0 and the bottom most scan line is the maximum scan * line value. * - Bits 5-6 are the cursor skew. */ vga_set_crtc(VGA_CRTC_CESL, msl); } void vga_clear(int color) { unsigned short val; int i; val = (color << 8) | ' '; for (i = 0; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) { VGA_SCREEN[i] = val; } } void vga_drawc(int c, int color) { int row; int col; vga_getpos(&row, &col); VGA_SCREEN[row*VGA_TEXT_COLS + col] = (color << 8) | c; } void vga_scroll(int color) { unsigned short val; int i; val = (color << 8) | ' '; for (i = 0; i < (VGA_TEXT_ROWS-1)*VGA_TEXT_COLS; i++) { VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS]; } for (; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) { VGA_SCREEN[i] = val; } } void vga_setpos(int row, int col) { int off; off = row * VGA_TEXT_COLS + col; vga_set_crtc(VGA_CRTC_CLAH, off >> 8); vga_set_crtc(VGA_CRTC_CLAL, off & 0xff); } void vga_getpos(int *row, int *col) { int off; off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL); *row = off / VGA_TEXT_COLS; *col = off % VGA_TEXT_COLS; } static void vga_set_crtc(int index, unsigned char val) { outb(VGA_COLOR_CRTC_INDEX, index); outb(VGA_COLOR_CRTC_DATA, val); } static unsigned char vga_get_crtc(int index) { outb(VGA_COLOR_CRTC_INDEX, index); return (inb(VGA_COLOR_CRTC_DATA)); }