mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
interrupt: nmi work
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include <arch/gdt.h>
|
#include <arch/gdt.h>
|
||||||
#include <kernel/dpc.h>
|
#include <kernel/dpc.h>
|
||||||
#include <arch/context.h>
|
#include <arch/context.h>
|
||||||
|
#include <arch/prof.h>
|
||||||
|
|
||||||
#define EFER_SYSCALLENABLE 1
|
#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_THREAD 1
|
||||||
#define TOPOLOGY_TYPE_CORE 2
|
#define TOPOLOGY_TYPE_CORE 2
|
||||||
#define TOPOLOGY_TYPE_PACKAGE 0xffffffff
|
#define TOPOLOGY_TYPE_PACKAGE 0xffffffff
|
||||||
@@ -237,6 +259,15 @@ void arch_cpu_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
current_cpu()->topology_node = topology_nodes[topology_depth - 1];
|
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);
|
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
|
.offset = (uint64_t)idt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void asm_nmi_handler();
|
||||||
extern const uint64_t isr_table[256];
|
extern const uint64_t isr_table[256];
|
||||||
|
|
||||||
void arch_idt_setup() {
|
void arch_idt_setup() {
|
||||||
for (int i = 0; i < 256; ++i) {
|
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].segment = 0x8;
|
||||||
idt[i].ist = 0;
|
idt[i].ist = i == 2 ? 1 : 0;
|
||||||
idt[i].flags = 0x8e;
|
idt[i].flags = 0x8e;
|
||||||
idt[i].offset2 = (isr_table[i] >> 16) & 0xffff;
|
idt[i].offset2 = (addr >> 16) & 0xffff;
|
||||||
idt[i].offset3 = (isr_table[i] >> 32) & 0xffffffff;
|
idt[i].offset3 = (addr >> 32) & 0xffffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ isr_common:
|
|||||||
mov rdi, rbp ; vec
|
mov rdi, rbp ; vec
|
||||||
mov rsi, rsp ; ctx
|
mov rsi, rsp ; ctx
|
||||||
|
|
||||||
|
; set this as the end of the stack frame
|
||||||
|
xor rbp, rbp
|
||||||
|
|
||||||
cld
|
cld
|
||||||
extern interrupt_isr
|
extern interrupt_isr
|
||||||
call interrupt_isr
|
call interrupt_isr
|
||||||
@@ -93,6 +96,78 @@ isr_common:
|
|||||||
.notneeded2:
|
.notneeded2:
|
||||||
o64 iret
|
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
|
section .rodata
|
||||||
global isr_table
|
global isr_table
|
||||||
isr_table:
|
isr_table:
|
||||||
|
|||||||
@@ -273,6 +273,9 @@ arch_syscall_entry:
|
|||||||
mov rdx, rsi
|
mov rdx, rsi
|
||||||
mov rsi, rdi
|
mov rsi, rdi
|
||||||
|
|
||||||
|
; set this as the end of the stack frame
|
||||||
|
xor rbp, rbp
|
||||||
|
|
||||||
; call logging function
|
; call logging function
|
||||||
|
|
||||||
sti
|
sti
|
||||||
|
|||||||
Reference in New Issue
Block a user