mirror of
https://github.com/zeldaret/mm.git
synced 2026-05-24 07:10:44 -04:00
2006a65ba6
* 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>
239 lines
5.6 KiB
C
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);
|
|
}
|