/* author: Luo Jia 2019-11-29 */ .section .vectors, "ax" .globl _gd32vf103_vectors _gd32vf103_vectors: /* source: Firmware\RISCV\env_Eclipse\start.S */ .weak eclic_msip_handler .weak eclic_mtip_handler .weak eclic_bwei_handler .weak eclic_pmovi_handler .weak WWDGT_IRQHandler .weak LVD_IRQHandler .weak TAMPER_IRQHandler .weak RTC_IRQHandler .weak FMC_IRQHandler .weak RCU_IRQHandler .weak EXTI0_IRQHandler .weak EXTI1_IRQHandler .weak EXTI2_IRQHandler .weak EXTI3_IRQHandler .weak EXTI4_IRQHandler .weak DMA0_Channel0_IRQHandler .weak DMA0_Channel1_IRQHandler .weak DMA0_Channel2_IRQHandler .weak DMA0_Channel3_IRQHandler .weak DMA0_Channel4_IRQHandler .weak DMA0_Channel5_IRQHandler .weak DMA0_Channel6_IRQHandler .weak ADC0_1_IRQHandler .weak CAN0_TX_IRQHandler .weak CAN0_RX0_IRQHandler .weak CAN0_RX1_IRQHandler .weak CAN0_EWMC_IRQHandler .weak EXTI5_9_IRQHandler .weak TIMER0_BRK_IRQHandler .weak TIMER0_UP_IRQHandler .weak TIMER0_TRG_CMT_IRQHandler .weak TIMER0_Channel_IRQHandler .weak TIMER1_IRQHandler .weak TIMER2_IRQHandler .weak TIMER3_IRQHandler .weak I2C0_EV_IRQHandler .weak I2C0_ER_IRQHandler .weak I2C1_EV_IRQHandler .weak I2C1_ER_IRQHandler .weak SPI0_IRQHandler .weak SPI1_IRQHandler .weak USART0_IRQHandler .weak USART1_IRQHandler .weak USART2_IRQHandler .weak EXTI10_15_IRQHandler .weak RTC_Alarm_IRQHandler .weak USBFS_WKUP_IRQHandler .weak EXMC_IRQHandler .weak TIMER4_IRQHandler .weak SPI2_IRQHandler .weak UART3_IRQHandler .weak UART4_IRQHandler .weak TIMER5_IRQHandler .weak TIMER6_IRQHandler .weak DMA1_Channel0_IRQHandler .weak DMA1_Channel1_IRQHandler .weak DMA1_Channel2_IRQHandler .weak DMA1_Channel3_IRQHandler .weak DMA1_Channel4_IRQHandler .weak CAN1_TX_IRQHandler .weak CAN1_RX0_IRQHandler .weak CAN1_RX1_IRQHandler .weak CAN1_EWMC_IRQHandler .weak USBFS_IRQHandler jal x0, _start_logical_addr .word 0 .word 0 .word eclic_msip_handler .word 0 .word 0 .word 0 .word eclic_mtip_handler .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word eclic_bwei_handler .word eclic_pmovi_handler .word WWDGT_IRQHandler .word LVD_IRQHandler .word TAMPER_IRQHandler .word RTC_IRQHandler .word FMC_IRQHandler .word RCU_IRQHandler .word EXTI0_IRQHandler .word EXTI1_IRQHandler .word EXTI2_IRQHandler .word EXTI3_IRQHandler .word EXTI4_IRQHandler .word DMA0_Channel0_IRQHandler .word DMA0_Channel1_IRQHandler .word DMA0_Channel2_IRQHandler .word DMA0_Channel3_IRQHandler .word DMA0_Channel4_IRQHandler .word DMA0_Channel5_IRQHandler .word DMA0_Channel6_IRQHandler .word ADC0_1_IRQHandler .word CAN0_TX_IRQHandler .word CAN0_RX0_IRQHandler .word CAN0_RX1_IRQHandler .word CAN0_EWMC_IRQHandler .word EXTI5_9_IRQHandler .word TIMER0_BRK_IRQHandler .word TIMER0_UP_IRQHandler .word TIMER0_TRG_CMT_IRQHandler .word TIMER0_Channel_IRQHandler .word TIMER1_IRQHandler .word TIMER2_IRQHandler .word TIMER3_IRQHandler .word I2C0_EV_IRQHandler .word I2C0_ER_IRQHandler .word I2C1_EV_IRQHandler .word I2C1_ER_IRQHandler .word SPI0_IRQHandler .word SPI1_IRQHandler .word USART0_IRQHandler .word USART1_IRQHandler .word USART2_IRQHandler .word EXTI10_15_IRQHandler .word RTC_Alarm_IRQHandler .word USBFS_WKUP_IRQHandler .word 0 .word 0 .word 0 .word 0 .word 0 .word EXMC_IRQHandler .word 0 .word TIMER4_IRQHandler .word SPI2_IRQHandler .word UART3_IRQHandler .word UART4_IRQHandler .word TIMER5_IRQHandler .word TIMER6_IRQHandler .word DMA1_Channel0_IRQHandler .word DMA1_Channel1_IRQHandler .word DMA1_Channel2_IRQHandler .word DMA1_Channel3_IRQHandler .word DMA1_Channel4_IRQHandler .word 0 .word 0 .word CAN1_TX_IRQHandler .word CAN1_RX0_IRQHandler .word CAN1_RX1_IRQHandler .word CAN1_EWMC_IRQHandler .word USBFS_IRQHandler # RISC-V defined CSR registers .equ mstatus, 0x300 .equ mie, 0x304 .equ mtvec, 0x305 # Bumblebee core defined CSR registers .equ mtvt, 0x307 .equ msubm, 0x7c4 .equ mtvt2, 0x7ec .equ jalmnxti, 0x7ed .equ pushmcause, 0x7ee .equ pushmepc, 0x7ef .equ pushmsubm, 0x7eb # Constants .equ REGBYTES,4 .equ MSTATUS_MIE, 0x00000008 .section .init, "ax" .globl _start_logical_addr _start_logical_addr: la a0, _start_logical_addr li a1, 1 slli a1, a1, 29 bleu a1, a0, _start_bootstrap srli a1, a1, 2 bleu a1, a0, _start_bootstrap la a0, _start_bootstrap add a0, a0, a1 jr a0 _start_bootstrap: # Initialize mtvt la t0, _gd32vf103_vectors csrw mtvt, t0 # Initialize and enable mtvt2 la t0, _gd32vf103_irq_entry csrw mtvt2, t0 csrs mtvt2, 0x1 # Initialize mtvec for trap & NMI base addr la t0, _gd32vf103_trap_entry csrw mtvec, t0 # todo: conflict with riscv-rt? # Start riscv-rt Rust entry which would check hart id, # allocate stack, clear bss section j _start .macro SAVE_CONTEXT sw ra, 0*REGBYTES(sp) sw tp, 1*REGBYTES(sp) sw t0, 2*REGBYTES(sp) sw t1, 3*REGBYTES(sp) sw t2, 4*REGBYTES(sp) sw t3, 5*REGBYTES(sp) sw t4, 6*REGBYTES(sp) sw t5, 7*REGBYTES(sp) sw t6, 8*REGBYTES(sp) sw a0, 9*REGBYTES(sp) sw a1, 10*REGBYTES(sp) sw a2, 11*REGBYTES(sp) sw a3, 12*REGBYTES(sp) sw a4, 13*REGBYTES(sp) sw a5, 14*REGBYTES(sp) sw a6, 15*REGBYTES(sp) sw a7, 16*REGBYTES(sp) .endm .macro RESTORE_CONTEXT lw ra, 0*REGBYTES(sp) lw tp, 1*REGBYTES(sp) lw t0, 2*REGBYTES(sp) lw t1, 3*REGBYTES(sp) lw t2, 4*REGBYTES(sp) lw t3, 5*REGBYTES(sp) lw t4, 6*REGBYTES(sp) lw t5, 7*REGBYTES(sp) lw t6, 8*REGBYTES(sp) lw a0, 9*REGBYTES(sp) lw a1, 10*REGBYTES(sp) lw a2, 11*REGBYTES(sp) lw a3, 12*REGBYTES(sp) lw a4, 13*REGBYTES(sp) lw a5, 14*REGBYTES(sp) lw a6, 15*REGBYTES(sp) lw a7, 16*REGBYTES(sp) .endm .section .trap, "ax" .p2align 6 # 4-byte aligned .globl _gd32vf103_trap_entry .weak _gd32vf103_trap_entry _gd32vf103_trap_entry: ; .globl _start_trap ; _start_trap: # todo: verify # Allocate stack space addi sp, sp, -19*REGBYTES # Save ra, tp, t*, a* registers SAVE_CONTEXT # save 17 registers # Store mcause, mepc and msubm into memory csrrwi zero, pushmcause, 17 csrrwi zero, pushmepc, 18 csrrwi zero, pushmsubm, 19 # Set the function argument of trap handler mv a0, sp # Calls the trap handler (defined in riscv-rt) # extern "C" fn start_trap_rust(trap_frame: *const TrapFrame) jal ra, _start_trap_rust # Restore mcause, mepc and msubm lw a0, 19*REGBYTES(sp) csrw msubm, a0 lw a0, 18*REGBYTES(sp) csrw mepc, a0 lw a0, 17*REGBYTES(sp) csrw mcause, a0 # Restore ra, tp, t*, a* registers RESTORE_CONTEXT # restore 17 registers # Free stack space addi sp, sp, 20*REGBYTES mret .section .trap, "ax" .align 2 .globl _gd32vf103_irq_entry .weak _gd32vf103_irq_entry _gd32vf103_irq_entry: # Adjust stack pointer to allocate stack space addi sp, sp, -20*REGBYTES # Save ra, tp, t*, a* registers SAVE_CONTEXT # save 17 registers # These are special CSR read operations # which actually uses mcause, mepc and msubm as operand # to directly store it to memory (stack) csrrwi zero, pushmcause, 17 csrrwi zero, pushmepc, 18 csrrwi zero, pushmsubm, 19 # This special CSR read/write operation # It claims the CLIC to find its pending highest ID. # If the ID is not 0, then _automatically enable # the mstatus.MIE_, and jump to its vector-entry-label, # and update the link register. # This design targets to speed up biting tail interrupts. csrrw ra, jalmnxti, ra # Disable interrupts csrc mstatus, MSTATUS_MIE # Restore mcause, mepc and msubm lw a0, 19*REGBYTES(sp) csrw msubm, a0 lw a0, 18*REGBYTES(sp) csrw mepc, a0 lw a0, 17*REGBYTES(sp) csrw mcause, a0 # Restore ra, tp, t*, a* registers RESTORE_CONTEXT # restore 17 registers # Free stack space addi sp, sp, 20*REGBYTES mret