ref: f801657f77f3923ec2388c25bdcb036c8019ba89
dir: /l.s/
#include "mem.h" #include "handlers.h" #include "thumb2.h" #define _estack DATAEADDR // the stack starts at DATAEADDR #define RAMBOOT 0xF108F85F #undef ORB THUMB=4 /* vector table 0x08000000-0x08000108 */ TEXT _vector_table(SB), $0 WORD $_estack /* core exceptions */ WORD $Reset_Handler WORD $NMI_Handler WORD $HardFault_Handler WORD $MemManage_Handler WORD $BusFault_Handler WORD $UsageFault_Handler WORD $0x00 WORD $0x00 WORD $0x00 WORD $0x00 WORD $SVC_Handler WORD $DebugMon_Handler WORD $0x00 WORD $PendSV_Handler WORD $SysTick_Handler /* external exceptions */ WORD $WWDG_IRQHandler WORD $PVD_IRQHandler WORD $TAMPER_IRQHandler WORD $RTC_IRQHandler WORD $FLASH_IRQHandler WORD $RCC_IRQHandler WORD $EXTI0_IRQHandler WORD $EXTI1_IRQHandler WORD $EXTI2_IRQHandler WORD $EXTI3_IRQHandler WORD $EXTI4_IRQHandler WORD $DMA1_Channel1_IRQHandler WORD $DMA1_Channel2_IRQHandler WORD $DMA1_Channel3_IRQHandler WORD $DMA1_Channel4_IRQHandler WORD $DMA1_Channel5_IRQHandler WORD $DMA1_Channel6_IRQHandler WORD $DMA1_Channel7_IRQHandler WORD $ADC1_2_IRQHandler WORD $USB_HP_CAN1_TX_IRQHandler WORD $USB_LP_CAN1_RX0_IRQHandler WORD $CAN1_RX1_IRQHandler WORD $CAN1_SCE_IRQHandler WORD $EXTI9_5_IRQHandler WORD $TIM1_BRK_IRQHandler WORD $TIM1_UP_IRQHandler WORD $TIM1_TRG_COM_IRQHandler WORD $TIM1_CC_IRQHandler WORD $TIM2_IRQHandler WORD $TIM3_IRQHandler WORD $TIM4_IRQHandler WORD $I2C1_EV_IRQHandler WORD $I2C1_ER_IRQHandler WORD $I2C2_EV_IRQHandler WORD $I2C2_ER_IRQHandler WORD $SPI1_IRQHandler WORD $SPI2_IRQHandler WORD $USART1_IRQHandler WORD $USART2_IRQHandler WORD $USART3_IRQHandler WORD $EXTI15_10_IRQHandler WORD $RTC_Alarm_IRQHandler WORD $USBWakeUp_IRQHandler WORD $0x00 WORD $0x00 WORD $0x00 WORD $0x00 WORD $0x00 WORD $0x00 WORD $0x00 /* ram boot */ WORD $0x00 /* startup section */ TEXT _start(SB), THUMB, $-4 MOVW $setR12(SB), R1 MOVW R1, R12 /* static base (SB) */ MOVW $DATAEADDR, R1 MOVW R1, SP // copy the text segment unto the data segment MOVW $etext(SB), R1 MOVW $bdata(SB), R2 MOVW $edata(SB), R3 _start_loop: CMP R3, R2 BGE _end_start_loop MOVW (R1), R4 MOVW R4, (R2) ADD $4, R1 ADD $4, R2 B _start_loop _end_start_loop: BL ,introff(SB) B ,main(SB) /* Interrupt handlers */ /* default handler */ TEXT _default_handler(SB), THUMB, $-4 _infinite_loop: MOVW SP, R0 B _infinite_loop /* hard fault handler */ TEXT _hard_fault_handler(SB), THUMB, $-4 PUSH(0x1ff0, 0) MOVW SP, R0 B ,hard_fault_handler(SB) /* bus fault handler */ TEXT _bus_fault_handler(SB), THUMB, $-4 PUSH(0x1ff0, 0) MOVW SP, R0 B ,bus_fault_handler(SB) /* usage fault handler */ TEXT _usage_fault_handler(SB), THUMB, $-4 PUSH(0x1ff0, 0) MOVW SP, R0 B ,usage_fault_handler(SB) /* mem manage handler */ TEXT _mem_manage_handler(SB), THUMB, $-4 PUSH(0x1ff0, 0) MOVW SP, R0 B ,mem_manage_handler(SB) /* systick handler */ /* These exception handlers will be entered in handler mode, using the main stack pointer (MSP). */ TEXT _systick_handler(SB), THUMB, $-4 /* In handler mode; R0-R3, R12, R14, PC and xPSR from the preempted code are saved on the stack. R0 is stored lowest at the address pointed to by the stack pointer. */ MOVW 28(SP), R0 /* Read xPSR */ MOVW R0, R2 MOVW $0x060fffff, R1 AND.S R1, R0 /* Check the exception number and other bits. */ BNE _systick_exit /* Don't interrupt if these are set. */ /* Store the xPSR flags for the interrupted routine. These will be temporarily overwritten and restored later. */ MOVW $apsr_flags(SB), R1 MOVW R2, (R1) /* Record the interrupted PC in the slot for R12. */ MOVW 24(SP), R0 ORR $1, R0 MOVW R0, 16(SP) /* Clear the condition flags before jumping into the switcher. */ MOVW $0x07ffffff, R0 AND R2, R0 MOVW R0, 28(SP) MOVW $_preswitch(SB), R0 ORR $1, R0 MOVW R0, 24(SP) /* Return to the _preswitch routine instead. */ _systick_exit: RET /* When _systick returns, the exception returns and thread mode is entered again. The registers from the interrupted code have the values they would have if uninterrupted except for R12 which contains the interrupted PC and PC which points to here. */ TEXT _preswitch(SB), THUMB, $-4 MOVW R0, R0 PUSH(0x1000, 0) /* Save R12 (will be PC). */ PUSH(0x0bff, 1) /* Save registers R0-R9, R11 as well as R14, in case the interrupted code uses them. */ MOVW $setR12(SB), R1 MOVW R1, R12 /* Reset static base (SB) */ MOVW SP, R0 /* Pass the stack pointer to the switcher. */ BL ,switcher(SB) MOVW $apsr_flags(SB), R1 MOVW (R1), R1 MRS(0, MRS_PRIMASK) RSB $1, R0, R0 CPS(0, CPS_I) POP_LR_PC(0x0bff, 1, 0) /* Recover R0-R9, R11 and R14 */ POP_LR_PC(0, 0, 1) /* then PC. */