mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
- Detect PS/2 Port and Pointer Device (Mouse).
- Calculate CPU speed. - Fixed delay counter overrun. svn path=/trunk/; revision=7131
This commit is contained in:
parent
57af3eb9c8
commit
8bb5ad2bd8
6 changed files with 363 additions and 15 deletions
|
@ -1,3 +1,9 @@
|
|||
Changes in v1.8.19 (12/20/2003) (ekohl)
|
||||
|
||||
- Detect PS/2 Port and Pointer Device (Mouse).
|
||||
- Calculate CPU speed.
|
||||
- Fixed delay counter overrun.
|
||||
|
||||
Changes in v1.8.18 (12/14/2003) (ekohl)
|
||||
|
||||
- Detect serial ports and serial pointer devices (Mice/Trackballs)
|
||||
|
|
|
@ -50,6 +50,42 @@
|
|||
#define MOUSE_TYPE_MOUSESYSTEMS 4
|
||||
|
||||
|
||||
/* PS2 stuff */
|
||||
|
||||
/* Controller registers. */
|
||||
#define CONTROLLER_REGISTER_STATUS 0x64
|
||||
#define CONTROLLER_REGISTER_CONTROL 0x64
|
||||
#define CONTROLLER_REGISTER_DATA 0x60
|
||||
|
||||
/* Controller commands. */
|
||||
#define CONTROLLER_COMMAND_READ_MODE 0x20
|
||||
#define CONTROLLER_COMMAND_WRITE_MODE 0x60
|
||||
#define CONTROLLER_COMMAND_GET_VERSION 0xA1
|
||||
#define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
|
||||
#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
|
||||
#define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
|
||||
#define CONTROLLER_COMMAND_SELF_TEST 0xAA
|
||||
#define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
|
||||
#define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
|
||||
#define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
|
||||
#define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
|
||||
#define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
|
||||
|
||||
/* Controller status */
|
||||
#define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
|
||||
#define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
|
||||
#define CONTROLLER_STATUS_SELF_TEST 0x04
|
||||
#define CONTROLLER_STATUS_COMMAND 0x08
|
||||
#define CONTROLLER_STATUS_UNLOCKED 0x10
|
||||
#define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
|
||||
#define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
|
||||
#define CONTROLLER_STATUS_PARITY_ERROR 0x80
|
||||
#define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
|
||||
CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
|
||||
|
||||
/* Timeout in ms for sending to keyboard controller. */
|
||||
#define CONTROLLER_TIMEOUT 250
|
||||
|
||||
|
||||
typedef struct _CM_INT13_DRIVE_PARAMETER
|
||||
{
|
||||
|
@ -122,7 +158,8 @@ __KeStallExecutionProcessor(U32 Loops)
|
|||
|
||||
VOID KeStallExecutionProcessor(U32 Microseconds)
|
||||
{
|
||||
__KeStallExecutionProcessor((delay_count * Microseconds) / 1000);
|
||||
U64 LoopCount = ((U64)delay_count * (U64)Microseconds) / 1000ULL;
|
||||
__KeStallExecutionProcessor((U32)LoopCount);
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,7 +251,6 @@ HalpCalibrateStallExecution(VOID)
|
|||
}
|
||||
|
||||
/* We're finished: Do the finishing touches */
|
||||
|
||||
delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
|
||||
}
|
||||
|
||||
|
@ -991,7 +1027,8 @@ DetectSerialPointerPeripheral(HKEY ControllerKey,
|
|||
"Configuration Data",
|
||||
REG_FULL_RESOURCE_DESCRIPTOR,
|
||||
(PU8)&FullResourceDescriptor,
|
||||
sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
|
||||
sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
|
||||
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
|
@ -1016,8 +1053,7 @@ DetectSerialPointerPeripheral(HKEY ControllerKey,
|
|||
|
||||
|
||||
static VOID
|
||||
DetectSerialPorts(HKEY SystemKey,
|
||||
HKEY BusKey)
|
||||
DetectSerialPorts(HKEY BusKey)
|
||||
{
|
||||
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||
|
@ -1153,6 +1189,230 @@ DetectSerialPorts(HKEY SystemKey,
|
|||
}
|
||||
|
||||
|
||||
static VOID
|
||||
PS2ControllerWait(VOID)
|
||||
{
|
||||
U32 Timeout;
|
||||
U8 Status;
|
||||
|
||||
for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
|
||||
{
|
||||
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
|
||||
if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
|
||||
return;
|
||||
|
||||
/* Sleep for one millisecond */
|
||||
KeStallExecutionProcessor(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
DetectPS2AuxPort(VOID)
|
||||
{
|
||||
U32 Loops;
|
||||
U8 Scancode;
|
||||
U8 Status;
|
||||
|
||||
/* Put the value 0x5A in the output buffer using the
|
||||
* "WriteAuxiliary Device Output Buffer" command (0xD3).
|
||||
* Poll the Status Register for a while to see if the value really turns up
|
||||
* in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
|
||||
* to 1 in the Status Register, we assume this controller has an
|
||||
* Auxiliary Port (a.k.a. Mouse Port).
|
||||
*/
|
||||
PS2ControllerWait();
|
||||
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
|
||||
CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
|
||||
PS2ControllerWait();
|
||||
|
||||
/* 0x5A is a random dummy value */
|
||||
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
|
||||
0x5A);
|
||||
|
||||
for (Loops = 0; Loops < 10; Loops++)
|
||||
{
|
||||
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
|
||||
|
||||
if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
|
||||
{
|
||||
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
|
||||
if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
KeStallExecutionProcessor(10000);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
DetectPS2AuxDevice(VOID)
|
||||
{
|
||||
U8 Scancode;
|
||||
U8 Status;
|
||||
|
||||
PS2ControllerWait();
|
||||
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
|
||||
CONTROLLER_COMMAND_WRITE_MOUSE);
|
||||
PS2ControllerWait();
|
||||
|
||||
/* Identify device */
|
||||
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
|
||||
0xF2);
|
||||
|
||||
KeStallExecutionProcessor(10000);
|
||||
|
||||
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
|
||||
if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
|
||||
if (Scancode != 0xFA)
|
||||
return FALSE;
|
||||
|
||||
KeStallExecutionProcessor(10000);
|
||||
|
||||
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
|
||||
if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
|
||||
if (Scancode != 0x00)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectPS2Mouse(HKEY BusKey)
|
||||
{
|
||||
CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
|
||||
HKEY ControllerKey;
|
||||
HKEY PeripheralKey;
|
||||
S32 Error;
|
||||
|
||||
if (DetectPS2AuxPort())
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Detected PS2 port\n"));
|
||||
|
||||
/* Create controller key */
|
||||
Error = RegCreateKey(BusKey,
|
||||
"PointerController\\0",
|
||||
&ControllerKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
|
||||
return;
|
||||
}
|
||||
DbgPrint((DPRINT_HWDETECT, "Created key: PointerController\\0\n"));
|
||||
|
||||
/* Set 'ComponentInformation' value */
|
||||
SetComponentInformation(ControllerKey,
|
||||
0x20,
|
||||
0,
|
||||
0xFFFFFFFF);
|
||||
|
||||
memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
|
||||
|
||||
/* Initialize resource descriptor */
|
||||
FullResourceDescriptor.InterfaceType = Isa;
|
||||
FullResourceDescriptor.BusNumber = 0;
|
||||
FullResourceDescriptor.PartialResourceList.Count = 1;
|
||||
|
||||
/* Set Interrupt */
|
||||
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeInterrupt;
|
||||
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
|
||||
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
||||
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12;
|
||||
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 12;
|
||||
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
Error = RegSetValue(ControllerKey,
|
||||
"Configuration Data",
|
||||
REG_FULL_RESOURCE_DESCRIPTOR,
|
||||
(PU8)&FullResourceDescriptor,
|
||||
sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"RegSetValue(Configuration Data) failed (Error %u)\n",
|
||||
(int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (DetectPS2AuxDevice())
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Detected PS2 mouse\n"));
|
||||
|
||||
/* Create peripheral key */
|
||||
Error = RegCreateKey(ControllerKey,
|
||||
"PointerPeripheral\\0",
|
||||
&PeripheralKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
|
||||
return;
|
||||
}
|
||||
DbgPrint((DPRINT_HWDETECT, "Created key: PointerPeripheral\\0\n"));
|
||||
|
||||
/* Set 'ComponentInformation' value */
|
||||
SetComponentInformation(PeripheralKey,
|
||||
0x20,
|
||||
0,
|
||||
0xFFFFFFFF);
|
||||
|
||||
/* Initialize resource descriptor */
|
||||
memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
|
||||
FullResourceDescriptor.InterfaceType = Isa;
|
||||
FullResourceDescriptor.BusNumber = 0;
|
||||
FullResourceDescriptor.PartialResourceList.Count = 0;
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
Error = RegSetValue(PeripheralKey,
|
||||
"Configuration Data",
|
||||
REG_FULL_RESOURCE_DESCRIPTOR,
|
||||
(PU8)&FullResourceDescriptor,
|
||||
sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
|
||||
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"RegSetValue(Configuration Data) failed (Error %u)\n",
|
||||
(int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set 'Identifier' value */
|
||||
Error = RegSetValue(PeripheralKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)"MICROSOFT PS2 MOUSE",
|
||||
20);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"RegSetValue() failed (Error %u)\n",
|
||||
(int)Error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectIsaBios(HKEY SystemKey, U32 *BusNumber)
|
||||
{
|
||||
|
@ -1224,18 +1484,23 @@ DetectIsaBios(HKEY SystemKey, U32 *BusNumber)
|
|||
|
||||
/* Detect ISA/BIOS devices */
|
||||
DetectBiosDisks(SystemKey, BusKey);
|
||||
|
||||
#if 0
|
||||
DetectBiosFloppyDisks(SystemKey, BusKey);
|
||||
#endif
|
||||
|
||||
DetectSerialPorts(SystemKey, BusKey);
|
||||
DetectSerialPorts(BusKey);
|
||||
|
||||
#if 0
|
||||
DetectBiosParallelPorts();
|
||||
|
||||
DetectBiosKeyboard();
|
||||
DetectBiosMouse();
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
DetectBiosKeyboard(BusKey);
|
||||
#endif
|
||||
|
||||
DetectPS2Mouse(BusKey);
|
||||
|
||||
/* FIXME: Detect more ISA devices */
|
||||
}
|
||||
|
||||
|
@ -1280,10 +1545,10 @@ DetectHardware(VOID)
|
|||
|
||||
DbgPrint((DPRINT_HWDETECT, "DetectHardware() Done\n"));
|
||||
|
||||
#if 0
|
||||
//#if 0
|
||||
printf("*** System stopped ***\n");
|
||||
for (;;);
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -153,6 +153,8 @@ typedef struct _CM_COMPONENT_INFORMATION
|
|||
/* PROTOTYPES ***************************************************************/
|
||||
|
||||
/* hardware.c */
|
||||
VOID KeStallExecutionProcessor(U32 Microseconds);
|
||||
|
||||
VOID SetComponentInformation(HKEY ComponentKey,
|
||||
U32 Flags,
|
||||
U32 Key,
|
||||
|
@ -168,6 +170,7 @@ VOID GetCpuid(U32 Level,
|
|||
U32 *ebx,
|
||||
U32 *ecx,
|
||||
U32 *edx);
|
||||
U64 RDTSC(VOID);
|
||||
|
||||
/* i386pnp.S */
|
||||
U32 PnpBiosSupported(VOID);
|
||||
|
|
|
@ -77,6 +77,36 @@ typedef struct _MP_PROCESSOR_ENTRY
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static U32
|
||||
GetCpuSpeed(VOID)
|
||||
{
|
||||
U64 Timestamp1;
|
||||
U64 Timestamp2;
|
||||
U64 Diff;
|
||||
|
||||
/* Read TSC (Time Stamp Counter) */
|
||||
Timestamp1 = RDTSC();
|
||||
|
||||
/* Wait for 0.1 seconds (= 100 milliseconds = 100000 microseconds)*/
|
||||
KeStallExecutionProcessor(100000);
|
||||
|
||||
/* Read TSC (Time Stamp Counter) again */
|
||||
Timestamp2 = RDTSC();
|
||||
|
||||
/* Calculate elapsed time (check for counter overrun) */
|
||||
if (Timestamp2 > Timestamp1)
|
||||
{
|
||||
Diff = Timestamp2 - Timestamp1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Diff = Timestamp2 + (((U64)-1) - Timestamp1);
|
||||
}
|
||||
|
||||
return (U32)(Diff / 100000);
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectCPU(HKEY CpuKey,
|
||||
HKEY FpuKey)
|
||||
|
@ -92,6 +122,9 @@ DetectCPU(HKEY CpuKey,
|
|||
U32 edx = 0;
|
||||
U32 *Ptr;
|
||||
S32 Error;
|
||||
BOOL SupportTSC = FALSE;
|
||||
U32 CpuSpeed;
|
||||
|
||||
|
||||
/* Create the CPU instance key */
|
||||
Error = RegCreateKey(CpuKey,
|
||||
|
@ -136,6 +169,8 @@ DetectCPU(HKEY CpuKey,
|
|||
(unsigned int)((eax >> 4) & 0x0F),
|
||||
(unsigned int)(eax & 0x0F));
|
||||
FeatureSet = edx;
|
||||
if (((eax >> 8) & 0x0F) >= 5)
|
||||
SupportTSC = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -207,7 +242,21 @@ DetectCPU(HKEY CpuKey,
|
|||
|
||||
/* FIXME: Set 'Update Status' value (CPU only) */
|
||||
|
||||
/* FIXME: Set '~MHz' value (CPU only) */
|
||||
/* Set '~MHz' value (CPU only) */
|
||||
if (SupportTSC)
|
||||
{
|
||||
CpuSpeed = GetCpuSpeed();
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"~MHz",
|
||||
REG_DWORD,
|
||||
(PU8)&CpuSpeed,
|
||||
sizeof(U32));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -228,6 +277,7 @@ SetMpsProcessor(HKEY CpuKey,
|
|||
U32 edx = 0;
|
||||
U32 *Ptr;
|
||||
S32 Error;
|
||||
U32 CpuSpeed;
|
||||
|
||||
/* Get processor instance number */
|
||||
sprintf(Buffer, "%u", CpuEntry->LocalApicId);
|
||||
|
@ -336,7 +386,21 @@ SetMpsProcessor(HKEY CpuKey,
|
|||
|
||||
/* FIXME: Set 'Update Status' value (CPU only) */
|
||||
|
||||
/* FIXME: Set '~MHz' value (CPU only) */
|
||||
/* Set '~MHz' value (CPU only) */
|
||||
if (((CpuEntry->CpuSignature >> 8) & 0x0F) >= 5)
|
||||
{
|
||||
CpuSpeed = GetCpuSpeed();
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"~MHz",
|
||||
REG_DWORD,
|
||||
(PU8)&CpuSpeed,
|
||||
sizeof(U32));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -118,4 +118,14 @@ EXTERN(_GetCpuid)
|
|||
popl %ebp
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* U64 RDTSC(VOID);
|
||||
*/
|
||||
|
||||
EXTERN(_RDTSC)
|
||||
.code32
|
||||
rdtsc
|
||||
ret
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
|
||||
/* just some stuff */
|
||||
#define VERSION "FreeLoader v1.8.18"
|
||||
#define VERSION "FreeLoader v1.8.19"
|
||||
#define COPYRIGHT "Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>"
|
||||
#define AUTHOR_EMAIL "<brianp@sginet.com>"
|
||||
#define BY_AUTHOR "by Brian Palmer"
|
||||
|
@ -36,7 +36,7 @@
|
|||
//
|
||||
#define FREELOADER_MAJOR_VERSION 1
|
||||
#define FREELOADER_MINOR_VERSION 8
|
||||
#define FREELOADER_PATCH_VERSION 18
|
||||
#define FREELOADER_PATCH_VERSION 19
|
||||
|
||||
|
||||
#ifndef ASM
|
||||
|
|
Loading…
Reference in a new issue