feat(mt8188): update SVP region ID and permission
- Update SVP EMI-MPU region ID from 4 to 5 for resolving
the issue of duplicate region ID used by the DSP.
- For SVP EMI-MPU region, modify domain 1 and domain 6 APC from
FORBIDDEN to SEC_RW.
- Correct the calculation for the end address of SVP DRAM region.
- Add region 0 and region 1 for BL31 and BL32 memory protection.
- Add clear region protection API for SVP region.
Change-Id: Iaea348ad9be629e8a81cf579b148c6df66015b42
Signed-off-by: Haohao Sun <haohao.sun@mediatek.corp-partner.google.com>
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
index ef7134c..329a45e 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -18,7 +18,7 @@
#define FORBIDDEN (5)
#define SEC_R_NSEC_RW (6)
-#define LOCK (1)
+#define LOCK (1UL)
#define UNLOCK (0)
#if (EMI_MPU_DGROUP_NUM == 1)
@@ -69,6 +69,7 @@
int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
uint64_t zone_info);
int emi_mpu_set_protection(struct emi_region_info_t *region_info);
+int emi_mpu_clear_protection(unsigned int region);
void set_emi_mpu_regions(void);
int set_apu_emi_mpu_region(void);
#endif
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
index 8810be3..1e732f0 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -39,13 +39,13 @@
}
#if ENABLE_EMI_MPU_SW_LOCK
- if (region_lock_state[region] == 1) {
+ if (region_lock_state[region] == LOCK) {
WARN("invalid region\n");
return -1;
}
if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
- region_lock_state[region] = 1;
+ region_lock_state[region] = LOCK;
}
apc &= EMI_MPU_APC_SW_LOCK_MASK;
@@ -73,6 +73,50 @@
return 0;
}
+int emi_mpu_clear_protection(unsigned int region)
+{
+ unsigned int dgroup;
+
+ if (region >= EMI_MPU_REGION_NUM) {
+ WARN("invalid region number\n");
+ return -1;
+ }
+
+#if ENABLE_EMI_MPU_SW_LOCK
+ if (region_lock_state[region] == LOCK) {
+ WARN("SW:region is locked\n");
+ return -1;
+ }
+#endif
+ if (mmio_read_32(EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+ WARN("HW:EMI-MPU region is locked\n");
+ return -1;
+ }
+
+#if defined(SUB_EMI_MPU_BASE)
+ if (mmio_read_32(SUB_EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+ WARN("HW:SUB EMI-MPU region is locked\n");
+ return -1;
+ }
+#endif
+
+ for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+ mmio_write_32(EMI_MPU_APC(region, dgroup), 0x0);
+
+ mmio_write_32(EMI_MPU_SA(region), 0x0);
+ mmio_write_32(EMI_MPU_EA(region), 0x0);
+
+#if defined(SUB_EMI_MPU_BASE)
+ for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+ mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), 0x0);
+
+ mmio_write_32(SUB_EMI_MPU_SA(region), 0);
+ mmio_write_32(SUB_EMI_MPU_EA(region), 0);
+#endif
+ return 0;
+}
+
+
static void dump_emi_mpu_regions(void)
{
int region, i;
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index 7de6620..f7ed5e6 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -14,11 +14,33 @@
{
struct emi_region_info_t region_info;
+ /* BL31 address */
+ region_info.start = TZRAM_BASE;
+ region_info.end = TZRAM_BASE + TZRAM_SIZE - 1;
+ region_info.region = BL31_EMI_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+ emi_mpu_set_protection(®ion_info);
+
+ /* BL32 address */
+ region_info.start = BL32_REGION_BASE;
+ region_info.end = BL32_REGION_BASE + BL32_REGION_SIZE - 1;
+ region_info.region = BL32_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
+ emi_mpu_set_protection(®ion_info);
+
/* SCP core0 DRAM */
- region_info.start = 0x50000000ULL;
- region_info.end = 0x507FFFFFULL;
- region_info.region = 2;
- SET_ACCESS_PERMISSION(region_info.apc, 1,
+ region_info.start = SCP_CORE0_REGION_BASE;
+ region_info.end = SCP_CORE0_REGION_BASE + SCP_CORE0_REGION_SIZE - 1;
+ region_info.region = SCP_CORE0_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, LOCK,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -26,10 +48,10 @@
emi_mpu_set_protection(®ion_info);
/* SCP core1 DRAM */
- region_info.start = 0x70000000ULL;
- region_info.end = 0x79FFFFFFULL;
- region_info.region = 3;
- SET_ACCESS_PERMISSION(region_info.apc, 1,
+ region_info.start = SCP_CORE1_REGION_BASE;
+ region_info.end = SCP_CORE1_REGION_BASE + SCP_CORE1_REGION_SIZE - 1;
+ region_info.region = SCP_CORE1_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, LOCK,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -37,10 +59,10 @@
emi_mpu_set_protection(®ion_info);
/* DSP protect address */
- region_info.start = 0x60000000ULL;
- region_info.end = 0x610FFFFFULL;
- region_info.region = 4;
- SET_ACCESS_PERMISSION(region_info.apc, 1,
+ region_info.start = DSP_PROTECT_REGION_BASE;
+ region_info.end = DSP_PROTECT_REGION_BASE + DSP_PROTECT_REGION_SIZE - 1;
+ region_info.region = DSP_PROTECT_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, LOCK,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
@@ -48,10 +70,10 @@
emi_mpu_set_protection(®ion_info);
/* All default settings */
- region_info.start = 0x40000000ULL;
- region_info.end = 0x1FFFF0000ULL;
- region_info.region = 31;
- SET_ACCESS_PERMISSION(region_info.apc, 1,
+ region_info.start = DRAM_START_ADDR;
+ region_info.end = DRAM_START_ADDR + DRAM_MAX_SIZE - 1;
+ region_info.region = ALL_DEFAULT_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, LOCK,
FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN,
@@ -65,7 +87,7 @@
region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA;
region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1;
- region_info.region = APUSYS_SEC_BUF_EMI_REGION;
+ region_info.region = APUSYS_SEC_BUF_EMI_REGION_ID;
SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -86,12 +108,18 @@
return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
}
+static inline uint32_t get_decoded_set_clear_info(uint32_t info)
+{
+ return (info & 0x0000FFFF);
+}
+
int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
uint64_t zone_info)
{
uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
struct emi_region_info_t region_info;
enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
+ uint32_t is_set = get_decoded_set_clear_info(zone_info);
INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
encoded_addr, zone_size, zone_info);
@@ -101,17 +129,21 @@
return MTK_SIP_E_INVALID_PARAM;
}
- /* SVP DRAM */
- region_info.start = phys_addr;
- region_info.end = phys_addr + zone_size;
- region_info.region = 4;
- SET_ACCESS_PERMISSION(region_info.apc, 1,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+ if (is_set > 0) {
+ /* SVP DRAM */
+ region_info.start = phys_addr;
+ region_info.end = phys_addr + zone_size - 1;
+ region_info.region = SVP_DRAM_REGION_ID;
+ SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, SEC_RW, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
- emi_mpu_set_protection(®ion_info);
+ emi_mpu_set_protection(®ion_info);
+ } else { /* clear region protection */
+ emi_mpu_clear_protection(SVP_DRAM_REGION_ID);
+ }
return 0;
}
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
index cc7f7f1..18acb9c 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -7,7 +7,7 @@
#ifndef EMI_MPU_PRIV_H
#define EMI_MPU_PRIV_H
-#define ENABLE_EMI_MPU_SW_LOCK (1)
+#define ENABLE_EMI_MPU_SW_LOCK (0)
#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x000)
#define EMI_MPU_DBG (EMI_MPU_BASE + 0x004)
@@ -38,13 +38,34 @@
#define EMI_MPU_DOMAIN_NUM (16)
#define EMI_MPU_REGION_NUM (32)
#define EMI_MPU_ALIGN_BITS (16)
-#define DRAM_OFFSET (0x40000000 >> EMI_MPU_ALIGN_BITS)
+#define DRAM_START_ADDR (0x40000000ULL)
+#define DRAM_OFFSET (DRAM_START_ADDR >> EMI_MPU_ALIGN_BITS)
+#define DRAM_MAX_SIZE (0x200000000ULL)
+#define BL32_REGION_BASE (0x43000000ULL)
+#define BL32_REGION_SIZE (0x4600000ULL)
+#define SCP_CORE0_REGION_BASE (0x50000000ULL)
+#define SCP_CORE0_REGION_SIZE (0x800000ULL)
+#define SCP_CORE1_REGION_BASE (0x70000000ULL)
+#define SCP_CORE1_REGION_SIZE (0xa000000ULL)
+#define DSP_PROTECT_REGION_BASE (0x60000000ULL)
+#define DSP_PROTECT_REGION_SIZE (0x1100000ULL)
#define EMI_MPU_DGROUP_NUM (EMI_MPU_DOMAIN_NUM / 8)
/* APU EMI MPU Setting */
-#define APUSYS_SEC_BUF_EMI_REGION (21)
#define APUSYS_SEC_BUF_PA (0x55000000)
#define APUSYS_SEC_BUF_SZ (0x100000)
+enum region_ids {
+ BL31_EMI_REGION_ID = 0,
+ BL32_REGION_ID,
+ SCP_CORE0_REGION_ID,
+ SCP_CORE1_REGION_ID,
+ DSP_PROTECT_REGION_ID,
+ SVP_DRAM_REGION_ID,
+
+ APUSYS_SEC_BUF_EMI_REGION_ID = 21,
+
+ ALL_DEFAULT_REGION_ID = 31,
+};
#endif