summaryrefslogtreecommitdiff
path: root/kernel/syscall.asm
blob: 56be8a411fe182a3287c3801a5c6aec8c1825d43 (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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
bits 64

global load_gdt_and_idt
global start_user_mode

section .rodata

;0x28 picked to align with limine choice
;0x28 - kernel code
;0x30 - kernel data
;0x38 - user data
;0x40 - user code

gdtr:
  dw 0x47
  dq gdt

gdt:
  dq 0
  dq 0
  dq 0
  dq 0
  dq 0
  dq 0x00209b0000000000
  dq 0x00009b0000000000
  dq 0x0000fb0000000000
  dq 0x0020fb0000000000

idtr:
  dw 4095
  dq idt

idt:
  times 256 - ($ - idt) / 16 dq 0

section .text

load_gdt_and_idt:
  lgdt [gdtr]
  lidt [idtr]
  ret

extern syscall_encode_color

encode_color_syscall:
  call syscall_encode_color
  mov edi, eax
  xor rax, rax
  mov eax, edi
  xor rdi, rdi
  xor rsi, rsi
  xor rdx, rdx
  jmp syscall_return

extern syscall_get_fb_vaddr
extern syscall_get_fb_dims
extern syscall_get_fb_pitch

get_framebuffer_syscall:
  call syscall_get_fb_vaddr
  push rax
  call syscall_get_fb_dims
  push rax
  call syscall_get_fb_pitch
  xor rsi, rsi
  mov esi, eax
  pop rdi
  pop rax
  xor rdx, rdx
  jmp syscall_return

extern syscall_copy_framebuffer

draw_framebuffer_syscall:
  call syscall_copy_framebuffer
  xor rax, rax
  xor rdi, rdi
  xor rsi, rsi
  xor rdx, rdx
  jmp syscall_return

bad_syscall:
  xor rax, rax
  xor rdi, rdi
  xor rsi, rsi
  xor rdx, rdx
  jmp syscall_return

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

  cmp rax, 0
  je encode_color_syscall
  cmp rax, 1
  je get_framebuffer_syscall
  cmp rax, 2
  je draw_framebuffer_syscall
  jmp bad_syscall

syscall_return:
  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