libctru/libctru/source/services/cfgnor.c
2015-11-11 08:57:54 -08:00

120 lines
2.3 KiB
C

#include <stdlib.h>
#include <3ds/types.h>
#include <3ds/result.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/services/cfgnor.h>
#include <3ds/ipc.h>
Handle cfgnorHandle;
Result cfgnorInit(u8 value)
{
Result ret = 0;
if(R_FAILED(ret = srvGetServiceHandle(&cfgnorHandle, "cfg:nor")))return ret;
if(R_FAILED(ret = CFGNOR_Initialize(value))) svcCloseHandle(cfgnorHandle);
return ret;
}
void cfgnorExit(void)
{
if(cfgnorHandle != 0)
{
CFGNOR_Shutdown();
svcCloseHandle(cfgnorHandle);
cfgnorHandle = 0;
}
}
Result cfgnorDumpFlash(u32 *buf, u32 size)
{
Result ret = 0;
u32 pos=0;
u32 chunksize = 0x100;
for(pos=0; pos<size; pos+=chunksize)
{
if(size-pos < chunksize)chunksize = size-pos;
ret = CFGNOR_ReadData(pos, &buf[pos>>2], chunksize);
if(R_FAILED(ret))break;
}
return ret;
}
Result cfgnorWriteFlash(u32 *buf, u32 size)
{
Result ret = 0;
u32 pos=0;
u32 chunksize = 0x100;
for(pos=0; pos<size; pos+=chunksize)
{
if(size-pos < chunksize)chunksize = size-pos;
ret = CFGNOR_WriteData(pos, &buf[pos>>2], chunksize);
if(ret!=0)break;
}
return ret;
}
Result CFGNOR_Initialize(u8 value)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x1,1,0); // 0x10040
cmdbuf[1] = (u32)value;
if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret;
return cmdbuf[1];
}
Result CFGNOR_Shutdown(void)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x2,0,0); // 0x20000
if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret;
return cmdbuf[1];
}
Result CFGNOR_ReadData(u32 offset, u32 *buf, u32 size)
{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x5,2,2); // 0x50082
cmdbuf[1] = offset;
cmdbuf[2] = size;
cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_W);
cmdbuf[4] = (u32)buf;
if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret;
return cmdbuf[1];
}
Result CFGNOR_WriteData(u32 offset, u32 *buf, u32 size)
{
u32 ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x6,2,2); // 0x60082
cmdbuf[1] = offset;
cmdbuf[2] = size;
cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_R);
cmdbuf[4] = (u32)buf;
if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret;
return cmdbuf[1];
}