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>
This commit is contained in:
parent
67665bb554
commit
4116f1ae69
|
@ -15,6 +15,7 @@ test-list-y=\
|
|||
aes \
|
||||
compile_time_macros \
|
||||
crc32 \
|
||||
mpu \
|
||||
mutex \
|
||||
pingpong \
|
||||
rollback \
|
||||
|
|
|
@ -16,6 +16,7 @@ test-list-y=\
|
|||
aes \
|
||||
compile_time_macros \
|
||||
crc32 \
|
||||
mpu \
|
||||
mutex \
|
||||
pingpong \
|
||||
rollback \
|
||||
|
|
|
@ -13,6 +13,7 @@ test-list-y=\
|
|||
aes \
|
||||
compile_time_macros \
|
||||
crc32 \
|
||||
mpu \
|
||||
mutex \
|
||||
pingpong \
|
||||
rollback \
|
||||
|
|
|
@ -13,6 +13,7 @@ test-list-y=\
|
|||
aes \
|
||||
compile_time_macros \
|
||||
crc32 \
|
||||
mpu \
|
||||
mutex \
|
||||
pingpong \
|
||||
rollback \
|
||||
|
|
|
@ -65,6 +65,9 @@ int mpu_update_region(uint8_t region, uint32_t addr, uint8_t size_bit,
|
|||
if (!is_aligned(addr, BIT(size_bit)))
|
||||
return -EC_ERROR_INVAL;
|
||||
|
||||
if (region >= mpu_num_regions())
|
||||
return -EC_ERROR_INVAL;
|
||||
|
||||
asm volatile("isb; dsb;");
|
||||
|
||||
MPU_NUMBER = region;
|
||||
|
|
|
@ -150,6 +150,7 @@ motion_lid-y=motion_lid.o
|
|||
motion_sense_fifo-y=motion_sense_fifo.o
|
||||
online_calibration-y=online_calibration.o
|
||||
kasa-y=kasa.o
|
||||
mpu-y=mpu.o
|
||||
mutex-y=mutex.o
|
||||
newton_fit-y=newton_fit.o
|
||||
pingpong-y=pingpong.o
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* See CONFIG_TASK_LIST in config.h for details.
|
||||
*/
|
||||
#define CONFIG_TEST_TASK_LIST /* no tasks */
|
Loading…
Reference in New Issue