> On May 19, 2016, at 12:16 PM, Kinney, Michael D <michael.d.kin...@intel.com> 
> wrote:
> 
> Andrew,
> 
> My responses embedded below.
> 

Mike,

Likewise. 

> Mike
> 
>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of 
>> Andrew Fish
>> Sent: Thursday, May 19, 2016 10:53 AM
>> To: Kinney, Michael D <michael.d.kin...@intel.com>; edk2-devel@lists.01.org 
>> <edk2-
>> de...@ml01.01.org>
>> Subject: Re: [edk2] [RFC] Structured PCD Proposal
>> 
>> 
>>> On May 19, 2016, at 2:26 AM, Laszlo Ersek <ler...@redhat.com> 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. 

> 
>> 
>> 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. 

>> 
>>>> ## 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. 

> 
>> 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. 

>> 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. 

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|gUsbClassDevicePath
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|gUsbClassDevicePath
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|gUsbClassDevicePath
  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
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to