Mike,
I did a quick prototype that just outputs the current PCD DSC syntax with an
extra | C typedef name at the end when you build. The example includes a
structure with bit-fields and a device path.
build -p MdeModulePkg/MdeModulePkg.dsc -a X64 -t XCODE5
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[PcdsFixedAtBuild.common]
gMdeModulePkgTokenGuid.PcdFakePcdExample| { 0x53, 0x47, 0xc1, 0xe0, 0xbe,
0xf9, 0xd2, 0x11, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d, 0x21, 0x30,
0x04, 0x00, 0x03, 0x00, 0x00, 0x00,} | FAKE_PCD_EXAMPLE
gMdeModulePkgTokenGuid.PcdFakeDevicePathExample| { 0x03, 0x0f, 0x0b, 0x00,
0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x01, 0x7f, 0xff, 0x04, 0x00,} |
EFI_DEVICE_PATH_PROTOCOL
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
There are a few hacks:
1) The parser is not very robust from an error handling point of view.
2) Some of the compiler flags are missing. The reason is I could not undo the
-E from the flags I was trying to reuse. So this may take a little flags
cleanup to work.
3) I only had enough time to do the XCODE version, and I set the flags needed
to make sure you get the EFI Spec structure packing.
Thanks,
Andrew Fish
diff --git a/BaseTools/BinWrappers/PosixLike/StructuredPcdAutoGen.py
b/BaseTools/BinWrappers/PosixLike/StructuredPcdAutoGen.py
new file mode 100755
index 0000000..82a9b3b
--- /dev/null
+++ b/BaseTools/BinWrappers/PosixLike/StructuredPcdAutoGen.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python -u
+## @file
+# Prototype .pcd parser
+#
+# Parse the meta data
+#// @PCDTYPE [PcdsFixedAtBuild.common]
+#// @PCD
gMdeModulePkgTokenGuid.PcdFakePcdExample|FAKE_PCD_EXAMPLE|gFakePcdExample
+#
+# Create a C application to generate the PCD data.
+#
+# Copyright (c) 2016, Apple Inc. 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.
+#
+
+import sys
+
+programStart = '''
+// AutoGen file do not hand edit.
+#include <stdio.h>
+
+#ifdef NULL
+#undef NULL
+#endif
+
+#include "%s"
+
+int
+main (int argv, char **argc)
+{
+ unsigned char *c;
+ int i;
+
+'''
+
+programWork = '''
+ printf (" @1| {");
+ for (i=0, c = (unsigned char *)(unsigned long long) &@2; i < sizeof (@2);
i++) {
+ printf (" 0x%02x,", c[i]);
+ }
+ printf ("} | @3\\n");
+'''
+
+""
+
+programEnd = '''
+ printf ("\\n");
+ return 0;
+}
+
+'''
+
+def main (filename):
+ ''' strip out lines that do not start with @, and the @'''
+ print programStart % filename
+
+ pcd = {}
+ pcdType = ''
+ with open(filename) as openfile:
+ for line_of_c in openfile.readlines():
+ line = line_of_c.split()
+ if len(line) >= 3 and line[0] == '//':
+ if '@PCDTYPE' in line[1]:
+ #// @PCDTYPE [PcdsFixedAtBuild.common]
+ print ' printf ("%s\\n");' % line[2]
+ if '@PCD' in line[1]:
+ #// @PCD
gMdeModulePkgTokenGuid.PcdFakePcdExample|FAKE_PCD_EXAMPLE|gFakePcdExample
+ PcdEntry = line[2].split('|')
+ if len (PcdEntry) >= 3:
+ print programWork.replace('@1',
PcdEntry[0]).replace('@2', PcdEntry[2]).replace('@3', PcdEntry[1])
+
+ print programEnd
+
+if __name__ == "__main__":
+ if len (sys.argv) < 2:
+ sys.exit()
+
+ main (sys.argv[1])
+
+
diff --git a/BaseTools/Conf/build_rule.template
b/BaseTools/Conf/build_rule.template
index 91bcc18..3d2c47f 100644
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -604,3 +604,21 @@
GenFw -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID)
--hiibinpackage $(HII_BINARY_PACKAGES)
+[Pcd-Code-File]
+ <InputFile>
+ ?.pcd
+
+ <OutputFile>
+ $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}
+
+ <ExtraDependency>
+ $(MAKE_FILE)
+
+ <Command.XCODE>
+ StructuredPcdAutoGen.py ${src} >
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.AutoGen.c
+ "$(CC)" -mms-bitfields -fshort-wchar -funsigned-char $(INC) -o
$(OUTPUT_DIR)(+)${s_dir}(+)AutoGenTool
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.AutoGen.c
+ @echo
"\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ @$(OUTPUT_DIR)(+)${s_dir}(+)AutoGenTool
+ @echo
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
+
+
diff --git a/MdeModulePkg/Include/Pcd/FakeExample.h
b/MdeModulePkg/Include/Pcd/FakeExample.h
new file mode 100644
index 0000000..06d5526
--- /dev/null
+++ b/MdeModulePkg/Include/Pcd/FakeExample.h
@@ -0,0 +1,33 @@
+/** @file
+ Example of Structured PCDs include file.
+
+ Copyright (c) 2016, Apple Inc. 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.
+
+**/
+
+#ifndef __FAKE_EXAMPLE_H__
+#define __FAKE_EXAMPLE_H__
+
+typedef struct {
+ UINT32 BitsA:4;
+ UINT32 BitsB:8;
+ UINT32 BitsC:4;
+ UINT32 BitsD:8;
+} EXAMPLE_BITFIELD;
+
+typedef struct {
+ EFI_GUID Compression;
+ EXAMPLE_BITFIELD BitField;
+ UINT8 ClassCode[3];
+} FAKE_PCD_EXAMPLE;
+
+
+#endif
+
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 936f46d..4dbedd6 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -187,6 +187,9 @@
[PcdsFixedAtBuild.IPF]
gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000
+[Components]
+ MdeModulePkg/Pcd/Example.inf
+
###################################################################################################
#
# Components Section - list of the modules and components that will be
processed by compilation
diff --git a/MdeModulePkg/Pcd/Example.inf b/MdeModulePkg/Pcd/Example.inf
new file mode 100644
index 0000000..b12c383
--- /dev/null
+++ b/MdeModulePkg/Pcd/Example.inf
@@ -0,0 +1,31 @@
+## @file
+# Example of Structured PCDs set via C include infrastructure
+#
+# Portions copyright (c) 2016, Apple Inc. 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 = ExamplePcd
+ FILE_GUID = C8BE4EB8-2035-11E6-9969-B8E8562CBAFA
+ MODULE_TYPE = USER_DEFINED
+ VERSION_STRING = 1.0
+
+[Sources]
+ Example.pcd
+
+[Sources.IA32]
+ YouMustCompileInX64Mode.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
diff --git a/MdeModulePkg/Pcd/Example.pcd b/MdeModulePkg/Pcd/Example.pcd
new file mode 100644
index 0000000..f01dcd8
--- /dev/null
+++ b/MdeModulePkg/Pcd/Example.pcd
@@ -0,0 +1,74 @@
+/** @file
+ Example of Structured PCDs set via C include infrastructure
+
+ Copyright (c) 2016, Apple Inc. 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.h>
+#include <IndustryStandard/Pci.h>
+#include <Guid/PcAnsi.h>
+#include <Protocol/DevicePath.h>
+
+#include <Pcd/FakeExample.h>
+
+#define A 1
+#define B 2
+#define C 3
+#define D 4
+
+typedef struct {
+ USB_CLASS_DEVICE_PATH UsbClass;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+#define CLASS_HID 3
+#define SUBCLASS_BOOT 1
+#define PROTOCOL_KEYBOARD 1
+
+// @PCDTYPE [PcdsFixedAtBuild.common]
+
+
+// @PCD
gMdeModulePkgTokenGuid.PcdFakePcdExample|FAKE_PCD_EXAMPLE|gFakePcdExample
+FAKE_PCD_EXAMPLE gFakePcdExample = {
+ EFI_PC_ANSI_GUID,
+ { A, B, C, D },
+ { PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, PCI_IF_VGA_VGA }
+};
+
+
+// @PCD
gMdeModulePkgTokenGuid.PcdFakeDevicePathExample|EFI_DEVICE_PATH_PROTOCOL|gFakePcdDevicePathExample
+USB_CLASS_FORMAT_DEVICE_PATH gFakePcdDevicePathExample = {
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ {
+ (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
+ (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0xffff, // VendorId
+ 0xffff, // ProductId
+ CLASS_HID, // DeviceClass
+ SUBCLASS_BOOT, // DeviceSubClass
+ PROTOCOL_KEYBOARD // DeviceProtocol
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+ }
+};
+
> On May 20, 2016, at 2:48 PM, Andrew Fish <[email protected]> wrote:
>
>>
>> On May 20, 2016, at 12:34 PM, Kinney, Michael D <[email protected]>
>> wrote:
>>
>> Andrew,
>>
>> I hope there is not a misunderstanding in the include file used by a DEC
>> file for a PCD.
>>
>> It is not a parallel include file. The same include file is used in DEC
>> parsing and
>> by modules/libs that access the same Structured PCD. This is especially
>> important for
>> sharing a .h file between a PCD and VFR NV storage sources to eliminate
>> manual maintenance
>> of config value offsets in HII type PCD.
>>
>
> Mike,
>
> Sorry for the confusion I assume .h files are the same in both cases, and
> that is an absolute requirement. My point is the current DSC, INF, Conf/*.txt
> syntax supports figuring out the include pathing and passing the build
> generated compiler flags to the compiler, getting code auto generated, and
> built. Adding the C syntax info the .DEC and .DSC files means you have
> duplicate this mechanism. So I guess what I'm saying is if it is C like
> syntax use an INF, just like the C and ACPI code does today since you are
> really all sharing the C include infrastructure. If you try and duplicate
> build infrastructure with different code it is going to break (not get the
> same result as the INF path) in some subtle way at some point.Ssince it is a
> different syntax we could hit and end case where things are not symmetric
> (for example the INF files can have [BuildOptions] settings and new
> extensions to DEC/DSC don't support that). Also extending the DEC and DSC
> syntax is more new things for a developer to learn.
>
> Basically if it is a C like syntax (like C and ACPI) then we should use an
> INF file like today is what I'm advocating.
>
>> I only added syntax for some optional tags in comments for fields in the C
>> structure.
>> I want developer to only enter information (C struct in this case) one time.
>> We also
>> want to focus platform configuration information in the one DSC file for
>> simpler platform
>> configuration and generate PCD reports that show PCD configuration settings
>> (including
>> all field values in a Structured PCD).
>>
>> At this time, bit fields are a must have requirement for Structured PCDs.
>>
>> Main use case is register values with bit fields with no translation from
>> PCD to
>> register access. As a result SIZE_OF and OFFSET_OF are not sufficient. I
>> have ideas
>> on how to get bit offset/bit length from C compiler without using CLANG/AST.
>> It was
>> just very easy to get this info from CLANG/AST.
>>
>> Additional reason is size reduction of configuration data. Single bit or
>> BOOLEAN
>> like configuration setting takes up minimum of 8-bits today. If there are
>> many
>> configuration settings like these, then they can add up.
>>
>
> It is not so much as they are not supported, but you don't get an atomic
> write. You have to read modify write them, so 2 calls and a local variable.
> Actually we "solved that problem" in the IoLib by adding IoBitField*
> functions.... So that would imply what you need is an AND mask and you can
> hide the read modify write behind the library....
>
> Thus if you could generate a local, global or #define with the bit filed
> value all 1's and all the other fields 0's you can automate the read modify
> write into a single call. So maybe it is possible?
>
> Do all the compilers support C99? Named structure initialization makes this
> is easy if you know the type of the bitfield and the member name. Well you
> have to suppress the warning.
>
> ~/work/Compiler>cat bitfield.c
> typedef struct {
> unsigned int a:2;
> unsigned int b:4;
> unsigned int c:2;
> } TEST;
>
> TEST Test0 = { 0 };
> TEST Testa = { .a = 0xFFFFFFFF };
> TEST Testb = { .b = 0xFFFFFFFF };
> TEST Testc = { .c = 0xFFFFFFFF };
> ~/work/Compiler>clang -S -Wno-bitfield-constant-conversion bitfield.c
> ~/work/Compiler>cat bitfield.S
> .section __TEXT,__text,regular,pure_instructions
> .macosx_version_min 10, 11
> .section __DATA,__data
> .globl _Test0 ## @Test0
> .align 2
> _Test0:
> .byte 0 ## 0x0
> .space 3
>
> .globl _Testa ## @Testa
> .align 2
> _Testa:
> .byte 3 ## 0x3
> .space 3
>
> .globl _Testb ## @Testb
> .align 2
> _Testb:
> .byte 60 ## 0x3c
> .space 3
>
> .globl _Testc ## @Testc
> .align 2
> _Testc:
> .byte 192 ## 0xc0
> .space 3
>
> OK I think I'm convinced now it is likely we will be able to support
> bitfields.
>
> Thanks,
>
> Andrew Fish
>
> PS Mike if you look into this bitfield thing I can look at prototyping the
> INF based parsing with an example syntax from my previous mail. It will be
> easier to discuss with a prototype to look at.
>
> Well assuming I can track down the PACKAGES_PATH bug with ACPI tables.
> FfsInf.EfiOutputPath is missing the PACKAGES_PATH part and so I don't get any
> ACPI tables as the OUTPUT directory path is wrong so the search for the files
> fail :(.
>
>> Mike
>>
>>> -----Original Message-----
>>> From: [email protected] [mailto:[email protected]]
>>> Sent: Friday, May 20, 2016 12:15 PM
>>> To: Kinney, Michael D <[email protected]>
>>> Cc: [email protected] <[email protected]>
>>> Subject: Re: [edk2] [RFC] Structured PCD Proposal
>>>
>>>
>>>> On May 20, 2016, at 10:48 AM, Kinney, Michael D
>>>> <[email protected]> wrote:
>>>>
>>>> Andrew,
>>>>
>>>> 1) I think the strongest concern is on use of CLANG/AST. I will look at
>>>> your ideas
>>> and
>>>> some other ideas I have thought of as well to use standard C compiler that
>>>> is
>>> already
>>>> installed to build FW to support Structured PCD features.
>>>>
>>>> 2) The other concern I see here is extending PcdLib to access fields. You
>>>> prefer
>>> to
>>>> not add those APIs and always read/write entire structure. I have
>>>> requests to
>>> support
>>>> field access, so that is a bit of a requirement conflict.
>>>>
>>>
>>> Mike,
>>>
>>> Given the complexity we ended up with the basic edk2 design, that was also
>>> driven by
>>> complex requirements, I wanted to start the conversation of how some of the
>>> requirements maybe driving a disproportionate amount of the complexity. I
>>> would hate
>>> for a "nice to have" feature drive 80% of the complexity. I'm still feeling
>>> guilty
>>> about those PCD section names....
>>>
>>> I think there are two vectors of complexity:
>>> 1) Implementation - Requiring clang/AST
>>> I think stepping away with the assumption of clang/AST being required helps
>>> this
>>> vector out a lot.
>>>
>>> 2) Workflow - how a developer uses the feature day to day.
>>> I think my comments about the default values in the .DEC relate to the
>>> complexities a
>>> developer will face. As you point out there is going to be a .DEC grammar
>>> extension
>>> required just to support this feature. Also if I understand correctly
>>> changing a
>>> #define or a structure definition in another package could change the
>>> default. We
>>> currently don't have this behavior and I think that will lead to more
>>> confusion and
>>> hard to track down bugs. Thus I think we should consider sticking with the
>>> current
>>> .DEC syntax for the default variable if it is required. We could advocate
>>> comments
>>> that explain the fields and maybe even output information like that in
>>> build log PCD
>>> section so you can copy paste into the .DEC.
>>>
>>> Using an INF file and new file type for the structured PCD is also trying
>>> to manage
>>> developer complexity by making it symmetric with C and ACPI code. You can
>>> make the
>>> argument that PCDs always worked a certain way, but I will make the a
>>> counter
>>> argument that managing the C include file infrastructure has always worked
>>> a certain
>>> way too, and that is the reason to consider not building a parallel include
>>> infrastructure definition for the .DSC (and .DEC) files and use an INF
>>> file, not to
>>> mention it is probably easier to implement since it is a solved problem.
>>>
>>>
>>> I was also thinking about the PcdLib field accessors. If you don't support
>>> bit fields
>>> and don't need pedantic type safety I think this idea may get you 80% of
>>> what you
>>> want (I'm guessing you might have already thought of this). If the build
>>> system knows
>>> the C type of the structure and places it in the AutoGen.h and you know the
>>> structure
>>> member name in the calling code the Code calling the PcdLib.h can derive the
>>> structure offset and size of the field. It may also be possible to verify
>>> the size
>>> of the argument via a sizeof() in a macro.
>>>
>>> I just double checked that nested structures/unions would work, and clang
>>> looks
>>> happy.
>>>
>>> #include <stdio.h>
>>>
>>> #define OFFSET_OF(TYPE, Field) __builtin_offsetof(TYPE, Field)
>>> #define SIZE_OF(TYPE, Field) (sizeof(((TYPE *)0)->Field))
>>>
>>> typedef struct {
>>> int a;
>>> int b;
>>> int c;
>>> int leaf;
>>> } STRUCT_LEAF;
>>>
>>> typedef struct {
>>> STRUCT_LEAF Leaf;
>>> int i;
>>> } STRUCT;
>>>
>>> int
>>> main ()
>>> {
>>> STRUCT S;
>>>
>>> printf ("Offset 0x%lx size 0x%lx\n", OFFSET_OF(STRUCT, Leaf.leaf),
>>> SIZE_OF(STRUCT,
>>> Leaf.leaf));
>>> return 0;
>>> }
>>>
>>> So maybe the complexity tradeoff is how you support bitfields (union with a
>>> real type
>>> and granularity of access is that type) and how pedantic the type checking
>>> (C is not
>>> type safe, so this is no different than a cast in the C code) is going to
>>> be for the
>>> PcdLib structure field accessor.
>>>
>>> Thanks,
>>>
>>> Andrew Fish
>>>
>>>> More responses below.
>>>>
>>>> Mike
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: [email protected] [mailto:[email protected]]
>>>>> Sent: Thursday, May 19, 2016 3:25 PM
>>>>> To: Kinney, Michael D <[email protected]>
>>>>> Cc: [email protected] <[email protected]>
>>>>> Subject: Re: [edk2] [RFC] Structured PCD Proposal
>>>>>
>>>>>
>>>>>> On May 19, 2016, at 12:16 PM, Kinney, Michael D
>>>>>> <[email protected]>
>>> wrote:
>>>>>>
>>>>>> Andrew,
>>>>>>
>>>>>> My responses embedded below.
>>>>>>
>>>>>
>>>>> Mike,
>>>>>
>>>>> Likewise.
>>>>>
>>>>>> Mike
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: edk2-devel [mailto:[email protected]] On Behalf Of
>>>>>>> Andrew
>>> Fish
>>>>>>> Sent: Thursday, May 19, 2016 10:53 AM
>>>>>>> To: Kinney, Michael D <[email protected]>;
>>>>>>> [email protected]
>>> <edk2-
>>>>>>> [email protected]>
>>>>>>> Subject: Re: [edk2] [RFC] Structured PCD Proposal
>>>>>>>
>>>>>>>
>>>>>>>> On May 19, 2016, at 2:26 AM, Laszlo Ersek <[email protected]> wrote:
>>>>>>>>
>>>>>>>> On 05/19/16 01:28, Kinney, Michael D wrote:
>>>>>>>>
>>>>>>>> [snip]
>>>>>>>>
>>>>>>>>> ## C Structure Syntax Proposal
>>>>>>>>> * Use C typedef syntax to describe complex C structures
>>>>>>>>> * Use a C language parser with support for struct/union/array/bit
>>>>>>>>> fields/pack
>>>>>>>>> * Recommend use of libclang C language parser into Abstract Syntax
>>>>>>>>> Tree (AST)
>>>>>>>>> - Included with LLVM release
>>>>>>>>> - http://llvm.org/releases/download.html
>>>>>>>>> - http://clang.llvm.org/doxygen/group__CINDEX.html
>>>>>>>>> * Recommend use of Python bindings for CLANG for EDK II Python based
>>>>>>>>> BaseTools
>>>>>>>>> - pip install clang
>>>>>>>>
>>>>>>>> What versions are necessary? On RHEL-7, the following versions are
>>>>>>>> available (from EPEL only; RHEL does not provide clang):
>>>>>>>>
>>>>>>>> clang-devel: 3.4.2-8.el7
>>>>>>>> python-pip: 7.1.0-1.el7
>>>>>>>>
>>>>>>>
>>>>>>> Will it be possible to check everything into the edk2 git tree?
>>>>>>> Currently we
>>> only
>>>>>>> require the developer to have Xcode installed and everything else is in
>>>>>>> the git
>>>>> tree.
>>>>>>> I'm not sure it is possible to run pip on our production build servers?
>>>>>>
>>>>>> Is clang and clang libs included in your environment?
>>>>>
>>>>> clang is the compiler for Xcode so we have that for sure. I'm not sure
>>>>> about the
>>> libs
>>>>> but they are likely accessible.
>>>>>
>>>>>> That is not edk2 git today.
>>>>>> The only other component is the Python wrapper on top of the clang lib
>>>>>> and that
>>>>>> is available from another github project if you want to pull python
>>>>>> sources to
>>> it.
>>>>>>
>>>>>
>>>>> If is just Python code it should not be too complex?
>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>>
>>>>>>>>> ## DEC File Extensions
>>>>>>>>> * Declare link between PCD and C data structure and token range for
>>>>>>>>> fields
>>>>>>>>> * @Include path to include file with C typedef [Required]
>>>>>>>>> * Replace |VOID*| with name of C typedef
>>>>>>>>> * @TokenMap path to file with token number assignments [Optional]
>>>>>>>>> * Range of token numbers to assign to fields in C typedef [Required]
>>>>>>>>> * Example:
>>>>>>>>>
>>>>>>>>> ```
>>>>>>>>> # @Include Include/Pcd/AcpiLowerPowerIdleTable.h
>>>>>>>>> # @TokenMap Include/Pcd/AcpiLowerPowerIdleTable.map
>>>>>>>>>
>>>>>>>
>>>>>
>>> gPlatformTokenSpaceGuid.AcpiLowPowerIdleTable|{}|ACPI_LOW_POWER_IDLE_TABLE|0x00010080
>>>>>>> |0x0E000200-0x0E0002FF
>>>>>>>>> ```
>>>>>>>>
>>>>>>>> What does 0x00010080 mean here?
>>>>>>>>
>>>>>>>>>
>>>>>>>>> * Recommended File Paths
>>>>>>>>> - <PackageName>/Include/Pcd/<StructuredPcdName>.h
>>>>>>>>> - <PackageName>/Include/Pcd/<StructuredPcdName>.map [Optional]
>>>>>>>>> - <PackageName>/Include/Pcd/<StructuredPcdName>.uni [Optional]
>>>>>>>>> * C Pre-Processor Support
>>>>>>>>> - Use of #include, #define, #if supported
>>>>>>>>> - #include limited to files in same package
>>>>>>>>> - Including files from other packages being evaluated
>>>>>>>>>
>>>>>>>
>>>>>>> I think you need to share the C headers with the edk2 C and ASL code,
>>>>>>> so you
>>>>> should
>>>>>>> have full access including all the things set in the [BuildOptions]
>>>>>>> flags in the
>>>>> DSC.
>>>>>>> So use something like PP_FLAGS or ASLPP_FLAGS and allow customization
>>>>>>> via the
>>>>>>> Conf/build_rule.txt. I'd rather we not makeup a new thing and just use
>>>>>>> one of
>>> the
>>>>>>> existing pre processor schemes.
>>>>>>
>>>>>> I agree. Any flags set up in [BuildOptions] or -D flags on command line
>>>>>> would be
>>>>>> passed in, so the .h file associated with the Structured PCD is treated
>>>>>> the same
>>>>>> as any other .h file used to build modules/libs. There is no intention
>>>>>> to create
>>>>>> any new build rules to support Structured PCDs.
>>>>>
>>>>> OK I was confused by this statement. "Including files from other packages
>>>>> being
>>>>> evaluated". The more I think about it it is probably more related to this
>>>>> not
>>> being
>>>>> symmetric to how C and ASL works (you have an INF file to declare your
>>> dependencies).
>>>>> I'm worried that could cause issue. What if I needed a include file from
>>>>> a package
>>>>> that was not included any other way? If I was writing C or ASL I'd just
>>>>> update the
>>>>> INF file.
>>>>
>>>> Today, all of the content in a DEC file of a package does not have any
>>>> dependencies
>>>> outside that package. Modules/library implementations within a package
>>>> may have
>>>> dependencies on content from other packages as defined by the [Packages]
>>>> section
>>>> in an INF file. A PCD, declared in a package DEC files, that is
>>>> associated with
>>>> a typedef struct in an include file must follow the DEC file constraint
>>>> where there
>>>> are no dependencies on other packages.
>>>>
>>>> What is being evaluated is how to support a use case where an include file
>>>> used for
>>>> a Structured PCD needs definitions from include files in another package
>>>> (e.g. MdePkg for some industry standard defines/structs)
>>>>
>>>> We support multiple package dependencies in modules/library INF files
>>>> today with a
>>>> [Packages] section in the INF. One idea (not part of this proposal at
>>>> this time),
>>>> is to add a [Packages] section to a DEC file. The include paths used to
>>>> process a .h file associated with a Structured PCD can be appended with
>>>> all the
>>>> dependent package include paths. The [Packages] section in a DEC would
>>>> only be
>>>> used for DEC file dependencies. It would never be used to package
>>>> dependencies of
>>>> modules/libraries within that package.
>>>>
>>>> Adding a [Packages] section to a DEC file has wider impacts to other
>>>> BaseTools,
>>>> which is why I did not provide any more details than "under evaluation" at
>>>> this
>>>> time. My suggestion with the current proposal is to make sure all the .h
>>>> file
>>>> content required for a Structured PCD be within the package itself.
>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>> IMHO it will be easy enough to follow the proposed restrictive rules
>>>>>>> when you
>>> are
>>>>>>> starting from scratch, but I'm more worried about the case when you
>>>>>>> have an
>>>>> existing
>>>>>>> (very complex) include infrastructure that supports feature X in C and
>>>>>>> ASL and
>>> you
>>>>>>> decide to add a PCD for X. You don't want it to not work due to more
>>>>>>> restrictive
>>>>>>> rules around the PCD.
>>>>>>
>>>>>> A .h file can have lots of content in it. Only the typedef structure
>>>>>> name
>>>>> referenced
>>>>>> in the DEC file declaration has to follow any of the restrictions
>>>>>> associated with
>>>>>> a Structured PCD. The C Preprocessor statements above are there to show
>>>>>> that
>>> there
>>>>>> .h file for a Structured PCD can use the same C Preprocessor directives
>>>>>> that the
>>>>> rest
>>>>>> of the C code in modules/libs can use. The biggest restriction is in
>>>>>> the data
>>>>> types
>>>>>> of the leaf fields of the structures. Those have to be compatible with
>>>>>> the PCD
>>>>>> get/set APIs.
>>>>>>
>>>>>
>>>>> I think this makes my point about the complexity driving restrictions. If
>>>>> you did
>>> not
>>>>> have leaf field accessors you would not have that restriction.
>>>>
>>>> I agree that removing the requirement for leaf accessors reduces
>>>> complexity. I
>>> have
>>>> a request to support leaf accessors, so that is why they are part of this
>>>> proposal.
>>>>
>>>>>
>>>>>>>
>>>>>>>>> ## C Structure Syntax
>>>>>>>>> * Support struct/union/array with nesting
>>>>>>>>> * Support bit fields
>>>>>>>>
>>>>>>>> Bit fields will require new PcdLib interaces, right?
>>>>>>>>
>>>>>>>
>>>>>>> Yikes bit fileds. My over all feedback is this feature seems very
>>>>>>> complex and
>>>>>>> designed by committee (too many features). The complexity already seems
>>>>>>> to be
>>>>>>> introducing restrictions and will possible make it harder for
>>>>>>> developers to
>>>>>>> understand.
>>>>>>
>>>>>> The goal was to allow use of C syntax for a typedef struct with as few
>>> restrictions
>>>>>> as possible, so exiting C structs associated with VOID* PCDs could be
>>>>>> used "as
>>> is".
>>>>>> Yes. Supporting full C syntax can be complex, but by using CLANG front
>>>>>> end for
>>>>>> parsing into an AST, the complexity is handled by a well supported
>>>>>> parser.
>>>>>>
>>>>>>>
>>>>>>> I'll take a quick stab at simplification.
>>>>>>> 1) Add the new syntax to a new file type: *.pcd. This file would
>>>>>>> contain [Pcd*]
>>>>>>> sections and the C like syntax.
>>>>>>
>>>>>> C like syntax. That is what concerns me. Now we have to tell
>>>>>> developers that
>>>>>> they can use full C syntax for modules/libs, but there are different C
>>>>>> rules for
>>>>>> PCDs. I think it is easier is developers can use came C syntax for
>>>>>> modules/libs
>>>>>> and PCDs.
>>>>>
>>>>> I would assume the structure initialization is pure C, but there is meta
>>>>> data
>>>>> associated with the PCD that needs to get collected and associated
>>>>> initialized C
>>>>> structure. This is going to be true for any scheme.
>>>>
>>>> Yes. There is optional meta data in a comment block for a field of a
>>>> structure.
>>>> I have used the same meta-data tags and syntax that is defined in DEC file
>>>> comment blocks, to take advantage of the source style a developer already
>>>> knowns
>>>> when declaring PCDs in a DEC file. Only @TokenNumber (likely very rarely
>>>> used) and
>>>> @DefaultValue are new tags. But even the value syntax for these reuses
>>>> the value
>>>> syntax for a token number and default value in a PCD declaration in a DEC
>>>> file.
>>>>
>>>>>
>>>>>>
>>>>>>> 2) Don't support default values in the .dec with the C like syntax.
>>>>>>> Recommend no
>>>>>>> defaults and a build break if a PCD is not set by the platform build
>>>>>>> for
>>> complex
>>>>>>> structures.
>>>>>>
>>>>>> Why not support defaults in scope of DEC file or associated .h file? The
>>>>>> @DefaultValue tag in .h file is optional, so what you suggest here is
>>>>>> supported.
>>>>>>
>>>>>
>>>>> To simplify the .DEC parser so it does not require AST.
>>>>
>>>>
>>>> This is pushing more work onto platform porting in DSC/FDF file. The PCD
>>>> concept
>>>> from the beginning included the idea that the developer that designs a new
>>>> PCD
>>>> and adds it to a DEC file gets to support a "preferred" default value that
>>>> is
>>>> applicable to most platforms, and the DSC/FDF files only need to provide
>>>> override
>>>> values if the "preferred" default does not work for that specific
>>>> platform. Why
>>>> should we change this fundamental PCD concept just to simplify the tools.
>>>>
>>>> I agree that dependency on CLANG/AST/Python bindings may not be the best
>>>> Implementation choice based on feedback received so far, but should not
>>>> mean
>>>> burden the platform port and don't implement in better tools.
>>>>
>>>>>
>>>>>>> 3) Use the C pre processor with PP_FLAGS or ASLPP_FLAGS to handle the
>>>>>>> include
>>>>>>> infrastructure for maximum compatibility. Just like other rules in
>>>>>>> Conf/build_rule.txt. ?.pcd could be added to build_rule.txt.
>>>>>>
>>>>>> That is part of the current proposal.
>>>>>>
>>>>>>> 4) Don't add new PcdLib APIs. Return a pointer to the structure and use
>>>>>>> C code
>>> to
>>>>>>> access the data.
>>>>>>
>>>>>> That is supported today without this proposal.
>>>>>>
>>>>>> By adding new APIs, we can support access to individual fields within a
>>> Structured
>>>>>> PCD without having to require a local variable of the full C typedef.
>>>>>
>>>>> I don't see that as solving a real problem. From a walk up an use
>>>>> standpoint I
>>>>> initialize a C structure in a file, there is an API to return that
>>>>> structure and I
>>>>> dereference it with a pointer. That is how you write C code in any
>>>>> environment.
>>> Thus
>>>>> why do we need to invent another way to do this?
>>>>>
>>>>>> For Dynamic
>>>>>> or DynamicEx PCDs, individual fields can be accessed without having to
>>>>>> read/write
>>>>>> the entire structure.
>>>>>
>>>>> That could be an implementation optimization.
>>>>>
>>>>>>
>>>>>>> 5) OK someone is going to complain about type checking so add a new
>>>>>>> version of
>>>>>>> PcdGetPtr() that casts the pointer to the C pointer type returned. The
>>>>>>> type is
>>> in
>>>>> the
>>>>>>> AutoGen.h file (_PCD_GET_PTR_TYPE_##TokenName). If you don't use the
>>>>>>> new .pcd
>>> file
>>>>>>> syntax then you get a build break.
>>>>>>> 6) Don't be too restrictive on type checking. Support something like a
>>>>>>> device
>>>>> path.
>>>>>>> For example the globals in PlatformData.c of PlatformBdsLib could be PCD
>>> entries.
>>>>>>> This could be phase 2, and require a modified syntax if needed.
>>>>>>
>>>>>> This could be supported today using a VOID* PCD for each of this
>>>>>> structures.
>>>>>> Configuring through PCDs in a DSC file today as list of hex bytes is not
>>>>>> very
>>>>>> developer friendly. I agree that a phase 2 could help improve the
>>>>>> developer
>>>>>> experience configuring a VOID* buffer that is a sequence of Device Path
>>>>>> nodes.
>>>>>> Maybe even support the Device Path To String syntax a value syntax
>>>>>> extension.
>>>>>>
>>>>>>>
>>>>>>> This simpler scheme only requires initializing a global variable and
>>>>>>> being able
>>> to
>>>>>>> extract that information vs AST. The real value in this scheme is
>>>>>>> unifying the
>>>>>>> include infrastructure for C, ASL, and PCD. C can already access C
>>>>>>> structure
>>>>> members,
>>>>>>> seems like reinventing the wheel to come up with a complex scheme to
>>>>>>> abstract
>>> how
>>>>> to
>>>>>>> access C structure elements when a C pointer solves that problem.
>>>>>>
>>>>>> How would you initialize the global for a nested structure of many types
>>>>>> without
>>>>>> a parser?
>>>>>> How would you handle unions for a corner case when multiple union
>>>>>> members from the same union need to be initialized?
>>>>>
>>>>> Use the compiler we already have installed on the system as it is already
>>> configured
>>>>> to do the correct thing, and the produce and consumer are using the same
>>>>> tools.
>>>>>
>>>>> How are you going to deal with something like long (it is not the same
>>>>> width on
>>> all
>>>>> the IA32 compilers supported by edk2)? Or even structure packing rules?
>>>>> The
>>> default
>>>>> output of clang in not compatible with the EFI ABI and we have compiler
>>>>> flags and
>>>>> triples that fix that.
>>>>
>>>> I believe I have resolved all of the issues you raise here using
>>>> CLANG/AST. Type
>>>> 'long' is not supported as a leaf field type and generated an error in the
>>> prototype.
>>>> The supported leaf field types are in this proposal. I use the same
>>> ProcessorBind.h
>>>> mappings for CLANG for the supported leaf field types and it all works for
>>>> me.
>>>> CLANG/AST is only used to parse a C structure in a .h file. It is not
>>>> used for
>>>> compiling code, so there are never any EFI ABI issues with this use. CLANG
>>> supports
>>>> byte packing using the same #pragma pack syntax that is used in FW sources
>>>> and the
>>>> byte/bit offsets computed by CLANG match the byte/bit offsets from the
>>>> compiler
>>>> used to compile FW.
>>>>
>>>> As I mentioned at the top of email, I will evaluate using the current tool
>>>> chain
>>> tag
>>>> instead of CLANG/AST. I am confident the results will be the same for the
>>>> concerns
>>>> you raise here.
>>>>
>>>>>
>>>>> So the syntax probably needs some work as I'm making this up as I go
>>>>> along but you
>>>>> could have a *.pcd file that looks like:
>>>>>
>>>>> #include <BdsPlatform.h>
>>>>>
>>>>>
>>>>> // @ PCDTYPE [PcdsFixedAtBuild.common]
>>>>>
>>>>>
>>>>> // @PCD
>>>>>
>>> gMdeModulePkgTokenGuid|PcdUsbClassKeyboardDevicePath|EFI_DEVICE_PATH|gUsbClassDeviceP
>>>>> ath
>>>>> USB_CLASS_FORMAT_DEVICE_PATH gUsbClassDevicePath = {
>>>>> {
>>>>> {
>>>>> MESSAGING_DEVICE_PATH,
>>>>> MSG_USB_CLASS_DP,
>>>>> {
>>>>> (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
>>>>> (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
>>>>> }
>>>>> },
>>>>> 0xffff, // VendorId
>>>>> 0xffff, // ProductId
>>>>> CLASS_HID, // DeviceClass
>>>>> SUBCLASS_BOOT, // DeviceSubClass
>>>>> PROTOCOL_KEYBOARD // DeviceProtocol
>>>>> },
>>>>>
>>>>> {
>>>>> END_DEVICE_PATH_TYPE,
>>>>> END_ENTIRE_DEVICE_PATH_SUBTYPE,
>>>>> {
>>>>> END_DEVICE_PATH_LENGTH,
>>>>> 0
>>>>> }
>>>>> }
>>>>> };
>>>>>
>>>>> You do a quick parse to extract the meta data from the file: @ PCDTYPE
>>>>> [PcdsFixedAtBuild.common] and @PCD
>>>>>
>>> gMdeModulePkgTokenGuid|PcdUsbClassKeyboardDevicePath|EFI_DEVICE_PATH|gUsbClassDeviceP
>>>>> ath
>>>>> AutoGen a C program to do what you want and append it to the .pcd file.
>>>>> Compile and run the AutoGen code to create the output that could be as
>>>>> simple as
>>> the
>>>>> current PCD Pointer syntax.
>>>>>
>>>>> autogen code output looks like:
>>>>> // cat *.pcd file contents.
>>>>> // AutoGen Start.
>>>>> #include <stdio.h>
>>>>>
>>>>> int main() {
>>>>> char *c;
>>>>> int i;
>>>>>
>>>>> // @ PCDTYPE [PcdsFixedAtBuild.common]
>>>>> printf (" [PcdsFixedAtBuild.common]\n");
>>>>> // @PCD
>>>>>
>>> gMdeModulePkgTokenGuid|PcdUsbClassKeyboardDevicePath|EFI_DEVICE_PATH|gUsbClassDeviceP
>>>>> ath
>>>>> printf
>>> ("gMdeModulePkgTokenGuid|PcdUsbClassKeyboardDevicePath|EFI_DEVICE_PATH|{");
>>>>> for (i=0, c = (char *)(unsigned long long) &gUsbClassDevicePath; i <
>>>>> sizeof
>>>>> (gUsbClassDevicePath); i++) {
>>>>> printf (" 0x%02x,", c[i]);
>>>>> }
>>>>> printf (" }\n");
>>>>>
>>>>> return 0;
>>>>> }
>>>>>
>>>>> Thus basically use the same compiler on both sides, and some slightly
>>>>> modified
>>> form
>>>>> of the current PCD syntax (add the type). You could actually do this
>>>>> today with an
>>>>> INF file and a custom rule in the Conf/build_rule.txt. The only
>>>>> modification to
>>> the
>>>>> build system would adding the output files to the PCD database creation.
>>>>> There are
>>>>> other ways to do it but I'm a fan of making it work like C and ASL, as I
>>>>> think the
>>>>> symmetry is intuitive for the developer, and you don't need to learn a
>>>>> new way to
>>>>> specify packages, BuildOptions etc. as you are using the existing INF
>>>>> syntax to
>>> build
>>>>> and process for all file types.
>>>>>
>>>>> Another option is to abstract all the meta data in a C macro and follow
>>>>> the macro
>>>>> with the = {}; data. That is what we did, basically 1st pass the macro
>>>>> expands to
>>> the
>>>>> global. 2nd pass the macro expands to the code to write out the date. You
>>>>> still
>>> have
>>>>> to strip to bits you don't want before you compile the program (you don't
>>>>> want 2
>>>>> copies of all the preprocessed include stuff etc.
>>>>>
>>>>> So my point is you can get an 80% solution that is rock solid with zero
>>> constraints
>>>>> without going down the AST route, have it be a lot simpler, and not
>>>>> require a
>>> bunch
>>>>> of extra tools to be installed. I'm also a fan of using a new file type
>>>>> and an INF
>>>>> file vs. coming up with yet another edk2 unique syntax to do something
>>>>> the edk2
>>>>> already has a syntax to support.
>>>>>
>>>>> Ironically we asked the clang developers (that wrote the AST stuff) what
>>>>> was the
>>>>> safest way to do something like this and they recommended using the
>>>>> compiler in
>>> this
>>>>> fashion of my example. Our example was slightly more complex as we
>>>>> constructed an
>>>>> entire database, but close enough (no issue with the packing between
>>>>> structures in
>>>>> the PCD case).
>>>>>
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Andrew Fish
>>>>>
>>>>>>
>>>>>>>
>>>>>>> "The real art is knowing what to leave out, not what to put in" quote
>>>>>>> from Steve
>>>>>>> Jobs.
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> Andrew Fish
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> edk2-devel mailing list
>>>>>>> [email protected]
>>>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>>> _______________________________________________
>>>>>> edk2-devel mailing list
>>>>>> [email protected]
>>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel