Initial Commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#include <stdint.h>
|
||||
#include "stdio.h"
|
||||
#include "fs/vfs.h"
|
||||
|
||||
#define MSR_EFER 0xC0000080
|
||||
#define MSR_STAR 0xC0000081
|
||||
#define MSR_LSTAR 0xC0000082
|
||||
#define MSR_SFMASK 0xC0000084
|
||||
|
||||
#define EFER_SCE (1 << 0)
|
||||
|
||||
static inline void wrmsr(uint32_t msr, uint64_t value)
|
||||
{
|
||||
uint32_t lo = value & 0xFFFFFFFF;
|
||||
uint32_t hi = value >> 32;
|
||||
|
||||
asm volatile("wrmsr"
|
||||
:
|
||||
: "c"(msr), "a"(lo), "d"(hi));
|
||||
}
|
||||
|
||||
static inline uint64_t rdmsr(uint32_t msr)
|
||||
{
|
||||
uint32_t lo, hi;
|
||||
asm volatile("rdmsr"
|
||||
: "=a"(lo), "=d"(hi)
|
||||
: "c"(msr));
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
}
|
||||
|
||||
void syscall_handler(uint64_t rax, // syscall num
|
||||
uint64_t rdi, // arg1
|
||||
uint64_t rsi, // arg2
|
||||
uint64_t rdx, // arg3
|
||||
uint64_t r10, // arg4
|
||||
uint64_t r8, // arg5
|
||||
uint64_t r9) // arg6
|
||||
{
|
||||
switch (rax)
|
||||
{
|
||||
case 1: // write (int fd, const void *buf, size_t count);
|
||||
int c = (char)rdi;
|
||||
printf("%c", c);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// exit
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void syscall_init(void)
|
||||
{
|
||||
extern void syscall_entry(void);
|
||||
|
||||
uint64_t kernel_cs = 0x08;
|
||||
uint64_t user_cs = 0x1B;
|
||||
|
||||
uint64_t star =
|
||||
((uint64_t)kernel_cs << 32) |
|
||||
((uint64_t)user_cs << 48);
|
||||
|
||||
wrmsr(MSR_STAR, star);
|
||||
|
||||
wrmsr(MSR_LSTAR, (uint64_t)syscall_entry);
|
||||
|
||||
uint64_t efer = rdmsr(MSR_EFER);
|
||||
efer |= (1 << 0); // SYSCALL/SYSRET enable
|
||||
wrmsr(MSR_EFER, efer);
|
||||
|
||||
// disable interrupts on syscall entry
|
||||
wrmsr(MSR_SFMASK, (1 << 9));
|
||||
}
|
||||
Reference in New Issue
Block a user