Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <avr32/io.h>
- #include "boot.h"
- #include "parts.h"
- #if UC3C
- // These defines are missing from or wrong in the toolchain header file ip_xxx.h or part.h
- #ifndef AVR32_WDT_KEY_VALUE
- #define AVR32_WDT_KEY_VALUE 0x00000055
- #endif
- #define AVR32_SR_M_SUP 0x00000001
- #define AVR32_SR_M_SIZE 3
- #define AVR32_SR_M_OFFSET 22
- #define AVR32_SRAM_ADDRESS 0x00000000
- #endif
- //! @{
- //! \verbatim
- // Performs efficiently a bitwise logical Exclusive-OR between the specified
- // register and an immediate value of up to 32 bits. The result is stored in
- // the destination register.
- .macro eor.w rd, imm
- .if \imm & 0x0000FFFF
- eorl \rd, LO(\imm)
- .endif
- .if \imm & 0xFFFF0000
- eorh \rd, HI(\imm)
- .endif
- .endm
- // Moves efficiently an immediate value of up to 32 bits into a register.
- .macro mov.w rd, imm
- .if ((-(1 << (21 - 1))) <= \imm) && (\imm <= ((1 << (21 - 1)) - 1))
- mov \rd, \imm
- #if __AVR32_UC__ >= 2
- .elseif !(\imm & 0x0000FFFF)
- movh \rd, HI(\imm)
- #endif
- .else
- mov \rd, LO(\imm)
- orh \rd, HI(\imm)
- .endif
- .endm
- // Performs efficiently a bitwise logical OR between the specified register
- // and an immediate value of up to 32 bits. The result is stored in the
- // destination register.
- .macro or.w rd, imm
- .if \imm & 0x0000FFFF
- orl \rd, LO(\imm)
- .endif
- .if \imm & 0xFFFF0000
- orh \rd, HI(\imm)
- .endif
- .endm
- .section .reset, "ax", @progbits
- .balign 2
- // Reset vector: This must be linked @ 0x80000000.
- .global _start
- .type _start, @function
- _start:
- // Check if valid userpage
- mov.w r0, BOOT_CFG_ADDRESS
- ld.w r1, r0[0]
- mov.w r0, BOOT_CFG_BOOT_KEY1_VALUE
- cp r0, r1
- brne start_loader
- // Check if app available
- mov.w r0, BOOT_CFG_ADDRESS
- ld.w r1, r0[0xC]
- lsr r1, 16
- cp.w r1, BOOT_CFG_BOOT_KEY2_VALUE
- brne start_loader
- // Check if there is a boot task to do
- mov.w r0, BOOT_CFG_ADDRESS
- ld.w r1, r0[8]
- cp.w r1, 0
- breq start_program
- rcall start_loader
- // Start of the ISP process
- start_loader:
- rcall disable_wdt // Disable the WDT
- // Set initial stack pointer.
- mov sp, _estack
- // Disable the exception processing.
- ssrf AVR32_SR_EM_OFFSET
- // Set up EVBA so interrupts can be enabled.
- mov r0, _evba
- mtsr AVR32_EVBA, r0
- // Load initialized data having a global lifetime from the data LMA.
- mov r0, _data
- mov r1, _edata
- sub r2, pc, $ - _data_lma
- rcall load_idata
- // Clear uninitialized data having a global lifetime in the blank static storage section.
- mov r0, __bss_start
- mov r1, _end
- mov.w r2, 0
- mov.w r3, 0
- rjmp clear_udata
- clear_udata_loop:
- st.d r0++, r2
- clear_udata:
- cp.w r0, r1
- brlo clear_udata_loop
- // Load constant data and code from the const LMA.
- mov r0, _const
- mov r1, _econst
- sub r2, pc, $ - _const_lma
- rcall load_idata
- // Call the ISP main function, which must not return.
- call main
- start_program:
- lddpc pc, program_start_address
- disable_wdt:
- mov.w r9, AVR32_WDT_ADDRESS
- mov.w r2, AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET
- st.w r9[AVR32_WDT_CTRL], r2
- eor.w r2, AVR32_WDT_CTRL_KEY_MASK
- st.w r9[AVR32_WDT_CTRL], r2
- mov pc, lr
- load_idata_loop:
- ld.d r4, r2++
- st.d r0++, r4
- load_idata:
- cp.w r0, r1
- brle load_idata_loop
- mov pc, lr
- // Common CRC8 function
- crc8:
- clz r5, r4
- rsub r5, r5, 32 - 9
- lsl r5, r3, r5
- eor r4, r5
- test_crc8_end:
- cp.w r4, 0xFF
- brhi crc8
- cp.w r4, 0
- retal r4
- _reset_vector:
- mov R0, 0x8000
- lsl R0, 16
- mov pc, R0
- // Constant data area.
- .balign 4
- program_start_address:
- .word USER_APP_START_ADDRESS
- .section .evba, "ax", @progbits
- .balign 2
- // Export symbol.
- .global _evba
- .type _evba, @function
- _evba:
- .org 0x000
- // Unrecoverable Exception.
- _handle_Unrecoverable_Exception:
- call _reset_vector
- //rjmp $
- .org 0x004
- // TLB Multiple Hit.
- _handle_TLB_Multiple_Hit:
- rjmp $
- .org 0x008
- // Bus Error Data Fetch.
- _handle_Bus_Error_Data_Fetch:
- rjmp $
- .org 0x00C
- // Bus Error Instruction Fetch.
- _handle_Bus_Error_Instruction_Fetch:
- rjmp $
- .org 0x010
- // NMI.
- _handle_NMI:
- rjmp $
- .org 0x014
- // Instruction Address.
- _handle_Instruction_Address:
- rjmp $
- .org 0x018
- // ITLB Protection.
- _handle_ITLB_Protection:
- rjmp $
- .org 0x01C
- // Breakpoint.
- _handle_Breakpoint:
- rjmp $
- .org 0x020
- // Illegal Opcode.
- _handle_Illegal_Opcode:
- rjmp $
- .org 0x024
- // Unimplemented Instruction.
- _handle_Unimplemented_Instruction:
- rjmp $
- .org 0x028
- // Privilege Violation.
- _handle_Privilege_Violation:
- rjmp $
- .org 0x02C
- // Floating-Point: UNUSED IN AVR32UC and AVR32AP.
- _handle_Floating_Point:
- rjmp $
- .org 0x030
- // Coprocessor Absent: UNUSED IN AVR32UC.
- _handle_Coprocessor_Absent:
- rjmp $
- .org 0x034
- // Data Address (Read).
- _handle_Data_Address_Read:
- rjmp $
- .org 0x038
- // Data Address (Write).
- _handle_Data_Address_Write:
- rjmp $
- .org 0x03C
- // DTLB Protection (Read).
- _handle_DTLB_Protection_Read:
- rjmp $
- .org 0x040
- // DTLB Protection (Write).
- _handle_DTLB_Protection_Write:
- rjmp $
- .org 0x044
- // DTLB Modified: UNUSED IN AVR32UC.
- _handle_DTLB_Modified:
- rjmp $
- .org 0x050
- // ITLB Miss.
- _handle_ITLB_Miss:
- rjmp $
- .org 0x060
- // DTLB Miss (Read).
- _handle_DTLB_Miss_Read:
- rjmp $
- .org 0x070
- // DTLB Miss (Write).
- _handle_DTLB_Miss_Write:
- rjmp $
- .org 0x100
- // Supervisor Call.
- _handle_Supervisor_Call:
- rjmp $
- /*
- * Interrupt support.
- * The interrupt controller must provide the offset address relative to EVBA.
- * Important note:
- * All interrupts call a C function named _get_interrupt_handler.
- * This function will read group and interrupt line number to then return in
- *R12 a pointer to a user-provided interrupt handler.
- */
- .balign 4
- .irp priority, 0, 1, 2, 3
- .global _int\priority
- .type _int\priority, @function
- _int\priority:
- #if __AVR32_UC__
- /*
- * R8-R12, LR, PC and SR are automatically pushed onto the system stack
- * by the CPU upon interrupt entry. No other register is saved by
- * hardware.
- */
- #elif __AVR32_AP__
- /*
- * PC and SR are automatically saved in respectively RAR_INTx and
- * RSR_INTx by the CPU upon interrupt entry. No other register is saved
- * by hardware.
- */
- pushm r8-r12, lr
- #endif
- // Pass the int_level parameter to the _get_interrupt_handler function.
- mov r12, \priority
- call _get_interrupt_handler
- // Get the pointer to the interrupt handler returned by the function.
- cp.w r12, 0
- #if __AVR32_UC__
- /*
- * If this was not a spurious interrupt (R12 != NULL), jump to the
- * handler.
- */
- movne pc, r12
- #elif __AVR32_AP__
- // If this was a spurious interrupt (R12 == NULL), branch.
- breq spint\priority
- /*
- * Push the pointer to the interrupt handler onto the system stack since
- * no register may be altered.
- */
- st.w --sp, r12
- popm r8-r12, lr, pc // Restore registers and jump to the handler.
- spint\priority:
- popm r8-r12, lr
- #endif
- /*
- * If this was a spurious interrupt (R12 == NULL), return from event
- * handler.
- */
- rete
- .endr
- //! \endverbatim
- //! @}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement