From acdc7143096aa556256574c5e343f58db5ac5cf8 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 16 Feb 2024 15:14:20 +0100 Subject: [PATCH 01/58] [ot] scripts/opentitan: pyot.py: fix a bug with undefined start delay When start delay was not defined, the default value was overridden Signed-off-by: Emmanuel Blot --- scripts/opentitan/pyot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/opentitan/pyot.py b/scripts/opentitan/pyot.py index 43b0a95fb374..a12ce1af7ead 100755 --- a/scripts/opentitan/pyot.py +++ b/scripts/opentitan/pyot.py @@ -211,7 +211,7 @@ def run(self, qemu_args: List[str], timeout: int, name: str, try: # ensure that QEMU starts and give some time for it to set up # its VCP before attempting to connect to it - self._log.debug(f'Waiting {start_delay:.1f}s for VM init') + self._log.debug('Waiting %.1fs for VM init', start_delay) proc.wait(start_delay) except TimeoutExpired: pass @@ -1188,7 +1188,7 @@ def _build_qemu_command(self, args: Namespace, qemu_args.extend(('-icount', f'{args.icount}')) mux = f'mux={"on" if args.muxserial else "off"}' try: - start_delay = float(getattr(args, 'start_delay', 1.0)) + start_delay = float(getattr(args, 'start_delay') or 1.0) except ValueError as exc: raise ValueError(f'Invalid start up delay {args.start_delay}') \ from exc From 6611171b4d48da8ce65e33ea497b07611a767535 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 22 Feb 2024 15:54:41 +0100 Subject: [PATCH 02/58] [ot] scripts/opentitan: gdbreplay: fix parsing with rust demangled symbols. Also add an option to filter CPUs by index. Signed-off-by: Emmanuel Blot --- scripts/opentitan/gdbreplay.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/scripts/opentitan/gdbreplay.py b/scripts/opentitan/gdbreplay.py index a2e680c453db..3710a3dbc0bc 100755 --- a/scripts/opentitan/gdbreplay.py +++ b/scripts/opentitan/gdbreplay.py @@ -463,7 +463,7 @@ class QEMUGDBReplay: # Trace 0: 0x280003d00 [00000000/00008c9a/00101003/ff020000] _boot_start TCRE = re_compile(r'^Trace\s(\d+):\s0x[0-9a-f]+\s\[[0-9a-f]+/([0-9a-f]+)' - r'/[0-9a-f]+/[0-9a-f]+\]\s(\w+)\s*$') + r'/[0-9a-f]+/[0-9a-f]+\](?:\s([&,<>\s\w:]+))?\s*$') """Regex to parse QEMU execution trace from a QEMU log file.""" SIGNALS = { @@ -495,21 +495,26 @@ def xlen(self) -> int: """ return self._xlen or 4 - def load(self, qfp: TextIO) -> None: + def load(self, qfp: TextIO, cpus: Optional[List[int]] = None) -> None: """Load a recorded execution stream from a QEMU log file. see QEMU `-d exec` option. :param qfp: text stream to parse """ + threshold = 10 for lno, line in enumerate(qfp, start=1): tmo = self.TCRE.match(line) if not tmo: continue scpu, spc, func = tmo.groups() + if lno > threshold: + threshold *= 10 + if not lno % threshold: + self._log.debug('Parsed %d lines', lno) xcpu = int(scpu) + if cpus and xcpu not in cpus: + continue xpc = int(spc, 16) - if not lno % 10000: - self._log.debug('Parsed %d lines', lno) if xcpu not in self._vcpus: self._vcpus[xcpu] = QEMUVCPU(self._memctrl) self._vcpus[xcpu].record(xpc, func) @@ -832,6 +837,8 @@ def main(): argparser.add_argument('-e', '--elf', action='append', type=FileType('rb'), help='ELF application') + argparser.add_argument('-c', '--cpu', action='append', type=int, + help='Only consider selected CPUs') argparser.add_argument('-a', '--address', action='append', type=lambda x: int(x, 16 if x[1:2].lower() == 'x' else 10), @@ -874,7 +881,7 @@ def main(): for addr, blob in zip(args.address, args.bin): gdbr.load_bin(addr, blob) if args.trace: - gdbr.load(args.trace) + gdbr.load(args.trace, args.cpu) gdbr.serve(args.gdb) From ee8b445122c84a018e2981bbc698c400d536717f Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 8 Feb 2024 18:22:21 +0100 Subject: [PATCH 03/58] [ot] hw/riscv: rename Darjeeling and EarlGrey symbols Signed-off-by: Emmanuel Blot --- hw/riscv/ot_darjeeling.c | 901 +++++++++++++++---------------- hw/riscv/ot_earlgrey.c | 741 +++++++++++++------------ include/hw/riscv/ot_darjeeling.h | 14 +- include/hw/riscv/ot_earlgrey.h | 13 +- 4 files changed, 824 insertions(+), 845 deletions(-) diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index a8c67f2157cf..9636737027a6 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -78,12 +78,12 @@ /* Forward Declarations */ /* ------------------------------------------------------------------------ */ -static void ot_darjeeling_soc_hart_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); -static void ot_darjeeling_soc_otp_ctrl_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); -static void ot_darjeeling_soc_uart_configure( +static void ot_dj_soc_hart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent); +static void ot_dj_soc_otp_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); +static void ot_dj_soc_uart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent); /* ------------------------------------------------------------------------ */ /* Constants */ @@ -91,77 +91,77 @@ static void ot_darjeeling_soc_uart_configure( /* CTN address space */ -#define OT_DARJEELING_CTN_REGION_OFFSET 0x40000000u -#define OT_DARJEELING_CTN_REGION_SIZE (1u << 30u) +#define OT_DJ_CTN_REGION_OFFSET 0x40000000u +#define OT_DJ_CTN_REGION_SIZE (1u << 30u) /* CTN RAM (1MB) */ -#define OT_DARJEELING_CTN_RAM_ADDR 0x01000000u -#define OT_DARJEELING_CTN_RAM_SIZE (2u << 20u) - -enum OtDarjeelingSocDevice { - OT_DARJEELING_SOC_DEV_AES, - OT_DARJEELING_SOC_DEV_ALERT_HANDLER, - OT_DARJEELING_SOC_DEV_AON_TIMER, - OT_DARJEELING_SOC_DEV_AST, - OT_DARJEELING_SOC_DEV_CLKMGR, - OT_DARJEELING_SOC_DEV_CSRNG, - OT_DARJEELING_SOC_DEV_DM_TL_MBOX, - OT_DARJEELING_SOC_DEV_DMA, - OT_DARJEELING_SOC_DEV_DMI, - OT_DARJEELING_SOC_DEV_EDN0, - OT_DARJEELING_SOC_DEV_EDN1, - OT_DARJEELING_SOC_DEV_GPIO, - OT_DARJEELING_SOC_DEV_HART, - OT_DARJEELING_SOC_DEV_HMAC, - OT_DARJEELING_SOC_DEV_I2C0, - OT_DARJEELING_SOC_DEV_IBEX_WRAPPER, - OT_DARJEELING_SOC_DEV_KEYMGR_DPE, - OT_DARJEELING_SOC_DEV_KMAC, - OT_DARJEELING_SOC_DEV_LC_CTRL, - OT_DARJEELING_SOC_DEV_MBX0, - OT_DARJEELING_SOC_DEV_MBX1, - OT_DARJEELING_SOC_DEV_MBX2, - OT_DARJEELING_SOC_DEV_MBX3, - OT_DARJEELING_SOC_DEV_MBX4, - OT_DARJEELING_SOC_DEV_MBX5, - OT_DARJEELING_SOC_DEV_MBX6, - OT_DARJEELING_SOC_DEV_MBX_JTAG, - OT_DARJEELING_SOC_DEV_MBX_PCIE0, - OT_DARJEELING_SOC_DEV_MBX_PCIE1, - OT_DARJEELING_SOC_DEV_OTBN, - OT_DARJEELING_SOC_DEV_OTP_CTRL, - OT_DARJEELING_SOC_DEV_PINMUX, - OT_DARJEELING_SOC_DEV_PLIC, - OT_DARJEELING_SOC_DEV_PWRMGR, - OT_DARJEELING_SOC_DEV_ROM0, - OT_DARJEELING_SOC_DEV_ROM1, - OT_DARJEELING_SOC_DEV_RSTMGR, - OT_DARJEELING_SOC_DEV_RV_DM, - OT_DARJEELING_SOC_DEV_RV_DM_MEM, - OT_DARJEELING_SOC_DEV_SENSOR_CTRL, - OT_DARJEELING_SOC_DEV_SOC_PROXY, - OT_DARJEELING_SOC_DEV_SPI_DEVICE, - OT_DARJEELING_SOC_DEV_SPI_HOST0, - OT_DARJEELING_SOC_DEV_SRAM_MAIN, - OT_DARJEELING_SOC_DEV_SRAM_MBX, - OT_DARJEELING_SOC_DEV_SRAM_RET, - OT_DARJEELING_SOC_DEV_TIMER, - OT_DARJEELING_SOC_DEV_UART0, +#define OT_DJ_CTN_RAM_ADDR 0x01000000u +#define OT_DJ_CTN_RAM_SIZE (2u << 20u) + +enum OtDjSocDevice { + OT_DJ_SOC_DEV_AES, + OT_DJ_SOC_DEV_ALERT_HANDLER, + OT_DJ_SOC_DEV_AON_TIMER, + OT_DJ_SOC_DEV_AST, + OT_DJ_SOC_DEV_CLKMGR, + OT_DJ_SOC_DEV_CSRNG, + OT_DJ_SOC_DEV_DM_TL_MBOX, + OT_DJ_SOC_DEV_DMA, + OT_DJ_SOC_DEV_DMI, + OT_DJ_SOC_DEV_EDN0, + OT_DJ_SOC_DEV_EDN1, + OT_DJ_SOC_DEV_GPIO, + OT_DJ_SOC_DEV_HART, + OT_DJ_SOC_DEV_HMAC, + OT_DJ_SOC_DEV_I2C0, + OT_DJ_SOC_DEV_IBEX_WRAPPER, + OT_DJ_SOC_DEV_KEYMGR_DPE, + OT_DJ_SOC_DEV_KMAC, + OT_DJ_SOC_DEV_LC_CTRL, + OT_DJ_SOC_DEV_MBX0, + OT_DJ_SOC_DEV_MBX1, + OT_DJ_SOC_DEV_MBX2, + OT_DJ_SOC_DEV_MBX3, + OT_DJ_SOC_DEV_MBX4, + OT_DJ_SOC_DEV_MBX5, + OT_DJ_SOC_DEV_MBX6, + OT_DJ_SOC_DEV_MBX_JTAG, + OT_DJ_SOC_DEV_MBX_PCIE0, + OT_DJ_SOC_DEV_MBX_PCIE1, + OT_DJ_SOC_DEV_OTBN, + OT_DJ_SOC_DEV_OTP_CTRL, + OT_DJ_SOC_DEV_PINMUX, + OT_DJ_SOC_DEV_PLIC, + OT_DJ_SOC_DEV_PWRMGR, + OT_DJ_SOC_DEV_ROM0, + OT_DJ_SOC_DEV_ROM1, + OT_DJ_SOC_DEV_RSTMGR, + OT_DJ_SOC_DEV_RV_DM, + OT_DJ_SOC_DEV_RV_DM_MEM, + OT_DJ_SOC_DEV_SENSOR_CTRL, + OT_DJ_SOC_DEV_SOC_PROXY, + OT_DJ_SOC_DEV_SPI_DEVICE, + OT_DJ_SOC_DEV_SPI_HOST0, + OT_DJ_SOC_DEV_SRAM_MAIN, + OT_DJ_SOC_DEV_SRAM_MBX, + OT_DJ_SOC_DEV_SRAM_RET, + OT_DJ_SOC_DEV_TIMER, + OT_DJ_SOC_DEV_UART0, /* IRQ splitters, i.e. 1-to-N signal dispatchers */ - OT_DARJEELING_SOC_SPLITTER_LC_HW_DEBUG, - OT_DARJEELING_SOC_SPLITTER_LC_ESCALATE, + OT_DJ_SOC_SPLITTER_LC_HW_DEBUG, + OT_DJ_SOC_SPLITTER_LC_ESCALATE, }; /* Darjeeling Peripheral clock is 62.5 MHz */ -#define OT_DARJEELING_PERIPHERAL_CLK_HZ 62500000u +#define OT_DJ_PERIPHERAL_CLK_HZ 62500000u /* Darjeeling SPI host clock is 250 MHz */ -#define OT_DARJEELING__SPIHOST_CLK_HZ 250000000u +#define OT_DJ_SPIHOST_CLK_HZ 250000000u /* Darjeeling AON clock is 62.5 MHz */ -#define OT_DARJEELING_AON_CLK_HZ 62500000u +#define OT_DJ_AON_CLK_HZ 62500000u -static const uint8_t ot_darjeeling_pmp_cfgs[] = { +static const uint8_t ot_dj_pmp_cfgs[] = { /* clang-format off */ IBEX_PMP_CFG(0, IBEX_PMP_MODE_OFF, 0, 0, 0), IBEX_PMP_CFG(0, IBEX_PMP_MODE_OFF, 0, 0, 0), @@ -182,7 +182,7 @@ static const uint8_t ot_darjeeling_pmp_cfgs[] = { /* clang-format on */ }; -static const uint32_t ot_darjeeling_pmp_addrs[] = { +static const uint32_t ot_dj_pmp_addrs[] = { /* clang-format off */ IBEX_PMP_ADDR(0x00000000), IBEX_PMP_ADDR(0x00000000), @@ -203,25 +203,25 @@ static const uint32_t ot_darjeeling_pmp_addrs[] = { /* clang-format on */ }; -#define OT_DARJEELING_MSECCFG IBEX_MSECCFG(1, 1, 0) +#define OT_DJ_MSECCFG IBEX_MSECCFG(1, 1, 0) -enum OtDarjeelingMemoryRegion { - OT_DARJEELING_DEFAULT_MEMORY_REGION, - OT_DARJEELING_CTN_MEMORY_REGION, - OT_DARJEELING_DEBUG_MEMORY_REGION, +enum OtDjMemoryRegion { + OT_DJ_DEFAULT_MEMORY_REGION, + OT_DJ_CTN_MEMORY_REGION, + OT_DJ_DEBUG_MEMORY_REGION, }; -#define OT_DARJEELING_SOC_GPIO(_irq_, _target_, _num_) \ - IBEX_GPIO(_irq_, OT_DARJEELING_SOC_DEV_##_target_, _num_) +#define OT_DJ_SOC_GPIO(_irq_, _target_, _num_) \ + IBEX_GPIO(_irq_, OT_DJ_SOC_DEV_##_target_, _num_) -#define OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(_irq_, _target_, _num_) \ - IBEX_GPIO_SYSBUS_IRQ(_irq_, OT_DARJEELING_SOC_DEV_##_target_, _num_) +#define OT_DJ_SOC_GPIO_SYSBUS_IRQ(_irq_, _target_, _num_) \ + IBEX_GPIO_SYSBUS_IRQ(_irq_, OT_DJ_SOC_DEV_##_target_, _num_) -#define OT_DARJEELING_SOC_DEVLINK(_pname_, _target_) \ - IBEX_DEVLINK(_pname_, OT_DARJEELING_SOC_DEV_##_target_) +#define OT_DJ_SOC_DEVLINK(_pname_, _target_) \ + IBEX_DEVLINK(_pname_, OT_DJ_SOC_DEV_##_target_) /* Device named signal to device named signal */ -#define OT_DARJEELING_SOC_SIGNAL(_sname_, _snum_, _tgt_, _tname_, _tnum_) \ +#define OT_DJ_SOC_SIGNAL(_sname_, _snum_, _tgt_, _tname_, _tnum_) \ { \ .out = { \ .name = (_sname_), \ @@ -229,77 +229,73 @@ enum OtDarjeelingMemoryRegion { }, \ .in = { \ .name = (_tname_), \ - .index = (OT_DARJEELING_SOC_DEV_ ## _tgt_), \ + .index = (OT_DJ_SOC_DEV_ ## _tgt_), \ .num = (_tnum_), \ } \ } /* Device named signal to splitter input */ -#define OT_DARJEELING_SOC_D2S(_sname_, _snum_, _tgt_) \ +#define OT_DJ_SOC_D2S(_sname_, _snum_, _tgt_) \ { \ .out = { \ .name = (_sname_), \ .num = (_snum_), \ }, \ .in = { \ - .index = (OT_DARJEELING_SOC_SPLITTER_ ## _tgt_), \ + .index = (OT_DJ_SOC_SPLITTER_ ## _tgt_), \ } \ } /* Splitter output to device named signal */ -#define OT_DARJEELING_SOC_S2D(_snum_, _tgt_, _tname_, _tnum_) \ +#define OT_DJ_SOC_S2D(_snum_, _tgt_, _tname_, _tnum_) \ { \ .out = { \ .num = (_snum_), \ }, \ .in = { \ .name = (_tname_), \ - .index = (OT_DARJEELING_SOC_DEV_ ## _tgt_), \ + .index = (OT_DJ_SOC_DEV_ ## _tgt_), \ .num = (_tnum_), \ } \ } /* Request link */ -#define OT_DARJEELING_SOC_REQ(_req_, _tgt_) \ - OT_DARJEELING_SOC_SIGNAL(_req_##_REQ, 0, _tgt_, _req_##_REQ, 0) +#define OT_DJ_SOC_REQ(_req_, _tgt_) \ + OT_DJ_SOC_SIGNAL(_req_##_REQ, 0, _tgt_, _req_##_REQ, 0) /* Response link */ -#define OT_DARJEELING_SOC_RSP(_rsp_, _tgt_) \ - OT_DARJEELING_SOC_SIGNAL(_rsp_##_RSP, 0, _tgt_, _rsp_##_RSP, 0) +#define OT_DJ_SOC_RSP(_rsp_, _tgt_) \ + OT_DJ_SOC_SIGNAL(_rsp_##_RSP, 0, _tgt_, _rsp_##_RSP, 0) -#define OT_DARJEELING_SOC_DEV_MBX(_ix_, _addr_, _irq_) \ +#define OT_DJ_SOC_DEV_MBX(_ix_, _addr_, _irq_) \ .type = TYPE_OT_MBX, .instance = (_ix_), \ .memmap = MEMMAPENTRIES({ (_addr_), OT_MBX_HOST_APERTURE }), \ .gpio = \ - IBEXGPIOCONNDEFS(OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, (_irq_)), \ - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, \ - (_irq_) + 1u), \ - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, \ - (_irq_) + 2u)), \ + IBEXGPIOCONNDEFS(OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, (_irq_)), \ + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, (_irq_) + 1u), \ + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, (_irq_) + 2u)), \ .prop = IBEXDEVICEPROPDEFS(IBEX_DEV_STRING_PROP("ot_id", stringify(_ix_))) -#define OT_DARJEELING_SOC_DEV_MBX_DUAL(_ix_, _addr_, _irq_, _xaddr_) \ +#define OT_DJ_SOC_DEV_MBX_DUAL(_ix_, _addr_, _irq_, _xaddr_) \ .type = TYPE_OT_MBX, .instance = (_ix_), \ .memmap = MEMMAPENTRIES({ (_addr_), OT_MBX_HOST_APERTURE }, \ { (_xaddr_), OT_MBX_SYS_APERTURE }), \ .gpio = \ - IBEXGPIOCONNDEFS(OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, (_irq_)), \ - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, \ - (_irq_) + 1u), \ - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, \ - (_irq_) + 2u)), \ + IBEXGPIOCONNDEFS(OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, (_irq_)), \ + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, (_irq_) + 1u), \ + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, (_irq_) + 2u)), \ .prop = IBEXDEVICEPROPDEFS(IBEX_DEV_STRING_PROP("ot_id", stringify(_ix_))) -#define OT_DARJEELING_SOC_CLKMGR_HINT(_num_) \ - OT_DARJEELING_SOC_SIGNAL(OT_CLOCK_ACTIVE, 0, CLKMGR, OT_CLKMGR_HINT, _num_) +#define OT_DJ_SOC_CLKMGR_HINT(_num_) \ + OT_DJ_SOC_SIGNAL(OT_CLOCK_ACTIVE, 0, CLKMGR, OT_CLKMGR_HINT, _num_) -#define OT_DARJEELING_XPORT_MEMORY(_addr_) \ - IBEX_MEMMAP_MAKE_REG((_addr_), OT_DARJEELING_CTN_MEMORY_REGION) +#define OT_DJ_XPORT_MEMORY(_addr_) \ + IBEX_MEMMAP_MAKE_REG((_addr_), OT_DJ_CTN_MEMORY_REGION) -#define OT_DARJEELING_DBG_XBAR_APERTURE 0x2000u +#define OT_DJ_DBG_XBAR_APERTURE 0x2000u #define DEBUG_MEMORY(_addr_) \ - IBEX_MEMMAP_MAKE_REG((_addr_), OT_DARJEELING_DEBUG_MEMORY_REGION) + IBEX_MEMMAP_MAKE_REG((_addr_), OT_DJ_DEBUG_MEMORY_REGION) /* * Darjeeling RV DM @@ -313,11 +309,11 @@ enum OtDarjeelingMemoryRegion { * and * lowRISC/opentitan: hw/top_darjeeling/sw/autogen/top_darjeeling.h */ -static const IbexDeviceDef ot_darjeeling_soc_devices[] = { +static const IbexDeviceDef ot_dj_soc_devices[] = { /* clang-format off */ - [OT_DARJEELING_SOC_DEV_HART] = { + [OT_DJ_SOC_DEV_HART] = { .type = TYPE_RISCV_CPU_LOWRISC_IBEX, - .cfg = &ot_darjeeling_soc_hart_configure, + .cfg = &ot_dj_soc_hart_configure, .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_BOOL_PROP("m", true), IBEX_DEV_BOOL_PROP("pmp", true), @@ -332,18 +328,18 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { IBEX_DEV_BOOL_PROP("start-powered-off", true) ), }, - [OT_DARJEELING_SOC_DEV_DMI] = { + [OT_DJ_SOC_DEV_DMI] = { .type = TYPE_RISCV_DMI, .prop = IBEXDEVICEPROPDEFS( /* should be a constant, need to encode 0x500 */ IBEX_DEV_UINT_PROP("abits", 11u) ), }, - [OT_DARJEELING_SOC_DEV_DM_TL_MBOX] = { + [OT_DJ_SOC_DEV_DM_TL_MBOX] = { .type = TYPE_OT_DM_TL, .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("dmi", DMI), - OT_DARJEELING_SOC_DEVLINK("tl_dev", MBX_JTAG) + OT_DJ_SOC_DEVLINK("dmi", DMI), + OT_DJ_SOC_DEVLINK("tl_dev", MBX_JTAG) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("dmi_addr", 0x400u), @@ -352,70 +348,70 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { IBEX_DEV_STRING_PROP("tl_as_name", "ot-dbg") ) }, - [OT_DARJEELING_SOC_DEV_AES] = { + [OT_DJ_SOC_DEV_AES] = { .type = TYPE_OT_AES, .memmap = MEMMAPENTRIES( { 0x21100000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_AES) + OT_DJ_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_AES) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("edn", EDN0) + OT_DJ_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 5u) ), }, - [OT_DARJEELING_SOC_DEV_HMAC] = { + [OT_DJ_SOC_DEV_HMAC] = { .type = TYPE_OT_HMAC, .memmap = MEMMAPENTRIES( { 0x21110000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 115), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 116), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 117), - OT_DARJEELING_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_HMAC) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 115), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 116), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 117), + OT_DJ_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_HMAC) ), }, - [OT_DARJEELING_SOC_DEV_KMAC] = { + [OT_DJ_SOC_DEV_KMAC] = { .type = TYPE_OT_KMAC, .memmap = MEMMAPENTRIES( { 0x21120000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 118), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 119), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 120) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 118), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 119), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 120) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("edn", EDN0) + OT_DJ_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 3u), IBEX_DEV_UINT_PROP("num-app", 4u) ), }, - [OT_DARJEELING_SOC_DEV_OTBN] = { + [OT_DJ_SOC_DEV_OTBN] = { .type = TYPE_OT_OTBN, .memmap = MEMMAPENTRIES( { 0x21130000u, 0x10000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 121), - OT_DARJEELING_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_OTBN) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 121), + OT_DJ_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_OTBN) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("edn-u", EDN0), - OT_DARJEELING_SOC_DEVLINK("edn-r", EDN1) + OT_DJ_SOC_DEVLINK("edn-u", EDN0), + OT_DJ_SOC_DEVLINK("edn-r", EDN1) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-u-ep", 6u), IBEX_DEV_UINT_PROP("edn-r-ep", 0u) ), }, - [OT_DARJEELING_SOC_DEV_KEYMGR_DPE] = { + [OT_DJ_SOC_DEV_KEYMGR_DPE] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-keymgr_dpe", .cfg = &ibex_unimp_configure, @@ -423,57 +419,57 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x21140000u, 0x100u } ), }, - [OT_DARJEELING_SOC_DEV_CSRNG] = { + [OT_DJ_SOC_DEV_CSRNG] = { .type = TYPE_OT_CSRNG, .memmap = MEMMAPENTRIES( { 0x21150000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 123), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 124), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 125), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 126) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 123), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 124), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 125), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 126) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("random_src", AST), - OT_DARJEELING_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_DJ_SOC_DEVLINK("random_src", AST), + OT_DJ_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), }, - [OT_DARJEELING_SOC_DEV_EDN0] = { + [OT_DJ_SOC_DEV_EDN0] = { .type = TYPE_OT_EDN, .instance = 0, .memmap = MEMMAPENTRIES( { 0x21170000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 127), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 128) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 127), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 128) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("csrng", CSRNG) + OT_DJ_SOC_DEVLINK("csrng", CSRNG) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("csrng-app", 0) ), }, - [OT_DARJEELING_SOC_DEV_EDN1] = { + [OT_DJ_SOC_DEV_EDN1] = { .type = TYPE_OT_EDN, .instance = 1, .memmap = MEMMAPENTRIES( { 0x21180000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 129), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 130) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 129), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 130) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("csrng", CSRNG) + OT_DJ_SOC_DEVLINK("csrng", CSRNG) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("csrng-app", 1u) ), }, - [OT_DARJEELING_SOC_DEV_SRAM_MAIN] = { + [OT_DJ_SOC_DEV_SRAM_MAIN] = { .type = TYPE_OT_SRAM_CTRL, .instance = 0, .memmap = MEMMAPENTRIES( @@ -481,14 +477,14 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x10000000, 0x10000u } ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_DJ_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("size", 0x10000u), IBEX_DEV_STRING_PROP("ot_id", "ram") ), }, - [OT_DARJEELING_SOC_DEV_SRAM_MBX] = { + [OT_DJ_SOC_DEV_SRAM_MBX] = { .type = TYPE_OT_SRAM_CTRL, .instance = 1, .memmap = MEMMAPENTRIES( @@ -496,14 +492,14 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x11000000u, 0x1000u } ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_DJ_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("size", 0x1000u), IBEX_DEV_STRING_PROP("ot_id", "mbx") ), }, - [OT_DARJEELING_SOC_DEV_ROM0] = { + [OT_DJ_SOC_DEV_ROM0] = { .type = TYPE_OT_ROM_CTRL, .instance = 0, .memmap = MEMMAPENTRIES( @@ -511,13 +507,13 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x00008000u, 0x8000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_SIGNAL(OT_ROM_CTRL_GOOD, 0, PWRMGR, + OT_DJ_SOC_SIGNAL(OT_ROM_CTRL_GOOD, 0, PWRMGR, OT_PWRMGR_ROM_GOOD, 0), - OT_DARJEELING_SOC_SIGNAL(OT_ROM_CTRL_DONE, 0, PWRMGR, + OT_DJ_SOC_SIGNAL(OT_ROM_CTRL_DONE, 0, PWRMGR, OT_PWRMGR_ROM_DONE, 0) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("kmac", KMAC) + OT_DJ_SOC_DEVLINK("kmac", KMAC) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("ot_id", "rom0"), @@ -525,7 +521,7 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { IBEX_DEV_UINT_PROP("kmac-app", 2u) ), }, - [OT_DARJEELING_SOC_DEV_ROM1] = { + [OT_DJ_SOC_DEV_ROM1] = { .type = TYPE_OT_ROM_CTRL, .instance = 1, .memmap = MEMMAPENTRIES( @@ -533,13 +529,13 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x00020000u, 0x10000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_SIGNAL(OT_ROM_CTRL_GOOD, 0, PWRMGR, + OT_DJ_SOC_SIGNAL(OT_ROM_CTRL_GOOD, 0, PWRMGR, OT_PWRMGR_ROM_GOOD, 1), - OT_DARJEELING_SOC_SIGNAL(OT_ROM_CTRL_DONE, 0, PWRMGR, + OT_DJ_SOC_SIGNAL(OT_ROM_CTRL_DONE, 0, PWRMGR, OT_PWRMGR_ROM_DONE, 1) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("kmac", KMAC) + OT_DJ_SOC_DEVLINK("kmac", KMAC) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("ot_id", "rom1"), @@ -547,19 +543,19 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { IBEX_DEV_UINT_PROP("kmac-app", 3u) ), }, - [OT_DARJEELING_SOC_DEV_IBEX_WRAPPER] = { + [OT_DJ_SOC_DEV_IBEX_WRAPPER] = { .type = TYPE_OT_IBEX_WRAPPER_DJ, .memmap = MEMMAPENTRIES( { 0x211f0000u, 0x800u } ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("edn", EDN0) + OT_DJ_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 7u) ), }, - [OT_DARJEELING_SOC_DEV_RV_DM] = { + [OT_DJ_SOC_DEV_RV_DM] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-rv_dm", .cfg = &ibex_unimp_configure, @@ -567,40 +563,40 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x21200000u, 0x1000u } ), }, - [OT_DARJEELING_SOC_DEV_MBX0] = { - OT_DARJEELING_SOC_DEV_MBX(0, 0x22000000u, 134), + [OT_DJ_SOC_DEV_MBX0] = { + OT_DJ_SOC_DEV_MBX(0, 0x22000000u, 134), }, - [OT_DARJEELING_SOC_DEV_MBX1] = { - OT_DARJEELING_SOC_DEV_MBX(1, 0x22000100u, 137), + [OT_DJ_SOC_DEV_MBX1] = { + OT_DJ_SOC_DEV_MBX(1, 0x22000100u, 137), }, - [OT_DARJEELING_SOC_DEV_MBX2] = { - OT_DARJEELING_SOC_DEV_MBX(2, 0x22000200u, 140), + [OT_DJ_SOC_DEV_MBX2] = { + OT_DJ_SOC_DEV_MBX(2, 0x22000200u, 140), }, - [OT_DARJEELING_SOC_DEV_MBX3] = { - OT_DARJEELING_SOC_DEV_MBX(3, 0x22000300u, 143), + [OT_DJ_SOC_DEV_MBX3] = { + OT_DJ_SOC_DEV_MBX(3, 0x22000300u, 143), }, - [OT_DARJEELING_SOC_DEV_MBX4] = { - OT_DARJEELING_SOC_DEV_MBX(4, 0x22000400u, 146), + [OT_DJ_SOC_DEV_MBX4] = { + OT_DJ_SOC_DEV_MBX(4, 0x22000400u, 146), }, - [OT_DARJEELING_SOC_DEV_MBX5] = { - OT_DARJEELING_SOC_DEV_MBX(5, 0x22000500u, 149), + [OT_DJ_SOC_DEV_MBX5] = { + OT_DJ_SOC_DEV_MBX(5, 0x22000500u, 149), }, - [OT_DARJEELING_SOC_DEV_MBX6] = { - OT_DARJEELING_SOC_DEV_MBX(6, 0x22000600u, 152), + [OT_DJ_SOC_DEV_MBX6] = { + OT_DJ_SOC_DEV_MBX(6, 0x22000600u, 152), }, - [OT_DARJEELING_SOC_DEV_MBX_JTAG] = { - OT_DARJEELING_SOC_DEV_MBX_DUAL(7, 0x22000800u, 155, + [OT_DJ_SOC_DEV_MBX_JTAG] = { + OT_DJ_SOC_DEV_MBX_DUAL(7, 0x22000800u, 155, DEBUG_MEMORY(0x1000)), }, - [OT_DARJEELING_SOC_DEV_DMA] = { + [OT_DJ_SOC_DEV_DMA] = { .type = TYPE_OT_DMA, .memmap = MEMMAPENTRIES( { 0x22010000u, 0x200u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 131), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 132), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 133) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 131), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 132), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 133) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("ot_id", "0"), @@ -609,62 +605,62 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { ) }, - [OT_DARJEELING_SOC_DEV_SOC_PROXY] = { + [OT_DJ_SOC_DEV_SOC_PROXY] = { .type = TYPE_OT_SOC_PROXY, .memmap = MEMMAPENTRIES( { 0x22030000u, 0x10u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 83), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 84), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 85), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 86), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 87), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 88), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 89), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 90), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 91), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 92), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 93), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 94), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(12, PLIC, 95), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(13, PLIC, 96), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(14, PLIC, 97), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(15, PLIC, 98), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(16, PLIC, 99), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(17, PLIC, 100), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(18, PLIC, 101), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(19, PLIC, 102), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(20, PLIC, 103), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(21, PLIC, 104), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(22, PLIC, 105), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(23, PLIC, 106), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(24, PLIC, 107), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(25, PLIC, 108), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(26, PLIC, 109), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(27, PLIC, 110), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(28, PLIC, 111), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(29, PLIC, 112), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(30, PLIC, 113), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(31, PLIC, 114) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 83), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 84), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 85), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 86), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 87), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 88), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 89), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 90), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 91), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 92), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 93), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 94), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(12, PLIC, 95), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(13, PLIC, 96), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(14, PLIC, 97), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(15, PLIC, 98), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(16, PLIC, 99), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(17, PLIC, 100), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(18, PLIC, 101), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(19, PLIC, 102), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(20, PLIC, 103), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(21, PLIC, 104), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(22, PLIC, 105), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(23, PLIC, 106), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(24, PLIC, 107), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(25, PLIC, 108), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(26, PLIC, 109), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(27, PLIC, 110), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(28, PLIC, 111), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(29, PLIC, 112), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(30, PLIC, 113), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(31, PLIC, 114) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("ot_id", "0") ), }, - [OT_DARJEELING_SOC_DEV_MBX_PCIE0] = { - OT_DARJEELING_SOC_DEV_MBX(8, 0x22040000u, 158), + [OT_DJ_SOC_DEV_MBX_PCIE0] = { + OT_DJ_SOC_DEV_MBX(8, 0x22040000u, 158), }, - [OT_DARJEELING_SOC_DEV_MBX_PCIE1] = { - OT_DARJEELING_SOC_DEV_MBX(9, 0x22040100u, 161), + [OT_DJ_SOC_DEV_MBX_PCIE1] = { + OT_DJ_SOC_DEV_MBX(9, 0x22040100u, 161), }, - [OT_DARJEELING_SOC_DEV_PLIC] = { + [OT_DJ_SOC_DEV_PLIC] = { .type = TYPE_SIFIVE_PLIC, .memmap = MEMMAPENTRIES( { 0x28000000u, 0x8000000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO(1, HART, IRQ_M_EXT) + OT_DJ_SOC_GPIO(1, HART, IRQ_M_EXT) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("hart-config", "M"), @@ -681,79 +677,79 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { IBEX_DEV_UINT_PROP("aperture-size", 0x8000000u) ), }, - [OT_DARJEELING_SOC_DEV_GPIO] = { + [OT_DJ_SOC_DEV_GPIO] = { .type = TYPE_OT_GPIO, .name = "ot-gpio", .memmap = MEMMAPENTRIES( { 0x30000000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 9), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 10), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 11), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 12), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 13), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 14), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 15), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 16), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 17), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 18), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 19), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 20), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(12, PLIC, 21), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(13, PLIC, 22), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(14, PLIC, 23), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(15, PLIC, 24), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(16, PLIC, 25), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(17, PLIC, 26), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(18, PLIC, 27), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(19, PLIC, 28), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(20, PLIC, 29), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(21, PLIC, 30), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(22, PLIC, 31), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(23, PLIC, 32), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(24, PLIC, 33), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(25, PLIC, 34), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(26, PLIC, 35), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(27, PLIC, 36), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(28, PLIC, 37), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(29, PLIC, 38), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(30, PLIC, 39), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(31, PLIC, 40) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 9), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 10), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 11), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 12), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 13), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 14), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 15), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 16), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 17), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 18), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 19), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 20), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(12, PLIC, 21), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(13, PLIC, 22), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(14, PLIC, 23), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(15, PLIC, 24), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(16, PLIC, 25), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(17, PLIC, 26), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(18, PLIC, 27), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(19, PLIC, 28), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(20, PLIC, 29), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(21, PLIC, 30), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(22, PLIC, 31), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(23, PLIC, 32), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(24, PLIC, 33), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(25, PLIC, 34), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(26, PLIC, 35), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(27, PLIC, 36), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(28, PLIC, 37), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(29, PLIC, 38), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(30, PLIC, 39), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(31, PLIC, 40) ) }, - [OT_DARJEELING_SOC_DEV_UART0] = { + [OT_DJ_SOC_DEV_UART0] = { .type = TYPE_OT_UART, - .cfg = &ot_darjeeling_soc_uart_configure, + .cfg = &ot_dj_soc_uart_configure, .instance = 0, .memmap = MEMMAPENTRIES( { 0x30010000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 1), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 2), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 3), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 4), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 5), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 6), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 7), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 8) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 1), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 2), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 3), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 4), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 5), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 6), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 7), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 8) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_DARJEELING_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_DJ_PERIPHERAL_CLK_HZ) ), }, - [OT_DARJEELING_SOC_DEV_SENSOR_CTRL] = { + [OT_DJ_SOC_DEV_SENSOR_CTRL] = { .type = TYPE_OT_SENSOR, .memmap = MEMMAPENTRIES( { 0x30020000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 81), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 82) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 81), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 82) ) }, - [OT_DARJEELING_SOC_DEV_I2C0] = { + [OT_DJ_SOC_DEV_I2C0] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-i2c", .cfg = &ibex_unimp_configure, @@ -762,69 +758,69 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x30080000u, 0x80u } ), }, - [OT_DARJEELING_SOC_DEV_TIMER] = { + [OT_DJ_SOC_DEV_TIMER] = { .type = TYPE_OT_TIMER, .memmap = MEMMAPENTRIES( { 0x30100000u, 0x200u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO(0, HART, IRQ_M_TIMER), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 68) + OT_DJ_SOC_GPIO(0, HART, IRQ_M_TIMER), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 68) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_DARJEELING_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_DJ_PERIPHERAL_CLK_HZ) ), }, - [OT_DARJEELING_SOC_DEV_OTP_CTRL] = { + [OT_DJ_SOC_DEV_OTP_CTRL] = { .type = TYPE_OT_OTP_DJ, - .cfg = &ot_darjeeling_soc_otp_ctrl_configure, + .cfg = &ot_dj_soc_otp_ctrl_configure, .memmap = MEMMAPENTRIES( { 0x30130000u, 0x8000u }, { 0x30138000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 69), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 70), - OT_DARJEELING_SOC_RSP(OT_PWRMGR_OTP, PWRMGR) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 69), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 70), + OT_DJ_SOC_RSP(OT_PWRMGR_OTP, PWRMGR) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("edn", EDN0) + OT_DJ_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 1u) ), }, - [OT_DARJEELING_SOC_DEV_LC_CTRL] = { + [OT_DJ_SOC_DEV_LC_CTRL] = { .type = TYPE_OT_LC_CTRL, .memmap = MEMMAPENTRIES( { 0x30140000u, 0x100u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_D2S(OT_LC_BROADCAST, OT_LC_HW_DEBUG_EN, + OT_DJ_SOC_D2S(OT_LC_BROADCAST, OT_LC_HW_DEBUG_EN, LC_HW_DEBUG), - OT_DARJEELING_SOC_D2S(OT_LC_BROADCAST, OT_LC_ESCALATE_EN, + OT_DJ_SOC_D2S(OT_LC_BROADCAST, OT_LC_ESCALATE_EN, LC_ESCALATE), - OT_DARJEELING_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_CPU_EN, + OT_DJ_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_CPU_EN, IBEX_WRAPPER, OT_IBEX_WRAPPER_CPU_EN, OT_IBEX_LC_CTRL_CPU_EN), - OT_DARJEELING_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_CHECK_BYP_EN, + OT_DJ_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_CHECK_BYP_EN, OTP_CTRL, OT_LC_BROADCAST, OT_OTP_LC_CHECK_BYP_EN), - OT_DARJEELING_SOC_SIGNAL(OT_LC_BROADCAST, + OT_DJ_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_CREATOR_SEED_SW_RW_EN, OTP_CTRL, OT_LC_BROADCAST, OT_OTP_LC_CREATOR_SEED_SW_RW_EN), - OT_DARJEELING_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_OWNER_SEED_SW_RW_EN, + OT_DJ_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_OWNER_SEED_SW_RW_EN, OTP_CTRL, OT_LC_BROADCAST, OT_OTP_LC_OWNER_SEED_SW_RW_EN), - OT_DARJEELING_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_SEED_HW_RD_EN, + OT_DJ_SOC_SIGNAL(OT_LC_BROADCAST, OT_LC_SEED_HW_RD_EN, OTP_CTRL, OT_LC_BROADCAST, OT_OTP_LC_SEED_HW_RD_EN), - OT_DARJEELING_SOC_RSP(OT_PWRMGR_LC, PWRMGR) + OT_DJ_SOC_RSP(OT_PWRMGR_LC, PWRMGR) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("otp_ctrl", OTP_CTRL), - OT_DARJEELING_SOC_DEVLINK("kmac", KMAC) + OT_DJ_SOC_DEVLINK("otp_ctrl", OTP_CTRL), + OT_DJ_SOC_DEVLINK("kmac", KMAC) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("silicon_creator_id", 0x4002u), @@ -834,126 +830,126 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { IBEX_DEV_UINT_PROP("kmac-app", 1u) ) }, - [OT_DARJEELING_SOC_DEV_ALERT_HANDLER] = { + [OT_DJ_SOC_DEV_ALERT_HANDLER] = { .type = TYPE_OT_ALERT_DJ, .memmap = MEMMAPENTRIES( { 0x30150000u, 0x800u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 71), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 72), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 73), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 74) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 71), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 72), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 73), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 74) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("edn", EDN0) + OT_DJ_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 4u) ), }, - [OT_DARJEELING_SOC_DEV_SPI_HOST0] = { + [OT_DJ_SOC_DEV_SPI_HOST0] = { .type = TYPE_OT_SPI_HOST, .instance = 0, .memmap = MEMMAPENTRIES( { 0x30300000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 76), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 77) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 76), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 77) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("bus-num", 0) ), }, - [OT_DARJEELING_SOC_DEV_SPI_DEVICE] = { + [OT_DJ_SOC_DEV_SPI_DEVICE] = { .type = TYPE_OT_SPI_DEVICE, .memmap = MEMMAPENTRIES( { 0x30310000u, 0x2000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 41), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 42), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 43), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 44), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 45), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 46), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 47), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 48), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 49), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 50), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 51), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 52) + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 41), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 42), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 43), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 44), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 45), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 46), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 47), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 48), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 49), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 50), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 51), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 52) ), }, - [OT_DARJEELING_SOC_DEV_PWRMGR] = { + [OT_DJ_SOC_DEV_PWRMGR] = { .type = TYPE_OT_PWRMGR, .memmap = MEMMAPENTRIES( { 0x30400000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 78), - OT_DARJEELING_SOC_REQ(OT_PWRMGR_OTP, OTP_CTRL), - OT_DARJEELING_SOC_REQ(OT_PWRMGR_LC, LC_CTRL), - OT_DARJEELING_SOC_SIGNAL(OT_PWRMGR_CPU_EN, 0, IBEX_WRAPPER, + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 78), + OT_DJ_SOC_REQ(OT_PWRMGR_OTP, OTP_CTRL), + OT_DJ_SOC_REQ(OT_PWRMGR_LC, LC_CTRL), + OT_DJ_SOC_SIGNAL(OT_PWRMGR_CPU_EN, 0, IBEX_WRAPPER, OT_IBEX_WRAPPER_CPU_EN, OT_IBEX_PWRMGR_CPU_EN) ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("rstmgr", RSTMGR) + OT_DJ_SOC_DEVLINK("rstmgr", RSTMGR) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("num-rom", 2u) ), }, - [OT_DARJEELING_SOC_DEV_RSTMGR] = { + [OT_DJ_SOC_DEV_RSTMGR] = { .type = TYPE_OT_RSTMGR, .memmap = MEMMAPENTRIES( { 0x30410000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_SIGNAL(OT_RSTMGR_SW_RST, 0, PWRMGR, + OT_DJ_SOC_SIGNAL(OT_RSTMGR_SW_RST, 0, PWRMGR, OT_PWRMGR_SW_RST, 0) ), }, - [OT_DARJEELING_SOC_DEV_CLKMGR] = { + [OT_DJ_SOC_DEV_CLKMGR] = { .type = TYPE_OT_CLKMGR, .memmap = MEMMAPENTRIES( { 0x30420000u, 0x80u } ), }, - [OT_DARJEELING_SOC_DEV_PINMUX] = { + [OT_DJ_SOC_DEV_PINMUX] = { .type = TYPE_OT_PINMUX, .memmap = MEMMAPENTRIES( { 0x30460000u, 0x1000u } ), }, - [OT_DARJEELING_SOC_DEV_AON_TIMER] = { + [OT_DJ_SOC_DEV_AON_TIMER] = { .type = TYPE_OT_AON_TIMER, .memmap = MEMMAPENTRIES( { 0x30470000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 79), - OT_DARJEELING_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 80), - OT_DARJEELING_SOC_SIGNAL(OT_AON_TIMER_WKUP, 0, PWRMGR, + OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 79), + OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 80), + OT_DJ_SOC_SIGNAL(OT_AON_TIMER_WKUP, 0, PWRMGR, OT_PWRMGR_WKUP, OT_PWRMGR_WAKEUP_AON_TIMER), - OT_DARJEELING_SOC_SIGNAL(OT_AON_TIMER_BITE, 0, PWRMGR, + OT_DJ_SOC_SIGNAL(OT_AON_TIMER_BITE, 0, PWRMGR, OT_PWRMGR_RST, OT_PWRMGR_RST_AON_TIMER) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_DARJEELING_AON_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_DJ_AON_CLK_HZ) ), }, - [OT_DARJEELING_SOC_DEV_AST] = { + [OT_DJ_SOC_DEV_AST] = { .type = TYPE_OT_AST_DJ, .memmap = MEMMAPENTRIES( { 0x30480000u, 0x400u } ), }, - [OT_DARJEELING_SOC_DEV_SRAM_RET] = { + [OT_DJ_SOC_DEV_SRAM_RET] = { .type = TYPE_OT_SRAM_CTRL, .instance = 2, .memmap = MEMMAPENTRIES( @@ -961,7 +957,7 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { { 0x30600000u, 0x1000u } ), .link = IBEXDEVICELINKDEFS( - OT_DARJEELING_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_DJ_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("size", 0x1000u), @@ -969,18 +965,18 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { ), }, /* IRQ splitters */ - [OT_DARJEELING_SOC_SPLITTER_LC_HW_DEBUG] = { + [OT_DJ_SOC_SPLITTER_LC_HW_DEBUG] = { .type = TYPE_SPLIT_IRQ, .instance = 0, .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("num-lines", 1u) // to be changed ) }, - [OT_DARJEELING_SOC_SPLITTER_LC_ESCALATE] = { + [OT_DJ_SOC_SPLITTER_LC_ESCALATE] = { .type = TYPE_SPLIT_IRQ, .instance = 1, .gpio = IBEXGPIOCONNDEFS( - OT_DARJEELING_SOC_S2D(0, OTP_CTRL, OT_LC_BROADCAST, + OT_DJ_SOC_S2D(0, OTP_CTRL, OT_LC_BROADCAST, OT_OTP_LC_ESCALATE_EN) ), .prop = IBEXDEVICEPROPDEFS( @@ -990,36 +986,36 @@ static const IbexDeviceDef ot_darjeeling_soc_devices[] = { /* clang-format on */ }; -enum OtDarjeelingBoardDevice { - OT_DARJEELING_BOARD_DEV_SOC, - OT_DARJEELING_BOARD_DEV_FLASH, - OT_DARJEELING_BOARD_DEV_DEV_PROXY, - _OT_DARJEELING_BOARD_DEV_COUNT, +enum OtDjBoardDevice { + OT_DJ_BOARD_DEV_SOC, + OT_DJ_BOARD_DEV_FLASH, + OT_DJ_BOARD_DEV_DEV_PROXY, + OT_DJ_BOARD_DEV_COUNT, }; /* ------------------------------------------------------------------------ */ /* Type definitions */ /* ------------------------------------------------------------------------ */ -struct OtDarjeelingSoCClass { +struct OtDjSoCClass { DeviceClass parent_class; DeviceRealize parent_realize; ResettablePhases parent_phases; }; -struct OtDarjeelingSoCState { +struct OtDjSoCState { SysBusDevice parent_obj; DeviceState **devices; }; -struct OtDarjeelingBoardState { +struct OtDjBoardState { DeviceState parent_obj; DeviceState **devices; }; -struct OtDarjeelingMachineState { +struct OtDjMachineState { MachineState parent_obj; bool no_epmp_cfg; @@ -1029,11 +1025,10 @@ struct OtDarjeelingMachineState { /* Device Configuration */ /* ------------------------------------------------------------------------ */ -static void ot_darjeeling_soc_hart_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) +static void ot_dj_soc_hart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent) { - OtDarjeelingMachineState *ms = - RISCV_OT_DARJEELING_MACHINE(qdev_get_machine()); + OtDjMachineState *ms = RISCV_OT_DJ_MACHINE(qdev_get_machine()); QList *pmp_cfg, *pmp_addr; (void)def; (void)parent; @@ -1044,21 +1039,21 @@ static void ot_darjeeling_soc_hart_configure( } pmp_cfg = qlist_new(); - for (unsigned ix = 0; ix < ARRAY_SIZE(ot_darjeeling_pmp_cfgs); ix++) { - qlist_append_int(pmp_cfg, ot_darjeeling_pmp_cfgs[ix]); + for (unsigned ix = 0; ix < ARRAY_SIZE(ot_dj_pmp_cfgs); ix++) { + qlist_append_int(pmp_cfg, ot_dj_pmp_cfgs[ix]); } qdev_prop_set_array(dev, "pmp_cfg", pmp_cfg); pmp_addr = qlist_new(); - for (unsigned ix = 0; ix < ARRAY_SIZE(ot_darjeeling_pmp_addrs); ix++) { - qlist_append_int(pmp_addr, ot_darjeeling_pmp_addrs[ix]); + for (unsigned ix = 0; ix < ARRAY_SIZE(ot_dj_pmp_addrs); ix++) { + qlist_append_int(pmp_addr, ot_dj_pmp_addrs[ix]); } qdev_prop_set_array(dev, "pmp_addr", pmp_addr); - qdev_prop_set_uint64(dev, "mseccfg", (uint64_t)OT_DARJEELING_MSECCFG); + qdev_prop_set_uint64(dev, "mseccfg", (uint64_t)OT_DJ_MSECCFG); } -static void ot_darjeeling_soc_otp_ctrl_configure( +static void ot_dj_soc_otp_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); @@ -1070,8 +1065,8 @@ static void ot_darjeeling_soc_otp_ctrl_configure( } } -static void ot_darjeeling_soc_uart_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) +static void ot_dj_soc_uart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent) { (void)def; (void)parent; @@ -1082,64 +1077,64 @@ static void ot_darjeeling_soc_uart_configure( /* SoC */ /* ------------------------------------------------------------------------ */ -static void ot_darjeeling_soc_reset_hold(Object *obj) +static void ot_dj_soc_reset_hold(Object *obj) { - OtDarjeelingSoCClass *c = RISCV_OT_DARJEELING_SOC_GET_CLASS(obj); - OtDarjeelingSoCState *s = RISCV_OT_DARJEELING_SOC(obj); + OtDjSoCClass *c = RISCV_OT_DJ_SOC_GET_CLASS(obj); + OtDjSoCState *s = RISCV_OT_DJ_SOC(obj); if (c->parent_phases.hold) { c->parent_phases.hold(obj); } - Object *dmi = OBJECT(s->devices[OT_DARJEELING_SOC_DEV_DMI]); + Object *dmi = OBJECT(s->devices[OT_DJ_SOC_DEV_DMI]); resettable_reset(dmi, RESET_TYPE_COLD); - resettable_reset(OBJECT(s->devices[OT_DARJEELING_SOC_DEV_DM_TL_MBOX]), + resettable_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_DM_TL_MBOX]), RESET_TYPE_COLD); /* keep ROM_CTRLs in reset, we'll release them last */ - resettable_assert_reset(OBJECT(s->devices[OT_DARJEELING_SOC_DEV_ROM0]), + resettable_assert_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_ROM0]), RESET_TYPE_COLD); - resettable_assert_reset(OBJECT(s->devices[OT_DARJEELING_SOC_DEV_ROM1]), + resettable_assert_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_ROM1]), RESET_TYPE_COLD); /* * leave hart on reset * power manager should release it once ROMs have been validated */ - CPUState *cs = CPU(s->devices[OT_DARJEELING_SOC_DEV_HART]); + CPUState *cs = CPU(s->devices[OT_DJ_SOC_DEV_HART]); resettable_assert_reset(OBJECT(cs), RESET_TYPE_COLD); } -static void ot_darjeeling_soc_reset_exit(Object *obj) +static void ot_dj_soc_reset_exit(Object *obj) { - OtDarjeelingSoCClass *c = RISCV_OT_DARJEELING_SOC_GET_CLASS(obj); - OtDarjeelingSoCState *s = RISCV_OT_DARJEELING_SOC(obj); + OtDjSoCClass *c = RISCV_OT_DJ_SOC_GET_CLASS(obj); + OtDjSoCState *s = RISCV_OT_DJ_SOC(obj); if (c->parent_phases.exit) { c->parent_phases.exit(obj); } /* let ROM_CTRLs get out of reset now */ - resettable_release_reset(OBJECT(s->devices[OT_DARJEELING_SOC_DEV_ROM0]), + resettable_release_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_ROM0]), RESET_TYPE_COLD); - resettable_release_reset(OBJECT(s->devices[OT_DARJEELING_SOC_DEV_ROM1]), + resettable_release_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_ROM1]), RESET_TYPE_COLD); } -static void ot_darjeeling_soc_realize(DeviceState *dev, Error **errp) +static void ot_dj_soc_realize(DeviceState *dev, Error **errp) { - OtDarjeelingSoCState *s = RISCV_OT_DARJEELING_SOC(dev); + OtDjSoCState *s = RISCV_OT_DJ_SOC(dev); (void)errp; - CPUState *cpu = CPU(s->devices[OT_DARJEELING_SOC_DEV_HART]); + CPUState *cpu = CPU(s->devices[OT_DJ_SOC_DEV_HART]); cpu->memory = get_system_memory(); cpu->cpu_index = 0; /* Link, define properties and realize devices, then connect GPIOs */ ibex_configure_devices_with_id(s->devices, dev->parent_bus, "ot_id", "", - false, ot_darjeeling_soc_devices, - ARRAY_SIZE(ot_darjeeling_soc_devices)); + false, ot_dj_soc_devices, + ARRAY_SIZE(ot_dj_soc_devices)); Object *oas; @@ -1149,19 +1144,19 @@ static void ot_darjeeling_soc_realize(DeviceState *dev, Error **errp) MemoryRegion *dbg_mr = g_new0(MemoryRegion, 1u); memory_region_init(dbg_mr, OBJECT(dev), "dbg-xbar", - OT_DARJEELING_DBG_XBAR_APERTURE); + OT_DJ_DBG_XBAR_APERTURE); MemoryRegion *mrs[IBEX_MEMMAP_REGIDX_COUNT] = { - [OT_DARJEELING_DEFAULT_MEMORY_REGION] = cpu->memory, - [OT_DARJEELING_CTN_MEMORY_REGION] = ctn_as->root, - [OT_DARJEELING_DEBUG_MEMORY_REGION] = dbg_mr, + [OT_DJ_DEFAULT_MEMORY_REGION] = cpu->memory, + [OT_DJ_CTN_MEMORY_REGION] = ctn_as->root, + [OT_DJ_DEBUG_MEMORY_REGION] = dbg_mr, }; - ibex_map_devices_mask(s->devices, mrs, ot_darjeeling_soc_devices, - ARRAY_SIZE(ot_darjeeling_soc_devices), + ibex_map_devices_mask(s->devices, mrs, ot_dj_soc_devices, + ARRAY_SIZE(ot_dj_soc_devices), IBEX_MEMMAP_MAKE_REG_MASK( - OT_DARJEELING_DEFAULT_MEMORY_REGION) | + OT_DJ_DEFAULT_MEMORY_REGION) | IBEX_MEMMAP_MAKE_REG_MASK( - OT_DARJEELING_DEBUG_MEMORY_REGION)); + OT_DJ_DEBUG_MEMORY_REGION)); AddressSpace *dbg_as = g_new0(AddressSpace, 1u); address_space_init(dbg_as, dbg_mr, "dbg-as"); @@ -1182,8 +1177,7 @@ static void ot_darjeeling_soc_realize(DeviceState *dev, Error **errp) */ MemoryRegion *ctn_dma_mr = g_new0(MemoryRegion, 1u); memory_region_init(ctn_dma_mr, OBJECT(dev), "ctn-dma", - OT_DARJEELING_CTN_REGION_OFFSET + - OT_DARJEELING_CTN_REGION_SIZE); + OT_DJ_CTN_REGION_OFFSET + OT_DJ_CTN_REGION_SIZE); /* create an AS view for this new root region */ AddressSpace *ctn_dma_as = g_new0(AddressSpace, 1u); @@ -1192,10 +1186,8 @@ static void ot_darjeeling_soc_realize(DeviceState *dev, Error **errp) /* create and map an alias to the CTN MR into the elevated region */ MemoryRegion *ctn_amr = g_new0(MemoryRegion, 1u); memory_region_init_alias(ctn_amr, OBJECT(dev), "ctn-dma-alias", - ctn_as->root, 0u, - (uint64_t)OT_DARJEELING_CTN_REGION_SIZE); - memory_region_add_subregion(ctn_dma_mr, - (hwaddr)OT_DARJEELING_CTN_REGION_OFFSET, + ctn_as->root, 0u, (uint64_t)OT_DJ_CTN_REGION_SIZE); + memory_region_add_subregion(ctn_dma_mr, (hwaddr)OT_DJ_CTN_REGION_OFFSET, ctn_amr); oas = object_new(TYPE_OT_ADDRESS_SPACE); @@ -1206,62 +1198,61 @@ static void ot_darjeeling_soc_realize(DeviceState *dev, Error **errp) ibex_load_kernel(cpu->as); } -static void ot_darjeeling_soc_init(Object *obj) +static void ot_dj_soc_init(Object *obj) { - OtDarjeelingSoCState *s = RISCV_OT_DARJEELING_SOC(obj); + OtDjSoCState *s = RISCV_OT_DJ_SOC(obj); jtag_configure_tap(IBEX_TAP_IR_LENGTH, DARJEELING_TAP_IDCODE); - s->devices = - ibex_create_devices(ot_darjeeling_soc_devices, - ARRAY_SIZE(ot_darjeeling_soc_devices), DEVICE(s)); + s->devices = ibex_create_devices(ot_dj_soc_devices, + ARRAY_SIZE(ot_dj_soc_devices), DEVICE(s)); } -static void ot_darjeeling_soc_class_init(ObjectClass *oc, void *data) +static void ot_dj_soc_class_init(ObjectClass *oc, void *data) { - OtDarjeelingSoCClass *sc = RISCV_OT_DARJEELING_SOC_CLASS(oc); + OtDjSoCClass *sc = RISCV_OT_DJ_SOC_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(dc); (void)data; - resettable_class_set_parent_phases(rc, NULL, &ot_darjeeling_soc_reset_hold, - &ot_darjeeling_soc_reset_exit, + resettable_class_set_parent_phases(rc, NULL, &ot_dj_soc_reset_hold, + &ot_dj_soc_reset_exit, &sc->parent_phases); - dc->realize = &ot_darjeeling_soc_realize; + dc->realize = &ot_dj_soc_realize; dc->user_creatable = false; } -static const TypeInfo ot_darjeeling_soc_type_info = { - .name = TYPE_RISCV_OT_DARJEELING_SOC, +static const TypeInfo ot_dj_soc_type_info = { + .name = TYPE_RISCV_OT_DJ_SOC, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(OtDarjeelingSoCState), - .instance_init = &ot_darjeeling_soc_init, - .class_init = &ot_darjeeling_soc_class_init, - .class_size = sizeof(OtDarjeelingSoCClass), + .instance_size = sizeof(OtDjSoCState), + .instance_init = &ot_dj_soc_init, + .class_init = &ot_dj_soc_class_init, + .class_size = sizeof(OtDjSoCClass), }; -static void ot_darjeeling_soc_register_types(void) +static void ot_dj_soc_register_types(void) { - type_register_static(&ot_darjeeling_soc_type_info); + type_register_static(&ot_dj_soc_type_info); } -type_init(ot_darjeeling_soc_register_types); +type_init(ot_dj_soc_register_types); /* ------------------------------------------------------------------------ */ /* Board */ /* ------------------------------------------------------------------------ */ -static void ot_darjeeling_board_realize(DeviceState *dev, Error **errp) +static void ot_dj_board_realize(DeviceState *dev, Error **errp) { - OtDarjeelingBoardState *board = RISCV_OT_DARJEELING_BOARD(dev); + OtDjBoardState *board = RISCV_OT_DJ_BOARD(dev); - DeviceState *soc = board->devices[OT_DARJEELING_BOARD_DEV_SOC]; + DeviceState *soc = board->devices[OT_DJ_BOARD_DEV_SOC]; object_property_add_child(OBJECT(board), "soc", OBJECT(soc)); /* CTN memory region */ MemoryRegion *ctn_mr = g_new0(MemoryRegion, 1u); memory_region_init(ctn_mr, OBJECT(dev), "ctn-xbar", - (uint64_t)OT_DARJEELING_CTN_REGION_SIZE); + (uint64_t)OT_DJ_CTN_REGION_SIZE); /* CTN address space */ AddressSpace *ctn_as = g_new0(AddressSpace, 1); @@ -1270,7 +1261,7 @@ static void ot_darjeeling_board_realize(DeviceState *dev, Error **errp) object_property_add_child(OBJECT(dev), ctn_as->name, oas); ot_address_space_set(OT_ADDRESS_SPACE(oas), ctn_as); - OtDarjeelingSoCState *s = RISCV_OT_DARJEELING_SOC(soc); + OtDjSoCState *s = RISCV_OT_DJ_SOC(soc); BusState *bus = sysbus_get_default(); qdev_realize_and_unref(DEVICE(soc), bus, &error_fatal); @@ -1278,19 +1269,18 @@ static void ot_darjeeling_board_realize(DeviceState *dev, Error **errp) /* CTN RAM */ MemoryRegion *ctn_ram = g_new0(MemoryRegion, 1u); memory_region_init_ram_nomigrate(ctn_ram, OBJECT(s), "ctn-ram", - OT_DARJEELING_CTN_RAM_SIZE, errp); - memory_region_add_subregion(ctn_mr, OT_DARJEELING_CTN_RAM_ADDR, ctn_ram); + OT_DJ_CTN_RAM_SIZE, errp); + memory_region_add_subregion(ctn_mr, OT_DJ_CTN_RAM_ADDR, ctn_ram); /* CTN aliased memory in CPU address space */ MemoryRegion *ctn_alias_mr = g_new0(MemoryRegion, 1u); memory_region_init_alias(ctn_alias_mr, OBJECT(dev), "ctn-alias", ctn_mr, 0u, - (uint64_t)OT_DARJEELING_CTN_REGION_SIZE); + (uint64_t)OT_DJ_CTN_REGION_SIZE); memory_region_add_subregion(get_system_memory(), - (hwaddr)OT_DARJEELING_CTN_REGION_OFFSET, - ctn_alias_mr); + (hwaddr)OT_DJ_CTN_REGION_OFFSET, ctn_alias_mr); - DeviceState *spihost = s->devices[OT_DARJEELING_SOC_DEV_SPI_HOST0]; - DeviceState *flash = board->devices[OT_DARJEELING_BOARD_DEV_FLASH]; + DeviceState *spihost = s->devices[OT_DJ_SOC_DEV_SPI_HOST0]; + DeviceState *flash = board->devices[OT_DJ_BOARD_DEV_FLASH]; BusState *spibus = qdev_get_child_bus(spihost, "spi0"); g_assert(spibus); @@ -1305,108 +1295,105 @@ static void ot_darjeeling_board_realize(DeviceState *dev, Error **errp) qemu_irq cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0); qdev_connect_gpio_out_named(spihost, SSI_GPIO_CS, 0, cs); - DeviceState *devproxy = board->devices[OT_DARJEELING_BOARD_DEV_DEV_PROXY]; + DeviceState *devproxy = board->devices[OT_DJ_BOARD_DEV_DEV_PROXY]; object_property_add_child(OBJECT(board), "devproxy", OBJECT(devproxy)); qdev_realize_and_unref(devproxy, NULL, errp); } -static void ot_darjeeling_board_init(Object *obj) +static void ot_dj_board_init(Object *obj) { - OtDarjeelingBoardState *s = RISCV_OT_DARJEELING_BOARD(obj); + OtDjBoardState *s = RISCV_OT_DJ_BOARD(obj); - s->devices = g_new0(DeviceState *, _OT_DARJEELING_BOARD_DEV_COUNT); - s->devices[OT_DARJEELING_BOARD_DEV_SOC] = - qdev_new(TYPE_RISCV_OT_DARJEELING_SOC); - s->devices[OT_DARJEELING_BOARD_DEV_FLASH] = qdev_new("is25wp128"); - s->devices[OT_DARJEELING_BOARD_DEV_DEV_PROXY] = qdev_new(TYPE_OT_DEV_PROXY); + s->devices = g_new0(DeviceState *, OT_DJ_BOARD_DEV_COUNT); + s->devices[OT_DJ_BOARD_DEV_SOC] = qdev_new(TYPE_RISCV_OT_DJ_SOC); + s->devices[OT_DJ_BOARD_DEV_FLASH] = qdev_new("is25wp128"); + s->devices[OT_DJ_BOARD_DEV_DEV_PROXY] = qdev_new(TYPE_OT_DEV_PROXY); } -static void ot_darjeeling_board_class_init(ObjectClass *oc, void *data) +static void ot_dj_board_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); (void)data; - dc->realize = &ot_darjeeling_board_realize; + dc->realize = &ot_dj_board_realize; } -static const TypeInfo ot_darjeeling_board_type_info = { - .name = TYPE_RISCV_OT_DARJEELING_BOARD, +static const TypeInfo ot_dj_board_type_info = { + .name = TYPE_RISCV_OT_DJ_BOARD, .parent = TYPE_DEVICE, - .instance_size = sizeof(OtDarjeelingBoardState), - .instance_init = &ot_darjeeling_board_init, - .class_init = &ot_darjeeling_board_class_init, + .instance_size = sizeof(OtDjBoardState), + .instance_init = &ot_dj_board_init, + .class_init = &ot_dj_board_class_init, }; -static void ot_darjeeling_board_register_types(void) +static void ot_dj_board_register_types(void) { - type_register_static(&ot_darjeeling_board_type_info); + type_register_static(&ot_dj_board_type_info); } -type_init(ot_darjeeling_board_register_types); +type_init(ot_dj_board_register_types); /* ------------------------------------------------------------------------ */ /* Machine */ /* ------------------------------------------------------------------------ */ -static bool ot_darjeeling_machine_get_no_epmp_cfg(Object *obj, Error **errp) +static bool ot_dj_machine_get_no_epmp_cfg(Object *obj, Error **errp) { - OtDarjeelingMachineState *s = RISCV_OT_DARJEELING_MACHINE(obj); + OtDjMachineState *s = RISCV_OT_DJ_MACHINE(obj); (void)errp; return s->no_epmp_cfg; } -static void -ot_darjeeling_machine_set_no_epmp_cfg(Object *obj, bool value, Error **errp) +static void ot_dj_machine_set_no_epmp_cfg(Object *obj, bool value, Error **errp) { - OtDarjeelingMachineState *s = RISCV_OT_DARJEELING_MACHINE(obj); + OtDjMachineState *s = RISCV_OT_DJ_MACHINE(obj); (void)errp; s->no_epmp_cfg = value; } -static void ot_darjeeling_machine_instance_init(Object *obj) +static void ot_dj_machine_instance_init(Object *obj) { - OtDarjeelingMachineState *s = RISCV_OT_DARJEELING_MACHINE(obj); + OtDjMachineState *s = RISCV_OT_DJ_MACHINE(obj); s->no_epmp_cfg = false; - object_property_add_bool(obj, "no-epmp-cfg", - &ot_darjeeling_machine_get_no_epmp_cfg, - &ot_darjeeling_machine_set_no_epmp_cfg); + object_property_add_bool(obj, "no-epmp-cfg", &ot_dj_machine_get_no_epmp_cfg, + &ot_dj_machine_set_no_epmp_cfg); object_property_set_description(obj, "no-epmp-cfg", "Skip default ePMP configuration"); } -static void ot_darjeeling_machine_init(MachineState *state) +static void ot_dj_machine_init(MachineState *state) { - DeviceState *dev = qdev_new(TYPE_RISCV_OT_DARJEELING_BOARD); + DeviceState *dev = qdev_new(TYPE_RISCV_OT_DJ_BOARD); object_property_add_child(OBJECT(state), "board", OBJECT(dev)); qdev_realize(dev, NULL, &error_fatal); } -static void ot_darjeeling_machine_class_init(ObjectClass *oc, void *data) +static void ot_dj_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); (void)data; mc->desc = "RISC-V Board compatible with OpenTitan Darjeeling platform"; - mc->init = ot_darjeeling_machine_init; + mc->init = ot_dj_machine_init; mc->max_cpus = 1u; mc->default_cpus = 1u; } -static const TypeInfo ot_darjeeling_machine_type_info = { - .name = TYPE_RISCV_OT_DARJEELING_MACHINE, +static const TypeInfo ot_dj_machine_type_info = { + .name = TYPE_RISCV_OT_DJ_MACHINE, .parent = TYPE_MACHINE, - .instance_size = sizeof(OtDarjeelingMachineState), - .instance_init = &ot_darjeeling_machine_instance_init, - .class_init = &ot_darjeeling_machine_class_init, + .instance_size = sizeof(OtDjMachineState), + .instance_init = &ot_dj_machine_instance_init, + .class_init = &ot_dj_machine_class_init, }; -static void ot_darjeeling_machine_register_types(void) +static void ot_dj_machine_register_types(void) { - type_register_static(&ot_darjeeling_machine_type_info); + type_register_static(&ot_dj_machine_type_info); } -type_init(ot_darjeeling_machine_register_types); +type_init(ot_dj_machine_register_types); diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index bb9c560e6630..8772f8149e63 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -70,74 +70,74 @@ /* Forward Declarations */ /* ------------------------------------------------------------------------ */ -static void ot_earlgrey_soc_flash_ctrl_configure( +static void ot_eg_soc_flash_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); -static void ot_earlgrey_soc_hart_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); -static void ot_earlgrey_soc_otp_ctrl_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); -static void ot_earlgrey_soc_uart_configure( +static void ot_eg_soc_hart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent); +static void ot_eg_soc_otp_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent); +static void ot_eg_soc_uart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent); /* ------------------------------------------------------------------------ */ /* Constants */ /* ------------------------------------------------------------------------ */ -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_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_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_SRAM_RET_CTRL, - 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_MAIN_CTRL, - 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, +enum OtEGSocDevice { + OT_EG_SOC_DEV_ADC_CTRL, + OT_EG_SOC_DEV_AES, + OT_EG_SOC_DEV_ALERT_HANDLER, + OT_EG_SOC_DEV_AON_TIMER, + OT_EG_SOC_DEV_AST, + OT_EG_SOC_DEV_CLKMGR, + OT_EG_SOC_DEV_CSRNG, + OT_EG_SOC_DEV_EDN0, + OT_EG_SOC_DEV_EDN1, + OT_EG_SOC_DEV_ENTROPY_SRC, + OT_EG_SOC_DEV_FLASH_CTRL, + OT_EG_SOC_DEV_GPIO, + OT_EG_SOC_DEV_HART, + OT_EG_SOC_DEV_HMAC, + OT_EG_SOC_DEV_I2C0, + OT_EG_SOC_DEV_I2C1, + OT_EG_SOC_DEV_I2C2, + OT_EG_SOC_DEV_IBEX_WRAPPER, + OT_EG_SOC_DEV_KEYMGR, + OT_EG_SOC_DEV_KMAC, + OT_EG_SOC_DEV_LC_CTRL, + OT_EG_SOC_DEV_OTBN, + OT_EG_SOC_DEV_OTP_CTRL, + OT_EG_SOC_DEV_PATTGEN, + OT_EG_SOC_DEV_PINMUX, + OT_EG_SOC_DEV_PLIC, + OT_EG_SOC_DEV_PWM, + OT_EG_SOC_DEV_PWRMGR, + OT_EG_SOC_DEV_SRAM_RET_CTRL, + OT_EG_SOC_DEV_ROM_CTRL, + OT_EG_SOC_DEV_RSTMGR, + OT_EG_SOC_DEV_RV_DM, + OT_EG_SOC_DEV_RV_DM_MEM, + OT_EG_SOC_DEV_SENSOR_CTRL, + OT_EG_SOC_DEV_SPI_DEVICE, + OT_EG_SOC_DEV_SPI_HOST0, + OT_EG_SOC_DEV_SPI_HOST1, + OT_EG_SOC_DEV_SRAM_MAIN_CTRL, + OT_EG_SOC_DEV_SYSRST_CTRL, + OT_EG_SOC_DEV_TIMER, + OT_EG_SOC_DEV_UART0, + OT_EG_SOC_DEV_UART1, + OT_EG_SOC_DEV_UART2, + OT_EG_SOC_DEV_UART3, + OT_EG_SOC_DEV_USBDEV, }; /* EarlGrey/CW310 Peripheral clock is 2.5 MHz */ -#define OT_EARLGREY_PERIPHERAL_CLK_HZ 2500000u +#define OT_EG_PERIPHERAL_CLK_HZ 2500000u /* EarlGrey/CW310 AON clock is 250 kHz */ -#define OT_EARLGREY_AON_CLK_HZ 250000u +#define OT_EG_AON_CLK_HZ 250000u -static const uint8_t ot_earlgrey_pmp_cfgs[] = { +static const uint8_t ot_eg_pmp_cfgs[] = { /* clang-format off */ IBEX_PMP_CFG(0, IBEX_PMP_MODE_OFF, 0, 0, 0), IBEX_PMP_CFG(0, IBEX_PMP_MODE_OFF, 0, 0, 0), @@ -158,7 +158,7 @@ static const uint8_t ot_earlgrey_pmp_cfgs[] = { /* clang-format on */ }; -static const uint32_t ot_earlgrey_pmp_addrs[] = { +static const uint32_t ot_eg_pmp_addrs[] = { /* clang-format off */ IBEX_PMP_ADDR(0x00000000), IBEX_PMP_ADDR(0x00000000), @@ -179,18 +179,18 @@ static const uint32_t ot_earlgrey_pmp_addrs[] = { /* clang-format on */ }; -#define OT_EARLGREY_MSECCFG IBEX_MSECCFG(1, 1, 0) +#define OT_EG_MSECCFG IBEX_MSECCFG(1, 1, 0) -#define OT_EARLGREY_SOC_GPIO(_irq_, _target_, _num_) \ - IBEX_GPIO(_irq_, OT_EARLGREY_SOC_DEV_##_target_, _num_) +#define OT_EG_SOC_GPIO(_irq_, _target_, _num_) \ + IBEX_GPIO(_irq_, OT_EG_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_EG_SOC_GPIO_SYSBUS_IRQ(_irq_, _target_, _num_) \ + IBEX_GPIO_SYSBUS_IRQ(_irq_, OT_EG_SOC_DEV_##_target_, _num_) -#define OT_EARLGREY_SOC_DEVLINK(_pname_, _target_) \ - IBEX_DEVLINK(_pname_, OT_EARLGREY_SOC_DEV_##_target_) +#define OT_EG_SOC_DEVLINK(_pname_, _target_) \ + IBEX_DEVLINK(_pname_, OT_EG_SOC_DEV_##_target_) -#define OT_EARLGREY_SOC_SIGNAL(_sname_, _snum_, _tgt_, _tname_, _tnum_) \ +#define OT_EG_SOC_SIGNAL(_sname_, _snum_, _tgt_, _tname_, _tnum_) \ { \ .out = { \ .name = (_sname_), \ @@ -198,13 +198,13 @@ static const uint32_t ot_earlgrey_pmp_addrs[] = { }, \ .in = { \ .name = (_tname_), \ - .index = (OT_EARLGREY_SOC_DEV_ ## _tgt_), \ + .index = (OT_EG_SOC_DEV_ ## _tgt_), \ .num = (_tnum_), \ } \ } -#define OT_EARLGREY_SOC_CLKMGR_HINT(_num_) \ - OT_EARLGREY_SOC_SIGNAL(OT_CLOCK_ACTIVE, 0, CLKMGR, OT_CLKMGR_HINT, _num_) +#define OT_EG_SOC_CLKMGR_HINT(_num_) \ + OT_EG_SOC_SIGNAL(OT_CLOCK_ACTIVE, 0, CLKMGR, OT_CLKMGR_HINT, _num_) /* * MMIO/interrupt mapping as per: @@ -212,11 +212,11 @@ static const uint32_t ot_earlgrey_pmp_addrs[] = { * and * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey.h */ -static const IbexDeviceDef ot_earlgrey_soc_devices[] = { +static const IbexDeviceDef ot_eg_soc_devices[] = { /* clang-format off */ - [OT_EARLGREY_SOC_DEV_HART] = { + [OT_EG_SOC_DEV_HART] = { .type = TYPE_RISCV_CPU_LOWRISC_IBEX, - .cfg = &ot_earlgrey_soc_hart_configure, + .cfg = &ot_eg_soc_hart_configure, .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_BOOL_PROP("m", true), IBEX_DEV_BOOL_PROP("pmp", true), @@ -230,7 +230,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { IBEX_DEV_BOOL_PROP("start-powered-off", true) ), }, - [OT_EARLGREY_SOC_DEV_RV_DM_MEM] = { + [OT_EG_SOC_DEV_RV_DM_MEM] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-rv_dm_mem", .cfg = &ibex_unimp_configure, @@ -238,155 +238,155 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x00010000u, 0x1000u } ), }, - [OT_EARLGREY_SOC_DEV_UART0] = { + [OT_EG_SOC_DEV_UART0] = { .type = TYPE_OT_UART, - .cfg = &ot_earlgrey_soc_uart_configure, + .cfg = &ot_eg_soc_uart_configure, .instance = 0, .memmap = MEMMAPENTRIES( { 0x40000000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 1), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 2), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 3), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 4), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 5), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 6), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 7), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 8) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 1), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 2), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 3), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 4), + OT_EG_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 5), + OT_EG_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 6), + OT_EG_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 7), + OT_EG_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 8) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_EARLGREY_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_EG_PERIPHERAL_CLK_HZ) ), }, - [OT_EARLGREY_SOC_DEV_UART1] = { + [OT_EG_SOC_DEV_UART1] = { .type = TYPE_OT_UART, - .cfg = &ot_earlgrey_soc_uart_configure, + .cfg = &ot_eg_soc_uart_configure, .instance = 1, .memmap = MEMMAPENTRIES( { 0x40010000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 9), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 10), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 11), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 12), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 13), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 14), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 15), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 16) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 9), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 10), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 11), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 12), + OT_EG_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 13), + OT_EG_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 14), + OT_EG_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 15), + OT_EG_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 16) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_EARLGREY_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_EG_PERIPHERAL_CLK_HZ) ), }, - [OT_EARLGREY_SOC_DEV_UART2] = { + [OT_EG_SOC_DEV_UART2] = { .type = TYPE_OT_UART, - .cfg = &ot_earlgrey_soc_uart_configure, + .cfg = &ot_eg_soc_uart_configure, .instance = 2, .memmap = MEMMAPENTRIES( { 0x40020000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 17), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 18), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 19), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 20), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 21), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 22), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 23), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 24) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 17), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 18), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 19), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 20), + OT_EG_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 21), + OT_EG_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 22), + OT_EG_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 23), + OT_EG_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 24) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_EARLGREY_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_EG_PERIPHERAL_CLK_HZ) ), }, - [OT_EARLGREY_SOC_DEV_UART3] = { + [OT_EG_SOC_DEV_UART3] = { .type = TYPE_OT_UART, - .cfg = &ot_earlgrey_soc_uart_configure, + .cfg = &ot_eg_soc_uart_configure, .instance = 3, .memmap = MEMMAPENTRIES( { 0x40030000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 25), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 26), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 27), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 28), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 29), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 30), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 31), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 32) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 25), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 26), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 27), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 28), + OT_EG_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 29), + OT_EG_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 30), + OT_EG_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 31), + OT_EG_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 32) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_EARLGREY_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_EG_PERIPHERAL_CLK_HZ) ), }, - [OT_EARLGREY_SOC_DEV_GPIO] = { + [OT_EG_SOC_DEV_GPIO] = { .type = TYPE_OT_GPIO, .name = "ot-gpio", .memmap = MEMMAPENTRIES( { 0x40040000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 33), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 34), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 35), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 36), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 37), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 38), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 49), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 40), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 41), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 42), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 43), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 44), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(12, PLIC, 45), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(13, PLIC, 46), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(14, PLIC, 47), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(15, PLIC, 48), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(16, PLIC, 59), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(17, PLIC, 50), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(18, PLIC, 51), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(19, PLIC, 52), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(20, PLIC, 53), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(21, PLIC, 54), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(22, PLIC, 55), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(23, PLIC, 56), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(24, PLIC, 57), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(25, PLIC, 58), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(26, PLIC, 69), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(27, PLIC, 60), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(28, PLIC, 61), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(29, PLIC, 62), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(30, PLIC, 63), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(31, PLIC, 64) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 33), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 34), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 35), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 36), + OT_EG_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 37), + OT_EG_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 38), + OT_EG_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 49), + OT_EG_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 40), + OT_EG_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 41), + OT_EG_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 42), + OT_EG_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 43), + OT_EG_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 44), + OT_EG_SOC_GPIO_SYSBUS_IRQ(12, PLIC, 45), + OT_EG_SOC_GPIO_SYSBUS_IRQ(13, PLIC, 46), + OT_EG_SOC_GPIO_SYSBUS_IRQ(14, PLIC, 47), + OT_EG_SOC_GPIO_SYSBUS_IRQ(15, PLIC, 48), + OT_EG_SOC_GPIO_SYSBUS_IRQ(16, PLIC, 59), + OT_EG_SOC_GPIO_SYSBUS_IRQ(17, PLIC, 50), + OT_EG_SOC_GPIO_SYSBUS_IRQ(18, PLIC, 51), + OT_EG_SOC_GPIO_SYSBUS_IRQ(19, PLIC, 52), + OT_EG_SOC_GPIO_SYSBUS_IRQ(20, PLIC, 53), + OT_EG_SOC_GPIO_SYSBUS_IRQ(21, PLIC, 54), + OT_EG_SOC_GPIO_SYSBUS_IRQ(22, PLIC, 55), + OT_EG_SOC_GPIO_SYSBUS_IRQ(23, PLIC, 56), + OT_EG_SOC_GPIO_SYSBUS_IRQ(24, PLIC, 57), + OT_EG_SOC_GPIO_SYSBUS_IRQ(25, PLIC, 58), + OT_EG_SOC_GPIO_SYSBUS_IRQ(26, PLIC, 69), + OT_EG_SOC_GPIO_SYSBUS_IRQ(27, PLIC, 60), + OT_EG_SOC_GPIO_SYSBUS_IRQ(28, PLIC, 61), + OT_EG_SOC_GPIO_SYSBUS_IRQ(29, PLIC, 62), + OT_EG_SOC_GPIO_SYSBUS_IRQ(30, PLIC, 63), + OT_EG_SOC_GPIO_SYSBUS_IRQ(31, PLIC, 64) ) }, - [OT_EARLGREY_SOC_DEV_SPI_DEVICE] = { + [OT_EG_SOC_DEV_SPI_DEVICE] = { .type = TYPE_OT_SPI_DEVICE, .memmap = MEMMAPENTRIES( { 0x40050000u, 0x2000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 65), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 66), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 67), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 68), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 69), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 70), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 71), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 72), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 73), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 74), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 75), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 76) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 65), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 66), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 67), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 68), + OT_EG_SOC_GPIO_SYSBUS_IRQ(4, PLIC, 69), + OT_EG_SOC_GPIO_SYSBUS_IRQ(5, PLIC, 70), + OT_EG_SOC_GPIO_SYSBUS_IRQ(6, PLIC, 71), + OT_EG_SOC_GPIO_SYSBUS_IRQ(7, PLIC, 72), + OT_EG_SOC_GPIO_SYSBUS_IRQ(8, PLIC, 73), + OT_EG_SOC_GPIO_SYSBUS_IRQ(9, PLIC, 74), + OT_EG_SOC_GPIO_SYSBUS_IRQ(10, PLIC, 75), + OT_EG_SOC_GPIO_SYSBUS_IRQ(11, PLIC, 76) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_BOOL_PROP("dpsram", true) ), }, - [OT_EARLGREY_SOC_DEV_I2C0] = { + [OT_EG_SOC_DEV_I2C0] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-i2c", .cfg = &ibex_unimp_configure, @@ -395,7 +395,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40080000u, 0x80u } ), }, - [OT_EARLGREY_SOC_DEV_I2C1] = { + [OT_EG_SOC_DEV_I2C1] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-i2c", .cfg = &ibex_unimp_configure, @@ -404,7 +404,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40090000u, 0x80u } ), }, - [OT_EARLGREY_SOC_DEV_I2C2] = { + [OT_EG_SOC_DEV_I2C2] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-i2c", .cfg = &ibex_unimp_configure, @@ -413,7 +413,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x400a0000u, 0x80u } ), }, - [OT_EARLGREY_SOC_DEV_PATTGEN] = { + [OT_EG_SOC_DEV_PATTGEN] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-pattgen", .cfg = &ibex_unimp_configure, @@ -421,45 +421,45 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x400e0000u, 0x40u } ), }, - [OT_EARLGREY_SOC_DEV_TIMER] = { + [OT_EG_SOC_DEV_TIMER] = { .type = TYPE_OT_TIMER, .memmap = MEMMAPENTRIES( { 0x40100000u, 0x200u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO(0, HART, IRQ_M_TIMER), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 124) + OT_EG_SOC_GPIO(0, HART, IRQ_M_TIMER), + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 124) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_EARLGREY_PERIPHERAL_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_EG_PERIPHERAL_CLK_HZ) ), }, - [OT_EARLGREY_SOC_DEV_OTP_CTRL] = { + [OT_EG_SOC_DEV_OTP_CTRL] = { .type = TYPE_OT_OTP_EG, - .cfg = &ot_earlgrey_soc_otp_ctrl_configure, + .cfg = &ot_eg_soc_otp_ctrl_configure, .memmap = MEMMAPENTRIES( { 0x40130000u, 0x2000u }, { 0x40132000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 125), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 126) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 125), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 126) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("edn", EDN0) + OT_EG_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 1u) ), }, - [OT_EARLGREY_SOC_DEV_LC_CTRL] = { + [OT_EG_SOC_DEV_LC_CTRL] = { .type = TYPE_OT_LC_CTRL, .memmap = MEMMAPENTRIES( { 0x40140000u, 0x100u } ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("otp_ctrl", OTP_CTRL), - OT_EARLGREY_SOC_DEVLINK("kmac", KMAC) + OT_EG_SOC_DEVLINK("otp_ctrl", OTP_CTRL), + OT_EG_SOC_DEVLINK("kmac", KMAC) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 4u) @@ -472,53 +472,53 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { IBEX_DEV_UINT_PROP("kmac-app", 1u) ) }, - [OT_EARLGREY_SOC_DEV_ALERT_HANDLER] = { + [OT_EG_SOC_DEV_ALERT_HANDLER] = { .type = TYPE_OT_ALERT_EG, .memmap = MEMMAPENTRIES( { 0x40150000u, 0x800u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 127), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 128), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 129), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 130) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 127), + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 128), + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 129), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 130) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("edn", EDN0) + OT_EG_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 4u) ), }, - [OT_EARLGREY_SOC_DEV_SPI_HOST0] = { + [OT_EG_SOC_DEV_SPI_HOST0] = { .type = TYPE_OT_SPI_HOST, .instance = 0, .memmap = MEMMAPENTRIES( { 0x40300000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 131), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 132) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 131), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 132) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("bus-num", 0) ), }, - [OT_EARLGREY_SOC_DEV_SPI_HOST1] = { + [OT_EG_SOC_DEV_SPI_HOST1] = { .type = TYPE_OT_SPI_HOST, .instance = 1, .memmap = MEMMAPENTRIES( { 0x40310000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 133), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 134) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 133), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 134) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("bus-num", 1) ), }, - [OT_EARLGREY_SOC_DEV_USBDEV] = { + [OT_EG_SOC_DEV_USBDEV] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-usbdev", .cfg = &ibex_unimp_configure, @@ -526,20 +526,20 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40320000u, 0x1000u } ), }, - [OT_EARLGREY_SOC_DEV_PWRMGR] = { + [OT_EG_SOC_DEV_PWRMGR] = { .type = TYPE_OT_PWRMGR, .memmap = MEMMAPENTRIES( { 0x40400000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 152), + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 152), /* loopback signal since Earlgrey OTP signal are not supported yet*/ - OT_EARLGREY_SOC_SIGNAL(OT_PWRMGR_OTP_REQ, 0, PWRMGR, + OT_EG_SOC_SIGNAL(OT_PWRMGR_OTP_REQ, 0, PWRMGR, OT_PWRMGR_OTP_RSP, 0), /* loopback signal since Earlgrey OTP signal are not supported yet*/ - OT_EARLGREY_SOC_SIGNAL(OT_PWRMGR_LC_REQ, 0, PWRMGR, + OT_EG_SOC_SIGNAL(OT_PWRMGR_LC_REQ, 0, PWRMGR, OT_PWRMGR_LC_RSP, 0), - OT_EARLGREY_SOC_SIGNAL(OT_PWRMGR_CPU_EN, 0, IBEX_WRAPPER, + OT_EG_SOC_SIGNAL(OT_PWRMGR_CPU_EN, 0, IBEX_WRAPPER, OT_IBEX_WRAPPER_CPU_EN, OT_IBEX_PWRMGR_CPU_EN) ), @@ -547,26 +547,26 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { IBEX_DEV_UINT_PROP("num-rom", 1u) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("rstmgr", RSTMGR) + OT_EG_SOC_DEVLINK("rstmgr", RSTMGR) ), }, - [OT_EARLGREY_SOC_DEV_RSTMGR] = { + [OT_EG_SOC_DEV_RSTMGR] = { .type = TYPE_OT_RSTMGR, .memmap = MEMMAPENTRIES( { 0x40410000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_SIGNAL(OT_RSTMGR_SW_RST, 0, PWRMGR, \ + OT_EG_SOC_SIGNAL(OT_RSTMGR_SW_RST, 0, PWRMGR, \ OT_PWRMGR_SW_RST, 0) ), }, - [OT_EARLGREY_SOC_DEV_CLKMGR] = { + [OT_EG_SOC_DEV_CLKMGR] = { .type = TYPE_OT_CLKMGR, .memmap = MEMMAPENTRIES( { 0x40420000u, 0x80u } ), }, - [OT_EARLGREY_SOC_DEV_SYSRST_CTRL] = { + [OT_EG_SOC_DEV_SYSRST_CTRL] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-sysrst_ctrl", .cfg = &ibex_unimp_configure, @@ -574,7 +574,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40430000u, 0x100u } ), }, - [OT_EARLGREY_SOC_DEV_ADC_CTRL] = { + [OT_EG_SOC_DEV_ADC_CTRL] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-adc_ctrl", .cfg = &ibex_unimp_configure, @@ -582,7 +582,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40440000u, 0x80u } ), }, - [OT_EARLGREY_SOC_DEV_PWM] = { + [OT_EG_SOC_DEV_PWM] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-pwm", .cfg = &ibex_unimp_configure, @@ -590,44 +590,44 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40450000u, 0x80u } ), }, - [OT_EARLGREY_SOC_DEV_PINMUX] = { + [OT_EG_SOC_DEV_PINMUX] = { .type = TYPE_OT_PINMUX, .memmap = MEMMAPENTRIES( { 0x40460000u, 0x1000u } ), }, - [OT_EARLGREY_SOC_DEV_AON_TIMER] = { + [OT_EG_SOC_DEV_AON_TIMER] = { .type = TYPE_OT_AON_TIMER, .memmap = MEMMAPENTRIES( { 0x40470000u, 0x40u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 155), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 156), - OT_EARLGREY_SOC_SIGNAL(OT_AON_TIMER_WKUP, 0, PWRMGR, \ + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 155), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 156), + OT_EG_SOC_SIGNAL(OT_AON_TIMER_WKUP, 0, PWRMGR, \ OT_PWRMGR_WKUP, \ OT_PWRMGR_WAKEUP_AON_TIMER), - OT_EARLGREY_SOC_SIGNAL(OT_AON_TIMER_BITE, 0, PWRMGR, \ + OT_EG_SOC_SIGNAL(OT_AON_TIMER_BITE, 0, PWRMGR, \ OT_PWRMGR_RST, OT_PWRMGR_RST_AON_TIMER) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("pclk", OT_EARLGREY_AON_CLK_HZ) + IBEX_DEV_UINT_PROP("pclk", OT_EG_AON_CLK_HZ) ), }, - [OT_EARLGREY_SOC_DEV_AST] = { + [OT_EG_SOC_DEV_AST] = { .type = TYPE_OT_AST_EG, .memmap = MEMMAPENTRIES( { 0x40480000u, 0x400u } ), }, - [OT_EARLGREY_SOC_DEV_SENSOR_CTRL] = { + [OT_EG_SOC_DEV_SENSOR_CTRL] = { .type = TYPE_OT_SENSOR, .memmap = MEMMAPENTRIES( { 0x40490000u, 0x40u } ), }, - [OT_EARLGREY_SOC_DEV_SRAM_RET_CTRL] = { + [OT_EG_SOC_DEV_SRAM_RET_CTRL] = { .type = TYPE_OT_SRAM_CTRL, .instance = 0, .memmap = MEMMAPENTRIES( @@ -635,94 +635,94 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x40600000u, 0x1000u } ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_EG_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("size", 0x1000u), IBEX_DEV_STRING_PROP("ot_id", "ret") ), }, - [OT_EARLGREY_SOC_DEV_FLASH_CTRL] = { + [OT_EG_SOC_DEV_FLASH_CTRL] = { .type = TYPE_OT_FLASH, - .cfg = &ot_earlgrey_soc_flash_ctrl_configure, + .cfg = &ot_eg_soc_flash_ctrl_configure, .memmap = MEMMAPENTRIES( { 0x41000000u, 0x1000u }, { 0x41008000u, 0x1000u }, { 0x20000000u, 0x100000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 159), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 160), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 161), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 162), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 163), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 164) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 159), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 160), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 161), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 162), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 163), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 164) ), }, - [OT_EARLGREY_SOC_DEV_AES] = { + [OT_EG_SOC_DEV_AES] = { .type = TYPE_OT_AES, .memmap = MEMMAPENTRIES( { 0x41100000u, 0x100u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_AES) + OT_EG_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_AES) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("edn", EDN0) + OT_EG_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 5u) ), }, - [OT_EARLGREY_SOC_DEV_HMAC] = { + [OT_EG_SOC_DEV_HMAC] = { .type = TYPE_OT_HMAC, .memmap = MEMMAPENTRIES( { 0x41110000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 165), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 166), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 167), - OT_EARLGREY_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_HMAC) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 165), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 166), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 167), + OT_EG_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_HMAC) ), }, - [OT_EARLGREY_SOC_DEV_KMAC] = { + [OT_EG_SOC_DEV_KMAC] = { .type = TYPE_OT_KMAC, .memmap = MEMMAPENTRIES( { 0x41120000u, 0x1000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 168), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 169), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 170) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 168), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 169), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 170) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("edn", EDN0) + OT_EG_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 3u), IBEX_DEV_UINT_PROP("num-app", 3u) ), }, - [OT_EARLGREY_SOC_DEV_OTBN] = { + [OT_EG_SOC_DEV_OTBN] = { .type = TYPE_OT_OTBN, .memmap = MEMMAPENTRIES( { 0x41130000u, 0x10000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 171), - OT_EARLGREY_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_OTBN) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 171), + OT_EG_SOC_CLKMGR_HINT(OT_CLKMGR_HINT_OTBN) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("edn-u", EDN0), - OT_EARLGREY_SOC_DEVLINK("edn-r", EDN1) + OT_EG_SOC_DEVLINK("edn-u", EDN0), + OT_EG_SOC_DEVLINK("edn-r", EDN1) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-u-ep", 6u), IBEX_DEV_UINT_PROP("edn-r-ep", 0u) ), }, - [OT_EARLGREY_SOC_DEV_KEYMGR] = { + [OT_EG_SOC_DEV_KEYMGR] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-keymgr", .cfg = &ibex_unimp_configure, @@ -730,73 +730,73 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x41140000u, 0x100u } ), }, - [OT_EARLGREY_SOC_DEV_CSRNG] = { + [OT_EG_SOC_DEV_CSRNG] = { .type = TYPE_OT_CSRNG, .memmap = MEMMAPENTRIES( { 0x41150000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 173), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 174), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 175), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 176) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 173), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 174), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 175), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 176) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("random_src", ENTROPY_SRC), - OT_EARLGREY_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_EG_SOC_DEVLINK("random_src", ENTROPY_SRC), + OT_EG_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), }, - [OT_EARLGREY_SOC_DEV_ENTROPY_SRC] = { + [OT_EG_SOC_DEV_ENTROPY_SRC] = { .type = TYPE_OT_ENTROPY_SRC, .memmap = MEMMAPENTRIES( { 0x41160000u, 0x100u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 177), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 178), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 179), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 180) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 177), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 178), + OT_EG_SOC_GPIO_SYSBUS_IRQ(2, PLIC, 179), + OT_EG_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 180) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("ast", AST), - OT_EARLGREY_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_EG_SOC_DEVLINK("ast", AST), + OT_EG_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), }, - [OT_EARLGREY_SOC_DEV_EDN0] = { + [OT_EG_SOC_DEV_EDN0] = { .type = TYPE_OT_EDN, .instance = 0, .memmap = MEMMAPENTRIES( { 0x41170000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 181), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 182) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 181), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 182) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("csrng", CSRNG) + OT_EG_SOC_DEVLINK("csrng", CSRNG) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("csrng-app", 0u) ), }, - [OT_EARLGREY_SOC_DEV_EDN1] = { + [OT_EG_SOC_DEV_EDN1] = { .type = TYPE_OT_EDN, .instance = 1, .memmap = MEMMAPENTRIES( { 0x41180000u, 0x80u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 183), - OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 184) + OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 183), + OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 184) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("csrng", CSRNG) + OT_EG_SOC_DEVLINK("csrng", CSRNG) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("csrng-app", 1u) ), }, - [OT_EARLGREY_SOC_DEV_SRAM_MAIN_CTRL] = { + [OT_EG_SOC_DEV_SRAM_MAIN_CTRL] = { .type = TYPE_OT_SRAM_CTRL, .instance = 1, .memmap = MEMMAPENTRIES( @@ -804,14 +804,14 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x10000000u, 0x20000u } ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("otp_ctrl", OTP_CTRL) + OT_EG_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("size", 0x20000u), IBEX_DEV_STRING_PROP("ot_id", "ram") ), }, - [OT_EARLGREY_SOC_DEV_ROM_CTRL] = { + [OT_EG_SOC_DEV_ROM_CTRL] = { .type = TYPE_OT_ROM_CTRL, .name = "ot-rom_ctrl", .memmap = MEMMAPENTRIES( @@ -819,13 +819,13 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x00008000u, 0x8000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_SIGNAL(OT_ROM_CTRL_GOOD, 0, PWRMGR, \ + OT_EG_SOC_SIGNAL(OT_ROM_CTRL_GOOD, 0, PWRMGR, \ OT_PWRMGR_ROM_GOOD, 0), - OT_EARLGREY_SOC_SIGNAL(OT_ROM_CTRL_DONE, 0, PWRMGR, \ + OT_EG_SOC_SIGNAL(OT_ROM_CTRL_DONE, 0, PWRMGR, \ OT_PWRMGR_ROM_DONE, 0) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("kmac", KMAC) + OT_EG_SOC_DEVLINK("kmac", KMAC) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("ot_id", "rom"), @@ -833,19 +833,19 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { IBEX_DEV_UINT_PROP("kmac-app", 2u) ), }, - [OT_EARLGREY_SOC_DEV_IBEX_WRAPPER] = { + [OT_EG_SOC_DEV_IBEX_WRAPPER] = { .type = TYPE_OT_IBEX_WRAPPER_EG, .memmap = MEMMAPENTRIES( { 0x411f0000u, 0x100u } ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("edn", EDN0) + OT_EG_SOC_DEVLINK("edn", EDN0) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("edn-ep", 7u) ), }, - [OT_EARLGREY_SOC_DEV_RV_DM] = { + [OT_EG_SOC_DEV_RV_DM] = { .type = TYPE_UNIMPLEMENTED_DEVICE, .name = "ot-rv_dm", .cfg = &ibex_unimp_configure, @@ -853,13 +853,13 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { { 0x41200000u, 0x4u } ), }, - [OT_EARLGREY_SOC_DEV_PLIC] = { + [OT_EG_SOC_DEV_PLIC] = { .type = TYPE_SIFIVE_PLIC, .memmap = MEMMAPENTRIES( { 0x48000000u, 0x8000000u } ), .gpio = IBEXGPIOCONNDEFS( - OT_EARLGREY_SOC_GPIO(1, HART, IRQ_M_EXT) + OT_EG_SOC_GPIO(1, HART, IRQ_M_EXT) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_STRING_PROP("hart-config", "M"), @@ -879,35 +879,35 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { /* clang-format on */ }; -enum OtEarlGreyBoardDevice { - OT_EARLGREY_BOARD_DEV_SOC, - OT_EARLGREY_BOARD_DEV_FLASH, - _OT_EARLGREY_BOARD_DEV_COUNT, +enum OtEGBoardDevice { + OT_EG_BOARD_DEV_SOC, + OT_EG_BOARD_DEV_FLASH, + OT_EG_BOARD_DEV_COUNT, }; /* ------------------------------------------------------------------------ */ /* Type definitions */ /* ------------------------------------------------------------------------ */ -struct OtEarlGreySoCClass { +struct OtEGSoCClass { DeviceClass parent_class; DeviceRealize parent_realize; ResettablePhases parent_phases; }; -struct OtEarlGreySoCState { +struct OtEGSoCState { SysBusDevice parent_obj; DeviceState **devices; }; -struct OtEarlGreyBoardState { +struct OtEGBoardState { DeviceState parent_obj; DeviceState **devices; }; -struct OtEarlGreyMachineState { +struct OtEGMachineState { MachineState parent_obj; bool no_epmp_cfg; @@ -917,7 +917,7 @@ struct OtEarlGreyMachineState { /* Device Configuration */ /* ------------------------------------------------------------------------ */ -static void ot_earlgrey_soc_flash_ctrl_configure( +static void ot_eg_soc_flash_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { DriveInfo *dinfo = drive_get(IF_MTD, 1, 0); @@ -930,10 +930,10 @@ static void ot_earlgrey_soc_flash_ctrl_configure( } } -static void ot_earlgrey_soc_hart_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) +static void ot_eg_soc_hart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent) { - OtEarlGreyMachineState *ms = RISCV_OT_EARLGREY_MACHINE(qdev_get_machine()); + OtEGMachineState *ms = RISCV_OT_EG_MACHINE(qdev_get_machine()); QList *pmp_cfg, *pmp_addr; (void)def; (void)parent; @@ -944,21 +944,21 @@ static void ot_earlgrey_soc_hart_configure( } pmp_cfg = qlist_new(); - for (unsigned ix = 0; ix < ARRAY_SIZE(ot_earlgrey_pmp_cfgs); ix++) { - qlist_append_int(pmp_cfg, ot_earlgrey_pmp_cfgs[ix]); + for (unsigned ix = 0; ix < ARRAY_SIZE(ot_eg_pmp_cfgs); ix++) { + qlist_append_int(pmp_cfg, ot_eg_pmp_cfgs[ix]); } qdev_prop_set_array(dev, "pmp_cfg", pmp_cfg); pmp_addr = qlist_new(); - for (unsigned ix = 0; ix < ARRAY_SIZE(ot_earlgrey_pmp_addrs); ix++) { - qlist_append_int(pmp_addr, ot_earlgrey_pmp_addrs[ix]); + for (unsigned ix = 0; ix < ARRAY_SIZE(ot_eg_pmp_addrs); ix++) { + qlist_append_int(pmp_addr, ot_eg_pmp_addrs[ix]); } qdev_prop_set_array(dev, "pmp_addr", pmp_addr); - qdev_prop_set_uint64(dev, "mseccfg", (uint64_t)OT_EARLGREY_MSECCFG); + qdev_prop_set_uint64(dev, "mseccfg", (uint64_t)OT_EG_MSECCFG); } -static void ot_earlgrey_soc_otp_ctrl_configure( +static void ot_eg_soc_otp_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); @@ -971,8 +971,8 @@ static void ot_earlgrey_soc_otp_ctrl_configure( } } -static void ot_earlgrey_soc_uart_configure( - DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) +static void ot_eg_soc_uart_configure(DeviceState *dev, const IbexDeviceDef *def, + DeviceState *parent) { (void)def; (void)parent; @@ -983,114 +983,113 @@ static void ot_earlgrey_soc_uart_configure( /* SoC */ /* ------------------------------------------------------------------------ */ -static void ot_earlgrey_soc_reset_hold(Object *obj) +static void ot_eg_soc_reset_hold(Object *obj) { - OtEarlGreySoCClass *c = RISCV_OT_EARLGREY_SOC_GET_CLASS(obj); - OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(obj); + OtEGSoCClass *c = RISCV_OT_EG_SOC_GET_CLASS(obj); + OtEGSoCState *s = RISCV_OT_EG_SOC(obj); if (c->parent_phases.hold) { c->parent_phases.hold(obj); } /* keep ROM_CTRL in reset, we'll release it last */ - resettable_assert_reset(OBJECT(s->devices[OT_EARLGREY_SOC_DEV_ROM_CTRL]), + resettable_assert_reset(OBJECT(s->devices[OT_EG_SOC_DEV_ROM_CTRL]), RESET_TYPE_COLD); /* * leave hart on reset * power manager should release it once ROM has been validated */ - CPUState *cs = CPU(s->devices[OT_EARLGREY_SOC_DEV_HART]); + CPUState *cs = CPU(s->devices[OT_EG_SOC_DEV_HART]); resettable_assert_reset(OBJECT(cs), RESET_TYPE_COLD); } -static void ot_earlgrey_soc_reset_exit(Object *obj) +static void ot_eg_soc_reset_exit(Object *obj) { - OtEarlGreySoCClass *c = RISCV_OT_EARLGREY_SOC_GET_CLASS(obj); - OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(obj); + OtEGSoCClass *c = RISCV_OT_EG_SOC_GET_CLASS(obj); + OtEGSoCState *s = RISCV_OT_EG_SOC(obj); if (c->parent_phases.exit) { c->parent_phases.exit(obj); } /* let ROM_CTRL get out of reset now */ - resettable_release_reset(OBJECT(s->devices[OT_EARLGREY_SOC_DEV_ROM_CTRL]), + resettable_release_reset(OBJECT(s->devices[OT_EG_SOC_DEV_ROM_CTRL]), RESET_TYPE_COLD); } -static void ot_earlgrey_soc_realize(DeviceState *dev, Error **errp) +static void ot_eg_soc_realize(DeviceState *dev, Error **errp) { - OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(dev); + OtEGSoCState *s = RISCV_OT_EG_SOC(dev); (void)errp; /* Link, define properties and realize devices, then connect GPIOs */ BusState *bus = sysbus_get_default(); ibex_configure_devices_with_id(s->devices, bus, "ot_id", "", false, - ot_earlgrey_soc_devices, - ARRAY_SIZE(ot_earlgrey_soc_devices)); + ot_eg_soc_devices, + ARRAY_SIZE(ot_eg_soc_devices)); MemoryRegion *mrs[] = { get_system_memory(), NULL, NULL, NULL }; - ibex_map_devices(s->devices, mrs, ot_earlgrey_soc_devices, - ARRAY_SIZE(ot_earlgrey_soc_devices)); + ibex_map_devices(s->devices, mrs, ot_eg_soc_devices, + ARRAY_SIZE(ot_eg_soc_devices)); /* load kernel if provided */ ibex_load_kernel(NULL); } -static void ot_earlgrey_soc_init(Object *obj) +static void ot_eg_soc_init(Object *obj) { - OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(obj); + OtEGSoCState *s = RISCV_OT_EG_SOC(obj); - s->devices = - ibex_create_devices(ot_earlgrey_soc_devices, - ARRAY_SIZE(ot_earlgrey_soc_devices), DEVICE(s)); + s->devices = ibex_create_devices(ot_eg_soc_devices, + ARRAY_SIZE(ot_eg_soc_devices), DEVICE(s)); } -static void ot_earlgrey_soc_class_init(ObjectClass *oc, void *data) +static void ot_eg_soc_class_init(ObjectClass *oc, void *data) { - OtEarlGreySoCClass *sc = RISCV_OT_EARLGREY_SOC_CLASS(oc); + OtEGSoCClass *sc = RISCV_OT_EG_SOC_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(dc); (void)data; - resettable_class_set_parent_phases(rc, NULL, &ot_earlgrey_soc_reset_hold, - &ot_earlgrey_soc_reset_exit, + resettable_class_set_parent_phases(rc, NULL, &ot_eg_soc_reset_hold, + &ot_eg_soc_reset_exit, &sc->parent_phases); - dc->realize = &ot_earlgrey_soc_realize; + dc->realize = &ot_eg_soc_realize; dc->user_creatable = false; } -static const TypeInfo ot_earlgrey_soc_type_info = { - .name = TYPE_RISCV_OT_EARLGREY_SOC, +static const TypeInfo ot_eg_soc_type_info = { + .name = TYPE_RISCV_OT_EG_SOC, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(OtEarlGreySoCState), - .instance_init = &ot_earlgrey_soc_init, - .class_init = &ot_earlgrey_soc_class_init, - .class_size = sizeof(OtEarlGreySoCClass), + .instance_size = sizeof(OtEGSoCState), + .instance_init = &ot_eg_soc_init, + .class_init = &ot_eg_soc_class_init, + .class_size = sizeof(OtEGSoCClass), }; -static void ot_earlgrey_soc_register_types(void) +static void ot_eg_soc_register_types(void) { - type_register_static(&ot_earlgrey_soc_type_info); + type_register_static(&ot_eg_soc_type_info); } -type_init(ot_earlgrey_soc_register_types); +type_init(ot_eg_soc_register_types); /* ------------------------------------------------------------------------ */ /* Board */ /* ------------------------------------------------------------------------ */ -static void ot_earlgrey_board_realize(DeviceState *dev, Error **errp) +static void ot_eg_board_realize(DeviceState *dev, Error **errp) { - OtEarlGreyBoardState *board = RISCV_OT_EARLGREY_BOARD(dev); + OtEGBoardState *board = RISCV_OT_EG_BOARD(dev); - DeviceState *soc = board->devices[OT_EARLGREY_BOARD_DEV_SOC]; + DeviceState *soc = board->devices[OT_EG_BOARD_DEV_SOC]; object_property_add_child(OBJECT(board), "soc", OBJECT(soc)); sysbus_realize_and_unref(SYS_BUS_DEVICE(soc), &error_fatal); DeviceState *spihost = - RISCV_OT_EARLGREY_SOC(soc)->devices[OT_EARLGREY_SOC_DEV_SPI_HOST0]; - DeviceState *flash = board->devices[OT_EARLGREY_BOARD_DEV_FLASH]; + RISCV_OT_EG_SOC(soc)->devices[OT_EG_SOC_DEV_SPI_HOST0]; + DeviceState *flash = board->devices[OT_EG_BOARD_DEV_FLASH]; BusState *spibus = qdev_get_child_bus(spihost, "spi0"); g_assert(spibus); @@ -1106,107 +1105,103 @@ static void ot_earlgrey_board_realize(DeviceState *dev, Error **errp) qdev_connect_gpio_out_named(spihost, SSI_GPIO_CS, 0, cs); } -static void ot_earlgrey_board_init(Object *obj) +static void ot_eg_board_init(Object *obj) { - OtEarlGreyBoardState *s = RISCV_OT_EARLGREY_BOARD(obj); + OtEGBoardState *s = RISCV_OT_EG_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); - s->devices[OT_EARLGREY_BOARD_DEV_FLASH] = qdev_new("is25wp128"); + s->devices = g_new0(DeviceState *, OT_EG_BOARD_DEV_COUNT); + s->devices[OT_EG_BOARD_DEV_SOC] = qdev_new(TYPE_RISCV_OT_EG_SOC); + s->devices[OT_EG_BOARD_DEV_FLASH] = qdev_new("is25wp128"); } -static void ot_earlgrey_board_class_init(ObjectClass *oc, void *data) +static void ot_eg_board_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); (void)data; - dc->realize = &ot_earlgrey_board_realize; + dc->realize = &ot_eg_board_realize; } -static const TypeInfo ot_earlgrey_board_type_info = { - .name = TYPE_RISCV_OT_EARLGREY_BOARD, +static const TypeInfo ot_eg_board_type_info = { + .name = TYPE_RISCV_OT_EG_BOARD, .parent = TYPE_DEVICE, - .instance_size = sizeof(OtEarlGreyBoardState), - .instance_init = &ot_earlgrey_board_init, - .class_init = &ot_earlgrey_board_class_init, + .instance_size = sizeof(OtEGBoardState), + .instance_init = &ot_eg_board_init, + .class_init = &ot_eg_board_class_init, }; -static void ot_earlgrey_board_register_types(void) +static void ot_eg_board_register_types(void) { - type_register_static(&ot_earlgrey_board_type_info); + type_register_static(&ot_eg_board_type_info); } -type_init(ot_earlgrey_board_register_types); +type_init(ot_eg_board_register_types); /* ------------------------------------------------------------------------ */ /* Machine */ /* ------------------------------------------------------------------------ */ -static bool ot_earlgrey_machine_get_no_epmp_cfg(Object *obj, Error **errp) +static bool ot_eg_machine_get_no_epmp_cfg(Object *obj, Error **errp) { - OtEarlGreyMachineState *s = RISCV_OT_EARLGREY_MACHINE(obj); + OtEGMachineState *s = RISCV_OT_EG_MACHINE(obj); (void)errp; return s->no_epmp_cfg; } -static void -ot_earlgrey_machine_set_no_epmp_cfg(Object *obj, bool value, Error **errp) +static void ot_eg_machine_set_no_epmp_cfg(Object *obj, bool value, Error **errp) { - OtEarlGreyMachineState *s = RISCV_OT_EARLGREY_MACHINE(obj); + OtEGMachineState *s = RISCV_OT_EG_MACHINE(obj); (void)errp; s->no_epmp_cfg = value; } -static void ot_earlgrey_machine_instance_init(Object *obj) +static void ot_eg_machine_instance_init(Object *obj) { - OtEarlGreyMachineState *s = RISCV_OT_EARLGREY_MACHINE(obj); + OtEGMachineState *s = RISCV_OT_EG_MACHINE(obj); s->no_epmp_cfg = false; - object_property_add_bool(obj, "no-epmp-cfg", - &ot_earlgrey_machine_get_no_epmp_cfg, - &ot_earlgrey_machine_set_no_epmp_cfg); + object_property_add_bool(obj, "no-epmp-cfg", &ot_eg_machine_get_no_epmp_cfg, + &ot_eg_machine_set_no_epmp_cfg); object_property_set_description(obj, "no-epmp-cfg", "Skip default ePMP configuration"); } -static void ot_earlgrey_machine_init(MachineState *state) +static void ot_eg_machine_init(MachineState *state) { - DeviceState *dev = qdev_new(TYPE_RISCV_OT_EARLGREY_BOARD); + DeviceState *dev = qdev_new(TYPE_RISCV_OT_EG_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, void *data) +static void ot_eg_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); (void)data; mc->desc = "RISC-V Board compatible with OpenTitan EarlGrey FPGA platform"; - mc->init = ot_earlgrey_machine_init; + mc->init = ot_eg_machine_init; mc->max_cpus = 1u; - mc->default_cpu_type = - ot_earlgrey_soc_devices[OT_EARLGREY_SOC_DEV_HART].type; + mc->default_cpu_type = ot_eg_soc_devices[OT_EG_SOC_DEV_HART].type; const IbexDeviceDef *sram = - &ot_earlgrey_soc_devices[OT_EARLGREY_SOC_DEV_SRAM_MAIN_CTRL]; + &ot_eg_soc_devices[OT_EG_SOC_DEV_SRAM_MAIN_CTRL]; mc->default_ram_id = sram->type; mc->default_ram_size = sram->memmap[1].size; } -static const TypeInfo ot_earlgrey_machine_type_info = { - .name = TYPE_RISCV_OT_EARLGREY_MACHINE, +static const TypeInfo ot_eg_machine_type_info = { + .name = TYPE_RISCV_OT_EG_MACHINE, .parent = TYPE_MACHINE, - .instance_size = sizeof(OtEarlGreyMachineState), - .instance_init = &ot_earlgrey_machine_instance_init, - .class_init = &ot_earlgrey_machine_class_init, + .instance_size = sizeof(OtEGMachineState), + .instance_init = &ot_eg_machine_instance_init, + .class_init = &ot_eg_machine_class_init, }; -static void ot_earlgrey_machine_register_types(void) +static void ot_eg_machine_register_types(void) { - type_register_static(&ot_earlgrey_machine_type_info); + type_register_static(&ot_eg_machine_type_info); } -type_init(ot_earlgrey_machine_register_types); +type_init(ot_eg_machine_register_types); diff --git a/include/hw/riscv/ot_darjeeling.h b/include/hw/riscv/ot_darjeeling.h index 3e202e405896..f86840819dea 100644 --- a/include/hw/riscv/ot_darjeeling.h +++ b/include/hw/riscv/ot_darjeeling.h @@ -25,15 +25,13 @@ #include "qom/object.h" -#define TYPE_RISCV_OT_DARJEELING_MACHINE MACHINE_TYPE_NAME("ot-darjeeling") -OBJECT_DECLARE_SIMPLE_TYPE(OtDarjeelingMachineState, - RISCV_OT_DARJEELING_MACHINE) +#define TYPE_RISCV_OT_DJ_MACHINE MACHINE_TYPE_NAME("ot-darjeeling") +OBJECT_DECLARE_SIMPLE_TYPE(OtDjMachineState, RISCV_OT_DJ_MACHINE) -#define TYPE_RISCV_OT_DARJEELING_BOARD "riscv.ot_darjeeling.board" -OBJECT_DECLARE_SIMPLE_TYPE(OtDarjeelingBoardState, RISCV_OT_DARJEELING_BOARD) +#define TYPE_RISCV_OT_DJ_BOARD "riscv.ot_darjeeling.board" +OBJECT_DECLARE_SIMPLE_TYPE(OtDjBoardState, RISCV_OT_DJ_BOARD) -#define TYPE_RISCV_OT_DARJEELING_SOC "riscv.ot_darjeeling.soc" -OBJECT_DECLARE_TYPE(OtDarjeelingSoCState, OtDarjeelingSoCClass, - RISCV_OT_DARJEELING_SOC) +#define TYPE_RISCV_OT_DJ_SOC "riscv.ot_darjeeling.soc" +OBJECT_DECLARE_TYPE(OtDjSoCState, OtDjSoCClass, RISCV_OT_DJ_SOC) #endif /* HW_RISCV_OT_DARJEELING_H */ diff --git a/include/hw/riscv/ot_earlgrey.h b/include/hw/riscv/ot_earlgrey.h index 4c04a10bd83b..cb85abb36674 100644 --- a/include/hw/riscv/ot_earlgrey.h +++ b/include/hw/riscv/ot_earlgrey.h @@ -24,14 +24,13 @@ #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_EG_MACHINE MACHINE_TYPE_NAME("ot-earlgrey") +OBJECT_DECLARE_SIMPLE_TYPE(OtEGMachineState, RISCV_OT_EG_MACHINE) -#define TYPE_RISCV_OT_EARLGREY_BOARD "riscv.ot_earlgrey.board" -OBJECT_DECLARE_SIMPLE_TYPE(OtEarlGreyBoardState, RISCV_OT_EARLGREY_BOARD) +#define TYPE_RISCV_OT_EG_BOARD "riscv.ot_earlgrey.board" +OBJECT_DECLARE_SIMPLE_TYPE(OtEGBoardState, RISCV_OT_EG_BOARD) -#define TYPE_RISCV_OT_EARLGREY_SOC "riscv.ot_earlgrey.soc" -OBJECT_DECLARE_TYPE(OtEarlGreySoCState, OtEarlGreySoCClass, - RISCV_OT_EARLGREY_SOC) +#define TYPE_RISCV_OT_EG_SOC "riscv.ot_earlgrey.soc" +OBJECT_DECLARE_TYPE(OtEGSoCState, OtEGSoCClass, RISCV_OT_EG_SOC) #endif /* HW_RISCV_OT_EARLGREY_H */ From 5131defb5cf3969cffc4a204746b1f81a6d6f343 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 19:38:52 +0100 Subject: [PATCH 04/58] [ot] hw/opentitan: ot_ibex_wrapper: fix call to stop vCPU execution Also rework vCPU reference Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_ibex_wrapper_dj.c | 35 ++++++++++++++++--------------- hw/opentitan/ot_ibex_wrapper_eg.c | 34 ++++++++++++++++-------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/hw/opentitan/ot_ibex_wrapper_dj.c b/hw/opentitan/ot_ibex_wrapper_dj.c index 0544cc7ff3b3..48c8640b026e 100644 --- a/hw/opentitan/ot_ibex_wrapper_dj.c +++ b/hw/opentitan/ot_ibex_wrapper_dj.c @@ -709,6 +709,7 @@ struct OtIbexWrapperDjState { uint32_t *regs; OtIbexTestLogEngine *log_engine; + CPUState *cpu; uint8_t cpu_en_bm; bool entropy_requested; bool edn_connected; @@ -1267,24 +1268,16 @@ static void ot_ibex_wrapper_dj_cpu_enable_recv(void *opaque, int n, int level) trace_ot_ibex_wrapper_cpu_enable(s->ot_id ?: "", n ? "PWR" : "LC", (bool)level, s->cpu_en_bm, enable); - CPUState *cpu = ot_common_get_local_cpu(DEVICE(s)); - if (!cpu) { - error_setg(&error_fatal, "Could not find the vCPU to start!"); - g_assert_not_reached(); - } - - bool in_reset = cpu->held_in_reset; - if (enable) { - cpu->halted = 0; - if (in_reset) { - resettable_release_reset(OBJECT(cpu), RESET_TYPE_COLD); + s->cpu->halted = 0; + if (s->cpu->held_in_reset) { + resettable_release_reset(OBJECT(s->cpu), RESET_TYPE_COLD); } - cpu_resume(cpu); + cpu_resume(s->cpu); } else { - if (!cpu->halted) { - cpu->halted = 1; - cpu_loop_exit(cpu); + if (!s->cpu->halted) { + s->cpu->halted = 1; + cpu_exit(s->cpu); } } } @@ -1482,12 +1475,20 @@ static void ot_ibex_wrapper_dj_reset(DeviceState *dev) { OtIbexWrapperDjState *s = OT_IBEX_WRAPPER_DJ(dev); - g_assert(s->ot_id); - trace_ot_ibex_wrapper_reset(s->ot_id); + g_assert(s->ot_id); g_assert(s->sys_mem); + if (!s->cpu) { + CPUState *cpu = ot_common_get_local_cpu(DEVICE(s)); + if (!cpu) { + error_setg(&error_fatal, "Could not find the associated vCPU"); + g_assert_not_reached(); + } + s->cpu = cpu; + } + for (unsigned slot = 0; slot < PARAM_NUM_REGIONS; slot++) { ot_ibex_wrapper_dj_remapper_destroy(s, slot); } diff --git a/hw/opentitan/ot_ibex_wrapper_eg.c b/hw/opentitan/ot_ibex_wrapper_eg.c index 55febe22c834..64dcffcb7378 100644 --- a/hw/opentitan/ot_ibex_wrapper_eg.c +++ b/hw/opentitan/ot_ibex_wrapper_eg.c @@ -228,6 +228,7 @@ struct OtIbexWrapperEgState { uint32_t *regs; OtIbexTestLogEngine *log_engine; + CPUState *cpu; uint8_t cpu_en_bm; bool entropy_requested; bool edn_connected; @@ -726,24 +727,16 @@ static void ot_ibex_wrapper_eg_cpu_enable_recv(void *opaque, int n, int level) trace_ot_ibex_wrapper_cpu_enable(s->ot_id ?: "", n ? "PWR" : "LC", (bool)level, s->cpu_en_bm, enable); - CPUState *cpu = ot_common_get_local_cpu(DEVICE(s)); - if (!cpu) { - error_setg(&error_fatal, "Could not find the vCPU to start!"); - g_assert_not_reached(); - } - - bool in_reset = cpu->held_in_reset; - if (enable) { - cpu->halted = 0; - if (in_reset) { - resettable_release_reset(OBJECT(cpu), RESET_TYPE_COLD); + s->cpu->halted = 0; + if (s->cpu->held_in_reset) { + resettable_release_reset(OBJECT(s->cpu), RESET_TYPE_COLD); } - cpu_resume(cpu); + cpu_resume(s->cpu); } else { - if (!cpu->halted) { - cpu->halted = 1; - cpu_loop_exit(cpu); + if (!s->cpu->halted) { + s->cpu->halted = 1; + cpu_exit(s->cpu); } } } @@ -935,12 +928,21 @@ static void ot_ibex_wrapper_eg_reset(DeviceState *dev) { OtIbexWrapperEgState *s = OT_IBEX_WRAPPER_EG(dev); - g_assert(s->ot_id); trace_ot_ibex_wrapper_reset(s->ot_id); + g_assert(s->ot_id); g_assert(s->edn); g_assert(s->edn_ep != UINT8_MAX); + if (!s->cpu) { + CPUState *cpu = ot_common_get_local_cpu(DEVICE(s)); + if (!cpu) { + error_setg(&error_fatal, "Could not find the associated vCPU"); + g_assert_not_reached(); + } + s->cpu = cpu; + } + for (unsigned slot = 0; slot < PARAM_NUM_REGIONS; slot++) { ot_ibex_wrapper_eg_remapper_destroy(s, slot); } From d724b31b46814ce2e640628ad98a54e89a9c7335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Wed, 14 Feb 2024 15:42:56 +0100 Subject: [PATCH 05/58] [ot] hw/opentitan: flash: don't exit QEMU on flash disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- hw/opentitan/ot_flash.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hw/opentitan/ot_flash.c b/hw/opentitan/ot_flash.c index c320a16c5643..0bae1b299a75 100644 --- a/hw/opentitan/ot_flash.c +++ b/hw/opentitan/ot_flash.c @@ -52,9 +52,6 @@ #include "sysemu/block-backend.h" #include "trace.h" -/* set to abort QEMU whenever guest code disable flash access */ -#define ABORT_ON_DISABLEMENT 1 - /* set to use I/O to access the flash partition */ #define DATA_PART_USE_IO_OPS 0 @@ -1059,14 +1056,10 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64, val32 &= R_DIS_VAL_MASK; s->regs[reg] = ot_multibitbool_w1s_write(s->regs[reg], val32, 4u); if (ot_flash_is_disabled(s)) { -#if ABORT_ON_DISABLEMENT - error_setg(&error_fatal, "flash controller disabled by SW"); -#else xtrace_ot_flash_error("flash controller disabled by SW"); memory_region_set_enabled(&s->mmio.mem, false); memory_region_set_enabled(&s->mmio.csrs, false); memory_region_set_enabled(&s->mmio.regs, false); -#endif } break; case R_INIT: From b4197b0fa4de0a914db92bd46edf288066f7bd64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Wed, 14 Feb 2024 15:43:42 +0100 Subject: [PATCH 06/58] [ot] hw/riscv: ot-earlgrey: connect lc_ctrl and pwrmgr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- hw/riscv/ot_earlgrey.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index 8772f8149e63..4392bc4f4a6a 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -203,6 +203,15 @@ static const uint32_t ot_eg_pmp_addrs[] = { } \ } +/* Request link */ +#define OT_EG_SOC_REQ(_req_, _tgt_) \ + OT_EG_SOC_SIGNAL(_req_##_REQ, 0, _tgt_, _req_##_REQ, 0) + +/* Response link */ +#define OT_EG_SOC_RSP(_rsp_, _tgt_) \ + OT_EG_SOC_SIGNAL(_rsp_##_RSP, 0, _tgt_, _rsp_##_RSP, 0) + + #define OT_EG_SOC_CLKMGR_HINT(_num_) \ OT_EG_SOC_SIGNAL(OT_CLOCK_ACTIVE, 0, CLKMGR, OT_CLKMGR_HINT, _num_) @@ -457,6 +466,9 @@ static const IbexDeviceDef ot_eg_soc_devices[] = { .memmap = MEMMAPENTRIES( { 0x40140000u, 0x100u } ), + .gpio = IBEXGPIOCONNDEFS( + OT_EG_SOC_RSP(OT_PWRMGR_LC, PWRMGR) + ), .link = IBEXDEVICELINKDEFS( OT_EG_SOC_DEVLINK("otp_ctrl", OTP_CTRL), OT_EG_SOC_DEVLINK("kmac", KMAC) @@ -536,9 +548,7 @@ static const IbexDeviceDef ot_eg_soc_devices[] = { /* loopback signal since Earlgrey OTP signal are not supported yet*/ OT_EG_SOC_SIGNAL(OT_PWRMGR_OTP_REQ, 0, PWRMGR, OT_PWRMGR_OTP_RSP, 0), - /* loopback signal since Earlgrey OTP signal are not supported yet*/ - OT_EG_SOC_SIGNAL(OT_PWRMGR_LC_REQ, 0, PWRMGR, - OT_PWRMGR_LC_RSP, 0), + OT_EG_SOC_REQ(OT_PWRMGR_LC, LC_CTRL), OT_EG_SOC_SIGNAL(OT_PWRMGR_CPU_EN, 0, IBEX_WRAPPER, OT_IBEX_WRAPPER_CPU_EN, OT_IBEX_PWRMGR_CPU_EN) From 136ee0d63f07ded487bfcba4f9c48d6abb01d5c2 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 15 Feb 2024 18:10:45 +0100 Subject: [PATCH 07/58] [ot] hw/opentitan: ot_flash: fix invalid trace source Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_flash.c | 2 +- hw/opentitan/trace-events | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/opentitan/ot_flash.c b/hw/opentitan/ot_flash.c index 0bae1b299a75..f8787a11581b 100644 --- a/hw/opentitan/ot_flash.c +++ b/hw/opentitan/ot_flash.c @@ -669,7 +669,7 @@ struct OtFlashState { static void ot_flash_update_irqs(OtFlashState *s) { uint32_t level = s->regs[R_INTR_STATE] & s->regs[R_INTR_ENABLE]; - trace_ot_csrng_irqs(s->regs[R_INTR_STATE], s->regs[R_INTR_ENABLE], level); + trace_ot_flash_irqs(s->regs[R_INTR_STATE], s->regs[R_INTR_ENABLE], level); for (unsigned ix = 0; ix < PARAM_NUM_IRQS; ix++) { ibex_irq_set(&s->irqs[ix], (int)((level >> ix) & 0x1u)); } diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index ad32243f1060..92c0403a3d18 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -152,6 +152,7 @@ ot_flash_op_complete(int op, bool success) "%d: %u" ot_flash_error(const char *func, int line, const char *err) "%s:%d %s" ot_flash_info(const char *func, int line, const char *msg, uint32_t value) "%s:%d %s: 0x%08x" ot_flash_info_part(uint32_t op_addr, unsigned bank, unsigned infosel, uint32_t addr) "op_addr 0x%06x bank %u infosel %u addr 0x%06x" +ot_flash_irqs(uint32_t active, uint32_t mask, uint32_t eff) "act:0x%08x msk:0x%08x eff:0x%08x" # ot_gpio.c From cc0cf39448ea82f3de95e89b68d849993b9083ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Wed, 14 Feb 2024 14:29:33 +0100 Subject: [PATCH 08/58] [ot] hw/opentitan: ot_csrng: remove command processing delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- hw/opentitan/ot_csrng.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/hw/opentitan/ot_csrng.c b/hw/opentitan/ot_csrng.c index 675581e1e9e3..d582f0aaa46e 100644 --- a/hw/opentitan/ot_csrng.c +++ b/hw/opentitan/ot_csrng.c @@ -210,13 +210,6 @@ static_assert(OT_CSRNG_AES_BLOCK_SIZE + OT_CSRNG_AES_KEY_SIZE == #define SW_INSTANCE_ID OT_CSRNG_HW_APP_MAX -#define CMD_EXECUTE_DELAY_NS 500000u /* 500 us */ - -#define MAX_GENERATION_DELAY_NS 700000000u /* 0.7 s */ -#define MAX_GENERATION_COUNT 4096u -/* no need for rounding up, as processing takes time anyway */ -#define PACKET_GENERATION_DELAY_NS \ - (MAX_GENERATION_DELAY_NS / MAX_GENERATION_COUNT) #define ENTROPY_SRC_INITIAL_REQUEST_COUNT 5u enum { @@ -293,7 +286,7 @@ struct OtCSRNGState { IbexIRQ irqs[PARAM_NUM_IRQS]; IbexIRQ alerts[PARAM_NUM_ALERTS]; qemu_irq entropy_state; - QEMUTimer *cmd_scheduler; + QEMUBH *cmd_scheduler; uint32_t *regs; bool enabled; @@ -441,7 +434,7 @@ int ot_csrng_push_command(OtCSRNGState *s, unsigned app_id, cmd_request); if (QSIMPLEQ_EMPTY(&s->cmd_requests)) { - timer_del(s->cmd_scheduler); + qemu_bh_cancel(s->cmd_scheduler); } } } @@ -818,7 +811,7 @@ static bool ot_csrng_expedite_uninstantiation(OtCSRNGInstance *inst) QSIMPLEQ_REMOVE(&s->cmd_requests, inst, OtCSRNGInstance, cmd_request); if (QSIMPLEQ_EMPTY(&s->cmd_requests)) { - timer_del(s->cmd_scheduler); + qemu_bh_cancel(s->cmd_scheduler); } trace_ot_csrng_instanciate(slot, false); @@ -891,7 +884,7 @@ static void ot_csrng_handle_enable(OtCSRNGState *s) xtrace_ot_csrng_info("disable: last RS generation", s->entropy_gennum); /* cancel any outstanding asynchronous request */ - timer_del(s->cmd_scheduler); + qemu_bh_cancel(s->cmd_scheduler); /* discard any on-going command request */ OtCSRNGInstance *inst, *next; @@ -1376,14 +1369,8 @@ static void ot_csrng_command_schedule(OtCSRNGState *s, OtCSRNGInstance *inst) QSIMPLEQ_INSERT_TAIL(&s->cmd_requests, inst, cmd_request); - if (timer_pending(s->cmd_scheduler)) { - xtrace_ot_csrng_info("command scheduler already active", 0); - return; - } - trace_ot_csrng_schedule(ot_csrng_get_slot(inst), "command"); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - timer_mod(s->cmd_scheduler, (int64_t)(now + CMD_EXECUTE_DELAY_NS)); + qemu_bh_schedule(s->cmd_scheduler); } static void ot_csrng_command_scheduler(void *opaque) @@ -1465,8 +1452,7 @@ static void ot_csrng_command_scheduler(void *opaque) if (!QSIMPLEQ_EMPTY(&s->cmd_requests)) { if (s->state != CSRNG_ERROR) { xtrace_ot_csrng_info("scheduling new command", 0); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - timer_mod(s->cmd_scheduler, (int64_t)(now + CMD_EXECUTE_DELAY_NS)); + qemu_bh_schedule(s->cmd_scheduler); } else { xtrace_ot_csrng_error("cannot schedule new command on error"); } @@ -1768,7 +1754,7 @@ static void ot_csrng_reset(DeviceState *dev) OBJECT_CHECK(OtRandomSrcIf, s->random_src, TYPE_OT_RANDOM_SRC_IF); g_assert(s->otp_ctrl); - timer_del(s->cmd_scheduler); + qemu_bh_cancel(s->cmd_scheduler); memset(s->regs, 0, REGS_SIZE); @@ -1845,8 +1831,7 @@ static void ot_csrng_init(Object *obj) /* current instance is the SW instance */ ot_fifo32_create(&inst->sw.bits_fifo, OT_CSRNG_PACKET_WORD_COUNT); - s->cmd_scheduler = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_csrng_command_scheduler, s); + s->cmd_scheduler = qemu_bh_new(&ot_csrng_command_scheduler, s); QSIMPLEQ_INIT(&s->cmd_requests); } From ea9d7f4f84813f126c2059b7e09facefb6b4028a Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 15 Feb 2024 19:30:55 +0100 Subject: [PATCH 09/58] [ot] hw/opentitan: ot_csrng: fix a race condition Generation command could be scheduled by a HW app, i.e. an EDN instance while Instantiation has not yet been completed, as the CSRNG command response of a Generate request was interpreted by the EDN as the completion of the Instantiate command. Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_csrng.c | 65 ++++++++++++++++++++++++++------------- hw/opentitan/trace-events | 6 +++- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/hw/opentitan/ot_csrng.c b/hw/opentitan/ot_csrng.c index d582f0aaa46e..779cb1a56d47 100644 --- a/hw/opentitan/ot_csrng.c +++ b/hw/opentitan/ot_csrng.c @@ -253,6 +253,7 @@ typedef struct { unsigned reseed_counter; unsigned rem_packet_count; /* remaining packets to generate */ bool instantiated; + bool seeded; /* ready to generate randomness */ bool fips; } OtCSRNGDrng; @@ -285,7 +286,6 @@ struct OtCSRNGState { MemoryRegion mmio; IbexIRQ irqs[PARAM_NUM_IRQS]; IbexIRQ alerts[PARAM_NUM_ALERTS]; - qemu_irq entropy_state; QEMUBH *cmd_scheduler; uint32_t *regs; @@ -528,7 +528,7 @@ static void ot_csrng_drng_increment(OtCSRNGDrng *drng) } } -static OtCSRNDCmdResult ot_csrng_drng_instanciate( +static OtCSRNDCmdResult ot_csrng_drng_instantiate( OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) { OtCSRNGDrng *drng = &inst->drng; @@ -553,6 +553,17 @@ static OtCSRNDCmdResult ot_csrng_drng_instanciate( res = ot_csrng_drng_reseed(inst, rand_dev, flag0); if (res) { drng->instantiated = false; + return res; + } + + if (inst->hw.genbits_ready) { + /* + * a HW client app of this instance has already requested randomness + * through #ot_csrng_hwapp_ready_irq. This request had been deferred + * till the instanciation stage has completed, it is now safe to + * schedule the actual generation + */ + qemu_bh_schedule(inst->hw.filler_bh); } return res; @@ -567,6 +578,7 @@ static void ot_csrng_drng_uninstantiate(OtCSRNGInstance *inst) } drng->instantiated = false; + drng->seeded = false; drng->fips = false; drng->rem_packet_count = 0; @@ -574,7 +586,7 @@ static void ot_csrng_drng_uninstantiate(OtCSRNGInstance *inst) memset(drng->v_counter, 0, sizeof(drng->v_counter)); } -static int ot_csrng_drng_update(OtCSRNGInstance *inst) +static void ot_csrng_drng_update(OtCSRNGInstance *inst) { OtCSRNGDrng *drng = &inst->drng; @@ -620,8 +632,6 @@ static int ot_csrng_drng_update(OtCSRNGInstance *inst) OT_CSRNG_AES_KEY_SIZE); xtrace_ot_csrng_show_buffer(appid, "n-V", drng->v_counter, OT_CSRNG_AES_BLOCK_SIZE); - - return 0; } static OtCSRNDCmdResult @@ -630,6 +640,8 @@ ot_csrng_drng_reseed(OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) OtCSRNGDrng *drng = &inst->drng; g_assert(drng->instantiated); + drng->seeded = false; + if (!flag0) { if (!inst->parent->es_available) { qemu_log_mask(LOG_GUEST_ERROR, @@ -647,13 +659,16 @@ ot_csrng_drng_reseed(OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) uint64_t entropy[OT_RANDOM_SRC_DWORD_COUNT]; int res; bool fips; - xtrace_ot_csrng_info("request ES entropy w/ generation", - s->entropy_gennum); - + trace_ot_csrng_request_entropy(ot_csrng_get_slot(inst), + s->entropy_gennum); OtRandomSrcIfClass *cls = OT_RANDOM_SRC_IF_GET_CLASS(rand_dev); OtRandomSrcIf *randif = OT_RANDOM_SRC_IF(rand_dev); res = cls->get_random_values(randif, s->entropy_gennum, entropy, &fips); if (res) { + trace_ot_csrng_entropy_rejected(ot_csrng_get_slot(inst), + res < 0 ? (res == -2 ? "stalled" : + "error") : + "not ready"); return res < 0 ? (res == -2 ? CSRNG_CMD_STALLED : CSRNG_CMD_ERROR) : CSRNG_CMD_RETRY; } @@ -672,6 +687,8 @@ ot_csrng_drng_reseed(OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) drng->reseed_counter = 1u; + drng->seeded = true; + return CSRNG_CMD_OK; } @@ -792,7 +809,7 @@ static bool ot_csrng_is_in_queue(OtCSRNGInstance *inst) static bool ot_csrng_expedite_uninstantiation(OtCSRNGInstance *inst) { - /* check if the instance has been flagged for uninstanciation */ + /* check if the instance has been flagged for uninstantiation */ if (ot_fifo32_is_empty(&inst->cmd_fifo)) { return false; } @@ -814,7 +831,7 @@ static bool ot_csrng_expedite_uninstantiation(OtCSRNGInstance *inst) qemu_bh_cancel(s->cmd_scheduler); } - trace_ot_csrng_instanciate(slot, false); + trace_ot_csrng_instantiate(slot, false); ot_csrng_drng_uninstantiate(inst); ot_csrng_complete_command(inst, 0); @@ -994,7 +1011,7 @@ ot_csrng_handle_instantiate(OtCSRNGState *s, unsigned slot) { OtCSRNGInstance *inst = &s->instances[slot]; - trace_ot_csrng_instanciate(slot, true); + trace_ot_csrng_instantiate(slot, true); uint32_t command = ot_fifo32_peek(&inst->cmd_fifo); uint32_t clen = FIELD_EX32(command, OT_CSNRG_CMD, CLEN); @@ -1018,7 +1035,7 @@ ot_csrng_handle_instantiate(OtCSRNGState *s, unsigned slot) int res; - res = ot_csrng_drng_instanciate(inst, s->random_src, flag0); + res = ot_csrng_drng_instantiate(inst, s->random_src, flag0); if ((res == CSRNG_CMD_OK) && !flag0) { /* if flag0 is set, entropy source is not used for reseeding */ s->regs[R_INTR_STATE] |= INTR_CS_ENTROPY_REQ_MASK; @@ -1033,7 +1050,7 @@ ot_csrng_handle_uninstantiate(OtCSRNGState *s, unsigned slot) { OtCSRNGInstance *inst = &s->instances[slot]; - trace_ot_csrng_instanciate(slot, false); + trace_ot_csrng_instantiate(slot, false); ot_csrng_drng_uninstantiate(inst); @@ -1169,7 +1186,15 @@ static void ot_csrng_hwapp_ready_irq(void *opaque, int n, int level) ot_csrng_drng_remaining_count(inst)); if (ready) { - qemu_bh_schedule(inst->hw.filler_bh); + if (!inst->drng.seeded) { + /* + * instanciation has not completed yet, wait for generation. + * see #ot_csrng_drng_instanciate + */ + trace_ot_csrng_defer_generation(slot); + } else { + qemu_bh_schedule(inst->hw.filler_bh); + } } } @@ -1211,8 +1236,6 @@ static void ot_csrng_hwapp_filler_bh(void *opaque) * its readiness status (only generate commands complete async.) */ if (!ot_csrng_drng_remaining_count(inst)) { - unsigned slot = ot_csrng_get_slot(inst); - xtrace_ot_csrng_info("complete deferred generation", slot); ot_csrng_complete_command(inst, 0); } } @@ -1237,8 +1260,6 @@ static void ot_csrng_swapp_fill(OtCSRNGInstance *inst) } else { /* check if the instance is running an deferred completion command */ if (inst->defer_completion) { - unsigned slot = ot_csrng_get_slot(inst); - xtrace_ot_csrng_info("complete deferred generation", slot); ot_csrng_complete_command(inst, 0); } } @@ -1361,7 +1382,9 @@ static void ot_csrng_command_schedule(OtCSRNGState *s, OtCSRNGInstance *inst) { bool queued = ot_csrng_is_in_queue(inst); if (queued) { - xtrace_ot_csrng_error("instance executing several commands at once"); + /* execution resumes, but this is likely internal bug...*/ + error_report("%s: instance executing several commands at once", + __func__); s->regs[R_INTR_STATE] |= INTR_CS_HW_INST_EXC_MASK; ot_csrng_update_irqs(s); return; @@ -1451,7 +1474,7 @@ static void ot_csrng_command_scheduler(void *opaque) if (!QSIMPLEQ_EMPTY(&s->cmd_requests)) { if (s->state != CSRNG_ERROR) { - xtrace_ot_csrng_info("scheduling new command", 0); + trace_ot_csrng_scheduling_command(slot); qemu_bh_schedule(s->cmd_scheduler); } else { xtrace_ot_csrng_error("cannot schedule new command on error"); @@ -1802,7 +1825,7 @@ static void ot_csrng_init(Object *obj) /* aes_desc is defined in libtomcrypt */ s->aes_cipher = register_cipher(&aes_desc); if (s->aes_cipher < 0) { - error_report("OpenTitan AES: Unable to use libtomcrypt AES API"); + error_report("%s: unable to use libtomcrypt AES API", __func__); } s->regs = g_new0(uint32_t, REGS_COUNT); diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 92c0403a3d18..02f4d6b0f22c 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -44,8 +44,10 @@ ot_csrng_change_state(int line, const char *old, int nold, const char *new, int ot_csrng_command_scheduler(unsigned slot, const char *action) "#%u: %s" ot_csrng_complete_command(unsigned slot, const char *kind, const char *cmd, unsigned acmd, int res) "#%u (%s) acmd: %s(%u): %d" ot_csrng_connection(unsigned slot) "#%u" +ot_csrng_defer_generation(unsigned slot) "#%u instanciation not yet completed" ot_csrng_end_of_gen(unsigned slot, unsigned rempack) "#%u rem %u" ot_csrng_entropy_injecter(unsigned slot, const char *action) "#%u: %s" +ot_csrng_entropy_rejected(unsigned slot, const char *reason) "#%u: %s" ot_csrng_error(const char *func, int line, const char *err) "%s:%d %s" ot_csrng_expedite_uninstantiation(unsigned slot) "#%u" ot_csrng_fill_entropy(unsigned slot, bool fips) "#%u fips %u" @@ -53,15 +55,17 @@ ot_csrng_generate(unsigned slot, unsigned count) "#%u %u packets to generate" ot_csrng_hwapp_need_entropy(unsigned slot, const char *msg) "#%u: %s" ot_csrng_hwapp_ready(unsigned slot, bool ready, unsigned rem) "#%u: %u rem %u" ot_csrng_info(const char *func, int line, const char *msg, uint32_t value) "%s:%d %s: 0x%08x" -ot_csrng_instanciate(unsigned slot, bool on) "#%u: %u" +ot_csrng_instantiate(unsigned slot, bool on) "#%u: %u" ot_csrng_invalid_state(const char *func, const char *state, int st) "%s [%s:%d]" ot_csrng_io_read_out(uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_csrng_io_write(uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_csrng_irqs(uint32_t active, uint32_t mask, uint32_t eff) "act:0x%08x msk:0x%08x eff:0x%08x" ot_csrng_push_command(unsigned slot, const char *cmd, unsigned acmd, char code, unsigned len) "#%u: %s(%u) %clen: %u" ot_csrng_read_state_db(unsigned slot, unsigned pos, uint32_t val) "#%u [%u] = 0x%08x" +ot_csrng_request_entropy(unsigned slot, int gen) "#%u gen %d" ot_csrng_retry_es_init(unsigned retry_count) "rescheduling initial ES request: %u to go" ot_csrng_schedule(unsigned slot, const char *kind) "#%u: %s" +ot_csrng_scheduling_command(unsigned slot) "#%u" ot_csrng_show_buffer(const char *func, int line, unsigned appid, const char *msg, const char *hexstr) "%s:%u #%u %s: %s" ot_csrng_show_command(const char *msg, unsigned slot, const char *cmd, unsigned acmd) "%s slot #%u, acmd: %s(%u)" ot_csrng_swapp_fill(unsigned count) "%u to go" From fe2d7c9d08d52c812bf79809afb0b6f884d9f2ed Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 16 Feb 2024 16:04:10 +0100 Subject: [PATCH 10/58] [ot] hw/opentitan: ot_csrng: add wait time hints from entropy source. The entropy source can give wait time hints to the CSRNG so that the latter does not uselessly poll the former while it is initializing. Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_csrng.c | 58 +++++++++++++++++++--------- hw/opentitan/trace-events | 3 +- include/hw/opentitan/ot_random_src.h | 2 + 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/hw/opentitan/ot_csrng.c b/hw/opentitan/ot_csrng.c index 779cb1a56d47..78b8124c977d 100644 --- a/hw/opentitan/ot_csrng.c +++ b/hw/opentitan/ot_csrng.c @@ -221,7 +221,7 @@ typedef enum { CSRNG_CMD_STALLED = -2, /* entropy stack is stalled */ CSRNG_CMD_ERROR = -1, /* command error, not recoverable */ CSRNG_CMD_OK = 0, /* command completed ok */ - CSRNG_CMD_RETRY = 1, /* command cannot be executed at the moment */ + CSRNG_CMD_RETRY = 1, /* command cannot be executed for now */ CSRNG_CMD_DEFERRED = 2, /* command completion deferred */ } OtCSRNDCmdResult; @@ -287,6 +287,7 @@ struct OtCSRNGState { IbexIRQ irqs[PARAM_NUM_IRQS]; IbexIRQ alerts[PARAM_NUM_ALERTS]; QEMUBH *cmd_scheduler; + QEMUTimer *entropy_scheduler; uint32_t *regs; bool enabled; @@ -294,6 +295,7 @@ struct OtCSRNGState { bool read_int_granted; bool es_available; uint32_t scheduled_cmd; + unsigned entropy_delay; unsigned es_retry_count; unsigned state_db_ix; int entropy_gennum; @@ -435,6 +437,7 @@ int ot_csrng_push_command(OtCSRNGState *s, unsigned app_id, if (QSIMPLEQ_EMPTY(&s->cmd_requests)) { qemu_bh_cancel(s->cmd_scheduler); + timer_del(s->entropy_scheduler); } } } @@ -665,10 +668,12 @@ ot_csrng_drng_reseed(OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) OtRandomSrcIf *randif = OT_RANDOM_SRC_IF(rand_dev); res = cls->get_random_values(randif, s->entropy_gennum, entropy, &fips); if (res) { + s->entropy_delay = (res > 1) ? (unsigned)res : 0; trace_ot_csrng_entropy_rejected(ot_csrng_get_slot(inst), res < 0 ? (res == -2 ? "stalled" : "error") : - "not ready"); + "not ready", + res); return res < 0 ? (res == -2 ? CSRNG_CMD_STALLED : CSRNG_CMD_ERROR) : CSRNG_CMD_RETRY; } @@ -829,6 +834,7 @@ static bool ot_csrng_expedite_uninstantiation(OtCSRNGInstance *inst) if (QSIMPLEQ_EMPTY(&s->cmd_requests)) { qemu_bh_cancel(s->cmd_scheduler); + timer_del(s->entropy_scheduler); } trace_ot_csrng_instantiate(slot, false); @@ -845,7 +851,6 @@ static void ot_csrng_handle_enable(OtCSRNGState *s) * "CSRNG may only be enabled if ENTROPY_SRC is enabled. CSRNG may only be * disabled if all EDNs are disabled. Once disabled, CSRNG may only be * re-enabled after ENTROPY_SRC has been disabled and re-enabled." - * ... */ OtRandomSrcIfClass *cls = OT_RANDOM_SRC_IF_GET_CLASS(s->random_src); OtRandomSrcIf *randif = OT_RANDOM_SRC_IF(s->random_src); @@ -853,25 +858,26 @@ static void ot_csrng_handle_enable(OtCSRNGState *s) if (ot_csrng_is_ctrl_enabled(s)) { xtrace_ot_csrng_info("enabling CSRNG", 0); int gennum = cls->get_random_generation(randif); - /* - * ... however it is not re-enabling CSRNG w/o cycling the entropy_src - * that is prohibited, but to request entropy from it. The check is - * therefore deferred to the reseed handling which makes use of the - * entropy_src only if flag0 is not set. - */ if (gennum >= 0) { + /* + * however it is not re-enabling CSRNG w/o cycling the entropy_src + * that is prohibited, but to request entropy from it. The check is + * therefore deferred to the reseed handling which makes use of the + * entropy_src only if flag0 is not set. + */ s->es_available = gennum > s->entropy_gennum; - s->enabled = true; - s->es_retry_count = ENTROPY_SRC_INITIAL_REQUEST_COUNT; - s->entropy_gennum = gennum; - xtrace_ot_csrng_info("enable: new RS generation", gennum); + xtrace_ot_csrng_info("enable: new ES generation", gennum); } else { + /* + * tracking enablement/disablement order is not supported by the + * entropy source (such as on Darjeeling) + */ s->es_available = true; - s->enabled = true; - s->es_retry_count = ENTROPY_SRC_INITIAL_REQUEST_COUNT; - s->entropy_gennum = gennum; - xtrace_ot_csrng_info("enable: unique RS generation", gennum); + xtrace_ot_csrng_info("enable: no ES gen tracking", gennum); } + s->enabled = true; + s->es_retry_count = ENTROPY_SRC_INITIAL_REQUEST_COUNT; + s->entropy_gennum = gennum; } if (ot_csrng_is_ctrl_disabled(s)) { @@ -902,6 +908,7 @@ static void ot_csrng_handle_enable(OtCSRNGState *s) /* cancel any outstanding asynchronous request */ qemu_bh_cancel(s->cmd_scheduler); + timer_del(s->entropy_scheduler); /* discard any on-going command request */ OtCSRNGInstance *inst, *next; @@ -1393,6 +1400,7 @@ static void ot_csrng_command_schedule(OtCSRNGState *s, OtCSRNGInstance *inst) QSIMPLEQ_INSERT_TAIL(&s->cmd_requests, inst, cmd_request); trace_ot_csrng_schedule(ot_csrng_get_slot(inst), "command"); + timer_del(s->entropy_scheduler); qemu_bh_schedule(s->cmd_scheduler); } @@ -1475,7 +1483,14 @@ static void ot_csrng_command_scheduler(void *opaque) if (!QSIMPLEQ_EMPTY(&s->cmd_requests)) { if (s->state != CSRNG_ERROR) { trace_ot_csrng_scheduling_command(slot); - qemu_bh_schedule(s->cmd_scheduler); + if (CSRNG_CMD_RETRY == res && s->entropy_delay) { + timer_mod(s->entropy_scheduler, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) + + (int64_t)s->entropy_delay); + s->entropy_delay = 0; + } else { + qemu_bh_schedule(s->cmd_scheduler); + } } else { xtrace_ot_csrng_error("cannot schedule new command on error"); } @@ -1773,11 +1788,14 @@ static void ot_csrng_reset(DeviceState *dev) { OtCSRNGState *s = OT_CSRNG(dev); + trace_ot_csrng_reset(); + g_assert(s->random_src); OBJECT_CHECK(OtRandomSrcIf, s->random_src, TYPE_OT_RANDOM_SRC_IF); g_assert(s->otp_ctrl); - qemu_bh_cancel(s->cmd_scheduler); + timer_del(s->entropy_scheduler); + s->entropy_delay = 0; memset(s->regs, 0, REGS_SIZE); @@ -1855,6 +1873,8 @@ static void ot_csrng_init(Object *obj) ot_fifo32_create(&inst->sw.bits_fifo, OT_CSRNG_PACKET_WORD_COUNT); s->cmd_scheduler = qemu_bh_new(&ot_csrng_command_scheduler, s); + s->entropy_scheduler = + timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_csrng_command_scheduler, s); QSIMPLEQ_INIT(&s->cmd_requests); } diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 02f4d6b0f22c..66c209f86dc4 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -47,7 +47,7 @@ ot_csrng_connection(unsigned slot) "#%u" ot_csrng_defer_generation(unsigned slot) "#%u instanciation not yet completed" ot_csrng_end_of_gen(unsigned slot, unsigned rempack) "#%u rem %u" ot_csrng_entropy_injecter(unsigned slot, const char *action) "#%u: %s" -ot_csrng_entropy_rejected(unsigned slot, const char *reason) "#%u: %s" +ot_csrng_entropy_rejected(unsigned slot, const char *reason, int res) "#%u: %s (%d)" ot_csrng_error(const char *func, int line, const char *err) "%s:%d %s" ot_csrng_expedite_uninstantiation(unsigned slot) "#%u" ot_csrng_fill_entropy(unsigned slot, bool fips) "#%u fips %u" @@ -64,6 +64,7 @@ ot_csrng_push_command(unsigned slot, const char *cmd, unsigned acmd, char code, ot_csrng_read_state_db(unsigned slot, unsigned pos, uint32_t val) "#%u [%u] = 0x%08x" ot_csrng_request_entropy(unsigned slot, int gen) "#%u gen %d" ot_csrng_retry_es_init(unsigned retry_count) "rescheduling initial ES request: %u to go" +ot_csrng_reset(void) "" ot_csrng_schedule(unsigned slot, const char *kind) "#%u: %s" ot_csrng_scheduling_command(unsigned slot) "#%u" ot_csrng_show_buffer(const char *func, int line, unsigned appid, const char *msg, const char *hexstr) "%s:%u #%u %s: %s" diff --git a/include/hw/opentitan/ot_random_src.h b/include/hw/opentitan/ot_random_src.h index 86da50834558..7313130b5e8d 100644 --- a/include/hw/opentitan/ot_random_src.h +++ b/include/hw/opentitan/ot_random_src.h @@ -71,6 +71,8 @@ struct OtRandomSrcIfClass { * @random the buffer to fill in with random data * @fips on success, updated to @true if random data are FIPS-compliant * @return 0 on success, + * >=1 if the source is initializing, if >1, indicates the hint on + * how many ns to wait before retrying, * -1 if the random source is not available, i.e. if the module is * not enabled or if the selected route is not the HW one, * -2 if the generation ID does not match and execution cannot From ab05081ac66f314155273418ff951d96aa7dd76e Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 16 Feb 2024 16:08:31 +0100 Subject: [PATCH 11/58] [ot] hw/opentitan: ot_ast_dj: implement entropy source time hinting Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_ast_dj.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/opentitan/ot_ast_dj.c b/hw/opentitan/ot_ast_dj.c index 47df01e29bca..8ba446fdb0c2 100644 --- a/hw/opentitan/ot_ast_dj.c +++ b/hw/opentitan/ot_ast_dj.c @@ -175,8 +175,17 @@ static int ot_ast_dj_get_random(OtRandomSrcIf *dev, int genid, } if (!rnd->avail) { + /* not ready */ trace_ot_ast_no_entropy(0); - return 1; + int wait_ns; + if (timer_pending(s->random.timer)) { + wait_ns = 1; + } else { + /* computed delay fits into a 31-bit value */ + wait_ns = (int)(timer_expire_time_ns(s->random.timer) - + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT)); + } + return wait_ns; } memcpy(random, rnd->buffer, OT_RANDOM_SRC_DWORD_COUNT * sizeof(uint64_t)); @@ -185,7 +194,7 @@ static int ot_ast_dj_get_random(OtRandomSrcIf *dev, int genid, /* note: fips compliancy is only simulated here for now */ *fips = true; - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); timer_mod(rnd->timer, (int64_t)(now + OT_AST_DJ_RANDOM_FILL_RATE_NS)); return 0; @@ -403,7 +412,7 @@ static void ot_ast_dj_reset(DeviceState *dev) s->regsa[R_REGA37] = 0x25u; s->regsa[R_REGAL] = 0x26u; - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); timer_mod(rnd->timer, (int64_t)(now + OT_AST_DJ_RANDOM_FILL_RATE_NS)); } @@ -421,7 +430,7 @@ static void ot_ast_dj_init(Object *obj) OtASTDjRandom *rnd = &s->random; rnd->timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_ast_dj_random_scheduler, s); + timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_ast_dj_random_scheduler, s); rnd->buffer = g_new0(uint64_t, OT_RANDOM_SRC_DWORD_COUNT); } From d4896f7813bc8d3697042ff4fd1432e9f4991843 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 16 Feb 2024 16:11:31 +0100 Subject: [PATCH 12/58] [ot] hw/opentitan: ot_entropy_src: implement entropy source time hinting Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_entropy_src.c | 25 +++++++++++++++++++------ hw/opentitan/trace-events | 3 ++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/hw/opentitan/ot_entropy_src.c b/hw/opentitan/ot_entropy_src.c index ed59fd9eaf7a..4a2650d9306a 100644 --- a/hw/opentitan/ot_entropy_src.c +++ b/hw/opentitan/ot_entropy_src.c @@ -502,9 +502,20 @@ static int ot_entropy_src_get_random(OtRandomSrcIf *dev, int genid, case ENTROPY_SRC_STARTUP_HT_START: case ENTROPY_SRC_STARTUP_PHASE1: case ENTROPY_SRC_STARTUP_PASS1: - case ENTROPY_SRC_STARTUP_FAIL1: - trace_ot_entropy_src_init_ongoing(STATE_NAME(s->state), s->state); - return 1; /* not ready */ + case ENTROPY_SRC_STARTUP_FAIL1: { + int wait_ns; + if (timer_pending(s->scheduler)) { + wait_ns = 1; + } else { + /* computed delay fits into a 31-bit value */ + wait_ns = (int)(timer_expire_time_ns(s->scheduler) - + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT)); + } + trace_ot_entropy_src_init_ongoing(STATE_NAME(s->state), s->state, + wait_ns); + /* not ready */ + return wait_ns; + } case ENTROPY_SRC_IDLE: qemu_log_mask(LOG_GUEST_ERROR, "%s: module is not enabled\n", __func__); return -1; @@ -766,7 +777,7 @@ static void ot_entropy_src_update_filler(OtEntropySrcState *s) */ if (!timer_pending(s->scheduler)) { trace_ot_entropy_src_info("reschedule"); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); timer_mod(s->scheduler, (int64_t)(now + (uint64_t)ES_FILL_RATE_NS)); } } @@ -1320,7 +1331,7 @@ static void ot_entropy_src_regs_write(void *opaque, hwaddr addr, uint64_t val64, /* boot phase */ ot_entropy_src_change_state(s, ENTROPY_SRC_BOOT_HT_RUNNING); } - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); timer_mod(s->scheduler, (int64_t)(now + (uint64_t)OT_ENTROPY_SRC_BOOT_DELAY_NS)); @@ -1533,6 +1544,8 @@ static void ot_entropy_src_reset(DeviceState *dev) { OtEntropySrcState *s = OT_ENTROPY_SRC(dev); + trace_ot_entropy_src_reset(); + g_assert(s->ast); g_assert(s->otp_ctrl); @@ -1619,7 +1632,7 @@ static void ot_entropy_src_init(Object *obj) ot_fifo32_create(&s->final_fifo, ES_FINAL_FIFO_WORD_COUNT); s->scheduler = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_entropy_src_scheduler, s); + timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_entropy_src_scheduler, s); } static void ot_entropy_src_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 66c209f86dc4..618d8eb81463 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -135,7 +135,7 @@ ot_entropy_src_consume_entropy(bool obs_fifo, bool bypass, bool hw_path, unsigne ot_entropy_src_error(const char *msg, const char *state, int st) "%s [%s:%u]" ot_entropy_src_fill_noise(unsigned count, unsigned infifo) "up to %u, input fifo %u" ot_entropy_src_info(const char *msg) "%s" -ot_entropy_src_init_ongoing(const char *state, int st) "entropy source still initializing in [%s:%u]" +ot_entropy_src_init_ongoing(const char *state, int st, int ns) "ES still initializing in [%s:%u] %d ns to go" ot_entropy_src_io_read_out(uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_entropy_src_io_write(uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_entropy_src_is_fips_capable(bool en, bool es_route, bool es_type, bool rng_bit_en, bool res) "en:%u rt:%u tp:%u !rb:%u => %u" @@ -143,6 +143,7 @@ ot_entropy_src_no_entropy(unsigned count) "only %u words available" ot_entropy_src_obs_fifo(unsigned level, unsigned thold) "level %u, threshold %u" ot_entropy_src_otp_conf(bool fw_read, bool fw_over) "fw_read %u, fw_over %u" ot_entropy_src_push_bypass_entropy(unsigned slot) "final FIFO depth: %u" +ot_entropy_src_reset(void) "" ot_entropy_src_show_buffer(const char *func, int line, const char *msg, const char *hexstr) "%s:%u %s: %s" ot_entropy_src_update_filler(bool iok, bool ook, bool pok, bool all) "in %u, out %u, proc %u -> %u" ot_entropy_src_update_generation(unsigned gennum) "%u" From 29484868f9ed70c769e699110adb4b1743465bff Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 20 Feb 2024 15:38:26 +0100 Subject: [PATCH 13/58] [ot] hw/opentitan: ot_common: define which virtual clock to use for all IPs Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_aes.c | 5 ++--- hw/opentitan/ot_aon_timer.c | 21 ++++++++++----------- hw/opentitan/ot_ast_dj.c | 8 ++++---- hw/opentitan/ot_csrng.c | 4 ++-- hw/opentitan/ot_dma.c | 8 ++++---- hw/opentitan/ot_entropy_src.c | 9 ++++----- hw/opentitan/ot_flash.c | 4 ++-- hw/opentitan/ot_hmac.c | 7 ++++--- hw/opentitan/ot_kmac.c | 5 ++--- hw/opentitan/ot_otbn.c | 5 +++-- hw/opentitan/ot_otp_dj.c | 14 +++++++------- hw/opentitan/ot_otp_eg.c | 4 ++-- hw/opentitan/ot_pwrmgr.c | 4 ++-- hw/opentitan/ot_spi_device.c | 10 +++++----- hw/opentitan/ot_spi_host.c | 5 +++-- hw/opentitan/ot_timer.c | 13 +++++++------ include/hw/opentitan/ot_common.h | 8 ++++++++ 17 files changed, 71 insertions(+), 63 deletions(-) diff --git a/hw/opentitan/ot_aes.c b/hw/opentitan/ot_aes.c index ea95756f9234..ad71d1ec38ec 100644 --- a/hw/opentitan/ot_aes.c +++ b/hw/opentitan/ot_aes.c @@ -905,7 +905,7 @@ static void ot_aes_process_cond(OtAESState *s) * AES throughput. */ timer_del(s->retard_timer); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(s->retard_timer, (int64_t)(now + OT_AES_RETARD_DELAY_NS)); } else { @@ -1278,8 +1278,7 @@ static void ot_aes_init(Object *obj) ibex_qdev_init_irq(obj, &s->clkmgr, OT_CLOCK_ACTIVE); s->process_bh = qemu_bh_new(&ot_aes_handle_process, s); - s->retard_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_aes_handle_process, s); + s->retard_timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_aes_handle_process, s); } static void ot_aes_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_aon_timer.c b/hw/opentitan/ot_aon_timer.c index c8891b63801c..32c42127c4b8 100644 --- a/hw/opentitan/ot_aon_timer.c +++ b/hw/opentitan/ot_aon_timer.c @@ -34,6 +34,7 @@ #include "qemu/timer.h" #include "hw/opentitan/ot_alert.h" #include "hw/opentitan/ot_aon_timer.h" +#include "hw/opentitan/ot_common.h" #include "hw/qdev-properties.h" #include "hw/registerfields.h" #include "hw/riscv/ibex_common.h" @@ -200,7 +201,7 @@ static void ot_aon_timer_update_irqs(OtAonTimerState *s) static void ot_aon_timer_rearm_wkup(OtAonTimerState *s, bool reset_origin) { - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); if (reset_origin) { s->wkup_origin_ns = now; @@ -239,7 +240,7 @@ static void ot_aon_timer_wkup_cb(void *opaque) static void ot_aon_timer_rearm_wdog(OtAonTimerState *s, bool reset_origin) { - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); if (reset_origin) { s->wdog_origin_ns = now; @@ -306,14 +307,14 @@ static uint64_t ot_aon_timer_read(void *opaque, hwaddr addr, unsigned size) break; case R_WKUP_COUNT: { uint64_t now = ot_aon_timer_is_wkup_enabled(s) ? - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) : + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) : s->wkup_origin_ns; val32 = ot_aon_timer_get_wkup_count(s, now); break; } case R_WDOG_COUNT: { uint64_t now = ot_aon_timer_is_wdog_enabled(s) ? - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) : + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) : s->wdog_origin_ns; val32 = ot_aon_timer_get_wdog_count(s, now); break; @@ -368,7 +369,7 @@ static void ot_aon_timer_write(void *opaque, hwaddr addr, uint64_t value, /* stop timer */ timer_del(s->wkup_timer); /* save current count */ - uint32_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + uint32_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); s->regs[R_WKUP_COUNT] = ot_aon_timer_get_wkup_count(s, now); s->wkup_origin_ns = now; } @@ -401,7 +402,7 @@ static void ot_aon_timer_write(void *opaque, hwaddr addr, uint64_t value, /* stop timer */ timer_del(s->wdog_timer); /* save current count */ - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); s->regs[R_WDOG_COUNT] = ot_aon_timer_get_wdog_count(s, now); s->wdog_origin_ns = now; } @@ -435,7 +436,7 @@ static void ot_aon_timer_write(void *opaque, hwaddr addr, uint64_t value, * schedule the timer for the next peripheral clock tick to check again * for interrupt condition */ - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); int64_t next = ot_aon_timer_compute_next_timeout(s, now, 0); if (change & INTR_WKUP_TIMER_EXPIRED_MASK) { timer_mod_anticipate(s->wkup_timer, next); @@ -503,10 +504,8 @@ static void ot_aon_timer_init(Object *obj) TYPE_OT_AON_TIMER, REGS_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); - s->wkup_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_aon_timer_wkup_cb, s); - s->wdog_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_aon_timer_wdog_cb, s); + s->wkup_timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_aon_timer_wkup_cb, s); + s->wdog_timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_aon_timer_wdog_cb, s); } static void ot_aon_timer_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_ast_dj.c b/hw/opentitan/ot_ast_dj.c index 8ba446fdb0c2..cec5d4838583 100644 --- a/hw/opentitan/ot_ast_dj.c +++ b/hw/opentitan/ot_ast_dj.c @@ -36,6 +36,7 @@ #include "qemu/typedefs.h" #include "qapi/error.h" #include "hw/opentitan/ot_ast_dj.h" +#include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_random_src.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" @@ -194,7 +195,7 @@ static int ot_ast_dj_get_random(OtRandomSrcIf *dev, int genid, /* note: fips compliancy is only simulated here for now */ *fips = true; - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(rnd->timer, (int64_t)(now + OT_AST_DJ_RANDOM_FILL_RATE_NS)); return 0; @@ -412,7 +413,7 @@ static void ot_ast_dj_reset(DeviceState *dev) s->regsa[R_REGA37] = 0x25u; s->regsa[R_REGAL] = 0x26u; - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(rnd->timer, (int64_t)(now + OT_AST_DJ_RANDOM_FILL_RATE_NS)); } @@ -429,8 +430,7 @@ static void ot_ast_dj_init(Object *obj) OtASTDjRandom *rnd = &s->random; - rnd->timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_ast_dj_random_scheduler, s); + rnd->timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_ast_dj_random_scheduler, s); rnd->buffer = g_new0(uint64_t, OT_RANDOM_SRC_DWORD_COUNT); } diff --git a/hw/opentitan/ot_csrng.c b/hw/opentitan/ot_csrng.c index 78b8124c977d..49ebcd9cf185 100644 --- a/hw/opentitan/ot_csrng.c +++ b/hw/opentitan/ot_csrng.c @@ -1485,7 +1485,7 @@ static void ot_csrng_command_scheduler(void *opaque) trace_ot_csrng_scheduling_command(slot); if (CSRNG_CMD_RETRY == res && s->entropy_delay) { timer_mod(s->entropy_scheduler, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) + + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + (int64_t)s->entropy_delay); s->entropy_delay = 0; } else { @@ -1874,7 +1874,7 @@ static void ot_csrng_init(Object *obj) s->cmd_scheduler = qemu_bh_new(&ot_csrng_command_scheduler, s); s->entropy_scheduler = - timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_csrng_command_scheduler, s); + timer_new_ns(OT_VIRTUAL_CLOCK, &ot_csrng_command_scheduler, s); QSIMPLEQ_INIT(&s->cmd_requests); } diff --git a/hw/opentitan/ot_dma.c b/hw/opentitan/ot_dma.c index 3b52211f501c..aaf7e92c5f78 100644 --- a/hw/opentitan/ot_dma.c +++ b/hw/opentitan/ot_dma.c @@ -880,7 +880,7 @@ static bool ot_dma_go(OtDMAState *s) s->regs[R_STATUS] |= R_STATUS_BUSY_MASK; timer_del(s->timer); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(s->timer, (int64_t)(now + DMA_PACE_NS)); return true; @@ -899,7 +899,7 @@ static void ot_dma_abort(OtDMAState *s) /* simulate a delayed response */ timer_del(s->timer); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(s->timer, (int64_t)(now + DMA_PACE_NS)); } @@ -1014,7 +1014,7 @@ static void ot_dma_transfer(void *opaque) if (op->size) { /* schedule next block if any */ - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(s->timer, (int64_t)(now + DMA_PACE_NS)); return; } @@ -1345,7 +1345,7 @@ static void ot_dma_init(Object *obj) ibex_qdev_init_irq(obj, &s->alerts[ix], OT_DEVICE_ALERT); } - s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_dma_transfer, s); + s->timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_dma_transfer, s); } static void ot_dma_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_entropy_src.c b/hw/opentitan/ot_entropy_src.c index 4a2650d9306a..de069e9302f7 100644 --- a/hw/opentitan/ot_entropy_src.c +++ b/hw/opentitan/ot_entropy_src.c @@ -509,7 +509,7 @@ static int ot_entropy_src_get_random(OtRandomSrcIf *dev, int genid, } else { /* computed delay fits into a 31-bit value */ wait_ns = (int)(timer_expire_time_ns(s->scheduler) - - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT)); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK)); } trace_ot_entropy_src_init_ongoing(STATE_NAME(s->state), s->state, wait_ns); @@ -777,7 +777,7 @@ static void ot_entropy_src_update_filler(OtEntropySrcState *s) */ if (!timer_pending(s->scheduler)) { trace_ot_entropy_src_info("reschedule"); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(s->scheduler, (int64_t)(now + (uint64_t)ES_FILL_RATE_NS)); } } @@ -1331,7 +1331,7 @@ static void ot_entropy_src_regs_write(void *opaque, hwaddr addr, uint64_t val64, /* boot phase */ ot_entropy_src_change_state(s, ENTROPY_SRC_BOOT_HT_RUNNING); } - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); timer_mod(s->scheduler, (int64_t)(now + (uint64_t)OT_ENTROPY_SRC_BOOT_DELAY_NS)); @@ -1631,8 +1631,7 @@ static void ot_entropy_src_init(Object *obj) ot_fifo32_create(&s->swread_fifo, ES_SWREAD_FIFO_WORD_COUNT); ot_fifo32_create(&s->final_fifo, ES_FINAL_FIFO_WORD_COUNT); - s->scheduler = - timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_entropy_src_scheduler, s); + s->scheduler = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_entropy_src_scheduler, s); } static void ot_entropy_src_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_flash.c b/hw/opentitan/ot_flash.c index f8787a11581b..f52cfdc22882 100644 --- a/hw/opentitan/ot_flash.c +++ b/hw/opentitan/ot_flash.c @@ -721,7 +721,7 @@ static void ot_flash_initialize(OtFlashState *s) s->regs[R_PHY_STATUS] = FIELD_DP32(s->regs[R_PHY_STATUS], PHY_STATUS, INIT_WIP, 0u); timer_mod(s->op_delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + OP_INIT_DURATION_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + OP_INIT_DURATION_NS); } static bool ot_flash_fifo_in_reset(OtFlashState *s) @@ -1824,7 +1824,7 @@ static void ot_flash_init(Object *obj) for (unsigned ix = 0; ix < PARAM_NUM_ALERTS; ix++) { ibex_qdev_init_irq(obj, &s->alerts[ix], OT_DEVICE_ALERT); } - s->op_delay = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_flash_op_signal, s); + s->op_delay = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_flash_op_signal, s); } static void ot_flash_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_hmac.c b/hw/opentitan/ot_hmac.c index 32e788179cfc..96429738367a 100644 --- a/hw/opentitan/ot_hmac.c +++ b/hw/opentitan/ot_hmac.c @@ -34,6 +34,7 @@ #include "hw/irq.h" #include "hw/opentitan/ot_alert.h" #include "hw/opentitan/ot_clkmgr.h" +#include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_hmac.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" @@ -465,7 +466,7 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value, timer_del(s->fifo_trigger_handle); ibex_irq_set(&s->clkmgr, true); timer_mod(s->fifo_trigger_handle, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + FIFO_TRIGGER_DELAY_NS); } break; @@ -566,7 +567,7 @@ static void ot_hmac_fifo_write(void *opaque, hwaddr addr, uint64_t value, /* trigger delayed processing of FIFO */ timer_del(s->fifo_trigger_handle); timer_mod(s->fifo_trigger_handle, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + FIFO_TRIGGER_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + FIFO_TRIGGER_DELAY_NS); } static Property ot_hmac_properties[] = { @@ -619,7 +620,7 @@ static void ot_hmac_init(Object *obj) /* setup FIFO Interrupt Timer */ s->fifo_trigger_handle = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_hmac_fifo_trigger_update, s); + timer_new_ns(OT_VIRTUAL_CLOCK, &ot_hmac_fifo_trigger_update, s); /* FIFO sizes as per OT Spec */ fifo8_create(&s->input_fifo, OT_HMAC_FIFO_LENGTH); diff --git a/hw/opentitan/ot_kmac.c b/hw/opentitan/ot_kmac.c index da2319fff50e..dd9df18e0b88 100644 --- a/hw/opentitan/ot_kmac.c +++ b/hw/opentitan/ot_kmac.c @@ -441,7 +441,7 @@ static void ot_kmac_trigger_deferred_bh(OtKMACState *s) { timer_del(s->bh_timer); timer_mod(s->bh_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + BH_TRIGGER_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + BH_TRIGGER_DELAY_NS); } static void ot_kmac_bh_timer_handler(void *opaque) @@ -1649,8 +1649,7 @@ static void ot_kmac_init(Object *obj) &s->msgfifo_mmio); /* setup deferred processing */ - s->bh_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_kmac_bh_timer_handler, s); + s->bh_timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_kmac_bh_timer_handler, s); s->bh = qemu_bh_new(&ot_kmac_process, s); /* FIFO sizes as per OT Spec */ diff --git a/hw/opentitan/ot_otbn.c b/hw/opentitan/ot_otbn.c index 0e749e06cacb..d56e82efa806 100644 --- a/hw/opentitan/ot_otbn.c +++ b/hw/opentitan/ot_otbn.c @@ -38,6 +38,7 @@ #include "qapi/error.h" #include "hw/opentitan/ot_alert.h" #include "hw/opentitan/ot_clkmgr.h" +#include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_edn.h" #include "hw/opentitan/ot_fifo32.h" #include "hw/opentitan/ot_otbn.h" @@ -253,7 +254,7 @@ static void ot_otbn_proxy_completion_bh(void *opaque) */ timer_del(s->proxy_defer); timer_mod(s->proxy_defer, - qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 100u); + qemu_clock_get_us(OT_VIRTUAL_CLOCK) + 100u); } else { ot_otbn_post_execute(s); } @@ -676,7 +677,7 @@ static void ot_otbn_init(Object *obj) } s->proxy_completion_bh = qemu_bh_new(&ot_otbn_proxy_completion_bh, s); - s->proxy_defer = timer_new_us(QEMU_CLOCK_VIRTUAL, &ot_otbn_post_execute, s); + s->proxy_defer = timer_new_us(OT_VIRTUAL_CLOCK, &ot_otbn_post_execute, s); s->proxy = ot_otbn_proxy_new(&ot_otbn_trigger_entropy_req, &s->rnds[OT_OTBN_URND], &ot_otbn_trigger_entropy_req, &s->rnds[OT_OTBN_RND], diff --git a/hw/opentitan/ot_otp_dj.c b/hw/opentitan/ot_otp_dj.c index dec1c33f3266..86684e8b4c3e 100644 --- a/hw/opentitan/ot_otp_dj.c +++ b/hw/opentitan/ot_otp_dj.c @@ -1671,7 +1671,7 @@ static void ot_otp_dj_dai_read(OtOTPDjState *s) if (!ot_otp_dj_is_buffered(partition)) { /* fake slow access to OTP cell */ timer_mod(s->dai.delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + DAI_READ_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + DAI_READ_DELAY_NS); } else { DAI_CHANGE_STATE(s, OTP_DAI_IDLE); } @@ -1785,7 +1785,7 @@ static void ot_otp_dj_dai_write(OtOTPDjState *s) DAI_CHANGE_STATE(s, OTP_DAI_WRITE_WAIT); timer_mod(s->dai.delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + DAI_WRITE_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + DAI_WRITE_DELAY_NS); } static void ot_otp_dj_dai_digest(OtOTPDjState *s) @@ -1866,7 +1866,7 @@ static void ot_otp_dj_dai_digest(OtOTPDjState *s) /* fake slow access to OTP cell */ timer_mod(s->dai.delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + DAI_DIGEST_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + DAI_DIGEST_DELAY_NS); } static void ot_otp_dj_dai_write_digest(void *opaque) @@ -1897,7 +1897,7 @@ static void ot_otp_dj_dai_write_digest(void *opaque) DAI_CHANGE_STATE(s, OTP_DAI_WRITE_WAIT); timer_mod(s->dai.delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + DAI_WRITE_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + DAI_WRITE_DELAY_NS); } else { /* TODO: no idea on how to report the error since partition is undef */ ot_otp_dj_dai_set_error(s, error); @@ -2977,7 +2977,7 @@ static void ot_otp_dj_lci_write_word(void *opaque) lci->hpos += 1; timer_mod(lci->prog_delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + LCI_PROG_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + LCI_PROG_DELAY_NS); LCI_CHANGE_STATE(s, OTP_LCI_WRITE_WAIT); } @@ -3278,10 +3278,10 @@ static void ot_otp_dj_init(Object *obj) s->hw_cfg = g_new0(OtOTPHWCfg, 1u); s->tokens = g_new0(OtOTPTokens, 1u); - s->dai.delay = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_otp_dj_dai_complete, s); + s->dai.delay = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_otp_dj_dai_complete, s); s->dai.digest_bh = qemu_bh_new(&ot_otp_dj_dai_write_digest, s); s->lci.prog_delay = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_otp_dj_lci_write_word, s); + timer_new_ns(OT_VIRTUAL_CLOCK, &ot_otp_dj_lci_write_word, s); s->lci.prog_bh = qemu_bh_new(&ot_otp_dj_lci_write_word, s); } diff --git a/hw/opentitan/ot_otp_eg.c b/hw/opentitan/ot_otp_eg.c index 5553907a278d..ba74dcddd2a0 100644 --- a/hw/opentitan/ot_otp_eg.c +++ b/hw/opentitan/ot_otp_eg.c @@ -677,7 +677,7 @@ static void ot_otp_eg_direct_read(OtOTPEgState *s) if (!ot_otp_eg_is_buffered(partition)) { timer_mod(s->dai_delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + DAI_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + DAI_DELAY_NS); return; } @@ -1384,7 +1384,7 @@ static void ot_otp_eg_init(Object *obj) s->hw_cfg = g_new0(OtOTPHWCfg, 1u); s->entropy_cfg = g_new0(OtOTPEntropyCfg, 1u); - s->dai_delay = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_otp_eg_complete_dai, s); + s->dai_delay = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_otp_eg_complete_dai, s); } static void ot_otp_eg_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index b556af8bbc82..98511c326d46 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -737,7 +737,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64, val32 &= R_CFG_CDC_SYNC_SYNC_MASK; s->regs[reg] |= val32; /* not described as RW1S, but looks like it */ if (val32) { - timer_mod(s->cdc_sync, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + timer_mod(s->cdc_sync, qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + CDC_SYNC_PULSE_DURATION_NS); } break; @@ -868,7 +868,7 @@ static void ot_pwrmgr_init(Object *obj) ibex_qdev_init_irq(obj, &s->pwr_otp_req, OT_PWRMGR_OTP_REQ); ibex_qdev_init_irq(obj, &s->cpu_enable, OT_PWRMGR_CPU_EN); - s->cdc_sync = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_pwrmgr_cdc_sync, s); + s->cdc_sync = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_pwrmgr_cdc_sync, s); qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_wkup, OT_PWRMGR_WKUP, OT_PWRMGR_WAKEUP_COUNT); diff --git a/hw/opentitan/ot_spi_device.c b/hw/opentitan/ot_spi_device.c index 1a9e46cd7be3..0139d841c2a6 100644 --- a/hw/opentitan/ot_spi_device.c +++ b/hw/opentitan/ot_spi_device.c @@ -1100,7 +1100,7 @@ static void ot_spi_device_flash_pace_spibus(OtSPIDeviceState *s) SpiDeviceFlash *f = &s->flash; timer_del(f->irq_timer); - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); trace_ot_spi_device_flash_pace("set", timer_pending(f->irq_timer)); timer_mod(f->irq_timer, (int64_t)(now + SPI_BUS_FLASH_READ_DELAY_NS)); } @@ -2359,7 +2359,7 @@ static void ot_spi_device_chr_recv_generic(OtSPIDeviceState *s, count--; } if (!fifo8_is_empty(&g->rx_fifo) && bus->byte_count) { - uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); /* todo: use R_CFG_TIMER_V field to change the timeout */ timer_mod(g->rx_timer, (int64_t)(now + SPI_BUS_TIMEOUT_NS)); } @@ -2673,9 +2673,9 @@ static void ot_spi_device_init(Object *obj) * co-operative multitasking between the vCPU and the IO thread */ f->irq_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_spi_device_flash_resume_read, s); - g->rx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - &ot_spi_device_recv_generic_timeout, s); + timer_new_ns(OT_VIRTUAL_CLOCK, &ot_spi_device_flash_resume_read, s); + g->rx_timer = + timer_new_ns(OT_VIRTUAL_CLOCK, &ot_spi_device_recv_generic_timeout, s); } static void ot_spi_device_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_spi_host.c b/hw/opentitan/ot_spi_host.c index 77ba33d76749..426484bff6a7 100644 --- a/hw/opentitan/ot_spi_host.c +++ b/hw/opentitan/ot_spi_host.c @@ -45,6 +45,7 @@ #include "hw/hw.h" #include "hw/irq.h" #include "hw/opentitan/ot_alert.h" +#include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_spi_host.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" @@ -840,7 +841,7 @@ static void ot_spi_host_step_fsm(OtSPIHostState *s, const char *cause) headcmd->ongoing = ongoing; timer_mod(s->fsm_delay, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + FSM_TRIGGER_DELAY_NS); + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) + FSM_TRIGGER_DELAY_NS); ot_spi_host_trace_status("S<", ot_spi_host_get_status(s)); } @@ -1277,7 +1278,7 @@ static void ot_spi_host_instance_init(Object *obj) cmdfifo_create(s->cmd_fifo, CMDFIFO_LEN); s->fsm_bh = qemu_bh_new(&ot_spi_host_schedule_fsm, s); - s->fsm_delay = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ot_spi_host_post_fsm, s); + s->fsm_delay = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_spi_host_post_fsm, s); } static void ot_spi_host_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/ot_timer.c b/hw/opentitan/ot_timer.c index 1dd9489c2376..ae6a98cc4f20 100644 --- a/hw/opentitan/ot_timer.c +++ b/hw/opentitan/ot_timer.c @@ -29,6 +29,7 @@ #include "qemu/log.h" #include "qemu/timer.h" #include "hw/opentitan/ot_alert.h" +#include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_timer.h" #include "hw/qdev-properties.h" #include "hw/registerfields.h" @@ -160,7 +161,7 @@ static void ot_timer_update_irqs(OtTimerState *s) static void ot_timer_rearm(OtTimerState *s, bool reset_origin) { - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); if (reset_origin) { s->origin_ns = now; @@ -211,14 +212,14 @@ static uint64_t ot_timer_read(void *opaque, hwaddr addr, unsigned size) break; case R_TIMER_V_LOWER0: { int64_t now = ot_timer_is_active(s) ? - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) : + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) : s->origin_ns; val32 = ot_timer_get_mtime(s, now); break; } case R_TIMER_V_UPPER0: { int64_t now = ot_timer_is_active(s) ? - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) : + qemu_clock_get_ns(OT_VIRTUAL_CLOCK) : s->origin_ns; val32 = ot_timer_get_mtime(s, now) >> 32u; break; @@ -272,7 +273,7 @@ static void ot_timer_write(void *opaque, hwaddr addr, uint64_t value, /* stop timer */ timer_del(s->timer); /* save current mtime */ - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); uint64_t mtime = ot_timer_get_mtime(s, now); s->regs[R_TIMER_V_LOWER0] = (uint32_t)mtime; s->regs[R_TIMER_V_UPPER0] = (uint32_t)(mtime >> 32u); @@ -292,7 +293,7 @@ static void ot_timer_write(void *opaque, hwaddr addr, uint64_t value, * schedule the timer for the next peripheral clock tick to check again * for interrupt condition */ - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK); int64_t next = ot_timer_compute_next_timeout(s, now, 0); timer_mod_anticipate(s->timer, next); break; @@ -373,7 +374,7 @@ static void ot_timer_init(Object *obj) REGS_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); - s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, &ot_timer_cb, s); + s->timer = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_timer_cb, s); } static void ot_timer_class_init(ObjectClass *klass, void *data) diff --git a/include/hw/opentitan/ot_common.h b/include/hw/opentitan/ot_common.h index 7edb299eddb5..cceda7662ba2 100644 --- a/include/hw/opentitan/ot_common.h +++ b/include/hw/opentitan/ot_common.h @@ -23,10 +23,18 @@ #ifndef HW_OPENTITAN_OT_COMMON_H #define HW_OPENTITAN_OT_COMMON_H +#include "qemu/timer.h" #include "chardev/char-fe.h" #include "exec/memory.h" #include "hw/core/cpu.h" +/* ------------------------------------------------------------------------ */ +/* Timer */ +/* ------------------------------------------------------------------------ */ + +/* QEMU virtual timer to use for OpenTitan devices */ +#define OT_VIRTUAL_CLOCK QEMU_CLOCK_VIRTUAL_RT + /* ------------------------------------------------------------------------ */ /* Multi-bit boolean values */ /* ------------------------------------------------------------------------ */ From c8663e84e2cabf632f690459b3b585f773ac2e81 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 16 Feb 2024 16:17:30 +0100 Subject: [PATCH 14/58] [ot] hw/opentitan: ot_edn: fix a bug with outstanding requests The outstanding requests were not discarded on EDN reset Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_edn.c | 24 ++++++++++++++++-------- hw/opentitan/trace-events | 9 +++++---- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/hw/opentitan/ot_edn.c b/hw/opentitan/ot_edn.c index a3d04fb8ac5b..02db52df67d9 100644 --- a/hw/opentitan/ot_edn.c +++ b/hw/opentitan/ot_edn.c @@ -821,7 +821,7 @@ static void ot_edn_dispatch(OtEDNState *s) } } -static void ot_edn_clean_up(OtEDNState *s) +static void ot_edn_clean_up(OtEDNState *s, bool discard_requests) { OtEDNCSRNG *c = &s->rng; @@ -836,12 +836,14 @@ static void ot_edn_clean_up(OtEDNState *s) for (unsigned ix = 0; ix < PARAM_NUM_ALERTS; ix++) { ibex_irq_set(&s->alerts[ix], 0); } -#ifdef EDN_DISCARD_PENDING_REQUEST_ON_DISABLE - /* clear all pending end point requests */ - while (QSIMPLEQ_FIRST(&s->ep_requests)) { - QSIMPLEQ_REMOVE_HEAD(&s->ep_requests, request); + + if (discard_requests) { + /* clear all pending end point requests */ + while (QSIMPLEQ_FIRST(&s->ep_requests)) { + QSIMPLEQ_REMOVE_HEAD(&s->ep_requests, request); + } } -#endif + for (unsigned epix = 0; epix < ARRAY_SIZE(s->endpoints); epix++) { ot_fifo32_reset(&s->endpoints[epix].fifo); s->endpoints[epix].fips = false; @@ -1000,7 +1002,11 @@ static void ot_edn_csrng_ack_irq(void *opaque, int n, int level) if (ot_edn_is_sw_port_mode(s)) { ot_edn_complete_sw_req(s); } - ot_edn_clean_up(s); +#ifdef EDN_DISCARD_PENDING_REQUEST_ON_DISABLE + ot_edn_clean_up(s, true); +#else + ot_edn_clean_up(s, false); +#endif return; default: break; @@ -1273,13 +1279,15 @@ static void ot_edn_reset(DeviceState *dev) OtEDNState *s = OT_EDN(dev); OtEDNCSRNG *c = &s->rng; + trace_ot_edn_reset(s->rng.appid); + memset(s->regs, 0, REGS_SIZE); s->regs[R_REGWEN] = 0x1u; s->regs[R_CTRL] = 0x9999u; s->regs[R_BOOT_INS_CMD] = 0x901u; s->regs[R_BOOT_GEN_CMD] = 0xfff003u; - ot_edn_clean_up(s); + ot_edn_clean_up(s, true); /* do not reset connection info since reset order is not known */ (void)c->genbits_ready; diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 618d8eb81463..307a705fcce0 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -108,24 +108,25 @@ ot_dma_transfer(const char *did, const char *dir, const char *asname, uint64_t a ot_edn_change_state(unsigned appid, int line, const char *old, int nold, const char *new, int nnew) "a#%u @ %d [%s:%d] -> [%s:%d]" ot_edn_connect_endpoint(unsigned appid, unsigned epid) "a#%u:e#%u" -ot_edn_ctrl_in_state(unsigned appid, const char *state, int nstate) "a#%u [%s:%d]" ot_edn_csrng_ack(unsigned appid, const char *state, int level) "a#%u %s %d" +ot_edn_ctrl_in_state(unsigned appid, const char *state, int nstate) "a#%u [%s:%d]" +ot_edn_dinfo(unsigned appid, const char *func, int line, const char *msg, uint32_t value) "a#%u %s:%d %s %u" ot_edn_enable(unsigned appid, const char *msg) "a#%u: %s" ot_edn_ep_fifo(unsigned appid, const char *msg, unsigned remwslot) "a#%u %s rem:%u" ot_edn_ep_request(unsigned appid, bool avail, const char *state, int st, bool refill, unsigned rem) "a#%u avail %u, [%s:%d], refill %u, rem %u" ot_edn_error(unsigned appid, const char *func, int line, const char *err) "a#%u %s:%d %s" ot_edn_fill_bits(unsigned appid, unsigned rem, bool packet_fips, bool fips) "a#%u rem %u, fips %u/%u" ot_edn_fill_endpoint(unsigned appid, unsigned epid, uint32_t bits, bool fips, size_t gcnt, size_t tcnt) "a#%u:e#%u bits 0x%08x fips %u count %lu/%lu" -ot_edn_dinfo(unsigned appid, const char *func, int line, const char *msg, uint32_t value) "a#%u %s:%d %s %u" -ot_edn_xinfo(unsigned appid, const char *func, int line, const char *msg, uint32_t value) "a#%u %s:%d %s 0x%08x" +ot_edn_handle_ep_request(unsigned appid, unsigned epid) "a#%u:e#%u" ot_edn_invalid_state(unsigned appid, const char *func, const char *state, int st) "a#%u %s [%s:%d]" ot_edn_io_read_out(unsigned appid, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "a#%u addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_edn_io_write(unsigned appid, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "a#%u addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_edn_irqs(unsigned appid, uint32_t active, uint32_t mask, uint32_t eff) "#%u act:0x%08x msk:0x%08x eff:0x%08x" ot_edn_request_entropy(unsigned appid, unsigned epid) "a#%u:e#%u" +ot_edn_reset(unsigned appid) "a#%u" ot_edn_schedule(unsigned appid, const char *cause) "a#%u %s" -ot_edn_handle_ep_request(unsigned appid, unsigned epid) "a#%u:e#%u" ot_edn_update_genbits_ready(unsigned appid, unsigned rem, unsigned fslot, bool accept) "a#%u rem packet %u, free slot %u, accept? %u" +ot_edn_xinfo(unsigned appid, const char *func, int line, const char *msg, uint32_t value) "a#%u %s:%d %s 0x%08x" # ot_entropy_src.c From 836754bf028054fccb4d7d3261be5b737ffce91c Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 20 Feb 2024 15:33:26 +0100 Subject: [PATCH 15/58] [ot] hw/opentitan: ot_gpio: fix invalid debug trace Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/opentitan/ot_gpio.c b/hw/opentitan/ot_gpio.c index fd119c0b0393..1992f6e744b5 100644 --- a/hw/opentitan/ot_gpio.c +++ b/hw/opentitan/ot_gpio.c @@ -358,7 +358,7 @@ static void ot_gpio_chr_receive(void *opaque, const uint8_t *buf, int size) OtGpioState *s = opaque; if (s->ipos + (unsigned)size > sizeof(s->ibuf)) { - qemu_log("%s: Incoherent chardev receive\n", __func__); + error_report("%s: Unexpected chardev receive\n", __func__); return; } From fc51acab41f11d9d14815e62540164da699489b8 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 20 Feb 2024 15:33:46 +0100 Subject: [PATCH 16/58] [ot] hw/opentitan: ot_devproxy: fix invalid debug traces Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_dev_proxy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/opentitan/ot_dev_proxy.c b/hw/opentitan/ot_dev_proxy.c index ab8b0eba63cb..920a38628915 100644 --- a/hw/opentitan/ot_dev_proxy.c +++ b/hw/opentitan/ot_dev_proxy.c @@ -317,8 +317,8 @@ static void ot_dev_proxy_enumerate_devices(OtDevProxyState *s) memcpy(&entry->desc[2u], item->caps.mr->name, slen); entry->desc[2u + slen] = (char)('0' + mrcount++); } else { - qemu_log("ignoring discovered device: %s\n", - object_get_typename(item->obj)); + warn_report("%s: ignoring discovered device: %s\n", __func__, + object_get_typename(item->obj)); continue; } entry->header = ix << 16u; @@ -1301,7 +1301,7 @@ static void ot_dev_proxy_receive(void *opaque, const uint8_t *buf, int size) OtDevProxyState *s = opaque; if (fifo8_num_free(&s->rx_fifo) < size) { - qemu_log("Incoherent chardev receive\n"); + error_report("%s: Unexpected chardev receive\n", __func__); return; } From 80fe928fef05e1ba8cc2ebbce6762135d160d2fd Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 19:50:39 +0100 Subject: [PATCH 17/58] [ot] hw/riscv: ot_darjeeling, ot_earlgrey: document extra reset cycle Signed-off-by: Emmanuel Blot --- hw/riscv/ot_darjeeling.c | 8 ++++++-- hw/riscv/ot_earlgrey.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index 9636737027a6..307049289f87 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -1099,8 +1099,12 @@ static void ot_dj_soc_reset_hold(Object *obj) RESET_TYPE_COLD); /* - * leave hart on reset - * power manager should release it once ROMs have been validated + * Power-On-Reset: leave hart on reset + * PowerManager takes care of managing Ibex reset when ready + * + * Note that an initial, extra single reset cycle (assert/release) is + * performed from the generic #riscv_cpu_realize function on machine + * realization. */ CPUState *cs = CPU(s->devices[OT_DJ_SOC_DEV_HART]); resettable_assert_reset(OBJECT(cs), RESET_TYPE_COLD); diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index 4392bc4f4a6a..25c8bb951cf1 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -1007,8 +1007,12 @@ static void ot_eg_soc_reset_hold(Object *obj) RESET_TYPE_COLD); /* - * leave hart on reset - * power manager should release it once ROM has been validated + * Power-On-Reset: leave hart on reset + * PowerManager takes care of managing Ibex reset when ready + * + * Note that an initial, extra single reset cycle (assert/release) is + * performed from the generic #riscv_cpu_realize function on machine + * realization. */ CPUState *cs = CPU(s->devices[OT_EG_SOC_DEV_HART]); resettable_assert_reset(OBJECT(cs), RESET_TYPE_COLD); From ef48d3e18232562646f5d1d6db324da0aee2f010 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 20 Feb 2024 14:31:12 +0100 Subject: [PATCH 18/58] [ot] hw/riscv: ibex_irq: add an API to initialize IbexIRQ with custom value. This API can be used to ensure the first time IbexIRQ is set, the new IRQ value is propagated to the connected device. The need may arise to forward a 0 value which is otherwise ignored as the role of IbexIRQ is to not propagate updates with unchanged values. Signed-off-by: Emmanuel Blot --- include/hw/riscv/ibex_irq.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/hw/riscv/ibex_irq.h b/include/hw/riscv/ibex_irq.h index da0fbc52756e..eb9f3b8a3918 100644 --- a/include/hw/riscv/ibex_irq.h +++ b/include/hw/riscv/ibex_irq.h @@ -76,6 +76,13 @@ static inline void ibex_qdev_init_irq(Object *obj, IbexIRQ *irq, qdev_init_gpio_out_named(DEVICE(obj), &irq->irq, name, 1); } +static inline void ibex_qdev_init_irq_default(Object *obj, IbexIRQ *irq, + const char *name, int level) +{ + irq->level = level; + qdev_init_gpio_out_named(DEVICE(obj), &irq->irq, name, 1); +} + static inline void ibex_qdev_init_irqs(Object *obj, IbexIRQ *irqs, const char *name, unsigned count) { From 9299270514633d9a861354d8b699490962f47c17 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 21 Feb 2024 13:46:52 +0100 Subject: [PATCH 19/58] [ot] hw/opentitan: ot_ibex_wrapper_dj: add `lc-ignore-ids` option Signed-off-by: Emmanuel Blot --- docs/opentitan/darjeeling.md | 6 ++++++ hw/opentitan/ot_ibex_wrapper_dj.c | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/opentitan/darjeeling.md b/docs/opentitan/darjeeling.md index 4efc81aaf493..4393dbd906bd 100644 --- a/docs/opentitan/darjeeling.md +++ b/docs/opentitan/darjeeling.md @@ -143,6 +143,12 @@ See [`tools.md`](tools.md) alternative to allow the Ibex core to execute guest code is to provide a valid OTP image with one of the expected LifeCycle state, such as TestUnlock*, Dev, Prod or RMA. +* `-global ot-ibex_wrapper-dj.lc-ignore-ids=` acts as `lc-ignore`, enabling the selection of + specific ibex wrapper instance based on their unique identifiers. See `ot_id` property in the + machine definition file for a list of valid identifiers. `` should be defined as a comma- + separated list of valid identifiers. It is only possible to ignore LifeCycle states with this + option, not to enforce them. + * `-cpu lowrisc-ibex,x-zbr=false` can be used to force disable the Zbr experimental-and-deprecated RISC-V bitmap extension for CRC32 extension. diff --git a/hw/opentitan/ot_ibex_wrapper_dj.c b/hw/opentitan/ot_ibex_wrapper_dj.c index 48c8640b026e..14ff12717ccd 100644 --- a/hw/opentitan/ot_ibex_wrapper_dj.c +++ b/hw/opentitan/ot_ibex_wrapper_dj.c @@ -716,6 +716,7 @@ struct OtIbexWrapperDjState { /* Optional properties */ char *ot_id; + char *lc_ignore_ids; OtEDNState *edn; uint8_t edn_ep; bool lc_ignore; @@ -1459,6 +1460,7 @@ static Property ot_ibex_wrapper_dj_properties[] = { OtEDNState *), DEFINE_PROP_UINT8("edn-ep", OtIbexWrapperDjState, edn_ep, UINT8_MAX), DEFINE_PROP_BOOL("lc-ignore", OtIbexWrapperDjState, lc_ignore, false), + DEFINE_PROP_STRING("lc-ignore-ids", OtIbexWrapperDjState, lc_ignore_ids), DEFINE_PROP_CHR("logdev", OtIbexWrapperDjState, chr), DEFINE_PROP_END_OF_LIST(), }; @@ -1480,6 +1482,18 @@ static void ot_ibex_wrapper_dj_reset(DeviceState *dev) g_assert(s->ot_id); g_assert(s->sys_mem); + if (s->lc_ignore_ids) { + char *ign = g_strdup(s->lc_ignore_ids); + char *token = strtok(ign, ","); + while (token) { + if (!strcmp(token, s->ot_id)) { + s->lc_ignore = true; + } + token = strtok(NULL, ","); + } + g_free(ign); + } + if (!s->cpu) { CPUState *cpu = ot_common_get_local_cpu(DEVICE(s)); if (!cpu) { From ae62256205f2e5cfacd651f6617f77f630ad7fdf Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 19:50:02 +0100 Subject: [PATCH 20/58] [ot] hw/opentitan: ot_rstmgr: fix a bug on vCPU reset It is mandatory to wait for the vCPU to actually stop before resuming the reset sequence. Failing to do so may lead TCG to execute a cached TB from the new PC, updated from reset vector. Avoid using pause_all_vcpus/resume_all_vcpus as other SoCs in the machine should not be stopped. Moreover the virtual clock should not be halted as other SoCs may keep running while the local reset sequence is ran. Avoid using qemu_system_reset_request for the same reason, which is even more intrusive for the whole VM. Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_rstmgr.c | 53 ++++++++++++++++++++++++++++++++------- hw/opentitan/trace-events | 1 + 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/hw/opentitan/ot_rstmgr.c b/hw/opentitan/ot_rstmgr.c index 522a8dede23f..9abf2e0bafd0 100644 --- a/hw/opentitan/ot_rstmgr.c +++ b/hw/opentitan/ot_rstmgr.c @@ -47,6 +47,7 @@ #include "hw/riscv/ibex_common.h" #include "hw/riscv/ibex_irq.h" #include "hw/sysbus.h" +#include "sysemu/hw_accel.h" #include "trace.h" @@ -151,6 +152,8 @@ struct OtRstMgrState { MemoryRegion mmio; IbexIRQ sw_reset; IbexIRQ alert; + QEMUBH *bus_reset_bh; + CPUState *cpu; uint32_t *regs; @@ -208,17 +211,36 @@ void ot_rstmgr_reset_req(OtRstMgrState *s, bool fastclk, OtRstMgrResetReq req) trace_ot_rstmgr_reset_req(REQ_NAME(req), req, fastclk); - /* - * Reset all devices connected to RSTMGR parent bus, i.e. OpenTitan devices - * TODO: manage reset tree (depending on power domains, etc.) - */ - bus_cold_reset(s->parent_obj.parent_obj.parent_bus); + qemu_bh_schedule(s->bus_reset_bh); } /* -------------------------------------------------------------------------- */ /* Private implementation */ /* -------------------------------------------------------------------------- */ +static void ot_rstmgr_reset_bus(void *opaque) +{ + OtRstMgrState *s = opaque; + + /* request the vCPU to stop */ + s->cpu->stop = true; + + /* wait for the vCPU to stop */ + while (!s->cpu->stopped) { + qemu_mutex_unlock_iothread(); + qemu_cpu_kick(s->cpu); + qemu_mutex_lock_iothread(); + } + qemu_notify_event(); + + cpu_synchronize_state(s->cpu); + /* Reset all OpenTitan devices connected to RSTMGR parent bus */ + bus_cold_reset(s->parent_obj.parent_obj.parent_bus); + cpu_synchronize_post_reset(s->cpu); + + /* TODO: manage reset tree (depending on power domains, etc.) */ +} + static int ot_rstmgr_sw_rst_walker(DeviceState *dev, void *opaque) { OtRstMgrResetDesc *desc = opaque; @@ -249,8 +271,8 @@ static void ot_rstmgr_update_sw_reset(OtRstMgrState *s, unsigned devix) const OtRstMgrResettable *rst = &SW_RESETTABLE_DEVICES[devix]; if (!rst->typename) { - qemu_log_mask(LOG_UNIMP, "Reset for slot %u not yet implemented", - devix); + qemu_log_mask(LOG_UNIMP, "%s: Reset for slot %u not yet implemented", + __func__, devix); return; } @@ -259,13 +281,15 @@ static void ot_rstmgr_update_sw_reset(OtRstMgrState *s, unsigned devix) desc.path = g_strdup_printf("%s[%d]", rst->typename, rst->idx); desc.reset = !s->regs[R_SW_RST_CTRL_N_0 + devix]; + trace_ot_rstmgr_sw_reset(desc.path); + /* search for the device on the same local bus */ int res = qbus_walk_children(s->parent_obj.parent_obj.parent_bus, &ot_rstmgr_sw_rst_walker, NULL, NULL, NULL, &desc); if (res >= 0) { - qemu_log_mask(LOG_GUEST_ERROR, "rstmgr: unable to locate device %s", - desc.path); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Unable to locate device %s", + __func__, desc.path); } g_free(desc.path); @@ -459,6 +483,15 @@ static void ot_rstmgr_reset(DeviceState *dev) trace_ot_rstmgr_reset(); + if (!s->cpu) { + CPUState *cpu = ot_common_get_local_cpu(DEVICE(s)); + if (!cpu) { + error_setg(&error_fatal, "Could not find the associated vCPU"); + g_assert_not_reached(); + } + s->cpu = cpu; + } + s->regs[R_RESET_REQ] = OT_MULTIBITBOOL4_FALSE; if (s->por) { memset(s->regs, 0, REGS_SIZE); @@ -494,6 +527,8 @@ static void ot_rstmgr_init(Object *obj) ibex_qdev_init_irq(obj, &s->sw_reset, OT_RSTMGR_SW_RST); ibex_qdev_init_irq(obj, &s->alert, OT_DEVICE_ALERT); + + s->bus_reset_bh = qemu_bh_new(&ot_rstmgr_reset_bus, s); } static void ot_rstmgr_class_init(ObjectClass *klass, void *data) diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 307a705fcce0..c7597d462e5b 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -303,6 +303,7 @@ ot_rstmgr_io_read_out(uint32_t addr, const char * regname, uint32_t val, uint32_ ot_rstmgr_io_write(uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_rstmgr_reset(void) "" ot_rstmgr_reset_req(const char *req, unsigned reqix, bool fastclk) "%s(%u) @%u" +ot_rstmgr_sw_reset(const char *devpath) "SW reset %s" ot_rstmgr_sw_rst(const char *path, bool reset) "%s: reset:%u" # ot_sensor.c From 19158d72dbf300306fc4b0144539885f440f88ba Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 19:40:53 +0100 Subject: [PATCH 21/58] [ot] hw/opentitan: ot_pwrmgr: ensure only one reset req. can be scheduled Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_pwrmgr.c | 9 +++++++++ hw/opentitan/trace-events | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index 98511c326d46..f01969e2c745 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -209,6 +209,7 @@ typedef struct { } OtPwrMgrRomStatus; typedef enum { + OT_PWRMGR_NO_DOMAIN, OT_PWRMGR_SLOW_DOMAIN, OT_PWRMGR_FAST_DOMAIN, } OtPwrMgrClockDomain; @@ -436,10 +437,13 @@ static void ot_pwrmgr_rst_req(void *opaque, int irq, int level) if (s->regs[R_RESET_STATUS]) { /* do nothing if a reset is already in progress */ /* TODO: is it true for HW vs. SW request ?*/ + trace_ot_pwrmgr_ignore_req("reset on-going"); return; } s->regs[R_RESET_STATUS] |= rstmask; + g_assert(s->reset_req.domain == OT_PWRMGR_NO_DOMAIN); + switch (irq) { case OT_PWRMGR_RST_SYSRST: s->reset_req.req = OT_RSTMGR_RESET_SYSCTRL; @@ -481,10 +485,14 @@ static void ot_pwrmgr_sw_rst_req(void *opaque, int irq, int level) if (s->regs[R_RESET_STATUS]) { /* do nothing if a reset is already in progress */ + trace_ot_pwrmgr_ignore_req("reset on-going"); return; } + s->regs[R_RESET_STATUS] |= rstbit; + g_assert(s->reset_req.domain == OT_PWRMGR_NO_DOMAIN); + s->reset_req.req = OT_RSTMGR_RESET_SW; s->reset_req.domain = OT_PWRMGR_FAST_DOMAIN; @@ -593,6 +601,7 @@ static void ot_pwrmgr_fast_fsm_tick(OtPwrMgrState *s) PWR_CHANGE_FAST_STATE(s, RESET_WAIT); ot_rstmgr_reset_req(s->rstmgr, (bool)s->reset_req.domain, s->reset_req.req); + s->reset_req.domain = OT_PWRMGR_NO_DOMAIN; break; /* NOLINTNEXTLINE */ case OT_PWR_FAST_ST_RESET_WAIT: diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index c7597d462e5b..e38543c6c8ae 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -279,6 +279,7 @@ ot_pinmux_io_write(uint32_t addr, uint32_t val, uint32_t pc) "addr=0x%02x, val=0 # ot_pwrmgr.c ot_pwrmgr_change_state(const char *id, int line, const char *type, const char *old, int nold, const char *new, int nnew) "%s @ %d %s: [%s:%d] -> [%s:%d]" +ot_pwrmgr_ignore_req(const char *reason) "%s" ot_pwrmgr_io_read_out(const char *id, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "%s: addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_pwrmgr_io_write(const char *id, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "%s: addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_pwrmgr_reset(const char *id) "%s" From f56c3324add25e4fbb97d876a9a875d6dbfe88b5 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 14 Feb 2024 23:02:38 +0100 Subject: [PATCH 22/58] [ot] hw/opentitan: ot_pwrmgr: rework event management Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_pwrmgr.c | 149 +++++++++++++++++--------------------- hw/opentitan/trace-events | 2 + 2 files changed, 68 insertions(+), 83 deletions(-) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index f01969e2c745..f19633edd63a 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -156,10 +156,6 @@ static const char *REG_NAMES[REGS_COUNT] = { }; #undef REG_NAME_ENTRY -/* not a real register, but a way to store incoming signals */ -SHARED_FIELD(INPUTS_LC, 0u, 1u) -SHARED_FIELD(INPUTS_OTP, 1u, 1u) - typedef enum { OT_PWRMGR_INIT_OTP, OT_PWRMGR_INIT_LC_CTRL, @@ -219,6 +215,21 @@ typedef struct { OtPwrMgrClockDomain domain; } OtPwrMgrResetReq; +typedef union { + uint32_t bitmap; + struct { + uint8_t hw_reset : 1; /* HW reset request */ + uint8_t sw_reset : 1; /* SW reset request */ + uint8_t otp_done : 1; + uint8_t lc_done : 1; + uint8_t rom_good; /* up to 8 ROMs */ + uint8_t rom_done; /* up to 8 ROMs */ + }; +} OtPwrMgrEvents; + +static_assert(sizeof(OtPwrMgrEvents) == sizeof(uint32_t), + "Invalid OtPwrMgrEvents definition"); + struct OtPwrMgrState { SysBusDevice parent_obj; @@ -233,12 +244,10 @@ struct OtPwrMgrState { OtPwrMgrFastState f_state; OtPwrMgrSlowState s_state; - unsigned fsm_event_count; - uint32_t inputs; + OtPwrMgrEvents fsm_events; uint32_t *regs; OtPwrMgrResetReq reset_req; - OtPwrMgrRomStatus *roms; char *ot_id; OtRstMgrState *rstmgr; @@ -355,26 +364,14 @@ static void ot_pwrmgr_update_irq(OtPwrMgrState *s) ibex_irq_set(&s->irq, (int)(bool)level); } -static void ot_pwrmgr_fsm_push_event(OtPwrMgrState *s, bool trigger) -{ - s->fsm_event_count += 1u; - if (trigger) { - qemu_bh_schedule(s->fsm_tick_bh); - } -} - -static void ot_pwrmgr_fsm_pop_event(OtPwrMgrState *s) -{ - g_assert(s->fsm_event_count); - - s->fsm_event_count -= 1u; -} +#define ot_pwrmgr_schedule_fsm(_s_) \ + ot_pwrmgr_xschedule_fsm(_s_, __func__, __LINE__) -static void ot_pwrmgr_fsm_schedule(OtPwrMgrState *s) +static void ot_pwrmgr_xschedule_fsm(OtPwrMgrState *s, const char *func, + int line) { - if (s->fsm_event_count) { - qemu_bh_schedule(s->fsm_tick_bh); - } + trace_ot_pwrmgr_schedule_fsm(func, line); + qemu_bh_schedule(s->fsm_tick_bh); } static void ot_pwrmgr_cdc_sync(void *opaque) @@ -390,11 +387,12 @@ static void ot_pwrmgr_rom_good(void *opaque, int n, int level) g_assert((unsigned)n < s->num_rom); - s->roms[n].good = level; + trace_ot_pwrmgr_rom(s->ot_id, n, "good", level); - trace_ot_pwrmgr_rom(s->ot_id, n, "good", s->roms[n].good); - - ot_pwrmgr_fsm_push_event(s, true); + if (level) { + s->fsm_events.rom_good |= 1u << n; + ot_pwrmgr_schedule_fsm(s); + } } static void ot_pwrmgr_rom_done(void *opaque, int n, int level) @@ -403,11 +401,12 @@ static void ot_pwrmgr_rom_done(void *opaque, int n, int level) g_assert((unsigned)n < s->num_rom); - s->roms[n].done = level; - - trace_ot_pwrmgr_rom(s->ot_id, n, "done", s->roms[n].done); + trace_ot_pwrmgr_rom(s->ot_id, n, "done", level); - ot_pwrmgr_fsm_push_event(s, true); + if (level) { + s->fsm_events.rom_done |= 1u << n; + ot_pwrmgr_schedule_fsm(s); + } } static void ot_pwrmgr_wkup(void *opaque, int irq, int level) @@ -460,7 +459,8 @@ static void ot_pwrmgr_rst_req(void *opaque, int irq, int level) trace_ot_pwrmgr_reset_req(s->ot_id, "scheduling reset", src); - ot_pwrmgr_fsm_push_event(s, true); + s->fsm_events.hw_reset = true; + ot_pwrmgr_schedule_fsm(s); } } @@ -497,7 +497,9 @@ static void ot_pwrmgr_sw_rst_req(void *opaque, int irq, int level) s->reset_req.domain = OT_PWRMGR_FAST_DOMAIN; trace_ot_pwrmgr_reset_req(s->ot_id, "scheduling SW reset", 0); - ot_pwrmgr_fsm_push_event(s, true); + + s->fsm_events.sw_reset = true; + ot_pwrmgr_schedule_fsm(s); } } @@ -520,20 +522,18 @@ static void ot_pwrmgr_fast_fsm_tick(OtPwrMgrState *s) switch (s->f_state) { case OT_PWR_FAST_ST_LOW_POWER: PWR_CHANGE_FAST_STATE(s, ENABLE_CLOCKS); - ot_pwrmgr_fsm_push_event(s, false); break; case OT_PWR_FAST_ST_ENABLE_CLOCKS: PWR_CHANGE_FAST_STATE(s, RELEASE_LC_RST); // TODO: need to release ROM controllers from reset here to emulate // they are clocked and start to verify their contents. - ot_pwrmgr_fsm_push_event(s, false); break; case OT_PWR_FAST_ST_RELEASE_LC_RST: PWR_CHANGE_FAST_STATE(s, OTP_INIT); ibex_irq_set(&s->pwr_otp_req, (int)true); break; case OT_PWR_FAST_ST_OTP_INIT: - if (s->inputs & INPUTS_OTP_MASK) { + if (s->fsm_events.otp_done) { /* release the request signal */ ibex_irq_set(&s->pwr_otp_req, (int)false); PWR_CHANGE_FAST_STATE(s, LC_INIT); @@ -541,7 +541,7 @@ static void ot_pwrmgr_fast_fsm_tick(OtPwrMgrState *s) } break; case OT_PWR_FAST_ST_LC_INIT: - if (s->inputs & INPUTS_LC_MASK) { + if (s->fsm_events.lc_done) { /* release the request signal */ ibex_irq_set(&s->pwr_lc_req, (int)false); PWR_CHANGE_FAST_STATE(s, STRAP); @@ -550,45 +550,30 @@ static void ot_pwrmgr_fast_fsm_tick(OtPwrMgrState *s) case OT_PWR_FAST_ST_STRAP: // TODO: need to sample straps PWR_CHANGE_FAST_STATE(s, ACK_PWR_UP); - ot_pwrmgr_fsm_push_event(s, false); break; case OT_PWR_FAST_ST_ACK_PWR_UP: PWR_CHANGE_FAST_STATE(s, ROM_CHECK_DONE); - ot_pwrmgr_fsm_push_event(s, false); break; case OT_PWR_FAST_ST_ROM_CHECK_DONE: - for (unsigned ix = 0; ix < s->num_rom; ix++) { - if (!s->roms[ix].done) { - break; - } + if (s->fsm_events.rom_done == (1u << s->num_rom) - 1u) { + PWR_CHANGE_FAST_STATE(s, ROM_CHECK_GOOD); } - PWR_CHANGE_FAST_STATE(s, ROM_CHECK_GOOD); break; - case OT_PWR_FAST_ST_ROM_CHECK_GOOD: { - bool success = true; - for (unsigned ix = 0; ix < s->num_rom; ix++) { - if (!s->roms[ix].good) { - success = false; - break; - } - } - if (success) { + case OT_PWR_FAST_ST_ROM_CHECK_GOOD: + if (s->fsm_events.rom_good == (1u << s->num_rom) - 1u) { PWR_CHANGE_FAST_STATE(s, ACTIVE); - ot_pwrmgr_fsm_push_event(s, false); } - } break; + break; case OT_PWR_FAST_ST_ACTIVE: if (!s->regs[R_RESET_STATUS]) { ibex_irq_set(&s->cpu_enable, (int)true); } else { ibex_irq_set(&s->cpu_enable, (int)false); PWR_CHANGE_FAST_STATE(s, DIS_CLKS); - ot_pwrmgr_fsm_push_event(s, false); } break; case OT_PWR_FAST_ST_DIS_CLKS: PWR_CHANGE_FAST_STATE(s, RESET_PREP); - ot_pwrmgr_fsm_push_event(s, false); break; case OT_PWR_FAST_ST_FALL_THROUGH: case OT_PWR_FAST_ST_NVM_IDLE_CHK: @@ -596,8 +581,8 @@ static void ot_pwrmgr_fast_fsm_tick(OtPwrMgrState *s) case OT_PWR_FAST_ST_NVM_SHUT_DOWN: qemu_log_mask(LOG_UNIMP, "%s: low power modes are not implemented\n", __func__); - break; - case OT_PWR_FAST_ST_RESET_PREP: /* fallthrough */ + /* fallthrough */ + case OT_PWR_FAST_ST_RESET_PREP: PWR_CHANGE_FAST_STATE(s, RESET_WAIT); ot_rstmgr_reset_req(s->rstmgr, (bool)s->reset_req.domain, s->reset_req.req); @@ -617,14 +602,16 @@ static void ot_pwrmgr_fsm_tick(void *opaque) { OtPwrMgrState *s = opaque; - ot_pwrmgr_fsm_pop_event(s); - ot_pwrmgr_slow_fsm_tick(s); - ot_pwrmgr_fast_fsm_tick(s); - if (s->f_state != OT_PWR_FAST_ST_INVALID && - s->s_state != OT_PWR_SLOW_ST_INVALID) { - ot_pwrmgr_fsm_schedule(s); + OtPwrMgrFastState f_state = s->f_state; + ot_pwrmgr_fast_fsm_tick(s); + if (f_state != s->f_state) { + /* schedule FSM update once more if its state has changed */ + ot_pwrmgr_schedule_fsm(s); + } else { + /* otherwise, go idle and wait for an external event */ + trace_ot_pwrmgr_go_idle(s->ot_id, FST_NAME(s->f_state)); } } @@ -638,9 +625,9 @@ static void ot_pwrmgr_pwr_lc_rsp(void *opaque, int n, int level) g_assert(n == 0); - if (level == 1) { - s->inputs |= INPUTS_LC_MASK; - ot_pwrmgr_fsm_push_event(s, true); + if (level) { + s->fsm_events.lc_done = true; + ot_pwrmgr_schedule_fsm(s); } } @@ -650,9 +637,9 @@ static void ot_pwrmgr_pwr_otp_rsp(void *opaque, int n, int level) g_assert(n == 0); - if (level == 1) { - s->inputs |= INPUTS_OTP_MASK; - ot_pwrmgr_fsm_push_event(s, true); + if (level) { + s->fsm_events.otp_done = true; + ot_pwrmgr_schedule_fsm(s); } } @@ -827,9 +814,7 @@ static void ot_pwrmgr_reset(DeviceState *dev) s->regs[R_CONTROL] = 0x180u; s->regs[R_WAKEUP_EN_REGWEN] = 0x1u; s->regs[R_RESET_EN_REGWEN] = 0x1u; - - s->inputs = 0; - s->fsm_event_count = 0; + s->fsm_events.bitmap = 0; PWR_CHANGE_FAST_STATE(s, LOW_POWER); PWR_CHANGE_SLOW_STATE(s, RESET); @@ -840,9 +825,7 @@ static void ot_pwrmgr_reset(DeviceState *dev) ibex_irq_set(&s->pwr_lc_req, 0); ibex_irq_set(&s->alert, 0); - memset(s->roms, 0, s->num_rom * sizeof(OtPwrMgrRomStatus)); - - ot_pwrmgr_fsm_push_event(s, true); + ot_pwrmgr_schedule_fsm(s); } static void ot_pwrmgr_realize(DeviceState *dev, Error **errp) @@ -851,14 +834,14 @@ static void ot_pwrmgr_realize(DeviceState *dev, Error **errp) (void)errp; if (s->num_rom) { - s->roms = g_new0(OtPwrMgrRomStatus, s->num_rom); - + if (s->num_rom > 8u * sizeof(uint8_t)) { + error_setg(&error_fatal, "too many ROMs\n"); + g_assert_not_reached(); + } qdev_init_gpio_in_named(dev, &ot_pwrmgr_rom_good, OT_PWRMGR_ROM_GOOD, s->num_rom); qdev_init_gpio_in_named(dev, &ot_pwrmgr_rom_done, OT_PWRMGR_ROM_DONE, s->num_rom); - } else { - s->roms = NULL; } } diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index e38543c6c8ae..0f528c427dc1 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -279,6 +279,7 @@ ot_pinmux_io_write(uint32_t addr, uint32_t val, uint32_t pc) "addr=0x%02x, val=0 # ot_pwrmgr.c ot_pwrmgr_change_state(const char *id, int line, const char *type, const char *old, int nold, const char *new, int nnew) "%s @ %d %s: [%s:%d] -> [%s:%d]" +ot_pwrmgr_go_idle(const char *id, const char *state) "%s: %s" ot_pwrmgr_ignore_req(const char *reason) "%s" ot_pwrmgr_io_read_out(const char *id, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "%s: addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_pwrmgr_io_write(const char *id, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "%s: addr=0x%02x (%s), val=0x%x, pc=0x%x" @@ -286,6 +287,7 @@ ot_pwrmgr_reset(const char *id) "%s" ot_pwrmgr_reset_req(const char *id, const char *name, unsigned val) "%s: %s: %u" ot_pwrmgr_rom(const char *id, int n, const char *what, bool val) "%s rom #%u %s=%u" ot_pwrmgr_rst_req(const char *id, const char *name, unsigned src) "%s %s(%u)" +ot_pwrmgr_schedule_fsm(const char *func, int line) "@ %s:%d" ot_pwrmgr_sw_rst_req(const char *id, unsigned src, bool active) "%s: %u: %u" ot_pwrmgr_wkup(const char *id, const char *name, unsigned src, bool active) "%s: %s(%u): %u" From e3cfc32532f3f4d328c71e513f295dc169847f03 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 16 Feb 2024 18:39:22 +0100 Subject: [PATCH 23/58] [ot] hw/opentitan: ot_pwrmgr: add a custom extension to hold on Ibex fetch This extension is disabled by default. To enable it, `fetch-ctrl` property should be set. If set, Power Manager IRQ `OT_PWRMGR_HOLDON_FETCH` should be reset to enable the Power Manager Fast FSM to move to the ACTIVE state. Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_pwrmgr.c | 21 ++++++++++++++++++++- include/hw/opentitan/ot_pwrmgr.h | 3 +++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index f19633edd63a..67a73663c9dd 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -222,6 +222,7 @@ typedef union { uint8_t sw_reset : 1; /* SW reset request */ uint8_t otp_done : 1; uint8_t lc_done : 1; + uint8_t holdon_fetch : 1; /* custom extension */ uint8_t rom_good; /* up to 8 ROMs */ uint8_t rom_done; /* up to 8 ROMs */ }; @@ -252,6 +253,7 @@ struct OtPwrMgrState { char *ot_id; OtRstMgrState *rstmgr; uint8_t num_rom; + bool fetch_ctrl; }; #define PWRMGR_NAME_ENTRY(_pre_, _name_) [_pre_##_##_name_] = stringify(_name_) @@ -560,7 +562,8 @@ static void ot_pwrmgr_fast_fsm_tick(OtPwrMgrState *s) } break; case OT_PWR_FAST_ST_ROM_CHECK_GOOD: - if (s->fsm_events.rom_good == (1u << s->num_rom) - 1u) { + if ((s->fsm_events.rom_good == (1u << s->num_rom) - 1u) && + !s->fsm_events.holdon_fetch) { PWR_CHANGE_FAST_STATE(s, ACTIVE); } break; @@ -643,6 +646,16 @@ static void ot_pwrmgr_pwr_otp_rsp(void *opaque, int n, int level) } } +static void ot_pwrmgr_holdon_fetch(void *opaque, int n, int level) +{ + OtPwrMgrState *s = opaque; + + g_assert(n == 0); + + s->fsm_events.holdon_fetch = (bool)level; + ot_pwrmgr_schedule_fsm(s); +} + static uint64_t ot_pwrmgr_regs_read(void *opaque, hwaddr addr, unsigned size) { OtPwrMgrState *s = opaque; @@ -784,6 +797,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64, static Property ot_pwrmgr_properties[] = { DEFINE_PROP_STRING("ot_id", OtPwrMgrState, ot_id), DEFINE_PROP_UINT8("num-rom", OtPwrMgrState, num_rom, 0), + DEFINE_PROP_BOOL("fetch-ctrl", OtPwrMgrState, fetch_ctrl, false), DEFINE_PROP_LINK("rstmgr", OtPwrMgrState, rstmgr, TYPE_OT_RSTMGR, OtRstMgrState *), DEFINE_PROP_END_OF_LIST(), @@ -815,6 +829,7 @@ static void ot_pwrmgr_reset(DeviceState *dev) s->regs[R_WAKEUP_EN_REGWEN] = 0x1u; s->regs[R_RESET_EN_REGWEN] = 0x1u; s->fsm_events.bitmap = 0; + s->fsm_events.holdon_fetch = s->fetch_ctrl; PWR_CHANGE_FAST_STATE(s, LOW_POWER); PWR_CHANGE_SLOW_STATE(s, RESET); @@ -842,6 +857,10 @@ static void ot_pwrmgr_realize(DeviceState *dev, Error **errp) s->num_rom); qdev_init_gpio_in_named(dev, &ot_pwrmgr_rom_done, OT_PWRMGR_ROM_DONE, s->num_rom); + if (s->fetch_ctrl) { + qdev_init_gpio_in_named(dev, &ot_pwrmgr_holdon_fetch, + OT_PWRMGR_HOLDON_FETCH, 1u); + } } } diff --git a/include/hw/opentitan/ot_pwrmgr.h b/include/hw/opentitan/ot_pwrmgr.h index e3b47c1847f9..224e0d3d589d 100644 --- a/include/hw/opentitan/ot_pwrmgr.h +++ b/include/hw/opentitan/ot_pwrmgr.h @@ -67,4 +67,7 @@ typedef enum { #define OT_PWRMGR_ROM_GOOD TYPE_OT_PWRMGR "-rom-good" #define OT_PWRMGR_ROM_DONE TYPE_OT_PWRMGR "-rom-done" +/* custom extension */ +#define OT_PWRMGR_HOLDON_FETCH TYPE_OT_PWRMGR "-holdon-fetch" + #endif /* HW_OPENTITAN_OT_PWRMGR_H */ From 64b5074db9ac7c5ba7abba4316fb20fd606f023c Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 20 Feb 2024 14:28:02 +0100 Subject: [PATCH 24/58] [ot] hw/opentitan: ot_pwgmgr: use Resettable reset management. Reset is not a transient state but is now stateful. Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_pwrmgr.c | 47 ++++++++++++++++++++++++++------ hw/opentitan/trace-events | 4 +-- include/hw/opentitan/ot_pwrmgr.h | 2 +- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index 67a73663c9dd..1a4090f5e4ef 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -256,6 +256,11 @@ struct OtPwrMgrState { bool fetch_ctrl; }; +struct OtPwrMgrClass { + SysBusDeviceClass parent_class; + ResettablePhases parent_phases; +}; + #define PWRMGR_NAME_ENTRY(_pre_, _name_) [_pre_##_##_name_] = stringify(_name_) #define FAST_ST_NAME_ENTRY(_name_) PWRMGR_NAME_ENTRY(OT_PWR_FAST_ST, _name_) @@ -372,7 +377,7 @@ static void ot_pwrmgr_update_irq(OtPwrMgrState *s) static void ot_pwrmgr_xschedule_fsm(OtPwrMgrState *s, const char *func, int line) { - trace_ot_pwrmgr_schedule_fsm(func, line); + trace_ot_pwrmgr_schedule_fsm(s->ot_id, func, line); qemu_bh_schedule(s->fsm_tick_bh); } @@ -811,13 +816,18 @@ static const MemoryRegionOps ot_pwrmgr_regs_ops = { .impl.max_access_size = 4u, }; -static void ot_pwrmgr_reset(DeviceState *dev) +static void ot_pwrmgr_reset_enter(Object *obj, ResetType type) { - OtPwrMgrState *s = OT_PWRMGR(dev); + OtPwrMgrClass *c = OT_PWRMGR_GET_CLASS(obj); + OtPwrMgrState *s = OT_PWRMGR(obj); g_assert(s->ot_id); - trace_ot_pwrmgr_reset(s->ot_id); + trace_ot_pwrmgr_reset(s->ot_id, "enter"); + + if (c->parent_phases.enter) { + c->parent_phases.enter(obj, type); + } assert(s->rstmgr); @@ -839,6 +849,18 @@ static void ot_pwrmgr_reset(DeviceState *dev) ibex_irq_set(&s->pwr_otp_req, 0); ibex_irq_set(&s->pwr_lc_req, 0); ibex_irq_set(&s->alert, 0); +} + +static void ot_pwrmgr_reset_exit(Object *obj) +{ + OtPwrMgrClass *c = OT_PWRMGR_GET_CLASS(obj); + OtPwrMgrState *s = OT_PWRMGR(obj); + + trace_ot_pwrmgr_reset(s->ot_id, "exit"); + + if (c->parent_phases.exit) { + c->parent_phases.exit(obj); + } ot_pwrmgr_schedule_fsm(s); } @@ -857,10 +879,11 @@ static void ot_pwrmgr_realize(DeviceState *dev, Error **errp) s->num_rom); qdev_init_gpio_in_named(dev, &ot_pwrmgr_rom_done, OT_PWRMGR_ROM_DONE, s->num_rom); - if (s->fetch_ctrl) { - qdev_init_gpio_in_named(dev, &ot_pwrmgr_holdon_fetch, - OT_PWRMGR_HOLDON_FETCH, 1u); - } + } + + if (s->fetch_ctrl) { + qdev_init_gpio_in_named(dev, &ot_pwrmgr_holdon_fetch, + OT_PWRMGR_HOLDON_FETCH, 1u); } } @@ -901,9 +924,14 @@ static void ot_pwrmgr_class_init(ObjectClass *klass, void *data) (void)data; dc->realize = &ot_pwrmgr_realize; - dc->reset = &ot_pwrmgr_reset; device_class_set_props(dc, ot_pwrmgr_properties); set_bit(DEVICE_CATEGORY_MISC, dc->categories); + + ResettableClass *rc = RESETTABLE_CLASS(dc); + OtPwrMgrClass *pc = OT_PWRMGR_CLASS(klass); + resettable_class_set_parent_phases(rc, &ot_pwrmgr_reset_enter, NULL, + &ot_pwrmgr_reset_exit, + &pc->parent_phases); } static const TypeInfo ot_pwrmgr_info = { @@ -912,6 +940,7 @@ static const TypeInfo ot_pwrmgr_info = { .instance_size = sizeof(OtPwrMgrState), .instance_init = &ot_pwrmgr_init, .class_init = &ot_pwrmgr_class_init, + .class_size = sizeof(OtPwrMgrClass) }; static void ot_pwrmgr_register_types(void) diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 0f528c427dc1..e605f0233734 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -283,11 +283,11 @@ ot_pwrmgr_go_idle(const char *id, const char *state) "%s: %s" ot_pwrmgr_ignore_req(const char *reason) "%s" ot_pwrmgr_io_read_out(const char *id, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "%s: addr=0x%02x (%s), val=0x%x, pc=0x%x" ot_pwrmgr_io_write(const char *id, uint32_t addr, const char * regname, uint32_t val, uint32_t pc) "%s: addr=0x%02x (%s), val=0x%x, pc=0x%x" -ot_pwrmgr_reset(const char *id) "%s" +ot_pwrmgr_reset(const char *id, const char *action) "%s: %s" ot_pwrmgr_reset_req(const char *id, const char *name, unsigned val) "%s: %s: %u" ot_pwrmgr_rom(const char *id, int n, const char *what, bool val) "%s rom #%u %s=%u" ot_pwrmgr_rst_req(const char *id, const char *name, unsigned src) "%s %s(%u)" -ot_pwrmgr_schedule_fsm(const char *func, int line) "@ %s:%d" +ot_pwrmgr_schedule_fsm(const char *id, const char *func, int line) "%s @ %s:%d" ot_pwrmgr_sw_rst_req(const char *id, unsigned src, bool active) "%s: %u: %u" ot_pwrmgr_wkup(const char *id, const char *name, unsigned src, bool active) "%s: %s(%u): %u" diff --git a/include/hw/opentitan/ot_pwrmgr.h b/include/hw/opentitan/ot_pwrmgr.h index 224e0d3d589d..bbfd214c8adc 100644 --- a/include/hw/opentitan/ot_pwrmgr.h +++ b/include/hw/opentitan/ot_pwrmgr.h @@ -32,7 +32,7 @@ #include "qom/object.h" #define TYPE_OT_PWRMGR "ot-pwrmgr" -OBJECT_DECLARE_SIMPLE_TYPE(OtPwrMgrState, OT_PWRMGR) +OBJECT_DECLARE_TYPE(OtPwrMgrState, OtPwrMgrClass, OT_PWRMGR) /* Match PWRMGR_PARAM_*_WKUP_REQ_IDX definitions */ typedef enum { From eb5e2f80f68f66f3d86af2738e2aa0ad9e37c437 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 20 Feb 2024 15:56:23 +0100 Subject: [PATCH 25/58] [ot] hw/opentitan: ot_pwrmgr: handle EarlGrey and Darjeeling variations. Power Manager has diverged between OpenTitan variants. Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_pwrmgr.c | 125 +++++++++++++++++++++---------- hw/riscv/ot_darjeeling.c | 25 +++++-- hw/riscv/ot_earlgrey.c | 16 ++-- include/hw/opentitan/ot_pwrmgr.h | 13 ++-- 4 files changed, 123 insertions(+), 56 deletions(-) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index 1a4090f5e4ef..6f5a28ba049e 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -119,6 +119,9 @@ REG32(FAULT_STATUS, 0x40u) #define CDC_SYNC_PULSE_DURATION_NS 100000u /* 100us */ +#define PWRMGR_WAKEUP_MAX 6u +#define PWRMGR_RESET_MAX 3u + /* Verbatim definitions from RTL */ #define NUM_SW_RST_REQ 1u #define HW_RESET_WIDTH \ @@ -211,8 +214,8 @@ typedef enum { } OtPwrMgrClockDomain; typedef struct { - OtRstMgrResetReq req; OtPwrMgrClockDomain domain; + int req; } OtPwrMgrResetReq; typedef union { @@ -253,6 +256,7 @@ struct OtPwrMgrState { char *ot_id; OtRstMgrState *rstmgr; uint8_t num_rom; + uint8_t version; bool fetch_ctrl; }; @@ -312,31 +316,77 @@ static const char *SLOW_ST_NAMES[] = { #define SST_NAME(_st_) \ ((_st_) < ARRAY_SIZE(SLOW_ST_NAMES) ? SLOW_ST_NAMES[(_st_)] : "?") -#define WAKEUP_NAME_ENTRY(_name_) PWRMGR_NAME_ENTRY(OT_PWRMGR_WAKEUP, _name_) +typedef struct { + unsigned wakeup_count; + unsigned reset_count; +} OtPwrMgrConfig; + /* clang-format off */ -static const char *WAKEUP_NAMES[] = { - WAKEUP_NAME_ENTRY(SYSRST), - WAKEUP_NAME_ENTRY(ADC_CTRL), - WAKEUP_NAME_ENTRY(PINMUX), - WAKEUP_NAME_ENTRY(USBDEV), - WAKEUP_NAME_ENTRY(AON_TIMER), - WAKEUP_NAME_ENTRY(SENSOR), +static const OtPwrMgrConfig PWRMGR_CONFIG[OT_PWMGR_VERSION_COUNT] = { + [OT_PWMGR_VERSION_EG] = { + .wakeup_count = 6u, + .reset_count = 3u, + }, + [OT_PWMGR_VERSION_DJ] = { + .wakeup_count = 6u, + .reset_count = 2u, + }, }; -/* clang-format on */ -#undef WAKEUP_NAME_ENTRY -#define WAKEUP_NAME(_clk_) \ - ((_clk_) < ARRAY_SIZE(WAKEUP_NAMES) ? WAKEUP_NAMES[(_clk_)] : "?") -#define RESET_NAME_ENTRY(_name_) PWRMGR_NAME_ENTRY(OT_PWRMGR_RST, _name_) -/* clang-format off */ -static const char *RST_NAMES[] = { - RESET_NAME_ENTRY(SYSRST), - RESET_NAME_ENTRY(AON_TIMER), +static int PWRMGR_RESET_DISPATCH[OT_PWMGR_VERSION_COUNT][PWRMGR_RESET_MAX] = { + [OT_PWMGR_VERSION_EG] = { + [0] = OT_RSTMGR_RESET_SYSCTRL, + [1] = OT_RSTMGR_RESET_AON_TIMER, + [2] = -1 + }, + [OT_PWMGR_VERSION_DJ] = { + [0] = OT_RSTMGR_RESET_AON_TIMER, + [1] = -1, + [2] = -1, + }, +}; + +static const char * +PWRMGR_WAKEUP_NAMES[OT_PWMGR_VERSION_COUNT][PWRMGR_WAKEUP_MAX] = { + [OT_PWMGR_VERSION_EG] = { + [0] = "SYSRST", + [1] = "ADC_CTRL", + [2] = "PINMUX", + [3] = "USBDEV", + [4] = "AON_TIMER", + [5] = "SENSOR", + }, + [OT_PWMGR_VERSION_DJ] = { + [0] = "PINMUX", + [1] = "USBDEV", + [2] = "AON_TIMER", + [3] = "SENSOR", + [4] = "SOC_PROXY_INT", + [5] = "SOC_PROXY_EXT", + }, +}; + +static const char *PWRMGR_RST_NAMES[OT_PWMGR_VERSION_COUNT][PWRMGR_RESET_MAX] = { + [OT_PWMGR_VERSION_EG] = { + [0] = "SYSRST", + [1] = "AON_TIMER", + [2] = "SENSOR", + }, + [OT_PWMGR_VERSION_DJ] = { + [0] = "AON_TIMER", + [1] = "SOC_PROXY", + } }; /* clang-format on */ -#undef RESET_NAME_ENTRY -#define RST_NAME(_clk_) \ - ((_clk_) < ARRAY_SIZE(RST_NAMES) ? RST_NAMES[(_clk_)] : "?") + +#define WAKEUP_NAME(_s_, _w_) \ + ((_w_) < PWRMGR_CONFIG[(_s_)->version].wakeup_count ? \ + PWRMGR_WAKEUP_NAMES[(_s_)->version][(_w_)] : \ + "?") +#define RST_NAME(_s_, _r_) \ + ((_r_) < PWRMGR_CONFIG[(_s_)->version].reset_count ? \ + PWRMGR_RST_NAMES[(_s_)->version][(_r_)] : \ + "?") #undef PWRMGR_NAME_ENTRY @@ -421,11 +471,9 @@ static void ot_pwrmgr_wkup(void *opaque, int irq, int level) OtPwrMgrState *s = opaque; unsigned src = (unsigned)irq; - assert(src < OT_PWRMGR_WAKEUP_COUNT); - - qemu_log_mask(LOG_UNIMP, "%s", __func__); + assert(src < PWRMGR_WAKEUP_MAX); - trace_ot_pwrmgr_wkup(s->ot_id, WAKEUP_NAME(src), src, (bool)level); + trace_ot_pwrmgr_wkup(s->ot_id, WAKEUP_NAME(s, src), src, (bool)level); } static void ot_pwrmgr_rst_req(void *opaque, int irq, int level) @@ -433,12 +481,12 @@ static void ot_pwrmgr_rst_req(void *opaque, int irq, int level) OtPwrMgrState *s = opaque; unsigned src = (unsigned)irq; - g_assert(src < OT_PWRMGR_RST_COUNT); + g_assert(src < PWRMGR_CONFIG[s->version].reset_count); uint32_t rstmask = 1u << src; /* rst_req are stored in the LSBs */ if (level) { - trace_ot_pwrmgr_rst_req(s->ot_id, RST_NAME(src), src); + trace_ot_pwrmgr_rst_req(s->ot_id, RST_NAME(s, src), src); if (s->regs[R_RESET_STATUS]) { /* do nothing if a reset is already in progress */ @@ -450,19 +498,14 @@ static void ot_pwrmgr_rst_req(void *opaque, int irq, int level) g_assert(s->reset_req.domain == OT_PWRMGR_NO_DOMAIN); - switch (irq) { - case OT_PWRMGR_RST_SYSRST: - s->reset_req.req = OT_RSTMGR_RESET_SYSCTRL; - s->reset_req.domain = OT_PWRMGR_SLOW_DOMAIN; - break; - case OT_PWRMGR_RST_AON_TIMER: - s->reset_req.req = OT_RSTMGR_RESET_AON_TIMER; - s->reset_req.domain = OT_PWRMGR_SLOW_DOMAIN; - break; - default: + s->reset_req.domain = OT_PWRMGR_SLOW_DOMAIN; + + int req = PWRMGR_RESET_DISPATCH[s->version][src]; + if (req < 0) { + /* not yet implemented */ g_assert_not_reached(); - break; } + s->reset_req.req = req; trace_ot_pwrmgr_reset_req(s->ot_id, "scheduling reset", src); @@ -802,6 +845,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64, static Property ot_pwrmgr_properties[] = { DEFINE_PROP_STRING("ot_id", OtPwrMgrState, ot_id), DEFINE_PROP_UINT8("num-rom", OtPwrMgrState, num_rom, 0), + DEFINE_PROP_UINT8("version", OtPwrMgrState, version, UINT8_MAX), DEFINE_PROP_BOOL("fetch-ctrl", OtPwrMgrState, fetch_ctrl, false), DEFINE_PROP_LINK("rstmgr", OtPwrMgrState, rstmgr, TYPE_OT_RSTMGR, OtRstMgrState *), @@ -822,6 +866,7 @@ static void ot_pwrmgr_reset_enter(Object *obj, ResetType type) OtPwrMgrState *s = OT_PWRMGR(obj); g_assert(s->ot_id); + g_assert(s->version < OT_PWMGR_VERSION_COUNT); trace_ot_pwrmgr_reset(s->ot_id, "enter"); @@ -905,9 +950,9 @@ static void ot_pwrmgr_init(Object *obj) s->cdc_sync = timer_new_ns(OT_VIRTUAL_CLOCK, &ot_pwrmgr_cdc_sync, s); qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_wkup, OT_PWRMGR_WKUP, - OT_PWRMGR_WAKEUP_COUNT); + PWRMGR_WAKEUP_MAX); qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_rst_req, OT_PWRMGR_RST, - OT_PWRMGR_RST_COUNT); + PWRMGR_RESET_MAX); qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_sw_rst_req, OT_PWRMGR_SW_RST, NUM_SW_RST_REQ); qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_pwr_lc_rsp, diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index 307049289f87..d76cd546cb04 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -152,6 +152,22 @@ enum OtDjSocDevice { OT_DJ_SOC_SPLITTER_LC_ESCALATE, }; +enum OtDjResetRequest { + OT_DJ_RESET_AON_TIMER, + OT_DJ_RESET_SOC_PROXY, + OT_DJ_RESET_COUNT, +}; + +enum OtDjResetWakeup { + OT_DJ_WAKEUP_PINMUX_AON_PIN, + OT_DJ_WAKEUP_PINMUX_AON_USB, + OT_DJ_WAKEUP_AON_TIMER_AON, + OT_DJ_WAKEUP_SENSOR_CTRL, + OT_DJ_WAKEUP_SOC_PROXY_INTERNAL, + OT_DJ_WAKEUP_SOC_PROXY_EXTERNAL, + OT_DJ_WAKEUP_COUNT, +}; + /* Darjeeling Peripheral clock is 62.5 MHz */ #define OT_DJ_PERIPHERAL_CLK_HZ 62500000u @@ -899,7 +915,8 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { OT_DJ_SOC_DEVLINK("rstmgr", RSTMGR) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("num-rom", 2u) + IBEX_DEV_UINT_PROP("num-rom", 2u), + IBEX_DEV_UINT_PROP("version", OT_PWMGR_VERSION_DJ) ), }, [OT_DJ_SOC_DEV_RSTMGR] = { @@ -933,11 +950,9 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { OT_DJ_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 79), OT_DJ_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 80), OT_DJ_SOC_SIGNAL(OT_AON_TIMER_WKUP, 0, PWRMGR, - OT_PWRMGR_WKUP, - OT_PWRMGR_WAKEUP_AON_TIMER), + OT_PWRMGR_WKUP, OT_PWRMGR_WAKEUP_AON_TIMER), OT_DJ_SOC_SIGNAL(OT_AON_TIMER_BITE, 0, PWRMGR, - OT_PWRMGR_RST, - OT_PWRMGR_RST_AON_TIMER) + OT_PWRMGR_RST, OT_DJ_RESET_AON_TIMER) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("pclk", OT_DJ_AON_CLK_HZ) diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index 25c8bb951cf1..60889a7b5120 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -131,6 +131,13 @@ enum OtEGSocDevice { OT_EG_SOC_DEV_USBDEV, }; +enum OtEgResetRequest { + OT_EG_RESET_SYSRST_CTRL, + OT_EG_RESET_AON_TIMER, + OT_EG_RESET_SENSOR_CTRL, + OT_EG_RESET_COUNT +}; + /* EarlGrey/CW310 Peripheral clock is 2.5 MHz */ #define OT_EG_PERIPHERAL_CLK_HZ 2500000u @@ -554,7 +561,8 @@ static const IbexDeviceDef ot_eg_soc_devices[] = { OT_IBEX_PWRMGR_CPU_EN) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("num-rom", 1u) + IBEX_DEV_UINT_PROP("num-rom", 1u), + IBEX_DEV_UINT_PROP("version", OT_PWMGR_VERSION_EG) ), .link = IBEXDEVICELINKDEFS( OT_EG_SOC_DEVLINK("rstmgr", RSTMGR) @@ -615,11 +623,9 @@ static const IbexDeviceDef ot_eg_soc_devices[] = { OT_EG_SOC_GPIO_SYSBUS_IRQ(0, PLIC, 155), OT_EG_SOC_GPIO_SYSBUS_IRQ(1, PLIC, 156), OT_EG_SOC_SIGNAL(OT_AON_TIMER_WKUP, 0, PWRMGR, \ - OT_PWRMGR_WKUP, \ - OT_PWRMGR_WAKEUP_AON_TIMER), + OT_PWRMGR_WKUP, OT_PWRMGR_WAKEUP_AON_TIMER), OT_EG_SOC_SIGNAL(OT_AON_TIMER_BITE, 0, PWRMGR, \ - OT_PWRMGR_RST, - OT_PWRMGR_RST_AON_TIMER) + OT_PWRMGR_RST, OT_EG_RESET_AON_TIMER) ), .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("pclk", OT_EG_AON_CLK_HZ) diff --git a/include/hw/opentitan/ot_pwrmgr.h b/include/hw/opentitan/ot_pwrmgr.h index bbfd214c8adc..44fb15820535 100644 --- a/include/hw/opentitan/ot_pwrmgr.h +++ b/include/hw/opentitan/ot_pwrmgr.h @@ -34,6 +34,13 @@ #define TYPE_OT_PWRMGR "ot-pwrmgr" OBJECT_DECLARE_TYPE(OtPwrMgrState, OtPwrMgrClass, OT_PWRMGR) +/* Supported PowerManager versions */ +typedef enum { + OT_PWMGR_VERSION_EG, + OT_PWMGR_VERSION_DJ, + OT_PWMGR_VERSION_COUNT, +} OtPwrMgrVersion; + /* Match PWRMGR_PARAM_*_WKUP_REQ_IDX definitions */ typedef enum { OT_PWRMGR_WAKEUP_SYSRST, @@ -45,12 +52,6 @@ typedef enum { OT_PWRMGR_WAKEUP_COUNT, } OtPwrMgrWakeup; -typedef enum { - OT_PWRMGR_RST_SYSRST, - OT_PWRMGR_RST_AON_TIMER, /* watchdog bite */ - OT_PWRMGR_RST_COUNT, -} OtPwrMgrRst; - /* output lines */ #define OT_PWRMGR_LC_REQ TYPE_OT_PWRMGR "-lc-req" #define OT_PWRMGR_OTP_REQ TYPE_OT_PWRMGR "-otp-req" From dcb5a90c927256cd689f229d1a2af73286af4de4 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 23 Feb 2024 18:24:31 +0100 Subject: [PATCH 26/58] [ot] hw/riscv: Implement resettable interface for OT Darjeeling machine Signed-off-by: Emmanuel Blot --- hw/riscv/ot_darjeeling.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index d76cd546cb04..37770b9eb084 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -72,6 +72,7 @@ #include "hw/riscv/ot_darjeeling.h" #include "hw/ssi/ssi.h" #include "sysemu/blockdev.h" +#include "sysemu/reset.h" #include "sysemu/sysemu.h" /* ------------------------------------------------------------------------ */ @@ -1033,6 +1034,8 @@ struct OtDjBoardState { struct OtDjMachineState { MachineState parent_obj; + ResettableState reset; + bool no_epmp_cfg; }; @@ -1372,6 +1375,27 @@ static void ot_dj_machine_set_no_epmp_cfg(Object *obj, bool value, Error **errp) s->no_epmp_cfg = value; } +static void ot_dj_machine_transitional_reset(Object *obj) +{ + (void)obj; + + qemu_devices_reset(SHUTDOWN_CAUSE_GUEST_RESET); +} + +static ResettableTrFunction ot_dj_get_transitional_reset(Object *obj) +{ + (void)obj; + + return ot_dj_machine_transitional_reset; +} + +static ResettableState *ot_dj_get_reset_state(Object *obj) +{ + OtDjMachineState *s = RISCV_OT_DJ_MACHINE(obj); + + return &s->reset; +} + static void ot_dj_machine_instance_init(Object *obj) { OtDjMachineState *s = RISCV_OT_DJ_MACHINE(obj); @@ -1400,6 +1424,11 @@ static void ot_dj_machine_class_init(ObjectClass *oc, void *data) mc->init = ot_dj_machine_init; mc->max_cpus = 1u; mc->default_cpus = 1u; + + ResettableClass *rc = RESETTABLE_CLASS(oc); + + rc->get_state = &ot_dj_get_reset_state; + rc->get_transitional_function = &ot_dj_get_transitional_reset; } static const TypeInfo ot_dj_machine_type_info = { @@ -1408,6 +1437,7 @@ static const TypeInfo ot_dj_machine_type_info = { .instance_size = sizeof(OtDjMachineState), .instance_init = &ot_dj_machine_instance_init, .class_init = &ot_dj_machine_class_init, + .interfaces = (InterfaceInfo[]){ { TYPE_RESETTABLE_INTERFACE }, {} }, }; static void ot_dj_machine_register_types(void) From d92079f13feead74dc36c7acafd28c5e3ea0621a Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 14:27:33 +0100 Subject: [PATCH 27/58] [ot] hw/opentitan: ot_mbx: fix host & sys mailbox apertures Signed-off-by: Emmanuel Blot --- include/hw/opentitan/ot_mbx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/hw/opentitan/ot_mbx.h b/include/hw/opentitan/ot_mbx.h index 59c38bdea0ac..3a9661d84445 100644 --- a/include/hw/opentitan/ot_mbx.h +++ b/include/hw/opentitan/ot_mbx.h @@ -37,8 +37,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(OtMbxState, OT_MBX) #define OT_MBX_SYS_REGS_COUNT 6u #define OT_MBX_HOST_APERTURE \ - DIV_ROUND_UP((OT_MBX_HOST_REGS_COUNT * sizeof(uint32_t)), 0x10u) + ROUND_UP((OT_MBX_HOST_REGS_COUNT * sizeof(uint32_t)), 0x10u) #define OT_MBX_SYS_APERTURE \ - DIV_ROUND_UP((OT_MBX_SYS_REGS_COUNT * sizeof(uint32_t)), 0x10u) + ROUND_UP((OT_MBX_SYS_REGS_COUNT * sizeof(uint32_t)), 0x10u) #endif /* HW_OPENTITAN_OT_MBX_H */ From 7c3e1073c19c1a6ad692f52d47dfa3f733a6b6cc Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 8 Feb 2024 19:29:24 +0100 Subject: [PATCH 28/58] [ot] hw/riscv: ot_darjeeling: set DMI abits to 12 Signed-off-by: Emmanuel Blot --- hw/riscv/ot_darjeeling.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index 37770b9eb084..9c99453ad7ed 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -348,8 +348,7 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { [OT_DJ_SOC_DEV_DMI] = { .type = TYPE_RISCV_DMI, .prop = IBEXDEVICEPROPDEFS( - /* should be a constant, need to encode 0x500 */ - IBEX_DEV_UINT_PROP("abits", 11u) + IBEX_DEV_UINT_PROP("abits", 12u) ), }, [OT_DJ_SOC_DEV_DM_TL_MBOX] = { From ee761a5e1fd5b16bfa53b21d41e2ef781e648cac Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:19:57 +0100 Subject: [PATCH 29/58] [ot] hw/riscv: ot_darjeeling: use explicit constants Signed-off-by: Emmanuel Blot --- hw/riscv/ot_darjeeling.c | 74 +++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index 9c99453ad7ed..7788abbdf67c 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -90,14 +90,11 @@ static void ot_dj_soc_uart_configure(DeviceState *dev, const IbexDeviceDef *def, /* Constants */ /* ------------------------------------------------------------------------ */ - -/* CTN address space */ -#define OT_DJ_CTN_REGION_OFFSET 0x40000000u -#define OT_DJ_CTN_REGION_SIZE (1u << 30u) - -/* CTN RAM (1MB) */ -#define OT_DJ_CTN_RAM_ADDR 0x01000000u -#define OT_DJ_CTN_RAM_SIZE (2u << 20u) +enum OtDjMemoryRegion { + OT_DJ_DEFAULT_MEMORY_REGION, + OT_DJ_CTN_MEMORY_REGION, + OT_DJ_DEBUG_MEMORY_REGION, +}; enum OtDjSocDevice { OT_DJ_SOC_DEV_AES, @@ -106,7 +103,7 @@ enum OtDjSocDevice { OT_DJ_SOC_DEV_AST, OT_DJ_SOC_DEV_CLKMGR, OT_DJ_SOC_DEV_CSRNG, - OT_DJ_SOC_DEV_DM_TL_MBOX, + OT_DJ_SOC_DEV_DM_TL_MBX, OT_DJ_SOC_DEV_DMA, OT_DJ_SOC_DEV_DMI, OT_DJ_SOC_DEV_EDN0, @@ -169,14 +166,25 @@ enum OtDjResetWakeup { OT_DJ_WAKEUP_COUNT, }; -/* Darjeeling Peripheral clock is 62.5 MHz */ -#define OT_DJ_PERIPHERAL_CLK_HZ 62500000u +/* CTN address space */ +#define OT_DJ_CTN_REGION_OFFSET 0x40000000u +#define OT_DJ_CTN_REGION_SIZE (1u << 30u) + +/* CTN RAM (1MB) */ +#define OT_DJ_CTN_RAM_ADDR 0x01000000u +#define OT_DJ_CTN_RAM_SIZE (2u << 20u) -/* Darjeeling SPI host clock is 250 MHz */ -#define OT_DJ_SPIHOST_CLK_HZ 250000000u +/* DEBUG address space */ +#define OT_DJ_DEBUG_RV_DM_ADDR 0x2000u +#define OT_DJ_DEBUG_MBX_JTAG_ADDR 0x2200u +#define OT_DJ_DEBUG_SOCDBG_CTRL_ADDR 0x2300u +#define OT_DJ_DEBUG_LC_CTRL_ADDR 0x3000u +#define OT_DJ_DEBUG_LC_CTRL_SIZE 0x400u +#define OT_DJ_DBG_XBAR_SIZE 0x4000u -/* Darjeeling AON clock is 62.5 MHz */ -#define OT_DJ_AON_CLK_HZ 62500000u +#define OT_DJ_PERIPHERAL_CLK_HZ 62500000u +#define OT_DJ_SPIHOST_CLK_HZ 250000000u +#define OT_DJ_AON_CLK_HZ 62500000u static const uint8_t ot_dj_pmp_cfgs[] = { /* clang-format off */ @@ -222,12 +230,6 @@ static const uint32_t ot_dj_pmp_addrs[] = { #define OT_DJ_MSECCFG IBEX_MSECCFG(1, 1, 0) -enum OtDjMemoryRegion { - OT_DJ_DEFAULT_MEMORY_REGION, - OT_DJ_CTN_MEMORY_REGION, - OT_DJ_DEBUG_MEMORY_REGION, -}; - #define OT_DJ_SOC_GPIO(_irq_, _target_, _num_) \ IBEX_GPIO(_irq_, OT_DJ_SOC_DEV_##_target_, _num_) @@ -309,11 +311,19 @@ enum OtDjMemoryRegion { #define OT_DJ_XPORT_MEMORY(_addr_) \ IBEX_MEMMAP_MAKE_REG((_addr_), OT_DJ_CTN_MEMORY_REGION) -#define OT_DJ_DBG_XBAR_APERTURE 0x2000u - #define DEBUG_MEMORY(_addr_) \ IBEX_MEMMAP_MAKE_REG((_addr_), OT_DJ_DEBUG_MEMORY_REGION) +#define OT_DJ_DEBUG_TL_TO_DMI(_val_) ((_val_) / sizeof(uint32_t)) + +#define OT_DJ_DEBUG_LC_CTRL_DMI_ADDR \ + OT_DJ_DEBUG_TL_TO_DMI(OT_DJ_DEBUG_LC_CTRL_ADDR) +#define OT_DJ_DEBUG_LC_CTRL_DMI_SIZE \ + OT_DJ_DEBUG_TL_TO_DMI(OT_DJ_DEBUG_LC_CTRL_SIZE) +#define OT_DJ_DEBUG_MBX_JTAG_DMI_ADDR \ + OT_DJ_DEBUG_TL_TO_DMI(OT_DJ_DEBUG_MBX_JTAG_ADDR) +#define OT_DJ_DEBUG_MBX_JTAG_DMI_SIZE (OT_MBX_SYS_APERTURE / sizeof(uint32_t)) + /* * Darjeeling RV DM * see https://github.com/lowRISC/part-number-registry/blob/main/jtag_partno.md @@ -351,16 +361,16 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { IBEX_DEV_UINT_PROP("abits", 12u) ), }, - [OT_DJ_SOC_DEV_DM_TL_MBOX] = { + [OT_DJ_SOC_DEV_DM_TL_MBX] = { .type = TYPE_OT_DM_TL, .link = IBEXDEVICELINKDEFS( OT_DJ_SOC_DEVLINK("dmi", DMI), OT_DJ_SOC_DEVLINK("tl_dev", MBX_JTAG) ), .prop = IBEXDEVICEPROPDEFS( - IBEX_DEV_UINT_PROP("dmi_addr", 0x400u), - IBEX_DEV_UINT_PROP("dmi_size", OT_MBX_SYS_REGS_COUNT), - IBEX_DEV_UINT_PROP("tl_addr", 0x1000u), + IBEX_DEV_UINT_PROP("dmi_addr", OT_DJ_DEBUG_MBX_JTAG_DMI_ADDR), + IBEX_DEV_UINT_PROP("dmi_size", OT_DJ_DEBUG_MBX_JTAG_DMI_SIZE), + IBEX_DEV_UINT_PROP("tl_addr", OT_DJ_DEBUG_MBX_JTAG_ADDR), IBEX_DEV_STRING_PROP("tl_as_name", "ot-dbg") ) }, @@ -602,7 +612,7 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { }, [OT_DJ_SOC_DEV_MBX_JTAG] = { OT_DJ_SOC_DEV_MBX_DUAL(7, 0x22000800u, 155, - DEBUG_MEMORY(0x1000)), + DEBUG_MEMORY(OT_DJ_DEBUG_MBX_JTAG_ADDR)), }, [OT_DJ_SOC_DEV_DMA] = { .type = TYPE_OT_DMA, @@ -809,7 +819,8 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { [OT_DJ_SOC_DEV_LC_CTRL] = { .type = TYPE_OT_LC_CTRL, .memmap = MEMMAPENTRIES( - { 0x30140000u, 0x100u } + { 0x30140000u, 0x100u }, + { DEBUG_MEMORY(OT_DJ_DEBUG_LC_CTRL_ADDR), OT_DJ_DEBUG_LC_CTRL_SIZE } ), .gpio = IBEXGPIOCONNDEFS( OT_DJ_SOC_D2S(OT_LC_BROADCAST, OT_LC_HW_DEBUG_EN, @@ -1106,7 +1117,7 @@ static void ot_dj_soc_reset_hold(Object *obj) Object *dmi = OBJECT(s->devices[OT_DJ_SOC_DEV_DMI]); resettable_reset(dmi, RESET_TYPE_COLD); - resettable_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_DM_TL_MBOX]), + resettable_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_DM_TL_MBX]), RESET_TYPE_COLD); /* keep ROM_CTRLs in reset, we'll release them last */ @@ -1164,8 +1175,7 @@ static void ot_dj_soc_realize(DeviceState *dev, Error **errp) AddressSpace *ctn_as = ot_address_space_get(OT_ADDRESS_SPACE(oas)); MemoryRegion *dbg_mr = g_new0(MemoryRegion, 1u); - memory_region_init(dbg_mr, OBJECT(dev), "dbg-xbar", - OT_DJ_DBG_XBAR_APERTURE); + memory_region_init(dbg_mr, OBJECT(dev), "dbg-xbar", OT_DJ_DBG_XBAR_SIZE); MemoryRegion *mrs[IBEX_MEMMAP_REGIDX_COUNT] = { [OT_DJ_DEFAULT_MEMORY_REGION] = cpu->memory, From 2554f967dad3125411e3831841a4179e423c8744 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:04:10 +0100 Subject: [PATCH 30/58] [ot] hw/riscv: ot_darjeeling: add LC_CTRL DMI Signed-off-by: Emmanuel Blot --- hw/riscv/ot_darjeeling.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index 7788abbdf67c..2bb506b0f6f4 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -103,6 +103,7 @@ enum OtDjSocDevice { OT_DJ_SOC_DEV_AST, OT_DJ_SOC_DEV_CLKMGR, OT_DJ_SOC_DEV_CSRNG, + OT_DJ_SOC_DEV_DM_TL_LC_CTRL, OT_DJ_SOC_DEV_DM_TL_MBX, OT_DJ_SOC_DEV_DMA, OT_DJ_SOC_DEV_DMI, @@ -361,8 +362,23 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { IBEX_DEV_UINT_PROP("abits", 12u) ), }, + [OT_DJ_SOC_DEV_DM_TL_LC_CTRL] = { + .type = TYPE_OT_DM_TL, + .instance = 0, + .link = IBEXDEVICELINKDEFS( + OT_DJ_SOC_DEVLINK("dmi", DMI), + OT_DJ_SOC_DEVLINK("tl_dev", LC_CTRL) + ), + .prop = IBEXDEVICEPROPDEFS( + IBEX_DEV_UINT_PROP("dmi_addr", OT_DJ_DEBUG_LC_CTRL_DMI_ADDR), + IBEX_DEV_UINT_PROP("dmi_size", OT_DJ_DEBUG_LC_CTRL_DMI_SIZE), + IBEX_DEV_UINT_PROP("tl_addr", OT_DJ_DEBUG_LC_CTRL_ADDR), + IBEX_DEV_STRING_PROP("tl_as_name", "ot-dbg") + ) + }, [OT_DJ_SOC_DEV_DM_TL_MBX] = { .type = TYPE_OT_DM_TL, + .instance = 1, .link = IBEXDEVICELINKDEFS( OT_DJ_SOC_DEVLINK("dmi", DMI), OT_DJ_SOC_DEVLINK("tl_dev", MBX_JTAG) @@ -1117,6 +1133,9 @@ static void ot_dj_soc_reset_hold(Object *obj) Object *dmi = OBJECT(s->devices[OT_DJ_SOC_DEV_DMI]); resettable_reset(dmi, RESET_TYPE_COLD); + // TODO: not sure where Reset is plugged here... + resettable_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_DM_TL_LC_CTRL]), + RESET_TYPE_COLD); resettable_reset(OBJECT(s->devices[OT_DJ_SOC_DEV_DM_TL_MBX]), RESET_TYPE_COLD); From 735faece2fc5d7d5424bc627892026a3ca8a38c6 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 12 Feb 2024 12:31:07 +0100 Subject: [PATCH 31/58] [ot] jtag: jtag_bitbang: fix idcode handling - idcode could only be read once - simplify TDO response - improve JTAG traces - code clean up Signed-off-by: Emmanuel Blot --- jtag/jtag_bitbang.c | 60 ++++++++++++++++++++++++--------------------- jtag/trace-events | 14 ++++++----- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/jtag/jtag_bitbang.c b/jtag/jtag_bitbang.c index 4d3c1be2e7bb..57d7cbc51d82 100644 --- a/jtag/jtag_bitbang.c +++ b/jtag/jtag_bitbang.c @@ -55,7 +55,7 @@ * Type definitions */ -typedef enum _TAPState { +typedef enum { TEST_LOGIC_RESET, RUN_TEST_IDLE, SELECT_DR_SCAN, @@ -75,6 +75,8 @@ typedef enum _TAPState { _TAP_STATE_COUNT } TAPState; +typedef enum { TAPCTRL_BYPASS = 0, TAPCTRL_IDCODE = 1 } TAPCtrlKnownIrCodes; + typedef TAPDataHandler *tapctrl_data_reg_extender_t(uint64_t value); typedef struct _TAPController { @@ -96,8 +98,6 @@ typedef struct _TAPController { TAPDataHandler *tdh; /* Current data register handler */ TAPDataHandler *tdhs; /* Registered handlers */ /* buffer */ - uint8_t *outbuf; /* TDO output */ - size_t outpos; /* Meaningful count of bytes in outbuf */ } TAPController; typedef struct _TAPRegisterState { @@ -111,11 +111,6 @@ typedef struct _TAPProcess { bool attached; } TAPProcess; -enum RSState { - RS_INACTIVE, - RS_IDLE, -}; - typedef struct _TAPServerState { TAPController *tap; CharBackend chr; @@ -172,15 +167,19 @@ static const char TAPFSM_NAMES[_TAP_STATE_COUNT][18U] = { NAME_FSMSTATE(EXIT2_IR), NAME_FSMSTATE(UPDATE_IR), }; +static void tapctrl_idcode_capture(TAPDataHandler *tdh); + /* Common TAP instructions */ static const TAPDataHandler tapctrl_bypass = { .name = "bypass", .length = 1, .value = 0, }; + static const TAPDataHandler tapctrl_idcode = { .name = "idcode", .length = 32, + .capture = &tapctrl_idcode_capture, }; /* @@ -208,7 +207,13 @@ static void tapctrl_dump_register(const char *msg, uint64_t value, } buf[ix] = '\0'; - trace_jtag_tapctr_dump_register(msg, value, length, buf); + trace_jtag_tapctrl_dump_register(msg, value, length, buf); +} + +static void tapctrl_idcode_capture(TAPDataHandler *tdh) +{ + /* special case for ID code: opaque contains the ID code value */ + tdh->value = (uint64_t)(uintptr_t)tdh->opaque; } static void tapctrl_reset(TAPController *tap) @@ -225,7 +230,6 @@ static void tapctrl_reset(TAPController *tap) tap->dr = 0u; tap->dr_len = 0u; tap->tdh = &tap->tdhs[tap->ir]; - tap->outpos = 0u; } static void tapctrl_register_handler(TAPController *tap, unsigned code, @@ -241,26 +245,23 @@ static void tapctrl_register_handler(TAPController *tap, unsigned code, static void tapctrl_init(TAPController *tap, size_t irlength, uint32_t idcode) { + trace_jtag_tapctrl_init(irlength, idcode); + tap->ir_len = irlength; tapctrl_reset(tap); - if (!tap->outbuf) { - tap->outbuf = g_new0(uint8_t, MAX_PACKET_LENGTH); - tap->outpos = 0; - } if (!tap->tdhs) { size_t irslots = 1u << irlength; tap->tdhs = g_new0(TAPDataHandler, irslots); - tapctrl_register_handler(tap, 0x00, &tapctrl_bypass); - tapctrl_register_handler(tap, 0x01, &tapctrl_idcode); + tapctrl_register_handler(tap, TAPCTRL_BYPASS, &tapctrl_bypass); + tapctrl_register_handler(tap, TAPCTRL_IDCODE, &tapctrl_idcode); tapctrl_register_handler(tap, irslots - 1u, &tapctrl_bypass); - tap->tdhs[0x01].value = idcode; + /* special case for ID code: opaque store the constant idcode value */ + tap->tdhs[TAPCTRL_IDCODE].opaque = (void *)(uintptr_t)idcode; } } static void tapctrl_deinit(TAPController *tap) { - g_free(tap->outbuf); - tap->outbuf = NULL; if (tap->tdhs) { unsigned irslots = 1 << tap->ir_len; for (unsigned ix = 0; ix < irslots; ix++) { @@ -272,6 +273,7 @@ static void tapctrl_deinit(TAPController *tap) } g_free(tap->tdhs); tap->tdhs = NULL; + tap->tdh = NULL; } static TAPState tapctrl_get_next_state(TAPController *tap, bool tms) @@ -317,7 +319,7 @@ static void tapctrl_capture_dr(TAPController *tap, uint64_t value) } if (tdh != prev) { - trace_jtag_tapctr_select_dr(tdh->name, value); + trace_jtag_tapctrl_select_dr(tdh->name, value); } tap->tdh = tdh; @@ -408,7 +410,7 @@ static void tapctrl_bb_blink(TAPController *tap, bool light) {} static void tapctrl_bb_read(TAPController *tap) { - tap->outbuf[tap->outpos++] = '0' + (unsigned)tap->tdo; + (void)tap; } static void tapctrl_bb_quit(TAPController *tap) @@ -435,7 +437,7 @@ static void tapctrl_bb_reset(TAPController *tap, bool trst, bool srst) * TAP Server implementation */ -static void tap_read_byte(uint8_t ch) +static bool tap_read_byte(uint8_t ch) { switch ((char)ch) { case 'B': @@ -491,6 +493,9 @@ static void tap_read_byte(uint8_t ch) (unsigned)ch); break; } + + /* true if TDO level should be sent to the peer */ + return (int)ch == 'R'; } static int tap_chr_can_receive(void *opaque) @@ -504,12 +509,11 @@ static void tap_chr_receive(void *opaque, const uint8_t *buf, int size) TAPServerState *s = (TAPServerState *)opaque; for (unsigned ix = 0; ix < size; ix++) { - tap_read_byte(buf[ix]); - } - - if (s->tap->outpos) { - qemu_chr_fe_write_all(&s->chr, s->tap->outbuf, (int)s->tap->outpos); - s->tap->outpos = 0u; + if (tap_read_byte(buf[ix])) { + const TAPController *tap = s->tap; + uint8_t outbuf[1] = { '0' + (unsigned)tap->tdo }; + qemu_chr_fe_write_all(&s->chr, outbuf, (int)sizeof(outbuf)); + } } } diff --git a/jtag/trace-events b/jtag/trace-events index 9c7642df0473..b141ab845dd1 100644 --- a/jtag/trace-events +++ b/jtag/trace-events @@ -1,8 +1,10 @@ -# JTAG -jtag_tapctrl_register(unsigned code, const char *name) "register %u: %s" -jtag_tapctrl_reset(bool tap, bool sys) "tap: %u, system: %u" -jtag_tapctrl_change_state(const char *prev, const char *new) "%s -> %s" +# jtag_bitbang.c + jtag_tapctrl_change(const char *msg, const char *value) "%s %s" +jtag_tapctrl_change_state(const char *prev, const char *new) "%s -> %s" +jtag_tapctrl_dump_register(const char *msg, uint64_t val, size_t len, const char *buf) "%s: 0x%016" PRIx64 "/%zu [%s]" +jtag_tapctrl_init(size_t irlen, uint32_t ircode) "irlength %zu, idcode 0x%08x" +jtag_tapctrl_register(unsigned code, const char *name) "register 0x%x: %s" +jtag_tapctrl_reset(bool tap, bool sys) "tap: %u, system: %u" +jtag_tapctrl_select_dr(const char *name, uint64_t value) "Select DR %s 0x%02" PRIx64 jtag_tapctrl_step(bool tck, bool tms, bool tdi) "tck:%u tms:%u tdi:%u" -jtag_tapctr_dump_register(const char *msg, uint64_t val, size_t len, const char *buf) "%s: 0x%016" PRIx64 "/%zu [%s]" -jtag_tapctr_select_dr(const char *name, uint64_t value) "Select DR %s 0x%02" PRIx64 From f2627c728c1228b70a8863ce984a4e8613280919 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 12 Feb 2024 17:17:11 +0100 Subject: [PATCH 32/58] [ot] hw/riscv: add a trace for DTM reset Signed-off-by: Emmanuel Blot --- hw/riscv/dmi.c | 1 + hw/riscv/trace-events | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/riscv/dmi.c b/hw/riscv/dmi.c index 8f7c6a557182..d5ca6945ef75 100644 --- a/hw/riscv/dmi.c +++ b/hw/riscv/dmi.c @@ -260,6 +260,7 @@ static void riscv_dmi_tap_dtmcs_update(TAPDataHandler *tdh) RISCVDMIState *s = tdh->opaque; if (tdh->value & (1u << 16u)) { /* dmireset */ + trace_riscv_dmi_dtmcs_reset(); s->dmistat = RISCV_DEBUG_NOERR; } if (tdh->value & (1u << 17u)) { diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events index aeb3e48cdc91..5f963b3d1cc7 100644 --- a/hw/riscv/trace-events +++ b/hw/riscv/trace-events @@ -1,4 +1,5 @@ # Debug Module Interface +riscv_dmi_dtmcs_reset(void) "" riscv_dmi_error(const char *func, int line, const char *msg) "%s:%d %s" riscv_dmi_info(const char *func, int line, const char *msg, uint32_t val) "%s:%d %s 0x%08x" riscv_dmi_register_dm(unsigned count, uint64_t first, uint64_t last, bool ok) "#%u 0x%" PRIx64 "..0x%" PRIx64 ": %u" From a12f442455b6cc36b66eb18d73a519c7ef8bee70 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:32:24 +0100 Subject: [PATCH 33/58] [ot] jtag: quit VM on JTAG bitbang request. Signed-off-by: Emmanuel Blot --- jtag/jtag_bitbang.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jtag/jtag_bitbang.c b/jtag/jtag_bitbang.c index 57d7cbc51d82..7dad1104f97c 100644 --- a/jtag/jtag_bitbang.c +++ b/jtag/jtag_bitbang.c @@ -415,7 +415,11 @@ static void tapctrl_bb_read(TAPController *tap) static void tapctrl_bb_quit(TAPController *tap) { - tapctrl_reset(tap); + (void)tap; + + qemu_log("%s: JTAG-requested termination\n", __func__); + + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } static void tapctrl_bb_write(TAPController *tap, bool tck, bool tms, bool tdi) From 9ada186fbff3e7b6219825700effd8b74233e2d6 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 14 Feb 2024 16:17:29 +0100 Subject: [PATCH 34/58] [ot] jtag: use an hash_table for storing data handlers Signed-off-by: Emmanuel Blot --- jtag/jtag_bitbang.c | 98 +++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/jtag/jtag_bitbang.c b/jtag/jtag_bitbang.c index 7dad1104f97c..410d353bfa23 100644 --- a/jtag/jtag_bitbang.c +++ b/jtag/jtag_bitbang.c @@ -55,6 +55,8 @@ * Type definitions */ +/* clang-format off */ + typedef enum { TEST_LOGIC_RESET, RUN_TEST_IDLE, @@ -77,6 +79,8 @@ typedef enum { typedef enum { TAPCTRL_BYPASS = 0, TAPCTRL_IDCODE = 1 } TAPCtrlKnownIrCodes; +/* clang-format on */ + typedef TAPDataHandler *tapctrl_data_reg_extender_t(uint64_t value); typedef struct _TAPController { @@ -96,7 +100,7 @@ typedef struct _TAPController { size_t dr_len; /* count of meaningful bits in dr */ /* handlers */ TAPDataHandler *tdh; /* Current data register handler */ - TAPDataHandler *tdhs; /* Registered handlers */ + GHashTable *tdhtable; /* Registered handlers */ /* buffer */ } TAPController; @@ -210,6 +214,20 @@ static void tapctrl_dump_register(const char *msg, uint64_t value, trace_jtag_tapctrl_dump_register(msg, value, length, buf); } +static bool tapctrl_has_data_handler(TAPController *tap, unsigned code) +{ + return (bool)g_hash_table_contains(tap->tdhtable, GINT_TO_POINTER(code)); +} + +static TAPDataHandler * +tapctrl_get_data_handler(TAPController *tap, unsigned code) +{ + TAPDataHandler *tdh; + tdh = (TAPDataHandler *)g_hash_table_lookup(tap->tdhtable, + GINT_TO_POINTER(code)); + return tdh; +} + static void tapctrl_idcode_capture(TAPDataHandler *tdh) { /* special case for ID code: opaque contains the ID code value */ @@ -229,50 +247,63 @@ static void tapctrl_reset(TAPController *tap) tap->ir_hold = 0b01; tap->dr = 0u; tap->dr_len = 0u; - tap->tdh = &tap->tdhs[tap->ir]; + tap->tdh = tapctrl_get_data_handler(tap, TAPCTRL_IDCODE); + g_assert(tap->tdh); } static void tapctrl_register_handler(TAPController *tap, unsigned code, const TAPDataHandler *tdh) { - memcpy(&tap->tdhs[code], tdh, sizeof(*tdh)); if (code >= (1 << tap->ir_len)) { error_setg(&error_fatal, "JTAG: Invalid IR code: 0x%x", code); + g_assert_not_reached(); + } + if (tapctrl_has_data_handler(tap, code)) { + warn_report("JTAG: IR code already registered: 0x%x", code); + /* resume and override */ + } + TAPDataHandler *ltdh = g_new0(TAPDataHandler, 1u); + memcpy(ltdh, tdh, sizeof(*tdh)); + ltdh->name = g_strdup(tdh->name); + g_hash_table_insert(tap->tdhtable, GINT_TO_POINTER(code), ltdh); + trace_jtag_tapctrl_register(code, ltdh->name); +} + +static void tapctrl_free_data_handler(gpointer entry) +{ + TAPDataHandler *tdh = entry; + if (!entry) { + return; } - tap->tdhs[code].name = g_strdup(tdh->name); - trace_jtag_tapctrl_register(code, tap->tdhs[code].name); + g_free((char *)tdh->name); + g_free(tdh); } static void tapctrl_init(TAPController *tap, size_t irlength, uint32_t idcode) { trace_jtag_tapctrl_init(irlength, idcode); - tap->ir_len = irlength; - tapctrl_reset(tap); - if (!tap->tdhs) { + if (!tap->tdhtable) { size_t irslots = 1u << irlength; - tap->tdhs = g_new0(TAPDataHandler, irslots); + tap->tdhtable = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, tapctrl_free_data_handler); tapctrl_register_handler(tap, TAPCTRL_BYPASS, &tapctrl_bypass); tapctrl_register_handler(tap, TAPCTRL_IDCODE, &tapctrl_idcode); tapctrl_register_handler(tap, irslots - 1u, &tapctrl_bypass); /* special case for ID code: opaque store the constant idcode value */ - tap->tdhs[TAPCTRL_IDCODE].opaque = (void *)(uintptr_t)idcode; + TAPDataHandler *tdh = tapctrl_get_data_handler(tap, TAPCTRL_IDCODE); + g_assert(tdh); + tdh->opaque = (void *)(uintptr_t)idcode; } + tapctrl_reset(tap); } static void tapctrl_deinit(TAPController *tap) { - if (tap->tdhs) { - unsigned irslots = 1 << tap->ir_len; - for (unsigned ix = 0; ix < irslots; ix++) { - if (tap->tdhs[ix].name) { - g_free((char *)tap->tdhs[ix].name); - tap->tdhs[ix].name = NULL; - } - } + if (tap->tdhtable) { + g_hash_table_destroy(tap->tdhtable); + tap->tdhtable = NULL; } - g_free(tap->tdhs); - tap->tdhs = NULL; tap->tdh = NULL; } @@ -284,7 +315,7 @@ static TAPState tapctrl_get_next_state(TAPController *tap, bool tms) static void tapctrl_capture_ir(TAPController *tap) { - tap->ir = 0b01; + tap->ir = TAPCTRL_IDCODE; } static void tapctrl_shift_ir(TAPController *tap, bool tdi) @@ -299,27 +330,26 @@ static void tapctrl_update_ir(TAPController *tap) tapctrl_dump_register("Update IR", tap->ir_hold, tap->ir_len); } -static void tapctrl_capture_dr(TAPController *tap, uint64_t value) +static void tapctrl_capture_dr(TAPController *tap) { TAPDataHandler *prev = tap->tdh; - if (value >= (1 << tap->ir_len)) { - qemu_log_mask(LOG_UNIMP, "%s: Invalid IR 0x%02x\n", __func__, - (unsigned)value); - abort(); - return; + if (tap->ir_hold >= (1 << tap->ir_len)) { + /* internal error, should never happen */ + error_setg(&error_fatal, "Invalid IR 0x%02x\n", (unsigned)tap->ir_hold); + g_assert_not_reached(); } - TAPDataHandler *tdh = &tap->tdhs[value]; - if (!tdh->length) { - qemu_log_mask(LOG_UNIMP, "%s: Unknown IR 0x%02x\n", __func__, - (unsigned)value); - abort(); + TAPDataHandler *tdh = tapctrl_get_data_handler(tap, tap->ir_hold); + if (!tdh) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown IR 0x%02x\n", __func__, + (unsigned)tap->ir_hold); + tap->dr = 0; return; } if (tdh != prev) { - trace_jtag_tapctrl_select_dr(tdh->name, value); + trace_jtag_tapctrl_select_dr(tdh->name, tap->ir_hold); } tap->tdh = tdh; @@ -379,7 +409,7 @@ static void tapctrl_step(TAPController *tap, bool tck, bool tms, bool tdi) tapctrl_reset(tap); break; case CAPTURE_DR: - tapctrl_capture_dr(tap, tap->ir_hold); + tapctrl_capture_dr(tap); break; case SHIFT_DR: tap->tdo = tap->dr & 0b1; From 6cf4747867e1edcced40574e46e266af731863d1 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 11:00:18 +0100 Subject: [PATCH 35/58] [ot] scripts/opentitan: create a Python module for OpenTitan tools Signed-off-by: Emmanuel Blot --- scripts/opentitan/ot/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 scripts/opentitan/ot/__init__.py diff --git a/scripts/opentitan/ot/__init__.py b/scripts/opentitan/ot/__init__.py new file mode 100644 index 000000000000..dca8c95e274c --- /dev/null +++ b/scripts/opentitan/ot/__init__.py @@ -0,0 +1,4 @@ +"""OpenTitan modules.""" + +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 From b5f979ca00e59c288c8f43760bd99bd87527748d Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 11:02:08 +0100 Subject: [PATCH 36/58] [ot] scripts/opentitan: add a Python module for log utilities Signed-off-by: Emmanuel Blot --- scripts/opentitan/ot/util/__init__.py | 4 ++ scripts/opentitan/ot/util/log.py | 90 +++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 scripts/opentitan/ot/util/__init__.py create mode 100644 scripts/opentitan/ot/util/log.py diff --git a/scripts/opentitan/ot/util/__init__.py b/scripts/opentitan/ot/util/__init__.py new file mode 100644 index 000000000000..890797d26e79 --- /dev/null +++ b/scripts/opentitan/ot/util/__init__.py @@ -0,0 +1,4 @@ +"""Utilities.""" + +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 diff --git a/scripts/opentitan/ot/util/log.py b/scripts/opentitan/ot/util/log.py new file mode 100644 index 000000000000..cafaa7832b26 --- /dev/null +++ b/scripts/opentitan/ot/util/log.py @@ -0,0 +1,90 @@ +"""Logging helpers. +""" + +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +from logging import (Formatter, Logger, StreamHandler, CRITICAL, DEBUG, INFO, + ERROR, WARNING, getLogger) +from os import isatty +from sys import stderr +from typing import List + + +class ColorLogFormatter(Formatter): + """Custom log formatter for ANSI terminals. + Colorize log levels. + + Optional features: + * 'time' (boolean): prefix log messsages with 24h HH:MM:SS time + * 'ms' (boolean): prefix log messages with 24h HH:MM:SS.msec time + * 'lineno'(boolean): show line numbers + * 'name_width' (int): padding width for logger names + * 'color' (boolean): enable/disable log level colorization + """ + + GREY = "\x1b[38;20m" + YELLOW = "\x1b[33;1m" + RED = "\x1b[31;1m" + MAGENTA = "\x1b[35;1m" + WHITE = "\x1b[37;1m" + RESET = "\x1b[0m" + FMT_LEVEL = '%(levelname)8s' + + COLORS = { + DEBUG: GREY, + INFO: WHITE, + WARNING: YELLOW, + ERROR: RED, + CRITICAL: MAGENTA, + } + + def __init__(self, *args, **kwargs): + kwargs = dict(kwargs) + name_width = kwargs.pop('name_width', 10) + self._use_ansi = kwargs.pop('color', isatty(stderr.fileno())) + use_ms = kwargs.pop('ms', False) + use_time = kwargs.pop('time', use_ms) + use_lineno = kwargs.pop('lineno', False) + super().__init__(*args, **kwargs) + format_trail = f' %(name)-{name_width}s %(message)s' + if use_time: + tfmt = '%(asctime)s ' if not use_ms else '%(asctime)s.%(msecs)03d ' + else: + tfmt = '' + lno = ' [%(lineno)d] ' if use_lineno else '' + self._plain_format = f'{tfmt}{self.FMT_LEVEL}{lno}{format_trail}' + self._color_formats = { + lvl: f'{tfmt}{clr}{self.FMT_LEVEL}{self.RESET}{lno}{format_trail}' + for lvl, clr in self.COLORS.items() + } + self._formatter_args = ['%H:%M:%S'] if use_time else [] + + def format(self, record): + log_fmt = self._color_formats[record.levelno] if self._use_ansi \ + else self._plain_format + formatter = Formatter(log_fmt, *self._formatter_args) + return formatter.format(record) + + +def configure_loggers(level: int, *lognames: List[str], **kwargs) \ + -> List[Logger]: + """Configure loggers. + + :param level: level (stepping: 1) + :param lognames: one or more loggers to configure + :param kwargs: optional features + :return: configured loggers + """ + loglevel = max(DEBUG, ERROR - (10 * (level or 0))) + loglevel = min(ERROR, loglevel) + formatter = ColorLogFormatter(**kwargs) + logh = StreamHandler(stderr) + logh.setFormatter(formatter) + loggers: List[Logger] = [] + for logname in lognames: + log = getLogger(logname) + log.setLevel(loglevel) + log.addHandler(logh) + loggers.append(log) + return loggers From f906e33beb5eae96ef7a7091f43d7f5bfd61b9b0 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 11:03:41 +0100 Subject: [PATCH 37/58] [ot] scripts/opentitan: factorize log configuration using log utility Signed-off-by: Emmanuel Blot --- scripts/opentitan/devproxy.py | 8 +-- scripts/opentitan/flashgen.py | 22 ++++----- scripts/opentitan/gdbreplay.py | 59 ++++------------------ scripts/opentitan/loghelp.py | 22 ++++----- scripts/opentitan/mbbdef.py | 21 ++++---- scripts/opentitan/ot/util/log.py | 13 +++-- scripts/opentitan/otphelp.py | 30 ++++++------ scripts/opentitan/otptool.py | 21 ++++---- scripts/opentitan/pyot.py | 78 +++++++++--------------------- scripts/opentitan/swexit.py | 7 ++- scripts/opentitan/treillis/boot.py | 7 +++ scripts/opentitan/treillis/code.py | 20 +++++--- 12 files changed, 121 insertions(+), 187 deletions(-) diff --git a/scripts/opentitan/devproxy.py b/scripts/opentitan/devproxy.py index a07102235c3e..f7389bd3856b 100644 --- a/scripts/opentitan/devproxy.py +++ b/scripts/opentitan/devproxy.py @@ -1,9 +1,11 @@ -"""Device proxy for OpenTitan devices and peripherals -""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""Device proxy for OpenTitan devices and peripherals + + :author: Emmanuel Blot +""" + from binascii import hexlify, unhexlify from collections import deque from logging import getLogger diff --git a/scripts/opentitan/flashgen.py b/scripts/opentitan/flashgen.py index dcd6308933d6..ad62590d0562 100755 --- a/scripts/opentitan/flashgen.py +++ b/scripts/opentitan/flashgen.py @@ -1,17 +1,19 @@ #!/usr/bin/env python3 -"""Create/update an OpenTitan backend flash file. -""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""Create/update an OpenTitan backend flash file. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser, FileType from binascii import hexlify from hashlib import sha256 from itertools import repeat from io import BytesIO -from logging import DEBUG, ERROR, getLogger, Formatter, StreamHandler +from logging import getLogger from os import SEEK_END, SEEK_SET, rename, stat from os.path import abspath, basename, exists, isfile from re import sub as re_sub @@ -21,6 +23,8 @@ from typing import (Any, BinaryIO, Dict, Iterator, List, NamedTuple, Optional, Tuple, Union) +from ot.util.log import configure_loggers + try: # note: pyelftools package is an OpenTitan toolchain requirement, see # python-requirements.txt file from OT top directory. @@ -826,15 +830,7 @@ def main(): args = argparser.parse_args() debug = args.debug - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = Formatter('%(levelname)8s [%(lineno)d] %(name)-12s ' - '%(message)s') - log = getLogger('flashgen') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + configure_loggers(args.verbose, 'flashgen') use_bl0 = bool(args.boot) or len(args.otdesc) > 1 gen = FlashGen(args.offset if use_bl0 else 0, bool(args.unsafe_elf), diff --git a/scripts/opentitan/gdbreplay.py b/scripts/opentitan/gdbreplay.py index 3710a3dbc0bc..3dfefa6814a1 100755 --- a/scripts/opentitan/gdbreplay.py +++ b/scripts/opentitan/gdbreplay.py @@ -1,27 +1,29 @@ #!/usr/bin/env python3 -"""QEMU GDB replay. -""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""QEMU GDB replay. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser, FileType, Namespace from binascii import hexlify from io import BytesIO -from logging import (Formatter, StreamHandler, CRITICAL, DEBUG, INFO, ERROR, - WARNING, getLogger) -from os import isatty, linesep +from logging import getLogger +from os import linesep from os.path import dirname, isfile, join as joinpath, normpath from re import compile as re_compile from socket import (SOL_SOCKET, SO_REUSEADDR, SHUT_RDWR, socket, timeout as LegacyTimeoutError) from string import ascii_uppercase -from sys import exit as sysexit, modules, stderr, stdout +from sys import exit as sysexit, modules, stderr from traceback import format_exc from typing import (BinaryIO, Dict, Iterator, List, Optional, TextIO, Tuple, Union) +from ot.util.log import configure_loggers try: from elftools.common.exceptions import ELFError @@ -33,40 +35,6 @@ Segment = None -class CustomFormatter(Formatter): - """Custom log formatter for ANSI terminals. Colorize log levels. - """ - - GREY = "\x1b[38;20m" - YELLOW = "\x1b[33;1m" - RED = "\x1b[31;1m" - MAGENTA = "\x1b[35;1m" - WHITE = "\x1b[37;1m" - RESET = "\x1b[0m" - FORMAT_LEVEL = '%(levelname)8s' - FORMAT_TRAIL = ' %(name)-10s %(message)s' - - COLOR_FORMATS = { - DEBUG: f'{GREY}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - INFO: f'{WHITE}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - WARNING: f'{YELLOW}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - ERROR: f'{RED}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - CRITICAL: f'{MAGENTA}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - } - - PLAIN_FORMAT = f'{FORMAT_LEVEL}{FORMAT_TRAIL}' - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._istty = isatty(stdout.fileno()) - - def format(self, record): - log_fmt = self.COLOR_FORMATS[record.levelno] if self._istty \ - else self.PLAIN_FORMAT - formatter = Formatter(log_fmt) - return formatter.format(record) - - class ElfBlob: """Load ELF application.""" @@ -857,14 +825,7 @@ def main(): args = argparser.parse_args() debug = args.debug - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = CustomFormatter() - log = getLogger('gdbrp') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + configure_loggers(args.verbose, 'gdbrp') acount = len(args.address or []) bcount = len(args.bin or []) diff --git a/scripts/opentitan/loghelp.py b/scripts/opentitan/loghelp.py index 2781e9f6f290..8e509976b623 100755 --- a/scripts/opentitan/loghelp.py +++ b/scripts/opentitan/loghelp.py @@ -1,19 +1,23 @@ #!/usr/bin/env python3 -"""Verify register definitions. -""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""Verify register definitions. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser, FileType -from logging import DEBUG, ERROR, getLogger, Formatter, StreamHandler +from logging import getLogger from os.path import basename, splitext from re import compile as re_compile, sub as re_sub from sys import exit as sysexit, modules, stderr from traceback import format_exc from typing import Dict, TextIO, Tuple +from ot.util.log import configure_loggers + REG_CRE = re_compile(r'^#define ([A-Z][\w]+)_REG_(OFFSET|RESVAL)\s+' r'((?:0x)?[A-Fa-f0-9]+)(?:\s|$)') @@ -99,15 +103,7 @@ def main(): args = argparser.parse_args() debug = args.debug - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = Formatter('%(asctime)s.%(msecs)03d %(levelname)8s ' - '%(name)-10s %(message)s', '%H:%M:%S') - log = getLogger('ot') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + configure_loggers(args.verbose, 'ot', ms=True) defs = parse_defs(args.reg) if args.reg else {} check(args.log[0], args.component, defs) diff --git a/scripts/opentitan/mbbdef.py b/scripts/opentitan/mbbdef.py index e988f87a7403..659638991d21 100755 --- a/scripts/opentitan/mbbdef.py +++ b/scripts/opentitan/mbbdef.py @@ -1,13 +1,15 @@ #!/usr/bin/env python3 -"""Find and report multi-bit boolean definitions from HJSON configuration file. -""" - # Copyright (c) 2024, Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""Find and report multi-bit boolean definitions from HJSON configuration file. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser -from logging import DEBUG, ERROR, getLogger, Formatter, StreamHandler +from logging import getLogger from os import walk from os.path import basename, dirname, join as joinpath, splitext from pprint import pprint @@ -15,6 +17,8 @@ from traceback import format_exc from typing import Dict, Iterator, List, TextIO +from ot.util.log import configure_loggers + try: from hjson import load as jload @@ -122,14 +126,7 @@ def main(): args = argparser.parse_args() debug = args.debug - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = Formatter('%(levelname)8s %(name)-10s %(message)s') - log = getLogger('mbb') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + configure_loggers(args.verbose, 'mbb') for hjson in args.ot: mbb = MbbChecker() diff --git a/scripts/opentitan/ot/util/log.py b/scripts/opentitan/ot/util/log.py index cafaa7832b26..6189bf92e71e 100644 --- a/scripts/opentitan/ot/util/log.py +++ b/scripts/opentitan/ot/util/log.py @@ -74,17 +74,20 @@ def configure_loggers(level: int, *lognames: List[str], **kwargs) \ :param level: level (stepping: 1) :param lognames: one or more loggers to configure :param kwargs: optional features - :return: configured loggers + :return: configured loggers or level change """ - loglevel = max(DEBUG, ERROR - (10 * (level or 0))) + loglevel = ERROR - (10 * (level or 0)) loglevel = min(ERROR, loglevel) formatter = ColorLogFormatter(**kwargs) logh = StreamHandler(stderr) logh.setFormatter(formatter) loggers: List[Logger] = [] - for logname in lognames: - log = getLogger(logname) - log.setLevel(loglevel) + for logdef in lognames: + if isinstance(logdef, int): + loglevel += -10 * logdef + continue + log = getLogger(logdef) + log.setLevel(max(DEBUG, loglevel)) log.addHandler(logh) loggers.append(log) return loggers diff --git a/scripts/opentitan/otphelp.py b/scripts/opentitan/otphelp.py index b637a2178c07..97a23578e113 100755 --- a/scripts/opentitan/otphelp.py +++ b/scripts/opentitan/otphelp.py @@ -1,24 +1,30 @@ #!/usr/bin/env python3 -"""OpenTitan OTP HJSON helper +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""OpenTitan OTP HJSON helper. + + :note: this script is deprecated and should be merged into otptool.py + + :author: Emmanuel Blot """ -# Copyright (c) 2023 Rivos, Inc. -# SPDX-License-Identifier: Apache2 -from argparse import ArgumentParser, FileType, Namespace +from argparse import ArgumentParser, FileType try: # try to use HJSON if available from hjson import load as jload except ImportError as _exc: raise ImportError("HJSON Python module required") from _exc -from logging import (Formatter, StreamHandler, CRITICAL, DEBUG, INFO, ERROR, - WARNING, getLogger) +from logging import getLogger from os import linesep from pprint import pprint from sys import exit as sysexit, modules, stderr from traceback import format_exc -from typing import BinaryIO, Optional +from typing import BinaryIO + +from ot.util.log import configure_loggers class OtpHelper: @@ -132,15 +138,7 @@ def main(): args = argparser.parse_args() debug = args.debug - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = Formatter('%(levelname)8s [%(lineno)d] %(name)-12s ' - '%(message)s') - log = getLogger('otp') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + configure_loggers('otp', args.verbose, name_width=12, lineno=True) otp = OtpHelper() otp.load(args.config) diff --git a/scripts/opentitan/otptool.py b/scripts/opentitan/otptool.py index f49cb6393181..eb66c5c37fe4 100755 --- a/scripts/opentitan/otptool.py +++ b/scripts/opentitan/otptool.py @@ -1,15 +1,17 @@ #!/usr/bin/env python3 -"""QEMU OT tool to manage OTP files. -""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""QEMU OT tool to manage OTP files. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser, FileType from binascii import hexlify, unhexlify from io import BytesIO, StringIO -from logging import DEBUG, ERROR, getLogger, Formatter, StreamHandler +from logging import getLogger from os.path import basename from re import match as re_match, sub as re_sub from struct import calcsize as scalc, pack as spack, unpack as sunpack @@ -19,6 +21,8 @@ from typing import (Any, BinaryIO, Dict, Iterator, List, Optional, Set, TextIO, Tuple, Union) +from ot.util.log import configure_loggers + try: # try to load HJSON if available from hjson import load as hjload @@ -997,14 +1001,7 @@ def main(): args = argparser.parse_args() debug = args.debug - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = Formatter('%(levelname)8s %(name)-10s %(message)s') - log = getLogger('otptool') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + configure_loggers(args.verbose, 'otptool') otp = OtpImage(args.ecc) diff --git a/scripts/opentitan/pyot.py b/scripts/opentitan/pyot.py index a12ce1af7ead..899704e952aa 100755 --- a/scripts/opentitan/pyot.py +++ b/scripts/opentitan/pyot.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 -"""OpenTitan QEMU test sequencer. -""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""OpenTitan QEMU unit test sequencer. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser, FileType, Namespace from atexit import register from collections import defaultdict @@ -18,17 +20,15 @@ except ImportError: # fallback on legacy JSON syntax otherwise from json import load as jload -from logging import (Formatter, StreamHandler, CRITICAL, DEBUG, INFO, ERROR, - WARNING, getLogger) -from os import (close, curdir, environ, getcwd, isatty, linesep, pardir, sep, - unlink) +from logging import CRITICAL, DEBUG, INFO, ERROR, getLogger +from os import close, curdir, environ, getcwd, linesep, pardir, sep, unlink from os.path import (abspath, basename, dirname, isabs, isdir, isfile, join as joinpath, normpath, relpath) from re import Match, compile as re_compile, sub as re_sub from shutil import rmtree from socket import socket, timeout as LegacyTimeoutError from subprocess import Popen, PIPE, TimeoutExpired -from sys import argv, exit as sysexit, modules, stderr, stdout +from sys import argv, exit as sysexit, modules, stderr from threading import Thread from tempfile import mkdtemp, mkstemp from time import time as now @@ -36,6 +36,8 @@ from typing import (Any, Deque, Dict, Iterator, List, NamedTuple, Optional, Set, Tuple) +from ot.util.log import configure_loggers + DEFAULT_MACHINE = 'ot-earlgrey' DEFAULT_DEVICE = 'localhost:8000' @@ -61,40 +63,6 @@ class TestResult(NamedTuple): error: str -class CustomFormatter(Formatter): - """Custom log formatter for ANSI terminals. Colorize log levels. - """ - - GREY = "\x1b[38;20m" - YELLOW = "\x1b[33;1m" - RED = "\x1b[31;1m" - MAGENTA = "\x1b[35;1m" - WHITE = "\x1b[37;1m" - RESET = "\x1b[0m" - FORMAT_LEVEL = '%(levelname)8s' - FORMAT_TRAIL = ' %(name)-10s %(message)s' - - COLOR_FORMATS = { - DEBUG: f'{GREY}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - INFO: f'{WHITE}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - WARNING: f'{YELLOW}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - ERROR: f'{RED}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - CRITICAL: f'{MAGENTA}{FORMAT_LEVEL}{RESET}{FORMAT_TRAIL}', - } - - PLAIN_FORMAT = f'{FORMAT_LEVEL}{FORMAT_TRAIL}' - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._istty = isatty(stdout.fileno()) - - def format(self, record): - log_fmt = self.COLOR_FORMATS[record.levelno] if self._istty \ - else self.PLAIN_FORMAT - formatter = Formatter(log_fmt) - return formatter.format(record) - - class ResultFormatter: """Format a result CSV file as a simple result table.""" @@ -737,7 +705,7 @@ def command(self) -> str: def _run(self): self._resume = True - #pylint: disable=consider-using-with + # pylint: disable=consider-using-with proc = Popen(self._cmd, bufsize=1, stdout=PIPE, stderr=PIPE, shell=True, env=self._env, encoding='utf-8', errors='ignore', text=True) @@ -941,6 +909,11 @@ class QEMUExecuter: QEMUWrapper.NO_MATCH_RETURN_CODE: 'UNKNOWN', } + DEFAULT_START_DELAY = 1.0 + """Default start up delay to let QEMU initialize before connecting the + virtual UART port. + """ + def __init__(self, qfm: QEMUFileManager, config: Dict[str, any], args: Namespace): self._log = getLogger('pyot.exec') @@ -993,7 +966,8 @@ def run(self, debug: bool) -> int: DEFAULT_TIMEOUT_FACTOR)))) self._log.debug('Execute %s', basename(self._argdict['exec'])) ret, xtime, err = qot.run(self._qemu_cmd, timeout, - self.get_test_radix(app), None) + self.get_test_radix(app), None, + self.DEFAULT_START_DELAY) results[ret] += 1 sret = self.RESULT_MAP.get(ret, ret) icount = self._argdict.get('icount') @@ -1156,8 +1130,8 @@ def _build_qemu_command(self, args: Namespace, if not isfile(args.flash): raise ValueError(f'No such flash file: {args.flash}') if any((args.exec, args.boot)): - raise ValueError('Flash file argument is mutually exclusive with' - ' bootloader or rom extension') + raise ValueError('Flash file argument is mutually exclusive ' + 'with bootloader or rom extension') flash_path = self.abspath(args.flash) qemu_args.extend(('-drive', f'if=mtd,bus=1,file={flash_path},' f'format=raw')) @@ -1188,7 +1162,8 @@ def _build_qemu_command(self, args: Namespace, qemu_args.extend(('-icount', f'{args.icount}')) mux = f'mux={"on" if args.muxserial else "off"}' try: - start_delay = float(getattr(args, 'start_delay') or 1.0) + start_delay = float(getattr(args, 'start_delay') or\ + self.DEFAULT_START_DELAY) except ValueError as exc: raise ValueError(f'Invalid start up delay {args.start_delay}') \ from exc @@ -1475,14 +1450,7 @@ def main(): close(tmpfd) args.result = tmp_result - loglevel = max(DEBUG, ERROR - (10 * (args.verbose or 0))) - loglevel = min(ERROR, loglevel) - formatter = CustomFormatter() - log = getLogger('pyot') - logh = StreamHandler(stderr) - logh.setFormatter(formatter) - log.setLevel(loglevel) - log.addHandler(logh) + log = configure_loggers(args.verbose, 'pyot')[0] qfm = QEMUFileManager(args.keep_tmp) diff --git a/scripts/opentitan/swexit.py b/scripts/opentitan/swexit.py index 5e240bd837b9..efbd236120b4 100755 --- a/scripts/opentitan/swexit.py +++ b/scripts/opentitan/swexit.py @@ -1,10 +1,13 @@ #!/usr/bin/env python3 -"""OpenTitan exit code generator for QEMU.""" - # Copyright (c) 2023-2024 Rivos, Inc. # SPDX-License-Identifier: Apache2 +"""OpenTitan exit code generator for QEMU. + + :author: Emmanuel Blot +""" + from argparse import ArgumentParser, FileType from struct import pack as spack from sys import exit as sysexit, modules, stderr, stdout diff --git a/scripts/opentitan/treillis/boot.py b/scripts/opentitan/treillis/boot.py index 8ab87f79426a..931aa4bfe58c 100644 --- a/scripts/opentitan/treillis/boot.py +++ b/scripts/opentitan/treillis/boot.py @@ -1,3 +1,10 @@ +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""Configuration file for CircuitPython.""" + +# pylint: disable=import-error + import usb_cdc import usb_midi diff --git a/scripts/opentitan/treillis/code.py b/scripts/opentitan/treillis/code.py index bba2935bea4f..bdd67ee9966a 100644 --- a/scripts/opentitan/treillis/code.py +++ b/scripts/opentitan/treillis/code.py @@ -1,12 +1,17 @@ +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + """Simple CircuitPython script (which is stuck with Python 3.4) that maps QEMU GPIO chardev backend device onto a NeoTreillis M4 Express device. + + :author: Emmanuel Blot """ -#pylint: disable=import-error -#pylint: disable=invalid-name -#pylint: disable=missing-function-docstring -#pylint: disable=consider-using-f-string -#pylint: disable=missing-class-docstring +# pylint: disable=import-error +# pylint: disable=invalid-name +# pylint: disable=missing-function-docstring +# pylint: disable=consider-using-f-string +# pylint: disable=missing-class-docstring try: @@ -18,6 +23,7 @@ 'CircuitPython') raise + class OtGPIO: """OpenTitan GPIO interface with an Adafruit NeoTrellis M4 Express. @@ -25,7 +31,7 @@ class OtGPIO: """ GPO_ON = (20, 0, 0) # red - GPO_OFF = (0, 20, 0) # green + GPO_OFF = (0, 20, 0) # green GPI_ON = (0, 0, 80) # bright blue GPI_OFF = (2, 2, 2) # greyish @@ -42,7 +48,7 @@ def __init__(self, serial): self._lock_in = 0 # locked keys self._lock_time = {} # when key has been first pressed (ns timestamp) - def _update_input(self, newval, force=False): + def _update_input(self, newval): ts = now() change = self._kin ^ newval self._kin = newval From eeded64d62d156cb4ad3afde83b03e2beaec743e Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 13 Feb 2024 11:09:19 +0100 Subject: [PATCH 38/58] [ot] scripts/opentitan: add a mailbox requester module Signed-off-by: Emmanuel Blot --- scripts/opentitan/ot/mailbox/__init__.py | 4 + scripts/opentitan/ot/mailbox/sysmbox.py | 105 +++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 scripts/opentitan/ot/mailbox/__init__.py create mode 100644 scripts/opentitan/ot/mailbox/sysmbox.py diff --git a/scripts/opentitan/ot/mailbox/__init__.py b/scripts/opentitan/ot/mailbox/__init__.py new file mode 100644 index 000000000000..7fbe72811a0d --- /dev/null +++ b/scripts/opentitan/ot/mailbox/__init__.py @@ -0,0 +1,4 @@ +"""Mailbox tools.""" + +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 diff --git a/scripts/opentitan/ot/mailbox/sysmbox.py b/scripts/opentitan/ot/mailbox/sysmbox.py new file mode 100644 index 000000000000..b45d0b3c735a --- /dev/null +++ b/scripts/opentitan/ot/mailbox/sysmbox.py @@ -0,0 +1,105 @@ +"""System Mailbox. + + :author: Emmanuel Blot +""" + +from binascii import hexlify +from logging import getLogger +from time import sleep, time as now + + +class SysMboxError(RuntimeError): + """System mailbox error.""" + + +class SysMbox: + """Mailbox requester API + """ + def __init__(self): + self._log = getLogger('mbox.sys') + + @property + def busy(self) -> bool: + """Report whether the mailbox is busy.""" + raise NotImplementedError('ABC') + + @property + def on_error(self) -> bool: + """Report whether the mailbox is on error.""" + raise NotImplementedError('ABC') + + @property + def object_ready(self) -> bool: + """Report whether the mailbox contains a response.""" + raise NotImplementedError('ABC') + + def go(self) -> None: + """Tell the mailbox to process the request.""" + # pylint: disable=invalid-name + raise NotImplementedError('ABC') + + def abort(self) -> None: + """Tell the mailbox to abort the request / clear any error.""" + raise NotImplementedError('ABC') + + def write_word(self, word: int) -> None: + """Write a single request word into the mailbox. + + It is the caller responsability to check the mailbox is ready to + receive a new word. + """ + raise NotImplementedError('ABC') + + def read_word(self, ack: bool = True) -> int: + """Read a single response word from the mailbox. + + It is the caller responsability to check the mailbox contains a new + word. + """ + raise NotImplementedError('ABC') + + def acknowledge_read(self) -> None: + """Acknowledge the read out of the last retrieved word.""" + raise NotImplementedError('ABC') + + def write(self, request: bytes) -> int: + """Send a request to the mailbox.""" + if self.busy: + raise SysMboxError('Mailbox is busy') + if self.on_error: + raise SysMboxError('Mailbox is on error') + trailing = len(request) & 0x3 + if trailing: + request = b''.join((request, bytes(4-trailing))) + self._log.info('TX: (%d) %s', len(request), hexlify(request).decode()) + reqlen = 0 + while request: + chunk, request = request[:4], request[4:] + self.write_word(int.from_bytes(chunk, 'little')) + reqlen += 4 + self.go() + return reqlen + + def read(self) -> bytes: + """Receive a response from the mailbox.""" + timeout = now() + 2.0 + while True: + if self.on_error: + self.abort() + raise SysMboxError('Mailbox is on error') + if self.object_ready: + break + if now() > timeout: + raise TimeoutError('No response from mailbox') + sleep(0.1) + response = bytearray() + while self.object_ready: + chunk = self.read_word() + response.extend(chunk.to_bytes(4, 'little')) + self._log.info('RX: (%d) %s', len(response), hexlify(response).decode()) + return bytes(response) + + def exchange(self, request: bytes) -> bytes: + """Performs a full half-duplex response-request on the mailbox.""" + self.write(request) + return self.read() From 639d2fb3d7bc4aad87bcd8842a80b907f118503c Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 15 Feb 2024 17:37:24 +0100 Subject: [PATCH 39/58] [ot] scripts/opentitan: move DoE module into a sub-directory Signed-off-by: Emmanuel Blot --- scripts/opentitan/{ => ot}/devproxy.py | 76 +----------- scripts/opentitan/ot/mailbox/doe.py | 162 +++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 74 deletions(-) rename scripts/opentitan/{ => ot}/devproxy.py (95%) create mode 100644 scripts/opentitan/ot/mailbox/doe.py diff --git a/scripts/opentitan/devproxy.py b/scripts/opentitan/ot/devproxy.py similarity index 95% rename from scripts/opentitan/devproxy.py rename to scripts/opentitan/ot/devproxy.py index f7389bd3856b..b0c0d6211f54 100644 --- a/scripts/opentitan/devproxy.py +++ b/scripts/opentitan/ot/devproxy.py @@ -17,6 +17,8 @@ from typing import (Any, Callable, Dict, Iterator, List, NamedTuple, Optional, Tuple, Union) +from .mailbox.doe import DOEHeader + try: from serial import Serial, serial_for_url except ImportError: @@ -88,80 +90,6 @@ def __init__(self): super().__init__(0x201, 'Device On Error') -class DOEHeader: - """Container/helper for DOE headers. - - :param vid: vendor identifier - :param objtype: object type - :param dwlength: count of 32-bit words in the DOE packet (incl. the - header 2x 32-bit words) - """ - - FORMAT = ' str: - return f'vid:0x{self._vid:04x}, objtype:0x{self._objtype:02x}' - - def __repr__(self) -> str: - return f'{self.__class__.__name__} ' \ - f'0x{self._vid:04x},0x{self._objtype:02x}' - - def set_dwlength(self, dwlength: int) -> None: - """Set the actual 32-bit word length of the DOE packet.""" - if not isinstance(dwlength, int) or not 0 <= dwlength <= 0x3ff: - raise ValueError('Invalid dwlength') - self._dwlength = dwlength - - @property - def vid(self): - """Report the stored vendor identifier.""" - return self._vid - - @property - def objtype(self): - """Report the stored object type.""" - return self._objtype - - @property - def dwlength(self): - """Report the count of double words (i.e. 32 bit words) including - the two double words from this very header in the DOE packet. - """ - return self._dwlength - - @classmethod - def decode(cls, buf: bytes) -> 'DOEHeader': - """Decode a byte buffer into a DOE header.""" - if len(buf) < cls.SIZE: - raise ValueError('Too short a buffer') - vid, objtype, length = sunpack(cls.FORMAT, buf) - length &= 0x3ff - return cls(vid, objtype, length) - - def encode(self) -> bytes: - """Encode this DOE header into a byte sequence.""" - buf = spack(self.FORMAT, self._vid, self._objtype, self._dwlength) - return buf - - class MemoryRoot(NamedTuple): """A root memory region. """ diff --git a/scripts/opentitan/ot/mailbox/doe.py b/scripts/opentitan/ot/mailbox/doe.py new file mode 100644 index 000000000000..003a9d5538d8 --- /dev/null +++ b/scripts/opentitan/ot/mailbox/doe.py @@ -0,0 +1,162 @@ +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""Device proxy for OpenTitan devices and peripherals + + :author: Emmanuel Blot +""" + +from logging import getLogger +from struct import calcsize as scalc, pack as spack, unpack as sunpack +from typing import Tuple + +from .sysmbox import SysMbox, SysMboxError + + +class DOEHeader: + """Container/helper for DOE headers. + + :param vid: vendor identifier + :param objtype: object type + :param dwlength: count of 32-bit words in the DOE packet (incl. the + header 2x 32-bit words) + """ + + FORMAT = ' str: + return f'vid:0x{self._vid:04x}, objtype:0x{self._objtype:02x}' + + def __repr__(self) -> str: + return f'{self.__class__.__name__} ' \ + f'0x{self._vid:04x},0x{self._objtype:02x}' + + def set_dwlength(self, dwlength: int) -> None: + """Set the actual 32-bit word length of the DOE packet.""" + if not isinstance(dwlength, int) or not 0 <= dwlength <= 0x3ff: + raise ValueError('Invalid dwlength') + self._dwlength = dwlength + + @property + def vid(self): + """Report the stored vendor identifier.""" + return self._vid + + @property + def objtype(self): + """Report the stored object type.""" + return self._objtype + + @property + def dwlength(self): + """Report the count of double words (i.e. 32 bit words) including + the two double words from this very header in the DOE packet. + """ + return self._dwlength + + @classmethod + def decode(cls, buf: bytes) -> 'DOEHeader': + """Decode a byte buffer into a DOE header.""" + if len(buf) < cls.SIZE: + raise ValueError('Too short a buffer') + vid, objtype, length = sunpack(cls.FORMAT, buf) + length &= 0x3ff + return cls(vid, objtype, length) + + def encode(self) -> bytes: + """Encode this DOE header into a byte sequence.""" + buf = spack(self.FORMAT, self._vid, self._objtype, self._dwlength) + return buf + + +class DOEMailbox: + """Mailbox with a DOE header. + + :param mailbox: a system mailbox instance + :param vid: vendor ID for the DOE header + """ + + def __init__(self, mailbox: SysMbox, vid: int): + self._mbox = mailbox + self._vid = vid + self._log = getLogger('mbox.doe') + + def abort(self): + """Tell the mailbox to abort the request / clear any error.""" + self._mbox.abort() + + @property + def busy(self) -> bool: + """Report whether the mailbox is busy.""" + return self._mbox.busy + + @property + def on_error(self) -> bool: + """Report whether the mailbox is on error.""" + return self._mbox.on_error + + @property + def object_ready(self) -> bool: + """Report whether the mailbox contains a response.""" + return self._mbox.object_ready + + def write(self, oid: int, msg: bytes) -> None: + """Send a DOE message.""" + hdr = DOEHeader(self._vid, oid) + trailing = len(msg) & 0x3 + if trailing: + msg = b''.join((msg, bytes(4-trailing))) + dwlen = len(msg)//4 + DOEHeader.DWSIZE + hdr.set_dwlength(dwlen) + req = b''.join((hdr.encode(), msg)) + self._log.debug('len %d', len(req)) + count = self._mbox.write(req) + if count != len(req): + raise SysMboxError(f'Cannot write full buffer {count}/{len(req)}') + if self._mbox.on_error: + raise SysMboxError('JTAG mailbox on error') + + def read(self) -> Tuple[int, bytes]: + """Receive a DOE message.""" + resp = self._mbox.read() + if not resp: + raise SysMboxError('No response from host') + if len(resp) < DOEHeader.SIZE: + raise SysMboxError('Truncated response from host') + self._log.debug('len %d', len(resp)) + hdr = DOEHeader.decode(resp[:DOEHeader.SIZE]) + if hdr.vid != self._vid: + raise SysMboxError(f'Unexpected vendor ID 0x{hdr.vid:04x}') + plen = (hdr.dwlength - DOEHeader.DWSIZE) * 4 + payload = resp[DOEHeader.SIZE:] + if plen != len(payload): + raise SysMboxError(f'Unexpected payload length ' + f'{plen}/{len(payload)}') + oid = hdr.objtype + return oid, payload + + def exchange(self, oid: int, msg: bytes) -> bytes: + """Exchange a message/response on the mailbox.""" + self.write(oid, msg) + roid, payload = self.read() + if roid != oid: + raise SysMboxError(f'Unexpected object type: {oid}/{roid}') + return payload From 402bb7437d0765563b3353dbe4b19c613b48867f Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 12 Feb 2024 12:14:21 +0100 Subject: [PATCH 40/58] [ot] scripts/jtag: add a Python module to communicate with JTAG server Signed-off-by: Emmanuel Blot --- scripts/jtag/.flake8 | 2 + scripts/jtag/.pylintrc | 7 + scripts/jtag/__init__.py | 4 + scripts/jtag/bitbang.py | 180 ++++++++++++ scripts/jtag/bits.py | 592 +++++++++++++++++++++++++++++++++++++++ scripts/jtag/jtag.py | 351 +++++++++++++++++++++++ 6 files changed, 1136 insertions(+) create mode 100644 scripts/jtag/.flake8 create mode 100644 scripts/jtag/.pylintrc create mode 100644 scripts/jtag/__init__.py create mode 100644 scripts/jtag/bitbang.py create mode 100644 scripts/jtag/bits.py create mode 100644 scripts/jtag/jtag.py diff --git a/scripts/jtag/.flake8 b/scripts/jtag/.flake8 new file mode 100644 index 000000000000..15fc7e33eb08 --- /dev/null +++ b/scripts/jtag/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 80 diff --git a/scripts/jtag/.pylintrc b/scripts/jtag/.pylintrc new file mode 100644 index 000000000000..3dcc728c9599 --- /dev/null +++ b/scripts/jtag/.pylintrc @@ -0,0 +1,7 @@ +[MESSAGES CONTROL] + + disable = too - few - public - methods, + too - many - arguments, too - many - branches, + too - many - instance - attributes, too - many - lines, too - many - locals, + too - many - nested - blocks, too - many - public - methods, + too - many - statements, unspecified - encoding diff --git a/scripts/jtag/__init__.py b/scripts/jtag/__init__.py new file mode 100644 index 000000000000..fe3d00da1f20 --- /dev/null +++ b/scripts/jtag/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""JTAG tools.""" diff --git a/scripts/jtag/bitbang.py b/scripts/jtag/bitbang.py new file mode 100644 index 000000000000..1c13f03b3f63 --- /dev/null +++ b/scripts/jtag/bitbang.py @@ -0,0 +1,180 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""JTAG controller for OpenOCD/QEMU bitbang protocol. + + :author: Emmanuel Blot + + Protocol abstract: + + TCLK TMS TDI + b'0' - Write 0 0 0 + b'1' - Write 0 0 1 + b'2' - Write 0 1 0 + b'3' - Write 0 1 1 + b'4' - Write 1 0 0 + b'5' - Write 1 0 1 + b'6' - Write 1 1 0 + b'7' - Write 1 1 1 + + TRST SRST + b'r' - Reset 0 0 + b's' - Reset 0 1 + b't' - Reset 1 0 + b'u' - Reset 1 1 + + b'R' - Read request -> b'0' or b'1' + b'Q' - Quit request +""" + +from logging import getLogger +from socket import socket +from time import time as now +from typing import Optional + +from .bits import BitSequence +from .jtag import JtagController + + +class JtagBitbangController(JtagController): + """JTAG master for Remote Bitbang connection.""" + + DEFAULT_PORT = 3335 + """Default TCP port.""" + + INSTRUCTIONS = dict(bypass=0x0, idcode=0x1) + """Common instruction register codes.""" + + RECV_TIMEOUT = 0.25 + """Maximum allowed time in seconds to receive a response from the JTAG + controller. + """ + + READ = 'R'.encode() + """JTAG bitbang code to receive data from TDO.""" + + QUIT = 'Q'.encode() + """JTAG bitbang code to quit.""" + + def __init__(self, sock: socket): + self._log = getLogger('jtag.ctrl') + self._sock = sock + self._last: Optional[bool] = None # Last deferred TDO bit + self._outbuf = bytearray() + self._tck = False + self._tms = False + self._tdi = False + self._trst = False + self._srst = False + + def tap_reset(self, use_trst: bool = False) -> None: + self._log.info('TAP reset (%s)', 'TRST' if use_trst else 'SW') + if use_trst: + self._trst = not self._trst + self._write(self._reset_code(self._trst, self._srst)) + self._trst = not self._trst + self._write(self._reset_code(self._trst, self._srst)) + else: + self.write_tms(BitSequence('11111')) + + def system_reset(self) -> None: + self._log.info('System reset') + self._write(self._reset_code(self._trst, self._srst)) + self._srst = not self._srst + self._write(self._reset_code(self._trst, self._srst)) + self._srst = not self._srst + self._write(self._reset_code(self._trst, self._srst)) + + def quit(self) -> None: + self._log.info('Quit') + self._sock.send(self.QUIT) + + def write_tms(self, modesel: BitSequence) -> None: + if not isinstance(modesel, BitSequence): + raise ValueError('Expect a BitSequence') + # apply the last TDO bit + if self._last is not None: + self._tdi = self._last + self._last = None + self._log.debug('write TMS [%d] %s', len(modesel), modesel) + while modesel: + tms = modesel.pop_left_bit() + self._write(self._bus_code(self._tck, tms, self._tdi)) + self._tck = not self._tck + self._write(self._bus_code(self._tck, tms, self._tdi)) + self._tck = not self._tck + self._tms = tms + + def write(self, out: BitSequence, use_last: bool = True): + if not isinstance(out, BitSequence): + raise ValueError('out is not a BitSequence') + if use_last: + if self._last is not None: + # TODO: check if this case needs to be handled + raise NotImplementedError('Last is lost') + self._last = out.pop_left_bit() + self._log.debug('write TDI [%d] %s', len(out), out) + while out: + tdi = out.pop_right_bit() + self._write(self._bus_code(self._tck, self._tms, tdi)) + self._tck = not self._tck + self._write(self._bus_code(self._tck, self._tms, tdi)) + self._tck = not self._tck + self._tdi = tdi + + def read(self, length: int) -> BitSequence: + if length == 0: + raise ValueError() + bseq = BitSequence() + rem = length + timeout = now() + self.RECV_TIMEOUT + self._log.debug('read %d bits, TMS: %d', length, self._tms) + for _ in range(length): + self._write(self._bus_code(self._tck, self._tms, self._tdi)) + self._tck = not self._tck + self._write(self._bus_code(self._tck, self._tms, self._tdi)) + self._tck = not self._tck + self._sock.send(self.READ) + while rem: + try: + data = self._sock.recv(length) + except TimeoutError: + if now() < timeout: + continue + raise + rem -= len(data) + bseq.push_right(data) + timeout = now() + self.RECV_TIMEOUT + bseq.reverse() + self._log.debug('read TDI [%d] %s', len(bseq), bseq) + return bseq + + @property + def tdi(self) -> bool: + return self._tdi + + @tdi.setter + def tdi(self, value: bool): + self._tdi = bool(value) + self._log.info('SET TDI %u', self._tdi) + + @property + def tms(self) -> bool: + return self._tms + + @tms.setter + def tms(self, value: bool): + self._tms = bool(value) + + @classmethod + def _bus_code(cls, tclk: bool, tms: bool, tdi: bool) -> int: + return 0x30 + ((int(tclk) << 2) | (int(tms) << 1) | tdi) + + @classmethod + def _reset_code(cls, trst: bool, srst: bool) -> int: + return ord('r') + ((int(trst) << 1) | srst) + + def _write(self, code: int): + self._log.debug('_write 0x%02x %s (%s)', code, f'{code-0x30:03b}', + chr(code)) + self._sock.send(bytes([code])) diff --git a/scripts/jtag/bits.py b/scripts/jtag/bits.py new file mode 100644 index 000000000000..873a12ab04b0 --- /dev/null +++ b/scripts/jtag/bits.py @@ -0,0 +1,592 @@ +# Copyright (c) 2010-2024 Emmanuel Blot +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Bit sequence helpers for JTAG/DTM. + + BitSequence is a wrapper to help manipulating bits with the JTAG tools. + + >>> empty = BitSequence() + + >>> len(empty) + 0 + >>> int(empty) + 0 + >>> bool(empty) + False + >>> bs = BitSequence(0xC4, 8) + + >>> bs + [1, 1, 0, 0, 0, 1, 0, 0] + >>> str(bs) + '11000100' + >>> bs = BitSequence('11000100') + + >>> bs + [1, 1, 0, 0, 0, 1, 0, 0] + >>> int(bs) + 196 + >>> bs = BitSequence(b'11000100') + + >>> bs + [1, 1, 0, 0, 0, 1, 0, 0] + >>> bs = BitSequence([1, 1, 0, 0, 0, 1, 0, 0]) + + >>> bs + [1, 1, 0, 0, 0, 1, 0, 0] + >>> bs.pop_right() + [0] + >>> bs.pop_right(2) + [1, 0] + >>> bs.pop_right_bit() + False + >>> bs.push_right('0111') + [1, 1, 0, 0, 0, 1, 1, 1] + >>> bs.pop_left_bit() + True + >>> bs.pop_left(2) + [1, 0] + >>> bs + [0, 0, 1, 1, 1] + >>> len(bs) + 5 + >>> bs.push_left([False, True, True]) + [0, 1, 1, 0, 0, 1, 1, 1] + >>> bs.rll() + [1, 1, 0, 0, 1, 1, 1, 0] + >>> bs.rrl(3) + [1, 1, 0, 1, 1, 0, 0, 1] + >>> bs.inc() + [1, 1, 0, 1, 1, 0, 1, 0] + >>> bs.invert() + [0, 0, 1, 0, 0, 1, 0, 1] + >>> bs.reverse() + [1, 0, 1, 0, 0, 1, 0, 0] + >>> bs = BitSequence(0xff, 8) + >>> bs.inc() + [0, 0, 0, 0, 0, 0, 0, 0] + >>> bs.invariant() + False + >>> len(bs) + 8 + >>> bs.dec() + [1, 1, 1, 1, 1, 1, 1, 1] + >>> bs.invariant() + True + >>> len(bs) + 8 + >>> bs1 = BitSequence(0x13, 5) # 10011 + + >>> bs2 = BitSequence(0x19, 5) # 11001 + + >>> bs3 = bs2.copy().reverse() + + >>> bs1 == bs3 + True + >>> bs1 == bs2 + False + >>> bs1 != bs2 + True + >>> bs1 < bs2 + True + >>> bs1 <= bs2 + True + >>> bs1 > bs2 + False + >>> bs1 | bs2 + [1, 1, 0, 1, 1] + >>> bs1 & bs2 + [1, 0, 0, 0, 1] + >>> bs1 ^ bs2 + [0, 1, 0, 1, 0] + >>> ~(bs1 ^ bs2) + [1, 0, 1, 0, 1] +""" + +from typing import Any, Iterable, List, Union + + +class BitSequenceError(Exception): + """Bit sequence error""" + + +BitSequenceInitializer = Union['BitSequence', str, int, bytes, bytearray, + Iterable[int], Iterable[bool], None] +"""Supported types to initialize a BitSequence.""" + + +class BitSequence: + """Bit sequence. + + Support most of the common bit operations and conversion from and to + integral values, as well as sequence of boolean, int and characters. + + Bit sequence objects are iterable. + + :param value: initial value + :param length: count of signficant bits in the bit sequence + """ + + # pylint: disable=protected-access + + def __init__(self, value: BitSequenceInitializer = None, + width: int = 0): + if value is None: + self._int = 0 + self._width = width + return + if isinstance(value, BitSequence): + self._int, self._width = value._int, value._width + return + if isinstance(value, int): + bseq = self.from_int(value, width) + self._int, self._width = bseq._int, bseq._width + return + if is_iterable(value): + bseq = self.from_iterable(value) + if width and width != bseq._width: + raise ValueError('Specified width does not match input value') + self._int, self._width = bseq._int, bseq._width + return + raise BitSequenceError(f'Cannot initialize from a {type(value)}') + + @classmethod + def from_iterable(cls, iterable: Iterable) -> 'BitSequence': + """Instanciate a BitSequence from an iterable.""" + # pylint: disable=duplicate-key + smap = { + 0: 0, 1: 1, # as int + '0': 0, '1': 1, # as string + 0x30: 0, 0x31: 1, # as bytes + False: 0, True: 1, # as bool + } + value = 0 + width = 0 + for bit in iterable: + try: + value <<= 1 + value |= smap[bit] + width += 1 + except KeyError as exc: + raise ValueError(f"Invalid item '{bit}' in iterable at pos " + f"{width}") from exc + return BitSequence.from_int(value, width) + + @classmethod + def from_int(cls, value: int, width: int) -> 'BitSequence': + """Instanciate a BitSequence from an integer value.""" + bseq = BitSequence() + bseq._int = value + bseq._width = width + return bseq + + def __len__(self): + return self._width + + def __bool__(self): + # report wether the Bit Sequence is empty or not. + # to fold a single bit sequence into a boolean, see #to_bit + return bool(self._width) + + def __int__(self): + return self._int + + def __repr__(self) -> str: + sseq = ', '.join((f'{b:0d}' for b in self)) + return f'[{sseq}]' + + def __str__(self) -> str: + return f'{self._int:0{self._width}b}' + + def copy(self) -> 'BitSequence': + """Duplicate bitsequence.""" + bseq = self.__class__() + bseq._int = self._int + bseq._width = self._width + return bseq + + @property + def mask(self) -> int: + """Bit mask.""" + return (1 << self._width) - 1 + + def to_bit(self) -> bool: + """Fold the sequence into a single bit, if possible""" + if self._width != 1: + raise BitSequenceError("BitSequence too large") + return bool(self._int & 1) + + def to_byte(self, msb: bool = False) -> int: + """Convert the sequence into a single byte value, if possible""" + if self._width > 8: + raise BitSequenceError("Cannot fit into a single byte") + if not msb: + bseq = BitSequence(self) + bseq.reverse() + else: + bseq = self + return self._int + + def to_bytes(self) -> bytes: + """Return the internal representation as bytes""" + return bytes((int(b) for b in self)) + + def to_bool_list(self) -> List[bool]: + """Convert the sequence into a list of boolean values.""" + return list(self) + + def to_bytestream(self, msb: bool = False, msby: bool = False) -> bytes: + """Convert the sequence into a sequence of byte values""" + out: List[int] = [] + bseq = BitSequence(self) + if not msb: + bseq.reverse() + while bseq._width: + out.append(self._int & 0xff) + self._int >>= 8 + if msby and not msb: + out.reverse() + return bytes(out) + + def reverse(self) -> 'BitSequence': + """In-place reverse. + + :return: self + """ + bseq = self.__class__.from_iterable(reversed(self)) + assert bseq._width == self._width + self._int = bseq._int + return self + + def invert(self) -> 'BitSequence': + """In-place invert of each sequence value. + + :return: self + """ + self._int = ~self._int & self.mask + return self + + def push_right(self, bseq: BitSequenceInitializer) -> 'BitSequence': + """Push a bit sequence to the right side. + + :param bseq: the bit sequence to push + :return: self + """ + if not isinstance(bseq, BitSequence): + bseq = BitSequence(bseq) + self._int <<= len(bseq) + self._int |= bseq._int + self._width += len(bseq) + return self + + def push_left(self, bseq: BitSequenceInitializer) -> 'BitSequence': + """Push a bit sequence to the left side. + + :param bseq: the bit sequence to push + :return: self + """ + if not isinstance(bseq, BitSequence): + bseq = BitSequence(bseq) + self._int = (bseq._int << self._width) | self._int + self._width += len(bseq) + return self + + def pop_right(self, count: int = 1) -> 'BitSequence': + """Pop bits from the right side. + + :param count: how many bits to pop + :return: popped bits a a new BitSequence + """ + if count > self._width: + raise ValueError('Count too large') + if count == 0: + return BitSequence() + if count < 0: + raise ValueError('Negative shift is not defined') + bseq = self.__class__.from_int(self._int & ((1 << count) - 1), count) + self._int >>= count + self._width -= count + return bseq + + def pop_left(self, count: int = 1) -> 'BitSequence': + """Pop bits from the left side. + + :param count: how many bits to pop + :return: popped bits a a new BitSequence + """ + if count > self._width: + raise ValueError('Count too large') + if count == 0: + return BitSequence() + if count < 0: + raise ValueError('Negative shift is not defined') + shift = self._width - count + bseq = self.__class__.from_int(self._int >> shift, count) + self._int &= (1 << shift) - 1 + self._width -= count + return bseq + + def pop_right_bit(self) -> bool: + """Pop a single bit from the right side. + + :return: popped bit + """ + if self._width == 0: + raise RuntimeError('Empty bit sequence') + bit = bool(self._int & 1) + self._int >>= 1 + self._width -= 1 + return bit + + def pop_left_bit(self) -> bool: + """Pop a single bit from the left side. + + :return: popped bit + """ + if self._width == 0: + raise RuntimeError('Empty bit sequence') + bit = bool(self._int >> (self._width - 1)) + self._width -= 1 + self._int &= self.mask + return bit + + def rll(self, count: int = 1) -> 'BitSequence': + """Rotate Left Logical. + + :return: self + """ + count %= self._width + bseq = self.pop_left(count) + self.push_right(bseq) + return self + + def rrl(self, count: int = 1) -> 'BitSequence': + """Rotate Right Logical. + + :return: self + """ + count %= self._width + bseq = self.pop_right(count) + self.push_left(bseq) + return self + + def inc(self, wrap: bool = True) -> 'BitSequence': + """Increment the sequence.""" + self._int += 1 + if not wrap: + if self._int >> self._width: + self._width += 1 + else: + self._int &= self.mask + return self + + def dec(self, wrap: bool = True) -> 'BitSequence': + """Decrement the sequence""" + self._int -= 1 + if not wrap: + if not self._int >> self._width: + self._width -= 1 + else: + self._int &= self.mask + return self + + def invariant(self) -> bool: + """Tells whether all bits of the sequence are of the same value. + + Return the value, or ValueError if the bits are not of the same + value + """ + if self._int == 0: + return False + if self._int == self.mask: + return True + raise ValueError('Bits do no match') + + class Iterator: + """BitSequence iterator. + + Iterate from left to right (MSB to LSB) if reverse is not set. + + :param bseq: the BitSequence to iterate + :param reverse: whether to create a reverse iterator + """ + + def __init__(self, bseq: 'BitSequence', reverse: bool = False): + self._bseq = bseq + self._reverse = reverse + self._width = bseq._width + self._pos = 0 + + def __iter__(self) -> 'BitSequence.Iterator': + return self + + def __next__(self) -> bool: + if self._width != self._bseq._width: + raise RuntimeError('BitSequence modified while iterating') + if self._pos >= self._bseq._width: + raise StopIteration() + if self._reverse: + bit = bool((self._bseq._int >> self._pos) & 1) + else: + pos = self._width - self._pos - 1 + bit = bool((self._bseq._int >> pos) & 1) + self._pos += 1 + return bit + + def __iter__(self) -> 'BitSequence.Iterator': + """Iterate from left to right, i.e. MSB to LSB.""" + return self.__class__.Iterator(self) + + def __reversed__(self): + """Iterate from right to left, i.e. LSB to MSB.""" + return self.__class__.Iterator(self, reverse=True) + + def __eq__(self, other: 'BitSequence') -> bool: + if not isinstance(other, self.__class__): + raise ValueError(f'Cannot compare with {type(other)}') + return self._cmp(other) == 0 + + def __ne__(self, other: 'BitSequence') -> bool: + if not isinstance(other, self.__class__): + raise ValueError(f'Cannot compare with {type(other)}') + return not self == other + + def __le__(self, other: 'BitSequence') -> bool: + if not isinstance(other, self.__class__): + raise ValueError(f'Cannot compare with {type(other)}') + return self._cmp(other) <= 0 + + def __lt__(self, other: 'BitSequence') -> bool: + if not isinstance(other, self.__class__): + raise ValueError(f'Cannot compare with {type(other)}') + return self._cmp(other) < 0 + + def __ge__(self, other: 'BitSequence') -> bool: + if not isinstance(other, self.__class__): + raise ValueError(f'Cannot compare with {type(other)}') + return self._cmp(other) >= 0 + + def __gt__(self, other: 'BitSequence') -> bool: + if not isinstance(other, self.__class__): + raise ValueError(f'Cannot compare with {type(other)}') + return self._cmp(other) > 0 + + def _cmp(self, other: 'BitSequence') -> int: + # the bit sequence should be of the same length + ld = self._width - other._width + if ld: + return ld + return self._int - other._int + + def __and__(self, other: 'BitSequence') -> 'BitSequence': + if not isinstance(other, self.__class__): + raise ValueError('Need a BitSequence to combine') + if self._width != other._width: + raise ValueError('Sequences must be the same size') + value = self._int & other._int + return self.__class__.from_int(value, self._width) + + def __or__(self, other: 'BitSequence') -> 'BitSequence': + if not isinstance(other, self.__class__): + raise ValueError('Need a BitSequence to combine') + if self._width != other._width: + raise ValueError('Sequences must be the same size') + value = self._int | other._int + return self.__class__.from_int(value, self._width) + + def __xor__(self, other: 'BitSequence') -> 'BitSequence': + if not isinstance(other, self.__class__): + raise ValueError('Need a BitSequence to combine') + if self._width != other._width: + raise ValueError('Sequences must be the same size') + value = self._int ^ other._int + return self.__class__.from_int(value, self._width) + + def __invert__(self) -> 'BitSequence': + value = (~self._int) & self.mask + return self.__class__.from_int(value, self._width) + + def __ilshift__(self, count) -> 'BitSequence': + self.pop_left() + return self + + def __irshift__(self, count) -> 'BitSequence': + self.pop_right() + return self + + def __getitem__(self, index) -> 'BitSequence': + # TODO: not yet validated, likely buggy + if isinstance(index, slice): + bits: List[int] = [] + for bpos in range(index.start, index.stop, index.step): + if bpos < 0: + continue + if bpos >= self._width: + break + bits.append((self._int >> bpos) & 1) + return self.__class__.from_iterable(reversed(bits)) + if not isinstance(index, int): + raise TypeError(f'{self.__class__.__name__} indices must be ' + f'integers or slices, not {type(index)}') + if ~index >= self._width: + raise IndexError(f'{self.__class__.__name__} index out of range') + if index >= 0: + value = (self._int >> index) & 1 + else: + value = (self._int >> (self._width - index - 1)) & 1 + return self.__class__.from_int(value, 1) + + def __setitem__(self, index, value) -> None: + # TODO: not yet validated, likely buggy + if isinstance(index, slice): + if not isinstance(value, BitSequence): + if not is_iterable(value): + raise TypeError(f'Cannot set item with {type(value)}') + value = self.from_iterable(value) + else: + value = value.copy() + for bpos in range(index.start, index.stop, index.step): + if bpos < 0: + continue + if bpos >= self._width: + break + self._int &= ~(1 << bpos) + self._int |= int(value.pop_right()) << bpos + if value._width == 0: + break + if not isinstance(index, int): + raise TypeError(f'{self.__class__.__name__} indices must be ' + f'integers or slices, not {type(index)}') + if isinstance(value, BitSequence): + value = value.tobit() + elif isinstance(value, int): + if value not in (0, 1): + raise ValueError('Invalid value') + value = int(value) + if ~index >= self._width: + raise IndexError(f'{self.__class__.__name__} index out of ' + f'range') + if index < 0: + index = self._width - index - 1 + self._int[index] = value + + +def is_iterable(obj: Any) -> bool: + """Tells whether an instance is iterable or not. + + :param obj: the instance to test + :type obj: object + :return: True if the object is iterable + :rtype: bool + """ + try: + iter(obj) + return True + except TypeError: + return False + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/scripts/jtag/jtag.py b/scripts/jtag/jtag.py new file mode 100644 index 000000000000..92b7dfe6635c --- /dev/null +++ b/scripts/jtag/jtag.py @@ -0,0 +1,351 @@ +# Copyright (c) 2010-2024, Emmanuel Blot +# Copyright (c) 2016, Emmanuel Bouaziz +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""JTAG tools. + + Based on JTAG support for FTDI from PyFtdi module +""" + +# pylint: enable=missing-function-docstring + +from logging import getLogger +from typing import List, Optional, Tuple, Union + +from .bits import BitSequence + + +class JtagError(Exception): + """Generic JTAG error.""" + + +class JtagState: + """Test Access Port controller state. + + :param name: the name of the state + :param modes: categories to which the state belongs + """ + + def __init__(self, name: str, modes: Tuple[str, str]): + self.name = name + self.modes = modes + self.exits = [self, self] # dummy value before initial configuration + + def __str__(self): + return self.name + + def __repr__(self): + return self.name + + def setx(self, fstate: 'JtagState', tstate: 'JtagState'): + """Define the two exit state of a state.""" + self.exits = [fstate, tstate] + + def getx(self, event) -> 'JtagState': + """Retrieve the exit state of the state. + + :param event: evaluated as a boolean value + :return: next state + """ + return self.exits[int(bool(event))] + + def is_of(self, mode: str) -> bool: + """Report if the state is a member of the specified mode.""" + return mode in self.modes + + +class JtagStateMachine: + """Test Access Port controller state machine.""" + + def __init__(self): + self._log = getLogger('jtag.fsm') + self.states = {} + for state, modes in [('test_logic_reset', ('reset', ' idle')), + ('run_test_idle', ('idle',)), + ('select_dr_scan', ('dr',)), + ('capture_dr', ('dr', 'shift', 'capture')), + ('shift_dr', ('dr', 'shift')), + ('exit_1_dr', ('dr', 'update', 'pause')), + ('pause_dr', ('dr', 'pause')), + ('exit_2_dr', ('dr', 'shift', 'udpate')), + ('update_dr', ('dr', 'idle')), + ('select_ir_scan', ('ir',)), + ('capture_ir', ('ir', 'shift', 'capture')), + ('shift_ir', ('ir', 'shift')), + ('exit_1_ir', ('ir', 'udpate', 'pause')), + ('pause_ir', ('ir', 'pause')), + ('exit_2_ir', ('ir', 'shift', 'update')), + ('update_ir', ('ir', 'idle'))]: + self.states[state] = JtagState(state, modes) + self['test_logic_reset'].setx(self['run_test_idle'], + self['test_logic_reset']) + self['run_test_idle'].setx(self['run_test_idle'], + self['select_dr_scan']) + self['select_dr_scan'].setx(self['capture_dr'], + self['select_ir_scan']) + self['capture_dr'].setx(self['shift_dr'], self['exit_1_dr']) + self['shift_dr'].setx(self['shift_dr'], self['exit_1_dr']) + self['exit_1_dr'].setx(self['pause_dr'], self['update_dr']) + self['pause_dr'].setx(self['pause_dr'], self['exit_2_dr']) + self['exit_2_dr'].setx(self['shift_dr'], self['update_dr']) + self['update_dr'].setx(self['run_test_idle'], + self['select_dr_scan']) + self['select_ir_scan'].setx(self['capture_ir'], + self['test_logic_reset']) + self['capture_ir'].setx(self['shift_ir'], self['exit_1_ir']) + self['shift_ir'].setx(self['shift_ir'], self['exit_1_ir']) + self['exit_1_ir'].setx(self['pause_ir'], self['update_ir']) + self['pause_ir'].setx(self['pause_ir'], self['exit_2_ir']) + self['exit_2_ir'].setx(self['shift_ir'], self['update_ir']) + self['update_ir'].setx(self['run_test_idle'], self['select_dr_scan']) + self._current = self['test_logic_reset'] + + def __getitem__(self, name: str) -> JtagState: + return self.states[name] + + @property + def state(self) -> JtagState: + """Return the current state.""" + return self._current + + def state_of(self, mode: str) -> bool: + """Report if the current state is of the specified mode.""" + return self._current.is_of(mode) + + def reset(self): + """Reset the state machine.""" + self._current = self['test_logic_reset'] + + def find_path(self, target: Union[JtagState, str], + source: Union[JtagState, str, None] = None) \ + -> List[JtagState]: + """Find the shortest event sequence to move from source state to + target state. If source state is not specified, used the current + state. + + :return: the list of states, including source and target states. + """ + if source is None: + source = self.state + if isinstance(source, str): + source = self[source] + if isinstance(target, str): + target = self[target] + + def next_path(state, target, path): + # this test match the target, path is valid + if state == target: + return path+[state] + # candidate paths + paths = [] + for xstate in state.exits: + # next state is self (loop around), kill the path + if xstate == state: + continue + # next state already in upstream (loop back), kill the path + if xstate in path: + continue + # try the current path + npath = next_path(xstate, target, path + [state]) + # downstream is a valid path, store it + if npath: + paths.append(npath) + # keep the shortest path + return min(((len(path), path) for path in paths), + key=lambda x: x[0])[1] if paths else [] + return next_path(source, target, []) + + @classmethod + def get_events(cls, path): + """Build up an event sequence from a state sequence, so that the + resulting event sequence allows the JTAG state machine to advance + from the first state to the last one of the input sequence""" + events = [] + for sstate, dstate in zip(path[:-1], path[1:]): + for epos, xstate in enumerate(sstate.exits): + if xstate == dstate: + events.append(epos) + if len(events) != len(path) - 1: + raise JtagError("Invalid path") + return BitSequence(events) + + def handle_events(self, events: BitSequence) -> None: + """State machine stepping. + + :param events: a sequence of boolean events to advance the FSM. + """ + for event in events: + self._current = self._current.getx(event) + + +class JtagController: + """JTAG master API.""" + + INSTRUCTIONS = dict(bypass=0x0, idcode=0x1) + """Common instruction register codes.""" + + def tap_reset(self, use_trst: bool = False) -> None: + """Reset the TAP controller. + + :param use_trst: use TRST HW wire if available + """ + raise NotImplementedError('ABC') + + def system_reset(self) -> None: + """Reset the device.""" + + def quit(self) -> None: + """Terminate session.""" + + def write_tms(self, modesel: BitSequence) -> None: + """Change the TAP controller state. + + :note: modesel content may be consumed, i.e. emptied + :note: last TMS bit should be stored and clocked on next write + request + + :param modesel: the bit sequence of TMS bits to clock in + """ + raise NotImplementedError('ABC') + + def write(self, out: BitSequence, use_last: bool = True): + """Write a sequence of bits to TDI. + + :note: out content may be consumed, i.e. emptied + :param out: the bot sequence of TDI bits to clock in + :param use_last: whether to clock in the stored TMS bits on first + clock cycle + """ + raise NotImplementedError('ABC') + + def read(self, length: int) -> BitSequence: + """Read out a sequence of bits from TDO. + + :param length: the number of bits to clock out from the remote device + :return: the received TDO bits (length-long) + """ + raise NotImplementedError('ABC') + + @property + def tdi(self) -> bool: + """Get current TDI value.""" + raise NotImplementedError('ABC') + + @tdi.setter + def tdi(self, value: bool): + """Set TDI value, to be clocked out on next operation.""" + raise NotImplementedError('ABC') + + @property + def tms(self) -> bool: + """Get current TMS value.""" + raise NotImplementedError('ABC') + + @tms.setter + def tms(self, value: bool): + """Set TMS value, to be clocked out on next operation.""" + raise NotImplementedError('ABC') + + +class JtagEngine: + """High-level JTAG engine controller""" + + def __init__(self, ctrl: 'JtagController'): + self._ctrl = ctrl + self._log = getLogger('jtag.eng') + self._fsm = JtagStateMachine() + self._seq = bytearray() + + @property + def fsm(self) -> JtagStateMachine: + """Return the state machine.""" + return self._fsm + + @property + def controller(self) -> 'JtagController': + """Return the JTAG controller.""" + return self._ctrl + + def reset(self) -> None: + """Reset the attached TAP controller""" + self._ctrl.reset() + self._fsm.reset() + + def get_available_statenames(self): + """Return a list of supported state name""" + return [str(s) for s in self._fsm.states] + + def change_state(self, statename) -> None: + """Advance the TAP controller to the defined state""" + # find the state machine path to move to the new instruction + path = self._fsm.find_path(statename) + self._log.debug('path: %s', + ', '.join((str(s).upper() for s in path[1:]))) + # convert the path into an event sequence + events = self._fsm.get_events(path) + # update the remote device tap controller (write TMS consumes the seq) + self._ctrl.write_tms(events.copy()) + # update the current state machine's state + self._fsm.handle_events(events) + + def go_idle(self) -> None: + """Change the current TAP controller to the IDLE state""" + self.change_state('run_test_idle') + + def run(self) -> None: + """Change the current TAP controller to the IDLE state""" + self.change_state('run_test_idle') + + def capture_ir(self) -> None: + """Capture the current instruction from the TAP controller""" + self.change_state('capture_ir') + + def write_ir(self, instruction) -> None: + """Change the current instruction of the TAP controller""" + self.change_state('shift_ir') + ilength = len(instruction) # write consumes the instruction + self._ctrl.write(instruction) + self.change_state('update_ir') + # flush IR output + self._ctrl.tms = False + self._ctrl.read(ilength) + + def capture_dr(self) -> None: + """Capture the current data register from the TAP controller""" + self.change_state('capture_dr') + + def write_dr(self, data) -> None: + """Change the data register of the TAP controller""" + self.change_state('shift_dr') + self._ctrl.write(data) + self.change_state('update_dr') + + def read_dr(self, length: int) -> BitSequence: + """Read the data register from the TAP controller""" + self.change_state('shift_dr') + self._ctrl.tms = False + data = self._ctrl.read(length) + self.change_state('update_dr') + return data + + def write_tms(self, out) -> None: + """Change the TAP controller state""" + self._ctrl.write_tms(out) + + def write(self, out, use_last=False) -> None: + """Write a sequence of bits to TDI""" + self._ctrl.write(out, use_last) + + def read(self, length): + """Read out a sequence of bits from TDO""" + return self._ctrl.read(length) + + def set_tdi(self, value: bool): + """Force default TDI value, clocked out on each cycle.""" + self._ctrl.tdi = value + + def set_tms(self, value: bool): + """Force default TMS value clocked out on each cycle.""" + self._ctrl.tms = value From 2c889299b6691ce35ef56c80bbab7028305bf944 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:38:37 +0100 Subject: [PATCH 41/58] [ot] scripts/opentitan: add a Python module for DTM/DMI implementation. Signed-off-by: Emmanuel Blot --- scripts/opentitan/dtm.py | 99 ++++++++ scripts/opentitan/ot/dtm/__init__.py | 9 + scripts/opentitan/ot/dtm/dtm.py | 325 +++++++++++++++++++++++++++ 3 files changed, 433 insertions(+) create mode 100755 scripts/opentitan/dtm.py create mode 100644 scripts/opentitan/ot/dtm/__init__.py create mode 100644 scripts/opentitan/ot/dtm/dtm.py diff --git a/scripts/opentitan/dtm.py b/scripts/opentitan/dtm.py new file mode 100755 index 000000000000..14c86900e583 --- /dev/null +++ b/scripts/opentitan/dtm.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024, Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""Debug Transport Module tiny demo. + + :author: Emmanuel Blot +""" + +from argparse import ArgumentParser, Namespace +from os import linesep +from os.path import dirname, join as joinpath, normpath +from socket import create_connection +from traceback import format_exc +from typing import Optional +import sys + +# pylint: disable=wrong-import-position +# pylint: disable=wrong-import-order +# pylint: disable=import-error + +# JTAG module is available from the scripts/ directory +sys.path.append(joinpath(normpath(dirname(dirname(sys.argv[0]))))) + +from ot.util.log import configure_loggers # noqa: E402 +from ot.dtm import DebugTransportModule # noqa: E402 +from jtag.bits import BitSequence # noqa: E402 +from jtag.bitbang import JtagBitbangController # noqa: E402 +from jtag.jtag import JtagEngine # noqa: E402 + + +def idcode(engine: JtagEngine, ir_length: int) -> None: + """Retrieve ID code.""" + code = JtagBitbangController.INSTRUCTIONS['idcode'] + engine.write_ir(BitSequence(code, ir_length)) + value = engine.read_dr(32) + engine.go_idle() + return int(value) + + +def main(): + """Entry point.""" + debug = True + try: + args: Optional[Namespace] = None + argparser = ArgumentParser(description=sys.modules[__name__].__doc__) + qvm = argparser.add_argument_group(title='Virtual machine') + + qvm.add_argument('-H', '--host', default='127.0.0.1', + help='JTAG host (default: localhost)') + qvm.add_argument('-P', '--port', type=int, + default=JtagBitbangController.DEFAULT_PORT, + help=f'JTAG port, ' + f'default: {JtagBitbangController.DEFAULT_PORT}') + qvm.add_argument('-I', '--info', action='store_true', + help='Report JTAG ID code and DTM configuration') + qvm.add_argument('-l', '--ir-length', type=int, default=5, + help='bit length of the IR register') + extra = argparser.add_argument_group(title='Extras') + extra.add_argument('-v', '--verbose', action='count', + help='increase verbosity') + extra.add_argument('-d', '--debug', action='store_true', + help='enable debug mode') + + args = argparser.parse_args() + debug = args.debug + + configure_loggers(args.verbose, 'dtm', 'jtag') + + sock = create_connection((args.host, args.port), timeout=0.5) + sock.settimeout(0.1) + ctrl = JtagBitbangController(sock) + eng = JtagEngine(ctrl) + ctrl.tap_reset(True) + ir_length = args.ir_length + dtm = DebugTransportModule(eng, ir_length) + if args.info: + code = idcode(eng, ir_length) + print(f'IDCODE: 0x{code:x}') + sys.exit(0) + version = dtm['dtmcs'].dmi_version + abits = dtm['dtmcs'].abits + print(f'DTM: v{version[0]}.{version[1]}, {abits} bits') + dtm['dtmcs'].check() + dtm['dtmcs'].dmireset() + + # pylint: disable=broad-except + except Exception as exc: + print(f'{linesep}Error: {exc}', file=sys.stderr) + if debug: + print(format_exc(chain=False), file=sys.stderr) + sys.exit(1) + except KeyboardInterrupt: + sys.exit(2) + + +if __name__ == '__main__': + main() diff --git a/scripts/opentitan/ot/dtm/__init__.py b/scripts/opentitan/ot/dtm/__init__.py new file mode 100644 index 000000000000..7304c878e4d9 --- /dev/null +++ b/scripts/opentitan/ot/dtm/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""Debug Module tools. + + :author: Emmanuel Blot +""" + +from .dtm import DebugTransportModule diff --git a/scripts/opentitan/ot/dtm/dtm.py b/scripts/opentitan/ot/dtm/dtm.py new file mode 100644 index 000000000000..54a64b4d15fb --- /dev/null +++ b/scripts/opentitan/ot/dtm/dtm.py @@ -0,0 +1,325 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""Debug Module tools. + + :author: Emmanuel Blot +""" + + +from logging import getLogger +from sys import modules +from typing import Dict, Optional, Tuple + +# pylint: disable=import-error +from jtag.bits import BitSequence # noqa: E402 +from jtag.jtag import JtagEngine # noqa: E402 + + +class DMIError(RuntimeError): + """DMI Error.""" + + +class DMIBusyError(DMIError): + """Last operation still in progress.""" + + def __init__(self): + super().__init__('DMI is busy') + + +class DMIFailedError(DMIError): + """Last operation has failed.""" + + def __init__(self): + super().__init__('DMI execution failed') + + +class DTMRegister: + """Abstract base class for DTM registers.""" + + def __init__(self, dtm: 'DebugTransportModule'): + name = self.__class__.__name__ + if (not hasattr(self.__class__, 'ADDRESS') or + not isinstance(getattr(self, 'ADDRESS'), int)): + raise NotImplementedError(f'{name} address not defined') + self._dtm = dtm + self._log = getLogger(f'dtm.{name.lower()}') + + @property + def address(self) -> int: + """Return the register address.""" + # pylint: disable=no-member + return self.ADDRESS + + def _read(self, length: int) -> BitSequence: + """Read the current register value.""" + self._log.debug('read %d bits', length) + return self._dtm.read(self.address, length) + + def _write(self, bseq: BitSequence): + """Read the current register value.""" + self._log.debug('write %s', bseq) + return self._dtm.write(self.address, bseq) + + def _read_word(self) -> int: + """Read the current register value as a 32-bit value.""" + self._log.debug('read_word') + return self._dtm.read_word(self.address) + + def _write_word(self, value: int): + """Read the current register value as a 32-bit value.""" + self._log.debug('write_word %x', value) + return self._dtm.write_word(self.address, value) + + +class DTMCS(DTMRegister): + """DTM Control and Status register.""" + + ADDRESS = 0x10 + + @property + def idle(self) -> int: + """Minimum number of cycles a debugger should spend in Run-Test/Idle + after every DMI scan (hint only) + """ + hint = (self._read_word() >> 12) & 0b111 + self._log.debug('idle: %d', hint) + return hint + + @property + def dmistat(self) -> int: + """Return DMI status + + 0: No error. + 1: Reserved. Interpret the same as 2 (see DMI register) + 2: An operation failed (resulted in DMI operation of type 2). + 3: An operation was attempted while a DMI access was still in + progress (resulted in DMI operation of type 3). + """ + dmistat = (self._read_word() >> 10) & 0b11 + self._log.debug('dmistat: %d', dmistat) + return dmistat + + @property + def abits(self) -> int: + """The bit size of address in DMI.""" + abits = (self._read_word() >> 4) & 0b111111 + self._log.debug('abits: %d', abits) + return abits + + @property + def version(self) -> int: + """Version of the supported DMI specification (raw code).""" + version = self._read_word() & 0b1111 + self._log.debug('version: %d', version) + return version + + @property + def dmi_version(self) -> Tuple[int, int]: + """Version of the supported DMI specification.""" + try: + tversion = {0: (0, 11), 1: (0, 13)}[self.version] + except KeyError: + tversion = (0, 0) + self._log.debug('version: %d.%d', *tversion) + return tversion + + def check(self) -> None: + """Raise a DMI Error if any. + """ + self._log.debug('check') + dmistat = self.dmistat + err = self._dtm.build_error(dmistat) + if err: + self._dtm.set_sticky(err) + raise err + + def dmireset(self) -> None: + """Clears the sticky error state and allows the DTM to retry or complete + the previous transaction. + """ + self._log.debug('dmi reset') + self._write_word(1 << 16) + self._dtm.clear_sticky() + + def dmihardreset(self) -> None: + """Causes the DTM to forget about any outstanding DMI transactions. + """ + self._log.debug('dmi hard reset') + self._write_word(1 << 17) + self._dtm.clear_sticky() + + +class DMI(DTMRegister): + """Debug Module Interface Access.""" + + ADDRESS = 0x11 + + OPS = dict(nop=0, read=1, write=2) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._abits = 0 + + @property + def length(self) -> int: + """Return the register length in bits.""" + return self._abits + 32 + 2 + + def write(self, address: int, value: int) -> None: + """Write a 32-bit value to the specified address + """ + dmi = self._build_dmi(address) + value &= 0xffff_ffff + dmi |= value << 2 + dmi |= self.OPS['write'] + wbseq = BitSequence(dmi, self.length) + self._log.info('write: 0x%08x', value) + self._write(wbseq) + rbseq = self._read(self.length) + res = int(rbseq) & 0b11 + err = self._dtm.build_error(res) + if err: + self._log.error('op res %d -> %s', res, err) + self._dtm.set_sticky(err) + raise err + + def read(self, address: int) -> int: + """Read a 32-bit value from the specified address + """ + self._log.info('read @ 0x%x', address) + dmi = self._build_dmi(address) + dmi |= self.OPS['read'] + wbseq = BitSequence(dmi, self.length) + self._write(wbseq) + rbseq = self._read(self.length) + value = int(rbseq) + res = value & 0b11 + err = self._dtm.build_error(res) + if err: + self._log.error('op res %d -> %s', res, err) + self._dtm.set_sticky(err) + raise err + value >>= 2 + value &= 0xffff_ffff + self._log.info('read: 0x%08x', value) + return value + + def _build_dmi(self, address: int) -> int: + self._check_error() + if not self._abits: + self._abits = self._dtm.abits() + if self._abits < 1: + raise DMIError('Invalid reported address bits') + self._log.info('DMI width: %d bits', self._abits) + if address >= (1 << self._abits): + raise ValueError(f'Address 0x{address:x} too large, ' + f'max 0x{(1 << self._abits) -1:x}') + return address << (32 + 2) + + def _check_error(self) -> None: + self._dtm.check_sticky() + + +class DebugTransportModule: + """Debug Transport Modules provide access to the DM over JTAG. + + :param engine: JTAG engine + :param ir_length: the length in bits of the IR register + """ + + # INSTRUCTIONS = dict(dmtcs=DTMCS.ADDRESS, dmi=0x11) + # INSTRUCTIONS.update(JtagController.INSTRUCTIONS) + + def __init__(self, engine: JtagEngine, ir_length: int): + self._engine = engine + self._ir_length = ir_length + self._log = getLogger('dtm') + self._regs = self._load_registers() + self._sticky: Optional[DMIError] = None + + def __getitem__(self, name: str): + try: + return self._regs[name] + except KeyError as exc: + raise ValueError(f"No such DTM reg '{name}'") from exc + + @property + def engine(self) -> JtagEngine: + """Provide the associated engine.""" + return self._engine + + @classmethod + def build_error(cls, code: int) -> Optional[DMIError]: + """Build a DMIError from an error code.""" + if code in (1, 2): + return DMIFailedError() + if code == 3: + return DMIBusyError() + if code == 0: + return None + raise ValueError(f'Invalid DTM error code: {code}') + + def read(self, address: int, length: int) -> BitSequence: + """Read a bit sequence value.""" + self._engine.write_ir(BitSequence(address, self._ir_length)) + self._engine.set_tdi(False) + return self._engine.read_dr(length) + + def write(self, address: int, bseq: BitSequence) -> None: + """Write a bit sequence value.""" + self._engine.write_ir(BitSequence(address, self._ir_length)) + self._engine.write_dr(bseq) + self._engine.run() + + def read_word(self, address: int) -> int: + """Read a 32-bit value.""" + return int(self.read(address, 32)) + + def write_word(self, address: int, value: int) -> int: + """Write a 32-bit value.""" + self.write(address, BitSequence(value, 32)) + + def set_sticky(self, error: DMIError): + """Set sticky error. + @warning Internal API, should not be called but from the DMI + register. + """ + self._sticky = error + + def clear_sticky(self) -> None: + """Clear sticky error. + @warning Internal API, should not be called but from the DMI + register. + """ + self._sticky = None + + def check_sticky(self) -> None: + """Raise a DMIError if a sticky error has been recorded. + """ + if self._sticky: + raise self._sticky + + def abits(self) -> int: + """Report the bit size of address in DMI.""" + try: + dtmcs = self['dtmcs'] + except KeyError as exc: + raise DMIError('Missing DTMCS register') from exc + return dtmcs.abits + + def _load_registers(self) -> Dict[str, DTMRegister]: + module = modules[__name__] + regs = {} + for name in dir(module): + class_ = getattr(module, name) + if not isinstance(class_, type): + continue + if not issubclass(class_, DTMRegister) or class_ is DTMRegister: + continue + address = getattr(class_, 'ADDRESS', None) + if not address or not isinstance(address, int): + continue + self._log.debug('Instanciate %s', name) + regs[name.lower()] = class_(self) + return regs From 43f115638d5a94cbdcbb97d583dc626dd2c18235 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:39:17 +0100 Subject: [PATCH 42/58] [ot] scripts/opentitan: add a mailbox requester JTAG implementation Signed-off-by: Emmanuel Blot --- docs/opentitan/jtagmbx.md | 40 ++++++++++++++ scripts/opentitan/ot/mailbox/jtag.py | 79 ++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 scripts/opentitan/ot/mailbox/jtag.py diff --git a/docs/opentitan/jtagmbx.md b/docs/opentitan/jtagmbx.md index 755d530dba5c..d918739e91a3 100644 --- a/docs/opentitan/jtagmbx.md +++ b/docs/opentitan/jtagmbx.md @@ -31,6 +31,46 @@ where: QEMU should be started with an option such as `-jtag tcp::3335` so that the JTAG server is instantiated and listen for incoming connection on TCP port 3335. +#### macOS + +If you want to avoid the boring pop-up window from macOS +``` +Do you want the application “qemu-system-riscv32” to accept incoming network connections? +``` +restrict the listening interfaces to the localhost with `-jtag tcp:localhost:3335` as QEMU defaults +to listening on all interfaces, _i.e._ 0.0.0.0 + +## Communicating with JTAG server and JTAG MailBox using Python + +OpenTitan implementation provides JTAG/DTM/DMI/Mailbox stack available as Python modules: + +* jtag/tap module is available from `scripts/jtag` directory +* dtm/dmi and jtag mailbox modules are available from `scripts/opentitan` directory + +Python snippet to create a communication channel with the VM JTAG mailbox: + +````py +from socket import create_connection +from jtag.bitbang import JtagBitbangController +from jtag.jtag import JtagEngine +from ot.dtm import DebugTransportModule +from ot.mailbox.jtag import JtagMbox + +sock = create_connection(('localhost', 3335), timeout=1.0) +ctrl = JtagBitbangController(sock) +eng = JtagEngine(ctrl) +ctrl.tap_reset(True) +dtm = DebugTransportModule(eng, 5) # IR length depends on the actual machine +version, abits = dtm['dtmcs'].dmi_version, dtm['dtmcs'].abits +print(f'DTM: v{version[0]}.{version[1]}, {abits} bits') +dtm['dtmcs'].dmireset() +mbj = JtagMbox(dtm, 0x2200 >> 2) + +# See ot.mailbox.sysmbox.SysMbox for mailbox communication API +```` + +## Communicating with JTAG server using OpenOCD + It is possible from OpenOCD running a host to connect to the embedded JTAG server using the `remote_bitbang` protocol, using a configuration script such as diff --git a/scripts/opentitan/ot/mailbox/jtag.py b/scripts/opentitan/ot/mailbox/jtag.py new file mode 100644 index 000000000000..63520f3115d5 --- /dev/null +++ b/scripts/opentitan/ot/mailbox/jtag.py @@ -0,0 +1,79 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""Mailbox over JTAG access. + + :author: Emmanuel Blot +""" + +from logging import getLogger + +# see scripts/jtag +# pylint: disable=import-error +# pylint: disable=unused-import +from jtag.jtag import JtagError # noqa: F401 +from .sysmbox import SysMbox +from ..dtm import DebugTransportModule + + +class JtagMbox(SysMbox): + """JTAG Mailbox requester API + """ + + SYSREGS = dict(control=2, status=3, wdata=4, rdata=5) + + def __init__(self, dtm: 'DebugTransportModule', address: int): + super().__init__() + self._log = getLogger('dtm.jtagmbx') + self._dmi = dtm['dmi'] + self._address = address + + @property + def busy(self) -> bool: + return bool(self._read_reg('status') & 0b001) + + @property + def on_error(self) -> bool: + return bool(self._read_reg('status') & 0b100) + + @property + def object_ready(self) -> bool: + return bool(self._read_reg('status') >> 31) + + def go(self) -> None: + self._write_reg('control', 1 << 31) + + def abort(self) -> None: + self._write_reg('control', 0b1) + + def write_word(self, word: int) -> None: + self._write_reg('wdata', word) + + def read_word(self, ack: bool = True) -> int: + word = self._read_reg('rdata') + if ack: + self.acknowledge_read() + return word + + def acknowledge_read(self) -> None: + self._write_reg('rdata', 0) # value is meaningless + + def _write_reg(self, name: str, value: int) -> None: + if value >= (1 << 32): + raise ValueError('Invalid value') + try: + reg = self.SYSREGS[name] + except KeyError as exc: + raise ValueError(f"No such mailbox register: '{name}'") from exc + self._log.info('write %s: 0x%08x', name, value) + return self._dmi.write(self._address + reg, value) + + def _read_reg(self, name: str) -> int: + try: + reg = self.SYSREGS[name] + except KeyError as exc: + raise ValueError(f"No such mailbox register: '{name}'") from exc + self._log.info('read %s', name) + value = self._dmi.read(self._address + reg) + self._log.info('read 0x%08x', value) + return value From 541e7cd97c812288ab7210dfefb525c404a2b84f Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:45:13 +0100 Subject: [PATCH 43/58] [ot] hw/riscv: rename dmi as dtm Signed-off-by: Emmanuel Blot --- hw/riscv/Kconfig | 2 +- hw/riscv/{dmi.c => dtm.c} | 130 +++++++++++++++--------------- hw/riscv/meson.build | 2 +- hw/riscv/trace-events | 14 ++-- include/hw/riscv/{dmi.h => dtm.h} | 22 ++--- 5 files changed, 86 insertions(+), 84 deletions(-) rename hw/riscv/{dmi.c => dtm.c} (79%) rename include/hw/riscv/{dmi.h => dtm.h} (76%) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index c3f11dd08c8a..a04a210f5a71 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -138,7 +138,7 @@ config RISCV_VIRT config RISCV_DEBUG bool -config RISCV_DMI +config RISCV_DTM bool config SHAKTI_C diff --git a/hw/riscv/dmi.c b/hw/riscv/dtm.c similarity index 79% rename from hw/riscv/dmi.c rename to hw/riscv/dtm.c index d5ca6945ef75..c386194926db 100644 --- a/hw/riscv/dmi.c +++ b/hw/riscv/dtm.c @@ -1,5 +1,5 @@ /* - * QEMU Debug Module Interface and Controller + * QEMU Debug Transport Module * * Copyright (c) 2022-2024 Rivos, Inc. * Author(s): @@ -25,7 +25,7 @@ * * Generated code for absract commands has been extracted from the PULP Debug * module whose file (dm_mem.sv) contains the following copyright. This piece of - * code is self contained within the `riscv_dmi_dm_access_register` function: + * code is self contained within the `riscv_dtm_dm_access_register` function: * * Copyright and related rights are licensed under the Solderpad Hardware * License, Version 0.51 (the “License”); you may not use this file except in @@ -57,7 +57,7 @@ #include "hw/qdev-properties.h" #include "hw/registerfields.h" #include "hw/riscv/debug.h" -#include "hw/riscv/dmi.h" +#include "hw/riscv/dtm.h" #include "hw/sysbus.h" #include "sysemu/cpus.h" #include "sysemu/hw_accel.h" @@ -90,10 +90,10 @@ REG64(DMI, 0x11u) * Macros */ -#define xtrace_riscv_dmi_error(_msg_) \ - trace_riscv_dmi_error(__func__, __LINE__, _msg_) -#define xtrace_riscv_dmi_info(_msg_, _val_) \ - trace_riscv_dmi_info(__func__, __LINE__, _msg_, _val_) +#define xtrace_riscv_dtm_error(_msg_) \ + trace_riscv_dtm_error(__func__, __LINE__, _msg_) +#define xtrace_riscv_dtm_info(_msg_, _val_) \ + trace_riscv_dtm_info(__func__, __LINE__, _msg_, _val_) /* * Type definitions @@ -110,7 +110,7 @@ typedef struct RISCVDebugModule { } RISCVDebugModule; /** Debug Module Interface */ -struct RISCVDMIState { +struct RISCVDTMState { DeviceState parent; RISCVDebugModuleList dms; @@ -129,14 +129,14 @@ struct RISCVDMIState { * Forward declarations */ -static void riscv_dmi_reset(DeviceState *dev); -static RISCVDebugModule* riscv_dmi_get_dm(RISCVDMIState *s, uint32_t addr); -static void riscv_dmi_sort_dms(RISCVDMIState *s); +static void riscv_dtm_reset(DeviceState *dev); +static RISCVDebugModule* riscv_dtm_get_dm(RISCVDTMState *s, uint32_t addr); +static void riscv_dtm_sort_dms(RISCVDTMState *s); -static void riscv_dmi_tap_dtmcs_capture(TAPDataHandler *tdh); -static void riscv_dmi_tap_dtmcs_update(TAPDataHandler *tdh); -static void riscv_dmi_tap_dmi_capture(TAPDataHandler *tdh); -static void riscv_dmi_tap_dmi_update(TAPDataHandler *tdh); +static void riscv_dtm_tap_dtmcs_capture(TAPDataHandler *tdh); +static void riscv_dtm_tap_dtmcs_update(TAPDataHandler *tdh); +static void riscv_dtm_tap_dmi_capture(TAPDataHandler *tdh); +static void riscv_dtm_tap_dmi_update(TAPDataHandler *tdh); /* * Constants @@ -150,16 +150,16 @@ static const TAPDataHandler RISCVDMI_DTMCS = { .name = "dtmcs", .length = 32u, .value = RISCV_DEBUG_DMI_VERSION, /* abits updated at runtime */ - .capture = &riscv_dmi_tap_dtmcs_capture, - .update = &riscv_dmi_tap_dtmcs_update, + .capture = &riscv_dtm_tap_dtmcs_capture, + .update = &riscv_dtm_tap_dtmcs_update, }; static const TAPDataHandler RISCVDMI_DMI = { .name = "dmi", /* data, op; abits updated at runtime */ .length = R_DMI_OP_LENGTH + R_DMI_DATA_LENGTH, - .capture = &riscv_dmi_tap_dmi_capture, - .update = &riscv_dmi_tap_dmi_update, + .capture = &riscv_dtm_tap_dmi_capture, + .update = &riscv_dtm_tap_dmi_update, }; #define MAKE_RUNSTATE_ENTRY(_ent_) [RUN_STATE_##_ent_] = stringify(_ent_) @@ -194,10 +194,10 @@ static const char *RISCVDMI_RUNSTATE_NAMES[] = { /* Public API */ /* -------------------------------------------------------------------------- */ -bool riscv_dmi_register_dm(DeviceState *dev, RISCVDebugDeviceState *dbgdev, +bool riscv_dtm_register_dm(DeviceState *dev, RISCVDebugDeviceState *dbgdev, hwaddr base_addr, hwaddr size) { - RISCVDMIState *s = RISCV_DMI(dev); + RISCVDTMState *s = RISCV_DTM(dev); if ((base_addr + size - 1u) > (1u << s->abits)) { error_setg(&error_fatal, @@ -235,10 +235,10 @@ bool riscv_dmi_register_dm(DeviceState *dev, RISCVDebugDeviceState *dbgdev, QLIST_INSERT_HEAD(&s->dms, dm, entry); s->last_dm = dm; - trace_riscv_dmi_register_dm(count, base_addr, base_addr + size - 1u, + trace_riscv_dtm_register_dm(count, base_addr, base_addr + size - 1u, s->jtag_ok); - riscv_dmi_sort_dms(s); + riscv_dtm_sort_dms(s); return s->jtag_ok; } @@ -247,20 +247,20 @@ bool riscv_dmi_register_dm(DeviceState *dev, RISCVDebugDeviceState *dbgdev, /* DTMCS/DMI implementation */ /* -------------------------------------------------------------------------- */ -static void riscv_dmi_tap_dtmcs_capture(TAPDataHandler *tdh) +static void riscv_dtm_tap_dtmcs_capture(TAPDataHandler *tdh) { - RISCVDMIState *s = tdh->opaque; + RISCVDTMState *s = tdh->opaque; tdh->value = (s->abits << 4u) | (RISCV_DEBUG_DMI_VERSION << 0u) | ((uint64_t)s->dmistat << 10u); /* see DMI op result */ } -static void riscv_dmi_tap_dtmcs_update(TAPDataHandler *tdh) +static void riscv_dtm_tap_dtmcs_update(TAPDataHandler *tdh) { - RISCVDMIState *s = tdh->opaque; + RISCVDTMState *s = tdh->opaque; if (tdh->value & (1u << 16u)) { /* dmireset */ - trace_riscv_dmi_dtmcs_reset(); + trace_riscv_dtm_dtmcs_reset(); s->dmistat = RISCV_DEBUG_NOERR; } if (tdh->value & (1u << 17u)) { @@ -269,15 +269,15 @@ static void riscv_dmi_tap_dtmcs_update(TAPDataHandler *tdh) } } -static void riscv_dmi_tap_dmi_capture(TAPDataHandler *tdh) +static void riscv_dtm_tap_dmi_capture(TAPDataHandler *tdh) { - RISCVDMIState *s = tdh->opaque; + RISCVDTMState *s = tdh->opaque; uint32_t addr = s->address; uint32_t value; if (s->dmistat == RISCV_DEBUG_NOERR) { - RISCVDebugModule *dm = riscv_dmi_get_dm(s, addr); + RISCVDebugModule *dm = riscv_dtm_get_dm(s, addr); if (!dm) { s->dmistat = RISCV_DEBUG_FAILED; value = 0; @@ -298,9 +298,9 @@ static void riscv_dmi_tap_dmi_capture(TAPDataHandler *tdh) ((uint64_t)(s->dmistat & 0b11)); } -static void riscv_dmi_tap_dmi_update(TAPDataHandler *tdh) +static void riscv_dtm_tap_dmi_update(TAPDataHandler *tdh) { - RISCVDMIState *s = tdh->opaque; + RISCVDTMState *s = tdh->opaque; uint32_t value; uint32_t addr = @@ -310,7 +310,7 @@ static void riscv_dmi_tap_dmi_update(TAPDataHandler *tdh) /* store address for next read back */ s->address = addr; - RISCVDebugModule *dm = riscv_dmi_get_dm(s, addr); + RISCVDebugModule *dm = riscv_dtm_get_dm(s, addr); if (!dm) { s->dmistat = RISCV_DEBUG_FAILED; qemu_log_mask(LOG_UNIMP, "%s: Unknown DM address 0x%x\n", __func__, @@ -344,7 +344,7 @@ static void riscv_dmi_tap_dmi_update(TAPDataHandler *tdh) } } -static void riscv_dmi_register_tap_handlers(RISCVDMIState *s) +static void riscv_dtm_register_tap_handlers(RISCVDTMState *s) { /* * copy the template to update the opaque value @@ -356,7 +356,7 @@ static void riscv_dmi_register_tap_handlers(RISCVDMIState *s) tdh.value |= s->abits << 4u; /* add address bit count */ tdh.opaque = s; if (jtag_register_handler(RISCVDMI_DTMCS_IR, &tdh)) { - xtrace_riscv_dmi_error("cannot register DMTCS"); + xtrace_riscv_dtm_error("cannot register DMTCS"); return; } @@ -365,12 +365,12 @@ static void riscv_dmi_register_tap_handlers(RISCVDMIState *s) tdh.opaque = s; /* the data handler is copied by the TAP controller */ if (jtag_register_handler(RISCVDMI_DMI_IR, &tdh)) { - xtrace_riscv_dmi_error("cannot register DMI"); + xtrace_riscv_dtm_error("cannot register DMI"); return; } } -static RISCVDebugModule *riscv_dmi_get_dm(RISCVDMIState *s, uint32_t addr) +static RISCVDebugModule *riscv_dtm_get_dm(RISCVDTMState *s, uint32_t addr) { RISCVDebugModule *dm = s->last_dm; @@ -389,21 +389,21 @@ static RISCVDebugModule *riscv_dmi_get_dm(RISCVDMIState *s, uint32_t addr) return NULL; } -static void riscv_dmi_vm_state_change(void *opaque, bool running, +static void riscv_dtm_vm_state_change(void *opaque, bool running, RunState state) { (void)opaque; (void)running; - trace_riscv_dmi_vm_state_change(RUNSTATE_NAME(state), state); + trace_riscv_dtm_vm_state_change(RUNSTATE_NAME(state), state); } -static int riscv_dmi_order_dm(const void *pdm1, const void *pdm2) +static int riscv_dtm_order_dm(const void *pdm1, const void *pdm2) { return ((int)(*(RISCVDebugModule **)pdm1)->base) - ((int)(*(RISCVDebugModule **)pdm2)->base); } -static void riscv_dmi_sort_dms(RISCVDMIState *s) +static void riscv_dtm_sort_dms(RISCVDTMState *s) { RISCVDebugModule *dm; @@ -421,7 +421,7 @@ static void riscv_dmi_sort_dms(RISCVDMIState *s) } /* sort DM reference by increasing base address */ - qsort(dma, count, sizeof(RISCVDebugModule *), &riscv_dmi_order_dm); + qsort(dma, count, sizeof(RISCVDebugModule *), &riscv_dtm_order_dm); /* create a new list of ordered, managed DMs */ RISCVDebugModuleList sorted; @@ -442,14 +442,14 @@ static void riscv_dmi_sort_dms(RISCVDMIState *s) g_free(dma); } -static Property riscv_dmi_properties[] = { - DEFINE_PROP_UINT32("abits", RISCVDMIState, abits, 0x7u), +static Property riscv_dtm_properties[] = { + DEFINE_PROP_UINT32("abits", RISCVDTMState, abits, 0x7u), DEFINE_PROP_END_OF_LIST(), }; -static void riscv_dmi_reset(DeviceState *dev) +static void riscv_dtm_reset(DeviceState *dev) { - RISCVDMIState *s = RISCV_DMI(dev); + RISCVDTMState *s = RISCV_DTM(dev); s->address = 0; s->last_dm = NULL; @@ -460,9 +460,9 @@ static void riscv_dmi_reset(DeviceState *dev) } } -static void riscv_dmi_realize(DeviceState *dev, Error **errp) +static void riscv_dtm_realize(DeviceState *dev, Error **errp) { - RISCVDMIState *s = RISCV_DMI(dev); + RISCVDTMState *s = RISCV_DTM(dev); if (s->abits < 7u || s->abits > 30u) { error_setg(errp, "Invalid address bit count"); @@ -473,41 +473,41 @@ static void riscv_dmi_realize(DeviceState *dev, Error **errp) s->jtag_ok = jtag_tap_enabled(); if (s->jtag_ok) { - (void)riscv_dmi_register_tap_handlers(s); + (void)riscv_dtm_register_tap_handlers(s); } } -static void riscv_dmi_init(Object *obj) +static void riscv_dtm_init(Object *obj) { - RISCVDMIState *s = RISCV_DMI(obj); + RISCVDTMState *s = RISCV_DTM(obj); - qemu_add_vm_change_state_handler(&riscv_dmi_vm_state_change, s); + qemu_add_vm_change_state_handler(&riscv_dtm_vm_state_change, s); QLIST_INIT(&s->dms); } -static void riscv_dmi_class_init(ObjectClass *klass, void *data) +static void riscv_dtm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); (void)data; - dc->reset = &riscv_dmi_reset; - dc->realize = &riscv_dmi_realize; - device_class_set_props(dc, riscv_dmi_properties); + dc->reset = &riscv_dtm_reset; + dc->realize = &riscv_dtm_realize; + device_class_set_props(dc, riscv_dtm_properties); set_bit(DEVICE_CATEGORY_MISC, dc->categories); } -static const TypeInfo riscv_dmi_info = { - .name = TYPE_RISCV_DMI, +static const TypeInfo riscv_dtm_info = { + .name = TYPE_RISCV_DTM, .parent = TYPE_DEVICE, - .instance_size = sizeof(RISCVDMIState), - .instance_init = &riscv_dmi_init, - .class_init = &riscv_dmi_class_init, + .instance_size = sizeof(RISCVDTMState), + .instance_init = &riscv_dtm_init, + .class_init = &riscv_dtm_class_init, }; -static void riscv_dmi_register_types(void) +static void riscv_dtm_register_types(void) { - type_register_static(&riscv_dmi_info); + type_register_static(&riscv_dtm_info); } -type_init(riscv_dmi_register_types); +type_init(riscv_dtm_register_types); diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build index 810f313988f9..343603d10216 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -15,6 +15,6 @@ riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c')) riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c')) riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) riscv_ss.add(when: 'CONFIG_RISCV_DEBUG', if_true: files('debug.c')) -riscv_ss.add(when: 'CONFIG_RISCV_DMI', if_true: files('dmi.c')) +riscv_ss.add(when: 'CONFIG_RISCV_DTM', if_true: files('dtm.c')) hw_arch += {'riscv': riscv_ss} diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events index 5f963b3d1cc7..d77b54615bb4 100644 --- a/hw/riscv/trace-events +++ b/hw/riscv/trace-events @@ -1,6 +1,8 @@ -# Debug Module Interface -riscv_dmi_dtmcs_reset(void) "" -riscv_dmi_error(const char *func, int line, const char *msg) "%s:%d %s" -riscv_dmi_info(const char *func, int line, const char *msg, uint32_t val) "%s:%d %s 0x%08x" -riscv_dmi_register_dm(unsigned count, uint64_t first, uint64_t last, bool ok) "#%u 0x%" PRIx64 "..0x%" PRIx64 ": %u" -riscv_dmi_vm_state_change(const char *name, unsigned state) "VM state: %s[%u]" +# See documentation at docs/devel/tracing.rst + +# Debug Transport Module +riscv_dtm_dtmcs_reset(void) "" +riscv_dtm_error(const char *func, int line, const char *msg) "%s:%d %s" +riscv_dtm_info(const char *func, int line, const char *msg, uint32_t val) "%s:%d %s 0x%08x" +riscv_dtm_register_dm(unsigned count, uint64_t first, uint64_t last, bool ok) "#%u 0x%" PRIx64 "..0x%" PRIx64 ": %u" +riscv_dtm_vm_state_change(const char *name, unsigned state) "VM state: %s[%u]" diff --git a/include/hw/riscv/dmi.h b/include/hw/riscv/dtm.h similarity index 76% rename from include/hw/riscv/dmi.h rename to include/hw/riscv/dtm.h index 7bbc6acf0632..c7eb9752a865 100644 --- a/include/hw/riscv/dmi.h +++ b/include/hw/riscv/dtm.h @@ -1,7 +1,7 @@ /* - * QEMU RISC-V Debug Module Interface and Controller + * QEMU RISC-V Debug Tranport Module * - * Copyright (c) 2022-2023 Rivos, Inc. + * Copyright (c) 2022-2024 Rivos, Inc. * Author(s): * Emmanuel Blot * @@ -24,27 +24,27 @@ * THE SOFTWARE. */ -#ifndef HW_RISCV_DMI_H -#define HW_RISCV_DMI_H +#ifndef HW_RISCV_DTM_H +#define HW_RISCV_DTM_H #include "exec/hwaddr.h" #include "hw/riscv/debug.h" -#define TYPE_RISCV_DMI "riscv-dmi" -OBJECT_DECLARE_SIMPLE_TYPE(RISCVDMIState, RISCV_DMI) +#define TYPE_RISCV_DTM "riscv.dtm" +OBJECT_DECLARE_SIMPLE_TYPE(RISCVDTMState, RISCV_DTM) /** - * Register a debug module on the Debug Module Interface. + * Register a debug module on the Debug Transport Module. * It is valid to register the same module multiple time, as long as base_addr * and size are not modified. * - * @dev the DMI instance + * @dev the DTM instance * @dmif the DM to register * @base_addr the address of the first DM register * @size the count of DM registers - * @return @c true if DMI is enabled, @c false otherwise + * @return @c true if DTM is enabled, @c false otherwise */ -bool riscv_dmi_register_dm(DeviceState *dev, RISCVDebugDeviceState *dmif, +bool riscv_dtm_register_dm(DeviceState *dev, RISCVDebugDeviceState *dmif, hwaddr base_addr, hwaddr size); -#endif /* HW_RISCV_DMI_H */ +#endif /* HW_RISCV_DTM_H */ From 97e6544bfb5728197e6c04b49854c96e406ed136 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 22 Feb 2024 19:53:16 +0100 Subject: [PATCH 44/58] [ot] hw/opentitan: rename dmi as dtm Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_dm_tl.c | 18 +++++++++--------- hw/riscv/Kconfig | 2 +- hw/riscv/ot_darjeeling.c | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/hw/opentitan/ot_dm_tl.c b/hw/opentitan/ot_dm_tl.c index 9590b4a62cb3..713ea9dd0ca2 100644 --- a/hw/opentitan/ot_dm_tl.c +++ b/hw/opentitan/ot_dm_tl.c @@ -38,7 +38,7 @@ #include "hw/qdev-properties.h" #include "hw/registerfields.h" #include "hw/riscv/debug.h" -#include "hw/riscv/dmi.h" +#include "hw/riscv/dtm.h" #include "hw/riscv/ibex_common.h" #include "hw/sysbus.h" #include "trace.h" @@ -50,9 +50,9 @@ struct OtDMTLState { hwaddr tl_offset; uint32_t value; MemTxAttrs attrs; - bool dmi_ok; /* DMI is available */ + bool dtm_ok; /* DTM is available */ - RISCVDMIState *dmi; + RISCVDTMState *dtm; SysBusDevice *tl_dev; char *tl_as_name; uint64_t tl_base; @@ -62,7 +62,7 @@ struct OtDMTLState { }; /* -------------------------------------------------------------------------- */ -/* DMI interface implementation */ +/* DTM interface implementation */ /* -------------------------------------------------------------------------- */ static RISCVDebugResult @@ -124,7 +124,7 @@ static uint32_t ot_dm_tl_read_value(RISCVDebugDeviceState *dev) } static Property ot_dm_tl_properties[] = { - DEFINE_PROP_LINK("dmi", OtDMTLState, dmi, TYPE_RISCV_DMI, RISCVDMIState *), + DEFINE_PROP_LINK("dtm", OtDMTLState, dtm, TYPE_RISCV_DTM, RISCVDTMState *), DEFINE_PROP_UINT32("dmi_addr", OtDMTLState, dmi_addr, 0), DEFINE_PROP_UINT32("dmi_size", OtDMTLState, dmi_size, 0), DEFINE_PROP_STRING("tl_as_name", OtDMTLState, tl_as_name), @@ -139,14 +139,14 @@ static void ot_dm_tl_reset(DeviceState *dev) { OtDMTLState *dmtl = OT_DM_TL(dev); - g_assert(dmtl->dmi != NULL); + g_assert(dmtl->dtm != NULL); g_assert(dmtl->dmi_size); - dmtl->dmi_ok = - riscv_dmi_register_dm(DEVICE(dmtl->dmi), RISCV_DEBUG_DEVICE(dev), + dmtl->dtm_ok = + riscv_dtm_register_dm(DEVICE(dmtl->dtm), RISCV_DEBUG_DEVICE(dev), dmtl->dmi_addr, dmtl->dmi_size); - if (dmtl->dmi_ok) { + if (dmtl->dtm_ok) { Object *soc = OBJECT(dev)->parent; Object *obj; OtAddressSpaceState *oas; diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index a04a210f5a71..a57387423495 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -44,7 +44,7 @@ config OT_DARJEELING select OT_SRAM_CTRL select OT_TIMER select OT_UART - select RISCV_DMI + select RISCV_DTM select SIFIVE_PLIC select SPLIT_IRQ diff --git a/hw/riscv/ot_darjeeling.c b/hw/riscv/ot_darjeeling.c index 2bb506b0f6f4..480fe1177eaf 100644 --- a/hw/riscv/ot_darjeeling.c +++ b/hw/riscv/ot_darjeeling.c @@ -67,7 +67,7 @@ #include "hw/opentitan/ot_timer.h" #include "hw/opentitan/ot_uart.h" #include "hw/qdev-properties.h" -#include "hw/riscv/dmi.h" +#include "hw/riscv/dtm.h" #include "hw/riscv/ibex_common.h" #include "hw/riscv/ot_darjeeling.h" #include "hw/ssi/ssi.h" @@ -106,7 +106,7 @@ enum OtDjSocDevice { OT_DJ_SOC_DEV_DM_TL_LC_CTRL, OT_DJ_SOC_DEV_DM_TL_MBX, OT_DJ_SOC_DEV_DMA, - OT_DJ_SOC_DEV_DMI, + OT_DJ_SOC_DEV_DTM, OT_DJ_SOC_DEV_EDN0, OT_DJ_SOC_DEV_EDN1, OT_DJ_SOC_DEV_GPIO, @@ -356,8 +356,8 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { IBEX_DEV_BOOL_PROP("start-powered-off", true) ), }, - [OT_DJ_SOC_DEV_DMI] = { - .type = TYPE_RISCV_DMI, + [OT_DJ_SOC_DEV_DTM] = { + .type = TYPE_RISCV_DTM, .prop = IBEXDEVICEPROPDEFS( IBEX_DEV_UINT_PROP("abits", 12u) ), @@ -366,7 +366,7 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { .type = TYPE_OT_DM_TL, .instance = 0, .link = IBEXDEVICELINKDEFS( - OT_DJ_SOC_DEVLINK("dmi", DMI), + OT_DJ_SOC_DEVLINK("dtm", DTM), OT_DJ_SOC_DEVLINK("tl_dev", LC_CTRL) ), .prop = IBEXDEVICEPROPDEFS( @@ -380,7 +380,7 @@ static const IbexDeviceDef ot_dj_soc_devices[] = { .type = TYPE_OT_DM_TL, .instance = 1, .link = IBEXDEVICELINKDEFS( - OT_DJ_SOC_DEVLINK("dmi", DMI), + OT_DJ_SOC_DEVLINK("dtm", DTM), OT_DJ_SOC_DEVLINK("tl_dev", MBX_JTAG) ), .prop = IBEXDEVICEPROPDEFS( @@ -1130,7 +1130,7 @@ static void ot_dj_soc_reset_hold(Object *obj) c->parent_phases.hold(obj); } - Object *dmi = OBJECT(s->devices[OT_DJ_SOC_DEV_DMI]); + Object *dmi = OBJECT(s->devices[OT_DJ_SOC_DEV_DTM]); resettable_reset(dmi, RESET_TYPE_COLD); // TODO: not sure where Reset is plugged here... From 8d7b539ddc13cbf169b132dfab3937fda469b1fe Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:25:00 +0100 Subject: [PATCH 45/58] [ot] jtag: jtag_bitbang: improve trace messages Signed-off-by: Emmanuel Blot --- jtag/jtag_bitbang.c | 16 ++++++++++------ jtag/trace-events | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/jtag/jtag_bitbang.c b/jtag/jtag_bitbang.c index 410d353bfa23..ecefc1d65c72 100644 --- a/jtag/jtag_bitbang.c +++ b/jtag/jtag_bitbang.c @@ -197,8 +197,8 @@ static TAPServerState tapserver_state; * TAP State Machine implementation */ -static void tapctrl_dump_register(const char *msg, uint64_t value, - size_t length) +static void tapctrl_dump_register(const char *msg, const char *iname, + uint64_t value, size_t length) { char buf[80]; if (length > 64u) { @@ -211,7 +211,11 @@ static void tapctrl_dump_register(const char *msg, uint64_t value, } buf[ix] = '\0'; - trace_jtag_tapctrl_dump_register(msg, value, length, buf); + if (iname) { + trace_jtag_tapctrl_idump_register(msg, iname, value, length, buf); + } else { + trace_jtag_tapctrl_dump_register(msg, value, length, buf); + } } static bool tapctrl_has_data_handler(TAPController *tap, unsigned code) @@ -327,7 +331,7 @@ static void tapctrl_shift_ir(TAPController *tap, bool tdi) static void tapctrl_update_ir(TAPController *tap) { tap->ir_hold = tap->ir; - tapctrl_dump_register("Update IR", tap->ir_hold, tap->ir_len); + tapctrl_dump_register("Update IR", NULL, tap->ir_hold, tap->ir_len); } static void tapctrl_capture_dr(TAPController *tap) @@ -359,7 +363,7 @@ static void tapctrl_capture_dr(TAPController *tap) tdh->capture(tdh); } tap->dr = tdh->value; - tapctrl_dump_register("Capture DR", tap->dr, tap->dr_len); + tapctrl_dump_register("Capture DR", tap->tdh->name, tap->dr, tap->dr_len); } static void tapctrl_shift_dr(TAPController *tap, bool tdi) @@ -370,7 +374,7 @@ static void tapctrl_shift_dr(TAPController *tap, bool tdi) static void tapctrl_update_dr(TAPController *tap) { - tapctrl_dump_register("Update DR", tap->dr, tap->dr_len); + tapctrl_dump_register("Update DR", tap->tdh->name, tap->dr, tap->dr_len); TAPDataHandler *tdh = tap->tdh; tdh->value = tap->dr; if (tdh->update) { diff --git a/jtag/trace-events b/jtag/trace-events index b141ab845dd1..45c30deec64f 100644 --- a/jtag/trace-events +++ b/jtag/trace-events @@ -2,7 +2,8 @@ jtag_tapctrl_change(const char *msg, const char *value) "%s %s" jtag_tapctrl_change_state(const char *prev, const char *new) "%s -> %s" -jtag_tapctrl_dump_register(const char *msg, uint64_t val, size_t len, const char *buf) "%s: 0x%016" PRIx64 "/%zu [%s]" +jtag_tapctrl_dump_register(const char *msg, uint64_t val, size_t len, const char *buf) "%s: 0x%" PRIx64 "/%zu [b%s]" +jtag_tapctrl_idump_register(const char *msg, const char *iname, uint64_t val, size_t len, const char *buf) "%s (%s): 0x%" PRIx64 "/%zu [b%s]" jtag_tapctrl_init(size_t irlen, uint32_t ircode) "irlength %zu, idcode 0x%08x" jtag_tapctrl_register(unsigned code, const char *name) "register 0x%x: %s" jtag_tapctrl_reset(bool tap, bool sys) "tap: %u, system: %u" From 02d42885b66f95a900f59220f5dcd3b3ae8201ff Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 22 Feb 2024 19:57:37 +0100 Subject: [PATCH 46/58] [ot] hw/riscv: dtm: fix handling of NOP operations. Signed-off-by: Emmanuel Blot --- hw/riscv/dtm.c | 74 ++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/hw/riscv/dtm.c b/hw/riscv/dtm.c index c386194926db..7792f6a72fd0 100644 --- a/hw/riscv/dtm.c +++ b/hw/riscv/dtm.c @@ -86,18 +86,21 @@ REG64(DMI, 0x11u) FIELD(DMI, DATA, 2u, 32u) FIELD(DMI, ADDRESS, 34u, 64u-34u) /* real width is a runtime property */ -/* - * Macros - */ - #define xtrace_riscv_dtm_error(_msg_) \ trace_riscv_dtm_error(__func__, __LINE__, _msg_) #define xtrace_riscv_dtm_info(_msg_, _val_) \ trace_riscv_dtm_info(__func__, __LINE__, _msg_, _val_) /* - * Type definitions + * DMI register operations + * see RISC-V debug spec secttion 6.1.5 Debug Module Interface Access */ +typedef enum { + DMI_IGNORE, + DMI_READ, + DMI_WRITE, + DMI_RESERVED, +} RISCVDMIOperation; typedef QLIST_HEAD(, RISCVDebugModule) RISCVDebugModuleList; @@ -142,9 +145,9 @@ static void riscv_dtm_tap_dmi_update(TAPDataHandler *tdh); * Constants */ -#define RISCV_DEBUG_DMI_VERSION 1u /* RISC-V Debug spec 0.13.x & 1.0 */ -#define RISCVDMI_DTMCS_IR 0x10u -#define RISCVDMI_DMI_IR 0x11u +#define RISCV_DEBUG_DMI_VERSION 1u /* RISC-V Debug spec 0.13.x & 1.0 */ +#define RISCVDMI_DTMCS_IR 0x10u +#define RISCVDMI_DMI_IR 0x11u static const TAPDataHandler RISCVDMI_DTMCS = { .name = "dtmcs", @@ -274,20 +277,21 @@ static void riscv_dtm_tap_dmi_capture(TAPDataHandler *tdh) RISCVDTMState *s = tdh->opaque; uint32_t addr = s->address; - uint32_t value; + uint32_t value = 0; if (s->dmistat == RISCV_DEBUG_NOERR) { - RISCVDebugModule *dm = riscv_dtm_get_dm(s, addr); - if (!dm) { - s->dmistat = RISCV_DEBUG_FAILED; - value = 0; - qemu_log_mask(LOG_UNIMP, "%s: Unknown DM address 0x%x\n", __func__, - addr); - } else { - value = dm->dc->read_value(dm->dev); + unsigned op = (unsigned)(tdh->value & 0b11); + if (op == DMI_READ) { + RISCVDebugModule *dm = riscv_dtm_get_dm(s, addr); + if (!dm) { + s->dmistat = RISCV_DEBUG_FAILED; + value = 0; + qemu_log_mask(LOG_UNIMP, "%s: Unknown DM address 0x%x\n", __func__, + addr); + } else { + value = dm->dc->read_value(dm->dev); + } } - } else { - value = 0; } /* @@ -307,14 +311,23 @@ static void riscv_dtm_tap_dmi_update(TAPDataHandler *tdh) (uint32_t)extract64(tdh->value, R_DMI_ADDRESS_SHIFT, (int)s->abits); unsigned op = (unsigned)(tdh->value & 0b11); + if (op == DMI_IGNORE) { + /* + * Don’t send anything over the DMI during Update-DR. This operation + * should never result in a busy or error response. The address and data + * reported in the following Capture-DR are undefined. + */ + return; + } + /* store address for next read back */ s->address = addr; RISCVDebugModule *dm = riscv_dtm_get_dm(s, addr); if (!dm) { s->dmistat = RISCV_DEBUG_FAILED; - qemu_log_mask(LOG_UNIMP, "%s: Unknown DM address 0x%x\n", __func__, - addr); + qemu_log_mask(LOG_UNIMP, "%s: Unknown DM address 0x%x, op %u\n", + __func__, addr, op); return; } @@ -323,21 +336,17 @@ static void riscv_dtm_tap_dmi_update(TAPDataHandler *tdh) * current status reported in op is sticky. */ switch (op) { - case 0: /* NOP */ - /* - * Don’t send anything over the DMI during Update-DR. This operation - * should never result in a busy or error response. The address and data - * reported in the following Capture-DR are undefined. - */ + case DMI_IGNORE: /* NOP */ + g_assert_not_reached(); return; - case 1: /* READ from address */ + case DMI_READ: s->dmistat = dm->dc->read_rq(dm->dev, addr - dm->base); break; - case 2: /* WRITE to address */ + case DMI_WRITE: value = (uint32_t)FIELD_EX64(tdh->value, DMI, DATA); s->dmistat = dm->dc->write_rq(dm->dev, addr - dm->base, value); break; - case 3: + case DMI_RESERVED: default: s->dmistat = RISCV_DEBUG_FAILED; qemu_log_mask(LOG_UNIMP, "%s: Unknown operation %u\n", __func__, op); @@ -453,11 +462,6 @@ static void riscv_dtm_reset(DeviceState *dev) s->address = 0; s->last_dm = NULL; - - if (!s->jtag_ok) { - /* JTAG not enabled, nothing more can be done for this session */ - return; - } } static void riscv_dtm_realize(DeviceState *dev, Error **errp) From 600aec6055adc43c60b26e3b706bea035c6c4738 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 22 Feb 2024 19:57:57 +0100 Subject: [PATCH 47/58] [ot] hw/opentitan: ot_dm_tl: improve trace Signed-off-by: Emmanuel Blot --- hw/opentitan/trace-events | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index e605f0233734..c2b4386fe633 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -88,7 +88,7 @@ ot_dev_proxy_write_reg(const char *prefix, unsigned devix, unsigned offset, unsi ot_dm_tl_invalid_addr(uint32_t addr) "0x%x" ot_dm_tl_update(uint32_t addr, uint32_t value, const char *msg, uint32_t res) "0x%x: 0x%x (%s): %u" -ot_dm_tl_capture(uint32_t addr, uint32_t value) "0x%x: %u" +ot_dm_tl_capture(uint32_t addr, uint32_t value) "0x%x: 0x%08x" # ot_dma.c From d7d972afde18cbe0653628621273c09a424ebfe1 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 26 Feb 2024 12:39:40 +0100 Subject: [PATCH 48/58] [ot] scripts/opentitan: add a Python module for LifeCycle Controller over DMI Signed-off-by: Emmanuel Blot --- docs/opentitan/darjeeling.md | 1 + docs/opentitan/lc_ctrl_dmi.md | 67 +++++ docs/opentitan/tools.md | 6 + scripts/opentitan/ot/lc_ctrl/__init__.py | 8 + scripts/opentitan/ot/lc_ctrl/lcdmi.py | 338 +++++++++++++++++++++++ scripts/opentitan/ot/util/mbb.py | 15 + 6 files changed, 435 insertions(+) create mode 100644 docs/opentitan/lc_ctrl_dmi.md create mode 100644 scripts/opentitan/ot/lc_ctrl/__init__.py create mode 100644 scripts/opentitan/ot/lc_ctrl/lcdmi.py create mode 100644 scripts/opentitan/ot/util/mbb.py diff --git a/docs/opentitan/darjeeling.md b/docs/opentitan/darjeeling.md index 4393dbd906bd..fe4d29911e0d 100644 --- a/docs/opentitan/darjeeling.md +++ b/docs/opentitan/darjeeling.md @@ -50,6 +50,7 @@ Devices in this group implement subset(s) of the real HW. * KMAC * Side loading is not supported * Lifecycle controller + * [LC controller](lc_ctrl_dmi.md) can be accessed through JTAG using a DM-TL bridge * Escalation is not supported * Power Manager * Fast FSM is partially supported, Slow FSM is bypassed diff --git a/docs/opentitan/lc_ctrl_dmi.md b/docs/opentitan/lc_ctrl_dmi.md new file mode 100644 index 000000000000..e3732d8bd2c9 --- /dev/null +++ b/docs/opentitan/lc_ctrl_dmi.md @@ -0,0 +1,67 @@ +# Darjeeling LifeCycle Controller over DMI + +## Communicating with the JTAG Mailbox through a JTAG connection + +In QEMU, a bridge between the Debug Module Interface (DMI) and the JTAG Mailbox is implemented +as Debug Module bridge. + +``` ++----------------+ +| Host (OpenOCD) | ++----------------+ + | + | TCP connection ("bitbang mode") + | ++-----|-----------------------------------------------------------------------------------+ +| v | +| +-------------+ +-----+ +----------+ +---------+ +------+ | +| | JTAG server |---->| DMI |---->| ot_dm_tl |====D====| LC Ctrl |====P====| Hart | | +| +-------------+ +-----+ +----------+ +---------+ +------+ | +| QEMU| ++-----------------------------------------------------------------------------------------+ +``` + +where: + `P` is the private OT bus + `D` is the debug bus + +QEMU should be started with an option such as `-jtag tcp::3335` so that the JTAG server is +instantiated and listen for incoming connection on TCP port 3335. + +#### macOS + +If you want to avoid the boring pop-up window from macOS +``` +Do you want the application “qemu-system-riscv32” to accept incoming network connections? +``` +restrict the listening interfaces to the localhost with `-jtag tcp:localhost:3335` as QEMU defaults +to listening on all interfaces, _i.e._ 0.0.0.0 + +## Communicating with JTAG server and Life Cycle controller using Python + +OpenTitan implementation provides JTAG/DTM/DMI/Mailbox stack available as Python modules: + +* jtag/tap module is available from `scripts/jtag` directory +* dtm/dmi and jtag mailbox modules are available from `scripts/opentitan` directory + +Python snippet to create a communication channel with the VM JTAG mailbox: + +````py +from socket import create_connection +from jtag.bitbang import JtagBitbangController +from jtag.jtag import JtagEngine +from ot.dtm import DebugTransportModule +from ot.lc_ctrl.lcdmi import LifeCycleController + +sock = create_connection(('localhost', 3335), timeout=1.0) +ctrl = JtagBitbangController(sock) +eng = JtagEngine(ctrl) +ctrl.tap_reset(True) +dtm = DebugTransportModule(eng, 5) # IR length depends on the actual machine +version, abits = dtm['dtmcs'].dmi_version, dtm['dtmcs'].abits +print(f'DTM: v{version[0]}.{version[1]}, {abits} bits') +dtm['dtmcs'].dmireset() +lc_ctrl = LifeCycleController(dtm, 0x3000 >> 2) + +# See LifeCycleController for LC controller communication API +```` diff --git a/docs/opentitan/tools.md b/docs/opentitan/tools.md index e9a3e3e6ab0a..afa7f25bd594 100644 --- a/docs/opentitan/tools.md +++ b/docs/opentitan/tools.md @@ -41,6 +41,12 @@ directory to help with these tasks. HW digest verification. * `treillis/` directory contains the test application to test the [GPIO](gpio.md) device. +## Python modules + +* Available from `scripts/jtag` and `scripts/opentitan/ot` +* [JTAG mailbox](jtagmbx.md) provides an API to access the system side of the mailbox over JTAG/DMI +* [LC DMI](lc_ctrl_dmi.md) provides an API to control the Life Cycle controller over JTAG/DMI + ## Configuration files * `darjeeling-ocd.cfg` is a sample configuration file for OpenOCD to connect to the JTAG interface diff --git a/scripts/opentitan/ot/lc_ctrl/__init__.py b/scripts/opentitan/ot/lc_ctrl/__init__.py new file mode 100644 index 000000000000..c7a9e406c921 --- /dev/null +++ b/scripts/opentitan/ot/lc_ctrl/__init__.py @@ -0,0 +1,8 @@ +"""LifeCycle tools.""" + +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + + +class LifeCycleError(RuntimeError): + """Life Cycle Error""" diff --git a/scripts/opentitan/ot/lc_ctrl/lcdmi.py b/scripts/opentitan/ot/lc_ctrl/lcdmi.py new file mode 100644 index 000000000000..d47c3baffb25 --- /dev/null +++ b/scripts/opentitan/ot/lc_ctrl/lcdmi.py @@ -0,0 +1,338 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""LifeCycle DMI. + + :author: Emmanuel Blot +""" + +from binascii import Error as BinasciiError, hexlify, unhexlify +from logging import getLogger +from struct import pack as spack, unpack as sunpack +from typing import Dict, NamedTuple, Tuple + +from . import LifeCycleError +from ..dtm import DebugTransportModule +from ..util.mbb import MB8_TRUE, MB8_FALSE, MB8_MASK + + +class HardwareRevision(NamedTuple): + """OpenTitan Hardware Revision.""" + silicon_creator: int + product_id: int + revision_id: int + + +class LifeCycleController: + """LifeCycle Controller over DMI.""" + + STATUS = """ + initialized + ready + ext_clock_switched + transition_successful + transition_count_error + transition_error + token_error + flash_rma_error + otp_error + state_error + bus_integ_error + otp_partition_error + """.split() + """Status bits.""" + + STATES = """ + RAW + TEST_UNLOCKED0 + TEST_LOCKED0 + TEST_UNLOCKED1 + TEST_LOCKED1 + TEST_UNLOCKED2 + TEST_LOCKED2 + TEST_UNLOCKED3 + TEST_LOCKED3 + TEST_UNLOCKED4 + TEST_LOCKED4 + TEST_UNLOCKED5 + TEST_LOCKED5 + TEST_UNLOCKED6 + TEST_LOCKED6 + TEST_UNLOCKED7 + DEV + PROD + PROD_END + RMA + SCRAP + """.split() + + REGS = dict(alert_test=0, status=1, claim_transition_if_regwen=2, + claim_transition_if=3, transition_regwen=4, transition_cmd=5, + transition_ctrl=6, transition_token=7, transition_target=11, + otp_vendor_test_ctrl=12, otp_vendor_test_status=13, lc_state=14, + lc_transition_cnt=15, lc_id_state=16, hw_revision=17, + device_id=19, manuf_state=27) + """Registers.""" + + ALERTS = 'prog_error state_error bus_integ_error'.split() + """Alerts.""" + + TOKEN_FORMAT = '<4I' + + def __init__(self, dtm: DebugTransportModule, address: int): + super().__init__() + self._log = getLogger('dtm.lcctrl') + self._dtm = dtm + self._dmi = dtm['dmi'] + self._address = address + self._hw_rev_widths = (16, 16, 8) + + def restart_system(self) -> None: + """Restart the remote machine.""" + self._dtm.engine.controller.system_reset() + + def set_alert_test(self, alert: str) -> None: + """Test alert.""" + try: + alix = self.ALERTS.index(alert.lower()) + except IndexError as exc: + raise ValueError(f'No such alert {alert}') from exc + self._write_reg('alert_test', 1 << alix) + + @property + def status(self) -> Dict[str, bool]: + """Retrieve the current status.""" + value = self._read_reg('status') + status = {self.STATUS[b]: bool(value & (1 << b)) + for b in range(len(self.STATUS))} + return status + + def disable_claim_transition_if_regwen(self): + """Disable claim transition interface.""" + self._write_reg('claim_transition_if_regwen', 0) + + def claim_transition_if(self, claim: bool) -> bool: + """Clain transition interface. + + :return: True of the interface has been successfully claimed for DMI. + """ + reg = 'claim_transition_if' + self._log.debug('%s interface', 'Claim' if claim else 'Release') + if claim: + self._write_reg(reg, MB8_TRUE) + val = self._read_reg(reg) & MB8_MASK + success = val == MB8_TRUE + return success + self._write_reg(reg, MB8_FALSE) + val = self._read_reg(reg) & MB8_MASK + if val == MB8_TRUE: + raise LifeCycleError('Cannot release LC interface') + return val == MB8_FALSE + + @property + def transition_regwen(self) -> bool: + """Tells whether transition registers can be written.""" + regwen = bool(self._read_reg('transition_regwen') & 0x1) + self._log.debug('Transition regwen: %s', regwen) + return regwen + + def transition_start(self) -> str: + """Start the transition operation.""" + self._log.debug('Start transition') + self._write_reg('transition_cmd', 0b1) + + @property + def volatile_raw_unlock(self) -> bool: + """Report whether volatile unlock is enabled.""" + reg = 'volatile_raw_unlock' + vru = bool(self._read_reg(reg) & 0b1) + return vru + + @volatile_raw_unlock.setter + def volatile_raw_unlock(self, enable: bool) -> None: + """Enable or disable volatile unlock.""" + reg = 'transition_ctrl' + value = self._read_reg(reg) + if enable: + value |= 0b10 + else: + value &= ~0b10 + self._write_reg(reg, value) + + @property + def ext_clock_en(self) -> bool: + """Report whether external clock is selected.""" + reg = 'transition_ctrl' + value = self._read_reg(reg) + value |= 0b1 + self._write_reg(reg, value) + + @ext_clock_en.setter + def ext_clock_en(self) -> None: + """Select external clock source.""" + + @property + def transition_token(self) -> bytes: + """Report current transition token.""" + tokens = (self._read_reg('transition_token', pos) for pos in range(4)) + token = spack(self.TOKEN_FORMAT, *tokens) + self._log.debug('Transition token: %s', hexlify(token).decode()) + return token + + @transition_token.setter + def transition_token(self, token: [bytes | bytearray | str | None]) -> None: + """Define the transition token as a 16-byte token. + + :param token: if None, use an empty zeroed token, + if provided as a string, it should be an hexadecimal + value of 32 characters, otherwise it should be a + 16-byte sequence. + """ + if isinstance(token, str): + try: + token = unhexlify(token) + except BinasciiError as exc: + raise ValueError('Invalid token string: {exc}') from exc + elif token is None: + token = bytes(16) + elif not isinstance(token, (bytes, bytearray)): + raise ValueError('Invalid token type') + if len(token) != 16: + raise ValueError('Invalid token length') + token = bytes(reversed(token)) + for tix, tok in enumerate(sunpack('<4I', token)): + self._log.debug('Write token[%d] 0x%08x', tix, tok) + self._write_reg('transition_token', tok, tix) + + @property + def transition_target(self) -> Tuple[str, int]: + """Read back the transition target.""" + target = self._read_reg('transition_target') + starget = self._decode_state(target) + self._log.debug('Transition target: %s', starget) + return starget, target + + @transition_target.setter + def transition_target(self, target: [str | int]) -> None: + """Define the transition token as a 16-byte token.""" + if isinstance(target, str): + itarget = self._encode_state(target) + elif isinstance(target, int): + if target < (1 << 5): + itarget = self._expand_state(target) + else: + itarget = target + self._check_state(itarget) + else: + raise ValueError('Invalid target type') + self._log.debug('Set transition target: 0x%08x', itarget) + self._write_reg('transition_target', itarget) + + def otp_vendor_test_ctrl(self) -> int: + """Provide the OTP vendor test control as a 32-bit value.""" + return self._read_reg('otp_vendor_test_ctrl') + + def otp_vendor_test_status(self) -> int: + """Provide the OTP vendor test status as a 32-bit value.""" + return self._read_reg('otp_vendor_test_status') + + @property + def lc_state(self) -> [str | int]: + """Report the current state.""" + istate = self._read_reg('lc_state') + tix = self._check_state(istate) + return self.STATES[tix], istate + + @property + def lc_transition_count(self) -> int: + """Report the current transition count.""" + return self._read_reg('lc_transition_cnt') & 0x1f + + @property + def lc_id_state(self) -> str: + """Report the current ID state.""" + value = self._read_reg('lc_id_state') + idmap = {0: 'blank', 0x55555555: 'personalized', 0xaaaaaaaa: 'invalid'} + try: + return idmap[value] + except KeyError as exc: + raise LifeCycleError(f'Unknown ID state 0x{value:08x}') from exc + + @property + def hw_revision(self) -> HardwareRevision: + """Report the HW revision.""" + hw0 = self._read_reg('hw_revision', 0) + hw1 = self._read_reg('hw_revision', 1) + widths = self._hw_rev_widths + creator = hw0 >> widths[1] & ((1 << widths[0]) - 1) + product = hw0 & ((1 << widths[1]) - 1) + revision = hw1 & ((1 << widths[2]) - 1) + return HardwareRevision(creator, product, revision) + + @property + def device_identifier(self) -> bytes: + """Report the device identifier as a 32-byte value.""" + devids = (self._read_reg('device_id', pos) for pos in range(8)) + devid = spack(self.TOKEN_FORMAT, *devids) + self._log.debug('Transition token: %s', hexlify(devid).decode()) + return devid + + @property + def manufacturer_state(self) -> bytes: + """Report the manufacturer state as a 32-byte value.""" + devids = (self._read_reg('manuf_state', pos) for pos in range(8)) + devid = spack(self.TOKEN_FORMAT, *devids) + self._log.debug('Transition token: %s', hexlify(devid).decode()) + return devid + + @classmethod + def _decode_state(cls, state: int) -> str: + tgix = cls._check_state(state) + return cls.STATES[tgix] + + @classmethod + def _encode_state(cls, state: str) -> int: + try: + tgix = cls.STATES.index(state.upper()) + except IndexError as exc: + raise ValueError(f"Unknwon state '{state}'") from exc + return cls._expand_state(tgix) + + @classmethod + def _check_state(cls, state: int) -> int: + base = cls._base_state(state) + if cls._expand_state(state) != state: + raise ValueError(f'Unknown state {state:08x}') + if not 0 <= base < len(cls.STATES): + raise ValueError(f'Unknown state {state:08x}') + return base + + @classmethod + def _base_state(cls, state: int) -> int: + return state & ((1 << 5) - 1) + + @classmethod + def _expand_state(cls, state: int) -> int: + base = cls._base_state(state) + return ((base << 25) | (base << 20) | (base << 15) | (base << 10) | + (base << 5) | base) + + def _write_reg(self, name: str, value: int, offset: int = 0) -> None: + if value >= (1 << 32): + raise ValueError('Invalid value') + try: + reg = self.REGS[name] + offset + except KeyError as exc: + raise ValueError(f"No such LC register: '{name}'") from exc + self._log.info('write %s: 0x%08x', name, value) + return self._dmi.write(self._address + reg, value) + + def _read_reg(self, name: str, offset: int = 0) -> int: + try: + reg = self.REGS[name] + offset + except KeyError as exc: + raise ValueError(f"No such LC register: '{name}'") from exc + self._log.info('read %s', name) + value = self._dmi.read(self._address + reg) + self._log.info('read 0x%08x', value) + return value diff --git a/scripts/opentitan/ot/util/mbb.py b/scripts/opentitan/ot/util/mbb.py new file mode 100644 index 000000000000..215f2d7a8539 --- /dev/null +++ b/scripts/opentitan/ot/util/mbb.py @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""MultiBit Boolean values + + :author: Emmanuel Blot +""" + +MB4_TRUE = 0x6 +MB4_FALSE = 0x9 +MB4_MASK = 0xf + +MB8_TRUE = 0x96 +MB8_FALSE = 0x89 +MB8_MASK = 0xff From 5691cab0d30cf181ab6d1693d7d480ca58a93077 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Fri, 23 Feb 2024 18:11:04 +0100 Subject: [PATCH 49/58] [ot] jtag: jtag_bitbang: implement system reset Signed-off-by: Emmanuel Blot --- jtag/jtag_bitbang.c | 21 +++++++++++++++++++++ jtag/trace-events | 1 + 2 files changed, 22 insertions(+) diff --git a/jtag/jtag_bitbang.c b/jtag/jtag_bitbang.c index ecefc1d65c72..8d7e62748a99 100644 --- a/jtag/jtag_bitbang.c +++ b/jtag/jtag_bitbang.c @@ -36,6 +36,7 @@ #include "qemu/module.h" #include "qemu/sockets.h" #include "qapi/error.h" +#include "qom/object.h" #include "chardev/char-fe.h" #include "chardev/char.h" #include "exec/gdbstub.h" @@ -43,6 +44,7 @@ #include "exec/jtagstub.h" #include "hw/boards.h" #include "hw/cpu/cluster.h" +#include "hw/resettable.h" #include "monitor/monitor.h" #include "semihosting/semihost.h" #include "sysemu/hw_accel.h" @@ -255,6 +257,22 @@ static void tapctrl_reset(TAPController *tap) g_assert(tap->tdh); } +static void tapctrl_system_reset(TAPController *tap) +{ + Object *mc = qdev_get_machine(); + ObjectClass *oc = object_get_class(mc); + (void)tap; + + if (!object_class_dynamic_cast(oc, TYPE_RESETTABLE_INTERFACE)) { + qemu_log_mask(LOG_UNIMP, "%s: Machine %s is not resettable\n", __func__, + object_get_typename(mc)); + return; + } + + trace_jtag_tapctrl_system_reset(); + resettable_reset(mc, RESET_TYPE_COLD); +} + static void tapctrl_register_handler(TAPController *tap, unsigned code, const TAPDataHandler *tdh) { @@ -467,6 +485,9 @@ static void tapctrl_bb_reset(TAPController *tap, bool trst, bool srst) if (trst) { tapctrl_reset(tap); } + if (srst) { + tapctrl_system_reset(tap); + } tap->trst = trst; tap->srst = srst; } diff --git a/jtag/trace-events b/jtag/trace-events index 45c30deec64f..555ad47348f6 100644 --- a/jtag/trace-events +++ b/jtag/trace-events @@ -9,3 +9,4 @@ jtag_tapctrl_register(unsigned code, const char *name) "register 0x%x: %s" jtag_tapctrl_reset(bool tap, bool sys) "tap: %u, system: %u" jtag_tapctrl_select_dr(const char *name, uint64_t value) "Select DR %s 0x%02" PRIx64 jtag_tapctrl_step(bool tck, bool tms, bool tdi) "tck:%u tms:%u tdi:%u" +jtag_tapctrl_system_reset(void) "SYSTEM RESET" From 2084aad65148108da82fe08282087a0317745224 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 28 Feb 2024 13:28:35 +0100 Subject: [PATCH 50/58] [ot] scripts/opentitan: create a small QEMU stream muxer. This can be useful to observe multiple UART output at once. Signed-off-by: Emmanuel Blot --- docs/opentitan/tools.md | 2 + docs/opentitan/uartmux.md | 58 ++++++++ scripts/opentitan/uartmux.py | 252 +++++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+) create mode 100644 docs/opentitan/uartmux.md create mode 100755 scripts/opentitan/uartmux.py diff --git a/docs/opentitan/tools.md b/docs/opentitan/tools.md index afa7f25bd594..2421fe70d803 100644 --- a/docs/opentitan/tools.md +++ b/docs/opentitan/tools.md @@ -40,6 +40,8 @@ directory to help with these tasks. * `present.py` implements the Present 128-bit scrambler/descrambler used in OTP image files for HW digest verification. * `treillis/` directory contains the test application to test the [GPIO](gpio.md) device. +* [`uartmux.py`](uartmux.md) is a tiny stream wrapper to help dealing with multiple QEMU output + streams, typically multiple virtual UARTs. ## Python modules diff --git a/docs/opentitan/uartmux.md b/docs/opentitan/uartmux.md new file mode 100644 index 000000000000..5b3f5636c470 --- /dev/null +++ b/docs/opentitan/uartmux.md @@ -0,0 +1,58 @@ +# `uartmux.py` + +`uartmux.py` is a tiny stream wrapper to help dealing with multiple QEMU output streams, typically multiple virtual UARTs. + +## Usage + +````text +usage: uartmux.py [-h] [-i IFACE] [-p PORT] [-c CHANNEL] [-v] [-d] [name ...] + +QEMU UART muxer. + +positional arguments: + name assign name to input connection + +options: + -h, --help show this help message and exit + -i IFACE, --iface IFACE + specify TCP interface to listen to (default: localhost) + -p PORT, --port PORT specify TCP port to listen to (default: 9000) + -c CHANNEL, --channel CHANNEL + expected comm channel count(default: 3) + -s SEPARATOR, --separator SEPARATOR + repeat separator between each session + -v, --verbose increase verbosity + -d, --debug enable debug mode +```` + +`uartmux.py` may be used with QEMU character devices, _i.e._ `chardev` defined as network streams, +such as `-chardev socket`. + +`uartmux.py` listens on multiple input streams, and prints them one line at a time, colorizing each +stream with a different color when an ANSI terminal is used. + +It enables a coherent output log when multiple virtual UARTs are emitting at once. + +### Arguments + +* `name` optional name(s) for prexifing each log message line with the known channel name +* `-c` / `--channel` how many input streams are expected, in order to assign the same ANSI color + to the same input stream across subsequence QEMU sessions. Note that if not defined, default to + the count of defined names +* `-d` / `--debug` only useful to debug the script, reports any Python traceback to the standard + error stream. +* `-i` / `--iface` select an alternative interface for listening on, default to localhost +* `-p` / `--port` select an altenative TCP port for listening on, default to 9000 +* `-s` / `--separator` emit this separator between each detected QEMU session +* `-v` / `--verbose` can be repeated to increase verbosity of the script, mostly for debug purpose. + +### Example + +QEMU using two virtual UART output identified as `uart0` and `uart1`: + +* run `uartmux.py uart0 uart1` in one terminal +* run QEMU in another terminal with the following option switches: + ``` + -chardev socket,id=uart0,host=127.0.0.1,port=9000 + -chardev socket,id=uart1,host=127.0.0.1,port=9000 + ``` diff --git a/scripts/opentitan/uartmux.py b/scripts/opentitan/uartmux.py new file mode 100755 index 000000000000..c6dfc27ae284 --- /dev/null +++ b/scripts/opentitan/uartmux.py @@ -0,0 +1,252 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023-2024 Rivos, Inc. +# SPDX-License-Identifier: Apache2 + +"""QEMU UART muxer. + + :author: Emmanuel Blot +""" + +from argparse import ArgumentParser +from collections import deque +from logging import getLogger +from socketserver import StreamRequestHandler, ThreadingTCPServer +from sys import exit as sysexit, modules, stderr, stdout +from threading import Event, Lock, Thread +from traceback import format_exc +from typing import Deque, List, Optional, Set, TextIO, Tuple + +from ot.util.log import configure_loggers + + +class UartHandler(StreamRequestHandler): + """Handle a single QEMU output stream. + """ + + def __init__(self, *args, **kwargs): + self._buffer = bytearray() + self._id = - 1 + self._log = None + # init calls handle immediately, so local attributes need to be + # initialized first + super().__init__(*args, **kwargs) + + def setup(self): + self._id = self.server.get_id(self) + self._log = getLogger(f'mux.h[{self._id}]') + self._log.debug('connected') + self.request.settimeout(0.2) + + def finish(self): + self._log.debug('disconnected') + self.server.discard(self) + + def handle(self): + self._log.debug('handle') + try: + while self.server.resume: + try: + rdata = self.request.recv(1024) + except TimeoutError: + continue + except ConnectionResetError: + break + if not rdata: + # blocking socket reading nothing: client is disconnected + break + self._buffer.extend(rdata) + while self._buffer: + self._log.debug('buf: %d', len(self._buffer)) + pos = self._buffer.find(b'\n') + self._log.debug('pos %d', pos) + if pos < 0: + break + line = bytes(self._buffer[:pos+1]) + self._buffer[:] = self._buffer[pos+1:] + self.server.push(self._id, line) + except Exception as exc: + if self.server.debug: + print(format_exc(chain=False), file=stderr) + else: + self._log.critical('Error: %s', str(exc)) + self.server.resume = False + raise + + +class UartMuxer(ThreadingTCPServer): + """A simple UART muxer for multiple QEMU output streams + """ + + # do not wait for thread completion + daemon_threads = True + allow_reuse_address = True + timeout = None + + COLOR_PREFIX = '\x1b[' + COLOR_SUFFIX = ';1m' + RESET = '\x1b[0m' + + def __init__(self, addr: Tuple[str, int], out: TextIO, debug: bool = False, + separator: Optional[str] = None): + super().__init__(addr, UartHandler) + self._out = out + self._debug = debug + self._log = getLogger('mux.muxer') + self._runner = Thread(target=self._pop, daemon=True) + self._resume = False + self._que: Deque[Tuple[int, bytes]] = deque() + self._evt = Event() + self._lock = Lock() + self._handlers: List[UartHandler] = [] + self._discarded: Set[UartHandler] = set() + self._channel_count = 1 + self._channels: List[str] = [] + self._use_color = out.isatty() + if separator: + sep = separator if ' ' in separator else (separator * 80)[:80] + self._sep = f'{sep}\n' + else: + self._sep = None + + @property + def debug(self) -> bool: + """Tell whether mode is enabled.""" + return self._debug + + @property + def resume(self): + """Tell whether muxer should continue listening on.""" + return self._resume + + @resume.setter + def resume(self, value: bool): + value = bool(value) + if self._resume and not value: + self._resume = value + self._evt.set() + self.shutdown() + else: + self._resume = value + + def run(self, channel_count: int, channels: List[str]) -> None: + """Start listening on QEMU streams.""" + self._channel_count = min(channel_count, 8) + self._channels = channels + self._resume = True + self._runner.start() + try: + self.serve_forever() + finally: + if self._use_color: + self._out.write(self.RESET) + + def push(self, uart_id: int, line: bytes) -> None: + """Push a new log message line from one of the QEMU stream listeners.""" + self._que.append((uart_id, line)) + self._evt.set() + + def get_id(self, uart_handler: UartHandler) -> None: + """Get/assign a unique identifier to a listener.""" + with self._lock: + if self._sep and not self._handlers: + self._out.write(self._sep) + if uart_handler not in self._handlers: + self._handlers.append(uart_handler) + return self._handlers.index(uart_handler) + + def discard(self, uart_handler: UartHandler) -> None: + """Called when a listener terminates.""" + with self._lock: + try: + self._discarded.add(uart_handler) + except ValueError: + pass + # track listeners; when all known ones are closed it is likely the + # QEMU VM has quit, reset the all listeners so on next QEMU run, + # same ids are assigned (which is likely to assign the same color + # for the same QEMU output stream, despite it is somewhat a + # heuristic) + if self._discarded == set(self._handlers): + self._discarded.clear() + self._handlers.clear() + self._log.debug('All clients flushed') + + def _pop(self) -> None: + try: + while self._resume: + if not self._que: + if not self._evt.wait(0.1): + continue + self._evt.clear() + if self._resume and self._que: + uid, byteline = self._que.popleft() + line = byteline.decode(errors='ignore') + if uid < len(self._channels): + name = f'{self._channels[uid]}: ' + else: + name = '' + if self._use_color: + clr = uid % self._channel_count + 31 + ansi = f'{self.COLOR_PREFIX}{clr:d}{self.COLOR_SUFFIX}' + # self._log.error('ANSI %s', ansi) + self._out.write(f'{name}{ansi}{line}{self.RESET}') + # raise ValueError() + else: + self._out.write(line) + finally: + self.resume = False + + +def main(): + """Main routine""" + debug = True + default_port = 9000 + default_iface = 'localhost' + default_channel_count = 3 + mux = None + try: + desc = modules[__name__].__doc__.split('.', 1)[0].strip() + argparser = ArgumentParser(description=f'{desc}.') + argparser.add_argument('name', nargs='*', + help='assign name to input connection') + argparser.add_argument('-i', '--iface', default=default_iface, + help=f'specify TCP interface to listen to ' + f'(default: {default_iface})') + argparser.add_argument('-p', '--port', default=default_port, + help=f'specify TCP port to listen to ' + f'(default: {default_port})') + argparser.add_argument('-c', '--channel', + help=f'expected comm channel count' + f'(default: {default_channel_count})') + argparser.add_argument('-s', '--separator', + help='repeat separator between each session') + argparser.add_argument('-v', '--verbose', action='count', + help='increase verbosity') + argparser.add_argument('-d', '--debug', action='store_true', + help='enable debug mode') + args = argparser.parse_args() + debug = args.debug + + configure_loggers(args.verbose, 'mux') + + ThreadingTCPServer.allow_reuse_address = True + mux = UartMuxer((args.iface, args.port), stdout, debug, args.separator) + channel = args.channel + if channel is None: + channel = len(args.name) if args.name else default_channel_count + mux.run(channel, args.name) + + except (IOError, ValueError, ImportError) as exc: + print(f'\nError: {exc}', file=stderr) + if debug: + print(format_exc(chain=False), file=stderr) + sysexit(1) + except KeyboardInterrupt: + if mux: + mux.resume = False + sysexit(2) + + +if __name__ == '__main__': + main() From fdf983038f085bb22fb694490e8c068e3d2af1e7 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 28 Feb 2024 15:04:15 +0100 Subject: [PATCH 51/58] [ot] hw/opentitan: use qemu_system_shutdown_request_with_code, not exit Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_dev_proxy.c | 3 ++- hw/opentitan/ot_edn.c | 3 ++- hw/opentitan/ot_ibex_wrapper_dj.c | 10 +++++++--- hw/opentitan/ot_ibex_wrapper_eg.c | 10 +++++++--- hw/riscv/ibex_common.c | 4 +++- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/hw/opentitan/ot_dev_proxy.c b/hw/opentitan/ot_dev_proxy.c index 920a38628915..39dd5060d389 100644 --- a/hw/opentitan/ot_dev_proxy.c +++ b/hw/opentitan/ot_dev_proxy.c @@ -47,6 +47,7 @@ #include "hw/registerfields.h" #include "hw/riscv/ibex_common.h" #include "hw/riscv/ibex_irq.h" +#include "sysemu/runstate.h" #include "trace.h" /* ------------------------------------------------------------------------ */ @@ -1183,7 +1184,7 @@ static void ot_dev_proxy_quit(OtDevProxyState *s) ot_dev_proxy_reply_payload(s, PROXY_COMMAND('q', 't'), NULL, 0); usleep(200000); - exit(code); + qemu_system_shutdown_request_with_code(SHUTDOWN_CAUSE_GUEST_SHUTDOWN, code); } static void ot_dev_proxy_intercepted_irq(void *opaque, int irq, int level) diff --git a/hw/opentitan/ot_edn.c b/hw/opentitan/ot_edn.c index 02db52df67d9..b7bfe02f77e2 100644 --- a/hw/opentitan/ot_edn.c +++ b/hw/opentitan/ot_edn.c @@ -45,6 +45,7 @@ #include "hw/riscv/ibex_common.h" #include "hw/riscv/ibex_irq.h" #include "hw/sysbus.h" +#include "sysemu/runstate.h" #include "trace.h" @@ -867,7 +868,7 @@ static void ot_edn_fill_bits(void *opaque, const uint32_t *bits, bool fips) default: xtrace_ot_edn_error(c->appid, "unexpected state"); ot_edn_change_state(s, EDN_ERROR); - exit(1); + qemu_system_shutdown_request_with_code(SHUTDOWN_CAUSE_GUEST_PANIC, 1); break; } diff --git a/hw/opentitan/ot_ibex_wrapper_dj.c b/hw/opentitan/ot_ibex_wrapper_dj.c index 14ff12717ccd..f507ff49af11 100644 --- a/hw/opentitan/ot_ibex_wrapper_dj.c +++ b/hw/opentitan/ot_ibex_wrapper_dj.c @@ -42,6 +42,7 @@ #include "hw/riscv/ibex_common.h" #include "hw/riscv/ibex_irq.h" #include "hw/sysbus.h" +#include "sysemu/runstate.h" #include "trace.h" @@ -1371,7 +1372,8 @@ static void ot_ibex_wrapper_dj_regs_write(void *opaque, hwaddr addr, if (val32 > 127u) { val32 = 127u; } - exit((int)val32); + qemu_system_shutdown_request_with_code( + SHUTDOWN_CAUSE_GUEST_SHUTDOWN, (int)val32); } val32 &= R_SW_FATAL_ERR_VAL_MASK; s->regs[reg] = ot_multibitbool_w1s_write(s->regs[reg], val32, 4u); @@ -1423,7 +1425,8 @@ static void ot_ibex_wrapper_dj_regs_write(void *opaque, hwaddr addr, switch (val32 & R_DV_SIM_STATUS_CODE_MASK) { case TEST_STATUS_PASSED: trace_ot_ibex_wrapper_exit(s->ot_id, "DV SIM success, exiting", 0); - exit(0); + qemu_system_shutdown_request_with_code( + SHUTDOWN_CAUSE_GUEST_SHUTDOWN, 0); break; case TEST_STATUS_FAILED: { uint32_t info = FIELD_EX32(val32, DV_SIM_STATUS, INFO); @@ -1436,7 +1439,8 @@ static void ot_ibex_wrapper_dj_regs_write(void *opaque, hwaddr addr, } trace_ot_ibex_wrapper_exit(s->ot_id, "DV SIM failure, exiting", ret); - exit(ret); + qemu_system_shutdown_request_with_code( + SHUTDOWN_CAUSE_GUEST_SHUTDOWN, ret); break; } default: diff --git a/hw/opentitan/ot_ibex_wrapper_eg.c b/hw/opentitan/ot_ibex_wrapper_eg.c index 64dcffcb7378..7122e672c090 100644 --- a/hw/opentitan/ot_ibex_wrapper_eg.c +++ b/hw/opentitan/ot_ibex_wrapper_eg.c @@ -43,6 +43,7 @@ #include "hw/riscv/ibex_common.h" #include "hw/riscv/ibex_irq.h" #include "hw/sysbus.h" +#include "sysemu/runstate.h" #include "trace.h" @@ -817,7 +818,8 @@ static void ot_ibex_wrapper_eg_regs_write(void *opaque, hwaddr addr, if (val32 > 127u) { val32 = 127u; } - exit((int)val32); + qemu_system_shutdown_request_with_code( + SHUTDOWN_CAUSE_GUEST_SHUTDOWN, (int)val32); } val32 &= R_SW_FATAL_ERR_VAL_MASK; s->regs[reg] = ot_multibitbool_w1s_write(s->regs[reg], val32, 4u); @@ -877,7 +879,8 @@ static void ot_ibex_wrapper_eg_regs_write(void *opaque, hwaddr addr, switch (val32) { case TEST_STATUS_PASSED: trace_ot_ibex_wrapper_exit(s->ot_id, "DV SIM success, exiting", 0); - exit(0); + qemu_system_shutdown_request_with_code( + SHUTDOWN_CAUSE_GUEST_SHUTDOWN, 0); break; case TEST_STATUS_FAILED: { uint32_t info = FIELD_EX32(val32, DV_SIM_STATUS, INFO); @@ -890,7 +893,8 @@ static void ot_ibex_wrapper_eg_regs_write(void *opaque, hwaddr addr, } trace_ot_ibex_wrapper_exit(s->ot_id, "DV SIM failure, exiting", ret); - exit(ret); + qemu_system_shutdown_request_with_code( + SHUTDOWN_CAUSE_GUEST_SHUTDOWN, ret); break; } default: diff --git a/hw/riscv/ibex_common.c b/hw/riscv/ibex_common.c index 36eb942a2c02..5a013dcf8dbe 100644 --- a/hw/riscv/ibex_common.c +++ b/hw/riscv/ibex_common.c @@ -38,6 +38,7 @@ #include "hw/riscv/ibex_common.h" #include "hw/sysbus.h" #include "monitor/monitor.h" +#include "sysemu/runstate.h" static void rust_demangle_fn(const char *st_name, int st_info, uint64_t st_value, uint64_t st_size); @@ -615,7 +616,8 @@ uint32_t ibex_load_kernel(AddressSpace *as) &kernel_entry, NULL, NULL, NULL, 0, EM_RISCV, 1, 0, as, true, &rust_demangle_fn) <= 0) { error_report("Cannot load ELF kernel %s", ms->kernel_filename); - exit(EXIT_FAILURE); + qemu_system_shutdown_request_with_code(SHUTDOWN_CAUSE_HOST_ERROR, + EXIT_FAILURE); } if (((uint32_t)kernel_entry & 0xFFu) != 0x80u) { From 390279cf78343d9e635131cc6a3a1f2f60010dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Thu, 29 Feb 2024 16:40:18 +0100 Subject: [PATCH 52/58] [ot] .gitlab-ci.d: update baremetal reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- .gitlab-ci.d/opentitan/bmref.yml | 2 -- .gitlab-ci.d/opentitan/qemu-ot.yml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 .gitlab-ci.d/opentitan/bmref.yml diff --git a/.gitlab-ci.d/opentitan/bmref.yml b/.gitlab-ci.d/opentitan/bmref.yml deleted file mode 100644 index 403c2635b384..000000000000 --- a/.gitlab-ci.d/opentitan/bmref.yml +++ /dev/null @@ -1,2 +0,0 @@ -variables: - BAREMETAL_REF: "240207-2" diff --git a/.gitlab-ci.d/opentitan/qemu-ot.yml b/.gitlab-ci.d/opentitan/qemu-ot.yml index 8afa03b04b07..106ba24bbf96 100644 --- a/.gitlab-ci.d/opentitan/qemu-ot.yml +++ b/.gitlab-ci.d/opentitan/qemu-ot.yml @@ -1,10 +1,10 @@ variables: + BAREMETAL_REF: "240223-1" QEMU_BUILD_OPTS: "" CLANG_FORMAT_CONF: "ot.clang_format" CLANG_TIDY_CONF: "ot.clang_tidy" include: - - local: '/.gitlab-ci.d/opentitan/bmref.yml' - local: '/.gitlab-ci.d/opentitan/build.yml' - local: '/.gitlab-ci.d/opentitan/ot-smoke.yml' - local: '/.gitlab-ci.d/opentitan/ot-bmtests.yml' From 432f2b232fb784f67c2c715a7fdf5cef056a56f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Thu, 29 Feb 2024 16:40:47 +0100 Subject: [PATCH 53/58] [ot] .gitlab-ci.d: explicitly select clang version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- .gitlab-ci.d/opentitan/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.d/opentitan/build.yml b/.gitlab-ci.d/opentitan/build.yml index 0b7e3feff26f..9319884753a9 100644 --- a/.gitlab-ci.d/opentitan/build.yml +++ b/.gitlab-ci.d/opentitan/build.yml @@ -23,7 +23,7 @@ build-clang: - git clean -dffx subprojects - mkdir build - cd build - - ../configure --cc=clang --disable-werror $QEMU_BUILD_OPTS + - ../configure --cc=clang-16 --disable-werror $QEMU_BUILD_OPTS --target-list=riscv32-softmmu,riscv64-softmmu,x86_64-linux-user - ninja - ninja qemu-img From 7ce95d858350567d811ca255ccfa3e892129e21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Thu, 29 Feb 2024 17:24:28 +0100 Subject: [PATCH 54/58] [ot] .gitlab-ci.d: fix pyot test filter for EarlGrey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- .gitlab-ci.d/opentitan/ot-bmtests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.d/opentitan/ot-bmtests.yml b/.gitlab-ci.d/opentitan/ot-bmtests.yml index 27fa9d5bd926..cfbc86604c87 100644 --- a/.gitlab-ci.d/opentitan/ot-bmtests.yml +++ b/.gitlab-ci.d/opentitan/ot-bmtests.yml @@ -19,7 +19,7 @@ baremetal-eg-tests: - zstd -d --stdout ot-eg-bmtest.tar.zst | tar xf - -C ${BASEDIR} - find ${BASEDIR} - scripts/opentitan/pyot.py -vv -c ${BASEDIR}/data/qemu/pyot-ot-earlgrey.hjson - -w ot-earlgrey.csv -R -T 3 -F '!aes-kat*' + -w ot-earlgrey.csv -R -T 3 -F '*' -F '!aes-kat*' artifacts: public: false expire_in: 1 year From a0f53e54c6b75784a9f770d978438483c6889041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Thu, 29 Feb 2024 17:29:05 +0100 Subject: [PATCH 55/58] [ot] .gitlab-ci.d: add jtag to clang-tidy and clang-format config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- .gitlab-ci.d/opentitan/ot.clang_format | 2 ++ .gitlab-ci.d/opentitan/ot.clang_tidy | 1 + 2 files changed, 3 insertions(+) diff --git a/.gitlab-ci.d/opentitan/ot.clang_format b/.gitlab-ci.d/opentitan/ot.clang_format index e765aeefda0e..d9c3783a8b83 100644 --- a/.gitlab-ci.d/opentitan/ot.clang_format +++ b/.gitlab-ci.d/opentitan/ot.clang_format @@ -1,3 +1,5 @@ +jtag/*.c +include/exec/jtagstub.h hw/opentitan/*.c hw/opentitan/*.h hw/riscv/ibex*.c diff --git a/.gitlab-ci.d/opentitan/ot.clang_tidy b/.gitlab-ci.d/opentitan/ot.clang_tidy index c6c66a01861c..c12c5dc3a3a1 100644 --- a/.gitlab-ci.d/opentitan/ot.clang_tidy +++ b/.gitlab-ci.d/opentitan/ot.clang_tidy @@ -1,3 +1,4 @@ +jtag/*.c hw/opentitan/*.c hw/riscv/ot_*.c hw/riscv/ibex_*.c From 102e8ef38e1658e2d16cbe5c37c4950a49e87f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Fri, 1 Mar 2024 11:45:23 +0100 Subject: [PATCH 56/58] [ot] scripts/opentitan: add default file list to ot-format/tidy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passing option "--ci" to ot-format (resp. ot-tidy) will get the list of files to be processed from scripts/opentitan/clang-format.d/*.lst (resp. scripts/opentitan/clang-tidy.d/*.lst) Signed-off-by: Loïc Lefort --- scripts/opentitan/clang-format.d/jtag.lst | 2 + .../opentitan/clang-format.d/opentitan.lst | 8 ++++ scripts/opentitan/clang-tidy.d/jtag.lst | 1 + scripts/opentitan/clang-tidy.d/opentitan.lst | 4 ++ scripts/opentitan/ot-format.sh | 39 +++++++++++++++++-- scripts/opentitan/ot-tidy.sh | 37 ++++++++++++++++-- 6 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 scripts/opentitan/clang-format.d/jtag.lst create mode 100644 scripts/opentitan/clang-format.d/opentitan.lst create mode 100644 scripts/opentitan/clang-tidy.d/jtag.lst create mode 100644 scripts/opentitan/clang-tidy.d/opentitan.lst diff --git a/scripts/opentitan/clang-format.d/jtag.lst b/scripts/opentitan/clang-format.d/jtag.lst new file mode 100644 index 000000000000..754467c64adb --- /dev/null +++ b/scripts/opentitan/clang-format.d/jtag.lst @@ -0,0 +1,2 @@ +jtag/*.c +include/exec/jtagstub.h diff --git a/scripts/opentitan/clang-format.d/opentitan.lst b/scripts/opentitan/clang-format.d/opentitan.lst new file mode 100644 index 000000000000..e765aeefda0e --- /dev/null +++ b/scripts/opentitan/clang-format.d/opentitan.lst @@ -0,0 +1,8 @@ +hw/opentitan/*.c +hw/opentitan/*.h +hw/riscv/ibex*.c +hw/riscv/ot_*.c +include/hw/opentitan/*.h +include/hw/riscv/ibex*.h +include/hw/riscv/ot_*.h +target/riscv/ibex*.c diff --git a/scripts/opentitan/clang-tidy.d/jtag.lst b/scripts/opentitan/clang-tidy.d/jtag.lst new file mode 100644 index 000000000000..411d4c986363 --- /dev/null +++ b/scripts/opentitan/clang-tidy.d/jtag.lst @@ -0,0 +1 @@ +jtag/*.c diff --git a/scripts/opentitan/clang-tidy.d/opentitan.lst b/scripts/opentitan/clang-tidy.d/opentitan.lst new file mode 100644 index 000000000000..c6c66a01861c --- /dev/null +++ b/scripts/opentitan/clang-tidy.d/opentitan.lst @@ -0,0 +1,4 @@ +hw/opentitan/*.c +hw/riscv/ot_*.c +hw/riscv/ibex_*.c +target/riscv/ibex_*.c diff --git a/scripts/opentitan/ot-format.sh b/scripts/opentitan/ot-format.sh index 1c3b9db3e7ab..80f9123a2efc 100755 --- a/scripts/opentitan/ot-format.sh +++ b/scripts/opentitan/ot-format.sh @@ -18,7 +18,8 @@ if [ -z "${clangformat}" ]; then fi # check clang-format version -version_full="$(${clangformat} --version | head -1 | \ +version_full="$(${clangformat} --version | \ + grep "clang-format version" | head -1 | \ sed -E 's/^.*clang-format version ([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')" version_major="$(echo ${version_full} | cut -d. -f1)" if [ ${version_major} -lt ${EXPECTED_VERSION} ]; then @@ -31,7 +32,39 @@ else fi fi -# build config path +CI_MODE=0 +ARGS="" + +# filter arguments +while [ $# -gt 0 ]; do + case "$1" in + --ci) + CI_MODE=1 + ;; + --style=*) + echo "Cannot override --style option" >&2 + exit 1 + ;; + *) + ARGS="$ARGS $1" + ;; + esac + shift +done + +# config +QEMU_ROOT="$(dirname $0)"/../.. CFG="$(dirname $0)"/clang-format.yml +FILES="" + +# automatic file list +if [ $CI_MODE -eq 1 ]; then + # file list path + FILES_D="$(dirname $0)"/clang-format.d + + for filespec in $(cat "$FILES_D"/*.lst); do + FILES="$FILES $QEMU_ROOT/$filespec" + done +fi -exec "${clangformat}" --style=file:"${CFG}" $* +exec "${clangformat}" --style=file:"${CFG}" $ARGS $FILES diff --git a/scripts/opentitan/ot-tidy.sh b/scripts/opentitan/ot-tidy.sh index 9e51a02793d2..9e77b82e15c0 100755 --- a/scripts/opentitan/ot-tidy.sh +++ b/scripts/opentitan/ot-tidy.sh @@ -18,7 +18,8 @@ if [ -z "${clangtidy}" ]; then fi # check clang-tidy version -version_full="$(${clangtidy} --version | head -1 | \ +version_full="$(${clangtidy} --version | \ + grep "LLVM version" | head -1 | \ sed -E 's/^.*LLVM version ([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')" version_major="$(echo ${version_full} | cut -d. -f1)" if [ ${version_major} -lt ${EXPECTED_VERSION} ]; then @@ -31,7 +32,37 @@ else fi fi -# build config path +CI_MODE=0 +ARGS="" + +# filter arguments +while [ $# -gt 0 ]; do + case "$1" in + --ci) + CI_MODE=1 + ;; + --config-file=*) + echo "Cannot override --config-file option" >&2 + exit 1 + ;; + *) + ARGS="$ARGS $1" + ;; + esac + shift +done + +# config +QEMU_ROOT="$(dirname $0)"/../.. CFG="$(dirname $0)"/clang-tidy.yml +FILES_D="$(dirname $0)"/clang-tidy.d +FILES="" + +# automatic file list +if [ $CI_MODE -eq 1 ]; then + for filespec in $(cat "$FILES_D"/*.lst); do + FILES="$FILES $QEMU_ROOT/$filespec" + done +fi -exec "${clangtidy}" --config-file="${CFG}" $* +exec "${clangtidy}" --config-file="${CFG}" $ARGS $FILES From 3f4386a83179dcdaef564c91a660e184f0b9747f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Fri, 1 Mar 2024 11:48:57 +0100 Subject: [PATCH 57/58] [ot] .gitlab-ci.d: use --ci option for ot-format/tidy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- .gitlab-ci.d/opentitan/build.yml | 4 ++-- .gitlab-ci.d/opentitan/ot.clang_format | 10 ---------- .gitlab-ci.d/opentitan/ot.clang_tidy | 5 ----- .gitlab-ci.d/opentitan/qemu-ot.yml | 2 -- 4 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 .gitlab-ci.d/opentitan/ot.clang_format delete mode 100644 .gitlab-ci.d/opentitan/ot.clang_tidy diff --git a/.gitlab-ci.d/opentitan/build.yml b/.gitlab-ci.d/opentitan/build.yml index 9319884753a9..f8d885d2b49e 100644 --- a/.gitlab-ci.d/opentitan/build.yml +++ b/.gitlab-ci.d/opentitan/build.yml @@ -62,7 +62,7 @@ format: - qemu_ot stage: build script: - - scripts/opentitan/ot-format.sh -i $(tr '\n' ' ' < .gitlab-ci.d/opentitan/$CLANG_FORMAT_CONF) + - scripts/opentitan/ot-format.sh --ci -i - git status -s - test $(git status -s | wc -l) -eq 0 @@ -72,4 +72,4 @@ tidy: stage: build needs: ["build-clang"] script: - - scripts/opentitan/ot-tidy.sh -p build $(tr '\n' ' ' < .gitlab-ci.d/opentitan/$CLANG_TIDY_CONF) + - scripts/opentitan/ot-tidy.sh --ci -p build diff --git a/.gitlab-ci.d/opentitan/ot.clang_format b/.gitlab-ci.d/opentitan/ot.clang_format deleted file mode 100644 index d9c3783a8b83..000000000000 --- a/.gitlab-ci.d/opentitan/ot.clang_format +++ /dev/null @@ -1,10 +0,0 @@ -jtag/*.c -include/exec/jtagstub.h -hw/opentitan/*.c -hw/opentitan/*.h -hw/riscv/ibex*.c -hw/riscv/ot_*.c -include/hw/opentitan/*.h -include/hw/riscv/ibex*.h -include/hw/riscv/ot_*.h -target/riscv/ibex*.c diff --git a/.gitlab-ci.d/opentitan/ot.clang_tidy b/.gitlab-ci.d/opentitan/ot.clang_tidy deleted file mode 100644 index c12c5dc3a3a1..000000000000 --- a/.gitlab-ci.d/opentitan/ot.clang_tidy +++ /dev/null @@ -1,5 +0,0 @@ -jtag/*.c -hw/opentitan/*.c -hw/riscv/ot_*.c -hw/riscv/ibex_*.c -target/riscv/ibex_*.c diff --git a/.gitlab-ci.d/opentitan/qemu-ot.yml b/.gitlab-ci.d/opentitan/qemu-ot.yml index 106ba24bbf96..54776cf727c5 100644 --- a/.gitlab-ci.d/opentitan/qemu-ot.yml +++ b/.gitlab-ci.d/opentitan/qemu-ot.yml @@ -1,8 +1,6 @@ variables: BAREMETAL_REF: "240223-1" QEMU_BUILD_OPTS: "" - CLANG_FORMAT_CONF: "ot.clang_format" - CLANG_TIDY_CONF: "ot.clang_tidy" include: - local: '/.gitlab-ci.d/opentitan/build.yml' From e5da0abdc77bc5e2a56ef4acbdbcf4e99e423ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Fri, 1 Mar 2024 11:49:20 +0100 Subject: [PATCH 58/58] [ot] .github: use ot-format/ot-tidy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- .github/workflows/build_test.yaml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index b43e3cb0fd2d..6ec103bb713e 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -73,10 +73,7 @@ jobs: uses: actions/checkout@v4 - name: Check execution run: | - clang-format-16 -i \ - hw/opentitan/*.c hw/opentitan/*.h include/hw/opentitan/*.h \ - hw/riscv/ibex*.c include/hw/riscv/ibex*.h target/riscv/ibex*.c \ - hw/riscv/ot_*.c include/hw/riscv/ot_*.h + scripts/opentitan/ot-format.sh --ci -i lint-clang: runs-on: ubuntu-latest @@ -100,11 +97,7 @@ jobs: - name: Clang tidy # Expect many warnings/errors (accounted but not reported) from included QEMU files run: | - clang-tidy -p build-clang \ - hw/opentitan/*.c \ - hw/riscv/ot_*.c \ - hw/riscv/ibex*.c \ - target/riscv/ibex_csr.c + scripts/opentitan/ot-tidy.sh --ci -p build-clang test-clang: runs-on: ubuntu-latest