diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:13:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:13:47 +0000 |
commit | 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 (patch) | |
tree | bcf648efac40ca6139842707f0eba5a4496a6dd2 /plat/mediatek/drivers/emi_mpu/emi_mpu_common.c | |
parent | Initial commit. (diff) | |
download | arm-trusted-firmware-102b0d2daa97dae68d3eed54d8fe37a9cc38a892.tar.xz arm-trusted-firmware-102b0d2daa97dae68d3eed54d8fe37a9cc38a892.zip |
Adding upstream version 2.8.0+dfsg.upstream/2.8.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | plat/mediatek/drivers/emi_mpu/emi_mpu_common.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c new file mode 100644 index 0000000..27b2b07 --- /dev/null +++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <emi_mpu.h> +#include <lib/mtk_init/mtk_init.h> + +#if ENABLE_EMI_MPU_SW_LOCK +static unsigned char region_lock_state[EMI_MPU_REGION_NUM]; +#endif + +#define EMI_MPU_START_MASK (0x00FFFFFF) +#define EMI_MPU_END_MASK (0x00FFFFFF) +#define EMI_MPU_APC_SW_LOCK_MASK (0x00FFFFFF) +#define EMI_MPU_APC_HW_LOCK_MASK (0x80FFFFFF) + +static int _emi_mpu_set_protection(unsigned int start, unsigned int end, + unsigned int apc) +{ + unsigned int dgroup; + unsigned int region; + + region = (start >> 24) & 0xFF; + start &= EMI_MPU_START_MASK; + dgroup = (end >> 24) & 0xFF; + end &= EMI_MPU_END_MASK; + + if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) { + WARN("invalid region, domain\n"); + return -1; + } + +#if ENABLE_EMI_MPU_SW_LOCK + if (region_lock_state[region] == 1) { + WARN("invalid region\n"); + return -1; + } + + if ((dgroup == 0) && ((apc >> 31) & 0x1)) { + region_lock_state[region] = 1; + } + + apc &= EMI_MPU_APC_SW_LOCK_MASK; +#else + apc &= EMI_MPU_APC_HW_LOCK_MASK; +#endif + + if ((start >= DRAM_OFFSET) && (end >= start)) { + start -= DRAM_OFFSET; + end -= DRAM_OFFSET; + } else { + WARN("invalid range\n"); + return -1; + } + + mmio_write_32(EMI_MPU_SA(region), start); + mmio_write_32(EMI_MPU_EA(region), end); + mmio_write_32(EMI_MPU_APC(region, dgroup), apc); + +#if defined(SUB_EMI_MPU_BASE) + mmio_write_32(SUB_EMI_MPU_SA(region), start); + mmio_write_32(SUB_EMI_MPU_EA(region), end); + mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc); +#endif + return 0; +} + +static void dump_emi_mpu_regions(void) +{ + int region, i; + + /* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */ + for (region = 0; region < 8; ++region) { + INFO("region %d:\n", region); + INFO("\tsa: 0x%x, ea: 0x%x\n", + mmio_read_32(EMI_MPU_SA(region)), mmio_read_32(EMI_MPU_EA(region))); + + for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i) { + INFO("\tapc%d: 0x%x\n", i, mmio_read_32(EMI_MPU_APC(region, i))); + } + } +} + +int emi_mpu_set_protection(struct emi_region_info_t *region_info) +{ + unsigned int start, end; + int i; + + if (region_info->region >= EMI_MPU_REGION_NUM) { + WARN("invalid region\n"); + return -1; + } + + start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) | + (region_info->region << 24); + + for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) { + end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) | (i << 24); + + if (_emi_mpu_set_protection(start, end, region_info->apc[i]) < 0) { + WARN("Failed to set emi mpu protection(%d, %d, %d)\n", + start, end, region_info->apc[i]); + } + } + + return 0; +} + +int emi_mpu_init(void) +{ + INFO("[%s] emi mpu initialization\n", __func__); + + set_emi_mpu_regions(); + dump_emi_mpu_regions(); + + return 0; +} +MTK_PLAT_SETUP_0_INIT(emi_mpu_init); |