nolibc header update for 5.2-rc1 (RISCV support)

This single commit adds support for the RISCV architecture to the
 nolibc header file. Currently the file is only used by rcutorture but
 Pranith Kumar who contributed it would like to have this work merged.
 
 I only did some trivial tests to verify that it does not break x86,
 which I consider sufficient since all the code is cleanly enclosed
 inside a single #if/endif block.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJc0t6sAAoJEE44bZycYXAvmnAQAJoVGH2R4jnx65QyMuEO6gYm
 oPKxG9t7scCdQfVpVQ0/IuXJde/KMdMu0MEx97pIaWiswWDY4pjMNVsvk0iSgLCo
 MQt0pNlRogMRe2EmMLRNLKU4YNdqJdbF7oR0ntXkn5OHmDUMucxk/9V+r43XiVBD
 9BWaDRZFCN36dXEEHfSwf5i0OdZu/V3MZi58z+Rw8abDzA+S9fFFDytF7E0G9tak
 KSxf0bZY9JPLfMh/qCR9gz6E2deVLylkA6cFCBARtKDT8i77o3A81/Atm6tbAdHq
 UwCuA361rj+XCN97AOS/nNasxgtxyQ8SRJV7jhNQZbevqS7h+weCEKSlFHTivPZu
 R/zNGnwe8ROb13ZoPhEU6fIG6WdySwGBBNbNodlIEHQF+jJxoOmhNajtcmSx7/bM
 B9hh6/p945GW+E2vZNo25v4r+k2Btt9uFEpUQ0cxWpIixIFrvNalOmmAhidbX2nW
 ENQT89u8k6upJ0DLgLwruqHqdVbar4qau2pKwqZvkksjdFrW8nEWh/aEyyq+8znJ
 F9Dcvtr6Q8nomAG0PqP10jfHiQf75mbw6KBBs6+OPiKa6LEfZWJqrpNNkivD0kHu
 28J5BPb83ez4ITaJqFprstvCsY95MoOrTuIj6xDfSHc5wLkRVtlQiFmS2fObVsXk
 8Q3Dxjps5U3NkJx7/ga1
 =fCdT
 -----END PGP SIGNATURE-----

Merge tag 'nolibc-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc

Pull RISC-V nolibc header update from Willy Tarreau:
 "This single commit adds support for the RISCV architecture to the
  nolibc header file. Currently the file is only used by rcutorture but
  Pranith Kumar who contributed it would like to have this work merged.

  I only did some trivial tests to verify that it does not break x86,
  which I consider sufficient since all the code is cleanly enclosed
  inside a single #if/endif block"

* tag 'nolibc-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc:
  tool headers nolibc: add RISCV support
This commit is contained in:
Linus Torvalds 2019-05-08 12:18:44 -07:00
commit 019d7316ea

View File

@ -1243,6 +1243,200 @@ struct sys_stat_struct {
long st_pad4[14];
};
#elif defined(__riscv)
#if __riscv_xlen == 64
#define PTRLOG "3"
#define SZREG "8"
#elif __riscv_xlen == 32
#define PTRLOG "2"
#define SZREG "4"
#endif
/* Syscalls for RISCV :
* - stack is 16-byte aligned
* - syscall number is passed in a7
* - arguments are in a0, a1, a2, a3, a4, a5
* - the system call is performed by calling ecall
* - syscall return comes in a0
* - the arguments are cast to long and assigned into the target
* registers which are then simply passed as registers to the asm code,
* so that we don't have to experience issues with register constraints.
*/
#define my_syscall0(num) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0"); \
\
asm volatile ( \
"ecall\n\t" \
: "=r"(_arg1) \
: "r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
#define my_syscall1(num, arg1) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0") = (long)(arg1); \
\
asm volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
#define my_syscall2(num, arg1, arg2) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0") = (long)(arg1); \
register long _arg2 asm("a1") = (long)(arg2); \
\
asm volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), \
"r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
#define my_syscall3(num, arg1, arg2, arg3) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0") = (long)(arg1); \
register long _arg2 asm("a1") = (long)(arg2); \
register long _arg3 asm("a2") = (long)(arg3); \
\
asm volatile ( \
"ecall\n\t" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), \
"r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
#define my_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0") = (long)(arg1); \
register long _arg2 asm("a1") = (long)(arg2); \
register long _arg3 asm("a2") = (long)(arg3); \
register long _arg4 asm("a3") = (long)(arg4); \
\
asm volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), "r"(_arg4), \
"r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0") = (long)(arg1); \
register long _arg2 asm("a1") = (long)(arg2); \
register long _arg3 asm("a2") = (long)(arg3); \
register long _arg4 asm("a3") = (long)(arg4); \
register long _arg5 asm("a4") = (long)(arg5); \
\
asm volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
"r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
register long _num asm("a7") = (num); \
register long _arg1 asm("a0") = (long)(arg1); \
register long _arg2 asm("a1") = (long)(arg2); \
register long _arg3 asm("a2") = (long)(arg3); \
register long _arg4 asm("a3") = (long)(arg4); \
register long _arg5 asm("a4") = (long)(arg5); \
register long _arg6 asm("a5") = (long)(arg6); \
\
asm volatile ( \
"ecall\n" \
: "+r"(_arg1) \
: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
"r"(_num) \
: "memory", "cc" \
); \
_arg1; \
})
/* startup code */
asm(".section .text\n"
".global _start\n"
"_start:\n"
".option push\n"
".option norelax\n"
"lla gp, __global_pointer$\n"
".option pop\n"
"ld a0, 0(sp)\n" // argc (a0) was in the stack
"add a1, sp, "SZREG"\n" // argv (a1) = sp
"slli a2, a0, "PTRLOG"\n" // envp (a2) = SZREG*argc ...
"add a2, a2, "SZREG"\n" // + SZREG (skip null)
"add a2,a2,a1\n" // + argv
"andi sp,a1,-16\n" // sp must be 16-byte aligned
"call main\n" // main() returns the status code, we'll exit with it.
"andi a0, a0, 0xff\n" // limit exit code to 8 bits
"li a7, 93\n" // NR_exit == 93
"ecall\n"
"");
/* fcntl / open */
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 0x100
#define O_EXCL 0x200
#define O_NOCTTY 0x400
#define O_TRUNC 0x1000
#define O_APPEND 0x2000
#define O_NONBLOCK 0x4000
#define O_DIRECTORY 0x200000
struct sys_stat_struct {
unsigned long st_dev; /* Device. */
unsigned long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
unsigned int st_nlink; /* Link count. */
unsigned int st_uid; /* User ID of the file's owner. */
unsigned int st_gid; /* Group ID of the file's group. */
unsigned long st_rdev; /* Device number, if device. */
unsigned long __pad1;
long st_size; /* Size of file, in bytes. */
int st_blksize; /* Optimal block size for I/O. */
int __pad2;
long st_blocks; /* Number 512-byte blocks allocated. */
long st_atime; /* Time of last access. */
unsigned long st_atime_nsec;
long st_mtime; /* Time of last modification. */
unsigned long st_mtime_nsec;
long st_ctime; /* Time of last status change. */
unsigned long st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
#endif