From 6ad1b899ed93f8bc110cdec7a722c8740f9f8d66 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 31 Jul 2023 22:24:29 +0300 Subject: start working on irqs --- include/arch/cpu.h | 6 +-- include/arch/irq.h | 43 +++++++++++++--- include/arch/proc.h | 2 + include/kmi/caps.h | 3 ++ include/kmi/ipi.h | 9 +--- include/kmi/irq.h | 42 ++++++++++++++++ include/kmi/panic.h | 22 ++++++++ include/kmi/syscalls.h | 4 ++ include/kmi/timer.h | 2 + include/kmi/uapi.h | 134 ++++++++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 248 insertions(+), 19 deletions(-) create mode 100644 include/kmi/irq.h create mode 100644 include/kmi/panic.h (limited to 'include') diff --git a/include/arch/cpu.h b/include/arch/cpu.h index d142433..1fd146e 100644 --- a/include/arch/cpu.h +++ b/include/arch/cpu.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: copyleft-next-0.3.1 */ /* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ -#ifndef KMI_CPU_H -#define KMI_CPU_H +#ifndef KMI_ARCH_CPU_H +#define KMI_ARCH_CPU_H /** * @file cpu.h @@ -43,4 +43,4 @@ void cpu_assign(struct tcb *t); */ void cpu_send_ipi(id_t cpu_id); -#endif /* KMI_CPU_H */ +#endif /* KMI_ARCH_CPU_H */ diff --git a/include/arch/irq.h b/include/arch/irq.h index 72b998e..85a7360 100644 --- a/include/arch/irq.h +++ b/include/arch/irq.h @@ -1,8 +1,11 @@ /* SPDX-License-Identifier: copyleft-next-0.3.1 */ /* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ -#ifndef KMI_IRQ_H -#define KMI_IRQ_H +#ifndef KMI_ARCH_IRQ_H +#define KMI_ARCH_IRQ_H + +/** Type for IRQ id. */ +typedef uint_fast32_t irq_t; /** * @file irq.h @@ -19,16 +22,42 @@ #endif /** - * Initialize IRQ subsystem. + * Initialize arch-specific IRQ stuff. * * @param fdt Global FDT pointer. */ -void init_irq(void *fdt); +void setup_irq(void *fdt); + +/** + * Activate IRQ for \p id. + * Assumes there's one interrupt controller for the whole system, which might be + * an oversimplification. + * + * @param id IRQ id to deactivate. + * @return OK on success, non-zero otherwise. + */ +stat_t activate_irq(irq_t id); + +/** + * Deactivates IRQ for \p id. + * + * @param id IRQ id to deactivate. + * @return OK on success, non-zero otherwise. + */ +stat_t deactivate_irq(irq_t id); /** Enable IRQs. */ -void enable_irq(); +void enable_irqs(); /** Disable IRQs. */ -void disable_irq(); +void disable_irqs(); + +/** Get IRQ to handle. + * + * @return ID of IRQ to handle. + * + * @todo what about illegal IRQs due to bug or something? + */ +irq_t get_irq(); -#endif /* KMI_IRQ_H */ +#endif /* KMI_ARCH_IRQ_H */ diff --git a/include/arch/proc.h b/include/arch/proc.h index 79b099e..341a2f4 100644 --- a/include/arch/proc.h +++ b/include/arch/proc.h @@ -21,6 +21,8 @@ * Attach argument data to thread. * * @param t Thread that will run after return. + * @param n How many of the arguments to attach. Might micro-optimize some + * stuff. * @param a Arguments to attach. */ void set_args(struct tcb *t, size_t n, struct sys_ret a); diff --git a/include/kmi/caps.h b/include/kmi/caps.h index 078dd3d..2813634 100644 --- a/include/kmi/caps.h +++ b/include/kmi/caps.h @@ -34,6 +34,9 @@ enum { /** Thread is allowed to access configuration parameters. */ CAP_CONF = (1 << 4), + + /** Thread is allowed to request to handle IRQs. */ + CAP_IRQ = (1 << 5), }; /** diff --git a/include/kmi/ipi.h b/include/kmi/ipi.h index 4567edb..72b54b9 100644 --- a/include/kmi/ipi.h +++ b/include/kmi/ipi.h @@ -29,12 +29,7 @@ bool clear_ipi(struct tcb *t); */ void send_ipi(struct tcb *t); -/** - * Handle IPI. - * - * @param t Thread who was interrupted by IPI. - * @return Possible arguments to IPI. - */ -struct sys_ret handle_ipi(struct tcb *t); +/** Handle IPI. */ +void handle_ipi(); #endif /* KMI_IPI_H */ diff --git a/include/kmi/irq.h b/include/kmi/irq.h new file mode 100644 index 0000000..ccc654b --- /dev/null +++ b/include/kmi/irq.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ + +#ifndef KMI_IRQ_H +#define KMI_IRQ_H + +/** + * @file irq.h + * Common IRQ handling stuff. + */ + +#include +#include + +/** + * Initialize IRQ subsystem. + * + * @param fdt Flattened device tree. + */ +void init_irq(void *fdt); + +/** Handle irq. */ +void handle_irq(); + +/** + * Register IRQ with thread \p t. + * + * @param t Thread to register IRQ \p id to. + * @param id IRQ id to register to \p t. + * @return OK on success, non-zero otherwise. + */ +stat_t register_irq(struct tcb *t, irq_t id); + +/** + * Unregister IRQ with thread \p t. + * + * @param t Thread to unregister \p id from. + * @param id IRQ id to unregister from \p t. + * @return OK on success, non-zero otherwise. + */ +stat_t unregister_irq(struct tcb *t, irq_t id); + +#endif /* KMI_IRQ_H */ diff --git a/include/kmi/panic.h b/include/kmi/panic.h new file mode 100644 index 0000000..44593a3 --- /dev/null +++ b/include/kmi/panic.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ + +#ifndef KMI_PANIC_H +#define KMI_PANIC_H + +/** + * @file panic.h + * Kernel panic handler. + */ + +/** + * Call on kernel panic, tries to reboot the system. Failing that, spin. + * Ideally registers and kernel state would be printed, but keep things simple + * for now. + * + * @param pc Address where fault occured. Should preferably be in the kernel. + * @param addr Possibly associated address. + * @param cause Possible error code associated with panic. Page fault, etc. + */ +__noreturn void kernel_panic(void *pc, void *addr, long cause); + +#endif /* KMI_PANIC_H */ diff --git a/include/kmi/syscalls.h b/include/kmi/syscalls.h index 8ca6546..79cd692 100644 --- a/include/kmi/syscalls.h +++ b/include/kmi/syscalls.h @@ -134,6 +134,10 @@ enum { /** Shutdown, reboot, etc. */ SYS_POWEROFF, + + /** Request to handle IRQ. */ + SYS_IRQ_REQ, + /** @} */ SYS_NUM, diff --git a/include/kmi/timer.h b/include/kmi/timer.h index c0855e4..c1a07a2 100644 --- a/include/kmi/timer.h +++ b/include/kmi/timer.h @@ -133,4 +133,6 @@ static inline ticks_t secs_to_ticks(tunit_t secs) return msecs_to_ticks(secs * 1000); } +void handle_timer(); + #endif /* KMI_TIMER_H */ diff --git a/include/kmi/uapi.h b/include/kmi/uapi.h index 477e315..891b5f9 100644 --- a/include/kmi/uapi.h +++ b/include/kmi/uapi.h @@ -796,6 +796,21 @@ SYSCALL_DECLARE3(clear_cap, tid, off, cap); * Shouldn't return at all. */ SYSCALL_DECLARE1(poweroff, type); + +/** + * Request to handle IRQ. + * + * @param t Current tcb. + * @param id ID if IRQ to handle. + * @param b Unused. + * @param c Unused. + * @param d Unused. + * @param e Unused. + * + * Returns OK on success, non-zero otherwise. + * @todo document error codes better. + */ +SYSCALL_DECLARE1(irq_req, id); /** @} */ /** @@ -818,32 +833,147 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, #include +/** + * Set one argument to pass to thread when returning to userspace. + * + * @param t Thread whose arguments to set. + * @param a First argument. + */ #define set_args1(t, a) set_args(t, 1, SYS_RET1(a)) + +/** + * Set two arguments to pass to thread when returning to userspace. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + */ #define set_args2(t, a, b) set_args(t, 2, SYS_RET2(a, b)) + +/** + * Set three arguments to pass to thread when returning to userspace. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + */ #define set_args3(t, a, b, c) set_args(t, 3, SYS_RET3(a, b, c)) + +/** + * Set four arguments to pass to thread when returning to userspace. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + * @param d Fourth argument. + */ #define set_args4(t, a, b, c, d) set_args(t, 4, SYS_RET4(a, b, c, d)) + +/** + * Set five arguments to pass to thread when returning to userspace. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + * @param d Fourth argument. + * @param e Fifth argument. + */ #define set_args5(t, a, b, c, d, e) set_args(t, 5, SYS_RET5(a, b, c, d, e)) -#define set_args6(t, a, b, c, d, e, f) set_args(t, 6, \ - SYS_RET6(a, b, c, d, e, f)) +/** + * Set six arguments to pass to thread when returning to userspace. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + * @param d Fourth argument. + * @param e Fifth argument. + * @param f Sixth argument. + */ +#define set_args6(t, a, b, c, d, e, f) \ + set_args(t, 6, SYS_RET6(a, b, c, d, e, f)) + +/** + * Set one argument and return from uapi function. + * Essentially a beauty macro and slight micro-optimization, avoiding setting + * registers to zero when not required. + * + * @param t Thread whose arguments to set. + * @param a First argument. + */ #define return_args1(t, a) \ {set_args1(t, a); return;} +/** + * Set two arguments and return from uapi function. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + */ #define return_args2(t, a, b) \ {set_args2(t, a, b); return;} +/** + * Set three arguments and return from uapi function. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + */ #define return_args3(t, a, b, c) \ {set_args3(t, a, b, c); return;} +/** + * Set four arguments and return from uapi function. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + * @param d Fourth argument. + */ #define return_args4(t, a, b, c, d) \ {set_args4(t, a, b, c, d); return;} +/** + * Set five arguments and return from uapi function. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + * @param d Fourth argument. + * @param e Fifth argument. + */ #define return_args5(t, a, b, c, d, e) \ {set_args5(t, a, b, c, d, e); return;} +/** + * Set six arguments and return from uapi function. + * + * @param t Thread whose arguments to set. + * @param a First argument. + * @param b Second argument. + * @param c Third argument. + * @param d Fourth argument. + * @param e Fifth argument. + * @param f Sixth argument. + */ #define return_args6(t, a, b, c, d, e, f) \ {set_args6(t, a, b, c, d, e, f); return;} +/** + * Set all arguments and return from uapi function. + * + * @param t Thread whose arguments to set. + * @param x Arguments to set. + */ #define return_args(t, x) {set_args((t), 6, (x)); return;} #endif /* KMI_UAPI_H */ -- cgit v1.3