mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-12 08:21:55 +00:00
157 lines
4.0 KiB
C
157 lines
4.0 KiB
C
/*
|
|
* Copyright (C) 2019 9elements Agency GmbH <patrick.rudolph@9elements.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <glib.h>
|
|
#include <glib/gstdio.h>
|
|
|
|
#include "fu-plugin-vfuncs.h"
|
|
#include "fu-device-metadata.h"
|
|
#include "fu-device-private.h"
|
|
#include "fu-plugin-coreboot.h"
|
|
|
|
void
|
|
fu_plugin_init (FuPlugin *plugin)
|
|
{
|
|
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
|
}
|
|
|
|
gboolean
|
|
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
|
|
{
|
|
const gchar *major;
|
|
const gchar *minor;
|
|
const gchar *vendor;
|
|
const gchar *version;
|
|
GBytes *bios_table;
|
|
gboolean updatable = FALSE; /* TODO: Implement update support */
|
|
g_autofree gchar *name = NULL;
|
|
g_autofree gchar *triplet = NULL;
|
|
g_autoptr(FuDevice) dev = NULL;
|
|
|
|
/* don't include FU_HWIDS_KEY_BIOS_VERSION */
|
|
static const gchar *hwids[] = {
|
|
"HardwareID-3",
|
|
"HardwareID-4",
|
|
"HardwareID-5",
|
|
"HardwareID-6",
|
|
"HardwareID-10",
|
|
};
|
|
|
|
vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
|
|
if (vendor == NULL) {
|
|
g_set_error (error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_NOT_FOUND,
|
|
"Failed to get DMI value FU_HWIDS_KEY_BIOS_VENDOR");
|
|
return FALSE;
|
|
}
|
|
|
|
version = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VERSION);
|
|
if (version != NULL)
|
|
triplet = fu_plugin_coreboot_version_string_to_triplet (version, error);
|
|
|
|
if (version == NULL || triplet == NULL) {
|
|
major = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE);
|
|
if (major == NULL) {
|
|
g_set_error (error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_NOT_FOUND,
|
|
"Missing BIOS major release");
|
|
return FALSE;
|
|
}
|
|
minor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_MINOR_RELEASE);
|
|
if (minor == NULL) {
|
|
g_set_error (error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_NOT_FOUND,
|
|
"Missing BIOS minor release");
|
|
return FALSE;
|
|
}
|
|
triplet = g_strdup_printf ("%s.%s.0", major, minor);
|
|
}
|
|
|
|
if (triplet == NULL) {
|
|
g_set_error (error,
|
|
G_IO_ERROR,
|
|
G_IO_ERROR_INVALID_DATA,
|
|
"No version string found");
|
|
|
|
return FALSE;
|
|
}
|
|
dev = fu_device_new ();
|
|
|
|
fu_device_set_version (dev, triplet, FWUPD_VERSION_FORMAT_TRIPLET);
|
|
fu_device_set_summary (dev, "Open Source system boot firmware");
|
|
fu_device_set_id (dev, vendor);
|
|
fu_device_set_vendor (dev, vendor);
|
|
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
|
|
fu_device_add_icon (dev, "computer");
|
|
name = fu_plugin_coreboot_get_name_for_type (plugin, NULL);
|
|
if (name != NULL) {
|
|
fu_device_set_name (dev, name);
|
|
} else {
|
|
fu_device_set_name (dev, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME));
|
|
}
|
|
fu_device_set_vendor (dev, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER));
|
|
fu_device_add_instance_id (dev, "main-system-firmware");
|
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (hwids); i++) {
|
|
char *str;
|
|
str = fu_plugin_get_hwid_replace_value (plugin, hwids[i], NULL);
|
|
if (str != NULL)
|
|
fu_device_add_instance_id (dev, str);
|
|
}
|
|
|
|
bios_table = fu_plugin_get_smbios_data (plugin, FU_SMBIOS_STRUCTURE_TYPE_BIOS);
|
|
if (bios_table != NULL) {
|
|
guint32 bios_characteristics;
|
|
gsize len;
|
|
const guint8 *value = g_bytes_get_data (bios_table, &len);
|
|
if (len >= 0x9) {
|
|
gint firmware_size = (value[0x9] + 1) * 64 * 1024;
|
|
fu_device_set_firmware_size_max (dev, firmware_size);
|
|
}
|
|
if (len >= (0xa + sizeof(guint32))) {
|
|
memcpy (&bios_characteristics, &value[0xa], sizeof (guint32));
|
|
/* Read the "BIOS is upgradeable (Flash)" flag */
|
|
if (!(bios_characteristics & (1 << 11)))
|
|
updatable = FALSE;
|
|
}
|
|
}
|
|
|
|
if (updatable)
|
|
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
|
|
|
|
/* convert instances to GUID */
|
|
fu_device_convert_instance_ids (dev);
|
|
|
|
fu_plugin_device_add (plugin, dev);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
|
{
|
|
const gchar *vendor;
|
|
|
|
vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
|
|
if (g_strcmp0 (vendor, "coreboot") != 0) {
|
|
g_set_error (error,
|
|
FWUPD_ERROR,
|
|
FWUPD_ERROR_NOT_FOUND,
|
|
"No coreboot detected on this machine.");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|