From c844d07ff578fec4d3e5cf8d4491f745ce321fe2 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Tue, 17 Apr 2018 20:12:56 +0200 Subject: [PATCH] util: add coreboot's commonlib/include directory for building ifdtool --- util/commonlib/include/commonlib/cbfs.h | 82 +++ .../include/commonlib/cbfs_serialized.h | 240 +++++++++ util/commonlib/include/commonlib/cbmem_id.h | 135 +++++ .../commonlib/include/commonlib/compression.h | 34 ++ .../include/commonlib/coreboot_tables.h | 470 ++++++++++++++++++ util/commonlib/include/commonlib/endian.h | 263 ++++++++++ .../include/commonlib/fmap_serialized.h | 74 +++ util/commonlib/include/commonlib/fsp.h | 32 ++ util/commonlib/include/commonlib/helpers.h | 99 ++++ util/commonlib/include/commonlib/iobuf.h | 162 ++++++ util/commonlib/include/commonlib/loglevel.h | 174 +++++++ util/commonlib/include/commonlib/mem_pool.h | 69 +++ util/commonlib/include/commonlib/region.h | 274 ++++++++++ .../include/commonlib/rmodule-defs.h | 60 +++ .../include/commonlib/sd_mmc_ctrlr.h | 228 +++++++++ util/commonlib/include/commonlib/sdhci.h | 76 +++ util/commonlib/include/commonlib/stdlib.h | 74 +++ util/commonlib/include/commonlib/storage.h | 151 ++++++ .../include/commonlib/timestamp_serialized.h | 249 ++++++++++ util/ifdtool/Makefile | 2 +- 20 files changed, 2947 insertions(+), 1 deletion(-) create mode 100644 util/commonlib/include/commonlib/cbfs.h create mode 100644 util/commonlib/include/commonlib/cbfs_serialized.h create mode 100644 util/commonlib/include/commonlib/cbmem_id.h create mode 100644 util/commonlib/include/commonlib/compression.h create mode 100644 util/commonlib/include/commonlib/coreboot_tables.h create mode 100644 util/commonlib/include/commonlib/endian.h create mode 100644 util/commonlib/include/commonlib/fmap_serialized.h create mode 100644 util/commonlib/include/commonlib/fsp.h create mode 100644 util/commonlib/include/commonlib/helpers.h create mode 100644 util/commonlib/include/commonlib/iobuf.h create mode 100644 util/commonlib/include/commonlib/loglevel.h create mode 100644 util/commonlib/include/commonlib/mem_pool.h create mode 100644 util/commonlib/include/commonlib/region.h create mode 100644 util/commonlib/include/commonlib/rmodule-defs.h create mode 100644 util/commonlib/include/commonlib/sd_mmc_ctrlr.h create mode 100644 util/commonlib/include/commonlib/sdhci.h create mode 100644 util/commonlib/include/commonlib/stdlib.h create mode 100644 util/commonlib/include/commonlib/storage.h create mode 100644 util/commonlib/include/commonlib/timestamp_serialized.h diff --git a/util/commonlib/include/commonlib/cbfs.h b/util/commonlib/include/commonlib/cbfs.h new file mode 100644 index 0000000..163bef2 --- /dev/null +++ b/util/commonlib/include/commonlib/cbfs.h @@ -0,0 +1,82 @@ +/* + * 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. + * + * 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_CBFS_H_ +#define _COMMONLIB_CBFS_H_ + +#include +#include +#include + +/* Object representing cbfs files. */ +struct cbfsf { + struct region_device metadata; + struct region_device data; +}; + +/* Locate file by name and optional type. Returns 0 on succcess else < 0 on + * error.*/ +int cbfs_locate(struct cbfsf *fh, const struct region_device *cbfs, + const char *name, uint32_t *type); + +static inline void cbfs_file_data(struct region_device *data, + const struct cbfsf *file) +{ + rdev_chain(data, &file->data, 0, region_device_sz(&file->data)); +} + +static inline void cbfs_file_metadata(struct region_device *metadata, + const struct cbfsf *file) +{ + rdev_chain(metadata, &file->metadata, 0, + region_device_sz(&file->metadata)); +} + +/* + * Provide a handle to each cbfs file within a cbfs. The prev pointer represents + * the previous file (NULL on first invocation). The next object gets filled + * out with the next file. This returns < 0 on error, 0 on finding the next + * file, and > 0 at end of cbfs. + */ +int cbfs_for_each_file(const struct region_device *cbfs, + const struct cbfsf *prev, struct cbfsf *fh); + +/* + * Return the offset for each CBFS attribute in a CBFS file metadata region. + * The metadata must already be fully mapped by the caller. Will return the + * offset (relative to the start of the metadata) or 0 when there are no + * further attributes. Should be called with 0 to begin, then always with + * the previously returned value until it returns 0. + */ +size_t cbfs_for_each_attr(void *metadata, size_t metadata_size, + size_t last_offset); + +/* + * Find out the decompression algorithm and decompressed size of a non-stage + * CBFS file (by parsing its metadata attributes), and return them with + * out-parameters. Returns 0 on success and < 0 on error. + */ +int cbfsf_decompression_info(struct cbfsf *fh, uint32_t *algo, size_t *size); + +/* + * Perform the vb2 hash over the CBFS region skipping empty file contents. + * Caller is responsible for providing the hash algorithm as well as storage + * for the final digest. Return 0 on success or non-zero on error. + */ +int cbfs_vb2_hash_contents(const struct region_device *cbfs, + enum vb2_hash_algorithm hash_alg, void *digest, + size_t digest_sz); + +#endif diff --git a/util/commonlib/include/commonlib/cbfs_serialized.h b/util/commonlib/include/commonlib/cbfs_serialized.h new file mode 100644 index 0000000..9273b35 --- /dev/null +++ b/util/commonlib/include/commonlib/cbfs_serialized.h @@ -0,0 +1,240 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Jordan Crouse + * Copyright (C) 2012 Google, Inc. + * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. + * + * This file is dual-licensed. You can choose between: + * - The GNU GPL, version 2, as published by the Free Software Foundation + * - The revised BSD license (without advertising clause) + * + * --------------------------------------------------------------------------- + * 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. + * --------------------------------------------------------------------------- + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * --------------------------------------------------------------------------- + */ + +#ifndef _CBFS_SERIALIZED_H_ +#define _CBFS_SERIALIZED_H_ + +#include +#include + +/** These are standard values for the known compression + algorithms that coreboot knows about for stages and + payloads. Of course, other CBFS users can use whatever + values they want, as long as they understand them. */ + +#define CBFS_COMPRESS_NONE 0 +#define CBFS_COMPRESS_LZMA 1 +#define CBFS_COMPRESS_LZ4 2 + +/** These are standard component types for well known + components (i.e - those that coreboot needs to consume. + Users are welcome to use any other value for their + components */ + +#define CBFS_TYPE_DELETED 0x00000000 +#define CBFS_TYPE_DELETED2 0xffffffff +#define CBFS_TYPE_STAGE 0x10 +#define CBFS_TYPE_PAYLOAD 0x20 +#define CBFS_TYPE_OPTIONROM 0x30 +#define CBFS_TYPE_BOOTSPLASH 0x40 +#define CBFS_TYPE_RAW 0x50 +#define CBFS_TYPE_VSA 0x51 +#define CBFS_TYPE_MBI 0x52 +#define CBFS_TYPE_MICROCODE 0x53 +#define CBFS_TYPE_FSP 0x60 +#define CBFS_TYPE_MRC 0x61 +#define CBFS_TYPE_MMA 0x62 +#define CBFS_TYPE_EFI 0x63 +#define CBFS_TYPE_STRUCT 0x70 +#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa +#define CBFS_TYPE_SPD 0xab +#define CBFS_TYPE_MRC_CACHE 0xac +#define CBFS_COMPONENT_CMOS_LAYOUT 0x01aa + +#define CBFS_HEADER_MAGIC 0x4F524243 +#define CBFS_HEADER_VERSION1 0x31313131 +#define CBFS_HEADER_VERSION2 0x31313132 +#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2 + +/* this is the master cbfs header - it must be located somewhere available + * to bootblock (to load romstage). The last 4 bytes in the image contain its + * relative offset from the end of the image (as a 32-bit signed integer). */ + +struct cbfs_header { + uint32_t magic; + uint32_t version; + uint32_t romsize; + uint32_t bootblocksize; + uint32_t align; /* fixed to 64 bytes */ + uint32_t offset; + uint32_t architecture; + uint32_t pad[1]; +} __packed; + +/* this used to be flexible, but wasn't ever set to something different. */ +#define CBFS_ALIGNMENT 64 + +/* "Unknown" refers to CBFS headers version 1, + * before the architecture was defined (i.e., x86 only). + */ +#define CBFS_ARCHITECTURE_UNKNOWN 0xFFFFFFFF +#define CBFS_ARCHITECTURE_X86 0x00000001 +#define CBFS_ARCHITECTURE_ARM 0x00000010 + +/** This is a component header - every entry in the CBFS + will have this header. + + This is how the component is arranged in the ROM: + + -------------- <- 0 + component header + -------------- <- sizeof(struct component) + component name + -------------- <- offset + data + ... + -------------- <- offset + len +*/ + +#define CBFS_FILE_MAGIC "LARCHIVE" + +struct cbfs_file { + char magic[8]; + uint32_t len; + uint32_t type; + uint32_t attributes_offset; + uint32_t offset; +} __packed; + +/* The common fields of extended cbfs file attributes. + Attributes are expected to start with tag/len, then append their + specific fields. */ +struct cbfs_file_attribute { + uint32_t tag; + /* len covers the whole structure, incl. tag and len */ + uint32_t len; + uint8_t data[0]; +} __packed; + +/* Depending on how the header was initialized, it may be backed with 0x00 or + * 0xff. Support both. */ +#define CBFS_FILE_ATTR_TAG_UNUSED 0 +#define CBFS_FILE_ATTR_TAG_UNUSED2 0xffffffff +#define CBFS_FILE_ATTR_TAG_COMPRESSION 0x42435a4c +#define CBFS_FILE_ATTR_TAG_HASH 0x68736148 +#define CBFS_FILE_ATTR_TAG_POSITION 0x42435350 /* PSCB */ +#define CBFS_FILE_ATTR_TAG_ALIGNMENT 0x42434c41 /* ALCB */ + +struct cbfs_file_attr_compression { + uint32_t tag; + uint32_t len; + /* whole file compression format. 0 if no compression. */ + uint32_t compression; + uint32_t decompressed_size; +} __packed; + +struct cbfs_file_attr_hash { + uint32_t tag; + uint32_t len; + uint32_t hash_type; + /* hash_data is len - sizeof(struct) bytes */ + uint8_t hash_data[]; +} __packed; + +struct cbfs_file_attr_position { + uint32_t tag; + uint32_t len; + uint32_t position; +} __packed; + +struct cbfs_file_attr_align { + uint32_t tag; + uint32_t len; + uint32_t alignment; +} __packed; + +/* + * ROMCC does not understand uint64_t, so we hide future definitions as they are + * unlikely to be ever needed from ROMCC + */ +#ifndef __ROMCC__ + +/*** Component sub-headers ***/ + +/* Following are component sub-headers for the "standard" + component types */ + +/** This is the sub-header for stage components. Stages are + loaded by coreboot during the normal boot process */ + +struct cbfs_stage { + uint32_t compression; /** Compression type */ + uint64_t entry; /** entry point */ + uint64_t load; /** Where to load in memory */ + uint32_t len; /** length of data to load */ + uint32_t memlen; /** total length of object in memory */ +} __packed; + +/** this is the sub-header for payload components. Payloads + are loaded by coreboot at the end of the boot process */ + +struct cbfs_payload_segment { + uint32_t type; + uint32_t compression; + uint32_t offset; + uint64_t load_addr; + uint32_t len; + uint32_t mem_len; +} __packed; + +struct cbfs_payload { + struct cbfs_payload_segment segments; +}; + +#define PAYLOAD_SEGMENT_CODE 0x434F4445 +#define PAYLOAD_SEGMENT_DATA 0x44415441 +#define PAYLOAD_SEGMENT_BSS 0x42535320 +#define PAYLOAD_SEGMENT_PARAMS 0x50415241 +#define PAYLOAD_SEGMENT_ENTRY 0x454E5452 + +struct cbfs_optionrom { + uint32_t compression; + uint32_t len; +} __packed; + +#endif /* __ROMCC__ */ + +#endif /* _CBFS_SERIALIZED_H_ */ diff --git a/util/commonlib/include/commonlib/cbmem_id.h b/util/commonlib/include/commonlib/cbmem_id.h new file mode 100644 index 0000000..3529fef --- /dev/null +++ b/util/commonlib/include/commonlib/cbmem_id.h @@ -0,0 +1,135 @@ +/* + * 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. + * + * 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 _CBMEM_ID_H_ +#define _CBMEM_ID_H_ + +#define CBMEM_ID_ACPI 0x41435049 +#define CBMEM_ID_ACPI_GNVS 0x474e5653 +#define CBMEM_ID_ACPI_GNVS_PTR 0x474e5650 +#define CBMEM_ID_AFTER_CAR 0xc4787a93 +#define CBMEM_ID_AGESA_RUNTIME 0x41474553 +#define CBMEM_ID_AMDMCT_MEMINFO 0x494D454E +#define CBMEM_ID_CAR_GLOBALS 0xcac4e6a3 +#define CBMEM_ID_CBTABLE 0x43425442 +#define CBMEM_ID_CBTABLE_FWD 0x43425443 +#define CBMEM_ID_CONSOLE 0x434f4e53 +#define CBMEM_ID_COVERAGE 0x47434f56 +#define CBMEM_ID_EHCI_DEBUG 0xe4c1deb9 +#define CBMEM_ID_ELOG 0x454c4f47 +#define CBMEM_ID_FREESPACE 0x46524545 +#define CBMEM_ID_FSP_RESERVED_MEMORY 0x46535052 +#define CBMEM_ID_FSP_RUNTIME 0x52505346 +#define CBMEM_ID_GDT 0x4c474454 +#define CBMEM_ID_HOB_POINTER 0x484f4221 +#define CBMEM_ID_IGD_OPREGION 0x4f444749 +#define CBMEM_ID_IMD_ROOT 0xff4017ff +#define CBMEM_ID_IMD_SMALL 0x53a11439 +#define CBMEM_ID_MEMINFO 0x494D454D +#define CBMEM_ID_MMA_DATA 0x4D4D4144 +#define CBMEM_ID_MPTABLE 0x534d5054 +#define CBMEM_ID_MRCDATA 0x4d524344 +#define CBMEM_ID_VAR_MRCDATA 0x4d524345 +#define CBMEM_ID_MTC 0xcb31d31c +#define CBMEM_ID_NONE 0x00000000 +#define CBMEM_ID_PIRQ 0x49525154 +#define CBMEM_ID_POWER_STATE 0x50535454 +#define CBMEM_ID_RAM_OOPS 0x05430095 +#define CBMEM_ID_RAMSTAGE 0x9a357a9e +#define CBMEM_ID_RAMSTAGE_CACHE 0x9a3ca54e +#define CBMEM_ID_REFCODE 0x04efc0de +#define CBMEM_ID_REFCODE_CACHE 0x4efc0de5 +#define CBMEM_ID_RESUME 0x5245534d +#define CBMEM_ID_RESUME_SCRATCH 0x52455343 +#define CBMEM_ID_ROMSTAGE_INFO 0x47545352 +#define CBMEM_ID_ROMSTAGE_RAM_STACK 0x90357ac4 +#define CBMEM_ID_ROOT 0xff4007ff +#define CBMEM_ID_SMBIOS 0x534d4254 +#define CBMEM_ID_SMM_SAVE_SPACE 0x07e9acee +#define CBMEM_ID_STAGEx_META 0x57a9e000 +#define CBMEM_ID_STAGEx_CACHE 0x57a9e100 +#define CBMEM_ID_STAGEx_RAW 0x57a9e200 +#define CBMEM_ID_STORAGE_DATA 0x53746f72 +#define CBMEM_ID_TCPA_LOG 0x54435041 +#define CBMEM_ID_TIMESTAMP 0x54494d45 +#define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 +#define CBMEM_ID_VBOOT_SEL_REG 0x780074f1 +#define CBMEM_ID_VBOOT_WORKBUF 0x78007343 +#define CBMEM_ID_VPD 0x56504420 +#define CBMEM_ID_WIFI_CALIBRATION 0x57494649 +#define CBMEM_ID_EC_HOSTEVENT 0x63ccbbc3 +#define CBMEM_ID_EXT_VBT 0x69866684 +#define CBMEM_ID_ROM0 0x524f4d30 +#define CBMEM_ID_ROM1 0x524f4d31 +#define CBMEM_ID_ROM2 0x524f4d32 +#define CBMEM_ID_ROM3 0x524f4d33 + +#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_AGESA_RUNTIME, "AGESA RSVD " }, \ + { CBMEM_ID_AFTER_CAR, "AFTER CAR " }, \ + { CBMEM_ID_AMDMCT_MEMINFO, "AMDMEM INFO" }, \ + { CBMEM_ID_CAR_GLOBALS, "CAR GLOBALS" }, \ + { CBMEM_ID_CBTABLE, "COREBOOT " }, \ + { CBMEM_ID_CBTABLE_FWD, "COREBOOTFWD" }, \ + { CBMEM_ID_CONSOLE, "CONSOLE " }, \ + { CBMEM_ID_COVERAGE, "COVERAGE " }, \ + { CBMEM_ID_EHCI_DEBUG, "USBDEBUG " }, \ + { CBMEM_ID_ELOG, "ELOG " }, \ + { CBMEM_ID_FREESPACE, "FREE SPACE " }, \ + { CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY " }, \ + { CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" }, \ + { CBMEM_ID_GDT, "GDT " }, \ + { CBMEM_ID_HOB_POINTER, "HOB " }, \ + { CBMEM_ID_IMD_ROOT, "IMD ROOT " }, \ + { CBMEM_ID_IMD_SMALL, "IMD SMALL " }, \ + { CBMEM_ID_MEMINFO, "MEM INFO " }, \ + { CBMEM_ID_MMA_DATA, "MMA DATA " }, \ + { CBMEM_ID_MPTABLE, "SMP TABLE " }, \ + { CBMEM_ID_MRCDATA, "MRC DATA " }, \ + { CBMEM_ID_VAR_MRCDATA, "VARMRC DATA" }, \ + { CBMEM_ID_MTC, "MTC " }, \ + { CBMEM_ID_PIRQ, "IRQ TABLE " }, \ + { CBMEM_ID_POWER_STATE, "POWER STATE" }, \ + { CBMEM_ID_RAM_OOPS, "RAMOOPS " }, \ + { CBMEM_ID_RAMSTAGE_CACHE, "RAMSTAGE $ " }, \ + { CBMEM_ID_RAMSTAGE, "RAMSTAGE " }, \ + { CBMEM_ID_REFCODE_CACHE, "REFCODE $ " }, \ + { CBMEM_ID_REFCODE, "REFCODE " }, \ + { CBMEM_ID_RESUME, "ACPI RESUME" }, \ + { CBMEM_ID_RESUME_SCRATCH, "ACPISCRATCH" }, \ + { CBMEM_ID_ROMSTAGE_INFO, "ROMSTAGE " }, \ + { CBMEM_ID_ROMSTAGE_RAM_STACK, "ROMSTG STCK" }, \ + { CBMEM_ID_ROOT, "CBMEM ROOT " }, \ + { CBMEM_ID_SMBIOS, "SMBIOS " }, \ + { CBMEM_ID_SMM_SAVE_SPACE, "SMM BACKUP " }, \ + { CBMEM_ID_STORAGE_DATA, "SD/MMC/eMMC" }, \ + { CBMEM_ID_TCPA_LOG, "TCPA LOG " }, \ + { CBMEM_ID_TIMESTAMP, "TIME STAMP " }, \ + { CBMEM_ID_VBOOT_HANDOFF, "VBOOT " }, \ + { CBMEM_ID_VBOOT_SEL_REG, "VBOOT SEL " }, \ + { CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK " }, \ + { CBMEM_ID_VPD, "VPD " }, \ + { CBMEM_ID_WIFI_CALIBRATION, "WIFI CLBR " }, \ + { CBMEM_ID_EC_HOSTEVENT, "EC HOSTEVENT"}, \ + { CBMEM_ID_EXT_VBT, "EXT VBT"}, \ + { CBMEM_ID_ROM0, "VGA ROM #0 "}, \ + { CBMEM_ID_ROM1, "VGA ROM #1 "}, \ + { CBMEM_ID_ROM2, "VGA ROM #2 "}, \ + { CBMEM_ID_ROM3, "VGA ROM #3 "}, +#endif /* _CBMEM_ID_H_ */ diff --git a/util/commonlib/include/commonlib/compression.h b/util/commonlib/include/commonlib/compression.h new file mode 100644 index 0000000..428ee42 --- /dev/null +++ b/util/commonlib/include/commonlib/compression.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * 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_COMPRESSION_H_ +#define _COMMONLIB_COMPRESSION_H_ + +#include + +/* Decompresses an LZ4F image (multiple LZ4 blocks with frame header) from src + * to dst, ensuring that it doesn't read more than srcn bytes and doesn't write + * more than dstn. Buffer sizes must stay below 2GB. Can decompress files loaded + * to the end of a buffer in-place, as long as buffer is larger than the final + * output size. (Usually just a few bytes, but may be up to (8 + dstn/255) in + * worst case. Will reliably return an error if buffer was too small.) + * Returns amount of decompressed bytes, or 0 on error. + */ +size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn); + +/* Same as ulz4fn() but does not perform any bounds checks. */ +size_t ulz4f(const void *src, void *dst); + +#endif /* _COMMONLIB_COMPRESSION_H_ */ diff --git a/util/commonlib/include/commonlib/coreboot_tables.h b/util/commonlib/include/commonlib/coreboot_tables.h new file mode 100644 index 0000000..f411ff2 --- /dev/null +++ b/util/commonlib/include/commonlib/coreboot_tables.h @@ -0,0 +1,470 @@ +/* + * 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_COREBOOT_TABLES_H +#define COMMONLIB_COREBOOT_TABLES_H + +#include + +/* The coreboot table information is for conveying information + * from the firmware to the loaded OS image. Primarily this + * is expected to be information that cannot be discovered by + * other means, such as querying the hardware directly. + * + * All of the information should be Position Independent Data. + * That is it should be safe to relocated any of the information + * without it's meaning/correctness changing. For table that + * can reasonably be used on multiple architectures the data + * size should be fixed. This should ease the transition between + * 32 bit and 64 bit architectures etc. + * + * The completeness test for the information in this table is: + * - Can all of the hardware be detected? + * - Are the per motherboard constants available? + * - Is there enough to allow a kernel to run that was written before + * a particular motherboard is constructed? (Assuming the kernel + * has drivers for all of the hardware but it does not have + * assumptions on how the hardware is connected together). + * + * With this test it should be straight forward to determine if a + * table entry is required or not. This should remove much of the + * long term compatibility burden as table entries which are + * irrelevant or have been replaced by better alternatives may be + * dropped. Of course it is polite and expedite to include extra + * table entries and be backwards compatible, but it is not required. + */ + +/* 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, + * breaking the table format. + * + * lb_uint64 will keep 64bit coreboot table values aligned to 32bit + * to ensure compatibility. They can be accessed with the two functions + * below: unpack_lb64() and pack_lb64() + * + * See also: util/lbtdump/lbtdump.c + */ + +struct lb_uint64 { + uint32_t lo; + uint32_t hi; +}; + +static inline uint64_t unpack_lb64(struct lb_uint64 value) +{ + uint64_t result; + result = value.hi; + result = (result << 32) + value.lo; + return result; +} + +static inline struct lb_uint64 pack_lb64(uint64_t value) +{ + struct lb_uint64 result; + result.lo = (value >> 0) & 0xffffffff; + result.hi = (value >> 32) & 0xffffffff; + return result; +} + +struct lb_header { + uint8_t signature[4]; /* LBIO */ + uint32_t header_bytes; + uint32_t header_checksum; + uint32_t table_bytes; + uint32_t table_checksum; + uint32_t table_entries; +}; + +/* Every entry in the boot environment list will correspond to a boot + * info record. Encoding both type and size. The type is obviously + * so you can tell what it is. The size allows you to skip that + * boot environment record if you don't know what it is. This allows + * forward compatibility with records not yet defined. + */ +struct lb_record { + uint32_t tag; /* tag ID */ + 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; + struct lb_uint64 size; + uint32_t type; +#define LB_MEM_RAM 1 /* Memory anyone can use */ +#define LB_MEM_RESERVED 2 /* Don't use this memory region */ +#define LB_MEM_ACPI 3 /* ACPI Tables */ +#define LB_MEM_NVS 4 /* ACPI NVS Memory */ +#define LB_MEM_UNUSABLE 5 /* Unusable address space */ +#define LB_MEM_VENDOR_RSVD 6 /* Vendor Reserved */ +#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ +}; + +struct lb_memory { + uint32_t tag; + uint32_t size; + 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; + uint8_t vendor_idx; + uint8_t part_number_idx; + 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; + uint32_t timestamp; +}; + + +/* 0xe is taken by v3 */ + +#define LB_TAG_SERIAL 0x000f +struct lb_serial { + uint32_t tag; + uint32_t size; +#define LB_SERIAL_TYPE_IO_MAPPED 1 +#define LB_SERIAL_TYPE_MEMORY_MAPPED 2 + uint32_t type; + uint32_t baseaddr; + uint32_t baud; + uint32_t regwidth; + + /* Crystal or input frequency to the chip containing the UART. + * Provide the board specific details to allow the payload to + * initialize the chip containing the UART and make independent + * decisions as to which dividers to select and their values + * to eventually arrive at the desired console baud-rate. */ + uint32_t input_hertz; + + /* UART PCI address: bus, device, function + * 1 << 31 - Valid bit, PCI UART in use + * Bus << 20 + * Device << 15 + * Function << 12 + */ + uint32_t uart_pci_addr; +}; + +#define LB_TAG_CONSOLE 0x0010 +struct lb_console { + uint32_t tag; + uint32_t size; + uint16_t type; +}; + +#define LB_TAG_CONSOLE_SERIAL8250 0 +#define LB_TAG_CONSOLE_VGA 1 // OBSOLETE +#define LB_TAG_CONSOLE_BTEXT 2 // OBSOLETE +#define LB_TAG_CONSOLE_LOGBUF 3 // OBSOLETE +#define LB_TAG_CONSOLE_SROM 4 // OBSOLETE +#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; + uint64_t forward; +}; + +/** + * coreboot framebuffer + * + * The coreboot framebuffer uses a very common format usually referred + * to as "linear framebuffer": + * + * The first pixel of the framebuffer is the upper left corner, its + * address is given by `physical_address`. + * + * Each pixel is represented by exactly `bits_per_pixel` bits. If a + * pixel (or a color component therein) doesn't fill a whole byte or + * doesn't start on a byte boundary, it starts at the least signifi- + * cant bit not occupied by the previous pixel (or color component). + * Pixels (or color components) that span multiple bytes always start + * in the byte with the lowest address. + * + * The framebuffer provides a visible rectangle of `x_resolution` * + * `y_resolution` pixels. However, the lines always start at a byte + * boundary given by `bytes_per_line`, which may leave a gap after + * each line of pixels. Thus, the data for a pixel with the coordi- + * nates (x, y) from the upper left corner always starts at + * + * physical_address + y * bytes_per_line + x * bits_per_pixel / 8 + * + * `bytes_per_line` is always big enough to hold `x_resolution` + * pixels. It can, however, be arbitrarily higher (e.g. to fulfill + * hardware constraints or for optimization purposes). The size of + * the framebuffer is always `y_resolution * bytes_per_line`. + * + * The coreboot framebuffer only supports RGB color formats. The + * position and size of each color component are specified indivi- + * dually by _mask_pos and _mask_size. To allow byte + * or word aligned pixels, a fourth (padding) component may be + * specified by `reserved_mask_pos` and `reserved_mask_size`. + * + * Software utilizing the coreboot framebuffer shall consider all + * fields described above. It may, however, only implement a subset + * of the possible color formats. + */ +#define LB_TAG_FRAMEBUFFER 0x0012 +struct lb_framebuffer { + uint32_t tag; + uint32_t size; + + uint64_t physical_address; + uint32_t x_resolution; + uint32_t y_resolution; + uint32_t bytes_per_line; + uint8_t bits_per_pixel; + uint8_t red_mask_pos; + uint8_t red_mask_size; + uint8_t green_mask_pos; + uint8_t green_mask_size; + uint8_t blue_mask_pos; + uint8_t blue_mask_size; + uint8_t reserved_mask_pos; + uint8_t reserved_mask_size; +}; + +#define LB_TAG_GPIO 0x0013 + +struct lb_gpio { + uint32_t port; + uint32_t polarity; +#define ACTIVE_LOW 0 +#define ACTIVE_HIGH 1 + uint32_t value; +#define GPIO_MAX_NAME_LENGTH 16 + uint8_t name[GPIO_MAX_NAME_LENGTH]; +}; + +struct lb_gpios { + uint32_t tag; + uint32_t size; + + uint32_t count; + 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; + + uint64_t range_start; + uint32_t range_size; +}; + +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; + + uint64_t cbmem_addr; +}; + +#define LB_TAG_X86_ROM_MTRR 0x0021 +struct lb_x86_rom_mtrr { + uint32_t tag; + uint32_t size; + /* The variable range MTRR index covering the ROM. */ + 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; + uint32_t size; + uint32_t id_code; +}; + +#define LB_TAG_SPI_FLASH 0x0029 +struct lb_spi_flash { + uint32_t tag; + uint32_t size; + uint32_t flash_size; + uint32_t sector_size; + uint32_t erase_cmd; +}; + +#define LB_TAG_BOOT_MEDIA_PARAMS 0x0030 +struct lb_boot_media_params { + uint32_t tag; + uint32_t size; + /* offsets are relative to start of boot media */ + uint64_t fmap_offset; + uint64_t cbfs_offset; + uint64_t cbfs_size; + uint64_t boot_media_size; +}; + +/* + * 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; + + uint64_t address; + uint32_t entry_size; + uint32_t id; +}; + +#define LB_TAG_TSC_INFO 0x0032 +struct lb_tsc_info { + uint32_t tag; + uint32_t size; + + 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_macs { + uint32_t tag; + uint32_t size; + uint32_t count; + 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 */ + uint32_t size; /* size of the entire table */ + uint32_t header_length; /* length of header */ +}; + +/* cmos entry record + * This record is variable length. The name field may be + * shorter than CMOS_MAX_NAME_LENGTH. The entry may start + * anywhere in the byte, but can not span bytes unless it + * 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 */ + uint32_t bit; /* starting bit from start of image */ + uint32_t length; /* length of field in bits */ + uint32_t config; /* e=enumeration, h=hex, r=reserved */ + uint32_t config_id; /* a number linking to an enumeration record */ +#define CMOS_MAX_NAME_LENGTH 32 + uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name of entry in ascii, + variable length int aligned */ +}; + + +/* cmos enumerations record + * 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 */ + uint32_t config_id; /* a number identifying the config id */ + uint32_t value; /* the value associated with the text */ +#define CMOS_MAX_TEXT_LENGTH 32 + uint8_t text[CMOS_MAX_TEXT_LENGTH]; /* enum description in ascii, + variable length int aligned */ +}; + +/* 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 */ + uint32_t name_length; /* length of the following name field */ + uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name identifying the default */ +#define CMOS_IMAGE_BUFFER_SIZE 256 + 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; + /* In practice everything is byte aligned, but things are measured + * in bits to be consistent. + */ + uint32_t range_start; /* First bit that is checksummed (byte aligned) */ + uint32_t range_end; /* Last bit that is checksummed (byte aligned) */ + uint32_t location; /* First bit of the checksum (byte aligned) */ + uint32_t type; /* Checksum algorithm that is used */ +#define CHECKSUM_NONE 0 +#define CHECKSUM_PCBIOS 1 +}; + +#endif diff --git a/util/commonlib/include/commonlib/endian.h b/util/commonlib/include/commonlib/endian.h new file mode 100644 index 0000000..7b08eee --- /dev/null +++ b/util/commonlib/include/commonlib/endian.h @@ -0,0 +1,263 @@ +/* + * 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. + * + * 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_ENDIAN_H_ +#define _COMMONLIB_ENDIAN_H_ + +#include +#include +#include + +/* Endian agnostic functions working on single byte. */ + +static inline uint8_t read_ble8(const void *src) +{ + const uint8_t *s = src; + return *s; +} + +static inline uint8_t read_at_ble8(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_ble8(s); +} + +static inline void write_ble8(void *dest, uint8_t val) +{ + *(uint8_t *)dest = val; +} + +static inline void write_at_ble8(void *dest, uint8_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_ble8(d, val); +} + +/* Big Endian functions. */ + +static inline uint8_t read_be8(const void *src) +{ + return read_ble8(src); +} + +static inline uint8_t read_at_be8(const void *src, size_t offset) +{ + return read_at_ble8(src, offset); +} + +static inline void write_be8(void *dest, uint8_t val) +{ + write_ble8(dest, val); +} + +static inline void write_at_be8(void *dest, uint8_t val, size_t offset) +{ + write_at_ble8(dest, val, offset); +} + +static inline uint16_t read_be16(const void *src) +{ + const uint8_t *s = src; + return (((uint16_t)s[0]) << 8) | (((uint16_t)s[1]) << 0); +} + +static inline uint16_t read_at_be16(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_be16(s); +} + +static inline void write_be16(void *dest, uint16_t val) +{ + write_be8(dest, val >> 8); + write_at_be8(dest, val >> 0, sizeof(uint8_t)); +} + +static inline void write_at_be16(void *dest, uint16_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_be16(d, val); +} + +static inline uint32_t read_be32(const void *src) +{ + const uint8_t *s = src; + return (((uint32_t)s[0]) << 24) | (((uint32_t)s[1]) << 16) | + (((uint32_t)s[2]) << 8) | (((uint32_t)s[3]) << 0); +} + +static inline uint32_t read_at_be32(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_be32(s); +} + +static inline void write_be32(void *dest, uint32_t val) +{ + write_be16(dest, val >> 16); + write_at_be16(dest, val >> 0, sizeof(uint16_t)); +} + +static inline void write_at_be32(void *dest, uint32_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_be32(d, val); +} + +static inline uint64_t read_be64(const void *src) +{ + uint64_t val; + val = read_be32(src); + val <<= 32; + val |= read_at_be32(src, sizeof(uint32_t)); + return val; +} + +static inline uint64_t read_at_be64(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_be64(s); +} + +static inline void write_be64(void *dest, uint64_t val) +{ + write_be32(dest, val >> 32); + write_at_be32(dest, val >> 0, sizeof(uint32_t)); +} + +static inline void write_at_be64(void *dest, uint64_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_be64(d, val); +} + +/* Little Endian functions. */ + +static inline uint8_t read_le8(const void *src) +{ + return read_ble8(src); +} + +static inline uint8_t read_at_le8(const void *src, size_t offset) +{ + return read_at_ble8(src, offset); +} + +static inline void write_le8(void *dest, uint8_t val) +{ + write_ble8(dest, val); +} + +static inline void write_at_le8(void *dest, uint8_t val, size_t offset) +{ + write_at_ble8(dest, val, offset); +} + +static inline uint16_t read_le16(const void *src) +{ + const uint8_t *s = src; + return (((uint16_t)s[1]) << 8) | (((uint16_t)s[0]) << 0); +} + +static inline uint16_t read_at_le16(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_le16(s); +} + +static inline void write_le16(void *dest, uint16_t val) +{ + write_le8(dest, val >> 0); + write_at_le8(dest, val >> 8, sizeof(uint8_t)); +} + +static inline void write_at_le16(void *dest, uint16_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_le16(d, val); +} + +static inline uint32_t read_le32(const void *src) +{ + const uint8_t *s = src; + return (((uint32_t)s[3]) << 24) | (((uint32_t)s[2]) << 16) | + (((uint32_t)s[1]) << 8) | (((uint32_t)s[0]) << 0); +} + +static inline uint32_t read_at_le32(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_le32(s); +} + +static inline void write_le32(void *dest, uint32_t val) +{ + write_le16(dest, val >> 0); + write_at_le16(dest, val >> 16, sizeof(uint16_t)); +} + +static inline void write_at_le32(void *dest, uint32_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_le32(d, val); +} + +static inline uint64_t read_le64(const void *src) +{ + uint64_t val; + val = read_at_le32(src, sizeof(uint32_t)); + val <<= 32; + val |= read_le32(src); + return val; +} + +static inline uint64_t read_at_le64(const void *src, size_t offset) +{ + const uint8_t *s = src; + s += offset; + return read_le64(s); +} + +static inline void write_le64(void *dest, uint64_t val) +{ + write_le32(dest, val >> 0); + write_at_le32(dest, val >> 32, sizeof(uint32_t)); +} + +static inline void write_at_le64(void *dest, uint64_t val, size_t offset) +{ + uint8_t *d = dest; + d += offset; + write_le64(d, val); +} + +static inline void zero_n(void *dest, size_t n) +{ + memset(dest, 0, n); +} + +#endif diff --git a/util/commonlib/include/commonlib/fmap_serialized.h b/util/commonlib/include/commonlib/fmap_serialized.h new file mode 100644 index 0000000..cea231b --- /dev/null +++ b/util/commonlib/include/commonlib/fmap_serialized.h @@ -0,0 +1,74 @@ +/* + * Copyright 2010, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#ifndef FLASHMAP_SERIALIZED_H__ +#define FLASHMAP_SERIALIZED_H__ + +#include +#include + +#define FMAP_SIGNATURE "__FMAP__" +#define FMAP_VER_MAJOR 1 /* this header's FMAP minor version */ +#define FMAP_VER_MINOR 1 /* this header's FMAP minor version */ +#define FMAP_STRLEN 32 /* maximum length for strings, */ + /* including null-terminator */ + +enum fmap_flags { + FMAP_AREA_STATIC = 1 << 0, + FMAP_AREA_COMPRESSED = 1 << 1, + FMAP_AREA_RO = 1 << 2, +}; + +/* Mapping of volatile and static regions in firmware binary */ +struct fmap_area { + uint32_t offset; /* offset relative to base */ + uint32_t size; /* size in bytes */ + uint8_t name[FMAP_STRLEN]; /* descriptive name */ + uint16_t flags; /* flags for this area */ +} __packed; + +struct fmap { + uint8_t signature[8]; /* "__FMAP__" (0x5F5F464D41505F5F) */ + uint8_t ver_major; /* major version */ + uint8_t ver_minor; /* minor version */ + uint64_t base; /* address of the firmware binary */ + uint32_t size; /* size of firmware binary in bytes */ + uint8_t name[FMAP_STRLEN]; /* name of this firmware binary */ + uint16_t nareas; /* number of areas described by + fmap_areas[] below */ + struct fmap_area areas[]; +} __packed; + +#endif /* FLASHMAP_SERIALIZED_H__ */ diff --git a/util/commonlib/include/commonlib/fsp.h b/util/commonlib/include/commonlib/fsp.h new file mode 100644 index 0000000..a2a2fae --- /dev/null +++ b/util/commonlib/include/commonlib/fsp.h @@ -0,0 +1,32 @@ +/* + * 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. + * + * 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_FSP_H_ +#define _COMMONLIB_FSP_H_ + +#include +#include +#include + +/* + * Relocate FSP held within buffer defined by size to new_addr. Returns < 0 + * on error, offset to FSP_INFO_HEADER on success. + */ +ssize_t fsp_component_relocate(uintptr_t new_addr, void *fsp, size_t size); + +/* API to relocate fsp 1.1 component. */ +ssize_t fsp1_1_relocate(uintptr_t new_addr, void *fsp, size_t size); + +#endif diff --git a/util/commonlib/include/commonlib/helpers.h b/util/commonlib/include/commonlib/helpers.h new file mode 100644 index 0000000..f2acedc --- /dev/null +++ b/util/commonlib/include/commonlib/helpers.h @@ -0,0 +1,99 @@ +/* + * 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_HELPERS_H +#define COMMONLIB_HELPERS_H +/* This file is for helpers for both coreboot firmware and its utilities. */ + +#ifndef __ASSEMBLER__ +#include +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1UL) +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) +#define ALIGN_UP(x, a) ALIGN((x), (a)) +#define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) +#define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (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)) +/* + * 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)); \ +} \ +) + +/* Standard units. */ +#define KiB (1<<10) +#define MiB (1<<20) +#define GiB (1<<30) +/* Could we ever run into this one? I hope we get this much memory! */ +#define TiB (1<<40) + +#define KHz (1000) +#define MHz (1000 * KHz) +#define GHz (1000 * MHz) + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#if !defined(__clang__) +#define check_member(structure, member, offset) _Static_assert( \ + offsetof(struct structure, member) == offset, \ + "`struct " #structure "` offset for `" #member "` is not " #offset) +#else +#define check_member(structure, member, offset) +#endif + +/** + * container_of - cast a member of a structure out to the containing structure + * @param ptr: the pointer to the member. + * @param type: the type of the container struct this is embedded in. + * @param member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const __typeof__(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) + +/* Calculate size of structure member. */ +#define member_size(type, member) (sizeof(((type *)0)->member)) + +#ifndef __unused +#define __unused __attribute__((unused)) +#endif + +#endif /* COMMONLIB_HELPERS_H */ diff --git a/util/commonlib/include/commonlib/iobuf.h b/util/commonlib/include/commonlib/iobuf.h new file mode 100644 index 0000000..c5a0f4c --- /dev/null +++ b/util/commonlib/include/commonlib/iobuf.h @@ -0,0 +1,162 @@ +/* + * 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. + * + * 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_IOBUF_H +#define COMMONLIB_IOBUF_H + +#include +#include + +/* + * Two types are provided to aid in dealing with automatic buffer management + * for code that deals with serializing and deserializing data structures. + * The ibuf (input buffer) is read from while the obuf (output buffer) is + * written to. Both keep track of capacity of the buffer as well as current + * read or write cursor. + * + * When splicing or splitting ibufs of obufs the source object doesn't track + * reads or writes through the newly created objects back to the source object. + * + * Any function returning an int encodes the return values as < 0 on error + * and 0 on success. Any function returning a pointer returns NULL on error + * and non-NULL on success. + */ + +struct ibuf { + const uint8_t *b; + size_t n_read; + size_t capacity; +}; + +struct obuf { + uint8_t *b; + size_t n_written; + size_t capacity; +}; + +/* Helper functions. */ +static inline size_t ibuf_capacity(const struct ibuf *ib) +{ + return ib->capacity; +} + +static inline size_t ibuf_nr_read(const struct ibuf *ib) +{ + return ib->n_read; +} + +static inline size_t ibuf_remaining(const struct ibuf *ib) +{ + return ibuf_capacity(ib) - ibuf_nr_read(ib); +} + +static inline size_t obuf_capacity(const struct obuf *ob) +{ + return ob->capacity; +} + +static inline size_t obuf_nr_written(const struct obuf *ob) +{ + return ob->n_written; +} + +static inline size_t obuf_remaining(const struct obuf *ob) +{ + return obuf_capacity(ob) - obuf_nr_written(ob); +} + +/* Initialize an ibuf with buffer and size of data. */ +void ibuf_init(struct ibuf *ib, const void *b, size_t sz); + +/* Create a new ibuf based on a subregion of the src ibuf. */ +int ibuf_splice(const struct ibuf *src, struct ibuf *dst, size_t off, + size_t sz); + +/* Same as ibuf_splice(), but start from last read byte offset. */ +int ibuf_splice_current(const struct ibuf *src, struct ibuf *dst, size_t sz); + +/* Split an ibuf into 2 new ibufs at provided boundary. */ +int ibuf_split(const struct ibuf *src, struct ibuf *a, struct ibuf *b, + size_t boundary); + +/* Out-of-band drain of ibuf by returning pointer to data of specified size. */ +const void *ibuf_oob_drain(struct ibuf *ib, size_t sz); + +/* Read arbitray data from input buffer. */ +int ibuf_read(struct ibuf *ib, void *data, size_t sz); + +/* Read big endian fixed size values. */ +int ibuf_read_be8(struct ibuf *ib, uint8_t *v); +int ibuf_read_be16(struct ibuf *ib, uint16_t *v); +int ibuf_read_be32(struct ibuf *ib, uint32_t *v); +int ibuf_read_be64(struct ibuf *ib, uint64_t *v); + +/* Read little endian fixed size values. */ +int ibuf_read_le8(struct ibuf *ib, uint8_t *v); +int ibuf_read_le16(struct ibuf *ib, uint16_t *v); +int ibuf_read_le32(struct ibuf *ib, uint32_t *v); +int ibuf_read_le64(struct ibuf *ib, uint64_t *v); + +/* Read native endian fixed size values. */ +int ibuf_read_n8(struct ibuf *ib, uint8_t *v); +int ibuf_read_n16(struct ibuf *ib, uint16_t *v); +int ibuf_read_n32(struct ibuf *ib, uint32_t *v); +int ibuf_read_n64(struct ibuf *ib, uint64_t *v); + +/* Helper to create an ibuf from an obuf after an entity has written data. */ +void ibuf_from_obuf(struct ibuf *ib, const struct obuf *ob); + +/* Initialize an obuf with buffer and maximum capacity. */ +void obuf_init(struct obuf *ob, void *b, size_t sz); + +/* Provide the buffer and size of the written contents. */ +const void *obuf_contents(const struct obuf *ob, size_t *sz); + +/* Create a new obuf based on a subregion of the src obuf. */ +int obuf_splice(const struct obuf *src, struct obuf *dst, size_t off, + size_t sz); + +/* Same as obuf_splice(), but start from last written byte offset. */ +int obuf_splice_current(const struct obuf *src, struct obuf *dst, size_t sz); + +/* Split an obuf into 2 new obufs at provided boundary. */ +int obuf_split(const struct obuf *src, struct obuf *a, struct obuf *b, + size_t boundary); + +/* Fill the buffer out-of-band. The size is accounted for. */ +void *obuf_oob_fill(struct obuf *ob, size_t sz); + +/* Write arbitray data to output buffer. */ +int obuf_write(struct obuf *ob, const void *data, size_t sz); + +/* Write big endian fixed size values. */ +int obuf_write_be8(struct obuf *ob, uint8_t v); +int obuf_write_be16(struct obuf *ob, uint16_t v); +int obuf_write_be32(struct obuf *ob, uint32_t v); +int obuf_write_be64(struct obuf *ob, uint64_t v); + +/* Write little endian fixed size values. */ +int obuf_write_le8(struct obuf *ob, uint8_t v); +int obuf_write_le16(struct obuf *ob, uint16_t v); +int obuf_write_le32(struct obuf *ob, uint32_t v); +int obuf_write_le64(struct obuf *ob, uint64_t v); + +/* Write native endian fixed size values. */ +int obuf_write_n8(struct obuf *ob, uint8_t v); +int obuf_write_n16(struct obuf *ob, uint16_t v); +int obuf_write_n32(struct obuf *ob, uint32_t v); +int obuf_write_n64(struct obuf *ob, uint64_t v); + +#endif diff --git a/util/commonlib/include/commonlib/loglevel.h b/util/commonlib/include/commonlib/loglevel.h new file mode 100644 index 0000000..4247532 --- /dev/null +++ b/util/commonlib/include/commonlib/loglevel.h @@ -0,0 +1,174 @@ +/* + * 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 + * (at your option) any later version. + * + * 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 LOGLEVEL_H +#define LOGLEVEL_H + +/** + * @file loglevel.h + * + * \brief Definitions of the log levels to be used in printk calls. + * + * Safe for inclusion in assembly. + * + */ + +/** + * \brief BIOS_EMERG - Emergency / Fatal + * + * Log level for when the system is entirely unusable. To be used when execution + * is halting as a result of the failure. No further instructions should run. + * + * Example - End of all debug output / death notice. + * + * @{ + */ +#define BIOS_EMERG 0 +/** @} */ + +/** + * \brief BIOS_ALERT - Dying / Unrecoverable + * + * Log level for when the system is certainly in the process of dying. + * To be used when execution will eventually halt as a result of the + * failure, but the system can still output valuable debugging + * information. + * + * Example - Ram initialization fails, dumping relevant POST codes and + * information + * + * @{ + */ +#define BIOS_ALERT 1 +/** @} */ + +/** + * \brief BIOS_CRIT - Recovery unlikely + * + * Log level for when the system has experienced a dire issue in essential + * components. To be used when boot will probably be unsuccessful as a + * result of the failure, but recovery/retry can be attempted. + * + * Example - MSR failures, SMM/SMI failures. + * or + * + * @{ + */ +#define BIOS_CRIT 2 +/** @} */ + +/** + * \brief BIOS_ERR - System in incomplete state. + * + * Log level for when the system has experienced an issue that may not preclude + * a successful boot. To be used when coreboot execution may still succeed, + * but the error places some non-essential portion of the machine in a broken + * state that will be noticed downstream. + * + * Example - Payload could still load, but will be missing access to integral + * components such as drives. + * + * @{ + */ +#define BIOS_ERR 3 +/** @} */ + +/** + * \brief BIOS_WARNING - Bad configuration + * + * Log level for when the system has noticed an issue that most likely will + * not preclude a successful boot. To be used when something is wrong, and + * would likely be noticed by an end user. + * + * Example - Bad ME firmware, bad microcode, mis-clocked CPU + * + * @{ + */ +#define BIOS_WARNING 4 +/** @} */ + +/** + * \brief BIOS_NOTICE - Unexpected but relatively insignificant + * + * Log level for when the system has noticed an issue that is an edge case, + * but is handled and is recoverable. To be used when an end-user would likely + * not notice. + * + * Example - Hardware was misconfigured, but is promptly fixed. + * + * @{ + */ +#define BIOS_NOTICE 5 +/** @} */ + +/** + * \brief BIOS_INFO - Expected events. + * + * Log level for when the system has experienced some typical event. + * Messages should be superficial in nature. + * + * Example - Success messages. Status messages. + * + * @{ + */ +#define BIOS_INFO 6 +/** @} */ + +/** + * \brief BIOS_DEBUG - Verbose output + * + * Log level for details of a method. Messages may be dense, + * but should not be excessive. Messages should be detailed enough + * that this level provides sufficient details to diagnose a problem, + * but not necessarily enough to fix it. + * + * Example - Printing of important variables. + * + * @{ + */ +#define BIOS_DEBUG 7 +/** @} */ + +/** + * \brief BIOS_SPEW - Excessively verbose output + * + * Log level for intricacies of a method. Messages might contain raw + * data and will produce large logs. Developers should try to make sure + * that this level is not useful to anyone besides developers. + * + * Example - Data dumps. + * + * @{ + */ +#define BIOS_SPEW 8 +/** @} */ + +/** + * \brief BIOS_NEVER - Muted log level. + * + * Roughly equal to commenting out a printk statement. Because a user + * should not set their log level higher than 8, these statements + * are never printed. + * + * Example - A developer might locally define MY_LOGLEVEL to BIOS_SPEW, + * and later replace it with BIOS_NEVER as to mute their debug output. + * + * @{ + */ +#define BIOS_NEVER 9 +/** @} */ + +#endif /* LOGLEVEL_H */ diff --git a/util/commonlib/include/commonlib/mem_pool.h b/util/commonlib/include/commonlib/mem_pool.h new file mode 100644 index 0000000..c21fa0e --- /dev/null +++ b/util/commonlib/include/commonlib/mem_pool.h @@ -0,0 +1,69 @@ +/* + * 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. + * + * 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 _MEM_POOL_H_ +#define _MEM_POOL_H_ + +#include +#include + +/* + * The memory pool allows one to allocate memory from a fixed size buffer + * that also allows freeing semantics for reuse. However, the current + * limitation is that the most recent allocation is the only one that + * can be freed. If one tries to free any allocation that isn't the + * most recently allocated it will result in a leak within the memory pool. + * + * The memory returned by allocations are at least 8 byte aligned. Note + * that this requires the backing buffer to start on at least an 8 byte + * alignment. + */ + +struct mem_pool { + uint8_t *buf; + size_t size; + uint8_t *last_alloc; + size_t free_offset; +}; + +#define MEM_POOL_INIT(buf_, size_) \ + { \ + .buf = (buf_), \ + .size = (size_), \ + .last_alloc = NULL, \ + .free_offset = 0, \ + } + +static inline void mem_pool_reset(struct mem_pool *mp) +{ + mp->last_alloc = NULL; + mp->free_offset = 0; +} + +/* Initialize a memory pool. */ +static inline void mem_pool_init(struct mem_pool *mp, void *buf, size_t sz) +{ + mp->buf = buf; + mp->size = sz; + mem_pool_reset(mp); +} + +/* Allocate requested size from the memory pool. NULL returned on error. */ +void *mem_pool_alloc(struct mem_pool *mp, size_t sz); + +/* Free allocation from memory pool. */ +void mem_pool_free(struct mem_pool *mp, void *alloc); + +#endif /* _MEM_POOL_H_ */ diff --git a/util/commonlib/include/commonlib/region.h b/util/commonlib/include/commonlib/region.h new file mode 100644 index 0000000..45484dd --- /dev/null +++ b/util/commonlib/include/commonlib/region.h @@ -0,0 +1,274 @@ +/* + * 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. + * + * 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 _REGION_H_ +#define _REGION_H_ + +#include +#include +#include +#include + +/* + * Region support. + * + * Regions are intended to abstract away the access mechanisms for blocks of + * data. This could be SPI, eMMC, or a memory region as the backing store. + * They are accessed through a region_device. Subregions can be made by + * chaining together multiple region_devices. + */ + +struct region_device; + +/* + * Returns NULL on error otherwise a buffer is returned with the conents of + * the requested data at offset of size. + */ +void *rdev_mmap(const struct region_device *rd, size_t offset, size_t size); + +/* Unmap a previously mapped area. Returns 0 on success, < 0 on error. */ +int rdev_munmap(const struct region_device *rd, void *mapping); + +/* + * Returns < 0 on error otherwise returns size of data read at provided + * offset filling in the buffer passed. + */ +ssize_t rdev_readat(const struct region_device *rd, void *b, size_t offset, + size_t size); + +/* + * Returns < 0 on error otherwise returns size of data wrote at provided + * offset from the buffer passed. + */ +ssize_t rdev_writeat(const struct region_device *rd, const void *b, + size_t offset, size_t size); + +/* + * Returns < 0 on error otherwise returns size of data erased. + * If eraseat ops is not defined it returns size which indicates + * that operation was successful. + */ +ssize_t rdev_eraseat(const struct region_device *rd, size_t offset, + size_t size); + +/**************************************** + * Implementation of a region device * + ****************************************/ + +/* + * Create a child region of the parent provided the sub-region is within + * the parent's region. Returns < 0 on error otherwise 0 on success. Note + * that the child device only calls through the parent's operations. + */ +int rdev_chain(struct region_device *child, const struct region_device *parent, + size_t offset, size_t size); + + +/* A region_device operations. */ +struct region_device_ops { + void *(*mmap)(const struct region_device *, size_t, size_t); + int (*munmap)(const struct region_device *, void *); + ssize_t (*readat)(const struct region_device *, void *, size_t, size_t); + ssize_t (*writeat)(const struct region_device *, const void *, size_t, + size_t); + ssize_t (*eraseat)(const struct region_device *, size_t, size_t); +}; + +struct region { + size_t offset; + size_t size; +}; + +struct region_device { + const struct region_device *root; + const struct region_device_ops *ops; + struct region region; +}; + +#define REGION_DEV_INIT(ops_, offset_, size_) \ + { \ + .root = NULL, \ + .ops = (ops_), \ + .region = { \ + .offset = (offset_), \ + .size = (size_), \ + }, \ + } + +/* Helper to dynamically initialize region device. */ +void region_device_init(struct region_device *rdev, + const struct region_device_ops *ops, size_t offset, + size_t size); + +/* Return 1 if child is subregion of parent, else 0. */ +int region_is_subregion(const struct region *p, const struct region *c); + +static inline size_t region_offset(const struct region *r) +{ + return r->offset; +} + +static inline size_t region_sz(const struct region *r) +{ + return r->size; +} + +static inline const struct region *region_device_region( + const struct region_device *rdev) +{ + return &rdev->region; +} + +static inline size_t region_device_sz(const struct region_device *rdev) +{ + return region_sz(region_device_region(rdev)); +} + +static inline size_t region_device_offset(const struct region_device *rdev) +{ + return region_offset(region_device_region(rdev)); +} + +/* Memory map entire region device. Same semantics as rdev_mmap() above. */ +static inline void *rdev_mmap_full(const struct region_device *rd) +{ + return rdev_mmap(rd, 0, region_device_sz(rd)); +} + +/* + * Compute relative offset of the child (c) w.r.t. the parent (p). Returns < 0 + * when child is not within the parent's region. + */ +ssize_t rdev_relative_offset(const struct region_device *p, + const struct region_device *c); + +struct mem_region_device { + char *base; + struct region_device rdev; +}; + +/* Inititalize at runtime a mem_region_device. This would be used when + * the base and size are dynamic or can't be known during linking. + * There are two variants: read-only and read-write. */ +void mem_region_device_ro_init(struct mem_region_device *mdev, void *base, + size_t size); + +void mem_region_device_rw_init(struct mem_region_device *mdev, void *base, + size_t size); + +extern const struct region_device_ops mem_rdev_ro_ops; + +extern const struct region_device_ops mem_rdev_rw_ops; + +/* Statically initialize mem_region_device. */ +#define MEM_REGION_DEV_INIT(base_, size_, ops_) \ + { \ + .base = (void *)(base_), \ + .rdev = REGION_DEV_INIT((ops_), 0, (size_)), \ + } + +#define MEM_REGION_DEV_RO_INIT(base_, size_) \ + MEM_REGION_DEV_INIT(base_, size_, &mem_rdev_ro_ops) \ + +#define MEM_REGION_DEV_RW_INIT(base_, size_) \ + MEM_REGION_DEV_INIT(base_, size_, &mem_rdev_rw_ops) \ + +struct mmap_helper_region_device { + struct mem_pool pool; + struct region_device rdev; +}; + +#define MMAP_HELPER_REGION_INIT(ops_, offset_, size_) \ + { \ + .rdev = REGION_DEV_INIT((ops_), (offset_), (size_)), \ + } + +void mmap_helper_device_init(struct mmap_helper_region_device *mdev, + void *cache, size_t cache_size); + +void *mmap_helper_rdev_mmap(const struct region_device *, size_t, size_t); +int mmap_helper_rdev_munmap(const struct region_device *, void *); + +/* A translated region device provides the ability to publish a region device + * in one address space and use an access mechanism within another address + * space. The sub region is the window within the 1st address space and + * the request is modified prior to accessing the second address space + * provided by access_dev. */ +struct xlate_region_device { + const struct region_device *access_dev; + struct region sub_region; + struct region_device rdev; +}; + +extern const struct region_device_ops xlate_rdev_ro_ops; + +extern const struct region_device_ops xlate_rdev_rw_ops; + +#define XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, sub_size_, \ + parent_sz_, ops_) \ + { \ + .access_dev = access_dev_, \ + .sub_region = { \ + .offset = (sub_offset_), \ + .size = (sub_size_), \ + }, \ + .rdev = REGION_DEV_INIT((ops_), 0, (parent_sz_)), \ + } + +#define XLATE_REGION_DEV_RO_INIT(access_dev_, sub_offset_, sub_size_, \ + parent_sz_) \ + XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \ + sub_size_, parent_sz_, &xlate_rdev_ro_ops), \ + +#define XLATE_REGION_DEV_RW_INIT(access_dev_, sub_offset_, sub_size_, \ + parent_sz_) \ + XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \ + sub_size_, parent_sz_, &xlate_rdev_rw_ops), \ + +/* Helper to dynamically initialize xlate region device. */ +void xlate_region_device_ro_init(struct xlate_region_device *xdev, + const struct region_device *access_dev, + size_t sub_offset, size_t sub_size, + size_t parent_size); + +void xlate_region_device_rw_init(struct xlate_region_device *xdev, + const struct region_device *access_dev, + size_t sub_offset, size_t sub_size, + size_t parent_size); + +/* This type can be used for incoherent access where the read and write + * operations are backed by separate drivers. An example is x86 systems + * with memory mapped media for reading but use a spi flash driver for + * writing. One needs to ensure using this object is appropriate in context. */ +struct incoherent_rdev { + struct region_device rdev; + const struct region_device *read; + const struct region_device *write; +}; + +/* Initialize an incoherent_rdev based on the region as well as the read and + * write rdevs. The read and write rdevs should match in size to the passed + * in region. If not the initialization will fail returning NULL. Otherwise + * the function will return a pointer to the containing region_device to + * be used for region operations. Therefore, the lifetime of the returned + * pointer matches the lifetime of the incoherent_rdev object. Likewise, + * the lifetime of the read and write rdev need to match the lifetime of + * the incoherent_rdev object. */ +const struct region_device *incoherent_rdev_init(struct incoherent_rdev *irdev, + const struct region *r, + const struct region_device *read, + const struct region_device *write); + +#endif /* _REGION_H_ */ diff --git a/util/commonlib/include/commonlib/rmodule-defs.h b/util/commonlib/include/commonlib/rmodule-defs.h new file mode 100644 index 0000000..485d638 --- /dev/null +++ b/util/commonlib/include/commonlib/rmodule-defs.h @@ -0,0 +1,60 @@ +/* + * 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. + * + * 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 RMODULE_DEFS_H +#define RMODULE_DEFS_H + +#include +#include +#include + +#define RMODULE_MAGIC 0xf8fe +#define RMODULE_VERSION_1 1 + +/* All fields with '_offset' in the name are byte offsets into the flat blob. + * The linker and the linker script takes are of assigning the values. */ +struct rmodule_header { + uint16_t magic; + uint8_t version; + uint8_t type; + /* The payload represents the program's loadable code and data. */ + uint32_t payload_begin_offset; + uint32_t payload_end_offset; + /* Begin and of relocation information about the program module. */ + uint32_t relocations_begin_offset; + uint32_t relocations_end_offset; + /* The starting address of the linked program. This address is vital + * for determining relocation offsets as the relocation info and other + * symbols (bss, entry point) need this value as a basis to calculate + * the offsets. + */ + uint32_t module_link_start_address; + /* The module_program_size is the size of memory used while running + * the program. The program is assumed to consume a contiguous amount + * of memory. */ + uint32_t module_program_size; + /* This is program's execution entry point. */ + uint32_t module_entry_point; + /* Optional parameter structure that can be used to pass data into + * the module. */ + uint32_t parameters_begin; + uint32_t parameters_end; + /* BSS section information so the loader can clear the bss. */ + uint32_t bss_begin; + uint32_t bss_end; + /* Add some room for growth. */ + uint32_t padding[4]; +} __packed; + +#endif /* RMODULE_DEFS_H */ diff --git a/util/commonlib/include/commonlib/sd_mmc_ctrlr.h b/util/commonlib/include/commonlib/sd_mmc_ctrlr.h new file mode 100644 index 0000000..247c0a5 --- /dev/null +++ b/util/commonlib/include/commonlib/sd_mmc_ctrlr.h @@ -0,0 +1,228 @@ +/* + * Copyright 2011, Marvell Semiconductor Inc. + * Lei Wen + * + * Copyright 2017 Intel Corporation + * + * Controller independent definitions + * + * 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 (at your option) any later version. + * + * 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_SD_MMC_CTRLR_H__ +#define __COMMONLIB_SD_MMC_CTRLR_H__ + +#include + +/* Error values returned by the storage drivers */ +#define CARD_UNUSABLE_ERR -17 /* Unusable Card */ +#define CARD_COMM_ERR -18 /* Communications Error */ +#define CARD_TIMEOUT -19 +#define CARD_IN_PROGRESS -20 /* operation is in progress */ + +struct mmc_command { + uint16_t cmdidx; + +/* Common commands */ +#define MMC_CMD_GO_IDLE_STATE 0 +#define MMC_CMD_SEND_OP_COND 1 +#define MMC_CMD_ALL_SEND_CID 2 +#define MMC_CMD_SET_DSR 4 +#define MMC_CMD_SELECT_CARD 7 +#define MMC_CMD_SEND_CSD 9 +#define MMC_CMD_SEND_CID 10 +#define MMC_CMD_STOP_TRANSMISSION 12 +#define MMC_CMD_SEND_STATUS 13 +#define MMC_CMD_SET_BLOCKLEN 16 +#define MMC_CMD_READ_SINGLE_BLOCK 17 +#define MMC_CMD_READ_MULTIPLE_BLOCK 18 +#define MMC_CMD_WRITE_SINGLE_BLOCK 24 +#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25 +#define MMC_CMD_APP_CMD 55 + +/* MMC specific commands */ +#define MMC_CMD_SET_RELATIVE_ADDR 3 +#define MMC_CMD_SWITCH 6 +#define MMC_CMD_SEND_EXT_CSD 8 +#define MMC_CMD_AUTO_TUNING_SEQUENCE 21 +#define MMC_CMD_ERASE_GROUP_START 35 +#define MMC_CMD_ERASE_GROUP_END 36 +#define MMC_CMD_ERASE 38 +#define MMC_CMD_SPI_READ_OCR 58 +#define MMC_CMD_SPI_CRC_ON_OFF 59 + +/* SD specific commands */ +#define SD_CMD_SEND_RELATIVE_ADDR 3 +#define SD_CMD_SWITCH_FUNC 6 +#define SD_CMD_SEND_IF_COND 8 +#define SD_CMD_ERASE_WR_BLK_START 32 +#define SD_CMD_ERASE_WR_BLK_END 33 + +/* SD specific APP commands */ +#define SD_CMD_APP_SET_BUS_WIDTH 6 +#define SD_CMD_APP_SEND_OP_COND 41 +#define SD_CMD_APP_SEND_SCR 51 + + uint32_t resp_type; + +#define CARD_RSP_PRESENT (1 << 0) +#define CARD_RSP_136 (1 << 1) /* 136 bit response */ +#define CARD_RSP_CRC (1 << 2) /* expect valid crc */ +#define CARD_RSP_BUSY (1 << 3) /* card may send busy */ +#define CARD_RSP_OPCODE (1 << 4) /* response contains opcode */ + +#define CARD_RSP_NONE (0) +#define CARD_RSP_R1 (CARD_RSP_PRESENT|CARD_RSP_CRC|CARD_RSP_OPCODE) +#define CARD_RSP_R1b (CARD_RSP_PRESENT|CARD_RSP_CRC|CARD_RSP_OPCODE| \ + CARD_RSP_BUSY) +#define CARD_RSP_R2 (CARD_RSP_PRESENT|CARD_RSP_136|CARD_RSP_CRC) +#define CARD_RSP_R3 (CARD_RSP_PRESENT) +#define CARD_RSP_R4 (CARD_RSP_PRESENT) +#define CARD_RSP_R5 (CARD_RSP_PRESENT|CARD_RSP_CRC|CARD_RSP_OPCODE) +#define CARD_RSP_R6 (CARD_RSP_PRESENT|CARD_RSP_CRC|CARD_RSP_OPCODE) +#define CARD_RSP_R7 (CARD_RSP_PRESENT|CARD_RSP_CRC|CARD_RSP_OPCODE) + + uint32_t cmdarg; + +#define MMC_TRIM_ARG 0x1 +#define MMC_SECURE_ERASE_ARG 0x80000000 + + uint32_t response[4]; + uint32_t flags; + +#define CMD_FLAG_IGNORE_INHIBIT 1 +}; + +#define SD_SWITCH_CHECK 0 +#define SD_SWITCH_SWITCH 1 + +#define SD_DATA_4BIT 0x00040000 + +/* SCR definitions in different words */ +#define SD_HIGHSPEED_BUSY 0x00020000 +#define SD_HIGHSPEED_SUPPORTED 0x00020000 + +struct mmc_data { + union { + char *dest; + const char *src; + }; + uint32_t flags; + +#define DATA_FLAG_READ 1 +#define DATA_FLAG_WRITE 2 + + uint32_t blocks; + uint32_t blocksize; +}; + +struct sd_mmc_ctrlr { + int (*send_cmd)(struct sd_mmc_ctrlr *ctrlr, + struct mmc_command *cmd, struct mmc_data *data); + void (*set_ios)(struct sd_mmc_ctrlr *ctrlr); + void (*tuning_start)(struct sd_mmc_ctrlr *ctrlr, int retune); + int (*is_tuning_complete)(struct sd_mmc_ctrlr *ctrlr, int *successful); + + int initialized; + unsigned int version; + uint32_t voltages; + +#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ +#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ +#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ +#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ +#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ +#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ +#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ +#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ +#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ +#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ +#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ +#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ +#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ +#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ +#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ +#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ +#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ + +#define MMC_VDD_165_195_SHIFT 7 + + uint32_t clock_base; /* Controller's base clock */ + uint32_t f_min; + uint32_t f_max; + uint32_t request_hz; /* Desired clock frequency */ + uint32_t bus_hz; /* Actual bus clock frequency */ + +#define CLOCK_KHZ 1000 +#define CLOCK_MHZ (1000 * CLOCK_KHZ) +#define CLOCK_20MHZ (20 * CLOCK_MHZ) +#define CLOCK_25MHZ (25 * CLOCK_MHZ) +#define CLOCK_26MHZ (26 * CLOCK_MHZ) +#define CLOCK_50MHZ (50 * CLOCK_MHZ) +#define CLOCK_52MHZ (52 * CLOCK_MHZ) +#define CLOCK_200MHZ (200 * CLOCK_MHZ) + + uint32_t bus_width; + uint32_t caps; + +/* Generic controller & driver capabilities. Controller specific capabilities + * start at 0x00010000 + */ +#define DRVR_CAP_4BIT 0x00000001 +#define DRVR_CAP_8BIT 0x00000002 +#define DRVR_CAP_AUTO_CMD12 0x00000004 +#define DRVR_CAP_HC 0x00000008 +#define DRVR_CAP_HS 0x00000010 +#define DRVR_CAP_HS52 0x00000020 +#define DRVR_CAP_HS200 0x00000040 +#define DRVR_CAP_HS400 0x00000080 +#define DRVR_CAP_ENHANCED_STROBE 0x00000100 +#define DRVR_CAP_REMOVABLE 0x00000200 +#define DRVR_CAP_DMA_64BIT 0x00000400 +#define DRVR_CAP_HS200_TUNING 0x00000800 + + uint32_t b_max; + uint32_t timing; + +#define BUS_TIMING_LEGACY 0 +#define BUS_TIMING_MMC_HS 1 +#define BUS_TIMING_SD_HS 2 +#define BUS_TIMING_UHS_SDR12 3 +#define BUS_TIMING_UHS_SDR25 4 +#define BUS_TIMING_UHS_SDR50 5 +#define BUS_TIMING_UHS_SDR104 6 +#define BUS_TIMING_UHS_DDR50 7 +#define BUS_TIMING_MMC_DDR52 8 +#define BUS_TIMING_MMC_HS200 9 +#define BUS_TIMING_MMC_HS400 10 +#define BUS_TIMING_MMC_HS400ES 11 + + uint32_t mdelay_before_cmd0; + uint32_t mdelay_after_cmd0; + uint32_t udelay_wait_after_cmd; +}; + +/* SOC specific routine to override ctrlr->caps and .voltages + * + * Set/clear the necessary DRVR_CAP_xxx bits in ctrlr->caps to specify the + * controllers capabilities and driver workarounds. + * + * Set/clear the necessary MMC_VDD_xxx bits in ctrlr->voltages to specify the + * controllers power support. + */ +void soc_sd_mmc_controller_quirks(struct sd_mmc_ctrlr *ctrlr); + +/* Optional routines to support logging */ +void sdhc_log_command(struct mmc_command *cmd); +void sdhc_log_command_issued(void); +void sdhc_log_response(uint32_t entries, uint32_t *response); +void sdhc_log_ret(int ret); + +#endif /* __COMMONLIB_SD_MMC_CTRLR_H__ */ diff --git a/util/commonlib/include/commonlib/sdhci.h b/util/commonlib/include/commonlib/sdhci.h new file mode 100644 index 0000000..ffeb662 --- /dev/null +++ b/util/commonlib/include/commonlib/sdhci.h @@ -0,0 +1,76 @@ +/* + * Copyright 2011, Marvell Semiconductor Inc. + * Lei Wen + * + * Copyright 2017 Intel Corporation + * + * SD host controller specific definitions + * + * 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 (at your option) any later version. + * + * 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_SDHCI_H__ +#define __COMMONLIB_SDHCI_H__ + +#include + +/* Driver specific capabilities */ +#define DRVR_CAP_1V8_VDD 0x00010000 +#define DRVR_CAP_32BIT_DMA_ADDR 0x00020000 +#define DRVR_CAP_BROKEN_R1B 0x00040000 +#define DRVR_CAP_NO_CD 0x00080000 +#define DRVR_CAP_NO_HISPD_BIT 0x00100000 +#define DRVR_CAP_NO_SIMULT_VDD_AND_POWER 0x00200000 +#define DRVR_CAP_REG32_RW 0x00400000 +#define DRVR_CAP_SPI 0x00800000 +#define DRVR_CAP_WAIT_SEND_CMD 0x01000000 + +/* ADMA packet descriptor */ +struct sdhci_adma { + u16 attributes; + u16 length; + u32 addr; +}; + +struct sdhci_adma64 { + u16 attributes; + u16 length; + u32 addr; + u32 addr_hi; +}; + +struct sdhci_ctrlr { + struct sd_mmc_ctrlr sd_mmc_ctrlr; + void *ioaddr; + uint32_t b_max; + + /* + * Dynamically allocated array of ADMA descriptors to use for data + * transfers + */ + struct sdhci_adma *adma_descs; + struct sdhci_adma64 *adma64_descs; + + /* Number of ADMA descriptors currently in the array. */ + int adma_desc_count; +}; + +int add_sdhci(struct sdhci_ctrlr *sdhci_ctrlr); +int sdhci_controller_init(struct sdhci_ctrlr *sdhci_ctrlr, void *ioaddr); +void sdhci_update_pointers(struct sdhci_ctrlr *sdhci_ctrlr); +void sdhci_display_setup(struct sdhci_ctrlr *sdhci_ctrlr); + +/* Add SDHCI controller from PCI */ +struct sd_mmc_ctrlr *new_pci_sdhci_controller(uint32_t dev); + +/* Add SDHCI controller with memory address */ +struct sd_mmc_ctrlr *new_mem_sdhci_controller(void *ioaddr); + +#endif /* __COMMONLIB_SDHCI_H__ */ diff --git a/util/commonlib/include/commonlib/stdlib.h b/util/commonlib/include/commonlib/stdlib.h new file mode 100644 index 0000000..cfe027f --- /dev/null +++ b/util/commonlib/include/commonlib/stdlib.h @@ -0,0 +1,74 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright 2013 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __COMMONLIB_STDLIB_H__ +#define __COMMONLIB_STDLIB_H__ + +#include +#include +#include + +#if IS_ENABLED(CONFIG_COREBOOT_BUILD) +#include +#include +#define printf(...) printk(BIOS_ERR, __VA_ARGS__) +#define HALT(x) halt() +#else +#include +#define HALT(x) +#endif + +static inline void *xmalloc_work(size_t size, const char *file, + const char *func, int line) +{ + void *ret = malloc(size); + if (!ret && size) { + printf("%s/%s/line %d: Failed to malloc %zu bytes\n", + file, func, line, size); + while (1) + HALT(1); + } + return ret; +} +#define xmalloc(size) xmalloc_work((size), __FILE__, __FUNCTION__, __LINE__) + +static inline void *xzalloc_work(size_t size, const char *file, + const char *func, int line) +{ + void *ret = xmalloc_work(size, file, func, line); + memset(ret, 0, size); + return ret; +} +#define xzalloc(size) xzalloc_work((size), __FILE__, __FUNCTION__, __LINE__) + +void *dma_malloc(size_t size); +int dma_coherent(void *ptr); + +#endif /* __COMMONLIB_STDLIB_H__ */ diff --git a/util/commonlib/include/commonlib/storage.h b/util/commonlib/include/commonlib/storage.h new file mode 100644 index 0000000..6ad53dc --- /dev/null +++ b/util/commonlib/include/commonlib/storage.h @@ -0,0 +1,151 @@ +/* + * Copyright 2008,2010 Freescale Semiconductor, Inc + * Andy Fleming + * + * Copyright 2013 Google Inc. All rights reserved. + * Copyright 2017 Intel Corporation + * + * 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 (at your option) any later version. + * + * 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_STORAGE_H__ +#define __COMMONLIB_STORAGE_H__ + +#include + +/* + * EXT_CSD fields + */ +#define EXT_CSD_GP_SIZE_MULT_GP0 143 /* RO */ +#define EXT_CSD_GP_SIZE_MULT_GP1 146 /* RO */ +#define EXT_CSD_GP_SIZE_MULT_GP2 149 /* RO */ +#define EXT_CSD_GP_SIZE_MULT_GP3 152 /* RO */ +#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ +#define EXT_CSD_RPMB_SIZE_MULT 168 /* RO */ +#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ +#define EXT_CSD_PART_CONF 179 /* R/W */ +#define EXT_CSD_BUS_WIDTH 183 /* R/W */ +#define EXT_CSD_STROBE_SUPPORT 184 /* RO */ +#define EXT_CSD_HS_TIMING 185 /* R/W */ +#define EXT_CSD_REV 192 /* RO */ +#define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ +#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_BOOT_SIZE_MULT 226 /* RO */ +#define EXT_CSD_TRIM_MULT 232 /* RO */ + +/* + * EXT_CSD field definitions + */ + +#define EXT_CSD_CMD_SET_NORMAL (1 << 0) +#define EXT_CSD_CMD_SET_SECURE (1 << 1) +#define EXT_CSD_CMD_SET_CPSECURE (1 << 2) + +#define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */ +#define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */ + +#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ +#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ +#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ +#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ +#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ +#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */ + +#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */ +#define EXT_CSD_TIMING_HS 1 /* High speed */ +#define EXT_CSD_TIMING_HS200 2 /* HS200 */ +#define EXT_CSD_TIMING_HS400 3 /* HS400 */ + +#define EXT_CSD_SIZE 512 + +/* 179: EXT_CSD_PART_CONF */ +#define EXT_CSD_PART_ACCESS_MASK 7 /* Partition access mask */ + +/* 175: EXT_CSD_ERASE_GROUP_DEF */ +#define EXT_CSD_PARTITION_ENABLE 1 /* Enable partition access */ + +struct storage_media { + uint64_t capacity[8]; /* Partition capacity in bytes */ + struct sd_mmc_ctrlr *ctrlr; + +#define MMC_PARTITION_USER 0 +#define MMC_PARTITION_BOOT_1 1 +#define MMC_PARTITION_BOOT_2 2 +#define MMC_PARTITION_RPMB 3 +#define MMC_PARTITION_GP1 4 +#define MMC_PARTITION_GP2 5 +#define MMC_PARTITION_GP3 6 +#define MMC_PARTITION_GP4 7 + + uint32_t caps; + uint32_t version; + +#define SD_VERSION_SD 0x20000 +#define SD_VERSION_2 (SD_VERSION_SD | 0x20) +#define SD_VERSION_1_0 (SD_VERSION_SD | 0x10) +#define SD_VERSION_1_10 (SD_VERSION_SD | 0x1a) +#define MMC_VERSION_MMC 0x10000 +#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC) +#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x12) +#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x14) +#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x22) +#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x30) +#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x40) + + uint32_t read_bl_len; + uint32_t write_bl_len; + int high_capacity; + uint32_t tran_speed; + /* Erase size in terms of block length. */ + uint32_t erase_blocks; + /* Trim operation multiplier for determining timeout. */ + uint32_t trim_mult; + + uint32_t ocr; + +#define OCR_BUSY 0x80000000 +#define OCR_HCS 0x40000000 +#define OCR_VOLTAGE_MASK 0x00FFFF80 +#define OCR_ACCESS_MODE 0x60000000 + + uint32_t op_cond_response; // The response byte from the last op_cond + + uint32_t scr[2]; + uint32_t csd[4]; + uint32_t cid[4]; + uint16_t rca; + + uint8_t partition_config; /* Duplicate of EXT_CSD_PART_CONF */ +}; + +uint64_t storage_block_erase(struct storage_media *media, uint64_t start, + uint64_t count); +uint64_t storage_block_fill_write(struct storage_media *media, uint64_t start, + uint64_t count, uint32_t fill_pattern); +uint64_t storage_block_read(struct storage_media *media, uint64_t start, + uint64_t count, void *buffer); +uint64_t storage_block_write(struct storage_media *media, uint64_t start, + uint64_t count, const void *buffer); + +unsigned int storage_get_current_partition(struct storage_media *media); +const char *storage_partition_name(struct storage_media *media, + unsigned int partition_number); +int storage_setup_media(struct storage_media *media, + struct sd_mmc_ctrlr *ctrlr); + +int storage_set_partition(struct storage_media *media, + unsigned int partition_number); + +void storage_display_setup(struct storage_media *media); + +#endif /* __COMMONLIB_STORAGE_H__ */ diff --git a/util/commonlib/include/commonlib/timestamp_serialized.h b/util/commonlib/include/commonlib/timestamp_serialized.h new file mode 100644 index 0000000..11baf16 --- /dev/null +++ b/util/commonlib/include/commonlib/timestamp_serialized.h @@ -0,0 +1,249 @@ +/* + * 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. + * + * 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 __TIMESTAMP_SERIALIZED_H__ +#define __TIMESTAMP_SERIALIZED_H__ + +#include +#include + +struct timestamp_entry { + uint32_t entry_id; + uint64_t entry_stamp; +} __packed; + +struct timestamp_table { + uint64_t base_time; + uint16_t max_entries; + uint16_t tick_freq_mhz; + uint32_t num_entries; + struct timestamp_entry entries[0]; /* Variable number of entries */ +} __packed; + +enum timestamp_id { + TS_START_ROMSTAGE = 1, + TS_BEFORE_INITRAM = 2, + TS_AFTER_INITRAM = 3, + TS_END_ROMSTAGE = 4, + TS_START_VBOOT = 5, + TS_END_VBOOT = 6, + TS_START_COPYRAM = 8, + TS_END_COPYRAM = 9, + TS_START_RAMSTAGE = 10, + TS_START_BOOTBLOCK = 11, + TS_END_BOOTBLOCK = 12, + TS_START_COPYROM = 13, + TS_END_COPYROM = 14, + TS_START_ULZMA = 15, + TS_END_ULZMA = 16, + TS_START_ULZ4F = 17, + TS_END_ULZ4F = 18, + TS_DEVICE_ENUMERATE = 30, + TS_DEVICE_CONFIGURE = 40, + TS_DEVICE_ENABLE = 50, + TS_DEVICE_INITIALIZE = 60, + TS_OPROM_INITIALIZE = 65, + TS_OPROM_COPY_END = 66, + TS_OPROM_END = 67, + TS_DEVICE_DONE = 70, + TS_CBMEM_POST = 75, + TS_WRITE_TABLES = 80, + TS_FINALIZE_CHIPS = 85, + TS_LOAD_PAYLOAD = 90, + TS_ACPI_WAKE_JUMP = 98, + TS_SELFBOOT_JUMP = 99, + + /* 500+ reserved for vendorcode extensions (500-600: google/chromeos) */ + TS_START_COPYVER = 501, + TS_END_COPYVER = 502, + TS_START_TPMINIT = 503, + TS_END_TPMINIT = 504, + TS_START_VERIFY_SLOT = 505, + TS_END_VERIFY_SLOT = 506, + TS_START_HASH_BODY = 507, + TS_DONE_LOADING = 508, + TS_DONE_HASHING = 509, + TS_END_HASH_BODY = 510, + TS_START_COPYVPD = 550, + TS_END_COPYVPD_RO = 551, + TS_END_COPYVPD_RW = 552, + + /* 900-920 reserved for vendorcode extensions (900-940: AMD AGESA) */ + TS_AGESA_INIT_RESET_START = 900, + TS_AGESA_INIT_RESET_DONE = 901, + TS_AGESA_INIT_EARLY_START = 902, + TS_AGESA_INIT_EARLY_DONE = 903, + TS_AGESA_INIT_POST_START = 904, + TS_AGESA_INIT_POST_DONE = 905, + TS_AGESA_INIT_ENV_START = 906, + TS_AGESA_INIT_ENV_DONE = 907, + TS_AGESA_INIT_MID_START = 908, + TS_AGESA_INIT_MID_DONE = 909, + TS_AGESA_INIT_LATE_START = 910, + TS_AGESA_INIT_LATE_DONE = 911, + TS_AGESA_INIT_RTB_START = 912, + TS_AGESA_INIT_RTB_DONE = 913, + TS_AGESA_INIT_RESUME_START = 914, + TS_AGESA_INIT_RESUME_DONE = 915, + TS_AGESA_S3_LATE_START = 916, + TS_AGESA_S3_LATE_DONE = 917, + TS_AGESA_S3_FINAL_START = 918, + TS_AGESA_S3_FINAL_DONE = 919, + + /* 940-950 reserved for vendorcode extensions (940-950: Intel ME) */ + TS_ME_INFORM_DRAM_WAIT = 940, + TS_ME_INFORM_DRAM_DONE = 941, + + /* 950+ reserved for vendorcode extensions (950-999: intel/fsp) */ + TS_FSP_MEMORY_INIT_START = 950, + TS_FSP_MEMORY_INIT_END = 951, + TS_FSP_TEMP_RAM_EXIT_START = 952, + TS_FSP_TEMP_RAM_EXIT_END = 953, + TS_FSP_SILICON_INIT_START = 954, + TS_FSP_SILICON_INIT_END = 955, + TS_FSP_BEFORE_ENUMERATE = 956, + TS_FSP_AFTER_ENUMERATE = 957, + TS_FSP_BEFORE_FINALIZE = 958, + TS_FSP_AFTER_FINALIZE = 959, + TS_FSP_BEFORE_END_OF_FIRMWARE = 960, + TS_FSP_AFTER_END_OF_FIRMWARE = 961, + + /* 1000+ reserved for payloads (1000-1200: ChromeOS depthcharge) */ + + /* Depthcharge entry IDs start at 1000 */ + TS_DC_START = 1000, + + TS_RO_PARAMS_INIT = 1001, + TS_RO_VB_INIT = 1002, + TS_RO_VB_SELECT_FIRMWARE = 1003, + TS_RO_VB_SELECT_AND_LOAD_KERNEL = 1004, + + TS_RW_VB_SELECT_AND_LOAD_KERNEL = 1010, + + TS_VB_SELECT_AND_LOAD_KERNEL = 1020, + TS_VB_EC_VBOOT_DONE = 1030, + TS_VB_STORAGE_INIT_DONE = 1040, + TS_VB_READ_KERNEL_DONE = 1050, + TS_VB_VBOOT_DONE = 1100, + + TS_START_KERNEL = 1101, + TS_KERNEL_DECOMPRESSION = 1102, +}; + +static const struct timestamp_id_to_name { + uint32_t id; + const char *name; +} timestamp_ids[] = { + /* Marker to report base_time. */ + { 0, "1st timestamp" }, + { TS_START_ROMSTAGE, "start of romstage" }, + { TS_BEFORE_INITRAM, "before ram initialization" }, + { TS_AFTER_INITRAM, "after ram initialization" }, + { TS_END_ROMSTAGE, "end of romstage" }, + { TS_START_VBOOT, "start of verified boot" }, + { TS_END_VBOOT, "end of verified boot" }, + { TS_START_COPYRAM, "starting to load ramstage" }, + { TS_END_COPYRAM, "finished loading ramstage" }, + { TS_START_RAMSTAGE, "start of ramstage" }, + { TS_START_BOOTBLOCK, "start of bootblock" }, + { TS_END_BOOTBLOCK, "end of bootblock" }, + { TS_START_COPYROM, "starting to load romstage" }, + { TS_END_COPYROM, "finished loading romstage" }, + { TS_START_ULZMA, "starting LZMA decompress (ignore for x86)" }, + { TS_END_ULZMA, "finished LZMA decompress (ignore for x86)" }, + { TS_START_ULZ4F, "starting LZ4 decompress (ignore for x86)" }, + { TS_END_ULZ4F, "finished LZ4 decompress (ignore for x86)" }, + { TS_DEVICE_ENUMERATE, "device enumeration" }, + { TS_DEVICE_CONFIGURE, "device configuration" }, + { TS_DEVICE_ENABLE, "device enable" }, + { TS_DEVICE_INITIALIZE, "device initialization" }, + { TS_OPROM_INITIALIZE, "Option ROM initialization" }, + { TS_OPROM_COPY_END, "Option ROM copy done" }, + { TS_OPROM_END, "Option ROM run done" }, + { TS_DEVICE_DONE, "device setup done" }, + { TS_CBMEM_POST, "cbmem post" }, + { TS_WRITE_TABLES, "write tables" }, + { TS_FINALIZE_CHIPS, "finalize chips" }, + { TS_LOAD_PAYLOAD, "load payload" }, + { TS_ACPI_WAKE_JUMP, "ACPI wake jump" }, + { TS_SELFBOOT_JUMP, "selfboot jump" }, + + { TS_START_COPYVER, "starting to load verstage" }, + { TS_END_COPYVER, "finished loading verstage" }, + { TS_START_TPMINIT, "starting to initialize TPM" }, + { TS_END_TPMINIT, "finished TPM initialization" }, + { TS_START_VERIFY_SLOT, "starting to verify keyblock/preamble (RSA)" }, + { TS_END_VERIFY_SLOT, "finished verifying keyblock/preamble (RSA)" }, + { TS_START_HASH_BODY, "starting to verify body (load+SHA2+RSA) " }, + { TS_DONE_LOADING, "finished loading body (ignore for x86)" }, + { TS_DONE_HASHING, "finished calculating body hash (SHA2)" }, + { TS_END_HASH_BODY, "finished verifying body signature (RSA)" }, + + { TS_START_COPYVPD, "starting to load Chrome OS VPD" }, + { TS_END_COPYVPD_RO, "finished loading Chrome OS VPD (RO)" }, + { TS_END_COPYVPD_RW, "finished loading Chrome OS VPD (RW)" }, + + { TS_DC_START, "depthcharge start" }, + { TS_RO_PARAMS_INIT, "RO parameter init" }, + { TS_RO_VB_INIT, "RO vboot init" }, + { TS_RO_VB_SELECT_FIRMWARE, "RO vboot select firmware" }, + { TS_RO_VB_SELECT_AND_LOAD_KERNEL, "RO vboot select&load kernel" }, + { TS_RW_VB_SELECT_AND_LOAD_KERNEL, "RW vboot select&load kernel" }, + { TS_VB_SELECT_AND_LOAD_KERNEL, "vboot select&load kernel" }, + { TS_VB_EC_VBOOT_DONE, "finished EC verification" }, + { TS_VB_STORAGE_INIT_DONE, "finished storage device initialization" }, + { TS_VB_READ_KERNEL_DONE, "finished reading kernel from disk" }, + { TS_VB_VBOOT_DONE, "finished vboot kernel verification" }, + { TS_KERNEL_DECOMPRESSION, "starting kernel decompression/relocation" }, + { TS_START_KERNEL, "jumping to kernel" }, + + /* AMD AGESA related timestamps */ + { TS_AGESA_INIT_RESET_START, "calling AmdInitReset" }, + { TS_AGESA_INIT_RESET_DONE, "back from AmdInitReset" }, + { TS_AGESA_INIT_EARLY_START, "calling AmdInitEarly" }, + { TS_AGESA_INIT_EARLY_DONE, "back from AmdInitEarly" }, + { TS_AGESA_INIT_POST_START, "calling AmdInitPost" }, + { TS_AGESA_INIT_POST_DONE, "back from AmdInitPost" }, + { TS_AGESA_INIT_ENV_START, "calling AmdInitEnv" }, + { TS_AGESA_INIT_ENV_DONE, "back from AmdInitEnv" }, + { TS_AGESA_INIT_MID_START, "calling AmdInitMid" }, + { TS_AGESA_INIT_MID_DONE, "back from AmdInitMid" }, + { TS_AGESA_INIT_LATE_START, "calling AmdInitLate" }, + { TS_AGESA_INIT_LATE_DONE, "back from AmdInitLate" }, + { TS_AGESA_INIT_RTB_START, "calling AmdInitRtb/AmdS3Save" }, + { TS_AGESA_INIT_RTB_DONE, "back from AmdInitRtb/AmdS3Save" }, + + /* Intel ME related timestamps */ + { TS_ME_INFORM_DRAM_WAIT, "waiting for ME acknowledgement of raminit"}, + { TS_ME_INFORM_DRAM_DONE, "finished waiting for ME response"}, + + /* FSP related timestamps */ + { TS_FSP_MEMORY_INIT_START, "calling FspMemoryInit" }, + { TS_FSP_MEMORY_INIT_END, "returning from FspMemoryInit" }, + { TS_FSP_TEMP_RAM_EXIT_START, "calling FspTempRamExit" }, + { TS_FSP_TEMP_RAM_EXIT_END, "returning from FspTempRamExit" }, + { TS_FSP_SILICON_INIT_START, "calling FspSiliconInit" }, + { TS_FSP_SILICON_INIT_END, "returning from FspSiliconInit" }, + { TS_FSP_BEFORE_ENUMERATE, "calling FspNotify(AfterPciEnumeration)" }, + { TS_FSP_AFTER_ENUMERATE, + "returning from FspNotify(AfterPciEnumeration)" }, + { TS_FSP_BEFORE_FINALIZE, "calling FspNotify(ReadyToBoot)" }, + { TS_FSP_AFTER_FINALIZE, "returning from FspNotify(ReadyToBoot)" }, + { TS_FSP_BEFORE_END_OF_FIRMWARE, "calling FspNotify(EndOfFirmware)" }, + { TS_FSP_AFTER_END_OF_FIRMWARE, + "returning from FspNotify(EndOfFirmware)" }, +}; + +#endif diff --git a/util/ifdtool/Makefile b/util/ifdtool/Makefile index 936aa50..f742a1c 100644 --- a/util/ifdtool/Makefile +++ b/util/ifdtool/Makefile @@ -18,7 +18,7 @@ PROGRAM = ifdtool CC = gcc INSTALL = /usr/bin/install PREFIX = /usr/local -CFLAGS = -O2 -g -Wall -W -Werror -I../../src/commonlib/include +CFLAGS = -O2 -g -Wall -W -Werror -I../commonlib/include LDFLAGS = OBJS = ifdtool.o