mirror of https://github.com/ARMmbed/mbed-os.git
Modify to support NEON for RTOS. (mbed CMSIS HAL)
We modified to support NEON of CMSIS-RTOS RTX for Cortex-A9 and fixed some bugs of it.pull/1326/head
parent
39d801e5c6
commit
7ea62c20b3
|
@ -1,8 +1,8 @@
|
||||||
/**************************************************************************//**
|
/**************************************************************************//**
|
||||||
* @file pl310.c
|
* @file pl310.c
|
||||||
* @brief Implementation of pl310 functions
|
* @brief Implementation of PL310 PrimeCell Level 2 Cache Controller functions
|
||||||
* @version
|
* @version
|
||||||
* @date 11 June 2013
|
* @date 3 December 2014
|
||||||
*
|
*
|
||||||
* @note
|
* @note
|
||||||
*
|
*
|
||||||
|
@ -80,7 +80,7 @@ void PL310_CleanInvAllByWay (void)
|
||||||
assoc = 8;
|
assoc = 8;
|
||||||
|
|
||||||
PL310->CLEAN_INV_WAY = (1 << assoc) - 1;
|
PL310->CLEAN_INV_WAY = (1 << assoc) - 1;
|
||||||
while(PL310->CLEAN_INV_WAY && ((1 << assoc) - 1)); //poll invalidate
|
while(PL310->CLEAN_INV_WAY & ((1 << assoc) - 1)); //poll invalidate
|
||||||
|
|
||||||
PL310_Sync();
|
PL310_Sync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
/**************************************************************************//**
|
/**************************************************************************//**
|
||||||
* @file system_MBRZA1H.c
|
* @file system_MBRZA1H.c
|
||||||
* @brief CMSIS Device System Source File for
|
* @brief CMSIS Device System Source File for
|
||||||
* ARMCA9 Device Series
|
* ARM Cortex-A9 Device Series
|
||||||
* @version V1.00
|
* @version V1.00
|
||||||
* @date 19 Sept 2013
|
* @date 09 January 2015
|
||||||
*
|
*
|
||||||
* @note
|
* @note
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/* Copyright (c) 2011 - 2013 ARM LIMITED
|
/* Copyright (c) 2011 - 2015 ARM LIMITED
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -50,9 +50,9 @@ void FPUEnable(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t IRQNestLevel;
|
uint32_t IRQNestLevel;
|
||||||
|
unsigned char seen_id0_active = 0; // single byte to hold a flag used in the workaround for GIC errata 733075
|
||||||
|
|
||||||
|
|
||||||
#if defined(__ARMCC_VERSION)
|
|
||||||
/**
|
/**
|
||||||
* Initialize the cache.
|
* Initialize the cache.
|
||||||
*
|
*
|
||||||
|
@ -61,6 +61,7 @@ uint32_t IRQNestLevel;
|
||||||
*
|
*
|
||||||
* @brief Initialise caches. Requires PL1, so implemented as an SVC in case threads are USR mode.
|
* @brief Initialise caches. Requires PL1, so implemented as an SVC in case threads are USR mode.
|
||||||
*/
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION)
|
||||||
#pragma push
|
#pragma push
|
||||||
#pragma arm
|
#pragma arm
|
||||||
|
|
||||||
|
@ -189,7 +190,7 @@ void SystemInit (void)
|
||||||
|
|
||||||
//Fault Status Register (IFSR/DFSR) definitions
|
//Fault Status Register (IFSR/DFSR) definitions
|
||||||
#define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
|
#define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
|
||||||
#define FSR_INSTRUCTION_CACHE_MAINTAINANCE 0x04 //DFSR only - async/external
|
#define FSR_INSTRUCTION_CACHE_MAINTENANCE 0x04 //DFSR only - async/external
|
||||||
#define FSR_SYNC_EXT_TTB_WALK_FIRST 0x0c //sync/external
|
#define FSR_SYNC_EXT_TTB_WALK_FIRST 0x0c //sync/external
|
||||||
#define FSR_SYNC_EXT_TTB_WALK_SECOND 0x0e //sync/external
|
#define FSR_SYNC_EXT_TTB_WALK_SECOND 0x0e //sync/external
|
||||||
#define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
|
#define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
|
||||||
|
@ -223,7 +224,7 @@ void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
|
||||||
|
|
||||||
//Your code here. Value in DFAR is invalid for some fault statuses.
|
//Your code here. Value in DFAR is invalid for some fault statuses.
|
||||||
case FSR_ALIGNMENT_FAULT:
|
case FSR_ALIGNMENT_FAULT:
|
||||||
case FSR_INSTRUCTION_CACHE_MAINTAINANCE:
|
case FSR_INSTRUCTION_CACHE_MAINTENANCE:
|
||||||
case FSR_SYNC_EXT_TTB_WALK_FIRST:
|
case FSR_SYNC_EXT_TTB_WALK_FIRST:
|
||||||
case FSR_SYNC_EXT_TTB_WALK_SECOND:
|
case FSR_SYNC_EXT_TTB_WALK_SECOND:
|
||||||
case FSR_TRANSLATION_FAULT_FIRST:
|
case FSR_TRANSLATION_FAULT_FIRST:
|
||||||
|
@ -278,21 +279,36 @@ void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns amount to decrement lr by
|
//returns amount to decrement lr by
|
||||||
//this will be 0 when we have emulated the instruction and simply want to execute the next instruction
|
//this will be 0 when we have emulated the instruction and want to execute the next instruction
|
||||||
//this will be 2 when we have performed some maintenance and want to retry the instruction in thumb (state == 2)
|
//this will be 2 when we have performed some maintenance and want to retry the instruction in Thumb (state == 2)
|
||||||
//this will be 4 when we have performed some maintenance and want to retry the instruction in arm (state == 4)
|
//this will be 4 when we have performed some maintenance and want to retry the instruction in ARM (state == 4)
|
||||||
uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
|
uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
|
||||||
const unsigned int THUMB = 2;
|
const unsigned int THUMB = 2;
|
||||||
const unsigned int ARM = 4;
|
const unsigned int ARM = 4;
|
||||||
//Lazy VFP/NEON initialisation and switching
|
//Lazy VFP/NEON initialisation and switching
|
||||||
if ((state == ARM && ((opcode & 0x0C000000)) >> 26 == 0x03) ||
|
|
||||||
(state == THUMB && ((opcode & 0xEC000000)) >> 26 == 0x3B)) {
|
// (ARM ARM section A7.5) VFP data processing instruction?
|
||||||
if (((opcode & 0x00000E00) >> 9) == 5) { //fp instruction?
|
// (ARM ARM section A7.6) VFP/NEON register load/store instruction?
|
||||||
|
// (ARM ARM section A7.8) VFP/NEON register data transfer instruction?
|
||||||
|
// (ARM ARM section A7.9) VFP/NEON 64-bit register data transfer instruction?
|
||||||
|
if ((state == ARM && ((opcode & 0x0C000000) >> 26 == 0x03)) ||
|
||||||
|
(state == THUMB && ((opcode & 0xEC000000) >> 26 == 0x3B))) {
|
||||||
|
if (((opcode & 0x00000E00) >> 9) == 5) {
|
||||||
FPUEnable();
|
FPUEnable();
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (ARM ARM section A7.4) NEON data processing instruction?
|
||||||
|
if ((state == ARM && ((opcode & 0xFE000000) >> 24 == 0xF2)) ||
|
||||||
|
(state == THUMB && ((opcode & 0xEF000000) >> 24 == 0xEF)) ||
|
||||||
|
// (ARM ARM section A7.7) NEON load/store instruction?
|
||||||
|
(state == ARM && ((opcode >> 24) == 0xF4)) ||
|
||||||
|
(state == THUMB && ((opcode >> 24) == 0xF9))) {
|
||||||
|
FPUEnable();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
//Add code here for other Undef cases
|
//Add code here for other Undef cases
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
@ -304,18 +320,22 @@ uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
|
||||||
__asm void FPUEnable(void) {
|
__asm void FPUEnable(void) {
|
||||||
ARM
|
ARM
|
||||||
|
|
||||||
//Permit access to VFP registers by modifying CPACR
|
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||||
MRC p15,0,R1,c1,c0,2
|
MRC p15,0,R1,c1,c0,2
|
||||||
ORR R1,R1,#0x00F00000
|
ORR R1,R1,#0x00F00000
|
||||||
MCR p15,0,R1,c1,c0,2
|
MCR p15,0,R1,c1,c0,2
|
||||||
|
|
||||||
//Enable VFP
|
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||||
|
ISB
|
||||||
|
|
||||||
|
//Enable VFP/NEON
|
||||||
VMRS R1,FPEXC
|
VMRS R1,FPEXC
|
||||||
ORR R1,R1,#0x40000000
|
ORR R1,R1,#0x40000000
|
||||||
VMSR FPEXC,R1
|
VMSR FPEXC,R1
|
||||||
|
|
||||||
//Initialise VFP registers to 0
|
//Initialise VFP/NEON registers to 0
|
||||||
MOV R2,#0
|
MOV R2,#0
|
||||||
|
//Initialise D16 registers to 0
|
||||||
VMOV D0, R2,R2
|
VMOV D0, R2,R2
|
||||||
VMOV D1, R2,R2
|
VMOV D1, R2,R2
|
||||||
VMOV D2, R2,R2
|
VMOV D2, R2,R2
|
||||||
|
@ -332,7 +352,23 @@ __asm void FPUEnable(void) {
|
||||||
VMOV D13,R2,R2
|
VMOV D13,R2,R2
|
||||||
VMOV D14,R2,R2
|
VMOV D14,R2,R2
|
||||||
VMOV D15,R2,R2
|
VMOV D15,R2,R2
|
||||||
|
//Initialise D32 registers to 0
|
||||||
|
VMOV D16,R2,R2
|
||||||
|
VMOV D17,R2,R2
|
||||||
|
VMOV D18,R2,R2
|
||||||
|
VMOV D19,R2,R2
|
||||||
|
VMOV D20,R2,R2
|
||||||
|
VMOV D21,R2,R2
|
||||||
|
VMOV D22,R2,R2
|
||||||
|
VMOV D23,R2,R2
|
||||||
|
VMOV D24,R2,R2
|
||||||
|
VMOV D25,R2,R2
|
||||||
|
VMOV D26,R2,R2
|
||||||
|
VMOV D27,R2,R2
|
||||||
|
VMOV D28,R2,R2
|
||||||
|
VMOV D29,R2,R2
|
||||||
|
VMOV D30,R2,R2
|
||||||
|
VMOV D31,R2,R2
|
||||||
//Initialise FPSCR to a known state
|
//Initialise FPSCR to a known state
|
||||||
VMRS R2,FPSCR
|
VMRS R2,FPSCR
|
||||||
LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||||
|
@ -344,40 +380,71 @@ __asm void FPUEnable(void) {
|
||||||
#pragma pop
|
#pragma pop
|
||||||
|
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
void FPUEnable(void)
|
void FPUEnable(void) {
|
||||||
{
|
__asm__ (
|
||||||
__asm__ __volatile__ (
|
".ARM;"
|
||||||
".align 2 \n\t"
|
|
||||||
".arm \n\t"
|
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||||
"mrc p15,0,r1,c1,c0,2 \n\t"
|
"MRC p15,0,R1,c1,c0,2;"
|
||||||
"orr r1,r1,#0x00f00000 \n\t"
|
"ORR R1,R1,#0x00F00000;"
|
||||||
"mcr p15,0,r1,c1,c0,2 \n\t"
|
"MCR p15,0,R1,c1,c0,2;"
|
||||||
"vmrs r1,fpexc \n\t"
|
|
||||||
"orr r1,r1,#0x40000000 \n\t"
|
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||||
"vmsr fpexc,r1 \n\t"
|
"ISB;"
|
||||||
"mov r2,#0 \n\t"
|
|
||||||
"vmov d0, r2,r2 \n\t"
|
//Enable VFP/NEON
|
||||||
"vmov d1, r2,r2 \n\t"
|
"VMRS R1,FPEXC;"
|
||||||
"vmov d2, r2,r2 \n\t"
|
"ORR R1,R1,#0x40000000;"
|
||||||
"vmov d3, r2,r2 \n\t"
|
"VMSR FPEXC,R1;"
|
||||||
"vmov d4, r2,r2 \n\t"
|
|
||||||
"vmov d5, r2,r2 \n\t"
|
//Initialise VFP/NEON registers to 0
|
||||||
"vmov d6, r2,r2 \n\t"
|
"MOV R2,#0;"
|
||||||
"vmov d7, r2,r2 \n\t"
|
//Initialise D16 registers to 0
|
||||||
"vmov d8, r2,r2 \n\t"
|
"VMOV D0, R2,R2;"
|
||||||
"vmov d9, r2,r2 \n\t"
|
"VMOV D1, R2,R2;"
|
||||||
"vmov d10,r2,r2 \n\t"
|
"VMOV D2, R2,R2;"
|
||||||
"vmov d11,r2,r2 \n\t"
|
"VMOV D3, R2,R2;"
|
||||||
"vmov d12,r2,r2 \n\t"
|
"VMOV D4, R2,R2;"
|
||||||
"vmov d13,r2,r2 \n\t"
|
"VMOV D5, R2,R2;"
|
||||||
"vmov d14,r2,r2 \n\t"
|
"VMOV D6, R2,R2;"
|
||||||
"vmov d15,r2,r2 \n\t"
|
"VMOV D7, R2,R2;"
|
||||||
"vmrs r2,fpscr \n\t"
|
"VMOV D8, R2,R2;"
|
||||||
"ldr r3,=0x00086060 \n\t"
|
"VMOV D9, R2,R2;"
|
||||||
"and r2,r2,r3 \n\t"
|
"VMOV D10,R2,R2;"
|
||||||
"vmsr fpscr,r2 \n\t"
|
"VMOV D11,R2,R2;"
|
||||||
"bx lr \n\t"
|
"VMOV D12,R2,R2;"
|
||||||
);
|
"VMOV D13,R2,R2;"
|
||||||
|
"VMOV D14,R2,R2;"
|
||||||
|
"VMOV D15,R2,R2;"
|
||||||
|
//Initialise D32 registers to 0
|
||||||
|
"VMOV D16,R2,R2;"
|
||||||
|
"VMOV D17,R2,R2;"
|
||||||
|
"VMOV D18,R2,R2;"
|
||||||
|
"VMOV D19,R2,R2;"
|
||||||
|
"VMOV D20,R2,R2;"
|
||||||
|
"VMOV D21,R2,R2;"
|
||||||
|
"VMOV D22,R2,R2;"
|
||||||
|
"VMOV D23,R2,R2;"
|
||||||
|
"VMOV D24,R2,R2;"
|
||||||
|
"VMOV D25,R2,R2;"
|
||||||
|
"VMOV D26,R2,R2;"
|
||||||
|
"VMOV D27,R2,R2;"
|
||||||
|
"VMOV D28,R2,R2;"
|
||||||
|
"VMOV D29,R2,R2;"
|
||||||
|
"VMOV D30,R2,R2;"
|
||||||
|
"VMOV D31,R2,R2;"
|
||||||
|
|
||||||
|
//Initialise FPSCR to a known state
|
||||||
|
"VMRS R2,FPSCR;"
|
||||||
|
"LDR R3,=0x00086060;" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||||
|
"AND R2,R2,R3;"
|
||||||
|
"VMSR FPSCR,R2;"
|
||||||
|
|
||||||
|
//"BX LR;"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
:"r1", "r2", "r3");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue