From a22f2efa87b85bad82679d74fe9f5ece94edc5e3 Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Sat, 22 Jan 2022 23:19:07 +0100 Subject: [PATCH] ISV in hardware finally --- fw/rtl/cpu/cpu_cfg.sv | 35 ++++++++++++++--- fw/rtl/n64/n64_bootloader.sv | 2 +- fw/rtl/n64/n64_cfg.sv | 58 +++++++++++++++++++-------- fw/rtl/n64/n64_pi.sv | 36 ++++++++++++----- fw/rtl/system/config.sv | 15 +++++-- sw/pc/sc64.py | 2 - sw/riscv/src/isv.c | 76 ++++++++++++++++-------------------- sw/riscv/src/sys.h | 5 ++- 8 files changed, 148 insertions(+), 81 deletions(-) diff --git a/fw/rtl/cpu/cpu_cfg.sv b/fw/rtl/cpu/cpu_cfg.sv index 9686bb2..dcbcb18 100644 --- a/fw/rtl/cpu/cpu_cfg.sv +++ b/fw/rtl/cpu/cpu_cfg.sv @@ -6,8 +6,9 @@ module cpu_cfg ( logic skip_bootloader; logic trigger_reconfiguration; + logic [15:0] isv_current_rd_ptr; - typedef enum bit [2:0] { + typedef enum bit [3:0] { R_SCR, R_DDIPL_OFFSET, R_SAVE_OFFSET, @@ -15,7 +16,9 @@ module cpu_cfg ( R_DATA_0, R_DATA_1, R_VERSION, - R_RECONFIGURE + R_RECONFIGURE, + R_ISV_OFFSET, + R_ISV_RD_PTR } e_reg_id; const logic [31:0] RECONFIGURE_MAGIC = 32'h52535446; @@ -30,13 +33,14 @@ module cpu_cfg ( always_comb begin bus.rdata = 32'd0; if (bus.ack) begin - case (bus.address[4:2]) + case (bus.address[5:2]) R_SCR: bus.rdata = { cfg.cpu_ready, cfg.cpu_busy, 1'b0, cfg.cmd_error, - 21'd0, + 20'd0, + cfg.isv_enabled, skip_bootloader, cfg.flashram_enabled, cfg.sram_banked, @@ -52,6 +56,8 @@ module cpu_cfg ( R_DATA_1: bus.rdata = cfg.data[1]; R_VERSION: bus.rdata = sc64::SC64_VER; R_RECONFIGURE: bus.rdata = RECONFIGURE_MAGIC; + R_ISV_OFFSET: bus.rdata = {6'd0, cfg.isv_offset}; + R_ISV_RD_PTR: bus.rdata = {isv_current_rd_ptr, cfg.isv_rd_ptr}; default: bus.rdata = 32'd0; endcase end @@ -77,19 +83,23 @@ module cpu_cfg ( cfg.sram_enabled <= 1'b0; cfg.sram_banked <= 1'b0; cfg.flashram_enabled <= 1'b0; + cfg.isv_enabled <= 1'b0; cfg.ddipl_offset <= 26'h3BE_0000; cfg.save_offset <= 26'h3FE_0000; + cfg.isv_offset <= 26'h3FF_0000; skip_bootloader <= 1'b0; trigger_reconfiguration <= 1'b0; end else begin if (sys.n64_soft_reset) begin cfg.sdram_switch <= skip_bootloader; + cfg.sdram_writable <= 1'b0; + isv_current_rd_ptr <= 16'd0; end if (cfg.cmd_request) begin cfg.cpu_busy <= 1'b1; end if (bus.request) begin - case (bus.address[4:2]) + case (bus.address[5:2]) R_SCR: begin if (bus.wmask[3]) begin { @@ -100,6 +110,7 @@ module cpu_cfg ( end if (bus.wmask[0]) begin { + cfg.isv_enabled, skip_bootloader, cfg.flashram_enabled, cfg.sram_banked, @@ -107,7 +118,7 @@ module cpu_cfg ( cfg.dd_enabled, cfg.sdram_writable, cfg.sdram_switch - } <= bus.wdata[6:0]; + } <= bus.wdata[7:0]; end end @@ -128,6 +139,18 @@ module cpu_cfg ( trigger_reconfiguration <= 1'b1; end end + + R_ISV_OFFSET: begin + if (&bus.wmask) begin + cfg.isv_offset <= bus.wdata[25:0]; + end + end + + R_ISV_RD_PTR: begin + if (&bus.wmask[3:2]) begin + isv_current_rd_ptr <= bus.wdata[31:16]; + end + end endcase end end diff --git a/fw/rtl/n64/n64_bootloader.sv b/fw/rtl/n64/n64_bootloader.sv index 76565a4..f513efb 100644 --- a/fw/rtl/n64/n64_bootloader.sv +++ b/fw/rtl/n64/n64_bootloader.sv @@ -89,7 +89,7 @@ module n64_bootloader ( bus.ack = source_request == T_N64 && data_ack; bus.rdata = 16'd0; - if (bus.ack && bus.address >= 32'h10000000 && bus.address < 32'h10010000) begin + if (bus.ack && bus.address < 32'h00010000) begin if (bus.address[1]) bus.rdata = {data_rdata[23:16], data_rdata[31:24]}; else bus.rdata = {data_rdata[7:0], data_rdata[15:8]}; end diff --git a/fw/rtl/n64/n64_cfg.sv b/fw/rtl/n64/n64_cfg.sv index b26e970..74a07e0 100644 --- a/fw/rtl/n64/n64_cfg.sv +++ b/fw/rtl/n64/n64_cfg.sv @@ -5,7 +5,7 @@ module n64_cfg ( if_cpu_ram.external cpu_ram ); - typedef enum bit [3:0] { + typedef enum bit [2:0] { R_SR, R_COMMAND, R_DATA_0_H, @@ -16,6 +16,12 @@ module n64_cfg ( R_VERSION_L } e_reg_id; + typedef enum bit [3:0] { + R_ISV_ID_H = 4'h0, + R_ISV_ID_L = 4'h1, + R_ISV_RD_PTR = 4'hB + } e_reg_isv_id; + typedef enum bit [0:0] { S_IDLE, S_WAIT @@ -23,16 +29,16 @@ module n64_cfg ( e_state state; + logic [31:0] isv_id; + always_comb begin - cpu_ram.write = bus.request && bus.write && bus.address[14]; + cpu_ram.write = bus.request && bus.write && (bus.address[15:14] == 2'b01); cpu_ram.address = bus.address[13:1]; cpu_ram.wdata = {bus.wdata[7:0], bus.wdata[15:8]}; bus.rdata = 16'd0; if (bus.ack) begin - if (bus.address[14]) begin - bus.rdata = {cpu_ram.rdata[7:0], cpu_ram.rdata[15:8]}; - end else if (!(&bus.address[13:4])) begin + if (bus.address[15:14] == 2'b00) begin case (bus.address[3:1]) R_SR: bus.rdata = { cfg.cpu_ready, @@ -49,6 +55,14 @@ module n64_cfg ( R_VERSION_H: bus.rdata = sc64::SC64_VER[31:16]; R_VERSION_L: bus.rdata = sc64::SC64_VER[15:0]; endcase + end else if (bus.address[15:14] == 2'b01) begin + bus.rdata = {cpu_ram.rdata[7:0], cpu_ram.rdata[15:8]}; + end else if (bus.address[15:14] == 2'b11) begin + case (bus.address[4:1]) + R_ISV_ID_H: bus.rdata = isv_id[31:16]; + R_ISV_ID_L: bus.rdata = isv_id[15:0]; + R_ISV_RD_PTR: bus.rdata = cfg.isv_rd_ptr; + endcase end end end @@ -60,6 +74,10 @@ module n64_cfg ( if (cfg.data_write[0]) cfg.data[0] <= cfg.wdata; if (cfg.data_write[1]) cfg.data[1] <= cfg.wdata; + if (sys.n64_soft_reset) begin + cfg.isv_rd_ptr <= 16'd0; + end + if (sys.reset) begin state <= S_IDLE; end else begin @@ -68,17 +86,25 @@ module n64_cfg ( if (bus.request) begin state <= S_WAIT; bus.ack <= 1'b1; - if (bus.write && (!(&bus.address[14:4]))) begin - case (bus.address[3:1]) - R_COMMAND: begin - cfg.cmd <= bus.wdata[7:0]; - cfg.cmd_request <= 1'b1; - end - R_DATA_0_H: cfg.data[0][31:16] <= bus.wdata; - R_DATA_0_L: cfg.data[0][15:0] <= bus.wdata; - R_DATA_1_H: cfg.data[1][31:16] <= bus.wdata; - R_DATA_1_L: cfg.data[1][15:0] <= bus.wdata; - endcase + if (bus.write) begin + if (bus.address[15:14] == 2'b00) begin + case (bus.address[3:1]) + R_COMMAND: begin + cfg.cmd <= bus.wdata[7:0]; + cfg.cmd_request <= 1'b1; + end + R_DATA_0_H: cfg.data[0][31:16] <= bus.wdata; + R_DATA_0_L: cfg.data[0][15:0] <= bus.wdata; + R_DATA_1_H: cfg.data[1][31:16] <= bus.wdata; + R_DATA_1_L: cfg.data[1][15:0] <= bus.wdata; + endcase + end else if (bus.address[15:14] == 2'b11) begin + case (bus.address[4:1]) + R_ISV_ID_H: isv_id[31:16] <= bus.wdata; + R_ISV_ID_L: isv_id[15:0] <= bus.wdata; + R_ISV_RD_PTR: cfg.isv_rd_ptr <= bus.wdata; + endcase + end end end end diff --git a/fw/rtl/n64/n64_pi.sv b/fw/rtl/n64/n64_pi.sv index 407e9e7..8732cb2 100644 --- a/fw/rtl/n64/n64_pi.sv +++ b/fw/rtl/n64/n64_pi.sv @@ -211,27 +211,31 @@ module n64_pi ( // Address decoding + logic load_next; sc64::e_n64_id next_id; logic [31:0] next_offset; logic sram_selected; - logic cfg_selected; + logic isv_selected; always_ff @(posedge sys.clk) begin + load_next <= 1'b0; + if (aleh_op) begin n64_pi_address_valid <= 1'b0; next_id <= sc64::__ID_N64_END; next_offset <= 32'd0; sram_selected <= 1'b0; - cfg_selected <= 1'b0; + isv_selected <= 1'b0; if (cfg.dd_enabled) begin if (n64_pi_ad_input == 16'h0500) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_DD; + next_offset <= cfg.ddipl_offset - 32'h0500_0000; end if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_SDRAM; - next_offset <= cfg.ddipl_offset + 32'h0A00_0000; + next_offset <= cfg.ddipl_offset - 32'h0600_0000; end end if (cfg.flashram_enabled) begin @@ -239,7 +243,7 @@ module n64_pi ( n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_FLASHRAM; if (cfg.flashram_read_mode) begin - next_offset <= cfg.save_offset + 32'h0800_0000; + next_offset <= cfg.save_offset - 32'h0800_0000; end end end else if (cfg.sram_enabled) begin @@ -248,7 +252,7 @@ module n64_pi ( if (n64_pi_ad_input[3:2] != 2'b11 && n64_pi_ad_input[1:0] == 2'b00) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_SDRAM; - next_offset <= cfg.save_offset - {n64_pi_ad_input[3:2], 18'd0} + {n64_pi_ad_input[3:2], 15'd0} + 32'h0800_0000; + next_offset <= cfg.save_offset - {n64_pi_ad_input[3:2], 18'd0} + {n64_pi_ad_input[3:2], 15'd0} - 32'h0800_0000; sram_selected <= 1'b1; end end @@ -256,7 +260,7 @@ module n64_pi ( if (n64_pi_ad_input == 16'h0800) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_SDRAM; - next_offset <= cfg.save_offset + 32'h0800_0000; + next_offset <= cfg.save_offset - 32'h0800_0000; sram_selected <= 1'b1; end end @@ -264,11 +268,18 @@ module n64_pi ( if (n64_pi_ad_input >= 16'h1000 && n64_pi_ad_input < 16'h1400) begin n64_pi_address_valid <= 1'b1; next_id <= cfg.sdram_switch ? sc64::ID_N64_SDRAM : sc64::ID_N64_BOOTLOADER; + next_offset <= (-32'h1000_0000); + if (cfg.isv_enabled) begin + if (n64_pi_ad_input == 16'h13FF) begin + next_id <= sc64::ID_N64_SDRAM; + next_offset <= cfg.isv_offset - 32'h13FF_0000; + isv_selected <= 1'b1; + end + end end if (n64_pi_ad_input == 16'h1FFF) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_CFG; - cfg_selected <= 1'b1; end end if (alel_op) begin @@ -282,6 +293,13 @@ module n64_pi ( n64_pi_address_valid <= 1'b0; end end + if (isv_selected) begin + if (n64_pi_ad_input < 16'h0020) begin + next_offset <= (-32'h13FF_0000) + 32'h0000_C000; + next_id <= sc64::ID_N64_CFG; + end + end + load_next <= 1'b1; end end @@ -304,13 +322,13 @@ module n64_pi ( read_fifo_flush <= 1'b1; write_fifo_flush <= 1'b1; end else begin - write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected; + write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected && !isv_selected; if (aleh_op) begin starting_address[31:16] <= n64_pi_ad_input; end - if (alel_op) begin + if (load_next) begin read_fifo_flush <= 1'b1; can_read <= 1'b1; first_write_op <= 1'b1; diff --git a/fw/rtl/system/config.sv b/fw/rtl/system/config.sv index 4d5ddd0..0381415 100644 --- a/fw/rtl/system/config.sv +++ b/fw/rtl/system/config.sv @@ -15,8 +15,11 @@ interface if_config (); logic sram_banked; logic flashram_enabled; logic flashram_read_mode; + logic isv_enabled; logic [25:0] ddipl_offset; logic [25:0] save_offset; + logic [25:0] isv_offset; + logic [15:0] isv_rd_ptr; modport pi ( input sdram_switch, @@ -26,8 +29,10 @@ interface if_config (); input sram_banked, input flashram_enabled, input flashram_read_mode, + input isv_enabled, input ddipl_offset, - input save_offset + input save_offset, + input isv_offset ); modport flashram ( @@ -42,7 +47,8 @@ interface if_config (); output cmd, output data, input data_write, - input wdata + input wdata, + output isv_rd_ptr ); modport cpu ( @@ -60,8 +66,11 @@ interface if_config (); output sram_enabled, output sram_banked, output flashram_enabled, + output isv_enabled, output ddipl_offset, - output save_offset + output save_offset, + output isv_offset, + input isv_rd_ptr ); endinterface diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py index 1261e37..7a1b363 100644 --- a/sw/pc/sc64.py +++ b/sw/pc/sc64.py @@ -19,7 +19,6 @@ class SC64Exception(Exception): class SC64: - __CFG_ID_SDRAM_WRITABLE = 2 __CFG_ID_DD_ENABLE = 3 __CFG_ID_SAVE_TYPE = 4 __CFG_ID_CIC_SEED = 5 @@ -608,7 +607,6 @@ class SC64: def debug_loop(self, is_viewer_enabled: bool = False) -> None: - self.__change_config(self.__CFG_ID_SDRAM_WRITABLE, is_viewer_enabled) self.__change_config(self.__CFG_ID_IS_VIEWER_ENABLE, is_viewer_enabled) print("\r\n\033[34m --- Debug server started --- \033[0m\r\n") diff --git a/sw/riscv/src/isv.c b/sw/riscv/src/isv.c index 1163614..d6c1d97 100644 --- a/sw/riscv/src/isv.c +++ b/sw/riscv/src/isv.c @@ -2,73 +2,63 @@ #include "usb.h" -#define IS64_TOKEN (0x34365349) -#define IS64_OFFSET (SDRAM_BASE + 0x03FF0000) - - -typedef struct { - uint32_t ID; - uint32_t __padding_1[4]; - uint32_t RD_PTR; - uint32_t __padding_2[2]; - uint8_t BUFFER[(64 * 1024) - 0x20]; -} is_viewer_t; +#define ISV_REGS_SIZE (0x20) +#define ISV_BUFFER_SIZE ((64 * 1024) - ISV_REGS_SIZE) +#define ISV_DEFAULT_OFFSET (0x03FF0000UL) struct process { - bool enabled; bool ready; - uint32_t current_read_pointer; - is_viewer_t *ISV; }; -struct process p; +static struct process p; -void isv_set_enabled (bool enabled) { - p.enabled = enabled; +static void isv_set_ready (void) { p.ready = true; } +void isv_set_enabled (bool enabled) { + if (enabled) { + CFG->SCR |= CFG_SCR_ISV_EN; + p.ready = true; + } else { + CFG->SCR &= ~(CFG_SCR_ISV_EN); + } +} + bool isv_get_enabled (void) { - return p.enabled; + return (CFG->SCR & CFG_SCR_ISV_EN); } void isv_init (void) { - p.enabled = false; + CFG->ISV_OFFSET = ISV_DEFAULT_OFFSET; p.ready = true; - p.current_read_pointer = 0; - p.ISV = (is_viewer_t *) (IS64_OFFSET); } -void isv_set_ready (void) { - p.ready = true; -} void process_isv (void) { - if (!p.enabled || (p.ISV->ID != IS64_TOKEN)) { - p.current_read_pointer = 0; - p.ISV->RD_PTR = 0; - return; - } + if (p.ready && (CFG->SCR & CFG_SCR_ISV_EN)) { + uint16_t read_pointer = CFG->ISV_RD_PTR; + uint16_t current_read_pointer = CFG->ISV_CURRENT_RD_PTR; - uint32_t read_pointer = SWAP32(p.ISV->RD_PTR); + if (read_pointer != current_read_pointer) { + bool wrap = read_pointer < current_read_pointer; - if (p.ready && (read_pointer != p.current_read_pointer)) { - bool wrap = read_pointer < p.current_read_pointer; - uint32_t data[2] = { - ((wrap ? sizeof(p.ISV->BUFFER) : read_pointer) - p.current_read_pointer), - (uint32_t) (&p.ISV->BUFFER[p.current_read_pointer]), - }; + uint32_t length = ((wrap ? ISV_BUFFER_SIZE : read_pointer) - current_read_pointer); + uint32_t offset = CFG->ISV_OFFSET + ISV_REGS_SIZE + current_read_pointer; - usb_event_t event; - event.id = EVENT_ID_IS_VIEWER; - event.trigger = CALLBACK_SDRAM_READ; - event.callback = isv_set_ready; - if (usb_put_event(&event, data, sizeof(data))) { - p.ready = false; - p.current_read_pointer = wrap ? 0 : read_pointer; + usb_event_t event; + event.id = EVENT_ID_IS_VIEWER; + event.trigger = CALLBACK_SDRAM_READ; + event.callback = isv_set_ready; + uint32_t data[2] = { length, offset }; + + if (usb_put_event(&event, data, sizeof(data))) { + CFG->ISV_CURRENT_RD_PTR = wrap ? 0 : read_pointer; + p.ready = false; + } } } } diff --git a/sw/riscv/src/sys.h b/sw/riscv/src/sys.h index 380aafa..b6a9011 100644 --- a/sw/riscv/src/sys.h +++ b/sw/riscv/src/sys.h @@ -145,6 +145,9 @@ typedef volatile struct cfg_regs { io32_t DATA[2]; io32_t VERSION; io32_t RECONFIGURE; + io32_t ISV_OFFSET; + io16_t ISV_RD_PTR; + io16_t ISV_CURRENT_RD_PTR; } cfg_regs_t; #define CFG_BASE (0x70000000UL) @@ -157,8 +160,8 @@ typedef volatile struct cfg_regs { #define CFG_SCR_SRAM_BANKED (1 << 4) #define CFG_SCR_FLASHRAM_EN (1 << 5) #define CFG_SCR_SKIP_BOOTLOADER (1 << 6) +#define CFG_SCR_ISV_EN (1 << 7) #define CFG_SCR_CMD_ERROR (1 << 28) -#define CFG_SCR_USB_WAITING (1 << 29) #define CFG_SCR_CPU_BUSY (1 << 30) #define CFG_SCR_CPU_READY (1 << 31)