Coverage Report

Created: 2025-11-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupdplugin/fu-hwids-fdt.c
Line
Count
Source
1
/*
2
 * Copyright 2023 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
0
#define G_LOG_DOMAIN "FuContext"
8
9
#include "config.h"
10
11
#include "fu-context-private.h"
12
#include "fu-fdt-firmware.h"
13
#include "fu-hwids-private.h"
14
15
gboolean
16
fu_hwids_fdt_setup(FuContext *ctx, FuHwids *self, GError **error)
17
0
{
18
0
  g_autofree gchar *chassis_type = NULL;
19
0
  g_auto(GStrv) compatible = NULL;
20
0
  g_autoptr(FuFirmware) fdt_img = NULL;
21
0
  g_autoptr(FuFdtImage) fdt_img_baseb = NULL;
22
0
  g_autoptr(FuFdtImage) fdt_img_fwver = NULL;
23
0
  g_autoptr(FuFirmware) fdt = NULL;
24
0
  struct {
25
0
    const gchar *hwid;
26
0
    const gchar *key;
27
0
  } map[] = {{FU_HWIDS_KEY_MANUFACTURER, "vendor"},
28
0
       {FU_HWIDS_KEY_FAMILY, "model-name"},
29
0
       {FU_HWIDS_KEY_PRODUCT_NAME, "model"},
30
0
       {NULL, NULL}};
31
32
  /* adds compatible GUIDs */
33
0
  fdt = fu_context_get_fdt(ctx, error);
34
0
  if (fdt == NULL)
35
0
    return FALSE;
36
0
  fdt_img = fu_firmware_get_image_by_id(fdt, NULL, error);
37
0
  if (fdt_img == NULL)
38
0
    return FALSE;
39
0
  if (!fu_fdt_image_get_attr_strlist(FU_FDT_IMAGE(fdt_img), "compatible", &compatible, error))
40
0
    return FALSE;
41
0
  for (guint i = 0; compatible[i] != NULL; i++) {
42
0
    g_autofree gchar *guid = fwupd_guid_hash_string(compatible[i]);
43
0
    g_debug("using %s for DT compatible %s", guid, compatible[i]);
44
0
    fu_hwids_add_guid(self, guid);
45
0
  }
46
47
  /* root node */
48
0
  for (guint i = 0; map[i].key != NULL; i++) {
49
0
    g_autofree gchar *tmp = NULL;
50
0
    fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), map[i].key, &tmp, NULL);
51
0
    if (tmp == NULL)
52
0
      continue;
53
0
    fu_hwids_add_value(self, map[i].hwid, tmp);
54
0
  }
55
56
  /* chassis kind */
57
0
  fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), "chassis-type", &chassis_type, NULL);
58
0
  if (chassis_type != NULL) {
59
0
    struct {
60
0
      FuSmbiosChassisKind chassis_kind;
61
0
      const gchar *dt;
62
0
    } chassis_map[] = {{FU_SMBIOS_CHASSIS_KIND_CONVERTIBLE, "convertible"},
63
0
           {FU_SMBIOS_CHASSIS_KIND_EMBEDDED_PC, "embedded"},
64
0
           {FU_SMBIOS_CHASSIS_KIND_HAND_HELD, "handset"},
65
0
           {FU_SMBIOS_CHASSIS_KIND_LAPTOP, "laptop"},
66
0
           {FU_SMBIOS_CHASSIS_KIND_TABLET, "tablet"},
67
0
           {FU_SMBIOS_CHASSIS_KIND_UNKNOWN, NULL}};
68
0
    for (guint i = 0; chassis_map[i].dt != NULL; i++) {
69
0
      if (g_strcmp0(chassis_type, chassis_map[i].dt) == 0) {
70
0
        fu_context_set_chassis_kind(ctx, chassis_map[i].chassis_kind);
71
0
        break;
72
0
      }
73
0
    }
74
0
  }
75
76
  /* fallback */
77
0
  if (g_strv_length(compatible) > 0) {
78
0
    g_auto(GStrv) compatible0 = g_strsplit(compatible[0], ",", -1);
79
0
    fu_hwids_add_value(self, FU_HWIDS_KEY_MANUFACTURER, compatible0[0]);
80
0
    if (g_strv_length(compatible0) > 1)
81
0
      fu_hwids_add_value(self, FU_HWIDS_KEY_PRODUCT_NAME, compatible0[1]);
82
0
  }
83
0
  if (g_strv_length(compatible) > 1)
84
0
    fu_hwids_add_value(self, FU_HWIDS_KEY_FAMILY, compatible[1]);
85
0
  if (fu_context_get_chassis_kind(ctx) == FU_SMBIOS_CHASSIS_KIND_UNKNOWN) {
86
0
    if (fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), "battery", NULL, NULL))
87
0
      fu_context_set_chassis_kind(ctx, FU_SMBIOS_CHASSIS_KIND_PORTABLE);
88
0
  }
89
0
  fdt_img_fwver =
90
0
      fu_fdt_firmware_get_image_by_path(FU_FDT_FIRMWARE(fdt), "/ibm,firmware-versions", NULL);
91
0
  if (fdt_img_fwver != NULL) {
92
0
    g_autofree gchar *version = NULL;
93
0
    fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), "version", &version, NULL);
94
0
    fu_hwids_add_value(self, FU_HWIDS_KEY_BIOS_VERSION, version);
95
0
  }
96
97
  /* fall back to the firmware unix time */
98
0
  if (fdt_img_fwver == NULL) {
99
0
    fdt_img_fwver = fu_fdt_firmware_get_image_by_path(FU_FDT_FIRMWARE(fdt),
100
0
                  "/chosen/bootloader",
101
0
                  NULL);
102
0
  }
103
0
  if (fdt_img_fwver != NULL) {
104
0
    guint32 timestamp = 0;
105
0
    fu_fdt_image_get_attr_u32(FU_FDT_IMAGE(fdt_img_fwver),
106
0
            "build-timestamp",
107
0
            &timestamp,
108
0
            NULL);
109
0
    if (timestamp != 0) {
110
0
      g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc(timestamp);
111
0
      g_autofree gchar *version = g_date_time_format(dt, "%Y%m%d");
112
0
      fu_hwids_add_value(self, FU_HWIDS_KEY_BIOS_VERSION, version);
113
0
    }
114
0
  }
115
116
0
  fdt_img_baseb = fu_fdt_firmware_get_image_by_path(
117
0
      FU_FDT_FIRMWARE(fdt),
118
0
      "/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800",
119
0
      NULL);
120
0
  if (fdt_img_baseb != NULL) {
121
0
    g_autofree gchar *vendor = NULL;
122
0
    g_autofree gchar *product = NULL;
123
0
    fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img_baseb), "vendor", &vendor, NULL);
124
0
    fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img_baseb),
125
0
            "part-number",
126
0
            &product,
127
0
            NULL);
128
0
    if (vendor != NULL)
129
0
      fu_hwids_add_value(self, FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, vendor);
130
0
    if (product != NULL)
131
0
      fu_hwids_add_value(self, FU_HWIDS_KEY_BASEBOARD_PRODUCT, product);
132
0
  }
133
134
  /* success */
135
0
  return TRUE;
136
0
}