From f6dd22048ac815e94cd0f8a4b63fdfd0309092b0 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 8 Jun 2011 23:30:39 +0000 Subject: [PATCH] This finishes ALL AVR assembly language git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3685 42af7a65-404d-4744-a932-0658087f49c3 --- arch/avr/src/at90usb/at90usb_exceptions.S | 301 +++--- arch/avr/src/at90usb/at90usb_head.S | 554 +++++----- arch/avr/src/atmega/atmega_exceptions.S | 287 +++-- arch/avr/src/atmega/atmega_head.S | 542 +++++----- arch/avr/src/avr/excptmacros.h | 1133 ++++++++++---------- arch/avr/src/avr32/up_exceptions.S | 746 ++++++------- arch/avr/src/avr32/up_fullcontextrestore.S | 316 +++--- arch/avr/src/avr32/up_syscall6.S | 168 +-- 8 files changed, 2074 insertions(+), 1973 deletions(-) diff --git a/arch/avr/src/at90usb/at90usb_exceptions.S b/arch/avr/src/at90usb/at90usb_exceptions.S index 862ea06ae6..8fa931a044 100755 --- a/arch/avr/src/at90usb/at90usb_exceptions.S +++ b/arch/avr/src/at90usb/at90usb_exceptions.S @@ -1,125 +1,176 @@ -/******************************************************************************************** - * arch/avr/src/at90usb/at90usb_exceptions.S - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ********************************************************************************************/ - -/******************************************************************************************** - * Included Files - ********************************************************************************************/ - -#include - -#include - -#include "excptmacros.h" - -/******************************************************************************************** - * Pre-processor Definitions - ********************************************************************************************/ - -/******************************************************************************************** - * External Symbols - ********************************************************************************************/ - - .file "at90usb_exceptions.S" - .global up_doirq - -/******************************************************************************************** - * Macros - ********************************************************************************************/ - -/******************************************************************************************** - * Exception Vector Handlers - ********************************************************************************************/ - - .section .handlers, "ax", @progbits - - HANDLER at90usb_int0, AT90USB_IRQ_INT0, excpt_common /* External interrupt request 0 */ - HANDLER at90usb_int1, AT90USB_IRQ_INT1, excpt_common /* External interrupt request 1 */ - HANDLER at90usb_int2, AT90USB_IRQ_INT2, excpt_common /* External interrupt request 2 */ - HANDLER at90usb_int3, AT90USB_IRQ_INT3, excpt_common /* External interrupt request 3 */ - HANDLER at90usb_int4, AT90USB_IRQ_INT4, excpt_common /* External interrupt request 4 */ - HANDLER at90usb_int5, AT90USB_IRQ_INT5, excpt_common /* External interrupt request 5 */ - HANDLER at90usb_int6, AT90USB_IRQ_INT6, excpt_common /* External interrupt request 6 */ - HANDLER at90usb_int7, AT90USB_IRQ_INT7, excpt_common /* External interrupt request 7 */ - HANDLER at90usb_pcint0, AT90USB_IRQ_PCINT0, excpt_common /* Pin Change Interrupt Request 0 */ - HANDLER at90usb_usbgen, AT90USB_IRQ_USBGEN, excpt_common /* USB General USB General Interrupt request */ - HANDLER at90usb_usbep, AT90USB_IRQ_USBEP, excpt_common /* USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ - HANDLER at90usb_wdt, AT90USB_IRQ_WDT, excpt_common /* Watchdog Time-out Interrupt */ - HANDLER at90usb_t2compa, AT90USB_IRQ_T2COMPA, excpt_common /* TIMER2 COMPA Timer/Counter2 Compare Match A */ - HANDLER at90usb_t2compb, AT90USB_IRQ_T2COMPB, excpt_common /* TIMER2 COMPA Timer/Counter2 Compare Match B */ - HANDLER at90usb_t2ovf, AT90USB_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ - HANDLER at90usb_t1capt, AT90USB_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ - HANDLER at90usb_t1compa, AT90USB_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match A */ - HANDLER at90usb_t1compb, AT90USB_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match B */ - HANDLER at90usb_t1compc, AT90USB_IRQ_T1COMPC, excpt_common /* TIMER1 COMPC timer/counter1 compare match C */ - HANDLER at90usb_t1ovf, AT90USB_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ - HANDLER at90usb_t0compa, AT90USB_IRQ_T0COMPA, excpt_common /* TIMER0 COMPA Timer/Counter0 Compare Match A */ - HANDLER at90usb_t0compb, AT90USB_IRQ_T0COMPB, excpt_common /* TIMER0 COMPB Timer/Counter0 Compare Match B */ - HANDLER at90usb_t0ovf, AT90USB_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ - HANDLER at90usb_spi, AT90USB_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ - HANDLER at90usb_u1rx, AT90USB_IRQ_U1RX, excpt_common /* USART1 RX complete */ - HANDLER at90usb_u1dre, AT90USB_IRQ_U1DRE, excpt_common /* USART1 data register empty */ - HANDLER at90usb_u1tx, AT90USB_IRQ_U1TX, excpt_common /* USART1 TX complete */ - HANDLER at90usb_anacomp, AT90USB_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ - HANDLER at90usb_adc, AT90USB_IRQ_ADC, excpt_common /* ADC conversion complete */ - HANDLER at90usb_ee, AT90USB_IRQ_EE, excpt_common /* EEPROM ready */ - HANDLER at90usb_t3capt, AT90USB_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ - HANDLER at90usb_t3compa, AT90USB_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ - HANDLER at90usb_t3compb, AT90USB_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ - HANDLER at90usb_t3compc, AT90USB_IRQ_T3COMPC, excpt_common /* TIMER3 COMPC timer/counter3 compare match c */ - HANDLER at90usb_t3ovf, AT90USB_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ - HANDLER at90usb_twi, AT90USB_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ - HANDLER at90usb_spmrdy, AT90USB_IRQ_SPMRDY, excpt_common /* Store program memory ready */ - -/* Common exception handling logic. */ - -excpt_common: -#warning "Missing Logic" - -/**************************************************************************************************** - * Name: up_interruptstack - ****************************************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 0 - .bss - .align 4 - .globl up_interruptstack - .type up_interruptstack, object -up_interruptstack: - .skip CONFIG_ARCH_INTERRUPTSTACK -.Lintstackbase: - .size up_interruptstack, .-up_interruptstack -#endif - .end - +/******************************************************************************************** + * arch/avr/src/at90usb/at90usb_exceptions.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include + +#include "excptmacros.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * External Symbols + ********************************************************************************************/ + + .file "at90usb_exceptions.S" + .global up_doirq + .global up_fullcontextrestore + +/******************************************************************************************** + * Macros + ********************************************************************************************/ + +/******************************************************************************************** + * Exception Vector Handlers + ********************************************************************************************/ + + .section .handlers, "ax", @progbits + + HANDLER at90usb_int0, AT90USB_IRQ_INT0, excpt_common /* External interrupt request 0 */ + HANDLER at90usb_int1, AT90USB_IRQ_INT1, excpt_common /* External interrupt request 1 */ + HANDLER at90usb_int2, AT90USB_IRQ_INT2, excpt_common /* External interrupt request 2 */ + HANDLER at90usb_int3, AT90USB_IRQ_INT3, excpt_common /* External interrupt request 3 */ + HANDLER at90usb_int4, AT90USB_IRQ_INT4, excpt_common /* External interrupt request 4 */ + HANDLER at90usb_int5, AT90USB_IRQ_INT5, excpt_common /* External interrupt request 5 */ + HANDLER at90usb_int6, AT90USB_IRQ_INT6, excpt_common /* External interrupt request 6 */ + HANDLER at90usb_int7, AT90USB_IRQ_INT7, excpt_common /* External interrupt request 7 */ + HANDLER at90usb_pcint0, AT90USB_IRQ_PCINT0, excpt_common /* Pin Change Interrupt Request 0 */ + HANDLER at90usb_usbgen, AT90USB_IRQ_USBGEN, excpt_common /* USB General USB General Interrupt request */ + HANDLER at90usb_usbep, AT90USB_IRQ_USBEP, excpt_common /* USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ + HANDLER at90usb_wdt, AT90USB_IRQ_WDT, excpt_common /* Watchdog Time-out Interrupt */ + HANDLER at90usb_t2compa, AT90USB_IRQ_T2COMPA, excpt_common /* TIMER2 COMPA Timer/Counter2 Compare Match A */ + HANDLER at90usb_t2compb, AT90USB_IRQ_T2COMPB, excpt_common /* TIMER2 COMPA Timer/Counter2 Compare Match B */ + HANDLER at90usb_t2ovf, AT90USB_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ + HANDLER at90usb_t1capt, AT90USB_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ + HANDLER at90usb_t1compa, AT90USB_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match A */ + HANDLER at90usb_t1compb, AT90USB_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match B */ + HANDLER at90usb_t1compc, AT90USB_IRQ_T1COMPC, excpt_common /* TIMER1 COMPC timer/counter1 compare match C */ + HANDLER at90usb_t1ovf, AT90USB_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ + HANDLER at90usb_t0compa, AT90USB_IRQ_T0COMPA, excpt_common /* TIMER0 COMPA Timer/Counter0 Compare Match A */ + HANDLER at90usb_t0compb, AT90USB_IRQ_T0COMPB, excpt_common /* TIMER0 COMPB Timer/Counter0 Compare Match B */ + HANDLER at90usb_t0ovf, AT90USB_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ + HANDLER at90usb_spi, AT90USB_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ + HANDLER at90usb_u1rx, AT90USB_IRQ_U1RX, excpt_common /* USART1 RX complete */ + HANDLER at90usb_u1dre, AT90USB_IRQ_U1DRE, excpt_common /* USART1 data register empty */ + HANDLER at90usb_u1tx, AT90USB_IRQ_U1TX, excpt_common /* USART1 TX complete */ + HANDLER at90usb_anacomp, AT90USB_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ + HANDLER at90usb_adc, AT90USB_IRQ_ADC, excpt_common /* ADC conversion complete */ + HANDLER at90usb_ee, AT90USB_IRQ_EE, excpt_common /* EEPROM ready */ + HANDLER at90usb_t3capt, AT90USB_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ + HANDLER at90usb_t3compa, AT90USB_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ + HANDLER at90usb_t3compb, AT90USB_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ + HANDLER at90usb_t3compc, AT90USB_IRQ_T3COMPC, excpt_common /* TIMER3 COMPC timer/counter3 compare match c */ + HANDLER at90usb_t3ovf, AT90USB_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ + HANDLER at90usb_twi, AT90USB_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ + HANDLER at90usb_spmrdy, AT90USB_IRQ_SPMRDY, excpt_common /* Store program memory ready */ + +/******************************************************************************************** + * Name: excpt_common + * + * Description: + * Exception Vector Handlers + * + * On Entry: + * The return PC and the saved r24 is on the stack, r24 now contains the IRQ number + * + * PCL + * PCH + * R0 + * --- <- SP + * + ********************************************************************************************/ + +excpt_common: + /* Save the remaining registers on the stack, preserving the IRQ number in r14 */ + + EXCPT_PROLOGUE + + /* Call up_doirq with r24 = IRQ number, r22-23 = Pointer to the save structure. The stack + * pointer currently points to the save structure (or maybe the save struture -1 since + * the push operation post-decrements -- need to REVISIT this). + */ + + in r16, __SP_L__ /* Get the save structure pointer in a Call-saved register pair */ + in r17, __SP_H__ /* (Careful, push post-decrements) */ + movw r22, r16 /* Pass register save structure as the parameter 2 */ + USE_INTSTACK rx, ry, rz /* Switch to the interrupt stack */ + call up_doirq /* Dispatch the interrupt */ + RESTORE_STACK rx, ry /* - Undo the operations of USE_INTSTACK */ + + /* up_doiq returns with r24-r25 equal to the new save structure. If no context + * switch occurred, this will be the same as the value passed to it in r22-23. + * But if a context switch occurs, then the returned value will point not at a + * stack frame, but at a register save area inside of the new task's TCB. + */ + + cp r16, r24 + cpc r17, r25 + breq .Lnoswitch + + /* A context switch has occurred, jump to up_fullcontextrestore with r24, r25 + * equal to the address of the new register save ared. + */ + + jmp up_fullcontextrestore + + /* No context switch occurred.. just return off the stack */ + +.Lnoswitch: + EXCPT_EPILOGUE + reti + +/**************************************************************************************************** + * Name: up_interruptstack + ****************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + .bss + .align 4 + .globl up_interruptstack + .type up_interruptstack, object +up_interruptstack: + .skip CONFIG_ARCH_INTERRUPTSTACK +.Lintstackbase: + .size up_interruptstack, .-up_interruptstack +#endif + .end + diff --git a/arch/avr/src/at90usb/at90usb_head.S b/arch/avr/src/at90usb/at90usb_head.S index 608595f90f..a9ec75700c 100755 --- a/arch/avr/src/at90usb/at90usb_head.S +++ b/arch/avr/src/at90usb/at90usb_head.S @@ -1,277 +1,277 @@ -/**************************************************************************** - * arch/avr32/src/at90usb/at90usb_head.S - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -/**************************************************************************** - * Pre-processor definitions - ****************************************************************************/ - -/* Stack is allocated just after .bss and before the heap */ - -#define STACKBASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE-1) - -/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH. - * Only the AT90USB646, 647, 1286, and 1287 are supported by this file. - * - * - Support for the EPLMX instructions is assumed if RAMPZ is present - * - If RAMPZ is not present, support for LPMX is assumed - */ - -#if defined(CONFIG_ARCH_CHIP_AT90USB1286) || defined(CONFIG_ARCH_CHIP_AT90USB1286) -# define HAVE_RAMPZ 1 -#endif - -/**************************************************************************** - * External Symbols - ****************************************************************************/ - - .file "up_nommuhead.S" - .global __start /* Entry point */ - .global _sbss /* Start of .bss. Defined by ld.script */ - .global _ebss /* End of .bss. Defined by ld.script */ - .global _sdata /* Start of .data section in RAM */ - .global _edata /* End of .data section in RAM */ - .global _eronly /* Start of .data section in FLASH */ - .global up_lowinit /* Perform low level initialization */ - .global os_start /* NuttX entry point */ - - .global vectortab - .global at90usb_int0 /* External interrupt request 0 */ - .global at90usb_int1 /* External interrupt request 1 */ - .global at90usb_int2 /* External interrupt request 2 */ - .global at90usb_int3 /* External interrupt request 3 */ - .global at90usb_int4 /* External interrupt request 4 */ - .global at90usb_int5 /* External interrupt request 5 */ - .global at90usb_int6 /* External interrupt request 6 */ - .global at90usb_int7 /* External interrupt request 7 */ - .global at90usb_pcint0 /* Pin Change Interrupt Request 0 */ - .global at90usb_usbgen /* USB General USB General Interrupt request */ - .global at90usb_usbep /* USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ - .global at90usb_wdt /* Watchdog Time-out Interrupt */ - .global at90usb_t2compa /* TIMER2 COMPA Timer/Counter2 Compare Match A */ - .global at90usb_t2compb /* TIMER2 COMPB Timer/Counter2 Compare Match B */ - .global at90usb_t2ovf /* TIMER2 OVF Timer/Counter2 Overflow */ - .global at90usb_t1capt /* TIMER1 CAPT Timer/Counter1 Capture Event */ - .global at90usb_t1compa /* TIMER1 COMPA Timer/Counter1 Compare Match A */ - .global at90usb_t1compb /* TIMER1 COMPB Timer/Counter1 Compare Match B */ - .global at90usb_t1compc /* TIMER1 COMPC Timer/Counter1 Compare Match c */ - .global at90usb_t1ovf /* TIMER1 OVF Timer/Counter1 Overflow */ - .global at90usb_t0compa /* TIMER0 COMPA Timer/Counter0 Compare Match A */ - .global at90usb_t0compb /* TIMER0 COMPB Timer/Counter0 Compare Match B */ - .global at90usb_t0ovf /* TIMER0 OVF Timer/Counter0 Overflow */ - .global at90usb_spi /* STC SPI Serial Transfer Complete */ - .global at90usb_u1rx /* USART1 Rx Complete */ - .global at90usb_u1dre /* USART1 Data Register Empty */ - .global at90usb_u1tx /* USART1 Tx Complete */ - .global at90usb_anacomp /* ANALOG COMP Analog Comparator */ - .global at90usb_adc /* ADC Conversion Complete */ - .global at90usb_ee /* EEPROM Ready */ - .global at90usb_t3capt /* TIMER3 CAPT Timer/Counter3 Capture Event */ - .global at90usb_t3compa /* TIMER3 COMPA Timer/Counter3 Compare Match A */ - .global at90usb_t3compb /* TIMER3 COMPB Timer/Counter3 Compare Match B */ - .global at90usb_t3compc /* TIMER3 COMPC Timer/Counter3 Compare Match C */ - .global at90usb_t3ovf /* TIMER3 OVF Timer/Counter3 Overflow */ - .global at90usb_twi /* TWI Two-wire Serial Interface */ - .global at90usb_spmrdy /* Store Program Memory Ready */ - -/**************************************************************************** - * Macros - ****************************************************************************/ - - .macro vector name - jmp \name - .endm - -/**************************************************************************** - * Vector Table - ****************************************************************************/ - -/* The AT90USB has 38 interrupt vectors including vector 0, the reset - * vector. - */ - - .section .vectors, "ax", @progbits - .func vectortab -vectortab: - jmp __start /* 0: Vector 0 is the reset vector */ - vector at90usb_int0 /* 1: External interrupt request 0 */ - vector at90usb_int1 /* 2: External interrupt request 1 */ - vector at90usb_int2 /* 3: External interrupt request 2 */ - vector at90usb_int3 /* 4: External interrupt request 3 */ - vector at90usb_int4 /* 5: External interrupt request 4 */ - vector at90usb_int5 /* 6: External interrupt request 5 */ - vector at90usb_int6 /* 7: External interrupt request 6 */ - vector at90usb_int7 /* 8: External interrupt request 7 */ - vector at90usb_pcint0 /* 9: PCINT0 Pin Change Interrupt Request 0 */ - vector at90usb_usbgen /* 10: USB General USB General Interrupt request */ - vector at90usb_usbep /* 11: USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ - vector at90usb_wdt /* 12: Watchdog Time-out Interrupt */ - vector at90usb_t2compa /* 13: TIMER2 COMPA Timer/Counter2 Compare Match A */ - vector at90usb_t2compb /* 14: TIMER2 COMPB Timer/Counter2 Compare Match B */ - vector at90usb_t2ovf /* 15: TIMER2 OVF Timer/Counter2 Overflow */ - vector at90usb_t1capt /* 16: TIMER1 CAPT Timer/Counter1 Capture Event */ - vector at90usb_t1compa /* 17: TIMER1 COMPA Timer/Counter1 Compare Match A */ - vector at90usb_t1compb /* 18: TIMER1 COMPB Timer/Counter1 Compare Match B */ - vector at90usb_t1compc /* 19: TIMER1 COMPC Timer/Counter1 Compare Match c */ - vector at90usb_t1ovf /* 20: TIMER1 OVF Timer/Counter1 Overflow */ - vector at90usb_t0compa /* 21: TIMER0 COMPA Timer/Counter0 Compare Match A */ - vector at90usb_t0compb /* 22: TIMER0 COMPB Timer/Counter0 Compare Match B */ - vector at90usb_t0ovf /* 23: TIMER0 OVF Timer/Counter0 Overflow */ - vector at90usb_spi /* 24: STC SPI Serial Transfer Complete */ - vector at90usb_u1rx /* 25: USART1 Rx Complete */ - vector at90usb_u1dre /* 26: USART1 Data Register Empty */ - vector at90usb_u1tx /* 27: USART1 Tx Complete */ - vector at90usb_anacomp /* 28: ANALOG COMP Analog Comparator */ - vector at90usb_adc /* 29: ADC Conversion Complete */ - vector at90usb_ee /* 30: EEPROM Ready */ - vector at90usb_t3capt /* 31: TIMER3 CAPT Timer/Counter3 Capture Event */ - vector at90usb_t3compa /* 32: TIMER3 COMPA Timer/Counter3 Compare Match A */ - vector at90usb_t3compb /* 33: TIMER3 COMPB Timer/Counter3 Compare Match B */ - vector at90usb_t3compc /* 34: TIMER3 COMPC Timer/Counter3 Compare Match C */ - vector at90usb_t3ovf /* 35: TIMER3 OVF Timer/Counter3 Overflow */ - vector at90usb_twi /* 36: TWI Two-wire Serial Interface */ - vector at90usb_spmrdy /* 37: Store Program Memory Ready */ - .endfunc - -/**************************************************************************** - * Reset Entry Point - ****************************************************************************/ - - .section .init, "ax", @progbits - .func __start -__start: - - /* Clear the zero register, clear the status register and initialize the - * IDLE thread stack - */ - - clr r1 - out _SFR_IO_ADDR(SREG), r1 - ldi r28, lo8(STACKBASE) - ldi r29, hi8(STACKBASE) - out _SFR_IO_ADDR(SPH), r29 - out _SFR_IO_ADDR(SPL), r28 - - /* Copy initial global data values from FLASH into RAM */ - - .global __do_copy_data; /* Required to suppress dragging in logic from libgcc */ -__do_copy_data: - -#ifdef HAVE_RAMPZ - ldi r17, hi8(_edata) - ldi r26, lo8(_sdata) - ldi r27, hi8(_sdata) - ldi r30, lo8(_eronly) - ldi r31, hi8(_eronly) - ldi r16, hh8(_eronly) - out _SFR_IO_ADDR(RAMPZ), r16 - rjmp .Lcopystart - -.Lcopyloop: - elpm r0, Z+ - st X+, r0 - -.Lcopystart: - cpi r26, lo8(_edata) - cpc r27, r17 - brne .Lcopyloop -#else - ldi r17, hi8(_edata) - ldi r26, lo8(_sdata) - ldi r27, hi8(_sdata) - ldi r30, lo8(_eronly) - ldi r31, hi8(_eronly) - rjmp .Lcopystart - -.Lcopyloop: - lpm r0, Z+ - st X+, r0 -.Lcopystart: - cpi r26, lo8(_edata) - cpc r27, r17 - brne .Lcopyloop -#endif - - /* Clear uninitialized data */ - - .global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */ -__do_clear_bss: - - ldi r17, hi8(_ebss) - ldi r26, lo8(_sbss) - ldi r27, hi8(_sbss) - rjmp .Lclearstart - -.Lclearloop: - st X+, r1 -.Lclearstart: - cpi r26, lo8(_ebss) - cpc r27, r17 - brne .Lclearloop - - /* Perform any low-level initialization */ - - call up_lowinit - - /* Now start NuttX */ - - call os_start - jmp exit - .endfunc - -/**************************************************************************** - * Heap Base - ****************************************************************************/ - - /* This global variable is unsigned long g_heapbase and is - * exported from here only because of its coupling to other - * uses of _ebss in this file - */ - - .data - .globl g_heapbase - .type g_heapbase, object -g_heapbase: - .word _ebss+CONFIG_IDLETHREAD_STACKSIZE - .size g_heapbase, .-g_heapbase - .end +/**************************************************************************** + * arch/avr32/src/at90usb/at90usb_head.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* Stack is allocated just after .bss and before the heap */ + +#define STACKBASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE-1) + +/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH. + * Only the AT90USB646, 647, 1286, and 1287 are supported by this file. + * + * - Support for the EPLMX instructions is assumed if RAMPZ is present + * - If RAMPZ is not present, support for LPMX is assumed + */ + +#if defined(CONFIG_ARCH_CHIP_AT90USB1286) || defined(CONFIG_ARCH_CHIP_AT90USB1286) +# define HAVE_RAMPZ 1 +#endif + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_nommuhead.S" + .global __start /* Entry point */ + .global _sbss /* Start of .bss. Defined by ld.script */ + .global _ebss /* End of .bss. Defined by ld.script */ + .global _sdata /* Start of .data section in RAM */ + .global _edata /* End of .data section in RAM */ + .global _eronly /* Start of .data section in FLASH */ + .global up_lowinit /* Perform low level initialization */ + .global os_start /* NuttX entry point */ + + .global vectortab + .global at90usb_int0 /* External interrupt request 0 */ + .global at90usb_int1 /* External interrupt request 1 */ + .global at90usb_int2 /* External interrupt request 2 */ + .global at90usb_int3 /* External interrupt request 3 */ + .global at90usb_int4 /* External interrupt request 4 */ + .global at90usb_int5 /* External interrupt request 5 */ + .global at90usb_int6 /* External interrupt request 6 */ + .global at90usb_int7 /* External interrupt request 7 */ + .global at90usb_pcint0 /* Pin Change Interrupt Request 0 */ + .global at90usb_usbgen /* USB General USB General Interrupt request */ + .global at90usb_usbep /* USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ + .global at90usb_wdt /* Watchdog Time-out Interrupt */ + .global at90usb_t2compa /* TIMER2 COMPA Timer/Counter2 Compare Match A */ + .global at90usb_t2compb /* TIMER2 COMPB Timer/Counter2 Compare Match B */ + .global at90usb_t2ovf /* TIMER2 OVF Timer/Counter2 Overflow */ + .global at90usb_t1capt /* TIMER1 CAPT Timer/Counter1 Capture Event */ + .global at90usb_t1compa /* TIMER1 COMPA Timer/Counter1 Compare Match A */ + .global at90usb_t1compb /* TIMER1 COMPB Timer/Counter1 Compare Match B */ + .global at90usb_t1compc /* TIMER1 COMPC Timer/Counter1 Compare Match c */ + .global at90usb_t1ovf /* TIMER1 OVF Timer/Counter1 Overflow */ + .global at90usb_t0compa /* TIMER0 COMPA Timer/Counter0 Compare Match A */ + .global at90usb_t0compb /* TIMER0 COMPB Timer/Counter0 Compare Match B */ + .global at90usb_t0ovf /* TIMER0 OVF Timer/Counter0 Overflow */ + .global at90usb_spi /* STC SPI Serial Transfer Complete */ + .global at90usb_u1rx /* USART1 Rx Complete */ + .global at90usb_u1dre /* USART1 Data Register Empty */ + .global at90usb_u1tx /* USART1 Tx Complete */ + .global at90usb_anacomp /* ANALOG COMP Analog Comparator */ + .global at90usb_adc /* ADC Conversion Complete */ + .global at90usb_ee /* EEPROM Ready */ + .global at90usb_t3capt /* TIMER3 CAPT Timer/Counter3 Capture Event */ + .global at90usb_t3compa /* TIMER3 COMPA Timer/Counter3 Compare Match A */ + .global at90usb_t3compb /* TIMER3 COMPB Timer/Counter3 Compare Match B */ + .global at90usb_t3compc /* TIMER3 COMPC Timer/Counter3 Compare Match C */ + .global at90usb_t3ovf /* TIMER3 OVF Timer/Counter3 Overflow */ + .global at90usb_twi /* TWI Two-wire Serial Interface */ + .global at90usb_spmrdy /* Store Program Memory Ready */ + +/**************************************************************************** + * Macros + ****************************************************************************/ + + .macro vector name + jmp \name + .endm + +/**************************************************************************** + * Vector Table + ****************************************************************************/ + +/* The AT90USB has 38 interrupt vectors including vector 0, the reset + * vector. + */ + + .section .vectors, "ax", @progbits + .func vectortab +vectortab: + jmp __start /* 0: Vector 0 is the reset vector */ + vector at90usb_int0 /* 1: External interrupt request 0 */ + vector at90usb_int1 /* 2: External interrupt request 1 */ + vector at90usb_int2 /* 3: External interrupt request 2 */ + vector at90usb_int3 /* 4: External interrupt request 3 */ + vector at90usb_int4 /* 5: External interrupt request 4 */ + vector at90usb_int5 /* 6: External interrupt request 5 */ + vector at90usb_int6 /* 7: External interrupt request 6 */ + vector at90usb_int7 /* 8: External interrupt request 7 */ + vector at90usb_pcint0 /* 9: PCINT0 Pin Change Interrupt Request 0 */ + vector at90usb_usbgen /* 10: USB General USB General Interrupt request */ + vector at90usb_usbep /* 11: USB Endpoint/Pipe USB ENdpoint/Pipe Interrupt request */ + vector at90usb_wdt /* 12: Watchdog Time-out Interrupt */ + vector at90usb_t2compa /* 13: TIMER2 COMPA Timer/Counter2 Compare Match A */ + vector at90usb_t2compb /* 14: TIMER2 COMPB Timer/Counter2 Compare Match B */ + vector at90usb_t2ovf /* 15: TIMER2 OVF Timer/Counter2 Overflow */ + vector at90usb_t1capt /* 16: TIMER1 CAPT Timer/Counter1 Capture Event */ + vector at90usb_t1compa /* 17: TIMER1 COMPA Timer/Counter1 Compare Match A */ + vector at90usb_t1compb /* 18: TIMER1 COMPB Timer/Counter1 Compare Match B */ + vector at90usb_t1compc /* 19: TIMER1 COMPC Timer/Counter1 Compare Match c */ + vector at90usb_t1ovf /* 20: TIMER1 OVF Timer/Counter1 Overflow */ + vector at90usb_t0compa /* 21: TIMER0 COMPA Timer/Counter0 Compare Match A */ + vector at90usb_t0compb /* 22: TIMER0 COMPB Timer/Counter0 Compare Match B */ + vector at90usb_t0ovf /* 23: TIMER0 OVF Timer/Counter0 Overflow */ + vector at90usb_spi /* 24: STC SPI Serial Transfer Complete */ + vector at90usb_u1rx /* 25: USART1 Rx Complete */ + vector at90usb_u1dre /* 26: USART1 Data Register Empty */ + vector at90usb_u1tx /* 27: USART1 Tx Complete */ + vector at90usb_anacomp /* 28: ANALOG COMP Analog Comparator */ + vector at90usb_adc /* 29: ADC Conversion Complete */ + vector at90usb_ee /* 30: EEPROM Ready */ + vector at90usb_t3capt /* 31: TIMER3 CAPT Timer/Counter3 Capture Event */ + vector at90usb_t3compa /* 32: TIMER3 COMPA Timer/Counter3 Compare Match A */ + vector at90usb_t3compb /* 33: TIMER3 COMPB Timer/Counter3 Compare Match B */ + vector at90usb_t3compc /* 34: TIMER3 COMPC Timer/Counter3 Compare Match C */ + vector at90usb_t3ovf /* 35: TIMER3 OVF Timer/Counter3 Overflow */ + vector at90usb_twi /* 36: TWI Two-wire Serial Interface */ + vector at90usb_spmrdy /* 37: Store Program Memory Ready */ + .endfunc + +/**************************************************************************** + * Reset Entry Point + ****************************************************************************/ + + .section .init, "ax", @progbits + .func __start +__start: + + /* Clear the zero register, clear the status register and initialize the + * IDLE thread stack + */ + + clr r1 + out _SFR_IO_ADDR(SREG), r1 + ldi r28, lo8(STACKBASE) + ldi r29, hi8(STACKBASE) + out _SFR_IO_ADDR(SPH), r29 + out _SFR_IO_ADDR(SPL), r28 + + /* Copy initial global data values from FLASH into RAM */ + + .global __do_copy_data; /* Required to suppress dragging in logic from libgcc */ +__do_copy_data: + +#ifdef HAVE_RAMPZ + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + ldi r16, hh8(_eronly) + out _SFR_IO_ADDR(RAMPZ), r16 + rjmp .Lcopystart + +.Lcopyloop: + elpm r0, Z+ + st X+, r0 + +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#else + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + rjmp .Lcopystart + +.Lcopyloop: + lpm r0, Z+ + st X+, r0 +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#endif + + /* Clear uninitialized data */ + + .global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */ +__do_clear_bss: + + ldi r17, hi8(_ebss) + ldi r26, lo8(_sbss) + ldi r27, hi8(_sbss) + rjmp .Lclearstart + +.Lclearloop: + st X+, r1 +.Lclearstart: + cpi r26, lo8(_ebss) + cpc r27, r17 + brne .Lclearloop + + /* Perform any low-level initialization */ + + call up_lowinit + + /* Now start NuttX */ + + call os_start + jmp exit + .endfunc + +/**************************************************************************** + * Heap Base + ****************************************************************************/ + + /* This global variable is unsigned long g_heapbase and is + * exported from here only because of its coupling to other + * uses of _ebss in this file + */ + + .data + .globl g_heapbase + .type g_heapbase, object +g_heapbase: + .word _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_heapbase, .-g_heapbase + .end diff --git a/arch/avr/src/atmega/atmega_exceptions.S b/arch/avr/src/atmega/atmega_exceptions.S index 522eddbed5..c4fea31dab 100755 --- a/arch/avr/src/atmega/atmega_exceptions.S +++ b/arch/avr/src/atmega/atmega_exceptions.S @@ -1,118 +1,169 @@ -/******************************************************************************************** - * arch/avr/src/atmega/atmega_exceptions.S - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ********************************************************************************************/ - -/******************************************************************************************** - * Included Files - ********************************************************************************************/ - -#include - -#include - -#include "excptmacros.h" - -/******************************************************************************************** - * External Symbols - ********************************************************************************************/ - - .file "atmega_exceptions.S" - .global up_doirq - -/******************************************************************************************** - * Macros - ********************************************************************************************/ - -/******************************************************************************************** - * Exception Vector Handlers - ********************************************************************************************/ - - .section .handlers, "ax", @progbits - - HANDLER atmega_int0, ATMEGA_IRQ_INT0, excpt_common /* External interrupt request 0 */ - HANDLER atmega_int1, ATMEGA_IRQ_INT1, excpt_common /* External interrupt request 1 */ - HANDLER atmega_int2, ATMEGA_IRQ_INT2, excpt_common /* External interrupt request 2 */ - HANDLER atmega_int3, ATMEGA_IRQ_INT3, excpt_common /* External interrupt request 3 */ - HANDLER atmega_int4, ATMEGA_IRQ_INT4, excpt_common /* External interrupt request 4 */ - HANDLER atmega_int5, ATMEGA_IRQ_INT5, excpt_common /* External interrupt request 5 */ - HANDLER atmega_int6, ATMEGA_IRQ_INT6, excpt_common /* External interrupt request 6 */ - HANDLER atmega_int7, ATMEGA_IRQ_INT7, excpt_common /* External interrupt request 7 */ - HANDLER atmega_t2comp, ATMEGA_IRQ_T2COMP, excpt_common /* TIMER2 COMP timer/counter2 compare match */ - HANDLER atmega_t2ovf, ATMEGA_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ - HANDLER atmega_t1capt, ATMEGA_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ - HANDLER atmega_t1compa, ATMEGA_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match a */ - HANDLER atmega_t1compb, ATMEGA_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match b */ - HANDLER atmega_t1ovf, ATMEGA_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ - HANDLER atmega_t0comp, ATMEGA_IRQ_T0COMP, excpt_common /* TIMER0 COMP timer/counter0 compare match */ - HANDLER atmega_t0ovf, ATMEGA_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ - HANDLER atmega_spi, ATMEGA_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ - HANDLER atmega_u0rx, ATMEGA_IRQ_U0RX, excpt_common /* USART0 RX complete */ - HANDLER atmega_u0dre, ATMEGA_IRQ_U0DRE, excpt_common /* USART0 data register empty */ - HANDLER atmega_u0tx, ATMEGA_IRQ_U0TX, excpt_common /* USART0 TX complete */ - HANDLER atmega_adc, ATMEGA_IRQ_ADC, excpt_common /* ADC conversion complete */ - HANDLER atmega_ee, ATMEGA_IRQ_EE, excpt_common /* EEPROM ready */ - HANDLER atmega_anacomp, ATMEGA_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ - HANDLER atmega_t1compc, ATMEGA_IRQ_T1COMPC, excpt_common /* TIMER1 COMPC timer/countre1 compare match c */ - HANDLER atmega_t3capt, ATMEGA_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ - HANDLER atmega_t3compa, ATMEGA_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ - HANDLER atmega_t3compb, ATMEGA_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ - HANDLER atmega_t3compc, ATMEGA_IRQ_T3COMPC, excpt_common /* TIMER3 COMPC timer/counter3 compare match c */ - HANDLER atmega_t3ovf, ATMEGA_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ - HANDLER atmega_u1rx, ATMEGA_IRQ_U1RX, excpt_common /* USART1 RX complete */ - HANDLER atmega_u1dre, ATMEGA_IRQ_U1DRE, excpt_common /* USART1 data register empty */ - HANDLER atmega_u1tx, ATMEGA_IRQ_U1TX, excpt_common /* USART1 TX complete */ - HANDLER atmega_twi, ATMEGA_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ - HANDLER atmega_spmrdy, ATMEGA_IRQ_SPMRDY, excpt_common /* Store program memory ready */ - -/* Common exception handling logic. */ - -excpt_common: -#warning "Missing Logic" - -/**************************************************************************************************** - * Name: up_interruptstack - ****************************************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 0 - .bss - .align 4 - .globl up_interruptstack - .type up_interruptstack, object -up_interruptstack: - .skip CONFIG_ARCH_INTERRUPTSTACK -.Lintstackbase: - .size up_interruptstack, .-up_interruptstack -#endif - .end - +/******************************************************************************************** + * arch/avr/src/atmega/atmega_exceptions.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include + +#include "excptmacros.h" + +/******************************************************************************************** + * External Symbols + ********************************************************************************************/ + + .file "atmega_exceptions.S" + .global up_doirq + .gloal up_fullcontextrestore + +/******************************************************************************************** + * Macros + ********************************************************************************************/ + +/******************************************************************************************** + * Exception Vector Handlers + ********************************************************************************************/ + + .section .handlers, "ax", @progbits + + HANDLER atmega_int0, ATMEGA_IRQ_INT0, excpt_common /* External interrupt request 0 */ + HANDLER atmega_int1, ATMEGA_IRQ_INT1, excpt_common /* External interrupt request 1 */ + HANDLER atmega_int2, ATMEGA_IRQ_INT2, excpt_common /* External interrupt request 2 */ + HANDLER atmega_int3, ATMEGA_IRQ_INT3, excpt_common /* External interrupt request 3 */ + HANDLER atmega_int4, ATMEGA_IRQ_INT4, excpt_common /* External interrupt request 4 */ + HANDLER atmega_int5, ATMEGA_IRQ_INT5, excpt_common /* External interrupt request 5 */ + HANDLER atmega_int6, ATMEGA_IRQ_INT6, excpt_common /* External interrupt request 6 */ + HANDLER atmega_int7, ATMEGA_IRQ_INT7, excpt_common /* External interrupt request 7 */ + HANDLER atmega_t2comp, ATMEGA_IRQ_T2COMP, excpt_common /* TIMER2 COMP timer/counter2 compare match */ + HANDLER atmega_t2ovf, ATMEGA_IRQ_T2OVF, excpt_common /* TIMER2 OVF timer/counter2 overflow */ + HANDLER atmega_t1capt, ATMEGA_IRQ_T1CAPT, excpt_common /* TIMER1 CAPT timer/counter1 capture event */ + HANDLER atmega_t1compa, ATMEGA_IRQ_T1COMPA, excpt_common /* TIMER1 COMPA timer/counter1 compare match a */ + HANDLER atmega_t1compb, ATMEGA_IRQ_T1COMPB, excpt_common /* TIMER1 COMPB timer/counter1 compare match b */ + HANDLER atmega_t1ovf, ATMEGA_IRQ_T1OVF, excpt_common /* TIMER1 OVF timer/counter1 overflow */ + HANDLER atmega_t0comp, ATMEGA_IRQ_T0COMP, excpt_common /* TIMER0 COMP timer/counter0 compare match */ + HANDLER atmega_t0ovf, ATMEGA_IRQ_T0OVF, excpt_common /* TIMER0 OVF timer/counter0 overflow */ + HANDLER atmega_spi, ATMEGA_IRQ_SPI, excpt_common /* STC SPI serial transfer complete */ + HANDLER atmega_u0rx, ATMEGA_IRQ_U0RX, excpt_common /* USART0 RX complete */ + HANDLER atmega_u0dre, ATMEGA_IRQ_U0DRE, excpt_common /* USART0 data register empty */ + HANDLER atmega_u0tx, ATMEGA_IRQ_U0TX, excpt_common /* USART0 TX complete */ + HANDLER atmega_adc, ATMEGA_IRQ_ADC, excpt_common /* ADC conversion complete */ + HANDLER atmega_ee, ATMEGA_IRQ_EE, excpt_common /* EEPROM ready */ + HANDLER atmega_anacomp, ATMEGA_IRQ_ANACOMP, excpt_common /* ANALOG COMP analog comparator */ + HANDLER atmega_t1compc, ATMEGA_IRQ_T1COMPC, excpt_common /* TIMER1 COMPC timer/countre1 compare match c */ + HANDLER atmega_t3capt, ATMEGA_IRQ_T3CAPT, excpt_common /* TIMER3 CAPT timer/counter3 capture event */ + HANDLER atmega_t3compa, ATMEGA_IRQ_T3COMPA, excpt_common /* TIMER3 COMPA timer/counter3 compare match a */ + HANDLER atmega_t3compb, ATMEGA_IRQ_T3COMPB, excpt_common /* TIMER3 COMPB timer/counter3 compare match b */ + HANDLER atmega_t3compc, ATMEGA_IRQ_T3COMPC, excpt_common /* TIMER3 COMPC timer/counter3 compare match c */ + HANDLER atmega_t3ovf, ATMEGA_IRQ_T3OVF, excpt_common /* TIMER3 OVF timer/counter3 overflow */ + HANDLER atmega_u1rx, ATMEGA_IRQ_U1RX, excpt_common /* USART1 RX complete */ + HANDLER atmega_u1dre, ATMEGA_IRQ_U1DRE, excpt_common /* USART1 data register empty */ + HANDLER atmega_u1tx, ATMEGA_IRQ_U1TX, excpt_common /* USART1 TX complete */ + HANDLER atmega_twi, ATMEGA_IRQ_TWI, excpt_common /* TWI two-wire serial interface */ + HANDLER atmega_spmrdy, ATMEGA_IRQ_SPMRDY, excpt_common /* Store program memory ready */ + +/******************************************************************************************** + * Name: excpt_common + * + * Description: + * Exception Vector Handlers + * + * On Entry: + * The return PC and the saved r24 is on the stack, r24 now contains the IRQ number + * + * PCL + * PCH + * R0 + * --- <- SP + * + ********************************************************************************************/ + +excpt_common: + /* Save the remaining registers on the stack, preserving the IRQ number in r14 */ + + EXCPT_PROLOGUE + + /* Call up_doirq with r24 = IRQ number, r22-23 = Pointer to the save structure. The stack + * pointer currently points to the save structure (or maybe the save struture -1 since + * the push operation post-decrements -- need to REVISIT this). + */ + + in r16, __SP_L__ /* Get the save structure pointer in a Call-saved register pair */ + in r17, __SP_H__ /* (Careful, push post-decrements) */ + movw r22, r16 /* Pass register save structure as the parameter 2 */ + USE_INTSTACK rx, ry, rz /* Switch to the interrupt stack */ + call up_doirq /* Dispatch the interrupt */ + RESTORE_STACK rx, ry /* - Undo the operations of USE_INTSTACK */ + + /* up_doiq returns with r24-r25 equal to the new save structure. If no context + * switch occurred, this will be the same as the value passed to it in r22-23. + * But if a context switch occurs, then the returned value will point not at a + * stack frame, but at a register save area inside of the new task's TCB. + */ + + cp r16, r24 + cpc r17, r25 + breq .Lnoswitch + + /* A context switch has occurred, jump to up_fullcontextrestore with r24, r25 + * equal to the address of the new register save ared. + */ + + jmp up_fullcontextrestore + + /* No context switch occurred.. just return off the stack */ + +.Lnoswitch: + EXCPT_EPILOGUE + reti + +/**************************************************************************************************** + * Name: up_interruptstack + ****************************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + .bss + .align 4 + .globl up_interruptstack + .type up_interruptstack, object +up_interruptstack: + .skip CONFIG_ARCH_INTERRUPTSTACK +.Lintstackbase: + .size up_interruptstack, .-up_interruptstack +#endif + .end + diff --git a/arch/avr/src/atmega/atmega_head.S b/arch/avr/src/atmega/atmega_head.S index 281b1e1599..cc3027658c 100755 --- a/arch/avr/src/atmega/atmega_head.S +++ b/arch/avr/src/atmega/atmega_head.S @@ -1,271 +1,271 @@ -/**************************************************************************** - * arch/avr32/src/atmega/atmega_head.S - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -/**************************************************************************** - * Pre-processor definitions - ****************************************************************************/ - -/* Stack is allocated just after .bss and before the heap */ - -#define STACKBASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) - -/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH. - * At present, only the ATMega128 is supported so RAMPZ should always be - * available. - * - * - Support for the EPLMX instructions is assumed if RAMPZ is present - * - If RAMPZ is not present, support for LPMX is assumed - */ - -#define HAVE_RAMPZ 1 - -/**************************************************************************** - * External Symbols - ****************************************************************************/ - - .file "up_nommuhead.S" - .global __start /* Entry point */ - .global _sbss /* Start of .bss. Defined by ld.script */ - .global _ebss /* End of .bss. Defined by ld.script */ - .global _sdata /* Start of .data section in RAM */ - .global _edata /* End of .data section in RAM */ - .global _eronly /* Start of .data section in FLASH */ - .global up_lowinit /* Perform low level initialization */ - .global os_start /* NuttX entry point */ - - .global vectortab - .global atmega_int0 /* External interrupt request 0 */ - .global atmega_int1 /* External interrupt request 1 */ - .global atmega_int2 /* External interrupt request 2 */ - .global atmega_int3 /* External interrupt request 3 */ - .global atmega_int4 /* External interrupt request 4 */ - .global atmega_int5 /* External interrupt request 5 */ - .global atmega_int6 /* External interrupt request 6 */ - .global atmega_int7 /* External interrupt request 7 */ - .global atmega_t2comp /* TIMER2 COMP timer/counter2 compare match */ - .global atmega_t2ovf /* TIMER2 OVF timer/counter2 overflow */ - .global atmega_t1capt /* TIMER1 CAPT timer/counter1 capture event */ - .global atmega_t1compa /* TIMER1 COMPA timer/counter1 compare match a */ - .global atmega_t1compb /* TIMER1 COMPB timer/counter1 compare match b */ - .global atmega_t1ovf /* TIMER1 OVF timer/counter1 overflow */ - .global atmega_t0comp /* TIMER0 COMP timer/counter0 compare match */ - .global atmega_t0ovf /* TIMER0 OVF timer/counter0 overflow */ - .global atmega_spi /* STC SPI serial transfer complete */ - .global atmega_u0rx /* USART0 RX complete */ - .global atmega_u0dre /* USART0 data register empty */ - .global atmega_u0tx /* USART0 TX complete */ - .global atmega_adc /* ADC conversion complete */ - .global atmega_ee /* EEPROM ready */ - .global atmega_anacomp /* ANALOG COMP analog comparator */ - .global atmega_t1compc /* TIMER1 COMPC timer/countre1 compare match c */ - .global atmega_t3capt /* TIMER3 CAPT timer/counter3 capture event */ - .global atmega_t3compa /* TIMER3 COMPA timer/counter3 compare match a */ - .global atmega_t3compb /* TIMER3 COMPB timer/counter3 compare match b */ - .global atmega_t3compc /* TIMER3 COMPC timer/counter3 compare match c */ - .global atmega_t3ovf /* TIMER3 OVF timer/counter3 overflow */ - .global atmega_u1rx /* USART1 RX complete */ - .global atmega_u1dre /* USART1 data register empty */ - .global atmega_u1tx /* USART1 TX complete */ - .global atmega_twi /* TWI two-wire serial interface */ - .global atmega_spmrdy /* Store program memory ready */ - -/**************************************************************************** - * Macros - ****************************************************************************/ - - .macro vector name - jmp \name - .endm - -/**************************************************************************** - * Vector Table - ****************************************************************************/ - -/* The ATmega128 has 35 interrupt vectors including vector 0, the reset - * vector. - */ - - .section .vectors, "ax", @progbits - .func vectortab -vectortab: - jmp __start /* 0: Vector 0 is the reset vector */ - vector atmega_int0 /* 1: External interrupt request 0 */ - vector atmega_int1 /* 2: External interrupt request 1 */ - vector atmega_int2 /* 3: External interrupt request 2 */ - vector atmega_int3 /* 4: External interrupt request 3 */ - vector atmega_int4 /* 5: External interrupt request 4 */ - vector atmega_int5 /* 6 : External interrupt request 5 */ - vector atmega_int6 /* 7: External interrupt request 6 */ - vector atmega_int7 /* 8: External interrupt request 7 */ - vector atmega_t2comp /* 9: TIMER2 COMP timer/counter2 compare match */ - vector atmega_t2ovf /* 10: TIMER2 OVF timer/counter2 overflow */ - vector atmega_t1capt /* 11: TIMER1 CAPT timer/counter1 capture event */ - vector atmega_t1compa /* 12: TIMER1 COMPA timer/counter1 compare match a */ - vector atmega_t1compb /* 13: TIMER1 COMPB timer/counter1 compare match b */ - vector atmega_t1ovf /* 14: TIMER1 OVF timer/counter1 overflow */ - vector atmega_t0comp /* 15: TIMER0 COMP timer/counter0 compare match */ - vector atmega_t0ovf /* 16: TIMER0 OVF timer/counter0 overflow */ - vector atmega_spi /* 17: STC SPI serial transfer complete */ - vector atmega_u0rx /* 18: USART0 RX complete */ - vector atmega_u0dre /* 19: USART0 data register empty */ - vector atmega_u0tx /* 20: USART0 TX complete */ - vector atmega_adc /* 21: ADC conversion complete */ - vector atmega_ee /* 22: EEPROM ready */ - vector atmega_anacomp /* 23: ANALOG COMP analog comparator */ - vector atmega_t1compc /* 24: TIMER1 COMPC timer/countre1 compare match c */ - vector atmega_t3capt /* 25: TIMER3 CAPT timer/counter3 capture event */ - vector atmega_t3compa /* 26: TIMER3 COMPA timer/counter3 compare match a */ - vector atmega_t3compb /* 27: TIMER3 COMPB timer/counter3 compare match b */ - vector atmega_t3compc /* 28: TIMER3 COMPC timer/counter3 compare match c */ - vector atmega_t3ovf /* 29: TIMER3 OVF timer/counter3 overflow */ - vector atmega_u1rx /* 30: USART1 RX complete */ - vector atmega_u1dre /* 31: USART1 data register empty */ - vector atmega_u1tx /* 32: USART1 TX complete */ - vector atmega_twi /* 33: TWI two-wire serial interface */ - vector atmega_spmrdy /* 34: Store program memory ready */ - .endfunc - -/**************************************************************************** - * Reset Entry Point - ****************************************************************************/ - - .section .init, "ax", @progbits - .func __start -__start: - - /* Clear the zero register, clear the status register and initialize the - * IDLE thread stack - */ - - clr r1 - out _SFR_IO_ADDR(SREG), r1 - ldi r28, lo8(STACKBASE) - ldi r29, hi8(STACKBASE) - out _SFR_IO_ADDR(SPH), r29 - out _SFR_IO_ADDR(SPL), r28 - - /* Copy initial global data values from FLASH into RAM */ - - .global __do_copy_data; /* Required to suppress dragging in logic from libgcc */ -__do_copy_data: - -#ifdef HAVE_RAMPZ - ldi r17, hi8(_edata) - ldi r26, lo8(_sdata) - ldi r27, hi8(_sdata) - ldi r30, lo8(_eronly) - ldi r31, hi8(_eronly) - ldi r16, hh8(_eronly) - out _SFR_IO_ADDR(RAMPZ), r16 - rjmp .Lcopystart - -.Lcopyloop: - elpm r0, Z+ - st X+, r0 - -.Lcopystart: - cpi r26, lo8(_edata) - cpc r27, r17 - brne .Lcopyloop -#else - ldi r17, hi8(_edata) - ldi r26, lo8(_sdata) - ldi r27, hi8(_sdata) - ldi r30, lo8(_eronly) - ldi r31, hi8(_eronly) - rjmp .Lcopystart - -.Lcopyloop: - lpm r0, Z+ - st X+, r0 -.Lcopystart: - cpi r26, lo8(_edata) - cpc r27, r17 - brne .Lcopyloop -#endif - - /* Clear uninitialized data */ - - .global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */ -__do_clear_bss: - - ldi r17, hi8(_ebss) - ldi r26, lo8(_sbss) - ldi r27, hi8(_sbss) - rjmp .Lclearstart - -.Lclearloop: - st X+, r1 -.Lclearstart: - cpi r26, lo8(_ebss) - cpc r27, r17 - brne .Lclearloop - - /* Perform any low-level initialization */ - - call up_lowinit - - /* Now start NuttX */ - - call os_start - jmp exit - .endfunc - -/**************************************************************************** - * Heap Base - ****************************************************************************/ - - /* This global variable is unsigned long g_heapbase and is - * exported from here only because of its coupling to other - * uses of _ebss in this file - */ - - .data - .globl g_heapbase - .type g_heapbase, object -g_heapbase: - .word _ebss+CONFIG_IDLETHREAD_STACKSIZE - .size g_heapbase, .-g_heapbase - .end +/**************************************************************************** + * arch/avr32/src/atmega/atmega_head.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* Stack is allocated just after .bss and before the heap */ + +#define STACKBASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) + +/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH. + * At present, only the ATMega128 is supported so RAMPZ should always be + * available. + * + * - Support for the EPLMX instructions is assumed if RAMPZ is present + * - If RAMPZ is not present, support for LPMX is assumed + */ + +#define HAVE_RAMPZ 1 + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_nommuhead.S" + .global __start /* Entry point */ + .global _sbss /* Start of .bss. Defined by ld.script */ + .global _ebss /* End of .bss. Defined by ld.script */ + .global _sdata /* Start of .data section in RAM */ + .global _edata /* End of .data section in RAM */ + .global _eronly /* Start of .data section in FLASH */ + .global up_lowinit /* Perform low level initialization */ + .global os_start /* NuttX entry point */ + + .global vectortab + .global atmega_int0 /* External interrupt request 0 */ + .global atmega_int1 /* External interrupt request 1 */ + .global atmega_int2 /* External interrupt request 2 */ + .global atmega_int3 /* External interrupt request 3 */ + .global atmega_int4 /* External interrupt request 4 */ + .global atmega_int5 /* External interrupt request 5 */ + .global atmega_int6 /* External interrupt request 6 */ + .global atmega_int7 /* External interrupt request 7 */ + .global atmega_t2comp /* TIMER2 COMP timer/counter2 compare match */ + .global atmega_t2ovf /* TIMER2 OVF timer/counter2 overflow */ + .global atmega_t1capt /* TIMER1 CAPT timer/counter1 capture event */ + .global atmega_t1compa /* TIMER1 COMPA timer/counter1 compare match a */ + .global atmega_t1compb /* TIMER1 COMPB timer/counter1 compare match b */ + .global atmega_t1ovf /* TIMER1 OVF timer/counter1 overflow */ + .global atmega_t0comp /* TIMER0 COMP timer/counter0 compare match */ + .global atmega_t0ovf /* TIMER0 OVF timer/counter0 overflow */ + .global atmega_spi /* STC SPI serial transfer complete */ + .global atmega_u0rx /* USART0 RX complete */ + .global atmega_u0dre /* USART0 data register empty */ + .global atmega_u0tx /* USART0 TX complete */ + .global atmega_adc /* ADC conversion complete */ + .global atmega_ee /* EEPROM ready */ + .global atmega_anacomp /* ANALOG COMP analog comparator */ + .global atmega_t1compc /* TIMER1 COMPC timer/countre1 compare match c */ + .global atmega_t3capt /* TIMER3 CAPT timer/counter3 capture event */ + .global atmega_t3compa /* TIMER3 COMPA timer/counter3 compare match a */ + .global atmega_t3compb /* TIMER3 COMPB timer/counter3 compare match b */ + .global atmega_t3compc /* TIMER3 COMPC timer/counter3 compare match c */ + .global atmega_t3ovf /* TIMER3 OVF timer/counter3 overflow */ + .global atmega_u1rx /* USART1 RX complete */ + .global atmega_u1dre /* USART1 data register empty */ + .global atmega_u1tx /* USART1 TX complete */ + .global atmega_twi /* TWI two-wire serial interface */ + .global atmega_spmrdy /* Store program memory ready */ + +/**************************************************************************** + * Macros + ****************************************************************************/ + + .macro vector name + jmp \name + .endm + +/**************************************************************************** + * Vector Table + ****************************************************************************/ + +/* The ATmega128 has 35 interrupt vectors including vector 0, the reset + * vector. + */ + + .section .vectors, "ax", @progbits + .func vectortab +vectortab: + jmp __start /* 0: Vector 0 is the reset vector */ + vector atmega_int0 /* 1: External interrupt request 0 */ + vector atmega_int1 /* 2: External interrupt request 1 */ + vector atmega_int2 /* 3: External interrupt request 2 */ + vector atmega_int3 /* 4: External interrupt request 3 */ + vector atmega_int4 /* 5: External interrupt request 4 */ + vector atmega_int5 /* 6 : External interrupt request 5 */ + vector atmega_int6 /* 7: External interrupt request 6 */ + vector atmega_int7 /* 8: External interrupt request 7 */ + vector atmega_t2comp /* 9: TIMER2 COMP timer/counter2 compare match */ + vector atmega_t2ovf /* 10: TIMER2 OVF timer/counter2 overflow */ + vector atmega_t1capt /* 11: TIMER1 CAPT timer/counter1 capture event */ + vector atmega_t1compa /* 12: TIMER1 COMPA timer/counter1 compare match a */ + vector atmega_t1compb /* 13: TIMER1 COMPB timer/counter1 compare match b */ + vector atmega_t1ovf /* 14: TIMER1 OVF timer/counter1 overflow */ + vector atmega_t0comp /* 15: TIMER0 COMP timer/counter0 compare match */ + vector atmega_t0ovf /* 16: TIMER0 OVF timer/counter0 overflow */ + vector atmega_spi /* 17: STC SPI serial transfer complete */ + vector atmega_u0rx /* 18: USART0 RX complete */ + vector atmega_u0dre /* 19: USART0 data register empty */ + vector atmega_u0tx /* 20: USART0 TX complete */ + vector atmega_adc /* 21: ADC conversion complete */ + vector atmega_ee /* 22: EEPROM ready */ + vector atmega_anacomp /* 23: ANALOG COMP analog comparator */ + vector atmega_t1compc /* 24: TIMER1 COMPC timer/countre1 compare match c */ + vector atmega_t3capt /* 25: TIMER3 CAPT timer/counter3 capture event */ + vector atmega_t3compa /* 26: TIMER3 COMPA timer/counter3 compare match a */ + vector atmega_t3compb /* 27: TIMER3 COMPB timer/counter3 compare match b */ + vector atmega_t3compc /* 28: TIMER3 COMPC timer/counter3 compare match c */ + vector atmega_t3ovf /* 29: TIMER3 OVF timer/counter3 overflow */ + vector atmega_u1rx /* 30: USART1 RX complete */ + vector atmega_u1dre /* 31: USART1 data register empty */ + vector atmega_u1tx /* 32: USART1 TX complete */ + vector atmega_twi /* 33: TWI two-wire serial interface */ + vector atmega_spmrdy /* 34: Store program memory ready */ + .endfunc + +/**************************************************************************** + * Reset Entry Point + ****************************************************************************/ + + .section .init, "ax", @progbits + .func __start +__start: + + /* Clear the zero register, clear the status register and initialize the + * IDLE thread stack + */ + + clr r1 + out _SFR_IO_ADDR(SREG), r1 + ldi r28, lo8(STACKBASE) + ldi r29, hi8(STACKBASE) + out _SFR_IO_ADDR(SPH), r29 + out _SFR_IO_ADDR(SPL), r28 + + /* Copy initial global data values from FLASH into RAM */ + + .global __do_copy_data; /* Required to suppress dragging in logic from libgcc */ +__do_copy_data: + +#ifdef HAVE_RAMPZ + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + ldi r16, hh8(_eronly) + out _SFR_IO_ADDR(RAMPZ), r16 + rjmp .Lcopystart + +.Lcopyloop: + elpm r0, Z+ + st X+, r0 + +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#else + ldi r17, hi8(_edata) + ldi r26, lo8(_sdata) + ldi r27, hi8(_sdata) + ldi r30, lo8(_eronly) + ldi r31, hi8(_eronly) + rjmp .Lcopystart + +.Lcopyloop: + lpm r0, Z+ + st X+, r0 +.Lcopystart: + cpi r26, lo8(_edata) + cpc r27, r17 + brne .Lcopyloop +#endif + + /* Clear uninitialized data */ + + .global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */ +__do_clear_bss: + + ldi r17, hi8(_ebss) + ldi r26, lo8(_sbss) + ldi r27, hi8(_sbss) + rjmp .Lclearstart + +.Lclearloop: + st X+, r1 +.Lclearstart: + cpi r26, lo8(_ebss) + cpc r27, r17 + brne .Lclearloop + + /* Perform any low-level initialization */ + + call up_lowinit + + /* Now start NuttX */ + + call os_start + jmp exit + .endfunc + +/**************************************************************************** + * Heap Base + ****************************************************************************/ + + /* This global variable is unsigned long g_heapbase and is + * exported from here only because of its coupling to other + * uses of _ebss in this file + */ + + .data + .globl g_heapbase + .type g_heapbase, object +g_heapbase: + .word _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_heapbase, .-g_heapbase + .end diff --git a/arch/avr/src/avr/excptmacros.h b/arch/avr/src/avr/excptmacros.h index 463b952966..38aacdb963 100755 --- a/arch/avr/src/avr/excptmacros.h +++ b/arch/avr/src/avr/excptmacros.h @@ -1,567 +1,566 @@ -/******************************************************************************************** - * arch/avr/src/avr/excptmacros.h - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ********************************************************************************************/ - -#ifndef __ARCH_AVR_SRC_AVR_EXCPTMACROS_H -#define __ARCH_AVR_SRC_AVR_EXCPTMACROS_H - -/******************************************************************************************** - * Included Files - ********************************************************************************************/ - -#include - -#ifdef __ASSEMBLY__ - -#include - -#include -#include - -/******************************************************************************************** - * Pre-Processor Definitions - ********************************************************************************************/ - -/******************************************************************************************** - * Pre-processor Definitions - ********************************************************************************************/ - -#ifndef __SREG__ -# define __SREG__ 0x3f -#endif - -#ifndef __SP_H__ -# define __SP_H__ 0x3e -#endif - -#ifndef __SP_L__ -# define __SP_L__ 0x3d -#endif - -#ifndef __tmp_reg__ -# define __tmp_reg__ r0 -#endif - -#ifndef __zero_reg__ -# define __zero_reg__ r1 -#endif - -/******************************************************************************************** - * Global Symbols - ********************************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - .global g_intstackbase - .global g_nestlevel -#endif - -/******************************************************************************************** - * Assembly Language Macros - ********************************************************************************************/ - -/******************************************************************************************** - * General Exception Handling Example: - * - * HANDLER IRQ_X, my_exception - * ... - * my_exception: - * EXCPT_PROLOGUE - Save registers on stack, enable nested interrupts - * in r22, __SP_L__ - Pass register save structure as the parameter 2 - * in r23, __SP_H__ - (Careful, push post-decrements) - * USE_INTSTACK rx, ry, rz - Switch to the interrupt stack - * call handler - Handle the exception IN=old regs OUT=new regs - * RESTORE_STACK rx, ry - Undo the operations of USE_STACK - * - * EXCPT_EPILOGUE - Return to the context returned by handler() - * reti - Return from interrupt - * - ********************************************************************************************/ - -/******************************************************************************************** - * Name: HANDLER - * - * Description: - * This macro provides the exception entry logic. It is called with the PC already on the - * stack. It simply saves one register on the stack (r24) and passes the IRQ number to - * common logic (see EXCPT_PROLOGUE). - * - * On Entry: - * sp - Points to the top of the stack. The PC is already on the stack. - * Only the stack is available for storage - * - * PCL - * PCH - * --- <- SP - * - * At completion: - * Stack pointer is incremented by one, the saved r24 is on the stack, r24 now contains the - * IRQ number - * - * PCL - * PCH - * R0 - * --- <- SP - * - ********************************************************************************************/ - - .macro HANDLER, label, irqno, common - .global \label -\label: - push r24 - ldi r24, \irqno - rjmp \common - .endm - -/******************************************************************************************** - * Name: EXCPT_PROLOGUE - * - * Description: - * Provides the common "prologue" logic that should appear at the beginning of the exception - * handler. - * - * On Entry: - * r0 - has already been pushed onto the stack and now holds the IRQ number - * sp - Points to the top of the stack - * Only the stack is available for storage - * - * PCL - * PCH - * R0 - * --- <- SP - * - * At completion: - * Register state is saved on the stack; All registers are available for usage except sp. - * - ********************************************************************************************/ - - .macro EXCPT_PROLOGUE - - /* Save R1 - The zero register (but might not be zero) */ - - push r1 - - /* Save the status register on the stack */ - - in r1, __SREG__ /* Save the status register */ - cli /* Disable interrupts */ - push r1 - - /* R1 must be zero for our purposes */ - - clr r1 - - /* Save r2-r17 - Call-saved, "static" registers */ - - push r2 - push r3 - push r4 - push r5 - push r6 - push r7 - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - push r16 - push r17 - - /* Save r18-r27 - Call-used, "volatile" registers (r24 was saved by - * HANDLER, r26-r27 saved later, out of sequence) - */ - - push r18 - push r19 - push r20 - push r21 - push r22 - push r23 - push r25 - - /* Save r28-r29 - Call-saved, "static" registers */ - - push r28 - push r29 - - /* Save r30-r31 - Call-used, "volatile" registers */ - - push r30 - push r31 - - /* Now save r26-r27 */ - - push r26 - push r27 - - /* Finally, save the stack pointer. BUT we want the value of the stack pointer as - * it was on entry into this macro. We'll have to subtract to get that value. - */ - - in r24, __SP_L__ - in r25, __SP_H__ - adiw r24, XCPTCONTEXT_REGS - - push r24 - push r25 - .endm - -/******************************************************************************************** - * Name: EXCPT_EPILOGUE - * - * Description: - * Provides the "epilogue" logic that should appear at the end of every exception handler. - * - * On input: - * sp points to the address of the register save area (just as left by EXCPT_PROLOGUE). - * All registers are available for use. - * Interrupts are disabled. - * - * On completion: - * All registers restored except the PC which remains on the stack so that a return - * via reti can be performed. - * - ********************************************************************************************/ - - .macro EXCPT_EPILOGUE, regs - - /* We don't need to restore the stack pointer */ - - pop r27 - pop r26 - - /* Restore r26-r27 */ - - pop r27 - pop r26 - - /* Restore r30-r31 - Call-used, "volatile" registers */ - - pop r31 - pop r30 - - /* Restore r28-r29 - Call-saved, "static" registers */ - - pop r29 - pop r28 - - /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 already - * restored, r24 will be restored later) - */ - - pop r25 - pop r23 - pop r22 - pop r21 - pop r20 - pop r19 - pop r18 - - /* Restore r2-r17 - Call-saved, "static" registers */ - - pop r17 - pop r16 - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - pop r7 - pop r6 - pop r5 - pop r4 - pop r3 - pop r2 - - /* Restore r1 - the "zero" register (that may not be zero) */ - - pop r1 - - /* Restore the status register (probably enabling interrupts) */ - - pop r0 /* Restore the status register */ - out __SREG__, r0 - - /* Finally, restore r0 and r24 - the scratch and IRQ number registers */ - - pop r0 - pop r24 - .endm - -/******************************************************************************************** - * Name: USER_SAVE - * - * Description: - * Similar to EXPCT_PROLOGUE except that (1) this saves values into a register save - * data structure instead of on the stack, (2) the pointer is in r26;r27, and (3) - * Call-used registers are not saved. - * - * On Entry: - * X [r26:r27] - Points to the register save structure. - * Return address is already on the stack (due to CALL or RCALL instruction)/. - * Interrupts are disabled. - * - * At completion: - * Register state is saved on the stack; All registers are available for usage except sp. - * - ********************************************************************************************/ - - .macro USER_SAVE - - /* Save the current stack pointer. */ - - in r24, __SP_L__ - st x+, r24 - in r25, __SP_H__ - st x+, r24 - - /* Skip over r26-r27 and r30-r31 - Call-used, "volatile" registers */ - - adiw r26, 4 /* Four registers: r26-r27 and r30-r31*/ - - /* Save r28-r29 - Call-saved, "static" registers */ - - st x+, r29 - st x+, r28 - - /* Skip over r18-r27 - Call-used, "volatile" registers (r26-r27 have been skipped) */ - - adiw r26, 8 /* Eight registers: r18-r25 */ - - /* Save r2-r17 - Call-saved, "static" registers */ - - st x+, r17 - st x+, r16 - st x+, r15 - st x+, r14 - st x+, r13 - st x+, r12 - st x+, r11 - st x+, r10 - st x+, r9 - st x+, r8 - st x+, r7 - st x+, r6 - st x+, r5 - st x+, r4 - st x+, r3 - st x+, r2 - - /* Set r1 to zero - Function calls must return with r1=0 */ - - clr r1 - st x+, r1 - - /* Save the status register (probably not necessary since interrupts are disabled) */ - - in r0, __SREG__ - st x+, r0 - - /* Skip R0 and r24 - These are scratch register and Call-used, "volatile" registers */ - - adiw r26, 2 /* Two registers: r0, r24 */ - - /* Pop and save the return address */ - - pop r0 - st x+, r0 - pop r0 - st x+, r0 - .endm - -/******************************************************************************************** - * Name: TCB_RESTORE - * - * Description: - * Functionally equivalent to EXCPT_EPILOGUE excetp that register save area is not on the - * stack but is held in a data structure. - * - * On input: - * X [r26:r27] points to the data structure. - * All registers are available for use. - * Interrupts are disabled. - * - * On completion: - * All registers restored except for the PC with now resides at the top of the new stack - * so that iret can be used to switch to the new context. - * - ********************************************************************************************/ - - .macro TCB_RESTORE, regs - - /* Fetch the new stack pointer */ - - ld r24, x+ /* Fetch stack pointer (post-incrementing) */ - out __SP_L__, r24 - ld r25, x+ - out __SP_H__, r25 - - /* Fetch the return address and save it at the bottom of the new stack so - * that we can iret to switch contexts. - */ - - movw r28, r26 /* Get a pointer to the PCH/PCL storage location */ - adiw r28, REG_PCH - ld r25, y+ /* Load PCH and PCL */ - ld r24, y+ - push r24 /* Push PCH and PCL on the stack */ - push r25 - - /* Then get value of X [r26:r27]. Save X on the new stack where we can - * recover it later. - */ - - ld r25, x+ /* Fetch r26-r27 and save to the new stack */ - ld r24, x+ - push r24 - push r25 - - /* Restore r30-r31 - Call-used, "volatile" registers */ - - ld r31, x+ - ld r30, x+ - - /* Restore r28-r29 - Call-saved, "static" registers */ - - ld r29, x+ - ld r28, x+ - - /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 have been - * moved and r24 will be restore later) - */ - - ld r25, x+ - ld r23, x+ - ld r22, x+ - ld r21, x+ - ld r20, x+ - ld r19, x+ - ld r18, x+ - - /* Restore r2-r17 - Call-saved, "static" registers */ - - ld r17, x+ - ld r16, x+ - ld r15, x+ - ld r14, x+ - ld r13, x+ - ld r12, x+ - ld r11, x+ - ld r10, x+ - ld r9, x+ - ld r8, x+ - ld r7, x+ - ld r6, x+ - ld r5, x+ - ld r4, x+ - ld r3, x+ - ld r2, x+ - - /* Restore r1 - The "scratch" register */ - - ld r1, x+ - - /* Restore the status register (probably enabling interrupts) */ - - ld r0, x+ - out __SREG__, r0 - - /* Restore r0 and r241 - The scratch and IRQ number registers */ - - ld r0, x+ - ld r24, x+ - - /* Finally, recover X [r26-r27] from the the new stack. The PC remains on the new - * stack so that the user of this macro can return with iret. - */ - - pop r27 - pop r26 - .endm - -/******************************************************************************************** - * Name: USE_INTSTACK - * - * Description: - * Switch to the interrupt stack (if enabled in the configuration) and if the nesting level - * is equal to 0. Increment the nesting level in any event. - * - * On Entry: - * sp - Current value of the user stack pointer - * tmp1, tmp2, and tmp3 are registers that can be used temporarily. - * All interrupts should still be disabled. - * - * At completion: - * If the nesting level is 0, then (1) the user stack pointer is saved at the base of the - * interrupt stack and sp points to the interrupt stack. - * The values of tmp1, tmp2, tmp3, and sp have been altered - * - ********************************************************************************************/ - - .macro USE_INTSTACK, tmp1, tmp2, tmp3 -#if CONFIG_ARCH_INTERRUPTSTACK > 0 -# warning "Not implemented" -#endif - .endm - -/******************************************************************************************** - * Name: RESTORE_STACK - * - * Description: - * Restore the user stack. Not really.. actually only decrements the nesting level. We - * always get the new stack pointer for the register save array. - * - * On Entry: - * tmp1 and tmp2 are registers that can be used temporarily. - * All interrupts must be disabled. - * - * At completion: - * Current nesting level is decremented - * The values of tmp1 and tmp2 have been altered - * - ********************************************************************************************/ - - .macro RESTORE_STACK, tmp1, tmp2 -#if CONFIG_ARCH_INTERRUPTSTACK > 0 -# warning "Not implemented" -#endif - .endm - -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_AVR_SRC_AVR_EXCPTMACROS_H */ +/******************************************************************************************** + * arch/avr/src/avr/excptmacros.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ********************************************************************************************/ + +#ifndef __ARCH_AVR_SRC_AVR_EXCPTMACROS_H +#define __ARCH_AVR_SRC_AVR_EXCPTMACROS_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#ifdef __ASSEMBLY__ + +#include + +#include +#include + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +#ifndef __SREG__ +# define __SREG__ 0x3f +#endif + +#ifndef __SP_H__ +# define __SP_H__ 0x3e +#endif + +#ifndef __SP_L__ +# define __SP_L__ 0x3d +#endif + +#ifndef __tmp_reg__ +# define __tmp_reg__ r0 +#endif + +#ifndef __zero_reg__ +# define __zero_reg__ r1 +#endif + +/******************************************************************************************** + * Global Symbols + ********************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .global g_intstackbase + .global g_nestlevel +#endif + +/******************************************************************************************** + * Assembly Language Macros + ********************************************************************************************/ + +/******************************************************************************************** + * General Exception Handling Example: + * + * HANDLER IRQ_X, my_exception + * ... + * my_exception: + * EXCPT_PROLOGUE - Save registers on stack + * in r22, __SP_L__ - Pass register save structure as the parameter 2 + * in r23, __SP_H__ - (Careful, push post-decrements) + * USE_INTSTACK rx, ry, rz - Switch to the interrupt stack + * call handler - Handle the exception IN=old regs OUT=new regs + * RESTORE_STACK rx, ry - Undo the operations of USE_INTSTACK + * EXCPT_EPILOGUE - Return to the context returned by handler() + * reti - Return from interrupt + * + ********************************************************************************************/ + +/******************************************************************************************** + * Name: HANDLER + * + * Description: + * This macro provides the exception entry logic. It is called with the PC already on the + * stack. It simply saves one register on the stack (r24) and passes the IRQ number to + * common logic (see EXCPT_PROLOGUE). + * + * On Entry: + * sp - Points to the top of the stack. The PC is already on the stack. + * Only the stack is available for storage + * + * PCL + * PCH + * --- <- SP + * + * At completion: + * Stack pointer is incremented by one, the saved r24 is on the stack, r24 now contains the + * IRQ number + * + * PCL + * PCH + * R0 + * --- <- SP + * + ********************************************************************************************/ + + .macro HANDLER, label, irqno, common + .global \label +\label: + push r24 + ldi r24, \irqno + rjmp \common + .endm + +/******************************************************************************************** + * Name: EXCPT_PROLOGUE + * + * Description: + * Provides the common "prologue" logic that should appear at the beginning of the exception + * handler. + * + * On Entry: + * r0 - has already been pushed onto the stack and now holds the IRQ number + * sp - Points to the top of the stack + * Only the stack is available for storage + * + * PCL + * PCH + * R0 + * --- <- SP + * + * At completion: + * Register state is saved on the stack; All registers are available for usage except sp. + * + ********************************************************************************************/ + + .macro EXCPT_PROLOGUE + + /* Save R1 - The zero register (but might not be zero) */ + + push r1 + + /* Save the status register on the stack */ + + in r1, __SREG__ /* Save the status register */ + cli /* Disable interrupts */ + push r1 + + /* R1 must be zero for our purposes */ + + clr r1 + + /* Save r2-r17 - Call-saved, "static" registers */ + + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push r16 + push r17 + + /* Save r18-r27 - Call-used, "volatile" registers (r24 was saved by + * HANDLER, r26-r27 saved later, out of sequence) + */ + + push r18 + push r19 + push r20 + push r21 + push r22 + push r23 + push r25 + + /* Save r28-r29 - Call-saved, "static" registers */ + + push r28 + push r29 + + /* Save r30-r31 - Call-used, "volatile" registers */ + + push r30 + push r31 + + /* Now save r26-r27 */ + + push r26 + push r27 + + /* Finally, save the stack pointer. BUT we want the value of the stack pointer as + * it was on entry into this macro. We'll have to subtract to get that value. + */ + + in r24, __SP_L__ + in r25, __SP_H__ + adiw r24, XCPTCONTEXT_REGS + + push r24 + push r25 + .endm + +/******************************************************************************************** + * Name: EXCPT_EPILOGUE + * + * Description: + * Provides the "epilogue" logic that should appear at the end of every exception handler. + * + * On input: + * sp points to the address of the register save area (just as left by EXCPT_PROLOGUE). + * All registers are available for use. + * Interrupts are disabled. + * + * On completion: + * All registers restored except the PC which remains on the stack so that a return + * via reti can be performed. + * + ********************************************************************************************/ + + .macro EXCPT_EPILOGUE, regs + + /* We don't need to restore the stack pointer */ + + pop r27 + pop r26 + + /* Restore r26-r27 */ + + pop r27 + pop r26 + + /* Restore r30-r31 - Call-used, "volatile" registers */ + + pop r31 + pop r30 + + /* Restore r28-r29 - Call-saved, "static" registers */ + + pop r29 + pop r28 + + /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 already + * restored, r24 will be restored later) + */ + + pop r25 + pop r23 + pop r22 + pop r21 + pop r20 + pop r19 + pop r18 + + /* Restore r2-r17 - Call-saved, "static" registers */ + + pop r17 + pop r16 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + + /* Restore r1 - the "zero" register (that may not be zero) */ + + pop r1 + + /* Restore the status register (probably enabling interrupts) */ + + pop r0 /* Restore the status register */ + out __SREG__, r0 + + /* Finally, restore r0 and r24 - the scratch and IRQ number registers */ + + pop r0 + pop r24 + .endm + +/******************************************************************************************** + * Name: USER_SAVE + * + * Description: + * Similar to EXPCT_PROLOGUE except that (1) this saves values into a register save + * data structure instead of on the stack, (2) the pointer is in r26;r27, and (3) + * Call-used registers are not saved. + * + * On Entry: + * X [r26:r27] - Points to the register save structure. + * Return address is already on the stack (due to CALL or RCALL instruction)/. + * Interrupts are disabled. + * + * At completion: + * Register state is saved on the stack; All registers are available for usage except sp. + * + ********************************************************************************************/ + + .macro USER_SAVE + + /* Save the current stack pointer. */ + + in r24, __SP_L__ + st x+, r24 + in r25, __SP_H__ + st x+, r24 + + /* Skip over r26-r27 and r30-r31 - Call-used, "volatile" registers */ + + adiw r26, 4 /* Four registers: r26-r27 and r30-r31*/ + + /* Save r28-r29 - Call-saved, "static" registers */ + + st x+, r29 + st x+, r28 + + /* Skip over r18-r27 - Call-used, "volatile" registers (r26-r27 have been skipped) */ + + adiw r26, 8 /* Eight registers: r18-r25 */ + + /* Save r2-r17 - Call-saved, "static" registers */ + + st x+, r17 + st x+, r16 + st x+, r15 + st x+, r14 + st x+, r13 + st x+, r12 + st x+, r11 + st x+, r10 + st x+, r9 + st x+, r8 + st x+, r7 + st x+, r6 + st x+, r5 + st x+, r4 + st x+, r3 + st x+, r2 + + /* Set r1 to zero - Function calls must return with r1=0 */ + + clr r1 + st x+, r1 + + /* Save the status register (probably not necessary since interrupts are disabled) */ + + in r0, __SREG__ + st x+, r0 + + /* Skip R0 and r24 - These are scratch register and Call-used, "volatile" registers */ + + adiw r26, 2 /* Two registers: r0, r24 */ + + /* Pop and save the return address */ + + pop r0 + st x+, r0 + pop r0 + st x+, r0 + .endm + +/******************************************************************************************** + * Name: TCB_RESTORE + * + * Description: + * Functionally equivalent to EXCPT_EPILOGUE excetp that register save area is not on the + * stack but is held in a data structure. + * + * On input: + * X [r26:r27] points to the data structure. + * All registers are available for use. + * Interrupts are disabled. + * + * On completion: + * All registers restored except for the PC with now resides at the top of the new stack + * so that iret can be used to switch to the new context. + * + ********************************************************************************************/ + + .macro TCB_RESTORE, regs + + /* Fetch the new stack pointer */ + + ld r24, x+ /* Fetch stack pointer (post-incrementing) */ + out __SP_L__, r24 + ld r25, x+ + out __SP_H__, r25 + + /* Fetch the return address and save it at the bottom of the new stack so + * that we can iret to switch contexts. + */ + + movw r28, r26 /* Get a pointer to the PCH/PCL storage location */ + adiw r28, REG_PCH + ld r25, y+ /* Load PCH and PCL */ + ld r24, y+ + push r24 /* Push PCH and PCL on the stack */ + push r25 + + /* Then get value of X [r26:r27]. Save X on the new stack where we can + * recover it later. + */ + + ld r25, x+ /* Fetch r26-r27 and save to the new stack */ + ld r24, x+ + push r24 + push r25 + + /* Restore r30-r31 - Call-used, "volatile" registers */ + + ld r31, x+ + ld r30, x+ + + /* Restore r28-r29 - Call-saved, "static" registers */ + + ld r29, x+ + ld r28, x+ + + /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 have been + * moved and r24 will be restore later) + */ + + ld r25, x+ + ld r23, x+ + ld r22, x+ + ld r21, x+ + ld r20, x+ + ld r19, x+ + ld r18, x+ + + /* Restore r2-r17 - Call-saved, "static" registers */ + + ld r17, x+ + ld r16, x+ + ld r15, x+ + ld r14, x+ + ld r13, x+ + ld r12, x+ + ld r11, x+ + ld r10, x+ + ld r9, x+ + ld r8, x+ + ld r7, x+ + ld r6, x+ + ld r5, x+ + ld r4, x+ + ld r3, x+ + ld r2, x+ + + /* Restore r1 - The "scratch" register */ + + ld r1, x+ + + /* Restore the status register (probably enabling interrupts) */ + + ld r0, x+ + out __SREG__, r0 + + /* Restore r0 and r241 - The scratch and IRQ number registers */ + + ld r0, x+ + ld r24, x+ + + /* Finally, recover X [r26-r27] from the the new stack. The PC remains on the new + * stack so that the user of this macro can return with iret. + */ + + pop r27 + pop r26 + .endm + +/******************************************************************************************** + * Name: USE_INTSTACK + * + * Description: + * Switch to the interrupt stack (if enabled in the configuration) and if the nesting level + * is equal to 0. Increment the nesting level in any event. + * + * On Entry: + * sp - Current value of the user stack pointer + * tmp1, tmp2, and tmp3 are registers that can be used temporarily. + * All interrupts should still be disabled. + * + * At completion: + * If the nesting level is 0, then (1) the user stack pointer is saved at the base of the + * interrupt stack and sp points to the interrupt stack. + * The values of tmp1, tmp2, tmp3, and sp have been altered + * + ********************************************************************************************/ + + .macro USE_INTSTACK, tmp1, tmp2, tmp3 +#if CONFIG_ARCH_INTERRUPTSTACK > 0 +# warning "Not implemented" +#endif + .endm + +/******************************************************************************************** + * Name: RESTORE_STACK + * + * Description: + * Restore the user stack. Not really.. actually only decrements the nesting level. We + * always get the new stack pointer for the register save array. + * + * On Entry: + * tmp1 and tmp2 are registers that can be used temporarily. + * All interrupts must be disabled. + * + * At completion: + * Current nesting level is decremented + * The values of tmp1 and tmp2 have been altered + * + ********************************************************************************************/ + + .macro RESTORE_STACK, tmp1, tmp2 +#if CONFIG_ARCH_INTERRUPTSTACK > 0 +# warning "Not implemented" +#endif + .endm + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_AVR_SRC_AVR_EXCPTMACROS_H */ diff --git a/arch/avr/src/avr32/up_exceptions.S b/arch/avr/src/avr32/up_exceptions.S index e104a23701..448a93d767 100755 --- a/arch/avr/src/avr32/up_exceptions.S +++ b/arch/avr/src/avr32/up_exceptions.S @@ -1,373 +1,373 @@ -/**************************************************************************** - * arch/avr/src/avr32/up_exceptions.S - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -/**************************************************************************** - * External Symbols - ****************************************************************************/ - - .global avr32_int0irqno /* Returns IRQ number of INT0 event */ - .global avr32_int1irqno /* Returns IRQ number of INT1 event */ - .global avr32_int2irqno /* Returns IRQ number of INT2 event */ - .global avr32_int3irqno /* Returns IRQ number of INT3 event */ - .global up_doirq /* Dispatch an IRQ */ - .global up_fullcontextrestore /* Restore new task contex */ - -/**************************************************************************** - * Macros - ****************************************************************************/ - -/* Exception entry logic. On entry, thee context save area looks like: */ -/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ -/* ^ ^+2*4 */ -/* Upon joining common logic, the context save are will look like: */ -/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10 SR PC */ -/* ^ ^+3*4 */ -/* and r10 will hold the exception's IRQ number */ - - .macro HANDLER, label, irqno -\label: - st.w --sp, r10 - mov r10, \irqno - rjmp avr32_xcptcommon /* FIXME!!! Need IRQ in a register */ - .endm - -/**************************************************************************** - * Exception Vector Table - ****************************************************************************/ - -/* The Exception Vector Base Address (EVBA) register will contain "a */ -/* pointer to the exception routines. All exception routines start at this */ -/* address, or at a defined offset relative to the address. Special */ -/* alignment requirements may apply for EVBA, depending on the */ -/* implementation of the interrupt controller." */ - -/* REVISIT: This alignment requirement may be different on other AVR32s */ - - .text - .balign 0x200 - - .global vectortab - .type vectortab, @function -vectortab: - lda.w pc, avr32_unrec /* EVBA+0x00 Unrecoverable exception */ - lda.w pc, avr32_tlbmult /* EVBA+0x04 TLB multiple hit */ - lda.w pc, avr32_busdata /* EVBA+0x08 Bus error data fetch */ - lda.w pc, avr32_businst /* EVBA+0x0c Bus error instr fetch */ - lda.w pc, avr32_nmi /* EVBA+0x10 NMI */ - lda.w pc, avr32_instaddr /* EVBA+0x14 Instruction Address */ - lda.w pc, avr32_itlbrot /* EVBA+0x18 ITLB Protection */ - lda.w pc, avr32_bp /* EVBA+0x1c Breakpoint */ - lda.w pc, avr32_invinst /* EVBA+0x20 Illegal Opcode */ - lda.w pc, avr32_unimpinst /* EVBA+0x24 Unimplemented instruction */ - lda.w pc, avr32_priv /* EVBA+0x28 Privilege violation */ - lda.w pc, avr32_fp /* EVBA+0x2c Floating-point */ - lda.w pc, avr32_cop /* EVBA+0x30 Coprocessor absent */ - lda.w pc, avr32_rddata /* EVBA+0x34 Data Address (Read) */ - lda.w pc, avr32_wrdata /* EVBA+0x38 Data Address (Write) */ - lda.w pc, avr32_tddtlbprot /* EVBA+0x3c DTLB Protection (Read) */ - lda.w pc, avr32_wrdtlbprot /* EVBA+0x40 DTLB Protection (Write) */ - lda.w pc, avr32_dltbmod /* EVBA+0x44 DTLB Modified */ - .rept 2 - lda.w pc, avr32_badvector /* EVBA+0x48-0x4c No such vector */ - .endr - lda.w pc, avr32_itlbmiss /* EVBA+0x50 ITLB Miss */ - .rept 3 - lda.w pc, avr32_badvector /* EVBA+0x54-0x5c No such vector */ - .endr - lda.w pc, avr32_rddtlb /* EVBA+0x60 DTLB Miss (Read) */ - .rept 3 - lda.w pc, avr32_badvector /* EVBA+0x64-0x6c No such vector */ - .endr - lda.w pc, avr32_wrdtlb /* EVBA+0x70 DTLB Miss (Write) */ - .rept (3+4*8) - lda.w pc, avr32_badvector /* EVBA+0x74-0xfc No such vector */ - .endr - lda.w pc, avr32_super /* EVBA+0x100 Supervisor call */ - -/**************************************************************************** - * Interrupts - ****************************************************************************/ - -/* The interrupt controller must provide an address that is relative to the */ -/* the EVBA so it is natural to define these interrupt vectors just after */ -/* the exception table. On entry to each interrupt handler, R8-R12, LR, PC */ -/* and SR have already been pushed onto the system stack by the MCU. */ -/* */ -/* An interrupt may disappear while it is being fetched by the CPU and, */ -/* hence spurious interrupt may result. */ - - .balign 4 - .global avr32_int0 -avr32_int0: - mov r12, 0 /* r12=interrupt level 0 */ - rjmp avr32_intcommon /* Jump to common interrupt handling logic */ - - .balign 4 - .global avr32_int1 -avr32_int1: - mov r12, 1 /* r12=interrupt level 1 */ - rjmp avr32_intcommon /* Jump to common interrupt handling logic */ - - .balign 4 - .global avr32_int2 -avr32_int2: - mov r12, 2 /* r12=interrupt level 2 */ - rjmp avr32_intcommon /* Jump to common interrupt handling logic */ - - .balign 4 - .global avr32_int3 -avr32_int3: - mov r12, 3 /* r12=interrupt level 3 */ - -/* Common interrupt handling logic. R12 holds the interrupt level index */ - -avr32_intcommon: - mcall .Lavr32_intirqno /* Get the IRQ number of the int0 event */ - cp.w r12, 0 /* Negative returned if spurious interrupt */ - brge avr32_common /* Jump to the common xcptn handling logic */ - rete /* Ignore spurious interrupt */ - -.Lavr32_intirqno: - .word avr32_intirqno - -/**************************************************************************** - * Exception Vector Handlers - ****************************************************************************/ - -/* Exception Handlers: */ -/* On entry to each, the context save area looks like this: */ -/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ -/* ^ ^+2*4 */ - - HANDLER avr32_unrec, AVR32_IRQ_UNREC /* Unrecoverable xcptn */ - HANDLER avr32_tlbmult, AVR32_IRQ_TLBMULT /* TLB multiple hit */ - HANDLER avr32_busdata, AVR32_IRQ_BUSDATA /* Bus error data fetch */ - HANDLER avr32_businst, AVR32_IRQ_BUSINST /* Bus err instr fetch */ - HANDLER avr32_nmi, AVR32_IRQ_NMI /* NMI */ - HANDLER avr32_instaddr, AVR32_IRQ_INSTADDR /* Instruction Address */ - HANDLER avr32_itlbrot, AVR32_IRQ_ITLBPROT /* ITLB Protection */ - HANDLER avr32_bp, AVR32_IRQ_BP /* Breakpoint */ - HANDLER avr32_invinst, AVR32_IRQ_INVINST /* Illegal Opcode */ - HANDLER avr32_unimpinst, AVR32_IRQ_UNIMPINST /* Unimplemented intsr */ - HANDLER avr32_priv, AVR32_IRQ_PRIV /* Privilege violation */ - HANDLER avr32_fp, AVR32_IRQ_FP /* Floating-point */ - HANDLER avr32_cop, AVR32_IRQ_COP /* Coprocessor absent */ - HANDLER avr32_rddata, AVR32_IRQ_RDDATA /* Data Address (RD) */ - HANDLER avr32_wrdata, AVR32_IRQ_WRDATA /* Data Address (WR) */ - HANDLER avr32_tddtlbprot, AVR32_IRQ_RDDTLBPROT /* DTLB Protection (RD) */ - HANDLER avr32_wrdtlbprot, AVR32_IRQ_WRDTLBPROT /* DTLB Protection (WR) */ - HANDLER avr32_dltbmod, AVR32_IRQ_DLTBMOD /* DTLB Modified */ - HANDLER avr32_itlbmiss, AVR32_IRQ_ITLBMISS /* ITLB Miss */ - HANDLER avr32_rddtlb, AVR32_IRQ_RDDTLB /* DTLB Miss (RD) */ - HANDLER avr32_wrdtlb, AVR32_IRQ_WRDTLB /* DTLB Miss (WR) */ - HANDLER avr32_super, AVR32_IRQ_SUPER /* Supervisor call */ - HANDLER avr32_badvector, AVR32_IRQ_BADVECTOR /* No such vector */ - -/* Common exception handling logic. Unlike the interrupt handlers, the */ -/* exception handlers do not save R8-R12, and LR on the stack. Only the PC */ -/* and SR have been pushed onto the system stack by the MCU. The following */ -/* logic creates a common stack frame for exception handlers prior to */ -/* joining to the common interrupt/exception logic below. */ -/* */ -/* The context save area looks like this on entry to the HANDLER above. */ -/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ -/* ^ ^+2*4 */ -/* Upon joining common logic here, the context save are will loke: */ -/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10 SR PC */ -/* ^ ^+3*4 */ -/* and r10 will hold the exception's IRQ number */ -/* */ -/* either (1) non-time-critical, or (2) fatal. Obvious, that would not be */ -/* the case if TLB missing handling is required. Such time-critical vector */ -/* handling should be handled differently. */ - -avr32_xcptcommon: -/* Save r10-r12, lr on the stack: */ -/* xx xx xx xx xx xx xx xx xx xx xx LR 12 11 10 SR PC */ -/* ^ ^+4*4 ^+6*4 */ - - stm --sp, r11-r12, lr - -/* Move SR and PC into the expected position: */ -/* xx xx xx xx xx xx xx xx xx SR PC LI 12 11 10 SR PC */ -/* ^ ^+8*4 */ - - ld.w r12, sp[4*4] - ld.w r11, sp[5*4] - stm --sp, r11-r12 - -/* Save r8 and r8: */ -/* xx xx xx xx xx xx xx xx xx SR PC LI 12 11 10 SR PC */ -/* ^ ^+6*4 ^+8*4 */ - - st.w sp[6*4], r9 - st.w sp[7*4], r8 - -/* Move the IRQ number in r12 and fall through to the common event handling */ -/* logic. */ - - mov r12, r10 - -/**************************************************************************** - * Common Event Handling Logic - ****************************************************************************/ - -/* After this point, logic to manage interrupts and exceptions is */ -/* equivalent. Here we have: */ -/* */ -/* R8-R12, LR, SR, and the PC on the stack. */ -/* R12 holds the IRQ number to be dispatched. */ -/* */ -/* The context save area looks like this: */ -/* xx xx xx xx xx xx xx xx xx SR PC LR 12 11 10 09 08 */ -/* ^ ^+8*4 */ -/* This function will finish construction of the register save structure */ -/* and call the IRQ dispatching logic. */ - -avr32_common: - /* Disable interrupts in the current SR. This is necessary because the */ - /* AVR32 permits nested interrupts (if they are of higher priority). */ - /* We can support nested interrupts without some effort because: */ - /* - The global variable current_regs permits only one interrupt, */ - /* - If CONFIG_ARCH_INTERRUPTSTACK is defined, then there is a single */ - /* interrupt stack, and */ - /* - Probably other things. */ - - ssrf AVR32_SR_GM_SHIFT - - /* Save the SP (as it was before the interrupt) in the conext save */ - /* structure. */ - /* xx xx xx xx xx xx xx xx SP SR PC LR 12 11 10 09 08 */ - /* ^sp */ - - mov r8, sp - sub r8, -8*4 - st.w --sp, r8 - - /* Saving R0-R7 is all that is left to complete the context save. */ - /* 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ - /* ^sp */ - - stm --sp, r0-r7 - - /* Now call up_doirq passing the IRQ number in r12 and the base address */ - /* of the register context save area in r11. */ - - mov r11, sp - - /* Switch to the interrrupt stack if so configured. Move the current */ - /* stack pointer into a preserved register (r7) and set the interrupt */ - /* stack pointer. */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - mov r7, sp - lddpc sp, .Linstackbaseptr -#endif - - /* Call up_doirq with r12=IRQ number and r11=register save area */ - - mcall .Ldoirqptr - - /* Restore the user stack pointer. */ - /* 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ - /* ^sp */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - mov sp, r7 -#endif - - /* On return, r12 will hold the new address of the register context */ - /* save area. On an interrupt contex switch, this will (1) not be the */ - /* same as the value of r12 passed to up_doirq(), and (2) may not */ - /* reside on a stack. */ - - cp.w sp, r12 - brne 1f - - /* No context switch... do the simple return. First, restore r0-r7. */ - /* xx xx xx xx xx xx xx xx SP SR PC LR 12 11 10 09 08 */ - /* ^sp */ - - ldm sp++, r0-r7 - - /* Skip over the saved stack pointer and return from the interrupt. */ - /* xx xx xx xx xx xx xx xx xx SR PC LR 12 11 10 09 08 */ - /* ^sp */ - - sub sp, -4 - rete - - /* Context switch... jump to up_fullcontestrestor with r12=address of */ - /* the task context to restore. */ - -1: - lddpc pc, .Lfullcontextrestoreptr - -.Ldoirqptr: - .word up_doirq -.Lfullcontextrestoreptr: - .word up_fullcontextrestore - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 -.Linstackbaseptr: - .word .Lintstackbase -#endif - .size vectortab, .-vectortab - -/************************************************************************************ - * Name: up_interruptstack - ************************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - .bss - .align 4 - .globl up_interruptstack - .type up_interruptstack, object -up_interruptstack: - .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3) -.Lintstackbase: - .size up_interruptstack, .-up_interruptstack -#endif - .end - +/**************************************************************************** + * arch/avr/src/avr32/up_exceptions.S + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .global avr32_int0irqno /* Returns IRQ number of INT0 event */ + .global avr32_int1irqno /* Returns IRQ number of INT1 event */ + .global avr32_int2irqno /* Returns IRQ number of INT2 event */ + .global avr32_int3irqno /* Returns IRQ number of INT3 event */ + .global up_doirq /* Dispatch an IRQ */ + .global up_fullcontextrestore /* Restore new task contex */ + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Exception entry logic. On entry, thee context save area looks like: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ +/* ^ ^+2*4 */ +/* Upon joining common logic, the context save are will look like: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10 SR PC */ +/* ^ ^+3*4 */ +/* and r10 will hold the exception's IRQ number */ + + .macro HANDLER, label, irqno +\label: + st.w --sp, r10 + mov r10, \irqno + rjmp avr32_xcptcommon /* FIXME!!! Need IRQ in a register */ + .endm + +/**************************************************************************** + * Exception Vector Table + ****************************************************************************/ + +/* The Exception Vector Base Address (EVBA) register will contain "a */ +/* pointer to the exception routines. All exception routines start at this */ +/* address, or at a defined offset relative to the address. Special */ +/* alignment requirements may apply for EVBA, depending on the */ +/* implementation of the interrupt controller." */ + +/* REVISIT: This alignment requirement may be different on other AVR32s */ + + .text + .balign 0x200 + + .global vectortab + .type vectortab, @function +vectortab: + lda.w pc, avr32_unrec /* EVBA+0x00 Unrecoverable exception */ + lda.w pc, avr32_tlbmult /* EVBA+0x04 TLB multiple hit */ + lda.w pc, avr32_busdata /* EVBA+0x08 Bus error data fetch */ + lda.w pc, avr32_businst /* EVBA+0x0c Bus error instr fetch */ + lda.w pc, avr32_nmi /* EVBA+0x10 NMI */ + lda.w pc, avr32_instaddr /* EVBA+0x14 Instruction Address */ + lda.w pc, avr32_itlbrot /* EVBA+0x18 ITLB Protection */ + lda.w pc, avr32_bp /* EVBA+0x1c Breakpoint */ + lda.w pc, avr32_invinst /* EVBA+0x20 Illegal Opcode */ + lda.w pc, avr32_unimpinst /* EVBA+0x24 Unimplemented instruction */ + lda.w pc, avr32_priv /* EVBA+0x28 Privilege violation */ + lda.w pc, avr32_fp /* EVBA+0x2c Floating-point */ + lda.w pc, avr32_cop /* EVBA+0x30 Coprocessor absent */ + lda.w pc, avr32_rddata /* EVBA+0x34 Data Address (Read) */ + lda.w pc, avr32_wrdata /* EVBA+0x38 Data Address (Write) */ + lda.w pc, avr32_tddtlbprot /* EVBA+0x3c DTLB Protection (Read) */ + lda.w pc, avr32_wrdtlbprot /* EVBA+0x40 DTLB Protection (Write) */ + lda.w pc, avr32_dltbmod /* EVBA+0x44 DTLB Modified */ + .rept 2 + lda.w pc, avr32_badvector /* EVBA+0x48-0x4c No such vector */ + .endr + lda.w pc, avr32_itlbmiss /* EVBA+0x50 ITLB Miss */ + .rept 3 + lda.w pc, avr32_badvector /* EVBA+0x54-0x5c No such vector */ + .endr + lda.w pc, avr32_rddtlb /* EVBA+0x60 DTLB Miss (Read) */ + .rept 3 + lda.w pc, avr32_badvector /* EVBA+0x64-0x6c No such vector */ + .endr + lda.w pc, avr32_wrdtlb /* EVBA+0x70 DTLB Miss (Write) */ + .rept (3+4*8) + lda.w pc, avr32_badvector /* EVBA+0x74-0xfc No such vector */ + .endr + lda.w pc, avr32_super /* EVBA+0x100 Supervisor call */ + +/**************************************************************************** + * Interrupts + ****************************************************************************/ + +/* The interrupt controller must provide an address that is relative to the */ +/* the EVBA so it is natural to define these interrupt vectors just after */ +/* the exception table. On entry to each interrupt handler, R8-R12, LR, PC */ +/* and SR have already been pushed onto the system stack by the MCU. */ +/* */ +/* An interrupt may disappear while it is being fetched by the CPU and, */ +/* hence spurious interrupt may result. */ + + .balign 4 + .global avr32_int0 +avr32_int0: + mov r12, 0 /* r12=interrupt level 0 */ + rjmp avr32_intcommon /* Jump to common interrupt handling logic */ + + .balign 4 + .global avr32_int1 +avr32_int1: + mov r12, 1 /* r12=interrupt level 1 */ + rjmp avr32_intcommon /* Jump to common interrupt handling logic */ + + .balign 4 + .global avr32_int2 +avr32_int2: + mov r12, 2 /* r12=interrupt level 2 */ + rjmp avr32_intcommon /* Jump to common interrupt handling logic */ + + .balign 4 + .global avr32_int3 +avr32_int3: + mov r12, 3 /* r12=interrupt level 3 */ + +/* Common interrupt handling logic. R12 holds the interrupt level index */ + +avr32_intcommon: + mcall .Lavr32_intirqno /* Get the IRQ number of the int0 event */ + cp.w r12, 0 /* Negative returned if spurious interrupt */ + brge avr32_common /* Jump to the common xcptn handling logic */ + rete /* Ignore spurious interrupt */ + +.Lavr32_intirqno: + .word avr32_intirqno + +/**************************************************************************** + * Exception Vector Handlers + ****************************************************************************/ + +/* Exception Handlers: */ +/* On entry to each, the context save area looks like this: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ +/* ^ ^+2*4 */ + + HANDLER avr32_unrec, AVR32_IRQ_UNREC /* Unrecoverable xcptn */ + HANDLER avr32_tlbmult, AVR32_IRQ_TLBMULT /* TLB multiple hit */ + HANDLER avr32_busdata, AVR32_IRQ_BUSDATA /* Bus error data fetch */ + HANDLER avr32_businst, AVR32_IRQ_BUSINST /* Bus err instr fetch */ + HANDLER avr32_nmi, AVR32_IRQ_NMI /* NMI */ + HANDLER avr32_instaddr, AVR32_IRQ_INSTADDR /* Instruction Address */ + HANDLER avr32_itlbrot, AVR32_IRQ_ITLBPROT /* ITLB Protection */ + HANDLER avr32_bp, AVR32_IRQ_BP /* Breakpoint */ + HANDLER avr32_invinst, AVR32_IRQ_INVINST /* Illegal Opcode */ + HANDLER avr32_unimpinst, AVR32_IRQ_UNIMPINST /* Unimplemented intsr */ + HANDLER avr32_priv, AVR32_IRQ_PRIV /* Privilege violation */ + HANDLER avr32_fp, AVR32_IRQ_FP /* Floating-point */ + HANDLER avr32_cop, AVR32_IRQ_COP /* Coprocessor absent */ + HANDLER avr32_rddata, AVR32_IRQ_RDDATA /* Data Address (RD) */ + HANDLER avr32_wrdata, AVR32_IRQ_WRDATA /* Data Address (WR) */ + HANDLER avr32_tddtlbprot, AVR32_IRQ_RDDTLBPROT /* DTLB Protection (RD) */ + HANDLER avr32_wrdtlbprot, AVR32_IRQ_WRDTLBPROT /* DTLB Protection (WR) */ + HANDLER avr32_dltbmod, AVR32_IRQ_DLTBMOD /* DTLB Modified */ + HANDLER avr32_itlbmiss, AVR32_IRQ_ITLBMISS /* ITLB Miss */ + HANDLER avr32_rddtlb, AVR32_IRQ_RDDTLB /* DTLB Miss (RD) */ + HANDLER avr32_wrdtlb, AVR32_IRQ_WRDTLB /* DTLB Miss (WR) */ + HANDLER avr32_super, AVR32_IRQ_SUPER /* Supervisor call */ + HANDLER avr32_badvector, AVR32_IRQ_BADVECTOR /* No such vector */ + +/* Common exception handling logic. Unlike the interrupt handlers, the */ +/* exception handlers do not save R8-R12, and LR on the stack. Only the PC */ +/* and SR have been pushed onto the system stack by the MCU. The following */ +/* logic creates a common stack frame for exception handlers prior to */ +/* joining to the common interrupt/exception logic below. */ +/* */ +/* The context save area looks like this on entry to the HANDLER above. */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SR PC */ +/* ^ ^+2*4 */ +/* Upon joining common logic here, the context save are will loke: */ +/* xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10 SR PC */ +/* ^ ^+3*4 */ +/* and r10 will hold the exception's IRQ number */ +/* */ +/* either (1) non-time-critical, or (2) fatal. Obvious, that would not be */ +/* the case if TLB missing handling is required. Such time-critical vector */ +/* handling should be handled differently. */ + +avr32_xcptcommon: +/* Save r10-r12, lr on the stack: */ +/* xx xx xx xx xx xx xx xx xx xx xx LR 12 11 10 SR PC */ +/* ^ ^+4*4 ^+6*4 */ + + stm --sp, r11-r12, lr + +/* Move SR and PC into the expected position: */ +/* xx xx xx xx xx xx xx xx xx SR PC LI 12 11 10 SR PC */ +/* ^ ^+8*4 */ + + ld.w r12, sp[4*4] + ld.w r11, sp[5*4] + stm --sp, r11-r12 + +/* Save r8 and r8: */ +/* xx xx xx xx xx xx xx xx xx SR PC LI 12 11 10 SR PC */ +/* ^ ^+6*4 ^+8*4 */ + + st.w sp[6*4], r9 + st.w sp[7*4], r8 + +/* Move the IRQ number in r12 and fall through to the common event handling */ +/* logic. */ + + mov r12, r10 + +/**************************************************************************** + * Common Event Handling Logic + ****************************************************************************/ + +/* After this point, logic to manage interrupts and exceptions is */ +/* equivalent. Here we have: */ +/* */ +/* R8-R12, LR, SR, and the PC on the stack. */ +/* R12 holds the IRQ number to be dispatched. */ +/* */ +/* The context save area looks like this: */ +/* xx xx xx xx xx xx xx xx xx SR PC LR 12 11 10 09 08 */ +/* ^ ^+8*4 */ +/* This function will finish construction of the register save structure */ +/* and call the IRQ dispatching logic. */ + +avr32_common: + /* Disable interrupts in the current SR. This is necessary because the */ + /* AVR32 permits nested interrupts (if they are of higher priority). */ + /* We can support nested interrupts without some effort because: */ + /* - The global variable current_regs permits only one interrupt, */ + /* - If CONFIG_ARCH_INTERRUPTSTACK is defined, then there is a single */ + /* interrupt stack, and */ + /* - Probably other things. */ + + ssrf AVR32_SR_GM_SHIFT + + /* Save the SP (as it was before the interrupt) in the conext save */ + /* structure. */ + /* xx xx xx xx xx xx xx xx SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + mov r8, sp + sub r8, -8*4 + st.w --sp, r8 + + /* Saving R0-R7 is all that is left to complete the context save. */ + /* 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + stm --sp, r0-r7 + + /* Now call up_doirq passing the IRQ number in r12 and the base address */ + /* of the register context save area in r11. */ + + mov r11, sp + + /* Switch to the interrrupt stack if so configured. Move the current */ + /* stack pointer into a preserved register (r7) and set the interrupt */ + /* stack pointer. */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + mov r7, sp + lddpc sp, .Linstackbaseptr +#endif + + /* Call up_doirq with r12=IRQ number and r11=register save area */ + + mcall .Ldoirqptr + + /* Restore the user stack pointer. */ + /* 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + mov sp, r7 +#endif + + /* On return, r12 will hold the new address of the register context */ + /* save area. On an interrupt contex switch, this will (1) not be the */ + /* same as the value of r12 passed to up_doirq(), and (2) may not */ + /* reside on a stack. */ + + cp.w sp, r12 + brne 1f + + /* No context switch... do the simple return. First, restore r0-r7. */ + /* xx xx xx xx xx xx xx xx SP SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + ldm sp++, r0-r7 + + /* Skip over the saved stack pointer and return from the interrupt. */ + /* xx xx xx xx xx xx xx xx xx SR PC LR 12 11 10 09 08 */ + /* ^sp */ + + sub sp, -4 + rete + + /* Context switch... jump to up_fullcontestrestor with r12=address of */ + /* the task context to restore. */ + +1: + lddpc pc, .Lfullcontextrestoreptr + +.Ldoirqptr: + .word up_doirq +.Lfullcontextrestoreptr: + .word up_fullcontextrestore + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +.Linstackbaseptr: + .word .Lintstackbase +#endif + .size vectortab, .-vectortab + +/************************************************************************************ + * Name: up_interruptstack + ************************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + .bss + .align 4 + .globl up_interruptstack + .type up_interruptstack, object +up_interruptstack: + .skip (CONFIG_ARCH_INTERRUPTSTACK & ~3) +.Lintstackbase: + .size up_interruptstack, .-up_interruptstack +#endif + .end + diff --git a/arch/avr/src/avr32/up_fullcontextrestore.S b/arch/avr/src/avr32/up_fullcontextrestore.S index 3d99721801..466303abb2 100755 --- a/arch/avr/src/avr32/up_fullcontextrestore.S +++ b/arch/avr/src/avr32/up_fullcontextrestore.S @@ -1,158 +1,158 @@ -/**************************************************************************** - * arch/avr32/src/avr32/up_fullcontextrestore.S - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -/**************************************************************************** - * External Symbols - ****************************************************************************/ - - .file "up_fullcontextrestore.S" - -/**************************************************************************** - * Macros - ****************************************************************************/ - -/**************************************************************************** - * Name: up_fullcontextrestore - * - * Descripion: - * Restore the full-running contex of a thread. - * - * NOTE: Thus function must handle one very strange case. That is when - * this function is called with up_sigdeliver(). That case is strange in - * two ways: - * - * 1. It is not a context switch between threads. Rather, up_fullcontextrestore - * must behave more it more like a longjmp within the same task, using the - * same stack. - * 2. In this case, this function is called with r12 pointing to a register - * save area on the stack to be destroyed. This is dangerous for two - * reasons: (a) there is a period of time where the stack contents still - * contain valid data, but are outside of range protected by the stack - * pointer (hence, interrupts must be disabled), and (b) there is the - * very real possibility that the new stack pointer might overlap with - * the register save area and stack usage in this function might corrupt - * the register save data before the state is restored. It turns that - * an extra 3 words in the register save structure size will protect its - * contents (because that is the number of temporaries pushed onto the - * stack). - * - * Input Parameters: - * r12 = A pointer to the register save area of the thread to be restored. - * - * C Prototype: - * void up_fullcontextrestore(uint32_t *regs); - * - * Assumptions: - * Interrupts are disabled. - * - ****************************************************************************/ - - .text - .global up_fullcontextrestore - .type up_fullcontextrestore, @function -up_fullcontextrestore: - - /* Initially, r12 points to the r7 save area. Restore r0-r7. */ - /* regs: 07 06 05 04 03 02 01 00 xx xx xx xx xx xx xx xx xx */ - /* ^r12 */ - - ldm r12++, r0-r7 - - /* Now, r12 points to the SP (r13) save area. Recover the value of */ - /* the stack pointer (r13). We will need to save some temporaries on */ - /* the final stack. */ - /* regs: 07 06 05 04 03 02 01 00 SP xx xx xx xx xx xx xx xx */ - /* ^r12 */ - - ld.w sp, r12++ - - /* Now r12 points to the SR save area. Skip over the SR for now. */ - /* regs: 07 06 05 04 03 02 01 00 SP xx xx xx xx xx xx xx xx */ - /* ^r12 */ - - sub r12, -1*4 - - /* Get the pc, lr, and r12 (in r10, r9, and r8) and move them to the */ - /* stack. We can now use r12 and lr as scratch registers. */ - /* regs: 07 06 05 04 03 02 01 00 SP xx PC LR 12 xx xx xx xx */ - /* ^r12 */ - /* stack: lr, r12, pc */ - /* ^sp */ - - ldm r12++, r8-r10 /* Get r10=pc, r9=lr, r8=r12 */ - -#if 0 /* See comments below */ - stm --sp, r8-r10 /* Save r12, lr, and pc from the stack */ -#else - st.w --sp, r10 /* Save R10=PC on the stack */ - st.w --sp, r8 /* Save R8=r12 on the stack */ - st.w --sp, r9 /* Save R9=lr on the stack */ -#endif - - /* Now r12 now points to the r11 save area. Restore r8-r11. */ - /* regs: 07 06 05 04 03 02 01 00 SP xx PC LR 12 11 10 09 08 */ - /* ^r12 */ - - ldm r12++, r8-r11 - - /* r12 now points +4 beyond the end of the register save area. Restore */ - /* SR. NOTE: This may enable interrupts! */ - /* regs: 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ - /* ^r12-4*8 ^r12 */ - - ld.w lr, r12[-4*8] - mtsr AVR32_SR, lr - - /* Restore PC, LR and r12. Hmmm.. I need to study the behaviour of ldm */ - /* when r12,lr, and pc on in ldm reglist16. I'm not sure that I want */ - /* that behavior. */ - /* stack: lr, r12, pc */ - /* ^sp */ - -#if 0 - ldm sp++, r12, lr, pc /* Restore r12, lr, and pc from the stack */ -#else - ld.w lr, sp++ /* Recover lr from the stack */ - ld.w r12, sp++ /* Recover r12 from the stack */ - ld.w pc, sp++ /* Jump to the address on the stack */ -#endif - .end +/**************************************************************************** + * arch/avr32/src/avr32/up_fullcontextrestore.S + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * External Symbols + ****************************************************************************/ + + .file "up_fullcontextrestore.S" + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fullcontextrestore + * + * Descripion: + * Restore the full-running contex of a thread. + * + * NOTE: Thus function must handle one very strange case. That is when + * this function is called with up_sigdeliver(). That case is strange in + * two ways: + * + * 1. It is not a context switch between threads. Rather, up_fullcontextrestore + * must behave more it more like a longjmp within the same task, using the + * same stack. + * 2. In this case, this function is called with r12 pointing to a register + * save area on the stack to be destroyed. This is dangerous for two + * reasons: (a) there is a period of time where the stack contents still + * contain valid data, but are outside of range protected by the stack + * pointer (hence, interrupts must be disabled), and (b) there is the + * very real possibility that the new stack pointer might overlap with + * the register save area and stack usage in this function might corrupt + * the register save data before the state is restored. It turns that + * an extra 3 words in the register save structure size will protect its + * contents (because that is the number of temporaries pushed onto the + * stack). + * + * Input Parameters: + * r12 = A pointer to the register save area of the thread to be restored. + * + * C Prototype: + * void up_fullcontextrestore(uint32_t *regs); + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + + .text + .global up_fullcontextrestore + .type up_fullcontextrestore, @function +up_fullcontextrestore: + + /* Initially, r12 points to the r7 save area. Restore r0-r7. */ + /* regs: 07 06 05 04 03 02 01 00 xx xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + ldm r12++, r0-r7 + + /* Now, r12 points to the SP (r13) save area. Recover the value of */ + /* the stack pointer (r13). We will need to save some temporaries on */ + /* the final stack. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + ld.w sp, r12++ + + /* Now r12 points to the SR save area. Skip over the SR for now. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx xx xx xx xx xx xx xx */ + /* ^r12 */ + + sub r12, -1*4 + + /* Get the pc, lr, and r12 (in r10, r9, and r8) and move them to the */ + /* stack. We can now use r12 and lr as scratch registers. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx PC LR 12 xx xx xx xx */ + /* ^r12 */ + /* stack: lr, r12, pc */ + /* ^sp */ + + ldm r12++, r8-r10 /* Get r10=pc, r9=lr, r8=r12 */ + +#if 0 /* See comments below */ + stm --sp, r8-r10 /* Save r12, lr, and pc from the stack */ +#else + st.w --sp, r10 /* Save R10=PC on the stack */ + st.w --sp, r8 /* Save R8=r12 on the stack */ + st.w --sp, r9 /* Save R9=lr on the stack */ +#endif + + /* Now r12 now points to the r11 save area. Restore r8-r11. */ + /* regs: 07 06 05 04 03 02 01 00 SP xx PC LR 12 11 10 09 08 */ + /* ^r12 */ + + ldm r12++, r8-r11 + + /* r12 now points +4 beyond the end of the register save area. Restore */ + /* SR. NOTE: This may enable interrupts! */ + /* regs: 07 06 05 04 03 02 01 00 SP SR PC LR 12 11 10 09 08 */ + /* ^r12-4*8 ^r12 */ + + ld.w lr, r12[-4*8] + mtsr AVR32_SR, lr + + /* Restore PC, LR and r12. Hmmm.. I need to study the behaviour of ldm */ + /* when r12,lr, and pc on in ldm reglist16. I'm not sure that I want */ + /* that behavior. */ + /* stack: lr, r12, pc */ + /* ^sp */ + +#if 0 + ldm sp++, r12, lr, pc /* Restore r12, lr, and pc from the stack */ +#else + ld.w lr, sp++ /* Recover lr from the stack */ + ld.w r12, sp++ /* Recover r12 from the stack */ + ld.w pc, sp++ /* Jump to the address on the stack */ +#endif + .end diff --git a/arch/avr/src/avr32/up_syscall6.S b/arch/avr/src/avr32/up_syscall6.S index 26b91c6a4a..143980e62c 100755 --- a/arch/avr/src/avr32/up_syscall6.S +++ b/arch/avr/src/avr32/up_syscall6.S @@ -1,84 +1,84 @@ -/**************************************************************************** - * arch/avr/src/avr32/up_syscall6.S - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Based on Bran's kernel development tutorials. Rewritten for JamesM's - * kernel development tutorials. - * - * 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. - * 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. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS 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. - * - ****************************************************************************/ - - .file "up_syscall6.S" - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Globals - ****************************************************************************/ - -/**************************************************************************** - * .text - ****************************************************************************/ - - .text - -/**************************************************************************** - * Name: sys_call6 - * - * C Prototype: - * uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, - * uintptr_t parm2, uintptr_t parm3, - * uintptr_t parm4, uintptr_t parm5, - * uintptr_t parm6); - * - ****************************************************************************/ - - .global sys_call6 - .type sys_call6, @function - .align 2 - -sys_call6: - stm --sp, r3, r5, r6, lr - sub lr, sp, -16 - mov r8, r12 - ldm lr, r3, r5, r9-r12 - scall - ldm sp++, r3, r5, r6, pc - - .size sys_call6, . - sys_call6 +/**************************************************************************** + * arch/avr/src/avr32/up_syscall6.S + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on Bran's kernel development tutorials. Rewritten for JamesM's + * kernel development tutorials. + * + * 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. + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + + .file "up_syscall6.S" + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Globals + ****************************************************************************/ + +/**************************************************************************** + * .text + ****************************************************************************/ + + .text + +/**************************************************************************** + * Name: sys_call6 + * + * C Prototype: + * uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, + * uintptr_t parm2, uintptr_t parm3, + * uintptr_t parm4, uintptr_t parm5, + * uintptr_t parm6); + * + ****************************************************************************/ + + .global sys_call6 + .type sys_call6, @function + .align 2 + +sys_call6: + stm --sp, r3, r5, r6, lr + sub lr, sp, -16 + mov r8, r12 + ldm lr, r3, r5, r9-r12 + scall + ldm sp++, r3, r5, r6, pc + + .size sys_call6, . - sys_call6