From dbf4b5e3c8d227e9cc063f7423eca84e1afac9c0 Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Tue, 30 Aug 2022 15:52:55 +0200 Subject: [PATCH] moved lock to cfg address space --- fw/project/lcmxo2/sc64.ldf | 3 - fw/rtl/n64/n64_cfg.sv | 113 ++++++++++++++++++++++++++++--------- fw/rtl/n64/n64_lock.sv | 52 ----------------- fw/rtl/n64/n64_pi.sv | 18 ++---- fw/rtl/n64/n64_reg_bus.sv | 14 ----- fw/rtl/n64/n64_scb.sv | 9 +-- fw/rtl/n64/n64_top.sv | 9 --- sw/bootloader/src/io.h | 14 ++--- sw/bootloader/src/sc64.c | 9 +-- 9 files changed, 103 insertions(+), 138 deletions(-) delete mode 100644 fw/rtl/n64/n64_lock.sv diff --git a/fw/project/lcmxo2/sc64.ldf b/fw/project/lcmxo2/sc64.ldf index 7b10953..9bdab48 100644 --- a/fw/project/lcmxo2/sc64.ldf +++ b/fw/project/lcmxo2/sc64.ldf @@ -42,9 +42,6 @@ - - - diff --git a/fw/rtl/n64/n64_cfg.sv b/fw/rtl/n64/n64_cfg.sv index 3b13546..70dd91f 100644 --- a/fw/rtl/n64/n64_cfg.sv +++ b/fw/rtl/n64/n64_cfg.sv @@ -9,7 +9,7 @@ module n64_cfg ( output logic irq ); - typedef enum bit [2:0] { + typedef enum bit [3:0] { REG_STATUS, REG_COMMAND, REG_DATA_0_H, @@ -17,61 +17,118 @@ module n64_cfg ( REG_DATA_1_H, REG_DATA_1_L, REG_VERSION_H, - REG_VERSION_L + REG_VERSION_L, + REG_KEY_H, + REG_KEY_L } e_reg; logic cfg_error; always_comb begin reg_bus.rdata = 16'd0; - if (reg_bus.address[16] && (reg_bus.address[15:4] == 12'd0)) begin - case (reg_bus.address[3:1]) + if (reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin + case (reg_bus.address[4:1]) REG_STATUS: reg_bus.rdata = { n64_scb.cfg_pending, cfg_error, 14'd0 }; + REG_COMMAND: reg_bus.rdata = {8'd0, n64_scb.cfg_cmd}; REG_DATA_0_H: reg_bus.rdata = n64_scb.cfg_wdata[0][31:16]; REG_DATA_0_L: reg_bus.rdata = n64_scb.cfg_wdata[0][15:0]; REG_DATA_1_H: reg_bus.rdata = n64_scb.cfg_wdata[1][31:16]; REG_DATA_1_L: reg_bus.rdata = n64_scb.cfg_wdata[1][15:0]; REG_VERSION_H: reg_bus.rdata = n64_scb.cfg_version[31:16]; REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0]; + REG_KEY_H: reg_bus.rdata = 16'd0; + REG_KEY_L: reg_bus.rdata = 16'd0; endcase end end + logic unlock_flag; + logic lock_sequence_counter; + always_ff @(posedge clk) begin + if (n64_scb.cfg_done) begin + n64_scb.cfg_pending <= 1'b0; + cfg_error <= n64_scb.cfg_error; + end + + if (n64_scb.cfg_irq) begin + irq <= 1'b1; + end + + if (unlock_flag) begin + n64_scb.cfg_unlock <= 1'b1; + end + if (reset || n64_scb.n64_reset) begin n64_scb.cfg_pending <= 1'b0; n64_scb.cfg_cmd <= 8'h00; irq <= 1'b0; cfg_error <= 1'b0; - end else begin - if (n64_scb.cfg_done) begin - n64_scb.cfg_pending <= 1'b0; - cfg_error <= n64_scb.cfg_error; - end - - if (n64_scb.cfg_irq) begin - irq <= 1'b1; - end - - if (reg_bus.write) begin - if (reg_bus.address[16] && (reg_bus.address[15:4] == 12'd0)) begin - case (reg_bus.address[3:1]) - REG_COMMAND: begin - n64_scb.cfg_pending <= 1'b1; - n64_scb.cfg_cmd <= reg_bus.wdata[7:0]; - cfg_error <= 1'b0; + lock_sequence_counter <= 1'd0; + end else if (n64_scb.cfg_unlock) begin + if (reg_bus.write && reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin + case (reg_bus.address[4:1]) + REG_COMMAND: begin + n64_scb.cfg_pending <= 1'b1; + n64_scb.cfg_cmd <= reg_bus.wdata[7:0]; + cfg_error <= 1'b0; + end + REG_DATA_0_H: n64_scb.cfg_rdata[0][31:16] <= reg_bus.wdata; + REG_DATA_0_L: n64_scb.cfg_rdata[0][15:0] <= reg_bus.wdata; + REG_DATA_1_H: n64_scb.cfg_rdata[1][31:16] <= reg_bus.wdata; + REG_DATA_1_L: n64_scb.cfg_rdata[1][15:0] <= reg_bus.wdata; + REG_VERSION_L: irq <= 1'b0; + REG_KEY_H, REG_KEY_L: begin + lock_sequence_counter <= lock_sequence_counter + 1'd1; + if (reg_bus.wdata != 16'hFFFF) begin + lock_sequence_counter <= 1'd0; end - REG_DATA_0_H: n64_scb.cfg_rdata[0][31:16] <= reg_bus.wdata; - REG_DATA_0_L: n64_scb.cfg_rdata[0][15:0] <= reg_bus.wdata; - REG_DATA_1_H: n64_scb.cfg_rdata[1][31:16] <= reg_bus.wdata; - REG_DATA_1_L: n64_scb.cfg_rdata[1][15:0] <= reg_bus.wdata; - REG_VERSION_L: irq <= 1'b0; - endcase - end + if (lock_sequence_counter == 1'd1) begin + n64_scb.cfg_unlock <= (reg_bus.wdata != 16'hFFFF); + end + end + endcase + end + end + end + + const bit [15:0] UNLOCK_SEQUENCE [4] = { + 16'h5F55, + 16'h4E4C, + 16'h4F43, + 16'h4B5F + }; + + logic [1:0] unlock_sequence_counter; + + always_ff @(posedge clk) begin + unlock_flag <= 1'b0; + + if (reset || n64_scb.n64_reset || n64_scb.n64_nmi) begin + unlock_sequence_counter <= 2'd0; + end else if (!n64_scb.cfg_unlock) begin + if (reg_bus.write && reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin + case (reg_bus.address[4:1]) + REG_KEY_H, REG_KEY_L: begin + for (int index = 0; index < $size(UNLOCK_SEQUENCE); index++) begin + if (index == unlock_sequence_counter) begin + if (reg_bus.wdata == UNLOCK_SEQUENCE[index]) begin + unlock_sequence_counter <= unlock_sequence_counter + 1'd1; + if (index == ($size(UNLOCK_SEQUENCE) - 1'd1)) begin + unlock_flag <= 1'b1; + unlock_sequence_counter <= 2'd0; + end + end else begin + unlock_sequence_counter <= 2'd0; + end + end + end + end + endcase end end end diff --git a/fw/rtl/n64/n64_lock.sv b/fw/rtl/n64/n64_lock.sv deleted file mode 100644 index 5679260..0000000 --- a/fw/rtl/n64/n64_lock.sv +++ /dev/null @@ -1,52 +0,0 @@ -module n64_lock ( - input clk, - input reset, - - n64_reg_bus.lock reg_bus, - - n64_scb.lock n64_scb, -); - - const bit [15:0] UNLOCK_SEQUENCE [4] = { - 16'h5F55, - 16'h4E4C, - 16'h4F43, - 16'h4B5F - }; - - always_comb begin - reg_bus.rdata = 16'd0; - end - - logic [1:0] sequence_counter; - - always_ff @(posedge clk) begin - if (reset || n64_scb.n64_reset || n64_scb.n64_nmi) begin - n64_scb.cfg_unlock <= 1'b0; - sequence_counter <= 2'd0; - end else begin - if (reg_bus.write) begin - if (reg_bus.address[16] && (reg_bus.address[15:2] == 14'd0)) begin - for (int i = 0; i < $size(UNLOCK_SEQUENCE); i++) begin - if (sequence_counter == i) begin - if (reg_bus.wdata == UNLOCK_SEQUENCE[i]) begin - sequence_counter <= sequence_counter + 1'd1; - if (i == ($size(UNLOCK_SEQUENCE) - 1'd1)) begin - n64_scb.cfg_unlock <= 1'b1; - sequence_counter <= 2'd0; - end - end else begin - n64_scb.cfg_unlock <= 1'b0; - sequence_counter <= 2'd0; - end - end - end - end else begin - n64_scb.cfg_unlock <= 1'b0; - sequence_counter <= 2'd0; - end - end - end - end - -endmodule diff --git a/fw/rtl/n64/n64_pi.sv b/fw/rtl/n64/n64_pi.sv index 924e750..176f49b 100644 --- a/fw/rtl/n64/n64_pi.sv +++ b/fw/rtl/n64/n64_pi.sv @@ -139,7 +139,6 @@ module n64_pi ( write_port <= PORT_NONE; reg_bus.dd_select <= 1'b0; reg_bus.flashram_select <= 1'b0; - reg_bus.lock_select <= 1'b0; reg_bus.cfg_select <= 1'b0; end else if (aleh_op) begin read_port <= PORT_NONE; @@ -147,7 +146,6 @@ module n64_pi ( mem_offset <= 32'd0; reg_bus.dd_select <= 1'b0; reg_bus.flashram_select <= 1'b0; - reg_bus.lock_select <= 1'b0; reg_bus.cfg_select <= 1'b0; if (n64_scb.dd_enabled) begin @@ -222,24 +220,18 @@ module n64_pi ( mem_offset <= (-32'h1400_0000) + FLASH_OFFSET; end - if (n64_pi_dq_in >= 16'h1FFD && n64_pi_dq_in < 16'h1FFE) begin - read_port <= PORT_NONE; - write_port <= PORT_REG; - reg_bus.lock_select <= 1'b1; - end - if (n64_scb.cfg_unlock) begin if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h1FFF) begin read_port <= PORT_MEM; write_port <= PORT_MEM; mem_offset <= (-32'h1FFE_0000) + BUFFER_OFFSET; end + end - if (n64_pi_dq_in >= 16'h1FFF && n64_pi_dq_in < 16'h2000) begin - read_port <= PORT_REG; - write_port <= PORT_REG; - reg_bus.cfg_select <= 1'b1; - end + if (n64_pi_dq_in >= 16'h1FFF && n64_pi_dq_in < 16'h2000) begin + read_port <= n64_scb.cfg_unlock ? PORT_REG : PORT_NONE; + write_port <= PORT_REG; + reg_bus.cfg_select <= 1'b1; end end end diff --git a/fw/rtl/n64/n64_reg_bus.sv b/fw/rtl/n64/n64_reg_bus.sv index 969edd5..07573b7 100644 --- a/fw/rtl/n64/n64_reg_bus.sv +++ b/fw/rtl/n64/n64_reg_bus.sv @@ -2,7 +2,6 @@ interface n64_reg_bus (); logic flashram_select; logic dd_select; - logic lock_select; logic cfg_select; logic read; @@ -13,14 +12,12 @@ interface n64_reg_bus (); logic [15:0] flashram_rdata; logic [15:0] dd_rdata; - logic [15:0] lock_rdata; logic [15:0] cfg_rdata; modport controller ( output flashram_select, output dd_select, output cfg_select, - output lock_select, output read, output write, @@ -37,9 +34,6 @@ interface n64_reg_bus (); if (dd_select) begin rdata = dd_rdata; end - if (lock_select) begin - rdata = lock_rdata; - end if (cfg_select) begin rdata = cfg_rdata; end @@ -61,14 +55,6 @@ interface n64_reg_bus (); input wdata ); - modport lock ( - input .read(read && lock_select), - input .write(write && lock_select), - input address, - output .rdata(lock_rdata), - input wdata - ); - modport cfg ( input .read(read && cfg_select), input .write(write && cfg_select), diff --git a/fw/rtl/n64/n64_scb.sv b/fw/rtl/n64/n64_scb.sv index 9cf6d3f..bdb9aa1 100644 --- a/fw/rtl/n64/n64_scb.sv +++ b/fw/rtl/n64/n64_scb.sv @@ -161,16 +161,11 @@ interface n64_scb (); input dd_wdata ); - modport lock ( + modport cfg ( input n64_reset, input n64_nmi, - output cfg_unlock - ); - - modport cfg ( - input n64_reset, - + output cfg_unlock, output cfg_pending, input cfg_done, input cfg_error, diff --git a/fw/rtl/n64/n64_top.sv b/fw/rtl/n64/n64_top.sv index f6fd911..c63eafc 100644 --- a/fw/rtl/n64/n64_top.sv +++ b/fw/rtl/n64/n64_top.sv @@ -67,15 +67,6 @@ module n64_top ( .n64_scb(n64_scb) ); - n64_lock n64_lock_inst ( - .clk(clk), - .reset(reset), - - .reg_bus(reg_bus), - - .n64_scb(n64_scb) - ); - n64_cfg n64_cfg_inst ( .clk(clk), .reset(reset), diff --git a/sw/bootloader/src/io.h b/sw/bootloader/src/io.h index 512a4ea..b1435ad 100644 --- a/sw/bootloader/src/io.h +++ b/sw/bootloader/src/io.h @@ -225,14 +225,6 @@ typedef struct { #define PIFRAM ((io8_t *) PIFRAM_BASE) -typedef struct { - io32_t KEY; -} sc64_lock_t; - -#define SC64_LOCK_BASE (0x1FFD0000UL) -#define SC64_LOCK ((sc64_lock_t *) SC64_LOCK_BASE) - - typedef struct { io8_t BUFFER[8192]; io8_t EEPROM[2048]; @@ -248,6 +240,7 @@ typedef struct { io32_t SR_CMD; io32_t DATA[2]; io32_t VERSION; + io32_t KEY; } sc64_regs_t; #define SC64_REGS_BASE (0x1FFF0000UL) @@ -256,6 +249,11 @@ typedef struct { #define SC64_SR_CMD_ERROR (1 << 30) #define SC64_SR_CPU_BUSY (1 << 31) +#define SC64_KEY_RESET (0x00000000UL) +#define SC64_KEY_UNLOCK_1 (0x5F554E4CUL) +#define SC64_KEY_UNLOCK_2 (0x4F434B5FUL) +#define SC64_KEY_LOCK (0xFFFFFFFFUL) + typedef struct { uint32_t tv_type; diff --git a/sw/bootloader/src/sc64.c b/sw/bootloader/src/sc64.c index ce2a047..e601146 100644 --- a/sw/bootloader/src/sc64.c +++ b/sw/bootloader/src/sc64.c @@ -41,13 +41,14 @@ static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) { } void sc64_unlock (void) { - pi_io_write(&SC64_LOCK->KEY, 0x00000000); - pi_io_write(&SC64_LOCK->KEY, 0x5F554E4C); - pi_io_write(&SC64_LOCK->KEY, 0x4F434B5F); + pi_io_write(&SC64_REGS->KEY, SC64_KEY_RESET); + pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_1); + pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_2); } void sc64_lock (void) { - pi_io_write(&SC64_LOCK->KEY, 0x00000000); + pi_io_write(&SC64_REGS->KEY, SC64_KEY_RESET); + pi_io_write(&SC64_REGS->KEY, SC64_KEY_LOCK); } bool sc64_check_presence (void) {