1 | /**************************************************************************//**
|
---|
2 | * @file system_MBRZA1H.c
|
---|
3 | * @brief CMSIS Device System Source File for
|
---|
4 | * ARM Cortex-A9 Device Series
|
---|
5 | * @version V1.00
|
---|
6 | * @date 09 January 2015
|
---|
7 | *
|
---|
8 | * @note
|
---|
9 | *
|
---|
10 | ******************************************************************************/
|
---|
11 | /* Copyright (c) 2011 - 2015 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 | extern uint32_t IRQNestLevel;
|
---|
53 | unsigned char seen_id0_active = 0; // single byte to hold a flag used in the workaround for GIC errata 733075
|
---|
54 |
|
---|
55 |
|
---|
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 | #if defined(__ARMCC_VERSION)
|
---|
65 | #pragma push
|
---|
66 | #pragma arm
|
---|
67 |
|
---|
68 | void InitMemorySubsystem(void) {
|
---|
69 |
|
---|
70 | /* This SVC is specific for reset where data / tlb / btac may contain undefined data, therefore before
|
---|
71 | * enabling the cache you must invalidate the instruction cache, the data cache, TLB, and BTAC.
|
---|
72 | * You are not required to invalidate the main TLB, even though it is recommended for safety
|
---|
73 | * reasons. This ensures compatibility with future revisions of the processor. */
|
---|
74 |
|
---|
75 | unsigned int l2_id;
|
---|
76 |
|
---|
77 | /* Invalidate undefined data */
|
---|
78 | __ca9u_inv_tlb_all();
|
---|
79 | __v7_inv_icache_all();
|
---|
80 | __v7_inv_dcache_all();
|
---|
81 | __v7_inv_btac();
|
---|
82 |
|
---|
83 | /* 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
|
---|
84 | * invalidate in order to flush the valid data to the next level cache.
|
---|
85 | */
|
---|
86 | __enable_mmu();
|
---|
87 |
|
---|
88 | /* After MMU is enabled and data has been invalidated, enable caches and BTAC */
|
---|
89 | __enable_caches();
|
---|
90 | __enable_btac();
|
---|
91 |
|
---|
92 | /* If present, you may also need to Invalidate and Enable L2 cache here */
|
---|
93 | l2_id = PL310_GetID();
|
---|
94 | if (l2_id)
|
---|
95 | {
|
---|
96 | PL310_InvAllByWay();
|
---|
97 | PL310_Enable();
|
---|
98 | }
|
---|
99 | }
|
---|
100 | #pragma pop
|
---|
101 |
|
---|
102 | #elif defined(__GNUC__)
|
---|
103 |
|
---|
104 | void InitMemorySubsystem(void) {
|
---|
105 |
|
---|
106 | /* This SVC is specific for reset where data / tlb / btac may contain undefined data, therefore before
|
---|
107 | * enabling the cache you must invalidate the instruction cache, the data cache, TLB, and BTAC.
|
---|
108 | * You are not required to invalidate the main TLB, even though it is recommended for safety
|
---|
109 | * reasons. This ensures compatibility with future revisions of the processor. */
|
---|
110 |
|
---|
111 | unsigned int l2_id;
|
---|
112 |
|
---|
113 | /* Invalidate undefined data */
|
---|
114 | __ca9u_inv_tlb_all();
|
---|
115 | __v7_inv_icache_all();
|
---|
116 | __v7_inv_dcache_all();
|
---|
117 | __v7_inv_btac();
|
---|
118 |
|
---|
119 | /* 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
|
---|
120 | * invalidate in order to flush the valid data to the next level cache.
|
---|
121 | */
|
---|
122 | __enable_mmu();
|
---|
123 |
|
---|
124 | /* After MMU is enabled and data has been invalidated, enable caches and BTAC */
|
---|
125 | __enable_caches();
|
---|
126 | __enable_btac();
|
---|
127 |
|
---|
128 | /* If present, you may also need to Invalidate and Enable L2 cache here */
|
---|
129 | l2_id = PL310_GetID();
|
---|
130 | if (l2_id)
|
---|
131 | {
|
---|
132 | PL310_InvAllByWay();
|
---|
133 | PL310_Enable();
|
---|
134 | }
|
---|
135 | }
|
---|
136 | #else
|
---|
137 |
|
---|
138 | #endif
|
---|
139 |
|
---|
140 |
|
---|
141 | extern IRQHandler IRQTable[Renesas_RZ_A1_IRQ_MAX+1];
|
---|
142 |
|
---|
143 | uint32_t IRQCount = sizeof IRQTable / 4;
|
---|
144 |
|
---|
145 | uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler)
|
---|
146 | {
|
---|
147 | if (irq < IRQCount) {
|
---|
148 | IRQTable[irq] = handler;
|
---|
149 | return 0;
|
---|
150 | }
|
---|
151 | else {
|
---|
152 | return 1;
|
---|
153 | }
|
---|
154 | }
|
---|
155 |
|
---|
156 | uint32_t InterruptHandlerUnregister (IRQn_Type irq)
|
---|
157 | {
|
---|
158 | if (irq < IRQCount) {
|
---|
159 | IRQTable[irq] = 0;
|
---|
160 | return 0;
|
---|
161 | }
|
---|
162 | else {
|
---|
163 | return 1;
|
---|
164 | }
|
---|
165 | }
|
---|
166 |
|
---|
167 | /**
|
---|
168 | * Initialize the system
|
---|
169 | *
|
---|
170 | * @param none
|
---|
171 | * @return none
|
---|
172 | *
|
---|
173 | * @brief Setup the microcontroller system.
|
---|
174 | * Initialize the System.
|
---|
175 | */
|
---|
176 | void SystemInit (void)
|
---|
177 | {
|
---|
178 | IRQNestLevel = 0;
|
---|
179 | /* do not use global variables because this function is called before
|
---|
180 | reaching pre-main. RW section maybe overwritten afterwards. */
|
---|
181 | RZ_A1_InitClock();
|
---|
182 | RZ_A1_InitBus();
|
---|
183 |
|
---|
184 | //Configure GIC ICDICFR GIC_SetICDICFR()
|
---|
185 | GIC_Enable();
|
---|
186 | __enable_irq();
|
---|
187 |
|
---|
188 | }
|
---|
189 |
|
---|
190 |
|
---|
191 | //Fault Status Register (IFSR/DFSR) definitions
|
---|
192 | #define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
|
---|
193 | #define FSR_INSTRUCTION_CACHE_MAINTENANCE 0x04 //DFSR only - async/external
|
---|
194 | #define FSR_SYNC_EXT_TTB_WALK_FIRST 0x0c //sync/external
|
---|
195 | #define FSR_SYNC_EXT_TTB_WALK_SECOND 0x0e //sync/external
|
---|
196 | #define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
|
---|
197 | #define FSR_SYNC_PARITY_TTB_WALK_SECOND 0x1e //sync/external
|
---|
198 | #define FSR_TRANSLATION_FAULT_FIRST 0x05 //MMU Fault - internal
|
---|
199 | #define FSR_TRANSLATION_FAULT_SECOND 0x07 //MMU Fault - internal
|
---|
200 | #define FSR_ACCESS_FLAG_FAULT_FIRST 0x03 //MMU Fault - internal
|
---|
201 | #define FSR_ACCESS_FLAG_FAULT_SECOND 0x06 //MMU Fault - internal
|
---|
202 | #define FSR_DOMAIN_FAULT_FIRST 0x09 //MMU Fault - internal
|
---|
203 | #define FSR_DOMAIN_FAULT_SECOND 0x0b //MMU Fault - internal
|
---|
204 | #define FSR_PERMISION_FAULT_FIRST 0x0f //MMU Fault - internal
|
---|
205 | #define FSR_PERMISION_FAULT_SECOND 0x0d //MMU Fault - internal
|
---|
206 | #define FSR_DEBUG_EVENT 0x02 //internal
|
---|
207 | #define FSR_SYNC_EXT_ABORT 0x08 //sync/external
|
---|
208 | #define FSR_TLB_CONFLICT_ABORT 0x10 //sync/external
|
---|
209 | #define FSR_LOCKDOWN 0x14 //internal
|
---|
210 | #define FSR_COPROCESSOR_ABORT 0x1a //internal
|
---|
211 | #define FSR_SYNC_PARITY_ERROR 0x19 //sync/external
|
---|
212 | #define FSR_ASYNC_EXTERNAL_ABORT 0x16 //DFSR only - async/external
|
---|
213 | #define FSR_ASYNC_PARITY_ERROR 0x18 //DFSR only - async/external
|
---|
214 |
|
---|
215 | void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
|
---|
216 | uint32_t FS = (DFSR & (1 << 10)) >> 6 | (DFSR & 0x0f); //Store Fault Status
|
---|
217 |
|
---|
218 | switch(FS) {
|
---|
219 | //Synchronous parity errors - retry
|
---|
220 | case FSR_SYNC_PARITY_ERROR:
|
---|
221 | case FSR_SYNC_PARITY_TTB_WALK_FIRST:
|
---|
222 | case FSR_SYNC_PARITY_TTB_WALK_SECOND:
|
---|
223 | return;
|
---|
224 |
|
---|
225 | //Your code here. Value in DFAR is invalid for some fault statuses.
|
---|
226 | case FSR_ALIGNMENT_FAULT:
|
---|
227 | case FSR_INSTRUCTION_CACHE_MAINTENANCE:
|
---|
228 | case FSR_SYNC_EXT_TTB_WALK_FIRST:
|
---|
229 | case FSR_SYNC_EXT_TTB_WALK_SECOND:
|
---|
230 | case FSR_TRANSLATION_FAULT_FIRST:
|
---|
231 | case FSR_TRANSLATION_FAULT_SECOND:
|
---|
232 | case FSR_ACCESS_FLAG_FAULT_FIRST:
|
---|
233 | case FSR_ACCESS_FLAG_FAULT_SECOND:
|
---|
234 | case FSR_DOMAIN_FAULT_FIRST:
|
---|
235 | case FSR_DOMAIN_FAULT_SECOND:
|
---|
236 | case FSR_PERMISION_FAULT_FIRST:
|
---|
237 | case FSR_PERMISION_FAULT_SECOND:
|
---|
238 | case FSR_DEBUG_EVENT:
|
---|
239 | case FSR_SYNC_EXT_ABORT:
|
---|
240 | case FSR_TLB_CONFLICT_ABORT:
|
---|
241 | case FSR_LOCKDOWN:
|
---|
242 | case FSR_COPROCESSOR_ABORT:
|
---|
243 | case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid
|
---|
244 | case FSR_ASYNC_PARITY_ERROR: //DFAR invalid
|
---|
245 | default:
|
---|
246 | _kernel_default_exc_handler();
|
---|
247 | }
|
---|
248 | }
|
---|
249 |
|
---|
250 | void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
|
---|
251 | uint32_t FS = (IFSR & (1 << 10)) >> 6 | (IFSR & 0x0f); //Store Fault Status
|
---|
252 |
|
---|
253 | switch(FS) {
|
---|
254 | //Synchronous parity errors - retry
|
---|
255 | case FSR_SYNC_PARITY_ERROR:
|
---|
256 | case FSR_SYNC_PARITY_TTB_WALK_FIRST:
|
---|
257 | case FSR_SYNC_PARITY_TTB_WALK_SECOND:
|
---|
258 | return;
|
---|
259 |
|
---|
260 | //Your code here. Value in IFAR is invalid for some fault statuses.
|
---|
261 | case FSR_SYNC_EXT_TTB_WALK_FIRST:
|
---|
262 | case FSR_SYNC_EXT_TTB_WALK_SECOND:
|
---|
263 | case FSR_TRANSLATION_FAULT_FIRST:
|
---|
264 | case FSR_TRANSLATION_FAULT_SECOND:
|
---|
265 | case FSR_ACCESS_FLAG_FAULT_FIRST:
|
---|
266 | case FSR_ACCESS_FLAG_FAULT_SECOND:
|
---|
267 | case FSR_DOMAIN_FAULT_FIRST:
|
---|
268 | case FSR_DOMAIN_FAULT_SECOND:
|
---|
269 | case FSR_PERMISION_FAULT_FIRST:
|
---|
270 | case FSR_PERMISION_FAULT_SECOND:
|
---|
271 | case FSR_DEBUG_EVENT: //IFAR invalid
|
---|
272 | case FSR_SYNC_EXT_ABORT:
|
---|
273 | case FSR_TLB_CONFLICT_ABORT:
|
---|
274 | case FSR_LOCKDOWN:
|
---|
275 | case FSR_COPROCESSOR_ABORT:
|
---|
276 | default:
|
---|
277 | _kernel_default_exc_handler();
|
---|
278 | }
|
---|
279 | }
|
---|
280 |
|
---|
281 | //returns amount to decrement lr by
|
---|
282 | //this will be 0 when we have emulated the instruction and want to execute the next instruction
|
---|
283 | //this will be 2 when we have performed some maintenance and want to retry the instruction in Thumb (state == 2)
|
---|
284 | //this will be 4 when we have performed some maintenance and want to retry the instruction in ARM (state == 4)
|
---|
285 | uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
|
---|
286 | const unsigned int THUMB = 2;
|
---|
287 | const unsigned int ARM = 4;
|
---|
288 | //Lazy VFP/NEON initialisation and switching
|
---|
289 |
|
---|
290 | // (ARM ARM section A7.5) VFP data processing instruction?
|
---|
291 | // (ARM ARM section A7.6) VFP/NEON register load/store instruction?
|
---|
292 | // (ARM ARM section A7.8) VFP/NEON register data transfer instruction?
|
---|
293 | // (ARM ARM section A7.9) VFP/NEON 64-bit register data transfer instruction?
|
---|
294 | if ((state == ARM && ((opcode & 0x0C000000) >> 26 == 0x03)) ||
|
---|
295 | (state == THUMB && ((opcode & 0xEC000000) >> 26 == 0x3B))) {
|
---|
296 | if (((opcode & 0x00000E00) >> 9) == 5) {
|
---|
297 | FPUEnable();
|
---|
298 | return state;
|
---|
299 | }
|
---|
300 | }
|
---|
301 |
|
---|
302 | // (ARM ARM section A7.4) NEON data processing instruction?
|
---|
303 | if ((state == ARM && ((opcode & 0xFE000000) >> 24 == 0xF2)) ||
|
---|
304 | (state == THUMB && ((opcode & 0xEF000000) >> 24 == 0xEF)) ||
|
---|
305 | // (ARM ARM section A7.7) NEON load/store instruction?
|
---|
306 | (state == ARM && ((opcode >> 24) == 0xF4)) ||
|
---|
307 | (state == THUMB && ((opcode >> 24) == 0xF9))) {
|
---|
308 | FPUEnable();
|
---|
309 | return state;
|
---|
310 | }
|
---|
311 |
|
---|
312 | //Add code here for other Undef cases
|
---|
313 | _kernel_default_exc_handler();
|
---|
314 | return 0;
|
---|
315 | }
|
---|
316 |
|
---|
317 | #if defined(__ARMCC_VERSION)
|
---|
318 | #pragma push
|
---|
319 | #pragma arm
|
---|
320 | //Critical section, called from undef handler, so systick is disabled
|
---|
321 | __asm void FPUEnable(void) {
|
---|
322 | ARM
|
---|
323 |
|
---|
324 | //Permit access to VFP/NEON, registers by modifying CPACR
|
---|
325 | MRC p15,0,R1,c1,c0,2
|
---|
326 | ORR R1,R1,#0x00F00000
|
---|
327 | MCR p15,0,R1,c1,c0,2
|
---|
328 |
|
---|
329 | //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
---|
330 | ISB
|
---|
331 |
|
---|
332 | //Enable VFP/NEON
|
---|
333 | VMRS R1,FPEXC
|
---|
334 | ORR R1,R1,#0x40000000
|
---|
335 | VMSR FPEXC,R1
|
---|
336 |
|
---|
337 | //Initialise VFP/NEON registers to 0
|
---|
338 | MOV R2,#0
|
---|
339 | //Initialise D16 registers to 0
|
---|
340 | VMOV D0, R2,R2
|
---|
341 | VMOV D1, R2,R2
|
---|
342 | VMOV D2, R2,R2
|
---|
343 | VMOV D3, R2,R2
|
---|
344 | VMOV D4, R2,R2
|
---|
345 | VMOV D5, R2,R2
|
---|
346 | VMOV D6, R2,R2
|
---|
347 | VMOV D7, R2,R2
|
---|
348 | VMOV D8, R2,R2
|
---|
349 | VMOV D9, R2,R2
|
---|
350 | VMOV D10,R2,R2
|
---|
351 | VMOV D11,R2,R2
|
---|
352 | VMOV D12,R2,R2
|
---|
353 | VMOV D13,R2,R2
|
---|
354 | VMOV D14,R2,R2
|
---|
355 | VMOV D15,R2,R2
|
---|
356 | //Initialise D32 registers to 0
|
---|
357 | VMOV D16,R2,R2
|
---|
358 | VMOV D17,R2,R2
|
---|
359 | VMOV D18,R2,R2
|
---|
360 | VMOV D19,R2,R2
|
---|
361 | VMOV D20,R2,R2
|
---|
362 | VMOV D21,R2,R2
|
---|
363 | VMOV D22,R2,R2
|
---|
364 | VMOV D23,R2,R2
|
---|
365 | VMOV D24,R2,R2
|
---|
366 | VMOV D25,R2,R2
|
---|
367 | VMOV D26,R2,R2
|
---|
368 | VMOV D27,R2,R2
|
---|
369 | VMOV D28,R2,R2
|
---|
370 | VMOV D29,R2,R2
|
---|
371 | VMOV D30,R2,R2
|
---|
372 | VMOV D31,R2,R2
|
---|
373 | //Initialise FPSCR to a known state
|
---|
374 | VMRS R2,FPSCR
|
---|
375 | LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
---|
376 | AND R2,R2,R3
|
---|
377 | VMSR FPSCR,R2
|
---|
378 |
|
---|
379 | BX LR
|
---|
380 | }
|
---|
381 | #pragma pop
|
---|
382 |
|
---|
383 | #elif defined(__GNUC__)
|
---|
384 | void FPUEnable(void) {
|
---|
385 | __asm__ (
|
---|
386 | ".ARM;"
|
---|
387 |
|
---|
388 | //Permit access to VFP/NEON, registers by modifying CPACR
|
---|
389 | "MRC p15,0,R1,c1,c0,2;"
|
---|
390 | "ORR R1,R1,#0x00F00000;"
|
---|
391 | "MCR p15,0,R1,c1,c0,2;"
|
---|
392 |
|
---|
393 | //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
---|
394 | "ISB;"
|
---|
395 |
|
---|
396 | //Enable VFP/NEON
|
---|
397 | "VMRS R1,FPEXC;"
|
---|
398 | "ORR R1,R1,#0x40000000;"
|
---|
399 | "VMSR FPEXC,R1;"
|
---|
400 |
|
---|
401 | //Initialise VFP/NEON registers to 0
|
---|
402 | "MOV R2,#0;"
|
---|
403 | //Initialise D16 registers to 0
|
---|
404 | "VMOV D0, R2,R2;"
|
---|
405 | "VMOV D1, R2,R2;"
|
---|
406 | "VMOV D2, R2,R2;"
|
---|
407 | "VMOV D3, R2,R2;"
|
---|
408 | "VMOV D4, R2,R2;"
|
---|
409 | "VMOV D5, R2,R2;"
|
---|
410 | "VMOV D6, R2,R2;"
|
---|
411 | "VMOV D7, R2,R2;"
|
---|
412 | "VMOV D8, R2,R2;"
|
---|
413 | "VMOV D9, R2,R2;"
|
---|
414 | "VMOV D10,R2,R2;"
|
---|
415 | "VMOV D11,R2,R2;"
|
---|
416 | "VMOV D12,R2,R2;"
|
---|
417 | "VMOV D13,R2,R2;"
|
---|
418 | "VMOV D14,R2,R2;"
|
---|
419 | "VMOV D15,R2,R2;"
|
---|
420 | //Initialise D32 registers to 0
|
---|
421 | "VMOV D16,R2,R2;"
|
---|
422 | "VMOV D17,R2,R2;"
|
---|
423 | "VMOV D18,R2,R2;"
|
---|
424 | "VMOV D19,R2,R2;"
|
---|
425 | "VMOV D20,R2,R2;"
|
---|
426 | "VMOV D21,R2,R2;"
|
---|
427 | "VMOV D22,R2,R2;"
|
---|
428 | "VMOV D23,R2,R2;"
|
---|
429 | "VMOV D24,R2,R2;"
|
---|
430 | "VMOV D25,R2,R2;"
|
---|
431 | "VMOV D26,R2,R2;"
|
---|
432 | "VMOV D27,R2,R2;"
|
---|
433 | "VMOV D28,R2,R2;"
|
---|
434 | "VMOV D29,R2,R2;"
|
---|
435 | "VMOV D30,R2,R2;"
|
---|
436 | "VMOV D31,R2,R2;"
|
---|
437 |
|
---|
438 | //Initialise FPSCR to a known state
|
---|
439 | "VMRS R2,FPSCR;"
|
---|
440 | "LDR R3,=0x00086060;" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
---|
441 | "AND R2,R2,R3;"
|
---|
442 | "VMSR FPSCR,R2;"
|
---|
443 |
|
---|
444 | //"BX LR;"
|
---|
445 | :
|
---|
446 | :
|
---|
447 | :"r1", "r2", "r3");
|
---|
448 | return;
|
---|
449 | }
|
---|
450 | #else
|
---|
451 | #endif
|
---|
452 |
|
---|