1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-10 19:20:13 +00:00

Match retail z_std_dma.c (#1665)

* Match z_std_dma.c

* Fix DmaMgr_Error doc comment

* Unindent
This commit is contained in:
cadmic 2024-01-30 16:53:16 -08:00 committed by GitHub
parent 17da5e7bf9
commit 8ea4cb87e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 25 deletions

View file

@ -46,9 +46,11 @@ extern size_t gDmaMgrDmaBuffSize;
s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue, s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue,
OSMesg msg); OSMesg msg);
s32 DmaMgr_RequestSync(void* ram, uintptr_t vrom, size_t size); s32 DmaMgr_RequestSync(void* ram, uintptr_t vrom, size_t size);
#if OOT_DEBUG
s32 DmaMgr_RequestAsyncDebug(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue, s32 DmaMgr_RequestAsyncDebug(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue,
OSMesg msg, const char* file, s32 line); OSMesg msg, const char* file, s32 line);
s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char* file, s32 line); s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char* file, s32 line);
#endif
// Special-purpose DMA Requests // Special-purpose DMA Requests

View file

@ -36,12 +36,15 @@ u32 sDmaMgrIsRomCompressed = false;
// dmadata filenames // dmadata filenames
#define DEFINE_DMA_ENTRY(_0, nameString) nameString, #define DEFINE_DMA_ENTRY(_0, nameString) nameString,
#if OOT_DEBUG
const char* sDmaMgrFileNames[] = { const char* sDmaMgrFileNames[] = {
#include "tables/dmadata_table.h" #include "tables/dmadata_table.h"
}; };
#endif
#undef DEFINE_DMA_ENTRY #undef DEFINE_DMA_ENTRY
#if OOT_DEBUG
/** /**
* Compares `str1` and `str2`. * Compares `str1` and `str2`.
* *
@ -67,6 +70,7 @@ s32 DmaMgr_StrCmp(const char* str1, const char* str2) {
} }
return 0; return 0;
} }
#endif
/** /**
* Transfer `size` bytes from physical ROM address `rom` to `ram`. * Transfer `size` bytes from physical ROM address `rom` to `ram`.
@ -86,7 +90,6 @@ s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
OSMesg msg; OSMesg msg;
s32 ret; s32 ret;
size_t buffSize = gDmaMgrDmaBuffSize; size_t buffSize = gDmaMgrDmaBuffSize;
s32 pad[2];
if (buffSize == 0) { if (buffSize == 0) {
buffSize = DMAMGR_DEFAULT_BUFSIZE; buffSize = DMAMGR_DEFAULT_BUFSIZE;
@ -132,7 +135,9 @@ s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
ram = (u8*)ram + buffSize; ram = (u8*)ram + buffSize;
} }
if (1) {} // Also necessary to match if (1) { // Also necessary to match
s32 pad[2];
}
ioMsg.hdr.pri = OS_MESG_PRI_NORMAL; ioMsg.hdr.pri = OS_MESG_PRI_NORMAL;
ioMsg.hdr.retQueue = &queue; ioMsg.hdr.retQueue = &queue;
@ -219,17 +224,18 @@ void DmaMgr_DmaFromDriveRom(void* ram, uintptr_t rom, size_t size) {
osRecvMesg(&queue, NULL, OS_MESG_BLOCK); osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
} }
#if OOT_DEBUG
/** /**
* DMA error encountered, print error messages and bring up the crash screen. * DMA error encountered, print error messages and bring up the crash screen.
* *
* @param req DMA Request causing the error. * @param req DMA Request causing the error.
* @param file DMA data filename associated with the operation that errored. * @param filename DMA data filename associated with the operation that errored.
* @param errorName Error name string. * @param errorName Error name string.
* @param errorDesc Error description string. * @param errorDesc Error description string.
* *
* This function does not return. * This function does not return.
*/ */
NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorName, const char* errorDesc) { NORETURN void DmaMgr_Error(DmaRequest* req, const char* filename, const char* errorName, const char* errorDesc) {
uintptr_t vrom = req->vromAddr; uintptr_t vrom = req->vromAddr;
void* ram = req->dramAddr; void* ram = req->dramAddr;
size_t size = req->size; size_t size = req->size;
@ -241,7 +247,7 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
// "DMA Fatal Error" // "DMA Fatal Error"
PRINTF("DMA致命的エラー(%s)\nROM:%X RAM:%X SIZE:%X %s\n", PRINTF("DMA致命的エラー(%s)\nROM:%X RAM:%X SIZE:%X %s\n",
errorDesc != NULL ? errorDesc : (errorName != NULL ? errorName : "???"), vrom, ram, size, errorDesc != NULL ? errorDesc : (errorName != NULL ? errorName : "???"), vrom, ram, size,
file != NULL ? file : "???"); filename != NULL ? filename : "???");
if (req->filename != NULL) { // Source file name that issued the DMA request if (req->filename != NULL) { // Source file name that issued the DMA request
PRINTF("DMA ERROR: %s %d", req->filename, req->line); PRINTF("DMA ERROR: %s %d", req->filename, req->line);
@ -259,10 +265,15 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
sprintf(buff1, "DMA ERROR: %s", errorName != NULL ? errorName : "???"); sprintf(buff1, "DMA ERROR: %s", errorName != NULL ? errorName : "???");
} }
sprintf(buff2, "%07X %08X %X %s", vrom, ram, size, file != NULL ? file : "???"); sprintf(buff2, "%07X %08X %X %s", vrom, ram, size, filename != NULL ? filename : "???");
Fault_AddHungupAndCrashImpl(buff1, buff2); Fault_AddHungupAndCrashImpl(buff1, buff2);
} }
#define DMA_ERROR(req, filename, errorName, errorDesc, file, line) DmaMgr_Error(req, filename, errorName, errorDesc)
#else
#define DMA_ERROR(req, filename, errorName, errorDesc, file, line) Fault_AddHungupAndCrash(file, line)
#endif
/** /**
* Searches the filesystem for the entry containing the address `vrom`. Retrieves the name of this entry from * Searches the filesystem for the entry containing the address `vrom`. Retrieves the name of this entry from
* the array of file names. * the array of file names.
@ -271,6 +282,7 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
* @return Pointer to associated filename * @return Pointer to associated filename
*/ */
const char* DmaMgr_FindFileName(uintptr_t vrom) { const char* DmaMgr_FindFileName(uintptr_t vrom) {
#if OOT_DEBUG
DmaEntry* iter = gDmaDataTable; DmaEntry* iter = gDmaDataTable;
const char** name = sDmaMgrFileNames; const char** name = sDmaMgrFileNames;
@ -287,9 +299,13 @@ const char* DmaMgr_FindFileName(uintptr_t vrom) {
#ifdef AVOID_UB #ifdef AVOID_UB
return ""; return "";
#endif #endif
#else
return NULL;
#endif
} }
const char* DmaMgr_GetFileName(uintptr_t vrom) { const char* DmaMgr_GetFileName(uintptr_t vrom) {
#if OOT_DEBUG
const char* ret = DmaMgr_FindFileName(vrom); const char* ret = DmaMgr_FindFileName(vrom);
if (ret == NULL) { if (ret == NULL) {
@ -302,6 +318,9 @@ const char* DmaMgr_GetFileName(uintptr_t vrom) {
return NULL; return NULL;
} }
return ret; return ret;
#else
return "";
#endif
} }
void DmaMgr_ProcessRequest(DmaRequest* req) { void DmaMgr_ProcessRequest(DmaRequest* req) {
@ -314,15 +333,13 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
DmaEntry* iter; DmaEntry* iter;
const char* filename; const char* filename;
if (0) { #if OOT_DEBUG
// The string is defined in .rodata but not used, suggesting a debug print is here but was optimized out in
// some way. The last arg of this print looks like it may be filename, but filename above this block does not
// match.
PRINTF("DMA ROM:%08X RAM:%08X SIZE:%08X %s\n");
}
// Get the filename (for debugging) // Get the filename (for debugging)
filename = DmaMgr_GetFileName(vrom); filename = DmaMgr_GetFileName(vrom);
#else
// An unused empty string is defined in .rodata of retail builds, suggesting it was used near here.
filename = "";
#endif
// Iterate through the DMA data table until the region containing the vrom address for this request is found // Iterate through the DMA data table until the region containing the vrom address for this request is found
iter = gDmaDataTable; iter = gDmaDataTable;
@ -330,7 +347,11 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
if (vrom >= iter->vromStart && vrom < iter->vromEnd) { if (vrom >= iter->vromStart && vrom < iter->vromEnd) {
// Found the region this request falls into // Found the region this request falls into
if (1) {} // Necessary to match if (0) {
// The string is defined in .rodata of debug builds but not used, suggesting a debug print is here
// but was optimized out in some way.
PRINTF("DMA ROM:%08X RAM:%08X SIZE:%08X %s\n", vrom, ram, size, filename);
}
if (iter->romEnd == 0) { if (iter->romEnd == 0) {
// romEnd of 0 indicates that the file is uncompressed. Files that are stored uncompressed can have // romEnd of 0 indicates that the file is uncompressed. Files that are stored uncompressed can have
@ -340,8 +361,8 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
// Error, vrom + size ends up in a different file than it started in // Error, vrom + size ends up in a different file than it started in
// "DMA transfers cannot cross segment boundaries" // "DMA transfers cannot cross segment boundaries"
DmaMgr_Error(req, filename, "Segment Alignment Error", DMA_ERROR(req, filename, "Segment Alignment Error",
"セグメント境界をまたがってDMA転送することはできません"); "セグメント境界をまたがってDMA転送することはできません", "../z_std_dma.c", 726);
} }
DmaMgr_DmaRomToRam(iter->romStart + (vrom - iter->vromStart), ram, size); DmaMgr_DmaRomToRam(iter->romStart + (vrom - iter->vromStart), ram, size);
@ -360,16 +381,16 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
// Error, requested vrom is not the start of a file // Error, requested vrom is not the start of a file
// "DMA transfer cannot be performed from the middle of a compressed segment" // "DMA transfer cannot be performed from the middle of a compressed segment"
DmaMgr_Error(req, filename, "Can't Transfer Segment", DMA_ERROR(req, filename, "Can't Transfer Segment",
"圧縮されたセグメントの途中からはDMA転送することはできません"); "圧縮されたセグメントの途中からはDMA転送することはできません", "../z_std_dma.c", 746);
} }
if (size != iter->vromEnd - iter->vromStart) { if (size != iter->vromEnd - iter->vromStart) {
// Error, only part of the file was requested // Error, only part of the file was requested
// "It is not possible to DMA only part of a compressed segment" // "It is not possible to DMA only part of a compressed segment"
DmaMgr_Error(req, filename, "Can't Transfer Segment", DMA_ERROR(req, filename, "Can't Transfer Segment",
"圧縮されたセグメントの一部だけをDMA転送することはできません"); "圧縮されたセグメントの一部だけをDMA転送することはできません", "../z_std_dma.c", 752);
} }
// Reduce the thread priority and decompress the file, the decompression routine handles the DMA // Reduce the thread priority and decompress the file, the decompression routine handles the DMA
@ -395,7 +416,7 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
// Error, rom is compressed so DMA may only be requested within the filesystem bounds // Error, rom is compressed so DMA may only be requested within the filesystem bounds
// "Corresponding data does not exist" // "Corresponding data does not exist"
DmaMgr_Error(req, NULL, "DATA DON'T EXIST", "該当するデータが存在しません"); DMA_ERROR(req, NULL, "DATA DON'T EXIST", "該当するデータが存在しません", "../z_std_dma.c", 771);
return; return;
} else { } else {
// ROM is uncompressed, allow arbitrary DMA even if the region is not marked in the filesystem // ROM is uncompressed, allow arbitrary DMA even if the region is not marked in the filesystem
@ -460,11 +481,15 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
OSMesg msg) { OSMesg msg) {
static s32 sDmaMgrQueueFullLogged = 0; static s32 sDmaMgrQueueFullLogged = 0;
if ((1 && (ram == NULL)) || (osMemSize < OS_K0_TO_PHYSICAL(ram) + size) || (vrom & 1) || (vrom > 0x4000000) || #if OOT_DEBUG
if ((ram == NULL) || (osMemSize < OS_K0_TO_PHYSICAL(ram) + size) || (vrom & 1) || (vrom > 0x4000000) ||
(size == 0) || (size & 1)) { (size == 0) || (size & 1)) {
//! @bug `req` is passed to `DmaMgr_Error` without rom, ram and size being set // The line numbers for `DMA_ERROR` are only used in retail builds, but this usage was removed so
DmaMgr_Error(req, NULL, "ILLIGAL DMA-FUNCTION CALL", "パラメータ異常です"); // its line number is unknown.
//! @bug `req` is passed to `DMA_ERROR` without rom, ram and size being set
DMA_ERROR(req, NULL, "ILLIGAL DMA-FUNCTION CALL", "パラメータ異常です", "../z_std_dma.c", 0);
} }
#endif
req->vromAddr = vrom; req->vromAddr = vrom;
req->dramAddr = ram; req->dramAddr = ram;
@ -473,6 +498,7 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
req->notifyQueue = queue; req->notifyQueue = queue;
req->notifyMsg = msg; req->notifyMsg = msg;
#if OOT_DEBUG
if (1 && (sDmaMgrQueueFullLogged == 0) && MQ_IS_FULL(&sDmaMgrMsgQueue)) { if (1 && (sDmaMgrQueueFullLogged == 0) && MQ_IS_FULL(&sDmaMgrMsgQueue)) {
sDmaMgrQueueFullLogged++; sDmaMgrQueueFullLogged++;
PRINTF("%c", BEL); PRINTF("%c", BEL);
@ -483,6 +509,7 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
952); 952);
PRINTF(VT_RST); PRINTF(VT_RST);
} }
#endif
osSendMesg(&sDmaMgrMsgQueue, (OSMesg)req, OS_MESG_BLOCK); osSendMesg(&sDmaMgrMsgQueue, (OSMesg)req, OS_MESG_BLOCK);
return 0; return 0;
@ -523,12 +550,13 @@ void DmaMgr_Init(void) {
(u32)(_dmadataSegmentRomEnd - _dmadataSegmentRomStart)); (u32)(_dmadataSegmentRomEnd - _dmadataSegmentRomStart));
PRINTF("dma_rom_ad[]\n"); PRINTF("dma_rom_ad[]\n");
sDmaMgrIsRomCompressed = false; #if OOT_DEBUG
name = sDmaMgrFileNames; name = sDmaMgrFileNames;
iter = gDmaDataTable; iter = gDmaDataTable;
idx = 0; idx = 0;
// Check if the ROM is compressed (romEnd not 0) // Check if the ROM is compressed (romEnd not 0)
sDmaMgrIsRomCompressed = false;
while (iter->vromEnd != 0) { while (iter->vromEnd != 0) {
if (iter->romEnd != 0) { if (iter->romEnd != 0) {
sDmaMgrIsRomCompressed = true; sDmaMgrIsRomCompressed = true;
@ -545,6 +573,7 @@ void DmaMgr_Init(void) {
name++; name++;
} }
} }
#endif
// Ensure that the boot segment always follows after the makerom segment. // Ensure that the boot segment always follows after the makerom segment.
if ((uintptr_t)_bootSegmentRomStart != gDmaDataTable[0].vromEnd) { if ((uintptr_t)_bootSegmentRomStart != gDmaDataTable[0].vromEnd) {
@ -562,6 +591,7 @@ void DmaMgr_Init(void) {
osStartThread(&sDmaMgrThread); osStartThread(&sDmaMgrThread);
} }
#if OOT_DEBUG
/** /**
* Asynchronous DMA Request with source file and line info for debugging. * Asynchronous DMA Request with source file and line info for debugging.
* *
@ -597,3 +627,4 @@ s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char*
osRecvMesg(&queue, NULL, OS_MESG_BLOCK); osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
return 0; return 0;
} }
#endif