Compare commits

...

6 Commits

Author SHA1 Message Date
0162ce542b m1x/x86_64 + kern: Add panic() implementation
Signed-off-by: Ian Moffett <ian@mirocom.org>
2026-03-25 23:07:55 -04:00
47fcd53739 m1x/x86_64: Implement processor primitives
Signed-off-by: Ian Moffett <ian@mirocom.org>
2026-03-25 22:15:46 -04:00
5b7cc41d32 m1x/x86_64: Add trap management groundwork
Signed-off-by: Ian Moffett <ian@mirocom.org>
2026-03-25 19:30:45 -04:00
6cf0e10326 m1x/x86_64: idt: Make idt.h assembly friendly
Signed-off-by: Ian Moffett <ian@mirocom.org>
2026-03-25 19:30:09 -04:00
5afe970ff0 m1x/x86_64: Add interrupt descriptor table groundwork
Signed-off-by: Ian Moffett <ian@mirocom.org>
2026-03-25 19:18:45 -04:00
2c0b174f8e m1x/x86_64: Add GDT related definitions
Signed-off-by: Ian Moffett <ian@mirocom.org>
2026-03-25 19:18:45 -04:00
12 changed files with 312 additions and 1 deletions

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#include <machine/idt.h>
#include <machine/gdt.h>
__align(8) static struct idt_gate idt[256];
static struct idtr idtr = {
.limit = sizeof(idt) - 1,
.base = (uintptr_t)&idt[0]
};
void
md_idt_gate_set(uint8_t vector, uintptr_t isr, uint8_t ist, uint8_t type)
{
struct idt_gate *gate;
gate = &idt[vector];
gate->offset_low = (isr & 0xFFFF);
gate->offset_mid = (isr >> 16) & 0xFFFF;
gate->offset_high = (isr >> 32) & 0xFFFFFFFF;
gate->p = 1;
gate->dpl = (type == IDT_USER_GATE) ? 3 : 0;
gate->zero = 0;
gate->zero1 = 0;
gate->reserved = 0;
gate->type = type;
gate->ist = ist;
gate->segment_sel = GDT_KCODE;
}
void
md_idt_load(void)
{
__asmv("lidt %0" :: "m" (idtr) : "memory");
}

View File

@@ -4,6 +4,7 @@
*/
#include <sys/types.h>
#include <machine/idt.h>
/* From cpu/locore.S */
extern void md_cpu_lgdt(void *gdtr);
@@ -14,4 +15,10 @@ hal_cpu_init(void)
{
/* Load the GDT */
md_cpu_lgdt(g_GDTR);
/* Populate the IDT with entries */
md_idt_fill();
/* Load the IDT */
md_idt_load();
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#include <machine/frameasm.h>
#include <machine/idt.h>
.macro set_trap vector, isr, ist
mov $\vector, %rdi
lea \isr(%rip), %rsi
mov $\ist, %rdx
mov $IDT_TRAP_GATE, %rcx
call md_idt_gate_set
.endm
.text
.globl md_idt_fill
md_idt_fill:
push %r12
push %r13
push %r14
push %r15
push %rbx
set_trap 0x00, diverr, 0
pop %rbx
pop %r15
pop %r14
pop %r13
pop %r12
retq
.align 8
diverr:
FRAME_PREAMBLE
mov %rsp, %rdi
1: cli
hlt
jmp 1b

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
.text
.globl panic
.extern __panic
panic:
mov $1, %rax /* Lock ourselves */
xchg %rax, __mp_sync /* -> __mp_sync */
testq $1, %rax /* Are we another processor? */
jnz panic_lockout /* Yes, enter lockout */
lea stack_top(%rip), %rsp /* Load a sane stack */
jmp __panic
panic_lockout:
cli
hlt
jmp panic_lockout
.section .data
__mp_sync: .quad 0
.align 8
.section .bss
stack: .fill 4096, 1, 0
stack_top:

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#ifndef _MACHINE_GDT_H_
#define _MACHINE_GDT_H_ 1
/* Kernel code/data */
#define GDT_KCODE 0x08
#define GDT_KDATA 0x10
/* User code/data */
#define GDT_UCODE 0x18
#define GDT_UDATA 0x20
/* Task state segment */
#define GDT_TSS 0x28
#define GDT_TSS_INDEX 0x05
#endif /* !_MACHINE_GDT_H_ */

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#ifndef _MACHINE_IDT_H_
#define _MACHINE_IDT_H_ 1
#ifndef __ASSEMBLER__
#include <sys/types.h>
#include <sys/cdefs.h>
#endif /* !__ASSEMBLER__ */
#define IDT_INT_GATE 0x8E
#define IDT_TRAP_GATE 0x8F
#define IDT_USER_GATE 0xEE
#ifndef __ASSEMBLER__
/*
* Represents an interrupt descriptor table gate
* entry
*/
struct idt_gate {
uint16_t offset_low;
uint16_t segment_sel;
uint8_t ist : 3;
uint8_t zero : 5;
uint8_t type : 4;
uint8_t zero1 : 1;
uint8_t dpl : 2;
uint8_t p : 1;
uint16_t offset_mid;
uint32_t offset_high;
uint32_t reserved;
};
/*
* References an interrupt descriptor table
*/
struct __packed idtr {
uint16_t limit;
uintptr_t base;
};
/*
* Set an entry in the interrupt descriptor table
*
* @vector: Interrupt vector to set
* @isr: Interrupt service routine base
* @ist: Interrupt stack table
* @type: Interrupt gate type
*/
void md_idt_gate_set(uint8_t vector, uintptr_t isr, uint8_t ist, uint8_t type);
/*
* Fill the interrupt descriptor table with IDT gate
* entries
*/
void md_idt_fill(void);
/*
* Load the interrupt descriptor table register
*/
void md_idt_load(void);
#endif /* !__ASSEMBLER__ */
#endif /* !_MACHINE_IDT_H_ */

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#ifndef _MACHINE_PRIM_H_
#define _MACHINE_PRIM_H_ 1
#include <sys/types.h>
#include <sys/cdefs.h>
/* Hint to the processor that we are in a spinloop */
#define hal_cpu_spinwait() \
__asmv("pause" ::: "memory")
/* Halt the current processor core */
#define hal_cpu_halt() \
__asmv("hlt" ::: "memory")
/*
* Atomic swap operation
*
* @p: Location to swap with `v`
* @v: Value to swap to `p`
*/
__always_inline static inline size_t
hal_cpu_aswap(size_t *p, size_t v)
{
size_t vret;
if (p == NULL) {
return 0;
}
vret = *(volatile size_t *)p;
__asmv(
"xchg %0, %1\n"
: "+m" (*p), "+r" (v)
:
: "memory"
);
return vret;
}
#endif /* !_MACHINE_PRIM_H_ */

View File

@@ -6,6 +6,12 @@
#ifndef _HAL_CPU_H_
#define _HAL_CPU_H_ 1
/*
* Each architecture is to implement their own version
* of the standard processor primitives.
*/
#include <machine/prim.h>
/*
* Initialize the current processor
*/

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#ifndef _KERN_PANIC_H_
#define _KERN_PANIC_H_ 1
#include <sys/cdefs.h>
#include <stdarg.h>
/*
* Signal to the user that something went seriously wrong and
* cease all system operation.
*/
__no_return void panic(const char *fmt, ...);
/*
* Central panic handler
*
* XXX: This function should not be called directly! Use the
* panic() function instead.
*/
__no_return void __panic(const char *fmt, ...);
#endif /* !_KERN_PANIC_H_ */

View File

@@ -17,6 +17,7 @@ CFLAGS = \
-MMD \
-I../../sdk/include/ \
-I../include/ \
-I../target/ \
-I../foreign/flanterm/src \
-DPRINTF_DISABLE_SUPPORT_PTRDIFF_T \
-DPRINTF_DISABLE_SUPPORT_FLOAT \

View File

@@ -4,6 +4,7 @@
*/
#include <dev/cons/cons.h>
#include <kern/panic.h>
#include <lib/printf.h>
#include <hal/cpu.h>
@@ -35,5 +36,6 @@ kmain(void)
/* Initialize the BSP */
hal_cpu_init();
for (;;);
panic("end of kernel\n");
__builtin_unreachable();
}

28
src/m1x/kern/kern_panic.c Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2026, Mirocom Laboratories
* Provided under the BSD-3 clause
*/
#include <kern/panic.h>
#include <lib/printf.h>
#include <hal/cpu.h>
/*
* Even though the stack is guaranteed to be sane upon entry,
* it would still be wise to minimize its usage and therefore
* rely on globals.
*/
static char panic_buf[128];
static va_list panic_ap;
__no_return void
__panic(const char *fmt, ...)
{
va_start(panic_ap, fmt);
vsnprintf(panic_buf, sizeof(panic_buf), fmt, panic_ap);
printf("\033[31;40mpanic\033[0m: %s", panic_buf);
for (;;) {
hal_cpu_halt();
}
}