2015-08-05 03:57:37 +02:00
|
|
|
/*
|
|
|
|
* emunand.c
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "emunand.h"
|
2016-01-23 09:53:45 +01:00
|
|
|
#include "memory.h"
|
2015-08-05 03:57:37 +02:00
|
|
|
#include "fatfs/sdmmc/sdmmc.h"
|
|
|
|
|
2016-04-11 05:15:44 +02:00
|
|
|
void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND)
|
2016-04-02 17:58:06 +02:00
|
|
|
{
|
2016-04-14 17:10:55 +02:00
|
|
|
static u8 *const temp = (u8 *)0x24300000;
|
2016-03-10 14:58:11 +01:00
|
|
|
|
2016-03-31 15:57:02 +02:00
|
|
|
const u32 nandSize = getMMCDevice(0)->total_size;
|
|
|
|
u32 nandOffset = *emuNAND == 1 ? 0 :
|
2016-03-17 00:08:13 +01:00
|
|
|
(nandSize > 0x200000 ? 0x400000 : 0x200000);
|
|
|
|
|
2016-03-29 17:43:53 +02:00
|
|
|
//Check for RedNAND
|
2016-05-02 02:02:31 +02:00
|
|
|
if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) &&
|
|
|
|
*(u32 *)(temp + 0x100) == NCSD_MAGIC)
|
2016-04-02 17:58:06 +02:00
|
|
|
{
|
2016-05-02 02:02:31 +02:00
|
|
|
*off = nandOffset + 1;
|
|
|
|
*head = nandOffset + 1;
|
|
|
|
}
|
2016-04-04 18:19:00 +02:00
|
|
|
|
2016-05-02 02:02:31 +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
|
|
|
|
2016-05-02 02:02:31 +02:00
|
|
|
/* Fallback to the first emuNAND if there's no second one,
|
|
|
|
or to SysNAND if there isn't any */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
(*emuNAND)--;
|
|
|
|
if(*emuNAND) getEmunandSect(off, head, emuNAND);
|
2015-08-05 03:57:37 +02:00
|
|
|
}
|
2016-01-23 09:53:45 +01:00
|
|
|
}
|
|
|
|
|
2016-04-02 17:58:06 +02:00
|
|
|
u32 getSDMMC(u8 *pos, u32 size)
|
|
|
|
{
|
2016-01-23 09:53:45 +01:00
|
|
|
//Look for struct code
|
2016-03-26 19:21:17 +01:00
|
|
|
const u8 pattern[] = {0x21, 0x20, 0x18, 0x20};
|
2016-05-05 04:43:44 +02:00
|
|
|
const u8 *off = memsearch(pos, pattern, size, 4);
|
2016-03-21 18:56:41 +01:00
|
|
|
|
2016-05-05 04:43:44 +02:00
|
|
|
return *(u32 *)(off + 9) + *(u32 *)(off + 0xD);
|
2016-01-23 09:53:45 +01:00
|
|
|
}
|
|
|
|
|
2016-05-12 14:48:52 +02:00
|
|
|
void getEmuRW(u8 *pos, u32 size, u16 **readOffset, u16 **writeOffset)
|
2016-04-02 17:58:06 +02:00
|
|
|
{
|
2016-01-23 09:53:45 +01:00
|
|
|
//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-12 14:48:52 +02:00
|
|
|
*readOffset = (u16 *)memsearch(pos, pattern, size, 4) - 3;
|
|
|
|
*writeOffset = (u16 *)memsearch((u8 *)(*readOffset + 5), pattern, 0x100, 4) - 3;
|
2016-02-08 03:37:03 +01:00
|
|
|
}
|
|
|
|
|
2016-04-02 17:58:06 +02:00
|
|
|
u32 *getMPU(u8 *pos, u32 size)
|
|
|
|
{
|
2016-02-08 23:46:01 +01:00
|
|
|
//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-03-26 17:24:16 +01:00
|
|
|
return (u32 *)memsearch(pos, pattern, size, 4);
|
2016-03-21 03:20:15 +01:00
|
|
|
}
|
|
|
|
|
2016-05-11 19:28:28 +02:00
|
|
|
void *getEmuCode(u8 *pos)
|
2016-04-02 17:58:06 +02:00
|
|
|
{
|
2016-03-29 17:43:53 +02:00
|
|
|
const u8 pattern[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
|
|
|
|
|
2016-03-21 20:24:12 +01:00
|
|
|
//Looking for the last free space before Process9
|
2016-05-11 19:28:28 +02:00
|
|
|
return memsearch(pos + 0x13500, pattern, 0x1000, 6) + 0x455;
|
2015-08-05 03:57:37 +02:00
|
|
|
}
|