1 /* 2 * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <emi_mpu.h> 9 #include <mtk_sip_svc.h> 10 11 #define MPU_PHYSICAL_ADDR_SHIFT_BITS (16) 12 13 void set_emi_mpu_regions(void) 14 { 15 struct emi_region_info_t region_info; 16 17 /* BL31 address */ 18 region_info.start = TZRAM_BASE; 19 region_info.end = TZRAM_BASE + TZRAM_SIZE - 1; 20 region_info.region = BL31_EMI_REGION_ID; 21 SET_ACCESS_PERMISSION(region_info.apc, LOCK, 22 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 23 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 24 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 25 FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW); 26 emi_mpu_set_protection(®ion_info); 27 28 #ifndef SPD_NONE 29 /* BL32 address */ 30 region_info.start = BL32_REGION_BASE; 31 region_info.end = BL32_REGION_BASE + BL32_REGION_SIZE - 1; 32 region_info.region = BL32_REGION_ID; 33 SET_ACCESS_PERMISSION(region_info.apc, LOCK, 34 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 35 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 36 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 37 FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW); 38 emi_mpu_set_protection(®ion_info); 39 #endif 40 41 /* SCP core0 DRAM */ 42 region_info.start = SCP_CORE0_REGION_BASE; 43 region_info.end = SCP_CORE0_REGION_BASE + SCP_CORE0_REGION_SIZE - 1; 44 region_info.region = SCP_CORE0_REGION_ID; 45 SET_ACCESS_PERMISSION(region_info.apc, LOCK, 46 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 47 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, 48 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 49 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION); 50 emi_mpu_set_protection(®ion_info); 51 52 /* SCP core1 DRAM */ 53 region_info.start = SCP_CORE1_REGION_BASE; 54 region_info.end = SCP_CORE1_REGION_BASE + SCP_CORE1_REGION_SIZE - 1; 55 region_info.region = SCP_CORE1_REGION_ID; 56 SET_ACCESS_PERMISSION(region_info.apc, LOCK, 57 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 58 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, 59 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 60 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION); 61 emi_mpu_set_protection(®ion_info); 62 63 /* DSP protect address */ 64 region_info.start = DSP_PROTECT_REGION_BASE; 65 region_info.end = DSP_PROTECT_REGION_BASE + DSP_PROTECT_REGION_SIZE - 1; 66 region_info.region = DSP_PROTECT_REGION_ID; 67 SET_ACCESS_PERMISSION(region_info.apc, LOCK, 68 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 69 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 70 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION, 71 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION); 72 emi_mpu_set_protection(®ion_info); 73 74 /* All default settings */ 75 region_info.start = DRAM_START_ADDR; 76 region_info.end = DRAM_START_ADDR + DRAM_MAX_SIZE - 1; 77 region_info.region = ALL_DEFAULT_REGION_ID; 78 SET_ACCESS_PERMISSION(region_info.apc, LOCK, 79 FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION, 80 NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION, 81 NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN, 82 NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION); 83 emi_mpu_set_protection(®ion_info); 84 } 85 86 int set_apu_emi_mpu_region(void) 87 { 88 struct emi_region_info_t region_info; 89 90 region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA; 91 region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1; 92 region_info.region = APUSYS_SEC_BUF_EMI_REGION_ID; 93 94 SET_ACCESS_PERMISSION(region_info.apc, UNLOCK, 95 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 96 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 97 NO_PROTECTION, FORBIDDEN, NO_PROTECTION, FORBIDDEN, 98 FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW); 99 100 return emi_mpu_set_protection(®ion_info); 101 } 102 103 static inline uint64_t get_decoded_phys_addr(uint64_t addr) 104 { 105 return (addr << MPU_PHYSICAL_ADDR_SHIFT_BITS); 106 } 107 108 static inline uint32_t get_decoded_zone_id(uint32_t info) 109 { 110 return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS); 111 } 112 113 static inline uint32_t get_decoded_set_clear_info(uint32_t info) 114 { 115 return (info & 0x0000FFFF); 116 } 117 118 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size, 119 uint64_t zone_info) 120 { 121 uint64_t phys_addr = get_decoded_phys_addr(encoded_addr); 122 struct emi_region_info_t region_info; 123 enum region_ids zone_id = get_decoded_zone_id(zone_info); 124 uint32_t is_set = get_decoded_set_clear_info(zone_info); 125 126 INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n", 127 encoded_addr, zone_size, zone_info); 128 129 if (zone_id < SVP_DRAM_REGION_ID_START || zone_id > SVP_DRAM_REGION_ID_END) { 130 ERROR("Invalid param %s, %d\n", __func__, __LINE__); 131 return MTK_SIP_E_INVALID_PARAM; 132 } 133 134 if (is_set > 0) { 135 /* SVP DRAM */ 136 region_info.start = phys_addr; 137 region_info.end = phys_addr + zone_size - 1; 138 region_info.region = zone_id; 139 SET_ACCESS_PERMISSION(region_info.apc, UNLOCK, 140 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 141 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN, 142 FORBIDDEN, SEC_RW, FORBIDDEN, FORBIDDEN, 143 FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW); 144 145 emi_mpu_set_protection(®ion_info); 146 } else { /* clear region protection */ 147 emi_mpu_clear_protection(zone_id); 148 } 149 150 return 0; 151 } 152