Compare commits
4 Commits
08bbe517c5
...
022dde6c7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
022dde6c7c | ||
|
|
71c73dd493 | ||
|
|
33239034a7 | ||
|
|
a1205703f0 |
3
.clangd
3
.clangd
@@ -13,6 +13,3 @@ CompileFlags:
|
|||||||
- "-nostdlib"
|
- "-nostdlib"
|
||||||
- "-I"
|
- "-I"
|
||||||
- "/home/oliste/repos/nub-os/src/stdlib"
|
- "/home/oliste/repos/nub-os/src/stdlib"
|
||||||
|
|
||||||
Style:
|
|
||||||
AngledHeaders: "src/stdlib/.*"
|
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t base_address;
|
||||||
|
size_t length;
|
||||||
|
} memory_region_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
memory_region_t* regions;
|
||||||
|
size_t num_regions;
|
||||||
|
} memory_map_t;
|
||||||
|
|
||||||
|
extern memory_map_t memory_map;
|
||||||
|
|
||||||
void panic();
|
void panic();
|
||||||
void put_char(char character);
|
void put_char(char character);
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint64_t base_address;
|
|
||||||
size_t length;
|
|
||||||
} memory_region_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
memory_region_t* regions;
|
|
||||||
size_t num_regions;
|
|
||||||
} memory_map_t;
|
|
||||||
|
|
||||||
extern memory_map_t memory_map;
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
global _start
|
global _start
|
||||||
extern entry
|
extern entry
|
||||||
extern handle_isr
|
|
||||||
extern pml4
|
|
||||||
|
|
||||||
%define FLAGS 0b10
|
%define FLAGS 0b10
|
||||||
%define MAGIC 0x1BADB002
|
%define MAGIC 0x1BADB002
|
||||||
@@ -140,39 +138,6 @@ section .text
|
|||||||
hlt
|
hlt
|
||||||
jmp .hang
|
jmp .hang
|
||||||
|
|
||||||
section .bss
|
|
||||||
align 4096
|
|
||||||
idt64:
|
|
||||||
resb 4096
|
|
||||||
|
|
||||||
section .data
|
|
||||||
align 8
|
|
||||||
idt64_descriptor:
|
|
||||||
dw 4095
|
|
||||||
dq idt64
|
|
||||||
|
|
||||||
section .data
|
|
||||||
align 8
|
|
||||||
isr_stub_table:
|
|
||||||
%assign i 0
|
|
||||||
%rep 256
|
|
||||||
dq isr_stub_%[i]
|
|
||||||
%assign i i+1
|
|
||||||
%endrep
|
|
||||||
|
|
||||||
%macro ISR_NOERR 1
|
|
||||||
isr_stub_%1:
|
|
||||||
push qword 0
|
|
||||||
push qword %1
|
|
||||||
jmp isr_common
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro ISR_ERR 1
|
|
||||||
isr_stub_%1:
|
|
||||||
push qword %1
|
|
||||||
jmp isr_common
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
bits 64
|
bits 64
|
||||||
long_mode:
|
long_mode:
|
||||||
@@ -184,108 +149,9 @@ section .text
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
; Fill in the idt table with the stub functions
|
|
||||||
mov rdi, idt64
|
|
||||||
mov rsi, isr_stub_table
|
|
||||||
mov rcx, 256
|
|
||||||
.loop:
|
|
||||||
mov rax, [rsi]
|
|
||||||
mov [rdi], ax
|
|
||||||
mov word [rdi + 2], 0x08
|
|
||||||
mov word [rdi + 4], 0x8E00
|
|
||||||
shr rax, 16
|
|
||||||
mov [rdi + 6], ax
|
|
||||||
shr rax, 16
|
|
||||||
mov [rdi + 8], eax
|
|
||||||
mov dword [rdi + 12], 0
|
|
||||||
add rdi, 16
|
|
||||||
add rsi, 8
|
|
||||||
loop .loop
|
|
||||||
lidt [idt64_descriptor]
|
|
||||||
|
|
||||||
; Finally, we call in to c
|
; Finally, we call in to c
|
||||||
mov rdi, [multiboot_info]
|
mov rdi, [multiboot_info]
|
||||||
call entry
|
call entry
|
||||||
.hang:
|
.hang:
|
||||||
hlt
|
hlt
|
||||||
jmp .hang
|
jmp .hang
|
||||||
|
|
||||||
isr_common:
|
|
||||||
push rax
|
|
||||||
push rbx
|
|
||||||
push rcx
|
|
||||||
push rdx
|
|
||||||
push rsi
|
|
||||||
push rdi
|
|
||||||
push rbp
|
|
||||||
push r8
|
|
||||||
push r9
|
|
||||||
push r10
|
|
||||||
push r11
|
|
||||||
push r12
|
|
||||||
push r13
|
|
||||||
push r14
|
|
||||||
push r15
|
|
||||||
|
|
||||||
mov rdi, rsp
|
|
||||||
call handle_isr
|
|
||||||
|
|
||||||
pop r15
|
|
||||||
pop r14
|
|
||||||
pop r13
|
|
||||||
pop r12
|
|
||||||
pop r11
|
|
||||||
pop r10
|
|
||||||
pop r9
|
|
||||||
pop r8
|
|
||||||
pop rbp
|
|
||||||
pop rdi
|
|
||||||
pop rsi
|
|
||||||
pop rdx
|
|
||||||
pop rcx
|
|
||||||
pop rbx
|
|
||||||
pop rax
|
|
||||||
|
|
||||||
add rsp, 16
|
|
||||||
iretq
|
|
||||||
|
|
||||||
; CPU exceptions 0-31. Some of these contain error codes, so we define them manually
|
|
||||||
ISR_NOERR 0
|
|
||||||
ISR_NOERR 1
|
|
||||||
ISR_NOERR 2
|
|
||||||
ISR_NOERR 3
|
|
||||||
ISR_NOERR 4
|
|
||||||
ISR_NOERR 5
|
|
||||||
ISR_NOERR 6
|
|
||||||
ISR_NOERR 7
|
|
||||||
ISR_ERR 8
|
|
||||||
ISR_NOERR 9
|
|
||||||
ISR_ERR 10
|
|
||||||
ISR_ERR 11
|
|
||||||
ISR_ERR 12
|
|
||||||
ISR_ERR 13
|
|
||||||
ISR_ERR 14
|
|
||||||
ISR_NOERR 15
|
|
||||||
ISR_NOERR 16
|
|
||||||
ISR_ERR 17
|
|
||||||
ISR_NOERR 18
|
|
||||||
ISR_NOERR 19
|
|
||||||
ISR_NOERR 20
|
|
||||||
ISR_NOERR 21
|
|
||||||
ISR_NOERR 22
|
|
||||||
ISR_NOERR 23
|
|
||||||
ISR_NOERR 24
|
|
||||||
ISR_NOERR 25
|
|
||||||
ISR_NOERR 26
|
|
||||||
ISR_NOERR 27
|
|
||||||
ISR_NOERR 28
|
|
||||||
ISR_NOERR 29
|
|
||||||
ISR_ERR 30
|
|
||||||
ISR_NOERR 31
|
|
||||||
|
|
||||||
; Hardware interrupts and user-defined interrupts (32-255). These don't have error codes
|
|
||||||
%assign i 32
|
|
||||||
%rep 224
|
|
||||||
ISR_NOERR i
|
|
||||||
%assign i i+1
|
|
||||||
%endrep
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
#include "interrupts.h"
|
|
||||||
#include "../arch.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define PIC1_COMMAND 0x20
|
|
||||||
#define PIC1_DATA 0x21
|
|
||||||
#define PIC2_COMMAND 0xA0
|
|
||||||
#define PIC2_DATA 0xA1
|
|
||||||
|
|
||||||
static const char* exception_messages[32] = {
|
|
||||||
"divide by zero",
|
|
||||||
"debug",
|
|
||||||
"non maskable interrupt",
|
|
||||||
"breakpoint",
|
|
||||||
"overflow",
|
|
||||||
"bound range exceeded",
|
|
||||||
"invalid opcode",
|
|
||||||
"device not available",
|
|
||||||
"double fault",
|
|
||||||
"coprocessor segment overrun",
|
|
||||||
"invalid tss",
|
|
||||||
"segment not present",
|
|
||||||
"stack-segment fault",
|
|
||||||
"general protection fault",
|
|
||||||
"page fault",
|
|
||||||
"reserved",
|
|
||||||
"x87 floating point exception",
|
|
||||||
"alignment check",
|
|
||||||
"machine check",
|
|
||||||
"simd floating point exception",
|
|
||||||
"virtualization exception",
|
|
||||||
"control protection exception",
|
|
||||||
"reserved",
|
|
||||||
"reserved",
|
|
||||||
"reserved",
|
|
||||||
"reserved",
|
|
||||||
"reserved",
|
|
||||||
"reserved",
|
|
||||||
"hypervisor injection exception",
|
|
||||||
"vmm communication exception",
|
|
||||||
"security exception",
|
|
||||||
"reserved",
|
|
||||||
};
|
|
||||||
|
|
||||||
static irq_handler_t irq_handlers[16] = {0};
|
|
||||||
|
|
||||||
bool cpu_has_apic()
|
|
||||||
{
|
|
||||||
uint32_t eax, edx;
|
|
||||||
cpuid(1, &eax, &edx);
|
|
||||||
return (edx & CPUID_FEAT_EDX_APIC) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable_apic()
|
|
||||||
{
|
|
||||||
uint64_t apic_base = rdmsr(0x1B);
|
|
||||||
apic_base |= (1 << 11);
|
|
||||||
wrmsr(0x1B, apic_base);
|
|
||||||
printf("APIC enabled\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void remap_pic()
|
|
||||||
{
|
|
||||||
outb(PIC1_COMMAND, 0x11);
|
|
||||||
outb(PIC2_COMMAND, 0x11);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, 32);
|
|
||||||
outb(PIC2_DATA, 40);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, 4);
|
|
||||||
outb(PIC2_DATA, 2);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, 1);
|
|
||||||
outb(PIC2_DATA, 1);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, 0);
|
|
||||||
outb(PIC2_DATA, 0);
|
|
||||||
printf("PIC remapped\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_pic()
|
|
||||||
{
|
|
||||||
outb(PIC1_DATA, 0xFF);
|
|
||||||
outb(PIC2_DATA, 0xFF);
|
|
||||||
printf("PIC disabled\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_exception(const isr_frame_t* frame)
|
|
||||||
{
|
|
||||||
printf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code);
|
|
||||||
panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_irq_handler(uint8_t irq, irq_handler_t handler)
|
|
||||||
{
|
|
||||||
if (irq >= 16)
|
|
||||||
{
|
|
||||||
printf("Cannot register irq %d is out of bounds\n", irq);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
irq_handlers[irq] = handler;
|
|
||||||
printf("Registered irq handler at vector %d\n", irq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_irq(const isr_frame_t* frame)
|
|
||||||
{
|
|
||||||
uint8_t irq = frame->int_no - 32;
|
|
||||||
|
|
||||||
if (irq_handlers[irq])
|
|
||||||
{
|
|
||||||
irq_handlers[irq](frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irq >= 8)
|
|
||||||
{
|
|
||||||
outb(PIC2_COMMAND, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
outb(PIC1_COMMAND, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_isr(const isr_frame_t* frame)
|
|
||||||
{
|
|
||||||
if (frame->int_no < 32)
|
|
||||||
{
|
|
||||||
handle_exception(frame);
|
|
||||||
}
|
|
||||||
else if (frame->int_no < 48)
|
|
||||||
{
|
|
||||||
handle_irq(frame);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("interrupt[%d]: not implemented\n", frame->int_no);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
43
src/arch/x86_64/interrupts/exceptions.c
Normal file
43
src/arch/x86_64/interrupts/exceptions.c
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include "exceptions.h"
|
||||||
|
#include "../../arch.h"
|
||||||
|
|
||||||
|
static const char* exception_messages[32] = {
|
||||||
|
"divide by zero",
|
||||||
|
"debug",
|
||||||
|
"non maskable interrupt",
|
||||||
|
"breakpoint",
|
||||||
|
"overflow",
|
||||||
|
"bound range exceeded",
|
||||||
|
"invalid opcode",
|
||||||
|
"device not available",
|
||||||
|
"double fault",
|
||||||
|
"coprocessor segment overrun",
|
||||||
|
"invalid tss",
|
||||||
|
"segment not present",
|
||||||
|
"stack-segment fault",
|
||||||
|
"general protection fault",
|
||||||
|
"page fault",
|
||||||
|
"reserved",
|
||||||
|
"x87 floating point exception",
|
||||||
|
"alignment check",
|
||||||
|
"machine check",
|
||||||
|
"simd floating point exception",
|
||||||
|
"virtualization exception",
|
||||||
|
"control protection exception",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"hypervisor injection exception",
|
||||||
|
"vmm communication exception",
|
||||||
|
"security exception",
|
||||||
|
"reserved",
|
||||||
|
};
|
||||||
|
|
||||||
|
void handle_exception(const isr_frame_t* frame)
|
||||||
|
{
|
||||||
|
printf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
8
src/arch/x86_64/interrupts/exceptions.h
Normal file
8
src/arch/x86_64/interrupts/exceptions.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
typedef void (*exception_handler_t)(const isr_frame_t*);
|
||||||
|
|
||||||
|
void handle_exception(const isr_frame_t* frame);
|
||||||
|
void register_exception_handler(uint8_t irq, exception_handler_t handler);
|
||||||
136
src/arch/x86_64/interrupts/idt.asm
Normal file
136
src/arch/x86_64/interrupts/idt.asm
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
global idt_init
|
||||||
|
extern handle_isr
|
||||||
|
|
||||||
|
%macro ISR_NOERR 1
|
||||||
|
isr_stub_%1:
|
||||||
|
push qword 0
|
||||||
|
push qword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISR_ERR 1
|
||||||
|
isr_stub_%1:
|
||||||
|
push qword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
align 4096
|
||||||
|
idt64:
|
||||||
|
resb 4096
|
||||||
|
|
||||||
|
section .data
|
||||||
|
align 8
|
||||||
|
isr_stub_table:
|
||||||
|
%assign i 0
|
||||||
|
%rep 256
|
||||||
|
dq isr_stub_%[i]
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
|
||||||
|
idt64_descriptor:
|
||||||
|
dw 4095
|
||||||
|
dq idt64
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 64
|
||||||
|
idt_init:
|
||||||
|
; Fill in the idt table with the stub functions
|
||||||
|
mov rdi, idt64
|
||||||
|
mov rsi, isr_stub_table
|
||||||
|
mov rcx, 256
|
||||||
|
.loop:
|
||||||
|
mov rax, [rsi]
|
||||||
|
mov [rdi], ax
|
||||||
|
mov word [rdi + 2], 0x08
|
||||||
|
mov word [rdi + 4], 0x8E00
|
||||||
|
shr rax, 16
|
||||||
|
mov [rdi + 6], ax
|
||||||
|
shr rax, 16
|
||||||
|
mov [rdi + 8], eax
|
||||||
|
mov dword [rdi + 12], 0
|
||||||
|
add rdi, 16
|
||||||
|
add rsi, 8
|
||||||
|
loop .loop
|
||||||
|
lidt [idt64_descriptor]
|
||||||
|
ret
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
mov rdi, rsp
|
||||||
|
call handle_isr
|
||||||
|
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
|
||||||
|
add rsp, 16
|
||||||
|
iretq
|
||||||
|
|
||||||
|
; CPU exceptions 0-31. Some of these contain error codes, so we define them manually
|
||||||
|
ISR_NOERR 0
|
||||||
|
ISR_NOERR 1
|
||||||
|
ISR_NOERR 2
|
||||||
|
ISR_NOERR 3
|
||||||
|
ISR_NOERR 4
|
||||||
|
ISR_NOERR 5
|
||||||
|
ISR_NOERR 6
|
||||||
|
ISR_NOERR 7
|
||||||
|
ISR_ERR 8
|
||||||
|
ISR_NOERR 9
|
||||||
|
ISR_ERR 10
|
||||||
|
ISR_ERR 11
|
||||||
|
ISR_ERR 12
|
||||||
|
ISR_ERR 13
|
||||||
|
ISR_ERR 14
|
||||||
|
ISR_NOERR 15
|
||||||
|
ISR_NOERR 16
|
||||||
|
ISR_ERR 17
|
||||||
|
ISR_NOERR 18
|
||||||
|
ISR_NOERR 19
|
||||||
|
ISR_NOERR 20
|
||||||
|
ISR_NOERR 21
|
||||||
|
ISR_NOERR 22
|
||||||
|
ISR_NOERR 23
|
||||||
|
ISR_NOERR 24
|
||||||
|
ISR_NOERR 25
|
||||||
|
ISR_NOERR 26
|
||||||
|
ISR_NOERR 27
|
||||||
|
ISR_NOERR 28
|
||||||
|
ISR_NOERR 29
|
||||||
|
ISR_ERR 30
|
||||||
|
ISR_NOERR 31
|
||||||
|
|
||||||
|
; Hardware interrupts and user-defined interrupts (32-255). These don't have error codes
|
||||||
|
%assign i 32
|
||||||
|
%rep 224
|
||||||
|
ISR_NOERR i
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
3
src/arch/x86_64/interrupts/idt.h
Normal file
3
src/arch/x86_64/interrupts/idt.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern void idt_init();
|
||||||
76
src/arch/x86_64/interrupts/irq.c
Normal file
76
src/arch/x86_64/interrupts/irq.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#include "irq.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
#define PIC1_COMMAND 0x20
|
||||||
|
#define PIC1_DATA 0x21
|
||||||
|
#define PIC2_COMMAND 0xA0
|
||||||
|
#define PIC2_DATA 0xA1
|
||||||
|
|
||||||
|
static irq_handler_t irq_handlers[16] = {0};
|
||||||
|
|
||||||
|
bool cpu_has_apic()
|
||||||
|
{
|
||||||
|
uint32_t eax, edx;
|
||||||
|
cpuid(1, &eax, &edx);
|
||||||
|
return (edx & CPUID_FEAT_EDX_APIC) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable_apic()
|
||||||
|
{
|
||||||
|
uint64_t apic_base = rdmsr(0x1B);
|
||||||
|
apic_base |= (1 << 11);
|
||||||
|
wrmsr(0x1B, apic_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remap_pic()
|
||||||
|
{
|
||||||
|
outb(PIC1_COMMAND, 0x11);
|
||||||
|
outb(PIC2_COMMAND, 0x11);
|
||||||
|
|
||||||
|
outb(PIC1_DATA, 32);
|
||||||
|
outb(PIC2_DATA, 40);
|
||||||
|
|
||||||
|
outb(PIC1_DATA, 4);
|
||||||
|
outb(PIC2_DATA, 2);
|
||||||
|
|
||||||
|
outb(PIC1_DATA, 1);
|
||||||
|
outb(PIC2_DATA, 1);
|
||||||
|
|
||||||
|
outb(PIC1_DATA, 0);
|
||||||
|
outb(PIC2_DATA, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable_pic()
|
||||||
|
{
|
||||||
|
outb(PIC1_DATA, 0xFF);
|
||||||
|
outb(PIC2_DATA, 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_irq_handler(uint8_t irq, irq_handler_t handler)
|
||||||
|
{
|
||||||
|
if (irq >= 16)
|
||||||
|
{
|
||||||
|
printf("Cannot register irq %d is out of bounds\n", irq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
irq_handlers[irq] = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_irq(const isr_frame_t* frame)
|
||||||
|
{
|
||||||
|
uint8_t irq = frame->int_no - 32;
|
||||||
|
|
||||||
|
if (irq_handlers[irq])
|
||||||
|
{
|
||||||
|
irq_handlers[irq](frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irq >= 8)
|
||||||
|
{
|
||||||
|
outb(PIC2_COMMAND, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
outb(PIC1_COMMAND, 0x20);
|
||||||
|
}
|
||||||
13
src/arch/x86_64/interrupts/irq.h
Normal file
13
src/arch/x86_64/interrupts/irq.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef void (*irq_handler_t)(const isr_frame_t*);
|
||||||
|
|
||||||
|
void remap_pic();
|
||||||
|
void disable_pic();
|
||||||
|
bool cpu_has_apic();
|
||||||
|
void enable_apic();
|
||||||
|
void handle_irq(const isr_frame_t* frame);
|
||||||
|
void register_irq_handler(uint8_t irq, irq_handler_t handler);
|
||||||
20
src/arch/x86_64/interrupts/isr.c
Normal file
20
src/arch/x86_64/interrupts/isr.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include "isr.h"
|
||||||
|
#include "exceptions.h"
|
||||||
|
#include "irq.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void handle_isr(const isr_frame_t* frame)
|
||||||
|
{
|
||||||
|
if (frame->int_no < 32)
|
||||||
|
{
|
||||||
|
handle_exception(frame);
|
||||||
|
}
|
||||||
|
else if (frame->int_no < 48)
|
||||||
|
{
|
||||||
|
handle_irq(frame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("interrupt[%d]: not implemented\n", frame->int_no);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -12,16 +12,6 @@ typedef struct
|
|||||||
uint64_t rip, cs, rflags, rsp, ss;
|
uint64_t rip, cs, rflags, rsp, ss;
|
||||||
} __attribute__((packed)) isr_frame_t;
|
} __attribute__((packed)) isr_frame_t;
|
||||||
|
|
||||||
typedef void (*irq_handler_t)(const isr_frame_t*);
|
|
||||||
|
|
||||||
void remap_pic();
|
|
||||||
void disable_pic();
|
|
||||||
|
|
||||||
bool cpu_has_apic();
|
|
||||||
void enable_apic();
|
|
||||||
|
|
||||||
void register_irq_handler(uint8_t irq, irq_handler_t handler);
|
|
||||||
|
|
||||||
static inline void enable_interrupts()
|
static inline void enable_interrupts()
|
||||||
{
|
{
|
||||||
__asm__ volatile("sti");
|
__asm__ volatile("sti");
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
// handler_index += 1;
|
// handler_index += 1;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void init_keyboard()
|
// void keyboard_init()
|
||||||
// {
|
// {
|
||||||
// register_irq_handler(1, handle_keyboard);
|
// register_irq_handler(1, handle_keyboard);
|
||||||
// }
|
// }
|
||||||
@@ -14,6 +14,6 @@
|
|||||||
|
|
||||||
// typedef void (*keyboard_handler_t)(const keyboard_event_t*);
|
// typedef void (*keyboard_handler_t)(const keyboard_event_t*);
|
||||||
|
|
||||||
// void init_keyboard();
|
// void keyboard_init();
|
||||||
// void register_keypress_handler(keyboard_handler_t handler);
|
// void register_keypress_handler(keyboard_handler_t handler);
|
||||||
// char scan_code_to_ascii(uint8_t scan_code);
|
// char scan_code_to_ascii(uint8_t scan_code);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "mmap.h"
|
#include "mmap.h"
|
||||||
#include "../mmap.h"
|
#include "../arch.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -24,14 +24,22 @@ void map_memory(multiboot_info_t* mbd)
|
|||||||
{
|
{
|
||||||
multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(mbd->mmap_addr + offset);
|
multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(mbd->mmap_addr + offset);
|
||||||
|
|
||||||
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE && num_regions < USABLE_REGION_SIZE)
|
if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||||
{
|
{
|
||||||
usable_regions[num_regions] = (memory_region_t){
|
if (num_regions < USABLE_REGION_SIZE)
|
||||||
.base_address = mmmt->addr,
|
{
|
||||||
.length = mmmt->len,
|
usable_regions[num_regions] = (memory_region_t){
|
||||||
};
|
.base_address = mmmt->addr,
|
||||||
|
.length = mmmt->len,
|
||||||
|
};
|
||||||
|
|
||||||
num_regions++;
|
num_regions++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("System has more memory than the memory map can hold\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += mmmt->size + sizeof(mmmt->size);
|
offset += mmmt->size + sizeof(mmmt->size);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "../../kernel.h"
|
#include "../../kernel.h"
|
||||||
#include "../arch.h"
|
#include "../arch.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts/idt.h"
|
||||||
|
#include "interrupts/irq.h"
|
||||||
#include "mmap.h"
|
#include "mmap.h"
|
||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -10,22 +11,16 @@
|
|||||||
void entry(multiboot_info_t* mbd)
|
void entry(multiboot_info_t* mbd)
|
||||||
{
|
{
|
||||||
vga_clear();
|
vga_clear();
|
||||||
map_memory(mbd);
|
idt_init();
|
||||||
remap_pic();
|
remap_pic();
|
||||||
|
map_memory(mbd);
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_callback()
|
|
||||||
{
|
|
||||||
printf("Kernel panic!\n");
|
|
||||||
disable_interrupts();
|
|
||||||
halt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void panic()
|
void panic()
|
||||||
{
|
{
|
||||||
printf("Kernel panic!");
|
printf("Kernel panic!\n");
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
init_pmm();
|
pmm_init();
|
||||||
printf("Welcome to nub OS :)\n");
|
printf("Welcome to nub OS :)\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "pmm.h"
|
#include "pmm.h"
|
||||||
#include "arch/mmap.h"
|
#include "arch/arch.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -11,7 +11,7 @@ static uint8_t page_bitmap[BITMAP_SIZE];
|
|||||||
static uint64_t total_pages = 0;
|
static uint64_t total_pages = 0;
|
||||||
static uint64_t free_pages = 0;
|
static uint64_t free_pages = 0;
|
||||||
|
|
||||||
void init_pmm()
|
void pmm_init()
|
||||||
{
|
{
|
||||||
memset(page_bitmap, 0xFF, BITMAP_SIZE);
|
memset(page_bitmap, 0xFF, BITMAP_SIZE);
|
||||||
|
|
||||||
@@ -50,8 +50,6 @@ void init_pmm()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("PMM initialized\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t pmm_alloc_page()
|
uint64_t pmm_alloc_page()
|
||||||
|
|||||||
Reference in New Issue
Block a user