4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 DBG_DEFAULT_CHANNEL(HWDETECT
);
26 static CHAR Hex
[] = "0123456789ABCDEF";
27 //static unsigned int delay_count = 1;
29 extern ULONG reactos_disk_count
;
30 extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info
[];
33 PCM_PARTIAL_RESOURCE_LIST
34 GetHarddiskConfigurationData(UCHAR DriveNumber
, ULONG
* pSize
)
36 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
37 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
38 //EXTENDED_GEOMETRY ExtGeometry;
43 // Initialize returned size
47 /* Set 'Configuration Data' value */
48 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
49 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
50 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
51 if (PartialResourceList
== NULL
)
53 ERR("Failed to allocate a full resource descriptor\n");
57 memset(PartialResourceList
, 0, Size
);
58 PartialResourceList
->Version
= 1;
59 PartialResourceList
->Revision
= 1;
60 PartialResourceList
->Count
= 1;
61 PartialResourceList
->PartialDescriptors
[0].Type
=
62 CmResourceTypeDeviceSpecific
;
63 // PartialResourceList->PartialDescriptors[0].ShareDisposition =
64 // PartialResourceList->PartialDescriptors[0].Flags =
65 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
66 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
68 /* Get pointer to geometry data */
69 DiskGeometry
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
71 /* Get the disk geometry */
72 //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
74 if (MachDiskGetDriveGeometry(DriveNumber
, &Geometry
))
76 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
77 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
78 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
79 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
83 ERR("Reading disk geometry failed\n");
84 FrLdrHeapFree(PartialResourceList
, TAG_HW_RESOURCE_LIST
);
87 TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
89 DiskGeometry
->NumberOfCylinders
,
90 DiskGeometry
->NumberOfHeads
,
91 DiskGeometry
->SectorsPerTrack
,
92 DiskGeometry
->BytesPerSector
);
95 // Return configuration data
98 return PartialResourceList
;
101 typedef struct tagDISKCONTEXT
105 ULONGLONG SectorOffset
;
106 ULONGLONG SectorCount
;
107 ULONGLONG SectorNumber
;
112 DiskClose(ULONG FileId
)
114 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
116 FrLdrTempFree(Context
, TAG_HW_DISK_CONTEXT
);
122 DiskGetFileInformation(ULONG FileId
, FILEINFORMATION
* Information
)
124 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
126 RtlZeroMemory(Information
, sizeof(FILEINFORMATION
));
127 Information
->EndingAddress
.QuadPart
= (Context
->SectorOffset
+ Context
->SectorCount
) * Context
->SectorSize
;
128 Information
->CurrentAddress
.QuadPart
= (Context
->SectorOffset
+ Context
->SectorNumber
) * Context
->SectorSize
;
135 DiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
137 DISKCONTEXT
* Context
;
138 ULONG DrivePartition
, SectorSize
;
140 ULONGLONG SectorOffset
= 0;
141 ULONGLONG SectorCount
= 0;
142 PARTITION_TABLE_ENTRY PartitionTableEntry
;
145 if (!DissectArcPath(Path
, FileName
, &DriveNumber
, &DrivePartition
))
148 if (DrivePartition
== 0xff)
150 /* This is a CD-ROM device */
155 /* This is either a floppy disk device (DrivePartition == 0) or
156 * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
157 * it doesn't matter which one because they both have 512 bytes per sector */
161 if (DrivePartition
!= 0xff && DrivePartition
!= 0)
163 if (!XboxDiskGetPartitionEntry(DriveNumber
, DrivePartition
, &PartitionTableEntry
))
165 SectorOffset
= PartitionTableEntry
.SectorCountBeforePartition
;
166 SectorCount
= PartitionTableEntry
.PartitionSectorCount
;
170 SectorCount
= 0; /* FIXME */
173 Context
= FrLdrTempAlloc(sizeof(DISKCONTEXT
), TAG_HW_DISK_CONTEXT
);
176 Context
->DriveNumber
= DriveNumber
;
177 Context
->SectorSize
= SectorSize
;
178 Context
->SectorOffset
= SectorOffset
;
179 Context
->SectorCount
= SectorCount
;
180 Context
->SectorNumber
= 0;
181 FsSetDeviceSpecific(*FileId
, Context
);
188 DiskRead(ULONG FileId
, VOID
* Buffer
, ULONG N
, ULONG
* Count
)
190 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
191 UCHAR
* Ptr
= (UCHAR
*)Buffer
;
192 ULONG i
, Length
, Sectors
;
200 if (Length
> DiskReadBufferSize
)
201 Length
= DiskReadBufferSize
;
202 Sectors
= (Length
+ Context
->SectorSize
- 1) / Context
->SectorSize
;
203 ret
= MachDiskReadLogicalSectors(
204 Context
->DriveNumber
,
205 Context
->SectorNumber
+ Context
->SectorOffset
+ i
,
210 RtlCopyMemory(Ptr
, DiskReadBuffer
, Length
);
222 DiskSeek(ULONG FileId
, LARGE_INTEGER
* Position
, SEEKMODE SeekMode
)
224 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
226 if (SeekMode
!= SeekAbsolute
)
228 if (Position
->LowPart
& (Context
->SectorSize
- 1))
231 /* FIXME: take HighPart into account */
232 Context
->SectorNumber
= Position
->LowPart
/ Context
->SectorSize
;
236 static const DEVVTBL DiskVtbl
=
239 DiskGetFileInformation
,
247 GetHarddiskIdentifier(PCHAR Identifier
,
250 PMASTER_BOOT_RECORD Mbr
;
255 CHAR ArcName
[MAX_PATH
];
256 PARTITION_TABLE_ENTRY PartitionTableEntry
;
259 if (!MachDiskReadLogicalSectors(DriveNumber
, 0ULL, 1, DiskReadBuffer
))
261 ERR("Reading MBR failed\n");
265 Buffer
= (ULONG
*)DiskReadBuffer
;
266 Mbr
= (PMASTER_BOOT_RECORD
)DiskReadBuffer
;
268 Signature
= Mbr
->Signature
;
269 TRACE("Signature: %x\n", Signature
);
271 /* Calculate the MBR checksum */
273 for (i
= 0; i
< 512 / sizeof(ULONG
); i
++)
275 Checksum
+= Buffer
[i
];
277 Checksum
= ~Checksum
+ 1;
278 TRACE("Checksum: %x\n", Checksum
);
280 /* Fill out the ARC disk block */
281 reactos_arc_disk_info
[reactos_disk_count
].DiskSignature
.Signature
= Signature
;
282 reactos_arc_disk_info
[reactos_disk_count
].DiskSignature
.CheckSum
= Checksum
;
283 sprintf(ArcName
, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count
);
284 strcpy(reactos_arc_disk_info
[reactos_disk_count
].ArcName
, ArcName
);
285 reactos_arc_disk_info
[reactos_disk_count
].DiskSignature
.ArcName
=
286 reactos_arc_disk_info
[reactos_disk_count
].ArcName
;
287 reactos_disk_count
++;
289 sprintf(ArcName
, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber
- 0x80);
290 FsRegisterDevice(ArcName
, &DiskVtbl
);
294 DiskReportError(FALSE
);
295 while (XboxDiskGetPartitionEntry(DriveNumber
, i
, &PartitionTableEntry
))
297 if (PartitionTableEntry
.SystemIndicator
!= PARTITION_ENTRY_UNUSED
)
299 sprintf(ArcName
, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber
- 0x80, i
);
300 FsRegisterDevice(ArcName
, &DiskVtbl
);
304 DiskReportError(TRUE
);
306 /* Convert checksum and signature to identifier string */
307 Identifier
[0] = Hex
[(Checksum
>> 28) & 0x0F];
308 Identifier
[1] = Hex
[(Checksum
>> 24) & 0x0F];
309 Identifier
[2] = Hex
[(Checksum
>> 20) & 0x0F];
310 Identifier
[3] = Hex
[(Checksum
>> 16) & 0x0F];
311 Identifier
[4] = Hex
[(Checksum
>> 12) & 0x0F];
312 Identifier
[5] = Hex
[(Checksum
>> 8) & 0x0F];
313 Identifier
[6] = Hex
[(Checksum
>> 4) & 0x0F];
314 Identifier
[7] = Hex
[Checksum
& 0x0F];
316 Identifier
[9] = Hex
[(Signature
>> 28) & 0x0F];
317 Identifier
[10] = Hex
[(Signature
>> 24) & 0x0F];
318 Identifier
[11] = Hex
[(Signature
>> 20) & 0x0F];
319 Identifier
[12] = Hex
[(Signature
>> 16) & 0x0F];
320 Identifier
[13] = Hex
[(Signature
>> 12) & 0x0F];
321 Identifier
[14] = Hex
[(Signature
>> 8) & 0x0F];
322 Identifier
[15] = Hex
[(Signature
>> 4) & 0x0F];
323 Identifier
[16] = Hex
[Signature
& 0x0F];
324 Identifier
[17] = '-';
325 Identifier
[18] = 'A';
327 TRACE("Identifier: %s\n", Identifier
);
332 DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey
,
333 PCONFIGURATION_COMPONENT_DATA BusKey
)
335 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
336 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
338 PCONFIGURATION_COMPONENT_DATA DiskKey
, ControllerKey
;
344 /* Count the number of visible drives */
345 DiskReportError(FALSE
);
348 /* There are some really broken BIOSes out there. There are even BIOSes
349 * that happily report success when you ask them to read from non-existent
350 * harddisks. So, we set the buffer to known contents first, then try to
351 * read. If the BIOS reports success but the buffer contents haven't
352 * changed then we fail anyway */
353 memset(DiskReadBuffer
, 0xcd, DiskReadBufferSize
);
354 while (MachDiskReadLogicalSectors(0x80 + DiskCount
, 0ULL, 1, DiskReadBuffer
))
357 for (i
= 0; ! Changed
&& i
< DiskReadBufferSize
; i
++)
359 Changed
= ((PUCHAR
)DiskReadBuffer
)[i
] != 0xcd;
363 TRACE("BIOS reports success for disk %d but data didn't change\n",
368 memset(DiskReadBuffer
, 0xcd, DiskReadBufferSize
);
370 DiskReportError(TRUE
);
371 TRACE("BIOS reports %d harddisk%s\n",
372 (int)DiskCount
, (DiskCount
== 1) ? "" : "s");
374 //DetectBiosFloppyController(BusKey);
376 /* Allocate resource descriptor */
377 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) +
378 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
379 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
380 if (PartialResourceList
== NULL
)
382 ERR("Failed to allocate resource descriptor\n");
386 /* Initialize resource descriptor */
387 memset(PartialResourceList
, 0, Size
);
388 PartialResourceList
->Version
= 1;
389 PartialResourceList
->Revision
= 1;
390 PartialResourceList
->Count
= 1;
391 PartialResourceList
->PartialDescriptors
[0].Type
= CmResourceTypeDeviceSpecific
;
392 PartialResourceList
->PartialDescriptors
[0].ShareDisposition
= 0;
393 PartialResourceList
->PartialDescriptors
[0].Flags
= 0;
394 PartialResourceList
->PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
395 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
397 /* Get harddisk Int13 geometry data */
398 Int13Drives
= (PVOID
)(((ULONG_PTR
)PartialResourceList
) + sizeof(CM_PARTIAL_RESOURCE_LIST
));
399 for (i
= 0; i
< DiskCount
; i
++)
401 if (MachDiskGetDriveGeometry(0x80 + i
, &Geometry
))
403 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
404 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
405 Int13Drives
[i
].SectorsPerTrack
= (USHORT
)Geometry
.Sectors
;
406 Int13Drives
[i
].MaxHeads
= (USHORT
)Geometry
.Heads
- 1;
407 Int13Drives
[i
].NumberDrives
= DiskCount
;
410 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
412 Geometry
.Cylinders
- 1,
415 Geometry
.BytesPerSector
);
419 FldrCreateComponentKey(BusKey
,
429 TRACE("Created key: DiskController\\0\n");
431 /* Create and fill subkey for each harddisk */
432 for (i
= 0; i
< DiskCount
; i
++)
436 /* Get disk values */
437 PartialResourceList
= GetHarddiskConfigurationData(0x80 + i
, &Size
);
438 GetHarddiskIdentifier(Identifier
, 0x80 + i
);
440 /* Create disk key */
441 FldrCreateComponentKey(ControllerKey
,
456 DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey
, ULONG
*BusNumber
)
458 PCM_PARTIAL_RESOURCE_LIST PartialResourceList
;
459 PCONFIGURATION_COMPONENT_DATA BusKey
;
462 /* Set 'Configuration Data' value */
463 Size
= sizeof(CM_PARTIAL_RESOURCE_LIST
) -
464 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
465 PartialResourceList
= FrLdrHeapAlloc(Size
, TAG_HW_RESOURCE_LIST
);
466 if (PartialResourceList
== NULL
)
469 "Failed to allocate resource descriptor\n");
473 /* Initialize resource descriptor */
474 memset(PartialResourceList
, 0, Size
);
475 PartialResourceList
->Version
= 1;
476 PartialResourceList
->Revision
= 1;
477 PartialResourceList
->Count
= 0;
479 /* Create new bus key */
480 FldrCreateComponentKey(SystemKey
,
482 MultiFunctionAdapter
,
491 /* Increment bus number */
494 /* Detect ISA/BIOS devices */
495 DetectBiosDisks(SystemKey
, BusKey
);
498 /* FIXME: Detect more ISA devices */
501 PCONFIGURATION_COMPONENT_DATA
504 PCONFIGURATION_COMPONENT_DATA SystemKey
;
507 TRACE("DetectHardware()\n");
509 /* Create the 'System' key */
510 FldrCreateSystemKey(&SystemKey
);
512 /* TODO: Build actual xbox's hardware configuration tree */
513 DetectIsaBios(SystemKey
, &BusNumber
);
515 TRACE("DetectHardware() Done\n");
520 XboxInitializeBootDevices(VOID
)
522 // Emulate old behavior
523 return XboxHwDetect() != NULL
;
526 VOID
XboxHwIdle(VOID
)