From 72cbdcc2f3c51176a4358574e1b847341d619724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Thu, 19 Oct 2023 12:10:29 +0200 Subject: [PATCH 01/15] [ot] hw/opentitan: ot_flash: fix field definitions for MP_REGION_CFG 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 | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/hw/opentitan/ot_flash.c b/hw/opentitan/ot_flash.c index 24af406020a2..f6e37b92afbe 100644 --- a/hw/opentitan/ot_flash.c +++ b/hw/opentitan/ot_flash.c @@ -115,13 +115,12 @@ REG32(REGION_CFG_REGWEN_5, 0x44u) REG32(REGION_CFG_REGWEN_6, 0x48u) REG32(REGION_CFG_REGWEN_7, 0x4cu) REG32(MP_REGION_CFG_0, 0x50u) - SHARED_FIELD(MP_REGION_CFG_EN, 0u, 4u) - SHARED_FIELD(MP_REGION_CFG_RD_EN, 4u, 4u) - SHARED_FIELD(MP_REGION_CFG_PROG_EN, 8u, 4u) - SHARED_FIELD(MP_REGION_CFG_ERASE_EN, 12u, 4u) - SHARED_FIELD(MP_REGION_CFG_SCRAMBLE_EN, 16u, 4u) - SHARED_FIELD(MP_REGION_CFG_ECC_EN, 20u, 4u) - SHARED_FIELD(MP_REGION_CFG_HE_EN, 24u, 4u) + SHARED_FIELD(MP_REGION_CFG_RD_EN, 0u, 4u) + SHARED_FIELD(MP_REGION_CFG_PROG_EN, 4u, 4u) + SHARED_FIELD(MP_REGION_CFG_ERASE_EN, 8u, 4u) + SHARED_FIELD(MP_REGION_CFG_SCRAMBLE_EN, 12u, 4u) + SHARED_FIELD(MP_REGION_CFG_ECC_EN, 16u, 4u) + SHARED_FIELD(MP_REGION_CFG_HE_EN, 20u, 4u) REG32(MP_REGION_CFG_1, 0x54u) REG32(MP_REGION_CFG_2, 0x58u) REG32(MP_REGION_CFG_3, 0x5cu) From b8989aa2235f077b2d14d852028f8657bc99a93c Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 20 Sep 2023 16:57:00 +0200 Subject: [PATCH 02/15] [ot] hw/riscv: ibex_common: fix ibex_export_gpios function GPIO lists were never filled in. Signed-off-by: Emmanuel Blot --- hw/riscv/ibex_common.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/hw/riscv/ibex_common.c b/hw/riscv/ibex_common.c index e9402d374531..6cced7e132b6 100644 --- a/hw/riscv/ibex_common.c +++ b/hw/riscv/ibex_common.c @@ -297,9 +297,10 @@ void ibex_export_gpios(DeviceState **devices, DeviceState *parent, const IbexDeviceDef *def = &defs[idx]; if (def->gpio_export) { - const IbexGpioExportDef *export = def->gpio_export; + const IbexGpioExportDef *export; /* loop once to compute how the number of GPIO for each GPIO list */ + export = def->gpio_export; while (export->device.num >= 0 && export->parent.num >= 0) { const char *pname = export->parent.name; NamedGPIOList *pngl = ibex_xgpio_list(&pgpios, pname); @@ -309,8 +310,8 @@ void ibex_export_gpios(DeviceState **devices, DeviceState *parent, export ++; } - NamedGPIOList *ngl; - QLIST_FOREACH(ngl, &pgpios, node) { + NamedGPIOList *ngl, *ntmp; + QLIST_FOREACH_SAFE(ngl, &pgpios, node, ntmp) { NamedGPIOList *pngl; QLIST_FOREACH(pngl, &parent->gpios, node) { if (!g_strcmp0(ngl->name, pngl->name)) { @@ -336,6 +337,8 @@ void ibex_export_gpios(DeviceState **devices, DeviceState *parent, * Shallow copy device IRQ into parent's slots, as we do not want * to alter the device IRQ list. */ + export = def->gpio_export; + ngl = NULL; while (export->device.num >= 0 && export->parent.num >= 0) { const char *defname = "unnamed-gpio-in"; const char *dname = export->device.name; @@ -349,7 +352,17 @@ void ibex_export_gpios(DeviceState **devices, DeviceState *parent, qemu_irq devirq; devirq = qdev_get_gpio_in_named(dev, export->device.name, export->device.num); - + if (!ngl || g_strcmp0(ngl->name, pname)) { + ngl = NULL; + NamedGPIOList *pngl; + QLIST_FOREACH(pngl, &parent->gpios, node) { + if (!g_strcmp0(pngl->name, pname)) { + ngl = pngl; + break; + } + } + } + assert(ngl); ngl->in[export->parent.num] = devirq; (void)object_ref(OBJECT(devirq)); object_property_add_alias(OBJECT(parent), ppname, OBJECT(dev), From c37dc55a6bced5c51ad6db64e448bff1e36fe2b6 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 20 Sep 2023 16:58:39 +0200 Subject: [PATCH 03/15] [ot] hw/opentitan: ot_sram_ctrl: add a identifier property This is useful to disambiguate multiple controllers Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_sram_ctrl.c | 33 +++++++++++++++++++-------------- hw/opentitan/trace-events | 4 ++-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/hw/opentitan/ot_sram_ctrl.c b/hw/opentitan/ot_sram_ctrl.c index 98220bcf83d4..745962fd00cb 100644 --- a/hw/opentitan/ot_sram_ctrl.c +++ b/hw/opentitan/ot_sram_ctrl.c @@ -103,6 +103,7 @@ struct OtSramCtrlState { OtOTPState *otp_ctrl; /* optional */ uint32_t size; bool ifetch; /* only used when no otp_ctrl is defined */ + char *sram_id; }; static uint64_t ot_sram_ctrl_regs_read(void *opaque, hwaddr addr, unsigned size) @@ -122,19 +123,19 @@ static uint64_t ot_sram_ctrl_regs_read(void *opaque, hwaddr addr, unsigned size) break; case R_ALERT_TEST: qemu_log_mask(LOG_GUEST_ERROR, - "W/O register 0x%02" HWADDR_PRIx " (%s)\n", addr, - REG_NAME(reg)); + "%s: %s W/O register 0x%02" HWADDR_PRIx " (%s)\n", + __func__, s->sram_id, addr, REG_NAME(reg)); val32 = 0; break; default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", - __func__, addr); + qemu_log_mask(LOG_GUEST_ERROR, "%s: %s Bad offset 0x%" HWADDR_PRIx "\n", + __func__, s->sram_id, addr); val32 = 0; break; } uint64_t pc = ibex_get_current_pc(); - trace_ot_sram_ctrl_io_read_out((unsigned)addr, REG_NAME(reg), + trace_ot_sram_ctrl_io_read_out(s->sram_id, (unsigned)addr, REG_NAME(reg), (uint64_t)val32, pc); return (uint64_t)val32; @@ -149,7 +150,8 @@ static void ot_sram_ctrl_regs_write(void *opaque, hwaddr addr, uint64_t val64, hwaddr reg = R32_OFF(addr); uint64_t pc = ibex_get_current_pc(); - trace_ot_sram_ctrl_io_write((unsigned)addr, REG_NAME(reg), val64, pc); + trace_ot_sram_ctrl_io_write(s->sram_id, (unsigned)addr, REG_NAME(reg), + val64, pc); switch (reg) { case R_ALERT_TEST: @@ -170,8 +172,9 @@ static void ot_sram_ctrl_regs_write(void *opaque, hwaddr addr, uint64_t val64, s->cfg_ifetch = true; } } else { - qemu_log_mask(LOG_GUEST_ERROR, "%s: R_EXEC protected w/ REGWEN\n", - __func__); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: %s R_EXEC protected w/ REGWEN\n", __func__, + s->sram_id); } break; case R_CTRL_REGWEN: @@ -183,18 +186,19 @@ static void ot_sram_ctrl_regs_write(void *opaque, hwaddr addr, uint64_t val64, val32 &= R_CTRL_INIT_MASK | R_CTRL_RENEW_SCR_KEY_MASK; s->regs[val32] = val32; } else { - qemu_log_mask(LOG_GUEST_ERROR, "%s: R_CTRL protected w/ REGWEN\n", - __func__); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: %s R_CTRL protected w/ REGWEN\n", __func__, + s->sram_id); } break; case R_STATUS: qemu_log_mask(LOG_GUEST_ERROR, - "%s: R/O register 0x%02" HWADDR_PRIx " (%s)\n", __func__, - addr, REG_NAME(reg)); + "%s: %s R/O register 0x%02" HWADDR_PRIx " (%s)\n", + __func__, s->sram_id, addr, REG_NAME(reg)); break; default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", - __func__, addr); + qemu_log_mask(LOG_GUEST_ERROR, "%s: %s Bad offset 0x%" HWADDR_PRIx "\n", + __func__, s->sram_id, addr); break; } }; @@ -205,6 +209,7 @@ static Property ot_sram_ctrl_properties[] = { OtOTPState *), DEFINE_PROP_UINT32("size", OtSramCtrlState, size, 0u), DEFINE_PROP_BOOL("ifetch", OtSramCtrlState, ifetch, false), + DEFINE_PROP_STRING("id", OtSramCtrlState, sram_id), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 5da0a169f22c..573bb62c73e6 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -240,8 +240,8 @@ ot_spi_host_debug1(const char *msg, uint32_t val) "%s 0x%" PRIx32 # ot_sram_ctrl.c -ot_sram_ctrl_io_read_out(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 -ot_sram_ctrl_io_write(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 +ot_sram_ctrl_io_read_out(const char *sid, unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "%s: addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 +ot_sram_ctrl_io_write(const char *sid, unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "%s: addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 # ot_timer.c From 648d2f4115ea24e926a6520e6efd3d5d8f6b17cf Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Sat, 14 Oct 2023 17:29:17 +0200 Subject: [PATCH 04/15] [ot] hw/opentitan: fix several issues detected with clang-tidy Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_aes.c | 18 ++++++++------ hw/opentitan/ot_alert_earlgrey.c | 3 +++ hw/opentitan/ot_aon_timer.c | 10 +++++--- hw/opentitan/ot_clkmgr.c | 3 +++ hw/opentitan/ot_common.c | 2 +- hw/opentitan/ot_csrng.c | 9 ++++--- hw/opentitan/ot_edn.c | 4 +++ hw/opentitan/ot_entropy_src.c | 33 +++++++++++++------------ hw/opentitan/ot_flash.c | 29 ++++++++++++++-------- hw/opentitan/ot_gpio.c | 14 ++++++++--- hw/opentitan/ot_hmac.c | 8 +++++- hw/opentitan/ot_ibex_wrapper_earlgrey.c | 4 +++ hw/opentitan/ot_kmac.c | 25 ++++++++++++++----- hw/opentitan/ot_lifecycle.c | 6 ++++- hw/opentitan/ot_otbn.c | 5 +++- hw/opentitan/ot_otp_earlgrey.c | 17 +++++++++++-- hw/opentitan/ot_otp_earlgrey_lcvalues.c | 2 ++ hw/opentitan/ot_pinmux.c | 3 +++ hw/opentitan/ot_pwrmgr.c | 14 ++++++++--- hw/opentitan/ot_rom_ctrl.c | 21 ++++++++++------ hw/opentitan/ot_rom_ctrl_img.c | 17 ++++++++----- hw/opentitan/ot_rstmgr.c | 4 ++- hw/opentitan/ot_sensor.c | 26 ++++++++++++------- hw/opentitan/ot_spi_host.c | 25 ++++++++++--------- hw/opentitan/ot_sram_ctrl.c | 3 +++ hw/opentitan/ot_timer.c | 6 ++++- hw/opentitan/ot_uart.c | 19 ++++++++------ include/hw/opentitan/ot_ast.h | 2 +- 28 files changed, 230 insertions(+), 102 deletions(-) diff --git a/hw/opentitan/ot_aes.c b/hw/opentitan/ot_aes.c index bbc014934e73..e55a226a70c3 100644 --- a/hw/opentitan/ot_aes.c +++ b/hw/opentitan/ot_aes.c @@ -196,7 +196,7 @@ typedef struct OtAESRegisters { uint32_t status; /* implementation */ - DECLARE_BITMAP(keyshare_bm, PARAM_NUM_REGS_KEY * 2u); + DECLARE_BITMAP(keyshare_bm, (uint64_t)(PARAM_NUM_REGS_KEY * 2u)); DECLARE_BITMAP(iv_bm, PARAM_NUM_REGS_IV); DECLARE_BITMAP(data_in_bm, PARAM_NUM_REGS_DATA); DECLARE_BITMAP(data_out_bm, PARAM_NUM_REGS_DATA); @@ -431,7 +431,7 @@ static void ot_aes_init_keyshare(OtAESState *s) trace_ot_aes_init("keyshare"); ot_aes_randomize(s, r->keyshare, ARRAY_SIZE(r->keyshare)); - bitmap_zero(r->keyshare_bm, PARAM_NUM_REGS_KEY * 2u); + bitmap_zero(r->keyshare_bm, (int64_t)(PARAM_NUM_REGS_KEY * 2u)); c->key_ready = false; } @@ -906,7 +906,8 @@ static void ot_aes_process_cond(OtAESState *s) */ timer_del(s->retard_timer); uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - timer_mod(s->retard_timer, now + OT_AES_RETARD_DELAY_NS); + timer_mod(s->retard_timer, + (int64_t)(now + OT_AES_RETARD_DELAY_NS)); } else { /* * if fast mode is enabled, vCPU cannot resume execution before @@ -973,6 +974,7 @@ static void ot_aes_reseed(OtAESState *s) static uint64_t ot_aes_read(void *opaque, hwaddr addr, unsigned size) { OtAESState *s = opaque; + (void)size; OtAESRegisters *r = s->regs; uint32_t val32; @@ -1018,7 +1020,7 @@ static uint64_t ot_aes_read(void *opaque, hwaddr addr, unsigned size) case R_DATA_OUT_2: case R_DATA_OUT_3: val32 = r->data_out[reg - R_DATA_OUT_0]; - clear_bit(reg - R_DATA_OUT_0, r->data_out_bm); + clear_bit((int64_t)(reg - R_DATA_OUT_0), r->data_out_bm); if (bitmap_empty(r->data_out_bm, PARAM_NUM_REGS_DATA)) { r->status &= ~R_STATUS_OUTPUT_VALID_MASK; s->ctx->do_full = false; @@ -1061,6 +1063,7 @@ static void ot_aes_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtAESState *s = opaque; + (void)size; OtAESRegisters *r = s->regs; uint32_t val32 = (uint32_t)val64; @@ -1106,7 +1109,7 @@ static void ot_aes_write(void *opaque, hwaddr addr, uint64_t val64, case R_KEY_SHARE1_7: if (ot_aes_is_idle(s)) { r->keyshare[reg - R_KEY_SHARE0_0] = val32; - set_bit(reg - R_KEY_SHARE0_0, r->keyshare_bm); + set_bit((int64_t)(reg - R_KEY_SHARE0_0), r->keyshare_bm); ot_aes_update_key(s); ot_aes_update_config(s); } @@ -1117,7 +1120,7 @@ static void ot_aes_write(void *opaque, hwaddr addr, uint64_t val64, case R_IV_3: if (ot_aes_is_idle(s)) { r->iv[reg - R_IV_0] = val32; - set_bit(reg - R_IV_0, r->iv_bm); + set_bit((int64_t)(reg - R_IV_0), r->iv_bm); ot_aes_update_iv(s); ot_aes_update_config(s); } @@ -1127,7 +1130,7 @@ static void ot_aes_write(void *opaque, hwaddr addr, uint64_t val64, case R_DATA_IN_2: case R_DATA_IN_3: r->data_in[reg - R_DATA_IN_0] = val32; - set_bit(reg - R_DATA_IN_0, r->data_in_bm); + set_bit((int64_t)(reg - R_DATA_IN_0), r->data_in_bm); if (ot_aes_is_data_in_ready(r)) { ibex_irq_set(&s->clkmgr, (int)true); ot_aes_pop(s); @@ -1283,6 +1286,7 @@ static void ot_aes_init(Object *obj) static void ot_aes_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_aes_reset; device_class_set_props(dc, ot_aes_properties); diff --git a/hw/opentitan/ot_alert_earlgrey.c b/hw/opentitan/ot_alert_earlgrey.c index 319effaf8178..e034ca887cb6 100644 --- a/hw/opentitan/ot_alert_earlgrey.c +++ b/hw/opentitan/ot_alert_earlgrey.c @@ -266,6 +266,7 @@ static void ot_alert_eg_update_irqs(OtAlertEgState *s) static uint64_t ot_alert_eg_regs_read(void *opaque, hwaddr addr, unsigned size) { OtAlertEgState *s = opaque; + (void)size; OtAlertRegs *regs = s->regs; uint32_t val32; @@ -419,6 +420,7 @@ static void ot_alert_eg_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtAlertEgState *s = opaque; + (void)size; OtAlertRegs *regs = s->regs; uint32_t val32 = (uint32_t)val64; @@ -665,6 +667,7 @@ static void ot_alert_eg_init(Object *obj) static void ot_alert_eg_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_alert_eg_reset; device_class_set_props(dc, ot_alert_eg_properties); diff --git a/hw/opentitan/ot_aon_timer.c b/hw/opentitan/ot_aon_timer.c index 8e49c282bcf8..7f40c332714e 100644 --- a/hw/opentitan/ot_aon_timer.c +++ b/hw/opentitan/ot_aon_timer.c @@ -130,20 +130,21 @@ ot_aon_timer_ticks_to_ns(OtAonTimerState *s, uint32_t prescaler, uint32_t ticks) if (ns > INT64_MAX) { return INT64_MAX; } - return ns; + return (int64_t)ns; } static uint32_t ot_aon_timer_get_wkup_count(OtAonTimerState *s, uint64_t now) { uint32_t prescaler = FIELD_EX32(s->regs[R_WKUP_CTRL], WKUP_CTRL, PRESCALER); return s->regs[R_WKUP_COUNT] + - ot_aon_timer_ns_to_ticks(s, prescaler, now - s->wkup_origin_ns); + ot_aon_timer_ns_to_ticks(s, prescaler, + (int64_t)(now - s->wkup_origin_ns)); } static uint32_t ot_aon_timer_get_wdog_count(OtAonTimerState *s, uint64_t now) { return s->regs[R_WDOG_COUNT] + - ot_aon_timer_ns_to_ticks(s, 0u, now - s->wdog_origin_ns); + ot_aon_timer_ns_to_ticks(s, 0u, (int64_t)(now - s->wdog_origin_ns)); } static int64_t ot_aon_timer_compute_next_timeout(OtAonTimerState *s, @@ -288,6 +289,7 @@ static void ot_aon_timer_wdog_cb(void *opaque) static uint64_t ot_aon_timer_read(void *opaque, hwaddr addr, unsigned size) { OtAonTimerState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -340,6 +342,7 @@ static void ot_aon_timer_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { OtAonTimerState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)value; hwaddr reg = R32_OFF(addr); @@ -509,6 +512,7 @@ static void ot_aon_timer_init(Object *obj) static void ot_aon_timer_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = ot_aon_timer_reset; device_class_set_props(dc, ot_aon_timer_properties); diff --git a/hw/opentitan/ot_clkmgr.c b/hw/opentitan/ot_clkmgr.c index 93eab72e0a0d..e198266aa427 100644 --- a/hw/opentitan/ot_clkmgr.c +++ b/hw/opentitan/ot_clkmgr.c @@ -250,6 +250,7 @@ static uint32_t ot_clkmgr_get_clock_hints(OtClkMgrState *s) static uint64_t ot_clkmgr_read(void *opaque, hwaddr addr, unsigned size) { OtClkMgrState *s = opaque; + (void)size; uint32_t val32; @@ -315,6 +316,7 @@ static void ot_clkmgr_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtClkMgrState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -596,6 +598,7 @@ static void ot_clkmgr_init(Object *obj) static void ot_clkmgr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_clkmgr_reset; device_class_set_props(dc, ot_clkmgr_properties); diff --git a/hw/opentitan/ot_common.c b/hw/opentitan/ot_common.c index 45d0b0348f2b..0e0ec5b85ea5 100644 --- a/hw/opentitan/ot_common.c +++ b/hw/opentitan/ot_common.c @@ -37,7 +37,7 @@ typedef struct { static int ot_common_node_child_walker(Object *child, void *opaque) { OtCommonNodeEntry *entry = opaque; - if (!object_dynamic_cast(OBJECT(child), entry->type)) { + if (!object_dynamic_cast(child, entry->type)) { /* continue walking the children hierarchy */ return 0; } diff --git a/hw/opentitan/ot_csrng.c b/hw/opentitan/ot_csrng.c index 98dbef981a10..85ab511d68e4 100644 --- a/hw/opentitan/ot_csrng.c +++ b/hw/opentitan/ot_csrng.c @@ -393,7 +393,7 @@ qemu_irq ot_csnrg_connect_hw_app(OtCSRNGState *s, unsigned app_id, trace_ot_csrng_connection(app_id); return qdev_get_gpio_in_named(DEVICE(s), TYPE_OT_CSRNG "-genbits_ready", - app_id); + (int)app_id); } int ot_csrng_push_command(OtCSRNGState *s, unsigned app_id, @@ -1371,7 +1371,7 @@ static void ot_csrng_command_schedule(OtCSRNGState *s, OtCSRNGInstance *inst) 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, now + CMD_EXECUTE_DELAY_NS); + timer_mod(s->cmd_scheduler, (int64_t)(now + CMD_EXECUTE_DELAY_NS)); } static void ot_csrng_command_scheduler(void *opaque) @@ -1455,7 +1455,7 @@ static void ot_csrng_command_scheduler(void *opaque) 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, now + CMD_EXECUTE_DELAY_NS); + timer_mod(s->cmd_scheduler, (int64_t)(now + CMD_EXECUTE_DELAY_NS)); } else { xtrace_ot_csrng_error("cannot schedule new command on error"); } @@ -1510,6 +1510,7 @@ static uint32_t ot_csrng_read_state_db(OtCSRNGState *s) static uint64_t ot_csrng_regs_read(void *opaque, hwaddr addr, unsigned size) { OtCSRNGState *s = opaque; + (void)size; uint32_t val32; OtCSRNGInstance *inst; @@ -1597,6 +1598,7 @@ static void ot_csrng_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtCSRNGState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; OtCSRNGInstance *inst; @@ -1841,6 +1843,7 @@ static void ot_csrng_init(Object *obj) static void ot_csrng_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_csrng_reset; device_class_set_props(dc, ot_csrng_properties); diff --git a/hw/opentitan/ot_edn.c b/hw/opentitan/ot_edn.c index 34184b344847..3051fc13ef17 100644 --- a/hw/opentitan/ot_edn.c +++ b/hw/opentitan/ot_edn.c @@ -970,6 +970,7 @@ static void ot_edn_csrng_ack_irq(void *opaque, int n, int level) { OtEDNState *s = opaque; OtEDNCSRNG *c = &s->rng; + (void)n; trace_ot_edn_csrng_ack(c->appid, STATE_NAME(s->state), level); @@ -1038,6 +1039,7 @@ static void ot_edn_csrng_ack_irq(void *opaque, int n, int level) static uint64_t ot_edn_regs_read(void *opaque, hwaddr addr, unsigned size) { OtEDNState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -1105,6 +1107,7 @@ static void ot_edn_regs_write(void *opaque, hwaddr addr, uint64_t val64, OtEDNState *s = opaque; OtEDNCSRNG *c = &s->rng; uint32_t val32 = (uint32_t)val64; + (void)size; hwaddr reg = R32_OFF(addr); @@ -1325,6 +1328,7 @@ static void ot_edn_init(Object *obj) static void ot_edn_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_edn_reset; device_class_set_props(dc, ot_edn_properties); diff --git a/hw/opentitan/ot_entropy_src.c b/hw/opentitan/ot_entropy_src.c index 7b215d0ffdda..a90c67182a6a 100644 --- a/hw/opentitan/ot_entropy_src.c +++ b/hw/opentitan/ot_entropy_src.c @@ -23,6 +23,11 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. + * + * Notes: + * - missing correct handling of ALERT_FAIL_COUNTS, currently never incremented. + * - missing some error handling? ES_MAIN_SM_ERR is the only error that can be + * triggered. */ #include "qemu/osdep.h" @@ -243,7 +248,7 @@ REG32(MAIN_SM_STATE, 0xe0u) R_ERR_CODE_ES_CNTR_ERR_MASK | R_ERR_CODE_SHA3_STATE_ERR_MASK | \ R_ERR_CODE_SHA3_RST_STORAGE_ERR_MASK) -#define ALERT_STATUS_BIT(_x_) R_RECOV_ALERT_STS_##_x_##_FIELD_ALERT_MASK +#define ALERT_STATUS_BIT(_x_) R_RECOV_ALERT_STS_##_x_##_FIELD_ALERT_SHIFT #define REG_NAME_ENTRY(_reg_) [R_##_reg_] = stringify(_reg_) static const char *REG_NAMES[REGS_COUNT] = { @@ -315,7 +320,8 @@ static const char *REG_NAMES[REGS_COUNT] = { #define ES_FILL_BITS 128u #define ES_FINAL_FIFO_DEPTH 4u #define ES_FILL_RATE_NS \ - ((NANOSECONDS_PER_SECOND * ES_FILL_BITS) / (OT_AST_RANDOM_4BIT_RATE * 4u)) + ((NANOSECONDS_PER_SECOND * ES_FILL_BITS) / \ + ((uint64_t)OT_AST_RANDOM_4BIT_RATE * 4u)) #define OT_ENTROPY_SRC_FILL_WORD_COUNT (ES_FILL_BITS / (8u * sizeof(uint32_t))) #define ES_WORD_COUNT (OT_ENTROPY_SRC_WORD_COUNT) #define ES_SWREAD_FIFO_WORD_COUNT ES_WORD_COUNT @@ -701,16 +707,11 @@ static void ot_entropy_src_update_alerts(OtEntropySrcState *s) bool recoverable = (bool)s->regs[R_RECOV_ALERT_STS]; if (alert_count >= alert_threshold || recoverable) { ibex_irq_set(&s->alerts[ALERT_RECOVERABLE], 1); - if (s->state != ENTROPY_SRC_ERROR) { - ot_entropy_src_change_state(s, ENTROPY_SRC_ALERT_STATE); - } } uint32_t fatal_alert = s->regs[R_ERR_CODE] & ERR_CODE_FATAL_ERROR_MASK; + fatal_alert |= (1u << s->regs[R_ERR_CODE_TEST]) & ERR_CODE_FATAL_ERROR_MASK; if (fatal_alert) { ibex_irq_set(&s->alerts[ALERT_FATAL], 1); - if (s->state != ENTROPY_SRC_ERROR) { - ot_entropy_src_change_state(s, ENTROPY_SRC_ERROR); - } } } @@ -762,7 +763,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); - timer_mod(s->scheduler, now + (uint64_t)ES_FILL_RATE_NS); + timer_mod(s->scheduler, (int64_t)(now + (uint64_t)ES_FILL_RATE_NS)); } } } @@ -1047,8 +1048,6 @@ static void ot_entropy_src_scheduler(void *opaque) switch (s->state) { case ENTROPY_SRC_BOOT_HT_RUNNING: case ENTROPY_SRC_BOOT_PHASE_DONE: - ot_entropy_src_noise_refill(s); - break; case ENTROPY_SRC_STARTUP_HT_START: case ENTROPY_SRC_CONT_HT_START: case ENTROPY_SRC_CONT_HT_RUNNING: @@ -1084,6 +1083,7 @@ static uint64_t ot_entropy_src_regs_read(void *opaque, hwaddr addr, unsigned size) { OtEntropySrcState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -1142,7 +1142,7 @@ ot_entropy_src_regs_read(void *opaque, hwaddr addr, unsigned size) ot_fifo32_num_used(&s->final_fifo)); val32 = FIELD_DP32(val32, DEBUG_STATUS, MAIN_SM_IDLE, (uint32_t)(s->state == ENTROPY_SRC_IDLE)); - val32 = FIELD_DP32(0, DEBUG_STATUS, MAIN_SM_BOOT_DONE, + val32 = FIELD_DP32(val32, DEBUG_STATUS, MAIN_SM_BOOT_DONE, (uint32_t)(s->state == ENTROPY_SRC_BOOT_PHASE_DONE)); break; case R_MAIN_SM_STATE: @@ -1246,6 +1246,7 @@ static void ot_entropy_src_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtEntropySrcState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -1318,7 +1319,8 @@ static void ot_entropy_src_regs_write(void *opaque, hwaddr addr, uint64_t val64, } uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); timer_mod(s->scheduler, - now + (uint64_t)OT_ENTROPY_SRC_BOOT_DELAY_NS); + (int64_t)(now + + (uint64_t)OT_ENTROPY_SRC_BOOT_DELAY_NS)); } break; } @@ -1463,9 +1465,7 @@ static void ot_entropy_src_regs_write(void *opaque, hwaddr addr, uint64_t val64, break; case R_ERR_CODE_TEST: val32 &= R_ERR_CODE_TEST_VAL_MASK; - val32 = 1u << val32; - val32 &= ERR_CODE_MASK; - s->regs[R_ERR_CODE] = val32; + s->regs[R_ERR_CODE_TEST] = val32; ot_entropy_src_update_irqs(s); ot_entropy_src_update_alerts(s); break; @@ -1621,6 +1621,7 @@ static void ot_entropy_src_init(Object *obj) static void ot_entropy_src_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_entropy_src_reset; device_class_set_props(dc, ot_entropy_src_properties); diff --git a/hw/opentitan/ot_flash.c b/hw/opentitan/ot_flash.c index f6e37b92afbe..fe5e565c40ac 100644 --- a/hw/opentitan/ot_flash.c +++ b/hw/opentitan/ot_flash.c @@ -713,7 +713,8 @@ static void ot_flash_op_signal(void *opaque) static void ot_flash_initialize(OtFlashState *s) { if (s->op.kind != OP_NONE) { - qemu_log_mask(LOG_GUEST_ERROR, "cannot initialize while in op"); + qemu_log_mask(LOG_GUEST_ERROR, "%s: cannot initialize while in op", + __func__); return; } @@ -848,6 +849,7 @@ static void ot_flash_op_execute(OtFlashState *s) static uint64_t ot_flash_regs_read(void *opaque, hwaddr addr, unsigned size) { OtFlashState *s = opaque; + (void)size; uint32_t val32; if (ot_flash_is_disabled(s)) { @@ -994,8 +996,8 @@ static uint64_t ot_flash_regs_read(void *opaque, hwaddr addr, unsigned size) case R_ALERT_TEST: case R_PROG_FIFO: qemu_log_mask(LOG_GUEST_ERROR, - "W/O register 0x%03" HWADDR_PRIx " (%s)\n", addr, - REG_NAME(reg)); + "%s: W/O register 0x%03" HWADDR_PRIx " (%s)\n", __func__, + addr, REG_NAME(reg)); val32 = 0; break; default: @@ -1016,6 +1018,7 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtFlashState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -1087,6 +1090,7 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned info_sel = (unsigned)FIELD_EX32(val32, CONTROL, INFO_SEL); unsigned num = (unsigned)FIELD_EX32(val32, CONTROL, NUM); if (start && s->op.kind == OP_NONE) { + /* NOLINTNEXTLINE */ switch (op) { case 0: s->op.kind = OP_READ; @@ -1277,8 +1281,8 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64, case R_PHY_STATUS: case R_CURR_FIFO_LVL: qemu_log_mask(LOG_GUEST_ERROR, - "R/O register 0x%03" HWADDR_PRIx " (%s)\n", addr, - REG_NAME(reg)); + "%s: R/O register 0x%03" HWADDR_PRIx " (%s)\n", __func__, + addr, REG_NAME(reg)); break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", @@ -1290,6 +1294,7 @@ static void ot_flash_regs_write(void *opaque, hwaddr addr, uint64_t val64, static uint64_t ot_flash_csrs_read(void *opaque, hwaddr addr, unsigned size) { OtFlashState *s = opaque; + (void)size; uint32_t val32; if (ot_flash_is_disabled(s)) { @@ -1342,6 +1347,7 @@ static void ot_flash_csrs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtFlashState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr csr = R32_OFF(addr); @@ -1608,7 +1614,7 @@ static void ot_flash_load(OtFlashState *s, Error **errp) return; } - if (memcmp(header->magic, "vFSH", sizeof(header->magic))) { + if (memcmp(header->magic, "vFSH", sizeof(header->magic)) != 0) { error_setg(errp, "Flash file is not a valid flash backend"); return; } @@ -1667,10 +1673,10 @@ static void ot_flash_load(OtFlashState *s, Error **errp) /* two banks, OTRE+OTB0 binaries/bank */ size_t debug_trailer_size = - flash->bank_count * ELFNAME_SIZE * BIN_APP_COUNT; + (size_t)(flash->bank_count) * ELFNAME_SIZE * BIN_APP_COUNT; uint8_t *elfnames = blk_blockalign(s->blk, debug_trailer_size); - rc = blk_pread(s->blk, (int64_t)offset + flash_size, debug_trailer_size, - elfnames, 0); + rc = blk_pread(s->blk, (int64_t)offset + flash_size, + (int64_t)debug_trailer_size, elfnames, 0); if (!rc) { const char *elfname = (const char *)elfnames; for (unsigned ix = 0; ix < BIN_APP_COUNT; ix++) { @@ -1727,7 +1733,8 @@ static void ot_flash_load(OtFlashState *s, Error **errp) * - Debug info (ELF file names) */ flash->data = (uint32_t *)(base); - flash->info = (uint32_t *)(base + flash->bank_count * data_size); + flash->info = + (uint32_t *)(base + (uintptr_t)(flash->bank_count * data_size)); flash->data_size = data_size; flash->info_size = info_size; } @@ -1784,6 +1791,7 @@ static const MemoryRegionOps ot_flash_mem_ops = { static void ot_flash_realize(DeviceState *dev, Error **errp) { OtFlashState *s = OT_FLASH(dev); + (void)errp; ot_flash_load(s, &error_fatal); @@ -1831,6 +1839,7 @@ static void ot_flash_init(Object *obj) static void ot_flash_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_flash_reset; dc->realize = &ot_flash_realize; diff --git a/hw/opentitan/ot_gpio.c b/hw/opentitan/ot_gpio.c index 1d327e8c727f..09487095b813 100644 --- a/hw/opentitan/ot_gpio.c +++ b/hw/opentitan/ot_gpio.c @@ -45,7 +45,7 @@ #include "hw/sysbus.h" #include "trace.h" -/* +/* * Unfortunately, there is no QEMU API to properly disable serial control lines */ #ifndef _WIN32 @@ -198,13 +198,13 @@ static void ot_gpio_update_backend(OtGpioState *s, bool oe) len += snprintf(&buf[len], sizeof(buf), "O:%08x\r\n", s->data_out); - qemu_chr_fe_write(&s->chr, (const uint8_t *)buf, len); + qemu_chr_fe_write(&s->chr, (const uint8_t *)buf, (int)len); } static uint64_t ot_gpio_read(void *opaque, hwaddr addr, unsigned size) { OtGpioState *s = opaque; - + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -258,6 +258,7 @@ static void ot_gpio_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtGpioState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; uint32_t mask; @@ -281,7 +282,7 @@ static void ot_gpio_write(void *opaque, hwaddr addr, uint64_t val64, break; case R_ALERT_TEST: val32 &= ALERT_TEST_MASK; - ibex_irq_set(&s->alert, val32); + ibex_irq_set(&s->alert, (int)(bool)val32); break; case R_DIRECT_OUT: s->regs[reg] = val32; @@ -389,6 +390,7 @@ static void ot_gpio_chr_receive(void *opaque, const uint8_t *buf, int size) } uint32_t data_in = 0; char cmd = '\0'; + /* NOLINTNEXTLINE */ int ret = sscanf(s->ibuf, "%c:%08x", &cmd, &data_in); memmove(s->ibuf, eol + 1u, eolpos + 1u); s->ipos = 0; @@ -444,6 +446,8 @@ static gboolean ot_gpio_chr_watch_cb(void *do_not_use, GIOCondition cond, void *opaque) { OtGpioState *s = opaque; + (void)do_not_use; + (void)cond; s->watch_tag = 0; @@ -508,6 +512,7 @@ static void ot_gpio_reset(DeviceState *dev) static void ot_gpio_realize(DeviceState *dev, Error **errp) { OtGpioState *s = OT_GPIO(dev); + (void)errp; qemu_chr_fe_set_handlers(&s->chr, &ot_gpio_chr_can_receive, &ot_gpio_chr_receive, &ot_gpio_chr_event_hander, @@ -531,6 +536,7 @@ static void ot_gpio_init(Object *obj) static void ot_gpio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_gpio_reset; dc->realize = &ot_gpio_realize; diff --git a/hw/opentitan/ot_hmac.c b/hw/opentitan/ot_hmac.c index ad4e8381f9b2..3fb37fbd93a5 100644 --- a/hw/opentitan/ot_hmac.c +++ b/hw/opentitan/ot_hmac.c @@ -286,6 +286,7 @@ static inline void ot_hmac_wipe_buffer(OtHMACState *s, uint32_t *buffer, static uint64_t ot_hmac_regs_read(void *opaque, hwaddr addr, unsigned size) { OtHMACState *s = OT_HMAC(opaque); + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -371,6 +372,7 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { OtHMACState *s = OT_HMAC(opaque); + (void)size; uint32_t val32 = (uint32_t)value; hwaddr reg = R32_OFF(addr); @@ -513,6 +515,9 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value, static uint64_t ot_hmac_fifo_read(void *opaque, hwaddr addr, unsigned size) { + (void)opaque; + (void)addr; + (void)size; qemu_log_mask(LOG_GUEST_ERROR, "%s: MSG_FIFO is write only\n", __func__); return 0; @@ -556,7 +561,7 @@ static void ot_hmac_fifo_write(void *opaque, hwaddr addr, uint64_t value, value >>= 8u; } - s->regs->msg_length += 8u * size; + s->regs->msg_length += (uint64_t)size * 8u; /* trigger delayed processing of FIFO */ timer_del(s->fifo_trigger_handle); @@ -639,6 +644,7 @@ static void ot_hmac_reset(DeviceState *dev) static void ot_hmac_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_hmac_reset; device_class_set_props(dc, ot_hmac_properties); diff --git a/hw/opentitan/ot_ibex_wrapper_earlgrey.c b/hw/opentitan/ot_ibex_wrapper_earlgrey.c index c953447657f3..95e15b74692e 100644 --- a/hw/opentitan/ot_ibex_wrapper_earlgrey.c +++ b/hw/opentitan/ot_ibex_wrapper_earlgrey.c @@ -240,6 +240,7 @@ static void ot_ibex_wrapper_eg_request_entropy(OtIbexWrapperEgState *s) static void ot_ibex_wrapper_eg_update_remap(OtIbexWrapperEgState *s, bool doi, unsigned slot) { + (void)doi; g_assert(slot < PARAM_NUM_REGIONS); /* * Warning: @@ -284,6 +285,7 @@ static uint64_t ot_ibex_wrapper_eg_regs_read(void *opaque, hwaddr addr, unsigned size) { OtIbexWrapperEgState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -321,6 +323,7 @@ static void ot_ibex_wrapper_eg_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtIbexWrapperEgState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -446,6 +449,7 @@ static void ot_ibex_wrapper_eg_init(Object *obj) static void ot_ibex_wrapper_eg_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_ibex_wrapper_eg_reset; device_class_set_props(dc, ot_ibex_wrapper_eg_properties); diff --git a/hw/opentitan/ot_kmac.c b/hw/opentitan/ot_kmac.c index 2aa9a6e6c48f..a72059b832e2 100644 --- a/hw/opentitan/ot_kmac.c +++ b/hw/opentitan/ot_kmac.c @@ -561,7 +561,7 @@ static inline size_t ot_kmac_get_key_length(OtKMACState *s) static void ot_kmac_get_key(OtKMACState *s, uint8_t *key, size_t keylen) { - for (size_t ix = 0; ix < keylen && ix < NUM_KEY_REGS * 4u; ix++) { + for (size_t ix = 0; ix < keylen && ix < (size_t)NUM_KEY_REGS * 4u; ix++) { uint8_t reg = ix >> 2u; uint8_t byteoffset = ix & 3u; @@ -640,6 +640,7 @@ static void ot_kmac_process(void *opaque) case OT_KMAC_MODE_SHA3: sha3_done(&s->ltc_state, &s->keccak_state[0]); break; + /* NOLINTNEXTLINE */ case OT_KMAC_MODE_SHAKE: sha3_shake_done(&s->ltc_state, &s->keccak_state[0], ot_kmac_get_keccak_rate_bytes(cfg->strength)); @@ -855,7 +856,7 @@ static void ot_kmac_process_start(OtKMACState *s) switch (cfg->strength) { case 128u: case 256u: - sha3_shake_init(&s->ltc_state, cfg->strength); + sha3_shake_init(&s->ltc_state, (int)cfg->strength); break; default: /* should never happen: strength was already validated earlier */ @@ -867,9 +868,9 @@ static void ot_kmac_process_start(OtKMACState *s) switch (cfg->strength) { case 128u: case 256u: { - sha3_cshake_init(&s->ltc_state, cfg->strength, cfg->prefix.funcname, - cfg->prefix.funcname_len, cfg->prefix.customstr, - cfg->prefix.customstr_len); + sha3_cshake_init(&s->ltc_state, (int)cfg->strength, + cfg->prefix.funcname, cfg->prefix.funcname_len, + cfg->prefix.customstr, cfg->prefix.customstr_len); /* if KMAC mode is enabled, process key */ if (cfg->mode == OT_KMAC_MODE_KMAC) { uint8_t key[NUM_KEY_REGS * sizeof(uint32_t)]; @@ -1029,6 +1030,7 @@ static void ot_kmac_process_sw_command(OtKMACState *s, int cmd) static uint64_t ot_kmac_regs_read(void *opaque, hwaddr addr, unsigned size) { OtKMACState *s = OT_KMAC(opaque); + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -1152,6 +1154,7 @@ static void ot_kmac_regs_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { OtKMACState *s = OT_KMAC(opaque); + (void)size; uint32_t val32 = (uint32_t)value; hwaddr reg = R32_OFF(addr); @@ -1391,12 +1394,19 @@ static uint64_t ot_kmac_state_read(void *opaque, hwaddr addr, unsigned size) static void ot_kmac_state_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { + (void)opaque; + (void)addr; + (void)value; + (void)size; /* on real hardware, writes to STATE are ignored */ qemu_log_mask(LOG_GUEST_ERROR, "%s: STATE is read only\n", __func__); } static uint64_t ot_kmac_msgfifo_read(void *opaque, hwaddr addr, unsigned size) { + (void)opaque; + (void)addr; + (void)size; /* on real hardware, writes to FIFO will block. Let's just return 0. */ qemu_log_mask(LOG_GUEST_ERROR, "%s: MSG_FIFO is write only\n", __func__); return 0; @@ -1449,6 +1459,7 @@ void ot_kmac_connect_app(OtKMACState *s, unsigned app_idx, OtKMACApp *app = &s->apps[app_idx]; if (app->connected) { + /* NOLINTNEXTLINE */ if (memcmp(&app->cfg, cfg, sizeof(OtKMACAppCfg)) == 0 && fn == app->fn && opaque == app->opaque) { /* @@ -1474,7 +1485,7 @@ void ot_kmac_connect_app(OtKMACState *s, unsigned app_idx, app->cfg.strength = 128u; } if (app->cfg.mode == OT_KMAC_MODE_KMAC) { - if (memcmp(app->cfg.prefix.funcname, "KMAC", 4u) || + if (memcmp(app->cfg.prefix.funcname, "KMAC", 4u) != 0 || app->cfg.prefix.funcname_len != 4u) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid config for app index %u: invalid prefix" @@ -1598,6 +1609,7 @@ static void ot_kmac_reset(DeviceState *dev) static void ot_kmac_realize(DeviceState *dev, Error **errp) { OtKMACState *s = OT_KMAC(dev); + (void)errp; /* make sure num-app property is set */ g_assert(s->num_app > 0); @@ -1649,6 +1661,7 @@ static void ot_kmac_init(Object *obj) static void ot_kmac_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->realize = &ot_kmac_realize; dc->reset = &ot_kmac_reset; diff --git a/hw/opentitan/ot_lifecycle.c b/hw/opentitan/ot_lifecycle.c index f4ae6decc710..5998f8c47be8 100644 --- a/hw/opentitan/ot_lifecycle.c +++ b/hw/opentitan/ot_lifecycle.c @@ -240,6 +240,7 @@ static bool ot_lifecycle_own_hw_mutex(OtLifeCycleState *s) static void ot_lifecycle_start_transition(OtLifeCycleState *s) { + (void)s; qemu_log_mask(LOG_UNIMP, "%s: Transition commands not implemented\n", __func__); } @@ -335,6 +336,7 @@ static bool ot_lifecycle_is_vendor_test_state(uint32_t state) static uint64_t ot_lifecycle_regs_read(void *opaque, hwaddr addr, unsigned size) { OtLifeCycleState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -409,6 +411,7 @@ static void ot_lifecycle_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtLifeCycleState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -444,7 +447,7 @@ static void ot_lifecycle_regs_write(void *opaque, hwaddr addr, uint64_t val64, break; case R_TRANSITION_CMD: val32 &= R_TRANSITION_CMD_START_MASK; - if (ot_lifecycle_own_hw_mutex(s)) { + if (val32 && ot_lifecycle_own_hw_mutex(s)) { ot_lifecycle_start_transition(s); } break; @@ -555,6 +558,7 @@ static void ot_lifecycle_init(Object *obj) static void ot_lifecycle_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_lifecycle_reset; device_class_set_props(dc, ot_lifecycle_properties); diff --git a/hw/opentitan/ot_otbn.c b/hw/opentitan/ot_otbn.c index 59173d62a736..e76cb0bc8180 100644 --- a/hw/opentitan/ot_otbn.c +++ b/hw/opentitan/ot_otbn.c @@ -390,6 +390,7 @@ static void ot_otbn_handle_command(OtOTBNState *s, unsigned command) static uint64_t ot_otbn_regs_read(void *opaque, hwaddr addr, unsigned size) { OtOTBNState *s = opaque; + (void)size; uint32_t val32; uint64_t pc = ibex_get_current_pc(); @@ -444,6 +445,7 @@ static void ot_otbn_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtOTBNState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -493,7 +495,7 @@ static void ot_otbn_regs_write(void *opaque, hwaddr addr, uint64_t val64, ot_otbn_proxy_set_instruction_count(s->proxy, val32); break; case R_LOAD_CHECKSUM: - val32 = s->load_checksum; + s->load_checksum = val32; break; case R_STATUS: case R_FATAL_ALERT_CAUSE: @@ -691,6 +693,7 @@ static void ot_otbn_realize(DeviceState *dev, Error **errp) static void ot_otbn_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_otbn_reset; dc->realize = &ot_otbn_realize; diff --git a/hw/opentitan/ot_otp_earlgrey.c b/hw/opentitan/ot_otp_earlgrey.c index 55ce2a1d3ad9..3e11e7636076 100644 --- a/hw/opentitan/ot_otp_earlgrey.c +++ b/hw/opentitan/ot_otp_earlgrey.c @@ -559,6 +559,8 @@ static const OtOTPPartition OtOTPPartitions[] = { }; /* clang-format on */ + +/* NOLINTNEXTLINE */ #include "ot_otp_earlgrey_lcvalues.c" #define LC_TRANSITION_COUNT_MAX 24u @@ -768,17 +770,20 @@ static void ot_otp_eg_direct_read(OtOTPEgState *s) static void ot_otp_eg_direct_write(OtOTPEgState *s) { + (void)s; qemu_log_mask(LOG_UNIMP, "%s: OTP write is not supported\n", __func__); } static void ot_otp_eg_direct_digest(OtOTPEgState *s) { + (void)s; qemu_log_mask(LOG_UNIMP, "%s: OTP change is not supported\n", __func__); } static uint64_t ot_otp_eg_regs_read(void *opaque, hwaddr addr, unsigned size) { OtOTPEgState *s = OT_OTP_EARLGREY(opaque); + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -803,6 +808,7 @@ static uint64_t ot_otp_eg_regs_read(void *opaque, hwaddr addr, unsigned size) val32 = FIELD_DP32(0, DIRECT_ACCESS_REGWEN, REGWEN, (uint32_t)!s->dai_busy); break; + /* NOLINTNEXTLINE */ case R_DIRECT_ACCESS_CMD: val32 = 0; /* R0W1C */ break; @@ -901,6 +907,7 @@ static void ot_otp_eg_regs_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { OtOTPEgState *s = OT_OTP_EARLGREY(opaque); + (void)size; uint32_t val32 = (uint32_t)value; hwaddr reg = R32_OFF(addr); @@ -1128,6 +1135,8 @@ static void ot_otp_eg_swcfg_write(void *opaque, hwaddr addr, uint64_t value, static uint64_t ot_otp_eg_csrs_read(void *opaque, hwaddr addr, unsigned size) { + (void)opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -1159,6 +1168,8 @@ static uint64_t ot_otp_eg_csrs_read(void *opaque, hwaddr addr, unsigned size) static void ot_otp_eg_csrs_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { + (void)opaque; + (void)size; uint32_t val32 = (uint32_t)value; hwaddr reg = R32_OFF(addr); @@ -1364,7 +1375,7 @@ static void ot_otp_eg_load(OtOTPEgState *s, Error **errp) (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0); (void)blk_set_perm(s->blk, perm, perm, errp); - int rc = blk_pread(s->blk, 0, otp_size, otp->storage, 0); + int rc = blk_pread(s->blk, 0, (int64_t)otp_size, otp->storage, 0); if (rc < 0) { error_setg(errp, "failed to read the initial OTP content: %d", rc); return; @@ -1372,7 +1383,7 @@ static void ot_otp_eg_load(OtOTPEgState *s, Error **errp) const struct otp_header *otp_hdr = (const struct otp_header *)base; - if (memcmp(otp_hdr->magic, "vOTP", sizeof(otp_hdr->magic))) { + if (memcmp(otp_hdr->magic, "vOTP", sizeof(otp_hdr->magic)) != 0) { error_setg(errp, "OTP file is not a valid OTP backend"); return; } @@ -1407,6 +1418,7 @@ static void ot_otp_eg_load(OtOTPEgState *s, Error **errp) static void ot_otp_eg_realize(DeviceState *dev, Error **errp) { OtOTPEgState *s = OT_OTP_EARLGREY(dev); + (void)errp; ot_otp_eg_load(s, &error_fatal); } @@ -1445,6 +1457,7 @@ static void ot_otp_eg_init(Object *obj) static void ot_otp_eg_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_otp_eg_reset; dc->realize = &ot_otp_eg_realize; diff --git a/hw/opentitan/ot_otp_earlgrey_lcvalues.c b/hw/opentitan/ot_otp_earlgrey_lcvalues.c index 78e2e7349259..add2cbde2b68 100644 --- a/hw/opentitan/ot_otp_earlgrey_lcvalues.c +++ b/hw/opentitan/ot_otp_earlgrey_lcvalues.c @@ -30,6 +30,7 @@ /* Section auto-generated with otpconv.py [-i/-c/-h/-O lc_arrays] script */ /* clang-format off */ +/* NOLINTBEGIN */ static const char lc_states[21u][40u] = { [LC_STATE_RAW] = { 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, @@ -336,6 +337,7 @@ static const char lc_transition_cnts[25u][48u] = { 0xbeu, 0x76u, 0xfdu, 0x6bu, 0xfbu, 0x8fu, 0xcdu, 0xfbu }, }; +/* NOLINTEND */ /* clang-format on */ /* End of auto-generated section */ diff --git a/hw/opentitan/ot_pinmux.c b/hw/opentitan/ot_pinmux.c index 10c561c40034..6191fcb95cbf 100644 --- a/hw/opentitan/ot_pinmux.c +++ b/hw/opentitan/ot_pinmux.c @@ -197,6 +197,7 @@ struct OtPinmuxState { static uint64_t ot_pinmux_regs_read(void *opaque, hwaddr addr, unsigned size) { OtPinmuxState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); OtPinmuxStateRegs *regs = s->regs; @@ -293,6 +294,7 @@ static void ot_pinmux_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtPinmuxState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); OtPinmuxStateRegs *regs = s->regs; @@ -472,6 +474,7 @@ static void ot_pinmux_init(Object *obj) static void ot_pinmux_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_pinmux_reset; device_class_set_props(dc, ot_pinmux_properties); diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index ed05928aaef9..11c931f91321 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -207,7 +207,7 @@ static void ot_pwrmgr_update_irq(OtPwrMgrState *s) { uint32_t level = s->regs[R_INTR_STATE] & s->regs[R_INTR_ENABLE]; - ibex_irq_set(&s->irq, level); + ibex_irq_set(&s->irq, (int)(bool)level); } static void ot_pwrmgr_cdc_sync(void *opaque) @@ -265,6 +265,7 @@ static void ot_pwrmgr_rom_done(void *opaque, int irq, int level) static void ot_pwrmgr_wkup(void *opaque, int irq, int level) { /* not implemented yet */ + (void)opaque; unsigned src = (unsigned)irq; assert(src < OT_PWRMGR_WAKEUP_COUNT); @@ -346,6 +347,7 @@ static void ot_pwrmgr_trigger_reset(void *opaque) static uint64_t ot_pwrmgr_regs_read(void *opaque, hwaddr addr, unsigned size) { OtPwrMgrState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -393,6 +395,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtPwrMgrState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -429,8 +432,11 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64, break; case R_CFG_CDC_SYNC: val32 &= R_CFG_CDC_SYNC_SYNC_MASK; - timer_mod(s->cdc_sync, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - CDC_SYNC_PULSE_DURATION_NS); + 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) + + CDC_SYNC_PULSE_DURATION_NS); + } break; case R_WAKEUP_EN_REGWEN: val32 &= R_WAKEUP_EN_REGWEN_EN_MASK; @@ -514,6 +520,7 @@ static void ot_pwrmgr_reset(DeviceState *dev) static void ot_pwrmgr_realize(DeviceState *dev, Error **errp) { OtPwrMgrState *s = OT_PWRMGR(dev); + (void)errp; if (s->num_rom) { s->roms = g_new0(OtPwrMgrRomStatus, s->num_rom); @@ -553,6 +560,7 @@ static void ot_pwrmgr_init(Object *obj) static void ot_pwrmgr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->realize = &ot_pwrmgr_realize; dc->reset = &ot_pwrmgr_reset; diff --git a/hw/opentitan/ot_rom_ctrl.c b/hw/opentitan/ot_rom_ctrl.c index 6e4fb81975b1..2455831780ca 100644 --- a/hw/opentitan/ot_rom_ctrl.c +++ b/hw/opentitan/ot_rom_ctrl.c @@ -118,23 +118,23 @@ struct OtRomCtrlClass { struct OtRomCtrlState { SysBusDevice parent_obj; - IbexIRQ pwrmgr_good; - IbexIRQ pwrmgr_done; - MemoryRegion mem; MemoryRegion mmio; + IbexIRQ pwrmgr_good; + IbexIRQ pwrmgr_done; IbexIRQ alert; uint32_t regs[REGS_COUNT]; - bool first_reset; - bool fake_digest; hwaddr digest_offset; - char *rom_id; uint32_t size; OtKMACState *kmac; + char *rom_id; uint8_t kmac_app; + + bool first_reset; + bool fake_digest; }; static void ot_rom_ctrl_load_rom(OtRomCtrlState *s) @@ -202,6 +202,7 @@ static void ot_rom_ctrl_compare_and_notify(OtRomCtrlState *s) static uint64_t ot_rom_ctrl_regs_read(void *opaque, hwaddr addr, unsigned size) { OtRomCtrlState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -250,6 +251,7 @@ static void ot_rom_ctrl_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtRomCtrlState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -343,7 +345,7 @@ ot_rom_ctrl_handle_kmac_response(void *opaque, const OtKMACAppRsp *rsp) memcpy(&share1, &rsp->digest_share1[ix * sizeof(uint32_t)], sizeof(uint32_t)); s->regs[R_DIGEST_0 + ix] = share0 ^ share1; - /* if "fake digest" mode is enabled, copy computed digest to expected */ + /* "fake digest" mode enabled, copy computed digest to expected */ if (s->fake_digest) { s->regs[R_EXP_DIGEST_0 + ix] = s->regs[R_DIGEST_0 + ix]; } @@ -422,7 +424,7 @@ static void ot_rom_ctrl_mem_write(void *opaque, hwaddr addr, uint64_t value, uint8_t *rom_ptr = (uint8_t *)memory_region_get_ram_ptr(&s->mem); if ((addr + size) <= s->size) { - stn_le_p(&rom_ptr[addr], size, value); + stn_le_p(&rom_ptr[addr], (int)size, value); } else { qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx ", pc=0x%x\n", __func__, @@ -434,6 +436,7 @@ static bool ot_rom_ctrl_mem_accepts(void *opaque, hwaddr addr, unsigned size, bool is_write, MemTxAttrs attrs) { OtRomCtrlState *s = opaque; + (void)attrs; uint64_t pc = ibex_get_current_pc(); trace_ot_rom_ctrl_mem_accepts((unsigned int)addr, is_write, pc); @@ -500,6 +503,8 @@ static void ot_rom_ctrl_init(Object *obj) static void ot_rom_ctrl_class_init(ObjectClass *klass, void *data) { OtRomCtrlClass *rcc = OT_ROM_CTRL_CLASS(klass); + (void)data; + DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(dc); diff --git a/hw/opentitan/ot_rom_ctrl_img.c b/hw/opentitan/ot_rom_ctrl_img.c index c226017906c8..943d7e73d587 100644 --- a/hw/opentitan/ot_rom_ctrl_img.c +++ b/hw/opentitan/ot_rom_ctrl_img.c @@ -51,6 +51,7 @@ static void ot_rom_img_prop_set_file(Object *obj, const char *value, Error **errp) { OtRomImg *ri = OT_ROM_IMG(obj); + (void)errp; g_free(ri->filename); ri->filename = g_strdup(value); @@ -59,6 +60,7 @@ static void ot_rom_img_prop_set_file(Object *obj, const char *value, static char *ot_rom_img_prop_get_file(Object *obj, Error **errp) { OtRomImg *ri = OT_ROM_IMG(obj); + (void)errp; return g_strdup(ri->filename); } @@ -105,19 +107,21 @@ static void ot_rom_img_prop_set_digest(Object *obj, const char *value, static char *ot_rom_img_prop_get_digest(Object *obj, Error **errp) { OtRomImg *ri = OT_ROM_IMG(obj); - char *digest; + (void)errp; if (ri->fake_digest) { return g_strdup("fake"); } - digest = g_new0(char, (ri->digest_len * 2) + 1); + char *digest = g_new0(char, (ri->digest_len * 2u) + 1u); for (unsigned idx = 0; idx < ri->digest_len; idx++) { - uint8_t val = ri->digest[ri->digest_len - 1 - idx]; - digest[(idx * 2)] = HEX[(val >> 4) & 0xf]; - digest[(idx * 2) + 1] = HEX[val & 0xf]; + uint8_t val = ri->digest[ri->digest_len - 1u - idx]; + /* NOLINTNEXTLINE */ + digest[(idx * 2u)] = HEX[(val >> 4u) & 0xfu]; + digest[(idx * 2u) + 1u] = HEX[val & 0xfu]; } - digest[ri->digest_len * 2] = '\0'; + /* NOLINTNEXTLINE */ + digest[ri->digest_len * 2u] = '\0'; return digest; } @@ -156,6 +160,7 @@ static void ot_rom_img_complete(UserCreatable *uc, Error **errp) static void ot_rom_img_class_init(ObjectClass *oc, void *data) { UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); + (void)data; ucc->complete = &ot_rom_img_complete; diff --git a/hw/opentitan/ot_rstmgr.c b/hw/opentitan/ot_rstmgr.c index f998d84e5599..1cf33bed85df 100644 --- a/hw/opentitan/ot_rstmgr.c +++ b/hw/opentitan/ot_rstmgr.c @@ -273,6 +273,7 @@ static void ot_rstmgr_update_sw_reset(OtRstMgrState *s, unsigned devix) static uint64_t ot_rstmgr_regs_read(void *opaque, hwaddr addr, unsigned size) { OtRstMgrState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -331,6 +332,7 @@ static void ot_rstmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtRstMgrState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -455,7 +457,6 @@ static void ot_rstmgr_reset(DeviceState *dev) { OtRstMgrState *s = OT_RSTMGR(dev); - s->regs[R_RESET_REQ] = 0x9u; if (s->por) { memset(s->regs, 0, REGS_SIZE); @@ -496,6 +497,7 @@ static void ot_rstmgr_init(Object *obj) static void ot_rstmgr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_rstmgr_reset; device_class_set_props(dc, ot_rstmgr_properties); diff --git a/hw/opentitan/ot_sensor.c b/hw/opentitan/ot_sensor.c index cb77cca26640..1fd5ef4e7379 100644 --- a/hw/opentitan/ot_sensor.c +++ b/hw/opentitan/ot_sensor.c @@ -138,22 +138,26 @@ struct OtSensorState { SysBusDevice parent_obj; MemoryRegion mmio; - IbexIRQ irq; + IbexIRQ irqs[2u]; IbexIRQ alert; uint32_t *regs; }; -static void ot_sensor_update_irq(OtSensorState *s) +static void ot_sensor_update_irqs(OtSensorState *s) { - uint32_t level = s->regs[R_INTR_STATE] & s->regs[R_INTR_ENABLE]; + uint32_t levels = s->regs[R_INTR_STATE] & s->regs[R_INTR_ENABLE]; - ibex_irq_set(&s->irq, level); + for (unsigned ix = 0; ix < ARRAY_SIZE(s->irqs); ix++) { + int level = (int)(bool)(levels & (1u << ix)); + ibex_irq_set(&s->irqs[ix], level); + } } static uint64_t ot_sensor_regs_read(void *opaque, hwaddr addr, unsigned size) { OtSensorState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -200,6 +204,7 @@ static void ot_sensor_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtSensorState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -211,17 +216,17 @@ static void ot_sensor_regs_write(void *opaque, hwaddr addr, uint64_t val64, case R_INTR_STATE: val32 &= INTR_MASK; s->regs[R_INTR_STATE] &= ~val32; /* RW1C */ - ot_sensor_update_irq(s); + ot_sensor_update_irqs(s); break; case R_INTR_ENABLE: val32 &= INTR_MASK; s->regs[R_INTR_ENABLE] = val32; - ot_sensor_update_irq(s); + ot_sensor_update_irqs(s); break; case R_INTR_TEST: val32 &= INTR_MASK; s->regs[R_INTR_STATE] |= val32; - ot_sensor_update_irq(s); + ot_sensor_update_irqs(s); break; case R_ALERT_TEST: val32 &= ALERT_TEST_MASK; @@ -270,7 +275,7 @@ static void ot_sensor_reset(DeviceState *dev) s->regs[R_CFG_REGWEN] = 0x1u; - ot_sensor_update_irq(s); + ot_sensor_update_irqs(s); ibex_irq_set(&s->alert, 0); } @@ -283,13 +288,16 @@ static void ot_sensor_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio); s->regs = g_new0(uint32_t, REGS_COUNT); - ibex_sysbus_init_irq(obj, &s->irq); + for (unsigned ix = 0; ix < ARRAY_SIZE(s->irqs); ix++) { + ibex_sysbus_init_irq(obj, &s->irqs[ix]); + } ibex_qdev_init_irq(obj, &s->alert, OPENTITAN_DEVICE_ALERT); } static void ot_sensor_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_sensor_reset; device_class_set_props(dc, ot_sensor_properties); diff --git a/hw/opentitan/ot_spi_host.c b/hw/opentitan/ot_spi_host.c index 0543dcf0d34c..100876192596 100644 --- a/hw/opentitan/ot_spi_host.c +++ b/hw/opentitan/ot_spi_host.c @@ -249,17 +249,17 @@ static void ot_spi_host_trace_status(const char *msg, uint32_t status) unsigned rxd = FIELD_EX32(status, STATUS, RXQD); unsigned txd = FIELD_EX32(status, STATUS, TXQD); char str[64u]; - snprintf(str, sizeof(str), "%s%s%s%s%s%s%s%s%s%s", - FIELD_EX32(status, STATUS, RXWM) ? "RXM|" : "", - FIELD_EX32(status, STATUS, RXSTALL) ? "RXS|" : "", - FIELD_EX32(status, STATUS, RXEMPTY) ? "RXE|" : "", - FIELD_EX32(status, STATUS, RXFULL) ? "RXF|" : "", - FIELD_EX32(status, STATUS, TXWM) ? "TXM|" : "", - FIELD_EX32(status, STATUS, TXSTALL) ? "TXS|" : "", - FIELD_EX32(status, STATUS, TXEMPTY) ? "TXE|" : "", - FIELD_EX32(status, STATUS, TXFULL) ? "TXF|" : "", - FIELD_EX32(status, STATUS, ACTIVE) ? "ACT|" : "", - FIELD_EX32(status, STATUS, READY) ? "RDY|" : ""); + (void)snprintf(str, sizeof(str), "%s%s%s%s%s%s%s%s%s%s", + FIELD_EX32(status, STATUS, RXWM) ? "RXM|" : "", + FIELD_EX32(status, STATUS, RXSTALL) ? "RXS|" : "", + FIELD_EX32(status, STATUS, RXEMPTY) ? "RXE|" : "", + FIELD_EX32(status, STATUS, RXFULL) ? "RXF|" : "", + FIELD_EX32(status, STATUS, TXWM) ? "TXM|" : "", + FIELD_EX32(status, STATUS, TXSTALL) ? "TXS|" : "", + FIELD_EX32(status, STATUS, TXEMPTY) ? "TXE|" : "", + FIELD_EX32(status, STATUS, TXFULL) ? "TXF|" : "", + FIELD_EX32(status, STATUS, ACTIVE) ? "ACT|" : "", + FIELD_EX32(status, STATUS, READY) ? "RDY|" : ""); trace_ot_spi_host_status(msg, status, str, cmd, rxd, txd); } @@ -1231,6 +1231,7 @@ static Property ot_spi_host_properties[] = { static void ot_spi_host_realize(DeviceState *dev, Error **errp) { OtSPIHostState *s = OT_SPI_HOST(dev); + (void)errp; s->cs_lines = g_new0(qemu_irq, (size_t)s->num_cs); @@ -1278,6 +1279,8 @@ static void ot_spi_host_instance_init(Object *obj) static void ot_spi_host_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; + dc->realize = ot_spi_host_realize; dc->reset = ot_spi_host_reset; device_class_set_props(dc, ot_spi_host_properties); diff --git a/hw/opentitan/ot_sram_ctrl.c b/hw/opentitan/ot_sram_ctrl.c index 745962fd00cb..98486b37309e 100644 --- a/hw/opentitan/ot_sram_ctrl.c +++ b/hw/opentitan/ot_sram_ctrl.c @@ -109,6 +109,7 @@ struct OtSramCtrlState { static uint64_t ot_sram_ctrl_regs_read(void *opaque, hwaddr addr, unsigned size) { OtSramCtrlState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -145,6 +146,7 @@ static void ot_sram_ctrl_regs_write(void *opaque, hwaddr addr, uint64_t val64, unsigned size) { OtSramCtrlState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); @@ -269,6 +271,7 @@ static void ot_sram_ctrl_init(Object *obj) static void ot_sram_ctrl_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_sram_ctrl_reset; dc->realize = &ot_sram_ctrl_realize; diff --git a/hw/opentitan/ot_timer.c b/hw/opentitan/ot_timer.c index 355b6e50ae9c..578aec9e0cb6 100644 --- a/hw/opentitan/ot_timer.c +++ b/hw/opentitan/ot_timer.c @@ -112,7 +112,8 @@ static int64_t ot_timer_ticks_to_ns(OtTimerState *s, uint64_t ticks) if (ns > INT64_MAX) { return INT64_MAX; } - return ns; + + return (int64_t)ns; } static uint64_t ot_timer_get_mtime(OtTimerState *s, int64_t now) @@ -195,6 +196,7 @@ static void ot_timer_cb(void *opaque) static uint64_t ot_timer_read(void *opaque, hwaddr addr, unsigned size) { OtTimerState *s = opaque; + (void)size; uint32_t val32 = 0; hwaddr reg = R32_OFF(addr); @@ -245,6 +247,7 @@ static void ot_timer_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { OtTimerState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)value; hwaddr reg = R32_OFF(addr); @@ -376,6 +379,7 @@ static void ot_timer_init(Object *obj) static void ot_timer_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->reset = &ot_timer_reset; device_class_set_props(dc, ot_timer_properties); diff --git a/hw/opentitan/ot_uart.c b/hw/opentitan/ot_uart.c index 1bb353c2db8a..24bbb1d9be77 100644 --- a/hw/opentitan/ot_uart.c +++ b/hw/opentitan/ot_uart.c @@ -219,7 +219,7 @@ static int ot_uart_can_receive(void *opaque) OtUARTState *s = opaque; if (s->regs[R_CTRL] & R_CTRL_RX_MASK) { - return fifo8_num_free(&s->rx_fifo); + return (int)fifo8_num_free(&s->rx_fifo); } return 0; @@ -292,7 +292,7 @@ static void ot_uart_xmit(OtUARTState *s) /* system loopback mode, just forward to RX FIFO */ uint32_t count = fifo8_num_used(&s->tx_fifo); buf = fifo8_pop_buf(&s->tx_fifo, count, &size); - ot_uart_receive(s, buf, size); + ot_uart_receive(s, buf, (int)size); count -= size; /* * there may be more data to send if data wraps around the end of TX @@ -300,7 +300,7 @@ static void ot_uart_xmit(OtUARTState *s) */ if (count) { buf = fifo8_pop_buf(&s->tx_fifo, count, &size); - ot_uart_receive(s, buf, size); + ot_uart_receive(s, buf, (int)size); } } else { /* instant drain the fifo when there's no back-end */ @@ -313,7 +313,7 @@ static void ot_uart_xmit(OtUARTState *s) /* get a continuous buffer from the FIFO */ buf = fifo8_peek_buf(&s->tx_fifo, fifo8_num_used(&s->tx_fifo), &size); /* send as much as possible */ - ret = qemu_chr_fe_write(&s->chr, buf, size); + ret = qemu_chr_fe_write(&s->chr, buf, (int)size); /* if some characters where sent, remove them from the FIFO */ if (ret >= 0) { fifo8_consume_all(&s->tx_fifo, ret); @@ -337,6 +337,8 @@ static gboolean ot_uart_watch_cb(void *do_not_use, GIOCondition cond, void *opaque) { OtUARTState *s = opaque; + (void)do_not_use; + (void)cond; s->watch_tag = 0; ot_uart_xmit(s); @@ -368,9 +370,10 @@ static void uart_write_tx_fifo(OtUARTState *s, uint8_t val) } } -static uint64_t ot_uart_read(void *opaque, hwaddr addr, unsigned int size) +static uint64_t ot_uart_read(void *opaque, hwaddr addr, unsigned size) { OtUARTState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -447,9 +450,10 @@ static uint64_t ot_uart_read(void *opaque, hwaddr addr, unsigned int size) } static void ot_uart_write(void *opaque, hwaddr addr, uint64_t val64, - unsigned int size) + unsigned size) { OtUARTState *s = opaque; + (void)size; uint32_t val32 = val64; hwaddr reg = R32_OFF(addr); @@ -524,7 +528,6 @@ static void ot_uart_write(void *opaque, hwaddr addr, uint64_t val64, qemu_log_mask(LOG_GUEST_ERROR, "R/O register 0x%02" HWADDR_PRIx " (%s)\n", addr, REG_NAME(reg)); - val32 = 0; break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", @@ -566,6 +569,7 @@ static int ot_uart_be_change(void *opaque) static void ot_uart_realize(DeviceState *dev, Error **errp) { OtUARTState *s = OT_UART(dev); + (void)errp; fifo8_create(&s->tx_fifo, OT_UART_TX_FIFO_SIZE); fifo8_create(&s->rx_fifo, OT_UART_RX_FIFO_SIZE); @@ -606,6 +610,7 @@ static void ot_uart_init(Object *obj) static void ot_uart_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; dc->realize = ot_uart_realize; dc->reset = ot_uart_reset; diff --git a/include/hw/opentitan/ot_ast.h b/include/hw/opentitan/ot_ast.h index 6e18a5509e71..f0cefa55073b 100644 --- a/include/hw/opentitan/ot_ast.h +++ b/include/hw/opentitan/ot_ast.h @@ -33,7 +33,7 @@ #define TYPE_OT_AST "ot-ast" OBJECT_DECLARE_SIMPLE_TYPE(OtASTState, OT_AST) -#define OT_AST_RANDOM_4BIT_RATE 50000 /* 50 kHz */ +#define OT_AST_RANDOM_4BIT_RATE 50000u /* 50 kHz */ void ot_ast_getrandom(void *buf, size_t len); From 9d8b42840ef9d509c0d353b93c7bcb3f1ca9b351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Tue, 17 Oct 2023 19:17:44 +0200 Subject: [PATCH 05/15] [ot] hw/riscv: ot_earlgrey: fix several issues detected with clang-tidy 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 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index f658c47493cd..d4f0976eed62 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -883,6 +883,9 @@ static void ot_earlgrey_soc_flash_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { DriveInfo *dinfo = drive_get(IF_MTD, 1, 0); + (void)def; + (void)parent; + if (dinfo) { qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(dinfo), &error_fatal); @@ -893,6 +896,9 @@ static void ot_earlgrey_soc_hart_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { OtEarlGreyMachineState *ms = RISCV_OT_EARLGREY_MACHINE(qdev_get_machine()); + (void)def; + (void)parent; + if (ms->no_epmp_cfg) { /* skip default PMP config */ return; @@ -921,6 +927,9 @@ static void ot_earlgrey_soc_otp_ctrl_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); + (void)def; + (void)parent; + if (dinfo) { qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(dinfo), &error_fatal); @@ -930,6 +939,8 @@ static void ot_earlgrey_soc_otp_ctrl_configure( static void ot_earlgrey_soc_uart_configure( DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { + (void)def; + (void)parent; qdev_prop_set_chr(dev, "chardev", serial_hd(def->instance)); } @@ -970,6 +981,7 @@ static void ot_earlgrey_soc_reset_exit(Object *obj) static void ot_earlgrey_soc_realize(DeviceState *dev, Error **errp) { OtEarlGreySoCState *s = RISCV_OT_EARLGREY_SOC(dev); + (void)errp; /* Link, define properties and realize devices, then connect GPIOs */ ibex_link_devices(s->devices, ot_earlgrey_soc_devices, @@ -999,6 +1011,7 @@ static void ot_earlgrey_soc_class_init(ObjectClass *oc, void *data) OtEarlGreySoCClass *sc = RISCV_OT_EARLGREY_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, @@ -1066,6 +1079,7 @@ static void ot_earlgrey_board_init(Object *obj) static void ot_earlgrey_board_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); + (void)data; dc->realize = &ot_earlgrey_board_realize; } @@ -1092,6 +1106,7 @@ type_init(ot_earlgrey_board_register_types); static bool ot_earlgrey_machine_get_no_epmp_cfg(Object *obj, Error **errp) { OtEarlGreyMachineState *s = RISCV_OT_EARLGREY_MACHINE(obj); + (void)errp; return s->no_epmp_cfg; } @@ -1100,6 +1115,7 @@ static void ot_earlgrey_machine_set_no_epmp_cfg(Object *obj, bool value, Error **errp) { OtEarlGreyMachineState *s = RISCV_OT_EARLGREY_MACHINE(obj); + (void)errp; s->no_epmp_cfg = value; } @@ -1127,6 +1143,7 @@ static void ot_earlgrey_machine_init(MachineState *state) static void ot_earlgrey_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; From 167777a1b6de958132345a1c3ec4e0a8223ccf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lefort?= Date: Tue, 17 Oct 2023 14:30:01 +0200 Subject: [PATCH 06/15] [ot] hw/opentitan: ot_pwrmgr: only reset when request level is high MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Lefort --- hw/opentitan/ot_pwrmgr.c | 69 +++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/hw/opentitan/ot_pwrmgr.c b/hw/opentitan/ot_pwrmgr.c index 11c931f91321..eff331561043 100644 --- a/hw/opentitan/ot_pwrmgr.c +++ b/hw/opentitan/ot_pwrmgr.c @@ -295,15 +295,25 @@ static void ot_pwrmgr_rst_req(void *opaque, int irq, int level) break; } - uint32_t rstmask = 1u << src; /*rst_req are stored in the LSBs */ - s->regs[R_RESET_STATUS] |= rstmask; - - /* - * for now, there is no FSM in PWRMGR implementation. - * simply forward the request to the RSTMGR - */ - qemu_bh_schedule(s->reset_bh); - trace_ot_pwrmgr_reset_req("scheduling reset", src); + uint32_t rstmask = 1u << src; /* rst_req are stored in the LSBs */ + + if (level) { + if (s->regs[R_RESET_STATUS]) { + /* do nothing if a reset is already in progress */ + return; + } + + s->regs[R_RESET_STATUS] |= rstmask; + + /* + * for now, there is no FSM in PWRMGR implementation. + * simply forward the request to the RSTMGR + */ + qemu_bh_schedule(s->reset_bh); + trace_ot_pwrmgr_reset_req("scheduling reset", src); + } else { + s->regs[R_RESET_STATUS] &= ~rstmask; + } } static void ot_pwrmgr_sw_rst_req(void *opaque, int irq, int level) @@ -314,27 +324,34 @@ static void ot_pwrmgr_sw_rst_req(void *opaque, int irq, int level) assert(src < NUM_SW_RST_REQ); trace_ot_pwrmgr_sw_rst_req(src, (bool)level); - if (!level) { - return; - } uint32_t rstmask = 1u << (NUM_SW_RST_REQ + src); - if (!(s->regs[R_RESET_EN] & rstmask)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: SW reset %u not enabled\n", - __func__, src); - return; - } - s->regs[R_RESET_STATUS] |= rstmask; + if (level) { + if (!(s->regs[R_RESET_EN] & rstmask)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: SW reset %u not enabled\n", + __func__, src); + return; + } + + if (s->regs[R_RESET_STATUS]) { + /* do nothing if a reset is already in progress */ + return; + } - /* - * for now, there is no FSM in PWRMGR implementation. - * simply forward the request to the RSTMGR - */ - s->reset_req.req = OT_RSTMGR_RESET_SW; - s->reset_req.domain = true; - qemu_bh_schedule(s->reset_bh); - trace_ot_pwrmgr_reset_req("scheduling SW reset", 0); + s->regs[R_RESET_STATUS] |= rstmask; + + /* + * for now, there is no FSM in PWRMGR implementation. + * simply forward the request to the RSTMGR + */ + s->reset_req.req = OT_RSTMGR_RESET_SW; + s->reset_req.domain = true; + qemu_bh_schedule(s->reset_bh); + trace_ot_pwrmgr_reset_req("scheduling SW reset", 0); + } else { + s->regs[R_RESET_STATUS] &= ~rstmask; + } } static void ot_pwrmgr_trigger_reset(void *opaque) From 0062731c26048cfecbb17e7491ede5a8c9a818a7 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 18 Oct 2023 12:59:38 +0200 Subject: [PATCH 07/15] [ot] hw/opentitan: add a new option `addr` to load ROM with a binary file if `addr` is specified, `file` argument is loaded as a raw binary file, otherwise as an ELF file. `addr` specifies an absolute address, not a ROM-relative address Signed-off-by: Emmanuel Blot --- docs/opentitan/rom_ctrl.md | 33 ++++++- hw/opentitan/ot_rom_ctrl.c | 115 ++++++++++++++++++++++--- hw/opentitan/ot_rom_ctrl_img.c | 39 ++++++++- include/hw/opentitan/ot_rom_ctrl_img.h | 1 + qapi/qom.json | 3 +- 5 files changed, 168 insertions(+), 23 deletions(-) diff --git a/docs/opentitan/rom_ctrl.md b/docs/opentitan/rom_ctrl.md index 1474bdbbd243..b8bf87e62917 100644 --- a/docs/opentitan/rom_ctrl.md +++ b/docs/opentitan/rom_ctrl.md @@ -15,17 +15,38 @@ comparison happens). ## QEMU ROM Options +### Digest + +The ROM digest is either a sequence of 64 hex digits (_i.e._ 32 bytes) or the exact string `fake` to +enable _fake digest_ mode). + +### ELF ROM file + The ROM ELF file and its digest can be provided on the QEMU command line using this option: ``` -object ot-rom-img,id=rom,file=/path/to/rom.elf,digest= ``` -The ROM image ID may depend on the SoC. For EarlGrey which has a single ROM, the ID is expected to -be `rom`. +### Binary ROM file -The ROM digest is either a sequence of 64 hex digits (_i.e._ 32 bytes) or the exact string `fake` to -enable _fake digest_ mode). +The ROM binary file and its digest can be provided on the QEMU command line using this option: + +``` +-object ot-rom-img,id=rom,file=/path/to/rom.bin,digest=,addr=address +``` + +If `addr` is specifed, the file is loaded as a raw binary file, whatever its extension. + +`addr` is specified as an absolute address in the CPU address space, _i.e._ not relative to the +ROM base address. + +### ROM identifiers + +The ROM image ID may depend on the SoC. + +* for EarlGrey which has a single ROM, the ID is expected to be `rom`. +* for a SoC with two ROMs, the IDs would be expected to be `rom0` and `rom1`. ## Booting with and without ROM @@ -48,3 +69,7 @@ for the machine), it does not prevent the CPU from starting: - ROM Controller activates _fake digest_ mode: digest is computed on the empty ROM region and expected digest value is faked. ROM is "valid" so signal is sent to Power Manager to start the CPU. + +When the `-kernel` option is used, the default `resetvec` of the machine is overridden with the +entry point defined in the ELF file. The default `mtvec` is not modified - it is expected the ELF +early code updates the `mtvec` with a reachable location if no ROM is used. diff --git a/hw/opentitan/ot_rom_ctrl.c b/hw/opentitan/ot_rom_ctrl.c index 2455831780ca..cb85ee5d11ab 100644 --- a/hw/opentitan/ot_rom_ctrl.c +++ b/hw/opentitan/ot_rom_ctrl.c @@ -33,6 +33,7 @@ #include "qemu/bswap.h" #include "qemu/log.h" #include "qemu/timer.h" +#include "qapi/error.h" #include "elf.h" #include "hw/loader.h" #include "hw/opentitan/ot_alert.h" @@ -137,6 +138,92 @@ struct OtRomCtrlState { bool fake_digest; }; +static void ot_rom_ctrl_get_mem_bounds(OtRomCtrlState *s, hwaddr *minaddr, + hwaddr *maxaddr) +{ + *minaddr = s->mem.addr; + *maxaddr = s->mem.addr + (hwaddr)memory_region_size(&s->mem); +} + +static void ot_rom_ctrl_load_elf(OtRomCtrlState *s, const OtRomImg *ri) +{ + AddressSpace *as = ot_common_get_local_address_space(DEVICE(s)); + hwaddr minaddr; + hwaddr maxaddr; + ot_rom_ctrl_get_mem_bounds(s, &minaddr, &maxaddr); + uint64_t loaddr; + if (load_elf_ram_sym(ri->filename, NULL, NULL, NULL, NULL, &loaddr, NULL, + NULL, 0, EM_RISCV, 1, 0, as, false, NULL) <= 0) { + error_setg(&error_fatal, + "ot_rom_ctrl: %s: ROM image '%s', ELF loading failed", + s->rom_id, ri->filename); + return; + } + if ((loaddr < minaddr) || (loaddr > maxaddr)) { + /* cannot test upper load address as QEMU loader returns VMA, not LMA */ + error_setg(&error_fatal, "ot_rom_ctrl: %s: ELF cannot fit into ROM\n", + s->rom_id); + } +} + +static void ot_rom_ctrl_load_binary(OtRomCtrlState *s, const OtRomImg *ri) +{ + hwaddr minaddr; + hwaddr maxaddr; + ot_rom_ctrl_get_mem_bounds(s, &minaddr, &maxaddr); + + hwaddr binaddr = (hwaddr)ri->address; + + if (binaddr < minaddr) { + error_setg(&error_fatal, "ot_rom_ctrl: %s: address 0x%x: not in ROM:\n", + s->rom_id, ri->address); + } + + int fd = open(ri->filename, O_RDONLY | O_BINARY | O_CLOEXEC); + if (fd == -1) { + error_setg(&error_fatal, + "ot_rom_ctrl: %s: could not open ROM '%s': %s\n", + ri->filename, s->rom_id, strerror(errno)); + } + + ssize_t binsize = (ssize_t)lseek(fd, 0, SEEK_END); + if (binsize == -1) { + close(fd); + error_setg(&error_fatal, + "ot_rom_ctrl: %s: file %s: get size error: %s\n", s->rom_id, + ri->filename, strerror(errno)); + } + + if (binaddr + binsize > maxaddr) { + close(fd); + error_setg(&error_fatal, "ot_rom_ctrl: cannot fit into ROM\n"); + } + + uint8_t *data = g_malloc0(binsize); + lseek(fd, 0, SEEK_SET); + + ssize_t rc = read(fd, data, binsize); + close(fd); + if (rc != binsize) { + g_free(data); + error_setg( + &error_fatal, + "ot_rom_ctrl: %s: file %s: read error: rc=%zd (expected %zd)\n", + s->rom_id, ri->filename, rc, binsize); + return; /* static analyzer does not know error_fatal never returns */ + } + + hwaddr offset = binaddr - minaddr; + + uintptr_t hostptr = (uintptr_t)memory_region_get_ram_ptr(&s->mem); + hostptr += offset; + memcpy((void *)hostptr, data, binsize); + g_free(data); + + memory_region_set_dirty(&s->mem, offset, binsize); +} + + static void ot_rom_ctrl_load_rom(OtRomCtrlState *s) { Object *obj = NULL; @@ -152,17 +239,15 @@ static void ot_rom_ctrl_load_rom(OtRomCtrlState *s) } rom_img = (OtRomImg *)object_dynamic_cast(obj, TYPE_OT_ROM_IMG); if (!rom_img) { - warn_report("ot_rom_ctrl: Object with id '%s' is not a ROM Image", - s->rom_id); + error_setg(&error_fatal, "ot_rom_ctrl: %s: Object is not a ROM Image", + s->rom_id); return; } - AddressSpace *as = ot_common_get_local_address_space(DEVICE(s)); - if (load_elf_ram_sym(rom_img->filename, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, 0, EM_RISCV, 1, 0, as, false, NULL) <= 0) { - warn_report("ot_rom_ctrl: ROM image '%s', ELF loading failed", - s->rom_id); - return; + if (rom_img->address == UINT32_MAX) { + ot_rom_ctrl_load_elf(s, rom_img); + } else { + ot_rom_ctrl_load_binary(s, rom_img); } /* check if fake digest is requested */ @@ -187,10 +272,12 @@ static void ot_rom_ctrl_compare_and_notify(OtRomCtrlState *s) for (unsigned ix = 0; ix < ROM_DIGEST_WORDS; ix++) { if (s->regs[R_EXP_DIGEST_0 + ix] != s->regs[R_DIGEST_0 + ix]) { rom_good = false; - warn_report("ot_rom_ctrl: DIGEST_%u mismatch (expected 0x%08x got " - "0x%08x)", - ix, s->regs[R_EXP_DIGEST_0 + ix], - s->regs[R_DIGEST_0 + ix]); + error_setg( + &error_fatal, + "ot_rom_ctrl: %s: DIGEST_%u mismatch (expected 0x%08x got " + "0x%08x)", + s->rom_id, ix, s->regs[R_EXP_DIGEST_0 + ix], + s->regs[R_DIGEST_0 + ix]); } } @@ -427,8 +514,8 @@ static void ot_rom_ctrl_mem_write(void *opaque, hwaddr addr, uint64_t value, stn_le_p(&rom_ptr[addr], (int)size, value); } else { qemu_log_mask(LOG_GUEST_ERROR, - "%s: Bad offset 0x%" HWADDR_PRIx ", pc=0x%x\n", __func__, - addr, (unsigned)pc); + "%s: %s: Bad offset 0x%" HWADDR_PRIx ", pc=0x%x\n", + __func__, s->rom_id, addr, (unsigned)pc); } } diff --git a/hw/opentitan/ot_rom_ctrl_img.c b/hw/opentitan/ot_rom_ctrl_img.c index 943d7e73d587..a5687d574e5a 100644 --- a/hw/opentitan/ot_rom_ctrl_img.c +++ b/hw/opentitan/ot_rom_ctrl_img.c @@ -33,6 +33,8 @@ #include "qapi/error.h" #include "qom/object_interfaces.h" #include "hw/opentitan/ot_rom_ctrl_img.h" +#include "hw/qdev-properties-system.h" +#include "hw/qdev-properties.h" /* Current ROMs digests are 256 bits (32 bytes) */ #define ROM_DIGEST_BYTES (32u) @@ -45,6 +47,7 @@ static void ot_rom_img_reset(OtRomImg *ri) ri->digest = NULL; ri->digest_len = 0; ri->fake_digest = false; + ri->address = UINT32_MAX; } static void ot_rom_img_prop_set_file(Object *obj, const char *value, @@ -126,9 +129,35 @@ static char *ot_rom_img_prop_get_digest(Object *obj, Error **errp) return digest; } +static void ot_rom_img_prop_get_addr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + OtRomImg *ri = OT_ROM_IMG(obj); + (void)opaque; + + uint32_t address = ri->address; + + visit_type_uint32(v, name, &address, errp); +} + +static void ot_rom_img_prop_set_addr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + OtRomImg *ri = OT_ROM_IMG(obj); + (void)opaque; + uint32_t address; + + if (!visit_type_uint32(v, name, &address, errp)) { + return; + } + + ri->address = address; +} + static void ot_rom_img_instance_init(Object *obj) { OtRomImg *ri = OT_ROM_IMG(obj); + ot_rom_img_reset(ri); } @@ -164,10 +193,12 @@ static void ot_rom_img_class_init(ObjectClass *oc, void *data) ucc->complete = &ot_rom_img_complete; - object_class_property_add_str(oc, "file", ot_rom_img_prop_get_file, - ot_rom_img_prop_set_file); - object_class_property_add_str(oc, "digest", ot_rom_img_prop_get_digest, - ot_rom_img_prop_set_digest); + object_class_property_add_str(oc, "file", &ot_rom_img_prop_get_file, + &ot_rom_img_prop_set_file); + object_class_property_add_str(oc, "digest", &ot_rom_img_prop_get_digest, + &ot_rom_img_prop_set_digest); + object_class_property_add(oc, "addr", "uint32", &ot_rom_img_prop_get_addr, + &ot_rom_img_prop_set_addr, NULL, NULL); } static const TypeInfo ot_rom_img_info = { diff --git a/include/hw/opentitan/ot_rom_ctrl_img.h b/include/hw/opentitan/ot_rom_ctrl_img.h index 89776cea4a8f..f9d9cb9b6af7 100644 --- a/include/hw/opentitan/ot_rom_ctrl_img.h +++ b/include/hw/opentitan/ot_rom_ctrl_img.h @@ -39,6 +39,7 @@ struct OtRomImg { char *filename; uint8_t *digest; unsigned digest_len; + uint32_t address; bool fake_digest; }; diff --git a/qapi/qom.json b/qapi/qom.json index 1e289cc99e84..3fdaf7f41994 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -873,7 +873,8 @@ ## { 'struct': 'OtRomImgProperties', 'data': { 'file': 'str', - 'digest': 'str' } } + 'digest': 'str', + '*addr': 'uint32' } } ## # @ObjectType: From 6d84a7a6d57a8dd6ada44e608b1cf12da3224c08 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 10 Oct 2023 11:08:26 +0200 Subject: [PATCH 08/15] [ot] scripts/opentitan: pyot.py execute QEMU from build directory. macos 14 + meson fail to load dynlibs from alternative paths, since meson has introduced "reproducible" builds. Signed-off-by: Emmanuel Blot --- scripts/opentitan/pyot.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/scripts/opentitan/pyot.py b/scripts/opentitan/pyot.py index ea2b2e1a9cf2..90abc4b068a3 100755 --- a/scripts/opentitan/pyot.py +++ b/scripts/opentitan/pyot.py @@ -20,8 +20,8 @@ from json import load as jload from logging import (Formatter, StreamHandler, CRITICAL, DEBUG, INFO, ERROR, WARNING, getLogger) -from os import close, curdir, environ, isatty, linesep, pardir, sep, unlink -from os.path import (basename, dirname, isdir, isfile, join as joinpath, +from os import close, curdir, environ, getcwd, isatty, linesep, sep, unlink +from os.path import (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 @@ -163,10 +163,12 @@ def run(self, qemu_args: List[str], timeout: int, name: str, last_guest_error = '' #pylint: disable=too-many-nested-blocks try: + workdir = dirname(qemu_args[0]) log.info('Executing QEMU as %s', ' '.join(qemu_args)) #pylint: disable=consider-using-with - proc = Popen(qemu_args, bufsize=1, stdout=PIPE, stderr=PIPE, - encoding='utf-8', errors='ignore', text=True) + proc = Popen(qemu_args, bufsize=1, cwd=workdir, stdout=PIPE, + stderr=PIPE, encoding='utf-8', errors='ignore', + text=True) try: # ensure that QEMU starts and give some time for it to set up # its VCP before attempting to connect to it @@ -950,6 +952,13 @@ def flatten(lst: List) -> List: """ return [item for sublist in lst for item in sublist] + @staticmethod + def abspath(path: str) -> str: + """Build absolute path""" + if isabs(path): + return path + return normpath(joinpath(getcwd(), path)) + def _cleanup_temp_files(self, storage: Dict[str, Set[str]]) -> None: if self._qfm.keep_temporary: return @@ -981,8 +990,9 @@ def _build_qemu_command(self, args: Namespace, 'none' ] if args.rom: + rom_path = self.abspath(args.rom) qemu_args.extend(('-object', - f'ot-rom-img,id=rom,file={args.rom},digest=fake')) + f'ot-rom-img,id=rom,file={rom_path},digest=fake')) else: if all((args.exec, args.boot)): raise ValueError('Cannot use both a ROM ext/app and a ' @@ -1004,15 +1014,17 @@ def _build_qemu_command(self, args: Namespace, qemu_args.extend(('-drive', f'if=pflash,file={otp_file},format=raw')) elif args.otp_raw: + otp_raw_path = self.abspath(args.otp_raw) qemu_args.extend(('-drive', - f'if=pflash,file={args.otp_raw},format=raw')) + f'if=pflash,file={otp_raw_path},format=raw')) if args.flash: 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') - qemu_args.extend(('-drive', f'if=mtd,bus=1,file={args.flash},' + flash_path = self.abspath(args.flash) + qemu_args.extend(('-drive', f'if=mtd,bus=1,file={flash_path},' f'format=raw')) elif any((args.exec, args.boot)): if args.exec and not isfile(args.exec): @@ -1025,11 +1037,12 @@ def _build_qemu_command(self, args: Namespace, qemu_args.extend(('-drive', f'if=mtd,bus=1,file={flash_file},' f'format=raw')) if args.log_file: - qemu_args.extend(('-D', args.log_file)) + qemu_args.extend(('-D', self.abspath(args.log_file))) if args.trace: # use a FileType to let argparser validate presence and type args.trace.close() - qemu_args.extend(('-trace', f'events={args.trace.name}')) + qemu_args.extend(('-trace', + f'events={self.abspath(args.trace.name)}')) if args.log: qemu_args.append('-d') qemu_args.append(','.join(args.log)) From 8c7c9381fc4deee03e4196b944002f289578c787 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 10 Oct 2023 11:24:00 +0200 Subject: [PATCH 09/15] [ot] scripts/opentitan: pyot.py add an option to mux serial socket. This is required if several virtual UART are configured to use the same host port. Signed-off-by: Emmanuel Blot --- docs/opentitan/pyot.md | 3 +++ scripts/opentitan/pyot.py | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/opentitan/pyot.md b/docs/opentitan/pyot.md index d92cf6e20690..919c7ac5ab34 100644 --- a/docs/opentitan/pyot.md +++ b/docs/opentitan/pyot.md @@ -39,6 +39,7 @@ Virtual machine: trace event definition file -i N, --icount N virtual instruction counter with 2^N clock ticks per inst. -s, --singlestep enable "single stepping" QEMU execution mode + -U, --muxserial enable multiple virtual UARTs to be muxed into same host output channel Files: -r ELF, --rom ELF ROM ELF file @@ -102,6 +103,8 @@ This tool may be used in two ways, which can be combined: matches the expected FPGA-based lowRISC CPU. Note that this option slows down the execution of guest applications. * `-s` / `--singlestep` enable QEMU "single stepping" mode. +* `-U` / `--muxserial` enable muxing QEMU VCP. This option is required when several virtual UARTs + are routed to the same host output channel. ### File options: diff --git a/scripts/opentitan/pyot.py b/scripts/opentitan/pyot.py index 90abc4b068a3..65c4799d63b6 100755 --- a/scripts/opentitan/pyot.py +++ b/scripts/opentitan/pyot.py @@ -1051,6 +1051,7 @@ def _build_qemu_command(self, args: Namespace, if 'icount' in args: if args.icount is not None: qemu_args.extend(('-icount', f'{args.icount}')) + mux = f'mux={"on" if args.muxserial else "off"}' device = args.device devdesc = device.split(':') try: @@ -1060,7 +1061,7 @@ def _build_qemu_command(self, args: Namespace, tcpdev = (devdesc[0], port) qemu_args.extend(('-chardev', f'socket,id=serial0,host={devdesc[0]},' - f'port={port},server=on,wait=on')) + f'port={port},{mux},server=on,wait=on')) qemu_args.extend(('-serial', 'chardev:serial0')) except TypeError as exc: raise ValueError('Invalid TCP serial device') from exc @@ -1260,8 +1261,12 @@ def main(): help='virtual instruction counter with 2^N clock ticks' ' per inst.') qvm.add_argument('-s', '--singlestep', action='store_true', - default=False, + default=None, help='enable "single stepping" QEMU execution mode') + qvm.add_argument('-U', '--muxserial', action='store_true', + default=None, + help='enable multiple virtual UARTs to be muxed into ' + 'same host output channel') files = argparser.add_argument_group(title='Files') files.add_argument('-r', '--rom', metavar='ELF', help='ROM file') files.add_argument('-O', '--otp-raw', metavar='RAW', @@ -1314,10 +1319,16 @@ def main(): if not isinstance(aliases, dict): argparser.error('Invalid aliases definitions') qfm.define(aliases) - defaults = json.get('default', {}) + jdefaults = json.get('default', {}) jargs = [] - for arg, val in defaults.items(): + for arg, val in jdefaults.items(): + is_bool = isinstance(val, bool) + if is_bool: + if not val: + continue jargs.append(f'--{arg}' if len(arg) > 1 else f'-{arg}') + if is_bool: + continue # arg parser expects only string args, and substitute shell env. val = qfm.interpolate(val) jargs.append(val) From d841451deba17920e5bdf303c15ba246e07e9ed6 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 10 Oct 2023 15:03:14 +0200 Subject: [PATCH 10/15] [ot] scripts/opentitan: pyot.py add a section for sub command env. vars. Also define `QEMU_SRC_DIR` and `QEMU_BIN_DIR` special aliases. Signed-off-by: Emmanuel Blot --- docs/opentitan/pyot.md | 27 +++++++++++++++-- scripts/opentitan/pyot.py | 63 ++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/docs/opentitan/pyot.md b/docs/opentitan/pyot.md index 919c7ac5ab34..55c17e116bbf 100644 --- a/docs/opentitan/pyot.md +++ b/docs/opentitan/pyot.md @@ -327,6 +327,23 @@ Sample config for running some non-OpenTitan tests: { timeout: 6 } + mbxhost-test: + { + env: + { + PYTHONPATH: ${QEMU_SRC_DIR}/scripts/opentitan + } + opts: + [ + -chardev socket,id=devproxy,host=localhost,port=8003,server=on,wait=off + -global ot-dev_proxy.chardev=devproxy + ] + with: + [ + ${BASEDIR}/tools/mbxhost_test.py -vv -I 3 -P 3 -t + ] + timeout: 20 + } spihost-test: { # This test needs a specific SPI flash image @@ -375,9 +392,11 @@ Sample config for running some non-OpenTitan tests: Note that the resulting aliases are always uppercased. To use an alias, use the `${ALIAS}` syntax. Environment variables may also be used as aliases. - Two special variables are automatically defined: + Several special variables are automatically defined: * `${CONFIG}` refers to the path of the configuration file itself, * `${TESTDIR}` refers to the default test path (see `testdir` below). + * `${QEMU_SRC_DIR}` refers to the path to the QEMU source directory + * `${QEMU_BIN_DIR}` refers to the directory than contains the QEMU executable. * `testdir` This section may be used to define the default path where to look for tests to run. @@ -441,8 +460,7 @@ Sample config for running some non-OpenTitan tests: ### Special test sections -Each test section may have up to three special subsections that may be used to execute arbitrary -commands: +Each test section may have special subsections that may be used to execute arbitrary commands: * `pre` subsection contains commands to execute before QEMU is executed. @@ -458,6 +476,9 @@ commands: * This section may be useful to perform some cleanup or post processing analysis once the QEMU session is over +It is also possible to define an `env` section to define special environment variables that would be +required by the commands defined in the previous subsections. + Regular or 'synchronous' commands are only executed if all the previous commands have been successful. Moreover, commands in the `post` subsection are only executed if the QEMU session has completed successfully. diff --git a/scripts/opentitan/pyot.py b/scripts/opentitan/pyot.py index 65c4799d63b6..366c41628cb4 100755 --- a/scripts/opentitan/pyot.py +++ b/scripts/opentitan/pyot.py @@ -368,6 +368,20 @@ def keep_temporary(self) -> bool: """ return self._keep_temp + def set_qemu_src_dir(self, path: str) -> None: + """Set the QEMU "source" directory. + + :param path: the path to the QEMU source directory + """ + self._env['QEMU_SRC_DIR'] = normpath(path) + + def set_qemu_bin_dir(self, path: str) -> None: + """Set the QEMU executable directory. + + :param path: the path to the QEMU binary directory + """ + self._env['QEMU_BIN_DIR'] = normpath(path) + def set_config_dir(self, path: str) -> None: """Assign the configuration directory. @@ -657,9 +671,10 @@ def _run(self): while self._log_q: err, qline = self._log_q.popleft() if err: - if qline.find('info: ') > 0: + if qline.find('info: ') > 0 or qline.find(' INFO ') > 0: self._log.info(qline) - elif qline.find('warning: ') > 0: + elif qline.find('warning: ') > 0 \ + or qline.find(' WARNING ') > 0: self._log.warning(qline) else: self._log.error(qline) @@ -711,12 +726,15 @@ class QEMUContext: """ def __init__(self, test_name: str, qfm: QEMUFileManager, - qemu_cmd: List[str], context: Dict[str, List[str]]): + qemu_cmd: List[str], context: Dict[str, List[str]], + env: Optional[Dict[str, str]] = None): + #pylint: disable=too-many-arguments self._clog = getLogger('pyot.ctx') self._test_name = test_name self._qfm = qfm self._qemu_cmd = qemu_cmd self._context = context + self._env = env or {} self._workers: List[Popen] = [] def execute(self, ctx_name: str, code: int = 0) -> None: @@ -735,19 +753,20 @@ def execute(self, ctx_name: str, code: int = 0) -> None: #pylint: disable=too-many-nested-blocks ctx = self._context.get(ctx_name, None) if ctx_name == 'post' and code: - self._clog.info('Discard execution of "%s" commands after failure ' - 'of "%s"', ctx_name, self._test_name) + self._clog.info("Discard execution of '%s' commands after failure " + "of '%s'", ctx_name, self._test_name) return env = dict(environ) + env.update(self._env) if self._qemu_cmd: env['PATH'] = ':'.join((env['PATH'], dirname(self._qemu_cmd[0]))) if ctx: for cmd in ctx: if cmd.endswith('&'): if ctx_name == 'post': - raise ValueError(f'Cannot execute background command ' - f'in {ctx_name} context for ' - f'"{self._test_name}"') + raise ValueError(f"Cannot execute background command " + f"in [{ctx_name}] context for " + f"'{self._test_name}'") cmd = cmd[:-1].rstrip() self._clog.debug('Execute "%s" in backgrorund for [%s] ' 'context', cmd, ctx_name) @@ -776,9 +795,9 @@ def execute(self, ctx_name: str, code: int = 0) -> None: if line: logger(line) if fail: - self._log.error('Fail to execute "%s" command for "%s"', - cmd, self._test_name) - raise ValueError(f'Cannot execute {ctx_name} command') + self._clog.error("Fail to execute '%s' command for " + "'%s'", cmd, self._test_name) + raise ValueError(f"Cannot execute [{ctx_name}] command") if ctx_name == 'post': self._qfm.delete_default_dir(self._test_name) @@ -787,11 +806,11 @@ def check_error(self) -> bool: :return: True if any worker has failed """ - for w in self._workers: - ret = w.exit_code() + for worker in self._workers: + ret = worker.exit_code() if not ret: continue - self._clog.error("%s exited with %d", w.command, ret) + self._clog.error("%s exited with %d", worker.command, ret) return True return False @@ -979,6 +998,7 @@ def _build_qemu_command(self, args: Namespace, a dictionary of generated temporary files """ #pylint: disable=too-many-branches + #pylint: disable=too-many-locals #pylint: disable=too-many-statements if args.qemu is None: raise ValueError('QEMU path is not defined') @@ -1187,6 +1207,7 @@ def _build_test_context(self, test_name: str) -> QEMUContext: context = defaultdict(list) tests_cfg = self._config.get('tests', {}) test_cfg = tests_cfg.get(test_name, {}) + test_env = None if test_cfg: for ctx_name in ('pre', 'with', 'post'): if ctx_name not in test_cfg: @@ -1202,7 +1223,13 @@ def _build_test_context(self, test_name: str) -> QEMUContext: cmd = self._qfm.interpolate(cmd.strip()) cmd = self._qfm.interpolate_dirs(cmd, test_name) context[ctx_name].append(cmd) - return QEMUContext(test_name, self._qfm, self._qemu_cmd, dict(context)) + env = test_cfg.get('env') + if env: + if not isinstance(env, dict): + raise ValueError('Invalid context environment') + test_env = {k: self._qfm.interpolate(v) for k, v in env.items()} + return QEMUContext(test_name, self._qfm, self._qemu_cmd, dict(context), + test_env) def main(): @@ -1212,8 +1239,8 @@ def main(): #pylint: disable=too-many-statements #pylint: disable=too-many-nested-blocks debug = True - qemu_path = normpath(joinpath(dirname(dirname(dirname(__file__))), - 'build', 'qemu-system-riscv32')) + qemu_dir = normpath(joinpath(dirname(dirname(dirname(__file__))))) + qemu_path = normpath(joinpath(qemu_dir, 'build', 'qemu-system-riscv32')) if not isfile(qemu_path): qemu_path = None try: @@ -1354,6 +1381,8 @@ def main(): for name, val in defaults.items(): if getattr(args, name) is None: setattr(args, name, val) + qfm.set_qemu_src_dir(qemu_dir) + qfm.set_qemu_bin_dir(dirname(args.qemu)) qexc = QEMUExecuter(qfm, json, args) try: qexc.build() From 524688dd4853f94ccbde9b51a224de3a5b9304c2 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Tue, 3 Oct 2023 15:37:32 +0200 Subject: [PATCH 11/15] [ot] hw/riscv: ibex_common: add helper functions to combine Ibex SoCs Signed-off-by: Emmanuel Blot --- hw/riscv/ibex_common.c | 120 +++++++++++++++++++++++++++++++++ include/hw/riscv/ibex_common.h | 38 ++++++++++- 2 files changed, 157 insertions(+), 1 deletion(-) diff --git a/hw/riscv/ibex_common.c b/hw/riscv/ibex_common.c index 6cced7e132b6..6b2741f5205e 100644 --- a/hw/riscv/ibex_common.c +++ b/hw/riscv/ibex_common.c @@ -23,6 +23,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qemu/log.h" +#include "qom/object.h" #include "cpu.h" #include "disas/disas.h" #include "elf.h" @@ -227,6 +228,42 @@ void ibex_map_devices_mask(DeviceState **devices, MemoryRegion **mrs, } } +void ibex_map_devices_ext_mask(DeviceState *dev, MemoryRegion **mrs, + const IbexDeviceMapDef *defs, unsigned count, + uint32_t region_mask) +{ + for (unsigned ix = 0; ix < count; ix++) { + const IbexDeviceMapDef *def = &defs[ix]; + g_assert(def->type); + g_assert(def->memmap); + + char *name = g_strdup_printf("%s[%u]", def->type, def->instance); + Object *child; + child = object_property_get_link(OBJECT(dev), name, &error_fatal); + SysBusDevice *sdev; + sdev = OBJECT_CHECK(SysBusDevice, child, TYPE_SYS_BUS_DEVICE); + g_free(name); + + const MemMapEntry *memmap = def->memmap; + unsigned mem = 0; + while (memmap->size) { + if (!SKIP_MEMMAP(memmap)) { + unsigned region = IBEX_MEMMAP_GET_REGIDX(memmap->base); + if (region_mask & (1u << region)) { + MemoryRegion *mr = mrs[region]; + if (mr) { + ibex_mmio_map_device(sdev, mr, mem, + IBEX_MEMMAP_GET_ADDRESS( + memmap->base)); + } + } + } + mem++; + memmap++; + } + } +} + void ibex_connect_devices(DeviceState **devices, const IbexDeviceDef *defs, unsigned count) { @@ -375,6 +412,47 @@ void ibex_export_gpios(DeviceState **devices, DeviceState *parent, } } +void ibex_connect_soc_devices(DeviceState **soc_devices, DeviceState **devices, + const IbexDeviceDef *defs, unsigned count) +{ + for (unsigned ix = 0; ix < count; ix++) { + DeviceState *dev = devices[ix]; + if (!dev) { + continue; + } + const IbexDeviceDef *def = &defs[ix]; + if (!def->type || !def->gpio) { + continue; + } + + const IbexGpioConnDef *conn = def->gpio; + while (conn->out.num >= 0 && conn->in.num >= 0) { + if (conn->in.index < 0) { + unsigned grp = IBEX_GPIO_GET_GRP(conn->in.num); + if (!(grp < count)) { + g_assert_not_reached(); + } + DeviceState *socdev = soc_devices[grp]; + unsigned in_ix = IBEX_GPIO_GET_IDX(conn->in.num); + qemu_irq in_gpio = + qdev_get_gpio_in_named(socdev, conn->in.name, in_ix); + if (!in_gpio) { + error_setg( + &error_fatal, + "%s: cannot connect %s.%s.%u, no such IRQ '%s.%s.%u'\n", + __func__, object_get_typename(OBJECT(dev)), + conn->out.name, conn->out.num, + object_get_typename(OBJECT(socdev)), conn->in.name, + in_ix); + } + qdev_connect_gpio_out_named(dev, conn->out.name, conn->out.num, + in_gpio); + } + conn++; + } + } +} + void ibex_configure_devices(DeviceState **devices, BusState *bus, const IbexDeviceDef *defs, unsigned count) { @@ -384,6 +462,48 @@ void ibex_configure_devices(DeviceState **devices, BusState *bus, ibex_connect_devices(devices, defs, count); } +typedef struct { + Object *child; + const char *typename; + unsigned instance; +} IbexChildMatch; + +static int ibex_match_device(Object *child, void *opaque) +{ + IbexChildMatch *match = opaque; + + if (!object_dynamic_cast(child, match->typename)) { + return 0; + } + if (match->instance) { + match->instance -= 1; + return 0; + } + + match->child = child; + return 1; +} + +DeviceState *ibex_get_child_device(DeviceState *s, const char *typename, + unsigned instance) +{ + IbexChildMatch match = { + .child = NULL, + .typename = typename, + .instance = instance, + }; + + if (!object_child_foreach(OBJECT(s), &ibex_match_device, &match)) { + return NULL; + } + + if (!object_dynamic_cast(match.child, TYPE_DEVICE)) { + return NULL; + } + + return DEVICE(match.child); +} + void ibex_unimp_configure(DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent) { diff --git a/include/hw/riscv/ibex_common.h b/include/hw/riscv/ibex_common.h index 79babb461e0a..ffe77b2a8a2a 100644 --- a/include/hw/riscv/ibex_common.h +++ b/include/hw/riscv/ibex_common.h @@ -139,6 +139,7 @@ typedef struct { }; } IbexDevicePropDef; +/* Device definition */ struct IbexDeviceDef { /** Registered type of the device */ const char *type; @@ -160,6 +161,16 @@ struct IbexDeviceDef { const IbexGpioExportDef *gpio_export; }; +/* Additional device mapping for external buses */ +typedef struct { + /** Registered type of the device */ + const char *type; + /** Instance number, default to 0 */ + int instance; + /** Array of memory map */ + const MemMapEntry *memmap; +} IbexDeviceMapDef; + /* * Special memory address marked to flag a special MemMapEntry. * Flagged MemMapEntry are used to select a memory region while mem mapping @@ -198,6 +209,13 @@ struct IbexDeviceDef { #define IBEX_DEVLINK_MAKE_RMTDEV(_par_, _ix_) \ (((_par_) << IBEX_DEVLINK_RMT_SHIFT) | ((_ix_)&IBEX_DEVLINK_IDX_MASK)) +/* MemMapEntry that should be ignored (i.e. skipped, not mapped) */ +#define MEMMAPSKIP \ + { \ + .base = HWADDR_MAX, .size = HWADDR_MAX \ + } +#define SKIP_MEMMAP(_mmap_) ((_mmap_)->size == HWADDR_MAX) + /** * Create memory map entries, each arg is MemMapEntry definition */ @@ -246,6 +264,18 @@ struct IbexDeviceDef { } \ } +/** + * Create device additional map entries, each arg is IbexDeviceMapDef definition + */ +#define IBEXDEVICEMAPDEFS(...) \ + (const IbexDeviceMapDef[]) \ + { \ + __VA_ARGS__, \ + { \ + .type = NULL \ + } \ + } + /** * Create device gpio export property entries, each arg is IbexGpioExportDef * definition @@ -369,11 +399,17 @@ void ibex_connect_devices(DeviceState **devices, const IbexDeviceDef *defs, void ibex_map_devices_mask(DeviceState **devices, MemoryRegion **mrs, const IbexDeviceDef *defs, unsigned count, uint32_t region_mask); +void ibex_map_devices_ext_mask(DeviceState *dev, MemoryRegion **mrs, + const IbexDeviceMapDef *defs, unsigned count, + uint32_t region_mask); void ibex_configure_devices(DeviceState **devices, BusState *bus, const IbexDeviceDef *defs, unsigned count); void ibex_export_gpios(DeviceState **devices, DeviceState *parent, const IbexDeviceDef *defs, unsigned count); - +void ibex_connect_soc_devices(DeviceState **soc_devices, DeviceState **devices, + const IbexDeviceDef *defs, unsigned count); +DeviceState *ibex_get_child_device(DeviceState *s, const char *typename, + unsigned instance); /** * Utility function to configure unimplemented device. * The Ibex device definition should have one defined memory entry, and an From 576e1c16c614c34726aedf329f0ada9fa35a996e Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 9 Oct 2023 18:56:52 +0200 Subject: [PATCH 12/15] [ot] hw/opentitan: introduce abstraction for random source Signed-off-by: Emmanuel Blot --- hw/opentitan/Kconfig | 4 ++ hw/opentitan/meson.build | 1 + hw/opentitan/ot_csrng.c | 70 ++++++++++++--------- hw/opentitan/ot_entropy_src.c | 39 ++++++++---- hw/opentitan/ot_random_src.c | 42 +++++++++++++ hw/riscv/ot_earlgrey.c | 2 +- include/hw/opentitan/ot_entropy_src.h | 41 ------------- include/hw/opentitan/ot_random_src.h | 87 +++++++++++++++++++++++++++ 8 files changed, 203 insertions(+), 83 deletions(-) create mode 100644 hw/opentitan/ot_random_src.c create mode 100644 include/hw/opentitan/ot_random_src.h diff --git a/hw/opentitan/Kconfig b/hw/opentitan/Kconfig index ac99d48e3d2c..8cab24644da9 100644 --- a/hw/opentitan/Kconfig +++ b/hw/opentitan/Kconfig @@ -30,6 +30,7 @@ config OT_EDN bool config OT_ENTROPY_SRC + select OT_RANDOM_SRC bool config OT_FLASH @@ -74,6 +75,9 @@ config OT_PRNG config OT_PWRMGR bool +config OT_RANDOM_SRC + bool + config OT_ROM_CTRL bool select OT_COMMON diff --git a/hw/opentitan/meson.build b/hw/opentitan/meson.build index 5211b43d9b1b..69f0005b1c4c 100644 --- a/hw/opentitan/meson.build +++ b/hw/opentitan/meson.build @@ -27,6 +27,7 @@ softmmu_ss.add(when: 'CONFIG_OT_OTP_EARLGREY', if_true: files('ot_otp_earlgrey.c softmmu_ss.add(when: 'CONFIG_OT_PINMUX', if_true: files('ot_pinmux.c')) softmmu_ss.add(when: 'CONFIG_OT_PRNG', if_true: files('ot_prng.c')) softmmu_ss.add(when: 'CONFIG_OT_PWRMGR', if_true: files('ot_pwrmgr.c')) +softmmu_ss.add(when: 'CONFIG_OT_RANDOM_SRC', if_true: files('ot_random_src.c')) softmmu_ss.add(when: 'CONFIG_OT_ROM_CTRL', if_true: files('ot_rom_ctrl.c', 'ot_rom_ctrl_img.c')) softmmu_ss.add(when: 'CONFIG_OT_RSTMGR', if_true: files('ot_rstmgr.c')) softmmu_ss.add(when: 'CONFIG_OT_SENSOR', if_true: files('ot_sensor.c')) diff --git a/hw/opentitan/ot_csrng.c b/hw/opentitan/ot_csrng.c index 85ab511d68e4..abe031545eab 100644 --- a/hw/opentitan/ot_csrng.c +++ b/hw/opentitan/ot_csrng.c @@ -38,9 +38,9 @@ #include "hw/opentitan/ot_alert.h" #include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_csrng.h" -#include "hw/opentitan/ot_entropy_src.h" #include "hw/opentitan/ot_fifo32.h" #include "hw/opentitan/ot_otp.h" +#include "hw/opentitan/ot_random_src.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" #include "hw/registerfields.h" @@ -193,9 +193,9 @@ static const char *CMD_NAMES[] = { #define CMD_NAME(_cmd_) \ (((size_t)(_cmd_)) < ARRAY_SIZE(CMD_NAMES) ? CMD_NAMES[(_cmd_)] : "?") -static_assert(OT_CSRNG_PACKET_WORD_COUNT <= OT_ENTROPY_SRC_WORD_COUNT, +static_assert(OT_CSRNG_PACKET_WORD_COUNT <= OT_RANDOM_SRC_WORD_COUNT, "CSRNG packet cannot be larger than entropy_src packet"); -static_assert((OT_ENTROPY_SRC_WORD_COUNT % OT_CSRNG_PACKET_WORD_COUNT) == 0, +static_assert((OT_RANDOM_SRC_WORD_COUNT % OT_CSRNG_PACKET_WORD_COUNT) == 0, "CSRNG packet should be a multiple of entropy_src packet"); static_assert(OT_CSRNG_AES_BLOCK_SIZE + OT_CSRNG_AES_KEY_SIZE == OT_CSRNG_SEED_BYTE_COUNT, @@ -309,7 +309,7 @@ struct OtCSRNGState { OtCSRNGInstance *instances; OtCSRNGQueue cmd_requests; - OtEntropySrcState *entropy_src; + DeviceState *random_src; OtOTPState *otp_ctrl; }; @@ -363,8 +363,8 @@ static void ot_csrng_change_state_line(OtCSRNGState *s, OtCSRNGFsmState state, int line); static unsigned ot_csrng_get_slot(OtCSRNGInstance *inst); static bool ot_csrng_drng_is_instantiated(OtCSRNGInstance *inst); -static OtCSRNDCmdResult ot_csrng_drng_reseed( - OtCSRNGInstance *inst, OtEntropySrcState *entropy_src, bool flag0); +static OtCSRNDCmdResult +ot_csrng_drng_reseed(OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0); /* -------------------------------------------------------------------------- */ /* Public API */ @@ -537,7 +537,7 @@ static void ot_csrng_drng_increment(OtCSRNGDrng *drng) } static OtCSRNDCmdResult ot_csrng_drng_instanciate( - OtCSRNGInstance *inst, OtEntropySrcState *entropy_src, bool flag0) + OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) { OtCSRNGDrng *drng = &inst->drng; if (drng->instantiated) { @@ -558,7 +558,7 @@ static OtCSRNDCmdResult ot_csrng_drng_instanciate( memcpy(drng->key, key, OT_CSRNG_AES_KEY_SIZE); drng->instantiated = true; - res = ot_csrng_drng_reseed(inst, entropy_src, flag0); + res = ot_csrng_drng_reseed(inst, rand_dev, flag0); if (res) { drng->instantiated = false; } @@ -632,8 +632,8 @@ static int ot_csrng_drng_update(OtCSRNGInstance *inst) return 0; } -static OtCSRNDCmdResult ot_csrng_drng_reseed( - OtCSRNGInstance *inst, OtEntropySrcState *entropy_src, bool flag0) +static OtCSRNDCmdResult +ot_csrng_drng_reseed(OtCSRNGInstance *inst, DeviceState *rand_dev, bool flag0) { OtCSRNGDrng *drng = &inst->drng; g_assert(drng->instantiated); @@ -646,25 +646,27 @@ static OtCSRNDCmdResult ot_csrng_drng_reseed( return CSRNG_CMD_ERROR; } - uint64_t buffer[OT_ENTROPY_SRC_DWORD_COUNT]; + uint64_t buffer[OT_RANDOM_SRC_DWORD_COUNT]; memset(buffer, 0, sizeof(buffer)); unsigned len = drng->material_len * sizeof(uint32_t); memcpy(buffer, drng->material, MIN(len, sizeof(buffer))); OtCSRNGState *s = inst->parent; - uint64_t entropy[OT_ENTROPY_SRC_DWORD_COUNT]; + uint64_t entropy[OT_RANDOM_SRC_DWORD_COUNT]; int res; bool fips; xtrace_ot_csrng_info("request ES entropy w/ generation", s->entropy_gennum); - res = ot_entropy_src_get_random(entropy_src, s->entropy_gennum, entropy, - &fips); + + 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) { return res < 0 ? (res == -2 ? CSRNG_CMD_STALLED : CSRNG_CMD_ERROR) : CSRNG_CMD_RETRY; } /* always perform XOR which is a no-op if material_len is zero */ - for (unsigned ix = 0; ix < OT_ENTROPY_SRC_DWORD_COUNT; ix++) { + for (unsigned ix = 0; ix < OT_RANDOM_SRC_DWORD_COUNT; ix++) { buffer[ix] ^= entropy[ix]; } memcpy(drng->material, buffer, sizeof(entropy)); @@ -836,20 +838,31 @@ static void ot_csrng_handle_enable(OtCSRNGState *s) * 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); + if (ot_csrng_is_ctrl_enabled(s)) { xtrace_ot_csrng_info("enabling CSRNG", 0); - int gennum = ot_entropy_src_get_generation(s->entropy_src); + 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. */ - 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 ES generation", gennum); + if (gennum >= 0) { + 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); + } else { + 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); + } } if (ot_csrng_is_ctrl_disabled(s)) { @@ -875,8 +888,8 @@ static void ot_csrng_handle_enable(OtCSRNGState *s) } s->enabled = false; s->es_retry_count = 0; - s->entropy_gennum = ot_entropy_src_get_generation(s->entropy_src); - xtrace_ot_csrng_info("disable: last ES generation", s->entropy_gennum); + s->entropy_gennum = cls->get_random_generation(randif); + xtrace_ot_csrng_info("disable: last RS generation", s->entropy_gennum); /* cancel any outstanding asynchronous request */ timer_del(s->cmd_scheduler); @@ -1013,7 +1026,7 @@ ot_csrng_handle_instantiate(OtCSRNGState *s, unsigned slot) int res; - res = ot_csrng_drng_instanciate(inst, s->entropy_src, flag0); + res = ot_csrng_drng_instanciate(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; @@ -1110,7 +1123,7 @@ static OtCSRNDCmdResult ot_csrng_handle_reseed(OtCSRNGState *s, unsigned slot) } int res; - res = ot_csrng_drng_reseed(inst, s->entropy_src, flag0); + res = ot_csrng_drng_reseed(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; @@ -1735,8 +1748,8 @@ static void ot_csrng_regs_write(void *opaque, hwaddr addr, uint64_t val64, }; static Property ot_csrng_properties[] = { - DEFINE_PROP_LINK("entropy_src", OtCSRNGState, entropy_src, - TYPE_OT_ENTROPY_SRC, OtEntropySrcState *), + DEFINE_PROP_LINK("random_src", OtCSRNGState, random_src, TYPE_DEVICE, + DeviceState *), DEFINE_PROP_LINK("otp_ctrl", OtCSRNGState, otp_ctrl, TYPE_OT_OTP, OtOTPState *), DEFINE_PROP_END_OF_LIST(), @@ -1754,7 +1767,8 @@ static void ot_csrng_reset(DeviceState *dev) { OtCSRNGState *s = OT_CSRNG(dev); - g_assert(s->entropy_src); + g_assert(s->random_src); + OBJECT_CHECK(OtRandomSrcIf, s->random_src, TYPE_OT_RANDOM_SRC_IF); g_assert(s->otp_ctrl); timer_del(s->cmd_scheduler); diff --git a/hw/opentitan/ot_entropy_src.c b/hw/opentitan/ot_entropy_src.c index a90c67182a6a..804255da4567 100644 --- a/hw/opentitan/ot_entropy_src.c +++ b/hw/opentitan/ot_entropy_src.c @@ -43,6 +43,7 @@ #include "hw/opentitan/ot_entropy_src.h" #include "hw/opentitan/ot_fifo32.h" #include "hw/opentitan/ot_otp.h" +#include "hw/opentitan/ot_random_src.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" #include "hw/registerfields.h" @@ -323,11 +324,14 @@ static const char *REG_NAMES[REGS_COUNT] = { ((NANOSECONDS_PER_SECOND * ES_FILL_BITS) / \ ((uint64_t)OT_AST_RANDOM_4BIT_RATE * 4u)) #define OT_ENTROPY_SRC_FILL_WORD_COUNT (ES_FILL_BITS / (8u * sizeof(uint32_t))) -#define ES_WORD_COUNT (OT_ENTROPY_SRC_WORD_COUNT) +#define ES_WORD_COUNT (OT_RANDOM_SRC_WORD_COUNT) #define ES_SWREAD_FIFO_WORD_COUNT ES_WORD_COUNT #define ES_FINAL_FIFO_WORD_COUNT (ES_WORD_COUNT * ES_FINAL_FIFO_DEPTH) #define ES_HEXBUF_SIZE ((8U * 2u + 1u) * ES_WORD_COUNT + 4u) +/* see hw/ip/edn/doc/#multiple-edns-in-boot-time-request-mode */ +#define OT_ENTROPY_SRC_BOOT_DELAY_NS 2000000u /* 2 ms */ + enum { ALERT_RECOVERABLE, ALERT_FATAL, @@ -453,19 +457,19 @@ static void ot_entropy_src_reset(DeviceState *dev); static void ot_entropy_src_update_alerts(OtEntropySrcState *s); static void ot_entropy_src_update_filler(OtEntropySrcState *s); -/* -------------------------------------------------------------------------- */ -/* Public API */ -/* -------------------------------------------------------------------------- */ - -int ot_entropy_src_get_generation(OtEntropySrcState *s) +static int ot_entropy_src_get_generation(OtRandomSrcIf *dev) { + OtEntropySrcState *s = OT_ENTROPY_SRC(dev); + return ot_entropy_src_is_module_enabled(s) ? (int)s->gennum : 0; } -int ot_entropy_src_get_random(OtEntropySrcState *s, int genid, - uint64_t random[OT_ENTROPY_SRC_DWORD_COUNT], - bool *fips) +static int ot_entropy_src_get_random(OtRandomSrcIf *dev, int genid, + uint64_t random[OT_RANDOM_SRC_DWORD_COUNT], + bool *fips) { + OtEntropySrcState *s = OT_ENTROPY_SRC(dev); + if (!ot_entropy_src_is_module_enabled(s)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: entropy_src is down\n", __func__); return -2; @@ -838,19 +842,19 @@ static bool ot_entropy_src_can_hash(OtEntropySrcState *s) static void ot_entropy_src_perform_hash(OtEntropySrcState *s) { - uint32_t hash[OT_ENTROPY_SRC_WORD_COUNT]; + uint32_t hash[OT_RANDOM_SRC_WORD_COUNT]; int res; res = sha3_done(&s->sha3_state, (uint8_t *)hash); g_assert(res == CRYPT_OK); s->cond_word = 0; xtrace_ot_entropy_src_show_buffer("sha3 md", hash, - OT_ENTROPY_SRC_WORD_COUNT * + OT_RANDOM_SRC_WORD_COUNT * sizeof(uint32_t)); ot_entropy_src_change_state(s, ENTROPY_SRC_SHA3_MSGDONE); - for (unsigned ix = 0; ix < OT_ENTROPY_SRC_WORD_COUNT; ix++) { + for (unsigned ix = 0; ix < OT_RANDOM_SRC_WORD_COUNT; ix++) { g_assert(!ot_fifo32_is_full(&s->final_fifo)); ot_fifo32_push(&s->final_fifo, hash[ix]); } @@ -881,7 +885,7 @@ ot_entropy_src_push_bypass_entropy(OtEntropySrcState *s, uint32_t word) s->packet_count += 1u; trace_ot_entropy_src_push_bypass_entropy( - ot_fifo32_num_used(&s->final_fifo) / OT_ENTROPY_SRC_WORD_COUNT); + ot_fifo32_num_used(&s->final_fifo) / OT_RANDOM_SRC_WORD_COUNT); return true; } @@ -1626,6 +1630,10 @@ static void ot_entropy_src_class_init(ObjectClass *klass, void *data) dc->reset = &ot_entropy_src_reset; device_class_set_props(dc, ot_entropy_src_properties); set_bit(DEVICE_CATEGORY_MISC, dc->categories); + + OtRandomSrcIfClass *rdc = OT_RANDOM_SRC_IF_CLASS(klass); + rdc->get_random_generation = &ot_entropy_src_get_generation; + rdc->get_random_values = &ot_entropy_src_get_random; } static const TypeInfo ot_entropy_src_info = { @@ -1634,6 +1642,11 @@ static const TypeInfo ot_entropy_src_info = { .instance_size = sizeof(OtEntropySrcState), .instance_init = &ot_entropy_src_init, .class_init = &ot_entropy_src_class_init, + .interfaces = + (InterfaceInfo[]){ + { TYPE_OT_RANDOM_SRC_IF }, + {}, + }, }; static void ot_entropy_src_register_types(void) diff --git a/hw/opentitan/ot_random_src.c b/hw/opentitan/ot_random_src.c new file mode 100644 index 000000000000..276b767cd39b --- /dev/null +++ b/hw/opentitan/ot_random_src.c @@ -0,0 +1,42 @@ +/* + * QEMU OpenTitan Random Source interface + * + * Copyright (c) 2023 Rivos, Inc. + * + * Author(s): + * Emmanuel Blot + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/opentitan/ot_random_src.h" + +static const TypeInfo ot_random_src_info = { + .name = TYPE_OT_RANDOM_SRC_IF, + .parent = TYPE_INTERFACE, + .class_size = sizeof(OtRandomSrcIfClass), +}; + +static void ot_random_src_register_types(void) +{ + type_register_static(&ot_random_src_info); +} + +type_init(ot_random_src_register_types) diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index d4f0976eed62..5b3d5c641791 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -661,7 +661,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { OT_EARLGREY_SOC_GPIO_SYSBUS_IRQ(3, PLIC, 176) ), .link = IBEXDEVICELINKDEFS( - OT_EARLGREY_SOC_DEVLINK("entropy_src", ENTROPY_SRC), + OT_EARLGREY_SOC_DEVLINK("random_src", ENTROPY_SRC), OT_EARLGREY_SOC_DEVLINK("otp_ctrl", OTP_CTRL) ), }, diff --git a/include/hw/opentitan/ot_entropy_src.h b/include/hw/opentitan/ot_entropy_src.h index 28c5127d351e..f8bf089cc690 100644 --- a/include/hw/opentitan/ot_entropy_src.h +++ b/include/hw/opentitan/ot_entropy_src.h @@ -33,45 +33,4 @@ #define TYPE_OT_ENTROPY_SRC "ot-entropy_src" OBJECT_DECLARE_SIMPLE_TYPE(OtEntropySrcState, OT_ENTROPY_SRC) -#define OT_ENTROPY_SRC_PACKET_SIZE_BITS 384u - -#define OT_ENTROPY_SRC_BYTE_COUNT (OT_ENTROPY_SRC_PACKET_SIZE_BITS / 8u) -#define OT_ENTROPY_SRC_WORD_COUNT (OT_ENTROPY_SRC_BYTE_COUNT / sizeof(uint32_t)) -#define OT_ENTROPY_SRC_DWORD_COUNT \ - (OT_ENTROPY_SRC_BYTE_COUNT / sizeof(uint64_t)) - -/* see hw/ip/edn/doc/#multiple-edns-in-boot-time-request-mode */ -#define OT_ENTROPY_SRC_BOOT_DELAY_NS 2000000u /* 2 ms */ - -/* - * Tell whether the entropy source is available, i.e. whether the entropy - * source module has been enabled. - * - * @return 0 is the entropy_src is disabled, or a positive, monotonic increase - * generation number which indicates the number of time the entropy_src - * has been cycled (enabled from a disable state). This generation - * identifier should be passed on any subsequent - * #ot_entropy_src_get_random request - */ -int ot_entropy_src_get_generation(OtEntropySrcState *s); - -/* - * Fill up a buffer with random values - * - * @s the entropy state instance - * @genid the generation identifier, from #ot_entropy_src_get_generation - * @random the buffer to fill in with entropy data - * @fips on success, updated to @true if entropy data are FIPS-compliant - * @return 0 on success, - * -1 if the entropy 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 process - * any further, - * 1 if the entropy source is still initializing or not enough entropy - * is available to fill the output buffer. - */ -int ot_entropy_src_get_random(OtEntropySrcState *s, int genid, - uint64_t random[OT_ENTROPY_SRC_DWORD_COUNT], - bool *fips); - #endif /* HW_OPENTITAN_OT_ENTROPY_SRC_H */ diff --git a/include/hw/opentitan/ot_random_src.h b/include/hw/opentitan/ot_random_src.h new file mode 100644 index 000000000000..d15420104157 --- /dev/null +++ b/include/hw/opentitan/ot_random_src.h @@ -0,0 +1,87 @@ +/* + * QEMU OpenTitan Random Source interface + * + * Copyright (c) 2023 Rivos, Inc. + * + * Author(s): + * Emmanuel Blot + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_OPENTITAN_OT_RANDOM_SRC_H +#define HW_OPENTITAN_OT_RANDOM_SRC_H + +#include "qom/object.h" + +/* Implemented by devices that can be plugged on Conventional PCI buses */ +#define TYPE_OT_RANDOM_SRC_IF "ot-random_src-interface" +typedef struct OtRandomSrcIfClass OtRandomSrcIfClass; +DECLARE_CLASS_CHECKERS(OtRandomSrcIfClass, OT_RANDOM_SRC_IF, + TYPE_OT_RANDOM_SRC_IF) +#define OT_RANDOM_SRC_IF(_obj_) \ + INTERFACE_CHECK(OtRandomSrcIf, (_obj_), TYPE_OT_RANDOM_SRC_IF) + +#define OT_RANDOM_SRC_PACKET_SIZE_BITS 384u + +#define OT_RANDOM_SRC_BYTE_COUNT (OT_RANDOM_SRC_PACKET_SIZE_BITS / 8u) +#define OT_RANDOM_SRC_WORD_COUNT (OT_RANDOM_SRC_BYTE_COUNT / sizeof(uint32_t)) +#define OT_RANDOM_SRC_DWORD_COUNT (OT_RANDOM_SRC_BYTE_COUNT / sizeof(uint64_t)) + +typedef struct OtRandomSrcIf OtRandomSrcIf; + +struct OtRandomSrcIfClass { + InterfaceClass parent_class; + + /* + * Tell whether the random source is available, i.e. whether the random + * source module has been enabled. + * + * @dev the random source instance + * @return 0 if the random_src is disabled, otherwise: + * * a positive, monotonic increase generation number which indicates the + * number of time the random_src has been cycled (enabled from a + * disable state). This generation identifier should be passed on any + * subsequent #get_random_values request, or + * * a negative number, which indicates that the random source is enabled, + * but the generation number should be simply ignored. + */ + int (*get_random_generation)(OtRandomSrcIf *dev); + + /* + * Fill up a buffer with random values + * + * @dev the random source instance + * @genid the generation identifier, from #get_random_generation + * @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 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 + * process any further, 1 if the random source is still + * initializing or not enough entropy is available to fill the + * output buffer. + */ + int (*get_random_values)(OtRandomSrcIf *dev, int genid, + uint64_t random[OT_RANDOM_SRC_DWORD_COUNT], + bool *fips); +}; + +#endif /* HW_OPENTITAN_OT_RANDOM_SRC_H */ From cd42f9305c2642fdf97f9e022714c21c234518ec Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Mon, 9 Oct 2023 19:25:29 +0200 Subject: [PATCH 13/15] [ot] hw/opentitan: rename EarlGrey AST Signed-off-by: Emmanuel Blot --- hw/opentitan/Kconfig | 2 +- hw/opentitan/meson.build | 2 +- hw/opentitan/{ot_ast.c => ot_ast_earlgrey.c} | 69 ++++++++++--------- hw/opentitan/ot_entropy_src.c | 11 +-- hw/opentitan/trace-events | 6 +- hw/riscv/Kconfig | 2 +- hw/riscv/ot_earlgrey.c | 4 +- .../opentitan/{ot_ast.h => ot_ast_earlgrey.h} | 16 ++--- 8 files changed, 58 insertions(+), 54 deletions(-) rename hw/opentitan/{ot_ast.c => ot_ast_earlgrey.c} (85%) rename include/hw/opentitan/{ot_ast.h => ot_ast_earlgrey.h} (75%) diff --git a/hw/opentitan/Kconfig b/hw/opentitan/Kconfig index 8cab24644da9..831e5b0051bb 100644 --- a/hw/opentitan/Kconfig +++ b/hw/opentitan/Kconfig @@ -14,7 +14,7 @@ config OT_ALERT_EARLGREY config OT_AON_TIMER bool -config OT_AST +config OT_AST_EARLGREY bool config OT_CLKMGR diff --git a/hw/opentitan/meson.build b/hw/opentitan/meson.build index 69f0005b1c4c..d8bdf2075335 100644 --- a/hw/opentitan/meson.build +++ b/hw/opentitan/meson.build @@ -8,7 +8,7 @@ softmmu_ss.add(when: 'CONFIG_OT_AES', if_true: [files('ot_aes.c'), libtomcrypt_d softmmu_ss.add(when: 'CONFIG_OT_ALERT', if_true: files('ot_alert.c')) softmmu_ss.add(when: 'CONFIG_OT_ALERT_EARLGREY', if_true: files('ot_alert_earlgrey.c')) softmmu_ss.add(when: 'CONFIG_OT_AON_TIMER', if_true: files('ot_aon_timer.c')) -softmmu_ss.add(when: 'CONFIG_OT_AST', if_true: files('ot_ast.c')) +softmmu_ss.add(when: 'CONFIG_OT_AST_EARLGREY', if_true: files('ot_ast_earlgrey.c')) softmmu_ss.add(when: 'CONFIG_OT_CLKMGR', if_true: files('ot_clkmgr.c')) softmmu_ss.add(when: 'CONFIG_OT_COMMON', if_true: files('ot_common.c')) softmmu_ss.add(when: 'CONFIG_OT_CSRNG', if_true: [files('ot_csrng.c'), libtomcrypt_dep]) diff --git a/hw/opentitan/ot_ast.c b/hw/opentitan/ot_ast_earlgrey.c similarity index 85% rename from hw/opentitan/ot_ast.c rename to hw/opentitan/ot_ast_earlgrey.c index 30b6fdeba58c..28dece13f888 100644 --- a/hw/opentitan/ot_ast.c +++ b/hw/opentitan/ot_ast_earlgrey.c @@ -1,5 +1,5 @@ /* - * QEMU OpenTitan Analog Sensor Top device + * QEMU OpenTitan EarlGrey Analog Sensor Top device * * Copyright (c) 2023 Rivos, Inc. * @@ -34,7 +34,7 @@ #include "qemu/main-loop.h" #include "qemu/typedefs.h" #include "qapi/error.h" -#include "hw/opentitan/ot_ast.h" +#include "hw/opentitan/ot_ast_earlgrey.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" #include "hw/registerfields.h" @@ -130,7 +130,7 @@ static const char REGB_NAMES[REGSB_COUNT][6U] = { }; #undef REG_NAME_ENTRY -struct OtASTState { +struct OtASTEarlGreyState { SysBusDevice parent_obj; MemoryRegion mmio; @@ -143,7 +143,7 @@ struct OtASTState { /* Public API */ /* -------------------------------------------------------------------------- */ -void ot_ast_getrandom(void *buf, size_t len) +void ot_ast_eg_getrandom(void *buf, size_t len) { qemu_guest_getrandom_nofail(buf, len); } @@ -152,9 +152,10 @@ void ot_ast_getrandom(void *buf, size_t len) /* Private implementation */ /* -------------------------------------------------------------------------- */ -static uint64_t ot_ast_regs_read(void *opaque, hwaddr addr, unsigned size) +static uint64_t ot_ast_eg_regs_read(void *opaque, hwaddr addr, unsigned size) { - OtASTState *s = opaque; + OtASTEarlGreyState *s = opaque; + (void)size; uint32_t val32; hwaddr reg = R32_OFF(addr); @@ -216,22 +217,23 @@ static uint64_t ot_ast_regs_read(void *opaque, hwaddr addr, unsigned size) } uint64_t pc = ibex_get_current_pc(); - trace_ot_ast_io_read_out((unsigned)addr, REG_NAME(reg), (uint64_t)val32, - pc); + trace_ot_ast_eg_io_read_out((unsigned)addr, REG_NAME(reg), (uint64_t)val32, + pc); return (uint64_t)val32; }; -static void ot_ast_regs_write(void *opaque, hwaddr addr, uint64_t val64, - unsigned size) +static void ot_ast_eg_regs_write(void *opaque, hwaddr addr, uint64_t val64, + unsigned size) { - OtASTState *s = opaque; + OtASTEarlGreyState *s = opaque; + (void)size; uint32_t val32 = (uint32_t)val64; hwaddr reg = R32_OFF(addr); uint64_t pc = ibex_get_current_pc(); - trace_ot_ast_io_write((unsigned)addr, REG_NAME(reg), val64, pc); + trace_ot_ast_eg_io_write((unsigned)addr, REG_NAME(reg), val64, pc); switch (reg) { case R_REGA0: @@ -289,21 +291,21 @@ static void ot_ast_regs_write(void *opaque, hwaddr addr, uint64_t val64, } }; -static Property ot_ast_properties[] = { +static Property ot_ast_eg_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static const MemoryRegionOps ot_ast_regs_ops = { - .read = &ot_ast_regs_read, - .write = &ot_ast_regs_write, +static const MemoryRegionOps ot_ast_eg_regs_ops = { + .read = &ot_ast_eg_regs_read, + .write = &ot_ast_eg_regs_write, .endianness = DEVICE_NATIVE_ENDIAN, .impl.min_access_size = 4u, .impl.max_access_size = 4u, }; -static void ot_ast_reset(DeviceState *dev) +static void ot_ast_eg_reset(DeviceState *dev) { - OtASTState *s = OT_AST(dev); + OtASTEarlGreyState *s = OT_AST_EARLGREY(dev); memset(s->regsa, 0, REGSA_SIZE); memset(s->regsb, 0, REGSB_SIZE); @@ -348,38 +350,39 @@ static void ot_ast_reset(DeviceState *dev) s->regsa[R_REGAL] = 0x26u; } -static void ot_ast_init(Object *obj) +static void ot_ast_eg_init(Object *obj) { - OtASTState *s = OT_AST(obj); + OtASTEarlGreyState *s = OT_AST_EARLGREY(obj); - memory_region_init_io(&s->mmio, obj, &ot_ast_regs_ops, s, TYPE_OT_AST, - REGS_SIZE); + memory_region_init_io(&s->mmio, obj, &ot_ast_eg_regs_ops, s, + TYPE_OT_AST_EARLGREY, REGS_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio); s->regsa = g_new0(uint32_t, REGSA_COUNT); s->regsb = g_new0(uint32_t, REGSB_COUNT); } -static void ot_ast_class_init(ObjectClass *klass, void *data) +static void ot_ast_eg_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + (void)data; - dc->reset = &ot_ast_reset; - device_class_set_props(dc, ot_ast_properties); + dc->reset = &ot_ast_eg_reset; + device_class_set_props(dc, ot_ast_eg_properties); set_bit(DEVICE_CATEGORY_MISC, dc->categories); } -static const TypeInfo ot_ast_info = { - .name = TYPE_OT_AST, +static const TypeInfo ot_ast_eg_info = { + .name = TYPE_OT_AST_EARLGREY, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(OtASTState), - .instance_init = &ot_ast_init, - .class_init = &ot_ast_class_init, + .instance_size = sizeof(OtASTEarlGreyState), + .instance_init = &ot_ast_eg_init, + .class_init = &ot_ast_eg_class_init, }; -static void ot_ast_register_types(void) +static void ot_ast_eg_register_types(void) { - type_register_static(&ot_ast_info); + type_register_static(&ot_ast_eg_info); } -type_init(ot_ast_register_types) +type_init(ot_ast_eg_register_types) diff --git a/hw/opentitan/ot_entropy_src.c b/hw/opentitan/ot_entropy_src.c index 804255da4567..cae1082be522 100644 --- a/hw/opentitan/ot_entropy_src.c +++ b/hw/opentitan/ot_entropy_src.c @@ -38,7 +38,7 @@ #include "qemu/typedefs.h" #include "qapi/error.h" #include "hw/opentitan/ot_alert.h" -#include "hw/opentitan/ot_ast.h" +#include "hw/opentitan/ot_ast_earlgrey.h" #include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_entropy_src.h" #include "hw/opentitan/ot_fifo32.h" @@ -322,7 +322,7 @@ static const char *REG_NAMES[REGS_COUNT] = { #define ES_FINAL_FIFO_DEPTH 4u #define ES_FILL_RATE_NS \ ((NANOSECONDS_PER_SECOND * ES_FILL_BITS) / \ - ((uint64_t)OT_AST_RANDOM_4BIT_RATE * 4u)) + ((uint64_t)OT_AST_EARLGREY_RANDOM_4BIT_RATE * 4u)) #define OT_ENTROPY_SRC_FILL_WORD_COUNT (ES_FILL_BITS / (8u * sizeof(uint32_t))) #define ES_WORD_COUNT (OT_RANDOM_SRC_WORD_COUNT) #define ES_SWREAD_FIFO_WORD_COUNT ES_WORD_COUNT @@ -386,7 +386,7 @@ struct OtEntropySrcState { bool otp_fw_read; bool otp_fw_over; - OtASTState *ast; + OtASTEarlGreyState *ast; OtOTPState *otp_ctrl; }; @@ -987,7 +987,7 @@ static bool ot_entropy_src_fill_noise(OtEntropySrcState *s) uint32_t buffer[OT_ENTROPY_SRC_FILL_WORD_COUNT]; /* synchronous read */ - ot_ast_getrandom(buffer, sizeof(buffer)); + ot_ast_eg_getrandom(buffer, sizeof(buffer)); /* push the whole entropy buffer into the input FIFO */ unsigned pos = 0; @@ -1515,7 +1515,8 @@ static void ot_entropy_src_regs_write(void *opaque, hwaddr addr, uint64_t val64, }; static Property ot_entropy_src_properties[] = { - DEFINE_PROP_LINK("ast", OtEntropySrcState, ast, TYPE_OT_AST, OtASTState *), + DEFINE_PROP_LINK("ast", OtEntropySrcState, ast, TYPE_OT_AST_EARLGREY, + OtASTEarlGreyState *), DEFINE_PROP_LINK("otp_ctrl", OtEntropySrcState, otp_ctrl, TYPE_OT_OTP, OtOTPState *), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/opentitan/trace-events b/hw/opentitan/trace-events index 573bb62c73e6..aa9540d2355e 100644 --- a/hw/opentitan/trace-events +++ b/hw/opentitan/trace-events @@ -25,10 +25,10 @@ ot_aon_timer_irqs(bool wakeup, bool bark, bool bite) "wkup:%u bark:%u bite:%u" ot_aon_timer_read_out(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64", pc=0x%" PRIx64 ot_aon_timer_write(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 -# ot_ast.c +# ot_ast_earlgrey.c -ot_ast_io_read_out(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 -ot_ast_io_write(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 +ot_ast_eg_io_read_out(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 +ot_ast_eg_io_write(unsigned int addr, const char * regname, uint64_t val, uint64_t pc) "addr=0x%02x (%s), val=0x%" PRIx64 ", pc=0x%" PRIx64 # ot_clkmgr.c diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 1808ba86d85d..e51bbd902938 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -16,7 +16,7 @@ config OT_EARLGREY select OT_AES select OT_ALERT_EARLGREY select OT_AON_TIMER - select OT_AST + select OT_AST_EARLGREY select OT_CLKMGR select OT_CSRNG select OT_EDN diff --git a/hw/riscv/ot_earlgrey.c b/hw/riscv/ot_earlgrey.c index 5b3d5c641791..f7595610a07c 100644 --- a/hw/riscv/ot_earlgrey.c +++ b/hw/riscv/ot_earlgrey.c @@ -35,7 +35,7 @@ #include "hw/opentitan/ot_aes.h" #include "hw/opentitan/ot_alert_earlgrey.h" #include "hw/opentitan/ot_aon_timer.h" -#include "hw/opentitan/ot_ast.h" +#include "hw/opentitan/ot_ast_earlgrey.h" #include "hw/opentitan/ot_clkmgr.h" #include "hw/opentitan/ot_csrng.h" #include "hw/opentitan/ot_edn.h" @@ -536,7 +536,7 @@ static const IbexDeviceDef ot_earlgrey_soc_devices[] = { ), }, [OT_EARLGREY_SOC_DEV_AST] = { - .type = TYPE_OT_AST, + .type = TYPE_OT_AST_EARLGREY, .memmap = MEMMAPENTRIES( { 0x40480000u, 0x400u } ), diff --git a/include/hw/opentitan/ot_ast.h b/include/hw/opentitan/ot_ast_earlgrey.h similarity index 75% rename from include/hw/opentitan/ot_ast.h rename to include/hw/opentitan/ot_ast_earlgrey.h index f0cefa55073b..748f46bf540b 100644 --- a/include/hw/opentitan/ot_ast.h +++ b/include/hw/opentitan/ot_ast_earlgrey.h @@ -1,5 +1,5 @@ /* - * QEMU OpenTitan Analog Sensor Top device + * QEMU OpenTitan EarlGrey Analog Sensor Top device * * Copyright (c) 2023 Rivos, Inc. * @@ -25,16 +25,16 @@ * THE SOFTWARE. */ -#ifndef HW_OPENTITAN_OT_AST_H -#define HW_OPENTITAN_OT_AST_H +#ifndef HW_OPENTITAN_OT_AST_EARLGREY_H +#define HW_OPENTITAN_OT_AST_EARLGREY_H #include "qom/object.h" -#define TYPE_OT_AST "ot-ast" -OBJECT_DECLARE_SIMPLE_TYPE(OtASTState, OT_AST) +#define TYPE_OT_AST_EARLGREY "ot-ast-earlgrey" +OBJECT_DECLARE_SIMPLE_TYPE(OtASTEarlGreyState, OT_AST_EARLGREY) -#define OT_AST_RANDOM_4BIT_RATE 50000u /* 50 kHz */ +#define OT_AST_EARLGREY_RANDOM_4BIT_RATE 50000u /* 50 kHz */ -void ot_ast_getrandom(void *buf, size_t len); +void ot_ast_eg_getrandom(void *buf, size_t len); -#endif /* HW_OPENTITAN_OT_AST_H */ +#endif /* HW_OPENTITAN_OT_AST_EARLGREY_H */ From 85d83be7256e64627f5a54b48584cfc803366859 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 11 Oct 2023 18:43:42 +0200 Subject: [PATCH 14/15] [ot] hw/opentitan: move ChrBackend utility function to ot_common Signed-off-by: Emmanuel Blot --- hw/opentitan/ot_common.c | 23 +++++++++++++++++++++++ hw/opentitan/ot_gpio.c | 27 ++------------------------- include/hw/opentitan/ot_common.h | 7 +++++++ 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/hw/opentitan/ot_common.c b/hw/opentitan/ot_common.c index 0e0ec5b85ea5..f0502050f1f1 100644 --- a/hw/opentitan/ot_common.c +++ b/hw/opentitan/ot_common.c @@ -84,3 +84,26 @@ AddressSpace *ot_common_get_local_address_space(DeviceState *s) return cpu ? cpu->as : NULL; } + +/* + * Unfortunately, there is no QEMU API to properly disable serial control lines + */ +#ifndef _WIN32 +#include +#include "chardev/char-fd.h" +#include "io/channel-file.h" +#endif + +void ot_common_ignore_chr_status_lines(CharBackend *chr) +{ +/* it might be useful to move this to char-serial.c */ +#ifndef _WIN32 + FDChardev *cd = FD_CHARDEV(chr->chr); + QIOChannelFile *fioc = QIO_CHANNEL_FILE(cd->ioc_in); + + struct termios tty = { 0 }; + tcgetattr(fioc->fd, &tty); + tty.c_cflag |= CLOCAL; /* ignore modem status lines */ + tcsetattr(fioc->fd, TCSANOW, &tty); +#endif +} diff --git a/hw/opentitan/ot_gpio.c b/hw/opentitan/ot_gpio.c index 09487095b813..a520fd3cfaec 100644 --- a/hw/opentitan/ot_gpio.c +++ b/hw/opentitan/ot_gpio.c @@ -36,6 +36,7 @@ #include "chardev/char-fe.h" #include "hw/hw.h" #include "hw/opentitan/ot_alert.h" +#include "hw/opentitan/ot_common.h" #include "hw/opentitan/ot_gpio.h" #include "hw/qdev-properties-system.h" #include "hw/qdev-properties.h" @@ -45,16 +46,6 @@ #include "hw/sysbus.h" #include "trace.h" -/* - * Unfortunately, there is no QEMU API to properly disable serial control lines - */ -#ifndef _WIN32 -#include -#include "chardev/char-fd.h" -#include "io/channel-file.h" -#endif - - #define PARAM_NUM_ALERTS 1u /* clang-format off */ @@ -406,27 +397,13 @@ static void ot_gpio_chr_receive(void *opaque, const uint8_t *buf, int size) } } -static void ot_gpio_chr_ignore_status_lines(OtGpioState *s) -{ -/* it might be useful to move this to char-serial.c */ -#ifndef _WIN32 - FDChardev *cd = FD_CHARDEV(s->chr.chr); - QIOChannelFile *fioc = QIO_CHANNEL_FILE(cd->ioc_in); - - struct termios tty = { 0 }; - tcgetattr(fioc->fd, &tty); - tty.c_cflag |= CLOCAL; /* ignore modem status lines */ - tcsetattr(fioc->fd, TCSANOW, &tty); -#endif -} - static void ot_gpio_chr_event_hander(void *opaque, QEMUChrEvent event) { OtGpioState *s = opaque; if (event == CHR_EVENT_OPENED) { if (object_dynamic_cast(OBJECT(s->chr.chr), TYPE_CHARDEV_SERIAL)) { - ot_gpio_chr_ignore_status_lines(s); + ot_common_ignore_chr_status_lines(&s->chr); } ot_gpio_update_backend(s, true); diff --git a/include/hw/opentitan/ot_common.h b/include/hw/opentitan/ot_common.h index 7c561343126e..c81dea8917e3 100644 --- a/include/hw/opentitan/ot_common.h +++ b/include/hw/opentitan/ot_common.h @@ -23,6 +23,7 @@ #ifndef HW_OPENTITAN_OT_COMMON_H #define HW_OPENTITAN_OT_COMMON_H +#include "chardev/char-fe.h" #include "exec/memory.h" #include "hw/core/cpu.h" @@ -137,4 +138,10 @@ CPUState *ot_common_get_local_cpu(DeviceState *s); */ AddressSpace *ot_common_get_local_address_space(DeviceState *s); +/* ------------------------------------------------------------------------ */ +/* CharDev utilities */ +/* ------------------------------------------------------------------------ */ + +void ot_common_ignore_chr_status_lines(CharBackend *chr); + #endif /* HW_OPENTITAN_OT_COMMON_H */ From 45104fca7fa86e27bee1e1a9b5048e59bfdf5d80 Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Thu, 19 Oct 2023 12:33:35 +0200 Subject: [PATCH 15/15] [ot] scripts/opentitan: run qemu from build directory Signed-off-by: Emmanuel Blot --- scripts/opentitan/otboot.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/opentitan/otboot.sh b/scripts/opentitan/otboot.sh index 8cbbc87d08d0..91e556adfdb7 100755 --- a/scripts/opentitan/otboot.sh +++ b/scripts/opentitan/otboot.sh @@ -209,8 +209,8 @@ ${SCRIPT_DIR}/flashgen.py -v -D -x "${OT_ROM_EXT_BIN}" -b "${OT_BL0_TEST_BIN}" \ flash.raw ${FLASHGEN_OPTS} || die "flashgen.py failed" echo "Use [Ctrl-A] + x to quit QEMU" -${QEMU_BUILD_DIR}/qemu-system-riscv32 \ +(cd ${QEMU_BUILD_DIR} && ./qemu-system-riscv32 \ -M ot-earlgrey -display none -serial mon:stdio ${QEMU_GUEST_OPT} \ - -drive if=pflash,file=otp.raw,format=raw \ - -drive if=mtd,bus=1,file=flash.raw,format=raw $* + -drive if=pflash,file=${QEMU_DIR}/otp.raw,format=raw \ + -drive if=mtd,bus=1,file=${QEMU_DIR}/flash.raw,format=raw $*)