Dear all, we have discussed that a protocol is needed to fix-up device trees loaded by GRUB or other boot managers.
In the U-Boot code we have actually the following actions for device-trees: * load the device-tree to memory * copy the device-tree to an allocated memory region which has 12 KiB free space for device-tree fix-ups * do the actual fix-ups, i.e. add new nodes or change properties * reserve memory according to the /reserved-memory node and the memory reservation block as EfiBootServicesData or as EfiReservedMemoryType for no-map regions * install the device-tree as configuration table So I think the usage of a DT fix-up protocol could take the following steps: * GRUB loads the device-tree allocating sufficient memory for fix-ups * GRUB calls the protocol a fist time to add extra nodes and properties * GRUB applies its own device-tree fix-ups * GRUB calls the protocol a second time which - reserves memory according to the /reserved-memory node - installs the device-tree as configuration table One could join both service calls if GRUB applies its own fix-ups first. But maybe GRUB wants to analyze U-Boot's fix-ups before committing its own ones. So lets define a bit-field to pass to the fix-up protocol: /* Add nodes and update properties */ #define EFI_DT_APPLY_FIXUPS 0x00000001 /* * Reserve memory according to the /reserved-memory node * and the memory reservation block */ #define EFI_DT_RESERVE_MEMORY 0x00000002 /* Install the device-tree as configuration table */ #define EFI_DT_INSTALL_TABLE 0x00000004 Here is the rest of the proposed protocol definition: #define EFI_DT_FIXUP_PROTOCOL_GUID \ { 0xe617d64c, 0xfe08, 0x46da, \ { 0xf4, 0xdc, 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00 } } typedef struct _EFI_DT_FIXUP_PROTOCOL { EFI_DT_FIXUP fixup; } EFI_DT_FIXUP_PROTOCOL; typedef EFI_STATUS (EFIAPI *EFI_DT_FIXUP) ( IN EFI_DT_FIXUP_PROTOCOL *This, IN VOID *Fdt, IN OUT UINTN *BufferSize, IN UINT32 Flags, ); This: Pointer to the protocol Fdt: Buffer with the device-tree. This shall be memory of type EfiACPIReclaimMemory if Flags contains EFI_DT_INSTALL_TABLE. BufferSize: Pointer to the size of the buffer including trailing unused bytes for fix-ups. If the buffer size is too small, the required buffer size is returned. Flags: Bitmap containing at least one of the values EFI_DT_APPLY_FIXUPS, EFI_DT_RESERVE_MEMORY, EFI_DT_INSTALL_TABLE. Indicates the actions to be applied to the device-tree. The selected actions indicated in Flags are applied in the sequence: * Add nodes and update properties. * Reserve memory according to the /reserved-memory node and the memory reservation block * Install the device-tree as configuration table Memory is reserved as EfiBootServicesData if the reservation does not carry the no-map property and as EfiReservedMemoryType if it is marked as no-map. If *BufferSize exceeds the value of the totalsize field header of device-tree header upon entry to the service, the totalsize field is set to *BufferSize. Return values: EFI_INVALID_PARAMETER - This is NULL or does not point to a valid EFI_DT_FIXUP_PROTOCOL implementation. EFI_INVALID_PARAMETER - Fdt or BufferSize is NULL EFI_INVALID_PARAMETER - *Fdt is not a valid device-tree (e.g. incorrect value of magic) EFI_INVALID_PARAMETER - Invalid value of Flags (zero or unknown bit) EFI_BUFFER_TOO_SMALL - The buffer is too small to apply the fix-ups. EFI_SUCCESS - All steps succeeded If EFI_BUFFER_TOO_SMALL is returned, the device-tree is unmodified and *BufferSize is updated with the required buffer size for the provided device-tree. The required buffer size when called with EFI_DT_APPLY_FIXUPS should enforce at least 4 KiB unused space for additional fix-ups by the operating system or the caller. The available space in the device-tree shall be determined using the device-tree header fields: Available = header->totalsize - header->off_dt_strings - header->size_dt_strings; (The strings block is always last in the flattened device-tree. There might be more space between blocks but not all device-tree libraries can use it.) The required buffer size when called without EFI_DT_APPLY_FIXUPS shall be the value of the totalsize field of the flattened device tree header. If any other error code is returned, the state of the device-tree is undefined. The caller should discard the buffer content. The extent to which the validity of the device-tree is checked is implementation dependent. But a buffer without the correct value of the magic field of the flattened device tree header should always be rejected. The protocol implementation is not required to check if the device-tree is in memory of type EfiACPIReclaimMemory. Looking forward to your feedback. Best regards Heinrich _______________________________________________ boot-architecture mailing list boot-architecture@lists.linaro.org https://lists.linaro.org/mailman/listinfo/boot-architecture