moved lock to cfg address space

This commit is contained in:
Polprzewodnikowy 2022-08-30 15:52:55 +02:00
parent 30f0fc002e
commit dbf4b5e3c8
9 changed files with 103 additions and 138 deletions

View File

@ -42,9 +42,6 @@
<Source name="../../rtl/n64/n64_flashram.sv" type="Verilog" type_short="Verilog">
<Options VerilogStandard="System Verilog"/>
</Source>
<Source name="../../rtl/n64/n64_lock.sv" type="Verilog" type_short="Verilog">
<Options VerilogStandard="System Verilog"/>
</Source>
<Source name="../../rtl/n64/n64_pi.sv" type="Verilog" type_short="Verilog">
<Options VerilogStandard="System Verilog"/>
</Source>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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),

View File

@ -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,

View File

@ -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),

View File

@ -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;

View File

@ -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) {