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

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

explicitly load default BIOS IDT for real-mode VESA BIOS access (GRUB 2.00 setups an empty IDT for bootstrap)
always use an empty IDT during bootstrap (for consistency)
make sure the interrupts are disabled during bootstrap
make sure correct GDT is set after returning from VESA BIOS

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