audk/ArmVirtPkg/QemuFwCfgToPcdDxe/QemuFwCfgToPcd.c

74 lines
2.1 KiB
C
Raw Normal View History

ArmVirtPkg: add QemuFwCfgToPcdDxe Many universal DXE drivers in edk2 can be controlled by setting dynamic PCDs. Such a PCD must be set before the consumer DXE driver is dispatched. (In general we assume that the DXE driver will consume the PCD in its entry point, or in the constructor of a library instance it links against. In special cases this requirement can be relaxed a bit, if we know that the DXE driver accesses the PCD only in a protocol member function that it exports.) On the QEMU platform, the PCD values to be set for the universal drivers are frequently derived from fw_cfg files that QEMU exports. In OvmfPkg we tend to handle this in the following way: - For IA32 and X64, OvmfPkg provides a QemuFwCfgLib instance that is usable in PEI. - In PlatformPei, fw_cfg files can be loaded and transformed to PCD values. - Any DXE driver is bound to be dispatched after the PEI phase is done. (In specific cases other ordering solutions might be possible, via Depex or protocol notify, etc.) In ArmVirtPkg/ArmVirtQemu, things differ a bit: - We don't have an ArmVirtPkg-specific ("Platform") PEIM. This is actually a good thing for now, so let's not introduce one just for this purpose. - Even if we had such a PEIM, it could not easily access fw_cfg: the MMIO addresses of the fw_cfg device are available only in the DTB that QEMU exports. (Accordingly, our QemuFwCfgLib instance is restricted to DXE_DRIVER modules: VirtFdtDxe parses the DTB, stores the fw_cfg addresses in PCDs, and then QemuFwCfgLib's constructor fetches those PCDs.) There are some examples in ArmVirtPkg where early code is forced to parse the DTB manually, but those examples are all painful, and our goal here (controlling universal DXE drivers) doesn't justify more of that pain. Therefore, introduce a separate, minimal DXE driver that is dispatched strictly after VirtFdtDxe (so that it can use QemuFwCfgLib), and strictly before other DXE drivers (so that it can set dynamic PCDs for them). Because VirtFdtDxe is already ordered with the APRIORI DXE file, it is simplest to do the same for the new driver. Actual fw_cfg files and PCDs shall be accessed in future patches. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18042 6f19259b-4bc3-4df7-8a09-765794883524
2015-07-26 10:02:50 +02:00
/** @file
* An "early" DXE driver that parses well-known fw-cfg files into dynamic PCDs
* that control other (universal) DXE drivers.
*
* Copyright (C) 2015, Red Hat, Inc.
* Copyright (c) 2014, Linaro Ltd. 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 <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <IndustryStandard/SmBios.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
ArmVirtPkg: add QemuFwCfgToPcdDxe Many universal DXE drivers in edk2 can be controlled by setting dynamic PCDs. Such a PCD must be set before the consumer DXE driver is dispatched. (In general we assume that the DXE driver will consume the PCD in its entry point, or in the constructor of a library instance it links against. In special cases this requirement can be relaxed a bit, if we know that the DXE driver accesses the PCD only in a protocol member function that it exports.) On the QEMU platform, the PCD values to be set for the universal drivers are frequently derived from fw_cfg files that QEMU exports. In OvmfPkg we tend to handle this in the following way: - For IA32 and X64, OvmfPkg provides a QemuFwCfgLib instance that is usable in PEI. - In PlatformPei, fw_cfg files can be loaded and transformed to PCD values. - Any DXE driver is bound to be dispatched after the PEI phase is done. (In specific cases other ordering solutions might be possible, via Depex or protocol notify, etc.) In ArmVirtPkg/ArmVirtQemu, things differ a bit: - We don't have an ArmVirtPkg-specific ("Platform") PEIM. This is actually a good thing for now, so let's not introduce one just for this purpose. - Even if we had such a PEIM, it could not easily access fw_cfg: the MMIO addresses of the fw_cfg device are available only in the DTB that QEMU exports. (Accordingly, our QemuFwCfgLib instance is restricted to DXE_DRIVER modules: VirtFdtDxe parses the DTB, stores the fw_cfg addresses in PCDs, and then QemuFwCfgLib's constructor fetches those PCDs.) There are some examples in ArmVirtPkg where early code is forced to parse the DTB manually, but those examples are all painful, and our goal here (controlling universal DXE drivers) doesn't justify more of that pain. Therefore, introduce a separate, minimal DXE driver that is dispatched strictly after VirtFdtDxe (so that it can use QemuFwCfgLib), and strictly before other DXE drivers (so that it can set dynamic PCDs for them). Because VirtFdtDxe is already ordered with the APRIORI DXE file, it is simplest to do the same for the new driver. Actual fw_cfg files and PCDs shall be accessed in future patches. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18042 6f19259b-4bc3-4df7-8a09-765794883524
2015-07-26 10:02:50 +02:00
#include <Library/PcdLib.h>
#include <Library/QemuFwCfgLib.h>
/**
Set the SMBIOS entry point version for the generic SmbiosDxe driver.
**/
STATIC
VOID
SmbiosVersionInitialization (
VOID
)
{
FIRMWARE_CONFIG_ITEM Anchor;
UINTN AnchorSize;
SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
UINT16 SmbiosVersion;
if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smbios/smbios-anchor", &Anchor,
&AnchorSize)) ||
AnchorSize != sizeof QemuAnchor) {
return;
}
QemuFwCfgSelectItem (Anchor);
QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
if (CompareMem (QemuAnchor.AnchorString, "_SM_", 4) != 0 ||
CompareMem (QemuAnchor.IntermediateAnchorString, "_DMI_", 5) != 0) {
return;
}
SmbiosVersion = (UINT16)(QemuAnchor.MajorVersion << 8 |
QemuAnchor.MinorVersion);
DEBUG ((EFI_D_INFO, "%a: SMBIOS version from QEMU: 0x%04x\n", __FUNCTION__,
SmbiosVersion));
PcdSet16 (PcdSmbiosVersion, SmbiosVersion);
}
ArmVirtPkg: add QemuFwCfgToPcdDxe Many universal DXE drivers in edk2 can be controlled by setting dynamic PCDs. Such a PCD must be set before the consumer DXE driver is dispatched. (In general we assume that the DXE driver will consume the PCD in its entry point, or in the constructor of a library instance it links against. In special cases this requirement can be relaxed a bit, if we know that the DXE driver accesses the PCD only in a protocol member function that it exports.) On the QEMU platform, the PCD values to be set for the universal drivers are frequently derived from fw_cfg files that QEMU exports. In OvmfPkg we tend to handle this in the following way: - For IA32 and X64, OvmfPkg provides a QemuFwCfgLib instance that is usable in PEI. - In PlatformPei, fw_cfg files can be loaded and transformed to PCD values. - Any DXE driver is bound to be dispatched after the PEI phase is done. (In specific cases other ordering solutions might be possible, via Depex or protocol notify, etc.) In ArmVirtPkg/ArmVirtQemu, things differ a bit: - We don't have an ArmVirtPkg-specific ("Platform") PEIM. This is actually a good thing for now, so let's not introduce one just for this purpose. - Even if we had such a PEIM, it could not easily access fw_cfg: the MMIO addresses of the fw_cfg device are available only in the DTB that QEMU exports. (Accordingly, our QemuFwCfgLib instance is restricted to DXE_DRIVER modules: VirtFdtDxe parses the DTB, stores the fw_cfg addresses in PCDs, and then QemuFwCfgLib's constructor fetches those PCDs.) There are some examples in ArmVirtPkg where early code is forced to parse the DTB manually, but those examples are all painful, and our goal here (controlling universal DXE drivers) doesn't justify more of that pain. Therefore, introduce a separate, minimal DXE driver that is dispatched strictly after VirtFdtDxe (so that it can use QemuFwCfgLib), and strictly before other DXE drivers (so that it can set dynamic PCDs for them). Because VirtFdtDxe is already ordered with the APRIORI DXE file, it is simplest to do the same for the new driver. Actual fw_cfg files and PCDs shall be accessed in future patches. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18042 6f19259b-4bc3-4df7-8a09-765794883524
2015-07-26 10:02:50 +02:00
EFI_STATUS
EFIAPI
ParseQemuFwCfgToPcd (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
SmbiosVersionInitialization ();
ArmVirtPkg: add QemuFwCfgToPcdDxe Many universal DXE drivers in edk2 can be controlled by setting dynamic PCDs. Such a PCD must be set before the consumer DXE driver is dispatched. (In general we assume that the DXE driver will consume the PCD in its entry point, or in the constructor of a library instance it links against. In special cases this requirement can be relaxed a bit, if we know that the DXE driver accesses the PCD only in a protocol member function that it exports.) On the QEMU platform, the PCD values to be set for the universal drivers are frequently derived from fw_cfg files that QEMU exports. In OvmfPkg we tend to handle this in the following way: - For IA32 and X64, OvmfPkg provides a QemuFwCfgLib instance that is usable in PEI. - In PlatformPei, fw_cfg files can be loaded and transformed to PCD values. - Any DXE driver is bound to be dispatched after the PEI phase is done. (In specific cases other ordering solutions might be possible, via Depex or protocol notify, etc.) In ArmVirtPkg/ArmVirtQemu, things differ a bit: - We don't have an ArmVirtPkg-specific ("Platform") PEIM. This is actually a good thing for now, so let's not introduce one just for this purpose. - Even if we had such a PEIM, it could not easily access fw_cfg: the MMIO addresses of the fw_cfg device are available only in the DTB that QEMU exports. (Accordingly, our QemuFwCfgLib instance is restricted to DXE_DRIVER modules: VirtFdtDxe parses the DTB, stores the fw_cfg addresses in PCDs, and then QemuFwCfgLib's constructor fetches those PCDs.) There are some examples in ArmVirtPkg where early code is forced to parse the DTB manually, but those examples are all painful, and our goal here (controlling universal DXE drivers) doesn't justify more of that pain. Therefore, introduce a separate, minimal DXE driver that is dispatched strictly after VirtFdtDxe (so that it can use QemuFwCfgLib), and strictly before other DXE drivers (so that it can set dynamic PCDs for them). Because VirtFdtDxe is already ordered with the APRIORI DXE file, it is simplest to do the same for the new driver. Actual fw_cfg files and PCDs shall be accessed in future patches. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18042 6f19259b-4bc3-4df7-8a09-765794883524
2015-07-26 10:02:50 +02:00
return EFI_SUCCESS;
}