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