interrupt.h 2.8 KB

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