From patchwork Sat Jun 12 16:06:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12317181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36AAEC48BCF for ; Sat, 12 Jun 2021 16:11:48 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4543261156 for ; Sat, 12 Jun 2021 16:11:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4543261156 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56436 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ls6Ec-0006YB-05 for qemu-devel@archiver.kernel.org; Sat, 12 Jun 2021 12:11:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59950) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ls69q-0002au-6m; Sat, 12 Jun 2021 12:06:50 -0400 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:45077) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ls69l-0002It-Ar; Sat, 12 Jun 2021 12:06:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1623514004; x=1655050004; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=4RMU+0RWm/+x2Ub2rxVu3jE0pKHV0RR5eRgvFdYV/q0=; b=pvRvirClItKM8bGMFVTc8TmgawcU+K+c5srUSFkmiMKFojevFN7/AkSf pNQeEXWd36/vG4SG1N6A8T5zRwxOnmanRbA0MTbA7dEUES0+gjT+LOLjO TrnO5MEFUYbIFTbx5eCh6yP/k/jfwrFlPDcfzW8xqgV7nNQWz9ntspJx6 rqBbUrmovZdtN2vFGmwmxeuVtA+1EcTiZaNCPMMx+xJC62u9wkzIwnrUs 4+80OMQfHWLPyiW7o6jAaPoWq8urKxdTpIdduF4XWPBrUj8zu+1DPhyYc xM+CxLEd5PF7+sDpeQmP0uXBkflg2JwwxOUkXX63w2f5lGNUFc9EkqTyL g==; IronPort-SDR: NAlTL822CwwljO0G60fttFQ3SS7k7XDVtVYUS3rDi4FCwqdt98iyflDVLGj4QmGUS9suaNPbdY KXt+nbKZTK9lAVpavkS7+dgYESsvo4GRMhleTOE24gHQUEFC9KTMG7I8qL9ulMANy4ExGXU3oZ AmMz0V52GTJ/ajVRkGIQA4xDoaRcDUVTOSbUuDhpD+DuXnWVxCVPhRxazNDJ5/zAZF3WN5yd/j XQ46M4WBAR2WjfxKcnlZQp2utk5WycIDTMTQPt2u/nQseS/XcehzSetuNoNMBWN+mNcB0898to NEQ= X-IronPort-AV: E=Sophos;i="5.83,268,1616428800"; d="scan'208";a="171704747" Received: from mail-bn8nam12lp2177.outbound.protection.outlook.com (HELO NAM12-BN8-obe.outbound.protection.outlook.com) ([104.47.55.177]) by ob1.hgst.iphmx.com with ESMTP; 13 Jun 2021 00:06:40 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=e7zN02K/TFYQOMsmxes7C8Ev2fvtBqXosWUxqmtptmOr7tBqXFjJVm4tst+2O3uG8lGirYpA8YRY6hRMyeq9JchMHHCAqPFMWEH2c+vHRFr5vrpGIkbog6QVExW5nWKkcJYs4qwmELpMMjSofvjGG0FsAiDpn7cHmcRQ9M+3qGTdbC57wWddot90bHD91gzNuM1J8uEHgvdd1wiicZ+Hgzju5zw0/nSnspo9HxjhflcRdotHbybFVSpecLLuuE7do7RHF/7rryPB7I+DmWk87l15YFP2Qf5HkWNlf0B3Ub2dsyzUuWjk5zHWFH4vPfLUbbljvdPU0cPV8mKZs2wrkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BdHdkj4QNJzr2EhtBQDgu9UTKlLUVzDvpPiUU8aRBUo=; b=HbRqwBX+DwFYM9++YsXR/QG5EE3Dl4MI97fvI+I0LyvNw3SqCmuvtKiXM4SmSz/+2Y81tiyS8fKL1DtVYpwhmGY7K0LtZhAIMdgA7F9jKd8g1ychbc4x++FN7y9xw2+5mhrqkgZRfjXuisSdNxRD/36h6p7JMTqcUp16fWhAniwJ8Ln47SUaMsTbtOcvfGubfNQ3ARMGKNZK2NF/hCdn7aB2lyrtR4vov/mYEt6A5Yi2sxMfX5A/En539XeVqpZNDAkashDcHlCG4JfZ374rah83Ebf8hNZudtxAX8gWU93ZabLJyz/urT1EhD86oPoIgX3N727LjAbRfBIXPsNmUQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BdHdkj4QNJzr2EhtBQDgu9UTKlLUVzDvpPiUU8aRBUo=; b=TWQK34uAm0XbL+jpLPrH1DVY03OxW1CkFxuhjofvHYDh74R+D1P5u3j/6MRxXHIpqqfbknweVihtFfnqEYl2lzmw9UeKF9LvkBpZe1V6XSNwPTTXBqRBLlZ0f7SXQJIpa53/KrUg0WZt27vhZ/Tlx5UnnGudxlBg6zQhePFY0WE= Authentication-Results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7747.namprd04.prod.outlook.com (2603:10b6:5:35b::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.22; Sat, 12 Jun 2021 16:06:40 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::a153:b7f8:c87f:89f8]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::a153:b7f8:c87f:89f8%9]) with mapi id 15.20.4219.025; Sat, 12 Jun 2021 16:06:40 +0000 From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v1 1/3] hw/intc: Upgrade the SiFive CLINT implementation to RISC-V ACLINT Date: Sat, 12 Jun 2021 21:36:13 +0530 Message-Id: <20210612160615.330768-2-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210612160615.330768-1-anup.patel@wdc.com> References: <20210612160615.330768-1-anup.patel@wdc.com> X-Originating-IP: [122.171.171.205] X-ClientProxiedBy: MA1PR01CA0172.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::16) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from wdc.com (122.171.171.205) by MA1PR01CA0172.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.21 via Frontend Transport; Sat, 12 Jun 2021 16:06:36 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 69b0bf48-06ec-43d0-dc65-08d92dbc1024 X-MS-TrafficTypeDiagnostic: CO6PR04MB7747: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:240; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 3vYVimjdQxanplKgD0N23mSjsRZFSHhJjpMYaBQs68UrJJb9+1iged7ZHC/vY9dK2muzhl+Z546tQhu17h4CdPlKLfbXkhuJd51lJ9+gSRkNOqhMLE2zoC8ttbqlnppz67kVfiV0I6CwYGCOWYC68YzJj2x2P8FgeFLBmb59iUs4Z/gFRRFKqiGfh2xXa1QkJme4TEDgUUHZPPhra2V+8A9MZJco/NHVQIGwR/4CMygkBQKOVFVKoeTqDgGKAH9hTP27ulTHxhQ+/dsqFEdt9Cw7hcVBqzfvHJdDZ8JADMUXbFA41mQ1/VyJbq5OCEVLnLabv+/XwXnIwzmvWHLpT7L37vZGlfh3x0S5cTjUxYGGtQt3eQ99PCyt2TUmN0WJJebgnXr9lhKw/2L9VpOaLQR1s1R6ksEfWT9Vy0eyzMoipM2Brc/Yqz+qkCFpD69gL8FS0o7naltUrNj5+M0yMj80KQHRLF3fPUUDZR136KBEwnql9PY2acST2PsHgJToXEfnq4f5z8YEvyXNfTtseQkyBVniptX0Zwty10hgiQFbhjv9L5r3mEgCDWcb7Dpwaj5e7mfAhr2wXBGlxe28VbyORI6Quas6iMxSw23nE+KEvMa1Q22LGvg72f7jjlcwvPb3nRL83F0L+J+jA450Ho35Ti5gVQXuRByNI5FvRXdxeWe++0I/aPf4jzMoWAVdRZO6qLIFbe38R0aMLeb9jpSQpAkspbdy4YjdJOAyLUEL31d7D+M0iYj1ZoWykTw1DQjg5hPcO5kcELS5ZSBg9W1xYc4q0/S93EqUehKCvLs= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CO6PR04MB7812.namprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(6029001)(4636009)(376002)(396003)(136003)(366004)(346002)(39860400002)(54906003)(8936002)(8676002)(110136005)(4326008)(2616005)(44832011)(16526019)(186003)(66476007)(66556008)(66946007)(2906002)(956004)(316002)(38350700002)(86362001)(38100700002)(55016002)(30864003)(26005)(7696005)(8886007)(36756003)(52116002)(6666004)(83380400001)(1076003)(478600001)(5660300002)(2004002)(579004); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 2OFeP73Kp4Q3ATkX3Tn7C9g1bM1i16KpKFuQyQTsVOxgh0m+xGkYtOx/17R3L1NlSW6AiyXHUQganwzN4JyRmnrnL5crBn+tw0ogywGk75900yKcjIJB+uXdYEtC3QlQ4YLvP91Fw0TIicR/C8U3iFNSRQ4lrCHTZ//oLUW8GThednK5N5gS1IbSDPE4PboK2sXDyP6Cj9kGCrMFnEEsmeZSpNSFkltSlwF+alxETRSOzb7SWSzIb+z27J20mK1C0vhP1HV7AuMm3358kN0oxLnvOP5fDmDvrD+qovCp251OQbX3sgOdnjzpmCxGejYXQrHKxW40DNPSG4IR+eJQMKgMvh1HL4ql1QiK5wUb3ybR355gHZQM9O4eTqzPGwbeiolCkdN29mECY+i+aKbrzJFDHCqc6GeRe3DsPpvFR5McTk6WqkNP/jdWE+t0cxUJxUyFEA/SjugTh6Yh5yLiBNQ1leiB2XxdyjByToaUq9RXPANok86YNo6eYxynVvNORPoTfx4xOJLHxeFDnVFjT24STzp+mau+Ckj6BV2+coM2UWKLHFKZ3qcpgM02zvFWRTjrkbX1NsvG4mHccH/t97pyb5D1a8m+KnQkjiNeEq9JcJP3chEOyp2bbcqYTL9w5eDlcP8gqsQ53+HjjRKfK8sXZAc9a/5tCWFnMJaww/ysGpiY17Hk2m2UJKvf40kVFV+/+sW7MUJGgZVUYrxDtNSlI+7rE8gLccBjcBV+x9al5plCtbnGILFVWcvMKzqVymY9f8dyddh+Cz7sOMGg5CarkxNEwR7f+WRSuiJf3bg4pSV1tubsoscLI4z5odrHQZDwG3pia2zM+u+CXtnwT4FzstjYjfxGjheMwmNibv+kF4OJlF92XoEa0YeN+9BP0Pd2aBaFY3Q8CCOhxgfuzbwoQbWZ2d5pSXRqYV8LyjItCd0Q7fCkPX+od7LV6UBr1wk/gwEnGI4Mu2bEmBy/n4VyBeAfzy/nmFmW+9Yoh1yHKN86kMULKb8qNM23wTVIpnvCp0PIB38pjs8hKvN5ol6gFqaf+MNf9evKzpnVFqNUdP+Cm9ZAZZAcnkbpnXsWjjFGhH/In+Kq1TqWO5I7HuVsd9re4b+JnBZOyQ6KTkF+CDU5c74Zr79ycvSSBtjJ/cCOXOOTD/72wwMOsZ1Q575J40t7b2S2KP3M5qjoWCMUXNvJlVl0ieIf4+Shp1Q43Ho+0eyoFCtZpvqGo1FMoZ3ad7Oq/pVPAZf93NwVftwYOv7zCT4XVdhgWcTqbNLw78UFbZgBVSjkFxKUhf/WZZ97VaodkM27yG1/qB8tCONPaYN05Biax6Ubhkt4q9XG X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 69b0bf48-06ec-43d0-dc65-08d92dbc1024 X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2021 16:06:40.1859 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: SEAk+hKwod9HXIjo+TmXLL3xLgw90hJAGoQfM5PQOgA5Qexga7vKumBBOeKwOTCH0s4evCljFRciOIIxBu+9QQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7747 Received-SPF: pass client-ip=216.71.153.144; envelope-from=prvs=790f0be0c=Anup.Patel@wdc.com; helo=esa5.hgst.iphmx.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, MSGID_FROM_MTA_HEADER=0.001, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Atish Patra , Anup Patel , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Anup Patel Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The RISC-V ACLINT is more modular and backward compatible with original SiFive CLINT so instead of duplicating the orignal SiFive CLINT implementation we upgrade the current SiFive CLINT implementation to RISC-V ACLINT implementation. Signed-off-by: Anup Patel --- hw/intc/Kconfig | 2 +- hw/intc/meson.build | 2 +- hw/intc/riscv_aclint.c | 374 +++++++++++++++++++++++++++++++++ hw/intc/sifive_clint.c | 266 ----------------------- hw/riscv/Kconfig | 10 +- hw/riscv/microchip_pfsoc.c | 12 +- hw/riscv/sifive_e.c | 12 +- hw/riscv/sifive_u.c | 14 +- hw/riscv/spike.c | 15 +- hw/riscv/virt.c | 15 +- include/hw/intc/riscv_aclint.h | 73 +++++++ include/hw/intc/sifive_clint.h | 60 ------ 12 files changed, 494 insertions(+), 361 deletions(-) create mode 100644 hw/intc/riscv_aclint.c delete mode 100644 hw/intc/sifive_clint.c create mode 100644 include/hw/intc/riscv_aclint.h delete mode 100644 include/hw/intc/sifive_clint.h diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig index f4694088a4..78aed93c45 100644 --- a/hw/intc/Kconfig +++ b/hw/intc/Kconfig @@ -62,7 +62,7 @@ config RX_ICU config LOONGSON_LIOINTC bool -config SIFIVE_CLINT +config RISCV_ACLINT bool config SIFIVE_PLIC diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 1c299039f6..2482fcfaf8 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -48,7 +48,7 @@ specific_ss.add(when: 'CONFIG_RX_ICU', if_true: files('rx_icu.c')) specific_ss.add(when: 'CONFIG_S390_FLIC', if_true: files('s390_flic.c')) specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true: files('s390_flic_kvm.c')) specific_ss.add(when: 'CONFIG_SH_INTC', if_true: files('sh_intc.c')) -specific_ss.add(when: 'CONFIG_SIFIVE_CLINT', if_true: files('sifive_clint.c')) +specific_ss.add(when: 'CONFIG_RISCV_ACLINT', if_true: files('riscv_aclint.c')) specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true: files('sifive_plic.c')) specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c')) specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'], diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c new file mode 100644 index 0000000000..682f95cca7 --- /dev/null +++ b/hw/intc/riscv_aclint.c @@ -0,0 +1,374 @@ +/* + * RISC-V ACLINT (Advanced Core Local Interruptor) + * + * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu + * Copyright (c) 2017 SiFive, Inc. + * Copyright (c) 2021 Western Digital Corporation or its affiliates. + * + * This provides real-time clock, timer and interprocessor interrupts. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/module.h" +#include "hw/sysbus.h" +#include "target/riscv/cpu.h" +#include "hw/qdev-properties.h" +#include "hw/intc/riscv_aclint.h" +#include "qemu/timer.h" + +static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq) +{ + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + timebase_freq, NANOSECONDS_PER_SECOND); +} + +/* + * Called when timecmp is written to update the QEMU timer or immediately + * trigger timer interrupt if mtimecmp <= current timer value. + */ +static void riscv_aclint_mtimer_write_timecmp(RISCVCPU *cpu, uint64_t value, + uint32_t timebase_freq) +{ + uint64_t next; + uint64_t diff; + + uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq); + + cpu->env.timecmp = value; + if (cpu->env.timecmp <= rtc_r) { + /* if we're setting an MTIMECMP value in the "past", + immediately raise the timer interrupt */ + riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1)); + return; + } + + /* otherwise, set up the future timer interrupt */ + riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0)); + diff = cpu->env.timecmp - rtc_r; + /* back to ns (note args switched in muldiv64) */ + next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); + timer_mod(cpu->env.timer, next); +} + +/* + * Callback used when the timer set using timer_mod expires. + * Should raise the timer interrupt line + */ +static void riscv_aclint_mtimer_cb(void *opaque) +{ + RISCVCPU *cpu = opaque; + riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1)); +} + +/* CPU wants to read MTIMER register */ +static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, + unsigned size) +{ + RISCVAclintMTimerState *mtimer = opaque; + + if (addr < (mtimer->num_harts << 3)) { + size_t hartid = mtimer->hartid_base + (addr >> 3); + CPUState *cpu = qemu_get_cpu(hartid); + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; + if (!env) { + error_report("aclint-mtimer: invalid hartid: %zu", hartid); + } else if ((addr & 0x7) == 0) { + /* timecmp_lo */ + uint64_t timecmp = env->timecmp; + return timecmp & 0xFFFFFFFF; + } else if ((addr & 0x7) == 4) { + /* timecmp_hi */ + uint64_t timecmp = env->timecmp; + return (timecmp >> 32) & 0xFFFFFFFF; + } else { + error_report("aclint-mtimer: invalid read: %08x", (uint32_t)addr); + return 0; + } + } else if (addr == (mtimer->aperture_size - 8)) { + /* time_lo */ + return cpu_riscv_read_rtc(mtimer->timebase_freq) & 0xFFFFFFFF; + } else if (addr == (mtimer->aperture_size - 4)) { + /* time_hi */ + return (cpu_riscv_read_rtc(mtimer->timebase_freq) >> 32) & 0xFFFFFFFF; + } + + error_report("aclint-mtimer: invalid read: %08x", (uint32_t)addr); + return 0; +} + +/* CPU wrote MTIMER register */ +static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + RISCVAclintMTimerState *mtimer = opaque; + + if (addr < (mtimer->num_harts << 3)) { + size_t hartid = mtimer->hartid_base + (addr >> 3); + CPUState *cpu = qemu_get_cpu(hartid); + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; + if (!env) { + error_report("aclint-mtimer: invalid hartid: %zu", hartid); + } else if ((addr & 0x7) == 0) { + /* timecmp_lo */ + uint64_t timecmp_hi = env->timecmp >> 32; + riscv_aclint_mtimer_write_timecmp(RISCV_CPU(cpu), + timecmp_hi << 32 | (value & 0xFFFFFFFF), + mtimer->timebase_freq); + return; + } else if ((addr & 0x7) == 4) { + /* timecmp_hi */ + uint64_t timecmp_lo = env->timecmp; + riscv_aclint_mtimer_write_timecmp(RISCV_CPU(cpu), + value << 32 | (timecmp_lo & 0xFFFFFFFF), + mtimer->timebase_freq); + } else { + error_report("aclint-mtimer: invalid timecmp write: %08x", + (uint32_t)addr); + } + return; + } else if (addr == (mtimer->aperture_size - 8)) { + /* time_lo */ + error_report("aclint-mtimer: time_lo write not implemented"); + return; + } else if (addr == (mtimer->aperture_size - 4)) { + /* time_hi */ + error_report("aclint-mtimer: time_hi write not implemented"); + return; + } + + error_report("aclint-mtimer: invalid write: %08x", (uint32_t)addr); +} + +static const MemoryRegionOps riscv_aclint_mtimer_ops = { + .read = riscv_aclint_mtimer_read, + .write = riscv_aclint_mtimer_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8 + } +}; + +static Property riscv_aclint_mtimer_properties[] = { + DEFINE_PROP_UINT32("hartid-base", RISCVAclintMTimerState, + hartid_base, 0), + DEFINE_PROP_UINT32("num-harts", RISCVAclintMTimerState, num_harts, 0), + DEFINE_PROP_UINT32("aperture-size", RISCVAclintMTimerState, + aperture_size, 0), + DEFINE_PROP_UINT32("timebase-freq", RISCVAclintMTimerState, + timebase_freq, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) +{ + int i; + RISCVCPU *cpu; + RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev); + + memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_aclint_mtimer_ops, s, + TYPE_RISCV_ACLINT_MTIMER, s->aperture_size); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); + + /* Claim MTIP so that only MTIMER controls it. */ + for (i = 0; i < s->num_harts; i++) { + cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); + if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) { + error_report("MTIP already claimed"); + exit(1); + } + } +} + +static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = riscv_aclint_mtimer_realize; + device_class_set_props(dc, riscv_aclint_mtimer_properties); +} + +static const TypeInfo riscv_aclint_mtimer_info = { + .name = TYPE_RISCV_ACLINT_MTIMER, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(RISCVAclintMTimerState), + .class_init = riscv_aclint_mtimer_class_init, +}; + +/* + * Create ACLINT MTIMER device. + */ +DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, + uint32_t hartid_base, uint32_t num_harts, uint32_t timebase_freq, + bool provide_rdtime) +{ + int i; + for (i = 0; i < num_harts; i++) { + CPUState *cpu = qemu_get_cpu(hartid_base + i); + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; + if (!env) { + continue; + } + if (provide_rdtime) { + riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq); + } + env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + &riscv_aclint_mtimer_cb, cpu); + env->timecmp = 0; + } + + DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER); + qdev_prop_set_uint32(dev, "hartid-base", hartid_base); + qdev_prop_set_uint32(dev, "num-harts", num_harts); + qdev_prop_set_uint32(dev, "aperture-size", size); + qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); + return dev; +} + +/* CPU read [M|S]SWI register */ +static uint64_t riscv_aclint_swi_read(void *opaque, hwaddr addr, + unsigned size) +{ + RISCVAclintSwiState *swi = opaque; + + if (addr < (swi->num_harts << 2)) { + size_t hartid = swi->hartid_base + (addr >> 2); + CPUState *cpu = qemu_get_cpu(hartid); + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; + if (!env) { + error_report("aclint-swi: invalid hartid: %zu", hartid); + } else if ((addr & 0x3) == 0) { + return (env->mip & swi->sirq_mask) > 0; + } else { + error_report("aclint-swi: invalid read: %08x", (uint32_t)addr); + return 0; + } + } + + error_report("aclint-swi: invalid read: %08x", (uint32_t)addr); + return 0; +} + +/* CPU wrote [M|S]SWI register */ +static void riscv_aclint_swi_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + RISCVAclintSwiState *swi = opaque; + + if (addr < (swi->num_harts << 2)) { + size_t hartid = swi->hartid_base + (addr >> 2); + CPUState *cpu = qemu_get_cpu(hartid); + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; + if (!env) { + error_report("aclint-swi: invalid hartid: %zu", hartid); + } else if ((addr & 0x3) == 0) { + riscv_cpu_update_mip(RISCV_CPU(cpu), swi->sirq_mask, + BOOL_TO_MASK(value)); + } else { + error_report("aclint-swi: invalid [M|S]SIP write: %08x", + (uint32_t)addr); + } + return; + } + + error_report("aclint-swi: invalid write: %08x", (uint32_t)addr); +} + +static const MemoryRegionOps riscv_aclint_swi_ops = { + .read = riscv_aclint_swi_read, + .write = riscv_aclint_swi_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } +}; + +static Property riscv_aclint_swi_properties[] = { + DEFINE_PROP_UINT32("hartid-base", RISCVAclintSwiState, hartid_base, 0), + DEFINE_PROP_UINT32("num-harts", RISCVAclintSwiState, num_harts, 0), + DEFINE_PROP_UINT32("aperture-size", RISCVAclintSwiState, + aperture_size, 0), + DEFINE_PROP_UINT32("sirq-mask", RISCVAclintSwiState, sirq_mask, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp) +{ + int i; + RISCVCPU *cpu; + RISCVAclintSwiState *s = RISCV_ACLINT_SWI(dev); + + memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_aclint_swi_ops, s, + TYPE_RISCV_ACLINT_SWI, s->aperture_size); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); + + /* Claim [M|S]SIP so that can SWI controls it. */ + for (i = 0; i < s->num_harts; i++) { + cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); + + /* We don't claim SSIP bit of mip CSR because this bit is + * writable by software as-per RISC-V privilege specification. + */ + if ((s->sirq_mask != MIP_SSIP) && + riscv_cpu_claim_interrupts(cpu, s->sirq_mask) < 0) { + error_report("%s already claimed", + (s->sirq_mask == MIP_SSIP) ? "SSIP" : "MSIP"); + exit(1); + } + } +} + +static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = riscv_aclint_swi_realize; + device_class_set_props(dc, riscv_aclint_swi_properties); +} + +static const TypeInfo riscv_aclint_swi_info = { + .name = TYPE_RISCV_ACLINT_SWI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(RISCVAclintSwiState), + .class_init = riscv_aclint_swi_class_init, +}; + +/* + * Create ACLINT [M|S]SWI device. + */ +DeviceState *riscv_aclint_swi_create(hwaddr addr, hwaddr size, + uint32_t hartid_base, uint32_t num_harts, bool smode_swi) +{ + DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_SWI); + qdev_prop_set_uint32(dev, "hartid-base", hartid_base); + qdev_prop_set_uint32(dev, "num-harts", num_harts); + qdev_prop_set_uint32(dev, "aperture-size", size); + qdev_prop_set_uint32(dev, "sirq-mask", smode_swi ? MIP_SSIP : MIP_MSIP); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); + return dev; +} + +static void riscv_aclint_register_types(void) +{ + type_register_static(&riscv_aclint_mtimer_info); + type_register_static(&riscv_aclint_swi_info); +} + +type_init(riscv_aclint_register_types) diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c deleted file mode 100644 index 0f41e5ea1c..0000000000 --- a/hw/intc/sifive_clint.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * SiFive CLINT (Core Local Interruptor) - * - * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu - * Copyright (c) 2017 SiFive, Inc. - * - * This provides real-time clock, timer and interprocessor interrupts. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2 or later, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "hw/sysbus.h" -#include "target/riscv/cpu.h" -#include "hw/qdev-properties.h" -#include "hw/intc/sifive_clint.h" -#include "qemu/timer.h" - -static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq) -{ - return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - timebase_freq, NANOSECONDS_PER_SECOND); -} - -/* - * Called when timecmp is written to update the QEMU timer or immediately - * trigger timer interrupt if mtimecmp <= current timer value. - */ -static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value, - uint32_t timebase_freq) -{ - uint64_t next; - uint64_t diff; - - uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq); - - cpu->env.timecmp = value; - if (cpu->env.timecmp <= rtc_r) { - /* if we're setting an MTIMECMP value in the "past", - immediately raise the timer interrupt */ - riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1)); - return; - } - - /* otherwise, set up the future timer interrupt */ - riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0)); - diff = cpu->env.timecmp - rtc_r; - /* back to ns (note args switched in muldiv64) */ - next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); - timer_mod(cpu->env.timer, next); -} - -/* - * Callback used when the timer set using timer_mod expires. - * Should raise the timer interrupt line - */ -static void sifive_clint_timer_cb(void *opaque) -{ - RISCVCPU *cpu = opaque; - riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1)); -} - -/* CPU wants to read rtc or timecmp register */ -static uint64_t sifive_clint_read(void *opaque, hwaddr addr, unsigned size) -{ - SiFiveCLINTState *clint = opaque; - if (addr >= clint->sip_base && - addr < clint->sip_base + (clint->num_harts << 2)) { - size_t hartid = clint->hartid_base + ((addr - clint->sip_base) >> 2); - CPUState *cpu = qemu_get_cpu(hartid); - CPURISCVState *env = cpu ? cpu->env_ptr : NULL; - if (!env) { - error_report("clint: invalid timecmp hartid: %zu", hartid); - } else if ((addr & 0x3) == 0) { - return (env->mip & MIP_MSIP) > 0; - } else { - error_report("clint: invalid read: %08x", (uint32_t)addr); - return 0; - } - } else if (addr >= clint->timecmp_base && - addr < clint->timecmp_base + (clint->num_harts << 3)) { - size_t hartid = clint->hartid_base + - ((addr - clint->timecmp_base) >> 3); - CPUState *cpu = qemu_get_cpu(hartid); - CPURISCVState *env = cpu ? cpu->env_ptr : NULL; - if (!env) { - error_report("clint: invalid timecmp hartid: %zu", hartid); - } else if ((addr & 0x7) == 0) { - /* timecmp_lo */ - uint64_t timecmp = env->timecmp; - return timecmp & 0xFFFFFFFF; - } else if ((addr & 0x7) == 4) { - /* timecmp_hi */ - uint64_t timecmp = env->timecmp; - return (timecmp >> 32) & 0xFFFFFFFF; - } else { - error_report("clint: invalid read: %08x", (uint32_t)addr); - return 0; - } - } else if (addr == clint->time_base) { - /* time_lo */ - return cpu_riscv_read_rtc(clint->timebase_freq) & 0xFFFFFFFF; - } else if (addr == clint->time_base + 4) { - /* time_hi */ - return (cpu_riscv_read_rtc(clint->timebase_freq) >> 32) & 0xFFFFFFFF; - } - - error_report("clint: invalid read: %08x", (uint32_t)addr); - return 0; -} - -/* CPU wrote to rtc or timecmp register */ -static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - SiFiveCLINTState *clint = opaque; - - if (addr >= clint->sip_base && - addr < clint->sip_base + (clint->num_harts << 2)) { - size_t hartid = clint->hartid_base + ((addr - clint->sip_base) >> 2); - CPUState *cpu = qemu_get_cpu(hartid); - CPURISCVState *env = cpu ? cpu->env_ptr : NULL; - if (!env) { - error_report("clint: invalid timecmp hartid: %zu", hartid); - } else if ((addr & 0x3) == 0) { - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value)); - } else { - error_report("clint: invalid sip write: %08x", (uint32_t)addr); - } - return; - } else if (addr >= clint->timecmp_base && - addr < clint->timecmp_base + (clint->num_harts << 3)) { - size_t hartid = clint->hartid_base + - ((addr - clint->timecmp_base) >> 3); - CPUState *cpu = qemu_get_cpu(hartid); - CPURISCVState *env = cpu ? cpu->env_ptr : NULL; - if (!env) { - error_report("clint: invalid timecmp hartid: %zu", hartid); - } else if ((addr & 0x7) == 0) { - /* timecmp_lo */ - uint64_t timecmp_hi = env->timecmp >> 32; - sifive_clint_write_timecmp(RISCV_CPU(cpu), - timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq); - return; - } else if ((addr & 0x7) == 4) { - /* timecmp_hi */ - uint64_t timecmp_lo = env->timecmp; - sifive_clint_write_timecmp(RISCV_CPU(cpu), - value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq); - } else { - error_report("clint: invalid timecmp write: %08x", (uint32_t)addr); - } - return; - } else if (addr == clint->time_base) { - /* time_lo */ - error_report("clint: time_lo write not implemented"); - return; - } else if (addr == clint->time_base + 4) { - /* time_hi */ - error_report("clint: time_hi write not implemented"); - return; - } - - error_report("clint: invalid write: %08x", (uint32_t)addr); -} - -static const MemoryRegionOps sifive_clint_ops = { - .read = sifive_clint_read, - .write = sifive_clint_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 8 - } -}; - -static Property sifive_clint_properties[] = { - DEFINE_PROP_UINT32("hartid-base", SiFiveCLINTState, hartid_base, 0), - DEFINE_PROP_UINT32("num-harts", SiFiveCLINTState, num_harts, 0), - DEFINE_PROP_UINT32("sip-base", SiFiveCLINTState, sip_base, 0), - DEFINE_PROP_UINT32("timecmp-base", SiFiveCLINTState, timecmp_base, 0), - DEFINE_PROP_UINT32("time-base", SiFiveCLINTState, time_base, 0), - DEFINE_PROP_UINT32("aperture-size", SiFiveCLINTState, aperture_size, 0), - DEFINE_PROP_UINT32("timebase-freq", SiFiveCLINTState, timebase_freq, 0), - DEFINE_PROP_END_OF_LIST(), -}; - -static void sifive_clint_realize(DeviceState *dev, Error **errp) -{ - SiFiveCLINTState *s = SIFIVE_CLINT(dev); - memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s, - TYPE_SIFIVE_CLINT, s->aperture_size); - sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); -} - -static void sifive_clint_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - dc->realize = sifive_clint_realize; - device_class_set_props(dc, sifive_clint_properties); -} - -static const TypeInfo sifive_clint_info = { - .name = TYPE_SIFIVE_CLINT, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SiFiveCLINTState), - .class_init = sifive_clint_class_init, -}; - -static void sifive_clint_register_types(void) -{ - type_register_static(&sifive_clint_info); -} - -type_init(sifive_clint_register_types) - - -/* - * Create CLINT device. - */ -DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, - uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base, - uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq, - bool provide_rdtime) -{ - int i; - for (i = 0; i < num_harts; i++) { - CPUState *cpu = qemu_get_cpu(hartid_base + i); - CPURISCVState *env = cpu ? cpu->env_ptr : NULL; - if (!env) { - continue; - } - if (provide_rdtime) { - riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq); - } - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - &sifive_clint_timer_cb, cpu); - env->timecmp = 0; - } - - DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT); - qdev_prop_set_uint32(dev, "hartid-base", hartid_base); - qdev_prop_set_uint32(dev, "num-harts", num_harts); - qdev_prop_set_uint32(dev, "sip-base", sip_base); - qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base); - qdev_prop_set_uint32(dev, "time-base", time_base); - qdev_prop_set_uint32(dev, "aperture-size", size); - qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); - return dev; -} diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 1de18cdcf1..939cd0ef40 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -9,7 +9,7 @@ config MICROCHIP_PFSOC select MCHP_PFSOC_MMUART select MCHP_PFSOC_SYSREG select MSI_NONBROKEN - select SIFIVE_CLINT + select RISCV_ACLINT select SIFIVE_PDMA select SIFIVE_PLIC select UNIMP @@ -29,7 +29,7 @@ config RISCV_VIRT select PCI_EXPRESS_GENERIC_BRIDGE select PFLASH_CFI01 select SERIAL - select SIFIVE_CLINT + select RISCV_ACLINT select SIFIVE_PLIC select SIFIVE_TEST select VIRTIO_MMIO @@ -38,7 +38,7 @@ config RISCV_VIRT config SIFIVE_E bool select MSI_NONBROKEN - select SIFIVE_CLINT + select RISCV_ACLINT select SIFIVE_GPIO select SIFIVE_PLIC select SIFIVE_UART @@ -49,7 +49,7 @@ config SIFIVE_U bool select CADENCE select MSI_NONBROKEN - select SIFIVE_CLINT + select RISCV_ACLINT select SIFIVE_GPIO select SIFIVE_PDMA select SIFIVE_PLIC @@ -65,5 +65,5 @@ config SPIKE bool select HTIF select MSI_NONBROKEN - select SIFIVE_CLINT + select RISCV_ACLINT select SIFIVE_PLIC diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index c4146b7a6b..e637e5c885 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -51,7 +51,7 @@ #include "hw/riscv/boot.h" #include "hw/riscv/riscv_hart.h" #include "hw/riscv/microchip_pfsoc.h" -#include "hw/intc/sifive_clint.h" +#include "hw/intc/riscv_aclint.h" #include "hw/intc/sifive_plic.h" #include "sysemu/sysemu.h" @@ -235,10 +235,12 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) memmap[MICROCHIP_PFSOC_BUSERR_UNIT4].size); /* CLINT */ - sifive_clint_create(memmap[MICROCHIP_PFSOC_CLINT].base, - memmap[MICROCHIP_PFSOC_CLINT].size, 0, ms->smp.cpus, - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, - CLINT_TIMEBASE_FREQ, false); + riscv_aclint_swi_create(memmap[MICROCHIP_PFSOC_CLINT].base, + RISCV_ACLINT_SWI_SIZE, 0, ms->smp.cpus, false); + riscv_aclint_mtimer_create( + memmap[MICROCHIP_PFSOC_CLINT].base + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_MTIMER_SIZE, 0, ms->smp.cpus, + RISCV_ACLINT_TIMEBASE_FREQ, false); /* L2 cache controller */ create_unimplemented_device("microchip.pfsoc.l2cc", diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index f939bcf9ea..ea960a5f2e 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -42,7 +42,7 @@ #include "hw/riscv/sifive_e.h" #include "hw/riscv/boot.h" #include "hw/char/sifive_uart.h" -#include "hw/intc/sifive_clint.h" +#include "hw/intc/riscv_aclint.h" #include "hw/intc/sifive_plic.h" #include "hw/misc/sifive_e_prci.h" #include "chardev/char.h" @@ -210,10 +210,12 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp) SIFIVE_E_PLIC_CONTEXT_BASE, SIFIVE_E_PLIC_CONTEXT_STRIDE, memmap[SIFIVE_E_DEV_PLIC].size); - sifive_clint_create(memmap[SIFIVE_E_DEV_CLINT].base, - memmap[SIFIVE_E_DEV_CLINT].size, 0, ms->smp.cpus, - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, - SIFIVE_CLINT_TIMEBASE_FREQ, false); + riscv_aclint_swi_create(memmap[SIFIVE_E_DEV_CLINT].base, + RISCV_ACLINT_SWI_SIZE, 0, ms->smp.cpus, false); + riscv_aclint_mtimer_create(memmap[SIFIVE_E_DEV_CLINT].base + + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_MTIMER_SIZE, 0, ms->smp.cpus, + RISCV_ACLINT_TIMEBASE_FREQ, false); create_unimplemented_device("riscv.sifive.e.aon", memmap[SIFIVE_E_DEV_AON].base, memmap[SIFIVE_E_DEV_AON].size); sifive_e_prci_create(memmap[SIFIVE_E_DEV_PRCI].base); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 7b59942369..e5fe681984 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -52,7 +52,7 @@ #include "hw/riscv/sifive_u.h" #include "hw/riscv/boot.h" #include "hw/char/sifive_uart.h" -#include "hw/intc/sifive_clint.h" +#include "hw/intc/riscv_aclint.h" #include "hw/intc/sifive_plic.h" #include "chardev/char.h" #include "net/eth.h" @@ -160,7 +160,7 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, qemu_fdt_add_subnode(fdt, "/cpus"); qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", - SIFIVE_CLINT_TIMEBASE_FREQ); + RISCV_ACLINT_TIMEBASE_FREQ); qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); @@ -839,10 +839,12 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp) serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART0_IRQ)); sifive_uart_create(system_memory, memmap[SIFIVE_U_DEV_UART1].base, serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ)); - sifive_clint_create(memmap[SIFIVE_U_DEV_CLINT].base, - memmap[SIFIVE_U_DEV_CLINT].size, 0, ms->smp.cpus, - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, - SIFIVE_CLINT_TIMEBASE_FREQ, false); + riscv_aclint_swi_create(memmap[SIFIVE_U_DEV_CLINT].base, + RISCV_ACLINT_SWI_SIZE, 0, ms->smp.cpus, false); + riscv_aclint_mtimer_create(memmap[SIFIVE_U_DEV_CLINT].base + + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_MTIMER_SIZE, 0, ms->smp.cpus, + RISCV_ACLINT_TIMEBASE_FREQ, false); if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) { return; diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index ec7cb2f707..10681fbf99 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -36,7 +36,7 @@ #include "hw/riscv/boot.h" #include "hw/riscv/numa.h" #include "hw/char/riscv_htif.h" -#include "hw/intc/sifive_clint.h" +#include "hw/intc/riscv_aclint.h" #include "chardev/char.h" #include "sysemu/arch_init.h" #include "sysemu/device_tree.h" @@ -83,7 +83,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap, qemu_fdt_add_subnode(fdt, "/cpus"); qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", - SIFIVE_CLINT_TIMEBASE_FREQ); + RISCV_ACLINT_TIMEBASE_FREQ); qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); qemu_fdt_add_subnode(fdt, "/cpus/cpu-map"); @@ -225,11 +225,14 @@ static void spike_board_init(MachineState *machine) sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort); /* Core Local Interruptor (timer and IPI) for each socket */ - sifive_clint_create( + riscv_aclint_swi_create( memmap[SPIKE_CLINT].base + i * memmap[SPIKE_CLINT].size, - memmap[SPIKE_CLINT].size, base_hartid, hart_count, - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, - SIFIVE_CLINT_TIMEBASE_FREQ, false); + RISCV_ACLINT_SWI_SIZE, base_hartid, hart_count, false); + riscv_aclint_mtimer_create( + memmap[SPIKE_CLINT].base + i * memmap[SPIKE_CLINT].size + + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_MTIMER_SIZE, base_hartid, hart_count, + RISCV_ACLINT_TIMEBASE_FREQ, false); } /* register system main memory (actual RAM) */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index c0dc69ff33..5eb63f6efd 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -33,7 +33,7 @@ #include "hw/riscv/virt.h" #include "hw/riscv/boot.h" #include "hw/riscv/numa.h" -#include "hw/intc/sifive_clint.h" +#include "hw/intc/riscv_aclint.h" #include "hw/intc/sifive_plic.h" #include "hw/misc/sifive_test.h" #include "chardev/char.h" @@ -224,7 +224,7 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_add_subnode(fdt, "/cpus"); qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", - SIFIVE_CLINT_TIMEBASE_FREQ); + RISCV_ACLINT_TIMEBASE_FREQ); qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); qemu_fdt_add_subnode(fdt, "/cpus/cpu-map"); @@ -587,11 +587,14 @@ static void virt_machine_init(MachineState *machine) sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort); /* Per-socket CLINT */ - sifive_clint_create( + riscv_aclint_swi_create( memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size, - memmap[VIRT_CLINT].size, base_hartid, hart_count, - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, - SIFIVE_CLINT_TIMEBASE_FREQ, true); + RISCV_ACLINT_SWI_SIZE, base_hartid, hart_count, false); + riscv_aclint_mtimer_create( + memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size + + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_MTIMER_SIZE, base_hartid, hart_count, + RISCV_ACLINT_TIMEBASE_FREQ, true); /* Per-socket PLIC hart topology configuration string */ plic_hart_config_len = diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h new file mode 100644 index 0000000000..471a5ffd0b --- /dev/null +++ b/include/hw/intc/riscv_aclint.h @@ -0,0 +1,73 @@ +/* + * RISC-V ACLINT (Advanced Core Local Interruptor) interface + * + * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu + * Copyright (c) 2017 SiFive, Inc. + * Copyright (c) 2021 Western Digital Corporation or its affiliates. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef HW_RISCV_ACLINT_H +#define HW_RISCV_ACLINT_H + +#include "hw/sysbus.h" + +#define TYPE_RISCV_ACLINT_MTIMER "riscv.aclint.mtimer" + +#define RISCV_ACLINT_MTIMER(obj) \ + OBJECT_CHECK(RISCVAclintMTimerState, (obj), TYPE_RISCV_ACLINT_MTIMER) + +typedef struct RISCVAclintMTimerState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + uint32_t hartid_base; + uint32_t num_harts; + uint32_t aperture_size; + uint32_t timebase_freq; +} RISCVAclintMTimerState; + +DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, + uint32_t hartid_base, uint32_t num_harts, uint32_t timebase_freq, + bool provide_rdtime); + +#define TYPE_RISCV_ACLINT_SWI "riscv.aclint.swi" + +#define RISCV_ACLINT_SWI(obj) \ + OBJECT_CHECK(RISCVAclintSwiState, (obj), TYPE_RISCV_ACLINT_SWI) + +typedef struct RISCVAclintSwiState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + uint32_t hartid_base; + uint32_t num_harts; + uint32_t aperture_size; + uint32_t sirq_mask; +} RISCVAclintSwiState; + +DeviceState *riscv_aclint_swi_create(hwaddr addr, hwaddr size, + uint32_t hartid_base, uint32_t num_harts, bool smode_swi); + +enum { + RISCV_ACLINT_MTIMER_SIZE = 0x8000, + RISCV_ACLINT_TIMEBASE_FREQ = 10000000, + RISCV_ACLINT_SWI_SIZE = 0x4000 +}; + +#endif diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h deleted file mode 100644 index a30be0f3d6..0000000000 --- a/include/hw/intc/sifive_clint.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SiFive CLINT (Core Local Interruptor) interface - * - * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu - * Copyright (c) 2017 SiFive, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2 or later, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#ifndef HW_SIFIVE_CLINT_H -#define HW_SIFIVE_CLINT_H - -#include "hw/sysbus.h" - -#define TYPE_SIFIVE_CLINT "riscv.sifive.clint" - -#define SIFIVE_CLINT(obj) \ - OBJECT_CHECK(SiFiveCLINTState, (obj), TYPE_SIFIVE_CLINT) - -typedef struct SiFiveCLINTState { - /*< private >*/ - SysBusDevice parent_obj; - - /*< public >*/ - MemoryRegion mmio; - uint32_t hartid_base; - uint32_t num_harts; - uint32_t sip_base; - uint32_t timecmp_base; - uint32_t time_base; - uint32_t aperture_size; - uint32_t timebase_freq; -} SiFiveCLINTState; - -DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, - uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base, - uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq, - bool provide_rdtime); - -enum { - SIFIVE_SIP_BASE = 0x0, - SIFIVE_TIMECMP_BASE = 0x4000, - SIFIVE_TIME_BASE = 0xBFF8 -}; - -enum { - SIFIVE_CLINT_TIMEBASE_FREQ = 10000000 -}; - -#endif From patchwork Sat Jun 12 16:06:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12317185 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D64EC48BCF for ; Sat, 12 Jun 2021 16:14:38 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D0267613BF for ; Sat, 12 Jun 2021 16:14:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D0267613BF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34744 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ls6HN-0002TE-06 for qemu-devel@archiver.kernel.org; Sat, 12 Jun 2021 12:14:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59990) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ls69t-0002jn-Fp; Sat, 12 Jun 2021 12:06:53 -0400 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:45081) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ls69o-0002Kn-Mm; Sat, 12 Jun 2021 12:06:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1623514008; x=1655050008; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=lk3Ws4ysTXjixFJQXpwsxjyVtY8KYkjCwTGKdZyECSc=; b=BFFAapg74GonVLZJWXa7iFv/EtGohAEEudUNcMsjw9ypISMGAueiDnN6 OqEZF6EABlbEqYsOAO93zdjfk0IZhSdmG9r6PNc0LRsTrUsf+tCvLnQVv 4Ya39C/2vpycpQXQKUOBEjJbziAHNMgNbrGPNbw6QscjzlsgtL+HTvl42 vhwfba8ZmeZVgjlokpUnTmTB0lMU7zLS1WeXdZNIVkH+d1M+PeWqbqvJp 0nphUVXMn4i8NB2a0ziB0R0Thva1jpPw4KWhjb3SFNnnsF/K5hGe+g9eH XH//sJT2SrJxjklRQjfGQnpzgYlZe8QD9iLr/DUwjcA4mHOai9sqZ3mhs Q==; IronPort-SDR: 5YmtLKGm951QumsrpU839camZuTXMj71+63dIGIIZjsLlxKjAxrVMoyx4ZmKzObw9b8JGfFR+B veA0xHQUixOK/5Tm79w4K5vSqh8kFhoqQ+EYwDpPGElarC391Cy+MDYY0SPdJpXGmX6tR0TZ1r 2u3AGQZLiW+v5Uie+YMMMkARa86JghA2qcszHZ1TkxJKYJDi0wYkJBAMmp5+PqJC0iwL0ZQePz 7IJwc+1psM/ZtkhpDla4At6qAqUFmanCtiDul1TeO1AAMf9WA8K0vtagGzgiSEpDOAABWxy7qb Cxo= X-IronPort-AV: E=Sophos;i="5.83,268,1616428800"; d="scan'208";a="171704749" Received: from mail-bn8nam12lp2168.outbound.protection.outlook.com (HELO NAM12-BN8-obe.outbound.protection.outlook.com) ([104.47.55.168]) by ob1.hgst.iphmx.com with ESMTP; 13 Jun 2021 00:06:44 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AKb3AVxi6M7LL/mawM6B0VGp0jnoerdt1WmtTl0Q3J16tDdC4pZ9JkXgiEGR/iDEkSNkz7AmfYFBHVE5Z4REGJAeY0FPealYRa7CVWo6Qp0jieB/erMec8RT7LAAoZQ7gkppefQRcnFjD2yEqgrOirckJneF9DGGic2mxSQAAx15MefCFUh8mZ/fZSN72Ha5amDmUnICARbZTNSRY4xu14RjWsGaezjeCQTOiz+HdXdxtCLLw2xyAetHXF2qR0O8/GdmqqdHAz3W4SuDMxmg2DkCVPkkgXYE+XSw2rZ03hPnOysOeZ6XqiXf7FAT10xV767kaGL7isOYB4FgGfMbDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VRaUtYnHXMIsCuwMxUw7v/8INEqzPmljHB4ZZq87KSw=; b=JxuwWCSyvIfBt9MO5FuP5LnXhAgkPfLRaZRnjjL/wQHtN4N1t3mBoWll77SCkl8LdaYJnXu3qfzPvW+tCQG978gFAID/eKUKJK3GTiP+suuaK78z3KzpnlIun0aqhpcLHZuHM2Svevt5rbCdMsb+TmCTklNQayQtqVg8OWO45zbsv8FRg/jOPok0N4nbTXXiUozsNxTpYzusUqgY8fJZKVO4dgmeW86CJ6YDvIk4tIZ9t+cS9knDhlYVhGTi5fMoUF1RsHnUzFjS3vI8hFR4fy7c/PyFkkvv7gw7fnpNPNmwNqF6gx51Qrj7YmR1MnKgRaO02xrYGKppTIzJntk31A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VRaUtYnHXMIsCuwMxUw7v/8INEqzPmljHB4ZZq87KSw=; b=ewPT9IsLYblHeU2z2oiEnjh2SvAYCbjZIupcnsxAxsYz7doCMs5mEDnipoBL5Mg2cypuzxHECzfUxg9BwTNFgNnOHzlwyRzzlrD9XfIGwZQ17bWGtGISmsTdl1ny2FT5HwgW8B5q0EJhQxmVoBMgbmlO4Df4rRqF6i2VRgayQ7E= Authentication-Results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7747.namprd04.prod.outlook.com (2603:10b6:5:35b::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.22; Sat, 12 Jun 2021 16:06:44 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::a153:b7f8:c87f:89f8]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::a153:b7f8:c87f:89f8%9]) with mapi id 15.20.4219.025; Sat, 12 Jun 2021 16:06:44 +0000 From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v1 2/3] hw/riscv: virt: Re-factor FDT generation Date: Sat, 12 Jun 2021 21:36:14 +0530 Message-Id: <20210612160615.330768-3-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210612160615.330768-1-anup.patel@wdc.com> References: <20210612160615.330768-1-anup.patel@wdc.com> X-Originating-IP: [122.171.171.205] X-ClientProxiedBy: MA1PR01CA0172.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::16) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from wdc.com (122.171.171.205) by MA1PR01CA0172.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.21 via Frontend Transport; Sat, 12 Jun 2021 16:06:40 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 092d6be0-9eee-46af-6d44-08d92dbc1287 X-MS-TrafficTypeDiagnostic: CO6PR04MB7747: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:353; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: W8YGZFyxd0btKM2lsYFcjoxsvxJp+LVgg9aIrT7fpW/oSHmlpc0yIaUKJvk9jzxnMFf5qORSQAdKHrjNS07UK4CsD5eKJKcfK2tL77gpIUEnZx5Q/D0XKp9VocYyStRMmQ1CHuzQmgT8Ygs1gPUAFsR/qieLIZ6cg6uTVeTLRhF7OLQpEuejOebVkL7g4KPBqD2caZEgHWhLDevSOUhHJk/YRJn42CtTyVCZ+CR5NtZJ4XDFnZFChzH1l/HaNq+ujEAeLHNR6NggYHbCmiNS5jPlYSe10JrojeBLlyLLM8uGZ/mq/IKOmW6uJ+SqhfVh4l5gSWJy80/QaS1tJQJgWqeGrnuowjxp4G1AFm2eiyfWhitEtRQ447n0bqW9i1wNhxJYiTSP0++bM6t8LwaPChABnmNmVSCKnc1vRPr1N5VSP29/QSPRXXWLTEkIjDypMcSosFIkqplXjmOUHJdKlp/5GC91HHon+g5rlRHwuOf8gpQO8tVHcv2XAigqDu4JkQxIca1hq87pvAARetHo37V7XVkrgQuiTufKJVHr7wQkov8sJLxfS6iBZHvmswXzw4HnnbQQ5LvnBM1XZqtHySQj39lNppCiGtDHJHRseVoIhjD/E8V+NNKtT9X5S8Hd20fBNFuxESDq8Xx6+Z/txg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CO6PR04MB7812.namprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(396003)(136003)(366004)(346002)(39860400002)(54906003)(8936002)(8676002)(110136005)(4326008)(2616005)(44832011)(16526019)(186003)(66476007)(66556008)(66946007)(2906002)(956004)(316002)(38350700002)(86362001)(38100700002)(55016002)(30864003)(26005)(7696005)(8886007)(36756003)(52116002)(6666004)(83380400001)(1076003)(478600001)(5660300002); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: buyif0Af5q86EdwlpxTDBCxuoWSCsYowCyfrWmMUg6A2f1EdZfotN6NP9bZP+tQNHbIwC62taUTAVjzNGY8SU30TDjB5pQVrPK4SyDXvyAlsWM019EKCvLKBOHPngIUOlgm6mTRCwEGsK73aI211y2kG5EI+ejo26kfOlksHLzxWd7nySXmvK3ieOR9qQI35wGMBBWWP0QNr7XLkxQ8fkJ2qTYUUd56zve/R9+hxLqQ36CW2tOJyxNFt+FobS4oTZrSOs+Xz0Hke6TkrlYVy2ao3vOcAnvbrQm1dcunbRa6JQiTIMpLnwC9dVyCsTZBcU0ydRdrElRo34gO/wUIsvpPygQZcC9iOtuLQMfqzbQFXdj57Qns0Fv/qntX6plhBajnjcqvE3WjoerktkAOINB2jwJ+JEshtN14a64aNN6H/I36V3/cQXsP+lVHgtfMHKOhNyEuLXC3aQLQ6EKCLwMa10pIFEGkk75PrJKajh0StmsLEMt8TGHg835RjEw2JvJ0u3q5opudKHPk2fMXjPKOvws6397CD6FqdymGfR22DP+1egv/4Ou6sPldT5y5z7PKDO36Lgx5LiMM5ptME0f/MAlhO9dTN1CtKfryWLEPTdWhbZcq+N/bnch/E4F1XYthp75JKsdEyewevfqgLxKvLRFBVknTRtpfUxOl0wkvtK/8J2fSCITzpIcslc0t3keJLvoBZxHbwEEeU4XA7yIt0GJk37Kg03O1eY4fLGhruTUn7E55KMWo/JtjXBPFxCproFm/13oxTwQf1DzB8wtLLd/XGOBSLnVpOjP0bHbSQ/s42lzo4ACLLXSW5DwZnCXWrWTBOMQkdLuWzHnPWTL7UqJ8r9OEBX+qWTQzy8a6GeYAhwqn7ra72vbCNnhsAsgyYB5r8qQJ5PYVYztT0AGKTChlpQvW84X4XUXDnkRBhWibK4rC2nhPwOnY/YJNk6nBrxnl4bac5FcrXmSerdBFKtRenlIC3u8jMP4JbAiXaP1GGdrM8mI3DuYQW5qeu/zMsBD2/96PdSKbwMzafqgTZyp+1FPCBhgDdVdiE6cqv9uHSktF4dkcOWq8dNLo203TaWi5tzmjXsMYlA6iQFj9bHn53SDVITRehnlB5KkpNKypxtSTIbHbXDcPfXjUf7Wodv3htqwr4y1bUhU21+xJ/QhlIf/JdFDFpz7Ci+J6wpoGFOO62MButHin4lWMpNocCKEWhEt01dcG/tF8uo4k6oEb2mH7PdKQ66WsaysU7IidtUoOfIeIHaYSEYT110yBtJcK9V5PhZix3noWNzZHBm//l//LIMeZg9R3K10CEEkQ1PtpC2jjFkXpzDgOi X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 092d6be0-9eee-46af-6d44-08d92dbc1287 X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2021 16:06:43.9952 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: FJ2czKD+G3qpORE2OxdP46vxhqIsmiInsRcWPugKAWcG3Quoq8gPg2S4hi6Lg/AB2Xg9M2th1kMwahAJo9Eftg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7747 Received-SPF: pass client-ip=216.71.153.144; envelope-from=prvs=790f0be0c=Anup.Patel@wdc.com; helo=esa5.hgst.iphmx.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, MSGID_FROM_MTA_HEADER=0.001, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Atish Patra , Anup Patel , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Anup Patel Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We re-factor and break the FDT generation into smaller functions so that it is easier to modify FDT generation for different configurations of virt machine. Signed-off-by: Anup Patel --- hw/riscv/virt.c | 514 ++++++++++++++++++++++++++++++------------------ 1 file changed, 320 insertions(+), 194 deletions(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 5eb63f6efd..977d699753 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -178,206 +178,253 @@ static void create_pcie_irq_map(void *fdt, char *nodename, 0x1800, 0, 0, 0x7); } -static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, - uint64_t mem_size, const char *cmdline, bool is_32_bit) +static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, + char *clust_name, uint32_t *phandle, + bool is_32_bit, uint32_t *intc_phandles) { - void *fdt; - int i, cpu, socket; + int cpu; + uint32_t cpu_phandle; MachineState *mc = MACHINE(s); + char *name, *cpu_name, *core_name, *intc_name; + + for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) { + cpu_phandle = (*phandle)++; + + cpu_name = g_strdup_printf("/cpus/cpu@%d", + s->soc[socket].hartid_base + cpu); + qemu_fdt_add_subnode(mc->fdt, cpu_name); + qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type", + (is_32_bit) ? "riscv,sv32" : "riscv,sv48"); + name = riscv_isa_string(&s->soc[socket].harts[cpu]); + qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name); + g_free(name); + qemu_fdt_setprop_string(mc->fdt, cpu_name, "compatible", "riscv"); + qemu_fdt_setprop_string(mc->fdt, cpu_name, "status", "okay"); + qemu_fdt_setprop_cell(mc->fdt, cpu_name, "reg", + s->soc[socket].hartid_base + cpu); + qemu_fdt_setprop_string(mc->fdt, cpu_name, "device_type", "cpu"); + riscv_socket_fdt_write_id(mc, mc->fdt, cpu_name, socket); + qemu_fdt_setprop_cell(mc->fdt, cpu_name, "phandle", cpu_phandle); + + intc_phandles[cpu] = (*phandle)++; + + intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name); + qemu_fdt_add_subnode(mc->fdt, intc_name); + qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle", + intc_phandles[cpu]); + qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible", + "riscv,cpu-intc"); + qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1); + + core_name = g_strdup_printf("%s/core%d", clust_name, cpu); + qemu_fdt_add_subnode(mc->fdt, core_name); + qemu_fdt_setprop_cell(mc->fdt, core_name, "cpu", cpu_phandle); + + g_free(core_name); + g_free(intc_name); + g_free(cpu_name); + } +} + +static void create_fdt_socket_memory(RISCVVirtState *s, + const MemMapEntry *memmap, int socket) +{ + char *mem_name; uint64_t addr, size; - uint32_t *clint_cells, *plic_cells; - unsigned long clint_addr, plic_addr; - uint32_t plic_phandle[MAX_NODES]; - uint32_t cpu_phandle, intc_phandle, test_phandle; - uint32_t phandle = 1, plic_mmio_phandle = 1; - uint32_t plic_pcie_phandle = 1, plic_virtio_phandle = 1; - char *mem_name, *cpu_name, *core_name, *intc_name; - char *name, *clint_name, *plic_name, *clust_name; - hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; - hwaddr flashbase = virt_memmap[VIRT_FLASH].base; + MachineState *mc = MACHINE(s); - if (mc->dtb) { - fdt = mc->fdt = load_device_tree(mc->dtb, &s->fdt_size); - if (!fdt) { - error_report("load_device_tree() failed"); - exit(1); - } - goto update_bootargs; - } else { - fdt = mc->fdt = create_device_tree(&s->fdt_size); - if (!fdt) { - error_report("create_device_tree() failed"); - exit(1); - } + addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket); + size = riscv_socket_mem_size(mc, socket); + mem_name = g_strdup_printf("/memory@%lx", (long)addr); + qemu_fdt_add_subnode(mc->fdt, mem_name); + qemu_fdt_setprop_cells(mc->fdt, mem_name, "reg", + addr >> 32, addr, size >> 32, size); + qemu_fdt_setprop_string(mc->fdt, mem_name, "device_type", "memory"); + riscv_socket_fdt_write_id(mc, mc->fdt, mem_name, socket); + g_free(mem_name); +} + +static void create_fdt_socket_clint(RISCVVirtState *s, + const MemMapEntry *memmap, int socket, + uint32_t *intc_phandles) +{ + int cpu; + char *clint_name; + uint32_t *clint_cells; + unsigned long clint_addr; + MachineState *mc = MACHINE(s); + + clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); + + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { + clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]); + clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT); + clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]); + clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER); } - qemu_fdt_setprop_string(fdt, "/", "model", "riscv-virtio,qemu"); - qemu_fdt_setprop_string(fdt, "/", "compatible", "riscv-virtio"); - qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2); - qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2); + clint_addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket); + clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr); + qemu_fdt_add_subnode(mc->fdt, clint_name); + qemu_fdt_setprop_string(mc->fdt, clint_name, "compatible", + "riscv,clint0"); + qemu_fdt_setprop_cells(mc->fdt, clint_name, "reg", + 0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size); + qemu_fdt_setprop(mc->fdt, clint_name, "interrupts-extended", + clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4); + riscv_socket_fdt_write_id(mc, mc->fdt, clint_name, socket); + g_free(clint_name); + + g_free(clint_cells); +} + +static void create_fdt_socket_plic(RISCVVirtState *s, + const MemMapEntry *memmap, int socket, + uint32_t *phandle, uint32_t *intc_phandles, + uint32_t *plic_phandles) +{ + int cpu; + char *plic_name; + uint32_t *plic_cells; + unsigned long plic_addr; + MachineState *mc = MACHINE(s); - qemu_fdt_add_subnode(fdt, "/soc"); - qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); - qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); - qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); - qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); + plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); - qemu_fdt_add_subnode(fdt, "/cpus"); - qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { + plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]); + plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT); + plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]); + plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT); + } + + plic_phandles[socket] = (*phandle)++; + plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket); + plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr); + qemu_fdt_add_subnode(mc->fdt, plic_name); + qemu_fdt_setprop_cell(mc->fdt, plic_name, + "#address-cells", FDT_PLIC_ADDR_CELLS); + qemu_fdt_setprop_cell(mc->fdt, plic_name, + "#interrupt-cells", FDT_PLIC_INT_CELLS); + qemu_fdt_setprop_string(mc->fdt, plic_name, "compatible", "riscv,plic0"); + qemu_fdt_setprop(mc->fdt, plic_name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop(mc->fdt, plic_name, "interrupts-extended", + plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4); + qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg", + 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size); + qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV); + riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket); + qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle", + plic_phandles[socket]); + g_free(plic_name); + + g_free(plic_cells); +} + +static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, + bool is_32_bit, uint32_t *phandle, + uint32_t *irq_mmio_phandle, + uint32_t *irq_pcie_phandle, + uint32_t *irq_virtio_phandle) +{ + int socket; + char *clust_name; + uint32_t *intc_phandles; + MachineState *mc = MACHINE(s); + uint32_t xplic_phandles[MAX_NODES]; + + qemu_fdt_add_subnode(mc->fdt, "/cpus"); + qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency", RISCV_ACLINT_TIMEBASE_FREQ); - qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); - qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); - qemu_fdt_add_subnode(fdt, "/cpus/cpu-map"); + qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#size-cells", 0x0); + qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1); + qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map"); for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) { clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket); - qemu_fdt_add_subnode(fdt, clust_name); + qemu_fdt_add_subnode(mc->fdt, clust_name); - plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); - clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); + intc_phandles = g_new0(uint32_t, s->soc[socket].num_harts); - for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) { - cpu_phandle = phandle++; + create_fdt_socket_cpus(s, socket, clust_name, phandle, + is_32_bit, intc_phandles); - cpu_name = g_strdup_printf("/cpus/cpu@%d", - s->soc[socket].hartid_base + cpu); - qemu_fdt_add_subnode(fdt, cpu_name); - if (is_32_bit) { - qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32"); - } else { - qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48"); - } - name = riscv_isa_string(&s->soc[socket].harts[cpu]); - qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name); - g_free(name); - qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv"); - qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay"); - qemu_fdt_setprop_cell(fdt, cpu_name, "reg", - s->soc[socket].hartid_base + cpu); - qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu"); - riscv_socket_fdt_write_id(mc, fdt, cpu_name, socket); - qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle); - - intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name); - qemu_fdt_add_subnode(fdt, intc_name); - intc_phandle = phandle++; - qemu_fdt_setprop_cell(fdt, intc_name, "phandle", intc_phandle); - qemu_fdt_setprop_string(fdt, intc_name, "compatible", - "riscv,cpu-intc"); - qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0); - qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1); - - clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle); - clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT); - clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle); - clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER); - - plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle); - plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT); - plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle); - plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT); - - core_name = g_strdup_printf("%s/core%d", clust_name, cpu); - qemu_fdt_add_subnode(fdt, core_name); - qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle); - - g_free(core_name); - g_free(intc_name); - g_free(cpu_name); - } + create_fdt_socket_memory(s, memmap, socket); - addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket); - size = riscv_socket_mem_size(mc, socket); - mem_name = g_strdup_printf("/memory@%lx", (long)addr); - qemu_fdt_add_subnode(fdt, mem_name); - qemu_fdt_setprop_cells(fdt, mem_name, "reg", - addr >> 32, addr, size >> 32, size); - qemu_fdt_setprop_string(fdt, mem_name, "device_type", "memory"); - riscv_socket_fdt_write_id(mc, fdt, mem_name, socket); - g_free(mem_name); - - clint_addr = memmap[VIRT_CLINT].base + - (memmap[VIRT_CLINT].size * socket); - clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr); - qemu_fdt_add_subnode(fdt, clint_name); - qemu_fdt_setprop_string(fdt, clint_name, "compatible", "riscv,clint0"); - qemu_fdt_setprop_cells(fdt, clint_name, "reg", - 0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size); - qemu_fdt_setprop(fdt, clint_name, "interrupts-extended", - clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4); - riscv_socket_fdt_write_id(mc, fdt, clint_name, socket); - g_free(clint_name); - - plic_phandle[socket] = phandle++; - plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket); - plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr); - qemu_fdt_add_subnode(fdt, plic_name); - qemu_fdt_setprop_cell(fdt, plic_name, - "#address-cells", FDT_PLIC_ADDR_CELLS); - qemu_fdt_setprop_cell(fdt, plic_name, - "#interrupt-cells", FDT_PLIC_INT_CELLS); - qemu_fdt_setprop_string(fdt, plic_name, "compatible", "riscv,plic0"); - qemu_fdt_setprop(fdt, plic_name, "interrupt-controller", NULL, 0); - qemu_fdt_setprop(fdt, plic_name, "interrupts-extended", - plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4); - qemu_fdt_setprop_cells(fdt, plic_name, "reg", - 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size); - qemu_fdt_setprop_cell(fdt, plic_name, "riscv,ndev", VIRTIO_NDEV); - riscv_socket_fdt_write_id(mc, fdt, plic_name, socket); - qemu_fdt_setprop_cell(fdt, plic_name, "phandle", plic_phandle[socket]); - g_free(plic_name); - - g_free(clint_cells); - g_free(plic_cells); + create_fdt_socket_clint(s, memmap, socket, intc_phandles); + + create_fdt_socket_plic(s, memmap, socket, phandle, + intc_phandles, xplic_phandles); + + g_free(intc_phandles); g_free(clust_name); } for (socket = 0; socket < riscv_socket_count(mc); socket++) { if (socket == 0) { - plic_mmio_phandle = plic_phandle[socket]; - plic_virtio_phandle = plic_phandle[socket]; - plic_pcie_phandle = plic_phandle[socket]; + *irq_mmio_phandle = xplic_phandles[socket]; + *irq_virtio_phandle = xplic_phandles[socket]; + *irq_pcie_phandle = xplic_phandles[socket]; } if (socket == 1) { - plic_virtio_phandle = plic_phandle[socket]; - plic_pcie_phandle = plic_phandle[socket]; + *irq_virtio_phandle = xplic_phandles[socket]; + *irq_pcie_phandle = xplic_phandles[socket]; } if (socket == 2) { - plic_pcie_phandle = plic_phandle[socket]; + *irq_pcie_phandle = xplic_phandles[socket]; } } - riscv_socket_fdt_write_distance_matrix(mc, fdt); + riscv_socket_fdt_write_distance_matrix(mc, mc->fdt); +} + +static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap, + uint32_t irq_virtio_phandle) +{ + int i; + char *name; + MachineState *mc = MACHINE(s); for (i = 0; i < VIRTIO_COUNT; i++) { name = g_strdup_printf("/soc/virtio_mmio@%lx", (long)(memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size)); - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "compatible", "virtio,mmio"); - qemu_fdt_setprop_cells(fdt, name, "reg", + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "virtio,mmio"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size, 0x0, memmap[VIRT_VIRTIO].size); - qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", - plic_virtio_phandle); - qemu_fdt_setprop_cell(fdt, name, "interrupts", VIRTIO_IRQ + i); + qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", + irq_virtio_phandle); + qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", VIRTIO_IRQ + i); g_free(name); } +} + +static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, + uint32_t irq_pcie_phandle) +{ + char *name; + MachineState *mc = MACHINE(s); name = g_strdup_printf("/soc/pci@%lx", (long) memmap[VIRT_PCIE_ECAM].base); - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_cell(fdt, name, "#address-cells", FDT_PCI_ADDR_CELLS); - qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", FDT_PCI_INT_CELLS); - qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0x2); - qemu_fdt_setprop_string(fdt, name, "compatible", "pci-host-ecam-generic"); - qemu_fdt_setprop_string(fdt, name, "device_type", "pci"); - qemu_fdt_setprop_cell(fdt, name, "linux,pci-domain", 0); - qemu_fdt_setprop_cells(fdt, name, "bus-range", 0, + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_cell(mc->fdt, name, "#address-cells", + FDT_PCI_ADDR_CELLS); + qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", + FDT_PCI_INT_CELLS); + qemu_fdt_setprop_cell(mc->fdt, name, "#size-cells", 0x2); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", + "pci-host-ecam-generic"); + qemu_fdt_setprop_string(mc->fdt, name, "device_type", "pci"); + qemu_fdt_setprop_cell(mc->fdt, name, "linux,pci-domain", 0); + qemu_fdt_setprop_cells(mc->fdt, name, "bus-range", 0, memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1); - qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0); - qemu_fdt_setprop_cells(fdt, name, "reg", 0, + qemu_fdt_setprop(mc->fdt, name, "dma-coherent", NULL, 0); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0, memmap[VIRT_PCIE_ECAM].base, 0, memmap[VIRT_PCIE_ECAM].size); - qemu_fdt_setprop_sized_cells(fdt, name, "ranges", + qemu_fdt_setprop_sized_cells(mc->fdt, name, "ranges", 1, FDT_PCI_RANGE_IOPORT, 2, 0, 2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size, 1, FDT_PCI_RANGE_MMIO, @@ -387,63 +434,93 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size); - create_pcie_irq_map(fdt, name, plic_pcie_phandle); + create_pcie_irq_map(mc->fdt, name, irq_pcie_phandle); g_free(name); +} + +static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap, + uint32_t *phandle) +{ + char *name; + uint32_t test_phandle; + MachineState *mc = MACHINE(s); - test_phandle = phandle++; + test_phandle = (*phandle)++; name = g_strdup_printf("/soc/test@%lx", (long)memmap[VIRT_TEST].base); - qemu_fdt_add_subnode(fdt, name); + qemu_fdt_add_subnode(mc->fdt, name); { const char compat[] = "sifive,test1\0sifive,test0\0syscon"; - qemu_fdt_setprop(fdt, name, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop(mc->fdt, name, "compatible", compat, sizeof(compat)); } - qemu_fdt_setprop_cells(fdt, name, "reg", - 0x0, memmap[VIRT_TEST].base, - 0x0, memmap[VIRT_TEST].size); - qemu_fdt_setprop_cell(fdt, name, "phandle", test_phandle); - test_phandle = qemu_fdt_get_phandle(fdt, name); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, memmap[VIRT_TEST].base, 0x0, memmap[VIRT_TEST].size); + qemu_fdt_setprop_cell(mc->fdt, name, "phandle", test_phandle); + test_phandle = qemu_fdt_get_phandle(mc->fdt, name); g_free(name); name = g_strdup_printf("/soc/reboot"); - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-reboot"); - qemu_fdt_setprop_cell(fdt, name, "regmap", test_phandle); - qemu_fdt_setprop_cell(fdt, name, "offset", 0x0); - qemu_fdt_setprop_cell(fdt, name, "value", FINISHER_RESET); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot"); + qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle); + qemu_fdt_setprop_cell(mc->fdt, name, "offset", 0x0); + qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET); g_free(name); name = g_strdup_printf("/soc/poweroff"); - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-poweroff"); - qemu_fdt_setprop_cell(fdt, name, "regmap", test_phandle); - qemu_fdt_setprop_cell(fdt, name, "offset", 0x0); - qemu_fdt_setprop_cell(fdt, name, "value", FINISHER_PASS); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff"); + qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle); + qemu_fdt_setprop_cell(mc->fdt, name, "offset", 0x0); + qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_PASS); g_free(name); +} + +static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap, + uint32_t irq_mmio_phandle) +{ + char *name; + MachineState *mc = MACHINE(s); name = g_strdup_printf("/soc/uart@%lx", (long)memmap[VIRT_UART0].base); - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "compatible", "ns16550a"); - qemu_fdt_setprop_cells(fdt, name, "reg", + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0x0, memmap[VIRT_UART0].base, 0x0, memmap[VIRT_UART0].size); - qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 3686400); - qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", plic_mmio_phandle); - qemu_fdt_setprop_cell(fdt, name, "interrupts", UART0_IRQ); + qemu_fdt_setprop_cell(mc->fdt, name, "clock-frequency", 3686400); + qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", irq_mmio_phandle); + qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", UART0_IRQ); - qemu_fdt_add_subnode(fdt, "/chosen"); - qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name); + qemu_fdt_add_subnode(mc->fdt, "/chosen"); + qemu_fdt_setprop_string(mc->fdt, "/chosen", "stdout-path", name); g_free(name); +} + +static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap, + uint32_t irq_mmio_phandle) +{ + char *name; + MachineState *mc = MACHINE(s); name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base); - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "compatible", "google,goldfish-rtc"); - qemu_fdt_setprop_cells(fdt, name, "reg", - 0x0, memmap[VIRT_RTC].base, - 0x0, memmap[VIRT_RTC].size); - qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", plic_mmio_phandle); - qemu_fdt_setprop_cell(fdt, name, "interrupts", RTC_IRQ); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", + "google,goldfish-rtc"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, memmap[VIRT_RTC].base, 0x0, memmap[VIRT_RTC].size); + qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", + irq_mmio_phandle); + qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", RTC_IRQ); g_free(name); +} + +static void create_fdt_flash(RISCVVirtState *s, const MemMapEntry *memmap) +{ + char *name; + MachineState *mc = MACHINE(s); + hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; + hwaddr flashbase = virt_memmap[VIRT_FLASH].base; name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase); qemu_fdt_add_subnode(mc->fdt, name); @@ -453,10 +530,59 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, 2, flashbase + flashsize, 2, flashsize); qemu_fdt_setprop_cell(mc->fdt, name, "bank-width", 4); g_free(name); +} + +static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, + uint64_t mem_size, const char *cmdline, bool is_32_bit) +{ + MachineState *mc = MACHINE(s); + uint32_t phandle = 1, irq_mmio_phandle = 1; + uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1; + + if (mc->dtb) { + mc->fdt = load_device_tree(mc->dtb, &s->fdt_size); + if (!mc->fdt) { + error_report("load_device_tree() failed"); + exit(1); + } + goto update_bootargs; + } else { + mc->fdt = create_device_tree(&s->fdt_size); + if (!mc->fdt) { + error_report("create_device_tree() failed"); + exit(1); + } + } + + qemu_fdt_setprop_string(mc->fdt, "/", "model", "riscv-virtio,qemu"); + qemu_fdt_setprop_string(mc->fdt, "/", "compatible", "riscv-virtio"); + qemu_fdt_setprop_cell(mc->fdt, "/", "#size-cells", 0x2); + qemu_fdt_setprop_cell(mc->fdt, "/", "#address-cells", 0x2); + + qemu_fdt_add_subnode(mc->fdt, "/soc"); + qemu_fdt_setprop(mc->fdt, "/soc", "ranges", NULL, 0); + qemu_fdt_setprop_string(mc->fdt, "/soc", "compatible", "simple-bus"); + qemu_fdt_setprop_cell(mc->fdt, "/soc", "#size-cells", 0x2); + qemu_fdt_setprop_cell(mc->fdt, "/soc", "#address-cells", 0x2); + + create_fdt_sockets(s, memmap, is_32_bit, &phandle, + &irq_mmio_phandle, &irq_pcie_phandle, &irq_virtio_phandle); + + create_fdt_virtio(s, memmap, irq_virtio_phandle); + + create_fdt_pcie(s, memmap, irq_pcie_phandle); + + create_fdt_reset(s, memmap, &phandle); + + create_fdt_uart(s, memmap, irq_mmio_phandle); + + create_fdt_rtc(s, memmap, irq_mmio_phandle); + + create_fdt_flash(s, memmap); update_bootargs: if (cmdline) { - qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline); + qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline); } } From patchwork Sat Jun 12 16:06:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12317187 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 044F9C48BE5 for ; Sat, 12 Jun 2021 16:16:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 65810613BF for ; Sat, 12 Jun 2021 16:16:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 65810613BF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37618 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ls6Ii-0004ND-4c for qemu-devel@archiver.kernel.org; Sat, 12 Jun 2021 12:16:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60004) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ls69v-0002qo-I0; Sat, 12 Jun 2021 12:06:55 -0400 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:45085) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ls69r-0002MX-TN; Sat, 12 Jun 2021 12:06:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1623514011; x=1655050011; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=Km0TJF5ePaFDuyq5wpGJdAJ7cpeQazpNnOHVM/ZwHYQ=; b=Vf7zkUVHS4vA9RUHwTvpP+gdYGS14IDOK1rglWBvjFzFeq1NqDfFnlnt iRJbsPuwl5/LUh4gmCyCXIZwFiApzfjnxCZjP/JbTysKNraMzYv3JYsCv BRqbPd18evzbN7LOroVdlma5gIIdRyM/v7RhpFKlEIDBTHRT6vCektbxz 7OE01SvNEaxRmeDLu6gudSNwxSubeMNiF4yOBN4tvF2SZnLmo0UUW1bEp 4RmTX/FI/VO8a59VpB9CHnkIgqxZS8XlfnES9S1TzuT6IUCA0Qt1pkcVF ezf7wiG2XjiuuMlvxdx6OFYHqPZnOOCHIYUEplLEnSwMaaD+cJpko201S w==; IronPort-SDR: Cl8wIyf8wpciel3pyi4zC0pCSOUCpW41ismuhzC4cbpqy8MjgDOp/ZC7pTYhHBxbREOScnPe0Z kkC9YgewDWVdEs5dOPcnzai2Vk5A4xF2J/MdFo+8mfW2wdCFojmijpD50r0Beevghder2pT4Fg 6CjtYsGhGdsyi6n+lYuNKc2BTjJxGc8SpwM+/FW1lw+QQLSy3pasvikyN8/eedRT7w7Q9bEFZn WCEAshbShEy/Mow+Y6snarz6uQrE61lgV1BxOQJ+xEWiesurjHPf3GVUiuBPCJhTs2cPzQ0u1W 4AI= X-IronPort-AV: E=Sophos;i="5.83,268,1616428800"; d="scan'208";a="171704751" Received: from mail-bn8nam12lp2171.outbound.protection.outlook.com (HELO NAM12-BN8-obe.outbound.protection.outlook.com) ([104.47.55.171]) by ob1.hgst.iphmx.com with ESMTP; 13 Jun 2021 00:06:48 +0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=U6UupR73u3Kz4U6PcKNEqRaBeAKnihMd6kG4OGaxhrH4IlnF0mcVRPHqdVcee+e2iO2pUG+GcXPiZ8Zyk/AZmhwvzr6Lz45fJ8hwgFpfEk+pHETi/+fwdC8uPnRO/xqbne7n0ygSGHp+VLNQySXEcG5eIzOSoQ8OuZr6R8/WO3mHuBiQ3QmJORoKEZo0L9it3Lf7nMhPy1b05xHojb/jcn74/QrmtoGiSk5IsASp6FUuGOdfY3R0pxjCA+shsx49WFUi089WHL6Ph1+MRQRLm3rrTioMv2uTvWk1yxKZzpRXvHmfGF8nWDKWpcT06fUTxdbkMm6KxmWqjAw/PGqflw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Veym8/rcxGTH4N9Fc9tGK6mFihc8jHnWlASllzf9fXM=; b=d1MdtnzTdLLWumev6oMLOjmfJOYG0An4o54QPf2vMIkKYB4K78j27MEVir8Hq6gcApfBmtBg+XrpJGlisuN+INHoZzwcrWJI8SVKGzJrlS4OAXCYxnKYm8JxgwGmrc/6D/xYsiSN9oCrykn6jJ/akqut33XeYxNwc0QdQQK7rj1BT8+SogIbHdAqQEh9feaKVL1cz4QgGwLSXCWSF6i0dIRNaUL7CpVjGDMCvp2TNEO/YC/S0IU6FaP/p6PfQws5tICdi44EZVTWGp65gHcP3QaF3WPXVLcsBMuHQ46zglt0Xd9oKlkSVXvGcB+/r5/9dYHbNCOv1BojrcC9yM65TA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wdc.com; dmarc=pass action=none header.from=wdc.com; dkim=pass header.d=wdc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sharedspace.onmicrosoft.com; s=selector2-sharedspace-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Veym8/rcxGTH4N9Fc9tGK6mFihc8jHnWlASllzf9fXM=; b=pY9hvVaqLuvDAZBaqXqmR++Y2IOg1ntpYPhlb7yHSqZmXnd1JTVCpd5uZfvS6Bmq+4i65WglsaM1XCl6CtdE7aWvB0zBch4sJO3IDJ46VeJHgh1iUpsJxIc941XeU2Ijo1/wM6FO4f1wT910L5V+eguEe+XKqRKljJC2sRGQKJs= Authentication-Results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=wdc.com; Received: from CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) by CO6PR04MB7747.namprd04.prod.outlook.com (2603:10b6:5:35b::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.22; Sat, 12 Jun 2021 16:06:48 +0000 Received: from CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::a153:b7f8:c87f:89f8]) by CO6PR04MB7812.namprd04.prod.outlook.com ([fe80::a153:b7f8:c87f:89f8%9]) with mapi id 15.20.4219.025; Sat, 12 Jun 2021 16:06:48 +0000 From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v1 3/3] hw/riscv: virt: Add optional ACLINT support to virt machine Date: Sat, 12 Jun 2021 21:36:15 +0530 Message-Id: <20210612160615.330768-4-anup.patel@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210612160615.330768-1-anup.patel@wdc.com> References: <20210612160615.330768-1-anup.patel@wdc.com> X-Originating-IP: [122.171.171.205] X-ClientProxiedBy: MA1PR01CA0172.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::16) To CO6PR04MB7812.namprd04.prod.outlook.com (2603:10b6:303:138::6) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from wdc.com (122.171.171.205) by MA1PR01CA0172.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a01:d::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.21 via Frontend Transport; Sat, 12 Jun 2021 16:06:44 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4cf6a561-a365-464e-2123-08d92dbc14d9 X-MS-TrafficTypeDiagnostic: CO6PR04MB7747: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: WDCIPOUTBOUND: EOP-TRUE X-MS-Oob-TLC-OOBClassifiers: OLM:203; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: jEkRdLrsHJWJ0rDJvqcT8gK/OPhgK3L4GjKTmlyNbcVfK9K5cWj1Ip8vWN8rOBkJ+BPg3F6Px4U6vE8hmRQyhHpSfF3+wSI3AgEdEiB9l8+Sf8o0/1a39MByhlI8wUc63yaWQwO8lUpzdp8FbLVU/hogZWmIMPBENR31cdTpf/CHUVDk4zE9qgFFCyhImUBckBdxNiuJT902567xuJObxO/enQyLNvah0lBc0YGst8hpWCmz7uKa+OcDD/l+nyykaYk6xR7JF/CwnbWMgH+OzsS6zkXd01OJ5Rex4jOGsfYma1GOfM4v4ZHXzcgbdy7vazgYWG+x2k7V1ZD/HP8f0jwl7EYYNCVlAqXAoMr2L5VLyPjhDrPT1E+9ekS4GskpMylLQKIq6+c6ylRT5ZY1RfYOEOBNdl4BXY6RzWEx0PMhlsAR5H1DwpqHFp/DUQb1rXH77dypW4Vz5YB3z4f6kqiAv94CFlHSLXDCxL3HKdGveYzqihvWw74yUqUxDTJi+FqxOI1Rqald909fXvxzTDdK4zn48dWJg8XFsdhaMNnHSzi6uHLzUgAO3uwyLBeQKtDziL8nD4Kjpd/1HAQwSTVi7koIrt2MRVP7oDHAjvGBevYjikP+rdkP/U2fT0E9HAXLWghHO/X6yTNQmDcMhg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CO6PR04MB7812.namprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(396003)(136003)(366004)(346002)(39860400002)(54906003)(8936002)(8676002)(110136005)(4326008)(2616005)(44832011)(16526019)(186003)(66476007)(66556008)(66946007)(2906002)(956004)(316002)(38350700002)(86362001)(38100700002)(55016002)(26005)(7696005)(8886007)(36756003)(52116002)(6666004)(83380400001)(1076003)(478600001)(5660300002); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Jt+4lc8sgWG8P7tgXidilqrIJSW23QddcoqlYNRbmNNOkwQ7Y9GQkGp3qXNJ3zSIBsIKV7VPLadtMeRIzW7UBmDV7S5Zc+jxXG2imjuL9vjMHJ9+5Lhp64mqSrlrfpM2hoh5SUsnd9C1axmyhtPXOUcxYOxvN1CFZNug0tu4he/4BOtUlp4zpHM/0Cqu2z1Ob7yjO/VBDwvUbeHPv4SxHDpPakeiQSsDPjgBjXC1a47IJMNxV6Q9oOeX0xYWwR9V2UJr186u4FGfzs9ZpmWXOpgmxRfQ2QIfcRohE0mh380D4Dfvan8bhQx7935rBLGZSzCthWzkOMS8hqsaYGsQt6wC80QG2WY3Yap7NeCZMHvi4c3tEmflzqYiCCMCya4XTTNuDbxfeYPNimAn4FygzsgK+0lE0likfiqws2Z/60Ok71IKrvO6xMS/fRY+pR7eSoXSsCrjSF0XNEyBD3SXXco5YmfKGcKa3mdP22XN873BGrqLPSLYngGoU7vNKgtr+uaWaoOxFXeckVradfLT/V1B2fyce94sWlQrPLlhDADcgUsbvbSDalhrDmIkXxHIPUUYjpw5nu+N6MKJHVrpxf9NGej92qPxlkFJhsLst/cDWQ5zGteqVfUnzpy9Vyheu3PGNV5IhG9JY/zN9K39P4A2/NbFPeCfIq4DxkyeDKkbfMBJjfbPPZGRh4D+Y5WgYMuEXqvSljZsTIHi+9PCeHV7IqxjoGzR7B019TU9ZRA1+XZpQ5nWrX7af7CV9lT6RWdfmHK6uWhGFlmkTm4R1nz6OQVHmyU3RjwieLwPAkEaABjn6gDhwAzSNa5jH9LNIdUyGphJQGyjnq0u3xNVd8Iq6hQ/ktGMHV1KErnSmZEYRH65MwF+Se1eo1soznSY4h/WYHztBt3m93mfGkx3bBbOmO2cPGX6gXqsmi73gbhlUCkP25qrw26/D090Pg+MEiTtBcZr66ii+EQWNwCYdSHp4MxzIOXd+xKV4RbTM2O+iYxYqFolJrrObBsHK2uZx2v81nDy8x+v6G0XROw84qSLKImbp8mvzHr6Lh5AT5jeTdO8Lsb60AleKhVeujvfxKH5dwSYb2PBvUQS2ZYcDclEZ21J1moNAtp+nu2EpDtSNTXzpFqYVlVJUnN623XWScxB5sCZ80pEwzZPCNCjW1ue2BbWIa90zMC8NLPF461Bcc7NrT3di8M4neRf1/spia6+x8zv3IAv6A6MEiuZzcIvQYtnmnclV8ZrRp0OY6gXSoZXhTan1CiUBPWr1cCC9fCxM6IbPMYNw7RrOZimS2qiPmlpTWQp9yCow6iSnPuNU+njRAVtETx+4yybeMFh X-OriginatorOrg: wdc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4cf6a561-a365-464e-2123-08d92dbc14d9 X-MS-Exchange-CrossTenant-AuthSource: CO6PR04MB7812.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2021 16:06:48.0075 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b61c8803-16f3-4c35-9b17-6f65f441df86 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: saUpleVjCk5dM7VQvZ5+udUB2bs87gf0vtdW7V8Ua4TKMl3HkONJzQalwEATb6TKsbgKCxf3ua0Rj/s3fqI1zg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR04MB7747 Received-SPF: pass client-ip=216.71.153.144; envelope-from=prvs=790f0be0c=Anup.Patel@wdc.com; helo=esa5.hgst.iphmx.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, MSGID_FROM_MTA_HEADER=0.001, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Atish Patra , Anup Patel , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Anup Patel Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We extend virt machine to emulate ACLINT devices only when "aclint=on" parameter is passed along with machine name in QEMU command-line. Signed-off-by: Anup Patel --- hw/riscv/virt.c | 110 +++++++++++++++++++++++++++++++++++++++- include/hw/riscv/virt.h | 2 + 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 977d699753..a35f66af13 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -50,6 +50,7 @@ static const MemMapEntry virt_memmap[] = { [VIRT_TEST] = { 0x100000, 0x1000 }, [VIRT_RTC] = { 0x101000, 0x1000 }, [VIRT_CLINT] = { 0x2000000, 0x10000 }, + [VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 }, [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) }, [VIRT_UART0] = { 0x10000000, 0x100 }, @@ -279,6 +280,78 @@ static void create_fdt_socket_clint(RISCVVirtState *s, g_free(clint_cells); } +static void create_fdt_socket_aclint(RISCVVirtState *s, + const MemMapEntry *memmap, int socket, + uint32_t *intc_phandles) +{ + int cpu; + char *name; + unsigned long addr; + uint32_t aclint_cells_size; + uint32_t *aclint_mswi_cells; + uint32_t *aclint_sswi_cells; + uint32_t *aclint_mtimer_cells; + MachineState *mc = MACHINE(s); + + aclint_mswi_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); + aclint_mtimer_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); + aclint_sswi_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); + + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { + aclint_mswi_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + aclint_mswi_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_SOFT); + aclint_mtimer_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + aclint_mtimer_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_TIMER); + aclint_sswi_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + aclint_sswi_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_SOFT); + } + aclint_cells_size = s->soc[socket].num_harts * sizeof(uint32_t) * 2; + + addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket); + name = g_strdup_printf("/soc/mswi@%lx", addr); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "riscv,aclint-mswi"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, addr, 0x0, RISCV_ACLINT_SWI_SIZE); + qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", + aclint_mswi_cells, aclint_cells_size); + qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0); + riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); + g_free(name); + + addr = memmap[VIRT_CLINT].base + RISCV_ACLINT_SWI_SIZE + + (memmap[VIRT_CLINT].size * socket); + name = g_strdup_printf("/soc/mtimer@%lx", addr); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", + "riscv,aclint-mtimer"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, addr, 0x0, memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE); + qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", + aclint_mtimer_cells, aclint_cells_size); + riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); + g_free(name); + + addr = memmap[VIRT_ACLINT_SSWI].base + + (memmap[VIRT_ACLINT_SSWI].size * socket); + name = g_strdup_printf("/soc/sswi@%lx", addr); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "riscv,aclint-sswi"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, addr, 0x0, memmap[VIRT_ACLINT_SSWI].size); + qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", + aclint_sswi_cells, aclint_cells_size); + qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0); + riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); + g_free(name); + + g_free(aclint_mswi_cells); + g_free(aclint_mtimer_cells); + g_free(aclint_sswi_cells); +} + static void create_fdt_socket_plic(RISCVVirtState *s, const MemMapEntry *memmap, int socket, uint32_t *phandle, uint32_t *intc_phandles, @@ -352,7 +425,11 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, create_fdt_socket_memory(s, memmap, socket); - create_fdt_socket_clint(s, memmap, socket, intc_phandles); + if (s->have_aclint) { + create_fdt_socket_aclint(s, memmap, socket, intc_phandles); + } else { + create_fdt_socket_clint(s, memmap, socket, intc_phandles); + } create_fdt_socket_plic(s, memmap, socket, phandle, intc_phandles, xplic_phandles); @@ -722,6 +799,15 @@ static void virt_machine_init(MachineState *machine) RISCV_ACLINT_MTIMER_SIZE, base_hartid, hart_count, RISCV_ACLINT_TIMEBASE_FREQ, true); + /* Per-socket ACLINT SSWI */ + if (s->have_aclint) { + riscv_aclint_swi_create( + memmap[VIRT_ACLINT_SSWI].base + + i * memmap[VIRT_ACLINT_SSWI].size, + memmap[VIRT_ACLINT_SSWI].size, + base_hartid, hart_count, true); + } + /* Per-socket PLIC hart topology configuration string */ plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * hart_count; @@ -898,6 +984,22 @@ static void virt_machine_instance_init(Object *obj) { } +static bool virt_get_aclint(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + RISCVVirtState *s = RISCV_VIRT_MACHINE(ms); + + return s->have_aclint; +} + +static void virt_set_aclint(Object *obj, bool value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + RISCVVirtState *s = RISCV_VIRT_MACHINE(ms); + + s->have_aclint = value; +} + static void virt_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -913,6 +1015,12 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) mc->numa_mem_supported = true; machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); + + object_class_property_add_bool(oc, "aclint", virt_get_aclint, + virt_set_aclint); + object_class_property_set_description(oc, "aclint", + "Set on/off to enable/disable " + "emulating ACLINT devices"); } static const TypeInfo virt_machine_typeinfo = { diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 349fee1f89..d9105c1886 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -43,6 +43,7 @@ struct RISCVVirtState { FWCfgState *fw_cfg; int fdt_size; + bool have_aclint; }; enum { @@ -51,6 +52,7 @@ enum { VIRT_TEST, VIRT_RTC, VIRT_CLINT, + VIRT_ACLINT_SSWI, VIRT_PLIC, VIRT_UART0, VIRT_VIRTIO,