#include "tl2cdr.h" #include "sysDef.h" #if 0 /* 其他代码全部使用RV32E编译,仅此代码采用 RV32I 编译,故而可以使用x0, x16~x31寄存器 为了方便,不再使用ABI中的别名,直接使用x0, x16~x31;x1~x15使用ABI中定义的别名 x16~x23, 作为临时寄存器使用 x24, TL2CDR_BASE x25, 接收数据的存储地址,第一个4字节接收数据的长度,往后都是数据 x26, 当前需要发送的数据的地址,第一个4个字节是长度(写入tx0_txLen)、第二开始是数据 x27, 需要发送的数据长度 x28, plic_claim的地址,用于读取当前正在服务的中断号,清除中断号 x29, REG_ISR_ADDR 中断服务子程序入口 x30, 最小的服务中断号 x31, 最大的服务中断号 */ #endif #define REG_TL2CDR_BASE x24 #define REG_rx_data x25 #define REG_tx_data x26 #define REG_tx_data_len x27 #define REG_plic_claim x28 #define REG_ISR_ADDR x29 #define REG_min_isr_num x30 #define REG_max_isr_num x31 #define REG_4 x23 .globl _prog_start .globl _rv32i_plic_handle .section .text.init, "ax", %progbits _prog_start: //a0 call_function no li x16, SYS_INIT beqz a0, init_system_func //初始化系统,输入必要的地址信息,返回 中断程序 的地址 li x16, SYS_SEND_DATA beq a0, x16, send_data_func li x16, SYS_SET_RECV_INFO beq a0, x16, set_recv_info_func 10: j 10b //死循环,输入错误的功能号 ret //心理安慰,并不会返回 //初始化系统,输入必要的地址信息,返回中断程序的地址 //a1, plic_claim的地址, 其实也可以不用传送 init_system_func: mv REG_plic_claim, a1 # plic_claim la x17, _rv32i_plic_handle mv a0, x17 li REG_TL2CDR_BASE, TL2CDR_BASE la REG_ISR_ADDR, isr_hdl_table li REG_min_isr_num, 14 li REG_max_isr_num, 25 li REG_4, 4 ret //主站启动发送数据 //a1, 当前需要发送的数据的地址 //a2, 当前数据发送的长度 //a3, dummy //a4, dummy send_data_func: mv REG_tx_data, a1 mv REG_tx_data_len, a2 //*tx0_txLen = 8 + tx_len; //前导+长度命令 mv x16, a2 addi x17, x16, 8 sw x17, TX0_WriteTxLen(REG_TL2CDR_BASE) //*tx0_txFifo = (tx_len << 20) | (0 << 16) | 0x0000; slli x17, x16, 20 sw x17, TX0_WriteTxFifo(REG_TL2CDR_BASE) //*tx0_txFifo = data[0] #lw x17, 0(REG_tx_data) #sw x17, TX0_WriteTxFifo(REG_TL2CDR_BASE) #add REG_tx_data, REG_tx_data, REG_4 #sub REG_tx_data_len, REG_tx_data_len, REG_4 li a0, 1 ret //设置接收数据的地址,第一个接收数据的长度,往后都是数据 //a1, 设置接收数据的缓冲区 set_recv_info_func: mv REG_rx_data, a1 li a0, 1 ret //-------------------------------------------- //这是中断程序开始的地方 .balign 32 _rv32i_plic_handle: lw x16, 0(REG_plic_claim) # x16 = *plic_claim sw x16, 0(REG_plic_claim) # *plic_claim = x16 bltu x16, REG_min_isr_num, exit_handle #if x16 < REG_min_isr_num then goto exit_handle bltu REG_max_isr_num, x16, exit_handle #if REG_max_isr_num < x16 then goto exit_handle sub x17, x16, REG_min_isr_num slli x17, x17, 2 # x17 = x17 * 4 add x18, REG_ISR_ADDR, x17 # x18 = REG_ISR_ADDR + x17 jr x18 exit_handle: mret isr_tx0_end_hdl: #li x17, 1 #sw x17, TX0_WriteSoftReset(REG_TL2CDR_BASE) mret isr_tx1_end_hdl: #li x17, 1 #sw x17, TX0_WriteSoftReset(REG_TL2CDR_BASE) mret isr_rx0_err_hdl: mret isr_rx1_err_hdl: mret isr_rx0_start_hdl: mret isr_rx1_start_hdl: lw x22, RX1_ReadRxLen(REG_TL2CDR_BASE) sw x22, 0(REG_rx_data) add REG_rx_data, REG_rx_data, REG_4 mret isr_rx0_end_hdl: mret isr_rx1_end_hdl: mret isr_tx0_deq_hdl: beqz REG_tx_data_len, 1f //if (REG_tx_data_len > 0) lw x17, 0(REG_tx_data) sw x17, TX0_WriteTxFifo(REG_TL2CDR_BASE) add REG_tx_data, REG_tx_data, REG_4 sub REG_tx_data_len, REG_tx_data_len, REG_4 1: mret isr_tx1_deq_hdl: mret isr_rx0_enq_hdl: mret isr_rx1_enq_hdl: lw x17, RX1_ReadRxFifo(REG_TL2CDR_BASE) sw x17, 0(REG_rx_data) add REG_rx_data, REG_rx_data, REG_4 mret isr_hdl_table: j isr_tx0_end_hdl j isr_tx1_end_hdl j isr_rx0_err_hdl j isr_rx1_err_hdl j isr_rx0_start_hdl j isr_rx1_start_hdl j isr_rx0_end_hdl j isr_rx1_end_hdl j isr_tx0_deq_hdl j isr_tx1_deq_hdl j isr_rx0_enq_hdl j isr_rx1_enq_hdl