diff options
| -rw-r--r-- | tools/include/nolibc/nolibc.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h index 1708e9f9f8aa..2551e9b71167 100644 --- a/tools/include/nolibc/nolibc.h +++ b/tools/include/nolibc/nolibc.h | |||
| @@ -1243,6 +1243,200 @@ struct sys_stat_struct { | |||
| 1243 | long st_pad4[14]; | 1243 | long st_pad4[14]; |
| 1244 | }; | 1244 | }; |
| 1245 | 1245 | ||
| 1246 | #elif defined(__riscv) | ||
| 1247 | |||
| 1248 | #if __riscv_xlen == 64 | ||
| 1249 | #define PTRLOG "3" | ||
| 1250 | #define SZREG "8" | ||
| 1251 | #elif __riscv_xlen == 32 | ||
| 1252 | #define PTRLOG "2" | ||
| 1253 | #define SZREG "4" | ||
| 1254 | #endif | ||
| 1255 | |||
| 1256 | /* Syscalls for RISCV : | ||
| 1257 | * - stack is 16-byte aligned | ||
| 1258 | * - syscall number is passed in a7 | ||
| 1259 | * - arguments are in a0, a1, a2, a3, a4, a5 | ||
| 1260 | * - the system call is performed by calling ecall | ||
| 1261 | * - syscall return comes in a0 | ||
| 1262 | * - the arguments are cast to long and assigned into the target | ||
| 1263 | * registers which are then simply passed as registers to the asm code, | ||
| 1264 | * so that we don't have to experience issues with register constraints. | ||
| 1265 | */ | ||
| 1266 | |||
| 1267 | #define my_syscall0(num) \ | ||
| 1268 | ({ \ | ||
| 1269 | register long _num asm("a7") = (num); \ | ||
| 1270 | register long _arg1 asm("a0"); \ | ||
| 1271 | \ | ||
| 1272 | asm volatile ( \ | ||
| 1273 | "ecall\n\t" \ | ||
| 1274 | : "=r"(_arg1) \ | ||
| 1275 | : "r"(_num) \ | ||
| 1276 | : "memory", "cc" \ | ||
| 1277 | ); \ | ||
| 1278 | _arg1; \ | ||
| 1279 | }) | ||
| 1280 | |||
| 1281 | #define my_syscall1(num, arg1) \ | ||
| 1282 | ({ \ | ||
| 1283 | register long _num asm("a7") = (num); \ | ||
| 1284 | register long _arg1 asm("a0") = (long)(arg1); \ | ||
| 1285 | \ | ||
| 1286 | asm volatile ( \ | ||
| 1287 | "ecall\n" \ | ||
| 1288 | : "+r"(_arg1) \ | ||
| 1289 | : "r"(_num) \ | ||
| 1290 | : "memory", "cc" \ | ||
| 1291 | ); \ | ||
| 1292 | _arg1; \ | ||
| 1293 | }) | ||
| 1294 | |||
| 1295 | #define my_syscall2(num, arg1, arg2) \ | ||
| 1296 | ({ \ | ||
| 1297 | register long _num asm("a7") = (num); \ | ||
| 1298 | register long _arg1 asm("a0") = (long)(arg1); \ | ||
| 1299 | register long _arg2 asm("a1") = (long)(arg2); \ | ||
| 1300 | \ | ||
| 1301 | asm volatile ( \ | ||
| 1302 | "ecall\n" \ | ||
| 1303 | : "+r"(_arg1) \ | ||
| 1304 | : "r"(_arg2), \ | ||
| 1305 | "r"(_num) \ | ||
| 1306 | : "memory", "cc" \ | ||
| 1307 | ); \ | ||
| 1308 | _arg1; \ | ||
| 1309 | }) | ||
| 1310 | |||
| 1311 | #define my_syscall3(num, arg1, arg2, arg3) \ | ||
| 1312 | ({ \ | ||
| 1313 | register long _num asm("a7") = (num); \ | ||
| 1314 | register long _arg1 asm("a0") = (long)(arg1); \ | ||
| 1315 | register long _arg2 asm("a1") = (long)(arg2); \ | ||
| 1316 | register long _arg3 asm("a2") = (long)(arg3); \ | ||
| 1317 | \ | ||
| 1318 | asm volatile ( \ | ||
| 1319 | "ecall\n\t" \ | ||
| 1320 | : "+r"(_arg1) \ | ||
| 1321 | : "r"(_arg2), "r"(_arg3), \ | ||
| 1322 | "r"(_num) \ | ||
| 1323 | : "memory", "cc" \ | ||
| 1324 | ); \ | ||
| 1325 | _arg1; \ | ||
| 1326 | }) | ||
| 1327 | |||
| 1328 | #define my_syscall4(num, arg1, arg2, arg3, arg4) \ | ||
| 1329 | ({ \ | ||
| 1330 | register long _num asm("a7") = (num); \ | ||
| 1331 | register long _arg1 asm("a0") = (long)(arg1); \ | ||
| 1332 | register long _arg2 asm("a1") = (long)(arg2); \ | ||
| 1333 | register long _arg3 asm("a2") = (long)(arg3); \ | ||
| 1334 | register long _arg4 asm("a3") = (long)(arg4); \ | ||
| 1335 | \ | ||
| 1336 | asm volatile ( \ | ||
| 1337 | "ecall\n" \ | ||
| 1338 | : "+r"(_arg1) \ | ||
| 1339 | : "r"(_arg2), "r"(_arg3), "r"(_arg4), \ | ||
| 1340 | "r"(_num) \ | ||
| 1341 | : "memory", "cc" \ | ||
| 1342 | ); \ | ||
| 1343 | _arg1; \ | ||
| 1344 | }) | ||
| 1345 | |||
| 1346 | #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ | ||
| 1347 | ({ \ | ||
| 1348 | register long _num asm("a7") = (num); \ | ||
| 1349 | register long _arg1 asm("a0") = (long)(arg1); \ | ||
| 1350 | register long _arg2 asm("a1") = (long)(arg2); \ | ||
| 1351 | register long _arg3 asm("a2") = (long)(arg3); \ | ||
| 1352 | register long _arg4 asm("a3") = (long)(arg4); \ | ||
| 1353 | register long _arg5 asm("a4") = (long)(arg5); \ | ||
| 1354 | \ | ||
| 1355 | asm volatile ( \ | ||
| 1356 | "ecall\n" \ | ||
| 1357 | : "+r"(_arg1) \ | ||
| 1358 | : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ | ||
| 1359 | "r"(_num) \ | ||
| 1360 | : "memory", "cc" \ | ||
| 1361 | ); \ | ||
| 1362 | _arg1; \ | ||
| 1363 | }) | ||
| 1364 | |||
| 1365 | #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ | ||
| 1366 | ({ \ | ||
| 1367 | register long _num asm("a7") = (num); \ | ||
| 1368 | register long _arg1 asm("a0") = (long)(arg1); \ | ||
| 1369 | register long _arg2 asm("a1") = (long)(arg2); \ | ||
| 1370 | register long _arg3 asm("a2") = (long)(arg3); \ | ||
| 1371 | register long _arg4 asm("a3") = (long)(arg4); \ | ||
| 1372 | register long _arg5 asm("a4") = (long)(arg5); \ | ||
| 1373 | register long _arg6 asm("a5") = (long)(arg6); \ | ||
| 1374 | \ | ||
| 1375 | asm volatile ( \ | ||
| 1376 | "ecall\n" \ | ||
| 1377 | : "+r"(_arg1) \ | ||
| 1378 | : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \ | ||
| 1379 | "r"(_num) \ | ||
| 1380 | : "memory", "cc" \ | ||
| 1381 | ); \ | ||
| 1382 | _arg1; \ | ||
| 1383 | }) | ||
| 1384 | |||
| 1385 | /* startup code */ | ||
| 1386 | asm(".section .text\n" | ||
| 1387 | ".global _start\n" | ||
| 1388 | "_start:\n" | ||
| 1389 | ".option push\n" | ||
| 1390 | ".option norelax\n" | ||
| 1391 | "lla gp, __global_pointer$\n" | ||
| 1392 | ".option pop\n" | ||
| 1393 | "ld a0, 0(sp)\n" // argc (a0) was in the stack | ||
| 1394 | "add a1, sp, "SZREG"\n" // argv (a1) = sp | ||
| 1395 | "slli a2, a0, "PTRLOG"\n" // envp (a2) = SZREG*argc ... | ||
| 1396 | "add a2, a2, "SZREG"\n" // + SZREG (skip null) | ||
| 1397 | "add a2,a2,a1\n" // + argv | ||
| 1398 | "andi sp,a1,-16\n" // sp must be 16-byte aligned | ||
| 1399 | "call main\n" // main() returns the status code, we'll exit with it. | ||
| 1400 | "andi a0, a0, 0xff\n" // limit exit code to 8 bits | ||
| 1401 | "li a7, 93\n" // NR_exit == 93 | ||
| 1402 | "ecall\n" | ||
| 1403 | ""); | ||
| 1404 | |||
| 1405 | /* fcntl / open */ | ||
| 1406 | #define O_RDONLY 0 | ||
| 1407 | #define O_WRONLY 1 | ||
| 1408 | #define O_RDWR 2 | ||
| 1409 | #define O_CREAT 0x100 | ||
| 1410 | #define O_EXCL 0x200 | ||
| 1411 | #define O_NOCTTY 0x400 | ||
| 1412 | #define O_TRUNC 0x1000 | ||
| 1413 | #define O_APPEND 0x2000 | ||
| 1414 | #define O_NONBLOCK 0x4000 | ||
| 1415 | #define O_DIRECTORY 0x200000 | ||
| 1416 | |||
| 1417 | struct sys_stat_struct { | ||
| 1418 | unsigned long st_dev; /* Device. */ | ||
| 1419 | unsigned long st_ino; /* File serial number. */ | ||
| 1420 | unsigned int st_mode; /* File mode. */ | ||
| 1421 | unsigned int st_nlink; /* Link count. */ | ||
| 1422 | unsigned int st_uid; /* User ID of the file's owner. */ | ||
| 1423 | unsigned int st_gid; /* Group ID of the file's group. */ | ||
| 1424 | unsigned long st_rdev; /* Device number, if device. */ | ||
| 1425 | unsigned long __pad1; | ||
| 1426 | long st_size; /* Size of file, in bytes. */ | ||
| 1427 | int st_blksize; /* Optimal block size for I/O. */ | ||
| 1428 | int __pad2; | ||
| 1429 | long st_blocks; /* Number 512-byte blocks allocated. */ | ||
| 1430 | long st_atime; /* Time of last access. */ | ||
| 1431 | unsigned long st_atime_nsec; | ||
| 1432 | long st_mtime; /* Time of last modification. */ | ||
| 1433 | unsigned long st_mtime_nsec; | ||
| 1434 | long st_ctime; /* Time of last status change. */ | ||
| 1435 | unsigned long st_ctime_nsec; | ||
| 1436 | unsigned int __unused4; | ||
| 1437 | unsigned int __unused5; | ||
| 1438 | }; | ||
| 1439 | |||
| 1246 | #endif | 1440 | #endif |
| 1247 | 1441 | ||
| 1248 | 1442 | ||
