interrupt.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #pragma once
  2. #include <types/types.h>
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #define INTERRUPT_GATE_TYPE (0x8e)
  7. #define PIC_EOI (0x20)
  8. struct regs_32 {
  9. uint32_t edi;
  10. uint32_t esi;
  11. uint32_t ebp;
  12. uint32_t esp;
  13. uint32_t ebx;
  14. uint32_t edx;
  15. uint32_t ecx;
  16. uint32_t eax;
  17. };
  18. struct PACKED irq0_data {
  19. struct regs_32 s_regs;
  20. void* v_eip;
  21. uint32_t cs;
  22. uint32_t eflags;
  23. uint32_t esp;
  24. uint32_t ss;
  25. };
  26. // present: When set, the page fault was caused by a page-protection violation.
  27. // When not set, it was caused by a non-present page.
  28. // write: When set, the page fault was caused by a write access.
  29. // When not set, it was caused by a read access.
  30. // user: When set, the page fault was caused while CPL = 3.
  31. // This does not necessarily mean that the page fault was a privilege violation.
  32. // from https://wiki.osdev.org/Exceptions#Page_Fault
  33. struct page_fault_error_code {
  34. uint32_t present : 1;
  35. uint32_t write : 1;
  36. uint32_t user : 1;
  37. uint32_t reserved_write : 1;
  38. uint32_t instruction_fetch : 1;
  39. uint32_t protection_key : 1;
  40. uint32_t shadow_stack : 1;
  41. uint32_t software_guard_extensions : 1;
  42. };
  43. // external interrupt handler function
  44. // stub in assembly MUST be called irqN
  45. #define SET_UP_IRQ(N, SELECTOR) \
  46. ptr_t addr_irq##N = (ptr_t)irq##N; \
  47. SET_IDT_ENTRY(0x20 + (N), (addr_irq##N), (SELECTOR));
  48. #define SET_IDT_ENTRY_FN(N, FUNC_NAME, SELECTOR) \
  49. extern void FUNC_NAME(); \
  50. ptr_t addr_##FUNC_NAME = (ptr_t)FUNC_NAME; \
  51. SET_IDT_ENTRY((N), (addr_##FUNC_NAME), (SELECTOR));
  52. #define SET_IDT_ENTRY(N, ADDR, SELECTOR) \
  53. IDT[(N)].offset_low = (ADDR)&0x0000ffff; \
  54. IDT[(N)].selector = (SELECTOR); \
  55. IDT[(N)].zero = 0; \
  56. IDT[(N)].type_attr = INTERRUPT_GATE_TYPE; \
  57. IDT[(N)].offset_high = ((ADDR)&0xffff0000) >> 16
  58. struct IDT_entry {
  59. uint16_t offset_low;
  60. uint16_t selector;
  61. uint8_t zero;
  62. uint8_t type_attr;
  63. uint16_t offset_high;
  64. };
  65. #ifndef _INTERRUPT_C_
  66. extern struct IDT_entry IDT[256];
  67. #endif
  68. void init_idt(void);
  69. void init_pic(void);
  70. // idt_descriptor: uint16_t[3]
  71. // [0] bit 0 :15 => limit
  72. // [1] bit 16:47 => address
  73. extern void asm_load_idt(uint16_t idt_descriptor[3], int sti);
  74. void int13_handler(
  75. struct regs_32 s_regs,
  76. uint32_t error_code,
  77. ptr_t eip,
  78. uint16_t cs,
  79. uint32_t eflags);
  80. void int0(void);
  81. void int1(void);
  82. void int2(void);
  83. void int3(void);
  84. void int4(void);
  85. void int5(void);
  86. void int6(void);
  87. void int7(void);
  88. void int8(void);
  89. void int9(void);
  90. void int10(void);
  91. void int11(void);
  92. void int12(void);
  93. void int13(void);
  94. void int14(void);
  95. void irq0(void);
  96. void irq1(void);
  97. void irq2(void);
  98. void irq3(void);
  99. void irq4(void);
  100. void irq5(void);
  101. void irq6(void);
  102. void irq7(void);
  103. void irq8(void);
  104. void irq9(void);
  105. void irq10(void);
  106. void irq11(void);
  107. void irq12(void);
  108. void irq13(void);
  109. void irq14(void);
  110. void irq15(void);
  111. #ifdef __cplusplus
  112. }
  113. #endif