Skip to content

Add UUID-GUID conversion interfaces in ArmFfaLib #11004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -796,52 +796,6 @@ InitializeMiscMmCommunicateBuffer (
CopyGuid (&Buffer->HeaderGuid, ServiceGuid);
}

/**
Convert UUID to EFI_GUID format.
for example, If there is EFI_GUID named
"378daedc-f06b-4446-8314-40ab933c87a3",

EFI_GUID is saved in memory like:
dc ae 8d 37
6b f0 46 44
83 14 40 ab
93 3c 87 a3

However, UUID should be saved like:
37 8d ae dc
f0 6b 44 46
83 14 40 ab
93 3c 87 a3

FF-A and other software components (i.e. linux-kernel)
uses below format.

To patch mm-service properly, the passed uuid should be converted to
EFI_GUID format.

@param [in] Uuid Uuid
@param [out] Guid EFI_GUID

**/
STATIC
VOID
EFIAPI
ConvertUuidToEfiGuid (
IN UINT64 *Uuid,
OUT EFI_GUID *Guid
)
{
UINT32 *Data32;
UINT16 *Data16;

Data32 = (UINT32 *)Uuid;
Data32[0] = SwapBytes32 (Data32[0]);
Data16 = (UINT16 *)&Data32[1];
Data16[0] = SwapBytes16 (Data16[0]);
Data16[1] = SwapBytes16 (Data16[1]);
CopyGuid (Guid, (EFI_GUID *)Uuid);
}

/**
A loop to delegate events from SPMC.
DelegatedEventLoop() calls ArmCallSvc() to exit to SPMC.
Expand Down Expand Up @@ -911,7 +865,7 @@ DelegatedEventLoop (
FfaMsgInfo.DirectMsgVersion = DirectMsgV2;
Uuid[0] = EventCompleteSvcArgs->Arg2;
Uuid[1] = EventCompleteSvcArgs->Arg3;
ConvertUuidToEfiGuid (Uuid, &ServiceGuid);
ConvertUuidToGuid ((GUID *)Uuid, &ServiceGuid);
ServiceType = GetServiceType (&ServiceGuid);
} else {
Status = EFI_INVALID_PARAMETER;
Expand Down
47 changes: 2 additions & 45 deletions MdeModulePkg/Library/ArmFfaLib/ArmFfaCommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,49 +32,6 @@
BOOLEAN gFfaSupported;
UINT16 gPartId;

/**
Convert EFI_GUID to UUID format.
for example, If there is EFI_GUID named
"378daedc-f06b-4446-8314-40ab933c87a3",

EFI_GUID is saved in memory like:
dc ae 8d 37
6b f0 46 44
83 14 40 ab
93 3c 87 a3

However, UUID should be saved like:
37 8d ae dc
f0 6b 44 46
83 14 40 ab
93 3c 87 a3

FF-A and other software components (i.e. linux-kernel)
uses below format.

@param [in] Guid EFI_GUID
@param [out] Uuid Uuid

**/
STATIC
VOID
EFIAPI
ConvertEfiGuidToUuid (
IN EFI_GUID *Guid,
OUT UINT64 *Uuid
)
{
UINT32 *Data32;
UINT16 *Data16;

CopyGuid ((EFI_GUID *)Uuid, Guid);
Data32 = (UINT32 *)Uuid;
Data32[0] = SwapBytes32 (Data32[0]);
Data16 = (UINT16 *)&Data32[1];
Data16[0] = SwapBytes16 (Data16[0]);
Data16[1] = SwapBytes16 (Data16[1]);
}

/**
Convert EFI_STATUS to FFA return code.

Expand Down Expand Up @@ -525,7 +482,7 @@ ArmFfaLibPartitionInfoGet (
}

if (ServiceGuid != NULL) {
ConvertEfiGuidToUuid (ServiceGuid, Uuid);
ConvertGuidToUuid (ServiceGuid, (GUID *)Uuid);
} else {
ZeroMem (Uuid, sizeof (Uuid));
}
Expand Down Expand Up @@ -689,7 +646,7 @@ ArmFfaLibMsgSendDirectReq2 (
}

if (ServiceGuid != NULL) {
ConvertEfiGuidToUuid (ServiceGuid, Uuid);
ConvertGuidToUuid (ServiceGuid, (GUID *)Uuid);
} else {
ZeroMem (Uuid, sizeof (Uuid));
}
Expand Down
95 changes: 95 additions & 0 deletions MdePkg/Include/Library/BaseLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -4715,6 +4715,101 @@ BitFieldCountOnes64 (
IN UINTN EndBit
);

/*******************************************************************************

UUID (Universally Unique IDentifier), as defined in RFC4122
(https://datatracker.ietf.org/doc/html/rfc4122#section-4.1), is a 128-bit number
used to uniquely identify information in computer systems.

UUIDs contains 5 fields:
- time_low: 32 bits
- time_mid: 16 bits
- time_hi_and_version: 16 bits
- clock_seq_hi_and_reserved: 8 bits
- clock_seq_low: 8 bits
- node: 8 bits * 6

Each field encoded with the Most Significant Byte first (known as network byte
order, or big-endian).

GUID (Globally Unique Identifier), on the other hand, is a 128-bit number used
in UEFI environments, which is similar to UUID but has a different byte order
in memory. See https://uefi.org/specs/UEFI/2.11/Apx_A_GUID_and_Time_Formats.html

GUID also contains 5 fields:
- TimeLow: 32 bits
- TimeMid: 16 bits
- TimeHiAndVersion: 16 bits
- ClockSeqHighAndReserved: 16 bits
- ClockSeqLow: 8 bits
- Node: 8 bits * 6

TimeLow, TimeMid, TimeHighAndVersion fields in the EFI are encoded with the Least
Significant Byte first (also known as little-endian).

Example:
Consider the same string representation/registry format for MM communication v2:
"378daedc-f06b-4446-8314-40ab933c87a3"

In UUID format, it is represented as:
- Data fields:
- time_low: 0x37 0x8d 0xae 0xdc (0x378daedc in big-endian)
- time_mid: 0xf0 0x6b (0xf06b in big-endian)
- time_hi_and_version: 0x44 0x46 (0x4446 in big-endian)
- clock_seq_hi_and_reserved: 0x83
- clock_seq_low: 0x14
- node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
- Byte representation in memory:
- 37 8d ae dc f0 6b 44 46 83 14 40 ab 93 3c 87 a3

However, in GUID format, it is represented as:
- Data fields:
- TimeLow: 0xdc 0xae 0x8d 0x37 (0x378daedc in little-endian)
- TimeMid: 0x6b 0xf0 (0xf06b in little-endian)
- TimeHiAndVersion: 0x46 0x44 (0x4446 in little-endian)
- ClockSeqHighAndReserved: 0x83
- ClockSeqLow: 0x14
- Node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
- Byte representation in memory:
- dc ae 8d 37 6b f0 46 44 83 14 40 ab 93 3c 87 a3

*******************************************************************************/

/**
This function converts a GUID in UEFI format to a UUID in RFC4122 format.

The conversion is done by swapping the byte order of the TimeLow, TimeMid, and
TimeHiAndVersion fields, while keeping the ClockSeq and Node fields unchanged.

@param [in] FromGuid GUID in format to be converted to UUID RFC4122 format.
@param [out] ToUuid Pointer to a GUID structure that will hold the converted
UUID in RFC4122 format.
**/
VOID
EFIAPI
ConvertGuidToUuid (
IN GUID *FromGuid,
OUT GUID *ToUuid
);

/**
This function converts a UUID in RFC4122 format to a GUID in UEFI format.

The conversion is done by swapping the byte order of the time_low, time_mid, and
time_hi_and_version fields, while keeping the ClockSeq and Node fields unchanged.
This function is symmetric to ConvertGuidToUuid.

@param [in] FromUuid UUID in RFC4122 format to be converted to GUID in UEFI format.
@param [out] ToGuid Pointer to a GUID structure that will hold the converted
GUID in UEFI format.
**/
VOID
EFIAPI
ConvertUuidToGuid (
IN GUID *FromUuid,
OUT GUID *ToGuid
);

//
// Base Library Checksum Functions
//
Expand Down
1 change: 1 addition & 0 deletions MdePkg/Library/BaseLib/BaseLib.inf
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
DivS64x64Remainder.c
ARShiftU64.c
BitField.c
ConvertGuidUuid.c
CpuDeadLoop.c
Cpu.c
LinkedList.c
Expand Down
121 changes: 121 additions & 0 deletions MdePkg/Library/BaseLib/ConvertGuidUuid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/** @file
Convert 128 bit unique identifier between GUID and UUID format.

Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include "BaseLibInternals.h"

/*******************************************************************************

UUID (Universally Unique IDentifier), as defined in RFC4122
(https://datatracker.ietf.org/doc/html/rfc4122#section-4.1), is a 128-bit number
used to uniquely identify information in computer systems.

UUIDs contains 5 fields:
- time_low: 32 bits
- time_mid: 16 bits
- time_hi_and_version: 16 bits
- clock_seq_hi_and_reserved: 8 bits
- clock_seq_low: 8 bits
- node: 8 bits * 6

Each field encoded with the Most Significant Byte first (known as network byte
order, or big-endian).

GUID (Globally Unique Identifier), on the other hand, is a 128-bit number used
in UEFI environments, which is similar to UUID but has a different byte order
in memory. See https://uefi.org/specs/UEFI/2.11/Apx_A_GUID_and_Time_Formats.html

GUID also contains 5 fields:
- TimeLow: 32 bits
- TimeMid: 16 bits
- TimeHiAndVersion: 16 bits
- ClockSeqHighAndReserved: 16 bits
- ClockSeqLow: 8 bits
- Node: 8 bits * 6

TimeLow, TimeMid, TimeHighAndVersion fields in the EFI are encoded with the Least
Significant Byte first (also known as little-endian).

Example:
Consider the same string representation/registry format for MM communication v2:
"378daedc-f06b-4446-8314-40ab933c87a3"

In UUID format, it is represented as:
- Data fields:
- time_low: 0x37 0x8d 0xae 0xdc (0x378daedc in big-endian)
- time_mid: 0xf0 0x6b (0xf06b in big-endian)
- time_hi_and_version: 0x44 0x46 (0x4446 in big-endian)
- clock_seq_hi_and_reserved: 0x83
- clock_seq_low: 0x14
- node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
- Byte representation in memory:
- 37 8d ae dc f0 6b 44 46 83 14 40 ab 93 3c 87 a3

However, in GUID format, it is represented as:
- Data fields:
- TimeLow: 0xdc 0xae 0x8d 0x37 (0x378daedc in little-endian)
- TimeMid: 0x6b 0xf0 (0xf06b in little-endian)
- TimeHiAndVersion: 0x46 0x44 (0x4446 in little-endian)
- ClockSeqHighAndReserved: 0x83
- ClockSeqLow: 0x14
- Node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
- Byte representation in memory:
- dc ae 8d 37 6b f0 46 44 83 14 40 ab 93 3c 87 a3

*******************************************************************************/

/**
This function converts a GUID in UEFI format to a UUID in RFC4122 format.

The conversion is done by swapping the byte order of the TimeLow, TimeMid, and
TimeHiAndVersion fields, while keeping the ClockSeq and Node fields unchanged.

@param [in] FromGuid GUID in format to be converted to UUID RFC4122 format.
@param [out] ToUuid Pointer to a GUID structure that will hold the converted
UUID in RFC4122 format.
**/
VOID
EFIAPI
ConvertGuidToUuid (
IN GUID *FromGuid,
OUT GUID *ToUuid
)
{
ASSERT (ToUuid != NULL);
ASSERT (FromGuid != NULL);

CopyGuid (ToUuid, FromGuid);
ToUuid->Data1 = SwapBytes32 (ToUuid->Data1);
ToUuid->Data2 = SwapBytes16 (ToUuid->Data2);
ToUuid->Data3 = SwapBytes16 (ToUuid->Data3);
}

/**
This function converts a UUID in RFC4122 format to a GUID in UEFI format.

The conversion is done by swapping the byte order of the time_low, time_mid, and
time_hi_and_version fields, while keeping the ClockSeq and Node fields unchanged.
This function is symmetric to ConvertGuidToUuid.

@param [in] FromUuid UUID in RFC4122 format to be converted to GUID in UEFI format.
@param [out] ToGuid Pointer to a GUID structure that will hold the converted
GUID in UEFI format.
**/
VOID
EFIAPI
ConvertUuidToGuid (
IN GUID *FromUuid,
OUT GUID *ToGuid
)
{
// The conversion is symmetric, so we can use the same function.
// The only difference is the order of the parameters.
ConvertGuidToUuid (
FromUuid,
ToGuid
);
}
Loading