汇编模式建立
This commit is contained in:
24
Makefile
24
Makefile
@@ -60,25 +60,29 @@ test:
|
|||||||
|
|
||||||
|
|
||||||
sw:
|
sw:
|
||||||
riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs \
|
# 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 \
|
# -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 \
|
# -c ./tb/sw/src/main.c \
|
||||||
-o ./tb/sw/build/main.o
|
# -o ./tb/sw/build/main.o
|
||||||
|
|
||||||
riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs \
|
# 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 \
|
# -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 \
|
# -c ./tb/sw/axi_uart/uart.c \
|
||||||
-o ./tb/sw/build/uart.o
|
# -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 \
|
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 \
|
-c ./tb/sw/src/startup.S \
|
||||||
-o ./tb/sw/build/startup.o
|
-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 \
|
riscv64-unknown-elf-gcc -Os -ggdb -march=rv32i -mabi=ilp32 -Wall -mcmodel=medany -mexplicit-relocs -nostdlib -nodefaultlibs -nostartfiles \
|
||||||
-T ./tb/sw/linker.lds \
|
-T ./tb/sw/linker.lds \
|
||||||
./tb/sw/build/startup.o \
|
./tb/sw/build/startup.o \
|
||||||
./tb/sw/build/uart.o \
|
|
||||||
./tb/sw/build/main.o \
|
./tb/sw/build/main.o \
|
||||||
-o ./tb/sw/build/test.elf
|
-o ./tb/sw/build/test.elf
|
||||||
|
|
||||||
|
|||||||
102
tb/sw/src/custom_ops.S
Normal file
102
tb/sw/src/custom_ops.S
Normal file
@@ -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)
|
||||||
|
|
||||||
47
tb/sw/src/main.S
Normal file
47
tb/sw/src/main.S
Normal file
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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:
|
_prog_start:
|
||||||
|
|
||||||
li x1, 0
|
li x1, 0
|
||||||
@@ -35,18 +227,8 @@ _prog_start:
|
|||||||
li x30,0
|
li x30,0
|
||||||
li x31,0
|
li x31,0
|
||||||
|
|
||||||
# li t0, 0xffff
|
|
||||||
# csrc mie, t0
|
|
||||||
|
|
||||||
# li t0, 0xa
|
|
||||||
# csrc mstatus, t0
|
|
||||||
|
|
||||||
li sp, 0x80010000
|
li sp, 0x80010000
|
||||||
|
|
||||||
# la t0, trap_entry
|
|
||||||
# csrw mtvec, t0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
@@ -91,7 +273,7 @@ trap_entry:
|
|||||||
# csrr a0, mcause
|
# csrr a0, mcause
|
||||||
# csrr a1, mepc
|
# csrr a1, mepc
|
||||||
mv a2, sp
|
mv a2, sp
|
||||||
jal handle_trap
|
# jal handle_trap
|
||||||
# csrw mepc, a0
|
# csrw mepc, a0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user