mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-27 05:21:55 +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">
|
||||
<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>
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
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
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user