diff --git a/Makefile b/Makefile index dd96a0c..311081d 100644 --- a/Makefile +++ b/Makefile @@ -60,25 +60,29 @@ test: sw: - riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs \ - -I ./tb/sw/ -I ./tb/sw/src -I ./tb/sw/axi_gpio -I ./tb/sw/axi_uart -I ./tb/sw/axi_timer \ - -c ./tb/sw/src/main.c \ - -o ./tb/sw/build/main.o + # riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs \ + # -I ./tb/sw/ -I ./tb/sw/src -I ./tb/sw/axi_gpio -I ./tb/sw/axi_uart -I ./tb/sw/axi_timer \ + # -c ./tb/sw/src/main.c \ + # -o ./tb/sw/build/main.o - riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs \ - -I ./tb/sw/ -I ./tb/sw/src -I ./tb/sw/axi_gpio -I ./tb/sw/axi_uart -I ./tb/sw/axi_timer \ - -c ./tb/sw/axi_uart/uart.c \ - -o ./tb/sw/build/uart.o + # riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs \ + # -I ./tb/sw/ -I ./tb/sw/src -I ./tb/sw/axi_gpio -I ./tb/sw/axi_uart -I ./tb/sw/axi_timer \ + # -c ./tb/sw/axi_uart/uart.c \ + # -o ./tb/sw/build/uart.o riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs -mcmodel=medany -mexplicit-relocs \ - -I ./tb/sw/ -I ./tb/sw/src -I ./tb/sw/axi_gpio -I ./tb/sw/axi_uart -I ./tb/sw/axi_timer \ + -I ./tb/sw/ -I ./tb/sw/src \ -c ./tb/sw/src/startup.S \ -o ./tb/sw/build/startup.o + riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs -mcmodel=medany -mexplicit-relocs \ + -I ./tb/sw/ -I ./tb/sw/src \ + -c ./tb/sw/src/main.S \ + -o ./tb/sw/build/main.o + riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs -nostdlib -nodefaultlibs -nostartfiles \ -T ./tb/sw/linker.lds \ ./tb/sw/build/startup.o \ - ./tb/sw/build/uart.o \ ./tb/sw/build/main.o \ -o ./tb/sw/build/test.elf diff --git a/tb/sw/src/custom_ops.S b/tb/sw/src/custom_ops.S new file mode 100644 index 0000000..71889b9 --- /dev/null +++ b/tb/sw/src/custom_ops.S @@ -0,0 +1,102 @@ +// This is free and unencumbered software released into the public domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. + +#define regnum_q0 0 +#define regnum_q1 1 +#define regnum_q2 2 +#define regnum_q3 3 + +#define regnum_x0 0 +#define regnum_x1 1 +#define regnum_x2 2 +#define regnum_x3 3 +#define regnum_x4 4 +#define regnum_x5 5 +#define regnum_x6 6 +#define regnum_x7 7 +#define regnum_x8 8 +#define regnum_x9 9 +#define regnum_x10 10 +#define regnum_x11 11 +#define regnum_x12 12 +#define regnum_x13 13 +#define regnum_x14 14 +#define regnum_x15 15 +#define regnum_x16 16 +#define regnum_x17 17 +#define regnum_x18 18 +#define regnum_x19 19 +#define regnum_x20 20 +#define regnum_x21 21 +#define regnum_x22 22 +#define regnum_x23 23 +#define regnum_x24 24 +#define regnum_x25 25 +#define regnum_x26 26 +#define regnum_x27 27 +#define regnum_x28 28 +#define regnum_x29 29 +#define regnum_x30 30 +#define regnum_x31 31 + +#define regnum_zero 0 +#define regnum_ra 1 +#define regnum_sp 2 +#define regnum_gp 3 +#define regnum_tp 4 +#define regnum_t0 5 +#define regnum_t1 6 +#define regnum_t2 7 +#define regnum_s0 8 +#define regnum_s1 9 +#define regnum_a0 10 +#define regnum_a1 11 +#define regnum_a2 12 +#define regnum_a3 13 +#define regnum_a4 14 +#define regnum_a5 15 +#define regnum_a6 16 +#define regnum_a7 17 +#define regnum_s2 18 +#define regnum_s3 19 +#define regnum_s4 20 +#define regnum_s5 21 +#define regnum_s6 22 +#define regnum_s7 23 +#define regnum_s8 24 +#define regnum_s9 25 +#define regnum_s10 26 +#define regnum_s11 27 +#define regnum_t3 28 +#define regnum_t4 29 +#define regnum_t5 30 +#define regnum_t6 31 + +// x8 is s0 and also fp +#define regnum_fp 8 + +#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \ +.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0)) + +#define picorv32_getq_insn(_rd, _qs) \ +r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011) + +#define picorv32_setq_insn(_qd, _rs) \ +r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011) + +#define picorv32_retirq_insn() \ +r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011) + +#define picorv32_maskirq_insn(_rd, _rs) \ +r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011) + +#define picorv32_waitirq_insn(_rd) \ +r_type_insn(0b0000100, 0, 0, 0b100, regnum_ ## _rd, 0b0001011) + +#define picorv32_timer_insn(_rd, _rs) \ +r_type_insn(0b0000101, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011) + diff --git a/tb/sw/src/main.S b/tb/sw/src/main.S new file mode 100644 index 0000000..2237ce4 --- /dev/null +++ b/tb/sw/src/main.S @@ -0,0 +1,47 @@ + +#define cdr_0_tx_status 0x40000000 +#define cdr_0_tx_txLen 0x40000004 +#define cdr_0_tx_txFifo 0x40000008 +#define cdr_0_rx_softReset 0x40000010 +#define cdr_0_rx_status 0x40000014 +#define cdr_0_rx_rxLen 0x40000018 +#define cdr_0_rx_rxFifo 0x4000001c +#define cdr_1_tx_status 0x40000080 +#define cdr_1_tx_txLen 0x40000084 +#define cdr_1_tx_txFifo 0x40000088 +#define cdr_1_rx_softReset 0x40000090 +#define cdr_1_rx_status 0x40000094 +#define cdr_1_rx_rxLen 0x40000098 +#define cdr_1_rx_rxFifo 0x4000009c + +.global main + + +main: + lui x5, %hi(cdr_0_tx_status) + + li x6, 128 + sw x6, 4(x5) #cdr_0_tx_txLen + + li x6, 32 # 设置循环次数 +1: + beqz x15, 2f # 如果x10为0,则跳到2 + lw x7, 0(x5) # 读取cdr_0_tx_status的值 + andi x7, x7, 0x2 # 检查第1比特(位1) + beqz x7, 1b # 如果第1比特为0,则回到1处继续循环 + +2: + # 向cdr_0_tx_txFifo地址写入0x55,循环32次 + sw x6, 8(x5) # 向cdr_0_tx_txFifo写入0x55 + addi x6, x6, -1 # 递减计数器 + bnez x6, 1b # 如果计数器不为0,则继续循环 + +3: + j 3b + + + + + + + diff --git a/tb/sw/src/startup.S b/tb/sw/src/startup.S index cf8dd98..408b3a8 100644 --- a/tb/sw/src/startup.S +++ b/tb/sw/src/startup.S @@ -1,6 +1,198 @@ - .section .text.init - .globl _prog_start + +#include "custom_ops.S" + + + + .section .text + .globl _prog_start + .global irq + .extern main + +/* Interrupt handler + **********************************/ + +.balign 16 +irq_vec: + /* save registers */ + + picorv32_setq_insn(q2, x1) + picorv32_setq_insn(q3, x2) + + lui x1, %hi(irq_regs) + addi x1, x1, %lo(irq_regs) + + picorv32_getq_insn(x2, q0) + sw x2, 0*4(x1) + + picorv32_getq_insn(x2, q2) + sw x2, 1*4(x1) + + picorv32_getq_insn(x2, q3) + sw x2, 2*4(x1) + +#ifdef ENABLE_FASTIRQ + sw x5, 5*4(x1) + sw x6, 6*4(x1) + sw x7, 7*4(x1) + sw x10, 10*4(x1) + sw x11, 11*4(x1) + sw x12, 12*4(x1) + sw x13, 13*4(x1) + sw x14, 14*4(x1) + sw x15, 15*4(x1) + sw x16, 16*4(x1) + sw x17, 17*4(x1) + sw x28, 28*4(x1) + sw x29, 29*4(x1) + sw x30, 30*4(x1) + sw x31, 31*4(x1) +#else + sw x3, 3*4(x1) + sw x4, 4*4(x1) + sw x5, 5*4(x1) + sw x6, 6*4(x1) + sw x7, 7*4(x1) + sw x8, 8*4(x1) + sw x9, 9*4(x1) + sw x10, 10*4(x1) + sw x11, 11*4(x1) + sw x12, 12*4(x1) + sw x13, 13*4(x1) + sw x14, 14*4(x1) + sw x15, 15*4(x1) + sw x16, 16*4(x1) + sw x17, 17*4(x1) + sw x18, 18*4(x1) + sw x19, 19*4(x1) + sw x20, 20*4(x1) + sw x21, 21*4(x1) + sw x22, 22*4(x1) + sw x23, 23*4(x1) + sw x24, 24*4(x1) + sw x25, 25*4(x1) + sw x26, 26*4(x1) + sw x27, 27*4(x1) + sw x28, 28*4(x1) + sw x29, 29*4(x1) + sw x30, 30*4(x1) + sw x31, 31*4(x1) +#endif + + + + /* call interrupt handler C function */ + + lui sp, %hi(irq_stack) + addi sp, sp, %lo(irq_stack) + + // arg0 = address of regs + lui a0, %hi(irq_regs) + addi a0, a0, %lo(irq_regs) + + // arg1 = interrupt type + picorv32_getq_insn(a1, q1) + + + // call to C function + # jal ra, irq + + /* restore registers */ + + // new irq_regs address returned from C code in a0 + addi x1, a0, 0 + + lw x2, 0*4(x1) + picorv32_setq_insn(q0, x2) + + lw x2, 1*4(x1) + picorv32_setq_insn(q1, x2) + + lw x2, 2*4(x1) + picorv32_setq_insn(q2, x2) + +#ifdef ENABLE_FASTIRQ + lw x5, 5*4(x1) + lw x6, 6*4(x1) + lw x7, 7*4(x1) + lw x10, 10*4(x1) + lw x11, 11*4(x1) + lw x12, 12*4(x1) + lw x13, 13*4(x1) + lw x14, 14*4(x1) + lw x15, 15*4(x1) + lw x16, 16*4(x1) + lw x17, 17*4(x1) + lw x28, 28*4(x1) + lw x29, 29*4(x1) + lw x30, 30*4(x1) + lw x31, 31*4(x1) +#else + lw x3, 3*4(x1) + lw x4, 4*4(x1) + lw x5, 5*4(x1) + lw x6, 6*4(x1) + lw x7, 7*4(x1) + lw x8, 8*4(x1) + lw x9, 9*4(x1) + lw x10, 10*4(x1) + lw x11, 11*4(x1) + lw x12, 12*4(x1) + lw x13, 13*4(x1) + lw x14, 14*4(x1) + lw x15, 15*4(x1) + lw x16, 16*4(x1) + lw x17, 17*4(x1) + lw x18, 18*4(x1) + lw x19, 19*4(x1) + lw x20, 20*4(x1) + lw x21, 21*4(x1) + lw x22, 22*4(x1) + lw x23, 23*4(x1) + lw x24, 24*4(x1) + lw x25, 25*4(x1) + lw x26, 26*4(x1) + lw x27, 27*4(x1) + lw x28, 28*4(x1) + lw x29, 29*4(x1) + lw x30, 30*4(x1) + lw x31, 31*4(x1) +#endif + + picorv32_getq_insn(x1, q1) + picorv32_getq_insn(x2, q2) + + picorv32_retirq_insn() + + +.balign 0x200 +irq_regs: + // registers are saved to this memory region during interrupt handling + // the program counter is saved as register 0 + .fill 32,4 + + // stack for the interrupt handler + .fill 128,4 +irq_stack: + + + + + + + + + + + + + + + + + + + _prog_start: li x1, 0 @@ -35,18 +227,8 @@ _prog_start: li x30,0 li x31,0 - # li t0, 0xffff - # csrc mie, t0 - - # li t0, 0xa - # csrc mstatus, t0 - li sp, 0x80010000 - # la t0, trap_entry - # csrw mtvec, t0 - - call main @@ -91,7 +273,7 @@ trap_entry: # csrr a0, mcause # csrr a1, mepc mv a2, sp - jal handle_trap + # jal handle_trap # csrw mepc, a0