Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3143e7e1d0 | ||
|
|
d03396d272 | ||
|
|
c8aa2e8a89 | ||
|
|
c7a3a0278c | ||
|
|
5924f60d06 | ||
|
|
cd68b66c03 |
@@ -42,6 +42,8 @@
|
|||||||
#include "arm9_exception_handlers.h"
|
#include "arm9_exception_handlers.h"
|
||||||
#include "large_patches.h"
|
#include "large_patches.h"
|
||||||
|
|
||||||
|
#define K11EXT_VA 0x70000000
|
||||||
|
|
||||||
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
||||||
{
|
{
|
||||||
u8 *temp = memsearch(pos, "NCCH", size, 4);
|
u8 *temp = memsearch(pos, "NCCH", size, 4);
|
||||||
@@ -134,7 +136,7 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32
|
|||||||
static const u8 patternHook3_4[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA}; //SGI0 setup code, etc.
|
static const u8 patternHook3_4[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA}; //SGI0 setup code, etc.
|
||||||
|
|
||||||
//Our kernel11 extension is initially loaded in VRAM
|
//Our kernel11 extension is initially loaded in VRAM
|
||||||
u32 kextTotalSize = *(u32 *)0x18000020 - 0x40000000;
|
u32 kextTotalSize = *(u32 *)0x18000020 - K11EXT_VA;
|
||||||
u32 dstKextPA = (ISN3DS ? 0x2E000000 : 0x26C00000) - kextTotalSize;
|
u32 dstKextPA = (ISN3DS ? 0x2E000000 : 0x26C00000) - kextTotalSize;
|
||||||
|
|
||||||
u32 *hookVeneers = (u32 *)*freeK11Space;
|
u32 *hookVeneers = (u32 *)*freeK11Space;
|
||||||
@@ -143,11 +145,11 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32
|
|||||||
hookVeneers[0] = 0xE51FF004; //ldr pc, [pc, #-8+4]
|
hookVeneers[0] = 0xE51FF004; //ldr pc, [pc, #-8+4]
|
||||||
hookVeneers[1] = 0x18000004;
|
hookVeneers[1] = 0x18000004;
|
||||||
hookVeneers[2] = 0xE51FF004;
|
hookVeneers[2] = 0xE51FF004;
|
||||||
hookVeneers[3] = 0x40000000;
|
hookVeneers[3] = K11EXT_VA;
|
||||||
hookVeneers[4] = 0xE51FF004;
|
hookVeneers[4] = 0xE51FF004;
|
||||||
hookVeneers[5] = 0x40000008;
|
hookVeneers[5] = K11EXT_VA + 8;
|
||||||
hookVeneers[6] = 0xE51FF004;
|
hookVeneers[6] = 0xE51FF004;
|
||||||
hookVeneers[7] = 0x4000000C;
|
hookVeneers[7] = K11EXT_VA + 0xC;
|
||||||
|
|
||||||
(*freeK11Space) += 32;
|
(*freeK11Space) += 32;
|
||||||
|
|
||||||
@@ -175,14 +177,14 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32
|
|||||||
off += 4;
|
off += 4;
|
||||||
*off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 24);
|
*off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 24);
|
||||||
|
|
||||||
struct KExtParameters *p = (struct KExtParameters *)(*(u32 *)0x18000024 - 0x40000000 + 0x18000000);
|
struct KExtParameters *p = (struct KExtParameters *)(*(u32 *)0x18000024 - K11EXT_VA + 0x18000000);
|
||||||
p->basePA = dstKextPA;
|
p->basePA = dstKextPA;
|
||||||
|
|
||||||
for(u32 i = 0; i < 4; i++)
|
for(u32 i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
u32 *handlerPos = getKernel11HandlerVAPos(pos, arm11ExceptionsPage, baseK11VA, 1 + i);
|
u32 *handlerPos = getKernel11HandlerVAPos(pos, arm11ExceptionsPage, baseK11VA, 1 + i);
|
||||||
p->originalHandlers[i] = (void *)*handlerPos;
|
p->originalHandlers[i] = (void *)*handlerPos;
|
||||||
*handlerPos = 0x40000010 + 4 * i;
|
*handlerPos = K11EXT_VA + 0x10 + 4 * i;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CfwInfo *info = &p->info;
|
struct CfwInfo *info = &p->info;
|
||||||
@@ -248,14 +250,14 @@ u32 patchKernel11(u8 *pos, u32 size, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm
|
|||||||
|
|
||||||
//Redirect enableUserExceptionHandlersForCPUExc (= true)
|
//Redirect enableUserExceptionHandlersForCPUExc (= true)
|
||||||
for(off = arm11ExceptionsPage; *off != 0x96007F9; off++);
|
for(off = arm11ExceptionsPage; *off != 0x96007F9; off++);
|
||||||
off[1] = 0x40000028;
|
off[1] = K11EXT_VA + 0x28;
|
||||||
|
|
||||||
off = (u32 *)memsearch(pos, patternKThreadDebugReschedule, size, sizeof(patternKThreadDebugReschedule));
|
off = (u32 *)memsearch(pos, patternKThreadDebugReschedule, size, sizeof(patternKThreadDebugReschedule));
|
||||||
if(off == NULL)
|
if(off == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
off[-5] = 0xE51FF004;
|
off[-5] = 0xE51FF004;
|
||||||
off[-4] = 0x4000002C;
|
off[-4] = K11EXT_VA + 0x2C;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ ENTRY(_start)
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
vram : ORIGIN = 0x18000000, LENGTH = 0x18180000 - 0x18000000 /* Up to the kernel builtins. */
|
vram : ORIGIN = 0x18000000, LENGTH = 0x18180000 - 0x18000000 /* Up to the kernel builtins. */
|
||||||
main : ORIGIN = 0x40000000, LENGTH = 1M
|
main : ORIGIN = 0x70000000, LENGTH = 1M
|
||||||
}
|
}
|
||||||
|
|
||||||
PHDRS
|
PHDRS
|
||||||
@@ -15,7 +15,7 @@ PHDRS
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
PROVIDE(__start__ = 0x40000000);
|
PROVIDE(__start__ = ORIGIN(main));
|
||||||
. = ABSOLUTE(__start__);
|
. = ABSOLUTE(__start__);
|
||||||
|
|
||||||
.text :
|
.text :
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
#include "svc/ConnectToPort.h"
|
#include "svc/ConnectToPort.h"
|
||||||
#include "svcHandler.h"
|
#include "svcHandler.h"
|
||||||
|
|
||||||
|
#define K11EXT_VA 0x70000000
|
||||||
|
|
||||||
struct KExtParameters
|
struct KExtParameters
|
||||||
{
|
{
|
||||||
u32 basePA;
|
u32 basePA;
|
||||||
@@ -41,13 +43,13 @@ struct KExtParameters
|
|||||||
CfwInfo cfwInfo;
|
CfwInfo cfwInfo;
|
||||||
} kExtParameters = { .basePA = 0x12345678 }; // place this in .data
|
} kExtParameters = { .basePA = 0x12345678 }; // place this in .data
|
||||||
|
|
||||||
static ALIGN(1024) u32 L2TableFor0x40000000[256] = {0};
|
static ALIGN(1024) u32 g_L2Table[256] = {0};
|
||||||
|
|
||||||
void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
||||||
{
|
{
|
||||||
struct KExtParameters *p0 = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + 0x18000000);
|
struct KExtParameters *p0 = (struct KExtParameters *)((u32)&kExtParameters - K11EXT_VA + 0x18000000);
|
||||||
struct KExtParameters *p = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + p0->basePA);
|
struct KExtParameters *p = (struct KExtParameters *)((u32)&kExtParameters - K11EXT_VA + p0->basePA);
|
||||||
u32 *L2Table = (u32 *)((u32)L2TableFor0x40000000 - 0x40000000 + p0->basePA);
|
u32 *L2Table = (u32 *)((u32)g_L2Table - K11EXT_VA + p0->basePA);
|
||||||
|
|
||||||
if(coreId == 0)
|
if(coreId == 0)
|
||||||
{
|
{
|
||||||
@@ -56,7 +58,7 @@ void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
|||||||
memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__);
|
memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__);
|
||||||
memset((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__);
|
memset((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__);
|
||||||
|
|
||||||
// Map the kernel ext to 0x40000000
|
// Map the kernel ext at K11EXT_VA
|
||||||
// 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA]
|
// 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA]
|
||||||
for(u32 offset = 0; offset < (u32)(__end__ - __start__); offset += 0x1000)
|
for(u32 offset = 0; offset < (u32)(__end__ - __start__); offset += 0x1000)
|
||||||
L2Table[offset >> 12] = (p0->basePA + offset) | 0x516;
|
L2Table[offset >> 12] = (p0->basePA + offset) | 0x516;
|
||||||
@@ -76,7 +78,7 @@ void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
|||||||
L1Table[i + (VA >> 20)] = PA | attribs;
|
L1Table[i + (VA >> 20)] = PA | attribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
L1Table[0x40000000 >> 20] = (u32)L2Table | 1;
|
L1Table[K11EXT_VA >> 20] = (u32)L2Table | 1;
|
||||||
|
|
||||||
p->L1MMUTableAddrs[coreId] = (u32)L1Table;
|
p->L1MMUTableAddrs[coreId] = (u32)L1Table;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4; // not implemented
|
res = 0xF8C007F4; // not implemented
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -105,13 +106,16 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
*out = L2C_CTRL & 1;
|
*out = L2C_CTRL & 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4;
|
res = 0xF8C007F4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4;
|
res = 0xF8C007F4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +132,10 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
if((u32)param <= getNumberOfCores())
|
if((u32)param <= getNumberOfCores())
|
||||||
*out = L1MMUTableAddrs[param - 1];
|
*out = L1MMUTableAddrs[param - 1];
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4;
|
res = 0xF8C007F4;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -136,6 +143,13 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x20000:
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GetSystemInfo(out, type, param);
|
GetSystemInfo(out, type, param);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -29,18 +29,18 @@ static inline void loadCFWInfo(void)
|
|||||||
{
|
{
|
||||||
s64 out;
|
s64 out;
|
||||||
|
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 3));
|
if(svcGetSystemInfo(&out, 0x20000, 0) != 1) panic(0xDEADCAFE);
|
||||||
|
|
||||||
|
svcGetSystemInfo(&out, 0x10000, 3);
|
||||||
config = (u32)out;
|
config = (u32)out;
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 4));
|
svcGetSystemInfo(&out, 0x10000, 4);
|
||||||
multiConfig = (u32)out;
|
multiConfig = (u32)out;
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 5));
|
svcGetSystemInfo(&out, 0x10000, 5);
|
||||||
bootConfig = (u32)out;
|
bootConfig = (u32)out;
|
||||||
|
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 0x201));
|
svcGetSystemInfo(&out, 0x10000, 0x201);
|
||||||
isN3DS = (bool)out;
|
isN3DS = (bool)out;
|
||||||
//assertSuccess(svcGetSystemInfo(&out, 0x10000, 0x202));
|
svcGetSystemInfo(&out, 0x10000, 0x203);
|
||||||
//needToInitSd = (bool)out;
|
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 0x203));
|
|
||||||
isSdMode = (bool)out;
|
isSdMode = (bool)out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout)
|
|||||||
|
|
||||||
// Send custom notification to at least Rosalina to make it relinquish some non-KIP services handles, stop the debugger, etc.
|
// Send custom notification to at least Rosalina to make it relinquish some non-KIP services handles, stop the debugger, etc.
|
||||||
if (numKips >= 6) {
|
if (numKips >= 6) {
|
||||||
notifySubscribers(0x1001);
|
notifySubscribers(0x2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send notification 0x100 to the currently running application
|
// Send notification 0x100 to the currently running application
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ static inline void exitPXI(void)
|
|||||||
static u8 ALIGN(8) receiverStack[THREAD_STACK_SIZE];
|
static u8 ALIGN(8) receiverStack[THREAD_STACK_SIZE];
|
||||||
static u8 ALIGN(8) senderStack[THREAD_STACK_SIZE];
|
static u8 ALIGN(8) senderStack[THREAD_STACK_SIZE];
|
||||||
static u8 ALIGN(8) PXISRV11HandlerStack[THREAD_STACK_SIZE];
|
static u8 ALIGN(8) PXISRV11HandlerStack[THREAD_STACK_SIZE];
|
||||||
|
static MyThread receiverThread = {0}, senderThread = {0}, PXISRV11HandlerThread = {0};
|
||||||
|
|
||||||
Result __sync_init(void);
|
Result __sync_init(void);
|
||||||
Result __sync_fini(void);
|
Result __sync_fini(void);
|
||||||
@@ -152,7 +153,6 @@ void initSystem(void)
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
Handle handles[10] = {0}; //notification handle + service handles
|
Handle handles[10] = {0}; //notification handle + service handles
|
||||||
MyThread receiverThread = {0}, senderThread = {0}, PXISRV11HandlerThread = {0};
|
|
||||||
|
|
||||||
for(u32 i = 0; i < 9; i++)
|
for(u32 i = 0; i < 9; i++)
|
||||||
assertSuccess(srvRegisterService(handles + 1 + i, serviceNames[i], 1));
|
assertSuccess(srvRegisterService(handles + 1 + i, serviceNames[i], 1));
|
||||||
|
|||||||
@@ -262,7 +262,10 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMemRegions)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (address < 0x40000000 ///< Limit to check for regions
|
s64 TTBCR;
|
||||||
|
svcGetSystemInfo(&TTBCR, 0x10002, 0);
|
||||||
|
|
||||||
|
while (address < (1u << (32 - (u32)TTBCR)) ///< Limit to check for regions
|
||||||
&& posInBuffer < maxPosInBuffer
|
&& posInBuffer < maxPosInBuffer
|
||||||
&& R_SUCCEEDED(svcQueryProcessMemory(&memi, &pagei, handle, address)))
|
&& R_SUCCEEDED(svcQueryProcessMemory(&memi, &pagei, handle, address)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ static const ServiceManagerNotificationEntry notifications[] = {
|
|||||||
{ 0x100 , handleTermNotification },
|
{ 0x100 , handleTermNotification },
|
||||||
//{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues
|
//{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues
|
||||||
{ 0x1000, handleNextApplicationDebuggedByForce },
|
{ 0x1000, handleNextApplicationDebuggedByForce },
|
||||||
{ 0x1001, relinquishConnectionSessions },
|
{ 0x2000, relinquishConnectionSessions },
|
||||||
{ 0x000, NULL },
|
{ 0x000, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -172,11 +172,8 @@ Result ntpSetTimeDate(const struct tm *localt)
|
|||||||
if (R_FAILED(res)) goto cleanup;
|
if (R_FAILED(res)) goto cleanup;
|
||||||
|
|
||||||
// First, set the config RTC offset to 0
|
// First, set the config RTC offset to 0
|
||||||
u8 rtcOff = 0;
|
u8 rtcOff[8] = {0};
|
||||||
u8 rtcOff2[8] = {0};
|
res = CFG_SetConfigInfoBlk4(8, 0x30001, rtcOff);
|
||||||
res = CFG_SetConfigInfoBlk4(1, 0x10000, &rtcOff);
|
|
||||||
if (R_FAILED(res)) goto cleanup;
|
|
||||||
res = CFG_SetConfigInfoBlk4(8, 0x30001, rtcOff2);
|
|
||||||
if (R_FAILED(res)) goto cleanup;
|
if (R_FAILED(res)) goto cleanup;
|
||||||
|
|
||||||
u8 yr = (u8)(localt->tm_year - 100);
|
u8 yr = (u8)(localt->tm_year - 100);
|
||||||
|
|||||||
Reference in New Issue
Block a user