Add long mode IDT
This commit is contained in:
parent
5384ec3af0
commit
c6bca7f177
@ -34,7 +34,7 @@ cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, avx_f16c=0, avx_fma=0, bmi=0, xop=0, f
|
||||
cpuid: tbm=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0, smep=0, smap=0, mwait=1, vmx=1
|
||||
print_timestamps: enabled=0
|
||||
debugger_log: -
|
||||
magic_break: enabled=0
|
||||
magic_break: enabled=1
|
||||
port_e9_hack: enabled=0
|
||||
private_colormap: enabled=0
|
||||
clock: sync=none, time0=local, rtc_sync=0
|
||||
|
@ -37,7 +37,7 @@ static idt_register_t idt_reg;
|
||||
|
||||
void idt_set_gate(int n,uint32_t handler) {
|
||||
idt[n].low_offset=low_16(handler);
|
||||
idt[n].sel=KERNEL_CS;
|
||||
idt[n].sel=0x08;
|
||||
idt[n].always0=0;
|
||||
idt[n].flags=0xEE;
|
||||
idt[n].high_offset=high_16(handler);
|
||||
|
15
cpu/x86_64/cpu_init.c
Normal file
15
cpu/x86_64/cpu_init.c
Normal file
@ -0,0 +1,15 @@
|
||||
// #include "gdt.h"
|
||||
// #include "paging.h"
|
||||
#include "isr.h"
|
||||
#include <grub/multiboot.h>
|
||||
// #include "pmem.h"
|
||||
// #include "../tasking.h"
|
||||
|
||||
void cpu_init(multiboot_info_t* mbd) {
|
||||
// gdt_init();
|
||||
isr_install();
|
||||
asm volatile("sti");
|
||||
// pmem_init(mbd);
|
||||
// paging_init();
|
||||
// tasking_init();
|
||||
}
|
5
cpu/x86_64/halt.c
Normal file
5
cpu/x86_64/halt.c
Normal file
@ -0,0 +1,5 @@
|
||||
void halt() {
|
||||
asm volatile("cli;\
|
||||
hltlabel: hlt;\
|
||||
jmp hltlabel");
|
||||
}
|
55
cpu/x86_64/idt.c
Normal file
55
cpu/x86_64/idt.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include "idt.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Segment selectors */
|
||||
#define KERNEL_CS 0x08
|
||||
|
||||
/* How every interrupt gate (handler) is defined */
|
||||
typedef struct {
|
||||
uint16_t low_offset; /* Low 16 bits of handler function address */
|
||||
uint16_t sel; /* Kernel segment selector */
|
||||
uint8_t always0;
|
||||
/* First byte
|
||||
* Bit 7: "Interrupt is present"
|
||||
* Bits 6-5: Privilege level of caller (0=kernel..3=user)
|
||||
* Bit 4: Set to 0 for interrupt gates
|
||||
* Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */
|
||||
uint8_t flags;
|
||||
uint16_t middle_offset; /* Middle 16 bits of handler function address */
|
||||
uint32_t high_offset; /* High 32 bits of handler function address */
|
||||
uint32_t also0;
|
||||
} __attribute__((packed)) idt_gate_t ;
|
||||
|
||||
/* A pointer to the array of interrupt handlers.
|
||||
* Assembly instruction 'lidt' will read it */
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__((packed)) idt_register_t;
|
||||
|
||||
#define IDT_ENTRIES 256
|
||||
|
||||
static idt_gate_t idt[IDT_ENTRIES];
|
||||
static idt_register_t idt_reg;
|
||||
|
||||
#define low_16(address) (uint16_t)((address) & 0xFFFF)
|
||||
#define middle_16(address) (uint16_t)(((address) >> 16) & 0xFFFF)
|
||||
#define high_32(address) (uint32_t)(((address) >> 32) & 0xFFFFFFFF)
|
||||
|
||||
|
||||
void idt_set_gate(int n,uint64_t handler) {
|
||||
idt[n].low_offset=low_16(handler);
|
||||
idt[n].sel=KERNEL_CS;
|
||||
idt[n].always0=0;
|
||||
idt[n].flags=0xEE;
|
||||
idt[n].middle_offset=middle_16(handler);
|
||||
idt[n].high_offset=high_32(handler);
|
||||
idt[n].also0=0;
|
||||
}
|
||||
|
||||
void load_idt() {
|
||||
idt_reg.base=(uint64_t) &idt;
|
||||
idt_reg.limit=IDT_ENTRIES * sizeof(idt_gate_t) - 1;
|
||||
/* Don't make the mistake of loading &idt -- always load &idt_reg */
|
||||
asm volatile("lidtq (%0)":: "r" (&idt_reg));
|
||||
}
|
10
cpu/x86_64/idt.h
Normal file
10
cpu/x86_64/idt.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Functions implemented in idt.c */
|
||||
void idt_set_gate(int n,uint64_t handler);
|
||||
void load_idt();
|
||||
|
||||
#endif
|
469
cpu/x86_64/interrupt.asm
Normal file
469
cpu/x86_64/interrupt.asm
Normal file
@ -0,0 +1,469 @@
|
||||
; Defined in isr.c
|
||||
[extern isr_handler]
|
||||
[extern irq_handler]
|
||||
|
||||
; Common ISR code
|
||||
isr_common_stub:
|
||||
; 1. Save CPU state
|
||||
push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rbx
|
||||
push rsp
|
||||
push rbp
|
||||
push rsi
|
||||
push rdi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
; 2. Call C handler
|
||||
call isr_handler
|
||||
; 3. Restore state
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rbp
|
||||
pop rsp
|
||||
pop rbx
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
add esp, 16 ; Cleans up the pushed error code and pushed ISR number
|
||||
sti
|
||||
iretq ; pops 5 things at once: CS, EIP, RFLAGS, SS, and RSP
|
||||
|
||||
; Common IRQ code. Identical to ISR code except for the 'call'
|
||||
; and the 'pop ebx'
|
||||
irq_common_stub:
|
||||
; 1. Save CPU state
|
||||
push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rbx
|
||||
push rsp
|
||||
push rbp
|
||||
push rsi
|
||||
push rdi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
; 2. Call C handler
|
||||
call irq_handler
|
||||
; 3. Restore state
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rbp
|
||||
pop rsp
|
||||
pop rbx
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
add esp, 16 ; Cleans up the pushed error code and pushed ISR number
|
||||
sti
|
||||
iretq ; pops 5 things at once: CS, EIP, RFLAGS, SS, and RSP
|
||||
|
||||
; We don't get information about which interrupt was caller
|
||||
; when the handler is run, so we will need to have a different handler
|
||||
; for every interrupt.
|
||||
; Furthermore, some interrupts push an error code onto the stack but others
|
||||
; don't, so we will push a dummy error code for those which don't, so that
|
||||
; we have a consistent stack for all of them.
|
||||
|
||||
; First make the ISRs global
|
||||
global isr0
|
||||
global isr1
|
||||
global isr2
|
||||
global isr3
|
||||
global isr4
|
||||
global isr5
|
||||
global isr6
|
||||
global isr7
|
||||
global isr8
|
||||
global isr9
|
||||
global isr10
|
||||
global isr11
|
||||
global isr12
|
||||
global isr13
|
||||
global isr14
|
||||
global isr15
|
||||
global isr16
|
||||
global isr17
|
||||
global isr18
|
||||
global isr19
|
||||
global isr20
|
||||
global isr21
|
||||
global isr22
|
||||
global isr23
|
||||
global isr24
|
||||
global isr25
|
||||
global isr26
|
||||
global isr27
|
||||
global isr28
|
||||
global isr29
|
||||
global isr30
|
||||
global isr31
|
||||
global isr80
|
||||
; IRQs
|
||||
global irq0
|
||||
global irq1
|
||||
global irq2
|
||||
global irq3
|
||||
global irq4
|
||||
global irq5
|
||||
global irq6
|
||||
global irq7
|
||||
global irq8
|
||||
global irq9
|
||||
global irq10
|
||||
global irq11
|
||||
global irq12
|
||||
global irq13
|
||||
global irq14
|
||||
global irq15
|
||||
|
||||
; 0: Divide By Zero Exception
|
||||
isr0:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 0
|
||||
jmp isr_common_stub
|
||||
|
||||
; 1: Debug Exception
|
||||
isr1:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 1
|
||||
jmp isr_common_stub
|
||||
|
||||
; 2: Non Maskable Interrupt Exception
|
||||
isr2:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 2
|
||||
jmp isr_common_stub
|
||||
|
||||
; 3: Int 3 Exception
|
||||
isr3:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 3
|
||||
jmp isr_common_stub
|
||||
|
||||
; 4: INTO Exception
|
||||
isr4:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 4
|
||||
jmp isr_common_stub
|
||||
|
||||
; 5: Out of Bounds Exception
|
||||
isr5:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 5
|
||||
jmp isr_common_stub
|
||||
|
||||
; 6: Invalid Opcode Exception
|
||||
isr6:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 6
|
||||
jmp isr_common_stub
|
||||
|
||||
; 7: Coprocessor Not Available Exception
|
||||
isr7:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 7
|
||||
jmp isr_common_stub
|
||||
|
||||
; 8: Double Fault Exception (With Error Code!)
|
||||
isr8:
|
||||
cli
|
||||
push qword 8
|
||||
jmp isr_common_stub
|
||||
|
||||
; 9: Coprocessor Segment Overrun Exception
|
||||
isr9:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 9
|
||||
jmp isr_common_stub
|
||||
|
||||
; 10: Bad TSS Exception (With Error Code!)
|
||||
isr10:
|
||||
cli
|
||||
push qword 10
|
||||
jmp isr_common_stub
|
||||
|
||||
; 11: Segment Not Present Exception (With Error Code!)
|
||||
isr11:
|
||||
cli
|
||||
push qword 11
|
||||
jmp isr_common_stub
|
||||
|
||||
; 12: Stack Fault Exception (With Error Code!)
|
||||
isr12:
|
||||
cli
|
||||
push qword 12
|
||||
jmp isr_common_stub
|
||||
|
||||
; 13: General Protection Fault Exception (With Error Code!)
|
||||
isr13:
|
||||
cli
|
||||
push qword 13
|
||||
jmp isr_common_stub
|
||||
|
||||
; 14: Page Fault Exception (With Error Code!)
|
||||
isr14:
|
||||
cli
|
||||
push qword 14
|
||||
jmp isr_common_stub
|
||||
|
||||
; 15: Reserved Exception
|
||||
isr15:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 15
|
||||
jmp isr_common_stub
|
||||
|
||||
; 16: Floating Point Exception
|
||||
isr16:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 16
|
||||
jmp isr_common_stub
|
||||
|
||||
; 17: Alignment Check Exception
|
||||
isr17:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 17
|
||||
jmp isr_common_stub
|
||||
|
||||
; 18: Machine Check Exception
|
||||
isr18:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 18
|
||||
jmp isr_common_stub
|
||||
|
||||
; 19: Reserved
|
||||
isr19:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 19
|
||||
jmp isr_common_stub
|
||||
|
||||
; 20: Reserved
|
||||
isr20:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 20
|
||||
jmp isr_common_stub
|
||||
|
||||
; 21: Reserved
|
||||
isr21:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 21
|
||||
jmp isr_common_stub
|
||||
|
||||
; 22: Reserved
|
||||
isr22:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 22
|
||||
jmp isr_common_stub
|
||||
|
||||
; 23: Reserved
|
||||
isr23:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 23
|
||||
jmp isr_common_stub
|
||||
|
||||
; 24: Reserved
|
||||
isr24:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 24
|
||||
jmp isr_common_stub
|
||||
|
||||
; 25: Reserved
|
||||
isr25:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 25
|
||||
jmp isr_common_stub
|
||||
|
||||
; 26: Reserved
|
||||
isr26:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 26
|
||||
jmp isr_common_stub
|
||||
|
||||
; 27: Reserved
|
||||
isr27:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 27
|
||||
jmp isr_common_stub
|
||||
|
||||
; 28: Reserved
|
||||
isr28:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 28
|
||||
jmp isr_common_stub
|
||||
|
||||
; 29: Reserved
|
||||
isr29:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 29
|
||||
jmp isr_common_stub
|
||||
|
||||
; 30: Reserved
|
||||
isr30:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 30
|
||||
jmp isr_common_stub
|
||||
|
||||
; 31: Reserved
|
||||
isr31:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 31
|
||||
jmp isr_common_stub
|
||||
|
||||
; 80: Syscalls
|
||||
isr80:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 80
|
||||
jmp isr_common_stub
|
||||
|
||||
; IRQ handlers
|
||||
irq0:
|
||||
cli
|
||||
push qword 0
|
||||
push qword 32
|
||||
jmp irq_common_stub
|
||||
|
||||
irq1:
|
||||
cli
|
||||
push qword 1
|
||||
push qword 33
|
||||
jmp irq_common_stub
|
||||
|
||||
irq2:
|
||||
cli
|
||||
push qword 2
|
||||
push qword 34
|
||||
jmp irq_common_stub
|
||||
|
||||
irq3:
|
||||
cli
|
||||
push qword 3
|
||||
push qword 35
|
||||
jmp irq_common_stub
|
||||
|
||||
irq4:
|
||||
cli
|
||||
push qword 4
|
||||
push qword 36
|
||||
jmp irq_common_stub
|
||||
|
||||
irq5:
|
||||
cli
|
||||
push qword 5
|
||||
push qword 37
|
||||
jmp irq_common_stub
|
||||
|
||||
irq6:
|
||||
cli
|
||||
push qword 6
|
||||
push qword 38
|
||||
jmp irq_common_stub
|
||||
|
||||
irq7:
|
||||
cli
|
||||
push qword 7
|
||||
push qword 39
|
||||
jmp irq_common_stub
|
||||
|
||||
irq8:
|
||||
cli
|
||||
push qword 8
|
||||
push qword 40
|
||||
jmp irq_common_stub
|
||||
|
||||
irq9:
|
||||
cli
|
||||
push qword 9
|
||||
push qword 41
|
||||
jmp irq_common_stub
|
||||
|
||||
irq10:
|
||||
cli
|
||||
push qword 10
|
||||
push qword 42
|
||||
jmp irq_common_stub
|
||||
|
||||
irq11:
|
||||
cli
|
||||
push qword 11
|
||||
push qword 43
|
||||
jmp irq_common_stub
|
||||
|
||||
irq12:
|
||||
cli
|
||||
push qword 12
|
||||
push qword 44
|
||||
jmp irq_common_stub
|
||||
|
||||
irq13:
|
||||
cli
|
||||
push qword 13
|
||||
push qword 45
|
||||
jmp irq_common_stub
|
||||
|
||||
irq14:
|
||||
cli
|
||||
push qword 14
|
||||
push qword 46
|
||||
jmp irq_common_stub
|
||||
|
||||
irq15:
|
||||
cli
|
||||
push qword 15
|
||||
push qword 47
|
||||
jmp irq_common_stub
|
56
cpu/x86_64/interrupt.h
Normal file
56
cpu/x86_64/interrupt.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef INERRUPT_H
|
||||
#define INTERRUPT_H
|
||||
|
||||
/* ISRs reserved for CPU exceptions */
|
||||
void isr0();
|
||||
void isr1();
|
||||
void isr2();
|
||||
void isr3();
|
||||
void isr4();
|
||||
void isr5();
|
||||
void isr6();
|
||||
void isr7();
|
||||
void isr8();
|
||||
void isr9();
|
||||
void isr10();
|
||||
void isr11();
|
||||
void isr12();
|
||||
void isr13();
|
||||
void isr14();
|
||||
void isr15();
|
||||
void isr16();
|
||||
void isr17();
|
||||
void isr18();
|
||||
void isr19();
|
||||
void isr20();
|
||||
void isr21();
|
||||
void isr22();
|
||||
void isr23();
|
||||
void isr24();
|
||||
void isr25();
|
||||
void isr26();
|
||||
void isr27();
|
||||
void isr28();
|
||||
void isr29();
|
||||
void isr30();
|
||||
void isr31();
|
||||
void isr80();
|
||||
/* IRQ definitions */
|
||||
void irq0();
|
||||
void irq1();
|
||||
void irq2();
|
||||
void irq3();
|
||||
void irq4();
|
||||
void irq5();
|
||||
void irq6();
|
||||
void irq7();
|
||||
void irq8();
|
||||
void irq9();
|
||||
void irq10();
|
||||
void irq11();
|
||||
void irq12();
|
||||
void irq13();
|
||||
void irq14();
|
||||
void irq15();
|
||||
|
||||
#endif
|
203
cpu/x86_64/isr.c
Normal file
203
cpu/x86_64/isr.c
Normal file
@ -0,0 +1,203 @@
|
||||
#include "isr.h"
|
||||
#include "idt.h"
|
||||
#include "ports.h"
|
||||
// #include "paging.h"
|
||||
#include "../halt.h"
|
||||
#include "../../drivers/vga.h"
|
||||
// #include "../tasking.h"
|
||||
#include "interrupt.h"
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
void irq_handler(registers_t r);
|
||||
static isr_t interrupt_handlers[256];
|
||||
|
||||
/* Can't do this with a loop because we need the address
|
||||
* of the function names */
|
||||
void isr_install() {
|
||||
idt_set_gate(0,(uint64_t)isr0);
|
||||
idt_set_gate(1,(uint64_t)isr1);
|
||||
idt_set_gate(2,(uint64_t)isr2);
|
||||
idt_set_gate(3,(uint64_t)isr3);
|
||||
idt_set_gate(4,(uint64_t)isr4);
|
||||
idt_set_gate(5,(uint64_t)isr5);
|
||||
idt_set_gate(6,(uint64_t)isr6);
|
||||
idt_set_gate(7,(uint64_t)isr7);
|
||||
idt_set_gate(8,(uint64_t)isr8);
|
||||
idt_set_gate(9,(uint64_t)isr9);
|
||||
idt_set_gate(10,(uint64_t)isr10);
|
||||
idt_set_gate(11,(uint64_t)isr11);
|
||||
idt_set_gate(12,(uint64_t)isr12);
|
||||
idt_set_gate(13,(uint64_t)isr13);
|
||||
idt_set_gate(14,(uint64_t)isr14);
|
||||
idt_set_gate(15,(uint64_t)isr15);
|
||||
idt_set_gate(16,(uint64_t)isr16);
|
||||
idt_set_gate(17,(uint64_t)isr17);
|
||||
idt_set_gate(18,(uint64_t)isr18);
|
||||
idt_set_gate(19,(uint64_t)isr19);
|
||||
idt_set_gate(20,(uint64_t)isr20);
|
||||
idt_set_gate(21,(uint64_t)isr21);
|
||||
idt_set_gate(22,(uint64_t)isr22);
|
||||
idt_set_gate(23,(uint64_t)isr23);
|
||||
idt_set_gate(24,(uint64_t)isr24);
|
||||
idt_set_gate(25,(uint64_t)isr25);
|
||||
idt_set_gate(26,(uint64_t)isr26);
|
||||
idt_set_gate(27,(uint64_t)isr27);
|
||||
idt_set_gate(28,(uint64_t)isr28);
|
||||
idt_set_gate(29,(uint64_t)isr29);
|
||||
idt_set_gate(30,(uint64_t)isr30);
|
||||
idt_set_gate(31,(uint64_t)isr31);
|
||||
idt_set_gate(80,(uint64_t)isr80);
|
||||
// Remap the PIC
|
||||
port_byte_out(0x20,0x11);
|
||||
port_byte_out(0xA0,0x11);
|
||||
port_byte_out(0x21,0x20);
|
||||
port_byte_out(0xA1,0x28);
|
||||
port_byte_out(0x21,0x04);
|
||||
port_byte_out(0xA1,0x02);
|
||||
port_byte_out(0x21,0x01);
|
||||
port_byte_out(0xA1,0x01);
|
||||
port_byte_out(0x21,0x0);
|
||||
port_byte_out(0xA1,0x0);
|
||||
|
||||
// Install the IRQs
|
||||
idt_set_gate(32,(uint64_t)irq0);
|
||||
idt_set_gate(33,(uint64_t)irq1);
|
||||
idt_set_gate(34,(uint64_t)irq2);
|
||||
idt_set_gate(35,(uint64_t)irq3);
|
||||
idt_set_gate(36,(uint64_t)irq4);
|
||||
idt_set_gate(37,(uint64_t)irq5);
|
||||
idt_set_gate(38,(uint64_t)irq6);
|
||||
idt_set_gate(39,(uint64_t)irq7);
|
||||
idt_set_gate(40,(uint64_t)irq8);
|
||||
idt_set_gate(41,(uint64_t)irq9);
|
||||
idt_set_gate(42,(uint64_t)irq10);
|
||||
idt_set_gate(43,(uint64_t)irq11);
|
||||
idt_set_gate(44,(uint64_t)irq12);
|
||||
idt_set_gate(45,(uint64_t)irq13);
|
||||
idt_set_gate(46,(uint64_t)irq14);
|
||||
idt_set_gate(47,(uint64_t)irq15);
|
||||
|
||||
load_idt();
|
||||
}
|
||||
|
||||
|
||||
/* To print the message which defines every exception */
|
||||
static char *exception_messages[] = {
|
||||
"Division By Zero",
|
||||
"Debug",
|
||||
"Non Maskable Interrupt",
|
||||
"Breakpoint",
|
||||
"Into Detected Overflow",
|
||||
"Out of Bounds",
|
||||
"Invalid Opcode",
|
||||
"No Coprocessor",
|
||||
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Bad TSS",
|
||||
"Segment Not Present",
|
||||
"Stack Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"Unknown Interrupt",
|
||||
|
||||
"Coprocessor Fault",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved"
|
||||
};
|
||||
|
||||
void isr_handler(registers_t r) {
|
||||
switch (r.int_no) {
|
||||
case 14: {
|
||||
uint64_t addr;
|
||||
asm("movq %%cr2,%0": "=r"(addr));
|
||||
if (r.err_code==0) {
|
||||
vga_write_string("Kernel process tried to read a non-present page entry at address ");
|
||||
} else if (r.err_code==1) {
|
||||
vga_write_string("Kernel process tried to read a page and caused a protection fault at address ");
|
||||
} else if (r.err_code==2) {
|
||||
vga_write_string("Kernel process tried to write to a non-present page entry at address ");
|
||||
} else if (r.err_code==3) {
|
||||
vga_write_string("Kernel process tried to write a page and caused a protection fault at address ");
|
||||
} else if (r.err_code==4) {
|
||||
vga_write_string("User process tried to read a non-present page entry at address ");
|
||||
} else if (r.err_code==5) {
|
||||
vga_write_string("User process tried to read a page and caused a protection fault at address ");
|
||||
} else if (r.err_code==6) {
|
||||
vga_write_string("User process tried to write to a non-present page entry at address ");
|
||||
} else if (r.err_code==7) {
|
||||
vga_write_string("User process tried to write a page and caused a protection fault at address ");
|
||||
}
|
||||
char str[11];
|
||||
str[0]='\0';
|
||||
hex_to_ascii(addr,str);
|
||||
vga_write_string(str);
|
||||
vga_write_string("\n");
|
||||
// if ((r.err_code&1)==0) {
|
||||
// // int dir_entry=(addr&0xFFC00000)>>22;
|
||||
// // int table_entry=(addr&0x3FF000)>12;
|
||||
// // if (dir_entry_present(dir_entry)) {
|
||||
// // set_table_entry(dir_entry,table_entry,((dir_entry*1024)+table_entry)*0x1000,1,1,1);
|
||||
// // for(int page=0;page<1024;page++) {
|
||||
// // asm volatile("invlpg (%0)"::"r"(((dir_entry*1024)+page)*0x1000):"memory");
|
||||
// // }
|
||||
// // } else {
|
||||
// // for(int page=0;page<1024;page++) {
|
||||
// // set_table_entry(dir_entry,page,0x0,1,1,0);
|
||||
// // }
|
||||
// // set_table_entry(dir_entry,table_entry,((dir_entry*1024)+table_entry)*0x1000,1,1,1);
|
||||
// // set_directory_entry(dir_entry,dir_entry,1,1,1);
|
||||
// // }
|
||||
// // return;
|
||||
// }
|
||||
halt();
|
||||
break;
|
||||
case 80:
|
||||
// if (r.eax==1) {
|
||||
// tss_stack_reset();
|
||||
// tasking_yield();
|
||||
// } else if (r.eax==2) {
|
||||
// tasking_createTask((void*)r.ebx);
|
||||
// } else if (r.eax==3) {
|
||||
// r.ebx=(uint64_t)alloc_pages(r.ebx);
|
||||
// } else if (r.eax==4) {
|
||||
// alloc_pages_virt(r.ebx,(void*)r.ecx);
|
||||
// } else if (r.eax==5) {
|
||||
// r.ebx=(uint64_t)tasking_get_errno_address();
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
asm volatile("xchgw %bx, %bx");
|
||||
}
|
||||
|
||||
|
||||
void isr_register_handler(uint8_t n,isr_t handler) {
|
||||
interrupt_handlers[n] = handler;
|
||||
}
|
||||
|
||||
void irq_handler(registers_t r) {
|
||||
/* After every interrupt we need to send an EOI to the PICs
|
||||
* or they will not send another interrupt again */
|
||||
if (r.int_no >= 40) port_byte_out(0xA0,0x20); /* slave */
|
||||
port_byte_out(0x20,0x20); /* master */
|
||||
/* Handle the interrupt in a more modular way */
|
||||
if (interrupt_handlers[r.int_no] != 0) {
|
||||
isr_t handler = interrupt_handlers[r.int_no];
|
||||
handler(r);
|
||||
}
|
||||
}
|
90
cpu/x86_64/isr.h
Normal file
90
cpu/x86_64/isr.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef ISR_H
|
||||
#define ISR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ISRs reserved for CPU exceptions */
|
||||
extern void isr0();
|
||||
extern void isr1();
|
||||
extern void isr2();
|
||||
extern void isr3();
|
||||
extern void isr4();
|
||||
extern void isr5();
|
||||
extern void isr6();
|
||||
extern void isr7();
|
||||
extern void isr8();
|
||||
extern void isr9();
|
||||
extern void isr10();
|
||||
extern void isr11();
|
||||
extern void isr12();
|
||||
extern void isr13();
|
||||
extern void isr14();
|
||||
extern void isr15();
|
||||
extern void isr16();
|
||||
extern void isr17();
|
||||
extern void isr18();
|
||||
extern void isr19();
|
||||
extern void isr20();
|
||||
extern void isr21();
|
||||
extern void isr22();
|
||||
extern void isr23();
|
||||
extern void isr24();
|
||||
extern void isr25();
|
||||
extern void isr26();
|
||||
extern void isr27();
|
||||
extern void isr28();
|
||||
extern void isr29();
|
||||
extern void isr30();
|
||||
extern void isr31();
|
||||
extern void isr80();
|
||||
/* IRQ definitions */
|
||||
extern void irq0();
|
||||
extern void irq1();
|
||||
extern void irq2();
|
||||
extern void irq3();
|
||||
extern void irq4();
|
||||
extern void irq5();
|
||||
extern void irq6();
|
||||
extern void irq7();
|
||||
extern void irq8();
|
||||
extern void irq9();
|
||||
extern void irq10();
|
||||
extern void irq11();
|
||||
extern void irq12();
|
||||
extern void irq13();
|
||||
extern void irq14();
|
||||
extern void irq15();
|
||||
|
||||
/* Struct which aggregates many registers */
|
||||
typedef struct {
|
||||
uint64_t r15,r14,r13,r12,r11,r10,r9,r8,rdi,rsi,rbp,rsp,rbx,rdx,rcx,rax; /* Pushed by our code. */
|
||||
uint64_t int_no,err_code; /* Interrupt number and error code (if applicable) */
|
||||
uint64_t rip,cs,rflags,userrsp,ss; /* Pushed by the processor automatically */
|
||||
} registers_t;
|
||||
|
||||
#define IRQ0 32
|
||||
#define IRQ1 33
|
||||
#define IRQ2 34
|
||||
#define IRQ3 35
|
||||
#define IRQ4 36
|
||||
#define IRQ5 37
|
||||
#define IRQ6 38
|
||||
#define IRQ7 39
|
||||
#define IRQ8 40
|
||||
#define IRQ9 41
|
||||
#define IRQ10 42
|
||||
#define IRQ11 43
|
||||
#define IRQ12 44
|
||||
#define IRQ13 45
|
||||
#define IRQ14 46
|
||||
#define IRQ15 47
|
||||
|
||||
typedef void (*isr_t)(registers_t);
|
||||
|
||||
void isr_install();
|
||||
void isr_handler(registers_t r);
|
||||
void irq_handler(registers_t r);
|
||||
|
||||
void isr_register_handler(uint8_t n,isr_t handler);
|
||||
|
||||
#endif
|
@ -4,6 +4,12 @@ extern kmain
|
||||
section .boot.text
|
||||
bits 64
|
||||
long_mode_start:
|
||||
mov ax, 0
|
||||
mov ss, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov rax,kmain
|
||||
call rax
|
||||
loop: jmp loop
|
||||
|
0
ext2.img.lock
Normal file
0
ext2.img.lock
Normal file
@ -1,29 +1,29 @@
|
||||
// #include "../cpu/cpu_init.h"
|
||||
#include "../cpu/cpu_init.h"
|
||||
#include "../drivers/vga.h"
|
||||
// #include "../drivers/pci.h"
|
||||
// #include "../drivers/serial.h"
|
||||
#include "../drivers/pci.h"
|
||||
#include "../drivers/serial.h"
|
||||
// #include "../cpu/i386/ports.h"
|
||||
// #include "vfs.h"
|
||||
// #include "../fs/devfs.h"
|
||||
// #include "../fs/initrd.h"
|
||||
#include "vfs.h"
|
||||
#include "../fs/devfs.h"
|
||||
#include "../fs/initrd.h"
|
||||
#include <grub/text_fb_info.h>
|
||||
// #include <stdlib.h>
|
||||
// #include <tasking.h>
|
||||
// #include <string.h>
|
||||
// #include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <tasking.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <grub/multiboot.h>
|
||||
// #include "klog.h"
|
||||
// #include "elf.h"
|
||||
// #include <errno.h>
|
||||
// #include "../drivers/ide.h"
|
||||
// #include "parts.h"
|
||||
// #include "../fs/ext2.h"
|
||||
// #include <stdint.h>
|
||||
//
|
||||
// static long initrd_sz;
|
||||
// static char* initrd;
|
||||
// static multiboot_info_t* mbd;
|
||||
// typedef int (*func_ptr)();
|
||||
#include "klog.h"
|
||||
#include "elf.h"
|
||||
#include <errno.h>
|
||||
#include "../drivers/ide.h"
|
||||
#include "parts.h"
|
||||
#include "../fs/ext2.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static long initrd_sz;
|
||||
static char* initrd;
|
||||
static multiboot_info_t* mbd;
|
||||
typedef int (*func_ptr)();
|
||||
//
|
||||
// static int console_dev_drv(char* filename,int c,long pos,char wr) {
|
||||
// if (wr) {
|
||||
@ -76,7 +76,7 @@
|
||||
// for(;;) {}
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
// static void init() {
|
||||
// init_vfs();
|
||||
// init_devfs();
|
||||
@ -136,8 +136,8 @@
|
||||
// }
|
||||
|
||||
void kmain(multiboot_info_t* header) {
|
||||
// mbd=header;
|
||||
// cpu_init(mbd);
|
||||
mbd=header;
|
||||
cpu_init(mbd);
|
||||
text_fb_info info;
|
||||
// if (header->flags&MULTIBOOT_INFO_FRAMEBUFFER_INFO&&header->framebuffer_type==2) {
|
||||
// info.address=(char*)(((uint32_t)header->framebuffer_addr&0xFFFFFFFF)+0xC0000000);
|
||||
|
@ -1 +1 @@
|
||||
/Users/peterterpstra/x86_64-elf/bin/x86_64-elf-gcc -mcmodel=large
|
||||
/Users/peterterpstra/x86_64-elf/bin/x86_64-elf-gcc -mcmodel=large -mno-red-zone
|
||||
|
Loading…
Reference in New Issue
Block a user