ReactOS 0.4.17-dev-934-g091855f
ecam.c File Reference
#include <pci.h>
#include <debug.h>
Include dependency graph for ecam.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define PCI_ECAM_BUS_COUNT   (PCI_MAX_BRIDGE_NUMBER + 1)
 
#define PCI_ECAM_BUS_SIZE   (PCI_MAX_DEVICES * PCI_MAX_FUNCTION * PCI_EXTENDED_CONFIG_LENGTH)
 

Functions

static BOOLEAN NTAPI PciEcamParseWindow (_In_ PKEY_VALUE_PARTIAL_INFORMATION Value)
 
static NTSTATUS NTAPI PciEcamQueryWindow (VOID)
 
static PUCHAR NTAPI PciEcamMapBus (_In_ ULONG Bus)
 
static VOID NTAPI PciEcamDiscardWindow (VOID)
 
static PUCHAR NTAPI PciEcamFunctionBase (_In_ ULONG Bus, _In_ PCI_SLOT_NUMBER Slot)
 
static VOID NTAPI PciEcamTransfer (_In_ PUCHAR Function, _Inout_updates_bytes_(Length) PUCHAR Buffer, _In_ ULONG Offset, _In_ ULONG Length, _In_ BOOLEAN Read)
 
static NTSTATUS NTAPI PciEcamVerifyBus (_In_ PPCI_FDO_EXTENSION FdoExtension)
 
VOID NTAPI PciInitializeEcam (_In_ PPCI_FDO_EXTENSION FdoExtension)
 Maps the bus an FDO decodes into the ECAM window and verifies the window the first time a bus with devices on it is seen.
 
BOOLEAN NTAPI PciEcamReadWriteConfig (_In_ ULONG Bus, _In_ PCI_SLOT_NUMBER Slot, _Inout_updates_bytes_(Length) PVOID Buffer, _In_ ULONG Offset, _In_ ULONG Length, _In_ BOOLEAN Read)
 Performs a configuration space access through the ECAM window.
 

Variables

BOOLEAN PciEcamVerified = FALSE
 
static BOOLEAN PciEcamWindowQueried = FALSE
 
static BOOLEAN PciEcamSkipK8Northbridge = FALSE
 
static ULONGLONG PciEcamWindowStart
 
static ULONG PciEcamWindowBuses
 
static PUCHAR PciEcamBusView [PCI_ECAM_BUS_COUNT]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file ecam.c.

◆ PCI_ECAM_BUS_COUNT

#define PCI_ECAM_BUS_COUNT   (PCI_MAX_BRIDGE_NUMBER + 1)

Definition at line 17 of file ecam.c.

◆ PCI_ECAM_BUS_SIZE

Definition at line 18 of file ecam.c.

Function Documentation

◆ PciEcamDiscardWindow()

static VOID NTAPI PciEcamDiscardWindow ( VOID  )
static

Definition at line 184 of file ecam.c.

185{
186 ULONG Bus;
187 PAGED_CODE();
188
189 for (Bus = 0; Bus < PciEcamWindowBuses; Bus++)
190 {
191 if (!PciEcamBusView[Bus]) continue;
192
194 PciEcamBusView[Bus] = NULL;
195 }
196
198}
#define PAGED_CODE()
#define NULL
Definition: types.h:112
static PUCHAR PciEcamBusView[PCI_ECAM_BUS_COUNT]
Definition: ecam.c:26
#define PCI_ECAM_BUS_SIZE
Definition: ecam.c:18
static ULONG PciEcamWindowBuses
Definition: ecam.c:25
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
uint32_t ULONG
Definition: typedefs.h:59

Referenced by PciInitializeEcam().

◆ PciEcamFunctionBase()

static PUCHAR NTAPI PciEcamFunctionBase ( _In_ ULONG  Bus,
_In_ PCI_SLOT_NUMBER  Slot 
)
static

Definition at line 203 of file ecam.c.

206{
207 ULONG Index;
208
209 if ((Bus >= PciEcamWindowBuses) || !(PciEcamBusView[Bus])) return NULL;
210
212 (Bus == 0) &&
213 (Slot.u.bits.DeviceNumber >= 0x18))
214 {
215 return NULL;
216 }
217
218 Index = (Slot.u.bits.DeviceNumber * PCI_MAX_FUNCTION) + Slot.u.bits.FunctionNumber;
220}
static BOOLEAN PciEcamSkipK8Northbridge
Definition: ecam.c:23
_In_ WDFCOLLECTION _In_ ULONG Index
#define PCI_EXTENDED_CONFIG_LENGTH
Definition: iotypes.h:3598
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3601

Referenced by PciEcamReadWriteConfig(), and PciEcamVerifyBus().

◆ PciEcamMapBus()

static PUCHAR NTAPI PciEcamMapBus ( _In_ ULONG  Bus)
static

Definition at line 162 of file ecam.c.

164{
166 PAGED_CODE();
167
168 if (Bus >= PciEcamWindowBuses) return NULL;
169 if (PciEcamBusView[Bus]) return PciEcamBusView[Bus];
170
173 if (!PciEcamBusView[Bus])
174 {
175 DPRINT1("PCI: Unable to map ECAM for bus 0x%lx\n", Bus);
176 }
177
178 return PciEcamBusView[Bus];
179}
#define DPRINT1
Definition: precomp.h:8
static ULONGLONG PciEcamWindowStart
Definition: ecam.c:24
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
static WCHAR Address[46]
Definition: ping.c:68
int64_t LONGLONG
Definition: typedefs.h:68
uint64_t ULONGLONG
Definition: typedefs.h:67
@ MmNonCached
Definition: mmtypes.h:129

Referenced by PciInitializeEcam().

◆ PciEcamParseWindow()

static BOOLEAN NTAPI PciEcamParseWindow ( _In_ PKEY_VALUE_PARTIAL_INFORMATION  Value)
static

Definition at line 34 of file ecam.c.

36{
39 ULONGLONG Start, End, Buses;
40 PAGED_CODE();
41
43 (Value->DataLength < sizeof(IO_RESOURCE_REQUIREMENTS_LIST)))
44 {
45 return FALSE;
46 }
47
48 Requirements = (PIO_RESOURCE_REQUIREMENTS_LIST)Value->Data;
49 if (!(Requirements->AlternativeLists) || !(Requirements->List[0].Count)) return FALSE;
50
51 Window = &Requirements->List[0].Descriptors[0];
52 if ((Window->Type != CmResourceTypeMemory) &&
54 {
55 return FALSE;
56 }
57
58 Start = (ULONGLONG)Window->u.Memory.MinimumAddress.QuadPart;
59 End = (ULONGLONG)Window->u.Memory.MaximumAddress.QuadPart;
60 if (End < Start) return FALSE;
61
62 Buses = (End - Start + 1) / PCI_ECAM_BUS_SIZE;
63 if (!(Buses) || (Buses > PCI_ECAM_BUS_COUNT)) return FALSE;
64
67 return TRUE;
68}
static _Out_opt_ PULONGLONG Start
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PCI_ECAM_BUS_COUNT
Definition: ecam.c:17
if(dx< 0)
Definition: linetemp.h:194
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1507
#define CmResourceTypeMemory
Definition: restypes.h:106
Definition: window.c:29
IO_RESOURCE_DESCRIPTOR Descriptors[1]
Definition: iotypes.h:2739
IO_RESOURCE_LIST List[1]
Definition: iotypes.h:2749
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST

Referenced by PciEcamQueryWindow().

◆ PciEcamQueryWindow()

static NTSTATUS NTAPI PciEcamQueryWindow ( VOID  )
static

Definition at line 74 of file ecam.c.

75{
80 ULONG Size;
81 PAGED_CODE();
82
83 if (!PciOpenKey(L"\\Registry\\Machine\\System\\CurrentControlSet"
84 L"\\Control\\Arbiters\\ReservedResources",
85 NULL,
87 &KeyHandle,
88 &Status))
89 {
90 return Status;
91 }
92
93 RtlInitUnicodeString(&ValueName, L"MmConfigRange");
94 Status = ZwQueryValueKey(KeyHandle,
95 &ValueName,
97 NULL,
98 0,
99 &Size);
101 {
104 }
105
107 if (!Value)
108 {
111 }
112
113 Status = ZwQueryValueKey(KeyHandle,
114 &ValueName,
116 Value,
117 Size,
118 &Size);
120
122 {
124 }
125
127 return Status;
128}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
BOOLEAN NTAPI PciOpenKey(IN PWCHAR KeyName, IN HANDLE RootKey, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle, OUT PNTSTATUS KeyStatus)
Definition: utils.c:165
#define PCI_POOL_TAG
Definition: pci.h:27
static BOOLEAN NTAPI PciEcamParseWindow(_In_ PKEY_VALUE_PARTIAL_INFORMATION Value)
Definition: ecam.c:34
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:24
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValuePartialInformation
Definition: nt_native.h:1185
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

Referenced by PciInitializeEcam().

◆ PciEcamReadWriteConfig()

BOOLEAN NTAPI PciEcamReadWriteConfig ( _In_ ULONG  Bus,
_In_ PCI_SLOT_NUMBER  Slot,
_Inout_updates_bytes_(Length) PVOID  Buffer,
_In_ ULONG  Offset,
_In_ ULONG  Length,
_In_ BOOLEAN  Read 
)

Performs a configuration space access through the ECAM window.

Returns
FALSE if the window cannot serve the access, in which case the caller falls back to the legacy mechanism.

Definition at line 386 of file ecam.c.

393{
395
396 if (!PciEcamVerified) return FALSE;
397
400 {
401 return FALSE;
402 }
403
404 Function = PciEcamFunctionBase(Bus, Slot);
405 if (!Function) return FALSE;
406
408 return TRUE;
409}
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
BOOLEAN PciEcamVerified
Definition: ecam.c:20
static VOID NTAPI PciEcamTransfer(_In_ PUCHAR Function, _Inout_updates_bytes_(Length) PUCHAR Buffer, _In_ ULONG Offset, _In_ ULONG Length, _In_ BOOLEAN Read)
Definition: ecam.c:226
static PUCHAR NTAPI PciEcamFunctionBase(_In_ ULONG Bus, _In_ PCI_SLOT_NUMBER Slot)
Definition: ecam.c:203
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_ BOOLEAN Read
Definition: strmini.h:479
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by PciReadWriteConfigSpace().

◆ PciEcamTransfer()

static VOID NTAPI PciEcamTransfer ( _In_ PUCHAR  Function,
_Inout_updates_bytes_(Length) PUCHAR  Buffer,
_In_ ULONG  Offset,
_In_ ULONG  Length,
_In_ BOOLEAN  Read 
)
static

Definition at line 226 of file ecam.c.

232{
234 ULONG Width;
235
236 while (Length)
237 {
239
240 if ((Offset & 1) || ((Length & 3) == 1))
241 {
242 Width = sizeof(UCHAR);
243 if (Read)
244 {
246 }
247 else
248 {
250 }
251 }
252 else if (!(Offset & 3) && !(Length & 3))
253 {
254 Width = sizeof(ULONG);
255 if (Read)
256 {
258 }
259 else
260 {
262 }
263 }
264 else
265 {
266 Width = sizeof(USHORT);
267 if (Read)
268 {
270 }
271 else
272 {
274 }
275 }
276
277 Buffer += Width;
278 Offset += Width;
279 Length -= Width;
280 }
281}
#define WRITE_REGISTER_USHORT(r, v)
Definition: arm.h:14
#define READ_REGISTER_USHORT(r)
Definition: arm.h:13
#define WRITE_REGISTER_ULONG(r, v)
Definition: arm.h:11
#define READ_REGISTER_ULONG(r)
Definition: arm.h:10
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT * Width
Definition: dispmprt.h:1444
unsigned short USHORT
Definition: pedump.c:61
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
uint16_t * PUSHORT
Definition: typedefs.h:56
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)

Referenced by PciEcamReadWriteConfig().

◆ PciEcamVerifyBus()

static NTSTATUS NTAPI PciEcamVerifyBus ( _In_ PPCI_FDO_EXTENSION  FdoExtension)
static

Definition at line 287 of file ecam.c.

289{
290 PCI_SLOT_NUMBER Slot;
292 ULONG Device, LegacyIds, EcamIds, Matched;
293 PAGED_CODE();
294
295 Slot.u.AsULONG = 0;
296 Matched = 0;
297
298 for (Device = 0; Device < PCI_MAX_DEVICES; Device++)
299 {
300 Slot.u.bits.DeviceNumber = Device;
301
302 Function = PciEcamFunctionBase(FdoExtension->BaseBus, Slot);
303 if (!Function) continue;
304
305 LegacyIds = MAXULONG;
306 PciReadSlotConfig(FdoExtension, Slot, &LegacyIds, 0, sizeof(ULONG));
307 if (((USHORT)LegacyIds == PCI_INVALID_VENDORID) || !((USHORT)LegacyIds)) continue;
308
310 if (EcamIds != LegacyIds)
311 {
312 DPRINT1("PCI: ECAM mismatch at %02lx:%02lx.0, read %08lx expected %08lx\n",
313 FdoExtension->BaseBus,
314 Device,
315 EcamIds,
316 LegacyIds);
318 }
319
320 Matched++;
321 }
322
323 return Matched ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
324}
VOID NTAPI PciReadSlotConfig(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:165
@ FdoExtension
Definition: precomp.h:48
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:713
#define STATUS_SUCCESS
Definition: shellext.h:65
union _PCI_SLOT_NUMBER::@4969 u
struct _PCI_SLOT_NUMBER::@4969::@4970 bits
#define MAXULONG
Definition: typedefs.h:251
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3603
#define PCI_MAX_DEVICES
Definition: iotypes.h:3600

Referenced by PciInitializeEcam().

◆ PciInitializeEcam()

VOID NTAPI PciInitializeEcam ( _In_ PPCI_FDO_EXTENSION  FdoExtension)

Maps the bus an FDO decodes into the ECAM window and verifies the window the first time a bus with devices on it is seen.

Parameters
[in]FdoExtensionThe FDO extension of the bus being started.

Definition at line 336 of file ecam.c.

338{
340 PAGED_CODE();
341
343 {
345
347 if (!NT_SUCCESS(Status))
348 {
349 DPRINT1("PCI: No ECAM window available (0x%lx)\n", Status);
350 return;
351 }
352
353#if defined(_M_IX86) || defined(_M_AMD64)
354 PciEcamSkipK8Northbridge = PciEcamIsAmdK8();
355#endif
356 DPRINT1("PCI: ECAM window at 0x%I64x for 0x%lx buses\n",
359 }
360
361 if (!PciEcamMapBus(FdoExtension->BaseBus) || PciEcamVerified) return;
362
363 /* An empty bus proves nothing, so leave it to the next one */
366 {
368 }
369 else if (NT_SUCCESS(Status))
370 {
372 DPRINT1("PCI: ECAM verified on bus 0x%lx\n", FdoExtension->BaseBus);
373 }
374}
static VOID NTAPI PciEcamDiscardWindow(VOID)
Definition: ecam.c:184
static PUCHAR NTAPI PciEcamMapBus(_In_ ULONG Bus)
Definition: ecam.c:162
static NTSTATUS NTAPI PciEcamQueryWindow(VOID)
Definition: ecam.c:74
static NTSTATUS NTAPI PciEcamVerifyBus(_In_ PPCI_FDO_EXTENSION FdoExtension)
Definition: ecam.c:287
static BOOLEAN PciEcamWindowQueried
Definition: ecam.c:22

Referenced by PciAddDevice().

Variable Documentation

◆ PciEcamBusView

PUCHAR PciEcamBusView[PCI_ECAM_BUS_COUNT]
static

Definition at line 26 of file ecam.c.

Referenced by PciEcamDiscardWindow(), PciEcamFunctionBase(), and PciEcamMapBus().

◆ PciEcamSkipK8Northbridge

BOOLEAN PciEcamSkipK8Northbridge = FALSE
static

Definition at line 23 of file ecam.c.

Referenced by PciEcamFunctionBase(), and PciInitializeEcam().

◆ PciEcamVerified

BOOLEAN PciEcamVerified = FALSE

Definition at line 20 of file ecam.c.

Referenced by PciEcamReadWriteConfig(), PciGetExpressCapabilities(), and PciInitializeEcam().

◆ PciEcamWindowBuses

ULONG PciEcamWindowBuses
static

◆ PciEcamWindowQueried

BOOLEAN PciEcamWindowQueried = FALSE
static

Definition at line 22 of file ecam.c.

Referenced by PciInitializeEcam().

◆ PciEcamWindowStart

ULONGLONG PciEcamWindowStart
static

Definition at line 24 of file ecam.c.

Referenced by PciEcamMapBus(), PciEcamParseWindow(), and PciInitializeEcam().