source: trunk/packages/xen-3.1/xen-3.1/xen/drivers/video/vga.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 19.0 KB
Line 
1/******************************************************************************
2 * vga.c
3 *
4 * VGA support routines.
5 */
6
7#include <xen/config.h>
8#include <xen/compile.h>
9#include <xen/init.h>
10#include <xen/lib.h>
11#include <xen/mm.h>
12#include <xen/errno.h>
13#include <xen/event.h>
14#include <xen/spinlock.h>
15#include <xen/console.h>
16#include <xen/vga.h>
17#include <asm/io.h>
18#include "font.h"
19
20/* Some of the code below is taken from SVGAlib.  The original,
21   unmodified copyright notice for that code is below. */
22/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
23/*                                                                 */
24/* This library is free software; you can redistribute it and/or   */
25/* modify it without any restrictions. This library is distributed */
26/* in the hope that it will be useful, but without any warranty.   */
27
28/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
29/* partially copyrighted (C) 1993 by Hartmut Schirmer */
30
31/* VGA data register ports */
32#define VGA_CRT_DC      0x3D5   /* CRT Controller Data Register - color emulation */
33#define VGA_CRT_DM      0x3B5   /* CRT Controller Data Register - mono emulation */
34#define VGA_ATT_R       0x3C1   /* Attribute Controller Data Read Register */
35#define VGA_ATT_W       0x3C0   /* Attribute Controller Data Write Register */
36#define VGA_GFX_D       0x3CF   /* Graphics Controller Data Register */
37#define VGA_SEQ_D       0x3C5   /* Sequencer Data Register */
38#define VGA_MIS_R       0x3CC   /* Misc Output Read Register */
39#define VGA_MIS_W       0x3C2   /* Misc Output Write Register */
40#define VGA_FTC_R       0x3CA   /* Feature Control Read Register */
41#define VGA_IS1_RC      0x3DA   /* Input Status Register 1 - color emulation */
42#define VGA_IS1_RM      0x3BA   /* Input Status Register 1 - mono emulation */
43#define VGA_PEL_D       0x3C9   /* PEL Data Register */
44#define VGA_PEL_MSK     0x3C6   /* PEL mask register */
45
46/* EGA-specific registers */
47#define EGA_GFX_E0      0x3CC   /* Graphics enable processor 0 */
48#define EGA_GFX_E1      0x3CA   /* Graphics enable processor 1 */
49
50/* VGA index register ports */
51#define VGA_CRT_IC      0x3D4   /* CRT Controller Index - color emulation */
52#define VGA_CRT_IM      0x3B4   /* CRT Controller Index - mono emulation */
53#define VGA_ATT_IW      0x3C0   /* Attribute Controller Index & Data Write Register */
54#define VGA_GFX_I       0x3CE   /* Graphics Controller Index */
55#define VGA_SEQ_I       0x3C4   /* Sequencer Index */
56#define VGA_PEL_IW      0x3C8   /* PEL Write Index */
57#define VGA_PEL_IR      0x3C7   /* PEL Read Index */
58
59/* standard VGA indexes max counts */
60#define VGA_CRT_C       0x19    /* Number of CRT Controller Registers */
61#define VGA_ATT_C       0x15    /* Number of Attribute Controller Registers */
62#define VGA_GFX_C       0x09    /* Number of Graphics Controller Registers */
63#define VGA_SEQ_C       0x05    /* Number of Sequencer Registers */
64#define VGA_MIS_C       0x01    /* Number of Misc Output Register */
65
66/* VGA misc register bit masks */
67#define VGA_MIS_COLOR           0x01
68#define VGA_MIS_ENB_MEM_ACCESS  0x02
69#define VGA_MIS_DCLK_28322_720  0x04
70#define VGA_MIS_ENB_PLL_LOAD    (0x04 | 0x08)
71#define VGA_MIS_SEL_HIGH_PAGE   0x20
72
73/* VGA CRT controller register indices */
74#define VGA_CRTC_H_TOTAL        0
75#define VGA_CRTC_H_DISP         1
76#define VGA_CRTC_H_BLANK_START  2
77#define VGA_CRTC_H_BLANK_END    3
78#define VGA_CRTC_H_SYNC_START   4
79#define VGA_CRTC_H_SYNC_END     5
80#define VGA_CRTC_V_TOTAL        6
81#define VGA_CRTC_OVERFLOW       7
82#define VGA_CRTC_PRESET_ROW     8
83#define VGA_CRTC_MAX_SCAN       9
84#define VGA_CRTC_CURSOR_START   0x0A
85#define VGA_CRTC_CURSOR_END     0x0B
86#define VGA_CRTC_START_HI       0x0C
87#define VGA_CRTC_START_LO       0x0D
88#define VGA_CRTC_CURSOR_HI      0x0E
89#define VGA_CRTC_CURSOR_LO      0x0F
90#define VGA_CRTC_V_SYNC_START   0x10
91#define VGA_CRTC_V_SYNC_END     0x11
92#define VGA_CRTC_V_DISP_END     0x12
93#define VGA_CRTC_OFFSET         0x13
94#define VGA_CRTC_UNDERLINE      0x14
95#define VGA_CRTC_V_BLANK_START  0x15
96#define VGA_CRTC_V_BLANK_END    0x16
97#define VGA_CRTC_MODE           0x17
98#define VGA_CRTC_LINE_COMPARE   0x18
99#define VGA_CRTC_REGS           VGA_CRT_C
100
101/* VGA CRT controller bit masks */
102#define VGA_CR11_LOCK_CR0_CR7   0x80 /* lock writes to CR0 - CR7 */
103#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
104
105/* VGA attribute controller register indices */
106#define VGA_ATC_PALETTE0        0x00
107#define VGA_ATC_PALETTE1        0x01
108#define VGA_ATC_PALETTE2        0x02
109#define VGA_ATC_PALETTE3        0x03
110#define VGA_ATC_PALETTE4        0x04
111#define VGA_ATC_PALETTE5        0x05
112#define VGA_ATC_PALETTE6        0x06
113#define VGA_ATC_PALETTE7        0x07
114#define VGA_ATC_PALETTE8        0x08
115#define VGA_ATC_PALETTE9        0x09
116#define VGA_ATC_PALETTEA        0x0A
117#define VGA_ATC_PALETTEB        0x0B
118#define VGA_ATC_PALETTEC        0x0C
119#define VGA_ATC_PALETTED        0x0D
120#define VGA_ATC_PALETTEE        0x0E
121#define VGA_ATC_PALETTEF        0x0F
122#define VGA_ATC_MODE            0x10
123#define VGA_ATC_OVERSCAN        0x11
124#define VGA_ATC_PLANE_ENABLE    0x12
125#define VGA_ATC_PEL             0x13
126#define VGA_ATC_COLOR_PAGE      0x14
127
128#define VGA_AR_ENABLE_DISPLAY   0x20
129
130/* VGA sequencer register indices */
131#define VGA_SEQ_RESET           0x00
132#define VGA_SEQ_CLOCK_MODE      0x01
133#define VGA_SEQ_PLANE_WRITE     0x02
134#define VGA_SEQ_CHARACTER_MAP   0x03
135#define VGA_SEQ_MEMORY_MODE     0x04
136
137/* VGA sequencer register bit masks */
138#define VGA_SR01_CHAR_CLK_8DOTS 0x01 /* bit 0: character clocks 8 dots wide are generated */
139#define VGA_SR01_SCREEN_OFF     0x20 /* bit 5: Screen is off */
140#define VGA_SR02_ALL_PLANES     0x0F /* bits 3-0: enable access to all planes */
141#define VGA_SR04_EXT_MEM        0x02 /* bit 1: allows complete mem access to 256K */
142#define VGA_SR04_SEQ_MODE       0x04 /* bit 2: directs system to use a sequential addressing mode */
143#define VGA_SR04_CHN_4M         0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
144
145/* VGA graphics controller register indices */
146#define VGA_GFX_SR_VALUE        0x00
147#define VGA_GFX_SR_ENABLE       0x01
148#define VGA_GFX_COMPARE_VALUE   0x02
149#define VGA_GFX_DATA_ROTATE     0x03
150#define VGA_GFX_PLANE_READ      0x04
151#define VGA_GFX_MODE            0x05
152#define VGA_GFX_MISC            0x06
153#define VGA_GFX_COMPARE_MASK    0x07
154#define VGA_GFX_BIT_MASK        0x08
155
156/* VGA graphics controller bit masks */
157#define VGA_GR06_GRAPHICS_MODE  0x01
158
159/* macro for composing an 8-bit VGA register index and value
160 * into a single 16-bit quantity */
161#define VGA_OUT16VAL(v, r)       (((v) << 8) | (r))
162
163#define vgabase 0         /* use in/out port-access macros  */
164#define VGA_OUTW_WRITE    /* can use outw instead of 2xoutb */
165
166/*
167 * generic VGA port read/write
168 */
169 
170static inline uint8_t vga_io_r(uint16_t port)
171{
172    return inb(port);
173}
174
175static inline void vga_io_w(uint16_t port, uint8_t val)
176{
177    outb(val, port);
178}
179
180static inline void vga_io_w_fast(uint16_t port, uint8_t reg, uint8_t val)
181{
182    outw(VGA_OUT16VAL(val, reg), port);
183}
184
185static inline uint8_t vga_mm_r(void __iomem *regbase, uint16_t port)
186{
187    return readb((char *)regbase + port);
188}
189
190static inline void vga_mm_w(void __iomem *regbase, uint16_t port, uint8_t val)
191{
192    writeb(val, (char *)regbase + port);
193}
194
195static inline void vga_mm_w_fast(void __iomem *regbase, uint16_t port, uint8_t reg, uint8_t val)
196{
197    writew(VGA_OUT16VAL(val, reg), (char *)regbase + port);
198}
199
200static inline uint8_t vga_r(void __iomem *regbase, uint16_t port)
201{
202    if (regbase)
203        return vga_mm_r(regbase, port);
204    else
205        return vga_io_r(port);
206}
207
208static inline void vga_w(void __iomem *regbase, uint16_t port, uint8_t val)
209{
210    if (regbase)
211        vga_mm_w(regbase, port, val);
212    else
213        vga_io_w(port, val);
214}
215
216
217static inline void vga_w_fast(void __iomem *regbase, uint16_t port, uint8_t reg, uint8_t val)
218{
219    if (regbase)
220        vga_mm_w_fast(regbase, port, reg, val);
221    else
222        vga_io_w_fast(port, reg, val);
223}
224
225
226/*
227 * VGA CRTC register read/write
228 */
229 
230static inline uint8_t vga_rcrt(void __iomem *regbase, uint8_t reg)
231{
232    vga_w(regbase, VGA_CRT_IC, reg);
233    return vga_r(regbase, VGA_CRT_DC);
234}
235
236static inline void vga_wcrt(void __iomem *regbase, uint8_t reg, uint8_t val)
237{
238#ifdef VGA_OUTW_WRITE
239    vga_w_fast(regbase, VGA_CRT_IC, reg, val);
240#else
241    vga_w(regbase, VGA_CRT_IC, reg);
242    vga_w(regbase, VGA_CRT_DC, val);
243#endif /* VGA_OUTW_WRITE */
244}
245
246/*
247 * VGA sequencer register read/write
248 */
249 
250static inline uint8_t vga_rseq(void __iomem *regbase, uint8_t reg)
251{
252    vga_w(regbase, VGA_SEQ_I, reg);
253    return vga_r(regbase, VGA_SEQ_D);
254}
255
256static inline void vga_wseq(void __iomem *regbase, uint8_t reg, uint8_t val)
257{
258#ifdef VGA_OUTW_WRITE
259    vga_w_fast(regbase, VGA_SEQ_I, reg, val);
260#else
261    vga_w(regbase, VGA_SEQ_I, reg);
262    vga_w(regbase, VGA_SEQ_D, val);
263#endif /* VGA_OUTW_WRITE */
264}
265
266/*
267 * VGA graphics controller register read/write
268 */
269 
270static inline uint8_t vga_rgfx(void __iomem *regbase, uint8_t reg)
271{
272    vga_w(regbase, VGA_GFX_I, reg);
273    return vga_r(regbase, VGA_GFX_D);
274}
275
276static inline void vga_wgfx(void __iomem *regbase, uint8_t reg, uint8_t val)
277{
278#ifdef VGA_OUTW_WRITE
279    vga_w_fast(regbase, VGA_GFX_I, reg, val);
280#else
281    vga_w(regbase, VGA_GFX_I, reg);
282    vga_w(regbase, VGA_GFX_D, val);
283#endif /* VGA_OUTW_WRITE */
284}
285
286/*
287 * VGA attribute controller register read/write
288 */
289 
290static inline uint8_t vga_rattr(void __iomem *regbase, uint8_t reg)
291{
292    vga_w(regbase, VGA_ATT_IW, reg);
293    return vga_r(regbase, VGA_ATT_R);
294}
295
296static inline void vga_wattr(void __iomem *regbase, uint8_t reg, uint8_t val)
297{
298    vga_w(regbase, VGA_ATT_IW, reg);
299    vga_w(regbase, VGA_ATT_W, val);
300}
301
302static int detect_video(void *video_base)
303{
304    volatile u16 *p = (volatile u16 *)video_base;
305    u16 saved1 = p[0], saved2 = p[1];
306    int video_found = 1;
307
308    p[0] = 0xAA55;
309    p[1] = 0x55AA;
310    if ( (p[0] != 0xAA55) || (p[1] != 0x55AA) )
311        video_found = 0;
312
313    p[0] = 0x55AA;
314    p[1] = 0xAA55;
315    if ( (p[0] != 0x55AA) || (p[1] != 0xAA55) )
316        video_found = 0;
317
318    p[0] = saved1;
319    p[1] = saved2;
320
321    return video_found;
322}
323
324/* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
325static void *setup_vga(void)
326{
327    /* The following VGA state was saved from a chip in text mode 3. */
328    static unsigned char regs[] = {
329        /* Sequencer registers */
330        0x03, 0x00, 0x03, 0x00, 0x02,
331        /* CRTC registers */
332        0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x20,
333        0x0e, 0x00, 0x00, 0x01, 0xe0, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96,
334        0xb9, 0xa3, 0xff,
335        /* Graphic registers */
336        0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
337        /* Attribute registers */
338        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a,
339        0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00
340    };
341
342    char *video;
343    int i, j;
344
345    if ( memory_is_conventional_ram(0xB8000) )
346        goto no_vga;
347
348    inb(VGA_IS1_RC);
349    outb(0x00, VGA_ATT_IW);
350   
351    for ( i = j = 0; i < 5;  i++ )
352        vga_wseq(vgabase, i, regs[j++]);
353   
354    /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17]. */
355    vga_wcrt(vgabase, 17, regs[5+17] & 0x7F);
356   
357    for ( i = 0; i < 25; i++ ) 
358        vga_wcrt(vgabase, i, regs[j++]);
359   
360    for ( i = 0; i < 9;  i++ )
361        vga_wgfx(vgabase, i, regs[j++]);
362   
363    inb(VGA_IS1_RC);
364    for ( i = 0; i < 21; i++ )
365        vga_wattr(vgabase, i, regs[j++]);
366   
367    inb(VGA_IS1_RC);
368    outb(0x20, VGA_ATT_IW);
369
370    video = ioremap(0xB8000, 0x8000);
371
372    if ( !detect_video(video) )
373    {
374        iounmap(video);
375        goto no_vga;
376    }
377
378    return video;
379
380 no_vga:
381    printk("No VGA adaptor detected!\n");
382    return NULL;
383}
384
385static int vga_set_scanlines(unsigned scanlines)
386{
387    unsigned vtot, ovr, vss, vbs;
388    uint8_t vse, vbe, misc = 0;
389
390    switch (scanlines) {
391    case 43*8:
392        vtot = 0x1bf;
393        vss = 0x183;
394        vse = 0x05;
395        vbs = 0x163;
396        vbe = 0xba;
397        break;
398    case 25*16:
399    case 28*14:
400        vtot = 0x1bf;
401        vss = 0x19c;
402        vse = 0x0e;
403        vbs = 0x196;
404        vbe = 0xb9;
405        break;
406    case 30*16:
407    case 34*14:
408        vtot = 0x20b;
409        vss = 0x1ea;
410        vse = 0x0c;
411        vbs = 0x1e7;
412        vbe = 0x04;
413        /* Preserve clock select bits and color bit, set correct sync polarity. */
414        misc = (inb(VGA_MIS_R) & 0x0d) | 0xe2;
415        break;
416    default:
417        return -ENOSYS;
418    }
419
420    ovr = vga_rcrt(vgabase, VGA_CRTC_OVERFLOW);
421    if(vga_rcrt(vgabase, VGA_CRTC_V_DISP_END) + ((ovr & 0x02) << 7) + ((ovr & 0x40) << 3) == scanlines - 1)
422        return 0;
423
424    ovr = (ovr & 0x10)
425        | ((vtot >> 8) & 0x01)
426        | ((vtot >> 4) & 0x20)
427        | (((scanlines - 1) >> 7) & 0x02)
428        | (((scanlines - 1) >> 3) & 0x40)
429        | ((vss >> 6) & 0x04)
430        | ((vss >> 2) & 0x80)
431        | ((vbs >> 5) & 0x08);
432    vse |= vga_rcrt(vgabase, VGA_CRTC_V_SYNC_END) & 0x70;
433
434    vga_wcrt(vgabase, VGA_CRTC_V_SYNC_END, vse & 0x7f); /* Vertical sync end (also unlocks CR0-7) */
435    vga_wcrt(vgabase, VGA_CRTC_V_TOTAL, (uint8_t)vtot); /* Vertical total */
436    vga_wcrt(vgabase, VGA_CRTC_OVERFLOW, (uint8_t)ovr); /* Overflow */
437    vga_wcrt(vgabase, VGA_CRTC_V_SYNC_START, (uint8_t)vss); /* Vertical sync start */
438    vga_wcrt(vgabase, VGA_CRTC_V_SYNC_END, vse | 0x80); /* Vertical sync end (also locks CR0-7) */
439    vga_wcrt(vgabase, VGA_CRTC_V_DISP_END, (uint8_t)(scanlines - 1)); /* Vertical display end */
440    vga_wcrt(vgabase, VGA_CRTC_V_BLANK_START, (uint8_t)vbs); /* Vertical blank start */
441    vga_wcrt(vgabase, VGA_CRTC_V_BLANK_END, vbe); /* Vertical blank end */
442
443    if (misc)
444        outb(misc, VGA_MIS_W); /* Misc output register */
445
446    return 0;
447}
448
449#define FONT_COUNT_MAX 256
450#define FONT_HEIGHT_MAX 32
451#define CHAR_MAP_SIZE (FONT_COUNT_MAX * FONT_HEIGHT_MAX)
452
453/*
454 * We use font slot 0 because ATI cards do not honour changes to the
455 * character map select register. The fontslot parameter can be used to
456 * choose a non-default slot if the video card supports it and you wish to
457 * preserve the BIOS-initialised font data.
458 */
459static unsigned font_slot = 0;
460integer_param("fontslot", font_slot);
461
462static int vga_load_font(const struct font_desc *font, unsigned rows)
463{
464    unsigned fontheight = font ? font->height : 16;
465    uint8_t fsr = vga_rcrt(vgabase, VGA_CRTC_MAX_SCAN); /* Font size register */
466    int ret;
467
468    if (font_slot > 3 || (!font_slot && !font))
469        return -ENOSYS;
470
471    if (font
472        && (font->count > FONT_COUNT_MAX
473            || fontheight > FONT_HEIGHT_MAX
474            || font->width != 8))
475        return -EINVAL;
476
477    ret = vga_set_scanlines(rows * fontheight);
478    if (ret < 0)
479        return ret;
480
481    if ((fsr & 0x1f) == fontheight - 1)
482        return 0;
483
484    /* First, the Sequencer */
485    vga_wseq(vgabase, VGA_SEQ_RESET, 0x1);
486    /* CPU writes only to map 2 */
487    vga_wseq(vgabase, VGA_SEQ_PLANE_WRITE, 0x04);
488    /* Sequential addressing */
489    vga_wseq(vgabase, VGA_SEQ_MEMORY_MODE, 0x07);
490    /* Clear synchronous reset */
491    vga_wseq(vgabase, VGA_SEQ_RESET, 0x03);
492
493    /* Now, the graphics controller, select map 2 */
494    vga_wgfx(vgabase, VGA_GFX_PLANE_READ, 0x02);
495    /* disable odd-even addressing */
496    vga_wgfx(vgabase, VGA_GFX_MODE, 0x00);
497    /* map start at A000:0000 */
498    vga_wgfx(vgabase, VGA_GFX_MISC, 0x00);
499
500    if ( font )
501    {
502        unsigned i, j;
503        const uint8_t *data = font->data;
504        uint8_t *map;
505
506        map = ioremap(0xA0000 + font_slot*2*CHAR_MAP_SIZE, CHAR_MAP_SIZE);
507
508        for ( i = j = 0; i < CHAR_MAP_SIZE; )
509        {
510            writeb(j < font->count * fontheight ? data[j++] : 0, map + i++);
511            if ( !(j % fontheight) )
512                while ( i & (FONT_HEIGHT_MAX - 1) )
513                    writeb(0, map + i++);
514        }
515
516        iounmap(map);
517    }
518
519    /* First, the sequencer, Synchronous reset */
520    vga_wseq(vgabase, VGA_SEQ_RESET, 0x01);
521    /* CPU writes to maps 0 and 1 */
522    vga_wseq(vgabase, VGA_SEQ_PLANE_WRITE, 0x03);
523    /* odd-even addressing */
524    vga_wseq(vgabase, VGA_SEQ_MEMORY_MODE, 0x03);
525    /* Character Map Select: The default font is kept in slot 0. */
526    vga_wseq(vgabase, VGA_SEQ_CHARACTER_MAP,
527             font ? font_slot | (font_slot << 2) : 0x00);
528    /* clear synchronous reset */
529    vga_wseq(vgabase, VGA_SEQ_RESET, 0x03);
530
531    /* Now, the graphics controller, select map 0 for CPU */
532    vga_wgfx(vgabase, VGA_GFX_PLANE_READ, 0x00);
533    /* enable even-odd addressing */
534    vga_wgfx(vgabase, VGA_GFX_MODE, 0x10);
535    /* map starts at b800:0 */
536    vga_wgfx(vgabase, VGA_GFX_MISC, 0x0e);
537
538    /* Font size register */
539    fsr = (fsr & 0xe0) + (fontheight - 1);
540    vga_wcrt(vgabase, VGA_CRTC_MAX_SCAN, fsr);
541
542    /* Cursor shape registers */
543    fsr  = vga_rcrt(vgabase, VGA_CRTC_CURSOR_END) & 0xe0;
544    fsr |= fontheight - fontheight / 6;
545    vga_wcrt(vgabase, VGA_CRTC_CURSOR_END, fsr);
546    fsr  = vga_rcrt(vgabase, VGA_CRTC_CURSOR_START) & 0xe0;
547    fsr |= (fsr & 0x1f) - 1;
548    vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, fsr);
549
550    return 0;
551}
552
553
554/*
555 * HIGH-LEVEL INITIALISATION AND TEXT OUTPUT.
556 */
557
558static int vgacon_enabled = 0;
559static int vgacon_keep    = 0;
560static int vgacon_lines   = 50;
561static const struct font_desc *font;
562
563static int xpos, ypos;
564static unsigned char *video;
565
566/* vga: comma-separated options. */
567static char opt_vga[30] = "";
568string_param("vga", opt_vga);
569
570/* VGA text-mode definitions. */
571#define COLUMNS     80
572#define LINES       vgacon_lines
573#define ATTRIBUTE   7
574#define VIDEO_SIZE  (COLUMNS * LINES * 2)
575
576void vga_init(void)
577{
578    char *p;
579
580    for ( p = opt_vga; p != NULL; p = strchr(p, ',') )
581    {
582        if ( *p == ',' )
583            p++;
584        if ( strncmp(p, "keep", 4) == 0 )
585            vgacon_keep = 1;
586        else if ( strncmp(p, "text-80x", 8) == 0 )
587            vgacon_lines = simple_strtoul(p + 8, NULL, 10);
588    }
589
590    video = setup_vga();
591    if ( !video )
592        return;
593
594    switch ( vgacon_lines )
595    {
596    case 25:
597    case 30:
598        font = &font_vga_8x16;
599        break;
600    case 28:
601    case 34:
602        font = &font_vga_8x14;
603        break;
604    case 43:
605    case 50:
606    case 60:
607        font = &font_vga_8x8;
608        break;
609    }
610
611    if ( (font == NULL) || (vga_load_font(font, vgacon_lines) < 0) )
612    {
613        vgacon_lines = 25;
614        font = NULL;
615    }
616   
617    /* Clear the screen. */
618    memset(video, 0, VIDEO_SIZE);
619    xpos = ypos = 0;
620
621    /* Disable cursor. */
622    vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, 0x20);
623
624    vgacon_enabled = 1;
625}
626
627void vga_endboot(void)
628{
629    if ( !vgacon_enabled )
630        return;
631
632    if ( !vgacon_keep )
633        vgacon_enabled = 0;
634       
635    printk("Xen is %s VGA console.\n",
636           vgacon_keep ? "keeping" : "relinquishing");
637}
638
639
640static void put_newline(void)
641{
642    xpos = 0;
643    ypos++;
644
645    if ( ypos >= LINES )
646    {
647        ypos = LINES-1;
648        memmove((char*)video, 
649                (char*)video + 2*COLUMNS, (LINES-1)*2*COLUMNS);
650        memset((char*)video + (LINES-1)*2*COLUMNS, 0, 2*COLUMNS);
651    }
652}
653
654void vga_putchar(int c)
655{
656    if ( !vgacon_enabled )
657        return;
658
659    if ( c == '\n' )
660    {
661        put_newline();
662    }
663    else
664    {
665        if ( xpos >= COLUMNS )
666            put_newline();
667        video[(xpos + ypos * COLUMNS) * 2]     = c & 0xFF;
668        video[(xpos + ypos * COLUMNS) * 2 + 1] = ATTRIBUTE;
669        ++xpos;
670    }
671}
672
673int fill_console_start_info(struct dom0_vga_console_info *ci)
674{
675    memset(ci, 0, sizeof(*ci));
676
677    if ( !vgacon_enabled )
678        return 0;
679
680    ci->video_type = XEN_VGATYPE_TEXT_MODE_3;
681    ci->u.text_mode_3.rows     = LINES;
682    ci->u.text_mode_3.columns  = COLUMNS;
683    ci->u.text_mode_3.cursor_x = 0;
684    ci->u.text_mode_3.cursor_y = LINES - 1;
685    ci->u.text_mode_3.font_height = font ? font->height : 16;
686
687    return 1;
688}
Note: See TracBrowser for help on using the repository browser.