11b17e34cSPenny Jan /*
23d4b6f93SAllen-KH Cheng * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
31b17e34cSPenny Jan *
41b17e34cSPenny Jan * SPDX-License-Identifier: BSD-3-Clause
51b17e34cSPenny Jan */
61b17e34cSPenny Jan
71b17e34cSPenny Jan #include <string.h>
81b17e34cSPenny Jan #include <common/debug.h>
91b17e34cSPenny Jan #include <lib/mmio.h>
101b17e34cSPenny Jan #include <emi_mpu.h>
111b17e34cSPenny Jan
121b17e34cSPenny Jan #if ENABLE_EMI_MPU_SW_LOCK
131b17e34cSPenny Jan static unsigned char region_lock_state[EMI_MPU_REGION_NUM];
141b17e34cSPenny Jan #endif
151b17e34cSPenny Jan
161b17e34cSPenny Jan #define EMI_MPU_START_MASK (0x00FFFFFF)
171b17e34cSPenny Jan #define EMI_MPU_END_MASK (0x00FFFFFF)
181b17e34cSPenny Jan #define EMI_MPU_APC_SW_LOCK_MASK (0x00FFFFFF)
191b17e34cSPenny Jan #define EMI_MPU_APC_HW_LOCK_MASK (0x80FFFFFF)
201b17e34cSPenny Jan
_emi_mpu_set_protection(unsigned int start,unsigned int end,unsigned int apc)211b17e34cSPenny Jan static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
221b17e34cSPenny Jan unsigned int apc)
231b17e34cSPenny Jan {
241b17e34cSPenny Jan unsigned int dgroup;
251b17e34cSPenny Jan unsigned int region;
261b17e34cSPenny Jan
271b17e34cSPenny Jan region = (start >> 24) & 0xFF;
281b17e34cSPenny Jan start &= EMI_MPU_START_MASK;
291b17e34cSPenny Jan dgroup = (end >> 24) & 0xFF;
301b17e34cSPenny Jan end &= EMI_MPU_END_MASK;
311b17e34cSPenny Jan
321b17e34cSPenny Jan if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
331b17e34cSPenny Jan WARN("invalid region, domain\n");
341b17e34cSPenny Jan return -1;
351b17e34cSPenny Jan }
361b17e34cSPenny Jan
371b17e34cSPenny Jan #if ENABLE_EMI_MPU_SW_LOCK
381b17e34cSPenny Jan if (region_lock_state[region] == 1) {
391b17e34cSPenny Jan WARN("invalid region\n");
401b17e34cSPenny Jan return -1;
411b17e34cSPenny Jan }
421b17e34cSPenny Jan
431b17e34cSPenny Jan if ((dgroup == 0U) && ((apc >> 31) & 0x1)) {
441b17e34cSPenny Jan region_lock_state[region] = 1;
451b17e34cSPenny Jan }
461b17e34cSPenny Jan
471b17e34cSPenny Jan apc &= EMI_MPU_APC_SW_LOCK_MASK;
481b17e34cSPenny Jan #else
491b17e34cSPenny Jan apc &= EMI_MPU_APC_HW_LOCK_MASK;
501b17e34cSPenny Jan #endif
511b17e34cSPenny Jan
521b17e34cSPenny Jan if ((start >= DRAM_OFFSET) && (end >= start)) {
531b17e34cSPenny Jan start -= DRAM_OFFSET;
541b17e34cSPenny Jan end -= DRAM_OFFSET;
551b17e34cSPenny Jan } else {
561b17e34cSPenny Jan WARN("invalid range\n");
571b17e34cSPenny Jan return -1;
581b17e34cSPenny Jan }
591b17e34cSPenny Jan
601b17e34cSPenny Jan mmio_write_32(EMI_MPU_SA(region), start);
611b17e34cSPenny Jan mmio_write_32(EMI_MPU_EA(region), end);
621b17e34cSPenny Jan mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
631b17e34cSPenny Jan
641b17e34cSPenny Jan #if defined(SUB_EMI_MPU_BASE)
651b17e34cSPenny Jan mmio_write_32(SUB_EMI_MPU_SA(region), start);
661b17e34cSPenny Jan mmio_write_32(SUB_EMI_MPU_EA(region), end);
671b17e34cSPenny Jan mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc);
681b17e34cSPenny Jan #endif
691b17e34cSPenny Jan return 0;
701b17e34cSPenny Jan }
711b17e34cSPenny Jan
emi_mpu_set_protection(struct emi_region_info_t * region_info)721b17e34cSPenny Jan int emi_mpu_set_protection(struct emi_region_info_t *region_info)
731b17e34cSPenny Jan {
741b17e34cSPenny Jan unsigned int start, end;
751b17e34cSPenny Jan int i;
761b17e34cSPenny Jan
771b17e34cSPenny Jan if (region_info->region >= EMI_MPU_REGION_NUM) {
781b17e34cSPenny Jan WARN("invalid region\n");
791b17e34cSPenny Jan return -1;
801b17e34cSPenny Jan }
811b17e34cSPenny Jan
821b17e34cSPenny Jan start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) |
831b17e34cSPenny Jan (region_info->region << 24);
841b17e34cSPenny Jan
851b17e34cSPenny Jan for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
861b17e34cSPenny Jan end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) | (i << 24);
871b17e34cSPenny Jan
881b17e34cSPenny Jan if (_emi_mpu_set_protection(start, end, region_info->apc[i]) < 0) {
891b17e34cSPenny Jan WARN("failed to set emi mpu protection(%d, %d, %d)\n",
901b17e34cSPenny Jan start, end, region_info->apc[i]);
911b17e34cSPenny Jan }
921b17e34cSPenny Jan }
931b17e34cSPenny Jan
941b17e34cSPenny Jan return 0;
951b17e34cSPenny Jan }
961b17e34cSPenny Jan
emi_mpu_init(void)971b17e34cSPenny Jan void emi_mpu_init(void)
981b17e34cSPenny Jan {
993d4b6f93SAllen-KH Cheng struct emi_region_info_t region_info;
1003d4b6f93SAllen-KH Cheng
1013d4b6f93SAllen-KH Cheng /* SCP DRAM */
1023d4b6f93SAllen-KH Cheng region_info.start = 0x50000000ULL;
1033d4b6f93SAllen-KH Cheng region_info.end = 0x5109FFFFULL;
1043d4b6f93SAllen-KH Cheng region_info.region = 2;
1053d4b6f93SAllen-KH Cheng SET_ACCESS_PERMISSION(region_info.apc, 1,
1063d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1073d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1088a998b5aSYidi Lin FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
1098a998b5aSYidi Lin FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
1103d4b6f93SAllen-KH Cheng emi_mpu_set_protection(®ion_info);
1113d4b6f93SAllen-KH Cheng
1123d4b6f93SAllen-KH Cheng /* DSP protect address */
1133d4b6f93SAllen-KH Cheng region_info.start = 0x60000000ULL; /* dram base addr */
1143d4b6f93SAllen-KH Cheng region_info.end = 0x610FFFFFULL;
1153d4b6f93SAllen-KH Cheng region_info.region = 3;
1163d4b6f93SAllen-KH Cheng SET_ACCESS_PERMISSION(region_info.apc, 1,
1173d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1183d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
119*28a8b738STinghan Shen FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN,
1203d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
1213d4b6f93SAllen-KH Cheng emi_mpu_set_protection(®ion_info);
1223d4b6f93SAllen-KH Cheng
1233d4b6f93SAllen-KH Cheng /* Forbidden All */
1243d4b6f93SAllen-KH Cheng region_info.start = 0x40000000ULL; /* dram base addr */
1253d4b6f93SAllen-KH Cheng region_info.end = 0x1FFFF0000ULL;
1263d4b6f93SAllen-KH Cheng region_info.region = 4;
1273d4b6f93SAllen-KH Cheng SET_ACCESS_PERMISSION(region_info.apc, 1,
1283d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1293d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1303d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
1313d4b6f93SAllen-KH Cheng FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
1323d4b6f93SAllen-KH Cheng emi_mpu_set_protection(®ion_info);
1331b17e34cSPenny Jan }
134