- Enable SD slot on Intel Edison - Populate CSRT ACPI table for shared DMA controller on Intel Tangier - Convert Intel ICH-SPI driver to use new spi-mem ops - Enable config_distro_bootcmd for QEMU x86 - Support U-Boot as a payload for Intel Slim Bootloader - Avoid writing temporary asl files into the source tree which fixes the parallel build issue occasionally seen
This commit is contained in:
commit
9fd8b2c8c7
@ -115,6 +115,7 @@ source "arch/x86/cpu/efi/Kconfig"
|
||||
source "arch/x86/cpu/qemu/Kconfig"
|
||||
source "arch/x86/cpu/quark/Kconfig"
|
||||
source "arch/x86/cpu/queensbay/Kconfig"
|
||||
source "arch/x86/cpu/slimbootloader/Kconfig"
|
||||
source "arch/x86/cpu/tangier/Kconfig"
|
||||
|
||||
# architecture-specific options below
|
||||
@ -344,9 +345,17 @@ config INTEL_ME_FILE
|
||||
The filename of the file to use as Intel Management Engine in the
|
||||
board directory.
|
||||
|
||||
config USE_HOB
|
||||
bool "Use HOB (Hand-Off Block)"
|
||||
help
|
||||
Select this option to access HOB (Hand-Off Block) data structures
|
||||
and parse HOBs. This HOB infra structure can be reused with
|
||||
different solutions across different platforms.
|
||||
|
||||
config HAVE_FSP
|
||||
bool "Add an Firmware Support Package binary"
|
||||
depends on !EFI
|
||||
select USE_HOB
|
||||
help
|
||||
Select this option to add an Firmware Support Package binary to
|
||||
the resulting U-Boot image. It is a binary blob which U-Boot uses
|
||||
|
@ -42,6 +42,7 @@ obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
|
||||
obj-$(CONFIG_INTEL_BRASWELL) += braswell/
|
||||
obj-$(CONFIG_INTEL_BROADWELL) += broadwell/
|
||||
obj-$(CONFIG_SYS_COREBOOT) += coreboot/
|
||||
obj-$(CONFIG_SYS_SLIMBOOTLOADER) += slimbootloader/
|
||||
obj-$(CONFIG_EFI) += efi/
|
||||
obj-$(CONFIG_QEMU) += qemu/
|
||||
obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
|
||||
|
19
arch/x86/cpu/slimbootloader/Kconfig
Normal file
19
arch/x86/cpu/slimbootloader/Kconfig
Normal file
@ -0,0 +1,19 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
|
||||
config SYS_SLIMBOOTLOADER
|
||||
bool
|
||||
select USE_HOB
|
||||
imply SYS_NS16550
|
||||
imply AHCI_PCI
|
||||
imply SCSI
|
||||
imply SCSI_AHCI
|
||||
imply MMC
|
||||
imply MMC_PCI
|
||||
imply MMC_SDHCI
|
||||
imply MMC_SDHCI_SDMA
|
||||
imply USB
|
||||
imply USB_EHCI_HCD
|
||||
imply USB_XHCI_HCD
|
||||
imply E1000
|
5
arch/x86/cpu/slimbootloader/Makefile
Normal file
5
arch/x86/cpu/slimbootloader/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
|
||||
obj-y += car.o slimbootloader.o sdram.o serial.o
|
14
arch/x86/cpu/slimbootloader/car.S
Normal file
14
arch/x86/cpu/slimbootloader/car.S
Normal file
@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#include <generated/asm-offsets.h>
|
||||
|
||||
.section .text
|
||||
|
||||
.globl car_init
|
||||
car_init:
|
||||
/* Get hob pointer parameter from previous stage's stack */
|
||||
mov 0x4(%esp), %esi
|
||||
jmp car_init_ret
|
151
arch/x86/cpu/slimbootloader/sdram.c
Normal file
151
arch/x86/cpu/slimbootloader/sdram.c
Normal file
@ -0,0 +1,151 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/arch/slimbootloader.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* This returns a data pointer of memory map info from the guid hob.
|
||||
*
|
||||
* @return: A data pointer of memory map info hob
|
||||
*/
|
||||
static struct sbl_memory_map_info *get_memory_map_info(void)
|
||||
{
|
||||
struct sbl_memory_map_info *data;
|
||||
const efi_guid_t guid = SBL_MEMORY_MAP_INFO_GUID;
|
||||
|
||||
if (!gd->arch.hob_list)
|
||||
return NULL;
|
||||
|
||||
data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid);
|
||||
if (!data)
|
||||
panic("memory map info hob not found\n");
|
||||
if (!data->count)
|
||||
panic("invalid number of memory map entries\n");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#define for_each_if(condition) if (!(condition)) {} else
|
||||
|
||||
#define for_each_memory_map_entry_reversed(iter, entries) \
|
||||
for (iter = entries->count - 1; iter >= 0; iter--) \
|
||||
for_each_if(entries->entry[iter].type == E820_RAM)
|
||||
|
||||
/**
|
||||
* This is to give usable memory region information for u-boot relocation.
|
||||
* so search usable memory region lower than 4GB.
|
||||
* The memory map entries from Slim Bootloader hob are already sorted.
|
||||
*
|
||||
* @total_size: The memory size that u-boot occupies
|
||||
* @return : The top available memory address lower than 4GB
|
||||
*/
|
||||
ulong board_get_usable_ram_top(ulong total_size)
|
||||
{
|
||||
struct sbl_memory_map_info *data;
|
||||
int i;
|
||||
u64 addr_start;
|
||||
u64 addr_end;
|
||||
ulong ram_top;
|
||||
|
||||
data = get_memory_map_info();
|
||||
|
||||
/**
|
||||
* sorted memory map entries from Slim Bootloader based on physical
|
||||
* start memory address, from low to high. So do reversed search to
|
||||
* get highest usable, suitable size, 4KB aligned available memory
|
||||
* under 4GB.
|
||||
*/
|
||||
ram_top = 0;
|
||||
for_each_memory_map_entry_reversed(i, data) {
|
||||
addr_start = data->entry[i].addr;
|
||||
addr_end = addr_start + data->entry[i].size;
|
||||
|
||||
if (addr_start > SZ_4G)
|
||||
continue;
|
||||
|
||||
if (addr_end > SZ_4G)
|
||||
addr_end = SZ_4G;
|
||||
|
||||
if (addr_end < total_size)
|
||||
continue;
|
||||
|
||||
/* to relocate u-boot at 4K aligned memory */
|
||||
addr_end = rounddown(addr_end - total_size, SZ_4K);
|
||||
if (addr_end >= addr_start) {
|
||||
ram_top = (ulong)addr_end + total_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ram_top)
|
||||
panic("failed to find available memory for relocation!");
|
||||
|
||||
return ram_top;
|
||||
}
|
||||
|
||||
/**
|
||||
* The memory initialization has already been done in previous Slim Bootloader
|
||||
* stage thru FSP-M. Instead, this sets the ram_size from the memory map info
|
||||
* hob.
|
||||
*/
|
||||
int dram_init(void)
|
||||
{
|
||||
struct sbl_memory_map_info *data;
|
||||
int i;
|
||||
u64 ram_size;
|
||||
|
||||
data = get_memory_map_info();
|
||||
|
||||
/**
|
||||
* sorted memory map entries from Slim Bootloader based on physical
|
||||
* start memory address, from low to high. So do reversed search to
|
||||
* simply get highest usable memory address as RAM size
|
||||
*/
|
||||
ram_size = 0;
|
||||
for_each_memory_map_entry_reversed(i, data) {
|
||||
/* simply use the highest usable memory address as RAM size */
|
||||
ram_size = data->entry[i].addr + data->entry[i].size;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ram_size)
|
||||
panic("failed to detect memory size");
|
||||
|
||||
gd->ram_size = ram_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
if (!CONFIG_NR_DRAM_BANKS)
|
||||
return 0;
|
||||
|
||||
/* simply use a single bank to have whole size for now */
|
||||
gd->bd->bi_dram[0].start = 0;
|
||||
gd->bd->bi_dram[0].size = gd->ram_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int install_e820_map(unsigned int max_entries,
|
||||
struct e820_entry *entries)
|
||||
{
|
||||
struct sbl_memory_map_info *data;
|
||||
unsigned int i;
|
||||
|
||||
data = get_memory_map_info();
|
||||
|
||||
for (i = 0; i < data->count; i++) {
|
||||
entries[i].addr = data->entry[i].addr;
|
||||
entries[i].size = data->entry[i].size;
|
||||
entries[i].type = data->entry[i].type;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
67
arch/x86/cpu/slimbootloader/serial.c
Normal file
67
arch/x86/cpu/slimbootloader/serial.c
Normal file
@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <ns16550.h>
|
||||
#include <serial.h>
|
||||
#include <asm/arch/slimbootloader.h>
|
||||
|
||||
/**
|
||||
* The serial port info hob is generated by Slim Bootloader, so eligible for
|
||||
* Slim Bootloader based boards only.
|
||||
*/
|
||||
static int slimbootloader_serial_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
const efi_guid_t guid = SBL_SERIAL_PORT_INFO_GUID;
|
||||
struct sbl_serial_port_info *data;
|
||||
struct ns16550_platdata *plat = dev->platdata;
|
||||
|
||||
if (!gd->arch.hob_list)
|
||||
panic("hob list not found!");
|
||||
|
||||
data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid);
|
||||
if (!data) {
|
||||
debug("failed to get serial port information\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
debug("type:%d base=0x%08x baudrate=%d stride=%d clk=%d\n",
|
||||
data->type,
|
||||
data->base,
|
||||
data->baud,
|
||||
data->stride,
|
||||
data->clk);
|
||||
|
||||
/*
|
||||
* The data->type provides port io or mmio access type info,
|
||||
* but the access type will be controlled by
|
||||
* CONFIG_SYS_NS16550_PORT_MAPPED or CONFIG_SYS_NS16550_MEM32.
|
||||
*
|
||||
* TBD: ns16550 access type configuration in runtime.
|
||||
* ex) plat->access_type = data->type
|
||||
*/
|
||||
plat->base = data->base;
|
||||
/* ns16550 uses reg_shift, then covert stride to shift */
|
||||
plat->reg_shift = data->stride >> 1;
|
||||
plat->clock = data->clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id slimbootloader_serial_ids[] = {
|
||||
{ .compatible = "intel,slimbootloader-uart" },
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_slimbootloader) = {
|
||||
.name = "serial_slimbootloader",
|
||||
.id = UCLASS_SERIAL,
|
||||
.of_match = slimbootloader_serial_ids,
|
||||
.ofdata_to_platdata = slimbootloader_serial_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
|
||||
.priv_auto_alloc_size = sizeof(struct NS16550),
|
||||
.probe = ns16550_serial_probe,
|
||||
.ops = &ns16550_serial_ops,
|
||||
};
|
58
arch/x86/cpu/slimbootloader/slimbootloader.c
Normal file
58
arch/x86/cpu/slimbootloader/slimbootloader.c
Normal file
@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/slimbootloader.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* This sets tsc_base and clock_rate for early_timer and tsc_timer.
|
||||
* The performance info guid hob has all performance timestamp data, but
|
||||
* the only tsc frequency info is used for the timer driver for now.
|
||||
*
|
||||
* Slim Bootloader already calibrated TSC and provides it to U-Boot.
|
||||
* Therefore, U-Boot does not have to re-calibrate TSC.
|
||||
* Configuring tsc_base and clock_rate here makes x86 tsc_timer driver
|
||||
* bypass TSC calibration and use the provided TSC frequency.
|
||||
*/
|
||||
static void tsc_init(void)
|
||||
{
|
||||
struct sbl_performance_info *data;
|
||||
const efi_guid_t guid = SBL_PERFORMANCE_INFO_GUID;
|
||||
|
||||
if (!gd->arch.hob_list)
|
||||
panic("hob list not found!");
|
||||
|
||||
gd->arch.tsc_base = rdtsc();
|
||||
debug("tsc_base=0x%llx\n", gd->arch.tsc_base);
|
||||
|
||||
data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid);
|
||||
if (!data) {
|
||||
debug("performance info hob not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* frequency is in KHz, so to Hz */
|
||||
gd->arch.clock_rate = data->frequency * 1000;
|
||||
debug("freq=0x%lx\n", gd->arch.clock_rate);
|
||||
}
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
tsc_init();
|
||||
|
||||
return x86_cpu_init_f();
|
||||
}
|
||||
|
||||
int checkcpu(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
return default_print_cpuinfo();
|
||||
}
|
@ -97,7 +97,7 @@ early_board_init_ret:
|
||||
jmp car_init
|
||||
.globl car_init_ret
|
||||
car_init_ret:
|
||||
#ifndef CONFIG_HAVE_FSP
|
||||
#ifndef CONFIG_USE_HOB
|
||||
/*
|
||||
* We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM,
|
||||
* or fully initialised SDRAM - we really don't care which)
|
||||
@ -137,12 +137,13 @@ car_init_ret:
|
||||
|
||||
/* Get address of global_data */
|
||||
mov %fs:0, %edx
|
||||
#ifdef CONFIG_HAVE_FSP
|
||||
#ifdef CONFIG_USE_HOB
|
||||
/* Store the HOB list if we have one */
|
||||
test %esi, %esi
|
||||
jz skip_hob
|
||||
movl %esi, GD_HOB_LIST(%edx)
|
||||
|
||||
#ifdef CONFIG_HAVE_FSP
|
||||
/*
|
||||
* After fsp_init() returns, the stack has already been switched to a
|
||||
* place within system memory as defined by CONFIG_FSP_TEMP_RAM_ADDR.
|
||||
@ -151,6 +152,7 @@ car_init_ret:
|
||||
*/
|
||||
subl $CONFIG_FSP_SYS_MALLOC_F_LEN, %esp
|
||||
movl %esp, GD_MALLOC_BASE(%edx)
|
||||
#endif
|
||||
skip_hob:
|
||||
#else
|
||||
/* Store table pointer */
|
||||
|
@ -68,6 +68,44 @@ u32 acpi_fill_mcfg(u32 current)
|
||||
return current;
|
||||
}
|
||||
|
||||
static u32 acpi_fill_csrt_dma(struct acpi_csrt_group *grp)
|
||||
{
|
||||
struct acpi_csrt_shared_info *si = (struct acpi_csrt_shared_info *)&grp[1];
|
||||
|
||||
/* Fill the Resource Group with Shared Information attached */
|
||||
memset(grp, 0, sizeof(*grp));
|
||||
grp->shared_info_length = sizeof(struct acpi_csrt_shared_info);
|
||||
grp->length = sizeof(struct acpi_csrt_group) + grp->shared_info_length;
|
||||
/* TODO: All values below should come from U-Boot DT somehow */
|
||||
sprintf((char *)&grp->vendor_id, "%04X", 0x8086);
|
||||
grp->device_id = 0x11a2;
|
||||
|
||||
/* Fill the Resource Group Shared Information */
|
||||
memset(si, 0, sizeof(*si));
|
||||
si->major_version = 1;
|
||||
si->minor_version = 0;
|
||||
/* TODO: All values below should come from U-Boot DT somehow */
|
||||
si->mmio_base_low = 0xff192000;
|
||||
si->mmio_base_high = 0;
|
||||
si->gsi_interrupt = 32;
|
||||
si->interrupt_polarity = 1;
|
||||
si->interrupt_mode = 0;
|
||||
si->num_channels = 8;
|
||||
si->dma_address_width = 32;
|
||||
si->base_request_line = 0;
|
||||
si->num_handshake_signals = 16;
|
||||
si->max_block_size = 0x20000;
|
||||
|
||||
return grp->length;
|
||||
}
|
||||
|
||||
u32 acpi_fill_csrt(u32 current)
|
||||
{
|
||||
current += acpi_fill_csrt_dma((struct acpi_csrt_group *)current);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
@ -18,6 +18,7 @@ dtb-y += bayleybay.dtb \
|
||||
qemu-x86_i440fx.dtb \
|
||||
qemu-x86_q35.dtb \
|
||||
theadorable-x86-dfi-bt700.dtb \
|
||||
slimbootloader.dtb \
|
||||
baytrail_som-db5800-som-6867.dtb
|
||||
|
||||
targets += $(dtb-y)
|
||||
|
@ -84,15 +84,10 @@
|
||||
reg = <0xff3fc000 0x1000>;
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: For now U-Boot DM model doesn't allow to power up this controller.
|
||||
* Enabling it will make U-Boot hang.
|
||||
*
|
||||
sdcard: mmc@ff3fa000 {
|
||||
compatible = "intel,sdhci-tangier";
|
||||
reg = <0xff3fa000 0x1000>;
|
||||
};
|
||||
*/
|
||||
|
||||
pmu: power@ff00b000 {
|
||||
compatible = "intel,pmu-mid";
|
||||
|
27
arch/x86/dts/slimbootloader.dts
Normal file
27
arch/x86/dts/slimbootloader.dts
Normal file
@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
/include/ "reset.dtsi"
|
||||
/include/ "tsc_timer.dtsi"
|
||||
|
||||
/ {
|
||||
model = "slimbootloader x86 payload";
|
||||
compatible = "slimbootloader,x86-payload";
|
||||
|
||||
chosen {
|
||||
stdout-path = &serial;
|
||||
};
|
||||
|
||||
serial: serial {
|
||||
compatible = "intel,slimbootloader-uart";
|
||||
};
|
||||
|
||||
pci {
|
||||
compatible = "pci-x86";
|
||||
};
|
||||
};
|
@ -303,6 +303,37 @@ struct acpi_mcfg_mmconfig {
|
||||
/* ACPI global NVS structure */
|
||||
struct acpi_global_nvs;
|
||||
|
||||
/* CSRT (Core System Resource Table) */
|
||||
struct acpi_csrt {
|
||||
struct acpi_table_header header;
|
||||
};
|
||||
|
||||
struct acpi_csrt_group {
|
||||
u32 length;
|
||||
u32 vendor_id;
|
||||
u32 subvendor_id;
|
||||
u16 device_id;
|
||||
u16 subdevice_id;
|
||||
u16 revision;
|
||||
u16 reserved;
|
||||
u32 shared_info_length;
|
||||
};
|
||||
|
||||
struct acpi_csrt_shared_info {
|
||||
u16 major_version;
|
||||
u16 minor_version;
|
||||
u32 mmio_base_low;
|
||||
u32 mmio_base_high;
|
||||
u32 gsi_interrupt;
|
||||
u8 interrupt_polarity;
|
||||
u8 interrupt_mode;
|
||||
u8 num_channels;
|
||||
u8 dma_address_width;
|
||||
u16 base_request_line;
|
||||
u16 num_handshake_signals;
|
||||
u32 max_block_size;
|
||||
};
|
||||
|
||||
/* DBG2 definitions are partially used for SPCR interface_type */
|
||||
|
||||
/* Types for port_type field */
|
||||
@ -370,6 +401,7 @@ u32 acpi_fill_madt(u32 current);
|
||||
int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
|
||||
u16 seg_nr, u8 start, u8 end);
|
||||
u32 acpi_fill_mcfg(u32 current);
|
||||
u32 acpi_fill_csrt(u32 current);
|
||||
void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
|
||||
ulong write_acpi_tables(ulong start);
|
||||
|
||||
|
115
arch/x86/include/asm/arch-slimbootloader/slimbootloader.h
Normal file
115
arch/x86/include/asm/arch-slimbootloader/slimbootloader.h
Normal file
@ -0,0 +1,115 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __SLIMBOOTLOADER_ARCH_H__
|
||||
#define __SLIMBOOTLOADER_ARCH_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/hob.h>
|
||||
|
||||
/**
|
||||
* A GUID to get MemoryMap info hob which is provided by Slim Bootloader
|
||||
*/
|
||||
#define SBL_MEMORY_MAP_INFO_GUID \
|
||||
EFI_GUID(0xa1ff7424, 0x7a1a, 0x478e, \
|
||||
0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32)
|
||||
|
||||
/**
|
||||
* A GUID to get SerialPort info hob which is provided by Slim Bootloader
|
||||
*/
|
||||
#define SBL_SERIAL_PORT_INFO_GUID \
|
||||
EFI_GUID(0x6c6872fe, 0x56a9, 0x4403, \
|
||||
0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1)
|
||||
|
||||
/**
|
||||
* A GUID to get boot performance info hob which is provided by Slim Bootloader
|
||||
*/
|
||||
#define SBL_PERFORMANCE_INFO_GUID \
|
||||
EFI_GUID(0x868204be, 0x23d0, 0x4ff9, \
|
||||
0xac, 0x34, 0xb9, 0x95, 0xac, 0x04, 0xb1, 0xb9)
|
||||
|
||||
/**
|
||||
* A single entry of memory map information
|
||||
*
|
||||
* @addr: start address of a memory map entry
|
||||
* @size: size of a memory map entry
|
||||
* @type: usable:1, reserved:2, acpi:3, nvs:4, unusable:5
|
||||
* @flag: only used in Slim Bootloader
|
||||
* @rsvd: padding for alignment
|
||||
*/
|
||||
struct sbl_memory_map_entry {
|
||||
u64 addr;
|
||||
u64 size;
|
||||
u8 type;
|
||||
u8 flag;
|
||||
u8 rsvd[6];
|
||||
};
|
||||
|
||||
/**
|
||||
* This includes all memory map entries which is sorted based on physical start
|
||||
* address, from low to high, and carved out reserved, acpi nvs, acpi reclaim
|
||||
* and usable memory.
|
||||
*
|
||||
* @rev : revision of memory_map_info structure. currently 1.
|
||||
* @rsvd : padding for alignment
|
||||
* @count: the number of memory map entries
|
||||
* @entry: array of all memory map entries
|
||||
*/
|
||||
struct sbl_memory_map_info {
|
||||
u8 rev;
|
||||
u8 rsvd[3];
|
||||
u32 count;
|
||||
struct sbl_memory_map_entry entry[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* This includes serial port info which has already been initialized in previous
|
||||
* Slim Bootloader stage.
|
||||
* The Slim Bootloader initializes serial port regardless of debug/release build
|
||||
* modes, and it passes the information to a payload thru hob. So, a payload can
|
||||
* re-use the serial information without re-initializing serial port.
|
||||
*
|
||||
* @rev : revision of serial_port_info structure. currently 1.
|
||||
* @rsvd : padding for alignment
|
||||
* @type : port io: 1, mmio: 2
|
||||
* @base : io base address. ex) 0x3f8, 0x80001000
|
||||
* @baud : uart baud rate
|
||||
* @stride: register stride in Bytes
|
||||
* @clk : uart frequency in Hz
|
||||
* @rsvd1 : reserved
|
||||
*/
|
||||
struct sbl_serial_port_info {
|
||||
u8 rev;
|
||||
u8 rsvd[3];
|
||||
u32 type;
|
||||
u32 base;
|
||||
u32 baud;
|
||||
u32 stride;
|
||||
u32 clk;
|
||||
u32 rsvd1;
|
||||
};
|
||||
|
||||
/**
|
||||
* This includes timestamp data which has been collected in Slim Bootloader
|
||||
* stages from the reset vector. In addition, this has TSC frequency in KHz to
|
||||
* calculate each timestamp.
|
||||
*
|
||||
* @rev : revision of performance_info structure. currently 1.
|
||||
* @rsvd : padding for alignment
|
||||
* @count : the number of collected timestamp data
|
||||
* @flags : only used in Slim Bootloader
|
||||
* @frequency: tsc frequency in KHz
|
||||
* @timestamp: the array of timestamp data which has 64-bit tsc value
|
||||
*/
|
||||
struct sbl_performance_info {
|
||||
u8 rev;
|
||||
u8 rsvd[3];
|
||||
u16 count;
|
||||
u16 flags;
|
||||
u32 frequency;
|
||||
u64 timestamp[0];
|
||||
};
|
||||
|
||||
#endif /* __SLIMBOOTLOADER_ARCH_H__ */
|
@ -421,6 +421,28 @@ Device (PCI0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (GDMA)
|
||||
{
|
||||
Name (_ADR, 0x00150000)
|
||||
Name (_HID, "808611A2")
|
||||
Name (_UID, Zero)
|
||||
|
||||
Method (_STA, 0, NotSerialized)
|
||||
{
|
||||
Return (STA_VISIBLE)
|
||||
}
|
||||
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RBUF, ResourceTemplate ()
|
||||
{
|
||||
Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000)
|
||||
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 }
|
||||
})
|
||||
Return (RBUF)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (FLIS)
|
||||
|
@ -45,7 +45,7 @@ struct __packed ffs_file_header {
|
||||
* This GUID is the file name.
|
||||
* It is used to uniquely identify the file.
|
||||
*/
|
||||
struct efi_guid name;
|
||||
efi_guid_t name;
|
||||
/* Used to verify the integrity of the file */
|
||||
union ffs_integrity integrity;
|
||||
/* Identifies the type of file */
|
||||
@ -68,7 +68,7 @@ struct __packed ffs_file_header2 {
|
||||
* Name in any given firmware volume, except if the file type is
|
||||
* EFI_FV_FILE_TYPE_FFS_PAD.
|
||||
*/
|
||||
struct efi_guid name;
|
||||
efi_guid_t name;
|
||||
/* Used to verify the integrity of the file */
|
||||
union ffs_integrity integrity;
|
||||
/* Identifies the type of file */
|
||||
|
@ -80,7 +80,7 @@ struct fv_header {
|
||||
* Declares the file system with which the firmware volume
|
||||
* is formatted.
|
||||
*/
|
||||
struct efi_guid fs_guid;
|
||||
efi_guid_t fs_guid;
|
||||
/*
|
||||
* Length in bytes of the complete firmware volume, including
|
||||
* the header.
|
||||
@ -128,7 +128,7 @@ struct fv_header {
|
||||
/* Extension header pointed by ExtHeaderOffset of volume header */
|
||||
struct fv_ext_header {
|
||||
/* firmware volume name */
|
||||
struct efi_guid fv_name;
|
||||
efi_guid_t fv_name;
|
||||
/* Size of the rest of the extension header including this structure */
|
||||
u32 ext_hdr_size;
|
||||
};
|
||||
|
@ -7,124 +7,7 @@
|
||||
#ifndef __FSP_HOB_H__
|
||||
#define __FSP_HOB_H__
|
||||
|
||||
#include <efi.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 {
|
||||
u16 type; /* HOB type */
|
||||
u16 len; /* HOB length */
|
||||
u32 reserved; /* always zero */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
struct hob_header 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 is defined in
|
||||
* InstallProtocolInterface() in the UEFI 2.0 specification.
|
||||
*/
|
||||
struct efi_guid 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 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 {
|
||||
struct hob_header 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 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 {
|
||||
struct hob_header hdr;
|
||||
/* A GUID that defines the contents of this HOB */
|
||||
struct efi_guid name;
|
||||
/* GUID specific data goes here */
|
||||
};
|
||||
#include <asm/hob.h>
|
||||
|
||||
enum pixel_format {
|
||||
pixel_rgbx_8bpc, /* RGB 8 bit per color */
|
||||
@ -146,70 +29,6 @@ struct __packed hob_graphics_info {
|
||||
u32 pixels_per_scanline;
|
||||
};
|
||||
|
||||
/**
|
||||
* get_next_hob() - return 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: A pointer to the next HOB in the HOB list.
|
||||
*/
|
||||
static inline const struct hob_header *get_next_hob(const struct hob_header *hdr)
|
||||
{
|
||||
return (const struct hob_header *)((uintptr_t)hdr + hdr->len);
|
||||
}
|
||||
|
||||
/**
|
||||
* end_of_hob() - determine 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @retval true: The HOB specified by hdr is the last HOB in the HOB list.
|
||||
* @retval false: The HOB specified by hdr is not the last HOB in the HOB list.
|
||||
*/
|
||||
static inline bool end_of_hob(const struct hob_header *hdr)
|
||||
{
|
||||
return hdr->type == HOB_TYPE_EOH;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_guid_hob_data() - return 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: A pointer to the data buffer in a HOB.
|
||||
*/
|
||||
static inline void *get_guid_hob_data(const struct hob_header *hdr)
|
||||
{
|
||||
return (void *)((uintptr_t)hdr + sizeof(struct hob_guid));
|
||||
}
|
||||
|
||||
/**
|
||||
* get_guid_hob_data_size() - return 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: The size of the data buffer.
|
||||
*/
|
||||
static inline u16 get_guid_hob_data_size(const struct hob_header *hdr)
|
||||
{
|
||||
return hdr->len - sizeof(struct hob_guid);
|
||||
}
|
||||
|
||||
/* FSP specific GUID HOB definitions */
|
||||
#define FSP_GUID_DATA1 0x912740be
|
||||
#define FSP_GUID_DATA2 0x2284
|
||||
@ -223,56 +42,57 @@ static inline u16 get_guid_hob_data_size(const struct hob_header *hdr)
|
||||
#define FSP_GUID_DATA4_6 0x3f
|
||||
#define FSP_GUID_DATA4_7 0x0c
|
||||
|
||||
#define FSP_GUID_BYTE0 0xbe
|
||||
#define FSP_GUID_BYTE1 0x40
|
||||
#define FSP_GUID_BYTE2 0x27
|
||||
#define FSP_GUID_BYTE3 0x91
|
||||
#define FSP_GUID_BYTE4 0x84
|
||||
#define FSP_GUID_BYTE5 0x22
|
||||
#define FSP_GUID_BYTE6 0x34
|
||||
#define FSP_GUID_BYTE7 0x47
|
||||
#define FSP_GUID_BYTE8 FSP_GUID_DATA4_0
|
||||
#define FSP_GUID_BYTE9 FSP_GUID_DATA4_1
|
||||
#define FSP_GUID_BYTE10 FSP_GUID_DATA4_2
|
||||
#define FSP_GUID_BYTE11 FSP_GUID_DATA4_3
|
||||
#define FSP_GUID_BYTE12 FSP_GUID_DATA4_4
|
||||
#define FSP_GUID_BYTE13 FSP_GUID_DATA4_5
|
||||
#define FSP_GUID_BYTE14 FSP_GUID_DATA4_6
|
||||
#define FSP_GUID_BYTE15 FSP_GUID_DATA4_7
|
||||
|
||||
#define FSP_HEADER_GUID \
|
||||
{ \
|
||||
FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \
|
||||
{ FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \
|
||||
FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \
|
||||
FSP_GUID_DATA4_6, FSP_GUID_DATA4_7 } \
|
||||
}
|
||||
EFI_GUID(FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \
|
||||
FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \
|
||||
FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \
|
||||
FSP_GUID_DATA4_6, FSP_GUID_DATA4_7)
|
||||
|
||||
#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
|
||||
{ \
|
||||
0x721acf02, 0x4d77, 0x4c2a, \
|
||||
{ 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
|
||||
}
|
||||
EFI_GUID(0x721acf02, 0x4d77, 0x4c2a, \
|
||||
0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0)
|
||||
|
||||
#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \
|
||||
{ \
|
||||
0xbbcff46c, 0xc8d3, 0x4113, \
|
||||
{ 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } \
|
||||
}
|
||||
EFI_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 } \
|
||||
}
|
||||
EFI_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 } \
|
||||
}
|
||||
EFI_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 } \
|
||||
}
|
||||
EFI_GUID(0x9c7c3aa7, 0x5332, 0x4917, \
|
||||
0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07)
|
||||
|
||||
/* The following GUIDs are newly introduced in FSP spec 1.1 */
|
||||
|
||||
#define FSP_HOB_RESOURCE_OWNER_BOOTLOADER_TOLUM_GUID \
|
||||
{ \
|
||||
0x73ff4f56, 0xaa8e, 0x4451, \
|
||||
{ 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44 } \
|
||||
}
|
||||
EFI_GUID(0x73ff4f56, 0xaa8e, 0x4451, \
|
||||
0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44)
|
||||
|
||||
#define FSP_GRAPHICS_INFO_HOB_GUID \
|
||||
{ \
|
||||
0x39f62cce, 0x6825, 0x4669, \
|
||||
{ 0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07 } \
|
||||
}
|
||||
EFI_GUID(0x39f62cce, 0x6825, 0x4669, \
|
||||
0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07)
|
||||
|
||||
#endif
|
||||
|
@ -8,10 +8,10 @@
|
||||
#define __FSP_SUPPORT_H__
|
||||
|
||||
#include "fsp_types.h"
|
||||
#include "fsp_hob.h"
|
||||
#include "fsp_fv.h"
|
||||
#include "fsp_ffs.h"
|
||||
#include "fsp_api.h"
|
||||
#include "fsp_hob.h"
|
||||
#include "fsp_infoheader.h"
|
||||
#include "fsp_bootmode.h"
|
||||
#include "fsp_azalia.h"
|
||||
@ -106,7 +106,7 @@ u64 fsp_get_usable_highmem_top(const void *hob_list);
|
||||
* 0 if this region does not exist.
|
||||
*/
|
||||
u64 fsp_get_reserved_mem_from_guid(const void *hob_list,
|
||||
u64 *len, struct efi_guid *guid);
|
||||
u64 *len, const efi_guid_t *guid);
|
||||
|
||||
/**
|
||||
* This function retrieves the FSP reserved normal memory.
|
||||
@ -131,41 +131,6 @@ u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len);
|
||||
*/
|
||||
u32 fsp_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.
|
||||
*/
|
||||
const struct hob_header *fsp_get_next_hob(uint 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.
|
||||
*/
|
||||
const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *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 *fsp_get_guid_hob_data(const void *hob_list, u32 *len,
|
||||
struct efi_guid *guid);
|
||||
|
||||
/**
|
||||
* This function retrieves FSP Non-volatile Storage HOB buffer and size.
|
||||
*
|
||||
|
@ -7,14 +7,6 @@
|
||||
#ifndef __FSP_TYPES_H__
|
||||
#define __FSP_TYPES_H__
|
||||
|
||||
/* 128 bit buffer containing a unique identifier value */
|
||||
struct efi_guid {
|
||||
u32 data1;
|
||||
u16 data2;
|
||||
u16 data3;
|
||||
u8 data4[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a 16-bit signature built from 2 ASCII characters.
|
||||
*
|
||||
|
@ -83,7 +83,7 @@ struct arch_global_data {
|
||||
const struct pch_gpio_map *gpio_map; /* board GPIO map */
|
||||
struct memory_info meminfo; /* Memory information */
|
||||
struct pei_memory_info pei_meminfo; /* PEI memory information */
|
||||
#ifdef CONFIG_HAVE_FSP
|
||||
#ifdef CONFIG_USE_HOB
|
||||
void *hob_list; /* FSP HOB list */
|
||||
#endif
|
||||
struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS];
|
||||
|
230
arch/x86/include/asm/hob.h
Normal file
230
arch/x86/include/asm/hob.h
Normal file
@ -0,0 +1,230 @@
|
||||
/* SPDX-License-Identifier: Intel */
|
||||
/*
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __HOB_H__
|
||||
#define __HOB_H__
|
||||
|
||||
#include <efi.h>
|
||||
#include <efi_loader.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
|
||||
|
||||
/* 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 format and size of the data inside the HOB.
|
||||
* All HOBs must contain this generic HOB header.
|
||||
*/
|
||||
struct hob_header {
|
||||
u16 type; /* HOB type */
|
||||
u16 len; /* HOB length */
|
||||
u32 reserved; /* always zero */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
struct hob_header 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.
|
||||
*/
|
||||
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 mem_type;
|
||||
/* padding */
|
||||
u8 reserved[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
struct hob_header 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.
|
||||
*/
|
||||
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 {
|
||||
struct hob_header hdr;
|
||||
/* A GUID that defines the contents of this HOB */
|
||||
efi_guid_t name;
|
||||
/* GUID specific data goes here */
|
||||
};
|
||||
|
||||
/**
|
||||
* get_next_hob() - return 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: A pointer to the next HOB in the HOB list.
|
||||
*/
|
||||
static inline const struct hob_header *get_next_hob(const struct hob_header
|
||||
*hdr)
|
||||
{
|
||||
return (const struct hob_header *)((uintptr_t)hdr + hdr->len);
|
||||
}
|
||||
|
||||
/**
|
||||
* end_of_hob() - determine 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @retval true: The HOB specified by hdr is the last HOB in the HOB list.
|
||||
* @retval false: The HOB specified by hdr is not the last HOB in the HOB list.
|
||||
*/
|
||||
static inline bool end_of_hob(const struct hob_header *hdr)
|
||||
{
|
||||
return hdr->type == HOB_TYPE_EOH;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_guid_hob_data() - return 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: A pointer to the data buffer in a HOB.
|
||||
*/
|
||||
static inline void *get_guid_hob_data(const struct hob_header *hdr)
|
||||
{
|
||||
return (void *)((uintptr_t)hdr + sizeof(struct hob_guid));
|
||||
}
|
||||
|
||||
/**
|
||||
* get_guid_hob_data_size() - return 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.
|
||||
*
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: The size of the data buffer.
|
||||
*/
|
||||
static inline u16 get_guid_hob_data_size(const struct hob_header *hdr)
|
||||
{
|
||||
return hdr->len - sizeof(struct hob_guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
const struct hob_header *hob_get_next_hob(uint 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.
|
||||
*/
|
||||
const struct hob_header *hob_get_next_guid_hob(const 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 *hob_get_guid_hob_data(const void *hob_list, u32 *len,
|
||||
const efi_guid_t *guid);
|
||||
|
||||
#endif /* __HOB_H__ */
|
@ -42,6 +42,7 @@ obj-y += tables.o
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_CMD_ZBOOT) += zimage.o
|
||||
endif
|
||||
obj-$(CONFIG_USE_HOB) += hob.o
|
||||
obj-$(CONFIG_HAVE_FSP) += fsp/
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
|
@ -337,6 +337,30 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
|
||||
header->checksum = table_compute_checksum((void *)mcfg, header->length);
|
||||
}
|
||||
|
||||
__weak u32 acpi_fill_csrt(u32 current)
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
static void acpi_create_csrt(struct acpi_csrt *csrt)
|
||||
{
|
||||
struct acpi_table_header *header = &(csrt->header);
|
||||
u32 current = (u32)csrt + sizeof(struct acpi_csrt);
|
||||
|
||||
memset((void *)csrt, 0, sizeof(struct acpi_csrt));
|
||||
|
||||
/* Fill out header fields */
|
||||
acpi_fill_header(header, "CSRT");
|
||||
header->length = sizeof(struct acpi_csrt);
|
||||
header->revision = 0;
|
||||
|
||||
current = acpi_fill_csrt(current);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
header->length = current - (u32)csrt;
|
||||
header->checksum = table_compute_checksum((void *)csrt, header->length);
|
||||
}
|
||||
|
||||
static void acpi_create_spcr(struct acpi_spcr *spcr)
|
||||
{
|
||||
struct acpi_table_header *header = &(spcr->header);
|
||||
@ -464,6 +488,7 @@ ulong write_acpi_tables(ulong start)
|
||||
struct acpi_fadt *fadt;
|
||||
struct acpi_mcfg *mcfg;
|
||||
struct acpi_madt *madt;
|
||||
struct acpi_csrt *csrt;
|
||||
struct acpi_spcr *spcr;
|
||||
int i;
|
||||
|
||||
@ -553,6 +578,13 @@ ulong write_acpi_tables(ulong start)
|
||||
acpi_add_table(rsdp, mcfg);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: * CSRT\n");
|
||||
csrt = (struct acpi_csrt *)current;
|
||||
acpi_create_csrt(csrt);
|
||||
current += csrt->header.length;
|
||||
acpi_add_table(rsdp, csrt);
|
||||
current = ALIGN(current, 16);
|
||||
|
||||
debug("ACPI: * SPCR\n");
|
||||
spcr = (struct acpi_spcr *)current;
|
||||
acpi_create_spcr(spcr);
|
||||
|
@ -17,7 +17,7 @@
|
||||
int main(void)
|
||||
{
|
||||
DEFINE(GD_BIST, offsetof(gd_t, arch.bist));
|
||||
#ifdef CONFIG_HAVE_FSP
|
||||
#ifdef CONFIG_USE_HOB
|
||||
DEFINE(GD_HOB_LIST, offsetof(gd_t, arch.hob_list));
|
||||
#endif
|
||||
DEFINE(GD_TABLE, offsetof(gd_t, arch.table));
|
||||
|
@ -8,27 +8,6 @@
|
||||
#include <asm/fsp/fsp_support.h>
|
||||
#include <asm/post.h>
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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 bool compare_guid(const struct efi_guid *guid1,
|
||||
const struct efi_guid *guid2)
|
||||
{
|
||||
if (memcmp(guid1, guid2, sizeof(struct efi_guid)) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void)
|
||||
{
|
||||
/*
|
||||
@ -58,17 +37,22 @@ struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void)
|
||||
|
||||
/* Check the FFS GUID */
|
||||
if (fsp &&
|
||||
((struct ffs_file_header *)fsp)->name.data1 == FSP_GUID_DATA1 &&
|
||||
((struct ffs_file_header *)fsp)->name.data2 == FSP_GUID_DATA2 &&
|
||||
((struct ffs_file_header *)fsp)->name.data3 == FSP_GUID_DATA3 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[0] == FSP_GUID_DATA4_0 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[1] == FSP_GUID_DATA4_1 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[2] == FSP_GUID_DATA4_2 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[3] == FSP_GUID_DATA4_3 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[4] == FSP_GUID_DATA4_4 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[5] == FSP_GUID_DATA4_5 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[6] == FSP_GUID_DATA4_6 &&
|
||||
((struct ffs_file_header *)fsp)->name.data4[7] == FSP_GUID_DATA4_7) {
|
||||
((struct ffs_file_header *)fsp)->name.b[0] == FSP_GUID_BYTE0 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[1] == FSP_GUID_BYTE1 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[2] == FSP_GUID_BYTE2 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[3] == FSP_GUID_BYTE3 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[4] == FSP_GUID_BYTE4 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[5] == FSP_GUID_BYTE5 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[6] == FSP_GUID_BYTE6 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[7] == FSP_GUID_BYTE7 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[8] == FSP_GUID_BYTE8 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[9] == FSP_GUID_BYTE9 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[10] == FSP_GUID_BYTE10 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[11] == FSP_GUID_BYTE11 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[12] == FSP_GUID_BYTE12 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[13] == FSP_GUID_BYTE13 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[14] == FSP_GUID_BYTE14 &&
|
||||
((struct ffs_file_header *)fsp)->name.b[15] == FSP_GUID_BYTE15) {
|
||||
/* Add the FFS header size to find the raw section header */
|
||||
fsp += sizeof(struct ffs_file_header);
|
||||
} else {
|
||||
@ -305,7 +289,7 @@ u64 fsp_get_usable_highmem_top(const void *hob_list)
|
||||
}
|
||||
|
||||
u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len,
|
||||
struct efi_guid *guid)
|
||||
const efi_guid_t *guid)
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
struct hob_res_desc *res_desc;
|
||||
@ -318,7 +302,7 @@ u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len,
|
||||
if (hdr->type == HOB_TYPE_RES_DESC) {
|
||||
res_desc = (struct hob_res_desc *)hdr;
|
||||
if (res_desc->type == RES_MEM_RESERVED) {
|
||||
if (compare_guid(&res_desc->owner, guid)) {
|
||||
if (!guidcmp(&res_desc->owner, guid)) {
|
||||
if (len)
|
||||
*len = (u32)(res_desc->len);
|
||||
|
||||
@ -334,12 +318,12 @@ u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len,
|
||||
|
||||
u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len)
|
||||
{
|
||||
const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID;
|
||||
const efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID;
|
||||
u64 length;
|
||||
u32 base;
|
||||
|
||||
base = (u32)fsp_get_reserved_mem_from_guid(hob_list,
|
||||
&length, (struct efi_guid *)&guid);
|
||||
&length, &guid);
|
||||
if ((len != 0) && (base != 0))
|
||||
*len = (u32)length;
|
||||
|
||||
@ -348,86 +332,35 @@ u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len)
|
||||
|
||||
u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len)
|
||||
{
|
||||
const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID;
|
||||
const efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID;
|
||||
u64 length;
|
||||
u32 base;
|
||||
|
||||
base = (u32)fsp_get_reserved_mem_from_guid(hob_list,
|
||||
&length, (struct efi_guid *)&guid);
|
||||
&length, &guid);
|
||||
if ((len != 0) && (base != 0))
|
||||
*len = (u32)length;
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list)
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
|
||||
hdr = hob_list;
|
||||
|
||||
/* Parse the HOB list until end of list or matching type is found */
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == type)
|
||||
return hdr;
|
||||
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid,
|
||||
const void *hob_list)
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
struct hob_guid *guid_hob;
|
||||
|
||||
hdr = hob_list;
|
||||
while ((hdr = fsp_get_next_hob(HOB_TYPE_GUID_EXT,
|
||||
hdr)) != NULL) {
|
||||
guid_hob = (struct hob_guid *)hdr;
|
||||
if (compare_guid(guid, &(guid_hob->name)))
|
||||
break;
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
void *fsp_get_guid_hob_data(const void *hob_list, u32 *len,
|
||||
struct efi_guid *guid)
|
||||
{
|
||||
const struct hob_header *guid_hob;
|
||||
|
||||
guid_hob = fsp_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 *fsp_get_nvs_data(const void *hob_list, u32 *len)
|
||||
{
|
||||
const struct efi_guid guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
|
||||
const efi_guid_t guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
|
||||
|
||||
return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid);
|
||||
return hob_get_guid_hob_data(hob_list, len, &guid);
|
||||
}
|
||||
|
||||
void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len)
|
||||
{
|
||||
const struct efi_guid guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID;
|
||||
const efi_guid_t guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID;
|
||||
|
||||
return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid);
|
||||
return hob_get_guid_hob_data(hob_list, len, &guid);
|
||||
}
|
||||
|
||||
void *fsp_get_graphics_info(const void *hob_list, u32 *len)
|
||||
{
|
||||
const struct efi_guid guid = FSP_GRAPHICS_INFO_HOB_GUID;
|
||||
const efi_guid_t guid = FSP_GRAPHICS_INFO_HOB_GUID;
|
||||
|
||||
return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid);
|
||||
return hob_get_guid_hob_data(hob_list, len, &guid);
|
||||
}
|
||||
|
84
arch/x86/lib/hob.c
Normal file
84
arch/x86/lib/hob.c
Normal file
@ -0,0 +1,84 @@
|
||||
// SPDX-License-Identifier: Intel
|
||||
/*
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/hob.h>
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
const struct hob_header *hob_get_next_hob(uint type, const void *hob_list)
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
|
||||
hdr = hob_list;
|
||||
|
||||
/* Parse the HOB list until end of list or matching type is found */
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == type)
|
||||
return hdr;
|
||||
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid,
|
||||
const void *hob_list)
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
struct hob_guid *guid_hob;
|
||||
|
||||
hdr = hob_list;
|
||||
while ((hdr = hob_get_next_hob(HOB_TYPE_GUID_EXT, hdr))) {
|
||||
guid_hob = (struct hob_guid *)hdr;
|
||||
if (!guidcmp(guid, &guid_hob->name))
|
||||
break;
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 *hob_get_guid_hob_data(const void *hob_list, u32 *len,
|
||||
const efi_guid_t *guid)
|
||||
{
|
||||
const struct hob_header *guid_hob;
|
||||
|
||||
guid_hob = hob_get_next_guid_hob(guid, hob_list);
|
||||
if (!guid_hob)
|
||||
return NULL;
|
||||
|
||||
if (len)
|
||||
*len = get_guid_hob_data_size(guid_hob);
|
||||
|
||||
return get_guid_hob_data(guid_hob);
|
||||
}
|
@ -18,7 +18,8 @@ __weak ulong board_get_usable_ram_top(ulong total_size)
|
||||
|
||||
int init_cache_f_r(void)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP)
|
||||
#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) && \
|
||||
!defined(CONFIG_SYS_SLIMBOOTLOADER)
|
||||
int ret;
|
||||
|
||||
ret = mtrr_commit(false);
|
||||
|
@ -73,6 +73,19 @@ config TARGET_MINNOWMAX
|
||||
Note that PCIE_ECAM_BASE is set up by the FSP so the value used
|
||||
by U-Boot matches that value.
|
||||
|
||||
config TARGET_SLIMBOOTLOADER
|
||||
bool "slimbootloader"
|
||||
help
|
||||
This target is used for running U-Boot on top of Slim Bootloader
|
||||
boot firmware as a payload. Slim Bootloader does memory initialization
|
||||
and silicon initialization, and it passes necessary information in
|
||||
HOB (Hand Off Block) to a payload. The payload consumes HOB data
|
||||
which is generated by Slim Bootloader for its driver initialization.
|
||||
Slim Bootloader consumes FSP and its HOB, but FSP HOB is cleared
|
||||
Before launching a payload. Instead, Slim Bootloader generates its
|
||||
HOB data such as memory info, serial port info and so on.
|
||||
Refer to doc/board/intel/slimbootloader.rst for the details.
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/intel/bayleybay/Kconfig"
|
||||
@ -82,5 +95,6 @@ source "board/intel/crownbay/Kconfig"
|
||||
source "board/intel/edison/Kconfig"
|
||||
source "board/intel/galileo/Kconfig"
|
||||
source "board/intel/minnowmax/Kconfig"
|
||||
source "board/intel/slimbootloader/Kconfig"
|
||||
|
||||
endif
|
||||
|
@ -13,9 +13,19 @@
|
||||
#include <linux/usb/gadget.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/pmu.h>
|
||||
#include <asm/scu.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
|
||||
/* List of Intel Tangier LSSs */
|
||||
#define PMU_LSS_TANGIER_SDIO0_01 1
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
pmu_turn_power(PMU_LSS_TANGIER_SDIO0_01, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dwc3_device dwc3_device_data = {
|
||||
.maximum_speed = USB_SPEED_HIGH,
|
||||
.base = CONFIG_SYS_USB_OTG_BASE,
|
||||
|
28
board/intel/slimbootloader/Kconfig
Normal file
28
board/intel/slimbootloader/Kconfig
Normal file
@ -0,0 +1,28 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
|
||||
if TARGET_SLIMBOOTLOADER
|
||||
|
||||
config SYS_BOARD
|
||||
default "slimbootloader"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "intel"
|
||||
|
||||
config SYS_SOC
|
||||
default "slimbootloader"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "slimbootloader"
|
||||
|
||||
config SYS_TEXT_BASE
|
||||
default 0x00100000
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select SYS_SLIMBOOTLOADER
|
||||
select USB_STORAGE
|
||||
select USB_KEYBOARD
|
||||
|
||||
endif
|
6
board/intel/slimbootloader/MAINTAINERS
Normal file
6
board/intel/slimbootloader/MAINTAINERS
Normal file
@ -0,0 +1,6 @@
|
||||
Intel Slim Bootloader Payload
|
||||
M: Aiden Park <aiden.park@intel.com>
|
||||
S: Maintained
|
||||
F: board/intel/slimbootloader
|
||||
F: include/configs/slimbootloader.h
|
||||
F: configs/slimbootloader_defconfig
|
5
board/intel/slimbootloader/Makefile
Normal file
5
board/intel/slimbootloader/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
|
||||
obj-y += start.o slimbootloader.o
|
21
board/intel/slimbootloader/slimbootloader.c
Normal file
21
board/intel/slimbootloader/slimbootloader.c
Normal file
@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
/*
|
||||
* Make sure PCI bus is enumerated so that peripherals on the PCI bus
|
||||
* can be discovered by their drivers.
|
||||
*
|
||||
* Slim Bootloader has already done PCI bus enumeration before loading
|
||||
* U-Boot, so U-Boot needs to preserve PCI configuration.
|
||||
* Therefore, '# CONFIG_PCI_PNP is not set' is included in defconfig.
|
||||
*/
|
||||
pci_init();
|
||||
|
||||
return 0;
|
||||
}
|
9
board/intel/slimbootloader/start.S
Normal file
9
board/intel/slimbootloader/start.S
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
/* board early initialization */
|
||||
.globl early_board_init
|
||||
early_board_init:
|
||||
jmp early_board_init_ret
|
@ -2,4 +2,5 @@
|
||||
|
||||
obj-y += mtrr.o
|
||||
obj-$(CONFIG_CMD_EXCEPTION) += exception.o
|
||||
obj-$(CONFIG_USE_HOB) += hob.o
|
||||
obj-$(CONFIG_HAVE_FSP) += fsp.o
|
||||
|
@ -9,21 +9,6 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static char *hob_type[] = {
|
||||
"reserved",
|
||||
"Hand-off",
|
||||
"Mem Alloc",
|
||||
"Res Desc",
|
||||
"GUID Ext",
|
||||
"FV",
|
||||
"CPU",
|
||||
"Mem Pool",
|
||||
"reserved",
|
||||
"FV2",
|
||||
"Load PEIM",
|
||||
"Capsule",
|
||||
};
|
||||
|
||||
static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
struct fsp_header *hdr = find_fsp_header();
|
||||
@ -72,57 +57,8 @@ static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
uint type;
|
||||
char *desc;
|
||||
int i = 0;
|
||||
|
||||
hdr = gd->arch.hob_list;
|
||||
|
||||
printf("HOB list address: 0x%08x\n\n", (unsigned int)hdr);
|
||||
|
||||
printf("# | Address | Type | Len | ");
|
||||
printf("%42s\n", "GUID");
|
||||
printf("---|----------|-----------|------|-");
|
||||
printf("------------------------------------------\n");
|
||||
while (!end_of_hob(hdr)) {
|
||||
printf("%02x | %08x | ", i, (unsigned int)hdr);
|
||||
type = hdr->type;
|
||||
if (type == HOB_TYPE_UNUSED)
|
||||
desc = "*Unused*";
|
||||
else if (type == HOB_TYPE_EOH)
|
||||
desc = "*EOH*";
|
||||
else if (type >= 0 && type <= ARRAY_SIZE(hob_type))
|
||||
desc = hob_type[type];
|
||||
else
|
||||
desc = "*Invalid*";
|
||||
printf("%-9s | %04x | ", desc, hdr->len);
|
||||
|
||||
if (type == HOB_TYPE_MEM_ALLOC || type == HOB_TYPE_RES_DESC ||
|
||||
type == HOB_TYPE_GUID_EXT) {
|
||||
struct efi_guid *guid = (struct efi_guid *)(hdr + 1);
|
||||
int j;
|
||||
|
||||
printf("%08x-%04x-%04x", guid->data1,
|
||||
guid->data2, guid->data3);
|
||||
for (j = 0; j < ARRAY_SIZE(guid->data4); j++)
|
||||
printf("-%02x", guid->data4[j]);
|
||||
} else {
|
||||
printf("%42s", "Not Available");
|
||||
}
|
||||
printf("\n");
|
||||
hdr = get_next_hob(hdr);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cmd_tbl_t fsp_commands[] = {
|
||||
U_BOOT_CMD_MKENT(hdr, 0, 1, do_hdr, "", ""),
|
||||
U_BOOT_CMD_MKENT(hob, 0, 1, do_hob, "", ""),
|
||||
};
|
||||
|
||||
static int do_fsp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
@ -146,6 +82,5 @@ static int do_fsp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
U_BOOT_CMD(
|
||||
fsp, 2, 1, do_fsp,
|
||||
"Show Intel Firmware Support Package (FSP) related information",
|
||||
"hdr - Print FSP header information\n"
|
||||
"fsp hob - Print FSP Hand-Off Block (HOB) information"
|
||||
"hdr - Print FSP header information"
|
||||
);
|
||||
|
77
cmd/x86/hob.c
Normal file
77
cmd/x86/hob.c
Normal file
@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014-2015, Bin Meng <bmeng.cn@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <efi.h>
|
||||
#include <asm/hob.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static char *hob_type[] = {
|
||||
"reserved",
|
||||
"Hand-off",
|
||||
"Mem Alloc",
|
||||
"Res Desc",
|
||||
"GUID Ext",
|
||||
"FV",
|
||||
"CPU",
|
||||
"Mem Pool",
|
||||
"reserved",
|
||||
"FV2",
|
||||
"Load PEIM",
|
||||
"Capsule",
|
||||
};
|
||||
|
||||
static int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
const struct hob_header *hdr;
|
||||
uint type;
|
||||
char *desc;
|
||||
int i = 0;
|
||||
efi_guid_t *guid;
|
||||
char uuid[UUID_STR_LEN + 1];
|
||||
|
||||
hdr = gd->arch.hob_list;
|
||||
|
||||
printf("HOB list address: 0x%08x\n\n", (unsigned int)hdr);
|
||||
|
||||
printf("# | Address | Type | Len | ");
|
||||
printf("%36s\n", "GUID");
|
||||
printf("---|----------|-----------|------|-");
|
||||
printf("------------------------------------\n");
|
||||
while (!end_of_hob(hdr)) {
|
||||
printf("%02x | %08x | ", i, (unsigned int)hdr);
|
||||
type = hdr->type;
|
||||
if (type == HOB_TYPE_UNUSED)
|
||||
desc = "*Unused*";
|
||||
else if (type == HOB_TYPE_EOH)
|
||||
desc = "*EOH*";
|
||||
else if (type >= 0 && type <= ARRAY_SIZE(hob_type))
|
||||
desc = hob_type[type];
|
||||
else
|
||||
desc = "*Invalid*";
|
||||
printf("%-9s | %04x | ", desc, hdr->len);
|
||||
|
||||
if (type == HOB_TYPE_MEM_ALLOC || type == HOB_TYPE_RES_DESC ||
|
||||
type == HOB_TYPE_GUID_EXT) {
|
||||
guid = (efi_guid_t *)(hdr + 1);
|
||||
uuid_bin_to_str(guid->b, uuid, UUID_STR_FORMAT_GUID);
|
||||
printf("%s", uuid);
|
||||
} else {
|
||||
printf("%36s", "Not Available");
|
||||
}
|
||||
printf("\n");
|
||||
hdr = get_next_hob(hdr);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(hob, 1, 1, do_hob,
|
||||
"Print Hand-Off Block (HOB) information",
|
||||
""
|
||||
);
|
@ -4,6 +4,7 @@ CONFIG_NR_DRAM_BANKS=3
|
||||
CONFIG_VENDOR_INTEL=y
|
||||
CONFIG_TARGET_EDISON=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_BOARD_EARLY_INIT_R=y
|
||||
CONFIG_LAST_STAGE_INIT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
# CONFIG_CMDLINE_EDITING is not set
|
||||
|
@ -12,6 +12,7 @@ CONFIG_SMP=y
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_BUILD_ROM=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_SPL_LOAD_FIT=y
|
||||
|
@ -6,6 +6,7 @@ CONFIG_SMP=y
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_BUILD_ROM=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
|
22
configs/slimbootloader_defconfig
Normal file
22
configs/slimbootloader_defconfig
Normal file
@ -0,0 +1,22 @@
|
||||
CONFIG_X86=y
|
||||
CONFIG_VENDOR_INTEL=y
|
||||
CONFIG_TARGET_SLIMBOOTLOADER=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="slimbootloader"
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_SYSCON=y
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_BOARD_EARLY_INIT_R=y
|
||||
CONFIG_LAST_STAGE_INIT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_DOS_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_BOOTSTAGE=y
|
||||
CONFIG_BOOTSTAGE_REPORT=y
|
||||
CONFIG_BOOTDELAY=10
|
||||
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||
# CONFIG_PCI_PNP is not set
|
@ -54,6 +54,23 @@ If you want to check both consoles, use '-serial stdio'.
|
||||
Multicore is also supported by QEMU via '-smp n' where n is the number of cores
|
||||
to instantiate. Note, the maximum supported CPU number in QEMU is 255.
|
||||
|
||||
U-Boot uses 'distro_bootcmd' by default when booting on x86 QEMU. This tries to
|
||||
load a boot script, kernel, and ramdisk from several different interfaces. For
|
||||
the default boot order, see 'qemu-x86.h'. For more information, see
|
||||
'README.distro'. Most Linux distros can be booted by writing a uboot script.
|
||||
For example, Debian (stretch) can be booted by creating a script file named
|
||||
'boot.txt' with the contents::
|
||||
|
||||
setenv bootargs root=/dev/sda1 ro
|
||||
load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /vmlinuz
|
||||
load ${devtype} ${devnum}:${distro_bootpart} ${ramdisk_addr_r} /initrd.img
|
||||
zboot ${kernel_addr_r} - ${ramdisk_addr_r} ${filesize}
|
||||
|
||||
Then compile and install it with::
|
||||
|
||||
$ apt install u-boot-tools && \
|
||||
mkimage -T script -C none -n "Boot script" -d boot.txt /boot/boot.scr
|
||||
|
||||
The fw_cfg interface in QEMU also provides information about kernel data,
|
||||
initrd, command-line arguments and more. U-Boot supports directly accessing
|
||||
these informtion from fw_cfg interface, which saves the time of loading them
|
||||
|
@ -13,3 +13,4 @@ Intel
|
||||
edison
|
||||
galileo
|
||||
minnowmax
|
||||
slimbootloader
|
||||
|
174
doc/board/intel/slimbootloader.rst
Normal file
174
doc/board/intel/slimbootloader.rst
Normal file
@ -0,0 +1,174 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. sectionauthor:: Aiden Park <aiden.park@intel.com>
|
||||
|
||||
Slim Bootloader
|
||||
===============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This target is to enable U-Boot_ as a payload of `Slim Bootloader`_ (a.k.a SBL)
|
||||
boot firmware which currently supports QEMU, Apollolake, Whiskeylake,
|
||||
Coffeelake-R platforms.
|
||||
|
||||
The `Slim Bootloader`_ is designed with multi-stages (Stage1A/B, Stage2, Payload)
|
||||
architecture to cover from reset vector to OS booting and it consumes
|
||||
`Intel FSP`_ for silicon initialization.
|
||||
|
||||
* Stage1A: Reset vector, CAR init with FSP-T
|
||||
* Stage1B: Memory init with FSP-M, CAR teardown, Continue execution in memory
|
||||
* Stage2 : Rest of Silicon init with FSP-S, Create HOB, Hand-off to Payload
|
||||
* Payload: Payload init with HOB, Load OS from media, Booting OS
|
||||
|
||||
The Slim Bootloader stages (Stage1A/B, Stage2) focus on chipset, hardware and
|
||||
platform specific initialization, and it provides useful information to a
|
||||
payload in a HOB (Hand-Off Block) which has serial port, memory map, performance
|
||||
data info and so on. This is Slim Bootloader architectural design to make a
|
||||
payload light-weight, platform independent and more generic across different
|
||||
boot solutions or payloads, and to minimize hardware re-initialization in a
|
||||
payload.
|
||||
|
||||
Build Instruction for U-Boot as a Slim Bootloader payload
|
||||
---------------------------------------------------------
|
||||
|
||||
Build U-Boot and obtain u-boot-dtb.bin::
|
||||
|
||||
$ make distclean
|
||||
$ make slimbootloader_defconfig
|
||||
$ make all
|
||||
|
||||
Prepare Slim Bootloader
|
||||
-----------------------
|
||||
|
||||
1. Setup Build Environment for Slim Bootloader.
|
||||
|
||||
Refer to `Getting Started`_ page in `Slim Bootloader`_ document site.
|
||||
|
||||
2. Get source code. Let's simply clone the repo::
|
||||
|
||||
$ git clone https://github.com/slimbootloader/slimbootloader.git
|
||||
|
||||
3. Copy u-boot-dtb.bin to Slim Bootloader.
|
||||
Slim Bootloader looks for a payload from the specific location.
|
||||
Copy the build u-boot-dtb.bin to the expected location::
|
||||
|
||||
$ mkdir -p <Slim Bootloader Dir>/PayloadPkg/PayloadBins/
|
||||
$ cp <U-Boot Dir>/u-boot-dtb.bin <Slim Bootloader Dir>/PayloadPkg/PayloadBins/u-boot-dtb.bin
|
||||
|
||||
Build Instruction for Slim Bootloader for QEMU target
|
||||
-----------------------------------------------------
|
||||
|
||||
Slim Bootloader supports multiple payloads, and a board of Slim Bootloader
|
||||
detects its target payload by PayloadId in board configuration.
|
||||
The PayloadId can be any 4 Bytes value.
|
||||
|
||||
1. Update PayloadId. Let's use 'U-BT' as an example::
|
||||
|
||||
$ vi Platform/QemuBoardPkg/CfgData/CfgDataExt_Brd1.dlt
|
||||
-GEN_CFG_DATA.PayloadId | 'AUTO'
|
||||
+GEN_CFG_DATA.PayloadId | 'U-BT'
|
||||
|
||||
2. Update payload text base. PAYLOAD_EXE_BASE must be the same as U-Boot
|
||||
CONFIG_SYS_TEXT_BASE in board/intel/slimbootloader/Kconfig.
|
||||
PAYLOAD_LOAD_HIGH must be 0::
|
||||
|
||||
$ vi Platform/QemuBoardPkg/BoardConfig.py
|
||||
+ self.PAYLOAD_LOAD_HIGH = 0
|
||||
+ self.PAYLOAD_EXE_BASE = 0x00100000
|
||||
|
||||
3. Build QEMU target. Make sure u-boot-dtb.bin and U-BT PayloadId
|
||||
in build command. The output is Outputs/qemu/SlimBootloader.bin::
|
||||
|
||||
$ python BuildLoader.py build qemu -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma"
|
||||
|
||||
4. Launch Slim Bootloader on QEMU.
|
||||
You should reach at U-Boot serial console::
|
||||
|
||||
$ qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Outputs/qemu/SlimBootloader.bin
|
||||
|
||||
Build Instruction for Slim Bootloader for LeafHill (APL) target
|
||||
--------------------------------------------------------------
|
||||
|
||||
LeafHill is using PCI UART2 device as a serial port.
|
||||
For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
|
||||
|
||||
1. Enable CONFIG_SYS_NS16550_MEM32 in U-Boot::
|
||||
|
||||
$ vi include/configs/slimbootloader.h
|
||||
+#define CONFIG_SYS_NS16550_MEM32
|
||||
#ifdef CONFIG_SYS_NS16550_MEM3
|
||||
|
||||
2. Build U-Boot::
|
||||
|
||||
$ make disclean
|
||||
$ make slimbootloader_defconfig
|
||||
$ make all
|
||||
|
||||
3. Copy u-boot-dtb.bin to Slim Bootloader.
|
||||
Slim Bootloader looks for a payload from the specific location.
|
||||
Copy the build u-boot-dtb.bin to the expected location::
|
||||
|
||||
$ mkdir -p <Slim Bootloader Dir>/PayloadPkg/PayloadBins/
|
||||
$ cp <U-Boot Dir>/u-boot-dtb.bin <Slim Bootloader Dir>/PayloadPkg/PayloadBins/u-boot-dtb.bin
|
||||
|
||||
4. Update PayloadId. Let's use 'U-BT' as an example::
|
||||
|
||||
$ vi Platform/ApollolakeBoardPkg/CfgData/CfgData_Int_LeafHill.dlt
|
||||
-GEN_CFG_DATA.PayloadId | 'AUTO
|
||||
+GEN_CFG_DATA.PayloadId | 'U-BT'
|
||||
|
||||
5. Update payload text base.
|
||||
|
||||
* PAYLOAD_EXE_BASE must be the same as U-Boot CONFIG_SYS_TEXT_BASE
|
||||
in board/intel/slimbootloader/Kconfig.
|
||||
* PAYLOAD_LOAD_HIGH must be 0::
|
||||
|
||||
$ vi Platform/ApollolakeBoardPkg/BoardConfig.py
|
||||
+ self.PAYLOAD_LOAD_HIGH = 0
|
||||
+ self.PAYLOAD_EXE_BASE = 0x00100000
|
||||
|
||||
6. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
|
||||
in build command. The output is Outputs/apl/Stitch_Components.zip::
|
||||
|
||||
$ python BuildLoader.py build apl -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma"
|
||||
|
||||
7. Stitch IFWI.
|
||||
|
||||
Refer to Apollolake_ page in Slim Bootloader document site::
|
||||
|
||||
$ python Platform/ApollolakeBoardPkg/Script/StitchLoader.py -i <Existing IFWI> -s Outputs/apl/Stitch_Components.zip -o <Output IFWI>
|
||||
|
||||
8. Flash IFWI.
|
||||
|
||||
Use DediProg to flash IFWI. You should reach at U-Boot serial console.
|
||||
|
||||
|
||||
Build Instruction to use ELF U-Boot
|
||||
-----------------------------------
|
||||
|
||||
1. Enable CONFIG_OF_EMBED::
|
||||
|
||||
$ vi configs/slimbootloader_defconfig
|
||||
+CONFIG_OF_EMBED=y
|
||||
|
||||
2. Build U-Boot::
|
||||
|
||||
$ make disclean
|
||||
$ make slimbootloader_defconfig
|
||||
$ make all
|
||||
$ strip u-boot (removing symbol for reduced size)
|
||||
|
||||
3. Do same steps as above
|
||||
|
||||
* Copy u-boot (ELF) to PayloadBins directory
|
||||
* Update PayloadId 'U-BT' as above.
|
||||
* No need to set PAYLOAD_LOAD_HIGH and PAYLOAD_EXE_BASE.
|
||||
* Build Slim Bootloader. Use u-boot instead of u-boot-dtb.bin::
|
||||
|
||||
$ python BuildLoader.py build <qemu or apl> -p "OsLoader.efi:LLDR:Lz4;u-boot:U-BT:Lzma"
|
||||
|
||||
.. _U-Boot: https://gitlab.denx.de/
|
||||
.. _`Slim Bootloader`: https://github.com/slimbootloader/
|
||||
.. _`Intel FSP`: https://github.com/IntelFsp/
|
||||
.. _`Getting Started`: https://slimbootloader.github.io/getting-started/
|
||||
.. _Apollolake: https://slimbootloader.github.io/supported-hardware/apollo-lake-crb.html#stitching
|
@ -136,7 +136,6 @@ static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs,
|
||||
bool linear_ok;
|
||||
int attr;
|
||||
|
||||
break;
|
||||
debug("Mode %x: ", mode);
|
||||
memset(buffer, '\0', sizeof(struct vbe_mode_info));
|
||||
regs->e.eax = VESA_GET_MODE_INFO;
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include <pci_ids.h>
|
||||
#include <spi.h>
|
||||
#include <asm/io.h>
|
||||
#include <spi-mem.h>
|
||||
#include <div64.h>
|
||||
|
||||
#include "ich.h"
|
||||
|
||||
@ -171,18 +173,6 @@ static int ich_init_controller(struct udevice *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void spi_use_out(struct spi_trans *trans, unsigned bytes)
|
||||
{
|
||||
trans->out += bytes;
|
||||
trans->bytesout -= bytes;
|
||||
}
|
||||
|
||||
static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
|
||||
{
|
||||
trans->in += bytes;
|
||||
trans->bytesin -= bytes;
|
||||
}
|
||||
|
||||
static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
|
||||
{
|
||||
if (plat->ich_version == ICHV_7) {
|
||||
@ -213,47 +203,12 @@ static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
|
||||
return lock != 0;
|
||||
}
|
||||
|
||||
static void spi_setup_type(struct spi_trans *trans, int data_bytes)
|
||||
{
|
||||
trans->type = 0xFF;
|
||||
|
||||
/* Try to guess spi type from read/write sizes */
|
||||
if (trans->bytesin == 0) {
|
||||
if (trans->bytesout + data_bytes > 4)
|
||||
/*
|
||||
* If bytesin = 0 and bytesout > 4, we presume this is
|
||||
* a write data operation, which is accompanied by an
|
||||
* address.
|
||||
*/
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
||||
else
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trans->bytesout == 1) { /* and bytesin is > 0 */
|
||||
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trans->bytesout == 4) /* and bytesin is > 0 */
|
||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||
|
||||
/* Fast read command is called with 5 bytes instead of 4 */
|
||||
if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
|
||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||
--trans->bytesout;
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
||||
bool lock)
|
||||
{
|
||||
uint16_t optypes;
|
||||
uint8_t opmenu[ctlr->menubytes];
|
||||
|
||||
trans->opcode = trans->out[0];
|
||||
spi_use_out(trans, 1);
|
||||
if (!lock) {
|
||||
/* The lock is off, so just use index 0. */
|
||||
ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
|
||||
@ -285,12 +240,7 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
||||
|
||||
optypes = ich_readw(ctlr, ctlr->optype);
|
||||
optype = (optypes >> (opcode_index * 2)) & 0x3;
|
||||
if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
|
||||
optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
|
||||
trans->bytesout >= 3) {
|
||||
/* We guessed wrong earlier. Fix it up. */
|
||||
trans->type = optype;
|
||||
}
|
||||
|
||||
if (optype != trans->type) {
|
||||
printf("ICH SPI: Transaction doesn't fit type %d\n",
|
||||
optype);
|
||||
@ -300,26 +250,6 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_setup_offset(struct spi_trans *trans)
|
||||
{
|
||||
/* Separate the SPI address and data */
|
||||
switch (trans->type) {
|
||||
case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
|
||||
case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
|
||||
return 0;
|
||||
case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
|
||||
case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
|
||||
trans->offset = ((uint32_t)trans->out[0] << 16) |
|
||||
((uint32_t)trans->out[1] << 8) |
|
||||
((uint32_t)trans->out[2] << 0);
|
||||
spi_use_out(trans, 3);
|
||||
return 1;
|
||||
default:
|
||||
printf("Unrecognized SPI transaction type %#x\n", trans->type);
|
||||
return -EPROTO;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
|
||||
* below is true) or 0. In case the wait was for the bit(s) to set - write
|
||||
@ -350,7 +280,7 @@ static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
void ich_spi_config_opcode(struct udevice *dev)
|
||||
static void ich_spi_config_opcode(struct udevice *dev)
|
||||
{
|
||||
struct ich_spi_priv *ctlr = dev_get_priv(dev);
|
||||
|
||||
@ -365,90 +295,38 @@ void ich_spi_config_opcode(struct udevice *dev)
|
||||
ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
|
||||
}
|
||||
|
||||
static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
const void *dout, void *din, unsigned long flags)
|
||||
static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
|
||||
{
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct udevice *bus = dev_get_parent(slave->dev);
|
||||
struct ich_spi_platdata *plat = dev_get_platdata(bus);
|
||||
struct ich_spi_priv *ctlr = dev_get_priv(bus);
|
||||
uint16_t control;
|
||||
int16_t opcode_index;
|
||||
int with_address;
|
||||
int status;
|
||||
int bytes = bitlen / 8;
|
||||
struct spi_trans *trans = &ctlr->trans;
|
||||
unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
|
||||
int using_cmd = 0;
|
||||
bool lock = spi_lock_status(plat, ctlr->base);
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
/* We don't support writing partial bytes */
|
||||
if (bitlen % 8) {
|
||||
debug("ICH SPI: Accessing partial bytes not supported\n");
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
trans->in = NULL;
|
||||
trans->out = NULL;
|
||||
trans->type = 0xFF;
|
||||
|
||||
/* An empty end transaction can be ignored */
|
||||
if (type == SPI_XFER_END && !dout && !din)
|
||||
return 0;
|
||||
|
||||
if (type & SPI_XFER_BEGIN)
|
||||
memset(trans, '\0', sizeof(*trans));
|
||||
|
||||
/* Dp we need to come back later to finish it? */
|
||||
if (dout && type == SPI_XFER_BEGIN) {
|
||||
if (bytes > ICH_MAX_CMD_LEN) {
|
||||
debug("ICH SPI: Command length limit exceeded\n");
|
||||
return -ENOSPC;
|
||||
if (op->data.nbytes) {
|
||||
if (op->data.dir == SPI_MEM_DATA_IN) {
|
||||
trans->in = op->data.buf.in;
|
||||
trans->bytesin = op->data.nbytes;
|
||||
} else {
|
||||
trans->out = op->data.buf.out;
|
||||
trans->bytesout = op->data.nbytes;
|
||||
}
|
||||
memcpy(trans->cmd, dout, bytes);
|
||||
trans->cmd_len = bytes;
|
||||
debug_trace("ICH SPI: Saved %d bytes\n", bytes);
|
||||
}
|
||||
|
||||
if (trans->opcode != op->cmd.opcode)
|
||||
trans->opcode = op->cmd.opcode;
|
||||
|
||||
if (lock && trans->opcode == SPI_OPCODE_WRDIS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We process a 'middle' spi_xfer() call, which has no
|
||||
* SPI_XFER_BEGIN/END, as an independent transaction as if it had
|
||||
* an end. We therefore repeat the command. This is because ICH
|
||||
* seems to have no support for this, or because interest (in digging
|
||||
* out the details and creating a special case in the code) is low.
|
||||
*/
|
||||
if (trans->cmd_len) {
|
||||
trans->out = trans->cmd;
|
||||
trans->bytesout = trans->cmd_len;
|
||||
using_cmd = 1;
|
||||
debug_trace("ICH SPI: Using %d bytes\n", trans->cmd_len);
|
||||
} else {
|
||||
trans->out = dout;
|
||||
trans->bytesout = dout ? bytes : 0;
|
||||
}
|
||||
|
||||
trans->in = din;
|
||||
trans->bytesin = din ? bytes : 0;
|
||||
|
||||
/* There has to always at least be an opcode */
|
||||
if (!trans->bytesout) {
|
||||
debug("ICH SPI: No opcode for transfer\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (plat->ich_version == ICHV_7)
|
||||
ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
||||
else
|
||||
ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
||||
|
||||
spi_setup_type(trans, using_cmd ? bytes : 0);
|
||||
opcode_index = spi_setup_opcode(ctlr, trans, lock);
|
||||
if (opcode_index < 0)
|
||||
return -EINVAL;
|
||||
with_address = spi_setup_offset(trans);
|
||||
if (with_address < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (trans->opcode == SPI_OPCODE_WREN) {
|
||||
/*
|
||||
@ -461,6 +339,40 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (plat->ich_version == ICHV_7)
|
||||
ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
||||
else
|
||||
ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
||||
|
||||
/* Try to guess spi transaction type */
|
||||
if (op->data.dir == SPI_MEM_DATA_OUT) {
|
||||
if (op->addr.nbytes)
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
||||
else
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
|
||||
} else {
|
||||
if (op->addr.nbytes)
|
||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||
else
|
||||
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
|
||||
}
|
||||
/* Special erase case handling */
|
||||
if (op->addr.nbytes && !op->data.buswidth)
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
||||
|
||||
opcode_index = spi_setup_opcode(ctlr, trans, lock);
|
||||
if (opcode_index < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (op->addr.nbytes) {
|
||||
trans->offset = op->addr.val;
|
||||
with_address = 1;
|
||||
}
|
||||
|
||||
if (ctlr->speed && ctlr->max_speed >= 33000000) {
|
||||
int byte;
|
||||
|
||||
@ -472,13 +384,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
ich_writeb(ctlr, byte, ctlr->speed);
|
||||
}
|
||||
|
||||
/* See if we have used up the command data */
|
||||
if (using_cmd && dout && bytes) {
|
||||
trans->out = dout;
|
||||
trans->bytesout = bytes;
|
||||
debug_trace("ICH SPI: Moving to data, %d bytes\n", bytes);
|
||||
}
|
||||
|
||||
/* Preset control fields */
|
||||
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
|
||||
|
||||
@ -513,22 +418,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this is a write command atempting to transfer more bytes
|
||||
* than the controller can handle. Iterations for writes are not
|
||||
* supported here because each SPI write command needs to be preceded
|
||||
* and followed by other SPI commands, and this sequence is controlled
|
||||
* by the SPI chip driver.
|
||||
*/
|
||||
if (trans->bytesout > ctlr->databytes) {
|
||||
debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read or write up to databytes bytes at a time until everything has
|
||||
* been sent.
|
||||
*/
|
||||
while (trans->bytesout || trans->bytesin) {
|
||||
uint32_t data_length;
|
||||
|
||||
@ -543,9 +432,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
/* Program data into FDATA0 to N */
|
||||
if (trans->bytesout) {
|
||||
write_reg(ctlr, trans->out, ctlr->data, data_length);
|
||||
spi_use_out(trans, data_length);
|
||||
if (with_address)
|
||||
trans->offset += data_length;
|
||||
trans->bytesout -= data_length;
|
||||
}
|
||||
|
||||
/* Add proper control fields' values */
|
||||
@ -568,9 +455,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
|
||||
if (trans->bytesin) {
|
||||
read_reg(ctlr, ctlr->data, trans->in, data_length);
|
||||
spi_use_in(trans, data_length);
|
||||
if (with_address)
|
||||
trans->offset += data_length;
|
||||
trans->bytesin -= data_length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,6 +466,40 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op)
|
||||
{
|
||||
unsigned int page_offset;
|
||||
int addr = op->addr.val;
|
||||
unsigned int byte_count = op->data.nbytes;
|
||||
|
||||
if (hweight32(ICH_BOUNDARY) == 1) {
|
||||
page_offset = addr & (ICH_BOUNDARY - 1);
|
||||
} else {
|
||||
u64 aux = addr;
|
||||
|
||||
page_offset = do_div(aux, ICH_BOUNDARY);
|
||||
}
|
||||
|
||||
if (op->data.dir == SPI_MEM_DATA_IN && slave->max_read_size) {
|
||||
op->data.nbytes = min(ICH_BOUNDARY - page_offset,
|
||||
slave->max_read_size);
|
||||
} else if (slave->max_write_size) {
|
||||
op->data.nbytes = min(ICH_BOUNDARY - page_offset,
|
||||
slave->max_write_size);
|
||||
}
|
||||
|
||||
op->data.nbytes = min(op->data.nbytes, byte_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
const void *dout, void *din, unsigned long flags)
|
||||
{
|
||||
printf("ICH SPI: Only supports memory operations\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ich_spi_probe(struct udevice *dev)
|
||||
{
|
||||
struct ich_spi_platdata *plat = dev_get_platdata(dev);
|
||||
@ -686,10 +605,17 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct spi_controller_mem_ops ich_controller_mem_ops = {
|
||||
.adjust_op_size = ich_spi_adjust_size,
|
||||
.supports_op = NULL,
|
||||
.exec_op = ich_spi_exec_op,
|
||||
};
|
||||
|
||||
static const struct dm_spi_ops ich_spi_ops = {
|
||||
.xfer = ich_spi_xfer,
|
||||
.set_speed = ich_spi_set_speed,
|
||||
.set_mode = ich_spi_set_mode,
|
||||
.mem_ops = &ich_controller_mem_ops,
|
||||
/*
|
||||
* cs_info is not needed, since we require all chip selects to be
|
||||
* in the device tree explicitly
|
||||
|
@ -100,13 +100,8 @@ enum {
|
||||
HSFC_FSMIE = 0x8000
|
||||
};
|
||||
|
||||
enum {
|
||||
ICH_MAX_CMD_LEN = 5,
|
||||
};
|
||||
|
||||
struct spi_trans {
|
||||
uint8_t cmd[ICH_MAX_CMD_LEN];
|
||||
int cmd_len;
|
||||
uint8_t cmd;
|
||||
const uint8_t *out;
|
||||
uint32_t bytesout;
|
||||
uint8_t *in;
|
||||
@ -166,6 +161,8 @@ struct spi_trans {
|
||||
#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
|
||||
(SPI_OPMENU_1 << 8) | (SPI_OPMENU_0 << 0))
|
||||
|
||||
#define ICH_BOUNDARY 0x1000
|
||||
|
||||
enum ich_version {
|
||||
ICHV_7,
|
||||
ICHV_9,
|
||||
|
@ -10,8 +10,23 @@
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#define BOOT_TARGET_DEVICES(func) \
|
||||
func(USB, usb, 0) \
|
||||
func(SCSI, scsi, 0) \
|
||||
func(VIRTIO, virtio, 0) \
|
||||
func(IDE, ide, 0) \
|
||||
func(DHCP, dhcp, na)
|
||||
|
||||
#include <config_distro_bootcmd.h>
|
||||
#include <configs/x86-common.h>
|
||||
|
||||
#undef CONFIG_ENV_SIZE
|
||||
#define CONFIG_ENV_SIZE SZ_256K
|
||||
|
||||
#define CONFIG_PREBOOT "pci enum"
|
||||
|
||||
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
|
||||
|
||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,i8042-kbd\0" \
|
||||
|
62
include/configs/slimbootloader.h
Normal file
62
include/configs/slimbootloader.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __SLIMBOOTLOADER_CONFIG_H__
|
||||
#define __SLIMBOOTLOADER_CONFIG_H__
|
||||
|
||||
#include <configs/x86-common.h>
|
||||
|
||||
/*
|
||||
* By default, CONFIG_SYS_NS16550_PORT_MAPPED is enabled for port io serial.
|
||||
* To use mmio base serial, enable CONFIG_SYS_NS16550_MEM32 and disable
|
||||
* CONFIG_SYS_NS16550_PORT_MAPPED until ns16550 driver supports serial port
|
||||
* configuration in run-time.
|
||||
*
|
||||
* #define CONFIG_SYS_NS16550_MEM32
|
||||
* #undef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||
*/
|
||||
#ifdef CONFIG_SYS_NS16550_MEM32
|
||||
#undef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||
#endif
|
||||
|
||||
#define CONFIG_STD_DEVICES_SETTINGS \
|
||||
"stdin=serial,i8042-kbd,usbkbd\0" \
|
||||
"stdout=serial\0" \
|
||||
"stderr=serial\0"
|
||||
|
||||
/*
|
||||
* Override CONFIG_EXTRA_ENV_SETTINGS in x86-common.h
|
||||
*/
|
||||
#undef CONFIG_EXTRA_ENV_SETTINGS
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
CONFIG_STD_DEVICES_SETTINGS \
|
||||
"netdev=eth0\0" \
|
||||
"consoledev=ttyS0\0" \
|
||||
"ramdiskaddr=0x4000000\0" \
|
||||
"ramdiskfile=initrd\0" \
|
||||
"bootdev=usb\0" \
|
||||
"bootdevnum=0\0" \
|
||||
"bootdevpart=0\0" \
|
||||
"bootfsload=fatload\0" \
|
||||
"bootusb=setenv bootdev usb; boot\0" \
|
||||
"bootscsi=setenv bootdev scsi; boot\0" \
|
||||
"bootmmc=setenv bootdev mmc; boot\0" \
|
||||
"bootargs=console=ttyS0,115200 console=tty0\0"
|
||||
|
||||
/*
|
||||
* Override CONFIG_BOOTCOMMAND in x86-common.h
|
||||
*/
|
||||
#undef CONFIG_BOOTCOMMAND
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"if test ${bootdev} = \"usb\"; then ${bootdev} start; fi; " \
|
||||
"if test ${bootdev} = \"scsi\"; then ${bootdev} scan; fi; " \
|
||||
"${bootdev} info; " \
|
||||
"${bootfsload} ${bootdev} ${bootdevnum}:${bootdevpart} " \
|
||||
"${loadaddr} ${bootfile}; " \
|
||||
"${bootfsload} ${bootdev} ${bootdevnum}:${bootdevpart} " \
|
||||
"${ramdiskaddr} ${ramdiskfile}; " \
|
||||
"zboot ${loadaddr} 0 ${ramdiskaddr} ${filesize}"
|
||||
|
||||
#endif /* __SLIMBOOTLOADER_CONFIG_H__ */
|
@ -105,30 +105,37 @@
|
||||
#define CONFIG_OTHBOOTARGS "othbootargs=acpi=off\0"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISTRO_DEFAULTS
|
||||
#define BOOTENV
|
||||
#endif
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
CONFIG_STD_DEVICES_SETTINGS \
|
||||
"pciconfighost=1\0" \
|
||||
"netdev=eth0\0" \
|
||||
"consoledev=ttyS0\0" \
|
||||
CONFIG_OTHBOOTARGS \
|
||||
"ramdiskaddr=0x4000000\0" \
|
||||
"ramdiskfile=initramfs.gz\0"
|
||||
"scriptaddr=0x7000000\0" \
|
||||
"kernel_addr_r=0x1000000\0" \
|
||||
"ramdisk_addr_r=0x4000000\0" \
|
||||
"ramdiskfile=initramfs.gz\0" \
|
||||
BOOTENV
|
||||
|
||||
#define CONFIG_RAMBOOTCOMMAND \
|
||||
"setenv bootargs root=/dev/ram rw " \
|
||||
"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
|
||||
"console=$consoledev,$baudrate $othbootargs;" \
|
||||
"tftpboot $loadaddr $bootfile;" \
|
||||
"tftpboot $ramdiskaddr $ramdiskfile;" \
|
||||
"zboot $loadaddr 0 $ramdiskaddr $filesize"
|
||||
"tftpboot $kernel_addr_r $bootfile;" \
|
||||
"tftpboot $ramdisk_addr_r $ramdiskfile;" \
|
||||
"zboot $kernel_addr_r 0 $ramdisk_addr_r $filesize"
|
||||
|
||||
#define CONFIG_NFSBOOTCOMMAND \
|
||||
"setenv bootargs root=/dev/nfs rw " \
|
||||
"nfsroot=$serverip:$rootpath " \
|
||||
"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
|
||||
"console=$consoledev,$baudrate $othbootargs;" \
|
||||
"tftpboot $loadaddr $bootfile;" \
|
||||
"zboot $loadaddr"
|
||||
"tftpboot $kernel_addr_r $bootfile;" \
|
||||
"zboot $kernel_addr_r"
|
||||
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
|
@ -395,11 +395,22 @@ $(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/efi_free
|
||||
|
||||
# ACPI
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# This first sends the file (typically dsdt.asl) through the preprocessor
|
||||
# resolve includes and any CONFIG options used. This produces dsdt.asl.tmp
|
||||
# which is pure ASL code. The Intel ASL (ACPI (Advanced Configuration and Power
|
||||
# Interface) Source Language compiler (iasl) then converts this ASL code into a
|
||||
# C file containing the hex data to build into U-Boot. This file is called
|
||||
# dsdt.hex (despite us setting the prefix to .../dsdt.asl.tmp) so must be
|
||||
# renamed to dsdt.c for consumption by the build system.
|
||||
ASL_TMP = $(patsubst %.c,%.asl.tmp,$@)
|
||||
|
||||
quiet_cmd_acpi_c_asl= ASL $<
|
||||
cmd_acpi_c_asl= \
|
||||
$(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -P $(UBOOTINCLUDE) -o $<.tmp $<; \
|
||||
iasl -p $< -tc $<.tmp $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \
|
||||
mv $(patsubst %.asl,%.hex,$<) $@
|
||||
$(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -P $(UBOOTINCLUDE) \
|
||||
-o $(ASL_TMP) $< && \
|
||||
iasl -p $@ -tc $(ASL_TMP) $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \
|
||||
mv $(patsubst %.c,%.hex,$@) $@
|
||||
|
||||
$(obj)/dsdt.c: $(src)/dsdt.asl
|
||||
$(call cmd,acpi_c_asl)
|
||||
|
Loading…
Reference in New Issue
Block a user