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