Commit 82d8d4ab authored by Soby Mathew's avatar Soby Mathew Committed by TrustedFirmware Code Review
Browse files

Merge changes I0355e084,I6a6dd1c0 into integration

* changes:
  mediatek: mt8183: add EMI MPU driver for DRAM protection
  mediatek: mt8183: add DEVAPC driver to control protection
parents 251b2643 f25ea7e3
......@@ -8,6 +8,8 @@
#include <arch_helpers.h>
#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>
......@@ -135,6 +137,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
******************************************************************************/
void bl31_platform_setup(void)
{
devapc_init();
emi_mpu_init();
platform_setup_cpu();
generic_delay_timer_init();
......
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <devapc.h>
#include <drivers/console.h>
#include <lib/mmio.h>
static void set_master_transaction(uint32_t master_index,
enum TRANSACTION transaction_type)
{
uintptr_t base;
uint32_t master_register_index;
uint32_t master_set_index;
uint32_t set_bit;
master_register_index = master_index / (MOD_NO_IN_1_DEVAPC * 2);
master_set_index = master_index % (MOD_NO_IN_1_DEVAPC * 2);
base = DEVAPC_INFRA_MAS_SEC_0 + master_register_index * 4;
set_bit = 0x1 << master_set_index;
if (transaction_type == SECURE_TRANSACTION)
mmio_setbits_32(base, set_bit);
else
mmio_clrbits_32(base, set_bit);
}
static void set_master_domain(uint32_t master_index, enum MASK_DOM domain)
{
uintptr_t base;
uint32_t domain_reg;
uint32_t domain_index;
uint32_t clr_bit;
uint32_t set_bit;
domain_reg = master_index / MASTER_MOD_NO_IN_1_DEVAPC;
domain_index = master_index % MASTER_MOD_NO_IN_1_DEVAPC;
clr_bit = 0xF << (4 * domain_index);
set_bit = domain << (4 * domain_index);
base = DEVAPC_INFRA_MAS_DOM_0 + domain_reg * 4;
mmio_clrsetbits_32(base, clr_bit, set_bit);
}
static void set_master_domain_remap_infra(enum MASK_DOM domain_emi_view,
enum MASK_DOM domain_infra_view)
{
uintptr_t base;
uint32_t clr_bit;
uint32_t set_bit;
if (domain_emi_view < DOMAIN_10) {
base = DEVAPC_INFRA_DOM_RMP_0;
clr_bit = 0x7 << (domain_emi_view * 3);
set_bit = domain_infra_view << (domain_emi_view * 3);
mmio_clrsetbits_32(base, clr_bit, set_bit);
} else if (domain_emi_view > DOMAIN_10) {
base = DEVAPC_INFRA_DOM_RMP_1;
domain_emi_view = domain_emi_view - DOMAIN_11;
clr_bit = 0x7 << (domain_emi_view * 3 + 1);
set_bit = domain_infra_view << (domain_emi_view * 3 + 1);
mmio_clrsetbits_32(base, clr_bit, set_bit);
} else {
base = DEVAPC_INFRA_DOM_RMP_0;
clr_bit = 0x3 << (domain_emi_view * 3);
set_bit = domain_infra_view << (domain_emi_view * 3);
mmio_clrsetbits_32(base, clr_bit, set_bit);
base = DEVAPC_INFRA_DOM_RMP_1;
set_bit = (domain_infra_view & 0x4) >> 2;
mmio_clrsetbits_32(base, 0x1, set_bit);
}
}
static void set_master_domain_remap_mm(enum MASK_DOM domain_emi_view,
enum MASK_DOM domain_mm_view)
{
uintptr_t base;
uint32_t clr_bit;
uint32_t set_bit;
base = DEVAPC_MM_DOM_RMP_0;
clr_bit = 0x3 << (domain_emi_view * 2);
set_bit = domain_mm_view << (domain_emi_view * 2);
mmio_clrsetbits_32(base, clr_bit, set_bit);
}
static void set_module_apc(enum DAPC_SLAVE_TYPE slave_type, uint32_t module,
enum MASK_DOM domain_num,
enum APC_ATTR permission_control)
{
uintptr_t base;
uint32_t apc_index;
uint32_t apc_set_index;
uint32_t clr_bit;
uint32_t set_bit;
apc_index = module / MOD_NO_IN_1_DEVAPC;
apc_set_index = module % MOD_NO_IN_1_DEVAPC;
clr_bit = 0x3 << (apc_set_index * 2);
set_bit = permission_control << (apc_set_index * 2);
if (slave_type == DAPC_INFRA_SLAVE && module <= SLAVE_INFRA_MAX_INDEX)
base = DEVAPC_INFRA_D0_APC_0 + domain_num * 0x100 +
apc_index * 4;
else if (slave_type == DAPC_MM_SLAVE && module <= SLAVE_MM_MAX_INDEX)
base = DEVAPC_MM_D0_APC_0 + domain_num * 0x100 + apc_index * 4;
else
return;
mmio_clrsetbits_32(base, clr_bit, set_bit);
}
static void set_default_master_transaction(void)
{
set_master_transaction(MASTER_SSPM, SECURE_TRANSACTION);
}
static void set_default_master_domain(void)
{
set_master_domain(MASTER_SCP, DOMAIN_1);
set_master_domain_remap_infra(DOMAIN_1, DOMAIN_1);
set_master_domain_remap_mm(DOMAIN_1, DOMAIN_1);
set_master_domain(MASTER_SPM, DOMAIN_2);
set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2);
set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2);
set_master_domain(MASTER_SSPM, DOMAIN_2);
set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2);
set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2);
}
static void set_default_slave_permission(void)
{
uint32_t module_index;
uint32_t infra_size;
uint32_t mm_size;
infra_size = sizeof(D_APC_INFRA_Devices) / sizeof(struct DEVICE_INFO);
mm_size = sizeof(D_APC_MM_Devices) / sizeof(struct DEVICE_INFO);
for (module_index = 0; module_index < infra_size; module_index++) {
if (D_APC_INFRA_Devices[module_index].d0_permission > 0) {
set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_0,
D_APC_INFRA_Devices[module_index].d0_permission);
}
if (D_APC_INFRA_Devices[module_index].d1_permission > 0) {
set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_1,
D_APC_INFRA_Devices[module_index].d1_permission);
}
if (D_APC_INFRA_Devices[module_index].d2_permission > 0) {
set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_2,
D_APC_INFRA_Devices[module_index].d2_permission);
}
}
for (module_index = 0; module_index < mm_size; module_index++) {
if (D_APC_MM_Devices[module_index].d0_permission > 0) {
set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_0,
D_APC_MM_Devices[module_index].d0_permission);
}
if (D_APC_MM_Devices[module_index].d1_permission > 0) {
set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_1,
D_APC_MM_Devices[module_index].d1_permission);
}
if (D_APC_MM_Devices[module_index].d2_permission > 0) {
set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_2,
D_APC_MM_Devices[module_index].d2_permission);
}
}
}
static void dump_devapc(void)
{
int i;
INFO("[DEVAPC] dump DEVAPC registers:\n");
for (i = 0; i < 13; i++) {
INFO("[DEVAPC] (INFRA)D0_APC_%d = 0x%x, "
"(INFRA)D1_APC_%d = 0x%x, "
"(INFRA)D2_APC_%d = 0x%x\n",
i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + i * 4),
i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x100 + i * 4),
i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x200 + i * 4));
}
for (i = 0; i < 9; i++) {
INFO("[DEVAPC] (MM)D0_APC_%d = 0x%x, "
"(MM)D1_APC_%d = 0x%x, "
"(MM)D2_APC_%d = 0x%x\n",
i, mmio_read_32(DEVAPC_MM_D0_APC_0 + i * 4),
i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x100 + i * 4),
i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x200 + i * 4));
}
for (i = 0; i < 4; i++) {
INFO("[DEVAPC] MAS_DOM_%d = 0x%x\n", i,
mmio_read_32(DEVAPC_INFRA_MAS_DOM_0 + i * 4));
}
INFO("[DEVAPC] MAS_SEC_0 = 0x%x\n",
mmio_read_32(DEVAPC_INFRA_MAS_SEC_0));
INFO("[DEVAPC] (INFRA)MAS_DOMAIN_REMAP_0 = 0x%x, "
"(INFRA)MAS_DOMAIN_REMAP_1 = 0x%x\n",
mmio_read_32(DEVAPC_INFRA_DOM_RMP_0),
mmio_read_32(DEVAPC_INFRA_DOM_RMP_1));
INFO("[DEVAPC] (MM)MAS_DOMAIN_REMAP_0 = 0x%x\n",
mmio_read_32(DEVAPC_MM_DOM_RMP_0));
}
void devapc_init(void)
{
mmio_write_32(DEVAPC_INFRA_APC_CON, 0x80000001);
mmio_write_32(DEVAPC_MM_APC_CON, 0x80000001);
mmio_write_32(DEVAPC_MD_APC_CON, 0x80000001);
set_default_master_transaction();
set_default_master_domain();
set_default_slave_permission();
dump_devapc();
}
This diff is collapsed.
/*
* 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();
}
/*
* 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 */
......@@ -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
......
......@@ -9,6 +9,8 @@ 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/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
......@@ -46,6 +48,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT}/common/params_setup.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/drivers/devapc/devapc.c \
${MTK_PLAT_SOC}/drivers/mcsi/mcsi.c \
${MTK_PLAT_SOC}/drivers/pmic/pmic.c \
${MTK_PLAT_SOC}/drivers/rtc/rtc.c \
......@@ -56,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 \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment