2e5b37f070a7923b25020f17902272564bcdfc20
[reactos.git] / freeldr / freeldr / arch / i386 / hardware.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 2003, 2004 Eric Kohl
5 *
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.
10 *
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.
15 *
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.
19 */
20
21 #include <freeldr.h>
22 #include <arch.h>
23 #include <rtl.h>
24 #include <debug.h>
25 #include <disk.h>
26 #include <mm.h>
27 #include <portio.h>
28
29 #include "../../reactos/registry.h"
30 #include "hardware.h"
31
32
33 #define MILLISEC (10)
34 #define PRECISION (8)
35
36 #define HZ (100)
37 #define CLOCK_TICK_RATE (1193182)
38 #define LATCH (CLOCK_TICK_RATE / HZ)
39
40
41 /* No Mouse */
42 #define MOUSE_TYPE_NONE 0
43 /* Microsoft Mouse with 2 buttons */
44 #define MOUSE_TYPE_MICROSOFT 1
45 /* Logitech Mouse with 3 buttons */
46 #define MOUSE_TYPE_LOGITECH 2
47 /* Microsoft Wheel Mouse (aka Z Mouse) */
48 #define MOUSE_TYPE_WHEELZ 3
49 /* Mouse Systems Mouse */
50 #define MOUSE_TYPE_MOUSESYSTEMS 4
51
52
53 /* PS2 stuff */
54
55 /* Controller registers. */
56 #define CONTROLLER_REGISTER_STATUS 0x64
57 #define CONTROLLER_REGISTER_CONTROL 0x64
58 #define CONTROLLER_REGISTER_DATA 0x60
59
60 /* Controller commands. */
61 #define CONTROLLER_COMMAND_READ_MODE 0x20
62 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
63 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
64 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
65 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
66 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
67 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
68 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
69 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
70 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
71 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
72 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
73
74 /* Controller status */
75 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
76 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
77 #define CONTROLLER_STATUS_SELF_TEST 0x04
78 #define CONTROLLER_STATUS_COMMAND 0x08
79 #define CONTROLLER_STATUS_UNLOCKED 0x10
80 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
81 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
82 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
83 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
84 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
85
86 /* Timeout in ms for sending to keyboard controller. */
87 #define CONTROLLER_TIMEOUT 250
88
89
90 typedef struct _CM_INT13_DRIVE_PARAMETER
91 {
92 U16 DriveSelect;
93 U32 MaxCylinders;
94 U16 SectorsPerTrack;
95 U16 MaxHeads;
96 U16 NumberDrives;
97 } CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER;
98
99
100 typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA
101 {
102 U32 BytesPerSector;
103 U32 NumberOfCylinders;
104 U32 SectorsPerTrack;
105 U32 NumberOfHeads;
106 } CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA;
107
108
109 typedef struct _CM_PNP_BIOS_DEVICE_NODE
110 {
111 U16 Size;
112 U8 Node;
113 U32 ProductId;
114 U8 DeviceType[3];
115 U16 DeviceAttributes;
116 } __attribute__((packed)) CM_PNP_BIOS_DEVICE_NODE, *PCM_PNP_BIOS_DEVICE_NODE;
117
118
119 typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
120 {
121 U8 Signature[4];
122 U8 Revision;
123 U8 Length;
124 U16 ControlField;
125 U8 Checksum;
126 U32 EventFlagAddress;
127 U16 RealModeEntryOffset;
128 U16 RealModeEntrySegment;
129 U16 ProtectedModeEntryOffset;
130 U32 ProtectedModeCodeBaseAddress;
131 U32 OemDeviceId;
132 U16 RealModeDataBaseAddress;
133 U32 ProtectedModeDataBaseAddress;
134 } __attribute__((packed)) CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK;
135
136
137 typedef struct _CM_SERIAL_DEVICE_DATA
138 {
139 U16 Version;
140 U16 Revision;
141 U32 BaudClock;
142 } __attribute__((packed)) CM_SERIAL_DEVICE_DATA, *PCM_SERIAL_DEVICE_DATA;
143
144
145 typedef struct _CM_FLOPPY_DEVICE_DATA
146 {
147 U16 Version;
148 U16 Revision;
149 CHAR Size[8];
150 U32 MaxDensity;
151 U32 MountDensity;
152
153 /* Version 2.0 data */
154 U8 StepRateHeadUnloadTime;
155 U8 HeadLoadTime;
156 U8 MotorOffTime;
157 U8 SectorLengthCode;
158 U8 SectorPerTrack;
159 U8 ReadWriteGapLength;
160 U8 DataTransferLength;
161 U8 FormatGapLength;
162 U8 FormatFillCharacter;
163 U8 HeadSettleTime;
164 U8 MotorSettleTime;
165 U8 MaximumTrackValue;
166 U8 DataTransferRate;
167 } __attribute__((packed)) CM_FLOPPY_DEVICE_DATA, *PCM_FLOPPY_DEVICE_DATA;
168
169
170 typedef struct _CM_KEYBOARD_DEVICE_DATA
171 {
172 U16 Version;
173 U16 Revision;
174 U8 Type;
175 U8 Subtype;
176 U16 KeyboardFlags;
177 } __attribute__((packed)) CM_KEYBOARD_DEVICE_DATA, *PCM_KEYBOARD_DEVICE_DATA;
178
179
180 static char Hex[] = "0123456789ABCDEF";
181 static unsigned int delay_count = 1;
182
183
184 /* FUNCTIONS ****************************************************************/
185
186
187 static VOID
188 __KeStallExecutionProcessor(U32 Loops)
189 {
190 register unsigned int i;
191 for (i = 0; i < Loops; i++);
192 }
193
194 VOID KeStallExecutionProcessor(U32 Microseconds)
195 {
196 U64 LoopCount = ((U64)delay_count * (U64)Microseconds) / 1000ULL;
197 __KeStallExecutionProcessor((U32)LoopCount);
198 }
199
200
201 static U32
202 Read8254Timer(VOID)
203 {
204 U32 Count;
205
206 WRITE_PORT_UCHAR((PU8)0x43, 0x00);
207 Count = READ_PORT_UCHAR((PU8)0x40);
208 Count |= READ_PORT_UCHAR((PU8)0x40) << 8;
209
210 return Count;
211 }
212
213
214 static VOID
215 WaitFor8254Wraparound(VOID)
216 {
217 U32 CurCount;
218 U32 PrevCount = ~0;
219 S32 Delta;
220
221 CurCount = Read8254Timer();
222
223 do
224 {
225 PrevCount = CurCount;
226 CurCount = Read8254Timer();
227 Delta = CurCount - PrevCount;
228
229 /*
230 * This limit for delta seems arbitrary, but it isn't, it's
231 * slightly above the level of error a buggy Mercury/Neptune
232 * chipset timer can cause.
233 */
234 }
235 while (Delta < 300);
236 }
237
238
239 VOID
240 HalpCalibrateStallExecution(VOID)
241 {
242 U32 i;
243 U32 calib_bit;
244 U32 CurCount;
245
246 /* Initialise timer interrupt with MILLISECOND ms interval */
247 WRITE_PORT_UCHAR((PU8)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
248 WRITE_PORT_UCHAR((PU8)0x40, LATCH & 0xff); /* LSB */
249 WRITE_PORT_UCHAR((PU8)0x40, LATCH >> 8); /* MSB */
250
251 /* Stage 1: Coarse calibration */
252
253 WaitFor8254Wraparound();
254
255 delay_count = 1;
256
257 do {
258 delay_count <<= 1; /* Next delay count to try */
259
260 WaitFor8254Wraparound();
261
262 __KeStallExecutionProcessor(delay_count); /* Do the delay */
263
264 CurCount = Read8254Timer();
265 } while (CurCount > LATCH / 2);
266
267 delay_count >>= 1; /* Get bottom value for delay */
268
269 /* Stage 2: Fine calibration */
270
271 calib_bit = delay_count; /* Which bit are we going to test */
272
273 for(i=0;i<PRECISION;i++) {
274 calib_bit >>= 1; /* Next bit to calibrate */
275 if(!calib_bit) break; /* If we have done all bits, stop */
276
277 delay_count |= calib_bit; /* Set the bit in delay_count */
278
279 WaitFor8254Wraparound();
280
281 __KeStallExecutionProcessor(delay_count); /* Do the delay */
282
283 CurCount = Read8254Timer();
284 if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
285 delay_count &= ~calib_bit; /* calibrated bit back off */
286 }
287
288 /* We're finished: Do the finishing touches */
289 delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
290 }
291
292
293 VOID
294 SetComponentInformation(HKEY ComponentKey,
295 U32 Flags,
296 U32 Key,
297 U32 Affinity)
298 {
299 CM_COMPONENT_INFORMATION CompInfo;
300 S32 Error;
301
302 CompInfo.Flags = Flags;
303 CompInfo.Version = 0;
304 CompInfo.Key = Key;
305 CompInfo.Affinity = Affinity;
306
307 /* Set 'Component Information' value */
308 Error = RegSetValue(ComponentKey,
309 "Component Information",
310 REG_BINARY,
311 (PU8)&CompInfo,
312 sizeof(CM_COMPONENT_INFORMATION));
313 if (Error != ERROR_SUCCESS)
314 {
315 DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
316 }
317 }
318
319
320 static VOID
321 DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
322 {
323 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
324 PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
325 PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
326 char Buffer[80];
327 HKEY BusKey;
328 U32 x;
329 U32 NodeSize = 0;
330 U32 NodeCount = 0;
331 U8 NodeNumber;
332 U32 FoundNodeCount;
333 int i;
334 U32 PnpBufferSize;
335 U32 Size;
336 char *Ptr;
337 S32 Error;
338
339 InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
340 if (InstData == NULL || strncmp(InstData->Signature, "$PnP", 4))
341 {
342 DbgPrint((DPRINT_HWDETECT, "PnP-BIOS not supported\n"));
343 return;
344 }
345 DbgPrint((DPRINT_HWDETECT, "Signature '%c%c%c%c'\n",
346 InstData->Signature[0], InstData->Signature[1],
347 InstData->Signature[2], InstData->Signature[3]));
348
349
350 x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
351 if (x != 0 || NodeSize == 0 || NodeCount == 0)
352 {
353 DbgPrint((DPRINT_HWDETECT, "PnP-BIOS failed to enumerate device nodes\n"));
354 return;
355 }
356 DbgPrint((DPRINT_HWDETECT, "PnP-BIOS supported\n"));
357 DbgPrint((DPRINT_HWDETECT, "MaxNodeSize %u NodeCount %u\n", NodeSize, NodeCount));
358 DbgPrint((DPRINT_HWDETECT, "Estimated buffer size %u\n", NodeSize * NodeCount));
359
360 /* Create new bus key */
361 sprintf(Buffer,
362 "MultifunctionAdapter\\%u", *BusNumber);
363 Error = RegCreateKey(SystemKey,
364 Buffer,
365 &BusKey);
366 if (Error != ERROR_SUCCESS)
367 {
368 DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
369 return;
370 }
371
372 /* Increment bus number */
373 (*BusNumber)++;
374
375 /* Set 'Identifier' value */
376 Error = RegSetValue(BusKey,
377 "Identifier",
378 REG_SZ,
379 (PU8)"PNP BIOS",
380 9);
381 if (Error != ERROR_SUCCESS)
382 {
383 DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
384 return;
385 }
386
387 /* Set 'Configuration Data' value */
388 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + (NodeSize * NodeCount);
389 FullResourceDescriptor = MmAllocateMemory(Size);
390 if (FullResourceDescriptor == NULL)
391 {
392 DbgPrint((DPRINT_HWDETECT,
393 "Failed to allocate resource descriptor\n"));
394 return;
395 }
396 memset(FullResourceDescriptor, 0, Size);
397
398 /* Initialize resource descriptor */
399 FullResourceDescriptor->InterfaceType = Internal;
400 FullResourceDescriptor->BusNumber = 0;
401 FullResourceDescriptor->PartialResourceList.Count = 1;
402 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
403 CmResourceTypeDeviceSpecific;
404 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
405 CmResourceShareUndetermined;
406 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
407
408 Ptr = (char *)(((PVOID)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]) +
409 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
410
411 /* Set instalation check data */
412 memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
413 Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
414
415 /* Copy device nodes */
416 FoundNodeCount = 0;
417 PnpBufferSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
418 for (i = 0; i < 0xFF; i++)
419 {
420 NodeNumber = (U8)i;
421
422 x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER);
423 if (x == 0)
424 {
425 DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER;
426
427 DbgPrint((DPRINT_HWDETECT,
428 "Node: %u Size %u (0x%x)\n",
429 DeviceNode->Node,
430 DeviceNode->Size,
431 DeviceNode->Size));
432 // printf("Node: %u Size %u (0x%x)\n",
433 // DeviceNode->Node,
434 // DeviceNode->Size,
435 // DeviceNode->Size);
436
437 memcpy (Ptr,
438 DeviceNode,
439 DeviceNode->Size);
440
441 Ptr += DeviceNode->Size;
442 PnpBufferSize += DeviceNode->Size;
443
444 FoundNodeCount++;
445 if (FoundNodeCount >= NodeCount)
446 break;
447 }
448 }
449
450 /* Set real data size */
451 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
452 PnpBufferSize;
453 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + PnpBufferSize;
454
455 DbgPrint((DPRINT_HWDETECT, "Real buffer size: %u\n", PnpBufferSize));
456 DbgPrint((DPRINT_HWDETECT, "Resource size: %u\n", Size));
457
458 /* Set 'Configuration Data' value */
459 Error = RegSetValue(BusKey,
460 "Configuration Data",
461 REG_FULL_RESOURCE_DESCRIPTOR,
462 (PU8) FullResourceDescriptor,
463 Size);
464 MmFreeMemory(FullResourceDescriptor);
465 if (Error != ERROR_SUCCESS)
466 {
467 DbgPrint((DPRINT_HWDETECT,
468 "RegSetValue(Configuration Data) failed (Error %u)\n",
469 (int)Error));
470 }
471 }
472
473
474
475 static VOID
476 SetHarddiskConfigurationData(HKEY DiskKey,
477 U32 DriveNumber)
478 {
479 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
480 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
481 EXTENDED_GEOMETRY ExtGeometry;
482 GEOMETRY Geometry;
483 U32 Size;
484 S32 Error;
485
486 /* Set 'Configuration Data' value */
487 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
488 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
489 FullResourceDescriptor = MmAllocateMemory(Size);
490 if (FullResourceDescriptor == NULL)
491 {
492 DbgPrint((DPRINT_HWDETECT,
493 "Failed to allocate a full resource descriptor\n"));
494 return;
495 }
496
497 memset(FullResourceDescriptor, 0, Size);
498 FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined;
499 FullResourceDescriptor->BusNumber = 0;
500 FullResourceDescriptor->PartialResourceList.Count = 1;
501 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
502 CmResourceTypeDeviceSpecific;
503 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
504 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
505 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
506 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
507
508 /* Get pointer to geometry data */
509 DiskGeometry = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
510
511 /* Get the disk geometry */
512 ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
513 if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
514 {
515 DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
516 DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
517 DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
518 DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
519 }
520 else if(DiskGetDriveParameters(DriveNumber, &Geometry))
521 {
522 DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
523 DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
524 DiskGeometry->SectorsPerTrack = Geometry.Sectors;
525 DiskGeometry->NumberOfHeads = Geometry.Heads;
526 }
527 else
528 {
529 DbgPrint((DPRINT_HWDETECT, "Reading disk geometry failed\n"));
530 MmFreeMemory(FullResourceDescriptor);
531 return;
532 }
533 DbgPrint((DPRINT_HWDETECT,
534 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
535 DriveNumber,
536 DiskGeometry->NumberOfCylinders,
537 DiskGeometry->NumberOfHeads,
538 DiskGeometry->SectorsPerTrack,
539 DiskGeometry->BytesPerSector));
540
541 Error = RegSetValue(DiskKey,
542 "Configuration Data",
543 REG_FULL_RESOURCE_DESCRIPTOR,
544 (PU8) FullResourceDescriptor,
545 Size);
546 MmFreeMemory(FullResourceDescriptor);
547 if (Error != ERROR_SUCCESS)
548 {
549 DbgPrint((DPRINT_HWDETECT,
550 "RegSetValue(Configuration Data) failed (Error %u)\n",
551 (int)Error));
552 }
553 }
554
555
556 static VOID
557 SetHarddiskIdentifier(HKEY DiskKey,
558 U32 DriveNumber)
559 {
560 PMASTER_BOOT_RECORD Mbr;
561 U32 *Buffer;
562 U32 i;
563 U32 Checksum;
564 U32 Signature;
565 char Identifier[20];
566 S32 Error;
567
568 /* Read the MBR */
569 if (!DiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
570 {
571 DbgPrint((DPRINT_HWDETECT, "Reading MBR failed\n"));
572 return;
573 }
574
575 Buffer = (U32*)DISKREADBUFFER;
576 Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
577
578 Signature = Mbr->Signature;
579 DbgPrint((DPRINT_HWDETECT, "Signature: %x\n", Signature));
580
581 /* Calculate the MBR checksum */
582 Checksum = 0;
583 for (i = 0; i < 128; i++)
584 {
585 Checksum += Buffer[i];
586 }
587 Checksum = ~Checksum + 1;
588 DbgPrint((DPRINT_HWDETECT, "Checksum: %x\n", Checksum));
589
590 /* Convert checksum and signature to identifier string */
591 Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
592 Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
593 Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
594 Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
595 Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
596 Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
597 Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
598 Identifier[7] = Hex[Checksum & 0x0F];
599 Identifier[8] = '-';
600 Identifier[9] = Hex[(Signature >> 28) & 0x0F];
601 Identifier[10] = Hex[(Signature >> 24) & 0x0F];
602 Identifier[11] = Hex[(Signature >> 20) & 0x0F];
603 Identifier[12] = Hex[(Signature >> 16) & 0x0F];
604 Identifier[13] = Hex[(Signature >> 12) & 0x0F];
605 Identifier[14] = Hex[(Signature >> 8) & 0x0F];
606 Identifier[15] = Hex[(Signature >> 4) & 0x0F];
607 Identifier[16] = Hex[Signature & 0x0F];
608 Identifier[17] = '-';
609 Identifier[18] = 'A';
610 Identifier[19] = 0;
611 DbgPrint((DPRINT_HWDETECT, "Identifier: %xsn", Identifier));
612
613 /* Set identifier */
614 Error = RegSetValue(DiskKey,
615 "Identifier",
616 REG_SZ,
617 (PU8) Identifier,
618 20);
619 if (Error != ERROR_SUCCESS)
620 {
621 DbgPrint((DPRINT_HWDETECT,
622 "RegSetValue(Identifier) failed (Error %u)\n",
623 (int)Error));
624 }
625 }
626
627
628 static VOID
629 DetectBiosDisks(HKEY SystemKey,
630 HKEY BusKey)
631 {
632 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
633 PCM_INT13_DRIVE_PARAMETER Int13Drives;
634 GEOMETRY Geometry;
635 CHAR Buffer[80];
636 HKEY DiskKey;
637 U32 DiskCount;
638 U32 Size;
639 U32 i;
640 S32 Error;
641
642 /* Count the number of visible drives */
643 DiskReportError(FALSE);
644 DiskCount = 0;
645 while (DiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
646 {
647 DiskCount++;
648 }
649 DiskReportError(TRUE);
650 DbgPrint((DPRINT_HWDETECT, "BIOS reports %d harddisk%s\n",
651 (int)DiskCount, (DiskCount == 1) ? "": "s"));
652
653 /* Allocate resource descriptor */
654 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
655 sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
656 FullResourceDescriptor = MmAllocateMemory(Size);
657 if (FullResourceDescriptor == NULL)
658 {
659 DbgPrint((DPRINT_HWDETECT,
660 "Failed to allocate resource descriptor\n"));
661 return;
662 }
663
664 /* Initialize resource descriptor */
665 memset(FullResourceDescriptor, 0, Size);
666 FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined;
667 FullResourceDescriptor->BusNumber = -1;
668 FullResourceDescriptor->PartialResourceList.Count = 1;
669 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
670 CmResourceTypeDeviceSpecific;
671 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
672 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
673 FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
674 sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
675
676 /* Get harddisk Int13 geometry data */
677 Int13Drives = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
678 for (i = 0; i < DiskCount; i++)
679 {
680 if (DiskGetDriveParameters(0x80 + i, &Geometry))
681 {
682 Int13Drives[i].DriveSelect = 0x80 + i;
683 Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
684 Int13Drives[i].SectorsPerTrack = Geometry.Sectors;
685 Int13Drives[i].MaxHeads = Geometry.Heads - 1;
686 Int13Drives[i].NumberDrives = DiskCount;
687
688 DbgPrint((DPRINT_HWDETECT,
689 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
690 0x80 + i,
691 Geometry.Cylinders - 1,
692 Geometry.Heads -1,
693 Geometry.Sectors,
694 Geometry.BytesPerSector));
695 }
696 }
697
698 /* Set 'Configuration Data' value */
699 Error = RegSetValue(SystemKey,
700 "Configuration Data",
701 REG_FULL_RESOURCE_DESCRIPTOR,
702 (PU8) FullResourceDescriptor,
703 Size);
704 MmFreeMemory(FullResourceDescriptor);
705 if (Error != ERROR_SUCCESS)
706 {
707 DbgPrint((DPRINT_HWDETECT,
708 "RegSetValue(Configuration Data) failed (Error %u)\n",
709 (int)Error));
710 return;
711 }
712
713 /* Create and fill subkey for each harddisk */
714 for (i = 0; i < DiskCount; i++)
715 {
716 /* Create disk key */
717 sprintf (Buffer,
718 "DiskController\\0\\DiskPeripheral\\%u",
719 i);
720
721 Error = RegCreateKey(BusKey,
722 Buffer,
723 &DiskKey);
724 if (Error != ERROR_SUCCESS)
725 {
726 DbgPrint((DPRINT_HWDETECT, "Failed to create drive key\n"));
727 continue;
728 }
729 DbgPrint((DPRINT_HWDETECT, "Created key: %s\n", Buffer));
730
731 /* Set disk values */
732 SetHarddiskConfigurationData(DiskKey, 0x80 + i);
733 SetHarddiskIdentifier(DiskKey, 0x80 + i);
734 }
735 }
736
737
738 static U32
739 GetFloppyCount(VOID)
740 {
741 U8 Data;
742
743 WRITE_PORT_UCHAR((PUCHAR)0x70, 0x10);
744 Data = READ_PORT_UCHAR((PUCHAR)0x71);
745
746 return ((Data & 0xF0) ? 1 : 0) + ((Data & 0x0F) ? 1 : 0);
747 }
748
749
750 static U8
751 GetFloppyType(U8 DriveNumber)
752 {
753 U8 Data;
754
755 WRITE_PORT_UCHAR((PUCHAR)0x70, 0x10);
756 Data = READ_PORT_UCHAR((PUCHAR)0x71);
757
758 if (DriveNumber == 0)
759 return Data >> 4;
760 else if (DriveNumber == 1)
761 return Data & 0x0F;
762
763 return 0;
764 }
765
766
767 static PVOID
768 GetInt1eTable(VOID)
769 {
770 PU16 SegPtr = (PU16)0x7A;
771 PU16 OfsPtr = (PU16)0x78;
772
773 return (PVOID)(((U32)(*SegPtr)) << 4) + (U32)(*OfsPtr);
774 }
775
776
777 static VOID
778 DetectBiosFloppyPeripheral(HKEY ControllerKey)
779 {
780 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
781 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
782 PCM_FLOPPY_DEVICE_DATA FloppyData;
783 char KeyName[32];
784 char Identifier[20];
785 HKEY PeripheralKey;
786 U32 Size;
787 S32 Error;
788 U32 FloppyNumber;
789 U8 FloppyType;
790 U32 MaxDensity[6] = {0, 360, 1200, 720, 1440, 2880};
791 PU8 Ptr;
792
793 for (FloppyNumber = 0; FloppyNumber < 2; FloppyNumber++)
794 {
795 FloppyType = GetFloppyType(FloppyNumber);
796
797 if ((FloppyType > 5) || (FloppyType == 0))
798 continue;
799
800 DiskResetController(FloppyNumber);
801
802 Ptr = GetInt1eTable();
803
804 sprintf(KeyName, "FloppyDiskPeripheral\\%u", FloppyNumber);
805
806 Error = RegCreateKey(ControllerKey,
807 "FloppyDiskPeripheral\\0",
808 &PeripheralKey);
809 if (Error != ERROR_SUCCESS)
810 {
811 DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
812 return;
813 }
814
815 DbgPrint((DPRINT_HWDETECT, "Created key: %s\n", KeyName));
816
817 /* Set 'ComponentInformation' value */
818 SetComponentInformation(PeripheralKey,
819 0x0,
820 FloppyNumber,
821 0xFFFFFFFF);
822
823 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
824 sizeof(CM_FLOPPY_DEVICE_DATA);
825 FullResourceDescriptor = MmAllocateMemory(Size);
826 if (FullResourceDescriptor == NULL)
827 {
828 DbgPrint((DPRINT_HWDETECT,
829 "Failed to allocate resource descriptor\n"));
830 return;
831 }
832
833 memset(FullResourceDescriptor, 0, Size);
834 FullResourceDescriptor->InterfaceType = Isa;
835 FullResourceDescriptor->BusNumber = 0;
836 FullResourceDescriptor->PartialResourceList.Count = 1;
837
838 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
839 PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
840 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
841 PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_FLOPPY_DEVICE_DATA);
842
843 FloppyData = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
844 FloppyData->Version = 2;
845 FloppyData->Revision = 0;
846 FloppyData->MaxDensity = MaxDensity[FloppyType];
847 FloppyData->MountDensity = 0;
848 RtlCopyMemory(&FloppyData->StepRateHeadUnloadTime,
849 Ptr,
850 11);
851 FloppyData->MaximumTrackValue = (FloppyType == 1) ? 39 : 79;
852 FloppyData->DataTransferRate = 0;
853
854 /* Set 'Configuration Data' value */
855 Error = RegSetValue(PeripheralKey,
856 "Configuration Data",
857 REG_FULL_RESOURCE_DESCRIPTOR,
858 (PU8) FullResourceDescriptor,
859 Size);
860 MmFreeMemory(FullResourceDescriptor);
861 if (Error != ERROR_SUCCESS)
862 {
863 DbgPrint((DPRINT_HWDETECT,
864 "RegSetValue(Configuration Data) failed (Error %u)\n",
865 (int)Error));
866 return;
867 }
868
869 /* Set 'Identifier' value */
870 sprintf(Identifier, "FLOPPY%u", FloppyNumber + 1);
871 Error = RegSetValue(PeripheralKey,
872 "Identifier",
873 REG_SZ,
874 (PU8)Identifier,
875 strlen(Identifier) + 1);
876 if (Error != ERROR_SUCCESS)
877 {
878 DbgPrint((DPRINT_HWDETECT,
879 "RegSetValue() failed (Error %u)\n",
880 (int)Error));
881 }
882 }
883 }
884
885
886 static VOID
887 DetectBiosFloppyController(HKEY SystemKey,
888 HKEY BusKey)
889 {
890 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
891 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
892 HKEY ControllerKey;
893 U32 Size;
894 S32 Error;
895 U32 FloppyCount;
896
897 FloppyCount = GetFloppyCount();
898 DbgPrint((DPRINT_HWDETECT,
899 "Floppy count: %u\n",
900 FloppyCount));
901
902 if (FloppyCount == 0)
903 return;
904
905 Error = RegCreateKey(BusKey,
906 "DiskController\\0",
907 &ControllerKey);
908 if (Error != ERROR_SUCCESS)
909 {
910 DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
911 return;
912 }
913
914 DbgPrint((DPRINT_HWDETECT, "Created key: DiskController\\0\n"));
915
916 /* Set 'ComponentInformation' value */
917 SetComponentInformation(ControllerKey,
918 0x64,
919 0,
920 0xFFFFFFFF);
921
922 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
923 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
924 FullResourceDescriptor = MmAllocateMemory(Size);
925 if (FullResourceDescriptor == NULL)
926 {
927 DbgPrint((DPRINT_HWDETECT,
928 "Failed to allocate resource descriptor\n"));
929 return;
930 }
931 memset(FullResourceDescriptor, 0, Size);
932
933 /* Initialize resource descriptor */
934 FullResourceDescriptor->InterfaceType = Isa;
935 FullResourceDescriptor->BusNumber = 0;
936 FullResourceDescriptor->PartialResourceList.Count = 3;
937
938 /* Set IO Port */
939 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
940 PartialDescriptor->Type = CmResourceTypePort;
941 PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
942 PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
943 PartialDescriptor->u.Port.Start = (U64)0x03F0;
944 PartialDescriptor->u.Port.Length = 8;
945
946 /* Set Interrupt */
947 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
948 PartialDescriptor->Type = CmResourceTypeInterrupt;
949 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
950 PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
951 PartialDescriptor->u.Interrupt.Level = 6;
952 PartialDescriptor->u.Interrupt.Vector = 6;
953 PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
954
955 /* Set DMA channel */
956 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
957 PartialDescriptor->Type = CmResourceTypeDma;
958 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
959 PartialDescriptor->Flags = 0;
960 PartialDescriptor->u.Dma.Channel = 2;
961 PartialDescriptor->u.Dma.Port = 0;
962
963 /* Set 'Configuration Data' value */
964 Error = RegSetValue(ControllerKey,
965 "Configuration Data",
966 REG_FULL_RESOURCE_DESCRIPTOR,
967 (PU8) FullResourceDescriptor,
968 Size);
969 MmFreeMemory(FullResourceDescriptor);
970 if (Error != ERROR_SUCCESS)
971 {
972 DbgPrint((DPRINT_HWDETECT,
973 "RegSetValue(Configuration Data) failed (Error %u)\n",
974 (int)Error));
975 return;
976 }
977
978 DetectBiosFloppyPeripheral(ControllerKey);
979 }
980
981
982 static VOID
983 InitializeSerialPort(U32 Port,
984 U32 LineControl)
985 {
986 WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80); /* set DLAB on */
987 WRITE_PORT_UCHAR((PUCHAR)Port, 0x60); /* speed LO byte */
988 WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* speed HI byte */
989 WRITE_PORT_UCHAR((PUCHAR)Port + 3, LineControl);
990 WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* set comm and DLAB to 0 */
991 WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09); /* DR int enable */
992 READ_PORT_UCHAR((PUCHAR)Port + 5); /* clear error bits */
993 }
994
995
996 static U32
997 DetectSerialMouse(U32 Port)
998 {
999 CHAR Buffer[4];
1000 U32 i;
1001 U32 TimeOut = 200;
1002 U8 LineControl;
1003
1004 /* Shutdown mouse or something like that */
1005 LineControl = READ_PORT_UCHAR((PUCHAR)Port + 4);
1006 WRITE_PORT_UCHAR((PUCHAR)Port + 4, (LineControl & ~0x02) | 0x01);
1007 KeStallExecutionProcessor(100000);
1008
1009 /* Clear buffer */
1010 while (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01)
1011 READ_PORT_UCHAR((PUCHAR)Port);
1012
1013 /*
1014 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
1015 * 'Output Line 2' message. This enables mouse to identify.
1016 */
1017 WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);
1018
1019 /* Wait 10 milliseconds for the mouse getting ready */
1020 KeStallExecutionProcessor(10000);
1021
1022 /* Read first four bytes, which contains Microsoft Mouse signs */
1023 for (i = 0; i < 4; i++)
1024 {
1025 while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
1026 {
1027 KeStallExecutionProcessor(1000);
1028 --TimeOut;
1029 if (TimeOut == 0)
1030 return MOUSE_TYPE_NONE;
1031 }
1032 Buffer[i] = READ_PORT_UCHAR((PUCHAR)Port);
1033 }
1034
1035 DbgPrint((DPRINT_HWDETECT,
1036 "Mouse data: %x %x %x %x\n",
1037 Buffer[0],Buffer[1],Buffer[2],Buffer[3]));
1038
1039 /* Check that four bytes for signs */
1040 for (i = 0; i < 4; ++i)
1041 {
1042 if (Buffer[i] == 'B')
1043 {
1044 /* Sign for Microsoft Ballpoint */
1045 // DbgPrint("Microsoft Ballpoint device detected\n");
1046 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
1047 return MOUSE_TYPE_NONE;
1048 }
1049 else if (Buffer[i] == 'M')
1050 {
1051 /* Sign for Microsoft Mouse protocol followed by button specifier */
1052 if (i == 3)
1053 {
1054 /* Overflow Error */
1055 return MOUSE_TYPE_NONE;
1056 }
1057
1058 switch (Buffer[i + 1])
1059 {
1060 case '3':
1061 DbgPrint((DPRINT_HWDETECT,
1062 "Microsoft Mouse with 3-buttons detected\n"));
1063 return MOUSE_TYPE_LOGITECH;
1064
1065 case 'Z':
1066 DbgPrint((DPRINT_HWDETECT,
1067 "Microsoft Wheel Mouse detected\n"));
1068 return MOUSE_TYPE_WHEELZ;
1069
1070 /* case '2': */
1071 default:
1072 DbgPrint((DPRINT_HWDETECT,
1073 "Microsoft Mouse with 2-buttons detected\n"));
1074 return MOUSE_TYPE_MICROSOFT;
1075 }
1076 }
1077 }
1078
1079 return MOUSE_TYPE_NONE;
1080 }
1081
1082
1083 static U32
1084 GetSerialMousePnpId(U32 Port, char *Buffer)
1085 {
1086 U32 TimeOut;
1087 U32 i = 0;
1088 char c;
1089 char x;
1090
1091 WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09);
1092
1093 /* Wait 10 milliseconds for the mouse getting ready */
1094 KeStallExecutionProcessor(10000);
1095
1096 WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);
1097
1098 KeStallExecutionProcessor(10000);
1099
1100 for (;;)
1101 {
1102 TimeOut = 200;
1103 while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
1104 {
1105 KeStallExecutionProcessor(1000);
1106 --TimeOut;
1107 if (TimeOut == 0)
1108 {
1109 return 0;
1110 }
1111 }
1112
1113 c = READ_PORT_UCHAR((PUCHAR)Port);
1114 if (c == 0x08 || c == 0x28)
1115 break;
1116 }
1117
1118 Buffer[i++] = c;
1119 x = c + 1;
1120
1121 for (;;)
1122 {
1123 TimeOut = 200;
1124 while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
1125 {
1126 KeStallExecutionProcessor(1000);
1127 --TimeOut;
1128 if (TimeOut == 0)
1129 return 0;
1130 }
1131 c = READ_PORT_UCHAR((PUCHAR)Port);
1132 Buffer[i++] = c;
1133 if (c == x)
1134 break;
1135 if (i >= 256)
1136 break;
1137 }
1138
1139 return i;
1140 }
1141
1142
1143 static VOID
1144 DetectSerialPointerPeripheral(HKEY ControllerKey,
1145 U32 Base)
1146 {
1147 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
1148 char Buffer[256];
1149 char Identifier[256];
1150 HKEY PeripheralKey;
1151 U32 MouseType;
1152 U32 Length;
1153 U32 i;
1154 U32 j;
1155 S32 Error;
1156
1157 DbgPrint((DPRINT_HWDETECT,
1158 "DetectSerialPointerPeripheral()\n"));
1159
1160 Identifier[0] = 0;
1161
1162 InitializeSerialPort(Base, 2);
1163 MouseType = DetectSerialMouse(Base);
1164
1165 if (MouseType != MOUSE_TYPE_NONE)
1166 {
1167 Length = GetSerialMousePnpId(Base, Buffer);
1168 DbgPrint((DPRINT_HWDETECT,
1169 "PnP ID length: %u\n",
1170 Length));
1171
1172 if (Length != 0)
1173 {
1174 /* Convert PnP sting to ASCII */
1175 if (Buffer[0] == 0x08)
1176 {
1177 for (i = 0; i < Length; i++)
1178 Buffer[i] += 0x20;
1179 }
1180 Buffer[Length] = 0;
1181
1182 DbgPrint((DPRINT_HWDETECT,
1183 "PnP ID string: %s\n",
1184 Buffer));
1185
1186 /* Copy PnpId string */
1187 memcpy(&Identifier[0],
1188 &Buffer[3],
1189 7);
1190 memcpy(&Identifier[7],
1191 " - ",
1192 4);
1193
1194 /* Skip device serial number */
1195 i = 10;
1196 if (Buffer[i] == '\\')
1197 {
1198 for (j = ++i; i < Length; ++i)
1199 {
1200 if (Buffer[i] == '\\')
1201 break;
1202 }
1203 if (i >= Length)
1204 i -= 3;
1205 }
1206
1207 /* Skip PnP class */
1208 if (Buffer[i] == '\\')
1209 {
1210 for (j = ++i; i < Length; ++i)
1211 {
1212 if (Buffer[i] == '\\')
1213 break;
1214 }
1215
1216 if (i >= Length)
1217 i -= 3;
1218 }
1219
1220 /* Skip compatible PnP Id */
1221 if (Buffer[i] == '\\')
1222 {
1223 for (j = ++i; i < Length; ++i)
1224 {
1225 if (Buffer[i] == '\\')
1226 break;
1227 }
1228 if (Buffer[j] == '*')
1229 ++j;
1230 if (i >= Length)
1231 i -= 3;
1232 }
1233
1234 /* Get product description */
1235 if (Buffer[i] == '\\')
1236 {
1237 for (j = ++i; i < Length; ++i)
1238 {
1239 if (Buffer[i] == ';')
1240 break;
1241 }
1242 if (i >= Length)
1243 i -= 3;
1244 if (i > j + 1)
1245 {
1246 memcpy(&Identifier[10],
1247 &Buffer[j],
1248 i - j);
1249 Identifier[10 + (i-j)] = 0;
1250 }
1251 }
1252
1253 DbgPrint((DPRINT_HWDETECT,
1254 "Identifier string: %s\n",
1255 Identifier));
1256 }
1257
1258 if (Length == 0 || strlen(Identifier) < 11)
1259 {
1260 switch (MouseType)
1261 {
1262 case MOUSE_TYPE_LOGITECH:
1263 strcpy (Identifier,
1264 "LOGITECH SERIAL MOUSE");
1265 break;
1266
1267 case MOUSE_TYPE_WHEELZ:
1268 strcpy (Identifier,
1269 "MICROSOFT SERIAL MOUSE WITH WHEEL");
1270 break;
1271
1272 case MOUSE_TYPE_MICROSOFT:
1273 default:
1274 strcpy (Identifier,
1275 "MICROSOFT SERIAL MOUSE");
1276 break;
1277 }
1278 }
1279
1280 /* Create 'PointerPeripheral' key */
1281 Error = RegCreateKey(ControllerKey,
1282 "PointerPeripheral\\0",
1283 &PeripheralKey);
1284 if (Error != ERROR_SUCCESS)
1285 {
1286 DbgPrint((DPRINT_HWDETECT,
1287 "Failed to create peripheral key\n"));
1288 return;
1289 }
1290 DbgPrint((DPRINT_HWDETECT,
1291 "Created key: PointerPeripheral\\0\n"));
1292
1293 /* Set 'ComponentInformation' value */
1294 SetComponentInformation(PeripheralKey,
1295 0x20,
1296 0,
1297 0xFFFFFFFF);
1298
1299 /* Set 'Configuration Data' value */
1300 memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
1301 FullResourceDescriptor.InterfaceType = Isa;
1302 FullResourceDescriptor.BusNumber = 0;
1303 FullResourceDescriptor.PartialResourceList.Count = 0;
1304
1305 Error = RegSetValue(PeripheralKey,
1306 "Configuration Data",
1307 REG_FULL_RESOURCE_DESCRIPTOR,
1308 (PU8)&FullResourceDescriptor,
1309 sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
1310 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
1311 if (Error != ERROR_SUCCESS)
1312 {
1313 DbgPrint((DPRINT_HWDETECT,
1314 "RegSetValue(Configuration Data) failed (Error %u)\n",
1315 (int)Error));
1316 }
1317
1318 /* Set 'Identifier' value */
1319 Error = RegSetValue(PeripheralKey,
1320 "Identifier",
1321 REG_SZ,
1322 (PU8)Identifier,
1323 strlen(Identifier) + 1);
1324 if (Error != ERROR_SUCCESS)
1325 {
1326 DbgPrint((DPRINT_HWDETECT,
1327 "RegSetValue() failed (Error %u)\n",
1328 (int)Error));
1329 }
1330 }
1331 }
1332
1333
1334 static VOID
1335 DetectSerialPorts(HKEY BusKey)
1336 {
1337 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
1338 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
1339 PCM_SERIAL_DEVICE_DATA SerialDeviceData;
1340 U32 Base[4] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
1341 U32 Irq[4] = {4, 3, 4, 3};
1342 char Buffer[80];
1343 U32 ControllerNumber = 0;
1344 HKEY ControllerKey;
1345 U32 i;
1346 S32 Error;
1347 U32 Size;
1348
1349 DbgPrint((DPRINT_HWDETECT, "DetectSerialPorts()\n"));
1350
1351 for (i = 0; i < 4; i++)
1352 {
1353 WRITE_PORT_UCHAR ((PUCHAR)(Base[i] + 4), 0x10);
1354 if (!(READ_PORT_UCHAR((PUCHAR)Base[i] + 6) & 0xf0))
1355 {
1356 DbgPrint((DPRINT_HWDETECT,
1357 "Found COM%u port at 0x%x\n",
1358 i + 1,
1359 Base[i]));
1360
1361 /* Create controller key */
1362 sprintf(Buffer,
1363 "SerialController\\%u",
1364 ControllerNumber);
1365
1366 Error = RegCreateKey(BusKey,
1367 Buffer,
1368 &ControllerKey);
1369 if (Error != ERROR_SUCCESS)
1370 {
1371 DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
1372 continue;
1373 }
1374 DbgPrint((DPRINT_HWDETECT, "Created key: %s\n", Buffer));
1375
1376 /* Set 'ComponentInformation' value */
1377 SetComponentInformation(ControllerKey,
1378 0x78,
1379 ControllerNumber,
1380 0xFFFFFFFF);
1381
1382 /* Build full device descriptor */
1383 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
1384 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
1385 sizeof(CM_SERIAL_DEVICE_DATA);
1386 FullResourceDescriptor = MmAllocateMemory(Size);
1387 if (FullResourceDescriptor == NULL)
1388 {
1389 DbgPrint((DPRINT_HWDETECT,
1390 "Failed to allocate resource descriptor\n"));
1391 continue;
1392 }
1393 memset(FullResourceDescriptor, 0, Size);
1394
1395 /* Initialize resource descriptor */
1396 FullResourceDescriptor->InterfaceType = Isa;
1397 FullResourceDescriptor->BusNumber = 0;
1398 FullResourceDescriptor->PartialResourceList.Count = 3;
1399
1400 /* Set IO Port */
1401 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
1402 PartialDescriptor->Type = CmResourceTypePort;
1403 PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1404 PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
1405 PartialDescriptor->u.Port.Start = (U64)Base[i];
1406 PartialDescriptor->u.Port.Length = 7;
1407
1408 /* Set Interrupt */
1409 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
1410 PartialDescriptor->Type = CmResourceTypeInterrupt;
1411 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
1412 PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
1413 PartialDescriptor->u.Interrupt.Level = Irq[i];
1414 PartialDescriptor->u.Interrupt.Vector = Irq[i];
1415 PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
1416
1417 /* Set serial data (device specific) */
1418 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
1419 PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
1420 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
1421 PartialDescriptor->Flags = 0;
1422 PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_SERIAL_DEVICE_DATA);
1423
1424 SerialDeviceData =
1425 (PCM_SERIAL_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[3];
1426 SerialDeviceData->BaudClock = 1843200; /* UART Clock frequency (Hertz) */
1427
1428 /* Set 'Configuration Data' value */
1429 Error = RegSetValue(ControllerKey,
1430 "Configuration Data",
1431 REG_FULL_RESOURCE_DESCRIPTOR,
1432 (PU8) FullResourceDescriptor,
1433 Size);
1434 MmFreeMemory(FullResourceDescriptor);
1435 if (Error != ERROR_SUCCESS)
1436 {
1437 DbgPrint((DPRINT_HWDETECT,
1438 "RegSetValue(Configuration Data) failed (Error %u)\n",
1439 (int)Error));
1440 }
1441
1442 /* Set 'Identifier' value */
1443 sprintf(Buffer,
1444 "COM%u",
1445 i + 1);
1446 Error = RegSetValue(ControllerKey,
1447 "Identifier",
1448 REG_SZ,
1449 (PU8)Buffer,
1450 5);
1451 if (Error != ERROR_SUCCESS)
1452 {
1453 DbgPrint((DPRINT_HWDETECT,
1454 "RegSetValue() failed (Error %u)\n",
1455 (int)Error));
1456 continue;
1457 }
1458 DbgPrint((DPRINT_HWDETECT,
1459 "Created value: Identifier %s\n",
1460 Buffer));
1461
1462 /* Detect serial mouse */
1463 DetectSerialPointerPeripheral(ControllerKey, Base[i]);
1464
1465 ControllerNumber++;
1466 }
1467 }
1468 }
1469
1470
1471 static BOOLEAN
1472 DetectKeyboardDevice(VOID)
1473 {
1474 UCHAR Status;
1475 UCHAR Scancode;
1476
1477 WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
1478 0xF2);
1479
1480 KeStallExecutionProcessor(10000);
1481
1482 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1483 if ((Status & 0x01) != 0x01)
1484 {
1485 /* PC/XT keyboard or no keyboard */
1486 return FALSE;
1487 }
1488
1489 Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
1490 if (Scancode != 0xFA)
1491 {
1492 /* No ACK received */
1493 return FALSE;
1494 }
1495
1496 KeStallExecutionProcessor(10000);
1497 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1498 if ((Status & 0x01) != 0x01)
1499 {
1500 /* Found AT keyboard */
1501 return TRUE;
1502 }
1503
1504 Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
1505 if (Scancode != 0xAB)
1506 {
1507 /* No 0xAB received */
1508 return FALSE;
1509 }
1510
1511 KeStallExecutionProcessor(10000);
1512 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1513 if ((Status & 0x01) != 0x01)
1514 {
1515 /* No byte in buffer */
1516 return FALSE;
1517 }
1518
1519 Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
1520 if (Scancode != 0x41)
1521 {
1522 /* No 0x41 received */
1523 return FALSE;
1524 }
1525
1526 /* Found MF-II keyboard */
1527 return TRUE;
1528 }
1529
1530
1531 static VOID
1532 DetectKeyboardPeripheral(HKEY ControllerKey)
1533 {
1534 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
1535 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
1536 PCM_KEYBOARD_DEVICE_DATA KeyboardData;
1537 HKEY PeripheralKey;
1538 char Buffer[80];
1539 U32 Size;
1540 S32 Error;
1541
1542 if (DetectKeyboardDevice())
1543 {
1544 /* Create controller key */
1545 Error = RegCreateKey(ControllerKey,
1546 "KeyboardPeripheral\\0",
1547 &PeripheralKey);
1548 if (Error != ERROR_SUCCESS)
1549 {
1550 DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
1551 return;
1552 }
1553 DbgPrint((DPRINT_HWDETECT, "Created key: KeyboardPeripheral\\0\n"));
1554
1555 /* Set 'ComponentInformation' value */
1556 SetComponentInformation(ControllerKey,
1557 0x28,
1558 0,
1559 0xFFFFFFFF);
1560
1561 /* Set 'Configuration Data' value */
1562 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
1563 sizeof(CM_KEYBOARD_DEVICE_DATA);
1564 FullResourceDescriptor = MmAllocateMemory(Size);
1565 if (FullResourceDescriptor == NULL)
1566 {
1567 DbgPrint((DPRINT_HWDETECT,
1568 "Failed to allocate resource descriptor\n"));
1569 return;
1570 }
1571
1572 /* Initialize resource descriptor */
1573 memset(FullResourceDescriptor, 0, Size);
1574 FullResourceDescriptor->InterfaceType = Isa;
1575 FullResourceDescriptor->BusNumber = 0;
1576 FullResourceDescriptor->PartialResourceList.Count = 1;
1577
1578 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
1579 PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
1580 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
1581 PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA);
1582
1583 KeyboardData = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
1584 KeyboardData->Version = 0;
1585 KeyboardData->Revision = 0;
1586 KeyboardData->Type = 4;
1587 KeyboardData->Subtype = 0;
1588 KeyboardData->KeyboardFlags = 0x20;
1589
1590 /* Set 'Configuration Data' value */
1591 Error = RegSetValue(PeripheralKey,
1592 "Configuration Data",
1593 REG_FULL_RESOURCE_DESCRIPTOR,
1594 (PU8)FullResourceDescriptor,
1595 Size);
1596 MmFreeMemory(FullResourceDescriptor);
1597 if (Error != ERROR_SUCCESS)
1598 {
1599 DbgPrint((DPRINT_HWDETECT,
1600 "RegSetValue(Configuration Data) failed (Error %u)\n",
1601 (int)Error));
1602 }
1603
1604 /* Set 'Identifier' value */
1605 strcpy(Buffer,
1606 "PCAT_ENHANCED");
1607 Error = RegSetValue(ControllerKey,
1608 "Identifier",
1609 REG_SZ,
1610 (PU8)Buffer,
1611 strlen(Buffer) + 1);
1612 if (Error != ERROR_SUCCESS)
1613 {
1614 DbgPrint((DPRINT_HWDETECT,
1615 "RegSetValue() failed (Error %u)\n",
1616 (int)Error));
1617 }
1618 }
1619 }
1620
1621
1622 static VOID
1623 DetectKeyboardController(HKEY BusKey)
1624 {
1625 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
1626 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
1627 HKEY ControllerKey;
1628 U32 Size;
1629 S32 Error;
1630
1631 /* Create controller key */
1632 Error = RegCreateKey(BusKey,
1633 "KeyboardController\\0",
1634 &ControllerKey);
1635 if (Error != ERROR_SUCCESS)
1636 {
1637 DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
1638 return;
1639 }
1640 DbgPrint((DPRINT_HWDETECT, "Created key: KeyboardController\\0\n"));
1641
1642 /* Set 'ComponentInformation' value */
1643 SetComponentInformation(ControllerKey,
1644 0x28,
1645 0,
1646 0xFFFFFFFF);
1647
1648 /* Set 'Configuration Data' value */
1649 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
1650 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
1651 FullResourceDescriptor = MmAllocateMemory(Size);
1652 if (FullResourceDescriptor == NULL)
1653 {
1654 DbgPrint((DPRINT_HWDETECT,
1655 "Failed to allocate resource descriptor\n"));
1656 return;
1657 }
1658
1659 /* Initialize resource descriptor */
1660 memset(FullResourceDescriptor, 0, Size);
1661 FullResourceDescriptor->InterfaceType = Isa;
1662 FullResourceDescriptor->BusNumber = 0;
1663 FullResourceDescriptor->PartialResourceList.Count = 3;
1664
1665 /* Set Interrupt */
1666 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
1667 PartialDescriptor->Type = CmResourceTypeInterrupt;
1668 PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
1669 PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
1670 PartialDescriptor->u.Interrupt.Level = 1;
1671 PartialDescriptor->u.Interrupt.Vector = 1;
1672 PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
1673
1674 /* Set IO Port 0x60 */
1675 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
1676 PartialDescriptor->Type = CmResourceTypePort;
1677 PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1678 PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
1679 PartialDescriptor->u.Port.Start = (U64)0x60;
1680 PartialDescriptor->u.Port.Length = 1;
1681
1682 /* Set IO Port 0x64 */
1683 PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
1684 PartialDescriptor->Type = CmResourceTypePort;
1685 PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1686 PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
1687 PartialDescriptor->u.Port.Start = (U64)0x64;
1688 PartialDescriptor->u.Port.Length = 1;
1689
1690 /* Set 'Configuration Data' value */
1691 Error = RegSetValue(ControllerKey,
1692 "Configuration Data",
1693 REG_FULL_RESOURCE_DESCRIPTOR,
1694 (PU8)FullResourceDescriptor,
1695 Size);
1696 MmFreeMemory(FullResourceDescriptor);
1697 if (Error != ERROR_SUCCESS)
1698 {
1699 DbgPrint((DPRINT_HWDETECT,
1700 "RegSetValue(Configuration Data) failed (Error %u)\n",
1701 (int)Error));
1702 return;
1703 }
1704
1705 DetectKeyboardPeripheral(ControllerKey);
1706 }
1707
1708
1709 static VOID
1710 PS2ControllerWait(VOID)
1711 {
1712 U32 Timeout;
1713 U8 Status;
1714
1715 for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
1716 {
1717 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1718 if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
1719 return;
1720
1721 /* Sleep for one millisecond */
1722 KeStallExecutionProcessor(1000);
1723 }
1724 }
1725
1726
1727 static BOOLEAN
1728 DetectPS2AuxPort(VOID)
1729 {
1730 U32 Loops;
1731 U8 Scancode;
1732 U8 Status;
1733
1734 /* Put the value 0x5A in the output buffer using the
1735 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1736 * Poll the Status Register for a while to see if the value really turns up
1737 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1738 * to 1 in the Status Register, we assume this controller has an
1739 * Auxiliary Port (a.k.a. Mouse Port).
1740 */
1741 PS2ControllerWait();
1742 WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
1743 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
1744 PS2ControllerWait();
1745
1746 /* 0x5A is a random dummy value */
1747 WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
1748 0x5A);
1749
1750 for (Loops = 0; Loops < 10; Loops++)
1751 {
1752 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1753
1754 if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
1755 {
1756 Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
1757 if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
1758 {
1759 return TRUE;
1760 }
1761 break;
1762 }
1763
1764 KeStallExecutionProcessor(10000);
1765 }
1766
1767 return FALSE;
1768 }
1769
1770
1771 static BOOLEAN
1772 DetectPS2AuxDevice(VOID)
1773 {
1774 U8 Scancode;
1775 U8 Status;
1776
1777 PS2ControllerWait();
1778 WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
1779 CONTROLLER_COMMAND_WRITE_MOUSE);
1780 PS2ControllerWait();
1781
1782 /* Identify device */
1783 WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
1784 0xF2);
1785
1786 KeStallExecutionProcessor(10000);
1787
1788 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1789 if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
1790 {
1791 return FALSE;
1792 }
1793
1794 Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
1795 if (Scancode != 0xFA)
1796 return FALSE;
1797
1798 KeStallExecutionProcessor(10000);
1799
1800 Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
1801 if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
1802 {
1803 return FALSE;
1804 }
1805
1806 Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
1807 if (Scancode != 0x00)
1808 return FALSE;
1809
1810 return TRUE;
1811 }
1812
1813
1814 static VOID
1815 DetectPS2Mouse(HKEY BusKey)
1816 {
1817 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
1818 HKEY ControllerKey;
1819 HKEY PeripheralKey;
1820 S32 Error;
1821
1822 if (DetectPS2AuxPort())
1823 {
1824 DbgPrint((DPRINT_HWDETECT, "Detected PS2 port\n"));
1825
1826 /* Create controller key */
1827 Error = RegCreateKey(BusKey,
1828 "PointerController\\0",
1829 &ControllerKey);
1830 if (Error != ERROR_SUCCESS)
1831 {
1832 DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
1833 return;
1834 }
1835 DbgPrint((DPRINT_HWDETECT, "Created key: PointerController\\0\n"));
1836
1837 /* Set 'ComponentInformation' value */
1838 SetComponentInformation(ControllerKey,
1839 0x20,
1840 0,
1841 0xFFFFFFFF);
1842
1843 memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
1844
1845 /* Initialize resource descriptor */
1846 FullResourceDescriptor.InterfaceType = Isa;
1847 FullResourceDescriptor.BusNumber = 0;
1848 FullResourceDescriptor.PartialResourceList.Count = 1;
1849
1850 /* Set Interrupt */
1851 FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeInterrupt;
1852 FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
1853 FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
1854 FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12;
1855 FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 12;
1856 FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
1857
1858 /* Set 'Configuration Data' value */
1859 Error = RegSetValue(ControllerKey,
1860 "Configuration Data",
1861 REG_FULL_RESOURCE_DESCRIPTOR,
1862 (PU8)&FullResourceDescriptor,
1863 sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
1864 if (Error != ERROR_SUCCESS)
1865 {
1866 DbgPrint((DPRINT_HWDETECT,
1867 "RegSetValue(Configuration Data) failed (Error %u)\n",
1868 (int)Error));
1869 return;
1870 }
1871
1872
1873 if (DetectPS2AuxDevice())
1874 {
1875 DbgPrint((DPRINT_HWDETECT, "Detected PS2 mouse\n"));
1876
1877 /* Create peripheral key */
1878 Error = RegCreateKey(ControllerKey,
1879 "PointerPeripheral\\0",
1880 &PeripheralKey);
1881 if (Error != ERROR_SUCCESS)
1882 {
1883 DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
1884 return;
1885 }
1886 DbgPrint((DPRINT_HWDETECT, "Created key: PointerPeripheral\\0\n"));
1887
1888 /* Set 'ComponentInformation' value */
1889 SetComponentInformation(PeripheralKey,
1890 0x20,
1891 0,
1892 0xFFFFFFFF);
1893
1894 /* Initialize resource descriptor */
1895 memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
1896 FullResourceDescriptor.InterfaceType = Isa;
1897 FullResourceDescriptor.BusNumber = 0;
1898 FullResourceDescriptor.PartialResourceList.Count = 0;
1899
1900 /* Set 'Configuration Data' value */
1901 Error = RegSetValue(PeripheralKey,
1902 "Configuration Data",
1903 REG_FULL_RESOURCE_DESCRIPTOR,
1904 (PU8)&FullResourceDescriptor,
1905 sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
1906 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
1907 if (Error != ERROR_SUCCESS)
1908 {
1909 DbgPrint((DPRINT_HWDETECT,
1910 "RegSetValue(Configuration Data) failed (Error %u)\n",
1911 (int)Error));
1912 return;
1913 }
1914
1915 /* Set 'Identifier' value */
1916 Error = RegSetValue(PeripheralKey,
1917 "Identifier",
1918 REG_SZ,
1919 (PU8)"MICROSOFT PS2 MOUSE",
1920 20);
1921 if (Error != ERROR_SUCCESS)
1922 {
1923 DbgPrint((DPRINT_HWDETECT,
1924 "RegSetValue() failed (Error %u)\n",
1925 (int)Error));
1926 return;
1927 }
1928 }
1929 }
1930 }
1931
1932
1933 static VOID
1934 DetectIsaBios(HKEY SystemKey, U32 *BusNumber)
1935 {
1936 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
1937 char Buffer[80];
1938 HKEY BusKey;
1939 U32 Size;
1940 S32 Error;
1941
1942 /* Create new bus key */
1943 sprintf(Buffer,
1944 "MultifunctionAdapter\\%u", *BusNumber);
1945 Error = RegCreateKey(SystemKey,
1946 Buffer,
1947 &BusKey);
1948 if (Error != ERROR_SUCCESS)
1949 {
1950 DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
1951 return;
1952 }
1953
1954 /* Set 'Component Information' value similar to my NT4 box */
1955 SetComponentInformation(BusKey,
1956 0x0,
1957 0x0,
1958 0xFFFFFFFF);
1959
1960 /* Increment bus number */
1961 (*BusNumber)++;
1962
1963 /* Set 'Identifier' value */
1964 Error = RegSetValue(BusKey,
1965 "Identifier",
1966 REG_SZ,
1967 (PU8)"ISA",
1968 4);
1969 if (Error != ERROR_SUCCESS)
1970 {
1971 DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
1972 return;
1973 }
1974
1975 /* Set 'Configuration Data' value */
1976 Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
1977 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
1978 FullResourceDescriptor = MmAllocateMemory(Size);
1979 if (FullResourceDescriptor == NULL)
1980 {
1981 DbgPrint((DPRINT_HWDETECT,
1982 "Failed to allocate resource descriptor\n"));
1983 return;
1984 }
1985
1986 /* Initialize resource descriptor */
1987 memset(FullResourceDescriptor, 0, Size);
1988 FullResourceDescriptor->InterfaceType = Isa;
1989 FullResourceDescriptor->BusNumber = 0;
1990 FullResourceDescriptor->PartialResourceList.Count = 0;
1991
1992 /* Set 'Configuration Data' value */
1993 Error = RegSetValue(BusKey,
1994 "Configuration Data",
1995 REG_FULL_RESOURCE_DESCRIPTOR,
1996 (PU8) FullResourceDescriptor,
1997 Size);
1998 MmFreeMemory(FullResourceDescriptor);
1999 if (Error != ERROR_SUCCESS)
2000 {
2001 DbgPrint((DPRINT_HWDETECT,
2002 "RegSetValue(Configuration Data) failed (Error %u)\n",
2003 (int)Error));
2004 return;
2005 }
2006
2007 /* Detect ISA/BIOS devices */
2008 DetectBiosDisks(SystemKey, BusKey);
2009
2010 DetectBiosFloppyController(SystemKey, BusKey);
2011
2012 DetectSerialPorts(BusKey);
2013
2014 #if 0
2015 DetectParallelPorts(BusKey);
2016 #endif
2017
2018 DetectKeyboardController(BusKey);
2019
2020 DetectPS2Mouse(BusKey);
2021
2022 /* FIXME: Detect more ISA devices */
2023 }
2024
2025
2026 VOID
2027 DetectHardware(VOID)
2028 {
2029 HKEY SystemKey;
2030 U32 BusNumber = 0;
2031 S32 Error;
2032
2033 DbgPrint((DPRINT_HWDETECT, "DetectHardware()\n"));
2034
2035 HalpCalibrateStallExecution ();
2036
2037 /* Create the 'System' key */
2038 Error = RegCreateKey(NULL,
2039 "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
2040 &SystemKey);
2041 if (Error != ERROR_SUCCESS)
2042 {
2043 DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
2044 return;
2045 }
2046
2047 #if 0
2048 DetectSystemData();
2049 #endif
2050 DetectCPUs(SystemKey);
2051
2052 /* Detect buses */
2053 #if 0
2054 DetectPciBios(&BusNumber);
2055 DetectApmBios(&BusNumber);
2056 #endif
2057 DetectPnpBios(SystemKey, &BusNumber);
2058 DetectIsaBios(SystemKey, &BusNumber);
2059 #if 0
2060 DetectAcpiBios(&BusNumber);
2061 #endif
2062
2063
2064 DbgPrint((DPRINT_HWDETECT, "DetectHardware() Done\n"));
2065
2066 #if 0
2067 printf("*** System stopped ***\n");
2068 for (;;);
2069 #endif
2070 }
2071
2072 /* EOF */