From: Emmanuel Blot <[email protected]>

1. Define a generic version of lowrisc-ibex core that can be used in several 
machines:

 - leave MISA empty so that generic properties can be defined for this core
 - remove all arbitrary default properties but ISA I,C,U which are mandatory 
for ibex
 - define default mtvec which is only support vectored mode
 - update privilege version (1.12) according to the Ibex documentation
 - define ibex architecture identifier
 - remove hart array (mostly useless, its definition is incoherent and
   prevent from applying properties to CPU cores)

2. Add an EarlGrey machine that uses this new definition

Signed-off-by: Loïc Lefort <[email protected]>
Signed-off-by: Emmanuel Blot <[email protected]>
Signed-off-by: Lex Bailey <[email protected]>
---
 MAINTAINERS                    |   7 +
 hw/Kconfig                     |   3 +
 hw/meson.build                 |   1 +
 hw/opentitan/Kconfig           |   2 +
 hw/opentitan/meson.build       |   2 +
 hw/opentitan/trace-events      |   1 +
 hw/opentitan/trace.h           |   2 +
 hw/riscv/Kconfig               |   7 +
 hw/riscv/ibex_common.c         |  10 +-
 hw/riscv/meson.build           |   1 +
 hw/riscv/opentitan.c           |  30 +-
 hw/riscv/ot_earlgrey.c         | 734 +++++++++++++++++++++++++++++++++
 include/hw/riscv/ibex_common.h |   2 +-
 include/hw/riscv/opentitan.h   |   4 +-
 include/hw/riscv/ot_earlgrey.h |  27 ++
 meson.build                    |   1 +
 target/riscv/cpu-qom.h         |   2 +
 target/riscv/cpu.c             |  14 +-
 18 files changed, 829 insertions(+), 21 deletions(-)
 create mode 100644 hw/opentitan/Kconfig
 create mode 100644 hw/opentitan/meson.build
 create mode 100644 hw/opentitan/trace-events
 create mode 100644 hw/opentitan/trace.h
 create mode 100644 hw/riscv/ot_earlgrey.c
 create mode 100644 include/hw/riscv/ot_earlgrey.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 8b8bb7b554..c7f98e4b61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4460,6 +4460,13 @@ S: Supported
 F: hw/riscv/ibex_common.c
 F: include/hw/riscv/ibex_common.h
 F: include/hw/riscv/ibex_irq.h
+
+OpenTitan
+M: lowRISC <[email protected]>
+S: Supported
+F: hw/opentitan/*
+F: include/hw/opentitan/*
+
 Build and test automation
 -------------------------
 Build and test automation, general continuous integration
diff --git a/hw/Kconfig b/hw/Kconfig
index f8f92b5d03..5215240092 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -69,6 +69,9 @@ source sparc64/Kconfig
 source tricore/Kconfig
 source xtensa/Kconfig
 
+# OpenTitan devices
+source opentitan/Kconfig
+
 # Symbols used by multiple targets
 config TEST_DEVICES
     bool
diff --git a/hw/meson.build b/hw/meson.build
index 66e46b8090..f00346854e 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -20,6 +20,7 @@ subdir('sparc')
 subdir('sparc64')
 subdir('tricore')
 subdir('xtensa')
+subdir('opentitan')
 
 subdir('9pfs')
 subdir('acpi')
diff --git a/hw/opentitan/Kconfig b/hw/opentitan/Kconfig
new file mode 100644
index 0000000000..6bd1855a84
--- /dev/null
+++ b/hw/opentitan/Kconfig
@@ -0,0 +1,2 @@
+# OpenTitan devices
+
diff --git a/hw/opentitan/meson.build b/hw/opentitan/meson.build
new file mode 100644
index 0000000000..6bd1855a84
--- /dev/null
+++ b/hw/opentitan/meson.build
@@ -0,0 +1,2 @@
+# OpenTitan devices
+
diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events
new file mode 100644
index 0000000000..695debd380
--- /dev/null
+++ b/hw/opentitan/trace-events
@@ -0,0 +1 @@
+# OpenTitan EarlGrey Trace Events
diff --git a/hw/opentitan/trace.h b/hw/opentitan/trace.h
new file mode 100644
index 0000000000..17c1fd28ed
--- /dev/null
+++ b/hw/opentitan/trace.h
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "trace/trace-hw_opentitan.h"
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 7877f0615c..76588c43ae 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -12,6 +12,13 @@ config IBEX_COMMON
 
 # RISC-V machines in alphabetical order
 
+config OT_EARLGREY
+    bool
+    default y
+    select IBEX
+    select IBEX_COMMON
+    select SIFIVE_PLIC
+
 config MICROCHIP_PFSOC
     bool
     default y
diff --git a/hw/riscv/ibex_common.c b/hw/riscv/ibex_common.c
index c6056767c7..6b53662a5b 100644
--- a/hw/riscv/ibex_common.c
+++ b/hw/riscv/ibex_common.c
@@ -17,13 +17,13 @@
 #include "disas/disas.h"
 #include "elf.h"
 #include "exec/hwaddr.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
+#include "hw/core/boards.h"
+#include "hw/core/loader.h"
 #include "hw/misc/unimp.h"
-#include "hw/qdev-core.h"
-#include "hw/qdev-properties.h"
+#include "hw/core/qdev.h"
+#include "hw/core/qdev-properties.h"
 #include "hw/riscv/ibex_common.h"
-#include "hw/sysbus.h"
+#include "hw/core/sysbus.h"
 #include "monitor/monitor.h"
 
 
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index 70d63f56b5..76dc93147a 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -4,6 +4,7 @@ riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: 
files('numa.c'))
 riscv_ss.add(files('riscv_hart.c'))
 riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
 riscv_ss.add(when: 'CONFIG_IBEX_COMMON', if_true: files('ibex_common.c'))
+riscv_ss.add(when: 'CONFIG_OT_EARLGREY', if_true: files('ot_earlgrey.c'))
 riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c'))
 riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c'))
 riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifive_e.c'))
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 19cb35b351..22f8b20f42 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -104,7 +104,9 @@ static void opentitan_machine_init(MachineState *machine)
         riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL);
     }
 
-    riscv_boot_info_init(&boot_info, &s->soc.cpus);
+    boot_info.kernel_size = 0;
+    boot_info.is_32bit = 1;
+
     if (machine->kernel_filename) {
         riscv_load_kernel(machine, &boot_info,
                           memmap[IBEX_DEV_RAM].base,
@@ -119,7 +121,7 @@ static void opentitan_machine_class_init(ObjectClass *oc, 
const void *data)
     mc->desc = "RISC-V Board compatible with OpenTitan";
     mc->init = opentitan_machine_init;
     mc->max_cpus = 1;
-    mc->default_cpu_type = TYPE_RISCV_CPU_LOWRISC_IBEX;
+    mc->default_cpu_type = TYPE_RISCV_CPU_LOWRISC_OPENTITAN;
     mc->default_ram_id = "riscv.lowrisc.ibex.ram";
     mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
 }
@@ -128,7 +130,7 @@ static void lowrisc_ibex_soc_init(Object *obj)
 {
     LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
 
-    object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
+    object_initialize_child(obj, "cpu", &s->cpu, 
TYPE_RISCV_CPU_LOWRISC_OPENTITAN);
 
     object_initialize_child(obj, "plic", &s->plic, TYPE_SIFIVE_PLIC);
 
@@ -152,13 +154,17 @@ static void lowrisc_ibex_soc_realize(DeviceState 
*dev_soc, Error **errp)
     MemoryRegion *sys_mem = get_system_memory();
     int i;
 
-    object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
-                            &error_abort);
-    object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
-                            &error_abort);
-    object_property_set_int(OBJECT(&s->cpus), "resetvec", s->resetvec,
-                            &error_abort);
-    sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
+    Object *cpu = OBJECT(&s->cpu);
+    object_property_set_int(cpu, "resetvec", s->resetvec,
+                            &error_fatal);
+    object_property_set_bool(cpu, "m", true, &error_fatal);
+    object_property_set_bool(cpu, "pmp", true, &error_fatal);
+    object_property_set_bool(cpu, "zba", true, &error_fatal);
+    object_property_set_bool(cpu, "zbb", true, &error_fatal);
+    object_property_set_bool(cpu, "zbc", true, &error_fatal);
+    object_property_set_bool(cpu, "zbs", true, &error_fatal);
+    object_property_set_bool(cpu, "smepmp", true, &error_fatal);
+    qdev_realize(DEVICE(&s->cpu), NULL, &error_fatal);
 
     /* Boot ROM */
     memory_region_init_rom(&s->rom, OBJECT(dev_soc), "riscv.lowrisc.ibex.rom",
@@ -194,10 +200,10 @@ static void lowrisc_ibex_soc_realize(DeviceState 
*dev_soc, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_DEV_PLIC].base);
 
     for (i = 0; i < ms->smp.cpus; i++) {
-        CPUState *cpu = qemu_get_cpu(i);
+        CPUState *cpu_i = qemu_get_cpu(i);
 
         qdev_connect_gpio_out(DEVICE(&s->plic), ms->smp.cpus + i,
-                              qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
+                              qdev_get_gpio_in(DEVICE(cpu_i), IRQ_M_EXT));
     }
 
     /* UART */
diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c
new file mode 100644
index 0000000000..760a8d2c2e
--- /dev/null
+++ b/hw/riscv/ot_earlgrey.c
@@ -0,0 +1,734 @@
+/*
+ * QEMU RISC-V Board Compatible with OpenTitan EarlGrey FPGA platform
+ *
+ * Copyright (c) 2022-2023 Rivos, Inc.
+ *
+ * Author(s):
+ *  Emmanuel Blot <[email protected]>
+ *  Loïc Lefort <[email protected]>
+ *
+ * This implementation is based on OpenTitan RTL version:
+ *  <lowRISC/opentitan@caa3bd0a14ddebbf60760490f7c917901482c8fd>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "system/address-spaces.h"
+#include "hw/core/boards.h"
+#include "hw/intc/sifive_plic.h"
+#include "hw/misc/unimp.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/riscv/ibex_common.h"
+#include "hw/riscv/ot_earlgrey.h"
+#include "system/system.h"
+
+/* ------------------------------------------------------------------------ */
+/* Constants */
+/* ------------------------------------------------------------------------ */
+
+#define OT_EARLGREY_PERIPHERAL_CLK_HZ 2500000u
+
+enum OtEarlgreySocMemory {
+    OT_EARLGREY_SOC_MEM_ROM,
+    OT_EARLGREY_SOC_MEM_RAM,
+    OT_EARLGREY_SOC_MEM_FLASH,
+};
+
+static const MemMapEntry ot_earlgrey_soc_memories[] = {
+    [OT_EARLGREY_SOC_MEM_ROM] = { 0x00008000u, 0x8000u },
+    [OT_EARLGREY_SOC_MEM_RAM] = { 0x10000000u, 0x20000u },
+    [OT_EARLGREY_SOC_MEM_FLASH] = { 0x20000000u, 0x100000u },
+};
+
+enum OtEarlgreySocDevice {
+    OT_EARLGREY_SOC_DEV_ADC_CTRL,
+    OT_EARLGREY_SOC_DEV_AES,
+    OT_EARLGREY_SOC_DEV_ALERT_HANDLER,
+    OT_EARLGREY_SOC_DEV_AON_TIMER,
+    OT_EARLGREY_SOC_DEV_AST,
+    OT_EARLGREY_SOC_DEV_CLKMGR,
+    OT_EARLGREY_SOC_DEV_CSRNG,
+    OT_EARLGREY_SOC_DEV_EDN0,
+    OT_EARLGREY_SOC_DEV_EDN1,
+    OT_EARLGREY_SOC_DEV_ENTROPY_SRC,
+    OT_EARLGREY_SOC_DEV_FLASH_CTRL,
+    OT_EARLGREY_SOC_DEV_FLASH_CTRL_PRIM,
+    OT_EARLGREY_SOC_DEV_GPIO,
+    OT_EARLGREY_SOC_DEV_HART,
+    OT_EARLGREY_SOC_DEV_HMAC,
+    OT_EARLGREY_SOC_DEV_I2C0,
+    OT_EARLGREY_SOC_DEV_I2C1,
+    OT_EARLGREY_SOC_DEV_I2C2,
+    OT_EARLGREY_SOC_DEV_IBEX_WRAPPER,
+    OT_EARLGREY_SOC_DEV_KEYMGR,
+    OT_EARLGREY_SOC_DEV_KMAC,
+    OT_EARLGREY_SOC_DEV_LC_CTRL,
+    OT_EARLGREY_SOC_DEV_OTBN,
+    OT_EARLGREY_SOC_DEV_OTP_CTRL,
+    OT_EARLGREY_SOC_DEV_OTP_CTRL_PRIM,
+    OT_EARLGREY_SOC_DEV_PATTGEN,
+    OT_EARLGREY_SOC_DEV_PINMUX,
+    OT_EARLGREY_SOC_DEV_PLIC,
+    OT_EARLGREY_SOC_DEV_PWM,
+    OT_EARLGREY_SOC_DEV_PWRMGR,
+    OT_EARLGREY_SOC_DEV_RAM_RET,
+    OT_EARLGREY_SOC_DEV_ROM_CTRL,
+    OT_EARLGREY_SOC_DEV_RSTMGR,
+    OT_EARLGREY_SOC_DEV_RV_DM,
+    OT_EARLGREY_SOC_DEV_RV_DM_MEM,
+    OT_EARLGREY_SOC_DEV_SENSOR_CTRL,
+    OT_EARLGREY_SOC_DEV_SPI_DEVICE,
+    OT_EARLGREY_SOC_DEV_SPI_HOST0,
+    OT_EARLGREY_SOC_DEV_SPI_HOST1,
+    OT_EARLGREY_SOC_DEV_SRAM_CTRL,
+    OT_EARLGREY_SOC_DEV_SRAM_CTRL_MAIN,
+    OT_EARLGREY_SOC_DEV_SYSRST_CTRL,
+    OT_EARLGREY_SOC_DEV_TIMER,
+    OT_EARLGREY_SOC_DEV_UART0,
+    OT_EARLGREY_SOC_DEV_UART1,
+    OT_EARLGREY_SOC_DEV_UART2,
+    OT_EARLGREY_SOC_DEV_UART3,
+    OT_EARLGREY_SOC_DEV_USBDEV,
+};
+
+#define OT_EARLGREY_SOC_GPIO(_irq_, _target_, _num_) \
+    IBEX_GPIO(_irq_, OT_EARLGREY_SOC_DEV_##_target_, _num_)
+
+#define OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(_irq_, _target_, _num_) \
+    IBEX_GPIO_SYSBUS_IRQ(_irq_, OT_EARLGREY_SOC_DEV_##_target_, _num_)
+
+#define OT_EARLGREY_SOC_DEVLINK(_pname_, _target_) \
+    IBEX_DEVLINK(_pname_, OT_EARLGREY_SOC_DEV_##_target_)
+
+/*
+ * MMIO/interrupt mapping as per:
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
+ * and
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey.h
+ */
+static const IbexDeviceDef ot_earlgrey_soc_devices[] = {
+    /* clang-format off */
+    [OT_EARLGREY_SOC_DEV_HART] = {
+        .type = TYPE_RISCV_CPU_LOWRISC_OPENTITAN,
+        .prop = IBEXDEVICEPROPDEFS(
+            IBEX_DEV_BOOL_PROP("zba", true),
+            IBEX_DEV_BOOL_PROP("zbb", true),
+            IBEX_DEV_BOOL_PROP("zbc", true),
+            IBEX_DEV_BOOL_PROP("zbs", true),
+            IBEX_DEV_BOOL_PROP("smepmp", true)
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_RV_DM_MEM] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-rv_dm_mem",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x00010000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_UART0] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-uart",
+        .cfg = &ibex_unimp_configure,
+        .instance = 0,
+        .memmap = MEMMAPENTRIES(
+            { 0x40000000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_UART1] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-uart",
+        .cfg = &ibex_unimp_configure,
+        .instance = 1,
+        .memmap = MEMMAPENTRIES(
+            { 0x40010000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_UART2] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-uart",
+        .cfg = &ibex_unimp_configure,
+        .instance = 2,
+        .memmap = MEMMAPENTRIES(
+            { 0x40020000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_UART3] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-uart",
+        .cfg = &ibex_unimp_configure,
+        .instance = 3,
+        .memmap = MEMMAPENTRIES(
+            { 0x40030000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_GPIO] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-gpio",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40040000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SPI_DEVICE] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-spi_device",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40050000u, 0x2000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_I2C0] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-i2c",
+        .cfg = &ibex_unimp_configure,
+        .instance = 0,
+        .memmap = MEMMAPENTRIES(
+            { 0x40080000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_I2C1] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-i2c",
+        .cfg = &ibex_unimp_configure,
+        .instance = 1,
+        .memmap = MEMMAPENTRIES(
+            { 0x40090000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_I2C2] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-i2c",
+        .cfg = &ibex_unimp_configure,
+        .instance = 2,
+        .memmap = MEMMAPENTRIES(
+            { 0x400a0000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_PATTGEN] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-pattgen",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x400e0000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_TIMER] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-timer",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40100000u, 0x200u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_OTP_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-otp_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40130000u, 0x2000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_OTP_CTRL_PRIM] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-ot_ctrl_prim",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40132000u, 0x20u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_LC_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-lc_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40140000u, 0x100u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_ALERT_HANDLER] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-alert_handler",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40150000u, 0x800u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SPI_HOST0] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-spi_host",
+        .cfg = &ibex_unimp_configure,
+        .instance = 0,
+        .memmap = MEMMAPENTRIES(
+            { 0x40300000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SPI_HOST1] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-spi_host",
+        .cfg = &ibex_unimp_configure,
+        .instance = 1,
+        .memmap = MEMMAPENTRIES(
+            { 0x40310000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_USBDEV] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-usbdev",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40320000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_PWRMGR] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-pwrmgr",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40400000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_RSTMGR] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-rstmgr",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40410000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_CLKMGR] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-clkmgr",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40420000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SYSRST_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-sysrst_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40430000u, 0x100u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_ADC_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-adc_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40440000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_PWM] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-pwm",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40450000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_PINMUX] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-pinmux",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40460000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_AON_TIMER] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-aon_timer",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40470000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_AST] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-ast",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40480000u, 0x400u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SENSOR_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-sensor_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40490000u, 0x40u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SRAM_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-sram_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40500000u, 0x20u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_RAM_RET] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-ram_ret",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x40600000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_FLASH_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-flash_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41000000u, 0x200u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_FLASH_CTRL_PRIM] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-flash_ctrl_prim",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41008000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_AES] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-aes",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41100000u, 0x100u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_HMAC] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-hmac",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41110000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_KMAC] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-kmac",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41120000u, 0x1000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_OTBN] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-otbn",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41130000u, 0x10000u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_KEYMGR] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-keymgr",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41140000u, 0x100u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_CSRNG] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-csrng",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41150000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_ENTROPY_SRC] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-entropy_src",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41160000u, 0x100u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_EDN0] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-edn",
+        .cfg = &ibex_unimp_configure,
+        .instance = 0,
+        .memmap = MEMMAPENTRIES(
+            { 0x41170000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_EDN1] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-edn",
+        .cfg = &ibex_unimp_configure,
+        .instance = 1,
+        .memmap = MEMMAPENTRIES(
+            { 0x41180000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_SRAM_CTRL_MAIN] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-sram_ctrl_main",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x411c0000u, 0x20u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_ROM_CTRL] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-rom_ctrl",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x411e0000u, 0x80u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_IBEX_WRAPPER] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-ibex_wrapper",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x411f0000u, 0x100u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_RV_DM] = {
+        .type = TYPE_UNIMPLEMENTED_DEVICE,
+        .name = "ot-rv_dm",
+        .cfg = &ibex_unimp_configure,
+        .memmap = MEMMAPENTRIES(
+            { 0x41200000u, 0x4u }
+        ),
+    },
+    [OT_EARLGREY_SOC_DEV_PLIC] = {
+        .type = TYPE_SIFIVE_PLIC,
+        .memmap = MEMMAPENTRIES(
+            { 0x48000000u, 0x8000000u }
+        ),
+        .gpio = IBEXGPIOCONNDEFS(
+            OT_EARLGREY_SOC_GPIO(1, HART, IRQ_M_EXT)
+        ),
+        .prop = IBEXDEVICEPROPDEFS(
+            IBEX_DEV_STRING_PROP("hart-config", "M"),
+            IBEX_DEV_UINT_PROP("hartid-base", 0u),
+            /* note: should always be max_irq + 1 */
+            IBEX_DEV_UINT_PROP("num-sources", 185u),
+            IBEX_DEV_UINT_PROP("num-priorities", 3u),
+            IBEX_DEV_UINT_PROP("priority-base", 0x0u),
+            IBEX_DEV_UINT_PROP("pending-base", 0x1000u),
+            IBEX_DEV_UINT_PROP("enable-base", 0x2000u),
+            IBEX_DEV_UINT_PROP("enable-stride", 32u),
+            IBEX_DEV_UINT_PROP("context-base", 0x200000u),
+            IBEX_DEV_UINT_PROP("context-stride", 8u),
+            IBEX_DEV_UINT_PROP("aperture-size", 0x8000000u)
+        ),
+    },
+    /* clang-format on */
+};
+
+enum OtEarlgreyBoardDevice {
+    OT_EARLGREY_BOARD_DEV_SOC,
+    _OT_EARLGREY_BOARD_DEV_COUNT,
+};
+
+/* ------------------------------------------------------------------------ */
+/* Type definitions */
+/* ------------------------------------------------------------------------ */
+
+struct OtEarlGreySoCState {
+    SysBusDevice parent_obj;
+
+    DeviceState **devices;
+    MemoryRegion *memories;
+};
+
+struct OtEarlGreyBoardState {
+    DeviceState parent_obj;
+
+    DeviceState **devices;
+};
+
+struct OtEarlGreyMachineState {
+    MachineState parent_obj;
+};
+
+/* ------------------------------------------------------------------------ */
+/* SoC */
+/* ------------------------------------------------------------------------ */
+
+static void ot_earlgrey_soc_reset(DeviceState *dev)
+{
+    OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(dev);
+
+    cpu_reset(CPU(s->devices[OT_EARLGREY_SOC_DEV_HART]));
+}
+
+static void ot_earlgrey_soc_realize(DeviceState *dev, Error **errp)
+{
+    OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(dev);
+    const MemMapEntry *memmap = &ot_earlgrey_soc_memories[0];
+
+    MachineState *ms = MACHINE(qdev_get_machine());
+    MemoryRegion *sys_mem = get_system_memory();
+
+    /* RAM */
+    memory_region_add_subregion(sys_mem, memmap[OT_EARLGREY_SOC_MEM_RAM].base,
+                                ms->ram);
+
+    /* Boot ROM */
+    memory_region_init_rom(&s->memories[OT_EARLGREY_SOC_MEM_ROM], OBJECT(dev),
+                           "ot-rom", memmap[OT_EARLGREY_SOC_MEM_ROM].size,
+                           &error_fatal);
+    memory_region_add_subregion(sys_mem, memmap[OT_EARLGREY_SOC_MEM_ROM].base,
+                                &s->memories[OT_EARLGREY_SOC_MEM_ROM]);
+
+    /* Flash memory */
+    memory_region_init_rom(&s->memories[OT_EARLGREY_SOC_MEM_FLASH], 
OBJECT(dev),
+                           "ot-flash", memmap[OT_EARLGREY_SOC_MEM_FLASH].size,
+                           &error_fatal);
+    memory_region_add_subregion(sys_mem, 
memmap[OT_EARLGREY_SOC_MEM_FLASH].base,
+                                &s->memories[OT_EARLGREY_SOC_MEM_FLASH]);
+
+    /* Link, define properties and realize devices, then connect GPIOs */
+    ibex_link_devices(s->devices, ot_earlgrey_soc_devices,
+                      ARRAY_SIZE(ot_earlgrey_soc_devices));
+    ibex_define_device_props(s->devices, ot_earlgrey_soc_devices,
+                             ARRAY_SIZE(ot_earlgrey_soc_devices));
+    ibex_realize_system_devices(s->devices, ot_earlgrey_soc_devices,
+                                ARRAY_SIZE(ot_earlgrey_soc_devices));
+    ibex_connect_devices(s->devices, ot_earlgrey_soc_devices,
+                         ARRAY_SIZE(ot_earlgrey_soc_devices));
+
+    /* load kernel if provided */
+    ibex_load_kernel(NULL);
+}
+
+static void ot_earlgrey_soc_init(Object *obj)
+{
+    OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(obj);
+
+    s->devices =
+        ibex_create_devices(ot_earlgrey_soc_devices,
+                            ARRAY_SIZE(ot_earlgrey_soc_devices), DEVICE(s));
+    s->memories = g_new0(MemoryRegion, ARRAY_SIZE(ot_earlgrey_soc_memories));
+}
+
+static void ot_earlgrey_soc_class_init(ObjectClass *oc, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->legacy_reset = &ot_earlgrey_soc_reset;
+    dc->realize = &ot_earlgrey_soc_realize;
+    dc->user_creatable = false;
+}
+
+static const TypeInfo ot_earlgrey_soc_type_info = {
+    .name = TYPE_RISCV_OT_EARLGREY_SOC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OtEarlGreySoCState),
+    .instance_init = &ot_earlgrey_soc_init,
+    .class_init = &ot_earlgrey_soc_class_init,
+};
+
+static void ot_earlgrey_soc_register_types(void)
+{
+    type_register_static(&ot_earlgrey_soc_type_info);
+}
+
+type_init(ot_earlgrey_soc_register_types);
+
+/* ------------------------------------------------------------------------ */
+/* Board */
+/* ------------------------------------------------------------------------ */
+
+static void ot_earlgrey_board_realize(DeviceState *dev, Error **errp)
+{
+    OtEarlGreyBoardState *board = RISCV_OT_EARLGREY_BOARD(dev);
+
+    DeviceState *soc = board->devices[OT_EARLGREY_BOARD_DEV_SOC];
+    object_property_add_child(OBJECT(board), "soc", OBJECT(soc));
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(soc), &error_fatal);
+}
+
+static void ot_earlgrey_board_init(Object *obj)
+{
+    OtEarlGreyBoardState *s = RISCV_OT_EARLGREY_BOARD(obj);
+
+    s->devices = g_new0(DeviceState *, _OT_EARLGREY_BOARD_DEV_COUNT);
+    s->devices[OT_EARLGREY_BOARD_DEV_SOC] =
+        qdev_new(TYPE_RISCV_OT_EARLGREY_SOC);
+}
+
+static void ot_earlgrey_board_class_init(ObjectClass *oc, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = &ot_earlgrey_board_realize;
+}
+
+static const TypeInfo ot_earlgrey_board_type_info = {
+    .name = TYPE_RISCV_OT_EARLGREY_BOARD,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(OtEarlGreyBoardState),
+    .instance_init = &ot_earlgrey_board_init,
+    .class_init = &ot_earlgrey_board_class_init,
+};
+
+static void ot_earlgrey_board_register_types(void)
+{
+    type_register_static(&ot_earlgrey_board_type_info);
+}
+
+type_init(ot_earlgrey_board_register_types);
+
+/* ------------------------------------------------------------------------ */
+/* Machine */
+/* ------------------------------------------------------------------------ */
+
+static void ot_earlgrey_machine_instance_init(Object *obj)
+{
+    OtEarlGreyMachineState *s = RISCV_OT_EARLGREY_MACHINE(obj);
+
+    /* nothing here */
+    (void)s;
+}
+
+static void ot_earlgrey_machine_init(MachineState *state)
+{
+    DeviceState *dev = qdev_new(TYPE_RISCV_OT_EARLGREY_BOARD);
+
+    object_property_add_child(OBJECT(state), "board", OBJECT(dev));
+    qdev_realize(dev, NULL, &error_fatal);
+}
+
+static void ot_earlgrey_machine_class_init(ObjectClass *oc, const void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "RISC-V Board compatible with OpenTitan EarlGrey FPGA platform";
+    mc->init = ot_earlgrey_machine_init;
+    mc->max_cpus = 1u;
+    mc->default_cpu_type =
+        ot_earlgrey_soc_devices[OT_EARLGREY_SOC_DEV_HART].type;
+    mc->default_ram_id = "ot-ram";
+    mc->default_ram_size =
+        ot_earlgrey_soc_memories[OT_EARLGREY_SOC_MEM_RAM].size;
+}
+
+static const TypeInfo ot_earlgrey_machine_type_info = {
+    .name = TYPE_RISCV_OT_EARLGREY_MACHINE,
+    .parent = TYPE_MACHINE,
+    .instance_size = sizeof(OtEarlGreyMachineState),
+    .instance_init = &ot_earlgrey_machine_instance_init,
+    .class_init = &ot_earlgrey_machine_class_init,
+};
+
+static void ot_earlgrey_machine_register_types(void)
+{
+    type_register_static(&ot_earlgrey_machine_type_info);
+}
+
+type_init(ot_earlgrey_machine_register_types);
diff --git a/include/hw/riscv/ibex_common.h b/include/hw/riscv/ibex_common.h
index 6c7dae5cbe..963ab1fa78 100644
--- a/include/hw/riscv/ibex_common.h
+++ b/include/hw/riscv/ibex_common.h
@@ -16,7 +16,7 @@
 #include "qemu/osdep.h"
 #include "qom/object.h"
 #include "exec/hwaddr.h"
-#include "hw/qdev-core.h"
+#include "hw/core/qdev.h"
 
 
 /* ------------------------------------------------------------------------ */
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 5b9016e1d8..0da19c671f 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -19,13 +19,13 @@
 #ifndef HW_OPENTITAN_H
 #define HW_OPENTITAN_H
 
-#include "hw/riscv/riscv_hart.h"
 #include "hw/intc/sifive_plic.h"
 #include "hw/char/ibex_uart.h"
 #include "hw/timer/ibex_timer.h"
 #include "hw/ssi/ibex_spi_host.h"
 #include "hw/core/boards.h"
 #include "qom/object.h"
+#include "target/riscv/cpu.h"
 
 #define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
 OBJECT_DECLARE_SIMPLE_TYPE(LowRISCIbexSoCState, RISCV_IBEX_SOC)
@@ -41,7 +41,7 @@ struct LowRISCIbexSoCState {
     SysBusDevice parent_obj;
 
     /*< public >*/
-    RISCVHartArrayState cpus;
+    RISCVCPU cpu;
     SiFivePLICState plic;
     IbexUartState uart;
     IbexTimerState timer;
diff --git a/include/hw/riscv/ot_earlgrey.h b/include/hw/riscv/ot_earlgrey.h
new file mode 100644
index 0000000000..650f53a9dd
--- /dev/null
+++ b/include/hw/riscv/ot_earlgrey.h
@@ -0,0 +1,27 @@
+/*
+ * QEMU RISC-V Board Compatible with OpenTitan EarlGrey FPGA platform
+ *
+ * Copyright (c) 2022-2023 Rivos, Inc.
+ *
+ * Author(s):
+ *  Loïc Lefort <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#ifndef HW_RISCV_OT_EARLGREY_H
+#define HW_RISCV_OT_EARLGREY_H
+
+#include "qom/object.h"
+
+#define TYPE_RISCV_OT_EARLGREY_MACHINE MACHINE_TYPE_NAME("ot-earlgrey")
+OBJECT_DECLARE_SIMPLE_TYPE(OtEarlGreyMachineState, RISCV_OT_EARLGREY_MACHINE)
+
+#define TYPE_RISCV_OT_EARLGREY_BOARD "riscv.ot_earlgrey.board"
+OBJECT_DECLARE_SIMPLE_TYPE(OtEarlGreyBoardState, RISCV_OT_EARLGREY_BOARD)
+
+#define TYPE_RISCV_OT_EARLGREY_SOC "riscv.ot_earlgrey.soc"
+OBJECT_DECLARE_SIMPLE_TYPE(OtEarlGreySoCState, RISCV_OT_EARLGREY_SOC)
+
+#endif /* HW_RISCV_OT_EARLGREY_H */
diff --git a/meson.build b/meson.build
index 4af32c3e1f..55a85ec895 100644
--- a/meson.build
+++ b/meson.build
@@ -3626,6 +3626,7 @@ if have_system
     'hw/nubus',
     'hw/nvme',
     'hw/nvram',
+    'hw/opentitan',
     'hw/pci',
     'hw/pci-host',
     'hw/ppc',
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 3a6394fd11..418b56d69e 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -43,6 +43,8 @@
 #define TYPE_RISCV_CPU_RVA23U64         RISCV_CPU_TYPE_NAME("rva23u64")
 #define TYPE_RISCV_CPU_RVA23S64         RISCV_CPU_TYPE_NAME("rva23s64")
 #define TYPE_RISCV_CPU_LOWRISC_IBEX     RISCV_CPU_TYPE_NAME("lowrisc-ibex")
+#define TYPE_RISCV_CPU_LOWRISC_OPENTITAN \
+    RISCV_CPU_TYPE_NAME("lowrisc-opentitan")
 #define TYPE_RISCV_CPU_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E         RISCV_CPU_TYPE_NAME("sifive-e")
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index dd30b21dd2..507061e8e9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3043,13 +3043,25 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .misa_mxl_max = MXL_RV32,
     ),
 
-    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_LOWRISC_IBEX, TYPE_RISCV_VENDOR_CPU,
+
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_CPU_LOWRISC_IBEX,
+        TYPE_RISCV_VENDOR_CPU,
         .misa_mxl_max = MXL_RV32,
         .misa_ext = RVI | RVM | RVC | RVU,
         .priv_spec = PRIV_VERSION_1_12_0,
         .cfg.max_satp_mode = VM_1_10_MBARE,
         .cfg.ext_zifencei = true,
         .cfg.ext_zicsr = true,
+
+        .cfg.marchid = 0x16u,
+
+#ifndef CONFIG_USER_ONLY
+        .custom_csrs = ibex_csr_list,
+#endif
+    ),
+
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_LOWRISC_OPENTITAN,
+        TYPE_RISCV_CPU_LOWRISC_IBEX,
         .cfg.pmp = true,
         .cfg.ext_smepmp = true,
 
-- 
2.49.1



Reply via email to