aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-07-31 22:24:29 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-07-31 22:24:29 +0300
commit6ad1b899ed93f8bc110cdec7a722c8740f9f8d66 (patch)
tree99fe36028ffc4583c59e77d03bea2ade7a6c5ace /common
parent3212707a9ab549119ad0ad6441a07fe774c99f3b (diff)
downloadkmi-6ad1b899ed93f8bc110cdec7a722c8740f9f8d66.tar.gz
kmi-6ad1b899ed93f8bc110cdec7a722c8740f9f8d66.zip
start working on irqs
Diffstat (limited to 'common')
-rw-r--r--common/ipi.c4
-rw-r--r--common/irq.c66
-rw-r--r--common/main.c2
-rw-r--r--common/panic.c24
-rw-r--r--common/timer.c2
-rw-r--r--common/uapi/dispatch.c1
-rw-r--r--common/uapi/irq.c28
-rw-r--r--common/uapi/proc.c1
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);
}