blob: 9dfa854f5358381cbceb7a7b9a2343f61ca7d7aa [file] [log] [blame]
/* Copyright 2021 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef _CROSID_H
#define _CROSID_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
/* Common path constants */
#define PROC_FDT_PATH "/proc/device-tree"
#define PROC_FDT_COREBOOT_PATH PROC_FDT_PATH "/firmware/coreboot"
#define SYSFS_SMBIOS_ID_PATH "/sys/class/dmi/id"
#define SYSFS_VPD_RO_PATH "/sys/firmware/vpd/ro"
#define UNIBUILD_CONFIG_PATH "/usr/share/chromeos-config"
/* Logging functions */
enum log_level {
/*
* For printing messages that indicate why crosid is exiting
* with failure status.
*/
LOG_ERR = 0,
/*
* For printing messages for debugging device identity
* matching.
*/
LOG_DBG,
/*
* For all other messages, including those which may not
* actually indicate a real issue.
*/
LOG_SPEW,
};
/**
* crosid_set_log_level() - Set logging verbosity
*
* @log_level: The log level to use.
*/
void crosid_set_log_level(enum log_level log_level);
/**
* crosid_log() - Log to stderr
*
* @log_level: The verbosity of the message.
* @format: The format string.
*/
__attribute__((format(printf, 2, 3))) void
crosid_log(enum log_level log_level, const char *restrict format, ...);
/* File functions */
/**
* crosid_set_sysroot() - Change the root used by file operations
*
* @path: The new root directory.
*/
void crosid_set_sysroot(const char *path);
/**
* crosid_read_file() - Allocate a buffer and read a file into it
*
* @dir: The directory where the file is located
* @file: The file name
* @data_ptr: Set to the allocated buffer
* @size_ptr: Set to the size of the allocated buffer. If set to
* NULL, the size will not be stored.
*
* Returns: <0 on error, 0 on success
*
* Note: for convenience, the file contents will always be
* null-terminated. The size of the terminator is not included in the
* size written to size_ptr.
*/
int crosid_read_file(const char *dir, const char *file, char **data_ptr,
size_t *size_ptr);
/* SKU functions */
/**
* crosid_get_sku_id() - Get the SKU ID of the system
*
* @out: Output value, the SKU ID
* @srctype: Output pointer set to static string of source type
* (either SMBIOS or FDT). This is intended for printing in debug
* messages.
*
* Returns: <0 on error, 0 on success
*/
int crosid_get_sku_id(uint32_t *out, const char **srctype);
/* Device Probe Functions */
struct crosid_optional_string {
bool present;
char *value;
size_t len;
};
struct crosid_probed_device_data {
bool has_sku_id;
uint32_t sku_id;
struct crosid_optional_string smbios_name;
struct crosid_optional_string fdt_compatible;
struct crosid_optional_string custom_label_tag;
struct crosid_optional_string customization_id;
char *firmware_manifest_key;
};
/**
* crosid_probe() - Read firmware variables from device
*
* @out: A caller-allocated struct to write the probed data to
*
* Returns: <0 on error, 0 on success.
*
* Note: The struct must be passed to crosid_probe_free after usage to
* cleanup allocated memory from files read.
*/
int crosid_probe(struct crosid_probed_device_data *out);
/**
* crosid_match() - Match probed device data to a cros_config identity
*
* @data: The data struct, created from the result of a crosid_probe.
*
* Returns: <0 on error, or the index of the probed config upon
* success.
*/
int crosid_match(struct crosid_probed_device_data *data);
/**
* crosid_print_vars() - Print system info
*
* @out: Output file
* @data: The data struct, created from the result of a crosid_probe.
* @config_idx: The config index from crosid_match.
*/
void crosid_print_vars(FILE *out, struct crosid_probed_device_data *data,
int config_idx);
/**
* crosid_probe_free() - Free memory allocated by a crosid_probe()
*
* @data - The struct created from a crosid_probe()
*/
void crosid_probe_free(struct crosid_probed_device_data *data);
/* Identity table */
/*
* Bump this number when backwards-incompatible changes are made to
* the struct format. This must be kept in sync with the
* cros_config_schema implementation.
*/
#define CROSID_TABLE_VERSION 2
enum crosid_table_flags {
MATCH_SKU_ID = (1 << 0),
MATCH_CUSTOM_LABEL_TAG = (1 << 1),
MATCH_CUSTOMIZATION_ID = (1 << 2),
MATCH_FDT_COMPATIBLE = (1 << 3),
MATCH_SMBIOS_NAME = (1 << 4),
};
struct crosid_table_entry {
uint32_t flags;
uint32_t smbios_name_match;
uint32_t fdt_compatible_match;
uint32_t sku_id_match;
union {
uint32_t customization_id_match;
uint32_t custom_label_tag_match;
};
uint32_t firmware_manifest_key;
} __attribute__((packed));
struct crosid_table_header {
uint32_t version;
uint32_t entry_count;
struct crosid_table_entry entries[];
} __attribute__((packed));
/* High-level API entry points */
/**
* crosid_get_firmware_manifest_key() - Get futility manifest key
*
* @manifest_key_out - Output parameter of the firmware manifest key.
*
* Note: manifest_key_out is allocated by this function and should be
* freed by the caller when no longer required.
*
* Returns:
* - >=0, the matched identity index, if probe and match was
* successful (manifest key available)
* - <0 error
*/
int crosid_get_firmware_manifest_key(char **manifest_key_out);
#endif /* _CROSID_H */