Made proper structure for arch-specific code; added panic

This commit is contained in:
NotYourFox 2025-01-13 23:37:34 +03:00
parent 309be28067
commit be052c9ce7
12 changed files with 341 additions and 0 deletions

View File

@ -0,0 +1,68 @@
// NOTE: This file contains code derived from or inspired by:
// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX.
// Copyright (c) 2023-2025 NotYourFox, sigsegv
// SPDX-License-Identifier: GPL-3.0-or-later
// 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/>.
#include "arch/cpu/control.h"
#include "kreflock.h"
#include "kstdlib.h"
static inline void __cpu_enable_interrupt() {
asm volatile("sti");
}
static inline void __cpu_disable_interrupt() {
asm volatile("cli");
}
static reflock_t lock =
NEW_REFLOCK(__cpu_disable_interrupt, __cpu_enable_interrupt, false, true);
bool cpu_interrupt_lock_acquired() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}
return reflock_is_locked(&lock);
}
void cpu_interrupt_lock_acquire() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}
reflock_acquire(&lock);
}
void cpu_interrupt_lock_release() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}
reflock_release(&lock);
}
void cpu_interrupt_lock_force_release() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}
reflock_force_unlock(&lock);
}
void cpu_halt() {
asm ("hlt");
}

View File

@ -0,0 +1,26 @@
#define __ASSEMBLY__
.intel_syntax noprefix
#include "arch/cpu/tables.h"
.code64
.global __asm_update_regs
get_flags:
pushfd
mov rax, [rsp]
popfd
ret
get_rip:
mov rax, [rsp]
ret
// TODO because I'm not familiar with x86-64 conventions
__asm_update_regs:
ret
#undef __ASSEMBLY__

View File

@ -0,0 +1,11 @@
#include "amd64/cpu/regs.h"
#include "arch/cpu/strace.h"
#include "kstring.h"
extern void __asm_update_regs(asm_regs_t *regs);
// work in progress
void update_asm_regs(asm_regs_t *state) {
memset(state, 0x00, sizeof(asm_regs_t));
return;
}

View File

@ -0,0 +1,47 @@
#include "amd64/cpu/regs.h"
#include "khal.h"
void cpu_state_print() {
asm_regs_t current_state;
serial_printf("The following register dump is a stub and a work-in-progress.\n");
update_asm_regs(&current_state);
serial_printf("Registers:\n");
serial_printf("\tRAX: 0x%x RBX: 0x%x RCX: 0x%x RDX: 0x%x\n",
current_state.eax, current_state.ebx, current_state.ecx,
current_state.edx);
serial_printf("\tRBP: 0x%x RSP: 0x%x RSI: 0x%x RDI: 0x%x\n",
current_state.ebp, current_state.esp, current_state.esi,
current_state.edi);
serial_printf("\tCS: 0x%x DS: 0x%x ES: 0x%x FS: 0x%x\n",
current_state.cs, current_state.ds, current_state.es,
current_state.fs);
serial_printf("\tGS: 0x%x SS: 0x%x\n", current_state.gs,
current_state.ss);
serial_printf("\tCR0: 0x%x CR2: 0x%x CR3: 0x%x CR4: 0x%x\n",
current_state.cr0, current_state.cr2, current_state.cr3,
current_state.cr4);
serial_printf("\tDR0: 0x%x DR1: 0x%x DR2: 0x%x DR3: 0x%x\n",
current_state.dr0, current_state.dr1, current_state.dr2,
current_state.dr3);
serial_printf("\tDR6: 0x%x DR7: 0x%x\n", current_state.dr6,
current_state.dr7);
serial_printf("\tGDTR: base=0x%x, limit=0x%x\n\tLDTR: base=0x%x, "
"limit=0x%x\n\tIDTR: base=0x%x, limit=0x%x\n",
current_state.gdtr.base, current_state.gdtr.limit,
current_state.ldtr.base, current_state.ldtr.limit,
current_state.idtr.base, current_state.idtr.limit);
// TODO: symbol names
serial_printf("\tRIP: 0x%x", current_state.rip);
// serial_printf("\tCode: ");
// for (int i = 0; i < 16; i++) {
// serial_printf("%x ", *(uint8_t *)(current_state.rip + i));
// }
// serial_printf("\n");
serial_printf("\n");
}

View File

@ -0,0 +1,19 @@
#include "arch/cpu/strace.h"
#include <stdint.h>
struct stackframe *strace_get() {
struct stackframe *res;
asm("movq %%rbp, %0" : "=r"(res));
return res;
}
uint64_t strace_get_framep(int sf_offset) {
struct stackframe *stack = strace_get();
// skip get_x86_stack_trace(), 0 points to this function
for (int i = 0; stack && i < sf_offset + 1; i++) {
stack = stack->sp;
}
return stack->pc;
}

View File

@ -0,0 +1,97 @@
#ifndef __ARCH_CPU_REGS
#define __ARCH_CPU_REGS
#include "amd64/cpu/tables.h"
#include <stdint.h>
typedef struct {
uint32_t eflags;
union {
struct {
uint8_t ah;
uint8_t al;
};
uint16_t ax;
uint32_t eax;
uint64_t rax;
};
union {
struct {
uint8_t bh;
uint8_t bl;
};
uint16_t bx;
uint32_t ebx;
uint64_t rbx;
};
union {
struct {
uint8_t ch;
uint8_t cl;
};
uint16_t cx;
uint32_t ecx;
uint64_t rcx;
};
union {
struct {
uint8_t dh;
uint8_t dl;
};
uint16_t dx;
uint32_t edx;
uint64_t rdx;
};
union {
uint16_t bp;
uint32_t ebp;
uint64_t rbp;
};
union {
uint16_t sp;
uint32_t esp;
uint64_t rsp;
};
union {
uint16_t si;
uint32_t esi;
uint64_t rsi;
};
union {
uint16_t di;
uint32_t edi;
uint64_t rdi;
};
uint64_t rip;
uint16_t cs;
uint16_t ds;
uint16_t es;
uint16_t fs;
uint16_t gs;
uint16_t ss;
uint32_t cr0;
uint32_t cr2;
uint32_t cr3;
uint32_t cr4;
uint32_t dr0;
uint32_t dr1;
uint32_t dr2;
uint32_t dr3;
uint32_t dr6;
uint32_t dr7;
struct desc_table gdtr;
struct desc_table ldtr;
struct desc_table idtr;
} __attribute__((packed)) asm_regs_t;
extern void update_asm_regs(asm_regs_t *state);
#endif

View File

@ -0,0 +1,15 @@
#ifndef __ARCH_CPU_TABLES
#define __ARCH_CPU_TABLES
#define DESC_TABLE_SIZE 6
#ifndef __ASSEMBLY__
#include <stdint.h>
struct desc_table {
uint16_t limit;
uint32_t base;
} __attribute__((packed));
#endif
#endif

View File

@ -0,0 +1,13 @@
#ifndef __ARCH_CPU_CONTROL
#define __ARCH_CPU_CONTROL
#include <stdbool.h>
extern bool cpu_interrupt_lock_acquired();
extern void cpu_interrupt_lock_acquire();
extern void cpu_interrupt_lock_release();
extern void cpu_interrupt_lock_force_release();
void cpu_halt();
#endif

View File

@ -0,0 +1,6 @@
#ifndef __K_SYS_CPU_STATE
#define __K_SYS_CPU_STATE
extern void cpu_state_print();
#endif

View File

@ -0,0 +1,14 @@
#ifndef __ARCH_CPU_STRACE
#define __ARCH_CPU_STRACE
#include <stdint.h>
struct stackframe {
struct stackframe *sp;
uint64_t pc;
};
extern struct stackframe *strace_get();
extern uint64_t strace_get_framep(int sf_offset);
#endif

View File

@ -0,0 +1,4 @@
#include <stdint.h>
void __attribute__((noreturn)) panic_int(uint8_t int_no, const char *msg);
void __attribute__((noreturn)) panic(const char *msg);

21
kernel/sys/panic.c Normal file
View File

@ -0,0 +1,21 @@
#include "khal.h"
#include "arch/cpu/state.h"
#include "arch/cpu/control.h"
#include <stdint.h>
// TODO: make printf-like
void __attribute__((noreturn)) panic_int(uint8_t int_no, const char *msg) {
serial_printf("\n\rKernel panic (in interrupt) [INT=0x%02X] - %s\n", int_no,
msg);
cpu_state_print();
for (;;) cpu_halt();
}
void __attribute__((noreturn)) panic(const char *msg) {
serial_printf("\n\rKernel panic - %s\n", msg);
cpu_state_print();
for (;;) cpu_halt();
}