From patchwork Thu Mar 17 14:36:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gary guo X-Patchwork-Id: 64005 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp507911lbc; Thu, 17 Mar 2016 07:38:16 -0700 (PDT) X-Received: by 10.98.19.195 with SMTP id 64mr14349018pft.62.1458225496154; Thu, 17 Mar 2016 07:38:16 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id h17si6202827pfj.143.2016.03.17.07.38.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Mar 2016 07:38:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id BF5D01A1E50; Thu, 17 Mar 2016 07:38:35 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x22e.google.com (mail-pf0-x22e.google.com [IPv6:2607:f8b0:400e:c00::22e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 55C451A1E47 for ; Thu, 17 Mar 2016 07:38:34 -0700 (PDT) Received: by mail-pf0-x22e.google.com with SMTP id u190so123656218pfb.3 for ; Thu, 17 Mar 2016 07:38:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xRuU/49FCPPNpiLgJZdZVLtkDiJFkdqNt4bnoALh1oA=; b=QgpQKz/0ipQvS0k3IoBoz2w5E/NKmG1zgypYufem+y//VpvuOyv5bWvKrlnF7vqpMz B6uGEy20btlciuYJBxUnpHAnMGhMVi+77Bri7DS5BjKwSCdBjEEzeQZcSYjZuMp2qbhV gMaoqdYkArhXnzsekDbuH7A0SCCWQ1zGgdNIU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xRuU/49FCPPNpiLgJZdZVLtkDiJFkdqNt4bnoALh1oA=; b=NMuNZlwX+u+6iroRFMoY1PEnLgpUQpEvm9V0c7XgXmMTsTsn6jxnQHKHzMZxCZ6ANO BgE7lmDQputVWKOhGwq4n74VwXn/F3vzwuFKWnDUG6CpR9jElsnH+DhiueE/0UEw+fdc rnOJBNEnWBXiTUT1IiVq3je00kIZzwjatz85rF2oZt6a7SuRZqbuGq8nUUbA+g9eNuAN tRXgfBYjqyoVk7vG7UK59DLBuHNarJiTBYOme7oshImNdO5Kjj+Bjy0iqcdzrbWl924T CWVnUU04P8NMugxXifYLpUZlbY4fsXpWGFK1Zz8VJGu71H+hj59Pz0wK7ILS3wgdgtwL EH9A== X-Gm-Message-State: AD7BkJJ9yInvszwO/2bQDlhFsvekiireo9g5549yEfgKWGMdili+IGdSkl5ZZP8oBc/nmXNC X-Received: by 10.66.140.70 with SMTP id re6mr15521553pab.100.1458225494037; Thu, 17 Mar 2016 07:38:14 -0700 (PDT) Received: from localhost.localdomain ([104.237.91.211]) by smtp.gmail.com with ESMTPSA id 87sm13933748pfq.93.2016.03.17.07.38.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 17 Mar 2016 07:38:13 -0700 (PDT) From: Heyi Guo To: edk2-devel@lists.01.org Date: Thu, 17 Mar 2016 22:36:54 +0800 Message-Id: <1458225414-19812-4-git-send-email-heyi.guo@linaro.org> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1458225414-19812-1-git-send-email-heyi.guo@linaro.org> References: <1458225414-19812-1-git-send-email-heyi.guo@linaro.org> Subject: [edk2] [PATCH v2 3/3] MdeModulePkg/TerminalDxe: Set polling rate by serial IO mode X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Heyi Guo , Feng Tian , Star Zeng MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Calculate serial input polling rate according to parameters from serial IO mode as below, to fix potential input truncation with fixed polling interval 0.02s. Polling interval (100ns) = FifoDepth * (ParityBits + StopBits + DataBits) * 10,000,000 / BaudRate However, as UEFI events will probably delayed by other code of higher TPL, we use below equation to make polling rate fast enough: FifoDepth * DataBits * 10,000,000 * 2 / (BaudRate * 3) Signed-off-by: Heyi Guo Cc: Feng Tian Cc: Star Zeng --- .../Universal/Console/TerminalDxe/Terminal.c | 5 +- .../Universal/Console/TerminalDxe/Terminal.h | 27 ++++++++- .../Universal/Console/TerminalDxe/TerminalConIn.c | 68 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) -- 2.7.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c index 5adaa97..db790f3 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c @@ -71,6 +71,7 @@ TERMINAL_DEV mTerminalDevTemplate = { }, NULL, // TerminalConsoleModeData 0, // SerialInTimeOut + DEFAULT_KEYBOARD_TIMER_INTERVAL, // KeyboardTimerInterval NULL, // RawFifo NULL, // UnicodeFiFo @@ -984,10 +985,12 @@ TerminalDriverBindingStart ( ); ASSERT_EFI_ERROR (Status); + TerminalDevice->KeyboardTimerInterval = GetKeyboardTimerInterval (Mode); + Status = gBS->SetTimer ( TerminalDevice->TimerEvent, TimerPeriodic, - KEYBOARD_TIMER_INTERVAL + TerminalDevice->KeyboardTimerInterval ); ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h index 269d2ae..58d5664 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h @@ -68,7 +68,7 @@ typedef struct { UINTN Rows; } TERMINAL_CONSOLE_MODE_DATA; -#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s +#define DEFAULT_KEYBOARD_TIMER_INTERVAL 200000 // 0.02s #define TERMINAL_DEV_SIGNATURE SIGNATURE_32 ('t', 'm', 'n', 'l') @@ -91,6 +91,7 @@ typedef struct { EFI_SIMPLE_TEXT_OUTPUT_MODE SimpleTextOutputMode; TERMINAL_CONSOLE_MODE_DATA *TerminalConsoleModeData; UINTN SerialInTimeOut; + UINT64 KeyboardTimerInterval; RAW_DATA_FIFO *RawFiFo; UNICODE_FIFO *UnicodeFiFo; EFI_KEY_FIFO *EfiKeyFiFo; @@ -1358,4 +1359,28 @@ TerminalConInTimerHandler ( IN EFI_EVENT Event, IN VOID *Context ); + +/** + Calculate input polling timer interval by serial IO mode. + + @param Mode Pointer to serial IO mode. + + @retval The required polling timer interval in 100ns. + +**/ +UINT64 +GetKeyboardTimerInterval ( + IN EFI_SERIAL_IO_MODE *Mode + ); + +/** + Update period of polling timer event. + + @param TerminalDevice The terminal device to update. +**/ +VOID +UpdatePollingRate ( + IN TERMINAL_DEV *TerminalDevice + ); + #endif diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c index 2215df6..22349a0 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c @@ -502,6 +502,71 @@ TerminalConInWaitForKey ( } /** + Calculate input polling timer interval by serial IO mode. + + @param Mode Pointer to serial IO mode. + + @retval The required polling timer interval in 100ns. + +**/ +UINT64 +GetKeyboardTimerInterval ( + IN EFI_SERIAL_IO_MODE *Mode + ) +{ + UINT32 FifoDepth; + + if (Mode->BaudRate == 0) { + return DEFAULT_KEYBOARD_TIMER_INTERVAL; + } + + FifoDepth = Mode->ReceiveFifoDepth; + // Fix incorrect FIFO depth + if (FifoDepth == 0) { + FifoDepth = 1; + } + + // We ignore stop bits and parity bit, and reduce the interval by 1/3, + // to make polling rate fast enough to avoid serial input truncation. + return DivU64x64Remainder ( + FifoDepth * Mode->DataBits * 10000000 * 2, + Mode->BaudRate * 3, + NULL + ); +} + + +/** + Update period of polling timer event. + + @param TerminalDevice The terminal device to update. +**/ +VOID +UpdatePollingRate ( + IN TERMINAL_DEV *TerminalDevice + ) +{ + UINT64 NewInterval; + EFI_STATUS Status; + + NewInterval = GetKeyboardTimerInterval (TerminalDevice->SerialIo->Mode); + + if (TerminalDevice->KeyboardTimerInterval == NewInterval) { + return; + } + + Status = gBS->SetTimer ( + TerminalDevice->TimerEvent, + TimerPeriodic, + NewInterval + ); + ASSERT_EFI_ERROR (Status); + + TerminalDevice->KeyboardTimerInterval = NewInterval; +} + + +/** Timer handler to poll the key from serial. @param Event Indicates the event that invoke this function. @@ -560,6 +625,9 @@ TerminalConInTimerHandler ( TerminalDevice->SerialInTimeOut = SerialInTimeOut; } } + + UpdatePollingRate (TerminalDevice); + // // Check whether serial buffer is empty. // Skip the key transfer loop only if the SerialIo protocol instance