On 12/16/14 13:18, Olivier Martin wrote: > Reviewed-By: Olivier Martin <[email protected]>
Thanks. I had to rework the qemu patchset almost from the ground up, and this patch needs to be updated too. (The fw_cfg registers will be big endian. Long discussion on qemu-devel.) Thanks! Laszlo > >> -----Original Message----- >> From: Laszlo Ersek [mailto:[email protected]] >> Sent: 11 December 2014 02:46 >> To: [email protected]; [email protected]; >> [email protected]; [email protected] >> Subject: [edk2] [PATCH v3 02/13] ArmVirtualizationPkg: introduce >> QemuFwCfgLib instance for DXE drivers >> >> After reviewing OvmfPkg's use of its own QemuFwCfgLib instances, it is >> clear that its only pre-DXE fw_cfg dependency concerns S3 support (the >> QemuFwCfgS3Enabled() call in "PlatformPei/Platform.c"). >> >> For ARM guests, S3 is in the distant future, but we can see several >> shorter term applications for fw_cfg that all reside in DXE: >> - controlling boot order (to be implemented in PlatformBdsLib for Intel >> BDS), >> - supporting -kernel / -initrd / -append boot on QEMU (to be >> implemented >> in PlatformBdsLib for Intel BDS, similarly), >> - loading and linking ACPI tables, >> - installing SMBIOS tables. >> >> Therefore it makes sense to add a simple MMIO-based fw_cfg client >> library >> to ArmVirtualizationPkg that for the moment is only available to >> DXE_DRIVER modules. >> >> Because MMIO accesses are costly on KVM/ARM, >> InternalQemuFwCfgReadBytes() >> accesses the fw_cfg data register in full words. This speeds up >> transfers >> almost linearly. >> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Laszlo Ersek <[email protected]> >> --- >> >> Notes: >> v3: >> - full word access to fw_cfg data register >> - mention '-kernel' booting in commit message >> >> >> ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.i >> nf | 52 ++++++++++ >> >> ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c >> | 358 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc >> | 1 + >> 3 files changed, 411 insertions(+) >> >> diff --git >> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib >> .inf >> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib >> .inf >> new file mode 100644 >> index 0000000..21ab2bf >> --- /dev/null >> +++ >> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib >> .inf >> @@ -0,0 +1,52 @@ >> +## @file >> +# >> +# Stateful, implicitly initialized fw_cfg library. >> +# >> +# Copyright (C) 2013 - 2014, Red Hat, Inc. >> +# Copyright (c) 2008 - 2012, Intel Corporation. All rights >> reserved.<BR> >> +# >> +# This program and the accompanying materials are licensed and made >> available >> +# under the terms and conditions of the BSD License which accompanies >> this >> +# distribution. The full text of the license may be found at >> +# http://opensource.org/licenses/bsd-license.php >> +# >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >> BASIS, >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS >> OR >> +# IMPLIED. >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x00010005 >> + BASE_NAME = QemuFwCfgLib >> + FILE_GUID = B271F41F-B841-48A9-BA8D- >> 545B4BC2E2BF >> + MODULE_TYPE = BASE >> + VERSION_STRING = 1.0 >> + LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER >> + >> + CONSTRUCTOR = QemuFwCfgInitialize >> + >> +# >> +# The following information is for reference only and not required by >> the build >> +# tools. >> +# >> +# VALID_ARCHITECTURES = ARM AARCH64 >> +# >> + >> +[Sources] >> + QemuFwCfgLib.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + OvmfPkg/OvmfPkg.dec >> + ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec >> + >> +[LibraryClasses] >> + BaseLib >> + BaseMemoryLib >> + IoLib >> + PcdLib >> + >> +[Pcd] >> + gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress >> + gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress >> diff --git >> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib >> .c >> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib >> .c >> new file mode 100644 >> index 0000000..dc7506f >> --- /dev/null >> +++ >> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib >> .c >> @@ -0,0 +1,358 @@ >> +/** @file >> + >> + Stateful and implicitly initialized fw_cfg library implementation. >> + >> + Copyright (C) 2013 - 2014, Red Hat, Inc. >> + Copyright (c) 2011 - 2013, Intel Corporation. All rights >> reserved.<BR> >> + >> + This program and the accompanying materials are licensed and made >> available >> + under the terms and conditions of the BSD License which accompanies >> this >> + distribution. The full text of the license may be found at >> + http://opensource.org/licenses/bsd-license.php >> + >> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >> BASIS, WITHOUT >> + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >> IMPLIED. >> +**/ >> + >> +#include <Library/BaseLib.h> >> +#include <Library/BaseMemoryLib.h> >> +#include <Library/IoLib.h> >> +#include <Library/PcdLib.h> >> +#include <Library/QemuFwCfgLib.h> >> + >> +STATIC UINTN mFwCfgSelectorAddress; >> +STATIC UINTN mFwCfgDataAddress; >> + >> + >> +/** >> + Returns a boolean indicating if the firmware configuration interface >> is >> + available for library-internal purposes. >> + >> + This function never changes fw_cfg state. >> + >> + @retval TRUE The interface is available internally. >> + @retval FALSE The interface is not available internally. >> +**/ >> +BOOLEAN >> +EFIAPI >> +InternalQemuFwCfgIsAvailable ( >> + VOID >> + ) >> +{ >> + return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress != >> 0); >> +} >> + >> + >> +/** >> + Returns a boolean indicating if the firmware configuration interface >> + is available or not. >> + >> + This function may change fw_cfg state. >> + >> + @retval TRUE The interface is available >> + @retval FALSE The interface is not available >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +QemuFwCfgIsAvailable ( >> + VOID >> + ) >> +{ >> + return InternalQemuFwCfgIsAvailable (); >> +} >> + >> + >> +RETURN_STATUS >> +EFIAPI >> +QemuFwCfgInitialize ( >> + VOID >> + ) >> +{ >> + mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress); >> + mFwCfgDataAddress = (UINTN)PcdGet64 (PcdFwCfgDataAddress); >> + >> + if (InternalQemuFwCfgIsAvailable ()) { >> + UINT32 Signature; >> + >> + QemuFwCfgSelectItem (QemuFwCfgItemSignature); >> + Signature = QemuFwCfgRead32 (); >> + if (Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) { >> + mFwCfgSelectorAddress = 0; >> + mFwCfgDataAddress = 0; >> + } >> + } >> + return RETURN_SUCCESS; >> +} >> + >> + >> +/** >> + Selects a firmware configuration item for reading. >> + >> + Following this call, any data read from this item will start from >> the >> + beginning of the configuration item's data. >> + >> + @param[in] QemuFwCfgItem Firmware Configuration item to read >> + >> +**/ >> +VOID >> +EFIAPI >> +QemuFwCfgSelectItem ( >> + IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem >> + ) >> +{ >> + if (InternalQemuFwCfgIsAvailable ()) { >> + MmioWrite16 (mFwCfgSelectorAddress, (UINT16)QemuFwCfgItem); >> + } >> +} >> + >> + >> +/** >> + Reads firmware configuration bytes into a buffer >> + >> + @param[in] Size Size in bytes to read >> + @param[in] Buffer Buffer to store data into (OPTIONAL if Size is >> 0) >> + >> +**/ >> +STATIC >> +VOID >> +EFIAPI >> +InternalQemuFwCfgReadBytes ( >> + IN UINTN Size, >> + IN VOID *Buffer OPTIONAL >> + ) >> +{ >> + UINTN Left; >> + UINT8 *Ptr; >> + UINT8 *End; >> + >> +#ifdef MDE_CPU_AARCH64 >> + Left = Size & 7; >> +#else >> + Left = Size & 3; >> +#endif >> + >> + Size -= Left; >> + Ptr = Buffer; >> + End = Ptr + Size; >> + >> +#ifdef MDE_CPU_AARCH64 >> + while (Ptr < End) { >> + *(UINT64 *)Ptr = MmioRead64 (mFwCfgDataAddress); >> + Ptr += 8; >> + } >> + if (Left & 4) { >> + *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress); >> + Ptr += 4; >> + } >> +#else >> + while (Ptr < End) { >> + *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress); >> + Ptr += 4; >> + } >> +#endif >> + >> + if (Left & 2) { >> + *(UINT16 *)Ptr = MmioRead16 (mFwCfgDataAddress); >> + Ptr += 2; >> + } >> + if (Left & 1) { >> + *Ptr = MmioRead8 (mFwCfgDataAddress); >> + } >> +} >> + >> + >> +/** >> + Reads firmware configuration bytes into a buffer >> + >> + If called multiple times, then the data read will continue at the >> offset of >> + the firmware configuration item where the previous read ended. >> + >> + @param[in] Size Size in bytes to read >> + @param[in] Buffer Buffer to store data into >> + >> +**/ >> +VOID >> +EFIAPI >> +QemuFwCfgReadBytes ( >> + IN UINTN Size, >> + IN VOID *Buffer >> + ) >> +{ >> + if (InternalQemuFwCfgIsAvailable ()) { >> + InternalQemuFwCfgReadBytes (Size, Buffer); >> + } else { >> + ZeroMem (Buffer, Size); >> + } >> +} >> + >> +/** >> + Write firmware configuration bytes from a buffer >> + >> + If called multiple times, then the data written will continue at the >> offset >> + of the firmware configuration item where the previous write ended. >> + >> + @param[in] Size Size in bytes to write >> + @param[in] Buffer Buffer to read data from >> + >> +**/ >> +VOID >> +EFIAPI >> +QemuFwCfgWriteBytes ( >> + IN UINTN Size, >> + IN VOID *Buffer >> + ) >> +{ >> + if (InternalQemuFwCfgIsAvailable ()) { >> + UINTN Idx; >> + >> + for (Idx = 0; Idx < Size; ++Idx) { >> + MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]); >> + } >> + } >> +} >> + >> + >> +/** >> + Reads a UINT8 firmware configuration value >> + >> + @return Value of Firmware Configuration item read >> + >> +**/ >> +UINT8 >> +EFIAPI >> +QemuFwCfgRead8 ( >> + VOID >> + ) >> +{ >> + UINT8 Result; >> + >> + QemuFwCfgReadBytes (sizeof Result, &Result); >> + return Result; >> +} >> + >> + >> +/** >> + Reads a UINT16 firmware configuration value >> + >> + @return Value of Firmware Configuration item read >> + >> +**/ >> +UINT16 >> +EFIAPI >> +QemuFwCfgRead16 ( >> + VOID >> + ) >> +{ >> + UINT16 Result; >> + >> + QemuFwCfgReadBytes (sizeof Result, &Result); >> + return Result; >> +} >> + >> + >> +/** >> + Reads a UINT32 firmware configuration value >> + >> + @return Value of Firmware Configuration item read >> + >> +**/ >> +UINT32 >> +EFIAPI >> +QemuFwCfgRead32 ( >> + VOID >> + ) >> +{ >> + UINT32 Result; >> + >> + QemuFwCfgReadBytes (sizeof Result, &Result); >> + return Result; >> +} >> + >> + >> +/** >> + Reads a UINT64 firmware configuration value >> + >> + @return Value of Firmware Configuration item read >> + >> +**/ >> +UINT64 >> +EFIAPI >> +QemuFwCfgRead64 ( >> + VOID >> + ) >> +{ >> + UINT64 Result; >> + >> + QemuFwCfgReadBytes (sizeof Result, &Result); >> + return Result; >> +} >> + >> + >> +/** >> + Find the configuration item corresponding to the firmware >> configuration file. >> + >> + @param[in] Name Name of file to look up. >> + @param[out] Item Configuration item corresponding to the file, to >> be passed >> + to QemuFwCfgSelectItem (). >> + @param[out] Size Number of bytes in the file. >> + >> + @retval RETURN_SUCCESS If file is found. >> + @retval RETURN_NOT_FOUND If file is not found. >> + @retval RETURN_UNSUPPORTED If firmware configuration is >> unavailable. >> + >> +**/ >> +RETURN_STATUS >> +EFIAPI >> +QemuFwCfgFindFile ( >> + IN CONST CHAR8 *Name, >> + OUT FIRMWARE_CONFIG_ITEM *Item, >> + OUT UINTN *Size >> + ) >> +{ >> + UINT32 Count; >> + UINT32 Idx; >> + >> + if (!InternalQemuFwCfgIsAvailable ()) { >> + return RETURN_UNSUPPORTED; >> + } >> + >> + QemuFwCfgSelectItem (QemuFwCfgItemFileDir); >> + Count = SwapBytes32 (QemuFwCfgRead32 ()); >> + >> + for (Idx = 0; Idx < Count; ++Idx) { >> + UINT32 FileSize; >> + UINT16 FileSelect; >> + CHAR8 FName[QEMU_FW_CFG_FNAME_SIZE]; >> + >> + FileSize = QemuFwCfgRead32 (); >> + FileSelect = QemuFwCfgRead16 (); >> + QemuFwCfgRead16 (); // skip the field called "reserved" >> + InternalQemuFwCfgReadBytes (sizeof (FName), FName); >> + >> + if (AsciiStrCmp (Name, FName) == 0) { >> + *Item = SwapBytes16 (FileSelect); >> + *Size = SwapBytes32 (FileSize); >> + return RETURN_SUCCESS; >> + } >> + } >> + >> + return RETURN_NOT_FOUND; >> +} >> + >> + >> +/** >> + Determine if S3 support is explicitly enabled. >> + >> + @retval TRUE if S3 support is explicitly enabled. >> + FALSE otherwise. This includes unavailability of the >> firmware >> + configuration interface. >> +**/ >> +BOOLEAN >> +EFIAPI >> +QemuFwCfgS3Enabled ( >> + VOID >> + ) >> +{ >> + return FALSE; >> +} >> diff --git >> a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc >> b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc >> index 1f3ddea..60f7d7f 100644 >> --- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc >> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc >> @@ -42,6 +42,7 @@ >> # Virtio Support >> VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf >> >> VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevic >> eLib.inf >> + >> QemuFwCfgLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/Q >> emuFwCfgLib.inf >> >> >> ArmPlatformLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualiz >> ationPlatformLib/ArmVirtualizationPlatformLib.inf >> >> ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibN >> ull/ArmPlatformSysConfigLibNull.inf >> -- >> 1.8.3.1 >> >> >> >> ----------------------------------------------------------------------- >> ------- >> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server >> from Actuate! Instantly Supercharge Your Business Reports and >> Dashboards >> with Interactivity, Sharing, Native Excel Exports, App Integration & >> more >> Get technology previously reserved for billion-dollar corporations, >> FREE >> http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.c >> lktrk >> _______________________________________________ >> edk2-devel mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/edk2-devel > > > > > > ------------------------------------------------------------------------------ > Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server > from Actuate! Instantly Supercharge Your Business Reports and Dashboards > with Interactivity, Sharing, Native Excel Exports, App Integration & more > Get technology previously reserved for billion-dollar corporations, FREE > http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk > _______________________________________________ > edk2-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/edk2-devel > ------------------------------------------------------------------------------ Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server from Actuate! Instantly Supercharge Your Business Reports and Dashboards with Interactivity, Sharing, Native Excel Exports, App Integration & more Get technology previously reserved for billion-dollar corporations, FREE http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/edk2-devel
