]> pd.if.org Git - zos/blob - syscalls.s
add a readme with a public domain note
[zos] / syscalls.s
1 global syscall_entry:function
2 global ksyscall:function
3
4 extern printk
5 extern allstop
6 extern need_schedule
7
8 ; syscall to kernel
9 ; syscall number in rax
10 ; fourth argument (rcx) on stack?
11 ksyscall:
12         ; syscall over-writes rcx, save it
13         push rcx
14         syscall
15         pop rcx
16         ret
17
18 %define STAR 0xC0000081
19 %define LSTAR 0xC0000082
20 %define FMASK 0xC0000084
21
22 extern enable_syscall
23
24 global init_syscalls:function
25 init_syscalls:
26         ; STAR register
27         mov ecx, STAR
28         rdmsr
29         mov edx, 0x23 ; user code segment / user data segment / 64 bit user code segment
30         shr edx, 16
31         or edx, 0x10 ; kernel code segment
32         wrmsr
33
34         ; syscall rip
35         mov rax, qword syscall_entry
36         mov rdx, qword syscall_entry
37         shr rdx, 32
38         mov ecx, LSTAR
39         wrmsr
40
41         ; rflags mask
42         mov ecx, FMASK
43         rdmsr
44         mov eax, ~0x202
45         wrmsr
46
47         ; turn on the enable bit (bit 1 of EFER, iirc)
48         call enable_syscall
49         ret
50         
51 ; still using user stack and memory map
52 ; can't use user's stack because user may lie about where it is
53 ; causing us to overwrite memory.
54
55 extern sleep
56 extern timer_ticks
57
58 syscall_entry:
59         mov dr0, rcx
60         mov dr1, rax
61         mov dr2, rdi
62
63         ; TODO switch to kernel stack
64
65         ; save values for sysret
66         push r11
67         push rcx
68         mov r10, rcx ; fourth arg in r10, since syscall clobbers rcx
69
70         push rax
71         push rdi
72         push rsi
73         mov r8, rdi
74         mov r9, rsi
75
76         mov rdi, qword sleepstr
77         mov rdx, qword timer_ticks
78         mov rsi, [rdx]
79         mov edx, 0
80         mov ecx, eax
81
82         call printk
83         pop rsi
84         pop rdi
85         pop rax
86
87         call sleep
88
89         ; syscall number in rax
90         ; rcx would be the fourth argument, but over-written by syscall
91         ; so we pass it in r10, another scratch register
92
93         ; may not need to check for schedule, the syscall itself
94         ; should do a yield if it wants to
95
96         ; need to check for schedule, could possible just do
97         ; an interrupt if it needed scheduling
98         call need_schedule
99         mov dr1, rax
100         ;call allstop
101         test eax,eax
102         jz .nosched
103         mov eax, 0x1123f982
104         mov dr0, rax
105         call allstop
106         int 0x81 ; force a schedule call, any int would do actually
107 .nosched:
108
109         mov eax, __LINE__
110         mov dr3, rax
111         mov dr2, r11
112         mov dr1, rcx
113         ;call allstop
114
115         pop rcx
116         pop r11
117         db 0x48 ; no sysretq in yasm
118         sysret
119
120 ign:
121 db      'ignoring syscall %u', 0xa, 0
122
123 sleepstr:
124         db '%u pid %u syscall %u : %u %u', 0xa, 0
125