From 0e3371a20b57b4bee73d3ddc8190bbb085c2a403 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 19 Sep 2019 11:44:52 +0200 Subject: [PATCH] util: update ifdtool to the current state in coreboot/util --- util/commonlib/include/commonlib/cbfs.h | 2 - .../include/commonlib/cbfs_serialized.h | 1 - util/commonlib/include/commonlib/cbmem_id.h | 17 +- util/commonlib/include/commonlib/compiler.h | 64 ++++ .../commonlib/include/commonlib/compression.h | 2 - .../include/commonlib/coreboot_tables.h | 127 ++++--- util/commonlib/include/commonlib/endian.h | 2 - .../include/commonlib/fmap_serialized.h | 2 +- util/commonlib/include/commonlib/fsp.h | 2 - util/commonlib/include/commonlib/helpers.h | 73 +++- util/commonlib/include/commonlib/iobuf.h | 2 - util/commonlib/include/commonlib/loglevel.h | 2 - util/commonlib/include/commonlib/mem_pool.h | 2 - util/commonlib/include/commonlib/region.h | 2 - .../include/commonlib/rmodule-defs.h | 3 - .../include/commonlib/sd_mmc_ctrlr.h | 9 +- util/commonlib/include/commonlib/sdhci.h | 9 +- util/commonlib/include/commonlib/sort.h | 25 ++ util/commonlib/include/commonlib/stdlib.h | 8 +- util/commonlib/include/commonlib/storage.h | 6 +- .../include/commonlib/tcpa_log_serialized.h | 40 +++ .../include/commonlib/timestamp_serialized.h | 7 +- util/ifdtool/Makefile | 4 +- util/ifdtool/ifdtool.c | 317 +++++++++++++++--- util/ifdtool/ifdtool.h | 45 ++- 25 files changed, 600 insertions(+), 173 deletions(-) create mode 100644 util/commonlib/include/commonlib/compiler.h create mode 100644 util/commonlib/include/commonlib/sort.h create mode 100644 util/commonlib/include/commonlib/tcpa_log_serialized.h diff --git a/util/commonlib/include/commonlib/cbfs.h b/util/commonlib/include/commonlib/cbfs.h index c31df51..cadc8c9 100644 --- a/util/commonlib/include/commonlib/cbfs.h +++ b/util/commonlib/include/commonlib/cbfs.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2015 Google 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. diff --git a/util/commonlib/include/commonlib/cbfs_serialized.h b/util/commonlib/include/commonlib/cbfs_serialized.h index e8f027f..6e254f6 100644 --- a/util/commonlib/include/commonlib/cbfs_serialized.h +++ b/util/commonlib/include/commonlib/cbfs_serialized.h @@ -48,7 +48,6 @@ #define _CBFS_SERIALIZED_H_ #include -#include /** These are standard values for the known compression algorithms that coreboot knows about for stages and diff --git a/util/commonlib/include/commonlib/cbmem_id.h b/util/commonlib/include/commonlib/cbmem_id.h index 3529fef..8d0ca46 100644 --- a/util/commonlib/include/commonlib/cbmem_id.h +++ b/util/commonlib/include/commonlib/cbmem_id.h @@ -1,9 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2009 coresystems GmbH - * Copyright (C) 2013 Google, 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. @@ -19,7 +16,7 @@ #define CBMEM_ID_ACPI 0x41435049 #define CBMEM_ID_ACPI_GNVS 0x474e5653 -#define CBMEM_ID_ACPI_GNVS_PTR 0x474e5650 +#define CBMEM_ID_ACPI_UCSI 0x55435349 #define CBMEM_ID_AFTER_CAR 0xc4787a93 #define CBMEM_ID_AGESA_RUNTIME 0x41474553 #define CBMEM_ID_AMDMCT_MEMINFO 0x494D454E @@ -40,6 +37,7 @@ #define CBMEM_ID_IMD_SMALL 0x53a11439 #define CBMEM_ID_MEMINFO 0x494D454D #define CBMEM_ID_MMA_DATA 0x4D4D4144 +#define CBMEM_ID_MMC_STATUS 0x4d4d4353 #define CBMEM_ID_MPTABLE 0x534d5054 #define CBMEM_ID_MRCDATA 0x4d524344 #define CBMEM_ID_VAR_MRCDATA 0x4d524345 @@ -64,9 +62,11 @@ #define CBMEM_ID_STAGEx_RAW 0x57a9e200 #define CBMEM_ID_STORAGE_DATA 0x53746f72 #define CBMEM_ID_TCPA_LOG 0x54435041 +#define CBMEM_ID_TCPA_TCG_LOG 0x54445041 #define CBMEM_ID_TIMESTAMP 0x54494d45 -#define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 -#define CBMEM_ID_VBOOT_SEL_REG 0x780074f1 +#define CBMEM_ID_TPM2_TCG_LOG 0x54504d32 +#define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 /* deprecated */ +#define CBMEM_ID_VBOOT_SEL_REG 0x780074f1 /* deprecated */ #define CBMEM_ID_VBOOT_WORKBUF 0x78007343 #define CBMEM_ID_VPD 0x56504420 #define CBMEM_ID_WIFI_CALIBRATION 0x57494649 @@ -80,7 +80,7 @@ #define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ { CBMEM_ID_ACPI_GNVS, "ACPI GNVS " }, \ - { CBMEM_ID_ACPI_GNVS_PTR, "GNVS PTR " }, \ + { CBMEM_ID_ACPI_UCSI, "ACPI UCSI " }, \ { CBMEM_ID_AGESA_RUNTIME, "AGESA RSVD " }, \ { CBMEM_ID_AFTER_CAR, "AFTER CAR " }, \ { CBMEM_ID_AMDMCT_MEMINFO, "AMDMEM INFO" }, \ @@ -100,6 +100,7 @@ { CBMEM_ID_IMD_SMALL, "IMD SMALL " }, \ { CBMEM_ID_MEMINFO, "MEM INFO " }, \ { CBMEM_ID_MMA_DATA, "MMA DATA " }, \ + { CBMEM_ID_MMC_STATUS, "MMC STATUS " }, \ { CBMEM_ID_MPTABLE, "SMP TABLE " }, \ { CBMEM_ID_MRCDATA, "MRC DATA " }, \ { CBMEM_ID_VAR_MRCDATA, "VARMRC DATA" }, \ @@ -120,7 +121,9 @@ { CBMEM_ID_SMM_SAVE_SPACE, "SMM BACKUP " }, \ { CBMEM_ID_STORAGE_DATA, "SD/MMC/eMMC" }, \ { CBMEM_ID_TCPA_LOG, "TCPA LOG " }, \ + { CBMEM_ID_TCPA_TCG_LOG, "TCPA TCGLOG" }, \ { CBMEM_ID_TIMESTAMP, "TIME STAMP " }, \ + { CBMEM_ID_TPM2_TCG_LOG, "TPM2 TCGLOG" }, \ { CBMEM_ID_VBOOT_HANDOFF, "VBOOT " }, \ { CBMEM_ID_VBOOT_SEL_REG, "VBOOT SEL " }, \ { CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK " }, \ diff --git a/util/commonlib/include/commonlib/compiler.h b/util/commonlib/include/commonlib/compiler.h new file mode 100644 index 0000000..972a229 --- /dev/null +++ b/util/commonlib/include/commonlib/compiler.h @@ -0,0 +1,64 @@ +/* + * This file is part of the coreboot project. + * + * 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 _COMMONLIB_COMPILER_H_ +#define _COMMONLIB_COMPILER_H_ + +#ifndef __packed +#if defined(__WIN32) || defined(__WIN64) +#define __packed __attribute__((gcc_struct, packed)) +#else +#define __packed __attribute__((packed)) +#endif +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((aligned(x))) +#endif + +#ifndef __always_unused +#define __always_unused __attribute__((unused)) +#endif + +#ifndef __must_check +#define __must_check __attribute__((warn_unused_result)) +#endif + +#ifndef __weak +#define __weak __attribute__((weak)) +#endif + +#ifndef __noreturn +#define __noreturn __attribute__((noreturn)) +#endif + +#ifndef __always_inline +#define __always_inline inline __attribute__((always_inline)) +#endif + +/* This evaluates to the type of the first expression, unless that is constant + in which case it evalutates to the type of the second. This is useful when + assigning macro parameters to temporary variables, because that would + normally circumvent the special loosened type promotion rules for integer + literals. By using this macro, the promotion can happen at the time the + literal is assigned to the temporary variable. If the literal doesn't fit in + the chosen type, -Werror=overflow will catch it, so this should be safe. */ +#define __TYPEOF_UNLESS_CONST(expr, fallback_expr) __typeof__( \ + __builtin_choose_expr(__builtin_constant_p(expr), fallback_expr, expr)) + +/* This creates a unique local variable name for use in macros. */ +#define __TMPNAME_3(i) __tmpname_##i +#define __TMPNAME_2(i) __TMPNAME_3(i) +#define __TMPNAME __TMPNAME_2(__COUNTER__) + +#endif diff --git a/util/commonlib/include/commonlib/compression.h b/util/commonlib/include/commonlib/compression.h index 428ee42..3988ef8 100644 --- a/util/commonlib/include/commonlib/compression.h +++ b/util/commonlib/include/commonlib/compression.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2016 Google 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. diff --git a/util/commonlib/include/commonlib/coreboot_tables.h b/util/commonlib/include/commonlib/coreboot_tables.h index f411ff2..7bded2a 100644 --- a/util/commonlib/include/commonlib/coreboot_tables.h +++ b/util/commonlib/include/commonlib/coreboot_tables.h @@ -44,6 +44,58 @@ * table entries and be backwards compatible, but it is not required. */ +enum { + LB_TAG_UNUSED = 0x0000, + LB_TAG_MEMORY = 0x0001, + LB_TAG_HWRPB = 0x0002, + LB_TAG_MAINBOARD = 0x0003, + LB_TAG_VERSION = 0x0004, + LB_TAG_EXTRA_VERSION = 0x0005, + LB_TAG_BUILD = 0x0006, + LB_TAG_COMPILE_TIME = 0x0007, + LB_TAG_COMPILE_BY = 0x0008, + LB_TAG_COMPILE_HOST = 0x0009, + LB_TAG_COMPILE_DOMAIN = 0x000a, + LB_TAG_COMPILER = 0x000b, + LB_TAG_LINKER = 0x000c, + LB_TAG_ASSEMBLER = 0x000d, + LB_TAG_SERIAL = 0x000f, + LB_TAG_CONSOLE = 0x0010, + LB_TAG_FORWARD = 0x0011, + LB_TAG_FRAMEBUFFER = 0x0012, + LB_TAG_GPIO = 0x0013, + LB_TAG_TIMESTAMPS = 0x0016, + LB_TAG_CBMEM_CONSOLE = 0x0017, + LB_TAG_MRC_CACHE = 0x0018, + LB_TAG_VBNV = 0x0019, + LB_TAG_VBOOT_HANDOFF = 0x0020, /* deprecated */ + LB_TAG_X86_ROM_MTRR = 0x0021, + LB_TAG_DMA = 0x0022, + LB_TAG_RAM_OOPS = 0x0023, + LB_TAG_ACPI_GNVS = 0x0024, + LB_TAG_BOARD_ID = 0x0025, + LB_TAG_VERSION_TIMESTAMP = 0x0026, + LB_TAG_WIFI_CALIBRATION = 0x0027, + LB_TAG_RAM_CODE = 0x0028, + LB_TAG_SPI_FLASH = 0x0029, + LB_TAG_SERIALNO = 0x002a, + LB_TAG_MTC = 0x002b, + LB_TAG_VPD = 0x002c, + LB_TAG_SKU_ID = 0x002d, + LB_TAG_BOOT_MEDIA_PARAMS = 0x0030, + LB_TAG_CBMEM_ENTRY = 0x0031, + LB_TAG_TSC_INFO = 0x0032, + LB_TAG_MAC_ADDRS = 0x0033, + LB_TAG_VBOOT_WORKBUF = 0x0034, + LB_TAG_MMC_INFO = 0x0035, + LB_TAG_TCPA_LOG = 0x0036, + LB_TAG_CMOS_OPTION_TABLE = 0x00c8, + LB_TAG_OPTION = 0x00c9, + LB_TAG_OPTION_ENUM = 0x00ca, + LB_TAG_OPTION_DEFAULTS = 0x00cb, + LB_TAG_OPTION_CHECKSUM = 0x00cc, +}; + /* Since coreboot is usually compiled 32bit, gcc will align 64bit * types to 32bit boundaries. If the coreboot table is dumped on a * 64bit system, a uint64_t would be aligned to 64bit boundaries, @@ -97,9 +149,6 @@ struct lb_record { uint32_t size; /* size of record (in bytes) */ }; -#define LB_TAG_UNUSED 0x0000 - -#define LB_TAG_MEMORY 0x0001 struct lb_memory_range { struct lb_uint64 start; @@ -120,14 +169,12 @@ struct lb_memory { struct lb_memory_range map[0]; }; -#define LB_TAG_HWRPB 0x0002 struct lb_hwrpb { uint32_t tag; uint32_t size; uint64_t hwrpb; }; -#define LB_TAG_MAINBOARD 0x0003 struct lb_mainboard { uint32_t tag; uint32_t size; @@ -136,23 +183,12 @@ struct lb_mainboard { uint8_t strings[0]; }; -#define LB_TAG_VERSION 0x0004 -#define LB_TAG_EXTRA_VERSION 0x0005 -#define LB_TAG_BUILD 0x0006 -#define LB_TAG_COMPILE_TIME 0x0007 -#define LB_TAG_COMPILE_BY 0x0008 -#define LB_TAG_COMPILE_HOST 0x0009 -#define LB_TAG_COMPILE_DOMAIN 0x000a -#define LB_TAG_COMPILER 0x000b -#define LB_TAG_LINKER 0x000c -#define LB_TAG_ASSEMBLER 0x000d struct lb_string { uint32_t tag; uint32_t size; uint8_t string[0]; }; -#define LB_TAG_VERSION_TIMESTAMP 0x0026 struct lb_timestamp { uint32_t tag; uint32_t size; @@ -162,7 +198,6 @@ struct lb_timestamp { /* 0xe is taken by v3 */ -#define LB_TAG_SERIAL 0x000f struct lb_serial { uint32_t tag; uint32_t size; @@ -189,7 +224,6 @@ struct lb_serial { uint32_t uart_pci_addr; }; -#define LB_TAG_CONSOLE 0x0010 struct lb_console { uint32_t tag; uint32_t size; @@ -204,7 +238,6 @@ struct lb_console { #define LB_TAG_CONSOLE_EHCI 5 #define LB_TAG_CONSOLE_SERIAL8250MEM 6 -#define LB_TAG_FORWARD 0x0011 struct lb_forward { uint32_t tag; uint32_t size; @@ -250,7 +283,18 @@ struct lb_forward { * fields described above. It may, however, only implement a subset * of the possible color formats. */ -#define LB_TAG_FRAMEBUFFER 0x0012 + +/* + * Framebuffer orientation, matches drm_connector.h drm_panel_orientation in the + * Linux kernel. + */ +enum lb_fb_orientation { + LB_FB_ORIENTATION_NORMAL = 0, + LB_FB_ORIENTATION_BOTTOM_UP = 1, + LB_FB_ORIENTATION_LEFT_UP = 2, + LB_FB_ORIENTATION_RIGHT_UP = 3, +}; + struct lb_framebuffer { uint32_t tag; uint32_t size; @@ -268,9 +312,9 @@ struct lb_framebuffer { uint8_t blue_mask_size; uint8_t reserved_mask_pos; uint8_t reserved_mask_size; + uint8_t orientation; }; -#define LB_TAG_GPIO 0x0013 struct lb_gpio { uint32_t port; @@ -290,12 +334,6 @@ struct lb_gpios { struct lb_gpio gpios[0]; }; -#define LB_TAG_VDAT 0x0015 -#define LB_TAG_VBNV 0x0019 -#define LB_TAB_VBOOT_HANDOFF 0x0020 -#define LB_TAB_DMA 0x0022 -#define LB_TAG_RAM_OOPS 0x0023 -#define LB_TAG_MTC 0x002b struct lb_range { uint32_t tag; uint32_t size; @@ -306,12 +344,6 @@ struct lb_range { void lb_ramoops(struct lb_header *header); -#define LB_TAG_TIMESTAMPS 0x0016 -#define LB_TAG_CBMEM_CONSOLE 0x0017 -#define LB_TAG_MRC_CACHE 0x0018 -#define LB_TAG_ACPI_GNVS 0x0024 -#define LB_TAG_WIFI_CALIBRATION 0x0027 -#define LB_TAG_VPD 0x002c struct lb_cbmem_ref { uint32_t tag; uint32_t size; @@ -319,7 +351,6 @@ struct lb_cbmem_ref { uint64_t cbmem_addr; }; -#define LB_TAG_X86_ROM_MTRR 0x0021 struct lb_x86_rom_mtrr { uint32_t tag; uint32_t size; @@ -327,9 +358,6 @@ struct lb_x86_rom_mtrr { uint32_t index; }; -#define LB_TAG_BOARD_ID 0x0025 -#define LB_TAG_RAM_CODE 0x0028 -#define LB_TAG_SKU_ID 0x002d struct lb_strapping_id { uint32_t tag; @@ -337,7 +365,6 @@ struct lb_strapping_id { uint32_t id_code; }; -#define LB_TAG_SPI_FLASH 0x0029 struct lb_spi_flash { uint32_t tag; uint32_t size; @@ -346,7 +373,6 @@ struct lb_spi_flash { uint32_t erase_cmd; }; -#define LB_TAG_BOOT_MEDIA_PARAMS 0x0030 struct lb_boot_media_params { uint32_t tag; uint32_t size; @@ -360,7 +386,6 @@ struct lb_boot_media_params { /* * There can be more than one of these records as there is one per cbmem entry. */ -#define LB_TAG_CBMEM_ENTRY 0x0031 struct lb_cbmem_entry { uint32_t tag; uint32_t size; @@ -370,7 +395,6 @@ struct lb_cbmem_entry { uint32_t id; }; -#define LB_TAG_TSC_INFO 0x0032 struct lb_tsc_info { uint32_t tag; uint32_t size; @@ -378,12 +402,25 @@ struct lb_tsc_info { uint32_t freq_khz; }; -#define LB_TAG_MAC_ADDRS 0x0033 struct mac_address { uint8_t mac_addr[6]; uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */ }; +struct lb_mmc_info { + uint32_t tag; + uint32_t size; + /* + * Passes the early mmc status to payload to indicate if firmware + * successfully sent CMD0, CMD1 to the card or not. In case of + * success, the payload can skip the first step of the initialization + * sequence which is to send CMD0, and instead start by sending CMD1 + * as described in Jedec Standard JESD83-B1 section 6.4.3. + * passes 1 on success + */ + int32_t early_cmd1_status; +}; + struct lb_macs { uint32_t tag; uint32_t size; @@ -391,11 +428,9 @@ struct lb_macs { struct mac_address mac_addrs[0]; }; -#define LB_TAG_SERIALNO 0x002a #define MAX_SERIALNO_LENGTH 32 /* The following structures are for the cmos definitions table */ -#define LB_TAG_CMOS_OPTION_TABLE 200 /* cmos header record */ struct cmos_option_table { uint32_t tag; /* CMOS definitions table type */ @@ -410,7 +445,6 @@ struct cmos_option_table { * starts at the beginning of the byte and the length is * fills complete bytes. */ -#define LB_TAG_OPTION 201 struct cmos_entries { uint32_t tag; /* entry type */ uint32_t size; /* length of this record */ @@ -428,7 +462,6 @@ struct cmos_entries { * This record is variable length. The text field may be * shorter than CMOS_MAX_TEXT_LENGTH. */ -#define LB_TAG_OPTION_ENUM 202 struct cmos_enums { uint32_t tag; /* enumeration type */ uint32_t size; /* length of this record */ @@ -442,7 +475,6 @@ struct cmos_enums { /* cmos defaults record * This record contains default settings for the cmos ram. */ -#define LB_TAG_OPTION_DEFAULTS 203 struct cmos_defaults { uint32_t tag; /* default type */ uint32_t size; /* length of this record */ @@ -452,7 +484,6 @@ struct cmos_defaults { uint8_t default_set[CMOS_IMAGE_BUFFER_SIZE]; /* default settings */ }; -#define LB_TAG_OPTION_CHECKSUM 204 struct cmos_checksum { uint32_t tag; uint32_t size; diff --git a/util/commonlib/include/commonlib/endian.h b/util/commonlib/include/commonlib/endian.h index 7b08eee..3d7ccb1 100644 --- a/util/commonlib/include/commonlib/endian.h +++ b/util/commonlib/include/commonlib/endian.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2015 Google 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. diff --git a/util/commonlib/include/commonlib/fmap_serialized.h b/util/commonlib/include/commonlib/fmap_serialized.h index cea231b..53a09af 100644 --- a/util/commonlib/include/commonlib/fmap_serialized.h +++ b/util/commonlib/include/commonlib/fmap_serialized.h @@ -37,7 +37,6 @@ #define FLASHMAP_SERIALIZED_H__ #include -#include #define FMAP_SIGNATURE "__FMAP__" #define FMAP_VER_MAJOR 1 /* this header's FMAP minor version */ @@ -49,6 +48,7 @@ enum fmap_flags { FMAP_AREA_STATIC = 1 << 0, FMAP_AREA_COMPRESSED = 1 << 1, FMAP_AREA_RO = 1 << 2, + FMAP_AREA_PRESERVE = 1 << 3, }; /* Mapping of volatile and static regions in firmware binary */ diff --git a/util/commonlib/include/commonlib/fsp.h b/util/commonlib/include/commonlib/fsp.h index a2a2fae..2ae7949 100644 --- a/util/commonlib/include/commonlib/fsp.h +++ b/util/commonlib/include/commonlib/fsp.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2016 Google 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. diff --git a/util/commonlib/include/commonlib/helpers.h b/util/commonlib/include/commonlib/helpers.h index f2acedc..4429ea4 100644 --- a/util/commonlib/include/commonlib/helpers.h +++ b/util/commonlib/include/commonlib/helpers.h @@ -16,6 +16,7 @@ /* This file is for helpers for both coreboot firmware and its utilities. */ #ifndef __ASSEMBLER__ +#include #include #endif @@ -29,31 +30,71 @@ #define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) #define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) +/* Double-evaluation unsafe min/max, for bitfields and outside of functions */ +#define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b)) +#define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <) +#define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >) + +#define __CMP_SAFE(a, b, op, var_a, var_b) ({ \ + __TYPEOF_UNLESS_CONST(a, b) var_a = (a); \ + __TYPEOF_UNLESS_CONST(b, a) var_b = (b); \ + var_a op var_b ? var_a : var_b; \ +}) + +#ifdef __ROMCC__ /* romcc doesn't support __builtin_choose_expr() */ +#define __CMP(a, b, op) __CMP_UNSAFE(a, b, op) +#else +#define __CMP(a, b, op) __builtin_choose_expr( \ + __builtin_constant_p(a) && __builtin_constant_p(b), \ + __CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME)) +#endif + #ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MIN(a, b) __CMP(a, b, <) #endif #ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MAX(a, b) __CMP(a, b, >) #endif -#define ABS(a) (((a) < 0) ? (-(a)) : (a)) -#define CEIL_DIV(a, b) (((a) + (b) - 1) / (b)) -#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) -#define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) + +#ifndef ABS +#define ABS(a) ({ \ + __typeof__(a) _abs_local_a = (a); \ + (_abs_local_a < 0) ? (-_abs_local_a) : _abs_local_a; \ +}) +#endif + +#define IS_POWER_OF_2(x) ({ \ + __typeof__(x) _power_local_x = (x); \ + (_power_local_x & (_power_local_x - 1)) == 0; \ +}) + +#define DIV_ROUND_UP(x, y) ({ \ + __typeof__(x) _div_local_x = (x); \ + __typeof__(y) _div_local_y = (y); \ + (_div_local_x + _div_local_y - 1) / _div_local_y; \ +}) + +#define SWAP(a, b) do { \ + __typeof__(&(a)) _swap_local_a = &(a); \ + __typeof__(&(b)) _swap_local_b = &(b); \ + __typeof__(a) _swap_local_tmp = *_swap_local_a; \ + *_swap_local_a = *_swap_local_b; \ + *_swap_local_b = _swap_local_tmp; \ +} while (0) + /* * Divide positive or negative dividend by positive divisor and round * to closest integer. Result is undefined for negative divisors and * for negative dividends if the divisor variable type is unsigned. */ -#define DIV_ROUND_CLOSEST(x, divisor)( \ -{ \ - typeof(x) __x = x; \ - typeof(divisor) __d = divisor; \ - (((typeof(x))-1) > 0 || \ - ((typeof(divisor))-1) > 0 || (__x) > 0) ? \ - (((__x) + ((__d) / 2)) / (__d)) : \ - (((__x) - ((__d) / 2)) / (__d)); \ -} \ -) +#define DIV_ROUND_CLOSEST(x, divisor)({ \ + __typeof__(x) _div_local_x = (x); \ + __typeof__(divisor) _div_local_d = (divisor); \ + (((__typeof__(x))-1) > 0 || \ + ((__typeof__(divisor))-1) > 0 || (_div_local_x) > 0) ? \ + ((_div_local_x + (_div_local_d / 2)) / _div_local_d) : \ + ((_div_local_x - (_div_local_d / 2)) / _div_local_d); \ +}) /* Standard units. */ #define KiB (1<<10) diff --git a/util/commonlib/include/commonlib/iobuf.h b/util/commonlib/include/commonlib/iobuf.h index c5a0f4c..f114ef8 100644 --- a/util/commonlib/include/commonlib/iobuf.h +++ b/util/commonlib/include/commonlib/iobuf.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2017 Google 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. diff --git a/util/commonlib/include/commonlib/loglevel.h b/util/commonlib/include/commonlib/loglevel.h index 4247532..7a16541 100644 --- a/util/commonlib/include/commonlib/loglevel.h +++ b/util/commonlib/include/commonlib/loglevel.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2015 Nicholas Sielicki - * * 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; either version 2 of the License, or diff --git a/util/commonlib/include/commonlib/mem_pool.h b/util/commonlib/include/commonlib/mem_pool.h index c21fa0e..ed473eb 100644 --- a/util/commonlib/include/commonlib/mem_pool.h +++ b/util/commonlib/include/commonlib/mem_pool.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2015 Google 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. diff --git a/util/commonlib/include/commonlib/region.h b/util/commonlib/include/commonlib/region.h index 45484dd..dca12dc 100644 --- a/util/commonlib/include/commonlib/region.h +++ b/util/commonlib/include/commonlib/region.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright 2015 Google 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. diff --git a/util/commonlib/include/commonlib/rmodule-defs.h b/util/commonlib/include/commonlib/rmodule-defs.h index 485d638..de06941 100644 --- a/util/commonlib/include/commonlib/rmodule-defs.h +++ b/util/commonlib/include/commonlib/rmodule-defs.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2014 Google 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. @@ -17,7 +15,6 @@ #include #include -#include #define RMODULE_MAGIC 0xf8fe #define RMODULE_VERSION_1 1 diff --git a/util/commonlib/include/commonlib/sd_mmc_ctrlr.h b/util/commonlib/include/commonlib/sd_mmc_ctrlr.h index 247c0a5..d4a7d54 100644 --- a/util/commonlib/include/commonlib/sd_mmc_ctrlr.h +++ b/util/commonlib/include/commonlib/sd_mmc_ctrlr.h @@ -1,10 +1,5 @@ /* - * Copyright 2011, Marvell Semiconductor Inc. - * Lei Wen - * - * Copyright 2017 Intel Corporation - * - * Controller independent definitions + * This file is part of the coreboot project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,6 +10,8 @@ * 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. + * + * Controller independent definitions */ #ifndef __COMMONLIB_SD_MMC_CTRLR_H__ #define __COMMONLIB_SD_MMC_CTRLR_H__ diff --git a/util/commonlib/include/commonlib/sdhci.h b/util/commonlib/include/commonlib/sdhci.h index ffeb662..015fd0c 100644 --- a/util/commonlib/include/commonlib/sdhci.h +++ b/util/commonlib/include/commonlib/sdhci.h @@ -1,10 +1,5 @@ /* - * Copyright 2011, Marvell Semiconductor Inc. - * Lei Wen - * - * Copyright 2017 Intel Corporation - * - * SD host controller specific definitions + * This file is part of the coreboot project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,6 +10,8 @@ * 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. + * + * SD host controller specific definitions */ #ifndef __COMMONLIB_SDHCI_H__ #define __COMMONLIB_SDHCI_H__ diff --git a/util/commonlib/include/commonlib/sort.h b/util/commonlib/include/commonlib/sort.h new file mode 100644 index 0000000..3d91cd8 --- /dev/null +++ b/util/commonlib/include/commonlib/sort.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * 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 _COMMONLIB_SORT_H_ +#define _COMMONLIB_SORT_H_ + +#include + +typedef enum { + NUM_ASCENDING, + NUM_DESCENDING +} sort_order_t; + +void bubblesort(int *v, size_t num_entries, sort_order_t order); + +#endif /* _COMMONLIB_SORT_H_ */ diff --git a/util/commonlib/include/commonlib/stdlib.h b/util/commonlib/include/commonlib/stdlib.h index cfe027f..4a3671c 100644 --- a/util/commonlib/include/commonlib/stdlib.h +++ b/util/commonlib/include/commonlib/stdlib.h @@ -35,14 +35,14 @@ #include #include -#if IS_ENABLED(CONFIG_COREBOOT_BUILD) +#if CONFIG(COREBOOT_BUILD) #include #include -#define printf(...) printk(BIOS_ERR, __VA_ARGS__) #define HALT(x) halt() #else #include -#define HALT(x) +#define printk(level, ...) printf(__VA_ARGS__) +#define HALT(x) abort() #endif static inline void *xmalloc_work(size_t size, const char *file, @@ -50,7 +50,7 @@ static inline void *xmalloc_work(size_t size, const char *file, { void *ret = malloc(size); if (!ret && size) { - printf("%s/%s/line %d: Failed to malloc %zu bytes\n", + printk(BIOS_ERR, "%s/%s/line %d: Failed to malloc %zu bytes\n", file, func, line, size); while (1) HALT(1); diff --git a/util/commonlib/include/commonlib/storage.h b/util/commonlib/include/commonlib/storage.h index 6ad53dc..47a2bb6 100644 --- a/util/commonlib/include/commonlib/storage.h +++ b/util/commonlib/include/commonlib/storage.h @@ -1,9 +1,5 @@ /* - * Copyright 2008,2010 Freescale Semiconductor, Inc - * Andy Fleming - * - * Copyright 2013 Google Inc. All rights reserved. - * Copyright 2017 Intel Corporation + * This file is part of the coreboot project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/util/commonlib/include/commonlib/tcpa_log_serialized.h b/util/commonlib/include/commonlib/tcpa_log_serialized.h new file mode 100644 index 0000000..020eb04 --- /dev/null +++ b/util/commonlib/include/commonlib/tcpa_log_serialized.h @@ -0,0 +1,40 @@ +/* + * This file is part of the coreboot project. + * + * 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 __TCPA_LOG_SERIALIZED_H__ +#define __TCPA_LOG_SERIALIZED_H__ + +#include + +#define MAX_TCPA_LOG_ENTRIES 50 +#define TCPA_DIGEST_MAX_LENGTH 64 +#define TCPA_PCR_HASH_NAME 50 +#define TCPA_PCR_HASH_LEN 10 +/* Assumption of 2K TCPA log size reserved for CAR/SRAM */ +#define MAX_PRERAM_TCPA_LOG_ENTRIES 15 + +struct tcpa_entry { + uint32_t pcr; + char digest_type[TCPA_PCR_HASH_LEN]; + uint8_t digest[TCPA_DIGEST_MAX_LENGTH]; + uint32_t digest_length; + char name[TCPA_PCR_HASH_NAME]; +} __packed; + +struct tcpa_table { + uint16_t max_entries; + uint16_t num_entries; + struct tcpa_entry entries[0]; /* Variable number of entries */ +} __packed; + +#endif diff --git a/util/commonlib/include/commonlib/timestamp_serialized.h b/util/commonlib/include/commonlib/timestamp_serialized.h index 304e43f..7b1a730 100644 --- a/util/commonlib/include/commonlib/timestamp_serialized.h +++ b/util/commonlib/include/commonlib/timestamp_serialized.h @@ -1,8 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. - * * 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. @@ -17,7 +15,6 @@ #define __TIMESTAMP_SERIALIZED_H__ #include -#include struct timestamp_entry { uint32_t entry_id; @@ -64,6 +61,8 @@ enum timestamp_id { TS_LOAD_PAYLOAD = 90, TS_ACPI_WAKE_JUMP = 98, TS_SELFBOOT_JUMP = 99, + TS_START_POSTCAR = 100, + TS_END_POSTCAR = 101, /* 500+ reserved for vendorcode extensions (500-600: google/chromeos) */ TS_START_COPYVER = 501, @@ -258,6 +257,8 @@ static const struct timestamp_id_to_name { { TS_FSP_BEFORE_END_OF_FIRMWARE, "calling FspNotify(EndOfFirmware)" }, { TS_FSP_AFTER_END_OF_FIRMWARE, "returning from FspNotify(EndOfFirmware)" }, + { TS_START_POSTCAR, "start of postcar" }, + { TS_END_POSTCAR, "end of postcar" }, }; #endif diff --git a/util/ifdtool/Makefile b/util/ifdtool/Makefile index fcd0c68..4011851 100644 --- a/util/ifdtool/Makefile +++ b/util/ifdtool/Makefile @@ -16,9 +16,9 @@ PROGRAM = ifdtool CC = gcc -INSTALL = /usr/bin/install +INSTALL = /usr/bin/env install PREFIX = /usr/local -CFLAGS = -O2 -g -Wall -W -Werror -I../commonlib/include +CFLAGS = -O2 -g -Wall -Wextra -Wmissing-prototypes -Werror -I../commonlib/include LDFLAGS = OBJS = ifdtool.o diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index d99bdb9..83caa69 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -40,6 +40,7 @@ (const char *)&(ptr)[1] <= (base) + (limit)) static int ifd_version; +static int chipset; static unsigned int max_regions = 0; static int selected_chip = 0; static int platform = -1; @@ -56,6 +57,33 @@ static const struct region_name region_names[MAX_REGIONS] = { { "EC", "ec", "flashregion_8_ec.bin" }, }; +/* port from flashrom */ +static const char *const ich_chipset_names[] = { + "Unknown ICH", + "ICH", + "ICH2345", + "ICH6", + "SCH U", + "Atom E6xx", + "Atom S1220 S1240 S1260", + "ICH7", + "ICH8", + "ICH9", + "ICH10", + "5 series Ibex Peak", + "6 series Cougar Point", + "7 series Panther Point", + "8 series Lynx Point", + "Baytrail", + "8 series Lynx Point LP", + "8 series Wellsburg", + "9 series Wildcat Point", + "9 series Wildcat Point LP", + "100 series Sunrise Point", + "C620 series Lewisburg", + NULL +}; + static fdbar_t *find_fd(char *image, int size) { int i, found = 0; @@ -77,6 +105,21 @@ static fdbar_t *find_fd(char *image, int size) return PTR_IN_RANGE(fdb, image, size) ? fdb : NULL; } +static char *find_flumap(char *image, int size) +{ + /* The upper map is located in the word before the 256B-long OEM section + * at the end of the 4kB-long flash descriptor. In the official + * documentation this is defined as FDBAR + 0xEFC. However, starting + * with B-Step of Ibex Peak (5 series) the signature (and thus FDBAR) + * has moved 16 bytes back to offset 0x10 of the image. Although + * official documentation still maintains the offset relative to FDBAR + * this is wrong and a simple fixed offset from the start of the image + * works. + */ + char *flumap = image + 4096 - 256 - 4; + return PTR_IN_RANGE(flumap, image, size) ? flumap : NULL; +} + static fcba_t *find_fcba(char *image, int size) { fdbar_t *fdb = find_fd(image, size); @@ -125,6 +168,41 @@ static fmsba_t *find_fmsba(char *image, int size) return PTR_IN_RANGE(fmsba, image, size) ? fmsba : NULL; } +/* port from flashrom */ +static enum ich_chipset guess_ich_chipset(const fdbar_t *fdb) +{ + uint32_t iccriba = (fdb->flmap2 >> 16) & 0xff; + uint32_t msl = (fdb->flmap2 >> 8) & 0xff; + uint32_t isl = (fdb->flmap1 >> 24); + uint32_t nm = (fdb->flmap1 >> 8) & 0x7; + + if (iccriba == 0x00) { + if (msl == 0 && isl <= 2) + return CHIPSET_ICH8; + else if (isl <= 2) + return CHIPSET_ICH9; + else if (isl <= 10) + return CHIPSET_ICH10; + else if (isl <= 16) + return CHIPSET_5_SERIES_IBEX_PEAK; + printf("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n"); + return CHIPSET_5_SERIES_IBEX_PEAK; + } else if (iccriba < 0x31 && (fdb->flmap2 & 0xff) < 0x30) { + if (msl == 0 && isl <= 17) + return CHIPSET_BAYTRAIL; + else if (msl <= 1 && isl <= 18) + return CHIPSET_6_SERIES_COUGAR_POINT; + else if (msl <= 1 && isl <= 21) + return CHIPSET_8_SERIES_LYNX_POINT; + printf("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n"); + return CHIPSET_9_SERIES_WILDCAT_POINT; + } else if (nm == 6) { + return CHIPSET_C620_SERIES_LEWISBURG; + } else { + return CHIPSET_100_SERIES_SUNRISE_POINT; + } +} + /* * Some newer platforms have re-defined the FCBA field that was used to * distinguish IFD v1 v/s v2. Define a list of platforms that we know do not @@ -136,6 +214,7 @@ static int is_platform_ifd_2(void) static const int ifd_2_platforms[] = { PLATFORM_GLK, PLATFORM_CNL, + PLATFORM_ICL, }; unsigned int i; @@ -156,9 +235,14 @@ static int get_ifd_version_from_fcba(char *image, int size) { int read_freq; const fcba_t *fcba = find_fcba(image, size); - if (!fcba) + const fdbar_t *fdb = find_fd(image, size); + if (!fcba || !fdb) exit(EXIT_FAILURE); + chipset = guess_ich_chipset(fdb); + /* TODO: port ifd_version and max_regions + * against guess_ich_chipset() + */ read_freq = (fcba->flcomp >> 17) & 7; switch (read_freq) { @@ -448,6 +532,19 @@ static void dump_fpsba(const fpsba_t *fpsba) for (i = 0; i < ARRAY_SIZE(fpsba->pchstrp); i++) printf("PCHSTRP%u:%s 0x%08x\n", i, i < 10 ? " " : "", fpsba->pchstrp[i]); + + if (ifd_version >= IFD_VERSION_2) { + printf("HAP bit is %sset\n", + fpsba->pchstrp[0] & (1 << 16) ? "" : "not "); + } else if (chipset >= CHIPSET_ICH8 + && chipset <= CHIPSET_ICH10) { + printf("ICH_MeDisable bit is %sset\n", + fpsba->pchstrp[0] & 1 ? "" : "not "); + } else { + printf("AltMeDisable bit is %sset\n", + fpsba->pchstrp[10] & (1 << 7) ? "" : "not "); + } + printf("\n"); } @@ -520,16 +617,23 @@ static void dump_fmsba(const fmsba_t *fmsba) printf("Found Processor Strap Section\n"); for (i = 0; i < ARRAY_SIZE(fmsba->data); i++) printf("????: 0x%08x\n", fmsba->data[i]); + + if (chipset >= CHIPSET_ICH8 && chipset <= CHIPSET_ICH10) { + printf("MCH_MeDisable bit is %sset\n", + fmsba->data[0] & 1 ? "" : "not "); + printf("MCH_AltMeDisable bit is %sset\n", + fmsba->data[0] & (1 << 7) ? "" : "not "); + } } static void dump_jid(uint32_t jid) { - printf(" SPI Componend Device ID 1: 0x%02x\n", - (jid >> 16) & 0xff); - printf(" SPI Componend Device ID 0: 0x%02x\n", - (jid >> 8) & 0xff); printf(" SPI Componend Vendor ID: 0x%02x\n", jid & 0xff); + printf(" SPI Componend Device ID 0: 0x%02x\n", + (jid >> 8) & 0xff); + printf(" SPI Componend Device ID 1: 0x%02x\n", + (jid >> 16) & 0xff); } static void dump_vscc(uint32_t vscc) @@ -586,7 +690,8 @@ static void dump_vscc(uint32_t vscc) static void dump_vtba(const vtba_t *vtba, int vtl) { int i; - int num = (vtl >> 1) < 8 ? (vtl >> 1) : 8; + int max_len = sizeof(vtba_t)/sizeof(vscc_t); + int num = (vtl >> 1) < max_len ? (vtl >> 1) : max_len; printf("ME VSCC table:\n"); for (i = 0; i < num; i++) { @@ -617,6 +722,7 @@ static void dump_fd(char *image, int size) if (!fdb) exit(EXIT_FAILURE); + printf("ICH Revision: %s\n", ich_chipset_names[chipset]); printf("FLMAP0: 0x%08x\n", fdb->flmap0); printf(" NR: %d\n", (fdb->flmap0 >> 24) & 7); printf(" FRBA: 0x%x\n", ((fdb->flmap0 >> 16) & 0xff) << 4); @@ -633,14 +739,16 @@ static void dump_fd(char *image, int size) printf(" PSL: 0x%04x\n", (fdb->flmap2 >> 8) & 0xffff); printf(" FMSBA: 0x%x\n", ((fdb->flmap2) & 0xff) << 4); - printf("FLUMAP1: 0x%08x\n", fdb->flumap1); + char *flumap = find_flumap(image, size); + uint32_t flumap1 = *(uint32_t *)flumap; + printf("FLUMAP1: 0x%08x\n", flumap1); printf(" Intel ME VSCC Table Length (VTL): %d\n", - (fdb->flumap1 >> 8) & 0xff); + (flumap1 >> 8) & 0xff); printf(" Intel ME VSCC Table Base Address (VTBA): 0x%06x\n\n", - (fdb->flumap1 & 0xff) << 4); + (flumap1 & 0xff) << 4); dump_vtba((vtba_t *) - (image + ((fdb->flumap1 & 0xff) << 4)), - (fdb->flumap1 >> 8) & 0xff); + (image + ((flumap1 & 0xff) << 4)), + (flumap1 >> 8) & 0xff); dump_oem((const uint8_t *)image + 0xf00); const frba_t *frba = find_frba(image, size); @@ -817,15 +925,24 @@ static void set_chipdensity(const char *filename, char *image, int size, write_image(filename, image, size); } +static int check_region(const frba_t *frba, unsigned int region_type) +{ + region_t region; + + if (!frba) + return 0; + + region = get_region(frba, region_type); + return !!((region.base < region.limit) && (region.size > 0)); +} + static void lock_descriptor(const char *filename, char *image, int size) { int wr_shift, rd_shift; fmba_t *fmba = find_fmba(image, size); + const frba_t *frba = find_frba(image, size); if (!fmba) exit(EXIT_FAILURE); - /* TODO: Dynamically take Platform Data Region and GbE Region - * into regard. - */ if (ifd_version >= IFD_VERSION_2) { wr_shift = FLMSTR_WR_SHIFT_V2; @@ -835,6 +952,7 @@ static void lock_descriptor(const char *filename, char *image, int size) fmba->flmstr1 &= 0xff; fmba->flmstr2 &= 0xff; fmba->flmstr3 &= 0xff; + fmba->flmstr5 &= 0xff; } else { wr_shift = FLMSTR_WR_SHIFT_V1; rd_shift = FLMSTR_RD_SHIFT_V1; @@ -857,37 +975,69 @@ static void lock_descriptor(const char *filename, char *image, int size) /* TXE can only write Device Expansion */ fmba->flmstr2 |= 0x20 << wr_shift; break; + case PLATFORM_CNL: + case PLATFORM_ICL: case PLATFORM_SKLKBL: - /* CPU/BIOS can read descriptor, BIOS and GbE. */ - fmba->flmstr1 |= 0xb << rd_shift; - /* CPU/BIOS can write BIOS and Gbe. */ - fmba->flmstr1 |= 0xa << wr_shift; - /* ME can read descriptor, ME and GbE. */ - fmba->flmstr2 |= 0xd << rd_shift; + /* CPU/BIOS can read descriptor and BIOS. */ + fmba->flmstr1 |= (1 << REGION_DESC) << rd_shift; + fmba->flmstr1 |= (1 << REGION_BIOS) << rd_shift; + /* CPU/BIOS can write BIOS. */ + fmba->flmstr1 |= (1 << REGION_BIOS) << wr_shift; + /* ME can read descriptor and ME. */ + fmba->flmstr2 |= (1 << REGION_DESC) << rd_shift; + fmba->flmstr2 |= (1 << REGION_ME) << rd_shift; /* ME can write ME. */ - fmba->flmstr2 |= 0x4 << wr_shift; - /* GbE can read GbE and descriptor. */ - fmba->flmstr3 |= 0x9 << rd_shift; - /* GbE can write GbE. */ - fmba->flmstr3 |= 0x8 << wr_shift; - /* EC can read EC and descriptor. */ - fmba->flmstr5 |= 0x101 << rd_shift; - /* EC can write EC region. */ - fmba->flmstr5 |= 0x100 << wr_shift; + fmba->flmstr2 |= (1 << REGION_ME) << wr_shift; + if (check_region(frba, REGION_GBE)) { + /* BIOS can read/write GbE. */ + fmba->flmstr1 |= (1 << REGION_GBE) << rd_shift; + fmba->flmstr1 |= (1 << REGION_GBE) << wr_shift; + /* ME can read GbE. */ + fmba->flmstr2 |= (1 << REGION_GBE) << rd_shift; + /* GbE can read descriptor and read/write GbE.. */ + fmba->flmstr3 |= (1 << REGION_DESC) << rd_shift; + fmba->flmstr3 |= (1 << REGION_GBE) << rd_shift; + fmba->flmstr3 |= (1 << REGION_GBE) << wr_shift; + } + if (check_region(frba, REGION_PDR)) { + /* BIOS can read/write PDR. */ + fmba->flmstr1 |= (1 << REGION_PDR) << rd_shift; + fmba->flmstr1 |= (1 << REGION_PDR) << wr_shift; + } + if (check_region(frba, REGION_EC)) { + /* BIOS can read EC. */ + fmba->flmstr1 |= (1 << REGION_EC) << rd_shift; + /* EC can read descriptor and read/write EC. */ + fmba->flmstr5 |= (1 << REGION_DESC) << rd_shift; + fmba->flmstr5 |= (1 << REGION_EC) << rd_shift; + fmba->flmstr5 |= (1 << REGION_EC) << wr_shift; + } break; default: - /* CPU/BIOS can read descriptor, BIOS, and GbE. */ - fmba->flmstr1 |= 0xb << rd_shift; - /* CPU/BIOS can write BIOS and GbE. */ - fmba->flmstr1 |= 0xa << wr_shift; - /* ME can read descriptor, ME, and GbE. */ - fmba->flmstr2 |= 0xd << rd_shift; - /* ME can write ME and GbE. */ - fmba->flmstr2 |= 0xc << wr_shift; - /* GbE can write only GbE. */ - fmba->flmstr3 |= 0x8 << rd_shift; - /* GbE can read only GbE. */ - fmba->flmstr3 |= 0x8 << wr_shift; + /* CPU/BIOS can read descriptor and BIOS. */ + fmba->flmstr1 |= (1 << REGION_DESC) << rd_shift; + fmba->flmstr1 |= (1 << REGION_BIOS) << rd_shift; + /* CPU/BIOS can write BIOS. */ + fmba->flmstr1 |= (1 << REGION_BIOS) << wr_shift; + /* ME can read descriptor and ME. */ + fmba->flmstr2 |= (1 << REGION_DESC) << rd_shift; + fmba->flmstr2 |= (1 << REGION_ME) << rd_shift; + /* ME can write ME. */ + fmba->flmstr2 |= (1 << REGION_ME) << wr_shift; + if (check_region(frba, REGION_GBE)) { + /* BIOS can read GbE. */ + fmba->flmstr1 |= (1 << REGION_GBE) << rd_shift; + /* BIOS can write GbE. */ + fmba->flmstr1 |= (1 << REGION_GBE) << wr_shift; + /* ME can read GbE. */ + fmba->flmstr2 |= (1 << REGION_GBE) << rd_shift; + /* ME can write GbE. */ + fmba->flmstr2 |= (1 << REGION_GBE) << wr_shift; + /* GbE can write GbE. */ + fmba->flmstr3 |= (1 << REGION_GBE) << rd_shift; + /* GbE can read GbE. */ + fmba->flmstr3 |= (1 << REGION_GBE) << wr_shift; + } break; } @@ -905,6 +1055,7 @@ static void unlock_descriptor(const char *filename, char *image, int size) fmba->flmstr1 = 0xffffff00 | (fmba->flmstr1 & 0xff); fmba->flmstr2 = 0xffffff00 | (fmba->flmstr2 & 0xff); fmba->flmstr3 = 0xffffff00 | (fmba->flmstr3 & 0xff); + fmba->flmstr5 = 0xffffff00 | (fmba->flmstr5 & 0xff); } else { fmba->flmstr1 = 0xffff0000; fmba->flmstr2 = 0xffff0000; @@ -915,7 +1066,48 @@ static void unlock_descriptor(const char *filename, char *image, int size) write_image(filename, image, size); } -void inject_region(const char *filename, char *image, int size, +/* Set the AltMeDisable (or HAP for >= IFD_VERSION_2) */ +static void fpsba_set_altmedisable(fpsba_t *fpsba, fmsba_t *fmsba, bool altmedisable) +{ + if (ifd_version >= IFD_VERSION_2) { + printf("%sting the HAP bit to %s Intel ME...\n", + altmedisable?"Set":"Unset", + altmedisable?"disable":"enable"); + if (altmedisable) + fpsba->pchstrp[0] |= (1 << 16); + else + fpsba->pchstrp[0] &= ~(1 << 16); + } else { + if (chipset >= CHIPSET_ICH8 && chipset <= CHIPSET_ICH10) { + printf("%sting the ICH_MeDisable, MCH_MeDisable, " + "and MCH_AltMeDisable to %s Intel ME...\n", + altmedisable?"Set":"Unset", + altmedisable?"disable":"enable"); + if (altmedisable) { + /* MCH_MeDisable */ + fmsba->data[0] |= 1; + /* MCH_AltMeDisable */ + fmsba->data[0] |= (1 << 7); + /* ICH_MeDisable */ + fpsba->pchstrp[0] |= 1; + } else { + fmsba->data[0] &= ~1; + fmsba->data[0] &= ~(1 << 7); + fpsba->pchstrp[0] &= ~1; + } + } else { + printf("%sting the AltMeDisable to %s Intel ME...\n", + altmedisable?"Set":"Unset", + altmedisable?"disable":"enable"); + if (altmedisable) + fpsba->pchstrp[10] |= (1 << 7); + else + fpsba->pchstrp[10] &= ~(1 << 7); + } + } +} + +static void inject_region(const char *filename, char *image, int size, unsigned int region_type, const char *region_fname) { frba_t *frba = find_frba(image, size); @@ -981,7 +1173,7 @@ void inject_region(const char *filename, char *image, int size, write_image(filename, image, size); } -unsigned int next_pow2(unsigned int x) +static unsigned int next_pow2(unsigned int x) { unsigned int y = 1; if (x == 0) @@ -996,7 +1188,7 @@ unsigned int next_pow2(unsigned int x) * Determine if two memory regions overlap. * * @param r1, r2 Memory regions to compare. - * @return 0 if the two regions are seperate + * @return 0 if the two regions are separate * @return 1 if the two regions overlap */ static int regions_collide(const region_t *r1, const region_t *r2) @@ -1004,14 +1196,11 @@ static int regions_collide(const region_t *r1, const region_t *r2) if ((r1->size == 0) || (r2->size == 0)) return 0; - if ( ((r1->base >= r2->base) && (r1->base <= r2->limit)) || - ((r1->limit >= r2->base) && (r1->limit <= r2->limit)) ) - return 1; - - return 0; + /* r1 should be either completely below or completely above r2 */ + return !(r1->limit < r2->base || r1->base > r2->limit); } -void new_layout(const char *filename, char *image, int size, +static void new_layout(const char *filename, char *image, int size, const char *layout_fname) { FILE *romlayout; @@ -1182,6 +1371,8 @@ static void print_usage(const char *name) " Dual Output Fast Read Support\n" " -l | --lock Lock firmware descriptor and ME region\n" " -u | --unlock Unlock firmware descriptor and ME region\n" + " -M | --altmedisable <0|1> Set the AltMeDisable (or HAP for skylake or newer platform)\n" + " bit to disable ME\n" " -p | --platform Add platform-specific quirks\n" " aplk - Apollo Lake\n" " cnl - Cannon Lake\n" @@ -1199,6 +1390,7 @@ int main(int argc, char *argv[]) int mode_dump = 0, mode_extract = 0, mode_inject = 0, mode_spifreq = 0; int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0; int mode_layout = 0, mode_newlayout = 0, mode_density = 0; + int mode_altmedisable = 0, altmedisable = 0; char *region_type_string = NULL, *region_fname = NULL; const char *layout_fname = NULL; int region_type = -1, inputfreq = 0; @@ -1214,6 +1406,7 @@ int main(int argc, char *argv[]) {"spifreq", 1, NULL, 's'}, {"density", 1, NULL, 'D'}, {"chip", 1, NULL, 'C'}, + {"altmedisable", 1, NULL, 'M'}, {"em100", 0, NULL, 'e'}, {"lock", 0, NULL, 'l'}, {"unlock", 0, NULL, 'u'}, @@ -1223,7 +1416,7 @@ int main(int argc, char *argv[]) {0, 0, 0, 0} }; - while ((opt = getopt_long(argc, argv, "df:D:C:xi:n:s:p:eluvh?", + while ((opt = getopt_long(argc, argv, "df:D:C:M:xi:n:s:p:eluvh?", long_options, &option_index)) != EOF) { switch (opt) { case 'd': @@ -1327,6 +1520,15 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } break; + case 'M': + mode_altmedisable = 1; + altmedisable = strtol(optarg, NULL, 0); + if (altmedisable > 1) { + fprintf(stderr, "error: Illegal value\n"); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + break; case 's': // Parse the requested SPI frequency inputfreq = strtol(optarg, NULL, 0); @@ -1381,6 +1583,8 @@ int main(int argc, char *argv[]) platform = PLATFORM_CNL; } else if (!strcmp(optarg, "glk")) { platform = PLATFORM_GLK; + } else if (!strcmp(optarg, "icl")) { + platform = PLATFORM_ICL; } else if (!strcmp(optarg, "sklkbl")) { platform = PLATFORM_SKLKBL; } else { @@ -1404,7 +1608,7 @@ int main(int argc, char *argv[]) if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_newlayout + (mode_spifreq | mode_em100 | mode_unlocked | - mode_locked)) > 1) { + mode_locked) + mode_altmedisable) > 1) { fprintf(stderr, "You may not specify more than one mode.\n\n"); print_usage(argv[0]); exit(EXIT_FAILURE); @@ -1412,7 +1616,7 @@ int main(int argc, char *argv[]) if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_newlayout + mode_spifreq + mode_em100 + mode_locked + - mode_unlocked + mode_density) == 0) { + mode_unlocked + mode_density + mode_altmedisable) == 0) { fprintf(stderr, "You need to specify a mode.\n\n"); print_usage(argv[0]); exit(EXIT_FAILURE); @@ -1485,6 +1689,13 @@ int main(int argc, char *argv[]) if (mode_unlocked) unlock_descriptor(filename, image, size); + if (mode_altmedisable) { + fpsba_t *fpsba = find_fpsba(image, size); + fmsba_t *fmsba = find_fmsba(image, size); + fpsba_set_altmedisable(fpsba, fmsba, altmedisable); + write_image(filename, image, size); + } + free(image); return 0; diff --git a/util/ifdtool/ifdtool.h b/util/ifdtool/ifdtool.h index ef85555..f3b9a53 100644 --- a/util/ifdtool/ifdtool.h +++ b/util/ifdtool/ifdtool.h @@ -14,6 +14,7 @@ */ #include +#include #define IFDTOOL_VERSION "1.2" enum ifd_version { @@ -21,10 +22,41 @@ enum ifd_version { IFD_VERSION_2, }; +/* port from flashrom */ +enum ich_chipset { + CHIPSET_ICH_UNKNOWN, + CHIPSET_ICH, + CHIPSET_ICH2345, + CHIPSET_ICH6, + CHIPSET_POULSBO, /* SCH U* */ + CHIPSET_TUNNEL_CREEK, /* Atom E6xx */ + CHIPSET_CENTERTON, /* Atom S1220 S1240 S1260 */ + CHIPSET_ICH7, + CHIPSET_ICH8, + CHIPSET_ICH9, + CHIPSET_ICH10, + CHIPSET_5_SERIES_IBEX_PEAK, + CHIPSET_6_SERIES_COUGAR_POINT, + CHIPSET_7_SERIES_PANTHER_POINT, + CHIPSET_8_SERIES_LYNX_POINT, + CHIPSET_BAYTRAIL, /* Actually all with Silvermont architecture: + * Bay Trail, Avoton/Rangeley + */ + CHIPSET_8_SERIES_LYNX_POINT_LP, + CHIPSET_8_SERIES_WELLSBURG, + CHIPSET_9_SERIES_WILDCAT_POINT, + CHIPSET_9_SERIES_WILDCAT_POINT_LP, + CHIPSET_100_SERIES_SUNRISE_POINT, /* also 6th/7th gen Core i/o (LP) + * variants + */ + CHIPSET_C620_SERIES_LEWISBURG, +}; + enum platform { PLATFORM_APL, PLATFORM_CNL, PLATFORM_GLK, + PLATFORM_ICL, PLATFORM_SKLKBL, }; @@ -56,14 +88,21 @@ typedef struct { uint32_t flmap0; uint32_t flmap1; uint32_t flmap2; - uint8_t reserved[0xefc - 0x20]; - uint32_t flumap1; } __attribute__((packed)) fdbar_t; // regions #define MAX_REGIONS 9 #define MAX_REGIONS_OLD 5 +enum flash_regions { + REGION_DESC, + REGION_BIOS, + REGION_ME, + REGION_GBE, + REGION_PDR, + REGION_EC = 8, +}; + typedef struct { uint32_t flreg[MAX_REGIONS]; } __attribute__((packed)) frba_t; @@ -113,6 +152,8 @@ typedef struct { typedef struct { // Actual number of entries specified in vtl + /* FIXME: Rationale for the limit of 8. + * AFAICT it's 127, cf. flashrom's ich_descriptors_tool). */ vscc_t entry[8]; } vtba_t;