Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | /* SPDX-License-Identifier: GPL-2.0+ */ /* * Computer Hardware Identifiers (Windows CHID) * * See: https://github.com/fwupd/fwupd/blob/main/docs/hwids.md * * Copyright 2025 Simon Glass <sjg@chromium.org> */ #ifndef __chid_h #define __chid_h #include <linux/types.h> #include <stdbool.h> /** * enum chid_field_t - fields we pick up from SMBIOS tables * * Used as BIT(x) values that can be ORed together to define which fields are * used in each CHID variant. * * The table and field name is shown here (see smbios.h). All are strings * except those noted as int. * * @CHID_MANUF: SMBIOS Type 1 (System Information): manufacturer * @CHID_FAMILY: SMBIOS Type 1 (System Information): family * @CHID_PRODUCT_NAME: SMBIOS Type 1 (System Information): product_name * @CHID_PRODUCT_SKU: SMBIOS Type 1 (System Information): sku_number * @CHID_BOARD_MANUF: SMBIOS Type 2 (Baseboard Information): manufacturer * @CHID_BOARD_PRODUCT: SMBIOS Type 2 (Baseboard Information): product_name * @CHID_BIOS_VENDOR: SMBIOS Type 0 (BIOS Information): vendor * @CHID_BIOS_VERSION: SMBIOS Type 0 (BIOS Information): bios_ver * @CHID_BIOS_MAJOR: SMBIOS Type 0 (BIOS Information): bios_major_release (int) * @CHID_BIOS_MINOR: SMBIOS Type 0 (BIOS Information): bios_minor_release (int) * @CHID_ENCLOSURE_TYPE: SMBIOS Type 3 (System Enclosure): chassis_type (int) * @CHID_COUNT: Number of CHID fields */ enum chid_field_t { CHID_MANUF, CHID_FAMILY, CHID_PRODUCT_NAME, CHID_PRODUCT_SKU, CHID_BOARD_MANUF, CHID_BOARD_PRODUCT, CHID_BIOS_VENDOR, CHID_BIOS_VERSION, CHID_BIOS_MAJOR, CHID_BIOS_MINOR, CHID_ENCLOSURE_TYPE, CHID_COUNT, }; /* * enum chid_variant_id - Microsoft CHID hardware ID variants * * This covers HardwareID-00 through HardwareID-14 */ enum chid_variant_id { CHID_00, /* Most specific */ CHID_01, CHID_02, CHID_03, CHID_04, CHID_05, CHID_06, CHID_07, CHID_08, CHID_09, CHID_10, CHID_11, CHID_12, CHID_13, CHID_14, /* Least specific */ CHID_VARIANT_COUNT }; /** * struct chid_variant - defines which fields are used in each CHID variant * * @name: Human-readable name for debugging * @fields: Bitmask of fields (BIT(CHID_xxx) values ORed together) */ struct chid_variant { const char *name; u32 fields; }; /** * struct chid_data - contains SMBIOS field values to use in calculating CHID * * There is one field here for each item in enum chid_field_t * * @manuf: System manufacturer string * @family: Product family string * @product_name: Product name string * @product_sku: Product SKU string * @board_manuf: Baseboard manufacturer string * @board_product: Baseboard product string * @bios_vendor: BIOS vendor string * @bios_version: BIOS version string * @bios_major: BIOS major version number * @bios_minor: BIOS minor version number * @enclosure_type: System enclosure type */ struct chid_data { const char *manuf; const char *family; const char *product_name; const char *product_sku; const char *board_manuf; const char *board_product; const char *bios_vendor; const char *bios_version; u8 bios_major; u8 bios_minor; u8 enclosure_type; }; /** * chid_from_smbios() - Extract CHID data from SMBIOS tables * * @chid: Pointer to CHID data structure to fill * * Return: 0 if OK, -ENOENT if a required table is missing (SMBIOS types 0-1), * other -ve error code if the SMBIOS tables cannot be found (see * smbios_locate()) */ int chid_from_smbios(struct chid_data *chid); /** * chid_generate() - Generate a specific CHID variant * * @variant: Which CHID variant to generate (0-14) * @data: SMBIOS data to use for generation * @chid: Output buffer for the generated CHID (16 bytes) * * Return: 0 if OK, -ve error code on failure */ int chid_generate(int variant, const struct chid_data *data, u8 chid[16]); /** * chid_get_field_name() - Get display name of a specific CHID field * * @field: Which CHID field * * Return: String containing the field name */ const char *chid_get_field_name(enum chid_field_t field); /** * chid_get_variant_fields() - Get the fields mask for a CHID variant * * @variant: Which CHID variant (0-14) * * Return: Bitmask of fields used by this variant */ u32 chid_get_variant_fields(int variant); /** * chid_get_variant_name() - Get the name of a CHID variant * * @variant: Which CHID variant (0-14) * * Return: String containing the variant name (e.g., "HardwareID-00") */ const char *chid_get_variant_name(int variant); /** * chid_variant_allowed() - Check if a CHID variant is permitted * * @variant: Which CHID variant (enum chid_variant_id) * * Some CHID variants are considered too generic and are not permitted: * - Manufacturer + EnclosureKind (CHID_12) * - Manufacturer + Family (CHID_11) * - Manufacturer only (CHID_14) * - Manufacturer + BaseboardManufacturer + BaseboardProduct (CHID_13) * * Return: true if variant is permitted, false if prohibited */ bool chid_variant_allowed(enum chid_variant_id variant); /** * chid_select_data() - Select compatible string using CHID data * @chid_data: SMBIOS-derived CHID data to use for matching * @compatp: Pointer to store the compatible string (if found) * * This is the core selection function that can be tested with specific * CHID data without requiring SMBIOS hardware access. * * The selection algorithm: * 1. Find all CHID nodes in the devicetree * 2. Calculate match scores for each node based on: * - Exact CHID match (highest priority) * - CHID variant specificity * - Field overlap with provided CHID data * 3. Return the compatible string from the highest-scoring node * * Expected devicetree structure: * /chid { * device-node-name { * compatible = "vendor,device-name"; * variant = <0>; // CHID variant (0-14) * fields = <0x3cf>; // Bitmask of fields used * chid = [12 34 56 78 ...]; // UUID_LEN-byte CHID UUID * }; * }; * * Return: 0 if compatible string found, -ENOENT if no match, other -ve on error */ int chid_select_data(const struct chid_data *chid_data, const char **compatp); /** * chid_select() - Select compatible string using CHID and SMBIOS * * This function examines CHID information in the devicetree and compares it * with the current system's SMBIOS data to select the most appropriate * compatible string for the hardware platform. * * This is a convenience wrapper around chid_select_data() * that automatically extracts SMBIOS data from the current system. * * @compatp: Returns pointer to compatible string if found * Return: 0 if OK, -ENOENT if no suitable match, other -ve on error */ int chid_select(const char **compatp); #endif |