Merge branch 'master' into developer
Conflicts: source/firm.c source/patches.c source/patches.h source/utils.h
This commit is contained in:
commit
ac01fe417e
@ -82,23 +82,23 @@ Result FSLDR_SetPriority(u32 priority)
|
|||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FSLDR_OpenFileDirectly(Handle* out, FS_Archive archive, FS_Path path, u32 openFlags, u32 attributes)
|
Result FSLDR_OpenFileDirectly(Handle* out, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 openFlags, u32 attributes)
|
||||||
{
|
{
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x803,8,4); // 0x8030204
|
cmdbuf[0] = IPC_MakeHeader(0x803,8,4); // 0x8030204
|
||||||
cmdbuf[1] = 0;
|
cmdbuf[1] = 0;
|
||||||
cmdbuf[2] = archive.id;
|
cmdbuf[2] = archiveId;
|
||||||
cmdbuf[3] = archive.lowPath.type;
|
cmdbuf[3] = archivePath.type;
|
||||||
cmdbuf[4] = archive.lowPath.size;
|
cmdbuf[4] = archivePath.size;
|
||||||
cmdbuf[5] = path.type;
|
cmdbuf[5] = filePath.type;
|
||||||
cmdbuf[6] = path.size;
|
cmdbuf[6] = filePath.size;
|
||||||
cmdbuf[7] = openFlags;
|
cmdbuf[7] = openFlags;
|
||||||
cmdbuf[8] = attributes;
|
cmdbuf[8] = attributes;
|
||||||
cmdbuf[9] = IPC_Desc_StaticBuffer(archive.lowPath.size, 2);
|
cmdbuf[9] = IPC_Desc_StaticBuffer(archivePath.size, 2);
|
||||||
cmdbuf[10] = (u32) archive.lowPath.data;
|
cmdbuf[10] = (u32)archivePath.data;
|
||||||
cmdbuf[11] = IPC_Desc_StaticBuffer(path.size, 0);
|
cmdbuf[11] = IPC_Desc_StaticBuffer(filePath.size, 0);
|
||||||
cmdbuf[12] = (u32) path.data;
|
cmdbuf[12] = (u32)filePath.data;
|
||||||
|
|
||||||
Result ret = 0;
|
Result ret = 0;
|
||||||
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
if(R_FAILED(ret = svcSendSyncRequest(fsldrHandle))) return ret;
|
||||||
|
@ -6,4 +6,4 @@ Result fsldrInit(void);
|
|||||||
void fsldrExit(void);
|
void fsldrExit(void);
|
||||||
Result FSLDR_InitializeWithSdkVersion(Handle session, u32 version);
|
Result FSLDR_InitializeWithSdkVersion(Handle session, u32 version);
|
||||||
Result FSLDR_SetPriority(u32 priority);
|
Result FSLDR_SetPriority(u32 priority);
|
||||||
Result FSLDR_OpenFileDirectly(Handle* out, FS_Archive archive, FS_Path path, u32 openFlags, u32 attributes);
|
Result FSLDR_OpenFileDirectly(Handle* out, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 openFlags, u32 attributes);
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
#include "ifile.h"
|
#include "ifile.h"
|
||||||
#include "fsldr.h"
|
#include "fsldr.h"
|
||||||
|
|
||||||
Result IFile_Open(IFile *file, FS_Archive archive, FS_Path path, u32 flags)
|
Result IFile_Open(IFile *file, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 flags)
|
||||||
{
|
{
|
||||||
Result res;
|
Result res;
|
||||||
|
|
||||||
res = FSLDR_OpenFileDirectly(&file->handle, archive, path, flags, 0);
|
res = FSLDR_OpenFileDirectly(&file->handle, archiveId, archivePath, filePath, flags, 0);
|
||||||
file->pos = 0;
|
file->pos = 0;
|
||||||
file->size = 0;
|
file->size = 0;
|
||||||
return res;
|
return res;
|
||||||
|
@ -9,7 +9,7 @@ typedef struct
|
|||||||
u64 size;
|
u64 size;
|
||||||
} IFile;
|
} IFile;
|
||||||
|
|
||||||
Result IFile_Open(IFile *file, FS_Archive archive, FS_Path path, u32 flags);
|
Result IFile_Open(IFile *file, FS_ArchiveID archiveId, FS_Path archivePath, FS_Path filePath, u32 flags);
|
||||||
Result IFile_Close(IFile *file);
|
Result IFile_Close(IFile *file);
|
||||||
Result IFile_GetSize(IFile *file, u64 *size);
|
Result IFile_GetSize(IFile *file, u64 *size);
|
||||||
Result IFile_Read(IFile *file, u64 *total, void *buffer, u32 len);
|
Result IFile_Read(IFile *file, u64 *total, void *buffer, u32 len);
|
@ -109,21 +109,20 @@ static Result allocate_shared_mem(prog_addrs_t *shared, prog_addrs_t *vaddr, int
|
|||||||
static Result load_code(u64 progid, prog_addrs_t *shared, u64 prog_handle, int is_compressed)
|
static Result load_code(u64 progid, prog_addrs_t *shared, u64 prog_handle, int is_compressed)
|
||||||
{
|
{
|
||||||
IFile file;
|
IFile file;
|
||||||
FS_Archive archive;
|
FS_Path archivePath;
|
||||||
FS_Path path;
|
FS_Path filePath;
|
||||||
Result res;
|
Result res;
|
||||||
u64 size;
|
u64 size;
|
||||||
u64 total;
|
u64 total;
|
||||||
|
|
||||||
archive.id = ARCHIVE_SAVEDATA_AND_CONTENT2;
|
archivePath.type = PATH_BINARY;
|
||||||
archive.lowPath.type = PATH_BINARY;
|
archivePath.data = &prog_handle;
|
||||||
archive.lowPath.data = &prog_handle;
|
archivePath.size = 8;
|
||||||
archive.lowPath.size = 8;
|
|
||||||
//archive.handle = prog_handle; // not needed
|
filePath.type = PATH_BINARY;
|
||||||
path.type = PATH_BINARY;
|
filePath.data = CODE_PATH;
|
||||||
path.data = CODE_PATH;
|
filePath.size = sizeof(CODE_PATH);
|
||||||
path.size = sizeof(CODE_PATH);
|
if (R_FAILED(IFile_Open(&file, ARCHIVE_SAVEDATA_AND_CONTENT2, archivePath, filePath, FS_OPEN_READ)))
|
||||||
if (R_FAILED(IFile_Open(&file, archive, path, FS_OPEN_READ)))
|
|
||||||
{
|
{
|
||||||
svcBreak(USERBREAK_ASSERT);
|
svcBreak(USERBREAK_ASSERT);
|
||||||
}
|
}
|
||||||
|
@ -82,21 +82,12 @@ static inline size_t strnlen(const char *string, size_t maxlen)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fileOpen(IFile *file, FS_ArchiveID id, const char *path, int flags)
|
static int fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags)
|
||||||
{
|
{
|
||||||
FS_Archive archive;
|
FS_Path filePath = {PATH_ASCII, strnlen(path, PATH_MAX) + 1, path},
|
||||||
FS_Path ppath;
|
archivePath = {PATH_EMPTY, 1, (u8 *)""};
|
||||||
|
|
||||||
size_t len = strnlen(path, PATH_MAX);
|
return IFile_Open(file, archiveId, archivePath, filePath, flags);
|
||||||
archive.id = id;
|
|
||||||
archive.lowPath.type = PATH_EMPTY;
|
|
||||||
archive.lowPath.size = 1;
|
|
||||||
archive.lowPath.data = (u8 *)"";
|
|
||||||
ppath.type = PATH_ASCII;
|
|
||||||
ppath.data = path;
|
|
||||||
ppath.size = len + 1;
|
|
||||||
|
|
||||||
return IFile_Open(file, archive, ppath, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 secureInfoExists(void)
|
static u32 secureInfoExists(void)
|
||||||
|
@ -7,14 +7,15 @@
|
|||||||
#include "screeninit.h"
|
#include "screeninit.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include "i2c.h"
|
||||||
#include "buttons.h"
|
#include "buttons.h"
|
||||||
|
|
||||||
void configureCFW(const char *configPath)
|
void configureCFW(const char *configPath)
|
||||||
{
|
{
|
||||||
initScreens();
|
u32 needToDeinit = initScreens();
|
||||||
|
|
||||||
drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE);
|
drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE);
|
||||||
drawString("Press A to select, START to save and reboot", 10, 30, COLOR_WHITE);
|
drawString("Press A to select, START to save", 10, 30, COLOR_WHITE);
|
||||||
|
|
||||||
const char *multiOptionsText[] = { "Screen-init brightness: 4( ) 3( ) 2( ) 1( )",
|
const char *multiOptionsText[] = { "Screen-init brightness: 4( ) 3( ) 2( ) 1( )",
|
||||||
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" };
|
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" };
|
||||||
@ -175,8 +176,16 @@ void configureCFW(const char *configPath)
|
|||||||
|
|
||||||
fileWrite(&config, configPath, 4);
|
fileWrite(&config, configPath, 4);
|
||||||
|
|
||||||
//Zero the last booted FIRM flag
|
//Wait for the pressed buttons to change
|
||||||
CFG_BOOTENV = 0;
|
while(HID_PAD == BUTTON_START);
|
||||||
|
|
||||||
mcuReboot();
|
if(needToDeinit)
|
||||||
|
{
|
||||||
|
//Turn off backlight
|
||||||
|
i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x16);
|
||||||
|
deinitScreens();
|
||||||
|
PDN_GPU_CNT = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(0x1400000);
|
||||||
}
|
}
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define CFG_BOOTENV (*(vu32 *)0x10010000)
|
|
||||||
|
|
||||||
#define CONFIG(a) ((config >> (a + 16)) & 1)
|
#define CONFIG(a) ((config >> (a + 16)) & 1)
|
||||||
#define MULTICONFIG(a) ((config >> (a * 2 + 6)) & 3)
|
#define MULTICONFIG(a) ((config >> (a * 2 + 6)) & 3)
|
||||||
#define BOOTCONFIG(a, b) ((config >> a) & b)
|
#define BOOTCONFIG(a, b) ((config >> a) & b)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "screeninit.h"
|
#include "screeninit.h"
|
||||||
|
#include "utils.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
@ -39,10 +40,7 @@ void loadSplash(void)
|
|||||||
//Don't delay boot if no splash image is on the SD
|
//Don't delay boot if no splash image is on the SD
|
||||||
if(fileRead(fb->top_left, "/luma/splash.bin") +
|
if(fileRead(fb->top_left, "/luma/splash.bin") +
|
||||||
fileRead(fb->bottom, "/luma/splashbottom.bin"))
|
fileRead(fb->bottom, "/luma/splashbottom.bin"))
|
||||||
{
|
delay(0x1400000);
|
||||||
u64 i = 0x1400000;
|
|
||||||
while(i--) __asm("mov r0, r0"); //Less Ghetto sleep func
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCharacter(char character, int posX, int posY, u32 color)
|
void drawCharacter(char character, int posX, int posY, u32 color)
|
||||||
|
@ -103,8 +103,16 @@ void main(void)
|
|||||||
|
|
||||||
//If no configuration file exists or SELECT is held, load configuration menu
|
//If no configuration file exists or SELECT is held, load configuration menu
|
||||||
if(needConfig == 2 || (pressed & BUTTON_SELECT))
|
if(needConfig == 2 || (pressed & BUTTON_SELECT))
|
||||||
|
{
|
||||||
configureCFW(configPath);
|
configureCFW(configPath);
|
||||||
|
|
||||||
|
//Zero the last booted FIRM flag
|
||||||
|
CFG_BOOTENV = 0;
|
||||||
|
|
||||||
|
//Update pressed buttons
|
||||||
|
pressed = HID_PAD;
|
||||||
|
}
|
||||||
|
|
||||||
u32 devMode = CONFIG(5);
|
u32 devMode = CONFIG(5);
|
||||||
|
|
||||||
if(devMode)
|
if(devMode)
|
||||||
@ -247,7 +255,7 @@ void main(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
launchFirm(bootType);
|
launchFirm(!firmType, bootType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void loadFirm(u32 firmType, u32 externalFirm)
|
static inline void loadFirm(u32 firmType, u32 externalFirm)
|
||||||
@ -414,14 +422,13 @@ static inline void patchReboots(u8 *arm9Section, u8 *proc9Offset)
|
|||||||
|
|
||||||
static inline void copySection0AndInjectLoader(void)
|
static inline void copySection0AndInjectLoader(void)
|
||||||
{
|
{
|
||||||
u32 loaderSize;
|
|
||||||
u8 *arm11Section0 = (u8 *)firm + section[0].offset;
|
u8 *arm11Section0 = (u8 *)firm + section[0].offset;
|
||||||
u32 injectorOffset = (u8 *)getLoader((u8 *)firm + section[0].offset, section[0].size, &loaderSize) - arm11Section0;
|
u32 loaderSize;
|
||||||
u32 remaining = section[0].size - (injectorOffset + loaderSize);
|
u32 loaderOffset = getLoader(arm11Section0, &loaderSize);
|
||||||
|
|
||||||
memcpy(section[0].address, arm11Section0, injectorOffset);
|
memcpy(section[0].address, arm11Section0, loaderOffset);
|
||||||
memcpy(section[0].address + injectorOffset, injector, injector_size);
|
memcpy(section[0].address + loaderOffset, injector, injector_size);
|
||||||
memcpy(section[0].address + injectorOffset + injector_size, arm11Section0 + section[0].size - remaining, remaining);
|
memcpy(section[0].address + loaderOffset + injector_size, arm11Section0 + loaderOffset + loaderSize, section[0].size - (loaderOffset + loaderSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void patchLegacyFirm(u32 firmType)
|
static inline void patchLegacyFirm(u32 firmType)
|
||||||
@ -503,10 +510,10 @@ static void patchFirmWrites(u8 *arm9Section, u32 mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void launchFirm(u32 bootType)
|
static inline void launchFirm(u32 firstSectionToCopy, u32 bootType)
|
||||||
{
|
{
|
||||||
//Copy FIRM sections to respective memory locations
|
//Copy FIRM sections to respective memory locations
|
||||||
for(u32 i = 1; i < 4 && section[i].size; i++)
|
for(u32 i = firstSectionToCopy; i < 4 && section[i].size; i++)
|
||||||
memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size);
|
memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size);
|
||||||
|
|
||||||
//Determine the ARM11 entry to use
|
//Determine the ARM11 entry to use
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#define PDN_MPCORE_CFG (*(vu32 *)0x10140FFC)
|
#define PDN_MPCORE_CFG (*(vu32 *)0x10140FFC)
|
||||||
#define PDN_SPI_CNT (*(vu32 *)0x101401C0)
|
#define PDN_SPI_CNT (*(vu32 *)0x101401C0)
|
||||||
|
#define CFG_BOOTENV (*(vu32 *)0x10010000)
|
||||||
|
|
||||||
//FIRM Header layout
|
//FIRM Header layout
|
||||||
typedef struct firmSectionHeader {
|
typedef struct firmSectionHeader {
|
||||||
@ -44,4 +45,4 @@ static inline void copySection0AndInjectLoader(void);
|
|||||||
static inline void patchLegacyFirm(u32 firmType);
|
static inline void patchLegacyFirm(u32 firmType);
|
||||||
static inline void patchSafeFirm(void);
|
static inline void patchSafeFirm(void);
|
||||||
static void patchFirmWrites(u8 *arm9Section, u32 mode);
|
static void patchFirmWrites(u8 *arm9Section, u32 mode);
|
||||||
static inline void launchFirm(u32 bootType);
|
static inline void launchFirm(u32 firstSectionToCopy, u32 bootType);
|
@ -82,18 +82,19 @@ u8 *getUnitInfoValueSet(u8 *pos, u32 size)
|
|||||||
return memsearch(pos, pattern, size, 4) + 3;
|
return memsearch(pos, pattern, size, 4) + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getLoader(u8 *pos, u32 size, u32 *loaderSize)
|
u32 getLoader(u8 *pos, u32 *loaderSize)
|
||||||
{
|
{
|
||||||
u8 *off = pos;
|
u8 *off = pos;
|
||||||
do
|
u32 size;
|
||||||
|
|
||||||
|
while(1)
|
||||||
{
|
{
|
||||||
if(*(u32 *)(off + 0x200) == 0x64616F6C) break; //"load"
|
size = *(u32 *)(off + 0x104) * 0x200;
|
||||||
off += *(u32 *)(off + 0x104) * 0x200; //size of the CXI
|
if(*(u32 *)(off + 0x200) == 0x64616F6C) break;
|
||||||
|
off += size;
|
||||||
}
|
}
|
||||||
while(off < pos + size);
|
|
||||||
|
|
||||||
if(off >= pos + size) return NULL;
|
*loaderSize = size;
|
||||||
|
|
||||||
*loaderSize = *(u32 *)(off + 0x104) * 0x200;
|
return (u32)(off - pos);
|
||||||
return off;
|
|
||||||
}
|
}
|
@ -26,4 +26,4 @@ u32 getfOpen(u8 *proc9Offset, void *rebootOffset);
|
|||||||
u16 *getFirmWrite(u8 *pos, u32 size);
|
u16 *getFirmWrite(u8 *pos, u32 size);
|
||||||
u16 *getFirmWriteSafe(u8 *pos, u32 size);
|
u16 *getFirmWriteSafe(u8 *pos, u32 size);
|
||||||
u8 *getUnitInfoValueSet(u8 *pos, u32 size);
|
u8 *getUnitInfoValueSet(u8 *pos, u32 size);
|
||||||
void *getLoader(u8 *pos, u32 size, u32 *loaderSize);
|
u32 getLoader(u8 *pos, u32 *loaderSize);
|
@ -43,9 +43,11 @@ void deinitScreens(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initScreens(void)
|
u32 initScreens(void)
|
||||||
{
|
{
|
||||||
if(PDN_GPU_CNT == 1)
|
u32 needToInit = PDN_GPU_CNT == 1;
|
||||||
|
|
||||||
|
if(needToInit)
|
||||||
{
|
{
|
||||||
u32 *const screenInitAddress = (u32 *)0x24FFFC00;
|
u32 *const screenInitAddress = (u32 *)0x24FFFC00;
|
||||||
|
|
||||||
@ -62,4 +64,6 @@ void initScreens(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearScreens();
|
clearScreens();
|
||||||
|
|
||||||
|
return needToInit;
|
||||||
}
|
}
|
@ -12,4 +12,4 @@
|
|||||||
#define PDN_GPU_CNT (*(vu8 *)0x10141200)
|
#define PDN_GPU_CNT (*(vu8 *)0x10141200)
|
||||||
|
|
||||||
void deinitScreens(void);
|
void deinitScreens(void);
|
||||||
void initScreens(void);
|
u32 initScreens(void);
|
@ -33,6 +33,11 @@ u32 waitInput(void)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delay(u64 length)
|
||||||
|
{
|
||||||
|
while(length--) __asm("mov r0, r0");
|
||||||
|
}
|
||||||
|
|
||||||
void mcuReboot(void)
|
void mcuReboot(void)
|
||||||
{
|
{
|
||||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2);
|
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2);
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
u32 waitInput(void);
|
u32 waitInput(void);
|
||||||
|
void delay(u64 length);
|
||||||
void mcuReboot(void);
|
void mcuReboot(void);
|
||||||
void error(const char *message);
|
|
Reference in New Issue
Block a user