- Reimplement HalpAssignPCISlotResources() (based on the old implementation, just changing to the new way of reading/writing PCI config space, formatting and other misc changes).

svn path=/trunk/; revision=27330
This commit is contained in:
Aleksey Bragin 2007-06-29 17:20:26 +00:00
parent 129a800f3f
commit 017976049f

View file

@ -485,6 +485,14 @@ HalpReleasePciDeviceForDebugging(IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
return STATUS_NOT_IMPLEMENTED;
}
static ULONG STDCALL
PciSize(ULONG Base, ULONG Mask)
{
ULONG Size = Mask & Base; /* Find the significant bits */
Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */
return Size;
}
NTSTATUS
NTAPI
HalpAssignPCISlotResources(IN PBUS_HANDLER BusHandler,
@ -494,10 +502,126 @@ HalpAssignPCISlotResources(IN PBUS_HANDLER BusHandler,
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
IN ULONG Slot,
IN OUT PCM_RESOURCE_LIST *pAllocatedResources)
IN OUT PCM_RESOURCE_LIST *AllocatedResources)
{
KEBUGCHECK(0);
return STATUS_SUCCESS;
PCI_COMMON_CONFIG PciConfig;
SIZE_T Address;
SIZE_T ResourceCount;
ULONG Size[PCI_TYPE0_ADDRESSES];
NTSTATUS Status = STATUS_SUCCESS;
UCHAR Offset;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
PCI_SLOT_NUMBER SlotNumber;
ULONG WriteBuffer;
/* FIXME: Should handle 64-bit addresses */
/* Read configuration data */
SlotNumber.u.AsULONG = Slot;
HalpReadPCIConfig(BusHandler, SlotNumber, &PciConfig, 0, PCI_COMMON_HDR_LENGTH);
/* Check if we read it correctly */
if (PciConfig.VendorID == PCI_INVALID_VENDORID)
return STATUS_NO_SUCH_DEVICE;
/* Read the PCI configuration space for the device and store base address and
size information in temporary storage. Count the number of valid base addresses */
ResourceCount = 0;
for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
{
if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address])
PciConfig.u.type0.BaseAddresses[Address] = 0;
/* Memory resource */
if (0 != PciConfig.u.type0.BaseAddresses[Address])
{
ResourceCount++;
Offset = FIELD_OFFSET(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
/* Write 0xFFFFFFFF there */
WriteBuffer = 0xffffffff;
HalpWritePCIConfig(BusHandler, SlotNumber, &WriteBuffer, Offset, sizeof(ULONG));
/* Read that figure back from the config space */
HalpReadPCIConfig(BusHandler, SlotNumber, &Size[Address], Offset, sizeof(ULONG));
/* Write back initial value */
HalpWritePCIConfig(BusHandler, SlotNumber, &PciConfig.u.type0.BaseAddresses[Address], Offset, sizeof(ULONG));
}
}
/* Interrupt resource */
if (0 != PciConfig.u.type0.InterruptLine)
ResourceCount++;
/* Allocate output buffer and initialize */
*AllocatedResources = ExAllocatePoolWithTag(
PagedPool,
sizeof(CM_RESOURCE_LIST) +
(ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
TAG('H','a','l',' '));
if (NULL == *AllocatedResources)
return STATUS_NO_MEMORY;
(*AllocatedResources)->Count = 1;
(*AllocatedResources)->List[0].InterfaceType = PCIBus;
(*AllocatedResources)->List[0].BusNumber = BusHandler->BusNumber;
(*AllocatedResources)->List[0].PartialResourceList.Version = 1;
(*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
(*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount;
Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
/* Store configuration information */
for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
{
if (0 != PciConfig.u.type0.BaseAddresses[Address])
{
if (/*PCI_BASE_ADDRESS_SPACE_MEMORY*/ 0 ==
(PciConfig.u.type0.BaseAddresses[Address] & 0x1))
{
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE; /* FIXME Just a guess */
Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_ADDRESS_MEMORY_ADDRESS_MASK);
Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_ADDRESS_MEMORY_ADDRESS_MASK);
}
else if (PCI_ADDRESS_IO_SPACE ==
(PciConfig.u.type0.BaseAddresses[Address] & 0x1))
{
Descriptor->Type = CmResourceTypePort;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
Descriptor->Flags = CM_RESOURCE_PORT_IO; /* FIXME Just a guess */
Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_ADDRESS_IO_ADDRESS_MASK;
Descriptor->u.Port.Length = PciSize(Size[Address], PCI_ADDRESS_IO_ADDRESS_MASK & 0xffff);
}
else
{
ASSERT(FALSE);
return STATUS_UNSUCCESSFUL;
}
Descriptor++;
}
}
if (0 != PciConfig.u.type0.InterruptLine)
{
Descriptor->Type = CmResourceTypeInterrupt;
Descriptor->ShareDisposition = CmResourceShareShared; /* FIXME Just a guess */
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; /* FIXME Just a guess */
Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
Descriptor++;
}
ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount);
/* FIXME: Should store the resources in the registry resource map */
return Status;
}
ULONG