- Implement logical keyboard interface. Converts scan code to ASCII codes (just ok).
authorevb <evb@svn.reactos.org>
Wed, 3 Feb 2010 01:19:26 +0000 (01:19 +0000)
committerevb <evb@svn.reactos.org>
Wed, 3 Feb 2010 01:19:26 +0000 (01:19 +0000)
- 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

reactos/boot/armllb/armllb.rbuild
reactos/boot/armllb/crtsupp.c
reactos/boot/armllb/fw.c
reactos/boot/armllb/hw/keyboard.c [new file with mode: 0755]
reactos/boot/armllb/hw/versatile/hwinit.c
reactos/boot/armllb/hw/versatile/hwkmi.c [new file with mode: 0755]
reactos/boot/armllb/inc/hw.h
reactos/boot/armllb/inc/keyboard.h [new file with mode: 0755]
reactos/boot/armllb/inc/precomp.h
reactos/boot/armllb/inc/versa.h
reactos/boot/armllb/main.c

index 6def3c9..ea39a50 100644 (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>
index df0f37c..ba2dde3 100644 (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 */
index 0dad841..baa9cde 100644 (file)
@@ -28,9 +28,8 @@ LlbFwKbHit(VOID)
 INT
 LlbFwGetCh(VOID)
 {
-    /* Not yet implemented */
-    while (TRUE);
-    return 0;
+    /* Return the key pressed */
+    return LlbKeyboardGetChar();
 }
 
 /* EOF */
diff --git a/reactos/boot/armllb/hw/keyboard.c b/reactos/boot/armllb/hw/keyboard.c
new file mode 100755 (executable)
index 0000000..06d2c67
--- /dev/null
@@ -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 */
index d1cc822..6aa73e6 100755 (executable)
@@ -17,6 +17,9 @@ LlbHwInitialize(VOID)
     
     /* Setup the UART (PL011) */
     LlbHwVersaUartInitialize();
+    
+    /* Setup the KMI (PL050) */
+    LlbHwVersaKmiInitialize();
 }
 
 //
diff --git a/reactos/boot/armllb/hw/versatile/hwkmi.c b/reactos/boot/armllb/hw/versatile/hwkmi.c
new file mode 100755 (executable)
index 0000000..1963b0c
--- /dev/null
@@ -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 */
index 269c43e..1d8ad18 100755 (executable)
@@ -86,6 +86,18 @@ LlbHwBuildMemoryMap(
     IN PBIOS_MEMORY_MAP MemoryMap
 );
 
+VOID
+NTAPI
+LlbHwKbdSend(
+    IN ULONG Value
+);
+
+INT
+NTAPI
+LlbHwKbdRead(
+    VOID
+);
+
 POSLOADER_INIT
 NTAPI
 LlbHwLoadOsLoaderFromRam(
diff --git a/reactos/boot/armllb/inc/keyboard.h b/reactos/boot/armllb/inc/keyboard.h
new file mode 100755 (executable)
index 0000000..034f76d
--- /dev/null
@@ -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 */
index 6c211a1..ce2a637 100755 (executable)
 #include "fw.h"
 #include "serial.h"
 #include "video.h"
+#include "keyboard.h"
+
+VOID
+DbgPrint(
+    const char *fmt,
+    ...
+);
 
 /* EOF */
index 3de745a..fae0835 100755 (executable)
@@ -18,4 +18,10 @@ LlbHwVersaClcdInitialize(
     VOID
 );
 
+VOID
+NTAPI
+LlbHwVersaKmiInitialize(
+    VOID
+);
+
 /* EOF */
index 142b839..7248cbc 100755 (executable)
@@ -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 */