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