- 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:
evb 2010-02-03 01:19:26 +00:00
parent 66bdab40af
commit e7ff33a8bc
11 changed files with 438 additions and 17 deletions

View file

@ -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>

View 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 */

View file

@ -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
View 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 */

View file

@ -17,6 +17,9 @@ LlbHwInitialize(VOID)
/* Setup the UART (PL011) */
LlbHwVersaUartInitialize();
/* Setup the KMI (PL050) */
LlbHwVersaKmiInitialize();
}
//

View 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 */

View file

@ -86,6 +86,18 @@ LlbHwBuildMemoryMap(
IN PBIOS_MEMORY_MAP MemoryMap
);
VOID
NTAPI
LlbHwKbdSend(
IN ULONG Value
);
INT
NTAPI
LlbHwKbdRead(
VOID
);
POSLOADER_INIT
NTAPI
LlbHwLoadOsLoaderFromRam(

View 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 */

View file

@ -15,5 +15,12 @@
#include "fw.h"
#include "serial.h"
#include "video.h"
#include "keyboard.h"
VOID
DbgPrint(
const char *fmt,
...
);
/* EOF */

View file

@ -18,4 +18,10 @@ LlbHwVersaClcdInitialize(
VOID
);
VOID
NTAPI
LlbHwVersaKmiInitialize(
VOID
);
/* EOF */

View file

@ -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 */