diff --git a/arch/at91sam3x8e/Makefile b/arch/at91sam3x8e/Makefile index 01afd9d..171a58b 100644 --- a/arch/at91sam3x8e/Makefile +++ b/arch/at91sam3x8e/Makefile @@ -28,6 +28,7 @@ ARDIX_ARCH_PWD = $(PWD)/arch/at91sam3x8e ARDIX_SOURCES += \ $(ARDIX_ARCH_PWD)/atom.c \ $(ARDIX_ARCH_PWD)/atomic.c \ + $(ARDIX_ARCH_PWD)/entry.c \ $(ARDIX_ARCH_PWD)/interrupt.c \ $(ARDIX_ARCH_PWD)/sched.c \ $(ARDIX_ARCH_PWD)/serial.c \ @@ -36,7 +37,8 @@ ARDIX_SOURCES += \ $(ARDIX_ARCH_PWD)/watchdog.c ARDIX_ASM_SOURCES += \ - $(ARDIX_ARCH_PWD)/irq_pend_sv.S + $(ARDIX_ARCH_PWD)/irq_pend_sv.S \ + $(ARDIX_ARCH_PWD)/irq_svc.S CFLAGS += \ -DARCH_AT91SAM3X8E diff --git a/arch/at91sam3x8e/entry.c b/arch/at91sam3x8e/entry.c new file mode 100644 index 0000000..94d7aeb --- /dev/null +++ b/arch/at91sam3x8e/entry.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* See the end of this file for copyright, licensing, and warranty information. */ + +#include +#include + +#include +#include + +#include +#include + +void arch_syscall(void *sp) +{ + struct reg_snapshot *regs = sp; + enum syscall sc_num = arch_syscall_num(regs); + int (*handler)(sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, + sysarg_t arg4, sysarg_t arg5, sysarg_t arg6); + int sc_ret; + + if (sc_num > NSYSCALLS) { + arch_syscall_set_rval(regs, -EINVAL); + return; + } + + handler = syscall_table[sc_num]; + if (handler == NULL) { + arch_syscall_set_rval(regs, -EINVAL); + return; + } + + /* TODO: not every syscall uses the max amount of parameters (duh) */ + sc_ret = handler(arch_syscall_arg1(regs), arch_syscall_arg2(regs), arch_syscall_arg3(regs), + arch_syscall_arg4(regs), arch_syscall_arg5(regs), arch_syscall_arg6(regs)); + + arch_syscall_set_rval(regs, sc_ret); +} + +/* + * Copyright (c) 2020 Felix Kopp + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/arch/at91sam3x8e/irq_pend_sv.S b/arch/at91sam3x8e/irq_pend_sv.S index 7c3f4a1..f477381 100644 --- a/arch/at91sam3x8e/irq_pend_sv.S +++ b/arch/at91sam3x8e/irq_pend_sv.S @@ -26,8 +26,8 @@ irq_pend_sv: * required because lr is overwritten when entering the irq). * The stuff we push onto the stack manually looks about like this: * - * >>> stack grow direction >>> - * r7 r6 r5 r4 lr r11 r10 r9 r8 + * <<< stack grow direction (decreasing addresses) <<< + * r8 r9 r10 r11 lr r4 r5 r6 r7 */ push {r4-r7} /* r4-r7 */ diff --git a/arch/at91sam3x8e/irq_svc.S b/arch/at91sam3x8e/irq_svc.S new file mode 100644 index 0000000..25416b8 --- /dev/null +++ b/arch/at91sam3x8e/irq_svc.S @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* See the end of this file for copyright, licensing, and warranty information. */ + +.syntax unified +.thumb + +.text + +.extern arch_syscall + +.thumb_func +.global irq_svc +.type irq_svc, %function + +/* void irq_svc(void); */ +irq_svc: + /* + * Syscalls on Cortex-M use the following parameter calling convention: + * + * arg1: r0 + * arg2: r1 + * arg3: r2 + * arg4: r3 + * rval: r0 + * + * The syscall number is passed as part of the SVC instruction and read + * from the program counter in arch_syscall(). + */ + + /* + * like in irq_pend_sv, we save everything on the stack to make early + * process switching possible in case the syscall is blocking. + */ + push {r4-r7} /* r4-r7 */ + + mov r3, r8 + mov r4, r9 + mov r5, r10 + mov r6, r11 + mov r7, lr + push {r3-r7} /* r8-r11, lr */ + + mov r0, sp + bl arch_syscall /* arch_syscall(sp); */ + + pop {r3-r7} /* r8-r11, lr */ + mov lr, r7 + mov r11, r6 + mov r10, r5 + mov r9, r4 + mov r8, r3 + + pop {r4-r7} /* r4-r7 */ + + bx lr + +.size irq_svc, .-irq_svc + +/* + * Copyright (c) 2020 Felix Kopp + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/arch/at91sam3x8e/sys.c b/arch/at91sam3x8e/sys.c index 5f9d114..b0c4ce7 100644 --- a/arch/at91sam3x8e/sys.c +++ b/arch/at91sam3x8e/sys.c @@ -19,7 +19,7 @@ */ uint32_t sys_core_clock = 84000000UL; -int sys_init(void) +void sys_init(void) { /* * This method is basically an implementation of chapter 28.12 in the @@ -83,8 +83,6 @@ int sys_init(void) REG_PMC_MCKR = REG_PMC_MCKR_PRES_VAL(1 /* = as fast as it gets */) | REG_PMC_MCKR_CSS_VAL(2 /* = PLLA clock */); mom_are_we_there_yet(REG_PMC_SR & REG_PMC_SR_MCKRDY_BIT); - - return 0; } /* diff --git a/include/arch/at91sam3x8e/hardware.h b/include/arch/at91sam3x8e/hardware.h index b25bf32..c493f6e 100644 --- a/include/arch/at91sam3x8e/hardware.h +++ b/include/arch/at91sam3x8e/hardware.h @@ -3,7 +3,9 @@ #pragma once -#include +#include + +typedef uint32_t word_t; /** Current (volatile) system frequency in Hertz. */ extern uint32_t sys_core_clock; @@ -16,19 +18,19 @@ extern uint32_t sys_core_clock; * hardware routines on IRQ entry. Required for scheduling / context switching. */ struct reg_sw_snapshot { - uint32_t r8; - uint32_t r9; - uint32_t r10; - uint32_t r11; + word_t r8; + word_t r9; + word_t r10; + word_t r11; /* * lr is saved by hardware, but we need to store it twice * because the IRQ entry overwrites it */ void *lr; /* alias r14 */ - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; + word_t r4; + word_t r5; + word_t r6; + word_t r7; }; /** @@ -36,14 +38,14 @@ struct reg_sw_snapshot { * an IRQ, in the correct order. */ struct reg_hw_snapshot { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; + word_t r0; + word_t r1; + word_t r2; + word_t r3; + word_t r12; void *lr; /* alias r14 */ void *pc; /* alias r15 */ - uint32_t psr; + word_t psr; }; /** Combination of `struct reg_sw_snapshot` and `struct reg_hw_snapshot`. */ @@ -52,6 +54,16 @@ struct reg_snapshot { struct reg_hw_snapshot hw; }; +#define arch_syscall_num(reg_snap) ( ((uint8_t *)((reg_snap)->hw.lr))[1] ) +#define arch_syscall_arg1(reg_snap) ((reg_snap)->hw.r0) +#define arch_syscall_arg2(reg_snap) ((reg_snap)->hw.r1) +#define arch_syscall_arg3(reg_snap) ((reg_snap)->hw.r2) +#define arch_syscall_arg4(reg_snap) ((reg_snap)->hw.r3) +#define arch_syscall_arg5(reg_snap) ((reg_snap)->sw.r8) +#define arch_syscall_arg6(reg_snap) ((reg_snap)->sw.r9) + +#define arch_syscall_set_rval(reg_snap, val) ((reg_snap)->hw.r0 = (uint32_t)(val)); + /* * Real-time Timer (RTT) */ diff --git a/include/arch/entry.h b/include/arch/entry.h new file mode 100644 index 0000000..9420313 --- /dev/null +++ b/include/arch/entry.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* See the end of this file for copyright, licensing, and warranty information. */ + +#pragma once + +/** + * Perform a syscall. + * + * This is the first and only method called by the irq handler for system calls. + * It is responsible for finishing the context switch, obtaining the syscall + * number and arguments, and invoking the respective system call. + * + * @param sp: The current stack pointer. + */ +void arch_syscall(void *sp); + +/* + * Copyright (c) 2020 Felix Kopp + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/include/arch/hardware.h b/include/arch/hardware.h index e8468d3..fcbefb6 100644 --- a/include/arch/hardware.h +++ b/include/arch/hardware.h @@ -26,14 +26,10 @@ * to know about it (especially the flash controller) * - Enabling interrupts that are vital for stable operation * - * If any of this fails, a nonzero value must be returned to indicate the error - * condition. An on-chip LED should be used to "morse" some kind of diagnostic - * message, if the system has one (kind of like BIOS beep codes). - * - * @returns `0` on success, a negative POSIX error code if applicable, or a - * positive (platform-dependant) number on hardware fault. + * If any of this fails, an on-chip LED should be used to "morse" some kind of + * diagnostic message, if the system has one (kind of like BIOS beep codes). */ -int sys_init(void); +void sys_init(void); #ifndef STACK_SIZE /** stack size per process in bytes */ diff --git a/include/ardix/syscall.h b/include/ardix/syscall.h new file mode 100644 index 0000000..5370ef6 --- /dev/null +++ b/include/ardix/syscall.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* See the end of this file for copyright, licensing, and warranty information. */ + +#pragma once + +#include + +#include +#include + +enum syscall { + SYSCALL_READ = 0, + SYSCALL_WRITE = 1, + NSYSCALLS +}; + +/** The table of system call handlers, indexed by syscall number. */ +extern const int (*syscall_table[NSYSCALLS])(sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, + sysarg_t arg4, sysarg_t arg5, sysarg_t arg6); + +/* catchall handler that returns -ENOSYS */ +int sys_stub(void); + +int sys_read(int fd, void *buf, size_t len, size_t off); +int sys_write(int fd, const void *buf, size_t len, size_t off); + +/* + * Copyright (c) 2020 Felix Kopp + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/kernel/Makefile b/kernel/Makefile index 8474464..38ef7ee 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -32,4 +32,5 @@ ARDIX_SOURCES += \ $(ARDIX_KERNEL_PWD)/printk.c \ $(ARDIX_KERNEL_PWD)/ringbuf.c \ $(ARDIX_KERNEL_PWD)/sched.c \ - $(ARDIX_KERNEL_PWD)/serial.c + $(ARDIX_KERNEL_PWD)/serial.c \ + $(ARDIX_KERNEL_PWD)/syscall.c diff --git a/kernel/syscall.c b/kernel/syscall.c new file mode 100644 index 0000000..d585178 --- /dev/null +++ b/kernel/syscall.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* See the end of this file for copyright, licensing, and warranty information. */ + +#include + +#include + +#define syscall_entry(number, func) \ + [number] (int (*)(sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t))(func) + +__rodata +const int (*syscall_table[NSYSCALLS])(sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, + sysarg_t arg4, sysarg_t arg5, sysarg_t arg6) = { + syscall_entry(SYSCALL_READ, &sys_stub), + syscall_entry(SYSCALL_WRITE, &sys_stub), +}; + +int sys_stub(void) +{ + return -ENOSYS; +} + +/* + * Copyright (c) 2020 Felix Kopp + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */