This repository has been archived on 2022-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
Luma3DS-3GX/source/emunand.c

114 lines
3.4 KiB
C
Raw Normal View History

2015-08-05 03:57:37 +02:00
/*
* emunand.c
*/
#include "emunand.h"
#include "memory.h"
2015-08-05 03:57:37 +02:00
#include "fatfs/sdmmc/sdmmc.h"
#include "../build/emunandpatch.h"
2015-08-05 03:57:37 +02:00
2016-06-12 22:14:52 +02:00
void locateEmuNAND(u32 *off, u32 *head, FirmwareSource *emuNAND)
{
2016-04-14 17:10:55 +02:00
static u8 *const temp = (u8 *)0x24300000;
2016-03-10 14:58:11 +01:00
const u32 nandSize = getMMCDevice(0)->total_size;
2016-06-12 22:14:52 +02:00
u32 nandOffset = *emuNAND == FIRMWARE_EMUNAND ? 0 :
(nandSize > 0x200000 ? 0x400000 : 0x200000);
//Check for RedNAND
if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) &&
*(u32 *)(temp + 0x100) == NCSD_MAGIC)
{
*off = nandOffset + 1;
*head = nandOffset + 1;
}
2016-04-04 18:19:00 +02:00
//Check for Gateway emuNAND
else if(!sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) &&
*(u32 *)(temp + 0x100) == NCSD_MAGIC)
{
*off = nandOffset;
*head = nandOffset + nandSize;
}
2016-04-04 18:19:00 +02:00
/* Fallback to the first emuNAND if there's no second one,
or to SysNAND if there isn't any */
else
{
2016-06-12 22:14:52 +02:00
*emuNAND = (*emuNAND == FIRMWARE_EMUNAND2) ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
if(*emuNAND) locateEmuNAND(off, head, emuNAND);
2015-08-05 03:57:37 +02:00
}
}
2016-05-25 15:26:51 +02:00
static inline void *getEmuCode(u8 *pos, u32 size)
{
const u8 pattern[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
//Looking for the last free space before Process9
return memsearch(pos + 0x13500, pattern, size - 0x13500, 6) + 0x455;
}
static inline u32 getSDMMC(u8 *pos, u32 size)
{
//Look for struct code
2016-03-26 19:21:17 +01:00
const u8 pattern[] = {0x21, 0x20, 0x18, 0x20};
const u8 *off = memsearch(pos, pattern, size, 4);
return *(u32 *)(off + 9) + *(u32 *)(off + 0xD);
}
2016-05-25 15:26:51 +02:00
static inline void patchNANDRW(u8 *pos, u32 size, u32 branchOffset)
{
2016-05-25 15:26:51 +02:00
const u16 nandRedir[2] = {0x4C00, 0x47A0};
//Look for read/write code
2016-03-26 19:21:17 +01:00
const u8 pattern[] = {0x1E, 0x00, 0xC8, 0x05};
2016-02-08 03:37:03 +01:00
2016-05-27 04:16:49 +02:00
u16 *readOffset = (u16 *)memsearch(pos, pattern, size, 4) - 3,
*writeOffset = (u16 *)memsearch((u8 *)(readOffset + 5), pattern, 0x100, 4) - 3;
2016-05-25 15:26:51 +02:00
*readOffset = nandRedir[0];
readOffset[1] = nandRedir[1];
((u32 *)readOffset)[1] = branchOffset;
*writeOffset = nandRedir[0];
writeOffset[1] = nandRedir[1];
((u32 *)writeOffset)[1] = branchOffset;
2016-02-08 03:37:03 +01:00
}
2016-05-25 15:26:51 +02:00
static inline void patchMPU(u8 *pos, u32 size)
{
2016-05-25 15:26:51 +02:00
const u32 mpuPatch[3] = {0x00360003, 0x00200603, 0x001C0603};
//Look for MPU pattern
2016-03-26 19:21:17 +01:00
const u8 pattern[] = {0x03, 0x00, 0x24, 0x00};
2016-02-08 03:37:03 +01:00
2016-05-25 15:26:51 +02:00
u32 *off = (u32 *)memsearch(pos, pattern, size, 4);
2016-05-25 15:26:51 +02:00
off[0] = mpuPatch[0];
off[6] = mpuPatch[1];
off[9] = mpuPatch[2];
}
2016-05-25 15:26:51 +02:00
void patchEmuNAND(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuOffset, u32 emuHeader, u32 branchAdditive)
{
//Copy emuNAND code
void *emuCodeOffset = getEmuCode(arm9Section, arm9SectionSize);
memcpy(emuCodeOffset, emunand, emunand_size);
//Add the data of the found emuNAND
2016-05-27 04:16:49 +02:00
u32 *pos_offset = (u32 *)memsearch(emuCodeOffset, "NAND", emunand_size, 4),
*pos_header = (u32 *)memsearch(emuCodeOffset, "NCSD", emunand_size, 4);
*pos_offset = emuOffset;
*pos_header = emuHeader;
//Find and add the SDMMC struct
u32 *pos_sdmmc = (u32 *)memsearch(emuCodeOffset, "SDMC", emunand_size, 4);
*pos_sdmmc = getSDMMC(process9Offset, process9Size);
//Add emuNAND hooks
u32 branchOffset = (u32)emuCodeOffset - branchAdditive;
2016-05-25 15:26:51 +02:00
patchNANDRW(process9Offset, process9Size, branchOffset);
//Set MPU for emu code region
2016-05-25 15:26:51 +02:00
patchMPU(arm9Section, arm9SectionSize);
2015-08-05 03:57:37 +02:00
}