From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.61]) by mx.groups.io with SMTP id smtpd.web09.322.1582676792496122244 for ; Tue, 25 Feb 2020 16:26:32 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=OBaypxPX; spf=pass (domain: redhat.com, ip: 205.139.110.61, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1582676791; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=07TNVMPklpdC3Hset6VvApKwAcTVrxAQBsbrhncYLc4=; b=OBaypxPXJkf2TB0Xv96HfmXLy2TSt5EdEDYCFj2r3En8I8C48yzoN9bwv7jrDmHJMWGh4z laVlb6F/8MTTj/bG0fS6vHdzKb0X2on0tjUKF6KZzjbO18GCSMhXW+9NgjpqyfLHAKzp8p Cwp7T6SP2iH37VP9Fp81b5blSbyoC6U= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-360-aP-vhX6PNK-jlsyxwc5kkg-1; Tue, 25 Feb 2020 19:26:30 -0500 X-MC-Unique: aP-vhX6PNK-jlsyxwc5kkg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D2A1A6125B; Wed, 26 Feb 2020 00:26:28 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-117-104.ams2.redhat.com [10.36.117.104]) by smtp.corp.redhat.com (Postfix) with ESMTP id C1BB192D03; Wed, 26 Feb 2020 00:26:15 +0000 (UTC) Subject: Re: [edk2-devel] [PATCH v2 4/5] ArmVirtPkg: implement ArmVirtPsciResetSystemPeiLib To: devel@edk2.groups.io, ard.biesheuvel@linaro.org Cc: eric.auger@redhat.com, philmd@redhat.com, marcandre.lureau@redhat.com, stefanb@linux.ibm.com, leif@nuviainc.com References: <20200225104449.22453-1-ard.biesheuvel@linaro.org> <20200225104449.22453-5-ard.biesheuvel@linaro.org> From: "Laszlo Ersek" Message-ID: <41485cfc-0fac-48b7-f28b-d2f4c0d5ec86@redhat.com> Date: Wed, 26 Feb 2020 01:26:14 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20200225104449.22453-5-ard.biesheuvel@linaro.org> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit On 02/25/20 11:44, Ard Biesheuvel wrote: > Implement a ArmVirtPkg specific version of the PSCI ResetSystemLib that > is usable in the PEI phase, as the existing one relies on the FDT client > protocol, making it unsuitable. > > Note that accessing the device tree passed by QEMU via its initial base > address is guaranteed to be safe at any time during the PEI phase, so we > can defer discovery of the PSCI method until the time the reset library > is actually invoked (which is rarely) > > Signed-off-by: Ard Biesheuvel > --- > ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c | 232 ++++++++++++++++++++ > ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf | 39 ++++ > 2 files changed, 271 insertions(+) > > diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c > new file mode 100644 > index 000000000000..394a04e3c384 > --- /dev/null > +++ b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c > @@ -0,0 +1,232 @@ > +/** @file > + Reset System lib using PSCI hypervisor or secure monitor calls > + > + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
> + Copyright (c) 2013, ARM Ltd. All rights reserved.
> + Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.
> + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +typedef enum { > + PsciMethodUnknown, > + PsciMethodSmc, > + PsciMethodHvc, > +} PSCI_METHOD; > + > +STATIC > +PSCI_METHOD > +DiscoverPsciMethod ( > + VOID > + ) > +{ > + VOID *DeviceTreeBase; > + INT32 Node, Prev; > + INT32 Len; > + CONST CHAR8 *Compatible; > + CONST CHAR8 *CompatibleItem; > + CONST VOID *Prop; > + > + DeviceTreeBase = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); > + ASSERT (fdt_check_header (DeviceTreeBase) == 0); > + > + // > + // Enumerate all FDT nodes looking for the PSCI node and capture the method > + // > + for (Prev = 0;; Prev = Node) { > + Node = fdt_next_node (DeviceTreeBase, Prev, NULL); > + if (Node < 0) { > + break; > + } > + > + Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len); > + if (Compatible == NULL) { > + continue; > + } > + > + // > + // Iterate over the NULL-separated items in the compatible string > + // > + for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len; > + CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) { > + > + if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) { > + continue; > + } > + > + Prop = fdt_getprop (DeviceTreeBase, Node, "method", NULL); > + if (!Prop) { > + DEBUG ((DEBUG_ERROR, "%a: Missing PSCI method property\n", > + __FUNCTION__)); > + return PsciMethodUnknown; > + } > + > + if (AsciiStrnCmp (Prop, "hvc", 3) == 0) { > + return PsciMethodHvc; > + } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) { > + return PsciMethodSmc; > + } else { > + DEBUG ((DEBUG_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__, > + Prop)); > + return PsciMethodUnknown; > + } > + } > + } > + return PsciMethodUnknown; > +} > + > +STATIC > +VOID > +PerformPsciAction ( > + IN UINTN Arg0 > + ) > +{ > + ARM_SMC_ARGS ArmSmcArgs; > + ARM_HVC_ARGS ArmHvcArgs; > + > + ArmSmcArgs.Arg0 = Arg0; > + ArmHvcArgs.Arg0 = Arg0; > + > + switch (DiscoverPsciMethod ()) { > + case PsciMethodHvc: > + ArmCallHvc (&ArmHvcArgs); > + break; > + > + case PsciMethodSmc: > + ArmCallSmc (&ArmSmcArgs); > + break; > + > + default: > + DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__)); > + ASSERT (FALSE); > + } > +} > + > +/** > + This function causes a system-wide reset (cold reset), in which > + all circuitry within the system returns to its initial state. This type of reset > + is asynchronous to system operation and operates without regard to > + cycle boundaries. > + > + If this function returns, it means that the system does not support cold reset. > +**/ > +VOID > +EFIAPI > +ResetCold ( > + VOID > + ) > +{ > + // Send a PSCI 0.2 SYSTEM_RESET command > + PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_RESET); > +} > + > +/** > + This function causes a system-wide initialization (warm reset), in which all processors > + are set to their initial state. Pending cycles are not corrupted. > + > + If this function returns, it means that the system does not support warm reset. > +**/ > +VOID > +EFIAPI > +ResetWarm ( > + VOID > + ) > +{ > + // Map a warm reset into a cold reset > + ResetCold (); > +} > + > +/** > + This function causes the system to enter a power state equivalent > + to the ACPI G2/S5 or G3 states. > + > + If this function returns, it means that the system does not support shutdown reset. > +**/ > +VOID > +EFIAPI > +ResetShutdown ( > + VOID > + ) > +{ > + // Send a PSCI 0.2 SYSTEM_OFF command > + PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_OFF); > +} > + > +/** > + This function causes a systemwide reset. The exact type of the reset is > + defined by the EFI_GUID that follows the Null-terminated Unicode string passed > + into ResetData. If the platform does not recognize the EFI_GUID in ResetData > + the platform must pick a supported reset type to perform.The platform may > + optionally log the parameters from any non-normal reset that occurs. > + > + @param[in] DataSize The size, in bytes, of ResetData. > + @param[in] ResetData The data buffer starts with a Null-terminated string, > + followed by the EFI_GUID. > +**/ > +VOID > +EFIAPI > +ResetPlatformSpecific ( > + IN UINTN DataSize, > + IN VOID *ResetData > + ) > +{ > + // Map the platform specific reset as reboot > + ResetCold (); > +} > + > +/** > + The ResetSystem function resets the entire platform. > + > + @param[in] ResetType The type of reset to perform. > + @param[in] ResetStatus The status code for the reset. > + @param[in] DataSize The size, in bytes, of ResetData. > + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown > + the data buffer starts with a Null-terminated string, optionally > + followed by additional binary data. The string is a description > + that the caller may use to further indicate the reason for the > + system reset. > +**/ > +VOID > +EFIAPI > +ResetSystem ( > + IN EFI_RESET_TYPE ResetType, > + IN EFI_STATUS ResetStatus, > + IN UINTN DataSize, > + IN VOID *ResetData OPTIONAL > + ) > +{ > + switch (ResetType) { > + case EfiResetWarm: > + ResetWarm (); > + break; > + > + case EfiResetCold: > + ResetCold (); > + break; > + > + case EfiResetShutdown: > + ResetShutdown (); > + return; > + > + case EfiResetPlatformSpecific: > + ResetPlatformSpecific (DataSize, ResetData); > + return; > + > + default: > + return; > + } > +} > diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf > new file mode 100644 > index 000000000000..3a65706e8dc6 > --- /dev/null > +++ b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf > @@ -0,0 +1,39 @@ > +#/** @file > +# Reset System lib using PSCI hypervisor or secure monitor calls > +# > +# Copyright (c) 2008, Apple Inc. All rights reserved.
> +# Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +# > +#**/ > + > +[Defines] > + INF_VERSION = 1.27 > + BASE_NAME = ArmVirtPsciResetSystemPeiLib > + FILE_GUID = 551cfb98-c185-41a3-86bf-8cdb7e2a530c > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = ResetSystemLib|PEIM > + > +[Sources] > + ArmVirtPsciResetSystemPeiLib.c > + > +[Packages] > + ArmPkg/ArmPkg.dec > + ArmVirtPkg/ArmVirtPkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + > +[LibraryClasses] > + ArmSmcLib > + ArmHvcLib > + BaseLib > + DebugLib > + FdtLib > + HobLib > + > +[Pcd] > + gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress > Acked-by: Laszlo Ersek