From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788435024; cv=pass; d=zohomail.com; s=zohoarc; b=FCmuwdbRXgLWOvb56ssaNN+eoX3NmqEqu2ZwOtPJn6dCi7cBzoXE/T8u9tvzQOjQSJfgefEKlcbP2kBvEEU6UyMFqhvxhvWcGvka2C20x3PlO8MQyB4DhqU4lJnDJdIP3Kn23s3YYlKs/sD8vQamkNOkVZJkklb36x8NXoDKq4w= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788435024; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=sP5B7KduE+ohaZcnUPmMyrq/Gl9zLGQgxnH6KzabY/4=; b=i3EJjKm+gLRVKuXowGkIE0ivCG9/2ps0fXoyWqK5Fu8HIcaShl/kYweGzG0SZZ3V89p8jsDgna7WYuzG17xUu9sLzEDNFvwJGNzxnqGJ9t+RpflHzKdtp55WWEF1LSQtCSaOQnkhY/2WSVFc0qjsIL69axO2E+Lv9PcCn5trxPc= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788435024292872.9605001643109; Thu, 3 Sep 2026 04:30:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25a6-0005TW-C2; Thu, 03 Sep 2026 07:26:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a4-0005Sh-42; Thu, 03 Sep 2026 07:26:08 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a2-0006f9-8Q; Thu, 03 Sep 2026 07:26:07 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:25:53 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:25:53 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=j/lxyrzDfz83YbtXcHxh+QEfOet/9seugfU1JAsH4E3QH4MsYDW4pgwsJ3NlSPRVHetbjJkhR/dbmIh22c4IdagaAuEn6ScyN1aXGTKq7tem8k7GG5KjBQxAOMmB+DONVSZrrXWvNV3TvgMpsEs6BNxqv0xI8vSSCHEuDGNW7T5sOdUMKtxDiwwwrTe+qKQnSVHg6emu9IYfVb/e4zZiVQ/JAemwt9IxuxoGAOmUC1LMn92Y2CORXpCayWCDi+onja6D19B8AAbArTqscb+l+iJ3/ESZvi7/0DqHHHJK61rDUe13S3MLre8cMa29EIZqOaBl9fo1pwIeAPknJxlcNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=sP5B7KduE+ohaZcnUPmMyrq/Gl9zLGQgxnH6KzabY/4=; b=HvpRd4eFXWfjKjfsCcMjN5uhcNE97pXIHM/JMqSM9bVOTjdHuhw9vxicSk96raoL1ao/apgwYqXB/KFAEThNyry8T0ZsBIKj/NmMDBc7INJA5gdgz555aVMt5jsRa7wfmy/2zTIytp6bBKUDtg39dnckCR9WK30xso0Foqeok+JFecaf6yjMxROG2wZ+WJIiYJU13chypxNOqiaVGYbEcJRjtiYAKIgWE63Ho9eim39Jni4Zy31mQSTwYw2u6/bEi5KchgQQyFbUiSqmwqbh0sqZqtA6PyyaIVAoRh9JBklK3+9LY7R7SmTnx19rfU2+8r65JGrp/ucKiv46YPZ7Nw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=sP5B7KduE+ohaZcnUPmMyrq/Gl9zLGQgxnH6KzabY/4=; b=jg/WHaEaqAJUOoqDTrBwSPnfPNHEigLlcliQ36e5GZVpVPo31r78ojpbdCWzCSwOuv7fe9jvpPjmcQmtv04SbexbZYmKL+QnYPVDu2lM1VGSVjfXFx0OtxzTmVfXlkqGRs0YvuRgVv6hSBm/qQ9VktpEI+e7DEj2RpgiSlchRO7L/sNjmAlaxd1e0nFSS4pR889CqY55dVVoWD4td/02Mhf945cF5KuM4YMzxgF3NJYxJ3YNBiJMXyqEwm2NA5I6rHePYtwc8wWx0ba+zwjOfONekSfDgXR2f1QtUumn2YIjROZpdPkhMaIoWkA2R8KNyU92Ubt+tyzlgqSuUwRSkw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 01/33] target/arm: Add Phytium FTC310 and FTC664 CPU models Date: Thu, 3 Sep 2026 19:24:41 +0800 Message-ID: <20260903112532.3276678-2-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 7b465f0b-9ae4-4667-cb6a-08df09ae1d6b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: Z042oRFFNGpU4XbhzYv1pct+nbgZUnuZMAr/ndjlHyahGLDhZIlMAtXQQYBYj7f2F5Gxk00ZJz7B57A0MmN/4a4En1y3o+P9dHFOGCHSFC7+4SYYDMLRy5nv0HKCOW58P4Ox0Bc6S9Fg3lPATXmdTe717jNhKy20bxVuE7Ob6yESa+wdmTw4nyqeC++F/uYKMYorI0Ns+5sa7UvSfUpNjWzUIiIEmGm64+PisprZY7SqVL5o/+HOsW70tH1FYnYk3pwKjRvMI1LoCDspZp24ltR/eY/aviqMi4K2Ac4r7oeK5y2ElE8FMzMOVo8Jt0Gg56B09ShAI+SrM8owbhx6T0if3OfPg+L4NiLoEdKhpdNXk7Oi+Z/Es3fTNbdRi3Y6ZpRhhEFFvxAWsUd6NsopPGrgU11jBS7fI0BoYJpEJYTLNq/NiNbmGZtm9GZraxHzIlX4XgeK+24JtwsgoDoJPSpdTtXc0UJG73L5Ndku2DsGbOHIF7EV1DFhyIMzeyskTPuFLyCk320i2B71Nb4YeroTBB5V2HSkAonn7ZC4zY0aPcQQbVjGl+AWqI6EbE/xJItLHI8fneF47gGaT/8q0f0CbRbB+0A58EromZm3DufANuqkrDdY7Jtpbh1+DqjFNRHrOWkGF0GbZ0qyJ8sQBL7L20Cc1tjcSrVzfjKrcrU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?pjy3a5tmn7braoSedUGXZL4q51gijHmUfw2toBzPGwL5NiXdd+VFdiYmznhq?= =?us-ascii?Q?dUWdLF3qmQ/a+Z/AKpTOtHBCGEmmlhw17fEh/gmFiy8Ug8+Dlf+s0/RGmO5H?= =?us-ascii?Q?H/4QpR4uoXrtZBSl6xwV/AR9ZRhT7l8e341p9RnZey3atuuHmGhS9t/SDTO6?= =?us-ascii?Q?MKGdIODXNZ/Y3b8rGq9BOMS1L33IOTdp/WXsTgVbGLdAzcy97TQQPycqyH1m?= =?us-ascii?Q?Fta2ZFsZxYrtLpt0WVShnJWrYoj5M1E2N5IYCDZ0c3V5HYSiQLvVFXbZ2TNP?= =?us-ascii?Q?6z69r0ae/f/0TwpMJ5Z2ZmnwqmCv2H1SN+/IRi4PPLeqtOsROtq7kSGXN2kp?= =?us-ascii?Q?ePwSiH1dC7EIlMWKFnWZtykdQB5+lDIObTAZ3s9dlhtfsL83C0zomQEFfnri?= =?us-ascii?Q?iRfbqzB+iEq5al50xASOYqLzEQr7hYHUhMrx/BJXGlyoubZoWLtlFag3oGq8?= =?us-ascii?Q?x9hZZPE8GFM4DHyKlc1myN6YQNB6apBb4eEiVF9bI00ShAfa2jFMbVbwuFrJ?= =?us-ascii?Q?eWcxFHJ1miJZJa9O2tXvJMABbX/OZWyw1Y9oK2NZzUM5cWQyI/yWqxPTFHQp?= =?us-ascii?Q?8R7cFecnJCsRL3pc5ZBt7GMIbq0sQb1FcH6xWwL6C9sSfS+LBw+bNAiMjuXC?= =?us-ascii?Q?KlCBsazm+ynkFz//SPnxU/LaYxvLISwDM4CXDggr51H41Yjmqax77tWNWJcQ?= =?us-ascii?Q?oG7Is+RkeWHzMIpo4dM+H/D6ef+TpzlHM/2ixNBZQAWOgg2AteO+PnG1dHh8?= =?us-ascii?Q?NrEY8yxjvj82U0KFaIfQ4S2RKxWvCerXvQQ/OPl0HQSgHH45G/1c0U31thAO?= =?us-ascii?Q?hJDt0hhWuBEVaEZeznkpn3SXAR7IebYKljTu98q/3n4nPlzKEW0bCMqpVeIF?= =?us-ascii?Q?sOKPjgeEVpTqz6yMJAq3K5gzE2JBD6ZuO/zC4P30Qa5GNHRMLaHiPC0phNr5?= =?us-ascii?Q?xZdlwkdlOvGi9aLfVpKOpIRMLJ6Sjb9935jNGZ4r4woZ9E5ZDiZkmoEffSml?= =?us-ascii?Q?pnPg0BfnGPf8RRSv4phfFYAFcu2hB7P3CnnKwWtEx57vP1MiRAfzjfDGsJL/?= =?us-ascii?Q?6rTU7mtJ43+NPQnQ8HEOQ3kmi3l71KnTKmGUd7qKVlqskN98MqT6w68yeFOj?= =?us-ascii?Q?0VJ+V9e8rd/G2WhKJ8gM+15wNaco7gZr7HLZ32u4oyO70BX2/ONTWIiZtZdp?= =?us-ascii?Q?eHSXCtyPpJ7/GKZud3P7yOEpjrNZZ50yLr0rVCvLaIvKgkHA6GUGhMZWit2j?= =?us-ascii?Q?e9YAYtQ0FQ21dwwKwSPaoH8W7KJSjFhPMbWNT5X/ORNdJIGu2PpJvzGvvSOb?= =?us-ascii?Q?DNygcZ+VrrNCnrbL78vykuFQDtpPD4lTWZLx2ZgehIXzN66MJCdw7gulXOUd?= =?us-ascii?Q?T3Nk98XTcTJ+10IRckFc2vwIzyz6w+sr/voV65asLIHvHiUF2jxF7ZhBVFrk?= =?us-ascii?Q?BHmaejAiYTmacPfSdoN3Ksh0eeWFuvrjx8sEUWDX1TwEze7lwelMYTUDrMd7?= =?us-ascii?Q?x2W9mP7dKQdNURZFFhakiCn+SHscyjZSE3R8FyXEO1maCmYs5sMhFByk+nXy?= =?us-ascii?Q?3Uj9PuNJzUOOY9MkXoitPg5mb4s/GmBY7plG/TGz6Zg18nJySE9c+fnisXAo?= =?us-ascii?Q?+YFQ/RCuOkH2eE2uo9R750vMHzbuo1mSZUi5dlJ7Le6D9Qj3iy3Y+mCdP2Yu?= =?us-ascii?Q?FmKHMNZR49myMnR/JnhhKpKfTzINpVt3A1yOqTpWfIwj7DIieqCtkq7meTLr?= =?us-ascii?Q?wzW1s45V2xMBDRe5rw1dCWb6GrbaMg8=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7b465f0b-9ae4-4667-cb6a-08df09ae1d6b X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:25:53.3478 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: cmOumWFf43uB0DbqESwP52qQ23OlDxsKhrmOVBsi/MRAVPKyK5j7fOpueHnJSC+uiLbPNdjc60rlE65vm5uGzVxhJ+I7LRkNgsZJnjSER8Q= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788435025347158500 Content-Type: text/plain; charset="utf-8" The Phytium E2000Q combines two FTC310 cores and two FTC664 cores. Its EL3 firmware accesses implementation-defined system registers while setting up the cores. Using generic Cortex-A72 CPUs leaves these registers undefined and traps firmware before it can reach U-Boot. Add FTC310 and FTC664 CPU types using Cortex-A72 as their common execution base. Provide conservative RAZ/WI and NOP stubs for the firmware-visible E2000 controls that have no modeled behavior. Set each CPU DT compatible string, MIDR, instruction feature fields, AArch32 floating-point feature fields, and CTR_EL0.L1Ip field to values observed on an E2000Q board. The FTC310 reports a VIPT instruction cache, while the FTC664 reports a PIPT instruction cache. Signed-off-by: Bin Meng --- target/arm/tcg/cpu64.c | 81 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index affd87a3ae..0fd2f79bbc 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -336,6 +336,85 @@ static void aarch64_a72_initfn(Object *obj) define_cortex_a72_a57_a53_cp_reginfo(cpu); } =20 +static const ARMCPRegInfo phytium_e2000_cp_reginfo[] =3D { + /* + * The E2000 EL3 firmware touches implementation-defined CPU registers + * during the PBF/BL1 cache and core setup. QEMU does not model these + * controls, so expose conservative RAZ/WI stubs for the boot firmware. + * + * PBF reads these identification and cluster controls after writing + * them. Returning zero preserves the reset state without claiming that + * QEMU implements the associated cache or coherency controls. + */ + { .name =3D "E2000_CPUID_CTL1", .state =3D ARM_CP_STATE_AA64, + .opc0 =3D 3, .opc1 =3D 1, .crn =3D 15, .crm =3D 1, .opc2 =3D 0, + .access =3D PL1_RW, .type =3D ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue =3D 0 }, + { .name =3D "E2000_CLUSTER_CTL", .state =3D ARM_CP_STATE_AA64, + .opc0 =3D 3, .opc1 =3D 1, .crn =3D 11, .crm =3D 8, .opc2 =3D 6, + .access =3D PL1_RW, .type =3D ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue =3D 0 }, + /* + * The remaining controls are only programmed as part of firmware setu= p. + * Accept the writes without retaining state because no modeled CPU + * behavior depends on their values. + */ + { .name =3D "E2000_EL1_CTL", .state =3D ARM_CP_STATE_AA64, + .opc0 =3D 3, .opc1 =3D 2, .crn =3D 15, .crm =3D 15, .opc2 =3D 0, + .access =3D PL1_RW, .type =3D ARM_CP_NOP | ARM_CP_NO_RAW }, + { .name =3D "E2000_EL2_CTL", .state =3D ARM_CP_STATE_AA64, + .opc0 =3D 3, .opc1 =3D 4, .crn =3D 15, .crm =3D 15, .opc2 =3D 0, + .access =3D PL2_RW, .type =3D ARM_CP_NOP | ARM_CP_NO_RAW }, + { .name =3D "E2000_EL2_CTL2", .state =3D ARM_CP_STATE_AA64, + .opc0 =3D 3, .opc1 =3D 4, .crn =3D 15, .crm =3D 2, .opc2 =3D 4, + .access =3D PL2_RW, .type =3D ARM_CP_NOP | ARM_CP_NO_RAW }, + { .name =3D "E2000_EL3_CTL", .state =3D ARM_CP_STATE_AA64, + .opc0 =3D 3, .opc1 =3D 6, .crn =3D 15, .crm =3D 15, .opc2 =3D 0, + .access =3D PL3_RW, .type =3D ARM_CP_NOP | ARM_CP_NO_RAW }, +}; + +/* + * Use the Cortex-A72 execution model as the common E2000 TCG base, then + * replace the architected identity fields that differ between the two + * physical core types. + */ +static void aarch64_phytium_e2000_base_initfn(Object *obj) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + + aarch64_a72_initfn(obj); + define_arm_cp_regs(cpu, phytium_e2000_cp_reginfo); +} + +static void aarch64_phytium_ftc310_initfn(Object *obj) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + ARMISARegisters *isar =3D &cpu->isar; + + aarch64_phytium_e2000_base_initfn(obj); + + /* FTC310 cores identify with the FTC303 part number */ + cpu->dtb_compatible =3D "phytium,ftc310"; + cpu->midr =3D 0x700f3034; + SET_IDREG(isar, ID_AA64ISAR0, 0x00011100012120); + cpu->isar.mvfr0 =3D 0x10110222; + cpu->ctr =3D FIELD_DP64(cpu->ctr, CTR_EL0, L1IP, 2); /* VIPT */ +} + +static void aarch64_phytium_ftc664_initfn(Object *obj) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + ARMISARegisters *isar =3D &cpu->isar; + + aarch64_phytium_e2000_base_initfn(obj); + + cpu->dtb_compatible =3D "phytium,ftc664"; + cpu->midr =3D 0x701f6643; + SET_IDREG(isar, ID_AA64ISAR0, 0x00000100012120); + cpu->isar.mvfr0 =3D 0x10111222; + cpu->ctr =3D FIELD_DP64(cpu->ctr, CTR_EL0, L1IP, 3); /* PIPT */ +} + static void aarch64_a76_initfn(Object *obj) { ARMCPU *cpu =3D ARM_CPU(obj); @@ -1533,6 +1612,8 @@ static const ARMCPUInfo aarch64_cpus[] =3D { { .name =3D "cortex-a55", .initfn =3D aarch64_a55_initfn }, { .name =3D "cortex-a72", .initfn =3D aarch64_a72_initfn }, { .name =3D "cortex-a76", .initfn =3D aarch64_a76_initfn }, + { .name =3D "phytium-ftc310", .initfn =3D aarch64_phytium_ftc310_i= nitfn }, + { .name =3D "phytium-ftc664", .initfn =3D aarch64_phytium_ftc664_i= nitfn }, /* * The Cortex-A78AE differs slightly from the plain Cortex-A78. We don= 't * currently model the latter. --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434813; cv=pass; d=zohomail.com; s=zohoarc; b=M87vJMJSAu7047HJ3ShrDvU7ohKOjbzTJthy/0q2uJ2ho6GFQ9UfPyM/igbZTwLOTfntxEyylwEh9C+Vcoc6BJjf0cy5OUPN6b1LTxMZVQaQdcMdpBpQez92C1RSanIR9TL9MPTsqNKKhru4Z0Jrkwf4KFQaWN7Vipoxfe/b8n4= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434813; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=XX96mZt1R/wbnG4n+EbhSsTnbIITaxhh65tuvEiD1XI=; b=EsZFqGEdd1GJm8noilDN8fpvY/3v3IpxMZXJemXKOmyNynX5AKQJJqAS6J0JjWY5bNZHI/IpFYRha5XmLrts7Qi+udbRcW5RDztqftcv77KUlaJLQbN0ffyk6Y9gEPeuic7YQzvdfLI1EnKaL8NO6ty1xQIe7ANM1EySH9AXPOA= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434813591557.4765859008924; Thu, 3 Sep 2026 04:26:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25a9-0005Ut-GP; Thu, 03 Sep 2026 07:26:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a7-0005To-MX; Thu, 03 Sep 2026 07:26:11 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a5-0006gK-0M; Thu, 03 Sep 2026 07:26:11 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:25:55 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:25:55 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=tpMOWse5/rcTlopzSpVHNLr6zBitJbXknLKYsJV6CTJjEO1vf1/Wri+V9ngn+Gflzm9KUe/OAjBU9boOr40jkFXkQ4QUZhAFQZHCcLUmLLtBsn/r879GfmxK8mO8wAZbrckZtkp7XT+G5BUZVTgtLunTiVG/tnTgyA2StPYGL0l9KNJFOpHQY875LrLCbM9LZuv7BYa/JCAEDz5pSmSoOcYLIIWAcpvshgh6pZhRty7js0RbYu1WHb21JgzU1XuSWa7Oh4RUo7bIU2iyuUkgxg0GJpWLzmoyulYTIDwqN2Wpj4ZpDZK5XHC2QEqwbrmJePq9Oyh/n+16MigyD+mEAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=XX96mZt1R/wbnG4n+EbhSsTnbIITaxhh65tuvEiD1XI=; b=qbubApfI2+lB6ZjzJOBSmremGYppviorDbNSupCzDY4ej5ptPliqFiC5UAra1ADB/8ps7N5/7akfjB8M+Ur8sWfwfjv3dWyJMo+hEGldEe0nzHRVg6VT+E3pRNePJYgQxudOiHjDKh9nMCPrdaPF3y/dK5sGLBrmArYHY6lTEB0aWBsh5TX3QRvfhjmOzcX2hSJADH/avVz+qJznJ39YqoMCQWqzn0LHaYNx6tX8+FZWaskECK30kd6gX2HW6y/eNaVr7etOuHTn19tgB5iZuIp0BbyNPow/dPzQ+U5WY98szJbE4vUi3t3vrGxnkEIVY323K9HGFoDeaWhd0Wk7Og== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XX96mZt1R/wbnG4n+EbhSsTnbIITaxhh65tuvEiD1XI=; b=ABi3aZKAnOzX9szRniW9VD1FFXqnuMmLj0EMuSkAu8WLsfVAUwhV15srIf0seGTRSopQoDSkSKr54tZBswCRwazHzI7kcyB4MwqvNOm67UATHkCda8h0IVqu08ee6oNb80BgvzkShEBAlU5Kejq1A6J/PsO8BtXCk9HeIkVswbkrcmq9jq5y/9d9jZzE9OZmabzAsYrejHFR7DguhrcuKWTwGgBJkmwQNVJ4Q0+jKqkpXaR9eevZWk13JwaBVfJBngT84RtC0Q8EzimlRNsamH1S1k87JoougF5LLJxLLGyrk3QBQop9nANLmbQCHiZjnG47oOCcuEbIYsERk7OeuA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Paolo Bonzini , Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 02/33] hw/arm: Add basic Phytium Pi machine Date: Thu, 3 Sep 2026 19:24:42 +0800 Message-ID: <20260903112532.3276678-3-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: c63ae4d6-9e0d-47c7-6678-08df09ae1e94 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: 6Ik0S8q/johx/09bGvmFuwASZ4HFTmvPRW67XKx8yZkjUjHTxV1BF17ZORBeLlCmDwUzjmErhjNVYDMdo7fQd4+iWMpzTDl5PWTqZuQ2x8u3bhnDUGr/+jRRKZhmLeSwiyx4FqQt5bXV8pUH8tqT4W8/B1DypLJlHFJlmJQodxyyzS1Oh2WWJEKfRFKldQlktaUAxo+gOzTVoRGPQKbjNdboh/zgdLCaYvNzObs8ktkLw4QZ8nqbppMpF5RsPMKnnj9qdCvJX8En6PQZYEuXTJVx33LjK75OjjS1Dr3XUCRCDeKTIqA0bIWx/hYwResKZYRKwIIZAIFr1yAWuP5JOlYvbZ4AHhWwCJfJrXr76jx0y7u22l6FjMICfZTYeZtqPiT5fuhbh0VTDpJDFPnJ7CxG9HmPjOWqi0BSqfOoDYMME6u7ilqLd/oxpftN2Qm4u5Rdw6FayaWqlG+iiMFolF61GbVBGW32jo2GSsZx+jbahD4HHbxrD0kUVxLCxnYg3WOMMa6tTHx/l2z59gApgqArv22z2eROjlgwhWhFOcBnT/ZjRsQLcZvewNpvR9i16PxTyBosi9Sy+TuKJRM4DW9NvT5jJPkzwm2EuBKELVsuBpBFVNxd3ivnAg0ARO3s3k0jdizKzcJyWxv4pxoADpjAsqiCouZ26aznJ5ofQN0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?9u5/3S7jbp6oeW2LyNiOjkE8GoLZBo3XekidnyweHKWwkDgR8UGJrcYPMHmt?= =?us-ascii?Q?eQ23jGUD25fcMG6tucF+tve1nTPXystNv69zYrTsbV6Q6zcn2sMBWhdYsxuN?= =?us-ascii?Q?EVT+qdMl5zakMv4XK49gj/HIaTVIBjU4msQGY7D3eiz3NRpWDTeu/CpJLzRr?= =?us-ascii?Q?hdCX2/QLWs6v4eSAkka1OqgyRy0fA7WJXIKkvqV343MdIle7nlC/JNaxYu1B?= =?us-ascii?Q?Z59WUqCz4AHuEfWXgw6LzN/GRLLT0CkvodVowJ0TVNoCliHCSd4d9o2PATVg?= =?us-ascii?Q?QKyBDn3nYDFcBie0+dA9b+40RtLuL8ox5kOctYBNxalt0yjjQsjW+npAa349?= =?us-ascii?Q?PoGqrElIi8F0IbJXIgXtrmwK9pDfEKYkmmuag8Ts7q9WgebVGHB3AUKjkN8n?= =?us-ascii?Q?+NIT6bs0dP/qEAyi06btsCqYuKtRrvsdKKyaJf95BZJpx2is2UoHNs2zmV9+?= =?us-ascii?Q?AOyeqBksELyoVhcWxHRexcXDUtRadkTJ2tLFtSTC3e57VMTo4ooWx6VOtjt3?= =?us-ascii?Q?ed1uMlo86x5tsu2Ps5QjFI9dWwFmQZ607ANdBC2Zs+J4A5VGvqWn06rwO+MM?= =?us-ascii?Q?hr5NRGu8PgY1G+rGHeEiAZo3PoCZrk2UczzNCvh4OnRvVpUyYkMVkZsUGXcb?= =?us-ascii?Q?LNahRNgG7TYhMxNGnJCGIxxO3dkJHnocWr0YOwj9XX6i3bFf6BHTuRzrZ32j?= =?us-ascii?Q?LbBQ4kc/R7vrVMZKmxZzIozC9KaxpOx9AclzadYmmNLhY9a3AwQq1RSvNCdS?= =?us-ascii?Q?1B+NbTk4EKuKdJWOJSEkOW/FYEX+Pbc+f/nrNiYUvht8319J8irJ5Sdja0L8?= =?us-ascii?Q?8KxuNzxH/d+P+YCx1fWFyqnYhnvQbZSvMLyy9M9TlTItTY3ntaT/In7VYAjg?= =?us-ascii?Q?xOb1aQWM03BeFsqy7lnCjxfAbl+IQj0tIqgZ7t0xoGLkdxa8INq5V48UhDd9?= =?us-ascii?Q?i9i+6QM1mtXVwFyr/bX/dm2ZHyPQw5x9OppW3/uScKGEtxUOR0VYk06WQ3bA?= =?us-ascii?Q?Ri4Bvd7O1qg+8AHrQA4w1E6Qq2AaTZodhJ3hhB94XkeKnEpFwddRSAlOxuVH?= =?us-ascii?Q?neFvGsEsw/mra2WAE8eG2Yjo99hdaFeEnup09NzZZeYND130mnKxZs9UHZjT?= =?us-ascii?Q?G5O57TLukneqwmAh+4Etn0FbHnsOqvk5GMBIwkKJYax6L6BtX2Wfoetunurk?= =?us-ascii?Q?5CqcAM5cIj2ThTs/PVOOi/WWUbVqrgAYIx05LDRr+6BlKw5D7o8hL2SPnrrf?= =?us-ascii?Q?iXm6VwvuNC380SvhYpJDtHY6qzA25fJ54v4iCyimviejpvNNkESwDV/WFNl1?= =?us-ascii?Q?/MfKGsV7BO6jGxK2qBahsGPWfV3iJCOXTQQgbgyKb/sT2a0dJI/EuOOIsOel?= =?us-ascii?Q?ocTzTCw6FdlSmLGxH0KKCgGTaArSYdjnMql+dgxWRQ60NjulBLZWz3jEPYFY?= =?us-ascii?Q?Ppp4PluP1yVG4kPFQdCLDXSjeQCUrOhQ9BYz9X4ujeF1MDk4CG3vqL9Hfskg?= =?us-ascii?Q?SkcfrN40Xxldt0MCJiCMmckCfU82IL/Fx58Y0IeZbShyOaDcA3rbim090Iy9?= =?us-ascii?Q?7kTlaOJemnpTy4XLvo0PZombo+lOqjE0gNKeB4PSbef/8Lx4vO4SmwgltCfo?= =?us-ascii?Q?uZFjmUoOmTrc8BM0Bu4awlKcltVsyE9giyv4cnjseOWr6xxn2ri0N9wfM5qM?= =?us-ascii?Q?rwrEwaAGgD0B2eFThzhjx878ypMOqYG2EuSRtjHBStmNDkNqXg9vvZxYrBWe?= =?us-ascii?Q?axFn8IeMu1h03PDuqIvugnPUWU6wGfc=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: c63ae4d6-9e0d-47c7-6678-08df09ae1e94 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:25:55.3312 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: lNA4mgvNtPcgPSW999ROfQr0rDbkJHT430SIW0012KmKh9/wL+Z/XwLcH53+A1eA3GrYCF7IVwVNnoSg/aXa+VHu2bCQTric3OODIPkaUzc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434817155158500 Content-Type: text/plain; charset="utf-8" Add the base topology for the Phytium Pi board built around the E2000Q SoC, with two FTC310 and two FTC664 CPUs, RAM, GICv3/ITS, and PL011 UARTs. Describe the CPUs as three non-uniform clusters matching the vendor Linux device tree. Preserve the board CPU slot order so firmware MPIDR 0x200 maps to QEMU CPU index 2. Signed-off-by: Bin Meng Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/arm/Kconfig | 8 + hw/arm/meson.build | 1 + hw/arm/phytium_e2000.c | 406 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 hw/arm/phytium_e2000.c diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 5db7ce057f..20863b5847 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -126,6 +126,14 @@ config OMAP select SD select SERIAL_MM =20 +config PHYTIUM_E2000 + bool + default y + depends on TCG && AARCH64 + select ARM_GIC + select PL011 + select UNIMP + config REALVIEW bool default y diff --git a/hw/arm/meson.build b/hw/arm/meson.build index 78acb04c8b..6f685b414d 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -10,6 +10,7 @@ arm_common_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: = files('netduinoplus2.c' arm_common_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex= -stm32-h405.c')) arm_common_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npc= m7xx_boards.c')) arm_common_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c', 'npc= m8xx_boards.c')) +arm_common_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2= 000.c')) arm_common_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c')) arm_common_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c')) arm_common_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c')) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c new file mode 100644 index 0000000000..defc265a5d --- /dev/null +++ b/hw/arm/phytium_e2000.c @@ -0,0 +1,406 @@ +/* + * Phytium E2000 board models + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "system/address-spaces.h" +#include "system/kvm.h" +#include "system/system.h" +#include "exec/hwaddr.h" +#include "hw/arm/boot.h" +#include "hw/arm/bsa.h" +#include "hw/arm/machines-qom.h" +#include "hw/char/pl011.h" +#include "hw/core/boards.h" +#include "hw/core/qdev-properties.h" +#include "hw/intc/arm_gicv3_common.h" +#include "hw/intc/arm_gicv3_its_common.h" +#include "hw/misc/unimp.h" +#include "qobject/qlist.h" +#include "qom/object.h" +#include "target/arm/cpu.h" +#include "target/arm/cpu-qom.h" +#include "target/arm/gtimer.h" + +#define TYPE_PHYTIUM_PI MACHINE_TYPE_NAME("phytium-pi") +OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_PI) + +#define PHYTIUM_E2000_NUM_CPUS 4 +#define PHYTIUM_E2000_NUM_IRQS 256 + +#define PHYTIUM_E2000_NUM_UARTS 7 + +#define PHYTIUM_E2000_GTIMER_HZ 50000000 + +enum { + PHYTIUM_E2000_LOW_PERIPH, + PHYTIUM_E2000_UART0, + PHYTIUM_E2000_UART1, + PHYTIUM_E2000_UART2, + PHYTIUM_E2000_UART3, + PHYTIUM_E2000_UART4, + PHYTIUM_E2000_UART5, + PHYTIUM_E2000_UART6, + PHYTIUM_E2000_GIC_DIST, + PHYTIUM_E2000_GIC_ITS, + PHYTIUM_E2000_GIC_REDIST, + PHYTIUM_E2000_BOOT_SRAM, + PHYTIUM_E2000_BOARD_CTRL, + PHYTIUM_E2000_BOOT_IACC, + PHYTIUM_E2000_RAM, + PHYTIUM_E2000_RAM_HIGH, +}; + +struct PhytiumE2000State { + MachineState parent; + struct arm_boot_info bootinfo; + DeviceState *gic; + MemoryRegion ram_low; + MemoryRegion ram_high; +}; + +/* + * Keep the physical addresses used by the vendor firmware even before eve= ry + * device behind them is modeled. In particular, boot SRAM carries PBR/PBF + * handoff data and IACC is the fixed execution window for system firmware. + */ +static const MemMapEntry phytium_e2000_memmap[] =3D { + [PHYTIUM_E2000_LOW_PERIPH] =3D { 0x28000000, 0x00100000 }, + [PHYTIUM_E2000_UART0] =3D { 0x2800c000, 0x00001000 }, + [PHYTIUM_E2000_UART1] =3D { 0x2800d000, 0x00001000 }, + [PHYTIUM_E2000_UART2] =3D { 0x2800e000, 0x00001000 }, + [PHYTIUM_E2000_UART3] =3D { 0x2800f000, 0x00001000 }, + [PHYTIUM_E2000_UART4] =3D { 0x28014000, 0x00001000 }, + [PHYTIUM_E2000_UART5] =3D { 0x2802a000, 0x00001000 }, + [PHYTIUM_E2000_UART6] =3D { 0x28032000, 0x00001000 }, + [PHYTIUM_E2000_GIC_DIST] =3D { 0x30800000, 0x00020000 }, + [PHYTIUM_E2000_GIC_ITS] =3D { 0x30820000, 0x00020000 }, + [PHYTIUM_E2000_GIC_REDIST] =3D { 0x30880000, 0x00080000 }, + [PHYTIUM_E2000_BOOT_SRAM] =3D { 0x30c00000, 0x00100000 }, + [PHYTIUM_E2000_BOARD_CTRL] =3D { 0x31800000, 0x01400000 }, + [PHYTIUM_E2000_BOOT_IACC] =3D { 0x38000000, 0x08000000 }, + [PHYTIUM_E2000_RAM] =3D { 0x80000000, 0x80000000 }, + [PHYTIUM_E2000_RAM_HIGH] =3D { 0x2000000000ULL, 0x180000000ULL }, +}; + +static const int phytium_e2000_uart_irqmap[] =3D { + [0] =3D 83, + [1] =3D 84, + [2] =3D 85, + [3] =3D 86, + [4] =3D 92, + [5] =3D 103, + [6] =3D 107, +}; + +typedef struct PhytiumE2000CPUConfig { + const char *type; + uint64_t mp_affinity; + int64_t cluster_id; + int64_t core_id; +} PhytiumE2000CPUConfig; + +static const PhytiumE2000CPUConfig +phytium_e2000_cpu_config[PHYTIUM_E2000_NUM_CPUS] =3D { + { + .type =3D ARM_CPU_TYPE_NAME("phytium-ftc664"), + .mp_affinity =3D 0x000, + .cluster_id =3D 0, + .core_id =3D 0, + }, + { + .type =3D ARM_CPU_TYPE_NAME("phytium-ftc664"), + .mp_affinity =3D 0x100, + .cluster_id =3D 1, + .core_id =3D 0, + }, + { + .type =3D ARM_CPU_TYPE_NAME("phytium-ftc310"), + .mp_affinity =3D 0x200, + .cluster_id =3D 2, + .core_id =3D 0, + }, + { + .type =3D ARM_CPU_TYPE_NAME("phytium-ftc310"), + .mp_affinity =3D 0x201, + .cluster_id =3D 2, + .core_id =3D 1, + }, +}; + +static void phytium_e2000_create_its(PhytiumE2000State *s) +{ + DeviceState *dev =3D qdev_new(its_class_name()); + + object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(s->gic), + &error_abort); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, + phytium_e2000_memmap[PHYTIUM_E2000_GIC_ITS].base); +} + +static void phytium_e2000_create_gic(PhytiumE2000State *s) +{ + MachineState *ms =3D MACHINE(s); + SysBusDevice *gicbusdev; + QList *redist_region_count; + int i; + + s->gic =3D qdev_new(gicv3_class_name()); + qdev_prop_set_uint32(s->gic, "revision", 3); + qdev_prop_set_uint32(s->gic, "num-cpu", ms->smp.cpus); + qdev_prop_set_uint32(s->gic, "num-irq", PHYTIUM_E2000_NUM_IRQS + 32); + qdev_prop_set_bit(s->gic, "has-security-extensions", true); + qdev_prop_set_bit(s->gic, "has-lpi", true); + + redist_region_count =3D qlist_new(); + qlist_append_int(redist_region_count, ms->smp.cpus); + qdev_prop_set_array(s->gic, "redist-region-count", redist_region_count= ); + + object_property_set_link(OBJECT(s->gic), "sysmem", + OBJECT(get_system_memory()), &error_fatal); + + gicbusdev =3D SYS_BUS_DEVICE(s->gic); + sysbus_realize_and_unref(gicbusdev, &error_fatal); + sysbus_mmio_map(gicbusdev, 0, + phytium_e2000_memmap[PHYTIUM_E2000_GIC_DIST].base); + sysbus_mmio_map(gicbusdev, 1, + phytium_e2000_memmap[PHYTIUM_E2000_GIC_REDIST].base); + + for (i =3D 0; i < ms->smp.cpus; i++) { + DeviceState *cpudev =3D DEVICE(qemu_get_cpu(i)); + int intidbase =3D PHYTIUM_E2000_NUM_IRQS + i * GIC_INTERNAL; + static const int timer_irq[] =3D { + [GTIMER_PHYS] =3D ARCH_TIMER_NS_EL1_IRQ, + [GTIMER_VIRT] =3D ARCH_TIMER_VIRT_IRQ, + [GTIMER_HYP] =3D ARCH_TIMER_NS_EL2_IRQ, + [GTIMER_SEC] =3D ARCH_TIMER_S_EL1_IRQ, + }; + + for (int irq =3D 0; irq < ARRAY_SIZE(timer_irq); irq++) { + qdev_connect_gpio_out(cpudev, irq, + qdev_get_gpio_in(s->gic, intidbase + timer_irq[irq])); + } + qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",= 0, + qdev_get_gpio_in(s->gic, intidbase + ARCH_GIC_MAINT_IRQ)); + qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, + qdev_get_gpio_in(s->gic, intidbase + VIRTUAL_PMU_IRQ)); + + sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_= IRQ)); + sysbus_connect_irq(gicbusdev, i + ms->smp.cpus, + qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); + sysbus_connect_irq(gicbusdev, i + 2 * ms->smp.cpus, + qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); + sysbus_connect_irq(gicbusdev, i + 3 * ms->smp.cpus, + qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); + } + + phytium_e2000_create_its(s); +} + +static void phytium_e2000_create_uart(PhytiumE2000State *s, int index) +{ + int map_idx =3D PHYTIUM_E2000_UART0 + index; + DeviceState *dev =3D qdev_new(TYPE_PL011); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + + qdev_prop_set_chr(dev, "chardev", serial_hd(index)); + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map(sbd, 0, phytium_e2000_memmap[map_idx].base); + sysbus_connect_irq(sbd, 0, + qdev_get_gpio_in(s->gic, phytium_e2000_uart_irqmap[index])); +} + +static void phytium_e2000_create_unimplemented(void) +{ + /* + * Preserve the SoC address map while individual boot-critical devices= are + * introduced. More specific devices may overlap these low-priority + * catch-all regions without silently accepting accesses elsewhere. + */ + create_unimplemented_device( + "phytium-e2000.low-peripheral", + phytium_e2000_memmap[PHYTIUM_E2000_LOW_PERIPH].base, + phytium_e2000_memmap[PHYTIUM_E2000_LOW_PERIPH].size); + create_unimplemented_device( + "phytium-e2000.board-control", + phytium_e2000_memmap[PHYTIUM_E2000_BOARD_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_BOARD_CTRL].size); +} + +static void phytium_e2000_create_ram(PhytiumE2000State *s) +{ + MachineState *ms =3D MACHINE(s); + uint64_t low_size =3D + MIN(ms->ram_size, phytium_e2000_memmap[PHYTIUM_E2000_RAM].size); + uint64_t high_size =3D ms->ram_size - low_size; + + /* + * Keep the machine RAMBlock contiguous for migration, but expose it in + * the two physical windows implemented by E2000. The high alias resum= es + * at low_size, so the intervening PCIe hole consumes no guest RAM. + */ + memory_region_init_alias(&s->ram_low, OBJECT(s), + "phytium-e2000.ram-low", ms->ram, 0, low_size); + memory_region_add_subregion(get_system_memory(), + phytium_e2000_memmap[PHYTIUM_E2000_RAM].base, &s->ram_low); + + if (!high_size) { + return; + } + + memory_region_init_alias(&s->ram_high, OBJECT(s), + "phytium-e2000.ram-high", ms->ram, low_size, high_size); + memory_region_add_subregion(get_system_memory(), + phytium_e2000_memmap[PHYTIUM_E2000_RAM_HIGH].base, &s->ram_high); +} + +static void phytium_e2000_create_cpus(PhytiumE2000State *s) +{ + MachineState *ms =3D MACHINE(s); + const CPUArchIdList *possible_cpus; + int i; + + possible_cpus =3D MACHINE_GET_CLASS(ms)->possible_cpu_arch_ids(ms); + + for (i =3D 0; i < ms->smp.cpus; i++) { + Object *cpuobj =3D object_new(possible_cpus->cpus[i].type); + CPUState *cs; + + object_property_set_int(cpuobj, "mp-affinity", + possible_cpus->cpus[i].arch_id, + &error_abort); + object_property_set_int(cpuobj, "cntfrq", PHYTIUM_E2000_GTIMER_HZ, + &error_abort); + if (object_property_find(cpuobj, "has_el3")) { + /* + * The generic-loader U-Boot path starts after the EL3 firmware + * stages that normally provide the Phytium SMC services. + */ + object_property_set_bool(cpuobj, "has_el3", false, &error_abor= t); + } + object_property_set_link(cpuobj, "memory", OBJECT(get_system_memor= y()), + &error_abort); + cs =3D CPU(cpuobj); + cs->cpu_index =3D i; + qdev_realize(DEVICE(cpuobj), NULL, &error_fatal); + object_unref(cpuobj); + } +} + +static void phytium_pi_init(MachineState *ms) +{ + PhytiumE2000State *s =3D PHYTIUM_PI(ms); + int i; + + if (kvm_enabled()) { + error_report("phytium-pi: KVM is not supported"); + exit(1); + } + + if (ms->smp.cpus > PHYTIUM_E2000_NUM_CPUS) { + error_report("phytium-pi supports at most %d CPUs", + PHYTIUM_E2000_NUM_CPUS); + exit(1); + } + + if (ms->ram_size > + phytium_e2000_memmap[PHYTIUM_E2000_RAM].size + + phytium_e2000_memmap[PHYTIUM_E2000_RAM_HIGH].size) { + error_report("phytium-pi supports at most 8 GiB RAM"); + exit(1); + } + + phytium_e2000_create_ram(s); + phytium_e2000_create_unimplemented(); + + phytium_e2000_create_cpus(s); + phytium_e2000_create_gic(s); + + for (i =3D 0; i < PHYTIUM_E2000_NUM_UARTS; i++) { + phytium_e2000_create_uart(s, i); + } + + s->bootinfo.ram_size =3D ms->ram_size; + s->bootinfo.board_id =3D -1; + s->bootinfo.loader_start =3D phytium_e2000_memmap[PHYTIUM_E2000_RAM].b= ase; + s->bootinfo.psci_conduit =3D QEMU_PSCI_CONDUIT_SMC; + s->bootinfo.firmware_loaded =3D false; + arm_load_kernel(ARM_CPU(first_cpu), ms, &s->bootinfo); +} + +static const CPUArchIdList *phytium_e2000_possible_cpu_arch_ids(MachineSta= te *ms) +{ + int i; + + if (ms->possible_cpus) { + return ms->possible_cpus; + } + + ms->possible_cpus =3D g_malloc0(sizeof(CPUArchIdList) + + sizeof(CPUArchId) * ms->smp.max_cpus); + ms->possible_cpus->len =3D ms->smp.max_cpus; + + for (i =3D 0; i < ms->possible_cpus->len; i++) { + const PhytiumE2000CPUConfig *config =3D &phytium_e2000_cpu_config[= i]; + + ms->possible_cpus->cpus[i].type =3D config->type; + ms->possible_cpus->cpus[i].arch_id =3D config->mp_affinity; + ms->possible_cpus->cpus[i].props.has_cluster_id =3D true; + ms->possible_cpus->cpus[i].props.cluster_id =3D config->cluster_id; + ms->possible_cpus->cpus[i].props.has_core_id =3D true; + ms->possible_cpus->cpus[i].props.core_id =3D config->core_id; + ms->possible_cpus->cpus[i].props.has_thread_id =3D true; + ms->possible_cpus->cpus[i].props.thread_id =3D 0; + } + + return ms->possible_cpus; +} + +static void phytium_pi_class_init(ObjectClass *oc, const void *data) +{ + MachineClass *mc =3D MACHINE_CLASS(oc); + static const char * const valid_cpu_types[] =3D { + /* The machine assigns the FTC310 slots independently */ + ARM_CPU_TYPE_NAME("phytium-ftc664"), + NULL, + }; + + mc->init =3D phytium_pi_init; + mc->desc =3D "Phytium Pi board (Phytium E2000Q)"; + mc->default_cpu_type =3D ARM_CPU_TYPE_NAME("phytium-ftc664"); + mc->valid_cpu_types =3D valid_cpu_types; + mc->max_cpus =3D PHYTIUM_E2000_NUM_CPUS; + mc->default_cpus =3D PHYTIUM_E2000_NUM_CPUS; + mc->default_ram_size =3D 1 * GiB; + mc->default_ram_id =3D "phytium-e2000.ram"; + mc->minimum_page_bits =3D 12; + mc->block_default_type =3D IF_SD; + mc->no_cdrom =3D 1; + mc->possible_cpu_arch_ids =3D phytium_e2000_possible_cpu_arch_ids; +} + +static const TypeInfo phytium_pi_info =3D { + .name =3D TYPE_PHYTIUM_PI, + .parent =3D TYPE_MACHINE, + .class_init =3D phytium_pi_class_init, + .instance_size =3D sizeof(PhytiumE2000State), + .interfaces =3D aarch64_machine_interfaces, +}; + +static void phytium_pi_machine_init(void) +{ + type_register_static(&phytium_pi_info); +} + +type_init(phytium_pi_machine_init); --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434814; cv=pass; d=zohomail.com; s=zohoarc; b=JzYhHlbo5NofY4Mbd2VMvhY+U6aWvwu1YMxOsr6wL3Dokp+7hnTL47/i3CR6NC3W0soLNn9Y/Bg2YFeSrrRcmtCic55OF2X19F/ydFjbkokSxicUdN+YC2LpQzwW6CPPqgpoQrcdB+aVefs2c8mMcqupGy/+7t3tVqKAU7VA5Ro= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434814; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gs8i7lnDNzaOhIBGDLGDuLdsJvjxFRUwbju3AA6pexw=; b=nkdCOB8wTZp51vLm5BwgR7b6HHcGdhrOE+DAlFHuUt+gqZ1sadvZAzTdJusv11qdXvZbxJJwo27MpFYa52XgRpeZLRbsbDVV7FiznjSBPVyZvW6CoBSmP7LUZkB48WEp0FQGY1aqiimoYbXGlYejlj7bFAAR9bV1quAHfY+1zAw= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434813796949.2865470181657; Thu, 3 Sep 2026 04:26:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25a7-0005Tr-SL; Thu, 03 Sep 2026 07:26:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a7-0005Tb-04; Thu, 03 Sep 2026 07:26:11 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a4-0006f9-U8; Thu, 03 Sep 2026 07:26:10 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:25:57 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:25:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=uMt+NNaHxhN1vZ9Widn6x7EEkeLgPXaCx83w0B/ANfYsDSoci5HnDriZxkjISnZtTNKa/7VD/ivXjOvEyX9UjxDCZ1bX4oHt46e6BpMTj3U43fomUHvCNSrjw8jAohevxDxTAcJlrr1N+EeaQufB3uXTZTIJositY09XA5kyJHYomQhWtU3rD64sVAkMz/5rZ0B6gHyKbmLouxpmdji3xiqCw0Uv7Jp2CfAKNzvxLS0x+wz7ggm1xVA1Yg4Mcd/ZDGDRnJzuecCXgf27Gq+3ioxdf00h3B9ohhG267s2hbR5PrkyCxzgMXTsjHoNkL5oIXKK19dMlsxjNBhDv7lnAg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gs8i7lnDNzaOhIBGDLGDuLdsJvjxFRUwbju3AA6pexw=; b=X1GDLRY1ZBgDJSc0bFRcdBy5Ox7SimjqKLKE+8AL5mVaC33XY00sHoEQcPOaq73hGAj+Zn1TNC07/80QYV6x0ybLQBFo86lrBBhI9bKoaKBrWnSbHCy0COLEVFbu39ugUeROrveVMBo9cZ6/lXoRStZpBAiBTxtqX7JQ3Ntaj3BBY6L1vBiTwQU7j6KDmJm+cTeiX6bU3gW86ab/Qvnc7uwLnq6j9f7ykSqKpn1jU3MMoW36DSTd7kc4HNbDgqkUTeIRvXNp59sFi//SOBYDQvCDQCZgkbITuEB9Qxo9vZH/foJdj0lqje9ynuDmQTAGk7fdc4Ubg+XyB7a6sRaxww== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gs8i7lnDNzaOhIBGDLGDuLdsJvjxFRUwbju3AA6pexw=; b=O9i4i92AkMhhPW8zjZLB3nMV1uujCaOhoQQF4LPqLumcmBJJvfXNgP7EPqGz/1dgllw7wPcD+JrmsR5KodXqTkYd9PgoZDXZlE36LYZGOI8EzWbLKZO3f1x/4yiysxg21WZVHewU6nnP7vaF9dN2jimTE7bF4x2D68k3Q30zASe6H4BskZN7+pPDa/jqpos2xR0UG+iPAMGltH1empbpkFY3md3EIFscZ+lXYcOWLnwp5XWx/4Q+mHoWnxva/sUtVscawRSMXWaSLINwoYm3t1ia5RsieJSPzXfxXn5QsLTsNFrX3VbKdfmJyWJwoUZJ8EZB7xDLAFR2oS8tGFgGfg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Paolo Bonzini , Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 03/33] hw/arm: phytium: Add Phytium E2000 PCIe host Date: Thu, 3 Sep 2026 19:24:43 +0800 Message-ID: <20260903112532.3276678-4-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 978bcbe5-bc0e-405c-d8c1-08df09ae1fbc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|5023799004|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: WpkLAY90whhNV1VNNvXUCIhurqbwelPDnennIsDZbzMEoPCOz86YrAgSEaKkauhuvyRtgmNBswBt+E0wsA4EZI0fp9hJ8Q7AxXYSCTqybNbWd4IpqJg5RoKtYxRwWcYBYIZhIRaqXMT+Mcmiy8kQtUulyQQYAGj9GhXtWZgWqjvfoH4ErIG/mq/RBvrPl4xbJjne5jloXfIzJHslcJ43DYAtqqAaiWzUN4kS0DLa+rwUqtlunxtc+Ir+Tlex9VhKCIImGAuqYfKDSd+jZdt+28VjK7/+hZTkC36J2TUOFQ3aAEjqeljb8pfGrKyzeUGbuoRwjjK+Rzx44T36QEjf8rvqEyyMTWZ+Y25NL/qM5zcBuOc+VRbOx9JdsGX6gqOsH+HVCpBqpC5ySEmPmVPe4dO7R4nG8MYcTZdcvP5ApU+PJ3AhMIt8jvFroWyWzTYh/KTfjOSDYsfDcKV1ArfacoXx1hferZKyxLkdJ90SpIPccn6ZF/vHa6ilB5IMou8aHcxZrYeqNZf3tarIE8yKofynveFByi2jj5fdcDvq4/m0ykfJeoH+KYtPGOu+FI0MIL3haPHlFSSJFkW3cAWr7tEIfQHbyBvEt0U4HOTDcMszf7J3NI+XGio4KYOIHK2syCU9AJy9vboH/TQ6DmY4/GwNpYKx/bDpj48Q8JGQBnA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(5023799004)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?SU5TU/4Bs01QuBNF2YumSjKgT0CP8d99vRQGXyHoDk5gfJny/E/5sHUchND6?= =?us-ascii?Q?JByBDv9ELLfa25/k6ysTx2o+aYiAYbnFn4K8PbkEeuyQiqKqxe5RV96GnMi1?= =?us-ascii?Q?fn5fN9rdKdjRqlawG6PoxmqNr7u/UluyrgMJJDDkMqOc89/YXVcbwoLK1KqW?= =?us-ascii?Q?5r+d5mMnhxYMfNsru4aCdpcvrFPAJ2OHf6YbXVCW7fEU8K1juD/ZbasBG7Z9?= =?us-ascii?Q?cHDSDX9kS0ie8v8cX/1POzDepBJJwVhjBqCkL//YfTEGHVQIyUwAKCNRf9ih?= =?us-ascii?Q?tNYnOcexd5ZvQQFVi4aJydtI+ruQBvMo4dDt8Beb75pbujlb+/MMlET5KWiZ?= =?us-ascii?Q?KmSgK3bykBP57J01v4Qdp7/3BPCQPCF7mGjXdQfKv3H57w/IKnJPH0Tf0Vzy?= =?us-ascii?Q?xiCD/Wo68T2hELEfCXqCvclqVXnX26ujvdKNmAVHbYg/voC9wd09TElvDthn?= =?us-ascii?Q?CRJj0jGRkm6kIru60r4BjA2c9nNjz3tFSesGoJDwLOUrnOzAnD88Y6MgahgZ?= =?us-ascii?Q?DRpD29kDqLwIus84zzjoLHEiur7jVs0WfHTG/KVrdnPk4QLsQLvrde2cWTa1?= =?us-ascii?Q?2F3rWVAnfDVWhcNMQIzRUrjZik/xfdg8Xa2b2FAoksEjf0X5IBuQl4ZrA9nf?= =?us-ascii?Q?V0+wPYX6AdlN3faDzTAmMa9zeGeq7bX0sChietnNXu3Vtu5/vKBRZzGNflJM?= =?us-ascii?Q?dLupAer2vDqg25411/UdbqhgCOPDckc6N0vMWUsP7SoNIdaf75FpJuwI3z/8?= =?us-ascii?Q?89wwSdMq59OgSeLH7J8nPMwh7WjxFhsXEUFsv2jqUik9JyYY3wFVaE9l1JSy?= =?us-ascii?Q?gZQ1Nt77afnei8g7sSAsVhRbRgu0r9K1Ql1IKi6wtVMc3+2EYb3PMYJx8EWw?= =?us-ascii?Q?rivurjM0OW1oFvZO4enIRSpRV1Y7soBGobYs8QpCRFp0u14UgvAx+8xQP8Go?= =?us-ascii?Q?5wlfwZF6uSaPXWmElsxV/JmMTHzUd9pZJlI7xVc0SqEd3q1XXh/+TA0GD2Pe?= =?us-ascii?Q?O0A7g1B+wosDJzECAs3emqSndAEyZ/v1e4DzggMUJYmKi6yRrq/neTrLPIeh?= =?us-ascii?Q?RiFN1bijFlVmgS58VhkNarWCPZUOdcbft5w9ZbINKHW79TDUGQwuLsKFtJEt?= =?us-ascii?Q?vAoiceaDfS66N5y8g3Y1uRohj+D4wfQqrmluGjW8SNhu3/NNGTDsGosb4Uzl?= =?us-ascii?Q?/kCgnT5/s34adjXIm+xC9ZkluAwyGFVtXUqiIJRp1QgUkAPGAR/0RnpK2J7E?= =?us-ascii?Q?RteIIr9sj+iMSqQ9eYcpjVg3rp0X1d3RS3cd7uuf0KOOPMiCJlFYF22b5lJ5?= =?us-ascii?Q?8RWx9D8hgWhaQ/j1b0iLQ3hM4veV6tLzi4LIQc9zS92xcBdAg/S7qig0zFIc?= =?us-ascii?Q?j1zonM8i503UA9IvYpXNYjfe5kKpLRrMrUq/DcD8Sy8LxNw0OLYihoPEOOQb?= =?us-ascii?Q?IZxtO+SWp1ok1EQBBy74KDlJvo27aY4EssuTiztegL6PGmnf1RBLuLXy8Yyd?= =?us-ascii?Q?WVcimYV/bvYbzYxiBfR6uQrbElQCxAm1v1gBvKImuOwZwDRqsfKRiNY+F9sk?= =?us-ascii?Q?lffA70Md8XWHnGXRRZ+KDpvxpLsroEBrxAp5pZOi1Vffzgg5u25Fukg7tBb/?= =?us-ascii?Q?yepTYKaZ1zVuvQXWUPsGNE21lB8bydqs2pwq+lvXeV7gTYOaOsA8Ou5cpprY?= =?us-ascii?Q?tL7k33rjOmW7DygP6knkl3WBSCrp4BABFaTP8ysBZvQFg9rfUlAhiQpbwQOY?= =?us-ascii?Q?dLwnQV+aQLgAWFvn/wHh9flxysQ6RtI=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 978bcbe5-bc0e-405c-d8c1-08df09ae1fbc X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:25:57.2757 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: oQUN48RrngzxxImHgkmT7srBGaFrPf+X1ucUJ5lPYQs7iUqaD7BiU7Yxwv1uMSzDv0ci6C79dERiSe/rvzwcRXiiY08hcEacw/t2Cvqso/U= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434817195158500 Content-Type: text/plain; charset="utf-8" Add the E2000 GPEX host with ECAM, PIO, and 32-bit and 64-bit MMIO windows. Connect MSI through the ITS and route the four INTx outputs to GIC SPI 4 through 7. The vendor device tree masks out the slot number and maps each interrupt pin directly to the corresponding SPI. Override the GPEX root-bus IRQ mapper so it selects an output solely by pin. Standard PCI-to-PCI bridge swizzling remains unchanged. Expose the SoC-specific PCIe port and PHY control apertures as low-priority unimplemented regions. Firmware programs these windows before enumerating ECAM, but their state does not affect the generic host bridge. Signed-off-by: Bin Meng --- hw/arm/Kconfig | 3 ++ hw/arm/phytium_e2000.c | 118 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 20863b5847..e68f137a66 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -130,7 +130,10 @@ config PHYTIUM_E2000 bool default y depends on TCG && AARCH64 + imply PCI_DEVICES select ARM_GIC + select PCI_EXPRESS + select PCI_EXPRESS_GENERIC_BRIDGE select PL011 select UNIMP =20 diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index defc265a5d..aac798aa07 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -26,6 +26,8 @@ #include "hw/intc/arm_gicv3_common.h" #include "hw/intc/arm_gicv3_its_common.h" #include "hw/misc/unimp.h" +#include "hw/pci/pci.h" +#include "hw/pci-host/gpex.h" #include "qobject/qlist.h" #include "qom/object.h" #include "target/arm/cpu.h" @@ -55,9 +57,15 @@ enum { PHYTIUM_E2000_GIC_ITS, PHYTIUM_E2000_GIC_REDIST, PHYTIUM_E2000_BOOT_SRAM, + PHYTIUM_E2000_PCIE_CTRL, + PHYTIUM_E2000_PCIE_PHY_CTRL, PHYTIUM_E2000_BOARD_CTRL, PHYTIUM_E2000_BOOT_IACC, + PHYTIUM_E2000_PCIE_ECAM, + PHYTIUM_E2000_PCIE_PIO, + PHYTIUM_E2000_PCIE_MMIO, PHYTIUM_E2000_RAM, + PHYTIUM_E2000_PCIE_MMIO_HIGH, PHYTIUM_E2000_RAM_HIGH, }; =20 @@ -87,9 +95,15 @@ static const MemMapEntry phytium_e2000_memmap[] =3D { [PHYTIUM_E2000_GIC_ITS] =3D { 0x30820000, 0x00020000 }, [PHYTIUM_E2000_GIC_REDIST] =3D { 0x30880000, 0x00080000 }, [PHYTIUM_E2000_BOOT_SRAM] =3D { 0x30c00000, 0x00100000 }, + [PHYTIUM_E2000_PCIE_CTRL] =3D { 0x31000000, 0x00200000 }, + [PHYTIUM_E2000_PCIE_PHY_CTRL] =3D { 0x31500000, 0x00001000 }, [PHYTIUM_E2000_BOARD_CTRL] =3D { 0x31800000, 0x01400000 }, [PHYTIUM_E2000_BOOT_IACC] =3D { 0x38000000, 0x08000000 }, + [PHYTIUM_E2000_PCIE_ECAM] =3D { 0x40000000, 0x10000000 }, + [PHYTIUM_E2000_PCIE_PIO] =3D { 0x50000000, 0x00f00000 }, + [PHYTIUM_E2000_PCIE_MMIO] =3D { 0x58000000, 0x28000000 }, [PHYTIUM_E2000_RAM] =3D { 0x80000000, 0x80000000 }, + [PHYTIUM_E2000_PCIE_MMIO_HIGH] =3D { 0x1000000000ULL, 0x1000000000ULL = }, [PHYTIUM_E2000_RAM_HIGH] =3D { 0x2000000000ULL, 0x180000000ULL }, }; =20 @@ -103,6 +117,13 @@ static const int phytium_e2000_uart_irqmap[] =3D { [6] =3D 107, }; =20 +static const int phytium_e2000_pcie_irqmap[PCI_NUM_PINS] =3D { + [0] =3D 4, + [1] =3D 5, + [2] =3D 6, + [3] =3D 7, +}; + typedef struct PhytiumE2000CPUConfig { const char *type; uint64_t mp_affinity; @@ -221,6 +242,88 @@ static void phytium_e2000_create_uart(PhytiumE2000Stat= e *s, int index) qdev_get_gpio_in(s->gic, phytium_e2000_uart_irqmap[index])); } =20 +/* The vendor DT maps root-bus INTx solely by pin */ +static int phytium_e2000_pcie_map_irq(PCIDevice *pdev, int pin) +{ + return pin; +} + +static void phytium_e2000_create_pcie(PhytiumE2000State *s) +{ + DeviceState *dev =3D qdev_new(TYPE_GPEX_HOST); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + MemoryRegion *ecam_alias; + MemoryRegion *ecam_reg; + MemoryRegion *mmio_alias; + MemoryRegion *mmio_high_alias; + MemoryRegion *mmio_reg; + int i; + + /* + * GPEX owns generic ECAM, PIO, and MMIO containers. The aliases below + * place those containers at the E2000 physical windows that U-Boot sc= ans + * and that the SDK device tree publishes to Linux. + * + * The MMIO container is indexed by PCI bus address, so each alias uses + * the physical window base as its source offset to preserve a 1:1 map= ping + * between CPU and PCI addresses. + */ + qdev_prop_set_uint64(dev, PCI_HOST_ECAM_BASE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_ECAM].base); + qdev_prop_set_uint64(dev, PCI_HOST_ECAM_SIZE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_ECAM].size); + qdev_prop_set_uint64(dev, PCI_HOST_PIO_BASE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_PIO].base); + qdev_prop_set_uint64(dev, PCI_HOST_PIO_SIZE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_PIO].size); + qdev_prop_set_uint64(dev, PCI_HOST_BELOW_4G_MMIO_BASE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO].base); + qdev_prop_set_uint64(dev, PCI_HOST_BELOW_4G_MMIO_SIZE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO].size); + qdev_prop_set_uint64(dev, PCI_HOST_ABOVE_4G_MMIO_BASE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO_HIGH].base); + qdev_prop_set_uint64(dev, PCI_HOST_ABOVE_4G_MMIO_SIZE, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO_HIGH].size); + + sysbus_realize_and_unref(sbd, &error_fatal); + pci_bus_map_irqs(PCI_HOST_BRIDGE(dev)->bus, + phytium_e2000_pcie_map_irq); + + ecam_alias =3D g_new0(MemoryRegion, 1); + ecam_reg =3D sysbus_mmio_get_region(sbd, 0); + memory_region_init_alias(ecam_alias, OBJECT(dev), "phytium-pcie-ecam", + ecam_reg, 0, phytium_e2000_memmap[PHYTIUM_E2000_PCIE_ECAM].size); + memory_region_add_subregion(get_system_memory(), + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_ECAM].base, ecam_alias); + + mmio_alias =3D g_new0(MemoryRegion, 1); + mmio_reg =3D sysbus_mmio_get_region(sbd, 1); + memory_region_init_alias(mmio_alias, OBJECT(dev), "phytium-pcie-mmio", + mmio_reg, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO].base, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO].size); + memory_region_add_subregion(get_system_memory(), + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO].base, + mmio_alias); + + mmio_high_alias =3D g_new0(MemoryRegion, 1); + memory_region_init_alias(mmio_high_alias, OBJECT(dev), + "phytium-pcie-mmio-high", mmio_reg, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO_HIGH].base, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO_HIGH].size); + memory_region_add_subregion(get_system_memory(), + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_MMIO_HIGH].base, + mmio_high_alias); + + sysbus_mmio_map(sbd, 2, phytium_e2000_memmap[PHYTIUM_E2000_PCIE_PIO].b= ase); + + for (i =3D 0; i < PCI_NUM_PINS; i++) { + sysbus_connect_irq(sbd, i, + qdev_get_gpio_in(s->gic, phytium_e2000_pcie_irqmap[i])); + gpex_set_irq_num(GPEX_HOST(dev), i, phytium_e2000_pcie_irqmap[i]); + } +} + static void phytium_e2000_create_unimplemented(void) { /* @@ -232,6 +335,19 @@ static void phytium_e2000_create_unimplemented(void) "phytium-e2000.low-peripheral", phytium_e2000_memmap[PHYTIUM_E2000_LOW_PERIPH].base, phytium_e2000_memmap[PHYTIUM_E2000_LOW_PERIPH].size); + /* + * PBF programs SoC-specific PCIe PHY and port controls before U-Boot + * enumerates ECAM. Their values do not affect the generic host bridge= , so + * keep this control aperture visible without inventing register behav= ior. + */ + create_unimplemented_device( + "phytium-e2000.pcie-control", + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_CTRL].size); + create_unimplemented_device( + "phytium-e2000.pcie-phy-control", + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_PHY_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_PCIE_PHY_CTRL].size); create_unimplemented_device( "phytium-e2000.board-control", phytium_e2000_memmap[PHYTIUM_E2000_BOARD_CTRL].base, @@ -331,6 +447,8 @@ static void phytium_pi_init(MachineState *ms) phytium_e2000_create_uart(s, i); } =20 + phytium_e2000_create_pcie(s); + s->bootinfo.ram_size =3D ms->ram_size; s->bootinfo.board_id =3D -1; s->bootinfo.loader_start =3D phytium_e2000_memmap[PHYTIUM_E2000_RAM].b= ase; --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788435056; cv=pass; d=zohomail.com; s=zohoarc; b=IbpxSQtaQyWDdErPOqa9aHY0LzGc0D8r3X2oGMZfSrVlxxQZv0EwtNjR8SPGhOjYCCUGxyQgHsyE+PzFyBFR6fZQ+po0SHTLOKuqCAgXZN3NzcCg660yqBDvgQ6It03ebSpQbY+Id+t933NMbRj5IdjHXWOGEyTaVx0vTRIcnqc= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788435056; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=MLvYLX6o4gmwcnDkpC3vIO9SnCMFN8fbA8lWZfVnd2U=; b=kHrl2POAQMYUUoNGwSwFNtKe9UytcYNtLB8DPZh4sSvF9SrKqvohhjQIyY0D7CouEfemFz9c6S9rqBcun45BQEhSa6GT3km1Ko6olyxL+XptIkA57Kb6MLlFjXwPLUDuBT29e9OBizNGwypvbrnj2kWy/KY5zaeKQaXp1pVoG+I= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788435055987810.5290820635379; Thu, 3 Sep 2026 04:30:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aE-0005Xi-4A; Thu, 03 Sep 2026 07:26:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aC-0005X1-VD; Thu, 03 Sep 2026 07:26:16 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a8-0006f9-1J; Thu, 03 Sep 2026 07:26:16 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:25:59 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:25:59 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Ul6cKukt5t8jbr13tfGqAD436N7VZmbV9BEyNSQ8Fo5eDTyICy9N80XnLePorsp5aaWFQegp6qzGdut0GcWe4BaL5xKfh2wj73+yK0VrIRV2VQZt8ASRySQe0xdCdaAzXerbZr3bpF8kMTU2yUb6KfmyMhI6MxtdahYXqe+F78zqTBEyQ+NzaDU6qyS6NAJdnQ/Uw0DN8PzG72EekRECeG/fSqQWIgGwO4InOAzDlBBcrayPa+WiUT3UuuwCoN9BnB1pSrD5jhLrEoXUrtBHYTfbCOPxVpE/Af0hF89kWNKWnQ8l5okJiFixVFdSbxaekCpQvkm4PljNdQOzOY8olw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MLvYLX6o4gmwcnDkpC3vIO9SnCMFN8fbA8lWZfVnd2U=; b=sHJNtVOoP8RFind4vqGomKhXtvGqHC9A5+/kf6v75h1BAAddCnKezJjuBNE99CMeqAxZwMok5lX8V3jPdKo/eWrqrhwi7L9SCw1YwUmi7VqIvGZUQpZU+7x3/rOBw9Oswt/Hkx4REUWccd1PRmYPFpYh1AJrlZyfpPYxbCwVfWYieNE0NNcq9HCKnPQlSD7py3ORTlbUW5l4YQOfiQ59JrNVDc3lfcKKtVXOB8nbQFIx0U76V1sldZ7QIexFHXaV/josic0FxtjPVNb9tGBD8pfTDlO+yJ1Rok1Ub0FqG2ooa/ST2JFU98tFJdQ9yJW6tQv+/FW4D6wGFN6iS13JYg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MLvYLX6o4gmwcnDkpC3vIO9SnCMFN8fbA8lWZfVnd2U=; b=oYg+duNopKfP0Z604aYYFJGJzqzaDq2sPqtFSdvd5iMpkjxLFqCMeN9GgtCykJHJSmrFrewOpgPvmFppTOl2lABG+MT2GHhEjLz26/MvfoBBR78hVckzTXpxXZFskFWX4zYFZod9r2+38PEAR2uH9iXbUJotyb94CjTopPTK21Qy9j+mWfRCB5WLiVTb7t2KN11KxjDicqHu0LY7ojYLE2TThwYyM/GiukypvT99LgFy/GHa6LAIpCzFAc+V7bPLMXao1zBPI0Tjhb9ldVH6sgs7sdInZdVsdq1ouwCvWiiRPkyjQu/HLNu8j2XJXi158i8XFL7YbRrIpUBy7D416A== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Bin Meng , Paolo Bonzini , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , qemu-block@nongnu.org Subject: [PATCH 04/33] hw/sd: Add Synopsys DesignWare MCI controller Date: Thu, 3 Sep 2026 19:24:44 +0800 Message-ID: <20260903112532.3276678-5-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: fe92e43c-7bf8-438f-0c88-08df09ae2106 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: enKUr1qfnSn6MxTM/SXI12WMPXTsE04+2IItNR06ZvoTH48IqjKvKMM0axeqKvt4q3viYmLNUQYpunwaVeqySxWk3H7Ul5LQa5M78uSa+j/EmvtpxE13e/cWS2+QY8/Kr7RNL4AFV75hQiBQVe7olDH+XAcd5fuapQ+lRgOSsoO+ZNOBgdSsNfFkPY9qHOUDFUtsLquMuyTZcgzfztjT/LjCqeUL2Si7VpktJBQ0S+n1yzoUmpzUUrYv01lMgtNkiAttkV8d3auMcvHXHsUKM6iI3yAhaozf2y/ABBbzmMn3Efrqz52BneS354js1bj2Omlb/1gN/Ap5cDVCFTgEKxPiUbw/XOjqMmcTBVXz8FIaaQ/PyESzDMO7E1ICe4glx+6bO2OI6mNtpKjhGSat2H33Y41GMc4WvHZzc25qLD8F0Av1MiajPkbuCJak6ueVO4/dQvLLyFTvpT+yw/d0SONuXVCQyse4a3gFa4hXhb7pWE3bhI1TMEPojvyiEgzBBZXw35TVIGqq+DVWwmEjeuRhzp0JvKZi0rgTrOoZ4PFBnJINSq3yD1Zj9JbazKd+6blT4BZF6IaX5C/b6EGW/gWneqDyqlLFRo6le6lLpNcOFi8l4O/fV1Z3+dw/XOi9tkHY/7YRwtQyIQS1dSFCiLsTvQjOMP7xWPuOFIGa8ac= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?Vk9ZQ1ZmQnRlaWZzRUhqeDhDQXNya1hSY1MvbHczQ0xKZGtZTjhZa0dYdStY?= =?utf-8?B?ZENNRmZWam85ZjhqM1BBZktDKzJMbDYwRExIYUp6dXpFNXBWRjhxVDhjeHEr?= =?utf-8?B?RDNuem5SbHBMVHNTV3FPd1RiaThxVkJoZ1dJZEE1cllpWU9vMXhNZ1JvcERv?= =?utf-8?B?SkFBMHAweXVJdUtZUFd5dmZ1K3F1c0Ftam9uZEhBbWhwamZ5ZGxjRkFjS2lU?= =?utf-8?B?UlZaa0NZVlVlbXNpRDA4eWN5N0xKanZhZUR1ZEowMU1pTXhsQnQ2a1h2djhw?= =?utf-8?B?dkttNXZaWVN2cjg4Z1NKQ1N4WTVVVkNDM2ptU3dHVk1NRzRWYVdJZEFoWXVD?= =?utf-8?B?bnRnLzJPcmMzTml5UTJrWm9sd0x4VG8wb0pvdWRzcjNObUFYVzBrUlpDTDJq?= =?utf-8?B?bjlDeVhnL0dWdzBQY0MyWHVySlFhMTJvTitoZGFtQi8wclphVkNBZUhyeHpS?= =?utf-8?B?eWdjblVRejhFa0R5di84UFF6M3BBSGhZM0ViL0Z3cEdkRWdEVTZZY0x0ay93?= =?utf-8?B?ZmU1NFZDZUg5NmxZc3puWEhiS0E4YURnQStiZlZMS3NMbDdYNkh1d3YyNVdV?= =?utf-8?B?UGppN2Y5NjhJR0xQaVRXQWZ4a2hBc2cyN0xCSWFLMVBaOUs5NGp0YUJOTitk?= =?utf-8?B?cWZLcHJ5YW9FWmlVNXVWR0pSVTZhRWhrSjFaUDhTMmdENWxxM1JybVhtZFUy?= =?utf-8?B?a0g4YlNYZ2tqWExPNEo4VUUwbDM0R081SFNtYkVVTkh1QWZ2a3VaYnJ2Vkxt?= =?utf-8?B?WHJpSkxpVHFaMDhyYTAvWGpOZFkyNGFIMVR3SVpoU1lENk9QY2hZQmdDTUVO?= =?utf-8?B?SnFhMGJHbWprOXErdXdYNTZpUVlqVXR3b0dqdXZvbU03UXNSbjBiVThnb2dK?= =?utf-8?B?RENKSExNK2JZZnVwcnNybWhUN1kyZ0QydTVWZmpZS3JvT1NPTzhOMXRZYkgy?= =?utf-8?B?M0Z3SERmSE9VQnA0TS9LZWlGWlhLZEY1L2k0OEo1cGtsNnZSNmQyMG9wOUhF?= =?utf-8?B?ZGJwYVNFN3JubWJyOERnaDI5Vng5RXVyVHhxWi9mK1gyYkk0UVFpeFI4em9W?= =?utf-8?B?bkVWOHVDd0xReTFJZ01xWnV3blBpT0k4TS9qTWE1Ly9SbktoeVZTVXZPd2dt?= =?utf-8?B?RG1ab1VhRHJyZzJxRnZva3E0TE9zekk4N1gxVmowSXJYUkpIdzB6WEdVWjFR?= =?utf-8?B?QzU5cG9wZjZzbG1JdURCNVgyMzRXMFMwcU1yWE1qK05LWnB4cWNaTHZCeGM3?= =?utf-8?B?MzBPdUdINHJ2SkYreWxidUFTOWZEWUNjV3JNQ2Rmcy8xbTJIYzdLM050bXVq?= =?utf-8?B?cEwwT0pSM29hRmlBR0xQNExKRko0MlBmcThxdGM3U2E2MVhCbXJJd0dwOUJX?= =?utf-8?B?UTA4Q0Yzenl2Q0dkSTlocXppU1ZVYUhzd3hXRE1sVFdkeURhMHoxSUduajZD?= =?utf-8?B?N3A5UkF5ak14V3ZTL0YwUW1jMUVuRTBTaFYzVXlzNEEyWHU0ZFZheCt1bWRC?= =?utf-8?B?M0pPSi9nZVRvYmFBUE1wN1ZLQ1hGa2IxbUxyYU5UZG5VbEZPSEpjeFVCc3ZG?= =?utf-8?B?OThDajNyRUNkUzNwajRybWRjR1UwdHpaR3EyL3hwYTFVakErNjZuMmNJRDJO?= =?utf-8?B?Y3lpaXpWc2xXek9Jc1ZJSHdKNm5QV1dHNTlxbzBCd3JZUCsyWnlldHprYTlw?= =?utf-8?B?dFdIdG8vb2xGb0hOM1QyUGZxWXlQTGNlNjRZTzdValhwZjdzdWJOblkvQXlv?= =?utf-8?B?VzE3TUJCZzA4dnVCdWJnVnA1OEg0L01pYnhkQUdjcnM3b0VVUTRvblYvUkda?= =?utf-8?B?Q1M0Y3dXY1R4R1VKUy9nTE1HM01DMFdKdWlkRXJjS1J5akV6eERWbXVjK3hE?= =?utf-8?B?aHUvOG9JYWI1Z00vNmRsQis5ZVo3WDJzSHM1V1BiMVhPclpadzhUKy9aZEpU?= =?utf-8?B?OXM2WWg4U3NxRW5qR2VIamdjZGNDemd1ZWM5VVd2b2x2QTJhd1g5bi9UbG1w?= =?utf-8?B?VGNsRGEyeXkvaXJkWXQ4aS9MNGY4Y0xXOG9oV3AreExZcDBPTFVUZEw1dUx6?= =?utf-8?B?d1VRYWFCUzk4MklIMlI2OUpqNStYbG5IL0ZWUmFSUk9lMXU5cWEwYXhOR1dk?= =?utf-8?B?ZCt5ZVBFcmFpVzlHYm5uL2lpd2tuSnN2bmxpazZIT0pWdEV6THBnaThNOWho?= =?utf-8?B?UGFWa0tqOHhxYUlyNSthdlZiNzBmL3h4NlZTbmNQUG9Wb1pPMCs2L3c2R1lP?= =?utf-8?B?Z1p6dWtrQW5vcE13ell0SkFiVDVvMkRiblVYMGZXQzg0YSs1TEE2UjhrUndW?= =?utf-8?B?RGZDbkUyazh6cC9GdDl5QS9VQjFJV0MvZ1JNc0RCUWlIbnl0THFwT1lUMTJJ?= =?utf-8?Q?KKr6dgFxoaYZ//Tw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: fe92e43c-7bf8-438f-0c88-08df09ae2106 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:25:59.5245 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: gLRPKHLPPIwKC3fgcCDwwSvL2EMppS9zKc9LrsBU4eDcQxBACCeUHctHbD9AiQLL6f8yfN33suW2slHIKAl85xXlYRedSmkfTGMEXFTUVYE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788435057759158500 The Synopsys DesignWare Mobile Storage Host predates SDHCI and uses a distinct MCI programming interface. It is integrated by Samsung Exynos, Rockchip, HiSilicon, and Altera/Intel SoCFPGA platforms, among others. Add a reusable controller model based on the DesignWare Mobile Storage Host 2.40a databook. Cover command and response handling, PIO FIFO aliases, reset and interrupt semantics, card state, and the standard 32-bit internal descriptor DMA engine. Also support the later 64-bit descriptor layout used by vendor variants. Expose class hooks and immutable configuration fields so vendor extensions can reuse the common implementation. Signed-off-by: Bin Meng --- MAINTAINERS | 2 + hw/sd/Kconfig | 5 + hw/sd/dw_mci.c | 1382 ++++++++++++++++++++++++++++++++++++++++ hw/sd/meson.build | 1 + include/hw/sd/dw_mci.h | 74 +++ 5 files changed, 1464 insertions(+) create mode 100644 hw/sd/dw_mci.c create mode 100644 include/hw/sd/dw_mci.h diff --git a/MAINTAINERS b/MAINTAINERS index a1830cdad1..1ea3af260f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2411,8 +2411,10 @@ M: Philippe Mathieu-Daud=C3=A9 M: Bin Meng L: qemu-block@nongnu.org S: Odd Fixes +F: include/hw/sd/dw_mci.h F: include/hw/sd/sd* F: hw/sd/core.c +F: hw/sd/dw_mci.c F: hw/sd/sd* F: hw/sd/ssi-sd.c F: tests/qtest/fuzz-sdcard-test.c diff --git a/hw/sd/Kconfig b/hw/sd/Kconfig index c69bf24f8d..dc3ebefa52 100644 --- a/hw/sd/Kconfig +++ b/hw/sd/Kconfig @@ -10,6 +10,11 @@ config SSI_SD config SD bool =20 +config DW_MCI + bool + select REGISTER + select SD + config SDHCI bool select SD diff --git a/hw/sd/dw_mci.c b/hw/sd/dw_mci.c new file mode 100644 index 0000000000..245435f43e --- /dev/null +++ b/hw/sd/dw_mci.c @@ -0,0 +1,1382 @@ +/* + * Synopsys DesignWare Multimedia Card Interface + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/sd/dw_mci.h" + +#include "hw/core/irq.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "qemu/bswap.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "system/address-spaces.h" +#include "system/dma.h" + +REG32(CTRL, 0x000) + FIELD(CTRL, RESET, 0, 1) + FIELD(CTRL, FIFO_RESET, 1, 1) + FIELD(CTRL, DMA_RESET, 2, 1) + FIELD(CTRL, INT_ENABLE, 4, 1) + FIELD(CTRL, DMA_ENABLE, 5, 1) + FIELD(CTRL, USE_IDMAC, 25, 1) +REG32(PWREN, 0x004) +REG32(CLKDIV, 0x008) +REG32(CLKSRC, 0x00c) +REG32(CLKENA, 0x010) +REG32(TMOUT, 0x014) +REG32(CTYPE, 0x018) +REG32(BLKSIZ, 0x01c) +REG32(BYTCNT, 0x020) +REG32(INTMASK, 0x024) +REG32(CMDARG, 0x028) +REG32(CMD, 0x02c) + FIELD(CMD, INDEX, 0, 6) + FIELD(CMD, RESP_EXP, 6, 1) + FIELD(CMD, RESP_LONG, 7, 1) + FIELD(CMD, RESP_CRC, 8, 1) + FIELD(CMD, DAT_EXP, 9, 1) + FIELD(CMD, DAT_WR, 10, 1) + FIELD(CMD, SEND_STOP, 12, 1) + FIELD(CMD, STOP, 14, 1) + FIELD(CMD, UPD_CLK, 21, 1) + FIELD(CMD, START, 31, 1) +REG32(RESP0, 0x030) +REG32(RESP1, 0x034) +REG32(RESP2, 0x038) +REG32(RESP3, 0x03c) +REG32(MINTSTS, 0x040) +REG32(RINTSTS, 0x044) +REG32(STATUS, 0x048) + FIELD(STATUS, FIFO_RX_WMARK, 0, 1) + FIELD(STATUS, FIFO_TX_WMARK, 1, 1) + FIELD(STATUS, FIFO_EMPTY, 2, 1) + FIELD(STATUS, FIFO_FULL, 3, 1) + FIELD(STATUS, BUSY, 9, 1) + FIELD(STATUS, RESPONSE_INDEX, 11, 6) + FIELD(STATUS, FIFO_COUNT, 17, 13) +REG32(FIFOTH, 0x04c) + FIELD(FIFOTH, TX_WMARK, 0, 12) + FIELD(FIFOTH, RX_WMARK, 16, 12) + FIELD(FIFOTH, MSIZE, 28, 3) +REG32(CDETECT, 0x050) +REG32(WRTPRT, 0x054) +REG32(GPIO, 0x058) +REG32(TCBCNT, 0x05c) +REG32(TBBCNT, 0x060) +REG32(DEBNCE, 0x064) +REG32(USRID, 0x068) +REG32(VERID, 0x06c) +REG32(HCON, 0x070) + FIELD(HCON, CARD_TYPE, 0, 1) + FIELD(HCON, NUM_CARDS, 1, 5) + FIELD(HCON, HBUS_TYPE, 6, 1) + FIELD(HCON, HDATA_WIDTH, 7, 3) + FIELD(HCON, HADDR_WIDTH, 10, 6) + FIELD(HCON, TRANS_MODE, 16, 2) + FIELD(HCON, FIFO_RAM_INSIDE, 21, 1) + FIELD(HCON, HOLD_REG, 22, 1) + /* Later revisions use bit 27 to advertise 64-bit IDMAC addresses */ + FIELD(HCON, ADDR_CONFIG, 27, 1) +REG32(UHS_REG, 0x074) +REG32(RST_N, 0x078) +REG32(BMOD, 0x080) + FIELD(BMOD, SWRESET, 0, 1) + FIELD(BMOD, FIXED_BURST, 1, 1) + FIELD(BMOD, DSL, 2, 5) + FIELD(BMOD, ENABLE, 7, 1) + FIELD(BMOD, PBL, 8, 3) +REG32(PLDMND, 0x084) +REG32(IDMAC_088, 0x088) +REG32(IDMAC_08C, 0x08c) +REG32(IDMAC_090, 0x090) +REG32(IDMAC_094, 0x094) +REG32(IDMAC_098, 0x098) +REG32(IDMAC_09C, 0x09c) +REG32(IDMAC_0A0, 0x0a0) +REG32(IDMAC_0A4, 0x0a4) +REG32(CDTHRCTL, 0x100) +REG32(BACK_END_POWER, 0x104) +REG32(UHS_REG_EXT, 0x108) +REG32(DDR_REG, 0x10c) +REG32(ENABLE_SHIFT, 0x110) + +#define DW_MCI_INT_CD BIT(0) +#define DW_MCI_INT_RESP_ERR BIT(1) +#define DW_MCI_INT_CMD_DONE BIT(2) +#define DW_MCI_INT_DATA_OVER BIT(3) +#define DW_MCI_INT_TXDR BIT(4) +#define DW_MCI_INT_RXDR BIT(5) +#define DW_MCI_INT_RCRC BIT(6) +#define DW_MCI_INT_DCRC BIT(7) +#define DW_MCI_INT_RTO BIT(8) +#define DW_MCI_INT_DRTO BIT(9) +#define DW_MCI_INT_HTO BIT(10) +#define DW_MCI_INT_FRUN BIT(11) +#define DW_MCI_INT_HLE BIT(12) +#define DW_MCI_INT_SBE BIT(13) +#define DW_MCI_INT_ACD BIT(14) +#define DW_MCI_INT_EBE BIT(15) + +#define DW_MCI_IDSTS_TI BIT(0) +#define DW_MCI_IDSTS_RI BIT(1) +#define DW_MCI_IDSTS_FBE BIT(2) +#define DW_MCI_IDSTS_DU BIT(4) +#define DW_MCI_IDSTS_CES BIT(5) +#define DW_MCI_IDSTS_NI BIT(8) +#define DW_MCI_IDSTS_AI BIT(9) +#define DW_MCI_IDSTS_NORMAL (DW_MCI_IDSTS_TI | DW_MCI_IDSTS_RI) +#define DW_MCI_IDSTS_ABNORMAL (DW_MCI_IDSTS_FBE | DW_MCI_IDSTS_DU | \ + DW_MCI_IDSTS_CES) +#define DW_MCI_IDSTS_MASK (DW_MCI_IDSTS_TI | DW_MCI_IDSTS_RI | \ + DW_MCI_IDSTS_FBE | DW_MCI_IDSTS_DU | \ + DW_MCI_IDSTS_CES | DW_MCI_IDSTS_NI | \ + DW_MCI_IDSTS_AI) + +#define DW_MCI_IDMAC_DIC BIT(1) +#define DW_MCI_IDMAC_LD BIT(2) +#define DW_MCI_IDMAC_FS BIT(3) +#define DW_MCI_IDMAC_CH BIT(4) +#define DW_MCI_IDMAC_ER BIT(5) +#define DW_MCI_IDMAC_CES BIT(30) +#define DW_MCI_IDMAC_OWN BIT(31) +#define DW_MCI_IDMAC_SIZE_MASK 0x1fff +#define DW_MCI_IDMAC_SIZE2_SHIFT 13 +#define DW_MCI_IDMAC_MAX_DESCS 4096 +#define DW_MCI_DMA_CHUNK_SIZE 1024 + +#define DW_MCI_IDMAC_FSM_IDLE 0 +#define DW_MCI_IDMAC_FSM_SUSPEND 1 + +#define TYPE_DW_MCI_BUS "dw-mci-bus" + +typedef struct DwMciIdmac32 { + uint32_t control; + uint32_t sizes; + uint32_t buffer; + uint32_t next; +} DwMciIdmac32; + +typedef struct DwMciIdmac64 { + uint32_t control; + uint32_t reserved0; + uint32_t sizes; + uint32_t reserved1; + uint32_t buffer_lo; + uint32_t buffer_hi; + uint32_t next_lo; + uint32_t next_hi; +} DwMciIdmac64; + +typedef struct DwMciDescriptor { + uint32_t control; + uint32_t size[2]; + uint64_t buffer[2]; + uint64_t next; +} DwMciDescriptor; + +static bool dw_mci_run_idmac(DwMciState *s); + +static bool dw_mci_is_64bit(DwMciState *s) +{ + return s->hcon & R_HCON_ADDR_CONFIG_MASK; +} + +/* + * The 64-bit layout inserts DBADDRU at 0x8c, shifting IDSTS and IDINTEN o= ne + * register higher than their locations in the legacy layout. + */ +static unsigned dw_mci_idsts_reg(DwMciState *s) +{ + return dw_mci_is_64bit(s) ? R_IDMAC_090 : R_IDMAC_08C; +} + +static unsigned dw_mci_idinten_reg(DwMciState *s) +{ + return dw_mci_is_64bit(s) ? R_IDMAC_094 : R_IDMAC_090; +} + +static uint32_t dw_mci_host_bus_bytes(DwMciState *s) +{ + unsigned width =3D FIELD_EX32(s->hcon, HCON, HDATA_WIDTH); + + return width <=3D 2 ? 2U << width : sizeof(uint32_t); +} + +static void dw_mci_set_idmac_fsm(DwMciState *s, uint32_t state) +{ + unsigned idsts =3D dw_mci_idsts_reg(s); + + s->regs[idsts] =3D deposit32(s->regs[idsts], 13, 4, state); +} + +static uint64_t dw_mci_descriptor_base(DwMciState *s) +{ + uint64_t address =3D s->regs[R_IDMAC_088]; + + if (dw_mci_is_64bit(s)) { + address |=3D (uint64_t)s->regs[R_IDMAC_08C] << 32; + } + return address; +} + +static uint32_t dw_mci_fifo_capacity(DwMciState *s) +{ + return MIN(s->fifo_depth, (uint32_t)DW_MCI_FIFO_MAX_WORDS) * 4; +} + +static void dw_mci_fifo_reset(DwMciState *s) +{ + s->fifo_head =3D 0; + s->fifo_len =3D 0; + memset(s->fifo, 0, sizeof(s->fifo)); +} + +static void dw_mci_fifo_push(DwMciState *s, const uint8_t *data, + uint32_t length) +{ + uint32_t capacity =3D dw_mci_fifo_capacity(s); + uint32_t tail =3D (s->fifo_head + s->fifo_len) % capacity; + + while (length--) { + s->fifo[tail] =3D *data++; + tail =3D (tail + 1) % capacity; + s->fifo_len++; + } +} + +static void dw_mci_fifo_pop(DwMciState *s, uint8_t *data, uint32_t length) +{ + uint32_t capacity =3D dw_mci_fifo_capacity(s); + + while (length--) { + *data++ =3D s->fifo[s->fifo_head]; + s->fifo_head =3D (s->fifo_head + 1) % capacity; + s->fifo_len--; + } + if (!s->fifo_len) { + s->fifo_head =3D 0; + } +} + +static void dw_mci_update_irq(DwMciState *s) +{ + uint32_t core =3D s->regs[R_RINTSTS] & s->regs[R_INTMASK]; + uint32_t idsts =3D s->regs[dw_mci_idsts_reg(s)]; + uint32_t idinten =3D s->regs[dw_mci_idinten_reg(s)]; + bool core_irq =3D (s->regs[R_CTRL] & R_CTRL_INT_ENABLE_MASK) && core; + bool idmac_irq =3D ((idsts & DW_MCI_IDSTS_NI) && + (idinten & DW_MCI_IDSTS_NI)) || + ((idsts & DW_MCI_IDSTS_AI) && + (idinten & DW_MCI_IDSTS_AI)); + + /* The top-level interrupt is the logical OR of the BIU and IDMAC line= s */ + qemu_set_irq(s->irq, core_irq || idmac_irq); +} + +static void dw_mci_set_idmac_status(DwMciState *s, uint32_t status) +{ + unsigned idsts =3D dw_mci_idsts_reg(s); + uint32_t idinten =3D s->regs[dw_mci_idinten_reg(s)]; + + s->regs[idsts] |=3D status; + + /* + * NIS and AIS are sticky summary events, not aliases of the individual + * status bits. The databook requires both the member interrupt and i= ts + * group interrupt to be enabled before the summary is raised. + */ + if ((status & DW_MCI_IDSTS_NORMAL & idinten) && + (idinten & DW_MCI_IDSTS_NI)) { + s->regs[idsts] |=3D DW_MCI_IDSTS_NI; + } + if ((status & DW_MCI_IDSTS_ABNORMAL & idinten) && + (idinten & DW_MCI_IDSTS_AI)) { + s->regs[idsts] |=3D DW_MCI_IDSTS_AI; + } +} + +static void dw_mci_update_fifo_interrupts(DwMciState *s) +{ + uint32_t fifo_words =3D DIV_ROUND_UP(s->fifo_len, sizeof(uint32_t)); + uint32_t tx_wmark =3D FIELD_EX32(s->regs[R_FIFOTH], FIFOTH, TX_WMARK); + uint32_t rx_wmark =3D FIELD_EX32(s->regs[R_FIFOTH], FIFOTH, RX_WMARK); + + if (!s->transfer_active) { + s->regs[R_RINTSTS] &=3D ~(DW_MCI_INT_RXDR | DW_MCI_INT_TXDR); + } else if (s->transfer_write) { + if (fifo_words <=3D tx_wmark) { + s->regs[R_RINTSTS] |=3D DW_MCI_INT_TXDR; + } else { + s->regs[R_RINTSTS] &=3D ~DW_MCI_INT_TXDR; + } + s->regs[R_RINTSTS] &=3D ~DW_MCI_INT_RXDR; + } else { + if (fifo_words > rx_wmark) { + s->regs[R_RINTSTS] |=3D DW_MCI_INT_RXDR; + } else { + s->regs[R_RINTSTS] &=3D ~DW_MCI_INT_RXDR; + } + s->regs[R_RINTSTS] &=3D ~DW_MCI_INT_TXDR; + } + dw_mci_update_irq(s); +} + +static void dw_mci_send_auto_stop(DwMciState *s) +{ + SDRequest request =3D { .cmd =3D 12, .arg =3D 0 }; + uint8_t response[16]; + size_t response_len; + + if (!s->transfer_send_stop) { + return; + } + s->transfer_send_stop =3D false; + response_len =3D sdbus_do_command(&s->sdbus, &request, response, + sizeof(response)); + if (response_len =3D=3D sizeof(uint32_t)) { + /* Auto-stop preserves the preceding response in RESP0 */ + s->regs[R_RESP1] =3D ldl_be_p(response); + s->regs[R_STATUS] =3D FIELD_DP32(s->regs[R_STATUS], STATUS, + RESPONSE_INDEX, request.cmd); + } + s->regs[R_RINTSTS] |=3D DW_MCI_INT_ACD; +} + +static void dw_mci_complete_data(DwMciState *s) +{ + dw_mci_send_auto_stop(s); + s->regs[R_RINTSTS] |=3D DW_MCI_INT_DATA_OVER; + s->transfer_active =3D false; + s->transfer_remaining =3D 0; + dw_mci_update_fifo_interrupts(s); +} + +static void dw_mci_set_data_error(DwMciState *s) +{ + s->regs[R_RINTSTS] |=3D DW_MCI_INT_DRTO; + s->transfer_active =3D false; + dw_mci_update_fifo_interrupts(s); +} + +static void dw_mci_refill_fifo(DwMciState *s) +{ + uint8_t buffer[DW_MCI_DMA_CHUNK_SIZE]; + uint32_t capacity =3D dw_mci_fifo_capacity(s); + + while (s->transfer_active && !s->transfer_write && + s->transfer_remaining && s->fifo_len < capacity) { + uint32_t length =3D MIN((uint32_t)sizeof(buffer), + s->transfer_remaining); + + length =3D MIN(length, capacity - s->fifo_len); + sdbus_read_data(&s->sdbus, buffer, length); + dw_mci_fifo_push(s, buffer, length); + s->transfer_remaining -=3D length; + s->regs[R_TCBCNT] +=3D length; + } + if (!s->transfer_remaining) { + /* + * DATA_OVER follows completion at the card side. Keep the transfer + * active until the guest drains prefetched data so FIFO status st= ill + * describes the readable bytes. + */ + s->regs[R_RINTSTS] |=3D DW_MCI_INT_DATA_OVER; + } + dw_mci_update_fifo_interrupts(s); +} + +static void dw_mci_store_response(DwMciState *s, const uint8_t *response, + size_t length) +{ + s->regs[R_RESP0] =3D 0; + s->regs[R_RESP1] =3D 0; + s->regs[R_RESP2] =3D 0; + s->regs[R_RESP3] =3D 0; + + if (length =3D=3D 4) { + s->regs[R_RESP0] =3D ldl_be_p(response); + } else if (length =3D=3D 16) { + /* + * SDBus returns a long response most-significant word first, while + * the controller exposes its least-significant word in RESP0. + */ + s->regs[R_RESP0] =3D ldl_be_p(response + 12); + s->regs[R_RESP1] =3D ldl_be_p(response + 8); + s->regs[R_RESP2] =3D ldl_be_p(response + 4); + s->regs[R_RESP3] =3D ldl_be_p(response); + } +} + +static bool dw_mci_idmac_armed(DwMciState *s) +{ + return (s->regs[R_CTRL] & R_CTRL_USE_IDMAC_MASK) && + (s->regs[R_BMOD] & R_BMOD_ENABLE_MASK) && + FIELD_EX32(s->hcon, HCON, TRANS_MODE) =3D=3D 0 && + !s->idmac_fatal; +} + +static bool dw_mci_send_command(DwMciState *s, uint32_t command) +{ + SDRequest request =3D { 0 }; + uint8_t response[16]; + bool response_expected =3D command & R_CMD_RESP_EXP_MASK; + bool long_response =3D command & R_CMD_RESP_LONG_MASK; + size_t response_len; + + s->regs[R_CMD] =3D command & ~R_CMD_START_MASK; + + if (command & R_CMD_UPD_CLK_MASK) { + /* No card command is sent, so the CIU must not raise Command Done= */ + return true; + } + + if (!sdbus_get_inserted(&s->sdbus) && response_expected) { + s->regs[R_RINTSTS] |=3D DW_MCI_INT_CMD_DONE | DW_MCI_INT_RTO; + dw_mci_update_irq(s); + return false; + } + + request.cmd =3D FIELD_EX32(command, CMD, INDEX); + request.arg =3D s->regs[R_CMDARG]; + response_len =3D sdbus_do_command(&s->sdbus, &request, response, + sizeof(response)); + + if (response_expected && + ((!long_response && response_len !=3D 4) || + (long_response && response_len !=3D 16))) { + s->regs[R_RINTSTS] |=3D DW_MCI_INT_CMD_DONE | DW_MCI_INT_RTO; + dw_mci_update_irq(s); + return false; + } + if (response_expected) { + dw_mci_store_response(s, response, response_len); + s->regs[R_STATUS] =3D FIELD_DP32(s->regs[R_STATUS], STATUS, + RESPONSE_INDEX, request.cmd); + } + + s->regs[R_RINTSTS] |=3D DW_MCI_INT_CMD_DONE; + + if (command & R_CMD_STOP_MASK) { + s->transfer_active =3D false; + s->transfer_remaining =3D 0; + s->transfer_send_stop =3D false; + dw_mci_update_fifo_interrupts(s); + return true; + } + + if (command & R_CMD_DAT_EXP_MASK) { + if (!sdbus_get_inserted(&s->sdbus) || !s->regs[R_BYTCNT]) { + dw_mci_set_data_error(s); + return false; + } + dw_mci_fifo_reset(s); + s->regs[R_TCBCNT] =3D 0; + s->regs[R_TBBCNT] =3D 0; + s->transfer_remaining =3D s->regs[R_BYTCNT]; + s->transfer_active =3D true; + s->transfer_write =3D command & R_CMD_DAT_WR_MASK; + s->transfer_send_stop =3D command & R_CMD_SEND_STOP_MASK; + s->idmac_desc_addr =3D dw_mci_descriptor_base(s); + s->idmac_suspended =3D false; + dw_mci_set_idmac_fsm(s, DW_MCI_IDMAC_FSM_IDLE); + + if (dw_mci_idmac_armed(s)) { + dw_mci_run_idmac(s); + } else if (s->transfer_write) { + dw_mci_update_fifo_interrupts(s); + } else { + dw_mci_refill_fifo(s); + } + } + + dw_mci_update_irq(s); + return true; +} + +static void dw_mci_set_current_descriptor(DwMciState *s, + uint64_t descriptor, + uint64_t buffer) +{ + if (dw_mci_is_64bit(s)) { + s->regs[R_IDMAC_098] =3D descriptor; + s->regs[R_IDMAC_09C] =3D descriptor >> 32; + s->regs[R_IDMAC_0A0] =3D buffer; + s->regs[R_IDMAC_0A4] =3D buffer >> 32; + } else { + s->regs[R_IDMAC_094] =3D descriptor; + s->regs[R_IDMAC_098] =3D buffer; + } +} + +static bool dw_mci_read_descriptor32(uint64_t address, + DwMciDescriptor *result) +{ + DwMciIdmac32 descriptor; + MemTxResult tx_result; + + tx_result =3D dma_memory_read(&address_space_memory, address, &descrip= tor, + sizeof(descriptor), MEMTXATTRS_UNSPECIFIED= ); + if (tx_result !=3D MEMTX_OK) { + return false; + } + + result->control =3D le32_to_cpu(descriptor.control); + result->size[0] =3D le32_to_cpu(descriptor.sizes) & + DW_MCI_IDMAC_SIZE_MASK; + result->size[1] =3D (le32_to_cpu(descriptor.sizes) >> + DW_MCI_IDMAC_SIZE2_SHIFT) & DW_MCI_IDMAC_SIZE_MASK; + result->buffer[0] =3D le32_to_cpu(descriptor.buffer); + result->buffer[1] =3D le32_to_cpu(descriptor.next); + result->next =3D result->buffer[1]; + return true; +} + +static bool dw_mci_read_descriptor64(uint64_t address, + DwMciDescriptor *result) +{ + DwMciIdmac64 descriptor; + MemTxResult tx_result; + + tx_result =3D dma_memory_read(&address_space_memory, address, &descrip= tor, + sizeof(descriptor), MEMTXATTRS_UNSPECIFIED= ); + if (tx_result !=3D MEMTX_OK) { + return false; + } + + result->control =3D le32_to_cpu(descriptor.control); + result->size[0] =3D le32_to_cpu(descriptor.sizes) & + DW_MCI_IDMAC_SIZE_MASK; + result->size[1] =3D 0; + result->buffer[0] =3D le32_to_cpu(descriptor.buffer_lo) | + (uint64_t)le32_to_cpu(descriptor.buffer_hi) << 32; + result->buffer[1] =3D 0; + result->next =3D le32_to_cpu(descriptor.next_lo) | + (uint64_t)le32_to_cpu(descriptor.next_hi) << 32; + return true; +} + +static bool dw_mci_write_descriptor_control(uint64_t address, + uint32_t control) +{ + uint32_t value =3D cpu_to_le32(control); + + return dma_memory_write(&address_space_memory, address, &value, + sizeof(value), MEMTXATTRS_UNSPECIFIED) =3D=3D = MEMTX_OK; +} + +static bool dw_mci_transfer_buffer(DwMciState *s, uint64_t address, + uint32_t length) +{ + uint8_t buffer[DW_MCI_DMA_CHUNK_SIZE]; + + while (length) { + uint32_t chunk =3D MIN(length, (uint32_t)sizeof(buffer)); + MemTxResult result; + + if (s->transfer_write) { + result =3D dma_memory_read(&address_space_memory, address, buf= fer, + chunk, MEMTXATTRS_UNSPECIFIED); + if (result !=3D MEMTX_OK) { + return false; + } + sdbus_write_data(&s->sdbus, buffer, chunk); + } else { + sdbus_read_data(&s->sdbus, buffer, chunk); + result =3D dma_memory_write(&address_space_memory, address, bu= ffer, + chunk, MEMTXATTRS_UNSPECIFIED); + if (result !=3D MEMTX_OK) { + return false; + } + } + + address +=3D chunk; + length -=3D chunk; + s->transfer_remaining -=3D chunk; + s->regs[R_TCBCNT] +=3D chunk; + s->regs[R_TBBCNT] +=3D chunk; + } + return true; +} + +static void dw_mci_suspend_idmac(DwMciState *s) +{ + s->idmac_suspended =3D true; + dw_mci_set_idmac_fsm(s, DW_MCI_IDMAC_FSM_SUSPEND); + dw_mci_set_idmac_status(s, DW_MCI_IDSTS_DU); + dw_mci_update_irq(s); +} + +static void dw_mci_fatal_idmac_error(DwMciState *s) +{ + s->idmac_fatal =3D true; + s->idmac_suspended =3D false; + s->transfer_active =3D false; + dw_mci_set_idmac_fsm(s, DW_MCI_IDMAC_FSM_IDLE); + dw_mci_set_idmac_status(s, DW_MCI_IDSTS_FBE); + dw_mci_update_fifo_interrupts(s); +} + +static uint64_t dw_mci_next_descriptor(DwMciState *s, + const DwMciDescriptor *descriptor, + uint64_t current, + uint32_t descriptor_size) +{ + if (descriptor->control & DW_MCI_IDMAC_CH) { + return descriptor->next & + ~(uint64_t)(dw_mci_host_bus_bytes(s) - 1); + } + if (descriptor->control & DW_MCI_IDMAC_ER) { + return dw_mci_descriptor_base(s); + } + + /* DSL is expressed in host-bus-width units, not bytes */ + return current + descriptor_size + + FIELD_EX32(s->regs[R_BMOD], BMOD, DSL) * + dw_mci_host_bus_bytes(s); +} + +static bool dw_mci_run_idmac(DwMciState *s) +{ + uint32_t descriptor_size =3D dw_mci_is_64bit(s) ? + sizeof(DwMciIdmac64) : + sizeof(DwMciIdmac32); + unsigned int count =3D 0; + + if (!s->transfer_active || !dw_mci_idmac_armed(s)) { + return false; + } + if (!s->idmac_desc_addr) { + s->idmac_desc_addr =3D dw_mci_descriptor_base(s); + } + if (!s->idmac_desc_addr) { + dw_mci_suspend_idmac(s); + return false; + } + + /* + * Bound descriptor traversal so a cyclic guest chain cannot monopolize + * the vCPU. Exhaustion follows the descriptor-unavailable suspend path + * below, allowing the guest to recover through PLDMND. + */ + while (s->transfer_remaining && count++ < DW_MCI_IDMAC_MAX_DESCS) { + DwMciDescriptor descriptor =3D { 0 }; + uint64_t descriptor_address =3D s->idmac_desc_addr; + bool read_ok; + unsigned int i; + + dw_mci_set_current_descriptor(s, descriptor_address, 0); + if (dw_mci_is_64bit(s)) { + read_ok =3D dw_mci_read_descriptor64(descriptor_address, + &descriptor); + } else { + read_ok =3D dw_mci_read_descriptor32(descriptor_address, + &descriptor); + } + if (!read_ok) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: failed to read IDMAC descriptor at " + "0x%" PRIx64 "\n", + TYPE_DW_MCI, descriptor_address); + dw_mci_fatal_idmac_error(s); + return false; + } + if (!(descriptor.control & DW_MCI_IDMAC_OWN)) { + dw_mci_suspend_idmac(s); + return false; + } + + for (i =3D 0; i < ARRAY_SIZE(descriptor.buffer) && + s->transfer_remaining; i++) { + uint64_t buffer_address; + uint32_t length =3D MIN(descriptor.size[i], + s->transfer_remaining); + + /* DES3 is a next-descriptor pointer in chained mode */ + if (i =3D=3D 1 && (descriptor.control & DW_MCI_IDMAC_CH)) { + break; + } + if (!length) { + continue; + } + buffer_address =3D descriptor.buffer[i] & + ~(uint64_t)(dw_mci_host_bus_bytes(s) - 1); + dw_mci_set_current_descriptor(s, descriptor_address, + buffer_address); + if (!dw_mci_transfer_buffer(s, buffer_address, length)) { + dw_mci_fatal_idmac_error(s); + return false; + } + } + + descriptor.control &=3D ~DW_MCI_IDMAC_OWN; + if (!dw_mci_write_descriptor_control(descriptor_address, + descriptor.control)) { + dw_mci_fatal_idmac_error(s); + return false; + } + + if (!(descriptor.control & DW_MCI_IDMAC_DIC)) { + dw_mci_set_idmac_status(s, s->transfer_write ? + DW_MCI_IDSTS_TI : DW_MCI_IDSTS_RI); + } + + if (!s->transfer_remaining) { + break; + } + if (descriptor.control & DW_MCI_IDMAC_LD) { + dw_mci_suspend_idmac(s); + return false; + } + + s->idmac_desc_addr =3D dw_mci_next_descriptor(s, &descriptor, + descriptor_address, + descriptor_size); + if (!s->idmac_desc_addr) { + dw_mci_suspend_idmac(s); + return false; + } + } + + if (s->transfer_remaining) { + dw_mci_suspend_idmac(s); + return false; + } + + s->idmac_suspended =3D false; + dw_mci_set_idmac_fsm(s, DW_MCI_IDMAC_FSM_IDLE); + dw_mci_complete_data(s); + dw_mci_update_irq(s); + return true; +} + +static uint64_t dw_mci_read_data(DwMciState *s, unsigned size) +{ + uint8_t buffer[sizeof(uint64_t)] =3D { 0 }; + uint32_t length; + + if (!s->transfer_active || s->transfer_write) { + return 0; + } + if (!s->fifo_len && s->transfer_remaining) { + dw_mci_refill_fifo(s); + } + + length =3D MIN((uint32_t)size, s->fifo_len); + if (length) { + dw_mci_fifo_pop(s, buffer, length); + s->regs[R_TBBCNT] +=3D length; + } + if (s->transfer_remaining) { + dw_mci_refill_fifo(s); + } + if (!s->transfer_remaining && !s->fifo_len) { + dw_mci_complete_data(s); + } else { + dw_mci_update_fifo_interrupts(s); + } + return ldn_le_p(buffer, size); +} + +static void dw_mci_write_data(DwMciState *s, uint64_t value, unsigned size) +{ + uint8_t buffer[sizeof(uint64_t)] =3D { 0 }; + uint32_t length; + + if (!s->transfer_active || !s->transfer_write) { + return; + } + + /* + * The functional model consumes PIO writes synchronously through SDBu= s. + * Its FIFO therefore remains empty and TXDR continues to advertise ro= om. + */ + length =3D MIN((uint32_t)size, s->transfer_remaining); + stn_le_p(buffer, size, value); + sdbus_write_data(&s->sdbus, buffer, length); + s->transfer_remaining -=3D length; + s->regs[R_TCBCNT] +=3D length; + s->regs[R_TBBCNT] +=3D length; + + if (!s->transfer_remaining) { + dw_mci_complete_data(s); + } else { + dw_mci_update_fifo_interrupts(s); + } +} + +static bool dw_mci_idmac_offset(hwaddr offset) +{ + return offset >=3D A_IDMAC_088 && offset <=3D A_IDMAC_0A4 && + !(offset & 3); +} + +static uint64_t dw_mci_read_idmac_register(DwMciState *s, hwaddr offset) +{ + unsigned reg =3D offset / sizeof(uint32_t); + + if (!dw_mci_is_64bit(s) && offset > A_IDMAC_098) { + return 0; + } + return s->regs[reg]; +} + +static void dw_mci_write_idmac_register(DwMciState *s, hwaddr offset, + uint32_t value) +{ + unsigned reg =3D offset / sizeof(uint32_t); + unsigned idsts =3D dw_mci_idsts_reg(s); + unsigned idinten =3D dw_mci_idinten_reg(s); + + if (reg =3D=3D idsts) { + s->regs[reg] &=3D ~(value & DW_MCI_IDSTS_MASK); + } else if (reg =3D=3D idinten) { + s->regs[reg] =3D value & DW_MCI_IDSTS_MASK; + } else if (offset =3D=3D A_IDMAC_088) { + s->regs[reg] =3D value & ~(dw_mci_host_bus_bytes(s) - 1); + } else if (dw_mci_is_64bit(s) && offset =3D=3D A_IDMAC_08C) { + s->regs[reg] =3D value; + } + dw_mci_update_irq(s); +} + +static void dw_mci_reset_idmac(DwMciState *s) +{ + s->regs[R_BMOD] =3D 0; + s->regs[R_IDMAC_088] =3D 0; + if (dw_mci_is_64bit(s)) { + s->regs[R_IDMAC_08C] =3D 0; + s->regs[R_IDMAC_090] =3D 0; + s->regs[R_IDMAC_094] =3D 0; + s->regs[R_IDMAC_098] =3D 0; + s->regs[R_IDMAC_09C] =3D 0; + s->regs[R_IDMAC_0A0] =3D 0; + s->regs[R_IDMAC_0A4] =3D 0; + } else { + s->regs[R_IDMAC_08C] =3D 0; + s->regs[R_IDMAC_090] =3D 0; + s->regs[R_IDMAC_094] =3D 0; + s->regs[R_IDMAC_098] =3D 0; + } + s->idmac_desc_addr =3D 0; + s->idmac_suspended =3D false; + s->idmac_fatal =3D false; +} + +static uint64_t dw_mci_ctrl_pre_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + if (value & R_CTRL_RESET_MASK) { + /* + * CTRL.controller_reset only resets the BIU/CIU interface and its + * state machines. In particular, it must not clear registers, FI= FO + * contents, interrupt state, or the IDMAC CSR block. + */ + s->transfer_active =3D false; + s->transfer_remaining =3D 0; + s->transfer_send_stop =3D false; + value &=3D ~(BIT(6) | BIT(7) | BIT(8)); + } + if (value & R_CTRL_FIFO_RESET_MASK) { + dw_mci_fifo_reset(s); + } + /* CTRL.dma_reset belongs to the external DMA handshake, not IDMAC */ + return value & ~(R_CTRL_RESET_MASK | R_CTRL_FIFO_RESET_MASK | + R_CTRL_DMA_RESET_MASK); +} + +static void dw_mci_ctrl_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + dw_mci_update_irq(s); +} + +static void dw_mci_pwren_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + if (value & 1) { + sdbus_set_voltage(&s->sdbus, SD_VOLTAGE_3_3V); + } +} + +static uint64_t dw_mci_cmd_pre_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + uint32_t command =3D value; + + if (command & R_CMD_START_MASK) { + dw_mci_send_command(s, command); + } + return command & ~R_CMD_START_MASK; +} + +static void dw_mci_status_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + dw_mci_update_fifo_interrupts(s); +} + +static uint64_t dw_mci_mintsts_post_read(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + return s->regs[R_RINTSTS] & s->regs[R_INTMASK]; +} + +static uint64_t dw_mci_status_post_read(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + uint32_t capacity =3D dw_mci_fifo_capacity(s); + uint32_t fifo_words =3D DIV_ROUND_UP(s->fifo_len, sizeof(uint32_t)); + uint32_t tx_wmark =3D FIELD_EX32(s->regs[R_FIFOTH], FIFOTH, TX_WMARK); + uint32_t rx_wmark =3D FIELD_EX32(s->regs[R_FIFOTH], FIFOTH, RX_WMARK); + uint32_t status =3D s->regs[R_STATUS] & R_STATUS_RESPONSE_INDEX_MASK; + + status =3D FIELD_DP32(status, STATUS, FIFO_COUNT, fifo_words); + if (!s->fifo_len) { + status |=3D R_STATUS_FIFO_EMPTY_MASK; + } + if (s->fifo_len >=3D capacity) { + status |=3D R_STATUS_FIFO_FULL_MASK; + } + if (fifo_words > rx_wmark) { + status |=3D R_STATUS_FIFO_RX_WMARK_MASK; + } + if (fifo_words <=3D tx_wmark) { + status |=3D R_STATUS_FIFO_TX_WMARK_MASK; + } + if (s->transfer_active) { + status |=3D R_STATUS_BUSY_MASK; + } + return status; +} + +static uint64_t dw_mci_cdetect_post_read(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + return sdbus_get_inserted(&s->sdbus) ? 0 : 1; +} + +static uint64_t dw_mci_wrtprt_post_read(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + return sdbus_get_readonly(&s->sdbus) ? 1 : 0; +} + +static uint64_t dw_mci_verid_post_read(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + return s->verid; +} + +static uint64_t dw_mci_hcon_post_read(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + return s->hcon; +} + +static uint64_t dw_mci_bmod_pre_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + if (value & R_BMOD_SWRESET_MASK) { + uint32_t pbl =3D FIELD_EX32(s->regs[R_FIFOTH], FIFOTH, MSIZE); + + dw_mci_reset_idmac(s); + /* The read-only PBL mirror is not reset with the IDMAC state */ + s->regs[R_BMOD] =3D FIELD_DP32(0, BMOD, PBL, pbl); + return s->regs[R_BMOD]; + } + + /* PBL is a read-only mirror of FIFOTH.MSIZE */ + return FIELD_DP32(value, BMOD, PBL, + FIELD_EX32(s->regs[R_FIFOTH], FIFOTH, MSIZE)); +} + +static void dw_mci_bmod_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + if (s->transfer_active && dw_mci_idmac_armed(s)) { + dw_mci_run_idmac(s); + } + dw_mci_update_irq(s); +} + +static void dw_mci_pldmnd_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + /* Any write, including zero, releases the descriptor-suspend state */ + if (s->idmac_suspended && s->transfer_active && + dw_mci_idmac_armed(s)) { + s->idmac_suspended =3D false; + dw_mci_set_idmac_fsm(s, DW_MCI_IDMAC_FSM_IDLE); + dw_mci_run_idmac(s); + } +} + +static uint64_t dw_mci_pldmnd_post_read(RegisterInfo *reg, uint64_t value) +{ + return 0; +} + +static void dw_mci_fifoth_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + s->regs[R_BMOD] =3D FIELD_DP32(s->regs[R_BMOD], BMOD, PBL, + FIELD_EX32(value, FIFOTH, MSIZE)); + dw_mci_update_fifo_interrupts(s); +} + +static void dw_mci_uhs_post_write(RegisterInfo *reg, uint64_t value) +{ + DwMciState *s =3D DW_MCI(reg->opaque); + + sdbus_set_voltage(&s->sdbus, value & BIT(0) ? + SD_VOLTAGE_1_8V : SD_VOLTAGE_3_3V); +} + +static const RegisterAccessInfo dw_mci_regs_info[] =3D { + { .name =3D "CTRL", .addr =3D A_CTRL, .reset =3D BIT(24), + .pre_write =3D dw_mci_ctrl_pre_write, + .post_write =3D dw_mci_ctrl_post_write }, + { .name =3D "PWREN", .addr =3D A_PWREN, .ro =3D UINT32_MAX ^ BIT(0), + .post_write =3D dw_mci_pwren_post_write }, + { .name =3D "CLKDIV", .addr =3D A_CLKDIV, .ro =3D 0xffffff00 }, + { .name =3D "CLKSRC", .addr =3D A_CLKSRC, .ro =3D 0xfffffffc }, + { .name =3D "CLKENA", .addr =3D A_CLKENA, + .ro =3D UINT32_MAX ^ (BIT(0) | BIT(16)) }, + { .name =3D "TMOUT", .addr =3D A_TMOUT, .reset =3D 0xffffff40 }, + { .name =3D "CTYPE", .addr =3D A_CTYPE, + .ro =3D UINT32_MAX ^ (BIT(0) | BIT(16)) }, + { .name =3D "BLKSIZ", .addr =3D A_BLKSIZ, .reset =3D 0x200, + .ro =3D 0xffff0000 }, + { .name =3D "BYTCNT", .addr =3D A_BYTCNT, .reset =3D 0x200 }, + { .name =3D "INTMASK", .addr =3D A_INTMASK, + .post_write =3D dw_mci_ctrl_post_write }, + { .name =3D "CMDARG", .addr =3D A_CMDARG }, + { .name =3D "CMD", .addr =3D A_CMD, + .pre_write =3D dw_mci_cmd_pre_write }, + { .name =3D "RESP0", .addr =3D A_RESP0, .ro =3D UINT32_MAX }, + { .name =3D "RESP1", .addr =3D A_RESP1, .ro =3D UINT32_MAX }, + { .name =3D "RESP2", .addr =3D A_RESP2, .ro =3D UINT32_MAX }, + { .name =3D "RESP3", .addr =3D A_RESP3, .ro =3D UINT32_MAX }, + { .name =3D "MINTSTS", .addr =3D A_MINTSTS, .ro =3D UINT32_MAX, + .post_read =3D dw_mci_mintsts_post_read }, + { .name =3D "RINTSTS", .addr =3D A_RINTSTS, .w1c =3D UINT32_MAX, + .post_write =3D dw_mci_status_post_write }, + { .name =3D "STATUS", .addr =3D A_STATUS, .ro =3D UINT32_MAX, + .reset =3D R_STATUS_FIFO_EMPTY_MASK | R_STATUS_FIFO_TX_WMARK_MASK, + .post_read =3D dw_mci_status_post_read }, + { .name =3D "FIFOTH", .addr =3D A_FIFOTH, + .ro =3D 0x8000f000, + .post_write =3D dw_mci_fifoth_post_write }, + { .name =3D "CDETECT", .addr =3D A_CDETECT, .ro =3D UINT32_MAX, + .post_read =3D dw_mci_cdetect_post_read }, + { .name =3D "WRTPRT", .addr =3D A_WRTPRT, .ro =3D UINT32_MAX, + .post_read =3D dw_mci_wrtprt_post_read }, + { .name =3D "GPIO", .addr =3D A_GPIO, + .ro =3D 0xff0000ff }, + { .name =3D "TCBCNT", .addr =3D A_TCBCNT, .ro =3D UINT32_MAX }, + { .name =3D "TBBCNT", .addr =3D A_TBBCNT, .ro =3D UINT32_MAX }, + { .name =3D "DEBNCE", .addr =3D A_DEBNCE, .reset =3D 0x00ffffff, + .ro =3D 0xff000000 }, + { .name =3D "USRID", .addr =3D A_USRID }, + { .name =3D "VERID", .addr =3D A_VERID, .ro =3D UINT32_MAX, + .post_read =3D dw_mci_verid_post_read }, + { .name =3D "HCON", .addr =3D A_HCON, .ro =3D UINT32_MAX, + .post_read =3D dw_mci_hcon_post_read }, + { .name =3D "UHS_REG", .addr =3D A_UHS_REG, + .ro =3D UINT32_MAX ^ (BIT(0) | BIT(16)), + .post_write =3D dw_mci_uhs_post_write }, + { .name =3D "RST_N", .addr =3D A_RST_N, + .ro =3D UINT32_MAX ^ BIT(0) }, + { .name =3D "BMOD", .addr =3D A_BMOD, .ro =3D 0xffffff00, + .pre_write =3D dw_mci_bmod_pre_write, + .post_write =3D dw_mci_bmod_post_write }, + { .name =3D "PLDMND", .addr =3D A_PLDMND, + .post_write =3D dw_mci_pldmnd_post_write, + .post_read =3D dw_mci_pldmnd_post_read }, + { .name =3D "CDTHRCTL", .addr =3D A_CDTHRCTL, + .ro =3D 0xf000fffe }, + { .name =3D "BACK_END_POWER", .addr =3D A_BACK_END_POWER, + .ro =3D UINT32_MAX ^ BIT(0) }, + { .name =3D "UHS_REG_EXT", .addr =3D A_UHS_REG_EXT }, + { .name =3D "DDR_REG", .addr =3D A_DDR_REG }, + { .name =3D "ENABLE_SHIFT", .addr =3D A_ENABLE_SHIFT }, +}; + +static bool dw_mci_fifo_offset(DwMciState *s, hwaddr offset) +{ + return offset >=3D s->data_offset && offset < DW_MCI_MMIO_SIZE; +} + +static uint64_t dw_mci_read(void *opaque, hwaddr offset, unsigned size) +{ + RegisterInfoArray *reg_array =3D opaque; + DwMciState *s =3D DW_MCI(register_array_get_owner(reg_array)); + DwMciClass *dmc =3D DW_MCI_GET_CLASS(s); + uint64_t value; + + if (dmc->vendor_read && dmc->vendor_read(s, offset, &value, size)) { + return value; + } + if (dw_mci_fifo_offset(s, offset)) { + if (s->regs[R_CTRL] & R_CTRL_USE_IDMAC_MASK) { + return 0; + } + return dw_mci_read_data(s, size); + } + if (dw_mci_idmac_offset(offset)) { + return size =3D=3D 4 ? dw_mci_read_idmac_register(s, offset) : 0; + } + if (size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid %u-byte access at 0x%" HWADDR_PRIx "\n", + TYPE_DW_MCI, size, offset); + return 0; + } + return register_read_memory(opaque, offset, size); +} + +static void dw_mci_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + RegisterInfoArray *reg_array =3D opaque; + DwMciState *s =3D DW_MCI(register_array_get_owner(reg_array)); + DwMciClass *dmc =3D DW_MCI_GET_CLASS(s); + + if (dmc->vendor_write && + dmc->vendor_write(s, offset, value, size)) { + return; + } + if (dw_mci_fifo_offset(s, offset)) { + if (!(s->regs[R_CTRL] & R_CTRL_USE_IDMAC_MASK)) { + dw_mci_write_data(s, value, size); + } + return; + } + if (dw_mci_idmac_offset(offset)) { + if (size =3D=3D 4) { + dw_mci_write_idmac_register(s, offset, value); + } + return; + } + if (size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid %u-byte access at 0x%" HWADDR_PRIx "\n", + TYPE_DW_MCI, size, offset); + return; + } + register_write_memory(opaque, offset, value, size); +} + +static const MemoryRegionOps dw_mci_ops =3D { + .read =3D dw_mci_read, + .write =3D dw_mci_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + .unaligned =3D false, + }, +}; + +static void dw_mci_set_inserted(DeviceState *dev, bool inserted) +{ + DwMciState *s =3D DW_MCI(dev); + + if (s->card_inserted =3D=3D inserted) { + return; + } + s->card_inserted =3D inserted; + s->regs[R_RINTSTS] |=3D DW_MCI_INT_CD; + dw_mci_update_irq(s); +} + +static void dw_mci_set_readonly(DeviceState *dev, bool readonly) +{ + DwMciState *s =3D DW_MCI(dev); + + s->card_readonly =3D readonly; +} + +static void dw_mci_bus_class_init(ObjectClass *klass, const void *data) +{ + SDBusClass *sbc =3D SD_BUS_CLASS(klass); + + sbc->set_inserted =3D dw_mci_set_inserted; + sbc->set_readonly =3D dw_mci_set_readonly; +} + +static void dw_mci_reset(DeviceState *dev) +{ + DwMciState *s =3D DW_MCI(dev); + DwMciClass *dmc =3D DW_MCI_GET_CLASS(s); + int i; + + s->transfer_active =3D false; + s->transfer_write =3D false; + s->transfer_send_stop =3D false; + s->transfer_remaining =3D 0; + s->idmac_desc_addr =3D 0; + s->idmac_suspended =3D false; + s->idmac_fatal =3D false; + dw_mci_fifo_reset(s); + memset(s->regs, 0, sizeof(s->regs)); + + for (i =3D 0; i < ARRAY_SIZE(s->regs_info); i++) { + register_reset(&s->regs_info[i]); + } + s->regs[R_FIFOTH] =3D FIELD_DP32(0, FIFOTH, RX_WMARK, + s->fifo_depth - 1); + s->regs[R_RST_N] =3D 1; + if (dmc->vendor_reset) { + dmc->vendor_reset(s); + } + s->card_inserted =3D sdbus_get_inserted(&s->sdbus); + s->card_readonly =3D sdbus_get_readonly(&s->sdbus); + sdbus_set_voltage(&s->sdbus, SD_VOLTAGE_3_3V); + dw_mci_update_irq(s); +} + +static void dw_mci_realize(DeviceState *dev, Error **errp) +{ + DwMciState *s =3D DW_MCI(dev); + + if (!s->fifo_depth || s->fifo_depth > DW_MCI_FIFO_MAX_WORDS) { + error_setg(errp, "invalid DW MCI FIFO depth %u", s->fifo_depth); + return; + } + if ((s->data_offset !=3D 0x100 && s->data_offset !=3D 0x200) || + s->data_offset >=3D DW_MCI_MMIO_SIZE) { + error_setg(errp, "invalid DW MCI DATA offset 0x%x", + s->data_offset); + } +} + +static int dw_mci_post_load(void *opaque, int version_id) +{ + DwMciState *s =3D opaque; + uint32_t capacity =3D dw_mci_fifo_capacity(s); + + if (s->fifo_head >=3D capacity || s->fifo_len > capacity) { + return -EINVAL; + } + dw_mci_update_fifo_interrupts(s); + return 0; +} + +static const VMStateDescription dw_mci_vmsd =3D { + .name =3D TYPE_DW_MCI, + .version_id =3D 1, + .minimum_version_id =3D 1, + .post_load =3D dw_mci_post_load, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, DwMciState, DW_MCI_REG_COUNT), + VMSTATE_UINT8_ARRAY(fifo, DwMciState, DW_MCI_FIFO_MAX_BYTES), + VMSTATE_UINT32(fifo_head, DwMciState), + VMSTATE_UINT32(fifo_len, DwMciState), + VMSTATE_UINT32(transfer_remaining, DwMciState), + VMSTATE_UINT64(idmac_desc_addr, DwMciState), + VMSTATE_BOOL(transfer_active, DwMciState), + VMSTATE_BOOL(transfer_write, DwMciState), + VMSTATE_BOOL(transfer_send_stop, DwMciState), + VMSTATE_BOOL(idmac_suspended, DwMciState), + VMSTATE_BOOL(idmac_fatal, DwMciState), + VMSTATE_BOOL(card_inserted, DwMciState), + VMSTATE_BOOL(card_readonly, DwMciState), + VMSTATE_END_OF_LIST() + }, +}; + +static void dw_mci_init(Object *obj) +{ + DwMciState *s =3D DW_MCI(obj); + DwMciClass *dmc =3D DW_MCI_GET_CLASS(s); + RegisterInfoArray *reg_array; + + s->verid =3D dmc->verid; + s->hcon =3D dmc->hcon; + s->data_offset =3D dmc->data_offset; + s->fifo_depth =3D dmc->fifo_depth; + + qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_DW_MCI_BUS, + DEVICE(obj), "sd-bus"); + memory_region_init(&s->iomem, obj, TYPE_DW_MCI, DW_MCI_MMIO_SIZE); + reg_array =3D register_init_block32(DEVICE(obj), dw_mci_regs_info, + ARRAY_SIZE(dw_mci_regs_info), + s->regs_info, s->regs, + &dw_mci_ops, false, + DW_MCI_MMIO_SIZE); + memory_region_add_subregion(&s->iomem, 0, ®_array->mem); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); +} + +static void dw_mci_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + DwMciClass *dmc =3D DW_MCI_CLASS(klass); + + dmc->verid =3D 0x5342240a; + dmc->hcon =3D FIELD_DP32(0, HCON, CARD_TYPE, 1); + dmc->hcon =3D FIELD_DP32(dmc->hcon, HCON, HBUS_TYPE, 1); + dmc->hcon =3D FIELD_DP32(dmc->hcon, HCON, HDATA_WIDTH, 1); + dmc->hcon =3D FIELD_DP32(dmc->hcon, HCON, HADDR_WIDTH, 9); + dmc->hcon =3D FIELD_DP32(dmc->hcon, HCON, FIFO_RAM_INSIDE, 1); + dmc->data_offset =3D 0x200; + dmc->fifo_depth =3D 256; + + dc->realize =3D dw_mci_realize; + dc->vmsd =3D &dw_mci_vmsd; + device_class_set_legacy_reset(dc, dw_mci_reset); +} + +SDBus *dw_mci_get_bus(DwMciState *s) +{ + return &s->sdbus; +} + +static const TypeInfo dw_mci_info =3D { + .name =3D TYPE_DW_MCI, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(DwMciState), + .instance_init =3D dw_mci_init, + .class_size =3D sizeof(DwMciClass), + .class_init =3D dw_mci_class_init, +}; + +static const TypeInfo dw_mci_bus_info =3D { + .name =3D TYPE_DW_MCI_BUS, + .parent =3D TYPE_SD_BUS, + .instance_size =3D sizeof(SDBus), + .class_size =3D sizeof(SDBusClass), + .class_init =3D dw_mci_bus_class_init, +}; + +static void dw_mci_register_types(void) +{ + type_register_static(&dw_mci_bus_info); + type_register_static(&dw_mci_info); +} + +type_init(dw_mci_register_types) diff --git a/hw/sd/meson.build b/hw/sd/meson.build index ebf09e30a4..d7b97cdca4 100644 --- a/hw/sd/meson.build +++ b/hw/sd/meson.build @@ -1,5 +1,6 @@ system_ss.add(when: 'CONFIG_PL181', if_true: files('pl181.c')) system_ss.add(when: 'CONFIG_SD', if_true: files('sd.c', 'core.c')) +system_ss.add(when: 'CONFIG_DW_MCI', if_true: files('dw_mci.c')) system_ss.add(when: 'CONFIG_SDHCI', if_true: files('sdhci.c')) system_ss.add(when: 'CONFIG_SDHCI_PCI', if_true: files('sdhci-pci.c')) system_ss.add(when: 'CONFIG_SSI_SD', if_true: files('ssi-sd.c')) diff --git a/include/hw/sd/dw_mci.h b/include/hw/sd/dw_mci.h new file mode 100644 index 0000000000..de4175540d --- /dev/null +++ b/include/hw/sd/dw_mci.h @@ -0,0 +1,74 @@ +/* + * Synopsys DesignWare Multimedia Card Interface + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_SD_DW_MCI_H +#define HW_SD_DW_MCI_H + +#include "hw/core/register.h" +#include "hw/core/sysbus.h" +#include "hw/sd/sd.h" +#include "qom/object.h" + +#define TYPE_DW_MCI "dw-mci" +OBJECT_DECLARE_TYPE(DwMciState, DwMciClass, DW_MCI) + +#define DW_MCI_MMIO_SIZE 0x1000 +#define DW_MCI_REG_COUNT (DW_MCI_MMIO_SIZE / sizeof(uint32_t)) +#define DW_MCI_FIFO_MAX_WORDS 2048 +#define DW_MCI_FIFO_MAX_BYTES (DW_MCI_FIFO_MAX_WORDS * sizeof(uint32_t)) + +struct DwMciState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + SDBus sdbus; + qemu_irq irq; + + uint32_t regs[DW_MCI_REG_COUNT]; + RegisterInfo regs_info[DW_MCI_REG_COUNT]; + + uint8_t fifo[DW_MCI_FIFO_MAX_BYTES]; + uint32_t fifo_head; + uint32_t fifo_len; + uint32_t transfer_remaining; + uint64_t idmac_desc_addr; + bool transfer_active; + bool transfer_write; + bool transfer_send_stop; + bool idmac_suspended; + bool idmac_fatal; + bool card_inserted; + bool card_readonly; + + uint32_t verid; + uint32_t hcon; + uint32_t data_offset; + uint32_t fifo_depth; +}; + +struct DwMciClass { + SysBusDeviceClass parent_class; + + uint32_t verid; + uint32_t hcon; + uint32_t data_offset; + uint32_t fifo_depth; + + bool (*vendor_read)(DwMciState *s, hwaddr offset, uint64_t *value, + unsigned size); + bool (*vendor_write)(DwMciState *s, hwaddr offset, uint64_t value, + unsigned size); + void (*vendor_reset)(DwMciState *s); +}; + +SDBus *dw_mci_get_bus(DwMciState *s); + +#endif --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434830; cv=pass; d=zohomail.com; s=zohoarc; b=JtOhxC+WzB7j0PUb2BWpFQRXnJQZiY+YWwJqTf7G9kJ2JC/J7oVWZupUkHuRyxVtltkmN+clA+gyWvbX5QBh52ReieE5CI1LHxiofwnsA08IGLe84uBTM/nwuxLofAe3si5IJApoY9TIgJbApjJmp6zqbusvy5g5Em/JeitXI50= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434830; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=trH1bEPf7Ar2UjDMwSViLFlOWdW+dkJyF+6cHG1jzNo=; b=O4/VxNKokusg87l/pB7qg1QK/OReLKPxcbf4LBVkhougQbfd37JmugHgnF0JrfBWMjEpqVLS3O2ACOm/J+DLaaT2EnnoZyzDekfWjIerjyNQqqu7AVJQXSTT2NIkPEQZaTogCSEwc47stgy+pdeXip+YACs8f6bKEEPpxx1zK4g= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434830448292.4857939308415; Thu, 3 Sep 2026 04:27:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aB-0005W6-EE; Thu, 03 Sep 2026 07:26:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aA-0005VS-Ck; Thu, 03 Sep 2026 07:26:14 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25a8-0006gK-K4; Thu, 03 Sep 2026 07:26:14 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:01 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:01 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nMOhYb6A1HYT8RF0aS3gDh86rOxWcBCDIz3ZhN5KPFqXfhd2x1XjYp0XEufQe5adcaSPpQqpuhHJGF9bdh8ihAgIwl/fWQ9XeKMEoaXaqpwOWzzM0M5wfTaACtA9Cw2HI0uObRb59tlRoe9xU0ZMymvSPeM3xm9lAKJAKBIBNKw9XXSraqUF4gmz/NpzV9ZrcITeMlQNV3ZwMBxZlVBHgSTZOipaUkVI16piqi9KKZiw1O0Ejzk1Ohj0EYiHOz3udzkvEE9BXbbk5XEAnsT5tA1wgxsU4KI7lLYKFefFpIgAnsXEIKNb5rJkQm3PJD7ikt3iI0G4S5vHMdl+5XDrrQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=trH1bEPf7Ar2UjDMwSViLFlOWdW+dkJyF+6cHG1jzNo=; b=ETRTwG5NUo0pMCPboLILxBQRx20QaGpivpoFYJwMTwGDHVURS9W9CC90hEV5JrX02C24dhtZHpNhm9akVq1nXyeFnT7M38MyGKdtBCEnR2KtyMKoFnzKDVJe95kNeZ9pkaGmf7LZ2FuPQ3B+ZY32fdwbEC9bpMjQmimieohSOWDTZt39QWy/dzuMfdLB8MszHJfwPJqHAlkDnf0+goYgVWghoy1q0XI3fBXEwAxgYeG/iHflXx/OfSgs35ENwFeqyuD5DVzGeA5thV1RrUPieleyif4NKr4D1BrFbfBFykSaa0SJjV/bb1BE6gmnv3HRQ9DYe/Sgq8VdHQJqD/izIA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=trH1bEPf7Ar2UjDMwSViLFlOWdW+dkJyF+6cHG1jzNo=; b=lA4x0xR0InLjWQCvu3kyjLEjhYbn0NdeR5jWfRNVsX72qsyOh8Df3+JlMHK358wh2GnKeiTmyVza+eWhQlHApcC6E6wY41evLYkGXBU0b9KooeF4mMTM776Cii3en0TlVG5+VBVMt1/04zjO8nt8s3K29MOpdIWh3nDwoyo82JeFO+8854HfVnRri2hKKZ3cCH2zAy6rjmrGiNWK2WFHer2TvSOGUWOOVKestoRplCFi9Pp+1GpQ17Z+SLULCQ705qFfRuuIiYU27LjXTMWv/Te8vQGjoq6fB6fU6hJNezvaiV9SzattPQcT8dhUKGJikOB7zYcpbviyc+nCusT0BQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Paolo Bonzini , Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 05/33] hw/sd: Add Phytium E2000 MCI controller Date: Thu, 3 Sep 2026 19:24:45 +0800 Message-ID: <20260903112532.3276678-6-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 1c3f05b9-7b8a-4b09-815d-08df09ae223b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: USr/MXcNS4RSmv2nrT/aW/8tnUZihRg44jB749ZTdRJXOHJ/Jrq4MELoN39ALf1O6mhMzwaTCVswIxfo/8Hm0KQLePQSDJn9vGeMeRMOlMtETE6mALkFh8JlkmNbPvFVv/tubhcucEm3g72WV74ocgJcxKxgmIr3BFMMdhgov1xa2o/rqIEIDF4wqyz52t71zCiL+VQpeMeK7J6J8v0a7aY9ajlLPLIhHRtIzFNuAgInvHkTTmfss2uOYRzUcp3ZtzsDkocxyLi8Vk/hqnXb0j+Yn33bkWxQub8n2vgclLFyf3hrOjjWNmidNpBhIQLleXZWyi9vLmiCr2S58O8pcoSZWAkh0IDlZZvt21VvAV9K7DQ2n1WvIae7vTgbrmlArNS7uIfYXcLAG9Tzy+C5HRpm1er/vgv5m8LQ/DS5vFbhZSo9nF2iI2E3ZrYCEBeJgf6zoljAgRm9bV31894Ug3YxMnYcv6NmikxINAxYT0TzRakfz+cr59/JYuBG5d1ZUl4CLB7xs8xC6IEB5USxxeJ09QQf1nuFICDSvsNyrADVhXbXovPli70PmR1F95dgBTkWrh4KhdoxJr3ODRcckOJzGY/7FlxJeDTuo3pZIpmoYPS0glc1oeHlo8BBLlYLaRVP8E0NN0kxiSV7qhZkehsnEaBVS7TVvV3PeckUEKI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?V9Pv4/TC4EXzmD8MT7NqSo/xxhzbRM3DdbFPa6b7GsvLkJnnZlV7tJ26shJ0?= =?us-ascii?Q?LOWt1N/wTGOHIS8YmEyjDVEfyl3JtG6afIjEOXwd8fRQX1c7J0mmPcI+wQGt?= =?us-ascii?Q?5iF4jVZQ/TNvM3Yy6icKZBkK01rf/Z+f5t6M7GhGMzKFMbW4KfmIZjYAeg12?= =?us-ascii?Q?LL4ZxIbDpwIh/0vDCYF6OfJxL8m3e+oMbRfm8A72uUeaFhB4F8Zn8xYl8Dco?= =?us-ascii?Q?jfRLvfbav2OoxsUl3ugZGM46Lx2v9QPzZvOo+TUAF5ZG+U8lD3rlz3qYJCUx?= =?us-ascii?Q?UqWamBkXs4vFoE4jx3xSUmsIYtEc0TcXul1PE0QWvho34GFx/zsTh631i0/U?= =?us-ascii?Q?TYtcMc6SRTgAQWOxeuKmtzrbeKvKZXH0qX4aW4RHdcbyoMOj4BHHEiQkl9vf?= =?us-ascii?Q?4Q9B2lZDH36gV98w++PSFG0pKKIDEyrBJKnnFIVKzy+IOqmtgVYvJzzixnQG?= =?us-ascii?Q?qZF0mTizolDYIAVDhV8YN8RPcH/cja4l0H4fwxFpb/jTEyTOPn61cTFRfbcZ?= =?us-ascii?Q?LzX3O7wNFbB7McLgJf5IlDIsA1XMahnrqHw1sa76PxZncvD7aoia7L0PmwCK?= =?us-ascii?Q?RZRmH3tCCixBGbgGhY6fLxRoVzLB4Syoz9aeZndZJ2LBjDIMjh2fPc24YB4c?= =?us-ascii?Q?P0z8woRsNzz4aVkxN+xCbOF0WY18zFgbeIwQEFBKxb/hqMTfbB8XuVo7hwkI?= =?us-ascii?Q?LoXlbA1vIYjhWsV1txd6lnXfD121ZctajV5qEv1Dk2GRyLyZ+g2VDYY7Bv6k?= =?us-ascii?Q?UiCIaLoksJFtLQOVIW3E3uFkbU3vC4kPFIzml2YvKyq3JUJnXm9rTBo1I93x?= =?us-ascii?Q?sSWbVCIcZayhcwIbc0WHRug9K9XyAIAOzd7dyXccM8nD34pkZFmkKX8sXVaF?= =?us-ascii?Q?jknKgj3FlKWLd5vP5lYqEip5gxjVUV08gtlBO6e/78BXAhfqJPGRtoFIkAiU?= =?us-ascii?Q?duKAorQfHG8tS/K+gQRtI5eBDrZoP1zZVI+hx7vnPtVXXhyDm9O4+sRyZOCV?= =?us-ascii?Q?0EGGDuMW4WqmEVCchVhAst1kKBKjBiasPxSLO8XTxkEYexq/4sh/JnY1DzHF?= =?us-ascii?Q?mPGRf6oeNEArAkpCYVymF2Sbn9P4LKJYR2JvT7CnOU1xNk11pavRNJrXm083?= =?us-ascii?Q?H9gBh8/xZplHb3iZF4JNxXbPIhG/asuihZxKOSok78UHDHGRbAxIVRboEjxN?= =?us-ascii?Q?ymxW3kM4hffq8i2teYpIubu2VlxNhHvOqvpUPAZ2s6MZBmjR3XStTExUkkGP?= =?us-ascii?Q?KdD3LvITpwyOZZSWYFC0yrypj0FDcG3IlzmtBUDdxZX0mNBRMaYiTxXoIrSG?= =?us-ascii?Q?UXncvN6gOb7ZVudukqcuqUN+gQ/2OEeYxrObSSsQ6uZsMlg9CseTP2LemCfD?= =?us-ascii?Q?M1nT7gaY7lt2HOM8vuBA4n9C5XRoOaz1zLE0BXl7j/O9zTQcU7cqFN+an0B+?= =?us-ascii?Q?8MxKy7+f9mNeyDH5VxEw9tkNEAUeEfvAjXPKnHjJ6GiFc59gLQB76Rv2DA+f?= =?us-ascii?Q?j3JplCpsF/Zgml5e8q29sRMcHVYym96s78KLalXKRJR4d3cXN0mBzsjB97CU?= =?us-ascii?Q?CwTRTtwBdV+dNI7ShVKp1v0uTv1dLcpfy5DdkzjMNP4p72AVaYgCos46QwmV?= =?us-ascii?Q?Tku/p7OnvOqR6Jli5MgNlVJPYEsDlfcci+kHVthjIRSEL/eW4Pa3i4ONViVU?= =?us-ascii?Q?q1z/fEUyx+4PvBxgf0DHJI3ICrc3DHErQMNwTzKTglWF9Cmiv6CVT+zUq40d?= =?us-ascii?Q?35idVtMjI6oqdNgg2kFYT22xDsnqERw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1c3f05b9-7b8a-4b09-815d-08df09ae223b X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:01.4542 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9x6I1dP3RTBRG1b0iKu0S5XP7goXyLpZdWcJluJ3Fr3K+LhfECJO35SZtjmup+n9hg7jtXhc2j2IEoNA1GjOPBe7gdYkNu65G0tUNyQGg0U= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434832220158500 Content-Type: text/plain; charset="utf-8" Model the E2000 SD/MMC controller as a subclass of the reusable DesignWare MCI implementation. Supply the E2000 hardware configuration, FIFO depth, data window, clock-ready behavior, and vendor divider register while inheriting the standard command and DMA paths. Signed-off-by: Bin Meng --- hw/arm/Kconfig | 1 + hw/sd/meson.build | 1 + hw/sd/phytium_e2000_mci.c | 95 +++++++++++++++++++++++++++++++ include/hw/sd/phytium_e2000_mci.h | 21 +++++++ 4 files changed, 118 insertions(+) create mode 100644 hw/sd/phytium_e2000_mci.c create mode 100644 include/hw/sd/phytium_e2000_mci.h diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index e68f137a66..99a5799b22 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -132,6 +132,7 @@ config PHYTIUM_E2000 depends on TCG && AARCH64 imply PCI_DEVICES select ARM_GIC + select DW_MCI select PCI_EXPRESS select PCI_EXPRESS_GENERIC_BRIDGE select PL011 diff --git a/hw/sd/meson.build b/hw/sd/meson.build index d7b97cdca4..5792d0c923 100644 --- a/hw/sd/meson.build +++ b/hw/sd/meson.build @@ -6,6 +6,7 @@ system_ss.add(when: 'CONFIG_SDHCI_PCI', if_true: files('sdh= ci-pci.c')) system_ss.add(when: 'CONFIG_SSI_SD', if_true: files('ssi-sd.c')) =20 system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_mmc.c')) +system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= mci.c')) system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c')) system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sdhci.c')) system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sdhos= t.c')) diff --git a/hw/sd/phytium_e2000_mci.c b/hw/sd/phytium_e2000_mci.c new file mode 100644 index 0000000000..84cfc213de --- /dev/null +++ b/hw/sd/phytium_e2000_mci.c @@ -0,0 +1,95 @@ +/* + * Phytium E2000 extension to the Synopsys DesignWare MCI + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/sd/phytium_e2000_mci.h" + +#include "qemu/bitops.h" +#include "qemu/module.h" + +#define PHYTIUM_E2000_MCI_CCLK_RDY 0x058 +#define PHYTIUM_E2000_MCI_CLK_DIVIDER 0x114 +#define PHYTIUM_E2000_MCI_VERID 0x280a +#define PHYTIUM_E2000_MCI_HCON (BIT(27) | BIT(7)) +#define PHYTIUM_E2000_MCI_DATA_OFFSET 0x200 +#define PHYTIUM_E2000_MCI_FIFO_DEPTH 512 + +struct PhytiumE2000MciState { + DwMciState parent_obj; +}; + +/* + * The vendor driver polls CCLK_RDY after programming its private divider. + * QEMU has no controller clock tree, so completion is immediate while the + * divider remains ordinary storage for firmware readback. + */ +static bool phytium_e2000_mci_read(DwMciState *s, hwaddr offset, + uint64_t *value, unsigned size) +{ + if (size !=3D sizeof(uint32_t)) { + return false; + } + + switch (offset) { + case PHYTIUM_E2000_MCI_CCLK_RDY: + *value =3D 1; + return true; + case PHYTIUM_E2000_MCI_CLK_DIVIDER: + *value =3D s->regs[offset / sizeof(uint32_t)]; + return true; + default: + return false; + } +} + +static bool phytium_e2000_mci_write(DwMciState *s, hwaddr offset, + uint64_t value, unsigned size) +{ + if (size !=3D sizeof(uint32_t)) { + return false; + } + + switch (offset) { + case PHYTIUM_E2000_MCI_CCLK_RDY: + return true; + case PHYTIUM_E2000_MCI_CLK_DIVIDER: + s->regs[offset / sizeof(uint32_t)] =3D value; + return true; + default: + return false; + } +} + +static void phytium_e2000_mci_class_init(ObjectClass *klass, const void *d= ata) +{ + DwMciClass *dmc =3D DW_MCI_CLASS(klass); + + dmc->verid =3D PHYTIUM_E2000_MCI_VERID; + dmc->hcon =3D PHYTIUM_E2000_MCI_HCON; + dmc->data_offset =3D PHYTIUM_E2000_MCI_DATA_OFFSET; + dmc->fifo_depth =3D PHYTIUM_E2000_MCI_FIFO_DEPTH; + dmc->vendor_read =3D phytium_e2000_mci_read; + dmc->vendor_write =3D phytium_e2000_mci_write; +} + +static const TypeInfo phytium_e2000_mci_info =3D { + .name =3D TYPE_PHYTIUM_E2000_MCI, + .parent =3D TYPE_DW_MCI, + .instance_size =3D sizeof(PhytiumE2000MciState), + .class_init =3D phytium_e2000_mci_class_init, +}; + +static void phytium_e2000_mci_register_types(void) +{ + type_register_static(&phytium_e2000_mci_info); +} + +type_init(phytium_e2000_mci_register_types) diff --git a/include/hw/sd/phytium_e2000_mci.h b/include/hw/sd/phytium_e200= 0_mci.h new file mode 100644 index 0000000000..cc6fce06d0 --- /dev/null +++ b/include/hw/sd/phytium_e2000_mci.h @@ -0,0 +1,21 @@ +/* + * Phytium E2000 SD/MMC controller + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_SD_PHYTIUM_E2000_MCI_H +#define HW_SD_PHYTIUM_E2000_MCI_H + +#include "hw/sd/dw_mci.h" +#include "qom/object.h" + +#define TYPE_PHYTIUM_E2000_MCI "phytium-e2000-mci" +OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000MciState, PHYTIUM_E2000_MCI) + +#endif --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434996; cv=pass; d=zohomail.com; s=zohoarc; b=OJo+1KMHGvgvhico35ybjkI9B78reIMD2Se3PlRQiBOlTETk9zvkogX1TF1D/Wzl4Nvtb14Z0F2p20hhKcNUHQACwOWtUwEzIn8qjPseJld0RBFYW4YlNbKvdyUEh9EZaqhGphCdsLtR2/5mvnjnfh1cTKR4K9EEyyJL9jxnIx4= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434996; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=mMr2MBfXZ6nzhlZEvTEEoENW6TSa2co8cwLmcENFbPo=; b=PRXXLbliZ3blcPEEgNbnnG4aac96rpuo8HqGp3njSyBjGCOWW88fponA+7xMeo6yYjxZdchTrW+N4QPucOkfoufcO4ZdGYBgS/sE74ZvGA4PJOlSOJxP/dby9yh003+g7g7to5RGSovY/EdjpJVZkr53eAmly94xFBBBp477pak= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434996649154.63383090637763; Thu, 3 Sep 2026 04:29:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aE-0005Xk-G8; Thu, 03 Sep 2026 07:26:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aD-0005X3-3S; Thu, 03 Sep 2026 07:26:17 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aB-0006gK-Aq; Thu, 03 Sep 2026 07:26:16 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:03 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:03 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KnByxuPTeZwoPJ201clRM8pZz6eU41Q4hJ6cMu2Mq1GEMy/L+QG2bRm0mrabL6jzOdjRtPhl0JFTKcdN/2WjY2Hoc1Mzc8O9CqkRK7ynz6l3gCZHWte2Gb8PYsgM4EcUkwSZXjefiLHcNoebRr/dak7Kh2g2cuRMxLNSJSGV5rcq+LSlBsU8qhpF1rzD1S5rsJlFQdWrzhz11TSLnzBGbeyl3Zl3u2sECo9cDUwVqA+D6Bq1jzy4uyYPHyxqxNLMqojp8QNG86L05xL7Xo8Zkezv7xFHzN28OjGrzZpzbBYg9qeJxKMbCUaAki5qmuN9iXNbAWQMc3BaGVVrFzuVMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mMr2MBfXZ6nzhlZEvTEEoENW6TSa2co8cwLmcENFbPo=; b=G0wvXhz5JZbBBpBnt1oZtUm3GHOKusXWhWA76VqQFqLtvmt6U4uCagwzLn2oDDVF4iUvmr71W7V3W87CM/U+0igzclak2P+Pvll1DaSZiQawB8SdYfNjdOURSQsoWnyd9km2Kwv8BWo2/DRevb8c36XVHHAr3Hs7TaRHEIrzWrDN2vNztwWcoMPKHxzt1OsikoOiV/gbTL8q5VT3pHFqSZVNhpnPXVryoqHTLM+eLPuhCbhmOrd24eA8WR5zWSLsQ42AhTMcw+kHHh6cl9tAaFHpkFGOgVjJNX5ic8lBJWZDSnpNZ3NLTJM1W/BGG+HrSgYLFPzvDJb0RkscVCJgQQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mMr2MBfXZ6nzhlZEvTEEoENW6TSa2co8cwLmcENFbPo=; b=tNKR/nUzEFEdtFS59gn2uDecoGbkAVHhJ+xg90WZ0wXIYUv/ZTOOCsj912gCRQVFG539IZOlcnLve9aYHdB9z7vRA91JilP4yDqIg2r5zaFmY+1rwTN2q9YuYzplvVUTmjmPOzWleUex2Zcrb80KClsTrWXxUCpBzdW8JwTFNr53fG755f2OOFFp2lscgLLjYTtYsZd4C5rdKF1ddnRa8ctq0Bm9uKuMLhF7NPAQTcwKc7PaGq0vJIK220jxgCaI9GlEF7WzEyQKYBMyfsUX3W0rxEkwk3Hyy+qXGi3uR4rkez2KgZ81Phifwj6M3EFcT6p/dymQr6yKdGV6/gBOZA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Paolo Bonzini , Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 06/33] hw/arm: phytium: Connect Phytium E2000 MCI controllers Date: Thu, 3 Sep 2026 19:24:46 +0800 Message-ID: <20260903112532.3276678-7-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 5b4b8c3f-496a-419e-6c5c-08df09ae236e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: YHjE9NJgL3+tjr0V3rHeTFuTRt3ltEwuSKi6WwIw4WmTyyZOWXclLVnEIQk/2ocjnzqIqTBntvHNfH7MzChGKhD5GmlTZFoZBAqMRZ92rUW2WIzUUpktwKHZSRZ7kk9iHRPvJt3nzXLU9L40oD6A4C1YnjB5cLcm5CkBiNoXIgaUaOkbE+PNEgi5IXt/2sAk2qS8n77qnplvYPLKpHYs48AvGJ4rPImGBYXe2iiKRtUlXpOR8WXSsO6etCOXAyImBDydT6jLFTyiMDvEsZlEKqZadP4PJ99S4xKb2bMLcy2qtInYSH022iFAcJrKjUh2A7kqJ5uUMy7Cx/Z7fsfTmOUdBG1PN17ZabRVcuFzT4SDNUDsw/au/n008/MnOIXfZIG98m378KT9f+RRRjMxNkPD8PZz3CYurOR43EIVDqEe27/7G04bRiVeMG9ZEusGB5fzV8DWinSy7p2NwdTp9+LemKkqvSQmzgb7zGZOtsead0A4iTarj7Gd8QRkH1Sj9EU49PlZI4G/aXj0aZmixiCoen9PbToT3POnoigpYfHk0lVI/TtYuakDJpv6DPlcBd719ikJxTPUxA8edpedZYiRRr9wAPBNIpmzsYfOnRcBcc/HPlU2YLWCh3CQ6Z5KeJWozIXe+yLIlMxPohkWyHELh9SsHP5n6popU8Fct/U= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(56012099006)(10067099003)(22082099003)(18002099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?TTZ4KHXpOBHjKOa/0gsdktX/sxXmb4+Nc3ZrAJRA4+EY3YCYH0qH1qU2TPRY?= =?us-ascii?Q?Folh7RUBGUbNT2CnzLphBF9lOgD2dLWP6D+gPmwPqBuWcOsy4aP8mF0VacDq?= =?us-ascii?Q?yBoAlVgdTE8rpZkmXDnXwSFKOWM+STb9H8wRY+z9kmAEBKyA1h7sI+Q1c7Co?= =?us-ascii?Q?qbJR1oFc1nfcZ/Br6epCyUBxWvkEfb+6D5fkNkWxU98Ngw+7Mb7nXwhBF68u?= =?us-ascii?Q?/04kQB36iYsLbu4GLJYonPYAICBO/qz33w8bTDuvJpRRG71TBTyJHG0vkX/w?= =?us-ascii?Q?aCLbUoH515nugKnfftZD+ji6zewUPdyXhypAHSikXPbzsxbYL8BZjfjMv8iX?= =?us-ascii?Q?AxRGxJyQiHCWxrenWEkyzre2CGOE9Sz90Ty9MGMG322PfA7RPrzwj/TAP8dj?= =?us-ascii?Q?ZWC4E1Be41ApWIFZwimHhFA0BXTzNL7Tn7RhP+ranVahcBqbmiUW7LSOIGCK?= =?us-ascii?Q?T7heMlYS9ilUL3nPT+9gZfQ0vNqbltSxVIzMt0p+QhVTYhHlkxCtsVon6xE6?= =?us-ascii?Q?lsnY/wzdVMqFRGIn6sXKiUoTP87Kd+dAn5mkgU1fkIDgVXnTDX0eXsxIzdw2?= =?us-ascii?Q?kKsOfzmUnJrFqUAvMpY1uiNb4yA01r4C2YsMQTrj3dcWKht3bKqrN1UASKf5?= =?us-ascii?Q?Pd16qPJUHbNdDNlqvYa2dfrBHwXX6dZ471QpbX31g7zNL4vije3peltPQzcR?= =?us-ascii?Q?JqAaiT5OzwYcMnP3dWrvL+nPh+Y1EbNARdoa7WLUNd9jo91RCuIAH9ODm3ch?= =?us-ascii?Q?KMrZKxxEQsW/tLyjQLexgaJ2GcRXo//3u5bM4yRgffP3FO+dMqcSSdbtI9rI?= =?us-ascii?Q?jYQaPstMz8nKChuMXkhMpzFkBUi8hG0zOosocyxm9AUv+727T25g+wv+UoCH?= =?us-ascii?Q?d/9CkArD8FZWkqCuT0ApcNXht24dWL+5bLyWSaDR+klb98Z0bc5ucZEgYfR8?= =?us-ascii?Q?MIOAR3cWiLF5u5QTG099SFou7Cg4sAMtee2EVrDmXsbXR4WUx7hrtgMneuUT?= =?us-ascii?Q?tXSo6DjLEKqix1hrGjMrDNB67nPWJW/Y6d9zq5H2tO4NFnugmEVYr7FqmHoh?= =?us-ascii?Q?29NQUgii/CKJQyO/6gPpkjSWQUHKJ6hmDAe9ItHV9mdwcmZemTuQNPONINQz?= =?us-ascii?Q?ixeVSm2bd2ONciEesSj7xHwQH3XE/nC/co4sarSiQqCdIj1f4bQZ3OwfwCvy?= =?us-ascii?Q?1mMyVmiRfcyXnOye+Dusouc34JTZm5u+Q0FtS5L96WkPxB9iH5DWXy72H00t?= =?us-ascii?Q?GpawV9snYkxZvRWngi+nXpYJKkKoeNyuN0MebffSU+wEzRBJnu0cZYyUlhL6?= =?us-ascii?Q?Q61B52DibgwJsLWHQ9MNvq/SY44IdAAVqqrkERuDjqkxBKCiFuhSCj6QhM2G?= =?us-ascii?Q?hYGLemcjRrBeQCFAncqDeYAvx6RiviQ3tA45nqXv7ITyQ3KRSLa2ahyDTbfm?= =?us-ascii?Q?B6FgqW7idPVR6y5sfCLwfo+cVvZinobEJIJvF4UzUbK6IC4rOP6ZR149qlKi?= =?us-ascii?Q?QPNxA61l1Xax0C+OHVAUsFa5ph06qy+hSa9uBzCGDHf2EFQnLC1oAvhqgKf2?= =?us-ascii?Q?oqEME+DPjYvsGGJm76bebxSK9+iFH52IYmC5McYA86otSLXSz02N3Ddm5Ilu?= =?us-ascii?Q?YEAIZ0svhJd0bT8bw558I8MXnqHgeVyIGSPmsxDZG9S8hUfFtDi9kCaaRoYX?= =?us-ascii?Q?6jxKBJqLkoYmuG+h79Lm+e7OcOSs3S1Nt9bQpR6iV0zmsSIwlIN7ai87IEjF?= =?us-ascii?Q?+QxatPFeuNLZJPHhSA3pKvGVwRISEtw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5b4b8c3f-496a-419e-6c5c-08df09ae236e X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:03.4654 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: awJHHFeeVjZkGE/RJuKpOpi5v8J1f1mR0ePrn1Ea2qzgVcSnVxh6RP/fWxAYGhuCsl/TAb/546zXiK1NZox9MIXR9t4vySmdS1hJpt3SLTI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434997086158500 Content-Type: text/plain; charset="utf-8" Instantiate both E2000 MCI controllers at their low-peripheral addresses, route their interrupts to the GIC, and create an SD card on each exported bus. Map legacy IF_SD backends by controller index so firmware and Linux use the same board-visible media topology. Keep the broad unimplemented aperture underneath the concrete devices and make SD the machine's default block interface. Signed-off-by: Bin Meng --- hw/arm/Kconfig | 1 + hw/arm/phytium_e2000.c | 65 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 99a5799b22..9358a47b8a 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -136,6 +136,7 @@ config PHYTIUM_E2000 select PCI_EXPRESS select PCI_EXPRESS_GENERIC_BRIDGE select PL011 + select SD select UNIMP =20 config REALVIEW diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index aac798aa07..88307184e9 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -28,6 +28,8 @@ #include "hw/misc/unimp.h" #include "hw/pci/pci.h" #include "hw/pci-host/gpex.h" +#include "hw/sd/phytium_e2000_mci.h" +#include "hw/sd/sd.h" #include "qobject/qlist.h" #include "qom/object.h" #include "target/arm/cpu.h" @@ -40,12 +42,15 @@ OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_P= I) #define PHYTIUM_E2000_NUM_CPUS 4 #define PHYTIUM_E2000_NUM_IRQS 256 =20 +#define PHYTIUM_E2000_NUM_MCIS 2 #define PHYTIUM_E2000_NUM_UARTS 7 =20 #define PHYTIUM_E2000_GTIMER_HZ 50000000 =20 enum { PHYTIUM_E2000_LOW_PERIPH, + PHYTIUM_E2000_MCI0, + PHYTIUM_E2000_MCI1, PHYTIUM_E2000_UART0, PHYTIUM_E2000_UART1, PHYTIUM_E2000_UART2, @@ -73,6 +78,7 @@ struct PhytiumE2000State { MachineState parent; struct arm_boot_info bootinfo; DeviceState *gic; + PhytiumE2000MciState *mci[PHYTIUM_E2000_NUM_MCIS]; MemoryRegion ram_low; MemoryRegion ram_high; }; @@ -84,6 +90,8 @@ struct PhytiumE2000State { */ static const MemMapEntry phytium_e2000_memmap[] =3D { [PHYTIUM_E2000_LOW_PERIPH] =3D { 0x28000000, 0x00100000 }, + [PHYTIUM_E2000_MCI0] =3D { 0x28000000, 0x00001000 }, + [PHYTIUM_E2000_MCI1] =3D { 0x28001000, 0x00001000 }, [PHYTIUM_E2000_UART0] =3D { 0x2800c000, 0x00001000 }, [PHYTIUM_E2000_UART1] =3D { 0x2800d000, 0x00001000 }, [PHYTIUM_E2000_UART2] =3D { 0x2800e000, 0x00001000 }, @@ -107,6 +115,11 @@ static const MemMapEntry phytium_e2000_memmap[] =3D { [PHYTIUM_E2000_RAM_HIGH] =3D { 0x2000000000ULL, 0x180000000ULL }, }; =20 +static const int phytium_e2000_mci_irqmap[] =3D { + [0] =3D 72, + [1] =3D 73, +}; + static const int phytium_e2000_uart_irqmap[] =3D { [0] =3D 83, [1] =3D 84, @@ -324,6 +337,55 @@ static void phytium_e2000_create_pcie(PhytiumE2000Stat= e *s) } } =20 +static BlockBackend *phytium_e2000_sd_blk(int index) +{ + DriveInfo *dinfo =3D drive_get(IF_SD, 0, index); + + return dinfo ? blk_by_legacy_dinfo(dinfo) : NULL; +} + +static void phytium_e2000_attach_sd_card(DwMciState *mci, int index) +{ + BlockBackend *blk =3D phytium_e2000_sd_blk(index); + BusState *bus =3D BUS(dw_mci_get_bus(mci)); + DeviceState *card; + + /* + * Always instantiate the socket-level card object. A missing backend = then + * behaves as an empty slot, while if=3Dsd,index=3DN gives firmware a = real SD + * card on the matching physical MCI controller. + */ + card =3D qdev_new(TYPE_SD_CARD); + qdev_prop_set_drive_err(card, "drive", blk, &error_fatal); + qdev_realize_and_unref(card, bus, &error_fatal); +} + +static void phytium_e2000_create_mci(PhytiumE2000State *s, int index) +{ + PhytiumE2000MciState *mci =3D + PHYTIUM_E2000_MCI(qdev_new(TYPE_PHYTIUM_E2000_MCI)); + DeviceState *dev =3D DEVICE(mci); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + MemoryRegion *iomem; + int map_idx =3D PHYTIUM_E2000_MCI0 + index; + g_autofree char *name =3D g_strdup_printf("mci%d", index); + + /* + * MCI0 and MCI1 occupy the first two pages of the broad low-peripheral + * placeholder. Use a higher overlap priority so real command and data + * accesses reach the controller model. + */ + s->mci[index] =3D mci; + object_property_add_child(OBJECT(s), name, OBJECT(mci)); + sysbus_realize_and_unref(sbd, &error_fatal); + iomem =3D sysbus_mmio_get_region(sbd, 0); + memory_region_add_subregion_overlap( + get_system_memory(), phytium_e2000_memmap[map_idx].base, iomem, 1); + sysbus_connect_irq(sbd, 0, + qdev_get_gpio_in(s->gic, phytium_e2000_mci_irqmap[index])); + phytium_e2000_attach_sd_card(DW_MCI(mci), index); +} + static void phytium_e2000_create_unimplemented(void) { /* @@ -443,6 +505,9 @@ static void phytium_pi_init(MachineState *ms) phytium_e2000_create_cpus(s); phytium_e2000_create_gic(s); =20 + for (i =3D 0; i < PHYTIUM_E2000_NUM_MCIS; i++) { + phytium_e2000_create_mci(s, i); + } for (i =3D 0; i < PHYTIUM_E2000_NUM_UARTS; i++) { phytium_e2000_create_uart(s, i); } --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434833; cv=pass; d=zohomail.com; s=zohoarc; b=J9hbX8ouc4EH2wj1O/7Ia/hofYKbKXMxyY3nCoqsBNjFYc6F9JN6/tLpESoB6Ehz5E8NMvL3ZrExirw7x1ZXqA9UolAuE0QwcITtsHpnmPmHgyyet8Y1PffOD8KMaZ+7hT0jH+hmBxji8Wu8LGzTDlcDuA+Du6Ya8wyxAyQIrKc= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434833; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=RIXfz26wMs8qpMe+eyckF0vSRoNrJQKNNhNJMc0rPhE=; b=ffsYeVSk00GRi3kwahkvvq5xVca+hPvRQihp/1ZP2WLAqZ9Nb7x4lSYKvCTrSb60h/UWtlum0/nd4hThH1UNFevg/66z6aQg/tRwFeNWCrAEcfPvCfAhRkquU+PvvWhsgZWhTqWlbvWKg3McAolwWYgqSiZlLEFUeQTHp4Bk/FY= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434832763740.0549683558341; Thu, 3 Sep 2026 04:27:12 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aJ-0005Zw-Ph; Thu, 03 Sep 2026 07:26:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aH-0005Z8-If; Thu, 03 Sep 2026 07:26:21 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aF-0006f9-32; Thu, 03 Sep 2026 07:26:21 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:06 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:06 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=H5wtvw2Zm3EhphL6fUinup89f+lWruBcmLLm891i6ieWNxY2zp+usRr5GXcoq89ds7xw1un7iwti0o7dJwl5wwAriUnRDLkrhFesta4qKErHrdqiYKXov8VIJxz5zNBxAZliEMpnkC/bQ4ZKOwBc4fiT44UyVwz+w7lC3UczNsmVgBCTzvwAMka1U4t1wTpzwD4GoE0LMU0c2rmiPIdMYDENKsy1Qeqg+p3gs40y9jCA92Mv+aMfhrPUSVDeF1suiK0iU+3xXE2li8sHqV0moYqYAwfKUo3tPCDw+TcLNX1LldKRhVkKsAoz16s+loIGKbrIdMyQ9xi08QQm8iIC8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RIXfz26wMs8qpMe+eyckF0vSRoNrJQKNNhNJMc0rPhE=; b=ssearvOJXfEYg8JZ4IBBfk28IQBNNxoFA60L8yyxd8L+dNGtMjCW6JIabodLafd99e+daMINqCKPEMMdAcQoEnv65t4IxO0dUt/kzAUr6qjA/YM3VIiJt25bW0b2E1v3cHbaZMhoPCiZT17sxoK5H9NNwq89sqqwMcIxOnLkQRo5dDSshulrizrs9lbZ7dpi3hWbpPAT2SfOcKVsTiL6EpGvYoP3IA6aiVVmNRZ+qehpD+0v1a5FlrBttHhei4H2PIfLcDcYfXbpp97vOzfn1Xr0iMfCHUXf2e8oeUXW/LiTM3PFvh6HH3rm606w5bUcnwGNdSq330v5bQUSuppmRg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RIXfz26wMs8qpMe+eyckF0vSRoNrJQKNNhNJMc0rPhE=; b=VfZpve/xXCee5Z9pR5tAD+7GSaPx+QsHNk0eRkbGpQIbcDp7gQ/PHZr5PyRyTFQgMNm4GTBjMwv6dU1nepn+I6XkWnmsqWGqYfM/MmHleh3ltaJPD/py1QQ4fyQP0I00T+8EOP4Oow25b0A8xq1wubw2onV4Xaic4DVAPdqYL2/2S++U+obnrxulOAwEsEHBrnfUkSBmrY1SDCgEqaVkXVTeQbJlM/zom9+Asw0a31GgPD1sykh/MB+pPIWcR1nzb4H/gP9P2R6yd1muewKMzV6xWWqvmrRDGUrZHtVEROTljPsmbN0uad4bkBzgAl9Ylx71MtlxFmAkt2l6LE6npw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Bin Meng , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , qemu-block@nongnu.org Subject: [PATCH 07/33] tests/qtest: Add Synopsys DesignWare MCI coverage Date: Thu, 3 Sep 2026 19:24:47 +0800 Message-ID: <20260903112532.3276678-8-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: e69f1c2c-b608-4b58-fbb3-08df09ae24ed X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: 3HqofjRaThmC9Q5JGtBXOhI8Ts+z/7xZO2xQjy0+10svOtHGR/u6YFauASP+o7NBBqc0WEIgxQcXD3ovqM7qRoe2KZdajPGSyWvyv1vgYFEzQNIplxn6g99asmMKYZVVTnq1bjIyrUDrxQGzkHCySNC1c8BoWCq8UQDpBTFaRUmGGFBLdQMKalPdkHeYI4q2mjNrVnZPuSNxCZi6r3FKAPsUfj3oka6LXU96AyRgLwOc5C2uiGgWVzszyr7N8B1iCTi71cvEML+dP1lO/qafMxURhdR/8yyHFiBPRpilFwS4NcZQeuhuE+gub+EW+EtKvXRV8LbbZSvJ9odNWZe0+uSgoGbTwVcAOCUncRBYQb0OUoP/vyQPdMj9LUtgM2zbVHPu1ihyKzYbGmQDt+4TZezRqP0dwa/aTuCGJb1tYupuJ5gLqGi6qBvAhcufG8mUPs/maTtw0OKYmXe/qOLnqjGzIl6xuAwvd/nJ+5d1ygjgevVtEv/vgZMc4T55jwB+6pdLcw5VNDJ1GI15v64d0+UMpdaP8z4NDwO9cIwHaHcFAm2k0cEIPq+sP87H+0WbUFhLWNEQ5dCnLqnNwDYL44PbAnZ79QvYYxVe9gWK3D4TZ90nERUvqxG4lpWb7qAcfqU3lKzuiwvOL8YzouePVCGn3r2T2mVXKA9BMJU27u8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(56012099006)(10067099003)(22082099003)(18002099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?r2shJpYOdHg9XAgm7vsqS8wnoSHi1kaGLiDNUWznb8PQc2HFk79kM90aMAEk?= =?us-ascii?Q?sPzkaOqjceN7e0rXjau828jDN89I/Oh8xSDJFoG73ommfll3oGM/A/Klp3m4?= =?us-ascii?Q?TiSrBs1wBRQ3Xb+3vEeppYonL5ei5tjmDftdzpiVDXe3BgfiZQcywCOW/ePl?= =?us-ascii?Q?fpnqApSWs25zQqKSZDXv6tKgOc+b66ypmlMwvn2R40c8sRbkh2L1cyp8bbHs?= =?us-ascii?Q?zu9TJRkAZC0etoWi4Gq6nJfS10feH+KCHzYub7vC3U4XmCYTR3hFockAwT6U?= =?us-ascii?Q?ELX8jjlmQL32uMoj1InNVjIiqnrwJj1CDNHpuqND7s26oTOh11dhLL9DUl+o?= =?us-ascii?Q?p9yMqIsE64yFxeWuY5qK7GPtneXfkSX2ZaVFqneJyfYeUuf7H34nfyBzh81H?= =?us-ascii?Q?rc7dKGsJ8uvuKsUStq5dUQ05unf9FMBV6sZPTCoiRUAtSs+SxPphP/6TFvSw?= =?us-ascii?Q?mx1fpZ4KKBdNzwtmko9xvP9wMiX4iE4w6L0i/4uKRKkD87Mc4IkJ/aQTa2S8?= =?us-ascii?Q?BngSMvYIIaF/db3zIdQlSaKtHpHq6S0QiEP98K5FrvDbAtlBfG3BpbKKoR1l?= =?us-ascii?Q?kYXNXGszyuyUbT+JWO/rPQlcWvKVMTNsdgKtfhtS3Krzuh8bwZNiSdtyXptW?= =?us-ascii?Q?Vqu07mrBiyilQg0kGvbI3Vx9o1hcqwu31++ayQdq3SdzFVra7VmjkAGVkw7x?= =?us-ascii?Q?rvRNa1jO3Sh/aku8ywGZfTCPdH8WWdgeZGlNdqsBGCt6zD0TLhmP/l7qwCA+?= =?us-ascii?Q?GQG4/wMy6Y3n73BaMGSL3kQw0VCPLQdc+i9a0IHQC0NYnX72dre74NLq7Lj9?= =?us-ascii?Q?/arKXHF64DcaytoY8XrV965N9H13DIjKJaBXqttdQKREnPB7J6Pxi8vsJhl1?= =?us-ascii?Q?QJohT+gcx2rYpLmuTYINbGtbwLHkIFcooPHrsMVfhKkuropVKO9Z1ZF2Xyw0?= =?us-ascii?Q?n4aB+ARlp7+C32jbdZRmC46oA6RNhZWO/xVT8eTzIby3FGr/hx4+98WMkOzF?= =?us-ascii?Q?M7hM1ywIeObylaROZ9xQXClaljXINea5CQt3btc0v1sIa9KKHFXf0Ti/us8x?= =?us-ascii?Q?g9Scnzm6NKNVHtDZLAmmDQHyVxqirBzLX4woApWaeehZ+wGxkJotOLwFPUKo?= =?us-ascii?Q?5dVwPbUvx4uBUk+9hmncxEp/FfonKUyRtDjyRIkq2TjW4UaLd6GUqpBu1YPo?= =?us-ascii?Q?035Fh8ZYAc+tX7MelFq/dZZZe+WKJ+TG+FkiFbDh+1MtYSxvRd/4axZEOz52?= =?us-ascii?Q?2+bXgqWuzu81nR6xCnx4FDhHYFtllql0UkPc/Opfk/IQ4TiLQWI/bVkDg+BP?= =?us-ascii?Q?DCTZzR3IW3TvlGN/KbsHU0hWYWqUNPzzkvpxFRC7EVH8JyW8gQGy5dn0z+e4?= =?us-ascii?Q?oTP+2WLAc74zdp06HQHKfht/3W14HqlZZyX/8gVMuryZGsDCNSZvGGEq6LXM?= =?us-ascii?Q?iLNFKzTkuhkBa59ykLB6Cmb2RBC/Iiw5HSp4BC3Rpy4WFe8hb/HTlf0ncR4j?= =?us-ascii?Q?cH93DtZ5yfuJP5/R8U9X2pQCztFaq70Bxt97+3lN2xOt62ZxOoEiBdDWG87Z?= =?us-ascii?Q?OWXb/AvuhVBbx/bxay9jvaG/YyjcODS2zVAilwGY+OHmXIbbuoOEQlqajIZY?= =?us-ascii?Q?Ij6TVWS42BUpFDpV6oTTeGxvIQ0xJeULdK0/efv5erRHHHGdwifkdx7Gswze?= =?us-ascii?Q?WO5KPxHLq1N99tS21abaU57g3OsBEJ/HQx69tE6fVlfwR5jvK7bNFjyNrlS8?= =?us-ascii?Q?I4heH2NXyGP88PnmOAQ9RcJ0Ncj+vcI=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: e69f1c2c-b608-4b58-fbb3-08df09ae24ed X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:06.0224 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: RVAMGS59wC9yTF3Z887iMz7sVpGgkaM7HQE8yBW7QrFhOuV0XYq2pqfbsTyl5OfaCaHK9wEHjBJ0SWMf3HNSYsbLqJDsEUP6GnA1wHj2C/s= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434834252158500 Content-Type: text/plain; charset="utf-8" Exercise the reusable DesignWare MCI behavior through the Phytium Pi board integration. Cover register reset and interrupt handling, 64-bit IDMAC write/read and suspend/resume paths, and FIFO PIO transfers against an SD image. Signed-off-by: Bin Meng --- MAINTAINERS | 1 + tests/qtest/dw_mci-test.c | 417 ++++++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 1 + 3 files changed, 419 insertions(+) create mode 100644 tests/qtest/dw_mci-test.c diff --git a/MAINTAINERS b/MAINTAINERS index 1ea3af260f..c915c5f996 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2417,6 +2417,7 @@ F: hw/sd/core.c F: hw/sd/dw_mci.c F: hw/sd/sd* F: hw/sd/ssi-sd.c +F: tests/qtest/dw_mci-test.c F: tests/qtest/fuzz-sdcard-test.c F: tests/qtest/sdhci-test.c =20 diff --git a/tests/qtest/dw_mci-test.c b/tests/qtest/dw_mci-test.c new file mode 100644 index 0000000000..c8c8b9be93 --- /dev/null +++ b/tests/qtest/dw_mci-test.c @@ -0,0 +1,417 @@ +/* + * QTests for the Synopsys DesignWare Multimedia Card Interface + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "qemu/bswap.h" +#include "qemu/units.h" +#include "libqtest.h" + +#define DW_MCI_BASE 0x28001000 + +#define DW_MCI_CTRL 0x000 +#define DW_MCI_PWREN 0x004 +#define DW_MCI_TMOUT 0x014 +#define DW_MCI_BLKSIZ 0x01c +#define DW_MCI_BYTCNT 0x020 +#define DW_MCI_INTMASK 0x024 +#define DW_MCI_CMDARG 0x028 +#define DW_MCI_CMD 0x02c +#define DW_MCI_RESP0 0x030 +#define DW_MCI_MINTSTS 0x040 +#define DW_MCI_RINTSTS 0x044 +#define DW_MCI_STATUS 0x048 +#define DW_MCI_FIFOTH 0x04c +#define DW_MCI_CDETECT 0x050 +#define DW_MCI_TCBCNT 0x05c +#define DW_MCI_TBBCNT 0x060 +#define DW_MCI_DEBNCE 0x064 +#define DW_MCI_VERID 0x06c +#define DW_MCI_HCON 0x070 +#define DW_MCI_RST_N 0x078 +#define DW_MCI_BMOD 0x080 +#define DW_MCI_PLDMND 0x084 +#define DW_MCI_DBADDRL 0x088 +#define DW_MCI_DBADDRU 0x08c +#define DW_MCI_IDSTS 0x090 +#define DW_MCI_IDINTEN 0x094 +#define DW_MCI_DSCADDRL 0x098 +#define DW_MCI_DSCADDRU 0x09c +#define DW_MCI_BUFADDRL 0x0a0 +#define DW_MCI_BUFADDRU 0x0a4 +#define DW_MCI_FIFO 0x200 + +#define DW_MCI_CTRL_INT_ENABLE BIT(4) +#define DW_MCI_CTRL_USE_IDMAC BIT(25) + +#define DW_MCI_CMD_RESP_EXP BIT(6) +#define DW_MCI_CMD_RESP_LONG BIT(7) +#define DW_MCI_CMD_DAT_EXP BIT(9) +#define DW_MCI_CMD_DAT_WR BIT(10) +#define DW_MCI_CMD_UPD_CLK BIT(21) +#define DW_MCI_CMD_START BIT(31) + +#define DW_MCI_INT_CMD_DONE BIT(2) +#define DW_MCI_INT_DATA_OVER BIT(3) +#define DW_MCI_INT_RTO BIT(8) + +#define DW_MCI_BMOD_ENABLE BIT(7) + +#define DW_MCI_IDSTS_TI BIT(0) +#define DW_MCI_IDSTS_RI BIT(1) +#define DW_MCI_IDSTS_DU BIT(4) +#define DW_MCI_IDSTS_NI BIT(8) +#define DW_MCI_IDSTS_AI BIT(9) + +#define DW_MCI_IDMAC_LD BIT(2) +#define DW_MCI_IDMAC_FS BIT(3) +#define DW_MCI_IDMAC_OWN BIT(31) + +#define DW_MCI_DESC_ADDR 0x80010000 +#define DW_MCI_DATA_ADDR 0x80011000 +#define DW_MCI_READ_ADDR 0x80012000 +#define DW_MCI_BLOCK_SIZE 512 +#define DW_MCI_IMAGE_SIZE (1 * MiB) + +static QTestState *dw_mci_start(const char *sd_path) +{ + if (sd_path) { + return qtest_initf("-machine phytium-pi -m 1G -display none " + "-drive file=3D%s,format=3Draw,if=3Dsd,index=3D= 1", + sd_path); + } + + return qtest_init("-machine phytium-pi -m 1G -display none"); +} + +static char *dw_mci_create_image(void) +{ + g_autoptr(GError) error =3D NULL; + char *path =3D NULL; + int fd; + int ret; + + fd =3D g_file_open_tmp("dw-mci-XXXXXX", &path, &error); + g_assert_no_error(error); + g_assert_cmpint(fd, >=3D, 0); + ret =3D ftruncate(fd, DW_MCI_IMAGE_SIZE); + g_assert_cmpint(ret, =3D=3D, 0); + close(fd); + + return path; +} + +static uint32_t dw_mci_command(QTestState *qts, uint32_t index, + uint32_t argument, uint32_t flags) +{ + uint32_t raw; + + qtest_writel(qts, DW_MCI_BASE + DW_MCI_RINTSTS, UINT32_MAX); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_CMDARG, argument); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_CMD, + DW_MCI_CMD_START | flags | index); + raw =3D qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS); + g_assert_cmphex(raw & DW_MCI_INT_CMD_DONE, =3D=3D, DW_MCI_INT_CMD_DONE= ); + g_assert_cmphex(raw & DW_MCI_INT_RTO, =3D=3D, 0); + + return qtest_readl(qts, DW_MCI_BASE + DW_MCI_RESP0); +} + +static void dw_mci_init_card(QTestState *qts) +{ + uint32_t rca; + + qtest_writel(qts, DW_MCI_BASE + DW_MCI_PWREN, 1); + dw_mci_command(qts, 0, 0, 0); + dw_mci_command(qts, 55, 0, DW_MCI_CMD_RESP_EXP); + dw_mci_command(qts, 41, 0x41200000, DW_MCI_CMD_RESP_EXP); + dw_mci_command(qts, 2, 0, + DW_MCI_CMD_RESP_EXP | DW_MCI_CMD_RESP_LONG); + rca =3D dw_mci_command(qts, 3, 0, DW_MCI_CMD_RESP_EXP) & 0xffff0000; + g_assert_cmphex(rca, !=3D, 0); + dw_mci_command(qts, 7, rca, DW_MCI_CMD_RESP_EXP); + dw_mci_command(qts, 16, DW_MCI_BLOCK_SIZE, DW_MCI_CMD_RESP_EXP); +} + +static void dw_mci_write_descriptor(QTestState *qts, uint32_t control, + uint32_t buffer) +{ + qtest_writel(qts, DW_MCI_DESC_ADDR, control); + qtest_writel(qts, DW_MCI_DESC_ADDR + 4, 0); + qtest_writel(qts, DW_MCI_DESC_ADDR + 8, DW_MCI_BLOCK_SIZE); + qtest_writel(qts, DW_MCI_DESC_ADDR + 12, 0); + qtest_writel(qts, DW_MCI_DESC_ADDR + 16, buffer); + qtest_writel(qts, DW_MCI_DESC_ADDR + 20, 0); + qtest_writel(qts, DW_MCI_DESC_ADDR + 24, 0); + qtest_writel(qts, DW_MCI_DESC_ADDR + 28, 0); +} + +static void dw_mci_prepare_idmac(QTestState *qts, uint32_t interrupts) +{ + qtest_writel(qts, DW_MCI_BASE + DW_MCI_CTRL, + DW_MCI_CTRL_USE_IDMAC); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_BMOD, + DW_MCI_BMOD_ENABLE); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_BLKSIZ, + DW_MCI_BLOCK_SIZE); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_BYTCNT, + DW_MCI_BLOCK_SIZE); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_DBADDRL, + DW_MCI_DESC_ADDR); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_DBADDRU, 0); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_IDINTEN, interrupts); +} + +static void test_registers_and_irq(void) +{ + QTestState *qts =3D dw_mci_start(NULL); + + qtest_irq_intercept_out_named(qts, "/machine/mci1", "sysbus-irq"); + + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_CTRL), =3D=3D, + BIT(24)); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_STATUS) & + (BIT(1) | BIT(2)), =3D=3D, BIT(1) | BIT(2)); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_TMOUT), =3D=3D, + 0xffffff40); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_BLKSIZ), =3D=3D, + DW_MCI_BLOCK_SIZE); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_BYTCNT), =3D=3D, + DW_MCI_BLOCK_SIZE); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_FIFOTH), =3D=3D, + 0x01ff0000); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_CDETECT), =3D=3D= , 1); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DEBNCE), =3D=3D, + 0x00ffffff); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_VERID), =3D=3D, + 0x280a); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_HCON), =3D=3D, + 0x08000080); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RST_N), =3D=3D, = 1); + + /* Exercise the 64-bit IDMAC layout selected by HCON.ADDR_CONFIG */ + qtest_writel(qts, DW_MCI_BASE + DW_MCI_DBADDRL, + DW_MCI_DESC_ADDR + 3); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DBADDRL), =3D=3D, + DW_MCI_DESC_ADDR); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_DBADDRU, 1); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DBADDRU), =3D=3D= , 1); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_IDINTEN, + DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_IDINTEN), =3D=3D, + DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DSCADDRU), =3D= =3D, 0); + + qtest_writel(qts, DW_MCI_BASE + DW_MCI_RINTSTS, UINT32_MAX); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_CMD, + DW_MCI_CMD_START | DW_MCI_CMD_UPD_CLK); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS) & + DW_MCI_INT_CMD_DONE, =3D=3D, 0); + + qtest_writel(qts, DW_MCI_BASE + DW_MCI_CTRL, + DW_MCI_CTRL_INT_ENABLE); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_INTMASK, + DW_MCI_INT_CMD_DONE | DW_MCI_INT_RTO); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_CMD, + DW_MCI_CMD_START | DW_MCI_CMD_RESP_EXP); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_MINTSTS), =3D=3D, + DW_MCI_INT_CMD_DONE | DW_MCI_INT_RTO); + g_assert_true(qtest_get_irq(qts, 0)); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_RINTSTS, + DW_MCI_INT_CMD_DONE | DW_MCI_INT_RTO); + g_assert_false(qtest_get_irq(qts, 0)); + + qtest_system_reset(qts); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_CTRL), =3D=3D, + BIT(24)); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS), =3D=3D= , 0); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_BMOD), =3D=3D, 0= ); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DBADDRL), =3D=3D= , 0); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DBADDRU), =3D=3D= , 0); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_IDINTEN), =3D=3D= , 0); + qtest_quit(qts); +} + +static void test_idmac_write_and_read(void) +{ + g_autofree char *sd_path =3D dw_mci_create_image(); + uint8_t pattern[DW_MCI_BLOCK_SIZE]; + uint8_t actual[DW_MCI_BLOCK_SIZE]; + uint8_t zero[DW_MCI_BLOCK_SIZE] =3D { 0 }; + QTestState *qts =3D dw_mci_start(sd_path); + uint32_t status; + size_t i; + ssize_t size; + int fd; + + qtest_irq_intercept_out_named(qts, "/machine/mci1", "sysbus-irq"); + dw_mci_init_card(qts); + + for (i =3D 0; i < sizeof(pattern); i++) { + pattern[i] =3D i ^ 0xa5; + } + qtest_memwrite(qts, DW_MCI_DATA_ADDR, pattern, sizeof(pattern)); + dw_mci_write_descriptor(qts, + DW_MCI_IDMAC_OWN | DW_MCI_IDMAC_FS | + DW_MCI_IDMAC_LD, + DW_MCI_DATA_ADDR); + dw_mci_prepare_idmac(qts, DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI); + dw_mci_command(qts, 24, 0, + DW_MCI_CMD_RESP_EXP | DW_MCI_CMD_DAT_EXP | + DW_MCI_CMD_DAT_WR); + + g_assert_cmphex(qtest_readl(qts, DW_MCI_DESC_ADDR) & + DW_MCI_IDMAC_OWN, =3D=3D, 0); + status =3D qtest_readl(qts, DW_MCI_BASE + DW_MCI_IDSTS); + g_assert_cmphex(status & (DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI), =3D=3D, + DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DSCADDRL), =3D= =3D, + DW_MCI_DESC_ADDR); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_DSCADDRU), =3D= =3D, 0); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_BUFADDRL), =3D= =3D, + DW_MCI_DATA_ADDR); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_BUFADDRU), =3D= =3D, 0); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS) & + DW_MCI_INT_DATA_OVER, =3D=3D, DW_MCI_INT_DATA_OVER); + g_assert_true(qtest_get_irq(qts, 0)); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_IDSTS, + DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI); + g_assert_false(qtest_get_irq(qts, 0)); + + qtest_memwrite(qts, DW_MCI_READ_ADDR, zero, sizeof(zero)); + dw_mci_write_descriptor(qts, + DW_MCI_IDMAC_OWN | DW_MCI_IDMAC_FS | + DW_MCI_IDMAC_LD, + DW_MCI_READ_ADDR); + dw_mci_prepare_idmac(qts, DW_MCI_IDSTS_RI | DW_MCI_IDSTS_NI); + dw_mci_command(qts, 17, 0, + DW_MCI_CMD_RESP_EXP | DW_MCI_CMD_DAT_EXP); + qtest_memread(qts, DW_MCI_READ_ADDR, actual, sizeof(actual)); + g_assert_cmpmem(actual, sizeof(actual), pattern, sizeof(pattern)); + status =3D qtest_readl(qts, DW_MCI_BASE + DW_MCI_IDSTS); + g_assert_cmphex(status & (DW_MCI_IDSTS_RI | DW_MCI_IDSTS_NI), =3D=3D, + DW_MCI_IDSTS_RI | DW_MCI_IDSTS_NI); + qtest_quit(qts); + + fd =3D open(sd_path, O_RDONLY); + g_assert_cmpint(fd, >=3D, 0); + size =3D read(fd, actual, sizeof(actual)); + close(fd); + g_assert_cmpint(size, =3D=3D, sizeof(actual)); + g_assert_cmpmem(actual, sizeof(actual), pattern, sizeof(pattern)); + unlink(sd_path); +} + +static void test_idmac_suspend_and_resume(void) +{ + g_autofree char *sd_path =3D dw_mci_create_image(); + uint8_t pattern[DW_MCI_BLOCK_SIZE]; + QTestState *qts =3D dw_mci_start(sd_path); + uint32_t status; + size_t i; + + qtest_irq_intercept_out_named(qts, "/machine/mci1", "sysbus-irq"); + dw_mci_init_card(qts); + + for (i =3D 0; i < sizeof(pattern); i++) { + pattern[i] =3D i ^ 0x69; + } + qtest_memwrite(qts, DW_MCI_DATA_ADDR, pattern, sizeof(pattern)); + dw_mci_write_descriptor(qts, 0, DW_MCI_DATA_ADDR); + dw_mci_prepare_idmac(qts, + DW_MCI_IDSTS_TI | DW_MCI_IDSTS_DU | + DW_MCI_IDSTS_NI | DW_MCI_IDSTS_AI); + dw_mci_command(qts, 24, 0, + DW_MCI_CMD_RESP_EXP | DW_MCI_CMD_DAT_EXP | + DW_MCI_CMD_DAT_WR); + + status =3D qtest_readl(qts, DW_MCI_BASE + DW_MCI_IDSTS); + g_assert_cmphex(status & (DW_MCI_IDSTS_DU | DW_MCI_IDSTS_AI), =3D=3D, + DW_MCI_IDSTS_DU | DW_MCI_IDSTS_AI); + g_assert_cmphex((status >> 13) & 0xf, =3D=3D, 1); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS) & + DW_MCI_INT_DATA_OVER, =3D=3D, 0); + g_assert_true(qtest_get_irq(qts, 0)); + + qtest_writel(qts, DW_MCI_BASE + DW_MCI_IDSTS, + DW_MCI_IDSTS_DU | DW_MCI_IDSTS_AI); + g_assert_false(qtest_get_irq(qts, 0)); + dw_mci_write_descriptor(qts, + DW_MCI_IDMAC_OWN | DW_MCI_IDMAC_FS | + DW_MCI_IDMAC_LD, + DW_MCI_DATA_ADDR); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_PLDMND, 0); + + status =3D qtest_readl(qts, DW_MCI_BASE + DW_MCI_IDSTS); + g_assert_cmphex(status & (DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI), =3D=3D, + DW_MCI_IDSTS_TI | DW_MCI_IDSTS_NI); + g_assert_cmphex((status >> 13) & 0xf, =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS) & + DW_MCI_INT_DATA_OVER, =3D=3D, DW_MCI_INT_DATA_OVER); + g_assert_true(qtest_get_irq(qts, 0)); + + qtest_quit(qts); + unlink(sd_path); +} + +static void test_fifo_data_port(void) +{ + g_autofree char *sd_path =3D dw_mci_create_image(); + uint8_t pattern[DW_MCI_BLOCK_SIZE]; + uint8_t actual[DW_MCI_BLOCK_SIZE]; + QTestState *qts =3D dw_mci_start(sd_path); + size_t i; + ssize_t size; + int fd; + + dw_mci_init_card(qts); + for (i =3D 0; i < sizeof(pattern); i++) { + pattern[i] =3D i ^ 0x3c; + } + + qtest_writel(qts, DW_MCI_BASE + DW_MCI_BLKSIZ, DW_MCI_BLOCK_SIZE); + qtest_writel(qts, DW_MCI_BASE + DW_MCI_BYTCNT, DW_MCI_BLOCK_SIZE); + dw_mci_command(qts, 24, 0, + DW_MCI_CMD_RESP_EXP | DW_MCI_CMD_DAT_EXP | + DW_MCI_CMD_DAT_WR); + for (i =3D 0; i < sizeof(pattern); i +=3D sizeof(uint32_t)) { + qtest_writel(qts, DW_MCI_BASE + DW_MCI_FIFO + (i % 64), + ldl_le_p(pattern + i)); + } + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_TCBCNT), =3D=3D, + DW_MCI_BLOCK_SIZE); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_TBBCNT), =3D=3D, + DW_MCI_BLOCK_SIZE); + g_assert_cmphex(qtest_readl(qts, DW_MCI_BASE + DW_MCI_RINTSTS) & + DW_MCI_INT_DATA_OVER, =3D=3D, DW_MCI_INT_DATA_OVER); + qtest_quit(qts); + + fd =3D open(sd_path, O_RDONLY); + g_assert_cmpint(fd, >=3D, 0); + size =3D read(fd, actual, sizeof(actual)); + close(fd); + g_assert_cmpint(size, =3D=3D, sizeof(actual)); + g_assert_cmpmem(actual, sizeof(actual), pattern, sizeof(pattern)); + unlink(sd_path); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("dw-mci/registers-and-irq", test_registers_and_irq); + qtest_add_func("dw-mci/idmac-write-and-read", test_idmac_write_and_rea= d); + qtest_add_func("dw-mci/idmac-suspend-and-resume", + test_idmac_suspend_and_resume); + qtest_add_func("dw-mci/fifo-data-port", test_fifo_data_port); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 50a1a5272f..de47741ff1 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -279,6 +279,7 @@ qtests_aarch64 =3D \ config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test',= 'tpm-tis-i2c-swtpm-test'] : []) + \ (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed64 : [])= + \ (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \ + (config_all_devices.has_key('CONFIG_PHYTIUM_E2000') ? ['dw_mci-test'] : = []) + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_ARM_VIRT') ? ['iommu-smmuv3-test'] : []) + \ --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434932; cv=pass; d=zohomail.com; s=zohoarc; b=bReAjdknWuZGtkQ4oCp9TS3PxSjKFOZsMk5EHO0mcRFFHDgUNHv/InmvfpiiiRoZIuQ4HYFNRytWD70jT7Zo/BGTnXEkotLwTcnqZ0PjqFmOoC84peClpLezyOlswrMnISlEl0HJWdgW36ba2jQb9t6de1sXFkX4ZMDYoJSGjMw= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434932; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tyE5diPs9tc+ibUZFSef20+fLdVx7hybKj/Pa7imnGc=; b=jY7mATXFNtxE11C3fiXI5OsJHuk0T6K8EmTOc4SzNutJXtbgMvxSsjsavkBtqvmgpj+GfYgvAzEmaOzcY4gTUriuH7zOfQwL2CXbhEl91/IcOd4dv1urVOrK4cZua503JnWHRcoN0tK++ywYYMm7WKqp3HleGOtDaO11mK6CLfw= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434932837608.2418660123395; Thu, 3 Sep 2026 04:28:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aI-0005Zp-P8; Thu, 03 Sep 2026 07:26:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aG-0005Yu-RC; Thu, 03 Sep 2026 07:26:20 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aF-0006gK-1b; Thu, 03 Sep 2026 07:26:20 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:08 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:08 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=c+RP5o0wVSTTef4hWy7kuCFWHILQP8hBPGSg6Rd3gYYvtP9iMv5s3Zz8R2aDZ0qRDT+BY675asgAcEU/ByNNsYKklBeCyjVFogOBU50k1iHY5Uq1mSdSf3w7tzpcPj0eGCr0vwMSVbHi9n3he9Ldv0rVpPhWJ/+QCGezpfZyFJnetUDwADUkbTxpKQoBTWFAfiIyy67mN0Wh6xONDhBEzcp3QxR/tkcvILrtBw5ysPGroxIltk22weyPvQV5BaH/3wbZ7LB3XJMovnbAf2RArWxOysdhPTVSlItKfH/ZczUtk1+8I3jxTy3eISvNVMJBfxkocN2av4NHjy3w2gT5bA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=tyE5diPs9tc+ibUZFSef20+fLdVx7hybKj/Pa7imnGc=; b=NukK5w1Wf6Vu+f75daUQ6HX44dIkPe+fSbGQDBP++n7RiNmrf7uwDA7wTc006ZMXVZ53cXliwKrZgTF8Qbv7GjLhzieafgIWqtYAH0R8N+tyidQti5ba6ZdKJXZ6N1fXQiwb8PqgksVo/NOO8Q+ednNiUz7qbbLZVygGfBfidu0G3yaBecpEDWJLi6Q3ZsvWSac42BkWDS3YVE8v285ErqPZ5WMVMKu32BtWTo1oocGxE42jWe+32RPA7PFfTMTgY1Wkh+pu7s+NgVs34XJmhCdDoRTC5QZqryRphbi7JQysr+r7sclfmN4KzgLZ1EhfqbBT6zZ9gTWF1s59JQs2Ng== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tyE5diPs9tc+ibUZFSef20+fLdVx7hybKj/Pa7imnGc=; b=Ns1iALbPTVu/N2KfTteP6HBYxlOOhsyCnlczWboHeXFEN5VqKAgU+qw733EJEP9KCO44yyaP5dffYNOu9r5XXAtqauNJxtfsuSH5ceuCOp0VSxCn1qG+Rq3ZvjJXPtuubFO9Ru9m+Jwg/91zTSXWKSkaZCWC5JRrabUIFdo62Ga/SsbUwFquh4V7Li2fhNscBGW1fsGw8kVusXDRqs5jQ9+lr2hhasxs2BLOtxiuyU43mz7mOi6JCTh/bbmx12HDQExFGm6oDb4rZqxqw5OoYIdipscWwP5d/ce744H0aMjK3ZL0eAwzFfYlueRWHIKFwHCfg4IBogg5bHs8urnLeg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Paolo Bonzini , Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 08/33] hw/arm: phytium: Connect Phytium E2000 GEM controllers Date: Thu, 3 Sep 2026 19:24:48 +0800 Message-ID: <20260903112532.3276678-9-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: ec7b4494-e48b-4a1f-b09c-08df09ae2623 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|5023799004|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: yQMG1qvnFWNJXBSaQsoX9bxVXdF0sPUQ61qbduFxBqFmnaY6P4edYocHwIWFZaFa47zOU5yD6GAyuuGSqxrFBe0MfytyKEhlyVR3sV4qkNEtQqTlcnu28D0ldOSKXVZMHU1+O2RsEGI+/JXI/U31q84Q7AQ8WExowo0Nxw7vVz/aD1CBhZnfnEgTbTtF562TiG/W9uqk+a9D5950g7HWyMcPvY9aRKqB3QrWINzhHD1H+qRBkMChXxrOYY+fTGLwWhbl5iod2HuMmAvW75/65vg27gkDEMIllQGw/DAa3+rGjovd9pDV5YCDyuYAeEBR39GC4iiG0zmYQlC4Sii77CVzbOczxxQluef2dfHV05O4sZGgut4ENAYf2sx3E5W0wozUPxv7BlOOTqP8ef3zpxHgdy3q3LHnjpJeE5qKa4glMBNzzS7v+i0YcxGhZQaZ8S+TACpILWwELYXg5KtQ/+yUJefwuZug/USC7F0v/3NbuW77sE/C7g05P552sxZIVrqNFNWyMJl8kHPkrb7mfGOZEFp4tNmYrzcj5uMLaGHJQNn/ipCLbCjSHxdy9cMDw5LrURVV7fwAFec1uqZEShfg6rXzupmwcw1pO2PW5YZM+CGep0UFEKxRNuHbtklh72j+rNYcDn1ScNIfDmwLlAAS4gCGwCaFko+8ptYV7wE= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(5023799004)(56012099006)(10067099003)(22082099003)(18002099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?dbzzB/m9W2jLPBQnNIDlQ0E0wFp7BdDSICIf4pN8uyNZ8XWKhv7YnvmVaBdO?= =?us-ascii?Q?lQWK80zCVK5LmwkMOwihArYdhIefehjDTfohT2v/0rWBsi1Jm4yYUJ5l8/jQ?= =?us-ascii?Q?u9kz/d+w+d7uHpNQlUGSsy6+DSXsTfusBWNY3YzWmGtJ1yQSMqtU2stADsWz?= =?us-ascii?Q?A3JYXBhgB6768zB3w4x7U+WqP9iPmc9DvKVkGii1/VIaC1d/3TvN+Tk3gvRr?= =?us-ascii?Q?SPwkZhptzYhhgFN5OnJjGqJigAPrzyT/jc5AStOBb5kSFJeO+j0OxpU3nI4U?= =?us-ascii?Q?ZieSCcw+NOcRRSc63ekQHVRnfYP+7kqDCr5qPnQr0aUr5OcnudRRfmL2JXZT?= =?us-ascii?Q?HILyCw4EgTDiW3ubfcd+Fe+9SOoFdaANN6oE2j+9KjE21IkUNRDFGB/rU7U3?= =?us-ascii?Q?xtSkvjqIsCxa0lHTaIc0yHH7ByeCaDFLdBHVpQVxiYI8evpoEHZVl4I6g0D/?= =?us-ascii?Q?FGz8Aq2XtN9J4du58PR6n8vdUMCIRQYL9Zn3Tppa1EBXszbR5oRYeFykcwrr?= =?us-ascii?Q?uMPD0KQlT9USTJ9eMmTTuldWjRsNk4JIC/FfkbZoHiapZUQ9qmF4Pf8cEUdu?= =?us-ascii?Q?BCNb26tCuQDDW/vH2uB9M/FBb3q4I9MySmiJIBYEmAqKQyuRgPuDW2SBECxR?= =?us-ascii?Q?Y4CfFZDe8Nt1DJDFM7FUWIepD0sJ0l6UbT+o3pe1Lbr5pDgnflTZP5raU+ES?= =?us-ascii?Q?GR04cFacDXbaCqHoNKEkhJYm6/a2JYH8MX2t0kIY56ohjHn1qvcesByih9Fs?= =?us-ascii?Q?Kd5lHrSMtf1A9C6/16JPfKEBJzBmeSlz9NjS9XFIFpPifhhYeU6yUrGMKkT3?= =?us-ascii?Q?lTxcWSMTqsizXk0SMNyDexod3pJip4V0HpuCuJMzcIlZTZo8TOI/r3ywoFQf?= =?us-ascii?Q?G/chgKgo8CeGsmsRbSZqXfclGEEz7ZTYOVki4sy0elqmXkUIy7iCDAljUmMB?= =?us-ascii?Q?aAeYTymcBANzg9ycHSEt+awztP2K/fc6jJjh3VQuREHGG6RIBBBY3wyhW2Yg?= =?us-ascii?Q?mx0lTe9LYBoFTVh6vvoIqGz9yJkeR53d6ZC6C9YwZfHzq62mTEsPIAdKU47c?= =?us-ascii?Q?OBZbgHsc+/KN4mH4mZVUvIWYNhTTi0QSI/yU5wuyvX601vRbFJvcailAnmYc?= =?us-ascii?Q?WUvwky0MKO4PvHoJRmOkNGBQI30/FHGX7yJaMRHQ/tFTYNfkLI9lhk6fD3Fn?= =?us-ascii?Q?5NFO1Jre0ZQd7TzjZ7lKr/Gou7a/uEk3HkXXCaoqq1IEvUoF1qBmOJlmIdcB?= =?us-ascii?Q?/XwRS0Flybl5FrCXM6APud1MMyfS4vRkZjhqHTunTmf8QRl+zzOkoOSHk08x?= =?us-ascii?Q?q7teWYFGRPCEkMIv/O/V3PsLtID15fwewtxRcq7x09f8Ge9Hz6Ulh7WViS1C?= =?us-ascii?Q?GkLFPxPHrsw2AxbUtstZ1XNpMVb2bsOON+sAHdtDaDMe7+bHmc09ATl9AmON?= =?us-ascii?Q?lplGFRaDkw5QnTw9/fpiDQckUxggpzVMvTWx1dSmBQEKTN8Qt+mLLJLAYD57?= =?us-ascii?Q?5PNiGLXAystMlZWc3dcJn2UK9OdqZpnKOs/fS8o2TJt2JYyVBUYJeCySdNAV?= =?us-ascii?Q?sACMNLTEcKesdXzNjO3Bg6G7hLxWUkeo2v4tlZWlrEJUgDllJ+hIaJotwq4J?= =?us-ascii?Q?ZMbtPZPuS47iik+UeqdDeThIg2g4rgSQQc4TzI545C9f1x7ZK2p0ocZPQZXb?= =?us-ascii?Q?xdJ1AmKDsqg7W0LvPQGiXh3zL6DKYLAhx0aPJ2xQObY7s33whzTgQRFCYhVp?= =?us-ascii?Q?7cnAjql2v6z6V1AxxbB8moZKKLqaTZw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: ec7b4494-e48b-4a1f-b09c-08df09ae2623 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:08.0068 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: JA1J1aIrYO5uQ7ZuLsgqHz5TnewDLpbdl3MIUi2w61i8hEQzj98mEaD87ezy+LwiKmw42HvEfmpkPjw+Da5uG555ranPvQIA68/qpFK2D6U= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434934720158500 Content-Type: text/plain; charset="utf-8" Instantiate all four standard Cadence GEM controllers described by the E2000 SoC device tree. The generic model implements the first 0x800 bytes of each 0x2000-byte E2000 aperture, so cover the complete window with a low-priority unimplemented region and map the Cadence registers on top. This accepts accesses to the SoC-specific clock and SerDes selectors without inventing their behavior. Connect eight queue interrupts for GEM0 and four for GEM1 through GEM3, and configure the PCS, MDIO PHY address and 16360-byte jumbo limit expected by the SDK drivers. Signed-off-by: Bin Meng --- hw/arm/Kconfig | 1 + hw/arm/phytium_e2000.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 9358a47b8a..08128232ca 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -132,6 +132,7 @@ config PHYTIUM_E2000 depends on TCG && AARCH64 imply PCI_DEVICES select ARM_GIC + select CADENCE select DW_MCI select PCI_EXPRESS select PCI_EXPRESS_GENERIC_BRIDGE diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index 88307184e9..c68a565330 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -26,10 +26,12 @@ #include "hw/intc/arm_gicv3_common.h" #include "hw/intc/arm_gicv3_its_common.h" #include "hw/misc/unimp.h" +#include "hw/net/cadence_gem.h" #include "hw/pci/pci.h" #include "hw/pci-host/gpex.h" #include "hw/sd/phytium_e2000_mci.h" #include "hw/sd/sd.h" +#include "net/net.h" #include "qobject/qlist.h" #include "qom/object.h" #include "target/arm/cpu.h" @@ -44,6 +46,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_PI) =20 #define PHYTIUM_E2000_NUM_MCIS 2 #define PHYTIUM_E2000_NUM_UARTS 7 +#define PHYTIUM_E2000_NUM_GEMS 4 =20 #define PHYTIUM_E2000_GTIMER_HZ 50000000 =20 @@ -65,6 +68,10 @@ enum { PHYTIUM_E2000_PCIE_CTRL, PHYTIUM_E2000_PCIE_PHY_CTRL, PHYTIUM_E2000_BOARD_CTRL, + PHYTIUM_E2000_GEM0, + PHYTIUM_E2000_GEM1, + PHYTIUM_E2000_GEM2, + PHYTIUM_E2000_GEM3, PHYTIUM_E2000_BOOT_IACC, PHYTIUM_E2000_PCIE_ECAM, PHYTIUM_E2000_PCIE_PIO, @@ -79,6 +86,7 @@ struct PhytiumE2000State { struct arm_boot_info bootinfo; DeviceState *gic; PhytiumE2000MciState *mci[PHYTIUM_E2000_NUM_MCIS]; + CadenceGEMState *gem[PHYTIUM_E2000_NUM_GEMS]; MemoryRegion ram_low; MemoryRegion ram_high; }; @@ -106,6 +114,10 @@ static const MemMapEntry phytium_e2000_memmap[] =3D { [PHYTIUM_E2000_PCIE_CTRL] =3D { 0x31000000, 0x00200000 }, [PHYTIUM_E2000_PCIE_PHY_CTRL] =3D { 0x31500000, 0x00001000 }, [PHYTIUM_E2000_BOARD_CTRL] =3D { 0x31800000, 0x01400000 }, + [PHYTIUM_E2000_GEM0] =3D { 0x3200c000, 0x00002000 }, + [PHYTIUM_E2000_GEM1] =3D { 0x3200e000, 0x00002000 }, + [PHYTIUM_E2000_GEM2] =3D { 0x32010000, 0x00002000 }, + [PHYTIUM_E2000_GEM3] =3D { 0x32012000, 0x00002000 }, [PHYTIUM_E2000_BOOT_IACC] =3D { 0x38000000, 0x08000000 }, [PHYTIUM_E2000_PCIE_ECAM] =3D { 0x40000000, 0x10000000 }, [PHYTIUM_E2000_PCIE_PIO] =3D { 0x50000000, 0x00f00000 }, @@ -130,6 +142,16 @@ static const int phytium_e2000_uart_irqmap[] =3D { [6] =3D 107, }; =20 +static const uint8_t phytium_e2000_gem_num_queues[] =3D { 8, 4, 4, 4 }; + +static const int phytium_e2000_gem_irqmap[PHYTIUM_E2000_NUM_GEMS] + [MAX_PRIORITY_QUEUES] =3D { + [0] =3D { 55, 56, 57, 58, 28, 29, 30, 31 }, + [1] =3D { 59, 60, 61, 62 }, + [2] =3D { 64, 65, 66, 67 }, + [3] =3D { 68, 69, 70, 71 }, +}; + static const int phytium_e2000_pcie_irqmap[PCI_NUM_PINS] =3D { [0] =3D 4, [1] =3D 5, @@ -255,6 +277,43 @@ static void phytium_e2000_create_uart(PhytiumE2000Stat= e *s, int index) qdev_get_gpio_in(s->gic, phytium_e2000_uart_irqmap[index])); } =20 +static void phytium_e2000_create_gem(PhytiumE2000State *s, int index) +{ + DeviceState *dev =3D qdev_new(TYPE_CADENCE_GEM); + CadenceGEMState *gem =3D CADENCE_GEM(dev); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + g_autofree char *name =3D g_strdup_printf("gem%d", index); + g_autofree char *unimp_name =3D + g_strdup_printf("phytium-e2000.gem%d-unimplemented", index); + int map_idx =3D PHYTIUM_E2000_GEM0 + index; + hwaddr base =3D phytium_e2000_memmap[map_idx].base; + int i; + + s->gem[index] =3D gem; + object_property_add_child(OBJECT(s), name, OBJECT(dev)); + + qemu_configure_nic_device(dev, true, name); + qdev_prop_set_uint8(dev, "phy-addr", 0); + qdev_prop_set_uint8(dev, "num-priority-queues", + phytium_e2000_gem_num_queues[index]); + qdev_prop_set_uint16(dev, "jumbo-max-len", 16360); + qdev_prop_set_bit(dev, "pcs-enabled", true); + + /* + * The E2000 exposes a 0x2000-byte aperture, while the generic Cadence + * model implements the first 0x800 bytes. Catch accesses to the remai= ning + * SoC-specific registers without inventing their clock and SerDes eff= ects. + */ + create_unimplemented_device(unimp_name, base, + phytium_e2000_memmap[map_idx].size); + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map(sbd, 0, base); + for (i =3D 0; i < phytium_e2000_gem_num_queues[index]; i++) { + sysbus_connect_irq(sbd, i, + qdev_get_gpio_in(s->gic, phytium_e2000_gem_irqmap[index][i])); + } +} + /* The vendor DT maps root-bus INTx solely by pin */ static int phytium_e2000_pcie_map_irq(PCIDevice *pdev, int pin) { @@ -511,6 +570,9 @@ static void phytium_pi_init(MachineState *ms) for (i =3D 0; i < PHYTIUM_E2000_NUM_UARTS; i++) { phytium_e2000_create_uart(s, i); } + for (i =3D 0; i < PHYTIUM_E2000_NUM_GEMS; i++) { + phytium_e2000_create_gem(s, i); + } =20 phytium_e2000_create_pcie(s); =20 --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434925; cv=pass; d=zohomail.com; s=zohoarc; b=cgOxIYS79B8wvnWRKzsVWNxgc/czYlZ8DjFLvFrnKMBjICZaW2wSjLDBIe7R1OI66ZSCPPTaOI94TZ7Ese4WMt3dZUlxXAw9uEMIUNBJpDT0hl6Xltm0wPG365/iWkR0NJ85FXP+YUBQmt9HHZBD743t59xvOTaB8kYBe1sllAM= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434925; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5Bwt5xuT8uavNLv9mvjSW+ertxOy/H7bnmDCr4wucNg=; b=HrmUOEgf1vAIrsyg5E4cTi3EQYpZPb186EqhGyuLMbSA6X4+brNsveHFPhIc+rfjdQkFdXwNA+uMgJn2esUqzMUi9IHqzEpTJNTcGVYJrJsb81gixgq9E0BYOP4FGmOs6e7rqcAhJyYjm6E0kHtUynb7sAfWgFPBKNgy3Ie91qU= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434925472766.5646781285424; Thu, 3 Sep 2026 04:28:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aL-0005bB-0R; Thu, 03 Sep 2026 07:26:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aJ-0005aa-UT; Thu, 03 Sep 2026 07:26:23 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aH-0006gK-MT; Thu, 03 Sep 2026 07:26:23 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:09 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:09 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=BK8WYhgVUVNFd2JOACJak05mPhhYqKZol8gv5RKxrCBmASiteIHpX9LmcEhdlO2UbXB+nCNTU7eBSmx0xIJSxzVuLNFjIMD9LH+0NNjZwYw09fXLCzmHQDnVBWdV/bkDIv9Z9Qg4AdNqdamXDb9f5VktxHammGMCpbxL3hGeDIGarC/fgakhGvxl/2EmQCxt5XKjY8sgnHrxeH8H8lNKkfpjMaMGdRdzesLbUW+gtWXz1Pc4f9e2N8Z9KiKcTK7taRSwqCac7rF68vQJ9uM4SixMjAxjVkQ3wyxB8CITJgg72JXLeaGb/5Y0FuG06EKHranSHvBYAV3o+xWuzbtJxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5Bwt5xuT8uavNLv9mvjSW+ertxOy/H7bnmDCr4wucNg=; b=uzlIexzuJS5QYKBT/KM75pg3JOupig2wqXcm6YMbozjWeXLWAChZKvpEBRIQu8WBIAm6Cr7AdWNpP2bUjAIr8hZi6yBbulghkMPkjQ67fceUbw5dRESb+LbyN/AMJ0is+WWwqYyE6uG/jT17/hvMTW99vXKpkUpICFSSuKRgQYX+d23MLbBX18KNvx0EO9QimhNy4CwVK2wnBUl706m2UlUIYJQWuQkPlkdUX5MFJZaJ9KdftrPpo/rYxLSOgq6qsZ9KsdSwqr/fr+vxAecHdh/Sm+Xd5Hci7dF6OoRonNRh77z0IOFPT8gjfHXiUrFbtwJUevy0TRMgilMf6UXROA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5Bwt5xuT8uavNLv9mvjSW+ertxOy/H7bnmDCr4wucNg=; b=ndD3b1feUBCN/vBR8yyXrMU+VlJ9qe0pxLAm80FcsyGFsRb14MQ4Kc3GpZael5zZw+WB70Jywrex1LHfpHdm/B7ffVhsLJZcY5hRBM3TRxPUCHv/qBhfgA7CHQSccM7KZPX/yoqihHHdjwhbjnA8nMF1Z1vjLsdl4upaWyOB5gswHKiI2m/CYYMxdcdhBUY57zEFRSWi7yxcj1RZcgOYkpy2W1OHBKbzRxqgJdiKUQPndJENqCMCdHlFZb3dbmMyqWcvdhVaaP5UjKspoN+7uATd1T6fa8tlwjw6cPseE7rOEn/uxIuGTbD2vdzbmYIlziohJz9dYxrhEXkFNcOnrw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: qemu-arm@nongnu.org Subject: [PATCH 09/33] hw/misc: Add Phytium E2000 DDR status Date: Thu, 3 Sep 2026 19:24:49 +0800 Message-ID: <20260903112532.3276678-10-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 436745a2-8d39-48f7-a1b2-08df09ae2716 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: 8sYhFw/MbrThknwhZ7xh3BqP2aNYpbLa83H2y/Tg9aVBFlqwgwR4Ts1ULZLndfSNb9HTF/RcHMWgyyHMIM4OzWqWT6VoSCzeJ3nc3ry19Tw+F+/5G24bm2lubANVe8TJNLsSZzI+KYY1fVqQcjbc2W6GG4Fr2q7IVFfuCU/WCyYjEpswAq/OiU8NrlxsyiPvosRXkQubh2kB0Shn9bp23TT8I4pe5Z1N8FtR1TWHu+Bk8sgzkHUtTAivsTRFgD3Ie+PqgEVhlMUhYiVjanAXbOjcwDPn427VfOkHwm1XVQpNRhn8XX5OZmkVKAtvZHxr7j1hoe0RnRDyq61FKjpvZGSajuWMiyc0Xbc/r3IDjD2hdCbzzRqwMxyRf1P1tOhB3Z1oAou8l3qwASTF2rrywCKn0ezpL+mRtPaUrJXBW/UePLVTr0Um6ik/nxvI7F2bra7kMjBNI2vq4lXPJ7Nab3WJeeb1+ZVvato08IIZqd1x4QBQEPSHDCJBoIhYUXKY/dzJkMIgBAMoCz6JJTlUg13BEJjRZWOO+KACHIsf6XD+tqG+75EMgOeBxoFBA3Za5+hcj/xleUonz8xKySvGtsYIU2xqlulG9cRIu6ICUfCvvZMYpEi+sAMIX3fiHu2zG8kWYUwpjeRZ7c706qPIRlRwocoBAi6o+OmlIIQkgEs= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?dK+mYCYl+gM54XM52jG3DQKOfUbKakT9ukKMvbnRCOgV6tgDRLHebkt9zqMi?= =?us-ascii?Q?MvdcB0xt1s8Fwx9i6u3ioYBLGNrkBVY/KhrFQK0bjP5iRgqEglN26nQSw67q?= =?us-ascii?Q?ugP5rJYkJJzol9civBTQecjhfnJ5pZpvvluZqBUrb0uoJWwPEfDyzWwtxWtE?= =?us-ascii?Q?eG2GVmv/NlvjUdNt7xlge5KI5sabUtmNZeZ3V3bFM3s8y8+VSOHiKfraqFPi?= =?us-ascii?Q?53JO6/MM+CBaC/kLKkaFuahWqqSSQ9L9c4k3MoszSW7uv0ByqsHi1R8tiseu?= =?us-ascii?Q?jGpARcuowannSXQylgDnM1IFMBo187VzYKIy8NDk/ZpWFd94djbaC3C/+1Sv?= =?us-ascii?Q?cceG45x5w0evXfHmaamZc+1oVWVn+xqlZ5qLm2/5BTsJtgOZzKlWSTBRaO+f?= =?us-ascii?Q?+MC4AwW3bZDXl5qCt5lwkBQkD3zf74YL2uBGmKL1IsQpiq3xKCobwLHl3BdY?= =?us-ascii?Q?+GS3afJz9kVUdyQ6HKYSvA5fGdtqUETLvS7eHhNzz6UP5jRHzn+YYnDaPQF3?= =?us-ascii?Q?irrXWa2tKEqPMEplggTD/WeIaNbFwBi43Bg3cKmjW6qzG+9dsB+pb5Lmmxn+?= =?us-ascii?Q?G2ygxJOc39OMiXOZ3gmJaqdJ2wt+VPbbBuKSdboryEPcqrRwyAuL0GAZiPEt?= =?us-ascii?Q?fepdsuxEnJUbdUErJMqi5Uj6Zss7K3s0WsKkvjPyupKY2L2y8mLl/ne3eFqR?= =?us-ascii?Q?4QhLM8gtQh3wu8s72W53rBGa66Vh6ffAEZIuq8YyGUXPVlYBMBN7VkaXVRSD?= =?us-ascii?Q?JHZY91NL9VjT9SbxSq74GrcS4u+UT/H0tmDPdit2lVpcJchC36UrM4dfC/2j?= =?us-ascii?Q?zlf9tU2tPrzaSJw5k+GOk/3ubvT7wWSqQCHbCYCWQok+MQzQZ0shiJjIxFDu?= =?us-ascii?Q?tSAXHYt3WHo53UHlUDFhbtxxNyJ1mDLHAjyVFls4y1PDdQwOnGR2z8PiRrVw?= =?us-ascii?Q?cTiM2ZXe9h76xivTv58AXmxxiXQJqygDWqMf2VyA3Hj1mTs3Qq0bMvwcLk5O?= =?us-ascii?Q?bEKxH1kXdclOsLCHkrSZM9csGxEo25J/X/Q4d4AcqVONMwUmNIb2RuboXLAt?= =?us-ascii?Q?OzK93sUarJl4zhi1kyMnPoSZIGwir6d/TWsSCbScqjPLa6Yv8294rqPEAJIo?= =?us-ascii?Q?J9EYceodwaWBZzj1uk9jM3v5aHuNg8/fTUS79Kof/G8+vOxpJSeOJ1tJEoNb?= =?us-ascii?Q?vc9W3mK4OlDgurf8dn5H6wriozLrCPlWsBe2l8OWJ/VTirhvQ5KiRIfTjkrd?= =?us-ascii?Q?89hSALbURZL/ZJJA1kvniKLSqU3ZppRHiU2Xp2eqdUmZnxSOO5eASeS7CvpT?= =?us-ascii?Q?jXomluK5XQSIzgeR5q3hbv7H4TeCSvjJssiVH9BZy6LIIOuwioiKnpPIdxmt?= =?us-ascii?Q?ZE9kW7xcvC+HmjkH6KfmRTyFumg97l2vJ7eoUlCLPz4uPKb9AyJ79qjycI48?= =?us-ascii?Q?kyl7vpPdJO12ovHnKIQmUn+paA19HRIHn2v0hE+J5/0c1ZhHCxLMI+kw5LXn?= =?us-ascii?Q?QLHbiHC/KqBxDMR+6YH+Fl67DA9aMYLzUeVxRM9JwHWu4zvaGB1B8NpA2x4b?= =?us-ascii?Q?7tI1wkLd5Ax8ei/qtp7wGp1JKh8j95zdLOuaP6sea0ToV5c+tvMRKyMEwe2t?= =?us-ascii?Q?dux7tyoRmw2Woqmp3LtSTISFmlJAUXKzURvEKbZxoo+3AqOVfFYasqEp5BWD?= =?us-ascii?Q?FM3op87K0WkME3+g1athcyynWOa+KccrxFi8k/FfErI+k7jI2CXCYJNt1DIg?= =?us-ascii?Q?CB1uj5l4upG2UY4vXSquqjXDOQ/uIPI=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 436745a2-8d39-48f7-a1b2-08df09ae2716 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:09.5978 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: oUb/h7ykS8N+vyZyLSKZdZpQZ2WEw/E7olFjDBL3yGJnaMehQjxxGUNv5MAnRQ/D/0SU/z/KEw3kC7/tSUEobu18nNbTG9JliyBnHtpRvfY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434926800158500 Content-Type: text/plain; charset="utf-8" Move the E2000 DDR initialization and training compatibility window into a first-class registerinfo device. Keep ordinary aligned registers as persistent storage and implement the indirect selector/value interface used by the vendor PBF. Return the expected initialization, PHY training, update, and BIST results, including the training-error range. This models the firmware contract without attempting a timing-accurate DDR PHY. Signed-off-by: Bin Meng --- hw/misc/meson.build | 1 + hw/misc/phytium_e2000_ddr.c | 197 ++++++++++++++++++++++++++++ include/hw/misc/phytium_e2000_ddr.h | 23 ++++ 3 files changed, 221 insertions(+) create mode 100644 hw/misc/phytium_e2000_ddr.c create mode 100644 include/hw/misc/phytium_e2000_ddr.h diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 54e07aacda..898cf6ea87 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -16,6 +16,7 @@ system_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l= 2x0.c')) system_ss.add(when: 'CONFIG_INTEGRATOR_DEBUG', if_true: files('arm_integra= tor_debug.c')) system_ss.add(when: 'CONFIG_A9SCU', if_true: files('a9scu.c')) system_ss.add(when: 'CONFIG_ARM11SCU', if_true: files('arm11scu.c')) +system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= ddr.c')) =20 system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_ras.c')) =20 diff --git a/hw/misc/phytium_e2000_ddr.c b/hw/misc/phytium_e2000_ddr.c new file mode 100644 index 0000000000..ab46a46961 --- /dev/null +++ b/hw/misc/phytium_e2000_ddr.c @@ -0,0 +1,197 @@ +/* + * Phytium E2000 DDR training status + * + * The vendor firmware accesses controller and PHY state through an indexed + * selector/value window. This functional model reproduces the completion = and + * error predicates used during boot; it does not simulate analog DDR trai= ning + * or generate physical calibration results. + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/misc/phytium_e2000_ddr.h" + +#include "hw/core/register.h" +#include "migration/vmstate.h" +#include "qemu/module.h" + +REG32(SELECTOR, 0x80) +REG32(VALUE, 0x84) + +#define PHYTIUM_E2000_DDR_R_MAX \ + (PHYTIUM_E2000_DDR_MMIO_SIZE / sizeof(uint32_t)) +/* + * Selectors encode a register index as a byte offset. PBF uses separate + * direct, indirect, and training banks distinguished by 0x800 and 0x1000 + * index biases. + */ +#define PHYTIUM_E2000_DDR_SELECTOR(reg) ((reg) * 4) +#define PHYTIUM_E2000_DDR_INDIRECT_SELECTOR(reg) (((reg) + 0x800) * 4) +#define PHYTIUM_E2000_DDR_TRAINING_SELECTOR(reg) (((reg) + 0x1000) * 4) +#define PHYTIUM_E2000_DDR_TRAINING_ERR_FIRST 0xc72 +#define PHYTIUM_E2000_DDR_TRAINING_ERR_LAST 0xc79 + +struct PhytiumE2000DDRState { + SysBusDevice parent_obj; + + uint32_t regs[PHYTIUM_E2000_DDR_R_MAX]; + RegisterInfo regs_info[PHYTIUM_E2000_DDR_R_MAX]; + RegisterAccessInfo regs_access_info[PHYTIUM_E2000_DDR_R_MAX]; +}; + +static uint64_t phytium_e2000_ddr_value_post_read(RegisterInfo *reg, + uint64_t value) +{ + PhytiumE2000DDRState *s =3D PHYTIUM_E2000_DDR(reg->opaque); + uint32_t selector =3D s->regs[R_SELECTOR]; + + /* + * These fixed selectors are controller/PHY polls observed in the test= ed + * firmware. Return only the ready and completion bits that its loops + * require, without assigning behavior to the surrounding register ban= k. + */ + switch (selector) { + case PHYTIUM_E2000_DDR_INDIRECT_SELECTOR(0xdc): + return BIT(0); + case PHYTIUM_E2000_DDR_SELECTOR(0x256): + return BIT(0) | BIT(25); + case PHYTIUM_E2000_DDR_INDIRECT_SELECTOR(0x76): + return BIT(0) | BIT(14) | BIT(27); + case PHYTIUM_E2000_DDR_SELECTOR(0x10f): + return 0x40U << 24; + case PHYTIUM_E2000_DDR_SELECTOR(0x229): + return BIT(0); + case PHYTIUM_E2000_DDR_SELECTOR(0x257): + return BIT(3); + case PHYTIUM_E2000_DDR_SELECTOR(0x255): + return BIT(16); + case PHYTIUM_E2000_DDR_SELECTOR(0x1d5): + return BIT(16) | BIT(24) | BIT(25); + default: + /* + * The training bank is read repeatedly for lane state and error + * summaries. Error selectors report no failure; the remaining val= ues + * are deterministic so repeated sweeps see stable lane data. + */ + if (selector >=3D PHYTIUM_E2000_DDR_TRAINING_SELECTOR(0) && + selector < PHYTIUM_E2000_DDR_TRAINING_SELECTOR(0x1000)) { + uint32_t index =3D selector / sizeof(uint32_t) - 0x1000; + + if (index >=3D PHYTIUM_E2000_DDR_TRAINING_ERR_FIRST && + index <=3D PHYTIUM_E2000_DDR_TRAINING_ERR_LAST) { + return 0; + } + /* + * Preserve the masks and flag combinations checked by the PBF + * training algorithm for these recurring low-byte selectors. + */ + if ((index & 0xff) =3D=3D 0x34) { + return 0x00000fff; + } + if ((index & 0xff) =3D=3D 0x38) { + return BIT(4) | BIT(5); + } + if ((index & 0xff) =3D=3D 0x83) { + return 0; + } + if ((index & 0xff) =3D=3D 0x3b) { + return 0x01234567U | BIT(26) | BIT(27); + } + return 0x01234567U; + } + /* + * Unclassified offsets retain ordinary register storage. This kee= ps + * setup writes readable without pretending they affect DDR timing. + */ + return value; + } +} + +static const MemoryRegionOps phytium_e2000_ddr_ops =3D { + .read =3D register_read_memory, + .write =3D register_write_memory, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static void phytium_e2000_ddr_reset(DeviceState *dev) +{ + PhytiumE2000DDRState *s =3D PHYTIUM_E2000_DDR(dev); + int i; + + for (i =3D 0; i < PHYTIUM_E2000_DDR_R_MAX; i++) { + register_reset(&s->regs_info[i]); + } +} + +static void phytium_e2000_ddr_init(Object *obj) +{ + PhytiumE2000DDRState *s =3D PHYTIUM_E2000_DDR(obj); + RegisterInfoArray *reg_array; + int i; + + /* + * Firmware may touch any word in this compact window before selecting= a + * status source, so create registerinfo metadata for the full apertur= e and + * specialize only SELECTOR and VALUE. + */ + for (i =3D 0; i < PHYTIUM_E2000_DDR_R_MAX; i++) { + s->regs_access_info[i].name =3D "DDR_STATUS"; + s->regs_access_info[i].addr =3D i * sizeof(uint32_t); + } + s->regs_access_info[R_SELECTOR].name =3D "SELECTOR"; + s->regs_access_info[R_VALUE].name =3D "VALUE"; + s->regs_access_info[R_VALUE].ro =3D UINT32_MAX; + s->regs_access_info[R_VALUE].post_read =3D + phytium_e2000_ddr_value_post_read; + + reg_array =3D register_init_block32( + DEVICE(obj), s->regs_access_info, PHYTIUM_E2000_DDR_R_MAX, + s->regs_info, s->regs, &phytium_e2000_ddr_ops, false, + PHYTIUM_E2000_DDR_MMIO_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), ®_array->mem); +} + +static const VMStateDescription phytium_e2000_ddr_vmsd =3D { + .name =3D TYPE_PHYTIUM_E2000_DDR, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, PhytiumE2000DDRState, + PHYTIUM_E2000_DDR_R_MAX), + VMSTATE_END_OF_LIST() + }, +}; + +static void phytium_e2000_ddr_class_init(ObjectClass *klass, const void *d= ata) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &phytium_e2000_ddr_vmsd; + device_class_set_legacy_reset(dc, phytium_e2000_ddr_reset); +} + +static const TypeInfo phytium_e2000_ddr_info =3D { + .name =3D TYPE_PHYTIUM_E2000_DDR, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(PhytiumE2000DDRState), + .instance_init =3D phytium_e2000_ddr_init, + .class_init =3D phytium_e2000_ddr_class_init, +}; + +static void phytium_e2000_ddr_register_types(void) +{ + type_register_static(&phytium_e2000_ddr_info); +} + +type_init(phytium_e2000_ddr_register_types) diff --git a/include/hw/misc/phytium_e2000_ddr.h b/include/hw/misc/phytium_= e2000_ddr.h new file mode 100644 index 0000000000..91dc661106 --- /dev/null +++ b/include/hw/misc/phytium_e2000_ddr.h @@ -0,0 +1,23 @@ +/* + * Phytium E2000 DDR training status + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_PHYTIUM_E2000_DDR_H +#define HW_MISC_PHYTIUM_E2000_DDR_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define TYPE_PHYTIUM_E2000_DDR "phytium-e2000-ddr" +OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000DDRState, PHYTIUM_E2000_DDR) + +#define PHYTIUM_E2000_DDR_MMIO_SIZE 0x400 + +#endif --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434908; cv=pass; d=zohomail.com; s=zohoarc; b=VvwR+7SdOprVzegbVeyiP1k3wXA8WFXBtOFc9LzE8cj+m0UZ8Y6RzR/5tSl/+3VNe32q+Q6RqD/9bZRzh/vQHbTXzXcR+dJWR4nhnGv4RNPp99OvGQ+Jog2R+DglUeYve8QH4AN0tRh0FRn6EY4TeEHfUROa/HAiRAv0wZBUy+M= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434908; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AuPQv9wUpkh+ZqJ9ZmbI39uB/S6gKKCZcnD8xCRFkoU=; b=M2XqCGFTFMl1hlTZZ078aW6yrdPpRb4U89iTlCgw8eh7ur37a0N+qItUu/ezBa1s6kx3KDw5NzMwwuNADRmaalnLjfVmcRhovcyWFfRNQC7oaJrkreW6lPBQ5fRJH1dbvRa/uEQIvnn5ClQnIVVAi8dcVlvLtRPCBN3qmvG/ZgE= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434908478618.9490430926315; Thu, 3 Sep 2026 04:28:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aL-0005bC-1m; Thu, 03 Sep 2026 07:26:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aK-0005at-6B; Thu, 03 Sep 2026 07:26:24 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aI-0006f9-Lb; Thu, 03 Sep 2026 07:26:23 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:11 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:11 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pNABOMBtzXV682Q1bzpdwQtjbzQ6dPHzEyg9nXT8gdtV1CSdUKIdHP5S9hq4vbmMA+snKEeKs9XPf6Upb45ajbnMVPnmzEQy1y+GrEhRADY5D7lNpStIJzduFFwkBi246jdjqCEnTL2Oo7ibvjC1wD///DAMD4twLdX2MKHMDRooEuC7I2tG9fDqYQOu7IP7qRay6+hOEiAuMFT0gUIRhca7am6GN0KUV+pUFEKzHmG7qU11HECogvWuNajhMRSITpwWYPT5H0jVwWKQg2XtFUWa6A2IhnP5y7WuBSxIgJakrXS+YtB8e3Tb5YWiLpoNhUqPvAGDdxuI61we7KcBhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=AuPQv9wUpkh+ZqJ9ZmbI39uB/S6gKKCZcnD8xCRFkoU=; b=jMmtuUpUnojkLf8hufKaI87cQd6E7y2qjFfMwUxJFLAgZMT7e66cCQB2u7vQvtMHnDAiiqyvr/rNNBWRE/DASmCmzKipoB35JPBEGs2RilTptbVPY8E07/S/Ewj8fedvHB/cX+eCZo5wM4uiSwuA4Kypo9J0rnyjAh+tRX53u98RB0MSBOtFFCnF35X2wERuFkn0CaA/PNlkNJft+RiNLesuLX2xPBmpaDQmGILhn8wAqQx3oF7vsxriOziYO4xLi4xrWvM4MSmol/eCwS4MhJKS20fPYyNlUvgSvYIlIVmxaPv24/8Edjanpv+BLVq8w7ioAexJxfY+s6xdeWNT1Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=AuPQv9wUpkh+ZqJ9ZmbI39uB/S6gKKCZcnD8xCRFkoU=; b=ro+/X7pxDyOqERHGnhQK0gJWtMxD87LcXz6s/6zVWoX9SsuAOfMXpTt6kueyTYjZk6NG35OsNDoFdNlOHCSXIMtjCFiriepfOK+Z2A/c0fJQCRKGNvc0wJbBf4HiXPJ75xa3TNRyhg6g8BCy8h1A48IGsDgJ39lX8HN9bquYAA7JYH7KZraVPSqFuYAWNEcHrBpHOGjybvE9iIE/+YKtATaMbIW9oF1kjWEcmxpcapqCoV+at5z4m40qq5XgwkClU436RAAdYpZpZJGz8xYepucli6/YLQH1B+GaCYz6Tq/MmjB3JLmr9aJ6ecsoSMrh0VMkTDowfbAapS8wh4lCKQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 10/33] hw/arm: phytium: Connect the Phytium E2000 DDR status Date: Thu, 3 Sep 2026 19:24:50 +0800 Message-ID: <20260903112532.3276678-11-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 121d3384-7d5f-4daa-1022-08df09ae2827 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: UTSQjyq+i7vLkYQffXocyA/niz1tqwOo53+dqr7XdepWfcV9OGLnZ8tttshA4cP9vrLspvb/wV7IUXmGtKBtWib/D/1c+Ad1FMDelNJWCbEq2SFl5lnl9h37e6lD+zTCKi+mz/UySrzYxB/jlcUCRJh1tfy6SK/v9/DpLmSfWpd+CRqxWq1UcdgSZX+Rx7GB9EmGKXZzJYGKkICI++dp1XjD1wqrky8ytuwte9Cc167OgZ5X3nDI1ttZTyCsAqJMct/BIhKJlyNSybq8li4qffSxmzaqu2nt/nBPimtdilaFLtfH9UEz3ExfULQG/jDgtyy488VCHHkI5QF//S3wlBLWbfW9H2z3qZrrMiHqsF5UgGkGeW23Mh6c6lipYRXVEplOTeTvw2teHN4tlvS1PWqjlpQhFM3jwC1yh8IhC+7LQJseVyhGMvuAOC0cnnnFBUcoPqw6t9gmK0bGCFg1xU64j3aEb2IKTL+TvTiuxdkwkt+Wdm2owchANM6igrHfUqiIiZe4mIET0bJlYwYbqnE943f3vzk2qut7rHUF3QiPz5ndX8LQFFe526Rwu/yqgPUlEr6N24bRmxGYqTFuhUfqR2qbcmOx6eqvSDeHhMw6Cp5GTl+4ieTWYxq4fXvk7E/YKhflMO/D1I8WWgC15+VNxiVb46ojQCnDz+X3f9o= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?5LMzzdHrkosS8xbUOk1nXgKLsCjo1/XFDpamvuEzL1CDdVN0rBV+SqNvadyO?= =?us-ascii?Q?Oh/5Xb8X82IQwQdMSKCbGpkW+84ObPuUMFFze7AS711AEjrKC6NWxKwBKceU?= =?us-ascii?Q?Ow5rPoe/1U2f6Cr5IA8fj3pANNrFFFmJ9Aih6FU8diIjyh4KiAHRzQ5uxuIG?= =?us-ascii?Q?widgRTZu0E8ja9bUb/oxpJ7wff3jjVYBt7wH41VnqqgBYdmneY9XtiTHndMv?= =?us-ascii?Q?qF5L29SOUadnOho8Euxr9b+97MLJDXDd2AYahZkF53DAqprHMLoVaieYyaUg?= =?us-ascii?Q?94AVIQTH3amiY4An6UmhtHfypXiMp5RVPj/7eeRs19XmzBDefHsl72U3ypmd?= =?us-ascii?Q?ZNK61iSHArFIIm4LHOm1P9SXfiWvHa+QeKsSTFiP5IKBWH3YicYjEQzAiEsL?= =?us-ascii?Q?OOW1n1GAJF9ib5hzLTsxkEig85rPutN3f6VuGTWqGMxm1rfziGVSUxqumZVL?= =?us-ascii?Q?m4tFBV+LNIXtGllzAxjqUP4hFTnRINLWEk9rJ0OqjlyEqQnsGVCCmUqkIkxx?= =?us-ascii?Q?3lW2WoaMFDA3fqR2D7kwLLUgHhzbcdbncC5UwAnwpKxejpEv0MzsOMn5SQr6?= =?us-ascii?Q?+7/jaKyHCh+W0bXc8n+3k4N9Y/JWkQif+a+KBe3v1RrrpdJCjAzLC2q2A/HY?= =?us-ascii?Q?QoVUHYRhPi1P7lJWRdM8hjk7GKpGYnD5vS/WDqUHM8FS6xs9iWjINZdT8lRx?= =?us-ascii?Q?NpQU3qNdngzt+soTdFlwUSj37UMdlUDo3sQiVAM/SY2DYoJLuxPdkJYgTvCy?= =?us-ascii?Q?jqIO1WGJN6knp7s7qjHxxqZey6hn85ispWyeAvzhWVxn3xotOCeBBGmdUNgn?= =?us-ascii?Q?yxOXrQY0OBprlXlpusXSMSegDi3eXhPr6CC802D708kOHVl6Ckm4QvEM/m3u?= =?us-ascii?Q?kpJPPa3jnnzT4cVcJMoEmo5I6HREFICXZXgUhBNVWo6PrVI0PwJiBMjVD+VT?= =?us-ascii?Q?npWvKl+9MEihKawqj0u12BEHlsWez+eeO+gaB6Jj6F/2YSNwlkAihXG/Am7P?= =?us-ascii?Q?RmVPk64d95Kp/F3K3CUwXf8NtRa2I1BEBeomcXlF/cR1p1/RgOhKDYBOoGiA?= =?us-ascii?Q?rv2+haLyDaoJ5yyuMAOjANu3IPH3nZUvTPzfer82Gxy3AOQs+ID95IWguSX9?= =?us-ascii?Q?AbGVAUMFzrzIdEObXfqsK4V8pWacunWS7kWrJpeUjKCrC7rSL/tOBWAptxjT?= =?us-ascii?Q?IroB8Q06SBdA4SBFKLvjs2TisZvRtzajWjk75+BfdBwftN7d1V8wu1Y3pDq5?= =?us-ascii?Q?UG2na9fWODvnrKQZ/wADrIxtXsgc3N0tBN517sWPoR/myqzpzumVP/9roZYD?= =?us-ascii?Q?aD4NMiI9ESLJbut602SxQUYK1WTV6v/onjURLJUQ27q6EFxun9vvXVJNpwop?= =?us-ascii?Q?xhV93thGaCHDlv0OA6t7AWb1wyBNH75S0JlysprsGiOR65doUTY2AnJfy+8j?= =?us-ascii?Q?z/vYAnypyKQgAB6i/Ownon926rc5UQWrplpFcUBDpPCC4fztL1SAkgSRKAGG?= =?us-ascii?Q?UMqb8Xl/lVtRPIPeahrOf35zTmgDDOyCIEy2pQPq1yP33g8emhnavVo3QAC3?= =?us-ascii?Q?QnRPYVVIReUEuKqMDnCTXp2Hy+SW1/d090xFEqFQVvfLiLbEc3s5xOa8N7Bb?= =?us-ascii?Q?XtbbgIYt7SyLOTuIGzYmBFI33i7uCg7PyXcd6RMhenG2MHclB3pZyZINnsL2?= =?us-ascii?Q?Dv5ffsUD6ZyTDwVuwBg6F1inGe0FRNjHm1KSOB3JdWDWwTusrkCFMonrkd6Q?= =?us-ascii?Q?mn7Eo0zXp+TpTvRFED/uwwBzQRZLcHc=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 121d3384-7d5f-4daa-1022-08df09ae2827 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:11.4328 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ZAww4k+Qc1n0PWzLIdTKrmOkQIdOp3jlU5roKlJc/KJU7Ys5V5T4SHeXi+uYeng8KmZPm0CUCEuLA2q/TzrrUdCSjF6OZhoYHiqxw4GPSgE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434910533158500 Content-Type: text/plain; charset="utf-8" Instantiate the E2000 DDR status device at 0x32b33000 and map it over the board-control placeholder. PBF and early U-Boot poll this selector window while firmware coordinates DRAM initialization from EL3. Signed-off-by: Bin Meng --- hw/arm/phytium_e2000.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index c68a565330..f586184e51 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -25,6 +25,7 @@ #include "hw/core/qdev-properties.h" #include "hw/intc/arm_gicv3_common.h" #include "hw/intc/arm_gicv3_its_common.h" +#include "hw/misc/phytium_e2000_ddr.h" #include "hw/misc/unimp.h" #include "hw/net/cadence_gem.h" #include "hw/pci/pci.h" @@ -48,6 +49,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_PI) #define PHYTIUM_E2000_NUM_UARTS 7 #define PHYTIUM_E2000_NUM_GEMS 4 =20 +#define PHYTIUM_E2000_DDR_STATUS_BASE 0x32b33000 + #define PHYTIUM_E2000_GTIMER_HZ 50000000 =20 enum { @@ -445,6 +448,21 @@ static void phytium_e2000_create_mci(PhytiumE2000State= *s, int index) phytium_e2000_attach_sd_card(DW_MCI(mci), index); } =20 +static void phytium_e2000_create_ddr_status(PhytiumE2000State *s) +{ + DeviceState *dev =3D qdev_new(TYPE_PHYTIUM_E2000_DDR); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + + /* + * The selector window is embedded in the board-control aperture. It m= ust + * override the placeholder because early U-Boot polls it while PBF is + * still coordinating DRAM initialization from EL3. + */ + object_property_add_child(OBJECT(s), "ddr-status", OBJECT(dev)); + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map_overlap(sbd, 0, PHYTIUM_E2000_DDR_STATUS_BASE, 2); +} + static void phytium_e2000_create_unimplemented(void) { /* @@ -564,6 +582,8 @@ static void phytium_pi_init(MachineState *ms) phytium_e2000_create_cpus(s); phytium_e2000_create_gic(s); =20 + phytium_e2000_create_ddr_status(s); + for (i =3D 0; i < PHYTIUM_E2000_NUM_MCIS; i++) { phytium_e2000_create_mci(s, i); } --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434880; cv=pass; d=zohomail.com; s=zohoarc; b=jDBOGRa2gbYEQ+M1RdEGf/sElmt7kIN83I5wFQ3SkjfcsoQDaKm1eoaw31g7naVeGGf6A4BZgrModpoR6kfEtf+tfIrB1hq9rKCzYpJ4YSIbAK3WmxYuKrG6BIYswJj0Ey6JNeIsvS+fHBfZWn11HMgdpNqOzF7BylanErKarYM= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434880; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=2XOHjco1ZRstk8sH2uMDdaEG1Ll6xxFEyxMp814x/Eg=; b=gpi0UvIn0ZuBjbyMkJq7BZL3S7vzCn3YWsj/ok4ePjz8X5P7KoNtCqriVb2n7vZEaTuTwiKs/4LTWvCTQKkj6rmaPfnZZrjV1iN9BekIjcA/VEaF4H2siAS62THv0XjhtUuvpYl4iCBsGtS0SXWRZyPlmrRznKm/1XGCOz85fTo= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434880341770.1186084654812; Thu, 3 Sep 2026 04:28:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aO-0005fb-UM; Thu, 03 Sep 2026 07:26:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aM-0005cO-W9; Thu, 03 Sep 2026 07:26:27 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aK-0006gK-Oh; Thu, 03 Sep 2026 07:26:26 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:13 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:13 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=oM+B59/sr55dpQsXQGx+u0QQFAFD/V4e3yoEnQfiB+u2lRD7wMrQsz/ilwMT4D1hZhswB0wOCI+ic90Pgqbn6KMMbtGFVjWv7RYheHe02pl21FqoCGPDlrWsdFo3Y8aoNNUpos/gkLZF9iQQ/MRg4JRB6BMAIE1L2ZXG0esGzYsJbqDKvYqYEQC/WKqtap3WNNvz6A8OsMGmrnD0tR/I93hG3dJqru3cfM2ih+3V462awGQm6eKWWWdAdNGLG+IcpXnw6Np1C+sg9fpNoL3L/xzXXBaaBQ2Kz1sMAjH5OaQQXQif+gr4tfFXWFxYD8QcKMOcJZZHEfXCasjHbwJHjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2XOHjco1ZRstk8sH2uMDdaEG1Ll6xxFEyxMp814x/Eg=; b=BRofkr5ljIcyy4TwaXxM2OSfiaKc3Yx90WOMMG7U6dVAAOSfEMTz27eD6lNWqFuzEB6BCa2fG8ILRQiNitxvmqyyZKwmOsJS21eXj9/+Af0pwph5R8kp+3EYL/7teH8wzhrv96EFCdxyw1f3gHuags27oyP5BUI143xdwCEebkQ/hW93AxIjeot+v2bd95L5JVZzpmPEbR/VSCEd/eZAjBhjK6Mcy9+o6IG5eS5bYq7FoDzPnKmUc8kK3N/JlGw9Qv1uwsLGwBhKHEb9BDzikh+Q9lQiQ8uaYYcLSpQcNSH5BeX6ScJ5IQB307ADZauyEtwxbAxBoHnYTBbY0MQYxA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2XOHjco1ZRstk8sH2uMDdaEG1Ll6xxFEyxMp814x/Eg=; b=RBBCgX/d7UUPtWU2wOS3E63zx6TLDNNEmzAXb1aaPv7EsdlXWGPkZrDeAzPaQUDwG6pXcW4T1Ho/MITSz2UDpe+ydLC1ySKsFE9TpzfTrEoSt9wsthaz1KWKdLEeyRJfC9dynPw7O3/Cx+UWYverLwGd/Cz4FYBslUlLCZTbdWQSWPm3XW53Ez7swj7L63IBPYkVlYMGvZWUniwf/0Yxe67yiWLC2mpDbVrstfTUoRWUxUXIU3n+Fl2/ZX3UdSCzQaJXk8yUdjMuj/vGR+gzmXBqbOOfC9Pb13pBoHIX6YeLlgHePeqEVzdtzxl8QgW/SieKm6SxDQYMovgI0DKEOA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: qemu-arm@nongnu.org Subject: [PATCH 11/33] hw/misc: Add Phytium E2000 MHU doorbell Date: Thu, 3 Sep 2026 19:24:51 +0800 Message-ID: <20260903112532.3276678-12-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: d82e20d8-ce66-424f-5ff6-08df09ae2926 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: HwPcVSTHFOy7PB+wi0NjAZpxIbGnzbiR3Hx7Fbul6CD90LJ2+wLQB6fOONMbwqNYbWLjfkOCBZFcmOZUTmQo/cvu4np6OHamfBCdA5RMwiqbIxQoXc42gXEtlhD4fyTvnnwlw24eG/fDumOMQzGJWCtwXt/9iyKvmtiF8NLSmU/69H004KQ42S73SF1j69p90n5vMUllAVkmMs8rDyiF+cUqJRxMjGriBAIJ2fER6QHh63BQHikwAAsZt+xDl6RM5YIIqCPJCZN+r6FjEb0zZsQXISu3TyKrLHlvsB+oR4Av/bccfqPd7VD07GWoS9OuQLNDt0g4vrHig3JxZvVyA132BDUClJEwnBrLUYcy1IihOGWUh9hzt/2EHIRVC/cLx0OdCdW6LjvhnDvFUjyKaGW3VOvRyw+TcvBgzK1oK++Y6hJnWSAXYXSTYrWIWoI3Mdtk5SQghh8+SgCjJHTzctUOVWnHCHT+IyGVcsOfSHlEDckJqx/k9Eu20xygPqtDW9AfTbok8Yd88i+HFgpWkB703WjZW09z1UAnJobxESBVzwB4ncDQBaQ5skvRohhy3W5AgD3w8cyUYA7TDEAZSyHOnbMUoD7gWus7Fqcuq/gaCcwgRPEhHKJtZnCXstdhdJryaj2qdNHemWciK1KE6Nl/RrJ5JTOlfYUJSHHZUhI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ZUEqIVhzUavbQeIJmhlOTBMU5yp7OMiwV+5hXGmIPfY4YRKo2qUCvdpXCxQJ?= =?us-ascii?Q?b3pAifbE57XERrPyrOsRA0jWd5Nf6kSCZxjl1izm8/gjKC9qsBQGm0w80Aq0?= =?us-ascii?Q?U0c4npuZQpMZgwU/wz/sgdfXMBYyDtv2dGiJg66KSGu8AIkp+IZXWyNzA9WO?= =?us-ascii?Q?vVKb+IuaDLi6ViD3X999jEDabA9jDrwo5OaFw9g75eGQXqRiKfkkxyRHDpCG?= =?us-ascii?Q?p+7Nn0okWGVRQbO/p+91d4OJQuHoyjYmIsbMJQcD7glP6Lj61zUAYpJCCMsR?= =?us-ascii?Q?hGOn8U3owJ2MN/qdiWFe70YwP1G5HcJdmgdx9ZIfKqe6aeDeqVbr7vqMojFu?= =?us-ascii?Q?9cAtzhXdXGLM1KtqNDu5HESbURiWDZIUUceSPNkpR0W4QEq32/rm7IWNeg17?= =?us-ascii?Q?LbaayLBLSYstylVclE9KePCBnLttH09nA+cywSJ08fmJZW+tWwYW6vguseBM?= =?us-ascii?Q?nxlCfmrV/2I8gafM872AOuPNBAZ+/U9hZJYXVjPf4sDE1z+VJZ+x3lTK3V6J?= =?us-ascii?Q?jAPMsSPeS1FbxBjmGC5FHVH+PoGy939L/G5wcF0cWU6HowFn5PoNFN0hma3q?= =?us-ascii?Q?CYc3PjKH/WXRHMOa+OyKoePQd6auBYn93QN0DjZX4KMnbkklPcX7QASyvV81?= =?us-ascii?Q?z5zm6YlfO7Z4zlEDeKwYShVmLdeEXWX4wISeOUlXv+sUeEmzWh1D6L5uNWYZ?= =?us-ascii?Q?R+oKrx1MzFFIjGgAXeb8kSVWy5Q8wcpOs7gBPshhFJkVWgksrg25mGxmyxfq?= =?us-ascii?Q?1Im53ciD0aQ9nlEFCrHah4EX3owEWU0g//COIX/nHZPv02WvWXz9y3wcB15F?= =?us-ascii?Q?jMHK/CCZXBIa1WhFV6KAYpuM9pBxhkNyhqHRfY80D6TdzPUNTukRjlZoHUMF?= =?us-ascii?Q?D0HseiW3QXAium+t7nNgmscjaJn/K3pT/+yFcUfOESsybNF3VaVpYNY7YMLE?= =?us-ascii?Q?G19jqzDuxcXYgFKS1+Htg5RFqhbXJ6tA6efJwu2b6qPCfG/9PuJ+h1ZIOMeW?= =?us-ascii?Q?g7R9e7CVVKUzwghj98K2K/wNpYYOiJNF0IZtvuMuQBfyA7ZiWCnuj/bCqRRw?= =?us-ascii?Q?T4fF5SSkBks2p44p8iPgnAsZ0uEoCoddjqOqUPVSb2PXk0iLZLZjbUHWI0QI?= =?us-ascii?Q?hjcc8T+/t1sd9m/5j+EzWbtCpcNgBCrD1C28rX+/WZzK9VybmikfrlIcGZL6?= =?us-ascii?Q?pmOCWY9M/B/iBDt4KRgtpqtfk/+LbntvdVB24KWFTLw8PCQgcHA8vDyWyO92?= =?us-ascii?Q?QF7VtV0koXaIln44FeHEOshVluxWLQD+wgQGQPRWYOMSB9O7I3FkQwA22yLN?= =?us-ascii?Q?mn4GepDPxeTZhHxCUy+WlnqcAxZhYBQ8MneCBrOkGUdZ71b8vpBX9GaSBvCB?= =?us-ascii?Q?8DU4x31M0+VfD0iBvKG9efAbAoQEYmX9fgrQYT+M0PRWcmaJCV3t+WE+e607?= =?us-ascii?Q?+QxIN0A0e/66l8SC+BTW46gg95K8OEcHIUaDEJp3BdXUm80llcxEi+B//pcP?= =?us-ascii?Q?Jxg99M08+sL5rjI3/ZjaRjy5FvjkXS5huzoRCXgE5mIMmo/zq2ohAItPxzM9?= =?us-ascii?Q?JinA/prvkIH0FSR8rc8mtW7kSBih7a8TcMeMatTzhMYffotPHaovFPkcK71z?= =?us-ascii?Q?Q9bTgzztAbiqblQJ1rn1SxjTgjXM0dg65KSQif3yDjoz9x1Q1kVyS84XWmsd?= =?us-ascii?Q?1pNRM63pEBuv0s0Jo2lHcC6icp1tr++beXnxA3ZFF+MzR/YSO4Z9KQ/6kq7i?= =?us-ascii?Q?OwBz90t99V8t+yY5jN++PEN6xgmFkfw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: d82e20d8-ce66-424f-5ff6-08df09ae2926 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:13.0700 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: /LSiAXmA48Yu+9QDHP2nYupU0oegdMyf4ZVfr226qO1HLcSTS3W314NYg35hGWqQsJXQUcU9SSWKP39WmNdhywxGbvWsivydcLcNabWnUas= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434882454158500 Content-Type: text/plain; charset="utf-8" Add a model for the E2000 AP OS MHU channel used by vendor firmware. Model its status, set and clear registers and complete nonzero notifications by updating the shared SCMI mailbox. The device also provides the mailbox seeding helper required by the later PBR handoff. Board address mapping and SCP SRAM ownership are intentionally left to a following machine-integration commit. Signed-off-by: Bin Meng --- hw/misc/meson.build | 1 + hw/misc/phytium_e2000_mhu.c | 185 ++++++++++++++++++++++++++++ include/hw/misc/phytium_e2000_mhu.h | 25 ++++ 3 files changed, 211 insertions(+) create mode 100644 hw/misc/phytium_e2000_mhu.c create mode 100644 include/hw/misc/phytium_e2000_mhu.h diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 898cf6ea87..a2ea120dd4 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -17,6 +17,7 @@ system_ss.add(when: 'CONFIG_INTEGRATOR_DEBUG', if_true: f= iles('arm_integrator_de system_ss.add(when: 'CONFIG_A9SCU', if_true: files('a9scu.c')) system_ss.add(when: 'CONFIG_ARM11SCU', if_true: files('arm11scu.c')) system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= ddr.c')) +system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= mhu.c')) =20 system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_ras.c')) =20 diff --git a/hw/misc/phytium_e2000_mhu.c b/hw/misc/phytium_e2000_mhu.c new file mode 100644 index 0000000000..4ea23af900 --- /dev/null +++ b/hw/misc/phytium_e2000_mhu.c @@ -0,0 +1,185 @@ +/* + * Phytium E2000 MHU/SCMI doorbell + * + * This is a boot-oriented SCMI transport proxy. It acknowledges requests = in + * shared SRAM so PBF can complete clock and platform setup; it is not a f= ull + * SCMI protocol server. + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/misc/phytium_e2000_mhu.h" + +#include "hw/core/register.h" +#include "migration/vmstate.h" +#include "qemu/module.h" +#include "system/address-spaces.h" + +#define PHYTIUM_E2000_PBF_SCMI_MBOX_BASE 0x32a10400 +#define PHYTIUM_E2000_SCMI_STATUS_OFFSET 0x04 +#define PHYTIUM_E2000_SCMI_LEN_OFFSET 0x14 +#define PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET 0x1c +#define PHYTIUM_E2000_SCMI_STATUS_FREE BIT(0) + +/* + * The SDK defines AP OS status/set/clear at 0x100/0x108/0x110 within a + * channel. PBF selects the channel at MHU offset 0x200, producing the glo= bal + * offsets below. Writes to AP_OS_SET are the request notification. + */ +REG32(AP_OS_STAT, 0x300) +REG32(AP_OS_SET, 0x308) +REG32(AP_OS_CLR, 0x310) + +#define PHYTIUM_E2000_MHU_R_MAX \ + (PHYTIUM_E2000_MHU_MMIO_SIZE / sizeof(uint32_t)) + +struct PhytiumE2000MHUState { + SysBusDevice parent_obj; + + uint32_t regs[PHYTIUM_E2000_MHU_R_MAX]; + RegisterInfo regs_info[PHYTIUM_E2000_MHU_R_MAX]; +}; + +static void phytium_e2000_mhu_complete_scmi(void) +{ + uint8_t buf[sizeof(uint32_t)]; + uint32_t len; + + /* + * Preserve the caller's message length, but reserve one status word f= or + * the minimal success response returned in the payload. + */ + address_space_read(&address_space_memory, + PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + + PHYTIUM_E2000_SCMI_LEN_OFFSET, + MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); + len =3D MAX(ldl_le_p(buf), (uint32_t)sizeof(uint32_t)); + + stl_le_p(buf, 0); + address_space_write(&address_space_memory, + PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + + PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET, + MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); + stl_le_p(buf, len); + address_space_write(&address_space_memory, + PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + + PHYTIUM_E2000_SCMI_LEN_OFFSET, + MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); + stl_le_p(buf, PHYTIUM_E2000_SCMI_STATUS_FREE); + /* + * Publish the free bit last. PBF polls this field as the ownership ha= ndoff + * and may consume the response immediately after observing it. + */ + address_space_write(&address_space_memory, + PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + + PHYTIUM_E2000_SCMI_STATUS_OFFSET, + MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); +} + +void phytium_e2000_mhu_seed_mailbox(void) +{ + /* + * PBR leaves the shared channel available before releasing PBF. Seed = the + * same ownership and success state even before the first doorbell wri= te. + */ + phytium_e2000_mhu_complete_scmi(); +} + +static void phytium_e2000_mhu_doorbell_post_write(RegisterInfo *reg, + uint64_t value) +{ + /* + * Complete requests synchronously because no separate SCP CPU execute= s in + * this model. Zero writes only update doorbell storage. + */ + if (value) { + phytium_e2000_mhu_complete_scmi(); + } +} + +static const RegisterAccessInfo phytium_e2000_mhu_regs_info[] =3D { + /* + * The functional transport does not model an SCP interrupt line. STAT= is + * therefore idle, SET completes the shared-memory transaction, and CLR + * remains ordinary register storage for the firmware acknowledge path. + */ + { .name =3D "AP_OS_STAT", .addr =3D A_AP_OS_STAT, + .ro =3D UINT32_MAX }, + { .name =3D "AP_OS_SET", .addr =3D A_AP_OS_SET, + .post_write =3D phytium_e2000_mhu_doorbell_post_write }, + { .name =3D "AP_OS_CLR", .addr =3D A_AP_OS_CLR }, +}; + +static const MemoryRegionOps phytium_e2000_mhu_ops =3D { + .read =3D register_read_memory, + .write =3D register_write_memory, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static void phytium_e2000_mhu_reset(DeviceState *dev) +{ + PhytiumE2000MHUState *s =3D PHYTIUM_E2000_MHU(dev); + int i; + + for (i =3D 0; i < ARRAY_SIZE(phytium_e2000_mhu_regs_info); i++) { + register_reset(&s->regs_info[ + phytium_e2000_mhu_regs_info[i].addr / sizeof(uint32_t)]); + } +} + +static void phytium_e2000_mhu_init(Object *obj) +{ + PhytiumE2000MHUState *s =3D PHYTIUM_E2000_MHU(obj); + RegisterInfoArray *reg_array; + + reg_array =3D register_init_block32( + DEVICE(obj), phytium_e2000_mhu_regs_info, + ARRAY_SIZE(phytium_e2000_mhu_regs_info), s->regs_info, s->regs, + &phytium_e2000_mhu_ops, false, PHYTIUM_E2000_MHU_MMIO_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), ®_array->mem); +} + +static const VMStateDescription phytium_e2000_mhu_vmsd =3D { + .name =3D TYPE_PHYTIUM_E2000_MHU, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, PhytiumE2000MHUState, + PHYTIUM_E2000_MHU_R_MAX), + VMSTATE_END_OF_LIST() + }, +}; + +static void phytium_e2000_mhu_class_init(ObjectClass *klass, const void *d= ata) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &phytium_e2000_mhu_vmsd; + device_class_set_legacy_reset(dc, phytium_e2000_mhu_reset); +} + +static const TypeInfo phytium_e2000_mhu_info =3D { + .name =3D TYPE_PHYTIUM_E2000_MHU, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(PhytiumE2000MHUState), + .instance_init =3D phytium_e2000_mhu_init, + .class_init =3D phytium_e2000_mhu_class_init, +}; + +static void phytium_e2000_mhu_register_types(void) +{ + type_register_static(&phytium_e2000_mhu_info); +} + +type_init(phytium_e2000_mhu_register_types) diff --git a/include/hw/misc/phytium_e2000_mhu.h b/include/hw/misc/phytium_= e2000_mhu.h new file mode 100644 index 0000000000..0527d6fe8d --- /dev/null +++ b/include/hw/misc/phytium_e2000_mhu.h @@ -0,0 +1,25 @@ +/* + * Phytium E2000 MHU/SCMI doorbell + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_PHYTIUM_E2000_MHU_H +#define HW_MISC_PHYTIUM_E2000_MHU_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define TYPE_PHYTIUM_E2000_MHU "phytium-e2000-mhu" +OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000MHUState, PHYTIUM_E2000_MHU) + +#define PHYTIUM_E2000_MHU_MMIO_SIZE 0x1000 + +void phytium_e2000_mhu_seed_mailbox(void); + +#endif --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788435109; cv=pass; d=zohomail.com; s=zohoarc; b=C66u9tsMqEu5Y4pcEv3kMCzzBGMVEgcBoHuZWYE6T0cgXXddTzo1bxNNECyLj+fRChgm0jFhg/Ge/RXNJJsYFHEmT52tYqA8bRdfdz5byS4wShroYG8Fk8CxdX3Yy6IG6ZRlrl/aGGXWnmn2GCUyOhjEUucJH4nigAT1/zHjTH8= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788435109; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=fMZtu0XsHNr6XoDBG3mjHuOwjWp7tTI+GuK281sj0Qs=; b=P8ww8XMzBr+zSycrk5kZL87O///b7sTBmrjoRmdfC4jB0gF+jZNf2NTcmGqKoMTF6lsaxYhd2lXPcXe83LkTuZwClef1g4ZOr85gtia9wV5NNvSh74g8L5tuPeFy+mMow2OIDYzkXp2552XD4j7lg9pp9eA+xhgVC8jpxD9jm0w= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788435109956504.8004259375998; Thu, 3 Sep 2026 04:31:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25ai-0005t7-EO; Thu, 03 Sep 2026 07:26:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25ah-0005rT-34; Thu, 03 Sep 2026 07:26:47 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25af-0006f9-G3; Thu, 03 Sep 2026 07:26:46 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:14 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:14 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bLiPZvaE5drNNCWX4BSh8UFpMW45J8F8bOCL/yR/PAbrZ3yAmSslVoVIMK4TapgPGx+Oorkv4ACi801wsIIXFHjIDBuzbPcvNSK7PMQYUx5xXtUJI158G9EcGqAa2wWfcj/LB/IBpjS6g2UzOYX/8fMrIQidM7G6aCYR+ifqdwurpPZq+azB82kvSI4zFNRp5i3nn0rK1hShxLvEHuiAHDtfWJEnA30lUjkeBEr6+wXScMkK1lBvh0iEZdJxxNq5zN5hPqMlU3s+bzblOAxjnvKVRJEJ8Yn5XHUj4tR2zeiGwU2s9eVTikdb2qHD2XZtpiH5+iTfl8WvknmJG0C/Cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=fMZtu0XsHNr6XoDBG3mjHuOwjWp7tTI+GuK281sj0Qs=; b=vJ6CfeWCRWDzPqKUTdvyvPQ3vTRbUprD4AJMYYBigD/v/NK89PAEGb7HS8Eazqs+RnVbgCeTZXpC2LV9kJky0YVxFrvvhT2MBUDghllv6JMLs6nv/FX3Dj+vnzwwJRb1ZttHJLGKhEDG51W4tVKhBA3xh0EKp2G7qQRKlMvkHnDxHvZRDl2YEqFF2UvOSuP4uXP/BGQCsqIidyQ+g4aYuLvmndogBuCnONzLj04Q1VYfy+uIKa1nVS1dmYIATuHrskvJyv4lghKei6BqLGb5d7AKwf2VUhndI15vzUavUcmPvRNOugIVvqyrO3mrPIKUbC/xa0SgGm9ibwAB/VWTdQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fMZtu0XsHNr6XoDBG3mjHuOwjWp7tTI+GuK281sj0Qs=; b=p3nhjkrNwPe1qJ/Jd7AdR/UnQztwvgXaEl+Z4oobwterw/ZH3jHB/fEZtMctv6e6rkVw9QVCVZxu0e9BcoHWmOH4NLk1ER7SA/ciz5ZNlfFsRYCk8pVWYvgqvRdnXrGaGZ9YLtrGChBLtJrtPH+/rzLAxKfo0qvIGL98smqllgZa1ux01Wktm6h0QzEIF7L0tKVmJx0B/AOeyarhWj/tEm4KKHlZLsQiNUqoslV5dOBiODbvkEiQq/wkSDBFhJlQhhNPMdMzaWjlHSIPECPt3F3KT3Y9h+Ix+NpL8qlVGuNjYG5bwpy3IEs9/uCbRmV8ewcBisLbHYhuVheivZRhHg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 12/33] hw/arm: phytium: Connect the Phytium E2000 MHU Date: Thu, 3 Sep 2026 19:24:52 +0800 Message-ID: <20260903112532.3276678-13-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 6040c5f1-ede0-423e-bbd4-08df09ae2a35 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: 9rv0rnHTE9lDKqOWTfJ7WMfk60k9R4UnY0+fZADjaHCo8JQqYU+eCZw7TuUFXiOXdkwWUL6Qw8oqr3WKN+xA1d7Ey9mXqPjiJIKy2xcsg5xcn62sohtMw7J8rAz6Mn9VfO9APY6AgfqDttQYmKp60Hsf5sFUqfLEE9La0UHsFErBP5WDXNNs/XjQcp6i53LshRxXLr1OLLoRRqO2Ap41m5+/QfyiinZRjUPxy0uzRhexaWhrKVLs3fSIqOppuxqBCPyoXXobm5880VJRWCVoCLphRHyQOFbWnK0LCd2Pk6tn4J5QhkADZtBjrLGCsa5AokQ7spVGgs2hnYZVX7p2HhxLRO9QfqllcJcOd9jpH8duy+YMZ7q3FCLWZf/8eUrMG59/Xc6Yo5WsVxSVNcCw/BpzQvBpeimhiHS5kfGh7Gj/d43wiGL/PQ73cl3MA8PxYUfS7xBjEex9x62+klJghV6NkPZWWKp2QzHdXvJN6FkHPhkrv9aIZ47VM/WqogWSSWxW2EancSmxAFotPJkBsT41pPPJHavbotlQraTpthFnW99GDo3TurQquReCf214Q6QRSEpXZh81ahSkuaGFEPuOltjIX1oO4vhJfIcz0hQJb/lp3d3Om8B3duvN9de7xDcNF+n7CrTqaf4q3GoNy/t8kkLvxzh+l2lm8EsDuhI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?YjsfOMqZNBGVrDn9bAqVQtwS4xo8tsFHp5Lxo9rPbhM3aRsnQg0vqWwuEAs8?= =?us-ascii?Q?Ef77lXck8+eEjZR+9JJHBIko2/UDTooEU9pEB8UTQlHg3njGGjusG82LZ/sk?= =?us-ascii?Q?JK0ln/EvX8M3i9W90bZSyT9LAS46qAERUtwR6bDkcYZsyrhaQOIE1Ei15VXr?= =?us-ascii?Q?ZTNEYZbAHt2pXfnLM6kujoFpNHbV/EzGChaFFv4AdTvxcsUnifm4WCvkRfBv?= =?us-ascii?Q?7nAaIzGGcx9RQ4CyIsRsCBBA1gJEIA+2YNkjnaJYADm5+lWfNK5wdb8Hql3T?= =?us-ascii?Q?Uq3PKLjF3J4gwFSbYUaQy9yU4OxKoiJ4Z3CjoNxsASyR09H3gzIQbelnsLgE?= =?us-ascii?Q?pNUSk5OEqmsdTkvxzuR1+JHWC4L68bEBKXo6h2fZslQeV9fS6d8EJVO1mU3S?= =?us-ascii?Q?XuKrpjfDZI09nIA0BCGduNaXbqNTuFAYqYC2rWhHtR3RAicRAMYXsCVSDGrk?= =?us-ascii?Q?IFSKAFHDldiU8E+5Q0gogPIt4qFiNGe0gul47J1xrYDXkiCRChlGPDvgxtMD?= =?us-ascii?Q?ZEqFXAYVXTUesC0awgfHq0IM7Z9Am+p5nfy3APIECdi1Huk+Jb/QZifX3UBl?= =?us-ascii?Q?cvWrHVPxXaJ3TQCA/QrxCxTiSh2ZZu/nP9n21ue9a0CfCzP7sDS76krf6Wwt?= =?us-ascii?Q?AeYM2gplkRZAduqCLeBJWS+HzkEk2EjsN+y7Ofm7BfqcJ6S5O1rT1x/Ly/U6?= =?us-ascii?Q?hfyNbT6bObotjWX02sTszlFoginHveATGqTQodZj6QpigJk1uXZiCfLNSYwL?= =?us-ascii?Q?XuJoWlJ8ZUDlXtsOJBT4rMSt8pSjT3Hi67pMl04fYwmrmoGUT/0pWFbDgCsv?= =?us-ascii?Q?lNFsrEpWbbD3mzBpCPHEItjr/h6P5OpF8zzgLHHpWvX7przkt6f1dG3/5pDQ?= =?us-ascii?Q?75w3L7jnl3MIbA58XVq3O4QwfK0xjZzzKHv7HaHV7OsOgPhssQrEHxYmyszQ?= =?us-ascii?Q?xDTIRdEAIRi96EnLBfi/lAENhK2rvNR4nI4X66ViFq1NZNVc9iBrQCnj9E5m?= =?us-ascii?Q?ABtvrjDCzOwrKVZbWd5NdUbJpTbWOEvrtrjN2i+i/z08IxpDVNkIZUrx/Qm5?= =?us-ascii?Q?UFK6p995Rfm289AH7a9MKpUlotEGohEHoIIy8yyYCiSXEP21KGIMCja1cB1R?= =?us-ascii?Q?m1xs3H0on4IFTsaPF0kMdVD4SBT/mucnBwYo6vlJJiQdTywah4dzPIsTemEx?= =?us-ascii?Q?PhAlY2ROCp1u/yPydukCajnTIIVMeHZztwEFDgMq34+kmgx5IaIKFQXToBSG?= =?us-ascii?Q?q8ql3LjoxElMucmD9j3fFp42Pj4XfPmKruVspgQUJF5+yPi1uggaFsq0e3c1?= =?us-ascii?Q?v5gSD49U51K64PyqCqM5uxa6ZqYHzUM5D/FOej6zTsFwcyQk09PgBWopOBmT?= =?us-ascii?Q?TpFrKmLlrom8cmqYx9Nn/BYClOXf49ufKHwmjbsJrPLn0g8+Xokqk0Q7VXSp?= =?us-ascii?Q?+vhQYfQeFW6xydEyg1g2Kwk0ADkAMFN3J2n5+bZHeyHn2UewgFGgZ4sdYQLM?= =?us-ascii?Q?HZs4Bwv0evNK6t8N1D+fwX07wihrEL2dP6GMYH0xEp5TMrtbR5ck+LfD5MGv?= =?us-ascii?Q?1Z8FE/8r3qmUCkSh2NOrbR24I9CwxQmd1y8H71yzBCoor6BmSvQp58XG1g6y?= =?us-ascii?Q?MYAfO0onCTJs86idLx+LeGgJ9U2kxzohgZ0p0DblZL13ns3XyQPcwlFneSO0?= =?us-ascii?Q?Iz0FPmeaTG4xcCStYwJeV5Yybt3eRF7d+XlN6TN+lpOBDubiWK5InCwqBq15?= =?us-ascii?Q?RRXl8cz+sEXuh2a3GI8XQKM5iMNFew0=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6040c5f1-ede0-423e-bbd4-08df09ae2a35 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:14.8442 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 1b+InS8gvdlkQvk1LKNPdSqJYULj9TrHZgvk+hH5/CbI1z6XsHKSJ4Qvmq0y5qBMoP9fNnezpvsejhkQtL4pLqWbIiP96qn8BVDqpYZI33A= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788435111911158500 Content-Type: text/plain; charset="utf-8" Add the E2000 SCP SRAM window used for SCMI messages and map the MHU doorbell into the board-control aperture. Signed-off-by: Bin Meng --- hw/arm/phytium_e2000.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index f586184e51..ff8dd3354b 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -26,6 +26,7 @@ #include "hw/intc/arm_gicv3_common.h" #include "hw/intc/arm_gicv3_its_common.h" #include "hw/misc/phytium_e2000_ddr.h" +#include "hw/misc/phytium_e2000_mhu.h" #include "hw/misc/unimp.h" #include "hw/net/cadence_gem.h" #include "hw/pci/pci.h" @@ -49,6 +50,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_PI) #define PHYTIUM_E2000_NUM_UARTS 7 #define PHYTIUM_E2000_NUM_GEMS 4 =20 +#define PHYTIUM_E2000_MHU_BASE 0x32a00000 +#define PHYTIUM_E2000_SCP_SRAM_BASE 0x32a10000 +#define PHYTIUM_E2000_SCP_SRAM_SIZE 0x2000 #define PHYTIUM_E2000_DDR_STATUS_BASE 0x32b33000 =20 #define PHYTIUM_E2000_GTIMER_HZ 50000000 @@ -90,6 +94,7 @@ struct PhytiumE2000State { DeviceState *gic; PhytiumE2000MciState *mci[PHYTIUM_E2000_NUM_MCIS]; CadenceGEMState *gem[PHYTIUM_E2000_NUM_GEMS]; + MemoryRegion scp_sram; MemoryRegion ram_low; MemoryRegion ram_high; }; @@ -463,6 +468,33 @@ static void phytium_e2000_create_ddr_status(PhytiumE20= 00State *s) sysbus_mmio_map_overlap(sbd, 0, PHYTIUM_E2000_DDR_STATUS_BASE, 2); } =20 +static void phytium_e2000_create_scp_sram(PhytiumE2000State *s) +{ + /* + * PBF exchanges SCMI messages and platform parameters through this SCP + * SRAM window. Map writable RAM over the board-control placeholder be= fore + * the MHU doorbell starts completing requests in it. + */ + memory_region_init_ram(&s->scp_sram, NULL, "phytium-e2000.scp-sram", + PHYTIUM_E2000_SCP_SRAM_SIZE, &error_fatal); + memory_region_add_subregion_overlap(get_system_memory(), + PHYTIUM_E2000_SCP_SRAM_BASE, &s->scp_sram, 1); +} + +static void phytium_e2000_create_mhu(PhytiumE2000State *s) +{ + DeviceState *dev =3D qdev_new(TYPE_PHYTIUM_E2000_MHU); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + + /* + * MHU is the notification side of the SCMI transport. The message body + * remains in SCP SRAM, so this device only owns the doorbell aperture. + */ + object_property_add_child(OBJECT(s), "mhu", OBJECT(dev)); + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map_overlap(sbd, 0, PHYTIUM_E2000_MHU_BASE, 2); +} + static void phytium_e2000_create_unimplemented(void) { /* @@ -582,6 +614,8 @@ static void phytium_pi_init(MachineState *ms) phytium_e2000_create_cpus(s); phytium_e2000_create_gic(s); =20 + phytium_e2000_create_scp_sram(s); + phytium_e2000_create_mhu(s); phytium_e2000_create_ddr_status(s); =20 for (i =3D 0; i < PHYTIUM_E2000_NUM_MCIS; i++) { --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788435062; cv=pass; d=zohomail.com; s=zohoarc; b=YhMOXip3aDenRUqTEoMLD5DPMqjhOm6JXEfx6CmAAcNJgkrOHPdrhEeW3uCrGoFoS0WGTzFzmihPsvIutufh4OlDWPSe0O6es3a/4NYxSMWmQu/9Sj/1l3J8Ls7E6k/mYDJZIfKV5jcCxTfHh+ik8Tz/Dih7aCBtMIaHEMQhz4c= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788435062; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=YVgyN5T+BhT36Uiw/AnRFYarN4n34p2oj5w411p6Hx0=; b=VjFhOg5ONaJYPW9+BwCi+3ygMZC1YwNSEaBdByzhPDEKzDoxqAN+ydqwGw8YhuFugMgzGH7IuKYYM5rfD5k1pRLXY53KSRkm6dP+0NxA6NMDGwg82JLIHxpZeMU7Ym24Nk8KbjIDnHCI4SPYTrCjx7aMQ95daJoTC4mar9RqidY= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788435062913233.23451456791054; Thu, 3 Sep 2026 04:31:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25ao-00063j-CR; Thu, 03 Sep 2026 07:26:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25an-00062H-9t; Thu, 03 Sep 2026 07:26:53 -0400 Received: from mail-koreacentralazlp170130006.outbound.protection.outlook.com ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25ak-0006gK-PX; Thu, 03 Sep 2026 07:26:53 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by TYZPR02MB6358.apcprd02.prod.outlook.com (2603:1096:400:419::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:18 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:16 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=qI6Clc6D12vjGKB01xMAcSCDyETV63T2wZzw0fAZ0hdNOh2WPXok41jennhvwWCH1NACI0ovwIsCShLS73Aaayv1XP7dqRiwn/Ybj4MXjeumU5xfp6B3G8Fp53mxzGrb09tgVhewJVNzswUt/qezFvKBbZXJRj6z5apt8vBirK9rsXlUvQRL9eO/q7vz3B/rvOSJX+8kKmKtUtIUY7APKZw5Q0/XPmLEmADo4IAkULX3epIeylCMvrtL+TqwWw/dnOh2MAEiN0a/WF0HfUSV0KdjyM3Gd7ymRryL9xq2igoEO0EibFrwbd4gvqPYpnm/9T/0kqxGCqTrhcOZFXaHZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=YVgyN5T+BhT36Uiw/AnRFYarN4n34p2oj5w411p6Hx0=; b=nwlRffsy/4GhYLkHe5fVfLbQoZ0pBySrmt1Hi3ajx+sMkBaCJWWgiqu6u9zmKrCH9cej5srvltWMZMGo9nxlL+vVqa+ptSqMdFy4rjEEGXZkxphJpQm/vMiivm3JY2qP0iKLvwD3yhC1Nq+7e2LQAJib4cQes+1UdDufxv+c7oNfXj3h6TtC6Pr7B/g/9eEM2+5bEXmSdxqW0B9xOcPuF4lyCGuMeR+nJsXRGFNWL8mH4C9fnw/Pjukdse/b+aedaCB6DPd0bHnqTN0hkccjweZkudH7ad+a02krjxLoR2ii8kF8q/I/N0TuiU8qQxWzxknkhX9FybOGcTpc57ONXA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=YVgyN5T+BhT36Uiw/AnRFYarN4n34p2oj5w411p6Hx0=; b=iFse4N6fK6EddYZKEqsPHCS+Z4M8Pd6yC2zxFl38QnKchiMdymN1VHKgrbazQu4tOpnyWoW0f1GsyWIQ0ZxWnSIDqaLCJRFeacTT2d9TaN/79KFNlaKvznFiVUaMuT9i0PeQBe74ocfKgpsVavphxMpT7lRgLna5j97FoFJsm09D0iGzQ7hR/zysw1XM458dN4foRD/sVE4td/y5ZW4ehy1LI3acd/N41xEkNScPz3wioLa3c5lnBGut7K6+60I/iFWXXqN2l56GYBqiBZlA7DunMpQ3uA+h9Y9UOnsSAjziJYCx9jywfT/Tlu+cZ5OD7AGIbigD6q8vJbXFJh66Nw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Alistair Francis , Paolo Bonzini , qemu-arm@nongnu.org Subject: [PATCH 13/33] hw/ssi: Add Phytium E2000 QSPI controller Date: Thu, 3 Sep 2026 19:24:53 +0800 Message-ID: <20260903112532.3276678-14-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|TYZPR02MB6358:EE_ X-MS-Office365-Filtering-Correlation-Id: 9aae019b-030f-4756-7c82-08df09ae2b76 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|23010399003|1800799024|376014|6133799003|5023799004|56012099006|10067099003|22082099003|18002099003|3023799007; X-Microsoft-Antispam-Message-Info: grcMGkys2MUaPsakueNfmP4qRozx8rLmlZ+qpwABSvXpBHb5A6LWtCZV9xpssO6VOjdBR8Wmln4SDcTW+28jJJav6KaGdkzRYYSGB3cMnDupgIAfkUP8lE9jSUo5J9hk7r65LE0EPa5wjlX/dPbO1UsBHCp/qV5FbpPsozxmh7gI6NXpnHrvvEa2oToBgSzo3PA9ZAqvN+X9VswoetMwCy8U7+logeMJzCMvzKwfOgIZ+gdw7oY+5EFaOwMcgqqJ/SkV6aQBNYJZZWIvace76pJbG8YHSkg6qQXqEzx/QGAgdkXrZzlkcd/dk/tfWuA87SJMPyeJ/Uv7aBClvBlIfY+sce9Ou8ZPlPzmFV2s59LEa61prcbrSfZzDdJ8NvJMIIxvMkfly1LPlZCct7tkAyz33dmC5TT4YTkqZfYF8yYu1D9q5s0Chkbx1wGmdtuaBpXf4+uGwVN21eAwxzgB//dG//ovYgE6UpRRe2oLpuFoTKcW2Xlqe8BLQALQ2JGXDQUDW2P5bj9sRfRe99Hp/gl7SUKiWjV/yV84xlmV3Dru0RqRECztSOcoP1+n/vInIkRDEtU35Dn9HU99Df04StrOQN3EsxLI530AJuWlXUBKilMpO3qOCxvkXBOXNCIwu9YlVH8WI+KsYI166NDP22pr2AEfs1AmqKOVlImIAo0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(6133799003)(5023799004)(56012099006)(10067099003)(22082099003)(18002099003)(3023799007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?kk+4x3gxCb9Yty6yIlGEzw05W0hc6JPr5W+f07lxY1B/Jnkd0nyZebZ74sIL?= =?us-ascii?Q?Ie4RV35Dk1Qhu+0xNByywFMHJcHFiOavfTE9cQ6yXq8rNK9259WJc0DfWVej?= =?us-ascii?Q?Az0/v6C2ZrPJtPZq42bl59bfLTdXjdf+pOc0u4nxuIV+Ez7L7/+IHa4nhDxf?= =?us-ascii?Q?1DbjZj3SmKvnPm8td3Uo+p78P1obv2avIlgVtM82vTuLEsQXeQULrcOqEGtw?= =?us-ascii?Q?CCSdh/R9iFDizE9A8OlvYrNvU7au0TCyUR/eR7BitQgo5H03uv96hJoF722R?= =?us-ascii?Q?a8qYIavdKqQlGjN7i68UlVFLgmbe9Y0zaEThmM3FifAHufZB9/OPRUvuAH5B?= =?us-ascii?Q?GYgCw0TdGvXIEpO5Ewk55LQQJUSLVljajHcLqlBR9Z1fasid5FPJZY8BIAnh?= =?us-ascii?Q?e/EKLiCfypczb9fB5khZBAN9UWqIQSpuibCcZ/d3GsUQ0J7yL111aQUWxQqB?= =?us-ascii?Q?QE0makTbjIK+otMxCj8q+iIdgg46wLgC1K6peiDnVjwcsju9VqTn7FT3F0Uv?= =?us-ascii?Q?si/xp5JA3d8BZXCP+I2kXLLzfO/T9h1vgdIyDxu0DrH/NR+hvS5PGs2ZDKGy?= =?us-ascii?Q?a60Y64HrKdjf35SylbGt25QwW6Ez02QxapXn/3dU8BgbxQjyGGH5/2Lh3U78?= =?us-ascii?Q?Bb/ExYEGtQkV7RQuMVMg0krXqNaDXFjRPf7JPBy/dTGKelgDPj9yl/xtnH7k?= =?us-ascii?Q?gj2Y8NHYWVsMG1OI46uYfsA2tq0D+QFyGVGzJIPUqpHmx18a3RNZ75M/XX2C?= =?us-ascii?Q?zU34gZjuiRYbzJfiAO2JK0eUwrc7VEFN74DUkCTSGNe9JLafT+IFi8bWZNYn?= =?us-ascii?Q?JAzyARe4uf6yzj2tKGuQQxGtkrbTgIxi3Rl0aZp5QQZkP1H0l1mjkd1eX9bY?= =?us-ascii?Q?nBeE9Ngv9GuJ6oVSFQKCxQ2scymdvxmaoRPVz0kgI2jBDDGQIGu2rXmiIElU?= =?us-ascii?Q?g5hnQcuOOI4mawamB4LcEcqUhb9RS5qVKgTR2ac9JDLCBEhHa2U/czPvVwZz?= =?us-ascii?Q?G5GbecjNq0myQphgq8gqHq7BrPk18rWQjf5DizrXkgjjdSVHhINgEym526MW?= =?us-ascii?Q?p9ICr74GQpprxL4dW8iOjrcXtWXL/lTDMF5EQulS0SXw90x51h5GGgs95CHV?= =?us-ascii?Q?AhFFo3Foqz1rOLDJRdmrZl18IAhKSbJ1uu3s3YGHQS5zcB0pyP7vOnZxopA6?= =?us-ascii?Q?oKLsHa3OSqAwq8rx/KJY9pTuDNgGI3qO1U1MsoG8Ymx+ZxJTVyk1dqNtAUma?= =?us-ascii?Q?lICYWplZeyF0um+Fe/MndUQblxRYgT80GqnpIWABqAPSpEVTnnKQLYmcdPSh?= =?us-ascii?Q?yZ8wSzmVHBfMZ9aM9r3K/+9/Z+S5hCb4MmmWyhf0oTTyiO/5w8yfa6CJ4Bzf?= =?us-ascii?Q?tomtONW3zQ6PR4nR+UjmzLh7F4GWFap36FpcFHhdDTOhI4bqD9l+74A4fHUL?= =?us-ascii?Q?d1ga14RGWZ96N4nk1UzPZGzqzNSEjb99rodWWshS4xlP7rZhdmJSO6NNf9Wr?= =?us-ascii?Q?UFN4BvNq4sbxOj9Oag7nkm4QoQDTJb9jvXPH/nrgwSC2p3q+p4bZ29uXiXjI?= =?us-ascii?Q?qiP0FObj6wZuJNqPk5VqE/e3Wnnjq7q6sDVduTYCoMylvl6e3MsBLJzIuU2x?= =?us-ascii?Q?g60yRbqMRhiIbnyVPa66Vj5XBrdrdQeNno3G9XY3CXpv9NsQ0guuF0UuYLfn?= =?us-ascii?Q?j2aGzaU2OWfUeWwhYiIyWs8vHLewDPzitZElAuWc1WrtLSR3/WNCNfODtF9d?= =?us-ascii?Q?WephqfiCGjIURZHZ2CiRVzdy+ZXZoAw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9aae019b-030f-4756-7c82-08df09ae2b76 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:16.9626 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: P3sLoQ47RkAYyvZrXX0eOszJIksPZ6Ubk9N7rSv4el1FydAdmjPF5nBBqWzJxC3QUMoZXS9+B06UCPSn62SVHY1VHSXDPtdu3gKbVW1rLOw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: TYZPR02MB6358 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c40f::6; envelope-from=bin.meng@processmission.com; helo=SEYPR02CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788435063628158500 Content-Type: text/plain; charset="utf-8" Phytium E2000Q integrates a QSPI controller which seems to be an in-house IP. This adds a model for it with command-port and direct-map paths, and exposes an SSI bus and chip-select output. Signed-off-by: Bin Meng --- hw/ssi/Kconfig | 5 + hw/ssi/meson.build | 1 + hw/ssi/phytium_qspi.c | 398 ++++++++++++++++++++++++++++++++++ include/hw/ssi/phytium_qspi.h | 23 ++ 4 files changed, 427 insertions(+) create mode 100644 hw/ssi/phytium_qspi.c create mode 100644 include/hw/ssi/phytium_qspi.h diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig index 1bd56463c1..202c81c5ac 100644 --- a/hw/ssi/Kconfig +++ b/hw/ssi/Kconfig @@ -9,6 +9,11 @@ config SIFIVE_SPI config SSI bool =20 +config PHYTIUM_E2000_QSPI + bool + select REGISTER + select SSI + config XILINX_SPI bool select SSI diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build index 6afb1ea200..c76945ddf4 100644 --- a/hw/ssi/meson.build +++ b/hw/ssi/meson.build @@ -13,3 +13,4 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi= .c')) system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c')) system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c')) system_ss.add(when: 'CONFIG_PNV_SPI', if_true: files('pnv_spi.c')) +system_ss.add(when: 'CONFIG_PHYTIUM_E2000_QSPI', if_true: files('phytium_q= spi.c')) diff --git a/hw/ssi/phytium_qspi.c b/hw/ssi/phytium_qspi.c new file mode 100644 index 0000000000..da7dce1d46 --- /dev/null +++ b/hw/ssi/phytium_qspi.c @@ -0,0 +1,398 @@ +/* + * Phytium E2000 QSPI controller + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/ssi/phytium_qspi.h" + +#include "hw/core/register.h" +#include "hw/core/irq.h" +#include "hw/ssi/ssi.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "qemu/module.h" + +REG32(FLASH_CAP, 0x00) +REG32(RD_CFG, 0x04) + FIELD(RD_CFG, CMD, 24, 8) + FIELD(RD_CFG, ADDR_SEL, 19, 1) + FIELD(RD_CFG, LATENCY, 18, 1) + FIELD(RD_CFG, DUMMY, 4, 5) +REG32(WR_CFG, 0x08) + FIELD(WR_CFG, CMD, 24, 8) + FIELD(WR_CFG, ADDR_SEL, 4, 1) + FIELD(WR_CFG, MODE, 3, 1) +REG32(FLUSH, 0x0c) +REG32(CMD_PORT, 0x10) + FIELD(CMD_PORT, CMD, 24, 8) + FIELD(CMD_PORT, CS, 19, 2) + FIELD(CMD_PORT, CMD_ADDR, 15, 1) + FIELD(CMD_PORT, LATENCY, 14, 1) + FIELD(CMD_PORT, DATA_XFER, 13, 1) + FIELD(CMD_PORT, ADDR_SEL, 12, 1) + FIELD(CMD_PORT, DUMMY, 7, 5) + FIELD(CMD_PORT, RW_NUM, 3, 3) +REG32(ADDR_PORT, 0x14) +REG32(HD_PORT, 0x18) +REG32(LD_PORT, 0x1c) +REG32(FUN_SET, 0x20) +REG32(WIP, 0x24) +REG32(WP, 0x28) +REG32(MODE, 0x2c) +REG32(LEGACY_CTRL, 0x30) + +#define PHYTIUM_E2000_QSPI_R_MAX (A_LEGACY_CTRL / sizeof(uint32_t) + 1) +#define PHYTIUM_E2000_QSPI_PAGE_SIZE 256 + +struct PhytiumE2000QSPIState { + SysBusDevice parent_obj; + + uint32_t regs[PHYTIUM_E2000_QSPI_R_MAX]; + RegisterInfo regs_info[PHYTIUM_E2000_QSPI_R_MAX]; + MemoryRegion direct_mr; + SSIBus *spi; + qemu_irq cs; + uint8_t write_buffer[PHYTIUM_E2000_QSPI_PAGE_SIZE]; + uint32_t write_address; + uint16_t write_len; + bool write_pending; + bool resetting; +}; + +static void phytium_e2000_qspi_select(PhytiumE2000QSPIState *s) +{ + qemu_irq_lower(s->cs); +} + +static void phytium_e2000_qspi_deselect(PhytiumE2000QSPIState *s) +{ + qemu_irq_raise(s->cs); +} + +static void phytium_e2000_qspi_send_address(PhytiumE2000QSPIState *s, + uint32_t address, + unsigned int length) +{ + int shift; + + for (shift =3D (length - 1) * 8; shift >=3D 0; shift -=3D 8) { + ssi_transfer(s->spi, extract32(address, shift, 8)); + } +} + +static void phytium_e2000_qspi_send_dummy(PhytiumE2000QSPIState *s, + unsigned int cycles) +{ + unsigned int i; + + for (i =3D 0; i < DIV_ROUND_UP(cycles, 8); i++) { + ssi_transfer(s->spi, 0); + } +} + +static void phytium_e2000_qspi_exec_port(PhytiumE2000QSPIState *s) +{ + uint32_t cfg =3D s->regs[R_CMD_PORT]; + uint64_t tx =3D s->regs[R_LD_PORT] | + ((uint64_t)s->regs[R_HD_PORT] << 32); + uint64_t rx =3D 0; + unsigned int cs =3D FIELD_EX32(cfg, CMD_PORT, CS); + unsigned int length; + unsigned int i; + + if (cs !=3D 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: command selects unwired CS%u\n", + TYPE_PHYTIUM_E2000_QSPI, cs); + s->regs[R_LD_PORT] =3D 0; + s->regs[R_HD_PORT] =3D 0; + return; + } + + phytium_e2000_qspi_select(s); + ssi_transfer(s->spi, FIELD_EX32(cfg, CMD_PORT, CMD)); + + if (FIELD_EX32(cfg, CMD_PORT, CMD_ADDR)) { + length =3D FIELD_EX32(cfg, CMD_PORT, ADDR_SEL) ? 4 : 3; + phytium_e2000_qspi_send_address(s, s->regs[R_ADDR_PORT], length); + } + + if (FIELD_EX32(cfg, CMD_PORT, LATENCY)) { + phytium_e2000_qspi_send_dummy( + s, FIELD_EX32(cfg, CMD_PORT, DUMMY) + 1); + } + + if (FIELD_EX32(cfg, CMD_PORT, DATA_XFER)) { + length =3D FIELD_EX32(cfg, CMD_PORT, RW_NUM) + 1; + for (i =3D 0; i < length; i++) { + rx =3D deposit64(rx, i * 8, 8, + ssi_transfer(s->spi, extract64(tx, i * 8, 8))); + } + } + + phytium_e2000_qspi_deselect(s); + s->regs[R_LD_PORT] =3D extract64(rx, 0, 32); + s->regs[R_HD_PORT] =3D extract64(rx, 32, 32); +} + +static void phytium_e2000_qspi_ld_post_write(RegisterInfo *reg, + uint64_t value) +{ + PhytiumE2000QSPIState *s =3D PHYTIUM_E2000_QSPI(reg->opaque); + + /* + * LD_PORT is the final staging write and commits the command assemble= d in + * CMD_PORT, ADDR_PORT, HD_PORT, and LD_PORT. register_reset() invokes= the + * same callback, so suppress SPI side effects while installing defaul= ts. + */ + if (!s->resetting) { + phytium_e2000_qspi_exec_port(s); + } +} + +static void phytium_e2000_qspi_flush_write_buffer(PhytiumE2000QSPIState *s) +{ + uint32_t cfg =3D s->regs[R_WR_CFG]; + unsigned int address_len; + unsigned int i; + + if (!s->write_pending) { + return; + } + if (!FIELD_EX32(cfg, WR_CFG, MODE)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: FLUSH with direct writes disabled\n", + TYPE_PHYTIUM_E2000_QSPI); + return; + } + + phytium_e2000_qspi_select(s); + ssi_transfer(s->spi, FIELD_EX32(cfg, WR_CFG, CMD)); + address_len =3D FIELD_EX32(cfg, WR_CFG, ADDR_SEL) ? 4 : 3; + phytium_e2000_qspi_send_address(s, s->write_address, address_len); + for (i =3D 0; i < s->write_len; i++) { + ssi_transfer(s->spi, s->write_buffer[i]); + } + phytium_e2000_qspi_deselect(s); + + s->write_pending =3D false; + s->write_address =3D 0; + s->write_len =3D 0; +} + +static uint64_t phytium_e2000_qspi_flush_pre_write(RegisterInfo *reg, + uint64_t value) +{ + PhytiumE2000QSPIState *s =3D PHYTIUM_E2000_QSPI(reg->opaque); + + if (value & BIT(0)) { + phytium_e2000_qspi_flush_write_buffer(s); + } + return 0; +} + +static const RegisterAccessInfo phytium_e2000_qspi_regs_info[] =3D { + { .name =3D "FLASH_CAP", .addr =3D A_FLASH_CAP, + .rsvd =3D 0xfffc0000 }, + { .name =3D "RD_CFG", .addr =3D A_RD_CFG }, + { .name =3D "WR_CFG", .addr =3D A_WR_CFG, + .rsvd =3D 0x00fffc00 }, + { .name =3D "FLUSH", .addr =3D A_FLUSH, + .rsvd =3D 0xfffffffe, + .pre_write =3D phytium_e2000_qspi_flush_pre_write }, + { .name =3D "CMD_PORT", .addr =3D A_CMD_PORT, + .rsvd =3D BIT(23) }, + { .name =3D "ADDR_PORT", .addr =3D A_ADDR_PORT }, + { .name =3D "HD_PORT", .addr =3D A_HD_PORT }, + { .name =3D "LD_PORT", .addr =3D A_LD_PORT, + .post_write =3D phytium_e2000_qspi_ld_post_write }, + { .name =3D "FUN_SET", .addr =3D A_FUN_SET }, + { .name =3D "WIP", .addr =3D A_WIP, + .rsvd =3D 0x00ffffe0 }, + { .name =3D "WP", .addr =3D A_WP, + .rsvd =3D 0xfffc0000 }, + { .name =3D "MODE", .addr =3D A_MODE, + .rsvd =3D 0xffff0000 }, + { .name =3D "LEGACY_CTRL", .addr =3D A_LEGACY_CTRL, + .rsvd =3D 0xfffffeff }, +}; + +static const MemoryRegionOps phytium_e2000_qspi_regs_ops =3D { + .read =3D register_read_memory, + .write =3D register_write_memory, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static uint64_t phytium_e2000_qspi_direct_read(void *opaque, hwaddr addres= s, + unsigned int size) +{ + PhytiumE2000QSPIState *s =3D opaque; + uint32_t cfg =3D s->regs[R_RD_CFG]; + uint64_t value =3D 0; + unsigned int address_len; + unsigned int i; + + phytium_e2000_qspi_select(s); + ssi_transfer(s->spi, FIELD_EX32(cfg, RD_CFG, CMD)); + address_len =3D FIELD_EX32(cfg, RD_CFG, ADDR_SEL) ? 4 : 3; + phytium_e2000_qspi_send_address(s, address, address_len); + + if (FIELD_EX32(cfg, RD_CFG, LATENCY)) { + phytium_e2000_qspi_send_dummy( + s, FIELD_EX32(cfg, RD_CFG, DUMMY) + 1); + } + + for (i =3D 0; i < size; i++) { + value =3D deposit64(value, i * 8, 8, ssi_transfer(s->spi, 0)); + } + phytium_e2000_qspi_deselect(s); + + return value; +} + +static void phytium_e2000_qspi_direct_write(void *opaque, hwaddr address, + uint64_t value, + unsigned int size) +{ + PhytiumE2000QSPIState *s =3D opaque; + uint32_t cfg =3D s->regs[R_WR_CFG]; + unsigned int i; + + if (!FIELD_EX32(cfg, WR_CFG, MODE)) { + return; + } + + /* + * The direct aperture accepts multiple CPU stores for one page progra= m. + * Buffer them until FLUSH supplies the transaction boundary required = by + * the flash command. + */ + if (!s->write_pending) { + if ((address & ~(PHYTIUM_E2000_QSPI_PAGE_SIZE - 1)) !=3D + ((address + size - 1) & + ~(PHYTIUM_E2000_QSPI_PAGE_SIZE - 1))) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: direct write crosses a flash page\n", + TYPE_PHYTIUM_E2000_QSPI); + return; + } + s->write_pending =3D true; + s->write_address =3D address; + s->write_len =3D 0; + } else if (address !=3D s->write_address + s->write_len || + (s->write_address & + (PHYTIUM_E2000_QSPI_PAGE_SIZE - 1)) + + s->write_len + size > PHYTIUM_E2000_QSPI_PAGE_SIZE) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: non-contiguous direct writes before FLUSH\n", + TYPE_PHYTIUM_E2000_QSPI); + return; + } + + for (i =3D 0; i < size; i++) { + s->write_buffer[s->write_len++] =3D extract64(value, i * 8, 8); + } +} + +static const MemoryRegionOps phytium_e2000_qspi_direct_ops =3D { + .read =3D phytium_e2000_qspi_direct_read, + .write =3D phytium_e2000_qspi_direct_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + .unaligned =3D true, + }, +}; + +static void phytium_e2000_qspi_reset(DeviceState *dev) +{ + PhytiumE2000QSPIState *s =3D PHYTIUM_E2000_QSPI(dev); + size_t i; + + s->resetting =3D true; + for (i =3D 0; i < ARRAY_SIZE(phytium_e2000_qspi_regs_info); i++) { + register_reset(&s->regs_info[ + phytium_e2000_qspi_regs_info[i].addr / sizeof(uint32_t)]); + } + memset(s->write_buffer, 0, sizeof(s->write_buffer)); + s->write_address =3D 0; + s->write_len =3D 0; + s->write_pending =3D false; + s->resetting =3D false; + phytium_e2000_qspi_deselect(s); +} + +static void phytium_e2000_qspi_init(Object *obj) +{ + PhytiumE2000QSPIState *s =3D PHYTIUM_E2000_QSPI(obj); + RegisterInfoArray *reg_array; + + s->spi =3D ssi_create_bus(DEVICE(obj), "spi"); + qdev_init_gpio_out_named(DEVICE(obj), &s->cs, "cs", 1); + + reg_array =3D register_init_block32( + DEVICE(obj), phytium_e2000_qspi_regs_info, + ARRAY_SIZE(phytium_e2000_qspi_regs_info), s->regs_info, s->regs, + &phytium_e2000_qspi_regs_ops, false, + PHYTIUM_E2000_QSPI_REG_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), ®_array->mem); + + memory_region_init_io(&s->direct_mr, obj, + &phytium_e2000_qspi_direct_ops, s, + TYPE_PHYTIUM_E2000_QSPI ".direct", + PHYTIUM_E2000_QSPI_DIRECT_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->direct_mr); +} + +static const VMStateDescription phytium_e2000_qspi_vmsd =3D { + .name =3D TYPE_PHYTIUM_E2000_QSPI, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, PhytiumE2000QSPIState, + PHYTIUM_E2000_QSPI_R_MAX), + VMSTATE_UINT8_ARRAY(write_buffer, PhytiumE2000QSPIState, + PHYTIUM_E2000_QSPI_PAGE_SIZE), + VMSTATE_UINT32(write_address, PhytiumE2000QSPIState), + VMSTATE_UINT16(write_len, PhytiumE2000QSPIState), + VMSTATE_BOOL(write_pending, PhytiumE2000QSPIState), + VMSTATE_END_OF_LIST() + }, +}; + +static void phytium_e2000_qspi_class_init(ObjectClass *klass, + const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &phytium_e2000_qspi_vmsd; + device_class_set_legacy_reset(dc, phytium_e2000_qspi_reset); +} + +static const TypeInfo phytium_e2000_qspi_info =3D { + .name =3D TYPE_PHYTIUM_E2000_QSPI, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(PhytiumE2000QSPIState), + .instance_init =3D phytium_e2000_qspi_init, + .class_init =3D phytium_e2000_qspi_class_init, +}; + +static void phytium_e2000_qspi_register_types(void) +{ + type_register_static(&phytium_e2000_qspi_info); +} + +type_init(phytium_e2000_qspi_register_types) diff --git a/include/hw/ssi/phytium_qspi.h b/include/hw/ssi/phytium_qspi.h new file mode 100644 index 0000000000..c6534af16d --- /dev/null +++ b/include/hw/ssi/phytium_qspi.h @@ -0,0 +1,23 @@ +/* + * Phytium E2000 QSPI controller + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_SSI_PHYTIUM_QSPI_H +#define HW_SSI_PHYTIUM_QSPI_H + +#include "hw/core/sysbus.h" + +#define TYPE_PHYTIUM_E2000_QSPI "phytium-e2000-qspi" +OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000QSPIState, PHYTIUM_E2000_QSPI) + +#define PHYTIUM_E2000_QSPI_REG_SIZE 0x1000 +#define PHYTIUM_E2000_QSPI_DIRECT_SIZE 0x10000000 + +#endif --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434891; cv=pass; d=zohomail.com; s=zohoarc; b=lLuFDflN9ZnHpcAaA6GyFjLf9legJ2dpTG+1SNmu4WAgDxVTYTDuaxUYbKCVOhJ/2nr1yql56q0sFHEGGxb49OoVm874Z2wbi2a7at53NcKl5AVVQ/rT4QNpegPdgzPIKRSWlr7lf9hLeEiSv6UjqtG6s3351FnEfV839rNmmbo= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434891; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=0vCRSG8GvzegJRwVZ/ioclH/rbVjrr98Hmwdsp4KnHQ=; b=cxKGS50pLwzGPFtDUlXQPh9QyLOIZTbe9KkPMJ+h5B6ElenCfUigQAUx0d43DdPfSGzJ3AZc+ton2OmNbaIx1XKHYPBTIjioJuQFyOWKBZLEKPhGG0WWq2aKkaqGWTN0J1n9mY8/ghxKjzxgsKg2BX+9i+0EL8vwLLHzspCVMp4= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434891625134.82794642227827; Thu, 3 Sep 2026 04:28:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aO-0005fU-PF; Thu, 03 Sep 2026 07:26:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aM-0005bY-KG; Thu, 03 Sep 2026 07:26:26 -0400 Received: from mail-japaneastazlp170120005.outbound.protection.outlook.com ([2a01:111:f403:c405::5] helo=TYPPR03CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aL-0006k3-3s; Thu, 03 Sep 2026 07:26:26 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by OSNPR02MB8962.apcprd02.prod.outlook.com (2603:1096:604:45b::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:19 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:19 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=vpgOTuYxTDX/6tTHjZd6rJ+LmxrquAhx0n+m5/NgJR/MQ7Zo9IxmrdaFdIvwagMs4zxyxcpPA8xzUKBhJnAQaCqfd6dpRGkKjtoWXbWcWIG2vAsqdp5dUQ0QmTc0vgTmgMjPWQFMvPFokcqMrMD0RU07KzXEyBdi00VEdSX1Ihk1TbvTWw3BoNyXTXOG7nkFd5z3YTagvFwCZxrhzHwIrd4c34O8MoY5P+1/RmtPyuv9H76Y3bIu9zlXHQ6OIJjyd6+c/ZiuW703TrtfuQpBF9Y5dmxVTcq+3g5sVKSw7ON/oAcV+kukPxcwGFBtLP2uAb/LifLa3DX6Mhi6YeJ0cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=0vCRSG8GvzegJRwVZ/ioclH/rbVjrr98Hmwdsp4KnHQ=; b=iC9TrIxRavdLwZNT/Ww/3FKghclzlehU5mWO6nAPoWzKunHSOPaat2YwX2/uHrDysHNVTVxrS/IRQ2wKoRGyOtht2edehTDy5er7SHwuOkRDRo7EPOhlEzMpQLdVwKIv3KRZ5Z8tZO9XmDub8IBsMFOJtQpXH/6bUwohrJ3tJB+A3kFXll8eXtjJ+eW3GhPzZ/EPyOC1pxyUvXIfyy5mMD6DrLJHPSuXSv5ULUK8wDCe00nJ66E8sSxv3m54X6dRW2S7pg/I6+xpxqotpVk+O+m6vLwCx8m25SlO4nqTFlZhcOR+uykrd+rDwETV8MYl8Hemu97kFg6Z9dVW3It9fg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=0vCRSG8GvzegJRwVZ/ioclH/rbVjrr98Hmwdsp4KnHQ=; b=CgMhkRmJeBBqfXUc4zmULhZ1ClJNC4U78UgNWWEkDo4b7AkjUxE6oKjy+AvkHqKNCgrEy+GchnXNzmqyswdlL9dBNPGoYJOC1a3OP23AmgaejT5Ew50mhBgxkbClaMnAGRJOquF3PDuPa6xz3FYP243fcaIwxSMxdbRYkGzOecfE3Kr4gx+O98B4bOrLyazO5iHhUWh7jCNNWSheDGDucC+K+qz59SCSmFB5E0nyzYfjYkOn3oMNuxwInh8zyALscrwz4W2x1xfj0aphpT+bl1ZT68tbLcz5dSvl60IwDazmdPgc8hlAEhvkEsLwJhIZB9iYRBnmle97nzY185pcKQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Paolo Bonzini , Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 14/33] hw/arm: phytium: Connect the Phytium E2000 QSPI controller Date: Thu, 3 Sep 2026 19:24:54 +0800 Message-ID: <20260903112532.3276678-15-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|OSNPR02MB8962:EE_ X-MS-Office365-Filtering-Correlation-Id: cd7e1c4c-3741-4878-de6e-08df09ae2ca5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|23010399003|366016|10067099003|22082099003|18002099003|56012099006; X-Microsoft-Antispam-Message-Info: H+YdtdzeFVgz7p1VdgskRnu93gZbdQEyk9PVajaRMlwr1ZZ1HfoQWdqyQ2VCBY+4I+MtoBl5BKqn4JlQLWT9/u9p2uILpPYFVy8FGumcb/1fBWi4jQdyMt1C3It3ol4hpHjamKkTVuaSK2VojBovSBnN/Rbm0UvCLwJL/Up+R62hJyH/S61Y2ox6qiZM7Zhx87WE9jDIk+t0IweZOFOt357kNri6OhGN44+Fu8WmsBL6H0+F6eLvE08AeP0l/RAxZozBdY7fgz9+IMO4Wc/kwEiZxCb/ua39toZXyx/9gxciwlM2BxMDVe+gMIdp4rmV6G4Dn9rKEvxpflyIPhs6Dj2kAbVaM3aTJREg6BYKrYdda0u/U6RpQ0ZLHM3z7YD3k1ZjzJ+Ol+2LazVaPc6T0W2fnErwTgk00PdLy0jZWF+jZ7Sl384z84NFqtxdDCfsm4DvEwA5LLPJiMfl0rRYJqbBnSG5qPqzuLwaHLKWirIxXnSUzDRpFwdNZpVmGsMXjzOveZ8JSMs+M+H/NwDRL/PxaN+wiAnn04VGSHCYPPTcoDlp9SgJ6OvJJ1FzyPUrjbaOcntrYU4ZGqtYM7MuCH7fLTjdCXtYEsrZtizWBoyJj6KtK6IW5oTcMm8573Xtqrtuee66sP2sE6V9cHECkXN0LiS4WoR8ghA3qy9GKzs= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(23010399003)(366016)(10067099003)(22082099003)(18002099003)(56012099006); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?iKEH/rH07M0WjOsJcSmzNCWxWnaJmA7wZW/BqvEJ78SWAVUngav0RPLOSR/V?= =?us-ascii?Q?vLs0vVi++ygpGJe5HeZSFCd47OuNP4WwPvln6Wlnh5gUmP0rD7vOegTHD99Y?= =?us-ascii?Q?UqX+MHFMIyuKMqGd4tTebgVRBGWdD8S8Nn2Pn6nEhNJmKCIQtdY7p1MnOyMh?= =?us-ascii?Q?8uhCC0wwX7bBC9MfD6QgsXz0t2QjBjuWXo0lcZBAdr3zj9ITFeteT33GKdh3?= =?us-ascii?Q?xyVfGskbZSjbedb9b19mLlXspQpASXdIBxdTrZSCCespP3ZxSxLGE2+GK3E8?= =?us-ascii?Q?j8gCEQbDIiRkh62ktRA0SQWda8A1QzVqHmskGKfBCcePnf8F8a3L1Vo4zN/r?= =?us-ascii?Q?PSXxbTJjdePjXJF9D7WpZXClkGA4pQ5lmObZfAJt08GjakqX/0gfdi0aLU5p?= =?us-ascii?Q?qcIoEiiXY1sYG+syK3hVBUR+5k9mwPWLPDPiWzXou954rLEiGb3WQG+xyIJu?= =?us-ascii?Q?rKs8WAWSZIUXAr70ifdOMdjZxAm8peSUTe/PAs/7x1+uzHdE1+FBG3Er6h5d?= =?us-ascii?Q?BO2CBTpbfH9A7yHAyDApTVrW7K7kddTR+AHaQwuGNSOpo9nPEAYuM0pP3QpJ?= =?us-ascii?Q?lQxZaNV20+4oTXxtx5dpyAAnK3YFrTTioPp5U8j8nGDLjzRP53VeO6u56YZG?= =?us-ascii?Q?erdQ+CaRSiAoAVq4VBxhlaWp6SGyheZMoorZG+it7LZ912DnzmtUQT0MtXcD?= =?us-ascii?Q?jD/WWG/HCBuR4jo9fdkqeR/5/6DjnlgT2J7M1cIJYthTckyB7yadLCYpj7HZ?= =?us-ascii?Q?Z1vFQqUWeAzParwHP2NdKZPhMt/wkZZubDlIWcFX7assvSJS7JGsjjRNPwPG?= =?us-ascii?Q?hyAjtpWkheiegRGQzC8TNmbiWEPmOxxYENDf9VJtH1c4fMU0pXjyUKZsUlAd?= =?us-ascii?Q?i05ncyLoa7IVkPkuHaKox1X6H8WFqPtSdzIvf+Q8NL8h40y04xx3pcHH9G0d?= =?us-ascii?Q?dtWOgiG9T+CbwSEwuUeWqH8Sq19Yj0HMmklrKvmouAt4YemCFb4FfFV6uKdc?= =?us-ascii?Q?8fvc09w8WlTN756tkRawXjiJ5JxhkOzQYkExqVbCamZjosA1mOHQQwSbS9qU?= =?us-ascii?Q?HyZFN1Hc+vgBoQjt8BXt9Y+chjOs8M8xh6sXR0wiN4nO0XDJIN5xsrBTpGmm?= =?us-ascii?Q?whoeB5rczKjLvwxmBG9T2nkhiXuQTxLfAK/KQdfwyaQBneu2QEj2f1QW4qzC?= =?us-ascii?Q?+iONah1R9Po+t69IIf79W7f/TgXQiCsuYhMB3eLFkIsR2A5nO7fZePtbRAPJ?= =?us-ascii?Q?B9nXmHkTemxRcMwlaCG0x/0uC3h93C3bjKZdTEp22jIExWIoTuL/Wzs1sttZ?= =?us-ascii?Q?vtbRDU/17XsP1oNf2zOhuuvXc6yDgOCC2NIYT85AW8NGYR/ue87/YSVCrV2G?= =?us-ascii?Q?oruWoQJT6tTkbvGM6FqxX/Gy9I6m5HYT36Eg7hzQ3gET+47RA0+kEJ22ATpm?= =?us-ascii?Q?AzQTKOPLxySEiKdWevuPUgIkIBgywm/WS0wousMy4GiA3AC5AZp94UY6aCcu?= =?us-ascii?Q?Pjh4t9bDaZqSvdvWcRFHC/BOQLj+CN9/LDYh0VFVkzc2o/2kiVrsIJQPVauy?= =?us-ascii?Q?1Ew71aw3jxNDsCX0TjLkU7XtWPQlI6nBtNFK+M+jnNG4p0OQYW/VihJnhOoX?= =?us-ascii?Q?5UaM3+1E7RhKMw+MLvzvR2wmkAoobMvgoMwdj5CpuDyZbh3MmThdD1WPUmAa?= =?us-ascii?Q?4KWw0Zvr7acSauQ7ywUz36nP3PCtkS1k8o+wd4s66aSYxyZrI+doHHN2FNBh?= =?us-ascii?Q?wZ5RHV98g41Re4tLwhpKsWUggPJt2mw=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: cd7e1c4c-3741-4878-de6e-08df09ae2ca5 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:18.9305 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: XrUfu1MWWQvX4G9sXODIekY6/SPcCN5JtjtjYKdj5f0wAzgWZHVrPp2Yv9VMdPC06FeMCX/cDcg8E7Zqj69eDdSABdBMXwoHzNy/sW4cjxs= X-MS-Exchange-Transport-CrossTenantHeadersStamped: OSNPR02MB8962 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c405::5; envelope-from=bin.meng@processmission.com; helo=TYPPR03CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, RCVD_IN_DNSWL_NONE=-0.0001, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434892405158500 Content-Type: text/plain; charset="utf-8" Instantiate QSPI0 at its command and direct-map windows so accesses from E2000 firmware reach the controller model. Signed-off-by: Bin Meng --- hw/arm/Kconfig | 1 + hw/arm/phytium_e2000.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 08128232ca..891d09e86b 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -136,6 +136,7 @@ config PHYTIUM_E2000 select DW_MCI select PCI_EXPRESS select PCI_EXPRESS_GENERIC_BRIDGE + select PHYTIUM_E2000_QSPI select PL011 select SD select UNIMP diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index ff8dd3354b..c6d789bb04 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -33,6 +33,7 @@ #include "hw/pci-host/gpex.h" #include "hw/sd/phytium_e2000_mci.h" #include "hw/sd/sd.h" +#include "hw/ssi/phytium_qspi.h" #include "net/net.h" #include "qobject/qlist.h" #include "qom/object.h" @@ -58,9 +59,11 @@ OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_PI) #define PHYTIUM_E2000_GTIMER_HZ 50000000 =20 enum { + PHYTIUM_E2000_QSPI_DIRECT, PHYTIUM_E2000_LOW_PERIPH, PHYTIUM_E2000_MCI0, PHYTIUM_E2000_MCI1, + PHYTIUM_E2000_QSPI_REGS, PHYTIUM_E2000_UART0, PHYTIUM_E2000_UART1, PHYTIUM_E2000_UART2, @@ -92,6 +95,7 @@ struct PhytiumE2000State { MachineState parent; struct arm_boot_info bootinfo; DeviceState *gic; + DeviceState *qspi; PhytiumE2000MciState *mci[PHYTIUM_E2000_NUM_MCIS]; CadenceGEMState *gem[PHYTIUM_E2000_NUM_GEMS]; MemoryRegion scp_sram; @@ -105,9 +109,11 @@ struct PhytiumE2000State { * handoff data and IACC is the fixed execution window for system firmware. */ static const MemMapEntry phytium_e2000_memmap[] =3D { + [PHYTIUM_E2000_QSPI_DIRECT] =3D { 0x00000000, 0x10000000 }, [PHYTIUM_E2000_LOW_PERIPH] =3D { 0x28000000, 0x00100000 }, [PHYTIUM_E2000_MCI0] =3D { 0x28000000, 0x00001000 }, [PHYTIUM_E2000_MCI1] =3D { 0x28001000, 0x00001000 }, + [PHYTIUM_E2000_QSPI_REGS] =3D { 0x28008000, 0x00001000 }, [PHYTIUM_E2000_UART0] =3D { 0x2800c000, 0x00001000 }, [PHYTIUM_E2000_UART1] =3D { 0x2800d000, 0x00001000 }, [PHYTIUM_E2000_UART2] =3D { 0x2800e000, 0x00001000 }, @@ -453,6 +459,18 @@ static void phytium_e2000_create_mci(PhytiumE2000State= *s, int index) phytium_e2000_attach_sd_card(DW_MCI(mci), index); } =20 +static void phytium_e2000_create_qspi(PhytiumE2000State *s) +{ + DeviceState *controller =3D qdev_new(TYPE_PHYTIUM_E2000_QSPI); + + s->qspi =3D controller; + sysbus_realize_and_unref(SYS_BUS_DEVICE(controller), &error_fatal); + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(controller), 0, + phytium_e2000_memmap[PHYTIUM_E2000_QSPI_REGS].base, 2); + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(controller), 1, + phytium_e2000_memmap[PHYTIUM_E2000_QSPI_DIRECT].base, 2); +} + static void phytium_e2000_create_ddr_status(PhytiumE2000State *s) { DeviceState *dev =3D qdev_new(TYPE_PHYTIUM_E2000_DDR); @@ -611,6 +629,8 @@ static void phytium_pi_init(MachineState *ms) phytium_e2000_create_ram(s); phytium_e2000_create_unimplemented(); =20 + phytium_e2000_create_qspi(s); + phytium_e2000_create_cpus(s); phytium_e2000_create_gic(s); =20 --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434960; cv=pass; d=zohomail.com; s=zohoarc; b=lxm8CxbycKj8jiOnkChk9BAgO16LFRd7XvhAMadvMjBQLHZcig7OApJhIV2yPtGb15BXwfHXGNOcERiEHMymePdXZW4CLIrWQz+nEQ//iyzmpW1jAtmS3sWEnlDqiV35unbNpXPXyH0Qd0bn/9JQ46xigGma62iAHZ1aTu4V96k= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434960; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ifur4lAMm6mx+K5hWVN1LBOmHcUPPlnITBAO3OuNV4s=; b=PyFPa3nxq4dybupRZmWHpnjTCmuKWJ5b8L7R7lT4ciJ83f0xiKrwlGewntZjEvBmOk6Y8BoU1DCumaiWu8DhAttfU6kNWYi8zlnh01YbkOfG45eCzPToAYTAA1Pzex1rPu4Im2a7wAUMG5F34tgnirEaMVEQtd5LaBoH0SBS0o8= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434960869822.6312952426438; Thu, 3 Sep 2026 04:29:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aU-0005iB-H6; Thu, 03 Sep 2026 07:26:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aS-0005h9-7o; Thu, 03 Sep 2026 07:26:32 -0400 Received: from mail-japaneastazlp170120005.outbound.protection.outlook.com ([2a01:111:f403:c405::5] helo=TYPPR03CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aN-0006k3-Jp; Thu, 03 Sep 2026 07:26:31 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by OSNPR02MB8962.apcprd02.prod.outlook.com (2603:1096:604:45b::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:20 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:20 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PJOJXEJQFZ/8GQHEeUqKuT8WU8xZ80DcE6FMYDFHB2QtIrfijr9qph/LdMLeks22phmYz8VB5EdvmZMBt/7xZNdmbPIASttf7Rj65VcTk6HYm/G75K8eKKnYtMIE84m/oecJxov9/zXsLB+IE+98AfT7cuuHbA8xWsYviPUe7r9K4I6K0u7TMXHDD/66bqPuKqiWk9JmVGbLKbQ/kFUtHL0aUR58YU2yHXQD60pBDObjdqrYbH7fDTaTqpVevXUWzgx4jTOoVSMCBMVzR8StGk3gAeSQNnF1S9PUKnCvypwRS2+9JfXKdRFS7ClqGi5sXNBoh02c0kkFnboVAqDCUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ifur4lAMm6mx+K5hWVN1LBOmHcUPPlnITBAO3OuNV4s=; b=VHnimWsv03tWpa5wkP9TxoN62qk8q0EpODolZmkwoWUpuYRh/ZK26jsElTyB098op0jgy3XvwySFAf/0sGPORgApvZA1+rrpSjYOLubDKIED+U2l0Z21VhfbTaZMpm/8HZtHAfsws/QVz+vJoUer87K30+u/BsDjO4RQfI64wXEUsm36chFxJEHVJnL8UXEN3tpb8hswXhWl5DirKLfEUeEZcU9RAB0/qcp0MaqyNXgjAulpGvYoZDJel5UqXX/Tq9LhtDjNz7kATPSp70Jll1NmFX+Pc8sX/20Y22gtvbwVnRBhB53VFxrShYz9lNU5nkFbS9ivshq5ZS6+eWBL5g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ifur4lAMm6mx+K5hWVN1LBOmHcUPPlnITBAO3OuNV4s=; b=vowkLymDq+8jrrIt4+84O/alwiXyUf31x+aqejw43Rxxkfq8o58bsKH1ZfeO5XrcNCzBlHEnGQzEY58P/UStUhxxS3OygglIFhhH9XMFtYcANbK2b9gBDn+msArvfm4Qc7pVpFJOZZW52/UTJPbWMw6lqr/my54XyTppu92plxCcbdMs3v+lGIjQ2AIKtZ3Zerods4kegeDnLeja8cDcI5BHhoVMt2ENuCjuQjMgynZZeolJFFW3qKh/TBOGtc5bIUtNa+VdWYdWJiRb2Ab0RGPOs2e1xpE57r/3qEkTPw1xXCVCPvYBMpcMczR/FavG1znr3bxfFGSKhpyMjKjqUA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: qemu-arm@nongnu.org Subject: [PATCH 15/33] hw/misc: Add Phytium E2000 PBR model Date: Thu, 3 Sep 2026 19:24:55 +0800 Message-ID: <20260903112532.3276678-16-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|OSNPR02MB8962:EE_ X-MS-Office365-Filtering-Correlation-Id: e0a05f85-ded5-4959-7712-08df09ae2d9e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|23010399003|366016|10067099003|5023799004|6133799003|3023799007|22082099003|18002099003|56012099006; X-Microsoft-Antispam-Message-Info: 3FnrdXKpzuT3tBN+pqCGbMB69ozsUazK+LTlM1pMvaLFgsEqtw4Px0z7grH7CNqOBLEv/HnZgYzkeU36Yw5C90pBN3oxQ0MHSSBIGQWOCm73dzALDHiazoSO98Oy1Amb2//HpG3hlqoGy8EPesTSX4dZbQvxHiBd5WQ2VXpy/VF7XkFJjp7cvO8r/BtlWbghWfxsrIBXUhQ6y9DELCeNrIHisOzuuvj16GDD2moXoXt5y+DkY1suUxmaYtiFNjGz6m0upSYmQqh8Bkgryrw2D6ifvx1LZFDS5CK8o6xfvDqVpn26oWdTF5CNbTfMoq8I0K2Qfv7qfIpdl/V5E4gLGcEk/WhPkCeIqWPiLq7JuLPHnTB6y3StAKXYSYapY1tPhacRvAAquF7WyFjwkmoq6Rb66LybTbUIwI1/153pXgF7zhoaUZFGKcIk5xk8caXNVO4qS4Yq8scTqOm7TePKgY77SQeWT/kvvw61vZTSKYqQ2YT6tIQBpqkQfTLydpKwdWR/npC8dO8j50vln8l+fE1Ik5v1COYLm5ax1kDEE+sogoiYnJ6Eu1aUtJE4h7jWf922wW3ipUXGypRDWgTkBTHosVKN53K1veWPb/Z2MRhk6Upug8VSwEnUVg3BRGt2l3xnJ5gSncVsBrH7PG8yUGWgnxafmeXXwihuYTT6EmI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(23010399003)(366016)(10067099003)(5023799004)(6133799003)(3023799007)(22082099003)(18002099003)(56012099006); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?3kcuk0/Zmr91+7sv9mQnLoff5NiMn4XrO4WF1hRx8PN3VhDGe7AofbpQg+P7?= =?us-ascii?Q?1ssqv0+enuKu+XrIkMy580ugEBJ2vFkMK92SCDFRRDlGG5H1QXx9Gssa9T7S?= =?us-ascii?Q?KAxyCKlEdlBMOwojuPk7MnDmdDgItaaXmRIBNjGOH3v5ndrS8hxduunv+Epz?= =?us-ascii?Q?iF48ICkOebHVSFe6d5HVd8PQ6PESjvlhxFDEvWPWqWWMoIlJpj0VmJHCWxUy?= =?us-ascii?Q?WzbCztuLKr4pWC6/xr2gHIOjhOE/UkaqwNm+Rg2geZ0800qGw4JB4YTQScVF?= =?us-ascii?Q?+kpDDzt/PoGQiylBpWmcL69XQv+cJtIaKYmlJYVN9DLtgv9Li8BMrSR+5d01?= =?us-ascii?Q?ItV1N8GjO4TFxoH1/qbdHn6v9fFIocDer5eC0r2sd0bfXBkpvUhWm4t4IsLm?= =?us-ascii?Q?xIAkGG+PbQF3jF/yfpxhWYLZKKN1mcDGjxBpJmEPgrvABi/YD3i15hrorpHy?= =?us-ascii?Q?ARLDm4lS5T1olNgDiQA5EmHMrwtrH0ElqkgRzSntTka7Z7u253oh6ES9qVpu?= =?us-ascii?Q?vpU2c0ecQihSbQaMzHAnlvXy7gUCIhoiGPQthQW3F9ckgYMt7zdMLZ0LzzMe?= =?us-ascii?Q?IwhmG9TvFWYNMVjc8Q8foTi/IHvWM4QrBBB1daJYF0wWqaEV0/0gov8F6pS1?= =?us-ascii?Q?B8R2lUVAIRreVcvjxsoVTIgGMRIAfzdm5ZrGtaMRxQcx0m/EBadYfkmy6lR7?= =?us-ascii?Q?RKpewZnxGd4yGSVqi0dvkImTGFU2Gvgw6t0ulwAKgupqVEuGEWetfKcN3TRP?= =?us-ascii?Q?tZeWoNe9N14J94uH6ZzoYxEZB/a23Jh60ldpMLR/PZPI3t1IUjPN9l8xRlJ8?= =?us-ascii?Q?XqEZghXE88jotZXWhg+PeFpBjXuo/y0B7yaXDIFOHMiiYpFuZuxX94IHBobn?= =?us-ascii?Q?EYnTM8i7HPydon5xA+Bk5o8socF+M23JWercn8atu1YLU9usPc6IOUR3TR1H?= =?us-ascii?Q?J5TmeZs1BreRaFyXPhs4GkSDntpx+S4SfKnG8vGJUd2EMP1h3xfL5aRVB1LD?= =?us-ascii?Q?UiKr3qXO3rTLHMroQ5Pw2Q4GCNrIJmwgUw2oR7IVTxJh7Aih0l/5/769aSbR?= =?us-ascii?Q?00dvfjUm2m/mU/bgCAi/26Vz2ssUs9xlK5x/EPUl2RyjDWM9SsOsA0rR0Atx?= =?us-ascii?Q?13xsha61q8u2Eyz2VVVt+lijlAZwOj2Zn0p8lrHM+GvJRHYOvi1g4PF4eDyS?= =?us-ascii?Q?DHkTmM/VGC6Rv3zSneBWyyY3KlDxeYPiMLrqtZpNl0J991BthPMWyOw2HIam?= =?us-ascii?Q?hgXUnqSu04Vto6WMOa/7Yhlh74wvYr/2Usu1ugQCEqQ2UKI65dhi/cZ+AglR?= =?us-ascii?Q?lRzWPBmHQlVujPa+OUzmsomJe9gXIjLkAx0GTQpGpYyv9YHorTBpxSR3eCIW?= =?us-ascii?Q?g/Pk6ORqc6Rgf7T8zWezLcgyigSizHrWRo9lc7ASLbKrho48GxK1XhrwAcYy?= =?us-ascii?Q?ERTlryNNn9nta+WFLsnSFvRakREF3CbToKrzH0O1wNq3mK9qAVmOkbl0/oHC?= =?us-ascii?Q?UjnsZdWRyEsBYMclP5VqtF9d2nIYZvb/bTZ4Lj4SBqvcvmgMaqoa+cDuFH49?= =?us-ascii?Q?MYyUlgNRbLh3lWrP46DKzlkPuuxTr6MnmWrvtJ8slnU6RlXI5RZ6iehzfpIo?= =?us-ascii?Q?3TQkz43lgbR5OWpCZvidOO5F+Vrb6qgXbEzGrjdpqZH6CoEp8MKWyeUc80sV?= =?us-ascii?Q?rJnr1oMep3B9yaRrTuDm7KGnHSpblj/o3jrh5j3VoZ4DAmLkKlzzl5UeyXno?= =?us-ascii?Q?0MSacn6MalUTRB4VBvilI0ohiQg47gs=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: e0a05f85-ded5-4959-7712-08df09ae2d9e X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:20.6090 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: s0z44zI4jIjJG34ecgbaA2oojZnCaLxzycoONqsf9qJBZazNDjuHEjusHbB32E7a2rnmnKqK6XQGGY3DAi5jeK9LpAKPRmv7rVi/wJQ5BSY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: OSNPR02MB8962 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c405::5; envelope-from=bin.meng@processmission.com; helo=TYPPR03CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, RCVD_IN_DNSWL_NONE=-0.0001, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434962944158500 Content-Type: text/plain; charset="utf-8" Model the E2000 Phytium Boot ROM as a standalone device. Parse the selected fip-all.bin medium and validate its PBF, TF-A FIP, and platform parameter records. Use the common PBF parameter header to validate exact E2000 PLL, PCIe, DDR/MCU, and COMMON records, their declared sizes, and slot bounds. Stage the opaque records without interpreting service-specific payloads or selecting handoff addresses from their versions. Locate the embedded TF-A FIP and memmap drivers from their data-structure relationships. Validate the documented vendor-private handoff relations instead of maintaining unexplained firmware-version address tables. Expose the board strap as a PBR boot-mode property and derive the firmware-visible boot-media status inside the device. Stage IACC, relocate BL1, build the firmware handoff state, and release the primary CPU selected by the firmware. Keep status, boot SRAM, IACC, reset sequencing, and migration state inside the device so board code only supplies topology and the selected boot backend. Signed-off-by: Bin Meng --- hw/misc/meson.build | 1 + hw/misc/phytium_e2000_pbr.c | 1221 +++++++++++++++++++++++++++ include/hw/misc/phytium_e2000_pbr.h | 55 ++ 3 files changed, 1277 insertions(+) create mode 100644 hw/misc/phytium_e2000_pbr.c create mode 100644 include/hw/misc/phytium_e2000_pbr.h diff --git a/hw/misc/meson.build b/hw/misc/meson.build index a2ea120dd4..8db55e3ef9 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -18,6 +18,7 @@ system_ss.add(when: 'CONFIG_A9SCU', if_true: files('a9scu= .c')) system_ss.add(when: 'CONFIG_ARM11SCU', if_true: files('arm11scu.c')) system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= ddr.c')) system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= mhu.c')) +system_ss.add(when: 'CONFIG_PHYTIUM_E2000', if_true: files('phytium_e2000_= pbr.c')) =20 system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_ras.c')) =20 diff --git a/hw/misc/phytium_e2000_pbr.c b/hw/misc/phytium_e2000_pbr.c new file mode 100644 index 0000000000..4485f073e1 --- /dev/null +++ b/hw/misc/phytium_e2000_pbr.c @@ -0,0 +1,1221 @@ +/* + * Phytium E2000 PBR (Phytium Boot ROM) model + * + * The on-chip PBR does not execute Arm instructions in QEMU. This device + * reproduces its boot-medium loading and handoff behavior before releasing + * PBF on the primary CPU selected by the firmware container. + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/misc/phytium_e2000_pbr.h" + +#include "hw/core/cpu.h" +#include "hw/core/qdev-properties.h" +#include "hw/core/register.h" +#include "hw/misc/phytium_e2000_mhu.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "qemu/cutils.h" +#include "qemu/host-utils.h" +#include "qemu/module.h" +#include "qemu/units.h" +#include "system/address-spaces.h" +#include "system/block-backend-io.h" + +REG32(RESET_SOURCE, 0x00) +REG32(SCP_READY, 0x04) +REG32(BOOT_MEDIA, 0x08) +REG32(ETH_TRAINING_STATUS, 0x60) + +#define PHYTIUM_E2000_PBR_R_MAX \ + (PHYTIUM_E2000_PBR_MMIO_SIZE / sizeof(uint32_t)) + +#define PHYTIUM_E2000_FIP_ALL_HEADER_SIZE 0x000f4c10 +#define PHYTIUM_E2000_FIP_ALL_PAYLOAD_INFO_OFFSET 0x000f4c00 +#define PHYTIUM_E2000_FIP_ALL_MIN_SIZE 0x00100000 +#define PHYTIUM_E2000_FIP_ALL_MAX_SIZE (4 * MiB) +#define PHYTIUM_E2000_TFA_FIP_OFFSET 0x000d0000 +#define PHYTIUM_E2000_TFA_FIP_MAGIC 0xaa640001 +#define PHYTIUM_E2000_TFA_FIP_HEADER_SIZE 16 +#define PHYTIUM_E2000_TFA_FIP_UUID_SIZE 16 +#define PHYTIUM_E2000_TFA_FIP_ENTRY_SIZE 40 +#define PHYTIUM_E2000_TFA_FIP_MAX_ENTRIES 64 + +#define PHYTIUM_E2000_PBF_PARAMETER_OFFSET 0x000f4000 +#define PHYTIUM_E2000_PBF_MAGIC 0x54460000 +#define PHYTIUM_E2000_PBF_PRIMARY_CORE_OFFSET 0x1c +#define PHYTIUM_E2000_BL1_FLASH_OFFSET 0x00040000 +#define PHYTIUM_E2000_BL1_SIZE 0x00090000 +#define PHYTIUM_E2000_PBR_BL1_RUNTIME_BASE 0xf8c40000 + +#define PHYTIUM_E2000_PBR_ROOT_OFFSET 0x00000f00 +#define PHYTIUM_E2000_PBR_ROOT \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x1000) +#define PHYTIUM_E2000_PBR_PARAM_NODE \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x10a0) +#define PHYTIUM_E2000_PBR_PARAM_SLOT \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x1200) +#define PHYTIUM_E2000_PBR_PLL_DESC \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x1220) +#define PHYTIUM_E2000_PBR_MCU_DESC \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x1240) +#define PHYTIUM_E2000_PBR_PCIE_DESC \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x1260) +#define PHYTIUM_E2000_PBR_COMMON_DESC \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0x1280) + +#define PHYTIUM_E2000_PBR_SCP_PARAM_BASE 0x32a10c00 +#define PHYTIUM_E2000_PBR_PLL_PAYLOAD \ + (PHYTIUM_E2000_PBR_SCP_PARAM_BASE + 0x000) +#define PHYTIUM_E2000_PBR_MCU_PAYLOAD \ + (PHYTIUM_E2000_PBR_SCP_PARAM_BASE + 0x100) +#define PHYTIUM_E2000_PBR_PCIE_PAYLOAD \ + (PHYTIUM_E2000_PBR_SCP_PARAM_BASE + 0x200) +#define PHYTIUM_E2000_PBR_COMMON_PAYLOAD \ + (PHYTIUM_E2000_PBR_SCP_PARAM_BASE + 0x300) +#define PHYTIUM_E2000_PBR_PARAM_COPY 0xf1801300 +#define PHYTIUM_E2000_PBR_PARAM_COPY_SIZE 0x20 + +#define PHYTIUM_E2000_PARAM_BASE 0x000f5000 +#define PHYTIUM_E2000_PARAM_SLOT_SIZE 0x100 +#define PHYTIUM_PBF_PARAM_SIZE_OFFSET 0x08 +#define PHYTIUM_PBF_PARAM_HEADER_SIZE 0x10 + +typedef enum PhytiumE2000PbfParameter { + PHYTIUM_E2000_PBF_PARAM_PLL, + PHYTIUM_E2000_PBF_PARAM_DDR, + PHYTIUM_E2000_PBF_PARAM_PCIE, + PHYTIUM_E2000_PBF_PARAM_COMMON, + PHYTIUM_E2000_PBF_PARAM_COUNT, +} PhytiumE2000PbfParameter; + +typedef struct PhytiumE2000PbfParameterSpec { + const char *name; + size_t source_offset; + hwaddr destination; + uint32_t magic; + uint32_t minimum_size; + uint32_t slot_size; +} PhytiumE2000PbfParameterSpec; + +/* + * The PBF interface specification publishes the common parameter-record + * header, but not this E2000 fip-all.bin placement or the PBR-owned SCP S= RAM + * handoff. Keep the documented record shape separate from this + * firmware-derived E2000 profile. + * + * The specification's older PLL/PCIe/DDR magics are 0x54460010, + * 0x54460011, and 0x54460014. Every inspected E2000 image instead uses t= he + * exact values below. Do not infer compatibility from the common prefix: + * recognizing a record class does not prove that this PBF accepts its + * payload format. + */ +static const PhytiumE2000PbfParameterSpec +phytium_e2000_pbf_parameters[PHYTIUM_E2000_PBF_PARAM_COUNT] =3D { + [PHYTIUM_E2000_PBF_PARAM_PLL] =3D { + .name =3D "PLL", + .source_offset =3D PHYTIUM_E2000_PARAM_BASE, + .destination =3D PHYTIUM_E2000_PBR_PLL_PAYLOAD, + .magic =3D 0x54460020, + .minimum_size =3D PHYTIUM_PBF_PARAM_HEADER_SIZE, + .slot_size =3D PHYTIUM_E2000_PARAM_SLOT_SIZE, + }, + [PHYTIUM_E2000_PBF_PARAM_DDR] =3D { + /* MCU is Memory Controller Unit, not a microcontroller */ + .name =3D "DDR/MCU", + .source_offset =3D PHYTIUM_E2000_PARAM_BASE + 0x300, + .destination =3D PHYTIUM_E2000_PBR_MCU_PAYLOAD, + .magic =3D 0x54460024, + .minimum_size =3D PHYTIUM_PBF_PARAM_HEADER_SIZE, + .slot_size =3D PHYTIUM_E2000_PARAM_SLOT_SIZE, + }, + [PHYTIUM_E2000_PBF_PARAM_PCIE] =3D { + .name =3D "PCIe", + .source_offset =3D PHYTIUM_E2000_PARAM_BASE + 0x100, + .destination =3D PHYTIUM_E2000_PBR_PCIE_PAYLOAD, + .magic =3D 0x54460021, + .minimum_size =3D PHYTIUM_PBF_PARAM_HEADER_SIZE, + .slot_size =3D PHYTIUM_E2000_PARAM_SLOT_SIZE, + }, + [PHYTIUM_E2000_PBF_PARAM_COMMON] =3D { + .name =3D "COMMON", + .source_offset =3D PHYTIUM_E2000_PARAM_BASE + 0x200, + .destination =3D PHYTIUM_E2000_PBR_COMMON_PAYLOAD, + .magic =3D 0x54460013, + .minimum_size =3D PHYTIUM_PBF_PARAM_HEADER_SIZE, + .slot_size =3D PHYTIUM_E2000_PARAM_SLOT_SIZE, + }, +}; + +static const PhytiumE2000PbfParameterSpec +phytium_e2000_pbf_summary =3D { + /* + * The public service specification does not describe this container + * summary. All inspected E2000 images nevertheless use the same comm= on + * header, followed by the PBR-to-PBF fields consumed below. + */ + .name =3D "PBF", + .source_offset =3D PHYTIUM_E2000_PBF_PARAMETER_OFFSET, + .magic =3D PHYTIUM_E2000_PBF_MAGIC, + .minimum_size =3D PHYTIUM_E2000_PBR_PARAM_COPY_SIZE, + .slot_size =3D PHYTIUM_E2000_PARAM_SLOT_SIZE, +}; + +/* + * TF-A v2.3 represents an I/O driver as an io_dev_connector_t followed by + * io_dev_funcs_t. The former contains one pointer and the latter contains + * nine function pointers on AArch64. PBF embeds a FIP driver, a memmap + * driver, and the memmap driver's static io_dev_info_t consecutively. + * + * These sizes come from the public TF-A v2.3 io_driver.h ABI. They are n= ot + * Phytium guesses and must stay expressed in terms of the TF-A types inst= ead + * of unexplained offsets such as 0x50, 0xa0, and 0xb0. + */ +#define PHYTIUM_E2000_TFA_IO_CONNECTOR_SIZE sizeof(uint64_t) +#define PHYTIUM_E2000_TFA_IO_FUNC_COUNT 9 +#define PHYTIUM_E2000_TFA_IO_FUNCS_SIZE \ + (PHYTIUM_E2000_TFA_IO_FUNC_COUNT * sizeof(uint64_t)) +#define PHYTIUM_E2000_TFA_IO_DRIVER_SIZE \ + (PHYTIUM_E2000_TFA_IO_CONNECTOR_SIZE + PHYTIUM_E2000_TFA_IO_FUNCS_SIZE) +#define PHYTIUM_E2000_TFA_FIP_DRIVER_OFFSET 0 +#define PHYTIUM_E2000_TFA_MEMMAP_DRIVER_OFFSET \ + PHYTIUM_E2000_TFA_IO_DRIVER_SIZE +#define PHYTIUM_E2000_TFA_MEMMAP_DEV_INFO_OFFSET \ + (2 * PHYTIUM_E2000_TFA_IO_DRIVER_SIZE) +#define PHYTIUM_E2000_TFA_IO_DEV_INFO_SIZE (2 * sizeof(uint64_t)) +#define PHYTIUM_E2000_TFA_IO_DRIVER_GROUP_SIZE \ + (PHYTIUM_E2000_TFA_MEMMAP_DEV_INFO_OFFSET + \ + PHYTIUM_E2000_TFA_IO_DEV_INFO_SIZE) + +/* + * A TF-A platform I/O policy entry contains dev_handle, image_spec, and + * check. Three entries are sufficient to distinguish the leading memmap + * policy from the following FIP policies in every inspected PBF. + */ +#define PHYTIUM_E2000_TFA_IO_POLICY_ENTRY_SIZE (3 * sizeof(uint64_t)) +#define PHYTIUM_E2000_TFA_IO_POLICY_PREFIX_SIZE \ + (3 * PHYTIUM_E2000_TFA_IO_POLICY_ENTRY_SIZE) + +/* + * The address of fip_dev_info is not present as data in the PBF image. P= BR + * obtains it by calling the FIP driver's dev_open callback. Disassembly = of + * that callback in the 2 GiB and 4 GiB Phytium Pi SDK PBFs and the COMe S= DK + * PBF shows the compiler-emitted object 0xb0 bytes before the fip_dev_con + * slot. This is a property of those firmware builds, not a TF-A or hardw= are + * ABI. + * + * Executing an arbitrary PBF callback inside QEMU's reset path is neither= a + * safe parser nor an emulation of the ROM. Keep this one empirical relat= ion + * explicit and reject images whose surrounding TF-A structures do not mat= ch, + * rather than silently selecting an address from the DDR/MCU record versi= on. + */ +#define PHYTIUM_E2000_PBR_FIP_DEV_INFO_BACKOFF 0xb0 +#define PHYTIUM_E2000_PBR_FIP_DEV_STATE_OFFSET 0x10 + +typedef struct PhytiumE2000TfaIoHandoff { + hwaddr fip_connector_slot; + hwaddr fip_handle_slot; + hwaddr fip_dev_info; + hwaddr fip_dev_state; + hwaddr fip_connector; + hwaddr fip_funcs; + hwaddr memmap_connector_slot; + hwaddr memmap_handle_slot; + hwaddr memmap_connector; + hwaddr memmap_dev_info; +} PhytiumE2000TfaIoHandoff; + +struct PhytiumE2000PBRState { + SysBusDevice parent_obj; + + uint32_t regs[PHYTIUM_E2000_PBR_R_MAX]; + RegisterInfo regs_info[PHYTIUM_E2000_PBR_R_MAX]; + MemoryRegion boot_sram; + MemoryRegion iacc; + uint32_t boot_media; + BlockBackend *boot_blk; + char *boot_mode; + hwaddr ram_base; + uint64_t ram_size; + uint64_t cpu_mpidrs[PHYTIUM_E2000_PBR_MAX_CPUS]; + CPUState *cpus[PHYTIUM_E2000_PBR_MAX_CPUS]; + unsigned int num_cpus; + bool firmware_loaded; + int32_t primary_cpu; + uint32_t parameter_sizes[PHYTIUM_E2000_PBF_PARAM_COUNT]; + PhytiumE2000TfaIoHandoff tfa_io; + uint8_t *iacc_image; + size_t iacc_image_size; + uint8_t *bl1; + size_t bl1_size; +}; + +static const char *phytium_e2000_pbr_boot_medium(PhytiumE2000PBRState *s) +{ + if (!strcmp(s->boot_mode, PHYTIUM_E2000_PBR_BOOT_MODE_QSPI)) { + return "QSPI"; + } + + return "SD"; +} + +static const RegisterAccessInfo phytium_e2000_pbr_regs_info[] =3D { + /* + * These reset values are the boot contract observed by the vendor PBF: + * reset source 1 selects the power-on path, 0xabcdef releases the SCP + * ready wait, boot media reflects the board strap selected by PBR, and + * 0x0c reports the Ethernet training state expected by the tested + * firmware. + * + * They remain read-only because software is consuming PBR-owned statu= s, + * not configuring a live peripheral. + */ + { .name =3D "RESET_SOURCE", .addr =3D A_RESET_SOURCE, + .reset =3D 0x1, .ro =3D UINT32_MAX }, + { .name =3D "SCP_READY", .addr =3D A_SCP_READY, + .reset =3D 0x00abcdef, .ro =3D UINT32_MAX }, + { .name =3D "BOOT_MEDIA", .addr =3D A_BOOT_MEDIA, + .ro =3D UINT32_MAX }, + { .name =3D "ETH_TRAINING_STATUS", .addr =3D A_ETH_TRAINING_STATUS, + .reset =3D 0x0c, .ro =3D UINT32_MAX }, +}; + +static const MemoryRegionOps phytium_e2000_pbr_ops =3D { + .read =3D register_read_memory, + .write =3D register_write_memory, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + /* + * PBF byte-copies the complete status structure into SCP SRAM, + * including reserved holes such as base + 0x10. Accept subword and + * unaligned reads even though the defined status fields are 32-bi= t. + */ + .min_access_size =3D 1, + .max_access_size =3D 4, + .unaligned =3D true, + }, +}; + +static bool phytium_e2000_pbr_ranges_overlap(uint64_t first_offset, + uint64_t first_size, + uint64_t second_offset, + uint64_t second_size) +{ + if (!first_size || !second_size) { + return false; + } + + return first_offset < second_offset + second_size && + second_offset < first_offset + first_size; +} + +static bool phytium_e2000_pbr_fip_extent(const uint8_t *header, + uint64_t medium_size, + size_t *extent, Error **errp) +{ + const uint8_t *info =3D + header + PHYTIUM_E2000_FIP_ALL_PAYLOAD_INFO_OFFSET; + uint32_t bl33_offset =3D ldl_le_p(info); + uint32_t bl33_size =3D ldl_le_p(info + 4); + uint32_t bl32_offset =3D ldl_le_p(info + 8); + uint32_t bl32_size =3D ldl_le_p(info + 12); + uint32_t bl33_end; + uint32_t bl32_end; + uint64_t image_extent; + + if (ldl_le_p(header + PHYTIUM_E2000_PBF_PARAMETER_OFFSET) !=3D + PHYTIUM_E2000_PBF_MAGIC) { + error_setg(errp, "PBF magic at 0x%x is not 0x%08x", + PHYTIUM_E2000_PBF_PARAMETER_OFFSET, + PHYTIUM_E2000_PBF_MAGIC); + return false; + } + + if (uadd32_overflow(bl33_offset, bl33_size, &bl33_end) || + uadd32_overflow(bl32_offset, bl32_size, &bl32_end)) { + error_setg(errp, "BL32/BL33 metadata overflows its address range"); + return false; + } + + if (bl33_end > medium_size || bl32_end > medium_size) { + error_setg(errp, "BL32/BL33 range exceeds the boot medium"); + return false; + } + + if (phytium_e2000_pbr_ranges_overlap(bl33_offset, bl33_size, + bl32_offset, bl32_size)) { + error_setg(errp, "BL32 and BL33 payload ranges overlap"); + return false; + } + + image_extent =3D MAX((uint64_t)PHYTIUM_E2000_FIP_ALL_MIN_SIZE, + MAX(bl33_end, bl32_end)); + if (image_extent > medium_size) { + error_setg(errp, "computed fip-all.bin extent 0x%" PRIx64 + " exceeds the boot medium size 0x%" PRIx64, + image_extent, medium_size); + return false; + } + if (image_extent > PHYTIUM_E2000_FIP_ALL_MAX_SIZE) { + error_setg(errp, "computed fip-all.bin extent 0x%" PRIx64 + " exceeds the 4 MiB firmware region", image_extent); + return false; + } + + *extent =3D image_extent; + return true; +} + +static bool phytium_e2000_pbr_tfa_fip_valid(const uint8_t *data, size_t si= ze, + Error **errp) +{ + const uint8_t *fip =3D data + PHYTIUM_E2000_TFA_FIP_OFFSET; + uint64_t max_payload_end =3D 0; + uint64_t min_payload_offset =3D UINT64_MAX; + uint64_t available; + size_t entry_offset; + unsigned int i; + bool has_entry =3D false; + + if (size < PHYTIUM_E2000_TFA_FIP_OFFSET + + PHYTIUM_E2000_TFA_FIP_HEADER_SIZE + + PHYTIUM_E2000_TFA_FIP_ENTRY_SIZE) { + error_setg(errp, "image is too small for the TF-A FIP header"); + return false; + } + if (ldl_le_p(fip) !=3D PHYTIUM_E2000_TFA_FIP_MAGIC) { + error_setg(errp, "TF-A FIP magic at 0x%x is not 0x%08x", + PHYTIUM_E2000_TFA_FIP_OFFSET, + PHYTIUM_E2000_TFA_FIP_MAGIC); + return false; + } + if (!ldl_le_p(fip + sizeof(uint32_t))) { + error_setg(errp, "TF-A FIP serial number is zero"); + return false; + } + + available =3D size - PHYTIUM_E2000_TFA_FIP_OFFSET; + entry_offset =3D PHYTIUM_E2000_TFA_FIP_HEADER_SIZE; + for (i =3D 0; i < PHYTIUM_E2000_TFA_FIP_MAX_ENTRIES; i++) { + const uint8_t *entry; + uint64_t payload_offset; + uint64_t payload_size; + uint64_t payload_end; + uint64_t payload_flags; + + if (entry_offset + PHYTIUM_E2000_TFA_FIP_ENTRY_SIZE > available) { + error_setg(errp, "TF-A FIP TOC has no in-bounds terminator"); + return false; + } + + entry =3D fip + entry_offset; + payload_offset =3D ldq_le_p(entry + PHYTIUM_E2000_TFA_FIP_UUID_SIZ= E); + payload_size =3D ldq_le_p(entry + + PHYTIUM_E2000_TFA_FIP_UUID_SIZE + 8); + payload_flags =3D ldq_le_p(entry + + PHYTIUM_E2000_TFA_FIP_UUID_SIZE + 16); + if (buffer_is_zero(entry, PHYTIUM_E2000_TFA_FIP_UUID_SIZE)) { + uint64_t toc_end =3D entry_offset + + PHYTIUM_E2000_TFA_FIP_ENTRY_SIZE; + + /* + * A zero UUID terminates the TF-A TOC. Its offset records the= end + * of the package rather than another payload start, so all pr= ior + * payloads and the TOC itself must fit below that boundary. + */ + if (!has_entry) { + error_setg(errp, "TF-A FIP TOC has no payload entries"); + return false; + } + if (payload_size || payload_flags || payload_offset < toc_end = || + payload_offset > available || + max_payload_end > payload_offset || + min_payload_offset < toc_end) { + error_setg(errp, "TF-A FIP TOC terminator is out of bounds= "); + return false; + } + return true; + } + + if (uadd64_overflow(payload_offset, payload_size, &payload_end) || + payload_offset < PHYTIUM_E2000_TFA_FIP_HEADER_SIZE || + payload_end > available) { + error_setg(errp, "TF-A FIP payload range is out of bounds"); + return false; + } + has_entry =3D true; + min_payload_offset =3D MIN(min_payload_offset, payload_offset); + max_payload_end =3D MAX(max_payload_end, payload_end); + entry_offset +=3D PHYTIUM_E2000_TFA_FIP_ENTRY_SIZE; + } + + error_setg(errp, "TF-A FIP TOC exceeds %u entries", + PHYTIUM_E2000_TFA_FIP_MAX_ENTRIES); + return false; +} + +static bool phytium_e2000_pbr_parameter_valid( + const uint8_t *data, size_t size, + const PhytiumE2000PbfParameterSpec *spec, uint32_t *validated_size, + Error **errp) +{ + const uint8_t *parameter; + uint32_t record_size; + + if (spec->source_offset > size || + size - spec->source_offset < PHYTIUM_PBF_PARAM_HEADER_SIZE) { + error_setg(errp, "%s parameter record at 0x%zx is out of bounds", + spec->name, spec->source_offset); + return false; + } + + parameter =3D data + spec->source_offset; + if (ldl_le_p(parameter) !=3D spec->magic) { + error_setg(errp, "%s parameter magic at 0x%zx is not 0x%08x", + spec->name, spec->source_offset, spec->magic); + return false; + } + + record_size =3D ldl_le_p(parameter + PHYTIUM_PBF_PARAM_SIZE_OFFSET); + if (record_size < spec->minimum_size || + record_size > spec->slot_size || + record_size > size - spec->source_offset) { + error_setg(errp, "%s parameter size 0x%x is outside the " + "0x%x-byte parameter slot", spec->name, record_size, + spec->slot_size); + return false; + } + + /* + * The public PBF ABI defines magic, version, size, and reserved as a + * common 16-byte header for PLL, PCIe, DDR, and COMMON parameters. It + * passes each service-specific payload to PBF by address rather than + * defining it as part of a PBR layout. In particular, the DDR record + * contains firmware-owned SPD and training data. + * + * GET_PARAMETER_VERSION reports a separate version for each PBF servi= ce. + * Consequently, a record version describes that service's payload, not + * the PBR handoff graph or TF-A object placement. Preserve the paylo= ad + * and reserved word verbatim and accept an otherwise valid future + * version instead of inventing version-specific PBR layouts. + */ + if (validated_size) { + *validated_size =3D record_size; + } + + return true; +} + +static bool phytium_e2000_pbr_pbf_code_pointer(uint64_t value) +{ + return value >=3D PHYTIUM_E2000_PBR_IACC_BASE + + PHYTIUM_E2000_BL1_FLASH_OFFSET && + value < PHYTIUM_E2000_PBR_IACC_BASE + + PHYTIUM_E2000_TFA_FIP_OFFSET && + !(value & 3); +} + +static bool phytium_e2000_pbr_boot_sram_qword(uint64_t value) +{ + return value >=3D PHYTIUM_E2000_PBR_BOOT_SRAM_BASE && + value <=3D PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + + PHYTIUM_E2000_PBR_BOOT_SRAM_SIZE - sizeof(uint64_t) && + !(value & 7); +} + +static bool phytium_e2000_pbr_tfa_io_driver_candidate(const uint8_t *data, + size_t offset) +{ + unsigned int implemented =3D 0; + unsigned int i; + + /* + * connector->dev_open is mandatory. Individual io_dev_funcs_t entries + * may be NULL: for example, TF-A's FIP driver has no size/write metho= ds + * and its memmap driver has no dev_close method in the inspected buil= ds. + * Requiring every slot to be non-NULL would encode one implementation, + * while accepting non-code values would make the scan match random da= ta. + */ + if (!phytium_e2000_pbr_pbf_code_pointer(ldq_le_p(data + offset))) { + return false; + } + + for (i =3D 0; i < PHYTIUM_E2000_TFA_IO_FUNC_COUNT; i++) { + uint64_t function =3D ldq_le_p( + data + offset + PHYTIUM_E2000_TFA_IO_CONNECTOR_SIZE + + i * sizeof(uint64_t)); + + if (!function) { + continue; + } + if (!phytium_e2000_pbr_pbf_code_pointer(function)) { + return false; + } + implemented++; + } + + /* + * All known TF-A I/O drivers used here implement substantially more t= han + * a connector. This lower bound is a parser discriminator, not an ABI + * promise about which particular callbacks must exist. + */ + return implemented >=3D 4; +} + +static bool phytium_e2000_pbr_tfa_io_driver_group_candidate( + const uint8_t *data, size_t offset) +{ + size_t memmap =3D offset + PHYTIUM_E2000_TFA_MEMMAP_DRIVER_OFFSET; + size_t dev_info =3D offset + PHYTIUM_E2000_TFA_MEMMAP_DEV_INFO_OFFSET; + uint64_t expected_funcs =3D + PHYTIUM_E2000_PBR_IACC_BASE + memmap + + PHYTIUM_E2000_TFA_IO_CONNECTOR_SIZE; + + if (!phytium_e2000_pbr_tfa_io_driver_candidate( + data, offset + PHYTIUM_E2000_TFA_FIP_DRIVER_OFFSET) || + !phytium_e2000_pbr_tfa_io_driver_candidate(data, memmap)) { + return false; + } + + /* + * The memmap driver uses a static io_dev_info_t immediately after both + * drivers. Its funcs member points at the memmap io_dev_funcs_t and = its + * info member is zero. This relation is defined by TF-A source and m= akes + * the otherwise relocatable driver group uniquely identifiable. + */ + return ldq_le_p(data + dev_info) =3D=3D expected_funcs && + !ldq_le_p(data + dev_info + sizeof(uint64_t)); +} + +static bool phytium_e2000_pbr_tfa_io_policy_candidate( + const uint8_t *data, size_t offset, hwaddr *memmap_handle_slot, + hwaddr *fip_handle_slot) +{ + const uint8_t *memmap_policy =3D data + offset; + const uint8_t *fip_policy =3D memmap_policy + + PHYTIUM_E2000_TFA_IO_POLICY_ENTRY_SIZE; + const uint8_t *second_fip_policy =3D + fip_policy + PHYTIUM_E2000_TFA_IO_POLICY_ENTRY_SIZE; + uint64_t memmap_handle =3D ldq_le_p(memmap_policy); + uint64_t fip_handle =3D ldq_le_p(fip_policy); + uint64_t second_fip_handle =3D ldq_le_p(second_fip_policy); + const uint8_t *policies[] =3D { + memmap_policy, fip_policy, second_fip_policy, + }; + unsigned int i; + + /* + * TF-A's plat_io_policy[] stores a pointer to each driver's handle sl= ot, + * not the handle value itself. The first policy maps the FIP contain= er + * through the memmap device; image policies that follow use the FIP + * device. This ordering is visible in arm_io_storage.c and is shared= by + * all three inspected PBF images. + * + * The complete vendor table has 28 entries and contains sparse zero + * holes, but neither its length nor a terminator is self-describing. + * Depending on that sample-specific count would merely replace one ma= gic + * address with a magic array length, so only the semantically meaning= ful + * three-entry prefix is used to locate the two handle slots. + */ + if (!phytium_e2000_pbr_boot_sram_qword(memmap_handle) || + !phytium_e2000_pbr_boot_sram_qword(fip_handle) || + memmap_handle =3D=3D fip_handle || second_fip_handle !=3D fip_hand= le || + memmap_handle < PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + + sizeof(uint64_t) || + fip_handle < PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + + sizeof(uint64_t)) { + return false; + } + + for (i =3D 0; i < ARRAY_SIZE(policies); i++) { + if (!phytium_e2000_pbr_pbf_code_pointer( + ldq_le_p(policies[i] + sizeof(uint64_t))) || + !phytium_e2000_pbr_pbf_code_pointer( + ldq_le_p(policies[i] + 2 * sizeof(uint64_t)))) { + return false; + } + } + + *memmap_handle_slot =3D memmap_handle; + *fip_handle_slot =3D fip_handle; + return true; +} + +static bool phytium_e2000_pbr_tfa_io_handoff_valid( + const uint8_t *data, size_t size, PhytiumE2000TfaIoHandoff *handoff, + Error **errp) +{ + size_t scan_end =3D MIN(size, (size_t)PHYTIUM_E2000_TFA_FIP_OFFSET); + size_t driver_offset =3D 0; + hwaddr memmap_handle_slot =3D 0; + hwaddr fip_handle_slot =3D 0; + size_t offset; + + /* + * Real PBR registers and opens the TF-A memmap and FIP I/O devices be= fore + * releasing PBF. QEMU intentionally models that ROM-visible result + * instead of executing undocumented PBR instructions. + * + * The PBF image contains the relocatable driver definitions and policy + * table, so scan for their public TF-A structural relationships. Thi= s is + * why no DDR/MCU record-version address table appears here: even the = two + * version 4 builds put these objects at different IACC offsets. + */ + for (offset =3D PHYTIUM_E2000_BL1_FLASH_OFFSET; + offset + PHYTIUM_E2000_TFA_IO_DRIVER_GROUP_SIZE <=3D scan_end; + offset +=3D sizeof(uint64_t)) { + if (!phytium_e2000_pbr_tfa_io_driver_group_candidate(data, + offset)) { + continue; + } + if (driver_offset) { + error_setg(errp, "PBF contains multiple TF-A I/O driver groups= "); + return false; + } + driver_offset =3D offset; + } + if (!driver_offset) { + error_setg(errp, "PBF does not contain a valid TF-A I/O driver " + "group"); + return false; + } + + for (offset =3D PHYTIUM_E2000_BL1_FLASH_OFFSET; + offset + PHYTIUM_E2000_TFA_IO_POLICY_PREFIX_SIZE <=3D scan_end; + offset +=3D sizeof(uint64_t)) { + hwaddr candidate_memmap_handle; + hwaddr candidate_fip_handle; + + if (!phytium_e2000_pbr_tfa_io_policy_candidate( + data, offset, &candidate_memmap_handle, + &candidate_fip_handle)) { + continue; + } + if (fip_handle_slot) { + error_setg(errp, "PBF contains multiple TF-A I/O policy " + "tables"); + return false; + } + memmap_handle_slot =3D candidate_memmap_handle; + fip_handle_slot =3D candidate_fip_handle; + } + if (!fip_handle_slot) { + error_setg(errp, "PBF does not contain a valid TF-A I/O policy " + "table"); + return false; + } + + handoff->fip_connector_slot =3D fip_handle_slot - sizeof(uint64_t); + handoff->fip_handle_slot =3D fip_handle_slot; + if (handoff->fip_connector_slot < + PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + + PHYTIUM_E2000_PBR_FIP_DEV_INFO_BACKOFF) { + error_setg(errp, "PBF TF-A FIP connector slot is too low for its " + "device state"); + return false; + } + handoff->fip_dev_info =3D handoff->fip_connector_slot - + PHYTIUM_E2000_PBR_FIP_DEV_INFO_BACKOFF; + handoff->fip_dev_state =3D handoff->fip_dev_info + + PHYTIUM_E2000_PBR_FIP_DEV_STATE_OFFSET; + handoff->memmap_connector_slot =3D + memmap_handle_slot - sizeof(uint64_t); + handoff->memmap_handle_slot =3D memmap_handle_slot; + + if (!phytium_e2000_pbr_boot_sram_qword(handoff->fip_dev_info) || + !phytium_e2000_pbr_boot_sram_qword(handoff->fip_dev_state) || + !phytium_e2000_pbr_boot_sram_qword( + handoff->memmap_connector_slot)) { + error_setg(errp, "PBF TF-A I/O handoff objects are outside boot " + "SRAM"); + return false; + } + + handoff->fip_connector =3D + PHYTIUM_E2000_PBR_IACC_BASE + driver_offset + + PHYTIUM_E2000_TFA_FIP_DRIVER_OFFSET; + handoff->fip_funcs =3D + handoff->fip_connector + PHYTIUM_E2000_TFA_IO_CONNECTOR_SIZE; + handoff->memmap_connector =3D + PHYTIUM_E2000_PBR_IACC_BASE + driver_offset + + PHYTIUM_E2000_TFA_MEMMAP_DRIVER_OFFSET; + handoff->memmap_dev_info =3D + PHYTIUM_E2000_PBR_IACC_BASE + driver_offset + + PHYTIUM_E2000_TFA_MEMMAP_DEV_INFO_OFFSET; + return true; +} + +static bool phytium_e2000_pbr_parse_firmware(PhytiumE2000PBRState *s, + const uint8_t *data, + size_t size, Error **errp) +{ + uint32_t primary_mpidr; + uint64_t bl1_end; + int primary_cpu =3D -1; + unsigned int i; + + if (size < PHYTIUM_E2000_BL1_FLASH_OFFSET + + PHYTIUM_E2000_BL1_SIZE) { + error_setg(errp, "image is too small for the PBF handoff data"); + return false; + } + + if (!phytium_e2000_pbr_parameter_valid(data, size, + &phytium_e2000_pbf_summary, + NULL, errp)) { + return false; + } + + for (i =3D 0; i < PHYTIUM_E2000_PBF_PARAM_COUNT; i++) { + if (!phytium_e2000_pbr_parameter_valid( + data, size, &phytium_e2000_pbf_parameters[i], + &s->parameter_sizes[i], errp)) { + return false; + } + } + if (!phytium_e2000_pbr_tfa_io_handoff_valid(data, size, &s->tfa_io, + errp)) { + return false; + } + + primary_mpidr =3D lduw_le_p(data + PHYTIUM_E2000_PBF_PARAMETER_OFFSET + + PHYTIUM_E2000_PBF_PRIMARY_CORE_OFFSET); + /* + * The PBF container stores only Aff1:Aff0 in this 16-bit field. Compa= re + * the same affinities from each complete architectural MPIDR. + */ + for (i =3D 0; i < s->num_cpus; i++) { + if ((s->cpu_mpidrs[i] & 0xffff) =3D=3D primary_mpidr) { + primary_cpu =3D i; + break; + } + } + if (primary_cpu < 0) { + error_setg(errp, "PBR firmware primary core 0x%x is not present; " + "use at least -smp 3", primary_mpidr); + return false; + } + + bl1_end =3D PHYTIUM_E2000_PBR_BL1_RUNTIME_BASE + + PHYTIUM_E2000_BL1_SIZE; + if (s->ram_size < bl1_end - s->ram_base) { + error_setg(errp, "PBR firmware requires RAM to cover PBF runtime " + "address 0x%" HWADDR_PRIx "; use -m 2G", + (hwaddr)PHYTIUM_E2000_PBR_BL1_RUNTIME_BASE); + return false; + } + + if (size > PHYTIUM_E2000_PBR_IACC_SIZE) { + error_setg(errp, "PBR firmware image does not fit in boot IACC"); + return false; + } + + s->firmware_loaded =3D true; + s->primary_cpu =3D primary_cpu; + s->iacc_image_size =3D size; + s->iacc_image =3D g_memdup2(data, size); + s->bl1_size =3D PHYTIUM_E2000_BL1_SIZE; + s->bl1 =3D g_memdup2(data + PHYTIUM_E2000_BL1_FLASH_OFFSET, + s->bl1_size); + return true; +} + +static bool phytium_e2000_pbr_load_firmware(PhytiumE2000PBRState *s, + Error **errp) +{ + g_autofree uint8_t *contents =3D NULL; + const char *boot_medium =3D phytium_e2000_pbr_boot_medium(s); + Error *local_err =3D NULL; + int64_t backend_size; + size_t extent; + + if (!s->boot_blk) { + /* + * A missing backend is valid for direct -kernel boot. Leave + * firmware_loaded clear so the machine selects the generic Arm + * loader instead of the PBR reset handoff. + */ + return true; + } + + backend_size =3D blk_getlength(s->boot_blk); + if (backend_size < 0) { + error_setg_errno(errp, -backend_size, + "failed to determine %s boot-medium size", + boot_medium); + return false; + } + if (backend_size < PHYTIUM_E2000_FIP_ALL_HEADER_SIZE) { + error_setg(errp, "%s is too small for the fip-all.bin metadata", + boot_medium); + return false; + } + + contents =3D g_malloc(PHYTIUM_E2000_FIP_ALL_HEADER_SIZE); + if (blk_pread(s->boot_blk, 0, PHYTIUM_E2000_FIP_ALL_HEADER_SIZE, + contents, 0) < 0) { + error_setg(errp, "failed to read fip-all.bin metadata at %s " + "offset 0", boot_medium); + return false; + } + + if (!phytium_e2000_pbr_fip_extent(contents, backend_size, &extent, + &local_err)) { + error_prepend(&local_err, "invalid fip-all.bin at %s offset 0: ", + boot_medium); + error_propagate(errp, local_err); + return false; + } + + contents =3D g_realloc(contents, extent); + if (extent > PHYTIUM_E2000_FIP_ALL_HEADER_SIZE && + blk_pread(s->boot_blk, PHYTIUM_E2000_FIP_ALL_HEADER_SIZE, + extent - PHYTIUM_E2000_FIP_ALL_HEADER_SIZE, + contents + PHYTIUM_E2000_FIP_ALL_HEADER_SIZE, 0) < 0) { + error_setg(errp, "failed to read fip-all.bin extent 0x%zx from %s " + "offset 0", extent, boot_medium); + return false; + } + + if (!phytium_e2000_pbr_tfa_fip_valid(contents, extent, &local_err)) { + error_prepend(&local_err, "invalid fip-all.bin at %s offset 0: ", + boot_medium); + error_propagate(errp, local_err); + return false; + } + + if (!phytium_e2000_pbr_parse_firmware(s, contents, extent, &local_err)= ) { + error_prepend(&local_err, "invalid fip-all.bin at %s offset 0: ", + boot_medium); + error_propagate(errp, local_err); + return false; + } + + return true; +} + +static void phytium_e2000_pbr_seed_shared(PhytiumE2000PBRState *s) +{ + const PhytiumE2000TfaIoHandoff *tfa_io =3D &s->tfa_io; + uint8_t *sram =3D memory_region_get_ram_ptr(&s->boot_sram); + uint8_t *iacc =3D memory_region_get_ram_ptr(&s->iacc); + uint8_t parameter[PHYTIUM_E2000_PARAM_SLOT_SIZE]; + hwaddr sram_base =3D PHYTIUM_E2000_PBR_BOOT_SRAM_BASE; + unsigned int i; + + /* + * This graph is a firmware-private PBR-to-PBF handoff, not a device-t= ree + * description or a public E2000 register ABI. It was reconstructed by + * tracing the early loads performed by the 2 GiB and 4 GiB Phytium Pi= SDK + * PBFs and the COMe SDK PBF. All three use the same boot-SRAM + * descriptors, SCP-SRAM parameter slots, and 0xf1801300 parameter cop= y. + * + * The addresses cannot be read from fip-all.bin as a documented table. + * They appear as constants in vendor PBF instructions. Teaching the + * parser to recognize arbitrary compiler-generated AArch64 instruction + * sequences would be more fragile than recording the observed ROM ABI + * here. Keep the graph together and heavily annotated so that a futu= re + * firmware failure is treated as missing evidence, not "fixed" by an + * unexplained per-version address. + */ + stq_le_p(sram + PHYTIUM_E2000_PBR_ROOT_OFFSET, + PHYTIUM_E2000_PBR_ROOT); + stq_le_p(sram + (PHYTIUM_E2000_PBR_ROOT - sram_base) + 0x10, + PHYTIUM_E2000_PBR_PARAM_NODE); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PARAM_NODE - sram_base) + 0x18, + PHYTIUM_E2000_PBR_PLL_DESC); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PLL_DESC - sram_base) + 0x08, + PHYTIUM_E2000_PBR_PLL_PAYLOAD); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PARAM_NODE - sram_base) + 0x20, + PHYTIUM_E2000_PBR_PCIE_DESC); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PCIE_DESC - sram_base) + 0x08, + PHYTIUM_E2000_PBR_PCIE_PAYLOAD); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PARAM_NODE - sram_base) + 0x28, + PHYTIUM_E2000_PBR_COMMON_DESC); + stq_le_p(sram + (PHYTIUM_E2000_PBR_COMMON_DESC - sram_base), + PHYTIUM_E2000_PBR_COMMON_PAYLOAD); + stq_le_p(sram + (PHYTIUM_E2000_PBR_COMMON_DESC - sram_base) + 0x08, + PHYTIUM_E2000_PBR_COMMON_PAYLOAD); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PARAM_NODE - sram_base) + 0x30, + PHYTIUM_E2000_PBR_MCU_DESC); + stq_le_p(sram + (PHYTIUM_E2000_PBR_MCU_DESC - sram_base), + PHYTIUM_E2000_PBR_MCU_PAYLOAD); + stq_le_p(sram + (PHYTIUM_E2000_PBR_MCU_DESC - sram_base) + 0x08, + PHYTIUM_E2000_PBR_MCU_PAYLOAD); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PARAM_NODE - sram_base) + 0x38, + PHYTIUM_E2000_PBR_PARAM_SLOT); + stq_le_p(sram + (PHYTIUM_E2000_PBR_PARAM_SLOT - sram_base) + 0x08, + PHYTIUM_E2000_PBR_PARAM_COPY); + + /* + * Reproduce the result of TF-A register_io_dev_*() and dev_open(): + * + * *_dev_con -> embedded io_dev_connector_t + * *_dev_handle -> initialized io_dev_info_t + * fip_dev_info =3D { &fip_dev_funcs, &fip_dev_state } + * + * The memmap driver owns a static io_dev_info_t in the PBF image, whi= le + * the FIP driver creates its state in boot SRAM. plat_io_policy[] po= ints + * at the two *_dev_handle slots populated below. + */ + stq_le_p(sram + (tfa_io->fip_connector_slot - sram_base), + tfa_io->fip_connector); + stq_le_p(sram + (tfa_io->fip_handle_slot - sram_base), + tfa_io->fip_dev_info); + stq_le_p(sram + (tfa_io->fip_dev_info - sram_base), + tfa_io->fip_funcs); + stq_le_p(sram + (tfa_io->fip_dev_info - sram_base) + + sizeof(uint64_t), tfa_io->fip_dev_state); + stq_le_p(sram + (tfa_io->fip_dev_state - sram_base), 0); + stq_le_p(sram + (tfa_io->memmap_connector_slot - sram_base), + tfa_io->memmap_connector); + stq_le_p(sram + (tfa_io->memmap_handle_slot - sram_base), + tfa_io->memmap_dev_info); + + address_space_write(&address_space_memory, + PHYTIUM_E2000_PBR_PARAM_COPY, + MEMTXATTRS_UNSPECIFIED, + iacc + PHYTIUM_E2000_PBF_PARAMETER_OFFSET, + PHYTIUM_E2000_PBR_PARAM_COPY_SIZE); + + /* + * PBF consumes each service parameter through the same public record + * header, while the payload remains service- and version-specific. C= opy + * every validated record without interpretation and clear the rest of + * its PBR-owned slot so that a shorter future format cannot expose st= ale + * reset data. + * + * This also stages PLL at 0x32a10c00. Inspected PBFs follow the boot= -SRAM + * PLL descriptor and require magic 0x54460020 there, just as they req= uire + * the PCIe, COMMON, and DDR/MCU records in the following slots. + */ + for (i =3D 0; i < PHYTIUM_E2000_PBF_PARAM_COUNT; i++) { + const PhytiumE2000PbfParameterSpec *spec =3D + &phytium_e2000_pbf_parameters[i]; + + memset(parameter, 0, sizeof(parameter)); + memcpy(parameter, iacc + spec->source_offset, + s->parameter_sizes[i]); + address_space_write(&address_space_memory, spec->destination, + MEMTXATTRS_UNSPECIFIED, parameter, + spec->slot_size); + } +} + +static void phytium_e2000_pbr_reset_enter(Object *obj, ResetType type) +{ + PhytiumE2000PBRState *s =3D PHYTIUM_E2000_PBR(obj); + int i; + + (void)type; + + /* + * Only architected handoff words have RegisterAccessInfo entries. The + * reserved holes stay zero-filled in the backing register array. + */ + for (i =3D 0; i < ARRAY_SIZE(phytium_e2000_pbr_regs_info); i++) { + register_reset(&s->regs_info[ + phytium_e2000_pbr_regs_info[i].addr / sizeof(uint32_t)]); + } + s->regs[R_BOOT_MEDIA] =3D s->boot_media; +} + +static void phytium_e2000_pbr_reset_hold(Object *obj, ResetType type) +{ + PhytiumE2000PBRState *s =3D PHYTIUM_E2000_PBR(obj); + uint8_t *sram =3D memory_region_get_ram_ptr(&s->boot_sram); + uint8_t *iacc =3D memory_region_get_ram_ptr(&s->iacc); + + (void)type; + memset(sram, 0, PHYTIUM_E2000_PBR_BOOT_SRAM_SIZE); + memset(iacc, 0, PHYTIUM_E2000_PBR_IACC_SIZE); + memory_region_set_dirty(&s->boot_sram, 0, + PHYTIUM_E2000_PBR_BOOT_SRAM_SIZE); + memory_region_set_dirty(&s->iacc, 0, PHYTIUM_E2000_PBR_IACC_SIZE); + + if (!s->firmware_loaded) { + return; + } + + memcpy(iacc, s->iacc_image, s->iacc_image_size); + address_space_write(&address_space_memory, + PHYTIUM_E2000_PBR_BL1_RUNTIME_BASE, + MEMTXATTRS_UNSPECIFIED, s->bl1, s->bl1_size); + phytium_e2000_pbr_seed_shared(s); + phytium_e2000_mhu_seed_mailbox(); +} + +static void phytium_e2000_pbr_reset_exit(Object *obj, ResetType type) +{ + PhytiumE2000PBRState *s =3D PHYTIUM_E2000_PBR(obj); + + (void)type; + if (!s->firmware_loaded) { + return; + } + + g_assert(s->primary_cpu >=3D 0 && s->primary_cpu < s->num_cpus); + g_assert(s->cpus[s->primary_cpu]); + cpu_set_pc(s->cpus[s->primary_cpu], + PHYTIUM_E2000_PBR_BL1_RUNTIME_BASE); +} + +void phytium_e2000_pbr_configure(PhytiumE2000PBRState *s, + BlockBackend *boot_blk, + hwaddr ram_base, uint64_t ram_size, + const uint64_t *cpu_mpidrs, + unsigned int num_cpus) +{ + g_assert(!DEVICE(s)->realized); + g_assert(num_cpus <=3D PHYTIUM_E2000_PBR_MAX_CPUS); + + s->boot_blk =3D boot_blk; + s->ram_base =3D ram_base; + s->ram_size =3D ram_size; + s->num_cpus =3D num_cpus; + memcpy(s->cpu_mpidrs, cpu_mpidrs, + num_cpus * sizeof(s->cpu_mpidrs[0])); +} + +bool phytium_e2000_pbr_firmware_loaded(PhytiumE2000PBRState *s) +{ + return s->firmware_loaded; +} + +int phytium_e2000_pbr_primary_cpu(PhytiumE2000PBRState *s) +{ + g_assert(s->firmware_loaded); + return s->primary_cpu; +} + +void phytium_e2000_pbr_connect_cpu(PhytiumE2000PBRState *s, + unsigned int index, CPUState *cpu) +{ + g_assert(index < s->num_cpus); + g_assert(cpu); + g_assert(!s->cpus[index]); + object_ref(OBJECT(cpu)); + s->cpus[index] =3D cpu; +} + +static void phytium_e2000_pbr_realize(DeviceState *dev, Error **errp) +{ + PhytiumE2000PBRState *s =3D PHYTIUM_E2000_PBR(dev); + bool loaded; + + if (!s->boot_mode) { + error_setg(errp, "boot-mode was not configured"); + return; + } + if (!strcmp(s->boot_mode, PHYTIUM_E2000_PBR_BOOT_MODE_QSPI)) { + s->boot_media =3D PHYTIUM_E2000_PBR_BOOT_MEDIA_QSPI; + } else if (!strcmp(s->boot_mode, PHYTIUM_E2000_PBR_BOOT_MODE_SD0)) { + s->boot_media =3D PHYTIUM_E2000_PBR_BOOT_MEDIA_SD0; + } else { + error_setg(errp, "invalid boot-mode '%s'; valid values are " + "'qspi' and 'sd'", s->boot_mode); + return; + } + if (!s->num_cpus) { + error_setg(errp, "CPU topology was not configured"); + return; + } + loaded =3D phytium_e2000_pbr_load_firmware(s, errp); + s->boot_blk =3D NULL; + if (!loaded) { + return; + } +} + +static const Property phytium_e2000_pbr_properties[] =3D { + DEFINE_PROP_STRING("boot-mode", PhytiumE2000PBRState, boot_mode), +}; + +static void phytium_e2000_pbr_init(Object *obj) +{ + PhytiumE2000PBRState *s =3D PHYTIUM_E2000_PBR(obj); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + RegisterInfoArray *reg_array; + + reg_array =3D register_init_block32( + DEVICE(obj), phytium_e2000_pbr_regs_info, + ARRAY_SIZE(phytium_e2000_pbr_regs_info), s->regs_info, s->regs, + &phytium_e2000_pbr_ops, false, PHYTIUM_E2000_PBR_MMIO_SIZE); + sysbus_init_mmio(sbd, ®_array->mem); + + memory_region_init_ram(&s->boot_sram, obj, "phytium-e2000.boot-sram", + PHYTIUM_E2000_PBR_BOOT_SRAM_SIZE, &error_abort); + sysbus_init_mmio(sbd, &s->boot_sram); + memory_region_init_ram(&s->iacc, obj, "phytium-e2000.iacc", + PHYTIUM_E2000_PBR_IACC_SIZE, &error_abort); + sysbus_init_mmio(sbd, &s->iacc); + s->primary_cpu =3D -1; +} + +static void phytium_e2000_pbr_finalize(Object *obj) +{ + PhytiumE2000PBRState *s =3D PHYTIUM_E2000_PBR(obj); + unsigned int i; + + for (i =3D 0; i < s->num_cpus; i++) { + if (s->cpus[i]) { + object_unref(OBJECT(s->cpus[i])); + } + } + g_free(s->iacc_image); + g_free(s->bl1); +} + +/* + * boot_sram and iacc are RAMBlocks and migrate independently. The parsed + * image buffers remain immutable reset sources reconstructed from the boot + * backend while the destination machine is realized. + */ +static const VMStateDescription phytium_e2000_pbr_vmsd =3D { + .name =3D TYPE_PHYTIUM_E2000_PBR, + .version_id =3D 2, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, PhytiumE2000PBRState, + PHYTIUM_E2000_PBR_R_MAX), + VMSTATE_BOOL_V(firmware_loaded, PhytiumE2000PBRState, 2), + VMSTATE_INT32_V(primary_cpu, PhytiumE2000PBRState, 2), + VMSTATE_END_OF_LIST() + }, +}; + +static void phytium_e2000_pbr_class_init(ObjectClass *klass, const void *d= ata) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + dc->vmsd =3D &phytium_e2000_pbr_vmsd; + dc->realize =3D phytium_e2000_pbr_realize; + device_class_set_props(dc, phytium_e2000_pbr_properties); + rc->phases.enter =3D phytium_e2000_pbr_reset_enter; + rc->phases.hold =3D phytium_e2000_pbr_reset_hold; + rc->phases.exit =3D phytium_e2000_pbr_reset_exit; +} + +static const TypeInfo phytium_e2000_pbr_info =3D { + .name =3D TYPE_PHYTIUM_E2000_PBR, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(PhytiumE2000PBRState), + .instance_init =3D phytium_e2000_pbr_init, + .instance_finalize =3D phytium_e2000_pbr_finalize, + .class_init =3D phytium_e2000_pbr_class_init, +}; + +static void phytium_e2000_pbr_register_types(void) +{ + type_register_static(&phytium_e2000_pbr_info); +} + +type_init(phytium_e2000_pbr_register_types) diff --git a/include/hw/misc/phytium_e2000_pbr.h b/include/hw/misc/phytium_= e2000_pbr.h new file mode 100644 index 0000000000..890d419254 --- /dev/null +++ b/include/hw/misc/phytium_e2000_pbr.h @@ -0,0 +1,55 @@ +/* + * Phytium E2000 PBR (Phytium Boot ROM) model + * + * Copyright (c) 2026 Process Mission + * + * Author: + * Bin Meng + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_PHYTIUM_E2000_PBR_H +#define HW_MISC_PHYTIUM_E2000_PBR_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define TYPE_PHYTIUM_E2000_PBR "phytium-e2000-pbr" +OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000PBRState, PHYTIUM_E2000_PBR) + +/* + * These are E2000 physical addresses, not locations chosen by a particular + * PBF build. Keep them with the PBR device so that the machine memory map= and + * the firmware parser do not grow independent copies of the same constant= s. + * + * The boot SRAM contains the handoff left by the on-chip PBR. IACC is the + * vendor-named boot-time execution window into which PBR places fip-all.b= in. + * The status window is consumed by PBF as a snapshot of PBR-owned state. + */ +#define PHYTIUM_E2000_PBR_STATUS_BASE 0x32a11804 +#define PHYTIUM_E2000_PBR_BOOT_SRAM_BASE 0x30c00000 +#define PHYTIUM_E2000_PBR_IACC_BASE 0x38000000 + +#define PHYTIUM_E2000_PBR_MMIO_SIZE 0x64 +#define PHYTIUM_E2000_PBR_BOOT_SRAM_SIZE 0x00100000 +#define PHYTIUM_E2000_PBR_IACC_SIZE 0x08000000 +#define PHYTIUM_E2000_PBR_MAX_CPUS 4 + +#define PHYTIUM_E2000_PBR_BOOT_MEDIA_QSPI 0x1 +#define PHYTIUM_E2000_PBR_BOOT_MEDIA_SD0 0x4 + +#define PHYTIUM_E2000_PBR_BOOT_MODE_QSPI "qspi" +#define PHYTIUM_E2000_PBR_BOOT_MODE_SD0 "sd" + +void phytium_e2000_pbr_configure(PhytiumE2000PBRState *s, + BlockBackend *boot_blk, + hwaddr ram_base, uint64_t ram_size, + const uint64_t *cpu_mpidrs, + unsigned int num_cpus); +bool phytium_e2000_pbr_firmware_loaded(PhytiumE2000PBRState *s); +int phytium_e2000_pbr_primary_cpu(PhytiumE2000PBRState *s); +void phytium_e2000_pbr_connect_cpu(PhytiumE2000PBRState *s, + unsigned int index, CPUState *cpu); + +#endif --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788434898; cv=pass; d=zohomail.com; s=zohoarc; b=h4/yyufLlzNha1BCaf8F+DZIKGWd5nXog4UQhDxVKWeiNwqIn/UfjdWaw/kCvWTx2pNyOn9OzcqoH+DSPR68PdNjVtGEJIBSnBr5kWbh8V+CNDRPU3n42+4NSsTb4t2L5uvvwr5bzLGZTktpDOLr8vVf+0yFDnqvec3fi9a/CMw= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788434898; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=RPEJQLUZkXmRM6XjN98FFMEdMGGjPzf37MKPgJnatgw=; b=BIPdQxdAWV+BCvlz3kjGNInefPpG6FAlgcZN7PK7bjMSACTx+2UgHMV96+lPjQNt4gPJQXsn4I45MeSB4Z/NLlOWw4ZIjPT0H88z2US9u4q8arckEdYIqlhbRWnqvdEDcVLJGPUqstVWYt4uUt+2hsVVz+J4h8JVHziqMv0uflE= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788434898938317.54317964169456; Thu, 3 Sep 2026 04:28:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aW-0005jP-ER; Thu, 03 Sep 2026 07:26:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aU-0005iQ-S4; Thu, 03 Sep 2026 07:26:34 -0400 Received: from mail-japaneastazlp170120005.outbound.protection.outlook.com ([2a01:111:f403:c405::5] helo=TYPPR03CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aT-0006k3-0S; Thu, 03 Sep 2026 07:26:34 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by OSNPR02MB8962.apcprd02.prod.outlook.com (2603:1096:604:45b::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:22 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:22 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=IOjBd69L7Sq8MA+n73sZDP7+YxrvTL0sP1Lgeat7UYbRx8Od1vv+H3rwsE9kMS0qGOyDJXhtEssJJS5pVX0lOPR6HQj7Y60iSIY5/J23Ll6hwPUamBV4QQiHJLXCqGcYOTvLO947fRkvhjvqKnXpt1dPzkX6oXgRaftXpXLi2l2AEmLkCnBt5gWzHbk+iN2gSdNyl+68TxHovsLFNLrh4D4kIgNmox6Obbve1Q9HjFEcKEPZbAlTcxoM9tPUQXNg1MHoDq3ysiygQjOHG7O9yp5XVCKAmR6NLuwUr7CSulNRywlt2DabBtT75V/r4zt+Hd9a3voWK0mE6N7I/p1+zQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RPEJQLUZkXmRM6XjN98FFMEdMGGjPzf37MKPgJnatgw=; b=w6DPKKZehlxbSYi/QO2ipdPR49yrODzcOIzDJnzfbHcdEtyqVJ3pItIlyg9xxRQv05maMGIItP5NUyNKpyicS6WSZfEVr+1j388WBnO5OIbmrs3uMztJX7oWQoKyHb4bHuP69VGrxZSwqdquq7A1m/3tsRDDpqS5e6V6QZa8fcVKKjosss/wFhfYDKosIjQFghO6NmKaBDKm2a5ISG7p3j3Bj3c5kip2RlZdHzCXooQbbpOCWrvLfpAfvf+5mC2FAIcDb4i6P97EjD+IkRrVovgahrqdmEZG4ecRHQ1Z/oS+NiBOuATGWpHNs/msnRSRA5GcH5WINo4/yAHFt550JA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RPEJQLUZkXmRM6XjN98FFMEdMGGjPzf37MKPgJnatgw=; b=BvsTkXJmv0huiNPxGQQhXQti2ro9RqzTgU7MmFIiBuH17r1g4NhC8wH21T1kbetkFf+pruTM6v6e0uldhCYpiB7wMDT8JI3UzCryntbxSrY4ZS7zmUeEJRqLOk9wpL8TQG65N9eY3bSBa+OCNUgAOiSviVv0fA6w0OOBn7WH+764/fgVnz8UeIaFwaeKMIyymYG0UfeZS5X/QdusW/6J2IYVkTubbcTae1K1fxdNMD7eK4gO7d017QGnSpF57aEm/noM0kCAhvptXLIkcPNgjLX/RCErCBvppV3yAThhApXXqsxiREtfCz+W4CfOeicGHJ6+OmrJykMDg2H7yUEEzQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 16/33] hw/arm: phytium: Integrate the Phytium E2000 PBR Date: Thu, 3 Sep 2026 19:24:56 +0800 Message-ID: <20260903112532.3276678-17-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|OSNPR02MB8962:EE_ X-MS-Office365-Filtering-Correlation-Id: 841da7b8-0038-4c8c-8e44-08df09ae2eb6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|23010399003|366016|10067099003|6133799003|22082099003|18002099003|56012099006; X-Microsoft-Antispam-Message-Info: HO8MPK+GazyZ8asE5r/DTJ44tHc0NHMHEH3wMulgv5pyOhJwHFf0sBg0Yn1A/Ettameh4T5NGuM/+BcXrTlsPTQ5LqGyD42ySokPQmYG4YgwFXLW4G46g3zwWHe6jo0SeUj6KFC9oAQ/d+stPZiTSXKoFLzl3UcLyHnBEnPsjKnUTrxnD/2crO4hbMzseWLZpAkCTIPdN3CZ/jKY27cpxebCG5Nt1VBfHAqQd9h8r56DXI4kqFLNl8qRXcbGgy/WtmvkgeX/Sztvvpjiw6ZSdLPbDzByCWmNo0me7UXYvX4pE8BVOhnC19Ni+T59o8+GeTTpDWjzfJZhrMoPiO/uVlZKZubFaHPrULLhfEhZqYqHfZ6f/rNWm/jge61K0iq7Y3R7FpMAimNiEZeH8nsLDnzCKiSogBwP7JaY3vt5StSQzu3kZSn69MwB84uuaQt6c0gT7+q8FjjkweK8/UcvEjSX85fuAdfVZ8hH9QKvj3uN3jFT3Xn+rKKRpzJyaZhg/WgVd1RNWzV3IxHQMNHI5F2yvR3Q8Dv+qqYCaksAiB9UQK+/HNsXIdeMwGpOkMVGYkGTOScOQlyrfFQDL9UO0t8+B/5R5SKcQmauTK+jIbu1zj7UNEKwvMDTgVvYoyu2w0ipmn+aUrf1CxwfPgt+CqlnswpX+mbGj/eqjgRVwes= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(23010399003)(366016)(10067099003)(6133799003)(22082099003)(18002099003)(56012099006); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?aPbhf+M3e0M4220ZkHUFRTakMjzmpcAdDGvezKBFmWQy2/vuPjddqv44rIxK?= =?us-ascii?Q?KFYkm5TANJ8fIEkozpUInBFXzDdN/QBoNPaoQfkr9iOhHz3fAxx3EPTWNTmr?= =?us-ascii?Q?qGkf74TFgz1Ay4GLAeHaLmMSSrae/ACeFnnVZtaEXwZF/YiGzwG8g7BdSKlg?= =?us-ascii?Q?BtUr0h/npyfJFgT/ZvrjzeaWhE0F9JgQ8tfrTtVXrHz3+vSSSDkWD7Lb/y/G?= =?us-ascii?Q?JIcSF1pWnnAdedJRIGd/8fGJ6bmVfqNhLl6xoCZHVskRj950lAMORvKLhnwF?= =?us-ascii?Q?1DYgnR3b8xHhOOrlAUpx1KnJt+beLicqMUN3brqs68qhbpSS3PAv7fKY/p0S?= =?us-ascii?Q?R3GEAWO0C71lNCHcOEFh+u2rxN1dyavYRavHAeW/rqOKroKy/T1TwmRX5xvO?= =?us-ascii?Q?kLCJSBuVHz1dHVd08nGa/glQciIVXF7urj4Wr6n6KO26Bz22aKDelSV2sx7Q?= =?us-ascii?Q?VIrfh+dsDXwg//k3FiunZVVAzSyoPSpYqlvYNJ3GFslrN0y13PjWNboK10a/?= =?us-ascii?Q?SlzT4rnlAp2qbS+V+vzd8idNbwbhgC7FfnwD68z1segyDiGbpNSh78mnZDGU?= =?us-ascii?Q?tCskvdUZkQ80bzfWXDDqSaKpnEyG1UBfXZloEAYMoI06xD8sbyjv1pouzRBj?= =?us-ascii?Q?UkilfBulZksRhu7BajxjNsvZIPCOTUHFT5smD6we7if1GWaIQ2OW9tMiCa/M?= =?us-ascii?Q?Vhgg+5j4Ully2rkDJm7WGG4VZ1eMX6myA3XDWcBttojWsqysilpZzk1U5hHK?= =?us-ascii?Q?XtGKuYj0xkKGv4yDCB5KesM6Ex8ismJuWC9c1nCH54STyTpiV0L3XUhAoHu+?= =?us-ascii?Q?ulGLomuEOL2T+Y3Yrszs42+Hz9LXgHLBJAesOTXcCoL5LabO9Ir5ubgmhYQP?= =?us-ascii?Q?70WQMh2bwl+Xb/xfTAtYLvqOADH24dvKex23YBpT1MqGnC46jIR0XuUfsWGM?= =?us-ascii?Q?siCJmIc8pt3pcD7t0CU0ZpkCsK91pwaj6rfe91dIy3wn5m4avlBRRjRxGPEB?= =?us-ascii?Q?frtLbpICTVGP8nBRGFLgNO1VAsP+4yM/7cBY7z2NLCTO1/HNSnbWAJEVYU9R?= =?us-ascii?Q?y0OOohGbd72/ksY6z1Nx6XvlN5fUgO03CgHR0jvlTHAemTAi7nH6XqyeC+6p?= =?us-ascii?Q?YdRV4/372fSU0OJXXb0wlXAO5zcZbgR22jq3iwQIR0yFdnAN1XEv5yDFPhNw?= =?us-ascii?Q?MoDzL/mAY2Ye0z6OTLdTbPMgrXgDL2CHN1w7HmPIyBmy72p633KCYQqOYSbt?= =?us-ascii?Q?DmEQtiG92jiIjAL0He3m9hNgitwLDSnzqz5Q5s+hH07dsqQqL1UxZVEA3VVG?= =?us-ascii?Q?lL5Ld8ImYtZCzF0OW44gvCki1PwLSVLRdwjUC18STXDFYlLEin8IZkD/Q6i1?= =?us-ascii?Q?ZS1vsdydbgcmYKFndsf9QGePfB+IMfBsGjBzY0BN3vZS5b6x7QkArKOcxJek?= =?us-ascii?Q?G1yPNiY5FH5BIaBLW1kZuKi+0N3D10d8FguZ0WliEaL8RDYj3G8xaBkCj3eQ?= =?us-ascii?Q?Ydjj+WK0MmZhtUNTPBKolw+2X3AhClcHG2ksPczoMH/DpY+D01jfChaK5oud?= =?us-ascii?Q?nlxjO1907lA5/AVszFTDACOYI8QUSfiJ2n8BO1V0iCU040DuPG6kcPsxFvoX?= =?us-ascii?Q?PVTFW0hvGwQc32DdFqL/s/90oWk6FvYjdPrtQ7AjqbjEbclI19B3yEQIR4Zf?= =?us-ascii?Q?d0GcWyplMAbW5azlRgzLZ+eo3lRcd63tBaOSx5Me/dqO448yp1X9MeeR2z/e?= =?us-ascii?Q?syUsEZ2JqMULWkzAXCktOE4f1/sbjSU=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: 841da7b8-0038-4c8c-8e44-08df09ae2eb6 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:22.4120 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: PdBaiuOoXK/yRlB87c/3Xbrn0jHDF9ADwAXgAJSgY4PlHqxDsGfp+zMMHMJbXioCXTeYPDZmKDMt0Ou+IuQHsWEReJATO8IXxIFhdEi8GIA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: OSNPR02MB8962 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c405::5; envelope-from=bin.meng@processmission.com; helo=TYPPR03CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, RCVD_IN_DNSWL_NONE=-0.0001, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788434900560158500 Content-Type: text/plain; charset="utf-8" Instantiate PBR in the Phytium Pi machine, map its status and boot memories, provide the heterogeneous MPIDR topology, and connect all CPU objects for reset-time handoff. Use SD0 as the board firmware backend. Explicitly reject the unsupported -bios and pflash interfaces. Signed-off-by: Bin Meng --- hw/arm/phytium_e2000.c | 97 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index c6d789bb04..e74a0328fe 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -13,6 +13,7 @@ #include "qemu/error-report.h" #include "qemu/units.h" #include "qapi/error.h" +#include "exec/cpu-common.h" #include "system/address-spaces.h" #include "system/kvm.h" #include "system/system.h" @@ -20,6 +21,7 @@ #include "hw/arm/boot.h" #include "hw/arm/bsa.h" #include "hw/arm/machines-qom.h" +#include "hw/block/flash.h" #include "hw/char/pl011.h" #include "hw/core/boards.h" #include "hw/core/qdev-properties.h" @@ -27,6 +29,7 @@ #include "hw/intc/arm_gicv3_its_common.h" #include "hw/misc/phytium_e2000_ddr.h" #include "hw/misc/phytium_e2000_mhu.h" +#include "hw/misc/phytium_e2000_pbr.h" #include "hw/misc/unimp.h" #include "hw/net/cadence_gem.h" #include "hw/pci/pci.h" @@ -96,8 +99,10 @@ struct PhytiumE2000State { struct arm_boot_info bootinfo; DeviceState *gic; DeviceState *qspi; + PhytiumE2000PBRState *pbr; PhytiumE2000MciState *mci[PHYTIUM_E2000_NUM_MCIS]; CadenceGEMState *gem[PHYTIUM_E2000_NUM_GEMS]; + CPUState *cpu[PHYTIUM_E2000_NUM_CPUS]; MemoryRegion scp_sram; MemoryRegion ram_low; MemoryRegion ram_high; @@ -208,6 +213,17 @@ phytium_e2000_cpu_config[PHYTIUM_E2000_NUM_CPUS] =3D { }, }; =20 +static uint64_t phytium_e2000_cpu_mp_affinity(unsigned int cpu) +{ + /* + * E2000Q exposes one core in each of the first two clusters and two c= ores + * in the third cluster. Firmware stores these MPIDRs in its parameter + * tables, so a linear CPU index is not a valid affinity value. + */ + g_assert(cpu < ARRAY_SIZE(phytium_e2000_cpu_config)); + return phytium_e2000_cpu_config[cpu].mp_affinity; +} + static void phytium_e2000_create_its(PhytiumE2000State *s) { DeviceState *dev =3D qdev_new(its_class_name()); @@ -410,6 +426,15 @@ static void phytium_e2000_create_pcie(PhytiumE2000Stat= e *s) } } =20 +static void phytium_e2000_reject_legacy_firmware(MachineState *ms) +{ + if (ms->firmware || drive_get(IF_PFLASH, 0, 0)) { + error_report("phytium-pi: -bios and pflash firmware are not " + "supported; use an if=3Dsd,index=3D0 image"); + exit(1); + } +} + static BlockBackend *phytium_e2000_sd_blk(int index) { DriveInfo *dinfo =3D drive_get(IF_SD, 0, index); @@ -471,6 +496,47 @@ static void phytium_e2000_create_qspi(PhytiumE2000Stat= e *s) phytium_e2000_memmap[PHYTIUM_E2000_QSPI_DIRECT].base, 2); } =20 +static bool phytium_e2000_create_pbr(PhytiumE2000State *s) +{ + MachineState *ms =3D MACHINE(s); + DeviceState *dev =3D qdev_new(TYPE_PHYTIUM_E2000_PBR); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + BlockBackend *boot_blk =3D NULL; + uint64_t cpu_mpidrs[PHYTIUM_E2000_NUM_CPUS]; + int i; + + if (!ms->kernel_filename) { + boot_blk =3D phytium_e2000_sd_blk(0); + } + + for (i =3D 0; i < ms->smp.cpus; i++) { + cpu_mpidrs[i] =3D phytium_e2000_cpu_mp_affinity(i); + } + + qdev_prop_set_string(dev, "boot-mode", + PHYTIUM_E2000_PBR_BOOT_MODE_SD0); + phytium_e2000_pbr_configure(PHYTIUM_E2000_PBR(dev), boot_blk, + phytium_e2000_memmap[ + PHYTIUM_E2000_RAM].base, + ms->ram_size, cpu_mpidrs, ms->smp.cpus); + + /* + * PBR owns the status snapshot and both boot memories. The status blo= ck + * overlaps the broad board-control placeholder and therefore needs the + * higher mapping priority used by the previous status-only device. + */ + object_property_add_child(OBJECT(s), "pbr", OBJECT(dev)); + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map_overlap(sbd, 0, PHYTIUM_E2000_PBR_STATUS_BASE, 2); + sysbus_mmio_map(sbd, 1, + phytium_e2000_memmap[PHYTIUM_E2000_BOOT_SRAM].base); + sysbus_mmio_map(sbd, 2, + phytium_e2000_memmap[PHYTIUM_E2000_BOOT_IACC].base); + s->pbr =3D PHYTIUM_E2000_PBR(dev); + + return phytium_e2000_pbr_firmware_loaded(s->pbr); +} + static void phytium_e2000_create_ddr_status(PhytiumE2000State *s) { DeviceState *dev =3D qdev_new(TYPE_PHYTIUM_E2000_DDR); @@ -570,7 +636,8 @@ static void phytium_e2000_create_ram(PhytiumE2000State = *s) phytium_e2000_memmap[PHYTIUM_E2000_RAM_HIGH].base, &s->ram_high); } =20 -static void phytium_e2000_create_cpus(PhytiumE2000State *s) +static void phytium_e2000_create_cpus(PhytiumE2000State *s, + bool firmware_loaded) { MachineState *ms =3D MACHINE(s); const CPUArchIdList *possible_cpus; @@ -587,18 +654,30 @@ static void phytium_e2000_create_cpus(PhytiumE2000Sta= te *s) &error_abort); object_property_set_int(cpuobj, "cntfrq", PHYTIUM_E2000_GTIMER_HZ, &error_abort); - if (object_property_find(cpuobj, "has_el3")) { + if (!firmware_loaded && object_property_find(cpuobj, "has_el3")) { /* * The generic-loader U-Boot path starts after the EL3 firmware * stages that normally provide the Phytium SMC services. */ object_property_set_bool(cpuobj, "has_el3", false, &error_abor= t); } + /* + * PBR releases only the primary MPIDR named in the firmware param= eter + * header. Secondary CPUs remain powered off for later firmware or + * PSCI bring-up. + */ + if (firmware_loaded && + i !=3D phytium_e2000_pbr_primary_cpu(s->pbr)) { + object_property_set_bool(cpuobj, "start-powered-off", true, + &error_abort); + } object_property_set_link(cpuobj, "memory", OBJECT(get_system_memor= y()), &error_abort); cs =3D CPU(cpuobj); cs->cpu_index =3D i; qdev_realize(DEVICE(cpuobj), NULL, &error_fatal); + s->cpu[i] =3D cs; + phytium_e2000_pbr_connect_cpu(s->pbr, i, cs); object_unref(cpuobj); } } @@ -606,6 +685,7 @@ static void phytium_e2000_create_cpus(PhytiumE2000State= *s) static void phytium_pi_init(MachineState *ms) { PhytiumE2000State *s =3D PHYTIUM_PI(ms); + bool firmware_loaded; int i; =20 if (kvm_enabled()) { @@ -626,12 +706,15 @@ static void phytium_pi_init(MachineState *ms) exit(1); } =20 + phytium_e2000_reject_legacy_firmware(ms); + phytium_e2000_create_ram(s); phytium_e2000_create_unimplemented(); =20 phytium_e2000_create_qspi(s); + firmware_loaded =3D phytium_e2000_create_pbr(s); =20 - phytium_e2000_create_cpus(s); + phytium_e2000_create_cpus(s, firmware_loaded); phytium_e2000_create_gic(s); =20 phytium_e2000_create_scp_sram(s); @@ -654,7 +737,7 @@ static void phytium_pi_init(MachineState *ms) s->bootinfo.board_id =3D -1; s->bootinfo.loader_start =3D phytium_e2000_memmap[PHYTIUM_E2000_RAM].b= ase; s->bootinfo.psci_conduit =3D QEMU_PSCI_CONDUIT_SMC; - s->bootinfo.firmware_loaded =3D false; + s->bootinfo.firmware_loaded =3D firmware_loaded; arm_load_kernel(ARM_CPU(first_cpu), ms, &s->bootinfo); } =20 @@ -701,7 +784,11 @@ static void phytium_pi_class_init(ObjectClass *oc, con= st void *data) mc->valid_cpu_types =3D valid_cpu_types; mc->max_cpus =3D PHYTIUM_E2000_NUM_CPUS; mc->default_cpus =3D PHYTIUM_E2000_NUM_CPUS; - mc->default_ram_size =3D 1 * GiB; + /* + * PBF/BL1 relocates to 0xf8c40000, which is outside a 1 GiB RAM window + * starting at 0x80000000. Two GiB is the minimum useful firmware defa= ult. + */ + mc->default_ram_size =3D 2 * GiB; mc->default_ram_id =3D "phytium-e2000.ram"; mc->minimum_page_bits =3D 12; mc->block_default_type =3D IF_SD; --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788435111; cv=pass; d=zohomail.com; s=zohoarc; b=LP7qwou8f9qN7p/hsRYpWYEguI4YOIVmDMZh7IrTXjo1EKdlnr2dVzVe3h5maOtLrMzuBFwlmVAavQfj+kHKJYDEpIfnDp00XacT5aaDB7XMEwJmLpvUEZMkdF2LwG22lSvm3rgfhIW7lhhiX9gzCjnhu2q/evfrYVGAyMFmDes= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788435111; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tAdeO6cyG+fZluVgD6dq74RzbIpYaW0QwEnXFwHeM2I=; b=hpRU9OtEewgDvTF0xKm3e1OpF15rl0kLckhIVRYFm6jts68wRljh2hS2IVe3Czs5BLxPQ1JGHDcm3WMBInvg6brsC+j6Z3GhK8ssfbedxzEtYapfdEF/WXeShP9t2DoTXJNlShUGwl8dnC3H1CFH1B5tiZ+Mg2fnJZpOSWzsAHg= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788435111229843.3181123831255; Thu, 3 Sep 2026 04:31:51 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25aZ-0005lO-1G; Thu, 03 Sep 2026 07:26:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aX-0005kA-93; Thu, 03 Sep 2026 07:26:37 -0400 Received: from mail-japaneastazlp170120005.outbound.protection.outlook.com ([2a01:111:f403:c405::5] helo=TYPPR03CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aV-0006k3-Kw; Thu, 03 Sep 2026 07:26:37 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by OSNPR02MB8962.apcprd02.prod.outlook.com (2603:1096:604:45b::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:24 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:24 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=EFw0etWZ/aAh/B1SBv29XGzGv6/XRsHfPQajb+n3DsTHUqlUPasm+SZ6UFn1rlNi7UkKx83DqdjSl8TmKZYEiItni4Eu55bs7wZ/fXp+ePzy7j4Bx1e4wwP8OO7O7TLnNnrHRiF0TeCbhHm86O+ZKd1CbtZS9ljYjkdwX6nbCFf/y5M3vy70OXqfh5BJMu5zByNFb72EC+D9BItBVQ/6zOgLHBV98tT3qrCb/K9VQHHme2yg0KBn0RZBuWRmV7DHoMxwafJAcV8ZRCwlXhQttmXyhhJAMr18kFQYvqiGRDzVom3jFIWysObf48fQJeQz9TmqmihqsYBBHFjYv7cq/w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=tAdeO6cyG+fZluVgD6dq74RzbIpYaW0QwEnXFwHeM2I=; b=zBDdlfVBJR7tSzTL60O074eyONWYEcO896PEPZUnjUBOS8hUdqkjOSbM6H+XePw+3Vm3Y/i5VK8aDo1l/i0CdlM6/UIfKjLu+wIleNJt0QaclTmEWrs/Af2cERR/vY1gsnRXc9JWlmvgzGWVmgLLoJptg34z66LoxNCkawVmFzZ4XqLmnjF2B0RGDtUOXVzIQAdTXw/T8ohhWCaL8lFz5pnGRFDHD+GGuIFVLZ/MvR/+Wuyr1rQKnr9Oh4LveaotPm4oGtMyrLK9o0Uqocs+bYe6IGSPhgXULE6vzSfWPKYFH35kT0t3rCAYdTyYyJRcaZ0PkxiKGwQhp5DmZkCh/g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tAdeO6cyG+fZluVgD6dq74RzbIpYaW0QwEnXFwHeM2I=; b=X2qbQq/1+qI7+witujTbslyPmhZsXVvF7Lguzk1ZKBtNonzBaQqMvwSPcL41S+iMICNVaygET4rw+LSJpX9DGNrczp3tuATfh9/L9fzh6GS1JPniFr/ezId7jGoHZigF1gArKBFhP9sMzl3WLGV/yf8u4g3TzmKjoDEDhv/mBhnoiUGcUrPpvWJ69EsgJ/LWigmPpk+6VDvJtWQRIV+iNt7Jj2Az4rsVfQrpCWvh8/of9cxVZ4c9ioe03TMWB1MNkHS0kcwixY95hu6sndNRpQRuhTjy3ejpV0rJx8M1xFOuzEmLhI9igwdbL1ddFDbe7I63FGChjsPkswgsC5Vpzw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 17/33] hw/arm: phytium: Add Phytium E2000 control region placeholders Date: Thu, 3 Sep 2026 19:24:57 +0800 Message-ID: <20260903112532.3276678-18-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|OSNPR02MB8962:EE_ X-MS-Office365-Filtering-Correlation-Id: a18db33f-ebf6-46af-f94f-08df09ae2fd0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|23010399003|366016|10067099003|6133799003|3023799007|22082099003|18002099003|56012099006; X-Microsoft-Antispam-Message-Info: bhIzFu2ETmVgT9sk1HKNaIkpPSKrMD9aPuOvI9pvIVOHvAlVxhhHKplUBvnG/iBgXyCmnN2jewOxO1vyRWbjjmhediR4DzJPEapQ//XqTyuts6VwOIKFuXaJ2WVeftWmMq2/aE4XKsc6CcNo5g3N+Xky8gbDz5ma/ykwGREYAcHiVW1g4bY/PXjacP833cF3s8uFYV8vBR7iXciHrFeG6b/SUqR2F/jfLLwBgrqSze3qerPkuUb1aMrp+A2o5Unyo8CIB86FBl874zWYzeqWdPp6k44liaRyuGmmfbCf0vV2gqMO5ICMQ54Nr7K/H0CYR3fVSCvrXYafBU8iO1WdB09bezGAOjjsVlIKUHQHjc0d5LDOFXGYsvjWLoGcpLw1+XAuqrqwf5iCIETTiPjREzw7fWf3hGasoBXD2YiRfK25I2XdqUKhMT27bC5VEMZRYnzAJ4j1483nfYhNy9nW4dYVot6ERSKkYoq7jJQJseaaQwl0K1stg0HLYwRYlpEa4jJEMh3pMBWKvPnhNdcBgwYvSUWhca0tGIQhw2ZRUhZ9BZCl2mUZV13ulJkvq07IV/aETYW/Tc6nfT2u5KzmWavBLwfMpmaCQJQ7If+3YvSY3HV62Cdh44oOLNmvOgrw+CISN0ZKxNChX3dkQ15JiFLLk/ZE3kXdkC6b2wjhAK4= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(23010399003)(366016)(10067099003)(6133799003)(3023799007)(22082099003)(18002099003)(56012099006); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Yi1Q2NbDdTRgOp1ZybhQZUNKz3SwgANG2j0nPBkvdqaisW7rO6DbuhgCbdi1?= =?us-ascii?Q?n2/yS7Mecc6t/b0/8sJr2ieVaxKLlTsZNPY3HXxzPfi1SKiZCRwPJWDpO3jI?= =?us-ascii?Q?qD2d4ObrVn1yIeLDxkfRNovCIC3/Zdq5h8N8fpOMq/2t+GOH+fhB6Kt5EI+T?= =?us-ascii?Q?1CDcRNhvjhUERChtWhJIBbQep7hqSD7mNUAOSW915goToo/y0/+UTgbsIp+E?= =?us-ascii?Q?XB54HFN26GHKODJNYhH6naHu40+nHqMLIBK0QQdqVT5Kc31LLhaggcjmZ5D7?= =?us-ascii?Q?lPFomsjhy9Xf7UB1hmBs4mX+1SfLeavzoDqqHVMhLY/NqljQDAwrhfuIwMsR?= =?us-ascii?Q?b5x5gyN4Fck7DHVHzLONvD34WZS+aUNrlxcHcYFkDM0OPbqCAT4Tb/or8mNw?= =?us-ascii?Q?SgVB3dmGBqFRv2iOtGUxDTnoJCJcaF0vlcUtVrcNf8oAOedvgW3FLroEjRkC?= =?us-ascii?Q?9PWVBpKxEpStyUe05C6QMW0I5Vjt1CwvQB+Hn6cD6lxlGK+lXdIey2IQEVka?= =?us-ascii?Q?LGZd96Xw6y0NAgP6IkfqGHUf+e08aJKjQWroeyusB8KqjrwnATTC3ObaKDzx?= =?us-ascii?Q?/3dfcpWgG3qqVP5QhjUS+CWue7XS5uq4PLT+XnN23PHk1cDCVdnL0my+KL0J?= =?us-ascii?Q?GeZ2NBXZFoTMlfiieETh7AvvtwSMy+xN+FcHETXmz42Ir24xWRDJ/Z1VLhmW?= =?us-ascii?Q?Fm/WSpefICAUZ1RzTGfiHhPNGndDbei6td4Y/qgR70CQj+4Bpz2vvcQFNXJp?= =?us-ascii?Q?bKjU1GY7pJkLyIjLRszMh3l7cg/huaKm2eVvWRBVUDJuosoILm8dfI7tcBL1?= =?us-ascii?Q?Vxyb9ueusNS2EfKRCUptV1PsBJG5RK5pvwo5QKhnn6KdhKy7etkowJvBKQvm?= =?us-ascii?Q?X/Gc3TfVx3Q8l2aXaxlOI+t2wtqRqmJGxQTAG84YEECbpiGts5o0kd/VeQXm?= =?us-ascii?Q?+75fw6Y8eVyt1ZB2LW9wSOuzujbmBt+N6i/15a1B8tDUf1Sl1BJChYEWNHFb?= =?us-ascii?Q?YMZFxKNkLYM5UPbD0HC7UhX85pvcpbk7Y0GMrY1Ogttq0BQ33dIJRGNeqfhZ?= =?us-ascii?Q?9PVNRrM3urK6pvejryf+rpsK/baICObNMImOh05zYbWJSeQRXO+429t2sNvP?= =?us-ascii?Q?gP67K6uS7FmgMnJDsKip8CsRw8fNgE3Edd4bn9BcvYVyWQgc6xJnL6wmUP4q?= =?us-ascii?Q?KpafRKtVcq6a9zZEf1KlhzwYJfvro7dV+5g9crCImI3cLwdfbLmpBq5e34jT?= =?us-ascii?Q?vIOJPoQBC6pKRso3RcbOYAF4D7wpg8S/61J1Wqs1PDqKR1oJmmVIjboYj0AG?= =?us-ascii?Q?Gk/0v1zFlWFaXt4oEZOw1L1ahJrlG3kSGAliXikg0PdYFgfSvsimDRW27ig2?= =?us-ascii?Q?GR1LTXz39acEYaUh7docsztjvCHvD6oPpGLxErhY9uMDrg8wp2BOEDqzbhJE?= =?us-ascii?Q?aOM8Kpr7EBYDpNrzQGmS8KFBWRUqf1qb/6UbYi26Se9Qc3u/ZYg+tR8+lwpj?= =?us-ascii?Q?id8mF/Ga2C4p+Ll85pdnAQ6dPFnfzSS/KkC9jC+Vl9Ck7DXm26+MrlULUY2O?= =?us-ascii?Q?3OH9fsfF6lOdKi3AxmaVS1LuW2c7yLcaFlhChsJzbV5m2uoxikfzJw8HX3r8?= =?us-ascii?Q?klMhdu2zs/QxOkWJ4flhrQCnyauwnrZcYk9RzrBIE86MQ/LhGVduQ0bqjWs1?= =?us-ascii?Q?vpoU+/KU6TkZomRYo1W5rtrFfwtj9/ySz3Vm/J9VliqfEepxQY2N/46IbP5d?= =?us-ascii?Q?tVzjXeYXx5HAWAkADhhaxyOR3DboeA0=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: a18db33f-ebf6-46af-f94f-08df09ae2fd0 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:24.2423 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9FYrxZL4HrIRnuOMJW8EESCCBxseQlH/oBIkRBnmc2eVgqgEXvhy6960aG4niDXPp7vO9AfWMymGGVVfE7OR7S4CeDssynchmCrPay7W6NE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: OSNPR02MB8962 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c405::5; envelope-from=bin.meng@processmission.com; helo=TYPPR03CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, RCVD_IN_DNSWL_NONE=-0.0001, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788435111935158500 Content-Type: text/plain; charset="utf-8" The vendor PBF accesses clock, reset, platform, security, and chip control windows while bringing up the SoC. Expose these windows as low-priority unimplemented regions. This keeps the firmware-visible address map observable and allows later device models to overlap individual windows without inventing register semantics. Signed-off-by: Bin Meng --- hw/arm/phytium_e2000.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index e74a0328fe..1c337bf36e 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -74,6 +74,8 @@ enum { PHYTIUM_E2000_UART4, PHYTIUM_E2000_UART5, PHYTIUM_E2000_UART6, + PHYTIUM_E2000_CLK_CTRL, + PHYTIUM_E2000_SYSTEM_CTRL, PHYTIUM_E2000_GIC_DIST, PHYTIUM_E2000_GIC_ITS, PHYTIUM_E2000_GIC_REDIST, @@ -85,6 +87,9 @@ enum { PHYTIUM_E2000_GEM1, PHYTIUM_E2000_GEM2, PHYTIUM_E2000_GEM3, + PHYTIUM_E2000_PLATFORM_CTRL, + PHYTIUM_E2000_SECURITY_CTRL, + PHYTIUM_E2000_CHIP_CTRL, PHYTIUM_E2000_BOOT_IACC, PHYTIUM_E2000_PCIE_ECAM, PHYTIUM_E2000_PCIE_PIO, @@ -126,6 +131,8 @@ static const MemMapEntry phytium_e2000_memmap[] =3D { [PHYTIUM_E2000_UART4] =3D { 0x28014000, 0x00001000 }, [PHYTIUM_E2000_UART5] =3D { 0x2802a000, 0x00001000 }, [PHYTIUM_E2000_UART6] =3D { 0x28032000, 0x00001000 }, + [PHYTIUM_E2000_CLK_CTRL] =3D { 0x28100000, 0x00001000 }, + [PHYTIUM_E2000_SYSTEM_CTRL] =3D { 0x30000000, 0x00001000 }, [PHYTIUM_E2000_GIC_DIST] =3D { 0x30800000, 0x00020000 }, [PHYTIUM_E2000_GIC_ITS] =3D { 0x30820000, 0x00020000 }, [PHYTIUM_E2000_GIC_REDIST] =3D { 0x30880000, 0x00080000 }, @@ -137,6 +144,9 @@ static const MemMapEntry phytium_e2000_memmap[] =3D { [PHYTIUM_E2000_GEM1] =3D { 0x3200e000, 0x00002000 }, [PHYTIUM_E2000_GEM2] =3D { 0x32010000, 0x00002000 }, [PHYTIUM_E2000_GEM3] =3D { 0x32012000, 0x00002000 }, + [PHYTIUM_E2000_PLATFORM_CTRL] =3D { 0x32e40000, 0x00010000 }, + [PHYTIUM_E2000_SECURITY_CTRL] =3D { 0x32f00000, 0x00001000 }, + [PHYTIUM_E2000_CHIP_CTRL] =3D { 0x33000000, 0x00010000 }, [PHYTIUM_E2000_BOOT_IACC] =3D { 0x38000000, 0x08000000 }, [PHYTIUM_E2000_PCIE_ECAM] =3D { 0x40000000, 0x10000000 }, [PHYTIUM_E2000_PCIE_PIO] =3D { 0x50000000, 0x00f00000 }, @@ -590,6 +600,19 @@ static void phytium_e2000_create_unimplemented(void) "phytium-e2000.low-peripheral", phytium_e2000_memmap[PHYTIUM_E2000_LOW_PERIPH].base, phytium_e2000_memmap[PHYTIUM_E2000_LOW_PERIPH].size); + /* + * PBF writes clock and reset controls as part of physical SoC bring-u= p. + * QEMU derives virtual clocks and reset state elsewhere, so retaining + * placeholder visibility is sufficient for these write-only setup pat= hs. + */ + create_unimplemented_device( + "phytium-e2000.clock-control", + phytium_e2000_memmap[PHYTIUM_E2000_CLK_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_CLK_CTRL].size); + create_unimplemented_device( + "phytium-e2000.system-control", + phytium_e2000_memmap[PHYTIUM_E2000_SYSTEM_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_SYSTEM_CTRL].size); /* * PBF programs SoC-specific PCIe PHY and port controls before U-Boot * enumerates ECAM. Their values do not affect the generic host bridge= , so @@ -607,6 +630,18 @@ static void phytium_e2000_create_unimplemented(void) "phytium-e2000.board-control", phytium_e2000_memmap[PHYTIUM_E2000_BOARD_CTRL].base, phytium_e2000_memmap[PHYTIUM_E2000_BOARD_CTRL].size); + create_unimplemented_device( + "phytium-e2000.platform-control", + phytium_e2000_memmap[PHYTIUM_E2000_PLATFORM_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_PLATFORM_CTRL].size); + create_unimplemented_device( + "phytium-e2000.security-control", + phytium_e2000_memmap[PHYTIUM_E2000_SECURITY_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_SECURITY_CTRL].size); + create_unimplemented_device( + "phytium-e2000.chip-control", + phytium_e2000_memmap[PHYTIUM_E2000_CHIP_CTRL].base, + phytium_e2000_memmap[PHYTIUM_E2000_CHIP_CTRL].size); } =20 static void phytium_e2000_create_ram(PhytiumE2000State *s) --=20 2.53.0 From nobody Sat Sep 26 22:15:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass(p=quarantine dis=none) header.from=processmission.com ARC-Seal: i=2; a=rsa-sha256; t=1788435099; cv=pass; d=zohomail.com; s=zohoarc; b=Nfj3CLdpg0pX9P/iw5ayB+Yx3F2vC8N4B8ifFlDOfFWvzd7rtiTn9znivJxVut77rkaI7JBW9CRUX7xsovsFvaf0Ta7gNj79NlZ2Y9djfvvUYJ3eR7bKHVOhB5+eY1YO+OdgVVHDSjRpIUMDuMaqvafPKjawZHOdsi8ybQwwpAo= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788435099; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zr4sDc9HQtGN490MyRJD0wVLolNAS22aNGVYL5ym03s=; b=VkEqawziApqdW4eil3fdO5bz0j5Rf/VG3Tq6gzUPvGZTcgC2UkjvPRFKMsS64PvQsmrh3gvAqWvduiY0uPQf4gDv1I4I6FaV8fdbsbdKz+GidevsXY5ucxf8KtsHo9A/Tc0TBca3+gaydwRkHEtbCUR9aZpkPAtiMzbZBioTy8I= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=processmission.com); dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788435099515306.15205852670056; Thu, 3 Sep 2026 04:31:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x25ad-0005nb-G7; Thu, 03 Sep 2026 07:26:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25ab-0005m3-Os; Thu, 03 Sep 2026 07:26:41 -0400 Received: from mail-japaneastazlp170120005.outbound.protection.outlook.com ([2a01:111:f403:c405::5] helo=TYPPR03CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x25aX-0006ne-W4; Thu, 03 Sep 2026 07:26:41 -0400 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) by OSNPR02MB8962.apcprd02.prod.outlook.com (2603:1096:604:45b::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Thu, 3 Sep 2026 11:26:26 +0000 Received: from KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03]) by KL1PR02MB4977.apcprd02.prod.outlook.com ([fe80::9fdf:2557:8351:6c03%4]) with mapi id 15.21.0382.007; Thu, 3 Sep 2026 11:26:26 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ta0zpHT0M5VXJVrIMDLhIEmrrfBnFRgPNSe4VPzz14z8Ol5ktbClasmUSW0rQmqlNdKMAKgB1wQOR5x0jAix5qebZu+KKHC0JVCSGbF+gv+r/yOqpYvKGkZmoj8nPFHOAlixvo3YcXusmvZ8wxMjRFkfJiM0ekuau/OCFi6OmD3N3JYKWpXNB+xW685H4FWZQzjnibZxb+XWGBamr0PSr+XK8GaPVY/NNPPo54OMbfJ4MT49biL1qaDvzHp65uQj+PoCsMX9IZxtSO7f6IpYpqjlKHS3uH3P/SxVljZmEkRYJwBj72b888PgAbQVEPqqrSYn2zSDtCdeiVBuMHt8cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=zr4sDc9HQtGN490MyRJD0wVLolNAS22aNGVYL5ym03s=; b=e4pi20n1Q6oq8UZJr0/ffgiSyZrDVrr9A81FRQMlzH3Jw1hixNbChrP3+nyVVV+Gtw6IEIq6Q3jdD/GFLn3kRG35t25wYKV0Fp7Vnv+EGHE64gDxQMtJHtuwhMNsidD5ep/j169dcOdvjnlzqlOBTe9EmlFmE5DECD5LBTOsHFIGi0qRjQVCShMWS+u2NM7Eaz34sqenYQXCamunTe0aDEIVTjSag2OsnI1PIHF0k+8GLcOl/kOnZspMaiilUT9JwZZwy6xMz0/hC7eKjw/V82RS3zww5i/P+rVfS2zSrc8uX7HPbIkHH4nYSUBYM0SQrknCtNBuGxQFz+k76g4/2A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=processmission.com; dmarc=pass action=none header.from=processmission.com; dkim=pass header.d=processmission.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=processmission.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zr4sDc9HQtGN490MyRJD0wVLolNAS22aNGVYL5ym03s=; b=cDuvqd8FhGMIBJ9+nj8LA2/jSlvSpa83uRf+rx0CWG4jCZwcdnz6jTVDIQaSx8gQZ0uT6/xIDmqN6kIye99hjlKBuln7+8/sp6tIey3J2V/Tv0UXRyVR1YguUDHDy+W5CWweRn8ZFaKJtamqD0jXIT384WhGFzdtpoWt8q9xa4ra6okg3Z9Gl4+XS1ay7LK1/xpbZ69qvKRklxrjo9cUnz2kb6isJ684JvIeG8H0pd76gVWzHwEKU1EOwVByWIVseJXaVajqRIV68pGCA4cePVv2mtWWIQ1AthLBV1BjiRf2BJltq43ly/eek5Qy2J/RmzZggJS2UHVikXggkbteEw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=processmission.com; From: Bin Meng To: QEMU Cc: Peter Maydell , qemu-arm@nongnu.org Subject: [PATCH 18/33] hw/misc: Support Phytium E2000 SCMI CPU power control Date: Thu, 3 Sep 2026 19:24:58 +0800 Message-ID: <20260903112532.3276678-19-bin.meng@processmission.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com> References: <20260903112532.3276678-1-bin.meng@processmission.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TY4P286CA0026.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b0::11) To KL1PR02MB4977.apcprd02.prod.outlook.com (2603:1096:820:71::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR02MB4977:EE_|OSNPR02MB8962:EE_ X-MS-Office365-Filtering-Correlation-Id: b07ddf30-7f83-4cf6-9b53-08df09ae30e2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|23010399003|366016|10067099003|5023799004|6133799003|3023799007|22082099003|18002099003|56012099006; X-Microsoft-Antispam-Message-Info: +tafWmtdlL4y5tOS9hR8RmzX9afwPm1pmxxG+jy0A0Biblsl0E9HQyWaIBVpHGKrehK76IqUkbK5CzRMDU3RqJgZnM8fZLpTLfc/NWig7ubFrFErE42SPWJUBJnAnM2WXE6KTYAdsrWhnUaLVKElnZ/5l8jzrVNCjyyIPkrk8L3UMGLN7FTJ8xrd6Dy482nsyL0EAGKG12lIE/iWWY0LejCyTs0jProe3r9RW2np1nGzbZpxyuNKinX3Vd8iIAb+o1p4mA02yR/Hm9wZewq6QqCROkh7Q+StMcDvtufYbc0DThIVGlf8PDzrQqmItzbxu+6Vs+ZnRmjilOekJ78VJJaljjVp66qsY8eZ2iNn22U6ROF8/xQzSo8S1I5ijoICMktRTP775z4C3s/IxfBxvjNw21EMk3/dXXAjyMHP90TAVWnPzAzZYnQUfLwCuMYFIIcpY3dHhIOOjsJHkIBZFwvdHnlfgrRs7Ka02cRGtydcK2vpKJ+yT2X4D5lyg8h1+9xz+Y9ZnQwTCRglPTr46cRT8rl5Y3OdwXVIG72FQV/7WDxddJS42XGEznsz31Ip/qrC2U0seDlOqsF2sFxD5/HdEJccVZ26CuWJGm0/gS1UdRiq3rVGLdG7boFQNPhUPjeJhwyEsVdJSJRD7j/0qJx+shqS8HKxZf2ZlIkbhis= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:KL1PR02MB4977.apcprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(23010399003)(366016)(10067099003)(5023799004)(6133799003)(3023799007)(22082099003)(18002099003)(56012099006); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?WEbsbVkL0mOFZBCiwGle2YAUfYDPGD5ASz8lvPz47wlHy1gNEAA4LmyTUsGR?= =?us-ascii?Q?HtB1sK37Ne+Xx1EJBx4EmchHs927lSDhe6pmaDoa1p15/FllXw+z/8DtjSTG?= =?us-ascii?Q?hGui6FkBpeGKCzQUIBUtRVQJuaQjjDlVed1ViLHZFJSuneBEwp5OERnwJf+F?= =?us-ascii?Q?dDgS2H6y05waJRWUrkcI0/D5VPzzalkHh2E+XErLEn8M6JmYIFzUgB9Z3J4I?= =?us-ascii?Q?sF7z/wJi7/2KuhEnDI9WJWi96eBhCrIGof/xW7HkRQIojvdGuHjIv2C3zD2M?= =?us-ascii?Q?fzi6TKkYbeUgYf3plT2laq8XyFHJnKSfCJyic8tBEUhoW1zrmM+VAlbXJwgs?= =?us-ascii?Q?FafE7dzXO3oSMlRnEJzn3vjDjBTfoDktSR/5+lKSSFVygL9o6/eYL2Nc7VSM?= =?us-ascii?Q?RZCBcb8kbEqeCPTOoP5Ol5OUa07ov5S8D77T8Br7vPPvcC268UfHhTHUFHZl?= =?us-ascii?Q?pOjfIfsjLJD+W/GHZdB3eRRXL60QNjn+mDB0hOkdSjuLuk6Z1A2kjtINnjsW?= =?us-ascii?Q?AmBJGanfCClTjiZxSQOnZnMWAYaMjPGbviI36XqTnY9+cLde2vxIUbIVW9SN?= =?us-ascii?Q?4Y8pdE410gxNqEsgkjrDYNWZQNS4e8XRmcfEDx3G2iY6iK7zkhyPEa7LRN0z?= =?us-ascii?Q?V4oWrMA8JmnwSAr+uXl1ZOtC8/a7ZaRwNlMyMhXHTUUnFRHvFeaBdiH/HjVK?= =?us-ascii?Q?ERDeihHH9PAXoBY4m2zLh3J1hjwTBvlg+Z4CtuBz8uxa1zyx2Out4gIzH8Wt?= =?us-ascii?Q?m/5g3A03se1QTr02nAe/WIe2XmLSW6kfhJg9nxKWskbgSgeKPaz5XYBF8Mjh?= =?us-ascii?Q?E1IKmTyAfAzwQSB5ziwl7pVD7Df9l1FKtGMdcFzQc1o/ZNUe4A29XMR+dIHr?= =?us-ascii?Q?yFkekePMIw9h1MiE8s+fhcI93lLHq7KRZ1MAom97XQF4Gl0g1AzmwpVtS2uP?= =?us-ascii?Q?XLDIx8TMf5UOOPIK5Cw/51ZYyVIRUkolsLoMyivLWn0L90nr95/IakuToqKY?= =?us-ascii?Q?5x2D4Zo1uo/aCj/vfD1K7A1FAS1DDh3+dY+olRi9JyTCm9G17e7yFr1CSI1E?= =?us-ascii?Q?il1f5UN8PHlT99omXe2OvVDbaVFqMNSO9S+YLFrUEtv5a4P6zBs4QQe6BYHv?= =?us-ascii?Q?eE2FU0eaH4t2xodCJx3mKu2hp16Hd/YXnM4ITINm6omjVK7ljUB2YvRUFg9B?= =?us-ascii?Q?oLXXaoS5qzTbNIHqSSf6Jy9nI45aASImmGl6u6aCOxgUPzxXSSVLRi43xzdV?= =?us-ascii?Q?fysqWMeN+6ODycbYkKXs3qhrVK4YvFNi/6CrcC2rgTZx2KPIYD/JnW+6ELbJ?= =?us-ascii?Q?VWx5kt5lsHJfscsXiaIWxEtdzNcGJjZj+ONNMD4Pto6TlwWOyQrj6zlly1IC?= =?us-ascii?Q?vhPFDJSieJkLa4E7I5dCDhxM8pA1Z6JkyJAsl+g1rvBxYBnCz/JFgsSMrYSA?= =?us-ascii?Q?EEMDRZzuzCT30G97Ih1p75BLjct5hbjWvPODOX8wF3GYPAhjY1Qg3ACuShfR?= =?us-ascii?Q?IRyWOlsJ8wrCSvdBwMTYsDus0rSudu6paa4Gx2S5gyI/+gWMvWL5b/UBfeCs?= =?us-ascii?Q?owHUU5rvU75BJ+7jGCSHboMvGEG70oD3gli7MhZ0iZCDL7EfpwwLHZUlSXsD?= =?us-ascii?Q?EG3wk5Ip3ZUtvsmvGGqjGlzklJJSjOj3zk/WWmVU+Eo0M+3/KuRK94+MMjrB?= =?us-ascii?Q?/TfJflTmCBQOxrwFShRTR6NzfI4ctGGgC7FeWEm1LwGp49vJ8R1/Wtegpmp0?= =?us-ascii?Q?cXyk8sGYXPFC74vL49RmOiADERChrYk=3D?= X-OriginatorOrg: processmission.com X-MS-Exchange-CrossTenant-Network-Message-Id: b07ddf30-7f83-4cf6-9b53-08df09ae30e2 X-MS-Exchange-CrossTenant-AuthSource: KL1PR02MB4977.apcprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 11:26:26.0581 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e0544bf7-9765-4630-ab69-0b266dc2169c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: nbw8eCmKZ3lGJ6zi4YHlul98wVRcfl9XChdjDow0fGtOTiezU9dLtdELbmejEAcre7NZS+yjgKXQrjrkB2L6xDSElx5RcLfUgDcZr5JwwqM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: OSNPR02MB8962 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a01:111:f403:c405::5; envelope-from=bin.meng@processmission.com; helo=TYPPR03CU001.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, RCVD_IN_DNSWL_NONE=-0.0001, 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.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @processmission.com) X-ZM-MESSAGEID: 1788435101931158500 Content-Type: text/plain; charset="utf-8" The E2000 MHU previously acknowledged every SCMI message without applying power-state changes. Consequently, BL31 reported successful PSCI CPU_ON calls while all secondary CPUs remained powered off. Implement the power-domain requests and the Phytium PSOSTAT query used by the firmware. Follow the firmware-published runtime object graph, complete its SCP handoff, and reset each target CPU at the resident secondary entry published by BL1. The secondary handoff is not described by the public PBF specifications. Scan BL1 for invariant control-flow, MPIDR, and PBR-root anchors while masking compiler-dependent branch displacements, then obtain the firmware-owned vector-slot address from the adjacent literal. Reject missing, ambiguous, unaligned, or null handoff records. Pass the validated slot from PBR to MHU and dereference it for every CPU_ON request because firmware may publish the entry after boot and reuse the temporary BL1 image before Linux starts secondary CPUs. With this change, booting from SDK firmware images can bring up all four cores successfully. Signed-off-by: Bin Meng --- hw/arm/phytium_e2000.c | 18 ++ hw/misc/phytium_e2000_mhu.c | 384 ++++++++++++++++++++++++++-- hw/misc/phytium_e2000_pbr.c | 153 ++++++++++- include/hw/misc/phytium_e2000_mhu.h | 9 + include/hw/misc/phytium_e2000_pbr.h | 7 + 5 files changed, 543 insertions(+), 28 deletions(-) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index 1c337bf36e..1f2642df13 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -579,12 +579,30 @@ static void phytium_e2000_create_mhu(PhytiumE2000Stat= e *s) { DeviceState *dev =3D qdev_new(TYPE_PHYTIUM_E2000_MHU); SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + int i; =20 /* * MHU is the notification side of the SCMI transport. The message body * remains in SCP SRAM, so this device only owns the doorbell aperture. */ object_property_add_child(OBJECT(s), "mhu", OBJECT(dev)); + if (phytium_e2000_pbr_firmware_loaded(s->pbr)) { + /* + * PBR validates the firmware-specific BL1 handoff and owns all FIP + * interpretation. Pass only the resulting slot address to MHU; t= he + * transport must not parse firmware or assume a PBF build layout. + * Direct Linux boot has no firmware SCMI CPU_ON path and therefore + * intentionally leaves the slot unset. + */ + phytium_e2000_mhu_set_secondary_vector_slot( + PHYTIUM_E2000_MHU(dev), + phytium_e2000_pbr_secondary_vector_slot(s->pbr)); + } + for (i =3D 0; i < MACHINE(s)->smp.cpus; i++) { + phytium_e2000_mhu_connect_cpu(PHYTIUM_E2000_MHU(dev), i, + phytium_e2000_cpu_mp_affinity(i), + s->cpu[i]); + } sysbus_realize_and_unref(sbd, &error_fatal); sysbus_mmio_map_overlap(sbd, 0, PHYTIUM_E2000_MHU_BASE, 2); } diff --git a/hw/misc/phytium_e2000_mhu.c b/hw/misc/phytium_e2000_mhu.c index 4ea23af900..554448398b 100644 --- a/hw/misc/phytium_e2000_mhu.c +++ b/hw/misc/phytium_e2000_mhu.c @@ -18,15 +18,40 @@ =20 #include "hw/core/register.h" #include "migration/vmstate.h" +#include "qapi/error.h" +#include "qemu/bitops.h" #include "qemu/module.h" #include "system/address-spaces.h" +#include "target/arm/arm-powerctl.h" +#include "target/arm/cpu.h" =20 #define PHYTIUM_E2000_PBF_SCMI_MBOX_BASE 0x32a10400 #define PHYTIUM_E2000_SCMI_STATUS_OFFSET 0x04 #define PHYTIUM_E2000_SCMI_LEN_OFFSET 0x14 +#define PHYTIUM_E2000_SCMI_HEADER_OFFSET 0x18 #define PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET 0x1c #define PHYTIUM_E2000_SCMI_STATUS_FREE BIT(0) =20 +#define SCMI_MESSAGE_ID(header) extract32((header), 0, 8) +#define SCMI_PROTOCOL_ID(header) extract32((header), 10, 8) +#define SCMI_PROTOCOL_POWER_DOMAIN 0x11 +#define SCMI_PROTOCOL_PHYTIUM 0x81 +#define SCMI_POWER_STATE_SET 0x4 +#define SCMI_PHYTIUM_GET_PSOSTAT 0x3 +#define SCMI_POWER_STATE_TYPE BIT(30) +#define SCMI_POWER_STATE_ID_MASK (SCMI_POWER_STATE_TYPE - 1) + +#define SCMI_SUCCESS 0 +#define SCMI_INVALID_PARAMETERS (-2) +#define SCMI_GENERIC_ERROR (-8) + +#define PHYTIUM_E2000_PBF_ROOT_ANCHOR \ + (PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + 0xf00) +#define PHYTIUM_E2000_CPU_TARGET_OFFSET 0x08 +#define PHYTIUM_E2000_CPU_LOCK_DEPTH_OFFSET 0x28 +#define PHYTIUM_E2000_CPU_LOCK_OWNER_OFFSET 0x30 +#define PHYTIUM_E2000_CPU_ON_COMPLETE 0xabcdef98 + /* * The SDK defines AP OS status/set/clear at 0x100/0x108/0x110 within a * channel. PBF selects the channel at MHU offset 0x200, producing the glo= bal @@ -44,42 +69,308 @@ struct PhytiumE2000MHUState { =20 uint32_t regs[PHYTIUM_E2000_MHU_R_MAX]; RegisterInfo regs_info[PHYTIUM_E2000_MHU_R_MAX]; + uint64_t cpu_mpidrs[PHYTIUM_E2000_MHU_MAX_CPUS]; + CPUState *cpus[PHYTIUM_E2000_MHU_MAX_CPUS]; + /* Firmware-owned slot address supplied by the PBR before realization = */ + hwaddr secondary_vector_slot; + unsigned int num_cpus; }; =20 -static void phytium_e2000_mhu_complete_scmi(void) +static bool phytium_e2000_phys_readl(hwaddr addr, uint32_t *value) +{ + uint8_t buf[sizeof(*value)]; + + if (address_space_read(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, buf, + sizeof(buf)) !=3D MEMTX_OK) { + return false; + } + *value =3D ldl_le_p(buf); + return true; +} + +static bool phytium_e2000_phys_readq(hwaddr addr, uint64_t *value) +{ + uint8_t buf[sizeof(*value)]; + + if (address_space_read(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, buf, + sizeof(buf)) !=3D MEMTX_OK) { + return false; + } + *value =3D ldq_le_p(buf); + return true; +} + +static bool phytium_e2000_phys_writel(hwaddr addr, uint32_t value) +{ + uint8_t buf[sizeof(value)]; + + stl_le_p(buf, value); + return address_space_write(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, buf, + sizeof(buf)) =3D=3D MEMTX_OK; +} + +static bool phytium_e2000_phys_writeq(hwaddr addr, uint64_t value) +{ + uint8_t buf[sizeof(value)]; + + stq_le_p(buf, value); + return address_space_write(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, buf, + sizeof(buf)) =3D=3D MEMTX_OK; +} + +static uint32_t phytium_e2000_scmi_readl(hwaddr offset) { uint8_t buf[sizeof(uint32_t)]; - uint32_t len; =20 - /* - * Preserve the caller's message length, but reserve one status word f= or - * the minimal success response returned in the payload. - */ address_space_read(&address_space_memory, - PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + - PHYTIUM_E2000_SCMI_LEN_OFFSET, + PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + offset, MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); - len =3D MAX(ldl_le_p(buf), (uint32_t)sizeof(uint32_t)); + return ldl_le_p(buf); +} =20 - stl_le_p(buf, 0); - address_space_write(&address_space_memory, - PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + - PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET, - MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); - stl_le_p(buf, len); +static void phytium_e2000_scmi_writel(hwaddr offset, uint32_t value) +{ + uint8_t buf[sizeof(uint32_t)]; + + stl_le_p(buf, value); address_space_write(&address_space_memory, - PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + - PHYTIUM_E2000_SCMI_LEN_OFFSET, + PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + offset, MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); - stl_le_p(buf, PHYTIUM_E2000_SCMI_STATUS_FREE); +} + +static void phytium_e2000_scmi_publish(uint32_t len) +{ + phytium_e2000_scmi_writel(PHYTIUM_E2000_SCMI_LEN_OFFSET, len); /* * Publish the free bit last. PBF polls this field as the ownership ha= ndoff * and may consume the response immediately after observing it. */ - address_space_write(&address_space_memory, - PHYTIUM_E2000_PBF_SCMI_MBOX_BASE + - PHYTIUM_E2000_SCMI_STATUS_OFFSET, - MEMTXATTRS_UNSPECIFIED, buf, sizeof(buf)); + phytium_e2000_scmi_writel(PHYTIUM_E2000_SCMI_STATUS_OFFSET, + PHYTIUM_E2000_SCMI_STATUS_FREE); +} + +static bool phytium_e2000_mhu_cpu_is_on(PhytiumE2000MHUState *s, + uint64_t mpidr) +{ + unsigned int i; + + for (i =3D 0; i < s->num_cpus; i++) { + if ((s->cpu_mpidrs[i] & 0xffff) =3D=3D (mpidr & 0xffff)) { + return ARM_CPU(s->cpus[i])->power_state =3D=3D PSCI_ON; + } + } + + return false; +} + +static bool phytium_e2000_mhu_prepare_cpu_on(PhytiumE2000MHUState *s, + uint64_t mpidr, + uint64_t *runtime_cpu_control, + uint64_t *secondary_entry) +{ + uint64_t pbr_cpu_control; + uint64_t runtime_root; + uint64_t target; + uint64_t magic; + uint32_t first_instruction; + uint32_t lock_depth; + uint32_t lock_owner; + + /* + * BL1 and EL3 deliberately use different roots after PBF relocates the + * runtime object graph. BL1's reset trampoline follows the PBR-owned = root + * at 0x30c01000, while EL3 follows the relocatable anchor at 0x30c00f= 00. + * The emulated SCP therefore copies the requested MPIDR into BL1's + * control block before releasing the secondary CPU. + * + * The secondary-vector slot itself was recovered and validated while = PBR + * parsed BL1. Read the slot for every CPU_ON request rather than cac= hing + * its contents: BL1 first publishes the resident EL3 entry at runtime= and + * the temporary BL1 mapping may subsequently be overwritten. + */ + if (!phytium_e2000_phys_readq(PHYTIUM_E2000_PBR_ROOT, + &pbr_cpu_control) || + pbr_cpu_control !=3D PHYTIUM_E2000_PBR_CPU_CONTROL || + !phytium_e2000_phys_readq(pbr_cpu_control, &magic) || + magic !=3D PHYTIUM_E2000_PBR_CPU_CONTROL_MAGIC || + !phytium_e2000_phys_readq(PHYTIUM_E2000_PBF_ROOT_ANCHOR, + &runtime_root) || + runtime_root =3D=3D PHYTIUM_E2000_PBR_ROOT || + !QEMU_IS_ALIGNED(runtime_root, sizeof(uint64_t)) || + !phytium_e2000_phys_readq(runtime_root, runtime_cpu_control) || + !QEMU_IS_ALIGNED(*runtime_cpu_control, sizeof(uint64_t)) || + *runtime_cpu_control < PHYTIUM_E2000_PBR_BOOT_SRAM_BASE || + *runtime_cpu_control > PHYTIUM_E2000_PBR_BOOT_SRAM_BASE + + PHYTIUM_E2000_PBR_BOOT_SRAM_SIZE - + (PHYTIUM_E2000_CPU_LOCK_OWNER_OFFSET + + sizeof(uint32_t)) || + !phytium_e2000_phys_readq(*runtime_cpu_control + + PHYTIUM_E2000_CPU_TARGET_OFFSET, + &target) || + (target & 0xffff) !=3D (mpidr & 0xffff) || + !phytium_e2000_phys_readl(*runtime_cpu_control + + PHYTIUM_E2000_CPU_LOCK_DEPTH_OFFSET, + &lock_depth) || + !phytium_e2000_phys_readl(*runtime_cpu_control + + PHYTIUM_E2000_CPU_LOCK_OWNER_OFFSET, + &lock_owner) || + !s->secondary_vector_slot || + !phytium_e2000_phys_readq(s->secondary_vector_slot, + secondary_entry) || + !QEMU_IS_ALIGNED(*secondary_entry, sizeof(uint32_t)) || + !phytium_e2000_phys_readl(*secondary_entry, &first_instruction) || + first_instruction =3D=3D 0 || first_instruction =3D=3D UINT32_MAX)= { + return false; + } + + /* + * EL3 records three nested power-domain lock levels for the first CPU= _ON. + * Later requests observe the already retired zero state. The lock own= er + * must name a CPU which is currently powered on. + */ + if (!((lock_depth =3D=3D 3 && + phytium_e2000_mhu_cpu_is_on(s, lock_owner)) || + (lock_depth =3D=3D 0 && lock_owner =3D=3D 0))) { + return false; + } + + return phytium_e2000_phys_writeq( + pbr_cpu_control + PHYTIUM_E2000_CPU_TARGET_OFFSET, mpidr & 0xffff); +} + +static bool phytium_e2000_mhu_complete_cpu_on(uint64_t runtime_cpu_control) +{ + /* + * EL3 polls its relocated control block for 0xabcdef98 after issuing = the + * SCMI request. The secondary's on-finish hook begins by acquiring the + * same reentrant lock and writes the completion value only afterwards. + * The power-controller handoff must therefore retire the primary's lo= ck + * state before publishing completion, or both CPUs wait on each other. + * + * This ordering and the offsets were recovered from the Phytium Pi and + * COMe SDK BL1/EL3 binaries; they are not described by the published = PBF + * ABI. + */ + return phytium_e2000_phys_writel( + runtime_cpu_control + PHYTIUM_E2000_CPU_LOCK_DEPTH_OFFSET, = 0) && + phytium_e2000_phys_writel( + runtime_cpu_control + PHYTIUM_E2000_CPU_LOCK_OWNER_OFFSET, = 0) && + phytium_e2000_phys_writeq( + runtime_cpu_control + PHYTIUM_E2000_CPU_TARGET_OFFSET, + PHYTIUM_E2000_CPU_ON_COMPLETE); +} + +static uint32_t phytium_e2000_mhu_psostat(PhytiumE2000MHUState *s) +{ + uint32_t status =3D 0; + unsigned int i; + + /* + * Phytium PBF's vendor SCMI query returns two bits per E2000 core in = the + * SoC's physical CPU order. A value of 2 denotes powered off and 0 + * denotes powered on. This produces the 0x8a reset value observed on + * hardware when MPIDR 0x200 is the only running core. + */ + for (i =3D 0; i < s->num_cpus; i++) { + if (ARM_CPU(s->cpus[i])->power_state !=3D PSCI_ON) { + status |=3D 2U << (2 * i); + } + } + + return status; +} + +static int32_t phytium_e2000_mhu_set_power_state(PhytiumE2000MHUState *s) +{ + uint32_t domain_id =3D phytium_e2000_scmi_readl( + PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET + 4); + uint32_t power_state =3D phytium_e2000_scmi_readl( + PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET + 8); + uint32_t core_mask =3D power_state & SCMI_POWER_STATE_ID_MASK; + bool power_on =3D power_state & SCMI_POWER_STATE_TYPE; + uint64_t runtime_cpu_control; + uint64_t secondary_entry; + unsigned int i; + int ret; + + /* + * The E2000 firmware encodes Aff1 as the SCMI power domain and a sing= le + * Aff0 bit in the vendor power-state ID. This relation is visible in = the + * PBF request builder: MPIDR 0x201 becomes domain 2, state 0x40000002; + * MPIDR 0x100 becomes domain 1, state 0x40000001. + */ + if (!is_power_of_2(core_mask)) { + return SCMI_INVALID_PARAMETERS; + } + + for (i =3D 0; i < s->num_cpus; i++) { + uint64_t mpidr =3D s->cpu_mpidrs[i]; + unsigned int aff0 =3D extract64(mpidr, 0, 8); + unsigned int aff1 =3D extract64(mpidr, 8, 8); + + if (aff0 >=3D 30 || aff1 !=3D domain_id || BIT(aff0) !=3D core_mas= k) { + continue; + } + + if (power_on) { + if (!phytium_e2000_mhu_prepare_cpu_on( + s, mpidr, &runtime_cpu_control, &secondary_entry)) { + return SCMI_GENERIC_ERROR; + } + /* + * BL1 publishes the resident EL3 secondary entry in a fixed + * vector slot. Some firmware reuses the temporary BL1 image + * before Linux requests CPU_ON, so reset directly into the + * published resident entry rather than a BL1 flash offset. + */ + object_property_set_int(OBJECT(s->cpus[i]), "rvbar", + secondary_entry, &error_abort); + ret =3D arm_set_cpu_on_and_reset(mpidr); + if (ret =3D=3D QEMU_ARM_POWERCTL_RET_SUCCESS && + !phytium_e2000_mhu_complete_cpu_on(runtime_cpu_control)) { + return SCMI_GENERIC_ERROR; + } + } else { + ret =3D arm_set_cpu_off(mpidr); + } + return ret =3D=3D QEMU_ARM_POWERCTL_RET_SUCCESS ? + SCMI_SUCCESS : SCMI_GENERIC_ERROR; + } + + return SCMI_INVALID_PARAMETERS; +} + +static void phytium_e2000_mhu_complete_scmi(PhytiumE2000MHUState *s) +{ + uint32_t header =3D phytium_e2000_scmi_readl( + PHYTIUM_E2000_SCMI_HEADER_OFFSET); + uint32_t len =3D MAX(phytium_e2000_scmi_readl( + PHYTIUM_E2000_SCMI_LEN_OFFSET), (uint32_t)sizeof(uint32_t)); + int32_t scmi_status =3D SCMI_SUCCESS; + + /* + * PBF issues clock and platform setup commands whose side effects do = not + * affect modeled devices. Preserve their payload length and acknowled= ge + * them; only messages that change modeled CPU state need special hand= ling. + */ + if (SCMI_PROTOCOL_ID(header) =3D=3D SCMI_PROTOCOL_PHYTIUM && + SCMI_MESSAGE_ID(header) =3D=3D SCMI_PHYTIUM_GET_PSOSTAT) { + phytium_e2000_scmi_writel(PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET + 4, + phytium_e2000_mhu_psostat(s)); + len =3D 3 * sizeof(uint32_t); + } else if (SCMI_PROTOCOL_ID(header) =3D=3D SCMI_PROTOCOL_POWER_DOMAIN = && + SCMI_MESSAGE_ID(header) =3D=3D SCMI_POWER_STATE_SET) { + scmi_status =3D phytium_e2000_mhu_set_power_state(s); + len =3D 2 * sizeof(uint32_t); + } + + phytium_e2000_scmi_writel(PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET, + scmi_status); + phytium_e2000_scmi_publish(len); } =20 void phytium_e2000_mhu_seed_mailbox(void) @@ -88,18 +379,22 @@ void phytium_e2000_mhu_seed_mailbox(void) * PBR leaves the shared channel available before releasing PBF. Seed = the * same ownership and success state even before the first doorbell wri= te. */ - phytium_e2000_mhu_complete_scmi(); + phytium_e2000_scmi_writel(PHYTIUM_E2000_SCMI_PAYLOAD_OFFSET, + SCMI_SUCCESS); + phytium_e2000_scmi_publish(sizeof(uint32_t)); } =20 static void phytium_e2000_mhu_doorbell_post_write(RegisterInfo *reg, uint64_t value) { + PhytiumE2000MHUState *s =3D PHYTIUM_E2000_MHU(reg->opaque); + /* * Complete requests synchronously because no separate SCP CPU execute= s in * this model. Zero writes only update doorbell storage. */ if (value) { - phytium_e2000_mhu_complete_scmi(); + phytium_e2000_mhu_complete_scmi(s); } } =20 @@ -138,6 +433,36 @@ static void phytium_e2000_mhu_reset(DeviceState *dev) } } =20 +void phytium_e2000_mhu_connect_cpu(PhytiumE2000MHUState *s, + unsigned int index, uint64_t mpidr, + CPUState *cpu) +{ + g_assert(!DEVICE(s)->realized); + g_assert(index < PHYTIUM_E2000_MHU_MAX_CPUS); + g_assert(index =3D=3D s->num_cpus); + g_assert(cpu); + + object_ref(OBJECT(cpu)); + s->cpus[index] =3D cpu; + s->cpu_mpidrs[index] =3D mpidr; + s->num_cpus++; +} + +void phytium_e2000_mhu_set_secondary_vector_slot(PhytiumE2000MHUState *s, + hwaddr slot) +{ + /* + * This is immutable firmware configuration, not guest-programmable MHU + * state. Requiring it before realization prevents CPU_ON from observ= ing + * a partially configured transport. + */ + g_assert(!DEVICE(s)->realized); + g_assert(!s->secondary_vector_slot); + g_assert(slot && QEMU_IS_ALIGNED(slot, sizeof(uint64_t))); + + s->secondary_vector_slot =3D slot; +} + static void phytium_e2000_mhu_init(Object *obj) { PhytiumE2000MHUState *s =3D PHYTIUM_E2000_MHU(obj); @@ -150,6 +475,16 @@ static void phytium_e2000_mhu_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), ®_array->mem); } =20 +static void phytium_e2000_mhu_finalize(Object *obj) +{ + PhytiumE2000MHUState *s =3D PHYTIUM_E2000_MHU(obj); + unsigned int i; + + for (i =3D 0; i < s->num_cpus; i++) { + object_unref(OBJECT(s->cpus[i])); + } +} + static const VMStateDescription phytium_e2000_mhu_vmsd =3D { .name =3D TYPE_PHYTIUM_E2000_MHU, .version_id =3D 1, @@ -174,6 +509,7 @@ static const TypeInfo phytium_e2000_mhu_info =3D { .parent =3D TYPE_SYS_BUS_DEVICE, .instance_size =3D sizeof(PhytiumE2000MHUState), .instance_init =3D phytium_e2000_mhu_init, + .instance_finalize =3D phytium_e2000_mhu_finalize, .class_init =3D phytium_e2000_mhu_class_init, }; =20 diff --git a/hw/misc/phytium_e2000_pbr.c b/hw/misc/phytium_e2000_pbr.c index 4485f073e1..d6f7b3b26e 100644 --- a/hw/misc/phytium_e2000_pbr.c +++ b/hw/misc/phytium_e2000_pbr.c @@ -55,9 +55,38 @@ REG32(ETH_TRAINING_STATUS, 0x60) #define PHYTIUM_E2000_BL1_SIZE 0x00090000 #define PHYTIUM_E2000_PBR_BL1_RUNTIME_BASE 0xf8c40000 =20 +/* + * This is not a published PBF structure. It is the smallest instruction = and + * literal window that identifies the secondary-CPU handoff in each inspec= ted + * BL1 image. Keep the offsets named so the checks below document which p= arts + * of the recovered sequence are treated as its compatibility contract. + * + * +0x00 BL