summaryrefslogtreecommitdiff
path: root/kernel/syscall.asm
blob: c293402580ad52cea3fec9bf6d87a870ca94f31a (plain) (blame)
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
bits 64

global start_user_mode

section .text

extern do_syscall

syscall_entry:
  mov r11, rsp
  mov rsp, 0xfffffffffffff000
  push r11
  push rcx

  push rdx
  push rsi
  push rdi
  push rax

  mov rdi, rsp
  lea rsi, [rsp + 8]
  lea rdx, [rsp + 16]
  lea rcx, [rsp + 24]

  call do_syscall

  pop rax
  pop rdi
  pop rsi
  pop rdx

  xor r8, r8
  xor r9, r9
  xor r10, r10
  xor r11, r11
  or r11, 0x200
  pop rcx
  pop rsp

  o64 sysret

start_user_mode:
;intended rip in rdi
;intended rsp in rsi
;intended p4_paddr in rdx

  mov rax, rdx
  mov cr3, rax

  ;efer <- efer | 0x1
  mov rcx, 0xc0000080
  rdmsr
  or al, 1
  wrmsr

  ;lstar <- syscall_entry
  mov rdx, syscall_entry
  mov eax, edx
  shr rdx, 32
  mov ecx, 0xc0000082
  wrmsr

  ;star <- 0x0030.0028.0000.0000
  mov edx, 0x00300028
  xor eax, eax
  mov ecx, 0xc0000081
  wrmsr

  mov rcx, rdi
  mov rsp, rsi
  xor r11, r11
  or r11, 0x200

  xor rax, rax
  xor rbx, rbx
  xor rdx, rdx
  xor rdi, rdi
  xor rsi, rsi
  xor rbp, rbp
  xor r8, r8
  xor r9, r9
  xor r10, r10
  xor r12, r12
  xor r13, r13
  xor r14, r14
  xor r15, r15

  o64 sysret