diff options
Diffstat (limited to 'rtl')
| -rw-r--r-- | rtl/gfx/firmware/custom_ops.S | 103 | ||||
| -rw-r--r-- | rtl/gfx/firmware/gfx_bootrom.S | 76 | ||||
| -rw-r--r-- | rtl/gfx/gfx_bootrom.sv | 2 | ||||
| -rw-r--r-- | rtl/gfx/gfx_top.sv | 3 | ||||
| -rw-r--r-- | rtl/gfx/gfx_xbar_sched.sv | 36 |
5 files changed, 210 insertions, 10 deletions
diff --git a/rtl/gfx/firmware/custom_ops.S b/rtl/gfx/firmware/custom_ops.S new file mode 100644 index 0000000..95a2f53 --- /dev/null +++ b/rtl/gfx/firmware/custom_ops.S @@ -0,0 +1,103 @@ +// 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/rtl/gfx/firmware/gfx_bootrom.S b/rtl/gfx/firmware/gfx_bootrom.S new file mode 100644 index 0000000..bf7bd7d --- /dev/null +++ b/rtl/gfx/firmware/gfx_bootrom.S @@ -0,0 +1,76 @@ +#include "custom_ops.S" + +.text + +.global _start +_start: + + li a0, 0x00300000 # HOST_CTRL_BASE + li a1, 1 << 1 | 1 << 0 # ARINT | AWINT + li a2, 1 << 0 # B.VALID = 1 + li a3, 0x8 # Firmware handover word + la a4, .read_data + li a5, 1 << 11 | 1 << 9 # CTRL.WVALID | CTRL.AWVALID + li a6, 1 << 12 # CTRL.BDONE, doesn't fit in andi + + sw a1, 0(a0) + +.wait_axi: + picorv32_waitirq_insn(zero) + + lw t0, 0(a0) + andi t1, t0, 1 << 8 # ARVALID + bne t1, zero, .read + and t0, t0, a5 + beq t0, a5, .write + j .wait_axi + +.read: + lw t0, 4(a0) + andi t1, t0, 1 << 0 # AW.VALID + beq t1, zero, .wait_axi + andi t0, t0, 0b11 << 2 + add t0, a4, t0 + lw t0, 0(t0) + sw t0, 12(a0) # R.DATA + +.read_done: + lw t0, 0(a0) + andi t0, t0, 1 << 10 # CTRL.RDONE + beq t0, zero, .read_done + j .wait_axi + +.write: + lw t0, 8(a0) + andi t1, t0, 1 << 0 # AW.VALID + beq t1, zero, .wait_axi + lw t1, 16(a0) + sw a2, 20(a0) + +.write_done: + lw t2, 0(a0) + and t2, t2, a6 + beq t2, zero, .write_done + + andi t0, t0, ~0b11 + bne t0, a3, .wait_axi + sw zero, 0(a0) + # Pass magic & hardware version + lw a0, 0(a4) + lw a1, 4(a4) + jalr t1 + j . + +.balign 4 + +.read_data: + # Magic + .word 0x4a7a7b0c + # Hardware major.minor.patch + .word 1 << 16 | 0 << 8 | 0 << 0 + # Firmware yyyy.mm.dd.build + .word 2024 << 18 | 5 << 15 | 12 << 10 | 1 << 0 + # Register map version, rev 0 means this is the bootrom firmware + .word 0 + +.balign 4 diff --git a/rtl/gfx/gfx_bootrom.sv b/rtl/gfx/gfx_bootrom.sv index a8f3b74..5a45da4 100644 --- a/rtl/gfx/gfx_bootrom.sv +++ b/rtl/gfx/gfx_bootrom.sv @@ -7,7 +7,7 @@ import gfx::*; if_axil.s axis ); - localparam ROM_WORDS_LOG = 8; + localparam ROM_WORDS_LOG = 7; enum int unsigned { diff --git a/rtl/gfx/gfx_top.sv b/rtl/gfx/gfx_top.sv index 5f58edd..93e3ad9 100644 --- a/rtl/gfx/gfx_top.sv +++ b/rtl/gfx/gfx_top.sv @@ -63,7 +63,8 @@ import gfx::*; .debug(debug_axi.m), .bootrom(bootrom_axi.m), - .shader_0(shader_0_axi.m) + .shader_0(shader_0_axi.m), + .host_ctrl(host_ctrl_axi.m) ); /*TODO diff --git a/rtl/gfx/gfx_xbar_sched.sv b/rtl/gfx/gfx_xbar_sched.sv index 5661012..32305cd 100644 --- a/rtl/gfx/gfx_xbar_sched.sv +++ b/rtl/gfx/gfx_xbar_sched.sv @@ -7,28 +7,34 @@ import gfx::*; if_axil.s sched, if_axil.m debug, - if_axil.m bootrom, - if_axil.m shader_0 + bootrom, + shader_0, + host_ctrl ); - localparam word BOOTROM_MASK = 32'hfff0_0000; - localparam word DEBUG_BASE = 32'h0020_0000; - localparam word DEBUG_MASK = 32'hfff0_0000; - localparam word SHADER_0_BASE = 32'h0100_0000; - localparam word SHADER_0_MASK = 32'hfff0_0000; + localparam word + BOOTROM_MASK = 32'hfff0_0000, + DEBUG_BASE = 32'h0020_0000, + DEBUG_MASK = 32'hfff0_0000, + HOST_CTRL_BASE = 32'h0030_0000, + HOST_CTRL_MASK = 32'hfff0_0000, + SHADER_0_BASE = 32'h0100_0000, + SHADER_0_MASK = 32'hfff0_0000; defparam xbar.NM = 1; - defparam xbar.NS = 3; + defparam xbar.NS = 4; defparam xbar.OPT_LOWPOWER = 0; defparam xbar.SLAVE_ADDR = { SHADER_0_BASE, + HOST_CTRL_BASE, DEBUG_BASE, BOOTROM_BASE }; defparam xbar.SLAVE_MASK = { SHADER_0_MASK, + HOST_CTRL_MASK, DEBUG_MASK, BOOTROM_MASK }; @@ -64,34 +70,40 @@ import gfx::*; .M_AXI_AWADDR({ shader_0.awaddr, + host_ctrl.awaddr, debug.awaddr, bootrom.awaddr }), .M_AXI_AWPROT(), .M_AXI_AWVALID({ shader_0.awvalid, + host_ctrl.awvalid, debug.awvalid, bootrom.awvalid }), .M_AXI_AWREADY({ shader_0.awready, + host_ctrl.awready, debug.awready, bootrom.awready }), .M_AXI_WDATA({ shader_0.wdata, + host_ctrl.wdata, debug.wdata, bootrom.wdata }), .M_AXI_WSTRB(), .M_AXI_WVALID({ shader_0.wvalid, + host_ctrl.wvalid, debug.wvalid, bootrom.wvalid }), .M_AXI_WREADY({ shader_0.wready, + host_ctrl.wready, debug.wready, bootrom.wready }), @@ -99,45 +111,53 @@ import gfx::*; .M_AXI_BRESP('0), .M_AXI_BVALID({ shader_0.bvalid, + host_ctrl.bvalid, debug.bvalid, bootrom.bvalid }), .M_AXI_BREADY({ shader_0.bready, + host_ctrl.bready, debug.bready, bootrom.bready }), .M_AXI_ARADDR({ shader_0.araddr, + host_ctrl.araddr, debug.araddr, bootrom.araddr }), .M_AXI_ARPROT(), .M_AXI_ARVALID({ shader_0.arvalid, + host_ctrl.arvalid, debug.arvalid, bootrom.arvalid }), .M_AXI_ARREADY({ shader_0.arready, + host_ctrl.arready, debug.arready, bootrom.arready }), .M_AXI_RDATA({ shader_0.rdata, + host_ctrl.rdata, debug.rdata, bootrom.rdata }), .M_AXI_RRESP('0), .M_AXI_RVALID({ shader_0.rvalid, + host_ctrl.rvalid, debug.rvalid, bootrom.rvalid }), .M_AXI_RREADY({ shader_0.rready, + host_ctrl.rready, debug.rready, bootrom.rready }) |
