From 4ccfd30544d1da8f3b5a02293f1feca702dde90a Mon Sep 17 00:00:00 2001 From: li-elvin Date: Thu, 11 Oct 2012 07:01:22 +0000 Subject: [PATCH] Add PcdFastPS2Detection to improve PS2 keyboard driver start performance. Signed-off-by: Li Elvin Reviewed-by: Yao Jiewen git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13820 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c | 192 +++++++------- .../Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c | 20 +- .../Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf | 3 + .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c | 250 +++++++++--------- .../Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf | 5 +- .../IntelFrameworkModulePkg.dec | 5 +- 6 files changed, 251 insertions(+), 224 deletions(-) diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c index 4ad80c17c1..05b62f6a8c 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c @@ -1519,16 +1519,18 @@ InitKeyboard ( // Perform a read to cleanup the Status Register's // output buffer full bits within MAX TRY times // - while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) { - Status = KeyboardRead (ConsoleIn, &CommandByte); - TryTime ++; - } - // - // Exceed the max try times. The device may be error. - // - if (TryTime == KEYBOARD_MAX_TRY) { - Status = EFI_DEVICE_ERROR; - goto Done; + if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) { + while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) { + Status = KeyboardRead (ConsoleIn, &CommandByte); + TryTime ++; + } + // + // Exceed the max try times. The device may be error. + // + if (TryTime == KEYBOARD_MAX_TRY) { + Status = EFI_DEVICE_ERROR; + goto Done; + } } // // We should disable mouse interface during the initialization process @@ -1543,34 +1545,37 @@ InitKeyboard ( // time initialization // if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG) != 0) { - // - // 8042 controller is already setup (by myself or by mouse driver): - // See whether mouse interface is already enabled - // which determines whether we should enable it later - // - // - // Read the command byte of 8042 controller - // - Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ); - if (EFI_ERROR (Status)) { - KeyboardError (ConsoleIn, L"\n\r"); - goto Done; - } - - Status = KeyboardRead (ConsoleIn, &CommandByte); - if (EFI_ERROR (Status)) { - KeyboardError (ConsoleIn, L"\n\r"); - goto Done; - } - // - // Test the mouse enabling bit - // - if ((CommandByte & 0x20) != 0) { - mEnableMouseInterface = FALSE; + if (!PcdGetBool (PcdFastPS2Detection)) { + // + // 8042 controller is already setup (by myself or by mouse driver): + // See whether mouse interface is already enabled + // which determines whether we should enable it later + // + // + // Read the command byte of 8042 controller + // + Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ); + if (EFI_ERROR (Status)) { + KeyboardError (ConsoleIn, L"\n\r"); + goto Done; + } + + Status = KeyboardRead (ConsoleIn, &CommandByte); + if (EFI_ERROR (Status)) { + KeyboardError (ConsoleIn, L"\n\r"); + goto Done; + } + // + // Test the mouse enabling bit + // + if ((CommandByte & 0x20) != 0) { + mEnableMouseInterface = FALSE; + } else { + mEnableMouseInterface = TRUE; + } } else { - mEnableMouseInterface = TRUE; - } - + mEnableMouseInterface = FALSE; + } } else { // // 8042 controller is not setup yet: @@ -1580,36 +1585,38 @@ InitKeyboard ( // // Disable keyboard and mouse interfaces // - Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE); - if (EFI_ERROR (Status)) { - KeyboardError (ConsoleIn, L"\n\r"); - goto Done; - } - - Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE); - if (EFI_ERROR (Status)) { - KeyboardError (ConsoleIn, L"\n\r"); - goto Done; - } - - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST, - ConsoleIn->DevicePath - ); - // - // 8042 Controller Self Test - // - Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST); - if (EFI_ERROR (Status)) { - KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r"); - goto Done; - } - - Status = KeyboardWaitForValue (ConsoleIn, 0x55); - if (EFI_ERROR (Status)) { - KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r"); - goto Done; + if (!PcdGetBool (PcdFastPS2Detection)) { + Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE); + if (EFI_ERROR (Status)) { + KeyboardError (ConsoleIn, L"\n\r"); + goto Done; + } + + Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE); + if (EFI_ERROR (Status)) { + KeyboardError (ConsoleIn, L"\n\r"); + goto Done; + } + + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST, + ConsoleIn->DevicePath + ); + // + // 8042 Controller Self Test + // + Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST); + if (EFI_ERROR (Status)) { + KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r"); + goto Done; + } + + Status = KeyboardWaitForValue (ConsoleIn, 0x55); + if (EFI_ERROR (Status)) { + KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r"); + goto Done; + } } // // Don't enable mouse interface later @@ -1865,34 +1872,37 @@ CheckKeyboardConnect ( EFI_STATUS Status; UINTN WaitForValueTimeOutBcakup; - Status = EFI_SUCCESS; // // enable keyboard itself and wait for its ack // If can't receive ack, Keyboard should not be connected. // - Status = KeyboardWrite ( - ConsoleIn, - KEYBOARD_KBEN - ); - - if (EFI_ERROR (Status)) { - return FALSE; - } - // - // wait for 1s - // - WaitForValueTimeOutBcakup = mWaitForValueTimeOut; - mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT; - Status = KeyboardWaitForValue ( - ConsoleIn, - KEYBOARD_CMDECHO_ACK - ); - mWaitForValueTimeOut = WaitForValueTimeOutBcakup; - - if (EFI_ERROR (Status)) { - return FALSE; + if (!PcdGetBool (PcdFastPS2Detection)) { + Status = KeyboardWrite ( + ConsoleIn, + KEYBOARD_KBEN + ); + + if (EFI_ERROR (Status)) { + return FALSE; + } + // + // wait for 1s + // + WaitForValueTimeOutBcakup = mWaitForValueTimeOut; + mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT; + Status = KeyboardWaitForValue ( + ConsoleIn, + KEYBOARD_CMDECHO_ACK + ); + mWaitForValueTimeOut = WaitForValueTimeOutBcakup; + + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; + } else { + return TRUE; } - - return TRUE; } diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c index c73cf93613..4f87990876 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c @@ -263,15 +263,17 @@ KbdControllerDriverStart ( // // Return code is ignored on purpose. // - KeyboardRead (ConsoleIn, &Data); - if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { - // - // If nobody decodes KBC I/O port, it will read back as 0xFF. - // Check the Time-Out and Parity bit to see if it has an active KBC in system - // - Status = EFI_DEVICE_ERROR; - StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED; - goto ErrorExit; + if (!PcdGetBool (PcdFastPS2Detection)) { + KeyboardRead (ConsoleIn, &Data); + if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { + // + // If nobody decodes KBC I/O port, it will read back as 0xFF. + // Check the Time-Out and Parity bit to see if it has an active KBC in system + // + Status = EFI_DEVICE_ERROR; + StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED; + goto ErrorExit; + } } // diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf index 61fd036c3c..f2cc8b0061 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf @@ -68,6 +68,9 @@ [FeaturePcd] gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification +[Pcd] + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdFastPS2Detection + # [Event] # ## # # Event will be signaled for WaitForKey event. diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c index 3f0f9b699b..4ee20df1f7 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c @@ -1037,95 +1037,96 @@ BiosKeyboardReset ( // if not skip step 4&5 and jump to step 6 to selftest KBC and report this // else go step 4 // - if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_SYSF) != 0) { - // - // 4 - // CheckMouseStatus to decide enable it later or not - // - // - // Read the command byte of KBC - // - Status = KeyboardCommand ( - BiosKeyboardPrivate, - KBC_CMDREG_VIA64_CMDBYTE_R - ); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; - } - - Status = KeyboardRead ( - BiosKeyboardPrivate, - &CommandByte - ); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; - } - // - // Check mouse enabled or not before - // - if ((CommandByte & KB_CMMBYTE_DISABLE_AUX) != 0) { - MouseEnable = FALSE; + if (!PcdGetBool (PcdFastPS2Detection)) { + if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_SYSF) != 0) { + // + // 4 + // CheckMouseStatus to decide enable it later or not + // + // + // Read the command byte of KBC + // + Status = KeyboardCommand ( + BiosKeyboardPrivate, + KBC_CMDREG_VIA64_CMDBYTE_R + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = KeyboardRead ( + BiosKeyboardPrivate, + &CommandByte + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + // + // Check mouse enabled or not before + // + if ((CommandByte & KB_CMMBYTE_DISABLE_AUX) != 0) { + MouseEnable = FALSE; + } else { + MouseEnable = TRUE; + } + // + // 5 + // disable mouse (via KBC) and Keyborad device + // + Status = KeyboardCommand ( + BiosKeyboardPrivate, + KBC_CMDREG_VIA64_AUX_DISABLE + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = KeyboardCommand ( + BiosKeyboardPrivate, + KBC_CMDREG_VIA64_KB_DISABLE + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } } else { - MouseEnable = TRUE; - } - // - // 5 - // disable mouse (via KBC) and Keyborad device - // - Status = KeyboardCommand ( - BiosKeyboardPrivate, - KBC_CMDREG_VIA64_AUX_DISABLE - ); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; - } - - Status = KeyboardCommand ( - BiosKeyboardPrivate, - KBC_CMDREG_VIA64_KB_DISABLE - ); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; - } - - } else { - // - // 6 - // KBC Self Test - // - // - // Report a Progress Code for performing a self test on the keyboard controller - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST - ); - - Status = KeyboardCommand ( - BiosKeyboardPrivate, - KBC_CMDREG_VIA64_KBC_SLFTEST - ); - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; - } - - Status = KeyboardWaitForValue ( - BiosKeyboardPrivate, - KBC_CMDECHO_KBCSLFTEST_OK, - KEYBOARD_WAITFORVALUE_TIMEOUT - ); - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; + // + // 6 + // KBC Self Test + // + // + // Report a Progress Code for performing a self test on the keyboard controller + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST + ); + + Status = KeyboardCommand ( + BiosKeyboardPrivate, + KBC_CMDREG_VIA64_KBC_SLFTEST + ); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = KeyboardWaitForValue ( + BiosKeyboardPrivate, + KBC_CMDECHO_KBCSLFTEST_OK, + KEYBOARD_WAITFORVALUE_TIMEOUT + ); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } } } // @@ -1321,14 +1322,16 @@ BiosKeyboardReset ( // Done for validating keyboard. Enable keyboard (via KBC) // and recover the command byte to proper value // - Status = KeyboardCommand ( - BiosKeyboardPrivate, - KBC_CMDREG_VIA64_KB_ENABLE - ); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Exit; + if (!PcdGetBool (PcdFastPS2Detection)) { + Status = KeyboardCommand ( + BiosKeyboardPrivate, + KBC_CMDREG_VIA64_KB_ENABLE + ); + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } } // @@ -1674,35 +1677,38 @@ CheckKeyboardConnect ( // enable keyboard itself and wait for its ack // If can't receive ack, Keyboard should not be connected. // - Status = KeyboardWrite ( - BiosKeyboardPrivate, - KBC_INPBUF_VIA60_KBEN - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Keyboard enable failed!\n")); - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR - ); - return FALSE; - } + if (!PcdGetBool (PcdFastPS2Detection)) { + Status = KeyboardWrite ( + BiosKeyboardPrivate, + KBC_INPBUF_VIA60_KBEN + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Keyboard enable failed!\n")); + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR + ); + return FALSE; + } - Status = KeyboardWaitForValue ( - BiosKeyboardPrivate, - KBC_CMDECHO_ACK, - KEYBOARD_WAITFORVALUE_TIMEOUT - ); + Status = KeyboardWaitForValue ( + BiosKeyboardPrivate, + KBC_CMDECHO_ACK, + KEYBOARD_WAITFORVALUE_TIMEOUT + ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Timeout!\n")); - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR - ); - return FALSE; + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Timeout!\n")); + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR + ); + return FALSE; + } + return TRUE; + } else { + return TRUE; } - - return TRUE; } /** diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf index 28ef29bf1c..ee79f6b607 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf @@ -68,4 +68,7 @@ gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED [FeaturePcd] - gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE \ No newline at end of file + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE + +[Pcd] + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdFastPS2Detection \ No newline at end of file diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec index 6a6228837d..3054bb732a 100644 --- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec +++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec @@ -219,4 +219,7 @@ ## The PCD is used to specify the high PMM (Post Memory Manager) size with bytes above 1MB. # The value should be a multiple of 4KB. gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdHighPmmMemorySize|0x400000|UINT32|0x3000000a - \ No newline at end of file + + ## This PCD specifies whether to use the optimized timing for best PS2 detection performance. + # Note this PCD could be set to TRUE for best boot performance and set to FALSE for best device compatibility. + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdFastPS2Detection|FALSE|BOOLEAN|0x3000000b \ No newline at end of file -- 2.39.2