isr.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "isr.h"
  2. #include "idt.h"
  3. #include "../drivers/screen.h"
  4. #include "../drivers/keyboard.h"
  5. #include "../libc/string.h"
  6. #include "timer.h"
  7. #include "ports.h"
  8. isr_t interrupt_handlers[256];
  9. /* Can't do this with a loop because we need the address
  10. * of the function names */
  11. void isr_install() {
  12. set_idt_gate(0, (uint32_t)isr0);
  13. set_idt_gate(1, (uint32_t)isr1);
  14. set_idt_gate(2, (uint32_t)isr2);
  15. set_idt_gate(3, (uint32_t)isr3);
  16. set_idt_gate(4, (uint32_t)isr4);
  17. set_idt_gate(5, (uint32_t)isr5);
  18. set_idt_gate(6, (uint32_t)isr6);
  19. set_idt_gate(7, (uint32_t)isr7);
  20. set_idt_gate(8, (uint32_t)isr8);
  21. set_idt_gate(9, (uint32_t)isr9);
  22. set_idt_gate(10, (uint32_t)isr10);
  23. set_idt_gate(11, (uint32_t)isr11);
  24. set_idt_gate(12, (uint32_t)isr12);
  25. set_idt_gate(13, (uint32_t)isr13);
  26. set_idt_gate(14, (uint32_t)isr14);
  27. set_idt_gate(15, (uint32_t)isr15);
  28. set_idt_gate(16, (uint32_t)isr16);
  29. set_idt_gate(17, (uint32_t)isr17);
  30. set_idt_gate(18, (uint32_t)isr18);
  31. set_idt_gate(19, (uint32_t)isr19);
  32. set_idt_gate(20, (uint32_t)isr20);
  33. set_idt_gate(21, (uint32_t)isr21);
  34. set_idt_gate(22, (uint32_t)isr22);
  35. set_idt_gate(23, (uint32_t)isr23);
  36. set_idt_gate(24, (uint32_t)isr24);
  37. set_idt_gate(25, (uint32_t)isr25);
  38. set_idt_gate(26, (uint32_t)isr26);
  39. set_idt_gate(27, (uint32_t)isr27);
  40. set_idt_gate(28, (uint32_t)isr28);
  41. set_idt_gate(29, (uint32_t)isr29);
  42. set_idt_gate(30, (uint32_t)isr30);
  43. set_idt_gate(31, (uint32_t)isr31);
  44. // Remap the PIC
  45. port_byte_out(0x20, 0x11);
  46. port_byte_out(0xA0, 0x11);
  47. port_byte_out(0x21, 0x20);
  48. port_byte_out(0xA1, 0x28);
  49. port_byte_out(0x21, 0x04);
  50. port_byte_out(0xA1, 0x02);
  51. port_byte_out(0x21, 0x01);
  52. port_byte_out(0xA1, 0x01);
  53. port_byte_out(0x21, 0x0);
  54. port_byte_out(0xA1, 0x0);
  55. // Install the IRQs
  56. set_idt_gate(32, (uint32_t)irq0);
  57. set_idt_gate(33, (uint32_t)irq1);
  58. set_idt_gate(34, (uint32_t)irq2);
  59. set_idt_gate(35, (uint32_t)irq3);
  60. set_idt_gate(36, (uint32_t)irq4);
  61. set_idt_gate(37, (uint32_t)irq5);
  62. set_idt_gate(38, (uint32_t)irq6);
  63. set_idt_gate(39, (uint32_t)irq7);
  64. set_idt_gate(40, (uint32_t)irq8);
  65. set_idt_gate(41, (uint32_t)irq9);
  66. set_idt_gate(42, (uint32_t)irq10);
  67. set_idt_gate(43, (uint32_t)irq11);
  68. set_idt_gate(44, (uint32_t)irq12);
  69. set_idt_gate(45, (uint32_t)irq13);
  70. set_idt_gate(46, (uint32_t)irq14);
  71. set_idt_gate(47, (uint32_t)irq15);
  72. set_idt(); // Load with ASM
  73. }
  74. /* To print the message which defines every exception */
  75. char *exception_messages[] = {
  76. "Division By Zero",
  77. "Debug",
  78. "Non Maskable Interrupt",
  79. "Breakpoint",
  80. "Into Detected Overflow",
  81. "Out of Bounds",
  82. "Invalid Opcode",
  83. "No Coprocessor",
  84. "Double Fault",
  85. "Coprocessor Segment Overrun",
  86. "Bad TSS",
  87. "Segment Not Present",
  88. "Stack Fault",
  89. "General Protection Fault",
  90. "Page Fault",
  91. "Unknown Interrupt",
  92. "Coprocessor Fault",
  93. "Alignment Check",
  94. "Machine Check",
  95. "Reserved",
  96. "Reserved",
  97. "Reserved",
  98. "Reserved",
  99. "Reserved",
  100. "Reserved",
  101. "Reserved",
  102. "Reserved",
  103. "Reserved",
  104. "Reserved",
  105. "Reserved",
  106. "Reserved",
  107. "Reserved"
  108. };
  109. void isr_handler(registers_t *r) {
  110. kprint("received interrupt: ");
  111. char s[3];
  112. int_to_ascii(r->int_no, s);
  113. kprint(s);
  114. kprint("\n");
  115. kprint(exception_messages[r->int_no]);
  116. kprint("\n");
  117. }
  118. void register_interrupt_handler(uint8_t n, isr_t handler) {
  119. interrupt_handlers[n] = handler;
  120. }
  121. void irq_handler(registers_t *r) {
  122. /* After every interrupt we need to send an EOI to the PICs
  123. * or they will not send another interrupt again */
  124. if (r->int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */
  125. port_byte_out(0x20, 0x20); /* master */
  126. /* Handle the interrupt in a more modular way */
  127. if (interrupt_handlers[r->int_no] != 0) {
  128. isr_t handler = interrupt_handlers[r->int_no];
  129. handler(r);
  130. }
  131. }
  132. void irq_install() {
  133. /* Enable interruptions */
  134. asm volatile("sti");
  135. /* IRQ0: timer */
  136. init_timer(50);
  137. /* IRQ1: keyboard */
  138. init_keyboard();
  139. }