From patchwork Fri Nov 11 23:42:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 694003 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3tFxQb2mxGz9t1b for ; Sat, 12 Nov 2016 10:46:47 +1100 (AEDT) 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="Y8T7mcQs"; dkim-atps=neutral Received: from localhost ([::1]:55963 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c5LWv-00021G-3O for incoming@patchwork.ozlabs.org; Fri, 11 Nov 2016 18:46:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36422) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c5LVf-0001EY-I5 for qemu-devel@nongnu.org; Fri, 11 Nov 2016 18:45:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c5LVa-0002Wh-BO for qemu-devel@nongnu.org; Fri, 11 Nov 2016 18:45:27 -0500 Received: from mail-by2nam03on0051.outbound.protection.outlook.com ([104.47.42.51]:46547 helo=NAM03-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 1c5LVZ-0002WU-VF for qemu-devel@nongnu.org; Fri, 11 Nov 2016 18:45:22 -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=kMZjzLqbN8nSmLBTeY8VoaiDoqRAR+Tvg+uKkit0xf0=; b=Y8T7mcQsMiy8CPdWoJG4auuiA7v5Ath82tJbrx5JR9VgUg5NZkwRUOk+/+THP7/g3BLojEJHY44EZSZjpsLuB1GfonPkKOWRJlnOiNwFvRZgwr2hIgN4rbGvQHiBjkCQth8u9+cmpZxT8obpGF7+uIm6ycmAALN489m8UriWKXI= Received: from BN1PR02CA0037.namprd02.prod.outlook.com (10.141.56.37) by MWHPR02MB2879.namprd02.prod.outlook.com (10.175.50.142) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.707.6; Fri, 11 Nov 2016 23:45:18 +0000 Received: from BL2NAM02FT057.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e46::200) by BN1PR02CA0037.outlook.office365.com (2a01:111:e400:2a::37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.707.6 via Frontend Transport; Fri, 11 Nov 2016 23:45:18 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.83) 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.83 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.83; helo=xsj-pvapsmtpgw01; Received: from xsj-pvapsmtpgw01 (149.199.60.83) by BL2NAM02FT057.mail.protection.outlook.com (10.152.77.36) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.707.3 via Frontend Transport; Fri, 11 Nov 2016 23:45:15 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:; UpperCasedChecksum:; SizeAsReceived:1570; Count:17 Received: from unknown-38-66.xilinx.com ([149.199.38.66] helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw01 with esmtp (Exim 4.63) (envelope-from ) id 1c5LUL-00055V-AW; Fri, 11 Nov 2016 15:44:05 -0800 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1c5LUL-00022z-6d; Fri, 11 Nov 2016 15:44:05 -0800 Received: from xsj-pvapsmtp01 (xsj-smtp.xilinx.com [149.199.38.66]) by xsj-smtp-dlp2.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id uABNi0Dw009719; Fri, 11 Nov 2016 15:44:00 -0800 Received: from [172.19.74.182] (helo=xsjalistai50.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1c5LUG-00020f-HF; Fri, 11 Nov 2016 15:44:00 -0800 From: Alistair Francis To: , Date: Fri, 11 Nov 2016 15:42:29 -0800 Message-ID: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.0.0.1202-22692.006 X-TM-AS-User-Approved-Sender: Yes;Yes X-IncomingHeaderCount: 17 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.83; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(438002)(199003)(189002)(77096005)(50466002)(48376002)(5660300001)(47776003)(92566002)(63266004)(36756003)(87936001)(626004)(118296001)(305945005)(7846002)(76176999)(33646002)(50226002)(8676002)(106466001)(189998001)(586003)(5003940100001)(9786002)(81166006)(8936002)(356003)(575784001)(5001770100001)(6666003)(50986999)(36386004)(2906002)(81156014)(230783001)(2950100002)(4326007)(107986001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR02MB2879; H:xsj-pvapsmtpgw01; FPR:; SPF:Pass; PTR:unknown-60-83.xilinx.com; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2NAM02FT057; 1:sieLcNCR1Ejj+XCaabx72E43oKi5yjtEoCj93O7JIrr7aMQvEuROsS5SiG/dTvZ3ItHzyLXckjUfNQp0Tdi4PWGMKE2orLanNiA+AL0j2qs7Q1pPi7xm+gb6/7wkSNmddzFWhy5DxW4J4R+d7XcHOoDacD7NZjF0MCaPiw3TZIKyA/3pbA2kAvkbDoZjAryJ396qUGjMUJgXc6J/XfaWYjjrQmpS8lOVbN5s/336j2YbFw9xNuWR4MwvkGc1AWaFAWknLeT/oCWqbywusPlOemG8WYHROZnNNZiXYktBmirRBL54qv7AiKbPaaykpzPno6LtQzXaCBwr+na62OlCfGUw/zKQSwle/RL9RqrcJitd+QGW1mqZPKZORiCTjSuiIZcVQVi06Ik9rty3r9Y8QVfvFWd6nXXCnlpMUfGPXtshiympcdeRVbWr6ytStmhYVR4lu7/lqWzD0plrTbUeUbwqFbLtjRzqLSVoRikR6EV8krpgvEbaBX2zMfxIqjFKy/mIA1+I73WzEes3d9mdl/NF9amisERMTVj5gbcFx0hEaO0wedKNNBNSr+CheBJc4CSBXfbv49y/plRE8frc99e3nucZFe6HHGRqiDzXEv0= MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; MWHPR02MB2879; 2:Ho7emBQGmyuYcEGdgUllIDaamqHnpN7xJEp/llAqAHpKz7XHEZIU+zn9RN6an7/PlnYLnxMZG1rD8AUkv1XfcV7uHmSRSEa64betl6X4SPTpZ3/VJElRN+05LLuHV8s9axNCQkPPB73xB6WPKsEX/ecN9w0swTaLusLPvZfLrlI=; 3:aQMoJ9BRsq74eQRgb5NlryTRWlBwcY6UilLA0hfn5m+StXla9m3m+RoEOtteSEO/Ih1P4dDvncV+dRQRV0XJAJ7K0QIwmSlPeYO9/HA8kNj5momC/9PmPtAFd1kdRLL0F5Gnwk+NONwuHwmpBkIxKOlKlizc1+oou/zbF/FtEBbRau5ehCPpwjDh8/hbHt5v5asZ92m+mJu+EDfYukvmrz//t/3mqEfKWfz7BWFRAoEj98G13J5LD2BorTEc0ylSFVmSmFR3Favf3YDWxmbn6lut4CKH/kPJhXg9+Z6AIsQ=; 25:iHRnoMZStShRwZd4aU0n89F+d6QaqfD+LzoT4OF0wtbtmoACj/mYbhIC+Syb1s4DMFD/5gGhO+JikkOwxdpOy3uVNCc6ddVFAzGyk9FD+BBNILcG/V37ujk+dQjfH/gmHtOsdKOsXPFpY36pNKoBAYSbRkHEpsqrw+NLXjBwBitcgn8A6xlCFF6DeVCqBCtWlYwNTDkItmOqmWedZptWg0rXfodq4wnIfvPhkR8zSDDZ/pDD/sOv6llSWnBobSHk5jZC11tdp2rRZUVVztZs1oneGC/it6ZKeF8WPZbixx9jm9FCHtDDZuBtVJqsxzLBL6fLiMtOLROA0a0pPY0d5tCjAbRw5fZMf++SkELzUqX4JYB5Dw6sU2VMzscORRkzlvocUGk8bsH/ereULye2E5Pf2057DfJn1alkQknhAYazYnR7DD8q9QURZT997nh5 X-MS-Office365-Filtering-Correlation-Id: 5791d151-3ac0-458e-a878-08d40a8cca24 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(8251501002); SRVR:MWHPR02MB2879; X-Microsoft-Exchange-Diagnostics: 1; MWHPR02MB2879; 31:Q0s7ucceJ7ZmrPwmTz1Uu5MMEt/HsMruz3P3czJpKZy9EZXNx6lOwdEPIe5Uutpf+0b4YpRdOgv2oOWRBeysAnHQXcvmqrvL5n6IahdBqXSEVlu8sNgCuZxW+w4GFnDyhlL4hwcTm6RJYsZyK193qA4103lrptJsZwOtmCydC6Bvth6sJx/hHnAN/lHtjGYUJs9KjXETlYPR23JfxOHCYKLdeTQz5jUKsXKI7tB4Uq5GFrt2zUE5IKViA7JzsqDqRn5LuVfXq6i+sk3RPcjAfA==; 20:8KU0hA2Sz+UJqUSSuJe2E5KP69g9JkpYFoSNjSyiOLfEDQx/vvOIwG7D6JAT0nKZVvkD+W7hl21ZQcaW3Mb8YajmXNv63SHlSrs3F7Cg+lil4dKJwzAevOtoWszoink8WsciXy52/JIIedrmSGGJke+NM/GVVJX9wCJAgePckmIvsPJTRh93UsuykxNkN3YaBBQcojmiQbJk+wScTUcx6EIe30MrR86g4MUz1eDiX/fkq8P1zJnWw5uKEl3j16OWBSQZojJ99xYKLokuqei4BPy+vz/e/iswKvvaDq/NC8Efu2OKHIsncozWbjFNVkRIm+aLATUHDL1YHvc1uRM7KaRDtfZtaY0/wY6jOnqAQ2iJkn9CqTCd32VETfOa3z0EaZms/Bpvv1lwG6EaRwcNuNmVxQLFBkiAFbex50jYGHe0OEsybsHJ80DBd0KA3uoxpYaGJHWpMe19xRbJtJzQGbWDBFlKbaBf4tePphtPdRH4nDhs/mxedy4ZTOExmmwH X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592)(189271028609987); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(13018025)(5005006)(13023025)(13017025)(13015025)(8121501046)(13024025)(10201501046)(3002001)(6055026); SRVR:MWHPR02MB2879; BCL:0; PCL:0; RULEID:; SRVR:MWHPR02MB2879; X-Microsoft-Exchange-Diagnostics: 1; MWHPR02MB2879; 4:hGn41+W0vz7VCcj90MDQ77ZIbfA/ShbZ94JlPAZC3Od82cU2UD2izTT6fR5Ht8TUmyeBCqR9RVcv0N283KS/n93oKofGNNM2Nh16okuSY6frn2JEos2ItQw+seFn5+Mdw200+K5rZcngRNjtdWq/cXNDX9OrSyV9EqYLyr30nLDa2tfcVMsQUQg62eo3XCyJMevI19JYohqxI4wYS/by+ZP2JJ2DFVaAAHkPl5d/L5RTMcH5efcY2+59zWmHvupsKSwpGaxM+K+zZUelsXyhfNPGb4R1HHAG0fMsQA6ncZr5Ldg9iP4SMN1h4W+d+ssVtYyvY31Dbm6nqVB8gmUrvgZX933EKZMtVMvp7blRHP2WGHygDM7KRU5s0kkz+nrjmAxuN817c5RYum/2rJBSKV+S+A9jlMfjdncKqdjll4Sa+XOH35UwdwZGUK3veTXekzzUun8GZPj7B6su2VCCWUTshAKmkC3GSlj7lC0Av+NTi5Y2K5vRRayZB/A5mjlBS2tCormxQCWXgyB4KTpNq2Q+2eHlUkLqqzZNHsYh8KR1I/G/lLp1fBv4nq/LpAATsKRt5tpXciuEok7bOX0nwA== X-Forefront-PRVS: 012349AD1C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; MWHPR02MB2879; 23:qJtAsK66TzXSLtElu0FAQYKF2KCn5ulCON6bIeOwG?= =?us-ascii?Q?v9rohsLZMrEZr7njdYc8zQYWpliHYwyTiqsw2T9HRolx4sMLN8As6emqY2/3?= =?us-ascii?Q?ROf4Pl5Mf4hUqOZohWvUYxBFsLaULMDFAanCnnWw+KRzSKb0CYyZhSeisFoD?= =?us-ascii?Q?v2wWzbDMvhehpQGCn5pshRbfC+q8OMe2zmX19fbLiBvLEafjcH3XtKI/jFST?= =?us-ascii?Q?vceVFqFnZf/w6jF30HKyVaLFkCyXlNTCJ3PvFyD8A13Uba6CZqB4OENuLzwE?= =?us-ascii?Q?s0JsHpgkVPOuVKMMF4/BYV19fQg/gxtjpW/Qxgl0J2u/QQdp2O6gZYQr9wOB?= =?us-ascii?Q?8pYF33eHFlW4UvFUrs6y69RLqPqAW4EhQtwkdid8eB8vnFaDbGV8mZKCY8qd?= =?us-ascii?Q?DGM7y3XOsf5bF7mbmZDaBGuuuvUugN859wv5JKBmNQEc4+7Ja2eW9ru6o7yF?= =?us-ascii?Q?uLz75kRT1rgBtwSFV98ezY5X2p7RdqOqZJvSxk+YCKn3oBFmTZWr+h7Whb2S?= =?us-ascii?Q?UTysZaKVIPw335/3a7y+7K0LKr54ep+ZDgYtsdXPQA4CrIQN8LH4RfuxEG2r?= =?us-ascii?Q?bqSu8oiwTpfIG5u6X4ur4rRMsddhRf5wvR8HOjlIq/pqtAdufUTTC4JZUcuE?= =?us-ascii?Q?ejduQxfCB+UpRPRx0uJUlJQBt4fwP0UnC88m/PevkRnHDGlxz2gKVCXmg0rt?= =?us-ascii?Q?A4vb4s5EAZ/N1QMoCf97n2dd9YWNPle9pk7mMVE0Rg8/zZP+oSyt5XqziCjI?= =?us-ascii?Q?GXpnnWhhUOgn/sM4dsvNjxo2g0eZcTYYAlM810UiWJf2P2XFWrGHzhK+c+et?= =?us-ascii?Q?yYDIUuOfvohGXzLGexEykXcIWSPOmGFtcpDVYVuui1pxKrqVP/a+AYmxbbjX?= =?us-ascii?Q?YoWdmMLyS8K5j/VWi3Y37k8d3m2r/FLXfADgMArxtp4LAM61FkKiQZ6XW0bi?= =?us-ascii?Q?dn2SNop9fKhiiaKC6A28o6uUAJc22rnnrXgFhAtKdiZXqckKFT2QLw1hSg20?= =?us-ascii?Q?rVYp44TcStMzeIvh48i49CKP7cyKy24Ts0SBBo8zi76HA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR02MB2879; 6:g3wjDIdVu5CaMpkmITBkBT7p7SsGQEb+SMc+4Dy6eVnhO2D5c57yIzd8Uuas2+J2T3Z+woL/OVnEIdX5eRn+sLV/PRlFgr84HQXb+o5wjOavM1AkJTfiHZgA4hfW6c6ZvTSmBMIsjz49aweH5pvMD3GHQuycRiuCPo5RrXAnA2kELvEOmzZWl8cKOnJsaqUdPALPcN/i1GaonKXDbFHKF2gwWvPfMvq9shN91c/IulrZBiON45JatQ/hvtIEfz4Wh+XGNTUtTBEwuEwpuN1VgwTYj/5b/8/3Gywgg76276fcKoJg5xCHSvx4N5rYzxcbyb5hw2BtJIcGHCBIgG1tv4yWwykbg0qVtAmgf8px9IM=; 5:a5NeWl6MmkY0wN8U97YDpihPgtE7IJnZAkrPeU4x9l0lXHwrMHUAUN9DCUTzuWk7Zrxccp3tJfDcQXtO4eiltaQbzAFOcpBSBv7jRpiFMnZhh/i/alQWC4FN0p70LWX+HOu8A3FcmpcEtKAeVeG2Yg==; 24:1EzOGT1BRa2D46A4Z4wDEsgkT3UyjLHsBcPl46V8VBsIPWvJxpiBUue6E7+IIOzxzRd/Ie/q4C5BtZWvT4qbHcFhqvUWGbFBuUvaiL8cfcI= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; MWHPR02MB2879; 7:uC5suP5WClLHeIYuC2jPrat9c7lH2ASvlThv/SSjcsn1ke4QRqxrNcqzy3pUSuevNg4E80WMQ0ivnYaffCaM+bgdtVn5CQN4L7cAqA4ZfinJuCnx7RiL5f338TN/HPdmZCtFA7oQMLZcfH1AJg8JXqBcLwKKdD1mnCZTPSo744rS2ctOWE2Q+QGhr1BZqi7a01Ewv1xW8UulYQwX7yCuFUtKYwm/ARedA4MVQ7wQD9Pl0O+hNxWofA7MOc5szi1W2ufTO6djd4xQ0bLKPJM66mPbTck2S6pYPY7bmT80CMIebTjSFd8tVwziN2sGmr3qqjqtLmOquYQ82u7LtlNGQKXUtWzWm2yZ+uFu6+2vXzI= X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Nov 2016 23:45:15.0587 (UTC) 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.83]; Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR02MB2879 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.42.51 Subject: [Qemu-devel] [PATCH v1 1/2] xlnx-axi-gpio: Add the Xilinx AXI GPIO device 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" Add the Xilinx AXI GPIO device. This is a commonly used device that lives in the programmable logic (PL) in Xilinx chips. Signed-off-by: Alistair Francis --- hw/gpio/Makefile.objs | 1 + hw/gpio/xlnx-axi-gpio.c | 269 ++++++++++++++++++++++++++++++++++++++++ include/hw/gpio/xlnx-axi-gpio.h | 65 ++++++++++ 3 files changed, 335 insertions(+) create mode 100644 hw/gpio/xlnx-axi-gpio.c create mode 100644 include/hw/gpio/xlnx-axi-gpio.h diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs index a43c7cf..b9b7a59 100644 --- a/hw/gpio/Makefile.objs +++ b/hw/gpio/Makefile.objs @@ -7,3 +7,4 @@ common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o obj-$(CONFIG_OMAP) += omap_gpio.o obj-$(CONFIG_IMX) += imx_gpio.o +obj-y += xlnx-axi-gpio.o diff --git a/hw/gpio/xlnx-axi-gpio.c b/hw/gpio/xlnx-axi-gpio.c new file mode 100644 index 0000000..560c06a --- /dev/null +++ b/hw/gpio/xlnx-axi-gpio.c @@ -0,0 +1,269 @@ +/* + * QEMU model of the Xilinx AXI GPIO Registers + * + * Copyright (c) 2016 Xilinx Inc. + * Written by Alistair Francis + * + * The data sheet is avaliable here: + * http://www.xilinx.com/support/documentation/ip_documentation/xps_gpio.pdf + * + * 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/gpio/xlnx-axi-gpio.h" +#include "qemu/log.h" + +#ifndef XLNX_AXI_GPIO_ERR_DEBUG +#define XLNX_AXI_GPIO_ERR_DEBUG 0 +#endif + +/* The interrupts should be triggered when a change arrives on the GPIO pins */ +static void irq_update(XlnxAXIGPIO *s) +{ + bool general_enable = ARRAY_FIELD_EX32(s->regs, GIER, GIE); + bool pending = !!(s->regs[R_IP_ISR] & s->regs[R_IP_IER]); + + qemu_set_irq(s->parent_irq, general_enable & pending); +} + +static void data_handler(void *opaque, int irq, int level, int channel) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(opaque); + unsigned int data_regnr, tri_regnr; + + assert(channel > 0 && channel < 3); + data_regnr = channel == 1 ? R_GPIO_DATA : R_GPIO2_DATA; + tri_regnr = channel == 1 ? R_GPIO_TRI : R_GPIO2_TRI; + + if (!extract32(s->regs[tri_regnr], irq, 1) || + extract32(s->regs[data_regnr], irq, 1) == level) { + /* GPIO is configured as output, or there is no change */ + return; + } + + s->regs[data_regnr] = deposit32(s->regs[data_regnr], irq, 1, level); + + switch (channel) { + case 1: + ARRAY_FIELD_DP32(s->regs, IP_ISR, CHANNEL1_ST, 1); + break; + case 2: + ARRAY_FIELD_DP32(s->regs, IP_ISR, CHANNEL2_ST, 1); + break; + } + + irq_update(s); +} + +static void data_handler1(void *opaque, int irq, int level) +{ + data_handler(opaque, irq, level, 1); +} + +static void data_handler2(void *opaque, int irq, int level) +{ + data_handler(opaque, irq, level, 2); +} + +static void xlnx_axi_gpio_data_post_write(XlnxAXIGPIO *s, uint64_t val, + int channel) +{ + unsigned int tri_regnr; + bool gpio_set; + int i; + + assert(channel > 0 && channel < 3); + tri_regnr = channel == 1 ? R_GPIO_TRI : R_GPIO2_TRI; + + for (i = 0; i < 32; i++) { + if (extract32(s->regs[tri_regnr], i, 1)) { + /* GPIO is configured as input, don't change anything */ + continue; + } + + gpio_set = extract32(val, i, 1); + + switch (channel) { + case 1: + qemu_set_irq(s->outputs1[i], gpio_set); + break; + case 2: + qemu_set_irq(s->outputs2[i], gpio_set); + break; + } + } +} + +static void xlnx_axi_gpio_data_post_write1(RegisterInfo *reg, uint64_t val) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque); + + xlnx_axi_gpio_data_post_write(s, val, 1); +} + +static void xlnx_axi_gpio_data_post_write2(RegisterInfo *reg, uint64_t val) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque); + + xlnx_axi_gpio_data_post_write(s, val, 2); +} + +static void xlnx_axi_gpio_post_write(RegisterInfo *reg, uint64_t val) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque); + + irq_update(s); +} + +static uint64_t xlnx_axi_gpi_data_read(RegisterInfo *reg, uint64_t val, + uint8_t channel) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(reg->opaque); + + switch (channel) { + case 1: + return val & s->regs[R_GPIO_TRI]; + case 2: + return val & s->regs[R_GPIO2_TRI]; + default: + return val; + } +} + +static uint64_t xlnx_axi_gpio_data_post_read(RegisterInfo *reg, uint64_t val) +{ + return xlnx_axi_gpi_data_read(reg, val, 1); +} + +static uint64_t xlnx_axi_gpio2_data_post_read(RegisterInfo *reg, uint64_t val) +{ + return xlnx_axi_gpi_data_read(reg, val, 2); +} + +static RegisterAccessInfo xlnx_axi_gpio_regs_info[] = { + { .name = "GPIO_DATA", .addr = A_GPIO_DATA, + .post_read = xlnx_axi_gpio_data_post_read, + .post_write = xlnx_axi_gpio_data_post_write1, + },{ .name = "GPIO_TRI", .addr = A_GPIO_TRI, + },{ .name = "GPIO2_DATA", .addr = A_GPIO2_DATA, + .post_read = xlnx_axi_gpio2_data_post_read, + .post_write = xlnx_axi_gpio_data_post_write2, + },{ .name = "GPIO2_TRI", .addr = A_GPIO2_TRI, + },{ .name = "GIER", .addr = A_GIER, + .post_write = xlnx_axi_gpio_post_write, + },{ .name = "IP_IER", .addr = A_IP_IER, + .post_write = xlnx_axi_gpio_post_write, + },{ .name = "IP_ISR", .addr = A_IP_ISR, + .post_write = xlnx_axi_gpio_post_write, + } +}; + +static void xlnx_axi_gpio_reset(DeviceState *dev) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { + register_reset(&s->regs_info[i]); + } + + irq_update(s); +} + +static const MemoryRegionOps xlnx_axi_gpio_ops = { + .read = register_read_memory, + .write = register_write_memory, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void xlnx_axi_gpio_realize(DeviceState *dev, Error **errp) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(dev); + + /* Create two GPIO in banks that QTest can use */ + qdev_init_gpio_in(dev, data_handler1, 32); + qdev_init_gpio_in(dev, data_handler2, 32); + + /* Create GPIO banks as well */ + qdev_init_gpio_out(dev, s->outputs1, 32); + qdev_init_gpio_out(dev, s->outputs2, 32); +} + +static void xlnx_axi_gpio_init(Object *obj) +{ + XlnxAXIGPIO *s = XLNX_AXI_GPIO(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + RegisterInfoArray *reg_array; + + memory_region_init_io(&s->iomem, obj, &xlnx_axi_gpio_ops, s, + TYPE_XLNX_AXI_GPIO, XLNX_AXI_GPIO_R_MAX * 4); + + reg_array = + register_init_block32(DEVICE(obj), xlnx_axi_gpio_regs_info, + ARRAY_SIZE(xlnx_axi_gpio_regs_info), + s->regs_info, s->regs, + &xlnx_axi_gpio_ops, + XLNX_AXI_GPIO_ERR_DEBUG, + XLNX_AXI_GPIO_R_MAX * 4); + memory_region_add_subregion(&s->iomem, + A_GPIO_DATA, + ®_array->mem); + + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->parent_irq); +} + +static const VMStateDescription vmstate_gpio = { + .name = TYPE_XLNX_AXI_GPIO, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, XlnxAXIGPIO, XLNX_AXI_GPIO_R_MAX), + VMSTATE_END_OF_LIST(), + } +}; + +static void xlnx_axi_gpio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = xlnx_axi_gpio_reset; + dc->realize = xlnx_axi_gpio_realize; + dc->vmsd = &vmstate_gpio; +} + +static const TypeInfo xlnx_axi_gpio_info = { + .name = TYPE_XLNX_AXI_GPIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(XlnxAXIGPIO), + .class_init = xlnx_axi_gpio_class_init, + .instance_init = xlnx_axi_gpio_init, +}; + +static void xlnx_axi_gpio_register_types(void) +{ + type_register_static(&xlnx_axi_gpio_info); +} + +type_init(xlnx_axi_gpio_register_types) diff --git a/include/hw/gpio/xlnx-axi-gpio.h b/include/hw/gpio/xlnx-axi-gpio.h new file mode 100644 index 0000000..d5024ee --- /dev/null +++ b/include/hw/gpio/xlnx-axi-gpio.h @@ -0,0 +1,65 @@ +/* + * QEMU model of the Xilinx AXI GPIO Registers + * + * Copyright (c) 2016 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. + */ + +#ifndef XLNX_AXI_GPIO_H +#define XLNX_AXI_GPIO_H + +#include "qemu/osdep.h" +#include "hw/sysbus.h" +#include "hw/register.h" +#include "qemu/bitops.h" + +#define TYPE_XLNX_AXI_GPIO "xlnx.axi-gpio" + +#define XLNX_AXI_GPIO(obj) \ + OBJECT_CHECK(XlnxAXIGPIO, (obj), TYPE_XLNX_AXI_GPIO) + +REG32(GPIO_DATA, 0x00) +REG32(GPIO_TRI, 0x04) +REG32(GPIO2_DATA, 0x08) +REG32(GPIO2_TRI, 0x0C) +REG32(GIER, 0x11C) + FIELD(GIER, GIE, 31, 1) +REG32(IP_ISR, 0x120) + FIELD(IP_ISR, CHANNEL1_ST, 0, 1) + FIELD(IP_ISR, CHANNEL2_ST, 1, 1) +REG32(IP_IER, 0x128) + FIELD(IP_IER, CHANNEL1_EN, 0, 1) + FIELD(IP_IER, CHANNEL2_EN, 1, 1) + +#define XLNX_AXI_GPIO_R_MAX (R_IP_IER + 1) + +typedef struct XlnxAXIGPIO { + SysBusDevice parent_obj; + MemoryRegion iomem; + + qemu_irq parent_irq; + qemu_irq outputs1[32], outputs2[32]; + + uint32_t regs[XLNX_AXI_GPIO_R_MAX]; + RegisterInfo regs_info[XLNX_AXI_GPIO_R_MAX]; +} XlnxAXIGPIO; + +#endif /* XLNX_AXI_GPIO_H */