mirror of
https://github.com/CIS-osdev/kernel
synced 2025-03-12 20:22:55 +03:00
Made proper structure for arch-specific code; added panic
This commit is contained in:
parent
309be28067
commit
be052c9ce7
68
kernel/arch/amd64/cpu/control.c
Normal file
68
kernel/arch/amd64/cpu/control.c
Normal 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");
|
||||
}
|
26
kernel/arch/amd64/cpu/regs.S
Normal file
26
kernel/arch/amd64/cpu/regs.S
Normal 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__
|
11
kernel/arch/amd64/cpu/regs.c
Normal file
11
kernel/arch/amd64/cpu/regs.c
Normal 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;
|
||||
}
|
47
kernel/arch/amd64/cpu/state.c
Normal file
47
kernel/arch/amd64/cpu/state.c
Normal 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(¤t_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");
|
||||
}
|
19
kernel/arch/amd64/cpu/strace.c
Normal file
19
kernel/arch/amd64/cpu/strace.c
Normal 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;
|
||||
}
|
97
kernel/arch/include/amd64/cpu/regs.h
Normal file
97
kernel/arch/include/amd64/cpu/regs.h
Normal 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
|
15
kernel/arch/include/amd64/cpu/tables.h
Normal file
15
kernel/arch/include/amd64/cpu/tables.h
Normal 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
|
13
kernel/include/arch/cpu/control.h
Normal file
13
kernel/include/arch/cpu/control.h
Normal 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
|
6
kernel/include/arch/cpu/state.h
Normal file
6
kernel/include/arch/cpu/state.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __K_SYS_CPU_STATE
|
||||
#define __K_SYS_CPU_STATE
|
||||
|
||||
extern void cpu_state_print();
|
||||
|
||||
#endif
|
14
kernel/include/arch/cpu/strace.h
Normal file
14
kernel/include/arch/cpu/strace.h
Normal 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
|
4
kernel/include/sys/panic.h
Normal file
4
kernel/include/sys/panic.h
Normal 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
21
kernel/sys/panic.c
Normal 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();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user