Browse Source
Add EMI MPU driver for DRAM protection. Signed-off-by: kenny liang <kenny.liang@mediatek.com> Change-Id: I0355e084184b5396ad8ac99fff6ef9d050fb5e96pull/1935/head
kenny liang
5 years ago
5 changed files with 265 additions and 0 deletions
@ -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(); |
|||
} |
|||
|
@ -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 */ |
Loading…
Reference in new issue