From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Mon, 31 Mar 2025 17:56:58 +0000 (+0300) Subject: boot: Add EDID parsing X-Git-Tag: v258-rc1~668^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e86474151106df8619b40085e50af1c8945f9be3;p=thirdparty%2Fsystemd.git boot: Add EDID parsing Will be used for identifying the currently used display panel and choosing the appropriate DTB --- diff --git a/src/boot/edid.c b/src/boot/edid.c new file mode 100644 index 00000000000..62e338353ec --- /dev/null +++ b/src/boot/edid.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "edid.h" +#include "edid-fundamental.h" +#include "log.h" +#include "proto/edid-discovered.h" +#include "util.h" + +EFI_STATUS edid_get_discovered_panel_id(char16_t **ret_panel) { + assert(ret_panel); + + EFI_EDID_DISCOVERED_PROTOCOL *edid_discovered = NULL; + EFI_STATUS status = BS->LocateProtocol(MAKE_GUID_PTR(EFI_EDID_DISCOVERED_PROTOCOL), NULL, (void **) &edid_discovered); + if (EFI_STATUS_IS_ERROR(status)) + return status; + + if (!edid_discovered) + return EFI_UNSUPPORTED; + if (!edid_discovered->Edid) + return EFI_UNSUPPORTED; + if (edid_discovered->SizeOfEdid == 0) + return EFI_UNSUPPORTED; + + EdidHeader header; + if (edid_parse_blob(edid_discovered->Edid, edid_discovered->SizeOfEdid, &header) < 0) + return EFI_INCOMPATIBLE_VERSION; + + _cleanup_free_ char16_t *panel = xnew0(char16_t, 8); + if (edid_get_panel_id(&header, panel) < 0) + return EFI_INVALID_PARAMETER; + + *ret_panel = TAKE_PTR(panel); + return EFI_SUCCESS; +} diff --git a/src/boot/edid.h b/src/boot/edid.h new file mode 100644 index 00000000000..9832dadaab4 --- /dev/null +++ b/src/boot/edid.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "efi.h" + +EFI_STATUS edid_get_discovered_panel_id(char16_t **ret_panel); diff --git a/src/boot/hwids/device1.json b/src/boot/hwids/device1.json index 6649a76491e..5fa718c029c 100644 --- a/src/boot/hwids/device1.json +++ b/src/boot/hwids/device1.json @@ -3,7 +3,6 @@ "name": "Device 1", "compatible": "test,device-1", "hwids": [ - "2bdcafa9-727c-5e8b-b13b-236f1391c25a", - "c87886da-8026-5149-8c95-6d2504c1b7f9" + "75caebc1-5b41-5d33-a262-154720304180" ] } diff --git a/src/boot/meson.build b/src/boot/meson.build index d4bd202f6fe..c2a894d3236 100644 --- a/src/boot/meson.build +++ b/src/boot/meson.build @@ -292,6 +292,7 @@ libefi_sources = files( 'device-path-util.c', 'devicetree.c', 'drivers.c', + 'edid.c', 'efi-firmware.c', 'efi-string.c', 'efivars.c', diff --git a/src/boot/proto/edid-discovered.h b/src/boot/proto/edid-discovered.h new file mode 100644 index 00000000000..7c83fcdcaf9 --- /dev/null +++ b/src/boot/proto/edid-discovered.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "efi.h" + +#define EFI_EDID_DISCOVERED_PROTOCOL_GUID \ + GUID_DEF(0x1c0c34f6, 0xd380, 0x41fa, 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa) + +typedef struct { + uint32_t SizeOfEdid; + uint8_t *Edid; +} EFI_EDID_DISCOVERED_PROTOCOL; diff --git a/src/boot/test-chid-match.c b/src/boot/test-chid-match.c index 415681f201c..5a22db70e39 100644 --- a/src/boot/test-chid-match.c +++ b/src/boot/test-chid-match.c @@ -4,6 +4,8 @@ #include #include "chid.h" +#include "edid.h" +#include "efi-string.h" #include "smbios.h" #include "tests.h" @@ -12,6 +14,7 @@ extern size_t hwids_section_len; static struct { const RawSmbiosInfo smbios_info; + const char16_t *panel_id; uint32_t device_type; } info[] = { { @@ -23,6 +26,7 @@ static struct { .baseboard_product = "FODM1", .baseboard_manufacturer = "First ODM", }, + .panel_id = u"TST42", .device_type = DEVICE_TYPE_DEVICETREE, }, { @@ -79,9 +83,21 @@ void smbios_raw_info_get_cached(RawSmbiosInfo *ret_info) { *ret_info = current_info; } +static const char16_t *current_panel = NULL; +EFI_STATUS edid_get_discovered_panel_id(char16_t **ret_panel) { + assert(ret_panel); + + if (!current_panel) + return EFI_UNSUPPORTED; + + *ret_panel = xstrdup16(current_panel); + return EFI_SUCCESS; +} + TEST(chid_match) { for (size_t i = 0; i < ELEMENTSOF(info); i++) { current_info = info[i].smbios_info; + current_panel = info[i].panel_id; const Device *dev = NULL; /* Match and check */ ASSERT_EQ(chid_match(hwids_section_data, hwids_section_len, info[i].device_type, &dev), EFI_SUCCESS);