mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
interrupt: nmi work
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <arch/gdt.h>
|
||||
#include <kernel/dpc.h>
|
||||
#include <arch/context.h>
|
||||
#include <arch/prof.h>
|
||||
|
||||
#define EFER_SYSCALLENABLE 1
|
||||
|
||||
@@ -45,6 +46,27 @@ static void x87isr(isr_t *self, context_t *ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
void arch_nmi_isr(context_t *ctx) {
|
||||
// we are in an NMI context, running on IST0
|
||||
// first load the proper gsbase to get access to cpu-local variables.
|
||||
// the pointer to cpu's data is at the beggining of the stack so after the context struct.
|
||||
uint64_t old_gsbase = rdmsr(MSR_GSBASE);
|
||||
wrmsr(MSR_GSBASE, *(uint64_t *)(ctx + 1));
|
||||
|
||||
bool handled = false;
|
||||
|
||||
#ifdef ENABLE_PROFILING
|
||||
if (arch_profiling_irq(ctx))
|
||||
handled = true;
|
||||
#endif
|
||||
|
||||
if (!handled)
|
||||
_panic("Unhandled NMI", ctx);
|
||||
|
||||
// restore the old gsbase
|
||||
wrmsr(MSR_GSBASE, old_gsbase);
|
||||
}
|
||||
|
||||
#define TOPOLOGY_TYPE_THREAD 1
|
||||
#define TOPOLOGY_TYPE_CORE 2
|
||||
#define TOPOLOGY_TYPE_PACKAGE 0xffffffff
|
||||
@@ -237,6 +259,15 @@ void arch_cpu_init() {
|
||||
}
|
||||
|
||||
current_cpu()->topology_node = topology_nodes[topology_depth - 1];
|
||||
|
||||
// allocate ists
|
||||
uint64_t *ist1 = vmm_map(NULL, PAGE_SIZE * 4, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||
__assert(ist1);
|
||||
|
||||
// the cpu automatically aligns to 16 bytes when pushing the interrupt frame, so save ourselves the trouble:
|
||||
ist1 += PAGE_SIZE * 4 / sizeof(uint64_t) - 2;
|
||||
*ist1 = (uint64_t)current_cpu();
|
||||
current_cpu()->ist.ist1 = (uint64_t)ist1;
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(cpu, INIT_ROUTINE_FLAGS_NONE, arch_cpu_init, acpi_early);
|
||||
|
||||
@@ -29,16 +29,18 @@ static idtr_t idtr = {
|
||||
.offset = (uint64_t)idt
|
||||
};
|
||||
|
||||
void asm_nmi_handler();
|
||||
extern const uint64_t isr_table[256];
|
||||
|
||||
void arch_idt_setup() {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
idt[i].offset = isr_table[i] & 0xffff;
|
||||
uint64_t addr = i == 2 ? (uint64_t)asm_nmi_handler : isr_table[i];
|
||||
idt[i].offset = addr & 0xffff;
|
||||
idt[i].segment = 0x8;
|
||||
idt[i].ist = 0;
|
||||
idt[i].ist = i == 2 ? 1 : 0;
|
||||
idt[i].flags = 0x8e;
|
||||
idt[i].offset2 = (isr_table[i] >> 16) & 0xffff;
|
||||
idt[i].offset3 = (isr_table[i] >> 32) & 0xffffffff;
|
||||
idt[i].offset2 = (addr >> 16) & 0xffff;
|
||||
idt[i].offset3 = (addr >> 32) & 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ isr_common:
|
||||
mov rdi, rbp ; vec
|
||||
mov rsi, rsp ; ctx
|
||||
|
||||
; set this as the end of the stack frame
|
||||
xor rbp, rbp
|
||||
|
||||
cld
|
||||
extern interrupt_isr
|
||||
call interrupt_isr
|
||||
@@ -93,6 +96,78 @@ isr_common:
|
||||
.notneeded2:
|
||||
o64 iret
|
||||
|
||||
global asm_nmi_handler
|
||||
asm_nmi_handler:
|
||||
sub rsp, 8 ; error code, unused for nmi
|
||||
push rbp
|
||||
sub rsp, 8 ; vec number, unused for nmi
|
||||
push rsi
|
||||
push rdi
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
push r12
|
||||
push r11
|
||||
push r10
|
||||
push r9
|
||||
push r8
|
||||
push rdx
|
||||
push rcx
|
||||
push rbx
|
||||
push rax
|
||||
mov rax, ds
|
||||
push rax
|
||||
mov rax, es
|
||||
push rax
|
||||
mov rax, fs
|
||||
push rax
|
||||
mov rax, gs
|
||||
push rax
|
||||
mov rdi,cr2
|
||||
push rdi
|
||||
|
||||
; set up kernel segments
|
||||
mov rdi, 0x10
|
||||
mov ds, rdi
|
||||
mov es, rdi
|
||||
|
||||
; save ctx pointer
|
||||
mov rdi, rsp
|
||||
|
||||
; set this as the end of the stack frame
|
||||
xor rbp, rbp
|
||||
|
||||
cld
|
||||
extern arch_nmi_isr
|
||||
call arch_nmi_isr
|
||||
cli
|
||||
|
||||
; pop context
|
||||
add rsp, 24 ; cr2 gs and fs are not popped.
|
||||
pop rax
|
||||
mov es,rax
|
||||
pop rax
|
||||
mov ds,rax
|
||||
pop rax
|
||||
pop rbx
|
||||
pop rcx
|
||||
pop rdx
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
pop r11
|
||||
pop r12
|
||||
pop r13
|
||||
pop r14
|
||||
pop r15
|
||||
pop rdi
|
||||
pop rsi
|
||||
add rsp, 8 ; vector num, unused for nmi
|
||||
pop rbp
|
||||
add rsp, 8 ; error code, unused for nmi
|
||||
|
||||
o64 iret
|
||||
|
||||
section .rodata
|
||||
global isr_table
|
||||
isr_table:
|
||||
|
||||
@@ -273,6 +273,9 @@ arch_syscall_entry:
|
||||
mov rdx, rsi
|
||||
mov rsi, rdi
|
||||
|
||||
; set this as the end of the stack frame
|
||||
xor rbp, rbp
|
||||
|
||||
; call logging function
|
||||
|
||||
sti
|
||||
|
||||
Reference in New Issue
Block a user