Compare commits
6 Commits
631b7729a9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 0162ce542b | |||
| 47fcd53739 | |||
| 5b7cc41d32 | |||
| 6cf0e10326 | |||
| 5afe970ff0 | |||
| 2c0b174f8e |
38
src/m1x/arch/x86_64/cpu/cpu_idt.c
Normal file
38
src/m1x/arch/x86_64/cpu/cpu_idt.c
Normal 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");
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
41
src/m1x/arch/x86_64/cpu/trap.S
Normal file
41
src/m1x/arch/x86_64/cpu/trap.S
Normal 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
|
||||
27
src/m1x/arch/x86_64/kern/panic_thunk.S
Normal file
27
src/m1x/arch/x86_64/kern/panic_thunk.S
Normal 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:
|
||||
21
src/m1x/include/arch/x86_64/gdt.h
Normal file
21
src/m1x/include/arch/x86_64/gdt.h
Normal 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_ */
|
||||
68
src/m1x/include/arch/x86_64/idt.h
Normal file
68
src/m1x/include/arch/x86_64/idt.h
Normal 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_ */
|
||||
46
src/m1x/include/arch/x86_64/prim.h
Normal file
46
src/m1x/include/arch/x86_64/prim.h
Normal 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_ */
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
26
src/m1x/include/kern/panic.h
Normal file
26
src/m1x/include/kern/panic.h
Normal 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_ */
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
28
src/m1x/kern/kern_panic.c
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user