1 /** @file 2 Helper functions for USB Keyboard Driver. 3 4 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "KeyBoard.h" 16 17 USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin = { 18 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN), // Binary size 19 20 // 21 // EFI_HII_PACKAGE_HEADER 22 // 23 { 24 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32), 25 EFI_HII_PACKAGE_KEYBOARD_LAYOUT 26 }, 27 1, // LayoutCount 28 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength 29 USB_KEYBOARD_LAYOUT_KEY_GUID, // KeyGuid 30 sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (USB_KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset 31 USB_KEYBOARD_KEY_COUNT, // DescriptorCount 32 { 33 // 34 // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT) 35 // 36 {EfiKeyC1, 'a', 'A', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 37 {EfiKeyB5, 'b', 'B', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 38 {EfiKeyB3, 'c', 'C', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 39 {EfiKeyC3, 'd', 'D', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 40 {EfiKeyD3, 'e', 'E', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 41 {EfiKeyC4, 'f', 'F', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 42 {EfiKeyC5, 'g', 'G', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 43 {EfiKeyC6, 'h', 'H', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 44 {EfiKeyD8, 'i', 'I', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 45 {EfiKeyC7, 'j', 'J', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 46 {EfiKeyC8, 'k', 'K', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 47 {EfiKeyC9, 'l', 'L', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 48 {EfiKeyB7, 'm', 'M', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 49 {EfiKeyB6, 'n', 'N', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 50 {EfiKeyD9, 'o', 'O', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 51 {EfiKeyD10, 'p', 'P', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 52 {EfiKeyD1, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 53 {EfiKeyD4, 'r', 'R', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 54 {EfiKeyC2, 's', 'S', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 55 {EfiKeyD5, 't', 'T', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 56 {EfiKeyD7, 'u', 'U', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 57 {EfiKeyB4, 'v', 'V', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 58 {EfiKeyD2, 'w', 'W', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 59 {EfiKeyB2, 'x', 'X', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 60 {EfiKeyD6, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 61 {EfiKeyB1, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, 62 {EfiKeyE1, '1', '!', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 63 {EfiKeyE2, '2', '@', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 64 {EfiKeyE3, '3', '#', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 65 {EfiKeyE4, '4', '$', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 66 {EfiKeyE5, '5', '%', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 67 {EfiKeyE6, '6', '^', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 68 {EfiKeyE7, '7', '&', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 69 {EfiKeyE8, '8', '*', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 70 {EfiKeyE9, '9', '(', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 71 {EfiKeyE10, '0', ')', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 72 {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0}, 73 {EfiKeyEsc, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER, 0}, 74 {EfiKeyBackSpace, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER, 0}, 75 {EfiKeyTab, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER, 0}, 76 {EfiKeySpaceBar, ' ', ' ', 0, 0, EFI_NULL_MODIFIER, 0}, 77 {EfiKeyE11, '-', '_', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 78 {EfiKeyE12, '=', '+', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 79 {EfiKeyD11, '[', '{', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 80 {EfiKeyD12, ']', '}', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 81 {EfiKeyD13, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 82 {EfiKeyC12, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 83 {EfiKeyC10, ';', ':', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 84 {EfiKeyC11, '\'', '"', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 85 {EfiKeyE0, '`', '~', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 86 {EfiKeyB8, ',', '<', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 87 {EfiKeyB9, '.', '>', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 88 {EfiKeyB10, '/', '?', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, 89 {EfiKeyCapsLock, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER, 0}, 90 {EfiKeyF1, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER, 0}, 91 {EfiKeyF2, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER, 0}, 92 {EfiKeyF3, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER, 0}, 93 {EfiKeyF4, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0}, 94 {EfiKeyF5, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0}, 95 {EfiKeyF6, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER, 0}, 96 {EfiKeyF7, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0}, 97 {EfiKeyF8, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0}, 98 {EfiKeyF9, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER, 0}, 99 {EfiKeyF10, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER, 0}, 100 {EfiKeyF11, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0}, 101 {EfiKeyF12, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0}, 102 {EfiKeyPrint, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER, 0}, 103 {EfiKeySLck, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER, 0}, 104 {EfiKeyPause, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER, 0}, 105 {EfiKeyIns, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER, 0}, 106 {EfiKeyHome, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER, 0}, 107 {EfiKeyPgUp, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER, 0}, 108 {EfiKeyDel, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER, 0}, 109 {EfiKeyEnd, 0x00, 0x00, 0, 0, EFI_END_MODIFIER, 0}, 110 {EfiKeyPgDn, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER, 0}, 111 {EfiKeyRightArrow, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER, 0}, 112 {EfiKeyLeftArrow, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER, 0}, 113 {EfiKeyDownArrow, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER, 0}, 114 {EfiKeyUpArrow, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER, 0}, 115 {EfiKeyNLck, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER, 0}, 116 {EfiKeySlash, '/', '/', 0, 0, EFI_NULL_MODIFIER, 0}, 117 {EfiKeyAsterisk, '*', '*', 0, 0, EFI_NULL_MODIFIER, 0}, 118 {EfiKeyMinus, '-', '-', 0, 0, EFI_NULL_MODIFIER, 0}, 119 {EfiKeyPlus, '+', '+', 0, 0, EFI_NULL_MODIFIER, 0}, 120 {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0}, 121 {EfiKeyOne, '1', '1', 0, 0, EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 122 {EfiKeyTwo, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 123 {EfiKeyThree, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 124 {EfiKeyFour, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 125 {EfiKeyFive, '5', '5', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 126 {EfiKeySix, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 127 {EfiKeySeven, '7', '7', 0, 0, EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 128 {EfiKeyEight, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 129 {EfiKeyNine, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 130 {EfiKeyZero, '0', '0', 0, 0, EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 131 {EfiKeyPeriod, '.', '.', 0, 0, EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, 132 {EfiKeyA4, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER, 0}, 133 {EfiKeyLCtrl, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0}, 134 {EfiKeyLShift, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0}, 135 {EfiKeyLAlt, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER, 0}, 136 {EfiKeyA0, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0}, 137 {EfiKeyRCtrl, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0}, 138 {EfiKeyRShift, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0}, 139 {EfiKeyA2, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0}, 140 {EfiKeyA3, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0}, 141 }, 142 1, // DescriptionCount 143 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code 144 ' ', // Space 145 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[] 146 }; 147 148 // 149 // EFI_KEY to USB Keycode conversion table 150 // EFI_KEY is defined in UEFI spec. 151 // USB Keycode is defined in USB HID Firmware spec. 152 // 153 UINT8 EfiKeyToUsbKeyCodeConvertionTable[] = { 154 0xe0, // EfiKeyLCtrl 155 0xe3, // EfiKeyA0 156 0xe2, // EfiKeyLAlt 157 0x2c, // EfiKeySpaceBar 158 0xe6, // EfiKeyA2 159 0xe7, // EfiKeyA3 160 0x65, // EfiKeyA4 161 0xe4, // EfiKeyRCtrl 162 0x50, // EfiKeyLeftArrow 163 0x51, // EfiKeyDownArrow 164 0x4F, // EfiKeyRightArrow 165 0x62, // EfiKeyZero 166 0x63, // EfiKeyPeriod 167 0x28, // EfiKeyEnter 168 0xe1, // EfiKeyLShift 169 0x64, // EfiKeyB0 170 0x1D, // EfiKeyB1 171 0x1B, // EfiKeyB2 172 0x06, // EfiKeyB3 173 0x19, // EfiKeyB4 174 0x05, // EfiKeyB5 175 0x11, // EfiKeyB6 176 0x10, // EfiKeyB7 177 0x36, // EfiKeyB8 178 0x37, // EfiKeyB9 179 0x38, // EfiKeyB10 180 0xe5, // EfiKeyRShift 181 0x52, // EfiKeyUpArrow 182 0x59, // EfiKeyOne 183 0x5A, // EfiKeyTwo 184 0x5B, // EfiKeyThree 185 0x39, // EfiKeyCapsLock 186 0x04, // EfiKeyC1 187 0x16, // EfiKeyC2 188 0x07, // EfiKeyC3 189 0x09, // EfiKeyC4 190 0x0A, // EfiKeyC5 191 0x0B, // EfiKeyC6 192 0x0D, // EfiKeyC7 193 0x0E, // EfiKeyC8 194 0x0F, // EfiKeyC9 195 0x33, // EfiKeyC10 196 0x34, // EfiKeyC11 197 0x32, // EfiKeyC12 198 0x5C, // EfiKeyFour 199 0x5D, // EfiKeyFive 200 0x5E, // EfiKeySix 201 0x57, // EfiKeyPlus 202 0x2B, // EfiKeyTab 203 0x14, // EfiKeyD1 204 0x1A, // EfiKeyD2 205 0x08, // EfiKeyD3 206 0x15, // EfiKeyD4 207 0x17, // EfiKeyD5 208 0x1C, // EfiKeyD6 209 0x18, // EfiKeyD7 210 0x0C, // EfiKeyD8 211 0x12, // EfiKeyD9 212 0x13, // EfiKeyD10 213 0x2F, // EfiKeyD11 214 0x30, // EfiKeyD12 215 0x31, // EfiKeyD13 216 0x4C, // EfiKeyDel 217 0x4D, // EfiKeyEnd 218 0x4E, // EfiKeyPgDn 219 0x5F, // EfiKeySeven 220 0x60, // EfiKeyEight 221 0x61, // EfiKeyNine 222 0x35, // EfiKeyE0 223 0x1E, // EfiKeyE1 224 0x1F, // EfiKeyE2 225 0x20, // EfiKeyE3 226 0x21, // EfiKeyE4 227 0x22, // EfiKeyE5 228 0x23, // EfiKeyE6 229 0x24, // EfiKeyE7 230 0x25, // EfiKeyE8 231 0x26, // EfiKeyE9 232 0x27, // EfiKeyE10 233 0x2D, // EfiKeyE11 234 0x2E, // EfiKeyE12 235 0x2A, // EfiKeyBackSpace 236 0x49, // EfiKeyIns 237 0x4A, // EfiKeyHome 238 0x4B, // EfiKeyPgUp 239 0x53, // EfiKeyNLck 240 0x54, // EfiKeySlash 241 0x55, // EfiKeyAsterisk 242 0x56, // EfiKeyMinus 243 0x29, // EfiKeyEsc 244 0x3A, // EfiKeyF1 245 0x3B, // EfiKeyF2 246 0x3C, // EfiKeyF3 247 0x3D, // EfiKeyF4 248 0x3E, // EfiKeyF5 249 0x3F, // EfiKeyF6 250 0x40, // EfiKeyF7 251 0x41, // EfiKeyF8 252 0x42, // EfiKeyF9 253 0x43, // EfiKeyF10 254 0x44, // EfiKeyF11 255 0x45, // EfiKeyF12 256 0x46, // EfiKeyPrint 257 0x47, // EfiKeySLck 258 0x48 // EfiKeyPause 259 }; 260 261 // 262 // Keyboard modifier value to EFI Scan Code convertion table 263 // EFI Scan Code and the modifier values are defined in UEFI spec. 264 // 265 UINT8 ModifierValueToEfiScanCodeConvertionTable[] = { 266 SCAN_NULL, // EFI_NULL_MODIFIER 267 SCAN_NULL, // EFI_LEFT_CONTROL_MODIFIER 268 SCAN_NULL, // EFI_RIGHT_CONTROL_MODIFIER 269 SCAN_NULL, // EFI_LEFT_ALT_MODIFIER 270 SCAN_NULL, // EFI_RIGHT_ALT_MODIFIER 271 SCAN_NULL, // EFI_ALT_GR_MODIFIER 272 SCAN_INSERT, // EFI_INSERT_MODIFIER 273 SCAN_DELETE, // EFI_DELETE_MODIFIER 274 SCAN_PAGE_DOWN, // EFI_PAGE_DOWN_MODIFIER 275 SCAN_PAGE_UP, // EFI_PAGE_UP_MODIFIER 276 SCAN_HOME, // EFI_HOME_MODIFIER 277 SCAN_END, // EFI_END_MODIFIER 278 SCAN_NULL, // EFI_LEFT_SHIFT_MODIFIER 279 SCAN_NULL, // EFI_RIGHT_SHIFT_MODIFIER 280 SCAN_NULL, // EFI_CAPS_LOCK_MODIFIER 281 SCAN_NULL, // EFI_NUM_LOCK_MODIFIER 282 SCAN_LEFT, // EFI_LEFT_ARROW_MODIFIER 283 SCAN_RIGHT, // EFI_RIGHT_ARROW_MODIFIER 284 SCAN_DOWN, // EFI_DOWN_ARROW_MODIFIER 285 SCAN_UP, // EFI_UP_ARROW_MODIFIER 286 SCAN_NULL, // EFI_NS_KEY_MODIFIER 287 SCAN_NULL, // EFI_NS_KEY_DEPENDENCY_MODIFIER 288 SCAN_F1, // EFI_FUNCTION_KEY_ONE_MODIFIER 289 SCAN_F2, // EFI_FUNCTION_KEY_TWO_MODIFIER 290 SCAN_F3, // EFI_FUNCTION_KEY_THREE_MODIFIER 291 SCAN_F4, // EFI_FUNCTION_KEY_FOUR_MODIFIER 292 SCAN_F5, // EFI_FUNCTION_KEY_FIVE_MODIFIER 293 SCAN_F6, // EFI_FUNCTION_KEY_SIX_MODIFIER 294 SCAN_F7, // EFI_FUNCTION_KEY_SEVEN_MODIFIER 295 SCAN_F8, // EFI_FUNCTION_KEY_EIGHT_MODIFIER 296 SCAN_F9, // EFI_FUNCTION_KEY_NINE_MODIFIER 297 SCAN_F10, // EFI_FUNCTION_KEY_TEN_MODIFIER 298 SCAN_F11, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER 299 SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER 300 // 301 // For Partial Keystroke support 302 // 303 SCAN_NULL, // EFI_PRINT_MODIFIER 304 SCAN_NULL, // EFI_SYS_REQUEST_MODIFIER 305 SCAN_NULL, // EFI_SCROLL_LOCK_MODIFIER 306 SCAN_PAUSE, // EFI_PAUSE_MODIFIER 307 SCAN_NULL, // EFI_BREAK_MODIFIER 308 SCAN_NULL, // EFI_LEFT_LOGO_MODIFIER 309 SCAN_NULL, // EFI_RIGHT_LOGO_MODIFER 310 SCAN_NULL, // EFI_MENU_MODIFER 311 }; 312 313 /** 314 Initialize Key Convention Table by using default keyboard layout. 315 316 @param UsbKeyboardDevice The USB_KB_DEV instance. 317 318 @retval EFI_SUCCESS The default keyboard layout was installed successfully 319 @retval Others Failure to install default keyboard layout. 320 **/ 321 EFI_STATUS 322 InstallDefaultKeyboardLayout ( 323 IN OUT USB_KB_DEV *UsbKeyboardDevice 324 ) 325 { 326 EFI_STATUS Status; 327 EFI_HII_DATABASE_PROTOCOL *HiiDatabase; 328 EFI_HII_HANDLE HiiHandle; 329 330 // 331 // Locate Hii database protocol 332 // 333 Status = gBS->LocateProtocol ( 334 &gEfiHiiDatabaseProtocolGuid, 335 NULL, 336 (VOID **) &HiiDatabase 337 ); 338 if (EFI_ERROR (Status)) { 339 return Status; 340 } 341 342 // 343 // Install Keyboard Layout package to HII database 344 // 345 HiiHandle = HiiAddPackages ( 346 &gUsbKeyboardLayoutPackageGuid, 347 UsbKeyboardDevice->ControllerHandle, 348 &mUsbKeyboardLayoutBin, 349 NULL 350 ); 351 if (HiiHandle == NULL) { 352 return EFI_OUT_OF_RESOURCES; 353 } 354 355 // 356 // Set current keyboard layout 357 // 358 Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &gUsbKeyboardLayoutKeyGuid); 359 360 return Status; 361 } 362 363 364 /** 365 Uses USB I/O to check whether the device is a USB keyboard device. 366 367 @param UsbIo Pointer to a USB I/O protocol instance. 368 369 @retval TRUE Device is a USB keyboard device. 370 @retval FALSE Device is a not USB keyboard device. 371 372 **/ 373 BOOLEAN 374 IsUSBKeyboard ( 375 IN EFI_USB_IO_PROTOCOL *UsbIo 376 ) 377 { 378 EFI_STATUS Status; 379 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 380 381 // 382 // Get the default interface descriptor 383 // 384 Status = UsbIo->UsbGetInterfaceDescriptor ( 385 UsbIo, 386 &InterfaceDescriptor 387 ); 388 389 if (EFI_ERROR (Status)) { 390 return FALSE; 391 } 392 393 if (InterfaceDescriptor.InterfaceClass == CLASS_HID && 394 InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT && 395 InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD 396 ) { 397 return TRUE; 398 } 399 400 return FALSE; 401 } 402 403 /** 404 Get current keyboard layout from HII database. 405 406 @return Pointer to HII Keyboard Layout. 407 NULL means failure occurred while trying to get keyboard layout. 408 409 **/ 410 EFI_HII_KEYBOARD_LAYOUT * 411 GetCurrentKeyboardLayout ( 412 VOID 413 ) 414 { 415 EFI_STATUS Status; 416 EFI_HII_DATABASE_PROTOCOL *HiiDatabase; 417 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout; 418 UINT16 Length; 419 420 // 421 // Locate HII Database Protocol 422 // 423 Status = gBS->LocateProtocol ( 424 &gEfiHiiDatabaseProtocolGuid, 425 NULL, 426 (VOID **) &HiiDatabase 427 ); 428 if (EFI_ERROR (Status)) { 429 return NULL; 430 } 431 432 // 433 // Get current keyboard layout from HII database 434 // 435 Length = 0; 436 KeyboardLayout = NULL; 437 Status = HiiDatabase->GetKeyboardLayout ( 438 HiiDatabase, 439 NULL, 440 &Length, 441 KeyboardLayout 442 ); 443 if (Status == EFI_BUFFER_TOO_SMALL) { 444 KeyboardLayout = AllocatePool (Length); 445 ASSERT (KeyboardLayout != NULL); 446 447 Status = HiiDatabase->GetKeyboardLayout ( 448 HiiDatabase, 449 NULL, 450 &Length, 451 KeyboardLayout 452 ); 453 if (EFI_ERROR (Status)) { 454 FreePool (KeyboardLayout); 455 KeyboardLayout = NULL; 456 } 457 } 458 459 return KeyboardLayout; 460 } 461 462 /** 463 Find Key Descriptor in Key Convertion Table given its USB keycode. 464 465 @param UsbKeyboardDevice The USB_KB_DEV instance. 466 @param KeyCode USB Keycode. 467 468 @return The Key Descriptor in Key Convertion Table. 469 NULL means not found. 470 471 **/ 472 EFI_KEY_DESCRIPTOR * 473 GetKeyDescriptor ( 474 IN USB_KB_DEV *UsbKeyboardDevice, 475 IN UINT8 KeyCode 476 ) 477 { 478 UINT8 Index; 479 480 // 481 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7] 482 // 483 if ((!USBKBD_VALID_KEYCODE (KeyCode)) || ((KeyCode > 0x65) && (KeyCode < 0xe0)) || (KeyCode > 0xe7)) { 484 return NULL; 485 } 486 487 // 488 // Calculate the index of Key Descriptor in Key Convertion Table 489 // 490 if (KeyCode <= 0x65) { 491 Index = (UINT8) (KeyCode - 4); 492 } else { 493 Index = (UINT8) (KeyCode - 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE); 494 } 495 496 return &UsbKeyboardDevice->KeyConvertionTable[Index]; 497 } 498 499 /** 500 Find Non-Spacing key for given Key descriptor. 501 502 @param UsbKeyboardDevice The USB_KB_DEV instance. 503 @param KeyDescriptor Key descriptor. 504 505 @return The Non-Spacing key corresponding to KeyDescriptor 506 NULL means not found. 507 508 **/ 509 USB_NS_KEY * 510 FindUsbNsKey ( 511 IN USB_KB_DEV *UsbKeyboardDevice, 512 IN EFI_KEY_DESCRIPTOR *KeyDescriptor 513 ) 514 { 515 LIST_ENTRY *Link; 516 LIST_ENTRY *NsKeyList; 517 USB_NS_KEY *UsbNsKey; 518 519 NsKeyList = &UsbKeyboardDevice->NsKeyList; 520 Link = GetFirstNode (NsKeyList); 521 while (!IsNull (NsKeyList, Link)) { 522 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link); 523 524 if (UsbNsKey->NsKey[0].Key == KeyDescriptor->Key) { 525 return UsbNsKey; 526 } 527 528 Link = GetNextNode (NsKeyList, Link); 529 } 530 531 return NULL; 532 } 533 534 /** 535 Find physical key definition for a given key descriptor. 536 537 For a specified non-spacing key, there are a list of physical 538 keys following it. This function traverses the list of 539 physical keys and tries to find the physical key matching 540 the KeyDescriptor. 541 542 @param UsbNsKey The non-spacing key information. 543 @param KeyDescriptor The key descriptor. 544 545 @return The physical key definition. 546 If no physical key is found, parameter KeyDescriptor is returned. 547 548 **/ 549 EFI_KEY_DESCRIPTOR * 550 FindPhysicalKey ( 551 IN USB_NS_KEY *UsbNsKey, 552 IN EFI_KEY_DESCRIPTOR *KeyDescriptor 553 ) 554 { 555 UINTN Index; 556 EFI_KEY_DESCRIPTOR *PhysicalKey; 557 558 PhysicalKey = &UsbNsKey->NsKey[1]; 559 for (Index = 0; Index < UsbNsKey->KeyCount; Index++) { 560 if (KeyDescriptor->Key == PhysicalKey->Key) { 561 return PhysicalKey; 562 } 563 564 PhysicalKey++; 565 } 566 567 // 568 // No children definition matched, return original key 569 // 570 return KeyDescriptor; 571 } 572 573 /** 574 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID. 575 576 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID 577 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout(). 578 It tries to get curent keyboard layout from HII database. 579 580 @param Event Event being signaled. 581 @param Context Points to USB_KB_DEV instance. 582 583 **/ 584 VOID 585 EFIAPI 586 SetKeyboardLayoutEvent ( 587 IN EFI_EVENT Event, 588 IN VOID *Context 589 ) 590 { 591 USB_KB_DEV *UsbKeyboardDevice; 592 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout; 593 EFI_KEY_DESCRIPTOR TempKey; 594 EFI_KEY_DESCRIPTOR *KeyDescriptor; 595 EFI_KEY_DESCRIPTOR *TableEntry; 596 EFI_KEY_DESCRIPTOR *NsKey; 597 USB_NS_KEY *UsbNsKey; 598 UINTN Index; 599 UINTN Index2; 600 UINTN KeyCount; 601 UINT8 KeyCode; 602 603 UsbKeyboardDevice = (USB_KB_DEV *) Context; 604 if (UsbKeyboardDevice->Signature != USB_KB_DEV_SIGNATURE) { 605 return; 606 } 607 608 // 609 // Try to get current keyboard layout from HII database 610 // 611 KeyboardLayout = GetCurrentKeyboardLayout (); 612 if (KeyboardLayout == NULL) { 613 return; 614 } 615 616 // 617 // Re-allocate resource for KeyConvertionTable 618 // 619 ReleaseKeyboardLayoutResources (UsbKeyboardDevice); 620 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR)); 621 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL); 622 623 // 624 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT 625 // 626 KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT)); 627 for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) { 628 // 629 // Copy from HII keyboard layout package binary for alignment 630 // 631 CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR)); 632 633 // 634 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode. 635 // 636 KeyCode = EfiKeyToUsbKeyCodeConvertionTable [(UINT8) (TempKey.Key)]; 637 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, KeyCode); 638 if (TableEntry == NULL) { 639 ReleaseKeyboardLayoutResources (UsbKeyboardDevice); 640 FreePool (KeyboardLayout); 641 return; 642 } 643 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR)); 644 645 // 646 // For non-spacing key, create the list with a non-spacing key followed by physical keys. 647 // 648 if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) { 649 UsbNsKey = AllocateZeroPool (sizeof (USB_NS_KEY)); 650 ASSERT (UsbNsKey != NULL); 651 652 // 653 // Search for sequential children physical key definitions 654 // 655 KeyCount = 0; 656 NsKey = KeyDescriptor + 1; 657 for (Index2 = (UINT8) Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) { 658 CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR)); 659 if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) { 660 KeyCount++; 661 } else { 662 break; 663 } 664 NsKey++; 665 } 666 667 UsbNsKey->Signature = USB_NS_KEY_SIGNATURE; 668 UsbNsKey->KeyCount = KeyCount; 669 UsbNsKey->NsKey = AllocateCopyPool ( 670 (KeyCount + 1) * sizeof (EFI_KEY_DESCRIPTOR), 671 KeyDescriptor 672 ); 673 InsertTailList (&UsbKeyboardDevice->NsKeyList, &UsbNsKey->Link); 674 675 // 676 // Skip over the child physical keys 677 // 678 Index += KeyCount; 679 KeyDescriptor += KeyCount; 680 } 681 682 KeyDescriptor++; 683 } 684 685 // 686 // There are two EfiKeyEnter, duplicate its key descriptor 687 // 688 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, 0x58); 689 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28); 690 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR)); 691 692 FreePool (KeyboardLayout); 693 } 694 695 /** 696 Destroy resources for keyboard layout. 697 698 @param UsbKeyboardDevice The USB_KB_DEV instance. 699 700 **/ 701 VOID 702 ReleaseKeyboardLayoutResources ( 703 IN OUT USB_KB_DEV *UsbKeyboardDevice 704 ) 705 { 706 USB_NS_KEY *UsbNsKey; 707 LIST_ENTRY *Link; 708 709 if (UsbKeyboardDevice->KeyConvertionTable != NULL) { 710 FreePool (UsbKeyboardDevice->KeyConvertionTable); 711 } 712 UsbKeyboardDevice->KeyConvertionTable = NULL; 713 714 while (!IsListEmpty (&UsbKeyboardDevice->NsKeyList)) { 715 Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList); 716 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link); 717 RemoveEntryList (&UsbNsKey->Link); 718 719 FreePool (UsbNsKey->NsKey); 720 FreePool (UsbNsKey); 721 } 722 } 723 724 /** 725 Initialize USB keyboard layout. 726 727 This function initializes Key Convertion Table for the USB keyboard device. 728 It first tries to retrieve layout from HII database. If failed and default 729 layout is enabled, then it just uses the default layout. 730 731 @param UsbKeyboardDevice The USB_KB_DEV instance. 732 733 @retval EFI_SUCCESS Initialization succeeded. 734 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII 735 database, and default layout is disabled. 736 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group. 737 738 **/ 739 EFI_STATUS 740 InitKeyboardLayout ( 741 OUT USB_KB_DEV *UsbKeyboardDevice 742 ) 743 { 744 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout; 745 EFI_STATUS Status; 746 747 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR)); 748 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL); 749 750 InitializeListHead (&UsbKeyboardDevice->NsKeyList); 751 UsbKeyboardDevice->CurrentNsKey = NULL; 752 UsbKeyboardDevice->KeyboardLayoutEvent = NULL; 753 754 // 755 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group, 756 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout(). 757 // 758 Status = gBS->CreateEventEx ( 759 EVT_NOTIFY_SIGNAL, 760 TPL_NOTIFY, 761 SetKeyboardLayoutEvent, 762 UsbKeyboardDevice, 763 &gEfiHiiKeyBoardLayoutGuid, 764 &UsbKeyboardDevice->KeyboardLayoutEvent 765 ); 766 if (EFI_ERROR (Status)) { 767 return Status; 768 } 769 770 KeyboardLayout = GetCurrentKeyboardLayout (); 771 if (KeyboardLayout != NULL) { 772 // 773 // If current keyboard layout is successfully retrieved from HII database, 774 // force to initialize the keyboard layout. 775 // 776 gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent); 777 } else { 778 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) { 779 // 780 // If no keyboard layout can be retrieved from HII database, and default layout 781 // is disabled, then return EFI_NOT_READY. 782 // 783 return EFI_NOT_READY; 784 } 785 // 786 // If no keyboard layout can be retrieved from HII database, and default layout 787 // is enabled, then load the default keyboard layout. 788 // 789 InstallDefaultKeyboardLayout (UsbKeyboardDevice); 790 } 791 792 return EFI_SUCCESS; 793 } 794 795 796 /** 797 Initialize USB keyboard device and all private data structures. 798 799 @param UsbKeyboardDevice The USB_KB_DEV instance. 800 801 @retval EFI_SUCCESS Initialization is successful. 802 @retval EFI_DEVICE_ERROR Keyboard initialization failed. 803 804 **/ 805 EFI_STATUS 806 InitUSBKeyboard ( 807 IN OUT USB_KB_DEV *UsbKeyboardDevice 808 ) 809 { 810 UINT16 ConfigValue; 811 UINT8 Protocol; 812 EFI_STATUS Status; 813 UINT32 TransferResult; 814 815 REPORT_STATUS_CODE_WITH_DEVICE_PATH ( 816 EFI_PROGRESS_CODE, 817 (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST), 818 UsbKeyboardDevice->DevicePath 819 ); 820 821 InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY)); 822 InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA)); 823 InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA)); 824 825 // 826 // Use the config out of the descriptor 827 // Assumed the first config is the correct one and this is not always the case 828 // 829 Status = UsbGetConfiguration ( 830 UsbKeyboardDevice->UsbIo, 831 &ConfigValue, 832 &TransferResult 833 ); 834 if (EFI_ERROR (Status)) { 835 ConfigValue = 0x01; 836 // 837 // Uses default configuration to configure the USB Keyboard device. 838 // 839 Status = UsbSetConfiguration ( 840 UsbKeyboardDevice->UsbIo, 841 ConfigValue, 842 &TransferResult 843 ); 844 if (EFI_ERROR (Status)) { 845 // 846 // If configuration could not be set here, it means 847 // the keyboard interface has some errors and could 848 // not be initialized 849 // 850 REPORT_STATUS_CODE_WITH_DEVICE_PATH ( 851 EFI_ERROR_CODE | EFI_ERROR_MINOR, 852 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR), 853 UsbKeyboardDevice->DevicePath 854 ); 855 856 return EFI_DEVICE_ERROR; 857 } 858 } 859 860 UsbGetProtocolRequest ( 861 UsbKeyboardDevice->UsbIo, 862 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, 863 &Protocol 864 ); 865 // 866 // Set boot protocol for the USB Keyboard. 867 // This driver only supports boot protocol. 868 // 869 if (Protocol != BOOT_PROTOCOL) { 870 UsbSetProtocolRequest ( 871 UsbKeyboardDevice->UsbIo, 872 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, 873 BOOT_PROTOCOL 874 ); 875 } 876 877 UsbKeyboardDevice->CtrlOn = FALSE; 878 UsbKeyboardDevice->AltOn = FALSE; 879 UsbKeyboardDevice->ShiftOn = FALSE; 880 UsbKeyboardDevice->NumLockOn = FALSE; 881 UsbKeyboardDevice->CapsOn = FALSE; 882 UsbKeyboardDevice->ScrollOn = FALSE; 883 884 UsbKeyboardDevice->LeftCtrlOn = FALSE; 885 UsbKeyboardDevice->LeftAltOn = FALSE; 886 UsbKeyboardDevice->LeftShiftOn = FALSE; 887 UsbKeyboardDevice->LeftLogoOn = FALSE; 888 UsbKeyboardDevice->RightCtrlOn = FALSE; 889 UsbKeyboardDevice->RightAltOn = FALSE; 890 UsbKeyboardDevice->RightShiftOn = FALSE; 891 UsbKeyboardDevice->RightLogoOn = FALSE; 892 UsbKeyboardDevice->MenuKeyOn = FALSE; 893 UsbKeyboardDevice->SysReqOn = FALSE; 894 895 UsbKeyboardDevice->AltGrOn = FALSE; 896 897 UsbKeyboardDevice->CurrentNsKey = NULL; 898 899 // 900 // Sync the initial state of lights on keyboard. 901 // 902 SetKeyLED (UsbKeyboardDevice); 903 904 ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8); 905 906 // 907 // Create event for repeat keys' generation. 908 // 909 if (UsbKeyboardDevice->RepeatTimer != NULL) { 910 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer); 911 UsbKeyboardDevice->RepeatTimer = NULL; 912 } 913 914 gBS->CreateEvent ( 915 EVT_TIMER | EVT_NOTIFY_SIGNAL, 916 TPL_CALLBACK, 917 USBKeyboardRepeatHandler, 918 UsbKeyboardDevice, 919 &UsbKeyboardDevice->RepeatTimer 920 ); 921 922 // 923 // Create event for delayed recovery, which deals with device error. 924 // 925 if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) { 926 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent); 927 UsbKeyboardDevice->DelayedRecoveryEvent = NULL; 928 } 929 930 gBS->CreateEvent ( 931 EVT_TIMER | EVT_NOTIFY_SIGNAL, 932 TPL_NOTIFY, 933 USBKeyboardRecoveryHandler, 934 UsbKeyboardDevice, 935 &UsbKeyboardDevice->DelayedRecoveryEvent 936 ); 937 938 return EFI_SUCCESS; 939 } 940 941 942 /** 943 Handler function for USB keyboard's asynchronous interrupt transfer. 944 945 This function is the handler function for USB keyboard's asynchronous interrupt transfer 946 to manage the keyboard. It parses the USB keyboard input report, and inserts data to 947 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key 948 is also set accordingly. 949 950 @param Data A pointer to a buffer that is filled with key data which is 951 retrieved via asynchronous interrupt transfer. 952 @param DataLength Indicates the size of the data buffer. 953 @param Context Pointing to USB_KB_DEV instance. 954 @param Result Indicates the result of the asynchronous interrupt transfer. 955 956 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully. 957 @retval EFI_DEVICE_ERROR Hardware error occurs. 958 959 **/ 960 EFI_STATUS 961 EFIAPI 962 KeyboardHandler ( 963 IN VOID *Data, 964 IN UINTN DataLength, 965 IN VOID *Context, 966 IN UINT32 Result 967 ) 968 { 969 USB_KB_DEV *UsbKeyboardDevice; 970 EFI_USB_IO_PROTOCOL *UsbIo; 971 UINT8 *CurKeyCodeBuffer; 972 UINT8 *OldKeyCodeBuffer; 973 UINT8 CurModifierMap; 974 UINT8 OldModifierMap; 975 UINT8 Mask; 976 UINTN Index; 977 UINT8 Index2; 978 BOOLEAN KeyRelease; 979 BOOLEAN KeyPress; 980 USB_KEY UsbKey; 981 UINT8 NewRepeatKey; 982 UINT32 UsbStatus; 983 EFI_KEY_DESCRIPTOR *KeyDescriptor; 984 985 ASSERT (Context != NULL); 986 987 NewRepeatKey = 0; 988 UsbKeyboardDevice = (USB_KB_DEV *) Context; 989 UsbIo = UsbKeyboardDevice->UsbIo; 990 991 // 992 // Analyzes Result and performs corresponding action. 993 // 994 if (Result != EFI_USB_NOERROR) { 995 // 996 // Some errors happen during the process 997 // 998 REPORT_STATUS_CODE_WITH_DEVICE_PATH ( 999 EFI_ERROR_CODE | EFI_ERROR_MINOR, 1000 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR), 1001 UsbKeyboardDevice->DevicePath 1002 ); 1003 1004 // 1005 // Stop the repeat key generation if any 1006 // 1007 UsbKeyboardDevice->RepeatKey = 0; 1008 1009 gBS->SetTimer ( 1010 UsbKeyboardDevice->RepeatTimer, 1011 TimerCancel, 1012 USBKBD_REPEAT_RATE 1013 ); 1014 1015 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) { 1016 UsbClearEndpointHalt ( 1017 UsbIo, 1018 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, 1019 &UsbStatus 1020 ); 1021 } 1022 1023 // 1024 // Delete & Submit this interrupt again 1025 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt. 1026 // 1027 UsbIo->UsbAsyncInterruptTransfer ( 1028 UsbIo, 1029 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, 1030 FALSE, 1031 0, 1032 0, 1033 NULL, 1034 NULL 1035 ); 1036 // 1037 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling. 1038 // 1039 gBS->SetTimer ( 1040 UsbKeyboardDevice->DelayedRecoveryEvent, 1041 TimerRelative, 1042 EFI_USB_INTERRUPT_DELAY 1043 ); 1044 1045 return EFI_DEVICE_ERROR; 1046 } 1047 1048 // 1049 // If no error and no data, just return EFI_SUCCESS. 1050 // 1051 if (DataLength == 0 || Data == NULL) { 1052 return EFI_SUCCESS; 1053 } 1054 1055 // 1056 // Following code checks current keyboard input report against old key code buffer. 1057 // According to USB HID Firmware Specification, the report consists of 8 bytes. 1058 // Byte 0 is map of Modifier keys. 1059 // Byte 1 is reserved. 1060 // Bytes 2 to 7 are keycodes. 1061 // 1062 CurKeyCodeBuffer = (UINT8 *) Data; 1063 OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray; 1064 1065 // 1066 // Checks for new key stroke. 1067 // 1068 for (Index = 0; Index < 8; Index++) { 1069 if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) { 1070 break; 1071 } 1072 } 1073 1074 // 1075 // If no new key, return EFI_SUCCESS immediately. 1076 // 1077 if (Index == 8) { 1078 return EFI_SUCCESS; 1079 } 1080 1081 // 1082 // Parse the modifier key, which is the first byte of keyboard input report. 1083 // 1084 CurModifierMap = CurKeyCodeBuffer[0]; 1085 OldModifierMap = OldKeyCodeBuffer[0]; 1086 1087 // 1088 // Handle modifier key's pressing or releasing situation. 1089 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys: 1090 // Bit0: Left Control, Keycode: 0xe0 1091 // Bit1: Left Shift, Keycode: 0xe1 1092 // Bit2: Left Alt, Keycode: 0xe2 1093 // Bit3: Left GUI, Keycode: 0xe3 1094 // Bit4: Right Control, Keycode: 0xe4 1095 // Bit5: Right Shift, Keycode: 0xe5 1096 // Bit6: Right Alt, Keycode: 0xe6 1097 // Bit7: Right GUI, Keycode: 0xe7 1098 // 1099 for (Index = 0; Index < 8; Index++) { 1100 Mask = (UINT8) (1 << Index); 1101 if ((CurModifierMap & Mask) != (OldModifierMap & Mask)) { 1102 // 1103 // If current modifier key is up, then CurModifierMap & Mask = 0; 1104 // otherwise it is a non-zero value. 1105 // Insert the changed modifier key into key buffer. 1106 // 1107 UsbKey.KeyCode = (UINT8) (0xe0 + Index); 1108 UsbKey.Down = (BOOLEAN) ((CurModifierMap & Mask) != 0); 1109 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); 1110 } 1111 } 1112 1113 // 1114 // Handle normal key's releasing situation 1115 // Bytes 2 to 7 are for normal keycodes 1116 // 1117 KeyRelease = FALSE; 1118 for (Index = 2; Index < 8; Index++) { 1119 1120 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) { 1121 continue; 1122 } 1123 // 1124 // For any key in old keycode buffer, if it is not in current keycode buffer, 1125 // then it is released. Otherwise, it is not released. 1126 // 1127 KeyRelease = TRUE; 1128 for (Index2 = 2; Index2 < 8; Index2++) { 1129 1130 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) { 1131 continue; 1132 } 1133 1134 if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) { 1135 KeyRelease = FALSE; 1136 break; 1137 } 1138 } 1139 1140 if (KeyRelease) { 1141 UsbKey.KeyCode = OldKeyCodeBuffer[Index]; 1142 UsbKey.Down = FALSE; 1143 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); 1144 // 1145 // The original repeat key is released. 1146 // 1147 if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) { 1148 UsbKeyboardDevice->RepeatKey = 0; 1149 } 1150 } 1151 } 1152 1153 // 1154 // If original repeat key is released, cancel the repeat timer 1155 // 1156 if (UsbKeyboardDevice->RepeatKey == 0) { 1157 gBS->SetTimer ( 1158 UsbKeyboardDevice->RepeatTimer, 1159 TimerCancel, 1160 USBKBD_REPEAT_RATE 1161 ); 1162 } 1163 1164 // 1165 // Handle normal key's pressing situation 1166 // 1167 KeyPress = FALSE; 1168 for (Index = 2; Index < 8; Index++) { 1169 1170 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) { 1171 continue; 1172 } 1173 // 1174 // For any key in current keycode buffer, if it is not in old keycode buffer, 1175 // then it is pressed. Otherwise, it is not pressed. 1176 // 1177 KeyPress = TRUE; 1178 for (Index2 = 2; Index2 < 8; Index2++) { 1179 1180 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) { 1181 continue; 1182 } 1183 1184 if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) { 1185 KeyPress = FALSE; 1186 break; 1187 } 1188 } 1189 1190 if (KeyPress) { 1191 UsbKey.KeyCode = CurKeyCodeBuffer[Index]; 1192 UsbKey.Down = TRUE; 1193 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); 1194 1195 // 1196 // Handle repeat key 1197 // 1198 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]); 1199 if (KeyDescriptor == NULL) { 1200 continue; 1201 } 1202 1203 if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) { 1204 // 1205 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them. 1206 // 1207 UsbKeyboardDevice->RepeatKey = 0; 1208 } else { 1209 // 1210 // Prepare new repeat key, and clear the original one. 1211 // 1212 NewRepeatKey = CurKeyCodeBuffer[Index]; 1213 UsbKeyboardDevice->RepeatKey = 0; 1214 } 1215 } 1216 } 1217 1218 // 1219 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure. 1220 // 1221 for (Index = 0; Index < 8; Index++) { 1222 UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index]; 1223 } 1224 1225 // 1226 // If there is new key pressed, update the RepeatKey value, and set the 1227 // timer to repeate delay timer 1228 // 1229 if (NewRepeatKey != 0) { 1230 // 1231 // Sets trigger time to "Repeat Delay Time", 1232 // to trigger the repeat timer when the key is hold long 1233 // enough time. 1234 // 1235 gBS->SetTimer ( 1236 UsbKeyboardDevice->RepeatTimer, 1237 TimerRelative, 1238 USBKBD_REPEAT_DELAY 1239 ); 1240 UsbKeyboardDevice->RepeatKey = NewRepeatKey; 1241 } 1242 1243 return EFI_SUCCESS; 1244 } 1245 1246 1247 /** 1248 Retrieves a USB keycode after parsing the raw data in keyboard buffer. 1249 1250 This function parses keyboard buffer. It updates state of modifier key for 1251 USB_KB_DEV instancem, and returns keycode for output. 1252 1253 @param UsbKeyboardDevice The USB_KB_DEV instance. 1254 @param KeyCode Pointer to the USB keycode for output. 1255 1256 @retval EFI_SUCCESS Keycode successfully parsed. 1257 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode 1258 1259 **/ 1260 EFI_STATUS 1261 USBParseKey ( 1262 IN OUT USB_KB_DEV *UsbKeyboardDevice, 1263 OUT UINT8 *KeyCode 1264 ) 1265 { 1266 USB_KEY UsbKey; 1267 EFI_KEY_DESCRIPTOR *KeyDescriptor; 1268 1269 *KeyCode = 0; 1270 1271 while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) { 1272 // 1273 // Pops one raw data off. 1274 // 1275 Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); 1276 1277 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode); 1278 if (KeyDescriptor == NULL) { 1279 continue; 1280 } 1281 if (!UsbKey.Down) { 1282 // 1283 // Key is released. 1284 // 1285 switch (KeyDescriptor->Modifier) { 1286 1287 // 1288 // Ctrl release 1289 // 1290 case EFI_LEFT_CONTROL_MODIFIER: 1291 UsbKeyboardDevice->LeftCtrlOn = FALSE; 1292 UsbKeyboardDevice->CtrlOn = FALSE; 1293 break; 1294 case EFI_RIGHT_CONTROL_MODIFIER: 1295 UsbKeyboardDevice->RightCtrlOn = FALSE; 1296 UsbKeyboardDevice->CtrlOn = FALSE; 1297 break; 1298 1299 // 1300 // Shift release 1301 // 1302 case EFI_LEFT_SHIFT_MODIFIER: 1303 UsbKeyboardDevice->LeftShiftOn = FALSE; 1304 UsbKeyboardDevice->ShiftOn = FALSE; 1305 break; 1306 case EFI_RIGHT_SHIFT_MODIFIER: 1307 UsbKeyboardDevice->RightShiftOn = FALSE; 1308 UsbKeyboardDevice->ShiftOn = FALSE; 1309 break; 1310 1311 // 1312 // Alt release 1313 // 1314 case EFI_LEFT_ALT_MODIFIER: 1315 UsbKeyboardDevice->LeftAltOn = FALSE; 1316 UsbKeyboardDevice->AltOn = FALSE; 1317 break; 1318 case EFI_RIGHT_ALT_MODIFIER: 1319 UsbKeyboardDevice->RightAltOn = FALSE; 1320 UsbKeyboardDevice->AltOn = FALSE; 1321 break; 1322 1323 // 1324 // Left Logo release 1325 // 1326 case EFI_LEFT_LOGO_MODIFIER: 1327 UsbKeyboardDevice->LeftLogoOn = FALSE; 1328 break; 1329 1330 // 1331 // Right Logo release 1332 // 1333 case EFI_RIGHT_LOGO_MODIFIER: 1334 UsbKeyboardDevice->RightLogoOn = FALSE; 1335 break; 1336 1337 // 1338 // Menu key release 1339 // 1340 case EFI_MENU_MODIFIER: 1341 UsbKeyboardDevice->MenuKeyOn = FALSE; 1342 break; 1343 1344 // 1345 // SysReq release 1346 // 1347 case EFI_PRINT_MODIFIER: 1348 case EFI_SYS_REQUEST_MODIFIER: 1349 UsbKeyboardDevice->SysReqOn = FALSE; 1350 break; 1351 1352 // 1353 // AltGr release 1354 // 1355 case EFI_ALT_GR_MODIFIER: 1356 UsbKeyboardDevice->AltGrOn = FALSE; 1357 break; 1358 1359 default: 1360 break; 1361 } 1362 1363 continue; 1364 } 1365 1366 // 1367 // Analyzes key pressing situation 1368 // 1369 switch (KeyDescriptor->Modifier) { 1370 1371 // 1372 // Ctrl press 1373 // 1374 case EFI_LEFT_CONTROL_MODIFIER: 1375 UsbKeyboardDevice->LeftCtrlOn = TRUE; 1376 UsbKeyboardDevice->CtrlOn = TRUE; 1377 break; 1378 case EFI_RIGHT_CONTROL_MODIFIER: 1379 UsbKeyboardDevice->RightCtrlOn = TRUE; 1380 UsbKeyboardDevice->CtrlOn = TRUE; 1381 break; 1382 1383 // 1384 // Shift press 1385 // 1386 case EFI_LEFT_SHIFT_MODIFIER: 1387 UsbKeyboardDevice->LeftShiftOn = TRUE; 1388 UsbKeyboardDevice->ShiftOn = TRUE; 1389 break; 1390 case EFI_RIGHT_SHIFT_MODIFIER: 1391 UsbKeyboardDevice->RightShiftOn = TRUE; 1392 UsbKeyboardDevice->ShiftOn = TRUE; 1393 break; 1394 1395 // 1396 // Alt press 1397 // 1398 case EFI_LEFT_ALT_MODIFIER: 1399 UsbKeyboardDevice->LeftAltOn = TRUE; 1400 UsbKeyboardDevice->AltOn = TRUE; 1401 break; 1402 case EFI_RIGHT_ALT_MODIFIER: 1403 UsbKeyboardDevice->RightAltOn = TRUE; 1404 UsbKeyboardDevice->AltOn = TRUE; 1405 break; 1406 1407 // 1408 // Left Logo press 1409 // 1410 case EFI_LEFT_LOGO_MODIFIER: 1411 UsbKeyboardDevice->LeftLogoOn = TRUE; 1412 break; 1413 1414 // 1415 // Right Logo press 1416 // 1417 case EFI_RIGHT_LOGO_MODIFIER: 1418 UsbKeyboardDevice->RightLogoOn = TRUE; 1419 break; 1420 1421 // 1422 // Menu key press 1423 // 1424 case EFI_MENU_MODIFIER: 1425 UsbKeyboardDevice->MenuKeyOn = TRUE; 1426 break; 1427 1428 // 1429 // SysReq press 1430 // 1431 case EFI_PRINT_MODIFIER: 1432 case EFI_SYS_REQUEST_MODIFIER: 1433 UsbKeyboardDevice->SysReqOn = TRUE; 1434 break; 1435 1436 // 1437 // AltGr press 1438 // 1439 case EFI_ALT_GR_MODIFIER: 1440 UsbKeyboardDevice->AltGrOn = TRUE; 1441 break; 1442 1443 case EFI_NUM_LOCK_MODIFIER: 1444 // 1445 // Toggle NumLock 1446 // 1447 UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn)); 1448 SetKeyLED (UsbKeyboardDevice); 1449 break; 1450 1451 case EFI_CAPS_LOCK_MODIFIER: 1452 // 1453 // Toggle CapsLock 1454 // 1455 UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn)); 1456 SetKeyLED (UsbKeyboardDevice); 1457 break; 1458 1459 case EFI_SCROLL_LOCK_MODIFIER: 1460 // 1461 // Toggle ScrollLock 1462 // 1463 UsbKeyboardDevice->ScrollOn = (BOOLEAN) (!(UsbKeyboardDevice->ScrollOn)); 1464 SetKeyLED (UsbKeyboardDevice); 1465 break; 1466 1467 default: 1468 break; 1469 } 1470 1471 // 1472 // When encountering Ctrl + Alt + Del, then warm reset. 1473 // 1474 if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) { 1475 if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) { 1476 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); 1477 } 1478 } 1479 1480 *KeyCode = UsbKey.KeyCode; 1481 return EFI_SUCCESS; 1482 } 1483 1484 return EFI_NOT_READY; 1485 } 1486 1487 1488 /** 1489 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY. 1490 1491 @param UsbKeyboardDevice The USB_KB_DEV instance. 1492 @param KeyCode Indicates the key code that will be interpreted. 1493 @param KeyData A pointer to a buffer that is filled in with 1494 the keystroke information for the key that 1495 was pressed. 1496 1497 @retval EFI_SUCCESS Success. 1498 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65. 1499 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar. 1500 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER 1501 @retval EFI_DEVICE_ERROR Keyboard layout is invalid. 1502 1503 **/ 1504 EFI_STATUS 1505 UsbKeyCodeToEfiInputKey ( 1506 IN USB_KB_DEV *UsbKeyboardDevice, 1507 IN UINT8 KeyCode, 1508 OUT EFI_KEY_DATA *KeyData 1509 ) 1510 { 1511 EFI_KEY_DESCRIPTOR *KeyDescriptor; 1512 LIST_ENTRY *Link; 1513 LIST_ENTRY *NotifyList; 1514 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; 1515 1516 // 1517 // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7]. 1518 // 1519 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode); 1520 if (KeyDescriptor == NULL) { 1521 return EFI_DEVICE_ERROR; 1522 } 1523 1524 if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) { 1525 // 1526 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return. 1527 // 1528 UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor); 1529 return EFI_NOT_READY; 1530 } 1531 1532 if (UsbKeyboardDevice->CurrentNsKey != NULL) { 1533 // 1534 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding 1535 // physical key. 1536 // 1537 KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor); 1538 UsbKeyboardDevice->CurrentNsKey = NULL; 1539 } 1540 1541 // 1542 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec. 1543 // 1544 if (KeyDescriptor->Modifier >= (sizeof (ModifierValueToEfiScanCodeConvertionTable) / sizeof (UINT8))) { 1545 return EFI_DEVICE_ERROR; 1546 } 1547 1548 KeyData->Key.ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier]; 1549 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode; 1550 1551 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) { 1552 if (UsbKeyboardDevice->ShiftOn) { 1553 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode; 1554 1555 // 1556 // Need not return associated shift state if a class of printable characters that 1557 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F' 1558 // 1559 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) { 1560 UsbKeyboardDevice->LeftShiftOn = FALSE; 1561 UsbKeyboardDevice->RightShiftOn = FALSE; 1562 } 1563 1564 if (UsbKeyboardDevice->AltGrOn) { 1565 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode; 1566 } 1567 } else { 1568 // 1569 // Shift off 1570 // 1571 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode; 1572 1573 if (UsbKeyboardDevice->AltGrOn) { 1574 KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode; 1575 } 1576 } 1577 } 1578 1579 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) { 1580 if (UsbKeyboardDevice->CapsOn) { 1581 if (KeyData->Key.UnicodeChar == KeyDescriptor->Unicode) { 1582 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode; 1583 } else if (KeyData->Key.UnicodeChar == KeyDescriptor->ShiftedUnicode) { 1584 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode; 1585 } 1586 } 1587 } 1588 1589 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) { 1590 // 1591 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means 1592 // normal key, instead of original control key. So the ScanCode should be cleaned. 1593 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode. 1594 // 1595 if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) { 1596 KeyData->Key.ScanCode = SCAN_NULL; 1597 } else { 1598 KeyData->Key.UnicodeChar = CHAR_NULL; 1599 } 1600 } 1601 1602 // 1603 // Translate Unicode 0x1B (ESC) to EFI Scan Code 1604 // 1605 if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) { 1606 KeyData->Key.ScanCode = SCAN_ESC; 1607 KeyData->Key.UnicodeChar = CHAR_NULL; 1608 } 1609 1610 // 1611 // Not valid for key without both unicode key code and EFI Scan Code. 1612 // 1613 if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) { 1614 if (!UsbKeyboardDevice->IsSupportPartialKey) { 1615 return EFI_NOT_READY; 1616 } 1617 } 1618 1619 // 1620 // Save Shift/Toggle state 1621 // 1622 KeyData->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; 1623 KeyData->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; 1624 1625 if (UsbKeyboardDevice->LeftCtrlOn) { 1626 KeyData->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; 1627 } 1628 if (UsbKeyboardDevice->RightCtrlOn) { 1629 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; 1630 } 1631 if (UsbKeyboardDevice->LeftAltOn) { 1632 KeyData->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED; 1633 } 1634 if (UsbKeyboardDevice->RightAltOn) { 1635 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED; 1636 } 1637 if (UsbKeyboardDevice->LeftShiftOn) { 1638 KeyData->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; 1639 } 1640 if (UsbKeyboardDevice->RightShiftOn) { 1641 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; 1642 } 1643 if (UsbKeyboardDevice->LeftLogoOn) { 1644 KeyData->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; 1645 } 1646 if (UsbKeyboardDevice->RightLogoOn) { 1647 KeyData->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; 1648 } 1649 if (UsbKeyboardDevice->MenuKeyOn) { 1650 KeyData->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED; 1651 } 1652 if (UsbKeyboardDevice->SysReqOn) { 1653 KeyData->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED; 1654 } 1655 1656 if (UsbKeyboardDevice->ScrollOn) { 1657 KeyData->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; 1658 } 1659 if (UsbKeyboardDevice->NumLockOn) { 1660 KeyData->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE; 1661 } 1662 if (UsbKeyboardDevice->CapsOn) { 1663 KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; 1664 } 1665 if (UsbKeyboardDevice->IsSupportPartialKey) { 1666 KeyData->KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED; 1667 } 1668 // 1669 // Signal KeyNotify process event if this key pressed matches any key registered. 1670 // 1671 NotifyList = &UsbKeyboardDevice->NotifyList; 1672 for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) { 1673 CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE); 1674 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { 1675 // 1676 // The key notification function needs to run at TPL_CALLBACK 1677 // while current TPL is TPL_NOTIFY. It will be invoked in 1678 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK. 1679 // 1680 Enqueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, KeyData, sizeof (*KeyData)); 1681 gBS->SignalEvent (UsbKeyboardDevice->KeyNotifyProcessEvent); 1682 } 1683 } 1684 1685 return EFI_SUCCESS; 1686 } 1687 1688 /** 1689 Create the queue. 1690 1691 @param Queue Points to the queue. 1692 @param ItemSize Size of the single item. 1693 1694 **/ 1695 VOID 1696 InitQueue ( 1697 IN OUT USB_SIMPLE_QUEUE *Queue, 1698 IN UINTN ItemSize 1699 ) 1700 { 1701 UINTN Index; 1702 1703 Queue->ItemSize = ItemSize; 1704 Queue->Head = 0; 1705 Queue->Tail = 0; 1706 1707 if (Queue->Buffer[0] != NULL) { 1708 FreePool (Queue->Buffer[0]); 1709 } 1710 1711 Queue->Buffer[0] = AllocatePool (sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]) * ItemSize); 1712 ASSERT (Queue->Buffer[0] != NULL); 1713 1714 for (Index = 1; Index < sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]); Index++) { 1715 Queue->Buffer[Index] = ((UINT8 *) Queue->Buffer[Index - 1]) + ItemSize; 1716 } 1717 } 1718 1719 /** 1720 Destroy the queue 1721 1722 @param Queue Points to the queue. 1723 **/ 1724 VOID 1725 DestroyQueue ( 1726 IN OUT USB_SIMPLE_QUEUE *Queue 1727 ) 1728 { 1729 FreePool (Queue->Buffer[0]); 1730 } 1731 1732 1733 /** 1734 Check whether the queue is empty. 1735 1736 @param Queue Points to the queue. 1737 1738 @retval TRUE Queue is empty. 1739 @retval FALSE Queue is not empty. 1740 1741 **/ 1742 BOOLEAN 1743 IsQueueEmpty ( 1744 IN USB_SIMPLE_QUEUE *Queue 1745 ) 1746 { 1747 // 1748 // Meet FIFO empty condition 1749 // 1750 return (BOOLEAN) (Queue->Head == Queue->Tail); 1751 } 1752 1753 1754 /** 1755 Check whether the queue is full. 1756 1757 @param Queue Points to the queue. 1758 1759 @retval TRUE Queue is full. 1760 @retval FALSE Queue is not full. 1761 1762 **/ 1763 BOOLEAN 1764 IsQueueFull ( 1765 IN USB_SIMPLE_QUEUE *Queue 1766 ) 1767 { 1768 return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head); 1769 } 1770 1771 1772 /** 1773 Enqueue the item to the queue. 1774 1775 @param Queue Points to the queue. 1776 @param Item Points to the item to be enqueued. 1777 @param ItemSize Size of the item. 1778 **/ 1779 VOID 1780 Enqueue ( 1781 IN OUT USB_SIMPLE_QUEUE *Queue, 1782 IN VOID *Item, 1783 IN UINTN ItemSize 1784 ) 1785 { 1786 ASSERT (ItemSize == Queue->ItemSize); 1787 // 1788 // If keyboard buffer is full, throw the 1789 // first key out of the keyboard buffer. 1790 // 1791 if (IsQueueFull (Queue)) { 1792 Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1); 1793 } 1794 1795 CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize); 1796 1797 // 1798 // Adjust the tail pointer of the FIFO keyboard buffer. 1799 // 1800 Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1); 1801 } 1802 1803 1804 /** 1805 Dequeue a item from the queue. 1806 1807 @param Queue Points to the queue. 1808 @param Item Receives the item. 1809 @param ItemSize Size of the item. 1810 1811 @retval EFI_SUCCESS Item was successfully dequeued. 1812 @retval EFI_DEVICE_ERROR The queue is empty. 1813 1814 **/ 1815 EFI_STATUS 1816 Dequeue ( 1817 IN OUT USB_SIMPLE_QUEUE *Queue, 1818 OUT VOID *Item, 1819 IN UINTN ItemSize 1820 ) 1821 { 1822 ASSERT (Queue->ItemSize == ItemSize); 1823 1824 if (IsQueueEmpty (Queue)) { 1825 return EFI_DEVICE_ERROR; 1826 } 1827 1828 CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize); 1829 1830 // 1831 // Adjust the head pointer of the FIFO keyboard buffer. 1832 // 1833 Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1); 1834 1835 return EFI_SUCCESS; 1836 } 1837 1838 1839 /** 1840 Sets USB keyboard LED state. 1841 1842 @param UsbKeyboardDevice The USB_KB_DEV instance. 1843 1844 **/ 1845 VOID 1846 SetKeyLED ( 1847 IN USB_KB_DEV *UsbKeyboardDevice 1848 ) 1849 { 1850 LED_MAP Led; 1851 UINT8 ReportId; 1852 1853 // 1854 // Set each field in Led map. 1855 // 1856 Led.NumLock = (UINT8) ((UsbKeyboardDevice->NumLockOn) ? 1 : 0); 1857 Led.CapsLock = (UINT8) ((UsbKeyboardDevice->CapsOn) ? 1 : 0); 1858 Led.ScrollLock = (UINT8) ((UsbKeyboardDevice->ScrollOn) ? 1 : 0); 1859 Led.Resrvd = 0; 1860 1861 ReportId = 0; 1862 // 1863 // Call Set_Report Request to lighten the LED. 1864 // 1865 UsbSetReportRequest ( 1866 UsbKeyboardDevice->UsbIo, 1867 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber, 1868 ReportId, 1869 HID_OUTPUT_REPORT, 1870 1, 1871 (UINT8 *) &Led 1872 ); 1873 } 1874 1875 1876 /** 1877 Handler for Repeat Key event. 1878 1879 This function is the handler for Repeat Key event triggered 1880 by timer. 1881 After a repeatable key is pressed, the event would be triggered 1882 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered, 1883 following trigger will come with interval of USBKBD_REPEAT_RATE. 1884 1885 @param Event The Repeat Key event. 1886 @param Context Points to the USB_KB_DEV instance. 1887 1888 **/ 1889 VOID 1890 EFIAPI 1891 USBKeyboardRepeatHandler ( 1892 IN EFI_EVENT Event, 1893 IN VOID *Context 1894 ) 1895 { 1896 USB_KB_DEV *UsbKeyboardDevice; 1897 USB_KEY UsbKey; 1898 1899 UsbKeyboardDevice = (USB_KB_DEV *) Context; 1900 1901 // 1902 // Do nothing when there is no repeat key. 1903 // 1904 if (UsbKeyboardDevice->RepeatKey != 0) { 1905 // 1906 // Inserts the repeat key into keyboard buffer, 1907 // 1908 UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey; 1909 UsbKey.Down = TRUE; 1910 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); 1911 1912 // 1913 // Set repeat rate for next repeat key generation. 1914 // 1915 gBS->SetTimer ( 1916 UsbKeyboardDevice->RepeatTimer, 1917 TimerRelative, 1918 USBKBD_REPEAT_RATE 1919 ); 1920 } 1921 } 1922 1923 1924 /** 1925 Handler for Delayed Recovery event. 1926 1927 This function is the handler for Delayed Recovery event triggered 1928 by timer. 1929 After a device error occurs, the event would be triggered 1930 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY 1931 is defined in USB standard for error handling. 1932 1933 @param Event The Delayed Recovery event. 1934 @param Context Points to the USB_KB_DEV instance. 1935 1936 **/ 1937 VOID 1938 EFIAPI 1939 USBKeyboardRecoveryHandler ( 1940 IN EFI_EVENT Event, 1941 IN VOID *Context 1942 ) 1943 { 1944 1945 USB_KB_DEV *UsbKeyboardDevice; 1946 EFI_USB_IO_PROTOCOL *UsbIo; 1947 UINT8 PacketSize; 1948 1949 UsbKeyboardDevice = (USB_KB_DEV *) Context; 1950 1951 UsbIo = UsbKeyboardDevice->UsbIo; 1952 1953 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize); 1954 1955 // 1956 // Re-submit Asynchronous Interrupt Transfer for recovery. 1957 // 1958 UsbIo->UsbAsyncInterruptTransfer ( 1959 UsbIo, 1960 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress, 1961 TRUE, 1962 UsbKeyboardDevice->IntEndpointDescriptor.Interval, 1963 PacketSize, 1964 KeyboardHandler, 1965 UsbKeyboardDevice 1966 ); 1967 } 1968