mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9167 from TomoYamanaka/hanlder_without_RTOS
Modify IRQ handler processing when unusing RTOS at Cortex-Apull/9256/head
commit
d2e9136ddb
|
@ -0,0 +1,101 @@
|
||||||
|
/**************************************************
|
||||||
|
*
|
||||||
|
* Part two of the system initialization code, contains C-level
|
||||||
|
* initialization, thumb-2 only variant.
|
||||||
|
*
|
||||||
|
* $Revision: 59783 $
|
||||||
|
*
|
||||||
|
**************************************************/
|
||||||
|
/* Copyright 2008-2017, IAR Systems AB.
|
||||||
|
This source code is the property of IAR Systems. The source code may only
|
||||||
|
be used together with the IAR Embedded Workbench. Redistribution and use
|
||||||
|
in source and binary forms, with or without modification, is permitted
|
||||||
|
provided that the following conditions are met:
|
||||||
|
- Redistributions of source code, in whole or in part, must retain the
|
||||||
|
above copyright notice, this list of conditions and the disclaimer below.
|
||||||
|
- IAR Systems name may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
; --------------------------------------------------
|
||||||
|
; Module ?cmain, C-level initialization.
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
SECTION SHT$$PREINIT_ARRAY:CONST:NOROOT(2)
|
||||||
|
SECTION SHT$$INIT_ARRAY:CONST:NOROOT(2)
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
|
||||||
|
PUBLIC __cmain
|
||||||
|
;; Keep ?main for legacy reasons, it is accessed in countless instances of cstartup.s around the world...
|
||||||
|
PUBLIC ?main
|
||||||
|
EXTWEAK __iar_data_init3
|
||||||
|
EXTWEAK __iar_argc_argv
|
||||||
|
EXTERN __low_level_init
|
||||||
|
EXTERN __call_ctors
|
||||||
|
EXTERN main
|
||||||
|
EXTERN exit
|
||||||
|
EXTERN __iar_dynamic_initialization
|
||||||
|
EXTERN mbed_sdk_init
|
||||||
|
EXTERN mbed_main
|
||||||
|
EXTERN SystemInit
|
||||||
|
|
||||||
|
THUMB
|
||||||
|
__cmain:
|
||||||
|
?main:
|
||||||
|
|
||||||
|
; Initialize segments.
|
||||||
|
; __segment_init and __low_level_init are assumed to use the same
|
||||||
|
; instruction set and to be reachable by BL from the ICODE segment
|
||||||
|
; (it is safest to link them in segment ICODE).
|
||||||
|
|
||||||
|
FUNCALL __cmain, __low_level_init
|
||||||
|
bl __low_level_init
|
||||||
|
cmp r0,#0
|
||||||
|
beq ?l1
|
||||||
|
FUNCALL __cmain, __iar_data_init3
|
||||||
|
bl __iar_data_init3
|
||||||
|
MOVS r0,#0 ; No parameters
|
||||||
|
FUNCALL __cmain, mbed_sdk_init
|
||||||
|
BL mbed_sdk_init
|
||||||
|
MOVS r0,#0 ; No parameters
|
||||||
|
FUNCALL __cmain, __iar_dynamic_initialization
|
||||||
|
BL __iar_dynamic_initialization ; C++ dynamic initialization
|
||||||
|
|
||||||
|
?l1:
|
||||||
|
REQUIRE ?l3
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
|
||||||
|
PUBLIC _main
|
||||||
|
PUBLIC _call_main
|
||||||
|
THUMB
|
||||||
|
|
||||||
|
__iar_init$$done: ; Copy initialization is done
|
||||||
|
|
||||||
|
?l3:
|
||||||
|
_call_main:
|
||||||
|
MOVS r0,#0 ; No parameters
|
||||||
|
FUNCALL __cmain, __iar_argc_argv
|
||||||
|
BL __iar_argc_argv ; Maybe setup command line
|
||||||
|
|
||||||
|
MOVS r0,#0 ; No parameters
|
||||||
|
FUNCALL __cmain, mbed_main
|
||||||
|
BL mbed_main
|
||||||
|
|
||||||
|
FUNCALL __cmain, main
|
||||||
|
BL main
|
||||||
|
_main:
|
||||||
|
FUNCALL __cmain, exit
|
||||||
|
BL exit
|
||||||
|
|
||||||
|
END
|
|
@ -72,7 +72,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region
|
||||||
RW_IRAM1 +0 ALIGN 0x10
|
RW_IRAM1 +0 ALIGN 0x10
|
||||||
{ * (+ZI) } ; Application ZI data (.bss)
|
{ * (+ZI) } ; Application ZI data (.bss)
|
||||||
|
|
||||||
ARM_LIB_HEAP +0
|
ARM_LIB_HEAP +0 ALIGN 0x8
|
||||||
{ * (HEAP) } ; Application heap area (HEAP)
|
{ * (HEAP) } ; Application heap area (HEAP)
|
||||||
|
|
||||||
ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
|
ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
|
||||||
|
|
|
@ -45,16 +45,6 @@
|
||||||
void Vectors (void) __attribute__ ((section("RESET")));
|
void Vectors (void) __attribute__ ((section("RESET")));
|
||||||
void Reset_Handler(void);
|
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
|
Exception / Interrupt Vector Table
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
@ -153,10 +143,3 @@ goToSleep
|
||||||
IMPORT __main
|
IMPORT __main
|
||||||
BL __main
|
BL __main
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
Default Handler for Exceptions / Interrupts
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void Default_Handler(void) {
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,17 +45,54 @@ extern char Image$$ARM_LIB_HEAP$$Base[];
|
||||||
extern char Image$$ARM_LIB_STACK$$Base[];
|
extern char Image$$ARM_LIB_STACK$$Base[];
|
||||||
|
|
||||||
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
||||||
uint32_t zi_limit = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
|
|
||||||
uint32_t sp_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
|
|
||||||
|
|
||||||
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
|
|
||||||
|
|
||||||
struct __initial_stackheap r;
|
struct __initial_stackheap r;
|
||||||
r.heap_base = zi_limit;
|
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
|
||||||
r.heap_limit = sp_limit;
|
r.heap_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MBED_CONF_RTOS_PRESENT
|
||||||
|
|
||||||
|
/* The single region memory model would check stack collision at run time, verifying that
|
||||||
|
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
|
||||||
|
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
|
||||||
|
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
__asm(".global __use_two_region_memory\n\t");
|
||||||
|
__asm(".global __use_no_semihosting\n\t");
|
||||||
|
#else
|
||||||
|
#pragma import(__use_two_region_memory)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
|
||||||
|
*
|
||||||
|
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
|
||||||
|
* __rt_entry has the following call sequence:
|
||||||
|
* 1. _platform_pre_stackheap_init
|
||||||
|
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
|
||||||
|
* 3. _platform_post_stackheap_init
|
||||||
|
* 4. __rt_lib_init
|
||||||
|
* 5. _platform_post_lib_init
|
||||||
|
* 6. main()
|
||||||
|
* 7. exit()
|
||||||
|
*
|
||||||
|
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
|
||||||
|
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
|
||||||
|
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
|
||||||
|
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
|
||||||
|
* ARM_LIB_HEAP region is defined in scatter file.
|
||||||
|
*
|
||||||
|
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
|
||||||
|
* overridden and the overriding __rt_lib_init here gets meaningless.
|
||||||
|
*/
|
||||||
|
extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
|
||||||
|
|
||||||
|
__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
|
||||||
|
{
|
||||||
|
return $Super$$__rt_lib_init((unsigned)Image$$ARM_LIB_HEAP$$Base, (unsigned)Image$$ARM_LIB_STACK$$Base);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018 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.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Project: CMSIS-RTOS RTX
|
||||||
|
* Title: Cortex-A Exception handlers
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "core_ca.h"
|
||||||
|
|
||||||
|
#define MODE_SVC 0x13
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
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 FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Default Handler for Exceptions / Interrupts
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void Default_Handler(void) {
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Default IRQ Handler for Exceptions / Interrupts
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
__WEAK __ASM void IRQ_Handler(void) {
|
||||||
|
IMPORT IRQ_GetActiveIRQ
|
||||||
|
IMPORT IRQ_GetHandler
|
||||||
|
IMPORT IRQ_EndOfInterrupt
|
||||||
|
|
||||||
|
SUB LR, LR, #4 // Pre-adjust LR
|
||||||
|
SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack
|
||||||
|
CPS #MODE_SVC // Change to SVC mode
|
||||||
|
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
|
||||||
|
|
||||||
|
MOV R3, SP // Move SP into R3
|
||||||
|
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
|
||||||
|
SUB SP, SP, R3 // Adjust stack
|
||||||
|
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
|
||||||
|
|
||||||
|
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
|
||||||
|
MOV R4, R0 // Move interrupt ID to R4
|
||||||
|
|
||||||
|
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
|
||||||
|
CMP R0, #0 // Check if handler address is 0
|
||||||
|
BEQ IRQ_End // If 0, end interrupt and return
|
||||||
|
|
||||||
|
CPSIE i // Re-enable interrupts
|
||||||
|
BLX R0 // Call IRQ handler
|
||||||
|
CPSID i // Disable interrupts
|
||||||
|
|
||||||
|
IRQ_End
|
||||||
|
MOV R0, R4 // Move interrupt ID to R0
|
||||||
|
BLX IRQ_EndOfInterrupt // Signal end of interrupt
|
||||||
|
|
||||||
|
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
|
||||||
|
ADD SP, SP, R3 // Unadjust stack
|
||||||
|
|
||||||
|
POP {R0-R3, R12, LR} // Restore stacked APCS registers
|
||||||
|
RFEFD SP! // Return from IRQ handler
|
||||||
|
}
|
|
@ -223,27 +223,4 @@ sf_boot:
|
||||||
.pool
|
.pool
|
||||||
.size Reset_Handler, . - Reset_Handler
|
.size Reset_Handler, . - Reset_Handler
|
||||||
|
|
||||||
|
.end
|
||||||
.text
|
|
||||||
|
|
||||||
/* Macro to define default handlers. Default handler
|
|
||||||
* will be weak symbol and just dead loops. They can be
|
|
||||||
* overwritten by other handlers */
|
|
||||||
.macro def_default_handler handler_name
|
|
||||||
.align 1
|
|
||||||
.thumb_func
|
|
||||||
.weak \handler_name
|
|
||||||
.type \handler_name, %function
|
|
||||||
\handler_name :
|
|
||||||
b .
|
|
||||||
.size \handler_name, . - \handler_name
|
|
||||||
.endm
|
|
||||||
|
|
||||||
def_default_handler Undef_Handler
|
|
||||||
def_default_handler SVC_Handler
|
|
||||||
def_default_handler PAbt_Handler
|
|
||||||
def_default_handler DAbt_Handler
|
|
||||||
def_default_handler IRQ_Handler
|
|
||||||
def_default_handler FIQ_Handler
|
|
||||||
|
|
||||||
.END
|
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018 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.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Project: CMSIS-RTOS RTX
|
||||||
|
* Title: Cortex-A Exception handlers
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file "irq_weak.S"
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.equ MODE_SVC, 0x13
|
||||||
|
|
||||||
|
.arm
|
||||||
|
.section ".text"
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
|
||||||
|
/* Macro to define default handlers. Default handler
|
||||||
|
* will be weak symbol and just dead loops. They can be
|
||||||
|
* overwritten by other handlers */
|
||||||
|
.macro def_default_handler handler_name
|
||||||
|
.align 1
|
||||||
|
.thumb_func
|
||||||
|
.weak \handler_name
|
||||||
|
.type \handler_name, %function
|
||||||
|
\handler_name :
|
||||||
|
b .
|
||||||
|
.size \handler_name, . - \handler_name
|
||||||
|
.endm
|
||||||
|
|
||||||
|
def_default_handler Undef_Handler
|
||||||
|
def_default_handler SVC_Handler
|
||||||
|
def_default_handler PAbt_Handler
|
||||||
|
def_default_handler DAbt_Handler
|
||||||
|
def_default_handler FIQ_Handler
|
||||||
|
|
||||||
|
|
||||||
|
.weak IRQ_Handler
|
||||||
|
.type IRQ_Handler, %function
|
||||||
|
.global IRQ_Handler
|
||||||
|
.fnstart
|
||||||
|
.cantunwind
|
||||||
|
IRQ_Handler:
|
||||||
|
|
||||||
|
SUB LR, LR, #4 // Pre-adjust LR
|
||||||
|
SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack
|
||||||
|
CPS #MODE_SVC // Change to SVC mode
|
||||||
|
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
|
||||||
|
|
||||||
|
MOV R3, SP // Move SP into R3
|
||||||
|
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
|
||||||
|
SUB SP, SP, R3 // Adjust stack
|
||||||
|
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
|
||||||
|
|
||||||
|
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
|
||||||
|
MOV R4, R0 // Move interrupt ID to R4
|
||||||
|
|
||||||
|
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
|
||||||
|
CMP R0, #0 // Check if handler address is 0
|
||||||
|
BEQ IRQ_End // If 0, end interrupt and return
|
||||||
|
|
||||||
|
CPSIE i // Re-enable interrupts
|
||||||
|
BLX R0 // Call IRQ handler
|
||||||
|
CPSID i // Disable interrupts
|
||||||
|
|
||||||
|
IRQ_End:
|
||||||
|
MOV R0, R4 // Move interrupt ID to R0
|
||||||
|
BLX IRQ_EndOfInterrupt // Signal end of interrupt
|
||||||
|
|
||||||
|
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
|
||||||
|
ADD SP, SP, R3 // Unadjust stack
|
||||||
|
|
||||||
|
POP {R0-R3, R12, LR} // Restore stacked APCS registers
|
||||||
|
RFEFD SP! // Return from IRQ handler
|
||||||
|
|
||||||
|
.fnend
|
||||||
|
.size IRQ_Handler, .-IRQ_Handler
|
||||||
|
|
||||||
|
.end
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018 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.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Project: CMSIS-RTOS RTX
|
||||||
|
* Title: Cortex-A Exception handlers
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
NAME irq_weak.S
|
||||||
|
|
||||||
|
MODE_SVC EQU 0x13
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
|
||||||
|
PUBWEAK Undef_Handler
|
||||||
|
Undef_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK SVC_Handler
|
||||||
|
SVC_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK PAbt_Handler
|
||||||
|
PAbt_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK DAbt_Handler
|
||||||
|
DAbt_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK IRQ_Handler
|
||||||
|
IRQ_Handler
|
||||||
|
IMPORT IRQ_GetActiveIRQ
|
||||||
|
IMPORT IRQ_GetHandler
|
||||||
|
IMPORT IRQ_EndOfInterrupt
|
||||||
|
|
||||||
|
SUB LR, LR, #4 ; Pre-adjust LR
|
||||||
|
SRSFD SP!, #MODE_SVC ; Save LR_irq and SPSR_irq on to the SVC stack
|
||||||
|
CPS #MODE_SVC ; Change to SVC mode
|
||||||
|
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
|
||||||
|
|
||||||
|
MOV R3, SP ; Move SP into R3
|
||||||
|
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
|
||||||
|
SUB SP, SP, R3 ; Adjust stack
|
||||||
|
PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4)
|
||||||
|
|
||||||
|
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
|
||||||
|
MOV R4, R0 ; Move interrupt ID to R4
|
||||||
|
|
||||||
|
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
|
||||||
|
CMP R0, #0 ; Check if handler address is 0
|
||||||
|
BEQ IRQ_End ; If 0, end interrupt and return
|
||||||
|
|
||||||
|
CPSIE i ; Re-enable interrupts
|
||||||
|
BLX R0 ; Call IRQ handler
|
||||||
|
CPSID i ; Disable interrupts
|
||||||
|
|
||||||
|
IRQ_End
|
||||||
|
MOV R0, R4 ; Move interrupt ID to R0
|
||||||
|
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
|
||||||
|
|
||||||
|
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
|
||||||
|
ADD SP, SP, R3 ; Unadjust stack
|
||||||
|
|
||||||
|
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
|
||||||
|
RFEFD SP! ; Return from IRQ handler
|
||||||
|
|
||||||
|
END
|
|
@ -72,7 +72,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region
|
||||||
RW_IRAM1 +0 ALIGN 0x10
|
RW_IRAM1 +0 ALIGN 0x10
|
||||||
{ * (+ZI) } ; Application ZI data (.bss)
|
{ * (+ZI) } ; Application ZI data (.bss)
|
||||||
|
|
||||||
ARM_LIB_HEAP +0
|
ARM_LIB_HEAP +0 ALIGN 0x8
|
||||||
{ * (HEAP) } ; Application heap area (HEAP)
|
{ * (HEAP) } ; Application heap area (HEAP)
|
||||||
|
|
||||||
ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
|
ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
|
||||||
|
|
|
@ -45,16 +45,6 @@
|
||||||
void Vectors (void) __attribute__ ((section("RESET")));
|
void Vectors (void) __attribute__ ((section("RESET")));
|
||||||
void Reset_Handler(void);
|
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
|
Exception / Interrupt Vector Table
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
@ -153,10 +143,3 @@ goToSleep
|
||||||
IMPORT __main
|
IMPORT __main
|
||||||
BL __main
|
BL __main
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
Default Handler for Exceptions / Interrupts
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void Default_Handler(void) {
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,17 +45,54 @@ extern char Image$$ARM_LIB_HEAP$$Base[];
|
||||||
extern char Image$$ARM_LIB_STACK$$Base[];
|
extern char Image$$ARM_LIB_STACK$$Base[];
|
||||||
|
|
||||||
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
||||||
uint32_t zi_limit = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
|
|
||||||
uint32_t sp_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
|
|
||||||
|
|
||||||
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
|
|
||||||
|
|
||||||
struct __initial_stackheap r;
|
struct __initial_stackheap r;
|
||||||
r.heap_base = zi_limit;
|
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
|
||||||
r.heap_limit = sp_limit;
|
r.heap_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MBED_CONF_RTOS_PRESENT
|
||||||
|
|
||||||
|
/* The single region memory model would check stack collision at run time, verifying that
|
||||||
|
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
|
||||||
|
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
|
||||||
|
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
__asm(".global __use_two_region_memory\n\t");
|
||||||
|
__asm(".global __use_no_semihosting\n\t");
|
||||||
|
#else
|
||||||
|
#pragma import(__use_two_region_memory)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
|
||||||
|
*
|
||||||
|
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
|
||||||
|
* __rt_entry has the following call sequence:
|
||||||
|
* 1. _platform_pre_stackheap_init
|
||||||
|
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
|
||||||
|
* 3. _platform_post_stackheap_init
|
||||||
|
* 4. __rt_lib_init
|
||||||
|
* 5. _platform_post_lib_init
|
||||||
|
* 6. main()
|
||||||
|
* 7. exit()
|
||||||
|
*
|
||||||
|
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
|
||||||
|
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
|
||||||
|
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
|
||||||
|
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
|
||||||
|
* ARM_LIB_HEAP region is defined in scatter file.
|
||||||
|
*
|
||||||
|
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
|
||||||
|
* overridden and the overriding __rt_lib_init here gets meaningless.
|
||||||
|
*/
|
||||||
|
extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
|
||||||
|
|
||||||
|
__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
|
||||||
|
{
|
||||||
|
return $Super$$__rt_lib_init((unsigned)Image$$ARM_LIB_HEAP$$Base, (unsigned)Image$$ARM_LIB_STACK$$Base);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018 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.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Project: CMSIS-RTOS RTX
|
||||||
|
* Title: Cortex-A Exception handlers
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "core_ca.h"
|
||||||
|
|
||||||
|
#define MODE_SVC 0x13
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
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 FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Default Handler for Exceptions / Interrupts
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void Default_Handler(void) {
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
Default IRQ Handler for Exceptions / Interrupts
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
__WEAK __ASM void IRQ_Handler(void) {
|
||||||
|
IMPORT IRQ_GetActiveIRQ
|
||||||
|
IMPORT IRQ_GetHandler
|
||||||
|
IMPORT IRQ_EndOfInterrupt
|
||||||
|
|
||||||
|
SUB LR, LR, #4 // Pre-adjust LR
|
||||||
|
SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack
|
||||||
|
CPS #MODE_SVC // Change to SVC mode
|
||||||
|
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
|
||||||
|
|
||||||
|
MOV R3, SP // Move SP into R3
|
||||||
|
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
|
||||||
|
SUB SP, SP, R3 // Adjust stack
|
||||||
|
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
|
||||||
|
|
||||||
|
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
|
||||||
|
MOV R4, R0 // Move interrupt ID to R4
|
||||||
|
|
||||||
|
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
|
||||||
|
CMP R0, #0 // Check if handler address is 0
|
||||||
|
BEQ IRQ_End // If 0, end interrupt and return
|
||||||
|
|
||||||
|
CPSIE i // Re-enable interrupts
|
||||||
|
BLX R0 // Call IRQ handler
|
||||||
|
CPSID i // Disable interrupts
|
||||||
|
|
||||||
|
IRQ_End
|
||||||
|
MOV R0, R4 // Move interrupt ID to R0
|
||||||
|
BLX IRQ_EndOfInterrupt // Signal end of interrupt
|
||||||
|
|
||||||
|
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
|
||||||
|
ADD SP, SP, R3 // Unadjust stack
|
||||||
|
|
||||||
|
POP {R0-R3, R12, LR} // Restore stacked APCS registers
|
||||||
|
RFEFD SP! // Return from IRQ handler
|
||||||
|
}
|
|
@ -223,27 +223,4 @@ sf_boot:
|
||||||
.pool
|
.pool
|
||||||
.size Reset_Handler, . - Reset_Handler
|
.size Reset_Handler, . - Reset_Handler
|
||||||
|
|
||||||
|
.end
|
||||||
.text
|
|
||||||
|
|
||||||
/* Macro to define default handlers. Default handler
|
|
||||||
* will be weak symbol and just dead loops. They can be
|
|
||||||
* overwritten by other handlers */
|
|
||||||
.macro def_default_handler handler_name
|
|
||||||
.align 1
|
|
||||||
.thumb_func
|
|
||||||
.weak \handler_name
|
|
||||||
.type \handler_name, %function
|
|
||||||
\handler_name :
|
|
||||||
b .
|
|
||||||
.size \handler_name, . - \handler_name
|
|
||||||
.endm
|
|
||||||
|
|
||||||
def_default_handler Undef_Handler
|
|
||||||
def_default_handler SVC_Handler
|
|
||||||
def_default_handler PAbt_Handler
|
|
||||||
def_default_handler DAbt_Handler
|
|
||||||
def_default_handler IRQ_Handler
|
|
||||||
def_default_handler FIQ_Handler
|
|
||||||
|
|
||||||
.END
|
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018 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.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Project: CMSIS-RTOS RTX
|
||||||
|
* Title: Cortex-A Exception handlers
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
.file "irq_weak.S"
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.equ MODE_SVC, 0x13
|
||||||
|
|
||||||
|
.arm
|
||||||
|
.section ".text"
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
|
||||||
|
/* Macro to define default handlers. Default handler
|
||||||
|
* will be weak symbol and just dead loops. They can be
|
||||||
|
* overwritten by other handlers */
|
||||||
|
.macro def_default_handler handler_name
|
||||||
|
.align 1
|
||||||
|
.thumb_func
|
||||||
|
.weak \handler_name
|
||||||
|
.type \handler_name, %function
|
||||||
|
\handler_name :
|
||||||
|
b .
|
||||||
|
.size \handler_name, . - \handler_name
|
||||||
|
.endm
|
||||||
|
|
||||||
|
def_default_handler Undef_Handler
|
||||||
|
def_default_handler SVC_Handler
|
||||||
|
def_default_handler PAbt_Handler
|
||||||
|
def_default_handler DAbt_Handler
|
||||||
|
def_default_handler FIQ_Handler
|
||||||
|
|
||||||
|
|
||||||
|
.weak IRQ_Handler
|
||||||
|
.type IRQ_Handler, %function
|
||||||
|
.global IRQ_Handler
|
||||||
|
.fnstart
|
||||||
|
.cantunwind
|
||||||
|
IRQ_Handler:
|
||||||
|
|
||||||
|
SUB LR, LR, #4 // Pre-adjust LR
|
||||||
|
SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack
|
||||||
|
CPS #MODE_SVC // Change to SVC mode
|
||||||
|
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
|
||||||
|
|
||||||
|
MOV R3, SP // Move SP into R3
|
||||||
|
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
|
||||||
|
SUB SP, SP, R3 // Adjust stack
|
||||||
|
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
|
||||||
|
|
||||||
|
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
|
||||||
|
MOV R4, R0 // Move interrupt ID to R4
|
||||||
|
|
||||||
|
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
|
||||||
|
CMP R0, #0 // Check if handler address is 0
|
||||||
|
BEQ IRQ_End // If 0, end interrupt and return
|
||||||
|
|
||||||
|
CPSIE i // Re-enable interrupts
|
||||||
|
BLX R0 // Call IRQ handler
|
||||||
|
CPSID i // Disable interrupts
|
||||||
|
|
||||||
|
IRQ_End:
|
||||||
|
MOV R0, R4 // Move interrupt ID to R0
|
||||||
|
BLX IRQ_EndOfInterrupt // Signal end of interrupt
|
||||||
|
|
||||||
|
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
|
||||||
|
ADD SP, SP, R3 // Unadjust stack
|
||||||
|
|
||||||
|
POP {R0-R3, R12, LR} // Restore stacked APCS registers
|
||||||
|
RFEFD SP! // Return from IRQ handler
|
||||||
|
|
||||||
|
.fnend
|
||||||
|
.size IRQ_Handler, .-IRQ_Handler
|
||||||
|
|
||||||
|
.end
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018 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.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Project: CMSIS-RTOS RTX
|
||||||
|
* Title: Cortex-A Exception handlers
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
NAME irq_weak.S
|
||||||
|
|
||||||
|
MODE_SVC EQU 0x13
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
|
||||||
|
PUBWEAK Undef_Handler
|
||||||
|
Undef_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK SVC_Handler
|
||||||
|
SVC_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK PAbt_Handler
|
||||||
|
PAbt_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK DAbt_Handler
|
||||||
|
DAbt_Handler
|
||||||
|
B .
|
||||||
|
|
||||||
|
PUBWEAK IRQ_Handler
|
||||||
|
IRQ_Handler
|
||||||
|
IMPORT IRQ_GetActiveIRQ
|
||||||
|
IMPORT IRQ_GetHandler
|
||||||
|
IMPORT IRQ_EndOfInterrupt
|
||||||
|
|
||||||
|
SUB LR, LR, #4 ; Pre-adjust LR
|
||||||
|
SRSFD SP!, #MODE_SVC ; Save LR_irq and SPSR_irq on to the SVC stack
|
||||||
|
CPS #MODE_SVC ; Change to SVC mode
|
||||||
|
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
|
||||||
|
|
||||||
|
MOV R3, SP ; Move SP into R3
|
||||||
|
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
|
||||||
|
SUB SP, SP, R3 ; Adjust stack
|
||||||
|
PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4)
|
||||||
|
|
||||||
|
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
|
||||||
|
MOV R4, R0 ; Move interrupt ID to R4
|
||||||
|
|
||||||
|
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
|
||||||
|
CMP R0, #0 ; Check if handler address is 0
|
||||||
|
BEQ IRQ_End ; If 0, end interrupt and return
|
||||||
|
|
||||||
|
CPSIE i ; Re-enable interrupts
|
||||||
|
BLX R0 ; Call IRQ handler
|
||||||
|
CPSID i ; Disable interrupts
|
||||||
|
|
||||||
|
IRQ_End
|
||||||
|
MOV R0, R4 ; Move interrupt ID to R0
|
||||||
|
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
|
||||||
|
|
||||||
|
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
|
||||||
|
ADD SP, SP, R3 ; Unadjust stack
|
||||||
|
|
||||||
|
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
|
||||||
|
RFEFD SP! ; Return from IRQ handler
|
||||||
|
|
||||||
|
END
|
Loading…
Reference in New Issue