Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

631 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. agplib.h
  5. Abstract:
  6. Private header file for the common AGP library
  7. Author:
  8. John Vert (jvert) 10/22/1997
  9. Revision History:
  10. Elliot Shmukler (elliots) 3/24/1999 - Added support for "favored" memory
  11. ranges for AGP physical memory allocation,
  12. fixed some bugs.
  13. --*/
  14. #include "agp.h"
  15. #include "wdmguid.h"
  16. #include "wmilib.h"
  17. #include <devioctl.h>
  18. #include <acpiioct.h>
  19. //
  20. // regstr.h uses things of type WORD, which isn't around in kernel mode.
  21. //
  22. #define _IN_KERNEL_
  23. #include "regstr.h"
  24. #define AGP_HACK_FLAG_SUBSYSTEM 0x01
  25. #define AGP_HACK_FLAG_REVISION 0x02
  26. typedef struct _AGP_HACK_TABLE_ENTRY {
  27. USHORT VendorID;
  28. USHORT DeviceID;
  29. USHORT SubVendorID;
  30. USHORT SubSystemID;
  31. ULONGLONG DeviceFlags;
  32. UCHAR RevisionID;
  33. UCHAR Flags;
  34. } AGP_HACK_TABLE_ENTRY, *PAGP_HACK_TABLE_ENTRY;
  35. extern PAGP_HACK_TABLE_ENTRY AgpDeviceHackTable;
  36. extern PAGP_HACK_TABLE_ENTRY AgpGlobalHackTable;
  37. typedef
  38. ULONG_PTR
  39. (*PCRITICALROUTINE)(
  40. IN PVOID Extension,
  41. IN PVOID Context
  42. );
  43. typedef struct _AGP_CRITICAL_ROUTINE_CONTEXT {
  44. volatile LONG Gate;
  45. volatile LONG Barrier;
  46. PCRITICALROUTINE Routine;
  47. PVOID Extension;
  48. PVOID Context;
  49. } AGP_CRITICAL_ROUTINE_CONTEXT, *PAGP_CRITICAL_ROUTINE_CONTEXT;
  50. //
  51. // Define common device extension
  52. //
  53. typedef enum _AGP_EXTENSION_TYPE {
  54. AgpTargetFilter,
  55. AgpMasterFilter
  56. } AGP_EXTENSION_TYPE;
  57. #define TARGET_SIG 'TpgA'
  58. #define MASTER_SIG 'MpgA'
  59. typedef struct _COMMON_EXTENSION {
  60. ULONG Signature;
  61. BOOLEAN Deleted;
  62. AGP_EXTENSION_TYPE Type;
  63. PDEVICE_OBJECT AttachedDevice;
  64. BUS_INTERFACE_STANDARD BusInterface;
  65. } COMMON_EXTENSION, *PCOMMON_EXTENSION;
  66. // Structures to maintain a list of "favored" memory ranges
  67. // for AGP allocation.
  68. typedef struct _AGP_MEMORY_RANGE
  69. {
  70. PHYSICAL_ADDRESS Lower;
  71. PHYSICAL_ADDRESS Upper;
  72. } AGP_MEMORY_RANGE, *PAGP_MEMORY_RANGE;
  73. typedef struct _AGP_FAVORED_MEMORY
  74. {
  75. ULONG NumRanges;
  76. PAGP_MEMORY_RANGE Ranges;
  77. } AGP_FAVORED_MEMORY;
  78. //
  79. // WMI data types
  80. //
  81. #define AGP_WMI_STD_DATA_GUID \
  82. { 0x8c27fbed, 0x1c7b, 0x47e4, 0xa6, 0x49, 0x0e, 0x38, 0x9d, 0x3a, 0xda, 0x4f }
  83. typedef struct _AGP_STD_DATA {
  84. PHYSICAL_ADDRESS ApertureBase;
  85. ULONG ApertureLength;
  86. ULONG AgpStatus;
  87. ULONG AgpCommand;
  88. } AGP_STD_DATA, *PAGP_STD_DATA;
  89. //
  90. // Redirected functions for different flavors of resource handling
  91. //
  92. typedef struct _TARGET_EXTENSION *PTARGET_EXTENSION;
  93. typedef
  94. NTSTATUS
  95. (*PAGP_RESOURCE_FILTER_ROUTINE)(
  96. IN PDEVICE_OBJECT DeviceObject,
  97. IN PIRP Irp,
  98. IN PTARGET_EXTENSION Extension
  99. );
  100. typedef
  101. NTSTATUS
  102. (*PAGP_START_TARGET_ROUTINE)(
  103. IN PIRP Irp,
  104. IN PTARGET_EXTENSION Extension
  105. );
  106. typedef struct _TARGET_EXTENSION {
  107. COMMON_EXTENSION CommonExtension;
  108. PFAST_MUTEX Lock;
  109. struct _MASTER_EXTENSION *ChildDevice;
  110. PCM_RESOURCE_LIST Resources;
  111. PCM_RESOURCE_LIST ResourcesTranslated;
  112. AGP_FAVORED_MEMORY FavoredMemory;
  113. PHYSICAL_ADDRESS GartBase;
  114. ULONG GartLengthInPages;
  115. ULONG Agp3BridgeResourceIndex;
  116. PAGP_START_TARGET_ROUTINE StartTarget;
  117. PAGP_RESOURCE_FILTER_ROUTINE FilterResourceRquirements;
  118. PDEVICE_OBJECT PDO;
  119. PDEVICE_OBJECT Self;
  120. WMILIB_CONTEXT WmiLibInfo;
  121. //
  122. // This must be last, d'oh!
  123. //
  124. ULONGLONG AgpContext;
  125. } TARGET_EXTENSION, *PTARGET_EXTENSION;
  126. typedef struct _MASTER_EXTENSION {
  127. COMMON_EXTENSION CommonExtension;
  128. PTARGET_EXTENSION Target;
  129. ULONG Capabilities;
  130. ULONG InterfaceCount; // tracks the number of interfaces handed out
  131. ULONG ReservedPages; // tracks the number of pages reserved in the aperture
  132. BOOLEAN StopPending; // TRUE if we have seen a QUERY_STOP
  133. BOOLEAN RemovePending; // TRUE if we have seen a QUERY_REMOVE
  134. ULONG DisableCount; // non-zero if we are in a state where we cannot service requests
  135. } MASTER_EXTENSION, *PMASTER_EXTENSION;
  136. typedef struct _GLOBALS {
  137. //
  138. // Path to the driver's Services Key in the registry
  139. //
  140. UNICODE_STRING RegistryPath;
  141. //
  142. // Cached target capability settings
  143. //
  144. ULONG AgpStatus;
  145. ULONG AgpCommand;
  146. } GLOBALS;
  147. extern GLOBALS Globals;
  148. //
  149. // The MBAT - used to retrieve "favored" memory ranges from
  150. // the AGP northbridge via an ACPI BANK method
  151. //
  152. #include <pshpack1.h>
  153. typedef struct _MBAT
  154. {
  155. UCHAR TableVersion;
  156. UCHAR AgpBusNumber;
  157. UCHAR ValidEntryBitmap;
  158. AGP_MEMORY_RANGE DecodeRange[ANYSIZE_ARRAY];
  159. } MBAT, *PMBAT;
  160. #include <poppack.h>
  161. #define MBAT_VERSION 1
  162. #define MAX_MBAT_SIZE sizeof(MBAT) + ((sizeof(UCHAR) * 8) - ANYSIZE_ARRAY) \
  163. * sizeof(AGP_MEMORY_RANGE)
  164. #define CM_BANK_METHOD (ULONG)('KNAB')
  165. //
  166. // The highest memory address supported by AGP
  167. //
  168. #define MAX_MEM(_num_) _num_ = 1; \
  169. _num_ = _num_*1024*1024*1024*4 - 1
  170. #define RELEASE_BUS_INTERFACE(_ext_) (_ext_)->CommonExtension.BusInterface.InterfaceDereference((_ext_)->CommonExtension.BusInterface.Context)
  171. //
  172. // Macros for getting from the chipset-specific context to our structures
  173. //
  174. #define GET_TARGET_EXTENSION(_target_,_agp_context_) (_target_) = (CONTAINING_RECORD((_agp_context_), \
  175. TARGET_EXTENSION, \
  176. AgpContext)); \
  177. ASSERT_TARGET(_target_)
  178. #define GET_MASTER_EXTENSION(_master_,_agp_context_) { \
  179. PTARGET_EXTENSION _targetext_; \
  180. GET_TARGET_EXTENSION(_targetext_, (_agp_context_)); \
  181. (_master_) = _targetext_->ChildDevice; \
  182. ASSERT_MASTER(_master_); \
  183. }
  184. #define GET_TARGET_PDO(_pdo_,_agp_context_) { \
  185. PTARGET_EXTENSION _targetext_; \
  186. GET_TARGET_EXTENSION(_targetext_,(_agp_context_)); \
  187. (_pdo_) = _targetext_->CommonExtension.AttachedDevice; \
  188. }
  189. #define GET_MASTER_PDO(_pdo_,_agp_context_) { \
  190. PMASTER_EXTENSION _masterext_; \
  191. GET_MASTER_EXTENSION(_masterext_, (_agp_context_)); \
  192. (_pdo_) = _masterext_->CommonExtension.AttachedDevice; \
  193. }
  194. #define GET_AGP_CONTEXT(_targetext_) ((PVOID)(&(_targetext_)->AgpContext))
  195. #define GET_AGP_CONTEXT_FROM_MASTER(_masterext_) GET_AGP_CONTEXT((_masterext_)->Target)
  196. //
  197. // Some debugging macros
  198. //
  199. #define ASSERT_TARGET(_target_) ASSERT((_target_)->CommonExtension.Signature == TARGET_SIG);
  200. //
  201. // We may not have all our context filled out to this point yet...
  202. //
  203. // ASSERT((_target_)->ChildDevice->CommonExtension.Signature == MASTER_SIG)
  204. #define ASSERT_MASTER(_master_) ASSERT((_master_)->CommonExtension.Signature == MASTER_SIG); \
  205. ASSERT((_master_)->Target->CommonExtension.Signature == TARGET_SIG)
  206. //
  207. // Locking macros
  208. //
  209. #define LOCK_MUTEX(_fm_) ExAcquireFastMutex(_fm_); \
  210. ASSERT((_fm_)->Count == 0)
  211. #define UNLOCK_MUTEX(_fm_) ASSERT((_fm_)->Count == 0); \
  212. ExReleaseFastMutex(_fm_)
  213. #define LOCK_TARGET(_targetext_) ASSERT_TARGET(_targetext_); \
  214. LOCK_MUTEX((_targetext_)->Lock)
  215. #define LOCK_MASTER(_masterext_) ASSERT_MASTER(_masterext_); \
  216. LOCK_MUTEX((_masterext_)->Target->Lock)
  217. #define UNLOCK_TARGET(_targetext_) ASSERT_TARGET(_targetext_); \
  218. UNLOCK_MUTEX((_targetext_)->Lock)
  219. #define UNLOCK_MASTER(_masterext_) ASSERT_MASTER(_masterext_); \
  220. UNLOCK_MUTEX((_masterext_)->Target->Lock)
  221. //
  222. // Private resource type definition
  223. //
  224. typedef enum {
  225. AgpPrivateResource = '0PGA'
  226. } AGP_PRIVATE_RESOURCE_TYPES;
  227. #define JUNK_INDEX 0xBADCEEDE
  228. //
  229. // Define function prototypes
  230. //
  231. //
  232. // Driver and device initialization - init.c
  233. //
  234. NTSTATUS
  235. AgpAttachDeviceRelations(
  236. IN PDEVICE_OBJECT DeviceObject,
  237. IN PIRP Irp,
  238. IN PTARGET_EXTENSION Extension
  239. );
  240. //
  241. // IRP Dispatch routines - dispatch.c
  242. //
  243. NTSTATUS
  244. AgpDispatchPnp(
  245. IN PDEVICE_OBJECT DeviceObject,
  246. IN OUT PIRP Irp
  247. );
  248. NTSTATUS
  249. AgpDispatchPower(
  250. IN PDEVICE_OBJECT DeviceObject,
  251. IN OUT PIRP Irp
  252. );
  253. NTSTATUS
  254. AgpDispatchDeviceControl(
  255. IN PDEVICE_OBJECT DeviceObject,
  256. IN OUT PIRP Irp
  257. );
  258. NTSTATUS
  259. AgpDispatchWmi(
  260. IN PDEVICE_OBJECT DeviceObject,
  261. IN OUT PIRP Irp
  262. );
  263. NTSTATUS
  264. AgpSetEventCompletion(
  265. IN PDEVICE_OBJECT DeviceObject,
  266. IN PIRP Irp,
  267. IN PKEVENT Event
  268. );
  269. //
  270. // Config space handling routines - config.c
  271. //
  272. #if (WINVER < 0x502)
  273. ULONG
  274. ApLegacyGetBusData(
  275. IN PVOID Context,
  276. IN ULONG DataType,
  277. IN PVOID Buffer,
  278. IN ULONG Offset,
  279. IN ULONG Length
  280. );
  281. ULONG
  282. ApLegacySetBusData(
  283. IN PVOID Context,
  284. IN ULONG DataType,
  285. IN PVOID Buffer,
  286. IN ULONG Offset,
  287. IN ULONG Length
  288. );
  289. #endif
  290. NTSTATUS
  291. ApGetExtendedAgpCapability(
  292. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  293. IN PVOID Context,
  294. IN EXTENDED_AGP_REGISTER RegSelect,
  295. OUT PVOID ExtCapReg
  296. );
  297. NTSTATUS
  298. ApSetExtendedAgpCapability(
  299. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  300. IN PVOID Context,
  301. IN EXTENDED_AGP_REGISTER RegSelect,
  302. IN PVOID ExtCapReg
  303. );
  304. NTSTATUS
  305. ApQueryBusInterface(
  306. IN PDEVICE_OBJECT DeviceObject,
  307. OUT PBUS_INTERFACE_STANDARD BusInterface
  308. );
  309. NTSTATUS
  310. ApQueryAgpTargetBusInterface(
  311. IN PDEVICE_OBJECT DeviceObject,
  312. OUT PBUS_INTERFACE_STANDARD BusInterface,
  313. OUT PUCHAR CapabilityID
  314. );
  315. //
  316. // Resource handing routines - resource.c
  317. //
  318. NTSTATUS
  319. AgpFilterResourceRequirementsHost(
  320. IN PDEVICE_OBJECT DeviceObject,
  321. IN PIRP Irp,
  322. IN PTARGET_EXTENSION Extension
  323. );
  324. NTSTATUS
  325. Agp3FilterResourceRequirementsBridge(
  326. IN PDEVICE_OBJECT DeviceObject,
  327. IN PIRP Irp,
  328. IN PTARGET_EXTENSION Extension
  329. );
  330. NTSTATUS
  331. AgpFilterResourceRequirements(
  332. IN PDEVICE_OBJECT DeviceObject,
  333. IN PIRP Irp,
  334. IN PTARGET_EXTENSION Extension
  335. );
  336. NTSTATUS
  337. AgpQueryResources(
  338. IN PDEVICE_OBJECT DeviceObject,
  339. IN PIRP Irp,
  340. IN PTARGET_EXTENSION Extension
  341. );
  342. NTSTATUS
  343. AgpStartTarget(
  344. IN PIRP Irp,
  345. IN PTARGET_EXTENSION Extension
  346. );
  347. NTSTATUS
  348. Agp3StartTargetBridge(
  349. IN PIRP Irp,
  350. IN PTARGET_EXTENSION Extension
  351. );
  352. NTSTATUS
  353. AgpStartTargetHost(
  354. IN PIRP Irp,
  355. IN PTARGET_EXTENSION Extension
  356. );
  357. VOID
  358. AgpStopTarget(
  359. IN PTARGET_EXTENSION Extension
  360. );
  361. //
  362. // AGP Interface functions
  363. //
  364. NTSTATUS
  365. AgpInterfaceSetRate(
  366. IN PMASTER_EXTENSION Extension,
  367. IN ULONG AgpRate
  368. );
  369. VOID
  370. AgpInterfaceReference(
  371. IN PMASTER_EXTENSION Extension
  372. );
  373. VOID
  374. AgpInterfaceDereference(
  375. IN PMASTER_EXTENSION Extension
  376. );
  377. NTSTATUS
  378. AgpInterfaceReserveMemory(
  379. IN PMASTER_EXTENSION Extension,
  380. IN ULONG NumberOfPages,
  381. IN MEMORY_CACHING_TYPE MemoryType,
  382. OUT PVOID *MapHandle,
  383. OUT OPTIONAL PHYSICAL_ADDRESS *PhysicalAddress
  384. );
  385. NTSTATUS
  386. AgpInterfaceReleaseMemory(
  387. IN PMASTER_EXTENSION Extension,
  388. IN PVOID MapHandle
  389. );
  390. NTSTATUS
  391. AgpInterfaceCommitMemory(
  392. IN PMASTER_EXTENSION Extension,
  393. IN PVOID MapHandle,
  394. IN ULONG NumberOfPages,
  395. IN ULONG OffsetInPages,
  396. IN OUT PMDL Mdl OPTIONAL,
  397. OUT PHYSICAL_ADDRESS *MemoryBase
  398. );
  399. NTSTATUS
  400. AgpInterfaceFreeMemory(
  401. IN PMASTER_EXTENSION Extension,
  402. IN PVOID MapHandle,
  403. IN ULONG NumberOfPages,
  404. IN ULONG OffsetInPages
  405. );
  406. NTSTATUS
  407. AgpInterfaceGetMappedPages(
  408. IN PMASTER_EXTENSION Extension,
  409. IN PVOID MapHandle,
  410. IN ULONG NumberOfPages,
  411. IN ULONG OffsetInPages,
  412. OUT PMDL Mdl
  413. );
  414. //
  415. // Misc utils.c
  416. //
  417. BOOLEAN
  418. AgpOpenKey(
  419. IN PWSTR KeyName,
  420. IN HANDLE ParentHandle,
  421. OUT PHANDLE Handle,
  422. OUT PNTSTATUS Status
  423. );
  424. BOOLEAN
  425. AgpStringToUSHORT(
  426. IN PWCHAR String,
  427. OUT PUSHORT Result
  428. );
  429. ULONGLONG
  430. AgpGetDeviceFlags(
  431. IN PAGP_HACK_TABLE_ENTRY AgpHackTable,
  432. IN USHORT VendorID,
  433. IN USHORT DeviceID,
  434. IN USHORT SubVendorID,
  435. IN USHORT SubSystemID,
  436. IN UCHAR RevisionID
  437. );
  438. ULONG_PTR
  439. AgpExecuteCriticalSystemRoutine(
  440. IN ULONG_PTR Context
  441. );
  442. //
  443. // wmi.c
  444. //
  445. NTSTATUS
  446. AgpSystemControl(
  447. IN PDEVICE_OBJECT DeviceObject,
  448. IN PIRP Irp
  449. );
  450. NTSTATUS
  451. AgpWmiRegistration(
  452. IN PTARGET_EXTENSION Extension
  453. );
  454. NTSTATUS
  455. AgpWmiDeRegistration(
  456. IN PTARGET_EXTENSION Extension
  457. );
  458. NTSTATUS
  459. AgpSetWmiDataItem(
  460. IN PDEVICE_OBJECT DeviceObject,
  461. IN PIRP Irp,
  462. IN ULONG GuidIndex,
  463. IN ULONG InstanceIndex,
  464. IN ULONG DataItemId,
  465. IN ULONG BufferSize,
  466. IN PUCHAR Buffer
  467. );
  468. NTSTATUS
  469. AgpSetWmiDataBlock(
  470. IN PDEVICE_OBJECT DeviceObject,
  471. IN PIRP Irp,
  472. IN ULONG GuidIndex,
  473. IN ULONG InstanceIndex,
  474. IN ULONG BufferSize,
  475. IN PUCHAR Buffer
  476. );
  477. NTSTATUS
  478. AgpQueryWmiDataBlock(
  479. IN PDEVICE_OBJECT DeviceObject,
  480. IN PIRP Irp,
  481. IN ULONG GuidIndex,
  482. IN ULONG InstanceIndex,
  483. IN ULONG InstanceCount,
  484. IN OUT PULONG InstanceLengthArray,
  485. IN ULONG OutBufferSize,
  486. OUT PUCHAR Buffer
  487. );
  488. NTSTATUS
  489. AgpQueryWmiRegInfo(
  490. IN PDEVICE_OBJECT DeviceObject,
  491. OUT PULONG RegFlags,
  492. OUT PUNICODE_STRING InstanceName,
  493. OUT PUNICODE_STRING *RegistryPath,
  494. OUT PUNICODE_STRING MofResourceName,
  495. OUT PDEVICE_OBJECT *Pdo
  496. );
  497. //
  498. // AGP Physical Memory allocator
  499. //
  500. PMDL
  501. AgpLibAllocatePhysicalMemory(
  502. IN PVOID AgpContext,
  503. IN ULONG TotalBytes);
  504. //
  505. // Handy structures for mucking about in PCI config space
  506. //
  507. //
  508. // The PCI_COMMON_CONFIG includes the 192 bytes of device specific
  509. // data. The following structure is used to get only the first 64
  510. // bytes which is all we care about most of the time anyway. We cast
  511. // to PCI_COMMON_CONFIG to get at the actual fields.
  512. //
  513. typedef struct {
  514. ULONG Reserved[PCI_COMMON_HDR_LENGTH/sizeof(ULONG)];
  515. } PCI_COMMON_HEADER, *PPCI_COMMON_HEADER;