commit
b9206e61f3
@ -0,0 +1,20 @@ |
||||
/*
|
||||
* Copyright (C) 2013, Intel Corporation |
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: Intel |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/fsp/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; */ |
||||
} |
@ -0,0 +1,416 @@ |
||||
/*
|
||||
* Copyright (C) 2013, Intel Corporation |
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: Intel |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/fsp/fsp_support.h> |
||||
#include <asm/post.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; |
||||
} |
||||
|
||||
void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) |
||||
{ |
||||
u32 stack_len; |
||||
u32 stack_base; |
||||
u32 stack_top; |
||||
|
||||
post_code(POST_MRC); |
||||
|
||||
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 */ |
||||
fsp_init_done(hob_list); |
||||
} |
||||
|
||||
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 *)¶ms, 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 = ¶ms; |
||||
|
||||
shared_data.fsp_hdr = fsp_hdr; |
||||
shared_data.stack_top = (u32 *)stack_top; |
||||
|
||||
post_code(POST_PRE_MRC); |
||||
|
||||
/*
|
||||
* 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:;" |
||||
"movl %%ebx, %%eax;" /* shared_data */ |
||||
"movl 4(%%esp), %%edx;" /* status */ |
||||
"movl 8(%%esp), %%ecx;" /* hob_list */ |
||||
"jmp fsp_continue;" |
||||
: : "m"(params_ptr), "a"(init), "b"(&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(¶ms); |
||||
|
||||
/*
|
||||
* Should never return. |
||||
* Control will continue from ContinuationFunc |
||||
*/ |
||||
ASSERT(FALSE); |
||||
} |
||||
|
||||
u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) |
||||
{ |
||||
fsp_notify_f notify; |
||||
struct fsp_notify_params_t params; |
||||
struct fsp_notify_params_t *params_ptr; |
||||
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; |
||||
params_ptr = ¶ms; |
||||
|
||||
/*
|
||||
* Use ASM code to ensure correct parameter is on the stack for |
||||
* FspNotify as U-Boot is using different ABI from FSP |
||||
*/ |
||||
asm volatile ( |
||||
"pushl %1;" /* push notify phase */ |
||||
"call *%%eax;" /* call FspNotify */ |
||||
"addl $4, %%esp;" /* clean up the stack */ |
||||
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) |
||||
); |
||||
|
||||
return status; |
||||
} |
||||
|
||||
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); |
||||
} |
@ -0,0 +1,53 @@ |
||||
/* |
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
/dts-v1/; |
||||
|
||||
/include/ "coreboot.dtsi" |
||||
|
||||
/ { |
||||
#address-cells = <1>; |
||||
#size-cells = <1>; |
||||
model = "Intel Crown Bay"; |
||||
compatible = "intel,crownbay", "intel,queensbay"; |
||||
|
||||
config { |
||||
silent_console = <0>; |
||||
}; |
||||
|
||||
gpioa { |
||||
compatible = "intel,ich6-gpio"; |
||||
u-boot,dm-pre-reloc; |
||||
reg = <0 0x20>; |
||||
bank-name = "A"; |
||||
}; |
||||
|
||||
gpiob { |
||||
compatible = "intel,ich6-gpio"; |
||||
u-boot,dm-pre-reloc; |
||||
reg = <0x20 0x20>; |
||||
bank-name = "B"; |
||||
}; |
||||
|
||||
serial { |
||||
reg = <0x3f8 8>; |
||||
clock-frequency = <115200>; |
||||
}; |
||||
|
||||
chosen { }; |
||||
memory { device_type = "memory"; reg = <0 0>; }; |
||||
|
||||
spi { |
||||
#address-cells = <1>; |
||||
#size-cells = <0>; |
||||
compatible = "intel,ich7"; |
||||
spi-flash@0 { |
||||
reg = <0>; |
||||
compatible = "sst,25vf016b", "spi-flash"; |
||||
memory-map = <0xffe00000 0x00200000>; |
||||
}; |
||||
}; |
||||
}; |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 fsp_init_done(void *hob_list); |
||||
|
||||
/**
|
||||
* 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 |
@ -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 |
@ -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 |
@ -0,0 +1,6 @@ |
||||
#ifndef _ASM_X86_LINKAGE_H |
||||
#define _ASM_X86_LINKAGE_H |
||||
|
||||
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) |
||||
|
||||
#endif /* _ASM_X86_LINKAGE_H */ |
@ -0,0 +1,90 @@ |
||||
/*
|
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* Adapted from coreboot src/include/device/pnp_def.h |
||||
* and arch/x86/include/arch/io.h |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _ASM_PNP_DEF_H_ |
||||
#define _ASM_PNP_DEF_H_ |
||||
|
||||
#include <asm/io.h> |
||||
|
||||
#define PNP_IDX_EN 0x30 |
||||
#define PNP_IDX_IO0 0x60 |
||||
#define PNP_IDX_IO1 0x62 |
||||
#define PNP_IDX_IO2 0x64 |
||||
#define PNP_IDX_IO3 0x66 |
||||
#define PNP_IDX_IRQ0 0x70 |
||||
#define PNP_IDX_IRQ1 0x72 |
||||
#define PNP_IDX_DRQ0 0x74 |
||||
#define PNP_IDX_DRQ1 0x75 |
||||
#define PNP_IDX_MSC0 0xf0 |
||||
#define PNP_IDX_MSC1 0xf1 |
||||
|
||||
/* Generic functions for pnp devices */ |
||||
|
||||
/*
|
||||
* pnp device is a 16-bit integer composed of its i/o port address at high byte |
||||
* and logic function number at low byte. |
||||
*/ |
||||
#define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC)) |
||||
|
||||
static inline void pnp_write_config(uint16_t dev, uint8_t reg, uint8_t value) |
||||
{ |
||||
uint8_t port = dev >> 8; |
||||
|
||||
outb(reg, port); |
||||
outb(value, port + 1); |
||||
} |
||||
|
||||
static inline uint8_t pnp_read_config(uint16_t dev, uint8_t reg) |
||||
{ |
||||
uint8_t port = dev >> 8; |
||||
|
||||
outb(reg, port); |
||||
return inb(port + 1); |
||||
} |
||||
|
||||
static inline void pnp_set_logical_device(uint16_t dev) |
||||
{ |
||||
uint8_t device = dev & 0xff; |
||||
|
||||
pnp_write_config(dev, 0x07, device); |
||||
} |
||||
|
||||
static inline void pnp_set_enable(uint16_t dev, int enable) |
||||
{ |
||||
pnp_write_config(dev, PNP_IDX_EN, enable ? 1 : 0); |
||||
} |
||||
|
||||
static inline int pnp_read_enable(uint16_t dev) |
||||
{ |
||||
return !!pnp_read_config(dev, PNP_IDX_EN); |
||||
} |
||||
|
||||
static inline void pnp_set_iobase(uint16_t dev, uint8_t index, uint16_t iobase) |
||||
{ |
||||
pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff); |
||||
pnp_write_config(dev, index + 1, iobase & 0xff); |
||||
} |
||||
|
||||
static inline uint16_t pnp_read_iobase(uint16_t dev, uint8_t index) |
||||
{ |
||||
return ((uint16_t)(pnp_read_config(dev, index)) << 8) | |
||||
pnp_read_config(dev, index + 1); |
||||
} |
||||
|
||||
static inline void pnp_set_irq(uint16_t dev, uint8_t index, unsigned irq) |
||||
{ |
||||
pnp_write_config(dev, index, irq); |
||||
} |
||||
|
||||
static inline void pnp_set_drq(uint16_t dev, uint8_t index, unsigned drq) |
||||
{ |
||||
pnp_write_config(dev, index, drq & 0xff); |
||||
} |
||||
|
||||
#endif /* _ASM_PNP_DEF_H_ */ |
@ -0,0 +1,67 @@ |
||||
/*
|
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <linux/compiler.h> |
||||
#include <asm/arch/fsp/fsp_support.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static char *hob_type[] = { |
||||
"reserved", |
||||
"Hand-off", |
||||
"Memory Allocation", |
||||
"Resource Descriptor", |
||||
"GUID Extension", |
||||
"Firmware Volumn", |
||||
"CPU", |
||||
"Memory Pool", |
||||
"reserved", |
||||
"Firmware Volumn 2", |
||||
"Load PEIM Unused", |
||||
"UEFI Capsule", |
||||
}; |
||||
|
||||
int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
||||
{ |
||||
union hob_pointers_t hob; |
||||
u16 type; |
||||
char *desc; |
||||
int i = 0; |
||||
|
||||
hob.raw = (u8 *)gd->arch.hob_list; |
||||
|
||||
printf("HOB list address: 0x%08x\n\n", (unsigned int)hob.raw); |
||||
|
||||
printf("No. | Address | Type | Length in Bytes\n"); |
||||
printf("----|----------|---------------------|----------------\n"); |
||||
while (!END_OF_HOB(hob)) { |
||||
printf("%-3d | %08x | ", i, (unsigned int)hob.raw); |
||||
type = hob.hdr->type; |
||||
if (type == HOB_TYPE_UNUSED) |
||||
desc = "*Unused*"; |
||||
else if (type == HOB_TYPE_EOH) |
||||
desc = "**END OF HOB**"; |
||||
else if (type >= 0 && type <= ARRAY_SIZE(hob_type)) |
||||
desc = hob_type[type]; |
||||
else |
||||
desc = "!!!Invalid Type!!!"; |
||||
printf("%-19s | %-15d\n", desc, hob.hdr->len); |
||||
hob.raw = GET_NEXT_HOB(hob); |
||||
i++; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* -------------------------------------------------------------------- */ |
||||
|
||||
U_BOOT_CMD( |
||||
hob, 1, 1, do_hob, |
||||
"print FSP Hand-Off Block information", |
||||
"" |
||||
); |
@ -0,0 +1,33 @@ |
||||
/*
|
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/pnp_def.h> |
||||
|
||||
static void pnp_enter_conf_state(u16 dev) |
||||
{ |
||||
u16 port = dev >> 8; |
||||
|
||||
outb(0x55, port); |
||||
} |
||||
|
||||
static void pnp_exit_conf_state(u16 dev) |
||||
{ |
||||
u16 port = dev >> 8; |
||||
|
||||
outb(0xaa, port); |
||||
} |
||||
|
||||
void lpc47m_enable_serial(u16 dev, u16 iobase) |
||||
{ |
||||
pnp_enter_conf_state(dev); |
||||
pnp_set_logical_device(dev); |
||||
pnp_set_enable(dev, 0); |
||||
pnp_set_iobase(dev, PNP_IDX_IO0, iobase); |
||||
pnp_set_enable(dev, 1); |
||||
pnp_exit_conf_state(dev); |
||||
} |
@ -0,0 +1,19 @@ |
||||
/*
|
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _SMSC_LPC47M_H_ |
||||
#define _SMSC_LPC47M_H_ |
||||
|
||||
/**
|
||||
* Configure the base I/O port of the specified serial device and enable the |
||||
* serial device. |
||||
* |
||||
* @dev: High 8 bits = Super I/O port, low 8 bits = logical device number. |
||||
* @iobase: Processor I/O port address to assign to this serial device. |
||||
*/ |
||||
void lpc47m_enable_serial(u16 dev, u16 iobase); |
||||
|
||||
#endif /* _SMSC_LPC47M_H_ */ |
Loading…
Reference in new issue