BOOLEAN InitHW( IN PVOID DeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo ) { PACCESS_RANGE accessRange; PADAPTER_EXTENSION adaptExt; ENTER_FN(); adaptExt = (PADAPTER_EXTENSION)DeviceExtension; accessRange = &(*ConfigInfo->AccessRanges)[0]; ASSERT (FALSE == accessRange->RangeInMemory) ; RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("Port Resource [%08I64X-%08I64X]\n", accessRange->RangeStart.QuadPart, accessRange->RangeStart.QuadPart + accessRange->RangeLength)); if ( accessRange->RangeLength < IO_PORT_LENGTH) { LogError(DeviceExtension, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Wrong access range %x bytes\n", accessRange->RangeLength)); return FALSE; } adaptExt->device_base = (ULONG_PTR)StorPortGetDeviceBase(DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, accessRange->RangeStart, accessRange->RangeLength, (BOOLEAN)!accessRange->RangeInMemory); if (adaptExt->device_base == (ULONG_PTR)NULL) { LogError(DeviceExtension, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Couldn't map %x for %x bytes\n", (*ConfigInfo->AccessRanges)[0].RangeStart.LowPart, (*ConfigInfo->AccessRanges)[0].RangeLength)); return FALSE; } adaptExt->pvdev = &adaptExt->vdev; VirtIODeviceInitialize(adaptExt->pvdev, adaptExt->device_base, sizeof(VirtIODevice)); EXIT_FN(); return TRUE; }
PAHCI_MEMORY_REGISTERS GetABARAddress( _In_ PAHCI_ADAPTER_EXTENSION AdapterExtension, _In_ PPORT_CONFIGURATION_INFORMATION ConfigInfo ) /*++ Search a set of resources (I/O and memory) for an entry corresponding to an AHCI ABAR address. It assumes: AdapterExtension->AhciBaseAddress has been set Called by: AhciHwFindAdapter It performs: 1. If any resources are defined, loop over all resource entries, looking for the AHCI ABAR address. If found, return it. 2. If this point is reached, ABAR was not found. Return NULL. Affected Variables/Registers: none ReturnValue: Address of AHCI controller memory registers if found, NULL otherwise --*/ { PAHCI_MEMORY_REGISTERS abar; ULONG i; abar = NULL; // loop over resource entries if (ConfigInfo->NumberOfAccessRanges > 0) { for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++) { if ((*(ConfigInfo->AccessRanges))[i].RangeStart.QuadPart == AdapterExtension->AhciBaseAddress) { abar = (PAHCI_MEMORY_REGISTERS)StorPortGetDeviceBase(AdapterExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, (*(ConfigInfo->AccessRanges))[i].RangeStart, (*(ConfigInfo->AccessRanges))[i].RangeLength, (BOOLEAN)!(*(ConfigInfo->AccessRanges))[i].RangeInMemory); break; } } } return abar; }
static void *pci_map_address_range(void *context, int bar, size_t offset, size_t maxlen) { PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context; if (bar < PCI_TYPE0_ADDRESSES) { PVIRTIO_BAR pBar = &adaptExt->pci_bars[bar]; if (pBar->pBase == NULL) { pBar->pBase = StorPortGetDeviceBase( adaptExt, PCIBus, adaptExt->system_io_bus_number, pBar->BasePA, pBar->uLength, !!pBar->bPortSpace); } if (pBar->pBase != NULL && offset < pBar->uLength) { return (PUCHAR)pBar->pBase + offset; } } return NULL; }
PAHCI_MEMORY_REGISTERS GetABARAddress( _In_ PAHCI_ADAPTER_EXTENSION AdapterExtension, _In_ PPORT_CONFIGURATION_INFORMATION ConfigInfo ) /*++ Search a set of resources (I/O and memory) for an entry corresponding to an AHCI ABAR address. It assumes: AdapterExtension->AhciBaseAddress has been set Called by: AhciHwFindAdapter It performs: 1. If any resources are defined, loop over all resource entries, looking for the AHCI ABAR address. If found, return it. 2. If this point is reached, ABAR was not found. Return NULL. Affected Variables/Registers: none ReturnValue: Address of AHCI controller memory registers if found, NULL otherwise --*/ { PAHCI_MEMORY_REGISTERS abar; ULONG i; abar = NULL; // loop over resource entries if (ConfigInfo->NumberOfAccessRanges > 0) { for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++) { #if defined (_ARM_) || defined (_ARM64_) if ((*(ConfigInfo->AccessRanges))[i].RangeStart.QuadPart != 0) { #else if ((*(ConfigInfo->AccessRanges))[i].RangeStart.QuadPart == AdapterExtension->AhciBaseAddress) { #endif abar = (PAHCI_MEMORY_REGISTERS)StorPortGetDeviceBase(AdapterExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, (*(ConfigInfo->AccessRanges))[i].RangeStart, (*(ConfigInfo->AccessRanges))[i].RangeLength, (BOOLEAN)!(*(ConfigInfo->AccessRanges))[i].RangeInMemory); break; } } } return abar; } VOID RecordExecutionHistory( PAHCI_CHANNEL_EXTENSION ChannelExtension, ULONG Function ) /*++ Takes a snapshot of the AHCI registers for debugging It assumes: nothing Called by: Everything It performs: (overview) 1 Select the next available index 2 Take the snapshot (details) 1.1 Select the next available index 2.1 Copy over the Channel Extension header 2.2 Copy over the AHCI registers Affected Variables/Registers: none Return Value: none --*/ { int i; //1.1 Select the next available index // Actually, ExecutionHistoryNextAvailableIndex is used for current index. if (ChannelExtension->ExecutionHistoryNextAvailableIndex >= (MAX_EXECUTION_HISTORY_ENTRY_COUNT - 1)) { ChannelExtension->ExecutionHistoryNextAvailableIndex = 0; } else { ChannelExtension->ExecutionHistoryNextAvailableIndex++; } //2.1 Copy over the Channel Extension header ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Function = Function; if(ChannelExtension->AdapterExtension->IS) { // Keep using the old field "IS" to save StateFlags information. StorPortCopyMemory(&ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].IS, &ChannelExtension->StateFlags, sizeof(ULONG)); } else { ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].IS = (ULONG)~0; } StorPortCopyMemory(&ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].SlotManager, &ChannelExtension->SlotManager, sizeof(SLOT_MANAGER)); //2.2 Copy over the AHCI registers if(ChannelExtension->Px) { ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[0] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CLB.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[1] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CLBU); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[2] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->FB.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[3] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->FBU); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[4] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->IS.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[5] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->IE.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[6] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CMD.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[7] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->DW7_Reserved); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[8] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->TFD.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[9] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SIG.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[10] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SSTS.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[11] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SCTL.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[12] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SERR.AsUlong); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[13] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SACT); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[14] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CI); ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[15] = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SNTF.AsUlong); } else { for(i=0; i<0x10; i++) { ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Px[i] = (ULONG)~0; } } }