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