From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.34.46; helo=nam01-by2-obe.outbound.protection.outlook.com; envelope-from=meenakshi.aggarwal@nxp.com; receiver=edk2-devel@lists.01.org Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0046.outbound.protection.outlook.com [104.47.34.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id CAB752034C5F2 for ; Wed, 22 Nov 2017 01:56:42 -0800 (PST) Received: from BN3PR03CA0068.namprd03.prod.outlook.com (10.167.1.156) by BN3PR03MB2354.namprd03.prod.outlook.com (10.166.74.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.239.5; Wed, 22 Nov 2017 10:00:57 +0000 Received: from BN1AFFO11FD010.protection.gbl (2a01:111:f400:7c10::186) by BN3PR03CA0068.outlook.office365.com (2a01:111:e400:7a4d::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.239.5 via Frontend Transport; Wed, 22 Nov 2017 10:00:57 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1AFFO11FD010.mail.protection.outlook.com (10.58.52.70) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.218.12 via Frontend Transport; Wed, 22 Nov 2017 10:00:57 +0000 Received: from uefi-OptiPlex-790.ap.freescale.net (uefi-OptiPlex-790.ap.freescale.net [10.232.132.78]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id vAMA0nI5030922; Wed, 22 Nov 2017 03:00:54 -0700 From: Meenakshi Aggarwal To: , , , Date: Wed, 22 Nov 2017 21:18:53 +0530 Message-ID: <1511365740-1157-2-git-send-email-meenakshi.aggarwal@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1511365740-1157-1-git-send-email-meenakshi.aggarwal@nxp.com> References: <1510065736-9394-1-git-send-email-meenakshi.aggarwal@nxp.com> <1511365740-1157-1-git-send-email-meenakshi.aggarwal@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131558184578146841; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(336005)(7966004)(346002)(376002)(39860400002)(39380400002)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(50944005)(6306002)(2906002)(53376002)(47776003)(5660300001)(53936002)(36756003)(2950100002)(189998001)(15188155005)(2201001)(77096006)(85426001)(50226002)(54906003)(110136005)(50986999)(8936002)(76176999)(86362001)(16799955002)(316002)(16586007)(5003940100001)(966005)(498600001)(68736007)(106466001)(105606002)(4326008)(33646002)(8656006)(104016004)(48376002)(305945005)(50466002)(356003)(81156014)(8676002)(81166006)(97736004)(171213001)(44824005)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:BN3PR03MB2354; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD010; 1:5wbLd/ZAB1sCq0/59UhzTzndFxUTjoPeEiNzu5vlx4ILfb0vsb4S603IHeD76AB4u3MoE62rouKtD3LFR4fjwexe+ORHLcu3brq2T2OIGGGKtpfB5JqE+8091CErI8Yi MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 4df235c4-bc9e-4eb2-5711-08d5318fed77 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(4534020)(4628075)(201703131517081)(2017052603199); SRVR:BN3PR03MB2354; X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2354; 3:as+WyMinjJ3gsWfTaLaF2uTKtqxG/AUjjrNId5Q3QsW1jKlT7yTg+WTZUZmt2cmqYz0soqfDq0RaqGl1Q+mKDb4r7bB20fqyEbr1R+3lfh9J2jiRrTsYEIlsora70KkP2QxkkH3xKSFUCmoIDSTKW5RJXnNTqNDxnUAa5FGu5vi+PpPoA5zODelApLMuKinys5gw0NpSglmTMOKbv1Upqc2luY5jkWqMmaWnyPRRfxLv70IJHZFtn7iLzEsruVbqgaaYarrYoi1MvZNfQsln4MozE1t7IgEsYhyPYKPBphBv7Xy4ZX60bvRjMLpkYWoIeCh32Kv/vX9yfpRQqcpgVcVl9mghnynmxOOp1RYYsfk=; 25:cUAroMSKbltayuJtclNauFQ9Q9QARlybRyE+iC/sAqNH9Rvy4K+IDmSFi4DmIu7F6YjbQOtbEzSMWhSpaFxKDztP1XE+kYz/2IVu07sghqaf0nva77iasr5ToIkLD8TUevUPqUpYII+Ayq66d7O904v0tnhcaxKbg7KZQcZs4MT/SH0+Y6LKSF//cC0aGxv4UEY7A65r9cLqBlhiagOVdD+z9LKx6sCJpqOAKZiDNGELQrUdyLPa/jtJrQ+bV9sleR5HQDKuLRc+eNL+x9lAxLVvOoVVkaH2oAFC6I2XtU5cyfrWfSUZCGNSjmAfCgRYLpwL7GO0oxJrbqFlkMdXvg== X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN3PR03MB2354: X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2354; 31:UL7TXejTJ2lsUqHW94pswdhPk2Jno3aMJwUWFgvvQoCFyORJC2kc38+d+91eqOv611nq2M+RWIcPNuaQ0xKVM3qWQra+Kd5JVCBJeVRS5ItiWeSkjOb86L0o7azTsf15bII0lnf/MtvyoEfBiMHtb7YsXPqESyJa3sv6eJt3MV3fQ9dgDW/T5yKPuQDRIKIjOs0STx/7pwoUyljQ3+uOOKNvnv++/82PvaS3IRrBBao=; 4:avDx5VKVkAfYHGp1dR3Ety3bYuwZeItHOqCJDfjS10bZfvmjjhM9r7O6XvFAfHT6B6B++30p7TEloLe71JuyuC7Wtmdaij4THB0yoUkSgFjqfUHGyvwZ7ODhrhn1gFPVvgPruXeif8e0RUx4nzx+JPX09DJ1dKMjdCsfxiF5ZS3VBtimBTAXlRnHmR2O/Qu8pw07bTRxZKmEQcAtad6ZzkKqyAgdQis9DgaiVHIHwBPq+oieeywJ+ft0P4GapkMzNCZRiupK61dS6V/JNmhHuxZ9YzmIDc75HMP359MXAEAmtCayb+UBD4MkmwGz2cJ6 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6095135)(2401047)(5005006)(8121501046)(100000703101)(100105400095)(10201501046)(3231022)(3002001)(93006095)(93001095)(6055026)(6096035)(20161123563025)(20161123561025)(20161123565025)(20161123556025)(20161123559100)(201703131430075)(201703131441075)(201703131448075)(201703131433075)(201703161259150)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:BN3PR03MB2354; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(400006)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:BN3PR03MB2354; X-Forefront-PRVS: 0499DAF22A X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN3PR03MB2354; 23:PkZBt9j4srfXYcAhAEOmaUDYFHZcOzhj3+teM4hht?= =?us-ascii?Q?Dlj6ENlL0P+pzLisldbMN/pmGIJBsF3vQk/AJ073ggOplWFGoGozYExYY84E?= =?us-ascii?Q?Tg/rsf/EJJ/tbM3poFWqBf5Un0Av8FF3YeyjG581dzwCCgfeelTe5Iq1XBgK?= =?us-ascii?Q?X6kQKWDoiNoULYtG4sROVC6EWoNQdAKVyl9wMgfuq8vc2ZEM9QAhM1iJqAi3?= =?us-ascii?Q?2PJEJprvO87zNABDpkfJVp1hyID4iO7HeEr92ii4BqVgsytH54MSKrUvW6v1?= =?us-ascii?Q?1+ZA3kaYjA7usjrVIQNKpO5p+4YEzRvb26Zl/UZW2Q9wt5YdsV1fzV3ZtRc0?= =?us-ascii?Q?ROD96Z6ULXux4ZEbS6/iHythXPiM86ykgKcCZgj02ctFYSAIeWv6+0oNIYat?= =?us-ascii?Q?A/r3W00K8plxQwUgNFQ9u8I9Iyehz9EguxvViGWqmx8nC5+7sE8ntYALRrTZ?= =?us-ascii?Q?Nx7ZsbMGQsqsWwFv/Fo7awYGeTG48W28UmTIp4cZsWDu+CbSodSc2ge+TSyn?= =?us-ascii?Q?iPeD9q2x/IvRglOcBwhNf3M4GoGnw7QoVPW+6mgbFQ+gtTLNgt7glH0vxdT1?= =?us-ascii?Q?P6wlItSytosIPYrk9wrwN4YkCRxxdMx2/wClb0O9ftUELBa5yBKAXy5fDv/f?= =?us-ascii?Q?MTu4c1qfUABbl5KoKIrJdlhAm9n05/h3u/kJvjndTA7Qx3pdqjtxbrUHFpxE?= =?us-ascii?Q?aHEmLQ/A8E3KxhrXh7WtiuwQCikp4ofCdiZ0TRI6YdmGfHmzXu414UUlcX7C?= =?us-ascii?Q?TcWOpGbjwqc0eUXIJl+6E6by3n1m2sZSLaUikRSfmzZaQwRowVt4mdY3K7nv?= =?us-ascii?Q?PCwIrfvVMA9/oORX2M+ee0ufviwEE3MhZdy3ZHazTG0aqAKKv6WfsXOUElhR?= =?us-ascii?Q?ZRhISFmg0DAN+plYWYsGwbQzZD77b+6jAlF6Gtbi37RJ4x5sNJTWa8DX38xP?= =?us-ascii?Q?WzWm/RR1PJnI5uqPXFyCO7WcoOV36iSAyiFnkQYTD/bkDTP5fge1tATyKNyU?= =?us-ascii?Q?T0zjM7/30H7+c3I7Z0GtryJ3sEDEfLZTX6L5/qZi6F51KgWEf0REwpuu3dVo?= =?us-ascii?Q?3d7Idzy8RbJJBr2qr5Kl21Y/9AprHTGseSgttGxNpF5PRuj4PvXm336p6vFv?= =?us-ascii?Q?jxc5iXHOpAZ7o7CyB/qesQK7yWkMTmWAw9WJiRD/nulGYJoDdFj7PcdjVVR4?= =?us-ascii?Q?Lsw9svtz/Rpk28zLaoM0eMYNZ0JYCyE12vwDWXLNjyMIEZknN0aQZ9J/L3uv?= =?us-ascii?Q?1/FdboLxA/unKFl83oKU7laUMP21gnDGCvkYg97UyO2SCo5uqMwEPXqbEb5c?= =?us-ascii?Q?RKVDvEffhUOmL9qnWPTJgoSiZlAn1JuoUNR1aFhHYB7N8Z5hooOrX9rYJi5h?= =?us-ascii?Q?dWe/A=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2354; 6:rEJfMWCxRTLjWkE56tVzyDgwEXSs1mAPt5cy3u4BNU4UapbWPCZkvNEfdFD1a/LKnY1R4HUScO6IfcXhxHzOanEssylWNXV98Gs4agPpAZrppRZYzjI1+TS5NtdEXlTUzQ9+lhIOTgwhUdMv6Ufgh7AKXUgpiWuqO/9VneYM1WFu0DroVK7Vl+VkYhjnXVnDJfz8oHAng5SdAbU/yRtuZXry4kCN/aI2VCDE9knMJvTBc3aeC6zLE2+9tDnnV4hb0lIixkVgw/C/xqfcfbVUWJh3jxHGzghBI4yHpBdr4foXyy4etsTNXMxYGO/z9f9/JNOFFu77UWhnFUmEgE7zunXN/kXKn85IVKY08EnS6Zs=; 5:guWjG79IgV66yi5qwcWsInxsl3+hzAIXUEA+WB3FiTOrtMwirqfBe/4v8p5/Zo2ukb+mk0Jgo5p+5sLlltn1I1lVbdgu7wujnYkCT67WxUS2NQ9f93Nion3y33Z/MTWAWwdjVIr3U5n/7QV0alGT3vaHBQn8VTLvMgooC9+6wqE=; 24:Czoh/dgGRPGocDmzTpwj3WxBuRCRVWrKr+mYTF5X1Y/XioMQvurdOQv75jmQnVeyM4naupkYwT++riOR3GZ5yssmi+B50sRTAea1V9x9G5c=; 7:829nMxAvFF4t+dle4Tk7NFL+dkTU3z6wRfWwCqh715opFU3inWpSk44OwErSXYX3cWJ6xi2yvbXpHmwlEp8C71JDDGKbvIwG0HohT28YHfTQp2CF50XbjHrLEhLV1HJttZJQkSrGlCT3BIvip4lLWUnB88LTHUSnXEdt8fxv891SbD7Q69AnzSH3yKfstNHNK14DvbYeZ5zXPSJ705aNL2qsQe4zUZ8c7Vy2Jv8NDWNFNU8XW7sdNmwevda0G2bs SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Nov 2017 10:00:57.5338 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4df235c4-bc9e-4eb2-5711-08d5318fed77 X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR03MB2354 Subject: [PATCH v2 2/9] Platform/NXP : Add support for Watchdog driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Nov 2017 09:56:43 -0000 Content-Type: text/plain Installs watchdog timer arch protocol Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Meenakshi Aggarwal --- Platform/NXP/Drivers/WatchDog/WatchDog.c | 421 ++++++++++++++++++++++++++ Platform/NXP/Drivers/WatchDog/WatchDog.h | 37 +++ Platform/NXP/Drivers/WatchDog/WatchDogDxe.inf | 47 +++ 3 files changed, 505 insertions(+) create mode 100644 Platform/NXP/Drivers/WatchDog/WatchDog.c create mode 100644 Platform/NXP/Drivers/WatchDog/WatchDog.h create mode 100644 Platform/NXP/Drivers/WatchDog/WatchDogDxe.inf diff --git a/Platform/NXP/Drivers/WatchDog/WatchDog.c b/Platform/NXP/Drivers/WatchDog/WatchDog.c new file mode 100644 index 0000000..956e455 --- /dev/null +++ b/Platform/NXP/Drivers/WatchDog/WatchDog.c @@ -0,0 +1,421 @@ +/** WatchDog.c +* +* Based on Watchdog driver implemenation available in +* ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805Watchdog.c +* +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* 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 +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 +}; + +/** + 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; + } + + // 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/Platform/NXP/Drivers/WatchDog/WatchDog.h b/Platform/NXP/Drivers/WatchDog/WatchDog.h new file mode 100644 index 0000000..56ddbde --- /dev/null +++ b/Platform/NXP/Drivers/WatchDog/WatchDog.h @@ -0,0 +1,37 @@ +/** 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 + +#endif //__WATCHDOG_H__ diff --git a/Platform/NXP/Drivers/WatchDog/WatchDogDxe.inf b/Platform/NXP/Drivers/WatchDog/WatchDogDxe.inf new file mode 100644 index 0000000..a74f477 --- /dev/null +++ b/Platform/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 + Platform/NXP/NxpQoriqLs.dec + +[LibraryClasses] + BaseLib + BeIoLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Pcd] + gNxpQoriqLsTokenSpaceGuid.PcdWdog1BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdWdogBigEndian + +[Protocols] + gEfiWatchdogTimerArchProtocolGuid + +[Depex] + TRUE -- 1.9.1