- Rename existing FSP code to fsp1
- Add fsp2 directory in preparation to support FSP 2.0
- Various x86 platform codes update
- Various bug fixes and updates in dm core, sandbox and spl
This commit is contained in:
Tom Rini 2019-10-08 18:45:26 -04:00
commit efea5a34bb
153 changed files with 2032 additions and 1014 deletions

View File

@ -337,14 +337,18 @@ endif
# KBUILD_MODULES := 1
#endif
# Check ths size of a binary:
# Args:
# $1: File to check
# #2: Size limit in bytes (decimal or 0xhex)
define size_check
actual=$$( wc -c $1 | awk '{print $$1}'); \
limit=$$( printf "%d" $2 ); \
if test $$actual -gt $$limit; then \
echo "$1 exceeds file size limit:" >&2; \
echo " limit: $$limit bytes" >&2; \
echo " actual: $$actual bytes" >&2; \
echo " excess: $$((actual - limit)) bytes" >&2; \
echo " limit: $$(printf %#x bytes $$limit) bytes" >&2; \
echo " actual: $$(printf %#x $$actual) bytes" >&2; \
echo " excess: $$(printf %#x $$((actual - limit))) bytes" >&2;\
exit 1; \
fi
endef
@ -1213,7 +1217,9 @@ u-boot.ldr: u-boot
# Use 'make BINMAN_DEBUG=1' to enable debugging
quiet_cmd_binman = BINMAN $@
cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
build -u -d u-boot.dtb -O . -m \
--toolpath $(objtree)/tools \
$(if $(BINMAN_VERBOSE),-v$(BINMAN_VERBOSE)) \
build -u -d u-boot.dtb -O . -m \
-I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \
$(BINMAN_$(@F))

View File

@ -954,7 +954,7 @@ config ARCH_SUNXI
select USB if DISTRO_DEFAULTS
select USB_KEYBOARD if DISTRO_DEFAULTS
select USB_STORAGE if DISTRO_DEFAULTS
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
imply CMD_GPT
imply CMD_UBI if NAND

View File

@ -7,7 +7,7 @@ extra-y = start.o
obj-y = cpu.o cache.o
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_SPL_NO_CPU_SUPPORT_CODE
ifdef CONFIG_SPL_NO_CPU_SUPPORT
extra-y :=
endif
endif

View File

@ -11,7 +11,7 @@ config OMAP34XX
select ARM_ERRATA_454179
select ARM_ERRATA_621766
select ARM_ERRATA_725233
select USE_TINY_PRINTF if SPL
select SPL_USE_TINY_PRINTF if SPL
imply NAND_OMAP_GPMC
imply SPL_FS_EXT4
imply SPL_FS_FAT
@ -31,7 +31,7 @@ config OMAP34XX
config OMAP44XX
bool "OMAP44XX SoC"
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply NAND_OMAP_ELM
imply NAND_OMAP_GPMC
imply SPL_DISPLAY_PRINT
@ -124,7 +124,7 @@ config AM33XX
imply SPL_NAND_SUPPORT
imply SYS_I2C_OMAP24XX
imply SYS_THUMB_BUILD
imply USE_TINY_PRINTF
imply SPL_USE_TINY_PRINTF
help
Support for AM335x SOC from Texas Instruments.
The AM335x high performance SOC features a Cortex-A8

View File

@ -32,7 +32,7 @@ config RCAR_GEN3
imply SPL_SYS_MALLOC_SIMPLE
imply SPL_TINY_MEMSET
imply SPL_YMODEM_SUPPORT
imply USE_TINY_PRINTF
imply SPL_USE_TINY_PRINTF
config RZA1
prompt "Renesas ARM SoCs RZ/A1 (32bit)"

View File

@ -65,7 +65,7 @@ config TARGET_GOSE
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
config TARGET_KOELSCH
@ -74,7 +74,7 @@ config TARGET_KOELSCH
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
config TARGET_LAGER
@ -83,7 +83,7 @@ config TARGET_LAGER
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
config TARGET_KZM9G
@ -95,7 +95,7 @@ config TARGET_ALT
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
config TARGET_SILK
@ -104,7 +104,7 @@ config TARGET_SILK
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
config TARGET_PORTER
@ -113,7 +113,7 @@ config TARGET_PORTER
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
config TARGET_STOUT
@ -122,7 +122,7 @@ config TARGET_STOUT
select DM_SERIAL
select SPL_TINY_MEMSET
select SUPPORT_SPL
select USE_TINY_PRINTF
select SPL_USE_TINY_PRINTF
imply CMD_DM
endchoice

View File

@ -4,7 +4,7 @@ config NR_DRAM_BANKS
default 1
config SPL_SIZE_LIMIT
default 65536 if TARGET_SOCFPGA_GEN5
default 0x10000 if TARGET_SOCFPGA_GEN5
config SPL_SIZE_LIMIT_PROVIDE_STACK
default 0x200 if TARGET_SOCFPGA_GEN5
@ -45,7 +45,7 @@ config TARGET_SOCFPGA_ARRIA10
select SPL_SYSCON if SPL
select ETH_DESIGNWARE_SOCFPGA
imply FPGA_SOCFPGA
imply USE_TINY_PRINTF
imply SPL_USE_TINY_PRINTF
config TARGET_SOCFPGA_CYCLONE5
bool
@ -59,7 +59,7 @@ config TARGET_SOCFPGA_GEN5
imply SPL_SIZE_LIMIT_SUBTRACT_MALLOC
imply SPL_STACK_R
imply SPL_SYS_MALLOC_SIMPLE
imply USE_TINY_PRINTF
imply SPL_USE_TINY_PRINTF
config TARGET_SOCFPGA_STRATIX10
bool

View File

@ -13,14 +13,14 @@
int uniphier_pin_init(const char *pinconfig_name)
{
struct udevice *pctldev, *config, *next;
struct udevice *pctldev, *config;
int ret;
ret = uclass_first_device(UCLASS_PINCTRL, &pctldev);
if (ret)
return ret;
device_foreach_child_safe(config, next, pctldev) {
device_foreach_child(config, pctldev) {
if (strcmp(config->name, pinconfig_name))
continue;

View File

@ -225,6 +225,58 @@ phys_addr_t map_to_sysmem(const void *ptr)
return mentry->tag;
}
unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size)
{
struct sandbox_state *state = state_get_current();
if (!state->allow_memio)
return 0;
switch (size) {
case SB_SIZE_8:
return *(u8 *)addr;
case SB_SIZE_16:
return *(u16 *)addr;
case SB_SIZE_32:
return *(u32 *)addr;
case SB_SIZE_64:
return *(u64 *)addr;
}
return 0;
}
void sandbox_write(const void *addr, unsigned int val,
enum sandboxio_size_t size)
{
struct sandbox_state *state = state_get_current();
if (!state->allow_memio)
return;
switch (size) {
case SB_SIZE_8:
*(u8 *)addr = val;
break;
case SB_SIZE_16:
*(u16 *)addr = val;
break;
case SB_SIZE_32:
*(u32 *)addr = val;
break;
case SB_SIZE_64:
*(u64 *)addr = val;
break;
}
}
void sandbox_set_enable_memio(bool enable)
{
struct sandbox_state *state = state_get_current();
state->allow_memio = enable;
}
void sandbox_set_enable_pci_map(int enable)
{
enable_pci_map = enable;

View File

@ -78,3 +78,10 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
}
hang();
}
int handoff_arch_save(struct spl_handoff *ho)
{
ho->arch.magic = TEST_HANDOFF_MAGIC;
return 0;
}

View File

@ -147,6 +147,31 @@ static int sandbox_cmdline_cb_default_fdt(struct sandbox_state *state,
SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
"Use the default u-boot.dtb control FDT in U-Boot directory");
static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
const char *arg)
{
const char *fmt = "/arch/sandbox/dts/test.dtb";
char *p;
char *fname;
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
fname = os_malloc(len);
if (!fname)
return -ENOMEM;
strcpy(fname, state->argv[0]);
p = strrchr(fname, '/');
if (!p)
p = fname + strlen(fname);
len -= p - fname;
snprintf(p, len, fmt, p);
state->fdt_fname = fname;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(test_fdt, 'T', 0,
"Use the test.dtb control FDT in U-Boot directory");
static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
const char *arg)
{

View File

@ -103,9 +103,14 @@
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
emul@1f,0 {
compatible = "sandbox,swap-case";
};
sandbox,emul = <&swap_case_emul>;
};
};
emul {
compatible = "sandbox,pci-emul-parent";
swap_case_emul: emul@1f,0 {
compatible = "sandbox,swap-case";
};
};

View File

@ -447,29 +447,39 @@
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000000
0x01000000 0 0x20000000 0x20000000 0 0x2000>;
pci@0,0 {
compatible = "pci-generic";
reg = <0x0000 0 0 0 0>;
emul@0,0 {
compatible = "sandbox,swap-case";
};
sandbox,emul = <&swap_case_emul0_0>;
};
pci@1,0 {
compatible = "pci-generic";
reg = <0x0800 0 0 0 0>;
emul@0,0 {
compatible = "sandbox,swap-case";
use-ea;
};
/* reg 0 is at 0x14, using FDT_PCI_SPACE_MEM32 */
reg = <0x02000814 0 0 0 0
0x01000810 0 0 0 0>;
sandbox,emul = <&swap_case_emul0_1>;
};
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
emul@1f,0 {
compatible = "sandbox,swap-case";
};
/* reg 0 is at 0x10, using FDT_PCI_SPACE_IO */
reg = <0x0100f810 0 0 0 0>;
sandbox,emul = <&swap_case_emul0_1f>;
};
};
pci-emul0 {
compatible = "sandbox,pci-emul-parent";
swap_case_emul0_0: emul0@0,0 {
compatible = "sandbox,swap-case";
};
swap_case_emul0_1: emul0@1,0 {
compatible = "sandbox,swap-case";
use-ea;
};
swap_case_emul0_1f: emul0@1f,0 {
compatible = "sandbox,swap-case";
};
};
@ -499,9 +509,14 @@
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
emul@1f,0 {
compatible = "sandbox,swap-case";
};
sandbox,emul = <&swap_case_emul2_1f>;
};
};
pci-emul2 {
compatible = "sandbox,pci-emul-parent";
swap_case_emul2_1f: emul2@1f,0 {
compatible = "sandbox,swap-case";
};
};
@ -713,11 +728,13 @@
compatible = "sandbox,spmi";
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;
pm8916@0 {
compatible = "qcom,spmi-pmic";
reg = <0x0 0x1>;
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;
spmi_gpios: gpios@c000 {
compatible = "qcom,pm8916-gpio";

View File

@ -6,6 +6,13 @@
#ifndef __SANDBOX_ASM_IO_H
#define __SANDBOX_ASM_IO_H
enum sandboxio_size_t {
SB_SIZE_8,
SB_SIZE_16,
SB_SIZE_32,
SB_SIZE_64,
};
void *phys_to_virt(phys_addr_t paddr);
#define phys_to_virt phys_to_virt
@ -38,18 +45,21 @@ static inline void unmap_sysmem(const void *vaddr)
/* Map from a pointer to our RAM buffer */
phys_addr_t map_to_sysmem(const void *ptr);
/* Define nops for sandbox I/O access */
#define readb(addr) ((void)addr, 0)
#define readw(addr) ((void)addr, 0)
#define readl(addr) ((void)addr, 0)
unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size);
void sandbox_write(const void *addr, unsigned int val,
enum sandboxio_size_t size);
#define readb(addr) sandbox_read((const void *)addr, SB_SIZE_8)
#define readw(addr) sandbox_read((const void *)addr, SB_SIZE_16)
#define readl(addr) sandbox_read((const void *)addr, SB_SIZE_32)
#ifdef CONFIG_SANDBOX64
#define readq(addr) ((void)addr, 0)
#define readq(addr) sandbox_read((const void *)addr, SB_SIZE_64)
#endif
#define writeb(v, addr) ((void)addr)
#define writew(v, addr) ((void)addr)
#define writel(v, addr) ((void)addr)
#define writeb(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_8)
#define writew(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_16)
#define writel(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_32)
#ifdef CONFIG_SANDBOX64
#define writeq(v, addr) ((void)addr)
#define writeq(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_64)
#endif
/*
@ -110,13 +120,21 @@ phys_addr_t map_to_sysmem(const void *ptr);
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
/* I/O access functions */
int inl(unsigned int addr);
int inw(unsigned int addr);
int inb(unsigned int addr);
int _inl(unsigned int addr);
int _inw(unsigned int addr);
int _inb(unsigned int addr);
void outl(unsigned int value, unsigned int addr);
void outw(unsigned int value, unsigned int addr);
void outb(unsigned int value, unsigned int addr);
void _outl(unsigned int value, unsigned int addr);
void _outw(unsigned int value, unsigned int addr);
void _outb(unsigned int value, unsigned int addr);
#define inb(port) _inb((uintptr_t)(port))
#define inw(port) _inw((uintptr_t)(port))
#define inl(port) _inl((uintptr_t)(port))
#define outb(val, port) _outb(val, (uintptr_t)(port))
#define outw(val, port) _outw(val, (uintptr_t)(port))
#define outl(val, port) _outl(val, (uintptr_t)(port))
#define out_arch(type,endian,a,v) write##type(cpu_to_##endian(v),a)
#define in_arch(type,endian,a) endian##_to_cpu(read##type(a))
@ -188,6 +206,28 @@ static inline void memcpy_toio(volatile void *dst, const void *src, int count)
#define insw(port, buf, ns) _insw((u16 *)port, buf, ns)
#define outsw(port, buf, ns) _outsw((u16 *)port, buf, ns)
/* IO space accessors */
#define clrio(type, addr, clear) \
out##type(in##type(addr) & ~(clear), (addr))
#define setio(type, addr, set) \
out##type(in##type(addr) | (set), (addr))
#define clrsetio(type, addr, clear, set) \
out##type((in##type(addr) & ~(clear)) | (set), (addr))
#define clrio_32(addr, clear) clrio(l, addr, clear)
#define clrio_16(addr, clear) clrio(w, addr, clear)
#define clrio_8(addr, clear) clrio(b, addr, clear)
#define setio_32(addr, set) setio(l, addr, set)
#define setio_16(addr, set) setio(w, addr, set)
#define setio_8(addr, set) setio(b, addr, set)
#define clrsetio_32(addr, clear, set) clrsetio(l, addr, clear, set)
#define clrsetio_16(addr, clear, set) clrsetio(w, addr, clear, set)
#define clrsetio_8(addr, clear, set) clrsetio(b, addr, clear, set)
#include <iotrace.h>
#include <asm/types.h>

View File

@ -102,6 +102,7 @@ struct sandbox_state {
ulong next_tag; /* Next address tag to allocate */
struct list_head mapmem_head; /* struct sandbox_mapmem_entry */
bool hwspinlock; /* Hardware Spinlock status */
bool allow_memio; /* Allow readl() etc. to work */
/*
* This struct is getting large.

View File

@ -12,7 +12,7 @@
#define SANDBOX_I2C_TEST_ADDR 0x59
#define SANDBOX_PCI_VENDOR_ID 0x1234
#define SANDBOX_PCI_DEVICE_ID 0x5678
#define SANDBOX_PCI_SWAP_CASE_EMUL_ID 0x5678
#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
@ -198,4 +198,19 @@ int sandbox_get_pch_spi_protect(struct udevice *dev);
*/
int sandbox_get_pci_ep_irq_count(struct udevice *dev);
/**
* sandbox_pci_read_bar() - Read the BAR value for a read_config operation
*
* This is used in PCI emulators to read a base address reset. This has special
* rules because when the register is set to 0xffffffff it can be used to
* discover the type and size of the BAR.
*
* @barval: Current value of the BAR
* @type: Type of BAR (PCI_BASE_ADDRESS_SPACE_IO or
* PCI_BASE_ADDRESS_MEM_TYPE_32)
* @size: Size of BAR in bytes
* @return BAR value to return from emulator
*/
uint sandbox_pci_read_bar(u32 barval, int type, uint size);
#endif

View File

@ -91,7 +91,7 @@ static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
return -ENOSYS;
}
int inl(unsigned int addr)
int _inl(unsigned int addr)
{
unsigned long value;
int ret;
@ -101,7 +101,7 @@ int inl(unsigned int addr)
return ret ? 0 : value;
}
int inw(unsigned int addr)
int _inw(unsigned int addr)
{
unsigned long value;
int ret;
@ -111,7 +111,7 @@ int inw(unsigned int addr)
return ret ? 0 : value;
}
int inb(unsigned int addr)
int _inb(unsigned int addr)
{
unsigned long value;
int ret;
@ -121,17 +121,17 @@ int inb(unsigned int addr)
return ret ? 0 : value;
}
void outl(unsigned int value, unsigned int addr)
void _outl(unsigned int value, unsigned int addr)
{
pci_io_write(addr, value, PCI_SIZE_32);
}
void outw(unsigned int value, unsigned int addr)
void _outw(unsigned int value, unsigned int addr)
{
pci_io_write(addr, value, PCI_SIZE_16);
}
void outb(unsigned int value, unsigned int addr)
void _outb(unsigned int value, unsigned int addr)
{
pci_io_write(addr, value, PCI_SIZE_8);
}

View File

@ -364,6 +364,37 @@ config HAVE_FSP
Note: Without this binary U-Boot will not be able to set up its
SDRAM so will not boot.
config USE_CAR
bool "Use Cache-As-RAM (CAR) to get temporary RAM at start-up"
default y if !HAVE_FSP
help
Select this option if your board uses CAR init code, typically in a
car.S file, to get some initial memory for code execution. This is
common with Intel CPUs which don't use FSP.
choice
prompt "FSP version"
depends on HAVE_FSP
default FSP_VERSION1
help
Selects the FSP version to use. Intel has published several versions
of the FSP External Architecture Specification and this allows
selection of the version number used by a particular SoC.
config FSP_VERSION1
bool "FSP version 1.x"
help
This covers versions 1.0 and 1.1a. See here for details:
https://github.com/IntelFsp/fsp/wiki
config FSP_VERSION2
bool "FSP version 2.x"
help
This covers versions 2.0 and 2.1. See here for details:
https://github.com/IntelFsp/fsp/wiki
endchoice
config FSP_FILE
string "Firmware Support Package binary filename"
depends on HAVE_FSP
@ -429,7 +460,7 @@ config ENABLE_MRC_CACHE
For platforms that use Intel FSP for the memory initialization,
please check FSP output HOB via U-Boot command 'fsp hob' to see
if there is FSP_NON_VOLATILE_STORAGE_HOB_GUID (asm/fsp/fsp_hob.h).
if there is FSP_NON_VOLATILE_STORAGE_HOB_GUID (asm/fsp1/fsp_hob.h).
If such GUID does not exist, MRC cache is not available on such
platform (eg: Intel Queensbay), which means selecting this option
here does not make any difference.

View File

@ -26,7 +26,10 @@ endif
extra-$(CONFIG_$(SPL_TPL_)X86_16BIT_INIT) += resetvec.o start16.o
obj-y += cpu.o cpu_x86.o
obj-y += cpu.o
ifndef CONFIG_TPL_BUILD
obj-y += cpu_x86.o
endif
ifndef CONFIG_$(SPL_)X86_64
AFLAGS_REMOVE_call32.o := -mregparm=3 \

View File

@ -4,10 +4,10 @@
*/
#include <common.h>
#include <acpi_s3.h>
#include <cpu.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <asm/acpi_s3.h>
#include <asm/acpi_table.h>
#include <asm/io.h>
#include <asm/tables.h>
@ -167,7 +167,7 @@ void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
* and PMC_BASE_ADDRESS are accessed, so we need make sure the base addresses
* of these two blocks are programmed by either U-Boot or FSP.
*
* It has been verified that 1st phase API (see arch/x86/lib/fsp/fsp_car.S)
* It has been verified that 1st phase API (see arch/x86/lib/fsp1/fsp_car.S)
* on Intel BayTrail SoC already initializes these two base addresses so
* we are safe to access these registers here.
*/

View File

@ -68,9 +68,9 @@ static void set_max_freq(void)
msr_t msr;
/* Enable speed step */
msr = msr_read(MSR_IA32_MISC_ENABLES);
msr.lo |= (1 << 16);
msr_write(MSR_IA32_MISC_ENABLES, msr);
msr = msr_read(MSR_IA32_MISC_ENABLE);
msr.lo |= MISC_ENABLE_ENHANCED_SPEEDSTEP;
msr_write(MSR_IA32_MISC_ENABLE, msr);
/*
* Set guaranteed ratio [21:16] from IACORE_RATIOS to bits [15:8] of

View File

@ -7,7 +7,7 @@
#include <common.h>
#include <fdtdec.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
@ -27,7 +27,7 @@ __weak void update_fsp_azalia_configs(struct azalia_config **azalia)
* If the device tree does not specify an integer setting, use the default
* provided in Intel's Baytrail_FSP_Gold4.tgz release FSP/BayleyBayFsp.bsf file.
*/
void update_fsp_configs(struct fsp_config_data *config,
void fsp_update_configs(struct fsp_config_data *config,
struct fspinit_rtbuf *rt_buf)
{
struct upd_region *fsp_upd = &config->fsp_upd;

View File

@ -5,7 +5,7 @@
#include <common.h>
#include <fdtdec.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
@ -40,7 +40,7 @@ __weak void update_fsp_gpio_configs(struct gpio_family **family,
* If the device tree does not specify an integer setting, use the default
* provided in Intel's Braswell release FSP/BraswellFsp.bsf file.
*/
void update_fsp_configs(struct fsp_config_data *config,
void fsp_update_configs(struct fsp_config_data *config,
struct fspinit_rtbuf *rt_buf)
{
struct upd_region *fsp_upd = &config->fsp_upd;

View File

@ -41,12 +41,9 @@ int arch_cpu_init_dm(void)
void set_max_freq(void)
{
msr_t msr, perf_ctl, platform_info;
msr_t msr, perf_ctl;
/* Check for configurable TDP option */
platform_info = msr_read(MSR_PLATFORM_INFO);
if ((platform_info.hi >> 1) & 3) {
if (cpu_config_tdp_levels()) {
/* Set to nominal TDP ratio */
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
perf_ctl.lo = (msr.lo & 0xff) << 8;
@ -57,17 +54,22 @@ void set_max_freq(void)
}
perf_ctl.hi = 0;
msr_write(IA32_PERF_CTL, perf_ctl);
msr_write(MSR_IA32_PERF_CTL, perf_ctl);
debug("CPU: frequency set to %d MHz\n",
((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
((perf_ctl.lo >> 8) & 0xff) * INTEL_BCLK_MHZ);
}
int arch_cpu_init(void)
{
post_code(POST_CPU_INIT);
#ifdef CONFIG_TPL
/* Do a mini-init if TPL has already done the full init */
return x86_cpu_reinit_f();
#else
return x86_cpu_init_f();
#endif
}
int checkcpu(void)
@ -98,11 +100,8 @@ int print_cpuinfo(void)
void board_debug_uart_init(void)
{
struct udevice *bus = NULL;
/* com1 / com2 decode range */
pci_x86_write_config(bus, PCH_DEV_LPC, LPC_IO_DEC, 1 << 4, PCI_SIZE_16);
pci_x86_write_config(PCH_DEV_LPC, LPC_IO_DEC, 1 << 4, PCI_SIZE_16);
pci_x86_write_config(bus, PCH_DEV_LPC, LPC_EN, COMA_LPC_EN,
PCI_SIZE_16);
pci_x86_write_config(PCH_DEV_LPC, LPC_EN, COMA_LPC_EN, PCI_SIZE_16);
}

View File

@ -81,6 +81,13 @@ static const u8 power_limit_time_msr_to_sec[] = {
[0x11] = 128,
};
#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
int arch_cpu_init(void)
{
return 0;
}
#endif
/*
* The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate
* the 100MHz BCLCK against the 24MHz BLCK to restore the clocks properly
@ -322,15 +329,6 @@ static int bsp_init_before_ap_bringup(struct udevice *dev)
return 0;
}
static int cpu_config_tdp_levels(void)
{
msr_t platform_info;
/* Bits 34:33 indicate how many levels supported */
platform_info = msr_read(MSR_PLATFORM_INFO);
return (platform_info.hi >> 1) & 3;
}
static void set_max_ratio(void)
{
msr_t msr, perf_ctl;
@ -339,7 +337,7 @@ static void set_max_ratio(void)
/* Check for configurable TDP option */
if (turbo_get_state() == TURBO_ENABLED) {
msr = msr_read(MSR_NHM_TURBO_RATIO_LIMIT);
msr = msr_read(MSR_TURBO_RATIO_LIMIT);
perf_ctl.lo = (msr.lo & 0xff) << 8;
} else if (cpu_config_tdp_levels()) {
/* Set to nominal TDP ratio */
@ -350,10 +348,10 @@ static void set_max_ratio(void)
msr = msr_read(MSR_PLATFORM_INFO);
perf_ctl.lo = msr.lo & 0xff00;
}
msr_write(IA32_PERF_CTL, perf_ctl);
msr_write(MSR_IA32_PERF_CTL, perf_ctl);
debug("cpu: frequency set to %d\n",
((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
((perf_ctl.lo >> 8) & 0xff) * INTEL_BCLK_MHZ);
}
int broadwell_init(struct udevice *dev)
@ -472,9 +470,9 @@ static void configure_misc(void)
msr_t msr;
msr = msr_read(MSR_IA32_MISC_ENABLE);
msr.lo |= (1 << 0); /* Fast String enable */
msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
msr.lo |= MISC_ENABLE_FAST_STRING;
msr.lo |= MISC_ENABLE_TM1;
msr.lo |= MISC_ENABLE_ENHANCED_SPEEDSTEP;
msr_write(MSR_IA32_MISC_ENABLE, msr);
/* Disable thermal interrupts */
@ -488,24 +486,6 @@ static void configure_misc(void)
msr_write(MSR_IA32_PACKAGE_THERM_INTERRUPT, msr);
}
static void configure_thermal_target(struct udevice *dev)
{
int tcc_offset;
msr_t msr;
tcc_offset = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"intel,tcc-offset", 0);
/* Set TCC activaiton offset if supported */
msr = msr_read(MSR_PLATFORM_INFO);
if ((msr.lo & (1 << 30)) && tcc_offset) {
msr = msr_read(MSR_TEMPERATURE_TARGET);
msr.lo &= ~(0xf << 24); /* Bits 27:24 */
msr.lo |= (tcc_offset & 0xf) << 24;
msr_write(MSR_TEMPERATURE_TARGET, msr);
}
}
static void configure_dca_cap(void)
{
struct cpuid_result cpuid_regs;
@ -555,7 +535,7 @@ static void cpu_core_init(struct udevice *dev)
configure_misc();
/* Thermal throttle activation offset */
configure_thermal_target(dev);
cpu_configure_thermal_target(dev);
/* Enable Direct Cache Access */
configure_dca_cap();
@ -645,14 +625,7 @@ void cpu_set_power_limits(int power_limit_1_time)
static int broadwell_get_info(struct udevice *dev, struct cpu_info *info)
{
msr_t msr;
msr = msr_read(IA32_PERF_CTL);
info->cpu_freq = ((msr.lo >> 8) & 0xff) * BROADWELL_BCLK * 1000000;
info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU |
1 << CPU_FEAT_UCODE | 1 << CPU_FEAT_DEVICE_ID;
return 0;
return cpu_intel_get_info(info, INTEL_BCLK_MHZ);
}
static int broadwell_get_count(struct udevice *dev)

View File

@ -19,13 +19,13 @@
*/
#include <common.h>
#include <acpi_s3.h>
#include <command.h>
#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <syscon.h>
#include <asm/acpi.h>
#include <asm/acpi_s3.h>
#include <asm/acpi_table.h>
#include <asm/control_regs.h>
#include <asm/coreboot_tables.h>

View File

@ -1,11 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014 Google Inc.
* Copyright (c) 2016 Google, Inc
* Copyright (C) 2015-2018 Intel Corporation.
* Copyright (C) 2018 Siemens AG
* Some code taken from coreboot cpulib.c
*/
#include <common.h>
#include <cpu.h>
#include <dm.h>
#include <errno.h>
#include <asm/cpu.h>
#include <asm/cpu_common.h>
#include <asm/intel_regs.h>
#include <asm/lapic.h>
@ -110,3 +116,113 @@ int cpu_set_flex_ratio_to_tdp_nominal(void)
/* Not reached */
return -EINVAL;
}
int cpu_intel_get_info(struct cpu_info *info, int bclk)
{
msr_t msr;
msr = msr_read(MSR_IA32_PERF_CTL);
info->cpu_freq = ((msr.lo >> 8) & 0xff) * bclk * 1000000;
info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU |
1 << CPU_FEAT_UCODE | 1 << CPU_FEAT_DEVICE_ID;
return 0;
}
int cpu_configure_thermal_target(struct udevice *dev)
{
u32 tcc_offset;
msr_t msr;
int ret;
ret = dev_read_u32(dev, "tcc-offset", &tcc_offset);
if (!ret)
return -ENOENT;
/* Set TCC activaiton offset if supported */
msr = msr_read(MSR_PLATFORM_INFO);
if (msr.lo & (1 << 30)) {
msr = msr_read(MSR_TEMPERATURE_TARGET);
msr.lo &= ~(0xf << 24); /* Bits 27:24 */
msr.lo |= (tcc_offset & 0xf) << 24;
msr_write(MSR_TEMPERATURE_TARGET, msr);
}
return 0;
}
void cpu_set_perf_control(uint clk_ratio)
{
msr_t perf_ctl;
perf_ctl.lo = (clk_ratio & 0xff) << 8;
perf_ctl.hi = 0;
msr_write(MSR_IA32_PERF_CTL, perf_ctl);
debug("CPU: frequency set to %d MHz\n", clk_ratio * INTEL_BCLK_MHZ);
}
bool cpu_config_tdp_levels(void)
{
msr_t platform_info;
/* Bits 34:33 indicate how many levels supported */
platform_info = msr_read(MSR_PLATFORM_INFO);
return ((platform_info.hi >> 1) & 3) != 0;
}
void cpu_set_p_state_to_turbo_ratio(void)
{
msr_t msr;
msr = msr_read(MSR_TURBO_RATIO_LIMIT);
cpu_set_perf_control(msr.lo);
}
enum burst_mode_t cpu_get_burst_mode_state(void)
{
enum burst_mode_t state;
int burst_en, burst_cap;
msr_t msr;
uint eax;
eax = cpuid_eax(0x6);
burst_cap = eax & 0x2;
msr = msr_read(MSR_IA32_MISC_ENABLE);
burst_en = !(msr.hi & BURST_MODE_DISABLE);
if (!burst_cap && burst_en)
state = BURST_MODE_UNAVAILABLE;
else if (burst_cap && !burst_en)
state = BURST_MODE_DISABLED;
else if (burst_cap && burst_en)
state = BURST_MODE_ENABLED;
else
state = BURST_MODE_UNKNOWN;
return state;
}
void cpu_set_burst_mode(bool burst_mode)
{
msr_t msr;
msr = msr_read(MSR_IA32_MISC_ENABLE);
if (burst_mode)
msr.hi &= ~BURST_MODE_DISABLE;
else
msr.hi |= BURST_MODE_DISABLE;
msr_write(MSR_IA32_MISC_ENABLE, msr);
}
void cpu_set_eist(bool eist_status)
{
msr_t msr;
msr = msr_read(MSR_IA32_MISC_ENABLE);
if (eist_status)
msr.lo |= MISC_ENABLE_ENHANCED_SPEEDSTEP;
else
msr.lo &= ~MISC_ENABLE_ENHANCED_SPEEDSTEP;
msr_write(MSR_IA32_MISC_ENABLE, msr);
}

View File

@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <handoff.h>
#include <asm/cpu_common.h>
#include <asm/intel_regs.h>
#include <asm/lapic.h>
@ -21,6 +22,11 @@ int arch_cpu_init(void)
{
int ret;
#if CONFIG_IS_ENABLED(HANDOFF) && IS_ENABLED(CONFIG_USE_HOB)
struct spl_handoff *ho = gd->spl_handoff;
gd->arch.hob_list = ho->arch.hob_list;
#endif
ret = x86_cpu_reinit_f();
return ret;

View File

@ -199,6 +199,5 @@ int print_cpuinfo(void)
void board_debug_uart_init(void)
{
/* This enables the debug UART */
pci_x86_write_config(NULL, PCH_LPC_DEV, LPC_EN, COMA_LPC_EN,
PCI_SIZE_16);
pci_x86_write_config(PCH_LPC_DEV, LPC_EN, COMA_LPC_EN, PCI_SIZE_16);
}

View File

@ -5,11 +5,11 @@
#include <common.h>
#include <fdtdec.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
void update_fsp_configs(struct fsp_config_data *config,
void fsp_update_configs(struct fsp_config_data *config,
struct fspinit_rtbuf *rt_buf)
{
struct platform_config *plat_config = &config->plat_config;

View File

@ -12,6 +12,7 @@
#include <fdtdec.h>
#include <malloc.h>
#include <asm/cpu.h>
#include <asm/cpu_common.h>
#include <asm/cpu_x86.h>
#include <asm/msr.h>
#include <asm/msr-index.h>
@ -139,19 +140,16 @@ static const u8 power_limit_time_msr_to_sec[] = {
[0x11] = 128,
};
int cpu_config_tdp_levels(void)
bool cpu_ivybridge_config_tdp_levels(void)
{
struct cpuid_result result;
msr_t platform_info;
/* Minimum CPU revision */
result = cpuid(1);
if (result.eax < IVB_CONFIG_TDP_MIN_CPUID)
return 0;
return false;
/* Bits 34:33 indicate how many levels supported */
platform_info = msr_read(MSR_PLATFORM_INFO);
return (platform_info.hi >> 1) & 3;
return cpu_config_tdp_levels();
}
/*
@ -212,7 +210,7 @@ void set_power_limits(u8 power_limit_1_time)
msr_write(MSR_PKG_POWER_LIMIT, limit);
/* Use nominal TDP values for CPUs with configurable TDP */
if (cpu_config_tdp_levels()) {
if (cpu_ivybridge_config_tdp_levels()) {
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
limit.hi = 0;
limit.lo = msr.lo & 0xff;
@ -282,26 +280,6 @@ static void configure_c_states(void)
msr_write(MSR_PP1_CURRENT_CONFIG, msr);
}
static int configure_thermal_target(struct udevice *dev)
{
int tcc_offset;
msr_t msr;
tcc_offset = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"tcc-offset", 0);
/* Set TCC activaiton offset if supported */
msr = msr_read(MSR_PLATFORM_INFO);
if ((msr.lo & (1 << 30)) && tcc_offset) {
msr = msr_read(MSR_TEMPERATURE_TARGET);
msr.lo &= ~(0xf << 24); /* Bits 27:24 */
msr.lo |= (tcc_offset & 0xf) << 24;
msr_write(MSR_TEMPERATURE_TARGET, msr);
}
return 0;
}
static void configure_misc(void)
{
msr_t msr;
@ -348,24 +326,20 @@ static void configure_dca_cap(void)
static void set_max_ratio(void)
{
msr_t msr, perf_ctl;
perf_ctl.hi = 0;
msr_t msr;
uint ratio;
/* Check for configurable TDP option */
if (cpu_config_tdp_levels()) {
if (cpu_ivybridge_config_tdp_levels()) {
/* Set to nominal TDP ratio */
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
perf_ctl.lo = (msr.lo & 0xff) << 8;
ratio = msr.lo & 0xff;
} else {
/* Platform Info bits 15:8 give max ratio */
msr = msr_read(MSR_PLATFORM_INFO);
perf_ctl.lo = msr.lo & 0xff00;
ratio = (msr.lo & 0xff00) >> 8;
}
msr_write(MSR_IA32_PERF_CTL, perf_ctl);
debug("model_x06ax: frequency set to %d\n",
((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
cpu_set_perf_control(ratio);
}
static void set_energy_perf_bias(u8 policy)
@ -413,10 +387,11 @@ static int model_206ax_init(struct udevice *dev)
configure_misc();
/* Thermal throttle activation offset */
ret = configure_thermal_target(dev);
ret = cpu_configure_thermal_target(dev);
if (ret) {
debug("Cannot set thermal target\n");
return ret;
if (ret != -ENOENT)
return ret;
}
/* Enable Direct Cache Access */
@ -436,12 +411,7 @@ static int model_206ax_init(struct udevice *dev)
static int model_206ax_get_info(struct udevice *dev, struct cpu_info *info)
{
msr_t msr;
msr = msr_read(MSR_IA32_PERF_CTL);
info->cpu_freq = ((msr.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK * 1000000;
info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU |
1 << CPU_FEAT_UCODE;
return cpu_intel_get_info(info, INTEL_BCLK_MHZ);
return 0;
}

View File

@ -141,7 +141,7 @@ static void northbridge_init(struct udevice *dev, int rev)
* CPUs with configurable TDP also need power limits set
* in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT.
*/
if (cpu_config_tdp_levels()) {
if (cpu_ivybridge_config_tdp_levels()) {
msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);
writel(msr.lo, MCHBAR_REG(0x59A0));

View File

@ -50,11 +50,20 @@ void mtrr_close(struct mtrr_state *state, bool do_caches)
enable_caches();
}
static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
{
u64 mask;
wrmsrl(MTRR_PHYS_BASE_MSR(reg), start | type);
mask = ~(size - 1);
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
}
int mtrr_commit(bool do_caches)
{
struct mtrr_request *req = gd->arch.mtrr_req;
struct mtrr_state state;
uint64_t mask;
int i;
debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
@ -65,12 +74,8 @@ int mtrr_commit(bool do_caches)
debug("open\n");
mtrr_open(&state, do_caches);
debug("open done\n");
for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) {
mask = ~(req->size - 1);
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
wrmsrl(MTRR_PHYS_BASE_MSR(i), req->start | req->type);
wrmsrl(MTRR_PHYS_MASK_MSR(i), mask | MTRR_PHYS_MASK_VALID);
}
for (i = 0; i < gd->arch.mtrr_req_count; i++, req++)
set_var_mtrr(i, req->type, req->start, req->size);
/* Clear the ones that are unused */
debug("clear\n");
@ -107,3 +112,41 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
return 0;
}
static int get_var_mtrr_count(void)
{
return msr_read(MSR_MTRR_CAP_MSR).lo & MSR_MTRR_CAP_VCNT;
}
static int get_free_var_mtrr(void)
{
struct msr_t maskm;
int vcnt;
int i;
vcnt = get_var_mtrr_count();
/* Identify the first var mtrr which is not valid */
for (i = 0; i < vcnt; i++) {
maskm = msr_read(MTRR_PHYS_MASK_MSR(i));
if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
return i;
}
/* No free var mtrr */
return -ENOSPC;
}
int mtrr_set_next_var(uint type, uint64_t start, uint64_t size)
{
int mtrr;
mtrr = get_free_var_mtrr();
if (mtrr < 0)
return mtrr;
set_var_mtrr(mtrr, type, start, size);
debug("MTRR %x: start=%x, size=%x\n", mtrr, (uint)start, (uint)size);
return 0;
}

View File

@ -16,8 +16,8 @@
#include <asm/io.h>
#include <asm/pci.h>
int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
ulong *valuep, enum pci_size_t size)
int pci_x86_read_config(pci_dev_t bdf, uint offset, ulong *valuep,
enum pci_size_t size)
{
outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
switch (size) {
@ -35,8 +35,8 @@ int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
return 0;
}
int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
ulong value, enum pci_size_t size)
int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
enum pci_size_t size)
{
outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
switch (size) {
@ -54,6 +54,21 @@ int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
return 0;
}
int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
enum pci_size_t size)
{
ulong value;
int ret;
ret = pci_x86_read_config(bdf, offset, &value, size);
if (ret)
return ret;
value &= ~clr;
value |= set;
return pci_x86_write_config(bdf, offset, value, size);
}
void pci_assign_irqs(int bus, int device, u8 irq[4])
{
pci_dev_t bdf;

View File

@ -5,9 +5,9 @@
*/
#include <common.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
void update_fsp_configs(struct fsp_config_data *config,
void fsp_update_configs(struct fsp_config_data *config,
struct fspinit_rtbuf *rt_buf)
{
/* Initialize runtime buffer for fsp_init() */

View File

@ -12,7 +12,7 @@
#include <asm/post.h>
#include <asm/arch/device.h>
#include <asm/arch/tnc.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
#include <asm/processor.h>
static int __maybe_unused disable_igd(void)

View File

@ -2,6 +2,18 @@
/*
* U-Boot - x86 Startup Code
*
* This is always the first code to run from the U-Boot source. To spell it out:
*
* 1. When TPL (Tertiary Program Loader) is enabled, the boot flow is
* TPL->SPL->U-Boot and this file is used for TPL. Then start_from_tpl.S is used
* for SPL and start_from_spl.S is used for U-Boot proper.
*
* 2. When SPL (Secondary Program Loader) is enabled, but not TPL, the boot
* flow is SPL->U-Boot and this file is used for SPL. Then start_from_spl.S is
* used for U-Boot proper.
*
* 3. When neither TPL nor SPL is used, this file is used for U-Boot proper.
*
* (C) Copyright 2008-2011
* Graeme Russ, <graeme.russ@gmail.com>
*
@ -90,7 +102,7 @@ early_board_init_ret:
jmp car_init
.globl car_init_ret
car_init_ret:
#ifndef CONFIG_USE_HOB
#ifdef CONFIG_USE_CAR
/*
* We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM,
* or fully initialised SDRAM - we really don't care which)
@ -130,7 +142,7 @@ car_init_ret:
/* Get address of global_data */
mov %fs:0, %edx
#ifdef CONFIG_USE_HOB
#if defined(CONFIG_USE_HOB) && !defined(CONFIG_USE_CAR)
/* Store the HOB list if we have one */
test %esi, %esi
jz skip_hob

View File

@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* 32-bit x86 Startup Code when running from SPL
*
* 32-bit x86 Startup Code when running from SPL. This is the startup code in
* U-Boot proper, when SPL is used.
* Copyright 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* 32-bit x86 Startup Code when running from TPL
* 32-bit x86 Startup Code when running from TPL. This is the startup code in
* SPL, when TPL is used.
*
* Copyright 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>

View File

@ -60,8 +60,8 @@ int turbo_get_state(void)
cpuid_regs = cpuid(CPUID_LEAF_PM);
turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE);
msr = msr_read(MSR_IA32_MISC_ENABLES);
turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO);
msr = msr_read(MSR_IA32_MISC_ENABLE);
turbo_en = !(msr.hi & MISC_DISABLE_TURBO);
if (!turbo_cap && turbo_en) {
/* Unavailable */
@ -86,9 +86,9 @@ void turbo_enable(void)
/* Only possible if turbo is available but hidden */
if (turbo_get_state() == TURBO_DISABLED) {
/* Clear Turbo Disable bit in Misc Enables */
msr = msr_read(MSR_IA32_MISC_ENABLES);
msr.hi &= ~H_MISC_DISABLE_TURBO;
msr_write(MSR_IA32_MISC_ENABLES, msr);
msr = msr_read(MSR_IA32_MISC_ENABLE);
msr.hi &= ~MISC_DISABLE_TURBO;
msr_write(MSR_IA32_MISC_ENABLE, msr);
/* Update cached turbo state */
set_global_turbo_state(TURBO_ENABLED);

View File

@ -35,6 +35,12 @@ SECTIONS
. = ALIGN(4);
__data_end = .;
__init_end = .;
. = ALIGN(4);
.binman_sym_table : {
__binman_sym_start = .;
KEEP(*(SORT(.binman_sym*)));
__binman_sym_end = .;
}
_image_binary_end = .;

View File

@ -5,7 +5,7 @@
* From coreboot src/arch/x86/wakeup.S
*/
#include <asm/acpi_s3.h>
#include <acpi_s3.h>
#include <asm/processor.h>
#include <asm/processor-flags.h>

View File

@ -21,9 +21,6 @@
#define CPUID_BROADWELL_D0 0x306d3
#define CPUID_BROADWELL_E0 0x306d4
/* Broadwell bus clock is fixed at 100MHz */
#define BROADWELL_BCLK 100
#define BROADWELL_FAMILY_ULT 0x306d0
#define CORE_THREAD_COUNT_MSR 0x35

View File

@ -6,9 +6,6 @@
#ifndef __ASM_ARCH_PCH_H
#define __ASM_ARCH_PCH_H
/* CPU bus clock is fixed at 100MHz */
#define CPU_BCLK 100
#define PMBASE 0x40
#define ACPI_CNTL 0x44
#define ACPI_EN (1 << 7)

View File

@ -8,9 +8,6 @@
#ifndef _ASM_ARCH_MODEL_206AX_H
#define _ASM_ARCH_MODEL_206AX_H
/* SandyBridge/IvyBridge bus clock is fixed at 100MHz */
#define SANDYBRIDGE_BCLK 100
#define CPUID_VMX (1 << 5)
#define CPUID_SMX (1 << 6)
#define MSR_FEATURE_CONFIG 0x13c
@ -61,6 +58,6 @@
/* Configure power limits for turbo mode */
void set_power_limits(u8 power_limit_1_time);
int cpu_config_tdp_levels(void);
bool cpu_ivybridge_config_tdp_levels(void);
#endif

View File

@ -1,12 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Common code for Intel CPUs
*
* Copyright (c) 2016 Google, Inc
*/
#ifndef __ASM_CPU_COMMON_H
#define __ASM_CPU_COMMON_H
#define IA32_PERF_CTL 0x199
/* Standard Intel bus clock is fixed at 100MHz */
enum {
INTEL_BCLK_MHZ = 100
};
struct cpu_info;
/**
* cpu_common_init() - Set up common CPU init
@ -31,4 +38,94 @@ int cpu_common_init(void);
*/
int cpu_set_flex_ratio_to_tdp_nominal(void);
/**
* cpu_intel_get_info() - Obtain CPU info for Intel CPUs
*
* Most Intel CPUs use the same MSR to obtain the clock speed, and use the same
* features. This function fills in these values, given the value of the base
* clock in MHz (typically this should be set to 100).
*
* @info: cpu_info struct to fill in
* @bclk_mz: the base clock in MHz
*
* @return 0 always
*/
int cpu_intel_get_info(struct cpu_info *info, int bclk_mz);
/**
* cpu_configure_thermal_target() - Set the thermal target for a CPU
*
* This looks up the tcc-offset property and uses it to set the
* MSR_TEMPERATURE_TARGET value.
*
* @dev: CPU device
* @return 0 if OK, -ENOENT if no target is given in device tree
*/
int cpu_configure_thermal_target(struct udevice *dev);
/**
* cpu_set_perf_control() - Set the nominal CPU clock speed
*
* This sets the clock speed as a multiplier of BCLK
*
* @clk_ratio: Ratio to use
*/
void cpu_set_perf_control(uint clk_ratio);
/**
* cpu_config_tdp_levels() - Check for configurable TDP option
*
* @return true if the CPU has configurable TDP (Thermal-design power)
*/
bool cpu_config_tdp_levels(void);
/** enum burst_mode_t - Burst-mode states */
enum burst_mode_t {
BURST_MODE_UNKNOWN,
BURST_MODE_UNAVAILABLE,
BURST_MODE_DISABLED,
BURST_MODE_ENABLED
};
/*
* cpu_get_burst_mode_state() - Get the Burst/Turbo Mode State
*
* This reads MSR IA32_MISC_ENABLE 0x1A0
* Bit 38 - TURBO_MODE_DISABLE Bit to get state ENABLED / DISABLED.
* Also checks cpuid 0x6 to see whether burst mode is supported.
*
* @return current burst mode status
*/
enum burst_mode_t cpu_get_burst_mode_state(void);
/**
* cpu_set_burst_mode() - Set CPU burst mode
*
* @burst_mode: true to enable burst mode, false to disable
*/
void cpu_set_burst_mode(bool burst_mode);
/**
* cpu_set_eist() - Enable Enhanced Intel Speed Step Technology
*
* @eist_status: true to enable EIST, false to disable
*/
void cpu_set_eist(bool eist_status);
/**
* cpu_set_p_state_to_turbo_ratio() - Set turbo ratio
*
* TURBO_RATIO_LIMIT MSR (0x1AD) Bits 31:0 indicates the
* factory configured values for of 1-core, 2-core, 3-core
* and 4-core turbo ratio limits for all processors.
*
* 7:0 - MAX_TURBO_1_CORE
* 15:8 - MAX_TURBO_2_CORES
* 23:16 - MAX_TURBO_3_CORES
* 31:24 - MAX_TURBO_4_CORES
*
* Set PERF_CTL MSR (0x199) P_Req with that value.
*/
void cpu_set_p_state_to_turbo_ratio(void);
#endif

View File

@ -69,6 +69,10 @@ struct __packed hob_graphics_info {
EFI_GUID(0x721acf02, 0x4d77, 0x4c2a, \
0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0)
#define FSP_VARIABLE_NV_DATA_HOB_GUID \
EFI_GUID(0xa034147d, 0x690c, 0x4154, \
0x8d, 0xe6, 0xc0, 0x44, 0x64, 0x1d, 0xe9, 0x42)
#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \
EFI_GUID(0xbbcff46c, 0xc8d3, 0x4113, \
0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e)

View File

@ -33,6 +33,19 @@ struct __packed fsp_header {
#define FSP_HEADER_REVISION_1 1
#define FSP_HEADER_REVISION_2 2
#define FSP_ATTR_GRAPHICS_SUPPORT (1 << 0)
enum fsp_type {
FSP_ATTR_COMP_TYPE_FSP_T = 1,
FSP_ATTR_COMP_TYPE_FSP_M = 2,
FSP_ATTR_COMP_TYPE_FSP_S = 3,
};
enum {
FSP_ATTR_GRAPHICS_SUPPORT = 1 << 0,
FSP_ATTR_COMP_TYPE_SHIFT = 28,
FSP_ATTR_COMP_TYPE_MASK = 0xfU << FSP_ATTR_COMP_TYPE_SHIFT,
};
#define EFI_FSPH_SIGNATURE SIGNATURE_32('F', 'S', 'P', 'H')
#endif

View File

@ -7,177 +7,126 @@
#ifndef __FSP_SUPPORT_H__
#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_infoheader.h"
#include "fsp_bootmode.h"
#include "fsp_azalia.h"
#include <asm/arch/fsp/fsp_vpd.h>
#include <asm/arch/fsp/fsp_configs.h>
#include <asm/fsp/fsp_bootmode.h>
#include <asm/fsp/fsp_fv.h>
#include <asm/fsp/fsp_hob.h>
#include <asm/fsp/fsp_infoheader.h>
#include <asm/fsp/fsp_types.h>
#include <asm/fsp_arch.h>
#include <asm/fsp/fsp_azalia.h>
#define FSP_LOWMEM_BASE 0x100000UL
#define FSP_HIGHMEM_BASE 0x100000000ULL
#define UPD_TERMINATOR 0x55AA
/**
* FSP Continuation assembly helper routine
* fsp_find_header() - Find FSP header offset in FSP image
*
* This routine jumps to the C version of FSP continuation function
* @return the offset of FSP header. If signature is invalid, returns 0.
*/
void asm_continuation(void);
struct fsp_header *fsp_find_header(void);
/**
* FSP initialization complete
*
* This is the function that indicates FSP initialization is complete and jumps
* back to the bootloader with HOB list pointer as the parameter.
*
* @hob_list: HOB list pointer
*/
void fsp_init_done(void *hob_list);
/**
* FSP Continuation function
*
* @status: Always 0
* @hob_list: HOB list pointer
*
* @retval: Never returns
*/
void fsp_continue(u32 status, void *hob_list);
/**
* Find FSP header offset in FSP image
*
* @retval: the offset of FSP header. If signature is invalid, returns 0.
*/
struct fsp_header *find_fsp_header(void);
/**
* FSP initialization wrapper function.
*
* @stack_top: bootloader stack top address
* @boot_mode: boot mode defined in fsp_bootmode.h
* @nvs_buf: Non-volatile memory buffer pointer
*/
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf);
/**
* FSP notification wrapper function
* fsp_notify() - FSP notification wrapper function
*
* @fsp_hdr: Pointer to FSP information header
* @phase: FSP initialization phase defined in enum fsp_phase
*
* @retval: compatible status code with EFI_STATUS defined in PI spec
* @return compatible status code with EFI_STATUS defined in PI spec
*/
u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase);
/**
* This function retrieves the top of usable low memory.
* fsp_get_usable_lowmem_top() - retrieves the top of usable low memory
*
* @hob_list: A HOB list pointer.
*
* @retval: Usable low memory top.
* @return Usable low memory top.
*/
u32 fsp_get_usable_lowmem_top(const void *hob_list);
/**
* This function retrieves the top of usable high memory.
* fsp_get_usable_highmem_top() - retrieves the top of usable high memory
*
* @hob_list: A HOB list pointer.
*
* @retval: Usable high memory top.
* @return Usable high memory top.
*/
u64 fsp_get_usable_highmem_top(const void *hob_list);
/**
* This function retrieves a special reserved memory region.
* fsp_get_reserved_mem_from_guid() - retrieves a special reserved memory region
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the GUID HOB data buffer length.
* If the GUID HOB is located, the length will be updated.
* @guid: A pointer to the owner guild.
*
* @retval: Reserved region start address.
* @return Reserved region start address.
* 0 if this region does not exist.
*/
u64 fsp_get_reserved_mem_from_guid(const void *hob_list,
u64 *len, const efi_guid_t *guid);
/**
* This function retrieves the FSP reserved normal memory.
* fsp_get_fsp_reserved_mem() - retrieves the FSP reserved normal memory
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the FSP reserved memory length buffer.
* If the GUID HOB is located, the length will be updated.
* @retval: FSP reserved memory base
* @return FSP reserved memory base
* 0 if this region does not exist.
*/
u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len);
/**
* This function retrieves the TSEG reserved normal memory.
* fsp_get_tseg_reserved_mem() - retrieves the TSEG reserved normal memory
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the TSEG reserved memory length buffer.
* If the GUID HOB is located, the length will be updated.
*
* @retval NULL: Failed to find the TSEG reserved memory.
* @retval others: TSEG reserved memory base.
* @return NULL: Failed to find the TSEG reserved memory.
* @return others: TSEG reserved memory base.
*/
u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len);
/**
* This function retrieves FSP Non-volatile Storage HOB buffer and size.
* fsp_get_nvs_data() - retrieves FSP Non-volatile Storage HOB buffer and size
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the NVS data buffer length.
* If the HOB is located, the length will be updated.
*
* @retval NULL: Failed to find the NVS HOB.
* @retval others: FSP NVS data buffer pointer.
* @return NULL: Failed to find the NVS HOB.
* @return others: FSP NVS data buffer pointer.
*/
void *fsp_get_nvs_data(const void *hob_list, u32 *len);
/**
* This function retrieves Bootloader temporary stack buffer and size.
* fsp_get_var_nvs_data() - get FSP variable Non-volatile Storage HOB buffer
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the bootloader temporary stack length.
* @len: A pointer to the NVS data buffer length.
* If the HOB is located, the length will be updated.
*
* @retval NULL: Failed to find the bootloader temporary stack HOB.
* @retval others: Bootloader temporary stackbuffer pointer.
* @return NULL: Failed to find the NVS HOB.
* @return others: FSP NVS data buffer pointer.
*/
void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len);
void *fsp_get_var_nvs_data(const void *hob_list, u32 *len);
/**
* This function retrieves graphics information.
* fsp_get_graphics_info() - retrieves graphics information.
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the graphics info HOB length.
* If the HOB is located, the length will be updated.
*
* @retval NULL: Failed to find the graphics info HOB.
* @retval others: A pointer to struct hob_graphics_info.
* @return NULL: Failed to find the graphics info HOB.
* @return others: A pointer to struct hob_graphics_info.
*/
void *fsp_get_graphics_info(const void *hob_list, u32 *len);
/**
* This function overrides the default configurations of FSP.
*
* @config: A pointer to the FSP configuration data structure
* @rt_buf: A pointer to the FSP runtime buffer data structure
*
* @return: None
*/
void update_fsp_configs(struct fsp_config_data *config,
struct fspinit_rtbuf *rt_buf);
/**
* fsp_init_phase_pci() - Tell the FSP that we have completed PCI init
*
@ -185,4 +134,30 @@ void update_fsp_configs(struct fsp_config_data *config,
*/
int fsp_init_phase_pci(void);
/**
* fsp_scan_for_ram_size() - Scan the HOB list to find the RAM size
*
* This sets gd->ram_size based on what it finds.
*
* @return 0 if OK, -ve on error
*/
int fsp_scan_for_ram_size(void);
/**
* fsp_prepare_mrc_cache() - Find the DRAM training data from the MRC cache
*
* @return pointer to data, or NULL if no cache or no data found in the cache
*/
void *fsp_prepare_mrc_cache(void);
/**
* fsp_notify() - FSP notification wrapper function
*
* @fsp_hdr: Pointer to FSP information header
* @phase: FSP initialization phase defined in enum fsp_phase
*
* @return compatible status code with EFI_STATUS defined in PI spec
*/
u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase);
#endif

View File

@ -0,0 +1,72 @@
/* SPDX-License-Identifier: Intel */
/*
* Copyright (C) 2013, Intel Corporation
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#ifndef __FSP1_SUPPORT_H__
#define __FSP1_SUPPORT_H__
#include <asm/fsp/fsp_support.h>
#include "fsp_ffs.h"
/**
* fsp_asm_continuation() - FSP Continuation assembly helper routine
*
* This routine jumps to the C version of FSP continuation function
*/
void fsp_asm_continuation(void);
/**
* fsp_init_done() - FSP initialization complete
*
* This is the function that indicates FSP initialization is complete and jumps
* back to the bootloader with HOB list pointer as the parameter.
*
* @hob_list: HOB list pointer
*/
void fsp_init_done(void *hob_list);
/**
* fsp_continue() - FSP Continuation function
*
* @status: Always 0
* @hob_list: HOB list pointer
*
* @return Never returns
*/
void fsp_continue(u32 status, void *hob_list);
/**
* fsp_init() - FSP initialization wrapper function
*
* @stack_top: bootloader stack top address
* @boot_mode: boot mode defined in fsp_bootmode.h
* @nvs_buf: Non-volatile memory buffer pointer
*/
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf);
/**
* fsp_get_bootloader_tmp_mem() - retrieves temporary stack buffer and size
*
* @hob_list: A HOB list pointer.
* @len: A pointer to the bootloader temporary stack length.
* If the HOB is located, the length will be updated.
*
* @return NULL: Failed to find the bootloader temporary stack HOB.
* @return others: Bootloader temporary stackbuffer pointer.
*/
void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len);
/**
* fsp_update_configs() - overrides the default configurations of FSP
*
* @config: A pointer to the FSP configuration data structure
* @rt_buf: A pointer to the FSP runtime buffer data structure
*
* @return None
*/
void fsp_update_configs(struct fsp_config_data *config,
struct fspinit_rtbuf *rt_buf);
#endif

View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2019 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*
* Architecture-specific definitions (FSP config and VPD/UPD)
*/
#ifndef __FSP_ARCH_H__
#define __FSP_ARCH_H__
/*
* Note: use #ifndef __ASSEMBLY__ around any struct definitions or other C code
* since this file can be included from assembly.
*/
#include <asm/fsp1/fsp_api.h>
#include <asm/fsp1/fsp_ffs.h>
#include <asm/arch/fsp/fsp_vpd.h>
#include <asm/arch/fsp/fsp_configs.h>
#endif

View File

@ -9,7 +9,15 @@
#ifndef __x86_asm_handoff_h
#define __x86_asm_handoff_h
/**
* struct arch_spl_handoff - architecture-specific handoff info
*
* @usable_ram_top: Value returned by board_get_usable_ram_top() in SPL
* @hob_list: Start of FSP hand-off blocks (HOBs)
*/
struct arch_spl_handoff {
ulong usable_ram_top;
void *hob_list;
};
#endif

View File

@ -135,7 +135,7 @@ struct hob_guid {
*
* @hdr: A pointer to a HOB.
*
* @return: A pointer to the next HOB in the HOB list.
* @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)
@ -152,8 +152,8 @@ static inline const struct hob_header *get_next_hob(const struct hob_header
*
* @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.
* @return true: The HOB specified by hdr is the last HOB in the HOB list.
* @return 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)
{
@ -169,7 +169,7 @@ static inline bool end_of_hob(const struct hob_header *hdr)
*
* @hdr: A pointer to a HOB.
*
* @return: A pointer to the data buffer in a HOB.
* @return A pointer to the data buffer in a HOB.
*/
static inline void *get_guid_hob_data(const struct hob_header *hdr)
{
@ -185,7 +185,7 @@ static inline void *get_guid_hob_data(const struct hob_header *hdr)
*
* @hdr: A pointer to a HOB.
*
* @return: The size of the data buffer.
* @return The size of the data buffer.
*/
static inline u16 get_guid_hob_data_size(const struct hob_header *hdr)
{
@ -198,7 +198,7 @@ static inline u16 get_guid_hob_data_size(const struct hob_header *hdr)
* @type: HOB type to search
* @hob_list: A pointer to the HOB list
*
* @retval: A HOB object with matching type; Otherwise NULL.
* @return A HOB object with matching type; Otherwise NULL.
*/
const struct hob_header *hob_get_next_hob(uint type, const void *hob_list);
@ -208,7 +208,7 @@ const struct hob_header *hob_get_next_hob(uint type, const void *hob_list);
* @guid: GUID to search
* @hob_list: A pointer to the HOB list
*
* @retval: A HOB object with matching GUID; Otherwise NULL.
* @return 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);
@ -221,8 +221,8 @@ const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid,
* 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.
* @return NULL: Failed to find the GUID HOB.
* @return others: GUID HOB data buffer pointer.
*/
void *hob_get_guid_hob_data(const void *hob_list, u32 *len,
const efi_guid_t *guid);

View File

@ -43,6 +43,12 @@
#define MSR_PIC_MSG_CONTROL 0x2e
#define PLATFORM_INFO_SET_TDP (1 << 29)
#define MSR_MTRR_CAP_MSR 0x0fe
#define MSR_MTRR_CAP_SMRR (1 << 11)
#define MSR_MTRR_CAP_WC (1 << 10)
#define MSR_MTRR_CAP_FIX (1 << 8)
#define MSR_MTRR_CAP_VCNT 0xff
#define MSR_IA32_PERFCTR0 0x000000c1
#define MSR_IA32_PERFCTR1 0x000000c2
#define MSR_FSB_FREQ 0x000000cd
@ -67,6 +73,11 @@
#define ENABLE_ULFM_AUTOCM_MASK (1 << 2)
#define ENABLE_INDP_AUTOCM_MASK (1 << 3)
#define MSR_EMULATE_PM_TIMER 0x121
#define EMULATE_DELAY_OFFSET_VALUE 20
#define EMULATE_PM_TMR_EN (1 << 16)
#define EMULATE_DELAY_VALUE 0x13
#define MSR_IA32_SYSENTER_CS 0x00000174
#define MSR_IA32_SYSENTER_ESP 0x00000175
#define MSR_IA32_SYSENTER_EIP 0x00000176
@ -78,21 +89,67 @@
#define MSR_FLEX_RATIO 0x194
#define FLEX_RATIO_LOCK (1 << 20)
#define FLEX_RATIO_EN (1 << 16)
/* This is burst mode BIT 38 in IA32_MISC_ENABLE MSR at offset 1A0h */
#define BURST_MODE_DISABLE (1 << 6)
#define MSR_IA32_MISC_ENABLE 0x000001a0
/* MISC_ENABLE bits: architectural */
#define MISC_ENABLE_FAST_STRING BIT_ULL(0)
#define MISC_ENABLE_TCC BIT_ULL(1)
#define MISC_DISABLE_TURBO BIT_ULL(6)
#define MISC_ENABLE_EMON BIT_ULL(7)
#define MISC_ENABLE_BTS_UNAVAIL BIT_ULL(11)
#define MISC_ENABLE_PEBS_UNAVAIL BIT_ULL(12)
#define MISC_ENABLE_ENHANCED_SPEEDSTEP BIT_ULL(16)
#define MISC_ENABLE_MWAIT BIT_ULL(18)
#define MISC_ENABLE_LIMIT_CPUID BIT_ULL(22)
#define MISC_ENABLE_XTPR_DISABLE BIT_ULL(23)
#define MISC_ENABLE_XD_DISABLE BIT_ULL(34)
/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
#define MISC_ENABLE_X87_COMPAT BIT_ULL(2)
#define MISC_ENABLE_TM1 BIT_ULL(3)
#define MISC_ENABLE_SPLIT_LOCK_DISABLE BIT_ULL(4)
#define MISC_ENABLE_L3CACHE_DISABLE BIT_ULL(6)
#define MISC_ENABLE_SUPPRESS_LOCK BIT_ULL(8)
#define MISC_ENABLE_PREFETCH_DISABLE BIT_ULL(9)
#define MISC_ENABLE_FERR BIT_ULL(10)
#define MISC_ENABLE_FERR_MULTIPLEX BIT_ULL(10)
#define MISC_ENABLE_TM2 BIT_ULL(13)
#define MISC_ENABLE_ADJ_PREF_DISABLE BIT_ULL(19)
#define MISC_ENABLE_SPEEDSTEP_LOCK BIT_ULL(20)
#define MISC_ENABLE_L1D_CONTEXT BIT_ULL(24)
#define MISC_ENABLE_DCU_PREF_DISABLE BIT_ULL(37)
#define MISC_ENABLE_TURBO_DISABLE BIT_ULL(38)
#define MISC_ENABLE_IP_PREF_DISABLE BIT_ULL(39)
#define MSR_IA32_MISC_ENABLES 0x000001a0
#define MSR_TEMPERATURE_TARGET 0x1a2
#define MSR_PREFETCH_CTL 0x1a4
#define PREFETCH_L1_DISABLE (1 << 0)
#define PREFETCH_L2_DISABLE (1 << 2)
#define MSR_OFFCORE_RSP_0 0x000001a6
#define MSR_OFFCORE_RSP_1 0x000001a7
#define MSR_MISC_PWR_MGMT 0x1aa
#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0)
#define MSR_NHM_TURBO_RATIO_LIMIT 0x000001ad
#define MSR_IVT_TURBO_RATIO_LIMIT 0x000001ae
#define MSR_TURBO_RATIO_LIMIT 0x000001ad
#define MSR_IA32_ENERGY_PERFORMANCE_BIAS 0x1b0
#define ENERGY_POLICY_PERFORMANCE 0
#define ENERGY_POLICY_NORMAL 6
#define ENERGY_POLICY_POWERSAVE 15
#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
#define PACKAGE_THERM_STATUS_PROCHOT BIT(0)
#define PACKAGE_THERM_STATUS_POWER_LIMIT BIT(10)
#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2
#define PACKAGE_THERM_INT_HIGH_ENABLE BIT(0)
#define PACKAGE_THERM_INT_LOW_ENABLE BIT(1)
#define PACKAGE_THERM_INT_PLN_ENABLE BIT(24)
#define MSR_LBR_SELECT 0x000001c8
#define MSR_LBR_TOS 0x000001c9
#define MSR_IA32_PLATFORM_DCA_CAP 0x1f8
@ -404,68 +461,6 @@
#define MSR_THERM2_CTL_TM_SELECT (1ULL << 16)
#define MSR_IA32_MISC_ENABLE 0x000001a0
#define H_MISC_DISABLE_TURBO (1 << 6)
#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
#define ENERGY_PERF_BIAS_PERFORMANCE 0
#define ENERGY_PERF_BIAS_NORMAL 6
#define ENERGY_PERF_BIAS_POWERSAVE 15
#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
#define PACKAGE_THERM_STATUS_PROCHOT (1 << 0)
#define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10)
#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2
#define PACKAGE_THERM_INT_HIGH_ENABLE (1 << 0)
#define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1)
#define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24)
/* Thermal Thresholds Support */
#define THERM_INT_THRESHOLD0_ENABLE (1 << 15)
#define THERM_SHIFT_THRESHOLD0 8
#define THERM_MASK_THRESHOLD0 (0x7f << THERM_SHIFT_THRESHOLD0)
#define THERM_INT_THRESHOLD1_ENABLE (1 << 23)
#define THERM_SHIFT_THRESHOLD1 16
#define THERM_MASK_THRESHOLD1 (0x7f << THERM_SHIFT_THRESHOLD1)
#define THERM_STATUS_THRESHOLD0 (1 << 6)
#define THERM_LOG_THRESHOLD0 (1 << 7)
#define THERM_STATUS_THRESHOLD1 (1 << 8)
#define THERM_LOG_THRESHOLD1 (1 << 9)
/* MISC_ENABLE bits: architectural */
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0)
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)
#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7)
#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11)
#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12)
#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16)
#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18)
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22)
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23)
#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34)
/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2)
#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3)
#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4)
#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6)
#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8)
#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9)
#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10)
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10)
#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13)
#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19)
#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20)
#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24)
#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37)
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38)
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39)
#define MSR_IA32_TSC_DEADLINE 0x000006E0
/* P4/Xeon+ specific */
@ -600,6 +595,12 @@
#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490
#define MSR_IA32_VMX_VMFUNC 0x00000491
#define MSR_IA32_PQR_ASSOC 0xc8f
/* MSR bits 33:32 encode slot number 0-3 */
#define MSR_IA32_PQR_ASSOC_MASK (1 << 0 | 1 << 1)
#define MSR_L2_QOS_MASK(reg) (0xd10 + (reg))
/* VMX_BASIC bits and bitmasks */
#define VMX_BASIC_VMCS_SIZE_SHIFT 32
#define VMX_BASIC_64 0x0001000000000000LLU

View File

@ -25,6 +25,7 @@
#define MTRR_CAP_FIX (1 << 8)
#define MTRR_CAP_VCNT_MASK 0xff
#define MTRR_DEF_TYPE_MASK 0xff
#define MTRR_DEF_TYPE_EN (1 << 11)
#define MTRR_DEF_TYPE_FIX_EN (1 << 10)
@ -116,6 +117,18 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size);
*/
int mtrr_commit(bool do_caches);
/**
* mtrr_set_next_var() - set up a variable MTRR
*
* This finds the first free variable MTRR and sets to the given area
*
* @type: Requested type (MTRR_TYPE_)
* @start: Start address
* @size: Size
* @return 0 on success, -ENOSPC if there are no more MTRRs
*/
int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);
#endif
#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)

View File

@ -17,11 +17,48 @@
#ifndef __ASSEMBLY__
int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
ulong *valuep, enum pci_size_t size);
/**
* pci_x86_read_config() - Read a configuration value from a device
*
* This function can be called before PCI is set up in driver model.
*
* @bdf: PCI device address: bus, device and function -see PCI_BDF()
* @offset: Register offset to read
* @valuep: Place to put the returned value
* @size: Access size
* @return 0 if OK, -ve on error
*/
int pci_x86_read_config(pci_dev_t bdf, uint offset, ulong *valuep,
enum pci_size_t size);
int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
ulong value, enum pci_size_t size);
/**
* pci_bus_write_config() - Write a configuration value to a device
*
* This function can be called before PCI is set up in driver model.
*
* @bdf: PCI device address: bus, device and function -see PCI_BDF()
* @offset: Register offset to write
* @value: Value to write
* @size: Access size
* @return 0 if OK, -ve on error
*/
int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
enum pci_size_t size);
/**
* pci_bus_clrset_config32() - Update a configuration value for a device
*
* The register at @offset is updated to (oldvalue & ~clr) | set. This function
* can be called before PCI is set up in driver model.
*
* @bdf: PCI device address: bus, device and function -see PCI_BDF()
* @offset: Register offset to update
* @clr: Bits to clear
* @set: Bits to set
* @return 0 if OK, -ve on error
*/
int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
enum pci_size_t size);
/**
* Assign IRQ number to a PCI device

View File

@ -10,8 +10,7 @@
#define CONFIG_SPL_BOARD_LOAD_IMAGE
enum {
BOOT_DEVICE_SPI = 10,
BOOT_DEVICE_BOARD,
BOOT_DEVICE_SPI_MMAP = 10,
BOOT_DEVICE_CROS_VBOOT,
};

View File

@ -74,7 +74,7 @@ u32 isa_map_rom(u32 bus_addr, int size);
/* arch/x86/lib/... */
int video_bios_init(void);
/* arch/x86/lib/fsp/... */
/* arch/x86/lib/fsp1,2/... */
/**
* fsp_save_s3_stack() - save stack address to CMOS for next S3 boot

View File

@ -44,6 +44,8 @@ obj-$(CONFIG_CMD_ZBOOT) += zimage.o
endif
obj-$(CONFIG_USE_HOB) += hob.o
obj-$(CONFIG_HAVE_FSP) += fsp/
obj-$(CONFIG_FSP_VERSION1) += fsp1/
obj-$(CONFIG_FSP_VERSION2) += fsp2/
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_TPL_BUILD

View File

@ -4,8 +4,8 @@
*/
#include <common.h>
#include <acpi_s3.h>
#include <asm/acpi.h>
#include <asm/acpi_s3.h>
#include <asm/acpi_table.h>
#include <asm/post.h>
#include <linux/linkage.h>

View File

@ -4,8 +4,8 @@
*/
#include <common.h>
#include <acpi_s3.h>
#include <vbe.h>
#include <asm/acpi_s3.h>
#include <asm/coreboot_tables.h>
#include <asm/e820.h>

View File

@ -1,9 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2015 Google, Inc
# Copyright 2019 Google LLC
obj-y += fsp_car.o
obj-y += fsp_common.o
obj-y += fsp_dram.o
obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o
obj-y += fsp_support.o

View File

@ -4,10 +4,10 @@
*/
#include <common.h>
#include <acpi_s3.h>
#include <dm.h>
#include <errno.h>
#include <rtc.h>
#include <asm/acpi_s3.h>
#include <asm/cmos_layout.h>
#include <asm/early_cmos.h>
#include <asm/io.h>
@ -55,11 +55,9 @@ void board_final_cleanup(void)
debug("fail, error code %x\n", status);
else
debug("OK\n");
return;
}
static __maybe_unused void *fsp_prepare_mrc_cache(void)
void *fsp_prepare_mrc_cache(void)
{
struct mrc_data_container *cache;
struct mrc_region entry;
@ -104,62 +102,3 @@ int fsp_save_s3_stack(void)
return 0;
}
#endif
int arch_fsp_init(void)
{
void *nvs;
int stack = CONFIG_FSP_TEMP_RAM_ADDR;
int boot_mode = BOOT_FULL_CONFIG;
#ifdef CONFIG_HAVE_ACPI_RESUME
int prev_sleep_state = chipset_prev_sleep_state();
gd->arch.prev_sleep_state = prev_sleep_state;
#endif
if (!gd->arch.hob_list) {
#ifdef CONFIG_ENABLE_MRC_CACHE
nvs = fsp_prepare_mrc_cache();
#else
nvs = NULL;
#endif
#ifdef CONFIG_HAVE_ACPI_RESUME
if (prev_sleep_state == ACPI_S3) {
if (nvs == NULL) {
/* If waking from S3 and no cache then */
debug("No MRC cache found in S3 resume path\n");
post_code(POST_RESUME_FAILURE);
/* Clear Sleep Type */
chipset_clear_sleep_state();
/* Reboot */
debug("Rebooting..\n");
outb(SYS_RST | RST_CPU, IO_PORT_RESET);
/* Should not reach here.. */
panic("Reboot System");
}
/*
* DM is not available yet at this point, hence call
* CMOS access library which does not depend on DM.
*/
stack = cmos_read32(CMOS_FSP_STACK_ADDR);
boot_mode = BOOT_ON_S3_RESUME;
}
#endif
/*
* The first time we enter here, call fsp_init().
* Note the execution does not return to this function,
* instead it jumps to fsp_continue().
*/
fsp_init(stack, boot_mode, nvs);
} else {
/*
* The second time we enter here, adjust the size of malloc()
* pool before relocation. Given gd->malloc_base was adjusted
* after the call to board_init_f_init_reserve() in arch/x86/
* cpu/start.S, we should fix up gd->malloc_limit here.
*/
gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
}
return 0;
}

View File

@ -4,6 +4,7 @@
*/
#include <common.h>
#include <handoff.h>
#include <asm/fsp/fsp_support.h>
#include <asm/e820.h>
#include <asm/mrccache.h>
@ -11,7 +12,7 @@
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
int fsp_scan_for_ram_size(void)
{
phys_size_t ram_size = 0;
const struct hob_header *hdr;
@ -22,9 +23,8 @@ int dram_init(void)
if (hdr->type == HOB_TYPE_RES_DESC) {
res_desc = (struct hob_res_desc *)hdr;
if (res_desc->type == RES_SYS_MEM ||
res_desc->type == RES_MEM_RESERVED) {
res_desc->type == RES_MEM_RESERVED)
ram_size += res_desc->len;
}
}
hdr = get_next_hob(hdr);
}
@ -32,13 +32,8 @@ int dram_init(void)
gd->ram_size = ram_size;
post_code(POST_DRAM);
#ifdef CONFIG_ENABLE_MRC_CACHE
gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list,
&gd->arch.mrc_output_len);
#endif
return 0;
}
};
int dram_init_banksize(void)
{
@ -48,19 +43,6 @@ int dram_init_banksize(void)
return 0;
}
/*
* This function looks for the highest region of memory lower than 4GB which
* has enough space for U-Boot where U-Boot is aligned on a page boundary.
* It overrides the default implementation found elsewhere which simply
* picks the end of ram, wherever that may be. The location of the stack,
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
ulong board_get_usable_ram_top(ulong total_size)
{
return fsp_get_usable_lowmem_top(gd->arch.hob_list);
}
unsigned int install_e820_map(unsigned int max_entries,
struct e820_entry *entries)
{
@ -98,7 +80,7 @@ unsigned int install_e820_map(unsigned int max_entries,
* reserved in order for ACPI S3 resume to work.
*/
entries[num_entries].addr = gd->start_addr_sp - CONFIG_STACK_SIZE;
entries[num_entries].size = gd->ram_top - gd->start_addr_sp + \
entries[num_entries].size = gd->ram_top - gd->start_addr_sp +
CONFIG_STACK_SIZE;
entries[num_entries].type = E820_RESERVED;
num_entries++;
@ -106,3 +88,13 @@ unsigned int install_e820_map(unsigned int max_entries,
return num_entries;
}
#if CONFIG_IS_ENABLED(HANDOFF) && IS_ENABLED(CONFIG_USE_HOB)
int handoff_arch_save(struct spl_handoff *ho)
{
ho->arch.usable_ram_top = fsp_get_usable_lowmem_top(gd->arch.hob_list);
ho->arch.hob_list = gd->arch.hob_list;
return 0;
}
#endif

View File

@ -5,199 +5,9 @@
*/
#include <common.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
#include <asm/post.h>
struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void)
{
/*
* This function may be called before the a stack is established,
* so special care must be taken. First, it cannot declare any local
* variable using stack. Only register variable can be used here.
* Secondly, some compiler version will add prolog or epilog code
* for the C function. If so the function call may not work before
* stack is ready.
*
* GCC 4.8.1 has been verified to be working for the following codes.
*/
volatile register u8 *fsp asm("eax");
/* Initalize the FSP base */
fsp = (u8 *)CONFIG_FSP_ADDR;
/* Check the FV signature, _FVH */
if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) {
/* Go to the end of the FV header and align the address */
fsp += ((struct fv_header *)fsp)->ext_hdr_off;
fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size;
fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8);
} else {
fsp = 0;
}
/* Check the FFS GUID */
if (fsp &&
((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 {
fsp = 0;
}
if (fsp &&
((struct raw_section *)fsp)->type == EFI_SECTION_RAW) {
/* Add the raw section header size to find the FSP header */
fsp += sizeof(struct raw_section);
} else {
fsp = 0;
}
return (struct fsp_header *)fsp;
}
void fsp_continue(u32 status, void *hob_list)
{
post_code(POST_MRC);
assert(status == 0);
/* The boot loader main function entry */
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
{
struct fsp_config_data config_data;
fsp_init_f init;
struct fsp_init_params params;
struct fspinit_rtbuf rt_buf;
struct fsp_header *fsp_hdr;
struct fsp_init_params *params_ptr;
#ifdef CONFIG_FSP_USE_UPD
struct vpd_region *fsp_vpd;
struct upd_region *fsp_upd;
#endif
fsp_hdr = find_fsp_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header was found */
panic("Invalid FSP header");
}
config_data.common.fsp_hdr = fsp_hdr;
config_data.common.stack_top = stack_top;
config_data.common.boot_mode = boot_mode;
#ifdef CONFIG_FSP_USE_UPD
/* Get VPD region start */
fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base +
fsp_hdr->cfg_region_off);
/* Verify the VPD data region is valid */
assert(fsp_vpd->sign == VPD_IMAGE_ID);
fsp_upd = &config_data.fsp_upd;
/* Copy default data from Flash */
memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
sizeof(struct upd_region));
/* Verify the UPD data region is valid */
assert(fsp_upd->terminator == UPD_TERMINATOR);
#endif
memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf));
/* Override any configuration if required */
update_fsp_configs(&config_data, &rt_buf);
memset(&params, 0, sizeof(struct fsp_init_params));
params.nvs_buf = nvs_buf;
params.rt_buf = (struct fspinit_rtbuf *)&rt_buf;
params.continuation = (fsp_continuation_f)asm_continuation;
init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init);
params_ptr = &params;
post_code(POST_PRE_MRC);
/* Load GDT for FSP */
setup_fsp_gdt();
/*
* Use ASM code to ensure the register value in EAX & EDX
* will be passed into fsp_continue
*/
asm volatile (
"pushl %0;"
"call *%%eax;"
".global asm_continuation;"
"asm_continuation:;"
"movl 4(%%esp), %%eax;" /* status */
"movl 8(%%esp), %%edx;" /* hob_list */
"jmp fsp_continue;"
: : "m"(params_ptr), "a"(init)
);
/*
* Should never get here.
* Control will continue from fsp_continue.
* This line below is to prevent the compiler from optimizing
* structure intialization.
*
* DO NOT REMOVE!
*/
init(&params);
}
u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase)
{
fsp_notify_f notify;
struct fsp_notify_params params;
struct fsp_notify_params *params_ptr;
u32 status;
if (!fsp_hdr)
fsp_hdr = (struct fsp_header *)find_fsp_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header */
panic("Invalid FSP header");
}
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify);
params.phase = phase;
params_ptr = &params;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
);
return status;
}
u32 fsp_get_usable_lowmem_top(const void *hob_list)
{
const struct hob_header *hdr;
@ -324,7 +134,7 @@ u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len)
base = (u32)fsp_get_reserved_mem_from_guid(hob_list,
&length, &guid);
if ((len != 0) && (base != 0))
if (len && base)
*len = (u32)length;
return base;
@ -338,7 +148,7 @@ u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len)
base = (u32)fsp_get_reserved_mem_from_guid(hob_list,
&length, &guid);
if ((len != 0) && (base != 0))
if (len && base)
*len = (u32)length;
return base;
@ -351,6 +161,13 @@ void *fsp_get_nvs_data(const void *hob_list, u32 *len)
return hob_get_guid_hob_data(hob_list, len, &guid);
}
void *fsp_get_var_nvs_data(const void *hob_list, u32 *len)
{
const efi_guid_t guid = FSP_VARIABLE_NV_DATA_HOB_GUID;
return hob_get_guid_hob_data(hob_list, len, &guid);
}
void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len)
{
const efi_guid_t guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID;

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2015 Google, Inc
obj-y += fsp_car.o
obj-y += fsp_common.o
obj-y += fsp_dram.o
obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o
obj-y += fsp_support.o

View File

@ -20,10 +20,10 @@ car_init:
car_init_start:
post_code(POST_CAR_START)
lea find_fsp_header_romstack, %esp
jmp find_fsp_header
lea fsp_find_header_romstack, %esp
jmp fsp_find_header
find_fsp_header_ret:
fsp_find_header_ret:
/* EAX points to FSP_INFO_HEADER */
mov %eax, %ebp
@ -91,8 +91,8 @@ die:
* contain the function return address as well as the parameters.
*/
.balign 4
find_fsp_header_romstack:
.long find_fsp_header_ret
fsp_find_header_romstack:
.long fsp_find_header_ret
.balign 4
temp_ram_init_romstack:

View File

@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <acpi_s3.h>
#include <dm.h>
#include <errno.h>
#include <rtc.h>
#include <asm/cmos_layout.h>
#include <asm/early_cmos.h>
#include <asm/io.h>
#include <asm/mrccache.h>
#include <asm/post.h>
#include <asm/processor.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
int arch_fsp_init(void)
{
void *nvs;
int stack = CONFIG_FSP_TEMP_RAM_ADDR;
int boot_mode = BOOT_FULL_CONFIG;
#ifdef CONFIG_HAVE_ACPI_RESUME
int prev_sleep_state = chipset_prev_sleep_state();
gd->arch.prev_sleep_state = prev_sleep_state;
#endif
if (!gd->arch.hob_list) {
if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
nvs = fsp_prepare_mrc_cache();
else
nvs = NULL;
#ifdef CONFIG_HAVE_ACPI_RESUME
if (prev_sleep_state == ACPI_S3) {
if (nvs == NULL) {
/* If waking from S3 and no cache then */
debug("No MRC cache found in S3 resume path\n");
post_code(POST_RESUME_FAILURE);
/* Clear Sleep Type */
chipset_clear_sleep_state();
/* Reboot */
debug("Rebooting..\n");
outb(SYS_RST | RST_CPU, IO_PORT_RESET);
/* Should not reach here.. */
panic("Reboot System");
}
/*
* DM is not available yet at this point, hence call
* CMOS access library which does not depend on DM.
*/
stack = cmos_read32(CMOS_FSP_STACK_ADDR);
boot_mode = BOOT_ON_S3_RESUME;
}
#endif
/*
* The first time we enter here, call fsp_init().
* Note the execution does not return to this function,
* instead it jumps to fsp_continue().
*/
fsp_init(stack, boot_mode, nvs);
} else {
/*
* The second time we enter here, adjust the size of malloc()
* pool before relocation. Given gd->malloc_base was adjusted
* after the call to board_init_f_init_reserve() in arch/x86/
* cpu/start.S, we should fix up gd->malloc_limit here.
*/
gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
}
return 0;
}

View File

@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <asm/fsp/fsp_support.h>
int dram_init(void)
{
int ret;
/* The FSP has already set up DRAM, so grab the info we need */
ret = fsp_scan_for_ram_size();
if (ret)
return ret;
if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list,
&gd->arch.mrc_output_len);
return 0;
}
/*
* This function looks for the highest region of memory lower than 4GB which
* has enough space for U-Boot where U-Boot is aligned on a page boundary.
* It overrides the default implementation found elsewhere which simply
* picks the end of ram, wherever that may be. The location of the stack,
* the relocation address, and how far U-Boot is moved by relocation are
* set in the global data structure.
*/
ulong board_get_usable_ram_top(ulong total_size)
{
return fsp_get_usable_lowmem_top(gd->arch.hob_list);
}

View File

@ -7,7 +7,7 @@
#include <dm.h>
#include <vbe.h>
#include <video.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;

View File

@ -0,0 +1,199 @@
// SPDX-License-Identifier: Intel
/*
* Copyright (C) 2013, Intel Corporation
* Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <asm/fsp1/fsp_support.h>
#include <asm/post.h>
struct fsp_header *__attribute__((optimize("O0"))) fsp_find_header(void)
{
/*
* This function may be called before the a stack is established,
* so special care must be taken. First, it cannot declare any local
* variable using stack. Only register variable can be used here.
* Secondly, some compiler version will add prolog or epilog code
* for the C function. If so the function call may not work before
* stack is ready.
*
* GCC 4.8.1 has been verified to be working for the following codes.
*/
volatile register u8 *fsp asm("eax");
/* Initalize the FSP base */
fsp = (u8 *)CONFIG_FSP_ADDR;
/* Check the FV signature, _FVH */
if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) {
/* Go to the end of the FV header and align the address */
fsp += ((struct fv_header *)fsp)->ext_hdr_off;
fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size;
fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8);
} else {
fsp = 0;
}
/* Check the FFS GUID */
if (fsp &&
((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 {
fsp = 0;
}
if (fsp &&
((struct raw_section *)fsp)->type == EFI_SECTION_RAW) {
/* Add the raw section header size to find the FSP header */
fsp += sizeof(struct raw_section);
} else {
fsp = 0;
}
return (struct fsp_header *)fsp;
}
void fsp_continue(u32 status, void *hob_list)
{
post_code(POST_MRC);
assert(status == 0);
/* The boot loader main function entry */
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
{
struct fsp_config_data config_data;
fsp_init_f init;
struct fsp_init_params params;
struct fspinit_rtbuf rt_buf;
struct fsp_header *fsp_hdr;
struct fsp_init_params *params_ptr;
#ifdef CONFIG_FSP_USE_UPD
struct vpd_region *fsp_vpd;
struct upd_region *fsp_upd;
#endif
fsp_hdr = fsp_find_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header was found */
panic("Invalid FSP header");
}
config_data.common.fsp_hdr = fsp_hdr;
config_data.common.stack_top = stack_top;
config_data.common.boot_mode = boot_mode;
#ifdef CONFIG_FSP_USE_UPD
/* Get VPD region start */
fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base +
fsp_hdr->cfg_region_off);
/* Verify the VPD data region is valid */
assert(fsp_vpd->sign == VPD_IMAGE_ID);
fsp_upd = &config_data.fsp_upd;
/* Copy default data from Flash */
memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
sizeof(struct upd_region));
/* Verify the UPD data region is valid */
assert(fsp_upd->terminator == UPD_TERMINATOR);
#endif
memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf));
/* Override any configuration if required */
fsp_update_configs(&config_data, &rt_buf);
memset(&params, 0, sizeof(struct fsp_init_params));
params.nvs_buf = nvs_buf;
params.rt_buf = (struct fspinit_rtbuf *)&rt_buf;
params.continuation = (fsp_continuation_f)fsp_asm_continuation;
init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init);
params_ptr = &params;
post_code(POST_PRE_MRC);
/* Load GDT for FSP */
setup_fsp_gdt();
/*
* Use ASM code to ensure the register value in EAX & EDX
* will be passed into fsp_continue
*/
asm volatile (
"pushl %0;"
"call *%%eax;"
".global fsp_asm_continuation;"
"fsp_asm_continuation:;"
"movl 4(%%esp), %%eax;" /* status */
"movl 8(%%esp), %%edx;" /* hob_list */
"jmp fsp_continue;"
: : "m"(params_ptr), "a"(init)
);
/*
* Should never get here.
* Control will continue from fsp_continue.
* This line below is to prevent the compiler from optimizing
* structure intialization.
*
* DO NOT REMOVE!
*/
init(&params);
}
u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase)
{
fsp_notify_f notify;
struct fsp_notify_params params;
struct fsp_notify_params *params_ptr;
u32 status;
if (!fsp_hdr)
fsp_hdr = (struct fsp_header *)fsp_find_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header */
panic("Invalid FSP header");
}
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify);
params.phase = phase;
params_ptr = &params;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
);
return status;
}

View File

@ -13,7 +13,7 @@
* @type: HOB type to search
* @hob_list: A pointer to the HOB list
*
* @retval: A HOB object with matching type; Otherwise NULL.
* @return A HOB object with matching type; Otherwise NULL.
*/
const struct hob_header *hob_get_next_hob(uint type, const void *hob_list)
{
@ -38,7 +38,7 @@ const struct hob_header *hob_get_next_hob(uint type, const void *hob_list)
* @guid: GUID to search
* @hob_list: A pointer to the HOB list
*
* @retval: A HOB object with matching GUID; Otherwise NULL.
* @return 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)
@ -65,8 +65,8 @@ const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid,
* 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.
* @return NULL: Failed to find the GUID HOB.
* @return others: GUID HOB data buffer pointer.
*/
void *hob_get_guid_hob_data(const void *hob_list, u32 *len,
const efi_guid_t *guid)

View File

@ -12,15 +12,23 @@ DECLARE_GLOBAL_DATA_PTR;
int init_cache_f_r(void)
{
#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) && \
!defined(CONFIG_SYS_SLIMBOOTLOADER)
bool do_mtrr = CONFIG_IS_ENABLED(X86_32BIT_INIT) ||
IS_ENABLED(CONFIG_FSP_VERSION2);
int ret;
ret = mtrr_commit(false);
/* If MTRR MSR is not implemented by the processor, just ignore it */
if (ret && ret != -ENOSYS)
return ret;
#endif
do_mtrr &= !IS_ENABLED(CONFIG_FSP_VERSION1) &&
!IS_ENABLED(CONFIG_SYS_SLIMBOOTLOADER);
if (do_mtrr) {
ret = mtrr_commit(false);
/*
* If MTRR MSR is not implemented by the processor, just ignore
* it
*/
if (ret && ret != -ENOSYS)
return ret;
}
/* Initialise the CPU cache(s) */
return init_cache();
}

View File

@ -10,5 +10,7 @@
UCLASS_DRIVER(lpc) = {
.id = UCLASS_LPC,
.name = "lpc",
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
.post_bind = dm_scan_fdt_dev,
#endif
};

View File

@ -11,6 +11,7 @@
#include <asm/mrccache.h>
#include <asm/mtrr.h>
#include <asm/processor.h>
#include <asm/spl.h>
#include <asm-generic/sections.h>
DECLARE_GLOBAL_DATA_PTR;
@ -39,12 +40,7 @@ static int x86_spl_init(void)
debug("%s: spl_init() failed\n", __func__);
return ret;
}
#ifdef CONFIG_TPL
/* Do a mini-init if TPL has already done the full init */
ret = x86_cpu_reinit_f();
#else
ret = arch_cpu_init();
#endif
if (ret) {
debug("%s: arch_cpu_init() failed\n", __func__);
return ret;
@ -142,7 +138,7 @@ void board_init_f_r(void)
u32 spl_boot_device(void)
{
return BOOT_DEVICE_BOARD;
return BOOT_DEVICE_SPI_MMAP;
}
int spl_start_uboot(void)
@ -168,7 +164,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
return 0;
}
SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);
int spl_spi_load_image(void)
{
@ -183,8 +179,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
debug("ret=%d\n", ret);
while (1)
;
hang();
}
#endif

View File

@ -71,7 +71,7 @@ void board_init_f_r(void)
u32 spl_boot_device(void)
{
return IS_ENABLED(CONFIG_CHROMEOS) ? BOOT_DEVICE_CROS_VBOOT :
BOOT_DEVICE_BOARD;
BOOT_DEVICE_SPI_MMAP;
}
int spl_start_uboot(void)
@ -97,7 +97,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
return 0;
}
SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);
int spl_spi_load_image(void)
{
@ -108,8 +108,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
printf("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point);
jump_to_spl(spl_image->entry_point);
while (1)
;
hang();
}
void spl_board_init(void)

View File

@ -5,7 +5,7 @@
*/
#include <common.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
/* ALC262 Verb Table - 10EC0262 */
static const u32 verb_table_data13[] = {

View File

@ -5,7 +5,7 @@
#include <common.h>
#include <asm/arch/gpio.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
static const struct gpio_family gpio_family[] = {
GPIO_FAMILY_CONF("SOUTHEAST_2_hshvfamily_2x3_rcomp_7_0", NA, 0,

View File

@ -11,6 +11,13 @@
#include <command.h>
#include <asm/io.h>
/* Display values from last command */
static ulong last_addr, last_size;
static ulong last_length = 0x40;
static ulong base_address;
#define DISP_LINE_LEN 16
/*
* IO Display
*
@ -19,26 +26,66 @@
*/
int do_io_iod(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
ulong addr;
int size;
ulong addr, length, bytes;
u8 buf[DISP_LINE_LEN];
int size, todo;
if (argc != 2)
/*
* We use the last specified parameters, unless new ones are
* entered.
*/
addr = last_addr;
size = last_size;
length = last_length;
if (argc < 2)
return CMD_RET_USAGE;
size = cmd_get_data_size(argv[0], 4);
if (size < 0)
return 1;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/*
* New command specified. Check for a size specification.
* Defaults to long if no or incorrect specification.
*/
size = cmd_get_data_size(argv[0], 4);
if (size < 0)
return 1;
addr = simple_strtoul(argv[1], NULL, 16);
/* Address is specified since argc > 1 */
addr = simple_strtoul(argv[1], NULL, 16);
addr += base_address;
printf("%04x: ", (u16) addr);
/*
* If another parameter, it is the length to display.
* Length is the number of objects, not number of bytes.
*/
if (argc > 2)
length = simple_strtoul(argv[2], NULL, 16);
}
if (size == 4)
printf("%08x\n", inl(addr));
else if (size == 2)
printf("%04x\n", inw(addr));
else
printf("%02x\n", inb(addr));
bytes = size * length;
/* Print the lines */
for (; bytes > 0; addr += todo) {
u8 *ptr = buf;
int i;
todo = min(bytes, (ulong)DISP_LINE_LEN);
for (i = 0; i < todo; i += size, ptr += size) {
if (size == 4)
*(u32 *)ptr = inl(addr + i);
else if (size == 2)
*(u16 *)ptr = inw(addr + i);
else
*ptr = inb(addr + i);
}
print_buffer(addr, buf, size, todo / size,
DISP_LINE_LEN / size);
bytes -= todo;
}
last_addr = addr;
last_length = length;
last_size = size;
return 0;
}
@ -69,7 +116,7 @@ int do_io_iow(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
}
/**************************************************/
U_BOOT_CMD(iod, 2, 0, do_io_iod,
U_BOOT_CMD(iod, 3, 1, do_io_iod,
"IO space display", "[.b, .w, .l] address");
U_BOOT_CMD(iow, 3, 0, do_io_iow,

View File

@ -5,13 +5,13 @@
#include <common.h>
#include <command.h>
#include <asm/fsp/fsp_support.h>
#include <asm/fsp1/fsp_support.h>
DECLARE_GLOBAL_DATA_PTR;
static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct fsp_header *hdr = find_fsp_header();
struct fsp_header *hdr = fsp_find_header();
u32 img_addr = hdr->img_base;
char *sign = (char *)&hdr->sign;
int i;

View File

@ -26,7 +26,7 @@ config SPL_FRAMEWORK
and the Linux Kernel. If unsure, say Y.
config SPL_SIZE_LIMIT
int "Maximum size of SPL image"
hex "Maximum size of SPL image"
depends on SPL
default 69632 if ARCH_MX6
default 0
@ -115,7 +115,7 @@ if SPL
config SPL_HANDOFF
bool "Pass hand-off information from SPL to U-Boot proper"
depends on HANDOFF
depends on HANDOFF && SPL_BLOBLIST
default y
help
This option enables SPL to write handoff information. This can be
@ -963,7 +963,7 @@ config SPL_SERIAL_SUPPORT
for displaying messages while SPL is running. It also brings in
printf() and panic() functions. This should normally be enabled
unless there are space reasons not to. Even then, consider
enabling USE_TINY_PRINTF which is a small printf() version.
enabling SPL_USE_TINY_PRINTF which is a small printf() version.
config SPL_SPI_FLASH_SUPPORT
bool "Support SPI flash drivers"
@ -1185,7 +1185,7 @@ if TPL
config TPL_HANDOFF
bool "Pass hand-off information from TPL to SPL and U-Boot proper"
depends on HANDOFF
depends on HANDOFF && TPL_BLOBLIST
default y
help
This option enables TPL to write handoff information. This can be

View File

@ -356,17 +356,23 @@ static int setup_spl_handoff(void)
return 0;
}
__weak int handoff_arch_save(struct spl_handoff *ho)
{
return 0;
}
static int write_spl_handoff(void)
{
struct spl_handoff *ho;
int ret;
ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
if (!ho)
return -ENOENT;
handoff_save_dram(ho);
#ifdef CONFIG_SANDBOX
ho->arch.magic = TEST_HANDOFF_MAGIC;
#endif
ret = handoff_arch_save(ho);
if (ret)
return ret;
debug(SPL_TPL_PROMPT "Wrote SPL handoff\n");
return 0;
@ -404,23 +410,6 @@ static int spl_common_init(bool setup_malloc)
return ret;
}
#endif
if (CONFIG_IS_ENABLED(BLOBLIST)) {
ret = bloblist_init();
if (ret) {
debug("%s: Failed to set up bloblist: ret=%d\n",
__func__, ret);
return ret;
}
}
if (CONFIG_IS_ENABLED(HANDOFF)) {
int ret;
ret = setup_spl_handoff();
if (ret) {
puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
hang();
}
}
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
ret = fdtdec_setup();
if (ret) {
@ -598,6 +587,24 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
*/
timer_init();
#endif
if (CONFIG_IS_ENABLED(BLOBLIST)) {
ret = bloblist_init();
if (ret) {
debug("%s: Failed to set up bloblist: ret=%d\n",
__func__, ret);
puts(SPL_TPL_PROMPT "Cannot set up bloblist\n");
hang();
}
}
if (CONFIG_IS_ENABLED(HANDOFF)) {
int ret;
ret = setup_spl_handoff();
if (ret) {
puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
hang();
}
}
#if CONFIG_IS_ENABLED(BOARD_INIT)
spl_board_init();

View File

@ -173,7 +173,7 @@ parse_num (char *s, unsigned long *val, char **es, char *delim)
}
#if defined(DEBUG) && !defined(CONFIG_USE_TINY_PRINTF)
#if defined(DEBUG) && !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
/*
* Note: this debug setup works by storing the strings in a fixed buffer
*/

View File

@ -51,5 +51,5 @@ CONFIG_SPL_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_TPS65910=y
CONFIG_CONS_INDEX=4
# CONFIG_USE_TINY_PRINTF is not set
# CONFIG_SPL_USE_TINY_PRINTF is not set
# CONFIG_EFI_LOADER is not set

View File

@ -4,7 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_ROCKCHIP_RK3288=y
CONFIG_TARGET_EVB_RK3288=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL_SIZE_LIMIT=307200
CONFIG_SPL_SIZE_LIMIT=0x4b000
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xff690000
CONFIG_DEBUG_UART_CLOCK=24000000

View File

@ -67,7 +67,7 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
# CONFIG_USE_TINY_PRINTF is not set
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_RSA=y
CONFIG_SPL_RSA=y
CONFIG_EFI_LOADER_BOUNCE_BUFFER=y

View File

@ -67,5 +67,5 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
# CONFIG_USE_TINY_PRINTF is not set
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_EFI_LOADER_BOUNCE_BUFFER=y

View File

@ -65,7 +65,7 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
# CONFIG_USE_TINY_PRINTF is not set
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_RSA=y
CONFIG_SPL_RSA=y
CONFIG_EFI_LOADER_BOUNCE_BUFFER=y

View File

@ -65,5 +65,5 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
# CONFIG_USE_TINY_PRINTF is not set
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_EFI_LOADER_BOUNCE_BUFFER=y

View File

@ -191,7 +191,7 @@ CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_FS_CBFS=y
CONFIG_FS_CRAMFS=y
# CONFIG_USE_TINY_PRINTF is not set
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_CMD_DHRYSTONE=y
CONFIG_TPM=y
CONFIG_LZ4=y

View File

@ -18,3 +18,4 @@ CONFIG_REGMAP=y
CONFIG_SYSCON=y
# CONFIG_PCI_PNP is not set
CONFIG_CONSOLE_SCROLL_LINES=5
# CONFIG_USE_CAR is not set

View File

@ -5,7 +5,7 @@ CONFIG_SPL_GPIO_SUPPORT=y
CONFIG_ROCKCHIP_RK3288=y
CONFIG_TARGET_TINKER_RK3288=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL_SIZE_LIMIT=307200
CONFIG_SPL_SIZE_LIMIT=0x4b000
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEBUG_UART_BASE=0xff690000
CONFIG_DEBUG_UART_CLOCK=24000000

View File

@ -103,6 +103,8 @@ A device tree binary file can be provided with -d. If you edit the source
(it is stored at arch/sandbox/dts/sandbox.dts) you must rebuild U-Boot to
recreate the binary file.
To use the default device tree, use -D. To use the test device tree, use -T.
To execute commands directly, use the -c option. You can specify a single
command, or multiple commands separated by a semicolon, as is normal in
U-Boot. Be careful with quoting as the shell will normally process and
@ -499,6 +501,13 @@ run natively on your board if desired (and enabled).
To run all tests use "make check".
To run a single test in an existing sandbox build, you can use -T to use the
test device tree, and -c to select the test:
/tmp/b/sandbox/u-boot -T -c "ut dm pci_busdev"
This runs dm_test_pci_busdev() which is in test/dm/pci.c
Memory Map
----------

View File

@ -0,0 +1,62 @@
.. SPDX-License-Identifier: GPL-2.0+
.. sectionauthor:: Simon Glass <sjg@chromium.org>
Debugging driver model
======================
This document aims to provide help when you cannot work out why driver model is
not doing what you expect.
Useful techniques in general
----------------------------
Here are some useful debugging features generally.
- If you are writing a new feature, consider doing it in sandbox instead of
on your board. Sandbox has no limits, allows easy debugging (e.g. gdb) and
you can write emulators for most common devices.
- Put '#define DEBUG' at the top of a file, to activate all the debug() and
log_debug() statements in that file.
- Where logging is used, change the logging level, e.g. in SPL with
CONFIG_SPL_LOG_MAX_LEVEL=7 (which is LOGL_DEBUG) and
CONFIG_LOG_DEFAULT_LEVEL=7
- Where logging of return values is implemented with log_msg_ret(), set
CONFIG_LOG_ERROR_RETURN=y to see exactly where the error is happening
- Make sure you have a debug UART enabled - see CONFIG_DEBUG_UART. With this
you can get serial output (printf(), etc.) before the serial driver is
running.
- Use a JTAG emulator to set breakpoints and single-step through code
Not that most of these increase code/data size somewhat when enabled.
Failure to locate a device
--------------------------
Let's say you have uclass_first_device_err() and it is not finding anything.
If it is returning an error, then that gives you a clue. Look up linux/errno.h
to see errors. Common ones are:
- -ENOMEM which indicates that memory is short. If it happens in SPL or
before relocation in U-Boot, check CONFIG_SPL_SYS_MALLOC_F_LEN and
CONFIG_SYS_MALLOC_F_LEN as they may need to be larger. Add '#define DEBUG'
at the very top of malloc_simple.c to get an idea of where your memory is
going.
- -EINVAL which typically indicates that something was missing or wrong in
the device tree node. Check that everything is correct and look at the
ofdata_to_platdata() method in the driver.
If there is no error, you should check if the device is actually bound. Call
dm_dump_all() just before you locate the device to make sure it exists.
If it does not exist, check your device tree compatible strings match up with
what the driver expects (in the struct udevice_id array).
If you are using of-platdata (e.g. CONFIG_SPL_OF_PLATDATA), check that the
driver name is the same as the first compatible string in the device tree (with
invalid-variable characters converted to underscore).
If you are really stuck, #define DEBUG at the top of lists.c should show you
what is going on.

View File

@ -6,6 +6,7 @@ Driver Model
.. toctree::
:maxdepth: 2
debugging
design
fdt-fixup
fs_firmware_loader

View File

@ -103,7 +103,7 @@ in each of these nodes.
If PCI devices are not listed in the device tree, U_BOOT_PCI_DEVICE can be used
to specify the driver to use for the device. The device tree takes precedence
over U_BOOT_PCI_DEVICE. Plese note with U_BOOT_PCI_DEVICE, only drivers with
over U_BOOT_PCI_DEVICE. Please note with U_BOOT_PCI_DEVICE, only drivers with
DM_FLAG_PRE_RELOC will be bound before relocation. If neither device tree nor
U_BOOT_PCI_DEVICE is provided, the built-in driver (either pci_bridge_drv or
pci_generic_drv) will be used.
@ -113,14 +113,17 @@ Sandbox
-------
With sandbox we need a device emulator for each device on the bus since there
is no real PCI bus. This works by looking in the device tree node for a
driver. For example::
is no real PCI bus. This works by looking in the device tree node for an
emulator driver. For example::
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
emul@1f,0 {
sandbox,emul = <&emul_1f>;
};
pci-emul {
compatible = "sandbox,pci-emul-parent";
emul_1f: emul@1f,0 {
compatible = "sandbox,swap-case";
};
};
@ -130,14 +133,16 @@ Note that the first cell in the 'reg' value is the bus/device/function. See
PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994
PCI bus binding document, v2.1)
The pci-emul node should go outside the pci bus node, since otherwise it will
be scanned as a PCI device, causing confusion.
When this bus is scanned we will end up with something like this::
`- * pci-controller @ 05c660c8, 0
`- pci@1f,0 @ 05c661c8, 63488
`- emul@1f,0 @ 05c662c8
`- emul@1f,0 @ 05c662c8
When accesses go to the pci@1f,0 device they are forwarded to its child, the
emulator.
When accesses go to the pci@1f,0 device they are forwarded to its emulator.
The sandbox PCI drivers also support dynamic driver binding, allowing device
driver to declare the driver binding information via U_BOOT_PCI_DEVICE(),
@ -164,7 +169,3 @@ When this bus is scanned we will end up with something like this::
pci [ + ] pci_sandbo |-- pci-controller1
pci_emul [ ] sandbox_sw | |-- sandbox_swap_case_emul
pci_emul [ ] sandbox_sw | `-- sandbox_swap_case_emul
Note the difference from the statically declared device nodes is that the
device is directly attached to the host controller, instead of via a container
device like pci@1f,0.

View File

@ -142,9 +142,9 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
*/
struct blk_desc *blk_get_by_device(struct udevice *dev)
{
struct udevice *child_dev, *next;
struct udevice *child_dev;
device_foreach_child_safe(child_dev, next, dev) {
device_foreach_child(child_dev, dev) {
if (device_get_uclass_id(child_dev) != UCLASS_BLK)
continue;

View File

@ -404,7 +404,8 @@ int device_probe(struct udevice *dev)
goto fail;
}
if (drv->ofdata_to_platdata && dev_has_of_node(dev)) {
if (drv->ofdata_to_platdata &&
(CONFIG_IS_ENABLED(OF_PLATDATA) || dev_has_of_node(dev))) {
ret = drv->ofdata_to_platdata(dev);
if (ret)
goto fail;

Some files were not shown because too many files have changed in this diff Show More