mirror of
https://github.com/Fennix-Project/Drivers.git
synced 2025-05-25 22:14:31 +00:00
Add ATA_CMD_IDENTIFY and SATA SDD detection
This commit is contained in:
parent
da4a6317ea
commit
96530ad165
@ -21,23 +21,27 @@
|
||||
#include <base.h>
|
||||
#include <pci.h>
|
||||
|
||||
#define ATA_DEV_BUSY 0x80
|
||||
#define ATA_DEV_DRQ 0x08
|
||||
#define ATA_CMD_WRITE_DMA_EX 0x35
|
||||
#define ATA_DEV_BUSY 0x80
|
||||
#define ATA_CMD_READ_DMA_EX 0x25
|
||||
#define ATA_CMD_WRITE_DMA_EX 0x35
|
||||
#define ATA_CMD_IDENTIFY 0xEC
|
||||
|
||||
#define ATAPI_CMD_IDENTIFY_PACKET 0xA1
|
||||
|
||||
#define HBA_PORT_IPM_ACTIVE 0x1
|
||||
#define HBA_PORT_DEV_PRESENT 0x3
|
||||
#define HBA_PxIS_TFES (1 << 30)
|
||||
|
||||
#define HBA_PORT_DEV_PRESENT 0x3
|
||||
#define HBA_PORT_IPM_ACTIVE 0x1
|
||||
#define SATA_SIG_ATAPI 0xEB140101
|
||||
#define SATA_SIG_ATA 0x00000101
|
||||
#define SATA_SIG_SEMB 0xC33C0101
|
||||
#define SATA_SIG_PM 0x96690101
|
||||
#define SATA_SIG_SEMB 0xC33C0101
|
||||
#define SATA_SIG_ATAPI 0xEB140101
|
||||
|
||||
#define HBA_PxCMD_CR 0x8000
|
||||
#define HBA_PxCMD_FRE 0x0010
|
||||
#define HBA_PxCMD_ST 0x0001
|
||||
#define HBA_PxCMD_FRE 0x0010
|
||||
#define HBA_PxCMD_FR 0x4000
|
||||
#define HBA_PxCMD_CR 0x8000
|
||||
|
||||
enum PortType
|
||||
{
|
||||
@ -160,6 +164,402 @@ struct FIS_REG_H2D
|
||||
uint8_t Reserved1[4];
|
||||
};
|
||||
|
||||
/* https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data */
|
||||
struct __attribute__((packed)) ATA_IDENTIFY
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t Reserved1 : 1;
|
||||
uint16_t Retired3 : 1;
|
||||
uint16_t ResponseIncomplete : 1;
|
||||
uint16_t Retired2 : 3;
|
||||
uint16_t FixedDevice : 1;
|
||||
uint16_t RemovableMedia : 1;
|
||||
uint16_t Retired1 : 7;
|
||||
uint16_t DeviceType : 1;
|
||||
} GeneralConfiguration;
|
||||
uint16_t NumCylinders;
|
||||
uint16_t SpecificConfiguration;
|
||||
uint16_t NumHeads;
|
||||
uint16_t Retired1[2];
|
||||
uint16_t NumSectorsPerTrack;
|
||||
uint16_t VendorUnique1[3];
|
||||
uint8_t SerialNumber[20];
|
||||
uint16_t Retired2[2];
|
||||
uint16_t Obsolete1;
|
||||
uint8_t FirmwareRevision[8];
|
||||
uint8_t ModelNumber[40];
|
||||
uint8_t MaximumBlockTransfer;
|
||||
uint8_t VendorUnique2;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t FeatureSupported : 1;
|
||||
uint16_t Reserved : 15;
|
||||
} TrustedComputing;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint8_t CurrentLongPhysicalSectorAlignment : 2;
|
||||
uint8_t ReservedByte49 : 6;
|
||||
uint8_t DmaSupported : 1;
|
||||
uint8_t LbaSupported : 1;
|
||||
uint8_t IordyDisable : 1;
|
||||
uint8_t IordySupported : 1;
|
||||
uint8_t Reserved1 : 1;
|
||||
uint8_t StandybyTimerSupport : 1;
|
||||
uint8_t Reserved2 : 2;
|
||||
uint16_t ReservedWord50;
|
||||
} Capabilities;
|
||||
uint16_t ObsoleteWords51[2];
|
||||
uint16_t TranslationFieldsValid : 3;
|
||||
uint16_t Reserved3 : 5;
|
||||
uint16_t FreeFallControlSensitivity : 8;
|
||||
uint16_t NumberOfCurrentCylinders;
|
||||
uint16_t NumberOfCurrentHeads;
|
||||
uint16_t CurrentSectorsPerTrack;
|
||||
uint32_t CurrentSectorCapacity;
|
||||
uint8_t CurrentMultiSectorSetting;
|
||||
uint8_t MultiSectorSettingValid : 1;
|
||||
uint8_t ReservedByte59 : 3;
|
||||
uint8_t SanitizeFeatureSupported : 1;
|
||||
uint8_t CryptoScrambleExtCommandSupported : 1;
|
||||
uint8_t OverwriteExtCommandSupported : 1;
|
||||
uint8_t BlockEraseExtCommandSupported : 1;
|
||||
uint32_t UserAddressableSectors;
|
||||
uint16_t ObsoleteWord62;
|
||||
uint16_t MultiWordDMASupport : 8;
|
||||
uint16_t MultiWordDMAActive : 8;
|
||||
uint16_t AdvancedPIOModes : 8;
|
||||
uint16_t ReservedByte64 : 8;
|
||||
uint16_t MinimumMWXferCycleTime;
|
||||
uint16_t RecommendedMWXferCycleTime;
|
||||
uint16_t MinimumPIOCycleTime;
|
||||
uint16_t MinimumPIOCycleTimeIORDY;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t ZonedCapabilities : 2;
|
||||
uint16_t NonVolatileWriteCache : 1;
|
||||
uint16_t ExtendedUserAddressableSectorsSupported : 1;
|
||||
uint16_t DeviceEncryptsAllUserData : 1;
|
||||
uint16_t ReadZeroAfterTrimSupported : 1;
|
||||
uint16_t Optional28BitCommandsSupported : 1;
|
||||
uint16_t IEEE1667 : 1;
|
||||
uint16_t DownloadMicrocodeDmaSupported : 1;
|
||||
uint16_t SetMaxSetPasswordUnlockDmaSupported : 1;
|
||||
uint16_t WriteBufferDmaSupported : 1;
|
||||
uint16_t ReadBufferDmaSupported : 1;
|
||||
uint16_t DeviceConfigIdentifySetDmaSupported : 1;
|
||||
uint16_t LPSAERCSupported : 1;
|
||||
uint16_t DeterministicReadAfterTrimSupported : 1;
|
||||
uint16_t CFastSpecSupported : 1;
|
||||
} AdditionalSupported;
|
||||
uint16_t ReservedWords70[5];
|
||||
uint16_t QueueDepth : 5;
|
||||
uint16_t ReservedWord75 : 11;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t Reserved0 : 1;
|
||||
uint16_t SataGen1 : 1;
|
||||
uint16_t SataGen2 : 1;
|
||||
uint16_t SataGen3 : 1;
|
||||
uint16_t Reserved1 : 4;
|
||||
uint16_t NCQ : 1;
|
||||
uint16_t HIPM : 1;
|
||||
uint16_t PhyEvents : 1;
|
||||
uint16_t NcqUnload : 1;
|
||||
uint16_t NcqPriority : 1;
|
||||
uint16_t HostAutoPS : 1;
|
||||
uint16_t DeviceAutoPS : 1;
|
||||
uint16_t ReadLogDMA : 1;
|
||||
uint16_t Reserved2 : 1;
|
||||
uint16_t CurrentSpeed : 3;
|
||||
uint16_t NcqStreaming : 1;
|
||||
uint16_t NcqQueueMgmt : 1;
|
||||
uint16_t NcqReceiveSend : 1;
|
||||
uint16_t DEVSLPtoReducedPwrState : 1;
|
||||
uint16_t Reserved3 : 8;
|
||||
} SerialAtaCapabilities;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t Reserved0 : 1;
|
||||
uint16_t NonZeroOffsets : 1;
|
||||
uint16_t DmaSetupAutoActivate : 1;
|
||||
uint16_t DIPM : 1;
|
||||
uint16_t InOrderData : 1;
|
||||
uint16_t HardwareFeatureControl : 1;
|
||||
uint16_t SoftwareSettingsPreservation : 1;
|
||||
uint16_t NCQAutosense : 1;
|
||||
uint16_t DEVSLP : 1;
|
||||
uint16_t HybridInformation : 1;
|
||||
uint16_t Reserved1 : 6;
|
||||
} SerialAtaFeaturesSupported;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t Reserved0 : 1;
|
||||
uint16_t NonZeroOffsets : 1;
|
||||
uint16_t DmaSetupAutoActivate : 1;
|
||||
uint16_t DIPM : 1;
|
||||
uint16_t InOrderData : 1;
|
||||
uint16_t HardwareFeatureControl : 1;
|
||||
uint16_t SoftwareSettingsPreservation : 1;
|
||||
uint16_t DeviceAutoPS : 1;
|
||||
uint16_t DEVSLP : 1;
|
||||
uint16_t HybridInformation : 1;
|
||||
uint16_t Reserved1 : 6;
|
||||
} SerialAtaFeaturesEnabled;
|
||||
uint16_t MajorRevision;
|
||||
uint16_t MinorRevision;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t SmartCommands : 1;
|
||||
uint16_t SecurityMode : 1;
|
||||
uint16_t RemovableMediaFeature : 1;
|
||||
uint16_t PowerManagement : 1;
|
||||
uint16_t Reserved1 : 1;
|
||||
uint16_t WriteCache : 1;
|
||||
uint16_t LookAhead : 1;
|
||||
uint16_t ReleaseInterrupt : 1;
|
||||
uint16_t ServiceInterrupt : 1;
|
||||
uint16_t DeviceReset : 1;
|
||||
uint16_t HostProtectedArea : 1;
|
||||
uint16_t Obsolete1 : 1;
|
||||
uint16_t WriteBuffer : 1;
|
||||
uint16_t ReadBuffer : 1;
|
||||
uint16_t Nop : 1;
|
||||
uint16_t Obsolete2 : 1;
|
||||
uint16_t DownloadMicrocode : 1;
|
||||
uint16_t DmaQueued : 1;
|
||||
uint16_t Cfa : 1;
|
||||
uint16_t AdvancedPm : 1;
|
||||
uint16_t Msn : 1;
|
||||
uint16_t PowerUpInStandby : 1;
|
||||
uint16_t ManualPowerUp : 1;
|
||||
uint16_t Reserved2 : 1;
|
||||
uint16_t SetMax : 1;
|
||||
uint16_t Acoustics : 1;
|
||||
uint16_t BigLba : 1;
|
||||
uint16_t DeviceConfigOverlay : 1;
|
||||
uint16_t FlushCache : 1;
|
||||
uint16_t FlushCacheExt : 1;
|
||||
uint16_t WordValid83 : 2;
|
||||
uint16_t SmartErrorLog : 1;
|
||||
uint16_t SmartSelfTest : 1;
|
||||
uint16_t MediaSerialNumber : 1;
|
||||
uint16_t MediaCardPassThrough : 1;
|
||||
uint16_t StreamingFeature : 1;
|
||||
uint16_t GpLogging : 1;
|
||||
uint16_t WriteFua : 1;
|
||||
uint16_t WriteQueuedFua : 1;
|
||||
uint16_t WWN64Bit : 1;
|
||||
uint16_t URGReadStream : 1;
|
||||
uint16_t URGWriteStream : 1;
|
||||
uint16_t ReservedForTechReport : 2;
|
||||
uint16_t IdleWithUnloadFeature : 1;
|
||||
uint16_t WordValid : 2;
|
||||
} CommandSetSupport;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t SmartCommands : 1;
|
||||
uint16_t SecurityMode : 1;
|
||||
uint16_t RemovableMediaFeature : 1;
|
||||
uint16_t PowerManagement : 1;
|
||||
uint16_t Reserved1 : 1;
|
||||
uint16_t WriteCache : 1;
|
||||
uint16_t LookAhead : 1;
|
||||
uint16_t ReleaseInterrupt : 1;
|
||||
uint16_t ServiceInterrupt : 1;
|
||||
uint16_t DeviceReset : 1;
|
||||
uint16_t HostProtectedArea : 1;
|
||||
uint16_t Obsolete1 : 1;
|
||||
uint16_t WriteBuffer : 1;
|
||||
uint16_t ReadBuffer : 1;
|
||||
uint16_t Nop : 1;
|
||||
uint16_t Obsolete2 : 1;
|
||||
uint16_t DownloadMicrocode : 1;
|
||||
uint16_t DmaQueued : 1;
|
||||
uint16_t Cfa : 1;
|
||||
uint16_t AdvancedPm : 1;
|
||||
uint16_t Msn : 1;
|
||||
uint16_t PowerUpInStandby : 1;
|
||||
uint16_t ManualPowerUp : 1;
|
||||
uint16_t Reserved2 : 1;
|
||||
uint16_t SetMax : 1;
|
||||
uint16_t Acoustics : 1;
|
||||
uint16_t BigLba : 1;
|
||||
uint16_t DeviceConfigOverlay : 1;
|
||||
uint16_t FlushCache : 1;
|
||||
uint16_t FlushCacheExt : 1;
|
||||
uint16_t Resrved3 : 1;
|
||||
uint16_t Words119_120Valid : 1;
|
||||
uint16_t SmartErrorLog : 1;
|
||||
uint16_t SmartSelfTest : 1;
|
||||
uint16_t MediaSerialNumber : 1;
|
||||
uint16_t MediaCardPassThrough : 1;
|
||||
uint16_t StreamingFeature : 1;
|
||||
uint16_t GpLogging : 1;
|
||||
uint16_t WriteFua : 1;
|
||||
uint16_t WriteQueuedFua : 1;
|
||||
uint16_t WWN64Bit : 1;
|
||||
uint16_t URGReadStream : 1;
|
||||
uint16_t URGWriteStream : 1;
|
||||
uint16_t ReservedForTechReport : 2;
|
||||
uint16_t IdleWithUnloadFeature : 1;
|
||||
uint16_t Reserved4 : 2;
|
||||
} CommandSetActive;
|
||||
uint16_t UltraDMASupport : 8;
|
||||
uint16_t UltraDMAActive : 8;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t TimeRequired : 15;
|
||||
uint16_t ExtendedTimeReported : 1;
|
||||
} NormalSecurityEraseUnit;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t TimeRequired : 15;
|
||||
uint16_t ExtendedTimeReported : 1;
|
||||
} EnhancedSecurityEraseUnit;
|
||||
uint16_t CurrentAPMLevel : 8;
|
||||
uint16_t ReservedWord91 : 8;
|
||||
uint16_t MasterPasswordID;
|
||||
uint16_t HardwareResetResult;
|
||||
uint16_t CurrentAcousticValue : 8;
|
||||
uint16_t RecommendedAcousticValue : 8;
|
||||
uint16_t StreamMinRequestSize;
|
||||
uint16_t StreamingTransferTimeDMA;
|
||||
uint16_t StreamingAccessLatencyDMAPIO;
|
||||
uint32_t StreamingPerfGranularity;
|
||||
uint32_t Max48BitLBA[2];
|
||||
uint16_t StreamingTransferTime;
|
||||
uint16_t DsmCap;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t LogicalSectorsPerPhysicalSector : 4;
|
||||
uint16_t Reserved0 : 8;
|
||||
uint16_t LogicalSectorLongerThan256Words : 1;
|
||||
uint16_t MultipleLogicalSectorsPerPhysicalSector : 1;
|
||||
uint16_t Reserved1 : 2;
|
||||
} PhysicalLogicalSectorSize;
|
||||
uint16_t InterSeekDelay;
|
||||
uint16_t WorldWideName[4];
|
||||
uint16_t ReservedForWorldWideName128[4];
|
||||
uint16_t ReservedForTlcTechnicalReport;
|
||||
uint16_t WordsPerLogicalSector[2];
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t ReservedForDrqTechnicalReport : 1;
|
||||
uint16_t WriteReadVerify : 1;
|
||||
uint16_t WriteUncorrectableExt : 1;
|
||||
uint16_t ReadWriteLogDmaExt : 1;
|
||||
uint16_t DownloadMicrocodeMode3 : 1;
|
||||
uint16_t FreefallControl : 1;
|
||||
uint16_t SenseDataReporting : 1;
|
||||
uint16_t ExtendedPowerConditions : 1;
|
||||
uint16_t Reserved0 : 6;
|
||||
uint16_t WordValid : 2;
|
||||
} CommandSetSupportExt;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t ReservedForDrqTechnicalReport : 1;
|
||||
uint16_t WriteReadVerify : 1;
|
||||
uint16_t WriteUncorrectableExt : 1;
|
||||
uint16_t ReadWriteLogDmaExt : 1;
|
||||
uint16_t DownloadMicrocodeMode3 : 1;
|
||||
uint16_t FreefallControl : 1;
|
||||
uint16_t SenseDataReporting : 1;
|
||||
uint16_t ExtendedPowerConditions : 1;
|
||||
uint16_t Reserved0 : 6;
|
||||
uint16_t Reserved1 : 2;
|
||||
} CommandSetActiveExt;
|
||||
uint16_t ReservedForExpandedSupportandActive[6];
|
||||
uint16_t MsnSupport : 2;
|
||||
uint16_t ReservedWord127 : 14;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t SecuritySupported : 1;
|
||||
uint16_t SecurityEnabled : 1;
|
||||
uint16_t SecurityLocked : 1;
|
||||
uint16_t SecurityFrozen : 1;
|
||||
uint16_t SecurityCountExpired : 1;
|
||||
uint16_t EnhancedSecurityEraseSupported : 1;
|
||||
uint16_t Reserved0 : 2;
|
||||
uint16_t SecurityLevel : 1;
|
||||
uint16_t Reserved1 : 7;
|
||||
} SecurityStatus;
|
||||
uint16_t ReservedWord129[31];
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t MaximumCurrentInMA : 12;
|
||||
uint16_t CfaPowerMode1Disabled : 1;
|
||||
uint16_t CfaPowerMode1Required : 1;
|
||||
uint16_t Reserved0 : 1;
|
||||
uint16_t Word160Supported : 1;
|
||||
} CfaPowerMode1;
|
||||
uint16_t ReservedForCfaWord161[7];
|
||||
uint16_t NominalFormFactor : 4;
|
||||
uint16_t ReservedWord168 : 12;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t SupportsTrim : 1;
|
||||
uint16_t Reserved0 : 15;
|
||||
} DataSetManagementFeature;
|
||||
uint16_t AdditionalProductID[4];
|
||||
uint16_t ReservedForCfaWord174[2];
|
||||
uint16_t CurrentMediaSerialNumber[30];
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t Supported : 1;
|
||||
uint16_t Reserved0 : 1;
|
||||
uint16_t WriteSameSuported : 1;
|
||||
uint16_t ErrorRecoveryControlSupported : 1;
|
||||
uint16_t FeatureControlSuported : 1;
|
||||
uint16_t DataTablesSuported : 1;
|
||||
uint16_t Reserved1 : 6;
|
||||
uint16_t VendorSpecific : 4;
|
||||
} SCTCommandTransport;
|
||||
uint16_t ReservedWord207[2];
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t AlignmentOfLogicalWithinPhysical : 14;
|
||||
uint16_t Word209Supported : 1;
|
||||
uint16_t Reserved0 : 1;
|
||||
} BlockAlignment;
|
||||
uint16_t WriteReadVerifySectorCountMode3Only[2];
|
||||
uint16_t WriteReadVerifySectorCountMode2Only[2];
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t NVCachePowerModeEnabled : 1;
|
||||
uint16_t Reserved0 : 3;
|
||||
uint16_t NVCacheFeatureSetEnabled : 1;
|
||||
uint16_t Reserved1 : 3;
|
||||
uint16_t NVCachePowerModeVersion : 4;
|
||||
uint16_t NVCacheFeatureSetVersion : 4;
|
||||
} NVCacheCapabilities;
|
||||
uint16_t NVCacheSizeLSW;
|
||||
uint16_t NVCacheSizeMSW;
|
||||
uint16_t NominalMediaRotationRate;
|
||||
uint16_t ReservedWord218;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint8_t NVCacheEstimatedTimeToSpinUpInSeconds;
|
||||
uint8_t Reserved;
|
||||
} NVCacheOptions;
|
||||
uint16_t WriteReadVerifySectorCountMode : 8;
|
||||
uint16_t ReservedWord220 : 8;
|
||||
uint16_t ReservedWord221;
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
uint16_t MajorVersion : 12;
|
||||
uint16_t TransportType : 4;
|
||||
} TransportMajorVersion;
|
||||
uint16_t TransportMinorVersion;
|
||||
uint16_t ReservedWord224[6];
|
||||
uint32_t ExtendedNumberOfUserAddressableSectors[2];
|
||||
uint16_t MinBlocksPerDownloadMicrocodeMode03;
|
||||
uint16_t MaxBlocksPerDownloadMicrocodeMode03;
|
||||
uint16_t ReservedWord236[19];
|
||||
uint16_t Signature : 8;
|
||||
uint16_t CheckSum : 8;
|
||||
};
|
||||
|
||||
class Port
|
||||
{
|
||||
public:
|
||||
@ -167,6 +567,7 @@ public:
|
||||
HBAPort *HBAPortPtr;
|
||||
uint8_t *Buffer;
|
||||
uint8_t PortNumber;
|
||||
ATA_IDENTIFY *IdentifyData;
|
||||
|
||||
Port(PortType Type, HBAPort *PortPtr, uint8_t PortNumber)
|
||||
{
|
||||
@ -174,6 +575,8 @@ public:
|
||||
this->HBAPortPtr = PortPtr;
|
||||
this->Buffer = static_cast<uint8_t *>(AllocateMemory(1));
|
||||
MemorySet(this->Buffer, 0, PAGE_SIZE);
|
||||
this->IdentifyData = static_cast<ATA_IDENTIFY *>(AllocateMemory(1));
|
||||
MemorySet(this->IdentifyData, 0, PAGE_SIZE);
|
||||
this->PortNumber = PortNumber;
|
||||
}
|
||||
|
||||
@ -229,6 +632,8 @@ public:
|
||||
}
|
||||
this->StartCMD();
|
||||
|
||||
Identify();
|
||||
|
||||
Log("Port %d \"%x %x %x %x\" configured", PortNumber,
|
||||
HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1],
|
||||
HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]);
|
||||
@ -332,6 +737,75 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Identify()
|
||||
{
|
||||
MemorySet(this->IdentifyData, 0, sizeof(ATA_IDENTIFY));
|
||||
HBACommandHeader *CommandHeader = reinterpret_cast<HBACommandHeader *>(HBAPortPtr->CommandListBase);
|
||||
CommandHeader->CommandFISLength = sizeof(FIS_REG_H2D) / sizeof(uint32_t);
|
||||
CommandHeader->Write = 0;
|
||||
CommandHeader->PRDTLength = 1;
|
||||
|
||||
HBACommandTable *CommandTable = reinterpret_cast<HBACommandTable *>(CommandHeader->CommandTableBaseAddress);
|
||||
MemorySet(CommandTable, 0, sizeof(HBACommandTable) + (CommandHeader->PRDTLength - 1) * sizeof(HBAPRDTEntry));
|
||||
|
||||
CommandTable->PRDTEntry[0].DataBaseAddress = (uint32_t)(uint64_t)this->IdentifyData;
|
||||
CommandTable->PRDTEntry[0].DataBaseAddressUpper = (uint32_t)((uint64_t)this->IdentifyData >> 32);
|
||||
CommandTable->PRDTEntry[0].ByteCount = 511;
|
||||
CommandTable->PRDTEntry[0].InterruptOnCompletion = 1;
|
||||
|
||||
FIS_REG_H2D *CommandFIS = (FIS_REG_H2D *)(&CommandTable->CommandFIS);
|
||||
CommandFIS->FISType = FIS_TYPE_REG_H2D;
|
||||
CommandFIS->CommandControl = 1;
|
||||
CommandFIS->Command = this->AHCIPortType == PortType::SATAPI ? ATAPI_CMD_IDENTIFY_PACKET : ATA_CMD_IDENTIFY;
|
||||
|
||||
HBAPortPtr->CommandIssue = 1;
|
||||
|
||||
while (HBAPortPtr->CommandIssue)
|
||||
Yield();
|
||||
|
||||
if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES)
|
||||
{
|
||||
Log("Error reading IDENTIFY command.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto swap = [](uint16_t *data, size_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++)
|
||||
data[i] = (data[i] >> 8) | (data[i] << 8);
|
||||
};
|
||||
|
||||
char *Model = (char *)this->IdentifyData->ModelNumber;
|
||||
char ModelSwap[41];
|
||||
for (size_t i = 0; i < 40; i += 2)
|
||||
{
|
||||
ModelSwap[i] = Model[i + 1];
|
||||
ModelSwap[i + 1] = Model[i];
|
||||
}
|
||||
ModelSwap[40] = 0;
|
||||
|
||||
Log("Port %d \"%s\" identified", PortNumber,
|
||||
ModelSwap);
|
||||
Log("Port %d is %s (%d rotation rate)", PortNumber,
|
||||
IdentifyData->NominalMediaRotationRate == 1 ? "SSD" : "HDD",
|
||||
IdentifyData->NominalMediaRotationRate);
|
||||
|
||||
if (IdentifyData->Signature != 0xA5)
|
||||
{
|
||||
Log("Port %d has no validity signature.", PortNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *ptr = (uint8_t *)IdentifyData;
|
||||
uint8_t sum = 0;
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
sum += ptr[i];
|
||||
if (sum != 0)
|
||||
Log("Port %d has invalid checksum.", PortNumber);
|
||||
else
|
||||
Log("Port %d has valid checksum.", PortNumber);
|
||||
}
|
||||
};
|
||||
|
||||
Port *Ports[64];
|
||||
|
Loading…
x
Reference in New Issue
Block a user