~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to kernel/arch/ia32/src/boot/vesa_real.inc

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
31
vesa_init:
 
32
        jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
 
33
        
 
34
.code16
 
35
vesa_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
        
 
43
vesa_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
        int $0x10
 
157
        
 
158
        pop %di
 
159
        cmp $VESA_OK, %al
 
160
        jnz no_mode
 
161
        
 
162
        mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
 
163
        mov %si, %gs
 
164
        mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
 
165
        
 
166
        add $VESA_INFO_SIZE, %di
 
167
        
 
168
        next_mode:
 
169
                # try next mode
 
170
                mov %gs:(%si), %cx
 
171
                cmp $VESA_END_OF_MODES, %cx
 
172
                je no_mode
 
173
                
 
174
                inc %si
 
175
                inc %si
 
176
                push %cx
 
177
                push %di
 
178
                push %si
 
179
                mov $VESA_GET_MODE_INFO, %ax
 
180
                int $0x10
 
181
                
 
182
                pop %si
 
183
                pop %di
 
184
                pop %cx
 
185
                cmp $VESA_OK, %al
 
186
                jne no_mode
 
187
                
 
188
                # check for proper attributes (supported, color, graphics, linear framebuffer)
 
189
                
 
190
                mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
 
191
                and $0x99, %ax
 
192
                cmp $0x99, %ax
 
193
                jne next_mode
 
194
                
 
195
                # check for proper resolution
 
196
                
 
197
                mov default_width - vesa_init, %ax
 
198
                cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
 
199
                jne next_mode
 
200
                
 
201
                mov default_height - vesa_init, %ax
 
202
                cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
 
203
                jne next_mode
 
204
                
 
205
                # check for proper bpp
 
206
                
 
207
                mov default_bpp - vesa_init, %al
 
208
                cmp VESA_MODE_BPP_OFFSET(%di), %al
 
209
                je set_mode
 
210
                
 
211
                mov $24, %al
 
212
                cmp default_bpp - vesa_init, %al
 
213
                jne next_mode
 
214
                
 
215
                # for 24 bpp modes accept also 32 bit bpp
 
216
                
 
217
                mov $32, %al
 
218
                cmp VESA_MODE_BPP_OFFSET(%di), %al
 
219
                jne next_mode
 
220
        
 
221
        set_mode:
 
222
                mov %cx, %bx
 
223
                or $0xc000, %bx
 
224
                push %di
 
225
                mov $VESA_SET_MODE, %ax
 
226
                int $0x10
 
227
                
 
228
                pop %di
 
229
                cmp $VESA_OK, %al
 
230
                jnz no_mode
 
231
                
 
232
                # set 3:2:3 VGA palette
 
233
                
 
234
                mov VESA_MODE_BPP_OFFSET(%di), %al
 
235
                cmp $8, %al
 
236
                jnz vga_not_set
 
237
                
 
238
                mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
 
239
                push %di
 
240
                mov $vga323 - vesa_init, %di
 
241
                mov $0x100, %ecx
 
242
                
 
243
                bt $5, %ax              # test if VGA compatible registers are present
 
244
                jnc vga_compat
 
245
                
 
246
                        # try VESA routine to set palette
 
247
                        mov $VESA_SET_PALETTE, %ax
 
248
                        xor %bl, %bl
 
249
                        xor %dx, %dx
 
250
                        int $0x10
 
251
                        
 
252
                        cmp $0x00, %ah
 
253
                        je vga_not_compat
 
254
                
 
255
                vga_compat:
 
256
                        # try VGA registers to set palette
 
257
                        movw $0x3c6, %dx    # set palette mask
 
258
                        movb $0xff, %al
 
259
                        outb %al, %dx
 
260
                        
 
261
                        movw $0x3c8, %dx    # first index to set
 
262
                        xor %al, %al
 
263
                        outb %al, %dx
 
264
                        
 
265
                        movw $0x3c9, %dx    # data port
 
266
                        
 
267
                        vga_loop:
 
268
                                movb %es:2(%di), %al
 
269
                                outb %al, %dx
 
270
                                
 
271
                                movb %es:1(%di), %al
 
272
                                outb %al, %dx
 
273
                                
 
274
                                movb %es:(%di), %al
 
275
                                outb %al, %dx
 
276
                                
 
277
                                addw $4, %di
 
278
                        loop vga_loop
 
279
                
 
280
                vga_not_compat:
 
281
                
 
282
                        pop %di
 
283
                
 
284
                vga_not_set:
 
285
                
 
286
                # store mode parameters
 
287
                #  eax = bpp[8] scanline[16]
 
288
                #  ebx = width[16]  height[16]
 
289
                #  edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
 
290
                #  esi = blue_mask[8] blue_pos[8]
 
291
                #  edi = linear frame buffer
 
292
                
 
293
                mov VESA_MODE_BPP_OFFSET(%di), %al
 
294
                xor %ah, %ah
 
295
                shl $16, %eax
 
296
                mov VESA_MODE_SCANLINE_OFFSET(%di), %ax
 
297
                
 
298
                mov VESA_MODE_WIDTH_OFFSET(%di), %bx
 
299
                shl $16, %ebx
 
300
                mov VESA_MODE_HEIGHT_OFFSET(%di), %bx
 
301
                
 
302
                mov VESA_MODE_BLUE_MASK_OFFSET(%di), %dl
 
303
                shl $8, %edx
 
304
                mov VESA_MODE_BLUE_POS_OFFSET(%di), %dl
 
305
                mov %edx, %esi
 
306
                
 
307
                mov VESA_MODE_RED_MASK_OFFSET(%di), %dl
 
308
                shl $8, %edx
 
309
                mov VESA_MODE_RED_POS_OFFSET(%di), %dl
 
310
                shl $8, %edx
 
311
                mov VESA_MODE_GREEN_MASK_OFFSET(%di), %dl
 
312
                shl $8, %edx
 
313
                mov VESA_MODE_GREEN_POS_OFFSET(%di), %dl
 
314
                
 
315
                mov VESA_MODE_PHADDR_OFFSET(%di), %edi
 
316
                
 
317
                vesa_leave_real:
 
318
                
 
319
                        mov %cr0, %ecx
 
320
                        or $1, %ecx
 
321
                        mov %ecx, %cr0
 
322
                        
 
323
                        jmp vesa_leave_real2
 
324
                        
 
325
                vesa_leave_real2:
 
326
                
 
327
                        ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
 
328
        
 
329
        no_mode:
 
330
                # no prefered mode found
 
331
                mov $0x111, %cx
 
332
                push %di
 
333
                push %cx
 
334
                mov $VESA_GET_MODE_INFO, %ax
 
335
                int $0x10
 
336
                
 
337
                pop %cx
 
338
                pop %di
 
339
                cmp $VESA_OK, %al
 
340
                jnz text_mode
 
341
                jz set_mode             # force relative jump
 
342
        
 
343
        text_mode:
 
344
                # reset to EGA text mode (because of problems with VESA)
 
345
                mov $0x0003, %ax
 
346
                int $0x10
 
347
                mov $0xffffffff, %edi
 
348
                xor %ax, %ax
 
349
                jz vesa_leave_real      # force relative jump
 
350
 
 
351
vga323:
 
352
#include "vga323.pal"
 
353
 
 
354
default_width:
 
355
        .word 0
 
356
 
 
357
default_height:
 
358
        .word 0
 
359
 
 
360
default_bpp:
 
361
        .byte 0
 
362
 
 
363
default_mode:
 
364
        .ascii STRING(CONFIG_VESA_MODE)
 
365
        .ascii "-"
 
366
        .asciz STRING(CONFIG_VESA_BPP)
 
367
        .fill 24
 
368
 
 
369
#include "vesa_ret.inc"
 
370
 
 
371
.align 4
 
372
e_vesa_init:
 
373
#endif