mirror of
https://github.com/reactos/reactos.git
synced 2025-05-17 16:27:00 +00:00
- Implement logical keyboard interface. Converts scan code to ASCII codes (just ok).
- Implement firmware ConsGetCh based on keyboard interface. - Implement KMI (Keyboard & Mouse Interface) PL050 driver for Versatile to init PS/2 and read keyboard scancodes. Can now press ENTER/whatever when FreeLDR gives "Cannot find freeldr.ini" error. - More fixes svn path=/trunk/; revision=45385
This commit is contained in:
parent
66bdab40af
commit
e7ff33a8bc
11 changed files with 438 additions and 17 deletions
|
@ -24,6 +24,7 @@
|
|||
<file>envir.c</file>
|
||||
<file>fw.c</file>
|
||||
<directory name="hw">
|
||||
<file>keyboard.c</file>
|
||||
<file>serial.c</file>
|
||||
<file>video.c</file>
|
||||
<if property="SARCH" value="omap3">
|
||||
|
@ -38,6 +39,7 @@
|
|||
<if property="SARCH" value="versatile">
|
||||
<directory name="versatile">
|
||||
<file>hwclcd.c</file>
|
||||
<file>hwkmi.c</file>
|
||||
<file>hwuart.c</file>
|
||||
<file>hwinfo.c</file>
|
||||
<file>hwinit.c</file>
|
||||
|
|
|
@ -40,4 +40,18 @@ int printf(const char *fmt, ...)
|
|||
return puts(printbuffer);
|
||||
}
|
||||
|
||||
VOID
|
||||
DbgPrint(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
unsigned int i, j;
|
||||
char Buffer[1024];
|
||||
|
||||
va_start(args, fmt);
|
||||
i = vsprintf(Buffer, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
for (j = 0; j < i; j++) LlbSerialPutChar(Buffer[j]);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -28,9 +28,8 @@ LlbFwKbHit(VOID)
|
|||
INT
|
||||
LlbFwGetCh(VOID)
|
||||
{
|
||||
/* Not yet implemented */
|
||||
while (TRUE);
|
||||
return 0;
|
||||
/* Return the key pressed */
|
||||
return LlbKeyboardGetChar();
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
242
reactos/boot/armllb/hw/keyboard.c
Executable file
242
reactos/boot/armllb/hw/keyboard.c
Executable file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: boot/armllb/hw/keyboard.c
|
||||
* PURPOSE: LLB Keyboard Routines
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#define E0_KPENTER 96
|
||||
#define E0_RCTRL 97
|
||||
#define E0_KPSLASH 98
|
||||
#define E0_PRSCR 99
|
||||
#define E0_RALT 100
|
||||
#define E0_BREAK 101
|
||||
#define E0_HOME 102
|
||||
#define E0_UP 103
|
||||
#define E0_PGUP 104
|
||||
#define E0_LEFT 105
|
||||
#define E0_RIGHT 106
|
||||
#define E0_END 107
|
||||
#define E0_DOWN 108
|
||||
#define E0_PGDN 109
|
||||
#define E0_INS 110
|
||||
#define E0_DEL 111
|
||||
#define E1_PAUSE 119
|
||||
#define E0_MACRO 112
|
||||
#define E0_F13 113
|
||||
#define E0_F14 114
|
||||
#define E0_HELP 115
|
||||
#define E0_DO 116
|
||||
#define E0_F17 117
|
||||
#define E0_KPMINPLUS 118
|
||||
#define E0_OK 124
|
||||
#define E0_MSLW 125
|
||||
#define E0_MSRW 126
|
||||
#define E0_MSTM 127
|
||||
|
||||
/* US 101 KEYBOARD LAYOUT *****************************************************/
|
||||
|
||||
CHAR LlbHwScanCodeToAsciiTable[58][2] =
|
||||
{
|
||||
{ 0,0 } ,
|
||||
{ 27, 27 } ,
|
||||
{ '1','!' } ,
|
||||
{ '2','@' } ,
|
||||
{ '3','#' } ,
|
||||
{ '4','$' } ,
|
||||
{ '5','%' } ,
|
||||
{ '6','^' } ,
|
||||
{ '7','&' } ,
|
||||
{ '8','*' } ,
|
||||
{ '9','(' } ,
|
||||
{ '0',')' } ,
|
||||
{ '-','_' } ,
|
||||
{ '=','+' } ,
|
||||
{ 8,8 } ,
|
||||
{ 9,9 } ,
|
||||
{ 'q','Q' } ,
|
||||
{ 'w','W' } ,
|
||||
{ 'e','E' } ,
|
||||
{ 'r','R' } ,
|
||||
{ 't','T' } ,
|
||||
{ 'y','Y' } ,
|
||||
{ 'u','U' } ,
|
||||
{ 'i','I' } ,
|
||||
{ 'o','O' } ,
|
||||
{ 'p','P' } ,
|
||||
{ '[','{' } ,
|
||||
{ ']','}' } ,
|
||||
{ 13,13 } ,
|
||||
{ 0,0 } ,
|
||||
{ 'a','A' } ,
|
||||
{ 's','S' } ,
|
||||
{ 'd','D' } ,
|
||||
{ 'f','F' } ,
|
||||
{ 'g','G' } ,
|
||||
{ 'h','H' } ,
|
||||
{ 'j','J' } ,
|
||||
{ 'k','K' } ,
|
||||
{ 'l','L' } ,
|
||||
{ ';',':' } ,
|
||||
{ 39,34 } ,
|
||||
{ '`','~' } ,
|
||||
{ 0,0 } ,
|
||||
{ '\\','|'} ,
|
||||
{ 'z','Z' } ,
|
||||
{ 'x','X' } ,
|
||||
{ 'c','C' } ,
|
||||
{ 'v','V' } ,
|
||||
{ 'b','B' } ,
|
||||
{ 'n','N' } ,
|
||||
{ 'm','M' } ,
|
||||
{ ',','<' } ,
|
||||
{ '.','>' } ,
|
||||
{ '/','?' } ,
|
||||
{ 0,0 } ,
|
||||
{ 0,0 } ,
|
||||
{ 0,0 } ,
|
||||
{ ' ',' ' } ,
|
||||
};
|
||||
|
||||
/* EXTENDED KEY TABLE *********************************************************/
|
||||
|
||||
UCHAR LlbHwExtendedScanCodeTable[128] =
|
||||
{
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
E0_KPENTER, E0_RCTRL, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, E0_KPSLASH, 0, E0_PRSCR,
|
||||
E0_RALT, 0, 0, 0,
|
||||
0, E0_F13, E0_F14, E0_HELP,
|
||||
E0_DO, E0_F17, 0, 0,
|
||||
0, 0, E0_BREAK, E0_HOME,
|
||||
E0_UP, E0_PGUP, 0, E0_LEFT,
|
||||
E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
|
||||
E0_DOWN, E0_PGDN, E0_INS, E0_DEL,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, E0_MSLW,
|
||||
E0_MSRW, E0_MSTM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, E0_MACRO,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
USHORT LlbKbdLastScanCode;
|
||||
|
||||
UCHAR
|
||||
NTAPI
|
||||
LlbKbdTranslateScanCode(IN USHORT ScanCode,
|
||||
IN PUCHAR KeyCode)
|
||||
{
|
||||
ULONG LastScanCode;
|
||||
|
||||
/* Check for extended scan codes */
|
||||
if ((ScanCode == 0xE0) || (ScanCode == 0xE1))
|
||||
{
|
||||
/* We'll get these on the next scan */
|
||||
LlbKbdLastScanCode = ScanCode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for bogus scan codes */
|
||||
if ((ScanCode == 0x00) || (ScanCode == 0xFF))
|
||||
{
|
||||
/* Reset */
|
||||
LlbKbdLastScanCode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only act on the break, not the make */
|
||||
if (ScanCode > 0x80) return 0;
|
||||
|
||||
/* Keep only simple scan codes */
|
||||
ScanCode &= 0x7F;
|
||||
|
||||
/* Check if this was part of an extended sequence */
|
||||
if (LlbKbdLastScanCode)
|
||||
{
|
||||
/* Save the last scan code and clear it, since we've consumed it now */
|
||||
LastScanCode = LlbKbdLastScanCode;
|
||||
LlbKbdLastScanCode = 0;
|
||||
switch (LastScanCode)
|
||||
{
|
||||
/* E0 extended codes */
|
||||
case 0xE0:
|
||||
|
||||
/* Skip bogus codes */
|
||||
if ((ScanCode == 0x2A) || (ScanCode == 0x36)) return 0;
|
||||
|
||||
/* Lookup the code for it */
|
||||
if (!LlbHwExtendedScanCodeTable[ScanCode]) return 0;
|
||||
*KeyCode = LlbHwExtendedScanCodeTable[ScanCode];
|
||||
break;
|
||||
|
||||
/* E1 extended codes */
|
||||
case 0xE1:
|
||||
|
||||
/* Only recognize one (the SYSREQ/PAUSE sequence) */
|
||||
if (ScanCode != 0x1D) return 0;
|
||||
LlbKbdLastScanCode = 0x100;
|
||||
break;
|
||||
|
||||
/* PAUSE sequence */
|
||||
case 0x100:
|
||||
|
||||
/* Make sure it's the one */
|
||||
if (ScanCode != 0x45) return 0;
|
||||
*KeyCode = E1_PAUSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, the scancode is the key code */
|
||||
LlbKbdLastScanCode = 0;
|
||||
*KeyCode = ScanCode;
|
||||
}
|
||||
|
||||
/* Translation success */
|
||||
return 1;
|
||||
}
|
||||
|
||||
CHAR
|
||||
NTAPI
|
||||
LlbKeyboardGetChar(VOID)
|
||||
{
|
||||
UCHAR ScanCode, KeyCode;
|
||||
|
||||
do
|
||||
{
|
||||
/* Read the scan code and convert it to a virtual key code */
|
||||
ScanCode = LlbHwKbdRead();
|
||||
} while (!LlbKbdTranslateScanCode(ScanCode, &KeyCode));
|
||||
|
||||
/* Is this ASCII? */
|
||||
if (KeyCode > 96) return ScanCode;
|
||||
|
||||
/* Return the ASCII character */
|
||||
return LlbHwScanCodeToAsciiTable[KeyCode][0];
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -17,6 +17,9 @@ LlbHwInitialize(VOID)
|
|||
|
||||
/* Setup the UART (PL011) */
|
||||
LlbHwVersaUartInitialize();
|
||||
|
||||
/* Setup the KMI (PL050) */
|
||||
LlbHwVersaKmiInitialize();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
135
reactos/boot/armllb/hw/versatile/hwkmi.c
Executable file
135
reactos/boot/armllb/hw/versatile/hwkmi.c
Executable file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: boot/armllb/hw/versatile/hwkmi.c
|
||||
* PURPOSE: LLB KMI Support for Versatile
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
//
|
||||
// Control Register Bits
|
||||
//
|
||||
#define KMICR_TYPE (1 << 5)
|
||||
#define KMICR_RXINTREN (1 << 4)
|
||||
#define KMICR_TXINTREN (1 << 3)
|
||||
#define KMICR_EN (1 << 2)
|
||||
#define KMICR_FD (1 << 1)
|
||||
#define KMICR_FC (1 << 0)
|
||||
|
||||
//
|
||||
// Status Register Bits
|
||||
//
|
||||
#define KMISTAT_TXEMPTY (1 << 6)
|
||||
#define KMISTAT_TXBUSY (1 << 5)
|
||||
#define KMISTAT_RXFULL (1 << 4)
|
||||
#define KMISTAT_RXBUSY (1 << 3)
|
||||
#define KMISTAT_RXPARITY (1 << 2)
|
||||
#define KMISTAT_IC (1 << 1)
|
||||
#define KMISTAT_ID (1 << 0)
|
||||
|
||||
//
|
||||
// KMI Registers
|
||||
//
|
||||
#define PL050_KMICR (LlbHwVersaKmiBase + 0x00)
|
||||
#define PL050_KMISTAT (LlbHwVersaKmiBase + 0x04)
|
||||
#define PL050_KMIDATA (LlbHwVersaKmiBase + 0x08)
|
||||
#define PL050_KMICLKDIV (LlbHwVersaKmiBase + 0x0c)
|
||||
static const ULONG LlbHwVersaKmiBase = 0x10006000;
|
||||
|
||||
//
|
||||
// PS/2 Commands/Requests
|
||||
//
|
||||
#define PS2_O_RESET 0xff
|
||||
#define PS2_O_RESEND 0xfe
|
||||
#define PS2_O_DISABLE 0xf5
|
||||
#define PS2_O_ENABLE 0xf4
|
||||
#define PS2_O_ECHO 0xee
|
||||
#define PS2_O_SET_DEFAULT 0xf6
|
||||
#define PS2_O_SET_RATE_DELAY 0xf3
|
||||
#define PS2_O_SET_SCANSET 0xf0
|
||||
#define PS2_O_INDICATORS 0xed
|
||||
#define PS2_I_RESEND 0xfe
|
||||
#define PS2_I_DIAGFAIL 0xfd
|
||||
#define PS2_I_ACK 0xfa
|
||||
#define PS2_I_BREAK 0xf0
|
||||
#define PS2_I_ECHO 0xee
|
||||
#define PS2_I_BAT_OK 0xaa
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LlbHwVersaKmiSendAndWait(IN ULONG Value)
|
||||
{
|
||||
volatile int i = 1000;
|
||||
|
||||
/* Send the value */
|
||||
LlbHwKbdSend(Value);
|
||||
|
||||
/* Wait a bit */
|
||||
while (--i);
|
||||
|
||||
/* Now make sure we received an ACK */
|
||||
if (LlbHwKbdRead() != PS2_I_ACK) DbgPrint("PS/2 FAILURE!\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LlbHwVersaKmiInitialize(VOID)
|
||||
{
|
||||
UCHAR Divisor;
|
||||
|
||||
/* Setup divisor and enable KMI */
|
||||
Divisor = (LlbHwGetPClk() / 8000000) - 1;
|
||||
WRITE_REGISTER_UCHAR(PL050_KMICLKDIV, Divisor);
|
||||
WRITE_REGISTER_UCHAR(PL050_KMICR, KMICR_EN);
|
||||
|
||||
/* Reset PS/2 controller */
|
||||
LlbHwVersaKmiSendAndWait(PS2_O_RESET);
|
||||
if (LlbHwKbdRead() != PS2_I_BAT_OK) DbgPrint("PS/2 RESET FAILURE!\n");
|
||||
|
||||
/* Send PS/2 Initialization Stream */
|
||||
LlbHwVersaKmiSendAndWait(PS2_O_DISABLE);
|
||||
LlbHwVersaKmiSendAndWait(PS2_O_SET_DEFAULT);
|
||||
LlbHwVersaKmiSendAndWait(PS2_O_SET_SCANSET);
|
||||
LlbHwVersaKmiSendAndWait(1);
|
||||
LlbHwVersaKmiSendAndWait(PS2_O_ENABLE);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LlbHwKbdSend(IN ULONG Value)
|
||||
{
|
||||
ULONG Status;
|
||||
|
||||
/* Wait for ready signal */
|
||||
do
|
||||
{
|
||||
/* Read TX buffer state */
|
||||
Status = READ_REGISTER_UCHAR(PL050_KMISTAT);
|
||||
} while (!(Status & KMISTAT_TXEMPTY));
|
||||
|
||||
/* Send value */
|
||||
WRITE_REGISTER_UCHAR(PL050_KMIDATA, Value);
|
||||
}
|
||||
|
||||
INT
|
||||
NTAPI
|
||||
LlbHwKbdRead(VOID)
|
||||
{
|
||||
ULONG Status;
|
||||
|
||||
/* Wait for ready signal */
|
||||
do
|
||||
{
|
||||
/* Read TX buffer state */
|
||||
Status = READ_REGISTER_UCHAR(PL050_KMISTAT);
|
||||
} while (!(Status & KMISTAT_RXFULL));
|
||||
|
||||
/* Read current data on keyboard */
|
||||
return READ_REGISTER_UCHAR(PL050_KMIDATA);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -86,6 +86,18 @@ LlbHwBuildMemoryMap(
|
|||
IN PBIOS_MEMORY_MAP MemoryMap
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LlbHwKbdSend(
|
||||
IN ULONG Value
|
||||
);
|
||||
|
||||
INT
|
||||
NTAPI
|
||||
LlbHwKbdRead(
|
||||
VOID
|
||||
);
|
||||
|
||||
POSLOADER_INIT
|
||||
NTAPI
|
||||
LlbHwLoadOsLoaderFromRam(
|
||||
|
|
15
reactos/boot/armllb/inc/keyboard.h
Executable file
15
reactos/boot/armllb/inc/keyboard.h
Executable file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: boot/armllb/inc/keyboard.h
|
||||
* PURPOSE: LLB Keyboard Functions
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
CHAR
|
||||
NTAPI
|
||||
LlbKeyboardGetChar(
|
||||
VOID
|
||||
);
|
||||
|
||||
/* EOF */
|
|
@ -15,5 +15,12 @@
|
|||
#include "fw.h"
|
||||
#include "serial.h"
|
||||
#include "video.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
VOID
|
||||
DbgPrint(
|
||||
const char *fmt,
|
||||
...
|
||||
);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -18,4 +18,10 @@ LlbHwVersaClcdInitialize(
|
|||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LlbHwVersaKmiInitialize(
|
||||
VOID
|
||||
);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -25,18 +25,4 @@ LlbStartup(VOID)
|
|||
while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
DbgPrint(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
unsigned int i;
|
||||
char Buffer[1024];
|
||||
|
||||
va_start(args, fmt);
|
||||
i = vsprintf(Buffer, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
while (*Buffer) LlbSerialPutChar(*Buffer);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue