ReactOS 0.4.17-dev-1133-gc25e4fd
rbar.c File Reference
#include <pci.h>
#include <debug.h>
Include dependency graph for rbar.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define PCI_RBAR_SIZE_TO_LENGTH(Bit)   (1ULL << ((Bit) + 20))
 

Functions

VOID NTAPI PciGetResizableBarCapability (_Inout_ PPCI_PDO_EXTENSION PdoExtension)
 Records which BARs of a new function can be resized and the sizes each of them supports.
 
static BOOLEAN NTAPI PciFillResizedBarRequirement (_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor, _In_ PIO_RESOURCE_DESCRIPTOR Limit, _In_ ULONGLONG Length, _In_ UCHAR Option)
 
ULONG NTAPI PciAddResizableBarRequirements (_In_ PPCI_PDO_EXTENSION PdoExtension, _In_ ULONG BarIndex, _In_ PIO_RESOURCE_DESCRIPTOR Limit, _Out_writes_opt_(2) PIO_RESOURCE_DESCRIPTOR Descriptors)
 Writes the requirements for the sizes a resizable BAR can grow to. They go ahead of the default requirement, which the caller then lists as the alternative. The largest size is preferred, and the smallest supported size follows it when that is also bigger than the default.
 
static VOID NTAPI PciSelectResizableBarSize (_In_ PPCI_PDO_EXTENSION PdoExtension, _In_ ULONG BarIndex, _In_ ULONGLONG Length)
 
VOID NTAPI PciApplyResizableBarSizes (_In_ PPCI_PDO_EXTENSION PdoExtension)
 Sets every resizable BAR to the length it was assigned. The memory decode has to be off, since the size field changes what the BAR decodes. Critical devices call this from the IPI that updates their hardware.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file rbar.c.

◆ PCI_RBAR_SIZE_TO_LENGTH

#define PCI_RBAR_SIZE_TO_LENGTH (   Bit)    (1ULL << ((Bit) + 20))

Definition at line 17 of file rbar.c.

Function Documentation

◆ PciAddResizableBarRequirements()

ULONG NTAPI PciAddResizableBarRequirements ( _In_ PPCI_PDO_EXTENSION  PdoExtension,
_In_ ULONG  BarIndex,
_In_ PIO_RESOURCE_DESCRIPTOR  Limit,
_Out_writes_opt_(2) PIO_RESOURCE_DESCRIPTOR  Descriptors 
)

Writes the requirements for the sizes a resizable BAR can grow to. They go ahead of the default requirement, which the caller then lists as the alternative. The largest size is preferred, and the smallest supported size follows it when that is also bigger than the default.

Parameters
[in]PdoExtensionThe PDO extension of the function.
[in]BarIndexThe BAR the default requirement describes.
[in]LimitThe default requirement of the BAR.
[out]DescriptorsReceives up to two descriptors, or NULL to only count them.
Returns
The number of descriptors written, which is 0 when the BAR cannot grow.

Definition at line 142 of file rbar.c.

147{
148 IO_RESOURCE_DESCRIPTOR Resized[2];
149 ULONGLONG Largest, Smallest;
150 ULONG SizeMask, Count;
151 PAGED_CODE();
152
153 /* Only a memory BAR asking for less than 4GB is offered other sizes */
154 if ((BarIndex >= PCI_RBAR_MAX_ENTRIES) || (Limit->Type != CmResourceTypeMemory))
155 return 0;
156
157 SizeMask = PdoExtension->ResizableBarState.SizeMask[BarIndex];
158 if (!SizeMask)
159 return 0;
160
161 /* Built even when only counting, so a size that cannot be described is never counted */
163 if ((Largest <= Limit->u.Memory.Length) ||
165 {
166 return 0;
167 }
168 Count = 1;
169
171 if ((Smallest > Limit->u.Memory.Length) &&
172 (Smallest < Largest) &&
174 {
175 Count++;
176 }
177
178 if (Descriptors)
179 RtlCopyMemory(Descriptors, Resized, Count * sizeof(IO_RESOURCE_DESCRIPTOR));
180
181 return Count;
182}
#define PAGED_CODE()
#define PCI_RBAR_MAX_ENTRIES
Definition: pci.h:83
@ PdoExtension
Definition: precomp.h:61
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
int Count
Definition: noreturn.cpp:7
static BOOLEAN NTAPI PciFillResizedBarRequirement(_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor, _In_ PIO_RESOURCE_DESCRIPTOR Limit, _In_ ULONGLONG Length, _In_ UCHAR Option)
Definition: rbar.c:97
#define PCI_RBAR_SIZE_TO_LENGTH(Bit)
Definition: rbar.c:17
#define CmResourceTypeMemory
Definition: restypes.h:106
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
NTSYSAPI CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG)
Definition: bitmap.c:211
NTSYSAPI CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG)
Definition: bitmap.c:235
#define IO_RESOURCE_ALTERNATIVE
#define IO_RESOURCE_PREFERRED
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:304

Referenced by PciBuildRequirementsList().

◆ PciApplyResizableBarSizes()

VOID NTAPI PciApplyResizableBarSizes ( _In_ PPCI_PDO_EXTENSION  PdoExtension)

Sets every resizable BAR to the length it was assigned. The memory decode has to be off, since the size field changes what the BAR decodes. Critical devices call this from the IPI that updates their hardware.

Parameters
[in]PdoExtensionThe PDO extension of the function whose resources are being set.

Definition at line 229 of file rbar.c.

231{
234 ULONG BarIndex;
235
236 if (!PdoExtension->ResizableBarState.CapabilityPtr || !PdoExtension->Resources)
237 return;
238
239 /* A function whose decodes could not be turned off keeps the sizes it has */
241 &Command,
243 sizeof(Command));
245 {
246 DPRINT("PCI: Memory decode of %p is still on, not resizing BARs\n", PdoExtension);
247 return;
248 }
249
250 for (BarIndex = 0; BarIndex < PCI_RBAR_MAX_ENTRIES; BarIndex++)
251 {
252 if (!PdoExtension->ResizableBarState.SizeMask[BarIndex])
253 continue;
254
255 Current = &PdoExtension->Resources->Current[BarIndex];
256 if ((Current->Type != CmResourceTypeMemory) &&
257 (Current->Type != CmResourceTypeMemoryLarge))
258 {
259 continue;
260 }
261
263 BarIndex,
265 }
266}
ULONGLONG NTAPI RtlCmDecodeMemIoResource(_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, _Out_opt_ PULONGLONG Start)
Definition: memres.c:58
#define NULL
Definition: types.h:112
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:149
unsigned short USHORT
Definition: pedump.c:61
static VOID NTAPI PciSelectResizableBarSize(_In_ PPCI_PDO_EXTENSION PdoExtension, _In_ ULONG BarIndex, _In_ ULONGLONG Length)
Definition: rbar.c:187
#define DPRINT
Definition: sndvol32.h:73
Definition: shell.h:41
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3619

Referenced by PcipUpdateHardware().

◆ PciFillResizedBarRequirement()

static BOOLEAN NTAPI PciFillResizedBarRequirement ( _Out_ PIO_RESOURCE_DESCRIPTOR  Descriptor,
_In_ PIO_RESOURCE_DESCRIPTOR  Limit,
_In_ ULONGLONG  Length,
_In_ UCHAR  Option 
)
static

Definition at line 97 of file rbar.c.

102{
104
105 *Descriptor = *Limit;
106 Descriptor->Option = Option;
107 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
108
111 Length,
112 Length,
113 Limit->u.Memory.MinimumAddress.QuadPart,
114 Limit->u.Memory.MaximumAddress.QuadPart);
115 return NT_SUCCESS(Status);
116}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
NTSYSAPI NTSTATUS NTAPI RtlIoEncodeMemIoResource(_In_ struct _IO_RESOURCE_DESCRIPTOR *Descriptor, _In_ UCHAR Type, _In_ ULONGLONG Length, _In_ ULONGLONG Alignment, _In_ ULONGLONG MinimumAddress, _In_ ULONGLONG MaximumAddress)

Referenced by PciAddResizableBarRequirements().

◆ PciGetResizableBarCapability()

VOID NTAPI PciGetResizableBarCapability ( _Inout_ PPCI_PDO_EXTENSION  PdoExtension)

Records which BARs of a new function can be resized and the sizes each of them supports.

Parameters
[in,out]PdoExtensionThe PDO extension of the function being enumerated.

Definition at line 31 of file rbar.c.

33{
34 PPCI_RESIZABLE_BAR_STATE State = &PdoExtension->ResizableBarState;
36 ULONG Offset, Entry, EntryCount, Control, SizeMask, BarIndex;
37
38 PAGED_CODE();
39
40 RtlZeroMemory(State, sizeof(*State));
41
42 /* Bridges keep their windows after the first two BARs, so only endpoints are resized */
43 if (PdoExtension->HeaderType != PCI_DEVICE_TYPE)
44 return;
45
48 &Header,
49 sizeof(Header));
50 if (!Offset)
51 return;
52
53 /* Only the first control register holds the number of entries */
55 &Control,
57 sizeof(Control));
59 if (EntryCount > PCI_RBAR_MAX_ENTRIES)
60 EntryCount = PCI_RBAR_MAX_ENTRIES;
61
62 State->CapabilityPtr = (USHORT)Offset;
63
64 for (Entry = 0; Entry < EntryCount; Entry++)
65 {
67 &SizeMask,
69 sizeof(SizeMask));
71 &Control,
73 sizeof(Control));
74
77
78 /* Skip entries with no sizes, a BAR that cannot exist, or a BAR already seen */
79 if (!SizeMask ||
80 (BarIndex >= PCI_RBAR_MAX_ENTRIES) ||
81 State->SizeMask[BarIndex])
82 {
83 continue;
84 }
85
86 State->SizeMask[BarIndex] = SizeMask;
87 State->EntryIndex[BarIndex] = (UCHAR)Entry;
88
89 DPRINT1("PCI: BAR %lu of %p is resizable, sizes 0x%08lx\n",
90 BarIndex, PdoExtension, SizeMask);
91 }
92}
#define DPRINT1
Definition: precomp.h:8
Definition: Header.h:9
#define PCI_RBAR_CONTROL_BAR_INDEX_MASK
Definition: pci.h:87
#define PCI_RBAR_ENTRY_CONTROL(n)
Definition: pci.h:85
#define PCI_RBAR_CAPABILITY_SIZES_SHIFT
Definition: pci.h:86
#define PCI_RBAR_ENTRY_CAPABILITY(n)
Definition: pci.h:84
#define PCI_RBAR_CONTROL_COUNT_SHIFT
Definition: pci.h:89
#define PCI_RBAR_CONTROL_COUNT_MASK
Definition: pci.h:88
#define PCI_RBAR_EXTENDED_CAP_ID
Definition: pci.h:82
ULONG NTAPI PciReadDeviceExtendedCapability(_In_ PPCI_PDO_EXTENSION DeviceExtension, _In_ ULONG CapabilityId, _Out_writes_bytes_(Length) PPCI_EXPRESS_ENHANCED_CAPABILITY_HEADER Buffer, _In_ ULONG Length)
Finds an extended capability and reads it into the caller's buffer.
Definition: express.c:39
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
Entry
Definition: section.c:5216
unsigned char UCHAR
Definition: typedefs.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
#define PCI_DEVICE_TYPE
Definition: iotypes.h:3607

Referenced by PciGetEnhancedCapabilities().

◆ PciSelectResizableBarSize()

static VOID NTAPI PciSelectResizableBarSize ( _In_ PPCI_PDO_EXTENSION  PdoExtension,
_In_ ULONG  BarIndex,
_In_ ULONGLONG  Length 
)
static

Definition at line 187 of file rbar.c.

191{
192 PPCI_RESIZABLE_BAR_STATE State = &PdoExtension->ResizableBarState;
193 ULONGLONG Megabytes;
194 ULONG SizeBit, Control, Offset;
195
196 /* Only a power of two of at least a megabyte can be specified in the size field */
197 Megabytes = Length >> 20;
198 if (!Megabytes || (Megabytes & (Megabytes - 1)) || (Length & 0xFFFFF))
199 return;
200
201 if (!(State->SizeMask[BarIndex] & Megabytes))
202 return;
203
204 SizeBit = (ULONG)RtlFindMostSignificantBit(Megabytes);
205
206 Offset = State->CapabilityPtr + PCI_RBAR_ENTRY_CONTROL(State->EntryIndex[BarIndex]);
209 return;
210
211 Control &= ~PCI_RBAR_CONTROL_SIZE_MASK;
214
215 DPRINT("PCI: BAR %lu of %p resized to %I64u MB\n", BarIndex, PdoExtension, Megabytes);
216}
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:133
#define PCI_RBAR_CONTROL_SIZE_SHIFT
Definition: pci.h:91
#define PCI_RBAR_CONTROL_SIZE_MASK
Definition: pci.h:90

Referenced by PciApplyResizableBarSizes().