From 1a1fdf6a5a84cc64fbb59274086b6fed54069171 Mon Sep 17 00:00:00 2001 From: AKuHAK <621640+AKuHAK@users.noreply.github.com> Date: Sun, 7 Jan 2024 21:28:06 +0200 Subject: [PATCH] DEV9: various fixes for ATA Identify improved 48-bit addressing UDMA mode now set correctly MDMA0 mode now set correctly fixed user addressable sectors limit --- pcsx2/DEV9/ATA/ATA_Info.cpp | 100 ++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 38 deletions(-) diff --git a/pcsx2/DEV9/ATA/ATA_Info.cpp b/pcsx2/DEV9/ATA/ATA_Info.cpp index 2fb3c590186a5..2db914554092f 100644 --- a/pcsx2/DEV9/ATA/ATA_Info.cpp +++ b/pcsx2/DEV9/ATA/ATA_Info.cpp @@ -32,15 +32,18 @@ void ATA::WritePaddedString(u8* data, int* index, const std::string& value, u32 void ATA::CreateHDDinfo(u64 sizeSectors) { - //PS2 is limited to 32bit size HDD (2TB), however, + //PS2 is limited to 48bit size HDD (2TB), however, //we don't yet support 48bit, so limit to 28bit size - constexpr u32 maxSize = (1 << 28) - 1; // 128Gb - sizeSectors = std::min(sizeSectors, maxSize); + u64 maxSize = (1 << 28) - 1; // 128Gb + const u32 nbSectors = std::min(sizeSectors, maxSize); // nbSectors will hold 28-bit size + if (lba48Supported) + maxSize = (1ULL << 48) - 1; // 128PiB + + sizeSectors = std::min(sizeSectors, maxSize); constexpr u16 sectorSize = 512; DevCon.WriteLn("DEV9: HddSize : %i", sizeSectors * sectorSize / (1024 * 1024)); - const u64 nbSectors = sizeSectors; - DevCon.WriteLn("DEV9: nbSectors : %i", nbSectors); + DevCon.WriteLn("DEV9: sizeSectors : %i", sizeSectors); // SizeSectors will keep 48-bit size memset(&identifyData, 0, sizeof(identifyData)); //Defualt CHS translation @@ -150,7 +153,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors) */ WriteUInt16(identifyData, &index, static_cast(curMultipleSectorsSetting | (1 << 8))); //word 59 //Total number of user addressable logical sectors - WriteUInt32(identifyData, &index, static_cast(nbSectors < 268435456 ? nbSectors : 268435456)); //word 60-61 + WriteUInt32(identifyData, &index, nbSectors); //word 60-61 //DMA modes /* * bits 0-7: Singleword modes supported (0,1,2) @@ -165,19 +168,19 @@ void ATA::CreateHDDinfo(u64 sizeSectors) * bits 0-7: Multiword modes supported (0,1,2) * bits 8-15: Transfer mode active */ - if (mdmaMode > 0) + if (mdmaMode >= 0) WriteUInt16(identifyData, &index, static_cast(0x07 | (1 << (mdmaMode + 8)))); //word 63 else WriteUInt16(identifyData, &index, 0x07); //word 63 - //Bit 0-7-PIO modes supported (0,1,2,3,4) - WriteUInt16(identifyData, &index, 0x1F); //word 64 (pio3,4 supported) selection not reported here - //Minimum Multiword DMA transfer cycle time per word - WriteUInt16(identifyData, &index, 80); //word 65 - //Manufacturer’s recommended Multiword DMA transfer cycle time - WriteUInt16(identifyData, &index, 80); //word 66 - //Minimum PIO transfer cycle time without flow control + //Bits 0-1 PIO modes supported (3,4) + WriteUInt16(identifyData, &index, 0x03); //word 64 (pio3,4 supported) + //Minimum Multiword DMA transfer cycle time per word, 120ns + WriteUInt16(identifyData, &index, 120); //word 65 + //Manufacturer’s recommended Multiword DMA transfer cycle time, 120ns + WriteUInt16(identifyData, &index, 120); //word 66 + //Minimum PIO transfer cycle time without flow control, 120ns WriteUInt16(identifyData, &index, 120); //word 67 - //Minimum PIO transfer cycle time with IORDY flow control + //Minimum PIO transfer cycle time with IORDY flow control, 120ns WriteUInt16(identifyData, &index, 120); //word 68 //Reserved //69-70 @@ -188,10 +191,10 @@ void ATA::CreateHDDinfo(u64 sizeSectors) //Reserved //76-79 index = 80 * 2; - //Major revision number (1-3-Obsolete, 4-7-ATA4-7 supported) + //Major revision number (1-3: Obsolete, 4-7: ATA/ATAPI 4-7 supported) WriteUInt16(identifyData, &index, 0x70); //word 80 - //Minor revision number - WriteUInt16(identifyData, &index, 0); //word 81 + //Minor revision number, 0x18 - ATA/ATAPI-6 T13 1410D revision 0 + WriteUInt16(identifyData, &index, 0x18); //word 81 //Supported Feature Sets (82) /* * bit 0: Smart @@ -211,7 +214,12 @@ void ATA::CreateHDDinfo(u64 sizeSectors) * bit 14: NOP * bit 15: (Obsolete) */ - WriteUInt16(identifyData, &index, static_cast((1 << 14) | (1 << 5) | /*(1 << 1) | (1 << 10) |*/ 1)); //word 82 + // clang-format off + WriteUInt16(identifyData, &index, ( //word 82 + (1 << 0) | //Implemented + (1 << 5) | //Implemented + (1 << 14) //Implemented + /*| (1 << 1) | (1 << 10)*/)); //Supported Feature Sets (83) /* * bit 0: DOWNLOAD MICROCODE @@ -230,7 +238,12 @@ void ATA::CreateHDDinfo(u64 sizeSectors) * bit 13: FLUSH CACHE EXT * bit 14: 1 */ - WriteUInt16(identifyData, &index, static_cast((1 << 14) | (1 << 13) | (1 << 12) /*| (1 << 8)*/ | ((lba48Supported ? 1 : 0) << 10))); //word 83 + WriteUInt16(identifyData, &index, ( //word 83 + (lba48Supported << 10) | //user defined + (1 << 12) | //Implemented + (1 << 13) | //Implemented + (1 << 14) //Always one + /*| (1 << 8)*/)); //Supported Feature Sets (84) /* * bit 0: Smart error logging @@ -247,28 +260,35 @@ void ATA::CreateHDDinfo(u64 sizeSectors) * bit 13: IDLE IMMEDIATE with UNLOAD FEATURE * bit 14: 1 */ - WriteUInt16(identifyData, &index, static_cast((1 << 14) | (1 << 1) | 1)); //word 84 + WriteUInt16(identifyData, &index, ( //word 84 + (1 << 0) | //Implemented + (1 << 1) | //Implemented + (1 << 14))); //Always one //Command set/feature enabled/supported (See word 82) - WriteUInt16(identifyData, &index, static_cast((fetSmartEnabled << 0) | (fetSecurityEnabled << 1) | (fetWriteCacheEnabled << 5) | (fetHostProtectedAreaEnabled << 10) | (1 << 14))); //Fixed //word 85 + WriteUInt16(identifyData, &index, ( //word 85 + (fetSmartEnabled << 0) | //Variable, implemented + (fetSecurityEnabled << 1) | //Variable, not implemented + (fetWriteCacheEnabled << 5) | //Variable, implemented + (fetHostProtectedAreaEnabled << 10)|//Variable, not implemented + (1 << 14))); //Always one //Command set/feature enabled/supported (See word 83) - // clang-format off - WriteUInt16(identifyData, &index, static_cast( + WriteUInt16(identifyData, &index, ( //word 86 /*(1 << 8) | //SET MAX */ - ((lba48Supported ? 1 : 0) << 10) | //Fixed - (1 << 12) | //Fixed - (1 << 13))); //Fixed //word 86 + (lba48Supported << 10) | //user defined + (1 << 12) | //Implemented + (1 << 13))); //Implemented //Command set/feature enabled/supported (See word 84) - WriteUInt16(identifyData, &index, static_cast((1 << 14) | (1 << 1) | 1)); - WriteUInt16(identifyData, &index, static_cast( - (1) | //Fixed - ((1) << 1))); //Fixed //word 87 + WriteUInt16(identifyData, &index, ( //word 87 + (1 << 0) | //Implemented + (1 << 1) | //Implemented + (1 << 14))); //Fixed // clang-format on //UDMA modes /* * bits 0-7: ultraword modes supported (0,1,2,4,5,6,7) * bits 8-15: Transfer mode active */ - if (udmaMode > 0) + if (udmaMode >= 0) WriteUInt16(identifyData, &index, static_cast(0x7f | (1 << (udmaMode + 8)))); //word 88 else WriteUInt16(identifyData, &index, 0x7f); //word 88 @@ -297,7 +317,10 @@ void ATA::CreateHDDinfo(u64 sizeSectors) * bit 14: 1 */ index = 93 * 2; - WriteUInt16(identifyData, &index, static_cast(1 | (1 << 14) | 0x2000)); //word 93 + if (GetSelectedDevice()) + WriteUInt16(identifyData, &index, ((1 << 14) | (0x3 << 8))); //word 93, Device 1 + else + WriteUInt16(identifyData, &index, ((1 << 14) | (1 << 3) | 0x3)); //word 93, Device 0 //Vendor’s recommended acoustic management value. //94 //Stream Minimum Request Size @@ -310,9 +333,10 @@ void ATA::CreateHDDinfo(u64 sizeSectors) //98-99 //Total Number of User Addressable Sectors for the 48-bit Address feature set. index = 100 * 2; - WriteUInt64(identifyData, &index, static_cast(nbSectors)); - index -= 2; - WriteUInt16(identifyData, &index, 0); //truncate to 48bits + if (lba48Supported) + WriteUInt64(identifyData, &index, sizeSectors); + else + WriteUInt64(identifyData, &index, 0); // for 28-bit only this area is empty //Streaming Transfer Time - PIO //104 //Reserved @@ -325,7 +349,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors) * bit 14: 1 */ index = 106 * 2; - WriteUInt16(identifyData, &index, static_cast((1 << 14) | 0)); + WriteUInt16(identifyData, &index, ((1 << 14) | 0)); //Inter-seek delay for ISO-7779acoustic testing in microseconds //107 //WNN @@ -365,7 +389,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors) //15:8 Checksum, 7:0 Signature CreateHDDinfoCsum(); } -void ATA::CreateHDDinfoCsum() //Is this correct? +void ATA::CreateHDDinfoCsum() { u8 counter = 0;