mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
moved lock to cfg address space
This commit is contained in:
parent
30f0fc002e
commit
dbf4b5e3c8
@ -42,9 +42,6 @@
|
|||||||
<Source name="../../rtl/n64/n64_flashram.sv" type="Verilog" type_short="Verilog">
|
<Source name="../../rtl/n64/n64_flashram.sv" type="Verilog" type_short="Verilog">
|
||||||
<Options VerilogStandard="System Verilog"/>
|
<Options VerilogStandard="System Verilog"/>
|
||||||
</Source>
|
</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">
|
<Source name="../../rtl/n64/n64_pi.sv" type="Verilog" type_short="Verilog">
|
||||||
<Options VerilogStandard="System Verilog"/>
|
<Options VerilogStandard="System Verilog"/>
|
||||||
</Source>
|
</Source>
|
||||||
|
@ -9,7 +9,7 @@ module n64_cfg (
|
|||||||
output logic irq
|
output logic irq
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef enum bit [2:0] {
|
typedef enum bit [3:0] {
|
||||||
REG_STATUS,
|
REG_STATUS,
|
||||||
REG_COMMAND,
|
REG_COMMAND,
|
||||||
REG_DATA_0_H,
|
REG_DATA_0_H,
|
||||||
@ -17,37 +17,39 @@ module n64_cfg (
|
|||||||
REG_DATA_1_H,
|
REG_DATA_1_H,
|
||||||
REG_DATA_1_L,
|
REG_DATA_1_L,
|
||||||
REG_VERSION_H,
|
REG_VERSION_H,
|
||||||
REG_VERSION_L
|
REG_VERSION_L,
|
||||||
|
REG_KEY_H,
|
||||||
|
REG_KEY_L
|
||||||
} e_reg;
|
} e_reg;
|
||||||
|
|
||||||
logic cfg_error;
|
logic cfg_error;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
reg_bus.rdata = 16'd0;
|
reg_bus.rdata = 16'd0;
|
||||||
if (reg_bus.address[16] && (reg_bus.address[15:4] == 12'd0)) begin
|
if (reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin
|
||||||
case (reg_bus.address[3:1])
|
case (reg_bus.address[4:1])
|
||||||
REG_STATUS: reg_bus.rdata = {
|
REG_STATUS: reg_bus.rdata = {
|
||||||
n64_scb.cfg_pending,
|
n64_scb.cfg_pending,
|
||||||
cfg_error,
|
cfg_error,
|
||||||
14'd0
|
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_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_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_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_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_H: reg_bus.rdata = n64_scb.cfg_version[31:16];
|
||||||
REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0];
|
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
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
logic unlock_flag;
|
||||||
|
logic lock_sequence_counter;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
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
|
if (n64_scb.cfg_done) begin
|
||||||
n64_scb.cfg_pending <= 1'b0;
|
n64_scb.cfg_pending <= 1'b0;
|
||||||
cfg_error <= n64_scb.cfg_error;
|
cfg_error <= n64_scb.cfg_error;
|
||||||
@ -57,9 +59,19 @@ module n64_cfg (
|
|||||||
irq <= 1'b1;
|
irq <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (reg_bus.write) begin
|
if (unlock_flag) begin
|
||||||
if (reg_bus.address[16] && (reg_bus.address[15:4] == 12'd0)) begin
|
n64_scb.cfg_unlock <= 1'b1;
|
||||||
case (reg_bus.address[3:1])
|
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;
|
||||||
|
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
|
REG_COMMAND: begin
|
||||||
n64_scb.cfg_pending <= 1'b1;
|
n64_scb.cfg_pending <= 1'b1;
|
||||||
n64_scb.cfg_cmd <= reg_bus.wdata[7:0];
|
n64_scb.cfg_cmd <= reg_bus.wdata[7:0];
|
||||||
@ -70,10 +82,55 @@ module n64_cfg (
|
|||||||
REG_DATA_1_H: n64_scb.cfg_rdata[1][31:16] <= 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_DATA_1_L: n64_scb.cfg_rdata[1][15:0] <= reg_bus.wdata;
|
||||||
REG_VERSION_L: irq <= 1'b0;
|
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
|
||||||
|
if (lock_sequence_counter == 1'd1) begin
|
||||||
|
n64_scb.cfg_unlock <= (reg_bus.wdata != 16'hFFFF);
|
||||||
|
end
|
||||||
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -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
|
|
@ -139,7 +139,6 @@ module n64_pi (
|
|||||||
write_port <= PORT_NONE;
|
write_port <= PORT_NONE;
|
||||||
reg_bus.dd_select <= 1'b0;
|
reg_bus.dd_select <= 1'b0;
|
||||||
reg_bus.flashram_select <= 1'b0;
|
reg_bus.flashram_select <= 1'b0;
|
||||||
reg_bus.lock_select <= 1'b0;
|
|
||||||
reg_bus.cfg_select <= 1'b0;
|
reg_bus.cfg_select <= 1'b0;
|
||||||
end else if (aleh_op) begin
|
end else if (aleh_op) begin
|
||||||
read_port <= PORT_NONE;
|
read_port <= PORT_NONE;
|
||||||
@ -147,7 +146,6 @@ module n64_pi (
|
|||||||
mem_offset <= 32'd0;
|
mem_offset <= 32'd0;
|
||||||
reg_bus.dd_select <= 1'b0;
|
reg_bus.dd_select <= 1'b0;
|
||||||
reg_bus.flashram_select <= 1'b0;
|
reg_bus.flashram_select <= 1'b0;
|
||||||
reg_bus.lock_select <= 1'b0;
|
|
||||||
reg_bus.cfg_select <= 1'b0;
|
reg_bus.cfg_select <= 1'b0;
|
||||||
|
|
||||||
if (n64_scb.dd_enabled) begin
|
if (n64_scb.dd_enabled) begin
|
||||||
@ -222,27 +220,21 @@ module n64_pi (
|
|||||||
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
||||||
end
|
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_scb.cfg_unlock) begin
|
||||||
if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h1FFF) begin
|
if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h1FFF) begin
|
||||||
read_port <= PORT_MEM;
|
read_port <= PORT_MEM;
|
||||||
write_port <= PORT_MEM;
|
write_port <= PORT_MEM;
|
||||||
mem_offset <= (-32'h1FFE_0000) + BUFFER_OFFSET;
|
mem_offset <= (-32'h1FFE_0000) + BUFFER_OFFSET;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if (n64_pi_dq_in >= 16'h1FFF && n64_pi_dq_in < 16'h2000) begin
|
if (n64_pi_dq_in >= 16'h1FFF && n64_pi_dq_in < 16'h2000) begin
|
||||||
read_port <= PORT_REG;
|
read_port <= n64_scb.cfg_unlock ? PORT_REG : PORT_NONE;
|
||||||
write_port <= PORT_REG;
|
write_port <= PORT_REG;
|
||||||
reg_bus.cfg_select <= 1'b1;
|
reg_bus.cfg_select <= 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
// Mem bus read FIFO controller
|
// Mem bus read FIFO controller
|
||||||
|
@ -2,7 +2,6 @@ interface n64_reg_bus ();
|
|||||||
|
|
||||||
logic flashram_select;
|
logic flashram_select;
|
||||||
logic dd_select;
|
logic dd_select;
|
||||||
logic lock_select;
|
|
||||||
logic cfg_select;
|
logic cfg_select;
|
||||||
|
|
||||||
logic read;
|
logic read;
|
||||||
@ -13,14 +12,12 @@ interface n64_reg_bus ();
|
|||||||
|
|
||||||
logic [15:0] flashram_rdata;
|
logic [15:0] flashram_rdata;
|
||||||
logic [15:0] dd_rdata;
|
logic [15:0] dd_rdata;
|
||||||
logic [15:0] lock_rdata;
|
|
||||||
logic [15:0] cfg_rdata;
|
logic [15:0] cfg_rdata;
|
||||||
|
|
||||||
modport controller (
|
modport controller (
|
||||||
output flashram_select,
|
output flashram_select,
|
||||||
output dd_select,
|
output dd_select,
|
||||||
output cfg_select,
|
output cfg_select,
|
||||||
output lock_select,
|
|
||||||
|
|
||||||
output read,
|
output read,
|
||||||
output write,
|
output write,
|
||||||
@ -37,9 +34,6 @@ interface n64_reg_bus ();
|
|||||||
if (dd_select) begin
|
if (dd_select) begin
|
||||||
rdata = dd_rdata;
|
rdata = dd_rdata;
|
||||||
end
|
end
|
||||||
if (lock_select) begin
|
|
||||||
rdata = lock_rdata;
|
|
||||||
end
|
|
||||||
if (cfg_select) begin
|
if (cfg_select) begin
|
||||||
rdata = cfg_rdata;
|
rdata = cfg_rdata;
|
||||||
end
|
end
|
||||||
@ -61,14 +55,6 @@ interface n64_reg_bus ();
|
|||||||
input wdata
|
input wdata
|
||||||
);
|
);
|
||||||
|
|
||||||
modport lock (
|
|
||||||
input .read(read && lock_select),
|
|
||||||
input .write(write && lock_select),
|
|
||||||
input address,
|
|
||||||
output .rdata(lock_rdata),
|
|
||||||
input wdata
|
|
||||||
);
|
|
||||||
|
|
||||||
modport cfg (
|
modport cfg (
|
||||||
input .read(read && cfg_select),
|
input .read(read && cfg_select),
|
||||||
input .write(write && cfg_select),
|
input .write(write && cfg_select),
|
||||||
|
@ -161,16 +161,11 @@ interface n64_scb ();
|
|||||||
input dd_wdata
|
input dd_wdata
|
||||||
);
|
);
|
||||||
|
|
||||||
modport lock (
|
modport cfg (
|
||||||
input n64_reset,
|
input n64_reset,
|
||||||
input n64_nmi,
|
input n64_nmi,
|
||||||
|
|
||||||
output cfg_unlock
|
output cfg_unlock,
|
||||||
);
|
|
||||||
|
|
||||||
modport cfg (
|
|
||||||
input n64_reset,
|
|
||||||
|
|
||||||
output cfg_pending,
|
output cfg_pending,
|
||||||
input cfg_done,
|
input cfg_done,
|
||||||
input cfg_error,
|
input cfg_error,
|
||||||
|
@ -67,15 +67,6 @@ module n64_top (
|
|||||||
.n64_scb(n64_scb)
|
.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 (
|
n64_cfg n64_cfg_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
|
@ -225,14 +225,6 @@ typedef struct {
|
|||||||
#define PIFRAM ((io8_t *) PIFRAM_BASE)
|
#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 {
|
typedef struct {
|
||||||
io8_t BUFFER[8192];
|
io8_t BUFFER[8192];
|
||||||
io8_t EEPROM[2048];
|
io8_t EEPROM[2048];
|
||||||
@ -248,6 +240,7 @@ typedef struct {
|
|||||||
io32_t SR_CMD;
|
io32_t SR_CMD;
|
||||||
io32_t DATA[2];
|
io32_t DATA[2];
|
||||||
io32_t VERSION;
|
io32_t VERSION;
|
||||||
|
io32_t KEY;
|
||||||
} sc64_regs_t;
|
} sc64_regs_t;
|
||||||
|
|
||||||
#define SC64_REGS_BASE (0x1FFF0000UL)
|
#define SC64_REGS_BASE (0x1FFF0000UL)
|
||||||
@ -256,6 +249,11 @@ typedef struct {
|
|||||||
#define SC64_SR_CMD_ERROR (1 << 30)
|
#define SC64_SR_CMD_ERROR (1 << 30)
|
||||||
#define SC64_SR_CPU_BUSY (1 << 31)
|
#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 {
|
typedef struct {
|
||||||
uint32_t tv_type;
|
uint32_t tv_type;
|
||||||
|
@ -41,13 +41,14 @@ static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sc64_unlock (void) {
|
void sc64_unlock (void) {
|
||||||
pi_io_write(&SC64_LOCK->KEY, 0x00000000);
|
pi_io_write(&SC64_REGS->KEY, SC64_KEY_RESET);
|
||||||
pi_io_write(&SC64_LOCK->KEY, 0x5F554E4C);
|
pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_1);
|
||||||
pi_io_write(&SC64_LOCK->KEY, 0x4F434B5F);
|
pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_lock (void) {
|
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) {
|
bool sc64_check_presence (void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user