Refactor the emuNAND code
This commit is contained in:
parent
63073ea07f
commit
deb91d1d02
101
source/emunand.c
101
source/emunand.c
@ -25,64 +25,59 @@
|
|||||||
#include "fatfs/sdmmc/sdmmc.h"
|
#include "fatfs/sdmmc/sdmmc.h"
|
||||||
#include "../build/emunandpatch.h"
|
#include "../build/emunandpatch.h"
|
||||||
|
|
||||||
#define O3DS_TOSHIBA_NAND 0x1DD000
|
void locateEmuNand(u32 *emuHeader, FirmwareSource *emuNand)
|
||||||
|
|
||||||
#define O3DS_LEGACY_FAT 0x200000
|
|
||||||
#define O3DS_DEFAULT_FAT 0x1DE000
|
|
||||||
#define O3DS_MINIMUM_FAT 0x1D8000
|
|
||||||
|
|
||||||
#define N3DS_LEGACY_FAT 0x400000
|
|
||||||
#define N3DS_DEFAULT_FAT 0x3B2000
|
|
||||||
#define N3DS_MINIMUM_FAT 0x26E000
|
|
||||||
|
|
||||||
void locateEmuNand(u32 *off, u32 *head, FirmwareSource *emuNand)
|
|
||||||
{
|
{
|
||||||
static u8 temp[0x200];
|
static u8 temp[0x200];
|
||||||
|
|
||||||
const u32 nandSize = getMMCDevice(0)->total_size;
|
const u32 nandSize = getMMCDevice(0)->total_size;
|
||||||
const u32 nandLayoutO3DS[3] = { O3DS_LEGACY_FAT, O3DS_DEFAULT_FAT, O3DS_MINIMUM_FAT }; // Legacy, Default, Minimum
|
bool found = false;
|
||||||
const u32 nandLayoutN3DS[3] = { N3DS_LEGACY_FAT, N3DS_DEFAULT_FAT, N3DS_MINIMUM_FAT }; // Legacy, Default, Minimum
|
|
||||||
|
for (u32 i = 0; i < 3 && !found; i++)
|
||||||
u8 i;
|
{
|
||||||
u32 nandOffset;
|
u32 nandOffset;
|
||||||
bool found = false;
|
|
||||||
|
switch(i)
|
||||||
for (i = 0; i < 3; i++)
|
{
|
||||||
{
|
case 1:
|
||||||
if (i > 0 && *emuNand != FIRMWARE_EMUNAND2) break;
|
nandOffset = nandSize + 1; //"Default" layout
|
||||||
|
break;
|
||||||
// Check for 'Legacy', 'Default' and 'Minimum' partition layouts when checking for the 2nd EmuNAND
|
case 2:
|
||||||
nandOffset = (*emuNand == FIRMWARE_EMUNAND ? 0 : ((isN3DS || nandSize > O3DS_TOSHIBA_NAND) ? nandLayoutN3DS[i] : nandLayoutO3DS[i]));
|
nandOffset = isN3DS ? 0x26E000 : 0x1D8000; //"Minsize" layout
|
||||||
|
break;
|
||||||
// Exception for 2DS
|
default:
|
||||||
if (i == 2 && !isN3DS && nandOffset == N3DS_MINIMUM_FAT) nandOffset = O3DS_MINIMUM_FAT;
|
nandOffset = *emuNand == FIRMWARE_EMUNAND ? 0 : (nandSize > 0x200000 ? 0x400000 : 0x200000); //"Legacy" layout
|
||||||
|
break;
|
||||||
//Check for RedNAND
|
}
|
||||||
if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) && *(u32 *)(temp + 0x100) == NCSD_MAGIC)
|
|
||||||
{
|
//Check for RedNAND
|
||||||
*off = nandOffset + 1;
|
if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) && *(u32 *)(temp + 0x100) == NCSD_MAGIC)
|
||||||
*head = nandOffset + 1;
|
{
|
||||||
found = true;
|
emuOffset = nandOffset + 1;
|
||||||
break;
|
*emuHeader = nandOffset + 1;
|
||||||
}
|
found = true;
|
||||||
|
}
|
||||||
//Check for Gateway emuNAND
|
|
||||||
else if(!sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) && *(u32 *)(temp + 0x100) == NCSD_MAGIC)
|
//Check for Gateway emuNAND
|
||||||
{
|
else if(!sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) && *(u32 *)(temp + 0x100) == NCSD_MAGIC)
|
||||||
*off = nandOffset;
|
{
|
||||||
*head = nandOffset + nandSize;
|
emuOffset = nandOffset;
|
||||||
found = true;
|
*emuHeader = nandOffset + nandSize;
|
||||||
break;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if(*emuNand == FIRMWARE_EMUNAND) break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fallback to the first emuNAND if there's no second one,
|
/* Fallback to the first emuNAND if there's no second one,
|
||||||
or to SysNAND if there isn't any */
|
or to SysNAND if there isn't any */
|
||||||
if (!found)
|
if(!found)
|
||||||
{
|
{
|
||||||
*emuNand = (*emuNand == FIRMWARE_EMUNAND2) ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
|
if(*emuNand != FIRMWARE_EMUNAND)
|
||||||
if(*emuNand) locateEmuNand(off, head, emuNand);
|
{
|
||||||
}
|
*emuNand = FIRMWARE_EMUNAND;
|
||||||
|
locateEmuNand(emuHeader, emuNand);
|
||||||
|
}
|
||||||
|
else *emuNand = FIRMWARE_SYSNAND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u8 *getFreeK9Space(u8 *pos, u32 size)
|
static inline u8 *getFreeK9Space(u8 *pos, u32 size)
|
||||||
|
@ -29,5 +29,5 @@
|
|||||||
extern u32 emuOffset;
|
extern u32 emuOffset;
|
||||||
extern bool isN3DS;
|
extern bool isN3DS;
|
||||||
|
|
||||||
void locateEmuNand(u32 *off, u32 *head, FirmwareSource *emuNand);
|
void locateEmuNand(u32 *emuHeader, FirmwareSource *emuNand);
|
||||||
void patchEmuNand(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuHeader, u32 branchAdditive);
|
void patchEmuNand(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuHeader, u32 branchAdditive);
|
@ -341,34 +341,34 @@ static int Nand_Init()
|
|||||||
while((handleNAND.ret[0] & 0x80000000) == 0);
|
while((handleNAND.ret[0] & 0x80000000) == 0);
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10602, 0x0);
|
sdmmc_send_command(&handleNAND, 0x10602, 0x0);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10403, handleNAND.initarg << 0x10);
|
sdmmc_send_command(&handleNAND, 0x10403, handleNAND.initarg << 0x10);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10609, handleNAND.initarg << 0x10);
|
sdmmc_send_command(&handleNAND, 0x10609, handleNAND.initarg << 0x10);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
handleNAND.total_size = calcSDSize((u8*)&handleNAND.ret[0], 0);
|
handleNAND.total_size = calcSDSize((u8*)&handleNAND.ret[0], 0);
|
||||||
handleNAND.clk = 1;
|
handleNAND.clk = 1;
|
||||||
setckl(1);
|
setckl(1);
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10407, handleNAND.initarg << 0x10);
|
sdmmc_send_command(&handleNAND, 0x10407, handleNAND.initarg << 0x10);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
handleNAND.SDOPT = 1;
|
handleNAND.SDOPT = 1;
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10506, 0x3B70100);
|
sdmmc_send_command(&handleNAND, 0x10506, 0x3B70100);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10506, 0x3B90100);
|
sdmmc_send_command(&handleNAND, 0x10506, 0x3B90100);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x1040D, handleNAND.initarg << 0x10);
|
sdmmc_send_command(&handleNAND, 0x1040D, handleNAND.initarg << 0x10);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
sdmmc_send_command(&handleNAND, 0x10410, 0x200);
|
sdmmc_send_command(&handleNAND, 0x10410, 0x200);
|
||||||
if((handleNAND.error & 0x4))return -1;
|
if((handleNAND.error & 0x4)) return -1;
|
||||||
|
|
||||||
handleNAND.clk |= 0x200;
|
handleNAND.clk |= 0x200;
|
||||||
|
|
||||||
|
@ -195,13 +195,13 @@ void main(void)
|
|||||||
//If we need to boot emuNAND, make sure it exists
|
//If we need to boot emuNAND, make sure it exists
|
||||||
if(nandType != FIRMWARE_SYSNAND)
|
if(nandType != FIRMWARE_SYSNAND)
|
||||||
{
|
{
|
||||||
locateEmuNand(&emuOffset, &emuHeader, &nandType);
|
locateEmuNand(&emuHeader, &nandType);
|
||||||
if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND;
|
if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Same if we're using emuNAND as the FIRM source
|
//Same if we're using emuNAND as the FIRM source
|
||||||
else if(firmSource != FIRMWARE_SYSNAND)
|
else if(firmSource != FIRMWARE_SYSNAND)
|
||||||
locateEmuNand(&emuOffset, &emuHeader, &firmSource);
|
locateEmuNand(&emuHeader, &firmSource);
|
||||||
|
|
||||||
if(!isFirmlaunch)
|
if(!isFirmlaunch)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user