327 lines
9.6 KiB
C++
327 lines
9.6 KiB
C++
#include "idt.h"
|
|
#include "../pit.h"
|
|
#include "../keyboard/keyboard.h"
|
|
|
|
IDT_entry idt_table[256];
|
|
IDT_ptr idt_ptr;
|
|
|
|
void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){
|
|
idt_table[num].offset_1 = base & 0xFFFF;
|
|
idt_table[num].selector = sel;
|
|
idt_table[num].zero = 0;
|
|
idt_table[num].type_attr = flags;
|
|
idt_table[num].offset_2 = (base >> 16) & 0xFFFF;
|
|
|
|
};
|
|
|
|
void irs_handler (registers regs) {
|
|
|
|
//printf("(IRS) Interrupt number: %d \r", regs.int_no);
|
|
switch (regs.int_no)
|
|
{
|
|
case 0:
|
|
// Divide Error #DE
|
|
printf("#DE\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 1:
|
|
// Debug Exception #DB
|
|
printf("#DB\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 2:
|
|
// NMI Interrupt
|
|
printf("#NMI\n");
|
|
break;
|
|
|
|
case 3:
|
|
// Breakpoint Exception #BP
|
|
printf("#BP\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 4:
|
|
// Overflow Exception #OF
|
|
printf("#OF\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 5:
|
|
// BOUND Range Exceeded Exception #BR
|
|
printf("#BR\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 6:
|
|
// Invalid OpCode Exception #UD
|
|
printf("#UD\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 7:
|
|
// Device Not Available Exception #NM
|
|
printf("#NM\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 8:
|
|
// Double Fault Exception #DF
|
|
printf("#DF\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 9:
|
|
// Coprocessor Segment Overrun
|
|
printf("Coprocessor Segment overrun!\n");
|
|
break;
|
|
|
|
case 10:
|
|
// Invalid TSS Exception #TS
|
|
printf("#TS\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 11:
|
|
// Segment Not Present #NP
|
|
printf("#NP\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 12:
|
|
// Stack Fault Exception #SS
|
|
printf("#SS\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 13:
|
|
// General Protection Exception #GP
|
|
printf("#GP\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 14:
|
|
// Page Fault Exception #PF
|
|
printf("#PF\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 16:
|
|
// x87 FPU Floating-point Error #MF
|
|
printf("#MF\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 17:
|
|
// Alignment Check Exception #AC
|
|
printf("#AC\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 18:
|
|
// Machine-Check Exception #MC
|
|
printf("#MC\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 19:
|
|
// SIMD Floating-point Exception #XM
|
|
printf("#XM\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 20:
|
|
// Virtualization Exception #VE
|
|
printf("#VE\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
case 21:
|
|
// Control Protection Exception #CP
|
|
printf("#CP\n");
|
|
printf("EIP: 0x%x\n", regs.eip);
|
|
printf("EAX: 0x%x\n", regs.eax);
|
|
printf("EBP: 0x%x\n", regs.ebp);
|
|
break;
|
|
|
|
default:
|
|
// PANIC!!!
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void irq_handler (registers regs) {
|
|
|
|
|
|
|
|
switch (regs.int_no) {
|
|
case 0:
|
|
pit_tick++;
|
|
break;
|
|
case 1:
|
|
// Keyboard interrupt !!
|
|
|
|
int scan;
|
|
int i;/*register*/
|
|
|
|
// Read scancode
|
|
scan = inb(0x60);
|
|
|
|
// Send ack message!
|
|
i = inb(0x61);
|
|
outb(0x61, i|0x80);
|
|
outb(0x61, i);
|
|
|
|
// NOTE: check for special scan codes
|
|
// e.g. modifiers etc..
|
|
if( scan < 0x37){
|
|
//printf("Read from IO: 0x%x\n", scan);
|
|
keyPress.ScanCode = scan ;
|
|
//printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode);
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
case 12:
|
|
// PS2 Mouse interrupt
|
|
printf("Mouse event triggered!");
|
|
//int event = inb(0x60);
|
|
break;
|
|
|
|
default:
|
|
printf("Interrupt happened!");
|
|
printf("Received INT: 0x%x\n", regs.int_no);
|
|
break;
|
|
}
|
|
|
|
outb(0x20, 0x20); // send end of interrupt to master
|
|
|
|
if ( regs.int_no > 8 && regs.int_no <= 15) {
|
|
outb(0xA0, 0x20); // send end of interrupt to slave
|
|
}
|
|
|
|
|
|
if( regs.int_no == 13){
|
|
printf(" Error code: %d \n", regs.err_code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void init_idt(){
|
|
// Initialise the IDT pointer
|
|
idt_ptr.length = sizeof(IDT_entry) * 255;
|
|
idt_ptr.base = (uint32_t)&idt_table;
|
|
|
|
#ifdef __VERBOSE__
|
|
printf("Init IDT\n");
|
|
#endif
|
|
|
|
// TODO: Set everything to zero first
|
|
|
|
set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F);
|
|
set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E);
|
|
set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E);
|
|
set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E);
|
|
set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E);
|
|
set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E);
|
|
set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E);
|
|
set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E);
|
|
set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E);
|
|
set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E);
|
|
set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E);
|
|
set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E);
|
|
set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E);
|
|
set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E);
|
|
set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E);
|
|
set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E);
|
|
set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E);
|
|
set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E);
|
|
set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E);
|
|
set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E);
|
|
set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E);
|
|
set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E);
|
|
set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E);
|
|
set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E);
|
|
set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E);
|
|
set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E);
|
|
set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E);
|
|
set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E);
|
|
set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E);
|
|
set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E);
|
|
set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E);
|
|
set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E);
|
|
|
|
|
|
//print_serial("Remapping PIC\n");
|
|
PIC_remap(0x20, 0x28);
|
|
|
|
// clear mask for IRQ 12
|
|
uint8_t value = inb(0x21) & ~(1<< 12);
|
|
outb(0x21, value);
|
|
|
|
|
|
|
|
// pic IRQ Table
|
|
set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
|
|
set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); // PS2 Keyboard
|
|
set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E);
|
|
set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
|
|
set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E);
|
|
set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E);
|
|
set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E);
|
|
set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E);
|
|
set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E);
|
|
set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
|
|
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
|
|
set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
|
|
set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); // PS2 Mouse
|
|
set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E);
|
|
set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
|
|
set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
|
|
|
|
|
|
idt_flush((uint32_t)&idt_ptr);
|
|
}
|