summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaman <[email protected]>2023-10-25 06:58:03 +0530
committerGitHub <[email protected]>2023-10-25 09:28:03 +0800
commitadbb5fd94ae8cf6411bcb5161c2cdaa037331860 (patch)
tree92cccff1b0bb975e83535d3d94f143f9e7d92da4
parent53caa1587368c369bc6c2d202caa8934ad1c62fe (diff)
AT32UC3B: Rewire _intx for updated exceptions file from Microchip (#8182)
-rw-r--r--libcpu/avr32/uc3/exception_gcc.S379
1 files changed, 174 insertions, 205 deletions
diff --git a/libcpu/avr32/uc3/exception_gcc.S b/libcpu/avr32/uc3/exception_gcc.S
index cdf2576f54..8db4755c64 100644
--- a/libcpu/avr32/uc3/exception_gcc.S
+++ b/libcpu/avr32/uc3/exception_gcc.S
@@ -1,54 +1,48 @@
-/* This file is part of the ATMEL AVR32-UC3-SoftwareFramework-1.6.0 Release */
-
-/*This file is prepared for Doxygen automatic documentation generation.*/
-/*! \file *********************************************************************
- *
- * \brief Exception and interrupt vectors.
+/**
+ * \file
*
- * This file maps all events supported by an AVR32.
+ * \brief Exception and interrupt vectors mapping for the INTC Software Driver.
*
- * - Compiler: GNU GCC for AVR32
- * - Supported devices: All AVR32 devices with an INTC module can be used.
- * - AppNote:
+ * Copyright (c) 2009-2018 Microchip Technology Inc. and its subsidiaries.
*
- * \author Atmel Corporation: http://www.atmel.com \n
- * Support and FAQ: http://support.atmel.no/
+ * \asf_license_start
*
- ******************************************************************************/
-
-/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
+ * \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
- * 4. This software may only be redistributed and used in connection with an Atmel
- * AVR product.
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
*
*/
#if !__AVR32_UC__ && !__AVR32_AP__
- #error Implementation of the AVR32 architecture not supported by the INTC driver.
+ #error Implementation for the AVR32 architecture only.
#endif
@@ -59,227 +53,204 @@
//! \verbatim
- .section .exception, "ax", @progbits
+.section .exception, "ax", @progbits
// Start of Exception Vector Table.
- // EVBA must be aligned with a power of two strictly greater than the EVBA-
- // relative offset of the last vector.
- .balign 0x200
+/*
+ * EVBA must be aligned with a power of two strictly greater than the
+ * EVBA-relative offset of the last vector.
+ */
+.balign 0x200
- // Export symbol.
- .global _evba
- .type _evba, @function
+// Export symbol.
+.global _evba
+.type _evba, @function
_evba:
- .org 0x000
- // Unrecoverable Exception.
+ .org 0x000
+ // Unrecoverable Exception.
_handle_Unrecoverable_Exception:
- rjmp $
+ rjmp $
- .org 0x004
- // TLB Multiple Hit.
+ .org 0x004
+ // TLB Multiple Hit.
_handle_TLB_Multiple_Hit:
- rjmp $
+ rjmp $
- .org 0x008
- // Bus Error Data Fetch.
+ .org 0x008
+ // Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
- rjmp $
+ rjmp $
- .org 0x00C
- // Bus Error Instruction Fetch.
+ .org 0x00C
+ // Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
- rjmp $
+ rjmp $
- .org 0x010
- // NMI.
+ .org 0x010
+ // NMI.
_handle_NMI:
- rjmp $
+ rjmp $
- .org 0x014
- // Instruction Address.
+ .org 0x014
+ // Instruction Address.
_handle_Instruction_Address:
- rjmp $
+ rjmp $
- .org 0x018
- // ITLB Protection.
+ .org 0x018
+ // ITLB Protection.
_handle_ITLB_Protection:
- rjmp $
+ rjmp $
- .org 0x01C
- // Breakpoint.
+ .org 0x01C
+ // Breakpoint.
_handle_Breakpoint:
- rjmp $
+ rjmp $
- .org 0x020
- // Illegal Opcode.
+ .org 0x020
+ // Illegal Opcode.
_handle_Illegal_Opcode:
- rjmp $
+ rjmp $
- .org 0x024
- // Unimplemented Instruction.
+ .org 0x024
+ // Unimplemented Instruction.
_handle_Unimplemented_Instruction:
- rjmp $
+ rjmp $
- .org 0x028
- // Privilege Violation.
+ .org 0x028
+ // Privilege Violation.
_handle_Privilege_Violation:
- rjmp $
+ rjmp $
- .org 0x02C
- // Floating-Point: UNUSED IN AVR32UC and AVR32AP.
+ .org 0x02C
+ // Floating-Point: UNUSED IN AVR32UC and AVR32AP.
_handle_Floating_Point:
- rjmp $
+ rjmp $
- .org 0x030
- // Coprocessor Absent: UNUSED IN AVR32UC.
+ .org 0x030
+ // Coprocessor Absent: UNUSED IN AVR32UC.
_handle_Coprocessor_Absent:
- rjmp $
+ rjmp $
- .org 0x034
- // Data Address (Read).
+ .org 0x034
+ // Data Address (Read).
_handle_Data_Address_Read:
- rjmp $
+ rjmp $
- .org 0x038
- // Data Address (Write).
+ .org 0x038
+ // Data Address (Write).
_handle_Data_Address_Write:
- rjmp $
+ rjmp $
- .org 0x03C
- // DTLB Protection (Read).
+ .org 0x03C
+ // DTLB Protection (Read).
_handle_DTLB_Protection_Read:
- rjmp $
+ rjmp $
- .org 0x040
- // DTLB Protection (Write).
+ .org 0x040
+ // DTLB Protection (Write).
_handle_DTLB_Protection_Write:
- rjmp $
+ rjmp $
- .org 0x044
- // DTLB Modified: UNUSED IN AVR32UC.
+ .org 0x044
+ // DTLB Modified: UNUSED IN AVR32UC.
_handle_DTLB_Modified:
- rjmp $
+ rjmp $
- .org 0x050
- // ITLB Miss.
+ .org 0x050
+ // ITLB Miss.
_handle_ITLB_Miss:
- rjmp $
+ rjmp $
- .org 0x060
- // DTLB Miss (Read).
+ .org 0x060
+ // DTLB Miss (Read).
_handle_DTLB_Miss_Read:
- rjmp $
+ rjmp $
- .org 0x070
- // DTLB Miss (Write).
+ .org 0x070
+ // DTLB Miss (Write).
_handle_DTLB_Miss_Write:
- rjmp $
+ rjmp $
- .org 0x100
- // Supervisor Call.
+ .org 0x100
+ // Supervisor Call.
_handle_Supervisor_Call:
- rjmp $
-
-
-// Interrupt support.
-// The interrupt controller must provide the offset address relative to EVBA.
-// Important note:
-// All interrupts call a C function named _get_interrupt_handler.
-// This function will read group and interrupt line number to then return in
-// R12 a pointer to a user-provided interrupt handler.
-
- .balign 4
-
-_int0:
- mov r12, 0 // Pass the int_level parameter to the _get_interrupt_handler function.
- call _get_interrupt_handler
- cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
- breq _spint0 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
- call rt_interrupt_enter
- icall r12
- call rt_interrupt_leave
- ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
- lda.w r12, rt_interrupt_nest /* Is nested interrupt? */
- ld.w r11, r12[0]
- cp.w r11, 0
- brne _spint0
- lda.w r12, rt_thread_switch_interrupt_flag /* Is thread switch required? */
- ld.w r11, r12[0]
- cp.w r11, 1
- breq rt_hw_context_switch_interrupt_do
-_spint0:
- csrf AVR32_SR_GM_OFFSET /* Enable global interrupt */
- rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
+ rjmp $
-_int1:
- mov r12, 1 // Pass the int_level parameter to the _get_interrupt_handler function.
- call _get_interrupt_handler
- cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
- breq _spint1 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
- call rt_interrupt_enter
- icall r12
- call rt_interrupt_leave
- ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
- lda.w r12, rt_interrupt_nest /* Is nested interrupt? */
- ld.w r11, r12[0]
- cp.w r11, 0
- brne _spint1
- lda.w r12, rt_thread_switch_interrupt_flag /* Is thread switch required? */
- ld.w r11, r12[0]
- cp.w r11, 1
- breq rt_hw_context_switch_interrupt_do
-_spint1:
- csrf AVR32_SR_GM_OFFSET /* Enable global interrupt */
- rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
-
-
-_int2:
- mov r12, 2 // Pass the int_level parameter to the _get_interrupt_handler function.
- call _get_interrupt_handler
- cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
- breq _spint2 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
- call rt_interrupt_enter
- icall r12
- call rt_interrupt_leave
- ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
- lda.w r12, rt_interrupt_nest /* Is nested interrupt? */
- ld.w r11, r12[0]
- cp.w r11, 0
- brne _spint2
- lda.w r12, rt_thread_switch_interrupt_flag /* Is thread switch required? */
- ld.w r11, r12[0]
- cp.w r11, 1
- breq rt_hw_context_switch_interrupt_do
-_spint2:
- csrf AVR32_SR_GM_OFFSET /* Enable global interrupt */
- rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
-
+/*
+ * Interrupt support.
+ * The interrupt controller must provide the offset address relative to EVBA.
+ * Important note:
+ * All interrupts call a C function named _get_interrupt_handler.
+ * This function will read group and interrupt line number to then return in
+ *R12 a pointer to a user-provided interrupt handler.
+ */
-_int3:
- mov r12, 3 // Pass the int_level parameter to the _get_interrupt_handler function.
- call _get_interrupt_handler
- cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
- breq _spint3 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
- call rt_interrupt_enter
- icall r12
- call rt_interrupt_leave
- ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
- lda.w r12, rt_interrupt_nest /* Is nested interrupt? */
- ld.w r11, r12[0]
- cp.w r11, 0
- brne _spint3
- lda.w r12, rt_thread_switch_interrupt_flag /* Is thread switch required? */
- ld.w r11, r12[0]
- cp.w r11, 1
- breq rt_hw_context_switch_interrupt_do
-_spint3:
- csrf AVR32_SR_GM_OFFSET /* Enable global interrupt */
- rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
+.balign 4
+.irp priority, 0, 1, 2, 3
+.global _int\priority
+.type _int\priority, @function
+_int\priority:
+#if __AVR32_UC__
+ /*
+ * R8-R12, LR, PC and SR are automatically pushed onto the system stack
+ * by the CPU upon interrupt entry. No other register is saved by
+ * hardware.
+ */
+#elif __AVR32_AP__
+ /*
+ * PC and SR are automatically saved in respectively RAR_INTx and
+ * RSR_INTx by the CPU upon interrupt entry. No other register is saved
+ * by hardware.
+ */
+ pushm r8-r12, lr
+#endif
+ mov r12, \priority // Pass the int_level parameter to the _get_interrupt_handler function.
+ call _get_interrupt_handler
+ cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
+ breq _spint\priority // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
+ call rt_interrupt_enter
+ icall r12
+ call rt_interrupt_leave
+ ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
+ lda.w r12, rt_interrupt_nest /* Is nested interrupt? */
+ ld.w r11, r12[0]
+ cp.w r11, 0
+ brne _spint\priority
+ lda.w r12, rt_thread_switch_interrupt_flag /* Is thread switch required? */
+ ld.w r11, r12[0]
+ cp.w r11, 1
+ breq rt_hw_context_switch_interrupt_do
+_spint\priority:
+ csrf AVR32_SR_GM_OFFSET /* Enable global interrupt */
+#if __AVR32_UC__
+ /*
+ * If this was not a spurious interrupt (R12 != NULL), jump to the
+ * handler.
+ */
+ /* movne pc, r12 */
+#elif __AVR32_AP__
+ // If this was a spurious interrupt (R12 == NULL), branch.
+ breq spint\priority
+ /*
+ * Push the pointer to the interrupt handler onto the system stack since
+ * no register may be altered.
+ */
+ st.w --sp, r12
+ popm r8-r12, lr, pc // Restore registers and jump to the handler.
+spint\priority:
+ popm r8-r12, lr
+#endif
+ /*
+ * If this was a spurious interrupt (R12 == NULL), return from event
+ * handler.
+ */
+ rete
+.endr
rt_hw_context_switch_interrupt_do:
mov r11, 0
@@ -292,24 +263,22 @@ rt_hw_context_switch_interrupt_do:
st.w r12[0], sp /* Store old thread SP */
ld.w sp, r11[0] /* Load new thread SP */
ldm sp++, r0-r7 /* Pop R0-R7 (new thread) */
- rete /* RETE pops R8-R12, LR, PC, SR automatically */
-
+ rete /* RETE pops R8-R12, LR, PC, SR automatically */
// Constant data area.
- .balign 4
+.balign 4
- // Values to store in the interrupt priority registers for the various interrupt priority levels.
- // The interrupt priority registers contain the interrupt priority level and
- // the EVBA-relative interrupt vector offset.
- .global ipr_val
- .type ipr_val, @object
+// Values to store in the interrupt priority registers for the various interrupt priority levels.
+// The interrupt priority registers contain the interrupt priority level and
+// the EVBA-relative interrupt vector offset.
+.global ipr_val
+.type ipr_val, @object
ipr_val:
.word (AVR32_INTC_INT0 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int0 - _evba),\
(AVR32_INTC_INT1 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int1 - _evba),\
(AVR32_INTC_INT2 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int2 - _evba),\
(AVR32_INTC_INT3 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int3 - _evba)
-
//! \endverbatim
//! @}