Author: apriyadarshi
Date: Fri Jun 3 15:54:21 2016
New Revision: 71506
URL:
http://svn.reactos.org/svn/reactos?rev=71506&view=rev
Log:
AhciFindAdapter Completed
- Added AhciZeroMemory
- Added AhciAllocateResourceForAdapter
- Added AhciPortInitialize
Compile Status : OK
Modified:
branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c
branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] Fri Jun 3
15:54:21 2016
@@ -8,8 +8,135 @@
#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
@@ -53,6 +180,7 @@
)
{
ULONG ghc;
+ ULONG index;
ULONG portCount, portImplemented;
ULONG pci_cfg_len;
UCHAR pci_cfg_buf[0x30];
@@ -88,18 +216,17 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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();
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] Fri Jun 3
15:54:21 2016
@@ -1,5 +1,130 @@
+/*
+ * 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(a)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
{
@@ -22,7 +147,7 @@
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 @@
} 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 @@
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