4 * Copyright (C) 2003, 2004 Eric Kohl
5 * Copyright (C) 2009 Hervé Poussineau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #define CLOCK_TICK_RATE (1193182)
32 #define LATCH (CLOCK_TICK_RATE / HZ)
36 #define MOUSE_TYPE_NONE 0
37 /* Microsoft Mouse with 2 buttons */
38 #define MOUSE_TYPE_MICROSOFT 1
39 /* Logitech Mouse with 3 buttons */
40 #define MOUSE_TYPE_LOGITECH 2
41 /* Microsoft Wheel Mouse (aka Z Mouse) */
42 #define MOUSE_TYPE_WHEELZ 3
43 /* Mouse Systems Mouse */
44 #define MOUSE_TYPE_MOUSESYSTEMS 4
49 /* Controller registers. */
50 #define CONTROLLER_REGISTER_STATUS 0x64
51 #define CONTROLLER_REGISTER_CONTROL 0x64
52 #define CONTROLLER_REGISTER_DATA 0x60
54 /* Controller commands. */
55 #define CONTROLLER_COMMAND_READ_MODE 0x20
56 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
57 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
58 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
59 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
60 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
61 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
62 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
63 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
64 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
65 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
66 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
68 /* Controller status */
69 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
70 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
71 #define CONTROLLER_STATUS_SELF_TEST 0x04
72 #define CONTROLLER_STATUS_COMMAND 0x08
73 #define CONTROLLER_STATUS_UNLOCKED 0x10
74 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
75 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
76 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
77 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
78 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
80 /* Timeout in ms for sending to keyboard controller. */
81 #define CONTROLLER_TIMEOUT 250
83 DBG_DEFAULT_CHANNEL(HWDETECT
);
85 static unsigned int delay_count
= 1;
87 extern UCHAR PcBiosDiskCount
;
90 GetHarddiskIdentifier(
94 HwInitializeBiosDisks(VOID
);
96 /* FUNCTIONS ****************************************************************/
100 __StallExecutionProcessor(ULONG Loops
)
102 register volatile unsigned int i
;
103 for (i
= 0; i
< Loops
; i
++);
107 VOID
StallExecutionProcessor(ULONG Microseconds
)
109 ULONGLONG LoopCount
= ((ULONGLONG
)delay_count
* (ULONGLONG
)Microseconds
) / 1000ULL;
110 __StallExecutionProcessor((ULONG
)LoopCount
);
119 WRITE_PORT_UCHAR((PUCHAR
)0x43, 0x00);
120 Count
= READ_PORT_UCHAR((PUCHAR
)0x40);
121 Count
|= READ_PORT_UCHAR((PUCHAR
)0x40) << 8;
128 WaitFor8254Wraparound(VOID
)
131 ULONG PrevCount
= ~0;
134 CurCount
= Read8254Timer();
138 PrevCount
= CurCount
;
139 CurCount
= Read8254Timer();
140 Delta
= CurCount
- PrevCount
;
143 * This limit for delta seems arbitrary, but it isn't, it's
144 * slightly above the level of error a buggy Mercury/Neptune
145 * chipset timer can cause.
153 HalpCalibrateStallExecution(VOID
)
159 /* Initialise timer interrupt with MILLISECOND ms interval */
160 WRITE_PORT_UCHAR((PUCHAR
)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
161 WRITE_PORT_UCHAR((PUCHAR
)0x40, LATCH
& 0xff); /* LSB */
162 WRITE_PORT_UCHAR((PUCHAR
)0x40, LATCH
>> 8); /* MSB */
164 /* Stage 1: Coarse calibration */
166 WaitFor8254Wraparound();
171 delay_count
<<= 1; /* Next delay count to try */
173 WaitFor8254Wraparound();
175 __StallExecutionProcessor(delay_count
); /* Do the delay */
177 CurCount
= Read8254Timer();
178 } while (CurCount
> LATCH
/ 2);
180 delay_count
>>= 1; /* Get bottom value for delay */
182 /* Stage 2: Fine calibration */
184 calib_bit
= delay_count
; /* Which bit are we going to test */
186 for(i
=0;i
<PRECISION
;i
++) {
187 calib_bit
>>= 1; /* Next bit to calibrate */
188 if(!calib_bit
) break; /* If we have done all bits, stop */
190 delay_count
|= calib_bit
; /* Set the bit in delay_count */
192 WaitFor8254Wraparound();
194 __StallExecutionProcessor(delay_count
); /* Do the delay */
196 CurCount
= Read8254Timer();
197 if (CurCount
<= LATCH
/ 2) /* If a tick has passed, turn the */
198 delay_count
&= ~calib_bit
; /* calibrated bit back off */
201 /* We're finished: Do the finishing touches */
202 delay_count
/= (MILLISEC
/ 2); /* Calculate delay_count for 1ms */
206 DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
208 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
209 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
210 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
211 PCONFIGURATION_COMPONENT_DATA BusKey
;
216 ULONG FoundNodeCount
;
222 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
223 if (InstData
== NULL
|| strncmp((CHAR
*)InstData
->Signature
, "$PnP", 4))
225 TRACE("PnP-BIOS not supported\n");
229 TRACE("PnP-BIOS supported\n");
230 TRACE("Signature '%c%c%c%c'\n",
231 InstData
->Signature
[0], InstData
->Signature
[1],
232 InstData
->Signature
[2], InstData
->Signature
[3]);
234 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
237 TRACE("PnP-BIOS function 'Get Number of System Device Nodes' not supported\n");
241 NodeCount
&= 0xFF; // needed since some fscked up BIOSes return
242 // wrong info (e.g. Mac Virtual PC)
243 // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
244 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
246 ERR("PnP-BIOS failed to enumerate device nodes\n");
249 TRACE("MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
);
250 TRACE("Estimated buffer size %u\n", NodeSize
* NodeCount
);
252 /* Set 'Configuration Data' value */
253 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
)
254 + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
) + (NodeSize
* NodeCount
);
255 PartialResourceList
= MmHeapAlloc(Size
);
256 if (PartialResourceList
== NULL
)
258 ERR("Failed to allocate resource descriptor\n");
261 memset(PartialResourceList
, 0, Size
);
263 /* Initialize resource descriptor */
264 PartialResourceList
->Version
= 1;
265 PartialResourceList
->Revision
= 1;
266 PartialResourceList
->Count
= 1;
267 PartialResourceList
->PartialDescriptors
[0].Type
=
268 CmResourceTypeDeviceSpecific
;
269 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
=
270 CmResourceShareUndetermined
;
272 /* The buffer starts after PartialResourceList->PartialDescriptors[0] */
273 Ptr
= (char *)(PartialResourceList
+ 1);
275 /* Set instalation check data */
276 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
277 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
279 /* Copy device nodes */
281 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
282 for (i
= 0; i
< 0xFF; i
++)
284 NodeNumber
= (UCHAR
)i
;
286 x
= PnpBiosGetDeviceNode(&NodeNumber
, (PVOID
)DISKREADBUFFER
);
289 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DISKREADBUFFER
;
291 TRACE("Node: %u Size %u (0x%x)\n",
296 if (PnpBufferSize
+ DeviceNode
->Size
> Size
)
298 ERR("Buffer too small!\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 TRACE("Real buffer size: %u\n", PnpBufferSize
);
321 TRACE("Resource size: %u\n", Size
);
323 /* Create component key */
324 FldrCreateComponentKey(SystemKey
,
326 MultiFunctionAdapter
,
337 MmHeapFree(PartialResourceList
);
342 static PCM_PARTIAL_RESOURCE_LIST
343 GetHarddiskConfigurationData(UCHAR DriveNumber
, ULONG
* pSize
)
345 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
346 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
347 EXTENDED_GEOMETRY ExtGeometry
;
352 // Initialize returned size
356 /* Set 'Configuration Data' value */
357 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
358 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
359 PartialResourceList
= MmHeapAlloc(Size
);
360 if (PartialResourceList
== NULL
)
362 ERR("Failed to allocate a full resource descriptor\n");
366 memset(PartialResourceList
, 0, Size
);
367 PartialResourceList
->Version
= 1;
368 PartialResourceList
->Revision
= 1;
369 PartialResourceList
->Count
= 1;
370 PartialResourceList
->PartialDescriptors
[0].Type
=
371 CmResourceTypeDeviceSpecific
;
372 // PartialResourceList->PartialDescriptors[0].ShareDisposition =
373 // PartialResourceList->PartialDescriptors[0].Flags =
374 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
375 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
377 /* Get pointer to geometry data */
378 DiskGeometry
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
380 /* Get the disk geometry */
381 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
382 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
384 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
385 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
386 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
387 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
389 else if(MachDiskGetDriveGeometry(DriveNumber
, &Geometry
))
391 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
392 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
393 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
394 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
398 TRACE("Reading disk geometry failed\n");
399 MmHeapFree(PartialResourceList
);
402 TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
404 DiskGeometry
->NumberOfCylinders
,
405 DiskGeometry
->NumberOfHeads
,
406 DiskGeometry
->SectorsPerTrack
,
407 DiskGeometry
->BytesPerSector
);
410 // Return configuration data
413 return PartialResourceList
;
421 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
422 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
424 return ((Data
& 0xF0) ? 1 : 0) + ((Data
& 0x0F) ? 1 : 0);
429 GetFloppyType(UCHAR DriveNumber
)
433 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
434 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
436 if (DriveNumber
== 0)
438 else if (DriveNumber
== 1)
448 PUSHORT SegPtr
= (PUSHORT
)0x7A;
449 PUSHORT OfsPtr
= (PUSHORT
)0x78;
451 return (PVOID
)((ULONG_PTR
)(((ULONG
)(*SegPtr
)) << 4) + (ULONG
)(*OfsPtr
));
456 DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
)
458 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
459 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
460 PCM_FLOPPY_DEVICE_DATA FloppyData
;
462 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
466 ULONG MaxDensity
[6] = {0, 360, 1200, 720, 1440, 2880};
469 for (FloppyNumber
= 0; FloppyNumber
< 2; FloppyNumber
++)
471 FloppyType
= GetFloppyType(FloppyNumber
);
473 if ((FloppyType
> 5) || (FloppyType
== 0))
476 if (!DiskResetController(FloppyNumber
))
479 Ptr
= GetInt1eTable();
481 /* Set 'Identifier' value */
482 sprintf(Identifier
, "FLOPPY%d", FloppyNumber
+ 1);
484 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
485 sizeof(CM_FLOPPY_DEVICE_DATA
);
486 PartialResourceList
= MmHeapAlloc(Size
);
487 if (PartialResourceList
== NULL
)
489 ERR("Failed to allocate resource descriptor\n");
493 memset(PartialResourceList
, 0, Size
);
494 PartialResourceList
->Version
= 1;
495 PartialResourceList
->Revision
= 1;
496 PartialResourceList
->Count
= 1;
498 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
499 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
500 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
501 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_FLOPPY_DEVICE_DATA
);
503 FloppyData
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
504 FloppyData
->Version
= 2;
505 FloppyData
->Revision
= 0;
506 FloppyData
->MaxDensity
= MaxDensity
[FloppyType
];
507 FloppyData
->MountDensity
= 0;
508 RtlCopyMemory(&FloppyData
->StepRateHeadUnloadTime
,
511 FloppyData
->MaximumTrackValue
= (FloppyType
== 1) ? 39 : 79;
512 FloppyData
->DataTransferRate
= 0;
514 FldrCreateComponentKey(ControllerKey
,
516 FloppyDiskPeripheral
,
525 MmHeapFree(PartialResourceList
);
531 DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey
)
533 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
534 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
535 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
539 FloppyCount
= GetFloppyCount();
540 TRACE("Floppy count: %u\n",
543 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
544 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
545 PartialResourceList
= MmHeapAlloc(Size
);
546 if (PartialResourceList
== NULL
)
548 ERR("Failed to allocate resource descriptor\n");
551 memset(PartialResourceList
, 0, Size
);
553 /* Initialize resource descriptor */
554 PartialResourceList
->Version
= 1;
555 PartialResourceList
->Revision
= 1;
556 PartialResourceList
->Count
= 3;
559 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
560 PartialDescriptor
->Type
= CmResourceTypePort
;
561 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
562 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
563 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x03F0;
564 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
565 PartialDescriptor
->u
.Port
.Length
= 8;
568 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
569 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
570 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
571 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
572 PartialDescriptor
->u
.Interrupt
.Level
= 6;
573 PartialDescriptor
->u
.Interrupt
.Vector
= 6;
574 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
576 /* Set DMA channel */
577 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
578 PartialDescriptor
->Type
= CmResourceTypeDma
;
579 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
580 PartialDescriptor
->Flags
= 0;
581 PartialDescriptor
->u
.Dma
.Channel
= 2;
582 PartialDescriptor
->u
.Dma
.Port
= 0;
584 /* Create floppy disk controller */
585 FldrCreateComponentKey(BusKey
,
595 TRACE("Created key: DiskController\\0\n");
597 MmHeapFree(PartialResourceList
);
599 if (FloppyCount
) DetectBiosFloppyPeripheral(ControllerKey
);
602 static PCONFIGURATION_COMPONENT_DATA
605 PCONFIGURATION_COMPONENT_DATA SystemKey
;
606 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
607 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
613 DiskCount
= PcBiosDiskCount
;
615 /* Allocate resource descriptor */
616 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
617 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
618 PartialResourceList
= MmHeapAlloc(Size
);
619 if (PartialResourceList
== NULL
)
621 ERR("Failed to allocate resource descriptor\n");
625 /* Initialize resource descriptor */
626 memset(PartialResourceList
, 0, Size
);
627 PartialResourceList
->Version
= 1;
628 PartialResourceList
->Revision
= 1;
629 PartialResourceList
->Count
= 1;
630 PartialResourceList
->PartialDescriptors
[0].Type
= CmResourceTypeDeviceSpecific
;
631 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
= 0;
632 PartialResourceList
->PartialDescriptors
[0].Flags
= 0;
633 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
634 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
636 /* Get harddisk Int13 geometry data */
637 Int13Drives
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
638 for (i
= 0; i
< DiskCount
; i
++)
640 if (MachDiskGetDriveGeometry(0x80 + i
, &Geometry
))
642 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
643 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
644 Int13Drives
[i
].SectorsPerTrack
= (USHORT
)Geometry
.Sectors
;
645 Int13Drives
[i
].MaxHeads
= (USHORT
)Geometry
.Heads
- 1;
646 Int13Drives
[i
].NumberDrives
= DiskCount
;
648 TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
650 Geometry
.Cylinders
- 1,
653 Geometry
.BytesPerSector
);
657 FldrCreateComponentKey(NULL
,
668 MmHeapFree(PartialResourceList
);
674 DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey
)
676 PCONFIGURATION_COMPONENT_DATA DiskKey
, ControllerKey
;
679 FldrCreateComponentKey(BusKey
,
689 TRACE("Created key: DiskController\\0\n");
691 /* Create and fill subkey for each harddisk */
692 for (i
= 0; i
< PcBiosDiskCount
; i
++)
694 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
697 UCHAR DriveNumber
= 0x80 + (UCHAR
)i
;
699 /* Get disk values */
700 PartialResourceList
= GetHarddiskConfigurationData(DriveNumber
, &Size
);
701 Identifier
= GetHarddiskIdentifier(DriveNumber
);
703 /* Create disk key */
704 FldrCreateComponentKey(ControllerKey
,
719 InitializeSerialPort(PUCHAR Port
,
722 WRITE_PORT_UCHAR(Port
+ 3, 0x80); /* set DLAB on */
723 WRITE_PORT_UCHAR(Port
, 0x60); /* speed LO byte */
724 WRITE_PORT_UCHAR(Port
+ 1, 0); /* speed HI byte */
725 WRITE_PORT_UCHAR(Port
+ 3, LineControl
);
726 WRITE_PORT_UCHAR(Port
+ 1, 0); /* set comm and DLAB to 0 */
727 WRITE_PORT_UCHAR(Port
+ 4, 0x09); /* DR int enable */
728 READ_PORT_UCHAR(Port
+ 5); /* clear error bits */
733 DetectSerialMouse(PUCHAR Port
)
740 /* Shutdown mouse or something like that */
741 LineControl
= READ_PORT_UCHAR(Port
+ 4);
742 WRITE_PORT_UCHAR(Port
+ 4, (LineControl
& ~0x02) | 0x01);
743 StallExecutionProcessor(100000);
747 * Maybe there is no serial port although BIOS reported one (this
748 * is the case on Apple hardware), or the serial port is misbehaving,
749 * therefore we must give up after some time.
752 while (READ_PORT_UCHAR(Port
+ 5) & 0x01)
755 return MOUSE_TYPE_NONE
;
756 READ_PORT_UCHAR(Port
);
760 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
761 * 'Output Line 2' message. This enables mouse to identify.
763 WRITE_PORT_UCHAR(Port
+ 4, 0x0b);
765 /* Wait 10 milliseconds for the mouse getting ready */
766 StallExecutionProcessor(10000);
768 /* Read first four bytes, which contains Microsoft Mouse signs */
770 for (i
= 0; i
< 4; i
++)
772 while (((READ_PORT_UCHAR(Port
+ 5) & 1) == 0) && (TimeOut
> 0))
774 StallExecutionProcessor(1000);
777 return MOUSE_TYPE_NONE
;
779 Buffer
[i
] = READ_PORT_UCHAR(Port
);
782 TRACE("Mouse data: %x %x %x %x\n",
783 Buffer
[0],Buffer
[1],Buffer
[2],Buffer
[3]);
785 /* Check that four bytes for signs */
786 for (i
= 0; i
< 4; ++i
)
788 if (Buffer
[i
] == 'B')
790 /* Sign for Microsoft Ballpoint */
791 // DbgPrint("Microsoft Ballpoint device detected\n");
792 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
793 return MOUSE_TYPE_NONE
;
795 else if (Buffer
[i
] == 'M')
797 /* Sign for Microsoft Mouse protocol followed by button specifier */
801 return MOUSE_TYPE_NONE
;
804 switch (Buffer
[i
+ 1])
807 TRACE("Microsoft Mouse with 3-buttons detected\n");
808 return MOUSE_TYPE_LOGITECH
;
811 TRACE("Microsoft Wheel Mouse detected\n");
812 return MOUSE_TYPE_WHEELZ
;
816 TRACE("Microsoft Mouse with 2-buttons detected\n");
817 return MOUSE_TYPE_MICROSOFT
;
822 return MOUSE_TYPE_NONE
;
827 GetSerialMousePnpId(PUCHAR Port
, char *Buffer
)
834 WRITE_PORT_UCHAR(Port
+ 4, 0x09);
836 /* Wait 10 milliseconds for the mouse getting ready */
837 StallExecutionProcessor(10000);
839 WRITE_PORT_UCHAR(Port
+ 4, 0x0b);
841 StallExecutionProcessor(10000);
846 while (((READ_PORT_UCHAR(Port
+ 5) & 1) == 0) && (TimeOut
> 0))
848 StallExecutionProcessor(1000);
856 c
= READ_PORT_UCHAR(Port
);
857 if (c
== 0x08 || c
== 0x28)
867 while (((READ_PORT_UCHAR(Port
+ 5) & 1) == 0) && (TimeOut
> 0))
869 StallExecutionProcessor(1000);
874 c
= READ_PORT_UCHAR(Port
);
887 DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
,
890 CM_PARTIAL_RESOURCE_LIST PartialResourceList
;
892 CHAR Identifier
[256];
893 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
900 TRACE("DetectSerialPointerPeripheral()\n");
904 InitializeSerialPort(Base
, 2);
905 MouseType
= DetectSerialMouse(Base
);
907 if (MouseType
!= MOUSE_TYPE_NONE
)
909 Length
= GetSerialMousePnpId(Base
, Buffer
);
910 TRACE( "PnP ID length: %u\n", Length
);
914 /* Convert PnP sting to ASCII */
915 if (Buffer
[0] == 0x08)
917 for (i
= 0; i
< Length
; i
++)
922 TRACE("PnP ID string: %s\n", Buffer
);
924 /* Copy PnpId string */
925 for (i
= 0; i
< 7; i
++)
927 Identifier
[i
] = Buffer
[3+i
];
929 memcpy(&Identifier
[7],
933 /* Skip device serial number */
935 if (Buffer
[i
] == '\\')
937 for (j
= ++i
; i
< Length
; ++i
)
939 if (Buffer
[i
] == '\\')
947 if (Buffer
[i
] == '\\')
949 for (j
= ++i
; i
< Length
; ++i
)
951 if (Buffer
[i
] == '\\')
959 /* Skip compatible PnP Id */
960 if (Buffer
[i
] == '\\')
962 for (j
= ++i
; i
< Length
; ++i
)
964 if (Buffer
[i
] == '\\')
967 if (Buffer
[j
] == '*')
973 /* Get product description */
974 if (Buffer
[i
] == '\\')
976 for (j
= ++i
; i
< Length
; ++i
)
978 if (Buffer
[i
] == ';')
985 for (k
= 0; k
< i
- j
; k
++)
987 Identifier
[k
+ 10] = Buffer
[k
+ j
];
989 Identifier
[10 + (i
-j
)] = 0;
993 TRACE("Identifier string: %s\n", Identifier
);
996 if (Length
== 0 || strlen(Identifier
) < 11)
1000 case MOUSE_TYPE_LOGITECH
:
1001 strcpy(Identifier
, "LOGITECH SERIAL MOUSE");
1004 case MOUSE_TYPE_WHEELZ
:
1005 strcpy(Identifier
, "MICROSOFT SERIAL MOUSE WITH WHEEL");
1008 case MOUSE_TYPE_MICROSOFT
:
1010 strcpy(Identifier
, "MICROSOFT SERIAL MOUSE");
1015 /* Set 'Configuration Data' value */
1016 memset(&PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1017 PartialResourceList
.Version
= 1;
1018 PartialResourceList
.Revision
= 1;
1019 PartialResourceList
.Count
= 0;
1021 /* Create 'PointerPeripheral' key */
1022 FldrCreateComponentKey(ControllerKey
,
1029 &PartialResourceList
,
1030 sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1031 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
),
1034 TRACE("Created key: PointerPeripheral\\0\n");
1040 DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey
)
1042 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1043 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1044 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
1045 ULONG Irq
[4] = {4, 3, 4, 3};
1049 ULONG ControllerNumber
= 0;
1050 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1054 TRACE("DetectSerialPorts()\n");
1056 ControllerNumber
= 0;
1057 BasePtr
= (PUSHORT
)0x400;
1058 for (i
= 0; i
< 2; i
++, BasePtr
++)
1060 Base
= (ULONG
)*BasePtr
;
1064 TRACE("Found COM%u port at 0x%x\n", i
+ 1, Base
);
1066 /* Set 'Identifier' value */
1067 sprintf(Buffer
, "COM%ld", i
+ 1);
1069 /* Build full device descriptor */
1070 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
1071 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
1072 sizeof(CM_SERIAL_DEVICE_DATA
);
1073 PartialResourceList
= MmHeapAlloc(Size
);
1074 if (PartialResourceList
== NULL
)
1076 ERR("Failed to allocate resource descriptor\n");
1079 memset(PartialResourceList
, 0, Size
);
1081 /* Initialize resource descriptor */
1082 PartialResourceList
->Version
= 1;
1083 PartialResourceList
->Revision
= 1;
1084 PartialResourceList
->Count
= 3;
1087 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1088 PartialDescriptor
->Type
= CmResourceTypePort
;
1089 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1090 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1091 PartialDescriptor
->u
.Port
.Start
.LowPart
= Base
;
1092 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1093 PartialDescriptor
->u
.Port
.Length
= 7;
1096 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1097 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1098 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1099 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1100 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1101 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
1102 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1104 /* Set serial data (device specific) */
1105 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
1106 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1107 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1108 PartialDescriptor
->Flags
= 0;
1109 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
1112 (PCM_SERIAL_DEVICE_DATA
)&PartialResourceList
->PartialDescriptors
[3];
1113 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
1115 /* Create controller key */
1116 FldrCreateComponentKey(BusKey
,
1119 Output
| Input
| ConsoleIn
| ConsoleOut
,
1123 PartialResourceList
,
1127 MmHeapFree(PartialResourceList
);
1129 if (!Rs232PortInUse(Base
))
1131 /* Detect serial mouse */
1132 DetectSerialPointerPeripheral(ControllerKey
, UlongToPtr(Base
));
1141 DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey
)
1143 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1144 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1145 ULONG Irq
[3] = {7, 5, (ULONG
)-1};
1147 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1150 ULONG ControllerNumber
;
1154 TRACE("DetectParallelPorts() called\n");
1156 ControllerNumber
= 0;
1157 BasePtr
= (PUSHORT
)0x408;
1158 for (i
= 0; i
< 3; i
++, BasePtr
++)
1160 Base
= (ULONG
)*BasePtr
;
1164 TRACE("Parallel port %u: %x\n", ControllerNumber
, Base
);
1166 /* Set 'Identifier' value */
1167 sprintf(Buffer
, "PARALLEL%ld", i
+ 1);
1169 /* Build full device descriptor */
1170 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
);
1171 if (Irq
[i
] != (ULONG
)-1)
1172 Size
+= sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1174 PartialResourceList
= MmHeapAlloc(Size
);
1175 if (PartialResourceList
== NULL
)
1177 ERR("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
= (Irq
[i
] != (ULONG
)-1) ? 2 : 1;
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
= 3;
1197 if (Irq
[i
] != (ULONG
)-1)
1199 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1200 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1201 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1202 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1203 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1204 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
1205 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1208 /* Create controller key */
1209 FldrCreateComponentKey(BusKey
,
1216 PartialResourceList
,
1220 MmHeapFree(PartialResourceList
);
1225 TRACE("DetectParallelPorts() done\n");
1230 DetectKeyboardDevice(VOID
)
1235 BOOLEAN Result
= TRUE
;
1237 /* Identify device */
1238 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1241 /* Wait for reply */
1242 for (Loops
= 0; Loops
< 100; Loops
++)
1244 StallExecutionProcessor(10000);
1245 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1246 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1250 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
1252 /* PC/XT keyboard or no keyboard */
1256 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1257 if (Scancode
!= 0xFA)
1259 /* No ACK received */
1263 StallExecutionProcessor(10000);
1265 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1266 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
1268 /* Found AT keyboard */
1272 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1273 if (Scancode
!= 0xAB)
1275 /* No 0xAB received */
1279 StallExecutionProcessor(10000);
1281 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1282 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) == 0)
1284 /* No byte in buffer */
1288 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1289 if (Scancode
!= 0x41)
1291 /* No 0x41 received */
1295 /* Found MF-II keyboard */
1301 DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey
)
1303 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1304 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1305 PCM_KEYBOARD_DEVICE_DATA KeyboardData
;
1306 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
1309 /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2 */
1310 if (TRUE
|| DetectKeyboardDevice())
1312 /* Set 'Configuration Data' value */
1313 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
1314 sizeof(CM_KEYBOARD_DEVICE_DATA
);
1315 PartialResourceList
= MmHeapAlloc(Size
);
1316 if (PartialResourceList
== NULL
)
1318 ERR("Failed to allocate resource descriptor\n");
1322 /* Initialize resource descriptor */
1323 memset(PartialResourceList
, 0, Size
);
1324 PartialResourceList
->Version
= 1;
1325 PartialResourceList
->Revision
= 1;
1326 PartialResourceList
->Count
= 1;
1328 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1329 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1330 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1331 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_KEYBOARD_DEVICE_DATA
);
1333 KeyboardData
= (PCM_KEYBOARD_DEVICE_DATA
)(PartialDescriptor
+ 1);
1334 KeyboardData
->Version
= 1;
1335 KeyboardData
->Revision
= 1;
1336 KeyboardData
->Type
= 4;
1337 KeyboardData
->Subtype
= 0;
1338 KeyboardData
->KeyboardFlags
= 0x20;
1340 /* Create controller key */
1341 FldrCreateComponentKey(ControllerKey
,
1348 PartialResourceList
,
1351 TRACE("Created key: KeyboardPeripheral\\0\n");
1353 MmHeapFree(PartialResourceList
);
1359 DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey
)
1361 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1362 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1363 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1366 /* Set 'Configuration Data' value */
1367 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
1368 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1369 PartialResourceList
= MmHeapAlloc(Size
);
1370 if (PartialResourceList
== NULL
)
1372 ERR("Failed to allocate resource descriptor\n");
1376 /* Initialize resource descriptor */
1377 memset(PartialResourceList
, 0, Size
);
1378 PartialResourceList
->Version
= 1;
1379 PartialResourceList
->Revision
= 1;
1380 PartialResourceList
->Count
= 3;
1383 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[0];
1384 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1385 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1386 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1387 PartialDescriptor
->u
.Interrupt
.Level
= 1;
1388 PartialDescriptor
->u
.Interrupt
.Vector
= 1;
1389 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1391 /* Set IO Port 0x60 */
1392 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[1];
1393 PartialDescriptor
->Type
= CmResourceTypePort
;
1394 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1395 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1396 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x60;
1397 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1398 PartialDescriptor
->u
.Port
.Length
= 1;
1400 /* Set IO Port 0x64 */
1401 PartialDescriptor
= &PartialResourceList
->PartialDescriptors
[2];
1402 PartialDescriptor
->Type
= CmResourceTypePort
;
1403 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1404 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1405 PartialDescriptor
->u
.Port
.Start
.LowPart
= 0x64;
1406 PartialDescriptor
->u
.Port
.Start
.HighPart
= 0x0;
1407 PartialDescriptor
->u
.Port
.Length
= 1;
1409 /* Create controller key */
1410 FldrCreateComponentKey(BusKey
,
1417 PartialResourceList
,
1420 TRACE("Created key: KeyboardController\\0\n");
1422 MmHeapFree(PartialResourceList
);
1424 DetectKeyboardPeripheral(ControllerKey
);
1429 PS2ControllerWait(VOID
)
1434 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1436 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1437 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1440 /* Sleep for one millisecond */
1441 StallExecutionProcessor(1000);
1447 DetectPS2AuxPort(VOID
)
1450 /* Current detection is too unreliable. Just do as if
1451 * the PS/2 aux port is always present
1458 /* Put the value 0x5A in the output buffer using the
1459 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1460 * Poll the Status Register for a while to see if the value really turns up
1461 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1462 * to 1 in the Status Register, we assume this controller has an
1463 * Auxiliary Port (a.k.a. Mouse Port).
1465 PS2ControllerWait();
1466 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1467 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1468 PS2ControllerWait();
1470 /* 0x5A is a random dummy value */
1471 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1474 for (Loops
= 0; Loops
< 10; Loops
++)
1476 StallExecutionProcessor(10000);
1477 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1478 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1482 READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1484 return (Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
);
1490 DetectPS2AuxDevice(VOID
)
1495 BOOLEAN Result
= TRUE
;
1497 PS2ControllerWait();
1498 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1499 CONTROLLER_COMMAND_WRITE_MOUSE
);
1500 PS2ControllerWait();
1502 /* Identify device */
1503 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1506 /* Wait for reply */
1507 for (Loops
= 0; Loops
< 100; Loops
++)
1509 StallExecutionProcessor(10000);
1510 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1511 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1515 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1516 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1519 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1520 if (Scancode
!= 0xFA)
1523 StallExecutionProcessor(10000);
1525 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1526 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1529 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1530 if (Scancode
!= 0x00)
1538 DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey
)
1540 CM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1541 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1542 PCONFIGURATION_COMPONENT_DATA PeripheralKey
;
1544 if (DetectPS2AuxPort())
1546 TRACE("Detected PS2 port\n");
1548 memset(&PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1550 /* Initialize resource descriptor */
1551 PartialResourceList
.Version
= 1;
1552 PartialResourceList
.Revision
= 1;
1553 PartialResourceList
.Count
= 1;
1556 PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1557 PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1558 PartialResourceList
.PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1559 PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1560 PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Vector
= 12;
1561 PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1563 /* Create controller key */
1564 FldrCreateComponentKey(BusKey
,
1571 &PartialResourceList
,
1572 sizeof(CM_PARTIAL_RESOURCE_LIST
),
1574 TRACE("Created key: PointerController\\0\n");
1576 if (DetectPS2AuxDevice())
1578 TRACE("Detected PS2 mouse\n");
1580 /* Initialize resource descriptor */
1581 memset(&PartialResourceList
, 0, sizeof(CM_PARTIAL_RESOURCE_LIST
));
1582 PartialResourceList
.Version
= 1;
1583 PartialResourceList
.Revision
= 1;
1584 PartialResourceList
.Count
= 0;
1586 /* Create peripheral key */
1587 FldrCreateComponentKey(ControllerKey
,
1593 "MICROSOFT PS2 MOUSE",
1594 &PartialResourceList
,
1595 sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1596 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
),
1598 TRACE("Created key: PointerPeripheral\\0\n");
1605 DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey
)
1608 PCONFIGURATION_COMPONENT_DATA ControllerKey
;
1611 /* FIXME: Set 'ComponentInformation' value */
1613 VesaVersion
= BiosIsVesaSupported();
1614 if (VesaVersion
!= 0)
1616 TRACE("VESA version %c.%c\n",
1617 (VesaVersion
>> 8) + '0',
1618 (VesaVersion
& 0xFF) + '0');
1622 TRACE("VESA not supported\n");
1625 if (VesaVersion
>= 0x0200)
1627 strcpy(Buffer
, "VBE Display");
1631 strcpy(Buffer
, "VGA Display");
1634 FldrCreateComponentKey(BusKey
,
1644 TRACE("Created key: DisplayController\\0\n");
1646 /* FIXME: Add display peripheral (monitor) data */
1651 DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
1653 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
1654 PCONFIGURATION_COMPONENT_DATA BusKey
;
1657 /* Increment bus number */
1660 /* Set 'Configuration Data' value */
1661 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) -
1662 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1663 PartialResourceList
= MmHeapAlloc(Size
);
1664 if (PartialResourceList
== NULL
)
1666 ERR("Failed to allocate resource descriptor\n");
1670 /* Initialize resource descriptor */
1671 memset(PartialResourceList
, 0, Size
);
1672 PartialResourceList
->Version
= 1;
1673 PartialResourceList
->Revision
= 1;
1674 PartialResourceList
->Count
= 0;
1676 /* Create new bus key */
1677 FldrCreateComponentKey(SystemKey
,
1679 MultiFunctionAdapter
,
1684 PartialResourceList
,
1688 MmHeapFree(PartialResourceList
);
1690 /* Detect ISA/BIOS devices */
1691 DetectBiosDisks(BusKey
);
1693 DetectBiosFloppyController(BusKey
);
1695 DetectSerialPorts(BusKey
);
1697 DetectParallelPorts(BusKey
);
1699 DetectKeyboardController(BusKey
);
1701 DetectPS2Mouse(BusKey
);
1703 DetectDisplayController(BusKey
);
1705 /* FIXME: Detect more ISA devices */
1709 PCONFIGURATION_COMPONENT_DATA
1712 PCONFIGURATION_COMPONENT_DATA SystemKey
;
1713 ULONG BusNumber
= 0;
1715 TRACE("DetectHardware()\n");
1717 HwInitializeBiosDisks();
1719 /* Create the 'System' key */
1720 SystemKey
= DetectSystem();
1723 DetectPciBios(SystemKey
, &BusNumber
);
1724 DetectApmBios(SystemKey
, &BusNumber
);
1725 DetectPnpBios(SystemKey
, &BusNumber
);
1726 DetectIsaBios(SystemKey
, &BusNumber
);
1727 DetectAcpiBios(SystemKey
, &BusNumber
);
1729 TRACE("DetectHardware() Done\n");
1739 /* Select APM 1.0+ function */
1742 /* Function 05h: CPU idle */
1746 Int386(0x15, &Regs
, &Regs
);
1748 /* Check if successfull (CF set on error) */
1749 if (INT386_SUCCESS(Regs
))
1753 * No futher processing here.
1754 * Optionally implement HLT instruction handling.