Skip to content

Modify IRQ handler processing when unusing RTOS at Cortex-A #9167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions cmsis/TARGET_CORTEX_A/TOOLCHAIN_IAR/cmain.S
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region
RW_IRAM1 +0 ALIGN 0x10
{ * (+ZI) } ; Application ZI data (.bss)

ARM_LIB_HEAP +0
ARM_LIB_HEAP +0 ALIGN 0x8
{ * (HEAP) } ; Application heap area (HEAP)

ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,6 @@
void Vectors (void) __attribute__ ((section("RESET")));
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
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -153,10 +143,3 @@ goToSleep
IMPORT __main
BL __main
}

/*----------------------------------------------------------------------------
Default Handler for Exceptions / Interrupts
*----------------------------------------------------------------------------*/
void Default_Handler(void) {
while(1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,54 @@ extern char Image$$ARM_LIB_HEAP$$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) {
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;
r.heap_base = zi_limit;
r.heap_limit = sp_limit;
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
r.heap_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
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
}
#endif
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,27 +223,4 @@ sf_boot:
.pool
.size Reset_Handler, . - Reset_Handler


.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
.end
Loading