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

Last change on this file since 77578e8 was 77578e8, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Whittle down more unlicensed files using my best guess as to the intended licensing

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