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.

1630 lines
47 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. #include "extern.h"
  20. //
  21. // External Data
  22. //
  23. extern PCONFIGURATION_COMPONENT_DATA FwConfigurationTree;
  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 CurrentEntry, PreviousEntry;
  267. PCONFIGURATION_COMPONENT Component;
  268. RELATIONSHIP_FLAGS NextRelationship;
  269. CHAR Identifier[256];
  270. PCHAR MachineId;
  271. #if defined(_INCLUDE_LOADER_KBINFO_)
  272. USHORT KeyboardId = 0;
  273. #endif
  274. USHORT Length, InitialLength, i, j;
  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. PACPI_BIOS_MULTI_NODE AcpiMultiNode;
  282. PUCHAR Current;
  283. PRSDP rsdp;
  284. //
  285. // Allocate heap space for System component and initialize it.
  286. // Also make the System component the root of configuration tree.
  287. //
  288. ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  289. sizeof(CONFIGURATION_COMPONENT_DATA));
  290. Component = &ConfigurationRoot->ComponentEntry;
  291. Component->Class = SystemClass;
  292. Component->Type = MaximumType; // NOTE should be IsaCompatible
  293. Component->Version = 0;
  294. Component->Key = 0;
  295. Component->AffinityMask = 0;
  296. Component->ConfigurationDataLength = 0;
  297. MachineId = "Intel Itanium processor family";
  298. if (MachineId) {
  299. Length = RESET_SIZE_AT_USHORT_MAX(strlen(MachineId) + 1);
  300. IdentifierString = (PCHAR)BlAllocateHeap(Length);
  301. strcpy(IdentifierString, MachineId);
  302. Component->Identifier = IdentifierString;
  303. Component->IdentifierLength = Length;
  304. } else {
  305. Component->Identifier = 0;
  306. Component->IdentifierLength = 0;
  307. }
  308. NextRelationship = Child;
  309. PreviousEntry = ConfigurationRoot;
  310. //
  311. // ISA
  312. //
  313. AdapterEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  314. sizeof(CONFIGURATION_COMPONENT_DATA));
  315. Component = &AdapterEntry->ComponentEntry;
  316. Component->Class = AdapterClass;
  317. Component->Type = MultiFunctionAdapter;
  318. strcpy(Identifier, "ISA");
  319. Length = RESET_SIZE_AT_USHORT_MAX(strlen(Identifier) + 1);
  320. IdentifierString = (PCHAR)BlAllocateHeap(Length);
  321. strcpy(IdentifierString, Identifier);
  322. Component->Version = 0;
  323. Component->Key = 0;
  324. Component->AffinityMask = 0xffffffff;
  325. Component->IdentifierLength = Length;
  326. Component->Identifier = IdentifierString;
  327. //
  328. // Make Adapter component System's child
  329. //
  330. if (NextRelationship == Sibling) {
  331. PreviousEntry->Sibling = AdapterEntry;
  332. AdapterEntry->Parent = PreviousEntry->Parent;
  333. } else {
  334. PreviousEntry->Child = AdapterEntry;
  335. AdapterEntry->Parent = PreviousEntry;
  336. }
  337. NextRelationship = Child;
  338. PreviousEntry = AdapterEntry;
  339. //
  340. // Collect BIOS information for ConfigurationRoot component.
  341. // This step is done here because we need data collected in
  342. // adapter component. The ConfigurationData is:
  343. // HWRESOURCE_DESCRIPTOR_LIST header
  344. // HWPARTIAL_RESOURCE_DESCRIPTOR for Parameter Table
  345. // HWPARTIAL_RESOURCE_DESCRIPTOR for Rom Blocks.
  346. // (Note DATA_HEADER_SIZE contains the size of the first partial
  347. // descriptor already.)
  348. //
  349. #if DBG
  350. BlPrint(TEXT("Collecting Disk Geometry...\r\n"));
  351. #endif
  352. RomChain = (PHARD_DISK_PARAMETERS)
  353. BlAllocateHeap(SIZE_OF_PARAMETER * MAX_DRIVE_NUMBER);
  354. #if 0
  355. RomChain[0].DriveSelect = 0x80;
  356. RomChain[0].MaxCylinders = 0;
  357. RomChain[0].SectorsPerTrack = 0;
  358. RomChain[0].MaxHeads = 0;
  359. RomChain[0].NumberDrives = 1; // Gambit only access 1 drive
  360. NumberBiosDisks = 1; // was defined in diska.asm
  361. #endif
  362. InitialLength = (USHORT)(Length + RESERVED_ROM_BLOCK_LIST_SIZE + DATA_HEADER_SIZE +
  363. sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR));
  364. ConfigurationData = (PUCHAR)BlAllocateHeap(InitialLength);
  365. EndConfigurationData = ConfigurationData + DATA_HEADER_SIZE;
  366. if (Length != 0) {
  367. PRomChain = EndConfigurationData;
  368. RtlCopyMemory( PRomChain, (PVOID)RomChain, Length);
  369. }
  370. EndConfigurationData += (sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR) +
  371. Length);
  372. HwSetUpFreeFormDataHeader((PHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData,
  373. 0,
  374. 0,
  375. 0,
  376. Length
  377. );
  378. //
  379. // Scan ROM to collect all the ROM blocks, if possible.
  380. //
  381. #if DBG
  382. BlPrint(TEXT("Constructing ROM Blocks...\r\n"));
  383. #endif
  384. PRomBlock = EndConfigurationData;
  385. Length = 0;
  386. RomBlockLength = Length;
  387. if (Length != 0) {
  388. EndConfigurationData += Length;
  389. } else {
  390. PRomBlock = NULL;
  391. }
  392. //
  393. // We have both RomChain and RomBlock information/Headers.
  394. //
  395. DescriptorList = (PHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData;
  396. DescriptorList->Count = 2;
  397. Descriptor = (PHWPARTIAL_RESOURCE_DESCRIPTOR)(
  398. EndConfigurationData - Length -
  399. sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR));
  400. Descriptor->Type = RESOURCE_DEVICE_DATA;
  401. Descriptor->ShareDisposition = 0;
  402. Descriptor->Flags = 0;
  403. Descriptor->u.DeviceSpecificData.DataSize = (ULONG)Length;
  404. Descriptor->u.DeviceSpecificData.Reserved1 = 0;
  405. Descriptor->u.DeviceSpecificData.Reserved2 = 0;
  406. Length = (USHORT)(EndConfigurationData - ConfigurationData);
  407. ConfigurationRoot->ComponentEntry.ConfigurationDataLength = Length;
  408. ConfigurationRoot->ConfigurationData = ConfigurationData;
  409. FreeSize = InitialLength - Length;
  410. #if defined(_INCLUDE_LOADER_KBINFO_)
  411. //#if defined(NO_ACPI)
  412. //
  413. // Set up device information structure for Keyboard.
  414. //
  415. #if DBG
  416. BlPrint(TEXT("Constructing Keyboard Component ...\r\n"));
  417. #endif
  418. KeyboardId = 7; // PCAT_ENHANCED
  419. CurrentEntry = SetKeyboardConfigurationData(KeyboardId);
  420. //
  421. // Make display component the child of Adapter component.
  422. //
  423. if (NextRelationship == Sibling) {
  424. PreviousEntry->Sibling = CurrentEntry;
  425. CurrentEntry->Parent = PreviousEntry->Parent;
  426. } else {
  427. PreviousEntry->Child = CurrentEntry;
  428. CurrentEntry->Parent = PreviousEntry;
  429. }
  430. NextRelationship = Sibling;
  431. PreviousEntry = CurrentEntry;
  432. #endif // _INCLUDE_LOADER_MOUSEINFO_
  433. //
  434. // Set up device information for com port
  435. //
  436. #if defined(_INCLUDE_COMPORT_INFO_)
  437. //
  438. // This code was taken out because the GetComportInformation() routine
  439. // was manufacturing data about the com port and writing the com port
  440. // address to 40:0. This information should be determined by PnP
  441. //
  442. #if DBG
  443. BlPrint(TEXT("Constructing ComPort Component ...\r\n"));
  444. #endif
  445. if (CurrentEntry = GetComportInformation()) {
  446. //
  447. // Make current component the child of Adapter component.
  448. //
  449. if (NextRelationship == Sibling) {
  450. PreviousEntry->Sibling = CurrentEntry;
  451. } else {
  452. PreviousEntry->Child = CurrentEntry;
  453. }
  454. while (CurrentEntry) {
  455. CurrentEntry->Parent = AdapterEntry;
  456. PreviousEntry = CurrentEntry;
  457. CurrentEntry = CurrentEntry->Sibling;
  458. }
  459. NextRelationship = Sibling;
  460. }
  461. #else
  462. // DbgPrint("Skipping ComPort Component ...\r\n");
  463. //
  464. // acpi node should be a sibling of adapter entry
  465. //
  466. // Note: this only works if !defined(_INCLUDE_LOADER_MOUSEINFO_)
  467. //
  468. NextRelationship = Sibling;
  469. PreviousEntry = AdapterEntry;
  470. #endif
  471. #if defined(_INCLUDE_LOADER_MOUSEINFO_)
  472. //
  473. // Set up device information structure for Mouse.
  474. //
  475. #if DBG
  476. BlPrint(TEXT("Constructing Mouse Component ...\r\n"));
  477. #endif
  478. if (CurrentEntry = GetMouseInformation
  479. ()) {
  480. //
  481. // Make current component the child of Adapter component.
  482. //
  483. if (NextRelationship == Sibling) {
  484. PreviousEntry->Sibling = CurrentEntry;
  485. CurrentEntry->Parent = PreviousEntry->Parent;
  486. } else {
  487. PreviousEntry->Child = CurrentEntry;
  488. CurrentEntry->Parent = PreviousEntry;
  489. }
  490. NextRelationship = Sibling;
  491. PreviousEntry = CurrentEntry;
  492. }
  493. //#endif // NO_ACPI
  494. #endif // _INCLUDE_LOADER_MOUSEINFO_
  495. //DbgPrint("Constructing ACPI Bus Component ...\n");
  496. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  497. sizeof(CONFIGURATION_COMPONENT_DATA));
  498. Current = (PUCHAR) BlAllocateHeap( DATA_HEADER_SIZE +
  499. sizeof(ACPI_BIOS_MULTI_NODE) );
  500. AcpiMultiNode = (PACPI_BIOS_MULTI_NODE) (Current + DATA_HEADER_SIZE);
  501. //DbgPrint("AcpiTable: %p\n", AcpiTable);
  502. if (AcpiTable) {
  503. rsdp = (PRSDP) AcpiTable;
  504. AcpiMultiNode->RsdtAddress.QuadPart = rsdp->XsdtAddress.QuadPart;
  505. }
  506. CurrentEntry->ConfigurationData = Current;
  507. Component = &CurrentEntry->ComponentEntry;
  508. Component->ConfigurationDataLength = Length;
  509. Component->Class = AdapterClass;
  510. Component->Type = MultiFunctionAdapter;
  511. strcpy (Identifier, "ACPI BIOS");
  512. i = RESET_SIZE_AT_USHORT_MAX(strlen(Identifier) + 1);
  513. IdentifierString = (PCHAR)BlAllocateHeap(i);
  514. strcpy(IdentifierString, Identifier);
  515. Component->Version = 0;
  516. Component->Key = 0;
  517. Component->AffinityMask = 0xffffffff;
  518. Component->IdentifierLength = i;
  519. Component->Identifier = IdentifierString;
  520. HwSetUpFreeFormDataHeader(
  521. (PHWRESOURCE_DESCRIPTOR_LIST) ConfigurationData,
  522. 0,
  523. 0,
  524. 0,
  525. Length - DATA_HEADER_SIZE
  526. );
  527. //
  528. // Add it to tree
  529. //
  530. #if defined(_INCLUDE_COMPORT_INFO_)
  531. //
  532. // Note: this assumes the previousentry is a child of the AdapterEntry,
  533. // typically, this would be the comport info node
  534. //
  535. if (NextRelationship == Sibling) {
  536. PreviousEntry->Parent->Sibling = CurrentEntry;
  537. CurrentEntry->Parent = PreviousEntry->Parent->Parent;
  538. }
  539. NextRelationship = Sibling;
  540. #else
  541. //
  542. // ACPI BIOS node is a sibling of AdapterEntry
  543. //
  544. if (NextRelationship == Sibling) {
  545. PreviousEntry->Sibling = CurrentEntry;
  546. CurrentEntry->Parent = PreviousEntry->Parent;
  547. }
  548. //
  549. // ARC disk info node must be child of adapter entry
  550. //
  551. NextRelationship = Child;
  552. PreviousEntry = AdapterEntry;
  553. #endif
  554. #if 0
  555. if (NextRelationship == Sibling) {
  556. PreviousEntry->Sibling = CurrentEntry;
  557. CurrentEntry->Parent = PreviousEntry->Parent;
  558. } else {
  559. PreviousEntry->Child = CurrentEntry;
  560. CurrentEntry->Parent = PreviousEntry;
  561. }
  562. NextRelationship = Sibling;
  563. PreviousEntry = CurrentEntry;
  564. #endif
  565. //
  566. // First entry created to make BlGetArcDiskInformation() happy
  567. //
  568. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  569. sizeof(CONFIGURATION_COMPONENT_DATA));
  570. Component = &CurrentEntry->ComponentEntry;
  571. Component->ConfigurationDataLength = 0;
  572. Component->Class = ControllerClass;
  573. Component->Type = DiskController;
  574. strcpy (Identifier, "Controller Class Entry For Hard Disk");
  575. i = RESET_SIZE_AT_USHORT_MAX(strlen(Identifier) + 1);
  576. IdentifierString = (PCHAR)BlAllocateHeap(i);
  577. strcpy(IdentifierString, Identifier);
  578. Component->Version = 0;
  579. Component->Key = 0;
  580. Component->AffinityMask = 0xffffffff;
  581. Component->IdentifierLength = i;
  582. Component->Identifier = IdentifierString;
  583. //
  584. // Add it to tree
  585. //
  586. if (NextRelationship == Sibling) {
  587. PreviousEntry->Sibling = CurrentEntry;
  588. CurrentEntry->Parent = PreviousEntry->Parent;
  589. } else {
  590. PreviousEntry->Child = CurrentEntry;
  591. CurrentEntry->Parent = PreviousEntry;
  592. }
  593. NextRelationship = Child;
  594. PreviousEntry = CurrentEntry;
  595. //
  596. // Looks for disks on system and add them.
  597. //
  598. for( j=0; j<GetDriveCount(); j++ ) {
  599. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  600. sizeof(CONFIGURATION_COMPONENT_DATA));
  601. Component = &CurrentEntry->ComponentEntry;
  602. Component->ConfigurationDataLength = 0;
  603. Component->Class = PeripheralClass;
  604. Component->Type = DiskPeripheral;
  605. strcpy (Identifier, "Peripheral Class Entry For Hard Disk");
  606. i = RESET_SIZE_AT_USHORT_MAX(strlen(Identifier) + 1);
  607. IdentifierString = (PCHAR)BlAllocateHeap(i);
  608. strcpy(IdentifierString, Identifier);
  609. Component->Version = 0;
  610. Component->Key = j;
  611. Component->AffinityMask = 0xffffffff;
  612. Component->IdentifierLength = i;
  613. Component->Identifier = IdentifierString;
  614. //
  615. // Add it to tree
  616. //
  617. if (NextRelationship == Sibling) {
  618. PreviousEntry->Sibling = CurrentEntry;
  619. CurrentEntry->Parent = PreviousEntry->Parent;
  620. } else {
  621. PreviousEntry->Child = CurrentEntry;
  622. CurrentEntry->Parent = PreviousEntry;
  623. }
  624. NextRelationship = Sibling;
  625. PreviousEntry = CurrentEntry;
  626. }
  627. //
  628. // add an entry for the floppy disk peripheral
  629. //
  630. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  631. sizeof(CONFIGURATION_COMPONENT_DATA));
  632. Component = &CurrentEntry->ComponentEntry;
  633. Component->ConfigurationDataLength = 0;
  634. Component->Class = PeripheralClass;
  635. Component->Type = FloppyDiskPeripheral;
  636. strcpy (Identifier, "Peripheral Class Entry For Floppy Disk");
  637. i = RESET_SIZE_AT_USHORT_MAX(strlen(Identifier) + 1);
  638. IdentifierString = (PCHAR)BlAllocateHeap(i);
  639. strcpy(IdentifierString, Identifier);
  640. Component->Version = 0;
  641. Component->Key = 0;
  642. Component->AffinityMask = 0xffffffff;
  643. Component->IdentifierLength = i;
  644. Component->Identifier = IdentifierString;
  645. //
  646. // Add it to tree
  647. //
  648. if (NextRelationship == Sibling) {
  649. PreviousEntry->Sibling = CurrentEntry;
  650. CurrentEntry->Parent = PreviousEntry->Parent;
  651. } else {
  652. PreviousEntry->Child = CurrentEntry;
  653. CurrentEntry->Parent = PreviousEntry;
  654. }
  655. NextRelationship = Sibling;
  656. PreviousEntry = CurrentEntry;
  657. //
  658. // add another entry for the floppy disk peripheral
  659. // for virtual floppy support
  660. //
  661. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  662. sizeof(CONFIGURATION_COMPONENT_DATA));
  663. Component = &CurrentEntry->ComponentEntry;
  664. Component->ConfigurationDataLength = 0;
  665. Component->Class = PeripheralClass;
  666. Component->Type = FloppyDiskPeripheral;
  667. strcpy (Identifier, "Peripheral Class Entry For Floppy Disk");
  668. i = RESET_SIZE_AT_USHORT_MAX(strlen(Identifier) + 1);
  669. IdentifierString = (PCHAR)BlAllocateHeap(i);
  670. strcpy(IdentifierString, Identifier);
  671. Component->Version = 0;
  672. Component->Key = 1;
  673. Component->AffinityMask = 0xffffffff;
  674. Component->IdentifierLength = i;
  675. Component->Identifier = IdentifierString;
  676. //
  677. // Add it to tree
  678. //
  679. if (NextRelationship == Sibling) {
  680. PreviousEntry->Sibling = CurrentEntry;
  681. CurrentEntry->Parent = PreviousEntry->Parent;
  682. } else {
  683. PreviousEntry->Child = CurrentEntry;
  684. CurrentEntry->Parent = PreviousEntry;
  685. }
  686. NextRelationship = Child;
  687. PreviousEntry = CurrentEntry;
  688. //
  689. // Done
  690. //
  691. FwConfigurationTree = (PCONFIGURATION_COMPONENT_DATA) ConfigurationRoot;
  692. }
  693. #if defined(_INCLUDE_LOADER_KBINFO_)
  694. PCONFIGURATION_COMPONENT_DATA
  695. SetKeyboardConfigurationData (
  696. USHORT KeyboardId
  697. )
  698. /*++
  699. Routine Description:
  700. This routine maps Keyboard Id information to an ASCII string and
  701. stores the string in configuration data heap.
  702. Arguments:
  703. KeyboardId - Supplies a USHORT which describes the keyboard id information.
  704. Buffer - Supplies a pointer to a buffer where to put the ascii.
  705. Returns:
  706. None.
  707. --*/
  708. {
  709. PCONFIGURATION_COMPONENT_DATA Controller, CurrentEntry;
  710. PCONFIGURATION_COMPONENT Component;
  711. HWCONTROLLER_DATA ControlData;
  712. PHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
  713. CM_KEYBOARD_DEVICE_DATA *KeyboardData;
  714. USHORT z, Length;
  715. //
  716. // Set up Keyboard COntroller component
  717. //
  718. ControlData.NumberPortEntries = 0;
  719. ControlData.NumberIrqEntries = 0;
  720. ControlData.NumberMemoryEntries = 0;
  721. ControlData.NumberDmaEntries = 0;
  722. z = 0;
  723. Controller = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  724. sizeof(CONFIGURATION_COMPONENT_DATA));
  725. Component = &Controller->ComponentEntry;
  726. Component->Class = ControllerClass;
  727. Component->Type = KeyboardController;
  728. Component->Flags.ConsoleIn = 1;
  729. Component->Flags.Input = 1;
  730. Component->Version = 0;
  731. Component->Key = 0;
  732. Component->AffinityMask = 0xffffffff;
  733. //
  734. // Set up Port information
  735. //
  736. ControlData.NumberPortEntries = 2;
  737. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  738. ControlData.DescriptorList[z].ShareDisposition =
  739. CmResourceShareDeviceExclusive;
  740. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  741. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x60;
  742. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  743. ControlData.DescriptorList[z].u.Port.Length = 1;
  744. z++;
  745. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  746. ControlData.DescriptorList[z].ShareDisposition =
  747. CmResourceShareDeviceExclusive;
  748. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  749. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x64;
  750. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  751. ControlData.DescriptorList[z].u.Port.Length = 1;
  752. z++;
  753. //
  754. // Set up Irq information
  755. //
  756. ControlData.NumberIrqEntries = 1;
  757. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  758. ControlData.DescriptorList[z].ShareDisposition =
  759. CmResourceShareUndetermined;
  760. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  761. ControlData.DescriptorList[z].u.Interrupt.Level = 1;
  762. ControlData.DescriptorList[z].u.Interrupt.Vector = 1;
  763. if (HwBusType == MACHINE_TYPE_MCA) {
  764. ControlData.DescriptorList[z].Flags = LEVEL_SENSITIVE;
  765. } else {
  766. //
  767. // For EISA the LevelTriggered is temporarily set to FALSE.
  768. //
  769. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  770. }
  771. Controller->ConfigurationData =
  772. HwSetUpResourceDescriptor(Component,
  773. NULL,
  774. &ControlData,
  775. 0,
  776. NULL
  777. );
  778. //
  779. // Set up Keyboard peripheral component
  780. //
  781. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  782. sizeof(CONFIGURATION_COMPONENT_DATA));
  783. Component = &CurrentEntry->ComponentEntry;
  784. Component->Class = PeripheralClass;
  785. Component->Type = KeyboardPeripheral;
  786. Component->Flags.ConsoleIn = 1;
  787. Component->Flags.Input = 1;
  788. Component->Version = 0;
  789. Component->Key = 0;
  790. Component->AffinityMask = 0xffffffff;
  791. Component->ConfigurationDataLength = 0;
  792. CurrentEntry->ConfigurationData = (PVOID)NULL;
  793. Length = strlen(KeyboardIdentifier[KeyboardId]) + 1;
  794. Component->IdentifierLength = Length;
  795. Component->Identifier = BlAllocateHeap(Length);
  796. strcpy(Component->Identifier, KeyboardIdentifier[KeyboardId]);
  797. if (KeyboardId != UNKNOWN_KEYBOARD) {
  798. Length = sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
  799. sizeof(CM_KEYBOARD_DEVICE_DATA);
  800. DescriptorList = (PHWRESOURCE_DESCRIPTOR_LIST)BlAllocateHeap(Length);
  801. CurrentEntry->ConfigurationData = DescriptorList;
  802. Component->ConfigurationDataLength = Length;
  803. DescriptorList->Count = 1;
  804. DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  805. DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
  806. sizeof(CM_KEYBOARD_DEVICE_DATA);
  807. KeyboardData = (CM_KEYBOARD_DEVICE_DATA *)(DescriptorList + 1);
  808. KeyboardData->KeyboardFlags = 0;
  809. KeyboardData->Type = KeyboardType[KeyboardId];
  810. KeyboardData->Subtype = KeyboardSubtype[KeyboardId];
  811. }
  812. Controller->Child = CurrentEntry;
  813. Controller->Sibling = NULL;
  814. CurrentEntry->Parent = Controller;
  815. CurrentEntry->Sibling = NULL;
  816. CurrentEntry->Child = NULL;
  817. return(Controller);
  818. }
  819. #endif
  820. #if defined(_INCLUDE_LOADER_MOUSEINFO_)
  821. PCONFIGURATION_COMPONENT_DATA
  822. SetMouseConfigurationData (
  823. PMOUSE_INFORMATION MouseInfo,
  824. PCONFIGURATION_COMPONENT_DATA MouseList
  825. )
  826. /*++
  827. Routine Description:
  828. This routine fills in mouse configuration data.
  829. Arguments:
  830. MouseInfo - Supplies a pointer to the MOUSE_INFOR structure
  831. MouseList - Supplies a pointer to the existing mouse component list.
  832. Returns:
  833. Returns a pointer to our mice controller list.
  834. --*/
  835. {
  836. UCHAR i = 0;
  837. PCONFIGURATION_COMPONENT_DATA CurrentEntry, Controller, PeripheralEntry;
  838. PCONFIGURATION_COMPONENT Component;
  839. HWCONTROLLER_DATA ControlData;
  840. USHORT z, Length;
  841. PUCHAR pString;
  842. if ((MouseInfo->MouseSubtype != SERIAL_MOUSE) &&
  843. (MouseInfo->MouseSubtype != SERIAL_MOUSE_WITH_WHEEL)) {
  844. //
  845. // Initialize Controller data
  846. //
  847. ControlData.NumberPortEntries = 0;
  848. ControlData.NumberIrqEntries = 0;
  849. ControlData.NumberMemoryEntries = 0;
  850. ControlData.NumberDmaEntries = 0;
  851. z = 0;
  852. //
  853. // If it is not SERIAL_MOUSE, set up controller component
  854. //
  855. Controller = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  856. sizeof(CONFIGURATION_COMPONENT_DATA));
  857. Component = &Controller->ComponentEntry;
  858. Component->Class = ControllerClass;
  859. Component->Type = PointerController;
  860. Component->Flags.Input = 1;
  861. Component->Version = 0;
  862. Component->Key = MouseControllerKey;
  863. MouseControllerKey++;
  864. Component->AffinityMask = 0xffffffff;
  865. Component->IdentifierLength = 0;
  866. Component->Identifier = NULL;
  867. //
  868. // If we have mouse irq or port information, allocate configuration
  869. // data space for mouse controller component to store these information
  870. //
  871. if (MouseInfo->MouseIrq != 0xffff || MouseInfo->MousePort != 0xffff) {
  872. //
  873. // Set up port and Irq information
  874. //
  875. if (MouseInfo->MousePort != 0xffff) {
  876. ControlData.NumberPortEntries = 1;
  877. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  878. ControlData.DescriptorList[z].ShareDisposition =
  879. CmResourceShareDeviceExclusive;
  880. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  881. ControlData.DescriptorList[z].u.Port.Start.LowPart =
  882. (ULONG)MouseInfo->MousePort;
  883. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  884. ControlData.DescriptorList[z].u.Port.Length = 4;
  885. z++;
  886. }
  887. if (MouseInfo->MouseIrq != 0xffff) {
  888. ControlData.NumberIrqEntries = 1;
  889. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  890. ControlData.DescriptorList[z].ShareDisposition =
  891. CmResourceShareUndetermined;
  892. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  893. ControlData.DescriptorList[z].u.Interrupt.Level =
  894. (ULONG)MouseInfo->MouseIrq;
  895. ControlData.DescriptorList[z].u.Interrupt.Vector =
  896. (ULONG)MouseInfo->MouseIrq;
  897. if (HwBusType == MACHINE_TYPE_MCA) {
  898. ControlData.DescriptorList[z].Flags =
  899. LEVEL_SENSITIVE;
  900. } else {
  901. //
  902. // For EISA the LevelTriggered is temporarily set to FALSE.
  903. //
  904. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  905. }
  906. }
  907. Controller->ConfigurationData =
  908. HwSetUpResourceDescriptor(Component,
  909. NULL,
  910. &ControlData,
  911. 0,
  912. NULL
  913. );
  914. } else {
  915. //
  916. // Otherwise, we don't have configuration data for the controller
  917. //
  918. Controller->ConfigurationData = NULL;
  919. Component->ConfigurationDataLength = 0;
  920. }
  921. }
  922. //
  923. // Set up Mouse peripheral component
  924. //
  925. PeripheralEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  926. sizeof(CONFIGURATION_COMPONENT_DATA));
  927. Component = &PeripheralEntry->ComponentEntry;
  928. Component->Class = PeripheralClass;
  929. Component->Type = PointerPeripheral;
  930. Component->Flags.Input = 1;
  931. Component->Version = 0;
  932. Component->Key = 0;
  933. Component->AffinityMask = 0xffffffff;
  934. Component->ConfigurationDataLength = 0;
  935. PeripheralEntry->ConfigurationData = (PVOID)NULL;
  936. //
  937. // If Mouse PnP device id is found, translate it to ascii code.
  938. // (The mouse device id is presented to us by keyboard make code.)
  939. //
  940. Length = 0;
  941. if (MouseInfo->DeviceIdLength != 0) {
  942. USHORT i;
  943. if (MouseInfo->MouseSubtype == PS_MOUSE_WITH_WHEEL) {
  944. for (i = 0; i < MouseInfo->DeviceIdLength; i++) {
  945. if (MouseInfo->DeviceId[i] > MAX_MAKE_CODE_TRANSLATED) {
  946. MouseInfo->DeviceId[i] = '?';
  947. } else {
  948. MouseInfo->DeviceId[i] = MakeToAsciiTable[MouseInfo->DeviceId[i]];
  949. }
  950. }
  951. } else if (MouseInfo->MouseSubtype == SERIAL_MOUSE_WITH_WHEEL) {
  952. for (i = 0; i < MouseInfo->DeviceIdLength; i++) {
  953. MouseInfo->DeviceId[i] += 0x20;
  954. }
  955. }
  956. Length = MouseInfo->DeviceIdLength + 3;
  957. }
  958. Length += strlen(MouseIdentifier[MouseInfo->MouseType]) +
  959. strlen(MouseSubidentifier[MouseInfo->MouseSubtype]) + 1;
  960. pString = (PUCHAR)BlAllocateHeap(Length);
  961. if (MouseInfo->DeviceIdLength != 0) {
  962. strcpy(pString, MouseInfo->DeviceId);
  963. strcat(pString, " - ");
  964. strcat(pString, MouseIdentifier[MouseInfo->MouseType]);
  965. } else {
  966. strcpy(pString, MouseIdentifier[MouseInfo->MouseType]);
  967. }
  968. strcat(pString, MouseSubidentifier[MouseInfo->MouseSubtype]);
  969. Component->IdentifierLength = Length;
  970. Component->Identifier = pString;
  971. if ((MouseInfo->MouseSubtype != SERIAL_MOUSE) &&
  972. (MouseInfo->MouseSubtype != SERIAL_MOUSE_WITH_WHEEL)) {
  973. Controller->Child = PeripheralEntry;
  974. PeripheralEntry->Parent = Controller;
  975. if (MouseList) {
  976. //
  977. // Put the current mouse component to the beginning of the list
  978. //
  979. Controller->Sibling = MouseList;
  980. }
  981. return(Controller);
  982. } else {
  983. CurrentEntry = AdapterEntry->Child; // AdapterEntry MUST have child
  984. while (CurrentEntry) {
  985. if (CurrentEntry->ComponentEntry.Type == SerialController) {
  986. if (MouseInfo->MousePort == (USHORT)CurrentEntry->ComponentEntry.Key) {
  987. //
  988. // For serial mouse, the MousePort field contains
  989. // COM port number.
  990. //
  991. PeripheralEntry->Parent = CurrentEntry;
  992. CurrentEntry->Child = PeripheralEntry;
  993. break;
  994. }
  995. }
  996. CurrentEntry = CurrentEntry->Sibling;
  997. }
  998. return(NULL);
  999. }
  1000. }
  1001. PCONFIGURATION_COMPONENT_DATA
  1002. GetMouseInformation (
  1003. VOID
  1004. )
  1005. /*++
  1006. Routine Description:
  1007. This routine is the entry for mouse detection routine. It will invoke
  1008. lower level routines to detect ALL the mice in the system.
  1009. Arguments:
  1010. None.
  1011. Returns:
  1012. A pointer to a mouse component structure, if mouse/mice is detected.
  1013. Otherwise a NULL pointer is returned.
  1014. --*/
  1015. {
  1016. PMOUSE_INFORMATION MouseInfo;
  1017. PCONFIGURATION_COMPONENT_DATA MouseList = NULL;
  1018. MouseInfo = (PMOUSE_INFORMATION)BlAllocateHeap (
  1019. sizeof(MOUSE_INFORMATION));
  1020. MouseInfo->MouseType = 0x2; // Microsoft mouse
  1021. MouseInfo->MouseSubtype = PS2_MOUSE; // PS2 mouse
  1022. MouseInfo->MousePort = 0xffff; // PS2 mouse port
  1023. MouseInfo->MouseIrq = 0xc; // Interrupt request vector was 3
  1024. MouseInfo->DeviceIdLength = 0;
  1025. MouseList = SetMouseConfigurationData(MouseInfo, MouseList);
  1026. return(MouseList);
  1027. }
  1028. #endif // _INCLUDE_LOADER_MOUSEINFO_
  1029. #if defined(_INCLUDE_COMPORT_INFO_)
  1030. //
  1031. // This code was taken out because the GetComportInformation() routine
  1032. // was manufacturing data about the com port and writing the com port
  1033. // address to 40:0. This information should be determined by PnP
  1034. //
  1035. PCONFIGURATION_COMPONENT_DATA
  1036. GetComportInformation (
  1037. VOID
  1038. )
  1039. /*++
  1040. Routine Description:
  1041. This routine will attempt to detect the comports information
  1042. for the system. The information includes port address, irq
  1043. level.
  1044. Note that this routine can only detect up to 4 comports and
  1045. it assumes that if MCA, COM3 and COM4 use irq 4. Otherwise,
  1046. COM3 uses irq 4 and COM4 uses irq 3. Also, the number of ports
  1047. for COMPORT is set to 8 (for example, COM2 uses ports 2F8 - 2FF)
  1048. Arguments:
  1049. None.
  1050. Return Value:
  1051. A pointer to a stucture of type CONFIGURATION_COMPONENT_DATA
  1052. which is the root of comport component list.
  1053. If no comport exists, a value of NULL is returned.
  1054. --*/
  1055. {
  1056. PCONFIGURATION_COMPONENT_DATA CurrentEntry, PreviousEntry = NULL;
  1057. PCONFIGURATION_COMPONENT_DATA FirstComport = NULL;
  1058. PCONFIGURATION_COMPONENT Component;
  1059. HWCONTROLLER_DATA ControlData;
  1060. UCHAR i, j, z;
  1061. SHORT Port;
  1062. UCHAR ComportName[] = "COM?";
  1063. CM_SERIAL_DEVICE_DATA SerialData;
  1064. ULONG BaudClock = 1843200;
  1065. USHORT Vector;
  1066. USHORT IoPorts[MAX_COM_PORTS] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
  1067. //
  1068. // BIOS DATA area 40:0 is the port address of the first valid COM port
  1069. //
  1070. USHORT *pPortAddress = (USHORT *)0x00400000;
  1071. //
  1072. // Initialize serial device specific data
  1073. //
  1074. SerialData.Version = 0;
  1075. SerialData.Revision = 0;
  1076. SerialData.BaudClock = 1843200;
  1077. //
  1078. // Initialize Controller data
  1079. //
  1080. ControlData.NumberPortEntries = 0;
  1081. ControlData.NumberIrqEntries = 0;
  1082. ControlData.NumberMemoryEntries = 0;
  1083. ControlData.NumberDmaEntries = 0;
  1084. z = 0;
  1085. i = 0;
  1086. Port = IoPorts[i];
  1087. *(pPortAddress+i) = (USHORT)Port;
  1088. //
  1089. // Remember the port address in our global variable
  1090. // such that other detection code (e.g. Serial Mouse) can
  1091. // get the information.
  1092. //
  1093. #if 0 // unused
  1094. ComPortAddress[i] = Port;
  1095. #endif
  1096. CurrentEntry = (PCONFIGURATION_COMPONENT_DATA)BlAllocateHeap (
  1097. sizeof(CONFIGURATION_COMPONENT_DATA));
  1098. if (!FirstComport) {
  1099. FirstComport = CurrentEntry;
  1100. }
  1101. Component = &CurrentEntry->ComponentEntry;
  1102. Component->Class = ControllerClass;
  1103. Component->Type = SerialController;
  1104. Component->Flags.ConsoleOut = 1;
  1105. Component->Flags.ConsoleIn = 1;
  1106. Component->Flags.Output = 1;
  1107. Component->Flags.Input = 1;
  1108. Component->Version = 0;
  1109. Component->Key = i;
  1110. Component->AffinityMask = 0xffffffff;
  1111. //
  1112. // Set up type string.
  1113. //
  1114. ComportName[3] = i + (UCHAR)'1';
  1115. //
  1116. // Set up Port information
  1117. //
  1118. ControlData.NumberPortEntries = 1;
  1119. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  1120. ControlData.DescriptorList[z].ShareDisposition =
  1121. CmResourceShareDeviceExclusive;
  1122. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  1123. ControlData.DescriptorList[z].u.Port.Start.LowPart = (ULONG)Port;
  1124. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  1125. ControlData.DescriptorList[z].u.Port.Length = 8;
  1126. z++;
  1127. //
  1128. // Set up Irq information
  1129. //
  1130. ControlData.NumberIrqEntries = 1;
  1131. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  1132. ControlData.DescriptorList[z].ShareDisposition =
  1133. CmResourceShareUndetermined;
  1134. //
  1135. // For EISA the LevelTriggered is temporarily set to FALSE.
  1136. // COM1 and COM3 use irq 4; COM2 and COM4 use irq3
  1137. //
  1138. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  1139. if (Port == 0x3f8 || Port == 0x3e8) {
  1140. ControlData.DescriptorList[z].u.Interrupt.Level = 4;
  1141. ControlData.DescriptorList[z].u.Interrupt.Vector = 4;
  1142. } else if (Port == 0x2f8 || Port == 0x2e8) {
  1143. ControlData.DescriptorList[z].u.Interrupt.Level = 3;
  1144. ControlData.DescriptorList[z].u.Interrupt.Vector = 3;
  1145. } else if (i == 0 || i == 2) {
  1146. ControlData.DescriptorList[z].u.Interrupt.Level = 4;
  1147. ControlData.DescriptorList[z].u.Interrupt.Vector = 4;
  1148. } else {
  1149. ControlData.DescriptorList[z].u.Interrupt.Level = 3;
  1150. ControlData.DescriptorList[z].u.Interrupt.Vector = 3;
  1151. }
  1152. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  1153. //
  1154. // Try to determine the interrupt vector. If we success, the
  1155. // new vector will be used to replace the default value.
  1156. //
  1157. CurrentEntry->ConfigurationData =
  1158. HwSetUpResourceDescriptor(Component,
  1159. ComportName,
  1160. &ControlData,
  1161. sizeof(SerialData),
  1162. (PUCHAR)&SerialData
  1163. );
  1164. if (PreviousEntry) {
  1165. PreviousEntry->Sibling = CurrentEntry;
  1166. }
  1167. PreviousEntry = CurrentEntry;
  1168. return(FirstComport);
  1169. }
  1170. #endif
  1171. PVOID
  1172. HwSetUpResourceDescriptor (
  1173. PCONFIGURATION_COMPONENT Component,
  1174. PUCHAR Identifier,
  1175. PHWCONTROLLER_DATA ControlData,
  1176. USHORT SpecificDataLength,
  1177. PUCHAR SpecificData
  1178. )
  1179. /*++
  1180. Routine Description:
  1181. This routine allocates space from heap , puts the caller's controller
  1182. information to the space and sets up CONFIGURATION_COMPONENT
  1183. structure for the caller.
  1184. Arguments:
  1185. Component - Supplies the address the component whose configuration data
  1186. should be set up.
  1187. Identifier - Suppies a pointer to the identifier to identify the controller
  1188. ControlData - Supplies a point to a structure which describes
  1189. controller information.
  1190. SpecificDataLength - size of the device specific data. Device specific
  1191. data is the information not defined in the standard format.
  1192. SpecificData - Supplies a pointer to the device specific data.
  1193. Return Value:
  1194. Returns a pointer to the Configuration data.
  1195. --*/
  1196. {
  1197. PCHAR pIdentifier;
  1198. PHWRESOURCE_DESCRIPTOR_LIST pDescriptor = NULL;
  1199. USHORT Length;
  1200. SHORT Count, i;
  1201. PUCHAR pSpecificData;
  1202. //
  1203. // Set up Identifier string for hardware component, if necessary.
  1204. //
  1205. if (Identifier) {
  1206. Length = RESET_SIZE_AT_USHORT_MAX(strlen((PCHAR)Identifier) + 1);
  1207. Component->IdentifierLength = Length;
  1208. pIdentifier = (PCHAR)BlAllocateHeap(Length);
  1209. Component->Identifier = pIdentifier;
  1210. strcpy(pIdentifier, (PCHAR)Identifier);
  1211. } else {
  1212. Component->IdentifierLength = 0;
  1213. Component->Identifier = NULL;
  1214. }
  1215. //
  1216. // Set up configuration data for hardware component, if necessary
  1217. //
  1218. Count = ControlData->NumberPortEntries + ControlData->NumberIrqEntries +
  1219. ControlData->NumberMemoryEntries + ControlData->NumberDmaEntries;
  1220. if (SpecificDataLength) {
  1221. //
  1222. // if we have device specific data, we need to increment the count
  1223. // by one.
  1224. //
  1225. Count++;
  1226. }
  1227. if (Count >0) {
  1228. Length = (USHORT)(Count * sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR) +
  1229. FIELD_OFFSET(HWRESOURCE_DESCRIPTOR_LIST, PartialDescriptors) +
  1230. SpecificDataLength);
  1231. pDescriptor = (PHWRESOURCE_DESCRIPTOR_LIST)BlAllocateHeap(Length);
  1232. pDescriptor->Count = Count;
  1233. //
  1234. // Copy all the partial descriptors to the destination descriptors
  1235. // except the last one. (The last partial descriptor may be a device
  1236. // specific data. It requires special handling.)
  1237. //
  1238. for (i = 0; i < (Count - 1); i++) {
  1239. pDescriptor->PartialDescriptors[i] =
  1240. ControlData->DescriptorList[i];
  1241. }
  1242. //
  1243. // Set up the last partial descriptor. If it is a port, memory, irq or
  1244. // dma entry, we simply copy it. If the last one is for device specific
  1245. // data, we set up the length and copy the device spcific data to the end
  1246. // of the decriptor.
  1247. //
  1248. if (SpecificData) {
  1249. pDescriptor->PartialDescriptors[Count - 1].Type =
  1250. RESOURCE_DEVICE_DATA;
  1251. pDescriptor->PartialDescriptors[Count - 1].Flags = 0;
  1252. pDescriptor->PartialDescriptors[Count - 1].u.DeviceSpecificData.DataSize =
  1253. SpecificDataLength;
  1254. pSpecificData = (PUCHAR)&(pDescriptor->PartialDescriptors[Count]);
  1255. RtlCopyMemory( pSpecificData, SpecificData, SpecificDataLength);
  1256. } else {
  1257. pDescriptor->PartialDescriptors[Count - 1] =
  1258. ControlData->DescriptorList[Count - 1];
  1259. }
  1260. Component->ConfigurationDataLength = Length;
  1261. }
  1262. return(pDescriptor);
  1263. }
  1264. VOID
  1265. HwSetUpFreeFormDataHeader (
  1266. PHWRESOURCE_DESCRIPTOR_LIST Header,
  1267. USHORT Version,
  1268. USHORT Revision,
  1269. USHORT Flags,
  1270. ULONG DataSize
  1271. )
  1272. /*++
  1273. Routine Description:
  1274. This routine initialize free formed data header. Note this routine
  1275. sets the the Header and initialize the FIRST PartialDescriptor only.
  1276. If the header contains more than one descriptor, the caller must handle
  1277. it itself.
  1278. Arguments:
  1279. Header - Supplies a pointer to the header to be initialized.
  1280. Version - Version number for the header.
  1281. Revision - Revision number for the header.
  1282. Flags - Free formed data flags. (Currently, it is undefined and
  1283. should be zero.)
  1284. DataSize - Size of the free formed data.
  1285. Return Value:
  1286. None.
  1287. --*/
  1288. {
  1289. Header->Version = Version;
  1290. Header->Revision = Revision;
  1291. Header->Count = 1;
  1292. Header->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  1293. Header->PartialDescriptors[0].ShareDisposition = 0;
  1294. Header->PartialDescriptors[0].Flags = Flags;
  1295. Header->PartialDescriptors[0].u.DeviceSpecificData.DataSize = DataSize;
  1296. Header->PartialDescriptors[0].u.DeviceSpecificData.Reserved1 = 0;
  1297. Header->PartialDescriptors[0].u.DeviceSpecificData.Reserved2 = 0;
  1298. }