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