From d1297688a8e010e58052743675a536488afea80b Mon Sep 17 00:00:00 2001 From: "Jan (janneke) Nieuwenhuizen" Date: Sat, 30 Apr 2022 22:51:42 +0200 Subject: [PATCH] ARM: build: Cater for M2-Planet. * include/linux/arm/syscall.h: Add support for M2-Planet. * lib/linux/arm-mes-m2/_exit.c, lib/linux/arm-mes-m2/_write.c, lib/linux/arm-mes-m2/crt1.M1, lib/linux/arm-mes-m2/crt1.c, lib/linux/arm-mes-m2/syscall.c, lib/m2/arm/ELF-arm.hex2, lib/m2/arm/arm_defs.M1: New files. * build-aux/build.sh.in: Also allow kaem build for ARM. --- build-aux/build.sh.in | 3 +- include/linux/arm/syscall.h | 54 ++++++++--- lib/linux/arm-mes-m2/_exit.c | 28 ++++++ lib/linux/arm-mes-m2/_write.c | 30 ++++++ lib/linux/arm-mes-m2/crt1.M1 | 145 +++++++++++++++++++++++++++++ lib/linux/arm-mes-m2/crt1.c | 34 +++++++ lib/linux/arm-mes-m2/syscall.c | 165 +++++++++++++++++++++++++++++++++ lib/m2/arm/ELF-arm.hex2 | 74 +++++++++++++++ lib/m2/arm/arm_defs.M1 | 117 +++++++++++++++++++++++ 9 files changed, 635 insertions(+), 15 deletions(-) create mode 100644 lib/linux/arm-mes-m2/_exit.c create mode 100644 lib/linux/arm-mes-m2/_write.c create mode 100644 lib/linux/arm-mes-m2/crt1.M1 create mode 100644 lib/linux/arm-mes-m2/crt1.c create mode 100644 lib/linux/arm-mes-m2/syscall.c create mode 100644 lib/m2/arm/ELF-arm.hex2 create mode 100644 lib/m2/arm/arm_defs.M1 diff --git a/build-aux/build.sh.in b/build-aux/build.sh.in index d4120128..b56d7bd6 100644 --- a/build-aux/build.sh.in +++ b/build-aux/build.sh.in @@ -121,7 +121,8 @@ fi fi ) -if test -n "$M2_PLANET" && test "$mes_cpu" == "x86"; then +if test -n "$M2_PLANET" && (test "$mes_cpu" == "x86" \ + || test "$mes_cpu" == "arm"); then ( . ${srcdest}build-aux/trace.sh if [ -z "$V" -o "$V" = 0 ]; then diff --git a/include/linux/arm/syscall.h b/include/linux/arm/syscall.h index 8811d542..b04ff039 100644 --- a/include/linux/arm/syscall.h +++ b/include/linux/arm/syscall.h @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2018,2022 Jan (janneke) Nieuwenhuizen * Copyright © 2020 Danny Milosavljevic * * This file is part of GNU Mes. @@ -23,29 +23,58 @@ /* See https://github.com/torvalds/linux/blob/v4.19/arch/arm/tools/syscall.tbl */ -// libc +/* libc-mini */ +#ifndef SYS_exit +// CONSTANT SYS_exit 0x01 +#define SYS_exit 0x01 +#endif +#ifndef SYS_write +// CONSTANT SYS_write 0x04 +#define SYS_write 0x04 +#endif + +/* libc */ +// CONSTANT SYS_fork 0x02 #define SYS_fork 0x02 +// CONSTANT SYS_read 0x03 #define SYS_read 0x03 +// CONSTANT SYS_open 0x05 #define SYS_open 0x05 //#define SYS_waitpid +// CONSTANT SYS_wait4 0x72 #define SYS_wait4 0x72 +// CONSTANT SYS_execve 0x0b #define SYS_execve 0x0b +// CONSTANT SYS_chmod 0x0f #define SYS_chmod 0x0f +// CONSTANT SYS_access 0x21 #define SYS_access 0x21 +// CONSTANT SYS_brk 0x2d #define SYS_brk 0x2d +// CONSTANT SYS_ioctl 0x36 #define SYS_ioctl 0x36 +// CONSTANT SYS_fsync 0x76 #define SYS_fsync 0x76 +// CONSTANT SYS_getcwd 0xb7 +#define SYS_getcwd 0xb7 +// CONSTANT SYS_dup 0x29 +#define SYS_dup 0x29 +// CONSTANT SYS_dup2 0x3f +#define SYS_dup2 0x3f +// CONSTANT SYS_unlink 0x0a +#define SYS_unlink 0x0a +// CONSTANT SYS_gettimeofday 0x4e +#define SYS_gettimeofday 0x4e +// CONSTANT SYS_clock_gettime 0x107 +#define SYS_clock_gettime 0x107 -// libc+tcc +/* libc+tcc */ #define SYS_close 0x06 #define SYS_lseek 0x13 -#define SYS_unlink 0x0a #define SYS_rmdir 0x28 -#define SYS_gettimeofday 0x4e #define SYS_stat 0x6a -#define SYS_getcwd 0xb7 -// libc+gnu +/* libc+gnu */ #define SYS_chdir 0x0c #define SYS_link 0x09 #define SYS_getpid 0x14 @@ -53,34 +82,31 @@ #define SYS_kill 0x25 #define SYS_rename 0x26 #define SYS_mkdir 0x27 -#define SYS_dup 0x29 #define SYS_pipe 0x2a #define SYS_getgid 0x2f #define SYS_rt_sigaction 0xae #define SYS_rt_sigreturn 0xad #define SYS_fcntl 0x37 -#define SYS_dup2 0x3f #define SYS_getrusage 0x4d #define SYS_lstat 0x6b #define SYS_setitimer 0x68 #define SYS_fstat 0x6c #define SYS_nanosleep 0xa2 #define SYS_getdents 0x8d -#define SYS_clock_gettime 0x107 -// bash +/* bash */ #define SYS_setuid 0x17 #define SYS_setgid 0x2e #define SYS_geteuid 0x31 #define SYS_getegid 0x32 #define SYS_getppid 0x40 -// make+WITH_GLIBC +/* make+WITH_GLIBC */ #define SYS_rt_sigprocmask 0xaf -// tar +/* tar */ #define SYS_symlink 0x53 #define SYS_readlink 0x55 #define SYS_mknod 0x0e -#endif // __MES_LINUX_ARM_SYSCALL_H +#endif /* __MES_LINUX_ARM_SYSCALL_H */ diff --git a/lib/linux/arm-mes-m2/_exit.c b/lib/linux/arm-mes-m2/_exit.c new file mode 100644 index 00000000..001059d8 --- /dev/null +++ b/lib/linux/arm-mes-m2/_exit.c @@ -0,0 +1,28 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2020,2022 Jan (janneke) Nieuwenhuizen + * Copyright © 2020 Danny Milosavljevic + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +void +_exit () +{ + asm ("SYS_exit mov____$i8,%r7"); + asm ("!4 ldr____%r0,(%fp,-#$i8)"); + asm ("swi____$0"); +} diff --git a/lib/linux/arm-mes-m2/_write.c b/lib/linux/arm-mes-m2/_write.c new file mode 100644 index 00000000..7d35932a --- /dev/null +++ b/lib/linux/arm-mes-m2/_write.c @@ -0,0 +1,30 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2020,2022 Jan (janneke) Nieuwenhuizen + * Copyright © 2020 Danny Milosavljevic + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +void +_write () +{ + asm ("SYS_write mov____$i8,%r7"); + asm ("!4 ldr____%r0,(%fp,-#$i8)"); + asm ("!8 ldr____%r1,(%fp,-#$i8)"); + asm ("!12 ldr____%r2,(%fp,-#$i8)"); + asm ("swi____$0"); +} diff --git a/lib/linux/arm-mes-m2/crt1.M1 b/lib/linux/arm-mes-m2/crt1.M1 new file mode 100644 index 00000000..4c71e9e8 --- /dev/null +++ b/lib/linux/arm-mes-m2/crt1.M1 @@ -0,0 +1,145 @@ +### GNU Mes --- Maxwell Equations of Software +### Copyright (C) 2016 Jeremiah Orians +### Copyright © 2022 Jan (janneke) Nieuwenhuizen +### +### This file is part of GNU Mes. +### +### GNU Mes is free software; you can redistribute it and/or modify it +### under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 3 of the License, or (at +### your option) any later version. +### +### GNU Mes is distributed in the hope that it will be useful, but +### WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with GNU Mes. If not, see . + +:_start + '0' SP BP NO_SHIFT MOVE_ALWAYS ; Setup Base Pointer + + ;; Prepare argv + !4 R0 ADD BP ARITH_ALWAYS ; ARGV_address = BP + 4 + {R0} PUSH_ALWAYS ; Put argv on the stack + + ;; Prepare envp + '0' BP R0 NO_SHIFT MOVE_ALWAYS ; Address we need to load from + !0 R0 LOAD32 R0 MEMORY ; Get ARGC + !2 R0 ADD R0 ARITH_ALWAYS ; OFFSET = ARGC + 2 + '0' R0 R0 '1' MOVE_ALWAYS ; OFFSET = OFFSET * WORDSIZE + '0' R0 R0 ADD BP ARITH2_ALWAYS ; ENVP_address = BP + OFFSET + {R0} PUSH_ALWAYS ; Put envp on the stack + + mov____%r0,0x32 &GLOBAL_environ + + ;; Stack offset + !4 BP ADD BP ARITH_ALWAYS ; Fix BP + + ;;^~FUNCTION___init_io CALL_ALWAYS ; Setup for FILE* + + ;; Initialize MesCC lib file descriptors. + !0 mov____$i8,%r0 + mov____%r0,0x32 &GLOBAL___stdin + !1 mov____$i8,%r0 + mov____%r0,0x32 &GLOBAL___stdout + !2 mov____$i8,%r0 + mov____%r0,0x32 &GLOBAL___stderr + + ^~FUNCTION_main CALL_ALWAYS ; Jump right into main + + SYS_exit mov____$i8,%r7 + swi____$0 + + +# Unsigned Divide +:divide + {R4} PUSH_ALWAYS ; Protect R4 + {R3} PUSH_ALWAYS ; Protect R3 + {R2} PUSH_ALWAYS ; Protect R2 + + '0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0 + '0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1 + + !0 R0 LOADI8_ALWAYS ; MOV R0,#0 + !0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0 + !1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1 + !0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0 + !0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0 + '0' R0 R0 MVN_LT ; MVNLT R0,R0 + '0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0 + + !32 R0 LOADI8_ALWAYS ; MOV R0,#32. + !0 R1 LOADI8_ALWAYS ; MOV R1,#0 +:divide_loop + '0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2 + '0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1 + '0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3 + '0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3 + !1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1 + !1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1 + !0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0 + ^~divide_loop JUMP_NE ; BNE loop + + '0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2 + + {R2} POP_ALWAYS ; Restore R2 + {R3} POP_ALWAYS ; Restore R3 + {R4} POP_ALWAYS ; Restore R4 + '1' LR RETURN + +# Signed Divide +:divides + {R4} PUSH_ALWAYS ; Protect R4 + {R3} PUSH_ALWAYS ; Protect R3 + {R2} PUSH_ALWAYS ; Protect R2 + + '0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0 + '0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1 + + !0 R0 LOADI8_ALWAYS ; MOV R0,#0 + !0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0 + !0 R2 RSUB R2 ARITH_LT ; RSBLT R2,R2,#0 + !1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1 + !0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0 + !0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0 + '0' R0 R0 MVN_LT ; MVNLT R0,R0 + '0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0 + + !32 R0 LOADI8_ALWAYS ; MOV R0,#32. + !0 R1 LOADI8_ALWAYS ; MOV R1,#0 +:divides_loop + '0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2 + '0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1 + '0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3 + '0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3 + !1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1 + !1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1 + !0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0 + ^~divides_loop JUMP_NE ; BNE loop + + !0 CMPI8 R4 IMM_ALWAYS ; CMP R4,#0 + !0 R2 RSUB R2 ARITH_NE ; RSBNE R2,R2,#0 + '0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2 + + {R2} POP_ALWAYS ; Restore R2 + {R3} POP_ALWAYS ; Restore R3 + {R4} POP_ALWAYS ; Restore R4 + '1' LR RETURN + +# Unsigned Modulus +:modulus + {LR} PUSH_ALWAYS ; Prepare to leverage divide + ^~divide CALL_ALWAYS ; Use divide + '0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1 + {LR} POP_ALWAYS ; Prepare for return + '1' LR RETURN + +# Signed Modulus +:moduluss + {LR} PUSH_ALWAYS ; Prepare to leverage divide + ^~divides CALL_ALWAYS ; Use divides + '0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1 + {LR} POP_ALWAYS ; Prepare for return + '1' LR RETURN diff --git a/lib/linux/arm-mes-m2/crt1.c b/lib/linux/arm-mes-m2/crt1.c new file mode 100644 index 00000000..1f8fb0ab --- /dev/null +++ b/lib/linux/arm-mes-m2/crt1.c @@ -0,0 +1,34 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include "mes/lib-mini.h" + +int __stdin; +int __stdout; +int __stderr; +char **environ; +int main (int argc, char **argv, char **envp); + +/* FIXME: this is going to be called `FUNCTION__start' */ +//#int +//#_start () +//#{ +//# .. +//#} diff --git a/lib/linux/arm-mes-m2/syscall.c b/lib/linux/arm-mes-m2/syscall.c new file mode 100644 index 00000000..619b1444 --- /dev/null +++ b/lib/linux/arm-mes-m2/syscall.c @@ -0,0 +1,165 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018,2022 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +#include + +int errno; + +int +__sys_call (int sys_call) +{ + asm ("!4 ldr____%r7,(%fp,-#$i8)"); + asm ("swi____$0"); +} + +int +__sys_call1 (int sys_call, int one) +{ + asm ("!4 ldr____%r7,(%fp,-#$i8)"); + asm ("!8 ldr____%r0,(%fp,-#$i8)"); + asm ("swi____$0"); +} + +int +__sys_call2 (int sys_call, int one, int two) +{ + asm ("!4 ldr____%r7,(%fp,-#$i8)"); + asm ("!8 ldr____%r0,(%fp,-#$i8)"); + asm ("!12 ldr____%r1,(%fp,-#$i8)"); + asm ("swi____$0"); +} + +int +__sys_call3 (int sys_call, int one, int two, int three) +{ + asm ("!4 ldr____%r7,(%fp,-#$i8)"); + asm ("!8 ldr____%r0,(%fp,-#$i8)"); + asm ("!12 ldr____%r1,(%fp,-#$i8)"); + asm ("!16 ldr____%r2,(%fp,-#$i8)"); + asm ("swi____$0"); +} + +int +__sys_call4 (int sys_call, int one, int two, int three, int four) +{ + asm ("!4 ldr____%r7,(%fp,-#$i8)"); + asm ("!8 ldr____%r0,(%fp,-#$i8)"); + asm ("!12 ldr____%r1,(%fp,-#$i8)"); + asm ("!16 ldr____%r2,(%fp,-#$i8)"); + asm ("!20 ldr____%r2,(%fp,-#$i8)"); + asm ("swi____$0"); +} + +int +__sys_call6 (int sys_call, int one, int two, int three, int four, int five, int six) +{ + asm ("!4 ldr____%r7,(%fp,-#$i8)"); + asm ("!8 ldr____%r0,(%fp,-#$i8)"); + asm ("!12 ldr____%r1,(%fp,-#$i8)"); + asm ("!16 ldr____%r2,(%fp,-#$i8)"); + asm ("!20 ldr____%r2,(%fp,-#$i8)"); + asm ("!24 ldr____%r2,(%fp,-#$i8)"); + asm ("swi____$0"); +} + +int +_sys_call (int sys_call) +{ + int r = __sys_call (sys_call); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call1 (int sys_call, int one) +{ + int r = __sys_call1 (sys_call, one); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call2 (int sys_call, int one, int two) +{ + int r = __sys_call2 (sys_call, one, two); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call3 (int sys_call, int one, int two, int three) +{ + int r = __sys_call3 (sys_call, one, two, three); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call4 (int sys_call, int one, int two, int three, int four) +{ + int r = __sys_call4 (sys_call, one, two, three, four); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call6 (int sys_call, int one, int two, int three, int four, int five, int six) +{ + int r = __sys_call6 (sys_call, one, two, three, four, five, six); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} diff --git a/lib/m2/arm/ELF-arm.hex2 b/lib/m2/arm/ELF-arm.hex2 new file mode 100644 index 00000000..6c704ec5 --- /dev/null +++ b/lib/m2/arm/ELF-arm.hex2 @@ -0,0 +1,74 @@ +### Copyright (C) 2016 Jeremiah Orians +### Copyright (C) 2017 Jan Nieuwenhuizen +### This file is part of M2-Planet. +### +### M2-Planet is free software: you can redistribute it and/or modify +### it under the terms of the GNU General Public License as published by +### the Free Software Foundation, either version 3 of the License, or +### (at your option) any later version. +### +### M2-Planet is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with M2-Planet. If not, see . + +### stage0's hex2 format +### !