]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/BootSector/efi32.asm
DuetPkg BootSector:
[mirror_edk2.git] / DuetPkg / BootSector / efi32.asm
1 ;------------------------------------------------------------------------------
2 ;*
3 ;* Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 ;* This program and the accompanying materials
5 ;* are licensed and made available under the terms and conditions of the BSD License
6 ;* which accompanies this distribution. The full text of the license may be found at
7 ;* http://opensource.org/licenses/bsd-license.php
8 ;*
9 ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 ;*
12 ;* efi32.asm
13 ;*
14 ;* Abstract:
15 ;*
16 ;------------------------------------------------------------------------------
17
18 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19 ; Now in 32-bit protected mode.
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21
22 .486
23 .model flat
24 .stack
25 .code
26 org 21000h
27
28 DEFAULT_HANDLER_SIZE EQU INT1 - INT0
29
30 JmpCommonIdtEntry macro
31 ; jmp commonIdtEntry - this must be hand coded to keep the assembler from
32 ; using a 8 bit reletive jump when the entries are
33 ; within 255 bytes of the common entry. This must
34 ; be done to maintain the consistency of the size
35 ; of entry points...
36 db 0e9h ; jmp 16 bit relative
37 dd commonIdtEntry - $ - 4 ; offset to jump to
38 endm
39
40
41 Start:
42 mov ax,bx ; flat data descriptor in BX
43 mov ds,ax
44 mov es,ax
45 mov fs,ax
46 mov gs,ax
47 mov ss,ax
48 mov esp,0001ffff0h
49
50 call ClearScreen
51
52 ; Populate IDT with meaningful offsets for exception handlers...
53 sidt fword ptr [Idtr] ; get fword address of IDT
54
55 mov eax, offset Halt
56 mov ebx, eax ; use bx to copy 15..0 to descriptors
57 shr eax, 16 ; use ax to copy 31..16 to descriptors
58 mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
59 mov esi, [offset Idtr + 2]
60 mov edi, [esi]
61
62 @@: ; loop through all IDT entries exception handlers and initialize to default handler
63 mov word ptr [edi], bx ; write bits 15..0 of offset
64 mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
65 mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
66 mov word ptr [edi+6], ax ; write bits 31..16 of offset
67 add edi, 8 ; move up to next descriptor
68 add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
69 loop @b ; loop back through again until all descriptors are initialized
70
71 ;; at this point edi contains the offset of the descriptor for INT 20
72 ;; and bx contains the low 16 bits of the offset of the default handler
73 ;; so initialize all the rest of the descriptors with these two values...
74 ; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
75 ;@@: ; loop through all IDT entries exception handlers and initialize to default handler
76 ; mov word ptr [edi], bx ; write bits 15..0 of offset
77 ; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
78 ; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
79 ; mov word ptr [edi+6], ax ; write bits 31..16 of offset
80 ; add edi, 8 ; move up to next descriptor
81 ; loop @b ; loop back through again until all descriptors are initialized
82
83
84 ;; DUMP location of IDT and several of the descriptors
85 ; mov ecx, 8
86 ; mov eax, [offset Idtr + 2]
87 ; mov eax, [eax]
88 ; mov edi, 0b8000h
89 ; call PrintDword
90 ; mov esi, eax
91 ; mov edi, 0b80a0h
92 ; jmp OuterLoop
93
94 ;;
95 ;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
96 ; mov eax, 011111111h
97 ; mov ebx, 022222222h
98 ; mov ecx, 033333333h
99 ; mov edx, 044444444h
100 ; mov ebp, 055555555h
101 ; mov esi, 066666666h
102 ; mov edi, 077777777h
103 ; push 011111111h
104 ; push 022222222h
105 ; push 033333333h
106 ; int 119
107
108
109 mov esi,022000h ; esi = 22000
110 mov eax,[esi+014h] ; eax = [22014]
111 add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
112 mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
113 add ebp,esi
114 mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
115 mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
116 add eax,edi ; eax = ImageBase + EntryPoint
117 mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
118
119 mov bx,word ptr[ebp+6] ; bx = Number of sections
120 xor eax,eax
121 mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
122 add ebp,eax
123 add ebp,018h ; ebp = Start of 1st Section
124
125 SectionLoop:
126 push esi ; Save Base of EFILDR.C
127 push edi ; Save ImageBase
128 add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
129 add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
130 mov ecx,[ebp+010h] ; ecs = SizeOfRawData
131
132 cld
133 shr ecx,2
134 rep movsd
135
136 pop edi ; Restore ImageBase
137 pop esi ; Restore Base of EFILDR.C
138
139 add bp,028h ; ebp = ebp + 028h = Pointer to next section record
140 dec bx
141 cmp bx,0
142 jne SectionLoop
143
144 movzx eax, word ptr [Idtr] ; get size of IDT
145 inc eax
146 add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
147 push eax ; push memory map location on stack for call to EFILDR...
148
149 push eax ; push return address (useless, just for stack balance)
150 db 0b8h
151 EfiLdrOffset:
152 dd 000401000h ; Offset of EFILDR
153 ; mov eax, 401000h
154 push eax
155 ret
156
157 ; db "**** DEFAULT IDT ENTRY ***",0
158 align 02h
159 Halt:
160 INT0:
161 push 0h ; push error code place holder on the stack
162 push 0h
163 JmpCommonIdtEntry
164 ; db 0e9h ; jmp 16 bit reletive
165 ; dd commonIdtEntry - $ - 4 ; offset to jump to
166
167 INT1:
168 push 0h ; push error code place holder on the stack
169 push 1h
170 JmpCommonIdtEntry
171
172 INT2:
173 push 0h ; push error code place holder on the stack
174 push 2h
175 JmpCommonIdtEntry
176
177 INT3:
178 push 0h ; push error code place holder on the stack
179 push 3h
180 JmpCommonIdtEntry
181
182 INT4:
183 push 0h ; push error code place holder on the stack
184 push 4h
185 JmpCommonIdtEntry
186
187 INT5:
188 push 0h ; push error code place holder on the stack
189 push 5h
190 JmpCommonIdtEntry
191
192 INT6:
193 push 0h ; push error code place holder on the stack
194 push 6h
195 JmpCommonIdtEntry
196
197 INT7:
198 push 0h ; push error code place holder on the stack
199 push 7h
200 JmpCommonIdtEntry
201
202 INT8:
203 ; Double fault causes an error code to be pushed so no phony push necessary
204 nop
205 nop
206 push 8h
207 JmpCommonIdtEntry
208
209 INT9:
210 push 0h ; push error code place holder on the stack
211 push 9h
212 JmpCommonIdtEntry
213
214 INT10:
215 ; Invalid TSS causes an error code to be pushed so no phony push necessary
216 nop
217 nop
218 push 10
219 JmpCommonIdtEntry
220
221 INT11:
222 ; Segment Not Present causes an error code to be pushed so no phony push necessary
223 nop
224 nop
225 push 11
226 JmpCommonIdtEntry
227
228 INT12:
229 ; Stack fault causes an error code to be pushed so no phony push necessary
230 nop
231 nop
232 push 12
233 JmpCommonIdtEntry
234
235 INT13:
236 ; GP fault causes an error code to be pushed so no phony push necessary
237 nop
238 nop
239 push 13
240 JmpCommonIdtEntry
241
242 INT14:
243 ; Page fault causes an error code to be pushed so no phony push necessary
244 nop
245 nop
246 push 14
247 JmpCommonIdtEntry
248
249 INT15:
250 push 0h ; push error code place holder on the stack
251 push 15
252 JmpCommonIdtEntry
253
254 INT16:
255 push 0h ; push error code place holder on the stack
256 push 16
257 JmpCommonIdtEntry
258
259 INT17:
260 ; Alignment check causes an error code to be pushed so no phony push necessary
261 nop
262 nop
263 push 17
264 JmpCommonIdtEntry
265
266 INT18:
267 push 0h ; push error code place holder on the stack
268 push 18
269 JmpCommonIdtEntry
270
271 INT19:
272 push 0h ; push error code place holder on the stack
273 push 19
274 JmpCommonIdtEntry
275
276 INTUnknown:
277 REPEAT (78h - 20)
278 push 0h ; push error code place holder on the stack
279 ; push xxh ; push vector number
280 db 06ah
281 db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
282 JmpCommonIdtEntry
283 ENDM
284
285 commonIdtEntry:
286 pushad
287 mov ebp, esp
288 ;;
289 ;; At this point the stack looks like this:
290 ;;
291 ;; eflags
292 ;; Calling CS
293 ;; Calling EIP
294 ;; Error code or 0
295 ;; Int num or 0ffh for unknown int num
296 ;; eax
297 ;; ecx
298 ;; edx
299 ;; ebx
300 ;; esp
301 ;; ebp
302 ;; esi
303 ;; edi <------- ESP, EBP
304 ;;
305
306 call ClearScreen
307 mov esi, offset String1
308 call PrintString
309 mov eax, [ebp + 32] ;; move Int number into EAX
310 cmp eax, 19
311 ja PrintDefaultString
312 PrintExceptionString:
313 shl eax, 2 ;; multiply by 4 to get offset from StringTable to actual string address
314 add eax, offset StringTable
315 mov esi, [eax]
316 jmp PrintTheString
317 PrintDefaultString:
318 mov esi, offset IntUnknownString
319 ; patch Int number
320 mov edx, eax
321 call A2C
322 mov [esi + 1], al
323 mov eax, edx
324 shr eax, 4
325 call A2C
326 mov [esi], al
327 PrintTheString:
328 call PrintString
329 mov esi, offset String2
330 call PrintString
331 mov eax, [ebp+44] ; CS
332 call PrintDword
333 mov al, ':'
334 mov byte ptr [edi], al
335 add edi, 2
336 mov eax, [ebp+40] ; EIP
337 call PrintDword
338 mov esi, offset String3
339 call PrintString
340
341 mov edi, 0b8140h
342
343 mov esi, offset StringEax ; eax
344 call PrintString
345 mov eax, [ebp+28]
346 call PrintDword
347
348 mov esi, offset StringEbx ; ebx
349 call PrintString
350 mov eax, [ebp+16]
351 call PrintDword
352
353 mov esi, offset StringEcx ; ecx
354 call PrintString
355 mov eax, [ebp+24]
356 call PrintDword
357
358 mov esi, offset StringEdx ; edx
359 call PrintString
360 mov eax, [ebp+20]
361 call PrintDword
362
363 mov esi, offset StringEcode ; error code
364 call PrintString
365 mov eax, [ebp+36]
366 call PrintDword
367
368 mov edi, 0b81e0h
369
370 mov esi, offset StringEsp ; esp
371 call PrintString
372 mov eax, [ebp+12]
373 call PrintDword
374
375 mov esi, offset StringEbp ; ebp
376 call PrintString
377 mov eax, [ebp+8]
378 call PrintDword
379
380 mov esi, offset StringEsi ; esi
381 call PrintString
382 mov eax, [ebp+4]
383 call PrintDword
384
385 mov esi, offset StringEdi ; edi
386 call PrintString
387 mov eax, [ebp]
388 call PrintDword
389
390 mov esi, offset StringEflags ; eflags
391 call PrintString
392 mov eax, [ebp+48]
393 call PrintDword
394
395 mov edi, 0b8320h
396
397 mov esi, ebp
398 add esi, 52
399 mov ecx, 8
400
401
402 OuterLoop:
403 push ecx
404 mov ecx, 8
405 mov edx, edi
406
407 InnerLoop:
408 mov eax, [esi]
409 call PrintDword
410 add esi, 4
411 mov al, ' '
412 mov [edi], al
413 add edi, 2
414 loop InnerLoop
415
416 pop ecx
417 add edx, 0a0h
418 mov edi, edx
419 loop OuterLoop
420
421
422 mov edi, 0b8960h
423
424 mov eax, [ebp+40] ; EIP
425 sub eax, 32 * 4
426 mov esi, eax ; esi = eip - 32 DWORD linear (total 64 DWORD)
427
428 mov ecx, 8
429
430 OuterLoop1:
431 push ecx
432 mov ecx, 8
433 mov edx, edi
434
435 InnerLoop1:
436 mov eax, [esi]
437 call PrintDword
438 add esi, 4
439 mov al, ' '
440 mov [edi], al
441 add edi, 2
442 loop InnerLoop1
443
444 pop ecx
445 add edx, 0a0h
446 mov edi, edx
447 loop OuterLoop1
448
449
450
451 ; wbinvd ; Ken: this intruction does not support in early than 486 arch
452 @@:
453 jmp @b
454 ;
455 ; return
456 ;
457 mov esp, ebp
458 popad
459 add esp, 8 ; error code and INT number
460
461 iretd
462
463
464 PrintString:
465 push eax
466 @@:
467 mov al, byte ptr [esi]
468 cmp al, 0
469 je @f
470 mov byte ptr [edi], al
471 inc esi
472 add edi, 2
473 jmp @b
474 @@:
475 pop eax
476 ret
477
478 ;; EAX contains dword to print
479 ;; EDI contains memory location (screen location) to print it to
480 PrintDword:
481 push ecx
482 push ebx
483 push eax
484
485 mov ecx, 8
486 looptop:
487 rol eax, 4
488 mov bl, al
489 and bl, 0fh
490 add bl, '0'
491 cmp bl, '9'
492 jle @f
493 add bl, 7
494 @@:
495 mov byte ptr [edi], bl
496 add edi, 2
497 loop looptop
498 ;wbinvd
499
500 pop eax
501 pop ebx
502 pop ecx
503 ret
504
505 ClearScreen:
506 push eax
507 push ecx
508
509 mov al, ' '
510 mov ah, 0ch
511 mov edi, 0b8000h
512 mov ecx, 80 * 24
513 @@:
514 mov word ptr [edi], ax
515 add edi, 2
516 loop @b
517 mov edi, 0b8000h
518
519 pop ecx
520 pop eax
521
522 ret
523
524 A2C:
525 and al, 0fh
526 add al, '0'
527 cmp al, '9'
528 jle @f
529 add al, 7
530 @@:
531 ret
532
533 String1 db "*** INT ",0
534
535 Int0String db "00h Divide by 0 -",0
536 Int1String db "01h Debug exception -",0
537 Int2String db "02h NMI -",0
538 Int3String db "03h Breakpoint -",0
539 Int4String db "04h Overflow -",0
540 Int5String db "05h Bound -",0
541 Int6String db "06h Invalid opcode -",0
542 Int7String db "07h Device not available -",0
543 Int8String db "08h Double fault -",0
544 Int9String db "09h Coprocessor seg overrun (reserved) -",0
545 Int10String db "0Ah Invalid TSS -",0
546 Int11String db "0Bh Segment not present -",0
547 Int12String db "0Ch Stack fault -",0
548 Int13String db "0Dh General protection fault -",0
549 Int14String db "0Eh Page fault -",0
550 Int15String db "0Fh (Intel reserved) -",0
551 Int16String db "10h Floating point error -",0
552 Int17String db "11h Alignment check -",0
553 Int18String db "12h Machine check -",0
554 Int19String db "13h SIMD Floating-Point Exception -",0
555 IntUnknownString db "??h Unknown interrupt -",0
556
557 StringTable dd offset Int0String, offset Int1String, offset Int2String, offset Int3String,
558 offset Int4String, offset Int5String, offset Int6String, offset Int7String,
559 offset Int8String, offset Int9String, offset Int10String, offset Int11String,
560 offset Int12String, offset Int13String, offset Int14String, offset Int15String,
561 offset Int16String, offset Int17String, offset Int18String, offset Int19String
562
563 String2 db " HALT!! *** (",0
564 String3 db ")",0
565 StringEax db "EAX=",0
566 StringEbx db " EBX=",0
567 StringEcx db " ECX=",0
568 StringEdx db " EDX=",0
569 StringEcode db " ECODE=",0
570 StringEsp db "ESP=",0
571 StringEbp db " EBP=",0
572 StringEsi db " ESI=",0
573 StringEdi db " EDI=",0
574 StringEflags db " EFLAGS=",0
575
576 Idtr df 0
577
578 org 21ffeh
579 BlockSignature:
580 dw 0aa55h
581
582 end