Newer
Older
mbed-os / targets / TARGET_RENESAS / TARGET_RZ_A1XX / TARGET_GR_LYCHEE / device / TOOLCHAIN_ARM_STD / weak_handler.c
/*
 * 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
}