]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/CpuDxe/X64/CpuInterrupt.S
Fix the issue GCC DUET x64 cannot boot to front page but reset when timer interrupt...
[mirror_edk2.git] / DuetPkg / CpuDxe / X64 / CpuInterrupt.S
1 #------------------------------------------------------------------------------
2 #*
3 #* Copyright 2006 - 2010, 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 #* CpuInterrupt.S
13 #*
14 #* Abstract:
15 #*
16 #------------------------------------------------------------------------------
17
18 #PUBLIC SystemTimerHandler
19 #PUBLIC SystemExceptionHandler
20 #EXTERNDEF mExceptionCodeSize:DWORD
21
22 #EXTERN TimerHandler: NEAR
23 #EXTERN ExceptionHandler: NEAR
24 #EXTERN mTimerVector: DWORD
25
26 .data
27 ASM_GLOBAL ASM_PFX(mExceptionCodeSize)
28 ASM_PFX(mExceptionCodeSize): .long 9
29
30 .text
31 ASM_GLOBAL ASM_PFX(InitDescriptor)
32
33 ASM_PFX(InitDescriptor):
34 movq $GDT_BASE,%rax # EAX=PHYSICAL address of gdt
35 movq %rax, gdtr + 2 # Put address of gdt into the gdtr
36 lgdt gdtr
37 movq $0x18, %rax
38 movq %rax, %gs
39 movq %rax, %fs
40 movq $IDT_BASE,%rax # EAX=PHYSICAL address of idt
41 movq %rax, idtr + 2 # Put address of idt into the idtr
42 lidt idtr
43 ret
44
45 # VOID
46 # InstallInterruptHandler (
47 # UINTN Vector,
48 # VOID (*Handler)(VOID)
49 # )
50 ASM_GLOBAL ASM_PFX(InstallInterruptHandler)
51 ASM_PFX(InstallInterruptHandler):
52 # Vector:DWORD @ 4(%esp)
53 # Handler:DWORD @ 8(%esp)
54 push %rbx
55 pushfq # save eflags
56 cli # turn off interrupts
57 subq $0x10, %rsp # open some space on the stack
58 movq %rsp, %rbx
59
60 sidt (%rbx) # get fword address of IDT
61 movq 2(%rbx), %rbx # move offset of IDT into RBX
62 addq $0x10, %rsp # correct stack
63 movq %rcx, %rax # Get vector number
64 shlq $4, %rax # multiply by 16 to get offset
65 addq %rax, %rbx # add to IDT base to get entry
66 movq %rdx, %rax # load new address into IDT entry
67 movw %ax, (%rbx) # write bits 15..0 of offset
68 shrq $16, %rax # use ax to copy 31..16 to descriptors
69 movw %ax, 6(%rbx) # write bits 31..16 of offset
70 shrq $16, %rax # use eax to copy 63..32 to descriptors
71 movl %eax, 8(%rbx) # write bits 63..32 of offset
72 popfq # restore flags (possible enabling interrupts)
73 pop %rbx
74 ret
75
76 .macro JmpCommonIdtEntry
77 # jmp commonIdtEntry - this must be hand coded to keep the assembler from
78 # using a 8 bit reletive jump when the entries are
79 # within 255 bytes of the common entry. This must
80 # be done to maintain the consistency of the size
81 # of entry points...
82 .byte 0xe9 # jmp 16 bit reletive
83 .long commonIdtEntry - . - 4 # offset to jump to
84 .endm
85
86 .p2align 1
87 ASM_GLOBAL ASM_PFX(SystemExceptionHandler)
88 ASM_PFX(SystemExceptionHandler):
89 INT0:
90 push $0x0 # push error code place holder on the stack
91 push $0x0
92 JmpCommonIdtEntry
93 # db 0e9h # jmp 16 bit reletive
94 # dd commonIdtEntry - $ - 4 # offset to jump to
95
96 INT1:
97 push $0x0 # push error code place holder on the stack
98 push $0x1
99 JmpCommonIdtEntry
100
101 INT2:
102 push $0x0 # push error code place holder on the stack
103 push $0x2
104 JmpCommonIdtEntry
105
106 INT3:
107 push $0x0 # push error code place holder on the stack
108 push $0x3
109 JmpCommonIdtEntry
110
111 INT4:
112 push $0x0 # push error code place holder on the stack
113 push $0x4
114 JmpCommonIdtEntry
115
116 INT5:
117 push $0x0 # push error code place holder on the stack
118 push $0x5
119 JmpCommonIdtEntry
120
121 INT6:
122 push $0x0 # push error code place holder on the stack
123 push $0x6
124 JmpCommonIdtEntry
125
126 INT7:
127 push $0x0 # push error code place holder on the stack
128 push $0x7
129 JmpCommonIdtEntry
130
131 INT8:
132 # Double fault causes an error code to be pushed so no phony push necessary
133 nop
134 nop
135 push $0x8
136 JmpCommonIdtEntry
137
138 INT9:
139 push $0x0 # push error code place holder on the stack
140 push $0x9
141 JmpCommonIdtEntry
142
143 INT10:
144 # Invalid TSS causes an error code to be pushed so no phony push necessary
145 nop
146 nop
147 push $10
148 JmpCommonIdtEntry
149
150 INT11:
151 # Segment Not Present causes an error code to be pushed so no phony push necessary
152 nop
153 nop
154 push $11
155 JmpCommonIdtEntry
156
157 INT12:
158 # Stack fault causes an error code to be pushed so no phony push necessary
159 nop
160 nop
161 push $12
162 JmpCommonIdtEntry
163
164 INT13:
165 # GP fault causes an error code to be pushed so no phony push necessary
166 nop
167 nop
168 push $13
169 JmpCommonIdtEntry
170
171 INT14:
172 # Page fault causes an error code to be pushed so no phony push necessary
173 nop
174 nop
175 push $14
176 JmpCommonIdtEntry
177
178 INT15:
179 push $0x0 # push error code place holder on the stack
180 push $15
181 JmpCommonIdtEntry
182
183 INT16:
184 push $0x0 # push error code place holder on the stack
185 push $16
186 JmpCommonIdtEntry
187
188 INT17:
189 # Alignment check causes an error code to be pushed so no phony push necessary
190 nop
191 nop
192 push $17
193 JmpCommonIdtEntry
194
195 INT18:
196 push $0x0 # push error code place holder on the stack
197 push $18
198 JmpCommonIdtEntry
199
200 INT19:
201 push $0x0 # push error code place holder on the stack
202 push $19
203 JmpCommonIdtEntry
204
205 INTUnknown:
206 # The following segment repeats (32 - 20) times:
207 # macro .rept isn't used here because Apple GAS compiler doesn't support it.
208 # No. 1
209 push $0x0 # push error code place holder on the stack
210 # push xxh # push vector number
211 .byte 0x6a
212 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
213 JmpCommonIdtEntry
214 # No. 2
215 push $0x0 # push error code place holder on the stack
216 # push xxh # push vector number
217 .byte 0x6a
218 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
219 JmpCommonIdtEntry
220 # No. 3
221 push $0x0 # push error code place holder on the stack
222 # push xxh # push vector number
223 .byte 0x6a
224 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
225 JmpCommonIdtEntry
226 # No. 4
227 push $0x0 # push error code place holder on the stack
228 # push xxh # push vector number
229 .byte 0x6a
230 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
231 JmpCommonIdtEntry
232 # No. 5
233 push $0x0 # push error code place holder on the stack
234 # push xxh # push vector number
235 .byte 0x6a
236 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
237 JmpCommonIdtEntry
238 # No. 6
239 push $0x0 # push error code place holder on the stack
240 # push xxh # push vector number
241 .byte 0x6a
242 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
243 JmpCommonIdtEntry
244 # No. 7
245 push $0x0 # push error code place holder on the stack
246 # push xxh # push vector number
247 .byte 0x6a
248 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
249 JmpCommonIdtEntry
250 # No. 8
251 push $0x0 # push error code place holder on the stack
252 # push xxh # push vector number
253 .byte 0x6a
254 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
255 JmpCommonIdtEntry
256 # No. 9
257 push $0x0 # push error code place holder on the stack
258 # push xxh # push vector number
259 .byte 0x6a
260 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
261 JmpCommonIdtEntry
262 # No. 10
263 push $0x0 # push error code place holder on the stack
264 # push xxh # push vector number
265 .byte 0x6a
266 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
267 JmpCommonIdtEntry
268 # No. 11
269 push $0x0 # push error code place holder on the stack
270 # push xxh # push vector number
271 .byte 0x6a
272 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
273 JmpCommonIdtEntry
274 # No. 12
275 push $0x0 # push error code place holder on the stack
276 # push xxh # push vector number
277 .byte 0x6a
278 .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number
279 JmpCommonIdtEntry
280
281
282 ASM_GLOBAL ASM_PFX(SystemTimerHandler)
283 ASM_PFX(SystemTimerHandler):
284 push $0
285 push $ASM_PFX(mTimerVector)
286 JmpCommonIdtEntry
287
288 commonIdtEntry:
289 # +---------------------+
290 # + EFlags +
291 # +---------------------+
292 # + CS +
293 # +---------------------+
294 # + EIP +
295 # +---------------------+
296 # + Error Code +
297 # +---------------------+
298 # + Vector Number +
299 # +---------------------+
300 # + EBP +
301 # +---------------------+ <-- EBP
302
303 cli
304 push %rbp
305 movq %rsp,%rbp
306
307 #
308 # Since here the stack pointer is 16-byte aligned, so
309 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
310 # is 16-byte aligned
311 #
312
313 ## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax#
314 ## UINT64 R8, R9, R10, R11, R12, R13, R14, R15#
315 push %r15
316 push %r14
317 push %r13
318 push %r12
319 push %r11
320 push %r10
321 push %r9
322 push %r8
323 push %rax
324 push %rcx
325 push %rdx
326 push %rbx
327 push 6*8(%rbp)
328 push (%rbp)
329 push %rsi
330 push %rdi
331
332 ## UINT64 Gs, Fs, Es, Ds, Cs, Ss# insure high 16 bits of each is zero
333 movzx 7*8(%rbp), %rax
334 push %rax # for ss
335 movzx 4*8(%rbp), %rax
336 push %rax # for cs
337 movq %ds, %rax
338 push %rax
339 movq %es, %rax
340 push %rax
341 movq %fs, %rax
342 push %rax
343 movq %gs, %rax
344 push %rax
345
346 ## UINT64 Rip#
347 push 3*8(%rbp)
348
349 ## UINT64 Gdtr[2], Idtr[2]#
350 subq $16, %rsp
351 sidt (%rsp)
352 subq $16, %rsp
353 sgdt (%rsp)
354
355 ## UINT64 Ldtr, Tr#
356 xorq %rax, %rax
357 str %ax
358 push %rax
359 sldt %ax
360 push %rax
361
362 ## UINT64 RFlags#
363 push 5*8(%rbp)
364
365 ## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8#
366 movq %cr8, %rax
367 push %rax
368 movq %cr4, %rax
369 orq $0x208, %rax
370 movq %rax, %cr4
371 push %rax
372 movq %cr3, %rax
373 push %rax
374 movq %cr2, %rax
375 push %rax
376 xorq %rax, %rax
377 push %rax
378 movq %cr0, %rax
379 push %rax
380
381 ## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#
382 movq %dr7, %rax
383 push %rax
384
385 ## clear Dr7 while executing debugger itself
386 xorq %rax, %rax
387 movq %rax, %dr7
388
389 movq %dr6, %rax
390 push %rax
391
392 ## insure all status bits in dr6 are clear...
393 xorq %rax, %rax
394 movq %rax, %dr6
395
396 movq %dr3, %rax
397 push %rax
398 movq %dr2, %rax
399 push %rax
400 movq %dr1, %rax
401 push %rax
402 movq %dr0, %rax
403 push %rax
404
405
406 ## FX_SAVE_STATE_X64 FxSaveState#
407 subq $512, %rsp
408 movq %rsp, %rdi
409 fxsave (%rdi)
410
411 ## UINT64 ExceptionData#
412 push 2*8 (%rbp)
413
414 ## call into exception handler
415 ## Prepare parameter and call
416 movq 1*8(%rbp), %rcx
417 movq %rsp, %rdx
418 #
419 # Per X64 calling convention, allocate maximum parameter stack space
420 # and make sure RSP is 16-byte aligned
421 #
422 subq $(4*8+8), %rsp
423 cmpq $32, %rcx
424 jb CallException
425 call ASM_PFX(TimerHandler)
426 jmp ExceptionDone
427 CallException:
428 call ASM_PFX(ExceptionHandler)
429 ExceptionDone:
430 addq $(4*8+8), %rsp
431
432 cli
433 ## UINT64 ExceptionData#
434 addq $8, %rsp
435
436 ## FX_SAVE_STATE_X64 FxSaveState#
437 movq %rsp, %rsi
438 fxrstor (%esi)
439 addq $512, %rsp
440
441
442 ## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#
443 pop %rax
444 movq %rax, %dr0
445 pop %rax
446 movq %rax, %dr1
447 pop %rax
448 movq %rax, %dr2
449 pop %rax
450 movq %rax, %dr3
451 ## skip restore of dr6. We cleared dr6 during the context save.
452 addq $8, %rsp
453 pop %rax
454 movq %rax, %dr7
455
456 ## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8#
457 pop %rax
458 movq %rax, %cr0
459 addq $8, %rsp # not for Cr1
460 pop %rax
461 movq %rax, %cr2
462 pop %rax
463 movq %rax, %cr3
464 pop %rax
465 movq %rax, %cr4
466 pop %rax
467 mov %rax, %cr8
468
469 ## UINT64 RFlags#
470 pop 5*8(%rbp)
471
472 ## UINT64 Ldtr, Tr#
473 ## UINT64 Gdtr[2], Idtr[2]#
474 ## Best not let anyone mess with these particular registers...
475 addq $48, %rsp
476
477 ## UINT64 Rip#
478 pop 3*8(%rbp)
479
480 ## UINT64 Gs, Fs, Es, Ds, Cs, Ss#
481 pop %rax
482 # mov gs, rax # not for gs
483 pop %rax
484 # mov fs, rax # not for fs
485 # (X64 will not use fs and gs, so we do not restore it)
486 pop %rax
487 movq %rax, %es
488 pop %rax
489 movq %rax, %ds
490 pop 4*8(%rbp) # for cs
491 pop 7*8(%rbp) # for ss
492
493 ## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax#
494 ## UINT64 R8, R9, R10, R11, R12, R13, R14, R15#
495 pop %rdi
496 pop %rsi
497 addq $8, %rsp # not for rbp
498 pop 6*8(%rbp) # for rsp
499 pop %rbx
500 pop %rdx
501 pop %rcx
502 pop %rax
503 pop %r8
504 pop %r9
505 pop %r10
506 pop %r11
507 pop %r12
508 pop %r13
509 pop %r14
510 pop %r15
511
512 movq %rbp, %rsp
513 pop %rbp
514 addq $16, %rsp
515 iretq
516
517
518 ##############################################################################
519 # data
520 ##############################################################################
521
522 .data
523
524 gdtr: .short GDT_END - GDT_BASE - 1 # GDT limit
525 .quad 0 # (GDT base gets set above)
526 ##############################################################################
527 # global descriptor table (GDT)
528 ##############################################################################
529
530 .p2align 4 # make GDT 16-byte align
531
532 GDT_BASE:
533 # null descriptor
534 NULL_SEL = .-GDT_BASE # Selector [0x0]
535 .short 0 # limit 15:0
536 .short 0 # base 15:0
537 .byte 0 # base 23:16
538 .byte 0 # type
539 .byte 0 # limit 19:16, flags
540 .byte 0 # base 31:24
541
542 # linear data segment descriptor
543 LINEAR_SEL = .-GDT_BASE # Selector [0x8]
544 .short 0x0FFFF # limit 0xFFFFF
545 .short 0 # base 0
546 .byte 0
547 .byte 0x092 # present, ring 0, data, expand-up, writable
548 .byte 0x0CF # page-granular, 32-bit
549 .byte 0
550
551 # linear code segment descriptor
552 LINEAR_CODE_SEL = .-GDT_BASE # Selector [0x10]
553 .short 0x0FFFF # limit 0xFFFFF
554 .short 0 # base 0
555 .byte 0
556 .byte 0x09A # present, ring 0, code, expand-up, writable
557 .byte 0x0CF # page-granular, 32-bit
558 .byte 0
559
560 # system data segment descriptor
561 SYS_DATA_SEL = .-GDT_BASE # Selector [0x18]
562 .short 0x0FFFF # limit 0xFFFFF
563 .short 0 # base 0
564 .byte 0
565 .byte 0x092 # present, ring 0, data, expand-up, writable
566 .byte 0x0CF # page-granular, 32-bit
567 .byte 0
568
569 # system code segment descriptor
570 SYS_CODE_SEL = .-GDT_BASE # Selector [0x20]
571 .short 0x0FFFF # limit 0xFFFFF
572 .short 0 # base 0
573 .byte 0
574 .byte 0x09A # present, ring 0, code, expand-up, writable
575 .byte 0x0CF # page-granular, 32-bit
576 .byte 0
577
578 # spare segment descriptor
579 SPARE3_SEL = .-GDT_BASE # Selector [0x28]
580 .short 0
581 .short 0
582 .byte 0
583 .byte 0
584 .byte 0
585 .byte 0
586
587 # system data segment descriptor
588 SYS_DATA64_SEL = .-GDT_BASE # Selector [0x30]
589 .short 0x0FFFF # limit 0xFFFFF
590 .short 0 # base 0
591 .byte 0
592 .byte 0x092 # present, ring 0, data, expand-up, writable
593 .byte 0x0CF # page-granular, 32-bit
594 .byte 0
595
596 # system code segment descriptor
597 SYS_CODE64_SEL = .-GDT_BASE # Selector [0x38]
598 .short 0x0FFFF # limit 0xFFFFF
599 .short 0 # base 0
600 .byte 0
601 .byte 0x09A # present, ring 0, code, expand-up, writable
602 .byte 0x0AF # page-granular, 64-bit
603 .byte 0
604
605 # spare segment descriptor
606 SPARE4_SEL = .-GDT_BASE # Selector [0x40]
607 .short 0
608 .short 0
609 .byte 0
610 .byte 0
611 .byte 0
612 .byte 0
613
614 GDT_END:
615
616 idtr: .short IDT_END - IDT_BASE - 1 # IDT limit
617 .quad 0 # (IDT base gets set above)
618 ##############################################################################
619 # interrupt descriptor table (IDT)
620 #
621 # Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
622 # mappings. This implementation only uses the system timer and all other
623 # IRQs will remain masked. The descriptors for vectors 33+ are provided
624 # for convenience.
625 ##############################################################################
626
627 .p2align 3 # make IDT 8-byte align
628
629 IDT_BASE:
630 # divide by zero (INT 0)
631 DIV_ZERO_SEL = .-IDT_BASE
632 .short 0 # offset 15:0
633 .short SYS_CODE64_SEL # selector 15:0
634 .byte 0 # 0 for interrupt gate
635 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
636 .short 0 # offset 31:16
637 .long 0 # offset 63:32
638 .long 0 # for reserved
639
640 # debug exception (INT 1)
641 DEBUG_EXCEPT_SEL = .-IDT_BASE
642 .short 0 # offset 15:0
643 .short SYS_CODE64_SEL # selector 15:0
644 .byte 0 # 0 for interrupt gate
645 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
646 .short 0 # offset 31:16
647 .long 0 # offset 63:32
648 .long 0 # for reserved
649
650 # NMI (INT 2)
651 NMI_SEL = .-IDT_BASE
652 .short 0 # offset 15:0
653 .short SYS_CODE64_SEL # selector 15:0
654 .byte 0 # 0 for interrupt gate
655 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
656 .short 0 # offset 31:16
657 .long 0 # offset 63:32
658 .long 0 # for reserved
659
660 # soft breakpoint (INT 3)
661 BREAKPOINT_SEL = .-IDT_BASE
662 .short 0 # offset 15:0
663 .short SYS_CODE64_SEL # selector 15:0
664 .byte 0 # 0 for interrupt gate
665 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
666 .short 0 # offset 31:16
667 .long 0 # offset 63:32
668 .long 0 # for reserved
669
670 # overflow (INT 4)
671 OVERFLOW_SEL = .-IDT_BASE
672 .short 0 # offset 15:0
673 .short SYS_CODE64_SEL # selector 15:0
674 .byte 0 # 0 for interrupt gate
675 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
676 .short 0 # offset 31:16
677 .long 0 # offset 63:32
678 .long 0 # for reserved
679
680 # bounds check (INT 5)
681 BOUNDS_CHECK_SEL = .-IDT_BASE
682 .short 0 # offset 15:0
683 .short SYS_CODE64_SEL # selector 15:0
684 .byte 0 # 0 for interrupt gate
685 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
686 .short 0 # offset 31:16
687 .long 0 # offset 63:32
688 .long 0 # for reserved
689
690 # invalid opcode (INT 6)
691 INVALID_OPCODE_SEL = .-IDT_BASE
692 .short 0 # offset 15:0
693 .short SYS_CODE64_SEL # selector 15:0
694 .byte 0 # 0 for interrupt gate
695 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
696 .short 0 # offset 31:16
697 .long 0 # offset 63:32
698 .long 0 # for reserved
699
700 # device not available (INT 7)
701 DEV_NOT_AVAIL_SEL = .-IDT_BASE
702 .short 0 # offset 15:0
703 .short SYS_CODE64_SEL # selector 15:0
704 .byte 0 # 0 for interrupt gate
705 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
706 .short 0 # offset 31:16
707 .long 0 # offset 63:32
708 .long 0 # for reserved
709
710 # double fault (INT 8)
711 DOUBLE_FAULT_SEL = .-IDT_BASE
712 .short 0 # offset 15:0
713 .short SYS_CODE64_SEL # selector 15:0
714 .byte 0 # 0 for interrupt gate
715 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
716 .short 0 # offset 31:16
717 .long 0 # offset 63:32
718 .long 0 # for reserved
719
720 # Coprocessor segment overrun - reserved (INT 9)
721 RSVD_INTR_SEL1 = .-IDT_BASE
722 .short 0 # offset 15:0
723 .short SYS_CODE64_SEL # selector 15:0
724 .byte 0 # 0 for interrupt gate
725 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
726 .short 0 # offset 31:16
727 .long 0 # offset 63:32
728 .long 0 # for reserved
729
730 # invalid TSS (INT 0ah)
731 INVALID_TSS_SEL = .-IDT_BASE
732 .short 0 # offset 15:0
733 .short SYS_CODE64_SEL # selector 15:0
734 .byte 0 # 0 for interrupt gate
735 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
736 .short 0 # offset 31:16
737 .long 0 # offset 63:32
738 .long 0 # for reserved
739
740 # segment not present (INT 0bh)
741 SEG_NOT_PRESENT_SEL = .-IDT_BASE
742 .short 0 # offset 15:0
743 .short SYS_CODE64_SEL # selector 15:0
744 .byte 0 # 0 for interrupt gate
745 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
746 .short 0 # offset 31:16
747 .long 0 # offset 63:32
748 .long 0 # for reserved
749
750 # stack fault (INT 0ch)
751 STACK_FAULT_SEL = .-IDT_BASE
752 .short 0 # offset 15:0
753 .short SYS_CODE64_SEL # selector 15:0
754 .byte 0 # 0 for interrupt gate
755 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
756 .short 0 # offset 31:16
757 .long 0 # offset 63:32
758 .long 0 # for reserved
759
760 # general protection (INT 0dh)
761 GP_FAULT_SEL = .-IDT_BASE
762 .short 0 # offset 15:0
763 .short SYS_CODE64_SEL # selector 15:0
764 .byte 0 # 0 for interrupt gate
765 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
766 .short 0 # offset 31:16
767 .long 0 # offset 63:32
768 .long 0 # for reserved
769
770 # page fault (INT 0eh)
771 PAGE_FAULT_SEL = .-IDT_BASE
772 .short 0 # offset 15:0
773 .short SYS_CODE64_SEL # selector 15:0
774 .byte 0 # 0 for interrupt gate
775 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
776 .short 0 # offset 31:16
777 .long 0 # offset 63:32
778 .long 0 # for reserved
779
780 # Intel reserved - do not use (INT 0fh)
781 RSVD_INTR_SEL2 = .-IDT_BASE
782 .short 0 # offset 15:0
783 .short SYS_CODE64_SEL # selector 15:0
784 .byte 0 # 0 for interrupt gate
785 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
786 .short 0 # offset 31:16
787 .long 0 # offset 63:32
788 .long 0 # for reserved
789
790 # floating point error (INT 0x10)
791 FLT_POINT_ERR_SEL = .-IDT_BASE
792 .short 0 # offset 15:0
793 .short SYS_CODE64_SEL # selector 15:0
794 .byte 0 # 0 for interrupt gate
795 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
796 .short 0 # offset 31:16
797 .long 0 # offset 63:32
798 .long 0 # for reserved
799
800 # alignment check (INT 0x11)
801 ALIGNMENT_CHECK_SEL = .-IDT_BASE
802 .short 0 # offset 15:0
803 .short SYS_CODE64_SEL # selector 15:0
804 .byte 0 # 0 for interrupt gate
805 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
806 .short 0 # offset 31:16
807 .long 0 # offset 63:32
808 .long 0 # for reserved
809
810 # machine check (INT 0x12)
811 MACHINE_CHECK_SEL = .-IDT_BASE
812 .short 0 # offset 15:0
813 .short SYS_CODE64_SEL # selector 15:0
814 .byte 0 # 0 for interrupt gate
815 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
816 .short 0 # offset 31:16
817 .long 0 # offset 63:32
818 .long 0 # for reserved
819
820 # SIMD floating-point exception (INT 0x13)
821 SIMD_EXCEPTION_SEL = .-IDT_BASE
822 .short 0 # offset 15:0
823 .short SYS_CODE64_SEL # selector 15:0
824 .byte 0 # 0 for interrupt gate
825 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
826 .short 0 # offset 31:16
827 .long 0 # offset 63:32
828 .long 0 # for reserved
829
830 # The following segment repeats (32 - 20) times:
831 # macro .rept isn't used here because Apple GAS compiler doesn't support it.
832 # No. 1
833 .short 0 # offset 15:0
834 .short SYS_CODE_SEL # selector 15:0
835 .byte 0 # 0 for interrupt gate
836 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
837 .short 0 # offset 31:16
838 .long 0 # offset 63:32
839 .long 0 # for reserved
840 # No. 2
841 .short 0 # offset 15:0
842 .short SYS_CODE_SEL # selector 15:0
843 .byte 0 # 0 for interrupt gate
844 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
845 .short 0 # offset 31:16
846 .long 0 # offset 63:32
847 .long 0 # for reserved
848 # No. 3
849 .short 0 # offset 15:0
850 .short SYS_CODE_SEL # selector 15:0
851 .byte 0 # 0 for interrupt gate
852 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
853 .short 0 # offset 31:16
854 .long 0 # offset 63:32
855 .long 0 # for reserved
856 # No. 4
857 .short 0 # offset 15:0
858 .short SYS_CODE_SEL # selector 15:0
859 .byte 0 # 0 for interrupt gate
860 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
861 .short 0 # offset 31:16
862 .long 0 # offset 63:32
863 .long 0 # for reserved
864 # No. 5
865 .short 0 # offset 15:0
866 .short SYS_CODE_SEL # selector 15:0
867 .byte 0 # 0 for interrupt gate
868 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
869 .short 0 # offset 31:16
870 .long 0 # offset 63:32
871 .long 0 # for reserved
872 # No. 6
873 .short 0 # offset 15:0
874 .short SYS_CODE_SEL # selector 15:0
875 .byte 0 # 0 for interrupt gate
876 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
877 .short 0 # offset 31:16
878 .long 0 # offset 63:32
879 .long 0 # for reserved
880 # No. 7
881 .short 0 # offset 15:0
882 .short SYS_CODE_SEL # selector 15:0
883 .byte 0 # 0 for interrupt gate
884 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
885 .short 0 # offset 31:16
886 .long 0 # offset 63:32
887 .long 0 # for reserved
888 # No. 8
889 .short 0 # offset 15:0
890 .short SYS_CODE_SEL # selector 15:0
891 .byte 0 # 0 for interrupt gate
892 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
893 .short 0 # offset 31:16
894 .long 0 # offset 63:32
895 .long 0 # for reserved
896 # No. 9
897 .short 0 # offset 15:0
898 .short SYS_CODE_SEL # selector 15:0
899 .byte 0 # 0 for interrupt gate
900 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
901 .short 0 # offset 31:16
902 .long 0 # offset 63:32
903 .long 0 # for reserved
904 # No. 10
905 .short 0 # offset 15:0
906 .short SYS_CODE_SEL # selector 15:0
907 .byte 0 # 0 for interrupt gate
908 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
909 .short 0 # offset 31:16
910 .long 0 # offset 63:32
911 .long 0 # for reserved
912 # No. 11
913 .short 0 # offset 15:0
914 .short SYS_CODE_SEL # selector 15:0
915 .byte 0 # 0 for interrupt gate
916 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
917 .short 0 # offset 31:16
918 .long 0 # offset 63:32
919 .long 0 # for reserved
920 # No. 12
921 .short 0 # offset 15:0
922 .short SYS_CODE_SEL # selector 15:0
923 .byte 0 # 0 for interrupt gate
924 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
925 .short 0 # offset 31:16
926 .long 0 # offset 63:32
927 .long 0 # for reserved
928
929
930 # 72 unspecified descriptors
931 .fill 72 * 16, 1, 0
932
933 # IRQ 0 (System timer) - (INT 0x68)
934 IRQ0_SEL = .-IDT_BASE
935 .short 0 # offset 15:0
936 .short SYS_CODE64_SEL # selector 15:0
937 .byte 0 # 0 for interrupt gate
938 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
939 .short 0 # offset 31:16
940 .long 0 # offset 63:32
941 .long 0 # 0 for reserved
942
943 # IRQ 1 (8042 Keyboard controller) - (INT 0x69)
944 IRQ1_SEL = .-IDT_BASE
945 .short 0 # offset 15:0
946 .short SYS_CODE64_SEL # selector 15:0
947 .byte 0 # 0 for interrupt gate
948 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
949 .short 0 # offset 31:16
950 .long 0 # offset 63:32
951 .long 0 # for reserved
952
953 # Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
954 IRQ2_SEL = .-IDT_BASE
955 .short 0 # offset 15:0
956 .short SYS_CODE64_SEL # selector 15:0
957 .byte 0 # 0 for interrupt gate
958 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
959 .short 0 # offset 31:16
960 .long 0 # offset 63:32
961 .long 0 # for reserved
962
963 # IRQ 3 (COM 2) - (INT 6bh)
964 IRQ3_SEL = .-IDT_BASE
965 .short 0 # offset 15:0
966 .short SYS_CODE64_SEL # selector 15:0
967 .byte 0 # 0 for interrupt gate
968 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
969 .short 0 # offset 31:16
970 .long 0 # offset 63:32
971 .long 0 # for reserved
972
973 # IRQ 4 (COM 1) - (INT 6ch)
974 IRQ4_SEL = .-IDT_BASE
975 .short 0 # offset 15:0
976 .short SYS_CODE64_SEL # selector 15:0
977 .byte 0 # 0 for interrupt gate
978 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
979 .short 0 # offset 31:16
980 .long 0 # offset 63:32
981 .long 0 # for reserved
982
983 # IRQ 5 (LPT 2) - (INT 6dh)
984 IRQ5_SEL = .-IDT_BASE
985 .short 0 # offset 15:0
986 .short SYS_CODE64_SEL # selector 15:0
987 .byte 0 # 0 for interrupt gate
988 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
989 .short 0 # offset 31:16
990 .long 0 # offset 63:32
991 .long 0 # for reserved
992
993 # IRQ 6 (Floppy controller) - (INT 6eh)
994 IRQ6_SEL = .-IDT_BASE
995 .short 0 # offset 15:0
996 .short SYS_CODE64_SEL # selector 15:0
997 .byte 0 # 0 for interrupt gate
998 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
999 .short 0 # offset 31:16
1000 .long 0 # offset 63:32
1001 .long 0 # for reserved
1002
1003 # IRQ 7 (LPT 1) - (INT 6fh)
1004 IRQ7_SEL = .-IDT_BASE
1005 .short 0 # offset 15:0
1006 .short SYS_CODE64_SEL # selector 15:0
1007 .byte 0 # 0 for interrupt gate
1008 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1009 .short 0 # offset 31:16
1010 .long 0 # offset 63:32
1011 .long 0 # for reserved
1012
1013 # IRQ 8 (RTC Alarm) - (INT 0x70)
1014 IRQ8_SEL = .-IDT_BASE
1015 .short 0 # offset 15:0
1016 .short SYS_CODE64_SEL # selector 15:0
1017 .byte 0 # 0 for interrupt gate
1018 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1019 .short 0 # offset 31:16
1020 .long 0 # offset 63:32
1021 .long 0 # for reserved
1022
1023 # IRQ 9 - (INT 0x71)
1024 IRQ9_SEL = .-IDT_BASE
1025 .short 0 # offset 15:0
1026 .short SYS_CODE64_SEL # selector 15:0
1027 .byte 0 # 0 for interrupt gate
1028 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1029 .short 0 # offset 31:16
1030 .long 0 # offset 63:32
1031 .long 0 # for reserved
1032
1033 # IRQ 10 - (INT 0x72)
1034 IRQ10_SEL = .-IDT_BASE
1035 .short 0 # offset 15:0
1036 .short SYS_CODE64_SEL # selector 15:0
1037 .byte 0 # 0 for interrupt gate
1038 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1039 .short 0 # offset 31:16
1040 .long 0 # offset 63:32
1041 .long 0 # for reserved
1042
1043 # IRQ 11 - (INT 0x73)
1044 IRQ11_SEL = .-IDT_BASE
1045 .short 0 # offset 15:0
1046 .short SYS_CODE64_SEL # selector 15:0
1047 .byte 0 # 0 for interrupt gate
1048 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1049 .short 0 # offset 31:16
1050 .long 0 # offset 63:32
1051 .long 0 # for reserved
1052
1053 # IRQ 12 (PS/2 mouse) - (INT 0x74)
1054 IRQ12_SEL = .-IDT_BASE
1055 .short 0 # offset 15:0
1056 .short SYS_CODE64_SEL # selector 15:0
1057 .byte 0 # 0 for interrupt gate
1058 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1059 .short 0 # offset 31:16
1060 .long 0 # offset 63:32
1061 .long 0 # for reserved
1062
1063 # IRQ 13 (Floating point error) - (INT 0x75)
1064 IRQ13_SEL = .-IDT_BASE
1065 .short 0 # offset 15:0
1066 .short SYS_CODE64_SEL # selector 15:0
1067 .byte 0 # 0 for interrupt gate
1068 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1069 .short 0 # offset 31:16
1070 .long 0 # offset 63:32
1071 .long 0 # for reserved
1072
1073 # IRQ 14 (Secondary IDE) - (INT 0x76)
1074 IRQ14_SEL = .-IDT_BASE
1075 .short 0 # offset 15:0
1076 .short SYS_CODE64_SEL # selector 15:0
1077 .byte 0 # 0 for interrupt gate
1078 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1079 .short 0 # offset 31:16
1080 .long 0 # offset 63:32
1081 .long 0 # for reserved
1082
1083 # IRQ 15 (Primary IDE) - (INT 0x77)
1084 IRQ15_SEL = .-IDT_BASE
1085 .short 0 # offset 15:0
1086 .short SYS_CODE64_SEL # selector 15:0
1087 .byte 0 # 0 for interrupt gate
1088 .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present
1089 .short 0 # offset 31:16
1090 .long 0 # offset 63:32
1091 .long 0 # for reserved
1092
1093 .fill 16, 1, 0
1094
1095 IDT_END:
1096