It's pretty easy on RISC-V: All platform specific configuration
information that we need is the interrupt controller.

Base/size fields are obvious, max_irq defines the highest possible IRQ
on the controller. max_priority the highest possible priority of an IRQ.

hart_to_context is a map that maps physical HART IDs to PLIC Contexts.
hart_to_context is not used in combination with the APLIC.

hart_to_context in combination with the PLIC works as follows: On
regular RISC-V platforms, M and S-Mode of a HART are assigned to one
specific PLIC 'context'. For example:

PLIC Ctx 0 -> Hart 0, M-Mode
PLIC Ctx 1 -> Hart 0, S-Mode
PLIC Ctx 2 -> Hart 1, M-Mode
PLIC Ctx 3 -> Hart 1, S-Mode
PLIC Ctx 4 -> Hart 2, M-Mode
...

This is also how QEMU implements the PLIC. However, there are other
implementations out there, like the NOEL-V.

There, we have:
PLIC Ctx 0 -> Hart 0, M-Mode
PLIC Ctx 1 -> Hart 0, S-Mode
PLIC Ctx 2 -> ?
PLIC Ctx 3 -> ?
PLIC Ctx 4 -> Hart 1, M-Mode
PLIC Ctx 5 -> Hart 1, S-Mode
PLIC Ctx 6 -> ?
...

So we use the hart_to_context map to assign a hart to a Context ID.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 include/jailhouse/cell-config.h | 13 +++++++++++++
 pyjailhouse/config_parser.py    | 21 ++++++++++++++++++---
 tools/jailhouse-config-check    |  6 ++++++
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/include/jailhouse/cell-config.h b/include/jailhouse/cell-config.h
index 56b512a4..787d6a26 100644
--- a/include/jailhouse/cell-config.h
+++ b/include/jailhouse/cell-config.h
@@ -332,6 +332,8 @@ struct jailhouse_pio {
 #define SYS_FLAGS_VIRTUAL_DEBUG_CONSOLE(flags) \
        !!((flags) & JAILHOUSE_SYS_VIRTUAL_DEBUG_CONSOLE)
 
+#define JAILHOUSE_RISCV_PLIC           0
+
 /**
  * General descriptor of the system.
  */
@@ -370,6 +372,17 @@ struct jailhouse_system {
                                u64 gicv_base;
                                u64 gicr_base;
                        } __attribute__((packed)) arm;
+                       struct {
+                               struct {
+                                       u16 max_irq;
+                                       u8 type;
+                                       u8 _res;
+                                       u64 base_address;
+                                       u32 size;
+                                       u32 max_priority;
+                                       s16 hart_to_context[32];
+                               } __attribute__((packed)) irqchip;
+                       } __attribute__((packed)) riscv;
                } __attribute__((packed));
        } __attribute__((packed)) platform_info;
        struct jailhouse_cell_desc root_cell;
diff --git a/pyjailhouse/config_parser.py b/pyjailhouse/config_parser.py
index 0fe30de9..4b2989ed 100644
--- a/pyjailhouse/config_parser.py
+++ b/pyjailhouse/config_parser.py
@@ -23,8 +23,9 @@ _CONFIG_REVISION = 15
 JAILHOUSE_X86 = 0
 JAILHOUSE_ARM = 1
 JAILHOUSE_ARM64 = 2
+JAILHOUSE_RISCV64 = 3
 
-JAILHOUSE_ARCH_MAX = 2
+JAILHOUSE_ARCH_MAX = 3
 
 
 def convert_arch(arch):
@@ -34,6 +35,7 @@ def convert_arch(arch):
         JAILHOUSE_X86: 'x86',
         JAILHOUSE_ARM: 'arm',
         JAILHOUSE_ARM64: 'arm64',
+        JAILHOUSE_RISCV64: 'riscv64',
     }[arch]
 
 
@@ -269,6 +271,8 @@ class SystemConfig:
     _NUM_IOMMUS = 8
     _ARCH_ARM_FORMAT = '=BB2xQQQQQ'
     _ARCH_X86_FORMAT = '=HBxIII28x'
+    _ARCH_RISCV_FORMAT = '=HBxQII'
+    _ARCH_RISCV_FORMAT_HTC = '=32H'
 
     def __init__(self, data):
         self.data = data
@@ -318,8 +322,19 @@ class SystemConfig:
                  self.x86_tsc_khz,
                  self.x86_apic_khz) = \
                      struct.unpack_from(self._ARCH_X86_FORMAT, 
self.data[offs:])
-
-            offs += struct.calcsize(self._ARCH_ARM_FORMAT)
+            elif self.arch == 'riscv64':
+                (self.riscv_irqchip_max_irq,
+                 self.riscv_irqchip_type,
+                 self.riscv_irqchip_base_address,
+                 self.riscv_irqchip_size,
+                 self.riscv_irqchip_max_priority) = \
+                     struct.unpack_from(self._ARCH_RISCV_FORMAT,
+                                        self.data[offs:])
+                self.riscv_plic_hart_to_context = \
+                     struct.unpack_from(self._ARCH_RISCV_FORMAT_HTC,
+                                        self.data[offs:])
+            offs += struct.calcsize(self._ARCH_RISCV_FORMAT)
+            offs += struct.calcsize(self._ARCH_RISCV_FORMAT_HTC)
         except struct.error:
             raise RuntimeError('Not a root cell configuration')
 
diff --git a/tools/jailhouse-config-check b/tools/jailhouse-config-check
index ebfe97a8..d738f347 100755
--- a/tools/jailhouse-config-check
+++ b/tools/jailhouse-config-check
@@ -174,6 +174,12 @@ elif sysconfig.arch == 'x86':
     for irqchip in root_cell.irqchips:
         arch_resources.append(ResourceRegion(irqchip.address, 0x1000,
                                              "IOAPIC"))
+elif sysconfig.arch == 'riscv64':
+    arch_resources = []
+    arch_resources.append(ResourceRegion(sysconfig.riscv_irqchip_base_address,
+                                         sysconfig.riscv_irqchip_size,
+                                         "(A)PLIC"))
+
 for cell in cells:
     for mem in cell.memory_regions:
         idx = cell.memory_regions.index(mem)
-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20230519204033.643200-32-ralf.ramsauer%40oth-regensburg.de.

Reply via email to