• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <plat/inc/bl.h>
18 #include <platform.h>
19 #include <stdbool.h>
20 #include <stdint.h>
21 #include <mpu.h>
22 #include <cpu.h>
23 
24 struct CortexMpu {
25     volatile uint32_t CTRL;
26     volatile uint32_t RNR;
27     volatile uint32_t RBAR;
28     volatile uint32_t RASR;
29 };
30 
31 #define MPU ((struct CortexMpu*)0xE000ED94UL)
32 
33 #define MPU_REG_ROM          0
34 #define MPU_REG_RAM          1
35 #define MPU_REG_NULL_PAGE    2
36 
37 
38 /* region type */
39 #define MPU_TYPE_DEVICE (0x10UL << 16)
40 #define MPU_TYPE_MEMORY (0x0FUL << 16)
41 
42 /* region execute priviledges */
43 #define MPU_BIT_XN      (1UL << 28) /* no execute */
44 
45 /* region access priviledges */
46 #define MPU_NA          (0UL << 24) /* S: no access   U: no access */
47 #define MPU_U_NA_S_RW   (1UL << 24) /* S: RW          U: no access */
48 #define MPU_U_RO_S_RW   (2UL << 24) /* S: RW          U: RO        */
49 #define MPU_RW          (3UL << 24) /* S: RW          U: RW        */
50 #define MPU_U_NA_S_RO   (5UL << 24) /* S: RO          U: no access */
51 #define MPU_U_RO_S_RO   (6UL << 24) /* S: RO          U: RO        */
52 
53 /* subregion mask (not used so all ones) */
54 #define MPU_SRD_BITS    0xFF00UL
55 #define MPU_BIT_ENABLE  1UL
56 
57 /* these define rom */
58 extern uint8_t __shared_end[];
59 extern uint8_t __ram_start[];
60 extern uint8_t __ram_end[];
61 
mpuRegionCfg(uint32_t regionNo,uint32_t start,uint32_t len,uint32_t attrs)62 static void mpuRegionCfg(uint32_t regionNo, uint32_t start, uint32_t len, uint32_t attrs) /* region will be rounded to acceptable boundaries (32B minimum, self-aligned) by GROWTH */
63 {
64     uint32_t proposedStart, proposedLen, lenVal = 1;
65     uint64_t intState;
66 
67     /* expand until it works */
68     do {
69         /* special case 4GB region */
70         if (lenVal == 32) {
71             proposedStart = 0;
72             break;
73         }
74 
75         proposedStart = start &~ ((1ULL << lenVal) - 1);
76         proposedLen = start + len - proposedStart;
77         if (proposedLen < 32)
78             proposedLen = 32;
79         lenVal = (proposedLen & (proposedLen - 1)) ? 32 - __builtin_clz(proposedLen) : 31 - __builtin_clz(proposedLen);
80 
81     } while (proposedStart & ((1ULL << lenVal) - 1));
82 
83     intState = cpuIntsOff();
84     asm volatile("dsb\nisb");
85 
86     MPU->RNR = regionNo;
87     MPU->RASR = 0; /* disable region before changing it */
88     MPU->RBAR = proposedStart;
89     MPU->RASR = MPU_SRD_BITS | MPU_BIT_ENABLE | attrs | (lenVal << 1);
90 
91     asm volatile("dsb\nisb");
92     cpuIntsRestore(intState);
93 }
94 
mpuCfgRom(bool allowSvcWrite)95 static void mpuCfgRom(bool allowSvcWrite)
96 {
97     mpuRegionCfg(MPU_REG_ROM, (uint32_t)&BL, __shared_end - (uint8_t*)&BL, MPU_TYPE_MEMORY | (allowSvcWrite ? MPU_U_RO_S_RW : MPU_U_RO_S_RO));
98 }
99 
mpuCfgRam(bool allowSvcExecute)100 static void mpuCfgRam(bool allowSvcExecute)
101 {
102     mpuRegionCfg(MPU_REG_RAM, (uint32_t)&__ram_start, __ram_end - __ram_start, MPU_TYPE_MEMORY | MPU_RW | (allowSvcExecute ? 0 : MPU_BIT_XN));
103 }
104 
105 
mpuStart(void)106 void mpuStart(void)
107 {
108     MPU->CTRL = 0x07; //MPU on, even during faults, supervisor default: allow, user default: default deny
109 
110     mpuCfgRom(false);
111     mpuCfgRam(false);
112     mpuRegionCfg(MPU_REG_NULL_PAGE, 0, 4096, MPU_TYPE_MEMORY | MPU_NA | MPU_BIT_XN);
113 }
114 
mpuAllowRamExecution(bool allowSvcExecute)115 void mpuAllowRamExecution(bool allowSvcExecute)
116 {
117     mpuCfgRam(allowSvcExecute);
118 }
119 
mpuAllowRomWrite(bool allowSvcWrite)120 void mpuAllowRomWrite(bool allowSvcWrite)
121 {
122     mpuCfgRom(allowSvcWrite);
123 }
124 
125