This repository has been archived on 2022-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
Luma3DS-3GX/sysmodules/pxi/source/receiver.c

71 lines
2.1 KiB
C
Raw Normal View History

2017-11-02 15:11:55 +01:00
/*
receiver.c:
Fetches replies coming from Process9, writing them in the appropriate buffer.
2020-04-25 14:26:21 +02:00
(c) TuxSH, 2016-2020
2017-11-02 15:11:55 +01:00
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
*/
#include <string.h>
2017-11-02 15:11:55 +01:00
#include "receiver.h"
#include "PXI.h"
static inline void receiveFromArm9(void)
{
u32 serviceId = PXIReceiveWord();
//The offcical implementation can return 0xD90043FA
if(((serviceId >= 10)) || (sessionManager.sessionData[serviceId].state != STATE_SENT_TO_ARM9))
svcBreak(USERBREAK_PANIC);
sessionManager.receivedServiceId = serviceId;
RecursiveLock_Lock(&sessionManager.sessionData[serviceId].lock);
u32 replyHeader = PXIReceiveWord();
u32 replySizeWords = (replyHeader & 0x3F) + ((replyHeader & 0xFC0) >> 6) + 1;
if(replySizeWords > 0x40) svcBreak(USERBREAK_PANIC);
u32 *buf = sessionManager.sessionData[serviceId].buffer;
buf[0] = replyHeader;
PXIReceiveBuffer(buf + 1, replySizeWords - 1);
sessionManager.sessionData[serviceId].state = STATE_RECEIVED_FROM_ARM9;
RecursiveLock_Unlock(&sessionManager.sessionData[serviceId].lock);
if(serviceId == 0 && shouldTerminate)
{
assertSuccess(svcSignalEvent(terminationRequestedEvent));
return;
}
if(serviceId != 9)
{
s32 count;
assertSuccess(svcReleaseSemaphore(&count, sessionManager.replySemaphore, 1));
}
else
{
assertSuccess(svcSignalEvent(sessionManager.PXISRV11CommandReceivedEvent));
assertSuccess(svcWaitSynchronization(sessionManager.PXISRV11ReplySentEvent, -1LL));
if( (sessionManager.sessionData[serviceId].state != STATE_SENT_TO_ARM9))
svcBreak(USERBREAK_PANIC);
}
}
void receiver(void)
{
Handle handles[] = {PXISyncInterrupt, terminationRequestedEvent};
assertSuccess(svcWaitSynchronization(sessionManager.PXISRV11ReplySentEvent, -1LL));
while(true)
{
s32 index;
assertSuccess(svcWaitSynchronizationN(&index, handles, 2, false, -1LL));
if(index == 1) return;
while(!PXIIsReceiveFIFOEmpty())
receiveFromArm9();
}
}