diff options
Diffstat (limited to 'payloads')
-rw-r--r-- | payloads/tianocoreboot/Makefile | 80 | ||||
-rw-r--r-- | payloads/tianocoreboot/README | 27 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/BootMode.h | 38 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/EfiFirmwareVolumeHeader.h | 213 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/EfiTypes.h | 297 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/MemoryAllocationHob.h | 34 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/PeiHob.h | 257 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/PiFirmwareFile.h | 494 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/coff.h | 106 | ||||
-rw-r--r-- | payloads/tianocoreboot/include/efi.h | 36 | ||||
-rw-r--r-- | payloads/tianocoreboot/libpayload.config | 58 | ||||
-rw-r--r-- | payloads/tianocoreboot/tianocoreboot.c | 529 |
12 files changed, 2169 insertions, 0 deletions
diff --git a/payloads/tianocoreboot/Makefile b/payloads/tianocoreboot/Makefile new file mode 100644 index 0000000000..0d51af2738 --- /dev/null +++ b/payloads/tianocoreboot/Makefile @@ -0,0 +1,80 @@ +## +## This file is part of the TianoCoreBoot project. +## +## 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. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +src := $(shell pwd) +srctree := $(src) +obj ?= $(src)/build + +export V := $(V) + +CONFIG_SHELL := sh +UNAME_RELEASE := $(shell uname -r) +HAVE_DOTCONFIG := $(wildcard .config) +MAKEFLAGS += -rR --no-print-directory + +# Make is silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +LIBCONFIG_PATH := ../libpayload +LIBPAYLOAD_DIR := $(obj)/libpayload +LPCC := $(LIBPAYLOAD_DIR)/libpayload/bin/lpgcc +LPAS := $(LIBPAYLOAD_DIR)/libpayload/bin/lpas +HAVE_LIBPAYLOAD := $(wildcard $(LIBPAYLOAD_DIR)/libpayload/lib/libpayload.a) +OBJCOPY ?= objcopy + +INCLUDES = -Iinclude +CFLAGS := -Wall -Werror -Os $(INCLUDES) +OBJECTS = tianocoreboot.o +OBJS = $(patsubst %,$(obj)/%,$(OBJECTS)) +TARGET = $(obj)/tianocoreboot.elf + +all: $(TARGET) + +$(TARGET): prepare $(OBJS) libpayload + $(Q)printf " LINK $(subst $(shell pwd)/,,$(@))\n" + $(Q)CC="$(CC)" $(LPCC) -o $@ $(OBJS) + $(Q)$(OBJCOPY) --only-keep-debug $@ $(TARGET).debug + $(Q)$(OBJCOPY) --strip-debug $@ + $(Q)$(OBJCOPY) --add-gnu-debuglink=$(TARGET).debug $@ + +$(obj)/%.o: $(src)/%.c libpayload + $(Q)printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)CC="$(CC)" $(LPCC) $(CFLAGS) -c -o $@ $< + +ifneq ($(strip $(HAVE_LIBPAYLOAD)),) +libpayload: + $(Q)printf "Found Libpayload $(LIBPAYLOAD_DIR).\n" +else +libpayload: + $(Q)printf "Building libpayload @ $(LIBCONFIG_PATH).\n" + $(Q)cp libpayload.config .config + $(Q)make -C $(LIBCONFIG_PATH) distclean + $(Q)make -C $(LIBCONFIG_PATH) DESTDIR=$(LIBPAYLOAD_DIR) install DOTCONFIG=$(shell pwd)/.config +endif + +prepare: + $(Q)mkdir -p $(obj) + +clean: + $(Q)rm -rf $(obj) $(LIBPAYLOAD_DIR) .xcompile .config .config.old + +.PHONY: $(PHONY) clean + diff --git a/payloads/tianocoreboot/README b/payloads/tianocoreboot/README new file mode 100644 index 0000000000..0dce08bbcd --- /dev/null +++ b/payloads/tianocoreboot/README @@ -0,0 +1,27 @@ +mkdir Tiano +cd Tiano +svn co https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2 edk2 --username guest +cd edk2 +svn co https://edk2-fatdriver2.svn.sourceforge.net/svnroot/edk2-fatdriver2/trunk/FatPkg FatPkg --username guest +cd .. + +make -C edk2/BaseTools + +export EDK_TOOLS_PATH=$(pwd)/edk2/BaseTools +cd edk2 +. ./edksetup.sh BaseTools + +vi Conf/target.txt + +ACTIVE_PLATFORM = OvmfPkg/OvmfPkgIa32.dsc +TOOL_CHAIN_TAG = GCC46 + +------ +#TODO +TARGET_ARCH = IA32 X64 +------ + +build -D DEBUG_ON_SERIAL_PORT + +--> ./Build/OvmfIa32/DEBUG_GCC46/FV/DXEFV.Fv + diff --git a/payloads/tianocoreboot/include/BootMode.h b/payloads/tianocoreboot/include/BootMode.h new file mode 100644 index 0000000000..38b7c0c6df --- /dev/null +++ b/payloads/tianocoreboot/include/BootMode.h @@ -0,0 +1,38 @@ +/*++ + +Copyright (c) 2004, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + BootMode.h + +Abstract: + + This includes for the Boot mode information. + +--*/ + +#ifndef _EFI_BOOT_MODE_H +#define _EFI_BOOT_MODE_H + +#define BOOT_WITH_FULL_CONFIGURATION 0x00 +#define BOOT_WITH_MINIMAL_CONFIGURATION 0x01 +#define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02 +#define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03 +#define BOOT_WITH_DEFAULT_SETTINGS 0x04 +#define BOOT_ON_S4_RESUME 0x05 +#define BOOT_ON_S5_RESUME 0x06 +#define BOOT_ON_S2_RESUME 0x10 +#define BOOT_ON_S3_RESUME 0x11 +#define BOOT_ON_FLASH_UPDATE 0x12 +#define BOOT_IN_RECOVERY_MODE 0x20 +#define BOOT_IN_RECOVERY_MODE_MASK 0x40 +#define BOOT_SPECIAL_MASK 0x80 +#endif diff --git a/payloads/tianocoreboot/include/EfiFirmwareVolumeHeader.h b/payloads/tianocoreboot/include/EfiFirmwareVolumeHeader.h new file mode 100644 index 0000000000..9bbab35692 --- /dev/null +++ b/payloads/tianocoreboot/include/EfiFirmwareVolumeHeader.h @@ -0,0 +1,213 @@ +/*++ + +Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiFirmwareVolumeHeader.h + +Abstract: + + Defines data structure that is the volume header found at the beginning of + all firmware volumes that are either memory mapped, or have an + associated FirmwareVolumeBlock protocol. + +--*/ + +#ifndef _EFI_FIRMWARE_VOLUME_HEADER_H_ +#define _EFI_FIRMWARE_VOLUME_HEADER_H_ + + +// +// Firmware Volume Block Attributes bit definitions +// They are the shared between Framework and PI1.0. +// +typedef UINT32 EFI_FVB_ATTRIBUTES; + +#define EFI_FVB_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB_READ_STATUS 0x00000004 + +#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB_WRITE_STATUS 0x00000020 + +#define EFI_FVB_LOCK_CAP 0x00000040 +#define EFI_FVB_LOCK_STATUS 0x00000080 + +#define EFI_FVB_STICKY_WRITE 0x00000200 +#define EFI_FVB_MEMORY_MAPPED 0x00000400 +#define EFI_FVB_ERASE_POLARITY 0x00000800 + + +#if (PI_SPECIFICATION_VERSION < 0x00010000) + +#define EFI_FVB_ALIGNMENT_CAP 0x00008000 +#define EFI_FVB_ALIGNMENT_2 0x00010000 +#define EFI_FVB_ALIGNMENT_4 0x00020000 +#define EFI_FVB_ALIGNMENT_8 0x00040000 +#define EFI_FVB_ALIGNMENT_16 0x00080000 +#define EFI_FVB_ALIGNMENT_32 0x00100000 +#define EFI_FVB_ALIGNMENT_64 0x00200000 +#define EFI_FVB_ALIGNMENT_128 0x00400000 +#define EFI_FVB_ALIGNMENT_256 0x00800000 +#define EFI_FVB_ALIGNMENT_512 0x01000000 +#define EFI_FVB_ALIGNMENT_1K 0x02000000 +#define EFI_FVB_ALIGNMENT_2K 0x04000000 +#define EFI_FVB_ALIGNMENT_4K 0x08000000 +#define EFI_FVB_ALIGNMENT_8K 0x10000000 +#define EFI_FVB_ALIGNMENT_16K 0x20000000 +#define EFI_FVB_ALIGNMENT_32K 0x40000000 +#define EFI_FVB_ALIGNMENT_64K 0x80000000 + +#define EFI_FVB_CAPABILITIES (EFI_FVB_READ_DISABLED_CAP | \ + EFI_FVB_READ_ENABLED_CAP | \ + EFI_FVB_WRITE_DISABLED_CAP | \ + EFI_FVB_WRITE_ENABLED_CAP | \ + EFI_FVB_LOCK_CAP \ + ) + +#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS) + + + +#else + +#define EFI_FVB2_READ_LOCK_CAP 0x00001000 +#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 + +#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 +#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 + +#define EFI_FVB2_ALIGNMENT 0x001F0000 +#define EFI_FVB2_ALIGNMENT_1 0x00000000 +#define EFI_FVB2_ALIGNMENT_2 0x00010000 +#define EFI_FVB2_ALIGNMENT_4 0x00020000 +#define EFI_FVB2_ALIGNMENT_8 0x00030000 +#define EFI_FVB2_ALIGNMENT_16 0x00040000 +#define EFI_FVB2_ALIGNMENT_32 0x00050000 +#define EFI_FVB2_ALIGNMENT_64 0x00060000 +#define EFI_FVB2_ALIGNMENT_128 0x00070000 +#define EFI_FVB2_ALIGNMENT_256 0x00080000 +#define EFI_FVB2_ALIGNMENT_512 0x00090000 +#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 +#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 +#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 +#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 +#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 +#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 +#define EFI_FVB2_ALIGNMENT_64K 0x00100000 +#define EFI_FVB2_ALIGNMENT_128K 0x00110000 +#define EFI_FVB2_ALIGNMENT_256K 0x00120000 +#define EFI_FVB2_ALIGNMENT_512K 0x00130000 +#define EFI_FVB2_ALIGNMENT_1M 0x00140000 +#define EFI_FVB2_ALIGNMENT_2M 0x00150000 +#define EFI_FVB2_ALIGNMENT_4M 0x00160000 +#define EFI_FVB2_ALIGNMENT_8M 0x00170000 +#define EFI_FVB2_ALIGNMENT_16M 0x00180000 +#define EFI_FVB2_ALIGNMENT_32M 0x00190000 +#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 +#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 +#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 +#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 +#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 +#define EFI_FVB2_ALIGNMENT_2G 0x001F0000 + +#define EFI_FVB_CAPABILITIES (EFI_FVB_READ_DISABLED_CAP | \ + EFI_FVB_READ_ENABLED_CAP | \ + EFI_FVB_WRITE_DISABLED_CAP | \ + EFI_FVB_WRITE_ENABLED_CAP | \ + EFI_FVB_LOCK_CAP | \ + EFI_FVB2_READ_LOCK_CAP | \ + EFI_FVB2_WRITE_LOCK_CAP ) + +#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | \ + EFI_FVB_LOCK_STATUS | EFI_FVB2_READ_LOCK_STATUS | \ + EFI_FVB2_WRITE_LOCK_STATUS ) + + + +// +// Extended Header Header. Located via ExtHeaderOffset. +// The extended headers follow each other in memory and are +// terminated by ExtHeaderType EFI_FV_EXT_TYPE_END +// +#define EFI_FV_EXT_TYPE_END 0x00 +typedef struct { + UINT16 ExtEntrySize; + UINT16 ExtEntryType; +} EFI_FIRMWARE_VOLUME_EXT_ENTRY; + +// +// GUID that maps OEM file types to GUIDs +// +#define EFI_FV_EXT_TYPE_OEM_TYPE 0x01 +typedef struct { + EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; + UINT32 TypeMask; + EFI_GUID Types[1]; +} EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE; + +// +// Unique name of the FV +// +typedef struct { + EFI_GUID FvName; + UINT32 ExtHeaderSize; +} EFI_FIRMWARE_VOLUME_EXT_HEADER; + + +#endif + + +// +// Firmware Volume Header Revision definition +// +#define EFI_FVH_REVISION 0x01 +// +// PI1.0 define Firmware Volume Header Revision to 2 +// +#define EFI_FVH_PI_REVISION 0x02 + +// +// Firmware Volume Header Signature definition +// +#define EFI_FVH_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', 'H') + +// +// Firmware Volume Header Block Map Entry definition +// +typedef struct { + UINT32 NumBlocks; + UINT32 BlockLength; +} EFI_FV_BLOCK_MAP_ENTRY; + +// +// Firmware Volume Header definition +// +typedef struct { + UINT8 ZeroVector[16]; + EFI_GUID FileSystemGuid; + UINT64 FvLength; + UINT32 Signature; + EFI_FVB_ATTRIBUTES Attributes; + UINT16 HeaderLength; + UINT16 Checksum; +#if (PI_SPECIFICATION_VERSION < 0x00010000) + UINT8 Reserved[3]; +#else + UINT16 ExtHeaderOffset; + UINT8 Reserved[1]; +#endif + UINT8 Revision; + EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1]; +} EFI_FIRMWARE_VOLUME_HEADER; + +#endif diff --git a/payloads/tianocoreboot/include/EfiTypes.h b/payloads/tianocoreboot/include/EfiTypes.h new file mode 100644 index 0000000000..49760d3acb --- /dev/null +++ b/payloads/tianocoreboot/include/EfiTypes.h @@ -0,0 +1,297 @@ +/*++ + +Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiTypes.h + +Abstract: + + EFI defined types. Use these types when ever possible! + +--*/ + +#ifndef _EFI_TYPES_H_ +#define _EFI_TYPES_H_ + +// +// EFI Data Types based on ANSI C integer types in EfiBind.h +// +typedef uint8_t BOOLEAN; +typedef intn_t INTN; +typedef uintn_t UINTN; +typedef int8_t INT8; +typedef uint8_t UINT8; +typedef int16_t INT16; +typedef uint16_t UINT16; +typedef int32_t INT32; +typedef uint32_t UINT32; +typedef int64_t INT64; +typedef uint64_t UINT64; +typedef char CHAR8; +typedef uint16_t CHAR16; +typedef UINT64 EFI_LBA; + +// +// Modifiers for EFI Data Types used to self document code. +// Please see EFI coding convention for proper usage. +// +#ifndef IN +// +// Some other envirnments use this construct, so #ifndef to prevent +// mulitple definition. +// +#define IN +#define OUT +#define OPTIONAL +#endif + +#ifndef UNALIGNED +#define UNALIGNED +#endif + +// +// Modifiers for EFI Runtime and Boot Services +// +#define EFI_RUNTIMESERVICE +#define EFI_BOOTSERVICE + +// +// Boot Service add in EFI 1.1 +// +#define EFI_BOOTSERVICE11 + +// +// Modifiers to absract standard types to aid in debug of problems +// +#define CONST const +#define STATIC static +#define VOID void +#define VOLATILE volatile + +// +// Modifier to ensure that all protocol member functions and EFI intrinsics +// use the correct C calling convention. All protocol member functions and +// EFI intrinsics are required to modify thier member functions with EFIAPI. +// +#ifndef EFIAPI + #define EFIAPI _EFIAPI +#endif + +// +// EFI Constants. They may exist in other build structures, so #ifndef them. +// +#ifndef TRUE +#define TRUE ((BOOLEAN) (1 == 1)) +#endif + +#ifndef FALSE +#define FALSE ((BOOLEAN) (0 == 1)) +#endif + +#ifndef NULL +#define NULL ((VOID *) 0) +#endif +// +// EFI Data Types derived from other EFI data types. +// +typedef UINTN EFI_STATUS; + +typedef VOID *EFI_HANDLE; +#define NULL_HANDLE ((VOID *) 0) + +typedef VOID *EFI_EVENT; +typedef UINTN EFI_TPL; + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + +typedef union { + EFI_GUID Guid; + UINT8 Raw[16]; +} EFI_GUID_UNION; + +// +// EFI Time Abstraction: +// Year: 2000 - 20XX +// Month: 1 - 12 +// Day: 1 - 31 +// Hour: 0 - 23 +// Minute: 0 - 59 +// Second: 0 - 59 +// Nanosecond: 0 - 999,999,999 +// TimeZone: -1440 to 1440 or 2047 +// +typedef struct { + UINT16 Year; + UINT8 Month; + UINT8 Day; + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + UINT8 Pad1; + UINT32 Nanosecond; + INT16 TimeZone; + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +// +// Bit definitions for EFI_TIME.Daylight +// +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +// +// Value definition for EFI_TIME.TimeZone +// +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + +// +// Networking +// +typedef struct { + UINT8 Addr[4]; +} EFI_IPv4_ADDRESS; + +typedef struct { + UINT8 Addr[16]; +} EFI_IPv6_ADDRESS; + +typedef struct { + UINT8 Addr[32]; +} EFI_MAC_ADDRESS; + +typedef union { + UINT32 Addr[4]; + EFI_IPv4_ADDRESS v4; + EFI_IPv6_ADDRESS v6; +} EFI_IP_ADDRESS; + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +typedef struct { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + +// +// possible caching types for the memory range +// +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +// +// physical memory protection on range +// +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 + +// +// range requires a runtime mapping +// +#define EFI_MEMORY_RUNTIME 0x8000000000000000ULL + +typedef UINT64 EFI_PHYSICAL_ADDRESS; +typedef UINT64 EFI_VIRTUAL_ADDRESS; + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + UINT32 Type; + UINT32 Pad; + EFI_PHYSICAL_ADDRESS PhysicalStart; + EFI_VIRTUAL_ADDRESS VirtualStart; + UINT64 NumberOfPages; + UINT64 Attribute; +} EFI_MEMORY_DESCRIPTOR; + +// +// The EFI memory allocation functions work in units of EFI_PAGEs that are +// 4K. This should in no way be confused with the page size of the processor. +// An EFI_PAGE is just the quanta of memory in EFI. +// +#define EFI_PAGE_SIZE 4096 +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0)) + +#define EFI_PAGES_TO_SIZE(a) ( (a) << EFI_PAGE_SHIFT) + +// +// ALIGN_POINTER - aligns a pointer to the lowest boundry +// +#define ALIGN_POINTER(p, s) ((VOID *) (p + ((s - ((UINTN) p)) & (s - 1)))) + +// +// ALIGN_VARIABLE - aligns a variable up to the next natural boundry for int size of a processor +// +#define ALIGN_VARIABLE(Value, Adjustment) \ + (UINTN) Adjustment = 0; \ + if ((UINTN) Value % sizeof (UINTN)) { \ + (UINTN) Adjustment = sizeof (UINTN) - ((UINTN) Value % sizeof (UINTN)); \ + } \ + Value = (UINTN) Value + (UINTN) Adjustment + +// +// EFI_FIELD_OFFSET - returns the byte offset to a field within a structure +// +#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field))) + +// +// CONTAINING_RECORD - returns a pointer to the structure +// from one of it's elements. +// +#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) + +// +// Define macros to build data structure signatures from characters. +// +#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8)) +#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16)) +#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \ + (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32)) + +#endif diff --git a/payloads/tianocoreboot/include/MemoryAllocationHob.h b/payloads/tianocoreboot/include/MemoryAllocationHob.h new file mode 100644 index 0000000000..fb067571bc --- /dev/null +++ b/payloads/tianocoreboot/include/MemoryAllocationHob.h @@ -0,0 +1,34 @@ +/** @file + GUIDs for HOBs used in memory allcation + + Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR> + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + GUIDs introduced in PI Version 1.0. + +**/ + +#ifndef __MEMORY_ALLOCATION_GUID_H__ +#define __MEMORY_ALLOCATION_GUID_H__ + +#define EFI_HOB_MEMORY_ALLOC_BSP_STORE_GUID \ + {0x564b33cd, 0xc92a, 0x4593, {0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22} }; + +#define EFI_HOB_MEMORY_ALLOC_STACK_GUID \ + {0x4ed4bf27, 0x4092, 0x42e9, {0x80, 0x7d, 0x52, 0x7b, 0x1d, 0x0, 0xc9, 0xbd} } + +#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \ + {0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} } + +extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid; +extern EFI_GUID gEfiHobMemoryAllocStackGuid; +extern EFI_GUID gEfiHobMemoryAllocModuleGuid; + +#endif diff --git a/payloads/tianocoreboot/include/PeiHob.h b/payloads/tianocoreboot/include/PeiHob.h new file mode 100644 index 0000000000..407ea7673c --- /dev/null +++ b/payloads/tianocoreboot/include/PeiHob.h @@ -0,0 +1,257 @@ +/*++ + +Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PeiHob.h + +Abstract: + + PEI Hand Off Block (HOB) definition. + + The HOB is a memory data structure used to hand-off system information from + PEI to DXE (the next phase). + +--*/ + +#ifndef _PEI_HOB_H_ +#define _PEI_HOB_H_ + +#include "BootMode.h" + +// +// Every Hob must start with this data structure. +// +typedef struct { + UINT16 HobType; + UINT16 HobLength; + UINT32 Reserved; +} EFI_HOB_GENERIC_HEADER; + +// +// End of HOB List HOB +// +#define EFI_HOB_TYPE_END_OF_HOB_LIST 0xffff + +// +// Handoff Information Table HOB +// +#define EFI_HOB_TYPE_HANDOFF 0x0001 + +#define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009 + +typedef UINT32 EFI_BOOT_MODE; + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + UINT32 Version; + EFI_BOOT_MODE BootMode; + EFI_PHYSICAL_ADDRESS EfiMemoryTop; + EFI_PHYSICAL_ADDRESS EfiMemoryBottom; + EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop; + EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom; + EFI_PHYSICAL_ADDRESS EfiEndOfHobList; +} EFI_HOB_HANDOFF_INFO_TABLE; + +// +// Memory Descriptor HOB +// +#define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002 + +typedef struct { + EFI_GUID Name; + EFI_PHYSICAL_ADDRESS MemoryBaseAddress; + UINT64 MemoryLength; + EFI_MEMORY_TYPE MemoryType; + UINT8 Reserved[4]; +} EFI_HOB_MEMORY_ALLOCATION_HEADER; + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor; + // + // Additional data pertaining to the "Name" Guid memory + // may go here. + // +} EFI_HOB_MEMORY_ALLOCATION; + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor; +} EFI_HOB_MEMORY_ALLOCATION_BSP_STORE; + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor; +} EFI_HOB_MEMORY_ALLOCATION_STACK; + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader; + EFI_GUID ModuleName; + EFI_PHYSICAL_ADDRESS EntryPoint; +} EFI_HOB_MEMORY_ALLOCATION_MODULE; + +#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003 + +typedef UINT32 EFI_RESOURCE_TYPE; + +#define EFI_RESOURCE_SYSTEM_MEMORY 0 +#define EFI_RESOURCE_MEMORY_MAPPED_IO 1 +#define EFI_RESOURCE_IO 2 +#define EFI_RESOURCE_FIRMWARE_DEVICE 3 +#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 4 +#define EFI_RESOURCE_MEMORY_RESERVED 5 +#define EFI_RESOURCE_IO_RESERVED 6 +#define EFI_RESOURCE_MAX_MEMORY_TYPE 7 + +typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE; + +#define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001 +#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002 +#define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004 +#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008 +#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010 +#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020 +#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040 +#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080 +#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100 +#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200 +#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400 +#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800 +#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000 +#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000 +#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000 +#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000 +#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000 +#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000 +// +// The following values are defined in PI 1.2 errata B. +// +#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000 +#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000 +#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_GUID Owner; + EFI_RESOURCE_TYPE ResourceType; + EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute; + EFI_PHYSICAL_ADDRESS PhysicalStart; + UINT64 ResourceLength; +} EFI_HOB_RESOURCE_DESCRIPTOR; + +// +// GUID Extension HOB +// The HobLength is variable as it includes the GUID specific data. +// +#define EFI_HOB_TYPE_GUID_EXTENSION 0x0004 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_GUID Name; + + // + // Guid specific data goes here + // +} EFI_HOB_GUID_TYPE; + +// +// Firmware Volume HOB +// +#define EFI_HOB_TYPE_FV 0x0005 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINT64 Length; +} EFI_HOB_FIRMWARE_VOLUME; + +// +// CPU HOB +// +#define EFI_HOB_TYPE_CPU 0x0006 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + UINT8 SizeOfMemorySpace; + UINT8 SizeOfIoSpace; + UINT8 Reserved[6]; +} EFI_HOB_CPU; + +// +// PEI Core Memory Pool HOB +// The HobLength is variable as the HOB contains pool allocations by +// the PeiServices AllocatePool function +// +#define EFI_HOB_TYPE_PEI_MEMORY_POOL 0x0007 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; +} EFI_HOB_MEMORY_POOL; + +// +// Capsule volume HOB -- identical to a firmware volume +// +#define EFI_HOB_TYPE_CV 0x0008 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINT64 Length; +} EFI_HOB_CAPSULE_VOLUME; + +#if (PI_SPECIFICATION_VERSION >= 0x00010000) + +#define EFI_HOB_TYPE_FV2 0x0009 + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINT64 Length; + EFI_GUID FvName; + EFI_GUID FileName; +} EFI_HOB_FIRMWARE_VOLUME2; + +#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A + +#endif + +#define EFI_HOB_TYPE_UNUSED 0xFFFE + +// +// Union of all the possible HOB Types +// +typedef union { + EFI_HOB_GENERIC_HEADER *Header; + EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable; + EFI_HOB_MEMORY_ALLOCATION *MemoryAllocation; + EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore; + EFI_HOB_MEMORY_ALLOCATION_STACK *MemoryAllocationStack; + EFI_HOB_MEMORY_ALLOCATION_MODULE *MemoryAllocationModule; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor; + EFI_HOB_GUID_TYPE *Guid; + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolume; +#if (PI_SPECIFICATION_VERSION >= 0x00010000) + EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2; +#endif + EFI_HOB_CPU *Cpu; + EFI_HOB_MEMORY_POOL *Pool; + EFI_HOB_CAPSULE_VOLUME *CapsuleVolume; + UINT8 *Raw; +} EFI_PEI_HOB_POINTERS; + +#define GET_HOB_TYPE(Hob) ((Hob).Header->HobType) +#define GET_HOB_LENGTH(Hob) ((Hob).Header->HobLength) +#define GET_NEXT_HOB(Hob) ((Hob).Raw + GET_HOB_LENGTH (Hob)) +#define END_OF_HOB_LIST(Hob) (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST) + +#endif diff --git a/payloads/tianocoreboot/include/PiFirmwareFile.h b/payloads/tianocoreboot/include/PiFirmwareFile.h new file mode 100644 index 0000000000..750ba7091e --- /dev/null +++ b/payloads/tianocoreboot/include/PiFirmwareFile.h @@ -0,0 +1,494 @@ +/** @file + The firmware file related definitions in PI. + +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + PI Version 1.2. + +**/ + + +#ifndef __PI_FIRMWARE_FILE_H__ +#define __PI_FIRMWARE_FILE_H__ + +#pragma pack(1) +/// +/// Used to verify the integrity of the file. +/// +typedef union { + struct { + /// + /// The IntegrityCheck.Checksum.Header field is an 8-bit checksum of the file + /// header. The State and IntegrityCheck.Checksum.File fields are assumed + /// to be zero and the checksum is calculated such that the entire header sums to zero. + /// + UINT8 Header; + /// + /// If the FFS_ATTRIB_CHECKSUM (see definition below) bit of the Attributes + /// field is set to one, the IntegrityCheck.Checksum.File field is an 8-bit + /// checksum of the file data. + /// If the FFS_ATTRIB_CHECKSUM bit of the Attributes field is cleared to zero, + /// the IntegrityCheck.Checksum.File field must be initialized with a value of + /// 0xAA. The IntegrityCheck.Checksum.File field is valid any time the + /// EFI_FILE_DATA_VALID bit is set in the State field. + /// + UINT8 File; + } Checksum; + /// + /// This is the full 16 bits of the IntegrityCheck field. + /// + UINT16 Checksum16; +} EFI_FFS_INTEGRITY_CHECK; + +/// +/// FFS_FIXED_CHECKSUM is the checksum value used when the +/// FFS_ATTRIB_CHECKSUM attribute bit is clear. +/// +#define FFS_FIXED_CHECKSUM 0xAA + +typedef UINT8 EFI_FV_FILETYPE; +typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; +typedef UINT8 EFI_FFS_FILE_STATE; + +/// +/// File Types Definitions +/// +#define EFI_FV_FILETYPE_ALL 0x00 +#define EFI_FV_FILETYPE_RAW 0x01 +#define EFI_FV_FILETYPE_FREEFORM 0x02 +#define EFI_FV_FILETYPE_SECURITY_CORE 0x03 +#define EFI_FV_FILETYPE_PEI_CORE 0x04 +#define EFI_FV_FILETYPE_DXE_CORE 0x05 +#define EFI_FV_FILETYPE_PEIM 0x06 +#define EFI_FV_FILETYPE_DRIVER 0x07 +#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 +#define EFI_FV_FILETYPE_APPLICATION 0x09 +#define EFI_FV_FILETYPE_SMM 0x0A +#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B +#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C +#define EFI_FV_FILETYPE_SMM_CORE 0x0D +#define EFI_FV_FILETYPE_OEM_MIN 0xc0 +#define EFI_FV_FILETYPE_OEM_MAX 0xdf +#define EFI_FV_FILETYPE_DEBUG_MIN 0xe0 +#define EFI_FV_FILETYPE_DEBUG_MAX 0xef +#define EFI_FV_FILETYPE_FFS_MIN 0xf0 +#define EFI_FV_FILETYPE_FFS_MAX 0xff +#define EFI_FV_FILETYPE_FFS_PAD 0xf0 +/// +/// FFS File Attributes. +/// +#define FFS_ATTRIB_LARGE_FILE 0x01 +#define FFS_ATTRIB_FIXED 0x04 +#define FFS_ATTRIB_DATA_ALIGNMENT 0x38 +#define FFS_ATTRIB_CHECKSUM 0x40 + +/// +/// FFS File State Bits. +/// +#define EFI_FILE_HEADER_CONSTRUCTION 0x01 +#define EFI_FILE_HEADER_VALID 0x02 +#define EFI_FILE_DATA_VALID 0x04 +#define EFI_FILE_MARKED_FOR_UPDATE 0x08 +#define EFI_FILE_DELETED 0x10 +#define EFI_FILE_HEADER_INVALID 0x20 + + +/// +/// Each file begins with the header that describe the +/// contents and state of the files. +/// +typedef struct { + /// + /// This GUID is the file name. It is used to uniquely identify the file. + /// + EFI_GUID Name; + /// + /// Used to verify the integrity of the file. + /// + EFI_FFS_INTEGRITY_CHECK IntegrityCheck; + /// + /// Identifies the type of file. + /// + EFI_FV_FILETYPE Type; + /// + /// Declares various file attribute bits. + /// + EFI_FFS_FILE_ATTRIBUTES Attributes; + /// + /// The length of the file in bytes, including the FFS header. + /// + UINT8 Size[3]; + /// + /// Used to track the state of the file throughout the life of the file from creation to deletion. + /// + EFI_FFS_FILE_STATE State; +} EFI_FFS_FILE_HEADER; + +typedef struct { + /// + /// This GUID is the file name. It is used to uniquely identify the file. There may be only + /// one instance of a file with the file name GUID of Name in any given firmware + /// volume, except if the file type is EFI_FV_FILETYPE_FFS_PAD. + /// + EFI_GUID Name; + + /// + /// Used to verify the integrity of the file. + /// + EFI_FFS_INTEGRITY_CHECK IntegrityCheck; + + /// + /// Identifies the type of file. + /// + EFI_FV_FILETYPE Type; + + /// + /// Declares various file attribute bits. + /// + EFI_FFS_FILE_ATTRIBUTES Attributes; + + /// + /// The length of the file in bytes, including the FFS header. + /// The length of the file data is either (Size - sizeof(EFI_FFS_FILE_HEADER)). This calculation means a + /// zero-length file has a Size of 24 bytes, which is sizeof(EFI_FFS_FILE_HEADER). + /// Size is not required to be a multiple of 8 bytes. Given a file F, the next file header is + /// located at the next 8-byte aligned firmware volume offset following the last byte of the file F. + /// + UINT8 Size[3]; + + /// + /// Used to track the state of the file throughout the life of the file from creation to deletion. + /// + EFI_FFS_FILE_STATE State; + + /// + /// If FFS_ATTRIB_LARGE_FILE is set in Attributes, then ExtendedSize exists and Size must be set to zero. + /// If FFS_ATTRIB_LARGE_FILE is not set then EFI_FFS_FILE_HEADER is used. + /// + UINT32 ExtendedSize; +} EFI_FFS_FILE_HEADER2; + +#define IS_FFS_FILE2(FfsFileHeaderPtr) \ + (((((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Attributes) & FFS_ATTRIB_LARGE_FILE) == FFS_ATTRIB_LARGE_FILE) + +#define FFS_FILE_SIZE(FfsFileHeaderPtr) \ + ((UINT32) (*((UINT32 *) ((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Size) & 0x00ffffff)) + +#define FFS_FILE2_SIZE(FfsFileHeaderPtr) \ + (((EFI_FFS_FILE_HEADER2 *) (UINTN) FfsFileHeaderPtr)->ExtendedSize) + +typedef UINT8 EFI_SECTION_TYPE; + +/// +/// Pseudo type. It is used as a wild card when retrieving sections. +/// The section type EFI_SECTION_ALL matches all section types. +/// +#define EFI_SECTION_ALL 0x00 + +/// +/// Encapsulation section Type values. +/// +#define EFI_SECTION_COMPRESSION 0x01 + +#define EFI_SECTION_GUID_DEFINED 0x02 + +#define EFI_SECTION_DISPOSABLE 0x03 + +/// +/// Leaf section Type values. +/// +#define EFI_SECTION_PE32 0x10 +#define EFI_SECTION_PIC 0x11 +#define EFI_SECTION_TE 0x12 +#define EFI_SECTION_DXE_DEPEX 0x13 +#define EFI_SECTION_VERSION 0x14 +#define EFI_SECTION_USER_INTERFACE 0x15 +#define EFI_SECTION_COMPATIBILITY16 0x16 +#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define EFI_SECTION_RAW 0x19 +#define EFI_SECTION_PEI_DEPEX 0x1B +#define EFI_SECTION_SMM_DEPEX 0x1C + +/// +/// Common section header. +/// +typedef struct { + /// + /// A 24-bit unsigned integer that contains the total size of the section in bytes, + /// including the EFI_COMMON_SECTION_HEADER. + /// + UINT8 Size[3]; + EFI_SECTION_TYPE Type; + /// + /// Declares the section type. + /// +} EFI_COMMON_SECTION_HEADER; + +typedef struct { + /// + /// A 24-bit unsigned integer that contains the total size of the section in bytes, + /// including the EFI_COMMON_SECTION_HEADER. + /// + UINT8 Size[3]; + + EFI_SECTION_TYPE Type; + + /// + /// If Size is 0xFFFFFF, then ExtendedSize contains the size of the section. If + /// Size is not equal to 0xFFFFFF, then this field does not exist. + /// + UINT32 ExtendedSize; +} EFI_COMMON_SECTION_HEADER2; + +/// +/// Leaf section type that contains an +/// IA-32 16-bit executable image. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2; + +/// +/// CompressionType of EFI_COMPRESSION_SECTION. +/// +#define EFI_NOT_COMPRESSED 0x00 +#define EFI_STANDARD_COMPRESSION 0x01 +/// +/// An encapsulation section type in which the +/// section data is compressed. +/// +typedef struct { + /// + /// Usual common section header. CommonHeader.Type = EFI_SECTION_COMPRESSION. + /// + EFI_COMMON_SECTION_HEADER CommonHeader; + /// + /// The UINT32 that indicates the size of the section data after decompression. + /// + UINT32 UncompressedLength; + /// + /// Indicates which compression algorithm is used. + /// + UINT8 CompressionType; +} EFI_COMPRESSION_SECTION; + +typedef struct { + /// + /// Usual common section header. CommonHeader.Type = EFI_SECTION_COMPRESSION. + /// + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// UINT32 that indicates the size of the section data after decompression. + /// + UINT32 UncompressedLength; + /// + /// Indicates which compression algorithm is used. + /// + UINT8 CompressionType; +} EFI_COMPRESSION_SECTION2; + +/// +/// An encapsulation section type in which the section data is disposable. +/// A disposable section is an encapsulation section in which the section data may be disposed of during +/// the process of creating or updating a firmware image without significant impact on the usefulness of +/// the file. The Type field in the section header is set to EFI_SECTION_DISPOSABLE. This +/// allows optional or descriptive data to be included with the firmware file which can be removed in +/// order to conserve space. The contents of this section are implementation specific, but might contain +/// debug data or detailed integration instructions. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2; + +/// +/// The leaf section which could be used to determine the dispatch order of DXEs. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2; + +/// +/// The leaf section which contains a PI FV. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2; + +/// +/// The leaf section which contains a single GUID. +/// +typedef struct { + /// + /// Common section header. CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID. + /// + EFI_COMMON_SECTION_HEADER CommonHeader; + /// + /// This GUID is defined by the creator of the file. It is a vendor-defined file type. + /// + EFI_GUID SubTypeGuid; +} EFI_FREEFORM_SUBTYPE_GUID_SECTION; + +typedef struct { + /// + /// The common section header. CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID. + /// + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// This GUID is defined by the creator of the file. It is a vendor-defined file type. + /// + EFI_GUID SubTypeGuid; +} EFI_FREEFORM_SUBTYPE_GUID_SECTION2; + +/// +/// Attributes of EFI_GUID_DEFINED_SECTION. +/// +#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 +#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 +/// +/// The leaf section which is encapsulation defined by specific GUID. +/// +typedef struct { + /// + /// The common section header. CommonHeader.Type = EFI_SECTION_GUID_DEFINED. + /// + EFI_COMMON_SECTION_HEADER CommonHeader; + /// + /// The GUID that defines the format of the data that follows. It is a vendor-defined section type. + /// + EFI_GUID SectionDefinitionGuid; + /// + /// Contains the offset in bytes from the beginning of the common header to the first byte of the data. + /// + UINT16 DataOffset; + /// + /// The bit field that declares some specific characteristics of the section contents. + /// + UINT16 Attributes; +} EFI_GUID_DEFINED_SECTION; + +typedef struct { + /// + /// The common section header. CommonHeader.Type = EFI_SECTION_GUID_DEFINED. + /// + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// The GUID that defines the format of the data that follows. It is a vendor-defined section type. + /// + EFI_GUID SectionDefinitionGuid; + /// + /// Contains the offset in bytes from the beginning of the common header to the first byte of the data. + /// + UINT16 DataOffset; + /// + /// The bit field that declares some specific characteristics of the section contents. + /// + UINT16 Attributes; +} EFI_GUID_DEFINED_SECTION2; + +/// +/// The leaf section which contains PE32+ image. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2; + +/// +/// The leaf section used to determine the dispatch order of PEIMs. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2; + +/// +/// A leaf section type that contains a position-independent-code (PIC) image. +/// A PIC image section is a leaf section that contains a position-independent-code (PIC) image. +/// In addition to normal PE32+ images that contain relocation information, PEIM executables may be +/// PIC and are referred to as PIC images. A PIC image is the same as a PE32+ image except that all +/// relocation information has been stripped from the image and the image can be moved and will +/// execute correctly without performing any relocation or other fix-ups. EFI_PIC_SECTION2 must +/// be used if the section is 16MB or larger. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2; + +/// +/// The leaf section which constains the position-independent-code image. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2; + +/// +/// The leaf section which contains an array of zero or more bytes. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2; + +/// +/// The SMM dependency expression section is a leaf section that contains a dependency expression that +/// is used to determine the dispatch order for SMM drivers. Before the SMRAM invocation of the +/// SMM driver's entry point, this dependency expression must evaluate to TRUE. See the Platform +/// Initialization Specification, Volume 2, for details regarding the format of the dependency expression. +/// The dependency expression may refer to protocols installed in either the UEFI or the SMM protocol +/// database. EFI_SMM_DEPEX_SECTION2 must be used if the section is 16MB or larger. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2; + +/// +/// The leaf section which contains a unicode string that +/// is human readable file name. +/// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + + /// + /// Array of unicode string. + /// + CHAR16 FileNameString[1]; +} EFI_USER_INTERFACE_SECTION; + +typedef struct { + EFI_COMMON_SECTION_HEADER2 CommonHeader; + CHAR16 FileNameString[1]; +} EFI_USER_INTERFACE_SECTION2; + +/// +/// The leaf section which contains a numeric build number and +/// an optional unicode string that represents the file revision. +/// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + UINT16 BuildNumber; + + /// + /// Array of unicode string. + /// + CHAR16 VersionString[1]; +} EFI_VERSION_SECTION; + +typedef struct { + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// A UINT16 that represents a particular build. Subsequent builds have monotonically + /// increasing build numbers relative to earlier builds. + /// + UINT16 BuildNumber; + CHAR16 VersionString[1]; +} EFI_VERSION_SECTION2; + +#define IS_SECTION2(SectionHeaderPtr) \ + ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) (UINTN) SectionHeaderPtr)->Size) & 0x00ffffff) == 0x00ffffff) + +#define SECTION_SIZE(SectionHeaderPtr) \ + ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) (UINTN) SectionHeaderPtr)->Size) & 0x00ffffff)) + +#define SECTION2_SIZE(SectionHeaderPtr) \ + (((EFI_COMMON_SECTION_HEADER2 *) (UINTN) SectionHeaderPtr)->ExtendedSize) + +#pragma pack() + +#endif + diff --git a/payloads/tianocoreboot/include/coff.h b/payloads/tianocoreboot/include/coff.h new file mode 100644 index 0000000000..24b2c9c242 --- /dev/null +++ b/payloads/tianocoreboot/include/coff.h @@ -0,0 +1,106 @@ +/* + * This file is part of the TianoCoreBoot project. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +typedef struct { + uint8_t signature[2]; + uint16_t lastsize; + uint16_t nblocks; + uint16_t nreloc; + uint16_t hdrsize; + uint16_t minalloc; + uint16_t maxalloc; + uint16_t ss; + uint16_t sp; + uint16_t checksum; + uint16_t ip; + uint16_t cs; + uint16_t relocpos; + uint16_t noverlay; + uint16_t reserved1[4]; + uint16_t oem_id; + uint16_t oem_info; + uint16_t reserved2[10]; + uint32_t e_lfanew; +} dos_header_t; + +typedef struct { + uint8_t signature[4]; + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +} coff_header_t; + +typedef struct { + uint32_t VirtualAddress; + uint32_t Size; +} data_directory; + +typedef struct { + uint16_t signature; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint32_t BaseOfData; + uint32_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOSVersion; + uint16_t MinorOSVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Reserved; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t Checksum; + uint16_t Subsystem; + uint16_t DLLCharacteristics; + uint32_t SizeOfStackReserve; + uint32_t SizeOfStackCommit; + uint32_t SizeOfHeapReserve; + uint32_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + data_directory DataDirectory[16]; +} pe_opt_header_t; + +typedef struct { + uint8_t SectionName[8]; + uint32_t Size; + uint32_t RVA; + uint32_t PhysicalSizeOnDisk; + uint32_t PhysicalLocationOnDisk; + uint8_t Reserved[12]; + uint32_t SectionFlags; +} pe_section_t; + +typedef struct { + uint32_t VirtualAddress; + uint32_t SizeOfBlock; +} relocation_t; + diff --git a/payloads/tianocoreboot/include/efi.h b/payloads/tianocoreboot/include/efi.h new file mode 100644 index 0000000000..1c589a12a4 --- /dev/null +++ b/payloads/tianocoreboot/include/efi.h @@ -0,0 +1,36 @@ +/* + * This file is part of the TianoCoreBoot project. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> + +#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1UL) +#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) + +typedef long intn_t; +typedef unsigned long uintn_t; + +#include <EfiTypes.h> +#include <EfiFirmwareVolumeHeader.h> +#include <PiFirmwareFile.h> +#include <PeiHob.h> +#include <MemoryAllocationHob.h> + +#define EFI_DXE_FILE_GUID \ + { 0xb1644c1a, 0xc16a, 0x4c5b, { 0x88, 0xde, 0xea, 0xfb, 0xa9, 0x7e, 0x74, 0xd8 } } + diff --git a/payloads/tianocoreboot/libpayload.config b/payloads/tianocoreboot/libpayload.config new file mode 100644 index 0000000000..c7c0720b9c --- /dev/null +++ b/payloads/tianocoreboot/libpayload.config @@ -0,0 +1,58 @@ +# +# Automatically generated make config: don't edit +# libpayload version: 0.2.0 +# Thu Jan 17 12:32:59 2013 +# + +# +# Generic Options +# +# CONFIG_EXPERIMENTAL is not set +# CONFIG_OBSOLETE is not set +# CONFIG_DEVELOPER is not set +# CONFIG_CHROMEOS is not set + +# +# Architecture Options +# +# CONFIG_ARCH_ARMV7 is not set +# CONFIG_ARCH_POWERPC is not set +CONFIG_ARCH_X86=y +# CONFIG_MEMMAP_RAM_ONLY is not set +# CONFIG_MULTIBOOT is not set + +# +# Standard Libraries +# +CONFIG_LIBC=y +# CONFIG_CURSES is not set +CONFIG_CBFS=y +CONFIG_LZMA=y + +# +# Console Options +# +# CONFIG_SKIP_CONSOLE_INIT is not set +CONFIG_CBMEM_CONSOLE=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_IOBASE=0x3f8 +# CONFIG_SERIAL_SET_SPEED is not set +# CONFIG_SERIAL_ACS_FALLBACK is not set +CONFIG_VIDEO_CONSOLE=y +CONFIG_VGA_VIDEO_CONSOLE=y +# CONFIG_GEODELX_VIDEO_CONSOLE is not set +CONFIG_COREBOOT_VIDEO_CONSOLE=y +# CONFIG_PC_KEYBOARD is not set + +# +# Drivers +# +# CONFIG_PCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC_PORT_EXTENDED_VIA is not set +# CONFIG_SPEAKER is not set +# CONFIG_STORAGE is not set +# CONFIG_USB is not set +# CONFIG_BIG_ENDIAN is not set +CONFIG_LITTLE_ENDIAN=y +CONFIG_ARCH_SPECIFIC_OPTIONS=y diff --git a/payloads/tianocoreboot/tianocoreboot.c b/payloads/tianocoreboot/tianocoreboot.c new file mode 100644 index 0000000000..04d2f32203 --- /dev/null +++ b/payloads/tianocoreboot/tianocoreboot.c @@ -0,0 +1,529 @@ +/* + * This file is part of the TianoCoreBoot project. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <libpayload.h> +#include <endian.h> +#include <cbfs.h> +#include <efi.h> +#include <coff.h> + +#define DXE_CORE_SIZE (256*1024) +#define UEFI_STACK_SIZE (128*1024) +#define HOB_LIST_SIZE (16*1024) + +#undef VERBOSE +#undef INVENTORY + +static void print_guid(EFI_GUID *guid) +{ + printf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); +} + +static void dump_uefi_firmware_volume_header(EFI_FIRMWARE_VOLUME_HEADER *fvh) +{ + printf("Found UEFI firmware volume.\n"); + printf(" GUID: "); + print_guid(&(fvh->FileSystemGuid)); + printf("\n"); + printf(" length: 0x%016llx\n", fvh->FvLength); +#ifdef VERBOSE + printf(" signature: 0x%08x\n", fvh->Signature); + printf(" attributes: 0x%08x\n", fvh->Attributes); + printf(" header length: 0x%04x\n", fvh->HeaderLength); + printf(" checksum: 0x%04x\n", fvh->Checksum); + printf(" revision: 0x%02x\n", fvh->Revision); + printf(" block map:\n"); + int i = 0; + EFI_FV_BLOCK_MAP_ENTRY *fbm = &(fvh->FvBlockMap[0]); + while (fbm[i].NumBlocks || fbm[i].BlockLength) { + printf(" %2d. numblocks = 0x%08x length = 0x%08x\n", + i+1, fbm[i].NumBlocks, fbm[i].BlockLength); + i++; + } +#endif + printf("\n"); +} + +#ifdef INVENTORY +static void dump_uefi_ffs_file_header(EFI_FFS_FILE_HEADER *file) +{ + int size; + +#ifdef VERBOSE + printf("Found FFS file:\n GUID: "); +#endif + print_guid(&(file->Name)); +#ifdef VERBOSE + printf("\n integrity check: %02x %02x\n", + file->IntegrityCheck.Checksum.Header, + file->IntegrityCheck.Checksum.File); + printf(" file type: "); +#else + printf(" "); +#endif + switch (file->Type) { + case EFI_FV_FILETYPE_RAW: printf("raw"); break; + case EFI_FV_FILETYPE_FREEFORM: printf("free form"); break; + case EFI_FV_FILETYPE_SECURITY_CORE: printf("security core"); break; + case EFI_FV_FILETYPE_PEI_CORE: printf("PEIM core"); break; + case EFI_FV_FILETYPE_DXE_CORE: printf("DXE core"); break; + case EFI_FV_FILETYPE_PEIM: printf("PEIM"); break; + case EFI_FV_FILETYPE_DRIVER: printf("driver"); break; + case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: printf("combined PEIM driver"); break; + case EFI_FV_FILETYPE_APPLICATION: printf("application"); break; + case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: printf("firmware volume image"); break; + case EFI_FV_FILETYPE_FFS_PAD: printf("FFS pad"); break; + default: printf("unknown"); + } +#ifdef VERBOSE + printf("\n"); + printf(" attributes: 0x%02x\n", file->Attributes); +#endif + size = file->Size[0] | (file->Size[1] << 8) | (file->Size[2] << 16); +#ifdef VERBOSE + printf(" size: 0x%06x\n", size); + printf(" state: 0x%02x\n", file->State); +#else + printf(" (%d bytes)\n", size); +#endif +} +#endif + +void *load_dxe_core(void *pe, void *target) +{ + dos_header_t *dos_hdr = (dos_header_t *)pe; + +#if VERBOSE + printf("Loading DXE core at %p\n", pe); +#endif + + if (*(uint16_t *)pe != 0x5a4d) { + printf("DXE core not a PE binary.\n"); + return NULL; + } + +#ifdef VERBOSE + printf("e_lfanew = 0x%08x\n", dos_hdr->e_lfanew); +#endif + + coff_header_t *coff_hdr = (coff_header_t *)(pe + dos_hdr->e_lfanew); +#ifdef VERBOSE + printf("Machine: %x\n", coff_hdr->Machine); + printf("NumberOfSections: %x\n", coff_hdr->NumberOfSections); + printf("TimeDateStamp: %x\n", coff_hdr->TimeDateStamp); + printf("PointerToSymbolTable: %x\n", coff_hdr->PointerToSymbolTable); + printf("NumberOfSymbols: %x\n", coff_hdr->NumberOfSymbols); + printf("SizeOfOptionalHeader: %x\n", coff_hdr->SizeOfOptionalHeader); + printf("Characteristics: %x\n", coff_hdr->Characteristics); +#endif + if (coff_hdr->Machine != 0x14c) { + printf("Only x86 supported right now.\n"); + return NULL; + } + + /* Right after the coff header */ + pe_opt_header_t *pe_hdr = (pe_opt_header_t *)(&coff_hdr[1]); + if (pe_hdr->signature != 267) { + printf("No valid PE opt header\n"); + return NULL; + } + +#ifdef VERBOSE + printf("\n"); + printf("MajorLinkerVersion: %x\n", pe_hdr->MajorLinkerVersion); + printf("MinorLinkerVersion: %x\n", pe_hdr->MinorLinkerVersion); + printf("SizeOfCode: %x\n", pe_hdr->SizeOfCode); + printf("SizeOfInitializedData: %x\n", pe_hdr->SizeOfInitializedData); + printf("SizeOfUninitializedData: %x\n", pe_hdr->SizeOfUninitializedData); + printf("AddressOfEntryPoint: %x\n", pe_hdr->AddressOfEntryPoint); + printf("BaseOfCode: %x\n", pe_hdr->BaseOfCode); + printf("BaseOfData: %x\n", pe_hdr->BaseOfData); + printf("ImageBase: %x\n", pe_hdr->ImageBase); + printf("SectionAlignment: %x\n", pe_hdr->SectionAlignment); + printf("FileAlignment: %x\n", pe_hdr->FileAlignment); + printf("MajorOSVersion: %x\n", pe_hdr->MajorOSVersion); + printf("MinorOSVersion: %x\n", pe_hdr->MinorOSVersion); + printf("MajorImageVersion: %x\n", pe_hdr->MajorImageVersion); + printf("MinorImageVersion: %x\n", pe_hdr->MinorImageVersion); + printf("MajorSubsystemVersion: %x\n", pe_hdr->MajorSubsystemVersion); + printf("MinorSubsystemVersion: %x\n", pe_hdr->MinorSubsystemVersion); + printf("Reserved: %x\n", pe_hdr->Reserved); + printf("SizeOfImage: %x\n", pe_hdr->SizeOfImage); + printf("SizeOfHeaders: %x\n", pe_hdr->SizeOfHeaders); + printf("Checksum: %x\n", pe_hdr->Checksum); + printf("Subsystem: %x\n", pe_hdr->Subsystem); + printf("DLLCharacteristics: %x\n", pe_hdr->DLLCharacteristics); + printf("SizeOfStackReserve: %x\n", pe_hdr->SizeOfStackReserve); + printf("SizeOfStackCommit: %x\n", pe_hdr->SizeOfStackCommit); + printf("SizeOfHeapReserve: %x\n", pe_hdr->SizeOfHeapReserve); + printf("SizeOfHeapCommit: %x\n", pe_hdr->SizeOfHeapCommit); + printf("LoaderFlags: %x\n", pe_hdr->LoaderFlags); + printf("NumberOfRvaAndSizes: %x\n", pe_hdr->NumberOfRvaAndSizes); +#endif + + if(pe_hdr->Subsystem != 0xb) { + printf("Not an EFI binary.\n"); + return NULL; + } + + int i; +#ifdef VERBOSE + for (i = 0; i < pe_hdr->NumberOfRvaAndSizes; i++) { + if (!pe_hdr->DataDirectory[i].Size) + continue; + printf("Data Directory %d\n", i+1); + printf(" VirtualAddress %x\n", pe_hdr->DataDirectory[i].VirtualAddress); + printf(" Size %x\n", pe_hdr->DataDirectory[i].Size); + } +#endif + + pe_section_t *sections = (pe_section_t *)(&pe_hdr[1]); + + int offset = 0; + + for (i = 0; i < coff_hdr->NumberOfSections; i++) { + int j; + printf(" Section %d: ", i); + for (j = 0; j < 8; j++) + printf("%c", sections[i].SectionName[j] ? sections[i].SectionName[j] : ' '); + + printf(" size=%08x rva=%08x in file=%08x/%08x flags=%08x\n", + sections[i].Size, sections[i].RVA, sections[i].PhysicalSizeOnDisk, + sections[i].PhysicalLocationOnDisk, sections[i].SectionFlags); + + if (!strncmp((char *)sections[i].SectionName, ".text", 6)) { + // .text section + // size=157a0 rva=240 size on disk=157a0 location on disk=240 flags=60000020 + memcpy(target, pe + sections[i].PhysicalLocationOnDisk, + sections[i].PhysicalSizeOnDisk); + offset = sections[i].RVA; + } else + if (!strncmp((char *)sections[i].SectionName, ".data", 6)) { + // .data section + // size=6820 rva=159e0 size on disk=6820 location on disk=159e0 flags=c0000040 + memcpy(target + sections[i].RVA - offset, pe + sections[i].PhysicalLocationOnDisk, + sections[i].PhysicalSizeOnDisk); + } else + if (!strncmp((char *)sections[i].SectionName, ".reloc", 7)) { + // .reloc section + // section 2: .reloc + // size=1080 rva=1c200 size on disk=1080 location on disk=1c200 flags=42000040 + relocation_t *reloc = (relocation_t *) + (pe + sections[i].PhysicalLocationOnDisk); + while (reloc && reloc->SizeOfBlock) { +#ifdef VERBOSE + printf("Relocation Block Virtual %08x Size %08x\n", + reloc->VirtualAddress, reloc->SizeOfBlock); +#endif + for (i = sizeof(relocation_t); i < reloc->SizeOfBlock; i+= 2) { + uint16_t r = *(uint16_t *)((void *)reloc + i); + switch (r>>12) { + case 3: +#ifdef VERBOSE + printf(" HIGHLOW %08x\n", + reloc->VirtualAddress + (r & 0xfff)); +#endif + *(uint32_t *)(target - offset + reloc->VirtualAddress + (r & 0xfff)) + += (unsigned long)target - offset; + break; + case 0: +#ifdef VERBOSE + printf(" ABSOLUTE %08x\n", r & 0xfff); +#endif + break; + default: + printf("Unknown relocation type %x\n", r); + return NULL; + } + } + + reloc = (relocation_t *)(((void *)reloc) + reloc->SizeOfBlock); + } + } else + if (!strncmp((char *)sections[i].SectionName, ".debug", 7)) { + // debug section, silently ignored. + } else { + printf("section type "); + for (j = 0; j < 8; j++) + if (sections[i].SectionName[j]) + printf("%c", sections[i].SectionName[j]); + printf(" unknown. ignored.\n"); + } + } + + return (target + pe_hdr->AddressOfEntryPoint - offset); +} + +void start_dxe_core(void *entry, void *stack, void *hoblist) +{ + printf("\nJumping to DXE core at %p\n", entry); + asm volatile( + "movl %1, %%esp\n" + "pushl %2\n" + "call *%0\n" + : : "r"(entry), "r"(stack), "r"(hoblist) : "esp" + ); +} + +static const EFI_HOB_HANDOFF_INFO_TABLE HandoffInformationTable = { + { EFI_HOB_TYPE_HANDOFF, sizeof(EFI_HOB_HANDOFF_INFO_TABLE), 0 }, + EFI_HOB_HANDOFF_TABLE_VERSION, + BOOT_WITH_FULL_CONFIGURATION, + 0 /* EfiMemoryTop */, + 0 /* EfiMemoryBottom */, + 0 /* EfiFreeMemoryTop */, + 0 /* EfiFreeMemoryBottom */, + 0 /* EfiEndOfHobList */ +}; + +static const EFI_HOB_FIRMWARE_VOLUME FirmwareVolume = { + { EFI_HOB_TYPE_FV, sizeof(EFI_HOB_FIRMWARE_VOLUME), 0 }, + 0 /* BaseAddress */, + 0 /* Length */ +}; + +/* 1..n */ +static const EFI_HOB_RESOURCE_DESCRIPTOR ResourceDescriptor = { + { EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof(EFI_HOB_RESOURCE_DESCRIPTOR), 0 }, + { 0 }, // owner EFI_GUID + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED, + 0, /* PhysicalStart */ + 0 /* ResourceLength */ +}; + +static const EFI_HOB_MEMORY_ALLOCATION_MODULE MemoryAllocationModule = { + { EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof(EFI_HOB_MEMORY_ALLOCATION_MODULE), 0 }, + { EFI_HOB_MEMORY_ALLOC_MODULE_GUID, 0 /* MemoryBaseAddress */, 0 /* MemoryLength */, EfiBootServicesCode, {0,0,0,0} }, + EFI_DXE_FILE_GUID, + 0x0 // ADDR EntryPoint +}; + +static const EFI_HOB_CPU Cpu = { + { EFI_HOB_TYPE_CPU, sizeof(EFI_HOB_CPU), 0 }, + 32, /* SizeOfMemorySpace, u8 */ + 16, /* SizeOfIoSpace */ + { 0,0,0,0,0,0 } +}; + +static const EFI_HOB_GENERIC_HEADER End = + { EFI_HOB_TYPE_END_OF_HOB_LIST, sizeof(EFI_HOB_GENERIC_HEADER), 0 }; + + +static void prepare_handoff_blocks(void *hoblist, EFI_FIRMWARE_VOLUME_HEADER *fvh, + unsigned long EfiMemoryTop, unsigned long EfiMemoryBottom, + unsigned long EfiFreeMemoryTop, unsigned long EfiFreeMemoryBottom, + unsigned long dxecore_base) +{ + void *ptr = hoblist; + int i; + + EFI_HOB_HANDOFF_INFO_TABLE *hit = (EFI_HOB_HANDOFF_INFO_TABLE *)ptr; + memcpy(ptr, &HandoffInformationTable, sizeof(HandoffInformationTable)); + ptr += sizeof(HandoffInformationTable); + + EFI_HOB_FIRMWARE_VOLUME *fv = (EFI_HOB_FIRMWARE_VOLUME *)ptr; + memcpy(ptr, &FirmwareVolume, sizeof(FirmwareVolume)); + ptr += sizeof(FirmwareVolume); + + for (i = 0; i < lib_sysinfo.n_memranges; i++) { + EFI_HOB_RESOURCE_DESCRIPTOR *resource; + if (lib_sysinfo.memrange[i].type != CB_MEM_RAM) + continue; + resource = (EFI_HOB_RESOURCE_DESCRIPTOR *)ptr; + memcpy(ptr, &ResourceDescriptor, sizeof(ResourceDescriptor)); + ptr += sizeof(ResourceDescriptor); + resource->PhysicalStart = lib_sysinfo.memrange[i].base; + resource->ResourceLength = lib_sysinfo.memrange[i].size; + } + + EFI_HOB_MEMORY_ALLOCATION_MODULE *allocation = (EFI_HOB_MEMORY_ALLOCATION_MODULE *)ptr; + memcpy(ptr, &MemoryAllocationModule, sizeof(MemoryAllocationModule)); + ptr += sizeof(MemoryAllocationModule); + + memcpy(ptr, &Cpu, sizeof(Cpu)); + ptr += sizeof(Cpu); + + memcpy(ptr, &End, sizeof(End)); + ptr += sizeof(Cpu); + + /* Handoff Information Table HOB */ + hit->EfiMemoryTop = EfiMemoryTop; + hit->EfiMemoryBottom = EfiMemoryBottom; + hit->EfiFreeMemoryTop = EfiFreeMemoryTop; + hit->EfiFreeMemoryBottom = EfiFreeMemoryBottom; + hit->EfiEndOfHobList = (unsigned long)ptr; + + /* Firmware Volume HOB */ + fv->BaseAddress = (unsigned long)fvh; + fv->Length = fvh->FvLength; + + allocation->MemoryAllocationHeader.MemoryBaseAddress = dxecore_base; + allocation->MemoryAllocationHeader.MemoryLength = DXE_CORE_SIZE; +} + +int main(void) +{ + int i; + struct cbfs_file *file; + void *tiano; + unsigned long long ram_seg_base = 0, ram_seg_size = 0; + EFI_FIRMWARE_VOLUME_HEADER *fvh = NULL; + EFI_PEI_HOB_POINTERS hoblist; + EFI_COMMON_SECTION_HEADER *dxecore = NULL; + + printf("\nTiano Core Loader v1.0\n"); + printf("Copyright (C) 2013 Google Inc. All rights reserved.\n\n"); + + printf("Memory Map (%d entries):\n", lib_sysinfo.n_memranges); + for (i = 0; i < lib_sysinfo.n_memranges; i++) { + printf(" %d. %016llx - %016llx [%02x]\n", i + 1, + lib_sysinfo.memrange[i].base, + lib_sysinfo.memrange[i].base + + lib_sysinfo.memrange[i].size - 1, + lib_sysinfo.memrange[i].type); + + /* Look for the last chunk of memory below 4G */ + if (lib_sysinfo.memrange[i].type == CB_MEM_RAM && + lib_sysinfo.memrange[i].base < 0xffffffff) { + ram_seg_base = lib_sysinfo.memrange[i].base; + ram_seg_size = lib_sysinfo.memrange[i].size; + } + } + printf("\n"); + + if (!ram_seg_base || ram_seg_size < (1024*1024)) { + printf("No usable RAM found.\n"); + halt(); + } + + /* Find the end of our memory block, align to 4K */ + unsigned long memory = (ram_seg_base + ram_seg_size) & 0xfffff000; + + /* 256K for DXE core. It's 116K on my system but you never know. */ + memory -= DXE_CORE_SIZE; + unsigned long dxecore_base = memory; + memory -= UEFI_STACK_SIZE; + unsigned long uefi_stack = memory; + + memory -= 1024*1024; // FIXME this should go away + unsigned long free_memory = memory; // FIXME this should go away + + memory -= HOB_LIST_SIZE; + unsigned long hoblist_base = memory; + + printf("DXE code: %08lx\n", dxecore_base); + printf("DXE stack: %08lx\n", uefi_stack); + printf("HOB list: %08lx\n\n", hoblist_base); + + /* Find UEFI firmware volume in CBFS */ + file = cbfs_find("fallback/tianocore.fd"); + if (!file) { + printf("Could not find fallback/tianocore.fd in CBFS.\n"); + halt(); + } + + tiano = CBFS_SUBHEADER(file); + while (tiano < (void *)CBFS_SUBHEADER(file) + ntohl(file->len)) { + /* Verify UEFI firmware volume consistency */ + fvh = (EFI_FIRMWARE_VOLUME_HEADER *)tiano; + if (fvh->Signature != 0x4856465f) { + printf("Not an UEFI firmware volume.\n"); + halt(); + } + + /* Dump UEFI firmware volume header */ + dump_uefi_firmware_volume_header(fvh); + + /* Dump UEFI firmware file headers */ + for (i = fvh->HeaderLength; i < fvh->FvLength;) { + int size; + EFI_FFS_FILE_HEADER *ffs; + + ffs = (EFI_FFS_FILE_HEADER *)(tiano + i); + + size = ffs->Size[0] | (ffs->Size[1] << 8) | (ffs->Size[2] << 16); + if (size == 0xffffff) + break; +#ifdef INVENTORY + printf("%08x - ", i); + dump_uefi_ffs_file_header(ffs); +#endif + + if (ffs->Type == EFI_FV_FILETYPE_DXE_CORE) { + dxecore = (EFI_COMMON_SECTION_HEADER *)&ffs[1]; +#ifndef INVENTORY + break; +#endif + } + + i = ALIGN(i + size, 8); + } + + tiano += fvh->FvLength; +#ifdef INVENTORY + printf("\n"); +#endif + } + + /* Prepare Hand Off Blocks */ + prepare_handoff_blocks((void *)hoblist_base, fvh, + // FIXME memory top, memory bottom + (ram_seg_base + ram_seg_size) & 0xfffff000, ram_seg_base, + // FIXME free memory top, free memory bottom + uefi_stack, free_memory, + dxecore_base); + hoblist.Raw = (void *)hoblist_base; + + if (!dxecore) { + printf("No DXE core found.\n"); + halt(); + } + + printf("Found DXE core at %p\n", &dxecore[1]); +#ifdef VERBOSE + int size = dxecore->Size[0] | (dxecore->Size[1] << 8) | (dxecore->Size[2] << 16); + printf(" size = %d, type = %x\n", size, dxecore->Type); +#endif + + void *pe = (void *)&dxecore[1]; + + void *entry; + entry = load_dxe_core(pe, (void *)dxecore_base); + + if (!entry) { + printf("Could not load DXE code.\n"); + halt(); + } + + start_dxe_core(entry, (void *)(uefi_stack + UEFI_STACK_SIZE - 4), hoblist.Raw); + + printf("The end.\n"); + halt(); + + return 0; +} + +PAYLOAD_INFO(name, "TianoCoreBoot"); +PAYLOAD_INFO(listname, "Tiano Core"); +PAYLOAD_INFO(desc, "Tiano Core Loader"); |