brintos

brintos / linux-shallow public Read only

0
0
Text · 4.9 KiB · 2ec13d8 Raw
187 lines · c
1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */2/*3 * s390 specific definitions for NOLIBC4 */5 6#ifndef _NOLIBC_ARCH_S390_H7#define _NOLIBC_ARCH_S390_H8#include <asm/signal.h>9#include <asm/unistd.h>10 11#include "compiler.h"12#include "crt.h"13 14/* Syscalls for s390:15 *   - registers are 64-bit16 *   - syscall number is passed in r117 *   - arguments are in r2-r718 *   - the system call is performed by calling the svc instruction19 *   - syscall return value is in r220 *   - r1 and r2 are clobbered, others are preserved.21 *22 * Link s390 ABI: https://github.com/IBM/s390x-abi23 *24 */25 26#define my_syscall0(num)						\27({									\28	register long _num __asm__ ("1") = (num);			\29	register long _rc __asm__ ("2");				\30									\31	__asm__ volatile (						\32		"svc 0\n"						\33		: "=d"(_rc)						\34		: "d"(_num)						\35		: "memory", "cc"					\36		);							\37	_rc;								\38})39 40#define my_syscall1(num, arg1)						\41({									\42	register long _num __asm__ ("1") = (num);			\43	register long _arg1 __asm__ ("2") = (long)(arg1);		\44									\45	__asm__ volatile (						\46		"svc 0\n"						\47		: "+d"(_arg1)						\48		: "d"(_num)						\49		: "memory", "cc"					\50		);							\51	_arg1;								\52})53 54#define my_syscall2(num, arg1, arg2)					\55({									\56	register long _num __asm__ ("1") = (num);			\57	register long _arg1 __asm__ ("2") = (long)(arg1);		\58	register long _arg2 __asm__ ("3") = (long)(arg2);		\59									\60	__asm__ volatile (						\61		"svc 0\n"						\62		: "+d"(_arg1)						\63		: "d"(_arg2), "d"(_num)					\64		: "memory", "cc"					\65		);							\66	_arg1;								\67})68 69#define my_syscall3(num, arg1, arg2, arg3)				\70({									\71	register long _num __asm__ ("1") = (num);			\72	register long _arg1 __asm__ ("2") = (long)(arg1);		\73	register long _arg2 __asm__ ("3") = (long)(arg2);		\74	register long _arg3 __asm__ ("4") = (long)(arg3);		\75									\76	__asm__ volatile (						\77		"svc 0\n"						\78		: "+d"(_arg1)						\79		: "d"(_arg2), "d"(_arg3), "d"(_num)			\80		: "memory", "cc"					\81		);							\82	_arg1;								\83})84 85#define my_syscall4(num, arg1, arg2, arg3, arg4)			\86({									\87	register long _num __asm__ ("1") = (num);			\88	register long _arg1 __asm__ ("2") = (long)(arg1);		\89	register long _arg2 __asm__ ("3") = (long)(arg2);		\90	register long _arg3 __asm__ ("4") = (long)(arg3);		\91	register long _arg4 __asm__ ("5") = (long)(arg4);		\92									\93	__asm__ volatile (						\94		"svc 0\n"						\95		: "+d"(_arg1)						\96		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_num)		\97		: "memory", "cc"					\98		);							\99	_arg1;								\100})101 102#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)			\103({									\104	register long _num __asm__ ("1") = (num);			\105	register long _arg1 __asm__ ("2") = (long)(arg1);		\106	register long _arg2 __asm__ ("3") = (long)(arg2);		\107	register long _arg3 __asm__ ("4") = (long)(arg3);		\108	register long _arg4 __asm__ ("5") = (long)(arg4);		\109	register long _arg5 __asm__ ("6") = (long)(arg5);		\110									\111	__asm__ volatile (						\112		"svc 0\n"						\113		: "+d"(_arg1)						\114		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_arg5),	\115		  "d"(_num)						\116		: "memory", "cc"					\117		);							\118	_arg1;								\119})120 121#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)		\122({									\123	register long _num __asm__ ("1") = (num);			\124	register long _arg1 __asm__ ("2") = (long)(arg1);		\125	register long _arg2 __asm__ ("3") = (long)(arg2);		\126	register long _arg3 __asm__ ("4") = (long)(arg3);		\127	register long _arg4 __asm__ ("5") = (long)(arg4);		\128	register long _arg5 __asm__ ("6") = (long)(arg5);		\129	register long _arg6 __asm__ ("7") = (long)(arg6);		\130									\131	__asm__ volatile (						\132		"svc 0\n"						\133		: "+d"(_arg1)						\134		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_arg5),	\135		  "d"(_arg6), "d"(_num)					\136		: "memory", "cc"					\137		);							\138	_arg1;								\139})140 141/* startup code */142void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)143{144	__asm__ volatile (145		"lgr	%r2, %r15\n"          /* save stack pointer to %r2, as arg1 of _start_c */146		"aghi	%r15, -160\n"         /* allocate new stackframe                        */147		"xc	0(8,%r15), 0(%r15)\n" /* clear backchain                                */148		"brasl	%r14, _start_c\n"     /* transfer to c runtime                          */149	);150	__nolibc_entrypoint_epilogue();151}152 153struct s390_mmap_arg_struct {154	unsigned long addr;155	unsigned long len;156	unsigned long prot;157	unsigned long flags;158	unsigned long fd;159	unsigned long offset;160};161 162static __attribute__((unused))163void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,164	       off_t offset)165{166	struct s390_mmap_arg_struct args = {167		.addr = (unsigned long)addr,168		.len = (unsigned long)length,169		.prot = prot,170		.flags = flags,171		.fd = fd,172		.offset = (unsigned long)offset173	};174 175	return (void *)my_syscall1(__NR_mmap, &args);176}177#define sys_mmap sys_mmap178 179static __attribute__((unused))180pid_t sys_fork(void)181{182	return my_syscall5(__NR_clone, 0, SIGCHLD, 0, 0, 0);183}184#define sys_fork sys_fork185 186#endif /* _NOLIBC_ARCH_S390_H */187