Add keyboard detection.

svn path=/trunk/; revision=9690
This commit is contained in:
Eric Kohl 2004-06-16 20:21:20 +00:00
parent 0a30ec98a3
commit f38668e736

View file

@ -1,7 +1,7 @@
/*
* FreeLoader
*
* Copyright (C) 2003 Eric Kohl
* Copyright (C) 2003, 2004 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -167,6 +167,16 @@ typedef struct _CM_FLOPPY_DEVICE_DATA
} __attribute__((packed)) CM_FLOPPY_DEVICE_DATA, *PCM_FLOPPY_DEVICE_DATA;
typedef struct _CM_KEYBOARD_DEVICE_DATA
{
U16 Version;
U16 Revision;
U8 Type;
U8 Subtype;
U16 KeyboardFlags;
} __attribute__((packed)) CM_KEYBOARD_DEVICE_DATA, *PCM_KEYBOARD_DEVICE_DATA;
static char Hex[] = "0123456789ABCDEF";
static unsigned int delay_count = 1;
@ -885,7 +895,9 @@ DetectBiosFloppyController(HKEY SystemKey,
U32 FloppyCount;
FloppyCount = GetFloppyCount();
/* printf ("Floppy count: %u\n", FloppyCount);*/
DbgPrint((DPRINT_HWDETECT,
"Floppy count: %u\n",
FloppyCount));
if (FloppyCount == 0)
return;
@ -1456,6 +1468,244 @@ DetectSerialPorts(HKEY BusKey)
}
static BOOLEAN
DetectKeyboardDevice(VOID)
{
UCHAR Status;
UCHAR Scancode;
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
0xF2);
KeStallExecutionProcessor(10000);
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & 0x01) != 0x01)
{
/* PC/XT keyboard or no keyboard */
return FALSE;
}
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
if (Scancode != 0xFA)
{
/* No ACK received */
return FALSE;
}
KeStallExecutionProcessor(10000);
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & 0x01) != 0x01)
{
/* Found AT keyboard */
return TRUE;
}
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
if (Scancode != 0xAB)
{
/* No 0xAB received */
return FALSE;
}
KeStallExecutionProcessor(10000);
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & 0x01) != 0x01)
{
/* No byte in buffer */
return FALSE;
}
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
if (Scancode != 0x41)
{
/* No 0x41 received */
return FALSE;
}
/* Found MF-II keyboard */
return TRUE;
}
static VOID
DetectKeyboardPeripheral(HKEY ControllerKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PCM_KEYBOARD_DEVICE_DATA KeyboardData;
HKEY PeripheralKey;
char Buffer[80];
U32 Size;
S32 Error;
if (DetectKeyboardDevice())
{
/* Create controller key */
Error = RegCreateKey(ControllerKey,
"KeyboardPeripheral\\0",
&PeripheralKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: KeyboardPeripheral\\0\n"));
/* Set 'ComponentInformation' value */
SetComponentInformation(ControllerKey,
0x28,
0,
0xFFFFFFFF);
/* Set 'Configuration Data' value */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
sizeof(CM_KEYBOARD_DEVICE_DATA);
FullResourceDescriptor = MmAllocateMemory(Size);
if (FullResourceDescriptor == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(FullResourceDescriptor, 0, Size);
FullResourceDescriptor->InterfaceType = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Count = 1;
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA);
KeyboardData = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
KeyboardData->Version = 0;
KeyboardData->Revision = 0;
KeyboardData->Type = 4;
KeyboardData->Subtype = 0;
KeyboardData->KeyboardFlags = 0x20;
/* Set 'Configuration Data' value */
Error = RegSetValue(PeripheralKey,
"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PU8)FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
}
/* Set 'Identifier' value */
strcpy(Buffer,
"PCAT_ENHANCED");
Error = RegSetValue(ControllerKey,
"Identifier",
REG_SZ,
(PU8)Buffer,
strlen(Buffer) + 1);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue() failed (Error %u)\n",
(int)Error));
}
}
}
static VOID
DetectKeyboardController(HKEY BusKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
HKEY ControllerKey;
U32 Size;
S32 Error;
/* Create controller key */
Error = RegCreateKey(BusKey,
"KeyboardController\\0",
&ControllerKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: KeyboardController\\0\n"));
/* Set 'ComponentInformation' value */
SetComponentInformation(ControllerKey,
0x28,
0,
0xFFFFFFFF);
/* Set 'Configuration Data' value */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
FullResourceDescriptor = MmAllocateMemory(Size);
if (FullResourceDescriptor == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(FullResourceDescriptor, 0, Size);
FullResourceDescriptor->InterfaceType = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Count = 3;
/* Set Interrupt */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeInterrupt;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
PartialDescriptor->u.Interrupt.Level = 1;
PartialDescriptor->u.Interrupt.Vector = 1;
PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
/* Set IO Port 0x60 */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
PartialDescriptor->Type = CmResourceTypePort;
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
PartialDescriptor->u.Port.Start = (U64)0x60;
PartialDescriptor->u.Port.Length = 1;
/* Set IO Port 0x64 */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
PartialDescriptor->Type = CmResourceTypePort;
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
PartialDescriptor->u.Port.Start = (U64)0x64;
PartialDescriptor->u.Port.Length = 1;
/* Set 'Configuration Data' value */
Error = RegSetValue(ControllerKey,
"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PU8)FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
DetectKeyboardPeripheral(ControllerKey);
}
static VOID
PS2ControllerWait(VOID)
{
@ -1757,12 +2007,10 @@ DetectIsaBios(HKEY SystemKey, U32 *BusNumber)
DetectSerialPorts(BusKey);
#if 0
DetectBiosParallelPorts();
DetectParallelPorts(BusKey);
#endif
#if 0
DetectBiosKeyboard(BusKey);
#endif
DetectKeyboardController(BusKey);
DetectPS2Mouse(BusKey);