SYSCALL looks interruptible enough to me
This commit is contained in:
@@ -9,6 +9,7 @@ CFLAGS+=-Wall \
|
||||
-Wno-unused-variable \
|
||||
-Wno-language-extension-token \
|
||||
-Wno-gnu-zero-variadic-macro-arguments \
|
||||
-O0 \
|
||||
-ggdb
|
||||
|
||||
ifdef KERNEL_TEST_MODE
|
||||
|
||||
@@ -10,4 +10,14 @@
|
||||
#define get_cpu(off) \
|
||||
(cpu + off)(%rip)
|
||||
#endif
|
||||
|
||||
// To be used in interrupt handlers
|
||||
// DIRECTLY AFTER ENTRY without prior stack modification
|
||||
.macro swapgs_if_needed
|
||||
cmpq $0x08, 0x08(%rsp)
|
||||
je 1f
|
||||
swapgs
|
||||
1:
|
||||
.endm
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,7 @@ struct cpu {
|
||||
struct thread *thread; // 0x08
|
||||
uint64_t ticks; // 0x10
|
||||
amd64_tss_t *tss; // 0x18
|
||||
uint64_t syscall_rsp; // 0x20
|
||||
|
||||
// No need to define offsets for these: ther're not accessed
|
||||
// from assembly
|
||||
|
||||
+8
-2
@@ -5,7 +5,13 @@
|
||||
|
||||
amd64_irq0:
|
||||
cli
|
||||
swapgs
|
||||
// Stack:
|
||||
// ss
|
||||
// rsp
|
||||
// rflags
|
||||
// cs
|
||||
// rip
|
||||
swapgs_if_needed
|
||||
|
||||
// Interrupt entry:
|
||||
// rsp should be one of the following:
|
||||
@@ -45,7 +51,7 @@ amd64_irq0:
|
||||
|
||||
irq_pop_ctx
|
||||
|
||||
swapgs
|
||||
swapgs_if_needed
|
||||
iretq
|
||||
|
||||
_fmt0:
|
||||
|
||||
+24
-3
@@ -18,16 +18,37 @@ static char t_stack3[IDLE_STACK * AMD64_MAX_SMP] = {0};
|
||||
#endif
|
||||
static struct thread t_idle[AMD64_MAX_SMP] = {0};
|
||||
|
||||
void func0(uintptr_t id, int state) {
|
||||
uint16_t attr = (id + 0x2) << 8;
|
||||
uint16_t letter = '0' + id;
|
||||
*((uint16_t *) MM_VIRTUALIZE(0xB8000) + 80 * 0 + id) = state * attr | letter;
|
||||
asm volatile ("syscall");
|
||||
}
|
||||
|
||||
void idle_func(uintptr_t id) {
|
||||
#if defined(AMD64_IDLE_RING3)
|
||||
int state = 0;
|
||||
uint16_t attr = (id + 0x2) << 8;
|
||||
uint16_t letter = '0' + id;
|
||||
uintptr_t a0 = 0, a1 = 0;
|
||||
|
||||
*((uint16_t *) MM_VIRTUALIZE(0xB8000) + 80 * 1 + id) = (id + 'A') | ((id + 0x9) << 8);
|
||||
|
||||
{
|
||||
register uintptr_t rsp asm ("rsp");
|
||||
a0 = rsp;
|
||||
}
|
||||
asm volatile ("syscall");
|
||||
{
|
||||
register uintptr_t rsp asm ("rsp");
|
||||
a1 = rsp;
|
||||
}
|
||||
|
||||
if (a0 != a1) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
*((uint16_t *) MM_VIRTUALIZE(0xB8000) + 80 * 23 + id) = state * attr | letter;
|
||||
func0(id, state);
|
||||
asm volatile ("syscall");
|
||||
state = !state;
|
||||
for (size_t i = 0; i < 10000000; ++i);
|
||||
}
|
||||
|
||||
+32
-1
@@ -1,3 +1,5 @@
|
||||
#include "sys/amd64/asm/asm_cpu.h"
|
||||
|
||||
.section .text
|
||||
.global amd64_syscall_init
|
||||
|
||||
@@ -40,5 +42,34 @@ amd64_syscall_init:
|
||||
|
||||
// Entrypoint of SYSCALL instruction
|
||||
amd64_syscall_entry:
|
||||
xchgw %bx, %bx
|
||||
// R11 = rflags3
|
||||
// RSP = rsp3
|
||||
// RCX = rip3
|
||||
|
||||
swapgs
|
||||
|
||||
// // 1. Switch to kernel context
|
||||
// // 1.1. Store rsp3 in CPU struct
|
||||
movq %rsp, get_cpu(0x20)
|
||||
// 1.2. Load rsp0 from CPU struct
|
||||
movq get_cpu(0x08), %rsp
|
||||
movq (%rsp), %rsp
|
||||
|
||||
pushq %rax
|
||||
movq get_cpu(0x20), %rax
|
||||
pushq %rax
|
||||
|
||||
movq $100000000, %rax
|
||||
sti
|
||||
|
||||
1:
|
||||
decq %rax
|
||||
jnz 1b
|
||||
cli
|
||||
|
||||
popq %rdi
|
||||
popq %rax
|
||||
movq %rdi, %rsp
|
||||
|
||||
swapgs
|
||||
sysretq
|
||||
|
||||
Reference in New Issue
Block a user