]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Add EDID parsing
authoranonymix007 <48598263+anonymix007@users.noreply.github.com>
Mon, 31 Mar 2025 17:56:58 +0000 (20:56 +0300)
committeranonymix007 <48598263+anonymix007@users.noreply.github.com>
Wed, 7 May 2025 15:52:49 +0000 (18:52 +0300)
Will be used for identifying the currently used display panel
and choosing the appropriate DTB

src/boot/edid.c [new file with mode: 0644]
src/boot/edid.h [new file with mode: 0644]
src/boot/hwids/device1.json
src/boot/meson.build
src/boot/proto/edid-discovered.h [new file with mode: 0644]
src/boot/test-chid-match.c

diff --git a/src/boot/edid.c b/src/boot/edid.c
new file mode 100644 (file)
index 0000000..62e3383
--- /dev/null
@@ -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 (file)
index 0000000..9832dad
--- /dev/null
@@ -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);
index 6649a76491eae7992cb23195285ebe1981f4d565..5fa718c029c18cb7a3e2f0148745b60d9a47c057 100644 (file)
@@ -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"
     ]
 }
index d4bd202f6fef57f68ebf1153d120b4ec7131143e..c2a894d323684d0089fc6c4eb390ed4f072535e7 100644 (file)
@@ -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 (file)
index 0000000..7c83fcd
--- /dev/null
@@ -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;
index 415681f201c77f7d1a099ed5bfcabd2d84a45bea..5a22db70e391cf958df6d1ab32a0ecff9d999943 100644 (file)
@@ -4,6 +4,8 @@
 #include <stdint.h>
 
 #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);