Remove unnecessary code from SC64 flashcart module

This commit is contained in:
Mateusz Faderewski 2023-07-26 17:58:07 +02:00
parent 05bf7aeedf
commit 8d5aa4ecb1
5 changed files with 61 additions and 78 deletions

View File

@ -1,3 +1,5 @@
#include <libdragon.h>
#include "flashcart_utils.h" #include "flashcart_utils.h"
#include "utils/fs.h" #include "utils/fs.h"
#include "utils/utils.h" #include "utils/utils.h"
@ -9,3 +11,19 @@ void fix_file_size (FIL *fil) {
// Sending some extra bytes isn't an issue here. // Sending some extra bytes isn't an issue here.
fil->obj.objsize = ALIGN(f_size(fil), FS_SECTOR_SIZE); fil->obj.objsize = ALIGN(f_size(fil), FS_SECTOR_SIZE);
} }
void pi_dma_read_data (void *src, void *dst, size_t length) {
data_cache_hit_writeback_invalidate(dst, length);
dma_read_async(dst, (uint32_t) (src), length);
dma_wait();
}
void pi_dma_write_data (void *src, void *dst, size_t length) {
assert((((uint32_t) (src)) & 0x07) == 0);
assert((((uint32_t) (dst)) & 0x01) == 0);
assert((length & 1) == 0);
data_cache_hit_writeback(src, length);
dma_write_raw_async(src, (uint32_t) (dst), length);
dma_wait();
}

View File

@ -12,6 +12,8 @@
void fix_file_size (FIL *fil); void fix_file_size (FIL *fil);
void pi_dma_read_data (void *src, void *dst, size_t length);
void pi_dma_write_data (void *src, void *dst, size_t length);
#endif #endif

View File

@ -55,13 +55,9 @@ static flashcart_error_t load_to_flash (FIL *fil, void *address, size_t size, UI
static flashcart_error_t sc64_init (void) { static flashcart_error_t sc64_init (void) {
uint16_t major; uint16_t major;
uint16_t minor; uint16_t minor;
uint32_t revision;
sc64_unlock(); if (sc64_get_version(&major, &minor, &revision) != SC64_OK) {
if (!sc64_check_presence()) {
return FLASHCART_ERROR_UNSUPPORTED;
}
if (sc64_get_version(&major, &minor) != SC64_OK) {
return FLASHCART_ERROR_OUTDATED; return FLASHCART_ERROR_OUTDATED;
} }
if (major != SUPPORTED_MAJOR_VERSION) { if (major != SUPPORTED_MAJOR_VERSION) {
@ -192,12 +188,14 @@ static flashcart_error_t sc64_load_rom (char *rom_path) {
static flashcart_error_t sc64_load_save (char *save_path) { static flashcart_error_t sc64_load_save (char *save_path) {
void *address = NULL; void *address = NULL;
sc64_save_type_t type; uint32_t value;
if (sc64_get_config(CFG_SAVE_TYPE, &type) != SC64_OK) { if (sc64_get_config(CFG_SAVE_TYPE, &value) != SC64_OK) {
return FLASHCART_ERROR_INT; return FLASHCART_ERROR_INT;
} }
sc64_save_type_t type = (sc64_save_type_t) (value);
switch (type) { switch (type) {
case SAVE_TYPE_EEPROM_4K: case SAVE_TYPE_EEPROM_4K:
case SAVE_TYPE_EEPROM_16K: case SAVE_TYPE_EEPROM_16K:
@ -275,7 +273,7 @@ static flashcart_error_t sc64_set_save_type (flashcart_save_type_t save_type) {
} }
static flashcart_error_t sc64_set_save_writeback (uint32_t *sectors) { static flashcart_error_t sc64_set_save_writeback (uint32_t *sectors) {
sc64_write_data(sectors, SC64_BUFFERS->BUFFER, 1024); pi_dma_write_data(sectors, SC64_BUFFERS->BUFFER, 1024);
if (sc64_writeback_enable(SC64_BUFFERS->BUFFER) != SC64_OK) { if (sc64_writeback_enable(SC64_BUFFERS->BUFFER) != SC64_OK) {
return FLASHCART_ERROR_INT; return FLASHCART_ERROR_INT;

View File

@ -13,15 +13,9 @@ typedef struct {
#define SC64_REGS_BASE (0x1FFF0000UL) #define SC64_REGS_BASE (0x1FFF0000UL)
#define SC64_REGS ((sc64_regs_t *) SC64_REGS_BASE) #define SC64_REGS ((sc64_regs_t *) SC64_REGS_BASE)
#define SC64_SR_IRQ_PENDING (1 << 29)
#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_V2_IDENTIFIER (0x53437632)
#define SC64_KEY_RESET (0x00000000UL)
#define SC64_KEY_UNLOCK_1 (0x5F554E4CUL)
#define SC64_KEY_UNLOCK_2 (0x4F434B5FUL)
#define SC64_KEY_LOCK (0xFFFFFFFFUL) #define SC64_KEY_LOCK (0xFFFFFFFFUL)
@ -29,23 +23,12 @@ typedef enum {
CMD_ID_VERSION_GET = 'V', CMD_ID_VERSION_GET = 'V',
CMD_ID_CONFIG_GET = 'c', CMD_ID_CONFIG_GET = 'c',
CMD_ID_CONFIG_SET = 'C', CMD_ID_CONFIG_SET = 'C',
CMD_ID_SD_CARD_OP = 'i',
CMD_ID_WRITEBACK_PENDING = 'w', CMD_ID_WRITEBACK_PENDING = 'w',
CMD_ID_WRITEBACK_SD_INFO = 'W', CMD_ID_WRITEBACK_SD_INFO = 'W',
CMD_ID_FLASH_PROGRAM = 'K',
CMD_ID_FLASH_WAIT_BUSY = 'p', CMD_ID_FLASH_WAIT_BUSY = 'p',
CMD_ID_FLASH_ERASE_BLOCK = 'P', CMD_ID_FLASH_ERASE_BLOCK = 'P',
} sc64_cmd_id_t; } sc64_cmd_id_t;
typedef enum {
SD_CARD_OP_DEINIT = 0,
SD_CARD_OP_INIT = 1,
SD_CARD_OP_GET_STATUS = 2,
SD_CARD_OP_GET_INFO = 3,
SD_CARD_OP_BYTE_SWAP_ON = 4,
SD_CARD_OP_BYTE_SWAP_OFF = 5,
} sc64_sd_card_op_t;
typedef struct { typedef struct {
sc64_cmd_id_t id; sc64_cmd_id_t id;
uint32_t arg[2]; uint32_t arg[2];
@ -75,90 +58,78 @@ static sc64_error_t sc64_execute_cmd (sc64_cmd_t *cmd) {
} }
void sc64_unlock (void) {
io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_RESET);
io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_UNLOCK_1);
io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_UNLOCK_2);
}
void sc64_lock (void) { void sc64_lock (void) {
io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_LOCK); io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_LOCK);
} }
bool sc64_check_presence (void) { sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor, uint32_t *revision) {
return (io_read((uint32_t) (&SC64_REGS->IDENTIFIER)) == SC64_V2_IDENTIFIER); sc64_cmd_t cmd = {
} .id = CMD_ID_VERSION_GET
};
void sc64_read_data (void *src, void *dst, size_t length) {
data_cache_hit_writeback_invalidate(dst, length);
dma_read_raw_async(dst, (uint32_t) (src), length);
dma_wait();
}
void sc64_write_data (void *src, void *dst, size_t length) {
data_cache_hit_writeback(src, length);
dma_write_raw_async(src, (uint32_t) (dst), length);
dma_wait();
}
sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor) {
sc64_cmd_t cmd = { .id = CMD_ID_VERSION_GET };
sc64_error_t error = sc64_execute_cmd(&cmd); sc64_error_t error = sc64_execute_cmd(&cmd);
*major = ((cmd.rsp[0] >> 16) & 0xFFFF); *major = ((cmd.rsp[0] >> 16) & 0xFFFF);
*minor = (cmd.rsp[0] & 0xFFFF); *minor = (cmd.rsp[0] & 0xFFFF);
*revision = cmd.rsp[1];
return error; return error;
} }
sc64_error_t sc64_get_config (sc64_cfg_t id, void *value) { sc64_error_t sc64_get_config (sc64_cfg_t id, uint32_t *value) {
sc64_cmd_t cmd = { .id = CMD_ID_CONFIG_GET, .arg = { id } }; sc64_cmd_t cmd = {
.id = CMD_ID_CONFIG_GET,
.arg = { id }
};
sc64_error_t error = sc64_execute_cmd(&cmd); sc64_error_t error = sc64_execute_cmd(&cmd);
*((uint32_t *) (value)) = cmd.rsp[1]; *value = cmd.rsp[1];
return error; return error;
} }
sc64_error_t sc64_set_config (sc64_cfg_t id, uint32_t value) { sc64_error_t sc64_set_config (sc64_cfg_t id, uint32_t value) {
sc64_cmd_t cmd = { .id = CMD_ID_CONFIG_SET, .arg = { id, value } };
return sc64_execute_cmd(&cmd);
}
sc64_error_t sc64_sd_set_byte_swap (bool enabled) {
sc64_cmd_t cmd = { sc64_cmd_t cmd = {
.id = CMD_ID_SD_CARD_OP, .id = CMD_ID_CONFIG_SET,
.arg = { 0, enabled ? SD_CARD_OP_BYTE_SWAP_ON : SD_CARD_OP_BYTE_SWAP_OFF } .arg = { id, value }
}; };
return sc64_execute_cmd(&cmd); return sc64_execute_cmd(&cmd);
} }
sc64_error_t sc64_writeback_pending (bool *pending) { sc64_error_t sc64_writeback_pending (bool *pending) {
sc64_cmd_t cmd = { .id = CMD_ID_WRITEBACK_PENDING }; sc64_cmd_t cmd = {
.id = CMD_ID_WRITEBACK_PENDING
};
sc64_error_t error = sc64_execute_cmd(&cmd); sc64_error_t error = sc64_execute_cmd(&cmd);
*pending = (cmd.rsp[0] != 0); *pending = (cmd.rsp[0] != 0);
return error; return error;
} }
sc64_error_t sc64_writeback_enable (void *address) { sc64_error_t sc64_writeback_enable (void *address) {
sc64_cmd_t cmd = { .id = CMD_ID_WRITEBACK_SD_INFO, .arg = { (uint32_t) (address) } }; sc64_cmd_t cmd = {
return sc64_execute_cmd(&cmd); .id = CMD_ID_WRITEBACK_SD_INFO,
} .arg = { (uint32_t) (address) }
};
sc64_error_t sc64_flash_program (void *address, size_t length) {
sc64_cmd_t cmd = { .id = CMD_ID_FLASH_PROGRAM, .arg = { (uint32_t) (address), length } };
return sc64_execute_cmd(&cmd); return sc64_execute_cmd(&cmd);
} }
sc64_error_t sc64_flash_wait_busy (void) { sc64_error_t sc64_flash_wait_busy (void) {
sc64_cmd_t cmd = { .id = CMD_ID_FLASH_WAIT_BUSY, .arg = { true } }; sc64_cmd_t cmd = {
.id = CMD_ID_FLASH_WAIT_BUSY,
.arg = { true }
};
return sc64_execute_cmd(&cmd); return sc64_execute_cmd(&cmd);
} }
sc64_error_t sc64_flash_get_erase_block_size (size_t *erase_block_size) { sc64_error_t sc64_flash_get_erase_block_size (size_t *erase_block_size) {
sc64_cmd_t cmd = { .id = CMD_ID_FLASH_WAIT_BUSY, .arg = { false } }; sc64_cmd_t cmd = {
.id = CMD_ID_FLASH_WAIT_BUSY,
.arg = { false }
};
sc64_error_t error = sc64_execute_cmd(&cmd); sc64_error_t error = sc64_execute_cmd(&cmd);
*erase_block_size = (size_t) (cmd.rsp[0]); *erase_block_size = (size_t) (cmd.rsp[0]);
return error; return error;
} }
sc64_error_t sc64_flash_erase_block (void *address) { sc64_error_t sc64_flash_erase_block (void *address) {
sc64_cmd_t cmd = { .id = CMD_ID_FLASH_ERASE_BLOCK, .arg = { (uint32_t) (address) } }; sc64_cmd_t cmd = {
.id = CMD_ID_FLASH_ERASE_BLOCK,
.arg = { (uint32_t) (address) }
};
return sc64_execute_cmd(&cmd); return sc64_execute_cmd(&cmd);
} }

View File

@ -110,18 +110,12 @@ typedef enum {
} sc64_button_mode_t; } sc64_button_mode_t;
void sc64_unlock (void);
void sc64_lock (void); void sc64_lock (void);
bool sc64_check_presence (void); sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor, uint32_t *revision);
void sc64_read_data (void *src, void *dst, size_t length); sc64_error_t sc64_get_config (sc64_cfg_t cfg, uint32_t *value);
void sc64_write_data (void *src, void *dst, size_t length);
sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor);
sc64_error_t sc64_get_config (sc64_cfg_t cfg, void *value);
sc64_error_t sc64_set_config (sc64_cfg_t cfg, uint32_t value); sc64_error_t sc64_set_config (sc64_cfg_t cfg, uint32_t value);
sc64_error_t sc64_sd_set_byte_swap (bool enabled);
sc64_error_t sc64_writeback_pending (bool *pending); sc64_error_t sc64_writeback_pending (bool *pending);
sc64_error_t sc64_writeback_enable (void *address); sc64_error_t sc64_writeback_enable (void *address);
sc64_error_t sc64_flash_program (void *address, size_t length);
sc64_error_t sc64_flash_wait_busy (void); sc64_error_t sc64_flash_wait_busy (void);
sc64_error_t sc64_flash_get_erase_block_size (size_t *erase_block_size); sc64_error_t sc64_flash_get_erase_block_size (size_t *erase_block_size);
sc64_error_t sc64_flash_erase_block (void *address); sc64_error_t sc64_flash_erase_block (void *address);