APT : preliminary/experimental return to menu support

This commit is contained in:
smea 2014-02-01 00:23:59 +01:00
parent 08afa38c10
commit 4250f91d55
9 changed files with 303 additions and 130 deletions

View File

@ -9,52 +9,25 @@
#include <ctr/svc.h> #include <ctr/svc.h>
#include "costable.h" #include "costable.h"
Handle APTevents[2];
Handle aptLockHandle;
void aptInit()
{
Handle aptuHandle;
//initialize APT stuff, escape load screen
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_GetLockHandle(aptuHandle, 0x0, &aptLockHandle);
svc_closeHandle(aptuHandle);
svc_waitSynchronization1(aptLockHandle, U64_MAX); //APT lock handle is used because we need to wait for NS to be ready for us
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_Initialize(aptuHandle, APPID_APPLICATION, &APTevents[0], &APTevents[1]);
svc_closeHandle(aptuHandle);
svc_releaseMutex(aptLockHandle); //release the lock
svc_waitSynchronization1(aptLockHandle, U64_MAX);
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_Enable(aptuHandle, 0x0);
svc_closeHandle(aptuHandle);
svc_releaseMutex(aptLockHandle);
}
u8* gspHeap; u8* gspHeap;
u32* gxCmdBuf; u32* gxCmdBuf;
Handle gspGpuHandle;
u8 currentBuffer; u8 currentBuffer;
u8* topLeftFramebuffers[2]; u8* topLeftFramebuffers[2];
void gspGpuInit() void gspGpuInit()
{ {
//do stuff with GPU... gspInit();
srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu");
GSPGPU_AcquireRight(gspGpuHandle, 0x0); GSPGPU_AcquireRight(NULL, 0x0);
GSPGPU_SetLcdForceBlack(gspGpuHandle, 0x0); GSPGPU_SetLcdForceBlack(NULL, 0x0);
//set subscreen to blue //set subscreen to blue
u32 regData=0x01FF0000; u32 regData=0x01FF0000;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)&regData, 4); GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 4);
//grab main left screen framebuffer addresses //grab main left screen framebuffer addresses
GSPGPU_ReadHWRegs(gspGpuHandle, 0x400468, (u8*)&topLeftFramebuffers, 8); GSPGPU_ReadHWRegs(NULL, 0x400468, (u8*)&topLeftFramebuffers, 8);
//convert PA to VA (assuming FB in VRAM) //convert PA to VA (assuming FB in VRAM)
topLeftFramebuffers[0]+=0x7000000; topLeftFramebuffers[0]+=0x7000000;
@ -64,7 +37,7 @@ void gspGpuInit()
u8 threadID; u8 threadID;
Handle gspEvent, gspSharedMemHandle; Handle gspEvent, gspSharedMemHandle;
svc_createEvent(&gspEvent, 0x0); svc_createEvent(&gspEvent, 0x0);
GSPGPU_RegisterInterruptRelayQueue(gspGpuHandle, gspEvent, 0x1, &gspSharedMemHandle, &threadID); GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID);
svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000);
//map GSP heap //map GSP heap
@ -82,10 +55,10 @@ void gspGpuInit()
void swapBuffers() void swapBuffers()
{ {
u32 regData; u32 regData;
GSPGPU_ReadHWRegs(gspGpuHandle, 0x400478, (u8*)&regData, 4); GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)&regData, 4);
regData^=1; regData^=1;
currentBuffer=regData&1; currentBuffer=regData&1;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)&regData, 4); GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)&regData, 4);
} }
void copyBuffer() void copyBuffer()
@ -93,7 +66,7 @@ void copyBuffer()
//copy topleft FB //copy topleft FB
u8 copiedBuffer=currentBuffer^1; u8 copiedBuffer=currentBuffer^1;
u8* bufAdr=&gspHeap[0x46500*copiedBuffer]; u8* bufAdr=&gspHeap[0x46500*copiedBuffer];
GSPGPU_FlushDataCache(gspGpuHandle, bufAdr, 0x46500); GSPGPU_FlushDataCache(NULL, bufAdr, 0x46500);
//GX RequestDma //GX RequestDma
u32 gxCommand[0x8]; u32 gxCommand[0x8];
gxCommand[0]=0x00; //CommandID gxCommand[0]=0x00; //CommandID
@ -102,7 +75,7 @@ void copyBuffer()
gxCommand[3]=0x46500; //size gxCommand[3]=0x46500; //size
gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0;
GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, gspGpuHandle); GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, NULL);
} }
s32 pcCos(u16 v) s32 pcCos(u16 v)
@ -143,6 +116,8 @@ int main()
HIDUSER_Init(hidHandle); HIDUSER_Init(hidHandle);
aptSetupEventHandler();
while(1) while(1)
{ {
u32 PAD=((u32*)0x10000000)[7]; u32 PAD=((u32*)0x10000000)[7];
@ -150,7 +125,7 @@ int main()
swapBuffers(); swapBuffers();
copyBuffer(); copyBuffer();
u32 regData=PAD|0x01000000; u32 regData=PAD|0x01000000;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)&regData, 4); GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 4);
svc_sleepThread(1000000000); svc_sleepThread(1000000000);
} }

View File

@ -8,14 +8,22 @@ typedef enum{
APPID_APPLICATION = 0x300, // Application APPID_APPLICATION = 0x300, // Application
}NS_APPID; // cf http://3dbrew.org/wiki/NS#AppIDs }NS_APPID; // cf http://3dbrew.org/wiki/NS#AppIDs
Result APT_GetLockHandle(Handle handle, u16 flags, Handle* lockHandle); extern Handle aptEvents[3];
Result APT_Initialize(Handle handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2);
Result APT_Enable(Handle handle, u32 a); void aptInit();
Result APT_PrepareToJumpToHomeMenu(Handle handle); void aptOpenSession();
Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c); void aptCloseSession();
Result APT_InquireNotification(Handle handle, u32 appID, u8* signalType); void aptSetupEventHandler();
Result APT_NotifyToWait(Handle handle, NS_APPID appID);
Result APT_GlanceParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize); Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle);
Result APT_ReceiveParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize); Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2);
Result APT_Enable(Handle* handle, u32 a);
Result APT_PrepareToJumpToHomeMenu(Handle* handle);
Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c);
Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType);
Result APT_NotifyToWait(Handle* handle, NS_APPID appID);
Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2);
Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize);
Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize);
#endif #endif

View File

@ -1,13 +1,16 @@
#ifndef GSP_H #ifndef GSP_H
#define GSP_H #define GSP_H
Result GSPGPU_AcquireRight(Handle handle, u8 flags); void gspInit();
Result GSPGPU_SetLcdForceBlack(Handle handle, u8 flags);
Result GSPGPU_FlushDataCache(Handle handle, u8* adr, u32 size); Result GSPGPU_AcquireRight(Handle *handle, u8 flags);
Result GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size); Result GSPGPU_ReleaseRight(Handle *handle);
Result GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size); Result GSPGPU_SetLcdForceBlack(Handle *handle, u8 flags);
Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID); Result GSPGPU_FlushDataCache(Handle *handle, u8* adr, u32 size);
Result GSPGPU_TriggerCmdReqQueue(Handle handle); Result GSPGPU_WriteHWRegs(Handle *handle, u32 regAddr, u8* data, u8 size);
Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x20], Handle handle); Result GSPGPU_ReadHWRegs(Handle *handle, u32 regAddr, u8* data, u8 size);
Result GSPGPU_RegisterInterruptRelayQueue(Handle *handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID);
Result GSPGPU_TriggerCmdReqQueue(Handle *handle);
Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x20], Handle* handle);
#endif #endif

View File

@ -4,6 +4,8 @@
u32* getThreadCommandBuffer(void); u32* getThreadCommandBuffer(void);
void svc_exitProcess(void); void svc_exitProcess(void);
Result svc_createThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stacktop, s32 threadpriority, s32 processorid);
void svc_exitThread();
void svc_sleepThread(s64 ns); void svc_sleepThread(s64 ns);
Result svc_releaseMutex(Handle handle); Result svc_releaseMutex(Handle handle);
Result svc_controlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions); //(outaddr is usually the same as the input addr0) Result svc_controlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions); //(outaddr is usually the same as the input addr0)

View File

@ -30,5 +30,6 @@
typedef u32 Handle; typedef u32 Handle;
typedef s32 Result; typedef s32 Result;
typedef void (*ThreadFunc)(u32);
#endif #endif

View File

@ -2,32 +2,161 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctr/types.h> #include <ctr/types.h>
#include <ctr/srv.h>
#include <ctr/APT.h> #include <ctr/APT.h>
#include <ctr/GSP.h>
#include <ctr/svc.h> #include <ctr/svc.h>
Result APT_GetLockHandle(Handle handle, u16 flags, Handle* lockHandle) #define APT_HANDLER_STACKSIZE (0x10000)
Handle aptLockHandle;
Handle aptuHandle;
Handle aptEvents[3];
Handle aptEventHandlerThread;
u64 aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]; //u64 so that it's 8-byte aligned
u32 aptParameters[0x1000/4]; //TEMP
void aptEventHandler(u32 arg)
{ {
bool runThread=true;
while(runThread)
{
s32 syncedID=0x0;
svc_waitSynchronizationN(&syncedID, aptEvents, 2, 0, U64_MAX);
svc_clearEvent(aptEvents[syncedID]);
switch(syncedID)
{
case 0x0: //event 0 means we got a signal from NS (home button, power button etc)
{
u8 signalType;
aptOpenSession();
APT_InquireNotification(NULL, APPID_APPLICATION, &signalType); //check signal type
aptCloseSession();
switch(signalType)
{
case 0x1: //home menu button got pressed
aptOpenSession();
APT_PrepareToJumpToHomeMenu(NULL); //prepare for return to menu
aptCloseSession();
GSPGPU_ReleaseRight(NULL); //disable GSP module access
aptOpenSession();
APT_JumpToHomeMenu(NULL, 0x0, 0x0, 0x0); //jump !
aptCloseSession();
break;
}
}
break;
case 0x1: //event 1 means app just started or we're returning to app
{
aptOpenSession();
APT_ReceiveParameter(NULL, APPID_APPLICATION, 0x1000, aptParameters, NULL);
aptCloseSession();
// if(!draw)GSPGPU_AcquireRight(NULL, 0x0);
}
break;
case 0x2: //event 2 means we should exit the thread
runThread=false;
break;
}
}
svc_exitThread();
}
void aptInit()
{
//initialize APT stuff, escape load screen
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_GetLockHandle(&aptuHandle, 0x0, &aptLockHandle);
svc_closeHandle(aptuHandle);
aptOpenSession();
APT_Initialize(NULL, APPID_APPLICATION, &aptEvents[0], &aptEvents[1]);
aptCloseSession();
aptOpenSession();
APT_Enable(NULL, 0x0);
aptCloseSession();
aptOpenSession();
APT_NotifyToWait(NULL, APPID_APPLICATION);
aptCloseSession();
}
void aptSetupEventHandler()
{
u8 buf1[4], buf2[4];
buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; buf1[3]=0x04;
aptOpenSession();
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
aptCloseSession();
aptOpenSession();
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
aptCloseSession();
aptOpenSession();
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
aptCloseSession();
buf1[0]=0x13; buf1[1]=0x00; buf1[2]=0x10; buf1[3]=0x00;
aptOpenSession();
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
aptCloseSession();
aptOpenSession();
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
aptCloseSession();
//create thread for stuff handling APT events
svc_createThread(&aptEventHandlerThread, aptEventHandler, 0x0, (u32*)(&aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]), 0x31, 0xfffffffe);
}
void aptOpenSession()
{
svc_waitSynchronization1(aptLockHandle, U64_MAX);
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
}
void aptCloseSession()
{
svc_closeHandle(aptuHandle);
svc_releaseMutex(aptLockHandle);
}
Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle)
{
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x10040; //request header code cmdbuf[0]=0x10040; //request header code
cmdbuf[1]=flags; cmdbuf[1]=flags;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
if(lockHandle)*lockHandle=cmdbuf[5]; if(lockHandle)*lockHandle=cmdbuf[5];
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_Initialize(Handle handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2) Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x20080; //request header code cmdbuf[0]=0x20080; //request header code
cmdbuf[1]=appId; cmdbuf[1]=appId;
cmdbuf[2]=0x0; cmdbuf[2]=0x0;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
if(eventHandle1)*eventHandle1=cmdbuf[3]; //return to menu event ? if(eventHandle1)*eventHandle1=cmdbuf[3]; //return to menu event ?
if(eventHandle2)*eventHandle2=cmdbuf[4]; if(eventHandle2)*eventHandle2=cmdbuf[4];
@ -35,45 +164,49 @@ Result APT_Initialize(Handle handle, NS_APPID appId, Handle* eventHandle1, Handl
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_Enable(Handle handle, u32 a) Result APT_Enable(Handle* handle, u32 a)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x30040; //request header code cmdbuf[0]=0x30040; //request header code
cmdbuf[1]=a; cmdbuf[1]=a;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_InquireNotification(Handle handle, u32 appID, u8* signalType) Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0xB0040; //request header code cmdbuf[0]=0xB0040; //request header code
cmdbuf[1]=appID; cmdbuf[1]=appID;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
if(signalType)*signalType=cmdbuf[2]; if(signalType)*signalType=cmdbuf[2];
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_PrepareToJumpToHomeMenu(Handle handle) Result APT_PrepareToJumpToHomeMenu(Handle* handle)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x2b0000; //request header code cmdbuf[0]=0x2b0000; //request header code
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c) Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x2C0044; //request header code cmdbuf[0]=0x2C0044; //request header code
cmdbuf[1]=a; cmdbuf[1]=a;
@ -82,25 +215,49 @@ Result APT_JumpToHomeMenu(Handle handle, u32 a, u32 b, u32 c)
cmdbuf[4]=(b<<14)|2; cmdbuf[4]=(b<<14)|2;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_NotifyToWait(Handle handle, NS_APPID appID) Result APT_NotifyToWait(Handle* handle, NS_APPID appID)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x430040; //request header code cmdbuf[0]=0x430040; //request header code
cmdbuf[1]=appID; cmdbuf[1]=appID;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_GlanceParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize) Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x4B00C2; //request header code
cmdbuf[1]=a;
cmdbuf[2]=size1;
cmdbuf[3]=size2;
cmdbuf[4]=(size1<<14)|0x402;
cmdbuf[5]=(u32)buf1;
cmdbuf[0+0x100/4]=(size2<<14)|2;
cmdbuf[1+0x100/4]=(u32)buf2;
Result ret=0;
if((ret=svc_sendSyncRequest(*handle)))return ret;
if(out)*out=cmdbuf[2];
return cmdbuf[1];
}
Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize)
{
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0xE0080; //request header code cmdbuf[0]=0xE0080; //request header code
cmdbuf[1]=appID; cmdbuf[1]=appID;
@ -110,15 +267,16 @@ Result APT_GlanceParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* b
cmdbuf[1+0x100/4]=(u32)buffer; cmdbuf[1+0x100/4]=(u32)buffer;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
if(actualSize)*actualSize=cmdbuf[4]; if(actualSize)*actualSize=cmdbuf[4];
return cmdbuf[1]; return cmdbuf[1];
} }
Result APT_ReceiveParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize) Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize)
{ {
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0xD0080; //request header code cmdbuf[0]=0xD0080; //request header code
cmdbuf[1]=appID; cmdbuf[1]=appID;
@ -128,7 +286,7 @@ Result APT_ReceiveParameter(Handle handle, NS_APPID appID, u32 bufferSize, u32*
cmdbuf[1+0x100/4]=(u32)buffer; cmdbuf[1+0x100/4]=(u32)buffer;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
if(actualSize)*actualSize=cmdbuf[4]; if(actualSize)*actualSize=cmdbuf[4];

View File

@ -5,9 +5,18 @@
#include <ctr/GSP.h> #include <ctr/GSP.h>
#include <ctr/svc.h> #include <ctr/svc.h>
Handle gspGpuHandle;
Result GSPGPU_AcquireRight(Handle handle, u8 flags) void gspInit()
{ {
//do stuff with GPU...
srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu");
}
Result GSPGPU_AcquireRight(Handle* handle, u8 flags)
{
if(!handle)handle=&gspGpuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x160042; //request header code cmdbuf[0]=0x160042; //request header code
cmdbuf[1]=flags; cmdbuf[1]=flags;
@ -15,25 +24,42 @@ Result GSPGPU_AcquireRight(Handle handle, u8 flags)
cmdbuf[3]=0xffff8001; cmdbuf[3]=0xffff8001;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result GSPGPU_SetLcdForceBlack(Handle handle, u8 flags) Result GSPGPU_ReleaseRight(Handle* handle)
{ {
if(!handle)handle=&gspGpuHandle;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x170000; //request header code
Result ret=0;
if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1];
}
Result GSPGPU_SetLcdForceBlack(Handle* handle, u8 flags)
{
if(!handle)handle=&gspGpuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0xB0040; //request header code cmdbuf[0]=0xB0040; //request header code
cmdbuf[1]=flags; cmdbuf[1]=flags;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result GSPGPU_FlushDataCache(Handle handle, u8* adr, u32 size) Result GSPGPU_FlushDataCache(Handle* handle, u8* adr, u32 size)
{ {
if(!handle)handle=&gspGpuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x80082; //request header code cmdbuf[0]=0x80082; //request header code
cmdbuf[1]=(u32)adr; cmdbuf[1]=(u32)adr;
@ -42,13 +68,15 @@ Result GSPGPU_FlushDataCache(Handle handle, u8* adr, u32 size)
cmdbuf[4]=0xffff8001; cmdbuf[4]=0xffff8001;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size) Result GSPGPU_WriteHWRegs(Handle* handle, u32 regAddr, u8* data, u8 size)
{ {
if(!handle)handle=&gspGpuHandle;
if(size>0x80 || !data)return -1; if(size>0x80 || !data)return -1;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
@ -59,13 +87,15 @@ Result GSPGPU_WriteHWRegs(Handle handle, u32 regAddr, u8* data, u8 size)
cmdbuf[4]=(u32)data; cmdbuf[4]=(u32)data;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size) Result GSPGPU_ReadHWRegs(Handle* handle, u32 regAddr, u8* data, u8 size)
{ {
if(!handle)handle=&gspGpuHandle;
if(size>0x80 || !data)return -1; if(size>0x80 || !data)return -1;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
@ -76,13 +106,15 @@ Result GSPGPU_ReadHWRegs(Handle handle, u32 regAddr, u8* data, u8 size)
cmdbuf[0x40+1]=(u32)data; cmdbuf[0x40+1]=(u32)data;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID) Result GSPGPU_RegisterInterruptRelayQueue(Handle* handle, Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID)
{ {
if(!handle)handle=&gspGpuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x130042; //request header code cmdbuf[0]=0x130042; //request header code
cmdbuf[1]=flags; cmdbuf[1]=flags;
@ -90,7 +122,7 @@ Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32
cmdbuf[3]=eventHandle; cmdbuf[3]=eventHandle;
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
if(threadID)*threadID=cmdbuf[2]; if(threadID)*threadID=cmdbuf[2];
if(outMemHandle)*outMemHandle=cmdbuf[4]; if(outMemHandle)*outMemHandle=cmdbuf[4];
@ -98,13 +130,15 @@ Result GSPGPU_RegisterInterruptRelayQueue(Handle handle, Handle eventHandle, u32
return cmdbuf[1]; return cmdbuf[1];
} }
Result GSPGPU_TriggerCmdReqQueue(Handle handle) Result GSPGPU_TriggerCmdReqQueue(Handle* handle)
{ {
if(!handle)handle=&gspGpuHandle;
u32* cmdbuf=getThreadCommandBuffer(); u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0xC0000; //request header code cmdbuf[0]=0xC0000; //request header code
Result ret=0; Result ret=0;
if((ret=svc_sendSyncRequest(handle)))return ret; if((ret=svc_sendSyncRequest(*handle)))return ret;
return cmdbuf[1]; return cmdbuf[1];
} }
@ -112,7 +146,7 @@ Result GSPGPU_TriggerCmdReqQueue(Handle handle)
//essentially : get commandIndex and totalCommands, calculate offset of new command, copy command and update totalCommands //essentially : get commandIndex and totalCommands, calculate offset of new command, copy command and update totalCommands
//use LDREX/STREX because this data may also be accessed by the GSP module and we don't want to break stuff //use LDREX/STREX because this data may also be accessed by the GSP module and we don't want to break stuff
//(mostly, we could overwrite the buffer header with wrong data and make the GSP module reexecute old commands) //(mostly, we could overwrite the buffer header with wrong data and make the GSP module reexecute old commands)
Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8], Handle handle) Result GSPGPU_submitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8], Handle* handle)
{ {
if(!sharedGspCmdBuf || !gxCommand)return -1; if(!sharedGspCmdBuf || !gxCommand)return -1;

View File

@ -14,13 +14,12 @@ getThreadCommandBuffer:
.type svc_controlMemory, %function .type svc_controlMemory, %function
svc_controlMemory: svc_controlMemory:
stmfd sp!, {r0, r4} stmfd sp!, {r0, r4}
ldr R0, [sp, #0x8] ldr r0, [sp, #0x8]
ldr r4, [sp, #0x8+0x4] ldr r4, [sp, #0x8+0x4]
svc 0x01 svc 0x01
ldr r2, [sp] ldr r2, [sp], #4
str r1, [r2] str r1, [r2]
ldr r4, [sp, #4]! ldr r4, [sp], #4
add sp, sp, #4
bx lr bx lr
.global svc_exitProcess .global svc_exitProcess
@ -29,6 +28,24 @@ svc_exitProcess:
svc 0x03 svc 0x03
bx lr bx lr
.global svc_createThread
.type svc_createThread, %function
svc_createThread:
stmfd sp!, {r0, r4}
ldr r0, [sp, #0x8]
ldr r4, [sp, #0x8+0x4]
svc 0x08
ldr r2, [sp], #4
str r1, [r2]
ldr r4, [sp], #4
bx lr
.global svc_exitThread
.type svc_exitThread, %function
svc_exitThread:
svc 0x09
bx lr
.global svc_sleepThread .global svc_sleepThread
.type svc_sleepThread, %function .type svc_sleepThread, %function
svc_sleepThread: svc_sleepThread:

View File

@ -10,52 +10,25 @@
#include <ctr/svc.h> #include <ctr/svc.h>
#include "costable.h" #include "costable.h"
Handle APTevents[2];
Handle aptLockHandle;
void aptInit()
{
Handle aptuHandle;
//initialize APT stuff, escape load screen
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_GetLockHandle(aptuHandle, 0x0, &aptLockHandle);
svc_closeHandle(aptuHandle);
svc_waitSynchronization1(aptLockHandle, U64_MAX);
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_Initialize(aptuHandle, APPID_APPLICATION, &APTevents[0], &APTevents[1]);
svc_closeHandle(aptuHandle);
svc_releaseMutex(aptLockHandle);
svc_waitSynchronization1(aptLockHandle, U64_MAX);
srv_getServiceHandle(NULL, &aptuHandle, "APT:U");
APT_Enable(aptuHandle, 0x0);
svc_closeHandle(aptuHandle);
svc_releaseMutex(aptLockHandle);
}
u8* gspHeap; u8* gspHeap;
u32* gxCmdBuf; u32* gxCmdBuf;
Handle gspGpuHandle;
u8 currentBuffer; u8 currentBuffer;
u8* topLeftFramebuffers[2]; u8* topLeftFramebuffers[2];
void gspGpuInit() void gspGpuInit()
{ {
//do stuff with GPU... gspInit();
srv_getServiceHandle(NULL, &gspGpuHandle, "gsp::Gpu");
GSPGPU_AcquireRight(gspGpuHandle, 0x0); GSPGPU_AcquireRight(NULL, 0x0);
GSPGPU_SetLcdForceBlack(gspGpuHandle, 0x0); GSPGPU_SetLcdForceBlack(NULL, 0x0);
//set subscreen to blue //set subscreen to blue
u32 regData=0x01FF0000; u32 regData=0x01FF0000;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)&regData, 4); GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 4);
//grab main left screen framebuffer addresses //grab main left screen framebuffer addresses
GSPGPU_ReadHWRegs(gspGpuHandle, 0x400468, (u8*)&topLeftFramebuffers, 8); GSPGPU_ReadHWRegs(NULL, 0x400468, (u8*)&topLeftFramebuffers, 8);
//convert PA to VA (assuming FB in VRAM) //convert PA to VA (assuming FB in VRAM)
topLeftFramebuffers[0]+=0x7000000; topLeftFramebuffers[0]+=0x7000000;
@ -65,7 +38,7 @@ void gspGpuInit()
u8 threadID; u8 threadID;
Handle gspEvent, gspSharedMemHandle; Handle gspEvent, gspSharedMemHandle;
svc_createEvent(&gspEvent, 0x0); svc_createEvent(&gspEvent, 0x0);
GSPGPU_RegisterInterruptRelayQueue(gspGpuHandle, gspEvent, 0x1, &gspSharedMemHandle, &threadID); GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID);
svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000); svc_mapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000);
//map GSP heap //map GSP heap
@ -83,10 +56,10 @@ void gspGpuInit()
void swapBuffers() void swapBuffers()
{ {
u32 regData; u32 regData;
GSPGPU_ReadHWRegs(gspGpuHandle, 0x400478, (u8*)&regData, 4); GSPGPU_ReadHWRegs(NULL, 0x400478, (u8*)&regData, 4);
regData^=1; regData^=1;
currentBuffer=regData&1; currentBuffer=regData&1;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x400478, (u8*)&regData, 4); GSPGPU_WriteHWRegs(NULL, 0x400478, (u8*)&regData, 4);
} }
void copyBuffer() void copyBuffer()
@ -94,7 +67,7 @@ void copyBuffer()
//copy topleft FB //copy topleft FB
u8 copiedBuffer=currentBuffer^1; u8 copiedBuffer=currentBuffer^1;
u8* bufAdr=&gspHeap[0x46500*copiedBuffer]; u8* bufAdr=&gspHeap[0x46500*copiedBuffer];
GSPGPU_FlushDataCache(gspGpuHandle, bufAdr, 0x46500); GSPGPU_FlushDataCache(NULL, bufAdr, 0x46500);
//GX RequestDma //GX RequestDma
u32 gxCommand[0x8]; u32 gxCommand[0x8];
gxCommand[0]=0x00; //CommandID gxCommand[0]=0x00; //CommandID
@ -103,7 +76,7 @@ void copyBuffer()
gxCommand[3]=0x46500; //size gxCommand[3]=0x46500; //size
gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0;
GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, gspGpuHandle); GSPGPU_submitGxCommand(gxCmdBuf, gxCommand, NULL);
} }
s32 pcCos(u16 v) s32 pcCos(u16 v)
@ -156,6 +129,8 @@ int main()
FSUSER_OpenFileDirectly(fsuHandle, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSUSER_OpenFileDirectly(fsuHandle, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
FSFILE_Read(fileHandle, &bytesRead, 0x0, (u32*)gspHeap, 0x46500); FSFILE_Read(fileHandle, &bytesRead, 0x0, (u32*)gspHeap, 0x46500);
aptSetupEventHandler();
while(1) while(1)
{ {
u32 PAD=((u32*)0x10000000)[7]; u32 PAD=((u32*)0x10000000)[7];
@ -163,7 +138,7 @@ int main()
swapBuffers(); swapBuffers();
copyBuffer(); copyBuffer();
u32 regData=PAD|0x01000000; u32 regData=PAD|0x01000000;
GSPGPU_WriteHWRegs(gspGpuHandle, 0x202A04, (u8*)&regData, 4); GSPGPU_WriteHWRegs(NULL, 0x202A04, (u8*)&regData, 4);
svc_sleepThread(1000000000); svc_sleepThread(1000000000);
} }