Skip to content

Commit

Permalink
DEV9: various fixes for ATA Identify
Browse files Browse the repository at this point in the history
improved 48-bit addressing
UDMA mode now set correctly
MDMA0 mode now set correctly
fixed user addressable sectors limit
  • Loading branch information
AKuHAK authored and refractionpcsx2 committed Jan 9, 2024
1 parent c469b17 commit 1a1fdf6
Showing 1 changed file with 62 additions and 38 deletions.
100 changes: 62 additions & 38 deletions pcsx2/DEV9/ATA/ATA_Info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>(sizeSectors, maxSize);
u64 maxSize = (1 << 28) - 1; // 128Gb
const u32 nbSectors = std::min<u32>(sizeSectors, maxSize); // nbSectors will hold 28-bit size
if (lba48Supported)
maxSize = (1ULL << 48) - 1; // 128PiB

sizeSectors = std::min<u64>(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
Expand Down Expand Up @@ -150,7 +153,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
*/
WriteUInt16(identifyData, &index, static_cast<u16>(curMultipleSectorsSetting | (1 << 8))); //word 59
//Total number of user addressable logical sectors
WriteUInt32(identifyData, &index, static_cast<u32>(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)
Expand All @@ -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<u16>(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
Expand All @@ -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
Expand All @@ -211,7 +214,12 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
* bit 14: NOP
* bit 15: (Obsolete)
*/
WriteUInt16(identifyData, &index, static_cast<u16>((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
Expand All @@ -230,7 +238,12 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
* bit 13: FLUSH CACHE EXT
* bit 14: 1
*/
WriteUInt16(identifyData, &index, static_cast<u16>((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
Expand All @@ -247,28 +260,35 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
* bit 13: IDLE IMMEDIATE with UNLOAD FEATURE
* bit 14: 1
*/
WriteUInt16(identifyData, &index, static_cast<u16>((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<u16>((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<u16>(
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<u16>((1 << 14) | (1 << 1) | 1));
WriteUInt16(identifyData, &index, static_cast<u16>(
(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<u16>(0x7f | (1 << (udmaMode + 8)))); //word 88
else
WriteUInt16(identifyData, &index, 0x7f); //word 88
Expand Down Expand Up @@ -297,7 +317,10 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
* bit 14: 1
*/
index = 93 * 2;
WriteUInt16(identifyData, &index, static_cast<u16>(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
Expand All @@ -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<u16>(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
Expand All @@ -325,7 +349,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
* bit 14: 1
*/
index = 106 * 2;
WriteUInt16(identifyData, &index, static_cast<u16>((1 << 14) | 0));
WriteUInt16(identifyData, &index, ((1 << 14) | 0));
//Inter-seek delay for ISO-7779acoustic testing in microseconds
//107
//WNN
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 1a1fdf6

Please sign in to comment.