Source code of Windows XP (NT5)
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.

1631 lines
46 KiB

  1. /*++
  2. Copyright (c) 1990, 1991 Microsoft Corporation
  3. Module Name:
  4. config.c
  5. Abstract:
  6. Make a few ARC entries needed for NTLDR/ntoskrnl to boot.
  7. Author:
  8. Allen Kay (akay) 26-Oct-98
  9. Revision History:
  10. --*/
  11. #include "arccodes.h"
  12. #include "bootia64.h"
  13. #include "string.h"
  14. #include "pci.h"
  15. #include "ntacpi.h"
  16. #include "acpitabl.h"
  17. #include "efi.h"
  18. #include "biosdrv.h"
  19. //
  20. // External Data
  21. //
  22. extern PCONFIGURATION_COMPONENT_DATA FwConfigurationTree;
  23. extern PVOID AcpiTable;
  24. //
  25. // Defines
  26. //
  27. #define LEVEL_SENSITIVE CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
  28. #define EDGE_TRIGGERED CM_RESOURCE_INTERRUPT_LATCHED
  29. #define RESOURCE_PORT 1
  30. #define RESOURCE_INTERRUPT 2
  31. #define RESOURCE_MEMORY 3
  32. #define RESOURCE_DMA 4
  33. #define RESOURCE_DEVICE_DATA 5
  34. #define ALL_PROCESSORS 0xffffffff
  35. //
  36. // Internal references and definitions.
  37. //
  38. typedef enum _RELATIONSHIP_FLAGS {
  39. Child,
  40. Sibling,
  41. Parent
  42. } RELATIONSHIP_FLAGS;
  43. //
  44. // Hard Disk Drive
  45. //
  46. #define SIZE_OF_PARAMETER 12 // size of disk params
  47. #define MAX_DRIVE_NUMBER 8 // max number of drives
  48. #define RESOURCE_DEVICE_DATA 5
  49. #define RESERVED_ROM_BLOCK_LIST_SIZE (((0xf0000 - 0xc0000)/512) * sizeof(CM_ROM_BLOCK))
  50. #define DATA_HEADER_SIZE sizeof(CM_PARTIAL_RESOURCE_LIST)
  51. typedef CM_PARTIAL_RESOURCE_DESCRIPTOR HWPARTIAL_RESOURCE_DESCRIPTOR;
  52. typedef HWPARTIAL_RESOURCE_DESCRIPTOR *PHWPARTIAL_RESOURCE_DESCRIPTOR;
  53. typedef CM_PARTIAL_RESOURCE_LIST HWRESOURCE_DESCRIPTOR_LIST;
  54. typedef HWRESOURCE_DESCRIPTOR_LIST *PHWRESOURCE_DESCRIPTOR_LIST;
  55. //
  56. // Defines the structure to store controller information
  57. // (used by ntdetect internally)
  58. //
  59. #define MAXIMUM_DESCRIPTORS 10
  60. typedef struct _HWCONTROLLER_DATA {
  61. UCHAR NumberPortEntries;
  62. UCHAR NumberIrqEntries;
  63. UCHAR NumberMemoryEntries;
  64. UCHAR NumberDmaEntries;
  65. HWPARTIAL_RESOURCE_DESCRIPTOR DescriptorList[MAXIMUM_DESCRIPTORS];
  66. } HWCONTROLLER_DATA, *PHWCONTROLLER_DATA;
  67. //
  68. // Hard Disk Defines
  69. //
  70. #pragma pack(1)
  71. typedef struct _HARD_DISK_PARAMETERS {
  72. USHORT DriveSelect;
  73. ULONG MaxCylinders;
  74. USHORT SectorsPerTrack;
  75. USHORT MaxHeads;
  76. USHORT NumberDrives;
  77. } HARD_DISK_PARAMETERS, *PHARD_DISK_PARAMETERS;
  78. #pragma pack()
  79. PUCHAR PRomBlock = NULL;
  80. USHORT RomBlockLength = 0;
  81. USHORT NumberBiosDisks;
  82. #if defined(_INCLUDE_LOADER_KBINFO_)
  83. //
  84. // Keyboard defines
  85. //
  86. //
  87. // String table to map keyboard id to an ascii string.
  88. //
  89. #define UNKNOWN_KEYBOARD 0
  90. #define OLI_83KEY 1
  91. #define OLI_102KEY 2
  92. #define OLI_86KEY 3
  93. #define OLI_A101_102KEY 4
  94. #define XT_83KEY 5
  95. #define ATT_302 6
  96. #define PCAT_ENHANCED 7
  97. #define PCAT_86KEY 8
  98. #define PCXT_84KEY 9
  99. PUCHAR KeyboardIdentifier[] = {
  100. "UNKNOWN_KEYBOARD",
  101. "OLI_83KEY",
  102. "OLI_102KEY",
  103. "OLI_86KEY",
  104. "OLI_A101_102KEY",
  105. "XT_83KEY",
  106. "ATT_302",
  107. "PCAT_ENHANCED",
  108. "PCAT_86KEY",
  109. "PCXT_84KEY"
  110. };
  111. UCHAR KeyboardType[] = {
  112. -1,
  113. 1,
  114. 2,
  115. 3,
  116. 4,
  117. 1,
  118. 1,
  119. 4,
  120. 3,
  121. 1
  122. };
  123. UCHAR KeyboardSubtype[] = {
  124. -1,
  125. 0,
  126. 1,
  127. 10,
  128. 4,
  129. 42,
  130. 4,
  131. 0,
  132. 0,
  133. 0
  134. };
  135. #endif // _INCLUDE_LOADER_KBINFO_
  136. #if defined(_INCLUDE_LOADER_MOUSEINFO_)
  137. //
  138. // Mouse Defines
  139. //
  140. typedef struct _MOUSE_INFORMATION {
  141. UCHAR MouseType;
  142. UCHAR MouseSubtype;
  143. USHORT MousePort; // if serial mouse, 1 for com1, 2 for com2 ...
  144. USHORT MouseIrq;
  145. USHORT DeviceIdLength;
  146. UCHAR DeviceId[10];
  147. } MOUSE_INFORMATION, *PMOUSE_INFORMATION;
  148. //
  149. // Mouse Type definitions
  150. //
  151. #define UNKNOWN_MOUSE 0
  152. #define NO_MOUSE 0x100 // YES! it is 0x100 *NOT* 0x10000
  153. #define MS_MOUSE 0x200 // MS regular mouses
  154. #define MS_BALLPOINT 0x300 // MS ballpoint mouse
  155. #define LT_MOUSE 0x400 // Logitec Mouse
  156. //
  157. // note last 4 bits of the subtype are reserved subtype specific use
  158. //
  159. #define PS2_MOUSE 0x1
  160. #define SERIAL_MOUSE 0x2
  161. #define INPORT_MOUSE 0x3
  162. #define BUS_MOUSE 0x4
  163. #define PS_MOUSE_WITH_WHEEL 0x5
  164. #define SERIAL_MOUSE_WITH_WHEEL 0x6
  165. PUCHAR MouseIdentifier[] = {
  166. "UNKNOWN",
  167. "NO MOUSE",
  168. "MICROSOFT",
  169. "MICROSOFT BALLPOINT",
  170. "LOGITECH"
  171. };
  172. PUCHAR MouseSubidentifier[] = {
  173. "",
  174. " PS2 MOUSE",
  175. " SERIAL MOUSE",
  176. " INPORT MOUSE",
  177. " BUS MOUSE",
  178. " PS2 MOUSE WITH WHEEL",
  179. " SERIAL MOUSE WITH WHEEL"
  180. };
  181. //
  182. // The following table translates keyboard make code to
  183. // ascii code. Note, only 0-9 and A-Z are translated.
  184. // Everything else is translated to '?'
  185. //
  186. UCHAR MakeToAsciiTable[] = {
  187. 0x3f, 0x3f, 0x31, 0x32, 0x33, // ?, ?, 1, 2, 3,
  188. 0x34, 0x35, 0x36, 0x37, 0x38, // 4, 5, 6, 7, 8,
  189. 0x39, 0x30, 0x3f, 0x3f, 0x3f, // 9, 0, ?, ?, ?,
  190. 0x3f, 0x51, 0x57, 0x45, 0x52, // ?, Q, W, E, R,
  191. 0x54, 0x59, 0x55, 0x49, 0x4f, // T, Y, U, I, O,
  192. 0x50, 0x3f, 0x3f, 0x3f, 0x3f, // P, ?, ?, ?, ?,
  193. 0x41, 0x53, 0x44, 0x46, 0x47, // A, S, D, F, G,
  194. 0x48, 0x4a, 0x4b, 0x4c, 0x3f, // H, J, K, L, ?,
  195. 0x3f, 0x3f, 0x3f, 0x3f, 0x5a, // ?, ?, ?, ?, Z,
  196. 0x58, 0x43, 0x56, 0x42, 0x4e, // X, C, V, B, N,
  197. 0x4d}; // W
  198. #define MAX_MAKE_CODE_TRANSLATED 0x32
  199. static ULONG MouseControllerKey = 0;
  200. #endif // _INCLUDE_LOADER_MOUSEINFO_
  201. //
  202. // ComPortAddress[] is a global array to remember which comports have
  203. // been detected and their I/O port addresses.
  204. //
  205. #define MAX_COM_PORTS 4 // Max. number of comports detectable
  206. #define MAX_LPT_PORTS 3 // Max. number of LPT ports detectable
  207. #if 0 //unused
  208. USHORT ComPortAddress[MAX_COM_PORTS] = {0, 0, 0, 0};
  209. #endif
  210. //
  211. // Global Definition
  212. //
  213. #if defined(_INCLUDE_LOADER_MOUSEINFO_) || defined(_INCLUDE_LOADER_KBINFO_)
  214. USHORT HwBusType = 0;
  215. #endif
  216. PCONFIGURATION_COMPONENT_DATA AdapterEntry = NULL;
  217. //
  218. // Function Prototypes
  219. //
  220. #if defined(_INCLUDE_LOADER_KBINFO_)
  221. PCONFIGURATION_COMPONENT_DATA
  222. SetKeyboardConfigurationData (
  223. IN USHORT KeyboardId
  224. );
  225. #endif
  226. #if defined(_INCLUDE_LOADER_MOUSEINFO_)
  227. PCONFIGURATION_COMPONENT_DATA
  228. GetMouseInformation (
  229. VOID
  230. );
  231. #endif
  232. PCONFIGURATION_COMPONENT_DATA
  233. GetComportInformation (
  234. VOID
  235. );
  236. PVOID
  237. HwSetUpResourceDescriptor (
  238. PCONFIGURATION_COMPONENT Component,
  239. PUCHAR Identifier,
  240. PHWCONTROLLER_DATA ControlData,
  241. USHORT SpecificDataLength,
  242. PUCHAR SpecificData
  243. );
  244. VOID
  245. HwSetUpFreeFormDataHeader (
  246. PHWRESOURCE_DESCRIPTOR_LIST Header,
  247. USHORT Version,
  248. USHORT Revision,
  249. USHORT Flags,
  250. ULONG DataSize
  251. );
  252. BuildArcTree(
  253. )
  254. /*++
  255. Routine Description:
  256. Main entrypoint of the HW recognizer test. The routine builds
  257. a configuration tree and leaves it in the hardware heap.
  258. Arguments:
  259. ConfigurationTree - Supplies a 32 bit FLAT address of the variable to
  260. receive the hardware configuration tree.
  261. Returns:
  262. None.
  263. --*/
  264. {
  265. PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
  266. PCONFIGURATION_COMPONENT_DATA FirstCom = NULL, FirstLpt = NULL;
  267. PCONFIGURATION_COMPONENT_DATA CurrentEntry, PreviousEntry;
  268. PCONFIGURATION_COMPONENT_DATA AcpiAdapterEntry = NULL;
  269. PCONFIGURATION_COMPONENT Component;
  270. RELATIONSHIP_FLAGS NextRelationship;
  271. CHAR Identifier[256];
  272. PUCHAR MachineId;
  273. USHORT KeyboardId = 0;
  274. USHORT Length, InitialLength, i, j, Count = 0;
  275. PCHAR IdentifierString;
  276. PHARD_DISK_PARAMETERS RomChain;
  277. PUCHAR PRomChain = NULL, ConfigurationData, EndConfigurationData;
  278. SHORT FreeSize;
  279. PHWPARTIAL_RESOURCE_DESCRIPTOR Descriptor;
  280. PHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
  281. PCI_REGISTRY_INFO PciEntry;
  282. PACPI_BIOS_MULTI_NODE AcpiMultiNode;
  283. PUCHAR Current;
  284. PRSDP rsdp;
  285. //
  286. // Allocate heap space for System component and initialize it.
  287. // Also make the System component the root of configuration tree.
  288. //
  289. ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  290. sizeof(CONFIGURATION_COMPONENT_DATA));
  291. Component = &ConfigurationRoot->ComponentEntry;
  292. Component->Class = SystemClass;
  293. Component->Type = MaximumType; // NOTE should be IsaCompatible
  294. Component->Version = 0;
  295. Component->Key = 0;
  296. Component->AffinityMask = 0;
  297. Component->ConfigurationDataLength = 0;
  298. MachineId = "Intel Itanium processor family";
  299. if (MachineId) {
  300. Length = strlen(MachineId) + 1;
  301. IdentifierString = (PCHAR)BlAllocateHeap(Length);
  302. strcpy(IdentifierString, MachineId);
  303. Component->Identifier = IdentifierString;
  304. Component->IdentifierLength = Length;
  305. } else {
  306. Component->Identifier = 0;
  307. Component->IdentifierLength = 0;
  308. }
  309. NextRelationship = Child;
  310. PreviousEntry = ConfigurationRoot;
  311. //
  312. // ISA
  313. //
  314. AdapterEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  315. sizeof(CONFIGURATION_COMPONENT_DATA));
  316. Component = &AdapterEntry->ComponentEntry;
  317. Component->Class = AdapterClass;
  318. Component->Type = MultiFunctionAdapter;
  319. strcpy(Identifier, "ISA");
  320. Length = strlen(Identifier) + 1;
  321. IdentifierString = (PCHAR)BlAllocateHeap(Length);
  322. strcpy(IdentifierString, Identifier);
  323. Component->Version = 0;
  324. Component->Key = 0;
  325. Component->AffinityMask = 0xffffffff;
  326. Component->IdentifierLength = Length;
  327. Component->Identifier = IdentifierString;
  328. //
  329. // Make Adapter component System's child
  330. //
  331. if (NextRelationship == Sibling) {
  332. PreviousEntry->Sibling = AdapterEntry;
  333. AdapterEntry->Parent = PreviousEntry->Parent;
  334. } else {
  335. PreviousEntry->Child = AdapterEntry;
  336. AdapterEntry->Parent = PreviousEntry;
  337. }
  338. NextRelationship = Child;
  339. PreviousEntry = AdapterEntry;
  340. //
  341. // Collect BIOS information for ConfigurationRoot component.
  342. // This step is done here because we need data collected in
  343. // adapter component. The ConfigurationData is:
  344. // HWRESOURCE_DESCRIPTOR_LIST header
  345. // HWPARTIAL_RESOURCE_DESCRIPTOR for Parameter Table
  346. // HWPARTIAL_RESOURCE_DESCRIPTOR for Rom Blocks.
  347. // (Note DATA_HEADER_SIZE contains the size of the first partial
  348. // descriptor already.)
  349. //
  350. #if DBG
  351. BlPrint(TEXT("Collecting Disk Geometry...\r\n"));
  352. #endif
  353. RomChain = (PHARD_DISK_PARAMETERS)
  354. BlAllocateHeap(SIZE_OF_PARAMETER * MAX_DRIVE_NUMBER);
  355. #if 0
  356. RomChain[0].DriveSelect = 0x80;
  357. RomChain[0].MaxCylinders = 0;
  358. RomChain[0].SectorsPerTrack = 0;
  359. RomChain[0].MaxHeads = 0;
  360. RomChain[0].NumberDrives = 1; // Gambit only access 1 drive
  361. NumberBiosDisks = 1; // was defined in diska.asm
  362. #endif
  363. InitialLength = (USHORT)(Length + RESERVED_ROM_BLOCK_LIST_SIZE + DATA_HEADER_SIZE +
  364. sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR));
  365. ConfigurationData = (PUCHAR)BlAllocateHeap(InitialLength);
  366. EndConfigurationData = ConfigurationData + DATA_HEADER_SIZE;
  367. if (Length != 0) {
  368. PRomChain = EndConfigurationData;
  369. RtlCopyMemory( PRomChain, (PVOID)RomChain, Length);
  370. }
  371. EndConfigurationData += (sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR) +
  372. Length);
  373. HwSetUpFreeFormDataHeader((PHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData,
  374. 0,
  375. 0,
  376. 0,
  377. Length
  378. );
  379. //
  380. // Scan ROM to collect all the ROM blocks, if possible.
  381. //
  382. #if DBG
  383. BlPrint(TEXT("Constructing ROM Blocks...\r\n"));
  384. #endif
  385. PRomBlock = EndConfigurationData;
  386. Length = 0;
  387. RomBlockLength = Length;
  388. if (Length != 0) {
  389. EndConfigurationData += Length;
  390. } else {
  391. PRomBlock = NULL;
  392. }
  393. //
  394. // We have both RomChain and RomBlock information/Headers.
  395. //
  396. DescriptorList = (PHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData;
  397. DescriptorList->Count = 2;
  398. Descriptor = (PHWPARTIAL_RESOURCE_DESCRIPTOR)(
  399. EndConfigurationData - Length -
  400. sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR));
  401. Descriptor->Type = RESOURCE_DEVICE_DATA;
  402. Descriptor->ShareDisposition = 0;
  403. Descriptor->Flags = 0;
  404. Descriptor->u.DeviceSpecificData.DataSize = (ULONG)Length;
  405. Descriptor->u.DeviceSpecificData.Reserved1 = 0;
  406. Descriptor->u.DeviceSpecificData.Reserved2 = 0;
  407. Length = (USHORT)(EndConfigurationData - ConfigurationData);
  408. ConfigurationRoot->ComponentEntry.ConfigurationDataLength = Length;
  409. ConfigurationRoot->ConfigurationData = ConfigurationData;
  410. FreeSize = InitialLength - Length;
  411. #if defined(_INCLUDE_LOADER_KBINFO_)
  412. //#if defined(NO_ACPI)
  413. //
  414. // Set up device information structure for Keyboard.
  415. //
  416. #if DBG
  417. BlPrint(TEXT("Constructing Keyboard Component ...\r\n"));
  418. #endif
  419. KeyboardId = 7; // PCAT_ENHANCED
  420. CurrentEntry = SetKeyboardConfigurationData(KeyboardId);
  421. //
  422. // Make display component the child of Adapter component.
  423. //
  424. if (NextRelationship == Sibling) {
  425. PreviousEntry->Sibling = CurrentEntry;
  426. CurrentEntry->Parent = PreviousEntry->Parent;
  427. } else {
  428. PreviousEntry->Child = CurrentEntry;
  429. CurrentEntry->Parent = PreviousEntry;
  430. }
  431. NextRelationship = Sibling;
  432. PreviousEntry = CurrentEntry;
  433. #endif // _INCLUDE_LOADER_MOUSEINFO_
  434. //
  435. // Set up device information for com port
  436. //
  437. #if defined(_INCLUDE_COMPORT_INFO_)
  438. //
  439. // This code was taken out because the GetComportInformation() routine
  440. // was manufacturing data about the com port and writing the com port
  441. // address to 40:0. This information should be determined by PnP
  442. //
  443. #if DBG
  444. BlPrint(TEXT("Constructing ComPort Component ...\r\n"));
  445. #endif
  446. if (CurrentEntry = GetComportInformation()) {
  447. //
  448. // Make current component the child of Adapter component.
  449. //
  450. if (NextRelationship == Sibling) {
  451. PreviousEntry->Sibling = CurrentEntry;
  452. } else {
  453. PreviousEntry->Child = CurrentEntry;
  454. }
  455. while (CurrentEntry) {
  456. CurrentEntry->Parent = AdapterEntry;
  457. PreviousEntry = CurrentEntry;
  458. CurrentEntry = CurrentEntry->Sibling;
  459. }
  460. NextRelationship = Sibling;
  461. }
  462. #else
  463. // DbgPrint("Skipping ComPort Component ...\r\n");
  464. //
  465. // acpi node should be a sibling of adapter entry
  466. //
  467. // Note: this only works if !defined(_INCLUDE_LOADER_MOUSEINFO_)
  468. //
  469. NextRelationship = Sibling;
  470. PreviousEntry = AdapterEntry;
  471. #endif
  472. #if defined(_INCLUDE_LOADER_MOUSEINFO_)
  473. //
  474. // Set up device information structure for Mouse.
  475. //
  476. #if DBG
  477. BlPrint(TEXT("Constructing Mouse Component ...\r\n"));
  478. #endif
  479. if (CurrentEntry = GetMouseInformation
  480. ()) {
  481. //
  482. // Make current component the child of Adapter component.
  483. //
  484. if (NextRelationship == Sibling) {
  485. PreviousEntry->Sibling = CurrentEntry;
  486. CurrentEntry->Parent = PreviousEntry->Parent;
  487. } else {
  488. PreviousEntry->Child = CurrentEntry;
  489. CurrentEntry->Parent = PreviousEntry;
  490. }
  491. NextRelationship = Sibling;
  492. PreviousEntry = CurrentEntry;
  493. }
  494. //#endif // NO_ACPI
  495. #endif // _INCLUDE_LOADER_MOUSEINFO_
  496. //DbgPrint("Constructing ACPI Bus Component ...\n");
  497. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  498. sizeof(CONFIGURATION_COMPONENT_DATA));
  499. Current = (PCHAR) BlAllocateHeap( DATA_HEADER_SIZE +
  500. sizeof(ACPI_BIOS_MULTI_NODE) );
  501. AcpiMultiNode = (PACPI_BIOS_MULTI_NODE) (Current + DATA_HEADER_SIZE);
  502. //DbgPrint("AcpiTable: %p\n", AcpiTable);
  503. if (AcpiTable) {
  504. rsdp = (PRSDP) AcpiTable;
  505. AcpiMultiNode->RsdtAddress.QuadPart = rsdp->XsdtAddress.QuadPart;
  506. }
  507. CurrentEntry->ConfigurationData = Current;
  508. Component = &CurrentEntry->ComponentEntry;
  509. Component->ConfigurationDataLength = Length;
  510. Component->Class = AdapterClass;
  511. Component->Type = MultiFunctionAdapter;
  512. strcpy (Identifier, "ACPI BIOS");
  513. i = strlen(Identifier) + 1;
  514. IdentifierString = (PCHAR)BlAllocateHeap(i);
  515. strcpy(IdentifierString, Identifier);
  516. Component->Version = 0;
  517. Component->Key = 0;
  518. Component->AffinityMask = 0xffffffff;
  519. Component->IdentifierLength = i;
  520. Component->Identifier = IdentifierString;
  521. HwSetUpFreeFormDataHeader(
  522. (PHWRESOURCE_DESCRIPTOR_LIST) ConfigurationData,
  523. 0,
  524. 0,
  525. 0,
  526. Length - DATA_HEADER_SIZE
  527. );
  528. //
  529. // Add it to tree
  530. //
  531. #if defined(_INCLUDE_COMPORT_INFO_)
  532. //
  533. // Note: this assumes the previousentry is a child of the AdapterEntry,
  534. // typically, this would be the comport info node
  535. //
  536. if (NextRelationship == Sibling) {
  537. PreviousEntry->Parent->Sibling = CurrentEntry;
  538. CurrentEntry->Parent = PreviousEntry->Parent->Parent;
  539. }
  540. NextRelationship = Sibling;
  541. #else
  542. //
  543. // ACPI BIOS node is a sibling of AdapterEntry
  544. //
  545. if (NextRelationship == Sibling) {
  546. PreviousEntry->Sibling = CurrentEntry;
  547. CurrentEntry->Parent = PreviousEntry->Parent;
  548. }
  549. //
  550. // ARC disk info node must be child of adapter entry
  551. //
  552. NextRelationship = Child;
  553. PreviousEntry = AdapterEntry;
  554. #endif
  555. #if 0
  556. if (NextRelationship == Sibling) {
  557. PreviousEntry->Sibling = CurrentEntry;
  558. CurrentEntry->Parent = PreviousEntry->Parent;
  559. } else {
  560. PreviousEntry->Child = CurrentEntry;
  561. CurrentEntry->Parent = PreviousEntry;
  562. }
  563. NextRelationship = Sibling;
  564. PreviousEntry = CurrentEntry;
  565. #endif
  566. //
  567. // First entry created to make BlGetArcDiskInformation() happy
  568. //
  569. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  570. sizeof(CONFIGURATION_COMPONENT_DATA));
  571. Component = &CurrentEntry->ComponentEntry;
  572. Component->ConfigurationDataLength = 0;
  573. Component->Class = ControllerClass;
  574. Component->Type = DiskController;
  575. strcpy (Identifier, "Controller Class Entry For Hard Disk");
  576. i = strlen(Identifier) + 1;
  577. IdentifierString = (PCHAR)BlAllocateHeap(i);
  578. strcpy(IdentifierString, Identifier);
  579. Component->Version = 0;
  580. Component->Key = 0;
  581. Component->AffinityMask = 0xffffffff;
  582. Component->IdentifierLength = i;
  583. Component->Identifier = IdentifierString;
  584. //
  585. // Add it to tree
  586. //
  587. if (NextRelationship == Sibling) {
  588. PreviousEntry->Sibling = CurrentEntry;
  589. CurrentEntry->Parent = PreviousEntry->Parent;
  590. } else {
  591. PreviousEntry->Child = CurrentEntry;
  592. CurrentEntry->Parent = PreviousEntry;
  593. }
  594. NextRelationship = Child;
  595. PreviousEntry = CurrentEntry;
  596. //
  597. // Looks for disks on system and add them.
  598. //
  599. for( j=0; j<GetDriveCount(); j++ ) {
  600. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  601. sizeof(CONFIGURATION_COMPONENT_DATA));
  602. Component = &CurrentEntry->ComponentEntry;
  603. Component->ConfigurationDataLength = 0;
  604. Component->Class = PeripheralClass;
  605. Component->Type = DiskPeripheral;
  606. strcpy (Identifier, "Peripheral Class Entry For Hard Disk");
  607. i = strlen(Identifier) + 1;
  608. IdentifierString = (PCHAR)BlAllocateHeap(i);
  609. strcpy(IdentifierString, Identifier);
  610. Component->Version = 0;
  611. Component->Key = j;
  612. Component->AffinityMask = 0xffffffff;
  613. Component->IdentifierLength = i;
  614. Component->Identifier = IdentifierString;
  615. //
  616. // Add it to tree
  617. //
  618. if (NextRelationship == Sibling) {
  619. PreviousEntry->Sibling = CurrentEntry;
  620. CurrentEntry->Parent = PreviousEntry->Parent;
  621. } else {
  622. PreviousEntry->Child = CurrentEntry;
  623. CurrentEntry->Parent = PreviousEntry;
  624. }
  625. NextRelationship = Sibling;
  626. PreviousEntry = CurrentEntry;
  627. }
  628. //
  629. // add an entry for the floppy disk peripheral
  630. //
  631. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  632. sizeof(CONFIGURATION_COMPONENT_DATA));
  633. Component = &CurrentEntry->ComponentEntry;
  634. Component->ConfigurationDataLength = 0;
  635. Component->Class = PeripheralClass;
  636. Component->Type = FloppyDiskPeripheral;
  637. strcpy (Identifier, "Peripheral Class Entry For Floppy Disk");
  638. i = strlen(Identifier) + 1;
  639. IdentifierString = (PCHAR)BlAllocateHeap(i);
  640. strcpy(IdentifierString, Identifier);
  641. Component->Version = 0;
  642. Component->Key = 0;
  643. Component->AffinityMask = 0xffffffff;
  644. Component->IdentifierLength = i;
  645. Component->Identifier = IdentifierString;
  646. //
  647. // Add it to tree
  648. //
  649. if (NextRelationship == Sibling) {
  650. PreviousEntry->Sibling = CurrentEntry;
  651. CurrentEntry->Parent = PreviousEntry->Parent;
  652. } else {
  653. PreviousEntry->Child = CurrentEntry;
  654. CurrentEntry->Parent = PreviousEntry;
  655. }
  656. NextRelationship = Sibling;
  657. PreviousEntry = CurrentEntry;
  658. //
  659. // add another entry for the floppy disk peripheral
  660. // for virtual floppy support
  661. //
  662. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  663. sizeof(CONFIGURATION_COMPONENT_DATA));
  664. Component = &CurrentEntry->ComponentEntry;
  665. Component->ConfigurationDataLength = 0;
  666. Component->Class = PeripheralClass;
  667. Component->Type = FloppyDiskPeripheral;
  668. strcpy (Identifier, "Peripheral Class Entry For Floppy Disk");
  669. i = strlen(Identifier) + 1;
  670. IdentifierString = (PCHAR)BlAllocateHeap(i);
  671. strcpy(IdentifierString, Identifier);
  672. Component->Version = 0;
  673. Component->Key = 1;
  674. Component->AffinityMask = 0xffffffff;
  675. Component->IdentifierLength = i;
  676. Component->Identifier = IdentifierString;
  677. //
  678. // Add it to tree
  679. //
  680. if (NextRelationship == Sibling) {
  681. PreviousEntry->Sibling = CurrentEntry;
  682. CurrentEntry->Parent = PreviousEntry->Parent;
  683. } else {
  684. PreviousEntry->Child = CurrentEntry;
  685. CurrentEntry->Parent = PreviousEntry;
  686. }
  687. NextRelationship = Child;
  688. PreviousEntry = CurrentEntry;
  689. //
  690. // Done
  691. //
  692. FwConfigurationTree = (PCONFIGURATION_COMPONENT_DATA) ConfigurationRoot;
  693. }
  694. #if defined(_INCLUDE_LOADER_KBINFO_)
  695. PCONFIGURATION_COMPONENT_DATA
  696. SetKeyboardConfigurationData (
  697. USHORT KeyboardId
  698. )
  699. /*++
  700. Routine Description:
  701. This routine maps Keyboard Id information to an ASCII string and
  702. stores the string in configuration data heap.
  703. Arguments:
  704. KeyboardId - Supplies a USHORT which describes the keyboard id information.
  705. Buffer - Supplies a pointer to a buffer where to put the ascii.
  706. Returns:
  707. None.
  708. --*/
  709. {
  710. PCONFIGURATION_COMPONENT_DATA Controller, CurrentEntry;
  711. PCONFIGURATION_COMPONENT Component;
  712. HWCONTROLLER_DATA ControlData;
  713. PHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
  714. CM_KEYBOARD_DEVICE_DATA *KeyboardData;
  715. USHORT z, Length;
  716. //
  717. // Set up Keyboard COntroller component
  718. //
  719. ControlData.NumberPortEntries = 0;
  720. ControlData.NumberIrqEntries = 0;
  721. ControlData.NumberMemoryEntries = 0;
  722. ControlData.NumberDmaEntries = 0;
  723. z = 0;
  724. Controller = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  725. sizeof(CONFIGURATION_COMPONENT_DATA));
  726. Component = &Controller->ComponentEntry;
  727. Component->Class = ControllerClass;
  728. Component->Type = KeyboardController;
  729. Component->Flags.ConsoleIn = 1;
  730. Component->Flags.Input = 1;
  731. Component->Version = 0;
  732. Component->Key = 0;
  733. Component->AffinityMask = 0xffffffff;
  734. //
  735. // Set up Port information
  736. //
  737. ControlData.NumberPortEntries = 2;
  738. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  739. ControlData.DescriptorList[z].ShareDisposition =
  740. CmResourceShareDeviceExclusive;
  741. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  742. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x60;
  743. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  744. ControlData.DescriptorList[z].u.Port.Length = 1;
  745. z++;
  746. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  747. ControlData.DescriptorList[z].ShareDisposition =
  748. CmResourceShareDeviceExclusive;
  749. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  750. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x64;
  751. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  752. ControlData.DescriptorList[z].u.Port.Length = 1;
  753. z++;
  754. //
  755. // Set up Irq information
  756. //
  757. ControlData.NumberIrqEntries = 1;
  758. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  759. ControlData.DescriptorList[z].ShareDisposition =
  760. CmResourceShareUndetermined;
  761. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  762. ControlData.DescriptorList[z].u.Interrupt.Level = 1;
  763. ControlData.DescriptorList[z].u.Interrupt.Vector = 1;
  764. if (HwBusType == MACHINE_TYPE_MCA) {
  765. ControlData.DescriptorList[z].Flags = LEVEL_SENSITIVE;
  766. } else {
  767. //
  768. // For EISA the LevelTriggered is temporarily set to FALSE.
  769. //
  770. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  771. }
  772. Controller->ConfigurationData =
  773. HwSetUpResourceDescriptor(Component,
  774. NULL,
  775. &ControlData,
  776. 0,
  777. NULL
  778. );
  779. //
  780. // Set up Keyboard peripheral component
  781. //
  782. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  783. sizeof(CONFIGURATION_COMPONENT_DATA));
  784. Component = &CurrentEntry->ComponentEntry;
  785. Component->Class = PeripheralClass;
  786. Component->Type = KeyboardPeripheral;
  787. Component->Flags.ConsoleIn = 1;
  788. Component->Flags.Input = 1;
  789. Component->Version = 0;
  790. Component->Key = 0;
  791. Component->AffinityMask = 0xffffffff;
  792. Component->ConfigurationDataLength = 0;
  793. CurrentEntry->ConfigurationData = (PVOID)NULL;
  794. Length = strlen(KeyboardIdentifier[KeyboardId]) + 1;
  795. Component->IdentifierLength = Length;
  796. Component->Identifier = BlAllocateHeap(Length);
  797. strcpy(Component->Identifier, KeyboardIdentifier[KeyboardId]);
  798. if (KeyboardId != UNKNOWN_KEYBOARD) {
  799. Length = sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
  800. sizeof(CM_KEYBOARD_DEVICE_DATA);
  801. DescriptorList = (PHWRESOURCE_DESCRIPTOR_LIST)BlAllocateHeap(Length);
  802. CurrentEntry->ConfigurationData = DescriptorList;
  803. Component->ConfigurationDataLength = Length;
  804. DescriptorList->Count = 1;
  805. DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  806. DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
  807. sizeof(CM_KEYBOARD_DEVICE_DATA);
  808. KeyboardData = (CM_KEYBOARD_DEVICE_DATA *)(DescriptorList + 1);
  809. KeyboardData->KeyboardFlags = 0;
  810. KeyboardData->Type = KeyboardType[KeyboardId];
  811. KeyboardData->Subtype = KeyboardSubtype[KeyboardId];
  812. }
  813. Controller->Child = CurrentEntry;
  814. Controller->Sibling = NULL;
  815. CurrentEntry->Parent = Controller;
  816. CurrentEntry->Sibling = NULL;
  817. CurrentEntry->Child = NULL;
  818. return(Controller);
  819. }
  820. #endif
  821. #if defined(_INCLUDE_LOADER_MOUSEINFO_)
  822. PCONFIGURATION_COMPONENT_DATA
  823. SetMouseConfigurationData (
  824. PMOUSE_INFORMATION MouseInfo,
  825. PCONFIGURATION_COMPONENT_DATA MouseList
  826. )
  827. /*++
  828. Routine Description:
  829. This routine fills in mouse configuration data.
  830. Arguments:
  831. MouseInfo - Supplies a pointer to the MOUSE_INFOR structure
  832. MouseList - Supplies a pointer to the existing mouse component list.
  833. Returns:
  834. Returns a pointer to our mice controller list.
  835. --*/
  836. {
  837. UCHAR i = 0;
  838. PCONFIGURATION_COMPONENT_DATA CurrentEntry, Controller, PeripheralEntry;
  839. PCONFIGURATION_COMPONENT Component;
  840. HWCONTROLLER_DATA ControlData;
  841. USHORT z, Length;
  842. PUCHAR pString;
  843. if ((MouseInfo->MouseSubtype != SERIAL_MOUSE) &&
  844. (MouseInfo->MouseSubtype != SERIAL_MOUSE_WITH_WHEEL)) {
  845. //
  846. // Initialize Controller data
  847. //
  848. ControlData.NumberPortEntries = 0;
  849. ControlData.NumberIrqEntries = 0;
  850. ControlData.NumberMemoryEntries = 0;
  851. ControlData.NumberDmaEntries = 0;
  852. z = 0;
  853. //
  854. // If it is not SERIAL_MOUSE, set up controller component
  855. //
  856. Controller = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  857. sizeof(CONFIGURATION_COMPONENT_DATA));
  858. Component = &Controller->ComponentEntry;
  859. Component->Class = ControllerClass;
  860. Component->Type = PointerController;
  861. Component->Flags.Input = 1;
  862. Component->Version = 0;
  863. Component->Key = MouseControllerKey;
  864. MouseControllerKey++;
  865. Component->AffinityMask = 0xffffffff;
  866. Component->IdentifierLength = 0;
  867. Component->Identifier = NULL;
  868. //
  869. // If we have mouse irq or port information, allocate configuration
  870. // data space for mouse controller component to store these information
  871. //
  872. if (MouseInfo->MouseIrq != 0xffff || MouseInfo->MousePort != 0xffff) {
  873. //
  874. // Set up port and Irq information
  875. //
  876. if (MouseInfo->MousePort != 0xffff) {
  877. ControlData.NumberPortEntries = 1;
  878. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  879. ControlData.DescriptorList[z].ShareDisposition =
  880. CmResourceShareDeviceExclusive;
  881. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  882. ControlData.DescriptorList[z].u.Port.Start.LowPart =
  883. (ULONG)MouseInfo->MousePort;
  884. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  885. ControlData.DescriptorList[z].u.Port.Length = 4;
  886. z++;
  887. }
  888. if (MouseInfo->MouseIrq != 0xffff) {
  889. ControlData.NumberIrqEntries = 1;
  890. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  891. ControlData.DescriptorList[z].ShareDisposition =
  892. CmResourceShareUndetermined;
  893. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  894. ControlData.DescriptorList[z].u.Interrupt.Level =
  895. (ULONG)MouseInfo->MouseIrq;
  896. ControlData.DescriptorList[z].u.Interrupt.Vector =
  897. (ULONG)MouseInfo->MouseIrq;
  898. if (HwBusType == MACHINE_TYPE_MCA) {
  899. ControlData.DescriptorList[z].Flags =
  900. LEVEL_SENSITIVE;
  901. } else {
  902. //
  903. // For EISA the LevelTriggered is temporarily set to FALSE.
  904. //
  905. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  906. }
  907. }
  908. Controller->ConfigurationData =
  909. HwSetUpResourceDescriptor(Component,
  910. NULL,
  911. &ControlData,
  912. 0,
  913. NULL
  914. );
  915. } else {
  916. //
  917. // Otherwise, we don't have configuration data for the controller
  918. //
  919. Controller->ConfigurationData = NULL;
  920. Component->ConfigurationDataLength = 0;
  921. }
  922. }
  923. //
  924. // Set up Mouse peripheral component
  925. //
  926. PeripheralEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  927. sizeof(CONFIGURATION_COMPONENT_DATA));
  928. Component = &PeripheralEntry->ComponentEntry;
  929. Component->Class = PeripheralClass;
  930. Component->Type = PointerPeripheral;
  931. Component->Flags.Input = 1;
  932. Component->Version = 0;
  933. Component->Key = 0;
  934. Component->AffinityMask = 0xffffffff;
  935. Component->ConfigurationDataLength = 0;
  936. PeripheralEntry->ConfigurationData = (PVOID)NULL;
  937. //
  938. // If Mouse PnP device id is found, translate it to ascii code.
  939. // (The mouse device id is presented to us by keyboard make code.)
  940. //
  941. Length = 0;
  942. if (MouseInfo->DeviceIdLength != 0) {
  943. USHORT i;
  944. if (MouseInfo->MouseSubtype == PS_MOUSE_WITH_WHEEL) {
  945. for (i = 0; i < MouseInfo->DeviceIdLength; i++) {
  946. if (MouseInfo->DeviceId[i] > MAX_MAKE_CODE_TRANSLATED) {
  947. MouseInfo->DeviceId[i] = '?';
  948. } else {
  949. MouseInfo->DeviceId[i] = MakeToAsciiTable[MouseInfo->DeviceId[i]];
  950. }
  951. }
  952. } else if (MouseInfo->MouseSubtype == SERIAL_MOUSE_WITH_WHEEL) {
  953. for (i = 0; i < MouseInfo->DeviceIdLength; i++) {
  954. MouseInfo->DeviceId[i] += 0x20;
  955. }
  956. }
  957. Length = MouseInfo->DeviceIdLength + 3;
  958. }
  959. Length += strlen(MouseIdentifier[MouseInfo->MouseType]) +
  960. strlen(MouseSubidentifier[MouseInfo->MouseSubtype]) + 1;
  961. pString = (PUCHAR)BlAllocateHeap(Length);
  962. if (MouseInfo->DeviceIdLength != 0) {
  963. strcpy(pString, MouseInfo->DeviceId);
  964. strcat(pString, " - ");
  965. strcat(pString, MouseIdentifier[MouseInfo->MouseType]);
  966. } else {
  967. strcpy(pString, MouseIdentifier[MouseInfo->MouseType]);
  968. }
  969. strcat(pString, MouseSubidentifier[MouseInfo->MouseSubtype]);
  970. Component->IdentifierLength = Length;
  971. Component->Identifier = pString;
  972. if ((MouseInfo->MouseSubtype != SERIAL_MOUSE) &&
  973. (MouseInfo->MouseSubtype != SERIAL_MOUSE_WITH_WHEEL)) {
  974. Controller->Child = PeripheralEntry;
  975. PeripheralEntry->Parent = Controller;
  976. if (MouseList) {
  977. //
  978. // Put the current mouse component to the beginning of the list
  979. //
  980. Controller->Sibling = MouseList;
  981. }
  982. return(Controller);
  983. } else {
  984. CurrentEntry = AdapterEntry->Child; // AdapterEntry MUST have child
  985. while (CurrentEntry) {
  986. if (CurrentEntry->ComponentEntry.Type == SerialController) {
  987. if (MouseInfo->MousePort == (USHORT)CurrentEntry->ComponentEntry.Key) {
  988. //
  989. // For serial mouse, the MousePort field contains
  990. // COM port number.
  991. //
  992. PeripheralEntry->Parent = CurrentEntry;
  993. CurrentEntry->Child = PeripheralEntry;
  994. break;
  995. }
  996. }
  997. CurrentEntry = CurrentEntry->Sibling;
  998. }
  999. return(NULL);
  1000. }
  1001. }
  1002. PCONFIGURATION_COMPONENT_DATA
  1003. GetMouseInformation (
  1004. VOID
  1005. )
  1006. /*++
  1007. Routine Description:
  1008. This routine is the entry for mouse detection routine. It will invoke
  1009. lower level routines to detect ALL the mice in the system.
  1010. Arguments:
  1011. None.
  1012. Returns:
  1013. A pointer to a mouse component structure, if mouse/mice is detected.
  1014. Otherwise a NULL pointer is returned.
  1015. --*/
  1016. {
  1017. PMOUSE_INFORMATION MouseInfo;
  1018. PCONFIGURATION_COMPONENT_DATA MouseList = NULL;
  1019. MouseInfo = (PMOUSE_INFORMATION)BlAllocateHeap (
  1020. sizeof(MOUSE_INFORMATION));
  1021. MouseInfo->MouseType = 0x2; // Microsoft mouse
  1022. MouseInfo->MouseSubtype = PS2_MOUSE; // PS2 mouse
  1023. MouseInfo->MousePort = 0xffff; // PS2 mouse port
  1024. MouseInfo->MouseIrq = 0xc; // Interrupt request vector was 3
  1025. MouseInfo->DeviceIdLength = 0;
  1026. MouseList = SetMouseConfigurationData(MouseInfo, MouseList);
  1027. return(MouseList);
  1028. }
  1029. #endif // _INCLUDE_LOADER_MOUSEINFO_
  1030. #if defined(_INCLUDE_COMPORT_INFO_)
  1031. //
  1032. // This code was taken out because the GetComportInformation() routine
  1033. // was manufacturing data about the com port and writing the com port
  1034. // address to 40:0. This information should be determined by PnP
  1035. //
  1036. PCONFIGURATION_COMPONENT_DATA
  1037. GetComportInformation (
  1038. VOID
  1039. )
  1040. /*++
  1041. Routine Description:
  1042. This routine will attempt to detect the comports information
  1043. for the system. The information includes port address, irq
  1044. level.
  1045. Note that this routine can only detect up to 4 comports and
  1046. it assumes that if MCA, COM3 and COM4 use irq 4. Otherwise,
  1047. COM3 uses irq 4 and COM4 uses irq 3. Also, the number of ports
  1048. for COMPORT is set to 8 (for example, COM2 uses ports 2F8 - 2FF)
  1049. Arguments:
  1050. None.
  1051. Return Value:
  1052. A pointer to a stucture of type CONFIGURATION_COMPONENT_DATA
  1053. which is the root of comport component list.
  1054. If no comport exists, a value of NULL is returned.
  1055. --*/
  1056. {
  1057. PCONFIGURATION_COMPONENT_DATA CurrentEntry, PreviousEntry = NULL;
  1058. PCONFIGURATION_COMPONENT_DATA FirstComport = NULL;
  1059. PCONFIGURATION_COMPONENT Component;
  1060. HWCONTROLLER_DATA ControlData;
  1061. UCHAR i, j, z;
  1062. SHORT Port;
  1063. UCHAR ComportName[] = "COM?";
  1064. CM_SERIAL_DEVICE_DATA SerialData;
  1065. ULONG BaudClock = 1843200;
  1066. USHORT Vector;
  1067. USHORT IoPorts[MAX_COM_PORTS] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
  1068. //
  1069. // BIOS DATA area 40:0 is the port address of the first valid COM port
  1070. //
  1071. USHORT *pPortAddress = (USHORT *)0x00400000;
  1072. //
  1073. // Initialize serial device specific data
  1074. //
  1075. SerialData.Version = 0;
  1076. SerialData.Revision = 0;
  1077. SerialData.BaudClock = 1843200;
  1078. //
  1079. // Initialize Controller data
  1080. //
  1081. ControlData.NumberPortEntries = 0;
  1082. ControlData.NumberIrqEntries = 0;
  1083. ControlData.NumberMemoryEntries = 0;
  1084. ControlData.NumberDmaEntries = 0;
  1085. z = 0;
  1086. i = 0;
  1087. Port = IoPorts[i];
  1088. *(pPortAddress+i) = (USHORT)Port;
  1089. //
  1090. // Remember the port address in our global variable
  1091. // such that other detection code (e.g. Serial Mouse) can
  1092. // get the information.
  1093. //
  1094. #if 0 // unused
  1095. ComPortAddress[i] = Port;
  1096. #endif
  1097. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  1098. sizeof(CONFIGURATION_COMPONENT_DATA));
  1099. if (!FirstComport) {
  1100. FirstComport = CurrentEntry;
  1101. }
  1102. Component = &CurrentEntry->ComponentEntry;
  1103. Component->Class = ControllerClass;
  1104. Component->Type = SerialController;
  1105. Component->Flags.ConsoleOut = 1;
  1106. Component->Flags.ConsoleIn = 1;
  1107. Component->Flags.Output = 1;
  1108. Component->Flags.Input = 1;
  1109. Component->Version = 0;
  1110. Component->Key = i;
  1111. Component->AffinityMask = 0xffffffff;
  1112. //
  1113. // Set up type string.
  1114. //
  1115. ComportName[3] = i + (UCHAR)'1';
  1116. //
  1117. // Set up Port information
  1118. //
  1119. ControlData.NumberPortEntries = 1;
  1120. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  1121. ControlData.DescriptorList[z].ShareDisposition =
  1122. CmResourceShareDeviceExclusive;
  1123. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  1124. ControlData.DescriptorList[z].u.Port.Start.LowPart = (ULONG)Port;
  1125. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  1126. ControlData.DescriptorList[z].u.Port.Length = 8;
  1127. z++;
  1128. //
  1129. // Set up Irq information
  1130. //
  1131. ControlData.NumberIrqEntries = 1;
  1132. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  1133. ControlData.DescriptorList[z].ShareDisposition =
  1134. CmResourceShareUndetermined;
  1135. //
  1136. // For EISA the LevelTriggered is temporarily set to FALSE.
  1137. // COM1 and COM3 use irq 4; COM2 and COM4 use irq3
  1138. //
  1139. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  1140. if (Port == 0x3f8 || Port == 0x3e8) {
  1141. ControlData.DescriptorList[z].u.Interrupt.Level = 4;
  1142. ControlData.DescriptorList[z].u.Interrupt.Vector = 4;
  1143. } else if (Port == 0x2f8 || Port == 0x2e8) {
  1144. ControlData.DescriptorList[z].u.Interrupt.Level = 3;
  1145. ControlData.DescriptorList[z].u.Interrupt.Vector = 3;
  1146. } else if (i == 0 || i == 2) {
  1147. ControlData.DescriptorList[z].u.Interrupt.Level = 4;
  1148. ControlData.DescriptorList[z].u.Interrupt.Vector = 4;
  1149. } else {
  1150. ControlData.DescriptorList[z].u.Interrupt.Level = 3;
  1151. ControlData.DescriptorList[z].u.Interrupt.Vector = 3;
  1152. }
  1153. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  1154. //
  1155. // Try to determine the interrupt vector. If we success, the
  1156. // new vector will be used to replace the default value.
  1157. //
  1158. CurrentEntry->ConfigurationData =
  1159. HwSetUpResourceDescriptor(Component,
  1160. ComportName,
  1161. &ControlData,
  1162. sizeof(SerialData),
  1163. (PUCHAR)&SerialData
  1164. );
  1165. if (PreviousEntry) {
  1166. PreviousEntry->Sibling = CurrentEntry;
  1167. }
  1168. PreviousEntry = CurrentEntry;
  1169. return(FirstComport);
  1170. }
  1171. #endif
  1172. PVOID
  1173. HwSetUpResourceDescriptor (
  1174. PCONFIGURATION_COMPONENT Component,
  1175. PUCHAR Identifier,
  1176. PHWCONTROLLER_DATA ControlData,
  1177. USHORT SpecificDataLength,
  1178. PUCHAR SpecificData
  1179. )
  1180. /*++
  1181. Routine Description:
  1182. This routine allocates space from heap , puts the caller's controller
  1183. information to the space and sets up CONFIGURATION_COMPONENT
  1184. structure for the caller.
  1185. Arguments:
  1186. Component - Supplies the address the component whose configuration data
  1187. should be set up.
  1188. Identifier - Suppies a pointer to the identifier to identify the controller
  1189. ControlData - Supplies a point to a structure which describes
  1190. controller information.
  1191. SpecificDataLength - size of the device specific data. Device specific
  1192. data is the information not defined in the standard format.
  1193. SpecificData - Supplies a pointer to the device specific data.
  1194. Return Value:
  1195. Returns a pointer to the Configuration data.
  1196. --*/
  1197. {
  1198. PCHAR pIdentifier;
  1199. PHWRESOURCE_DESCRIPTOR_LIST pDescriptor = NULL;
  1200. USHORT Length;
  1201. SHORT Count, i;
  1202. PUCHAR pSpecificData;
  1203. //
  1204. // Set up Identifier string for hardware component, if necessary.
  1205. //
  1206. if (Identifier) {
  1207. Length = strlen(Identifier) + 1;
  1208. Component->IdentifierLength = Length;
  1209. pIdentifier = (PUCHAR)BlAllocateHeap(Length);
  1210. Component->Identifier = pIdentifier;
  1211. strcpy(pIdentifier, Identifier);
  1212. } else {
  1213. Component->IdentifierLength = 0;
  1214. Component->Identifier = NULL;
  1215. }
  1216. //
  1217. // Set up configuration data for hardware component, if necessary
  1218. //
  1219. Count = ControlData->NumberPortEntries + ControlData->NumberIrqEntries +
  1220. ControlData->NumberMemoryEntries + ControlData->NumberDmaEntries;
  1221. if (SpecificDataLength) {
  1222. //
  1223. // if we have device specific data, we need to increment the count
  1224. // by one.
  1225. //
  1226. Count++;
  1227. }
  1228. if (Count >0) {
  1229. Length = (USHORT)(Count * sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR) +
  1230. FIELD_OFFSET(HWRESOURCE_DESCRIPTOR_LIST, PartialDescriptors) +
  1231. SpecificDataLength);
  1232. pDescriptor = (PHWRESOURCE_DESCRIPTOR_LIST)BlAllocateHeap(Length);
  1233. pDescriptor->Count = Count;
  1234. //
  1235. // Copy all the partial descriptors to the destination descriptors
  1236. // except the last one. (The last partial descriptor may be a device
  1237. // specific data. It requires special handling.)
  1238. //
  1239. for (i = 0; i < (Count - 1); i++) {
  1240. pDescriptor->PartialDescriptors[i] =
  1241. ControlData->DescriptorList[i];
  1242. }
  1243. //
  1244. // Set up the last partial descriptor. If it is a port, memory, irq or
  1245. // dma entry, we simply copy it. If the last one is for device specific
  1246. // data, we set up the length and copy the device spcific data to the end
  1247. // of the decriptor.
  1248. //
  1249. if (SpecificData) {
  1250. pDescriptor->PartialDescriptors[Count - 1].Type =
  1251. RESOURCE_DEVICE_DATA;
  1252. pDescriptor->PartialDescriptors[Count - 1].Flags = 0;
  1253. pDescriptor->PartialDescriptors[Count - 1].u.DeviceSpecificData.DataSize =
  1254. SpecificDataLength;
  1255. pSpecificData = (PUCHAR)&(pDescriptor->PartialDescriptors[Count]);
  1256. RtlCopyMemory( pSpecificData, SpecificData, SpecificDataLength);
  1257. } else {
  1258. pDescriptor->PartialDescriptors[Count - 1] =
  1259. ControlData->DescriptorList[Count - 1];
  1260. }
  1261. Component->ConfigurationDataLength = Length;
  1262. }
  1263. return(pDescriptor);
  1264. }
  1265. VOID
  1266. HwSetUpFreeFormDataHeader (
  1267. PHWRESOURCE_DESCRIPTOR_LIST Header,
  1268. USHORT Version,
  1269. USHORT Revision,
  1270. USHORT Flags,
  1271. ULONG DataSize
  1272. )
  1273. /*++
  1274. Routine Description:
  1275. This routine initialize free formed data header. Note this routine
  1276. sets the the Header and initialize the FIRST PartialDescriptor only.
  1277. If the header contains more than one descriptor, the caller must handle
  1278. it itself.
  1279. Arguments:
  1280. Header - Supplies a pointer to the header to be initialized.
  1281. Version - Version number for the header.
  1282. Revision - Revision number for the header.
  1283. Flags - Free formed data flags. (Currently, it is undefined and
  1284. should be zero.)
  1285. DataSize - Size of the free formed data.
  1286. Return Value:
  1287. None.
  1288. --*/
  1289. {
  1290. Header->Version = Version;
  1291. Header->Revision = Revision;
  1292. Header->Count = 1;
  1293. Header->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  1294. Header->PartialDescriptors[0].ShareDisposition = 0;
  1295. Header->PartialDescriptors[0].Flags = Flags;
  1296. Header->PartialDescriptors[0].u.DeviceSpecificData.DataSize = DataSize;
  1297. Header->PartialDescriptors[0].u.DeviceSpecificData.Reserved1 = 0;
  1298. Header->PartialDescriptors[0].u.DeviceSpecificData.Reserved2 = 0;
  1299. }