PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Kernel/Singularity/Io/PciConfig.cs

#
C# | 1262 lines | 1015 code | 170 blank | 77 comment | 106 complexity | df31910d9466772e741fa98277c06e71 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // File: PciConfig.cs
  8. //
  9. // Note:
  10. //
  11. #define DEBUG_PCI
  12. using System;
  13. using StringBuilder = System.Text.StringBuilder;
  14. using System.Collections;
  15. using Microsoft.Singularity;
  16. #if !SINGULARITY_PROCESS
  17. using Microsoft.Singularity.Hal;
  18. #endif
  19. namespace Microsoft.Singularity.Io
  20. {
  21. [CLSCompliant(false)]
  22. public class PciConfig : IoConfig
  23. {
  24. //
  25. // Bit encodings for PCI_COMMON_CONFIG.HeaderType
  26. //
  27. public const uint PCI_MULTIFUNCTION = 0x800000; // full dword
  28. public const uint PCI_TYPE_MASK = 0x7f0000; // full dword
  29. public const uint PCI_DEVICE_TYPE = 0x000000; // full dword
  30. public const uint PCI_BRIDGE_TYPE = 0x010000; // full dword
  31. public const uint PCI_CARDBUS_TYPE = 0x020000; // full dword
  32. private const int PCI_CONTROL_OFFSET = 0x0004;
  33. private const int PCI_STATUS_OFFSET = 0x0006;
  34. //
  35. // Bit encodings for PCI_COMMON_CONFIG.Control
  36. //
  37. public const uint PCI_ENABLE_IO_SPACE = 0x0001;
  38. public const uint PCI_ENABLE_MEMORY_SPACE = 0x0002;
  39. public const uint PCI_ENABLE_BUS_MASTER = 0x0004;
  40. public const uint PCI_ENABLE_SPECIAL_CYCLES = 0x0008;
  41. public const uint PCI_ENABLE_WRITE_AND_INVALIDATE = 0x0010;
  42. public const uint PCI_ENABLE_VGA_COMPATIBLE_PALETTE = 0x0020;
  43. public const uint PCI_ENABLE_PARITY = 0x0040; // (ro+)
  44. public const uint PCI_ENABLE_WAIT_CYCLE = 0x0080; // (ro+)
  45. public const uint PCI_ENABLE_SERR = 0x0100; // (ro+)
  46. public const uint PCI_ENABLE_FAST_BACK_TO_BACK = 0x0200; // (ro)
  47. public const uint PCI_DISABLE_INTERRUPTS = 0x0400;
  48. //
  49. // Bit encodings for PCI_COMMON_CONFIG.Status
  50. //
  51. const uint PCI_STATUS_FAST_BACK_TO_BACK = 0x0080; // (ro)
  52. const uint PCI_STATUS_DATA_PARITY_DETECTED = 0x0100;
  53. const uint PCI_STATUS_DEVSEL = 0x0600; // 2 bits wide
  54. const uint PCI_STATUS_SIGNALED_TARGET_ABORT = 0x0800;
  55. const uint PCI_STATUS_RECEIVED_TARGET_ABORT = 0x1000;
  56. const uint PCI_STATUS_RECEIVED_MASTER_ABORT = 0x2000;
  57. const uint PCI_STATUS_SIGNALED_SYSTEM_ERROR = 0x4000;
  58. const uint PCI_STATUS_DETECTED_PARITY_ERROR = 0x8000;
  59. // Bit encodes for PCI_COMMON_CONFIG.u.type0.BaseAddresses
  60. //
  61. const uint PCI_BAR_TYPE_MASK = 0xf;
  62. const uint PCI_BAR_TYPE_IO = 0x1;
  63. const uint PCI_BAR_TYPE_MEM20 = 0x2;
  64. const uint PCI_BAR_TYPE_MEM32 = 0x0;
  65. const uint PCI_BAR_TYPE_MEM64 = 0x4;
  66. const uint PCI_BAR_TYPE_MEMMASK = 0x6;
  67. const uint PCI_BAR_TYPE_PREFETCH = 0x8;
  68. const uint PCI_ROMADDRESS_ENABLED = 0x00000001;
  69. const uint PCI_ENABLE_BRIDGE_PARITY_ERROR = 0x0001;
  70. const uint PCI_ENABLE_BRIDGE_SERR = 0x0002;
  71. const uint PCI_ENABLE_BRIDGE_ISA = 0x0004;
  72. const uint PCI_ENABLE_BRIDGE_VGA = 0x0008;
  73. const uint PCI_ENABLE_BRIDGE_MASTER_ABORT_SERR = 0x0020;
  74. const uint PCI_ASSERT_BRIDGE_RESET = 0x0040;
  75. const uint PCI_ENABLE_BRIDGE_FAST_BACK_TO_BACK = 0x0080;
  76. const byte PCI_CLASS_STORAGE = 0x01;
  77. const byte PCI_CLASS_NETWORK = 0x02;
  78. const byte PCI_CLASS_DISPLAY = 0x03;
  79. const byte PCI_CLASS_MULTIMEDIA = 0x04;
  80. const byte PCI_CLASS_MEMORY = 0x05;
  81. const byte PCI_CLASS_BRIDGE = 0x06;
  82. const byte PCI_CLASS_COMMUNICATION = 0x07;
  83. const byte PCI_CLASS_SYSTEM = 0x08;
  84. const byte PCI_CLASS_INPUT = 0x09;
  85. const byte PCI_CLASS_DOCKING = 0x0a;
  86. const byte PCI_CLASS_PROCESSOR = 0x0b;
  87. const byte PCI_CLASS_SERIAL = 0x0c;
  88. const byte PCI_CLASS_WIRELESS = 0x0d;
  89. const byte PCI_CLASS_I2O = 0x0e;
  90. const byte PCI_CLASS_SATELLITE = 0x0f;
  91. const byte PCI_CLASS_ENCRYPTION = 0x10;
  92. const byte PCI_CLASS_ACQUISITION = 0x11;
  93. const byte PCI_CLASS_OTHERS = 0xff;
  94. const byte PCI_CLASS_STORAGE_SCSI = 0x00;
  95. const byte PCI_CLASS_STORAGE_IDE = 0x01; // NB: Interface
  96. const byte PCI_CLASS_STORAGE_FLOPPY = 0x02;
  97. const byte PCI_CLASS_STORAGE_IPI = 0x03;
  98. const byte PCI_CLASS_STORAGE_RAID = 0x04;
  99. const byte PCI_CLASS_STORAGE_ATA = 0x05; // NB: Interface
  100. const byte PCI_CLASS_STORAGE_OTHER = 0x80;
  101. const byte PCI_CLASS_NETWORK_ETHERNET = 0x00;
  102. const byte PCI_CLASS_NETWORK_RING = 0x01;
  103. const byte PCI_CLASS_NETWORK_FDDI = 0x02;
  104. const byte PCI_CLASS_NETWORK_ATM = 0x03;
  105. const byte PCI_CLASS_NETWORK_ISDN = 0x04;
  106. const byte PCI_CLASS_NETWORK_FIP = 0x05;
  107. const byte PCI_CLASS_NETWORK_PICMG = 0x06; // NB: Interface
  108. const byte PCI_CLASS_NETWORK_OTHER = 0x80;
  109. const byte PCI_CLASS_DISPLAY_VGA = 0x00; // NB: Interface
  110. const byte PCI_CLASS_DISPLAY_XGA = 0x01;
  111. const byte PCI_CLASS_DISPLAY_3D = 0x02;
  112. const byte PCI_CLASS_DISPLAY_OTHER = 0x80;
  113. const byte PCI_CLASS_MULTIMEDIA_VIDEO = 0x00;
  114. const byte PCI_CLASS_MULTIMEDIA_AUDIO = 0x01;
  115. const byte PCI_CLASS_MULTIMEDIA_TELEPHONY = 0x02;
  116. const byte PCI_CLASS_MULTIMEDIA_OTHER = 0x80;
  117. const byte PCI_CLASS_MEMORY_RAM = 0x00;
  118. const byte PCI_CLASS_MEMORY_FLASH = 0x01;
  119. const byte PCI_CLASS_MEMORY_OTHER = 0x80;
  120. const byte PCI_CLASS_BRIDGE_HOST = 0x00;
  121. const byte PCI_CLASS_BRIDGE_ISA = 0x01;
  122. const byte PCI_CLASS_BRIDGE_EISA = 0x02;
  123. const byte PCI_CLASS_BRIDGE_MC = 0x03;
  124. const byte PCI_CLASS_BRIDGE_PCI = 0x04; // NB: Interface
  125. const byte PCI_CLASS_BRIDGE_PCMCIA = 0x05;
  126. const byte PCI_CLASS_BRIDGE_NUBUS = 0x06;
  127. const byte PCI_CLASS_BRIDGE_CARDBUS = 0x07;
  128. const byte PCI_CLASS_BRIDGE_RACEWAY = 0x08; // NB: Interface
  129. const byte PCI_CLASS_BRIDGE_SEMIPCI = 0x09; // NB: Interface
  130. const byte PCI_CLASS_BRIDGE_INFINIBAND = 0x0a;
  131. const byte PCI_CLASS_BRIDGE_OTHER = 0x80;
  132. const byte PCI_CLASS_COMMUNICATION_SERIAL = 0x00; // NB: Interface
  133. const byte PCI_CLASS_COMMUNICATION_PARALLEL = 0x01; // NB: Interface
  134. const byte PCI_CLASS_COMMUNICATION_MULTIPORT = 0x02;
  135. const byte PCI_CLASS_COMMUNICATION_MODEM = 0x03; // NB: Interface
  136. const byte PCI_CLASS_COMMUNICATION_GPIB = 0x04;
  137. const byte PCI_CLASS_COMMUNICATION_SMARTCARD = 0x05;
  138. const byte PCI_CLASS_COMMUNICATION_OTHER = 0x80;
  139. const byte PCI_CLASS_SYSTEM_PIC = 0x00; // NB: Interface
  140. const byte PCI_CLASS_SYSTEM_DMA = 0x01; // NB: Interface
  141. const byte PCI_CLASS_SYSTEM_TIMER = 0x02; // NB: Interface
  142. const byte PCI_CLASS_SYSTEM_RTC = 0x03; // NB: Interface
  143. const byte PCI_CLASS_SYSTEM_PCIHP = 0x04;
  144. const byte PCI_CLASS_SYSTEM_OTHER = 0x80;
  145. const byte PCI_CLASS_INPUT_KEYBOARD = 0x00;
  146. const byte PCI_CLASS_INPUT_PEN = 0x01;
  147. const byte PCI_CLASS_INPUT_MOUSE = 0x02;
  148. const byte PCI_CLASS_INPUT_SCANNER = 0x03;
  149. const byte PCI_CLASS_INPUT_GAMEPORT = 0x04; // NB: Interface
  150. const byte PCI_CLASS_INPUT_OTHER = 0x80;
  151. const byte PCI_CLASS_SERIAL_FIREWIRE = 0x00; // NB: Interface
  152. const byte PCI_CLASS_SERIAL_ACCESS = 0x01;
  153. const byte PCI_CLASS_SERIAL_SSA = 0x02;
  154. const byte PCI_CLASS_SERIAL_USB = 0x03; // NB: Interface
  155. const byte PCI_CLASS_SERIAL_FIBRE = 0x04;
  156. const byte PCI_CLASS_SERIAL_SMBUS = 0x05;
  157. const byte PCI_CLASS_SERIAL_INFINIBAND = 0x06;
  158. const byte PCI_CLASS_SERIAL_IPMI = 0x07; // NB: Interface
  159. const byte PCI_CLASS_SERIAL_SERCOS = 0x08;
  160. const byte PCI_CLASS_SERIAL_CANBUS = 0x09;
  161. const byte PCI_CLASS_WIRELESS_IRDA = 0x00;
  162. const byte PCI_CLASS_WIRELESS_IR = 0x01;
  163. const byte PCI_CLASS_WIRELESS_RF = 0x10;
  164. const byte PCI_CLASS_WIRELESS_BLUETOOTH = 0x11;
  165. const byte PCI_CLASS_WIRELESS_BROADBAND = 0x12;
  166. const byte PCI_CLASS_WIRELESS_OTHER = 0x80;
  167. const byte PCI_CLASS_I2O_I2O = 0x00; // NB: Interface
  168. const byte PCI_CLASS_SATELLITE_TV = 0x01;
  169. const byte PCI_CLASS_SATELLITE_AUDIO = 0x02;
  170. const byte PCI_CLASS_SATELLITE_VOICE = 0x03;
  171. const byte PCI_CLASS_SATELLITE_DATA = 0x04;
  172. const byte PCI_CLASS_ENCRYPTION_NETWORK = 0x00;
  173. const byte PCI_CLASS_ENCRYPTION_ENTERTAINMENT = 0x10;
  174. const byte PCI_CLASS_ENCRYPTION_OTHER = 0x80;
  175. const byte PCI_CLASS_ACQUISITION_DPIO = 0x00;
  176. const byte PCI_CLASS_ACQUISITION_PERF = 0x01;
  177. const byte PCI_CLASS_ACQUISITION_COMM = 0x10;
  178. const byte PCI_CLASS_ACQUISITION_MGMT = 0x20;
  179. const byte PCI_CLASS_ACQUISITION_OTHER = 0x80;
  180. const int PCI_INTERRUPT_LINE = 0x3c;
  181. const int PCI_INTERRUPT_PIN = 0x3d;
  182. const byte PCI_INTERRUPT_PIN_A = 1;
  183. const byte PCI_INTERRUPT_PIN_B = 2;
  184. const byte PCI_INTERRUPT_PIN_C = 3;
  185. const byte PCI_INTERRUPT_PIN_D = 4;
  186. protected PciPort port;
  187. public ushort VendorId; // 00..01 (ro)
  188. public ushort DeviceId; // 02..03 (ro)
  189. protected byte RevisionId; // 08..08 (ro)
  190. public byte Interface; // 09..09 (ro)
  191. protected byte SubClassId; // 0a..0a (ro)
  192. protected byte ClassId; // 0b..0b (ro)
  193. public byte CacheLineSize; // 0c..0c (ro+)
  194. protected byte LatencyTimer; // 0d..0d (ro+)
  195. protected byte HeaderType; // 0e..0e (ro)
  196. protected byte BIST; // 0f..0f Built in self test
  197. protected ulong[] BaseAddresses; // 10..17 or ..27 [2 or 6]
  198. protected ulong[] BaseAddrSizes;
  199. protected ushort SubsystemVendorId; // 2c..2d (devices only)
  200. protected ushort SubsystemDeviceId; // 2e..2f (devices only)
  201. protected uint ROMBaseAddress; // 38..3b or 30.33
  202. protected byte InterruptPin; // 3d..3d
  203. public static PciConfig Create(String[] ids, PciPort port,
  204. IoRange [] fixedRanges)
  205. {
  206. uint u = port.Read32(0);
  207. if (u == ~0u || u == 0) {
  208. return null;
  209. }
  210. PciConfig config = null;
  211. u = port.Read32(0x0c);
  212. switch (u & PciConfig.PCI_TYPE_MASK) {
  213. case PciConfig.PCI_DEVICE_TYPE:
  214. config = new PciDeviceConfig(port);
  215. break;
  216. case PciConfig.PCI_BRIDGE_TYPE:
  217. config = new PciBridgeConfig(port);
  218. break;
  219. case PciConfig.PCI_CARDBUS_TYPE:
  220. config = new PciCardbusConfig(port);
  221. break;
  222. }
  223. if (config != null) {
  224. config.FixedRanges = fixedRanges;
  225. }
  226. return config;
  227. }
  228. internal PciConfig(String[] ids, PciPort port)
  229. {
  230. this.port = port;
  231. this.Read();
  232. this.Ids = ids;
  233. }
  234. public PciConfig(PciPort port)
  235. {
  236. this.port = port;
  237. }
  238. public PciPort PciPort
  239. {
  240. get { return this.port; }
  241. }
  242. public IoIrqRange GetIrq()
  243. {
  244. return new IoIrqRange(InterruptLine, 1);
  245. }
  246. public void SetInterrupt(byte irq)
  247. {
  248. Write8(PCI_INTERRUPT_LINE, irq);
  249. }
  250. public byte InterruptLine
  251. {
  252. get { return Read8(PCI_INTERRUPT_LINE); }
  253. }
  254. public ushort Control
  255. {
  256. get { return Read16(PCI_CONTROL_OFFSET); }
  257. set { Write16(PCI_CONTROL_OFFSET, value); }
  258. }
  259. public ushort Status
  260. {
  261. get { return Read16(PCI_STATUS_OFFSET); }
  262. set { Write16(PCI_STATUS_OFFSET, value); }
  263. }
  264. public bool IoSpaceEnabled
  265. {
  266. get { return ((uint)Control & PCI_ENABLE_IO_SPACE) != 0; }
  267. set {
  268. uint tmp = (uint)Control & ~PCI_ENABLE_IO_SPACE;
  269. if (value) {
  270. tmp |= PCI_ENABLE_IO_SPACE;
  271. }
  272. Control = (ushort)(tmp & 0xffff);
  273. }
  274. }
  275. public bool MemorySpaceEnabled
  276. {
  277. get { return ((uint)Control & PCI_ENABLE_MEMORY_SPACE) != 0; }
  278. set {
  279. uint tmp = (uint)Control & ~PCI_ENABLE_MEMORY_SPACE;
  280. if (value) {
  281. tmp |= PCI_ENABLE_MEMORY_SPACE;
  282. }
  283. Control = (ushort)(tmp & 0xffff);
  284. }
  285. }
  286. public bool InterruptsEnabled
  287. {
  288. get { return ((uint)Control & PCI_DISABLE_INTERRUPTS) == 0; }
  289. set {
  290. uint tmp = (uint)Control & ~PCI_DISABLE_INTERRUPTS;
  291. if (!value) {
  292. tmp |= PCI_ENABLE_MEMORY_SPACE;
  293. }
  294. Control = (ushort)(tmp & 0xffff);
  295. }
  296. }
  297. ///////////////////////////////////////////////////////////////////////
  298. //
  299. // Port operations
  300. //
  301. public ulong Read64(int offset)
  302. {
  303. ulong hi = Read32(offset + 4);
  304. return (hi << 32) | (ulong)Read32(offset);
  305. }
  306. public void Write64(int offset, ulong value)
  307. {
  308. Write32(offset + 4, (uint)(value >> 32));
  309. Write32(offset, (uint)(value & 0xffffffff));
  310. }
  311. public uint Read32(int offset) {
  312. return port.Read32(offset);
  313. }
  314. public void Write32(int offset, uint value) {
  315. port.Write32(offset, value);
  316. }
  317. public ushort Read16(int offset) {
  318. return port.Read16(offset);
  319. }
  320. public void Write16(int offset, ushort value) {
  321. port.Write16(offset, value);
  322. }
  323. public byte Read8(int offset) {
  324. return port.Read8(offset);
  325. }
  326. public void Write8(int offset, byte value) {
  327. port.Write8(offset, value);
  328. }
  329. ///////////////////////////////////////////////////////////////////////
  330. protected virtual void Read()
  331. {
  332. uint u;
  333. u = Read32(0x00);
  334. VendorId = (ushort)(u & 0xffff);
  335. DeviceId = (ushort)((u >> 16) & 0xffff);
  336. u = Read32(0x08);
  337. RevisionId = (byte)(u & 0xff);
  338. Interface = (byte)((u >> 8) & 0xff);
  339. SubClassId = (byte)((u >> 16) & 0xff);
  340. ClassId = (byte)((u >> 24) & 0xff);
  341. u = Read32(0x0c);
  342. CacheLineSize = (byte)(u & 0xff);
  343. LatencyTimer = (byte)((u >> 8) & 0xff);
  344. HeaderType = (byte)((u >> 16) & 0xff);
  345. BIST = (byte)((u >> 24) & 0xff);
  346. this.Ids = GetIds();
  347. }
  348. /// <summary>
  349. /// <para>
  350. /// Builds the list of device IDs for this PCI device. We generate the same
  351. /// strings that Windows uses for its hardware IDs and compatible IDs.
  352. /// The order is significant; the PNP manager will search the device IDs,
  353. /// one by one, for a device driver that matches. The list is ordered from
  354. /// most specific to least specific.
  355. /// </para>
  356. ///
  357. /// <para>
  358. /// WDM "hardware IDs":
  359. /// PCI\VEN_xxxy&amp;DEV_yyyy&amp;SUBSYS_zzzzzzzz&amp;REV_rr
  360. /// PCI\VEN_xxxy&amp;DEV_yyyy&amp;SUBSYS_zzzzzzzz
  361. /// PCI\VEN_xxxy&amp;DEV_yyyy&amp;CC_ccssii
  362. /// PCI\VEN_xxxy&amp;DEV_yyyy&amp;CC_ccss
  363. /// PCI\VEN_xxxy
  364. /// </para>
  365. ///
  366. /// <para>
  367. /// WDM "compatible IDs":
  368. /// PCI\VEN_xxxy&amp;DEV_yyyy&amp;REV_rr
  369. /// PCI\VEN_xxxy&amp;DEV_yyyy
  370. /// PCI\VEN_xxxx&amp;CC_ccssii
  371. /// PCI\VEN_xxxx&amp;CC_ccss
  372. /// PCI\CC_ccssii
  373. /// PCI\CC_ccss
  374. /// </para>
  375. /// </summary>
  376. /// <returns>
  377. /// An array containing the device IDs. The list is ordered from most specific
  378. /// to least specific.
  379. /// </returns>
  380. public string[] GetIds()
  381. {
  382. const string pci_prefix = @"PCI/";
  383. const string and = "&";
  384. string id_classcode = "CC_" + ByteToHex(this.ClassId) + ByteToHex(this.SubClassId);
  385. string id_classcode_interface = id_classcode + ByteToHex(this.Interface);
  386. string id_vendor = "VEN_" + UInt16ToHex(this.VendorId);
  387. string id_device = "DEV_" + UInt16ToHex(this.DeviceId);
  388. string id_vendor_device = id_vendor + and + id_device;
  389. string id_revision = "REV_" + ByteToHex(this.RevisionId);
  390. string id_subsys = "SUBSYS_" + UInt16ToHex(this.SubsystemVendorId) + UInt16ToHex(this.SubsystemDeviceId);
  391. #if ENABLE_OLD_SIGNATURE
  392. string sing_id = String.Format("/pci/{0,2:x2}/{1,2:x2}/{2,4:x4}/{3,4:x4}/" +
  393. "{4,2:x2}",
  394. ClassId,
  395. SubClassId,
  396. VendorId,
  397. DeviceId,
  398. RevisionId);
  399. #endif
  400. string[] ids = {
  401. #if ENABLE_OLD_SIGNATURE
  402. sing_id,
  403. #endif
  404. // Hardware IDs
  405. pci_prefix + id_vendor_device + and + id_classcode
  406. + and + id_subsys + and + id_revision,
  407. pci_prefix + id_vendor_device + and + id_subsys + and + id_revision,
  408. pci_prefix + id_vendor_device + and + id_subsys,
  409. pci_prefix + id_vendor_device + and + id_classcode_interface,
  410. pci_prefix + id_vendor_device + and + id_classcode,
  411. pci_prefix + id_vendor,
  412. // Compatible IDs
  413. pci_prefix + id_vendor_device + and + id_revision,
  414. pci_prefix + id_vendor_device,
  415. pci_prefix + id_vendor + and + id_classcode_interface,
  416. pci_prefix + id_vendor + and + id_classcode,
  417. pci_prefix + id_classcode_interface,
  418. pci_prefix + id_classcode,
  419. };
  420. for (int i = 0; i < ids.Length; i++) {
  421. string id = ids[i];
  422. id = id.Replace('\\', '/').ToLower();
  423. ids[i] = id;
  424. }
  425. return ids;
  426. }
  427. static string ByteToHex(byte value)
  428. {
  429. StringBuilder sb = new StringBuilder(2);
  430. sb.Append(HexDigits[value >> 4]);
  431. sb.Append(HexDigits[value & 0xf]);
  432. return sb.ToString();
  433. }
  434. static string UInt16ToHex(ushort value)
  435. {
  436. StringBuilder sb = new StringBuilder(4);
  437. sb.Append(HexDigits[(value >> 12) & 0xf]);
  438. sb.Append(HexDigits[(value >> 8) & 0xf]);
  439. sb.Append(HexDigits[(value >> 4) & 0xf]);
  440. sb.Append(HexDigits[value & 0xf]);
  441. return sb.ToString();
  442. }
  443. const string HexDigits = "0123456789ABCDEF";
  444. private void ProbeIoRange(int offset,
  445. out ushort start,
  446. out ushort length)
  447. {
  448. uint start32 = port.Read32(offset);
  449. DebugStub.Assert((start32 & PCI_BAR_TYPE_IO) == PCI_BAR_TYPE_IO);
  450. Write32(offset, ~0u);
  451. uint length32 = Read32(offset);
  452. length32 &= ~PCI_BAR_TYPE_IO;
  453. length32 |= 0xffff0000;
  454. length32 = ~length32 + 1;
  455. Write32(offset, start32);
  456. if (start32 <= 0xffff && length32 <= 0xffff) {
  457. start = (ushort)start32;
  458. length = (ushort)length32;
  459. }
  460. else {
  461. start = 0;
  462. length = 0;
  463. #if DEBUG_PCI
  464. DebugStub.Break();
  465. #endif // DEBUG_PCI
  466. }
  467. }
  468. private void ProbeMemoryRange64(int offset,
  469. out ulong start,
  470. out ulong length)
  471. {
  472. start = Read64(offset);
  473. DebugStub.Assert((start & PCI_BAR_TYPE_MEMMASK) ==
  474. PCI_BAR_TYPE_MEM64);
  475. Write64(offset, UInt64.MaxValue);
  476. length = Read64(offset);
  477. length &= ~((ulong)PCI_BAR_TYPE_MASK);
  478. length = ~length + 1;
  479. Write64(offset, start);
  480. if (UIntPtr.Size == 4 &&
  481. (start > (ulong)UInt32.MaxValue ||
  482. (start + length) > (ulong)UInt32.MaxValue)) {
  483. start = 0;
  484. length = 0;
  485. #if DEBUG_PCI
  486. DebugStub.Break();
  487. #endif // DEBUG_PCI
  488. }
  489. }
  490. private void ProbeMemoryRange32(int offset,
  491. out uint start,
  492. out uint length)
  493. {
  494. start = Read32(offset);
  495. DebugStub.Assert(
  496. (start & PCI_BAR_TYPE_MEMMASK) == PCI_BAR_TYPE_MEM32 ||
  497. (start & PCI_BAR_TYPE_MEMMASK) == PCI_BAR_TYPE_MEM20
  498. );
  499. Write32(offset, UInt32.MaxValue);
  500. length = port.Read32(offset) & ~PCI_BAR_TYPE_MASK;
  501. if ((start & PCI_BAR_TYPE_MASK) == PCI_BAR_TYPE_MEM20) {
  502. length |= 0xfff00000;
  503. }
  504. length = ~length + 1;
  505. Write32(offset, start);
  506. }
  507. protected void ReadBaseAddresses(int n)
  508. {
  509. InterruptPin = Read8(PCI_INTERRUPT_PIN);
  510. if (InterruptPin != 0) {
  511. // Add interrupt resource to list of ranges if present
  512. DynamicRanges = new IoRange [n + 1];
  513. DynamicRanges[n] = new IoIrqRange(Read8(PCI_INTERRUPT_LINE), 1);
  514. byte currentInterruptLine = InterruptLine;
  515. #if !SINGULARITY_PROCESS
  516. byte newInterruptLine = Platform.TranslatePciInterrupt(currentInterruptLine,
  517. InterruptPin,
  518. port);
  519. if (newInterruptLine != currentInterruptLine)
  520. {
  521. SetInterrupt(newInterruptLine);
  522. currentInterruptLine = newInterruptLine;
  523. }
  524. #endif
  525. IoIrqRange range = new IoIrqRange(currentInterruptLine, 1);
  526. DynamicRanges[n] = range;
  527. }
  528. else {
  529. DynamicRanges = new IoRange [n];
  530. }
  531. BaseAddresses = new ulong [n];
  532. BaseAddrSizes = new ulong [n];
  533. uint control = Read32(0x04);
  534. uint send = (control & (~(PCI_ENABLE_IO_SPACE|PCI_ENABLE_MEMORY_SPACE)))
  535. & 0xffff;
  536. if (control == 0x02b00003) {
  537. send = (control & (~(PCI_ENABLE_IO_SPACE))) & 0xffff;
  538. }
  539. #if DONT_SKIP_NVIDIA
  540. if (control == 0x02b00003) {
  541. send = control & 0xffff;
  542. send &= ~PCI_ENABLE_IO_SPACE;
  543. port.Write32(0x04, send);
  544. Tracing.Log(Tracing.Debug, "NVIDIA Read[{0}]: ctrl={1:x8} send={2:x8}", n, control, send);
  545. uint x = Read32(0x04);
  546. Tracing.Log(Tracing.Debug, "NVIDIA Read[{0}]: finl={1:x8}", n, x);
  547. port.Write32(0x04, control & 0xffff);
  548. x = Read32(0x04);
  549. Tracing.Log(Tracing.Debug, "NVIDIA Read[{0}]: last={1:x8}", n, x);
  550. return;
  551. }
  552. #endif
  553. port.Write32(0x04, send);
  554. for (int i = 0, bar = 0; i < n; i++, bar++) {
  555. int offset = 0x10 + i * 4;
  556. uint type = Read32(offset) & PCI_BAR_TYPE_MASK;
  557. if ((type & PCI_BAR_TYPE_IO) == PCI_BAR_TYPE_IO) {
  558. ushort addr16, size16;
  559. ProbeIoRange(offset, out addr16, out size16);
  560. if (size16 != 0) {
  561. DynamicRanges[bar] =
  562. new IoPortRange(
  563. (ushort)((uint)addr16 & ~PCI_BAR_TYPE_IO),
  564. size16,
  565. Access.ReadWrite
  566. );
  567. BaseAddresses[bar] = addr16;
  568. BaseAddrSizes[bar] = size16;
  569. }
  570. }
  571. else if ((type & PCI_BAR_TYPE_MEMMASK) == PCI_BAR_TYPE_MEM64) {
  572. ulong addr64, size64;
  573. ProbeMemoryRange64(offset, out addr64, out size64);
  574. if (size64 != 0) {
  575. DynamicRanges[bar] =
  576. new IoMemoryRange(
  577. addr64 & ~PCI_BAR_TYPE_MASK,
  578. size64,
  579. Access.ReadWrite
  580. );
  581. BaseAddresses[bar] = addr64;
  582. BaseAddrSizes[bar] = size64;
  583. i += 1;
  584. }
  585. }
  586. else if ((type & PCI_BAR_TYPE_MEMMASK) == PCI_BAR_TYPE_MEM32 ||
  587. (type & PCI_BAR_TYPE_MEMMASK) == PCI_BAR_TYPE_MEM20) {
  588. uint addr32, size32;
  589. ProbeMemoryRange32(offset, out addr32, out size32);
  590. if (size32 != 0) {
  591. DynamicRanges[bar] =
  592. new IoMemoryRange(
  593. addr32 & ~PCI_BAR_TYPE_MASK,
  594. size32,
  595. Access.ReadWrite
  596. );
  597. BaseAddresses[bar] = addr32;
  598. BaseAddrSizes[bar] = size32;
  599. }
  600. }
  601. }
  602. port.Write32(0x04, control & 0xffff);
  603. }
  604. public override string ToString()
  605. {
  606. return String.Format("[PCI: VEN_{0:x4} DEV_{1:x4} CLASS {2:x2}.{3:x2}.{4:x2} BASE {5:x8}]",
  607. this.VendorId,
  608. this.DeviceId,
  609. this.ClassId,
  610. this.SubClassId,
  611. this.Interface,
  612. this.Base);
  613. }
  614. public override string ToPrint()
  615. {
  616. StringBuilder text = new StringBuilder();
  617. base.DumpRanges(text);
  618. text.AppendFormat(" PCI Vendor/Device: {0:x4}.{1:x4} rev {2:x2} {3} {4}\n",
  619. this.VendorId,
  620. this.DeviceId,
  621. this.RevisionId,
  622. this.Vendor,
  623. this.Device);
  624. text.AppendFormat(" PCI Class/Subclass: {0:x2}.{1:x2}.{2:x2}\n",
  625. this.ClassId,
  626. this.SubClassId,
  627. this.Interface,
  628. this.Class);
  629. return text.ToString();
  630. }
  631. protected string PrintAddresses()
  632. {
  633. String s;
  634. bool print = false;
  635. for (int i = 0; i < BaseAddresses.Length; i++) {
  636. if (BaseAddresses[i] != 0 || BaseAddrSizes[i] != 0) {
  637. print = true;
  638. break;
  639. }
  640. }
  641. if (!print &&
  642. ROMBaseAddress == 0 && InterruptLine == 0 && InterruptPin == 0) {
  643. return "";
  644. }
  645. s = String.Format(" RM={0:x8} IL={1,2:x2} IP={2,2:x2} ",
  646. ROMBaseAddress,
  647. InterruptLine,
  648. InterruptPin);
  649. int printed = 0;
  650. for (int i = 0; i < BaseAddresses.Length; i++) {
  651. if (DynamicRanges[i] != null) {
  652. s += String.Format("A{0}={1} ", i, DynamicRanges[i]);
  653. }
  654. #if DONT_PRINT_RAW_ADDRESSS_BUT_ONLY_RANGES
  655. if (BaseAddresses[i] == 0 && BaseAddrSizes[i] == 0) {
  656. continue;
  657. }
  658. if ((BaseAddresses[i] & PCI_BAR_TYPE_IO) != 0) {
  659. s += String.Format("A{0}=IO:{1:x8}[{2:x}] ",
  660. i, BaseAddresses[i], BaseAddrSizes[i]);
  661. }
  662. else if ((BaseAddresses[i] & PCI_BAR_TYPE_MEM64) != 0) {
  663. s += String.Format("A{0}=64:{1:x8}[{2:x}] ",
  664. i, BaseAddresses[i], BaseAddrSizes[i]);
  665. }
  666. else if ((BaseAddresses[i] & PCI_BAR_TYPE_MEM20) != 0) {
  667. s += String.Format("A{0}=20:{1:x8}[{2:x}] ",
  668. i, BaseAddresses[i], BaseAddrSizes[i]);
  669. }
  670. else {
  671. s += String.Format("A{0}=32:{1:x8}[{2:x}] ",
  672. i, BaseAddresses[i], BaseAddrSizes[i]);
  673. }
  674. #endif
  675. printed++;
  676. }
  677. return s;
  678. }
  679. protected string Vendor {
  680. get {
  681. switch (VendorId) {
  682. case 0x1011:
  683. return "DEC";
  684. case 0x104c:
  685. return "TI";
  686. case 0x5333:
  687. return "S3";
  688. case 0x8086:
  689. return "Intel";
  690. case 0x10de:
  691. return "nVidia";
  692. case 0x1106:
  693. return "VIA Technologies";
  694. default:
  695. return String.Format("{0,4:x4}", VendorId);
  696. }
  697. }
  698. }
  699. protected string Device {
  700. get {
  701. switch (VendorId) {
  702. case 0x8086:
  703. switch (DeviceId) {
  704. case 0x0484: return "82379AB";
  705. case 0x1229: return "82559nic";
  706. case 0x122E: return "82371FB";
  707. case 0x1234: return "82371MX";
  708. case 0x2410: return "82801AA";
  709. case 0x7000: return "82371SB";
  710. case 0x7110: return "82371AB";
  711. default:
  712. break;
  713. }
  714. break;
  715. case 0x10de:
  716. // NVIDIA
  717. switch (DeviceId) {
  718. case 0x0050: return "PCI-to-ISA bridge";
  719. case 0x0052: return "nForce PCI System Management Module";
  720. case 0x0057: return "nForce Network Interface";
  721. case 0x0059: return "Realtek AC'97 Audio";
  722. case 0x005a: return "USB OHCI";
  723. case 0x005d: return "PCI-to-PCI bridge";
  724. case 0x005e: return "nForce4 HyperTransport Bridge";
  725. default:
  726. break;
  727. }
  728. break;
  729. case 0x1106:
  730. // VIA
  731. switch (DeviceId) {
  732. case 0x3044: return "OHCI Compliant IEEE 1394 Host Controller";
  733. default:
  734. break;
  735. }
  736. break;
  737. default:
  738. break;
  739. }
  740. return String.Format("{0,4:x4}", DeviceId);
  741. }
  742. }
  743. protected string Class {
  744. get {
  745. switch (ClassId) {
  746. case PCI_CLASS_STORAGE:
  747. switch (SubClassId) {
  748. case PCI_CLASS_STORAGE_SCSI: return "Scsi";
  749. case PCI_CLASS_STORAGE_IDE: return "Ide";
  750. case PCI_CLASS_STORAGE_FLOPPY: return "Floppy";
  751. case PCI_CLASS_STORAGE_IPI: return "Ipi";
  752. case PCI_CLASS_STORAGE_RAID: return "Raid";
  753. case PCI_CLASS_STORAGE_OTHER: return "Other";
  754. default: return String.Format("{0,2:x2}", SubClassId);
  755. }
  756. case PCI_CLASS_NETWORK:
  757. switch (SubClassId) {
  758. case PCI_CLASS_NETWORK_ETHERNET: return "Ethernet";
  759. case PCI_CLASS_NETWORK_RING: return "Ring";
  760. case PCI_CLASS_NETWORK_FDDI: return "Fddi";
  761. case PCI_CLASS_NETWORK_ATM: return "Atm";
  762. case PCI_CLASS_NETWORK_OTHER: return "Other";
  763. case PCI_CLASS_NETWORK_FIP: return "FIP";
  764. case PCI_CLASS_NETWORK_PICMG: return "PICMG";
  765. default: return String.Format("{0,2:x2}", SubClassId);
  766. }
  767. case PCI_CLASS_DISPLAY:
  768. switch (SubClassId) {
  769. case PCI_CLASS_DISPLAY_VGA: return "Vga";
  770. case PCI_CLASS_DISPLAY_XGA: return "Xga";
  771. case PCI_CLASS_DISPLAY_3D: return "3D";
  772. case PCI_CLASS_DISPLAY_OTHER: return "Other";
  773. default: return String.Format("{0,2:x2}", SubClassId);
  774. }
  775. case PCI_CLASS_MULTIMEDIA:
  776. switch (SubClassId) {
  777. case PCI_CLASS_MULTIMEDIA_VIDEO: return "Video";
  778. case PCI_CLASS_MULTIMEDIA_AUDIO: return "Audio";
  779. case PCI_CLASS_MULTIMEDIA_TELEPHONY: return "Telephony";
  780. case PCI_CLASS_MULTIMEDIA_OTHER: return "Other";
  781. default: return String.Format("{0,2:x2}", SubClassId);
  782. }
  783. case PCI_CLASS_MEMORY:
  784. switch (SubClassId) {
  785. case PCI_CLASS_MEMORY_RAM: return "Ram";
  786. case PCI_CLASS_MEMORY_FLASH: return "Flash";
  787. case PCI_CLASS_MEMORY_OTHER: return "Other";
  788. default: return String.Format("{0,2:x2}", SubClassId);
  789. }
  790. case PCI_CLASS_BRIDGE:
  791. switch (SubClassId) {
  792. case PCI_CLASS_BRIDGE_HOST: return "Host";
  793. case PCI_CLASS_BRIDGE_ISA: return "Isa";
  794. case PCI_CLASS_BRIDGE_EISA: return "Eisa";
  795. case PCI_CLASS_BRIDGE_MC: return "Mc";
  796. case PCI_CLASS_BRIDGE_PCI: return "Pci";
  797. case PCI_CLASS_BRIDGE_PCMCIA: return "Pcmcia";
  798. case PCI_CLASS_BRIDGE_NUBUS: return "Nubus";
  799. case PCI_CLASS_BRIDGE_CARDBUS: return "Cardbus";
  800. case PCI_CLASS_BRIDGE_RACEWAY: return "Raceway";
  801. case PCI_CLASS_BRIDGE_SEMIPCI: return "Semipci";
  802. case PCI_CLASS_BRIDGE_INFINIBAND: return "Infiniband";
  803. case PCI_CLASS_BRIDGE_OTHER: return "Other";
  804. default: return String.Format("{0,2:x2}", SubClassId);
  805. }
  806. case PCI_CLASS_COMMUNICATION:
  807. switch (SubClassId) {
  808. case PCI_CLASS_COMMUNICATION_SERIAL: return "Serial";
  809. case PCI_CLASS_COMMUNICATION_PARALLEL: return "Parallel";
  810. case PCI_CLASS_COMMUNICATION_MULTIPORT: return "Multiport";
  811. case PCI_CLASS_COMMUNICATION_MODEM: return "Modem";
  812. case PCI_CLASS_COMMUNICATION_GPIB: return "Gpib";
  813. case PCI_CLASS_COMMUNICATION_SMARTCARD: return "Smartcard";
  814. case PCI_CLASS_COMMUNICATION_OTHER: return "Other";
  815. default: return String.Format("{0,2:x2}", SubClassId);
  816. }
  817. case PCI_CLASS_SYSTEM:
  818. switch (SubClassId) {
  819. case PCI_CLASS_SYSTEM_PIC: return "Pic";
  820. case PCI_CLASS_SYSTEM_DMA: return "Dma";
  821. case PCI_CLASS_SYSTEM_TIMER: return "Timer";
  822. case PCI_CLASS_SYSTEM_RTC: return "Rtc";
  823. case PCI_CLASS_SYSTEM_PCIHP: return "Pcihp";
  824. case PCI_CLASS_SYSTEM_OTHER: return "Other";
  825. default: return String.Format("{0,2:x2}", SubClassId);
  826. }
  827. case PCI_CLASS_INPUT:
  828. switch (SubClassId) {
  829. case PCI_CLASS_INPUT_KEYBOARD: return "Keyboard";
  830. case PCI_CLASS_INPUT_PEN: return "Pen";
  831. case PCI_CLASS_INPUT_MOUSE: return "Mouse";
  832. case PCI_CLASS_INPUT_SCANNER: return "Scanner";
  833. case PCI_CLASS_INPUT_GAMEPORT: return "Gameport";
  834. case PCI_CLASS_INPUT_OTHER: return "Other";
  835. default: return String.Format("{0,2:x2}", SubClassId);
  836. }
  837. case PCI_CLASS_SERIAL:
  838. switch (SubClassId) {
  839. case PCI_CLASS_SERIAL_FIREWIRE: return "Firewire";
  840. case PCI_CLASS_SERIAL_ACCESS: return "Access";
  841. case PCI_CLASS_SERIAL_SSA: return "Ssa";
  842. case PCI_CLASS_SERIAL_USB:
  843. switch (this.Interface) {
  844. case 0x00: return "USB1.1 UHCI";
  845. case 0x10: return "USB1.1 OHCI";
  846. case 0x20: return "USB2.0 EHCI";
  847. default:
  848. return "Usb";
  849. }
  850. case PCI_CLASS_SERIAL_FIBRE: return "Fibre";
  851. case PCI_CLASS_SERIAL_SMBUS: return "Smbus";
  852. case PCI_CLASS_SERIAL_INFINIBAND: return "Infiniband";
  853. case PCI_CLASS_SERIAL_IPMI: return "Ipmi";
  854. case PCI_CLASS_SERIAL_SERCOS: return "Sercos";
  855. case PCI_CLASS_SERIAL_CANBUS: return "Canbus";
  856. default: return String.Format("{0,2:x2}", SubClassId);
  857. }
  858. case PCI_CLASS_WIRELESS:
  859. switch (SubClassId) {
  860. case PCI_CLASS_WIRELESS_IRDA: return "Irda";
  861. case PCI_CLASS_WIRELESS_IR: return "Ir";
  862. case PCI_CLASS_WIRELESS_RF: return "Rf";
  863. case PCI_CLASS_WIRELESS_BLUETOOTH: return "Bluetooth";
  864. case PCI_CLASS_WIRELESS_BROADBAND: return "Broadband";
  865. case PCI_CLASS_WIRELESS_OTHER: return "Other";
  866. default: return String.Format("{0,2:x2}", SubClassId);
  867. }
  868. case PCI_CLASS_I2O:
  869. switch (SubClassId) {
  870. case PCI_CLASS_I2O_I2O: return "I2O";
  871. default: return String.Format("{0,2:x2}", SubClassId);
  872. }
  873. case PCI_CLASS_SATELLITE:
  874. switch (SubClassId) {
  875. case PCI_CLASS_SATELLITE_TV: return "Tv";
  876. case PCI_CLASS_SATELLITE_AUDIO: return "Audio";
  877. case PCI_CLASS_SATELLITE_VOICE: return "Voice";
  878. case PCI_CLASS_SATELLITE_DATA: return "Data";
  879. default: return String.Format("{0,2:x2}", SubClassId);
  880. }
  881. case PCI_CLASS_ENCRYPTION:
  882. switch (SubClassId) {
  883. case PCI_CLASS_ENCRYPTION_NETWORK: return "Network";
  884. case PCI_CLASS_ENCRYPTION_ENTERTAINMENT:return "Entertainment";
  885. case PCI_CLASS_ENCRYPTION_OTHER: return "Other";
  886. default: return String.Format("{0,2:x2}", SubClassId);
  887. }
  888. case PCI_CLASS_ACQUISITION:
  889. switch (SubClassId) {
  890. case PCI_CLASS_ACQUISITION_DPIO: return "Dpio";
  891. case PCI_CLASS_ACQUISITION_PERF: return "Perf";
  892. case PCI_CLASS_ACQUISITION_COMM: return "Comm";
  893. case PCI_CLASS_ACQUISITION_MGMT: return "Mgmt";
  894. case PCI_CLASS_ACQUISITION_OTHER: return "Other";
  895. default: return String.Format("{0,2:x2}", SubClassId);
  896. }
  897. default: return String.Format("{0,2:x2}", SubClassId);
  898. }
  899. }
  900. }
  901. protected string Base {
  902. get {
  903. switch (ClassId) {
  904. case PCI_CLASS_STORAGE: return "Storage";
  905. case PCI_CLASS_NETWORK: return "Network";
  906. case PCI_CLASS_DISPLAY: return "Display";
  907. case PCI_CLASS_MULTIMEDIA: return "Multimedia";
  908. case PCI_CLASS_MEMORY: return "Memory";
  909. case PCI_CLASS_BRIDGE: return "Bridge";
  910. case PCI_CLASS_COMMUNICATION: return "Communication";
  911. case PCI_CLASS_SYSTEM: return "System";
  912. case PCI_CLASS_INPUT: return "Input";
  913. case PCI_CLASS_DOCKING: return "Docking";
  914. case PCI_CLASS_PROCESSOR: return "Processor";
  915. case PCI_CLASS_SERIAL: return "Serial";
  916. case PCI_CLASS_OTHERS: return "Others";
  917. case PCI_CLASS_WIRELESS: return "Wireless";
  918. case PCI_CLASS_I2O: return "I2O";
  919. case PCI_CLASS_SATELLITE: return "Satellite";
  920. case PCI_CLASS_ENCRYPTION: return "Encryption";
  921. case PCI_CLASS_ACQUISITION: return "Acquisition";
  922. default: return String.Format("{0,2:x2}", ClassId);
  923. }
  924. }
  925. }
  926. }
  927. [CLSCompliant(false)]
  928. public class PciBridgeConfig : PciConfig
  929. {
  930. // Bridges: (HeaderType & ~PCI_MULTIFUNCTION) == PCI_BRIDGE_TYPE
  931. // public uint BaseAddresses[2]; // 10..17
  932. protected byte PrimaryBus; // 18..18
  933. protected byte SecondaryBus; // 19..19
  934. protected byte SubordinateBus; // 1a..1a
  935. protected byte SecondaryLatency; // 1b..1b
  936. protected byte IOBase; // 1c..1c
  937. protected byte IOLimit; // 1d..1d
  938. protected ushort SecondaryStatus; // 1e..1f
  939. protected ushort MemoryBase; // 20..21
  940. protected ushort MemoryLimit; // 22..23
  941. protected ushort PrefetchBase; // 24..25
  942. protected ushort PrefetchLimit; // 26..27
  943. protected uint PrefetchBaseUpper32; // 28..2b
  944. protected uint PrefetchLimitUpper32; // 2c..2f
  945. protected ushort IOBaseUpper16; // 30..31
  946. protected ushort IOLimitUpper16; // 32..33
  947. // protected uint Reserved; // 34..37
  948. // protected uint ROMBaseAddress; // 38..3b
  949. #if DISABLED
  950. // protected byte InterruptLine; // 3c..3c
  951. #endif
  952. // protected byte InterruptPin; // 3d..3d
  953. protected ushort BridgeControl; // 3e..3f
  954. public PciBridgeConfig(PciPort port)
  955. : base(port)
  956. {
  957. Read();
  958. }
  959. protected override void Read()
  960. {
  961. base.Read();
  962. base.ReadBaseAddresses(2);
  963. uint u;
  964. u = port.Read32(0x18);
  965. PrimaryBus = (byte)(u & 0xff);
  966. SecondaryBus = (byte)((u >> 8) & 0xff);
  967. SubordinateBus = (byte)((u >> 16) & 0xff);
  968. SecondaryLatency = (byte)((u >> 24) & 0xff);
  969. u = port.Read32(0x1c);
  970. IOBase = (byte)(u & 0xff);
  971. IOLimit = (byte)((u >> 8) & 0xff);
  972. SecondaryStatus = (ushort)((u >> 16) & 0xffff);
  973. u = port.Read32(0x20);
  974. MemoryBase = (ushort)(u & 0xffff);
  975. MemoryLimit = (ushort)((u >> 16) & 0xffff);
  976. u = port.Read32(0x24);
  977. PrefetchBase = (ushort)(u & 0xffff);
  978. PrefetchLimit = (ushort)((u >> 16) & 0xffff);
  979. u = port.Read32(0x28);
  980. PrefetchBaseUpper32 = u;
  981. u = port.Read32(0x2c);
  982. PrefetchLimitUpper32 = u;
  983. u = port.Read32(0x30);
  984. IOBaseUpper16 = (ushort)(u & 0xffff);
  985. IOLimitUpper16 = (ushort)((u >> 16) & 0xffff);
  986. u = port.Read32(0x38);
  987. ROMBaseAddress = u;
  988. u = port.Read32(0x3c);
  989. #if DISABLED
  990. InterruptLine = (byte)(u & 0xff);
  991. #endif
  992. InterruptPin = (byte)((u >> 8) & 0xff);
  993. BridgeControl = (ushort)((u >> 16) & 0xffff);
  994. }
  995. public override string ToPrint()
  996. {
  997. return base.ToPrint() +
  998. String.Format("BUS={0,2:x2}.{1,2:x2}.{2,2:x2} IO={3,4:x4}..{4,4:x4}",
  999. PrimaryBus, SecondaryBus, SubordinateBus,
  1000. IOBase, IOLimit) +
  1001. "" +
  1002. base.PrintAddresses() + "";
  1003. }
  1004. }
  1005. [CLSCompliant(false)]
  1006. public class PciDeviceConfig : PciConfig
  1007. {
  1008. // Devices: (HeaderType & ~PCI_MULTIFUNCTION) == PCI_DEVICE_TYPE
  1009. // public uint BaseAddresses[6]; // 10..27
  1010. protected uint CardbusCisPtr; // 28..2b
  1011. // protected ushort SubsystemVendorId; // 2c..2d
  1012. // protected ushort SubsystemDeviceId; // 2e..2f
  1013. // protected uint ROMBaseAddress; // 30..33
  1014. protected byte capabilities; // 34..34
  1015. // protected byte Reserved[7]; // 35..38
  1016. #if DISABLED
  1017. // protected byte InterruptLine; // 3c..3c
  1018. #endif
  1019. // protected byte InterruptPin; // 3d..3d (ro)
  1020. protected byte MinimumGrant; // 3e..3e …

Large files files are truncated, but you can click here to view the full file