mediatek: mt8183: add EMI MPU driver for DRAM protection
authorkenny liang <kenny.liang@mediatek.com>
Fri, 23 Aug 2019 07:50:58 +0000 (15:50 +0800)
committerkenny liang <kenny.liang@mediatek.com>
Thu, 3 Oct 2019 02:46:09 +0000 (10:46 +0800)
Add EMI MPU driver for DRAM protection.

Signed-off-by: kenny liang <kenny.liang@mediatek.com>
Change-Id: I0355e084184b5396ad8ac99fff6ef9d050fb5e96

plat/mediatek/mt8183/bl31_plat_setup.c
plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c [new file with mode: 0644]
plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.h [new file with mode: 0644]
plat/mediatek/mt8183/include/platform_def.h
plat/mediatek/mt8183/platform.mk

index 75694964d37875dfa00edebf9271786e7d8fbbab..8204d771706c732f9809f769217307a2cc5d1608 100644 (file)
@@ -9,6 +9,7 @@
 #include <common/bl_common.h>
 #include <common/desc_image_load.h>
 #include <devapc.h>
+#include <emi_mpu.h>
 #include <plat/common/common_def.h>
 #include <drivers/console.h>
 #include <common/debug.h>
@@ -138,6 +139,8 @@ void bl31_platform_setup(void)
 {
        devapc_init();
 
+       emi_mpu_init();
+
        platform_setup_cpu();
        generic_delay_timer_init();
 
diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
new file mode 100644 (file)
index 0000000..64d8548
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <emi_mpu.h>
+
+int is_4GB(void)
+{
+       return 0; /* 8183 doesn't use 4GB */
+}
+
+/*
+ * emi_mpu_set_region_protection: protect a region.
+ * @start: start address of the region
+ * @end: end address of the region
+ * @region: EMI MPU region id
+ * @access_permission: EMI MPU access permission
+ * Return 0 for success, otherwise negative status code.
+ */
+int emi_mpu_set_region_protection(
+       unsigned long start, unsigned long end,
+       int region,
+       unsigned int access_permission)
+{
+       int ret = 0;
+
+       if (end <= start) {
+               ERROR("[EMI][MTEE][MPU] Invalid address!.\n");
+               return -1;
+       }
+
+       if (is_4GB()) {
+               /* 4GB mode: emi_addr = phy_addr & 0xffff */
+               start = EMI_PHY_OFFSET & 0xffff;
+               end = EMI_PHY_OFFSET & 0xffff;
+       } else {
+               /* non-4GB mode: emi_addr = phy_addr - MEM_OFFSET */
+               start = start - EMI_PHY_OFFSET;
+               end = end - EMI_PHY_OFFSET;
+       }
+
+       /*Address 64KB alignment*/
+       start = start >> 16;
+       end = end >> 16;
+
+       switch (region) {
+       case 0:
+               mmio_write_32(EMI_MPU_APC0, 0);
+               mmio_write_32(EMI_MPU_SA0, start);
+               mmio_write_32(EMI_MPU_EA0, end);
+               mmio_write_32(EMI_MPU_APC0, access_permission);
+               break;
+
+       case 1:
+               mmio_write_32(EMI_MPU_APC1, 0);
+               mmio_write_32(EMI_MPU_SA1, start);
+               mmio_write_32(EMI_MPU_EA1, end);
+               mmio_write_32(EMI_MPU_APC1, access_permission);
+               break;
+
+       case 2:
+               mmio_write_32(EMI_MPU_APC2, 0);
+               mmio_write_32(EMI_MPU_SA2, start);
+               mmio_write_32(EMI_MPU_EA2, end);
+               mmio_write_32(EMI_MPU_APC2, access_permission);
+               break;
+
+       case 3:
+               mmio_write_32(EMI_MPU_APC3, 0);
+               mmio_write_32(EMI_MPU_SA3, start);
+               mmio_write_32(EMI_MPU_EA3, end);
+               mmio_write_32(EMI_MPU_APC3, access_permission);
+               break;
+
+       case 4:
+               mmio_write_32(EMI_MPU_APC4, 0);
+               mmio_write_32(EMI_MPU_SA4, start);
+               mmio_write_32(EMI_MPU_EA4, end);
+               mmio_write_32(EMI_MPU_APC4, access_permission);
+               break;
+
+       case 5:
+               mmio_write_32(EMI_MPU_APC5, 0);
+               mmio_write_32(EMI_MPU_SA5, start);
+               mmio_write_32(EMI_MPU_EA5, end);
+               mmio_write_32(EMI_MPU_APC5, access_permission);
+               break;
+
+       case 6:
+               mmio_write_32(EMI_MPU_APC6, 0);
+               mmio_write_32(EMI_MPU_SA6, start);
+               mmio_write_32(EMI_MPU_EA6, end);
+               mmio_write_32(EMI_MPU_APC6, access_permission);
+               break;
+
+       case 7:
+               mmio_write_32(EMI_MPU_APC7, 0);
+               mmio_write_32(EMI_MPU_SA7, start);
+               mmio_write_32(EMI_MPU_EA7, end);
+               mmio_write_32(EMI_MPU_APC7, access_permission);
+               break;
+
+       default:
+               ret = -1;
+               break;
+       }
+
+       return ret;
+}
+
+void dump_emi_mpu_regions(void)
+{
+       unsigned int apc, sa, ea;
+       unsigned int apc_addr = EMI_MPU_APC0;
+       unsigned int sa_addr = EMI_MPU_SA0;
+       unsigned int ea_addr = EMI_MPU_EA0;
+       int i;
+
+       for (i = 0; i < 8; ++i) {
+               apc = mmio_read_32(apc_addr + i * 4);
+               sa = mmio_read_32(sa_addr + i * 4);
+               ea = mmio_read_32(ea_addr + i * 4);
+               WARN("region %d:\n", i);
+               WARN("\tapc:0x%x, sa:0x%x, ea:0x%x\n", apc, sa, ea);
+       }
+}
+
+void emi_mpu_init(void)
+{
+       /* Set permission */
+       emi_mpu_set_region_protection(0x40000000UL, 0x4FFFFFFFUL, 0,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0x50000000UL, 0x528FFFFFUL, 1,
+                               (FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0x60000000UL, 0x7FFFFFFFUL, 3,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0x80000000UL, 0x9FFFFFFFUL, 4,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0xA0000000UL, 0xBFFFFFFFUL, 5,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0xC0000000UL, 0xDFFFFFFFUL, 6,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       emi_mpu_set_region_protection(0xE0000000UL, 0xFFFFFFFFUL, 7,
+                               (FORBIDDEN << 3 | FORBIDDEN << 6));
+       dump_emi_mpu_regions();
+}
+
diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.h
new file mode 100644 (file)
index 0000000..b67ea56
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __EMI_MPU_H
+#define __EMI_MPU_H
+
+#include <platform_def.h>
+
+#define EMI_MPUP               (EMI_BASE + 0x01D8)
+#define EMI_MPUQ               (EMI_BASE + 0x01E0)
+#define EMI_MPUR               (EMI_BASE + 0x01E8)
+#define EMI_MPUS               (EMI_BASE + 0x01F0)
+#define EMI_MPUT               (EMI_BASE + 0x01F8)
+#define EMI_MPUY               (EMI_BASE + 0x0220)
+#define EMI_MPU_CTRL   (EMI_MPU_BASE + 0x0000)
+#define EMI_MPUD0_ST   (EMI_BASE + 0x0160)
+#define EMI_MPUD1_ST   (EMI_BASE + 0x0164)
+#define EMI_MPUD2_ST   (EMI_BASE + 0x0168)
+#define EMI_MPUD3_ST   (EMI_BASE + 0x016C)
+#define EMI_MPUD0_ST2  (EMI_BASE + 0x0200)
+#define EMI_MPUD1_ST2  (EMI_BASE + 0x0204)
+#define EMI_MPUD2_ST2  (EMI_BASE + 0x0208)
+#define EMI_MPUD3_ST2  (EMI_BASE + 0x020C)
+
+#define EMI_PHY_OFFSET (0x40000000UL)
+#define EIGHT_DOMAIN
+
+#define NO_PROTECTION  (0)
+#define SEC_RW                 (1)
+#define SEC_RW_NSEC_R  (2)
+#define SEC_RW_NSEC_W  (3)
+#define SEC_R_NSEC_R   (4)
+#define FORBIDDEN              (5)
+#define SEC_R_NSEC_RW  (6)
+
+#define SECURE_OS_MPU_REGION_ID        (0)
+#define ATF_MPU_REGION_ID              (1)
+
+#ifdef EIGHT_DOMAIN
+#define SET_ACCESS_PERMISSON(d7, d6, d5, d4, d3, d2, d1, d0) \
+       (((d7) << 21) | ((d6) << 18) | ((d5) << 15) | ((d4) << 12) \
+       | ((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0))
+#else
+#define SET_ACCESS_PERMISSON(d3, d2, d1, d0) \
+       (((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0))
+#endif
+
+//#define EMI_MPU_BASE                (0x1020E000U)
+
+#define EMI_MPU_SA0                 (EMI_MPU_BASE + 0x100)
+#define EMI_MPU_SA1                 (EMI_MPU_BASE + 0x104)
+#define EMI_MPU_SA2                 (EMI_MPU_BASE + 0x108)
+#define EMI_MPU_SA3                 (EMI_MPU_BASE + 0x10C)
+#define EMI_MPU_SA4                 (EMI_MPU_BASE + 0x110)
+#define EMI_MPU_SA5                 (EMI_MPU_BASE + 0x114)
+#define EMI_MPU_SA6                 (EMI_MPU_BASE + 0x118)
+#define EMI_MPU_SA7                 (EMI_MPU_BASE + 0x11C)
+
+#define EMI_MPU_EA0                 (EMI_MPU_BASE + 0x200)
+#define EMI_MPU_EA1                 (EMI_MPU_BASE + 0x204)
+#define EMI_MPU_EA2                 (EMI_MPU_BASE + 0x208)
+#define EMI_MPU_EA3                 (EMI_MPU_BASE + 0x20C)
+#define EMI_MPU_EA4                 (EMI_MPU_BASE + 0x210)
+#define EMI_MPU_EA5                 (EMI_MPU_BASE + 0x214)
+#define EMI_MPU_EA6                 (EMI_MPU_BASE + 0x218)
+#define EMI_MPU_EA7                 (EMI_MPU_BASE + 0x21C)
+
+#define EMI_MPU_APC0                (EMI_MPU_BASE + 0x300)
+#define EMI_MPU_APC1                (EMI_MPU_BASE + 0x304)
+#define EMI_MPU_APC2                (EMI_MPU_BASE + 0x308)
+#define EMI_MPU_APC3                (EMI_MPU_BASE + 0x30C)
+#define EMI_MPU_APC4                (EMI_MPU_BASE + 0x310)
+#define EMI_MPU_APC5                (EMI_MPU_BASE + 0x314)
+#define EMI_MPU_APC6                (EMI_MPU_BASE + 0x318)
+#define EMI_MPU_APC7                (EMI_MPU_BASE + 0x31C)
+
+#define EMI_MPU_CTRL_D0             (EMI_MPU_BASE + 0x800)
+#define EMI_MPU_CTRL_D1             (EMI_MPU_BASE + 0x804)
+#define EMI_MPU_CTRL_D2             (EMI_MPU_BASE + 0x808)
+#define EMI_MPU_CTRL_D3             (EMI_MPU_BASE + 0x80C)
+#define EMI_MPU_CTRL_D4             (EMI_MPU_BASE + 0x810)
+#define EMI_MPU_CTRL_D5             (EMI_MPU_BASE + 0x814)
+#define EMI_MPU_CTRL_D6             (EMI_MPU_BASE + 0x818)
+#define EMI_MPU_CTRL_D7             (EMI_MPU_BASE + 0x81C)
+
+#define EMI_MPU_MASK_D0             (EMI_MPU_BASE + 0x900)
+#define EMI_MPU_MASK_D1             (EMI_MPU_BASE + 0x904)
+#define EMI_MPU_MASK_D2             (EMI_MPU_BASE + 0x908)
+#define EMI_MPU_MASK_D3             (EMI_MPU_BASE + 0x90C)
+#define EMI_MPU_MASK_D4             (EMI_MPU_BASE + 0x910)
+#define EMI_MPU_MASK_D5             (EMI_MPU_BASE + 0x914)
+#define EMI_MPU_MASK_D6             (EMI_MPU_BASE + 0x918)
+#define EMI_MPU_MASK_D7             (EMI_MPU_BASE + 0x91C)
+
+int emi_mpu_set_region_protection(
+       unsigned long start, unsigned long end,
+       int region,
+       unsigned int access_permission);
+
+void dump_emi_mpu_regions(void);
+void emi_mpu_init(void);
+
+#endif  /* __EMI_MPU_H */
index 766e76659dc65f3413d4ea029d6fbfd8677bf7e4..0a1e038b3e4c685204ca0c243f951befc6449404 100644 (file)
@@ -25,6 +25,7 @@
 #define MCUCFG_BASE        0x0c530000
 #define CFG_SF_CTRL        0x0c510014
 #define CFG_SF_INI         0x0c510010
+#define EMI_BASE           (IO_PHYS + 0x219000)
 #define EMI_MPU_BASE       (IO_PHYS + 0x226000)
 #define TRNG_base          (IO_PHYS + 0x20f000)
 #define MT_GIC_BASE        0x0c000000
index 71aa44ef5ef9842790bf9931c4b2423153720522..597e18b90192fd3aae26ae6f5f18511bc440e2bb 100644 (file)
@@ -9,6 +9,7 @@ MTK_PLAT_SOC  := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
                  -I${MTK_PLAT_SOC}/drivers/                       \
+                 -I${MTK_PLAT_SOC}/drivers/emi_mpu/               \
                  -I${MTK_PLAT_SOC}/drivers/devapc/                \
                  -I${MTK_PLAT_SOC}/drivers/mcdi/                  \
                  -I${MTK_PLAT_SOC}/drivers/spmc/                  \
@@ -58,6 +59,7 @@ BL31_SOURCES    += common/desc_image_load.c                              \
                    ${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c             \
                    ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c                 \
                    ${MTK_PLAT_SOC}/drivers/uart/uart.c                   \
+                   ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c             \
                    ${MTK_PLAT_SOC}/plat_pm.c                             \
                    ${MTK_PLAT_SOC}/plat_topology.c                       \
                    ${MTK_PLAT_SOC}/plat_mt_gic.c                         \