1#------------------------------------------------------------------------------
2#*
3#*   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4#*   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        .org 0x21000
23
24.global _start
25_start:
26
27.equ                 DEFAULT_HANDLER_SIZE, INT1 - INT0
28
29.macro jmpCommonIdtEntry
30    # jmp     commonIdtEntry - this must be hand coded to keep the assembler from
31    #                          using a 8 bit reletive jump when the entries are
32    #                          within 255 bytes of the common entry.  This must
33    #                          be done to maintain the consistency of the size
34    #                          of entry points...
35    .byte   0xe9                        # jmp 16 bit relative
36    .long      commonIdtEntry - . - 4   # offset to jump to
37.endm
38
39Start:
40    movw    %bx, %ax
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
60LOOP_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
123SectionLoop:
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
150EfiLdrOffset:
151    .long   0x00401000                  # Offset of EFILDR
152# mov eax, 401000h
153    pushl   %eax
154    ret
155
156#    db      "**** DEFAULT IDT ENTRY ***",0
157    .p2align 1
158Halt:
159INT0:
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
166INT1:
167    pushl   $0x0    # push error code place holder on the stack
168    pushl   $0x1
169    jmpCommonIdtEntry
170
171INT2:
172    pushl   $0x0    # push error code place holder on the stack
173    pushl   $0x2
174    jmpCommonIdtEntry
175
176INT3:
177    pushl   $0x0    # push error code place holder on the stack
178    pushl   $0x3
179    jmpCommonIdtEntry
180
181INT4:
182    pushl   $0x0    # push error code place holder on the stack
183    pushl   $0x4
184    jmpCommonIdtEntry
185
186INT5:
187    pushl   $0x0    # push error code place holder on the stack
188    pushl   $0x5
189    jmpCommonIdtEntry
190
191INT6:
192    pushl   $0x0    # push error code place holder on the stack
193    pushl   $0x6
194    jmpCommonIdtEntry
195
196INT7:
197    pushl   $0x0    # push error code place holder on the stack
198    pushl   $0x7
199    jmpCommonIdtEntry
200
201INT8:
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
208INT9:
209    pushl   $0x0    # push error code place holder on the stack
210    pushl   $0x9
211    jmpCommonIdtEntry
212
213INT10:
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
220INT11:
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
227INT12:
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
234INT13:
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
241INT14:
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
248INT15:
249    pushl   $0x0    # push error code place holder on the stack
250    pushl   $15
251    jmpCommonIdtEntry
252
253INT16:
254    pushl   $0x0    # push error code place holder on the stack
255    pushl   $16
256    jmpCommonIdtEntry
257
258INT17:
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
265INT18:
266    pushl   $0x0    # push error code place holder on the stack
267    pushl   $18
268    jmpCommonIdtEntry
269
270INT19:
271    pushl   $0x0    # push error code place holder on the stack
272    pushl   $19
273    jmpCommonIdtEntry
274
275INTUnknown:
276# The following segment repeats (0x78 - 20) times:
277# No. 1
278    pushl   $0x0    # push error code place holder on the stack
279#   push    $0xxx   # push vector number
280    .byte   0x6a
281    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
282    jmpCommonIdtEntry
283# No. 2
284    pushl   $0x0    # push error code place holder on the stack
285#   push    $0xxx   # push vector number
286    .byte   0x6a
287    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
288    jmpCommonIdtEntry
289# No. 3
290    pushl   $0x0    # push error code place holder on the stack
291#   push    $0xxx   # push vector number
292    .byte   0x6a
293    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
294    jmpCommonIdtEntry
295# No. 4
296    pushl   $0x0    # push error code place holder on the stack
297#   push    $0xxx   # push vector number
298    .byte   0x6a
299    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
300    jmpCommonIdtEntry
301# No. 5
302    pushl   $0x0    # push error code place holder on the stack
303#   push    $0xxx   # push vector number
304    .byte   0x6a
305    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
306    jmpCommonIdtEntry
307# No. 6
308    pushl   $0x0    # push error code place holder on the stack
309#   push    $0xxx   # push vector number
310    .byte   0x6a
311    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
312    jmpCommonIdtEntry
313# No. 7
314    pushl   $0x0    # push error code place holder on the stack
315#   push    $0xxx   # push vector number
316    .byte   0x6a
317    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
318    jmpCommonIdtEntry
319# No. 8
320    pushl   $0x0    # push error code place holder on the stack
321#   push    $0xxx   # push vector number
322    .byte   0x6a
323    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
324    jmpCommonIdtEntry
325# No. 9
326    pushl   $0x0    # push error code place holder on the stack
327#   push    $0xxx   # push vector number
328    .byte   0x6a
329    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
330    jmpCommonIdtEntry
331# No. 10
332    pushl   $0x0    # push error code place holder on the stack
333#   push    $0xxx   # push vector number
334    .byte   0x6a
335    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
336    jmpCommonIdtEntry
337# No. 11
338    pushl   $0x0    # push error code place holder on the stack
339#   push    $0xxx   # push vector number
340    .byte   0x6a
341    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
342    jmpCommonIdtEntry
343# No. 12
344    pushl   $0x0    # push error code place holder on the stack
345#   push    $0xxx   # push vector number
346    .byte   0x6a
347    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
348    jmpCommonIdtEntry
349# No. 13
350    pushl   $0x0    # push error code place holder on the stack
351#   push    $0xxx   # push vector number
352    .byte   0x6a
353    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
354    jmpCommonIdtEntry
355# No. 14
356    pushl   $0x0    # push error code place holder on the stack
357#   push    $0xxx   # push vector number
358    .byte   0x6a
359    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
360    jmpCommonIdtEntry
361# No. 15
362    pushl   $0x0    # push error code place holder on the stack
363#   push    $0xxx   # push vector number
364    .byte   0x6a
365    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
366    jmpCommonIdtEntry
367# No. 16
368    pushl   $0x0    # push error code place holder on the stack
369#   push    $0xxx   # push vector number
370    .byte   0x6a
371    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
372    jmpCommonIdtEntry
373# No. 17
374    pushl   $0x0    # push error code place holder on the stack
375#   push    $0xxx   # push vector number
376    .byte   0x6a
377    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
378    jmpCommonIdtEntry
379# No. 18
380    pushl   $0x0    # push error code place holder on the stack
381#   push    $0xxx   # push vector number
382    .byte   0x6a
383    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
384    jmpCommonIdtEntry
385# No. 19
386    pushl   $0x0    # push error code place holder on the stack
387#   push    $0xxx   # push vector number
388    .byte   0x6a
389    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
390    jmpCommonIdtEntry
391# No. 20
392    pushl   $0x0    # push error code place holder on the stack
393#   push    $0xxx   # push vector number
394    .byte   0x6a
395    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
396    jmpCommonIdtEntry
397# No. 21
398    pushl   $0x0    # push error code place holder on the stack
399#   push    $0xxx   # push vector number
400    .byte   0x6a
401    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
402    jmpCommonIdtEntry
403# No. 22
404    pushl   $0x0    # push error code place holder on the stack
405#   push    $0xxx   # push vector number
406    .byte   0x6a
407    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
408    jmpCommonIdtEntry
409# No. 23
410    pushl   $0x0    # push error code place holder on the stack
411#   push    $0xxx   # push vector number
412    .byte   0x6a
413    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
414    jmpCommonIdtEntry
415# No. 24
416    pushl   $0x0    # push error code place holder on the stack
417#   push    $0xxx   # push vector number
418    .byte   0x6a
419    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
420    jmpCommonIdtEntry
421# No. 25
422    pushl   $0x0    # push error code place holder on the stack
423#   push    $0xxx   # push vector number
424    .byte   0x6a
425    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
426    jmpCommonIdtEntry
427# No. 26
428    pushl   $0x0    # push error code place holder on the stack
429#   push    $0xxx   # push vector number
430    .byte   0x6a
431    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
432    jmpCommonIdtEntry
433# No. 27
434    pushl   $0x0    # push error code place holder on the stack
435#   push    $0xxx   # push vector number
436    .byte   0x6a
437    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
438    jmpCommonIdtEntry
439# No. 28
440    pushl   $0x0    # push error code place holder on the stack
441#   push    $0xxx   # push vector number
442    .byte   0x6a
443    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
444    jmpCommonIdtEntry
445# No. 29
446    pushl   $0x0    # push error code place holder on the stack
447#   push    $0xxx   # push vector number
448    .byte   0x6a
449    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
450    jmpCommonIdtEntry
451# No. 30
452    pushl   $0x0    # push error code place holder on the stack
453#   push    $0xxx   # push vector number
454    .byte   0x6a
455    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
456    jmpCommonIdtEntry
457# No. 31
458    pushl   $0x0    # push error code place holder on the stack
459#   push    $0xxx   # push vector number
460    .byte   0x6a
461    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
462    jmpCommonIdtEntry
463# No. 32
464    pushl   $0x0    # push error code place holder on the stack
465#   push    $0xxx   # push vector number
466    .byte   0x6a
467    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
468    jmpCommonIdtEntry
469# No. 33
470    pushl   $0x0    # push error code place holder on the stack
471#   push    $0xxx   # push vector number
472    .byte   0x6a
473    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
474    jmpCommonIdtEntry
475# No. 34
476    pushl   $0x0    # push error code place holder on the stack
477#   push    $0xxx   # push vector number
478    .byte   0x6a
479    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
480    jmpCommonIdtEntry
481# No. 35
482    pushl   $0x0    # push error code place holder on the stack
483#   push    $0xxx   # push vector number
484    .byte   0x6a
485    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
486    jmpCommonIdtEntry
487# No. 36
488    pushl   $0x0    # push error code place holder on the stack
489#   push    $0xxx   # push vector number
490    .byte   0x6a
491    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
492    jmpCommonIdtEntry
493# No. 37
494    pushl   $0x0    # push error code place holder on the stack
495#   push    $0xxx   # push vector number
496    .byte   0x6a
497    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
498    jmpCommonIdtEntry
499# No. 38
500    pushl   $0x0    # push error code place holder on the stack
501#   push    $0xxx   # push vector number
502    .byte   0x6a
503    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
504    jmpCommonIdtEntry
505# No. 39
506    pushl   $0x0    # push error code place holder on the stack
507#   push    $0xxx   # push vector number
508    .byte   0x6a
509    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
510    jmpCommonIdtEntry
511# No. 40
512    pushl   $0x0    # push error code place holder on the stack
513#   push    $0xxx   # push vector number
514    .byte   0x6a
515    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
516    jmpCommonIdtEntry
517# No. 41
518    pushl   $0x0    # push error code place holder on the stack
519#   push    $0xxx   # push vector number
520    .byte   0x6a
521    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
522    jmpCommonIdtEntry
523# No. 42
524    pushl   $0x0    # push error code place holder on the stack
525#   push    $0xxx   # push vector number
526    .byte   0x6a
527    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
528    jmpCommonIdtEntry
529# No. 43
530    pushl   $0x0    # push error code place holder on the stack
531#   push    $0xxx   # push vector number
532    .byte   0x6a
533    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
534    jmpCommonIdtEntry
535# No. 44
536    pushl   $0x0    # push error code place holder on the stack
537#   push    $0xxx   # push vector number
538    .byte   0x6a
539    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
540    jmpCommonIdtEntry
541# No. 45
542    pushl   $0x0    # push error code place holder on the stack
543#   push    $0xxx   # push vector number
544    .byte   0x6a
545    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
546    jmpCommonIdtEntry
547# No. 46
548    pushl   $0x0    # push error code place holder on the stack
549#   push    $0xxx   # push vector number
550    .byte   0x6a
551    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
552    jmpCommonIdtEntry
553# No. 47
554    pushl   $0x0    # push error code place holder on the stack
555#   push    $0xxx   # push vector number
556    .byte   0x6a
557    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
558    jmpCommonIdtEntry
559# No. 48
560    pushl   $0x0    # push error code place holder on the stack
561#   push    $0xxx   # push vector number
562    .byte   0x6a
563    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
564    jmpCommonIdtEntry
565# No. 49
566    pushl   $0x0    # push error code place holder on the stack
567#   push    $0xxx   # push vector number
568    .byte   0x6a
569    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
570    jmpCommonIdtEntry
571# No. 50
572    pushl   $0x0    # push error code place holder on the stack
573#   push    $0xxx   # push vector number
574    .byte   0x6a
575    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
576    jmpCommonIdtEntry
577# No. 51
578    pushl   $0x0    # push error code place holder on the stack
579#   push    $0xxx   # push vector number
580    .byte   0x6a
581    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
582    jmpCommonIdtEntry
583# No. 52
584    pushl   $0x0    # push error code place holder on the stack
585#   push    $0xxx   # push vector number
586    .byte   0x6a
587    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
588    jmpCommonIdtEntry
589# No. 53
590    pushl   $0x0    # push error code place holder on the stack
591#   push    $0xxx   # push vector number
592    .byte   0x6a
593    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
594    jmpCommonIdtEntry
595# No. 54
596    pushl   $0x0    # push error code place holder on the stack
597#   push    $0xxx   # push vector number
598    .byte   0x6a
599    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
600    jmpCommonIdtEntry
601# No. 55
602    pushl   $0x0    # push error code place holder on the stack
603#   push    $0xxx   # push vector number
604    .byte   0x6a
605    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
606    jmpCommonIdtEntry
607# No. 56
608    pushl   $0x0    # push error code place holder on the stack
609#   push    $0xxx   # push vector number
610    .byte   0x6a
611    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
612    jmpCommonIdtEntry
613# No. 57
614    pushl   $0x0    # push error code place holder on the stack
615#   push    $0xxx   # push vector number
616    .byte   0x6a
617    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
618    jmpCommonIdtEntry
619# No. 58
620    pushl   $0x0    # push error code place holder on the stack
621#   push    $0xxx   # push vector number
622    .byte   0x6a
623    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
624    jmpCommonIdtEntry
625# No. 59
626    pushl   $0x0    # push error code place holder on the stack
627#   push    $0xxx   # push vector number
628    .byte   0x6a
629    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
630    jmpCommonIdtEntry
631# No. 60
632    pushl   $0x0    # push error code place holder on the stack
633#   push    $0xxx   # push vector number
634    .byte   0x6a
635    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
636    jmpCommonIdtEntry
637# No. 61
638    pushl   $0x0    # push error code place holder on the stack
639#   push    $0xxx   # push vector number
640    .byte   0x6a
641    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
642    jmpCommonIdtEntry
643# No. 62
644    pushl   $0x0    # push error code place holder on the stack
645#   push    $0xxx   # push vector number
646    .byte   0x6a
647    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
648    jmpCommonIdtEntry
649# No. 63
650    pushl   $0x0    # push error code place holder on the stack
651#   push    $0xxx   # push vector number
652    .byte   0x6a
653    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
654    jmpCommonIdtEntry
655# No. 64
656    pushl   $0x0    # push error code place holder on the stack
657#   push    $0xxx   # push vector number
658    .byte   0x6a
659    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
660    jmpCommonIdtEntry
661# No. 65
662    pushl   $0x0    # push error code place holder on the stack
663#   push    $0xxx   # push vector number
664    .byte   0x6a
665    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
666    jmpCommonIdtEntry
667# No. 66
668    pushl   $0x0    # push error code place holder on the stack
669#   push    $0xxx   # push vector number
670    .byte   0x6a
671    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
672    jmpCommonIdtEntry
673# No. 67
674    pushl   $0x0    # push error code place holder on the stack
675#   push    $0xxx   # push vector number
676    .byte   0x6a
677    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
678    jmpCommonIdtEntry
679# No. 68
680    pushl   $0x0    # push error code place holder on the stack
681#   push    $0xxx   # push vector number
682    .byte   0x6a
683    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
684    jmpCommonIdtEntry
685# No. 69
686    pushl   $0x0    # push error code place holder on the stack
687#   push    $0xxx   # push vector number
688    .byte   0x6a
689    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
690    jmpCommonIdtEntry
691# No. 70
692    pushl   $0x0    # push error code place holder on the stack
693#   push    $0xxx   # push vector number
694    .byte   0x6a
695    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
696    jmpCommonIdtEntry
697# No. 71
698    pushl   $0x0    # push error code place holder on the stack
699#   push    $0xxx   # push vector number
700    .byte   0x6a
701    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
702    jmpCommonIdtEntry
703# No. 72
704    pushl   $0x0    # push error code place holder on the stack
705#   push    $0xxx   # push vector number
706    .byte   0x6a
707    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
708    jmpCommonIdtEntry
709# No. 73
710    pushl   $0x0    # push error code place holder on the stack
711#   push    $0xxx   # push vector number
712    .byte   0x6a
713    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
714    jmpCommonIdtEntry
715# No. 74
716    pushl   $0x0    # push error code place holder on the stack
717#   push    $0xxx   # push vector number
718    .byte   0x6a
719    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
720    jmpCommonIdtEntry
721# No. 75
722    pushl   $0x0    # push error code place holder on the stack
723#   push    $0xxx   # push vector number
724    .byte   0x6a
725    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
726    jmpCommonIdtEntry
727# No. 76
728    pushl   $0x0    # push error code place holder on the stack
729#   push    $0xxx   # push vector number
730    .byte   0x6a
731    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
732    jmpCommonIdtEntry
733# No. 77
734    pushl   $0x0    # push error code place holder on the stack
735#   push    $0xxx   # push vector number
736    .byte   0x6a
737    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
738    jmpCommonIdtEntry
739# No. 78
740    pushl   $0x0    # push error code place holder on the stack
741#   push    $0xxx   # push vector number
742    .byte   0x6a
743    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
744    jmpCommonIdtEntry
745# No. 79
746    pushl   $0x0    # push error code place holder on the stack
747#   push    $0xxx   # push vector number
748    .byte   0x6a
749    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
750    jmpCommonIdtEntry
751# No. 80
752    pushl   $0x0    # push error code place holder on the stack
753#   push    $0xxx   # push vector number
754    .byte   0x6a
755    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
756    jmpCommonIdtEntry
757# No. 81
758    pushl   $0x0    # push error code place holder on the stack
759#   push    $0xxx   # push vector number
760    .byte   0x6a
761    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
762    jmpCommonIdtEntry
763# No. 82
764    pushl   $0x0    # push error code place holder on the stack
765#   push    $0xxx   # push vector number
766    .byte   0x6a
767    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
768    jmpCommonIdtEntry
769# No. 83
770    pushl   $0x0    # push error code place holder on the stack
771#   push    $0xxx   # push vector number
772    .byte   0x6a
773    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
774    jmpCommonIdtEntry
775# No. 84
776    pushl   $0x0    # push error code place holder on the stack
777#   push    $0xxx   # push vector number
778    .byte   0x6a
779    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
780    jmpCommonIdtEntry
781# No. 85
782    pushl   $0x0    # push error code place holder on the stack
783#   push    $0xxx   # push vector number
784    .byte   0x6a
785    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
786    jmpCommonIdtEntry
787# No. 86
788    pushl   $0x0    # push error code place holder on the stack
789#   push    $0xxx   # push vector number
790    .byte   0x6a
791    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
792    jmpCommonIdtEntry
793# No. 87
794    pushl   $0x0    # push error code place holder on the stack
795#   push    $0xxx   # push vector number
796    .byte   0x6a
797    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
798    jmpCommonIdtEntry
799# No. 88
800    pushl   $0x0    # push error code place holder on the stack
801#   push    $0xxx   # push vector number
802    .byte   0x6a
803    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
804    jmpCommonIdtEntry
805# No. 89
806    pushl   $0x0    # push error code place holder on the stack
807#   push    $0xxx   # push vector number
808    .byte   0x6a
809    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
810    jmpCommonIdtEntry
811# No. 90
812    pushl   $0x0    # push error code place holder on the stack
813#   push    $0xxx   # push vector number
814    .byte   0x6a
815    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
816    jmpCommonIdtEntry
817# No. 91
818    pushl   $0x0    # push error code place holder on the stack
819#   push    $0xxx   # push vector number
820    .byte   0x6a
821    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
822    jmpCommonIdtEntry
823# No. 92
824    pushl   $0x0    # push error code place holder on the stack
825#   push    $0xxx   # push vector number
826    .byte   0x6a
827    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
828    jmpCommonIdtEntry
829# No. 93
830    pushl   $0x0    # push error code place holder on the stack
831#   push    $0xxx   # push vector number
832    .byte   0x6a
833    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
834    jmpCommonIdtEntry
835# No. 94
836    pushl   $0x0    # push error code place holder on the stack
837#   push    $0xxx   # push vector number
838    .byte   0x6a
839    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
840    jmpCommonIdtEntry
841# No. 95
842    pushl   $0x0    # push error code place holder on the stack
843#   push    $0xxx   # push vector number
844    .byte   0x6a
845    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
846    jmpCommonIdtEntry
847# No. 96
848    pushl   $0x0    # push error code place holder on the stack
849#   push    $0xxx   # push vector number
850    .byte   0x6a
851    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
852    jmpCommonIdtEntry
853# No. 97
854    pushl   $0x0    # push error code place holder on the stack
855#   push    $0xxx   # push vector number
856    .byte   0x6a
857    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
858    jmpCommonIdtEntry
859# No. 98
860    pushl   $0x0    # push error code place holder on the stack
861#   push    $0xxx   # push vector number
862    .byte   0x6a
863    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
864    jmpCommonIdtEntry
865# No. 99
866    pushl   $0x0    # push error code place holder on the stack
867#   push    $0xxx   # push vector number
868    .byte   0x6a
869    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
870    jmpCommonIdtEntry
871# No. 100
872    pushl   $0x0    # push error code place holder on the stack
873#   push    $0xxx   # push vector number
874    .byte   0x6a
875    .long   ( . - INTUnknown - 3 ) / 9 + 20  # vector number
876    jmpCommonIdtEntry
877
878
879commonIdtEntry:
880    pushal
881    movl    %esp, %ebp
882##
883##  At this point the stack looks like this:
884##
885##      eflags
886##      Calling CS
887##      Calling EIP
888##      Error code or 0
889##      Int num or 0ffh for unknown int num
890##      eax
891##      ecx
892##      edx
893##      ebx
894##      esp
895##      ebp
896##      esi
897##      edi <------- ESP, EBP
898##
899
900    call    ClearScreen
901    movl    String1, %esi
902    call    PrintString
903    movl    32(%ebp), %eax      ## move Int number into EAX
904    cmpl    $19, %eax
905    ja      PrintDefaultString
906PrintExceptionString:
907    shll    $2, %eax            ## multiply by 4 to get offset from StringTable to actual string address
908    addl    StringTable, %eax
909    movl    (%eax), %esi
910    jmp     PrintTheString
911PrintDefaultString:
912    movl    IntUnknownString, %esi
913    # patch Int number
914    movl    %eax, %edx
915    call    A2C
916    movb    %al, 1(%esi)
917    movl    %edx, %eax
918    shrl    $4, %eax
919    call    A2C
920    movb    %al, (%esi)
921PrintTheString:
922    call    PrintString
923    movl    String2, %esi
924    call    PrintString
925    movl    44(%ebp), %eax         # CS
926    call    PrintDword
927    movb    ':', %al
928    movb    %al, (%edi)
929    addl    $2, %edi
930    movl    40(%ebp), %eax         # EIP
931    call    PrintDword
932    movl    String3, %esi
933    call    PrintString
934
935    movl    $0xb8140, %edi
936
937    movl    StringEax, %esi           # eax
938    call    PrintString
939    movl    28(%ebp), %eax
940    call    PrintDword
941
942    movl    StringEbx, %esi           # ebx
943    call    PrintString
944    movl    16(%ebp), %eax
945    call    PrintDword
946
947    movl    StringEcx, %esi           # ecx
948    call    PrintString
949    movl    24(%ebp), %eax
950    call    PrintDword
951
952    movl    StringEdx, %esi           # edx
953    call    PrintString
954    movl    20(%ebp), %eax
955    call    PrintDword
956
957    movl    StringEcode, %esi         # error code
958    call    PrintString
959    movl    36(%ebp), %eax
960    call    PrintDword
961
962    movl    $0xb81e0, %edi
963
964    movl    StringEsp, %esi           # esp
965    call    PrintString
966    movl    12(%ebp), %eax
967    call    PrintDword
968
969    movl    StringEbp, %esi           # ebp
970    call    PrintString
971    movl    8(%ebp), %eax
972    call    PrintDword
973
974    movl    StringEsi, %esi           # esi
975    call    PrintString
976    movl    4(%ebp), %eax
977    call    PrintDword
978
979    movl    StringEdi, %esi          # edi
980    call    PrintString
981    movl    (%ebp), %eax
982    call    PrintDword
983
984    movl    StringEflags, %esi       # eflags
985    call    PrintString
986    movl    48(%ebp), %eax
987    call    PrintDword
988
989    movl    $0xb8320, %edi
990
991    movl    %ebp, %esi
992    addl    $52, %esi
993    movl    $8, %ecx
994
995
996OuterLoop:
997    pushl   %ecx
998    movl    $8, %ecx
999    movl    %edi, %edx
1000
1001InnerLoop:
1002    movl    (%esi), %eax
1003    call    PrintDword
1004    addl    $4, %esi
1005    movb    ' ', %al
1006    movb    %al, (%edi)
1007    addl    $2, %edi
1008    loop    InnerLoop
1009
1010    popl    %ecx
1011    addl    $0xa0, %edx
1012    movl    %edx, %edi
1013    loop    OuterLoop
1014
1015
1016    movl    $0xb8960, %edi
1017
1018    movl    40(%ebp), %eax # EIP
1019    subl    $32*4, %eax
1020    movl    %eax, %esi      # esi = eip - 32 DWORD linear (total 64 DWORD)
1021
1022    movl    $8, %ecx
1023
1024OuterLoop1:
1025    pushl   %ecx
1026    movl    $8, %ecx
1027    movl    %edi, %edx
1028
1029InnerLoop1:
1030    movl    (%esi), %eax
1031    call    PrintDword
1032    addl    $4, %esi
1033    movb    ' ', %al
1034    movb    %al, (%edi)
1035    addl    $2, %edi
1036    loop    InnerLoop1
1037
1038    popl    %ecx
1039    addl    $0xa0, %edx
1040    movl    %edx, %edi
1041    loop    OuterLoop1
1042
1043
1044
1045#    wbinvd ; this intruction does not support in early than 486 arch
1046LN_C1:
1047    jmp     LN_C1
1048#
1049# return
1050#
1051    movl    %ebp, %esp
1052    popal
1053    addl    $8, %esp # error code and INT number
1054
1055    iretl
1056
1057
1058PrintString:
1059    pushl   %eax
1060LN_C2:
1061    movb    (%esi), %al
1062    cmpb    $0, %al
1063    je      LN_C3
1064    movb    %al, (%edi)
1065    incl    %esi
1066    addl    $2, %edi
1067    jmp     LN_C2
1068LN_C3:
1069    popl    %eax
1070    ret
1071
1072## EAX contains dword to print
1073## EDI contains memory location (screen location) to print it to
1074PrintDword:
1075    pushl   %ecx
1076    pushl   %ebx
1077    pushl   %eax
1078
1079    movl    $8, %ecx
1080looptop:
1081    roll    $4, %eax
1082    movb    %al, %bl
1083    andb    $0xf, %bl
1084    addb    '0', %bl
1085    cmpb    '9', %bl
1086    jle     LN_C4
1087    addb    $7, %bl
1088LN_C4:
1089    movb    %bl, (%edi)
1090    addl    $2, %edi
1091    loop    looptop
1092    #wbinvd
1093
1094    popl    %eax
1095    popl    %ebx
1096    popl    %ecx
1097    ret
1098
1099ClearScreen:
1100    pushl   %eax
1101    pushl   %ecx
1102
1103    movb    $0x00, %al
1104    movb    $0xc, %ah
1105    movl    $0xb8000, %edi
1106    movl    $80*24, %ecx
1107LN_C5:
1108    movw    %ax, (%edi)
1109    addl    $2, %edi
1110    loop    LN_C5
1111    movl    $0xb8000, %edi
1112
1113    popl    %ecx
1114    popl    %eax
1115
1116    ret
1117
1118A2C:
1119    andb    $0xf, %al
1120    addb    '0', %al
1121    cmpb    '9', %al
1122    jle     LN_C6
1123    addb    $7, %al
1124LN_C6:
1125    ret
1126
1127String1:            .asciz      "*** INT "
1128
1129Int0String:         .asciz      "00h Divide by 0 -"
1130Int1String:         .asciz      "01h Debug exception -"
1131Int2String:         .asciz      "02h NMI -"
1132Int3String:         .asciz      "03h Breakpoint -"
1133Int4String:         .asciz      "04h Overflow -"
1134Int5String:         .asciz      "05h Bound -"
1135Int6String:         .asciz      "06h Invalid opcode -"
1136Int7String:         .asciz      "07h Device not available -"
1137Int8String:         .asciz      "08h Double fault -"
1138Int9String:         .asciz      "09h Coprocessor seg overrun (reserved) -"
1139Int10String:        .asciz      "0Ah Invalid TSS -"
1140Int11String:        .asciz      "0Bh Segment not present -"
1141Int12String:        .asciz      "0Ch Stack fault -"
1142Int13String:        .asciz      "0Dh General protection fault -"
1143Int14String:        .asciz      "0Eh Page fault -"
1144Int15String:        .asciz      "0Fh (Intel reserved) -"
1145Int16String:        .asciz      "10h Floating point error -"
1146Int17String:        .asciz      "11h Alignment check -"
1147Int18String:        .asciz      "12h Machine check -"
1148Int19String:        .asciz      "13h SIMD Floating-Point Exception -"
1149IntUnknownString:   .asciz      "??h Unknown interrupt -"
1150
1151StringTable:   .long  Int0String, Int1String, Int2String, Int3String,    \
1152                      Int4String, Int5String, Int6String, Int7String,    \
1153                      Int8String, Int9String, Int10String, Int11String,  \
1154                      Int12String, Int13String, Int14String, Int15String,\
1155                      Int16String, Int17String, Int18String, Int19String
1156
1157String2:         .asciz  " HALT!! *** ("
1158String3:         .asciz  ")"
1159StringEax:       .asciz  "EAX="
1160StringEbx:       .asciz  "EBX="
1161StringEcx:       .asciz  "ECX="
1162StringEdx:       .asciz  "EDX="
1163StringEcode:     .asciz  "ECODE="
1164StringEsp:       .asciz  "ESP="
1165StringEbp:       .asciz  "EBP="
1166StringEsi:       .asciz  "ESI="
1167StringEdi:       .asciz  "EDI="
1168StringEflags:    .asciz  "EFLAGS="
1169
1170Idtr:        .float  0
1171
1172    .org 0x21ffe
1173BlockSignature:
1174    .word   0xaa55
1175
1176
1177