source: mainline/kernel/arch/ia32/src/boot/vesa_real.inc@ b112055

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b112055 was 9e34750, checked in by Martin Decky <martin@…>, 14 years ago

[merge] VESA VBE improvements (thx Martin Sucha)

  • Property mode set to 100644
File size: 7.1 KB
Line 
1#ifdef CONFIG_FB
2
3#include <macros.h>
4
5#define VESA_INFO_SIZE 1024
6
7#define VESA_MODE_ATTRIBUTES_OFFSET 0
8#define VESA_MODE_LIST_PTR_OFFSET 14
9#define VESA_MODE_SCANLINE_OFFSET 16
10#define VESA_MODE_WIDTH_OFFSET 18
11#define VESA_MODE_HEIGHT_OFFSET 20
12#define VESA_MODE_BPP_OFFSET 25
13#define VESA_MODE_RED_MASK_OFFSET 31
14#define VESA_MODE_RED_POS_OFFSET 32
15#define VESA_MODE_GREEN_MASK_OFFSET 33
16#define VESA_MODE_GREEN_POS_OFFSET 34
17#define VESA_MODE_BLUE_MASK_OFFSET 35
18#define VESA_MODE_BLUE_POS_OFFSET 36
19#define VESA_MODE_PHADDR_OFFSET 40
20
21#define VESA_END_OF_MODES 0xffff
22
23#define VESA_OK 0x4f
24
25#define VESA_GET_INFO 0x4f00
26#define VESA_GET_MODE_INFO 0x4f01
27#define VESA_SET_MODE 0x4f02
28#define VESA_SET_PALETTE 0x4f09
29
30.code32
31vesa_init:
32 jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init
33
34.code16
35vesa_init_real:
36
37 mov %cr0, %eax
38 and $~1, %eax
39 mov %eax, %cr0
40
41 jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
42
43vesa_init_real2:
44 mov $VESA_INIT_SEGMENT, %bx
45
46 mov %bx, %es
47 mov %bx, %fs
48 mov %bx, %gs
49 mov %bx, %ds
50 mov %bx, %ss
51
52 movl %esp, %eax
53 movl $0x0000fffc, %esp
54 movl $0x0000fffc, %ebp
55 pushl %eax
56
57 /* Parse default mode string */
58
59 mov $default_mode - vesa_init, %di
60 xor %eax, %eax
61 xor %ebx, %ebx
62
63 mov $8, %ecx
64 parse_width:
65 mov (%di), %al
66
67 /* Check for digit */
68
69 cmp $'0', %al
70 jb parse_width_done
71
72 cmp $'9', %al
73 ja parse_width_done
74
75 sub $'0', %al
76
77 /* Multiply default_width by 10 and add digit */
78
79 mov default_width - vesa_init, %bx
80 lea (%ebx, %ebx, 4), %ebx
81 shl $1, %ebx
82 add %ax, %bx
83 mov %bx, default_width - vesa_init
84
85 inc %di
86 loop parse_width
87 parse_width_done:
88
89 mov (%di), %al
90 cmp $0, %al
91 jz parse_done
92 inc %di
93
94 mov $8, %ecx
95 parse_height:
96 mov (%di), %al
97
98 /* Check for digit */
99
100 cmp $'0', %al
101 jb parse_height_done
102
103 cmp $'9', %al
104 ja parse_height_done
105
106 sub $'0', %al
107
108 /* Multiply default_height by 10 and add digit */
109
110 mov default_height - vesa_init, %bx
111 lea (%ebx, %ebx, 4), %ebx
112 shl $1, %ebx
113 add %ax, %bx
114 mov %bx, default_height - vesa_init
115
116 inc %di
117 loop parse_height
118 parse_height_done:
119
120 mov (%di), %al
121 cmp $0, %al
122 jz parse_done
123 inc %di
124
125 mov $4, %ecx
126 parse_bpp:
127 mov (%di), %al
128
129 /* Check for digit */
130
131 cmp $'0', %al
132 jb parse_bpp_done
133
134 cmp $'9', %al
135 ja parse_bpp_done
136
137 sub $'0', %al
138
139 /* Multiply default_bpp by 10 and add digit */
140
141 mov default_bpp - vesa_init, %bx
142 lea (%ebx, %ebx, 4), %ebx
143 shl $1, %ebx
144 add %ax, %bx
145 mov %bx, default_bpp - vesa_init
146
147 inc %di
148 loop parse_bpp
149 parse_bpp_done:
150
151 parse_done:
152
153 mov $VESA_GET_INFO, %ax
154 mov $e_vesa_init - vesa_init, %di
155 push %di
156 /* Write the "VBE2" signature into the info structure in order
157 * to get proper mode information. The presence of "VBE2"
158 * indicates two things:
159 *
160 * - VBE controller information structure is expected to be
161 * 512 bytes long instead of 256 bytes.
162 * - The BIOS should report VBE 3.0 information (potentially
163 * including non-standard modes in the mode list).
164 */
165 movl $0x32454256, (%di)
166 int $0x10
167
168 pop %di
169 cmp $VESA_OK, %al
170 jnz no_mode
171
172 mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
173 mov %si, %gs
174 mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
175
176 add $VESA_INFO_SIZE, %di
177
178 next_mode:
179 /* Try next mode */
180
181 mov %gs:(%si), %cx
182 cmp $VESA_END_OF_MODES, %cx
183 je no_mode
184
185 inc %si
186 inc %si
187 push %cx
188 push %di
189 push %si
190 mov $VESA_GET_MODE_INFO, %ax
191 int $0x10
192
193 pop %si
194 pop %di
195 pop %cx
196 cmp $VESA_OK, %al
197 jne no_mode
198
199 /*
200 * Check for proper attributes (supported,
201 * color, graphics, linear framebuffer).
202 */
203
204 mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
205 and $0x99, %ax
206 cmp $0x99, %ax
207 jne next_mode
208
209 /* Check for proper resolution */
210
211 mov default_width - vesa_init, %ax
212 cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
213 jne next_mode
214
215 mov default_height - vesa_init, %ax
216 cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
217 jne next_mode
218
219 /* Check for proper bpp */
220
221 mov default_bpp - vesa_init, %al
222 cmp VESA_MODE_BPP_OFFSET(%di), %al
223 je set_mode
224
225 mov $24, %al
226 cmp default_bpp - vesa_init, %al
227 jne next_mode
228
229 /* For 24 bpp modes accept also 32 bit bpp */
230
231 mov $32, %al
232 cmp VESA_MODE_BPP_OFFSET(%di), %al
233 jne next_mode
234
235 set_mode:
236 mov %cx, %bx
237 or $0xc000, %bx
238 push %di
239 mov $VESA_SET_MODE, %ax
240 int $0x10
241
242 pop %di
243 cmp $VESA_OK, %al
244 jnz no_mode
245
246 /* Set 3:2:3 VGA palette */
247
248 mov VESA_MODE_BPP_OFFSET(%di), %al
249 cmp $8, %al
250 jnz vga_not_set
251
252 mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
253 push %di
254 mov $vga323 - vesa_init, %di
255 mov $0x100, %ecx
256
257 /* Test if VGA compatible registers are present */
258 bt $5, %ax
259 jnc vga_compat
260
261 /* Use VESA routine to set the palette */
262
263 mov $VESA_SET_PALETTE, %ax
264 xor %bl, %bl
265 xor %dx, %dx
266 int $0x10
267
268 cmp $0x00, %ah
269 je vga_not_compat
270
271 vga_compat:
272
273 /* Use VGA registers to set the palette */
274
275 movw $0x3c6, %dx /* set palette mask */
276 movb $0xff, %al
277 outb %al, %dx
278
279 movw $0x3c8, %dx /* first index to set */
280 xor %al, %al
281 outb %al, %dx
282
283 movw $0x3c9, %dx /* data port */
284
285 vga_loop:
286 movb %es:2(%di), %al
287 outb %al, %dx
288
289 movb %es:1(%di), %al
290 outb %al, %dx
291
292 movb %es:(%di), %al
293 outb %al, %dx
294
295 addw $4, %di
296 loop vga_loop
297
298 vga_not_compat:
299
300 pop %di
301
302 vga_not_set:
303
304 /*
305 * Store mode parameters:
306 * eax = bpp[8] scanline[16]
307 * ebx = width[16] height[16]
308 * edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
309 * esi = blue_mask[8] blue_pos[8]
310 * edi = linear frame buffer
311 */
312
313 mov VESA_MODE_BPP_OFFSET(%di), %al
314 xor %ah, %ah
315 shl $16, %eax
316 mov VESA_MODE_SCANLINE_OFFSET(%di), %ax
317
318 mov VESA_MODE_WIDTH_OFFSET(%di), %bx
319 shl $16, %ebx
320 mov VESA_MODE_HEIGHT_OFFSET(%di), %bx
321
322 mov VESA_MODE_BLUE_MASK_OFFSET(%di), %dl
323 shl $8, %edx
324 mov VESA_MODE_BLUE_POS_OFFSET(%di), %dl
325 mov %edx, %esi
326
327 mov VESA_MODE_RED_MASK_OFFSET(%di), %dl
328 shl $8, %edx
329 mov VESA_MODE_RED_POS_OFFSET(%di), %dl
330 shl $8, %edx
331 mov VESA_MODE_GREEN_MASK_OFFSET(%di), %dl
332 shl $8, %edx
333 mov VESA_MODE_GREEN_POS_OFFSET(%di), %dl
334
335 mov VESA_MODE_PHADDR_OFFSET(%di), %edi
336
337 vesa_leave_real:
338
339 mov %cr0, %ecx
340 or $1, %ecx
341 mov %ecx, %cr0
342
343 jmp vesa_leave_real2
344
345 vesa_leave_real2:
346
347 ljmpl $GDT_SELECTOR(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
348
349 no_mode:
350
351 /* No prefered mode found */
352
353 mov $0x111, %cx
354 push %di
355 push %cx
356 mov $VESA_GET_MODE_INFO, %ax
357 int $0x10
358
359 pop %cx
360 pop %di
361 cmp $VESA_OK, %al
362 jnz text_mode
363 jz set_mode /* force relative jump */
364
365 text_mode:
366
367 /* Reset to EGA text mode (because of problems with VESA) */
368
369 mov $0x0003, %ax
370 int $0x10
371 mov $0xffffffff, %edi
372 xor %ax, %ax
373 jz vesa_leave_real /* force relative jump */
374
375vga323:
376#include "vga323.pal"
377
378default_width:
379 .word 0
380
381default_height:
382 .word 0
383
384default_bpp:
385 .byte 0
386
387default_mode:
388 .ascii STRING(CONFIG_VESA_MODE)
389 .ascii "-"
390 .asciz STRING(CONFIG_VESA_BPP)
391 .fill 24
392
393#include "vesa_ret.inc"
394
395.align 4
396e_vesa_init:
397#endif
Note: See TracBrowser for help on using the repository browser.