From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 62717D811A4 for ; Tue, 19 Dec 2023 06:30:14 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=K4pCGjndKrxhW1MdoKtpFznk++G9DzAXXA0sjQ0bIrI=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type:Content-Transfer-Encoding; s=20140610; t=1702967413; v=1; b=pXyRyt9UdmzU2n7fMPgeC5Gp+ae92OeZ8jdNGwQlRRVaR0owDdSZyWFnCpZkvtyygm3ANhD+ pi1Vzuh8D28EHy6sSEWbVoy1dcsc5WjXio1gHou/6GJ7Bi3FBxcKcugH5m32t4BJ/Vh4ZIrnM6n zHGkn3YLVrVvGMiH3t2MnOBI= X-Received: by 127.0.0.2 with SMTP id CFOnYY7687511xxHbw8qXb5D; Mon, 18 Dec 2023 22:30:13 -0800 X-Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by mx.groups.io with SMTP id smtpd.web10.6809.1702967412334595651 for ; Mon, 18 Dec 2023 22:30:12 -0800 X-IronPort-AV: E=McAfee;i="6600,9927,10928"; a="8986269" X-IronPort-AV: E=Sophos;i="6.04,287,1695711600"; d="scan'208";a="8986269" X-Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Dec 2023 22:30:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10928"; a="919532508" X-IronPort-AV: E=Sophos;i="6.04,287,1695711600"; d="scan'208";a="919532508" X-Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by fmsmga001.fm.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 18 Dec 2023 22:30:11 -0800 X-Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 18 Dec 2023 22:30:11 -0800 X-Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35 via Frontend Transport; Mon, 18 Dec 2023 22:30:11 -0800 X-Received: from NAM12-MW2-obe.outbound.protection.outlook.com (104.47.66.40) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Mon, 18 Dec 2023 22:30:10 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GfIskdHUbgReXHTTQmGD25D0Rcy/RBaLcsEoXdus/P/7RmH8RIWJyCUUDK4uywgXyy5xJJFwQB2rCyKT8xdwDpFbgS/efYAQ6eb4oDeO98UoSenGsTTtKu3PbnrkDiYpnzJqT+ILwtD0M6lDSVG4TS6eBzQOxq5jNy0YKHkQTVIXUNA9TOB+Ofmf7P9Jk2yybPIGXYRAmNn+iWwihSV59UePeAMUdWuoM9/9p8lpBF0ZqNqcUmKeBFM8CSAiBzNzOUpGx9U/IQcsz8KuDwCtVHYK22rD5E9qal5ptpKDe/ArBXuMX0IbR5Ez/IERLuQwRId75AFYfLHHQFLgfjEMJQ== 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=JdhTkNzGFE8AgM+UB2ifdD/uuIRdGSBiGIUMFBj8P98=; b=DX9BPIwgPIHoI3g12Tfu1M/aPLrC6ffV82FT468XsFxGQ80T1CF+dBoEsj0gp4ZUZ+baUKmFoJ6jbXcvI2oPE+gEq9lycZdyMV39grxBYvufrVWdgXbOMHYrds0u/b1MQM4kOSjoIMSkzvgACbHADykRzDqFIzZe9POZlvwCr+k2L7Lozyr1KHYwXovUgJ9gIqlDc3x5VVceDu6h3dY4i+laqdti5WgDemZjBY+WdUmGQYyOO14Uti15q+4Z58PrnGFkscclQ71RZHLXEpIfPRJpPmBPZHpeLSoGyQmPb4oZWu7n8zkj8UTLpBol8uNVrCmeblNhS49bEeS07Wct+g== 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 X-Received: from MN6PR11MB8244.namprd11.prod.outlook.com (2603:10b6:208:470::14) by MN0PR11MB6232.namprd11.prod.outlook.com (2603:10b6:208:3c3::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7091.38; Tue, 19 Dec 2023 06:30:07 +0000 X-Received: from MN6PR11MB8244.namprd11.prod.outlook.com ([fe80::b614:1f5e:8b0c:9858]) by MN6PR11MB8244.namprd11.prod.outlook.com ([fe80::b614:1f5e:8b0c:9858%4]) with mapi id 15.20.7091.034; Tue, 19 Dec 2023 06:30:07 +0000 From: "Ni, Ray" To: Chao Li , "devel@edk2.groups.io" CC: "Dong, Eric" , "Kumar, Rahul R" , Gerd Hoffmann , Baoqi Zhang , Dongyan Qian Subject: Re: [edk2-devel] [PATCH v4 15/37] UefiCpuPkg: Add CpuDxe driver for LoongArch64 Thread-Topic: [PATCH v4 15/37] UefiCpuPkg: Add CpuDxe driver for LoongArch64 Thread-Index: AQHaLPz+QfR8RTZxQk6kbnVcdsssyrCwL2RA Date: Tue, 19 Dec 2023 06:30:06 +0000 Message-ID: References: <20231212130932.2467028-1-lichao@loongson.cn> <20231212131233.2470984-1-lichao@loongson.cn> In-Reply-To: <20231212131233.2470984-1-lichao@loongson.cn> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN6PR11MB8244:EE_|MN0PR11MB6232:EE_ x-ms-office365-filtering-correlation-id: ec94abd8-fd01-4e81-d45f-08dc005bf14b x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: /tVu4G8cGUM+h5K3jH5SBYrC901KvkUfo/m3wJJp7MTeVB08+z03CRL68n2gnSOcWpbhv3wYlT1U2Z1QsFgf0lnEjCBlD1R+Pnc0TW52/e1zMK1JRSwKxKX3Kcb4B2xOVI6wk74uLhqpbM4s9QDB9klDpUKoIH4I7jnArlKTE5Q9VV+vG573jTtYOA5G6VkXNRSxESYON3XPKKcI2olukx86CZj1GAOzXVT16Nq6a2h7ROY3EUzXrccPG4OCPElv/GbQOdsDDPxjOEkuT4KtPRTo5W3hUyv72FbY9/RvrwiRCJZh1Pgdrws2EQdYL4xQqd2rmmI6aNiOt5NOFE2MKcSNZt+MwzIWn0Dqq09cXTHIPh90S26VBqKA89Cz+HaD82Qsg44jpmQ+pGwx5HNtnE4LHfSluM4mibtZZbIceaR31yQj5PGks6V8Qm9oKB6oWbgBQfjJfU1m/zGNUHGQ7PnKc06EAb+fxaxpEOXR8SeBeHaa/Rt2WnapOlszGW4MZVqLkO/ED9UwmP6nOiYzBgfqkEcjjVvfa6PBR1j2m1yDaXqLUJrtCls4USs4HzDYm4eG1B40KVnDcA4bq+r2Jp7bwgVNtTqVMq0N8X7E4UPy0qTo47IhHUW67aik+WIh7LxqofkbV1zeqOd+wXvvhTSGXnHGUt/WYWzLIvIVNXQ= x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?xgC9uS4sE9YHhF29xgivPofBmn8TVcF0rVzZiggQko5KW+ZhS5IszpXPXAL0?= =?us-ascii?Q?EZ9YmPAxHl4EZDp85HBgT0t2iQb95tzGzKCXT5WVFyVpPYTb8LP9qrKc+jGU?= =?us-ascii?Q?3Pr0XyPigWnyeN7kg1GjK6lKKonT0hURX7LvHxlmrz+HB/2xiMx8m6GtbN4Z?= =?us-ascii?Q?e6zX014hVI373V56jy4samBmxM+D4ZTyeOgLhb3s4hFoaeFxOThKj/AS+qX/?= =?us-ascii?Q?VLvAOyXYJPXZycjx2YEI+LMOo3mqAge2I/yD09jKDJRPaKEioKcEPinUy3qt?= =?us-ascii?Q?P6RJq+N8m8+AlaEy61hydxEZqYRfqua5fzBb3oC6ccUI41Arnr1EU6i9GimD?= =?us-ascii?Q?jZpFxKSCUOsuFlKaAy47SVizoz4RcFAqQ1TmhhAFSrRKdCk1diOR9J8i9AvM?= =?us-ascii?Q?ei+HsqSSpw0MTGz+nwU//VKzjlR0kIBYoVv5e5Jdafvlj6j3YYdTwneEZqb9?= =?us-ascii?Q?+G0t/JAHe0AScHeQJzvGNL/XAjscmJl0ycH7mJRVYw5xQ53T1TUliqRMlAck?= =?us-ascii?Q?h3ZCHa2JL/XcAgJVXf8+OZ9ruO9DVU6rhrsBo0YCgSmbeeWzEgrc0LVfczpX?= =?us-ascii?Q?6uvi6d3e4BIwdEXkB7hz8LXSPNBQCU5Jnfu/Gz+jxk2ii6qmj7jcY0LvU4EK?= =?us-ascii?Q?bWq1y/tuNvxSqZKCSohbJltCBk7lAevNr8ppDkbwS6whcQ/axhxYzJTBUnjb?= =?us-ascii?Q?TAE8I2NgSfegbCPVFc+0KJ2w6VOQ2NBcIsegd/9Dj+4OLU5MmktC3QW9+rX4?= =?us-ascii?Q?BU6l98vDQ5MuO9hKozys0xJ3LrPvuSpyOt+jDIL7XTUka+EyhOZbddLTNgOz?= =?us-ascii?Q?E7tJ8zQq0tcd6pSfOhm2P6X4+F4dxVYNVapWoF9x7QiCnP647WvAzewaXwh+?= =?us-ascii?Q?j/Pknw/ox+rO8+sHRE0r7KPBYLHjTqFgHaqLlgMu3grgmOg8F4fq9SwQSTu7?= =?us-ascii?Q?RUqou/nz5VAaM2TjrjKQ5eV5AgpTWLTunSHF07fSNAEd86lWmkytC+50fDuq?= =?us-ascii?Q?yYvGtelrs9JSqbyrGSF32SaRbNLCLoFBINBAPo56pyHDqQE4VW8ceKpiwESY?= =?us-ascii?Q?eQzXWIsKZZjmI/roZpPKs7OSOoTeg9qxDPJ20TcKZeoICJ1yhbF2hNAWjD+J?= =?us-ascii?Q?x1Gnkfud+paRqTZYgZrP6e/80QI2Cq2f2bwFOXye4Lv6r+CLpkPU8Frh20XG?= =?us-ascii?Q?VuVffpeb6YAHYNiHrJ/nFZqVff1kt+B07gUd6zVSMsCIEG7hobFU/I/NGlzg?= =?us-ascii?Q?aeGQUUKxybtGn6cD3a4zWYrUIA2xXLQGHoC3vz8ZayXrK3Iz5LkSsXXLBAqc?= =?us-ascii?Q?VIsys7RT2+PYnfD0UIxfKk/X7yP++Pag5GONrbOF8iNur0LtAXDu1LgNCzPD?= =?us-ascii?Q?11qoWRuw3a+PRB3eyzAqDHswyTB9+0PQbDb4rfnSsQ0NfU6I/shFQlIy3Cy3?= =?us-ascii?Q?qIR2Yxj3OkAG8auaXC7pcZo8uYpmY7qE8JytCgW0g86UBQSAy2l75jRpuyOa?= =?us-ascii?Q?NvJIumefFN/rMXn/B61KNkqcX+3+Tg5N0E/vw/YT5z0Hy4htEjPfoNAxkpEr?= =?us-ascii?Q?8PhVYWDDPgTJ8iYyskE=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN6PR11MB8244.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ec94abd8-fd01-4e81-d45f-08dc005bf14b X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Dec 2023 06:30:06.9707 (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: pLW7C/ecqbOT8imN1KEUc8S0aEi4i+hR3fqE8ol4/HEtaHX5kfMSroikzScq/+xEeJ9a1XPqgGTMLuBdrtxF7g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR11MB6232 X-OriginatorOrg: intel.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ray.ni@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 2MUjW4PuzJapMZdgZdd0uUi9x7686176AA= Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=pXyRyt9U; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}") Acked-by: Ray Ni Thanks, Ray > -----Original Message----- > From: Chao Li > Sent: Tuesday, December 12, 2023 9:13 PM > To: devel@edk2.groups.io > Cc: Dong, Eric ; Ni, Ray ; Kumar, > Rahul R ; Gerd Hoffmann ; > Baoqi Zhang ; Dongyan Qian > > Subject: [PATCH v4 15/37] UefiCpuPkg: Add CpuDxe driver for LoongArch64 >=20 > Added a new DXE driver named CpuDxeLoongArch64. >=20 > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4584 >=20 > Cc: Eric Dong > Cc: Ray Ni > Cc: Rahul Kumar > Cc: Gerd Hoffmann > Signed-off-by: Chao Li > Co-authored-by: Baoqi Zhang > Co-authored-by: Dongyan Qian > --- > UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.c | 435 > ++++++++++++++++++ > UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.h | 281 ++++++++++++ > UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.inf | 60 +++ > UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.uni | 15 + > UefiCpuPkg/CpuDxeLoongArch64/CpuMp.c | 544 > +++++++++++++++++++++++ > UefiCpuPkg/CpuDxeLoongArch64/CpuMp.h | 471 > ++++++++++++++++++++ > UefiCpuPkg/CpuDxeLoongArch64/Exception.c | 150 +++++++ > UefiCpuPkg/UefiCpuPkg.dsc | 1 + > 8 files changed, 1957 insertions(+) > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.c > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.h > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.inf > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.uni > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/CpuMp.c > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/CpuMp.h > create mode 100644 UefiCpuPkg/CpuDxeLoongArch64/Exception.c >=20 > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.c > b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.c > new file mode 100644 > index 0000000000..b1e20047c8 > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.c > @@ -0,0 +1,435 @@ > +/** @file CpuDxe.c > + > + CPU DXE Module to produce CPU ARCH Protocol. > + > + Copyright (c) 2023, Loongson Technology Corporation Limited. All right= s > reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "CpuDxe.h" > +#include "CpuMp.h" > +#include > +#include > +#include > + > +// > +// Globals used to initialize the protocol > +// > +EFI_HANDLE mCpuHandle =3D NULL; > +EFI_CPU_ARCH_PROTOCOL gCpu =3D { > + CpuFlushCpuDataCache, > + CpuEnableInterrupt, > + CpuDisableInterrupt, > + CpuGetInterruptState, > + CpuInit, > + CpuRegisterInterruptHandler, > + CpuGetTimerValue, > + CpuSetMemoryAttributes, > + 0, // NumberOfTimers > + 4, // DmaBufferAlignment > +}; > + > +/** > + This function flushes the range of addresses from Start to Start+Lengt= h > + from the processor's data cache. If Start is not aligned to a cache li= ne > + boundary, then the bytes before Start to the preceding cache line > boundary > + are also flushed. If Start+Length is not aligned to a cache line bound= ary, > + then the bytes past Start+Length to the end of the next cache line > boundary > + are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate > must be > + supported. If the data cache is fully coherent with all DMA operations= , > then > + this function can just return EFI_SUCCESS. If the processor does not > support > + flushing a range of the data cache, then the entire data cache can be > flushed. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param Start The beginning physical address to flush > from the processor's data > + cache. > + @param Length The number of bytes to flush from the > processor's data cache. This > + function may flush more bytes than Length > specifies depending upon > + the granularity of the flush operation that > the processor supports. > + @param FlushType Specifies the type of flush operation to > perform. > + > + @retval EFI_SUCCESS The address range from Start to > Start+Length was flushed from > + the processor's data cache. > + @retval EFI_INVALID_PARAMETER The processor does not support the > cache flush type specified > + by FlushType. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuFlushCpuDataCache ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS Start, > + IN UINT64 Length, > + IN EFI_CPU_FLUSH_TYPE FlushType > + ) > +{ > + switch (FlushType) { > + case EfiCpuFlushTypeWriteBack: > + WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length); > + break; > + case EfiCpuFlushTypeInvalidate: > + InvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length); > + break; > + case EfiCpuFlushTypeWriteBackInvalidate: > + WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)Start, > (UINTN)Length); > + break; > + default: > + return EFI_INVALID_PARAMETER; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function enables interrupt processing by the processor. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + > + @retval EFI_SUCCESS Interrupts are enabled on the > processor. > + @retval EFI_DEVICE_ERROR Interrupts could not be enabled on > the processor. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuEnableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ) > +{ > + EnableInterrupts (); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function disables interrupt processing by the processor. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + > + @retval EFI_SUCCESS Interrupts are disabled on the > processor. > + @retval EFI_DEVICE_ERROR Interrupts could not be disabled on > the processor. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuDisableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ) > +{ > + DisableInterrupts (); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function retrieves the processor's current interrupt state a retu= rns it > in > + State. If interrupts are currently enabled, then TRUE is returned. If > interrupts > + are currently disabled, then FALSE is returned. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param State A pointer to the processor's current > interrupt state. Set to TRUE if > + interrupts are enabled and FALSE if > interrupts are disabled. > + > + @retval EFI_SUCCESS The processor's current interrupt state > was returned in State. > + @retval EFI_INVALID_PARAMETER State is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetInterruptState ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + OUT BOOLEAN *State > + ) > +{ > + if (State =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + *State =3D GetInterruptState (); > + return EFI_SUCCESS; > +} > + > +/** > + This function generates an INIT on the processor. If this function suc= ceeds, > then the > + processor will be reset, and control will not be returned to the calle= r. If > InitType is > + not supported by this processor, or the processor cannot programmatica= lly > generate an > + INIT without help from external hardware, then EFI_UNSUPPORTED is > returned. If an error > + occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is > returned. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param InitType The type of processor INIT to perform. > + > + @retval EFI_SUCCESS The processor INIT was performed. > This return code should never be seen. > + @retval EFI_UNSUPPORTED The processor INIT operation > specified by InitType is not supported > + by this processor. > + @retval EFI_DEVICE_ERROR The processor INIT failed. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuInit ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_CPU_INIT_TYPE InitType > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Registers a function to be called from the CPU interrupt handler. > + > + @param This Protocol instance structure > + @param InterruptType Defines which interrupt to hook. > IA-32 > + valid range is 0x00 through 0xFF > + @param InterruptHandler A pointer to a function of type > + EFI_CPU_INTERRUPT_HANDLER > that is called > + when a processor interrupt occurs. > A null > + pointer is an error condition. > + > + @retval EFI_SUCCESS If handler installed or uninstalled. > + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a > handler > + for InterruptType was previously > installed. > + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a > handler for > + InterruptType was not previously > installed. > + @retval EFI_UNSUPPORTED The interrupt specified by > InterruptType > + is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuRegisterInterruptHandler ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ) > +{ > + return RegisterInterruptHandler (InterruptType, InterruptHandler); > +} > + > +/** > + Returns a timer value from one of the CPU's internal timers. There is = no > + inherent time interval between ticks but is a function of the CPU > frequency. > + > + @param This - Protocol instance structure. > + @param TimerIndex - Specifies which CPU timer is > requested. > + @param TimerValue - Pointer to the returned timer value. > + @param TimerPeriod - A pointer to the amount of time that > passes > + in femtoseconds (10-15) for each > increment > + of TimerValue. If TimerValue does > not > + increment at a predictable rate, > then 0 is > + returned. The amount of time that > has > + passed between two calls to > GetTimerValue() > + can be calculated with the formula > + (TimerValue2 - TimerValue1) * > TimerPeriod. > + This parameter is optional and may > be NULL. > + > + @retval EFI_SUCCESS - If the CPU timer count was returned. > + @retval EFI_UNSUPPORTED - If the CPU does not have any > readable timers. > + @retval EFI_DEVICE_ERROR - If an error occurred while reading > the timer. > + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue > is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetTimerValue ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN UINT32 TimerIndex, > + OUT UINT64 *TimerValue, > + OUT UINT64 *TimerPeriod OPTIONAL > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + This function modifies the attributes for the memory region specified = by > BaseAddress and > + Length from their current attributes to the attributes specified by > Attributes. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param BaseAddress The physical address that is the start > address of a memory region. > + @param Length The size in bytes of the memory region. > + @param EfiAttributes The bit mask of attributes to set for the > memory region. > + > + @retval EFI_SUCCESS The attributes were set for the > memory region. > + @retval EFI_ACCESS_DENIED The attributes for the memory > resource range specified by > + BaseAddress and Length cannot be > modified. > + @retval EFI_INVALID_PARAMETER Length is zero. > + @retval EFI_OUT_OF_RESOURCES There are not enough system > resources to modify the attributes of > + the memory resource range. > + @retval EFI_UNSUPPORTED The processor does not support one > or more bytes of the memory > + resource range specified by > BaseAddress and Length. > + The bit mask of attributes is not > support for the memory resource > + range specified by BaseAddress and > Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuSetMemoryAttributes ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 EfiAttributes > + ) > +{ > + EFI_STATUS Status; > + UINTN LoongArchAttributes; > + UINTN RegionBaseAddress; > + UINTN RegionLength; > + UINTN RegionLoongArchAttributes; > + > + RegionLength =3D 0x0; > + > + if ((BaseAddress & (SIZE_4KB - 1)) !=3D 0) { > + // > + // Minimum granularity is SIZE_4KB. > + // > + DEBUG (( > + DEBUG_INFO, > + "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum granularity is > SIZE_4KB\n", > + BaseAddress, > + Length, > + EfiAttributes > + )); > + > + return EFI_UNSUPPORTED; > + } > + > + // > + // Convert the 'Attribute' into LoongArch Attribute > + // > + LoongArchAttributes =3D EfiAttributeConverse (EfiAttributes); > + > + // > + // Get the region starting from 'BaseAddress' and its 'Attribute' > + // > + RegionBaseAddress =3D BaseAddress; > + Status =3D GetMemoryRegionAttributes ( > + RegionBaseAddress, > + BaseAddress + Length, > + &RegionLength, > + &RegionLoongArchAttributes > + ); > + > + // > + // Data & Instruction Caches are flushed when we set new memory > attributes. > + // So, we only set the attributes if the new region is different. > + // > + if (EFI_ERROR (Status) || (RegionLoongArchAttributes !=3D > LoongArchAttributes) || > + ((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) > + { > + Status =3D SetMemoryRegionAttributes (BaseAddress, Length, > EfiAttributes, 0x0); > + ASSERT_EFI_ERROR (Status); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Callback function for idle events. > + > + @param Event Event whose notification function is > being invoked. > + @param Context The pointer to the notification > function's context, > + which is > implementation-dependent. > + > +**/ > +VOID > +EFIAPI > +IdleLoopEventCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + CpuSleep (); > +} > + > +/** > + IPI Interrupt Handler. > + > + @param InterruptType The type of interrupt that occurred > + @param SystemContext A pointer to the system context when the > interrupt occurred > +**/ > +VOID > +EFIAPI > +IpiInterruptHandler ( > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_SYSTEM_CONTEXT SystemContext > + ) > +{ > + UINT32 IpiStatus; > + > + VOID (*Procedure) ( > + VOID > + ); > + > + IpiStatus =3D IoCsrRead32 (LOONGARCH_IOCSR_IPI_STATUS); > + > + // > + // Clear interrupt. > + // > + IoCsrWrite32 (LOONGARCH_IOCSR_IPI_CLEAR, IpiStatus); > + > + MemoryFence (); > + > + // > + // If the IPI IRQ is SMP_BOOT_CPU, it means the BSP is waking up the A= Ps > from the kernel. > + // So read out the boot vector and jump to it. > + // > + if (IpiStatus & SMP_BOOT_CPU) { > + Procedure =3D (VOID *)IoCsrRead64 (LOONGARCH_IOCSR_MBUF0); > + Procedure (); > + } > +} > + > +/** > + Initialize the state information for the CPU Architectural Protocol. > + > + @param ImageHandle Image handle this driver. > + @param SystemTable Pointer to the System Table. > + > + @retval EFI_SUCCESS Thread can be successfully created > + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data > structure > + @retval EFI_DEVICE_ERROR Cannot create the thread > + > +**/ > +EFI_STATUS > +CpuDxeInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + EFI_EVENT IdleLoopEvent; > + > + InitializeExceptions (&gCpu); > + > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &mCpuHandle, > + &gEfiCpuArchProtocolGuid, > + &gCpu, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Setup a callback for idle events > + // > + Status =3D gBS->CreateEventEx ( > + EVT_NOTIFY_SIGNAL, > + TPL_NOTIFY, > + IdleLoopEventCallback, > + NULL, > + &gIdleLoopEventGuid, > + &IdleLoopEvent > + ); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D gCpu.RegisterInterruptHandler ( > + &gCpu, > + EXCEPT_LOONGARCH_INT_IPI, > + IpiInterruptHandler > + ); > + > + InitializeMpSupport (); > + > + return Status; > +} > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.h > b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.h > new file mode 100644 > index 0000000000..194d29095b > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.h > @@ -0,0 +1,281 @@ > +/** @file CpuDxe.c > + > + CPU DXE Module to produce CPU ARCH Protocol. > + > + Copyright (c) 2023, Loongson Technology Corporation Limited. All right= s > reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef CPU_DXE_H_ > +#define CPU_DXE_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +/* > + This function flushes the range of addresses from Start to Start+Lengt= h > + from the processor's data cache. If Start is not aligned to a cache li= ne > + boundary, then the bytes before Start to the preceding cache line > boundary > + are also flushed. If Start+Length is not aligned to a cache line bound= ary, > + then the bytes past Start+Length to the end of the next cache line > boundary > + are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate > must be > + supported. If the data cache is fully coherent with all DMA operations= , > then > + this function can just return EFI_SUCCESS. If the processor does not > support > + flushing a range of the data cache, then the entire data cache can be > flushed. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param Start The beginning physical address to flush > from the processor's data > + cache. > + @param Length The number of bytes to flush from the > processor's data cache. This > + function may flush more bytes than Length > specifies depending upon > + the granularity of the flush operation that > the processor supports. > + @param FlushType Specifies the type of flush operation to > perform. > + > + @retval EFI_SUCCESS The address range from Start to > Start+Length was flushed from > + the processor's data cache. > + @retval EFI_UNSUPPORTEDT The processor does not support the > cache flush type specified > + by FlushType. > + @retval EFI_DEVICE_ERROR The address range from Start to > Start+Length could not be flushed > + from the processor's data cache. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuFlushCpuDataCache ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS Start, > + IN UINT64 Length, > + IN EFI_CPU_FLUSH_TYPE FlushType > + ); > + > +/** > + This function enables interrupt processing by the processor. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + > + @retval EFI_SUCCESS Interrupts are enabled on the > processor. > + @retval EFI_DEVICE_ERROR Interrupts could not be enabled on > the processor. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuEnableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ); > + > +/** > + This function disables interrupt processing by the processor. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + > + @retval EFI_SUCCESS Interrupts are disabled on the > processor. > + @retval EFI_DEVICE_ERROR Interrupts could not be disabled on > the processor. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuDisableInterrupt ( > + IN EFI_CPU_ARCH_PROTOCOL *This > + ); > + > +/** > + This function retrieves the processor's current interrupt state a retu= rns it > in > + State. If interrupts are currently enabled, then TRUE is returned. If > interrupts > + are currently disabled, then FALSE is returned. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param State A pointer to the processor's current > interrupt state. Set to TRUE if > + interrupts are enabled and FALSE if > interrupts are disabled. > + > + @retval EFI_SUCCESS The processor's current interrupt state > was returned in State. > + @retval EFI_INVALID_PARAMETER State is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetInterruptState ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + OUT BOOLEAN *State > + ); > + > +/** > + This function generates an INIT on the processor. If this function suc= ceeds, > then the > + processor will be reset, and control will not be returned to the calle= r. If > InitType is > + not supported by this processor, or the processor cannot programmatica= lly > generate an > + INIT without help from external hardware, then EFI_UNSUPPORTED is > returned. If an error > + occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is > returned. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param InitType The type of processor INIT to perform. > + > + @retval EFI_SUCCESS The processor INIT was performed. > This return code should never be seen. > + @retval EFI_UNSUPPORTED The processor INIT operation > specified by InitType is not supported > + by this processor. > + @retval EFI_DEVICE_ERROR The processor INIT failed. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuInit ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_CPU_INIT_TYPE InitType > + ); > + > +/** > + Registers a function to be called from the CPU interrupt handler. > + > + @param This Protocol instance structure > + @param InterruptType Defines which interrupt to hook. > IA-32 > + valid range is 0x00 through 0xFF > + @param InterruptHandler A pointer to a function of type > + EFI_CPU_INTERRUPT_HANDLER > that is called > + when a processor interrupt occurs. > A null > + pointer is an error condition. > + > + @retval EFI_SUCCESS If handler installed or uninstalled. > + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a > handler > + for InterruptType was previously > installed. > + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a > handler for > + InterruptType was not previously > installed. > + @retval EFI_UNSUPPORTED The interrupt specified by > InterruptType > + is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuRegisterInterruptHandler ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ); > + > +/** > + Returns a timer value from one of the CPU's internal timers. There is = no > + inherent time interval between ticks but is a function of the CPU > frequency. > + > + @param This - Protocol instance structure. > + @param TimerIndex - Specifies which CPU timer is > requested. > + @param TimerValue - Pointer to the returned timer value. > + @param TimerPeriod - A pointer to the amount of time that > passes > + in femtoseconds (10-15) for each > increment > + of TimerValue. If TimerValue does > not > + increment at a predictable rate, > then 0 is > + returned. The amount of time that > has > + passed between two calls to > GetTimerValue() > + can be calculated with the formula > + (TimerValue2 - TimerValue1) * > TimerPeriod. > + This parameter is optional and may > be NULL. > + > + @retval EFI_SUCCESS - If the CPU timer count was returned. > + @retval EFI_UNSUPPORTED - If the CPU does not have any > readable timers. > + @retval EFI_DEVICE_ERROR - If an error occurred while reading > the timer. > + @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue > is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuGetTimerValue ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN UINT32 TimerIndex, > + OUT UINT64 *TimerValue, > + OUT UINT64 *TimerPeriod OPTIONAL > + ); > + > +/** > + This function registers and enables the handler specified by > InterruptHandler for a processor > + interrupt or exception type specified by InterruptType. If InterruptHa= ndler > is NULL, then the > + handler for the processor interrupt or exception type specified by > InterruptType is uninstalled. > + The installed handler is called once for each processor interrupt or > exception. > + > + @param InterruptType A pointer to the processor's current > interrupt state. Set to TRUE if interrupts > + are enabled and FALSE if interrupts are > disabled. > + @param InterruptHandler A pointer to a function of type > EFI_CPU_INTERRUPT_HANDLER that is called > + when a processor interrupt occurs. If this > parameter is NULL, then the handler > + will be uninstalled. > + > + @retval EFI_SUCCESS The handler for the processor > interrupt was successfully installed or uninstalled. > + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a > handler for InterruptType was > + previously installed. > + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a > handler for InterruptType was not > + previously installed. > + @retval EFI_UNSUPPORTED The interrupt specified by > InterruptType is not supported. > + > +**/ > +EFI_STATUS > +RegisterInterruptHandler ( > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ); > + > +/** > + This function modifies the attributes for the memory region specified = by > BaseAddress and > + Length from their current attributes to the attributes specified by > Attributes. > + > + @param This The EFI_CPU_ARCH_PROTOCOL instance. > + @param BaseAddress The physical address that is the start > address of a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes The bit mask of attributes to set for the > memory region. > + > + @retval EFI_SUCCESS The attributes were set for the > memory region. > + @retval EFI_ACCESS_DENIED The attributes for the memory > resource range specified by > + BaseAddress and Length cannot be > modified. > + @retval EFI_INVALID_PARAMETER Length is zero. > + @retval EFI_OUT_OF_RESOURCES There are not enough system > resources to modify the attributes of > + the memory resource range. > + @retval EFI_UNSUPPORTED The processor does not support one > or more bytes of the memory > + resource range specified by > BaseAddress and Length. > + The bit mask of attributes is not > support for the memory resource > + range specified by BaseAddress and > Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +CpuSetMemoryAttributes ( > + IN EFI_CPU_ARCH_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ); > + > +/** > + Initialize interrupt handling for DXE phase. > + > + @param Cpu A pointer of EFI_CPU_ARCH_PROTOCOL instance. > + > + @return VOID. > + > +**/ > +VOID > +InitializeExceptions ( > + IN EFI_CPU_ARCH_PROTOCOL *gCpu > + ); > + > +/** > + Converts EFI Attributes to corresponding architecture Attributes. > + > + @param[in] EfiAttributes Efi Attributes. > + > + @retval Corresponding architecture attributes. > +**/ > +UINTN > +EFIAPI > +EfiAttributeConverse ( > + IN UINTN EfiAttributes > + ); > + > +#endif // CPU_DXE_H_ > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.inf > b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.inf > new file mode 100644 > index 0000000000..112628d788 > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.inf > @@ -0,0 +1,60 @@ > +## @file > +# CPU driver installs CPU Architecture Protocol and CPU MP protocol. > +# > +# Copyright (c) 2023, Loongson Technology Corporation Limited. All righ= ts > reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 1.29 > + BASE_NAME =3D CpuDxe > + MODULE_UNI_FILE =3D CpuDxe.uni > + FILE_GUID =3D > BF954921-25C1-48C0-9BFB-8D0CD7EE92DA > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + > + ENTRY_POINT =3D CpuDxeInitialize > + > +[Sources] > + CpuDxe.c > + CpuMp.c > + Exception.c > + CpuDxe.h > + CpuMp.h > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + UefiCpuPkg/UefiCpuPkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + CacheMaintenanceLib > + CpuExceptionHandlerLib > + CpuLib > + CpuMmuLib > + DebugLib > + DxeServicesTableLib > + HobLib > + MpInitLib > + PeCoffGetEntryPointLib > + UefiDriverEntryPoint > + UefiLib > + > +[Protocols] > + gEfiCpuArchProtocolGuid > + gEfiMpServiceProtocolGuid > + > +[Guids] > + gEfiDebugImageInfoTableGuid > + gIdleLoopEventGuid > + gEfiVectorHandoffTableGuid > + > +[Pcd] > + gUefiCpuPkgTokenSpaceGuid.PcdCpuExceptionVectorBaseAddress > + > +[Depex] > + TRUE > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.uni > b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.uni > new file mode 100644 > index 0000000000..6db717b829 > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.uni > @@ -0,0 +1,15 @@ > +// /** @file > +// CPU driver installs CPU Architecture Protocol and CPU MP Protocol. > +// > +// CPU driver installs CPU Architecture Protocol and CPU MP Protocol. > +// > +// Copyright (c) 2023, Loongson Technology Corporation Limited. All righ= ts > reserved.
> +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US "CPU > driver installs CPU Architecture Protocol and CPU MP Protocol." > + > +#string STR_MODULE_DESCRIPTION #language en-US "CPU > driver installs CPU Architecture Protocol and CPU MP Protocol." > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/CpuMp.c > b/UefiCpuPkg/CpuDxeLoongArch64/CpuMp.c > new file mode 100644 > index 0000000000..562ae484ac > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/CpuMp.c > @@ -0,0 +1,544 @@ > +/** @file > + CPU DXE Module to produce CPU MP Protocol. > + > + Copyright (c) 2023, Loongson Technology Corporation Limited. All right= s > reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "CpuDxe.h" > +#include "CpuMp.h" > + > +EFI_HANDLE mMpServiceHandle =3D NULL; > +UINTN mNumberOfProcessors =3D 1; > + > +EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate =3D { > + GetNumberOfProcessors, > + GetProcessorInfo, > + StartupAllAPs, > + StartupThisAP, > + SwitchBSP, > + EnableDisableAP, > + WhoAmI > +}; > + > +/** > + This service retrieves the number of logical processor in the platform > + and the number of those logical processors that are enabled on this bo= ot. > + This service may only be called from the BSP. > + > + This function is used to retrieve the following information: > + - The number of logical processors that are present in the system. > + - The number of enabled logical processors in the system at the inst= ant > + this call is made. > + > + Because MP Service Protocol provides services to enable and disable > processors > + dynamically, the number of enabled logical processors may vary during = the > + course of a boot session. > + > + If this service is called from an AP, then EFI_DEVICE_ERROR is returne= d. > + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then > + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of > processors > + is returned in NumberOfProcessors, the number of currently enabled > processor > + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[out] NumberOfProcessors Pointer to the total > number of logical > + processors in the > system, including the BSP > + and disabled APs. > + @param[out] NumberOfEnabledProcessors Pointer to the number of > enabled logical > + processors that exist in > system, including > + the BSP. > + > + @retval EFI_SUCCESS The number of logical processors > and enabled > + logical processors was retrieved. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. > + @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is > NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetNumberOfProcessors ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + OUT UINTN *NumberOfProcessors, > + OUT UINTN *NumberOfEnabledProcessors > + ) > +{ > + if ((NumberOfProcessors =3D=3D NULL) || (NumberOfEnabledProcessors =3D= =3D > NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + return MpInitLibGetNumberOfProcessors ( > + NumberOfProcessors, > + NumberOfEnabledProcessors > + ); > +} > + > +/** > + Gets detailed MP-related information on the requested processor at the > + instant this call is made. This service may only be called from the BS= P. > + > + This service retrieves detailed MP-related information about any > processor > + on the platform. Note the following: > + - The processor information may change during the course of a boot > session. > + - The information presented here is entirely MP related. > + > + Information regarding the number of caches and their sizes, frequency = of > operation, > + slot numbers is all considered platform-related information and is not > provided > + by this service. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[in] ProcessorNumber The handle number of processor. > + @param[out] ProcessorInfoBuffer A pointer to the buffer where > information for > + the requested processor is > deposited. > + > + @retval EFI_SUCCESS Processor information was > returned. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. > + @retval EFI_NOT_FOUND The processor with the handle > specified by > + ProcessorNumber does not exist > in the platform. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetProcessorInfo ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN UINTN ProcessorNumber, > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer > + ) > +{ > + return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer= , > NULL); > +} > + > +/** > + This service executes a caller provided function on all enabled APs. A= Ps > can > + run either simultaneously or one at a time in sequence. This service > supports > + both blocking and non-blocking requests. The non-blocking requests use > EFI > + events so the BSP can detect when the APs have finished. This service > may only > + be called from the BSP. > + > + This function is used to dispatch all the enabled APs to the function > specified > + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is > returned > + immediately and Procedure is not started on any AP. > + > + If SingleThread is TRUE, all the enabled APs execute the function spec= ified > by > + Procedure one by one, in ascending order of processor handle number. > Otherwise, > + all the enabled APs execute the function specified by Procedure > simultaneously. > + > + If WaitEvent is NULL, execution is in blocking mode. The BSP waits unt= il all > + APs finish or TimeoutInMicroseconds expires. Otherwise, execution is i= n > non-blocking > + mode, and the BSP returns from this service without waiting for APs. I= f a > + non-blocking mode is requested after the UEFI Event > EFI_EVENT_GROUP_READY_TO_BOOT > + is signaled, then EFI_UNSUPPORTED must be returned. > + > + If the timeout specified by TimeoutInMicroseconds expires before all A= Ps > return > + from Procedure, then Procedure on the failed APs is terminated. All > enabled APs > + are always available for further calls to > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not > NULL, its > + content points to the list of processor handle numbers in which Proced= ure > was > + terminated. > + > + Note: It is the responsibility of the consumer of the > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + to make sure that the nature of the code that is executed on the BSP a= nd > the > + dispatched APs is well controlled. The MP Services Protocol does not > guarantee > + that the Procedure function is MP-safe. Hence, the tasks that can be r= un in > + parallel are limited to certain independent tasks and well-controlled > exclusive > + code. EFI services and protocols may not be called by APs unless other= wise > + specified. > + > + In blocking execution mode, BSP waits until all APs finish or > + TimeoutInMicroseconds expires. > + > + In non-blocking execution mode, BSP is freed to return to the caller a= nd > then > + proceed to the next task without having to wait for APs. The following > + sequence needs to occur in a non-blocking execution mode: > + > + -# The caller that intends to use this MP Services Protocol in > non-blocking > + mode creates WaitEvent by calling the EFI CreateEvent() service. > The caller > + invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the > parameter WaitEvent > + is not NULL, then StartupAllAPs() executes in non-blocking mode. = It > requests > + the function specified by Procedure to be started on all the enab= led > APs, > + and releases the BSP to continue with other tasks. > + -# The caller can use the CheckEvent() and WaitForEvent() services t= o > check > + the state of the WaitEvent created in step 1. > + -# When the APs complete their task or TimeoutInMicroSecondss > expires, the MP > + Service signals WaitEvent by calling the EFI SignalEvent() functi= on. If > + FailedCpuList is not NULL, its content is available when WaitEven= t is > + signaled. If all APs returned from Procedure prior to the timeout= , > then > + FailedCpuList is set to NULL. If not all APs return from Procedur= e > before > + the timeout, then FailedCpuList is filled in with the list of the= failed > + APs. The buffer is allocated by MP Service Protocol using > AllocatePool(). > + It is the caller's responsibility to free the buffer with FreePoo= l() > service. > + -# This invocation of SignalEvent() function informs the caller that > invoked > + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the > APs completed > + the specified task or a timeout occurred. The contents of > FailedCpuList > + can be examined to determine which APs did not complete the > specified task > + prior to the timeout. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[in] Procedure A pointer to the function to be > run on > + enabled APs of the system. > See type > + EFI_AP_PROCEDURE. > + @param[in] SingleThread If TRUE, then all the enabled > APs execute > + the function specified by > Procedure one by > + one, in ascending order of > processor handle > + number. If FALSE, then all > the enabled APs > + execute the function > specified by Procedure > + simultaneously. > + @param[in] WaitEvent The event created by the > caller with CreateEvent() > + service. If it is NULL, then > execute in > + blocking mode. BSP waits > until all APs finish > + or TimeoutInMicroseconds > expires. If it's > + not NULL, then execute in > non-blocking mode. > + BSP requests the function > specified by > + Procedure to be started on > all the enabled > + APs, and go on executing > immediately. If > + all return from Procedure, or > TimeoutInMicroseconds > + expires, this event is signaled. > The BSP > + can use the CheckEvent() or > WaitForEvent() > + services to check the state of > event. Type > + EFI_EVENT is defined in > CreateEvent() in > + the Unified Extensible > Firmware Interface > + Specification. > + @param[in] TimeoutInMicroseconds Indicates the time limit in > microseconds for > + APs to return from Procedure, > either for > + blocking or non-blocking > mode. Zero means > + infinity. If the timeout > expires before > + all APs return from > Procedure, then Procedure > + on the failed APs is > terminated. All enabled > + APs are available for next > function assigned > + by > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + or > EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). > + If the timeout expires in > blocking mode, > + BSP returns EFI_TIMEOUT. > If the timeout > + expires in non-blocking mode, > WaitEvent > + is signaled with > SignalEvent(). > + @param[in] ProcedureArgument The parameter passed into > Procedure for > + all APs. > + @param[out] FailedCpuList If NULL, this parameter is > ignored. Otherwise, > + if all APs finish successfully, > then its > + content is set to NULL. If not > all APs > + finish before timeout expires, > then its > + content is set to address of > the buffer > + holding handle numbers of > the failed APs. > + The buffer is allocated by MP > Service Protocol, > + and it's the caller's > responsibility to > + free the buffer with > FreePool() service. > + In blocking mode, it is ready > for consumption > + when the call returns. In > non-blocking mode, > + it is ready when WaitEvent is > signaled. The > + list of failed CPU is > terminated by > + END_OF_CPU_LIST. > + > + @retval EFI_SUCCESS In blocking mode, all APs have > finished before > + the timeout expired. > + @retval EFI_SUCCESS In non-blocking mode, function has > been dispatched > + to all enabled APs. > + @retval EFI_UNSUPPORTED A non-blocking mode request was > made after the > + UEFI event > EFI_EVENT_GROUP_READY_TO_BOOT was > + signaled. > + @retval EFI_DEVICE_ERROR Caller processor is AP. > + @retval EFI_NOT_STARTED No enabled APs exist in the > system. > + @retval EFI_NOT_READY Any enabled APs are busy. > + @retval EFI_TIMEOUT In blocking mode, the timeout > expired before > + all enabled APs have finished. > + @retval EFI_INVALID_PARAMETER Procedure is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +StartupAllAPs ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN EFI_AP_PROCEDURE Procedure, > + IN BOOLEAN SingleThread, > + IN EFI_EVENT WaitEvent > OPTIONAL, > + IN UINTN TimeoutInMicroseconds, > + IN VOID *ProcedureArgument > OPTIONAL, > + OUT UINTN **FailedCpuList > OPTIONAL > + ) > +{ > + return MpInitLibStartupAllAPs ( > + Procedure, > + SingleThread, > + WaitEvent, > + TimeoutInMicroseconds, > + ProcedureArgument, > + FailedCpuList > + ); > +} > + > +/** > + This service lets the caller get one enabled AP to execute a caller-pr= ovided > + function. The caller can request the BSP to either wait for the comple= tion > + of the AP or just proceed with the next task by using the EFI event > mechanism. > + See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on > non-blocking > + execution support. This service may only be called from the BSP. > + > + This function is used to dispatch one enabled AP to the function speci= fied > by > + Procedure passing in the argument specified by ProcedureArgument. If > WaitEvent > + is NULL, execution is in blocking mode. The BSP waits until the AP fin= ishes > or > + TimeoutInMicroSecondss expires. Otherwise, execution is in non-blockin= g > mode. > + BSP proceeds to the next task without waiting for the AP. If a non-blo= cking > mode > + is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT > is signaled, > + then EFI_UNSUPPORTED must be returned. > + > + If the timeout specified by TimeoutInMicroseconds expires before the A= P > returns > + from Procedure, then execution of Procedure by the AP is terminated. T= he > AP is > + available for subsequent calls to > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and > + EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[in] Procedure A pointer to the function to be > run on the > + designated AP of the system. > See type > + EFI_AP_PROCEDURE. > + @param[in] ProcessorNumber The handle number of the AP. > The range is > + from 0 to the total number of > logical > + processors minus 1. The > total number of > + logical processors can be > retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + @param[in] WaitEvent The event created by the > caller with CreateEvent() > + service. If it is NULL, then > execute in > + blocking mode. BSP waits > until this AP finish > + or TimeoutInMicroSeconds > expires. If it's > + not NULL, then execute in > non-blocking mode. > + BSP requests the function > specified by > + Procedure to be started on > this AP, > + and go on executing > immediately. If this AP > + return from Procedure or > TimeoutInMicroSeconds > + expires, this event is signaled. > The BSP > + can use the CheckEvent() or > WaitForEvent() > + services to check the state of > event. Type > + EFI_EVENT is defined in > CreateEvent() in > + the Unified Extensible > Firmware Interface > + Specification. > + @param[in] TimeoutInMicroseconds Indicates the time limit in > microseconds for > + this AP to finish this > Procedure, either for > + blocking or non-blocking > mode. Zero means > + infinity. If the timeout > expires before > + this AP returns from > Procedure, then Procedure > + on the AP is terminated. The > + AP is available for next > function assigned > + by > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + or > EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). > + If the timeout expires in > blocking mode, > + BSP returns EFI_TIMEOUT. > If the timeout > + expires in non-blocking mode, > WaitEvent > + is signaled with > SignalEvent(). > + @param[in] ProcedureArgument The parameter passed into > Procedure on the > + specified AP. > + @param[out] Finished If NULL, this parameter is > ignored. In > + blocking mode, this > parameter is ignored. > + In non-blocking mode, if AP > returns from > + Procedure before the > timeout expires, its > + content is set to TRUE. > Otherwise, the > + value is set to FALSE. The > caller can > + determine if the AP returned > from Procedure > + by evaluating this value. > + > + @retval EFI_SUCCESS In blocking mode, specified AP > finished before > + the timeout expires. > + @retval EFI_SUCCESS In non-blocking mode, the function > has been > + dispatched to specified AP. > + @retval EFI_UNSUPPORTED A non-blocking mode request was > made after the > + UEFI event > EFI_EVENT_GROUP_READY_TO_BOOT was > + signaled. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_TIMEOUT In blocking mode, the timeout > expired before > + the specified AP has finished. > + @retval EFI_NOT_READY The specified AP is busy. > + @retval EFI_NOT_FOUND The processor with the handle > specified by > + ProcessorNumber does not exist. > + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP > or disabled AP. > + @retval EFI_INVALID_PARAMETER Procedure is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +StartupThisAP ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN EFI_AP_PROCEDURE Procedure, > + IN UINTN ProcessorNumber, > + IN EFI_EVENT WaitEvent > OPTIONAL, > + IN UINTN TimeoutInMicroseconds, > + IN VOID *ProcedureArgument > OPTIONAL, > + OUT BOOLEAN *Finished > OPTIONAL > + ) > +{ > + return MpInitLibStartupThisAP ( > + Procedure, > + ProcessorNumber, > + WaitEvent, > + TimeoutInMicroseconds, > + ProcedureArgument, > + Finished > + ); > +} > + > +/** > + This service switches the requested AP to be the BSP from that point > onward. > + This service changes the BSP for all purposes. This call can only be > performed > + by the current BSP. > + > + This service switches the requested AP to be the BSP from that point > onward. > + This service changes the BSP for all purposes. The new BSP can take ov= er > the > + execution of the old BSP and continue seamlessly from where the old on= e > left > + off. This service may not be supported after the UEFI Event > EFI_EVENT_GROUP_READY_TO_BOOT > + is signaled. > + > + If the BSP cannot be switched prior to the return from this service, t= hen > + EFI_UNSUPPORTED must be returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL instance. > + @param[in] ProcessorNumber The handle number of AP that is to > become the new > + BSP. The range is from 0 to the total > number of > + logical processors minus 1. The total > number of > + logical processors can be retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed > as an > + enabled AP. Otherwise, it will be > disabled. > + > + @retval EFI_SUCCESS BSP successfully switched. > + @retval EFI_UNSUPPORTED Switching the BSP cannot be > completed prior to > + this service returning. > + @retval EFI_UNSUPPORTED Switching the BSP is not > supported. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_NOT_FOUND The processor with the handle > specified by > + ProcessorNumber does not exist. > + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the > current BSP or > + a disabled AP. > + @retval EFI_NOT_READY The specified AP is busy. > + > +**/ > +EFI_STATUS > +EFIAPI > +SwitchBSP ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN UINTN ProcessorNumber, > + IN BOOLEAN EnableOldBSP > + ) > +{ > + return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP); > +} > + > +/** > + This service lets the caller enable or disable an AP from this point o= nward. > + This service may only be called from the BSP. > + > + This service allows the caller enable or disable an AP from this point > onward. > + The caller can optionally specify the health status of the AP by Healt= h. If > + an AP is being disabled, then the state of the disabled AP is > implementation > + dependent. If an AP is enabled, then the implementation must guarantee > that a > + complete initialization sequence is performed on the AP, so the AP is = in a > state > + that is compatible with an MP operating system. This service may not b= e > supported > + after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. > + > + If the enable or disable AP operation cannot be completed prior to the > return > + from this service, then EFI_UNSUPPORTED must be returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL instance. > + @param[in] ProcessorNumber The handle number of AP. > + The range is from 0 to the total > number of > + logical processors minus 1. The total > number of > + logical processors can be retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + @param[in] EnableAP Specifies the new state for the > processor for > + enabled, FALSE for disabled. > + @param[in] HealthFlag If not NULL, a pointer to a value that > specifies > + the new health status of the AP. This > flag > + corresponds to StatusFlag defined in > + > EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only > + the > PROCESSOR_HEALTH_STATUS_BIT is used. All other > + bits are ignored. If it is NULL, this > parameter > + is ignored. > + > + @retval EFI_SUCCESS The specified AP was enabled or > disabled successfully. > + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot > be completed > + prior to this service returning. > + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not > supported. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_NOT_FOUND Processor with the handle > specified by ProcessorNumber > + does not exist. > + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the > BSP. > + > +**/ > +EFI_STATUS > +EFIAPI > +EnableDisableAP ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN UINTN ProcessorNumber, > + IN BOOLEAN EnableAP, > + IN UINT32 *HealthFlag OPTIONAL > + ) > +{ > + return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, > HealthFlag); > +} > + > +/** > + This return the handle number for the calling processor. This service= may > be > + called from the BSP and APs. > + > + This service returns the processor handle number for the calling proce= ssor. > + The returned value is in the range from 0 to the total number of logic= al > + processors minus 1. The total number of logical processors can be > retrieved > + with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This > service may be > + called from the BSP and APs. If ProcessorNumber is NULL, then > EFI_INVALID_PARAMETER > + is returned. Otherwise, the current processors handle number is return= ed > in > + ProcessorNumber, and EFI_SUCCESS is returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL instance. > + @param[out] ProcessorNumber Pointer to the handle number of AP. > + The range is from 0 to the total > number of > + logical processors minus 1. The total > number of > + logical processors can be retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + > + @retval EFI_SUCCESS The current processor handle > number was returned > + in ProcessorNumber. > + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +WhoAmI ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + OUT UINTN *ProcessorNumber > + ) > +{ > + return MpInitLibWhoAmI (ProcessorNumber); > +} > + > +/** > + Initialize Multi-processor support. > +**/ > +VOID > +InitializeMpSupport ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN NumberOfProcessors; > + UINTN NumberOfEnabledProcessors; > + > + // > + // Wakeup APs to do initialization > + // > + Status =3D MpInitLibInitialize (); > + ASSERT_EFI_ERROR (Status); > + > + MpInitLibGetNumberOfProcessors (&NumberOfProcessors, > &NumberOfEnabledProcessors); > + mNumberOfProcessors =3D NumberOfProcessors; > + DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", > mNumberOfProcessors)); > + > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &mMpServiceHandle, > + &gEfiMpServiceProtocolGuid, > + &mMpServicesTemplate, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > +} > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/CpuMp.h > b/UefiCpuPkg/CpuDxeLoongArch64/CpuMp.h > new file mode 100644 > index 0000000000..7994305206 > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/CpuMp.h > @@ -0,0 +1,471 @@ > +/** @file > + CPU DXE MP support > + > + Copyright (c) 2023, Loongson Technology Corporation Limited. All right= s > reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef CPU_MP_H_ > +#define CPU_MP_H_ > + > +#define SMP_BOOT_CPU BIT0 > + > +/** > + Initialize Multi-processor support. > + > +**/ > +VOID > +InitializeMpSupport ( > + VOID > + ); > + > +/** > + This service retrieves the number of logical processor in the platform > + and the number of those logical processors that are enabled on this bo= ot. > + This service may only be called from the BSP. > + > + This function is used to retrieve the following information: > + - The number of logical processors that are present in the system. > + - The number of enabled logical processors in the system at the inst= ant > + this call is made. > + > + Because MP Service Protocol provides services to enable and disable > processors > + dynamically, the number of enabled logical processors may vary during = the > + course of a boot session. > + > + If this service is called from an AP, then EFI_DEVICE_ERROR is returne= d. > + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then > + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of > processors > + is returned in NumberOfProcessors, the number of currently enabled > processor > + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[out] NumberOfProcessors Pointer to the total > number of logical > + processors in the > system, including the BSP > + and disabled APs. > + @param[out] NumberOfEnabledProcessors Pointer to the number of > enabled logical > + processors that exist in > system, including > + the BSP. > + > + @retval EFI_SUCCESS The number of logical processors > and enabled > + logical processors was retrieved. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. > + @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is > NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetNumberOfProcessors ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + OUT UINTN *NumberOfProcessors, > + OUT UINTN *NumberOfEnabledProcessors > + ); > + > +/** > + Gets detailed MP-related information on the requested processor at the > + instant this call is made. This service may only be called from the BS= P. > + > + This service retrieves detailed MP-related information about any > processor > + on the platform. Note the following: > + - The processor information may change during the course of a boot > session. > + - The information presented here is entirely MP related. > + > + Information regarding the number of caches and their sizes, frequency = of > operation, > + slot numbers is all considered platform-related information and is not > provided > + by this service. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[in] ProcessorNumber The handle number of processor. > + @param[out] ProcessorInfoBuffer A pointer to the buffer where > information for > + the requested processor is > deposited. > + > + @retval EFI_SUCCESS Processor information was > returned. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. > + @retval EFI_NOT_FOUND The processor with the handle > specified by > + ProcessorNumber does not exist > in the platform. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetProcessorInfo ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN UINTN ProcessorNumber, > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer > + ); > + > +/** > + This service executes a caller provided function on all enabled APs. A= Ps > can > + run either simultaneously or one at a time in sequence. This service > supports > + both blocking and non-blocking requests. The non-blocking requests use > EFI > + events so the BSP can detect when the APs have finished. This service > may only > + be called from the BSP. > + > + This function is used to dispatch all the enabled APs to the function > specified > + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is > returned > + immediately and Procedure is not started on any AP. > + > + If SingleThread is TRUE, all the enabled APs execute the function spec= ified > by > + Procedure one by one, in ascending order of processor handle number. > Otherwise, > + all the enabled APs execute the function specified by Procedure > simultaneously. > + > + If WaitEvent is NULL, execution is in blocking mode. The BSP waits unt= il all > + APs finish or TimeoutInMicroseconds expires. Otherwise, execution is i= n > non-blocking > + mode, and the BSP returns from this service without waiting for APs. I= f a > + non-blocking mode is requested after the UEFI Event > EFI_EVENT_GROUP_READY_TO_BOOT > + is signaled, then EFI_UNSUPPORTED must be returned. > + > + If the timeout specified by TimeoutInMicroseconds expires before all A= Ps > return > + from Procedure, then Procedure on the failed APs is terminated. All > enabled APs > + are always available for further calls to > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not > NULL, its > + content points to the list of processor handle numbers in which Proced= ure > was > + terminated. > + > + Note: It is the responsibility of the consumer of the > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + to make sure that the nature of the code that is executed on the BSP a= nd > the > + dispatched APs is well controlled. The MP Services Protocol does not > guarantee > + that the Procedure function is MP-safe. Hence, the tasks that can be r= un in > + parallel are limited to certain independent tasks and well-controlled > exclusive > + code. EFI services and protocols may not be called by APs unless other= wise > + specified. > + > + In blocking execution mode, BSP waits until all APs finish or > + TimeoutInMicroseconds expires. > + > + In non-blocking execution mode, BSP is freed to return to the caller a= nd > then > + proceed to the next task without having to wait for APs. The following > + sequence needs to occur in a non-blocking execution mode: > + > + -# The caller that intends to use this MP Services Protocol in > non-blocking > + mode creates WaitEvent by calling the EFI CreateEvent() service. > The caller > + invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the > parameter WaitEvent > + is not NULL, then StartupAllAPs() executes in non-blocking mode. = It > requests > + the function specified by Procedure to be started on all the enab= led > APs, > + and releases the BSP to continue with other tasks. > + -# The caller can use the CheckEvent() and WaitForEvent() services t= o > check > + the state of the WaitEvent created in step 1. > + -# When the APs complete their task or TimeoutInMicroSecondss > expires, the MP > + Service signals WaitEvent by calling the EFI SignalEvent() functi= on. If > + FailedCpuList is not NULL, its content is available when WaitEven= t is > + signaled. If all APs returned from Procedure prior to the timeout= , > then > + FailedCpuList is set to NULL. If not all APs return from Procedur= e > before > + the timeout, then FailedCpuList is filled in with the list of the= failed > + APs. The buffer is allocated by MP Service Protocol using > AllocatePool(). > + It is the caller's responsibility to free the buffer with FreePoo= l() > service. > + -# This invocation of SignalEvent() function informs the caller that > invoked > + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the > APs completed > + the specified task or a timeout occurred. The contents of > FailedCpuList > + can be examined to determine which APs did not complete the > specified task > + prior to the timeout. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[in] Procedure A pointer to the function to be > run on > + enabled APs of the system. > See type > + EFI_AP_PROCEDURE. > + @param[in] SingleThread If TRUE, then all the enabled > APs execute > + the function specified by > Procedure one by > + one, in ascending order of > processor handle > + number. If FALSE, then all > the enabled APs > + execute the function > specified by Procedure > + simultaneously. > + @param[in] WaitEvent The event created by the > caller with CreateEvent() > + service. If it is NULL, then > execute in > + blocking mode. BSP waits > until all APs finish > + or TimeoutInMicroseconds > expires. If it's > + not NULL, then execute in > non-blocking mode. > + BSP requests the function > specified by > + Procedure to be started on > all the enabled > + APs, and go on executing > immediately. If > + all return from Procedure, or > TimeoutInMicroseconds > + expires, this event is signaled. > The BSP > + can use the CheckEvent() or > WaitForEvent() > + services to check the state of > event. Type > + EFI_EVENT is defined in > CreateEvent() in > + the Unified Extensible > Firmware Interface > + Specification. > + @param[in] TimeoutInMicroseconds Indicates the time limit in > microseconds for > + APs to return from Procedure, > either for > + blocking or non-blocking > mode. Zero means > + infinity. If the timeout > expires before > + all APs return from > Procedure, then Procedure > + on the failed APs is > terminated. All enabled > + APs are available for next > function assigned > + by > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + or > EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). > + If the timeout expires in > blocking mode, > + BSP returns EFI_TIMEOUT. > If the timeout > + expires in non-blocking mode, > WaitEvent > + is signaled with > SignalEvent(). > + @param[in] ProcedureArgument The parameter passed into > Procedure for > + all APs. > + @param[out] FailedCpuList If NULL, this parameter is > ignored. Otherwise, > + if all APs finish successfully, > then its > + content is set to NULL. If not > all APs > + finish before timeout expires, > then its > + content is set to address of > the buffer > + holding handle numbers of > the failed APs. > + The buffer is allocated by MP > Service Protocol, > + and it's the caller's > responsibility to > + free the buffer with > FreePool() service. > + In blocking mode, it is ready > for consumption > + when the call returns. In > non-blocking mode, > + it is ready when WaitEvent is > signaled. The > + list of failed CPU is > terminated by > + END_OF_CPU_LIST. > + > + @retval EFI_SUCCESS In blocking mode, all APs have > finished before > + the timeout expired. > + @retval EFI_SUCCESS In non-blocking mode, function has > been dispatched > + to all enabled APs. > + @retval EFI_UNSUPPORTED A non-blocking mode request was > made after the > + UEFI event > EFI_EVENT_GROUP_READY_TO_BOOT was > + signaled. > + @retval EFI_DEVICE_ERROR Caller processor is AP. > + @retval EFI_NOT_STARTED No enabled APs exist in the > system. > + @retval EFI_NOT_READY Any enabled APs are busy. > + @retval EFI_TIMEOUT In blocking mode, the timeout > expired before > + all enabled APs have finished. > + @retval EFI_INVALID_PARAMETER Procedure is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +StartupAllAPs ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN EFI_AP_PROCEDURE Procedure, > + IN BOOLEAN SingleThread, > + IN EFI_EVENT WaitEvent > OPTIONAL, > + IN UINTN TimeoutInMicroseconds, > + IN VOID *ProcedureArgument > OPTIONAL, > + OUT UINTN **FailedCpuList > OPTIONAL > + ); > + > +/** > + This service lets the caller get one enabled AP to execute a caller-pr= ovided > + function. The caller can request the BSP to either wait for the comple= tion > + of the AP or just proceed with the next task by using the EFI event > mechanism. > + See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on > non-blocking > + execution support. This service may only be called from the BSP. > + > + This function is used to dispatch one enabled AP to the function speci= fied > by > + Procedure passing in the argument specified by ProcedureArgument. If > WaitEvent > + is NULL, execution is in blocking mode. The BSP waits until the AP fin= ishes > or > + TimeoutInMicroSecondss expires. Otherwise, execution is in non-blockin= g > mode. > + BSP proceeds to the next task without waiting for the AP. If a non-blo= cking > mode > + is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT > is signaled, > + then EFI_UNSUPPORTED must be returned. > + > + If the timeout specified by TimeoutInMicroseconds expires before the A= P > returns > + from Procedure, then execution of Procedure by the AP is terminated. T= he > AP is > + available for subsequent calls to > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and > + EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL > + instance. > + @param[in] Procedure A pointer to the function to be > run on > + enabled APs of the system. > See type > + EFI_AP_PROCEDURE. > + @param[in] ProcessorNumber The handle number of the AP. > The range is > + from 0 to the total number of > logical > + processors minus 1. The > total number of > + logical processors can be > retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + @param[in] WaitEvent The event created by the > caller with CreateEvent() > + service. If it is NULL, then > execute in > + blocking mode. BSP waits > until all APs finish > + or TimeoutInMicroseconds > expires. If it's > + not NULL, then execute in > non-blocking mode. > + BSP requests the function > specified by > + Procedure to be started on > all the enabled > + APs, and go on executing > immediately. If > + all return from Procedure or > TimeoutInMicroseconds > + expires, this event is signaled. > The BSP > + can use the CheckEvent() or > WaitForEvent() > + services to check the state of > event. Type > + EFI_EVENT is defined in > CreateEvent() in > + the Unified Extensible > Firmware Interface > + Specification. > + @param[in] TimeoutInMicroseconds Indicates the time limit in > microseconds for > + APs to return from Procedure, > either for > + blocking or non-blocking > mode. Zero means > + infinity. If the timeout > expires before > + all APs return from > Procedure, then Procedure > + on the failed APs is > terminated. All enabled > + APs are available for next > function assigned > + by > EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() > + or > EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). > + If the timeout expires in > blocking mode, > + BSP returns EFI_TIMEOUT. > If the timeout > + expires in non-blocking mode, > WaitEvent > + is signaled with > SignalEvent(). > + @param[in] ProcedureArgument The parameter passed into > Procedure for > + all APs. > + @param[out] Finished If NULL, this parameter is > ignored. In > + blocking mode, this > parameter is ignored. > + In non-blocking mode, if AP > returns from > + Procedure before the > timeout expires, its > + content is set to TRUE. > Otherwise, the > + value is set to FALSE. The > caller can > + determine if the AP returned > from Procedure > + by evaluating this value. > + > + @retval EFI_SUCCESS In blocking mode, specified AP > finished before > + the timeout expires. > + @retval EFI_SUCCESS In non-blocking mode, the function > has been > + dispatched to specified AP. > + @retval EFI_UNSUPPORTED A non-blocking mode request was > made after the > + UEFI event > EFI_EVENT_GROUP_READY_TO_BOOT was > + signaled. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_TIMEOUT In blocking mode, the timeout > expired before > + the specified AP has finished. > + @retval EFI_NOT_READY The specified AP is busy. > + @retval EFI_NOT_FOUND The processor with the handle > specified by > + ProcessorNumber does not exist. > + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP > or disabled AP. > + @retval EFI_INVALID_PARAMETER Procedure is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +StartupThisAP ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN EFI_AP_PROCEDURE Procedure, > + IN UINTN ProcessorNumber, > + IN EFI_EVENT WaitEvent > OPTIONAL, > + IN UINTN TimeoutInMicroseconds, > + IN VOID *ProcedureArgument > OPTIONAL, > + OUT BOOLEAN *Finished > OPTIONAL > + ); > + > +/** > + This service switches the requested AP to be the BSP from that point > onward. > + This service changes the BSP for all purposes. This call can only be > performed > + by the current BSP. > + > + This service switches the requested AP to be the BSP from that point > onward. > + This service changes the BSP for all purposes. The new BSP can take ov= er > the > + execution of the old BSP and continue seamlessly from where the old on= e > left > + off. This service may not be supported after the UEFI Event > EFI_EVENT_GROUP_READY_TO_BOOT > + is signaled. > + > + If the BSP cannot be switched prior to the return from this service, t= hen > + EFI_UNSUPPORTED must be returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL instance. > + @param[in] ProcessorNumber The handle number of AP that is to > become the new > + BSP. The range is from 0 to the total > number of > + logical processors minus 1. The total > number of > + logical processors can be retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed > as an > + enabled AP. Otherwise, it will be > disabled. > + > + @retval EFI_SUCCESS BSP successfully switched. > + @retval EFI_UNSUPPORTED Switching the BSP cannot be > completed prior to > + this service returning. > + @retval EFI_UNSUPPORTED Switching the BSP is not > supported. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_NOT_FOUND The processor with the handle > specified by > + ProcessorNumber does not exist. > + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the > current BSP or > + a disabled AP. > + @retval EFI_NOT_READY The specified AP is busy. > + > +**/ > +EFI_STATUS > +EFIAPI > +SwitchBSP ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN UINTN ProcessorNumber, > + IN BOOLEAN EnableOldBSP > + ); > + > +/** > + This service lets the caller enable or disable an AP from this point o= nward. > + This service may only be called from the BSP. > + > + This service allows the caller enable or disable an AP from this point > onward. > + The caller can optionally specify the health status of the AP by Healt= h. If > + an AP is being disabled, then the state of the disabled AP is > implementation > + dependent. If an AP is enabled, then the implementation must guarantee > that a > + complete initialization sequence is performed on the AP, so the AP is = in a > state > + that is compatible with an MP operating system. This service may not b= e > supported > + after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. > + > + If the enable or disable AP operation cannot be completed prior to the > return > + from this service, then EFI_UNSUPPORTED must be returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL instance. > + @param[in] ProcessorNumber The handle number of AP that is to > become the new > + BSP. The range is from 0 to the total > number of > + logical processors minus 1. The total > number of > + logical processors can be retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + @param[in] EnableAP Specifies the new state for the > processor for > + enabled, FALSE for disabled. > + @param[in] HealthFlag If not NULL, a pointer to a value that > specifies > + the new health status of the AP. This > flag > + corresponds to StatusFlag defined in > + > EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only > + the > PROCESSOR_HEALTH_STATUS_BIT is used. All other > + bits are ignored. If it is NULL, this > parameter > + is ignored. > + > + @retval EFI_SUCCESS The specified AP was enabled or > disabled successfully. > + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot > be completed > + prior to this service returning. > + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not > supported. > + @retval EFI_DEVICE_ERROR The calling processor is an AP. > + @retval EFI_NOT_FOUND Processor with the handle > specified by ProcessorNumber > + does not exist. > + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the > BSP. > + > +**/ > +EFI_STATUS > +EFIAPI > +EnableDisableAP ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + IN UINTN ProcessorNumber, > + IN BOOLEAN EnableAP, > + IN UINT32 *HealthFlag OPTIONAL > + ); > + > +/** > + This return the handle number for the calling processor. This service= may > be > + called from the BSP and APs. > + > + This service returns the processor handle number for the calling proce= ssor. > + The returned value is in the range from 0 to the total number of logic= al > + processors minus 1. The total number of logical processors can be > retrieved > + with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This > service may be > + called from the BSP and APs. If ProcessorNumber is NULL, then > EFI_INVALID_PARAMETER > + is returned. Otherwise, the current processors handle number is return= ed > in > + ProcessorNumber, and EFI_SUCCESS is returned. > + > + @param[in] This A pointer to the > EFI_MP_SERVICES_PROTOCOL instance. > + @param[out] ProcessorNumber The handle number of AP that is to > become the new > + BSP. The range is from 0 to the total > number of > + logical processors minus 1. The total > number of > + logical processors can be retrieved by > + > EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). > + > + @retval EFI_SUCCESS The current processor handle > number was returned > + in ProcessorNumber. > + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. > + > +**/ > +EFI_STATUS > +EFIAPI > +WhoAmI ( > + IN EFI_MP_SERVICES_PROTOCOL *This, > + OUT UINTN *ProcessorNumber > + ); > + > +#endif // CPU_MP_H_ > diff --git a/UefiCpuPkg/CpuDxeLoongArch64/Exception.c > b/UefiCpuPkg/CpuDxeLoongArch64/Exception.c > new file mode 100644 > index 0000000000..fc3823570f > --- /dev/null > +++ b/UefiCpuPkg/CpuDxeLoongArch64/Exception.c > @@ -0,0 +1,150 @@ > +/** @file Exception.c > + > + CPU DXE Module initialization exception instance. > + > + Copyright (c) 2023, Loongson Technology Corporation Limited. All right= s > reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "CpuDxe.h" > +#include > +#include > + > +VOID > +ExceptionEntryStart ( > + VOID > + ); > + > +VOID > +ExceptionEntryEnd ( > + VOID > + ); > + > +/** > + This function registers and enables the handler specified by > InterruptHandler for a processor > + interrupt or exception type specified by InterruptType. If InterruptHa= ndler > is NULL, then the > + handler for the processor interrupt or exception type specified by > InterruptType is uninstalled. > + The installed handler is called once for each processor interrupt or > exception. > + > + @param InterruptType A pointer to the processor's current > interrupt state. Set to TRUE if interrupts > + are enabled and FALSE if interrupts are > disabled. > + @param InterruptHandler A pointer to a function of type > EFI_CPU_INTERRUPT_HANDLER that is called > + when a processor interrupt occurs. If this > parameter is NULL, then the handler > + will be uninstalled. > + > + @retval EFI_SUCCESS The handler for the processor > interrupt was successfully installed or uninstalled. > + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a > handler for InterruptType was > + previously installed. > + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a > handler for InterruptType was not > + previously installed. > + @retval EFI_UNSUPPORTED The interrupt specified by > InterruptType is not supported. > + > +**/ > +EFI_STATUS > +RegisterInterruptHandler ( > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ) > +{ > + return (EFI_STATUS)RegisterCpuInterruptHandler (InterruptType, > InterruptHandler); > +} > + > +/** > + Update the exception start entry code. > + > + @retval EFI_SUCCESS Update the exception start entry code > down. > + @retval EFI_OUT_OF_RESOURCES The start entry code size out of > bounds. > + > +**/ > +EFI_STATUS > +EFIAPI > +UpdateExceptionStartEntry ( > + VOID > + ) > +{ > + EFI_PHYSICAL_ADDRESS ExceptionStartEntry; > + UINTN VectorLength; > + UINTN MaxLength; > + UINTN MaxSizeOfVector; > + > + VectorLength =3D (UINTN)ExceptionEntryEnd - (UINTN)ExceptionEntryStart= ; > + > + // > + // A vector is up to 512 bytes. > + // > + MaxSizeOfVector =3D 512; > + MaxLength =3D (MAX_LOONGARCH_EXCEPTION + > MAX_LOONGARCH_INTERRUPT) * MaxSizeOfVector; > + > + if (VectorLength > MaxLength) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + ExceptionStartEntry =3D PcdGet64 (PcdCpuExceptionVectorBaseAddress); > + > + InvalidateInstructionCacheRange ((VOID *)ExceptionStartEntry, > VectorLength); > + CopyMem ((VOID *)ExceptionStartEntry, (VOID *)ExceptionEntryStart, > VectorLength); > + InvalidateInstructionCacheRange ((VOID *)ExceptionStartEntry, > VectorLength); > + InvalidateDataCache (); > + > + return EFI_SUCCESS; > +} > + > +/** > + Initialize interrupt handling for DXE phase. > + > + @param Cpu A pointer of EFI_CPU_ARCH_PROTOCOL instance. > + > + @return VOID. > + > +**/ > +VOID > +InitializeExceptions ( > + IN EFI_CPU_ARCH_PROTOCOL *Cpu > + ) > +{ > + EFI_STATUS Status; > + EFI_VECTOR_HANDOFF_INFO *VectorInfoList; > + EFI_VECTOR_HANDOFF_INFO *VectorInfo; > + BOOLEAN IrqEnabled; > + > + VectorInfo =3D (EFI_VECTOR_HANDOFF_INFO *)NULL; > + Status =3D EfiGetSystemConfigurationTable > (&gEfiVectorHandoffTableGuid, (VOID **)&VectorInfoList); > + > + if ((Status =3D=3D EFI_SUCCESS) && (VectorInfoList !=3D NULL)) { > + VectorInfo =3D VectorInfoList; > + } > + > + // > + // Disable interrupts > + // > + Cpu->GetInterruptState (Cpu, &IrqEnabled); > + if (IrqEnabled) { > + Cpu->DisableInterrupt (Cpu); > + } > + > + // > + // Update the Exception Start Entry code to point into CpuDxe. > + // > + Status =3D UpdateExceptionStartEntry (); > + if (EFI_ERROR (Status)) { > + DebugPrint (EFI_D_ERROR, "[%a]: Exception start entry code out of > bounds!\n", __func__); > + ASSERT_EFI_ERROR (Status); > + } > + > + // > + // Intialize the CpuExceptionHandlerLib so we take over the exception > vector table from the DXE Core > + // > + Status =3D InitializeCpuExceptionHandlers (VectorInfo); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Enable interrupts > + // > + DebugPrint (EFI_D_INFO, "InitializeExceptions,IrqEnabled =3D %x\n", > IrqEnabled); > + if (!IrqEnabled) { > + Status =3D Cpu->EnableInterrupt (Cpu); > + } > + > + ASSERT_EFI_ERROR (Status); > +} > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc > index da49031877..15854dafef 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -213,6 +213,7 @@ > UefiCpuPkg/Library/LoongArch64CpuMmuLib/DxeCpuMmuLib.inf > UefiCpuPkg/Library/LoongArch64MpInitLib/PeiMpInitLib.inf > UefiCpuPkg/Library/LoongArch64MpInitLib/DxeMpInitLib.inf > + UefiCpuPkg/CpuDxeLoongArch64/CpuDxe.inf >=20 > [BuildOptions] > *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES > -- > 2.27.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#112696): https://edk2.groups.io/g/devel/message/112696 Mute This Topic: https://groups.io/mt/103129102/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/19134562= 12/xyzzy [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-