mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
merge
This commit is contained in:
commit
50f25faffc
14 files changed
+12081
-99
No files matched your search
@@ -1670,6 +1670,32 @@ void __init setup_arch(char **cmdline_p)
|
||||
screen_info.orig_video_cols = 80;
|
||||
screen_info.orig_video_ega_bx = 3;
|
||||
screen_info.orig_video_points = 16;
|
||||
if (xen_start_info->con_info_size >= sizeof(console_info_t)) {
|
||||
const console_info_t *console_info = (void *)xen_start_info + xen_start_info->con_info_offs;
|
||||
|
||||
screen_info.orig_video_mode = console_info->txt_mode;
|
||||
screen_info.orig_video_isVGA = console_info->video_type;
|
||||
screen_info.orig_video_lines = console_info->video_height;
|
||||
screen_info.orig_video_cols = console_info->video_width;
|
||||
screen_info.orig_video_points = console_info->txt_points;
|
||||
screen_info.lfb_width = console_info->video_width;
|
||||
screen_info.lfb_height = console_info->video_height;
|
||||
screen_info.lfb_depth = console_info->lfb_depth;
|
||||
screen_info.lfb_base = console_info->lfb_base;
|
||||
screen_info.lfb_size = console_info->lfb_size;
|
||||
screen_info.lfb_linelength = console_info->lfb_linelen;
|
||||
screen_info.red_size = console_info->red_size;
|
||||
screen_info.red_pos = console_info->red_pos;
|
||||
screen_info.green_size = console_info->green_size;
|
||||
screen_info.green_pos = console_info->green_pos;
|
||||
screen_info.blue_size = console_info->blue_size;
|
||||
screen_info.blue_pos = console_info->blue_pos;
|
||||
screen_info.rsvd_size = console_info->rsvd_size;
|
||||
screen_info.rsvd_pos = console_info->rsvd_pos;
|
||||
}
|
||||
screen_info.orig_y = screen_info.orig_video_lines - 1;
|
||||
xen_start_info->console_mfn = 0;
|
||||
xen_start_info->console_evtchn = 0;
|
||||
} else
|
||||
screen_info.orig_video_isVGA = 0;
|
||||
|
||||
|
||||
@@ -648,6 +648,32 @@ void __init setup_arch(char **cmdline_p)
|
||||
screen_info.orig_video_cols = 80;
|
||||
screen_info.orig_video_ega_bx = 3;
|
||||
screen_info.orig_video_points = 16;
|
||||
if (xen_start_info->con_info_size >= sizeof(console_info_t)) {
|
||||
const console_info_t *console_info = (void *)xen_start_info + xen_start_info->con_info_offs;
|
||||
|
||||
screen_info.orig_video_mode = console_info->txt_mode;
|
||||
screen_info.orig_video_isVGA = console_info->video_type;
|
||||
screen_info.orig_video_lines = console_info->video_height;
|
||||
screen_info.orig_video_cols = console_info->video_width;
|
||||
screen_info.orig_video_points = console_info->txt_points;
|
||||
screen_info.lfb_width = console_info->video_width;
|
||||
screen_info.lfb_height = console_info->video_height;
|
||||
screen_info.lfb_depth = console_info->lfb_depth;
|
||||
screen_info.lfb_base = console_info->lfb_base;
|
||||
screen_info.lfb_size = console_info->lfb_size;
|
||||
screen_info.lfb_linelength = console_info->lfb_linelen;
|
||||
screen_info.red_size = console_info->red_size;
|
||||
screen_info.red_pos = console_info->red_pos;
|
||||
screen_info.green_size = console_info->green_size;
|
||||
screen_info.green_pos = console_info->green_pos;
|
||||
screen_info.blue_size = console_info->blue_size;
|
||||
screen_info.blue_pos = console_info->blue_pos;
|
||||
screen_info.rsvd_size = console_info->rsvd_size;
|
||||
screen_info.rsvd_pos = console_info->rsvd_pos;
|
||||
}
|
||||
screen_info.orig_y = screen_info.orig_video_lines - 1;
|
||||
xen_start_info->console_mfn = 0;
|
||||
xen_start_info->console_evtchn = 0;
|
||||
} else
|
||||
screen_info.orig_video_isVGA = 0;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xen/smp.h>
|
||||
#include <xen/delay.h>
|
||||
#include <xen/event.h>
|
||||
#include <xen/console.h>
|
||||
#include <xen/elf.h>
|
||||
#include <xen/kernel.h>
|
||||
#include <xen/domain.h>
|
||||
@@ -334,8 +335,8 @@ int construct_dom0(struct domain *d,
|
||||
vphysmap_start = round_pgup(vinitrd_end);
|
||||
vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long));
|
||||
vstartinfo_start = round_pgup(vphysmap_end);
|
||||
vstartinfo_end = vstartinfo_start + PAGE_SIZE;
|
||||
vpt_start = vstartinfo_end;
|
||||
vstartinfo_end = vstartinfo_start + sizeof(start_info_t) + sizeof(console_info_t);
|
||||
vpt_start = round_pgup(vstartinfo_end);
|
||||
for ( nr_pt_pages = 2; ; nr_pt_pages++ )
|
||||
{
|
||||
vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE);
|
||||
@@ -770,6 +771,12 @@ int construct_dom0(struct domain *d,
|
||||
if ( cmdline != NULL )
|
||||
strncpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line)-1);
|
||||
|
||||
if ( fill_console_start_info((void *)(si + 1)) )
|
||||
{
|
||||
si->con_info_offs = sizeof(start_info_t);
|
||||
si->con_info_size = sizeof(console_info_t);
|
||||
}
|
||||
|
||||
/* Reinstate the caller's page tables. */
|
||||
write_ptbase(current);
|
||||
local_irq_enable();
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
subdir-y += char
|
||||
subdir-$(HAS_ACPI) += acpi
|
||||
subdir-y += video
|
||||
+56
-95
@@ -22,6 +22,8 @@
|
||||
#include <xen/delay.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/shutdown.h>
|
||||
#include <xen/font.h>
|
||||
#include <xen/vga.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/debugger.h>
|
||||
#include <asm/io.h>
|
||||
@@ -53,6 +55,8 @@ static char printk_prefix[16] = "";
|
||||
|
||||
static int sercon_handle = -1;
|
||||
static int vgacon_enabled = 0;
|
||||
static int vgacon_keep = 0;
|
||||
static const struct font_desc *font;
|
||||
|
||||
static DEFINE_SPINLOCK(console_lock);
|
||||
|
||||
@@ -64,7 +68,7 @@ static DEFINE_SPINLOCK(console_lock);
|
||||
|
||||
/* VGA text (mode 3) definitions. */
|
||||
#define COLUMNS 80
|
||||
#define LINES 25
|
||||
#define LINES vgacon_enabled
|
||||
#define ATTRIBUTE 7
|
||||
#define VIDEO_SIZE (COLUMNS * LINES * 2)
|
||||
|
||||
@@ -73,105 +77,47 @@ static void cls(void)
|
||||
{
|
||||
memset(video, 0, VIDEO_SIZE);
|
||||
xpos = ypos = 0;
|
||||
outw(10+(1<<(5+8)), 0x3d4); /* cursor off */
|
||||
vga_cursor_off();
|
||||
}
|
||||
|
||||
static int detect_video(void *video_base)
|
||||
{
|
||||
volatile u16 *p = (volatile u16 *)video_base;
|
||||
u16 saved1 = p[0], saved2 = p[1];
|
||||
int video_found = 1;
|
||||
|
||||
p[0] = 0xAA55;
|
||||
p[1] = 0x55AA;
|
||||
if ( (p[0] != 0xAA55) || (p[1] != 0x55AA) )
|
||||
video_found = 0;
|
||||
|
||||
p[0] = 0x55AA;
|
||||
p[1] = 0xAA55;
|
||||
if ( (p[0] != 0x55AA) || (p[1] != 0xAA55) )
|
||||
video_found = 0;
|
||||
|
||||
p[0] = saved1;
|
||||
p[1] = saved2;
|
||||
|
||||
return video_found;
|
||||
}
|
||||
|
||||
static int detect_vga(void)
|
||||
{
|
||||
/*
|
||||
* Look at a number of well-known locations. Even if video is not at
|
||||
* 0xB8000 right now, it will appear there when we set up text mode 3.
|
||||
*
|
||||
* We assume if there is any sign of a video adaptor then it is at least
|
||||
* VGA-compatible (surely noone runs CGA, EGA, .... these days?).
|
||||
*
|
||||
* These checks are basically to detect headless server boxes.
|
||||
*/
|
||||
return (detect_video(ioremap(0xA0000, VIDEO_SIZE)) ||
|
||||
detect_video(ioremap(0xB0000, VIDEO_SIZE)) ||
|
||||
detect_video(ioremap(0xB8000, VIDEO_SIZE)));
|
||||
}
|
||||
|
||||
/* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
|
||||
static void init_vga(void)
|
||||
{
|
||||
/* The following VGA state was saved from a chip in text mode 3. */
|
||||
static unsigned char regs[] = {
|
||||
/* Sequencer registers */
|
||||
0x03, 0x00, 0x03, 0x00, 0x02,
|
||||
/* CRTC registers */
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x20,
|
||||
0x0e, 0x00, 0x00, 0x01, 0xe0, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96,
|
||||
0xb9, 0xa3, 0xff,
|
||||
/* Graphic registers */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
|
||||
/* Attribute registers */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a,
|
||||
0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00
|
||||
};
|
||||
|
||||
int i, j = 0;
|
||||
volatile unsigned char tmp;
|
||||
|
||||
if ( !vgacon_enabled )
|
||||
return;
|
||||
|
||||
if ( !detect_vga() )
|
||||
video = setup_vga();
|
||||
if ( !video )
|
||||
{
|
||||
printk("No VGA adaptor detected!\n");
|
||||
vgacon_enabled = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
video = ioremap(0xB8000, VIDEO_SIZE);
|
||||
|
||||
tmp = inb(0x3da);
|
||||
outb(0x00, 0x3c0);
|
||||
|
||||
for ( i = 0; i < 5; i++ )
|
||||
outw((regs[j++] << 8) | i, 0x3c4);
|
||||
|
||||
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17]. */
|
||||
outw(((regs[5+17] & 0x7F) << 8) | 17, 0x3d4);
|
||||
|
||||
for ( i = 0; i < 25; i++ )
|
||||
outw((regs[j++] << 8) | i, 0x3d4);
|
||||
|
||||
for ( i = 0; i < 9; i++ )
|
||||
outw((regs[j++] << 8) | i, 0x3ce);
|
||||
|
||||
for ( i = 0; i < 21; i++ )
|
||||
switch ( vgacon_enabled )
|
||||
{
|
||||
tmp = inb(0x3da);
|
||||
outb(i, 0x3c0);
|
||||
outb(regs[j++], 0x3c0);
|
||||
case 25:
|
||||
case 30:
|
||||
font = &font_vga_8x16;
|
||||
break;
|
||||
case 28:
|
||||
case 34:
|
||||
font = &font_vga_8x14;
|
||||
break;
|
||||
case 43:
|
||||
case 50:
|
||||
case 60:
|
||||
font = &font_vga_8x8;
|
||||
break;
|
||||
default:
|
||||
vgacon_enabled = 25;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (font != NULL) && (vga_load_font(font, vgacon_enabled) < 0) )
|
||||
{
|
||||
vgacon_enabled = 25;
|
||||
font = NULL;
|
||||
}
|
||||
|
||||
tmp = inb(0x3da);
|
||||
outb(0x20, 0x3c0);
|
||||
|
||||
cls();
|
||||
}
|
||||
|
||||
@@ -180,7 +126,7 @@ static void put_newline(void)
|
||||
xpos = 0;
|
||||
ypos++;
|
||||
|
||||
if (ypos >= LINES)
|
||||
if ( ypos >= LINES )
|
||||
{
|
||||
ypos = LINES-1;
|
||||
memmove((char*)video,
|
||||
@@ -208,6 +154,21 @@ static void putchar_console(int c)
|
||||
}
|
||||
}
|
||||
|
||||
int fill_console_start_info(console_info_t *ci)
|
||||
{
|
||||
memset(ci, 0, sizeof(*ci));
|
||||
|
||||
if ( !vgacon_enabled )
|
||||
return 0;
|
||||
|
||||
ci->video_type = 1;
|
||||
ci->video_width = COLUMNS;
|
||||
ci->video_height = LINES;
|
||||
ci->txt_mode = 3;
|
||||
ci->txt_points = font ? font->height : 16;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ********************************************************
|
||||
@@ -478,9 +439,11 @@ void init_console(void)
|
||||
sercon_handle = serial_parse_handle(p);
|
||||
else if ( strncmp(p, "vga", 3) == 0 )
|
||||
{
|
||||
vgacon_enabled = 1;
|
||||
if ( strncmp(p+3, "[keep]", 6) == 0 )
|
||||
vgacon_enabled++;
|
||||
vgacon_enabled = p[3] < '1' || p[3] > '9'
|
||||
? (p += 3, 25)
|
||||
: simple_strtol(p + 3, &p, 10);
|
||||
if ( strncmp(p, "[keep]", 6) == 0 )
|
||||
vgacon_keep = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,12 +499,10 @@ void console_endboot(void)
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
if ( vgacon_enabled )
|
||||
{
|
||||
vgacon_enabled--;
|
||||
printk("Xen is %s VGA console.\n",
|
||||
vgacon_enabled ? "keeping" : "relinquishing");
|
||||
}
|
||||
if ( !vgacon_keep )
|
||||
vgacon_enabled = 0;
|
||||
printk("Xen is %s VGA console.\n",
|
||||
vgacon_keep ? "keeping" : "relinquishing");
|
||||
|
||||
/*
|
||||
* If user specifies so, we fool the switch routine to redirect input
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
obj-y += font_8x14.o
|
||||
obj-y += font_8x16.o
|
||||
obj-y += font_8x8.o
|
||||
obj-y += vga.o
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,554 @@
|
||||
/******************************************************************************
|
||||
* vga.c
|
||||
*
|
||||
* VGA support routines.
|
||||
*/
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <xen/compile.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/errno.h>
|
||||
#include <xen/event.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/console.h>
|
||||
#include <xen/font.h>
|
||||
#include <xen/vga.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* Some of the code below is taken from SVGAlib. The original,
|
||||
unmodified copyright notice for that code is below. */
|
||||
/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
|
||||
/* */
|
||||
/* This library is free software; you can redistribute it and/or */
|
||||
/* modify it without any restrictions. This library is distributed */
|
||||
/* in the hope that it will be useful, but without any warranty. */
|
||||
|
||||
/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
|
||||
/* partially copyrighted (C) 1993 by Hartmut Schirmer */
|
||||
|
||||
/* VGA data register ports */
|
||||
#define VGA_CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
|
||||
#define VGA_CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
|
||||
#define VGA_ATT_R 0x3C1 /* Attribute Controller Data Read Register */
|
||||
#define VGA_ATT_W 0x3C0 /* Attribute Controller Data Write Register */
|
||||
#define VGA_GFX_D 0x3CF /* Graphics Controller Data Register */
|
||||
#define VGA_SEQ_D 0x3C5 /* Sequencer Data Register */
|
||||
#define VGA_MIS_R 0x3CC /* Misc Output Read Register */
|
||||
#define VGA_MIS_W 0x3C2 /* Misc Output Write Register */
|
||||
#define VGA_FTC_R 0x3CA /* Feature Control Read Register */
|
||||
#define VGA_IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
|
||||
#define VGA_IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
|
||||
#define VGA_PEL_D 0x3C9 /* PEL Data Register */
|
||||
#define VGA_PEL_MSK 0x3C6 /* PEL mask register */
|
||||
|
||||
/* EGA-specific registers */
|
||||
#define EGA_GFX_E0 0x3CC /* Graphics enable processor 0 */
|
||||
#define EGA_GFX_E1 0x3CA /* Graphics enable processor 1 */
|
||||
|
||||
/* VGA index register ports */
|
||||
#define VGA_CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
|
||||
#define VGA_CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
|
||||
#define VGA_ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
|
||||
#define VGA_GFX_I 0x3CE /* Graphics Controller Index */
|
||||
#define VGA_SEQ_I 0x3C4 /* Sequencer Index */
|
||||
#define VGA_PEL_IW 0x3C8 /* PEL Write Index */
|
||||
#define VGA_PEL_IR 0x3C7 /* PEL Read Index */
|
||||
|
||||
/* standard VGA indexes max counts */
|
||||
#define VGA_CRT_C 0x19 /* Number of CRT Controller Registers */
|
||||
#define VGA_ATT_C 0x15 /* Number of Attribute Controller Registers */
|
||||
#define VGA_GFX_C 0x09 /* Number of Graphics Controller Registers */
|
||||
#define VGA_SEQ_C 0x05 /* Number of Sequencer Registers */
|
||||
#define VGA_MIS_C 0x01 /* Number of Misc Output Register */
|
||||
|
||||
/* VGA misc register bit masks */
|
||||
#define VGA_MIS_COLOR 0x01
|
||||
#define VGA_MIS_ENB_MEM_ACCESS 0x02
|
||||
#define VGA_MIS_DCLK_28322_720 0x04
|
||||
#define VGA_MIS_ENB_PLL_LOAD (0x04 | 0x08)
|
||||
#define VGA_MIS_SEL_HIGH_PAGE 0x20
|
||||
|
||||
/* VGA CRT controller register indices */
|
||||
#define VGA_CRTC_H_TOTAL 0
|
||||
#define VGA_CRTC_H_DISP 1
|
||||
#define VGA_CRTC_H_BLANK_START 2
|
||||
#define VGA_CRTC_H_BLANK_END 3
|
||||
#define VGA_CRTC_H_SYNC_START 4
|
||||
#define VGA_CRTC_H_SYNC_END 5
|
||||
#define VGA_CRTC_V_TOTAL 6
|
||||
#define VGA_CRTC_OVERFLOW 7
|
||||
#define VGA_CRTC_PRESET_ROW 8
|
||||
#define VGA_CRTC_MAX_SCAN 9
|
||||
#define VGA_CRTC_CURSOR_START 0x0A
|
||||
#define VGA_CRTC_CURSOR_END 0x0B
|
||||
#define VGA_CRTC_START_HI 0x0C
|
||||
#define VGA_CRTC_START_LO 0x0D
|
||||
#define VGA_CRTC_CURSOR_HI 0x0E
|
||||
#define VGA_CRTC_CURSOR_LO 0x0F
|
||||
#define VGA_CRTC_V_SYNC_START 0x10
|
||||
#define VGA_CRTC_V_SYNC_END 0x11
|
||||
#define VGA_CRTC_V_DISP_END 0x12
|
||||
#define VGA_CRTC_OFFSET 0x13
|
||||
#define VGA_CRTC_UNDERLINE 0x14
|
||||
#define VGA_CRTC_V_BLANK_START 0x15
|
||||
#define VGA_CRTC_V_BLANK_END 0x16
|
||||
#define VGA_CRTC_MODE 0x17
|
||||
#define VGA_CRTC_LINE_COMPARE 0x18
|
||||
#define VGA_CRTC_REGS VGA_CRT_C
|
||||
|
||||
/* VGA CRT controller bit masks */
|
||||
#define VGA_CR11_LOCK_CR0_CR7 0x80 /* lock writes to CR0 - CR7 */
|
||||
#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
|
||||
|
||||
/* VGA attribute controller register indices */
|
||||
#define VGA_ATC_PALETTE0 0x00
|
||||
#define VGA_ATC_PALETTE1 0x01
|
||||
#define VGA_ATC_PALETTE2 0x02
|
||||
#define VGA_ATC_PALETTE3 0x03
|
||||
#define VGA_ATC_PALETTE4 0x04
|
||||
#define VGA_ATC_PALETTE5 0x05
|
||||
#define VGA_ATC_PALETTE6 0x06
|
||||
#define VGA_ATC_PALETTE7 0x07
|
||||
#define VGA_ATC_PALETTE8 0x08
|
||||
#define VGA_ATC_PALETTE9 0x09
|
||||
#define VGA_ATC_PALETTEA 0x0A
|
||||
#define VGA_ATC_PALETTEB 0x0B
|
||||
#define VGA_ATC_PALETTEC 0x0C
|
||||
#define VGA_ATC_PALETTED 0x0D
|
||||
#define VGA_ATC_PALETTEE 0x0E
|
||||
#define VGA_ATC_PALETTEF 0x0F
|
||||
#define VGA_ATC_MODE 0x10
|
||||
#define VGA_ATC_OVERSCAN 0x11
|
||||
#define VGA_ATC_PLANE_ENABLE 0x12
|
||||
#define VGA_ATC_PEL 0x13
|
||||
#define VGA_ATC_COLOR_PAGE 0x14
|
||||
|
||||
#define VGA_AR_ENABLE_DISPLAY 0x20
|
||||
|
||||
/* VGA sequencer register indices */
|
||||
#define VGA_SEQ_RESET 0x00
|
||||
#define VGA_SEQ_CLOCK_MODE 0x01
|
||||
#define VGA_SEQ_PLANE_WRITE 0x02
|
||||
#define VGA_SEQ_CHARACTER_MAP 0x03
|
||||
#define VGA_SEQ_MEMORY_MODE 0x04
|
||||
|
||||
/* VGA sequencer register bit masks */
|
||||
#define VGA_SR01_CHAR_CLK_8DOTS 0x01 /* bit 0: character clocks 8 dots wide are generated */
|
||||
#define VGA_SR01_SCREEN_OFF 0x20 /* bit 5: Screen is off */
|
||||
#define VGA_SR02_ALL_PLANES 0x0F /* bits 3-0: enable access to all planes */
|
||||
#define VGA_SR04_EXT_MEM 0x02 /* bit 1: allows complete mem access to 256K */
|
||||
#define VGA_SR04_SEQ_MODE 0x04 /* bit 2: directs system to use a sequential addressing mode */
|
||||
#define VGA_SR04_CHN_4M 0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
|
||||
|
||||
/* VGA graphics controller register indices */
|
||||
#define VGA_GFX_SR_VALUE 0x00
|
||||
#define VGA_GFX_SR_ENABLE 0x01
|
||||
#define VGA_GFX_COMPARE_VALUE 0x02
|
||||
#define VGA_GFX_DATA_ROTATE 0x03
|
||||
#define VGA_GFX_PLANE_READ 0x04
|
||||
#define VGA_GFX_MODE 0x05
|
||||
#define VGA_GFX_MISC 0x06
|
||||
#define VGA_GFX_COMPARE_MASK 0x07
|
||||
#define VGA_GFX_BIT_MASK 0x08
|
||||
|
||||
/* VGA graphics controller bit masks */
|
||||
#define VGA_GR06_GRAPHICS_MODE 0x01
|
||||
|
||||
/* macro for composing an 8-bit VGA register index and value
|
||||
* into a single 16-bit quantity */
|
||||
#define VGA_OUT16VAL(v, r) (((v) << 8) | (r))
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define vgabase 0
|
||||
# define VGA_OUTW_WRITE
|
||||
# define vga_readb(x) (*(x))
|
||||
# define vga_writeb(x,y) (*(y) = (x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* generic VGA port read/write
|
||||
*/
|
||||
|
||||
static inline uint8_t vga_io_r (uint16_t port)
|
||||
{
|
||||
return inb(port);
|
||||
}
|
||||
|
||||
static inline void vga_io_w (uint16_t port, uint8_t val)
|
||||
{
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
static inline void vga_io_w_fast (uint16_t port, uint8_t reg, uint8_t val)
|
||||
{
|
||||
outw(VGA_OUT16VAL (val, reg), port);
|
||||
}
|
||||
|
||||
static inline uint8_t vga_mm_r (void __iomem *regbase, uint16_t port)
|
||||
{
|
||||
return readb (regbase + port);
|
||||
}
|
||||
|
||||
static inline void vga_mm_w (void __iomem *regbase, uint16_t port, uint8_t val)
|
||||
{
|
||||
writeb (val, regbase + port);
|
||||
}
|
||||
|
||||
static inline void vga_mm_w_fast (void __iomem *regbase, uint16_t port, uint8_t reg, uint8_t val)
|
||||
{
|
||||
writew (VGA_OUT16VAL (val, reg), regbase + port);
|
||||
}
|
||||
|
||||
static inline uint8_t vga_r (void __iomem *regbase, uint16_t port)
|
||||
{
|
||||
if (regbase)
|
||||
return vga_mm_r (regbase, port);
|
||||
else
|
||||
return vga_io_r (port);
|
||||
}
|
||||
|
||||
static inline void vga_w (void __iomem *regbase, uint16_t port, uint8_t val)
|
||||
{
|
||||
if (regbase)
|
||||
vga_mm_w (regbase, port, val);
|
||||
else
|
||||
vga_io_w (port, val);
|
||||
}
|
||||
|
||||
|
||||
static inline void vga_w_fast (void __iomem *regbase, uint16_t port, uint8_t reg, uint8_t val)
|
||||
{
|
||||
if (regbase)
|
||||
vga_mm_w_fast (regbase, port, reg, val);
|
||||
else
|
||||
vga_io_w_fast (port, reg, val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* VGA CRTC register read/write
|
||||
*/
|
||||
|
||||
static inline uint8_t vga_rcrt (void __iomem *regbase, uint8_t reg)
|
||||
{
|
||||
vga_w (regbase, VGA_CRT_IC, reg);
|
||||
return vga_r (regbase, VGA_CRT_DC);
|
||||
}
|
||||
|
||||
static inline void vga_wcrt (void __iomem *regbase, uint8_t reg, uint8_t val)
|
||||
{
|
||||
#ifdef VGA_OUTW_WRITE
|
||||
vga_w_fast (regbase, VGA_CRT_IC, reg, val);
|
||||
#else
|
||||
vga_w (regbase, VGA_CRT_IC, reg);
|
||||
vga_w (regbase, VGA_CRT_DC, val);
|
||||
#endif /* VGA_OUTW_WRITE */
|
||||
}
|
||||
|
||||
/*
|
||||
* VGA sequencer register read/write
|
||||
*/
|
||||
|
||||
static inline uint8_t vga_rseq (void __iomem *regbase, uint8_t reg)
|
||||
{
|
||||
vga_w (regbase, VGA_SEQ_I, reg);
|
||||
return vga_r (regbase, VGA_SEQ_D);
|
||||
}
|
||||
|
||||
static inline void vga_wseq (void __iomem *regbase, uint8_t reg, uint8_t val)
|
||||
{
|
||||
#ifdef VGA_OUTW_WRITE
|
||||
vga_w_fast (regbase, VGA_SEQ_I, reg, val);
|
||||
#else
|
||||
vga_w (regbase, VGA_SEQ_I, reg);
|
||||
vga_w (regbase, VGA_SEQ_D, val);
|
||||
#endif /* VGA_OUTW_WRITE */
|
||||
}
|
||||
|
||||
/*
|
||||
* VGA graphics controller register read/write
|
||||
*/
|
||||
|
||||
static inline uint8_t vga_rgfx (void __iomem *regbase, uint8_t reg)
|
||||
{
|
||||
vga_w (regbase, VGA_GFX_I, reg);
|
||||
return vga_r (regbase, VGA_GFX_D);
|
||||
}
|
||||
|
||||
static inline void vga_wgfx (void __iomem *regbase, uint8_t reg, uint8_t val)
|
||||
{
|
||||
#ifdef VGA_OUTW_WRITE
|
||||
vga_w_fast (regbase, VGA_GFX_I, reg, val);
|
||||
#else
|
||||
vga_w (regbase, VGA_GFX_I, reg);
|
||||
vga_w (regbase, VGA_GFX_D, val);
|
||||
#endif /* VGA_OUTW_WRITE */
|
||||
}
|
||||
|
||||
/*
|
||||
* VGA attribute controller register read/write
|
||||
*/
|
||||
|
||||
static inline uint8_t vga_rattr (void __iomem *regbase, uint8_t reg)
|
||||
{
|
||||
vga_w (regbase, VGA_ATT_IW, reg);
|
||||
return vga_r (regbase, VGA_ATT_R);
|
||||
}
|
||||
|
||||
static inline void vga_wattr (void __iomem *regbase, uint8_t reg, uint8_t val)
|
||||
{
|
||||
vga_w (regbase, VGA_ATT_IW, reg);
|
||||
vga_w (regbase, VGA_ATT_W, val);
|
||||
}
|
||||
|
||||
static int detect_video(void *video_base)
|
||||
{
|
||||
volatile u16 *p = (volatile u16 *)video_base;
|
||||
u16 saved1 = p[0], saved2 = p[1];
|
||||
int video_found = 1;
|
||||
|
||||
p[0] = 0xAA55;
|
||||
p[1] = 0x55AA;
|
||||
if ( (p[0] != 0xAA55) || (p[1] != 0x55AA) )
|
||||
video_found = 0;
|
||||
|
||||
p[0] = 0x55AA;
|
||||
p[1] = 0xAA55;
|
||||
if ( (p[0] != 0x55AA) || (p[1] != 0xAA55) )
|
||||
video_found = 0;
|
||||
|
||||
p[0] = saved1;
|
||||
p[1] = saved2;
|
||||
|
||||
return video_found;
|
||||
}
|
||||
|
||||
int detect_vga()
|
||||
{
|
||||
/*
|
||||
* Look at a number of well-known locations. Even if video is not at
|
||||
* 0xB8000 right now, it will appear there when we set up text mode 3.
|
||||
*
|
||||
* We assume if there is any sign of a video adaptor then it is at least
|
||||
* VGA-compatible (surely noone runs CGA, EGA, .... these days?).
|
||||
*
|
||||
* These checks are basically to detect headless server boxes.
|
||||
*/
|
||||
return (detect_video(ioremap(0xA0000, 0x1000)) ||
|
||||
detect_video(ioremap(0xB0000, 0x1000)) ||
|
||||
detect_video(ioremap(0xB8000, 0x1000)));
|
||||
}
|
||||
|
||||
/* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
|
||||
void *setup_vga()
|
||||
{
|
||||
/* The following VGA state was saved from a chip in text mode 3. */
|
||||
static unsigned char regs[] = {
|
||||
/* Sequencer registers */
|
||||
0x03, 0x00, 0x03, 0x00, 0x02,
|
||||
/* CRTC registers */
|
||||
0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x20,
|
||||
0x0e, 0x00, 0x00, 0x01, 0xe0, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96,
|
||||
0xb9, 0xa3, 0xff,
|
||||
/* Graphic registers */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
|
||||
/* Attribute registers */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a,
|
||||
0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00
|
||||
};
|
||||
|
||||
int i, j;
|
||||
|
||||
if ( !detect_vga() )
|
||||
{
|
||||
printk("No VGA adaptor detected!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inb(VGA_IS1_RC);
|
||||
outb(0x00, VGA_ATT_IW);
|
||||
|
||||
for ( i = j = 0; i < 5; i++ )
|
||||
vga_wseq(vgabase, i, regs[j++]);
|
||||
|
||||
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17]. */
|
||||
vga_wcrt(vgabase, 17, regs[5+17] & 0x7F);
|
||||
|
||||
for ( i = 0; i < 25; i++ )
|
||||
vga_wcrt(vgabase, i, regs[j++]);
|
||||
|
||||
for ( i = 0; i < 9; i++ )
|
||||
vga_wgfx(vgabase, i, regs[j++]);
|
||||
|
||||
inb(VGA_IS1_RC);
|
||||
for ( i = 0; i < 21; i++ )
|
||||
vga_wattr(vgabase, i, regs[j++]);
|
||||
|
||||
inb(VGA_IS1_RC);
|
||||
outb(0x20, VGA_ATT_IW);
|
||||
|
||||
return ioremap(0xB8000, 0x8000);
|
||||
}
|
||||
|
||||
void vga_cursor_off(void)
|
||||
{
|
||||
vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, 0x20);
|
||||
}
|
||||
|
||||
static int vga_set_scanlines(unsigned scanlines)
|
||||
{
|
||||
unsigned vtot, ovr, vss, vbs;
|
||||
uint8_t vse, vbe, misc = 0;
|
||||
|
||||
switch (scanlines) {
|
||||
case 43*8:
|
||||
vtot = 0x1bf;
|
||||
vss = 0x183;
|
||||
vse = 0x05;
|
||||
vbs = 0x163;
|
||||
vbe = 0xba;
|
||||
break;
|
||||
case 25*16:
|
||||
case 28*14:
|
||||
vtot = 0x1bf;
|
||||
vss = 0x19c;
|
||||
vse = 0x0e;
|
||||
vbs = 0x196;
|
||||
vbe = 0xb9;
|
||||
break;
|
||||
case 30*16:
|
||||
case 34*14:
|
||||
vtot = 0x20b;
|
||||
vss = 0x1ea;
|
||||
vse = 0x0c;
|
||||
vbs = 0x1e7;
|
||||
vbe = 0x04;
|
||||
/* Preserve clock select bits and color bit, set correct sync polarity. */
|
||||
misc = (inb(VGA_MIS_R) & 0x0d) | 0xe2;
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ovr = vga_rcrt(vgabase, VGA_CRTC_OVERFLOW);
|
||||
if(vga_rcrt(vgabase, VGA_CRTC_V_DISP_END) + ((ovr & 0x02) << 7) + ((ovr & 0x40) << 3) == scanlines - 1)
|
||||
return 0;
|
||||
|
||||
ovr = (ovr & 0x10)
|
||||
| ((vtot >> 8) & 0x01)
|
||||
| ((vtot >> 4) & 0x20)
|
||||
| (((scanlines - 1) >> 7) & 0x02)
|
||||
| (((scanlines - 1) >> 3) & 0x40)
|
||||
| ((vss >> 6) & 0x04)
|
||||
| ((vss >> 2) & 0x80)
|
||||
| ((vbs >> 5) & 0x08);
|
||||
vse |= vga_rcrt(vgabase, VGA_CRTC_V_SYNC_END) & 0x70;
|
||||
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_SYNC_END, vse & 0x7f); /* Vertical sync end (also unlocks CR0-7) */
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_TOTAL, (uint8_t)vtot); /* Vertical total */
|
||||
vga_wcrt(vgabase, VGA_CRTC_OVERFLOW, (uint8_t)ovr); /* Overflow */
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_SYNC_START, (uint8_t)vss); /* Vertical sync start */
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_SYNC_END, vse | 0x80); /* Vertical sync end (also locks CR0-7) */
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_DISP_END, (uint8_t)(scanlines - 1)); /* Vertical display end */
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_BLANK_START, (uint8_t)vbs); /* Vertical blank start */
|
||||
vga_wcrt(vgabase, VGA_CRTC_V_BLANK_END, vbe); /* Vertical blank end */
|
||||
|
||||
if (misc)
|
||||
outb(misc, VGA_MIS_W); /* Misc output register */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FONT_COUNT_MAX 256
|
||||
#define FONT_HEIGHT_MAX 32
|
||||
#define CHAR_MAP_SIZE (FONT_COUNT_MAX * FONT_HEIGHT_MAX)
|
||||
|
||||
/* At least on various ATI cards I haven't been able to get the sequencer
|
||||
to honor the change to the character map select register, thus at least
|
||||
a way to override the slot is needed. */
|
||||
static unsigned font_slot = 2;
|
||||
integer_param("fontslot", font_slot);
|
||||
|
||||
int vga_load_font(const struct font_desc *font, unsigned rows)
|
||||
{
|
||||
unsigned fontheight = font ? font->height : 16;
|
||||
uint8_t fsr = vga_rcrt(vgabase, VGA_CRTC_MAX_SCAN); /* Font size register */
|
||||
int ret;
|
||||
|
||||
if (font_slot > 3 || (!font_slot && !font))
|
||||
return -ENOSYS;
|
||||
|
||||
if (font
|
||||
&& (font->count > FONT_COUNT_MAX
|
||||
|| fontheight > FONT_HEIGHT_MAX
|
||||
|| font->width != 8))
|
||||
return -EINVAL;
|
||||
|
||||
ret = vga_set_scanlines(rows * fontheight);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((fsr & 0x1f) == fontheight - 1)
|
||||
return 0;
|
||||
|
||||
/* First, the Sequencer */
|
||||
vga_wseq(vgabase, VGA_SEQ_RESET, 0x1);
|
||||
/* CPU writes only to map 2 */
|
||||
vga_wseq(vgabase, VGA_SEQ_PLANE_WRITE, 0x04);
|
||||
/* Sequential addressing */
|
||||
vga_wseq(vgabase, VGA_SEQ_MEMORY_MODE, 0x07);
|
||||
/* Clear synchronous reset */
|
||||
vga_wseq(vgabase, VGA_SEQ_RESET, 0x03);
|
||||
|
||||
/* Now, the graphics controller, select map 2 */
|
||||
vga_wgfx(vgabase, VGA_GFX_PLANE_READ, 0x02);
|
||||
/* disable odd-even addressing */
|
||||
vga_wgfx(vgabase, VGA_GFX_MODE, 0x00);
|
||||
/* map start at A000:0000 */
|
||||
vga_wgfx(vgabase, VGA_GFX_MISC, 0x00);
|
||||
|
||||
if (font) {
|
||||
unsigned i, j;
|
||||
const uint8_t *data = font->data;
|
||||
uint8_t *map = (uint8_t *)__va(0xA0000) + font_slot * 2 * CHAR_MAP_SIZE;
|
||||
|
||||
for (i = j = 0; i < CHAR_MAP_SIZE; ) {
|
||||
vga_writeb(j < font->count * fontheight ? data[j++] : 0, map + i++);
|
||||
if (!(j % fontheight))
|
||||
while(i & (FONT_HEIGHT_MAX - 1))
|
||||
vga_writeb(0, map + i++);
|
||||
}
|
||||
}
|
||||
|
||||
/* First, the sequencer, Synchronous reset */
|
||||
vga_wseq(vgabase, VGA_SEQ_RESET, 0x01);
|
||||
/* CPU writes to maps 0 and 1 */
|
||||
vga_wseq(vgabase, VGA_SEQ_PLANE_WRITE, 0x03);
|
||||
/* odd-even addressing */
|
||||
vga_wseq(vgabase, VGA_SEQ_MEMORY_MODE, 0x03);
|
||||
/* Character Map Select: The default font is kept in slot 0 and
|
||||
* is never touched. Our custom font is loaded in slot 2. */
|
||||
vga_wseq(vgabase, VGA_SEQ_CHARACTER_MAP, font ? font_slot | (font_slot << 2) : 0x00);
|
||||
/* clear synchronous reset */
|
||||
vga_wseq(vgabase, VGA_SEQ_RESET, 0x03);
|
||||
|
||||
/* Now, the graphics controller, select map 0 for CPU */
|
||||
vga_wgfx(vgabase, VGA_GFX_PLANE_READ, 0x00);
|
||||
/* enable even-odd addressing */
|
||||
vga_wgfx(vgabase, VGA_GFX_MODE, 0x10);
|
||||
/* map starts at b800:0 */
|
||||
vga_wgfx(vgabase, VGA_GFX_MISC, 0x0e);
|
||||
|
||||
/* Font size register */
|
||||
fsr = (fsr & 0xe0) + (fontheight - 1);
|
||||
vga_wcrt(vgabase, VGA_CRTC_MAX_SCAN, fsr);
|
||||
|
||||
/* Cursor shape registers */
|
||||
fsr = (vga_rcrt(vgabase, VGA_CRTC_CURSOR_END) & 0xe0) | (fontheight - fontheight / 6);
|
||||
vga_wcrt(vgabase, VGA_CRTC_CURSOR_END, fsr);
|
||||
fsr = (vga_rcrt(vgabase, VGA_CRTC_CURSOR_START) & 0xe0) | ((fsr & 0x1f) - 1);
|
||||
vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, fsr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -466,8 +466,15 @@ struct start_info {
|
||||
uint32_t flags; /* SIF_xxx flags. */
|
||||
xen_pfn_t store_mfn; /* MACHINE page number of shared page. */
|
||||
uint32_t store_evtchn; /* Event channel for store communication. */
|
||||
xen_pfn_t console_mfn; /* MACHINE page number of console page. */
|
||||
uint32_t console_evtchn; /* Event channel for console messages. */
|
||||
union {
|
||||
xen_pfn_t console_mfn; /* MACHINE page number of console page. */
|
||||
uint32_t con_info_offs; /* Dom0 only: offset of console_info from
|
||||
start_info */
|
||||
};
|
||||
union {
|
||||
uint32_t console_evtchn;/* Event channel for console messages. */
|
||||
uint32_t con_info_size; /* Dom0 only: size of console_info */
|
||||
};
|
||||
/* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
|
||||
unsigned long pt_base; /* VIRTUAL address of page directory. */
|
||||
unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */
|
||||
@@ -482,6 +489,28 @@ typedef struct start_info start_info_t;
|
||||
#define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */
|
||||
#define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */
|
||||
|
||||
typedef struct console_info {
|
||||
uint8_t video_type;
|
||||
uint8_t txt_points;
|
||||
uint16_t txt_mode;
|
||||
uint16_t txt_x;
|
||||
uint16_t txt_y;
|
||||
uint16_t video_width;
|
||||
uint16_t video_height;
|
||||
uint16_t lfb_linelen;
|
||||
uint16_t lfb_depth;
|
||||
unsigned long lfb_base;
|
||||
unsigned long lfb_size;
|
||||
uint8_t red_pos;
|
||||
uint8_t red_size;
|
||||
uint8_t green_pos;
|
||||
uint8_t green_size;
|
||||
uint8_t blue_pos;
|
||||
uint8_t blue_size;
|
||||
uint8_t rsvd_pos;
|
||||
uint8_t rsvd_size;
|
||||
} console_info_t;
|
||||
|
||||
typedef uint64_t cpumap_t;
|
||||
|
||||
typedef uint8_t xen_domain_handle_t[16];
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <public/xen.h>
|
||||
|
||||
void set_printk_prefix(const char *prefix);
|
||||
|
||||
@@ -17,6 +18,8 @@ long read_console_ring(XEN_GUEST_HANDLE(char), u32 *, int);
|
||||
void init_console(void);
|
||||
void console_endboot(void);
|
||||
|
||||
int fill_console_start_info(console_info_t *);
|
||||
|
||||
void console_force_unlock(void);
|
||||
void console_force_lock(void);
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* font.h -- `Soft' font definitions
|
||||
*
|
||||
* Created 1995 by Geert Uytterhoeven
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef _XEN_FONT_H
|
||||
#define _XEN_FONT_H
|
||||
|
||||
struct font_desc {
|
||||
const char *name;
|
||||
unsigned width, height, count;
|
||||
const void *data;
|
||||
};
|
||||
|
||||
extern const struct font_desc font_vga_8x8, font_vga_8x14, font_vga_8x16;
|
||||
|
||||
#endif /* _XEN_FONT_H */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* vga.h
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef _XEN_VGA_H
|
||||
#define _XEN_VGA_H
|
||||
|
||||
struct font_desc;
|
||||
|
||||
int detect_vga(void);
|
||||
void *setup_vga(void);
|
||||
void vga_cursor_off(void);
|
||||
int vga_load_font(const struct font_desc *, unsigned rows);
|
||||
|
||||
#endif /* _XEN_VGA_H */
|
||||