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:
parent
17da5e7bf9
commit
8ea4cb87e5
2 changed files with 58 additions and 25 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue