shithub: p9-stm32-example-os

ref: f801657f77f3923ec2388c25bdcb036c8019ba89
dir: /l.s/

View raw version
#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. */