On 11/30/15 10:50, Laszlo Ersek wrote:
> On 11/30/15 10:28, Ard Biesheuvel wrote:
>> On 30 November 2015 at 10:22, Shannon Zhao <zhaoshengl...@huawei.com> wrote:
>>>
>>>
>>> On 2015/11/30 16:53, Laszlo Ersek wrote:
>>>> On 11/29/15 07:31, Shannon Zhao wrote:
>>>>> From: Shannon Zhao <shannon.z...@linaro.org>
>>>>>
>>>>> Here we add the memory space for the memory nodes except the lowest one
>>>>> in FDT. So these spaces will show up in the UEFI memory map.
>>>>>
>>>>> Contributed-under: TianoCore Contribution Agreement 1.0
>>>>> Signed-off-by: Shannon Zhao <shannon.z...@linaro.org>
>>>>> ---
>>>>>  ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.c   | 34 
>>>>> ++++++++++++++++++++++++++++++++++
>>>>>  ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.inf |  4 ++++
>>>>>  2 files changed, 38 insertions(+)
>>>>>
>>>>> diff --git a/ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.c 
>>>>> b/ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.c
>>>>> index 74f80d1..2c8d785 100644
>>>>> --- a/ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.c
>>>>> +++ b/ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.c
>>>>> @@ -27,6 +27,7 @@
>>>>>  #include <Library/HobLib.h>
>>>>>  #include <libfdt.h>
>>>>>  #include <Library/XenIoMmioLib.h>
>>>>> +#include <Library/DxeServicesTableLib.h>
>>>>>
>>>>>  #include <Guid/Fdt.h>
>>>>>  #include <Guid/VirtioMmioTransport.h>
>>>>> @@ -304,6 +305,8 @@ InitializeVirtFdtDxe (
>>>>>    UINT64                         FwCfgDataSize;
>>>>>    UINT64                         FwCfgDmaAddress;
>>>>>    UINT64                         FwCfgDmaSize;
>>>>> +  UINT64                         CurBase;
>>>>> +  UINT64                         CurSize;
>>>>>
>>>>>    Hob = GetFirstGuidHob(&gFdtHobGuid);
>>>>>    if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {
>>>>> @@ -332,6 +335,37 @@ InitializeVirtFdtDxe (
>>>>>        break;
>>>>>      }
>>>>>
>>>>> +    //
>>>>> +    // Check for memory node and add the memory spaces expect the lowest 
>>>>> one
>>>>> +    //
>>>>
>>>> (1) Based on the DTB node, which looks like:
>>>>
>>>>         memory {
>>>>                 reg = <0x0 0x40000000 0x0 0x8000000>;
>>>>                 device_type = "memory";
>>>>         };
>>>>
>>>> I agree that checking it here, before we look at "compatible", is a good
>>>> thing.
>>>>
>>>> However, can you please factor this out into a separate function? (Just
>>>> within this file, as a STATIC function.)
>>>>
>>>> I propose that the function return a BOOLEAN:
>>>> - TRUE if the node was a match (either successfully or unsuccessfully);
>>>>   in which case you can "continue;" with the next iteration directly
>>>> - FALSE, if there is no match (i.e., the current iteration must
>>>>   proceed, in order to look for different device types)
>>>>
>>>
>>> Sure.
>>>
>>>>> +    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
>>>>> +    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
>>>>> +      //
>>>>> +      // Get the 'reg' property of this node. For now, we will assume
>>>>> +      // two 8 byte quantities for base and size, respectively.
>>>>> +      //
>>>>> +      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
>>>>> +      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
>>>>> +
>>>>> +        CurBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
>>>>> +        CurSize = fdt64_to_cpu (((UINT64 *)RegProp)[1]);
>>>>> +
>>>>> +        if (FixedPcdGet64 (PcdSystemMemoryBase) != CurBase) {
>>>>> +          Status = gDS->AddMemorySpace(EfiGcdMemoryTypeSystemMemory,
>>>>> +                                       CurBase, CurSize,
>>>>> +                                       EFI_MEMORY_WB | 
>>>>> EFI_MEMORY_RUNTIME);
>>>>
>>>> (1) The edk2 coding style requires a space between the function name (or
>>>> function pointer) and the opening paren.
>>>>
>>>> (2) Regarding the indentation of function arguments, they are aligned
>>>> with the first or (more usually:) second character of the function or
>>>> *member* name. In this case, they should be aligned with the second "d"
>>>> in "AddMemorySpace".
>>>>
>>> Thanks for explain the edk2 coding style. Sorry, I'm not familiar with this.
>>>
>>>> (3) The last argument is a bitmask of capabilities. As far as I
>>>> remember, all system memory regions I've seen dumped by Linux from the
>>>> UEFI memmap at startup had all of: UC | WC | WT | WB.
>>>>
>>>> I agree that RUNTIME and WB should be listed here, but do you have any
>>>> particular reason for not allowing UC|WC|WT?
>>>>
>>>> (4) Related question -- when you boot the guest kernel with this patch
>>>> in the firmware, and pass "efi=debug" to Linux, do the memory attributes
>>>> of the additional NUMA nodes look identically to the "base" memory? (I'm
>>>> asking this to see if we need additional gDS->SetMemorySpaceAttributes()
>>>> calls.)
>>>>
>>>> Can you paste a sample output from "efi=debug"?
>>>>
>>>
>>> Processing EFI memory map:
>>>   0x000004000000-0x000007ffffff [Memory Mapped I/O  |RUN|  |XP|  |  |  |
>>>   |  |  |  |UC]
>>>   0x000009010000-0x000009010fff [Memory Mapped I/O  |RUN|  |XP|  |  |  |
>>>   |  |  |  |UC]
>>>   0x000040000000-0x00004000ffff [Loader Data        |   |  |  |  |  |  |
>>>   |WB|WT|WC|UC]
>>>   0x000040010000-0x00004007ffff [Conventional Memory|   |  |  |  |  |  |
>>>   |WB|WT|WC|UC]
>>>
>>> [cut some information here]
>>>
>>>   0x000060000000-0x0000bfffffff [Conventional Memory|RUN|  |  |  |  |  |
>>>   |WB|  |  |  ]
>>>
>>> Looks like the region is showed with the attributes we set. While
>>> comparing with other Conventional Memory, it doesn't have RUNTIME. So
>>> drop it?
>>>
>>
>> You should not set the runtime bit, but you should set the UC, WC and
>> WT bits, as Laszlo mentioned.
> 
> After reading the specs a bit more, I think the following should be done:
> 
> - Call AddMemorySpace() with Capabilities=WB|WT|WC|UC (and nothing
>   else) -- as you say. That is, in the existing call, clear RUNTIME, and
>   add WT|WC|UC.
> 
> - Then call SetMemorySpaceAttributes too, for the same range (each
>   range), with Attributes=WB only. The default attributes (after the
>   AddMemorySpace() call) don't seem to be specified by the PI spec, so
>   we had better specify explicitly what caching we'd like. (The UEFI
>   memmap dump also shows the capabilities only, not the current
>   setting.)
> 
>   So the point here is to set WB|WT|WC|UC as capabilities, and WB as
>   actual attribute.

Sigh. This could get messy. gDS->SetMemorySpaceAttributes() is
ultimately implemented by the CPU arch protocol driver, which in this
case is ArmPkg/Drivers/CpuDxe.

However, that driver is currently dispatched strictly later than VirtFdtDxe.

Should we add ArmPkg/Drivers/CpuDxe to the APRIORI file too, just before
VirtFdtDxe?

Or else, if we don't call gDS->SetMemorySpaceAttributes(), what do you
think will be the default caching attribute for the NUMA ranges?

It appears the simplest thing to try is to add CpuDxe to APRIORI DXE.

Thanks
Laszlo

> - If either of these calls fails, it should be logged on error level
>   (naming the range and also which call of the above two failed), but
>   we should continue processing the DTB either way.
> 
> Thanks
> Laszlo
> 
>>
>>>>> +          if (EFI_ERROR(Status)) {
>>>>> +            ASSERT_EFI_ERROR(Status);
>>>>> +          }
>>>>
>>>> (5) "ASSERT_EFI_ERROR (Status)" would suffice.
>>>>
>>>> However, I think I'd prefer if we just logged an error here (with
>>>> EFI_D_ERROR level), and continued (i.e., returned TRUE).
>>>>
>>>>> +      DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n",
>>>>> +                 __FUNCTION__, CurBase, CurBase + CurSize - 1));
>>>>> +        }
>>>>
>>>> (6) This isn't indented correctly (not just the arguments).
>>>>
>>>>> +      } else {
>>>>> +        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
>>>>> +               __FUNCTION__));
>>>>> +      }
>>>>
>>>> (7) I think this error log branch is not necessary here. The same will
>>>> have been logged in the code that is modified by patch #1.
>>>>
>>>
>>> Will fix these and re-send a new version.
>>>
>>> Thanks,
>>> --
>>> Shannon
>>>
> 

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

Reply via email to