]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
x86: Initial import from Intel FSP release for Queensbay platform
authorBin Meng <bmeng.cn@gmail.com>
Fri, 12 Dec 2014 13:05:28 +0000 (21:05 +0800)
committerSimon Glass <sjg@chromium.org>
Sun, 14 Dec 2014 05:32:05 +0000 (22:32 -0700)
This is the initial import from Intel FSP release for Queensbay
platform (Tunnel Creek processor and Topcliff Platform Controller
Hub), which can be downloaded from Intel website.

For more details, check http://www.intel.com/fsp.

Note: U-Boot coding convention was applied to these codes, so it
looks completely different from the original Intel release.
Also update FSP support codes license header to use SPDX ID.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
12 files changed:
arch/x86/cpu/queensbay/fsp_configs.c [new file with mode: 0644]
arch/x86/cpu/queensbay/fsp_support.c [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h [new file with mode: 0644]
arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h [new file with mode: 0644]

diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c
new file mode 100644 (file)
index 0000000..a7bb314
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#include <types.h>
+#include <string.h>
+#include "fsp_support.h"
+
+void update_fsp_upd(struct upd_region_t *fsp_upd)
+{
+       /* Override any UPD setting if required */
+
+       /* Uncomment the line below to enable DEBUG message */
+       /* fsp_upd->serial_dbgport_type = 1; */
+
+       /* Examples on how to initialize the pointers in UPD region */
+       /* fsp_upd->pcd_example = (EXAMPLE_DATA *)&example; */
+}
diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c
new file mode 100644 (file)
index 0000000..2048030
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#include <types.h>
+#include <string.h>
+#include "fsp_support.h"
+
+/**
+ * Reads a 64-bit value from memory that may be unaligned.
+ *
+ * This function returns the 64-bit value pointed to by buf. The function
+ * guarantees that the read operation does not produce an alignment fault.
+ *
+ * If the buf is NULL, then ASSERT().
+ *
+ * @buf: Pointer to a 64-bit value that may be unaligned.
+ *
+ * @return: The 64-bit value read from buf.
+ */
+static u64 read_unaligned64(const u64 *buf)
+{
+       ASSERT(buf != NULL);
+
+       return *buf;
+}
+
+/**
+ * Compares two GUIDs
+ *
+ * If the GUIDs are identical then TRUE is returned.
+ * If there are any bit differences in the two GUIDs, then FALSE is returned.
+ *
+ * If guid1 is NULL, then ASSERT().
+ * If guid2 is NULL, then ASSERT().
+ *
+ * @guid1:        A pointer to a 128 bit GUID.
+ * @guid2:        A pointer to a 128 bit GUID.
+ *
+ * @retval TRUE:  guid1 and guid2 are identical.
+ * @retval FALSE: guid1 and guid2 are not identical.
+ */
+static unsigned char compare_guid(const struct efi_guid_t *guid1,
+                                 const struct efi_guid_t *guid2)
+{
+       u64 guid1_low;
+       u64 guid2_low;
+       u64 guid1_high;
+       u64 guid2_high;
+
+       guid1_low  = read_unaligned64((const u64 *)guid1);
+       guid2_low  = read_unaligned64((const u64 *)guid2);
+       guid1_high = read_unaligned64((const u64 *)guid1 + 1);
+       guid2_high = read_unaligned64((const u64 *)guid2 + 1);
+
+       return (unsigned char)(guid1_low == guid2_low && guid1_high == guid2_high);
+}
+
+u32 __attribute__((optimize("O0"))) find_fsp_header(void)
+{
+       volatile register u8 *fsp asm("eax");
+
+       /* Initalize the FSP base */
+       fsp = (u8 *)CONFIG_FSP_LOCATION;
+
+       /* Check the FV signature, _FVH */
+       if (((struct fv_header_t *)fsp)->sign == 0x4856465F) {
+               /* Go to the end of the FV header and align the address */
+               fsp += ((struct fv_header_t *)fsp)->ext_hdr_off;
+               fsp += ((struct fv_ext_header_t *)fsp)->ext_hdr_size;
+               fsp  = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8);
+       } else {
+               fsp  = 0;
+       }
+
+       /* Check the FFS GUID */
+       if (fsp &&
+           (((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[0] == 0x912740BE) &&
+           (((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[1] == 0x47342284) &&
+           (((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[2] == 0xB08471B9) &&
+           (((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[3] == 0x0C3F3527)) {
+               /* Add the FFS header size to find the raw section header */
+               fsp += sizeof(struct ffs_file_header_t);
+       } else {
+               fsp = 0;
+       }
+
+       if (fsp &&
+           ((struct raw_section_t *)fsp)->type == EFI_SECTION_RAW) {
+               /* Add the raw section header size to find the FSP header */
+               fsp += sizeof(struct raw_section_t);
+       } else {
+               fsp = 0;
+       }
+
+       return (u32)fsp;
+}
+
+#ifdef __PRE_RAM__
+void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list)
+{
+       u32 stack_len;
+       u32 stack_base;
+       u32 stack_top;
+
+       ASSERT(status == 0);
+
+       /* Get the migrated stack in normal memory */
+       stack_base = (u32)get_bootloader_tmp_mem(hob_list, &stack_len);
+       ASSERT(stack_base != 0);
+       stack_top  = stack_base + stack_len - sizeof(u32);
+
+       /*
+        * Old stack base is stored at the very end of the stack top,
+        * use it to calculate the migrated shared data base
+        */
+       shared_data = (struct shared_data_t *)(stack_base +
+                       ((u32)shared_data - *(u32 *)stack_top));
+
+       /* The boot loader main function entry */
+       bl_main_continue(hob_list, shared_data);
+}
+
+void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
+{
+       struct shared_data_t shared_data;
+       fsp_init_f init;
+       struct fsp_init_params_t params;
+       struct fspinit_rtbuf_t rt_buf;
+       struct vpd_region_t *fsp_vpd;
+       struct fsp_header_t *fsp_hdr;
+       struct fsp_init_params_t *params_ptr;
+       struct upd_region_t *fsp_upd;
+
+       fsp_hdr = (struct fsp_header_t *)find_fsp_header();
+       if (fsp_hdr == NULL) {
+               /* No valid FSP info header was found */
+               ASSERT(FALSE);
+       }
+
+       fsp_upd = (struct upd_region_t *)&shared_data.fsp_upd;
+       memset((void *)&rt_buf, 0, sizeof(struct fspinit_rtbuf_t));
+
+       /* Reserve a gap in stack top */
+       rt_buf.common.stack_top = (u32 *)stack_top - 32;
+       rt_buf.common.boot_mode = boot_mode;
+       rt_buf.common.upd_data = (struct upd_region_t *)fsp_upd;
+
+       /* Get VPD region start */
+       fsp_vpd = (struct vpd_region_t *)(fsp_hdr->img_base +
+                       fsp_hdr->cfg_region_off);
+
+       /* Verifify the VPD data region is valid */
+       ASSERT((fsp_vpd->img_rev == VPD_IMAGE_REV) &&
+              (fsp_vpd->sign == VPD_IMAGE_ID));
+
+       /* Copy default data from Flash */
+       memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
+              sizeof(struct upd_region_t));
+
+       /* Verifify the UPD data region is valid */
+       ASSERT(fsp_upd->terminator == 0x55AA);
+
+       /* Override any UPD setting if required */
+       update_fsp_upd(fsp_upd);
+
+       memset((void *)&params, 0, sizeof(struct fsp_init_params_t));
+       params.nvs_buf = nvs_buf;
+       params.rt_buf = (struct fspinit_rtbuf_t *)&rt_buf;
+       params.continuation = (fsp_continuation_f)asm_continuation;
+
+       init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init);
+       params_ptr = &params;
+
+       shared_data.fsp_hdr = fsp_hdr;
+       shared_data.stack_top = (u32 *)stack_top;
+
+       /*
+        * Use ASM code to ensure the register value in EAX & ECX
+        * will be passed into BlContinuationFunc
+        */
+       asm volatile (
+               "pushl  %0;"
+               "call   *%%eax;"
+               ".global asm_continuation;"
+               "asm_continuation:;"
+               "popl   %%eax;" /* pop out return address */
+               "pushl  %%ecx;" /* push shared_data pointer */
+               "pushl  %%eax;" /* push back return address */
+               "jmp    fsp_continue;"
+               : : "m"(params_ptr), "a"(init), "c"(&shared_data)
+       );
+
+       /*
+        * Should never get here.
+        * Control will continue from romstage_main_continue_asm.
+        * This line below is to prevent the compiler from optimizing
+        * structure intialization.
+        */
+       init(&params);
+
+       /*
+        * Should never return.
+        * Control will continue from ContinuationFunc
+        */
+       ASSERT(FALSE);
+}
+
+#else
+
+u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase)
+{
+       fsp_notify_f notify;
+       struct fsp_notify_params_t params;
+       u32 status;
+
+       if (!fsp_hdr)
+               fsp_hdr = (struct fsp_header_t *)find_fsp_header();
+
+       if (fsp_hdr == NULL) {
+               /* No valid FSP info header */
+               ASSERT(FALSE);
+       }
+
+       notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify);
+       params.phase = phase;
+       status = notify(&params);
+
+       return status;
+}
+
+#endif  /* __PRE_RAM__ */
+
+u32 get_usable_lowmem_top(const void *hob_list)
+{
+       union hob_pointers_t hob;
+       phys_addr_t phys_start;
+       u32 top;
+
+       /* Get the HOB list for processing */
+       hob.raw = (void *)hob_list;
+
+       /* * Collect memory ranges */
+       top = 0x100000;
+       while (!END_OF_HOB(hob)) {
+               if (hob.hdr->type == HOB_TYPE_RES_DESC) {
+                       if (hob.res_desc->type == RES_SYS_MEM) {
+                               phys_start = hob.res_desc->phys_start;
+                               /* Need memory above 1MB to be collected here */
+                               if (phys_start >= 0x100000 &&
+                                   phys_start < (phys_addr_t)0x100000000)
+                                       top += (u32)(hob.res_desc->len);
+                       }
+               }
+               hob.raw = GET_NEXT_HOB(hob);
+       }
+
+       return top;
+}
+
+u64 get_usable_highmem_top(const void *hob_list)
+{
+       union hob_pointers_t hob;
+       phys_addr_t phys_start;
+       u64 top;
+
+       /* Get the HOB list for processing */
+       hob.raw = (void *)hob_list;
+
+       /* Collect memory ranges */
+       top = 0x100000000;
+       while (!END_OF_HOB(hob)) {
+               if (hob.hdr->type == HOB_TYPE_RES_DESC) {
+                       if (hob.res_desc->type == RES_SYS_MEM) {
+                               phys_start = hob.res_desc->phys_start;
+                               /* Need memory above 1MB to be collected here */
+                               if (phys_start >= (phys_addr_t)0x100000000)
+                                       top += (u32)(hob.res_desc->len);
+                       }
+               }
+               hob.raw = GET_NEXT_HOB(hob);
+       }
+
+       return top;
+}
+
+u64 get_fsp_reserved_mem_from_guid(const void *hob_list, u64 *len,
+                                  struct efi_guid_t *guid)
+{
+       union hob_pointers_t hob;
+
+       /* Get the HOB list for processing */
+       hob.raw = (void *)hob_list;
+
+       /* Collect memory ranges */
+       while (!END_OF_HOB(hob)) {
+               if (hob.hdr->type == HOB_TYPE_RES_DESC) {
+                       if (hob.res_desc->type == RES_MEM_RESERVED) {
+                               if (compare_guid(&hob.res_desc->owner, guid)) {
+                                       if (len)
+                                               *len = (u32)(hob.res_desc->len);
+
+                                       return (u64)(hob.res_desc->phys_start);
+                               }
+                       }
+               }
+               hob.raw = GET_NEXT_HOB(hob);
+       }
+
+       return 0;
+}
+
+u32 get_fsp_reserved_mem(const void *hob_list, u32 *len)
+{
+       const struct efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID;
+       u64 length;
+       u32 base;
+
+       base = (u32)get_fsp_reserved_mem_from_guid(hob_list,
+                       &length, (struct efi_guid_t *)&guid);
+       if ((len != 0) && (base != 0))
+               *len = (u32)length;
+
+       return base;
+}
+
+u32 get_tseg_reserved_mem(const void *hob_list, u32 *len)
+{
+       const struct efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID;
+       u64 length;
+       u32 base;
+
+       base = (u32)get_fsp_reserved_mem_from_guid(hob_list,
+                       &length, (struct efi_guid_t *)&guid);
+       if ((len != 0) && (base != 0))
+               *len = (u32)length;
+
+       return base;
+}
+
+void *get_next_hob(u16 type, const void *hob_list)
+{
+       union hob_pointers_t hob;
+
+       ASSERT(hob_list != NULL);
+
+       hob.raw = (u8 *)hob_list;
+
+       /* Parse the HOB list until end of list or matching type is found */
+       while (!END_OF_HOB(hob)) {
+               if (hob.hdr->type == type)
+                       return hob.raw;
+
+               hob.raw = GET_NEXT_HOB(hob);
+       }
+
+       return NULL;
+}
+
+void *get_next_guid_hob(const struct efi_guid_t *guid, const void *hob_list)
+{
+       union hob_pointers_t hob;
+
+       hob.raw = (u8 *)hob_list;
+       while ((hob.raw = get_next_hob(HOB_TYPE_GUID_EXT,
+                       hob.raw)) != NULL) {
+               if (compare_guid(guid, &hob.guid->name))
+                       break;
+               hob.raw = GET_NEXT_HOB(hob);
+       }
+
+       return hob.raw;
+}
+
+void *get_guid_hob_data(const void *hob_list, u32 *len, struct efi_guid_t *guid)
+{
+       u8 *guid_hob;
+
+       guid_hob = get_next_guid_hob(guid, hob_list);
+       if (guid_hob == NULL) {
+               return NULL;
+       } else {
+               if (len)
+                       *len = GET_GUID_HOB_DATA_SIZE(guid_hob);
+
+               return GET_GUID_HOB_DATA(guid_hob);
+       }
+}
+
+void *get_fsp_nvs_data(const void *hob_list, u32 *len)
+{
+       const struct efi_guid_t guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
+
+       return get_guid_hob_data(hob_list, len, (struct efi_guid_t *)&guid);
+}
+
+void *get_bootloader_tmp_mem(const void *hob_list, u32 *len)
+{
+       const struct efi_guid_t guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID;
+
+       return get_guid_hob_data(hob_list, len, (struct efi_guid_t *)&guid);
+}
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h
new file mode 100644 (file)
index 0000000..25b938f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_API_H__
+#define __FSP_API_H__
+
+/*
+ * FspInit continuation function prototype.
+ * Control will be returned to this callback function after FspInit API call.
+ */
+typedef void (*fsp_continuation_f)(u32 status, void *hob_list);
+
+#pragma pack(1)
+
+struct fsp_init_params_t {
+       /* Non-volatile storage buffer pointer */
+       void                    *nvs_buf;
+       /* Runtime buffer pointer */
+       void                    *rt_buf;
+       /* Continuation function address */
+       fsp_continuation_f      continuation;
+};
+
+struct common_buf_t {
+       /*
+        * Stack top pointer used by the bootloader. The new stack frame will be
+        * set up at this location after FspInit API call.
+        */
+       u32     *stack_top;
+       u32     boot_mode;      /* Current system boot mode */
+       void    *upd_data;      /* User platform configuraiton data region */
+       u32     reserved[7];    /* Reserved */
+};
+
+enum fsp_phase_t {
+       /* Notification code for post PCI enuermation */
+       INIT_PHASE_PCI  = 0x20,
+       /* Notification code before transfering control to the payload */
+       INIT_PHASE_BOOT = 0x40
+};
+
+struct fsp_notify_params_t {
+       /* Notification phase used for NotifyPhase API */
+       enum fsp_phase_t        phase;
+};
+
+#pragma pack()
+
+/* FspInit API function prototype */
+typedef u32 (*fsp_init_f)(struct fsp_init_params_t *param);
+
+/* FspNotify API function prototype */
+typedef u32 (*fsp_notify_f)(struct fsp_notify_params_t *param);
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h
new file mode 100644 (file)
index 0000000..c3f8b49
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_BOOT_MODE_H__
+#define __FSP_BOOT_MODE_H__
+
+/* 0x21 - 0xf..f are reserved */
+#define BOOT_FULL_CONFIG               0x00
+#define BOOT_MINIMAL_CONFIG            0x01
+#define BOOT_NO_CONFIG_CHANGES         0x02
+#define BOOT_FULL_CONFIG_PLUS_DIAG     0x03
+#define BOOT_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
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h
new file mode 100644 (file)
index 0000000..1f73680
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_FFS_H__
+#define __FSP_FFS_H__
+
+#pragma pack(1)
+
+/* Used to verify the integrity of the file */
+union ffs_integrity_t {
+       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.
+                */
+               u8      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.
+                */
+               u8      file;
+       } checksum;
+
+       /* This is the full 16 bits of the IntegrityCheck field */
+       u16     checksum16;
+};
+
+/*
+ * Each file begins with the header that describe the
+ * contents and state of the files.
+ */
+struct ffs_file_header_t {
+       /*
+        * This GUID is the file name.
+        * It is used to uniquely identify the file.
+        */
+       struct efi_guid_t       name;
+       /* Used to verify the integrity of the file */
+       union ffs_integrity_t   integrity;
+       /* Identifies the type of file */
+       u8                      type;
+       /* Declares various file attribute bits */
+       u8                      attr;
+       /* The length of the file in bytes, including the FFS header */
+       u8                      size[3];
+       /*
+        * Used to track the state of the file throughout the life of
+        * the file from creation to deletion.
+        */
+       u8                      state;
+};
+
+struct ffs_file_header2_t {
+       /*
+        * 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_FILE_TYPE_FFS_PAD.
+        */
+       struct efi_guid_t       name;
+       /* Used to verify the integrity of the file */
+       union ffs_integrity_t   integrity;
+       /* Identifies the type of file */
+       u8                      type;
+       /* Declares various file attribute bits */
+       u8                      attr;
+       /*
+        * The length of the file in bytes, including the FFS header.
+        * The length of the file data is either
+        * (size - sizeof(struct ffs_file_header_t)). This calculation means a
+        * zero-length file has a size of 24 bytes, which is
+        * sizeof(struct ffs_file_header_t). 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.
+        */
+       u8                      size[3];
+       /*
+        * Used to track the state of the file throughout the life of
+        * the file from creation to deletion.
+        */
+       u8                      state;
+       /*
+        * If FFS_ATTRIB_LARGE_FILE is set in attr, then ext_size exists
+        * and size must be set to zero.
+        * If FFS_ATTRIB_LARGE_FILE is not set then
+        * struct ffs_file_header_t is used.
+        */
+       u32                     ext_size;
+};
+
+/*
+ * 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 */
+struct raw_section_t {
+       /*
+        * A 24-bit unsigned integer that contains the total size of
+        * the section in bytes, including the EFI_COMMON_SECTION_HEADER.
+        */
+       u8      size[3];
+       u8      type;
+};
+
+struct raw_section2_t {
+       /*
+        * A 24-bit unsigned integer that contains the total size of
+        * the section in bytes, including the EFI_COMMON_SECTION_HEADER.
+        */
+       u8      size[3];
+       u8      type;
+       /*
+        * If size is 0xFFFFFF, then ext_size contains the size of
+        * the section. If size is not equal to 0xFFFFFF, then this
+        * field does not exist.
+        */
+       u32     ext_size;
+};
+
+#pragma pack()
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h
new file mode 100644 (file)
index 0000000..01300db
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_FV___
+#define __FSP_FV___
+
+/* Value of EFI_FV_FILE_ATTRIBUTES */
+#define EFI_FV_FILE_ATTR_ALIGNMENT     0x0000001F
+#define EFI_FV_FILE_ATTR_FIXED         0x00000100
+#define EFI_FV_FILE_ATTR_MEMORY_MAPPED 0x00000200
+
+/* Attributes bit definitions */
+#define EFI_FVB2_READ_DISABLED_CAP     0x00000001
+#define EFI_FVB2_READ_ENABLED_CAP      0x00000002
+#define EFI_FVB2_READ_STATUS           0x00000004
+#define EFI_FVB2_WRITE_DISABLED_CAP    0x00000008
+#define EFI_FVB2_WRITE_ENABLED_CAP     0x00000010
+#define EFI_FVB2_WRITE_STATUS          0x00000020
+#define EFI_FVB2_LOCK_CAP              0x00000040
+#define EFI_FVB2_LOCK_STATUS           0x00000080
+#define EFI_FVB2_STICKY_WRITE          0x00000200
+#define EFI_FVB2_MEMORY_MAPPED         0x00000400
+#define EFI_FVB2_ERASE_POLARITY                0x00000800
+#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
+
+struct fv_blkmap_entry_t {
+       /* The number of sequential blocks which are of the same size */
+       u32     num_blocks;
+       /* The size of the blocks */
+       u32     length;
+};
+
+/* Describes the features and layout of the firmware volume */
+struct fv_header_t {
+       /*
+        * The first 16 bytes are reserved to allow for the reset vector of
+        * processors whose reset vector is at address 0.
+        */
+       u8                      zero_vec[16];
+       /*
+        * Declares the file system with which the firmware volume
+        * is formatted.
+        */
+       struct efi_guid_t       fs_guid;
+       /*
+        * Length in bytes of the complete firmware volume, including
+        * the header.
+        */
+       u64                     fv_len;
+       /* Set to EFI_FVH_SIGNATURE */
+       u32                     sign;
+       /*
+        * Declares capabilities and power-on defaults for the firmware
+        * volume.
+        */
+       u32                     attr;
+       /* Length in bytes of the complete firmware volume header */
+       u16                     hdr_len;
+       /*
+        * A 16-bit checksum of the firmware volume header.
+        * A valid header sums to zero.
+        */
+       u16                     checksum;
+       /*
+        * Offset, relative to the start of the header, of the extended
+        * header (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is
+        * no extended header.
+        */
+       u16                     ext_hdr_off;
+       /* This field must always be set to zero */
+       u8                      reserved[1];
+       /*
+        * Set to 2. Future versions of this specification may define new
+        * header fields and will increment the Revision field accordingly.
+        */
+       u8                      rev;
+       /*
+        * An array of run-length encoded FvBlockMapEntry structures.
+        * The array is terminated with an entry of {0,0}.
+        */
+       struct fv_blkmap_entry_t        block_map[1];
+};
+
+#define EFI_FVH_SIGNATURE SIGNATURE_32('_', 'F', 'V', 'H')
+
+/* Firmware Volume Header Revision definition */
+#define EFI_FVH_REVISION       0x02
+
+/* Extension header pointed by ExtHeaderOffset of volume header */
+struct fv_ext_header_t {
+       /* firmware volume name */
+       struct efi_guid_t       fv_name;
+       /* Size of the rest of the extension header including this structure */
+       u32                     ext_hdr_size;
+};
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h
new file mode 100644 (file)
index 0000000..44c0f90
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_HOB_H__
+#define __FSP_HOB_H__
+
+/* Type of HOB Header */
+#define HOB_TYPE_MEM_ALLOC     0x0002
+#define HOB_TYPE_RES_DESC      0x0003
+#define HOB_TYPE_GUID_EXT      0x0004
+#define HOB_TYPE_UNUSED                0xFFFE
+#define HOB_TYPE_EOH           0xFFFF
+
+/*
+ * Describes the format and size of the data inside the HOB.
+ * All HOBs must contain this generic HOB header.
+ */
+struct hob_header_t {
+       u16     type;           /* HOB type */
+       u16     len;            /* HOB length */
+       u32     reserved;       /* always zero */
+};
+
+/* Enumeration of memory types introduced in UEFI */
+enum efi_mem_type_t {
+       EFI_RESERVED_MEMORY_TYPE,
+       /*
+        * The code portions of a loaded application.
+        * (Note that UEFI OS loaders are UEFI applications.)
+        */
+       EFI_LOADER_CODE,
+       /*
+        * The data portions of a loaded application and
+        * the default data allocation type used by an application
+        * to allocate pool memory.
+        */
+       EFI_LOADER_DATA,
+       /* The code portions of a loaded Boot Services Driver */
+       EFI_BOOT_SERVICES_CODE,
+       /*
+        * The data portions of a loaded Boot Serves Driver and
+        * the default data allocation type used by a Boot Services
+        * Driver to allocate pool memory.
+        */
+       EFI_BOOT_SERVICES_DATA,
+       /* The code portions of a loaded Runtime Services Driver */
+       EFI_RUNTIME_SERVICES_CODE,
+       /*
+        * The data portions of a loaded Runtime Services Driver and
+        * the default data allocation type used by a Runtime Services
+        * Driver to allocate pool memory.
+        */
+       EFI_RUNTIME_SERVICES_DATA,
+       /* Free (unallocated) memory */
+       EFI_CONVENTIONAL_MEMORY,
+       /* Memory in which errors have been detected */
+       EFI_UNUSABLE_MEMORY,
+       /* Memory that holds the ACPI tables */
+       EFI_ACPI_RECLAIM_MEMORY,
+       /* Address space reserved for use by the firmware */
+       EFI_ACPI_MEMORY_NVS,
+       /*
+        * Used by system firmware to request that a memory-mapped IO region
+        * be mapped by the OS to a virtual address so it can be accessed by
+        * EFI runtime services.
+        */
+       EFI_MMAP_IO,
+       /*
+        * System memory-mapped IO region that is used to translate
+        * memory cycles to IO cycles by the processor.
+        */
+       EFI_MMAP_IO_PORT,
+       /*
+        * Address space reserved by the firmware for code that is
+        * part of the processor.
+        */
+       EFI_PAL_CODE,
+       EFI_MAX_MEMORY_TYPE
+};
+
+/*
+ * Describes all memory ranges used during the HOB producer phase that
+ * exist outside the HOB list. This HOB type describes how memory is used,
+ * not the physical attributes of memory.
+ */
+struct hob_mem_alloc_t {
+       struct hob_header_t     hdr;
+       /*
+        * A GUID that defines the memory allocation region's type and purpose,
+        * as well as other fields within the memory allocation HOB. This GUID
+        * is used to define the additional data within the HOB that may be
+        * present for the memory allocation HOB. Type efi_guid_t is defined in
+        * InstallProtocolInterface() in the UEFI 2.0 specification.
+        */
+       struct efi_guid_t       name;
+       /*
+        * The base address of memory allocated by this HOB.
+        * Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0
+        * specification.
+        */
+       phys_addr_t             mem_base;
+       /* The length in bytes of memory allocated by this HOB */
+       phys_size_t             mem_len;
+       /*
+        * Defines the type of memory allocated by this HOB.
+        * The memory type definition follows the EFI_MEMORY_TYPE definition.
+        * Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0
+        * specification.
+        */
+       enum efi_mem_type_t     mem_type;
+       /* padding */
+       u8                      reserved[4];
+};
+
+/* Value of ResourceType in HOB_RES_DESC */
+#define RES_SYS_MEM            0x00000000
+#define RES_MMAP_IO            0x00000001
+#define RES_IO                 0x00000002
+#define RES_FW_DEVICE          0x00000003
+#define RES_MMAP_IO_PORT       0x00000004
+#define RES_MEM_RESERVED       0x00000005
+#define RES_IO_RESERVED                0x00000006
+#define RES_MAX_MEM_TYPE       0x00000007
+
+/*
+ * These types can be ORed together as needed.
+ *
+ * The first three enumerations describe settings
+ * The rest of the settings describe capabilities
+ */
+#define RES_ATTR_PRESENT                       0x00000001
+#define RES_ATTR_INITIALIZED                   0x00000002
+#define RES_ATTR_TESTED                                0x00000004
+#define RES_ATTR_SINGLE_BIT_ECC                        0x00000008
+#define RES_ATTR_MULTIPLE_BIT_ECC              0x00000010
+#define RES_ATTR_ECC_RESERVED_1                        0x00000020
+#define RES_ATTR_ECC_RESERVED_2                        0x00000040
+#define RES_ATTR_READ_PROTECTED                        0x00000080
+#define RES_ATTR_WRITE_PROTECTED               0x00000100
+#define RES_ATTR_EXECUTION_PROTECTED           0x00000200
+#define RES_ATTR_UNCACHEABLE                   0x00000400
+#define RES_ATTR_WRITE_COMBINEABLE             0x00000800
+#define RES_ATTR_WRITE_THROUGH_CACHEABLE       0x00001000
+#define RES_ATTR_WRITE_BACK_CACHEABLE          0x00002000
+#define RES_ATTR_16_BIT_IO                     0x00004000
+#define RES_ATTR_32_BIT_IO                     0x00008000
+#define RES_ATTR_64_BIT_IO                     0x00010000
+#define RES_ATTR_UNCACHED_EXPORTED             0x00020000
+
+/*
+ * Describes the resource properties of all fixed, nonrelocatable resource
+ * ranges found on the processor host bus during the HOB producer phase.
+ */
+struct hob_res_desc_t {
+       struct hob_header_t     hdr;
+       /*
+        * A GUID representing the owner of the resource. This GUID is
+        * used by HOB consumer phase components to correlate device
+        * ownership of a resource.
+        */
+       struct efi_guid_t       owner;
+       u32                     type;
+       u32                     attr;
+       /* The physical start address of the resource region */
+       phys_addr_t             phys_start;
+       /* The number of bytes of the resource region */
+       phys_size_t             len;
+};
+
+/*
+ * Allows writers of executable content in the HOB producer phase to
+ * maintain and manage HOBs with specific GUID.
+ */
+struct hob_guid_t {
+       struct hob_header_t     hdr;
+       /* A GUID that defines the contents of this HOB */
+       struct efi_guid_t       name;
+       /* GUID specific data goes here */
+};
+
+/* Union of all the possible HOB Types */
+union hob_pointers_t {
+       struct hob_header_t     *hdr;
+       struct hob_mem_alloc_t  *mem_alloc;
+       struct hob_res_desc_t   *res_desc;
+       struct hob_guid_t       *guid;
+       u8                      *raw;
+};
+
+/**
+ * Returns the type of a HOB.
+ *
+ * This macro returns the type field from the HOB header for the
+ * HOB specified by hob.
+ *
+ * @hob:    A pointer to a HOB.
+ *
+ * @return: HOB type.
+ */
+#define GET_HOB_TYPE(hob) \
+       ((*(struct hob_header_t **)&(hob))->type)
+
+/**
+ * Returns the length, in bytes, of a HOB.
+ *
+ * This macro returns the len field from the HOB header for the
+ * HOB specified by hob.
+ *
+ * @hob:    A pointer to a HOB.
+ *
+ * @return: HOB length.
+ */
+#define GET_HOB_LENGTH(hob) \
+       ((*(struct hob_header_t **)&(hob))->len)
+
+/**
+ * Returns a pointer to the next HOB in the HOB list.
+ *
+ * This macro returns a pointer to HOB that follows the HOB specified by hob
+ * in the HOB List.
+ *
+ * @hob:    A pointer to a HOB.
+ *
+ * @return: A pointer to the next HOB in the HOB list.
+ */
+#define GET_NEXT_HOB(hob)      \
+       (void *)(*(u8 **)&(hob) + GET_HOB_LENGTH(hob))
+
+/**
+ * Determines if a HOB is the last HOB in the HOB list.
+ *
+ * This macro determine if the HOB specified by hob is the last HOB in the
+ * HOB list.  If hob is last HOB in the HOB list, then TRUE is returned.
+ * Otherwise, FALSE is returned.
+ *
+ * @hob:          A pointer to a HOB.
+ *
+ * @retval TRUE:  The HOB specified by hob is the last HOB in the HOB list.
+ * @retval FALSE: The HOB specified by hob is not the last HOB in the HOB list.
+ */
+#define END_OF_HOB(hob)        (GET_HOB_TYPE(hob) == (u16)HOB_TYPE_EOH)
+
+/**
+ * Returns a pointer to data buffer from a HOB of type HOB_TYPE_GUID_EXT.
+ *
+ * This macro returns a pointer to the data buffer in a HOB specified by hob.
+ * hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT.
+ *
+ * @hob:    A pointer to a HOB.
+ *
+ * @return: A pointer to the data buffer in a HOB.
+ */
+#define GET_GUID_HOB_DATA(hob) \
+       (void *)(*(u8 **)&(hob) + sizeof(struct hob_guid_t))
+
+/**
+ * Returns the size of the data buffer from a HOB of type HOB_TYPE_GUID_EXT.
+ *
+ * This macro returns the size, in bytes, of the data buffer in a HOB
+ * specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT.
+ *
+ * @hob:    A pointer to a HOB.
+ *
+ * @return: The size of the data buffer.
+ */
+#define GET_GUID_HOB_DATA_SIZE(hob)    \
+       (u16)(GET_HOB_LENGTH(hob) - sizeof(struct hob_guid_t))
+
+/* FSP specific GUID HOB definitions */
+#define FSP_HEADER_GUID \
+       { \
+       0x912740be, 0x2284, 0x4734, \
+       {0xb9, 0x71, 0x84, 0xb0, 0x27, 0x35, 0x3f, 0x0c} \
+       }
+
+#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
+       { \
+       0x721acf02, 0x4d77, 0x4c2a, \
+       { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
+       }
+
+#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \
+       { \
+       0xbbcff46c, 0xc8d3, 0x4113, \
+       { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } \
+       }
+
+#define FSP_HOB_RESOURCE_OWNER_FSP_GUID \
+       { \
+       0x69a79759, 0x1373, 0x4367, \
+       { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } \
+       }
+
+#define FSP_HOB_RESOURCE_OWNER_TSEG_GUID \
+       { \
+       0xd038747c, 0xd00c, 0x4980, \
+       { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } \
+       }
+
+#define FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID \
+       { \
+       0x9c7c3aa7, 0x5332, 0x4917, \
+       { 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } \
+       }
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h
new file mode 100644 (file)
index 0000000..ad78bcd
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef _FSP_HEADER_H_
+#define _FSP_HEADER_H_
+
+#define FSP_HEADER_OFF 0x94    /* Fixed FSP header offset in the FSP image */
+
+#pragma pack(1)
+
+struct fsp_header_t {
+       u32     sign;                   /* 'FSPH' */
+       u32     hdr_len;                /* header length */
+       u8      reserved1[3];
+       u8      hdr_rev;                /* header rev */
+       u32     img_rev;                /* image rev */
+       char    img_id[8];              /* signature string */
+       u32     img_size;               /* image size */
+       u32     img_base;               /* image base */
+       u32     img_attr;               /* image attribute */
+       u32     cfg_region_off;         /* configuration region offset */
+       u32     cfg_region_size;        /* configuration region size */
+       u32     api_num;                /* number of API entries */
+       u32     fsp_tempram_init;       /* tempram_init offset */
+       u32     fsp_init;               /* fsp_init offset */
+       u32     fsp_notify;             /* fsp_notify offset */
+       u32     reserved2;
+};
+
+#pragma pack()
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h
new file mode 100644 (file)
index 0000000..a7b6e6b
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_PLATFORM_H__
+#define __FSP_PLATFORM_H__
+
+#pragma pack(1)
+
+struct fspinit_rtbuf_t {
+       struct common_buf_t     common; /* FSP common runtime data structure */
+};
+
+#pragma pack()
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h
new file mode 100644 (file)
index 0000000..3e53ea1
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_SUPPORT_H__
+#define __FSP_SUPPORT_H__
+
+#include "fsp_types.h"
+#include "fsp_fv.h"
+#include "fsp_ffs.h"
+#include "fsp_api.h"
+#include "fsp_hob.h"
+#include "fsp_platform.h"
+#include "fsp_infoheader.h"
+#include "fsp_bootmode.h"
+#include "fsp_vpd.h"
+
+struct shared_data_t {
+       struct fsp_header_t     *fsp_hdr;
+       u32                     *stack_top;
+       struct upd_region_t     fsp_upd;
+};
+
+void asm_continuation(void);
+
+void bl_main_continue(void *hob_list, struct shared_data_t *shared_data);
+
+/**
+ * FSP Continuation function
+ *
+ * @shared_data: Shared data base before stack migration
+ * @status:      Always 0
+ * @hob_list:    HOB list pointer
+ *
+ * @retval:      Never returns
+ */
+void fsp_continue(struct shared_data_t *shared_data, u32 status,
+                 void *hob_list);
+
+/**
+ * Find FSP header offset in FSP image
+ *
+ * If this function is called before the a stack is established, special care
+ * must be taken. First, it cannot declare any local variable using stack.
+ * Only register variable can be used here. Secondly, some compiler version
+ * will add prolog or epilog code for the C function. If so the function call
+ * may not work before stack is ready. GCC 4.8.1 has been verified to be
+ * working for the following code.
+ *
+ * @retval: the offset of FSP header. If signature is invalid, returns 0.
+ */
+u32 find_fsp_header(void);
+
+/**
+ * FSP initialization wrapper function.
+ *
+ * @stack_top: bootloader stack top address
+ * @boot_mode: boot mode defined in fsp_bootmode.h
+ * @nvs_buf:   Non-volatile memory buffer pointer
+ */
+void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf);
+
+/**
+ * FSP notification wrapper function
+ *
+ * @fsp_hdr: Pointer to FSP information header
+ * @phase:   FSP initialization phase defined in enum fsp_phase_t
+ *
+ * @retval:  compatible status code with EFI_STATUS defined in PI spec
+ */
+u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase);
+
+/**
+ * This function retrieves the top of usable low memory.
+ *
+ * @hob_list: A HOB list pointer.
+ *
+ * @retval:   Usable low memory top.
+ */
+u32 get_usable_lowmem_top(const void *hob_list);
+
+/**
+ * This function retrieves the top of usable high memory.
+ *
+ * @hob_list: A HOB list pointer.
+ *
+ * @retval:   Usable high memory top.
+ */
+u64 get_usable_highmem_top(const void *hob_list);
+
+/**
+ * This function retrieves a special reserved memory region.
+ *
+ * @hob_list: A HOB list pointer.
+ * @len:      A pointer to the GUID HOB data buffer length.
+ *            If the GUID HOB is located, the length will be updated.
+ * @guid:     A pointer to the owner guild.
+ *
+ * @retval:   Reserved region start address.
+ *            0 if this region does not exist.
+ */
+u64 get_fsp_reserved_mem_from_guid(const void *hob_list,
+                                  u64 *len, struct efi_guid_t *guid);
+
+/**
+ * This function retrieves the FSP reserved normal memory.
+ *
+ * @hob_list: A HOB list pointer.
+ * @len:      A pointer to the FSP reserved memory length buffer.
+ *            If the GUID HOB is located, the length will be updated.
+ * @retval:   FSP reserved memory base
+ *            0 if this region does not exist.
+ */
+u32 get_fsp_reserved_mem(const void *hob_list, u32 *len);
+
+/**
+ * This function retrieves the TSEG reserved normal memory.
+ *
+ * @hob_list:      A HOB list pointer.
+ * @len:           A pointer to the TSEG reserved memory length buffer.
+ *                 If the GUID HOB is located, the length will be updated.
+ *
+ * @retval NULL:   Failed to find the TSEG reserved memory.
+ * @retval others: TSEG reserved memory base.
+ */
+u32 get_tseg_reserved_mem(const void *hob_list, u32 *len);
+
+/**
+ * Returns the next instance of a HOB type from the starting HOB.
+ *
+ * @type:     HOB type to search
+ * @hob_list: A pointer to the HOB list
+ *
+ * @retval:   A HOB object with matching type; Otherwise NULL.
+ */
+void *get_next_hob(u16 type, const void *hob_list);
+
+/**
+ * Returns the next instance of the matched GUID HOB from the starting HOB.
+ *
+ * @guid:     GUID to search
+ * @hob_list: A pointer to the HOB list
+ *
+ * @retval:   A HOB object with matching GUID; Otherwise NULL.
+ */
+void *get_next_guid_hob(const struct efi_guid_t *guid, const void *hob_list);
+
+/**
+ * This function retrieves a GUID HOB data buffer and size.
+ *
+ * @hob_list:      A HOB list pointer.
+ * @len:           A pointer to the GUID HOB data buffer length.
+ *                 If the GUID HOB is located, the length will be updated.
+ * @guid           A pointer to HOB GUID.
+ *
+ * @retval NULL:   Failed to find the GUID HOB.
+ * @retval others: GUID HOB data buffer pointer.
+ */
+void *get_guid_hob_data(const void *hob_list, u32 *len,
+                       struct efi_guid_t *guid);
+
+/**
+ * This function retrieves FSP Non-volatile Storage HOB buffer and size.
+ *
+ * @hob_list:      A HOB list pointer.
+ * @len:           A pointer to the NVS data buffer length.
+ *                 If the HOB is located, the length will be updated.
+ *
+ * @retval NULL:   Failed to find the NVS HOB.
+ * @retval others: FSP NVS data buffer pointer.
+ */
+void *get_fsp_nvs_data(const void *hob_list, u32 *len);
+
+/**
+ * This function retrieves Bootloader temporary stack buffer and size.
+ *
+ * @hob_list:      A HOB list pointer.
+ * @len:           A pointer to the bootloader temporary stack length.
+ *                 If the HOB is located, the length will be updated.
+ *
+ * @retval NULL:   Failed to find the bootloader temporary stack HOB.
+ * @retval others: Bootloader temporary stackbuffer pointer.
+ */
+void *get_bootloader_tmp_mem(const void *hob_list, u32 *len);
+
+/**
+ * This function overrides the default configurations in the UPD data region.
+ *
+ * @fsp_upd: A pointer to the upd_region_t data strcture
+ *
+ * @return:  None
+ */
+void update_fsp_upd(struct upd_region_t *fsp_upd);
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h
new file mode 100644 (file)
index 0000000..12ebbfd
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __FSP_TYPES_H__
+#define __FSP_TYPES_H__
+
+/*
+ * Boolean true value.  UEFI Specification defines this value to be 1,
+ * but this form is more portable.
+ */
+#define TRUE                   ((unsigned char)(1 == 1))
+
+/*
+ * Boolean false value.  UEFI Specification defines this value to be 0,
+ * but this form is more portable.
+ */
+#define FALSE                  ((unsigned char)(0 == 1))
+
+/* 128 bit buffer containing a unique identifier value */
+struct efi_guid_t {
+       u32     data1;
+       u16     data2;
+       u16     data3;
+       u8      data4[8];
+};
+
+/**
+ * Returns a 16-bit signature built from 2 ASCII characters.
+ *
+ * This macro returns a 16-bit value built from the two ASCII characters
+ * specified by A and B.
+ *
+ * @A: The first ASCII character.
+ * @B: The second ASCII character.
+ *
+ * @return: A 16-bit value built from the two ASCII characters specified by
+ *          A and B.
+ */
+#define SIGNATURE_16(A, B)     ((A) | (B << 8))
+
+/**
+ * Returns a 32-bit signature built from 4 ASCII characters.
+ *
+ * This macro returns a 32-bit value built from the four ASCII characters
+ * specified by A, B, C, and D.
+ *
+ * @A: The first ASCII character.
+ * @B: The second ASCII character.
+ * @C: The third ASCII character.
+ * @D: The fourth ASCII character.
+ *
+ * @return: A 32-bit value built from the two ASCII characters specified by
+ *          A, B, C and D.
+ */
+#define SIGNATURE_32(A, B, C, D)       \
+       (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16))
+
+/**
+ * Returns a 64-bit signature built from 8 ASCII characters.
+ *
+ * This macro returns a 64-bit value built from the eight ASCII characters
+ * specified by A, B, C, D, E, F, G,and H.
+ *
+ * @A: The first ASCII character.
+ * @B: The second ASCII character.
+ * @C: The third ASCII character.
+ * @D: The fourth ASCII character.
+ * @E: The fifth ASCII character.
+ * @F: The sixth ASCII character.
+ * @G: The seventh ASCII character.
+ * @H: The eighth ASCII character.
+ *
+ * @return: A 64-bit value built from the two ASCII characters specified by
+ *          A, B, C, D, E, F, G and H.
+ */
+#define SIGNATURE_64(A, B, C, D, E, F, G, H)   \
+       (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
+
+/* Assertion for debug */
+#define ASSERT(exp)    do { if (!(exp)) for (;;); } while (FALSE)
+
+/*
+ * Define FSP API return status code.
+ * Compatiable with EFI_STATUS defined in PI Spec.
+ */
+#define FSP_SUCCESS            0
+#define FSP_INVALID_PARAM      0x80000002
+#define FSP_UNSUPPORTED                0x80000003
+#define FSP_DEVICE_ERROR       0x80000007
+#define FSP_NOT_FOUND          0x8000000E
+#define FSP_ALREADY_STARTED    0x80000014
+
+#endif
diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h
new file mode 100644 (file)
index 0000000..11cc32f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * This file is automatically generated. Please do NOT modify !!!
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#ifndef __VPDHEADER_H__
+#define __VPDHEADER_H__
+
+#pragma pack(1)
+
+struct upd_region_t {
+       u64     sign;                   /* Offset 0x0000 */
+       u64     reserved;               /* Offset 0x0008 */
+       u8      dummy[240];             /* Offset 0x0010 */
+       u8      hda_verb_header[12];    /* Offset 0x0100 */
+       u32     hda_verb_length;        /* Offset 0x010C */
+       u8      hda_verb_data0[16];     /* Offset 0x0110 */
+       u8      hda_verb_data1[16];     /* Offset 0x0120 */
+       u8      hda_verb_data2[16];     /* Offset 0x0130 */
+       u8      hda_verb_data3[16];     /* Offset 0x0140 */
+       u8      hda_verb_data4[16];     /* Offset 0x0150 */
+       u8      hda_verb_data5[16];     /* Offset 0x0160 */
+       u8      hda_verb_data6[16];     /* Offset 0x0170 */
+       u8      hda_verb_data7[16];     /* Offset 0x0180 */
+       u8      hda_verb_data8[16];     /* Offset 0x0190 */
+       u8      hda_verb_data9[16];     /* Offset 0x01A0 */
+       u8      hda_verb_data10[16];    /* Offset 0x01B0 */
+       u8      hda_verb_data11[16];    /* Offset 0x01C0 */
+       u8      hda_verb_data12[16];    /* Offset 0x01D0 */
+       u8      hda_verb_data13[16];    /* Offset 0x01E0 */
+       u8      hda_verb_pad[47];       /* Offset 0x01F0 */
+       u16     terminator;             /* Offset 0x021F */
+};
+
+#define VPD_IMAGE_ID   0x445056574F4E4E4D      /* 'MNNOWVPD' */
+#define VPD_IMAGE_REV  0x00000301
+
+struct vpd_region_t {
+       u64     sign;                   /* Offset 0x0000 */
+       u32     img_rev;                /* Offset 0x0008 */
+       u32     upd_offset;             /* Offset 0x000C */
+       u8      unused[16];             /* Offset 0x0010 */
+       u32     fsp_res_memlen;         /* Offset 0x0020 */
+       u8      disable_pcie1;          /* Offset 0x0024 */
+       u8      disable_pcie2;          /* Offset 0x0025 */
+       u8      disable_pcie3;          /* Offset 0x0026 */
+       u8      enable_azalia;          /* Offset 0x0027 */
+       u8      legacy_seg_decode;      /* Offset 0x0028 */
+       u8      pcie_port_ioh;          /* Offset 0x0029 */
+};
+
+#pragma pack()
+
+#endif