mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
581 lines
9.6 KiB
581 lines
9.6 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
Copyright (c) 1993 Digital Equipment Corporation
|
|
|
|
Module Name:
|
|
|
|
jxkbd.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the keyboard boot driver for the Jazz system.
|
|
|
|
Author:
|
|
|
|
David M. Robinson (davidro) 8-Aug-1991
|
|
|
|
Environment:
|
|
|
|
Kernel mode.
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
26-May-1992 John DeRosa [DEC]
|
|
|
|
Added Alpha/Jensen hooks. The Jensen firmware does not use any
|
|
interrupts. Additional keyboard changes are in fwsignal.c.
|
|
|
|
--*/
|
|
|
|
#include "fwp.h"
|
|
#include "iodevice.h"
|
|
#include "string.h"
|
|
#include "xxstring.h"
|
|
|
|
ARC_STATUS
|
|
KeyboardClose (
|
|
IN ULONG FileId
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardMount (
|
|
IN PCHAR MountPath,
|
|
IN MOUNT_OPERATION Operation
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardOpen (
|
|
IN PCHAR OpenPath,
|
|
IN OPEN_MODE OpenMode,
|
|
IN OUT PULONG FileId
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardRead (
|
|
IN ULONG FileId,
|
|
IN PVOID Buffer,
|
|
IN ULONG Length,
|
|
OUT PULONG Count
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardGetReadStatus (
|
|
IN ULONG FileId
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardSeek (
|
|
IN ULONG FileId,
|
|
IN PLARGE_INTEGER Offset,
|
|
IN SEEK_MODE SeekMode
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardWrite (
|
|
IN ULONG FileId,
|
|
IN PVOID Buffer,
|
|
IN ULONG Length,
|
|
OUT PULONG Count
|
|
);
|
|
|
|
ARC_STATUS
|
|
KeyboardGetFileInformation (
|
|
IN ULONG FileId,
|
|
OUT PFILE_INFORMATION Finfo
|
|
);
|
|
|
|
//
|
|
// Define static data.
|
|
//
|
|
BL_DEVICE_ENTRY_TABLE KeyboardEntryTable = {
|
|
KeyboardClose,
|
|
KeyboardMount,
|
|
KeyboardOpen,
|
|
KeyboardRead,
|
|
KeyboardGetReadStatus,
|
|
KeyboardSeek,
|
|
KeyboardWrite,
|
|
KeyboardGetFileInformation,
|
|
(PARC_SET_FILE_INFO_ROUTINE)NULL
|
|
};
|
|
|
|
KEYBOARD_BUFFER KbdBuffer;
|
|
|
|
BOOLEAN FwLeftShift;
|
|
BOOLEAN FwRightShift;
|
|
BOOLEAN FwControl;
|
|
BOOLEAN FwAlt;
|
|
BOOLEAN FwCapsLock;
|
|
|
|
|
|
//
|
|
// Define prototypes for all routines used by this module.
|
|
//
|
|
|
|
UCHAR
|
|
FwInputScanCode(
|
|
VOID
|
|
);
|
|
|
|
|
|
ARC_STATUS
|
|
KeyboardGetFileInformation (
|
|
IN ULONG FileId,
|
|
OUT PFILE_INFORMATION Finfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns EINVAL as no FileInformation can be
|
|
returned for the Keyboard driver.
|
|
|
|
Arguments:
|
|
|
|
The arguments are not used.
|
|
|
|
Return Value:
|
|
|
|
EINVAL is returned
|
|
|
|
--*/
|
|
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
|
|
ARC_STATUS
|
|
KeyboardClose (
|
|
IN ULONG FileId
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function closes the file table entry specified by the file id.
|
|
|
|
Arguments:
|
|
|
|
FileId - Supplies the file table index.
|
|
|
|
Return Value:
|
|
|
|
ESUCCESS is returned
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
BlFileTable[FileId].Flags.Open = 0;
|
|
return ESUCCESS;
|
|
}
|
|
|
|
ARC_STATUS
|
|
KeyboardMount (
|
|
IN PCHAR MountPath,
|
|
IN MOUNT_OPERATION Operation
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
return EINVAL;
|
|
}
|
|
|
|
ARC_STATUS
|
|
KeyboardOpen (
|
|
IN PCHAR OpenPath,
|
|
IN OPEN_MODE OpenMode,
|
|
IN OUT PULONG FileId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the open routine for the Keyboard device.
|
|
|
|
Arguments:
|
|
|
|
OpenPath - Supplies the pathname of the device to open.
|
|
|
|
OpenMode - Supplies the mode (read only, write only, or read write).
|
|
|
|
FileId - Supplies a free file identifier to use. If the device is already
|
|
open this parameter can be used to return the file identifier
|
|
already in use.
|
|
|
|
Return Value:
|
|
|
|
If the open was successful, ESUCCESS is returned, otherwise an error code
|
|
is returned.
|
|
|
|
--*/
|
|
{
|
|
PCONSOLE_CONTEXT Context;
|
|
|
|
Context = &BlFileTable[*FileId].u.ConsoleContext;
|
|
if ( strstr(OpenPath, ")console(1)" ) != NULL ) {
|
|
Context->ConsoleNumber = 1;
|
|
} else {
|
|
Context->ConsoleNumber = 0;
|
|
}
|
|
return ESUCCESS;
|
|
}
|
|
|
|
ARC_STATUS
|
|
KeyboardRead (
|
|
IN ULONG FileId,
|
|
IN PVOID Buffer,
|
|
IN ULONG Length,
|
|
OUT PULONG Count
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads keys from the keyboard and passes along either ascii
|
|
or Unicode characters to the caller.
|
|
|
|
In Alpha/Jensen, the polling is done in the FwInputScanCode() function.
|
|
|
|
|
|
Arguments:
|
|
|
|
FileId - Supplies a file id.
|
|
|
|
Buffer - Supplies a pointer to a buffer to receive the characters.
|
|
|
|
Length - Supplies the length of Buffer in bytes.
|
|
|
|
Count - Returns the count of the bytes that were received.
|
|
|
|
Return Value:
|
|
|
|
A value of ESUCCESS is returned.
|
|
|
|
--*/
|
|
{
|
|
PCHAR OutputBuffer;
|
|
PCONSOLE_CONTEXT Context;
|
|
BOOLEAN Unicode;
|
|
|
|
OutputBuffer = (PCHAR)Buffer;
|
|
Context = &BlFileTable[FileId].u.ConsoleContext;
|
|
|
|
if (Context->ConsoleNumber == 1) {
|
|
if (Length & 1) {
|
|
|
|
//
|
|
// Length is not an even number of bytes, return an error.
|
|
//
|
|
|
|
return(EINVAL);
|
|
}
|
|
Unicode = TRUE;
|
|
} else {
|
|
Unicode = FALSE;
|
|
}
|
|
|
|
*Count = 0;
|
|
while (*Count < Length) {
|
|
*OutputBuffer++ = FwInputScanCode();
|
|
(*Count)++;
|
|
if (Unicode) {
|
|
*OutputBuffer++ = 0;
|
|
(*Count)++;
|
|
}
|
|
}
|
|
return ESUCCESS;
|
|
}
|
|
|
|
|
|
ARC_STATUS
|
|
KeyboardGetReadStatus (
|
|
IN ULONG FileId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine checks to see if a character is available from the keyboard.
|
|
|
|
Arguments:
|
|
|
|
FileId - Supplies a file identifier.
|
|
|
|
Return Value:
|
|
|
|
Returns ESUCCESS is a byte is available, otherwise EAGAIN is returned.
|
|
|
|
--*/
|
|
{
|
|
|
|
#ifndef ALPHA
|
|
|
|
if (KbdBuffer.ReadIndex == KbdBuffer.WriteIndex) {
|
|
return EAGAIN;
|
|
} else {
|
|
return ESUCCESS;
|
|
}
|
|
|
|
#else
|
|
|
|
//
|
|
// Alpha does polling.
|
|
//
|
|
|
|
if (KbdBuffer.ReadIndex != KbdBuffer.WriteIndex) {
|
|
|
|
// A character is available
|
|
return ESUCCESS;
|
|
|
|
} else if (READ_PORT_UCHAR((PUCHAR)&KEYBOARD_READ->Status) & KBD_OBF_MASK) {
|
|
|
|
// A character is available at the keyboard, but it may be a
|
|
// character that is not returned to the calling program (e.g., a
|
|
// break code). Screen it here.
|
|
|
|
TranslateScanCode(READ_PORT_UCHAR((PUCHAR)&KEYBOARD_READ->Data));
|
|
if (KbdBuffer.ReadIndex != KbdBuffer.WriteIndex) {
|
|
// A character is now available
|
|
return ESUCCESS;
|
|
} else {
|
|
// A character is not available, let the user drain any other
|
|
// characters or non-characters by calling this again.
|
|
return EAGAIN;
|
|
}
|
|
|
|
} else {
|
|
|
|
// A character is not available
|
|
return EAGAIN;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
ARC_STATUS
|
|
KeyboardWrite (
|
|
IN ULONG FileId,
|
|
IN PVOID Buffer,
|
|
IN ULONG Length,
|
|
OUT PULONG Count
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
ESUCCESS is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
return ESUCCESS;
|
|
}
|
|
|
|
ARC_STATUS
|
|
KeyboardSeek (
|
|
IN ULONG FileId,
|
|
IN PLARGE_INTEGER Offset,
|
|
IN SEEK_MODE SeekMode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
ESUCCESS is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
return ESUCCESS;
|
|
}
|
|
|
|
VOID
|
|
KeyboardInitialize (
|
|
IN OUT PDRIVER_LOOKUP_ENTRY LookupTableEntry,
|
|
IN ULONG Entries
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the keyboard control registers, clears the
|
|
fifo, and initializes the keyboard entry in the driver lookup table.
|
|
|
|
Arguments:
|
|
|
|
LookupTableEntry - Supplies a pointer to the first free location in the
|
|
driver lookup table.
|
|
|
|
Entries - Supplies the number of free entries in the driver lookup table.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR Byte;
|
|
|
|
//
|
|
// Initialize the driver lookup table.
|
|
//
|
|
|
|
LookupTableEntry->DevicePath = FW_KEYBOARD_IN_DEVICE_PATH;
|
|
LookupTableEntry->DispatchTable = &KeyboardEntryTable;
|
|
|
|
//
|
|
// Initialize static data.
|
|
//
|
|
|
|
FwLeftShift = FALSE;
|
|
FwRightShift = FALSE;
|
|
FwControl = FALSE;
|
|
FwAlt = FALSE;
|
|
FwCapsLock = FALSE;
|
|
|
|
KbdBuffer.ReadIndex = KbdBuffer.WriteIndex = 0;
|
|
|
|
//
|
|
// Call the selftest keyboard initialization routine. If the keyboard
|
|
// is OK, enable interrupts.
|
|
//
|
|
|
|
if (!InitKeyboard()) {
|
|
|
|
//
|
|
// Enable kbd interrupts in the keyboard controller.
|
|
//
|
|
SendKbdCommand(KBD_CTR_READ_COMMAND);
|
|
GetKbdData(&Byte,100);
|
|
|
|
//
|
|
// Clear translation mode and enable Kbd interrupt.
|
|
//
|
|
Byte = (Byte & 0xBF) | KbdCommandEnableKbdInt;
|
|
SendKbdCommand(KBD_CTR_WRITE_COMMAND);
|
|
SendKbdData(Byte);
|
|
|
|
#ifndef ALPHA
|
|
//
|
|
// Not needed for Alpha.
|
|
//
|
|
//
|
|
// Enable keyboard interrupts in the interrupt enable register.
|
|
//
|
|
WRITE_PORT_USHORT(&((PINTERRUPT_REGISTERS)INTERRUPT_VIRTUAL_BASE)->Enable,
|
|
(1 << (KEYBOARD_VECTOR - DEVICE_VECTORS - 1)));
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
UCHAR
|
|
FwInputScanCode (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads a byte from the keyboard. If no data is available,
|
|
it blocks until a key is typed.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Returns the character read from the keyboard.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
#ifndef ALPHA
|
|
|
|
UCHAR ScanCode;
|
|
|
|
while (KbdBuffer.ReadIndex == KbdBuffer.WriteIndex) {
|
|
}
|
|
KbdBuffer.ReadIndex = (KbdBuffer.ReadIndex+1) % KBD_BUFFER_SIZE;
|
|
ScanCode = KbdBuffer.Buffer[KbdBuffer.ReadIndex];
|
|
|
|
return ScanCode;
|
|
|
|
#else
|
|
|
|
//
|
|
// Alpha. If there are remaining characters in the
|
|
// circular buffer, return the next one. Otherwise,
|
|
// hang until another character is typed and then call
|
|
// TranslateScanCode. Then return a character.
|
|
//
|
|
|
|
while (TRUE) {
|
|
|
|
if (KbdBuffer.ReadIndex != KbdBuffer.WriteIndex) {
|
|
|
|
//
|
|
// A character is in the buffer. Return it.
|
|
//
|
|
|
|
KbdBuffer.ReadIndex = (KbdBuffer.ReadIndex+1) % KBD_BUFFER_SIZE;
|
|
return (KbdBuffer.Buffer[KbdBuffer.ReadIndex]);
|
|
}
|
|
|
|
|
|
//
|
|
// Wait until a character is typed, then scan it, and loop back.
|
|
// The TranslateScanCode() calls will eventually bump the KbdBuffer
|
|
// WriteIndex.
|
|
//
|
|
|
|
while ((READ_PORT_UCHAR((PUCHAR)&KEYBOARD_READ->Status) &
|
|
KBD_OBF_MASK) == 0) {
|
|
}
|
|
|
|
TranslateScanCode(READ_PORT_UCHAR((PUCHAR)&KEYBOARD_READ->Data));
|
|
FwStallExecution(10); // Don't pound on the controller.
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|