started on isr/idt stuff
This commit is contained in:
58
kernel/idt.c
Normal file
58
kernel/idt.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <idt.h>
|
||||||
|
|
||||||
|
#define IDT_MAX_DESCRIPTORS 256
|
||||||
|
|
||||||
|
#define ATTR_KERN_32 0x8E // active(1), ring 0 (00), interrupt gate(0), 32 bit (1110)
|
||||||
|
|
||||||
|
#define SEGMENT_KERN 0x08
|
||||||
|
|
||||||
|
extern void load_idt(void);
|
||||||
|
extern void enable_int(void);
|
||||||
|
|
||||||
|
extern void isr0();
|
||||||
|
extern void isr1();
|
||||||
|
extern void isr8();
|
||||||
|
extern void isr13();
|
||||||
|
extern void isr14();
|
||||||
|
extern void isr32();
|
||||||
|
extern void isr33();
|
||||||
|
|
||||||
|
void* isr_stub_table[256] = {
|
||||||
|
[0] = isr0,
|
||||||
|
[1] = isr1,
|
||||||
|
[8] = isr8,
|
||||||
|
[13] = isr13,
|
||||||
|
[14] = isr14,
|
||||||
|
[32] = isr32,
|
||||||
|
[33] = isr33,
|
||||||
|
};
|
||||||
|
|
||||||
|
idt_entry idt[IDT_MAX_DESCRIPTORS];
|
||||||
|
idt_ptr idtr;
|
||||||
|
|
||||||
|
void set_idtr(uint8_t vector, void* isr, uint8_t attributes) {
|
||||||
|
idt_entry* desc = &idt[vector];
|
||||||
|
|
||||||
|
desc->isr_low = (uint32_t)isr & 0xFFFF;
|
||||||
|
desc->kernel_cs = SEGMENT_KERN;
|
||||||
|
desc->reserved = 0;
|
||||||
|
desc->attributes = attributes;
|
||||||
|
desc->isr_high = ((uint32_t)isr >> 16) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_idt() {
|
||||||
|
idtr.limit = (sizeof(idt_entry) * IDT_MAX_DESCRIPTORS) - 1;
|
||||||
|
idtr.base = (uint32_t)&idt;
|
||||||
|
|
||||||
|
for (int i = 0; i < IDT_MAX_DESCRIPTORS; i++) {
|
||||||
|
if (isr_stub_table[i] != 0) {
|
||||||
|
set_idtr(i, isr_stub_table[i], ATTR_KERN_32);
|
||||||
|
} else {
|
||||||
|
set_idtr(i, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load_idt();
|
||||||
|
enable_int();
|
||||||
|
}
|
||||||
19
kernel/idt.h
Normal file
19
kernel/idt.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef KIDT_H
|
||||||
|
#define KIDT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||||
|
uint16_t kernel_cs; // The GDT segment selector the CPU will load into CS
|
||||||
|
uint8_t reserved; // Set to 0
|
||||||
|
uint8_t attributes;// Type and attributes flags
|
||||||
|
uint16_t isr_high; // The higher 16 bits of the ISR's address
|
||||||
|
} idt_entry __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base;
|
||||||
|
} idt_ptr __attribute__((packed));
|
||||||
|
|
||||||
|
#endif
|
||||||
54
kernel/idt_stubs.s
Normal file
54
kernel/idt_stubs.s
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
.code32
|
||||||
|
|
||||||
|
.macro ISR_NOERRCODE num
|
||||||
|
.global isr\num
|
||||||
|
isr\num:
|
||||||
|
pushl $0
|
||||||
|
pushl $\num
|
||||||
|
jmp isr_common_stub
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ISR_ERRCODE num
|
||||||
|
.global isr\num
|
||||||
|
isr\num:
|
||||||
|
pushl $\num
|
||||||
|
jmp isr_common_stub
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.extern common_interrupt_handler
|
||||||
|
isr_common_stub:
|
||||||
|
pushal
|
||||||
|
|
||||||
|
pushl %esp
|
||||||
|
call common_interrupt_handler
|
||||||
|
addl $4, %esp
|
||||||
|
|
||||||
|
popal
|
||||||
|
addl $8, %esp
|
||||||
|
iret
|
||||||
|
|
||||||
|
.global master_eoi
|
||||||
|
master_eoi:
|
||||||
|
movb $0x20, %al
|
||||||
|
outb %al, $0x20
|
||||||
|
ret
|
||||||
|
|
||||||
|
.extern idtr
|
||||||
|
.global load_idt
|
||||||
|
load_idt:
|
||||||
|
lidt idtr
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global enable_int
|
||||||
|
enable_int:
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
|
||||||
|
ISR_NOERRCODE 0 # Divide by Zero
|
||||||
|
ISR_NOERRCODE 1 # Debug
|
||||||
|
ISR_ERRCODE 8 # Double Fault (Has Error Code!)
|
||||||
|
ISR_ERRCODE 13 # General Protection Fault (Has Error Code!)
|
||||||
|
ISR_ERRCODE 14 # Page Fault (Has Error Code!)
|
||||||
|
|
||||||
|
ISR_NOERRCODE 32 # IRQ0 - Timer
|
||||||
|
ISR_NOERRCODE 33 # IRQ1 - Keyboard
|
||||||
46
kernel/interrupts.c
Normal file
46
kernel/interrupts.c
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include "lib/print.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void master_eoi(void);
|
||||||
|
|
||||||
|
struct registers {
|
||||||
|
uint32_t edi, esi, ebp, esp_dummy, ebx, edx, ecx, eax;
|
||||||
|
|
||||||
|
uint32_t int_no;
|
||||||
|
uint32_t error_code;
|
||||||
|
|
||||||
|
uint32_t eip, cs, eflags, useresp, ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* err_messages[32] = {
|
||||||
|
[0] = "Divide by 0",
|
||||||
|
[1] = "",
|
||||||
|
[8] = "",
|
||||||
|
[13] = "General Protection Fault",
|
||||||
|
[14] = "Page Fault",
|
||||||
|
};
|
||||||
|
|
||||||
|
void common_interrupt_handler(struct registers *regs) {
|
||||||
|
switch (regs->int_no) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 8:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
kprint("CPU Error: ");
|
||||||
|
kprint(err_messages[regs->int_no]);
|
||||||
|
kprint("\n");
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
// wake the PIC timer driver
|
||||||
|
master_eoi();
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
// wake the keyboard driver
|
||||||
|
master_eoi();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
kprint("Received unhandled interrupt\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
|
|
||||||
|
#include <idt.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void init_idt();
|
||||||
|
extern idt_entry create_idt_entry(uint32_t addr, uint16_t segment, uint8_t attributes);
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
extern print_stream_t vga_print_stream;
|
extern print_stream_t vga_print_stream;
|
||||||
@@ -9,4 +16,6 @@ void kernel_main(void)
|
|||||||
kout->trunc();
|
kout->trunc();
|
||||||
|
|
||||||
kprint("RockOS booting...");
|
kprint("RockOS booting...");
|
||||||
|
|
||||||
|
init_idt();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user