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