private void startDma(int dmaControl) { this.dmaControl = dmaControl; if ((dmaControl & DMA_CONTROL_START) != 0) { int ppn = dmaAddress >> 10; int scramble = getScramble(ppn); // Read or write operation? if ((dmaControl & DMA_CONTROL_WRITE) != 0) { int lbn = endianSwap16(pageEccMemory.read16(6) & 0xFFFF); if (lbn == 0xFFFF) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("writing to ppn=0x{0:X} with lbn=0x{1:X} ignored", ppn, lbn)); } } else { TPointer spare = pageEccMemory.Pointer; sceNandModule.hleNandWriteSparePages(ppn, spare, 1, true, true, true); TPointer user = pageDataMemory.Pointer; // Updating the scramble as the LBN corresponding to the PPN might have been moved scramble = getScramble(ppn); if (scramble != 0) { sceNand.descramblePage(scramble, ppn, MMIOHandlerNandPage.Instance.Data, scrambleBuffer); user = scrambleBufferMemory.Pointer; } sceNandModule.hleNandWriteUserPages(ppn, user, 1, true, true); //if (log.DebugEnabled) { sbyte[] userBytes = new sbyte[sceNand.pageSize]; user = scramble != 0 ? scrambleBufferMemory.Pointer : pageDataMemory.Pointer; for (int i = 0; i < userBytes.Length; i++) { userBytes[i] = user.getValue8(i); } sbyte[] spareBytes = new sbyte[16]; spare = pageEccMemory.Pointer; for (int i = 0; i < spareBytes.Length; i++) { spareBytes[i] = spare.getValue8(i); } Console.WriteLine(string.Format("hleNandWritePages ppn=0x{0:X}, lbn=0x{1:X}, scramble=0x{2:X}: {3}{4}Spare: {5}", ppn, lbn, scramble, Utilities.getMemoryDump(userBytes), lineSeparator, Utilities.getMemoryDump(spareBytes))); } } triggerInterrupt(PSP_NAND_INTR_WRITE_COMPLETED); } else { TPointer user = scramble != 0 ? scrambleBufferMemory.Pointer : pageDataMemory.Pointer; TPointer spare = pageEccMemory.Pointer; sceNandModule.hleNandReadPages(ppn, user, spare, 1, true, true, true); //if (log.DebugEnabled) { sbyte[] bytes = new sbyte[sceNand.pageSize]; user = scramble != 0 ? scrambleBufferMemory.Pointer : pageDataMemory.Pointer; for (int i = 0; i < bytes.Length; i++) { bytes[i] = user.getValue8(i); } Console.WriteLine(string.Format("hleNandReadPages ppn=0x{0:X}, scramble=0x{1:X}: {2}", ppn, scramble, Utilities.getMemoryDump(bytes))); } if (scramble != 0) { sceNand.scramblePage(scramble, ppn, scrambleBuffer, MMIOHandlerNandPage.Instance.Data); } triggerInterrupt(PSP_NAND_INTR_READ_COMPLETED); } } }
private int hleUtilsBufferCopyWithRange() { TPointer outAddr = new TPointer(Memory, normalizeAddress(destAddr)); TPointer inAddr = new TPointer(Memory, normalizeAddress(sourceAddr)); int inSize; int outSize; int dataSize; int dataOffset; switch (command) { case PSP_KIRK_CMD_ENCRYPT: case PSP_KIRK_CMD_ENCRYPT_FUSE: // AES128_CBC_Header dataSize = inAddr.getValue32(16); inSize = dataSize + 20; outSize = dataSize + 20; break; case PSP_KIRK_CMD_DECRYPT: case PSP_KIRK_CMD_DECRYPT_FUSE: // AES128_CBC_Header dataSize = inAddr.getValue32(16); inSize = dataSize + 20; outSize = dataSize; break; case PSP_KIRK_CMD_DECRYPT_PRIVATE: // AES128_CMAC_Header dataSize = inAddr.getValue32(112); dataOffset = inAddr.getValue32(116); inSize = 144 + Utilities.alignUp(dataSize, 15) + dataOffset; outSize = Utilities.alignUp(dataSize, 15); break; case PSP_KIRK_CMD_PRIV_SIG_CHECK: // AES128_CMAC_Header dataSize = inAddr.getValue32(112); dataOffset = inAddr.getValue32(116); inSize = 144 + Utilities.alignUp(dataSize, 15) + dataOffset; outSize = 0; break; case PSP_KIRK_CMD_SHA1_HASH: // SHA1_Header inSize = inAddr.getValue32(0) + 4; outSize = 20; break; case PSP_KIRK_CMD_ECDSA_GEN_KEYS: inSize = 0; outSize = 0x3C; break; case PSP_KIRK_CMD_ECDSA_MULTIPLY_POINT: inSize = 0x3C; outSize = 0x28; break; case PSP_KIRK_CMD_PRNG: inSize = 0; outSize = 0x10; // TODO Unknown outSize? break; case PSP_KIRK_CMD_ECDSA_SIGN: inSize = 0x34; outSize = 0x28; break; case PSP_KIRK_CMD_ECDSA_VERIFY: inSize = 0x64; outSize = 0; break; case PSP_KIRK_CMD_INIT: inSize = 0; outSize = 0; break; case PSP_KIRK_CMD_CERT_VERIFY: inSize = 0xB8; outSize = 0; break; default: Console.WriteLine(string.Format("MMIOHandlerKirk.hleUtilsBufferCopyWithRange unimplemented KIRK command 0x{0:X}", command)); result = PSP_KIRK_INVALID_OPERATION; return(0); } //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleUtilsBufferCopyWithRange input: {0}", Utilities.getMemoryDump(inAddr, inSize))); } foreach (int commandToBeDumped in commandsToBeDumped) { if (command == commandToBeDumped) { string dumpFileName = string.Format("dump.hleUtilsBufferCopyWithRange.{0:D}", dumpIndex++); Console.WriteLine(string.Format("MMIOHandlerKirk: hleUtilsBufferCopyWithRange dumping command=0x{0:X}, outputSize=0x{1:X}, inputSize=0x{2:X}, input dumped into file '{3}'", command, outSize, inSize, dumpFileName)); try { System.IO.Stream dump = new System.IO.FileStream(dumpFileName, System.IO.FileMode.Create, System.IO.FileAccess.Write); sbyte[] inputBuffer = new sbyte[inSize]; for (int i = 0; i < inSize; i++) { inputBuffer[i] = inAddr.getValue8(i); } dump.Write(inputBuffer, 0, inputBuffer.Length); dump.Close(); } catch (IOException) { } } } result = Modules.semaphoreModule.hleUtilsBufferCopyWithRange(outAddr, outSize, inAddr, inSize, command); //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleUtilsBufferCopyWithRange result=0x{0:X}, output: {1}", result, Utilities.getMemoryDump(outAddr, outSize))); } if (result != 0) { string dumpFileName = string.Format("dump.hleUtilsBufferCopyWithRange.{0:D}", dumpIndex++); Console.WriteLine(string.Format("MMIOHandlerKirk: hleUtilsBufferCopyWithRange returned error result=0x{0:X} for command=0x{1:X}, outputSize=0x{2:X}, inputSize=0x{3:X}, input dumped into file '{4}'", result, command, outSize, inSize, dumpFileName)); try { System.IO.Stream dump = new System.IO.FileStream(dumpFileName, System.IO.FileMode.Create, System.IO.FileAccess.Write); sbyte[] inputBuffer = new sbyte[inSize]; for (int i = 0; i < inSize; i++) { inputBuffer[i] = inAddr.getValue8(i); } dump.Write(inputBuffer, 0, inputBuffer.Length); dump.Close(); } catch (IOException) { } } return(System.Math.Max(inSize, outSize)); }