PROGERR TransferPacket(uint32_t spi_id, AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf) { static uint32_t pktId = 0; pktId++; txBuf->packetId = pktId; txBuf->crc = GenerateCRC(txBuf); int ct = 0; for(; ct < MAX_CONNECT_TRIES; ct++) { PIOS_SPI_RC_PinSet(spi_id, 0); uint32_t res = PIOS_SPI_TransferBlock(spi_id, (uint8_t *) txBuf, (uint8_t *) rxBuf, sizeof(AhrsProgramPacket), NULL); PIOS_SPI_RC_PinSet(spi_id, 1); if(res == 0) { if(rxBuf->type != PROGRAM_NULL && rxBuf->crc == GenerateCRC(rxBuf) && rxBuf->packetId == pktId) { break; } } vTaskDelay(1 / portTICK_RATE_MS); } if(ct == MAX_CONNECT_TRIES) { return (PROGRAM_ERR_LINK); } if(rxBuf->type != PROGRAM_ACK) { return(PROGRAM_ERR_FUNCTION); } return(PROGRAM_ERR_OK); }
void GekkoCPU::HandleSpecialPipeData() { char Filename[1024]; u32 CRC; switch(PipeHandleData[1]) { case 'F': //load a file PipeHandleData[0] = 0x00; memcpy(Filename, &PipeHandleData[2], strlen((char *)&PipeHandleData[2]) + 1); dvd::LoadBootableFile(Filename); break; case 'S': //start the emulation PipeHandleData[0] = 0x00; core::g_started = true; core::SetState(core::SYS_RUNNING); break; case 'I': //instruction count hit, check memory and registers CRC = GenerateCRC((u8 *)&ireg, sizeof(ireg)); if(CRC != *(u32 *)(&PipeHandleData[2])) { printf("CPU Register mismatch before instruction count hit\n\tCRC: 0x%08X\tCorrect: 0x%08X\n", CRC, *(u32 *)(&PipeHandleData[2])); pause = true; } CRC = GenerateCRC(Mem_RAM, RAM_SIZE); if(CRC != *(u32 *)(&PipeHandleData[6])) { printf("Memory mismatch before instruction count hit\n\tCRC: 0x%08X\tCorrect: 0x%08X\n", CRC, *(u32 *)(&PipeHandleData[6])); pause = true; } //signal good or bad if(pause) PipeHandleData[0] = 0x03; else { PipeHandleData[0] = 0x02; //all good printf("Synced with server at IC %08X\n", ireg.IC); } break; } }
void HwWriteCMD(int HwPort, unsigned char CmdNo, unsigned char* buf) { int i; while (get_rev_count(HwPort)) { get_char(HwPort); } HW_Delay(10); memset (sendBuf, 0, sizeof(sendBuf)); *(sendBuf+0) = 'P'; *(sendBuf+1) = CmdNo; *(sendBuf+2) = 4; memcpy(sendBuf+3, buf, 4); *(sendBuf+7) = GenerateCRC(sendBuf, sizeof(sendBuf)); for(i=0; i<8; i++) { put_char(HwPort, sendBuf[i]); } HW_Delay(30); return ; }
BOOL Packetize(CHAR* bufferWithFile, int sentPacketCounter) { CHAR* data = (CHAR*)malloc(PACKET_BYTES_DATA); data[1024] = '\0'; BOOL isDone = FALSE; size_t fileSize = strlen(bufferWithFile); size_t StartLoc = PACKET_BYTES_DATA * sentPacketCounter; //1020 x sentPacketCounter = startingLocation //free(data); if(StartLoc > fileSize) { fprintf(stderr, "%s", "Cannot seek to this location.."); return TRUE; //WE'RE DONE. } for (size_t n = 0; n < PACKET_BYTES_TOTAL; n++) Packet[n] = ' '; for(size_t i = StartLoc, j = 0; j < PACKET_BYTES_DATA; i++, j++) { if((bufferWithFile[i] == EOF || bufferWithFile[i] == '\0')) //if(bufferWithFile[i] == '\0' || bufferWithFile[i] == EOF) //if(bufferWithFile[i] == '\0') { data[j] = 'W'; //data[j] = '\0'; isDone = TRUE; i--; } else { data[j] = bufferWithFile[i]; } } // Add control bytes to the packet Packet[0] = SYN; Packet[1] = (sentPacketCounter % 2 == 0) ? DC1 : DC2; // Add data bytes to the packet for(size_t i = 0; i < PACKET_BYTES_DATA; i++) Packet[i+2] = data[i]; // Add the trailer bytes to the packet (CRC) char pktral[2]; //char* GenerateCRC(char pkt[GENERATE_CRC_TEST_SIZE], char generatedCRC[2]){ // GENERATE_CRC_TEST_SIZE = 1020 GenerateCRC(data, pktral); Packet[PACKET_BYTES_TOTAL-2] = pktral[0]; Packet[PACKET_BYTES_TOTAL-1] = pktral[1]; // free(data); // Done with the data portion buffer char test = data[500]; char test2 = data[800]; return isDone; }
void ucode_loader_parse(u32 message) { //printf ("ucode_loader_parse: %08x\n"); if (ucode_loader.paramsleft>0) { *ucode_loader.parambuf = message; ucode_loader.parambuf++; ucode_loader.paramsleft--; } else { ucode_loader.command=message; switch (message) { case 0x80f3a001: /* RAM addr */ ucode_loader.paramsleft=1; ucode_loader.parambuf=&ucode_loader.DMA_RAMaddr; break; case 0x80f3c002: ucode_loader.paramsleft=1; ucode_loader.parambuf=&ucode_loader.DMA_IRAMaddr; break; case 0x80f3a002: ucode_loader.paramsleft=1; ucode_loader.parambuf=&ucode_loader.DMA_size; break; case 0x80f3b002: ucode_loader.paramsleft=1; ucode_loader.parambuf=&ucode_loader.DMA_DRAMaddr; break; case 0x80f3d001: ucode_loader.paramsleft=1; ucode_loader.parambuf=&ucode_loader.DMA_execaddr; break; default: printf("Unknown message to ucode_loader: %08x\n",message); return; } } if (ucode_loader.paramsleft==0) { if (ucode_loader.command==0x80f3d001) { printf("Execute DSP ucode from RAM %08x size %8x\n",ucode_loader.DMA_RAMaddr, ucode_loader.DMA_size); /* generate checksum */ u32 crc = GenerateCRC( &Mem_RAM[ucode_loader.DMA_RAMaddr & RAM_MASK], ucode_loader.DMA_size); printf("crc32=%08x\n",crc); switch (crc) { case 0x37c241aa: // Twilight Princess NTSC-J case 0x5d0d105e: // Wind Waker NTSC-U case 0xd2fdb38c: // Twlight Princess NTSC-U printf("Zelda: Wind Waker ucode\n"); DSPucode=DSPUCODE_ZWW; ucode_zww_init(); break; } } } }
int HwParseCMD(int HwPort, struct RevCmdData *p_rData) { unsigned char data; unsigned char crc_res, bufLen; unsigned char tmpbuf[30]; int i; bufLen = get_rev_count(HwPort); if (bufLen == 0) { return HW_WAITING; } #ifdef HW_DEBUG printf("bufLen = %d\n", bufLen); #endif for(i=0; i<bufLen; i++) { data = get_char(HwPort); #ifdef HW_DEBUG printf("%x\n", data); #endif //解析 switch(revStatus) { case STATE_RESET: if (data == 'P') { memset ((void *)p_rData, 0, sizeof(struct RevCmdData)); revStatus = STATE_PACKHEAD; } break; case STATE_PACKHEAD: p_rData->CmdNo = data; revStatus = STATE_CMDNO; break; case STATE_CMDNO: p_rData->CmdParaLen = data; revStatus = STATE_LENGTH; revParaLen = 0; break; case STATE_LENGTH: p_rData->CmdPara[revParaLen] = data; revParaLen++; if (revParaLen == p_rData->CmdParaLen) { revStatus = STATE_PARA_END; } break; case STATE_PARA_END: p_rData->CmdCRC = data; memset(tmpbuf, 0, sizeof(tmpbuf)); tmpbuf[0] = 'P'; tmpbuf[1] = p_rData->CmdNo; tmpbuf[2] = p_rData->CmdParaLen; memcpy(&(tmpbuf[3]), p_rData->CmdPara, p_rData->CmdParaLen); crc_res = GenerateCRC( tmpbuf, 4 + p_rData->CmdParaLen ); if (crc_res == p_rData->CmdCRC) { revStatus = STATE_CRC_OK; } else { revStatus = STATE_RESET; return HW_COMMUNICATION_ERR; } break; default: revStatus = STATE_RESET; return HW_COMMUNICATION_ERR; } //接受命令正确。 if (revStatus == STATE_CRC_OK) { revStatus = STATE_RESET; return HW_STATUS_OK; } } return HW_WAITING; }
/*---------------------------------------------------------------------------------------------------------*/ uint32_t MMC_Command_Exec (uint8_t nCmd, uint32_t nArg,uint8_t *pchar, uint32_t *response) { uint8_t loopguard; COMMAND current_command; // Local space for the command table UINT32 long_arg; // Local space for argument static uint32_t current_blklen = 512; uint32_t old_blklen = 512; int32_t counter = 0; // Byte counter for multi-byte fields; UINT16 card_response; // Variable for storing card response; uint8_t data_resp; // Variable for storing data response; UINT16 dummy_CRC; // Dummy variable for storing CRC field; card_response.i = 0; current_command = command_list[nCmd];// Retrieve desired command table entry // from code space; if(current_command.command_byte & 0x80) // Detect ACMD { if(MMC_Command_Exec(APP_CMD,EMPTY,EMPTY,response)==FALSE)//Send APP_CMD return FALSE; } SPI_SetSS(SPI1, SPI_SS0); // CS = 0 SingleWrite(0xFF); SingleWrite((current_command.command_byte | 0x40)&0x7f); DBG_PRINTF("CMD:%d,",current_command.command_byte&0x7f); long_arg.l = nArg; // Make argument byte addressable; // If current command changes block // length, update block length variable // to keep track; // Command byte = 16 means that a set // block length command is taking place // and block length variable must be // set; if(current_command.command_byte == 16) {current_blklen = nArg;} // Command byte = 9 or 10 means that a // 16-byte register value is being read // from the card, block length must be // set to 16 bytes, and restored at the // end of the transfer; if((current_command.command_byte == 9)||(current_command.command_byte == 10)) { old_blklen = current_blklen; // Command is a GET_CSD or GET_CID, current_blklen = 16; // set block length to 16-bytes; } // If an argument is required, transmit // one, otherwise transmit 4 bytes of // 0x00; if(current_command.arg_required == YES) { dummy_CRC.i = GenerateCRC((current_command.command_byte | 0x40), 0x1200, 0); for(counter=3;counter>=0;counter--) { SingleWrite(long_arg.b[counter]); dummy_CRC.i = GenerateCRC(long_arg.b[counter], 0x1200, dummy_CRC.i); } dummy_CRC.i = (dummy_CRC.i >> 8)| 0x01; SingleWrite(dummy_CRC.b[0]); } else
GekkoF GekkoCPU::ComparePipeData(u32 LastAddress) { u32 x; u32 RegCmpCRC; u32 MemCRC; u32 RegCRC; u32 CurAddress; static u32 StartedCompare = 0; u32 StartTime; #define CPU_IC 0x00000000 #define CPU_COMPARE_MEM 0 #if(AllowCompareAcrossEXEs) //server, send data u8 RegCompare[sizeof(Gekko_Registers)]; u32 RegOffset; #endif if(PipeIsClient) { for(;PipeHandleData[0] != 0x01 && PipeHandleData[0] != 0xFE;) { SDL_Delay(0); if(PipeHandleData[0] == 0xFF) { HandleSpecialPipeData(); return; } } if(!StartedCompare) { if(ireg.IC < CPU_IC) return; else { //set our flag and wait for the server to be ready StartedCompare = 1; printf("CPU Compare waiting on server for sync\n"); for(;PipeHandleData[0] != 0xFE;) { SDL_Delay(5); } HandleSpecialPipeData(); return; } } RegCmpCRC = *(u32 *)(&PipeHandleData[1]); // memcpy(&TempReg, &ireg, sizeof(ireg)); /* //due to a difference between int and rec, knock off the lower 32bits for(x = 0; x < 32; x++) { TempReg.fpr[x].ps0._u32[0] = 0; TempReg.fpr[x].ps0._u32[1] &= 0xFFFF0000; TempReg.fpr[x].ps1._u32[0] = 0; TempReg.fpr[x].ps1._u32[1] &= 0xFFFF0000; } */ #if(CPU_COMPARE_MEM) RegCRC = GenerateCRC(Mem_RAM, RAM_SIZE); #else RegCRC = GenerateCRC((u8 *)&ireg, sizeof(ireg)); #endif //copy our keys #pragma todo("what is this? commenting out because keys shouldn't be accessed this way") //if(PipeHandleData[5]) // memcpy(emu.keys, (void *)(&PipeHandleData[6]), sizeof(emu.keys)); if(RegCRC == RegCmpCRC) { //return our position to show good PipeHandleData[0] = 0x02; return; } Gekko_Registers CompareRegs; char opcodeStr[32], operandStr[32]; u32 target; u32 opcode; printf("CPU Data Mismatch!\n"); printf("------------------\n\n"); printf("Reg CRC: 0x%08X\tCorrect: 0x%08X\n", RegCRC, RegCmpCRC); // printf("Mem CRC: 0x%08X\tCorrect: 0x%08X\n", MemCRC, MemCmpCRC); //bad, return an invalid pointer PipeHandleData[0] = 0x03; for(;PipeHandleData[0] != 0x01;){SDL_Delay(0);} memcpy(&CompareRegs, &PipeHandleData[1], sizeof(CompareRegs)); //something does not match pause = true; x = 0; CurAddress = LastAddress; while(x != BRANCH_OPCODE) { opcode = Memory_Read32(CurAddress); x = DisassembleGekko(opcodeStr, operandStr, opcode, CurAddress, &target); printf("%08X (%08X): %s\t%s\n", CurAddress, opcode, opcodeStr, operandStr); CurAddress += 4; }; printf("\nPC: 0x%08X\tLast PC: 0x%08X", ireg.PC, iregBackup.PC); if(ireg.PC != CompareRegs.PC) printf("\tCorrect: 0x%08X\n", CompareRegs.PC); else printf("\n"); printf("TBR: 0x%016I64X", ireg.TBR.TBR); if(ireg.TBR.TBR != CompareRegs.TBR.TBR) printf("\tCorrect: 0x%016I64X\n", CompareRegs.TBR.TBR); else printf("\n"); printf("CR: 0x%08X", ireg.CR); if(ireg.CR != CompareRegs.CR) printf("\tCorrect: 0x%08X\n", CompareRegs.CR); else printf("\n"); printf("IC: 0x%08X", ireg.IC); if(ireg.IC != CompareRegs.IC) printf("\tCorrect: 0x%08X\n", CompareRegs.IC); else printf("\n"); printf("MSR: 0x%08X", ireg.MSR); if(ireg.MSR != CompareRegs.MSR) printf("\tCorrect: 0x%08X\n", CompareRegs.MSR); else printf("\n"); printf("FPSCR: 0x%08X", ireg.FPSCR); if(ireg.FPSCR != CompareRegs.FPSCR) printf("\tCorrect: 0x%08X\n", CompareRegs.FPSCR); else printf("\n"); printf("SRR0: 0x%08X\n", SRR0); printf("CTR: 0x%08X\n", CTR); //find out the invalid data for(x=0; x < 32; x++) { printf("GPR %d: Start: 0x%08X\tEnd: 0x%08X", x, iregBackup.gpr[x], ireg.gpr[x]); if(ireg.gpr[x] != CompareRegs.gpr[x]) printf("\tCorrect: 0x%08X\n", CompareRegs.gpr[x]); else printf("\n"); } //find out the invalid data for(x=0; x < 1024; x++) { if(ireg.spr[x] != CompareRegs.spr[x]) printf("SPR %d: Start: 0x%08X\tEnd: 0x%08X\tCorrect: 0x%08X\n", x, iregBackup.spr[x], ireg.spr[x], CompareRegs.spr[x]); } for(x=0; x < 16; x++) { if(ireg.sr[x] != CompareRegs.sr[x]) printf("SR %d: Start: 0x%08X\tEnd: 0x%08X\tCorrect: 0x%08X\n", x, iregBackup.sr[x], ireg.sr[x], CompareRegs.sr[x]); } for(x=0; x < 32; x++) { printf("FPR %d Start: 0x%016I64X-%016I64X\nFPR %d End:0x%016I64X-%016I64X\n", x, iregBackup.fpr[x].ps1._u64, iregBackup.fpr[x].ps0._u64, x, ireg.fpr[x].ps1._u64, ireg.fpr[x].ps0._u64); // if(((ireg.fpr[x].ps0._u32[1] & 0xFFFF0000) != (CompareRegs.fpr[x].ps0._u32[1] & 0xFFFF0000)) || // ((ireg.fpr[x].ps1._u32[1] & 0xFFFF0000) != (CompareRegs.fpr[x].ps1._u32[1] & 0xFFFF0000))) if((ireg.fpr[x].ps0._u32[1] != CompareRegs.fpr[x].ps0._u32[1]) || (ireg.fpr[x].ps1._u32[1] != CompareRegs.fpr[x].ps1._u32[1]) || (ireg.fpr[x].ps0._u32[0] != CompareRegs.fpr[x].ps0._u32[0]) || (ireg.fpr[x].ps1._u32[0] != CompareRegs.fpr[x].ps1._u32[0])) printf("FPR %d Correct: 0x%016I64X-%016I64X\n", x, CompareRegs.fpr[x].ps1._u64, CompareRegs.fpr[x].ps0._u64); printf("\n"); } //tell the cpu do dump it's data DumpInternalData(LastAddress, CurAddress - LastAddress); } else { if(!StartedCompare) { if(ireg.IC < CPU_IC) { //let it pass thru on the client side, client won't skip past due to needing other input PipeHandleData[0] = 0x01; return; } else { StartedCompare = 0x01; //generate the needed crc's for a full compare of memory and cpu RegCRC = GenerateCRC((u8 *)&ireg, sizeof(ireg)); *(u32*)(&PipeHandleData[2]) = RegCRC; MemCRC = GenerateCRC(Mem_RAM, RAM_SIZE); *(u32*)(&PipeHandleData[6]) = MemCRC; PipeHandleData[1] = 'I'; PipeHandleData[0] = 0xFE; printf("CPU Compare waiting on client for sync\n"); for(;PipeHandleData[0] == 0xFE;){SDL_Delay(5);} if(PipeHandleData[0] != 0x02) { printf("Memory or CPU does not match upon instruction count expiration\n"); pause = true; } else printf("Synced at IC %08X\n", CPU_IC); return; } } //if paused then don't allow any of the data to be modified if(pause) return; //generate the register crc //due to a difference between int and rec, knock off the lower 32bits // memcpy(&TempReg, &ireg, sizeof(ireg)); /* for(x = 0; x < 32; x++) { TempReg.fpr[x].ps0._u32[0] = 0; TempReg.fpr[x].ps0._u32[1] &= 0xFFFF0000; TempReg.fpr[x].ps1._u32[0] = 0; TempReg.fpr[x].ps1._u32[1] &= 0xFFFF0000; } */ #if(CPU_COMPARE_MEM) RegCRC = GenerateCRC(Mem_RAM, RAM_SIZE); #else RegCRC = GenerateCRC((u8 *)&ireg, sizeof(ireg)); #endif *(u32*)&PipeHandleData[1] = RegCRC; #pragma todo("what is this? commenting out because keys shouldn't be accessed this way") //copy our keys //if(emu.keychange) //{ // PipeHandleData[5] = 1; // memcpy((void *)(&PipeHandleData[6]), emu.compkeys, sizeof(emu.compkeys)); // memcpy((void *)emu.keys, emu.compkeys, sizeof(emu.keys)); // emu.keychange = FALSE; //} //else //{ PipeHandleData[5] = 0; //} //generate a CRC of the memory // MemCRC = GenerateCRC((u8 *)&Mem_RAM, sizeof(Mem_RAM)); // *(u32*)&PipeHandleData[5] = MemCRC; PipeHandleData[0] = 0x01; StartTime = SDL_GetTicks(); for(;PipeHandleData[0] == 0x01;) { if((SDL_GetTicks() - StartTime) > 5000) { printf("Waiting on client, IC @ 0x%08X\n", ireg.IC); for(;PipeHandleData[0] == 0x01;){SDL_Delay(0);} } } if(PipeHandleData[0] != 0x02) { printf("F****d Up version f****d up\n"); pause = true; memcpy(&PipeHandleData[1], &ireg, sizeof(ireg)); PipeHandleData[0] = 0x01; } } }