From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web11.57364.1675699403396306692 for ; Mon, 06 Feb 2023 08:03:23 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=CRq5yTAh; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: andrei.warkentin@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675699403; x=1707235403; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=Hsl+xRkJkm07rV9iTL5czdd78YVD2UzhwajvvNFDEgc=; b=CRq5yTAh2WPRxKVsSKV+3wivVFyTU5R3MyfbaBct7Z9Id5P+0o4exqiL BI6f2EFaWmcfWwkmu1JGfy+MpXzm9KvWEAmCRlPACJ+uC3ltdTP3FgqQD Ocb4Of6KTcID8FSiCCLIBIBoRgzRD+YeVdHzHqeUKrycR7pq5bubwdZaf /hQXaUzn6MI6qYcDC+E/zGo43YU2owqAJb7cy+f3s5Kt2ucumtaxhUHES VQ5IGwxYdEJeyF3m3nHDYGxtPmMsdxwzfM7lsGqxw7/bTa2G02oqZRclN RRwo4DQ+TqM2+y+/j/WLplZRfwvqwFmFkLS2SCWoGVBb8VwzKOAX4pF6x w==; X-IronPort-AV: E=McAfee;i="6500,9779,10613"; a="308883663" X-IronPort-AV: E=Sophos;i="5.97,276,1669104000"; d="scan'208";a="308883663" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2023 08:02:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10613"; a="840399610" X-IronPort-AV: E=Sophos;i="5.97,276,1669104000"; d="scan'208";a="840399610" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by orsmga005.jf.intel.com with ESMTP; 06 Feb 2023 08:02:55 -0800 Received: from fmsmsx601.amr.corp.intel.com (10.18.126.81) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Mon, 6 Feb 2023 08:02:55 -0800 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16 via Frontend Transport; Mon, 6 Feb 2023 08:02:55 -0800 Received: from NAM02-DM3-obe.outbound.protection.outlook.com (104.47.56.42) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.16; Mon, 6 Feb 2023 08:02:55 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Kl93MNRsgJsOc27OE1ZMJJTLLPx2F1FU7bVF0Z3rsASjYkKlDjpLqtkiijLb8gi/uN3ATeakiT6pecxs4rPhEtRQrAGGRfz9c15aL2yWdbti+rXOX3CwLn+uMkggDW+Xt+iuhXXcD4XHuUtMfwkbsZUtmPCeGoTuIh0vwfkqfTpPo4QDlodMuMpvcD3HFeuYufgnEaTVkY6+vvQ5js9e+iwhvNraBoRc18P8Z18Mi8HFiYoJjOmnqixgfOuMOP2NetY/4NL7YJWEt4Yj7HodD0HmAOGm0SZHVa/Gg6NaunssmGamWzbRRlECMibTHC6X2M0iE+gpvDnaKln3KgCzwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=P9MRAx+saPhjMOg6WPUkfDApD8QZ67PZDUuyoKcGn1o=; b=YywfeUeSCeiCyqIN5CTAOvjgYazmjEUf5LGbQ6MALmpJpp35/FKMV0HIDdEE/opK0wOA8JO3/QiLdQ7HaKPsL1G3DirP+ypVx75L2D4lsqGTQ5AYh5qhAq+rpdiN88DRE4tLFoPgDAW1klG61G8Ox2hAS55+BCI0X/ouFWsBoOL4wiv3QSbxWa5WGd6kOT1tcqCvpk9FPQT6zgXNMedMoKXwvPl/PKSiM0CzIqyQxYk523Tcwn+KglttiST3DGryQ/KhIVq243Oyx4t64DvkZ+3tXkQ5AEF5Fo1Ph9AxSVP+0KGIMpRNhKBVDjb2jTJYmrbShgzifKXIQuMrJbqQsA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from PH8PR11MB6856.namprd11.prod.outlook.com (2603:10b6:510:22b::7) by CH3PR11MB7938.namprd11.prod.outlook.com (2603:10b6:610:12f::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6064.34; Mon, 6 Feb 2023 16:02:53 +0000 Received: from PH8PR11MB6856.namprd11.prod.outlook.com ([fe80::9dba:633a:320c:87b]) by PH8PR11MB6856.namprd11.prod.outlook.com ([fe80::9dba:633a:320c:87b%5]) with mapi id 15.20.6064.032; Mon, 6 Feb 2023 16:02:52 +0000 From: "Andrei Warkentin" To: "devel@edk2.groups.io" , "sunilvl@ventanamicro.com" CC: Ard Biesheuvel , "Yao, Jiewen" , "Justen, Jordan L" , "Gerd Hoffmann" , Abner Chang Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Thread-Topic: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg/RiscVVirt: Add PciCpuIo2Dxe module Thread-Index: AQHZM01uhPi5L4+iWEy6pxeoodHuN67CIlGw Date: Mon, 6 Feb 2023 16:02:52 +0000 Message-ID: References: <20230128191807.2080547-1-sunilvl@ventanamicro.com> <20230128191807.2080547-18-sunilvl@ventanamicro.com> In-Reply-To: <20230128191807.2080547-18-sunilvl@ventanamicro.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PH8PR11MB6856:EE_|CH3PR11MB7938:EE_ x-ms-office365-filtering-correlation-id: 73a7460e-d81b-4378-404d-08db085b9a69 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: gGAnkWRpf4076Di1YrnrixDMqWXzqygWKCotvi+EYvgMcN5awfhO3tvzo3Q/Wt3eQXtuoya/QgWw+5fECD5CI1atZYe7Qu3UAmCRr04agDYjyB3RNGYsGxMO7WCNDQZmE8v7MzswJ7Ong1qH5T8rGwh6VERADcrXK3ujEP88YauatWOl16vU1RfElZTqaNbc8JTYsXIP2pwVl39mC8p4j7WHFGiK5LzU4fmBs2nUOFrrNbuvNYplC9Aom7dfWLmGZGk/JTo9ClzHfedJJufKxLn9wKNZRUky3YEIIEWqHdbdpHnxq81xj3QwSb3dsFlhjlmavE5YzANAuS/hUZ6kxpfTbCs3dO+d3j+jUWqNdu6+hrMRP0YPP1d198XMTZUAmTJ9D/eNeCLFZrxu2lqJH0twnGMaVG5vTq0Sh+66khyxCaxccaTVRBCpx4dzyoogcg9GhNOtLX3X/eJWLRz3sMywF2ndsMEIOAChnjXQXA5EDsSlXw92RSK01rvoCltSPNUBMSdPzYHETYJ3b1hFLPC/9JHRVw1ZeB5bk6YXKbroOKEi3rj3c7m2mewQQhqYS2dnOtHTKZdOQ9UyHi+973RwzrE0lqKNmWP/s9aJ/z1o0XATCXBkv2cSjMkLSi4rnyESi+zzS5ag0EsHnozDskjNTufA15aa1a6DOMRn04X/8d+JME15HiRTyiMJWea+i1Y/lzKiIjv7tB4NMeBhns8RnWpMjfL07U4Ahg38pXVbz5/hxKSuTM5bD6u9TcYvrfPa1QMy4CrecLaxpOxrZbPzN2zey9r4f2Bn01PLv1A= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB6856.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(366004)(346002)(136003)(39860400002)(396003)(376002)(451199018)(66899018)(478600001)(52536014)(30864003)(33656002)(86362001)(8936002)(41300700001)(66556008)(66446008)(64756008)(76116006)(66476007)(8676002)(66946007)(5660300002)(4326008)(2906002)(82960400001)(38100700002)(38070700005)(122000001)(316002)(19627235002)(7696005)(71200400001)(966005)(53546011)(54906003)(55016003)(110136005)(6506007)(186003)(9686003)(26005)(83380400001)(579004)(44824005);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?O3vBCyguimaO6a7SQbpW8FjKoQcPsuRGiMN3V6Ze4GzaLfIJ2TWpGUGe9uYN?= =?us-ascii?Q?xUr/u2u5ibHiyhBDC1tUuwrzB5N7ozhtDwLniUSx2v7wsc4LPug8TwLOYzCN?= =?us-ascii?Q?UaSVDdmpYLMuhSmaXaWNKXIOXw4oPfeqO3VqN+Xv4TzjJmQA8ZBc9MTtH6mi?= =?us-ascii?Q?Bc1/MzKlFUWGVbpKAOpD7mQmXyu0OT3fShtn58ykAJsmqSvjZIcFfFZTTdLw?= =?us-ascii?Q?yI2FEjOpCKi6kX5yUFbLd0/G0Y3Ex83mvra2vOQTINIqQ6rCxvo2I5didKhX?= =?us-ascii?Q?YaWrWI0wVM7IWfkZhGFmnVXHRG+tNjYGIUSz1NYSeM9244t8GZelNv8adSCJ?= =?us-ascii?Q?S88ps5WFrBgoHQG8eSyGkdd1f+uK1veZ3xq1fCo0XdXzq1kihSkqrr3MSBg6?= =?us-ascii?Q?5HvxYZpYEpmt+PEfPxYzwdi9pJWAqiZ9Hx/phzhief5Mrgzpfkl7ebBNmJ9z?= =?us-ascii?Q?EY1DOXB9WMN0LwGvR8gxJodumm7FhiVh1+a2/y7S3cvWWg03UBD9pn3YzQdi?= =?us-ascii?Q?1qvlwJCyC9l5Uua+cRmxWPmnnDIhkMHuXR+1zeH+mslymkXEeSA7mpKYQpFU?= =?us-ascii?Q?RcxScR7oOvtbBS6qFWdrdi5zRBHEG0tfC3pzl2Fag/dMg/ZSqI3s0UBjCNhx?= =?us-ascii?Q?r8dFf+DP4yAYKh9Bs2avJ3Q0zR7WBL0N6UI6bzlrdeCdtn0WUT6Ie31zm4dr?= =?us-ascii?Q?jcp4m15rSpKd7GWSJSlXNxuFjG+MGimIt7jLf7rzXQq763jbg3qcRxlpDzDC?= =?us-ascii?Q?Hb10ZE4CRTg041gW7Yf0k65VZ0iHqkkJ2ILygMPr9QLxL5gV1K7fOS/4Byb0?= =?us-ascii?Q?5+dl79GMjuI6cJGSpIRgH3/JIpGzHnOyii5oKFjxaSgO4HBv7PBt4hcFFriu?= =?us-ascii?Q?1gcGKUjiA5wSEd/Z62KvHkd3AyCVNaFSuxJgrr6iVGX0L+BWgx1u0InlFFrn?= =?us-ascii?Q?AutAb7qHOl8iTlRAU688gQyGsh0FMLbqoGyyP4QX3AoP4Da1RnFO9xSJ8ORh?= =?us-ascii?Q?44Pqpk6T6GCdHOo6d2yFp5fL5XqmqPGNCRLawwMJJL2s5kv49MqJClIsNjW5?= =?us-ascii?Q?JzS3r62BMuOsERSfKjH4c1UvIiZPVUXFnCfD72C+nrcTk21amzrghmkjq1Ah?= =?us-ascii?Q?wQr+80m6u8OrJvkGvLWWAKyTgDzQuO+bIlW2To13pVMNBW3f+3hdTjK2DEf/?= =?us-ascii?Q?jpxJfBfc0zcHuEx/z8kxnLz1rgrXGMIeBLRZKTDcp+owJsoJFnjRo2QODaQX?= =?us-ascii?Q?chVvQyFUWecGHuhYpyq9Jm+tg7f+IlyrWmcdqTXIONNSJfrbnwxWWqGW2kLq?= =?us-ascii?Q?aAPzfipuT41rfZEFMMFUeFPJAeYTcp1hXQzcLZ0IIbtoY3z4kFEjyVSoPZAH?= =?us-ascii?Q?LVpncdbfXisZjHdq913a3tSHAahRLl64c8a2ELoOk2fZGapDgZ/NrXW3M6lP?= =?us-ascii?Q?a8PpSLcpWbLBF7tf8ZzbNuRDzUBV2CLYOWkwbVTzzNJqoyyeLFSF6jWTO5uE?= =?us-ascii?Q?qihGMb2i+zOGnBgxw8+GECG+6KjtFO++MNsRYOdPQ/iLwVByiWkoWodw57yJ?= =?us-ascii?Q?VDJsd9iXKVYz6E/Qw8UKo/ScFVNK1B9eANdM2u37XXFJd6+2DsY4GYZmZ+j4?= =?us-ascii?Q?BA=3D=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB6856.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 73a7460e-d81b-4378-404d-08db085b9a69 X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Feb 2023 16:02:52.8223 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 5XD7VkfA3eN6Nxt0Ixp8DPDAanG9bfuWiU1aTDP1NbsKLmIOAbLPUUo9LtjEXiN1ZBiu3BTqCyqKYDTiRFWr8+mEC9IXcMJh+WugwiCcjbo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR11MB7938 Return-Path: andrei.warkentin@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Andrei Warkentin -----Original Message----- From: devel@edk2.groups.io On Behalf Of Sunil V L Sent: Saturday, January 28, 2023 1:18 PM To: devel@edk2.groups.io Cc: Ard Biesheuvel ; Yao, Jiewen ; Justen, Jordan L ; Gerd Hoffmann ; Abner Chang Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 17/20] OvmfPkg= /RiscVVirt: Add PciCpuIo2Dxe module Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL to add the transl= ation for IO access. This is copied from ArmPciCpuIo2Dxe driver. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Signed-off-by: Sunil V L Acked-by: Abner Chang --- OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 48 ++ OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 557 ++++++++++++++++++++ 2 files changed, 605 insertions(+) diff --git a/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf b/OvmfPkg/Risc= VVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf new file mode 100644 index 000000000000..4f78cfa4067b --- /dev/null +++ b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.inf @@ -0,0 +1,48 @@ +## @file +# Produces the CPU I/O 2 Protocol by using the services of the I/O Librar= y. +# +# Copyright (c) 2009 - 2014, Intel Corporation. All rights=20 +reserved.
# Copyright (c) 2016, Linaro Ltd. All rights=20 +reserved.
# Copyright (c) 2022, Ventana Micro Systems Inc. All=20 +rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent #=20 +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D PciCpuIo2Dxe + FILE_GUID =3D 9BD3C765-2579-4CF0-9349-D77205565030 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D PciCpuIo2Initialize + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D RISCV64 +# + +[Sources] + PciCpuIo2Dxe.c + +[Packages] + OvmfPkg/OvmfPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation + +[Protocols] + gEfiCpuIo2ProtocolGuid ## PRODUCES + +[Depex] + TRUE diff --git a/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c b/OvmfPkg/RiscVV= irt/PciCpuIo2Dxe/PciCpuIo2Dxe.c new file mode 100644 index 000000000000..f3bf07e63141 --- /dev/null +++ b/OvmfPkg/RiscVVirt/PciCpuIo2Dxe/PciCpuIo2Dxe.c @@ -0,0 +1,557 @@ +/** @file + Produces the CPU I/O 2 Protocol. + +Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
=20 +Copyright (c) 2016, Linaro Ltd. All rights reserved.
Copyright (c)=20 +2022, Ventana Micro Systems Inc. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include + +#define MAX_IO_PORT_ADDRESS 0xFFFF + +// +// Handle for the CPU I/O 2 Protocol +// +STATIC EFI_HANDLE mHandle =3D NULL; + +// +// Lookup table for increment values based on transfer widths // STATIC=20 +CONST UINT8 mInStride[] =3D { + 1, // EfiCpuIoWidthUint8 + 2, // EfiCpuIoWidthUint16 + 4, // EfiCpuIoWidthUint32 + 8, // EfiCpuIoWidthUint64 + 0, // EfiCpuIoWidthFifoUint8 + 0, // EfiCpuIoWidthFifoUint16 + 0, // EfiCpuIoWidthFifoUint32 + 0, // EfiCpuIoWidthFifoUint64 + 1, // EfiCpuIoWidthFillUint8 + 2, // EfiCpuIoWidthFillUint16 + 4, // EfiCpuIoWidthFillUint32 + 8 // EfiCpuIoWidthFillUint64 +}; + +// +// Lookup table for increment values based on transfer widths // STATIC=20 +CONST UINT8 mOutStride[] =3D { + 1, // EfiCpuIoWidthUint8 + 2, // EfiCpuIoWidthUint16 + 4, // EfiCpuIoWidthUint32 + 8, // EfiCpuIoWidthUint64 + 1, // EfiCpuIoWidthFifoUint8 + 2, // EfiCpuIoWidthFifoUint16 + 4, // EfiCpuIoWidthFifoUint32 + 8, // EfiCpuIoWidthFifoUint64 + 0, // EfiCpuIoWidthFillUint8 + 0, // EfiCpuIoWidthFillUint16 + 0, // EfiCpuIoWidthFillUint32 + 0 // EfiCpuIoWidthFillUint64 +}; + +/** + Check parameters to a CPU I/O 2 Protocol service request. + + The I/O operations are carried out exactly as requested. The caller=20 + is responsible for satisfying any alignment and I/O width=20 + restrictions that a PI System on a platform might require. For=20 + example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other=20 + hand, will be handled by the driver. + + @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port= operation. + @param[in] Width Signifies the width of the I/O or Memory opera= tion. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The n= umber of + bytes moved is Width size * Count, starting at= Address. + @param[in] Buffer For read operations, the destination buffer to= store the results. + For write operations, the source buffer from w= hich to write data. + + @retval EFI_SUCCESS The parameters for this request pass the = checks. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system= . + +**/ +STATIC +EFI_STATUS +CpuIoCheckParameter ( + IN BOOLEAN MmioOperation, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + UINT64 MaxCount; + UINT64 Limit; + + // + // Check to see if Buffer is NULL + // + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check to see if Width is in the valid range // if ((UINT32)Width=20 + >=3D EfiCpuIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + // + // For FIFO type, the target address won't increase during the=20 + access, // so treat Count as 1 // if ((Width >=3D=20 + EfiCpuIoWidthFifoUint8) && (Width <=3D EfiCpuIoWidthFifoUint64)) { + Count =3D 1; + } + + // + // Check to see if Width is in the valid range for I/O Port=20 + operations // Width =3D (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); if= =20 + (!MmioOperation && (Width =3D=3D EfiCpuIoWidthUint64)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check to see if Address is aligned // if ((Address &=20 + (UINT64)(mInStride[Width] - 1)) !=3D 0) { + return EFI_UNSUPPORTED; + } + + // + // Check to see if any address associated with this transfer exceeds=20 + the maximum // allowed address. The maximum address implied by the=20 + parameters passed in is // Address + Size * Count. If the following=20 + condition is met, then the transfer // is not supported. + // + // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_POR= T_ADDRESS) + 1 + // + // Since MAX_ADDRESS can be the maximum integer value supported by=20 + the CPU and Count // can also be the maximum integer value supported=20 + by the CPU, this range // check must be adjusted to avoid all overflow c= onditions. + // + // The following form of the range check is equivalent but assumes=20 + that // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1). + // + Limit =3D (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); if=20 + (Count =3D=3D 0) { + if (Address > Limit) { + return EFI_UNSUPPORTED; + } + } else { + MaxCount =3D RShiftU64 (Limit, Width); + if (MaxCount < (Count - 1)) { + return EFI_UNSUPPORTED; + } + + if (Address > LShiftU64 (MaxCount - Count + 1, Width)) { + return EFI_UNSUPPORTED; + } + } + + // + // Check to see if Buffer is aligned + // + if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width]) - 1))) != =3D 0) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Reads memory-mapped registers. + + The I/O operations are carried out exactly as requested. The caller=20 + is responsible for satisfying any alignment and I/O width=20 + restrictions that a PI System on a platform might require. For=20 + example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other=20 + hand, will be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16,=20 + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and=20 + Buffer are incremented for each of the Count operations that is performe= d. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, =20 + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times on the same Address= . + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, =20 + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times from the first elem= ent of Buffer. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[out] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system= . + +**/ +STATIC +EFI_STATUS +EFIAPI +CpuMemoryServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + Status =3D CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); = =20 + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Select loop based on the width of the transfer // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); for=20 + (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buffer += =3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + *Uint8Buffer =3D MmioRead8 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + *((UINT16 *)Uint8Buffer) =3D MmioRead16 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + *((UINT32 *)Uint8Buffer) =3D MmioRead32 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint64) { + *((UINT64 *)Uint8Buffer) =3D MmioRead64 ((UINTN)Address); + } + } + + return EFI_SUCCESS; +} + +/** + Writes memory-mapped registers. + + The I/O operations are carried out exactly as requested. The caller=20 + is responsible for satisfying any alignment and I/O width=20 + restrictions that a PI System on a platform might require. For=20 + example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other=20 + hand, will be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16,=20 + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and=20 + Buffer are incremented for each of the Count operations that is performe= d. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, =20 + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times on the same Address= . + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, =20 + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times from the first elem= ent of Buffer. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[in] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system= . + +**/ +STATIC +EFI_STATUS +EFIAPI +CpuMemoryServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + Status =3D CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); = =20 + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Select loop based on the width of the transfer // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); for=20 + (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buffer += =3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + MmioWrite8 ((UINTN)Address, *Uint8Buffer); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint64) { + MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); + } + } + + return EFI_SUCCESS; +} + +/** + Reads I/O registers. + + The I/O operations are carried out exactly as requested. The caller=20 + is responsible for satisfying any alignment and I/O width=20 + restrictions that a PI System on a platform might require. For=20 + example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other=20 + hand, will be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16,=20 + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and=20 + Buffer are incremented for each of the Count operations that is performe= d. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, =20 + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times on the same Address= . + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, =20 + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times from the first elem= ent of Buffer. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[out] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system= . + +**/ +STATIC +EFI_STATUS +EFIAPI +CpuIoServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + Status =3D CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); = =20 + if (EFI_ERROR (Status)) { + return Status; + } + + Address +=3D PcdGet64 (PcdPciIoTranslation); + + // + // Select loop based on the width of the transfer // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); + + for (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buff= er +=3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + *Uint8Buffer =3D MmioRead8 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + *((UINT16 *)Uint8Buffer) =3D MmioRead16 ((UINTN)Address); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + *((UINT32 *)Uint8Buffer) =3D MmioRead32 ((UINTN)Address); + } + } + + return EFI_SUCCESS; +} + +/** + Write I/O registers. + + The I/O operations are carried out exactly as requested. The caller=20 + is responsible for satisfying any alignment and I/O width=20 + restrictions that a PI System on a platform might require. For=20 + example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other=20 + hand, will be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16,=20 + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and=20 + Buffer are incremented for each of the Count operations that is performe= d. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, =20 + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times on the same Address= . + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, =20 + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address=20 + is incremented for each of the Count operations that is performed.=20 + The read or write operation is performed Count times from the first elem= ent of Buffer. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number= of + bytes moved is Width size * Count, starting at Addr= ess. + @param[in] Buffer For read operations, the destination buffer to stor= e the results. + For write operations, the source buffer from which = to write data. + + @retval EFI_SUCCESS The data was read from or written to the = PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given W= idth. + @retval EFI_UNSUPPORTED The address range specified by Address, W= idth, + and Count is not valid for this PI system= . + +**/ +STATIC +EFI_STATUS +EFIAPI +CpuIoServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; + UINT8 *Uint8Buffer; + + // + // Make sure the parameters are valid // Status =3D=20 + CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); if=20 + (EFI_ERROR (Status)) { + return Status; + } + + Address +=3D PcdGet64 (PcdPciIoTranslation); + + // + // Select loop based on the width of the transfer // + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + OperationWidth =3D (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); + + for (Uint8Buffer =3D (UINT8 *)Buffer; Count > 0; Address +=3D InStride, = Uint8Buffer +=3D OutStride, Count--) { + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { + MmioWrite8 ((UINTN)Address, *Uint8Buffer); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); + } + } + + return EFI_SUCCESS; +} + +// +// CPU I/O 2 Protocol instance +// +STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 =3D { + { + CpuMemoryServiceRead, + CpuMemoryServiceWrite + }, + { + CpuIoServiceRead, + CpuIoServiceWrite + } +}; + +/** + The user Entry Point for module CpuIo2Dxe. The user code starts with thi= s function. + + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry po= int. + +**/ +EFI_STATUS +EFIAPI +PciCpuIo2Initialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid); =20 + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mHandle, + &gEfiCpuIo2ProtocolGuid, + &mCpuIo2, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} -- 2.38.0