[mask_rom, address_translation] Add driver for address translation.
Signed-off-by: Douglas Reis <doreis@lowrisc.org>
diff --git a/sw/device/silicon_creator/lib/drivers/BUILD b/sw/device/silicon_creator/lib/drivers/BUILD
index 326eea7..42691ac 100644
--- a/sw/device/silicon_creator/lib/drivers/BUILD
+++ b/sw/device/silicon_creator/lib/drivers/BUILD
@@ -175,6 +175,17 @@
"//hw/ip/rv_core_ibex/data:rv_core_ibex_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:abs_mmio",
+ "//sw/device/silicon_creator/lib/base:sec_mmio",
+ ],
+)
+
+cc_test(
+ name = "ibex_unittest",
+ srcs = ["ibex_unittest.cc"],
+ deps = [
+ ":ibex",
+ "//sw/device/silicon_creator/testing:mask_rom_test",
+ "@googletest//:gtest_main",
],
)
diff --git a/sw/device/silicon_creator/lib/drivers/ibex.c b/sw/device/silicon_creator/lib/drivers/ibex.c
index 0da85f7..9adeca2 100644
--- a/sw/device/silicon_creator/lib/drivers/ibex.c
+++ b/sw/device/silicon_creator/lib/drivers/ibex.c
@@ -5,6 +5,7 @@
#include "sw/device/silicon_creator/lib/drivers/ibex.h"
#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "rv_core_ibex_regs.h"
@@ -16,3 +17,33 @@
uint32_t ibex_fpga_version(void) {
return abs_mmio_read32(kBase + RV_CORE_IBEX_FPGA_INFO_REG_OFFSET);
}
+
+void ibex_addr_remap_0_set(uint32_t matching_addr, uint32_t remap_addr,
+ size_t size) {
+ uint32_t mask = matching_addr | ((size - 1) >> 1);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_IBUS_ADDR_MATCHING_0_REG_OFFSET, mask);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_DBUS_ADDR_MATCHING_0_REG_OFFSET, mask);
+
+ sec_mmio_write32(kBase + RV_CORE_IBEX_IBUS_REMAP_ADDR_0_REG_OFFSET,
+ remap_addr);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_DBUS_REMAP_ADDR_0_REG_OFFSET,
+ remap_addr);
+
+ sec_mmio_write32(kBase + RV_CORE_IBEX_IBUS_ADDR_EN_0_REG_OFFSET, 1);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_DBUS_ADDR_EN_0_REG_OFFSET, 1);
+}
+
+void ibex_addr_remap_1_set(uint32_t matching_addr, uint32_t remap_addr,
+ size_t size) {
+ uint32_t mask = matching_addr | ((size - 1) >> 1);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_IBUS_ADDR_MATCHING_1_REG_OFFSET, mask);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_DBUS_ADDR_MATCHING_1_REG_OFFSET, mask);
+
+ sec_mmio_write32(kBase + RV_CORE_IBEX_IBUS_REMAP_ADDR_1_REG_OFFSET,
+ remap_addr);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_DBUS_REMAP_ADDR_1_REG_OFFSET,
+ remap_addr);
+
+ sec_mmio_write32(kBase + RV_CORE_IBEX_IBUS_ADDR_EN_1_REG_OFFSET, 1);
+ sec_mmio_write32(kBase + RV_CORE_IBEX_DBUS_ADDR_EN_1_REG_OFFSET, 1);
+}
diff --git a/sw/device/silicon_creator/lib/drivers/ibex.h b/sw/device/silicon_creator/lib/drivers/ibex.h
index 3615c1c..74c1ab8 100644
--- a/sw/device/silicon_creator/lib/drivers/ibex.h
+++ b/sw/device/silicon_creator/lib/drivers/ibex.h
@@ -5,6 +5,7 @@
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_IBEX_H_
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_IBEX_H_
+#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
@@ -18,6 +19,46 @@
*/
uint32_t ibex_fpga_version(void);
+/**
+ * The following constants represent the expected number of sec_mmio register
+ * writes performed by functions in provided in this module. See
+ * `SEC_MMIO_WRITE_INCREMENT()` for more details.
+ *
+ * Example:
+ * ```
+ * ibex_addr_remap_0_set(...);
+ * SEC_MMIO_WRITE_INCREMENT(kAddressTranslationSecMmioConfigure);
+ * ```
+ */
+enum {
+ kAddressTranslationSecMmioConfigure = 6,
+};
+
+/**
+ * Configure the instruction and data bus in the address translation slot 0.
+ *
+ * @param matching_addr When an incoming transaction matches the matching
+ * region, it is redirected to the new address. If a transaction does not match,
+ * then it is directly passed through.
+ * @param remap_addr The region where the matched transtaction will be
+ * redirected to.
+ * @param size The size of the regions mapped.
+ */
+void ibex_addr_remap_0_set(uint32_t matching_addr, uint32_t remap_addr,
+ size_t size);
+
+/**
+ * Configure the instruction and data bus in the address translation slot 1.
+ *
+ * @param matching_addr When an incoming transaction matches the matching
+ * region, it is redirected to the new address. If a transaction does not match,
+ * then it is directly passed through.
+ * @param remap_addr The region where the matched transtaction will be
+ * redirected to.
+ * @param size The size of the regions mapped.
+ */
+void ibex_addr_remap_1_set(uint32_t matching_addr, uint32_t remap_addr,
+ size_t size);
#ifdef __cplusplus
}
#endif
diff --git a/sw/device/silicon_creator/lib/drivers/ibex_unittest.cc b/sw/device/silicon_creator/lib/drivers/ibex_unittest.cc
new file mode 100644
index 0000000..7236ff9
--- /dev/null
+++ b/sw/device/silicon_creator/lib/drivers/ibex_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/silicon_creator/lib/drivers/ibex.h"
+
+#include <array>
+
+#include "gtest/gtest.h"
+#include "sw/device/lib/base/testing/mock_abs_mmio.h"
+#include "sw/device/silicon_creator/lib/base/mock_sec_mmio.h"
+#include "sw/device/silicon_creator/testing/mask_rom_test.h"
+
+#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+#include "rv_core_ibex_regs.h"
+
+namespace ibex_unittest {
+namespace {
+
+class AddressTranslationTest : public mask_rom_test::MaskRomTest {
+ protected:
+ uint32_t base_ = TOP_EARLGREY_RV_CORE_IBEX_CFG_BASE_ADDR;
+ mask_rom_test::MockSecMmio sec_;
+};
+
+TEST_F(AddressTranslationTest, Slot0Sucess) {
+ uint32_t matching_addr = 0x9000000;
+ uint32_t remap_addr = 0x2000000;
+ uint32_t size = 0x8000;
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_IBUS_ADDR_MATCHING_0_REG_OFFSET,
+ 0x9003fff);
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_DBUS_ADDR_MATCHING_0_REG_OFFSET,
+ 0x9003fff);
+
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_IBUS_REMAP_ADDR_0_REG_OFFSET,
+ remap_addr);
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_DBUS_REMAP_ADDR_0_REG_OFFSET,
+ remap_addr);
+
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_IBUS_ADDR_EN_0_REG_OFFSET, 1);
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_DBUS_ADDR_EN_0_REG_OFFSET, 1);
+
+ ibex_addr_remap_0_set(matching_addr, remap_addr, size);
+}
+
+TEST_F(AddressTranslationTest, Slot1Sucess) {
+ uint32_t matching_addr = 0xB040000;
+ uint32_t remap_addr = 0x6000000;
+ uint32_t size = 0x80000;
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_IBUS_ADDR_MATCHING_1_REG_OFFSET,
+ 0xb07ffff);
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_DBUS_ADDR_MATCHING_1_REG_OFFSET,
+ 0xb07ffff);
+
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_IBUS_REMAP_ADDR_1_REG_OFFSET,
+ remap_addr);
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_DBUS_REMAP_ADDR_1_REG_OFFSET,
+ remap_addr);
+
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_IBUS_ADDR_EN_1_REG_OFFSET, 1);
+ EXPECT_SEC_WRITE32(base_ + RV_CORE_IBEX_DBUS_ADDR_EN_1_REG_OFFSET, 1);
+
+ ibex_addr_remap_1_set(matching_addr, remap_addr, size);
+}
+} // namespace
+} // namespace ibex_unittest
diff --git a/sw/device/silicon_creator/lib/drivers/meson.build b/sw/device/silicon_creator/lib/drivers/meson.build
index 791aefe..76eb277 100644
--- a/sw/device/silicon_creator/lib/drivers/meson.build
+++ b/sw/device/silicon_creator/lib/drivers/meson.build
@@ -489,6 +489,7 @@
suite: 'mask_rom',
)
+
# Mask ROM otbn driver
sw_silicon_creator_lib_driver_otbn = declare_dependency(
link_with: static_library(
@@ -615,6 +616,26 @@
),
)
+
+test('sw_silicon_creator_lib_driver_ibex_unittest', executable(
+ 'sw_silicon_creator_lib_driver_ibex_unittest',
+ sources: [
+ hw_ip_ibex_reg_h,
+ 'ibex_unittest.cc',
+ 'ibex.c',
+ ],
+ dependencies: [
+ sw_vendor_gtest,
+ sw_lib_testing_hardened,
+ sw_silicon_creator_lib_base_mock_sec_mmio,
+ ],
+ native: true,
+ c_args: ['-DMOCK_ABS_MMIO', '-DOT_OFF_TARGET_TEST'],
+ cpp_args: ['-DMOCK_ABS_MMIO', '-DOT_OFF_TARGET_TEST'],
+ ),
+ suite: 'mask_rom',
+)
+
test('sw_silicon_creator_lib_driver_spi_device_unittest', executable(
'sw_silicon_creator_lib_driver_spi_device_unittest',
sources: [