1 /* 2 * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <lib/mmio.h> 9 #include <emi_mpu.h> 10 11 int is_4GB(void) 12 { 13 return 0; /* 8183 doesn't use 4GB */ 14 } 15 16 /* 17 * emi_mpu_set_region_protection: protect a region. 18 * @start: start address of the region 19 * @end: end address of the region 20 * @region: EMI MPU region id 21 * @access_permission: EMI MPU access permission 22 * Return 0 for success, otherwise negative status code. 23 */ 24 int emi_mpu_set_region_protection( 25 unsigned long start, unsigned long end, 26 int region, 27 unsigned int access_permission) 28 { 29 int ret = 0; 30 31 if (end <= start) { 32 ERROR("[EMI][MTEE][MPU] Invalid address!.\n"); 33 return -1; 34 } 35 36 if (is_4GB()) { 37 /* 4GB mode: emi_addr = phy_addr & 0xffff */ 38 start = EMI_PHY_OFFSET & 0xffff; 39 end = EMI_PHY_OFFSET & 0xffff; 40 } else { 41 /* non-4GB mode: emi_addr = phy_addr - MEM_OFFSET */ 42 start = start - EMI_PHY_OFFSET; 43 end = end - EMI_PHY_OFFSET; 44 } 45 46 /*Address 64KB alignment*/ 47 start = start >> 16; 48 end = end >> 16; 49 50 switch (region) { 51 case 0: 52 mmio_write_32(EMI_MPU_APC0, 0); 53 mmio_write_32(EMI_MPU_SA0, start); 54 mmio_write_32(EMI_MPU_EA0, end); 55 mmio_write_32(EMI_MPU_APC0, access_permission); 56 break; 57 58 case 1: 59 mmio_write_32(EMI_MPU_APC1, 0); 60 mmio_write_32(EMI_MPU_SA1, start); 61 mmio_write_32(EMI_MPU_EA1, end); 62 mmio_write_32(EMI_MPU_APC1, access_permission); 63 break; 64 65 case 2: 66 mmio_write_32(EMI_MPU_APC2, 0); 67 mmio_write_32(EMI_MPU_SA2, start); 68 mmio_write_32(EMI_MPU_EA2, end); 69 mmio_write_32(EMI_MPU_APC2, access_permission); 70 break; 71 72 case 3: 73 mmio_write_32(EMI_MPU_APC3, 0); 74 mmio_write_32(EMI_MPU_SA3, start); 75 mmio_write_32(EMI_MPU_EA3, end); 76 mmio_write_32(EMI_MPU_APC3, access_permission); 77 break; 78 79 case 4: 80 mmio_write_32(EMI_MPU_APC4, 0); 81 mmio_write_32(EMI_MPU_SA4, start); 82 mmio_write_32(EMI_MPU_EA4, end); 83 mmio_write_32(EMI_MPU_APC4, access_permission); 84 break; 85 86 case 5: 87 mmio_write_32(EMI_MPU_APC5, 0); 88 mmio_write_32(EMI_MPU_SA5, start); 89 mmio_write_32(EMI_MPU_EA5, end); 90 mmio_write_32(EMI_MPU_APC5, access_permission); 91 break; 92 93 case 6: 94 mmio_write_32(EMI_MPU_APC6, 0); 95 mmio_write_32(EMI_MPU_SA6, start); 96 mmio_write_32(EMI_MPU_EA6, end); 97 mmio_write_32(EMI_MPU_APC6, access_permission); 98 break; 99 100 case 7: 101 mmio_write_32(EMI_MPU_APC7, 0); 102 mmio_write_32(EMI_MPU_SA7, start); 103 mmio_write_32(EMI_MPU_EA7, end); 104 mmio_write_32(EMI_MPU_APC7, access_permission); 105 break; 106 107 default: 108 ret = -1; 109 break; 110 } 111 112 return ret; 113 } 114 115 void dump_emi_mpu_regions(void) 116 { 117 unsigned int apc, sa, ea; 118 unsigned int apc_addr = EMI_MPU_APC0; 119 unsigned int sa_addr = EMI_MPU_SA0; 120 unsigned int ea_addr = EMI_MPU_EA0; 121 int i; 122 123 for (i = 0; i < 8; ++i) { 124 apc = mmio_read_32(apc_addr + i * 4); 125 sa = mmio_read_32(sa_addr + i * 4); 126 ea = mmio_read_32(ea_addr + i * 4); 127 WARN("region %d:\n", i); 128 WARN("\tapc:0x%x, sa:0x%x, ea:0x%x\n", apc, sa, ea); 129 } 130 } 131 132 void emi_mpu_init(void) 133 { 134 /* Set permission */ 135 emi_mpu_set_region_protection(0x40000000UL, 0x4FFFFFFFUL, 0, 136 (FORBIDDEN << 3 | FORBIDDEN << 6)); 137 emi_mpu_set_region_protection(0x50000000UL, 0x528FFFFFUL, 1, 138 (FORBIDDEN << 6)); 139 emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2, 140 (FORBIDDEN << 3 | FORBIDDEN << 6)); 141 emi_mpu_set_region_protection(0x60000000UL, 0xFFFFFFFFUL, 3, 142 (FORBIDDEN << 3 | FORBIDDEN << 6)); 143 emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4, 144 (FORBIDDEN << 3 | FORBIDDEN << 6)); 145 dump_emi_mpu_regions(); 146 } 147 148