kernel: implement panic()
This commit is contained in:
9
arch/x86_64/include/socks/machine/panic.h
Normal file
9
arch/x86_64/include/socks/machine/panic.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef SOCKS_X86_64_PANIC_H_
|
||||
#define SOCKS_X86_64_PANIC_H_
|
||||
|
||||
struct cpu_context;
|
||||
|
||||
extern void ml_print_cpu_state(struct cpu_context *ctx);
|
||||
extern void ml_print_stack_trace(struct cpu_context *ctx);
|
||||
|
||||
#endif
|
||||
118
arch/x86_64/panic.c
Normal file
118
arch/x86_64/panic.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <socks/printk.h>
|
||||
#include <socks/libc/stdio.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#define R_CF 0
|
||||
#define R_PF 2
|
||||
#define R_AF 4
|
||||
#define R_ZF 6
|
||||
#define R_SF 7
|
||||
#define R_TF 8
|
||||
#define R_IF 9
|
||||
#define R_DF 10
|
||||
#define R_OF 11
|
||||
#define R_NT 14
|
||||
#define R_VM 17
|
||||
#define R_AC 18
|
||||
#define R_VIF 19
|
||||
#define R_VIP 20
|
||||
#define R_ID 21
|
||||
#define R_MAX 21
|
||||
|
||||
const char *pf_rfl_name(int bit)
|
||||
{
|
||||
switch (bit) {
|
||||
case R_CF:
|
||||
return "CF";
|
||||
case R_PF:
|
||||
return "PF";
|
||||
case R_AF:
|
||||
return "AF";
|
||||
case R_ZF:
|
||||
return "ZF";
|
||||
case R_SF:
|
||||
return "SF";
|
||||
case R_TF:
|
||||
return "TF";
|
||||
case R_IF:
|
||||
return "IF";
|
||||
case R_DF:
|
||||
return "DF";
|
||||
case R_OF:
|
||||
return "OF";
|
||||
case R_NT:
|
||||
return "NT";
|
||||
case R_VM:
|
||||
return "VM";
|
||||
case R_AC:
|
||||
return "AC";
|
||||
case R_VIF:
|
||||
return "VIF";
|
||||
case R_VIP:
|
||||
return "VIP";
|
||||
case R_ID:
|
||||
return "ID";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int pf_rfl_iopl(uint64_t flags)
|
||||
{
|
||||
int mask = 0x3000;
|
||||
int val = flags & mask;
|
||||
return val >> 12;
|
||||
}
|
||||
|
||||
static void print_rflags(uintptr_t rflags)
|
||||
{
|
||||
char buf[128];
|
||||
size_t buf_i = 0;
|
||||
|
||||
buf_i += snprintf(buf, sizeof(buf), " rfl %08lx [", rflags);
|
||||
|
||||
for (int i = 0; i < R_MAX; i++) {
|
||||
if (rflags & (1 << i)) {
|
||||
const char *name = pf_rfl_name(i);
|
||||
if (name) {
|
||||
buf_i += snprintf(buf + buf_i, sizeof(buf) - buf_i, " %s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf + buf_i, sizeof(buf) - buf_i, " ]");
|
||||
printk(buf);
|
||||
}
|
||||
|
||||
void ml_print_cpu_state(struct cpu_context *ctx)
|
||||
{
|
||||
printk("cpu state:");
|
||||
if (ctx) {
|
||||
printk(" rax %016lx rbx %016lx rcx %016x",
|
||||
ctx->rax, ctx->rbx, ctx->rcx);
|
||||
printk(" rdx %016lx rsi %016lx rdi %016x",
|
||||
ctx->rdx, ctx->rsi, ctx->rdi);
|
||||
printk(" rsp %016lx rbp %016lx r8 %016x",
|
||||
ctx->rsp, ctx->rbp, ctx->r8);
|
||||
printk(" r9 %016lx r10 %016lx r11 %016x",
|
||||
ctx->r9, ctx->r10, ctx->r11);
|
||||
printk(" r12 %016lx r13 %016lx r14 %016x",
|
||||
ctx->r12, ctx->r13, ctx->r14);
|
||||
printk(" r15 %016lx rip %016lx cs %04x ss %04x",
|
||||
ctx->r15, ctx->rip, ctx->cs, ctx->ss);
|
||||
print_rflags(ctx->rflags);
|
||||
}
|
||||
|
||||
uintptr_t cr0 = 0, cr2 = 0, cr3 = 0, cr4 = 0;
|
||||
asm volatile("mov %%cr0, %%rax" : "=a" (cr0));
|
||||
asm volatile("mov %%cr2, %%rax" : "=a" (cr2));
|
||||
asm volatile("mov %%cr3, %%rax" : "=a" (cr3));
|
||||
asm volatile("mov %%cr4, %%rax" : "=a" (cr4));
|
||||
printk(" cr0 %016x cr2 %016x", cr0, cr2);
|
||||
printk(" cr3 %016x cr4 %016x", cr3, cr4);
|
||||
}
|
||||
|
||||
void ml_print_stack_trace(struct cpu_context *ctx)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -21,15 +21,18 @@ void write_once(volatile T *ptr, T value)
|
||||
#endif
|
||||
|
||||
#undef __used
|
||||
#define __used __attribute__((used))
|
||||
#define __used __attribute__((__used__))
|
||||
|
||||
#undef __noreturn
|
||||
#define __noreturn __attribute__((__noreturn__))
|
||||
|
||||
#undef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#define __packed __attribute__((__packed__))
|
||||
|
||||
#undef __section
|
||||
#define __section(name) __attribute__((section(name)))
|
||||
#define __section(name) __attribute__((__section__(name)))
|
||||
|
||||
#undef __aligned
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
#define __aligned(x) __attribute__((__aligned__(x)))
|
||||
|
||||
#endif
|
||||
|
||||
8
include/socks/panic.h
Normal file
8
include/socks/panic.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef SOCKS_PANIC_H_
|
||||
#define SOCKS_PANIC_H_
|
||||
|
||||
#include <socks/compiler.h>
|
||||
|
||||
extern void __noreturn panic(const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
42
kernel/panic.c
Normal file
42
kernel/panic.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <stdarg.h>
|
||||
#include <socks/machine/panic.h>
|
||||
#include <socks/libc/stdio.h>
|
||||
#include <socks/printk.h>
|
||||
#include <socks/sched.h>
|
||||
#include <socks/cpu.h>
|
||||
|
||||
static int has_panicked = 0;
|
||||
|
||||
void panic(const char *fmt, ...)
|
||||
{
|
||||
char buf[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
printk("---[ kernel panic: %s", buf);
|
||||
printk("kernel: " BUILD_ID ", compiler version: " __VERSION__);
|
||||
|
||||
task_t *task = current_task();
|
||||
thread_t *thr = current_thread();
|
||||
|
||||
if (task && thr) {
|
||||
printk("task: %s (id: %d, thread: %d)", task->t_name, task->t_id, thr->tr_id);
|
||||
} else {
|
||||
printk("task: [bootstrap]");
|
||||
}
|
||||
|
||||
printk("cpu: %u", this_cpu());
|
||||
|
||||
ml_print_cpu_state(NULL);
|
||||
|
||||
if (READ_ONCE(has_panicked)) {
|
||||
ml_halt_cpu();
|
||||
}
|
||||
|
||||
WRITE_ONCE(has_panicked, 1);
|
||||
|
||||
printk("---[ end kernel panic: %s", buf);
|
||||
ml_halt_cpu();
|
||||
}
|
||||
Reference in New Issue
Block a user