brintos

brintos / linux-shallow public Read only

0
0
Text · 8.1 KiB · 8827bf9 Raw
158 lines · c
1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */2/*3 * RISCV (32 and 64) specific definitions for NOLIBC4 * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>5 */6 7#ifndef _NOLIBC_ARCH_RISCV_H8#define _NOLIBC_ARCH_RISCV_H9 10#include "compiler.h"11#include "crt.h"12 13/* Syscalls for RISCV :14 *   - stack is 16-byte aligned15 *   - syscall number is passed in a716 *   - arguments are in a0, a1, a2, a3, a4, a517 *   - the system call is performed by calling ecall18 *   - syscall return comes in a019 *   - the arguments are cast to long and assigned into the target20 *     registers which are then simply passed as registers to the asm code,21 *     so that we don't have to experience issues with register constraints.22 */23 24#define my_syscall0(num)                                                      \25({                                                                            \26	register long _num  __asm__ ("a7") = (num);                           \27	register long _arg1 __asm__ ("a0");                                   \28									      \29	__asm__ volatile (                                                    \30		"ecall\n\t"                                                   \31		: "=r"(_arg1)                                                 \32		: "r"(_num)                                                   \33		: "memory", "cc"                                              \34	);                                                                    \35	_arg1;                                                                \36})37 38#define my_syscall1(num, arg1)                                                \39({                                                                            \40	register long _num  __asm__ ("a7") = (num);                           \41	register long _arg1 __asm__ ("a0") = (long)(arg1);		      \42									      \43	__asm__ volatile (                                                    \44		"ecall\n"                                                     \45		: "+r"(_arg1)                                                 \46		: "r"(_num)                                                   \47		: "memory", "cc"                                              \48	);                                                                    \49	_arg1;                                                                \50})51 52#define my_syscall2(num, arg1, arg2)                                          \53({                                                                            \54	register long _num  __asm__ ("a7") = (num);                           \55	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \56	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \57									      \58	__asm__ volatile (                                                    \59		"ecall\n"                                                     \60		: "+r"(_arg1)                                                 \61		: "r"(_arg2),                                                 \62		  "r"(_num)                                                   \63		: "memory", "cc"                                              \64	);                                                                    \65	_arg1;                                                                \66})67 68#define my_syscall3(num, arg1, arg2, arg3)                                    \69({                                                                            \70	register long _num  __asm__ ("a7") = (num);                           \71	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \72	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \73	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \74									      \75	__asm__ volatile (                                                    \76		"ecall\n\t"                                                   \77		: "+r"(_arg1)                                                 \78		: "r"(_arg2), "r"(_arg3),                                     \79		  "r"(_num)                                                   \80		: "memory", "cc"                                              \81	);                                                                    \82	_arg1;                                                                \83})84 85#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \86({                                                                            \87	register long _num  __asm__ ("a7") = (num);                           \88	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \89	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \90	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \91	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \92									      \93	__asm__ volatile (                                                    \94		"ecall\n"                                                     \95		: "+r"(_arg1)                                                 \96		: "r"(_arg2), "r"(_arg3), "r"(_arg4),                         \97		  "r"(_num)                                                   \98		: "memory", "cc"                                              \99	);                                                                    \100	_arg1;                                                                \101})102 103#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \104({                                                                            \105	register long _num  __asm__ ("a7") = (num);                           \106	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \107	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \108	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \109	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \110	register long _arg5 __asm__ ("a4") = (long)(arg5);                    \111									      \112	__asm__ volatile (                                                    \113		"ecall\n"                                                     \114		: "+r"(_arg1)                                                 \115		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),             \116		  "r"(_num)                                                   \117		: "memory", "cc"                                              \118	);                                                                    \119	_arg1;                                                                \120})121 122#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \123({                                                                            \124	register long _num  __asm__ ("a7") = (num);                           \125	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \126	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \127	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \128	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \129	register long _arg5 __asm__ ("a4") = (long)(arg5);                    \130	register long _arg6 __asm__ ("a5") = (long)(arg6);                    \131									      \132	__asm__ volatile (                                                    \133		"ecall\n"                                                     \134		: "+r"(_arg1)                                                 \135		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \136		  "r"(_num)                                                   \137		: "memory", "cc"                                              \138	);                                                                    \139	_arg1;                                                                \140})141 142/* startup code */143void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)144{145	__asm__ volatile (146		".option push\n"147		".option norelax\n"148		"lla  gp, __global_pointer$\n"149		".option pop\n"150		"mv   a0, sp\n"           /* save stack pointer to a0, as arg1 of _start_c */151		"andi sp, a0, -16\n"      /* sp must be 16-byte aligned                    */152		"call _start_c\n"         /* transfer to c runtime                         */153	);154	__nolibc_entrypoint_epilogue();155}156 157#endif /* _NOLIBC_ARCH_RISCV_H */158