4 * Copyright (C) 2003, 2004 Eric Kohl
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include "../../reactos/registry.h"
37 #define CLOCK_TICK_RATE (1193182)
38 #define LATCH (CLOCK_TICK_RATE / HZ)
42 #define MOUSE_TYPE_NONE 0
43 /* Microsoft Mouse with 2 buttons */
44 #define MOUSE_TYPE_MICROSOFT 1
45 /* Logitech Mouse with 3 buttons */
46 #define MOUSE_TYPE_LOGITECH 2
47 /* Microsoft Wheel Mouse (aka Z Mouse) */
48 #define MOUSE_TYPE_WHEELZ 3
49 /* Mouse Systems Mouse */
50 #define MOUSE_TYPE_MOUSESYSTEMS 4
55 /* Controller registers. */
56 #define CONTROLLER_REGISTER_STATUS 0x64
57 #define CONTROLLER_REGISTER_CONTROL 0x64
58 #define CONTROLLER_REGISTER_DATA 0x60
60 /* Controller commands. */
61 #define CONTROLLER_COMMAND_READ_MODE 0x20
62 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
63 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
64 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
65 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
66 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
67 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
68 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
69 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
70 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
71 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
72 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
74 /* Controller status */
75 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
76 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
77 #define CONTROLLER_STATUS_SELF_TEST 0x04
78 #define CONTROLLER_STATUS_COMMAND 0x08
79 #define CONTROLLER_STATUS_UNLOCKED 0x10
80 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
81 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
82 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
83 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
84 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
86 /* Timeout in ms for sending to keyboard controller. */
87 #define CONTROLLER_TIMEOUT 250
90 typedef struct _CM_INT13_DRIVE_PARAMETER
97 } CM_INT13_DRIVE_PARAMETER
, *PCM_INT13_DRIVE_PARAMETER
;
100 typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA
103 U32 NumberOfCylinders
;
106 } CM_DISK_GEOMETRY_DEVICE_DATA
, *PCM_DISK_GEOMETRY_DEVICE_DATA
;
109 typedef struct _CM_PNP_BIOS_DEVICE_NODE
115 U16 DeviceAttributes
;
116 } __attribute__((packed
)) CM_PNP_BIOS_DEVICE_NODE
, *PCM_PNP_BIOS_DEVICE_NODE
;
119 typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
126 U32 EventFlagAddress
;
127 U16 RealModeEntryOffset
;
128 U16 RealModeEntrySegment
;
129 U16 ProtectedModeEntryOffset
;
130 U32 ProtectedModeCodeBaseAddress
;
132 U16 RealModeDataBaseAddress
;
133 U32 ProtectedModeDataBaseAddress
;
134 } __attribute__((packed
)) CM_PNP_BIOS_INSTALLATION_CHECK
, *PCM_PNP_BIOS_INSTALLATION_CHECK
;
137 typedef struct _CM_SERIAL_DEVICE_DATA
142 } __attribute__((packed
)) CM_SERIAL_DEVICE_DATA
, *PCM_SERIAL_DEVICE_DATA
;
145 typedef struct _CM_FLOPPY_DEVICE_DATA
153 /* Version 2.0 data */
154 U8 StepRateHeadUnloadTime
;
159 U8 ReadWriteGapLength
;
160 U8 DataTransferLength
;
162 U8 FormatFillCharacter
;
165 U8 MaximumTrackValue
;
167 } __attribute__((packed
)) CM_FLOPPY_DEVICE_DATA
, *PCM_FLOPPY_DEVICE_DATA
;
170 typedef struct _CM_KEYBOARD_DEVICE_DATA
177 } __attribute__((packed
)) CM_KEYBOARD_DEVICE_DATA
, *PCM_KEYBOARD_DEVICE_DATA
;
180 static char Hex
[] = "0123456789ABCDEF";
181 static unsigned int delay_count
= 1;
184 /* FUNCTIONS ****************************************************************/
188 __KeStallExecutionProcessor(U32 Loops
)
190 register unsigned int i
;
191 for (i
= 0; i
< Loops
; i
++);
194 VOID
KeStallExecutionProcessor(U32 Microseconds
)
196 U64 LoopCount
= ((U64
)delay_count
* (U64
)Microseconds
) / 1000ULL;
197 __KeStallExecutionProcessor((U32
)LoopCount
);
206 WRITE_PORT_UCHAR((PU8
)0x43, 0x00);
207 Count
= READ_PORT_UCHAR((PU8
)0x40);
208 Count
|= READ_PORT_UCHAR((PU8
)0x40) << 8;
215 WaitFor8254Wraparound(VOID
)
221 CurCount
= Read8254Timer();
225 PrevCount
= CurCount
;
226 CurCount
= Read8254Timer();
227 Delta
= CurCount
- PrevCount
;
230 * This limit for delta seems arbitrary, but it isn't, it's
231 * slightly above the level of error a buggy Mercury/Neptune
232 * chipset timer can cause.
240 HalpCalibrateStallExecution(VOID
)
246 /* Initialise timer interrupt with MILLISECOND ms interval */
247 WRITE_PORT_UCHAR((PU8
)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
248 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
& 0xff); /* LSB */
249 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
>> 8); /* MSB */
251 /* Stage 1: Coarse calibration */
253 WaitFor8254Wraparound();
258 delay_count
<<= 1; /* Next delay count to try */
260 WaitFor8254Wraparound();
262 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
264 CurCount
= Read8254Timer();
265 } while (CurCount
> LATCH
/ 2);
267 delay_count
>>= 1; /* Get bottom value for delay */
269 /* Stage 2: Fine calibration */
271 calib_bit
= delay_count
; /* Which bit are we going to test */
273 for(i
=0;i
<PRECISION
;i
++) {
274 calib_bit
>>= 1; /* Next bit to calibrate */
275 if(!calib_bit
) break; /* If we have done all bits, stop */
277 delay_count
|= calib_bit
; /* Set the bit in delay_count */
279 WaitFor8254Wraparound();
281 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
283 CurCount
= Read8254Timer();
284 if (CurCount
<= LATCH
/ 2) /* If a tick has passed, turn the */
285 delay_count
&= ~calib_bit
; /* calibrated bit back off */
288 /* We're finished: Do the finishing touches */
289 delay_count
/= (MILLISEC
/ 2); /* Calculate delay_count for 1ms */
294 SetComponentInformation(HKEY ComponentKey
,
299 CM_COMPONENT_INFORMATION CompInfo
;
302 CompInfo
.Flags
= Flags
;
303 CompInfo
.Version
= 0;
305 CompInfo
.Affinity
= Affinity
;
307 /* Set 'Component Information' value */
308 Error
= RegSetValue(ComponentKey
,
309 "Component Information",
312 sizeof(CM_COMPONENT_INFORMATION
));
313 if (Error
!= ERROR_SUCCESS
)
315 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
321 DetectPnpBios(HKEY SystemKey
, U32
*BusNumber
)
323 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
324 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
325 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
339 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
340 if (InstData
== NULL
|| strncmp(InstData
->Signature
, "$PnP", 4))
342 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS not supported\n"));
345 DbgPrint((DPRINT_HWDETECT
, "Signature '%c%c%c%c'\n",
346 InstData
->Signature
[0], InstData
->Signature
[1],
347 InstData
->Signature
[2], InstData
->Signature
[3]));
350 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
351 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
353 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS failed to enumerate device nodes\n"));
356 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS supported\n"));
357 DbgPrint((DPRINT_HWDETECT
, "MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
));
358 DbgPrint((DPRINT_HWDETECT
, "Estimated buffer size %u\n", NodeSize
* NodeCount
));
360 /* Create new bus key */
362 "MultifunctionAdapter\\%u", *BusNumber
);
363 Error
= RegCreateKey(SystemKey
,
366 if (Error
!= ERROR_SUCCESS
)
368 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
372 /* Increment bus number */
375 /* Set 'Identifier' value */
376 Error
= RegSetValue(BusKey
,
381 if (Error
!= ERROR_SUCCESS
)
383 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
387 /* Set 'Configuration Data' value */
388 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + (NodeSize
* NodeCount
);
389 FullResourceDescriptor
= MmAllocateMemory(Size
);
390 if (FullResourceDescriptor
== NULL
)
392 DbgPrint((DPRINT_HWDETECT
,
393 "Failed to allocate resource descriptor\n"));
396 memset(FullResourceDescriptor
, 0, Size
);
398 /* Initialize resource descriptor */
399 FullResourceDescriptor
->InterfaceType
= Internal
;
400 FullResourceDescriptor
->BusNumber
= 0;
401 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
402 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
403 CmResourceTypeDeviceSpecific
;
404 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].ShareDisposition
=
405 CmResourceShareUndetermined
;
406 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
408 Ptr
= (char *)(((PVOID
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0]) +
409 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
411 /* Set instalation check data */
412 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
413 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
415 /* Copy device nodes */
417 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
418 for (i
= 0; i
< 0xFF; i
++)
422 x
= PnpBiosGetDeviceNode(&NodeNumber
, (PVOID
)DISKREADBUFFER
);
425 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DISKREADBUFFER
;
427 DbgPrint((DPRINT_HWDETECT
,
428 "Node: %u Size %u (0x%x)\n",
432 // printf("Node: %u Size %u (0x%x)\n",
435 // DeviceNode->Size);
441 Ptr
+= DeviceNode
->Size
;
442 PnpBufferSize
+= DeviceNode
->Size
;
445 if (FoundNodeCount
>= NodeCount
)
450 /* Set real data size */
451 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
453 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + PnpBufferSize
;
455 DbgPrint((DPRINT_HWDETECT
, "Real buffer size: %u\n", PnpBufferSize
));
456 DbgPrint((DPRINT_HWDETECT
, "Resource size: %u\n", Size
));
458 /* Set 'Configuration Data' value */
459 Error
= RegSetValue(BusKey
,
460 "Configuration Data",
461 REG_FULL_RESOURCE_DESCRIPTOR
,
462 (PU8
) FullResourceDescriptor
,
464 MmFreeMemory(FullResourceDescriptor
);
465 if (Error
!= ERROR_SUCCESS
)
467 DbgPrint((DPRINT_HWDETECT
,
468 "RegSetValue(Configuration Data) failed (Error %u)\n",
476 SetHarddiskConfigurationData(HKEY DiskKey
,
479 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
480 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
481 EXTENDED_GEOMETRY ExtGeometry
;
486 /* Set 'Configuration Data' value */
487 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
488 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
489 FullResourceDescriptor
= MmAllocateMemory(Size
);
490 if (FullResourceDescriptor
== NULL
)
492 DbgPrint((DPRINT_HWDETECT
,
493 "Failed to allocate a full resource descriptor\n"));
497 memset(FullResourceDescriptor
, 0, Size
);
498 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
499 FullResourceDescriptor
->BusNumber
= 0;
500 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
501 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
502 CmResourceTypeDeviceSpecific
;
503 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
504 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
505 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
506 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
508 /* Get pointer to geometry data */
509 DiskGeometry
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
511 /* Get the disk geometry */
512 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
513 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
515 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
516 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
517 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
518 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
520 else if(DiskGetDriveParameters(DriveNumber
, &Geometry
))
522 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
523 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
524 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
525 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
529 DbgPrint((DPRINT_HWDETECT
, "Reading disk geometry failed\n"));
530 MmFreeMemory(FullResourceDescriptor
);
533 DbgPrint((DPRINT_HWDETECT
,
534 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
536 DiskGeometry
->NumberOfCylinders
,
537 DiskGeometry
->NumberOfHeads
,
538 DiskGeometry
->SectorsPerTrack
,
539 DiskGeometry
->BytesPerSector
));
541 Error
= RegSetValue(DiskKey
,
542 "Configuration Data",
543 REG_FULL_RESOURCE_DESCRIPTOR
,
544 (PU8
) FullResourceDescriptor
,
546 MmFreeMemory(FullResourceDescriptor
);
547 if (Error
!= ERROR_SUCCESS
)
549 DbgPrint((DPRINT_HWDETECT
,
550 "RegSetValue(Configuration Data) failed (Error %u)\n",
557 SetHarddiskIdentifier(HKEY DiskKey
,
560 PMASTER_BOOT_RECORD Mbr
;
569 if (!DiskReadLogicalSectors(DriveNumber
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
571 DbgPrint((DPRINT_HWDETECT
, "Reading MBR failed\n"));
575 Buffer
= (U32
*)DISKREADBUFFER
;
576 Mbr
= (PMASTER_BOOT_RECORD
)DISKREADBUFFER
;
578 Signature
= Mbr
->Signature
;
579 DbgPrint((DPRINT_HWDETECT
, "Signature: %x\n", Signature
));
581 /* Calculate the MBR checksum */
583 for (i
= 0; i
< 128; i
++)
585 Checksum
+= Buffer
[i
];
587 Checksum
= ~Checksum
+ 1;
588 DbgPrint((DPRINT_HWDETECT
, "Checksum: %x\n", Checksum
));
590 /* Convert checksum and signature to identifier string */
591 Identifier
[0] = Hex
[(Checksum
>> 28) & 0x0F];
592 Identifier
[1] = Hex
[(Checksum
>> 24) & 0x0F];
593 Identifier
[2] = Hex
[(Checksum
>> 20) & 0x0F];
594 Identifier
[3] = Hex
[(Checksum
>> 16) & 0x0F];
595 Identifier
[4] = Hex
[(Checksum
>> 12) & 0x0F];
596 Identifier
[5] = Hex
[(Checksum
>> 8) & 0x0F];
597 Identifier
[6] = Hex
[(Checksum
>> 4) & 0x0F];
598 Identifier
[7] = Hex
[Checksum
& 0x0F];
600 Identifier
[9] = Hex
[(Signature
>> 28) & 0x0F];
601 Identifier
[10] = Hex
[(Signature
>> 24) & 0x0F];
602 Identifier
[11] = Hex
[(Signature
>> 20) & 0x0F];
603 Identifier
[12] = Hex
[(Signature
>> 16) & 0x0F];
604 Identifier
[13] = Hex
[(Signature
>> 12) & 0x0F];
605 Identifier
[14] = Hex
[(Signature
>> 8) & 0x0F];
606 Identifier
[15] = Hex
[(Signature
>> 4) & 0x0F];
607 Identifier
[16] = Hex
[Signature
& 0x0F];
608 Identifier
[17] = '-';
609 Identifier
[18] = 'A';
611 DbgPrint((DPRINT_HWDETECT
, "Identifier: %xsn", Identifier
));
614 Error
= RegSetValue(DiskKey
,
619 if (Error
!= ERROR_SUCCESS
)
621 DbgPrint((DPRINT_HWDETECT
,
622 "RegSetValue(Identifier) failed (Error %u)\n",
629 DetectBiosDisks(HKEY SystemKey
,
632 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
633 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
642 /* Count the number of visible drives */
643 DiskReportError(FALSE
);
645 while (DiskReadLogicalSectors(0x80 + DiskCount
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
649 DiskReportError(TRUE
);
650 DbgPrint((DPRINT_HWDETECT
, "BIOS reports %d harddisk%s\n",
651 (int)DiskCount
, (DiskCount
== 1) ? "": "s"));
653 /* Allocate resource descriptor */
654 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
655 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
656 FullResourceDescriptor
= MmAllocateMemory(Size
);
657 if (FullResourceDescriptor
== NULL
)
659 DbgPrint((DPRINT_HWDETECT
,
660 "Failed to allocate resource descriptor\n"));
664 /* Initialize resource descriptor */
665 memset(FullResourceDescriptor
, 0, Size
);
666 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
667 FullResourceDescriptor
->BusNumber
= -1;
668 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
669 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
670 CmResourceTypeDeviceSpecific
;
671 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
672 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
673 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
674 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
676 /* Get harddisk Int13 geometry data */
677 Int13Drives
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
678 for (i
= 0; i
< DiskCount
; i
++)
680 if (DiskGetDriveParameters(0x80 + i
, &Geometry
))
682 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
683 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
684 Int13Drives
[i
].SectorsPerTrack
= Geometry
.Sectors
;
685 Int13Drives
[i
].MaxHeads
= Geometry
.Heads
- 1;
686 Int13Drives
[i
].NumberDrives
= DiskCount
;
688 DbgPrint((DPRINT_HWDETECT
,
689 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
691 Geometry
.Cylinders
- 1,
694 Geometry
.BytesPerSector
));
698 /* Set 'Configuration Data' value */
699 Error
= RegSetValue(SystemKey
,
700 "Configuration Data",
701 REG_FULL_RESOURCE_DESCRIPTOR
,
702 (PU8
) FullResourceDescriptor
,
704 MmFreeMemory(FullResourceDescriptor
);
705 if (Error
!= ERROR_SUCCESS
)
707 DbgPrint((DPRINT_HWDETECT
,
708 "RegSetValue(Configuration Data) failed (Error %u)\n",
713 /* Create and fill subkey for each harddisk */
714 for (i
= 0; i
< DiskCount
; i
++)
716 /* Create disk key */
718 "DiskController\\0\\DiskPeripheral\\%u",
721 Error
= RegCreateKey(BusKey
,
724 if (Error
!= ERROR_SUCCESS
)
726 DbgPrint((DPRINT_HWDETECT
, "Failed to create drive key\n"));
729 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
731 /* Set disk values */
732 SetHarddiskConfigurationData(DiskKey
, 0x80 + i
);
733 SetHarddiskIdentifier(DiskKey
, 0x80 + i
);
743 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
744 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
746 return ((Data
& 0xF0) ? 1 : 0) + ((Data
& 0x0F) ? 1 : 0);
751 GetFloppyType(U8 DriveNumber
)
755 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
756 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
758 if (DriveNumber
== 0)
760 else if (DriveNumber
== 1)
770 PU16 SegPtr
= (PU16
)0x7A;
771 PU16 OfsPtr
= (PU16
)0x78;
773 return (PVOID
)(((U32
)(*SegPtr
)) << 4) + (U32
)(*OfsPtr
);
778 DetectBiosFloppyPeripheral(HKEY ControllerKey
)
780 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
781 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
782 PCM_FLOPPY_DEVICE_DATA FloppyData
;
790 U32 MaxDensity
[6] = {0, 360, 1200, 720, 1440, 2880};
793 for (FloppyNumber
= 0; FloppyNumber
< 2; FloppyNumber
++)
795 FloppyType
= GetFloppyType(FloppyNumber
);
797 if ((FloppyType
> 5) || (FloppyType
== 0))
800 DiskResetController(FloppyNumber
);
802 Ptr
= GetInt1eTable();
804 sprintf(KeyName
, "FloppyDiskPeripheral\\%u", FloppyNumber
);
806 Error
= RegCreateKey(ControllerKey
,
807 "FloppyDiskPeripheral\\0",
809 if (Error
!= ERROR_SUCCESS
)
811 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
815 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", KeyName
));
817 /* Set 'ComponentInformation' value */
818 SetComponentInformation(PeripheralKey
,
823 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
824 sizeof(CM_FLOPPY_DEVICE_DATA
);
825 FullResourceDescriptor
= MmAllocateMemory(Size
);
826 if (FullResourceDescriptor
== NULL
)
828 DbgPrint((DPRINT_HWDETECT
,
829 "Failed to allocate resource descriptor\n"));
833 memset(FullResourceDescriptor
, 0, Size
);
834 FullResourceDescriptor
->InterfaceType
= Isa
;
835 FullResourceDescriptor
->BusNumber
= 0;
836 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
838 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
839 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
840 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
841 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_FLOPPY_DEVICE_DATA
);
843 FloppyData
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
844 FloppyData
->Version
= 2;
845 FloppyData
->Revision
= 0;
846 FloppyData
->MaxDensity
= MaxDensity
[FloppyType
];
847 FloppyData
->MountDensity
= 0;
848 RtlCopyMemory(&FloppyData
->StepRateHeadUnloadTime
,
851 FloppyData
->MaximumTrackValue
= (FloppyType
== 1) ? 39 : 79;
852 FloppyData
->DataTransferRate
= 0;
854 /* Set 'Configuration Data' value */
855 Error
= RegSetValue(PeripheralKey
,
856 "Configuration Data",
857 REG_FULL_RESOURCE_DESCRIPTOR
,
858 (PU8
) FullResourceDescriptor
,
860 MmFreeMemory(FullResourceDescriptor
);
861 if (Error
!= ERROR_SUCCESS
)
863 DbgPrint((DPRINT_HWDETECT
,
864 "RegSetValue(Configuration Data) failed (Error %u)\n",
869 /* Set 'Identifier' value */
870 sprintf(Identifier
, "FLOPPY%u", FloppyNumber
+ 1);
871 Error
= RegSetValue(PeripheralKey
,
875 strlen(Identifier
) + 1);
876 if (Error
!= ERROR_SUCCESS
)
878 DbgPrint((DPRINT_HWDETECT
,
879 "RegSetValue() failed (Error %u)\n",
887 DetectBiosFloppyController(HKEY SystemKey
,
890 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
891 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
897 FloppyCount
= GetFloppyCount();
898 DbgPrint((DPRINT_HWDETECT
,
899 "Floppy count: %u\n",
902 if (FloppyCount
== 0)
905 Error
= RegCreateKey(BusKey
,
908 if (Error
!= ERROR_SUCCESS
)
910 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
914 DbgPrint((DPRINT_HWDETECT
, "Created key: DiskController\\0\n"));
916 /* Set 'ComponentInformation' value */
917 SetComponentInformation(ControllerKey
,
922 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
923 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
924 FullResourceDescriptor
= MmAllocateMemory(Size
);
925 if (FullResourceDescriptor
== NULL
)
927 DbgPrint((DPRINT_HWDETECT
,
928 "Failed to allocate resource descriptor\n"));
931 memset(FullResourceDescriptor
, 0, Size
);
933 /* Initialize resource descriptor */
934 FullResourceDescriptor
->InterfaceType
= Isa
;
935 FullResourceDescriptor
->BusNumber
= 0;
936 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
939 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
940 PartialDescriptor
->Type
= CmResourceTypePort
;
941 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
942 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
943 PartialDescriptor
->u
.Port
.Start
= (U64
)0x03F0;
944 PartialDescriptor
->u
.Port
.Length
= 8;
947 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
948 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
949 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
950 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
951 PartialDescriptor
->u
.Interrupt
.Level
= 6;
952 PartialDescriptor
->u
.Interrupt
.Vector
= 6;
953 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
955 /* Set DMA channel */
956 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
957 PartialDescriptor
->Type
= CmResourceTypeDma
;
958 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
959 PartialDescriptor
->Flags
= 0;
960 PartialDescriptor
->u
.Dma
.Channel
= 2;
961 PartialDescriptor
->u
.Dma
.Port
= 0;
963 /* Set 'Configuration Data' value */
964 Error
= RegSetValue(ControllerKey
,
965 "Configuration Data",
966 REG_FULL_RESOURCE_DESCRIPTOR
,
967 (PU8
) FullResourceDescriptor
,
969 MmFreeMemory(FullResourceDescriptor
);
970 if (Error
!= ERROR_SUCCESS
)
972 DbgPrint((DPRINT_HWDETECT
,
973 "RegSetValue(Configuration Data) failed (Error %u)\n",
978 DetectBiosFloppyPeripheral(ControllerKey
);
983 InitializeSerialPort(U32 Port
,
986 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, 0x80); /* set DLAB on */
987 WRITE_PORT_UCHAR((PUCHAR
)Port
, 0x60); /* speed LO byte */
988 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* speed HI byte */
989 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, LineControl
);
990 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* set comm and DLAB to 0 */
991 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09); /* DR int enable */
992 READ_PORT_UCHAR((PUCHAR
)Port
+ 5); /* clear error bits */
997 DetectSerialMouse(U32 Port
)
1004 /* Shutdown mouse or something like that */
1005 LineControl
= READ_PORT_UCHAR((PUCHAR
)Port
+ 4);
1006 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, (LineControl
& ~0x02) | 0x01);
1007 KeStallExecutionProcessor(100000);
1010 while (READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 0x01)
1011 READ_PORT_UCHAR((PUCHAR
)Port
);
1014 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
1015 * 'Output Line 2' message. This enables mouse to identify.
1017 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
1019 /* Wait 10 milliseconds for the mouse getting ready */
1020 KeStallExecutionProcessor(10000);
1022 /* Read first four bytes, which contains Microsoft Mouse signs */
1023 for (i
= 0; i
< 4; i
++)
1025 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1027 KeStallExecutionProcessor(1000);
1030 return MOUSE_TYPE_NONE
;
1032 Buffer
[i
] = READ_PORT_UCHAR((PUCHAR
)Port
);
1035 DbgPrint((DPRINT_HWDETECT
,
1036 "Mouse data: %x %x %x %x\n",
1037 Buffer
[0],Buffer
[1],Buffer
[2],Buffer
[3]));
1039 /* Check that four bytes for signs */
1040 for (i
= 0; i
< 4; ++i
)
1042 if (Buffer
[i
] == 'B')
1044 /* Sign for Microsoft Ballpoint */
1045 // DbgPrint("Microsoft Ballpoint device detected\n");
1046 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
1047 return MOUSE_TYPE_NONE
;
1049 else if (Buffer
[i
] == 'M')
1051 /* Sign for Microsoft Mouse protocol followed by button specifier */
1054 /* Overflow Error */
1055 return MOUSE_TYPE_NONE
;
1058 switch (Buffer
[i
+ 1])
1061 DbgPrint((DPRINT_HWDETECT
,
1062 "Microsoft Mouse with 3-buttons detected\n"));
1063 return MOUSE_TYPE_LOGITECH
;
1066 DbgPrint((DPRINT_HWDETECT
,
1067 "Microsoft Wheel Mouse detected\n"));
1068 return MOUSE_TYPE_WHEELZ
;
1072 DbgPrint((DPRINT_HWDETECT
,
1073 "Microsoft Mouse with 2-buttons detected\n"));
1074 return MOUSE_TYPE_MICROSOFT
;
1079 return MOUSE_TYPE_NONE
;
1084 GetSerialMousePnpId(U32 Port
, char *Buffer
)
1091 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09);
1093 /* Wait 10 milliseconds for the mouse getting ready */
1094 KeStallExecutionProcessor(10000);
1096 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
1098 KeStallExecutionProcessor(10000);
1103 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1105 KeStallExecutionProcessor(1000);
1113 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
1114 if (c
== 0x08 || c
== 0x28)
1124 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1126 KeStallExecutionProcessor(1000);
1131 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
1144 DetectSerialPointerPeripheral(HKEY ControllerKey
,
1147 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1149 char Identifier
[256];
1157 DbgPrint((DPRINT_HWDETECT
,
1158 "DetectSerialPointerPeripheral()\n"));
1162 InitializeSerialPort(Base
, 2);
1163 MouseType
= DetectSerialMouse(Base
);
1165 if (MouseType
!= MOUSE_TYPE_NONE
)
1167 Length
= GetSerialMousePnpId(Base
, Buffer
);
1168 DbgPrint((DPRINT_HWDETECT
,
1169 "PnP ID length: %u\n",
1174 /* Convert PnP sting to ASCII */
1175 if (Buffer
[0] == 0x08)
1177 for (i
= 0; i
< Length
; i
++)
1182 DbgPrint((DPRINT_HWDETECT
,
1183 "PnP ID string: %s\n",
1186 /* Copy PnpId string */
1187 memcpy(&Identifier
[0],
1190 memcpy(&Identifier
[7],
1194 /* Skip device serial number */
1196 if (Buffer
[i
] == '\\')
1198 for (j
= ++i
; i
< Length
; ++i
)
1200 if (Buffer
[i
] == '\\')
1207 /* Skip PnP class */
1208 if (Buffer
[i
] == '\\')
1210 for (j
= ++i
; i
< Length
; ++i
)
1212 if (Buffer
[i
] == '\\')
1220 /* Skip compatible PnP Id */
1221 if (Buffer
[i
] == '\\')
1223 for (j
= ++i
; i
< Length
; ++i
)
1225 if (Buffer
[i
] == '\\')
1228 if (Buffer
[j
] == '*')
1234 /* Get product description */
1235 if (Buffer
[i
] == '\\')
1237 for (j
= ++i
; i
< Length
; ++i
)
1239 if (Buffer
[i
] == ';')
1246 memcpy(&Identifier
[10],
1249 Identifier
[10 + (i
-j
)] = 0;
1253 DbgPrint((DPRINT_HWDETECT
,
1254 "Identifier string: %s\n",
1258 if (Length
== 0 || strlen(Identifier
) < 11)
1262 case MOUSE_TYPE_LOGITECH
:
1264 "LOGITECH SERIAL MOUSE");
1267 case MOUSE_TYPE_WHEELZ
:
1269 "MICROSOFT SERIAL MOUSE WITH WHEEL");
1272 case MOUSE_TYPE_MICROSOFT
:
1275 "MICROSOFT SERIAL MOUSE");
1280 /* Create 'PointerPeripheral' key */
1281 Error
= RegCreateKey(ControllerKey
,
1282 "PointerPeripheral\\0",
1284 if (Error
!= ERROR_SUCCESS
)
1286 DbgPrint((DPRINT_HWDETECT
,
1287 "Failed to create peripheral key\n"));
1290 DbgPrint((DPRINT_HWDETECT
,
1291 "Created key: PointerPeripheral\\0\n"));
1293 /* Set 'ComponentInformation' value */
1294 SetComponentInformation(PeripheralKey
,
1299 /* Set 'Configuration Data' value */
1300 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1301 FullResourceDescriptor
.InterfaceType
= Isa
;
1302 FullResourceDescriptor
.BusNumber
= 0;
1303 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1305 Error
= RegSetValue(PeripheralKey
,
1306 "Configuration Data",
1307 REG_FULL_RESOURCE_DESCRIPTOR
,
1308 (PU8
)&FullResourceDescriptor
,
1309 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1310 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1311 if (Error
!= ERROR_SUCCESS
)
1313 DbgPrint((DPRINT_HWDETECT
,
1314 "RegSetValue(Configuration Data) failed (Error %u)\n",
1318 /* Set 'Identifier' value */
1319 Error
= RegSetValue(PeripheralKey
,
1323 strlen(Identifier
) + 1);
1324 if (Error
!= ERROR_SUCCESS
)
1326 DbgPrint((DPRINT_HWDETECT
,
1327 "RegSetValue() failed (Error %u)\n",
1335 DetectSerialPorts(HKEY BusKey
)
1337 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1338 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1339 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
1340 U32 Base
[4] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
1341 U32 Irq
[4] = {4, 3, 4, 3};
1343 U32 ControllerNumber
= 0;
1349 DbgPrint((DPRINT_HWDETECT
, "DetectSerialPorts()\n"));
1351 for (i
= 0; i
< 4; i
++)
1353 WRITE_PORT_UCHAR ((PUCHAR
)(Base
[i
] + 4), 0x10);
1354 if (!(READ_PORT_UCHAR((PUCHAR
)Base
[i
] + 6) & 0xf0))
1356 DbgPrint((DPRINT_HWDETECT
,
1357 "Found COM%u port at 0x%x\n",
1361 /* Create controller key */
1363 "SerialController\\%u",
1366 Error
= RegCreateKey(BusKey
,
1369 if (Error
!= ERROR_SUCCESS
)
1371 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1374 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
1376 /* Set 'ComponentInformation' value */
1377 SetComponentInformation(ControllerKey
,
1382 /* Build full device descriptor */
1383 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1384 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
1385 sizeof(CM_SERIAL_DEVICE_DATA
);
1386 FullResourceDescriptor
= MmAllocateMemory(Size
);
1387 if (FullResourceDescriptor
== NULL
)
1389 DbgPrint((DPRINT_HWDETECT
,
1390 "Failed to allocate resource descriptor\n"));
1393 memset(FullResourceDescriptor
, 0, Size
);
1395 /* Initialize resource descriptor */
1396 FullResourceDescriptor
->InterfaceType
= Isa
;
1397 FullResourceDescriptor
->BusNumber
= 0;
1398 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
1401 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1402 PartialDescriptor
->Type
= CmResourceTypePort
;
1403 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1404 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1405 PartialDescriptor
->u
.Port
.Start
= (U64
)Base
[i
];
1406 PartialDescriptor
->u
.Port
.Length
= 7;
1409 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
1410 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1411 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1412 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1413 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1414 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
1415 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1417 /* Set serial data (device specific) */
1418 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
1419 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1420 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1421 PartialDescriptor
->Flags
= 0;
1422 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
1425 (PCM_SERIAL_DEVICE_DATA
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[3];
1426 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
1428 /* Set 'Configuration Data' value */
1429 Error
= RegSetValue(ControllerKey
,
1430 "Configuration Data",
1431 REG_FULL_RESOURCE_DESCRIPTOR
,
1432 (PU8
) FullResourceDescriptor
,
1434 MmFreeMemory(FullResourceDescriptor
);
1435 if (Error
!= ERROR_SUCCESS
)
1437 DbgPrint((DPRINT_HWDETECT
,
1438 "RegSetValue(Configuration Data) failed (Error %u)\n",
1442 /* Set 'Identifier' value */
1446 Error
= RegSetValue(ControllerKey
,
1451 if (Error
!= ERROR_SUCCESS
)
1453 DbgPrint((DPRINT_HWDETECT
,
1454 "RegSetValue() failed (Error %u)\n",
1458 DbgPrint((DPRINT_HWDETECT
,
1459 "Created value: Identifier %s\n",
1462 /* Detect serial mouse */
1463 DetectSerialPointerPeripheral(ControllerKey
, Base
[i
]);
1472 DetectKeyboardDevice(VOID
)
1477 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1480 KeStallExecutionProcessor(10000);
1482 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1483 if ((Status
& 0x01) != 0x01)
1485 /* PC/XT keyboard or no keyboard */
1489 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1490 if (Scancode
!= 0xFA)
1492 /* No ACK received */
1496 KeStallExecutionProcessor(10000);
1497 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1498 if ((Status
& 0x01) != 0x01)
1500 /* Found AT keyboard */
1504 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1505 if (Scancode
!= 0xAB)
1507 /* No 0xAB received */
1511 KeStallExecutionProcessor(10000);
1512 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1513 if ((Status
& 0x01) != 0x01)
1515 /* No byte in buffer */
1519 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1520 if (Scancode
!= 0x41)
1522 /* No 0x41 received */
1526 /* Found MF-II keyboard */
1532 DetectKeyboardPeripheral(HKEY ControllerKey
)
1534 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1535 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1536 PCM_KEYBOARD_DEVICE_DATA KeyboardData
;
1542 if (DetectKeyboardDevice())
1544 /* Create controller key */
1545 Error
= RegCreateKey(ControllerKey
,
1546 "KeyboardPeripheral\\0",
1548 if (Error
!= ERROR_SUCCESS
)
1550 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
1553 DbgPrint((DPRINT_HWDETECT
, "Created key: KeyboardPeripheral\\0\n"));
1555 /* Set 'ComponentInformation' value */
1556 SetComponentInformation(ControllerKey
,
1561 /* Set 'Configuration Data' value */
1562 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1563 sizeof(CM_KEYBOARD_DEVICE_DATA
);
1564 FullResourceDescriptor
= MmAllocateMemory(Size
);
1565 if (FullResourceDescriptor
== NULL
)
1567 DbgPrint((DPRINT_HWDETECT
,
1568 "Failed to allocate resource descriptor\n"));
1572 /* Initialize resource descriptor */
1573 memset(FullResourceDescriptor
, 0, Size
);
1574 FullResourceDescriptor
->InterfaceType
= Isa
;
1575 FullResourceDescriptor
->BusNumber
= 0;
1576 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
1578 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1579 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1580 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1581 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_KEYBOARD_DEVICE_DATA
);
1583 KeyboardData
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
1584 KeyboardData
->Version
= 0;
1585 KeyboardData
->Revision
= 0;
1586 KeyboardData
->Type
= 4;
1587 KeyboardData
->Subtype
= 0;
1588 KeyboardData
->KeyboardFlags
= 0x20;
1590 /* Set 'Configuration Data' value */
1591 Error
= RegSetValue(PeripheralKey
,
1592 "Configuration Data",
1593 REG_FULL_RESOURCE_DESCRIPTOR
,
1594 (PU8
)FullResourceDescriptor
,
1596 MmFreeMemory(FullResourceDescriptor
);
1597 if (Error
!= ERROR_SUCCESS
)
1599 DbgPrint((DPRINT_HWDETECT
,
1600 "RegSetValue(Configuration Data) failed (Error %u)\n",
1604 /* Set 'Identifier' value */
1607 Error
= RegSetValue(ControllerKey
,
1611 strlen(Buffer
) + 1);
1612 if (Error
!= ERROR_SUCCESS
)
1614 DbgPrint((DPRINT_HWDETECT
,
1615 "RegSetValue() failed (Error %u)\n",
1623 DetectKeyboardController(HKEY BusKey
)
1625 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1626 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1631 /* Create controller key */
1632 Error
= RegCreateKey(BusKey
,
1633 "KeyboardController\\0",
1635 if (Error
!= ERROR_SUCCESS
)
1637 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1640 DbgPrint((DPRINT_HWDETECT
, "Created key: KeyboardController\\0\n"));
1642 /* Set 'ComponentInformation' value */
1643 SetComponentInformation(ControllerKey
,
1648 /* Set 'Configuration Data' value */
1649 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1650 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1651 FullResourceDescriptor
= MmAllocateMemory(Size
);
1652 if (FullResourceDescriptor
== NULL
)
1654 DbgPrint((DPRINT_HWDETECT
,
1655 "Failed to allocate resource descriptor\n"));
1659 /* Initialize resource descriptor */
1660 memset(FullResourceDescriptor
, 0, Size
);
1661 FullResourceDescriptor
->InterfaceType
= Isa
;
1662 FullResourceDescriptor
->BusNumber
= 0;
1663 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
1666 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1667 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1668 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1669 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1670 PartialDescriptor
->u
.Interrupt
.Level
= 1;
1671 PartialDescriptor
->u
.Interrupt
.Vector
= 1;
1672 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1674 /* Set IO Port 0x60 */
1675 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
1676 PartialDescriptor
->Type
= CmResourceTypePort
;
1677 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1678 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1679 PartialDescriptor
->u
.Port
.Start
= (U64
)0x60;
1680 PartialDescriptor
->u
.Port
.Length
= 1;
1682 /* Set IO Port 0x64 */
1683 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
1684 PartialDescriptor
->Type
= CmResourceTypePort
;
1685 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1686 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1687 PartialDescriptor
->u
.Port
.Start
= (U64
)0x64;
1688 PartialDescriptor
->u
.Port
.Length
= 1;
1690 /* Set 'Configuration Data' value */
1691 Error
= RegSetValue(ControllerKey
,
1692 "Configuration Data",
1693 REG_FULL_RESOURCE_DESCRIPTOR
,
1694 (PU8
)FullResourceDescriptor
,
1696 MmFreeMemory(FullResourceDescriptor
);
1697 if (Error
!= ERROR_SUCCESS
)
1699 DbgPrint((DPRINT_HWDETECT
,
1700 "RegSetValue(Configuration Data) failed (Error %u)\n",
1705 DetectKeyboardPeripheral(ControllerKey
);
1710 PS2ControllerWait(VOID
)
1715 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1717 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1718 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1721 /* Sleep for one millisecond */
1722 KeStallExecutionProcessor(1000);
1728 DetectPS2AuxPort(VOID
)
1734 /* Put the value 0x5A in the output buffer using the
1735 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1736 * Poll the Status Register for a while to see if the value really turns up
1737 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1738 * to 1 in the Status Register, we assume this controller has an
1739 * Auxiliary Port (a.k.a. Mouse Port).
1741 PS2ControllerWait();
1742 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1743 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1744 PS2ControllerWait();
1746 /* 0x5A is a random dummy value */
1747 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1750 for (Loops
= 0; Loops
< 10; Loops
++)
1752 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1754 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1756 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1757 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) != 0)
1764 KeStallExecutionProcessor(10000);
1772 DetectPS2AuxDevice(VOID
)
1777 PS2ControllerWait();
1778 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1779 CONTROLLER_COMMAND_WRITE_MOUSE
);
1780 PS2ControllerWait();
1782 /* Identify device */
1783 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1786 KeStallExecutionProcessor(10000);
1788 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1789 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1794 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1795 if (Scancode
!= 0xFA)
1798 KeStallExecutionProcessor(10000);
1800 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1801 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1806 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1807 if (Scancode
!= 0x00)
1815 DetectPS2Mouse(HKEY BusKey
)
1817 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1822 if (DetectPS2AuxPort())
1824 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 port\n"));
1826 /* Create controller key */
1827 Error
= RegCreateKey(BusKey
,
1828 "PointerController\\0",
1830 if (Error
!= ERROR_SUCCESS
)
1832 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1835 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerController\\0\n"));
1837 /* Set 'ComponentInformation' value */
1838 SetComponentInformation(ControllerKey
,
1843 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1845 /* Initialize resource descriptor */
1846 FullResourceDescriptor
.InterfaceType
= Isa
;
1847 FullResourceDescriptor
.BusNumber
= 0;
1848 FullResourceDescriptor
.PartialResourceList
.Count
= 1;
1851 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1852 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1853 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1854 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1855 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Vector
= 12;
1856 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1858 /* Set 'Configuration Data' value */
1859 Error
= RegSetValue(ControllerKey
,
1860 "Configuration Data",
1861 REG_FULL_RESOURCE_DESCRIPTOR
,
1862 (PU8
)&FullResourceDescriptor
,
1863 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1864 if (Error
!= ERROR_SUCCESS
)
1866 DbgPrint((DPRINT_HWDETECT
,
1867 "RegSetValue(Configuration Data) failed (Error %u)\n",
1873 if (DetectPS2AuxDevice())
1875 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 mouse\n"));
1877 /* Create peripheral key */
1878 Error
= RegCreateKey(ControllerKey
,
1879 "PointerPeripheral\\0",
1881 if (Error
!= ERROR_SUCCESS
)
1883 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
1886 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerPeripheral\\0\n"));
1888 /* Set 'ComponentInformation' value */
1889 SetComponentInformation(PeripheralKey
,
1894 /* Initialize resource descriptor */
1895 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1896 FullResourceDescriptor
.InterfaceType
= Isa
;
1897 FullResourceDescriptor
.BusNumber
= 0;
1898 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1900 /* Set 'Configuration Data' value */
1901 Error
= RegSetValue(PeripheralKey
,
1902 "Configuration Data",
1903 REG_FULL_RESOURCE_DESCRIPTOR
,
1904 (PU8
)&FullResourceDescriptor
,
1905 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1906 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1907 if (Error
!= ERROR_SUCCESS
)
1909 DbgPrint((DPRINT_HWDETECT
,
1910 "RegSetValue(Configuration Data) failed (Error %u)\n",
1915 /* Set 'Identifier' value */
1916 Error
= RegSetValue(PeripheralKey
,
1919 (PU8
)"MICROSOFT PS2 MOUSE",
1921 if (Error
!= ERROR_SUCCESS
)
1923 DbgPrint((DPRINT_HWDETECT
,
1924 "RegSetValue() failed (Error %u)\n",
1934 DetectIsaBios(HKEY SystemKey
, U32
*BusNumber
)
1936 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1942 /* Create new bus key */
1944 "MultifunctionAdapter\\%u", *BusNumber
);
1945 Error
= RegCreateKey(SystemKey
,
1948 if (Error
!= ERROR_SUCCESS
)
1950 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
1954 /* Set 'Component Information' value similar to my NT4 box */
1955 SetComponentInformation(BusKey
,
1960 /* Increment bus number */
1963 /* Set 'Identifier' value */
1964 Error
= RegSetValue(BusKey
,
1969 if (Error
!= ERROR_SUCCESS
)
1971 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
1975 /* Set 'Configuration Data' value */
1976 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1977 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1978 FullResourceDescriptor
= MmAllocateMemory(Size
);
1979 if (FullResourceDescriptor
== NULL
)
1981 DbgPrint((DPRINT_HWDETECT
,
1982 "Failed to allocate resource descriptor\n"));
1986 /* Initialize resource descriptor */
1987 memset(FullResourceDescriptor
, 0, Size
);
1988 FullResourceDescriptor
->InterfaceType
= Isa
;
1989 FullResourceDescriptor
->BusNumber
= 0;
1990 FullResourceDescriptor
->PartialResourceList
.Count
= 0;
1992 /* Set 'Configuration Data' value */
1993 Error
= RegSetValue(BusKey
,
1994 "Configuration Data",
1995 REG_FULL_RESOURCE_DESCRIPTOR
,
1996 (PU8
) FullResourceDescriptor
,
1998 MmFreeMemory(FullResourceDescriptor
);
1999 if (Error
!= ERROR_SUCCESS
)
2001 DbgPrint((DPRINT_HWDETECT
,
2002 "RegSetValue(Configuration Data) failed (Error %u)\n",
2007 /* Detect ISA/BIOS devices */
2008 DetectBiosDisks(SystemKey
, BusKey
);
2010 DetectBiosFloppyController(SystemKey
, BusKey
);
2012 DetectSerialPorts(BusKey
);
2015 DetectParallelPorts(BusKey
);
2018 DetectKeyboardController(BusKey
);
2020 DetectPS2Mouse(BusKey
);
2022 /* FIXME: Detect more ISA devices */
2027 DetectHardware(VOID
)
2033 DbgPrint((DPRINT_HWDETECT
, "DetectHardware()\n"));
2035 HalpCalibrateStallExecution ();
2037 /* Create the 'System' key */
2038 Error
= RegCreateKey(NULL
,
2039 "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
2041 if (Error
!= ERROR_SUCCESS
)
2043 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
2050 DetectCPUs(SystemKey
);
2054 DetectPciBios(&BusNumber
);
2055 DetectApmBios(&BusNumber
);
2057 DetectPnpBios(SystemKey
, &BusNumber
);
2058 DetectIsaBios(SystemKey
, &BusNumber
);
2060 DetectAcpiBios(&BusNumber
);
2064 DbgPrint((DPRINT_HWDETECT
, "DetectHardware() Done\n"));
2067 printf("*** System stopped ***\n");