From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=40.107.0.59; helo=eur02-am5-obe.outbound.protection.outlook.com; envelope-from=meenakshi.aggarwal@nxp.com; receiver=edk2-devel@lists.01.org Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00059.outbound.protection.outlook.com [40.107.0.59]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 52E9D223230CE for ; Fri, 16 Feb 2018 00:46:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=dcKCDyS45Oecaj1zuXIreMf2FaOAVelcouYuaqSpGmA=; b=UpwPVbf1uyzp8H6yCNAEAvG0T7VBaUOS08dXA+cZ+bbrYOzhqQRHpXrL+H1TEdLOp7pm8HTNitjHSH3mfAw5r0pNgeTUeyYu6kq2V3yq4hTkbak4k6ofACFnOhRcIJFV5OUemGJWxYx0S+uGWUJBb8tJoaX7I36+ESP9WaKLvvQ= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=meenakshi.aggarwal@nxp.com; Received: from idcbfarm.ap.freescale.net (192.88.169.1) by VI1PR04MB1008.eurprd04.prod.outlook.com (2a01:111:e400:5090::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.485.10; Fri, 16 Feb 2018 08:52:30 +0000 From: Meenakshi To: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, michael.d.kinney@intel.com, edk2-devel@lists.01.org Date: Fri, 16 Feb 2018 14:19:58 +0530 Message-Id: <1518771035-6733-3-git-send-email-meenakshi.aggarwal@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> MIME-Version: 1.0 X-Originating-IP: [192.88.169.1] X-ClientProxiedBy: HK2PR02CA0172.apcprd02.prod.outlook.com (2603:1096:201:1f::32) To VI1PR04MB1008.eurprd04.prod.outlook.com (2a01:111:e400:5090::28) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 85619082-793f-4cfc-41be-08d5751a9ec2 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:VI1PR04MB1008; X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB1008; 3:OKTUNJgvxaXpzar2B3J8G6eUw3ZL+VL2glv8mkgXjGZta/WtdiXkzgozDdjhsClUYLQaotqp2siUqR/hm4rng0zB9tBnUEuFiZO9KIvUefqyzTYWP+HRsOjzUvly6DwPYLMWyvbnRTAsUzRzJgnsYrKrUKpeXfyR+KrzDqFp7+uuTG0njFg2p9XxYhp5KlBo4uiovG9S9ZnQ3sxzhYi6pyYQ4mG2ROd094NnPivF65tjT9nNpCki4dceMF8fHSYz; 25:tkA/BDSNI8MxhVN0SWBJ0h5pX9OZUXaZgsSlfCT8+CSyXOy7tZIlINrd+wc/+f51PW+XoVXkuiM9BVERa49te6EBg8cPikgDp/390Mw6f/YLH9yZNRK+0EqSleWun/5/9E9WqYqU10ZRllSY6HQzj7no8LLtPgoX+xWZaw/eGo7kg9+z+eS0iRAVlsWt7ddoBNUrs6LpSYucAFCUDxnCnC8RbCP9x6p7E+VSCmr5UJ+7ihRQERvXMDls1eKmh+YKmn1uvrZ5ixZHIDn9v01Ed3ZCZa4i0B0j/DD1g4Nap533umecqmhIU6EafR6K1DU4ZPogNaJi/LbrxZ4kBEBSOg==; 31:1aNTmWPRrx7MjY0+fF79D9q4ii8wmnGk018XK/ESAq3wmcvNBSDrLXjZ6ycFCZ8Y8Q08Pra/KKbxZLuZHKBP0OXbEPlM/zxOyAfPB1/wV2Trlu0j1ipZRb5veQNqxfV3dajAh0d+uLbCgrm/1Xvdiv2VfNS4iK753C/QLI6tMjCmSgrL04R9LmqQWiPUkiNhaUutfTWrLWjoZ2Vb/v6Y5vKBWAfwYnp939Cy+cd7yqs= X-MS-TrafficTypeDiagnostic: VI1PR04MB1008: X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB1008; 20:FQ2wjxu9SxKROdTPoSyaq8wIQGprvrWt80KPNIuEqqGN0+XR16SMMUH74O7B5Hvh8WQOB8qgRcsReS7bFMiWKtMfGPlYhSjwduUpgK8DUqj/MpHxTgF3cRgIj77sYjteF6a+9jZLqr4U9dnrrmB981RIZbs4M0TXL18hS4nDvfU74m9fa5c08mVft4j0NxXoRQ4catc+tLUITxGArslsMwlG2y1vZc7gf/VIxzJpQsn+Mic4KsNLR1lVtrDOPtoKsHcFJsqMdifMk1gZRWYvZgozky/3bUUPb+sORWqhcY4C4K+pSIFQwBeEHmq9AK1pwlC01DO0nZc4pLz3GX6bcA2ESs4HLrIj7PKhhVsHxE4Ab2BchzlSS0AcsK4cEgcaaLlKNWnAIw9aNGOBGb0RS+LdIrkKfEjoF2UF1gInwXi7P+jDMGjIrIh1F4smyce6nXftnyeJ8u+2B7K3/sDBgvmVgTXeQRNcWfqsFQIQuku1DkOWZgEe6aIJ+mruqgm2; 4:O2hK3R7ncdAyQWFo/JSycIY9BZQepxtfAr6vEh3kfKOJM7lq2byIf7bvbCWJBZiTF61lMzw/fJVm3tm+1Lbg1bxWS8apDT9CuM8YDXNuiazTULSgc3xEIIrq/zeNZV3fYgy0Yq/9y1a0AVpTT4tbXFbZU52LOWplyRJEM2htvIY0KqFB9creNLTSS8Wu3hiOoXgD3N9XwVOQ65TaVtTu0MBW+QEd+tqBdqlZYvye+kQPnjl68o8NxyDa+4+N+oYzLTVTinrAePESsK3sphLPZiBtMXRXgaydW8Mj1NpwYu4JZUxSMQy/QPkcJj20Nll8 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(93006095)(93001095)(10201501046)(3002001)(3231101)(944501161)(6055026)(6041288)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:VI1PR04MB1008; BCL:0; PCL:0; RULEID:; SRVR:VI1PR04MB1008; X-Forefront-PRVS: 0585417D7B X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(376002)(39380400002)(396003)(39860400002)(366004)(199004)(50944005)(189003)(86362001)(6486002)(8676002)(76176011)(36756003)(53376002)(966005)(4326008)(6116002)(15188155005)(16799955002)(7736002)(386003)(68736007)(186003)(26005)(53936002)(305945005)(16526019)(81156014)(3846002)(6506007)(478600001)(50226002)(16586007)(8936002)(2950100002)(316002)(2906002)(59450400001)(25786009)(97736004)(50466002)(48376002)(105586002)(52116002)(47776003)(81166006)(51416003)(5660300001)(6666003)(106356001)(66066001)(6306002)(6512007)(171213001)(44824005)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR04MB1008; H:idcbfarm.ap.freescale.net; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR04MB1008; 23:4eYqPM+h+iwWqiyX4NA5FsArRY6+qA98/AAuxO0cp?= =?us-ascii?Q?2PSPZxoU4pvMJaSMGZIspV03uC4K6hld69V/vWiVR1IFOEMnbyAUSu5t+cz2?= =?us-ascii?Q?rNVMZEWbUq7Fz+fDkh1RTqzPOQiFVQoxflQBjjOJPbhEUy2UFh8p+Xj/nVt7?= =?us-ascii?Q?y+KnMeB3aAaZO9vz+kbuNfNJcY2Q4f8GlpO5z1y2A1J86028uDGeonoPlPOY?= =?us-ascii?Q?EIoxfJwHMrwjp4W9CEqx5697kjfLtfWaLGx1N5JR3LZJhpJrZoWt02iSMqbI?= =?us-ascii?Q?oce/BBgsGbMvZ6p9QPFajSSekeS/d7afJ5kQ7KEsDvn8qPs7cUz8DfrJCIlG?= =?us-ascii?Q?L8bXicjpCH1YxUjLuF0Vq2Pgjxpj369q+pxUXdz/Cg5gqv3at2QsyOXvgNxm?= =?us-ascii?Q?o0GpCkYg2A2QRKbuqGkyHgrgWAjzrJ4S7G2oAgoEDeYuVIM44pZkW9SnU/kr?= =?us-ascii?Q?qk9h+lHPY7BX+NZ6c0aHwHBIqr1o0t6dLG9qYYf/mG/W/K42fVCQXeS6SaDq?= =?us-ascii?Q?SFsxruTAzrnFeN/nIn6dqMCQUqEd7xSSepe+xCqN8P7LbCjgxxldktBbvstt?= =?us-ascii?Q?EaAQBdSjcyc6zKCiJBIhjJ/xHXfHNl8BSH2T9PNlII6LOInITnBHGPkoOlwB?= =?us-ascii?Q?XRG2v5EAiCPr4ARTO43peKLqRtHGMQZkN8phnmEjNIuVFL2JZdYLnfWuPmdE?= =?us-ascii?Q?R9BV/IjlQPCmRuoUhF07O1uVWPDSPTVoM4QyWQZnEBMxxgjMSzDjaJZiZsv3?= =?us-ascii?Q?yM3VVziDDMBsQl9DNI5tht7vKRKvrdCv1dhJfGmdUoZrsy1LQZNxosFK13Be?= =?us-ascii?Q?x6+qznclV3PezaPu4w9/uKvHwtAR9O+RdSTiCnFu4MXRkuB86cz0VzO/ANWM?= =?us-ascii?Q?7h8bBRZ+kragtWKINvdDYxzhHRCFazARkHGvUYvNOhP3Ee+JTy2l41l6I7Ow?= =?us-ascii?Q?SqUouNQm8rrHg2RMdDvgFoQg9cRYBlWPSlg/n0LCvU4vEocwn85rhGFkuN0T?= =?us-ascii?Q?ltxjSptKkDkP0mnNrAIZ+FonOfJjOHbZxHC8qZNRDfVEoAXN8rPNkTEaHbam?= =?us-ascii?Q?np2pjUE97mA8zlIzVu2ydRcxyTSvSGniO26FBY69M0qJhI9nWdSttWjiRIB1?= =?us-ascii?Q?+JxoQ8yk48SWNTqkdRRBPVmY2nzo5vvKoCxaJf0Y6B1t7nuauJku7XgURt8G?= =?us-ascii?Q?xDdjZoOLn4W/4z/hALsX6Wr8f0Ve9uBTLyNfOfIVVTA6eSTWqPdv7jE6Wzxk?= =?us-ascii?Q?uAlDJ2EJ+eTER2hI3U8Gp+Qb56LQ7xTGmoF3mSJP3UgWN5H00nm69+34cO1N?= =?us-ascii?Q?11eTpVhx4usC2BzwhEhlMw=3D?= X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB1008; 6:XytH9tK5XxWszU5JpUzrZpFwoBdH5eGzSza+OyGh2SzCfL0QEsGnr2XsQZV9XItc283884ElIGiIjp2s6k6drPlwsAe9wfX4MRDYWipNt96EHc1nAh1Vs/0F4e5z1ZZVwzp7s7YNnSHKdn4DZ8AmTMkcTlSEMSj5gLpZrG5kHSnIVhjnUVhR5ss6xrP9A38r1tiimpVlQ6LVU5l/pfU8YKhQ5mx5lHDeUAOrGw96hwpdQD2fXQaIfyW/mi2rGC/LRek4wYqHTRbYuOe+5XXFgwYqFdCSPsB7YmAQyaMFUh9qsPkc9JepgmHsexlQ1PVgVdGTb+t8EvrDuaWHXOQ5G41IdsGAlXNyQPJlf7I1Olg=; 5:+crpTJXDNv/+abxjKV+wPubJmlcoQWL+BMzCyzLKBiSrkoHqu9JDt2j5/+5j+a27UI5deVMTqus6XD26G4F4NcQIYydPgnn8DRdytxicJFGR+a/qSqp5FxwS9jvJ16Zpi3DP+za5++rZgUkV++DXKu+7YS43xeStyQirN1B8zNo=; 24:FkGGEzcNVbJeOH4CAsbMc2MoyxKviigrT/Rfc+PwuqUERNl6Hy4bM16N+rseiMBC0yanR/FT2dHbhj4q1OQbb2qi8POFfOljU2QmZpz+rRI=; 7:oADXJJJc4B8s5S6maECVM2ZJxspq3oophV/EHojtukno8DpovYOxqo6+a9NH7/DE5ZiClbiluI1Fb6Lazk85nk/7IQVir58r73Maxb2BxCIejfKwQ3nJ/sfDUBYFJt+bjyJK8YRDc0YyC472yIYHuGJwWual81yEYNFZKx8kOoQTF5GiwwP0+0qaTmuv6PWWnwXRQi1cx16fgJWO0OSGbWm4BxCdi16ultAdNSgFey4aGRnn+jPoFOgz9GOr6EmO SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Feb 2018 08:52:30.5923 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 85619082-793f-4cfc-41be-08d5751a9ec2 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR04MB1008 Subject: [PATCH edk2-platforms 02/39] Silicon/NXP : Add support for Watchdog driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Feb 2018 08:46:48 -0000 Content-Type: text/plain From: Meenakshi Aggarwal Installs watchdog timer arch protocol Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Meenakshi Aggarwal --- Silicon/NXP/Drivers/WatchDog/WatchDog.c | 459 +++++++++++++++++++++++++++ Silicon/NXP/Drivers/WatchDog/WatchDog.h | 39 +++ Silicon/NXP/Drivers/WatchDog/WatchDogDxe.inf | 47 +++ 3 files changed, 545 insertions(+) create mode 100644 Silicon/NXP/Drivers/WatchDog/WatchDog.c create mode 100644 Silicon/NXP/Drivers/WatchDog/WatchDog.h create mode 100644 Silicon/NXP/Drivers/WatchDog/WatchDogDxe.inf diff --git a/Silicon/NXP/Drivers/WatchDog/WatchDog.c b/Silicon/NXP/Drivers/WatchDog/WatchDog.c new file mode 100644 index 0000000..ca1377b --- /dev/null +++ b/Silicon/NXP/Drivers/WatchDog/WatchDog.c @@ -0,0 +1,459 @@ +/** WatchDog.c +* +* Based on Watchdog driver implemenation available in +* ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805Watchdog.c +* +* Copyright 2017 NXP +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "WatchDog.h" + +STATIC EFI_EVENT EfiExitBootServicesEvent; +STATIC EFI_EVENT WdogFeedEvent; + +STATIC +UINT16 +EFIAPI +WdogRead ( + IN UINTN Address + ) +{ + if (FixedPcdGetBool (PcdWdogBigEndian)) { + return BeMmioRead16 (Address); + } else { + return MmioRead16(Address); + } +} + +STATIC +UINT16 +EFIAPI +WdogWrite ( + IN UINTN Address, + IN UINT16 Value + ) +{ + if (FixedPcdGetBool (PcdWdogBigEndian)) { + return BeMmioWrite16 (Address, Value); + } else { + return MmioWrite16 (Address, Value); + } +} + +STATIC +UINT16 +EFIAPI +WdogAndThenOr ( + IN UINTN Address, + IN UINT16 And, + IN UINT16 Or + ) +{ + if (FixedPcdGetBool (PcdWdogBigEndian)) { + return BeMmioAndThenOr16 (Address, And, Or); + } else { + return MmioAndThenOr16 (Address, And, Or); + } +} + +STATIC +UINT16 +EFIAPI +WdogOr ( + IN UINTN Address, + IN UINT16 Or + ) +{ + if (FixedPcdGetBool (PcdWdogBigEndian)) { + return BeMmioOr16 (Address, Or); + } else { + return MmioOr16 (Address, Or); + } +} + +STATIC +VOID +WdogPing ( + VOID + ) +{ + // + // To reload a timeout value to the counter the proper service sequence begins by + // writing 0x_5555 followed by 0x_AAAA to the Watchdog Service Register (WDOG_WSR). + // This service sequence will reload the counter with the timeout value WT[7:0] of + // Watchdog Control Register (WDOG_WCR). + // + + WdogWrite (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WSR_OFFSET, + WDOG_SERVICE_SEQ1); + WdogWrite (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WSR_OFFSET, + WDOG_SERVICE_SEQ2); +} + +/** + Stop the Wdog watchdog timer from counting down. +**/ +STATIC +VOID +WdogStop ( + VOID + ) +{ + // Watchdog cannot be disabled by software once started. + // At best, we can keep reload counter with maximum value + + WdogAndThenOr (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WCR_OFFSET, + (UINT16)(~WDOG_WCR_WT), + (WD_COUNT (WT_MAX_TIME) & WD_COUNT_MASK)); + WdogPing (); +} + +/** + Starts the Wdog counting down by feeding Service register with + desired pattern. + The count down will start from the value stored in the Load register, + not from the value where it was previously stopped. +**/ +STATIC +VOID +WdogStart ( + VOID + ) +{ + //Reload the timeout value + WdogPing (); +} + +/** + On exiting boot services we must make sure the Wdog Watchdog Timer + is stopped. +**/ +STATIC +VOID +EFIAPI +ExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + WdogStop (); +} + +/** + This function registers the handler NotifyFunction so it is called every time + the watchdog timer expires. It also passes the amount of time since the last + handler call to the NotifyFunction. + If NotifyFunction is not NULL and a handler is not already registered, + then the new handler is registered and EFI_SUCCESS is returned. + If NotifyFunction is NULL, and a handler is already registered, + then that handler is unregistered. + If an attempt is made to register a handler when a handler is already registered, + then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + + @retval EFI_SUCCESS The watchdog timer handler was registered. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + +**/ +STATIC +EFI_STATUS +EFIAPI +WdogRegisterHandler ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction + ) +{ + // ERROR: This function is not supported. + // The hardware watchdog will reset the board + return EFI_INVALID_PARAMETER; +} + +/** + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ +STATIC +EFI_STATUS +EFIAPI +WdogSetTimerPeriod ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod // In 100ns units + ) +{ + EFI_STATUS Status; + UINT64 TimerPeriodInSec; + UINT16 Val; + + Status = EFI_SUCCESS; + + if (TimerPeriod == 0) { + // This is a watchdog stop request + WdogStop (); + return Status; + } else { + // Convert the TimerPeriod (in 100 ns unit) to an equivalent second value + + TimerPeriodInSec = DivU64x32 (TimerPeriod, NANO_SECOND_BASE); + + // The registers in the Wdog are only 32 bits + if (TimerPeriodInSec > WT_MAX_TIME) { + // We could load the watchdog with the maximum supported value but + // if a smaller value was requested, this could have the watchdog + // triggering before it was intended. + // Better generate an error to let the caller know. + Status = EFI_DEVICE_ERROR; + return Status; + } + + // set the new timeout value in the WCR + // Convert the timeout value from Seconds to timer count + Val = ((WD_COUNT(TimerPeriodInSec) & WD_COUNT_MASK) << 8); + + WdogAndThenOr (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WCR_OFFSET, + (UINT16)(~WDOG_WCR_WT), + Val); + // Start the watchdog + WdogStart (); + } + + return Status; +} + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ +STATIC +EFI_STATUS +EFIAPI +WdogGetTimerPeriod ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +{ + EFI_STATUS Status; + UINT64 ReturnValue; + UINT16 Val; + + Status = EFI_SUCCESS; + + if (TimerPeriod == NULL) { + return EFI_INVALID_PARAMETER; + } + + // Check if the watchdog is stopped + if ((WdogRead (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WCR_OFFSET) + & WDOG_WCR_WDE) == 0 ) { + // It is stopped, so return zero. + ReturnValue = 0; + } else { + // Convert the Watchdog ticks into equivalent TimerPeriod second value. + Val = (WdogRead (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WCR_OFFSET) + & WDOG_WCR_WT ) >> 8; + ReturnValue = WD_SEC(Val); + } + + *TimerPeriod = ReturnValue; + return Status; +} + +/** + Interface structure for the Watchdog Architectural Protocol. + + @par Protocol Description: + This protocol provides a service to set the amount of time to wait + before firing the watchdog timer, and it also provides a service to + register a handler that is invoked when the watchdog timer fires. + + @par When the watchdog timer fires, control will be passed to a handler + if one has been registered. If no handler has been registered, + or the registered handler returns, then the system will be + reset by calling the Runtime Service ResetSystem(). + + @param RegisterHandler + Registers a handler that will be called each time the + watchdogtimer interrupt fires. TimerPeriod defines the minimum + time between timer interrupts, so TimerPeriod will also + be the minimum time between calls to the registered + handler. + NOTE: If the watchdog resets the system in hardware, then + this function will not have any chance of executing. + + @param SetTimerPeriod + Sets the period of the timer interrupt in 100 nS units. + This function is optional, and may return EFI_UNSUPPORTED. + If this function is supported, then the timer period will + be rounded up to the nearest supported timer period. + + @param GetTimerPeriod + Retrieves the period of the timer interrupt in 100 nS units. + +**/ +STATIC +EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = { + WdogRegisterHandler, + WdogSetTimerPeriod, + WdogGetTimerPeriod +}; + +/** + Call back function when the timer event is signaled. + This function will feed the watchdog with maximum value + so that system wont reset in idle case e.g. stopped on UEFI shell. + + @param[in] Event The Event this notify function registered to. + @param[in] Context Pointer to the context data registered to the + Event. + +**/ +VOID +EFIAPI +WdogFeed ( + IN EFI_EVENT Event, + IN VOID* Context + ) +{ + WdogPing(); +} +/** + Initialize state information for the Watchdog Timer Architectural Protocol. + + @param ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Protocol registered + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure + @retval EFI_DEVICE_ERROR Hardware problems + +**/ +EFI_STATUS +EFIAPI +WdogInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + WdogAndThenOr (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WCR_OFFSET, + (UINT16)(~WDOG_WCR_WT), + (WD_COUNT (WT_MAX_TIME) & WD_COUNT_MASK)); + + WdogOr (PcdGet64 (PcdWdog1BaseAddr) + WDOG_WCR_OFFSET, WDOG_WCR_WDE); + + // + // Make sure the Watchdog Timer Architectural Protocol + // has not been installed in the system yet. + // This will avoid conflicts with the universal watchdog + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid); + + // Register for an ExitBootServicesEvent + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, + ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + // + // Start the timer to feed Watchdog with maximum timeout value. + // + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + WdogFeed, + NULL, + &WdogFeedEvent + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->SetTimer (WdogFeedEvent, TimerPeriodic, WT_FEED_INTERVAL); + if (EFI_ERROR (Status)) { + return Status; + } + + // Install the Timer Architectural Protocol onto a new handle + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (EfiExitBootServicesEvent); + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + WdogPing (); + + return Status; +} diff --git a/Silicon/NXP/Drivers/WatchDog/WatchDog.h b/Silicon/NXP/Drivers/WatchDog/WatchDog.h new file mode 100644 index 0000000..9542608 --- /dev/null +++ b/Silicon/NXP/Drivers/WatchDog/WatchDog.h @@ -0,0 +1,39 @@ +/** WatchDog.h +* +* Copyright 2017 NXP +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef __WATCHDOG_H__ +#define __WATCHDOG_H__ + +#define WDOG_SIZE 0x1000 +#define WDOG_WCR_OFFSET 0 +#define WDOG_WSR_OFFSET 2 +#define WDOG_WRSR_OFFSET 4 +#define WDOG_WICR_OFFSET 6 +#define WDOG_WCR_WT (0xFF << 8) +#define WDOG_WCR_WDE (1 << 2) +#define WDOG_SERVICE_SEQ1 0x5555 +#define WDOG_SERVICE_SEQ2 0xAAAA +#define WDOG_WCR_WDZST 0x1 +#define WDOG_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ + +#define WT_MAX_TIME 128 +#define WD_COUNT(Sec) (((Sec) * 2 - 1) << 8) +#define WD_COUNT_MASK 0xff00 +#define WD_SEC(Cnt) (((Cnt) + 1) / 2) + +#define NANO_SECOND_BASE 10000000 + +#define WT_FEED_INTERVAL (WT_MAX_TIME * NANO_SECOND_BASE) + +#endif //__WATCHDOG_H__ diff --git a/Silicon/NXP/Drivers/WatchDog/WatchDogDxe.inf b/Silicon/NXP/Drivers/WatchDog/WatchDogDxe.inf new file mode 100644 index 0000000..e6c06ef --- /dev/null +++ b/Silicon/NXP/Drivers/WatchDog/WatchDogDxe.inf @@ -0,0 +1,47 @@ +# WatchDog.inf +# +# Component description file for WatchDog module +# +# Copyright 2017 NXP +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = WatchDogDxe + FILE_GUID = 0358b544-ec65-4339-89cd-cad60a3dd787 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = WdogInitialize + +[Sources.common] + WatchDog.c + +[Packages] + MdePkg/MdePkg.dec + Silicon/NXP/NxpQoriqLs.dec + +[LibraryClasses] + BaseLib + BeIoLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Pcd] + gNxpQoriqLsTokenSpaceGuid.PcdWdog1BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdWdogBigEndian + +[Protocols] + gEfiWatchdogTimerArchProtocolGuid + +[Depex] + TRUE -- 1.9.1