mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
storage
This commit is contained in:
parent
015e4238ff
commit
49bae164bb
@ -9,7 +9,7 @@ module cpu_cfg (
|
|||||||
|
|
||||||
typedef enum bit [2:0] {
|
typedef enum bit [2:0] {
|
||||||
R_SCR,
|
R_SCR,
|
||||||
R_DD_OFFSET,
|
R_DDIPL_OFFSET,
|
||||||
R_SAVE_OFFSET,
|
R_SAVE_OFFSET,
|
||||||
R_COMMAND,
|
R_COMMAND,
|
||||||
R_DATA_0,
|
R_DATA_0,
|
||||||
@ -45,7 +45,7 @@ module cpu_cfg (
|
|||||||
cfg.sdram_writable,
|
cfg.sdram_writable,
|
||||||
cfg.sdram_switch
|
cfg.sdram_switch
|
||||||
};
|
};
|
||||||
R_DD_OFFSET: bus.rdata = {6'd0, cfg.dd_offset};
|
R_DDIPL_OFFSET: bus.rdata = {6'd0, cfg.ddipl_offset};
|
||||||
R_SAVE_OFFSET: bus.rdata = {6'd0, cfg.save_offset};
|
R_SAVE_OFFSET: bus.rdata = {6'd0, cfg.save_offset};
|
||||||
R_COMMAND: bus.rdata = {24'd0, cfg.cmd};
|
R_COMMAND: bus.rdata = {24'd0, cfg.cmd};
|
||||||
R_DATA_0: bus.rdata = cfg.data[0];
|
R_DATA_0: bus.rdata = cfg.data[0];
|
||||||
@ -77,7 +77,7 @@ module cpu_cfg (
|
|||||||
cfg.sram_enabled <= 1'b0;
|
cfg.sram_enabled <= 1'b0;
|
||||||
cfg.sram_banked <= 1'b0;
|
cfg.sram_banked <= 1'b0;
|
||||||
cfg.flashram_enabled <= 1'b0;
|
cfg.flashram_enabled <= 1'b0;
|
||||||
cfg.dd_offset <= 26'h3BE_0000;
|
cfg.ddipl_offset <= 26'h3BE_0000;
|
||||||
cfg.save_offset <= 26'h3FE_0000;
|
cfg.save_offset <= 26'h3FE_0000;
|
||||||
skip_bootloader <= 1'b0;
|
skip_bootloader <= 1'b0;
|
||||||
trigger_reconfiguration <= 1'b0;
|
trigger_reconfiguration <= 1'b0;
|
||||||
@ -112,9 +112,9 @@ module cpu_cfg (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
R_DD_OFFSET: begin
|
R_DDIPL_OFFSET: begin
|
||||||
if (&bus.wmask) begin
|
if (&bus.wmask) begin
|
||||||
cfg.dd_offset <= bus.wdata[25:0];
|
cfg.ddipl_offset <= bus.wdata[25:0];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ module n64_pi (
|
|||||||
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
next_id <= sc64::ID_N64_SDRAM;
|
next_id <= sc64::ID_N64_SDRAM;
|
||||||
next_offset <= cfg.dd_offset + 32'h0A00_0000;
|
next_offset <= cfg.ddipl_offset + 32'h0A00_0000;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if (cfg.flashram_enabled) begin
|
if (cfg.flashram_enabled) begin
|
||||||
|
@ -15,7 +15,7 @@ interface if_config ();
|
|||||||
logic sram_banked;
|
logic sram_banked;
|
||||||
logic flashram_enabled;
|
logic flashram_enabled;
|
||||||
logic flashram_read_mode;
|
logic flashram_read_mode;
|
||||||
logic [25:0] dd_offset;
|
logic [25:0] ddipl_offset;
|
||||||
logic [25:0] save_offset;
|
logic [25:0] save_offset;
|
||||||
|
|
||||||
modport pi (
|
modport pi (
|
||||||
@ -26,7 +26,7 @@ interface if_config ();
|
|||||||
input sram_banked,
|
input sram_banked,
|
||||||
input flashram_enabled,
|
input flashram_enabled,
|
||||||
input flashram_read_mode,
|
input flashram_read_mode,
|
||||||
input dd_offset,
|
input ddipl_offset,
|
||||||
input save_offset
|
input save_offset
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ interface if_config ();
|
|||||||
output sram_enabled,
|
output sram_enabled,
|
||||||
output sram_banked,
|
output sram_banked,
|
||||||
output flashram_enabled,
|
output flashram_enabled,
|
||||||
output dd_offset,
|
output ddipl_offset,
|
||||||
output save_offset
|
output save_offset
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ SRC_FILES = \
|
|||||||
init.c \
|
init.c \
|
||||||
main.c \
|
main.c \
|
||||||
sc64.c \
|
sc64.c \
|
||||||
|
storage.c \
|
||||||
sys.c \
|
sys.c \
|
||||||
syscalls.c \
|
syscalls.c \
|
||||||
fatfs/diskio.c \
|
fatfs/diskio.c \
|
||||||
|
@ -153,7 +153,7 @@
|
|||||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_RPATH 0
|
#define FF_FS_RPATH 2
|
||||||
/* This option configures support for relative path.
|
/* This option configures support for relative path.
|
||||||
/
|
/
|
||||||
/ 0: Disable relative path and remove related functions.
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
#include "sc64.h"
|
#include "sc64.h"
|
||||||
|
#include "storage.h"
|
||||||
|
|
||||||
|
|
||||||
void main (void) {
|
void main (void) {
|
||||||
@ -12,22 +13,24 @@ void main (void) {
|
|||||||
|
|
||||||
switch (sc64_info.boot_mode) {
|
switch (sc64_info.boot_mode) {
|
||||||
case BOOT_MODE_MENU:
|
case BOOT_MODE_MENU:
|
||||||
LOG_E("Menu boot mode not implemented!\r\n");
|
LOG_I("Running menu from SD card\r\n");
|
||||||
while (1);
|
storage_run_menu(STORAGE_BACKEND_SD, &boot_info, &sc64_info);
|
||||||
|
break;
|
||||||
|
|
||||||
case BOOT_MODE_ROM:
|
case BOOT_MODE_ROM:
|
||||||
boot_info.device_type = BOOT_DEVICE_TYPE_ROM;
|
boot_info.device_type = BOOT_DEVICE_TYPE_ROM;
|
||||||
LOG_I("Running ROM from SDRAM\r\n");
|
LOG_I("Running ROM from SDRAM\r\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOT_MODE_DD:
|
case BOOT_MODE_DDIPL:
|
||||||
boot_info.device_type = BOOT_DEVICE_TYPE_DD;
|
boot_info.device_type = BOOT_DEVICE_TYPE_DD;
|
||||||
LOG_I("Running DDIPL from SDRAM\r\n");
|
LOG_I("Running DDIPL from SDRAM\r\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOT_MODE_DIRECT:
|
case BOOT_MODE_DIRECT:
|
||||||
LOG_I("Running bootloader from SDRAM - assuming FSD available\r\n");
|
LOG_I("Running bootloader from SDRAM, running menu from FSD\r\n");
|
||||||
while (1);
|
storage_run_menu(STORAGE_BACKEND_USB, &boot_info, &sc64_info);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_E("Unknown boot mode! - %d\r\n", sc64_info.boot_mode);
|
LOG_E("Unknown boot mode! - %d\r\n", sc64_info.boot_mode);
|
||||||
@ -62,7 +65,7 @@ void main (void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I("Booting IPL3\r\n");
|
LOG_I("Booting IPL3\r\n\r\n");
|
||||||
|
|
||||||
boot(&boot_info);
|
boot(&boot_info);
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,11 @@ bool sc64_wait_cpu_busy (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool sc64_perform_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) {
|
bool sc64_perform_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) {
|
||||||
pi_io_write(&SC64->DATA[0], args[0]);
|
if (args != NULL) {
|
||||||
pi_io_write(&SC64->DATA[1], args[1]);
|
pi_io_write(&SC64->DATA[0], args[0]);
|
||||||
pi_io_write(&SC64->SR_CMD, (uint32_t) cmd);
|
pi_io_write(&SC64->DATA[1], args[1]);
|
||||||
|
}
|
||||||
|
pi_io_write(&SC64->SR_CMD, ((uint32_t) (cmd)) & 0xFF);
|
||||||
bool error = sc64_wait_cpu_busy();
|
bool error = sc64_wait_cpu_busy();
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
result[0] = pi_io_read(&SC64->DATA[0]);
|
result[0] = pi_io_read(&SC64->DATA[0]);
|
||||||
@ -51,55 +53,60 @@ void sc64_set_config (cfg_id_t id, uint32_t value) {
|
|||||||
void sc64_get_info (sc64_info_t *info) {
|
void sc64_get_info (sc64_info_t *info) {
|
||||||
io32_t *src = (io32_t *) UNCACHED(&header_text_info);
|
io32_t *src = (io32_t *) UNCACHED(&header_text_info);
|
||||||
uint32_t *dst = (uint32_t *) info->bootloader_version;
|
uint32_t *dst = (uint32_t *) info->bootloader_version;
|
||||||
|
|
||||||
|
bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH);
|
||||||
|
|
||||||
|
if (sdram_switched) {
|
||||||
|
sc64_set_config(CFG_ID_SDRAM_SWITCH, false);
|
||||||
|
}
|
||||||
|
|
||||||
sc64_set_config(CFG_ID_SDRAM_SWITCH, false);
|
|
||||||
for (int i = 0; i < sizeof(info->bootloader_version); i += sizeof(uint32_t)) {
|
for (int i = 0; i < sizeof(info->bootloader_version); i += sizeof(uint32_t)) {
|
||||||
*dst++ = pi_io_read(src++);
|
*dst++ = pi_io_read(src++);
|
||||||
}
|
}
|
||||||
sc64_set_config(CFG_ID_SDRAM_SWITCH, true);
|
|
||||||
|
if (sdram_switched) {
|
||||||
|
sc64_set_config(CFG_ID_SDRAM_SWITCH, true);
|
||||||
|
}
|
||||||
|
|
||||||
info->dd_enabled = (bool) sc64_get_config(CFG_ID_DD_ENABLE);
|
info->dd_enabled = (bool) sc64_get_config(CFG_ID_DD_ENABLE);
|
||||||
info->save_type = (save_type_t) sc64_get_config(CFG_ID_SAVE_TYPE);
|
info->save_type = (save_type_t) sc64_get_config(CFG_ID_SAVE_TYPE);
|
||||||
info->cic_seed = (uint16_t) sc64_get_config(CFG_ID_CIC_SEED);
|
info->cic_seed = (uint16_t) sc64_get_config(CFG_ID_CIC_SEED);
|
||||||
info->tv_type = (tv_type_t) sc64_get_config(CFG_ID_TV_TYPE);
|
info->tv_type = (tv_type_t) sc64_get_config(CFG_ID_TV_TYPE);
|
||||||
info->save_offset = (io32_t *) (0x10000000 | sc64_get_config(CFG_ID_SAVE_OFFEST));
|
info->save_location = (io32_t *) (0x10000000 | sc64_get_config(CFG_ID_SAVE_OFFEST));
|
||||||
info->dd_offset = (io32_t *) (0x10000000 | sc64_get_config(CFG_ID_DD_OFFEST));
|
info->ddipl_location = (io32_t *) (0x10000000 | sc64_get_config(CFG_ID_DDIPL_OFFEST));
|
||||||
info->boot_mode = (boot_mode_t) sc64_get_config(CFG_ID_BOOT_MODE);
|
info->boot_mode = (boot_mode_t) sc64_get_config(CFG_ID_BOOT_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_wait_usb_rx_ready (uint32_t *type, uint32_t *length) {
|
void sc64_wait_usb_rx_ready (uint32_t *type, uint32_t *length) {
|
||||||
uint32_t args[2] = { 0, 0 };
|
|
||||||
uint32_t result[2];
|
uint32_t result[2];
|
||||||
do {
|
do {
|
||||||
sc64_perform_cmd(SC64_CMD_DEBUG_RX_READY, args, result);
|
sc64_perform_cmd(SC64_CMD_DEBUG_RX_READY, NULL, result);
|
||||||
} while (result[0] == 0 && result[1] == 0);
|
} while (result[0] == 0 && result[1] == 0);
|
||||||
*type = result[0];
|
*type = result[0];
|
||||||
*length = result[1];
|
*length = result[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_wait_usb_rx_busy (void) {
|
void sc64_wait_usb_rx_busy (void) {
|
||||||
uint32_t args[2] = { 0, 0 };
|
|
||||||
uint32_t result[2];
|
uint32_t result[2];
|
||||||
do {
|
do {
|
||||||
sc64_perform_cmd(SC64_CMD_DEBUG_RX_BUSY, args, result);
|
sc64_perform_cmd(SC64_CMD_DEBUG_RX_BUSY, NULL, result);
|
||||||
} while (result[0]);
|
} while (result[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_usb_rx_data (io32_t *address, uint32_t length) {
|
void sc64_usb_rx_data (io32_t *address, uint32_t length) {
|
||||||
uint32_t args[2] = { (uint32_t) (address), length };
|
uint32_t args[2] = { (uint32_t) (address), ALIGN(length, 2) };
|
||||||
sc64_perform_cmd(SC64_CMD_DEBUG_RX_DATA, args, NULL);
|
sc64_perform_cmd(SC64_CMD_DEBUG_RX_DATA, args, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_wait_usb_tx_ready (void) {
|
void sc64_wait_usb_tx_ready (void) {
|
||||||
uint32_t args[2] = { 0, 0 };
|
|
||||||
uint32_t result[2];
|
uint32_t result[2];
|
||||||
do {
|
do {
|
||||||
sc64_perform_cmd(SC64_CMD_DEBUG_TX_READY, args, result);
|
sc64_perform_cmd(SC64_CMD_DEBUG_TX_READY, NULL, result);
|
||||||
} while (!result[0]);
|
} while (!result[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_usb_tx_data (io32_t *address, uint32_t length) {
|
void sc64_usb_tx_data (io32_t *address, uint32_t length) {
|
||||||
uint32_t args[2] = { (uint32_t) (address), length };
|
uint32_t args[2] = { (uint32_t) (address), ALIGN(length, 2) };
|
||||||
sc64_perform_cmd(SC64_CMD_DEBUG_TX_DATA, args, NULL);
|
sc64_perform_cmd(SC64_CMD_DEBUG_TX_DATA, args, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,10 +124,14 @@ void sc64_debug_write (uint8_t type, const void *data, uint32_t len) {
|
|||||||
sc64_wait_usb_tx_ready();
|
sc64_wait_usb_tx_ready();
|
||||||
|
|
||||||
bool writable = sc64_get_config(CFG_ID_SDRAM_WRITABLE);
|
bool writable = sc64_get_config(CFG_ID_SDRAM_WRITABLE);
|
||||||
|
bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH);
|
||||||
|
|
||||||
if (!writable) {
|
if (!writable) {
|
||||||
sc64_set_config(CFG_ID_SDRAM_WRITABLE, true);
|
sc64_set_config(CFG_ID_SDRAM_WRITABLE, true);
|
||||||
}
|
}
|
||||||
|
if (!sdram_switched) {
|
||||||
|
sc64_set_config(CFG_ID_SDRAM_SWITCH, true);
|
||||||
|
}
|
||||||
|
|
||||||
pi_io_write(dst++, *((uint32_t *) (dma)));
|
pi_io_write(dst++, *((uint32_t *) (dma)));
|
||||||
pi_io_write(dst++, (type << 24) | len);
|
pi_io_write(dst++, (type << 24) | len);
|
||||||
@ -139,6 +150,9 @@ void sc64_debug_write (uint8_t type, const void *data, uint32_t len) {
|
|||||||
if (!writable) {
|
if (!writable) {
|
||||||
sc64_set_config(CFG_ID_SDRAM_WRITABLE, false);
|
sc64_set_config(CFG_ID_SDRAM_WRITABLE, false);
|
||||||
}
|
}
|
||||||
|
if (!sdram_switched) {
|
||||||
|
sc64_set_config(CFG_ID_SDRAM_SWITCH, false);
|
||||||
|
}
|
||||||
|
|
||||||
sc64_usb_tx_data(sdram, (dst - sdram) * sizeof(uint32_t));
|
sc64_usb_tx_data(sdram, (dst - sdram) * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
@ -152,29 +166,34 @@ void sc64_debug_fsd_read (const void *data, uint32_t sector, uint32_t count) {
|
|||||||
io32_t *src = sdram;
|
io32_t *src = sdram;
|
||||||
uint32_t *dst = (uint32_t *) (data);
|
uint32_t *dst = (uint32_t *) (data);
|
||||||
|
|
||||||
uint32_t info[2] = { sector, count };
|
uint32_t read_length = count * 512;
|
||||||
|
|
||||||
sc64_debug_write(SC64_DEBUG_TYPE_FSD_READ, &info, sizeof(info));
|
sc64_debug_write(SC64_DEBUG_ID_FSD_SECTOR, §or, 4);
|
||||||
|
sc64_debug_write(SC64_DEBUG_ID_FSD_READ, &read_length, 4);
|
||||||
sc64_wait_usb_rx_ready(&type, &length);
|
sc64_wait_usb_rx_ready(&type, &length);
|
||||||
sc64_usb_rx_data(sdram, length);
|
sc64_usb_rx_data(sdram, length);
|
||||||
sc64_wait_usb_rx_busy();
|
sc64_wait_usb_rx_busy();
|
||||||
|
|
||||||
uint32_t copy_length = ALIGN(length, 4);
|
uint32_t copy_length = ALIGN(length, 4);
|
||||||
|
|
||||||
|
bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH);
|
||||||
|
|
||||||
|
if (!sdram_switched) {
|
||||||
|
sc64_set_config(CFG_ID_SDRAM_SWITCH, true);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < copy_length; i += 4) {
|
for (int i = 0; i < copy_length; i += 4) {
|
||||||
*dst++ = pi_io_read(src++);
|
*dst++ = pi_io_read(src++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sdram_switched) {
|
||||||
|
sc64_set_config(CFG_ID_SDRAM_SWITCH, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_debug_fsd_write (const void *data, uint32_t sector, uint32_t count) {
|
void sc64_debug_fsd_write (const void *data, uint32_t sector, uint32_t count) {
|
||||||
uint32_t length = (8 + (count * 512)) / 4;
|
sc64_debug_write(SC64_DEBUG_ID_FSD_SECTOR, §or, 4);
|
||||||
uint32_t buffer[length];
|
sc64_debug_write(SC64_DEBUG_ID_FSD_WRITE, data, count * 512);
|
||||||
buffer[0] = sector;
|
|
||||||
buffer[1] = count;
|
|
||||||
for (uint32_t i = 0; i < count * 512; i += 4) {
|
|
||||||
buffer[2 + i] = ((uint32_t *) (data))[i];
|
|
||||||
}
|
|
||||||
sc64_debug_write(SC64_DEBUG_TYPE_FSD_WRITE, buffer, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc64_init (void) {
|
void sc64_init (void) {
|
||||||
|
@ -46,9 +46,10 @@ typedef struct {
|
|||||||
#define SC64_DEBUG_READ_ADDRESS (0x13BD0000UL)
|
#define SC64_DEBUG_READ_ADDRESS (0x13BD0000UL)
|
||||||
#define SC64_DEBUG_MAX_SIZE (32 * 1024)
|
#define SC64_DEBUG_MAX_SIZE (32 * 1024)
|
||||||
|
|
||||||
#define SC64_DEBUG_TYPE_TEXT (0x01)
|
#define SC64_DEBUG_ID_TEXT (0x01)
|
||||||
#define SC64_DEBUG_TYPE_FSD_READ (0xF1)
|
#define SC64_DEBUG_ID_FSD_READ (0xF1)
|
||||||
#define SC64_DEBUG_TYPE_FSD_WRITE (0xF2)
|
#define SC64_DEBUG_ID_FSD_WRITE (0xF2)
|
||||||
|
#define SC64_DEBUG_ID_FSD_SECTOR (0xF3)
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -60,7 +61,7 @@ typedef enum {
|
|||||||
CFG_ID_CIC_SEED,
|
CFG_ID_CIC_SEED,
|
||||||
CFG_ID_TV_TYPE,
|
CFG_ID_TV_TYPE,
|
||||||
CFG_ID_SAVE_OFFEST,
|
CFG_ID_SAVE_OFFEST,
|
||||||
CFG_ID_DD_OFFEST,
|
CFG_ID_DDIPL_OFFEST,
|
||||||
CFG_ID_BOOT_MODE,
|
CFG_ID_BOOT_MODE,
|
||||||
CFG_ID_FLASH_SIZE,
|
CFG_ID_FLASH_SIZE,
|
||||||
CFG_ID_FLASH_READ,
|
CFG_ID_FLASH_READ,
|
||||||
@ -88,7 +89,7 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
BOOT_MODE_MENU = 0,
|
BOOT_MODE_MENU = 0,
|
||||||
BOOT_MODE_ROM = 1,
|
BOOT_MODE_ROM = 1,
|
||||||
BOOT_MODE_DD = 2,
|
BOOT_MODE_DDIPL = 2,
|
||||||
BOOT_MODE_DIRECT = 3,
|
BOOT_MODE_DIRECT = 3,
|
||||||
} boot_mode_t;
|
} boot_mode_t;
|
||||||
|
|
||||||
@ -97,29 +98,29 @@ typedef struct {
|
|||||||
save_type_t save_type;
|
save_type_t save_type;
|
||||||
uint16_t cic_seed;
|
uint16_t cic_seed;
|
||||||
tv_type_t tv_type;
|
tv_type_t tv_type;
|
||||||
io32_t *save_offset;
|
io32_t *save_location;
|
||||||
io32_t *dd_offset;
|
io32_t *ddipl_location;
|
||||||
boot_mode_t boot_mode;
|
boot_mode_t boot_mode;
|
||||||
char bootloader_version[32];
|
char bootloader_version[32];
|
||||||
} sc64_info_t;
|
} sc64_info_t;
|
||||||
|
|
||||||
|
|
||||||
bool sc64_check_presence(void);
|
bool sc64_check_presence (void);
|
||||||
void sc64_wait_cpu_ready(void);
|
void sc64_wait_cpu_ready (void);
|
||||||
bool sc64_wait_cpu_busy(void);
|
bool sc64_wait_cpu_busy (void);
|
||||||
bool sc64_perform_cmd(uint8_t cmd, uint32_t *args, uint32_t *result);
|
bool sc64_perform_cmd (uint8_t cmd, uint32_t *args, uint32_t *result);
|
||||||
uint32_t sc64_get_config(cfg_id_t id);
|
uint32_t sc64_get_config (cfg_id_t id);
|
||||||
void sc64_set_config(cfg_id_t id, uint32_t value);
|
void sc64_set_config (cfg_id_t id, uint32_t value);
|
||||||
void sc64_get_info(sc64_info_t *info);
|
void sc64_get_info (sc64_info_t *info);
|
||||||
void sc64_wait_usb_rx_ready (uint32_t *type, uint32_t *length);
|
void sc64_wait_usb_rx_ready (uint32_t *type, uint32_t *length);
|
||||||
void sc64_wait_usb_rx_busy (void);
|
void sc64_wait_usb_rx_busy (void);
|
||||||
void sc64_usb_rx_data (io32_t *address, uint32_t length);
|
void sc64_usb_rx_data (io32_t *address, uint32_t length);
|
||||||
void sc64_wait_usb_tx_ready(void);
|
void sc64_wait_usb_tx_ready (void);
|
||||||
void sc64_usb_tx_data(io32_t *address, uint32_t length);
|
void sc64_usb_tx_data (io32_t *address, uint32_t length);
|
||||||
void sc64_debug_write(uint8_t type, const void *data, uint32_t len);
|
void sc64_debug_write (uint8_t type, const void *data, uint32_t len);
|
||||||
void sc64_debug_fsd_read(const void *data, uint32_t sector, uint32_t count);
|
void sc64_debug_fsd_read (const void *data, uint32_t sector, uint32_t count);
|
||||||
void sc64_debug_fsd_write(const void *data, uint32_t sector, uint32_t count);
|
void sc64_debug_fsd_write (const void *data, uint32_t sector, uint32_t count);
|
||||||
void sc64_init(void);
|
void sc64_init (void);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
7
sw/n64/src/storage.c
Normal file
7
sw/n64/src/storage.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "storage.h"
|
||||||
|
|
||||||
|
|
||||||
|
void storage_run_menu (storage_backend_t storage_backend, boot_info_t *boot_info, sc64_info_t *sc64_info) {
|
||||||
|
// TODO: Implement ELF loader here
|
||||||
|
while (1);
|
||||||
|
}
|
18
sw/n64/src/storage.h
Normal file
18
sw/n64/src/storage.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef STORAGE_H__
|
||||||
|
#define STORAGE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "boot.h"
|
||||||
|
#include "sc64.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STORAGE_BACKEND_SD = 0,
|
||||||
|
STORAGE_BACKEND_USB = 1,
|
||||||
|
} storage_backend_t;
|
||||||
|
|
||||||
|
|
||||||
|
void storage_run_menu (storage_backend_t storage_backend, boot_info_t *boot_info, sc64_info_t *sc64_info);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -49,13 +49,12 @@ uint32_t pi_busy (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pi_io_read (io32_t *address) {
|
uint32_t pi_io_read (io32_t *address) {
|
||||||
while (pi_busy());
|
|
||||||
return io_read(address);
|
return io_read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pi_io_write (io32_t *address, uint32_t value) {
|
void pi_io_write (io32_t *address, uint32_t value) {
|
||||||
while (pi_busy());
|
|
||||||
io_write(address, value);
|
io_write(address, value);
|
||||||
|
while (pi_busy());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t si_busy (void) {
|
uint32_t si_busy (void) {
|
||||||
@ -63,11 +62,10 @@ uint32_t si_busy (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t si_io_read (io32_t *address) {
|
uint32_t si_io_read (io32_t *address) {
|
||||||
while (si_busy());
|
|
||||||
return io_read(address);
|
return io_read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void si_io_write (io32_t *address, uint32_t value) {
|
void si_io_write (io32_t *address, uint32_t value) {
|
||||||
while (si_busy());
|
|
||||||
io_write(address, value);
|
io_write(address, value);
|
||||||
|
while (si_busy());
|
||||||
}
|
}
|
||||||
|
@ -243,23 +243,6 @@ typedef struct {
|
|||||||
#define SI_SR_CLEAR_INTERRUPT (0)
|
#define SI_SR_CLEAR_INTERRUPT (0)
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t pi_config;
|
|
||||||
uint32_t clock_rate;
|
|
||||||
void (*entry_point)(void);
|
|
||||||
struct {
|
|
||||||
uint16_t __reserved_1;
|
|
||||||
uint8_t major;
|
|
||||||
char minor;
|
|
||||||
} sdk_version;
|
|
||||||
uint32_t crc[2];
|
|
||||||
uint32_t __reserved_1[2];
|
|
||||||
char name[20];
|
|
||||||
uint8_t __reserved_2[7];
|
|
||||||
char id[4];
|
|
||||||
uint8_t revision;
|
|
||||||
} rom_header_t;
|
|
||||||
|
|
||||||
#define ROM_DDIPL_BASE (0x06000000UL)
|
#define ROM_DDIPL_BASE (0x06000000UL)
|
||||||
#define ROM_DDIPL ((io32_t *) ROM_DDIPL_BASE)
|
#define ROM_DDIPL ((io32_t *) ROM_DDIPL_BASE)
|
||||||
#define ROM_CART_BASE (0x10000000UL)
|
#define ROM_CART_BASE (0x10000000UL)
|
||||||
|
@ -58,7 +58,7 @@ ssize_t _write_r (struct _reent *prt, int fd, const void *buf, size_t cnt) {
|
|||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
} else if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
|
} else if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
|
||||||
sc64_debug_write(SC64_DEBUG_TYPE_TEXT, buf, cnt);
|
sc64_debug_write(SC64_DEBUG_ID_TEXT, buf, cnt);
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
@ -26,7 +26,7 @@ class SC64:
|
|||||||
__CFG_ID_CIC_SEED = 5
|
__CFG_ID_CIC_SEED = 5
|
||||||
__CFG_ID_TV_TYPE = 6
|
__CFG_ID_TV_TYPE = 6
|
||||||
__CFG_ID_SAVE_OFFEST = 7
|
__CFG_ID_SAVE_OFFEST = 7
|
||||||
__CFG_ID_DD_OFFEST = 8
|
__CFG_ID_DDIPL_OFFEST = 8
|
||||||
__CFG_ID_BOOT_MODE = 9
|
__CFG_ID_BOOT_MODE = 9
|
||||||
__CFG_ID_FLASH_SIZE = 10
|
__CFG_ID_FLASH_SIZE = 10
|
||||||
__CFG_ID_FLASH_READ = 11
|
__CFG_ID_FLASH_READ = 11
|
||||||
@ -45,6 +45,7 @@ class SC64:
|
|||||||
__DEBUG_ID_TEXT = 0x01
|
__DEBUG_ID_TEXT = 0x01
|
||||||
__DEBUG_ID_FSD_READ = 0xF1
|
__DEBUG_ID_FSD_READ = 0xF1
|
||||||
__DEBUG_ID_FSD_WRITE = 0xF2
|
__DEBUG_ID_FSD_WRITE = 0xF2
|
||||||
|
__DEBUG_ID_FSD_SECTOR = 0xF3
|
||||||
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -348,65 +349,82 @@ class SC64:
|
|||||||
|
|
||||||
|
|
||||||
def download_dd_ipl(self, file: str) -> None:
|
def download_dd_ipl(self, file: str) -> None:
|
||||||
dd_ipl_offset = self.__query_config(self.__CFG_ID_DD_OFFEST)
|
dd_ipl_offset = self.__query_config(self.__CFG_ID_DDIPL_OFFEST)
|
||||||
self.__read_file_from_sdram(file, dd_ipl_offset, length=self.__DDIPL_ROM_LENGTH)
|
self.__read_file_from_sdram(file, dd_ipl_offset, length=self.__DDIPL_ROM_LENGTH)
|
||||||
|
|
||||||
|
|
||||||
def upload_dd_ipl(self, file: str, offset: int = None) -> None:
|
def upload_dd_ipl(self, file: str, offset: int = None) -> None:
|
||||||
if (offset != None):
|
if (offset != None):
|
||||||
self.__change_config(self.__CFG_ID_DD_OFFEST, offset)
|
self.__change_config(self.__CFG_ID_DDIPL_OFFEST, offset)
|
||||||
dd_ipl_offset = self.__query_config(self.__CFG_ID_DD_OFFEST)
|
dd_ipl_offset = self.__query_config(self.__CFG_ID_DDIPL_OFFEST)
|
||||||
self.__write_file_to_sdram(file, dd_ipl_offset, min_length=self.__DDIPL_ROM_LENGTH)
|
self.__write_file_to_sdram(file, dd_ipl_offset, min_length=self.__DDIPL_ROM_LENGTH)
|
||||||
|
|
||||||
|
|
||||||
def __debug_process_fsd_read(self, file: str, id: int, data: bytes) -> None:
|
def __debug_process_fsd_set_sector(self, data: bytes) -> None:
|
||||||
sector = int.from_bytes(data[0:4], byteorder='big')
|
sector = int.from_bytes(data[0:4], byteorder='big')
|
||||||
count = int.from_bytes(data[4:8], byteorder='big')
|
if (self.__fsd_file):
|
||||||
if (file):
|
|
||||||
if (self.__fsd_file == None):
|
|
||||||
self.__fsd_file = open(file, "rb")
|
|
||||||
self.__fsd_file.seek(sector * 512)
|
self.__fsd_file.seek(sector * 512)
|
||||||
self.__debug_write(id, self.__fsd_file.read(count * 512))
|
|
||||||
|
|
||||||
|
def __debug_process_fsd_read(self, data: bytes) -> None:
|
||||||
|
length = int.from_bytes(data[0:4], byteorder='big')
|
||||||
|
if (self.__fsd_file):
|
||||||
|
self.__debug_write(self.__DEBUG_ID_FSD_READ, self.__fsd_file.read(length))
|
||||||
else:
|
else:
|
||||||
self.__debug_write(id, bytes(count * 512))
|
self.__debug_write(self.__DEBUG_ID_FSD_READ, bytes(length))
|
||||||
|
|
||||||
|
|
||||||
|
def __debug_process_fsd_write(self, data: bytes) -> None:
|
||||||
|
if (self.__fsd_file):
|
||||||
|
self.__fsd_file.write(data)
|
||||||
|
|
||||||
|
|
||||||
def debug_loop(self, file: str = None) -> None:
|
def debug_loop(self, file: str = None) -> None:
|
||||||
print("\033[34m --- Debug server started --- \033[0m")
|
print("\r\n\033[34m --- Debug server started --- \033[0m\r\n")
|
||||||
|
|
||||||
self.__serial.timeout = 0.01
|
self.__serial.timeout = 0.01
|
||||||
self.__serial.write_timeout = 1
|
self.__serial.write_timeout = 1
|
||||||
|
|
||||||
while (True):
|
if (file):
|
||||||
start_indicator = self.__read_long(4)
|
self.__fsd_file = open(file, "rb+")
|
||||||
if (start_indicator == b"DMA@"):
|
|
||||||
header = self.__read_long(4)
|
|
||||||
id = int(header[0])
|
|
||||||
length = int.from_bytes(header[1:4], byteorder="big")
|
|
||||||
|
|
||||||
if (length > 0):
|
start_indicator = bytearray()
|
||||||
align = self.__align(length, 4) - length
|
dropped_bytes = 0
|
||||||
|
|
||||||
|
while (True):
|
||||||
|
while (start_indicator != b"DMA@"):
|
||||||
|
start_indicator.append(self.__read_long(1)[0])
|
||||||
|
if (len(start_indicator) > 4):
|
||||||
|
dropped_bytes += 1
|
||||||
|
start_indicator.pop(0)
|
||||||
|
start_indicator.clear()
|
||||||
|
|
||||||
|
if (dropped_bytes):
|
||||||
|
print(f"\033[35mWarning - dropped {dropped_bytes} bytes from stream\033[0m", file=sys.stderr)
|
||||||
|
dropped_bytes = 0
|
||||||
|
|
||||||
|
header = self.__read_long(4)
|
||||||
|
id = int(header[0])
|
||||||
|
length = int.from_bytes(header[1:4], byteorder="big")
|
||||||
|
|
||||||
|
if (length > 0):
|
||||||
data = self.__read_long(length)
|
data = self.__read_long(length)
|
||||||
|
|
||||||
if (id == self.__DEBUG_ID_TEXT):
|
if (id == self.__DEBUG_ID_TEXT):
|
||||||
print(data.decode(encoding="ascii", errors="backslashreplace"), end="")
|
print(data.decode(encoding="ascii", errors="backslashreplace"), end="")
|
||||||
elif (id == self.__DEBUG_ID_FSD_READ):
|
elif (id == self.__DEBUG_ID_FSD_READ):
|
||||||
pass
|
self.__debug_process_fsd_read(data)
|
||||||
elif (id == self.__DEBUG_ID_FSD_WRITE):
|
elif (id == self.__DEBUG_ID_FSD_WRITE):
|
||||||
pass
|
self.__debug_process_fsd_write(data)
|
||||||
else:
|
elif (id == self.__DEBUG_ID_FSD_SECTOR):
|
||||||
print(f"Got unknown id: {id}, length: {length}")
|
self.__debug_process_fsd_set_sector(data)
|
||||||
|
else:
|
||||||
|
print(f"\033[35mGot unknown id: {id}, length: {length}\033[0m", file=sys.stderr)
|
||||||
|
|
||||||
self.__read_long(align)
|
self.__read_long(self.__align(length, 4) - length)
|
||||||
end_indicator = self.__read_long(4)
|
end_indicator = self.__read_long(4)
|
||||||
if (end_indicator != b"CMPH"):
|
if (end_indicator != b"CMPH"):
|
||||||
print(f"Got unknown end indicator: {end_indicator.decode(encoding='ascii', errors='backslashreplace')}")
|
print(f"\033[35mGot unknown end indicator: {end_indicator.decode(encoding='ascii', errors='backslashreplace')}\033[0m", file=sys.stderr)
|
||||||
|
|
||||||
if (id == self.__DEBUG_ID_FSD_READ):
|
|
||||||
self.__debug_process_fsd_read(file, id, data)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print(f"Got unknown start indicator: {start_indicator.decode(encoding='ascii', errors='backslashreplace')}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#define SAVE_OFFSET_PKST2 (0x01608000UL)
|
#define SAVE_OFFSET_PKST2 (0x01608000UL)
|
||||||
|
|
||||||
#define DEFAULT_SAVE_OFFSET (0x03FE0000UL)
|
#define DEFAULT_SAVE_OFFSET (0x03FE0000UL)
|
||||||
#define DEFAULT_DD_OFFSET (0x03BE0000UL)
|
#define DEFAULT_DDIPL_OFFSET (0x03BE0000UL)
|
||||||
|
|
||||||
|
|
||||||
enum cfg_id {
|
enum cfg_id {
|
||||||
@ -25,7 +25,7 @@ enum cfg_id {
|
|||||||
CFG_ID_CIC_SEED,
|
CFG_ID_CIC_SEED,
|
||||||
CFG_ID_TV_TYPE,
|
CFG_ID_TV_TYPE,
|
||||||
CFG_ID_SAVE_OFFEST,
|
CFG_ID_SAVE_OFFEST,
|
||||||
CFG_ID_DD_OFFEST,
|
CFG_ID_DDIPL_OFFEST,
|
||||||
CFG_ID_BOOT_MODE,
|
CFG_ID_BOOT_MODE,
|
||||||
CFG_ID_FLASH_SIZE,
|
CFG_ID_FLASH_SIZE,
|
||||||
CFG_ID_FLASH_READ,
|
CFG_ID_FLASH_READ,
|
||||||
@ -143,8 +143,8 @@ void cfg_update (uint32_t *args) {
|
|||||||
case CFG_ID_SAVE_OFFEST:
|
case CFG_ID_SAVE_OFFEST:
|
||||||
CFG->SAVE_OFFSET = args[1];
|
CFG->SAVE_OFFSET = args[1];
|
||||||
break;
|
break;
|
||||||
case CFG_ID_DD_OFFEST:
|
case CFG_ID_DDIPL_OFFEST:
|
||||||
CFG->DD_OFFSET = args[1];
|
CFG->DDIPL_OFFSET = args[1];
|
||||||
break;
|
break;
|
||||||
case CFG_ID_BOOT_MODE:
|
case CFG_ID_BOOT_MODE:
|
||||||
p.boot_mode = args[1];
|
p.boot_mode = args[1];
|
||||||
@ -193,8 +193,8 @@ void cfg_query (uint32_t *args) {
|
|||||||
case CFG_ID_SAVE_OFFEST:
|
case CFG_ID_SAVE_OFFEST:
|
||||||
args[1] = CFG->SAVE_OFFSET;
|
args[1] = CFG->SAVE_OFFSET;
|
||||||
break;
|
break;
|
||||||
case CFG_ID_DD_OFFEST:
|
case CFG_ID_DDIPL_OFFEST:
|
||||||
args[1] = CFG->DD_OFFSET;
|
args[1] = CFG->DDIPL_OFFSET;
|
||||||
break;
|
break;
|
||||||
case CFG_ID_BOOT_MODE:
|
case CFG_ID_BOOT_MODE:
|
||||||
args[1] = p.boot_mode;
|
args[1] = p.boot_mode;
|
||||||
@ -212,7 +212,7 @@ void cfg_query (uint32_t *args) {
|
|||||||
void cfg_init (void) {
|
void cfg_init (void) {
|
||||||
set_save_type(SAVE_TYPE_NONE);
|
set_save_type(SAVE_TYPE_NONE);
|
||||||
|
|
||||||
CFG->DD_OFFSET = DEFAULT_DD_OFFSET;
|
CFG->DDIPL_OFFSET = DEFAULT_DDIPL_OFFSET;
|
||||||
CFG->SCR = CFG_SCR_CPU_READY | CFG_SCR_SDRAM_SWITCH;
|
CFG->SCR = CFG_SCR_CPU_READY | CFG_SCR_SDRAM_SWITCH;
|
||||||
|
|
||||||
p.cic_seed = 0xFFFF;
|
p.cic_seed = 0xFFFF;
|
||||||
|
@ -124,7 +124,7 @@ typedef volatile struct dma_regs {
|
|||||||
|
|
||||||
typedef volatile struct cfg_regs {
|
typedef volatile struct cfg_regs {
|
||||||
io32_t SCR;
|
io32_t SCR;
|
||||||
io32_t DD_OFFSET;
|
io32_t DDIPL_OFFSET;
|
||||||
io32_t SAVE_OFFSET;
|
io32_t SAVE_OFFSET;
|
||||||
io8_t CMD;
|
io8_t CMD;
|
||||||
io8_t __padding[3];
|
io8_t __padding[3];
|
||||||
|
Loading…
Reference in New Issue
Block a user