Files
mm/src/boot_O2_g3/z_std_dma.c
T
petrie911 2006a65ba6 z_overlay and z_fbdemo_dlftbls (Transition overlay handling), clean up a lot of u32s used to store pointers (#1073)
* overlay matches

* prototypes

* fbdemo too

* virtual to physical

* names, cleanup, etc

* bss reordering

* uintptr stuff

* fixed now?

* one fix

* headers and such

* fixes'n'stuff

* XXX action

* docs of a sort

* useless error codes

* n

* format

* header? I barely know her!

Co-authored-by: petrie911 <petrie911@users.noreply.github.com>
2022-10-04 21:46:32 +01:00

239 lines
5.6 KiB
C

#include "prevent_bss_reordering.h"
#include "global.h"
u32 sDmaMgrDmaBuffSize = 0x2000;
StackEntry sDmaMgrStackInfo;
u16 numDmaEntries;
OSMesgQueue sDmaMgrMsgQueue;
OSMesg sDmaMgrMsgs[32];
OSThread sDmaMgrThread;
u8 sDmaMgrStack[0x500];
s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
OSIoMesg ioMsg;
OSMesgQueue queue;
OSMesg msg[1];
s32 ret;
size_t buffSize = sDmaMgrDmaBuffSize;
osInvalDCache(ram, size);
osCreateMesgQueue(&queue, msg, ARRAY_COUNT(msg));
if (buffSize != 0) {
while (buffSize < size) {
ioMsg.hdr.pri = 0;
ioMsg.hdr.retQueue = &queue;
ioMsg.devAddr = rom;
ioMsg.dramAddr = ram;
ioMsg.size = buffSize;
ret = osEPiStartDma(gCartHandle, &ioMsg, 0);
if (ret) {
goto END;
}
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
size -= buffSize;
rom = rom + buffSize;
ram = (u8*)ram + buffSize;
}
}
ioMsg.hdr.pri = 0;
ioMsg.hdr.retQueue = &queue;
ioMsg.devAddr = rom;
ioMsg.dramAddr = ram;
ioMsg.size = size;
ret = osEPiStartDma(gCartHandle, &ioMsg, 0);
if (ret) {
goto END;
}
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
osInvalDCache(ram, size);
END:
return ret;
}
s32 DmaMgr_DmaHandler(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) {
return osEPiStartDma(pihandle, mb, direction);
}
DmaEntry* DmaMgr_FindDmaEntry(uintptr_t vrom) {
DmaEntry* curr;
for (curr = dmadata; curr->vromEnd != 0; curr++) {
if (vrom < curr->vromStart) {
continue;
}
if (vrom >= curr->vromEnd) {
continue;
}
return curr;
}
return NULL;
}
u32 DmaMgr_TranslateVromToRom(uintptr_t vrom) {
DmaEntry* entry = DmaMgr_FindDmaEntry(vrom);
if (entry != NULL) {
if (entry->romEnd == 0) {
return vrom + entry->romStart - entry->vromStart;
}
if (vrom == entry->vromStart) {
return entry->romStart;
}
return -1;
}
return -1;
}
s32 DmaMgr_FindDmaIndex(uintptr_t vrom) {
DmaEntry* entry = DmaMgr_FindDmaEntry(vrom);
if (entry != NULL) {
return entry - dmadata;
}
return -1;
}
const char* func_800809F4(u32 a0) {
return "??";
}
void DmaMgr_ProcessMsg(DmaRequest* req) {
uintptr_t vrom;
void* ram;
size_t size;
uintptr_t romStart;
size_t romSize;
DmaEntry* dmaEntry;
s32 index;
vrom = req->vromAddr;
ram = req->dramAddr;
size = req->size;
index = DmaMgr_FindDmaIndex(vrom);
if ((index >= 0) && (index < numDmaEntries)) {
dmaEntry = &dmadata[index];
if (dmaEntry->romEnd == 0) {
if (dmaEntry->vromEnd < (vrom + size)) {
Fault_AddHungupAndCrash("../z_std_dma.c", 499);
}
DmaMgr_DmaRomToRam((dmaEntry->romStart + vrom) - dmaEntry->vromStart, (u8*)ram, size);
return;
}
romSize = dmaEntry->romEnd - dmaEntry->romStart;
romStart = dmaEntry->romStart;
if (vrom != dmaEntry->vromStart) {
Fault_AddHungupAndCrash("../z_std_dma.c", 518);
}
if (size != (dmaEntry->vromEnd - dmaEntry->vromStart)) {
Fault_AddHungupAndCrash("../z_std_dma.c", 525);
}
osSetThreadPri(NULL, 10);
Yaz0_Decompress(romStart, ram, romSize);
osSetThreadPri(NULL, 17);
} else {
Fault_AddHungupAndCrash("../z_std_dma.c", 558);
}
}
void DmaMgr_ThreadEntry(void* a0) {
OSMesg msg;
DmaRequest* req;
while (1) {
osRecvMesg(&sDmaMgrMsgQueue, &msg, OS_MESG_BLOCK);
if (msg == NULL) {
break;
}
req = (DmaRequest*)msg;
DmaMgr_ProcessMsg(req);
if (req->notifyQueue) {
osSendMesg(req->notifyQueue, req->notifyMsg, OS_MESG_NOBLOCK);
}
}
}
s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, uintptr_t vromStart, size_t size, UNK_TYPE4 unused,
OSMesgQueue* queue, OSMesg msg) {
if (gIrqMgrResetStatus >= 2) {
return -2;
}
request->vromAddr = vromStart;
request->dramAddr = vramStart;
request->size = size;
request->unk14 = 0;
request->notifyQueue = queue;
request->notifyMsg = msg;
osSendMesg(&sDmaMgrMsgQueue, request, OS_MESG_BLOCK);
return 0;
}
s32 DmaMgr_SendRequest0(void* vramStart, uintptr_t vromStart, size_t size) {
DmaRequest req;
OSMesgQueue queue;
OSMesg msg[1];
s32 ret;
osCreateMesgQueue(&queue, msg, ARRAY_COUNT(msg));
ret = DmaMgr_SendRequestImpl(&req, vramStart, vromStart, size, 0, &queue, NULL);
if (ret == -1) {
return ret;
} else {
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
}
return 0;
}
void DmaMgr_Start(void) {
DmaMgr_DmaRomToRam(SEGMENT_ROM_START(dmadata), dmadata, SEGMENT_ROM_SIZE(dmadata));
{
DmaEntry* iter = dmadata;
u32 idx = 0;
while (iter->vromEnd != 0) {
iter++;
idx++;
}
numDmaEntries = idx;
}
osCreateMesgQueue(&sDmaMgrMsgQueue, sDmaMgrMsgs, ARRAY_COUNT(sDmaMgrMsgs));
StackCheck_Init(&sDmaMgrStackInfo, sDmaMgrStack, sDmaMgrStack + sizeof(sDmaMgrStack), 0, 0x100, "dmamgr");
osCreateThread(&sDmaMgrThread, Z_THREAD_ID_DMAMGR, DmaMgr_ThreadEntry, NULL, sDmaMgrStack + sizeof(sDmaMgrStack),
Z_PRIORITY_DMAMGR);
osStartThread(&sDmaMgrThread);
}
void DmaMgr_Stop(void) {
osSendMesg(&sDmaMgrMsgQueue, NULL, OS_MESG_BLOCK);
}