78f410be347588bfd458154b8d8974ce90cb35e1
[coreboot.git] / payloads / libpayload / drivers / video / video.c
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2008 Advanced Micro Devices, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <config.h>
31 #include <libpayload.h>
32 #include <video_console.h>
33
34 #ifdef CONFIG_GEODE_VIDEO_CONSOLE
35 extern struct video_console geode_video_console;
36 #endif
37
38 #ifdef CONFIG_VGA_VIDEO_CONSOLE
39 extern struct video_console vga_video_console;
40 #endif
41
42 static struct video_console *console_list[] =
43 {
44 #ifdef CONFIG_GEODE_VIDEO_CONSOLE
45         &geode_video_console,
46 #endif
47 #ifdef CONFIG_VGA_VIDEO_CONSOLE
48         &vga_video_console,
49 #endif
50 };
51
52 static struct video_console *console;
53
54 static unsigned int cursorx;
55 static unsigned int cursory;
56 static unsigned int cursor_enabled = 1;
57
58 static void video_console_fixup_cursor(void)
59 {
60         if (!cursor_enabled)
61                 return;
62
63         if (cursorx < 0)
64                 cursorx = 0;
65
66         if (cursory < 0)
67                 cursory = 0;
68
69         if (cursorx > VIDEO_COLS) {
70                 cursorx = 0;
71                 cursory++;
72         }
73
74         while(cursory >= VIDEO_ROWS) {
75                 console->scroll_up();
76                 cursory--;
77         }
78
79         if (console && console->set_cursor)
80                 console->set_cursor(cursorx, cursory);
81 }
82
83 void video_console_cursor_enable(int state)
84 {
85         if (console && console->enable_cursor)
86                 console->enable_cursor(state);
87
88         cursor_enabled = state;
89
90         if (cursor_enabled)
91                 video_console_fixup_cursor();
92 }
93
94 void video_console_clear(void)
95 {
96         if (console)
97                 console->clear();
98
99         cursorx = 0;
100         cursory = 0;
101
102         if (console && console->set_cursor)
103                 console->set_cursor(cursorx, cursory);
104 }
105
106 void video_console_putc(u8 row, u8 col, unsigned int ch)
107 {
108         if (console)
109                 console->putc(row, col, ch);
110 }
111
112 void video_console_putchar(unsigned int ch)
113 {
114         switch(ch & 0xFF) {
115         case '\r':
116                 cursorx = 0;
117                 break;
118
119         case '\n':
120                 cursory++;
121                 break;
122
123         case '\b':
124                 cursorx--;
125                 break;
126
127         case '\t':
128                 while(cursorx % 8 && cursorx < VIDEO_COLS) {
129                         if (console)
130                                 console->putc(cursory, cursorx, (ch & 0xFF00) | ' ');
131
132                         cursorx++;
133                 }
134                 break;
135         default:
136                 if (console)
137                         console->putc(cursory, cursorx++, ch);
138                 break;
139         }
140
141         video_console_fixup_cursor();
142 }
143
144 void video_console_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en)
145 {
146         *x=0;
147         *y=0;
148         *en=0;
149
150         if (console->get_cursor)
151                 console->get_cursor(x, y, en);
152
153         *x = cursorx;
154         *y = cursory;
155 }
156
157 void video_console_set_cursor(unsigned int x, unsigned int y)
158 {
159         cursorx = x;
160         cursory = y;
161         video_console_fixup_cursor();
162 }
163
164 int video_console_init(void)
165 {
166                 int i;
167
168                 for(i = 0; i < ARRAY_SIZE(console_list); i++) {
169                         if (console_list[i]->init())
170                                 continue;
171
172                         console = console_list[i];
173
174                         if (console->get_cursor)
175                                 console->get_cursor(&cursorx, &cursory, &cursor_enabled);
176
177                         if (cursorx) {
178                                 cursorx = 0;
179                                 cursory++;
180                         }
181
182                         video_console_fixup_cursor();
183                         return 0;
184                 }
185
186                 return 0;
187 }
188