diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/ipi.c | 4 | ||||
| -rw-r--r-- | common/irq.c | 66 | ||||
| -rw-r--r-- | common/main.c | 2 | ||||
| -rw-r--r-- | common/panic.c | 24 | ||||
| -rw-r--r-- | common/timer.c | 2 | ||||
| -rw-r--r-- | common/uapi/dispatch.c | 1 | ||||
| -rw-r--r-- | common/uapi/irq.c | 28 | ||||
| -rw-r--r-- | common/uapi/proc.c | 1 |
8 files changed, 124 insertions, 4 deletions
diff --git a/common/ipi.c b/common/ipi.c index a5435a3..59f9fd1 100644 --- a/common/ipi.c +++ b/common/ipi.c @@ -25,11 +25,11 @@ void send_ipi(struct tcb *t) cpu_send_ipi(t->cpu_id); } -struct sys_ret handle_ipi(struct tcb *t) +void handle_ipi() { + struct tcb *t = cur_tcb(); adjust_ipi(t); /** @todo use rpc stack */ set_return(t, t->callback); - return get_args(t); } diff --git a/common/irq.c b/common/irq.c new file mode 100644 index 0000000..9c538a2 --- /dev/null +++ b/common/irq.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ + +/** + * @file irq.c + * Common IRQ handling stuff implementations. + */ + +#include <kmi/irq.h> +#include <kmi/pmem.h> +#include <kmi/debug.h> +#include <kmi/assert.h> +#include <kmi/string.h> +#include <arch/irq.h> + +/** Hold maximum IRQ id supported by system. */ +static size_t max_irq; + +/** Hold map of IRD ID -> thread id. @todo process id? */ +static id_t *irq_map; + +void init_irq(void *fdt) +{ + /** @todo check arch max irq and adjust accordingly */ + irq_map = (id_t *)alloc_page(MM_O0); + memset(irq_map, 0, order_size(MM_O0)); + max_irq = order_size(MM_O0) / sizeof(irq_map[0]); + + setup_irq(fdt); +} + +stat_t register_irq(struct tcb *t, irq_t id) +{ + if (id >= max_irq) + return ERR_INVAL; + + if (irq_map[id]) + return ERR_EXT; + + irq_map[id] = t->tid; + return activate_irq(id); +} + +stat_t unregister_irq(struct tcb *t, irq_t id) +{ + id_t tid = irq_map[id]; + if (tid != t->tid) + return ERR_PERM; + + irq_map[id] = 0; + return deactivate_irq(id); +} + +void handle_irq() +{ + irq_t id = get_irq(); + hard_assert(id < max_irq, RETURN_VOID); + + id_t tid = irq_map[id]; + + if (!tid) { + bug("unregistered irq: %llu\n", (unsigned long long)id); + return; + } + + /** @todo switch to thread */ +} diff --git a/common/main.c b/common/main.c index 9eb6414..30d9ed5 100644 --- a/common/main.c +++ b/common/main.c @@ -12,9 +12,9 @@ #include <kmi/proc.h> #include <kmi/debug.h> #include <kmi/vmem.h> +#include <kmi/irq.h> #include <arch/arch.h> #include <arch/proc.h> -#include <arch/irq.h> #include <libfdt.h> /** diff --git a/common/panic.c b/common/panic.c new file mode 100644 index 0000000..c2b6948 --- /dev/null +++ b/common/panic.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ + +/** + * @file panic.c + * Kernel panic handler implementation. + */ + +#include <kmi/power.h> +#include <kmi/debug.h> + +void kernel_panic(void *pc, void *addr, long cause) +{ + /* could be useful to print out register values as well? */ + error("kernel paniced at pc: %p with address %p and cause %lx\n", + pc, addr, cause); + + info("attempting to reboot\n"); + + poweroff(COLD_REBOOT); + + /* spin if poweroff failed for some reason */ + error("reboot failed, spinning in place\n"); + while (1); +} diff --git a/common/timer.c b/common/timer.c index 50ec237..272ba02 100644 --- a/common/timer.c +++ b/common/timer.c @@ -195,7 +195,7 @@ ticks_t nsecs_to_ticks(tunit_t nsecs) } /* call to this function from exception handlers */ -void update_timers() +void handle_timer() { struct timer *t = newest_timer(); remove_timer(t); diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c index a9caa1e..5b523cc 100644 --- a/common/uapi/dispatch.c +++ b/common/uapi/dispatch.c @@ -76,6 +76,7 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, case SYS_GET_CAP: sys_get_cap(t, a, b, c, d, e); break; case SYS_CLEAR_CAP: sys_clear_cap(t, a, b, c, d, e); break; case SYS_POWEROFF: sys_poweroff(t, a, b, c, d, e); break; + case SYS_IRQ_REQ: sys_irq_req(t, a, b, c, d, e); break; default: error("Syscall %zu outside allowed range [0 - %i]\n", syscall, SYS_NUM - 1); diff --git a/common/uapi/irq.c b/common/uapi/irq.c new file mode 100644 index 0000000..3aa040e --- /dev/null +++ b/common/uapi/irq.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ + +/** + * @file irq.c + * IRQ request syscall handling implementation. + */ + +#include <kmi/uapi.h> +#include <kmi/irq.h> + +/** + * Actual IRQ handling request syscall handler. + * + * @param t Current tcb. + * @param id IRQ id to request to handle. + * + * @return OK on success, non-zero otherwise. + */ +SYSCALL_DEFINE1(irq_req)(struct tcb *t, sys_arg_t id) +{ + if (!has_cap(t->caps, CAP_IRQ)) + return_args1(t, ERR_PERM); + + if (!t->callback) + return_args1(t, ERR_NF); + + return_args1(t, register_irq(t, id)); +} diff --git a/common/uapi/proc.c b/common/uapi/proc.c index 0ec19fb..b6018b8 100644 --- a/common/uapi/proc.c +++ b/common/uapi/proc.c @@ -151,6 +151,7 @@ SYSCALL_DEFINE1(kill)(struct tcb *t, sys_arg_t tid) return_args1(t, ERR_PERM); /** @todo implement */ + /** @todo remember to unregister IRQ handlers */ return_args1(t, OK); } |
