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