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