altos: Work on MAX6691 driver
[fw/altos] / src / stm / ao_mpu_stm.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <ao.h>
20 #include <ao_mpu.h>
21
22 static uint32_t stm_mpu_dregion;
23
24 void
25 ao_mpu_init(void)
26 {
27         uint32_t        region;
28
29         /* Check to see how many regions we have */
30         stm_mpu_dregion = (stm_mpu.typer >> STM_MPU_TYPER_DREGION) & STM_MPU_TYPER_DREGION_MASK;
31
32         /* No MPU at all */
33         if (stm_mpu_dregion == 0)
34                 return;
35
36         /* Disable MPU */
37         stm_mpu.cr = ((0 << STM_MPU_CR_PRIVDEFENA) |
38                       (0 << STM_MPU_CR_HFNMIENA) |
39                       (0 << STM_MPU_CR_ENABLE));
40
41         /* Disable all regions */
42         for (region = 0; region < stm_mpu_dregion; region++) {
43                 /* Set the base address and RNR value */
44                 stm_mpu.rbar = ((0 & (STM_MPU_RBAR_ADDR_MASK << STM_MPU_RBAR_ADDR)) |
45                                 (1 << STM_MPU_RBAR_VALID) |
46                                 (region << STM_MPU_RBAR_REGION));
47
48                 /* Disable this region */
49                 stm_mpu.rasr = 0;
50         }
51
52         region = 0;
53
54         /* Flash */
55         /* 0x00000000 - 0x1fffffff */
56         stm_mpu.rbar = (0x0000000 |
57                         (1 << STM_MPU_RBAR_VALID) |
58                         (region << STM_MPU_RBAR_REGION));
59
60         stm_mpu.rasr = ((0 << STM_MPU_RASR_XN) |
61                         (STM_MPU_RASR_AP_RO_RO << STM_MPU_RASR_AP) |
62                         (5 << STM_MPU_RASR_TEX) |
63                         (0 << STM_MPU_RASR_C) |
64                         (1 << STM_MPU_RASR_B) |
65                         (0 << STM_MPU_RASR_S) |
66                         (0 << STM_MPU_RASR_SRD) |
67                         (28 << STM_MPU_RASR_SIZE) |
68                         (1 << STM_MPU_RASR_ENABLE));
69         region++;
70
71         /* Ram */
72         /* 0x20000000 - 0x3fffffff */
73         stm_mpu.rbar = (0x20000000 |
74                         (1 << STM_MPU_RBAR_VALID) |
75                         (region << STM_MPU_RBAR_REGION));
76
77         stm_mpu.rasr = ((0 << STM_MPU_RASR_XN) |
78                         (STM_MPU_RASR_AP_RW_RW << STM_MPU_RASR_AP) |
79                         (5 << STM_MPU_RASR_TEX) |
80                         (0 << STM_MPU_RASR_C) |
81                         (1 << STM_MPU_RASR_B) |
82                         (0 << STM_MPU_RASR_S) |
83                         (0 << STM_MPU_RASR_SRD) |
84                         (28 << STM_MPU_RASR_SIZE) |
85                         (1 << STM_MPU_RASR_ENABLE));
86         region++;
87
88         /* Peripherals */
89
90         /* 0x4000000 - 0x7ffffff */
91         stm_mpu.rbar = (0x40000000 |
92                         (1 << STM_MPU_RBAR_VALID) |
93                         (region << STM_MPU_RBAR_REGION));
94
95         stm_mpu.rasr = ((1 << STM_MPU_RASR_XN) |
96                         (STM_MPU_RASR_AP_RW_RW << STM_MPU_RASR_AP) |
97                         (2 << STM_MPU_RASR_TEX) |
98                         (0 << STM_MPU_RASR_C) |
99                         (0 << STM_MPU_RASR_B) |
100                         (0 << STM_MPU_RASR_S) |
101                         (0 << STM_MPU_RASR_SRD) |
102                         (29 << STM_MPU_RASR_SIZE) |
103                         (1 << STM_MPU_RASR_ENABLE));
104         region++;
105
106         /* 0x8000000 - 0xffffffff */
107         stm_mpu.rbar = (0x80000000 |
108                         (1 << STM_MPU_RBAR_VALID) |
109                         (region << STM_MPU_RBAR_REGION));
110
111         stm_mpu.rasr = ((1 << STM_MPU_RASR_XN) |
112                         (STM_MPU_RASR_AP_RW_RW << STM_MPU_RASR_AP) |
113                         (2 << STM_MPU_RASR_TEX) |
114                         (0 << STM_MPU_RASR_C) |
115                         (0 << STM_MPU_RASR_B) |
116                         (0 << STM_MPU_RASR_S) |
117                         (0 << STM_MPU_RASR_SRD) |
118                         (30 << STM_MPU_RASR_SIZE) |
119                         (1 << STM_MPU_RASR_ENABLE));
120         region++;
121
122         /* Enable MPU */
123         stm_mpu.cr = ((0 << STM_MPU_CR_PRIVDEFENA) |
124                       (0 << STM_MPU_CR_HFNMIENA) |
125                       (1 << STM_MPU_CR_ENABLE));
126 }
127
128 /*
129  * Protect the base of the stack from CPU access
130  */
131
132 void
133 ao_mpu_stack_guard(void *base)
134 {
135         uintptr_t       addr = (uintptr_t) base;
136
137         /* Round up to cover the lowest possible 32-byte region */
138         addr = (addr + ~(STM_MPU_RBAR_ADDR_MASK << STM_MPU_RBAR_ADDR)) & (STM_MPU_RBAR_ADDR_MASK << STM_MPU_RBAR_ADDR);
139
140         stm_mpu.rbar = addr | (1 << STM_MPU_RBAR_VALID) | (7 << STM_MPU_RBAR_REGION);
141         stm_mpu.rasr = ((1 << STM_MPU_RASR_XN) |
142                         (STM_MPU_RASR_AP_NONE_NONE << STM_MPU_RASR_AP) |
143                         (5 << STM_MPU_RASR_TEX) |
144                         (0 << STM_MPU_RASR_C) |
145                         (1 << STM_MPU_RASR_B) |
146                         (0 << STM_MPU_RASR_S) |
147                         (0 << STM_MPU_RASR_SRD) |
148                         (4 << STM_MPU_RASR_SIZE) |
149                         (1 << STM_MPU_RASR_ENABLE));
150 }