mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 10:14:44 +00:00
AhciFindAdapter Completed
- Added AhciZeroMemory - Added AhciAllocateResourceForAdapter - Added AhciPortInitialize Compile Status : OK svn path=/branches/GSoC_2016/AHCI/; revision=71506
This commit is contained in:
parent
c62ab931ac
commit
f7890a371a
2 changed files with 305 additions and 21 deletions
|
@ -11,6 +11,133 @@ BOOLEAN AhciAdapterReset(
|
|||
__in PAHCI_ADAPTER_EXTENSION adapterExtension
|
||||
);
|
||||
|
||||
VOID AhciZeroMemory(
|
||||
__in PCHAR buffer,
|
||||
__in ULONG bufferSize
|
||||
);
|
||||
|
||||
/**
|
||||
* @name AhciPortInitialize
|
||||
* @implemented
|
||||
*
|
||||
* Initialize port by setting up PxCLB & PxFB Registers
|
||||
*
|
||||
* @param portExtension
|
||||
*
|
||||
* @return
|
||||
* Return true if intialization was successful
|
||||
*/
|
||||
BOOLEAN AhciPortInitialize(
|
||||
__in PAHCI_PORT_EXTENSION portExtension
|
||||
)
|
||||
{
|
||||
ULONG mappedLength;
|
||||
PAHCI_MEMORY_REGISTERS abar;
|
||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||
STOR_PHYSICAL_ADDRESS commandListPhysical, receivedFISPhysical;
|
||||
|
||||
adapterExtension = portExtension->AdapterExtension;
|
||||
abar = adapterExtension->ABAR_Address;
|
||||
portExtension->Port = &abar->PortList[portExtension->PortNumber];
|
||||
|
||||
commandListPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->CommandList, &mappedLength);
|
||||
if (mappedLength == 0 || (commandListPhysical.LowPart % 1024) != 0)
|
||||
return FALSE;
|
||||
|
||||
receivedFISPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->ReceivedFIS, &mappedLength);
|
||||
if (mappedLength == 0 || (commandListPhysical.LowPart % 256) != 0)
|
||||
return FALSE;
|
||||
|
||||
// 10.1.2 For each implemented port, system software shall allocate memory for and program:
|
||||
// PxCLB and PxCLBU (if CAP.S64A is set to ‘1’)
|
||||
// PxFB and PxFBU (if CAP.S64A is set to ‘1’)
|
||||
//Note: Assuming 32bit support only
|
||||
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->CLB, commandListPhysical.LowPart);
|
||||
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->FB, receivedFISPhysical.LowPart);
|
||||
|
||||
return TRUE;
|
||||
}// -- AhciPortInitialize();
|
||||
|
||||
/**
|
||||
* @name AhciAllocateResourceForAdapter
|
||||
* @implemented
|
||||
*
|
||||
* Allocate memory from poll for required pointers
|
||||
*
|
||||
* @param adapterExtension
|
||||
* @param ConfigInfo
|
||||
*
|
||||
* @return
|
||||
* return TRUE if allocation was successful
|
||||
*/
|
||||
BOOLEAN AhciAllocateResourceForAdapter(
|
||||
__in PAHCI_ADAPTER_EXTENSION adapterExtension,
|
||||
__in PPORT_CONFIGURATION_INFORMATION ConfigInfo
|
||||
)
|
||||
{
|
||||
PVOID portsExtension = NULL;
|
||||
PCHAR nonCachedExtension;
|
||||
ULONG portCount, portImplemented, status, index, NCS, AlignedNCS, nonCachedExtensionSize, currentCount;
|
||||
|
||||
// 3.1.1 NCS = CAP[12:08] -> Align
|
||||
NCS = (adapterExtension->CAP & 0xF00) >> 8;
|
||||
AlignedNCS = ((NCS/8) + 1) * 8;
|
||||
|
||||
// get port count -- Number of set bits in `adapterExtension->PortImplemented`
|
||||
portCount = 0;
|
||||
portImplemented = adapterExtension->PortImplemented;
|
||||
while(portImplemented > 0)
|
||||
{
|
||||
portCount++;
|
||||
portImplemented &= (portImplemented-1);
|
||||
}
|
||||
|
||||
nonCachedExtensionSize = sizeof(AHCI_COMMAND_HEADER) * AlignedNCS + //should be 1K aligned
|
||||
sizeof(AHCI_RECEIVED_FIS);
|
||||
//align nonCachedExtensionSize to 1K
|
||||
nonCachedExtensionSize = (((nonCachedExtensionSize - 1) / 0x400) + 1) * 0x400;
|
||||
nonCachedExtensionSize *= portCount;
|
||||
|
||||
adapterExtension->NonCachedExtension = StorPortGetUncachedExtension(adapterExtension, ConfigInfo, nonCachedExtensionSize);
|
||||
if (adapterExtension->NonCachedExtension == NULL)
|
||||
return FALSE;
|
||||
|
||||
nonCachedExtension = (PCHAR)adapterExtension->NonCachedExtension;
|
||||
|
||||
AhciZeroMemory(nonCachedExtension, nonCachedExtensionSize);
|
||||
|
||||
|
||||
// allocate memory for port extension
|
||||
status = StorPortAllocatePool(
|
||||
adapterExtension,
|
||||
portCount * sizeof(AHCI_PORT_EXTENSION),
|
||||
AHCI_POOL_TAG,
|
||||
(PVOID*)&portsExtension);
|
||||
|
||||
if (status != STOR_STATUS_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
AhciZeroMemory((PCHAR)portsExtension, portCount * sizeof(AHCI_PORT_EXTENSION));
|
||||
|
||||
nonCachedExtensionSize /= portCount;
|
||||
currentCount = 0;
|
||||
for (index = 0; index < 32; index++)
|
||||
{
|
||||
if ((adapterExtension->PortImplemented & (1<<index)) != 0)
|
||||
{
|
||||
adapterExtension->PortExtension[index] = (PAHCI_PORT_EXTENSION)((PCHAR)portsExtension + sizeof(AHCI_PORT_EXTENSION) * currentCount);
|
||||
|
||||
adapterExtension->PortExtension[index]->PortNumber = index;
|
||||
adapterExtension->PortExtension[index]->AdapterExtension = adapterExtension;
|
||||
adapterExtension->PortExtension[index]->CommandList = (PAHCI_COMMAND_HEADER)(nonCachedExtension + (currentCount*nonCachedExtensionSize));
|
||||
adapterExtension->PortExtension[index]->ReceivedFIS = (PAHCI_RECEIVED_FIS)((PCHAR)adapterExtension->PortExtension[index]->CommandList + sizeof(AHCI_COMMAND_HEADER) * AlignedNCS);
|
||||
currentCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}// -- AhciAllocateResourceForAdapter();
|
||||
|
||||
/**
|
||||
* @name AhciFindAdapter
|
||||
* @implemented
|
||||
|
@ -53,6 +180,7 @@ ULONG AhciFindAdapter(
|
|||
)
|
||||
{
|
||||
ULONG ghc;
|
||||
ULONG index;
|
||||
ULONG portCount, portImplemented;
|
||||
ULONG pci_cfg_len;
|
||||
UCHAR pci_cfg_buf[0x30];
|
||||
|
@ -88,18 +216,17 @@ ULONG AhciFindAdapter(
|
|||
abar = NULL;
|
||||
if (ConfigInfo->NumberOfAccessRanges > 0)
|
||||
{
|
||||
ULONG accessIndex;
|
||||
for (accessIndex = 0; accessIndex < ConfigInfo->NumberOfAccessRanges; accessIndex++)
|
||||
for (index = 0; index < ConfigInfo->NumberOfAccessRanges; index++)
|
||||
{
|
||||
if ((*(ConfigInfo->AccessRanges))[accessIndex].RangeStart.QuadPart == adapterExtension->AhciBaseAddress)
|
||||
if ((*(ConfigInfo->AccessRanges))[index].RangeStart.QuadPart == adapterExtension->AhciBaseAddress)
|
||||
{
|
||||
abar = (PAHCI_MEMORY_REGISTERS)StorPortGetDeviceBase(
|
||||
adapterExtension,
|
||||
ConfigInfo->AdapterInterfaceType,
|
||||
ConfigInfo->SystemIoBusNumber,
|
||||
(*(ConfigInfo->AccessRanges))[accessIndex].RangeStart,
|
||||
(*(ConfigInfo->AccessRanges))[accessIndex].RangeLength,
|
||||
(BOOLEAN)!(*(ConfigInfo->AccessRanges))[accessIndex].RangeInMemory);
|
||||
(*(ConfigInfo->AccessRanges))[index].RangeStart,
|
||||
(*(ConfigInfo->AccessRanges))[index].RangeLength,
|
||||
(BOOLEAN)!(*(ConfigInfo->AccessRanges))[index].RangeInMemory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +242,7 @@ ULONG AhciFindAdapter(
|
|||
|
||||
// 10.1.2
|
||||
// 1. Indicate that system software is AHCI aware by setting GHC.AE to ‘1’.
|
||||
// 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
|
||||
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
|
||||
// AE := Highest Significant bit of GHC
|
||||
if ((ghc & (0x1<<31)) == 1)//Hmm, controller was already in power state
|
||||
|
@ -134,15 +262,6 @@ ULONG AhciFindAdapter(
|
|||
if (adapterExtension->PortImplemented == 0)
|
||||
return SP_RETURN_ERROR;
|
||||
|
||||
// get port count -- Number of set bits in `adapterExtension->PortImplemented`
|
||||
portCount = 0;
|
||||
portImplemented = adapterExtension->PortImplemented;
|
||||
while(portImplemented > 0)
|
||||
{
|
||||
portCount++;
|
||||
portImplemented &= (portImplemented - 1);// i love playing with bits :D
|
||||
}
|
||||
|
||||
ConfigInfo->MaximumTransferLength = 128 * 1024;//128 KB
|
||||
ConfigInfo->NumberOfPhysicalBreaks = 0x21;
|
||||
ConfigInfo->MaximumNumberOfTargets = 1;
|
||||
|
@ -152,12 +271,20 @@ ULONG AhciFindAdapter(
|
|||
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
|
||||
ConfigInfo->ScatterGather = TRUE;
|
||||
|
||||
// allocate necessary resource for each port
|
||||
if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo))
|
||||
return SP_RETURN_ERROR;
|
||||
|
||||
for (index = 0; index < 32; index++)
|
||||
{
|
||||
if ((adapterExtension->PortImplemented & (1<<index)) != 0)
|
||||
AhciPortInitialize(adapterExtension->PortExtension[index]);
|
||||
}
|
||||
|
||||
// Turn IE -- Interrupt Enabled
|
||||
ghc |= 0x2;
|
||||
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||
|
||||
|
||||
|
||||
return SP_RETURN_FOUND;
|
||||
}// -- AhciFindAdapter();
|
||||
|
||||
|
@ -184,8 +311,7 @@ ULONG DriverEntry(
|
|||
DebugPrint("Storahci -> DriverEntry()\n");
|
||||
|
||||
// initialize the hardware data structure
|
||||
for (i = 0; i < sizeof(HW_INITIALIZATION_DATA); i++)
|
||||
((PUCHAR)&hwInitializationData)[i] = 0;
|
||||
AhciZeroMemory((PCHAR)&hwInitializationData, sizeof(HW_INITIALIZATION_DATA));
|
||||
|
||||
// set size of hardware initialization structure
|
||||
hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
|
||||
|
@ -261,3 +387,21 @@ BOOLEAN AhciAdapterReset(
|
|||
|
||||
return TRUE;
|
||||
}// -- AhciAdapterReset();
|
||||
|
||||
/**
|
||||
* @name AhciZeroMemory
|
||||
* @implemented
|
||||
*
|
||||
* Clear buffer by filling zeros
|
||||
*
|
||||
* @param buffer
|
||||
*/
|
||||
VOID AhciZeroMemory(
|
||||
__in PCHAR buffer,
|
||||
__in ULONG bufferSize
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
for (i = 0; i < bufferSize; i++)
|
||||
buffer[i] = 0;
|
||||
}// -- AhciZeroMemory();
|
||||
|
|
|
@ -1,6 +1,131 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GNU GPLv2 only as published by the Free Software Foundation
|
||||
* PURPOSE: To Implement AHCI Miniport driver targeting storport NT 5.2
|
||||
* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
|
||||
*/
|
||||
|
||||
#include "miniport.h"
|
||||
#include "storport.h"
|
||||
|
||||
#define AHCI_POOL_TAG 'ahci'
|
||||
|
||||
typedef struct _AHCI_FIS_DMA_SETUP
|
||||
{
|
||||
ULONG ULONG0_1; // FIS_TYPE_DMA_SETUP
|
||||
// Port multiplier
|
||||
// Reserved
|
||||
// Data transfer direction, 1 - device to host
|
||||
// Interrupt bit
|
||||
// Auto-activate. Specifies if DMA Activate FIS is needed
|
||||
UCHAR Reserved[2]; // Reserved
|
||||
ULONG DmaBufferLow; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.
|
||||
ULONG DmaBufferHigh;
|
||||
ULONG Reserved2; //More reserved
|
||||
ULONG DmaBufferOffset; //Byte offset into buffer. First 2 bits must be 0
|
||||
ULONG TranferCount; //Number of bytes to transfer. Bit 0 must be 0
|
||||
ULONG Reserved3; //Reserved
|
||||
} AHCI_FIS_DMA_SETUP;
|
||||
|
||||
typedef struct _AHCI_PIO_SETUP_FIS
|
||||
{
|
||||
UCHAR FisType; //0x5F
|
||||
UCHAR Reserved1 :5;
|
||||
UCHAR D :1; // 1 is write (device to host)
|
||||
UCHAR I :1;
|
||||
UCHAR Reserved2 :1;
|
||||
UCHAR Status;
|
||||
UCHAR Error;
|
||||
|
||||
UCHAR SectorNumber;
|
||||
UCHAR CylLow;
|
||||
UCHAR CylHigh;
|
||||
UCHAR Dev_Head;
|
||||
|
||||
UCHAR SectorNumb_Exp;
|
||||
UCHAR CylLow_Exp;
|
||||
UCHAR CylHigh_Exp;
|
||||
UCHAR Reserved3;
|
||||
|
||||
UCHAR SectorCount;
|
||||
UCHAR SectorCount_Exp;
|
||||
UCHAR Reserved4;
|
||||
UCHAR E_Status;
|
||||
|
||||
USHORT TransferCount;
|
||||
UCHAR Reserved5[2];
|
||||
|
||||
} AHCI_PIO_SETUP_FIS;
|
||||
|
||||
typedef struct _AHCI_D2H_REGISTER_FIS
|
||||
{
|
||||
UCHAR FisType; // 0x34
|
||||
UCHAR Reserved1 :6;
|
||||
UCHAR I:1;
|
||||
UCHAR Reserved2 :1;
|
||||
UCHAR Status;
|
||||
UCHAR Error;
|
||||
|
||||
UCHAR SectorNumber;
|
||||
UCHAR CylLow;
|
||||
UCHAR CylHigh;
|
||||
UCHAR Dev_Head;
|
||||
|
||||
UCHAR SectorNum_Exp;
|
||||
UCHAR CylLow_Exp;
|
||||
UCHAR CylHigh_Exp;
|
||||
UCHAR Reserved;
|
||||
|
||||
UCHAR SectorCount;
|
||||
UCHAR SectorCount_Exp;
|
||||
UCHAR Reserved3[2];
|
||||
|
||||
UCHAR Reserved4[4];
|
||||
} AHCI_D2H_REGISTER_FIS;
|
||||
|
||||
typedef struct _AHCI_SET_DEVICE_BITS_FIS {
|
||||
|
||||
UCHAR FisType; //0xA1
|
||||
|
||||
UCHAR PMPort: 4;
|
||||
UCHAR Reserved1 :2;
|
||||
UCHAR I :1;
|
||||
UCHAR N :1;
|
||||
|
||||
UCHAR Status_Lo :3;
|
||||
UCHAR Reserved2 :1;
|
||||
UCHAR Status_Hi :3;
|
||||
UCHAR Reserved3 :1;
|
||||
|
||||
UCHAR Error;
|
||||
|
||||
UCHAR Reserved5[4];
|
||||
} AHCI_SET_DEVICE_BITS_FIS;
|
||||
|
||||
// 4.2.2
|
||||
typedef struct _AHCI_COMMAND_HEADER
|
||||
{
|
||||
ULONG HEADER_DESCRIPTION; // DW 0
|
||||
ULONG PRDBC; // DW 1
|
||||
ULONG CTBA0; // DW 2
|
||||
ULONG CTBA_U0; // DW 3
|
||||
ULONG Reserved[4]; // DW 4-7
|
||||
} AHCI_COMMAND_HEADER, *PAHCI_COMMAND_HEADER;
|
||||
|
||||
// Received FIS
|
||||
typedef struct _AHCI_RECEIVED_FIS
|
||||
{
|
||||
AHCI_FIS_DMA_SETUP DmaSetupFIS; // 0x00 -- DMA Setup FIS
|
||||
ULONG pad0; // 4 BYTE padding
|
||||
AHCI_PIO_SETUP_FIS PioSetupFIS; // 0x20 -- PIO Setup FIS
|
||||
ULONG pad1[3]; // 12 BYTE padding
|
||||
AHCI_D2H_REGISTER_FIS RegisterFIS; // 0x40 -- Register – Device to Host FIS
|
||||
ULONG pad2; // 4 BYTE padding
|
||||
AHCI_SET_DEVICE_BITS_FIS SetDeviceFIS; // 0x58 -- Set Device Bit FIS
|
||||
ULONG UnknowFIS[16]; // 0x60 -- Unknown FIS
|
||||
ULONG Reserved[24]; // 0xA0 -- Reserved
|
||||
} AHCI_RECEIVED_FIS, *PAHCI_RECEIVED_FIS;
|
||||
|
||||
typedef struct _AHCI_PORT
|
||||
{
|
||||
ULONG CLB; // 0x00, command list base address, 1K-byte aligned
|
||||
|
@ -22,7 +147,7 @@ typedef struct _AHCI_PORT
|
|||
ULONG FBS; // 0x40, FIS-based switch control
|
||||
ULONG RSV1[11]; // 0x44 ~ 0x6F, Reserved
|
||||
ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific
|
||||
} AHCI_PORT;
|
||||
} AHCI_PORT, *PAHCI_PORT;
|
||||
|
||||
typedef struct _AHCI_MEMORY_REGISTERS
|
||||
{
|
||||
|
@ -49,6 +174,17 @@ typedef struct _AHCI_MEMORY_REGISTERS
|
|||
|
||||
} AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
|
||||
|
||||
struct _AHCI_ADAPTER_EXTENSION;
|
||||
|
||||
typedef struct _AHCI_PORT_EXTENSION
|
||||
{
|
||||
ULONG PortNumber;
|
||||
struct _AHCI_ADAPTER_EXTENSION* AdapterExtension;
|
||||
PAHCI_COMMAND_HEADER CommandList;
|
||||
PAHCI_RECEIVED_FIS ReceivedFIS;
|
||||
PAHCI_PORT Port;
|
||||
} AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION;
|
||||
|
||||
typedef struct _AHCI_ADAPTER_EXTENSION
|
||||
{
|
||||
ULONG AdapterNumber;
|
||||
|
@ -65,7 +201,11 @@ typedef struct _AHCI_ADAPTER_EXTENSION
|
|||
ULONG Version;
|
||||
ULONG CAP;
|
||||
ULONG CAP2;
|
||||
|
||||
PVOID NonCachedExtension;
|
||||
|
||||
PAHCI_MEMORY_REGISTERS ABAR_Address;
|
||||
PAHCI_PORT_EXTENSION PortExtension[32];
|
||||
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
|
||||
|
||||
typedef struct _AHCI_SRB_EXTENSION
|
||||
|
|
Loading…
Reference in a new issue