mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[PCI][HALX86] Support PCI debugging devices
Also optimize the PCI bus scanning CORE-17360
This commit is contained in:
parent
216d69c59e
commit
734cd5e842
9 changed files with 880 additions and 84 deletions
|
@ -49,6 +49,30 @@ FdoLocateChildDevice(
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
PciIsDebuggingDevice(
|
||||
_In_ ULONG Bus,
|
||||
_In_ PCI_SLOT_NUMBER SlotNumber)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (!HasDebuggingDevice)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(PciDebuggingDevice); ++i)
|
||||
{
|
||||
if (PciDebuggingDevice[i].InUse &&
|
||||
PciDebuggingDevice[i].BusNumber == Bus &&
|
||||
PciDebuggingDevice[i].DeviceNumber == SlotNumber.u.bits.DeviceNumber &&
|
||||
PciDebuggingDevice[i].FunctionNumber == SlotNumber.u.bits.FunctionNumber)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
FdoEnumerateDevices(
|
||||
|
@ -92,7 +116,9 @@ FdoEnumerateDevices(
|
|||
&PciConfig,
|
||||
PCI_COMMON_HDR_LENGTH);
|
||||
DPRINT("Size %lu\n", Size);
|
||||
if (Size < PCI_COMMON_HDR_LENGTH)
|
||||
if (Size != PCI_COMMON_HDR_LENGTH ||
|
||||
PciConfig.VendorID == PCI_INVALID_VENDORID ||
|
||||
PciConfig.VendorID == 0)
|
||||
{
|
||||
if (FunctionNumber == 0)
|
||||
{
|
||||
|
@ -111,12 +137,6 @@ FdoEnumerateDevices(
|
|||
PciConfig.VendorID,
|
||||
PciConfig.DeviceID);
|
||||
|
||||
if (PciConfig.VendorID == 0 && PciConfig.DeviceID == 0)
|
||||
{
|
||||
DPRINT("Filter out devices with null vendor and device ID\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -132,6 +152,27 @@ FdoEnumerateDevices(
|
|||
|
||||
Device->BusNumber = DeviceExtension->BusNumber;
|
||||
|
||||
if (PciIsDebuggingDevice(DeviceExtension->BusNumber, SlotNumber))
|
||||
{
|
||||
Device->IsDebuggingDevice = TRUE;
|
||||
|
||||
/*
|
||||
* ReactOS-specific: apply a hack
|
||||
* to prevent driver installation for the debugging device.
|
||||
* NOTE: Nothing to do for IEEE 1394 devices; NT5.1 and NT5.2
|
||||
* support IEEE 1394 debugging.
|
||||
*
|
||||
* FIXME: We should set the device problem code
|
||||
* CM_PROB_USED_BY_DEBUGGER instead.
|
||||
*/
|
||||
if (PciConfig.BaseClass != PCI_CLASS_SERIAL_BUS_CTLR ||
|
||||
PciConfig.SubClass != PCI_SUBCLASS_SB_IEEE1394)
|
||||
{
|
||||
PciConfig.VendorID = 0xDEAD;
|
||||
PciConfig.DeviceID = 0xBEEF;
|
||||
}
|
||||
}
|
||||
|
||||
RtlCopyMemory(&Device->SlotNumber,
|
||||
&SlotNumber,
|
||||
sizeof(PCI_SLOT_NUMBER));
|
||||
|
|
|
@ -29,6 +29,8 @@ static NTSTATUS NTAPI PciPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
/*** PUBLIC ******************************************************************/
|
||||
|
||||
PPCI_DRIVER_EXTENSION DriverExtension = NULL;
|
||||
BOOLEAN HasDebuggingDevice = FALSE;
|
||||
PCI_TYPE1_CFG_CYCLE_BITS PciDebuggingDevice[2] = {0};
|
||||
|
||||
/*** PRIVATE *****************************************************************/
|
||||
|
||||
|
@ -194,6 +196,54 @@ PciUnload(
|
|||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("INIT")
|
||||
VOID
|
||||
PciLocateKdDevices(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
WCHAR KeyNameBuffer[16];
|
||||
ULONG BusNumber, SlotNumber;
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
||||
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].Name = L"Bus";
|
||||
QueryTable[0].EntryContext = &BusNumber;
|
||||
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[1].Name = L"Slot";
|
||||
QueryTable[1].EntryContext = &SlotNumber;
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(PciDebuggingDevice); ++i)
|
||||
{
|
||||
PCI_SLOT_NUMBER PciSlot;
|
||||
|
||||
RtlStringCbPrintfW(KeyNameBuffer, sizeof(KeyNameBuffer), L"PCI\\Debug\\%d", i);
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
||||
KeyNameBuffer,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return;
|
||||
|
||||
HasDebuggingDevice = TRUE;
|
||||
|
||||
PciSlot.u.AsULONG = SlotNumber;
|
||||
PciDebuggingDevice[i].DeviceNumber = PciSlot.u.bits.DeviceNumber;
|
||||
PciDebuggingDevice[i].FunctionNumber = PciSlot.u.bits.FunctionNumber;
|
||||
PciDebuggingDevice[i].BusNumber = BusNumber;
|
||||
PciDebuggingDevice[i].InUse = TRUE;
|
||||
|
||||
DPRINT1("PCI debugging device %02x:%02x.%x\n",
|
||||
BusNumber,
|
||||
PciSlot.u.bits.DeviceNumber,
|
||||
PciSlot.u.bits.FunctionNumber);
|
||||
}
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -224,6 +274,8 @@ DriverEntry(
|
|||
InitializeListHead(&DriverExtension->BusListHead);
|
||||
KeInitializeSpinLock(&DriverExtension->BusListLock);
|
||||
|
||||
PciLocateKdDevices();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <ntifs.h>
|
||||
#include <cmreslist.h>
|
||||
#include <ntstrsafe.h>
|
||||
|
||||
#define TAG_PCI '0ICP'
|
||||
|
||||
|
@ -24,6 +25,8 @@ typedef struct _PCI_DEVICE
|
|||
BOOLEAN EnableIoSpace;
|
||||
// Enable bus master
|
||||
BOOLEAN EnableBusMaster;
|
||||
// Whether the device is owned by the KD
|
||||
BOOLEAN IsDebuggingDevice;
|
||||
} PCI_DEVICE, *PPCI_DEVICE;
|
||||
|
||||
|
||||
|
@ -105,12 +108,28 @@ typedef struct _PCI_DRIVER_EXTENSION
|
|||
KSPIN_LOCK BusListLock;
|
||||
} PCI_DRIVER_EXTENSION, *PPCI_DRIVER_EXTENSION;
|
||||
|
||||
typedef union _PCI_TYPE1_CFG_CYCLE_BITS
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG InUse:2;
|
||||
ULONG RegisterNumber:6;
|
||||
ULONG FunctionNumber:3;
|
||||
ULONG DeviceNumber:5;
|
||||
ULONG BusNumber:8;
|
||||
ULONG Reserved2:8;
|
||||
};
|
||||
ULONG AsULONG;
|
||||
} PCI_TYPE1_CFG_CYCLE_BITS, *PPCI_TYPE1_CFG_CYCLE_BITS;
|
||||
|
||||
/* We need a global variable to get the driver extension,
|
||||
* because at least InterfacePciDevicePresent has no
|
||||
* other way to get it... */
|
||||
extern PPCI_DRIVER_EXTENSION DriverExtension;
|
||||
|
||||
extern BOOLEAN HasDebuggingDevice;
|
||||
extern PCI_TYPE1_CFG_CYCLE_BITS PciDebuggingDevice[2];
|
||||
|
||||
/* fdo.c */
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -6,6 +6,7 @@ list(APPEND HAL_GENERIC_SOURCE
|
|||
generic/dma.c
|
||||
generic/drive.c
|
||||
generic/halinit.c
|
||||
generic/kdpci.c
|
||||
generic/memory.c
|
||||
generic/misc.c
|
||||
generic/nmi.c
|
||||
|
|
578
hal/halx86/generic/kdpci.c
Normal file
578
hal/halx86/generic/kdpci.c
Normal file
|
@ -0,0 +1,578 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Kernel debugger PCI configurator
|
||||
* COPYRIGHT: Copyright 2022 Dmitry Borisov <di.sean@protonmail.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* FIXME: We don't use a PCI resource allocator and rely on firmware to
|
||||
* have configured PCI devices properly. The KD PCI configurator should
|
||||
* allocate and assign PCI resources for all PCI buses
|
||||
* before the debugging device can be enabled.
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
#if defined(EARLY_DEBUG)
|
||||
ULONG (*DPRINT0)(_In_ _Printf_format_string_ PCSTR Format, ...);
|
||||
#else
|
||||
#if defined(_MSC_VER)
|
||||
#define DPRINT0 __noop
|
||||
#else
|
||||
#define DPRINT0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
PCI_TYPE1_CFG_CYCLE_BITS HalpPciDebuggingDevice[2] = {0};
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
static
|
||||
CODE_SEG("INIT")
|
||||
ULONG
|
||||
HalpPciBarLength(
|
||||
_In_ ULONG CurrentBar,
|
||||
_In_ ULONG NextBar)
|
||||
{
|
||||
ULONG64 Bar;
|
||||
ULONG Length;
|
||||
|
||||
Bar = CurrentBar;
|
||||
|
||||
if (CurrentBar & PCI_ADDRESS_IO_SPACE)
|
||||
{
|
||||
Length = 1 << 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((CurrentBar & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
|
||||
{
|
||||
Bar = ((ULONG64)NextBar << 32) | CurrentBar;
|
||||
}
|
||||
|
||||
Length = 1 << 4;
|
||||
}
|
||||
|
||||
while (!(Bar & Length) && Length)
|
||||
{
|
||||
Length <<= 1;
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("INIT")
|
||||
BOOLEAN
|
||||
HalpConfigureDebuggingDevice(
|
||||
_In_ PDEBUG_DEVICE_DESCRIPTOR PciDevice,
|
||||
_In_ ULONG PciBus,
|
||||
_In_ PCI_SLOT_NUMBER PciSlot,
|
||||
_Inout_ PPCI_COMMON_HEADER PciConfig)
|
||||
{
|
||||
ULONG i, Register;
|
||||
|
||||
Register = PciConfig->Command & ~(PCI_ENABLE_MEMORY_SPACE |
|
||||
PCI_ENABLE_IO_SPACE);
|
||||
HalpPhase0SetPciDataByOffset(PciBus,
|
||||
PciSlot,
|
||||
&Register,
|
||||
FIELD_OFFSET(PCI_COMMON_HEADER, Command),
|
||||
sizeof(USHORT));
|
||||
|
||||
/* Fill out the device descriptor */
|
||||
for (i = 0; i < MAXIMUM_DEBUG_BARS; ++i)
|
||||
{
|
||||
ULONG Length, NextBar;
|
||||
PDEBUG_DEVICE_ADDRESS DeviceAddress;
|
||||
|
||||
DeviceAddress = &PciDevice->BaseAddress[i];
|
||||
DeviceAddress->Valid = FALSE;
|
||||
|
||||
Register = 0xFFFFFFFF;
|
||||
HalpPhase0SetPciDataByOffset(PciBus,
|
||||
PciSlot,
|
||||
&Register,
|
||||
FIELD_OFFSET(PCI_COMMON_HEADER, u.type0.BaseAddresses[i]),
|
||||
sizeof(ULONG));
|
||||
HalpPhase0GetPciDataByOffset(PciBus,
|
||||
PciSlot,
|
||||
&Register,
|
||||
FIELD_OFFSET(PCI_COMMON_HEADER, u.type0.BaseAddresses[i]),
|
||||
sizeof(ULONG));
|
||||
HalpPhase0SetPciDataByOffset(PciBus,
|
||||
PciSlot,
|
||||
&PciConfig->u.type0.BaseAddresses[i],
|
||||
FIELD_OFFSET(PCI_COMMON_HEADER, u.type0.BaseAddresses[i]),
|
||||
sizeof(ULONG));
|
||||
|
||||
if (i < MAXIMUM_DEBUG_BARS - 1)
|
||||
NextBar = PciConfig->u.type0.BaseAddresses[i + 1];
|
||||
else
|
||||
NextBar = 0;
|
||||
|
||||
Length = HalpPciBarLength(Register, NextBar);
|
||||
if (Register == 0 || Length == 0)
|
||||
continue;
|
||||
|
||||
/* I/O space */
|
||||
if (Register & PCI_ADDRESS_IO_SPACE)
|
||||
{
|
||||
DeviceAddress->Type = CmResourceTypePort;
|
||||
DeviceAddress->Length = Length;
|
||||
DeviceAddress->Valid = TRUE;
|
||||
DeviceAddress->TranslatedAddress =
|
||||
UlongToPtr(PciConfig->u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_ADDRESS_MASK);
|
||||
|
||||
DPRINT0("BAR[%u] IO %lx, length 0x%lx, 0x%lx\n",
|
||||
i,
|
||||
DeviceAddress->TranslatedAddress,
|
||||
Length,
|
||||
Register);
|
||||
}
|
||||
else
|
||||
{
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
BOOLEAN SkipBar = FALSE;
|
||||
|
||||
DeviceAddress->Type = CmResourceTypeMemory;
|
||||
DeviceAddress->Length = Length;
|
||||
DeviceAddress->Valid = TRUE;
|
||||
|
||||
/* 32-bit memory space */
|
||||
PhysicalAddress.HighPart = 0;
|
||||
PhysicalAddress.LowPart =
|
||||
PciConfig->u.type0.BaseAddresses[i] & PCI_ADDRESS_MEMORY_ADDRESS_MASK;
|
||||
|
||||
/* 64-bit memory space */
|
||||
if (((Register & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT))
|
||||
{
|
||||
PhysicalAddress.HighPart = NextBar;
|
||||
SkipBar = TRUE;
|
||||
}
|
||||
|
||||
DPRINT0("BAR[%u] MEM %I64x, length 0x%lx, 0x%lx\n",
|
||||
i,
|
||||
PhysicalAddress.QuadPart,
|
||||
Length,
|
||||
Register);
|
||||
|
||||
if (SkipBar)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
DeviceAddress->TranslatedAddress =
|
||||
HalpMapPhysicalMemory64(PhysicalAddress, BYTES_TO_PAGES(Length));
|
||||
}
|
||||
}
|
||||
PciDevice->Bus = PciBus;
|
||||
PciDevice->Slot = PciSlot.u.AsULONG;
|
||||
PciDevice->VendorID = PciConfig->VendorID;
|
||||
PciDevice->DeviceID = PciConfig->DeviceID;
|
||||
PciDevice->BaseClass = PciConfig->BaseClass;
|
||||
PciDevice->SubClass = PciConfig->SubClass;
|
||||
PciDevice->ProgIf = PciConfig->ProgIf;
|
||||
|
||||
/* Enable decodes */
|
||||
PciConfig->Command |= (PCI_ENABLE_MEMORY_SPACE |
|
||||
PCI_ENABLE_IO_SPACE |
|
||||
PCI_ENABLE_BUS_MASTER);
|
||||
HalpPhase0SetPciDataByOffset(PciBus,
|
||||
PciSlot,
|
||||
&PciConfig->Command,
|
||||
FIELD_OFFSET(PCI_COMMON_HEADER, Command),
|
||||
sizeof(USHORT));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("INIT")
|
||||
BOOLEAN
|
||||
HalpMatchDebuggingDevice(
|
||||
_In_ PDEBUG_DEVICE_DESCRIPTOR PciDevice,
|
||||
_In_ ULONG PciBus,
|
||||
_In_ PCI_SLOT_NUMBER PciSlot,
|
||||
_In_ PPCI_COMMON_HEADER PciConfig)
|
||||
{
|
||||
/* Check if we weren't given a specific device location */
|
||||
if (PciDevice->Bus == 0xFFFFFFFF && PciDevice->Slot == 0xFFFFFFFF)
|
||||
{
|
||||
if (PciDevice->DeviceID == 0xFFFF && PciDevice->VendorID == 0xFFFF)
|
||||
{
|
||||
if (PciDevice->BaseClass == PciConfig->BaseClass &&
|
||||
PciDevice->SubClass == PciConfig->SubClass)
|
||||
{
|
||||
if (PciDevice->ProgIf == 0xFF ||
|
||||
PciDevice->ProgIf == PciConfig->ProgIf)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PciDevice->DeviceID == PciConfig->DeviceID &&
|
||||
PciDevice->VendorID == PciConfig->VendorID)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (PciDevice->Bus == PciBus &&
|
||||
PciDevice->Slot == PciSlot.u.AsULONG)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("INIT")
|
||||
BOOLEAN
|
||||
HalpFindMatchingDebuggingDevice(
|
||||
_In_ PDEBUG_DEVICE_DESCRIPTOR PciDevice)
|
||||
{
|
||||
ULONG BusNumber, DeviceNumber, FunctionNumber;
|
||||
|
||||
for (BusNumber = 0; BusNumber < 0xFF; ++BusNumber)
|
||||
{
|
||||
for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; ++DeviceNumber)
|
||||
{
|
||||
for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; ++FunctionNumber)
|
||||
{
|
||||
ULONG Bytes;
|
||||
PCI_SLOT_NUMBER PciSlot;
|
||||
PCI_COMMON_HEADER PciConfig;
|
||||
|
||||
PciSlot.u.bits.DeviceNumber = DeviceNumber;
|
||||
PciSlot.u.bits.FunctionNumber = FunctionNumber;
|
||||
PciSlot.u.bits.Reserved = 0;
|
||||
Bytes = HalpPhase0GetPciDataByOffset(BusNumber,
|
||||
PciSlot,
|
||||
&PciConfig,
|
||||
0,
|
||||
PCI_COMMON_HDR_LENGTH);
|
||||
if (Bytes != PCI_COMMON_HDR_LENGTH ||
|
||||
PciConfig.VendorID == PCI_INVALID_VENDORID ||
|
||||
PciConfig.VendorID == 0)
|
||||
{
|
||||
if (FunctionNumber == 0)
|
||||
{
|
||||
/* This slot has no single- or a multi-function device */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Continue scanning the functions */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT0("Check %02x:%02x.%x [%04x:%04x]\n",
|
||||
BusNumber, DeviceNumber, FunctionNumber,
|
||||
PciConfig.VendorID, PciConfig.DeviceID);
|
||||
|
||||
switch (PCI_CONFIGURATION_TYPE(&PciConfig))
|
||||
{
|
||||
case PCI_DEVICE_TYPE:
|
||||
{
|
||||
if (HalpMatchDebuggingDevice(PciDevice, BusNumber, PciSlot, &PciConfig))
|
||||
{
|
||||
DPRINT0("Found device\n");
|
||||
|
||||
if (HalpConfigureDebuggingDevice(PciDevice,
|
||||
BusNumber,
|
||||
PciSlot,
|
||||
&PciConfig))
|
||||
{
|
||||
DPRINT0("Device is ready\n");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PCI_BRIDGE_TYPE:
|
||||
{
|
||||
/* FIXME: Implement PCI resource allocator */
|
||||
break;
|
||||
}
|
||||
|
||||
case PCI_CARDBUS_BRIDGE_TYPE:
|
||||
{
|
||||
/* FIXME: Implement PCI resource allocator */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!PCI_MULTIFUNCTION_DEVICE(&PciConfig))
|
||||
{
|
||||
/* The device is a single function device */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
VOID
|
||||
NTAPI
|
||||
HalpRegisterPciDebuggingDeviceInfo(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
WCHAR StringBuffer[16];
|
||||
BOOLEAN HasDebuggingDevice = FALSE;
|
||||
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\"
|
||||
L"CurrentControlSet\\Services\\PCI\\Debug");
|
||||
HANDLE Handle, KeyHandle;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(HalpPciDebuggingDevice); ++i)
|
||||
{
|
||||
if (HalpPciDebuggingDevice[i].InUse)
|
||||
{
|
||||
HasDebuggingDevice = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!HasDebuggingDevice)
|
||||
{
|
||||
/* Nothing to register */
|
||||
return;
|
||||
}
|
||||
|
||||
Status = HalpOpenRegistryKey(&Handle, 0, &KeyName, KEY_ALL_ACCESS, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return;
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(HalpPciDebuggingDevice); ++i)
|
||||
{
|
||||
ULONG Value;
|
||||
PCI_SLOT_NUMBER PciSlot;
|
||||
|
||||
if (!HalpPciDebuggingDevice[i].InUse)
|
||||
continue;
|
||||
|
||||
RtlInitEmptyUnicodeString(&KeyName, StringBuffer, sizeof(StringBuffer));
|
||||
RtlIntegerToUnicodeString(i, 10, &KeyName);
|
||||
Status = HalpOpenRegistryKey(&KeyHandle,
|
||||
Handle,
|
||||
&KeyName,
|
||||
KEY_ALL_ACCESS,
|
||||
TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
continue;
|
||||
|
||||
Value = HalpPciDebuggingDevice[i].BusNumber;
|
||||
RtlInitUnicodeString(&KeyName, L"Bus");
|
||||
ZwSetValueKey(KeyHandle,
|
||||
&KeyName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&Value,
|
||||
sizeof(Value));
|
||||
|
||||
PciSlot.u.AsULONG = 0;
|
||||
PciSlot.u.bits.DeviceNumber = HalpPciDebuggingDevice[i].DeviceNumber;
|
||||
PciSlot.u.bits.FunctionNumber = HalpPciDebuggingDevice[i].FunctionNumber;
|
||||
Value = PciSlot.u.AsULONG;
|
||||
RtlInitUnicodeString(&KeyName, L"Slot");
|
||||
ZwSetValueKey(KeyHandle,
|
||||
&KeyName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&Value,
|
||||
sizeof(Value));
|
||||
|
||||
ZwClose(KeyHandle);
|
||||
}
|
||||
|
||||
ZwClose(Handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Releases the PCI device MMIO mappings
|
||||
* previously allocated with HalpSetupPciDeviceForDebugging().
|
||||
*
|
||||
* This is used to release resources when a device specific initialization fails.
|
||||
*
|
||||
* @param[in,out] PciDevice
|
||||
* Pointer to the debug device descriptor, whose mappings are to be released.
|
||||
*
|
||||
* @return STATUS_SUCCESS.
|
||||
*/
|
||||
CODE_SEG("INIT")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HalpReleasePciDeviceForDebugging(
|
||||
_Inout_ PDEBUG_DEVICE_DESCRIPTOR PciDevice)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
DPRINT0("%s(%p) called\n", __FUNCTION__, PciDevice);
|
||||
|
||||
for (i = 0; i < MAXIMUM_DEBUG_BARS; ++i)
|
||||
{
|
||||
PDEBUG_DEVICE_ADDRESS DeviceAddress = &PciDevice->BaseAddress[i];
|
||||
|
||||
if (DeviceAddress->Type == CmResourceTypeMemory && DeviceAddress->Valid)
|
||||
{
|
||||
HalpUnmapVirtualAddress(DeviceAddress->TranslatedAddress,
|
||||
BYTES_TO_PAGES(DeviceAddress->Length));
|
||||
|
||||
DeviceAddress->Valid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Finds and fully initializes the PCI device
|
||||
* associated with the supplied debug device descriptor.
|
||||
*
|
||||
* @param[in] LoaderBlock
|
||||
* Pointer to the Loader parameter block. Can be NULL.
|
||||
*
|
||||
* @param[in,out] PciDevice
|
||||
* Pointer to the debug device descriptor.
|
||||
*
|
||||
* @return Status.
|
||||
*
|
||||
* This routine is used to match devices to debug device descriptors during
|
||||
* boot phase of the system. This function will search the first device that
|
||||
* matches the criteria given by the fields of the debug device descriptor.
|
||||
* A value of all 1's for the field will indicate that the function
|
||||
* should ignore that field in the search criteria.
|
||||
* The @c Length field of the debug memory requirements optionally specifies
|
||||
* library-determined number of bytes to be allocated for the device context.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* RtlZeroMemory(&PciDevice, sizeof(DEBUG_DEVICE_DESCRIPTOR));
|
||||
* PciDevice.VendorID = 0xFFFF;
|
||||
* PciDevice.DeviceID = 0xFFFF;
|
||||
* PciDevice.Bus = 0xFFFFFFFF;
|
||||
* PciDevice.Slot = 0xFFFFFFFF;
|
||||
* PciDevice.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
|
||||
* PciDevice.SubClass = PCI_SUBCLASS_SB_USB;
|
||||
* PciDevice.ProgIf = 0x30;
|
||||
* PciDevice.Memory.Length = sizeof(HW_EXTENSION);
|
||||
* @endcode
|
||||
*
|
||||
* @sa HalpReleasePciDeviceForDebugging
|
||||
*/
|
||||
CODE_SEG("INIT")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HalpSetupPciDeviceForDebugging(
|
||||
_In_opt_ PVOID LoaderBlock,
|
||||
_Inout_ PDEBUG_DEVICE_DESCRIPTOR PciDevice)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG64 MaxAddress;
|
||||
PFN_NUMBER PageCount;
|
||||
PCI_SLOT_NUMBER PciSlot;
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
PPCI_TYPE1_CFG_CYCLE_BITS DebuggingDevice;
|
||||
|
||||
#if defined(EARLY_DEBUG)
|
||||
if (LoaderBlock)
|
||||
{
|
||||
/* Define your own function or use the trick with FreeLoader */
|
||||
DPRINT0 = ((PLOADER_PARAMETER_BLOCK)LoaderBlock)->u.I386.CommonDataArea;
|
||||
}
|
||||
#endif
|
||||
|
||||
DPRINT0("%s(%p, %p) called\n", __FUNCTION__, LoaderBlock, PciDevice);
|
||||
|
||||
if (!HalpFindMatchingDebuggingDevice(PciDevice))
|
||||
{
|
||||
DPRINT0("No device found matching given device descriptor!\n");
|
||||
return STATUS_DEVICE_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (PciDevice->Initialized)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
PciSlot.u.AsULONG = PciDevice->Slot;
|
||||
|
||||
/* Check if the device is already present */
|
||||
for (i = 0; i < RTL_NUMBER_OF(HalpPciDebuggingDevice); ++i)
|
||||
{
|
||||
DebuggingDevice = &HalpPciDebuggingDevice[i];
|
||||
|
||||
if (DebuggingDevice->InUse &&
|
||||
DebuggingDevice->DeviceNumber == PciSlot.u.bits.DeviceNumber &&
|
||||
DebuggingDevice->FunctionNumber == PciSlot.u.bits.FunctionNumber &&
|
||||
DebuggingDevice->BusNumber == PciDevice->Bus)
|
||||
{
|
||||
DPRINT0("Device %p(0x%lx) is already in use!\n", PciDevice, PciDevice->Slot);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the device location */
|
||||
for (i = 0; i < RTL_NUMBER_OF(HalpPciDebuggingDevice); ++i)
|
||||
{
|
||||
DebuggingDevice = &HalpPciDebuggingDevice[i];
|
||||
|
||||
if (!DebuggingDevice->InUse)
|
||||
{
|
||||
DebuggingDevice->DeviceNumber = PciSlot.u.bits.DeviceNumber;
|
||||
DebuggingDevice->FunctionNumber = PciSlot.u.bits.FunctionNumber;
|
||||
DebuggingDevice->BusNumber = PciDevice->Bus;
|
||||
DebuggingDevice->InUse = TRUE;
|
||||
|
||||
PciDevice->Initialized = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == RTL_NUMBER_OF(HalpPciDebuggingDevice))
|
||||
{
|
||||
DPRINT0("Maximum device count reached!\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (!PciDevice->Memory.Length)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
if (!LoaderBlock)
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
|
||||
if (!PciDevice->Memory.MaxEnd.QuadPart)
|
||||
{
|
||||
PciDevice->Memory.MaxEnd.QuadPart = (ULONG64)-1;
|
||||
}
|
||||
MaxAddress = min(PciDevice->Memory.MaxEnd.QuadPart, 0xFFFFFFFF);
|
||||
PageCount = BYTES_TO_PAGES(PciDevice->Memory.Length);
|
||||
|
||||
/* Allocate the device context */
|
||||
PhysicalAddress.QuadPart = HalpAllocPhysicalMemory(LoaderBlock,
|
||||
MaxAddress,
|
||||
PageCount,
|
||||
FALSE);
|
||||
PciDevice->Memory.Start = PhysicalAddress;
|
||||
if (!PhysicalAddress.QuadPart)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
PciDevice->Memory.VirtualAddress = HalpMapPhysicalMemory64(PhysicalAddress, PageCount);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -244,21 +244,18 @@ typedef struct _PCI_TYPE0_CFG_CYCLE_BITS
|
|||
} u;
|
||||
} PCI_TYPE0_CFG_CYCLE_BITS, *PPCI_TYPE0_CFG_CYCLE_BITS;
|
||||
|
||||
typedef struct _PCI_TYPE1_CFG_CYCLE_BITS
|
||||
typedef union _PCI_TYPE1_CFG_CYCLE_BITS
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Reserved1:2;
|
||||
ULONG InUse:2;
|
||||
ULONG RegisterNumber:6;
|
||||
ULONG FunctionNumber:3;
|
||||
ULONG DeviceNumber:5;
|
||||
ULONG BusNumber:8;
|
||||
ULONG Reserved2:8;
|
||||
} bits;
|
||||
};
|
||||
ULONG AsULONG;
|
||||
} u;
|
||||
} PCI_TYPE1_CFG_CYCLE_BITS, *PPCI_TYPE1_CFG_CYCLE_BITS;
|
||||
|
||||
typedef struct _ARRAY
|
||||
|
@ -396,6 +393,24 @@ HalpAssignPCISlotResources(
|
|||
IN OUT PCM_RESOURCE_LIST *pAllocatedResources
|
||||
);
|
||||
|
||||
CODE_SEG("INIT")
|
||||
ULONG
|
||||
HalpPhase0GetPciDataByOffset(
|
||||
_In_ ULONG Bus,
|
||||
_In_ PCI_SLOT_NUMBER PciSlot,
|
||||
_Out_writes_bytes_all_(Length) PVOID Buffer,
|
||||
_In_ ULONG Offset,
|
||||
_In_ ULONG Length);
|
||||
|
||||
CODE_SEG("INIT")
|
||||
ULONG
|
||||
HalpPhase0SetPciDataByOffset(
|
||||
_In_ ULONG Bus,
|
||||
_In_ PCI_SLOT_NUMBER PciSlot,
|
||||
_In_reads_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Offset,
|
||||
_In_ ULONG Length);
|
||||
|
||||
/* NON-LEGACY */
|
||||
|
||||
ULONG
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
extern BOOLEAN HalpPciLockSettings;
|
||||
ULONG HalpBusType;
|
||||
|
||||
PCI_TYPE1_CFG_CYCLE_BITS HalpPciDebuggingDevice[2] = {{{{0}}}};
|
||||
|
||||
BOOLEAN HalpPCIConfigInitialized;
|
||||
ULONG HalpMinPciBus, HalpMaxPciBus;
|
||||
KSPIN_LOCK HalpPCIConfigLock;
|
||||
|
@ -302,21 +300,23 @@ HalpWritePCIConfig(IN PBUS_HANDLER BusHandler,
|
|||
}
|
||||
|
||||
#ifdef SARCH_XBOX
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpXboxBlacklistedPCISlot(IN PBUS_HANDLER BusHandler,
|
||||
IN PCI_SLOT_NUMBER Slot)
|
||||
HalpXboxBlacklistedPCISlot(
|
||||
_In_ ULONG BusNumber,
|
||||
_In_ PCI_SLOT_NUMBER Slot)
|
||||
{
|
||||
/* Trying to get PCI config data from devices 0:0:1 and 0:0:2 will completely
|
||||
* hang the Xbox. Also, the device number doesn't seem to be decoded for the
|
||||
* video card, so it appears to be present on 1:0:0 - 1:31:0.
|
||||
* We hack around these problems by indicating "device not present" for devices
|
||||
* 0:0:1, 0:0:2, 1:1:0, 1:2:0, 1:3:0, ...., 1:31:0 */
|
||||
if ((BusHandler->BusNumber == 0 && Slot.u.bits.DeviceNumber == 0 &&
|
||||
if ((BusNumber == 0 && Slot.u.bits.DeviceNumber == 0 &&
|
||||
(Slot.u.bits.FunctionNumber == 1 || Slot.u.bits.FunctionNumber == 2)) ||
|
||||
(BusHandler->BusNumber == 1 && Slot.u.bits.DeviceNumber != 0))
|
||||
(BusNumber == 1 && Slot.u.bits.DeviceNumber != 0))
|
||||
{
|
||||
DPRINT("Blacklisted PCI slot (%d:%d:%d)\n", BusHandler->BusNumber, Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber);
|
||||
DPRINT("Blacklisted PCI slot (%d:%d:%d)\n",
|
||||
BusNumber, Slot.u.bits.DeviceNumber, Slot.u.bits.FunctionNumber);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,8 @@ HalpValidPCISlot(IN PBUS_HANDLER BusHandler,
|
|||
if (Slot.u.bits.DeviceNumber >= BusData->MaxDevice) return FALSE;
|
||||
|
||||
#ifdef SARCH_XBOX
|
||||
if (HalpXboxBlacklistedPCISlot(BusHandler, Slot)) return FALSE;
|
||||
if (HalpXboxBlacklistedPCISlot(BusHandler->BusNumber, Slot))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
/* Function 0 doesn't need checking */
|
||||
|
@ -362,6 +363,143 @@ HalpValidPCISlot(IN PBUS_HANDLER BusHandler,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
ULONG
|
||||
HalpPhase0GetPciDataByOffset(
|
||||
_In_ ULONG Bus,
|
||||
_In_ PCI_SLOT_NUMBER PciSlot,
|
||||
_Out_writes_bytes_all_(Length) PVOID Buffer,
|
||||
_In_ ULONG Offset,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
ULONG BytesLeft = Length;
|
||||
PUCHAR BufferPtr = Buffer;
|
||||
PCI_TYPE1_CFG_BITS PciCfg;
|
||||
|
||||
#ifdef SARCH_XBOX
|
||||
if (HalpXboxBlacklistedPCISlot(Bus, PciSlot))
|
||||
{
|
||||
RtlFillMemory(Buffer, Length, 0xFF);
|
||||
return Length;
|
||||
}
|
||||
#endif
|
||||
|
||||
PciCfg.u.AsULONG = 0;
|
||||
PciCfg.u.bits.BusNumber = Bus;
|
||||
PciCfg.u.bits.DeviceNumber = PciSlot.u.bits.DeviceNumber;
|
||||
PciCfg.u.bits.FunctionNumber = PciSlot.u.bits.FunctionNumber;
|
||||
PciCfg.u.bits.Enable = TRUE;
|
||||
|
||||
while (BytesLeft)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
PciCfg.u.bits.RegisterNumber = Offset / sizeof(ULONG);
|
||||
WRITE_PORT_ULONG((PULONG)PCI_TYPE1_ADDRESS_PORT, PciCfg.u.AsULONG);
|
||||
|
||||
i = PCIDeref[Offset % sizeof(ULONG)][BytesLeft % sizeof(ULONG)];
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
*(PULONG)BufferPtr = READ_PORT_ULONG((PULONG)PCI_TYPE1_DATA_PORT);
|
||||
|
||||
/* Number of bytes read */
|
||||
i = sizeof(ULONG);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
*BufferPtr = READ_PORT_UCHAR((PUCHAR)(PCI_TYPE1_DATA_PORT +
|
||||
Offset % sizeof(ULONG)));
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
*(PUSHORT)BufferPtr = READ_PORT_USHORT((PUSHORT)(PCI_TYPE1_DATA_PORT +
|
||||
Offset % sizeof(ULONG)));
|
||||
break;
|
||||
}
|
||||
|
||||
DEFAULT_UNREACHABLE;
|
||||
}
|
||||
|
||||
Offset += i;
|
||||
BufferPtr += i;
|
||||
BytesLeft -= i;
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
ULONG
|
||||
HalpPhase0SetPciDataByOffset(
|
||||
_In_ ULONG Bus,
|
||||
_In_ PCI_SLOT_NUMBER PciSlot,
|
||||
_In_reads_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Offset,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
ULONG BytesLeft = Length;
|
||||
PUCHAR BufferPtr = Buffer;
|
||||
PCI_TYPE1_CFG_BITS PciCfg;
|
||||
|
||||
#ifdef SARCH_XBOX
|
||||
if (HalpXboxBlacklistedPCISlot(Bus, PciSlot))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
PciCfg.u.AsULONG = 0;
|
||||
PciCfg.u.bits.BusNumber = Bus;
|
||||
PciCfg.u.bits.DeviceNumber = PciSlot.u.bits.DeviceNumber;
|
||||
PciCfg.u.bits.FunctionNumber = PciSlot.u.bits.FunctionNumber;
|
||||
PciCfg.u.bits.Enable = TRUE;
|
||||
|
||||
while (BytesLeft)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
PciCfg.u.bits.RegisterNumber = Offset / sizeof(ULONG);
|
||||
WRITE_PORT_ULONG((PULONG)PCI_TYPE1_ADDRESS_PORT, PciCfg.u.AsULONG);
|
||||
|
||||
i = PCIDeref[Offset % sizeof(ULONG)][BytesLeft % sizeof(ULONG)];
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
WRITE_PORT_ULONG((PULONG)PCI_TYPE1_DATA_PORT, *(PULONG)BufferPtr);
|
||||
|
||||
/* Number of bytes written */
|
||||
i = sizeof(ULONG);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)(PCI_TYPE1_DATA_PORT + Offset % sizeof(ULONG)),
|
||||
*BufferPtr);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
WRITE_PORT_USHORT((PUSHORT)(PCI_TYPE1_DATA_PORT + Offset % sizeof(ULONG)),
|
||||
*(PUSHORT)BufferPtr);
|
||||
break;
|
||||
}
|
||||
|
||||
DEFAULT_UNREACHABLE;
|
||||
}
|
||||
|
||||
Offset += i;
|
||||
BufferPtr += i;
|
||||
BytesLeft -= i;
|
||||
}
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
/* HAL PCI CALLBACKS *********************************************************/
|
||||
|
||||
ULONG
|
||||
|
@ -380,14 +518,10 @@ HalpGetPCIData(IN PBUS_HANDLER BusHandler,
|
|||
|
||||
Slot.u.AsULONG = SlotNumber;
|
||||
#ifdef SARCH_XBOX
|
||||
if (HalpXboxBlacklistedPCISlot(BusHandler, Slot))
|
||||
if (HalpXboxBlacklistedPCISlot(BusHandler->BusNumber, Slot))
|
||||
{
|
||||
if (Offset == 0 && Length >= sizeof(USHORT))
|
||||
{
|
||||
*(PUSHORT)Buffer = PCI_INVALID_VENDORID;
|
||||
return sizeof(USHORT);
|
||||
}
|
||||
return 0;
|
||||
RtlFillMemory(Buffer, Length, 0xFF);
|
||||
return Length;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -464,7 +598,8 @@ HalpSetPCIData(IN PBUS_HANDLER BusHandler,
|
|||
|
||||
Slot.u.AsULONG = SlotNumber;
|
||||
#ifdef SARCH_XBOX
|
||||
if (HalpXboxBlacklistedPCISlot(BusHandler, Slot)) return 0;
|
||||
if (HalpXboxBlacklistedPCISlot(BusHandler->BusNumber, Slot))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* Normalize the length */
|
||||
|
@ -607,53 +742,6 @@ HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler,
|
|||
(*Range)->Limit = PciData.u.type0.InterruptLine;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock,
|
||||
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
|
||||
{
|
||||
DPRINT1("Unimplemented!\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HalpReleasePciDeviceForDebugging(IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
|
||||
{
|
||||
DPRINT1("Unimplemented!\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
VOID
|
||||
NTAPI
|
||||
HalpRegisterPciDebuggingDeviceInfo(VOID)
|
||||
{
|
||||
BOOLEAN Found = FALSE;
|
||||
ULONG i;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Loop PCI debugging devices */
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
/* Reserved bit is set if we found one */
|
||||
if (HalpPciDebuggingDevice[i].u.bits.Reserved1)
|
||||
{
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bail out if there aren't any */
|
||||
if (!Found) return;
|
||||
|
||||
/* FIXME: TODO */
|
||||
UNIMPLEMENTED_DBGBREAK("You have implemented the KD routines for searching PCI debugger"
|
||||
"devices, but you have forgotten to implement this routine\n");
|
||||
}
|
||||
#endif // _MINIHAL_
|
||||
|
||||
static ULONG NTAPI
|
||||
|
|
|
@ -13,6 +13,7 @@ list(APPEND HAL_PC98_SOURCE
|
|||
generic/dma.c
|
||||
generic/drive.c
|
||||
generic/halinit.c
|
||||
generic/kdpci.c
|
||||
generic/memory.c
|
||||
generic/misc.c
|
||||
generic/nmi.c
|
||||
|
|
|
@ -12,6 +12,7 @@ list(APPEND HAL_XBOX_SOURCE
|
|||
generic/dma.c
|
||||
generic/drive.c
|
||||
generic/halinit.c
|
||||
generic/kdpci.c
|
||||
generic/memory.c
|
||||
generic/misc.c
|
||||
generic/nmi.c
|
||||
|
|
Loading…
Reference in a new issue