Added C startup for Cortex-A devices and updated CORE_A functions
diff --git a/ARM.CMSIS.pdsc b/ARM.CMSIS.pdsc
index f3db990..77c7af4 100644
--- a/ARM.CMSIS.pdsc
+++ b/ARM.CMSIS.pdsc
@@ -2089,10 +2089,12 @@
<!-- include folder / device header file -->
<file category="include" name="Device/ARM/ARMCA7/Include/"/>
<!-- startup / system / mmu files -->
- <file category="sourceAsm" name="Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.s" version="1.0.0" attr="config" condition="ARMCC"/>
- <file category="linkerScript" name="Device/ARM/ARMCA7/Source/ARM/ARMCA7.sct" version="1.0.0" attr="config"/>
+ <file category="sourceC" name="Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.c" version="1.0.0" attr="config" condition="ARMCC"/>
<file category="sourceC" name="Device/ARM/ARMCA7/Source/system_ARMCA7.c" version="1.0.0" attr="config"/>
<file category="sourceC" name="Device/ARM/ARMCA7/Source/mmu_ARMCA7.c" version="1.0.0" attr="config"/>
+ <file category="header" name="Device/ARM/ARMCA7/Include/system_ARMCA7.h" version="1.0.0" attr="config"/>
+ <file category="header" name="Device/ARM/ARMCA7/Include/mem_ARMCA7.h" version="1.0.0" attr="config"/>
+ <file category="linkerScript" name="Device/ARM/ARMCA7/Source/ARM/ARMCA7.sct" version="1.0.0" attr="config"/>
</files>
</component>
@@ -2103,10 +2105,12 @@
<!-- include folder / device header file -->
<file category="include" name="Device/ARM/ARMCA9/Include/"/>
<!-- startup / system / mmu files -->
- <file category="sourceAsm" name="Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.s" version="1.0.0" attr="config" condition="ARMCC"/>
- <file category="linkerScript" name="Device/ARM/ARMCA9/Source/ARM/ARMCA9.sct" version="1.0.0" attr="config"/>
+ <file category="sourceC" name="Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.c" version="1.0.0" attr="config" condition="ARMCC"/>
<file category="sourceC" name="Device/ARM/ARMCA9/Source/system_ARMCA9.c" version="1.0.0" attr="config"/>
<file category="sourceC" name="Device/ARM/ARMCA9/Source/mmu_ARMCA9.c" version="1.0.0" attr="config"/>
+ <file category="header" name="Device/ARM/ARMCA9/Include/system_ARMCA9.h" version="1.0.0" attr="config"/>
+ <file category="header" name="Device/ARM/ARMCA9/Include/mem_ARMCA9.h" version="1.0.0" attr="config"/>
+ <file category="linkerScript" name="Device/ARM/ARMCA9/Source/ARM/ARMCA9.sct" version="1.0.0" attr="config"/>
</files>
</component>
diff --git a/CMSIS/CORE_A/Include/cmsis_armcc.h b/CMSIS/CORE_A/Include/cmsis_armcc.h
index 16bcd8d..5620075 100644
--- a/CMSIS/CORE_A/Include/cmsis_armcc.h
+++ b/CMSIS/CORE_A/Include/cmsis_armcc.h
@@ -255,6 +255,28 @@
return(__regCPSR);
}
+/** \brief Get Mode
+
+ This function gets the processor mode
+
+ \return Processor Mode
+ */
+__STATIC_INLINE uint32_t __get_mode(void) {
+ return (__get_CPSR() & 0x1FU);
+}
+
+/** \brief Set Mode
+
+ This function changes the processor mode
+
+ \param [in] mode Mode value to set
+ */
+__STATIC_INLINE __ASM void __set_mode(uint32_t mode) {
+ MOV r1, lr
+ MSR CPSR_C, r0
+ BX r1
+}
+
/** \brief Set Stack Pointer
This function assigns the given value to the current stack pointer.
@@ -299,17 +321,6 @@
BX LR
}
-/** \brief Set Mode
-
- This function changes the processor mode
-
- \param [in] mode Mode value to set
- */
-__STATIC_INLINE __ASM void __set_mode(uint32_t mode) {
- MOV r1, lr
- MSR CPSR_C, r0
- BX r1
-}
/** \brief Get FPEXC
This function returns the current value of the Floating Point Exception Control register.
@@ -478,17 +489,6 @@
return(__regMPIDR);
}
-/** \brief Set CNTP_TVAL
-
- This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
-
- \param [in] value CNTP_TVAL Register value to set
-*/
-__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) {
- register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0");
- __regCNTP_TVAL = value;
-}
-
/** \brief Get VBAR
This function returns the value of the Vector Base Address Register.
@@ -513,6 +513,17 @@
__regVBAR = vbar;
}
+/** \brief Set CNTP_TVAL
+
+ This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
+
+ \param [in] value CNTP_TVAL Register value to set
+*/
+__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) {
+ register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0");
+ __regCNTP_TVAL = value;
+}
+
/** \brief Get CNTP_TVAL
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
diff --git a/CMSIS/CORE_A/Include/core_ca.h b/CMSIS/CORE_A/Include/core_ca.h
index 2f0fab6..9c4efc0 100644
--- a/CMSIS/CORE_A/Include/core_ca.h
+++ b/CMSIS/CORE_A/Include/core_ca.h
@@ -482,6 +482,7 @@
/**
\brief Union type to access the L2C_310 Cache Controller.
*/
+#if (__L2C_PRESENT == 1U)
typedef struct
{
__I uint32_t CACHE_ID; /*!< Offset: 0x0000 Cache ID Register */
@@ -542,6 +543,7 @@
} L2C_310_TypeDef;
#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< L2C_310 Declaration */
+#endif
/** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD)
*/
@@ -585,6 +587,25 @@
#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< GIC Interface configuration struct */
+/** \brief Structure type to access the Private Timer
+*/
+#if (__CORTEX_A == 9U)
+typedef struct
+{
+ __IO uint32_t LOAD; // +0x000 - RW - Private Timer Load Register
+ __IO uint32_t COUNTER; // +0x004 - RW - Private Timer Counter Register
+ __IO uint32_t CONTROL; // +0x008 - RW - Private Timer Control Register
+ __IO uint32_t ISR; // +0x00C - RO - Private Timer Interrupt Status Register
+ uint32_t RESERVED[8];
+ __IO uint32_t WLOAD; // +0x020 - RW - Watchdog Load Register
+ __IO uint32_t WCOUNTER; // +0x024 - RW - Watchdog Counter Register
+ __IO uint32_t WCONTROL; // +0x028 - RW - Watchdog Control Register
+ __IO uint32_t WISR; // +0x02C - RW - Watchdog Interrupt Status Register
+ __IO uint32_t WRESET; // +0x030 - RW - Watchdog Reset Status Register
+ __I uint32_t WDISABLE; // +0x0FC - RO - Watchdog Disable Register
+} Timer_Type;
+#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< Timer configuration struct */
+#endif
/*******************************************************************************
* Hardware Abstraction Layer
@@ -728,7 +749,7 @@
/* ########################## L2 Cache functions ################################# */
-
+#if (__L2C_PRESENT == 1U)
//Cache Sync operation
__STATIC_INLINE void L2C_Sync(void)
{
@@ -817,6 +838,7 @@
L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa;
L2C_Sync();
}
+#endif
/* ########################## GIC functions ###################################### */
@@ -1043,20 +1065,48 @@
/* ########################## Generic Timer functions ############################ */
-__STATIC_INLINE void PL1_SetTimerValue(uint32_t value) {
+/* PL1 Physical Timer */
+#if (__CORTEX_A == 7U)
+__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) {
__set_CNTP_TVAL(value);
__ISB();
}
-__STATIC_INLINE uint32_t PL1_GetTimerValue() {
+__STATIC_INLINE uint32_t PL1_GetCurrentValue() {
return(__get_CNTP_TVAL());
}
-__STATIC_INLINE void PL1_SetTimerCtrl(uint32_t value) {
+__STATIC_INLINE void PL1_SetControl(uint32_t value) {
__set_CNTP_CTL(value);
__ISB();
}
+/* Private Timer */
+#elif (__CORTEX_A == 9U)
+__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) {
+ PTIM->LOAD = value;
+}
+
+__STATIC_INLINE uint32_t PTIM_GetLoadValue() {
+ return(PTIM->LOAD);
+}
+
+__STATIC_INLINE uint32_t PTIM_GetCurrentValue() {
+ return(PTIM->COUNTER);
+}
+
+__STATIC_INLINE void PTIM_SetControl(uint32_t value) {
+ PTIM->CONTROL = value;
+}
+
+__STATIC_INLINE uint32_t PTIM_GetControl(void) {
+ return(PTIM->CONTROL);
+}
+
+__STATIC_INLINE void PTIM_ClearEventFlag(void) {
+ PTIM->ISR = 1;
+}
+#endif
/* ########################## MMU functions ###################################### */
diff --git a/Device/ARM/ARMCA7/Include/mem_ARMCA7.h b/Device/ARM/ARMCA7/Include/mem_ARMCA7.h
new file mode 100644
index 0000000..70e402e
--- /dev/null
+++ b/Device/ARM/ARMCA7/Include/mem_ARMCA7.h
@@ -0,0 +1,94 @@
+/**************************************************************************//**
+ * @file mem_ARMCA7.h
+ * @brief Memory base and size definitions (used in scatter file)
+ * @version V1.00
+ * @date 22 Feb 2017
+ *
+ * @note
+ *
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEM_ARMCA7_H
+#define __MEM_ARMCA7_H
+
+/*----------------------------------------------------------------------------
+ User Stack & Heap size definition
+ *----------------------------------------------------------------------------*/
+/*
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+*/
+
+/*--------------------- ROM Configuration ------------------------------------
+//
+// <h> ROM Configuration
+// <o0> ROM Base Address <0x0-0xFFFFFFFF:8>
+// <o1> ROM Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// </h>
+ *----------------------------------------------------------------------------*/
+#define __ROM_BASE 0x80000000
+#define __ROM_SIZE 0x00200000
+
+/*--------------------- RAM Configuration -----------------------------------
+// <h> RAM Configuration
+// <o0> RAM Base Address <0x0-0xFFFFFFFF:8>
+// <o1> RAM Total Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o2> RW_DATA Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o3> ZI_DATA Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <h> Stack / Heap Configuration
+// <o4> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o5> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <h> Exceptional Modes
+// <o6> UND Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o7> ABT Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o8> SVC Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o9> IRQ Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o10> FIQ Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// </h>
+// </h>
+// </h>
+ *----------------------------------------------------------------------------*/
+#define __RAM_BASE 0x80200000
+#define __RAM_SIZE 0x00200000
+
+#define __RW_DATA_SIZE 0x00100000
+#define __ZI_DATA_SIZE 0x000F0000
+
+#define __STACK_SIZE 0x00001000
+#define __HEAP_SIZE 0x00008000
+
+#define __UND_STACK_SIZE 0x00000100
+#define __ABT_STACK_SIZE 0x00000100
+#define __SVC_STACK_SIZE 0x00000100
+#define __IRQ_STACK_SIZE 0x00000100
+#define __FIQ_STACK_SIZE 0x00000100
+
+/*----------------------------------------------------------------------------*/
+
+/*--------------------- TTB Configuration ------------------------------------
+//
+// <h> TTB Configuration
+// <o0> TTB Base Address <0x0-0xFFFFFFFF:8>
+// <o1> TTB Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// </h>
+ *----------------------------------------------------------------------------*/
+#define __TTB_BASE 0x80500000
+#define __TTB_SIZE 0x00004000
+
+#endif /* __MEM_ARMCA7_H */
diff --git a/Device/ARM/ARMCA7/Include/system_ARMCA7.h b/Device/ARM/ARMCA7/Include/system_ARMCA7.h
index e357c6a..fe57009 100644
--- a/Device/ARM/ARMCA7/Include/system_ARMCA7.h
+++ b/Device/ARM/ARMCA7/Include/system_ARMCA7.h
@@ -35,17 +35,10 @@
typedef void(*IRQHandler)();
uint32_t InterruptHandlerRegister(IRQn_Type, IRQHandler);
uint32_t InterruptHandlerUnregister(IRQn_Type);
-
-/**
- * Initialize the system
- *
- * @param none
- * @return none
- *
- * @brief Setup the microcontroller system.
- * Initialize the System and update the SystemCoreClock variable.
- */
-extern void SystemInit (void);
+void SystemCoreClockUpdate (void);
+extern uint32_t SystemCoreClock;
+void SystemInit (void);
+void MMU_CreateTranslationTable(void);
#ifdef __cplusplus
}
diff --git a/Device/ARM/ARMCA7/Source/ARM/ARMCA7.sct b/Device/ARM/ARMCA7/Source/ARM/ARMCA7.sct
index 66cf773..c5612de 100644
--- a/Device/ARM/ARMCA7/Source/ARM/ARMCA7.sct
+++ b/Device/ARM/ARMCA7/Source/ARM/ARMCA7.sct
@@ -1,3 +1,4 @@
+#! armcc -E
;**************************************************
; Copyright (c) 2017 ARM Ltd. All rights reserved.
;**************************************************
@@ -8,30 +9,69 @@
; This platform has 2GB SDRAM starting at 0x80000000.
+#include "mem_ARMCA7.h"
-SDRAM 0x80000000 0x40000000
+SDRAM __ROM_BASE __ROM_SIZE ; load region size_region
{
- VECTORS +0 0x200000
+ VECTORS __ROM_BASE __ROM_SIZE ; load address = execution address
{
- * (RESET, +FIRST) ; Vector table and other (assembler) startup code
+ * (RESET, +FIRST) ; Vector table and other startup code
* (InRoot$$Sections) ; All (library) code that must be in a root region
* (+RO-CODE) ; Application RO code (.text)
* (+RO-DATA) ; Application RO data (.constdata)
}
- RW_DATA 0x80200000 0x100000
+ RW_DATA __RAM_BASE __RW_DATA_SIZE
{ * (+RW) } ; Application RW data (.data)
- ZI_DATA 0x80300000 0x0F0000
+ ZI_DATA (__RAM_BASE+
+ __RW_DATA_SIZE) __ZI_DATA_SIZE
{ * (+ZI) } ; Application ZI data (.bss)
- ARM_LIB_STACK 0x80400000 EMPTY -0x8000 ; Stack region growing down
+ ARM_LIB_HEAP (__RAM_BASE
+ +__RW_DATA_SIZE
+ +__ZI_DATA_SIZE) EMPTY __HEAP_SIZE ; Heap region growing up
{ }
- ARM_LIB_HEAP 0x803F0000 EMPTY 0x8000 ; Heap region growing up
+ UND_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE
+ -__IRQ_STACK_SIZE
+ -__SVC_STACK_SIZE
+ -__ABT_STACK_SIZE) EMPTY -__UND_STACK_SIZE ; UND mode stack
{ }
- TTB 0x80500000 EMPTY 0x4000
- { } ; Level-1 Translation Table for MMU
+ ABT_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE
+ -__IRQ_STACK_SIZE
+ -__SVC_STACK_SIZE) EMPTY -__ABT_STACK_SIZE ; ABT mode stack
+ { }
+
+ SVC_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE
+ -__IRQ_STACK_SIZE) EMPTY -__SVC_STACK_SIZE ; SVC mode stack
+ { }
+
+ IRQ_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE) EMPTY -__IRQ_STACK_SIZE ; IRQ mode stack
+ { }
+
+ FIQ_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE) EMPTY -__FIQ_STACK_SIZE ; FIQ mode stack
+ { }
+ ARM_LIB_STACK (__RAM_BASE
+ +__RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
+ { }
+
+ TTB __TTB_BASE EMPTY __TTB_SIZE ; Level-1 Translation Table for MMU
+ { }
}
diff --git a/Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.c b/Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.c
new file mode 100644
index 0000000..18fc611
--- /dev/null
+++ b/Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ * @file system_ARMCA7.c
+ * @brief CMSIS Device System Source File for ARM Cortex-A7 Device Series
+ * @version V1.00
+ * @date 22 Feb 2017
+ *
+ * @note
+ *
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ARMCA7.h>
+
+/*----------------------------------------------------------------------------
+ Definitions
+ *----------------------------------------------------------------------------*/
+#define USR_MODE 0x10 // User mode
+#define FIQ_MODE 0x11 // Fast Interrupt Request mode
+#define IRQ_MODE 0x12 // Interrupt Request mode
+#define SVC_MODE 0x13 // Supervisor mode
+#define ABT_MODE 0x17 // Abort mode
+#define UND_MODE 0x1B // Undefined Instruction mode
+#define SYS_MODE 0x1F // System mode
+
+/*----------------------------------------------------------------------------
+ Linker generated Symbols
+ *----------------------------------------------------------------------------*/
+extern uint32_t Image$$FIQ_STACK$$ZI$$Limit;
+extern uint32_t Image$$IRQ_STACK$$ZI$$Limit;
+extern uint32_t Image$$SVC_STACK$$ZI$$Limit;
+extern uint32_t Image$$ABT_STACK$$ZI$$Limit;
+extern uint32_t Image$$UND_STACK$$ZI$$Limit;
+extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
+
+/*----------------------------------------------------------------------------
+ Internal References
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void);
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void IRQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector Table
+ *----------------------------------------------------------------------------*/
+void Vectors(void) __attribute__ ((section("RESET")));
+__ASM void Vectors(void) {
+ IMPORT Reset_Handler
+ IMPORT Undef_Handler
+ IMPORT SVC_Handler
+ IMPORT PAbt_Handler
+ IMPORT DAbt_Handler
+ IMPORT IRQ_Handler
+ IMPORT FIQ_Handler
+ LDR PC, =Reset_Handler
+ LDR PC, =Undef_Handler
+ LDR PC, =SVC_Handler
+ LDR PC, =PAbt_Handler
+ LDR PC, =DAbt_Handler
+ NOP
+ LDR PC, =IRQ_Handler
+ LDR PC, =FIQ_Handler
+}
+
+/*----------------------------------------------------------------------------
+ Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void) {
+uint32_t reg;
+
+ // Put any cores other than 0 to sleep
+ if ((__get_MPIDR()&3U)!=0) __WFI();
+
+ reg = __get_SCTLR(); // Read CP15 System Control register
+ reg &= ~(0x1 << 12); // Clear I bit 12 to disable I Cache
+ reg &= ~(0x1 << 2); // Clear C bit 2 to disable D Cache
+ reg &= ~(0x1 << 0); // Clear M bit 0 to disable MMU
+ reg &= ~(0x1 << 11); // Clear Z bit 11 to disable branch prediction
+ reg &= ~(0x1 << 13); // Clear V bit 13 to disable hivecs
+ __set_SCTLR(reg); // Write value back to CP15 System Control register
+ __ISB();
+
+ reg = __get_ACTRL(); // Read CP15 Auxiliary Control Register
+ reg |= (0x1 << 1); // Enable L2 prefetch hint (UNK/WI since r4p1)
+ __set_ACTRL(reg); // Write CP15 Auxiliary Control Register
+
+ __set_VBAR((uint32_t)((uint32_t*)&Vectors));
+
+ // Setup Stack for each exceptional mode
+ __set_mode(FIQ_MODE);
+ __set_SP((uint32_t)&Image$$FIQ_STACK$$ZI$$Limit);
+ __set_mode(IRQ_MODE);
+ __set_SP((uint32_t)&Image$$IRQ_STACK$$ZI$$Limit);
+ __set_mode(SVC_MODE);
+ __set_SP((uint32_t)&Image$$SVC_STACK$$ZI$$Limit);
+ __set_mode(ABT_MODE);
+ __set_SP((uint32_t)&Image$$ABT_STACK$$ZI$$Limit);
+ __set_mode(UND_MODE);
+ __set_SP((uint32_t)&Image$$UND_STACK$$ZI$$Limit);
+ __set_mode(SYS_MODE);
+ __set_SP((uint32_t)&Image$$ARM_LIB_STACK$$ZI$$Limit);
+
+ // Create Translation Table
+ MMU_CreateTranslationTable();
+
+ // Invalidate entire Unified TLB
+ __set_TLBIALL(0);
+ // Invalidate entire branch predictor array
+ __set_BPIALL(0);
+ __DSB();
+ __ISB();
+ // Invalidate instruction cache and flush branch target cache
+ __set_ICIALLU(0);
+ __DSB();
+ __ISB();
+
+ // Invalidate data cache
+ __L1C_CleanInvalidateCache(0);
+
+ // Invalidate entire Unified TLB
+ __set_TLBIALL(0);
+ // Invalidate entire branch predictor array
+ __set_BPIALL(0);
+ __DSB();
+ __ISB();
+ // Invalidate instruction cache and flush branch target cache
+ __set_ICIALLU(0);
+ __DSB();
+ __ISB();
+
+ // Enable MMU, but leave caches disabled (they will be enabled later)
+ reg = __get_SCTLR(); // Read CP15 System Control register
+ reg |= (0x1 << 29); // Set AFE bit 29 to enable simplified access permissions model
+ reg &= ~(0x1 << 28); // Clear TRE bit 28 to disable TEX remap
+ reg &= ~(0x1 << 12); // Clear I bit 12 to disable I Cache
+ reg &= ~(0x1 << 2); // Clear C bit 2 to disable D Cache
+ reg &= ~(0x1 << 1); // Clear A bit 1 to disable strict alignment fault checking
+ reg |= (0x1 << 0); // Set M bit 0 to enable MMU
+ __set_SCTLR(reg); // Write CP15 System Control register
+
+ SystemInit();
+
+ extern void __main(void);
+ __main();
+}
+
+/*----------------------------------------------------------------------------
+ Default Handler for Exceptions / Interrupts
+ *----------------------------------------------------------------------------*/
+void Default_Handler(void) {
+ while(1);
+}
diff --git a/Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.s b/Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.s
deleted file mode 100644
index c564d12..0000000
--- a/Device/ARM/ARMCA7/Source/ARM/startup_ARMCA7.s
+++ /dev/null
@@ -1,447 +0,0 @@
-;/**************************************************************************//**
-; * @file startup_ARMCA7.s
-; * @brief CMSIS Core Device Startup File for ARM Cortex-A7 Device Series
-; * @version V1.00
-; * @date 22 Feb 2017
-; *
-; * @note
-; *
-; ******************************************************************************/
-;/*
-; * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
-; *
-; * SPDX-License-Identifier: Apache-2.0
-; *
-; * Licensed under the Apache License, Version 2.0 (the License); you may
-; * not use this file except in compliance with the License.
-; * You may obtain a copy of the License at
-; *
-; * www.apache.org/licenses/LICENSE-2.0
-; *
-; * Unless required by applicable law or agreed to in writing, software
-; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-; * See the License for the specific language governing permissions and
-; * limitations under the License.
-; */
-;/*
-;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
-;*/
-
-GICC_OFFSET EQU 0x2000
-ICCIAR_OFFSET EQU 0x000C
-ICCEOIR_OFFSET EQU 0x0010
-
-Mode_USR EQU 0x10
-Mode_FIQ EQU 0x11
-Mode_IRQ EQU 0x12
-Mode_SVC EQU 0x13
-Mode_ABT EQU 0x17
-Mode_UND EQU 0x1B
-Mode_SYS EQU 0x1F
-
-I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
-F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
-T_Bit EQU 0x20 ; when T bit is set, core is in Thumb state
-
-Sect_Normal EQU 0x00005c06 ;outer & inner wb/wa, non-shareable, executable, rw, domain 0, base addr 0
-Sect_Normal_Cod EQU 0x0000dc06 ;outer & inner wb/wa, non-shareable, executable, ro, domain 0, base addr 0
-Sect_Normal_RO EQU 0x0000dc16 ;as Sect_Normal_Cod, but not executable
-Sect_Normal_RW EQU 0x00005c16 ;as Sect_Normal_Cod, but writeable and not executable
-Sect_SO EQU 0x00000c12 ;strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0
-Sect_Device_RO EQU 0x00008c12 ;device, non-shareable, non-executable, ro, domain 0, base addr 0
-Sect_Device_RW EQU 0x00000c12 ;as Sect_Device_RO, but writeable
-Sect_Fault EQU 0x00000000 ;this translation will fault (the bottom 2 bits are important, the rest are ignored)
-
-RAM_BASE EQU 0x80000000
-VRAM_BASE EQU 0x18000000
-SRAM_BASE EQU 0x2e000000
-ETHERNET EQU 0x1a000000
-CS3_PERIPHERAL_BASE EQU 0x1c000000
-
-; <h> Stack Configuration
-; <o> Stack Size (in Bytes, per mode) <0x0-0xFFFFFFFF:8>
-; </h>
-
-UND_Stack_Size EQU 0x00000100
-SVC_Stack_Size EQU 0x00000100
-ABT_Stack_Size EQU 0x00000100
-FIQ_Stack_Size EQU 0x00000000
-IRQ_Stack_Size EQU 0x00000100
-USR_Stack_Size EQU 0x00000100
-
-ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
- FIQ_Stack_Size + IRQ_Stack_Size)
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE USR_Stack_Size
-__initial_sp SPACE ISR_Stack_Size
-
-Stack_Top
-
-
-; <h> Heap Configuration
-; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-; </h>
-
-Heap_Size EQU 0x00000000
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
-
- PRESERVE8
- ARM
-
-
-; Vector Table Mapped to Address 0 at Reset
-
- AREA RESET, CODE, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors LDR PC, Reset_Addr ; Address of Reset Handler
- LDR PC, Undef_Addr ; Address of Undef Handler
- LDR PC, SVC_Addr ; Address of SVC Handler
- LDR PC, PAbt_Addr ; Address of Prefetch Abort Handler
- LDR PC, DAbt_Addr ; Address of Data Abort Handler
- NOP ; Reserved Vector
- LDR PC, IRQ_Addr ; Address of IRQ Handler
- LDR PC, FIQ_Addr ; Address of FIQ Handler
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
-Reset_Addr DCD Reset_Handler
-Undef_Addr DCD Undef_Handler
-SVC_Addr DCD SVC_Handler
-PAbt_Addr DCD PAbt_Handler
-DAbt_Addr DCD DAbt_Handler
-IRQ_Addr DCD IRQ_Handler
-FIQ_Addr DCD FIQ_Handler
-
- AREA |.text|, CODE, READONLY
-
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
-
- ; Put any cores other than 0 to sleep
- MRC p15, 0, R0, c0, c0, 5 ; Read MPIDR
- ANDS R0, R0, #3
-goToSleep
- WFINE
- BNE goToSleep
-
- MRC p15, 0, R0, c1, c0, 0 ; Read CP15 System Control register
- BIC R0, R0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
- BIC R0, R0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
- BIC R0, R0, #0x1 ; Clear M bit 0 to disable MMU
- BIC R0, R0, #(0x1 << 11) ; Clear Z bit 11 to disable branch prediction
- BIC R0, R0, #(0x1 << 13) ; Clear V bit 13 to disable hivecs
- MCR p15, 0, R0, c1, c0, 0 ; Write value back to CP15 System Control register
- ISB
-
-; ACTLR.SMP bit must be set before the caches and MMU are enabled,
-; or any cache and TLB maintenance operations are performed, even for "AMP" CPUs
- MRC p15, 0, r0, c1, c0, 1 ; Read CP15 Auxiliary Control Register
- ORR r0, r0, #(1 << 6) ; Set ACTLR.SMP bit
- ORR r0, r0, #(1 << 13) ; Set L1PCTL L1 Data prefetch control to 0b11
- ORR r0, r0, #(1 << 14) ; 3 outstanding pre-fetches permitted, this is the reset value
- MCR p15, 0, r0, c1, c0, 1 ; Write CP15 Auxiliary Control Register
-
-; Set Vector Base Address Register (VBAR) to point to this application's vector table
- LDR R0, =__Vectors
- MCR p15, 0, R0, c12, c0, 0
-
-; Setup Stack for each exceptional mode
- LDR R0, =Stack_Top
-
-; Enter Undefined Instruction Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_UND:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #UND_Stack_Size
-
-; Enter Abort Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_ABT:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #ABT_Stack_Size
-
-; Enter FIQ Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_FIQ:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #FIQ_Stack_Size
-
-; Enter IRQ Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_IRQ:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #IRQ_Stack_Size
-
-; Enter Supervisor Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_SVC:OR:I_Bit:OR:F_Bit
- MOV SP, R0
-
-; Enter System Mode to complete initialization and enter kernel
- MSR CPSR_C, #Mode_SYS:OR:I_Bit:OR:F_Bit
- MOV SP, R0
-
- IMPORT MMU_CreateTranslationTable
- BL MMU_CreateTranslationTable
-
- MOV r0, #0x0
- MCR p15, 0, r0, c8, c7, 0 ; TLBIALL - Invalidate entire Unified TLB
- MCR p15, 0, r0, c7, c5, 6 ; BPIALL - Invalidate entire branch predictor array
- DSB
- ISB
- MCR p15, 0, r0, c7, c5, 0 ; ICIALLU - Invalidate instruction cache and flush branch target cache
- DSB
- ISB
-
-; Invalidate data cache
- MOV r0, #0x0 ; 0 = invalidate data cache, 1 = clean data cache.
-
- MRC p15, 1, R6, c0, c0, 1 ; Read CLIDR
- ANDS R3, R6, #0x07000000 ; Extract coherency level
- MOV R3, R3, LSR #23 ; Total cache levels << 1
- BEQ Finished ; If 0, no need to clean
-
- MOV R10, #0 ; R10 holds current cache level << 1
-Loop1 ADD R2, R10, R10, LSR #1 ; R2 holds cache "Set" position
- MOV R1, R6, LSR R2 ; Bottom 3 bits are the Cache-type for this level
- AND R1, R1, #7 ; Isolate those lower 3 bits
- CMP R1, #2
- BLT Skip ; No cache or only instruction cache at this level
-
- MCR p15, 2, R10, c0, c0, 0 ; Write the Cache Size selection register
- ISB ; ISB to sync the change to the CacheSizeID reg
- MRC p15, 1, R1, c0, c0, 0 ; Reads current Cache Size ID register
- AND R2, R1, #7 ; Extract the line length field
- ADD R2, R2, #4 ; Add 4 for the line length offset (log2 16 bytes)
- LDR R4, =0x3FF
- ANDS R4, R4, R1, LSR #3 ; R4 is the max number on the way size (right aligned)
- CLZ R5, R4 ; R5 is the bit position of the way size increment
- LDR R7, =0x7FFF
- ANDS R7, R7, R1, LSR #13 ; R7 is the max number of the index size (right aligned)
-
-Loop2 MOV R9, R4 ; R9 working copy of the max way size (right aligned)
-
-Loop3 ORR R11, R10, R9, LSL R5 ; Factor in the Way number and cache number into R11
- ORR R11, R11, R7, LSL R2 ; Factor in the Set number
- CMP R0, #0
- BNE Dccsw
- MCR p15, 0, R11, c7, c6, 2 ; DCISW. Invalidate by Set/Way
- B cont
-Dccsw CMP R0, #1
- BNE Dccisw
- MCR p15, 0, R11, c7, c10, 2 ; DCCSW. Clean by Set/Way
- B cont
-Dccisw MCR p15, 0, R11, c7, c14, 2 ; DCCISW. Clean and Invalidate by Set/Way
-cont SUBS R9, R9, #1 ; Decrement the Way number
- BGE Loop3
- SUBS R7, R7, #1 ; Decrement the Set number
- BGE Loop2
-Skip ADD R10, R10, #2 ; Increment the cache number
- CMP R3, R10
- BGT Loop1
-Finished
- DSB
-
-; Enable MMU, but leave caches disabled (they will be enabled later)
- MRC p15, 0, r0, c1, c0, 0 ; Read CP15 System Control register
- ORR r0, r0, #(0x1 << 29) ; Set AFE bit 29 to enable simplified access permissions model
- BIC r0, r0, #(0x1 << 28) ; Clear TRE bit 28 to disable TEX remap
- BIC r0, r0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
- BIC r0, r0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
- BIC r0, r0, #(0x1 << 1) ; Clear A bit 1 to disable strict alignment fault checking
- ORR r0, r0, #0x1 ; Set M bit 0 to enable MMU
- MCR p15, 0, r0, c1, c0, 0 ; Write CP15 System Control register
-
-; USR/SYS stack pointer will be set during kernel init
-
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BLX R0
-
- ENDP
-
-Undef_Handler\
- PROC
- EXPORT Undef_Handler [WEAK]
- IMPORT CUndefHandler
- SRSFD SP!, #Mode_UND
- PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack
-
- MRS R0, SPSR
- TST R0, #T_Bit ; Check mode
- MOVEQ R1, #4 ; R1 = 4 ARM mode
- MOVNE R1, #2 ; R1 = 2 Thumb mode
- SUB R0, LR, R1
- LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction
- BEQ undef_cont
-
- ;Thumb instruction
- ;Determine if it is a 32-bit Thumb instruction
- LDRH R0, [R0]
- MOV R2, #0x1c
- CMP R2, R0, LSR #11
- BHS undef_cont ;16-bit Thumb instruction
-
- ;32-bit Thumb instruction. Unaligned - we need to reconstruct the offending instruction
- LDRH R2, [LR]
- ORR R0, R2, R0, LSL #16
-undef_cont
- MOV R2, LR ; Set LR to third argument
-
- AND R12, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R12 ; Adjust stack
- PUSH {R12, LR} ; Store stack adjustment and dummy LR
-
- ;R0 Offending instruction
- ;R1 =2 (Thumb) or =4 (ARM)
- BL CUndefHandler
-
- POP {R12, LR} ; Get stack adjustment & discard dummy LR
- ADD SP, SP, R12 ; Unadjust stack
-
- LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry
- SUB LR, LR, R0
- LDR R0, [SP, #28] ; Restore stacked SPSR
- MSR SPSR_CXSF, R0
- POP {R0-R4, R12} ; Restore stacked APCS registers
- ADD SP, SP, #8 ; Adjust SP for already-restored banked registers
- MOVS PC, LR
- ENDP
-
-PAbt_Handler\
- PROC
- EXPORT PAbt_Handler [WEAK]
- IMPORT CPAbtHandler
- SUB LR, LR, #4 ; Pre-adjust LR
- SRSFD SP!, #Mode_ABT ; Save LR and SPRS to ABT mode stack
- PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
- MRC p15, 0, R0, c5, c0, 1 ; IFSR
- MRC p15, 0, R1, c6, c0, 2 ; IFAR
-
- MOV R2, LR ; Set LR to third argument
-
- AND R12, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R12 ; Adjust stack
- PUSH {R12, LR} ; Store stack adjustment and dummy LR
-
- BL CPAbtHandler
-
- POP {R12, LR} ; Get stack adjustment & discard dummy LR
- ADD SP, SP, R12 ; Unadjust stack
-
- POP {R0-R4, R12} ; Restore stack APCS registers
- RFEFD SP! ; Return from exception
- ENDP
-
-
-DAbt_Handler\
- PROC
- EXPORT DAbt_Handler [WEAK]
- IMPORT CDAbtHandler
- SUB LR, LR, #8 ; Pre-adjust LR
- SRSFD SP!, #Mode_ABT ; Save LR and SPRS to ABT mode stack
- PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
- CLREX ; State of exclusive monitors unknown after taken data abort
- MRC p15, 0, R0, c5, c0, 0 ; DFSR
- MRC p15, 0, R1, c6, c0, 0 ; DFAR
-
- MOV R2, LR ; Set LR to third argument
-
- AND R12, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R12 ; Adjust stack
- PUSH {R12, LR} ; Store stack adjustment and dummy LR
-
- BL CDAbtHandler
-
- POP {R12, LR} ; Get stack adjustment & discard dummy LR
- ADD SP, SP, R12 ; Unadjust stack
-
- POP {R0-R4, R12} ; Restore stacked APCS registers
- RFEFD SP! ; Return from exception
- ENDP
-
-FIQ_Handler\
- PROC
- EXPORT FIQ_Handler [WEAK]
- B .
- ENDP
-
-SVC_Handler\
- PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-
-IRQ_Handler\
- PROC
- EXPORT IRQ_Handler [WEAK]
- IMPORT IRQCount
- IMPORT IRQTable
- IMPORT IRQNestLevel ; Flag indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR.
-
-
- ;prologue
- SUB LR, LR, #4 ; Pre-adjust LR
- SRSFD SP!, #Mode_SVC ; Save LR_IRQ and SPRS_IRQ to SVC mode stack
- CPS #Mode_SVC ; Switch to SVC mode, to avoid a nested interrupt corrupting LR on a BL
- PUSH {R0-R3, R12} ; Save remaining APCS corruptible registers to SVC stack
-
- AND R1, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R1 ; Adjust stack
- PUSH {R1, LR} ; Store stack adjustment and LR_SVC to SVC stack
-
- LDR R0, =IRQNestLevel ; Get address of nesting counter
- LDR R1, [R0]
- ADD R1, R1, #1 ; Increment nesting counter
- STR R1, [R0]
-
- ;identify and acknowledge interrupt
- MRC p15, 4, R1, c15, c0, 0 ; Read CBAR
- ADD R1, R1, #GICC_OFFSET ; Add GICC offset
- LDR R0, [R1, #ICCIAR_OFFSET] ; Read ICCIAR (GIC CPU Interface register)
- DSB ; Ensure that interrupt acknowledge completes before re-enabling interrupts
-
- LDR R2, =IRQCount ; Read number of entries in IRQ handler table
- LDR R2, [R2]
- CMP R0, R2 ; Is there a handler for this IRQ?
- BHS end_int ; No handler, so return as normal
- LDR R2, =IRQTable ; Get address of handler
- LDR R2, [R2, R0, LSL #2]
- CMP R2, #0 ; Clean up and return if handler address is 0
- BEQ end_int
- PUSH {R0,R1}
-
- CPSIE i ; Now safe to re-enable interrupts
- BLX R2 ; Call handler. R0 = IRQ number. Beware calls to PendSV_Handler and OS_Tick_Handler do not return this way
- CPSID i ; Disable interrupts again
-
- POP {R0,R1}
- DSB ; Ensure that interrupt source is cleared before signalling End Of Interrupt
-end_int
- ; R0 still contains the interrupt ID
- ; R1 still contains GICI_BASE
- STR R0, [R1, #ICCEOIR_OFFSET] ; Normal end-of-interrupt write to EOIR (GIC CPU Interface register) to clear the active bit
-ret_irq
- ;epilogue
- LDR R0, =IRQNestLevel ; Get address of nesting counter
- LDR R1, [R0]
- SUB R1, R1, #1 ; Decrement nesting counter
- STR R1, [R0]
-
- POP {R1, LR} ; Get stack adjustment and restore LR_SVC
- ADD SP, SP, R1 ; Unadjust stack
-
- POP {R0-R3,R12} ; Restore stacked APCS registers
- RFEFD SP! ; Return from exception
- ENDP
-
- END
diff --git a/Device/ARM/ARMCA7/Source/mmu_ARMCA7.c b/Device/ARM/ARMCA7/Source/mmu_ARMCA7.c
index fb7e38e..d65df5e 100644
--- a/Device/ARM/ARMCA7/Source/mmu_ARMCA7.c
+++ b/Device/ARM/ARMCA7/Source/mmu_ARMCA7.c
@@ -99,7 +99,6 @@
//Domain 0 is always the Client domain
//Descriptors should place all memory in domain 0
-#include <stdint.h>
#include "ARMCA7.h"
diff --git a/Device/ARM/ARMCA7/Source/system_ARMCA7.c b/Device/ARM/ARMCA7/Source/system_ARMCA7.c
index 7a71b28..4b7050d 100644
--- a/Device/ARM/ARMCA7/Source/system_ARMCA7.c
+++ b/Device/ARM/ARMCA7/Source/system_ARMCA7.c
@@ -26,264 +26,60 @@
*/
#include <ARMCA7.h>
-#include <stdint.h>
-extern void $Super$$main(void);
-__asm void __FPU_Enable(void);
+#define SYSTEM_CLOCK 12000000U
-// Flag indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR.
-uint32_t IRQNestLevel = 0;
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = SYSTEM_CLOCK;
-/**
- * Initialize the memory subsystem.
- *
- * @param none
- * @return none
- *
- * @brief Initialize the memory subsystem, including enabling the cache and BTAC. Requires PL1, so implemented as an SVC in case threads are USR mode.
- */
-#pragma push
-#pragma arm
-void __svc(1) EnableCaches(void);
-void __SVC_1(void) {
-
-/* Before enabling the caches, the instruction cache, the data cache, TLB, and BTAC must have been invalidated.
- * You are not required to invalidate the main TLB, even though it is recommended for safety
- * reasons. This ensures compatibility with future revisions of the processor. */
-
-// unsigned int l2_id;
-
- /* After MMU is enabled and data has been invalidated, enable caches and BTAC */
- L1C_EnableCaches();
- L1C_EnableBTAC();
-
- /* If L2C-310 is present, Invalidate and Enable L2 cache here */
-// l2_id = L2C_GetID();
-// if (l2_id)
-// {
-// L2C_InvAllByWay();
-// L2C_Enable();
-// }
+/*----------------------------------------------------------------------------
+ System Core Clock update function
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)
+{
+ SystemCoreClock = SYSTEM_CLOCK;
}
-#pragma pop
-IRQHandler IRQTable[] = {
- 0, //IRQ 0
- 0, //IRQ 1
- 0, //IRQ 2
- 0, //IRQ 3
- 0, //IRQ 4
- 0, //IRQ 5
- 0, //IRQ 6
- 0, //IRQ 7
- 0, //IRQ 8
- 0, //IRQ 9
- 0, //IRQ 10
- 0, //IRQ 11
- 0, //IRQ 12
- 0, //IRQ 13
- 0, //IRQ 14
- 0, //IRQ 15
- 0, //IRQ 16
- 0, //IRQ 17
- 0, //IRQ 18
- 0, //IRQ 19
- 0, //IRQ 20
- 0, //IRQ 21
- 0, //IRQ 22
- 0, //IRQ 23
- 0, //IRQ 24
- 0, //IRQ 25
- 0, //IRQ 26
- 0, //IRQ 27
- 0, //IRQ 28
- 0, //IRQ 29
- 0, //IRQ 30
- 0, //IRQ 31
- 0, //IRQ 32
- 0, //IRQ 33
- 0, //IRQ 34
- 0, //IRQ 35
- 0, //IRQ 36
- 0, //IRQ 37
- 0, //IRQ 38
- 0, //IRQ 39
- 0 //IRQ 40
-};
-uint32_t IRQCount = sizeof IRQTable / 4;
+/*----------------------------------------------------------------------------
+ IRQ Handler Register/Unregister
+ *----------------------------------------------------------------------------*/
+IRQHandler IRQTable[40U] = { 0U };
+
+uint32_t IRQCount = sizeof IRQTable / 4U;
uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler)
{
- if (irq < IRQCount) {
- IRQTable[irq] = handler;
- return 0;
- }
- else {
- return 1;
- }
+ if (irq < IRQCount) {
+ IRQTable[irq] = handler;
+ return 0U;
+ }
+ else {
+ return 1U;
+ }
}
uint32_t InterruptHandlerUnregister (IRQn_Type irq)
{
- if (irq < IRQCount) {
- IRQTable[irq] = 0;
- return 0;
- }
- else {
- return 1;
- }
+ if (irq < IRQCount) {
+ IRQTable[irq] = 0U;
+ return 0U;
+ }
+ else {
+ return 1U;
+ }
}
-/**
- * Initialize the system
- *
- * @param none
- * @return none
- *
- * @brief Setup the microcontroller system.
- * Initialize the System.
- */
+/*----------------------------------------------------------------------------
+ System Initialization
+ *----------------------------------------------------------------------------*/
void SystemInit (void)
{
-/* do not use global variables because this function is called before
- reaching pre-main. RW section may be overwritten afterwards. */
- GIC_Enable();
-}
-
-void $Sub$$main(void)
-{
-#ifdef __CMSIS_RTOS
- extern void PendSV_Handler(uint32_t);
- extern void OS_Tick_Handler(uint32_t);
- InterruptHandlerRegister(SGI0_IRQn , PendSV_Handler);
- InterruptHandlerRegister(PrivTimer_IRQn, OS_Tick_Handler);
- EnableCaches();
-#endif
-
- $Super$$main(); //Call main
-}
-
-//Fault Status Register (IFSR/DFSR) definitions
-#define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
-#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_SECOND 0x0e //sync/external
-#define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
-#define FSR_SYNC_PARITY_TTB_WALK_SECOND 0x1e //sync/external
-#define FSR_TRANSLATION_FAULT_FIRST 0x05 //MMU Fault - internal
-#define FSR_TRANSLATION_FAULT_SECOND 0x07 //MMU Fault - internal
-#define FSR_ACCESS_FLAG_FAULT_FIRST 0x03 //MMU Fault - internal
-#define FSR_ACCESS_FLAG_FAULT_SECOND 0x06 //MMU Fault - internal
-#define FSR_DOMAIN_FAULT_FIRST 0x09 //MMU Fault - internal
-#define FSR_DOMAIN_FAULT_SECOND 0x0b //MMU Fault - internal
-#define FSR_PERMISSION_FAULT_FIRST 0x0f //MMU Fault - internal
-#define FSR_PERMISSION_FAULT_SECOND 0x0d //MMU Fault - internal
-#define FSR_DEBUG_EVENT 0x02 //internal
-#define FSR_SYNC_EXT_ABORT 0x08 //sync/external
-#define FSR_TLB_CONFLICT_ABORT 0x10 //sync/external
-#define FSR_LOCKDOWN 0x14 //internal
-#define FSR_COPROCESSOR_ABORT 0x1a //internal
-#define FSR_SYNC_PARITY_ERROR 0x19 //sync/external
-#define FSR_ASYNC_EXTERNAL_ABORT 0x16 //DFSR only - async/external
-#define FSR_ASYNC_PARITY_ERROR 0x18 //DFSR only - async/external
-
-void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
- uint32_t FS = (DFSR & (1 << 10)) >> 6 | (DFSR & 0x0f); //Store Fault Status
-
- switch(FS) {
- //Synchronous parity errors - retry
- case FSR_SYNC_PARITY_ERROR:
- case FSR_SYNC_PARITY_TTB_WALK_FIRST:
- case FSR_SYNC_PARITY_TTB_WALK_SECOND:
- return;
-
- //Your code here. Value in DFAR is invalid for some fault statuses.
- case FSR_ALIGNMENT_FAULT:
- case FSR_INSTRUCTION_CACHE_MAINTENANCE:
- case FSR_SYNC_EXT_TTB_WALK_FIRST:
- case FSR_SYNC_EXT_TTB_WALK_SECOND:
- case FSR_TRANSLATION_FAULT_FIRST:
- case FSR_TRANSLATION_FAULT_SECOND:
- case FSR_ACCESS_FLAG_FAULT_FIRST:
- case FSR_ACCESS_FLAG_FAULT_SECOND:
- case FSR_DOMAIN_FAULT_FIRST:
- case FSR_DOMAIN_FAULT_SECOND:
- case FSR_PERMISSION_FAULT_FIRST:
- case FSR_PERMISSION_FAULT_SECOND:
- case FSR_DEBUG_EVENT:
- case FSR_SYNC_EXT_ABORT:
- case FSR_TLB_CONFLICT_ABORT:
- case FSR_LOCKDOWN:
- case FSR_COPROCESSOR_ABORT:
- case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid
- case FSR_ASYNC_PARITY_ERROR: //DFAR invalid
- default:
- while(1);
- }
-}
-
-void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
- uint32_t FS = (IFSR & (1 << 10)) >> 6 | (IFSR & 0x0f); //Store Fault Status
-
- switch(FS) {
- //Synchronous parity errors - retry
- case FSR_SYNC_PARITY_ERROR:
- case FSR_SYNC_PARITY_TTB_WALK_FIRST:
- case FSR_SYNC_PARITY_TTB_WALK_SECOND:
- return;
-
- //Your code here. Value in IFAR is invalid for some fault statuses.
- case FSR_SYNC_EXT_TTB_WALK_FIRST:
- case FSR_SYNC_EXT_TTB_WALK_SECOND:
- case FSR_TRANSLATION_FAULT_FIRST:
- case FSR_TRANSLATION_FAULT_SECOND:
- case FSR_ACCESS_FLAG_FAULT_FIRST:
- case FSR_ACCESS_FLAG_FAULT_SECOND:
- case FSR_DOMAIN_FAULT_FIRST:
- case FSR_DOMAIN_FAULT_SECOND:
- case FSR_PERMISSION_FAULT_FIRST:
- case FSR_PERMISSION_FAULT_SECOND:
- case FSR_DEBUG_EVENT: //IFAR invalid
- case FSR_SYNC_EXT_ABORT:
- case FSR_TLB_CONFLICT_ABORT:
- case FSR_LOCKDOWN:
- case FSR_COPROCESSOR_ABORT:
- default:
- while(1);
- }
-}
-
-//returns amount to decrement lr by
-//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 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) {
- const int THUMB = 2;
- const int ARM = 4;
- //Lazy VFP/NEON initialisation and switching
-
- // (ARM ARM section A7.5) VFP data processing 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) {
- __FPU_Enable();
- 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))) {
- __FPU_Enable();
- return state;
- }
-
- //Add code here for other Undef cases
- while(1);
+/* do not use global variables because this function is called before
+ reaching pre-main. RW section may be overwritten afterwards. */
+ GIC_Enable();
+ L1C_EnableCaches();
+ L1C_EnableBTAC();
+ __FPU_Enable();
}
diff --git a/Device/ARM/ARMCA9/Include/ARMCA9.h b/Device/ARM/ARMCA9/Include/ARMCA9.h
index 825341d..567831e 100644
--- a/Device/ARM/ARMCA9/Include/ARMCA9.h
+++ b/Device/ARM/ARMCA9/Include/ARMCA9.h
@@ -107,8 +107,10 @@
#define VE_A9_MP_CLCD_BASE (0x001F0000UL + 0x1C000000UL) /*!< (CLCD ) Base Address */
#define VE_A9_MP_GIC_DISTRIBUTOR_BASE (0x00001000UL + 0x2C000000UL) /*!< (GIC DIST ) Base Address */
#define VE_A9_MP_GIC_INTERFACE_BASE (0x00000100UL + 0x2C000000UL) /*!< (GIC CPU IF) Base Address */
+#define VE_A9_MP_PRIVATE_TIMER (0x00000600UL + 0x2C000000UL) /*!< (PTIM ) Base Address */
#define GIC_DISTRIBUTOR_BASE VE_A9_MP_GIC_DISTRIBUTOR_BASE
#define GIC_INTERFACE_BASE VE_A9_MP_GIC_INTERFACE_BASE
+#define TIMER_BASE VE_A9_MP_PRIVATE_TIMER
//The VE-A9 model implements L1 cache as architecturally defined, but does not implement L2 cache.
//Do not enable the L2 cache if you are running RTX on a VE-A9 model as it may cause a data abort.
diff --git a/Device/ARM/ARMCA9/Include/mem_ARMCA9.h b/Device/ARM/ARMCA9/Include/mem_ARMCA9.h
new file mode 100644
index 0000000..4bebfdf
--- /dev/null
+++ b/Device/ARM/ARMCA9/Include/mem_ARMCA9.h
@@ -0,0 +1,94 @@
+/**************************************************************************//**
+ * @file mem_ARMCA9.h
+ * @brief Memory base and size definitions (used in scatter file)
+ * @version V1.00
+ * @date 22 Feb 2017
+ *
+ * @note
+ *
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEM_ARMCA9_H
+#define __MEM_ARMCA9_H
+
+/*----------------------------------------------------------------------------
+ User Stack & Heap size definition
+ *----------------------------------------------------------------------------*/
+/*
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+*/
+
+/*--------------------- ROM Configuration ------------------------------------
+//
+// <h> ROM Configuration
+// <o0> ROM Base Address <0x0-0xFFFFFFFF:8>
+// <o1> ROM Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// </h>
+ *----------------------------------------------------------------------------*/
+#define __ROM_BASE 0x80000000
+#define __ROM_SIZE 0x00200000
+
+/*--------------------- RAM Configuration -----------------------------------
+// <h> RAM Configuration
+// <o0> RAM Base Address <0x0-0xFFFFFFFF:8>
+// <o1> RAM Total Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o2> RW_DATA Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o3> ZI_DATA Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <h> Stack / Heap Configuration
+// <o4> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o5> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <h> Exceptional Modes
+// <o6> UND Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o7> ABT Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o8> SVC Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o9> IRQ Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// <o10> FIQ Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// </h>
+// </h>
+// </h>
+ *----------------------------------------------------------------------------*/
+#define __RAM_BASE 0x80200000
+#define __RAM_SIZE 0x00200000
+
+#define __RW_DATA_SIZE 0x00100000
+#define __ZI_DATA_SIZE 0x000F0000
+
+#define __STACK_SIZE 0x00001000
+#define __HEAP_SIZE 0x00008000
+
+#define __UND_STACK_SIZE 0x00000100
+#define __ABT_STACK_SIZE 0x00000100
+#define __SVC_STACK_SIZE 0x00000100
+#define __IRQ_STACK_SIZE 0x00000100
+#define __FIQ_STACK_SIZE 0x00000100
+
+/*----------------------------------------------------------------------------*/
+
+/*--------------------- TTB Configuration ------------------------------------
+//
+// <h> TTB Configuration
+// <o0> TTB Base Address <0x0-0xFFFFFFFF:8>
+// <o1> TTB Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// </h>
+ *----------------------------------------------------------------------------*/
+#define __TTB_BASE 0x80500000
+#define __TTB_SIZE 0x00004000
+
+#endif /* __MEM_ARMCA9_H */
diff --git a/Device/ARM/ARMCA9/Include/system_ARMCA9.h b/Device/ARM/ARMCA9/Include/system_ARMCA9.h
index 9b1e9f2..d1652fd 100644
--- a/Device/ARM/ARMCA9/Include/system_ARMCA9.h
+++ b/Device/ARM/ARMCA9/Include/system_ARMCA9.h
@@ -35,17 +35,10 @@
typedef void(*IRQHandler)();
uint32_t InterruptHandlerRegister(IRQn_Type, IRQHandler);
uint32_t InterruptHandlerUnregister(IRQn_Type);
-
-/**
- * Initialize the system
- *
- * @param none
- * @return none
- *
- * @brief Setup the microcontroller system.
- * Initialize the System and update the SystemCoreClock variable.
- */
-extern void SystemInit (void);
+void SystemCoreClockUpdate (void);
+extern uint32_t SystemCoreClock;
+void SystemInit (void);
+void MMU_CreateTranslationTable(void);
#ifdef __cplusplus
}
diff --git a/Device/ARM/ARMCA9/Source/ARM/ARMCA9.sct b/Device/ARM/ARMCA9/Source/ARM/ARMCA9.sct
index 66cf773..a4402b0 100644
--- a/Device/ARM/ARMCA9/Source/ARM/ARMCA9.sct
+++ b/Device/ARM/ARMCA9/Source/ARM/ARMCA9.sct
@@ -1,3 +1,4 @@
+#! armcc -E
;**************************************************
; Copyright (c) 2017 ARM Ltd. All rights reserved.
;**************************************************
@@ -8,30 +9,69 @@
; This platform has 2GB SDRAM starting at 0x80000000.
+#include "mem_ARMCA9.h"
-SDRAM 0x80000000 0x40000000
+SDRAM __ROM_BASE __ROM_SIZE ; load region size_region
{
- VECTORS +0 0x200000
+ VECTORS __ROM_BASE __ROM_SIZE ; load address = execution address
{
- * (RESET, +FIRST) ; Vector table and other (assembler) startup code
+ * (RESET, +FIRST) ; Vector table and other startup code
* (InRoot$$Sections) ; All (library) code that must be in a root region
* (+RO-CODE) ; Application RO code (.text)
* (+RO-DATA) ; Application RO data (.constdata)
}
- RW_DATA 0x80200000 0x100000
+ RW_DATA __RAM_BASE __RW_DATA_SIZE
{ * (+RW) } ; Application RW data (.data)
- ZI_DATA 0x80300000 0x0F0000
+ ZI_DATA (__RAM_BASE+
+ __RW_DATA_SIZE) __ZI_DATA_SIZE
{ * (+ZI) } ; Application ZI data (.bss)
-
- ARM_LIB_STACK 0x80400000 EMPTY -0x8000 ; Stack region growing down
+
+ ARM_LIB_HEAP (__RAM_BASE
+ +__RW_DATA_SIZE
+ +__ZI_DATA_SIZE) EMPTY __HEAP_SIZE ; Heap region growing up
{ }
- ARM_LIB_HEAP 0x803F0000 EMPTY 0x8000 ; Heap region growing up
+ UND_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE
+ -__IRQ_STACK_SIZE
+ -__SVC_STACK_SIZE
+ -__ABT_STACK_SIZE) EMPTY -__UND_STACK_SIZE ; UND mode stack
+ { }
+
+ ABT_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE
+ -__IRQ_STACK_SIZE
+ -__SVC_STACK_SIZE) EMPTY -__ABT_STACK_SIZE ; ABT mode stack
+ { }
+
+ SVC_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE
+ -__IRQ_STACK_SIZE) EMPTY -__SVC_STACK_SIZE ; SVC mode stack
+ { }
+
+ IRQ_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE
+ -__FIQ_STACK_SIZE) EMPTY -__IRQ_STACK_SIZE ; IRQ mode stack
+ { }
+
+ FIQ_STACK (__RAM_BASE
+ +__RAM_SIZE
+ -__STACK_SIZE) EMPTY -__FIQ_STACK_SIZE ; FIQ mode stack
+ { }
+
+ ARM_LIB_STACK (__RAM_BASE
+ +__RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
{ }
- TTB 0x80500000 EMPTY 0x4000
- { } ; Level-1 Translation Table for MMU
-
+ TTB __TTB_BASE EMPTY __TTB_SIZE ; Level-1 Translation Table for MMU
+ { }
}
diff --git a/Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.c b/Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.c
new file mode 100644
index 0000000..efa4b51
--- /dev/null
+++ b/Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ * @file system_ARMCA9.c
+ * @brief CMSIS Device System Source File for ARM Cortex-A9 Device Series
+ * @version V1.00
+ * @date 22 Feb 2017
+ *
+ * @note
+ *
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ARMCA9.h>
+
+/*----------------------------------------------------------------------------
+ Definitions
+ *----------------------------------------------------------------------------*/
+#define USR_MODE 0x10 // User mode
+#define FIQ_MODE 0x11 // Fast Interrupt Request mode
+#define IRQ_MODE 0x12 // Interrupt Request mode
+#define SVC_MODE 0x13 // Supervisor mode
+#define ABT_MODE 0x17 // Abort mode
+#define UND_MODE 0x1B // Undefined Instruction mode
+#define SYS_MODE 0x1F // System mode
+
+/*----------------------------------------------------------------------------
+ Linker generated Symbols
+ *----------------------------------------------------------------------------*/
+extern uint32_t Image$$FIQ_STACK$$ZI$$Limit;
+extern uint32_t Image$$IRQ_STACK$$ZI$$Limit;
+extern uint32_t Image$$SVC_STACK$$ZI$$Limit;
+extern uint32_t Image$$ABT_STACK$$ZI$$Limit;
+extern uint32_t Image$$UND_STACK$$ZI$$Limit;
+extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
+
+/*----------------------------------------------------------------------------
+ Internal References
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void);
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void IRQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector Table
+ *----------------------------------------------------------------------------*/
+void Vectors(void) __attribute__ ((section("RESET")));
+__ASM void Vectors(void) {
+ IMPORT Reset_Handler
+ IMPORT Undef_Handler
+ IMPORT SVC_Handler
+ IMPORT PAbt_Handler
+ IMPORT DAbt_Handler
+ IMPORT IRQ_Handler
+ IMPORT FIQ_Handler
+ LDR PC, =Reset_Handler
+ LDR PC, =Undef_Handler
+ LDR PC, =SVC_Handler
+ LDR PC, =PAbt_Handler
+ LDR PC, =DAbt_Handler
+ NOP
+ LDR PC, =IRQ_Handler
+ LDR PC, =FIQ_Handler
+}
+
+/*----------------------------------------------------------------------------
+ Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void) {
+uint32_t reg;
+
+ // Put any cores other than 0 to sleep
+ if ((__get_MPIDR()&3U)!=0) __WFI();
+
+ reg = __get_SCTLR(); // Read CP15 System Control register
+ reg &= ~(0x1 << 12); // Clear I bit 12 to disable I Cache
+ reg &= ~(0x1 << 2); // Clear C bit 2 to disable D Cache
+ reg &= ~(0x1 << 0); // Clear M bit 0 to disable MMU
+ reg &= ~(0x1 << 11); // Clear Z bit 11 to disable branch prediction
+ reg &= ~(0x1 << 13); // Clear V bit 13 to disable hivecs
+ __set_SCTLR(reg); // Write value back to CP15 System Control register
+ __ISB();
+
+ reg = __get_ACTRL(); // Read CP15 Auxiliary Control Register
+ reg |= (0x1 << 1); // Enable L2 prefetch hint (UNK/WI since r4p1)
+ __set_ACTRL(reg); // Write CP15 Auxiliary Control Register
+
+ __set_VBAR((uint32_t)((uint32_t*)&Vectors));
+
+ // Setup Stack for each exceptional mode
+ __set_mode(FIQ_MODE);
+ __set_SP((uint32_t)&Image$$FIQ_STACK$$ZI$$Limit);
+ __set_mode(IRQ_MODE);
+ __set_SP((uint32_t)&Image$$IRQ_STACK$$ZI$$Limit);
+ __set_mode(SVC_MODE);
+ __set_SP((uint32_t)&Image$$SVC_STACK$$ZI$$Limit);
+ __set_mode(ABT_MODE);
+ __set_SP((uint32_t)&Image$$ABT_STACK$$ZI$$Limit);
+ __set_mode(UND_MODE);
+ __set_SP((uint32_t)&Image$$UND_STACK$$ZI$$Limit);
+ __set_mode(SYS_MODE);
+ __set_SP((uint32_t)&Image$$ARM_LIB_STACK$$ZI$$Limit);
+
+ // Create Translation Table
+ MMU_CreateTranslationTable();
+
+ // Invalidate entire Unified TLB
+ __set_TLBIALL(0);
+ // Invalidate entire branch predictor array
+ __set_BPIALL(0);
+ __DSB();
+ __ISB();
+ // Invalidate instruction cache and flush branch target cache
+ __set_ICIALLU(0);
+ __DSB();
+ __ISB();
+
+ // Invalidate data cache
+ __L1C_CleanInvalidateCache(0);
+
+ // Invalidate entire Unified TLB
+ __set_TLBIALL(0);
+ // Invalidate entire branch predictor array
+ __set_BPIALL(0);
+ __DSB();
+ __ISB();
+ // Invalidate instruction cache and flush branch target cache
+ __set_ICIALLU(0);
+ __DSB();
+ __ISB();
+
+ // Enable MMU, but leave caches disabled (they will be enabled later)
+ reg = __get_SCTLR(); // Read CP15 System Control register
+ reg |= (0x1 << 29); // Set AFE bit 29 to enable simplified access permissions model
+ reg &= ~(0x1 << 28); // Clear TRE bit 28 to disable TEX remap
+ reg &= ~(0x1 << 12); // Clear I bit 12 to disable I Cache
+ reg &= ~(0x1 << 2); // Clear C bit 2 to disable D Cache
+ reg &= ~(0x1 << 1); // Clear A bit 1 to disable strict alignment fault checking
+ reg |= (0x1 << 0); // Set M bit 0 to enable MMU
+ __set_SCTLR(reg); // Write CP15 System Control register
+
+ SystemInit();
+
+ extern void __main(void);
+ __main();
+}
+
+/*----------------------------------------------------------------------------
+ Default Handler for Exceptions / Interrupts
+ *----------------------------------------------------------------------------*/
+void Default_Handler(void) {
+ while(1);
+}
diff --git a/Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.s b/Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.s
deleted file mode 100644
index d489175..0000000
--- a/Device/ARM/ARMCA9/Source/ARM/startup_ARMCA9.s
+++ /dev/null
@@ -1,492 +0,0 @@
-;/******************************************************************************
-; * @file startup_ARMCA9.s
-; * @brief CMSIS Core Device Startup File for ARM Cortex-A9 Device Series
-; * @version V1.00
-; * @date 22 Feb 2017
-; *
-; * @note
-; *
-; ******************************************************************************/
-;/*
-; * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
-; *
-; * SPDX-License-Identifier: Apache-2.0
-; *
-; * Licensed under the Apache License, Version 2.0 (the License); you may
-; * not use this file except in compliance with the License.
-; * You may obtain a copy of the License at
-; *
-; * www.apache.org/licenses/LICENSE-2.0
-; *
-; * Unless required by applicable law or agreed to in writing, software
-; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
-; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-; * See the License for the specific language governing permissions and
-; * limitations under the License.
-; */
-;/*
-;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
-;*/
-
-GICI_BASE EQU 0x2C000100
-ICCIAR_OFFSET EQU 0x0000000C
-ICCEOIR_OFFSET EQU 0x00000010
-ICCHPIR_OFFSET EQU 0x00000018
-
-GICD_BASE EQU 0x2C001000
-ICDABR0_OFFSET EQU 0x00000300
-ICDIPR0_OFFSET EQU 0x00000400
-
-Mode_USR EQU 0x10
-Mode_FIQ EQU 0x11
-Mode_IRQ EQU 0x12
-Mode_SVC EQU 0x13
-Mode_ABT EQU 0x17
-Mode_UND EQU 0x1B
-Mode_SYS EQU 0x1F
-
-I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
-F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
-T_Bit EQU 0x20 ; when T bit is set, core is in Thumb state
-
-Sect_Normal EQU 0x00005c06 ;outer & inner wb/wa, non-shareable, executable, rw, domain 0, base addr 0
-Sect_Normal_Cod EQU 0x0000dc06 ;outer & inner wb/wa, non-shareable, executable, ro, domain 0, base addr 0
-Sect_Normal_RO EQU 0x0000dc16 ;as Sect_Normal_Cod, but not executable
-Sect_Normal_RW EQU 0x00005c16 ;as Sect_Normal_Cod, but writeable and not executable
-Sect_SO EQU 0x00000c12 ;strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0
-Sect_Device_RO EQU 0x00008c12 ;device, non-shareable, non-executable, ro, domain 0, base addr 0
-Sect_Device_RW EQU 0x00000c12 ;as Sect_Device_RO, but writeable
-Sect_Fault EQU 0x00000000 ;this translation will fault (the bottom 2 bits are important, the rest are ignored)
-
-RAM_BASE EQU 0x80000000
-VRAM_BASE EQU 0x18000000
-SRAM_BASE EQU 0x2e000000
-ETHERNET EQU 0x1a000000
-CS3_PERIPHERAL_BASE EQU 0x1c000000
-
-; <h> Stack Configuration
-; <o> Stack Size (in Bytes, per mode) <0x0-0xFFFFFFFF:8>
-; </h>
-
-UND_Stack_Size EQU 0x00000100
-SVC_Stack_Size EQU 0x00000100
-ABT_Stack_Size EQU 0x00000100
-FIQ_Stack_Size EQU 0x00000000
-IRQ_Stack_Size EQU 0x00000100
-USR_Stack_Size EQU 0x00000100
-
-ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
- FIQ_Stack_Size + IRQ_Stack_Size)
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE USR_Stack_Size
-__initial_sp SPACE ISR_Stack_Size
-
-Stack_Top
-
-
-; <h> Heap Configuration
-; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-; </h>
-
-Heap_Size EQU 0x00000000
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
-
- PRESERVE8
- ARM
-
-
-; Vector Table Mapped to Address 0 at Reset
-
- AREA RESET, CODE, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors LDR PC, Reset_Addr ; Address of Reset Handler
- LDR PC, Undef_Addr ; Address of Undef Handler
- LDR PC, SVC_Addr ; Address of SVC Handler
- LDR PC, PAbt_Addr ; Address of Prefetch Abort Handler
- LDR PC, DAbt_Addr ; Address of Data Abort Handler
- NOP ; Reserved Vector
- LDR PC, IRQ_Addr ; Address of IRQ Handler
- LDR PC, FIQ_Addr ; Address of FIQ Handler
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
-Reset_Addr DCD Reset_Handler
-Undef_Addr DCD Undef_Handler
-SVC_Addr DCD SVC_Handler
-PAbt_Addr DCD PAbt_Handler
-DAbt_Addr DCD DAbt_Handler
-IRQ_Addr DCD IRQ_Handler
-FIQ_Addr DCD FIQ_Handler
-
- AREA |.text|, CODE, READONLY
-
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
-
- ; Put any cores other than 0 to sleep
- MRC p15, 0, R0, c0, c0, 5 ; Read MPIDR
- ANDS R0, R0, #3
-goToSleep
- WFINE
- BNE goToSleep
-
- MRC p15, 0, R0, c1, c0, 0 ; Read CP15 System Control register
- BIC R0, R0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
- BIC R0, R0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
- BIC R0, R0, #0x1 ; Clear M bit 0 to disable MMU
- BIC R0, R0, #(0x1 << 11) ; Clear Z bit 11 to disable branch prediction
- BIC R0, R0, #(0x1 << 13) ; Clear V bit 13 to disable hivecs
- MCR p15, 0, R0, c1, c0, 0 ; Write value back to CP15 System Control register
- ISB
-
-; Configure ACTLR
- MRC p15, 0, r0, c1, c0, 1 ; Read CP15 Auxiliary Control Register
- ORR r0, r0, #(1 << 1) ; Enable L2 prefetch hint (UNK/WI since r4p1)
- MCR p15, 0, r0, c1, c0, 1 ; Write CP15 Auxiliary Control Register
-
-; Set Vector Base Address Register (VBAR) to point to this application's vector table
- LDR R0, =__Vectors
- MCR p15, 0, R0, c12, c0, 0
-
-; Setup Stack for each exceptional mode
- LDR R0, =Stack_Top
-
-; Enter Undefined Instruction Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_UND:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #UND_Stack_Size
-
-; Enter Abort Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_ABT:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #ABT_Stack_Size
-
-; Enter FIQ Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_FIQ:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #FIQ_Stack_Size
-
-; Enter IRQ Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_IRQ:OR:I_Bit:OR:F_Bit
- MOV SP, R0
- SUB R0, R0, #IRQ_Stack_Size
-
-; Enter Supervisor Mode and set its Stack Pointer
- MSR CPSR_C, #Mode_SVC:OR:I_Bit:OR:F_Bit
- MOV SP, R0
-
-; Enter System Mode to complete initialization and enter kernel
- MSR CPSR_C, #Mode_SYS:OR:I_Bit:OR:F_Bit
- MOV SP, R0
-
- IMPORT MMU_CreateTranslationTable
- BL MMU_CreateTranslationTable
-
- MOV r0, #0x0
- MCR p15, 0, r0, c8, c7, 0 ; TLBIALL - Invalidate entire Unified TLB
- MCR p15, 0, r0, c7, c5, 6 ; BPIALL - Invalidate entire branch predictor array
- DSB
- ISB
- MCR p15, 0, r0, c7, c5, 0 ; ICIALLU - Invalidate instruction cache and flush branch target cache
- DSB
- ISB
-
-; Invalidate data cache
- MOV r0, #0x0 ; 0 = invalidate data cache, 1 = clean data cache.
-
- MRC p15, 1, R6, c0, c0, 1 ; Read CLIDR
- ANDS R3, R6, #0x07000000 ; Extract coherency level
- MOV R3, R3, LSR #23 ; Total cache levels << 1
- BEQ Finished ; If 0, no need to clean
-
- MOV R10, #0 ; R10 holds current cache level << 1
-Loop1 ADD R2, R10, R10, LSR #1 ; R2 holds cache "Set" position
- MOV R1, R6, LSR R2 ; Bottom 3 bits are the Cache-type for this level
- AND R1, R1, #7 ; Isolate those lower 3 bits
- CMP R1, #2
- BLT Skip ; No cache or only instruction cache at this level
-
- MCR p15, 2, R10, c0, c0, 0 ; Write the Cache Size selection register
- ISB ; ISB to sync the change to the CacheSizeID reg
- MRC p15, 1, R1, c0, c0, 0 ; Reads current Cache Size ID register
- AND R2, R1, #7 ; Extract the line length field
- ADD R2, R2, #4 ; Add 4 for the line length offset (log2 16 bytes)
- LDR R4, =0x3FF
- ANDS R4, R4, R1, LSR #3 ; R4 is the max number on the way size (right aligned)
- CLZ R5, R4 ; R5 is the bit position of the way size increment
- LDR R7, =0x7FFF
- ANDS R7, R7, R1, LSR #13 ; R7 is the max number of the index size (right aligned)
-
-Loop2 MOV R9, R4 ; R9 working copy of the max way size (right aligned)
-
-Loop3 ORR R11, R10, R9, LSL R5 ; Factor in the Way number and cache number into R11
- ORR R11, R11, R7, LSL R2 ; Factor in the Set number
- CMP R0, #0
- BNE Dccsw
- MCR p15, 0, R11, c7, c6, 2 ; DCISW. Invalidate by Set/Way
- B cont
-Dccsw CMP R0, #1
- BNE Dccisw
- MCR p15, 0, R11, c7, c10, 2 ; DCCSW. Clean by Set/Way
- B cont
-Dccisw MCR p15, 0, R11, c7, c14, 2 ; DCCISW. Clean and Invalidate by Set/Way
-cont SUBS R9, R9, #1 ; Decrement the Way number
- BGE Loop3
- SUBS R7, R7, #1 ; Decrement the Set number
- BGE Loop2
-Skip ADD R10, R10, #2 ; Increment the cache number
- CMP R3, R10
- BGT Loop1
-Finished
- DSB
-
-; Enable MMU, but leave caches disabled (they will be enabled later)
- MRC p15, 0, r0, c1, c0, 0 ; Read CP15 System Control register
- ORR r0, r0, #(0x1 << 29) ; Set AFE bit 29 to enable simplified access permissions model
- BIC r0, r0, #(0x1 << 28) ; Clear TRE bit 28 to disable TEX remap
- BIC r0, r0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
- BIC r0, r0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
- BIC r0, r0, #(0x1 << 1) ; Clear A bit 1 to disable strict alignment fault checking
- ORR r0, r0, #0x1 ; Set M bit 0 to enable MMU
- MCR p15, 0, r0, c1, c0, 0 ; Write CP15 System Control register
-
-; USR/SYS stack pointer will be set during kernel init
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BLX R0
-
- ENDP
-
-Undef_Handler\
- PROC
- EXPORT Undef_Handler [WEAK]
- IMPORT CUndefHandler
- SRSFD SP!, #Mode_UND
- PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack
-
- MRS R0, SPSR
- TST R0, #T_Bit ; Check mode
- MOVEQ R1, #4 ; R1 = 4 ARM mode
- MOVNE R1, #2 ; R1 = 2 Thumb mode
- SUB R0, LR, R1
- LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction
- BEQ undef_cont
-
- ;Thumb instruction
- ;Determine if it is a 32-bit Thumb instruction
- LDRH R0, [R0]
- MOV R2, #0x1c
- CMP R2, R0, LSR #11
- BHS undef_cont ;16-bit Thumb instruction
-
- ;32-bit Thumb instruction. Unaligned - we need to reconstruct the offending instruction
- LDRH R2, [LR]
- ORR R0, R2, R0, LSL #16
-undef_cont
- MOV R2, LR ; Set LR to third argument
-
- AND R12, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R12 ; Adjust stack
- PUSH {R12, LR} ; Store stack adjustment and dummy LR
-
- ;R0 Offending instruction
- ;R1 =2 (Thumb) or =4 (ARM)
- BL CUndefHandler
-
- POP {R12, LR} ; Get stack adjustment & discard dummy LR
- ADD SP, SP, R12 ; Unadjust stack
-
- LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry
- SUB LR, LR, R0
- LDR R0, [SP, #28] ; Restore stacked SPSR
- MSR SPSR_CXSF, R0
- POP {R0-R4, R12} ; Restore stacked APCS registers
- ADD SP, SP, #8 ; Adjust SP for already-restored banked registers
- MOVS PC, LR
- ENDP
-
-PAbt_Handler\
- PROC
- EXPORT PAbt_Handler [WEAK]
- IMPORT CPAbtHandler
- SUB LR, LR, #4 ; Pre-adjust LR
- SRSFD SP!, #Mode_ABT ; Save LR and SPRS to ABT mode stack
- PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
- MRC p15, 0, R0, c5, c0, 1 ; IFSR
- MRC p15, 0, R1, c6, c0, 2 ; IFAR
-
- MOV R2, LR ; Set LR to third argument
-
- AND R12, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R12 ; Adjust stack
- PUSH {R12, LR} ; Store stack adjustment and dummy LR
-
- BL CPAbtHandler
-
- POP {R12, LR} ; Get stack adjustment & discard dummy LR
- ADD SP, SP, R12 ; Unadjust stack
-
- POP {R0-R4, R12} ; Restore stack APCS registers
- RFEFD SP! ; Return from exception
- ENDP
-
-
-DAbt_Handler\
- PROC
- EXPORT DAbt_Handler [WEAK]
- IMPORT CDAbtHandler
- SUB LR, LR, #8 ; Pre-adjust LR
- SRSFD SP!, #Mode_ABT ; Save LR and SPRS to ABT mode stack
- PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
- CLREX ; State of exclusive monitors unknown after taken data abort
- MRC p15, 0, R0, c5, c0, 0 ; DFSR
- MRC p15, 0, R1, c6, c0, 0 ; DFAR
-
- MOV R2, LR ; Set LR to third argument
-
- AND R12, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R12 ; Adjust stack
- PUSH {R12, LR} ; Store stack adjustment and dummy LR
-
- BL CDAbtHandler
-
- POP {R12, LR} ; Get stack adjustment & discard dummy LR
- ADD SP, SP, R12 ; Unadjust stack
-
- POP {R0-R4, R12} ; Restore stacked APCS registers
- RFEFD SP! ; Return from exception
- ENDP
-
-FIQ_Handler\
- PROC
- EXPORT FIQ_Handler [WEAK]
- ;; An FIQ might occur between the dummy read and the real read of the GIC in IRQ_Handler,
- ;; so if a real FIQ Handler is implemented, this will be needed before returning:
- ;; LDR R1, =GICI_BASE
- ;; LDR R0, [R1, #ICCHPIR_OFFSET] ; Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120
- B .
- ENDP
-
-SVC_Handler\
- PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-
-IRQ_Handler\
- PROC
- EXPORT IRQ_Handler [WEAK]
- IMPORT IRQCount
- IMPORT IRQTable
- IMPORT IRQNestLevel ; Flag indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR.
- IMPORT seen_id0_active ; Flag used to workaround GIC 390 errata 733075
-
- ;prologue
- SUB LR, LR, #4 ; Pre-adjust LR
- SRSFD SP!, #Mode_SVC ; Save LR_IRQ and SPRS_IRQ to SVC mode stack
- CPS #Mode_SVC ; Switch to SVC mode, to avoid a nested interrupt corrupting LR on a BL
- PUSH {R0-R3, R12} ; Save remaining APCS corruptible registers to SVC stack
-
- AND R1, SP, #4 ; Ensure stack is 8-byte aligned
- SUB SP, SP, R1 ; Adjust stack
- PUSH {R1, LR} ; Store stack adjustment and LR_SVC to SVC stack
-
- LDR R0, =IRQNestLevel ; Get address of nesting counter
- LDR R1, [R0]
- ADD R1, R1, #1 ; Increment nesting counter
- STR R1, [R0]
-
- ;identify and acknowledge interrupt
- LDR R1, =GICI_BASE
- LDR R0, [R1, #ICCHPIR_OFFSET] ; Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120
- LDR R0, [R1, #ICCIAR_OFFSET] ; Read ICCIAR (GIC CPU Interface register)
- DSB ; Ensure that interrupt acknowledge completes before re-enabling interrupts
-
- ; Workaround GIC 390 errata 733075 - see GIC-390_Errata_Notice_v6.pdf dated 09-Jul-2014
- ; The following workaround code is for a single-core system. It would be different in a multi-core system.
- ; If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up so unlock it, otherwise service the interrupt as normal
- ; Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 so will not occur here
- CMP R0, #0
- BEQ unlock
- MOV R2, #0x3FE
- CMP R0, R2
- BLT normal
-unlock
- ; Unlock the CPU interface with a dummy write to ICDIPR0
- LDR R2, =GICD_BASE
- LDR R3, [R2, #ICDIPR0_OFFSET]
- STR R3, [R2, #ICDIPR0_OFFSET]
- DSB ; Ensure the write completes before continuing
-
- ; If the ID is 0 and it is active and has not been seen before, then service it as normal,
- ; otherwise the interrupt should be treated as spurious and not serviced.
- CMP R0, #0
- BNE ret_irq ; Not 0, so spurious
- LDR R3, [R2, #ICDABR0_OFFSET] ; Get the interrupt state
- TST R3, #1
- BEQ ret_irq ; Not active, so spurious
- LDR R2, =seen_id0_active
- LDRB R3, [R2]
- CMP R3, #1
- BEQ ret_irq ; Seen it before, so spurious
-
- ; Record that ID0 has now been seen, then service it as normal
- MOV R3, #1
- STRB R3, [R2]
- ; End of Workaround GIC 390 errata 733075
-
-normal
- LDR R2, =IRQCount ; Read number of entries in IRQ handler table
- LDR R2, [R2]
- CMP R0, R2 ; Is there a handler for this IRQ?
- BHS end_int ; No handler, so return as normal
- LDR R2, =IRQTable ; Get address of handler
- LDR R2, [R2, R0, LSL #2]
- CMP R2, #0 ; Clean up and return if handler address is 0
- BEQ end_int
- PUSH {R0,R1}
-
- CPSIE i ; Now safe to re-enable interrupts
- BLX R2 ; Call handler. R0 = IRQ number. Beware calls to PendSV_Handler and OS_Tick_Handler do not return this way
- CPSID i ; Disable interrupts again
-
- POP {R0,R1}
- DSB ; Ensure that interrupt source is cleared before signalling End Of Interrupt
-end_int
- ; R0 still contains the interrupt ID
- ; R1 still contains GICI_BASE
- ; EOI does not need to be written for IDs 1020 to 1023 (0x3FC to 0x3FF)
- STR R0, [R1, #ICCEOIR_OFFSET] ; Normal end-of-interrupt write to EOIR (GIC CPU Interface register) to clear the active bit
-
- ; If it was ID0, clear the seen flag, otherwise return as normal
- CMP R0, #0
- LDREQ R1, =seen_id0_active
- STRBEQ R0, [R1] ; Clear the seen flag, using R0 (which is 0), to save loading another register
-ret_irq
- ;epilogue
- LDR R0, =IRQNestLevel ; Get address of nesting counter
- LDR R1, [R0]
- SUB R1, R1, #1 ; Decrement nesting counter
- STR R1, [R0]
-
- POP {R1, LR} ; Get stack adjustment and restore LR_SVC
- ADD SP, SP, R1 ; Unadjust stack
-
- POP {R0-R3,R12} ; Restore stacked APCS registers
- RFEFD SP! ; Return from exception
- ENDP
-
- END
diff --git a/Device/ARM/ARMCA9/Source/mmu_ARMCA9.c b/Device/ARM/ARMCA9/Source/mmu_ARMCA9.c
index 735c170..bfb3282 100644
--- a/Device/ARM/ARMCA9/Source/mmu_ARMCA9.c
+++ b/Device/ARM/ARMCA9/Source/mmu_ARMCA9.c
@@ -99,7 +99,6 @@
//Domain 0 is always the Client domain
//Descriptors should place all memory in domain 0
-#include <stdint.h>
#include "ARMCA9.h"
diff --git a/Device/ARM/ARMCA9/Source/system_ARMCA9.c b/Device/ARM/ARMCA9/Source/system_ARMCA9.c
index e67cee2..30e9f3b 100644
--- a/Device/ARM/ARMCA9/Source/system_ARMCA9.c
+++ b/Device/ARM/ARMCA9/Source/system_ARMCA9.c
@@ -26,267 +26,60 @@
*/
#include <ARMCA9.h>
-#include <stdint.h>
-extern void $Super$$main(void);
-__asm void __FPU_Enable(void);
+#define SYSTEM_CLOCK 12000000U
-// Flag indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR.
-uint32_t IRQNestLevel = 0;
-// Flag used to workaround GIC 390 errata 733075
-uint32_t seen_id0_active = 0;
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = SYSTEM_CLOCK;
-
-/**
- * Initialize the memory subsystem.
- *
- * @param none
- * @return none
- *
- * @brief Initialize the memory subsystem, including enabling the cache and BTAC. Requires PL1, so implemented as an SVC in case threads are USR mode.
- */
-#pragma push
-#pragma arm
-void __svc(1) EnableCaches(void);
-void __SVC_1(void) {
-
-/* Before enabling the caches, the instruction cache, the data cache, TLB, and BTAC must have been invalidated.
- * You are not required to invalidate the main TLB, even though it is recommended for safety
- * reasons. This ensures compatibility with future revisions of the processor. */
-
-// unsigned int l2_id;
-
- /* After MMU is enabled and data has been invalidated, enable caches and BTAC */
- L1C_EnableCaches();
- L1C_EnableBTAC();
-
- /* If L2C-310 is present, Invalidate and Enable L2 cache here */
-// l2_id = L2C_GetID();
-// if (l2_id)
-// {
-// L2C_InvAllByWay();
-// L2C_Enable();
-// }
+/*----------------------------------------------------------------------------
+ System Core Clock update function
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)
+{
+ SystemCoreClock = SYSTEM_CLOCK;
}
-#pragma pop
-IRQHandler IRQTable[] = {
- 0, //IRQ 0
- 0, //IRQ 1
- 0, //IRQ 2
- 0, //IRQ 3
- 0, //IRQ 4
- 0, //IRQ 5
- 0, //IRQ 6
- 0, //IRQ 7
- 0, //IRQ 8
- 0, //IRQ 9
- 0, //IRQ 10
- 0, //IRQ 11
- 0, //IRQ 12
- 0, //IRQ 13
- 0, //IRQ 14
- 0, //IRQ 15
- 0, //IRQ 16
- 0, //IRQ 17
- 0, //IRQ 18
- 0, //IRQ 19
- 0, //IRQ 20
- 0, //IRQ 21
- 0, //IRQ 22
- 0, //IRQ 23
- 0, //IRQ 24
- 0, //IRQ 25
- 0, //IRQ 26
- 0, //IRQ 27
- 0, //IRQ 28
- 0, //IRQ 29
- 0, //IRQ 30
- 0, //IRQ 31
- 0, //IRQ 32
- 0, //IRQ 33
- 0, //IRQ 34
- 0, //IRQ 35
- 0, //IRQ 36
- 0, //IRQ 37
- 0, //IRQ 38
- 0, //IRQ 39
- 0 //IRQ 40
-};
-uint32_t IRQCount = sizeof IRQTable / 4;
+/*----------------------------------------------------------------------------
+ IRQ Handler Register/Unregister
+ *----------------------------------------------------------------------------*/
+IRQHandler IRQTable[40U] = { 0U };
+
+uint32_t IRQCount = sizeof IRQTable / 4U;
uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler)
{
- if (irq < IRQCount) {
- IRQTable[irq] = handler;
- return 0;
- }
- else {
- return 1;
- }
+ if (irq < IRQCount) {
+ IRQTable[irq] = handler;
+ return 0U;
+ }
+ else {
+ return 1U;
+ }
}
uint32_t InterruptHandlerUnregister (IRQn_Type irq)
{
- if (irq < IRQCount) {
- IRQTable[irq] = 0;
- return 0;
- }
- else {
- return 1;
- }
+ if (irq < IRQCount) {
+ IRQTable[irq] = 0U;
+ return 0U;
+ }
+ else {
+ return 1U;
+ }
}
-/**
- * Initialize the system
- *
- * @param none
- * @return none
- *
- * @brief Setup the microcontroller system.
- * Initialize the System.
- */
+/*----------------------------------------------------------------------------
+ System Initialization
+ *----------------------------------------------------------------------------*/
void SystemInit (void)
{
-/* do not use global variables because this function is called before
- reaching pre-main. RW section may be overwritten afterwards. */
- GIC_Enable();
-}
-
-void $Sub$$main(void)
-{
-#ifdef __CMSIS_RTOS
- extern void PendSV_Handler(uint32_t);
- extern void OS_Tick_Handler(uint32_t);
- InterruptHandlerRegister(SGI0_IRQn , PendSV_Handler);
- InterruptHandlerRegister(PrivTimer_IRQn, OS_Tick_Handler);
- EnableCaches();
-#endif
-
- $Super$$main(); //Call main
-}
-
-//Fault Status Register (IFSR/DFSR) definitions
-#define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
-#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_SECOND 0x0e //sync/external
-#define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
-#define FSR_SYNC_PARITY_TTB_WALK_SECOND 0x1e //sync/external
-#define FSR_TRANSLATION_FAULT_FIRST 0x05 //MMU Fault - internal
-#define FSR_TRANSLATION_FAULT_SECOND 0x07 //MMU Fault - internal
-#define FSR_ACCESS_FLAG_FAULT_FIRST 0x03 //MMU Fault - internal
-#define FSR_ACCESS_FLAG_FAULT_SECOND 0x06 //MMU Fault - internal
-#define FSR_DOMAIN_FAULT_FIRST 0x09 //MMU Fault - internal
-#define FSR_DOMAIN_FAULT_SECOND 0x0b //MMU Fault - internal
-#define FSR_PERMISSION_FAULT_FIRST 0x0f //MMU Fault - internal
-#define FSR_PERMISSION_FAULT_SECOND 0x0d //MMU Fault - internal
-#define FSR_DEBUG_EVENT 0x02 //internal
-#define FSR_SYNC_EXT_ABORT 0x08 //sync/external
-#define FSR_TLB_CONFLICT_ABORT 0x10 //sync/external
-#define FSR_LOCKDOWN 0x14 //internal
-#define FSR_COPROCESSOR_ABORT 0x1a //internal
-#define FSR_SYNC_PARITY_ERROR 0x19 //sync/external
-#define FSR_ASYNC_EXTERNAL_ABORT 0x16 //DFSR only - async/external
-#define FSR_ASYNC_PARITY_ERROR 0x18 //DFSR only - async/external
-
-void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
- uint32_t FS = (DFSR & (1 << 10)) >> 6 | (DFSR & 0x0f); //Store Fault Status
-
- switch(FS) {
- //Synchronous parity errors - retry
- case FSR_SYNC_PARITY_ERROR:
- case FSR_SYNC_PARITY_TTB_WALK_FIRST:
- case FSR_SYNC_PARITY_TTB_WALK_SECOND:
- return;
-
- //Your code here. Value in DFAR is invalid for some fault statuses.
- case FSR_ALIGNMENT_FAULT:
- case FSR_INSTRUCTION_CACHE_MAINTENANCE:
- case FSR_SYNC_EXT_TTB_WALK_FIRST:
- case FSR_SYNC_EXT_TTB_WALK_SECOND:
- case FSR_TRANSLATION_FAULT_FIRST:
- case FSR_TRANSLATION_FAULT_SECOND:
- case FSR_ACCESS_FLAG_FAULT_FIRST:
- case FSR_ACCESS_FLAG_FAULT_SECOND:
- case FSR_DOMAIN_FAULT_FIRST:
- case FSR_DOMAIN_FAULT_SECOND:
- case FSR_PERMISSION_FAULT_FIRST:
- case FSR_PERMISSION_FAULT_SECOND:
- case FSR_DEBUG_EVENT:
- case FSR_SYNC_EXT_ABORT:
- case FSR_TLB_CONFLICT_ABORT:
- case FSR_LOCKDOWN:
- case FSR_COPROCESSOR_ABORT:
- case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid
- case FSR_ASYNC_PARITY_ERROR: //DFAR invalid
- default:
- while(1);
- }
-}
-
-void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
- uint32_t FS = (IFSR & (1 << 10)) >> 6 | (IFSR & 0x0f); //Store Fault Status
-
- switch(FS) {
- //Synchronous parity errors - retry
- case FSR_SYNC_PARITY_ERROR:
- case FSR_SYNC_PARITY_TTB_WALK_FIRST:
- case FSR_SYNC_PARITY_TTB_WALK_SECOND:
- return;
-
- //Your code here. Value in IFAR is invalid for some fault statuses.
- case FSR_SYNC_EXT_TTB_WALK_FIRST:
- case FSR_SYNC_EXT_TTB_WALK_SECOND:
- case FSR_TRANSLATION_FAULT_FIRST:
- case FSR_TRANSLATION_FAULT_SECOND:
- case FSR_ACCESS_FLAG_FAULT_FIRST:
- case FSR_ACCESS_FLAG_FAULT_SECOND:
- case FSR_DOMAIN_FAULT_FIRST:
- case FSR_DOMAIN_FAULT_SECOND:
- case FSR_PERMISSION_FAULT_FIRST:
- case FSR_PERMISSION_FAULT_SECOND:
- case FSR_DEBUG_EVENT: //IFAR invalid
- case FSR_SYNC_EXT_ABORT:
- case FSR_TLB_CONFLICT_ABORT:
- case FSR_LOCKDOWN:
- case FSR_COPROCESSOR_ABORT:
- default:
- while(1);
- }
-}
-
-//returns amount to decrement lr by
-//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 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) {
- const int THUMB = 2;
- const int ARM = 4;
- //Lazy VFP/NEON initialisation and switching
-
- // (ARM ARM section A7.5) VFP data processing 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) {
- __FPU_Enable();
- 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))) {
- __FPU_Enable();
- return state;
- }
-
- //Add code here for other Undef cases
- while(1);
+/* do not use global variables because this function is called before
+ reaching pre-main. RW section may be overwritten afterwards. */
+ GIC_Enable();
+ L1C_EnableCaches();
+ L1C_EnableBTAC();
+ __FPU_Enable();
}