AhciFindAdapter Completed

- Added AhciZeroMemory
- Added AhciAllocateResourceForAdapter
- Added AhciPortInitialize

Compile Status : OK

svn path=/branches/GSoC_2016/AHCI/; revision=71506
This commit is contained in:
Aman Priyadarshi 2016-06-03 15:54:21 +00:00
parent c62ab931ac
commit f7890a371a
2 changed files with 305 additions and 21 deletions

View file

@ -8,9 +8,136 @@
#include "storahci.h"
BOOLEAN AhciAdapterReset(
__in PAHCI_ADAPTER_EXTENSION adapterExtension
__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();

View file

@ -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