]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/BootSector/efi64.S
Use .p2align directive instead of ambiguous .align directive.
[mirror_edk2.git] / DuetPkg / BootSector / efi64.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 #* efi64.asm
13 #*
14 #* Abstract:
15 #*
16 #------------------------------------------------------------------------------
17
18 ##############################################################################
19 # Now in 64-bit long mode.
20 ##############################################################################
21
22 .486:
23 .stack:
24 .code:
25 .org 0x21000
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
40 Start:
41
42 movl $0x001fffe8,%esp # make final stack aligned
43
44 # set OSFXSR and OSXMMEXCPT because some code will use XMM register
45 .byte 0xf
46 .byte 0x20
47 .byte 0xe0
48 # mov rax, cr4
49 btsl $9,%eax
50 btsl $0xa,%eax
51 .byte 0xf
52 .byte 0x22
53 .byte 0xe0
54 # mov cr4, rax
55
56 call ClearScreen
57
58 # Populate IDT with meaningful offsets for exception handlers...
59 sidt Idtr
60
61
62 movl Halt, %eax
63 movl %eax,%ebx # use bx to copy 15..0 to descriptors
64 shrl $16,%eax # use ax to copy 31..16 to descriptors
65 # 63..32 of descriptors is 0
66 movl $0x78,%ecx # 78h IDT entries to initialize with unique entry points (exceptions)
67 movl (Idtr + 2), %esi
68 movl (%esi),%edi
69
70 LOOP_1: # loop through all IDT entries exception handlers and initialize to default handler
71 movw %bx, (%edi) # write bits 15..0 of offset
72 movw $0x38, 2(%edi) # SYS_CODE_SEL64 from GDT
73 movw $(0x0e00 | 0x8000), 4(%edi) # type = 386 interrupt gate, present
74 movw %ax, 6(%edi) # write bits 31..16 of offset
75 movl $0, 8(%edi) # write bits 31..16 of offset
76 addl $16, %edi # move up to next descriptor
77 addw DEFAULT_HANDLER_SIZE, %bx # move to next entry point
78 loopl LOOP_1 # loop back through again until all descriptors are initialized
79
80 ## at this point edi contains the offset of the descriptor for INT 20
81 ## and bx contains the low 16 bits of the offset of the default handler
82 ## so initialize all the rest of the descriptors with these two values...
83 # mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
84 #@@: ; loop through all IDT entries exception handlers and initialize to default handler
85 # mov word ptr [edi], bx ; write bits 15..0 of offset
86 # mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
87 # mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
88 # mov word ptr [edi+6], ax ; write bits 31..16 of offset
89 # mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
90 # add edi, 16 ; move up to next descriptor
91 # loop @b ; loop back through again until all descriptors are initialized
92
93
94 ## DUMP location of IDT and several of the descriptors
95 # mov ecx, 8
96 # mov eax, [offset Idtr + 2]
97 # mov eax, [eax]
98 # mov edi, 0b8000h
99 # call PrintQword
100 # mov esi, eax
101 # mov edi, 0b80a0h
102 # jmp OuterLoop
103
104 ##
105 ## just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
106 # mov eax, 011111111h
107 # mov ebx, 022222222h
108 # mov ecx, 033333333h
109 # mov edx, 044444444h
110 # mov ebp, 055555555h
111 # mov esi, 066666666h
112 # mov edi, 077777777h
113 # push 011111111h
114 # push 022222222h
115 # push 033333333h
116 # int 119
117
118 movl $0x22000,%esi # esi = 22000
119 movl 0x14(%esi),%eax # eax = [22014]
120 addl %eax,%esi # esi = 22000 + [22014] = Base of EFILDR.C
121 movl 0x3c(%esi),%ebp # ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
122 addl %esi,%ebp
123 movl 0x30(%ebp),%edi # edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore)
124 movl 0x28(%ebp),%eax # eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
125 addl %edi,%eax # eax = ImageBase + EntryPoint
126 movl %ebx, EfiLdrOffset
127 movl %eax, (%ebx) # Modify far jump instruction for correct entry point
128
129 movw 6(%ebp), %bx # bx = Number of sections
130 xorl %eax,%eax
131 movw 0x14(%ebp), %ax # ax = Optional Header Size
132 addl %eax,%ebp
133 addl $0x18,%ebp # ebp = Start of 1st Section
134
135 SectionLoop:
136 pushl %esi # Save Base of EFILDR.C
137 pushl %edi # Save ImageBase
138 addl 0x14(%ebp),%esi # esi = Base of EFILDR.C + PointerToRawData
139 addl 0x0c(%ebp),%edi # edi = ImageBase + VirtualAddress
140 movl 0x10(%ebp),%ecx # ecs = SizeOfRawData
141
142 cld
143 shrl $2,%ecx
144 rep
145 movsl
146
147 popl %edi # Restore ImageBase
148 popl %esi # Restore Base of EFILDR.C
149
150 addw $0x28,%bp # ebp = ebp + 028h = Pointer to next section record
151 .byte 0x66
152 .byte 0xff
153 .byte 0xcb
154 # dec bx
155 cmpw $0,%bx
156 jne SectionLoop
157
158 movl (Idtr), %eax # get size of IDT
159 movzx (%edx), %eax
160 .byte 0xff
161 .byte 0xc0
162 # inc eax
163 addl 2(%edx), %eax # add to base of IDT to get location of memory map...
164 xorl %ecx,%ecx
165 movl %eax,%ecx # put argument to RCX
166
167 .byte 0x48
168 .byte 0xc7
169 .byte 0xc0
170 EfiLdrOffset:
171 .long 0x00401000 # Offset of EFILDR
172 # mov rax, 401000h
173 .byte 0x50
174 # push rax
175
176 # ret
177 .byte 0xc3
178
179 # db "**** DEFAULT IDT ENTRY ***",0
180 .p2align 1
181 Halt:
182 INT0:
183 pushl $0x0 # push error code place holder on the stack
184 pushl $0x0
185 jmpCommonIdtEntry
186 # db 0e9h ; jmp 16 bit reletive
187 # dd commonIdtEntry - $ - 4 ; offset to jump to
188
189 INT1:
190 pushl $0x0 # push error code place holder on the stack
191 pushl $0x1
192 jmpCommonIdtEntry
193
194 INT2:
195 pushl $0x0 # push error code place holder on the stack
196 pushl $0x2
197 jmpCommonIdtEntry
198
199 INT3:
200 pushl $0x0 # push error code place holder on the stack
201 pushl $0x3
202 jmpCommonIdtEntry
203
204 INT4:
205 pushl $0x0 # push error code place holder on the stack
206 pushl $0x4
207 jmpCommonIdtEntry
208
209 INT5:
210 pushl $0x0 # push error code place holder on the stack
211 pushl $0x5
212 jmpCommonIdtEntry
213
214 INT6:
215 pushl $0x0 # push error code place holder on the stack
216 pushl $0x6
217 jmpCommonIdtEntry
218
219 INT7:
220 pushl $0x0 # push error code place holder on the stack
221 pushl $0x7
222 jmpCommonIdtEntry
223
224 INT8:
225 # Double fault causes an error code to be pushed so no phony push necessary
226 nop
227 nop
228 pushl $0x8
229 jmpCommonIdtEntry
230
231 INT9:
232 pushl $0x0 # push error code place holder on the stack
233 pushl $0x9
234 jmpCommonIdtEntry
235
236 INT10:
237 # Invalid TSS causes an error code to be pushed so no phony push necessary
238 nop
239 nop
240 pushl $10
241 jmpCommonIdtEntry
242
243 INT11:
244 # Segment Not Present causes an error code to be pushed so no phony push necessary
245 nop
246 nop
247 pushl $11
248 jmpCommonIdtEntry
249
250 INT12:
251 # Stack fault causes an error code to be pushed so no phony push necessary
252 nop
253 nop
254 pushl $12
255 jmpCommonIdtEntry
256
257 INT13:
258 # GP fault causes an error code to be pushed so no phony push necessary
259 nop
260 nop
261 pushl $13
262 jmpCommonIdtEntry
263
264 INT14:
265 # Page fault causes an error code to be pushed so no phony push necessary
266 nop
267 nop
268 pushl $14
269 jmpCommonIdtEntry
270
271 INT15:
272 pushl $0x0 # push error code place holder on the stack
273 pushl $15
274 jmpCommonIdtEntry
275
276 INT16:
277 pushl $0x0 # push error code place holder on the stack
278 pushl $16
279 jmpCommonIdtEntry
280
281 INT17:
282 # Alignment check causes an error code to be pushed so no phony push necessary
283 nop
284 nop
285 pushl $17
286 jmpCommonIdtEntry
287
288 INT18:
289 pushl $0x0 # push error code place holder on the stack
290 pushl $18
291 jmpCommonIdtEntry
292
293 INT19:
294 pushl $0x0 # push error code place holder on the stack
295 pushl $19
296 jmpCommonIdtEntry
297
298 INTUnknown:
299 .rept (0x78 - 20)
300 pushl $0x0 # push error code place holder on the stack
301 # push xxh ; push vector number
302 .byte 0x6a
303 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
304 jmpCommonIdtEntry
305 .endr
306
307 commonIdtEntry:
308 pushl %eax
309 pushl %ecx
310 pushl %edx
311 pushl %ebx
312 pushl %esp
313 pushl %ebp
314 pushl %esi
315 pushl %edi
316 .byte 0x41
317 .byte 0x50
318 # push r8
319 .byte 0x41
320 .byte 0x51
321 # push r9
322 .byte 0x41
323 .byte 0x52
324 # push r10
325 .byte 0x41
326 .byte 0x53
327 # push r11
328 .byte 0x41
329 .byte 0x54
330 # push r12
331 .byte 0x41
332 .byte 0x55
333 # push r13
334 .byte 0x41
335 .byte 0x56
336 # push r14
337 .byte 0x41
338 .byte 0x57
339 # push r15
340 .byte 0x48
341 movl %esp,%ebp
342 # mov rbp, rsp
343
344 ##
345 ## At this point the stack looks like this:
346 ##
347 ## Calling SS
348 ## Calling RSP
349 ## rflags
350 ## Calling CS
351 ## Calling RIP
352 ## Error code or 0
353 ## Int num or 0ffh for unknown int num
354 ## rax
355 ## rcx
356 ## rdx
357 ## rbx
358 ## rsp
359 ## rbp
360 ## rsi
361 ## rdi
362 ## r8
363 ## r9
364 ## r10
365 ## r11
366 ## r12
367 ## r13
368 ## r14
369 ## r15 <------- RSP, RBP
370 ##
371
372 call ClearScreen
373 mov String1, %esi
374 call PrintString
375 .byte 0x48
376 movl 16*8(%ebp),%eax ## move Int number into RAX
377 .byte 0x48
378 cmpl $18,%eax
379 ja PrintDefaultString
380 PrintExceptionString:
381 shll $3,%eax ## multiply by 8 to get offset from StringTable to actual string address
382 addl StringTable, %eax
383 movl (%eax),%esi
384 jmp PrintTheString
385 PrintDefaultString:
386 movl IntUnknownString, %esi
387 # patch Int number
388 movl %eax,%edx
389 call A2C
390 movb %al,1(%esi)
391 movl %edx,%eax
392 shrl $4,%eax
393 call A2C
394 movb %al,(%esi)
395 PrintTheString:
396 call PrintString
397 movl String2, %esi
398 call PrintString
399 .byte 0x48
400 movl 19*8(%ebp),%eax # CS
401 call PrintQword
402 movb $':', %al
403 movb %al, (%edi)
404 addl $2,%edi
405 .byte 0x48
406 movl 18*8(%ebp),%eax # RIP
407 call PrintQword
408 movl String3, %esi
409 call PrintString
410
411 movl $0xb8140,%edi
412
413 movl StringRax, %esi
414 call PrintString
415 .byte 0x48
416 movl 15*8(%ebp),%eax
417 call PrintQword
418
419 movl StringRcx, %esi
420 call PrintString
421 .byte 0x48
422 movl 14*8(%ebp),%eax
423 call PrintQword
424
425 movl StringRdx, %esi
426 call PrintString
427 .byte 0x48
428 movl 13*8(%ebp),%eax
429 call PrintQword
430
431 movl $0xb81e0,%edi
432
433 movl StringRbx, %esi
434 call PrintString
435 .byte 0x48
436 movl 12*8(%ebp),%eax
437 call PrintQword
438
439 movl StringRsp, %esi
440 call PrintString
441 .byte 0x48
442 movl 21*8(%ebp),%eax
443 call PrintQword
444
445 movl StringRbp, %esi
446 call PrintString
447 .byte 0x48
448 movl 10*8(%ebp),%eax
449 call PrintQword
450
451 movl $0xb8280,%edi
452
453 movl StringRsi, %esi
454 call PrintString
455 .byte 0x48
456 movl 9*8(%ebp),%eax
457 call PrintQword
458
459 movl StringRdi, %esi
460 call PrintString
461 .byte 0x48
462 movl 8*8(%ebp),%eax
463 call PrintQword
464
465 movl StringEcode, %esi
466 call PrintString
467 .byte 0x48
468 movl 17*8(%ebp),%eax
469 call PrintQword
470
471 movl $0xb8320,%edi
472
473 movl StringR8, %esi
474 call PrintString
475 .byte 0x48
476 movl 7*8(%ebp),%eax
477 call PrintQword
478
479 movl StringR9, %esi
480 call PrintString
481 .byte 0x48
482 movl 6*8(%ebp),%eax
483 call PrintQword
484
485 movl StringR10, %esi
486 call PrintString
487 .byte 0x48
488 movl 5*8(%ebp),%eax
489 call PrintQword
490
491 movl $0xb83c0,%edi
492
493 movl StringR11, %esi
494 call PrintString
495 .byte 0x48
496 movl 4*8(%ebp),%eax
497 call PrintQword
498
499 movl StringR12, %esi
500 call PrintString
501 .byte 0x48
502 movl 3*8(%ebp),%eax
503 call PrintQword
504
505 movl StringR13, %esi
506 call PrintString
507 .byte 0x48
508 movl 2*8(%ebp),%eax
509 call PrintQword
510
511 movl $0xb8460,%edi
512
513 movl StringR14, %esi
514 call PrintString
515 .byte 0x48
516 movl 1*8(%ebp),%eax
517 call PrintQword
518
519 movl StringR15, %esi
520 call PrintString
521 .byte 0x48
522 movl 0*8(%ebp),%eax
523 call PrintQword
524
525 movl StringSs, %esi
526 call PrintString
527 .byte 0x48
528 movl 22*8(%ebp),%eax
529 call PrintQword
530
531 movl $0xb8500,%edi
532
533 movl StringRflags, %esi
534 call PrintString
535 .byte 0x48
536 movl 20*8(%ebp),%eax
537 call PrintQword
538
539 movl $0xb8640,%edi
540
541 movl %ebp,%esi
542 addl $23*8,%esi
543 movl $4,%ecx
544
545
546 OuterLoop:
547 pushl %ecx
548 movl $4,%ecx
549 .byte 0x48
550 movl %edi,%edx
551
552 InnerLoop:
553 .byte 0x48
554 movl (%esi),%eax
555 call PrintQword
556 addl $8,%esi
557 mov $0x00, %al
558 movb %al,(%edi)
559 addl $2,%edi
560 loop InnerLoop
561
562 popl %ecx
563 addl $0xa0,%edx
564 movl %edx,%edi
565 loop OuterLoop
566
567
568 movl $0xb8960,%edi
569
570 .byte 0x48
571 movl 18*8(%ebp),%eax # RIP
572 subl $8*8,%eax
573 .byte 0x48
574 movl %eax,%esi # esi = rip - 8 QWORD linear (total 16 QWORD)
575
576 movl $4,%ecx
577
578 OuterLoop1:
579 pushl %ecx
580 movl $4,%ecx
581 movl %edi,%edx
582
583 InnerLoop1:
584 .byte 0x48
585 movl (%esi),%eax
586 call PrintQword
587 addl $8,%esi
588 movb $0x00, %al
589 movb %al,(%edi)
590 addl $2,%edi
591 loop InnerLoop1
592
593 popl %ecx
594 addl $0xa0,%edx
595 movl %edx,%edi
596 loop OuterLoop1
597
598
599
600 #wbinvd
601 LN_C1:
602 jmp LN_C1
603
604 #
605 # return
606 #
607 movl %ebp,%esp
608 # mov rsp, rbp
609 .byte 0x41
610 .byte 0x5f
611 # pop r15
612 .byte 0x41
613 .byte 0x5e
614 # pop r14
615 .byte 0x41
616 .byte 0x5d
617 # pop r13
618 .byte 0x41
619 .byte 0x5c
620 # pop r12
621 .byte 0x41
622 .byte 0x5b
623 # pop r11
624 .byte 0x41
625 .byte 0x5a
626 # pop r10
627 .byte 0x41
628 .byte 0x59
629 # pop r9
630 .byte 0x41
631 .byte 0x58
632 # pop r8
633 popl %edi
634 popl %esi
635 popl %ebp
636 popl %eax # esp
637 popl %ebx
638 popl %edx
639 popl %ecx
640 popl %eax
641
642 .byte 0x48
643 .byte 0x83
644 .byte 0xc4
645 .byte 0x10
646 # add esp, 16 ; error code and INT number
647
648 .byte 0x48
649 .byte 0xcf
650 # iretq
651
652 PrintString:
653 pushl %eax
654 LN_C2:
655 movb (%esi), %al
656 cmpb $0,%al
657 je LN_C3
658 movb %al, (%edi)
659 .byte 0xff
660 .byte 0xc6
661 # inc esi
662 addl $2,%edi
663 jmp LN_C2
664 LN_C3:
665 popl %eax
666 ret
667
668 ## RAX contains qword to print
669 ## RDI contains memory location (screen location) to print it to
670 PrintQword:
671 pushl %ecx
672 pushl %ebx
673 pushl %eax
674
675 .byte 0x48
676 .byte 0xc7
677 .byte 0xc1
678 .long 16
679 # mov rcx, 16
680 looptop:
681 .byte 0x48
682 roll $4,%eax
683 movb %al,%bl
684 andb $0xf,%bl
685 addb $'0', %bl
686 cmpb $'9', %bl
687 jle @f
688 addb $7,%bl
689 @@:
690 movb %bl, (%edi)
691 addl $2,%edi
692 loop looptop
693 #wbinvd
694
695 popl %eax
696 popl %ebx
697 popl %ecx
698 ret
699
700 ClearScreen:
701 pushl %eax
702 pushl %ecx
703
704 movb $0x00, %al
705 movb $0xc,%ah
706 movl $0xb8000,%edi
707 movl $80*24,%ecx
708 LN_C4:
709 movw %ax, (%edi)
710 addl $2,%edi
711 loop LN_C4
712 movl $0xb8000,%edi
713
714 popl %ecx
715 popl %eax
716
717 ret
718
719 A2C:
720 andb $0xf,%al
721 addb $'0', %al
722 cmpb $'9', %al
723 jle @f
724 addb $7,%al
725 LN_C5:
726 ret
727
728 String1: .asciz "*** INT "
729
730 Int0String: .asciz "00h Divide by 0 -"
731 Int1String: .asciz "01h Debug exception -"
732 Int2String: .asciz "02h NMI -"
733 Int3String: .asciz "03h Breakpoint -"
734 Int4String: .asciz "04h Overflow -"
735 Int5String: .asciz "05h Bound -"
736 Int6String: .asciz "06h Invalid opcode -"
737 Int7String: .asciz "07h Device not available -"
738 Int8String: .asciz "08h Double fault -"
739 Int9String: .asciz "09h Coprocessor seg overrun (reserved) -"
740 Int10String: .asciz "0Ah Invalid TSS -"
741 Int11String: .asciz "0Bh Segment not present -"
742 Int12String: .asciz "0Ch Stack fault -"
743 Int13String: .asciz "0Dh General protection fault -"
744 Int14String: .asciz "0Eh Page fault -"
745 Int15String: .asciz "0Fh (Intel reserved) -"
746 Int16String: .asciz "10h Floating point error -"
747 Int17String: .asciz "11h Alignment check -"
748 Int18String: .asciz "12h Machine check -"
749 Int19String: .asciz "13h SIMD Floating-Point Exception -"
750 IntUnknownString: .asciz "??h Unknown interrupt -"
751
752 StringTable: .long Int0String, Int1String, Int2String, Int3String, \
753 Int4String, Int5String, Int6String, Int7String, \
754 Int8String, Int9String, Int10String, Int11String, \
755 Int12String, Int13String, Int14String, Int15String,\
756 Int16String, Int17String, Int18String, Int19String
757
758 String2: .asciz " HALT!! *** ("
759 String3: .asciz ")"
760 StringRax: .asciz "RAX="
761 StringRcx: .asciz " RCX="
762 StringRdx: .asciz " RDX="
763 StringRbx: .asciz "RBX="
764 StringRsp: .asciz " RSP="
765 StringRbp: .asciz " RBP="
766 StringRsi: .asciz "RSI="
767 StringRdi: .asciz " RDI="
768 StringEcode: .asciz " ECODE="
769 StringR8: .asciz "R8 ="
770 StringR9: .asciz " R9 ="
771 StringR10: .asciz " R10="
772 StringR11: .asciz "R11="
773 StringR12: .asciz " R12="
774 StringR13: .asciz " R13="
775 StringR14: .asciz "R14="
776 StringR15: .asciz " R15="
777 StringSs: .asciz " SS ="
778 StringRflags: .asciz "RFLAGS="
779
780 Idtr: .float 0
781 .float 0
782
783 .org 0x21ffe
784 BlockSignature:
785 .word 0xaa55
786