summaryrefslogtreecommitdiff
path: root/test/mpu.c
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2020-05-14 14:32:32 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-22 19:22:19 +0000
commit4116f1ae6996ecc87b000f335880f4457780ceb8 (patch)
tree00126544311d0817c534ed753a5ccc550c20e93b /test/mpu.c
parent67665bb55473e64da629df0546245e61e810927b (diff)
downloadchrome-ec-4116f1ae6996ecc87b000f335880f4457780ceb8.tar.gz
test: Add on-device MPU unit test
BRANCH=none BUG=b:151105339, b:155229277 TEST=make BOARD=bloonchipper test-mpu -j && \ ./util/flash_jlink.py --board bloonchipper \ --image ./build/bloonchipper/mpu/mpu.bin => On console: "runtest" => All tests pass, except last which correctly panics: Data access violation, mfar = 20000000 Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I1c759f50da5075b1e9027cdba253d8c06843be5a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2202852 Commit-Queue: Yicheng Li <yichengli@chromium.org> Tested-by: Yicheng Li <yichengli@chromium.org> Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
Diffstat (limited to 'test/mpu.c')
-rw-r--r--test/mpu.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/test/mpu.c b/test/mpu.c
new file mode 100644
index 0000000000..64c8c78407
--- /dev/null
+++ b/test/mpu.c
@@ -0,0 +1,127 @@
+/* Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdbool.h>
+#include "mpu.h"
+#include "mpu_private.h"
+#include "test_util.h"
+
+struct mpu_info {
+ bool has_mpu;
+ int num_mpu_regions;
+ bool mpu_is_unified;
+};
+
+#if defined(CHIP_VARIANT_STM32F412)
+struct mpu_info mpu_info = {
+ .has_mpu = true,
+ .num_mpu_regions = 8,
+ .mpu_is_unified = true
+};
+#elif defined(CHIP_VARIANT_STM32H7X3)
+struct mpu_info mpu_info = {
+ .has_mpu = true,
+ .num_mpu_regions = 16,
+ .mpu_is_unified = true
+};
+#else
+#error "MPU info not defined for this chip. Please add it."
+#endif
+
+test_static int test_mpu_info(void)
+{
+ TEST_EQ(mpu_num_regions(), mpu_info.num_mpu_regions, "%d");
+ TEST_EQ(has_mpu(), mpu_info.has_mpu, "%d");
+ TEST_EQ(mpu_is_unified(), mpu_info.mpu_is_unified, "%d");
+ return EC_SUCCESS;
+}
+
+test_static int reset_mpu(void)
+{
+ int i;
+
+ mpu_disable();
+
+ for (i = 0; i < mpu_info.num_mpu_regions; ++i) {
+ /*
+ * Disable all regions.
+ *
+ * We use the smallest possible size (32 bytes), but it
+ * doesn't really matter since the regions are disabled.
+ */
+ TEST_EQ(mpu_config_region(i, 0, 32, 0, 0), EC_SUCCESS, "%d");
+ }
+
+ mpu_enable();
+
+ return EC_SUCCESS;
+}
+
+test_static int test_mpu_update_region_valid_region(void)
+{
+ volatile char data __maybe_unused;
+
+ char * const ram_base = (char * const)CONFIG_RAM_BASE;
+ const uint8_t size_bit = 5;
+ uint16_t mpu_attr = MPU_ATTR_NO_NO;
+
+ /*
+ * Initial read should work. MPU is not protecting the given address.
+ */
+ data = ram_base[0];
+
+ TEST_EQ(mpu_update_region(0, (uint32_t)ram_base, size_bit, mpu_attr, 1,
+ 0),
+ EC_SUCCESS, "%d");
+
+ /* This panics with a data violation at CONFIG_RAM_BASE:
+ *
+ * Data access violation, mfar = <CONFIG_RAM_BASE>
+ */
+ data = ram_base[0];
+
+ return EC_SUCCESS;
+}
+
+test_static int test_mpu_update_region_invalid_region(void)
+{
+ /* Test invalid region */
+ TEST_EQ(mpu_update_region(mpu_info.num_mpu_regions, 0x8020000, 17,
+ 0x1000, 1, 0),
+ -EC_ERROR_INVAL, "%d");
+ return EC_SUCCESS;
+}
+
+test_static int test_mpu_update_region_invalid_alignment(void)
+{
+ /*
+ * Test size that is not aligned to address.
+ */
+ const uint32_t addr = 0x20000;
+ const uint32_t size = 0x40000;
+ const uint32_t size_bit = 18;
+
+ TEST_EQ(size, BIT(size_bit), "%d");
+ TEST_EQ(reset_mpu(), EC_SUCCESS, "%d");
+ TEST_EQ(mpu_update_region(0, addr, size_bit, 0, 1, 0), -EC_ERROR_INVAL,
+ "%d");
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ ccprintf("Running MPU test\n");
+ RUN_TEST(reset_mpu);
+ RUN_TEST(test_mpu_info);
+ RUN_TEST(reset_mpu);
+ RUN_TEST(test_mpu_update_region_invalid_region);
+ RUN_TEST(reset_mpu);
+ RUN_TEST(test_mpu_update_region_invalid_alignment);
+ RUN_TEST(reset_mpu);
+ RUN_TEST(test_mpu_update_region_valid_region);
+ RUN_TEST(reset_mpu);
+ test_print_result();
+}