feat(plat/mediatek/mt8186): add EMI MPU basic driver
EMI MPU stands for external memory interface memory protect unit. MT8186 supports 32 regions and 16 domains. We add basic driver currently, and will add more settings for EMI MPU in next patch. TEST=build pass BUG=b:202871018 Signed-off-by: Penny Jan <penny.jan@mediatek.corp-partner.google.com> Change-Id: Ia9e5030164e40e060a05e8f91d2ac88258c2e98e
This commit is contained in:
parent
47833abd77
commit
1b17e34c5d
|
@ -15,6 +15,7 @@
|
|||
#include <lib/coreboot.h>
|
||||
|
||||
/* Platform Includes */
|
||||
#include <emi_mpu.h>
|
||||
#include <plat_params.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
|
@ -79,6 +80,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
|||
******************************************************************************/
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
emi_mpu_init();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 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>
|
||||
|
||||
#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 == 0U) && ((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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void emi_mpu_init(void)
|
||||
{
|
||||
/* TODO: more setting for EMI MPU. */
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 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 ENABLE_EMI_MPU_SW_LOCK 1
|
||||
|
||||
#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x000)
|
||||
#define EMI_MPU_DBG (EMI_MPU_BASE + 0x004)
|
||||
#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100)
|
||||
#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200)
|
||||
#define EMI_MPU_SA(region) (EMI_MPU_SA0 + (region * 4))
|
||||
#define EMI_MPU_EA(region) (EMI_MPU_EA0 + (region * 4))
|
||||
#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300)
|
||||
#define EMI_MPU_APC(region, dgroup) (EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
|
||||
#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800)
|
||||
#define EMI_MPU_CTRL_D(domain) (EMI_MPU_CTRL_D0 + (domain * 4))
|
||||
#define EMI_RG_MASK_D0 (EMI_MPU_BASE + 0x900)
|
||||
#define EMI_RG_MASK_D(domain) (EMI_RG_MASK_D0 + (domain * 4))
|
||||
#define EMI_MPU_START (0x000)
|
||||
#define EMI_MPU_END (0x93C)
|
||||
|
||||
#define SUB_EMI_MPU_CTRL (SUB_EMI_MPU_BASE + 0x000)
|
||||
#define SUB_EMI_MPU_DBG (SUB_EMI_MPU_BASE + 0x004)
|
||||
#define SUB_EMI_MPU_SA0 (SUB_EMI_MPU_BASE + 0x100)
|
||||
#define SUB_EMI_MPU_EA0 (SUB_EMI_MPU_BASE + 0x200)
|
||||
#define SUB_EMI_MPU_SA(region) (SUB_EMI_MPU_SA0 + (region * 4))
|
||||
#define SUB_EMI_MPU_EA(region) (SUB_EMI_MPU_EA0 + (region * 4))
|
||||
#define SUB_EMI_MPU_APC0 (SUB_EMI_MPU_BASE + 0x300)
|
||||
#define SUB_EMI_MPU_APC(region, dgroup) (SUB_EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
|
||||
#define SUB_EMI_MPU_CTRL_D0 (SUB_EMI_MPU_BASE + 0x800)
|
||||
#define SUB_EMI_MPU_CTRL_D(domain) (SUB_EMI_MPU_CTRL_D0 + (domain * 4))
|
||||
#define SUB_EMI_RG_MASK_D0 (SUB_EMI_MPU_BASE + 0x900)
|
||||
#define SUB_EMI_RG_MASK_D(domain) (SUB_EMI_RG_MASK_D0 + (domain * 4))
|
||||
|
||||
#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 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 LOCK 1
|
||||
#define UNLOCK 0
|
||||
|
||||
#define EMI_MPU_DGROUP_NUM (EMI_MPU_DOMAIN_NUM / 8)
|
||||
|
||||
#if (EMI_MPU_DGROUP_NUM == 1)
|
||||
#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \
|
||||
do { \
|
||||
apc_ary[1] = 0; \
|
||||
apc_ary[0] = \
|
||||
(((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \
|
||||
(((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \
|
||||
(((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \
|
||||
(((unsigned int) d1) << 3) | ((unsigned int) d0) | \
|
||||
((unsigned int) lock << 31); \
|
||||
} while (0)
|
||||
#elif (EMI_MPU_DGROUP_NUM == 2)
|
||||
#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \
|
||||
d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \
|
||||
do { \
|
||||
apc_ary[1] = \
|
||||
(((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) | \
|
||||
(((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) | \
|
||||
(((unsigned int) d11) << 9) | (((unsigned int) d10) << 6) | \
|
||||
(((unsigned int) d9) << 3) | ((unsigned int) d8); \
|
||||
apc_ary[0] = \
|
||||
(((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \
|
||||
(((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \
|
||||
(((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \
|
||||
(((unsigned int) d1) << 3) | ((unsigned int) d0) | \
|
||||
((unsigned int) lock << 31); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
struct emi_region_info_t {
|
||||
unsigned long long start;
|
||||
unsigned long long end;
|
||||
unsigned int region;
|
||||
unsigned int apc[EMI_MPU_DGROUP_NUM];
|
||||
};
|
||||
|
||||
void emi_mpu_init(void);
|
||||
|
||||
#endif
|
|
@ -29,6 +29,11 @@
|
|||
|
||||
#define UART_BAUDRATE 115200
|
||||
|
||||
/*******************************************************************************
|
||||
* EMI MPU related constants
|
||||
******************************************************************************/
|
||||
#define EMI_MPU_BASE (IO_PHYS + 0x0021B000)
|
||||
|
||||
/*******************************************************************************
|
||||
* System counter frequency related constants
|
||||
******************************************************************************/
|
||||
|
|
|
@ -8,6 +8,7 @@ MTK_PLAT := plat/mediatek
|
|||
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
|
||||
|
||||
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
|
||||
-I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
|
||||
-I${MTK_PLAT_SOC}/include/
|
||||
|
||||
include drivers/arm/gic/v3/gicv3.mk
|
||||
|
@ -30,6 +31,7 @@ BL31_SOURCES += common/desc_image_load.c \
|
|||
${MTK_PLAT_SOC}/aarch64/platform_common.c \
|
||||
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
|
||||
${MTK_PLAT_SOC}/bl31_plat_setup.c \
|
||||
${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \
|
||||
${MTK_PLAT_SOC}/plat_pm.c \
|
||||
${MTK_PLAT_SOC}/plat_topology.c
|
||||
|
||||
|
|
Loading…
Reference in New Issue