From patchwork Tue Jan 9 18:50:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 857678 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=xilinx.onmicrosoft.com header.i=@xilinx.onmicrosoft.com header.b="TjoZFE3n"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zGLvf1x5Zz9sQm for ; Wed, 10 Jan 2018 05:56:14 +1100 (AEDT) Received: from localhost ([::1]:40828 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYz4G-0005RR-9N for incoming@patchwork.ozlabs.org; Tue, 09 Jan 2018 13:56:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46680) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYz3Z-0005Pm-RF for qemu-devel@nongnu.org; Tue, 09 Jan 2018 13:55:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYz3V-0000lE-OX for qemu-devel@nongnu.org; Tue, 09 Jan 2018 13:55:29 -0500 Received: from mail-by2nam01on0046.outbound.protection.outlook.com ([104.47.34.46]:44896 helo=NAM01-BY2-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eYz3V-0000ju-B4 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 13:55:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=xilinx.onmicrosoft.com; s=selector1-xilinx-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=lzoczlHbzcgHe/4DKlM6afJu3Rp03IAb1mcUI8jstCU=; b=TjoZFE3nyJ7vY2rNnI+HwEJ1fK1pyZrFcr9vtLBKAwRzIsJ9QPJnidgwm9wJ14oaumb8VtcODT1/HkPKxLUFWGYIpfIhNJEwzQO239mLAsfvsZL6c2d22GG2kVZB5MM0+ZKtD4v4M7hMcNhmYLSN+M6xmAamXa+INlrdi6W6G2I= Received: from BY2PR02CA0121.namprd02.prod.outlook.com (10.163.44.175) by SN1PR02MB1342.namprd02.prod.outlook.com (10.162.0.148) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.386.5; Tue, 9 Jan 2018 18:55:21 +0000 Received: from BL2NAM02FT004.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e46::200) by BY2PR02CA0121.outlook.office365.com (2a01:111:e400:5261::47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.386.5 via Frontend Transport; Tue, 9 Jan 2018 18:55:21 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.100) smtp.mailfrom=xilinx.com; gmail.com; dkim=none (message not signed) header.d=none;gmail.com; dmarc=bestguesspass action=none header.from=xilinx.com; Received-SPF: Pass (protection.outlook.com: domain of xilinx.com designates 149.199.60.100 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.100; helo=xsj-pvapsmtpgw02; Received: from xsj-pvapsmtpgw02 (149.199.60.100) by BL2NAM02FT004.mail.protection.outlook.com (10.152.76.168) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.345.12 via Frontend Transport; Tue, 9 Jan 2018 18:55:20 +0000 Received: from unknown-38-66.xilinx.com ([149.199.38.66]:45576 helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw02 with esmtp (Exim 4.63) (envelope-from ) id 1eYz3P-00016w-WA; Tue, 09 Jan 2018 10:55:20 -0800 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1eYz3P-00054d-TY; Tue, 09 Jan 2018 10:55:19 -0800 Received: from xsj-pvapsmtp01 (smtp3.xilinx.com [149.199.38.66]) by xsj-smtp-dlp1.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id w09ItA2F017294; Tue, 9 Jan 2018 10:55:10 -0800 Received: from [172.19.2.220] (helo=xsjalistai50.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1eYz3G-00052N-6c; Tue, 09 Jan 2018 10:55:10 -0800 From: Alistair Francis To: , Date: Tue, 9 Jan 2018 10:50:52 -0800 Message-ID: X-Mailer: git-send-email 2.14.1 X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.2.0.1013-23584.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.100; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(376002)(39380400002)(346002)(39860400002)(396003)(2980300002)(438002)(199004)(189003)(7696005)(81156014)(48376002)(5660300001)(356003)(118296001)(305945005)(478600001)(230783001)(8936002)(47776003)(6666003)(50226002)(59450400001)(50466002)(4326008)(36386004)(51416003)(9786002)(39060400002)(81166006)(8676002)(106002)(77096006)(110136005)(36756003)(316002)(2906002)(106466001)(54906003)(16586007)(63266004)(107986001)(5001870100001); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR02MB1342; H:xsj-pvapsmtpgw02; FPR:; SPF:Pass; PTR:xapps1.xilinx.com,unknown-60-100.xilinx.com; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2NAM02FT004; 1:06g5a54FNxpTeIrvIF//I6U7pq5ey2hutjVW1mavJZHDTuTjPsQEEq4fDQ6W7i2aUQRR7//7n0Ovld+Izxiz3MpY1A9dFInq5vdnMU8zCDhJWWTQAY/yNMVvhULZ9aIw MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 10677145-38d8-4ebf-dc2e-08d55792889d X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(5600026)(4604075)(4608076)(2017052603307)(7153060); SRVR:SN1PR02MB1342; X-Microsoft-Exchange-Diagnostics: 1; SN1PR02MB1342; 3:uJpNi1iuZ04BBJj2rVksSCrwXp3uO9m7ixRFeIhd2tqGWsU5JRit2W67RbFCnJoD9xsOiGeHM9wbfcZPeGFSJdzRUA0ipbAZ120fU6EPNmci9bf9yo1GyFkXKF4/9DLWAazJDx1eORUH1RJe2tmpZKd39UhiMyPegR1HOKhdRrLJEmFwMDwXzlArN/1B+IiXCX2kuoxuvIwpFDaWibVt0t55CU50V4tT3PS4yVGOg6AOa7TTWYCHbP43Dclk/733AQsj99BrEGbWcxnRaj/5sjULEnjMgKOMf+1M5lJEMVwYko/ndhCFT+mIZED0aFK0ud7vMQfkt/9SctJsjxOhWoRQ5p3/6UkrgYXolH2INCM=; 25:9Dap82/8ViUw2E2L0lWF/V9RpZQtrIyAX+czjL7cdnqBJcNpkDrDo3A/qHLHcWr4iLiVuIdWboc0+PB5Nd9Za4gk/14v7svoDuUVCWi6OOPzIodR65sWoyZ/m91jYzFANgGBMQbXRdzIZwXgpgM8bHSbw+8lCN8dOpmSE/Lc2qeHzfxXmonOinxz/rvMSxz27VZCqn4oCAVJZKJzPoZqXPctxhTPmYCcRbC9Mw5e19T+8JSpSTI8P6ILGDbXw18RBNcBIJfQWJuMZX/iUj39hLGsAPjbI8GuGLuPvIg2ZYBOOESR06xxKdPXcL9yL3lllCivrTUooZY+kP0x5l8oVA== X-MS-TrafficTypeDiagnostic: SN1PR02MB1342: X-Microsoft-Exchange-Diagnostics: 1; SN1PR02MB1342; 31:RJ2nAGBt6CsT6TJCbjCFwOYolvJ6dgtOg+UXQEHes5HmoB4JXejFJ7QjreSTjChpNHmMm5QZEmylWkVufJTpq/Cfm71ycQY6b8De00johSjTAMaPp2SCIJm5JPXZZDY1QahAS4CZVl+TGu6IJxNPsRY3N8T3wj7vMcGfIf8GkpbkJSK2fkfYWZNS3VMQFf6pZc+QXgiWn+tkZj82US1rP7pGkRMqd1fKf98bnGJo+gA=; 20:A+X9KYN/4luTNqmD5ywVZv1fAXMoJVhqYgZ+p1hHcwxz1QKbx8v5bsDVWy9cqho2T3F+2j8/XejkWMsSSTx3JUj0xT7PhP6PCcRcNQLxVMjboStN/xocf8c4i6DE8AC5FGUrMpqSJYz8o9nqexADgtVXq2Vg9hwJfSZC96BHFf9/huIZovvzuDf4nsDB33OaeUB6IhNJKlTHwT8LnVpTSVZYfORlkXY8ctupeUQSO8cmKQUBrKiR0rzIKhUXaM3G5mVk+0bJ91FaTzPt89yWWWDSNx62LQxGqTLWLiUnGfbnYLliLUasrFxpFd2Ai/AZzuCwd9UNChuCE2kcxPFQWXEgcoRrCA3GjhtdBe4YhHuXhKKnykD9Hy2yL9LcCRNRJJ4BskStkqrT8FAhKBae7kHu1zDwrxKVleJncEGbR22a6XlG4SKSF52LxmJ1QidYun1gjh0qe9kcpubmWExJkWwPdZEH1ULJh+N3tfo5gABpt0aFWW9ySgZrg8bPFK4h X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040470)(2401047)(5005006)(8121501046)(93006095)(93004095)(10201501046)(3002001)(3231023)(944501075)(6055026)(6041268)(20161123562045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(6072148)(201708071742011); SRVR:SN1PR02MB1342; BCL:0; PCL:0; RULEID:(100000803101)(100110400095); SRVR:SN1PR02MB1342; X-Microsoft-Exchange-Diagnostics: 1; SN1PR02MB1342; 4:7O3Ju/iKJlfCfz1Y4zGoLLgST7/2N2un2nfiUHcICewkv7hEt7ax5e16jq4fg3zrhOT+pnyIrndY2N9mmtQtkB657LMiYOq88zGcOG6smVubL+ZjMRrdO2DKCjr4Hzwe4KLBShjtsMYsx11HgHfMkNGnhENdENF9Z9XeVAnzx33A/lDuUC43+1KU5lp52oJvvSzXBeKyT4KXriHIVEU7ztgdmvYgbKo/q4PygPmPdTmhIlWLuVX26invYpv0VIRBvS0HYmMfhsTFSpNPyTOa9noj2GcuuMQYwsRvJoeFoG5YaHMO2oXbBaBl0TsVvyr1 X-Forefront-PRVS: 0547116B72 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN1PR02MB1342; 23:khPET3z1hTYWerSFt9lvGWApPD3dLWdRCWO98H0J1?= tX6/NSe5m1yukczpHNzsRGaaAj8jFQ04N3lCkt1nxT9UnGkTlRd+q258KYVFVjLHyZrEt5uFfYB2UvZOlFAAhjmfL/x09YP1+9u3mmk4LemEHAI9t08dryTqR2uZuSEfovZkPezQQ8TzwchNpV1Hz/THtBoYLNXBTDCs83HUFjbt3uhsuTzuwlpK8ebYHPSTHxUyk8KYIiS8TUYD5hXYV4Qy8U4qlgO11vebZC4gv8M7zITdT/zvONh4fHA/koxpvJ9ef/ixpz1iaIw591V7TNg9Ol6VcHDqOYm2iliBMM8EK52JWApGFxhNokB20U8jq6yHQZdU9e4M6XYMdsmgbIbck2aCWTebKkehBK4yHQPW1JtJR/uXd+TQmacGM80Cpr1kFftIO4zR3BZsmvoVnkJxr38cmI4DAUpXTkNm25hY4f8lHLoMxdgo3xTWKIpnP5B9zlnsEY71P5YWm7jA3q/lFjE4cPYOwVbegNRVlt9zqC9mObEAuqRlW2xc5nlTlgVYqPgDo9xTSkRv0RklAUrs/FQQooJ2epKKFLVj6iAR7B65Pa7xV2ww8iS/ZSo/uS1AR9aMYwMeNqUBlCt++AlroxXCb520natwq/4Kqc1jWX6NNOMsUX/YnWDziZ9+hZRLjsG22u3iIqkUKb6yz2s8M+Ym0BTmZvqT00NtkzudZfRZsKhwyO1OzAt5FhjpQ+DmgZpYnRVa1gTJDNSCtrkJHTy0pmFMkOABFEJxpZrELJ/35zheYqGqJaqtsCBZ3KV9st5ktmzSEI945FYmELtx5fcJ272H/zLi8wPWl41gGFdmqNgXGdr0KEe+zU9R4dTGsa5qcndiX+lF7ckbwbfV8sQ4c8Ne45FeeF36VfD7JT08PIDY6U6v69QkHSHq5UvHnpQhN47q3nQZKuLegtm8115Za7HYOXfOpfvvQwLv2Kigctd9FHQIMPwH2OKP+YXR4Tg1ylxAnYgQfMMtL2del310eFwB3pextEUlo+6Sw== X-Microsoft-Exchange-Diagnostics: 1; SN1PR02MB1342; 6:KNYZZ/WGfdGYY2YZw2aC0TlRwt8D5FEgWQHdE0Chtu2AJu+i7gBhGUlUjj1wInl1SvPgZkO+AU8rNAhgyq0b9APYpZ2Q7QHCjV5wZ0RTzPSe53CwlVUfVEJk1LFwdpDn7kqA0g4yD5bBAVPltwLeyiYtX1VyU2zGqAlithvPmiQBBq56MvOZtHJNW1zawR7rrZFMcwtnY9G3Z0hQdgMP1yvMSsXsRBuRavstIgqOGDRfNbE7v7MsKuY/3QnTaW/cc4uaJvZaa7W5TIyOISMDT/LKeUDBJkEJapty7QuPUzyEdgoUp9FDbRwDMlR+KZ8QCnScDEnH2UWhPQyB25UMqwCHxduVd9LXKt4D85ZWUjs=; 5:BJw/Dce/PA5flfAW4lLYhpL+St9ZY/lNNALgNYhCRzhtVCZawQ1A7GLsfSKjyXocmflxZPwk7/OQgnQP3cT7bzBGxpD8pfM/QTiocQ6TEsFnQngqW6n7tIAoehJMZyLdHZsYl5j/eXHWzO4+2Thi5t8SjOcwXsyA/6Fb6BYnYqs=; 24:5QIzZTsPPeA/F7ufMrG5vB1RhIE0nc1c6XSl4LTCjCVhbNjGEfNdSMLMzFxJMqn2qIACJQvB/FK6z16fPnXeqcVMa+mPFVqelTxccqumCQo=; 7:oxOlOSi+HVAvpJQfHCWOVyv63UgqqZZOEVsDeZBWxi67mz0/KRYtYS2/S1uoKjZbiyvEar/h0V4Tbl8l7A0JDDBrktrudPbk4wWmLYMQdgVuqx1AMpY8RRyC/kn6N/vLCmpVDzpMA2reXyFqb0MsOdHVE+WcONIm9RHOICasVjl0h2Mg06LpNKIoss7xS4erQ00QZysfsVrXKQ5mRELab522sx/r5PMNmL/a64hCHqy/jsQfwAWnnawKw0zg4RIg SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Jan 2018 18:55:20.8400 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 10677145-38d8-4ebf-dc2e-08d55792889d X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c; Ip=[149.199.60.100]; Helo=[xsj-pvapsmtpgw02] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR02MB1342 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.34.46 Subject: [Qemu-devel] [PATCH v1 1/3] xlnx-zynqmp-rtc: Initial commit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, alistair23@gmail.com, edgar.iglesias@gmail.com, alistair.francis@xilinx.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Initial commit of the ZynqMP RTC device. Signed-off-by: Alistair Francis --- hw/timer/Makefile.objs | 1 + hw/timer/xlnx-zynqmp-rtc.c | 232 +++++++++++++++++++++++++++++++++++++ include/hw/timer/xlnx-zynqmp-rtc.h | 84 ++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 hw/timer/xlnx-zynqmp-rtc.c create mode 100644 include/hw/timer/xlnx-zynqmp-rtc.h diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 8c19eac3b6..8b27a4b7ef 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -21,6 +21,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o common-obj-$(CONFIG_IMX) += imx_gpt.o common-obj-$(CONFIG_LM32) += lm32_timer.o common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o +common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-rtc.o obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o diff --git a/hw/timer/xlnx-zynqmp-rtc.c b/hw/timer/xlnx-zynqmp-rtc.c new file mode 100644 index 0000000000..40533220fc --- /dev/null +++ b/hw/timer/xlnx-zynqmp-rtc.c @@ -0,0 +1,232 @@ +/* + * QEMU model of the Xilinx ZynqMP Real Time Clock (RTC). + * + * Copyright (c) 2017 Xilinx Inc. + * + * Written-by: Alistair Francis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/sysbus.h" +#include "hw/register.h" +#include "qemu/bitops.h" +#include "qemu/log.h" +#include "hw/timer/xlnx-zynqmp-rtc.h" + +#ifndef XLNX_ZYNQMP_RTC_ERR_DEBUG +#define XLNX_ZYNQMP_RTC_ERR_DEBUG 0 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) do { \ + if (XLNX_ZYNQMP_RTC_ERR_DEBUG >= lvl) { \ + qemu_log("%s: " fmt, __func__, ## args); \ + } \ +} while (0); + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +static void rtc_int_update_irq(XlnxZynqMPRTC *s) +{ + bool pending = s->regs[R_RTC_INT_STATUS] & ~s->regs[R_RTC_INT_MASK]; + qemu_set_irq(s->irq_rtc_int, pending); +} + +static void addr_error_int_update_irq(XlnxZynqMPRTC *s) +{ + bool pending = s->regs[R_ADDR_ERROR] & ~s->regs[R_ADDR_ERROR_INT_MASK]; + qemu_set_irq(s->irq_addr_error_int, pending); +} + +static void rtc_int_status_postw(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + rtc_int_update_irq(s); +} + +static uint64_t rtc_int_en_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + uint32_t val = val64; + + s->regs[R_RTC_INT_MASK] &= ~val; + rtc_int_update_irq(s); + return 0; +} + +static uint64_t rtc_int_dis_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + uint32_t val = val64; + + s->regs[R_RTC_INT_MASK] |= val; + rtc_int_update_irq(s); + return 0; +} + +static void addr_error_postw(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + addr_error_int_update_irq(s); +} + +static uint64_t addr_error_int_en_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + uint32_t val = val64; + + s->regs[R_ADDR_ERROR_INT_MASK] &= ~val; + addr_error_int_update_irq(s); + return 0; +} + +static uint64_t addr_error_int_dis_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + uint32_t val = val64; + + s->regs[R_ADDR_ERROR_INT_MASK] |= val; + addr_error_int_update_irq(s); + return 0; +} + +static const RegisterAccessInfo rtc_regs_info[] = { + { .name = "SET_TIME_WRITE", .addr = A_SET_TIME_WRITE, + },{ .name = "SET_TIME_READ", .addr = A_SET_TIME_READ, + .ro = 0xffffffff, + },{ .name = "CALIB_WRITE", .addr = A_CALIB_WRITE, + },{ .name = "CALIB_READ", .addr = A_CALIB_READ, + .ro = 0x1fffff, + },{ .name = "CURRENT_TIME", .addr = A_CURRENT_TIME, + .ro = 0xffffffff, + },{ .name = "CURRENT_TICK", .addr = A_CURRENT_TICK, + .ro = 0xffff, + },{ .name = "ALARM", .addr = A_ALARM, + },{ .name = "RTC_INT_STATUS", .addr = A_RTC_INT_STATUS, + .w1c = 0x3, + .post_write = rtc_int_status_postw, + },{ .name = "RTC_INT_MASK", .addr = A_RTC_INT_MASK, + .reset = 0x3, + .ro = 0x3, + },{ .name = "RTC_INT_EN", .addr = A_RTC_INT_EN, + .pre_write = rtc_int_en_prew, + },{ .name = "RTC_INT_DIS", .addr = A_RTC_INT_DIS, + .pre_write = rtc_int_dis_prew, + },{ .name = "ADDR_ERROR", .addr = A_ADDR_ERROR, + .w1c = 0x1, + .post_write = addr_error_postw, + },{ .name = "ADDR_ERROR_INT_MASK", .addr = A_ADDR_ERROR_INT_MASK, + .reset = 0x1, + .ro = 0x1, + },{ .name = "ADDR_ERROR_INT_EN", .addr = A_ADDR_ERROR_INT_EN, + .pre_write = addr_error_int_en_prew, + },{ .name = "ADDR_ERROR_INT_DIS", .addr = A_ADDR_ERROR_INT_DIS, + .pre_write = addr_error_int_dis_prew, + },{ .name = "CONTROL", .addr = A_CONTROL, + .reset = 0x1000000, + .rsvd = 0x70fffffe, + },{ .name = "SAFETY_CHK", .addr = A_SAFETY_CHK, + } +}; + +static void rtc_reset(DeviceState *dev) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(dev); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { + register_reset(&s->regs_info[i]); + } + + rtc_int_update_irq(s); + addr_error_int_update_irq(s); +} + +static const MemoryRegionOps rtc_ops = { + .read = register_read_memory, + .write = register_write_memory, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void rtc_realize(DeviceState *dev, Error **errp) +{ + /* Delete this if you don't need it */ +} + +static void rtc_init(Object *obj) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + RegisterInfoArray *reg_array; + + memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_RTC, + XLNX_ZYNQMP_RTC_R_MAX * 4); + reg_array = + register_init_block32(DEVICE(obj), rtc_regs_info, + ARRAY_SIZE(rtc_regs_info), + s->regs_info, s->regs, + &rtc_ops, + XLNX_ZYNQMP_RTC_ERR_DEBUG, + XLNX_ZYNQMP_RTC_R_MAX * 4); + memory_region_add_subregion(&s->iomem, + 0x0, + ®_array->mem); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq_rtc_int); + sysbus_init_irq(sbd, &s->irq_addr_error_int); +} + +static const VMStateDescription vmstate_rtc = { + .name = TYPE_XLNX_ZYNQMP_RTC, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPRTC, XLNX_ZYNQMP_RTC_R_MAX), + VMSTATE_END_OF_LIST(), + } +}; + +static void rtc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = rtc_reset; + dc->realize = rtc_realize; + dc->vmsd = &vmstate_rtc; +} + +static const TypeInfo rtc_info = { + .name = TYPE_XLNX_ZYNQMP_RTC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(XlnxZynqMPRTC), + .class_init = rtc_class_init, + .instance_init = rtc_init, +}; + +static void rtc_register_types(void) +{ + type_register_static(&rtc_info); +} + +type_init(rtc_register_types) diff --git a/include/hw/timer/xlnx-zynqmp-rtc.h b/include/hw/timer/xlnx-zynqmp-rtc.h new file mode 100644 index 0000000000..87649836cc --- /dev/null +++ b/include/hw/timer/xlnx-zynqmp-rtc.h @@ -0,0 +1,84 @@ +/* + * QEMU model of the Xilinx ZynqMP Real Time Clock (RTC). + * + * Copyright (c) 2017 Xilinx Inc. + * + * Written-by: Alistair Francis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "hw/register.h" + +#define TYPE_XLNX_ZYNQMP_RTC "xlnx-zynmp.rtc" + +#define XLNX_ZYNQMP_RTC(obj) \ + OBJECT_CHECK(XlnxZynqMPRTC, (obj), TYPE_XLNX_ZYNQMP_RTC) + +REG32(SET_TIME_WRITE, 0x0) +REG32(SET_TIME_READ, 0x4) +REG32(CALIB_WRITE, 0x8) + FIELD(CALIB_WRITE, FRACTION_EN, 20, 1) + FIELD(CALIB_WRITE, FRACTION_DATA, 16, 4) + FIELD(CALIB_WRITE, MAX_TICK, 0, 16) +REG32(CALIB_READ, 0xc) + FIELD(CALIB_READ, FRACTION_EN, 20, 1) + FIELD(CALIB_READ, FRACTION_DATA, 16, 4) + FIELD(CALIB_READ, MAX_TICK, 0, 16) +REG32(CURRENT_TIME, 0x10) +REG32(CURRENT_TICK, 0x14) + FIELD(CURRENT_TICK, VALUE, 0, 16) +REG32(ALARM, 0x18) +REG32(RTC_INT_STATUS, 0x20) + FIELD(RTC_INT_STATUS, ALARM, 1, 1) + FIELD(RTC_INT_STATUS, SECONDS, 0, 1) +REG32(RTC_INT_MASK, 0x24) + FIELD(RTC_INT_MASK, ALARM, 1, 1) + FIELD(RTC_INT_MASK, SECONDS, 0, 1) +REG32(RTC_INT_EN, 0x28) + FIELD(RTC_INT_EN, ALARM, 1, 1) + FIELD(RTC_INT_EN, SECONDS, 0, 1) +REG32(RTC_INT_DIS, 0x2c) + FIELD(RTC_INT_DIS, ALARM, 1, 1) + FIELD(RTC_INT_DIS, SECONDS, 0, 1) +REG32(ADDR_ERROR, 0x30) + FIELD(ADDR_ERROR, STATUS, 0, 1) +REG32(ADDR_ERROR_INT_MASK, 0x34) + FIELD(ADDR_ERROR_INT_MASK, MASK, 0, 1) +REG32(ADDR_ERROR_INT_EN, 0x38) + FIELD(ADDR_ERROR_INT_EN, MASK, 0, 1) +REG32(ADDR_ERROR_INT_DIS, 0x3c) + FIELD(ADDR_ERROR_INT_DIS, MASK, 0, 1) +REG32(CONTROL, 0x40) + FIELD(CONTROL, BATTERY_DISABLE, 31, 1) + FIELD(CONTROL, OSC_CNTRL, 24, 4) + FIELD(CONTROL, SLVERR_ENABLE, 0, 1) +REG32(SAFETY_CHK, 0x50) + +#define XLNX_ZYNQMP_RTC_R_MAX (R_SAFETY_CHK + 1) + +typedef struct XlnxZynqMPRTC { + SysBusDevice parent_obj; + MemoryRegion iomem; + qemu_irq irq_rtc_int; + qemu_irq irq_addr_error_int; + + uint32_t regs[XLNX_ZYNQMP_RTC_R_MAX]; + RegisterInfo regs_info[XLNX_ZYNQMP_RTC_R_MAX]; +} XlnxZynqMPRTC;