148 lines
3.5 KiB
C
148 lines
3.5 KiB
C
/*
|
|
* 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, 0xFFFFFFFFUL, 3,
|
|
(FORBIDDEN << 3 | FORBIDDEN << 6));
|
|
emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4,
|
|
(FORBIDDEN << 3 | FORBIDDEN << 6));
|
|
dump_emi_mpu_regions();
|
|
}
|
|
|