/src/systemd/src/fundamental/edid-fundamental.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #if !SD_BOOT |
4 | | #include <endian.h> |
5 | | #endif |
6 | | |
7 | | #include "edid-fundamental.h" |
8 | | #include "efivars-fundamental.h" |
9 | | |
10 | 0 | #define EDID_FIXED_HEADER_PATTERN "\x00\xFF\xFF\xFF\xFF\xFF\xFF" |
11 | | assert_cc(sizeof_field(EdidHeader, pattern) == sizeof(EDID_FIXED_HEADER_PATTERN)); |
12 | | |
13 | 0 | int edid_parse_blob(const void *blob, size_t blob_size, EdidHeader *ret_header) { |
14 | 0 | assert(ret_header); |
15 | | |
16 | | /* EDID size is at least 128 as per the specification */ |
17 | 0 | if (blob_size < 128) |
18 | 0 | return -EINVAL; |
19 | | |
20 | 0 | const EdidHeader *edid_header = ASSERT_PTR(blob); |
21 | 0 | if (memcmp(edid_header->pattern, EDID_FIXED_HEADER_PATTERN, sizeof(EDID_FIXED_HEADER_PATTERN)) != 0) |
22 | 0 | return -EINVAL; |
23 | | |
24 | 0 | *ret_header = (EdidHeader) { |
25 | 0 | .pattern = EDID_FIXED_HEADER_PATTERN, |
26 | 0 | .manufacturer_id = be16toh(edid_header->manufacturer_id), |
27 | 0 | .manufacturer_product_code = le16toh(edid_header->manufacturer_product_code), |
28 | 0 | .serial_number = le32toh(edid_header->serial_number), |
29 | 0 | .week_of_manufacture = edid_header->week_of_manufacture, |
30 | 0 | .year_of_manufacture = edid_header->year_of_manufacture, |
31 | 0 | .edid_version = edid_header->edid_version, |
32 | 0 | .edid_revision = edid_header->edid_revision, |
33 | 0 | }; |
34 | 0 | return 0; |
35 | 0 | } |
36 | | |
37 | 0 | int edid_get_panel_id(const EdidHeader *edid_header, char16_t ret_panel[static 8]) { |
38 | 0 | assert(edid_header); |
39 | 0 | assert(ret_panel); |
40 | |
|
41 | 0 | for (size_t i = 0; i < 3; i++) { |
42 | 0 | uint8_t letter = (edid_header->manufacturer_id >> (5 * i)) & 0b11111; |
43 | 0 | if (letter > 0b11010) |
44 | 0 | return -EINVAL; |
45 | 0 | ret_panel[2 - i] = letter + 'A' - 1; |
46 | 0 | } |
47 | 0 | ret_panel[3] = LOWERCASE_HEXDIGITS[(edid_header->manufacturer_product_code >> 12) & 0x0F]; |
48 | 0 | ret_panel[4] = LOWERCASE_HEXDIGITS[(edid_header->manufacturer_product_code >> 8) & 0x0F]; |
49 | 0 | ret_panel[5] = LOWERCASE_HEXDIGITS[(edid_header->manufacturer_product_code >> 4) & 0x0F]; |
50 | 0 | ret_panel[6] = LOWERCASE_HEXDIGITS[(edid_header->manufacturer_product_code >> 0) & 0x0F]; |
51 | 0 | ret_panel[7] = L'\0'; |
52 | 0 | return 0; |
53 | 0 | } |