From cc5b3446624cf85e13a8130a524e81360c5f4239 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Tue, 15 Jan 2013 17:02:58 -0800 Subject: [PATCH] Project PIANO aka tianocoreboot This is a Tiano Core loader payload based on libpayload. It will load a Tiano Core DXE core from an UEFI firmware volume stored in CBFS. Currently Tiano Core dies because it does not find all the UEFI services it needs: coreboot-4.0-3316-gc5c9ff8-dirty Mon Jan 28 15:37:12 PST 2013 starting... [..] Tiano Core Loader v1.0 Copyright (C) 2013 Google Inc. All rights reserved. Memory Map (5 entries): 1. 0000000000000000 - 0000000000000fff [10] 2. 0000000000001000 - 000000000009ffff [01] 3. 00000000000c0000 - 0000000003ebffff [01] 4. 0000000003ec0000 - 0000000003ffffff [10] 5. 00000000ff800000 - 00000000ffffffff [02] DXE code: 03e80000 DXE stack: 03e60000 HOB list: 03d5c000 Found UEFI firmware volume. GUID: 8c8ce578-8a3d-4f1c-9935-896185c32dd3 length: 0x0000000000260000 Found DXE core at 0xffc14e0c Section 0: .text size=000158a0 rva=00000240 in file=000158a0/00000240 flags=60000020 Section 1: .data size=00006820 rva=00015ae0 in file=00006820/00015ae0 flags=c0000040 Section 2: .reloc size=000010a0 rva=0001c300 in file=000010a0/0001c300 flags=42000040 Jumping to DXE core at 0x3e80000 InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 3E96708 HOBLIST address in DXE = 0x3E56010 Memory Allocation 0x00000003 0x3E80000 - 0x3EBFFFF FV Hob 0xFFC14D78 - 0xFFE74D77 InstallProtocolInterface: D8117CFE-94A6-11D4-9A3A-0090273FC14D 3E95EA0 InstallProtocolInterface: EE4E5898-3914-4259-9D6E-DC7BD79403CF 3E9630C Security Arch Protocol not present!! CPU Arch Protocol not present!! Metronome Arch Protocol not present!! Timer Arch Protocol not present!! Bds Arch Protocol not present!! Watchdog Timer Arch Protocol not present!! Runtime Arch Protocol not present!! Variable Arch Protocol not present!! Variable Write Arch Protocol not present!! Capsule Arch Protocol not present!! Monotonic Counter Arch Protocol not present!! Reset Arch Protocol not present!! Real Time Clock Arch Protocol not present!! ASSERT_EFI_ERROR (Status = Not Found) ASSERT /home/reinauer/svn/Tiano/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c(461): !EFI_ERROR (Status) Change-Id: I14068e9a28ff67ab1bf03105d56dab2e8be7b230 Signed-off-by: Stefan Reinauer Reviewed-on: http://review.coreboot.org/2154 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Ronald G. Minnich --- payloads/tianocoreboot/Makefile | 80 +++ payloads/tianocoreboot/README | 27 + payloads/tianocoreboot/include/BootMode.h | 38 ++ .../include/EfiFirmwareVolumeHeader.h | 213 +++++++ payloads/tianocoreboot/include/EfiTypes.h | 297 ++++++++++ .../include/MemoryAllocationHob.h | 34 ++ payloads/tianocoreboot/include/PeiHob.h | 257 +++++++++ .../tianocoreboot/include/PiFirmwareFile.h | 494 ++++++++++++++++ payloads/tianocoreboot/include/coff.h | 106 ++++ payloads/tianocoreboot/include/efi.h | 36 ++ payloads/tianocoreboot/libpayload.config | 58 ++ payloads/tianocoreboot/tianocoreboot.c | 529 ++++++++++++++++++ src/Kconfig | 20 + src/arch/x86/Makefile.inc | 14 + 14 files changed, 2203 insertions(+) create mode 100644 payloads/tianocoreboot/Makefile create mode 100644 payloads/tianocoreboot/README create mode 100644 payloads/tianocoreboot/include/BootMode.h create mode 100644 payloads/tianocoreboot/include/EfiFirmwareVolumeHeader.h create mode 100644 payloads/tianocoreboot/include/EfiTypes.h create mode 100644 payloads/tianocoreboot/include/MemoryAllocationHob.h create mode 100644 payloads/tianocoreboot/include/PeiHob.h create mode 100644 payloads/tianocoreboot/include/PiFirmwareFile.h create mode 100644 payloads/tianocoreboot/include/coff.h create mode 100644 payloads/tianocoreboot/include/efi.h create mode 100644 payloads/tianocoreboot/libpayload.config create mode 100644 payloads/tianocoreboot/tianocoreboot.c 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.
+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.
+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.
+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.
+ 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.
+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.
+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 + +#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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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"); diff --git a/src/Kconfig b/src/Kconfig index 2c97327fb6..e24eb78037 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -495,6 +495,15 @@ config PAYLOAD_FILO See http://coreboot.org/Payloads for more information. +config PAYLOAD_TIANOCORE + bool "Tiano Core" + help + Select this option if you want to build a coreboot image + with a Tiano Core payload. If you don't know what this is + about, just leave it enabled. + + See http://coreboot.org/Payloads for more information. + endchoice choice @@ -527,6 +536,13 @@ config FILO_MASTER Newest FILO version endchoice +config TIANOCORE_FILE + string "Tianocore FILE" + depends on PAYLOAD_TIANOCORE + default "DXEFV.Fv" + help + TBD + config PAYLOAD_FILE string "Payload path and filename" depends on PAYLOAD_ELF @@ -542,6 +558,10 @@ config PAYLOAD_FILE depends on PAYLOAD_FILO default "payloads/external/FILO/filo/build/filo.elf" +config PAYLOAD_FILE + depends on PAYLOAD_TIANOCORE + default "$(obj)/tiano/tianocoreboot.elf" + # TODO: Defined if no payload? Breaks build? config COMPRESSED_PAYLOAD_LZMA bool "Use LZMA compression for payloads" diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc index 190f7cb747..e498121dbe 100644 --- a/src/arch/x86/Makefile.inc +++ b/src/arch/x86/Makefile.inc @@ -48,6 +48,9 @@ endif ifeq ($(CONFIG_PAYLOAD_FILO),y) COREBOOT_ROM_DEPENDENCIES+=filo endif +ifeq ($(CONFIG_PAYLOAD_TIANOCORE),y) +COREBOOT_ROM_DEPENDENCIES+=tianocore +endif ifeq ($(CONFIG_AP_CODE_IN_CAR),y) COREBOOT_ROM_DEPENDENCIES+=$(objcbfs)/coreboot_ap.elf endif @@ -99,6 +102,12 @@ ifeq ($(CONFIG_PAYLOAD_FILO),y) @printf " PAYLOAD FILO (internal, compression: $(CBFS_PAYLOAD_COMPRESS_FLAG))\n" $(CBFSTOOL) $@.tmp add-payload -f $(CONFIG_PAYLOAD_FILE) -n $(CONFIG_CBFS_PREFIX)/payload -c $(CBFS_PAYLOAD_COMPRESS_FLAG) endif +ifeq ($(CONFIG_PAYLOAD_TIANOCORE),y) + @printf " PAYLOAD Tiano Core (internal, compression: $(CBFS_PAYLOAD_COMPRESS_FLAG))\n" + $(CBFSTOOL) $@.tmp add-payload -f $(CONFIG_PAYLOAD_FILE) -n $(CONFIG_CBFS_PREFIX)/payload -c $(CBFS_PAYLOAD_COMPRESS_FLAG) + @printf " PAYLOAD Tiano Core FD $(CONFIG_TIANOCORE_FILE)\n" + $(CBFSTOOL) $@.tmp add -f $(CONFIG_TIANOCORE_FILE) -n $(CONFIG_CBFS_PREFIX)/tianocore.fd -t raw +endif ifeq ($(CONFIG_INCLUDE_CONFIG_FILE),y) @printf " CONFIG $(DOTCONFIG)\n" if [ -f $(DOTCONFIG) ]; then \ @@ -408,3 +417,8 @@ filo: CONFIG_FILO_MASTER=$(CONFIG_FILO_MASTER) \ CONFIG_FILO_STABLE=$(CONFIG_FILO_STABLE) +tianocore: + $(MAKE) -C payloads/tianocoreboot \ + CC="$(CC)" AS="$(AS)" OBJCOPY="$(OBJCOPY)" \ + obj=$(abspath $(obj))/tiano +