assertions, interrupts
This commit is contained in:
parent
e04a9b82cf
commit
cb91c25253
7 changed files with 489 additions and 30 deletions
26
kernel/include/interrupts.h
Normal file
26
kernel/include/interrupts.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* Calcite, kernel/include/interrupts.h
|
||||||
|
* Copyright 2025 Benji Dial
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//switches to kernel gdt and idt, maps and unmasks irqs, enables interrupts
|
||||||
|
void enable_interrupts();
|
||||||
|
|
||||||
|
//the handler should have normal C linkage
|
||||||
|
void set_irq_handler(uint8_t irq_line, void (*handler)());
|
||||||
31
kernel/include/panic.h
Normal file
31
kernel/include/panic.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* Calcite, kernel/include/panic.h
|
||||||
|
* Copyright 2025 Benji Dial
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[[noreturn]] void panic_core(
|
||||||
|
const char *file, const char *function, int line, const char *message);
|
||||||
|
|
||||||
|
#define panic(message) panic_core(__FILE__, __func__, __LINE__, message);
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define assert(condition) ((void)0)
|
||||||
|
#else
|
||||||
|
#define assert(condition) \
|
||||||
|
{ \
|
||||||
|
if (!(condition)) \
|
||||||
|
panic("assertion failed: " #condition) \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -15,10 +15,12 @@
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <interrupts.h>
|
||||||
#include <utility.h>
|
#include <utility.h>
|
||||||
#include <initfs.h>
|
#include <initfs.h>
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <paging.h>
|
#include <paging.h>
|
||||||
|
#include <panic.h>
|
||||||
|
|
||||||
LIMINE_BASE_REVISION(3)
|
LIMINE_BASE_REVISION(3)
|
||||||
|
|
||||||
|
|
@ -177,30 +179,12 @@ static uint64_t initfs_length;
|
||||||
|
|
||||||
[[noreturn]] static void with_kernel_page_tables() {
|
[[noreturn]] static void with_kernel_page_tables() {
|
||||||
|
|
||||||
//test initfs
|
//further initialization
|
||||||
|
|
||||||
set_initfs(initfs_start, initfs_length);
|
set_initfs(initfs_start, initfs_length);
|
||||||
|
enable_interrupts();
|
||||||
|
|
||||||
const uint8_t *hello_start;
|
while (1)
|
||||||
uint64_t hello_length;
|
__asm__ ("hlt");
|
||||||
look_up_initfs_file("resx/hello.txt", &hello_start, &hello_length);
|
|
||||||
|
|
||||||
if (hello_length != 7)
|
|
||||||
die();
|
|
||||||
|
|
||||||
for (int i = 0; i < 7; ++i)
|
|
||||||
if (hello_start[i] != "Hello!\n"[i])
|
|
||||||
die();
|
|
||||||
|
|
||||||
//test framebuffer
|
|
||||||
|
|
||||||
for (int y = 0; y < fb_height; ++y)
|
|
||||||
for (int x = 0; x < fb_width; ++x) {
|
|
||||||
fb_base[y * fb_pitch + x * 4] = y * 256 / fb_height;
|
|
||||||
fb_base[y * fb_pitch + x * 4 + 1] = x * 256 / fb_width;
|
|
||||||
fb_base[y * fb_pitch + x * 4 + 2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
die();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
153
kernel/src/interrupts.asm
Normal file
153
kernel/src/interrupts.asm
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
; Calcite, kernel/src/interrupts.asm
|
||||||
|
; Copyright 2025 Benji Dial
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
; your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful, but
|
||||||
|
; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
; more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License along with
|
||||||
|
; this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
bits 64
|
||||||
|
|
||||||
|
;both defined in interrupts.c
|
||||||
|
extern isr_exception_c
|
||||||
|
extern isr_irq_c
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
|
||||||
|
;referenced in interrupts.c
|
||||||
|
global isrs
|
||||||
|
isrs:
|
||||||
|
%assign n 0
|
||||||
|
%rep 48
|
||||||
|
dq isr_ %+ n
|
||||||
|
%assign n n + 1
|
||||||
|
%endrep
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
%assign n 0
|
||||||
|
|
||||||
|
%rep 32
|
||||||
|
isr_ %+ n:
|
||||||
|
%if n <= 0x07 || n = 0x09 || (n >= 0x0f && n <= 0x1c && n <> 0x11 && n <> 0x15) || n = 0x1f
|
||||||
|
push qword 0
|
||||||
|
%endif
|
||||||
|
push qword n
|
||||||
|
jmp isr_exception_common
|
||||||
|
%assign n n + 1
|
||||||
|
%endrep
|
||||||
|
|
||||||
|
%rep 16
|
||||||
|
isr_ %+ n:
|
||||||
|
push rdi
|
||||||
|
mov rdi, n - 32
|
||||||
|
jmp isr_irq_common
|
||||||
|
%assign n n + 1
|
||||||
|
%endrep
|
||||||
|
|
||||||
|
isr_exception_common:
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
mov rdi, rsp
|
||||||
|
jmp isr_exception_c
|
||||||
|
|
||||||
|
isr_irq_common:
|
||||||
|
push rax
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
|
||||||
|
test dil, 0x08
|
||||||
|
jnz .high
|
||||||
|
|
||||||
|
call isr_irq_c
|
||||||
|
mov al, 0x20
|
||||||
|
out 0x20, al
|
||||||
|
jmp .common_end
|
||||||
|
|
||||||
|
.high:
|
||||||
|
call isr_irq_c
|
||||||
|
mov al, 0x20
|
||||||
|
out 0xa0, al
|
||||||
|
out 0x20, al
|
||||||
|
|
||||||
|
.common_end:
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rax
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
iretq
|
||||||
|
|
||||||
|
;referenced in interrupts.c
|
||||||
|
;rdi is pointer to gdt descriptor
|
||||||
|
;rsi is pointer to idt descriptor
|
||||||
|
;dx is offset of tss into gdt
|
||||||
|
global enable_interrupts_asm
|
||||||
|
enable_interrupts_asm:
|
||||||
|
|
||||||
|
;load tables
|
||||||
|
|
||||||
|
lgdt [rdi]
|
||||||
|
ltr dx
|
||||||
|
lidt [rsi]
|
||||||
|
|
||||||
|
;initialize interrupt controllers
|
||||||
|
|
||||||
|
mov al, 0x11
|
||||||
|
out 0x20, al
|
||||||
|
mov al, 0x20
|
||||||
|
out 0x21, al
|
||||||
|
mov al, 0x04
|
||||||
|
out 0x21, al
|
||||||
|
mov al, 0x01
|
||||||
|
out 0x21, al
|
||||||
|
mov al, 0x00
|
||||||
|
out 0x21, al
|
||||||
|
|
||||||
|
mov al, 0x11
|
||||||
|
out 0xa0, al
|
||||||
|
mov al, 0x28
|
||||||
|
out 0xa1, al
|
||||||
|
mov al, 0x02
|
||||||
|
out 0xa1, al
|
||||||
|
mov al, 0x01
|
||||||
|
out 0xa1, al
|
||||||
|
mov al, 0x00
|
||||||
|
out 0xa1, al
|
||||||
|
|
||||||
|
;enable interrupts and return
|
||||||
|
|
||||||
|
sti
|
||||||
|
ret
|
||||||
240
kernel/src/interrupts.c
Normal file
240
kernel/src/interrupts.c
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
/* Calcite, kernel/src/interrupts.c
|
||||||
|
* Copyright 2025 Benji Dial
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//relevant sources:
|
||||||
|
// amd64 architecture programmer's manual, volume 2: system programming
|
||||||
|
// https://osdev.wiki/wiki/Global_Descriptor_Table
|
||||||
|
// https://osdev.wiki/wiki/Interrupt_Descriptor_Table
|
||||||
|
// https://osdev.wiki/wiki/Task_State_Segment
|
||||||
|
|
||||||
|
#include <interrupts.h>
|
||||||
|
#include <panic.h>
|
||||||
|
|
||||||
|
struct [[gnu::packed]] exception_parameter {
|
||||||
|
uint64_t r15;
|
||||||
|
uint64_t r14;
|
||||||
|
uint64_t r13;
|
||||||
|
uint64_t r12;
|
||||||
|
uint64_t r11;
|
||||||
|
uint64_t r10;
|
||||||
|
uint64_t r9;
|
||||||
|
uint64_t r8;
|
||||||
|
uint64_t rbp;
|
||||||
|
uint64_t rsi;
|
||||||
|
uint64_t rdi;
|
||||||
|
uint64_t rdx;
|
||||||
|
uint64_t rcx;
|
||||||
|
uint64_t rbx;
|
||||||
|
uint64_t rax;
|
||||||
|
uint64_t exception_number;
|
||||||
|
//0 if exception pushes no error code
|
||||||
|
uint64_t error_code;
|
||||||
|
uint64_t rip;
|
||||||
|
uint64_t cs;
|
||||||
|
uint64_t rflags;
|
||||||
|
uint64_t rsp;
|
||||||
|
uint64_t ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
//referenced in interrupts.asm
|
||||||
|
void isr_exception_c(struct exception_parameter *parameter) {
|
||||||
|
(void)parameter;
|
||||||
|
panic("TODO");
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*irq_handlers[16])() = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
//referenced in interrupts.asm
|
||||||
|
void isr_irq_c(uint64_t irq_number) {
|
||||||
|
if (irq_handlers[irq_number])
|
||||||
|
(*irq_handlers[irq_number])();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_irq_handler(uint8_t irq_line, void (*handler)(void)) {
|
||||||
|
assert(irq_line < 16);
|
||||||
|
irq_handlers[irq_line] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
|
||||||
|
GDT_AB_CODE_DATA_ACCESSED = 0x01,
|
||||||
|
GDT_AB_DATA_WRITABLE = 0x02,
|
||||||
|
|
||||||
|
GDT_AB_TYPE_TSS = 0x09,
|
||||||
|
GDT_AB_TYPE_DATA = 0x10,
|
||||||
|
GDT_AB_TYPE_CODE = 0x18,
|
||||||
|
|
||||||
|
GDT_AB_DPL_ZERO = 0x00,
|
||||||
|
GDT_AB_DPL_THREE = 0x60,
|
||||||
|
|
||||||
|
GDT_AB_PRESENT = 0x80,
|
||||||
|
|
||||||
|
GDT_FLAG_LONG = 0x20
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] gdt_entry {
|
||||||
|
uint32_t zero;
|
||||||
|
uint8_t zero_;
|
||||||
|
uint8_t access_byte;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t zero__;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] gdt_entry_system {
|
||||||
|
uint16_t limit_0;
|
||||||
|
uint16_t base_0;
|
||||||
|
uint8_t base_16;
|
||||||
|
uint8_t access_byte;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t base_24;
|
||||||
|
uint32_t base_32;
|
||||||
|
uint32_t zero;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gdt_entry the_gdt[7];
|
||||||
|
|
||||||
|
struct [[gnu::packed]] gdt_descriptor {
|
||||||
|
uint16_t limit;
|
||||||
|
void *base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gdt_descriptor the_gdt_descriptor = {
|
||||||
|
.limit = 7 * sizeof(struct gdt_entry) - 1,
|
||||||
|
.base = the_gdt
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] tss {
|
||||||
|
uint32_t zero;
|
||||||
|
uint64_t rsp0;
|
||||||
|
uint64_t rsp1;
|
||||||
|
uint64_t rsp2;
|
||||||
|
uint64_t zero_;
|
||||||
|
uint64_t ist1;
|
||||||
|
uint64_t ist2;
|
||||||
|
uint64_t ist3;
|
||||||
|
uint64_t ist4;
|
||||||
|
uint64_t ist5;
|
||||||
|
uint64_t ist6;
|
||||||
|
uint64_t ist7;
|
||||||
|
uint64_t zero__;
|
||||||
|
uint16_t zero___;
|
||||||
|
uint16_t io_permission_map_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tss the_tss;
|
||||||
|
|
||||||
|
//maybe these should be allocated dynamically with guard pages?
|
||||||
|
#define INTERRUPT_STACK_SIZE (16 << 20)
|
||||||
|
static uint8_t interrupt_stack_one[INTERRUPT_STACK_SIZE];
|
||||||
|
static uint8_t interrupt_stack_two[INTERRUPT_STACK_SIZE];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
|
||||||
|
//"interrupt" here just means disable interrupts on entry.
|
||||||
|
//in our case, we use this for both irq's and exceptions.
|
||||||
|
IDT_TYPE_INTERRUPT = 0x0e,
|
||||||
|
|
||||||
|
IDT_TYPE_DPL_ZERO = 0x00,
|
||||||
|
IDT_TYPE_DPL_THREE = 0x60,
|
||||||
|
|
||||||
|
IDT_TYPE_PRESENT = 0x80
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] idt_entry {
|
||||||
|
uint16_t offset_0;
|
||||||
|
uint16_t segment_selector;
|
||||||
|
uint8_t interrupt_stack_index;
|
||||||
|
uint8_t type;
|
||||||
|
uint16_t offset_16;
|
||||||
|
uint32_t offset_32;
|
||||||
|
uint32_t zero;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct idt_entry the_idt[256];
|
||||||
|
|
||||||
|
struct [[gnu::packed]] idt_descriptor {
|
||||||
|
uint16_t limit;
|
||||||
|
void *base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct idt_descriptor the_idt_descriptor = {
|
||||||
|
.limit = 256 * sizeof(struct idt_entry) - 1,
|
||||||
|
.base = the_idt
|
||||||
|
};
|
||||||
|
|
||||||
|
//defined in interrupts.asm
|
||||||
|
extern void *isrs[48];
|
||||||
|
|
||||||
|
//defined in interrupts.asm
|
||||||
|
void enable_interrupts_asm(
|
||||||
|
struct gdt_descriptor *gdtr,
|
||||||
|
struct idt_descriptor *idtr,
|
||||||
|
uint16_t tssr);
|
||||||
|
|
||||||
|
void enable_interrupts() {
|
||||||
|
|
||||||
|
the_tss.ist1 = (uint64_t)&interrupt_stack_one;
|
||||||
|
the_tss.ist2 = (uint64_t)&interrupt_stack_two;
|
||||||
|
|
||||||
|
//having the table past the end of the tss will lead to a gpf when the
|
||||||
|
//cpu tries to access it, which is the same effect as a disabled port.
|
||||||
|
the_tss.io_permission_map_offset = 256;
|
||||||
|
|
||||||
|
uint64_t tss_base = (uint64_t)&the_tss;
|
||||||
|
uint16_t tss_limit = sizeof(struct tss) - 1;
|
||||||
|
|
||||||
|
struct gdt_entry_system *tss_entry = (struct gdt_entry_system *)&the_gdt[1];
|
||||||
|
tss_entry->limit_0 = tss_limit;
|
||||||
|
tss_entry->base_0 = tss_base & 0xffff;
|
||||||
|
tss_entry->base_16 = (tss_base >> 16) & 0xff;
|
||||||
|
tss_entry->access_byte =
|
||||||
|
GDT_AB_TYPE_TSS | GDT_AB_DPL_ZERO | GDT_AB_PRESENT;
|
||||||
|
tss_entry->flags = GDT_FLAG_LONG;
|
||||||
|
tss_entry->base_24 = (tss_base >> 24) & 0xff;
|
||||||
|
tss_entry->base_32 = tss_base >> 32;
|
||||||
|
|
||||||
|
struct gdt_entry *kernel_code_entry = &the_gdt[5];
|
||||||
|
kernel_code_entry->access_byte =
|
||||||
|
GDT_AB_CODE_DATA_ACCESSED | GDT_AB_TYPE_CODE |
|
||||||
|
GDT_AB_DPL_ZERO | GDT_AB_PRESENT;
|
||||||
|
kernel_code_entry->flags = GDT_FLAG_LONG;
|
||||||
|
|
||||||
|
struct gdt_entry *kernel_data_entry = &the_gdt[6];
|
||||||
|
kernel_data_entry->access_byte =
|
||||||
|
GDT_AB_CODE_DATA_ACCESSED | GDT_AB_DATA_WRITABLE |
|
||||||
|
GDT_AB_TYPE_DATA | GDT_AB_DPL_ZERO | GDT_AB_PRESENT;
|
||||||
|
kernel_data_entry->flags = GDT_FLAG_LONG;
|
||||||
|
|
||||||
|
for (int i = 0; i < 48; ++i) {
|
||||||
|
uint64_t offset = (uint64_t)isrs[i];
|
||||||
|
the_idt[i].offset_0 = offset & 0xffff;
|
||||||
|
the_idt[i].segment_selector = 0x0028;
|
||||||
|
the_idt[i].interrupt_stack_index = i < 32 ? 0x02 : 0x01;
|
||||||
|
the_idt[i].type =
|
||||||
|
IDT_TYPE_INTERRUPT | IDT_TYPE_DPL_ZERO | IDT_TYPE_PRESENT;
|
||||||
|
the_idt[i].offset_16 = (offset >> 16) & 0xffff;
|
||||||
|
the_idt[i].offset_32 = offset >> 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_interrupts_asm(&the_gdt_descriptor, &the_idt_descriptor, 0x08);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <paging.h>
|
#include <paging.h>
|
||||||
|
#include <panic.h>
|
||||||
|
|
||||||
#define MAX_PHYSICAL_GB 64ULL
|
#define MAX_PHYSICAL_GB 64ULL
|
||||||
|
|
||||||
|
|
@ -102,16 +103,10 @@ void map_in_kernel_page_table(
|
||||||
int writable, int executable) {
|
int writable, int executable) {
|
||||||
|
|
||||||
uint64_t virtual_base_u64 = (uint64_t)virtual_base;
|
uint64_t virtual_base_u64 = (uint64_t)virtual_base;
|
||||||
|
assert(virtual_base_u64 >= 0xffffffffc0000000);
|
||||||
//should probably die in this case
|
|
||||||
if (virtual_base_u64 < 0xffffffffc0000000)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint64_t p1s_index = (virtual_base_u64 - 0xffffffffc0000000) >> 12;
|
uint64_t p1s_index = (virtual_base_u64 - 0xffffffffc0000000) >> 12;
|
||||||
|
assert(kernel_p1s[p1s_index] == 0);
|
||||||
//should probably die in this case too
|
|
||||||
if (kernel_p1s[p1s_index] != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
kernel_p1s[p1s_index] =
|
kernel_p1s[p1s_index] =
|
||||||
physical_base | (writable ? 0x3 : 0x1) |
|
physical_base | (writable ? 0x3 : 0x1) |
|
||||||
|
|
|
||||||
30
kernel/src/panic.c
Normal file
30
kernel/src/panic.c
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* Calcite, kernel/src/panic.c
|
||||||
|
* Copyright 2025 Benji Dial
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[[noreturn]] void panic_core(
|
||||||
|
const char *file, const char *function, int line, const char *message) {
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
(void)file;
|
||||||
|
(void)function;
|
||||||
|
(void)line;
|
||||||
|
(void)message;
|
||||||
|
while (1)
|
||||||
|
__asm__ ("hlt");
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue