Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/24992
Change subject: lib; Add blob_provider functionality ......................................................................
lib; Add blob_provider functionality
* Add blob_read_map and blob_read_region_device for automated identification of blobs through defines. * Add blob_read_arbitrary_map and blob_read_arbitrary_region_device for manual identification of blobs. * blob_hook_region_device for hooking all function giving access to the region_device with meta information.
Change-Id: I30abc5be5d47a4c697c0b94babb068b0f0ae4794 Signed-off-by: zaolin zaolin@das-labor.org --- A src/include/blob_provider.h M src/lib/Makefile.inc A src/lib/blob_provider.c 3 files changed, 399 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/24992/1
diff --git a/src/include/blob_provider.h b/src/include/blob_provider.h new file mode 100644 index 0000000..cb64ef4 --- /dev/null +++ b/src/include/blob_provider.h @@ -0,0 +1,246 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 Facebook Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _BLOB_PROVIDER_H_ +#define _BLOB_PROVIDER_H_ + +#include <types.h> +#include <stddef.h> +#include <cbfs.h> +#include <region.h> + +struct blob_locator { + uint32_t id; + const char *fmap_name; + const char *cbfs_name; + uint32_t cbfs_type; +}; + +enum { + ID_DATA_BOOTSPLASH = 1, + ID_DATA_ACPI_SLIC = 2, + ID_DATA_ACPI_DSDT = 3, + ID_DATA_ACPI_SSDT = 4, + ID_DATA_MICROCODE = 5, + ID_DATA_MICROCODE_RMU = 6, + ID_DATA_MRC_CACHE = 7, + ID_DATA_VGA_VBT = 8, + ID_DATA_NVRAM_CMOS_LAYOUT = 9, + ID_DATA_NVRAM_CMOS_DEFAULT = 10, + ID_DATA_NVRAM_VPD = 11, + ID_DATA_SIEMENS_HWLIB = 12, + ID_DATA_SPD = 13, + ID_DATA_MAC = 14, + ID_DATA_AMD_S3NV = 15, + ID_DATA_MRC_CACHE_RW_REGION = 16, + ID_DATA_NVRAM_VPD_RO_REGION = 17, + ID_DATA_CODE_SPLIT = 50, + ID_CODE_AMD_AGESA = 51, + ID_CODE_AMD_AGESA_PRE_MEM = 52, + ID_CODE_AMD_AGESA_POST_MEM = 53, + ID_CODE_AMD_PSP = 54, + ID_CODE_INTEL_MRC = 55, + ID_CODE_INTEL_FSP_S = 56, + ID_CODE_INTEL_FSP_M = 57, + ID_CODE_INTEL_MMA = 58, + ID_CODE_NVIDIA_MTC = 59, + ID_CODE_QUALCOMM_CDT = 60, + ID_CODE_QUALCOMM_DDR = 61, + ID_CODE_QUALCOMM_TZ = 61, + ID_CODE_QUALCOMM_RPM = 63, +}; + +#define COREBOOT_REGION "COREBOOT" + +/********************************AUTO_MODE********************************/ + +/* Excluded blobs +VGA option roms +Intel NHLT blobs +Custom blobs / naming +*/ + +// Data Section +#define BLOB_DATA_BOOTSPLASH \ +((struct blob_locator) {.id = ID_DATA_BOOTSPLASH, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "bootsplash.jpg", \ + .cbfs_type = CBFS_TYPE_BOOTSPLASH}) +#define BLOB_DATA_ACPI_SLIC \ +((struct blob_locator) {.id = ID_DATA_ACPI_SLIC, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = CONFIG_CBFS_PREFIX "/slic", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_ACPI_DSDT \ +((struct blob_locator) {.id = ID_DATA_ACPI_DSDT, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = CONFIG_CBFS_PREFIX "/dsdt.aml", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_ACPI_SSDT \ +((struct blob_locator) {.id = ID_DATA_ACPI_SSDT, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = CONFIG_CBFS_PREFIX "/ssdt.aml", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_MICROCODE \ +((struct blob_locator) {.id = ID_DATA_MICROCODE, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "cpu_microcode_blob.bin", \ + .cbfs_type = CBFS_TYPE_MICROCODE}) +#define BLOB_DATA_MICROCODE_RMU \ +((struct blob_locator) {.id = ID_DATA_MICROCODE_RMU, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "rmu.bin", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_MRC_CACHE \ +((struct blob_locator) {.id = ID_DATA_MRC_CACHE, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "mrc.cache", \ + .cbfs_type = CBFS_TYPE_MRC_CACHE}) +#define BLOB_DATA_MRC_CACHE_RW_REGION \ +((struct blob_locator) {.id = ID_DATA_MRC_CACHE_RW_REGION, \ + .fmap_name = "RW_MRC_CACHE", \ + .cbfs_name = "RW MRC CACHE", \ + .cbfs_type = 0}) +#define BLOB_DATA_VGA_VBT \ +((struct blob_locator) {.id = ID_DATA_VGA_VBT, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "vbt.bin", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_NVRAM_CMOS_LAYOUT \ +((struct blob_locator) {.id = ID_DATA_NVRAM_CMOS_LAYOUT, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "cmos_layout.bin", \ + .cbfs_type = CBFS_COMPONENT_CMOS_LAYOUT}) +#define BLOB_DATA_NVRAM_CMOS_DEFAULT \ +((struct blob_locator) {.id = ID_DATA_NVRAM_CMOS_DEFAULT, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "cmos.default", \ + .cbfs_type = CBFS_COMPONENT_CMOS_DEFAULT}) +#define BLOB_DATA_NVRAM_VPD \ +((struct blob_locator) {.id = ID_DATA_NVRAM_VPD, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "vpd.bin", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_NVRAM_VPD_RO_REGION \ +((struct blob_locator) {.id = ID_DATA_NVRAM_VPD_RO_REGION, \ + .fmap_name = "RO_VPD", \ + .cbfs_name = "RO VPD", \ + .cbfs_type = 0}) +#define BLOB_DATA_SIEMENS_HWLIB \ +((struct blob_locator) {.id = ID_DATA_SIEMENS_HWLIB, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "hwinfo.hex", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_SPD \ +((struct blob_locator) {.id = ID_DATA_SPD, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "spd.bin", \ + .cbfs_type = CBFS_TYPE_SPD}) +#define BLOB_DATA_MAC \ +((struct blob_locator) {.id = ID_DATA_MAC, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "macaddress", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_DATA_AMD_S3NV \ +((struct blob_locator) {.id = ID_DATA_AMD_S3NV, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "s3nv", \ + .cbfs_type = CBFS_TYPE_RAW}) + +// Code Section +#define BLOB_CODE_AMD_AGESA \ +((struct blob_locator) {.id = ID_CODE_AMD_AGESA, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "AGESA", \ + .cbfs_type = CBFS_TYPE_STAGE}) +#define BLOB_CODE_AMD_AGESA_PRE_MEM \ +((struct blob_locator) {.id = ID_CODE_AMD_AGESA_PRE_MEM, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "AGESA_PRE_MEM", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_AMD_AGESA_POST_MEM \ +((struct blob_locator) {.id = ID_CODE_AMD_AGESA_POST_MEM, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "AGESA_POST_MEM", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_AMD_PSP \ +((struct blob_locator) {.id = ID_CODE_AMD_PSP, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "smu_fw", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_INTEL_MRC \ +((struct blob_locator) {.id = ID_CODE_INTEL_MRC, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "mrc.bin", \ + .cbfs_type = CBFS_TYPE_MRC}) +#define BLOB_CODE_INTEL_FSP_S \ +((struct blob_locator) {.id = ID_CODE_INTEL_FSP_S, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "fsps.bin", \ + .cbfs_type = CBFS_TYPE_FSP}) +#define BLOB_CODE_INTEL_FSP_M \ +((struct blob_locator) {.id = ID_CODE_INTEL_FSP_M, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "fspm.bin", \ + .cbfs_type = CBFS_TYPE_FSP}) +#define BLOB_CODE_INTEL_MMA \ +((struct blob_locator) {.id = ID_CODE_INTEL_MMA, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "mma_test_metadata.bin", \ + .cbfs_type = CBFS_TYPE_MMA}) +#define BLOB_CODE_NVIDIA_MTC \ +((struct blob_locator) {.id = ID_CODE_NVIDIA_MTC, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "tegra_mtc.bin", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_QUALCOMM_CDT \ +((struct blob_locator) {.id = ID_CODE_QUALCOMM_CDT, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "cdt.mbn", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_QUALCOMM_DDR \ +((struct blob_locator) {.id = ID_CODE_QUALCOMM_DDR, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "ddr.mbn", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_QUALCOMM_TZ \ +((struct blob_locator) {.id = ID_CODE_QUALCOMM_TZ, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "tz.mbn", \ + .cbfs_type = CBFS_TYPE_RAW}) +#define BLOB_CODE_QUALCOMM_RPM \ +((struct blob_locator) {.id = ID_CODE_QUALCOMM_RPM, \ + .fmap_name = "COREBOOT", \ + .cbfs_name = "rpm.mbn", \ + .cbfs_type = CBFS_TYPE_RAW}) + +void *blob_read_map(const struct blob_locator locator, size_t *size); + +int blob_read_region_device(const struct blob_locator locator, + struct region_device *data); + +/********************************AUTO_MODE********************************/ + +void *blob_read_arbitrary_map(const char *fmap_name, const char *cbfs_name, + uint32_t cbfs_type, size_t *size); + +int blob_read_arbitrary_region_device(const char *fmap_name, + const char *cbfs_name, uint32_t cbfs_type, + struct region_device *data); + +int blob_hook_region_device(const struct blob_locator locator, + const struct region_device *data); + +#endif /* _BLOB_PROVIDER_H_ */ diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index d77884c..ebfbef2 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -223,6 +223,13 @@ ramstage-y += reset.c smm-y += reset.c
+bootblock-y += blob_provider.c +verstage-y += blob_provider.c +romstage-y += blob_provider.c +postcar-y += blob_provider.c +ramstage-y += blob_provider.c +smm-y += blob_provider.c + postcar-y += bootmode.c postcar-y += boot_device.c postcar-y += cbfs.c diff --git a/src/lib/blob_provider.c b/src/lib/blob_provider.c new file mode 100644 index 0000000..c7a2ada --- /dev/null +++ b/src/lib/blob_provider.c @@ -0,0 +1,146 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 Facebook Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <blob_provider.h> +#include <console/console.h> +#include <fmap.h> +#include <string.h> + +int __attribute__((weak)) +blob_hook_region_device(const struct blob_locator locator, + const struct region_device *data) +{ + return 0; +} + +static int lookup_rdev(const struct blob_locator locator, + struct region_device *data) +{ + struct blob_locator blob_identifier = locator; + struct cbfsf file; + + if (strncmp(blob_identifier.fmap_name, COREBOOT_REGION, + strlen(COREBOOT_REGION)) != 0) { + if (fmap_locate_area_as_rdev(blob_identifier.fmap_name, data)) { + printk(BIOS_ERR, "Could not locate FMAP partition %s\n", + blob_identifier.fmap_name); + return -1; + } + } else { + if (cbfs_locate_file_in_region(&file, blob_identifier.fmap_name, + blob_identifier.cbfs_name, + &blob_identifier.cbfs_type) < + 0) { + printk(BIOS_ERR, + "Could not locate %s key in CBFS on FMAP " + "partition %s " + "with type %u\n", + blob_identifier.cbfs_name, + blob_identifier.fmap_name, + blob_identifier.cbfs_type); + return -1; + } + + cbfs_file_data(data, &file); + } + + // Hook into mapping + if (blob_hook_region_device(blob_identifier, data) < 0) { + printk(BIOS_ERR, "Could not locate FMAP partition %s\n", + blob_identifier.fmap_name); + return -1; + } + + return 0; +} + +void *blob_read_map(const struct blob_locator locator, size_t *size) +{ + struct blob_locator blob_identifier = locator; + struct region_device data; + + if (size) + *size = 0; + + if (blob_identifier.id > ID_DATA_CODE_SPLIT) { + printk(BIOS_ERR, "Can't use auto mmap function on code blob."); + return NULL; + } + + if (lookup_rdev(blob_identifier, &data) < 0) { + printk(BIOS_ERR, "Can't use auto mmap function on code blob."); + return NULL; + } + + if (size) + *size = region_device_sz(&data); + + return rdev_mmap_full(&data); +} + +int blob_read_region_device(const struct blob_locator locator, + struct region_device *data) +{ + struct blob_locator blob_identifier = locator; + + if (blob_identifier.id <= ID_DATA_CODE_SPLIT) { + printk(BIOS_ERR, "Can't use auto rd function on data blob."); + return -1; + } + + if (lookup_rdev(blob_identifier, data) < 0) { + printk(BIOS_ERR, "Can't use auto mmap function on code blob."); + return -1; + } + + return 0; +} + +void *blob_read_arbitrary_map(const char *fmap_name, const char *cbfs_name, + uint32_t cbfs_type, size_t *size) +{ + const struct blob_locator blob_identifier = {.id = 0, + .fmap_name = fmap_name, + .cbfs_name = cbfs_name, + .cbfs_type = cbfs_type}; + struct region_device data; + + if (lookup_rdev(blob_identifier, &data) < 0) { + printk(BIOS_ERR, "Can't use auto mmap function on code blob."); + return NULL; + } + + if (size) + *size = region_device_sz(&data); + + return rdev_mmap_full(&data); +} + +int blob_read_arbitrary_region_device(const char *fmap_name, + const char *cbfs_name, uint32_t cbfs_type, + struct region_device *data) +{ + const struct blob_locator blob_identifier = {.id = 0, + .fmap_name = fmap_name, + .cbfs_name = cbfs_name, + .cbfs_type = cbfs_type}; + + if (lookup_rdev(blob_identifier, data) < 0) { + printk(BIOS_ERR, "Can't use auto mmap function on code blob."); + return -1; + } + + return 0; +}