On Thu, Jul 24, 2014 at 12:51 AM, Andrew Fish <afish@apple.com> wrote:
What is the value for _PCD_GET_MODE_32_##TokenName in the autogen of the
module where the 0 is returned? Is it calling LibPcdGet32() or does it point
to the global?
_PCD_GET_MODE_32_##TokenName is #defined to the appropriate
_gPcd_FixedAtBuild_##TokenName in AutoGen.h of my module. LibPcdGet32()
is not called.
The same module's AutoGen.i contains
const UINT32 _gPcd_FixedAtBuild_##TokenName = <right_pcd_value>;
But when I check the value of _gPcd_FixedAtBuild_##TokenName from my module,
it always shows as 0.
AutoGen.i? Is this code assembly? If so you should look at the *.iii as that is the post processed version that gets sent to assembler. There is a tool to trim out code that is not compatible with the assembler, so it would be good to check that something is not going on in that step.
Are the globals in the image? What value do they have? You should be able to dump PE/COFF or ELF on your build system and find out.
#define PcdGet32(TokenName) _PCD_GET_MODE_32_##TokenName
It could be due to what Laszlo suggested earlier, but I already am
building for DEBUG.
ASSERT() acts as a no-op for me because PcdGet at [1] simply returns 0 and
DebugAssertEnabled always fails!
I don’t understand how that statement matches this statement you made: “The
execution never comes to calling LibPcdGet32(), for either BasePcdLibNull
or PcdLib.”
I meant that ASSERT() statements do nothing throughout the codebase because of
PcdGet failing.
OK that makes sense. If you dump the build.log for your module you can double check that you are only using FixedAtBuid PCDs. The 1st list of PCDs is the global list, but the each module has its list too and that is the one you want to look at.
On Wed, Jul 23, 2014 at 6:06 PM, Laszlo Ersek <lersek@redhat.com> wrote:
Library instances that usably resolve the PcdLib library class are:
$ git grep -l 'LIBRARY_CLASS *= *PcdLib' -- '*.inf'
EmulatorPkg/Library/SmbiosLib/SmbiosLib.inf
MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
MdePkg/Library/DxePcdLib/DxePcdLib.inf
MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
In PEIMs, you need the fourth; in DXE & UEFI drivers, you need the third.
I think I might not need these implementations for the PEI phase since I am
not using any Dymanic PCDs (as suggested in sec. 4.102 -
"MdePkg Document With Libraries.pdf" at [1]).
However, this is not the entire picture yet, because these libraries
delegate the work to a PPI (in PEI) and to a protocol (in DXE) that are
provided by dedicated drivers, respectively:
- MdeModulePkg/Universal/PCD/Pei/Pcd.inf
- MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
You should add these drivers to the corresponding (ie. PEI vs. DXE)
APRIORI files of the firmware volumes that your FDF file defines, so
that any driver loaded / dispatched later can use their PCD services
(through the above-mentioned library instances). Refer to
OvmfPkg/OvmfPkgX64.fdf for examples.
How are APRIORI drivers initialized? I couldn't figure which phase is
responsible for launching them.
The PEI and DXE dispatcher pre load their dispatch queues with the contents of the APRIORI file. The APRIORI file is discovered as the PEI/DXE dispatcher walks the firmware volume to find the modules to dispatch.
//
// Read the array of GUIDs from the Apriori file if it is present in the firmware volume
//
AprioriFile = NULL;
Status = Fv->ReadSection (
Fv,
&gAprioriGuid,
EFI_SECTION_RAW,
0,
(VOID **)&AprioriFile,
&SizeOfBuffer,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
} else {
AprioriEntryCount = 0;
}
//
// Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
// drivers not in the current FV and these must be skipped since the a priori list
// is only valid for the FV that it resided in.
//
for (Index = 0; Index < AprioriEntryCount; Index++) {
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
(FvHandle == DriverEntry->FvHandle)) {
CoreAcquireDispatcherLock ();
DriverEntry->Dependent = FALSE;
DriverEntry->Scheduled = TRUE;
InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
CoreReleaseDispatcherLock ();
DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n"));
break;
}
}
}
All the APRIORI file does is cause the PEI/DXE dispatcher to skip dependency (Depex) processing to decide driver order.
It does not really help with PCD. The Library that uses the PPI has a dependency on the PPI, and when you link this library against your PEIM your PEIM inherits the dependency. If you link against the NULL version of the lib you don’t get the dependency.
[Depex.common.PEIM]
gEfiPeiPcdPpiGuid
The only feature that the APRIORI file adds, that is not possible with the dependency expressions, is ordering modules with the same depex. Basically the PI spec states if you have 10 driver that have a depex that is TRUE the order those drivers run is not defined by the architecture. If the depex are all TRUE it is safe to run any of the drivers. Maybe one of the drivers is a debugger stub and you want to force that one to be 1st, this is what the APRIORI list is for.
Thanks,
Andrew Fish
[1] http://sourceforge.net/projects/edk2/files/EDK_II_Libraries/UDK2014/
Thanks,
Varad
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel