[270] | 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 |
|
---|