@ -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 <commonlib/cbfs_serialized.h> | |||||
#include <commonlib/region.h> | |||||
#include <vb2_api.h> | |||||
/* 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 |
@ -0,0 +1,240 @@ | |||||
/* | |||||
* This file is part of the coreboot project. | |||||
* | |||||
* Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net> | |||||
* 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 <stdint.h> | |||||
#include <compiler.h> | |||||
/** 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_ */ |
@ -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_ */ |
@ -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 <stddef.h> | |||||
/* 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_ */ |
@ -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 <stdint.h> | |||||
/* 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 <color>_mask_pos and <color>_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 |
@ -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 <stddef.h> | |||||
#include <stdint.h> | |||||
#include <string.h> | |||||
/* 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 |
@ -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 <stdint.h> | |||||
#include <compiler.h> | |||||
#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__ */ |
@ -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 <stddef.h> | |||||
#include <stdint.h> | |||||
#include <sys/types.h> | |||||
/* | |||||
* 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 |
@ -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 <stddef.h> | |||||
#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 */ |
@ -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 <stdint.h> | |||||
#include <sys/types.h> | |||||
/* | |||||
* 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 |
@ -0,0 +1,174 @@ | |||||
/* | |||||
* This file is part of the coreboot project. | |||||
* | |||||
* Copyright (C) 2015 Nicholas Sielicki <sielicki@nicky.io> | |||||
* | |||||
* 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 */ |
@ -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 <stddef.h> | |||||
#include <stdint.h> | |||||
/* | |||||
* 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_ */ |
@ -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 <sys/types.h> | |||||
#include <stdint.h> | |||||
#include <stddef.h> | |||||
#include <commonlib/mem_pool.h> | |||||
/* | |||||
* 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_ */ |
@ -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 <stdint.h> | |||||
#include <stddef.h> | |||||
#include <compiler.h> | |||||
#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 */ |
@ -0,0 +1,228 @@ | |||||
/* | |||||
* Copyright 2011, Marvell Semiconductor Inc. | |||||
* Lei Wen <leiwen@marvell.com> | |||||
* | |||||
* 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 <stdint.h> | |||||
/* 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__ */ |
@ -0,0 +1,76 @@ | |||||
/* | |||||
* Copyright 2011, Marvell Semiconductor Inc. | |||||
* Lei Wen <leiwen@marvell.com> | |||||
* | |||||
* 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 <commonlib/sd_mmc_ctrlr.h> | |||||
/* 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__ */ |
@ -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 <stddef.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#if IS_ENABLED(CONFIG_COREBOOT_BUILD) | |||||
#include <console/console.h> | |||||
#include <halt.h> | |||||
#define printf(...) printk(BIOS_ERR, __VA_ARGS__) | |||||
#define HALT(x) halt() | |||||
#else | |||||
#include <stdio.h> | |||||
#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__ */ |
@ -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 <commonlib/sd_mmc_ctrlr.h> | |||||
/* | |||||
* 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__ */ |
@ -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 <stdint.h> | |||||
#include <compiler.h> | |||||
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 |