1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub const syscall_arg_t = u64;
6
7pub fn syscall0(
8 number: SYS,
9) u64 {
10 return asm volatile ("ecall"
11 : [ret] "={x10}" (-> u64),
12 : [number] "{x17}" (@backingInt(number)),
13 : .{ .memory = true });
14}
15
16pub fn syscall1(
17 number: SYS,
18 arg1: syscall_arg_t,
19) u64 {
20 return asm volatile ("ecall"
21 : [ret] "={x10}" (-> u64),
22 : [number] "{x17}" (@backingInt(number)),
23 [arg1] "{x10}" (arg1),
24 : .{ .memory = true });
25}
26
27pub fn syscall2(
28 number: SYS,
29 arg1: syscall_arg_t,
30 arg2: syscall_arg_t,
31) u64 {
32 return asm volatile ("ecall"
33 : [ret] "={x10}" (-> u64),
34 : [number] "{x17}" (@backingInt(number)),
35 [arg1] "{x10}" (arg1),
36 [arg2] "{x11}" (arg2),
37 : .{ .memory = true });
38}
39
40pub fn syscall3(
41 number: SYS,
42 arg1: syscall_arg_t,
43 arg2: syscall_arg_t,
44 arg3: syscall_arg_t,
45) u64 {
46 return asm volatile ("ecall"
47 : [ret] "={x10}" (-> u64),
48 : [number] "{x17}" (@backingInt(number)),
49 [arg1] "{x10}" (arg1),
50 [arg2] "{x11}" (arg2),
51 [arg3] "{x12}" (arg3),
52 : .{ .memory = true });
53}
54
55pub fn syscall4(
56 number: SYS,
57 arg1: syscall_arg_t,
58 arg2: syscall_arg_t,
59 arg3: syscall_arg_t,
60 arg4: syscall_arg_t,
61) u64 {
62 return asm volatile ("ecall"
63 : [ret] "={x10}" (-> u64),
64 : [number] "{x17}" (@backingInt(number)),
65 [arg1] "{x10}" (arg1),
66 [arg2] "{x11}" (arg2),
67 [arg3] "{x12}" (arg3),
68 [arg4] "{x13}" (arg4),
69 : .{ .memory = true });
70}
71
72pub fn syscall5(
73 number: SYS,
74 arg1: syscall_arg_t,
75 arg2: syscall_arg_t,
76 arg3: syscall_arg_t,
77 arg4: syscall_arg_t,
78 arg5: syscall_arg_t,
79) u64 {
80 return asm volatile ("ecall"
81 : [ret] "={x10}" (-> u64),
82 : [number] "{x17}" (@backingInt(number)),
83 [arg1] "{x10}" (arg1),
84 [arg2] "{x11}" (arg2),
85 [arg3] "{x12}" (arg3),
86 [arg4] "{x13}" (arg4),
87 [arg5] "{x14}" (arg5),
88 : .{ .memory = true });
89}
90
91pub fn syscall6(
92 number: SYS,
93 arg1: syscall_arg_t,
94 arg2: syscall_arg_t,
95 arg3: syscall_arg_t,
96 arg4: syscall_arg_t,
97 arg5: syscall_arg_t,
98 arg6: syscall_arg_t,
99) u64 {
100 return asm volatile ("ecall"
101 : [ret] "={x10}" (-> u64),
102 : [number] "{x17}" (@backingInt(number)),
103 [arg1] "{x10}" (arg1),
104 [arg2] "{x11}" (arg2),
105 [arg3] "{x12}" (arg3),
106 [arg4] "{x13}" (arg4),
107 [arg5] "{x14}" (arg5),
108 [arg6] "{x15}" (arg6),
109 : .{ .memory = true });
110}
111
112pub fn clone() callconv(.naked) u64 {
113 // __clone(func, stack, flags, arg, ptid, tls, ctid)
114 // a0, a1, a2, a3, a4, a5, a6
115 //
116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117 // a7 a0, a1, a2, a3, a4
118 asm volatile (
119 \\ andi a1, a1, -16
120 \\ # Save func and arg to stack
121 \\ addi a1, a1, -16
122 \\ sd a0, 0(a1)
123 \\ sd a3, 8(a1)
124 \\
125 \\ # Call SYS_clone
126 \\ mv a0, a2
127 \\ mv a2, a4
128 \\ mv a3, a5
129 \\ mv a4, a6
130 \\ li a7, 220 # SYS_clone
131 \\ ecall
132 \\
133 \\ beqz a0, 1f
134 \\ # Parent
135 \\ ret
136 \\
137 \\ # Child
138 \\1:
139 );
140 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
141 \\ .cfi_undefined ra
142 );
143 asm volatile (
144 \\ mv fp, zero
145 \\ mv ra, zero
146 \\
147 \\ ld a1, 0(sp)
148 \\ ld a0, 8(sp)
149 \\ jalr a1
150 \\
151 \\ # Exit
152 \\ li a7, 93 # SYS_exit
153 \\ ecall
154 );
155}
156
157pub const time_t = i64;
158
159pub const VDSO = struct {
160 pub const CGT_SYM = "__vdso_clock_gettime";
161 pub const CGT_VER = "LINUX_4.15";
162
163 pub const HWPROBE_SYM = "__vdso_riscv_hwprobe";
164 pub const HWPROBE_VER = "LINUX_4.15";
165};