]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/system_MBRZA1H.c
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
[qmk_firmware.git] / tmk_core / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_RENESAS / TARGET_RZ_A1H / system_MBRZA1H.c
1 /**************************************************************************//**
2  * @file     system_MBRZA1H.c
3  * @brief    CMSIS Device System Source File for
4  *           ARMCA9 Device Series
5  * @version  V1.00
6  * @date     19 Sept 2013
7  *
8  * @note
9  *
10  ******************************************************************************/
11 /* Copyright (c) 2011 - 2013 ARM LIMITED
12
13    All rights reserved.
14    Redistribution and use in source and binary forms, with or without
15    modification, are permitted provided that the following conditions are met:
16    - Redistributions of source code must retain the above copyright
17      notice, this list of conditions and the following disclaimer.
18    - Redistributions in binary form must reproduce the above copyright
19      notice, this list of conditions and the following disclaimer in the
20      documentation and/or other materials provided with the distribution.
21    - Neither the name of ARM nor the names of its contributors may be used
22      to endorse or promote products derived from this software without
23      specific prior written permission.
24    *
25    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28    ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
29    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35    POSSIBILITY OF SUCH DAMAGE.
36    ---------------------------------------------------------------------------*/
37
38
39 #include <stdint.h>
40 #include "MBRZA1H.h"
41 #include "RZ_A1_Init.h"
42
43
44 #if defined(__ARMCC_VERSION)
45 extern void $Super$$main(void);
46 __asm void FPUEnable(void);
47 #else 
48 void FPUEnable(void); 
49
50 #endif
51
52 uint32_t IRQNestLevel;
53
54
55 #if defined(__ARMCC_VERSION)
56 /**
57  * Initialize the cache.
58  *
59  * @param  none
60  * @return none
61  *
62  * @brief Initialise caches. Requires PL1, so implemented as an SVC in case threads are USR mode.
63  */
64 #pragma push
65 #pragma arm
66
67 void InitMemorySubsystem(void) {
68
69     /* This SVC is specific for reset where data / tlb / btac may contain undefined data, therefore before
70      * enabling the cache you must invalidate the instruction cache, the data cache, TLB, and BTAC.
71      * You are not required to invalidate the main TLB, even though it is recommended for safety
72      * reasons. This ensures compatibility with future revisions of the processor. */
73
74     unsigned int l2_id;
75
76     /* Invalidate undefined data */
77     __ca9u_inv_tlb_all();
78     __v7_inv_icache_all();
79     __v7_inv_dcache_all();
80     __v7_inv_btac();
81
82     /* Don't use this function during runtime since caches may contain valid data. For a correct cache maintenance you may need to execute a clean and
83      * invalidate in order to flush the valid data to the next level cache.
84      */
85     __enable_mmu();
86
87     /* After MMU is enabled and data has been invalidated, enable caches and BTAC */
88     __enable_caches();
89     __enable_btac();
90
91     /* If present, you may also need to Invalidate and Enable L2 cache here */
92     l2_id = PL310_GetID();
93     if (l2_id)
94     {
95        PL310_InvAllByWay();
96        PL310_Enable();
97     }
98 }
99 #pragma pop
100
101 #elif defined(__GNUC__) 
102
103 void InitMemorySubsystem(void) { 
104  
105     /* This SVC is specific for reset where data / tlb / btac may contain undefined data, therefore before 
106      * enabling the cache you must invalidate the instruction cache, the data cache, TLB, and BTAC. 
107      * You are not required to invalidate the main TLB, even though it is recommended for safety 
108      * reasons. This ensures compatibility with future revisions of the processor. */ 
109  
110     unsigned int l2_id; 
111  
112     /* Invalidate undefined data */ 
113     __ca9u_inv_tlb_all(); 
114     __v7_inv_icache_all(); 
115     __v7_inv_dcache_all(); 
116     __v7_inv_btac(); 
117  
118     /* Don't use this function during runtime since caches may contain valid data. For a correct cache maintenance you may need to execute a clean and 
119      * invalidate in order to flush the valid data to the next level cache. 
120      */ 
121     __enable_mmu(); 
122  
123     /* After MMU is enabled and data has been invalidated, enable caches and BTAC */ 
124     __enable_caches(); 
125     __enable_btac(); 
126  
127     /* If present, you may also need to Invalidate and Enable L2 cache here */ 
128     l2_id = PL310_GetID(); 
129     if (l2_id) 
130     { 
131        PL310_InvAllByWay(); 
132        PL310_Enable(); 
133     } 
134
135 #else 
136
137 #endif 
138
139
140 IRQHandler IRQTable[Renesas_RZ_A1_IRQ_MAX+1];
141
142 uint32_t IRQCount = sizeof IRQTable / 4;
143
144 uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler)
145 {
146     if (irq < IRQCount) {
147         IRQTable[irq] = handler;
148         return 0;
149     }
150     else {
151         return 1;
152     }
153 }
154
155 uint32_t InterruptHandlerUnregister (IRQn_Type irq)
156 {
157     if (irq < IRQCount) {
158         IRQTable[irq] = 0;
159         return 0;
160     }
161     else {
162         return 1;
163     }
164 }
165
166 /**
167  * Initialize the system
168  *
169  * @param  none
170  * @return none
171  *
172  * @brief  Setup the microcontroller system.
173  *         Initialize the System.
174  */
175 void SystemInit (void)
176 {
177     IRQNestLevel = 0;
178 /*       do not use global variables because this function is called before
179          reaching pre-main. RW section maybe overwritten afterwards.          */
180     RZ_A1_InitClock();
181     RZ_A1_InitBus();
182
183         //Configure GIC ICDICFR GIC_SetICDICFR()
184     GIC_Enable();
185     __enable_irq();
186
187 }
188
189
190 //Fault Status Register (IFSR/DFSR) definitions
191 #define FSR_ALIGNMENT_FAULT                  0x01   //DFSR only. Fault on first lookup
192 #define FSR_INSTRUCTION_CACHE_MAINTAINANCE   0x04   //DFSR only - async/external
193 #define FSR_SYNC_EXT_TTB_WALK_FIRST          0x0c   //sync/external
194 #define FSR_SYNC_EXT_TTB_WALK_SECOND         0x0e   //sync/external
195 #define FSR_SYNC_PARITY_TTB_WALK_FIRST       0x1c   //sync/external
196 #define FSR_SYNC_PARITY_TTB_WALK_SECOND      0x1e   //sync/external
197 #define FSR_TRANSLATION_FAULT_FIRST          0x05   //MMU Fault - internal
198 #define FSR_TRANSLATION_FAULT_SECOND         0x07   //MMU Fault - internal
199 #define FSR_ACCESS_FLAG_FAULT_FIRST          0x03   //MMU Fault - internal
200 #define FSR_ACCESS_FLAG_FAULT_SECOND         0x06   //MMU Fault - internal
201 #define FSR_DOMAIN_FAULT_FIRST               0x09   //MMU Fault - internal
202 #define FSR_DOMAIN_FAULT_SECOND              0x0b   //MMU Fault - internal
203 #define FSR_PERMISION_FAULT_FIRST            0x0f   //MMU Fault - internal
204 #define FSR_PERMISION_FAULT_SECOND           0x0d   //MMU Fault - internal
205 #define FSR_DEBUG_EVENT                      0x02   //internal
206 #define FSR_SYNC_EXT_ABORT                   0x08   //sync/external
207 #define FSR_TLB_CONFLICT_ABORT               0x10   //sync/external
208 #define FSR_LOCKDOWN                         0x14   //internal
209 #define FSR_COPROCESSOR_ABORT                0x1a   //internal
210 #define FSR_SYNC_PARITY_ERROR                0x19   //sync/external
211 #define FSR_ASYNC_EXTERNAL_ABORT             0x16   //DFSR only - async/external
212 #define FSR_ASYNC_PARITY_ERROR               0x18   //DFSR only - async/external
213
214 void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
215     uint32_t FS = (DFSR & (1 << 10)) >> 6 | (DFSR & 0x0f); //Store Fault Status
216
217     switch(FS) {
218         //Synchronous parity errors - retry
219         case FSR_SYNC_PARITY_ERROR:
220         case FSR_SYNC_PARITY_TTB_WALK_FIRST:
221         case FSR_SYNC_PARITY_TTB_WALK_SECOND:
222             return;
223
224         //Your code here. Value in DFAR is invalid for some fault statuses.
225         case FSR_ALIGNMENT_FAULT:
226         case FSR_INSTRUCTION_CACHE_MAINTAINANCE:
227         case FSR_SYNC_EXT_TTB_WALK_FIRST:
228         case FSR_SYNC_EXT_TTB_WALK_SECOND:
229         case FSR_TRANSLATION_FAULT_FIRST:
230         case FSR_TRANSLATION_FAULT_SECOND:
231         case FSR_ACCESS_FLAG_FAULT_FIRST:
232         case FSR_ACCESS_FLAG_FAULT_SECOND:
233         case FSR_DOMAIN_FAULT_FIRST:
234         case FSR_DOMAIN_FAULT_SECOND:
235         case FSR_PERMISION_FAULT_FIRST:
236         case FSR_PERMISION_FAULT_SECOND:
237         case FSR_DEBUG_EVENT:
238         case FSR_SYNC_EXT_ABORT:
239         case FSR_TLB_CONFLICT_ABORT:
240         case FSR_LOCKDOWN:
241         case FSR_COPROCESSOR_ABORT:
242         case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid
243         case FSR_ASYNC_PARITY_ERROR:   //DFAR invalid
244         default:
245             while(1);
246     }
247 }
248
249 void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
250     uint32_t FS = (IFSR & (1 << 10)) >> 6 | (IFSR & 0x0f); //Store Fault Status
251
252     switch(FS) {
253         //Synchronous parity errors - retry
254         case FSR_SYNC_PARITY_ERROR:
255         case FSR_SYNC_PARITY_TTB_WALK_FIRST:
256         case FSR_SYNC_PARITY_TTB_WALK_SECOND:
257             return;
258
259         //Your code here. Value in IFAR is invalid for some fault statuses.
260         case FSR_SYNC_EXT_TTB_WALK_FIRST:
261         case FSR_SYNC_EXT_TTB_WALK_SECOND:
262         case FSR_TRANSLATION_FAULT_FIRST:
263         case FSR_TRANSLATION_FAULT_SECOND:
264         case FSR_ACCESS_FLAG_FAULT_FIRST:
265         case FSR_ACCESS_FLAG_FAULT_SECOND:
266         case FSR_DOMAIN_FAULT_FIRST:
267         case FSR_DOMAIN_FAULT_SECOND:
268         case FSR_PERMISION_FAULT_FIRST:
269         case FSR_PERMISION_FAULT_SECOND:
270         case FSR_DEBUG_EVENT: //IFAR invalid
271         case FSR_SYNC_EXT_ABORT:
272         case FSR_TLB_CONFLICT_ABORT:
273         case FSR_LOCKDOWN:
274         case FSR_COPROCESSOR_ABORT:
275         default:
276             while(1);
277     }
278 }
279
280 //returns amount to decrement lr by
281 //this will be 0 when we have emulated the instruction and simply want to execute the next instruction
282 //this will be 2 when we have performed some maintenance and want to retry the instruction in thumb (state == 2)
283 //this will be 4 when we have performed some maintenance and want to retry the instruction in arm (state == 4)
284 uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
285     const unsigned int THUMB = 2;
286     const unsigned int ARM = 4;
287     //Lazy VFP/NEON initialisation and switching
288     if ((state == ARM   && ((opcode & 0x0C000000)) >> 26 == 0x03) ||
289         (state == THUMB && ((opcode & 0xEC000000)) >> 26 == 0x3B)) {
290         if (((opcode & 0x00000E00) >> 9) == 5) { //fp instruction?
291             FPUEnable();
292             return state;
293         }
294     }
295
296     //Add code here for other Undef cases
297     while(1);
298 }
299
300 #if defined(__ARMCC_VERSION)
301 #pragma push
302 #pragma arm
303 //Critical section, called from undef handler, so systick is disabled
304 __asm void FPUEnable(void) {
305         ARM
306
307         //Permit access to VFP registers by modifying CPACR
308         MRC     p15,0,R1,c1,c0,2
309         ORR     R1,R1,#0x00F00000
310         MCR     p15,0,R1,c1,c0,2
311
312         //Enable VFP
313         VMRS    R1,FPEXC
314         ORR     R1,R1,#0x40000000
315         VMSR    FPEXC,R1
316
317         //Initialise VFP registers to 0
318         MOV     R2,#0
319         VMOV    D0, R2,R2
320         VMOV    D1, R2,R2
321         VMOV    D2, R2,R2
322         VMOV    D3, R2,R2
323         VMOV    D4, R2,R2
324         VMOV    D5, R2,R2
325         VMOV    D6, R2,R2
326         VMOV    D7, R2,R2
327         VMOV    D8, R2,R2
328         VMOV    D9, R2,R2
329         VMOV    D10,R2,R2
330         VMOV    D11,R2,R2
331         VMOV    D12,R2,R2
332         VMOV    D13,R2,R2
333         VMOV    D14,R2,R2
334         VMOV    D15,R2,R2
335
336         //Initialise FPSCR to a known state
337         VMRS    R2,FPSCR
338         LDR     R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
339         AND     R2,R2,R3
340         VMSR    FPSCR,R2
341
342         BX      LR
343 }
344 #pragma pop
345
346 #elif defined(__GNUC__)
347 void FPUEnable(void)
348 {
349     __asm__ __volatile__ (
350             ".align 2                   \n\t"
351             ".arm                       \n\t"
352             "mrc    p15,0,r1,c1,c0,2    \n\t"
353             "orr    r1,r1,#0x00f00000   \n\t"
354             "mcr    p15,0,r1,c1,c0,2    \n\t"
355             "vmrs   r1,fpexc            \n\t"
356             "orr    r1,r1,#0x40000000   \n\t"
357             "vmsr   fpexc,r1            \n\t"
358             "mov    r2,#0               \n\t"
359             "vmov   d0, r2,r2           \n\t"
360             "vmov   d1, r2,r2           \n\t"
361             "vmov   d2, r2,r2           \n\t"
362             "vmov   d3, r2,r2           \n\t"
363             "vmov   d4, r2,r2           \n\t"
364             "vmov   d5, r2,r2           \n\t"
365             "vmov   d6, r2,r2           \n\t"
366             "vmov   d7, r2,r2           \n\t"
367             "vmov   d8, r2,r2           \n\t"
368             "vmov   d9, r2,r2           \n\t"
369             "vmov   d10,r2,r2           \n\t"
370             "vmov   d11,r2,r2           \n\t"
371             "vmov   d12,r2,r2           \n\t"
372             "vmov   d13,r2,r2           \n\t"
373             "vmov   d14,r2,r2           \n\t"
374             "vmov   d15,r2,r2           \n\t"
375             "vmrs   r2,fpscr            \n\t"
376             "ldr    r3,=0x00086060      \n\t"
377             "and    r2,r2,r3            \n\t"
378             "vmsr   fpscr,r2            \n\t"
379             "bx     lr                  \n\t"
380     );
381 }
382 #else
383 #endif
384