mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-22 02:29:19 +01:00
Fixed SD card fault display + ROM boot changes
This commit is contained in:
parent
9f5557ff36
commit
25bb6f343c
323
src/boot/boot.c
323
src/boot/boot.c
@ -1,161 +1,162 @@
|
|||||||
#include <libdragon.h>
|
#include <libdragon.h>
|
||||||
|
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
#include "boot_io.h"
|
#include "boot_io.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
|
|
||||||
|
|
||||||
extern uint32_t ipl2 __attribute__((section(".data")));
|
#define C0_STATUS_FR (1 << 26)
|
||||||
|
#define C0_STATUS_CU0 (1 << 28)
|
||||||
|
#define C0_STATUS_CU1 (1 << 29)
|
||||||
typedef struct {
|
|
||||||
const uint32_t crc32;
|
|
||||||
const uint8_t seed;
|
extern uint32_t ipl2 __attribute__((section(".data")));
|
||||||
} ipl3_crc32_t;
|
|
||||||
|
|
||||||
static const ipl3_crc32_t ipl3_crc32[] = {
|
typedef struct {
|
||||||
{ .crc32 = 0x587BD543, .seed = 0xAC }, // 5101
|
const uint32_t crc32;
|
||||||
{ .crc32 = 0x6170A4A1, .seed = 0x3F }, // 6101
|
const uint8_t seed;
|
||||||
{ .crc32 = 0x009E9EA3, .seed = 0x3F }, // 7102
|
} ipl3_crc32_t;
|
||||||
{ .crc32 = 0x90BB6CB5, .seed = 0x3F }, // 6102/7101
|
|
||||||
{ .crc32 = 0x0B050EE0, .seed = 0x78 }, // x103
|
static const ipl3_crc32_t ipl3_crc32[] = {
|
||||||
{ .crc32 = 0x98BC2C86, .seed = 0x91 }, // x105
|
{ .crc32 = 0x587BD543, .seed = 0xAC }, // 5101
|
||||||
{ .crc32 = 0xACC8580A, .seed = 0x85 }, // x106
|
{ .crc32 = 0x6170A4A1, .seed = 0x3F }, // 6101
|
||||||
{ .crc32 = 0x0E018159, .seed = 0xDD }, // 5167
|
{ .crc32 = 0x009E9EA3, .seed = 0x3F }, // 7102
|
||||||
{ .crc32 = 0x10C68B18, .seed = 0xDD }, // NDXJ0
|
{ .crc32 = 0x90BB6CB5, .seed = 0x3F }, // 6102/7101
|
||||||
{ .crc32 = 0xBC605D0A, .seed = 0xDD }, // NDDJ0
|
{ .crc32 = 0x0B050EE0, .seed = 0x78 }, // x103
|
||||||
{ .crc32 = 0x502C4466, .seed = 0xDD }, // NDDJ1
|
{ .crc32 = 0x98BC2C86, .seed = 0x91 }, // x105
|
||||||
{ .crc32 = 0x0C965795, .seed = 0xDD }, // NDDJ2
|
{ .crc32 = 0xACC8580A, .seed = 0x85 }, // x106
|
||||||
{ .crc32 = 0x8FEBA21E, .seed = 0xDE }, // NDDE0
|
{ .crc32 = 0x0E018159, .seed = 0xDD }, // 5167
|
||||||
};
|
{ .crc32 = 0x10C68B18, .seed = 0xDD }, // NDXJ0
|
||||||
|
{ .crc32 = 0xBC605D0A, .seed = 0xDD }, // NDDJ0
|
||||||
|
{ .crc32 = 0x502C4466, .seed = 0xDD }, // NDDJ1
|
||||||
static io32_t *boot_get_device_base (boot_params_t *params) {
|
{ .crc32 = 0x0C965795, .seed = 0xDD }, // NDDJ2
|
||||||
io32_t *device_base_address = ROM_CART;
|
{ .crc32 = 0x8FEBA21E, .seed = 0xDE }, // NDDE0
|
||||||
if (params->device_type == BOOT_DEVICE_TYPE_DD) {
|
};
|
||||||
device_base_address = ROM_DDIPL;
|
|
||||||
}
|
|
||||||
return device_base_address;
|
static io32_t *boot_get_device_base (boot_params_t *params) {
|
||||||
}
|
io32_t *device_base_address = ROM_CART;
|
||||||
|
if (params->device_type == BOOT_DEVICE_TYPE_DD) {
|
||||||
static bool boot_detect_cic_seed (boot_params_t *params) {
|
device_base_address = ROM_DDIPL;
|
||||||
io32_t *base = boot_get_device_base(params);
|
}
|
||||||
|
return device_base_address;
|
||||||
uint32_t ipl3[1008] __attribute__((aligned(8)));
|
}
|
||||||
|
|
||||||
data_cache_hit_writeback_invalidate(ipl3, sizeof(ipl3));
|
static bool boot_detect_cic_seed (boot_params_t *params) {
|
||||||
dma_read_raw_async(ipl3, (uint32_t) (&base[16]), sizeof(ipl3));
|
io32_t *base = boot_get_device_base(params);
|
||||||
dma_wait();
|
|
||||||
|
uint32_t ipl3[1008] __attribute__((aligned(8)));
|
||||||
uint32_t crc32 = crc32_calculate(ipl3, sizeof(ipl3));
|
|
||||||
|
data_cache_hit_writeback_invalidate(ipl3, sizeof(ipl3));
|
||||||
for (int i = 0; i < sizeof(ipl3_crc32) / sizeof(ipl3_crc32_t); i++) {
|
dma_read_raw_async(ipl3, (uint32_t) (&base[16]), sizeof(ipl3));
|
||||||
if (ipl3_crc32[i].crc32 == crc32) {
|
dma_wait();
|
||||||
params->cic_seed = ipl3_crc32[i].seed;
|
|
||||||
return true;
|
uint32_t crc32 = crc32_calculate(ipl3, sizeof(ipl3));
|
||||||
}
|
|
||||||
}
|
for (int i = 0; i < sizeof(ipl3_crc32) / sizeof(ipl3_crc32_t); i++) {
|
||||||
|
if (ipl3_crc32[i].crc32 == crc32) {
|
||||||
return false;
|
params->cic_seed = ipl3_crc32[i].seed;
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool boot_is_warm (void) {
|
|
||||||
return (OS_INFO->reset_type == OS_INFO_RESET_TYPE_NMI);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void boot (boot_params_t *params) {
|
|
||||||
if (params->tv_type == BOOT_TV_TYPE_PASSTHROUGH) {
|
bool boot_is_warm (void) {
|
||||||
params->tv_type = OS_INFO->tv_type;
|
return (OS_INFO->reset_type == OS_INFO_RESET_TYPE_NMI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->detect_cic_seed) {
|
void boot (boot_params_t *params) {
|
||||||
if (!boot_detect_cic_seed(params)) {
|
if (params->tv_type == BOOT_TV_TYPE_PASSTHROUGH) {
|
||||||
params->cic_seed = 0x3F;
|
params->tv_type = OS_INFO->tv_type;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (params->detect_cic_seed) {
|
||||||
// asm volatile (
|
if (!boot_detect_cic_seed(params)) {
|
||||||
// "li $t1, %[status] \n"
|
params->cic_seed = 0x3F;
|
||||||
// "mtc0 $t1, $12 \n" ::
|
}
|
||||||
// [status] "i" (C0_SR_CU1 | C0_SR_CU0 | C0_SR_FR)
|
}
|
||||||
// );
|
|
||||||
|
OS_INFO->mem_size_6105 = OS_INFO->mem_size;
|
||||||
OS_INFO->mem_size_6105 = OS_INFO->mem_size;
|
|
||||||
|
C0_WRITE_STATUS(C0_STATUS_CU1 | C0_STATUS_CU0 | C0_STATUS_FR);
|
||||||
while (!(cpu_io_read(&SP->SR) & SP_SR_HALT));
|
|
||||||
|
while (!(cpu_io_read(&SP->SR) & SP_SR_HALT));
|
||||||
cpu_io_write(&SP->SR, SP_SR_CLR_INTR | SP_SR_SET_HALT);
|
|
||||||
|
cpu_io_write(&SP->SR, SP_SR_CLR_INTR | SP_SR_SET_HALT);
|
||||||
while (cpu_io_read(&SP->DMA_BUSY));
|
|
||||||
|
while (cpu_io_read(&SP->DMA_BUSY));
|
||||||
cpu_io_write(&PI->SR, PI_SR_CLR_INTR | PI_SR_RESET);
|
|
||||||
cpu_io_write(&VI->V_INTR, 0x3FF);
|
cpu_io_write(&PI->SR, PI_SR_CLR_INTR | PI_SR_RESET);
|
||||||
cpu_io_write(&VI->H_LIMITS, 0);
|
cpu_io_write(&VI->V_INTR, 0x3FF);
|
||||||
cpu_io_write(&VI->CURR_LINE, 0);
|
cpu_io_write(&VI->H_LIMITS, 0);
|
||||||
cpu_io_write(&AI->MADDR, 0);
|
cpu_io_write(&VI->CURR_LINE, 0);
|
||||||
cpu_io_write(&AI->LEN, 0);
|
cpu_io_write(&AI->MADDR, 0);
|
||||||
|
cpu_io_write(&AI->LEN, 0);
|
||||||
while (cpu_io_read(&SP->SR) & SP_SR_DMA_BUSY);
|
|
||||||
|
while (cpu_io_read(&SP->SR) & SP_SR_DMA_BUSY);
|
||||||
uint32_t *ipl2_src = &ipl2;
|
|
||||||
io32_t *ipl2_dst = SP_MEM->IMEM;
|
uint32_t *ipl2_src = &ipl2;
|
||||||
|
io32_t *ipl2_dst = SP_MEM->IMEM;
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
cpu_io_write(&ipl2_dst[i], ipl2_src[i]);
|
for (int i = 0; i < 8; i++) {
|
||||||
}
|
cpu_io_write(&ipl2_dst[i], ipl2_src[i]);
|
||||||
|
}
|
||||||
cpu_io_write(&PI->DOM[0].LAT, 0xFF);
|
|
||||||
cpu_io_write(&PI->DOM[0].PWD, 0xFF);
|
cpu_io_write(&PI->DOM[0].LAT, 0xFF);
|
||||||
cpu_io_write(&PI->DOM[0].PGS, 0x0F);
|
cpu_io_write(&PI->DOM[0].PWD, 0xFF);
|
||||||
cpu_io_write(&PI->DOM[0].RLS, 0x03);
|
cpu_io_write(&PI->DOM[0].PGS, 0x0F);
|
||||||
|
cpu_io_write(&PI->DOM[0].RLS, 0x03);
|
||||||
io32_t *base = boot_get_device_base(params);
|
|
||||||
uint32_t pi_config = io_read((uint32_t) (base));
|
io32_t *base = boot_get_device_base(params);
|
||||||
|
uint32_t pi_config = io_read((uint32_t) (base));
|
||||||
cpu_io_write(&PI->DOM[0].LAT, pi_config & 0xFF);
|
|
||||||
cpu_io_write(&PI->DOM[0].PWD, pi_config >> 8);
|
cpu_io_write(&PI->DOM[0].LAT, pi_config & 0xFF);
|
||||||
cpu_io_write(&PI->DOM[0].PGS, pi_config >> 16);
|
cpu_io_write(&PI->DOM[0].PWD, pi_config >> 8);
|
||||||
cpu_io_write(&PI->DOM[0].RLS, pi_config >> 20);
|
cpu_io_write(&PI->DOM[0].PGS, pi_config >> 16);
|
||||||
|
cpu_io_write(&PI->DOM[0].RLS, pi_config >> 20);
|
||||||
if (cpu_io_read(&DPC->SR) & DPC_SR_XBUS_DMEM_DMA) {
|
|
||||||
while (cpu_io_read(&DPC->SR) & DPC_SR_PIPE_BUSY);
|
if (cpu_io_read(&DPC->SR) & DPC_SR_XBUS_DMEM_DMA) {
|
||||||
}
|
while (cpu_io_read(&DPC->SR) & DPC_SR_PIPE_BUSY);
|
||||||
|
}
|
||||||
io32_t *ipl3_src = base;
|
|
||||||
io32_t *ipl3_dst = SP_MEM->DMEM;
|
io32_t *ipl3_src = base;
|
||||||
|
io32_t *ipl3_dst = SP_MEM->DMEM;
|
||||||
for (int i = 16; i < 1024; i++) {
|
|
||||||
cpu_io_write(&ipl3_dst[i], io_read((uint32_t) (&ipl3_src[i])));
|
for (int i = 16; i < 1024; i++) {
|
||||||
}
|
cpu_io_write(&ipl3_dst[i], io_read((uint32_t) (&ipl3_src[i])));
|
||||||
|
}
|
||||||
register void (*entry_point)(void) asm ("t3");
|
|
||||||
register uint32_t boot_device asm ("s3");
|
register void (*entry_point)(void) asm ("t3");
|
||||||
register uint32_t tv_type asm ("s4");
|
register uint32_t boot_device asm ("s3");
|
||||||
register uint32_t reset_type asm ("s5");
|
register uint32_t tv_type asm ("s4");
|
||||||
register uint32_t cic_seed asm ("s6");
|
register uint32_t reset_type asm ("s5");
|
||||||
register uint32_t version asm ("s7");
|
register uint32_t cic_seed asm ("s6");
|
||||||
void *stack_pointer;
|
register uint32_t version asm ("s7");
|
||||||
|
void *stack_pointer;
|
||||||
entry_point = (void (*)(void)) UNCACHED(&SP_MEM->DMEM[16]);
|
|
||||||
boot_device = (params->device_type & 0x01);
|
entry_point = (void (*)(void)) UNCACHED(&SP_MEM->DMEM[16]);
|
||||||
tv_type = (params->tv_type & 0x03);
|
boot_device = (params->device_type & 0x01);
|
||||||
reset_type = (params->reset_type & 0x01);
|
tv_type = (params->tv_type & 0x03);
|
||||||
cic_seed = (params->cic_seed & 0xFF);
|
reset_type = (params->reset_type & 0x01);
|
||||||
version = (params->tv_type == BOOT_TV_TYPE_PAL) ? 6 : 1;
|
cic_seed = (params->cic_seed & 0xFF);
|
||||||
stack_pointer = (void *) UNCACHED(&SP_MEM->IMEM[1020]);
|
version = (params->tv_type == BOOT_TV_TYPE_PAL) ? 6 : 1;
|
||||||
|
stack_pointer = (void *) UNCACHED(&SP_MEM->IMEM[1020]);
|
||||||
asm volatile (
|
|
||||||
"move $sp, %[stack_pointer] \n"
|
asm volatile (
|
||||||
"jr %[entry_point] \n" ::
|
"move $sp, %[stack_pointer] \n"
|
||||||
[entry_point] "r" (entry_point),
|
"jr %[entry_point] \n" ::
|
||||||
[boot_device] "r" (boot_device),
|
[entry_point] "r" (entry_point),
|
||||||
[tv_type] "r" (tv_type),
|
[boot_device] "r" (boot_device),
|
||||||
[reset_type] "r" (reset_type),
|
[tv_type] "r" (tv_type),
|
||||||
[cic_seed] "r" (cic_seed),
|
[reset_type] "r" (reset_type),
|
||||||
[version] "r" (version),
|
[cic_seed] "r" (cic_seed),
|
||||||
[stack_pointer] "r" (stack_pointer)
|
[version] "r" (version),
|
||||||
);
|
[stack_pointer] "r" (stack_pointer)
|
||||||
|
);
|
||||||
while (1);
|
|
||||||
}
|
while (1);
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@ static flashcart_t *flashcart = &((flashcart_t) {
|
|||||||
|
|
||||||
|
|
||||||
flashcart_error_t flashcart_init (void) {
|
flashcart_error_t flashcart_init (void) {
|
||||||
|
bool sd_initialized;
|
||||||
flashcart_error_t error;
|
flashcart_error_t error;
|
||||||
|
|
||||||
// HACK: Because libcart reads PI config from address 0x10000000 when initializing
|
// HACK: Because libcart reads PI config from address 0x10000000 when initializing
|
||||||
@ -48,9 +49,7 @@ flashcart_error_t flashcart_init (void) {
|
|||||||
extern uint32_t cart_dom1;
|
extern uint32_t cart_dom1;
|
||||||
cart_dom1 = 0x80371240;
|
cart_dom1 = 0x80371240;
|
||||||
|
|
||||||
if (!debug_init_sdfs("sd:/", -1)) {
|
sd_initialized = debug_init_sdfs("sd:/", -1);
|
||||||
return FLASHCART_ERROR_NOT_DETECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Flashcart model is extracted from libcart after debug_init_sdfs call is made
|
// NOTE: Flashcart model is extracted from libcart after debug_init_sdfs call is made
|
||||||
extern int cart_type;
|
extern int cart_type;
|
||||||
@ -66,13 +65,17 @@ flashcart_error_t flashcart_init (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FLASHCART_ERROR_UNSUPPORTED;
|
return FLASHCART_ERROR_NOT_DETECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = flashcart->init()) != FLASHCART_OK) {
|
if ((error = flashcart->init()) != FLASHCART_OK) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sd_initialized) {
|
||||||
|
return FLASHCART_ERROR_SD_CARD;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MENU_NO_USB_LOG
|
#ifndef MENU_NO_USB_LOG
|
||||||
// NOTE: Some flashcarts doesn't have USB port, can't throw error here
|
// NOTE: Some flashcarts doesn't have USB port, can't throw error here
|
||||||
debug_init_usblog();
|
debug_init_usblog();
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
FLASHCART_OK,
|
FLASHCART_OK,
|
||||||
FLASHCART_ERROR_NOT_DETECTED,
|
FLASHCART_ERROR_NOT_DETECTED,
|
||||||
FLASHCART_ERROR_UNSUPPORTED,
|
|
||||||
FLASHCART_ERROR_OUTDATED,
|
FLASHCART_ERROR_OUTDATED,
|
||||||
|
FLASHCART_ERROR_SD_CARD,
|
||||||
FLASHCART_ERROR_ARGS,
|
FLASHCART_ERROR_ARGS,
|
||||||
FLASHCART_ERROR_LOAD,
|
FLASHCART_ERROR_LOAD,
|
||||||
FLASHCART_ERROR_INT,
|
FLASHCART_ERROR_INT,
|
||||||
|
@ -11,10 +11,10 @@ static char *format_flashcart_error (flashcart_error_t error) {
|
|||||||
return "No error";
|
return "No error";
|
||||||
case FLASHCART_ERROR_NOT_DETECTED:
|
case FLASHCART_ERROR_NOT_DETECTED:
|
||||||
return "No flashcart hardware was detected";
|
return "No flashcart hardware was detected";
|
||||||
case FLASHCART_ERROR_UNSUPPORTED:
|
|
||||||
return "Unsupported flashcart";
|
|
||||||
case FLASHCART_ERROR_OUTDATED:
|
case FLASHCART_ERROR_OUTDATED:
|
||||||
return "Outdated flashcart firmware";
|
return "Outdated flashcart firmware";
|
||||||
|
case FLASHCART_ERROR_SD_CARD:
|
||||||
|
return "Error during SD card initialization";
|
||||||
case FLASHCART_ERROR_ARGS:
|
case FLASHCART_ERROR_ARGS:
|
||||||
return "Invalid argument passed to flashcart function";
|
return "Invalid argument passed to flashcart function";
|
||||||
case FLASHCART_ERROR_LOAD:
|
case FLASHCART_ERROR_LOAD:
|
||||||
|
@ -181,7 +181,7 @@ static void load (menu_t *menu) {
|
|||||||
path_free(path);
|
path_free(path);
|
||||||
|
|
||||||
menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
|
menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
|
||||||
menu->boot_params->reset_type = BOOT_RESET_TYPE_COLD;
|
menu->boot_params->reset_type = BOOT_RESET_TYPE_NMI;
|
||||||
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
|
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
|
||||||
menu->boot_params->detect_cic_seed = true;
|
menu->boot_params->detect_cic_seed = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user