This patch updates the PCI ID of the Geode IDE device to include the revision.
[coreboot.git] / util / ADLO / loader.s
1 ;*****************************************************
2 ; $Id: loader.s,v 1.1 2002/11/25 02:07:53 rminnich Exp $
3 ;*****************************************************
4 USE32
5 ; code it is loaded into memory at 0x7C00
6 ;*****************************************************
7 nop
8 nop
9 ;*****************************************************
10 ; A) setup GDT, so that we do not depend on program 
11 ; that loaded us for GDT. 
12 ; Ex: LinuxBIOS and EtherBOOT use different GDT's.
13
14 ;-----------------------------------------------------
15 ; 0)
16
17 cli
18
19 ;-----------------------------------------------------
20 ; I)
21
22 lgdt [0x7C00+protected_gdt]
23
24 ;-----------------------------------------------------
25 ; II) setup CS
26
27 jmp 0x08:0x7C00+newpgdt
28
29 newpgdt: nop
30
31 ;-----------------------------------------------------
32 ; III) setup all other segments
33
34 mov ax,  #0x10
35 mov ss,  ax
36 mov ds,  ax
37 mov es,  ax
38 mov fs,  ax
39 mov gs,  ax
40
41 ;-----------------------------------------------------
42 ; IV) 
43
44 ; not now
45 ;sti
46
47 ;*****************************************************
48 nop
49 nop
50 ;*****************************************************
51 ; B) shadow - ON (enable/read/write)
52
53 mov eax, #0x80000070
54 mov dx,  #0x0cf8
55 out dx,  eax
56
57 mov eax, #0xFFFFFFFF
58 mov dx,  #0x0cfc
59 out dx,  eax
60
61 ;*****************************************************
62 nop
63 nop
64 ;*****************************************************
65 ; C) copy -- boch bios
66
67 ; counter - 64kb.     
68 mov ecx, #0x10000
69
70 ; source - 0x8000  ( 0x7C00+0x400 = 0x8000 ) 
71 mov ax,  #0x10        ; src-segment - 2nd entry in GDT
72 mov ds,  ax
73 mov eax, #0x8000      ; src-offset  - 0x8000
74 mov esi, eax
75
76 ; destination - 0xE0000
77 mov ax,  #0x10        ; dst-segment - 2nd entry in GDT
78 mov es,  ax     
79 mov eax, #0xF0000     ; dst-offset  - 0xF0000
80 mov edi, eax
81
82 ; clear direction flag
83 cld
84
85 ; the copy
86 rep
87   movsb
88
89 ;*****************************************************
90 nop
91 nop
92 ;*****************************************************
93 ; X) copy -- LinuxBIOS table into safe place.
94
95         ;; TODO.
96         ;; Q1 :  what is the size of table.
97         ;; Q2 :  where to copy?
98                 
99 ;*****************************************************
100 nop
101 nop     
102 ;*****************************************************
103 ; E) shadow - OFF (write)
104
105 mov eax, #0x80000070
106 mov dx,  #0x0cf8
107 out dx,  eax
108
109 ;mov eax, #0xFFFFFFFF
110 mov eax, #0x0000FFFF
111 mov dx,  #0x0cfc
112 out dx,  eax
113
114 ;*****************************************************
115 nop
116 nop
117 ;*****************************************************
118 ; F) do a little prep work.
119
120 ;-----------------------------------------------------
121 ; I) disable cache
122
123 ; if you disable cache, GRUB's GFX mode will be VERY slow.
124 ; so DO NOT DISABLE
125
126 ;mov eax, cr0
127 ;or  eax, #0x60000000
128 ;wbinvd
129 ;mov cr0, eax
130 ;wbinvd
131
132 ;-----------------------------------------------------
133 ; II) disable MTRR
134 ; clear the "E" (0x800) and "FE" (0x400) flags in 
135 ; IA32_MTRRdefType register (0x2FF)
136
137 ;-----------------------
138
139 ;mov ECX,#0x2FF
140
141 ; select either of the two below 
142 ; depending on if your compiler suports 
143 ; {RD,WR}MSR or not
144 ;rdmsr
145 ; .byte 0x0F, 0x32
146
147 ;xor edx, edx
148 ; xor eax, eax
149 ;and eax, #0xFFFFF3FF
150
151 ; select either of the two below 
152 ; depending on if your compiler suports 
153 ; {RD,WR}MSR or not
154 ;wrmsr
155 ; .byte 0x0F, 0x30
156
157 ;-----------------------
158 ;; This is what PC BIOS is setting. -- P6STMT.
159 ; add VIDEO BIOS cacheable!!!!
160 ;-----------------------
161 ; Fixed Range C0--C8
162 ;mov ECX,#0x268
163 ;mov EDX,#0x05050505 
164 ;mov EAX,#0x05050505 
165 ;wrmsr
166 ;-----------------------
167 ; Fixed Range C8--CF
168 ;mov ECX,#0x269
169 ;mov EDX,#0x0 
170 ;mov EAX,#0x05050505 
171 ;wrmsr
172 ;-----------------------
173
174 ;-----------------------------------------------------
175 ; III) tell BOCHS' BIOS we want to boot from hdd.
176 ; 0x00 - floppy
177 ; 0x02 - hdd
178 ; In future there will be 'fd failover'option in bochs.
179
180 mov  al, #0x3d ;; cmos_reg
181 out  0x70, al
182 mov  al, #0x02 ;; val (hdd)
183 out  0x71, al
184
185 ;-----------------------------------------------------
186 ; IV) tell BOCHS' BIOS length of our mem block @ 1mb.
187 ;     This is for Int 15 / EAX=E820
188 ;     119mb = 0x77 00 00 00 
189 ;     (this is for 128mb of ram)
190 ;     (FIXME: this value is currently hard coded)
191 ;     (it should be being passed from LinuxBIOS )
192
193 ; for WinFast  6300
194 ; 07 70 = 0770
195 ; 06 80 = 0770 - 00F0           << ALT (for unpatched bochs)
196
197 ; for P6STMT - 10kb less ram
198 ; 077F - 10     = 07 6F 
199 ; 07 6F - 00 F0 = 06 7F
200
201 mov  al, #0x35 ;; cmos_reg
202 out  0x70, al
203 mov  al, #0x06 ;; val 
204 out  0x71, al
205
206 mov  al, #0x34 ;; cmos_reg
207 out  0x70, al
208 mov  al, #0x7F ;; val 
209 out  0x71, al
210
211 mov  al, #0x31 ;; cmos_reg
212 out  0x70, al
213 mov  al, #0x00 ;; val 
214 out  0x71, al
215
216 mov  al, #0x30 ;; cmos_reg
217 out  0x70, al
218 mov  al, #0x00 ;; val 
219 out  0x71, al
220
221 ;-----------------------------------------------------
222 ; V) tell BOCHS' BIOS we want to have LBA translation.
223 ; 0x00 - NONE
224 ; 0x01 - LBA    <<<<
225 ; 0x02 - LARGE
226 ; 0x03 - R-CHS
227 ; In future there will be 'fd failover'option in bochs.
228
229 mov  al, #0x39 ;; cmos_reg
230 out  0x70, al
231 mov  al, #0x01 ;; val (LBA)
232 out  0x71, al
233
234 ;*****************************************************
235 nop
236 nop
237 ;*****************************************************
238 ; G) the switch -- protected to real mode
239
240 ; IASDM, Vol 3
241 ; (8-14) 8.8.2 Switching Back to Real-Address Mode
242
243 ;=====================================================
244 ; 1) disable interrupts
245
246 cli
247
248 ;=====================================================
249 nop
250 ;=====================================================
251 ; 2) paging
252
253 ;not enabled, so not applicable.
254
255 ;=====================================================
256 ; 3) setup CS segment limit (64kb)
257 ; I)
258
259 lgdt [0x7C00+new_gdt]
260
261 ;-----------------------------------------------------
262 ; II)
263
264 jmp 0x08:0x7C00+new64lim
265
266 new64lim: nop
267
268 ;=====================================================
269 nop
270 ;=====================================================
271 ; 4) setup all other segments
272
273 mov ax,  #0x10
274 mov ss,  ax
275 mov ds,  ax
276 mov es,  ax
277 mov fs,  ax
278 mov gs,  ax
279
280 ;=====================================================
281 nop
282 ;=====================================================
283 ; 5) LIDT
284 ; I)
285
286 ; set up Real Mode IDT table (0...3FF)
287
288 ; for BOCH's BIOS the address 0xF000:0xFF53 
289 ; cantains value 0xCF which is IRET opcode.
290
291 ; counter 
292 mov cx,  #0xFF ;1024 bytes(255 interrupts)(4*255=0x3FF)
293
294 ; destination - 0x00000 = ES:EDI
295 mov ax,  #0x10        ; dst-segment - 2nd entry in GDT
296 mov es,  ax
297 mov eax, #0x00000     ; dst-offset  - 0x00000
298 mov edi, eax
299
300 ; data to store -- 0xF000:FF53
301 mov eax, #0xF000FF53
302
303 ; clear direction flag
304 cld
305
306 ; the store 
307 rep
308   stosd
309
310 ;-----------------------------------------------------
311 ; II)
312 ; load interrupt descriptor table
313
314 lidt [0x7C00+new_idt]
315
316 ;=====================================================
317 nop
318 nop
319 ;=====================================================
320 ; 6) clear the PE flag in CR0 register.
321 ; I)
322
323 ; switch to 16 bit segments
324 mov ax,  #0x20
325 mov ss,  ax
326 mov ds,  ax
327 mov es,  ax
328 mov fs,  ax
329 mov gs,  ax
330
331 ;-----------------------------------------------------
332 ; II)
333
334 ; switch to 16 bit CS
335
336 jmp 0x018:0x7C00+new16bit
337
338 USE16
339
340 new16bit: nop
341
342 ;-----------------------------------------------------
343 ; III)
344 ; the switch
345
346 ;xor eax, eax
347
348 mov eax, cr0            
349 and eax, #0xFFFFFFFE
350 mov cr0, eax            ;switch to RM
351
352 ;=====================================================
353 nop
354 nop
355 ;=====================================================
356 ; 7) far jump -- (to real mode address)
357
358 jmp 0x0:0x7C00+realcs
359
360 realcs: nop
361
362 ;=====================================================
363 ; 8) set all segment registers to 0's
364
365 mov ax,  #0x0
366 mov ss,  ax
367 mov ds,  ax
368 mov es,  ax
369 mov fs,  ax
370 mov gs,  ax
371
372 ;=====================================================
373 ; 9) re-enable interrupts
374
375 sti
376
377 ;*****************************************************
378 nop
379 nop
380 ;*****************************************************
381 ; G) jump to BIOS.
382
383 jmp 0xFFFF:0x0000
384 ;jmp 0xF000:0xFFF0
385
386 ;*****************************************************
387 ;*****************************************************
388 nop
389 nop
390 nop
391 nop
392 ;*****************************************************
393 ;*****************************************************
394
395 USE32
396
397 new_idt:
398 dw 0x03ff ;; limit 15:00
399 dw 0x0000 ;; base  15:00
400 dw 0x0000 ;; base  23:16
401
402 new_gdt:
403 dw 0x0028                     ;; limit 15:00
404 dw 0x7C00+new_gdt_table       ;; base  15:00
405 dw 0x0000                     ;; base  23:16
406
407 protected_gdt:
408 dw 0x0018                     ;; limit 15:00
409 dw 0x7C00+pmode_gdt_table     ;; base  15:00
410 dw 0x0000                     ;; base  23:16
411
412 ;-----------------------------------------------------
413
414 new_gdt_table:
415 ;//  1 2 3 4 
416 ;//0
417 dd 0x00000000
418 dd 0x00000000
419
420 ;//8
421 dd 0x0000ffff
422 dd 0x00409E00
423
424 ;//10
425 dd 0x0000ffff
426 dd 0x00409200
427
428 ;//18
429 dd 0x0000ffff
430 dd 0x00009a00
431
432 ;//20
433 dd 0x0000ffff
434 dd 0x00009200
435
436 ;-------------------------
437
438 pmode_gdt_table:
439 ;//  1 2 3 4 
440 ;//0
441 dd 0x00000000
442 dd 0x00000000
443
444 ;//8
445 dd 0x0000ffff
446 dd 0x00CF9E00
447
448 ;//10
449 dd 0x0000ffff
450 dd 0x00CF9200
451
452 ;*****************************************************
453 ;*****************************************************
454 ; the file size must be 1024 bytes.
455
456
457 .org 0x400-1
458 ; dd 0xdeadbeef                 
459 db 0x0
460
461 ;*****************************************************