1 /*
2 * Copyright (c) 2020, 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 <lib/mmio.h>
10
11 /*
12 * emi_mpu_set_region_protection: protect a region.
13 * @start: start address of the region
14 * @end: end address of the region
15 * @access_permission: EMI MPU access permission
16 * Return 0 for success, otherwise negative status code.
17 */
_emi_mpu_set_protection(unsigned long start,unsigned long end,unsigned int apc)18 static int _emi_mpu_set_protection(
19 unsigned long start, unsigned long end,
20 unsigned int apc)
21 {
22 unsigned int dgroup;
23 unsigned int region;
24
25 region = (start >> 24) & 0xFF;
26 start &= 0x00FFFFFF;
27 dgroup = (end >> 24) & 0xFF;
28 end &= 0x00FFFFFF;
29
30 if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
31 WARN("Region:%u or dgroup:%u is wrong!\n", region, dgroup);
32 return -1;
33 }
34
35 apc &= 0x80FFFFFF;
36
37 if ((start >= DRAM_OFFSET) && (end >= start)) {
38 start -= DRAM_OFFSET;
39 end -= DRAM_OFFSET;
40 } else {
41 WARN("start:0x%lx or end:0x%lx address is wrong!\n",
42 start, end);
43 return -2;
44 }
45
46 mmio_write_32(EMI_MPU_SA(region), start);
47 mmio_write_32(EMI_MPU_EA(region), end);
48 mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
49
50 return 0;
51 }
52
dump_emi_mpu_regions(void)53 void dump_emi_mpu_regions(void)
54 {
55 unsigned long apc[EMI_MPU_DGROUP_NUM], sa, ea;
56
57 int region, i;
58
59 /* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */
60 for (region = 0; region < 8; ++region) {
61 for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i)
62 apc[i] = mmio_read_32(EMI_MPU_APC(region, i));
63 sa = mmio_read_32(EMI_MPU_SA(region));
64 ea = mmio_read_32(EMI_MPU_EA(region));
65
66 WARN("region %d:\n", region);
67 WARN("\tsa:0x%lx, ea:0x%lx, apc0: 0x%lx apc1: 0x%lx\n",
68 sa, ea, apc[0], apc[1]);
69 }
70 }
71
emi_mpu_set_protection(struct emi_region_info_t * region_info)72 int emi_mpu_set_protection(struct emi_region_info_t *region_info)
73 {
74 unsigned long start, end;
75 int i;
76
77 if (region_info->region >= EMI_MPU_REGION_NUM)
78 return -1;
79
80 start = (unsigned long)(region_info->start >> EMI_MPU_ALIGN_BITS) |
81 (region_info->region << 24);
82
83 for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
84 end = (unsigned long)(region_info->end >> EMI_MPU_ALIGN_BITS) |
85 (i << 24);
86 _emi_mpu_set_protection(start, end, region_info->apc[i]);
87 }
88
89 return 0;
90 }
91
emi_mpu_init(void)92 void emi_mpu_init(void)
93 {
94 struct emi_region_info_t region_info;
95
96 /* reserve region 0 for future use */
97
98 /* PCI-e protect address(64MB) */
99 region_info.start = 0xC0000000ULL;
100 region_info.end = 0xC3FF0000ULL;
101 region_info.region = 1;
102 SET_ACCESS_PERMISSION(region_info.apc, 1,
103 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
104 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
105 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
106 FORBIDDEN, FORBIDDEN, NO_PROT, NO_PROT);
107 emi_mpu_set_protection(®ion_info);
108
109 /* SCP protect address */
110 region_info.start = 0x50000000ULL;
111 region_info.end = 0x513F0000ULL;
112 region_info.region = 2;
113 SET_ACCESS_PERMISSION(region_info.apc, 1,
114 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
115 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
116 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
117 NO_PROT, FORBIDDEN, FORBIDDEN, NO_PROT);
118 emi_mpu_set_protection(®ion_info);
119
120 /* DSP protect address */
121 region_info.start = 0x40000000ULL; /* dram base addr */
122 region_info.end = 0x1FFFF0000ULL;
123 region_info.region = 3;
124 SET_ACCESS_PERMISSION(region_info.apc, 1,
125 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
126 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
127 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
128 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
129 emi_mpu_set_protection(®ion_info);
130
131 /* Forbidden All */
132 region_info.start = 0x40000000ULL; /* dram base addr */
133 region_info.end = 0x1FFFF0000ULL;
134 region_info.region = 4;
135 SET_ACCESS_PERMISSION(region_info.apc, 1,
136 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
137 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
138 FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
139 FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
140 emi_mpu_set_protection(®ion_info);
141
142 dump_emi_mpu_regions();
143 }
144
145