5 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
16 #include "rv_core_ibex_regs.h"
22 static_assert(kDifRvCoreIbexErrorStatusRegisterTransmissionIntegrity ==
23 1 << RV_CORE_IBEX_ERR_STATUS_REG_INTG_ERR_BIT,
24 "Layout of RV_CORE_IBEX_ERR_STATUS_REG register changed.");
25 static_assert(kDifRvCoreIbexErrorStatusFatalResponseIntegrity ==
26 1 << RV_CORE_IBEX_ERR_STATUS_FATAL_INTG_ERR_BIT,
27 "Layout of RV_CORE_IBEX_ERR_STATUS_REG register changed.");
28 static_assert(kDifRvCoreIbexErrorStatusFatalInternalError ==
29 1 << RV_CORE_IBEX_ERR_STATUS_FATAL_CORE_ERR_BIT,
30 "Layout of RV_CORE_IBEX_ERR_STATUS_REG register changed.");
31 static_assert(kDifRvCoreIbexErrorStatusRecoverableInternal ==
32 1 << RV_CORE_IBEX_ERR_STATUS_RECOV_CORE_ERR_BIT,
33 "Layout of RV_CORE_IBEX_ERR_STATUS_REG register changed.");
43 [kDifRvCoreIbexAddrTranslationSlotCount]
44 [kDifRvCoreIbexAddrTranslationSlotCount] = {
45 [kDifRvCoreIbexAddrTranslationSlot_0]
46 [kDifRvCoreIbexAddrTranslationDBus] =
48 .matching = RV_CORE_IBEX_DBUS_ADDR_MATCHING_0_REG_OFFSET,
49 .remap = RV_CORE_IBEX_DBUS_REMAP_ADDR_0_REG_OFFSET,
50 .en = RV_CORE_IBEX_DBUS_ADDR_EN_0_REG_OFFSET,
51 .lock = RV_CORE_IBEX_DBUS_REGWEN_0_REG_OFFSET,
53 [kDifRvCoreIbexAddrTranslationSlot_0]
54 [kDifRvCoreIbexAddrTranslationIBus] =
56 .matching = RV_CORE_IBEX_IBUS_ADDR_MATCHING_0_REG_OFFSET,
57 .remap = RV_CORE_IBEX_IBUS_REMAP_ADDR_0_REG_OFFSET,
58 .en = RV_CORE_IBEX_IBUS_ADDR_EN_0_REG_OFFSET,
59 .lock = RV_CORE_IBEX_IBUS_REGWEN_0_REG_OFFSET,
61 [kDifRvCoreIbexAddrTranslationSlot_1]
62 [kDifRvCoreIbexAddrTranslationDBus] =
64 .matching = RV_CORE_IBEX_DBUS_ADDR_MATCHING_1_REG_OFFSET,
65 .remap = RV_CORE_IBEX_DBUS_REMAP_ADDR_1_REG_OFFSET,
66 .en = RV_CORE_IBEX_DBUS_ADDR_EN_1_REG_OFFSET,
67 .lock = RV_CORE_IBEX_DBUS_REGWEN_1_REG_OFFSET,
69 [kDifRvCoreIbexAddrTranslationSlot_1]
70 [kDifRvCoreIbexAddrTranslationIBus] =
72 .matching = RV_CORE_IBEX_IBUS_ADDR_MATCHING_1_REG_OFFSET,
73 .remap = RV_CORE_IBEX_IBUS_REMAP_ADDR_1_REG_OFFSET,
74 .en = RV_CORE_IBEX_IBUS_ADDR_EN_1_REG_OFFSET,
75 .lock = RV_CORE_IBEX_IBUS_REGWEN_1_REG_OFFSET,
86 static uint32_t to_napot(uint32_t addr,
size_t size) {
87 return addr | (size - 1) >> 1;
97 static uint32_t from_napot(uint32_t napot,
size_t *size) {
98 for (
size_t i = 1; i <
sizeof(uint32_t) * 8; ++i) {
99 uint32_t ref = (1u << i) - 1;
100 if ((napot & ref) == ref >> 1) {
105 return napot & ~((*size - 1) >> 1);
108 dif_result_t dif_rv_core_ibex_configure_addr_translation(
109 const dif_rv_core_ibex_t *rv_core_ibex,
110 dif_rv_core_ibex_addr_translation_slot_t slot,
111 dif_rv_core_ibex_addr_translation_bus_t bus,
113 if (rv_core_ibex == NULL || slot >= kDifRvCoreIbexAddrTranslationSlotCount ||
114 bus >= kDifRvCoreIbexAddrTranslationBusCount ||
121 if (mmio_region_read32(rv_core_ibex->base_addr, (ptrdiff_t)regs.lock) == 0) {
126 mmio_region_write32(rv_core_ibex->base_addr, (ptrdiff_t)regs.matching, mask);
127 mmio_region_write32(rv_core_ibex->base_addr, (ptrdiff_t)regs.remap,
134 const dif_rv_core_ibex_t *rv_core_ibex,
135 dif_rv_core_ibex_addr_translation_slot_t slot,
136 dif_rv_core_ibex_addr_translation_bus_t bus) {
137 if (rv_core_ibex == NULL || slot >= kDifRvCoreIbexAddrTranslationSlotCount ||
138 bus >= kDifRvCoreIbexAddrTranslationBusCount) {
142 if (mmio_region_read32(rv_core_ibex->base_addr, (ptrdiff_t)regs.lock) == 0) {
145 mmio_region_write32(rv_core_ibex->base_addr, (ptrdiff_t)regs.en, 1);
151 const dif_rv_core_ibex_t *rv_core_ibex,
152 dif_rv_core_ibex_addr_translation_slot_t slot,
153 dif_rv_core_ibex_addr_translation_bus_t bus) {
154 if (rv_core_ibex == NULL || slot >= kDifRvCoreIbexAddrTranslationSlotCount ||
155 bus >= kDifRvCoreIbexAddrTranslationBusCount) {
159 if (mmio_region_read32(rv_core_ibex->base_addr, (ptrdiff_t)regs.lock) == 0) {
162 mmio_region_write32(rv_core_ibex->base_addr, (ptrdiff_t)regs.en, 0);
168 const dif_rv_core_ibex_t *rv_core_ibex,
169 dif_rv_core_ibex_addr_translation_slot_t slot,
170 dif_rv_core_ibex_addr_translation_bus_t bus,
172 if (rv_core_ibex == NULL || addr_map == NULL ||
173 slot >= kDifRvCoreIbexAddrTranslationSlotCount ||
174 bus >= kDifRvCoreIbexAddrTranslationBusCount) {
181 mmio_region_read32(rv_core_ibex->base_addr, (ptrdiff_t)regs.matching);
185 mmio_region_read32(rv_core_ibex->base_addr, (ptrdiff_t)regs.remap);
191 const dif_rv_core_ibex_t *rv_core_ibex,
192 dif_rv_core_ibex_addr_translation_slot_t slot,
193 dif_rv_core_ibex_addr_translation_bus_t bus) {
194 if (rv_core_ibex == NULL || slot >= kDifRvCoreIbexAddrTranslationSlotCount ||
195 bus >= kDifRvCoreIbexAddrTranslationBusCount) {
201 if (mmio_region_read32(rv_core_ibex->base_addr, (ptrdiff_t)regs.lock) == 1) {
202 mmio_region_write32(rv_core_ibex->base_addr, (ptrdiff_t)regs.lock, 0);
209 const dif_rv_core_ibex_t *rv_core_ibex,
210 dif_rv_core_ibex_error_status_t *error_status) {
211 if (rv_core_ibex == NULL || error_status == NULL) {
215 *error_status = mmio_region_read32(rv_core_ibex->base_addr,
216 RV_CORE_IBEX_ERR_STATUS_REG_OFFSET);
222 const dif_rv_core_ibex_t *rv_core_ibex,
223 dif_rv_core_ibex_error_status_t error_status) {
224 if (rv_core_ibex == NULL ||
225 (error_status & ~(uint32_t)kDifRvCoreIbexErrorStatusAll) != 0) {
229 mmio_region_write32(rv_core_ibex->base_addr,
230 RV_CORE_IBEX_ERR_STATUS_REG_OFFSET, error_status);
235 dif_result_t dif_rv_core_ibex_enable_nmi(
const dif_rv_core_ibex_t *rv_core_ibex,
236 dif_rv_core_ibex_nmi_source_t nmi) {
237 if (rv_core_ibex == NULL || nmi & ~(uint32_t)kDifRvCoreIbexNmiSourceAll) {
243 reg, RV_CORE_IBEX_NMI_ENABLE_ALERT_EN_BIT,
244 (nmi & kDifRvCoreIbexNmiSourceAlert) == kDifRvCoreIbexNmiSourceAlert);
246 reg, RV_CORE_IBEX_NMI_ENABLE_WDOG_EN_BIT,
247 (nmi & kDifRvCoreIbexNmiSourceWdog) == kDifRvCoreIbexNmiSourceWdog);
249 mmio_region_write32(rv_core_ibex->base_addr,
250 RV_CORE_IBEX_NMI_ENABLE_REG_OFFSET, reg);
256 const dif_rv_core_ibex_t *rv_core_ibex,
258 if (rv_core_ibex == NULL || nmi_state == NULL) {
264 uint32_t reg = mmio_region_read32(rv_core_ibex->base_addr,
265 RV_CORE_IBEX_NMI_ENABLE_REG_OFFSET);
271 reg = mmio_region_read32(rv_core_ibex->base_addr,
272 RV_CORE_IBEX_NMI_STATE_REG_OFFSET);
282 const dif_rv_core_ibex_t *rv_core_ibex, dif_rv_core_ibex_nmi_source_t nmi) {
283 if (rv_core_ibex == NULL || nmi & ~(uint32_t)kDifRvCoreIbexNmiSourceAll) {
289 reg, RV_CORE_IBEX_NMI_STATE_ALERT_BIT,
290 (nmi & kDifRvCoreIbexNmiSourceAlert) == kDifRvCoreIbexNmiSourceAlert);
292 reg, RV_CORE_IBEX_NMI_STATE_WDOG_BIT,
293 (nmi & kDifRvCoreIbexNmiSourceWdog) == kDifRvCoreIbexNmiSourceWdog);
295 mmio_region_write32(rv_core_ibex->base_addr,
296 RV_CORE_IBEX_NMI_STATE_REG_OFFSET, reg);
301 const dif_rv_core_ibex_t *rv_core_ibex,
302 dif_rv_core_ibex_rnd_status_t *
status) {
303 if (rv_core_ibex == NULL ||
status == NULL) {
307 *
status = mmio_region_read32(rv_core_ibex->base_addr,
308 RV_CORE_IBEX_RND_STATUS_REG_OFFSET);
313 const dif_rv_core_ibex_t *rv_core_ibex, uint32_t *data) {
314 if (rv_core_ibex == NULL || data == NULL) {
318 *data = mmio_region_read32(rv_core_ibex->base_addr,
319 RV_CORE_IBEX_RND_DATA_REG_OFFSET);
324 const dif_rv_core_ibex_t *rv_core_ibex,
325 dif_rv_core_ibex_fpga_info_t *info) {
326 if (rv_core_ibex == NULL || info == NULL) {
330 *info = mmio_region_read32(rv_core_ibex->base_addr,
331 RV_CORE_IBEX_FPGA_INFO_REG_OFFSET);
336 const dif_rv_core_ibex_t *rv_core_ibex,
bool *enabled) {
337 if (rv_core_ibex == NULL || enabled == NULL) {
340 uint32_t reg = mmio_region_read32(rv_core_ibex->base_addr,
341 RV_CORE_IBEX_SW_RECOV_ERR_REG_OFFSET);
342 *enabled = reg != kMultiBitBool4False;
346 dif_result_t dif_rv_core_ibex_trigger_sw_recov_err_alert(
347 const dif_rv_core_ibex_t *rv_core_ibex) {
348 if (rv_core_ibex == NULL) {
356 mmio_region_write32(rv_core_ibex->base_addr,
357 RV_CORE_IBEX_SW_RECOV_ERR_REG_OFFSET, reg);
362 const dif_rv_core_ibex_t *rv_core_ibex,
bool *enabled) {
363 if (rv_core_ibex == NULL || enabled == NULL) {
366 uint32_t reg = mmio_region_read32(rv_core_ibex->base_addr,
367 RV_CORE_IBEX_SW_FATAL_ERR_REG_OFFSET);
368 *enabled = reg != kMultiBitBool4False;
372 dif_result_t dif_rv_core_ibex_trigger_sw_fatal_err_alert(
373 const dif_rv_core_ibex_t *rv_core_ibex) {
374 if (rv_core_ibex == NULL) {
382 mmio_region_write32(rv_core_ibex->base_addr,
383 RV_CORE_IBEX_SW_FATAL_ERR_REG_OFFSET, reg);
389 kIbexCrashDumpWordsCount = kIbexCrashDumpBytesCount /
sizeof(uint32_t),
391 kIbexCrashDumpStateWordsCount =
392 kIbexCrashDumpStateBytesCount /
sizeof(uint32_t),
393 kIbexCrashDumpPreviousStateBytesCount =
395 kIbexCrashDumpPreviousStateWordsCount =
396 kIbexCrashDumpPreviousStateBytesCount /
sizeof(uint32_t),
400 const dif_rv_core_ibex_t *rv_core_ibex, uint32_t *cpu_info,
401 uint32_t cpu_info_len,
403 if (rv_core_ibex == NULL || cpu_info == NULL || crash_dump_info == NULL ||
404 cpu_info_len < kIbexCrashDumpWordsCount) {
408 memcpy(crash_dump_info, cpu_info, kIbexCrashDumpBytesCount - 1);