--- /home/jbeulich/src/xen/2006-07-27/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c 2006-07-17 14:48:24.000000000 +0200 +++ 2006-07-27/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c 2006-07-18 14:46:00.000000000 +0200 @@ -1670,6 +1670,31 @@ 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->console_evtchn >= sizeof(console_info_t)) { + const console_info_t *console_info = (void *)xen_start_info + xen_start_info->console_mfn; + + 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; + } + xen_start_info->console_mfn = 0; + xen_start_info->console_evtchn = 0; } else screen_info.orig_video_isVGA = 0; --- /home/jbeulich/src/xen/2006-07-27/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c 2006-07-18 14:39:55.000000000 +0200 +++ 2006-07-27/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c 2006-06-29 13:47:24.000000000 +0200 @@ -648,6 +648,31 @@ 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->console_evtchn >= sizeof(console_info_t)) { + const console_info_t *console_info = (void *)xen_start_info + xen_start_info->console_mfn; + + 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; + } + xen_start_info->console_mfn = 0; + xen_start_info->console_evtchn = 0; } else screen_info.orig_video_isVGA = 0; --- /home/jbeulich/src/xen/2006-07-27/xen/arch/x86/domain_build.c 2006-06-19 17:41:08.000000000 +0200 +++ 2006-07-27/xen/arch/x86/domain_build.c 2006-07-31 13:44:15.363173048 +0200 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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,11 @@ 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->console_mfn = sizeof(start_info_t); + si->console_evtchn = sizeof(console_info_t); + } + /* Reinstate the caller's page tables. */ write_ptbase(current); local_irq_enable(); --- /home/jbeulich/src/xen/2006-07-27/xen/drivers/char/Makefile 2006-05-23 22:10:05.000000000 +0200 +++ 2006-07-27/xen/drivers/char/Makefile 2006-07-31 13:50:02.098461272 +0200 @@ -1,3 +1,7 @@ obj-y += console.o +obj-y += font_8x14.o +obj-y += font_8x16.o +obj-y += font_8x8.o obj-y += ns16550.o obj-y += serial.o +obj-y += vga.o --- /home/jbeulich/src/xen/2006-07-27/xen/drivers/char/console.c 2006-07-31 13:39:57.547367008 +0200 +++ 2006-07-27/xen/drivers/char/console.c 2006-07-31 13:44:15.395168184 +0200 @@ -25,6 +25,8 @@ #include #include +#include "font.h" + /* console: comma-separated list of console outputs. */ static char opt_console[30] = OPT_CONSOLE_STR; string_param("console", opt_console); @@ -52,6 +54,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); @@ -63,7 +66,7 @@ spinlock_t console_lock = SPIN_LOCK_UNLO /* VGA text (mode 3) definitions. */ #define COLUMNS 80 -#define LINES 25 +#define LINES vgacon_enabled #define ATTRIBUTE 7 #define VIDEO_SIZE (COLUMNS * LINES * 2) @@ -171,6 +174,30 @@ static void init_vga(void) tmp = inb(0x3da); outb(0x20, 0x3c0); + switch ( vgacon_enabled ) + { + 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 && vga_load_font(font, vgacon_enabled) < 0) { + vgacon_enabled = 25; + font = NULL; + } + cls(); } @@ -207,6 +244,18 @@ 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; +} /* * ******************************************************** @@ -477,9 +517,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; } } @@ -535,11 +575,11 @@ void init_console(void) printk("\n"); } - if ( vgacon_enabled ) + if ( vgacon_keep ) { - vgacon_enabled--; + vgacon_keep--; printk("Xen is %s VGA console.\n", - vgacon_enabled ? "keeping" : "relinquishing"); + vgacon_keep ? "keeping" : "relinquishing"); } /* --- /home/jbeulich/src/xen/2006-07-27/xen/drivers/char/font.h 1970-01-01 01:00:00.000000000 +0100 +++ 2006-07-27/xen/drivers/char/font.h 2006-02-23 10:35:27.000000000 +0100 @@ -0,0 +1,26 @@ +/* + * 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 _VIDEO_FONT_H +#define _VIDEO_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; + +int vga_load_font(const struct font_desc *, unsigned rows); + +#endif /* _VIDEO_FONT_H */ --- /home/jbeulich/src/xen/2006-07-27/xen/drivers/char/vga.c 1970-01-01 01:00:00.000000000 +0100 +++ 2006-07-27/xen/drivers/char/vga.c 2006-06-14 11:51:27.000000000 +0200 @@ -0,0 +1,582 @@ +/****************************************************************************** + * vga.c + * + * VGA support routines. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 */ +} + +static inline uint8_t vga_io_rcrt (uint8_t reg) +{ + vga_io_w (VGA_CRT_IC, reg); + return vga_io_r (VGA_CRT_DC); +} + +static inline void vga_io_wcrt (uint8_t reg, uint8_t val) +{ +#ifdef VGA_OUTW_WRITE + vga_io_w_fast (VGA_CRT_IC, reg, val); +#else + vga_io_w (VGA_CRT_IC, reg); + vga_io_w (VGA_CRT_DC, val); +#endif /* VGA_OUTW_WRITE */ +} + +static inline uint8_t vga_mm_rcrt (void __iomem *regbase, uint8_t reg) +{ + vga_mm_w (regbase, VGA_CRT_IC, reg); + return vga_mm_r (regbase, VGA_CRT_DC); +} + +static inline void vga_mm_wcrt (void __iomem *regbase, uint8_t reg, uint8_t val) +{ +#ifdef VGA_OUTW_WRITE + vga_mm_w_fast (regbase, VGA_CRT_IC, reg, val); +#else + vga_mm_w (regbase, VGA_CRT_IC, reg); + vga_mm_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 */ +} + +static inline uint8_t vga_io_rseq (uint8_t reg) +{ + vga_io_w (VGA_SEQ_I, reg); + return vga_io_r (VGA_SEQ_D); +} + +static inline void vga_io_wseq (uint8_t reg, uint8_t val) +{ +#ifdef VGA_OUTW_WRITE + vga_io_w_fast (VGA_SEQ_I, reg, val); +#else + vga_io_w (VGA_SEQ_I, reg); + vga_io_w (VGA_SEQ_D, val); +#endif /* VGA_OUTW_WRITE */ +} + +static inline uint8_t vga_mm_rseq (void __iomem *regbase, uint8_t reg) +{ + vga_mm_w (regbase, VGA_SEQ_I, reg); + return vga_mm_r (regbase, VGA_SEQ_D); +} + +static inline void vga_mm_wseq (void __iomem *regbase, uint8_t reg, uint8_t val) +{ +#ifdef VGA_OUTW_WRITE + vga_mm_w_fast (regbase, VGA_SEQ_I, reg, val); +#else + vga_mm_w (regbase, VGA_SEQ_I, reg); + vga_mm_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 */ +} + +static inline uint8_t vga_io_rgfx (uint8_t reg) +{ + vga_io_w (VGA_GFX_I, reg); + return vga_io_r (VGA_GFX_D); +} + +static inline void vga_io_wgfx (uint8_t reg, uint8_t val) +{ +#ifdef VGA_OUTW_WRITE + vga_io_w_fast (VGA_GFX_I, reg, val); +#else + vga_io_w (VGA_GFX_I, reg); + vga_io_w (VGA_GFX_D, val); +#endif /* VGA_OUTW_WRITE */ +} + +static inline uint8_t vga_mm_rgfx (void __iomem *regbase, uint8_t reg) +{ + vga_mm_w (regbase, VGA_GFX_I, reg); + return vga_mm_r (regbase, VGA_GFX_D); +} + +static inline void vga_mm_wgfx (void __iomem *regbase, uint8_t reg, uint8_t val) +{ +#ifdef VGA_OUTW_WRITE + vga_mm_w_fast (regbase, VGA_GFX_I, reg, val); +#else + vga_mm_w (regbase, VGA_GFX_I, reg); + vga_mm_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 inline uint8_t vga_io_rattr (uint8_t reg) +{ + vga_io_w (VGA_ATT_IW, reg); + return vga_io_r (VGA_ATT_R); +} + +static inline void vga_io_wattr (uint8_t reg, uint8_t val) +{ + vga_io_w (VGA_ATT_IW, reg); + vga_io_w (VGA_ATT_W, val); +} + +static inline uint8_t vga_mm_rattr (void __iomem *regbase, uint8_t reg) +{ + vga_mm_w (regbase, VGA_ATT_IW, reg); + return vga_mm_r (regbase, VGA_ATT_R); +} + +static inline void vga_mm_wattr (void __iomem *regbase, uint8_t reg, uint8_t val) +{ + vga_mm_w (regbase, VGA_ATT_IW, reg); + vga_mm_w (regbase, VGA_ATT_W, val); +} + +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; +} + +#include "font.h" + +#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; +} --- /home/jbeulich/src/xen/2006-07-27/xen/include/public/xen.h 2006-05-10 00:03:09.000000000 +0200 +++ 2006-07-27/xen/include/public/xen.h 2006-07-31 13:44:15.470156784 +0200 @@ -477,6 +477,28 @@ typedef struct start_info { #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]; --- /home/jbeulich/src/xen/2006-07-27/xen/include/xen/console.h 2006-05-10 00:03:09.000000000 +0200 +++ 2006-07-27/xen/include/xen/console.h 2006-07-31 13:44:15.472156480 +0200 @@ -9,6 +9,7 @@ #include #include +#include void set_printk_prefix(const char *prefix); @@ -16,6 +17,7 @@ long read_console_ring(GUEST_HANDLE(char 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);