Same demo as for other architectures.

Signed-off-by: Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de>
---
 inmates/demos/riscv/Makefile       |   3 +-
 inmates/demos/riscv/timer-demo.c   |  57 +++++++++++++++
 inmates/lib/riscv/Makefile         |   2 +-
 inmates/lib/riscv/header.S         |  29 ++++++++
 inmates/lib/riscv/include/inmate.h |  27 +++++++-
 inmates/lib/riscv/inmate.lds.S     |   3 +
 inmates/lib/riscv/irq.c            | 107 +++++++++++++++++++++++++++++
 7 files changed, 225 insertions(+), 3 deletions(-)
 create mode 100644 inmates/demos/riscv/timer-demo.c
 create mode 100644 inmates/lib/riscv/irq.c

diff --git a/inmates/demos/riscv/Makefile b/inmates/demos/riscv/Makefile
index 2f0bac84..e371a29b 100644
--- a/inmates/demos/riscv/Makefile
+++ b/inmates/demos/riscv/Makefile
@@ -12,8 +12,9 @@
 
 include $(INMATES_LIB)/Makefile.lib
 
-INMATES := tiny-demo.bin
+INMATES := tiny-demo.bin timer-demo.bin
 
 tiny-demo-y    := tiny-demo.o
+timer-demo-y   := timer-demo.o
 
 $(eval $(call DECLARE_TARGETS,$(INMATES)))
diff --git a/inmates/demos/riscv/timer-demo.c b/inmates/demos/riscv/timer-demo.c
new file mode 100644
index 00000000..748219b7
--- /dev/null
+++ b/inmates/demos/riscv/timer-demo.c
@@ -0,0 +1,57 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) OTH Regensburg, 2022
+ *
+ * Authors:
+ *  Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <inmate.h>
+
+#include <jailhouse/hypercall.h>
+
+#define TIMEBASE_FREQ  0x989680
+#define TIMER_DELTA    (TIMEBASE_FREQ / 6)
+
+unsigned long timer_next;
+
+static inline u64 timer_ticks_to_ns(u64 ticks)
+{
+       return (1000UL * 1000UL * 1000UL * ticks) / TIMEBASE_FREQ;
+}
+
+unsigned long timer_handler(void)
+{
+       static u64 min_delta = ~0ULL, max_delta = 0;
+       unsigned long delta;
+
+       delta = get_cycles() - timer_next;
+       if (delta < min_delta)
+               min_delta = delta;
+       if (delta > max_delta)
+               max_delta = delta;
+
+       printk("Timer fired, jitter: %6ld ns, min: %6ld ns, max: %6ld ns\n",
+               (long)timer_ticks_to_ns(delta),
+               (long)timer_ticks_to_ns(min_delta),
+               (long)timer_ticks_to_ns(max_delta));
+
+       timer_next += TIMER_DELTA;
+
+       return timer_next;
+}
+
+void inmate_main(void)
+{
+       printk("Initializing the timer...\n");
+       timer_next = get_cycles() + 0x400000;
+       sbi_set_timer(timer_next);
+       timer_enable();
+       enable_irqs();
+
+       halt();
+}
diff --git a/inmates/lib/riscv/Makefile b/inmates/lib/riscv/Makefile
index 9ff57721..3b796dc3 100644
--- a/inmates/lib/riscv/Makefile
+++ b/inmates/lib/riscv/Makefile
@@ -41,6 +41,6 @@ include $(INMATES_LIB)/Makefile.lib
 always-y := lib.a inmate.lds
 
 lib-y := $(common-objs-y)
-lib-y += header.o printk.o setup.o uart.o
+lib-y += header.o irq.o printk.o setup.o uart.o
 
 lib-y += ../cmdline.o ../printk.o ../setup.o ../string.o ../uart-8250.o
diff --git a/inmates/lib/riscv/header.S b/inmates/lib/riscv/header.S
index 3a12f51f..5ddffe79 100644
--- a/inmates/lib/riscv/header.S
+++ b/inmates/lib/riscv/header.S
@@ -36,9 +36,38 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define STRUCT_REGISTERS_SIZE (32 * 8)
+
+.macro context cmd
+        .irp reg 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, \
+                19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+                \cmd    x\reg, 8*(\reg - 1)(sp)
+        .endr
+.endm
+
 .section ".boot", "ax"
 
        .globl __reset_entry
 __reset_entry:
        la      sp, __stack_top
+       addi    sp, sp, -STRUCT_REGISTERS_SIZE
+
+       la      a5 , __ex_stack_top
+       csrw    sscratch, a5
+
+       la      a5, exception_handler
+       csrw    stvec, a5
+
        j       c_entry
+
+.text
+.align 4
+exception_handler:
+       csrrw   sp, sscratch, sp
+       context sd
+
+       jal arch_handle_trap
+
+       context ld
+       csrrw   sp, sscratch, sp
+       sret
diff --git a/inmates/lib/riscv/include/inmate.h 
b/inmates/lib/riscv/include/inmate.h
index dac9f146..57338d25 100644
--- a/inmates/lib/riscv/include/inmate.h
+++ b/inmates/lib/riscv/include/inmate.h
@@ -1,7 +1,7 @@
 /*
  * Jailhouse, a Linux-based partitioning hypervisor
  *
- * Copyright (c) OTH Regensburg
+ * Copyright (c) OTH Regensburg, 2022
  *
  * Authors:
  *  Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de>
@@ -60,6 +60,9 @@ typedef unsigned long long u64;
 
 #define SR_SIE 0x00000002UL
 
+#define IRQ_S_TIMER    5
+#define IE_TIE         (0x1UL << IRQ_S_TIMER)
+
 #define csr_read(csr)                                           \
 ({                                                              \
        register unsigned long __v;                             \
@@ -93,11 +96,31 @@ typedef unsigned long long u64;
                              : "memory");                      \
 })
 
+static inline unsigned long get_cycles(void)
+{
+       return csr_read(time);
+}
+
 static inline void disable_irqs(void)
 {
        csr_clear(sstatus, SR_SIE);
 }
 
+static inline void enable_irqs(void)
+{
+       csr_set(sstatus, SR_SIE);
+}
+
+static inline void timer_enable(void)
+{
+       csr_set(sie, IE_TIE);
+}
+
+static inline void timer_disable(void)
+{
+       csr_clear(sie, IE_TIE);
+}
+
 static inline void cpu_relax(void)
 {
        int dummy;
@@ -152,6 +175,8 @@ static inline void mmio_write64(void *address, u64 value)
        *(volatile u64 *)address = value;
 }
 
+unsigned long timer_handler(void);
+
 #include <inmate_common.h>
 
 #endif /* !_JAILHOUSE_INMATE_H */
diff --git a/inmates/lib/riscv/inmate.lds.S b/inmates/lib/riscv/inmate.lds.S
index cb6e7a76..91bc8f22 100644
--- a/inmates/lib/riscv/inmate.lds.S
+++ b/inmates/lib/riscv/inmate.lds.S
@@ -69,6 +69,9 @@ SECTIONS {
        . = ALIGN(4096);
        . = . + 0x1000;
        __stack_top = .;
+
+       . = . + 0x1000;
+       __ex_stack_top = .;
 }
 
 ENTRY(__reset_entry)
diff --git a/inmates/lib/riscv/irq.c b/inmates/lib/riscv/irq.c
new file mode 100644
index 00000000..8f6d0085
--- /dev/null
+++ b/inmates/lib/riscv/irq.c
@@ -0,0 +1,107 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) OTH Regensburg, 2022
+ *
+ * Authors:
+ *  Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Alternatively, you can use or redistribute this file under the following
+ * BSD license:
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <inmate.h>
+
+#define CAUSE_IRQ_FLAG (1UL << (__riscv_xlen - 1))
+
+void arch_handle_trap(void);
+
+static inline bool is_irq(u64 cause)
+{
+       return !!(cause & CAUSE_IRQ_FLAG);
+}
+
+static inline unsigned long to_irq(unsigned long cause)
+{
+       return cause & ~CAUSE_IRQ_FLAG;
+}
+
+static int handle_irq(unsigned int irq)
+{
+       int err;
+       struct sbiret ret;
+       unsigned long tval;
+
+       switch (irq) {
+               case IRQ_S_TIMER:
+                       tval = timer_handler();
+                       ret = sbi_set_timer(tval);
+                       err = ret.error;
+                       break;
+
+               default:
+                       err = -1;
+                       break;
+       }
+       return err;
+}
+
+/*
+ * Any positive value will reprogramm the timer, -1 will halt the timer.
+ */
+unsigned long __attribute__((weak)) timer_handler(void)
+{
+       return -1;
+}
+
+void arch_handle_trap(void)
+{
+       unsigned long scause = csr_read(scause);
+       int err;
+
+       if (is_irq(scause)) {
+               err = handle_irq(to_irq(scause));
+               goto out;
+       }
+
+       switch (scause) {
+       default:
+               /* We don't have any exception handlers at the moment */
+               printk("Unhandled exception %lu occured.\n", scause);
+               err = -1;
+               break;
+       }
+
+out:
+       if (err) {
+               printk("FATAL INMATE ERROR. HALTED.\n");
+               stop();
+
+       }
+}
-- 
2.40.1

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20230519204033.643200-54-ralf.ramsauer%40oth-regensburg.de.

Reply via email to