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.

529 lines
14 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. typedef struct _TARGET_EXTENSION {
  90. COMMON_EXTENSION CommonExtension;
  91. PFAST_MUTEX Lock;
  92. struct _MASTER_EXTENSION *ChildDevice;
  93. PCM_RESOURCE_LIST Resources;
  94. PCM_RESOURCE_LIST ResourcesTranslated;
  95. AGP_FAVORED_MEMORY FavoredMemory;
  96. PHYSICAL_ADDRESS GartBase;
  97. ULONG GartLengthInPages;
  98. PDEVICE_OBJECT PDO;
  99. PDEVICE_OBJECT Self;
  100. WMILIB_CONTEXT WmiLibInfo;
  101. //
  102. // This must be last, d'oh!
  103. //
  104. ULONGLONG AgpContext;
  105. } TARGET_EXTENSION, *PTARGET_EXTENSION;
  106. typedef struct _MASTER_EXTENSION {
  107. COMMON_EXTENSION CommonExtension;
  108. PTARGET_EXTENSION Target;
  109. ULONG Capabilities;
  110. ULONG InterfaceCount; // tracks the number of interfaces handed out
  111. ULONG ReservedPages; // tracks the number of pages reserved in the aperture
  112. BOOLEAN StopPending; // TRUE if we have seen a QUERY_STOP
  113. BOOLEAN RemovePending; // TRUE if we have seen a QUERY_REMOVE
  114. ULONG DisableCount; // non-zero if we are in a state where we cannot service requests
  115. } MASTER_EXTENSION, *PMASTER_EXTENSION;
  116. typedef struct _GLOBALS {
  117. //
  118. // Path to the driver's Services Key in the registry
  119. //
  120. UNICODE_STRING RegistryPath;
  121. //
  122. // Cached target capability settings
  123. //
  124. ULONG AgpStatus;
  125. ULONG AgpCommand;
  126. } GLOBALS;
  127. extern GLOBALS Globals;
  128. //
  129. // The MBAT - used to retrieve "favored" memory ranges from
  130. // the AGP northbridge via an ACPI BANK method
  131. //
  132. #include <pshpack1.h>
  133. typedef struct _MBAT
  134. {
  135. UCHAR TableVersion;
  136. UCHAR AgpBusNumber;
  137. UCHAR ValidEntryBitmap;
  138. AGP_MEMORY_RANGE DecodeRange[ANYSIZE_ARRAY];
  139. } MBAT, *PMBAT;
  140. #include <poppack.h>
  141. #define MBAT_VERSION 1
  142. #define MAX_MBAT_SIZE sizeof(MBAT) + ((sizeof(UCHAR) * 8) - ANYSIZE_ARRAY) \
  143. * sizeof(AGP_MEMORY_RANGE)
  144. #define CM_BANK_METHOD (ULONG)('KNAB')
  145. //
  146. // The highest memory address supported by AGP
  147. //
  148. #define MAX_MEM(_num_) _num_ = 1; \
  149. _num_ = _num_*1024*1024*1024*4 - 1
  150. #define RELEASE_BUS_INTERFACE(_ext_) (_ext_)->CommonExtension.BusInterface.InterfaceDereference((_ext_)->CommonExtension.BusInterface.Context)
  151. //
  152. // Macros for getting from the chipset-specific context to our structures
  153. //
  154. #define GET_TARGET_EXTENSION(_target_,_agp_context_) (_target_) = (CONTAINING_RECORD((_agp_context_), \
  155. TARGET_EXTENSION, \
  156. AgpContext)); \
  157. ASSERT_TARGET(_target_)
  158. #define GET_MASTER_EXTENSION(_master_,_agp_context_) { \
  159. PTARGET_EXTENSION _targetext_; \
  160. GET_TARGET_EXTENSION(_targetext_, (_agp_context_)); \
  161. (_master_) = _targetext_->ChildDevice; \
  162. ASSERT_MASTER(_master_); \
  163. }
  164. #define GET_TARGET_PDO(_pdo_,_agp_context_) { \
  165. PTARGET_EXTENSION _targetext_; \
  166. GET_TARGET_EXTENSION(_targetext_,(_agp_context_)); \
  167. (_pdo_) = _targetext_->CommonExtension.AttachedDevice; \
  168. }
  169. #define GET_MASTER_PDO(_pdo_,_agp_context_) { \
  170. PMASTER_EXTENSION _masterext_; \
  171. GET_MASTER_EXTENSION(_masterext_, (_agp_context_)); \
  172. (_pdo_) = _masterext_->CommonExtension.AttachedDevice; \
  173. }
  174. #define GET_AGP_CONTEXT(_targetext_) ((PVOID)(&(_targetext_)->AgpContext))
  175. #define GET_AGP_CONTEXT_FROM_MASTER(_masterext_) GET_AGP_CONTEXT((_masterext_)->Target)
  176. //
  177. // Some debugging macros
  178. //
  179. #define ASSERT_TARGET(_target_) ASSERT((_target_)->CommonExtension.Signature == TARGET_SIG); \
  180. ASSERT((_target_)->ChildDevice->CommonExtension.Signature == MASTER_SIG)
  181. #define ASSERT_MASTER(_master_) ASSERT((_master_)->CommonExtension.Signature == MASTER_SIG); \
  182. ASSERT((_master_)->Target->CommonExtension.Signature == TARGET_SIG)
  183. //
  184. // Locking macros
  185. //
  186. #define LOCK_MUTEX(_fm_) ExAcquireFastMutex(_fm_); \
  187. ASSERT((_fm_)->Count == 0)
  188. #define UNLOCK_MUTEX(_fm_) ASSERT((_fm_)->Count == 0); \
  189. ExReleaseFastMutex(_fm_)
  190. #define LOCK_TARGET(_targetext_) ASSERT_TARGET(_targetext_); \
  191. LOCK_MUTEX((_targetext_)->Lock)
  192. #define LOCK_MASTER(_masterext_) ASSERT_MASTER(_masterext_); \
  193. LOCK_MUTEX((_masterext_)->Target->Lock)
  194. #define UNLOCK_TARGET(_targetext_) ASSERT_TARGET(_targetext_); \
  195. UNLOCK_MUTEX((_targetext_)->Lock)
  196. #define UNLOCK_MASTER(_masterext_) ASSERT_MASTER(_masterext_); \
  197. UNLOCK_MUTEX((_masterext_)->Target->Lock)
  198. //
  199. // Private resource type definition
  200. //
  201. typedef enum {
  202. AgpPrivateResource = '0PGA'
  203. } AGP_PRIVATE_RESOURCE_TYPES;
  204. //
  205. // Define function prototypes
  206. //
  207. //
  208. // Driver and device initialization - init.c
  209. //
  210. NTSTATUS
  211. AgpAttachDeviceRelations(
  212. IN PDEVICE_OBJECT DeviceObject,
  213. IN PIRP Irp,
  214. IN PTARGET_EXTENSION Extension
  215. );
  216. //
  217. // IRP Dispatch routines - dispatch.c
  218. //
  219. NTSTATUS
  220. AgpDispatchPnp(
  221. IN PDEVICE_OBJECT DeviceObject,
  222. IN OUT PIRP Irp
  223. );
  224. NTSTATUS
  225. AgpDispatchPower(
  226. IN PDEVICE_OBJECT DeviceObject,
  227. IN OUT PIRP Irp
  228. );
  229. NTSTATUS
  230. AgpDispatchDeviceControl(
  231. IN PDEVICE_OBJECT DeviceObject,
  232. IN OUT PIRP Irp
  233. );
  234. NTSTATUS
  235. AgpDispatchWmi(
  236. IN PDEVICE_OBJECT DeviceObject,
  237. IN OUT PIRP Irp
  238. );
  239. NTSTATUS
  240. AgpSetEventCompletion(
  241. IN PDEVICE_OBJECT DeviceObject,
  242. IN PIRP Irp,
  243. IN PKEVENT Event
  244. );
  245. //
  246. // Config space handling routines - config.c
  247. //
  248. NTSTATUS
  249. ApQueryBusInterface(
  250. IN PDEVICE_OBJECT DeviceObject,
  251. OUT PBUS_INTERFACE_STANDARD BusInterface
  252. );
  253. //
  254. // Resource handing routines - resource.c
  255. //
  256. NTSTATUS
  257. AgpFilterResourceRequirements(
  258. IN PDEVICE_OBJECT DeviceObject,
  259. IN PIRP Irp,
  260. IN PTARGET_EXTENSION Extension
  261. );
  262. NTSTATUS
  263. AgpQueryResources(
  264. IN PDEVICE_OBJECT DeviceObject,
  265. IN PIRP Irp,
  266. IN PTARGET_EXTENSION Extension
  267. );
  268. NTSTATUS
  269. AgpStartTarget(
  270. IN PIRP Irp,
  271. IN PTARGET_EXTENSION Extension
  272. );
  273. VOID
  274. AgpStopTarget(
  275. IN PTARGET_EXTENSION Extension
  276. );
  277. //
  278. // AGP Interface functions
  279. //
  280. NTSTATUS
  281. AgpInterfaceSetRate(
  282. IN PMASTER_EXTENSION Extension,
  283. IN ULONG AgpRate
  284. );
  285. VOID
  286. AgpInterfaceReference(
  287. IN PMASTER_EXTENSION Extension
  288. );
  289. VOID
  290. AgpInterfaceDereference(
  291. IN PMASTER_EXTENSION Extension
  292. );
  293. NTSTATUS
  294. AgpInterfaceReserveMemory(
  295. IN PMASTER_EXTENSION Extension,
  296. IN ULONG NumberOfPages,
  297. IN MEMORY_CACHING_TYPE MemoryType,
  298. OUT PVOID *MapHandle,
  299. OUT OPTIONAL PHYSICAL_ADDRESS *PhysicalAddress
  300. );
  301. NTSTATUS
  302. AgpInterfaceReleaseMemory(
  303. IN PMASTER_EXTENSION Extension,
  304. IN PVOID MapHandle
  305. );
  306. NTSTATUS
  307. AgpInterfaceCommitMemory(
  308. IN PMASTER_EXTENSION Extension,
  309. IN PVOID MapHandle,
  310. IN ULONG NumberOfPages,
  311. IN ULONG OffsetInPages,
  312. IN OUT PMDL Mdl OPTIONAL,
  313. OUT PHYSICAL_ADDRESS *MemoryBase
  314. );
  315. NTSTATUS
  316. AgpInterfaceFreeMemory(
  317. IN PMASTER_EXTENSION Extension,
  318. IN PVOID MapHandle,
  319. IN ULONG NumberOfPages,
  320. IN ULONG OffsetInPages
  321. );
  322. NTSTATUS
  323. AgpInterfaceGetMappedPages(
  324. IN PMASTER_EXTENSION Extension,
  325. IN PVOID MapHandle,
  326. IN ULONG NumberOfPages,
  327. IN ULONG OffsetInPages,
  328. OUT PMDL Mdl
  329. );
  330. //
  331. // Misc utils.c
  332. //
  333. BOOLEAN
  334. AgpOpenKey(
  335. IN PWSTR KeyName,
  336. IN HANDLE ParentHandle,
  337. OUT PHANDLE Handle,
  338. OUT PNTSTATUS Status
  339. );
  340. BOOLEAN
  341. AgpStringToUSHORT(
  342. IN PWCHAR String,
  343. OUT PUSHORT Result
  344. );
  345. ULONGLONG
  346. AgpGetDeviceFlags(
  347. IN PAGP_HACK_TABLE_ENTRY AgpHackTable,
  348. IN USHORT VendorID,
  349. IN USHORT DeviceID,
  350. IN USHORT SubVendorID,
  351. IN USHORT SubSystemID,
  352. IN UCHAR RevisionID
  353. );
  354. ULONG_PTR
  355. AgpExecuteCriticalSystemRoutine(
  356. IN ULONG_PTR Context
  357. );
  358. //
  359. // wmi.c
  360. //
  361. NTSTATUS
  362. AgpSystemControl(
  363. IN PDEVICE_OBJECT DeviceObject,
  364. IN PIRP Irp
  365. );
  366. NTSTATUS
  367. AgpWmiRegistration(
  368. IN PTARGET_EXTENSION Extension
  369. );
  370. NTSTATUS
  371. AgpWmiDeRegistration(
  372. IN PTARGET_EXTENSION Extension
  373. );
  374. NTSTATUS
  375. AgpSetWmiDataItem(
  376. IN PDEVICE_OBJECT DeviceObject,
  377. IN PIRP Irp,
  378. IN ULONG GuidIndex,
  379. IN ULONG InstanceIndex,
  380. IN ULONG DataItemId,
  381. IN ULONG BufferSize,
  382. IN PUCHAR Buffer
  383. );
  384. NTSTATUS
  385. AgpSetWmiDataBlock(
  386. IN PDEVICE_OBJECT DeviceObject,
  387. IN PIRP Irp,
  388. IN ULONG GuidIndex,
  389. IN ULONG InstanceIndex,
  390. IN ULONG BufferSize,
  391. IN PUCHAR Buffer
  392. );
  393. NTSTATUS
  394. AgpQueryWmiDataBlock(
  395. IN PDEVICE_OBJECT DeviceObject,
  396. IN PIRP Irp,
  397. IN ULONG GuidIndex,
  398. IN ULONG InstanceIndex,
  399. IN ULONG InstanceCount,
  400. IN OUT PULONG InstanceLengthArray,
  401. IN ULONG OutBufferSize,
  402. OUT PUCHAR Buffer
  403. );
  404. NTSTATUS
  405. AgpQueryWmiRegInfo(
  406. IN PDEVICE_OBJECT DeviceObject,
  407. OUT PULONG RegFlags,
  408. OUT PUNICODE_STRING InstanceName,
  409. OUT PUNICODE_STRING *RegistryPath,
  410. OUT PUNICODE_STRING MofResourceName,
  411. OUT PDEVICE_OBJECT *Pdo
  412. );
  413. //
  414. // AGP Physical Memory allocator
  415. //
  416. PMDL
  417. AgpLibAllocatePhysicalMemory(
  418. IN PVOID AgpContext,
  419. IN ULONG TotalBytes);
  420. //
  421. // Handy structures for mucking about in PCI config space
  422. //
  423. //
  424. // The PCI_COMMON_CONFIG includes the 192 bytes of device specific
  425. // data. The following structure is used to get only the first 64
  426. // bytes which is all we care about most of the time anyway. We cast
  427. // to PCI_COMMON_CONFIG to get at the actual fields.
  428. //
  429. typedef struct {
  430. ULONG Reserved[PCI_COMMON_HDR_LENGTH/sizeof(ULONG)];
  431. } PCI_COMMON_HEADER, *PPCI_COMMON_HEADER;