TRK: matched serpoll and support; and making more progress (#565)

This commit is contained in:
mrshigure 2025-02-10 19:49:23 -08:00 committed by GitHub
parent 66a9a044fa
commit 23b7af3bc5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 1053 additions and 859 deletions

View file

@ -743,11 +743,11 @@ config.libs = [
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/nubinit.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msg.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msgbuf.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/serpoll.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/serpoll.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/usr_put.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/dispatch.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/msghndlr.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/support.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/support.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/mutex_TRK.c"),
Object(NonMatching, "TRK_MINNOW_DOLPHIN/notify.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "TRK_MINNOW_DOLPHIN/flush_cache.c"),

View file

@ -15,12 +15,12 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2,
int p3);
DSError HandleOpenFileSupportRequest(const char* path, u8 replyError,
u32* param_3, DSIOResult* ioResult);
u32* param_3, u8* ioResult);
DSError HandleCloseFileSupportRequest(int replyError, DSIOResult* ioResult);
DSError HandleCloseFileSupportRequest(int replyError, u8* ioResult);
DSError HandlePositionFileSupportRequest(DSReplyError replyErr, u32* param_2,
u8 param_3, DSIOResult* ioResult);
DSError HandlePositionFileSupportRequest(u32 replyErr, u32* param_2,
u8 param_3, u8* ioResult);
#ifdef __cplusplus
}

View file

@ -7,7 +7,7 @@
extern "C" {
#endif
u32 TRKTargetCPUMinorType(void);
u8 TRKTargetCPUMinorType(void);
#ifdef __cplusplus
}

View file

@ -245,4 +245,4 @@ lbl_8037149C:
#endif // clang-format on
}
u32 TRKTargetCPUMinorType(void) { return 0x54; }
u8 TRKTargetCPUMinorType(void) { return 0x54; }

View file

@ -9,41 +9,100 @@ static TRKFramingState gTRKFramingState;
void* gTRKInputPendingPtr;
MessageBufferID TRKTestForPacket()
{
int bytes;
int batch;
int err;
TRKBuffer* b;
int id;
static inline BOOL serpoll_inline_00(TRKBuffer* buffer) {
if (buffer->length < 2) {
TRKStandardACK(buffer, DSMSG_ReplyNAK, DSREPLY_PacketSizeError);
if (gTRKFramingState.msgBufID != -1) {
TRKReleaseBuffer(gTRKFramingState.msgBufID);
gTRKFramingState.msgBufID = -1;
}
gTRKFramingState.buffer = NULL;
gTRKFramingState.receiveState = DSRECV_Wait;
return FALSE;
}
buffer->position = 0;
buffer->length--;
return TRUE;
}
bytes = TRKPollUART();
if (bytes > 0) {
TRKGetFreeBuffer(&id, &b);
if (bytes > TRKMSGBUF_SIZE) {
for (; bytes > 0; bytes -= batch) {
batch = bytes > TRKMSGBUF_SIZE ? TRKMSGBUF_SIZE : bytes;
TRKReadUARTN(b->data, batch);
MessageBufferID TRKTestForPacket(void) {
s32 var_r29;
s32 var_r3;
s8 sp8;
s32 temp_r3;
var_r29 = 0;
var_r3 = TRKReadUARTPoll(&sp8);
while (var_r3 == 0 && var_r29 == 0) {
if (gTRKFramingState.receiveState != DSRECV_InFrame) {
gTRKFramingState.isEscape = FALSE;
}
TRKStandardACK(b, 0xff, 6);
switch (gTRKFramingState.receiveState) {
case DSRECV_Wait:
if (sp8 == 0x7E) {
var_r29 = TRKGetFreeBuffer(&gTRKFramingState.msgBufID, &gTRKFramingState.buffer);
gTRKFramingState.fcsType = 0;
gTRKFramingState.receiveState = DSRECV_Found;
}
break;
case DSRECV_Found:
if (sp8 == 0x7E) {
break;
}
gTRKFramingState.receiveState = DSRECV_InFrame;
/* fallthrough */
case DSRECV_InFrame:
if (sp8 == 0x7E) {
if (gTRKFramingState.isEscape) {
TRKStandardACK(gTRKFramingState.buffer, DSMSG_ReplyNAK, DSREPLY_EscapeError);
if (gTRKFramingState.msgBufID != -1) {
TRKReleaseBuffer(gTRKFramingState.msgBufID);
gTRKFramingState.msgBufID = -1;
}
gTRKFramingState.buffer = NULL;
gTRKFramingState.receiveState = DSRECV_Wait;
break;
}
if (serpoll_inline_00(gTRKFramingState.buffer)) {
temp_r3 = gTRKFramingState.msgBufID;
gTRKFramingState.msgBufID = -1;
gTRKFramingState.buffer = NULL;
gTRKFramingState.receiveState = DSRECV_Wait;
return temp_r3;
}
gTRKFramingState.receiveState = DSRECV_Wait;
} else {
err = TRKReadUARTN(b->data, bytes);
if (err == 0) {
b->length = bytes;
return id;
if (gTRKFramingState.isEscape) {
sp8 ^= 0x20;
gTRKFramingState.isEscape = FALSE;
} else if (sp8 == 0x7D) {
gTRKFramingState.isEscape = TRUE;
break;
}
var_r29 = TRKAppendBuffer1_ui8(gTRKFramingState.buffer, sp8);
gTRKFramingState.fcsType += sp8;
}
break;
case DSRECV_FrameOverflow:
if (sp8 == 0x7E) {
if (gTRKFramingState.msgBufID != -1) {
TRKReleaseBuffer(gTRKFramingState.msgBufID);
gTRKFramingState.msgBufID = -1;
}
if (id != -1) {
TRKReleaseBuffer(id);
gTRKFramingState.buffer = NULL;
gTRKFramingState.receiveState = DSRECV_Wait;
}
break;
}
var_r3 = TRKReadUARTPoll(&sp8);
}
return -1;
}
void TRKGetInput(void)
{
MessageBufferID id;
TRKBuffer* msgBuffer;
MessageBufferID id;
u8 command;
id = TRKTestForPacket();

View file

@ -28,7 +28,7 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count,
*io_result = DS_IONoError;
done = 0;
error = DS_NoError;
while (!exit && done < *count && error == DS_NoError && *io_result == 0) {
while (!exit && done < *count && error == DS_NoError && *io_result == DS_IONoError) {
if (*count - done > 0x800) {
length = 0x800;
} else {
@ -175,3 +175,114 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3)
return error;
}
DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, u32* param_3, u8* ioResult) {
int sp10;
int spC;
TRKBuffer* sp8;
TRKBuffer* var_r31;
DSError var_r26;
*param_3 = 0;
var_r26 = TRKGetFreeBuffer(&spC, &sp8);
if (var_r26 == DS_NoError) {
var_r26 = TRKAppendBuffer1_ui8(sp8, 0xD2);
}
if (var_r26 == DS_NoError) {
var_r26 = TRKAppendBuffer1_ui8(sp8, replyError);
}
if (var_r26 == DS_NoError) {
var_r26 = TRKAppendBuffer1_ui16(sp8, strlen(path) + 1);
}
if (var_r26 == DS_NoError) {
var_r26 = TRKAppendBuffer_ui8(sp8, (u8*) path, strlen(path) + 1);
}
if (var_r26 == DS_NoError) {
*ioResult = 0;
var_r26 = TRKRequestSend(sp8, &sp10, 7, 3, 0);
if (var_r26 == DS_NoError) {
var_r31 = TRKGetBuffer(sp10);
TRKSetBufferPosition(var_r31, 2);
}
if (var_r26 == DS_NoError) {
var_r26 = TRKReadBuffer1_ui8(var_r31, ioResult);
}
if (var_r26 == DS_NoError) {
var_r26 = TRKReadBuffer1_ui32(var_r31, param_3);
}
TRKReleaseBuffer(sp10);
}
TRKReleaseBuffer(spC);
return var_r26;
}
DSError HandleCloseFileSupportRequest(int replyError, u8* ioResult) {
int sp10;
int spC;
DSError var_r31;
TRKBuffer* sp8;
TRKBuffer* var_r30;
var_r31 = TRKGetFreeBuffer(&spC, &sp8);
if (var_r31 == DS_NoError) {
var_r31 = TRKAppendBuffer1_ui8(sp8, 0xD3);
}
if (var_r31 == DS_NoError) {
var_r31 = TRKAppendBuffer1_ui32(sp8, replyError);
}
if (var_r31 == DS_NoError) {
*ioResult = DS_IONoError;
var_r31 = TRKRequestSend(sp8, &sp10, 3, 3, 0);
if (var_r31 == DS_NoError) {
var_r30 = TRKGetBuffer(sp10);
TRKSetBufferPosition(var_r30, 2);
}
if (var_r31 == DS_NoError) {
var_r31 = TRKReadBuffer1_ui8(var_r30, ioResult);
}
TRKReleaseBuffer(sp10);
}
TRKReleaseBuffer(spC);
return var_r31;
}
DSError HandlePositionFileSupportRequest(u32 replyErr, u32* param_2, u8 param_3, u8* ioResult) {
int sp10;
int spC;
TRKBuffer* sp8;
TRKBuffer* var_r31;
DSError var_r27;
var_r27 = TRKGetFreeBuffer(&spC, &sp8);
if (var_r27 == DS_NoError) {
var_r27 = TRKAppendBuffer1_ui8(sp8, 0xD4);
}
if (var_r27 == DS_NoError) {
var_r27 = TRKAppendBuffer1_ui32(sp8, replyErr);
}
if (var_r27 == DS_NoError) {
var_r27 = TRKAppendBuffer1_ui32(sp8, *param_2);
}
if (var_r27 == DS_NoError) {
var_r27 = TRKAppendBuffer1_ui8(sp8, param_3);
}
if (var_r27 == DS_NoError) {
*ioResult = DS_IONoError;
var_r27 = TRKRequestSend(sp8, &sp10, 3, 3, 0);
if (var_r27 == DS_NoError) {
var_r31 = TRKGetBuffer(sp10);
TRKSetBufferPosition(var_r31, 2);
}
if (var_r27 == DS_NoError) {
var_r27 = TRKReadBuffer1_ui8(var_r31, ioResult);
}
if (var_r27 == DS_NoError) {
var_r27 = TRKReadBuffer1_ui32(var_r31, param_2);
} else {
*param_2 = -1;
}
TRKReleaseBuffer(sp10);
}
TRKReleaseBuffer(spC);
return var_r27;
}

View file

@ -114,6 +114,7 @@ asm void __TRK_set_MSR(register u32 msr) {
#endif // clang-format on
}
#pragma dont_inline on
DSError TRKValidMemory32(const void* addr, size_t length,
ValidMemoryOptions readWriteable)
{
@ -199,6 +200,7 @@ DSError TRKValidMemory32(const void* addr, size_t length,
return err;
}
#pragma dont_inline reset
static asm void TRK_ppc_memcpy(register void* dest, register const void* src,
register int n, register u32 param_4,
@ -240,6 +242,7 @@ out_loop:
#endif // clang-format on
}
#pragma dont_inline on
DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length,
MemoryAccessOptions accessOptions, BOOL read)
{
@ -279,6 +282,7 @@ DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length,
gTRKExceptionStatus = tempExceptionStatus;
return error;
}
#pragma dont_inline reset
DSError TRKTargetReadInstruction(void* data, u32 start)
{
@ -310,12 +314,12 @@ DSError TRKTargetAccessDefault(u32 firstRegister, u32 lastRegister,
tempExceptionStatus = gTRKExceptionStatus;
gTRKExceptionStatus.exceptionDetected = FALSE;
data = gTRKCPUState.Default.GPR + firstRegister;
count = (lastRegister - firstRegister) + 1;
gTRKExceptionStatus.exceptionDetected = FALSE;
*registersLengthPtr = count * sizeof(u32);
if (read) {
@ -480,7 +484,7 @@ DSError TRKTargetAccessExtended2(u32 firstRegister, u32 lastRegister,
DSError TRKTargetVersions(DSVersions* versions)
{
versions->kernelMajor = 0;
versions->kernelMinor = 8;
versions->kernelMinor = 10;
versions->protocolMajor = 1;
versions->protocolMinor = 10;
return DS_NoError;
@ -832,16 +836,26 @@ DSError TRKTargetAddStopInfo(TRKBuffer* buffer)
{
DSError error;
u32 instruction;
s32 i;
error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC);
if (error == 0) {
if (error == DS_NoError) {
error = TRKTargetReadInstruction(&instruction, gTRKCPUState.Default.PC);
}
if (error == 0)
if (error == DS_NoError)
error = TRKAppendBuffer1_ui32(buffer, instruction);
if (error == 0)
error
= TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID);
if (error == DS_NoError) {
for (i = 0; i < 32; i++) {
error = TRKAppendBuffer1_ui32(buffer, (u16) gTRKCPUState.Default.GPR[i]);
}
for (i = 0; i < 32; i++) {
error = TRKAppendBuffer1_ui64(buffer, (u16) gTRKCPUState.Float.FPR[i]);
}
}
return error;
}
@ -938,8 +952,8 @@ DSError TRKTargetSingleStep(u32 count, BOOL stepOver)
if (stepOver) {
error = DS_UnsupportedError;
} else {
gTRKStepStatus.count = count;
gTRKStepStatus.type = DSSTEP_IntoCount;
gTRKStepStatus.count = count;
error = TRKTargetDoStep();
}
@ -966,36 +980,51 @@ DSError TRKTargetStepOutOfRange(u32 rangeStart, u32 rangeEnd, BOOL stepOver)
u32 TRKTargetGetPC() { return gTRKCPUState.Default.PC; }
DSError TRKTargetSupportRequest()
{
DSError TRKTargetSupportRequest(void) {
DSError error;
u32 spC;
size_t* length;
DSIOResult ioResult;
MessageCommandID commandId;
TRKEvent event;
u8 ioResult;
commandId = gTRKCPUState.Default.GPR[3];
if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile) {
TRKConstructEvent(&event, 4);
commandId = (u8) gTRKCPUState.Default.GPR[3];
if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile && commandId != DSMSG_OpenFile && commandId != DSMSG_CloseFile && commandId != DSMSG_PositionFile) {
TRKConstructEvent(&event, NUBEVENT_Exception);
TRKPostEvent(&event);
return DS_NoError;
} else {
length = (size_t*)gTRKCPUState.Default.GPR[5];
error = TRKSuppAccessFile((u8)gTRKCPUState.Default.GPR[4],
(u8*)gTRKCPUState.Default.GPR[6], length,
&ioResult, TRUE, commandId == DSMSG_ReadFile);
}
if (commandId == DSMSG_OpenFile) {
error = HandleOpenFileSupportRequest((char*) gTRKCPUState.Default.GPR[4], gTRKCPUState.Default.GPR[5], (u32*) gTRKCPUState.Default.GPR[6], &ioResult);
if (ioResult == DS_IONoError && error != DS_NoError) {
ioResult = DS_IOError;
}
gTRKCPUState.Default.GPR[3] = ioResult;
} else if (commandId == DSMSG_CloseFile) {
error = HandleCloseFileSupportRequest(gTRKCPUState.Default.GPR[4], &ioResult);
if (ioResult == DS_IONoError && error != DS_NoError) {
ioResult = DS_IOError;
}
gTRKCPUState.Default.GPR[3] = ioResult;
} else if (commandId == DSMSG_PositionFile) {
spC = *((u32*) gTRKCPUState.Default.GPR[5]);
error = HandlePositionFileSupportRequest(gTRKCPUState.Default.GPR[4], &spC, gTRKCPUState.Default.GPR[6], &ioResult);
if (ioResult == DS_IONoError && error != DS_NoError) {
ioResult = DS_IOError;
}
gTRKCPUState.Default.GPR[3] = ioResult;
*((u32*) gTRKCPUState.Default.GPR[5]) = spC;
} else {
length = (size_t*) gTRKCPUState.Default.GPR[5];
error = TRKSuppAccessFile((u8) gTRKCPUState.Default.GPR[4], (u8*) gTRKCPUState.Default.GPR[6], length, (DSIOResult*) &ioResult, TRUE, commandId == DSMSG_ReadFile);
if (ioResult == DS_IONoError && error != DS_NoError) {
ioResult = DS_IOError;
}
gTRKCPUState.Default.GPR[3] = ioResult;
if (commandId == DSMSG_ReadFile) {
TRK_flush_cache((void*) gTRKCPUState.Default.GPR[6], *length);
}
}
gTRKCPUState.Default.PC += 4;
return error;
}
@ -1027,8 +1056,10 @@ DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read)
{
/* Initialize instruction array with nop */
u32 access_func[5]
= { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP };
u32 access_func[10] = {
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP,
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP
};
/*
** Construct a small assembly function to perform the
** requested access and call it. The read/write function
@ -1060,8 +1091,10 @@ DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read)
DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read)
{
// all nop by default
u32 instructionData[]
= { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP };
u32 instructionData[] = {
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP,
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP
};
if (read) {
instructionData[0]
@ -1074,12 +1107,15 @@ DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read)
return TRKPPCAccessSpecialReg(srcDestPtr, instructionData, read);
}
#pragma dont_inline on
DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read)
{
DSError error = DS_NoError;
// all nop by default
u32 instructionData1[]
= { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP };
u32 instructionData1[] = {
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP,
INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP
};
if (fpr < 0x20) {
if (read) {
@ -1090,25 +1126,12 @@ DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read)
error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read);
} else if (fpr == 0x20) {
if (read) {
instructionData1[0] = INSTR_STFD(1, 0, 4); // stfd f1, 0(r4)
instructionData1[1] = 0xfc20048e; // mtfsf 0xff, f1
instructionData1[2] = INSTR_STFD(1, 0, 3); // stfd f1, 0(r3)
instructionData1[3] = INSTR_LFD(1, 0, 4); // lfd f1, 0(r4)
} else {
instructionData1[0] = INSTR_STFD(1, 0, 4); // stfd f1, 0(r4)
instructionData1[1] = INSTR_LFD(1, 0, 3); // lfd f1, 0(r4)
instructionData1[2] = 0xfdfe0d8e; // mtfsf 0xff, f1
instructionData1[3] = INSTR_LFD(1, 0, 4); // lfd f1, 0(r4)
}
error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read);
*(u64*)srcDestPtr &= 0xFFFFFFFF;
} else if (fpr == 0x21) {
if (!read) {
*(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1);
}
error = TRKPPCAccessSPR(srcDestPtr, SPR_FPECR, read);
error = TRKPPCAccessSPR(srcDestPtr, 1022, read);
if (read) {
DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL;
}
@ -1116,6 +1139,7 @@ DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read)
return error;
}
#pragma dont_inline reset
#define DEBUG_VECTORREG_ACCESS 0