3 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <libpayload.h>
30 #include <video_console.h>
32 struct video_console vga_video_console
;
34 #define VGA_COLOR_WHITE 7
36 #define CRTC_INDEX 0x3d4
37 #define CRTC_DATA 0x3d5
39 #define VIDEO(_r, _c)\
40 ((u16 *) (phys_to_virt(0xB8000) + ((_r) * (vga_video_console.columns * 2)) + ((_c) * 2)))
42 static u8
crtc_read(u8 index
)
44 outb(index
, CRTC_INDEX
);
45 return inb(CRTC_DATA
);
48 static void crtc_write(u8 data
, u8 index
)
50 outb(index
, CRTC_INDEX
);
51 outb(data
, CRTC_DATA
);
54 static void vga_get_cursor(unsigned int *x
, unsigned int *y
, unsigned int *en
)
57 addr
= ((unsigned int) crtc_read(0x0E)) << 8;
58 addr
+= crtc_read(0x0F);
60 *x
= addr
% vga_video_console
.columns
;
61 *y
= addr
/ vga_video_console
.columns
;
63 *en
= !(crtc_read(0x0A) & (1 << 5));
66 static void vga_set_cursor(unsigned int x
, unsigned int y
)
70 addr
= x
+ (vga_video_console
.columns
* y
);
71 crtc_write(addr
>> 8, 0x0E);
72 crtc_write(addr
, 0x0F);
75 static void vga_enable_cursor(int state
)
77 unsigned char tmp
= crtc_read(0x0a);
85 crtc_write(tmp
, 0x0a);
88 static void vga_clear_line(u8 row
, u8 ch
, u8 attr
)
91 u16
*ptr
= VIDEO(row
, 0);
93 for(col
= 0; col
< vga_video_console
.columns
; col
++)
94 ptr
[col
] = ((attr
& 0xFF) << 8) | (ch
& 0xFF);
97 static void vga_scroll_up(void)
99 u16
*src
= VIDEO(1,0);
100 u16
*dst
= VIDEO(0,0);
103 for(i
= 0; i
< (vga_video_console
.rows
- 1) * vga_video_console
.columns
; i
++)
106 vga_clear_line(vga_video_console
.rows
- 1, ' ', VGA_COLOR_WHITE
);
109 static void vga_fill(u8 ch
, u8 attr
)
112 for(row
= 0; row
< vga_video_console
.rows
; row
++)
113 vga_clear_line(row
, ch
, attr
);
116 static void vga_clear(void)
118 vga_fill(' ', VGA_COLOR_WHITE
);
121 static void vga_putc(u8 row
, u8 col
, unsigned int c
)
123 u16
*ptr
= VIDEO(row
, col
);
124 *ptr
= (u16
) (c
& 0xFFFF);
127 static void vga_init_cursor(void)
131 #define CURSOR_MSL 0x09 /* cursor maximum scan line */
132 #define CURSOR_START 0x0A /* cursor start */
133 #define CURSOR_END 0x0B /* cursor end */
135 val
= crtc_read(CURSOR_MSL
) & 0x1f;
136 crtc_write(0, CURSOR_START
);
137 crtc_write(val
- 2, CURSOR_END
);
140 static int vga_init(void)
146 struct video_console vga_video_console
= {
150 .scroll_up
= vga_scroll_up
,
152 .get_cursor
= vga_get_cursor
,
153 .set_cursor
= vga_set_cursor
,
154 .enable_cursor
= vga_enable_cursor
,