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 #define CLOCK_TICK_RATE (1193182)
31 #define LATCH (CLOCK_TICK_RATE / HZ)
35 #define MOUSE_TYPE_NONE 0
36 /* Microsoft Mouse with 2 buttons */
37 #define MOUSE_TYPE_MICROSOFT 1
38 /* Logitech Mouse with 3 buttons */
39 #define MOUSE_TYPE_LOGITECH 2
40 /* Microsoft Wheel Mouse (aka Z Mouse) */
41 #define MOUSE_TYPE_WHEELZ 3
42 /* Mouse Systems Mouse */
43 #define MOUSE_TYPE_MOUSESYSTEMS 4
48 /* Controller registers. */
49 #define CONTROLLER_REGISTER_STATUS 0x64
50 #define CONTROLLER_REGISTER_CONTROL 0x64
51 #define CONTROLLER_REGISTER_DATA 0x60
53 /* Controller commands. */
54 #define CONTROLLER_COMMAND_READ_MODE 0x20
55 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
56 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
57 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
58 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
59 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
60 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
61 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
62 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
63 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
64 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
65 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
67 /* Controller status */
68 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
69 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
70 #define CONTROLLER_STATUS_SELF_TEST 0x04
71 #define CONTROLLER_STATUS_COMMAND 0x08
72 #define CONTROLLER_STATUS_UNLOCKED 0x10
73 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
74 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
75 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
76 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
77 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
79 /* Timeout in ms for sending to keyboard controller. */
80 #define CONTROLLER_TIMEOUT 250
82 static WCHAR Hex
[] = L
"0123456789ABCDEF";
83 static unsigned int delay_count
= 1;
85 extern ULONG reactos_disk_count
;
86 extern ARC_DISK_SIGNATURE reactos_arc_disk_info
[];
87 extern char reactos_arc_strings
[32][256];
89 /* FUNCTIONS ****************************************************************/
93 __StallExecutionProcessor(ULONG Loops
)
95 volatile register unsigned int i
;
96 for (i
= 0; i
< Loops
; i
++);
100 VOID
StallExecutionProcessor(ULONG Microseconds
)
102 ULONGLONG LoopCount
= ((ULONGLONG
)delay_count
* (ULONGLONG
)Microseconds
) / 1000ULL;
103 __StallExecutionProcessor((ULONG
)LoopCount
);
112 WRITE_PORT_UCHAR((PUCHAR
)0x43, 0x00);
113 Count
= READ_PORT_UCHAR((PUCHAR
)0x40);
114 Count
|= READ_PORT_UCHAR((PUCHAR
)0x40) << 8;
121 WaitFor8254Wraparound(VOID
)
124 ULONG PrevCount
= ~0;
127 CurCount
= Read8254Timer();
131 PrevCount
= CurCount
;
132 CurCount
= Read8254Timer();
133 Delta
= CurCount
- PrevCount
;
136 * This limit for delta seems arbitrary, but it isn't, it's
137 * slightly above the level of error a buggy Mercury/Neptune
138 * chipset timer can cause.
146 HalpCalibrateStallExecution(VOID
)
152 /* Initialise timer interrupt with MILLISECOND ms interval */
153 WRITE_PORT_UCHAR((PUCHAR
)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
154 WRITE_PORT_UCHAR((PUCHAR
)0x40, LATCH
& 0xff); /* LSB */
155 WRITE_PORT_UCHAR((PUCHAR
)0x40, LATCH
>> 8); /* MSB */
157 /* Stage 1: Coarse calibration */
159 WaitFor8254Wraparound();
164 delay_count
<<= 1; /* Next delay count to try */
166 WaitFor8254Wraparound();
168 __StallExecutionProcessor(delay_count
); /* Do the delay */
170 CurCount
= Read8254Timer();
171 } while (CurCount
> LATCH
/ 2);
173 delay_count
>>= 1; /* Get bottom value for delay */
175 /* Stage 2: Fine calibration */
177 calib_bit
= delay_count
; /* Which bit are we going to test */
179 for(i
=0;i
<PRECISION
;i
++) {
180 calib_bit
>>= 1; /* Next bit to calibrate */
181 if(!calib_bit
) break; /* If we have done all bits, stop */
183 delay_count
|= calib_bit
; /* Set the bit in delay_count */
185 WaitFor8254Wraparound();
187 __StallExecutionProcessor(delay_count
); /* Do the delay */
189 CurCount
= Read8254Timer();
190 if (CurCount
<= LATCH
/ 2) /* If a tick has passed, turn the */
191 delay_count
&= ~calib_bit
; /* calibrated bit back off */
194 /* We're finished: Do the finishing touches */
195 delay_count
/= (MILLISEC
/ 2); /* Calculate delay_count for 1ms */
199 DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
201 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
202 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
203 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
204 PCONFIGURATION_COMPONENT_DATA BusKey
;
209 ULONG FoundNodeCount
;
215 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
216 if (InstData
== NULL
|| strncmp((CHAR
*)InstData
->Signature
, "$PnP", 4))
218 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS not supported\n"));
221 DbgPrint((DPRINT_HWDETECT
, "Signature '%c%c%c%c'\n",
222 InstData
->Signature
[0], InstData
->Signature
[1],
223 InstData
->Signature
[2], InstData
->Signature
[3]));
226 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
227 NodeCount
&= 0xFF; // needed since some fscked up BIOSes return
228 // wrong info (e.g. Mac Virtual PC)
229 // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
230 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
232 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS failed to enumerate device nodes\n"));
235 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS supported\n"));
236 DbgPrint((DPRINT_HWDETECT
, "MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
));
237 DbgPrint((DPRINT_HWDETECT
, "Estimated buffer size %u\n", NodeSize
* NodeCount
));
239 /* Create component key */
240 FldrCreateComponentKey(SystemKey
,
241 L
"MultifunctionAdapter",
244 MultiFunctionAdapter
,
248 /* Set the component information */
249 FldrSetComponentInformation(BusKey
,
254 /* Set the identifier */
255 FldrSetIdentifier(BusKey
, L
"PNP BIOS");
257 /* Set 'Configuration Data' value */
258 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) + (NodeSize
* NodeCount
);
259 PartialResourceList
= MmHeapAlloc(Size
);
260 if (PartialResourceList
== NULL
)
262 DbgPrint((DPRINT_HWDETECT
,
263 "Failed to allocate resource descriptor\n"));
266 memset(PartialResourceList
, 0, Size
);
268 /* Initialize resource descriptor */
269 PartialResourceList
->Version
= 1;
270 PartialResourceList
->Revision
= 1;
271 PartialResourceList
->Count
= 1;
272 PartialResourceList
->PartialDescriptors
[0].Type
=
273 CmResourceTypeDeviceSpecific
;
274 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
=
275 CmResourceShareUndetermined
;
277 Ptr
= (char *)(((ULONG_PTR
)&PartialResourceList
->PartialDescriptors
[0]) +
278 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
280 /* Set instalation check data */
281 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
282 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
284 /* Copy device nodes */
286 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
287 for (i
= 0; i
< 0xFF; i
++)
289 NodeNumber
= (UCHAR
)i
;
291 x
= PnpBiosGetDeviceNode(&NodeNumber
, (PVOID
)DISKREADBUFFER
);
294 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DISKREADBUFFER
;
296 DbgPrint((DPRINT_HWDETECT
,
297 "Node: %u Size %u (0x%x)\n",
306 Ptr
+= DeviceNode
->Size
;
307 PnpBufferSize
+= DeviceNode
->Size
;
310 if (FoundNodeCount
>= NodeCount
)
315 /* Set real data size */
316 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
318 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) + PnpBufferSize
;
320 DbgPrint((DPRINT_HWDETECT
, "Real buffer size: %u\n", PnpBufferSize
));
321 DbgPrint((DPRINT_HWDETECT
, "Resource size: %u\n", Size
));
323 FldrSetConfigurationData(BusKey
, PartialResourceList
, Size
);
324 MmHeapFree(PartialResourceList
);
330 SetHarddiskConfigurationData(PCONFIGURATION_COMPONENT_DATA DiskKey
,
333 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
334 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
335 EXTENDED_GEOMETRY ExtGeometry
;
339 /* Set 'Configuration Data' value */
340 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
341 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
342 PartialResourceList
= MmHeapAlloc(Size
);
343 if (PartialResourceList
== NULL
)
345 DbgPrint((DPRINT_HWDETECT
,
346 "Failed to allocate a full resource descriptor\n"));
350 memset(PartialResourceList
, 0, Size
);
351 PartialResourceList
->Version
= 1;
352 PartialResourceList
->Revision
= 1;
353 PartialResourceList
->Count
= 1;
354 PartialResourceList
->PartialDescriptors
[0].Type
=
355 CmResourceTypeDeviceSpecific
;
356 // PartialResourceList->PartialDescriptors[0].ShareDisposition =
357 // PartialResourceList->PartialDescriptors[0].Flags =
358 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
359 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
361 /* Get pointer to geometry data */
362 DiskGeometry
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
364 /* Get the disk geometry */
365 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
366 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
368 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
369 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
370 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
371 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
373 else if(MachDiskGetDriveGeometry(DriveNumber
, &Geometry
))
375 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
376 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
377 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
378 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
382 DbgPrint((DPRINT_HWDETECT
, "Reading disk geometry failed\n"));
383 MmHeapFree(PartialResourceList
);
386 DbgPrint((DPRINT_HWDETECT
,
387 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
389 DiskGeometry
->NumberOfCylinders
,
390 DiskGeometry
->NumberOfHeads
,
391 DiskGeometry
->SectorsPerTrack
,
392 DiskGeometry
->BytesPerSector
));
394 FldrSetConfigurationData(DiskKey
, PartialResourceList
, Size
);
395 MmHeapFree(PartialResourceList
);
400 SetHarddiskIdentifier(PCONFIGURATION_COMPONENT_DATA DiskKey
,
403 PMASTER_BOOT_RECORD Mbr
;
408 WCHAR Identifier
[20];
412 if (!MachDiskReadLogicalSectors(DriveNumber
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
414 DbgPrint((DPRINT_HWDETECT
, "Reading MBR failed\n"));
418 Buffer
= (ULONG
*)DISKREADBUFFER
;
419 Mbr
= (PMASTER_BOOT_RECORD
)DISKREADBUFFER
;
421 Signature
= Mbr
->Signature
;
422 DbgPrint((DPRINT_HWDETECT
, "Signature: %x\n", Signature
));
424 /* Calculate the MBR checksum */
426 for (i
= 0; i
< 128; i
++)
428 Checksum
+= Buffer
[i
];
430 Checksum
= ~Checksum
+ 1;
431 DbgPrint((DPRINT_HWDETECT
, "Checksum: %x\n", Checksum
));
433 /* Fill out the ARC disk block */
434 reactos_arc_disk_info
[reactos_disk_count
].Signature
= Signature
;
435 reactos_arc_disk_info
[reactos_disk_count
].CheckSum
= Checksum
;
436 sprintf(ArcName
, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count
);
437 strcpy(reactos_arc_strings
[reactos_disk_count
], ArcName
);
438 reactos_arc_disk_info
[reactos_disk_count
].ArcName
=
439 reactos_arc_strings
[reactos_disk_count
];
440 reactos_disk_count
++;
442 /* Convert checksum and signature to identifier string */
443 Identifier
[0] = Hex
[(Checksum
>> 28) & 0x0F];
444 Identifier
[1] = Hex
[(Checksum
>> 24) & 0x0F];
445 Identifier
[2] = Hex
[(Checksum
>> 20) & 0x0F];
446 Identifier
[3] = Hex
[(Checksum
>> 16) & 0x0F];
447 Identifier
[4] = Hex
[(Checksum
>> 12) & 0x0F];
448 Identifier
[5] = Hex
[(Checksum
>> 8) & 0x0F];
449 Identifier
[6] = Hex
[(Checksum
>> 4) & 0x0F];
450 Identifier
[7] = Hex
[Checksum
& 0x0F];
451 Identifier
[8] = L
'-';
452 Identifier
[9] = Hex
[(Signature
>> 28) & 0x0F];
453 Identifier
[10] = Hex
[(Signature
>> 24) & 0x0F];
454 Identifier
[11] = Hex
[(Signature
>> 20) & 0x0F];
455 Identifier
[12] = Hex
[(Signature
>> 16) & 0x0F];
456 Identifier
[13] = Hex
[(Signature
>> 12) & 0x0F];
457 Identifier
[14] = Hex
[(Signature
>> 8) & 0x0F];
458 Identifier
[15] = Hex
[(Signature
>> 4) & 0x0F];
459 Identifier
[16] = Hex
[Signature
& 0x0F];
460 Identifier
[17] = L
'-';
461 Identifier
[18] = L
'A';
463 DbgPrint((DPRINT_HWDETECT
, "Identifier: %S\n", Identifier
));
466 FldrSetIdentifier(DiskKey
, Identifier
);
474 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
475 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
477 return ((Data
& 0xF0) ? 1 : 0) + ((Data
& 0x0F) ? 1 : 0);
482 GetFloppyType(UCHAR DriveNumber
)
486 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
487 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
489 if (DriveNumber
== 0)
491 else if (DriveNumber
== 1)
501 PUSHORT SegPtr
= (PUSHORT
)0x7A;
502 PUSHORT OfsPtr
= (PUSHORT
)0x78;
504 return (PVOID
)((ULONG_PTR
)(((ULONG
)(*SegPtr
)) << 4) + (ULONG
)(*OfsPtr
));
509 DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
)
511 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
512 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
513 PCM_FLOPPY_DEVICE_DATA FloppyData
;
514 WCHAR Identifier
[20];
515 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
519 ULONG MaxDensity
[6] = {0, 360, 1200, 720, 1440, 2880};
522 for (FloppyNumber
= 0; FloppyNumber
< 2; FloppyNumber
++)
524 FloppyType
= GetFloppyType(FloppyNumber
);
526 if ((FloppyType
> 5) || (FloppyType
== 0))
529 DiskResetController(FloppyNumber
);
531 Ptr
= GetInt1eTable();
533 FldrCreateComponentKey(ControllerKey
,
534 L
"FloppyDiskPeripheral",
537 FloppyDiskPeripheral
,
540 /* Set 'ComponentInformation' value */
541 FldrSetComponentInformation(PeripheralKey
,
546 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
547 sizeof(CM_FLOPPY_DEVICE_DATA
);
548 PartialResourceList
= MmHeapAlloc(Size
);
549 if (PartialResourceList
== NULL
)
551 DbgPrint((DPRINT_HWDETECT
,
552 "Failed to allocate resource descriptor\n"));
556 memset(PartialResourceList
, 0, Size
);
557 PartialResourceList
->Version
= 1;
558 PartialResourceList
->Revision
= 1;
559 PartialResourceList
->Count
= 1;
561 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
562 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
563 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
564 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_FLOPPY_DEVICE_DATA
);
566 FloppyData
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
567 FloppyData
->Version
= 2;
568 FloppyData
->Revision
= 0;
569 FloppyData
->MaxDensity
= MaxDensity
[FloppyType
];
570 FloppyData
->MountDensity
= 0;
571 RtlCopyMemory(&FloppyData
->StepRateHeadUnloadTime
,
574 FloppyData
->MaximumTrackValue
= (FloppyType
== 1) ? 39 : 79;
575 FloppyData
->DataTransferRate
= 0;
577 /* Set 'Configuration Data' value */
578 FldrSetConfigurationData(PeripheralKey
, PartialResourceList
, Size
);
579 MmHeapFree(PartialResourceList
);
581 /* Set 'Identifier' value */
582 swprintf(Identifier
, L
"FLOPPY%u", FloppyNumber
+ 1);
583 FldrSetIdentifier(PeripheralKey
, Identifier
);
589 DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey
,
590 PCONFIGURATION_COMPONENT_DATA ControllerKey
)
592 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
593 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
597 FloppyCount
= GetFloppyCount();
598 DbgPrint((DPRINT_HWDETECT
,
599 "Floppy count: %u\n",
602 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
603 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
604 PartialResourceList
= MmHeapAlloc(Size
);
605 if (PartialResourceList
== NULL
)
607 DbgPrint((DPRINT_HWDETECT
,
608 "Failed to allocate resource descriptor\n"));
611 memset(PartialResourceList
, 0, Size
);
613 /* Initialize resource descriptor */
614 PartialResourceList
->Version
= 1;
615 PartialResourceList
->Revision
= 1;
616 PartialResourceList
->Count
= 3;
619 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
620 PartialDescriptor
->Type
= CmResourceTypePort
;
621 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
622 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
623 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x03F0;
624 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
625 PartialDescriptor
->u
.Port
.Length
= 8;
628 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
629 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
630 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
631 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
632 PartialDescriptor
->u
.Interrupt
.Level
= 6;
633 PartialDescriptor
->u
.Interrupt
.Vector
= 6;
634 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
636 /* Set DMA channel */
637 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
638 PartialDescriptor
->Type
= CmResourceTypeDma
;
639 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
640 PartialDescriptor
->Flags
= 0;
641 PartialDescriptor
->u
.Dma
.Channel
= 2;
642 PartialDescriptor
->u
.Dma
.Port
= 0;
644 /* Set 'Configuration Data' value */
645 FldrSetConfigurationData(ControllerKey
, PartialResourceList
, Size
);
646 MmHeapFree(PartialResourceList
);
648 if (FloppyCount
) DetectBiosFloppyPeripheral(ControllerKey
);
652 DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey
,
653 PCONFIGURATION_COMPONENT_DATA BusKey
)
655 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
656 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
658 PCONFIGURATION_COMPONENT_DATA DiskKey
, ControllerKey
;
664 /* Count the number of visible drives */
665 DiskReportError(FALSE
);
668 /* There are some really broken BIOSes out there. There are even BIOSes
669 * that happily report success when you ask them to read from non-existent
670 * harddisks. So, we set the buffer to known contents first, then try to
671 * read. If the BIOS reports success but the buffer contents haven't
672 * changed then we fail anyway */
673 memset((PVOID
) DISKREADBUFFER
, 0xcd, 512);
674 while (MachDiskReadLogicalSectors(0x80 + DiskCount
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
677 for (i
= 0; ! Changed
&& i
< 512; i
++)
679 Changed
= ((PUCHAR
)DISKREADBUFFER
)[i
] != 0xcd;
683 DbgPrint((DPRINT_HWDETECT
, "BIOS reports success for disk %d but data didn't change\n",
688 memset((PVOID
) DISKREADBUFFER
, 0xcd, 512);
690 DiskReportError(TRUE
);
691 DbgPrint((DPRINT_HWDETECT
, "BIOS reports %d harddisk%s\n",
692 (int)DiskCount
, (DiskCount
== 1) ? "": "s"));
694 FldrCreateComponentKey(BusKey
,
700 DbgPrint((DPRINT_HWDETECT
, "Created key: DiskController\\0\n"));
702 /* Set 'ComponentInformation' value */
703 FldrSetComponentInformation(ControllerKey
,
704 Output
| Input
| Removable
,
708 DetectBiosFloppyController(BusKey
, ControllerKey
);
710 /* Allocate resource descriptor */
711 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
712 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
713 PartialResourceList
= MmHeapAlloc(Size
);
714 if (PartialResourceList
== NULL
)
716 DbgPrint((DPRINT_HWDETECT
,
717 "Failed to allocate resource descriptor\n"));
721 /* Initialize resource descriptor */
722 memset(PartialResourceList
, 0, Size
);
723 PartialResourceList
->Version
= 1;
724 PartialResourceList
->Revision
= 1;
725 PartialResourceList
->Count
= 1;
726 PartialResourceList
->PartialDescriptors
[0].Type
= CmResourceTypeDeviceSpecific
;
727 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
= 0;
728 PartialResourceList
->PartialDescriptors
[0].Flags
= 0;
729 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
730 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
732 /* Get harddisk Int13 geometry data */
733 Int13Drives
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
734 for (i
= 0; i
< DiskCount
; i
++)
736 if (MachDiskGetDriveGeometry(0x80 + i
, &Geometry
))
738 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
739 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
740 Int13Drives
[i
].SectorsPerTrack
= Geometry
.Sectors
;
741 Int13Drives
[i
].MaxHeads
= Geometry
.Heads
- 1;
742 Int13Drives
[i
].NumberDrives
= DiskCount
;
744 DbgPrint((DPRINT_HWDETECT
,
745 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
747 Geometry
.Cylinders
- 1,
750 Geometry
.BytesPerSector
));
754 /* Set 'Configuration Data' value */
755 FldrSetConfigurationData(SystemKey
, PartialResourceList
, Size
);
756 MmHeapFree(PartialResourceList
);
758 /* Create and fill subkey for each harddisk */
759 for (i
= 0; i
< DiskCount
; i
++)
761 /* Create disk key */
762 FldrCreateComponentKey(ControllerKey
,
769 /* Set 'ComponentInformation' value */
770 FldrSetComponentInformation(DiskKey
,
775 /* Set disk values */
776 SetHarddiskConfigurationData(DiskKey
, 0x80 + i
);
777 SetHarddiskIdentifier(DiskKey
, 0x80 + i
);
782 InitializeSerialPort(ULONG Port
,
785 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, 0x80); /* set DLAB on */
786 WRITE_PORT_UCHAR((PUCHAR
)Port
, 0x60); /* speed LO byte */
787 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* speed HI byte */
788 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, LineControl
);
789 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* set comm and DLAB to 0 */
790 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09); /* DR int enable */
791 READ_PORT_UCHAR((PUCHAR
)Port
+ 5); /* clear error bits */
796 DetectSerialMouse(ULONG Port
)
803 /* Shutdown mouse or something like that */
804 LineControl
= READ_PORT_UCHAR((PUCHAR
)Port
+ 4);
805 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, (LineControl
& ~0x02) | 0x01);
806 StallExecutionProcessor(100000);
810 * Maybe there is no serial port although BIOS reported one (this
811 * is the case on Apple hardware), or the serial port is misbehaving,
812 * therefore we must give up after some time.
815 while (READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 0x01)
818 return MOUSE_TYPE_NONE
;
819 READ_PORT_UCHAR((PUCHAR
)Port
);
823 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
824 * 'Output Line 2' message. This enables mouse to identify.
826 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
828 /* Wait 10 milliseconds for the mouse getting ready */
829 StallExecutionProcessor(10000);
831 /* Read first four bytes, which contains Microsoft Mouse signs */
833 for (i
= 0; i
< 4; i
++)
835 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
837 StallExecutionProcessor(1000);
840 return MOUSE_TYPE_NONE
;
842 Buffer
[i
] = READ_PORT_UCHAR((PUCHAR
)Port
);
845 DbgPrint((DPRINT_HWDETECT
,
846 "Mouse data: %x %x %x %x\n",
847 Buffer
[0],Buffer
[1],Buffer
[2],Buffer
[3]));
849 /* Check that four bytes for signs */
850 for (i
= 0; i
< 4; ++i
)
852 if (Buffer
[i
] == 'B')
854 /* Sign for Microsoft Ballpoint */
855 // DbgPrint("Microsoft Ballpoint device detected\n");
856 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
857 return MOUSE_TYPE_NONE
;
859 else if (Buffer
[i
] == 'M')
861 /* Sign for Microsoft Mouse protocol followed by button specifier */
865 return MOUSE_TYPE_NONE
;
868 switch (Buffer
[i
+ 1])
871 DbgPrint((DPRINT_HWDETECT
,
872 "Microsoft Mouse with 3-buttons detected\n"));
873 return MOUSE_TYPE_LOGITECH
;
876 DbgPrint((DPRINT_HWDETECT
,
877 "Microsoft Wheel Mouse detected\n"));
878 return MOUSE_TYPE_WHEELZ
;
882 DbgPrint((DPRINT_HWDETECT
,
883 "Microsoft Mouse with 2-buttons detected\n"));
884 return MOUSE_TYPE_MICROSOFT
;
889 return MOUSE_TYPE_NONE
;
894 GetSerialMousePnpId(ULONG Port
, char *Buffer
)
901 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09);
903 /* Wait 10 milliseconds for the mouse getting ready */
904 StallExecutionProcessor(10000);
906 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
908 StallExecutionProcessor(10000);
913 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
915 StallExecutionProcessor(1000);
923 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
924 if (c
== 0x08 || c
== 0x28)
934 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
936 StallExecutionProcessor(1000);
941 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
954 DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
,
957 CM_PARTIAL_RESOURCE_LIST PartialResourceList
;
959 WCHAR Identifier
[256];
960 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
967 DbgPrint((DPRINT_HWDETECT
,
968 "DetectSerialPointerPeripheral()\n"));
972 InitializeSerialPort(Base
, 2);
973 MouseType
= DetectSerialMouse(Base
);
975 if (MouseType
!= MOUSE_TYPE_NONE
)
977 Length
= GetSerialMousePnpId(Base
, Buffer
);
978 DbgPrint((DPRINT_HWDETECT
,
979 "PnP ID length: %u\n",
984 /* Convert PnP sting to ASCII */
985 if (Buffer
[0] == 0x08)
987 for (i
= 0; i
< Length
; i
++)
992 DbgPrint((DPRINT_HWDETECT
,
993 "PnP ID string: %s\n",
996 /* Copy PnpId string */
997 for (i
= 0; i
< 7; i
++)
999 Identifier
[i
] = Buffer
[3+i
];
1001 memcpy(&Identifier
[7],
1005 /* Skip device serial number */
1007 if (Buffer
[i
] == '\\')
1009 for (j
= ++i
; i
< Length
; ++i
)
1011 if (Buffer
[i
] == '\\')
1018 /* Skip PnP class */
1019 if (Buffer
[i
] == '\\')
1021 for (j
= ++i
; i
< Length
; ++i
)
1023 if (Buffer
[i
] == '\\')
1031 /* Skip compatible PnP Id */
1032 if (Buffer
[i
] == '\\')
1034 for (j
= ++i
; i
< Length
; ++i
)
1036 if (Buffer
[i
] == '\\')
1039 if (Buffer
[j
] == '*')
1045 /* Get product description */
1046 if (Buffer
[i
] == '\\')
1048 for (j
= ++i
; i
< Length
; ++i
)
1050 if (Buffer
[i
] == ';')
1057 for (k
= 0; k
< i
- j
; k
++)
1059 Identifier
[k
+ 10] = Buffer
[k
+ j
];
1061 Identifier
[10 + (i
-j
)] = 0;
1065 DbgPrint((DPRINT_HWDETECT
,
1066 "Identifier string: %S\n",
1070 if (Length
== 0 || wcslen(Identifier
) < 11)
1074 case MOUSE_TYPE_LOGITECH
:
1076 L
"LOGITECH SERIAL MOUSE");
1079 case MOUSE_TYPE_WHEELZ
:
1081 L
"MICROSOFT SERIAL MOUSE WITH WHEEL");
1084 case MOUSE_TYPE_MICROSOFT
:
1087 L
"MICROSOFT SERIAL MOUSE");
1092 /* Create 'PointerPeripheral' key */
1093 FldrCreateComponentKey(ControllerKey
,
1094 L
"PointerPeripheral",
1099 DbgPrint((DPRINT_HWDETECT
,
1100 "Created key: PointerPeripheral\\0\n"));
1102 /* Set 'ComponentInformation' value */
1103 FldrSetComponentInformation(PeripheralKey
,
1108 /* Set 'Configuration Data' value */
1109 memset(&PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1110 PartialResourceList
.Version
= 1;
1111 PartialResourceList
.Revision
= 1;
1112 PartialResourceList
.Count
= 0;
1114 FldrSetConfigurationData(PeripheralKey
,
1115 &PartialResourceList
,
1116 sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1117 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1119 /* Set 'Identifier' value */
1120 FldrSetIdentifier(PeripheralKey
, Identifier
);
1126 DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey
)
1128 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1129 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1130 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
1131 ULONG Irq
[4] = {4, 3, 4, 3};
1135 ULONG ControllerNumber
= 0;
1136 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1140 DbgPrint((DPRINT_HWDETECT
, "DetectSerialPorts()\n"));
1142 ControllerNumber
= 0;
1143 BasePtr
= (PUSHORT
)0x400;
1144 for (i
= 0; i
< 4; i
++, BasePtr
++)
1146 Base
= (ULONG
)*BasePtr
;
1150 DbgPrint((DPRINT_HWDETECT
,
1151 "Found COM%u port at 0x%x\n",
1155 /* Create controller key */
1156 FldrCreateComponentKey(BusKey
,
1157 L
"SerialController",
1163 /* Set 'ComponentInformation' value */
1164 FldrSetComponentInformation(ControllerKey
,
1165 Output
| Input
| ConsoleIn
| ConsoleOut
,
1169 /* Build full device descriptor */
1170 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
1171 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
1172 sizeof(CM_SERIAL_DEVICE_DATA
);
1173 PartialResourceList
= MmHeapAlloc(Size
);
1174 if (PartialResourceList
== NULL
)
1176 DbgPrint((DPRINT_HWDETECT
,
1177 "Failed to allocate resource descriptor\n"));
1180 memset(PartialResourceList
, 0, Size
);
1182 /* Initialize resource descriptor */
1183 PartialResourceList
->Version
= 1;
1184 PartialResourceList
->Revision
= 1;
1185 PartialResourceList
->Count
= 3;
1188 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1189 PartialDescriptor
->Type
= CmResourceTypePort
;
1190 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1191 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1192 PartialDescriptor
->u
.Port
.Start
.LowPart
= Base
;
1193 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1194 PartialDescriptor
->u
.Port
.Length
= 7;
1197 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1198 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1199 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1200 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1201 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1202 PartialDescriptor
->u
.Interrupt
.Vector
= 0;
1203 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1205 /* Set serial data (device specific) */
1206 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
1207 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1208 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1209 PartialDescriptor
->Flags
= 0;
1210 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
1213 (PCM_SERIAL_DEVICE_DATA
)&PartialResourceList
->PartialDescriptors
[3];
1214 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
1216 /* Set 'Configuration Data' value */
1217 FldrSetConfigurationData(ControllerKey
, PartialResourceList
, Size
);
1218 MmHeapFree(PartialResourceList
);
1220 /* Set 'Identifier' value */
1221 swprintf(Buffer
, L
"COM%u", i
+ 1);
1222 FldrSetIdentifier(ControllerKey
, Buffer
);
1223 DbgPrint((DPRINT_HWDETECT
,
1224 "Created value: Identifier %s\n",
1227 if (!Rs232PortInUse(Base
))
1229 /* Detect serial mouse */
1230 DetectSerialPointerPeripheral(ControllerKey
, Base
);
1239 DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey
)
1241 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1242 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1243 ULONG Irq
[3] = {7, 5, (ULONG
)-1};
1245 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1248 ULONG ControllerNumber
;
1252 DbgPrint((DPRINT_HWDETECT
, "DetectParallelPorts() called\n"));
1254 ControllerNumber
= 0;
1255 BasePtr
= (PUSHORT
)0x408;
1256 for (i
= 0; i
< 3; i
++, BasePtr
++)
1258 Base
= (ULONG
)*BasePtr
;
1262 DbgPrint((DPRINT_HWDETECT
,
1263 "Parallel port %u: %x\n",
1267 /* Create controller key */
1268 FldrCreateComponentKey(BusKey
,
1269 L
"ParallelController",
1275 /* Set 'ComponentInformation' value */
1276 FldrSetComponentInformation(ControllerKey
,
1281 /* Build full device descriptor */
1282 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
);
1283 if (Irq
[i
] != (ULONG
)-1)
1284 Size
+= sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1286 PartialResourceList
= MmHeapAlloc(Size
);
1287 if (PartialResourceList
== NULL
)
1289 DbgPrint((DPRINT_HWDETECT
,
1290 "Failed to allocate resource descriptor\n"));
1293 memset(PartialResourceList
, 0, Size
);
1295 /* Initialize resource descriptor */
1296 PartialResourceList
->Version
= 1;
1297 PartialResourceList
->Revision
= 1;
1298 PartialResourceList
->Count
= (Irq
[i
] != (ULONG
)-1) ? 2 : 1;
1301 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1302 PartialDescriptor
->Type
= CmResourceTypePort
;
1303 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1304 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1305 PartialDescriptor
->u
.Port
.Start
.LowPart
= Base
;
1306 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1307 PartialDescriptor
->u
.Port
.Length
= 3;
1310 if (Irq
[i
] != (ULONG
)-1)
1312 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1313 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1314 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1315 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1316 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1317 PartialDescriptor
->u
.Interrupt
.Vector
= 0;
1318 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1321 /* Set 'Configuration Data' value */
1322 FldrSetConfigurationData(ControllerKey
, PartialResourceList
, Size
);
1323 MmHeapFree(PartialResourceList
);
1325 /* Set 'Identifier' value */
1326 swprintf(Buffer
, L
"PARALLEL%u", i
+ 1);
1327 FldrSetIdentifier(ControllerKey
, Buffer
);
1328 DbgPrint((DPRINT_HWDETECT
,
1329 "Created value: Identifier %s\n",
1335 DbgPrint((DPRINT_HWDETECT
, "DetectParallelPorts() done\n"));
1340 DetectKeyboardDevice(VOID
)
1345 BOOLEAN Result
= TRUE
;
1347 /* Identify device */
1348 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1351 /* Wait for reply */
1352 for (Loops
= 0; Loops
< 100; Loops
++)
1354 StallExecutionProcessor(10000);
1355 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1356 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1360 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
1362 /* PC/XT keyboard or no keyboard */
1366 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1367 if (Scancode
!= 0xFA)
1369 /* No ACK received */
1373 StallExecutionProcessor(10000);
1375 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1376 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
1378 /* Found AT keyboard */
1382 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1383 if (Scancode
!= 0xAB)
1385 /* No 0xAB received */
1389 StallExecutionProcessor(10000);
1391 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1392 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
1394 /* No byte in buffer */
1398 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1399 if (Scancode
!= 0x41)
1401 /* No 0x41 received */
1405 /* Found MF-II keyboard */
1411 DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
)
1413 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1414 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1415 PCM_KEYBOARD_DEVICE_DATA KeyboardData
;
1416 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
1419 /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2 */
1420 if (TRUE
|| DetectKeyboardDevice())
1422 /* Create controller key */
1423 FldrCreateComponentKey(ControllerKey
,
1424 L
"KeyboardPeripheral",
1429 DbgPrint((DPRINT_HWDETECT
, "Created key: KeyboardPeripheral\\0\n"));
1431 /* Set 'ComponentInformation' value */
1432 FldrSetComponentInformation(PeripheralKey
,
1437 /* Set 'Configuration Data' value */
1438 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
1439 sizeof(CM_KEYBOARD_DEVICE_DATA
);
1440 PartialResourceList
= MmHeapAlloc(Size
);
1441 if (PartialResourceList
== NULL
)
1443 DbgPrint((DPRINT_HWDETECT
,
1444 "Failed to allocate resource descriptor\n"));
1448 /* Initialize resource descriptor */
1449 memset(PartialResourceList
, 0, Size
);
1450 PartialResourceList
->Version
= 1;
1451 PartialResourceList
->Revision
= 1;
1452 PartialResourceList
->Count
= 1;
1454 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1455 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1456 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1457 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_KEYBOARD_DEVICE_DATA
);
1459 KeyboardData
= (PCM_KEYBOARD_DEVICE_DATA
)(PartialDescriptor
+ 1);
1460 KeyboardData
->Version
= 1;
1461 KeyboardData
->Revision
= 1;
1462 KeyboardData
->Type
= 4;
1463 KeyboardData
->Subtype
= 0;
1464 KeyboardData
->KeyboardFlags
= 0x20;
1466 /* Set 'Configuration Data' value */
1467 FldrSetConfigurationData(PeripheralKey
, PartialResourceList
, Size
);
1468 MmHeapFree(PartialResourceList
);
1470 /* Set 'Identifier' value */
1471 FldrSetIdentifier(PeripheralKey
, L
"PCAT_ENHANCED");
1477 DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey
)
1479 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1480 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1481 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1484 /* Create controller key */
1485 FldrCreateComponentKey(BusKey
,
1486 L
"KeyboardController",
1491 DbgPrint((DPRINT_HWDETECT
, "Created key: KeyboardController\\0\n"));
1493 /* Set 'ComponentInformation' value */
1494 FldrSetComponentInformation(ControllerKey
,
1499 /* Set 'Configuration Data' value */
1500 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
1501 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1502 PartialResourceList
= MmHeapAlloc(Size
);
1503 if (PartialResourceList
== NULL
)
1505 DbgPrint((DPRINT_HWDETECT
,
1506 "Failed to allocate resource descriptor\n"));
1510 /* Initialize resource descriptor */
1511 memset(PartialResourceList
, 0, Size
);
1512 PartialResourceList
->Version
= 1;
1513 PartialResourceList
->Revision
= 1;
1514 PartialResourceList
->Count
= 3;
1517 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1518 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1519 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1520 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1521 PartialDescriptor
->u
.Interrupt
.Level
= 1;
1522 PartialDescriptor
->u
.Interrupt
.Vector
= 0;
1523 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1525 /* Set IO Port 0x60 */
1526 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1527 PartialDescriptor
->Type
= CmResourceTypePort
;
1528 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1529 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1530 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x60;
1531 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1532 PartialDescriptor
->u
.Port
.Length
= 1;
1534 /* Set IO Port 0x64 */
1535 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
1536 PartialDescriptor
->Type
= CmResourceTypePort
;
1537 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1538 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1539 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x64;
1540 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1541 PartialDescriptor
->u
.Port
.Length
= 1;
1543 /* Set 'Configuration Data' value */
1544 FldrSetConfigurationData(ControllerKey
, PartialResourceList
, Size
);
1545 MmHeapFree(PartialResourceList
);
1547 DetectKeyboardPeripheral(ControllerKey
);
1552 PS2ControllerWait(VOID
)
1557 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1559 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1560 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1563 /* Sleep for one millisecond */
1564 StallExecutionProcessor(1000);
1570 DetectPS2AuxPort(VOID
)
1573 /* Current detection is too unreliable. Just do as if
1574 * the PS/2 aux port is always present
1581 /* Put the value 0x5A in the output buffer using the
1582 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1583 * Poll the Status Register for a while to see if the value really turns up
1584 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1585 * to 1 in the Status Register, we assume this controller has an
1586 * Auxiliary Port (a.k.a. Mouse Port).
1588 PS2ControllerWait();
1589 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1590 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1591 PS2ControllerWait();
1593 /* 0x5A is a random dummy value */
1594 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1597 for (Loops
= 0; Loops
< 10; Loops
++)
1599 StallExecutionProcessor(10000);
1600 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1601 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1605 READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1607 return (Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
);
1613 DetectPS2AuxDevice(VOID
)
1618 BOOLEAN Result
= TRUE
;
1620 PS2ControllerWait();
1621 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1622 CONTROLLER_COMMAND_WRITE_MOUSE
);
1623 PS2ControllerWait();
1625 /* Identify device */
1626 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1629 /* Wait for reply */
1630 for (Loops
= 0; Loops
< 100; Loops
++)
1632 StallExecutionProcessor(10000);
1633 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1634 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1638 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1639 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1642 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1643 if (Scancode
!= 0xFA)
1646 StallExecutionProcessor(10000);
1648 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1649 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1652 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1653 if (Scancode
!= 0x00)
1661 DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey
)
1663 CM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1664 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1665 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
1667 if (DetectPS2AuxPort())
1669 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 port\n"));
1671 /* Create controller key */
1672 FldrCreateComponentKey(BusKey
,
1673 L
"PointerController",
1678 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerController\\0\n"));
1680 /* Set 'ComponentInformation' value */
1681 FldrSetComponentInformation(ControllerKey
,
1686 memset(&PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1688 /* Initialize resource descriptor */
1689 PartialResourceList
.Version
= 1;
1690 PartialResourceList
.Revision
= 1;
1691 PartialResourceList
.Count
= 1;
1694 PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1695 PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1696 PartialResourceList
.PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1697 PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1698 PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Vector
= 0;
1699 PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1701 /* Set 'Configuration Data' value */
1702 FldrSetConfigurationData(ControllerKey
,
1703 &PartialResourceList
,
1704 sizeof(CM_PARTIAL_RESOURCE_LIST
));
1706 if (DetectPS2AuxDevice())
1708 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 mouse\n"));
1710 /* Create peripheral key */
1711 FldrCreateComponentKey(ControllerKey
,
1712 L
"PointerPeripheral",
1717 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerPeripheral\\0\n"));
1719 /* Set 'ComponentInformation' value */
1720 FldrSetComponentInformation(PeripheralKey
,
1725 /* Initialize resource descriptor */
1726 memset(&PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1727 PartialResourceList
.Version
= 1;
1728 PartialResourceList
.Revision
= 1;
1729 PartialResourceList
.Count
= 0;
1731 /* Set 'Configuration Data' value */
1732 FldrSetConfigurationData(PeripheralKey
,
1733 &PartialResourceList
,
1734 sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1735 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1737 /* Set 'Identifier' value */
1738 FldrSetIdentifier(PeripheralKey
, L
"MICROSOFT PS2 MOUSE");
1745 DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey
)
1748 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1751 FldrCreateComponentKey(BusKey
,
1752 L
"DisplayController",
1757 DbgPrint((DPRINT_HWDETECT
, "Created key: DisplayController\\0\n"));
1759 /* Set 'ComponentInformation' value */
1760 FldrSetComponentInformation(ControllerKey
,
1765 /* FIXME: Set 'ComponentInformation' value */
1767 VesaVersion
= BiosIsVesaSupported();
1768 if (VesaVersion
!= 0)
1770 DbgPrint((DPRINT_HWDETECT
,
1771 "VESA version %c.%c\n",
1772 (VesaVersion
>> 8) + '0',
1773 (VesaVersion
& 0xFF) + '0'));
1777 DbgPrint((DPRINT_HWDETECT
,
1778 "VESA not supported\n"));
1781 if (VesaVersion
>= 0x0200)
1792 /* Set 'Identifier' value */
1793 FldrSetIdentifier(ControllerKey
, Buffer
);
1795 /* FIXME: Add display peripheral (monitor) data */
1800 DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
1802 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1803 PCONFIGURATION_COMPONENT_DATA BusKey
;
1806 /* Create new bus key */
1807 FldrCreateComponentKey(SystemKey
,
1808 L
"MultifunctionAdapter",
1811 MultiFunctionAdapter
,
1814 /* Set 'Component Information' value similar to my NT4 box */
1815 FldrSetComponentInformation(BusKey
,
1820 /* Increment bus number */
1823 /* Set 'Identifier' value */
1824 FldrSetIdentifier(BusKey
, L
"ISA");
1826 /* Set 'Configuration Data' value */
1827 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1828 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1829 PartialResourceList
= MmHeapAlloc(Size
);
1830 if (PartialResourceList
== NULL
)
1832 DbgPrint((DPRINT_HWDETECT
,
1833 "Failed to allocate resource descriptor\n"));
1837 /* Initialize resource descriptor */
1838 memset(PartialResourceList
, 0, Size
);
1839 PartialResourceList
->Version
= 1;
1840 PartialResourceList
->Revision
= 1;
1841 PartialResourceList
->Count
= 0;
1843 /* Set 'Configuration Data' value */
1844 FldrSetConfigurationData(BusKey
, PartialResourceList
, Size
);
1845 MmHeapFree(PartialResourceList
);
1847 /* Detect ISA/BIOS devices */
1848 DetectBiosDisks(SystemKey
, BusKey
);
1850 DetectSerialPorts(BusKey
);
1852 DetectParallelPorts(BusKey
);
1854 DetectKeyboardController(BusKey
);
1856 DetectPS2Mouse(BusKey
);
1858 DetectDisplayController(BusKey
);
1860 /* FIXME: Detect more ISA devices */
1864 PCONFIGURATION_COMPONENT_DATA
1867 PCONFIGURATION_COMPONENT_DATA SystemKey
;
1868 ULONG BusNumber
= 0;
1870 DbgPrint((DPRINT_HWDETECT
, "DetectHardware()\n"));
1872 /* Create the 'System' key */
1873 FldrCreateSystemKey(&SystemKey
);
1875 /* Set empty component information */
1876 FldrSetComponentInformation(SystemKey
,
1882 DetectPciBios(SystemKey
, &BusNumber
);
1883 DetectApmBios(SystemKey
, &BusNumber
);
1884 DetectPnpBios(SystemKey
, &BusNumber
);
1885 DetectIsaBios(SystemKey
, &BusNumber
);
1886 DetectAcpiBios(SystemKey
, &BusNumber
);
1888 DbgPrint((DPRINT_HWDETECT
, "DetectHardware() Done\n"));