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.
30 #include "../../reactos/registry.h"
38 #define CLOCK_TICK_RATE (1193182)
39 #define LATCH (CLOCK_TICK_RATE / HZ)
43 #define MOUSE_TYPE_NONE 0
44 /* Microsoft Mouse with 2 buttons */
45 #define MOUSE_TYPE_MICROSOFT 1
46 /* Logitech Mouse with 3 buttons */
47 #define MOUSE_TYPE_LOGITECH 2
48 /* Microsoft Wheel Mouse (aka Z Mouse) */
49 #define MOUSE_TYPE_WHEELZ 3
50 /* Mouse Systems Mouse */
51 #define MOUSE_TYPE_MOUSESYSTEMS 4
56 /* Controller registers. */
57 #define CONTROLLER_REGISTER_STATUS 0x64
58 #define CONTROLLER_REGISTER_CONTROL 0x64
59 #define CONTROLLER_REGISTER_DATA 0x60
61 /* Controller commands. */
62 #define CONTROLLER_COMMAND_READ_MODE 0x20
63 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
64 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
65 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
66 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
67 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
68 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
69 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
70 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
71 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
72 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
73 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
75 /* Controller status */
76 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
77 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
78 #define CONTROLLER_STATUS_SELF_TEST 0x04
79 #define CONTROLLER_STATUS_COMMAND 0x08
80 #define CONTROLLER_STATUS_UNLOCKED 0x10
81 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
82 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
83 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
84 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
85 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
87 /* Timeout in ms for sending to keyboard controller. */
88 #define CONTROLLER_TIMEOUT 250
91 typedef struct _CM_INT13_DRIVE_PARAMETER
98 } CM_INT13_DRIVE_PARAMETER
, *PCM_INT13_DRIVE_PARAMETER
;
101 typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA
104 U32 NumberOfCylinders
;
107 } CM_DISK_GEOMETRY_DEVICE_DATA
, *PCM_DISK_GEOMETRY_DEVICE_DATA
;
110 typedef struct _CM_PNP_BIOS_DEVICE_NODE
116 U16 DeviceAttributes
;
117 } __attribute__((packed
)) CM_PNP_BIOS_DEVICE_NODE
, *PCM_PNP_BIOS_DEVICE_NODE
;
120 typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
127 U32 EventFlagAddress
;
128 U16 RealModeEntryOffset
;
129 U16 RealModeEntrySegment
;
130 U16 ProtectedModeEntryOffset
;
131 U32 ProtectedModeCodeBaseAddress
;
133 U16 RealModeDataBaseAddress
;
134 U32 ProtectedModeDataBaseAddress
;
135 } __attribute__((packed
)) CM_PNP_BIOS_INSTALLATION_CHECK
, *PCM_PNP_BIOS_INSTALLATION_CHECK
;
138 typedef struct _CM_SERIAL_DEVICE_DATA
143 } __attribute__((packed
)) CM_SERIAL_DEVICE_DATA
, *PCM_SERIAL_DEVICE_DATA
;
146 typedef struct _CM_FLOPPY_DEVICE_DATA
154 /* Version 2.0 data */
155 U8 StepRateHeadUnloadTime
;
160 U8 ReadWriteGapLength
;
161 U8 DataTransferLength
;
163 U8 FormatFillCharacter
;
166 U8 MaximumTrackValue
;
168 } __attribute__((packed
)) CM_FLOPPY_DEVICE_DATA
, *PCM_FLOPPY_DEVICE_DATA
;
171 typedef struct _CM_KEYBOARD_DEVICE_DATA
178 } __attribute__((packed
)) CM_KEYBOARD_DEVICE_DATA
, *PCM_KEYBOARD_DEVICE_DATA
;
181 static char Hex
[] = "0123456789ABCDEF";
182 static unsigned int delay_count
= 1;
185 /* FUNCTIONS ****************************************************************/
189 __KeStallExecutionProcessor(U32 Loops
)
191 register unsigned int i
;
192 for (i
= 0; i
< Loops
; i
++);
195 VOID
KeStallExecutionProcessor(U32 Microseconds
)
197 U64 LoopCount
= ((U64
)delay_count
* (U64
)Microseconds
) / 1000ULL;
198 __KeStallExecutionProcessor((U32
)LoopCount
);
207 WRITE_PORT_UCHAR((PU8
)0x43, 0x00);
208 Count
= READ_PORT_UCHAR((PU8
)0x40);
209 Count
|= READ_PORT_UCHAR((PU8
)0x40) << 8;
216 WaitFor8254Wraparound(VOID
)
222 CurCount
= Read8254Timer();
226 PrevCount
= CurCount
;
227 CurCount
= Read8254Timer();
228 Delta
= CurCount
- PrevCount
;
231 * This limit for delta seems arbitrary, but it isn't, it's
232 * slightly above the level of error a buggy Mercury/Neptune
233 * chipset timer can cause.
241 HalpCalibrateStallExecution(VOID
)
247 /* Initialise timer interrupt with MILLISECOND ms interval */
248 WRITE_PORT_UCHAR((PU8
)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
249 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
& 0xff); /* LSB */
250 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
>> 8); /* MSB */
252 /* Stage 1: Coarse calibration */
254 WaitFor8254Wraparound();
259 delay_count
<<= 1; /* Next delay count to try */
261 WaitFor8254Wraparound();
263 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
265 CurCount
= Read8254Timer();
266 } while (CurCount
> LATCH
/ 2);
268 delay_count
>>= 1; /* Get bottom value for delay */
270 /* Stage 2: Fine calibration */
272 calib_bit
= delay_count
; /* Which bit are we going to test */
274 for(i
=0;i
<PRECISION
;i
++) {
275 calib_bit
>>= 1; /* Next bit to calibrate */
276 if(!calib_bit
) break; /* If we have done all bits, stop */
278 delay_count
|= calib_bit
; /* Set the bit in delay_count */
280 WaitFor8254Wraparound();
282 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
284 CurCount
= Read8254Timer();
285 if (CurCount
<= LATCH
/ 2) /* If a tick has passed, turn the */
286 delay_count
&= ~calib_bit
; /* calibrated bit back off */
289 /* We're finished: Do the finishing touches */
290 delay_count
/= (MILLISEC
/ 2); /* Calculate delay_count for 1ms */
295 SetComponentInformation(HKEY ComponentKey
,
300 CM_COMPONENT_INFORMATION CompInfo
;
303 CompInfo
.Flags
= Flags
;
304 CompInfo
.Version
= 0;
306 CompInfo
.Affinity
= Affinity
;
308 /* Set 'Component Information' value */
309 Error
= RegSetValue(ComponentKey
,
310 "Component Information",
313 sizeof(CM_COMPONENT_INFORMATION
));
314 if (Error
!= ERROR_SUCCESS
)
316 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
322 DetectPnpBios(HKEY SystemKey
, U32
*BusNumber
)
324 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
325 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
326 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
340 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
341 if (InstData
== NULL
|| strncmp(InstData
->Signature
, "$PnP", 4))
343 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS not supported\n"));
346 DbgPrint((DPRINT_HWDETECT
, "Signature '%c%c%c%c'\n",
347 InstData
->Signature
[0], InstData
->Signature
[1],
348 InstData
->Signature
[2], InstData
->Signature
[3]));
351 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
352 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
354 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS failed to enumerate device nodes\n"));
357 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS supported\n"));
358 DbgPrint((DPRINT_HWDETECT
, "MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
));
359 DbgPrint((DPRINT_HWDETECT
, "Estimated buffer size %u\n", NodeSize
* NodeCount
));
361 /* Create new bus key */
363 "MultifunctionAdapter\\%u", *BusNumber
);
364 Error
= RegCreateKey(SystemKey
,
367 if (Error
!= ERROR_SUCCESS
)
369 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
373 /* Increment bus number */
376 /* Set 'Identifier' value */
377 Error
= RegSetValue(BusKey
,
382 if (Error
!= ERROR_SUCCESS
)
384 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
388 /* Set 'Configuration Data' value */
389 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + (NodeSize
* NodeCount
);
390 FullResourceDescriptor
= MmAllocateMemory(Size
);
391 if (FullResourceDescriptor
== NULL
)
393 DbgPrint((DPRINT_HWDETECT
,
394 "Failed to allocate resource descriptor\n"));
397 memset(FullResourceDescriptor
, 0, Size
);
399 /* Initialize resource descriptor */
400 FullResourceDescriptor
->InterfaceType
= Internal
;
401 FullResourceDescriptor
->BusNumber
= 0;
402 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
403 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
404 CmResourceTypeDeviceSpecific
;
405 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].ShareDisposition
=
406 CmResourceShareUndetermined
;
407 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
409 Ptr
= (char *)(((PVOID
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0]) +
410 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
412 /* Set instalation check data */
413 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
414 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
416 /* Copy device nodes */
418 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
419 for (i
= 0; i
< 0xFF; i
++)
423 x
= PnpBiosGetDeviceNode(&NodeNumber
, (PVOID
)DISKREADBUFFER
);
426 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DISKREADBUFFER
;
428 DbgPrint((DPRINT_HWDETECT
,
429 "Node: %u Size %u (0x%x)\n",
433 // printf("Node: %u Size %u (0x%x)\n",
436 // DeviceNode->Size);
442 Ptr
+= DeviceNode
->Size
;
443 PnpBufferSize
+= DeviceNode
->Size
;
446 if (FoundNodeCount
>= NodeCount
)
451 /* Set real data size */
452 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
454 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + PnpBufferSize
;
456 DbgPrint((DPRINT_HWDETECT
, "Real buffer size: %u\n", PnpBufferSize
));
457 DbgPrint((DPRINT_HWDETECT
, "Resource size: %u\n", Size
));
459 /* Set 'Configuration Data' value */
460 Error
= RegSetValue(BusKey
,
461 "Configuration Data",
462 REG_FULL_RESOURCE_DESCRIPTOR
,
463 (PU8
) FullResourceDescriptor
,
465 MmFreeMemory(FullResourceDescriptor
);
466 if (Error
!= ERROR_SUCCESS
)
468 DbgPrint((DPRINT_HWDETECT
,
469 "RegSetValue(Configuration Data) failed (Error %u)\n",
477 SetHarddiskConfigurationData(HKEY DiskKey
,
480 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
481 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
482 EXTENDED_GEOMETRY ExtGeometry
;
487 /* Set 'Configuration Data' value */
488 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
489 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
490 FullResourceDescriptor
= MmAllocateMemory(Size
);
491 if (FullResourceDescriptor
== NULL
)
493 DbgPrint((DPRINT_HWDETECT
,
494 "Failed to allocate a full resource descriptor\n"));
498 memset(FullResourceDescriptor
, 0, Size
);
499 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
500 FullResourceDescriptor
->BusNumber
= 0;
501 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
502 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
503 CmResourceTypeDeviceSpecific
;
504 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
505 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
506 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
507 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
509 /* Get pointer to geometry data */
510 DiskGeometry
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
512 /* Get the disk geometry */
513 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
514 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
516 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
517 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
518 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
519 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
521 else if(DiskGetDriveParameters(DriveNumber
, &Geometry
))
523 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
524 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
525 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
526 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
530 DbgPrint((DPRINT_HWDETECT
, "Reading disk geometry failed\n"));
531 MmFreeMemory(FullResourceDescriptor
);
534 DbgPrint((DPRINT_HWDETECT
,
535 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
537 DiskGeometry
->NumberOfCylinders
,
538 DiskGeometry
->NumberOfHeads
,
539 DiskGeometry
->SectorsPerTrack
,
540 DiskGeometry
->BytesPerSector
));
542 Error
= RegSetValue(DiskKey
,
543 "Configuration Data",
544 REG_FULL_RESOURCE_DESCRIPTOR
,
545 (PU8
) FullResourceDescriptor
,
547 MmFreeMemory(FullResourceDescriptor
);
548 if (Error
!= ERROR_SUCCESS
)
550 DbgPrint((DPRINT_HWDETECT
,
551 "RegSetValue(Configuration Data) failed (Error %u)\n",
558 SetHarddiskIdentifier(HKEY DiskKey
,
561 PMASTER_BOOT_RECORD Mbr
;
570 if (!DiskReadLogicalSectors(DriveNumber
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
572 DbgPrint((DPRINT_HWDETECT
, "Reading MBR failed\n"));
576 Buffer
= (U32
*)DISKREADBUFFER
;
577 Mbr
= (PMASTER_BOOT_RECORD
)DISKREADBUFFER
;
579 Signature
= Mbr
->Signature
;
580 DbgPrint((DPRINT_HWDETECT
, "Signature: %x\n", Signature
));
582 /* Calculate the MBR checksum */
584 for (i
= 0; i
< 128; i
++)
586 Checksum
+= Buffer
[i
];
588 Checksum
= ~Checksum
+ 1;
589 DbgPrint((DPRINT_HWDETECT
, "Checksum: %x\n", Checksum
));
591 /* Convert checksum and signature to identifier string */
592 Identifier
[0] = Hex
[(Checksum
>> 28) & 0x0F];
593 Identifier
[1] = Hex
[(Checksum
>> 24) & 0x0F];
594 Identifier
[2] = Hex
[(Checksum
>> 20) & 0x0F];
595 Identifier
[3] = Hex
[(Checksum
>> 16) & 0x0F];
596 Identifier
[4] = Hex
[(Checksum
>> 12) & 0x0F];
597 Identifier
[5] = Hex
[(Checksum
>> 8) & 0x0F];
598 Identifier
[6] = Hex
[(Checksum
>> 4) & 0x0F];
599 Identifier
[7] = Hex
[Checksum
& 0x0F];
601 Identifier
[9] = Hex
[(Signature
>> 28) & 0x0F];
602 Identifier
[10] = Hex
[(Signature
>> 24) & 0x0F];
603 Identifier
[11] = Hex
[(Signature
>> 20) & 0x0F];
604 Identifier
[12] = Hex
[(Signature
>> 16) & 0x0F];
605 Identifier
[13] = Hex
[(Signature
>> 12) & 0x0F];
606 Identifier
[14] = Hex
[(Signature
>> 8) & 0x0F];
607 Identifier
[15] = Hex
[(Signature
>> 4) & 0x0F];
608 Identifier
[16] = Hex
[Signature
& 0x0F];
609 Identifier
[17] = '-';
610 Identifier
[18] = 'A';
612 DbgPrint((DPRINT_HWDETECT
, "Identifier: %xsn", Identifier
));
615 Error
= RegSetValue(DiskKey
,
620 if (Error
!= ERROR_SUCCESS
)
622 DbgPrint((DPRINT_HWDETECT
,
623 "RegSetValue(Identifier) failed (Error %u)\n",
630 DetectBiosDisks(HKEY SystemKey
,
633 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
634 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
643 /* Count the number of visible drives */
644 DiskReportError(FALSE
);
646 while (DiskReadLogicalSectors(0x80 + DiskCount
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
650 DiskReportError(TRUE
);
651 DbgPrint((DPRINT_HWDETECT
, "BIOS reports %d harddisk%s\n",
652 (int)DiskCount
, (DiskCount
== 1) ? "": "s"));
654 /* Allocate resource descriptor */
655 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
656 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
657 FullResourceDescriptor
= MmAllocateMemory(Size
);
658 if (FullResourceDescriptor
== NULL
)
660 DbgPrint((DPRINT_HWDETECT
,
661 "Failed to allocate resource descriptor\n"));
665 /* Initialize resource descriptor */
666 memset(FullResourceDescriptor
, 0, Size
);
667 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
668 FullResourceDescriptor
->BusNumber
= -1;
669 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
670 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
671 CmResourceTypeDeviceSpecific
;
672 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
673 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
674 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
675 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
677 /* Get harddisk Int13 geometry data */
678 Int13Drives
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
679 for (i
= 0; i
< DiskCount
; i
++)
681 if (DiskGetDriveParameters(0x80 + i
, &Geometry
))
683 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
684 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
685 Int13Drives
[i
].SectorsPerTrack
= Geometry
.Sectors
;
686 Int13Drives
[i
].MaxHeads
= Geometry
.Heads
- 1;
687 Int13Drives
[i
].NumberDrives
= DiskCount
;
689 DbgPrint((DPRINT_HWDETECT
,
690 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
692 Geometry
.Cylinders
- 1,
695 Geometry
.BytesPerSector
));
699 /* Set 'Configuration Data' value */
700 Error
= RegSetValue(SystemKey
,
701 "Configuration Data",
702 REG_FULL_RESOURCE_DESCRIPTOR
,
703 (PU8
) FullResourceDescriptor
,
705 MmFreeMemory(FullResourceDescriptor
);
706 if (Error
!= ERROR_SUCCESS
)
708 DbgPrint((DPRINT_HWDETECT
,
709 "RegSetValue(Configuration Data) failed (Error %u)\n",
714 /* Create and fill subkey for each harddisk */
715 for (i
= 0; i
< DiskCount
; i
++)
717 /* Create disk key */
719 "DiskController\\0\\DiskPeripheral\\%u",
722 Error
= RegCreateKey(BusKey
,
725 if (Error
!= ERROR_SUCCESS
)
727 DbgPrint((DPRINT_HWDETECT
, "Failed to create drive key\n"));
730 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
732 /* Set disk values */
733 SetHarddiskConfigurationData(DiskKey
, 0x80 + i
);
734 SetHarddiskIdentifier(DiskKey
, 0x80 + i
);
744 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
745 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
747 return ((Data
& 0xF0) ? 1 : 0) + ((Data
& 0x0F) ? 1 : 0);
752 GetFloppyType(U8 DriveNumber
)
756 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
757 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
759 if (DriveNumber
== 0)
761 else if (DriveNumber
== 1)
771 PU16 SegPtr
= (PU16
)0x7A;
772 PU16 OfsPtr
= (PU16
)0x78;
774 return (PVOID
)(((U32
)(*SegPtr
)) << 4) + (U32
)(*OfsPtr
);
779 DetectBiosFloppyPeripheral(HKEY ControllerKey
)
781 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
782 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
783 PCM_FLOPPY_DEVICE_DATA FloppyData
;
791 U32 MaxDensity
[6] = {0, 360, 1200, 720, 1440, 2880};
794 for (FloppyNumber
= 0; FloppyNumber
< 2; FloppyNumber
++)
796 FloppyType
= GetFloppyType(FloppyNumber
);
798 if ((FloppyType
> 5) || (FloppyType
== 0))
801 DiskResetController(FloppyNumber
);
803 Ptr
= GetInt1eTable();
805 sprintf(KeyName
, "FloppyDiskPeripheral\\%u", FloppyNumber
);
807 Error
= RegCreateKey(ControllerKey
,
808 "FloppyDiskPeripheral\\0",
810 if (Error
!= ERROR_SUCCESS
)
812 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
816 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", KeyName
));
818 /* Set 'ComponentInformation' value */
819 SetComponentInformation(PeripheralKey
,
824 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
825 sizeof(CM_FLOPPY_DEVICE_DATA
);
826 FullResourceDescriptor
= MmAllocateMemory(Size
);
827 if (FullResourceDescriptor
== NULL
)
829 DbgPrint((DPRINT_HWDETECT
,
830 "Failed to allocate resource descriptor\n"));
834 memset(FullResourceDescriptor
, 0, Size
);
835 FullResourceDescriptor
->InterfaceType
= Isa
;
836 FullResourceDescriptor
->BusNumber
= 0;
837 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
839 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
840 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
841 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
842 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_FLOPPY_DEVICE_DATA
);
844 FloppyData
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
845 FloppyData
->Version
= 2;
846 FloppyData
->Revision
= 0;
847 FloppyData
->MaxDensity
= MaxDensity
[FloppyType
];
848 FloppyData
->MountDensity
= 0;
849 RtlCopyMemory(&FloppyData
->StepRateHeadUnloadTime
,
852 FloppyData
->MaximumTrackValue
= (FloppyType
== 1) ? 39 : 79;
853 FloppyData
->DataTransferRate
= 0;
855 /* Set 'Configuration Data' value */
856 Error
= RegSetValue(PeripheralKey
,
857 "Configuration Data",
858 REG_FULL_RESOURCE_DESCRIPTOR
,
859 (PU8
) FullResourceDescriptor
,
861 MmFreeMemory(FullResourceDescriptor
);
862 if (Error
!= ERROR_SUCCESS
)
864 DbgPrint((DPRINT_HWDETECT
,
865 "RegSetValue(Configuration Data) failed (Error %u)\n",
870 /* Set 'Identifier' value */
871 sprintf(Identifier
, "FLOPPY%u", FloppyNumber
+ 1);
872 Error
= RegSetValue(PeripheralKey
,
876 strlen(Identifier
) + 1);
877 if (Error
!= ERROR_SUCCESS
)
879 DbgPrint((DPRINT_HWDETECT
,
880 "RegSetValue() failed (Error %u)\n",
888 DetectBiosFloppyController(HKEY SystemKey
,
891 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
892 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
898 FloppyCount
= GetFloppyCount();
899 DbgPrint((DPRINT_HWDETECT
,
900 "Floppy count: %u\n",
903 if (FloppyCount
== 0)
906 Error
= RegCreateKey(BusKey
,
909 if (Error
!= ERROR_SUCCESS
)
911 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
915 DbgPrint((DPRINT_HWDETECT
, "Created key: DiskController\\0\n"));
917 /* Set 'ComponentInformation' value */
918 SetComponentInformation(ControllerKey
,
923 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
924 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
925 FullResourceDescriptor
= MmAllocateMemory(Size
);
926 if (FullResourceDescriptor
== NULL
)
928 DbgPrint((DPRINT_HWDETECT
,
929 "Failed to allocate resource descriptor\n"));
932 memset(FullResourceDescriptor
, 0, Size
);
934 /* Initialize resource descriptor */
935 FullResourceDescriptor
->InterfaceType
= Isa
;
936 FullResourceDescriptor
->BusNumber
= 0;
937 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
940 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
941 PartialDescriptor
->Type
= CmResourceTypePort
;
942 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
943 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
944 PartialDescriptor
->u
.Port
.Start
= (U64
)0x03F0;
945 PartialDescriptor
->u
.Port
.Length
= 8;
948 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
949 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
950 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
951 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
952 PartialDescriptor
->u
.Interrupt
.Level
= 6;
953 PartialDescriptor
->u
.Interrupt
.Vector
= 6;
954 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
956 /* Set DMA channel */
957 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
958 PartialDescriptor
->Type
= CmResourceTypeDma
;
959 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
960 PartialDescriptor
->Flags
= 0;
961 PartialDescriptor
->u
.Dma
.Channel
= 2;
962 PartialDescriptor
->u
.Dma
.Port
= 0;
964 /* Set 'Configuration Data' value */
965 Error
= RegSetValue(ControllerKey
,
966 "Configuration Data",
967 REG_FULL_RESOURCE_DESCRIPTOR
,
968 (PU8
) FullResourceDescriptor
,
970 MmFreeMemory(FullResourceDescriptor
);
971 if (Error
!= ERROR_SUCCESS
)
973 DbgPrint((DPRINT_HWDETECT
,
974 "RegSetValue(Configuration Data) failed (Error %u)\n",
979 DetectBiosFloppyPeripheral(ControllerKey
);
984 InitializeSerialPort(U32 Port
,
987 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, 0x80); /* set DLAB on */
988 WRITE_PORT_UCHAR((PUCHAR
)Port
, 0x60); /* speed LO byte */
989 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* speed HI byte */
990 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, LineControl
);
991 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* set comm and DLAB to 0 */
992 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09); /* DR int enable */
993 READ_PORT_UCHAR((PUCHAR
)Port
+ 5); /* clear error bits */
998 DetectSerialMouse(U32 Port
)
1005 /* Shutdown mouse or something like that */
1006 LineControl
= READ_PORT_UCHAR((PUCHAR
)Port
+ 4);
1007 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, (LineControl
& ~0x02) | 0x01);
1008 KeStallExecutionProcessor(100000);
1011 while (READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 0x01)
1012 READ_PORT_UCHAR((PUCHAR
)Port
);
1015 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
1016 * 'Output Line 2' message. This enables mouse to identify.
1018 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
1020 /* Wait 10 milliseconds for the mouse getting ready */
1021 KeStallExecutionProcessor(10000);
1023 /* Read first four bytes, which contains Microsoft Mouse signs */
1024 for (i
= 0; i
< 4; i
++)
1026 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1028 KeStallExecutionProcessor(1000);
1031 return MOUSE_TYPE_NONE
;
1033 Buffer
[i
] = READ_PORT_UCHAR((PUCHAR
)Port
);
1036 DbgPrint((DPRINT_HWDETECT
,
1037 "Mouse data: %x %x %x %x\n",
1038 Buffer
[0],Buffer
[1],Buffer
[2],Buffer
[3]));
1040 /* Check that four bytes for signs */
1041 for (i
= 0; i
< 4; ++i
)
1043 if (Buffer
[i
] == 'B')
1045 /* Sign for Microsoft Ballpoint */
1046 // DbgPrint("Microsoft Ballpoint device detected\n");
1047 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
1048 return MOUSE_TYPE_NONE
;
1050 else if (Buffer
[i
] == 'M')
1052 /* Sign for Microsoft Mouse protocol followed by button specifier */
1055 /* Overflow Error */
1056 return MOUSE_TYPE_NONE
;
1059 switch (Buffer
[i
+ 1])
1062 DbgPrint((DPRINT_HWDETECT
,
1063 "Microsoft Mouse with 3-buttons detected\n"));
1064 return MOUSE_TYPE_LOGITECH
;
1067 DbgPrint((DPRINT_HWDETECT
,
1068 "Microsoft Wheel Mouse detected\n"));
1069 return MOUSE_TYPE_WHEELZ
;
1073 DbgPrint((DPRINT_HWDETECT
,
1074 "Microsoft Mouse with 2-buttons detected\n"));
1075 return MOUSE_TYPE_MICROSOFT
;
1080 return MOUSE_TYPE_NONE
;
1085 GetSerialMousePnpId(U32 Port
, char *Buffer
)
1092 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09);
1094 /* Wait 10 milliseconds for the mouse getting ready */
1095 KeStallExecutionProcessor(10000);
1097 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
1099 KeStallExecutionProcessor(10000);
1104 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1106 KeStallExecutionProcessor(1000);
1114 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
1115 if (c
== 0x08 || c
== 0x28)
1125 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1127 KeStallExecutionProcessor(1000);
1132 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
1145 DetectSerialPointerPeripheral(HKEY ControllerKey
,
1148 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1150 char Identifier
[256];
1158 DbgPrint((DPRINT_HWDETECT
,
1159 "DetectSerialPointerPeripheral()\n"));
1163 InitializeSerialPort(Base
, 2);
1164 MouseType
= DetectSerialMouse(Base
);
1166 if (MouseType
!= MOUSE_TYPE_NONE
)
1168 Length
= GetSerialMousePnpId(Base
, Buffer
);
1169 DbgPrint((DPRINT_HWDETECT
,
1170 "PnP ID length: %u\n",
1175 /* Convert PnP sting to ASCII */
1176 if (Buffer
[0] == 0x08)
1178 for (i
= 0; i
< Length
; i
++)
1183 DbgPrint((DPRINT_HWDETECT
,
1184 "PnP ID string: %s\n",
1187 /* Copy PnpId string */
1188 memcpy(&Identifier
[0],
1191 memcpy(&Identifier
[7],
1195 /* Skip device serial number */
1197 if (Buffer
[i
] == '\\')
1199 for (j
= ++i
; i
< Length
; ++i
)
1201 if (Buffer
[i
] == '\\')
1208 /* Skip PnP class */
1209 if (Buffer
[i
] == '\\')
1211 for (j
= ++i
; i
< Length
; ++i
)
1213 if (Buffer
[i
] == '\\')
1221 /* Skip compatible PnP Id */
1222 if (Buffer
[i
] == '\\')
1224 for (j
= ++i
; i
< Length
; ++i
)
1226 if (Buffer
[i
] == '\\')
1229 if (Buffer
[j
] == '*')
1235 /* Get product description */
1236 if (Buffer
[i
] == '\\')
1238 for (j
= ++i
; i
< Length
; ++i
)
1240 if (Buffer
[i
] == ';')
1247 memcpy(&Identifier
[10],
1250 Identifier
[10 + (i
-j
)] = 0;
1254 DbgPrint((DPRINT_HWDETECT
,
1255 "Identifier string: %s\n",
1259 if (Length
== 0 || strlen(Identifier
) < 11)
1263 case MOUSE_TYPE_LOGITECH
:
1265 "LOGITECH SERIAL MOUSE");
1268 case MOUSE_TYPE_WHEELZ
:
1270 "MICROSOFT SERIAL MOUSE WITH WHEEL");
1273 case MOUSE_TYPE_MICROSOFT
:
1276 "MICROSOFT SERIAL MOUSE");
1281 /* Create 'PointerPeripheral' key */
1282 Error
= RegCreateKey(ControllerKey
,
1283 "PointerPeripheral\\0",
1285 if (Error
!= ERROR_SUCCESS
)
1287 DbgPrint((DPRINT_HWDETECT
,
1288 "Failed to create peripheral key\n"));
1291 DbgPrint((DPRINT_HWDETECT
,
1292 "Created key: PointerPeripheral\\0\n"));
1294 /* Set 'ComponentInformation' value */
1295 SetComponentInformation(PeripheralKey
,
1300 /* Set 'Configuration Data' value */
1301 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1302 FullResourceDescriptor
.InterfaceType
= Isa
;
1303 FullResourceDescriptor
.BusNumber
= 0;
1304 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1306 Error
= RegSetValue(PeripheralKey
,
1307 "Configuration Data",
1308 REG_FULL_RESOURCE_DESCRIPTOR
,
1309 (PU8
)&FullResourceDescriptor
,
1310 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1311 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1312 if (Error
!= ERROR_SUCCESS
)
1314 DbgPrint((DPRINT_HWDETECT
,
1315 "RegSetValue(Configuration Data) failed (Error %u)\n",
1319 /* Set 'Identifier' value */
1320 Error
= RegSetValue(PeripheralKey
,
1324 strlen(Identifier
) + 1);
1325 if (Error
!= ERROR_SUCCESS
)
1327 DbgPrint((DPRINT_HWDETECT
,
1328 "RegSetValue() failed (Error %u)\n",
1336 DetectSerialPorts(HKEY BusKey
)
1338 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1339 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1340 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
1341 U32 Base
[4] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
1342 U32 Irq
[4] = {4, 3, 4, 3};
1344 U32 ControllerNumber
= 0;
1350 DbgPrint((DPRINT_HWDETECT
, "DetectSerialPorts()\n"));
1352 for (i
= 0; i
< 4; i
++)
1354 WRITE_PORT_UCHAR ((PUCHAR
)(Base
[i
] + 4), 0x10);
1355 if (!(READ_PORT_UCHAR((PUCHAR
)Base
[i
] + 6) & 0xf0))
1357 DbgPrint((DPRINT_HWDETECT
,
1358 "Found COM%u port at 0x%x\n",
1362 /* Create controller key */
1364 "SerialController\\%u",
1367 Error
= RegCreateKey(BusKey
,
1370 if (Error
!= ERROR_SUCCESS
)
1372 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1375 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
1377 /* Set 'ComponentInformation' value */
1378 SetComponentInformation(ControllerKey
,
1383 /* Build full device descriptor */
1384 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1385 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
1386 sizeof(CM_SERIAL_DEVICE_DATA
);
1387 FullResourceDescriptor
= MmAllocateMemory(Size
);
1388 if (FullResourceDescriptor
== NULL
)
1390 DbgPrint((DPRINT_HWDETECT
,
1391 "Failed to allocate resource descriptor\n"));
1394 memset(FullResourceDescriptor
, 0, Size
);
1396 /* Initialize resource descriptor */
1397 FullResourceDescriptor
->InterfaceType
= Isa
;
1398 FullResourceDescriptor
->BusNumber
= 0;
1399 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
1402 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1403 PartialDescriptor
->Type
= CmResourceTypePort
;
1404 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1405 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1406 PartialDescriptor
->u
.Port
.Start
= (U64
)Base
[i
];
1407 PartialDescriptor
->u
.Port
.Length
= 7;
1410 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
1411 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1412 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1413 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1414 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1415 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
1416 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1418 /* Set serial data (device specific) */
1419 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
1420 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1421 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1422 PartialDescriptor
->Flags
= 0;
1423 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
1426 (PCM_SERIAL_DEVICE_DATA
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[3];
1427 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
1429 /* Set 'Configuration Data' value */
1430 Error
= RegSetValue(ControllerKey
,
1431 "Configuration Data",
1432 REG_FULL_RESOURCE_DESCRIPTOR
,
1433 (PU8
) FullResourceDescriptor
,
1435 MmFreeMemory(FullResourceDescriptor
);
1436 if (Error
!= ERROR_SUCCESS
)
1438 DbgPrint((DPRINT_HWDETECT
,
1439 "RegSetValue(Configuration Data) failed (Error %u)\n",
1443 /* Set 'Identifier' value */
1447 Error
= RegSetValue(ControllerKey
,
1452 if (Error
!= ERROR_SUCCESS
)
1454 DbgPrint((DPRINT_HWDETECT
,
1455 "RegSetValue() failed (Error %u)\n",
1459 DbgPrint((DPRINT_HWDETECT
,
1460 "Created value: Identifier %s\n",
1463 /* Detect serial mouse */
1464 DetectSerialPointerPeripheral(ControllerKey
, Base
[i
]);
1473 DetectKeyboardDevice(VOID
)
1478 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1481 KeStallExecutionProcessor(10000);
1483 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1484 if ((Status
& 0x01) != 0x01)
1486 /* PC/XT keyboard or no keyboard */
1490 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1491 if (Scancode
!= 0xFA)
1493 /* No ACK received */
1497 KeStallExecutionProcessor(10000);
1498 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1499 if ((Status
& 0x01) != 0x01)
1501 /* Found AT keyboard */
1505 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1506 if (Scancode
!= 0xAB)
1508 /* No 0xAB received */
1512 KeStallExecutionProcessor(10000);
1513 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1514 if ((Status
& 0x01) != 0x01)
1516 /* No byte in buffer */
1520 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1521 if (Scancode
!= 0x41)
1523 /* No 0x41 received */
1527 /* Found MF-II keyboard */
1533 DetectKeyboardPeripheral(HKEY ControllerKey
)
1535 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1536 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1537 PCM_KEYBOARD_DEVICE_DATA KeyboardData
;
1543 if (DetectKeyboardDevice())
1545 /* Create controller key */
1546 Error
= RegCreateKey(ControllerKey
,
1547 "KeyboardPeripheral\\0",
1549 if (Error
!= ERROR_SUCCESS
)
1551 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
1554 DbgPrint((DPRINT_HWDETECT
, "Created key: KeyboardPeripheral\\0\n"));
1556 /* Set 'ComponentInformation' value */
1557 SetComponentInformation(ControllerKey
,
1562 /* Set 'Configuration Data' value */
1563 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1564 sizeof(CM_KEYBOARD_DEVICE_DATA
);
1565 FullResourceDescriptor
= MmAllocateMemory(Size
);
1566 if (FullResourceDescriptor
== NULL
)
1568 DbgPrint((DPRINT_HWDETECT
,
1569 "Failed to allocate resource descriptor\n"));
1573 /* Initialize resource descriptor */
1574 memset(FullResourceDescriptor
, 0, Size
);
1575 FullResourceDescriptor
->InterfaceType
= Isa
;
1576 FullResourceDescriptor
->BusNumber
= 0;
1577 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
1579 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1580 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1581 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1582 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_KEYBOARD_DEVICE_DATA
);
1584 KeyboardData
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
1585 KeyboardData
->Version
= 0;
1586 KeyboardData
->Revision
= 0;
1587 KeyboardData
->Type
= 4;
1588 KeyboardData
->Subtype
= 0;
1589 KeyboardData
->KeyboardFlags
= 0x20;
1591 /* Set 'Configuration Data' value */
1592 Error
= RegSetValue(PeripheralKey
,
1593 "Configuration Data",
1594 REG_FULL_RESOURCE_DESCRIPTOR
,
1595 (PU8
)FullResourceDescriptor
,
1597 MmFreeMemory(FullResourceDescriptor
);
1598 if (Error
!= ERROR_SUCCESS
)
1600 DbgPrint((DPRINT_HWDETECT
,
1601 "RegSetValue(Configuration Data) failed (Error %u)\n",
1605 /* Set 'Identifier' value */
1608 Error
= RegSetValue(ControllerKey
,
1612 strlen(Buffer
) + 1);
1613 if (Error
!= ERROR_SUCCESS
)
1615 DbgPrint((DPRINT_HWDETECT
,
1616 "RegSetValue() failed (Error %u)\n",
1624 DetectKeyboardController(HKEY BusKey
)
1626 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1627 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1632 /* Create controller key */
1633 Error
= RegCreateKey(BusKey
,
1634 "KeyboardController\\0",
1636 if (Error
!= ERROR_SUCCESS
)
1638 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1641 DbgPrint((DPRINT_HWDETECT
, "Created key: KeyboardController\\0\n"));
1643 /* Set 'ComponentInformation' value */
1644 SetComponentInformation(ControllerKey
,
1649 /* Set 'Configuration Data' value */
1650 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1651 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1652 FullResourceDescriptor
= MmAllocateMemory(Size
);
1653 if (FullResourceDescriptor
== NULL
)
1655 DbgPrint((DPRINT_HWDETECT
,
1656 "Failed to allocate resource descriptor\n"));
1660 /* Initialize resource descriptor */
1661 memset(FullResourceDescriptor
, 0, Size
);
1662 FullResourceDescriptor
->InterfaceType
= Isa
;
1663 FullResourceDescriptor
->BusNumber
= 0;
1664 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
1667 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1668 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1669 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1670 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1671 PartialDescriptor
->u
.Interrupt
.Level
= 1;
1672 PartialDescriptor
->u
.Interrupt
.Vector
= 1;
1673 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1675 /* Set IO Port 0x60 */
1676 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
1677 PartialDescriptor
->Type
= CmResourceTypePort
;
1678 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1679 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1680 PartialDescriptor
->u
.Port
.Start
= (U64
)0x60;
1681 PartialDescriptor
->u
.Port
.Length
= 1;
1683 /* Set IO Port 0x64 */
1684 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
1685 PartialDescriptor
->Type
= CmResourceTypePort
;
1686 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1687 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1688 PartialDescriptor
->u
.Port
.Start
= (U64
)0x64;
1689 PartialDescriptor
->u
.Port
.Length
= 1;
1691 /* Set 'Configuration Data' value */
1692 Error
= RegSetValue(ControllerKey
,
1693 "Configuration Data",
1694 REG_FULL_RESOURCE_DESCRIPTOR
,
1695 (PU8
)FullResourceDescriptor
,
1697 MmFreeMemory(FullResourceDescriptor
);
1698 if (Error
!= ERROR_SUCCESS
)
1700 DbgPrint((DPRINT_HWDETECT
,
1701 "RegSetValue(Configuration Data) failed (Error %u)\n",
1706 DetectKeyboardPeripheral(ControllerKey
);
1711 PS2ControllerWait(VOID
)
1716 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1718 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1719 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1722 /* Sleep for one millisecond */
1723 KeStallExecutionProcessor(1000);
1729 DetectPS2AuxPort(VOID
)
1735 /* Put the value 0x5A in the output buffer using the
1736 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1737 * Poll the Status Register for a while to see if the value really turns up
1738 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1739 * to 1 in the Status Register, we assume this controller has an
1740 * Auxiliary Port (a.k.a. Mouse Port).
1742 PS2ControllerWait();
1743 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1744 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1745 PS2ControllerWait();
1747 /* 0x5A is a random dummy value */
1748 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1751 for (Loops
= 0; Loops
< 10; Loops
++)
1753 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1755 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1757 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1758 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) != 0)
1765 KeStallExecutionProcessor(10000);
1773 DetectPS2AuxDevice(VOID
)
1778 PS2ControllerWait();
1779 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1780 CONTROLLER_COMMAND_WRITE_MOUSE
);
1781 PS2ControllerWait();
1783 /* Identify device */
1784 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1787 KeStallExecutionProcessor(10000);
1789 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1790 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1795 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1796 if (Scancode
!= 0xFA)
1799 KeStallExecutionProcessor(10000);
1801 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1802 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1807 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1808 if (Scancode
!= 0x00)
1816 DetectPS2Mouse(HKEY BusKey
)
1818 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1823 if (DetectPS2AuxPort())
1825 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 port\n"));
1827 /* Create controller key */
1828 Error
= RegCreateKey(BusKey
,
1829 "PointerController\\0",
1831 if (Error
!= ERROR_SUCCESS
)
1833 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1836 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerController\\0\n"));
1838 /* Set 'ComponentInformation' value */
1839 SetComponentInformation(ControllerKey
,
1844 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1846 /* Initialize resource descriptor */
1847 FullResourceDescriptor
.InterfaceType
= Isa
;
1848 FullResourceDescriptor
.BusNumber
= 0;
1849 FullResourceDescriptor
.PartialResourceList
.Count
= 1;
1852 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1853 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1854 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1855 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1856 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Vector
= 12;
1857 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1859 /* Set 'Configuration Data' value */
1860 Error
= RegSetValue(ControllerKey
,
1861 "Configuration Data",
1862 REG_FULL_RESOURCE_DESCRIPTOR
,
1863 (PU8
)&FullResourceDescriptor
,
1864 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1865 if (Error
!= ERROR_SUCCESS
)
1867 DbgPrint((DPRINT_HWDETECT
,
1868 "RegSetValue(Configuration Data) failed (Error %u)\n",
1874 if (DetectPS2AuxDevice())
1876 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 mouse\n"));
1878 /* Create peripheral key */
1879 Error
= RegCreateKey(ControllerKey
,
1880 "PointerPeripheral\\0",
1882 if (Error
!= ERROR_SUCCESS
)
1884 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
1887 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerPeripheral\\0\n"));
1889 /* Set 'ComponentInformation' value */
1890 SetComponentInformation(PeripheralKey
,
1895 /* Initialize resource descriptor */
1896 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1897 FullResourceDescriptor
.InterfaceType
= Isa
;
1898 FullResourceDescriptor
.BusNumber
= 0;
1899 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1901 /* Set 'Configuration Data' value */
1902 Error
= RegSetValue(PeripheralKey
,
1903 "Configuration Data",
1904 REG_FULL_RESOURCE_DESCRIPTOR
,
1905 (PU8
)&FullResourceDescriptor
,
1906 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1907 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1908 if (Error
!= ERROR_SUCCESS
)
1910 DbgPrint((DPRINT_HWDETECT
,
1911 "RegSetValue(Configuration Data) failed (Error %u)\n",
1916 /* Set 'Identifier' value */
1917 Error
= RegSetValue(PeripheralKey
,
1920 (PU8
)"MICROSOFT PS2 MOUSE",
1922 if (Error
!= ERROR_SUCCESS
)
1924 DbgPrint((DPRINT_HWDETECT
,
1925 "RegSetValue() failed (Error %u)\n",
1935 DetectDisplayController(HKEY BusKey
)
1942 Error
= RegCreateKey(BusKey
,
1943 "DisplayController\\0",
1945 if (Error
!= ERROR_SUCCESS
)
1947 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1950 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerController\\0\n"));
1952 /* Set 'ComponentInformation' value */
1953 SetComponentInformation(ControllerKey
,
1958 /* FIXME: Set 'ComponentInformation' value */
1960 VesaVersion
= BiosIsVesaSupported();
1961 if (VesaVersion
!= 0)
1963 DbgPrint((DPRINT_HWDETECT
,
1964 "VESA version %c.%c\n",
1965 (VesaVersion
>> 8) + '0',
1966 (VesaVersion
& 0xFF) + '0'));
1970 DbgPrint((DPRINT_HWDETECT
,
1971 "VESA not supported\n"));
1974 if (VesaVersion
>= 0x0200)
1985 /* Set 'Identifier' value */
1986 Error
= RegSetValue(ControllerKey
,
1990 strlen(Buffer
) + 1);
1991 if (Error
!= ERROR_SUCCESS
)
1993 DbgPrint((DPRINT_HWDETECT
,
1994 "RegSetValue() failed (Error %u)\n",
1999 /* FIXME: Add display peripheral (monitor) data */
2004 DetectIsaBios(HKEY SystemKey
, U32
*BusNumber
)
2006 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
2012 /* Create new bus key */
2014 "MultifunctionAdapter\\%u", *BusNumber
);
2015 Error
= RegCreateKey(SystemKey
,
2018 if (Error
!= ERROR_SUCCESS
)
2020 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
2024 /* Set 'Component Information' value similar to my NT4 box */
2025 SetComponentInformation(BusKey
,
2030 /* Increment bus number */
2033 /* Set 'Identifier' value */
2034 Error
= RegSetValue(BusKey
,
2039 if (Error
!= ERROR_SUCCESS
)
2041 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
2045 /* Set 'Configuration Data' value */
2046 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
2047 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
2048 FullResourceDescriptor
= MmAllocateMemory(Size
);
2049 if (FullResourceDescriptor
== NULL
)
2051 DbgPrint((DPRINT_HWDETECT
,
2052 "Failed to allocate resource descriptor\n"));
2056 /* Initialize resource descriptor */
2057 memset(FullResourceDescriptor
, 0, Size
);
2058 FullResourceDescriptor
->InterfaceType
= Isa
;
2059 FullResourceDescriptor
->BusNumber
= 0;
2060 FullResourceDescriptor
->PartialResourceList
.Count
= 0;
2062 /* Set 'Configuration Data' value */
2063 Error
= RegSetValue(BusKey
,
2064 "Configuration Data",
2065 REG_FULL_RESOURCE_DESCRIPTOR
,
2066 (PU8
) FullResourceDescriptor
,
2068 MmFreeMemory(FullResourceDescriptor
);
2069 if (Error
!= ERROR_SUCCESS
)
2071 DbgPrint((DPRINT_HWDETECT
,
2072 "RegSetValue(Configuration Data) failed (Error %u)\n",
2077 /* Detect ISA/BIOS devices */
2078 DetectBiosDisks(SystemKey
, BusKey
);
2080 DetectBiosFloppyController(SystemKey
, BusKey
);
2082 DetectSerialPorts(BusKey
);
2085 DetectParallelPorts(BusKey
);
2088 DetectKeyboardController(BusKey
);
2090 DetectPS2Mouse(BusKey
);
2092 DetectDisplayController(BusKey
);
2094 /* FIXME: Detect more ISA devices */
2099 DetectHardware(VOID
)
2105 DbgPrint((DPRINT_HWDETECT
, "DetectHardware()\n"));
2107 HalpCalibrateStallExecution ();
2109 /* Create the 'System' key */
2110 Error
= RegCreateKey(NULL
,
2111 "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
2113 if (Error
!= ERROR_SUCCESS
)
2115 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
2122 DetectCPUs(SystemKey
);
2126 DetectPciBios(&BusNumber
);
2127 DetectApmBios(&BusNumber
);
2129 DetectPnpBios(SystemKey
, &BusNumber
);
2130 DetectIsaBios(SystemKey
, &BusNumber
);
2132 DetectAcpiBios(&BusNumber
);
2136 DbgPrint((DPRINT_HWDETECT
, "DetectHardware() Done\n"));
2139 printf("*** System stopped ***\n");