19#include <Protocol/DevicePath.h>
22#include <Library/BaseLib.h>
23#include <Library/BaseMemoryLib.h>
24#include <Library/BaseOverflowLib.h>
25#include <Library/DebugLib.h>
26#include <Library/DevicePathLib.h>
27#include <Library/MemoryAllocationLib.h>
28#include <Library/PcdLib.h>
29#include <Library/PrintLib.h>
30#include <Library/UefiBootServicesTableLib.h>
31#include <Library/UefiRuntimeServicesTableLib.h>
34#define DEVICE_PATH_PROPERTY_DATA_SIGNATURE \
35 SIGNATURE_32 ('D', 'p', 'p', 'P')
38#define PROPERTY_DATABASE_FROM_PROTOCOL(This) \
41 DEVICE_PATH_PROPERTY_DATA, \
43 DEVICE_PATH_PROPERTY_DATA_SIGNATURE \
54#define APPLE_PATH_PROPERTIES_VARIABLE_NAME L"AAPL,PathProperties"
55#define APPLE_PATH_PROPERTY_VARIABLE_MAX_SIZE 768
56#define APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM 0x10000
58#define EFI_DEVICE_PATH_PROPERTY_NODE_SIGNATURE \
59 SIGNATURE_32 ('D', 'p', 'n', '\0')
61#define PROPERTY_NODE_FROM_LIST_ENTRY(Entry) \
62 ((EFI_DEVICE_PATH_PROPERTY_NODE *)( \
65 EFI_DEVICE_PATH_PROPERTY_NODE_HDR, \
67 EFI_DEVICE_PATH_PROPERTY_NODE_SIGNATURE \
71#define EFI_DEVICE_PATH_PROPERTY_NODE_SIZE(Node) \
72 (sizeof (EFI_DEVICE_PATH_PROPERTY_BUFFER_NODE_HDR) + GetDevicePathSize (&(Node)->DevicePath))
88#define EFI_DEVICE_PATH_PROPERTY_SIGNATURE \
89 SIGNATURE_32 ('D', 'p', 'p', '\0')
91#define EFI_DEVICE_PATH_PROPERTY_DATABASE_VERSION 1
93#define EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY(Entry) \
96 EFI_DEVICE_PATH_PROPERTY, \
98 EFI_DEVICE_PATH_PROPERTY_SIGNATURE \
101#define EFI_DEVICE_PATH_PROPERTY_SIZE(Property) \
102 ((Property)->Name->Size + (Property)->Value->Size)
104#define EFI_DEVICE_PATH_PROPERTY_VALUE_SIZE(Property) \
105 ((Property)->Value->Size - sizeof (*(Property)->Value))
107#define NEXT_EFI_DEVICE_PATH_PROPERTY(Property) \
108 (EFI_DEVICE_PATH_PROPERTY *)( \
109 (UINTN)(Property) + EFI_DEVICE_PATH_PROPERTY_SIZE (Property) \
126#define APPLE_THUNDERBOLT_NATIVE_HOST_INTERFACE_PROTOCOL_GUID \
127 { 0xC649D4F3, 0xD502, 0x4DAA, \
128 { 0xA1, 0x39, 0x39, 0x4A, 0xCC, 0xF2, 0xA6, 0x3B } }
137 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
141 UINTN DevicePathSize;
142 UINTN DevicePathSize2;
144 Node = GetFirstNode (&DevicePathPropertyData->Nodes);
145 DevicePathSize = GetDevicePathSize (DevicePath);
147 while (!IsNull (&DevicePathPropertyData->Nodes, Node)) {
150 if ( (DevicePathSize == DevicePathSize2)
156 Node = GetNextNode (&DevicePathPropertyData->Nodes, Node);
167 IN CONST CHAR16 *Name
170 LIST_ENTRY *Property;
172 Property = GetFirstNode (&Node->Hdr.Properties);
174 while (!IsNull (&Node->Hdr.Properties, Property)) {
179 Property = GetNextNode (&Node->Hdr.Properties, Property);
199 Status =
gBS->LocateHandleBuffer (
207 if (!EFI_ERROR (Status)) {
208 for (Index = 0; Index < NumberHandles; ++Index) {
209 Status =
gBS->HandleProtocol (
215 if (!EFI_ERROR (Status)) {
216 if (*(UINT32 *)((UINTN)Interface +
sizeof (UINT32)) == 0) {
217 (*(VOID (EFIAPI **)(VOID *))((UINTN)Interface + 232))(Interface);
253 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
254 IN CONST CHAR16 *Name,
255 OUT VOID *Value OPTIONAL,
263 BOOLEAN BufferTooSmall;
268 return EFI_NOT_FOUND;
272 if (Property == NULL) {
273 return EFI_NOT_FOUND;
277 BufferTooSmall = PropertySize > *
Size;
278 *
Size = PropertySize;
280 if (!BufferTooSmall) {
285 return EFI_BUFFER_TOO_SMALL;
308 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
309 IN CONST CHAR16 *Name,
316 UINTN DevicePathSize;
318 UINTN PropertyNameSize;
319 UINTN PropertyValueSize;
327 DevicePathSize = GetDevicePathSize (DevicePath);
328 Node = AllocateZeroPool (
sizeof (*Node) + DevicePathSize);
331 return EFI_OUT_OF_RESOURCES;
351 if (Property != NULL) {
358 RemoveEntryList (&Property->
Link);
362 FreePool (Property->
Name);
363 FreePool (Property->
Value);
368 Property = AllocateZeroPool (
sizeof (*Property));
370 if (Property == NULL) {
371 return EFI_OUT_OF_RESOURCES;
374 PropertyNameSize =
sizeof (*PropertyName) + StrSize (Name);
375 PropertyName = AllocateZeroPool (PropertyNameSize);
376 Property->
Name = PropertyName;
377 if (PropertyName == NULL) {
379 return EFI_OUT_OF_RESOURCES;
382 PropertyValueSize =
sizeof (*PropertyValue) +
Size;
383 PropertyValue = AllocateZeroPool (PropertyValueSize);
384 Property->
Value = PropertyValue;
386 if (PropertyValue == NULL) {
387 FreePool (PropertyName);
389 return EFI_OUT_OF_RESOURCES;
394 CopyMem (&Property->
Name->
Data[0], Name, PropertyNameSize - sizeof (*PropertyName));
395 Property->
Name->
Size = (UINT32)PropertyNameSize;
398 Property->
Value->
Size = (UINT32)PropertyValueSize;
424 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
425 IN CONST CHAR16 *Name
435 return EFI_NOT_FOUND;
439 if (Property == NULL) {
440 return EFI_NOT_FOUND;
443 DevicePathPropertyData->
Modified = TRUE;
445 RemoveEntryList (&Property->
Link);
449 FreePool (Property->
Name);
450 FreePool (Property->
Value);
454 RemoveEntryList (&Node->
Hdr.
Link);
488 LIST_ENTRY *NodeWalker;
490 LIST_ENTRY *Property;
491 UINT32 NumberOfNodes;
494 BOOLEAN BufferTooSmall;
498 if (IsListEmpty (Nodes)) {
503 if (PcdGetBool (PcdEnableAppleThunderboltSync)) {
507 NodeWalker = GetFirstNode (Nodes);
508 BufferSize =
sizeof (*Buffer);
511 while (!IsNull (Nodes, NodeWalker)) {
521 NodeWalker = GetNextNode (Nodes, NodeWalker);
526 DEBUG ((DEBUG_VERBOSE,
"Saving to %p, given %u, requested %u\n",
Buffer, (UINT32)*
Size, (UINT32)BufferSize));
528 BufferTooSmall = *
Size < BufferSize;
530 if (BufferTooSmall) {
531 return EFI_BUFFER_TOO_SMALL;
534 Buffer->Size = (UINT32)BufferSize;
536 Buffer->NumberOfNodes = NumberOfNodes;
538 NodeWalker = GetFirstNode (Nodes);
540 BufferNode = &
Buffer->Nodes[0];
542 while (!IsNull (Nodes, NodeWalker)) {
555 BufferSize +=
sizeof (BufferNode->
Hdr);
556 BufferPtr = (UINT8 *)BufferNode + BufferSize;
573 Property = GetNextNode (
579 BufferNode->
Hdr.
Size = (UINT32)BufferSize;
581 (UINTN)BufferNode + BufferSize
584 NodeWalker = GetNextNode (Nodes, NodeWalker);
594 IN EFI_GUID *VendorGuid,
601 CHAR16 IndexBuffer[5];
602 UINT32 NumberOfVariables;
603 UINT32 VariableIndex;
604 CHAR16 VariableName[64];
607 UINTN CurrentBufferSize;
617 NumberOfVariables = 0;
619 Status = EFI_BUFFER_TOO_SMALL;
624 sizeof (IndexBuffer),
630 StrCatS (VariableName,
ARRAY_SIZE (VariableName), IndexBuffer);
633 Status =
gRT->GetVariable (
642 if (BaseOverflowAddUN (BufferSize, DataSize, &BufferSize)) {
646 return EFI_OUT_OF_RESOURCES;
662 Buffer = AllocateZeroPool (BufferSize);
664 return EFI_OUT_OF_RESOURCES;
667 BufferPtr = (UINT8 *)
Buffer;
668 CurrentBufferSize = BufferSize;
669 Status = EFI_SUCCESS;
671 for (VariableIndex = 0; VariableIndex < NumberOfVariables; ++VariableIndex) {
674 sizeof (IndexBuffer),
680 StrCatS (VariableName,
ARRAY_SIZE (VariableName), IndexBuffer);
682 DataSize = CurrentBufferSize;
683 Status =
gRT->GetVariable (
691 if (EFI_ERROR (Status)) {
696 Status =
gRT->SetVariable (VariableName, VendorGuid, Attributes, 0, NULL);
698 if (EFI_ERROR (Status)) {
703 BufferPtr += DataSize;
704 CurrentBufferSize -= DataSize;
711 if ( (
Buffer->Size != BufferSize)
713 || (
Buffer->NumberOfNodes == 0))
719 if (EFI_ERROR (Status)) {
728 BufferNode = &
Buffer->Nodes[0];
729 for (NodeIndex = 0; NodeIndex <
Buffer->NumberOfNodes; ++NodeIndex) {
730 DataSize = GetDevicePathSize (&BufferNode->
DevicePath);
734 (UINTN)BufferNode + DataSize +
sizeof (*
Buffer)
738 (UINTN)NameData + NameData->
Size
746 DevicePathPropertyData->Protocol.SetProperty (
747 &DevicePathPropertyData->Protocol,
749 (CHAR16 *)&NameData->
Data,
750 (VOID *)&ValueData->
Data,
753 - sizeof (ValueData->
Size)
758 (UINTN)ValueData + ValueData->
Size
763 (UINTN)ValueData + ValueData->
Size + NameData->
Size
769 (UINTN)BufferNode + (UINTN)BufferNode->
Hdr.
Size
798 UINT32 VariableIndex;
799 CHAR16 IndexBuffer[5];
800 CHAR16 VariableName[64];
807 if (EFI_ERROR (Status)) {
808 DEBUG ((DEBUG_ERROR,
"OCDP: Uninstall failed - %r\n", Status));
812 Status =
gBS->LocateProtocol (
818 if (!EFI_ERROR (Status)) {
823 DevicePathPropertyData = AllocateZeroPool (
sizeof (*DevicePathPropertyData));
824 if (DevicePathPropertyData == NULL) {
836 InitializeListHead (&DevicePathPropertyData->
Nodes);
838 if (PcdGetBool (PcNvramInitDevicePropertyDatabase)) {
842 DevicePathPropertyData
845 if (EFI_ERROR (Status)) {
846 FreePool (DevicePathPropertyData);
850 DevicePathPropertyData->
Modified = FALSE;
855 DevicePathPropertyData
858 if (EFI_ERROR (Status)) {
859 FreePool (DevicePathPropertyData);
863 if (DevicePathPropertyData->
Modified) {
871 if (Status != EFI_BUFFER_TOO_SMALL) {
872 FreePool (DevicePathPropertyData);
876 Buffer = AllocateZeroPool (DataSize);
878 FreePool (DevicePathPropertyData);
887 if (EFI_ERROR (Status)) {
889 FreePool (DevicePathPropertyData);
894 Attributes = (EFI_VARIABLE_NON_VOLATILE
895 | EFI_VARIABLE_BOOTSERVICE_ACCESS
896 | EFI_VARIABLE_RUNTIME_ACCESS);
897 BufferPtr = (UINT8 *)
Buffer;
899 while (VariableIndex < APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM && DataSize > 0) {
902 sizeof (IndexBuffer),
908 StrCatS (VariableName,
ARRAY_SIZE (VariableName), IndexBuffer);
915 Status =
gRT->SetVariable (
923 if (EFI_ERROR (Status)) {
927 BufferPtr += VariableSize;
928 DataSize -= VariableSize;
933 if (EFI_ERROR (Status) || (DataSize != 0)) {
934 FreePool (DevicePathPropertyData);
941 sizeof (IndexBuffer),
947 StrCatS (VariableName,
ARRAY_SIZE (VariableName), IndexBuffer);
950 Status =
gRT->GetVariable (
958 if (Status != EFI_BUFFER_TOO_SMALL) {
959 Status = EFI_SUCCESS;
963 Status =
gRT->SetVariable (
974 if (EFI_ERROR (Status)) {
975 FreePool (DevicePathPropertyData);
980 DevicePathPropertyData->
Modified = FALSE;
984 Status =
gBS->InstallProtocolInterface (
987 EFI_NATIVE_INTERFACE,
991 if (EFI_ERROR (Status)) {
995 return &DevicePathPropertyData->
Protocol;
#define ARRAY_SIZE(Array)
EFI_GUID gAppleBootVariableGuid
EFI_GUID gAppleVendorVariableGuid
EFI_GUID gEfiDevicePathPropertyDatabaseProtocolGuid
#define EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL_REVISION
DMG_SIZE_DEVICE_PATH Size
#define PROPERTY_DATABASE_FROM_PROTOCOL(This)
STATIC EFI_DEVICE_PATH_PROPERTY_NODE * InternalGetPropertyNode(IN DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
STATIC VOID InternalSyncWithThunderboltDevices(VOID)
STATIC EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL DppDbProtocolTemplate
#define EFI_DEVICE_PATH_PROPERTY_SIZE(Property)
STATIC EFI_STATUS InternalReadEfiVariableProperties(IN EFI_GUID *VendorGuid, IN BOOLEAN DeleteVariables, IN DEVICE_PATH_PROPERTY_DATA *DevicePathPropertyData)
#define APPLE_THUNDERBOLT_NATIVE_HOST_INTERFACE_PROTOCOL_GUID
#define APPLE_PATH_PROPERTY_VARIABLE_MAX_SIZE
#define EFI_DEVICE_PATH_PROPERTY_NODE_SIGNATURE
EFI_STATUS EFIAPI DppDbGetPropertyBuffer(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, OUT EFI_DEVICE_PATH_PROPERTY_BUFFER *Buffer OPTIONAL, IN OUT UINTN *Size)
#define PROPERTY_NODE_FROM_LIST_ENTRY(Entry)
#define EFI_DEVICE_PATH_PROPERTY_NODE_SIZE(Node)
EFI_STATUS EFIAPI DppDbGetProperty(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *Name, OUT VOID *Value OPTIONAL, IN OUT UINTN *Size)
#define APPLE_PATH_PROPERTIES_VARIABLE_NAME
#define DEVICE_PATH_PROPERTY_DATA_SIGNATURE
#define EFI_DEVICE_PATH_PROPERTY_VALUE_SIZE(Property)
EFI_STATUS EFIAPI DppDbSetProperty(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *Name, IN VOID *Value, IN UINTN Size)
STATIC EFI_DEVICE_PATH_PROPERTY * InternalGetProperty(IN EFI_DEVICE_PATH_PROPERTY_NODE *Node, IN CONST CHAR16 *Name)
#define EFI_DEVICE_PATH_PROPERTY_DATABASE_VERSION
EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL * OcDevicePathPropertyInstallProtocol(IN BOOLEAN Reinstall)
#define EFI_DEVICE_PATH_PROPERTY_FROM_LIST_ENTRY(Entry)
EFI_GUID mAppleThunderboltNativeHostInterfaceProtocolGuid
EFI_STATUS EFIAPI DppDbRemoveProperty(IN EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *Name)
#define EFI_DEVICE_PATH_PROPERTY_SIGNATURE
#define APPLE_PATH_PROPERTY_VARIABLE_MAX_NUM
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
APPLE_EVENT_HANDLE Handle
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
STATIC VOID DeleteVariables(IN BOOLEAN PreserveBoot)
EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL Protocol
UINT32 NumberOfProperties
The size, in bytes, of the entire node.
The structure defining the header of a Device Property node.
EFI_DEVICE_PATH_PROTOCOL DevicePath
The device path for the current node.
EFI_DEVICE_PATH_PROPERTY_BUFFER_NODE_HDR Hdr
The node header structure.
The structure defining the header of a Device Property Buffer.
The structure exposed by the EFI_DEVICE_PATH_PROPERTY_DATABASE_PROTOCOL.
The structure defining the header of a Device Path Property.
UINT32 Size
The size, in bytes, of the current data set.
EFI_DEVICE_PATH_PROTOCOL DevicePath
EFI_DEVICE_PATH_PROPERTY_NODE_HDR Hdr
EFI_DEVICE_PATH_PROPERTY_DATA * Value
EFI_DEVICE_PATH_PROPERTY_DATA * Name