forked from casys-kaist/pintos-kaist
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsyscall.c
46 lines (40 loc) · 1.48 KB
/
syscall.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "userprog/syscall.h"
#include <stdio.h>
#include <syscall-nr.h>
#include "threads/interrupt.h"
#include "threads/thread.h"
#include "threads/loader.h"
#include "userprog/gdt.h"
#include "threads/flags.h"
#include "intrinsic.h"
void syscall_entry (void);
void syscall_handler (struct intr_frame *);
/* System call.
*
* Previously system call services was handled by the interrupt handler
* (e.g. int 0x80 in linux). However, in x86-64, the manufacturer supplies
* efficient path for requesting the system call, the `syscall` instruction.
*
* The syscall instruction works by reading the values from the the Model
* Specific Register (MSR). For the details, see the manual. */
#define MSR_STAR 0xc0000081 /* Segment selector msr */
#define MSR_LSTAR 0xc0000082 /* Long mode SYSCALL target */
#define MSR_SYSCALL_MASK 0xc0000084 /* Mask for the eflags */
void
syscall_init (void) {
write_msr(MSR_STAR, ((uint64_t)SEL_UCSEG - 0x10) << 48 |
((uint64_t)SEL_KCSEG) << 32);
write_msr(MSR_LSTAR, (uint64_t) syscall_entry);
/* The interrupt service rountine should not serve any interrupts
* until the syscall_entry swaps the userland stack to the kernel
* mode stack. Therefore, we masked the FLAG_FL. */
write_msr(MSR_SYSCALL_MASK,
FLAG_IF | FLAG_TF | FLAG_DF | FLAG_IOPL | FLAG_AC | FLAG_NT);
}
/* The main system call interface */
void
syscall_handler (struct intr_frame *f UNUSED) {
// TODO: Your implementation goes here.
printf ("system call!\n");
thread_exit ();
}