[U-Boot] [PATCH v3 0/27] x86: Add Intel Queensbay platform support

This patch series add the Intel Queensbay platform support. The Queensbay platform includes an Atom E6xx processor (codename Tunnel Creek) and a Platform Controller Hub EG20T (codename Topcliff). The support depends on Intel Firmware Support Package (FSP) to initialize the processor and chipset including system memory. With this patch series, U-Boot boots to Linux kernel. Validated on an Intel Crown Bay board with kernel 3.17.
Changes in v3: - Apply U-Boot coding conventions to typedefs in FSP codes - Use jnz to jump to the car_init error code at the end of tnc_car.S file instead of being in the normal path flow - Add a TODO comment block to document the fsp_init() call - Change label xxx_stack to xxx_romstack in tnc_car.S - Add a comment block to explain the ROM stack - Add a commit message for the SPI support
Changes in v2: - tools/ifdtool: Change WRITE_NUM to WRITE_MAX - tools/ifdtool: Remove the unnecessary initialiser of addr and wr_fname - Move setup_pch_gpios() to board support codes instead of making it a weak function - Add a comment to describe PNP_DEV - Change pnp device inline routine parameters to use proper size - Apply U-Boot coding convention to the FSP support codes - Update the codes to use U-Boot coding style - Move FspInit call from start.S to car_init - Use ARRAY_SIZE to indicate the maximum number of HOB tyeps - Remove some unnecessary spaces in the do_hob command output - Replace 0xcf9 with macro PORT_RESET from processor.h - Move FspInit call from start.S to car_init - Add UART0_BASE and UART1_BASE to ibmpc.h - Add a comment to explain we don't need check bit0 in GPIO base address register - Add setup_pch_gpios() in crownbay.c - Fix several typos in queensbay/Kconfig - Change FSP_FILE and CMC_FILE description to indicate the file is in the board directory - Add help for FSP_TEMP_RAM_ADDR - Add more help for CMC_FILE - New patch to use consistent name XXX_ADDR for binary blobs - Update ifdtool flags to indicate FSP and CMC files are in the board directory - Use consistent XXX_FILE name for binary blob file - Move PCH_LPC_DEV to arch/x86/include/asm/arch-queensbay/tnc.h - Check return value of x86_cpu_init_f() - Use ARRAY_SIZE(mmc_supported) instead of 2 - Check return value of add_sdhci() - New patch to rename coreboot-serial to x86-serial - Remove the 'make menuconfig' in the crownbay build instructions - Indicate all the binary blobs should be put in the board directory
Bin Meng (27): x86: Make ROM_SIZE configurable in Kconfig tools/ifdtool: Support writing multiple files (-w) simultaneously x86: Refactor u-boot.rom build rules x86: Clean up asm-offsets x86: ich6-gpio: Move setup_pch_gpios() to board support codes x86: Add Intel Crown Bay board dts file x86: Add a simple superio driver for SMSC LPC47M x86: Add Intel Topcliff PCH device IDs x86: ich-spi: Add Intel Tunnel Creek SPI controller support x86: Initial import from Intel FSP release for Queensbay platform x86: queensbay: Adapt FSP support codes x86: Add post failure codes for bist and car x86: Support Intel FSP initialization path in start.S x86: Add a simple command to show FSP HOB information x86: Integrate Tunnel Creek processor microcode x86: Add basic support to queensbay platform and crownbay board x86: ich6-gpio: Add Intel Tunnel Creek GPIO support x86: Enable the queensbay cpu directory build x86: Add queensbay and crownbay Kconfig files x86: Add crownbay defconfig and config.h x86: Use consistent name XXX_ADDR for binary blob flash address x86: Include FSP and CMC binary in the u-boot.rom build rules x86: crownbay: Add SPI flash support x86: crownbay: Enable Intel E1000 NIC support x86: crownbay: Add SDHCI support x86: Rename coreboot-serial to x86-serial x86: Add a README.x86 for U-Boot on x86 support
Makefile | 56 +- arch/x86/Kconfig | 91 +- arch/x86/cpu/Makefile | 1 + arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/cpu/ivybridge/sdram.c | 2 +- arch/x86/cpu/queensbay/Kconfig | 79 ++ arch/x86/cpu/queensbay/M0220661105.inc | 1288 ++++++++++++++++++++ arch/x86/cpu/queensbay/Makefile | 9 + arch/x86/cpu/queensbay/fsp_configs.c | 20 + arch/x86/cpu/queensbay/fsp_support.c | 416 +++++++ arch/x86/cpu/queensbay/tnc.c | 72 ++ arch/x86/cpu/queensbay/tnc_car.S | 127 ++ arch/x86/cpu/queensbay/tnc_dram.c | 78 ++ arch/x86/cpu/queensbay/tnc_pci.c | 61 + arch/x86/cpu/queensbay/topcliff.c | 47 + arch/x86/cpu/start.S | 17 +- arch/x86/dts/Makefile | 3 +- arch/x86/dts/coreboot.dtsi | 2 +- arch/x86/dts/crownbay.dts | 53 + arch/x86/include/asm/arch-coreboot/gpio.h | 3 + arch/x86/include/asm/arch-ivybridge/gpio.h | 3 + arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h | 59 + .../include/asm/arch-queensbay/fsp/fsp_bootmode.h | 24 + arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h | 158 +++ arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h | 137 +++ arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h | 310 +++++ .../asm/arch-queensbay/fsp/fsp_infoheader.h | 36 + .../include/asm/arch-queensbay/fsp/fsp_platform.h | 19 + .../include/asm/arch-queensbay/fsp/fsp_support.h | 198 +++ .../x86/include/asm/arch-queensbay/fsp/fsp_types.h | 97 ++ arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h | 58 + arch/x86/include/asm/arch-queensbay/gpio.h | 13 + arch/x86/include/asm/arch-queensbay/tnc.h | 15 + arch/x86/include/asm/global_data.h | 3 + arch/x86/include/asm/gpio.h | 3 +- arch/x86/include/asm/ibmpc.h | 3 + arch/x86/include/asm/pnp_def.h | 90 ++ arch/x86/include/asm/post.h | 2 + arch/x86/lib/Makefile | 1 + arch/x86/lib/asm-offsets.c | 5 +- arch/x86/lib/cmd_hob.c | 67 + board/coreboot/coreboot/coreboot.c | 6 + board/google/chromebook_link/Kconfig | 1 + board/google/chromebook_link/link.c | 40 + board/intel/crownbay/Kconfig | 20 + board/intel/crownbay/MAINTAINERS | 6 + board/intel/crownbay/Makefile | 7 + board/intel/crownbay/crownbay.c | 32 + board/intel/crownbay/start.S | 9 + configs/crownbay_defconfig | 6 + doc/README.x86 | 126 ++ drivers/gpio/intel_ich6_gpio.c | 73 +- drivers/misc/Makefile | 1 + drivers/misc/smsc_lpc47m.c | 33 + drivers/serial/Makefile | 2 +- drivers/serial/{serial_coreboot.c => serial_x86.c} | 12 +- drivers/spi/ich.c | 3 +- include/configs/chromebook_link.h | 6 +- include/configs/coreboot.h | 2 +- include/configs/crownbay.h | 61 + include/pci_ids.h | 8 + include/smsc_lpc47m.h | 19 + lib/asm-offsets.c | 3 - tools/ifdtool.c | 31 +- tools/ifdtool.h | 2 + 65 files changed, 4127 insertions(+), 109 deletions(-) create mode 100644 arch/x86/cpu/queensbay/Kconfig create mode 100644 arch/x86/cpu/queensbay/M0220661105.inc create mode 100644 arch/x86/cpu/queensbay/Makefile create mode 100644 arch/x86/cpu/queensbay/fsp_configs.c create mode 100644 arch/x86/cpu/queensbay/fsp_support.c create mode 100644 arch/x86/cpu/queensbay/tnc.c create mode 100644 arch/x86/cpu/queensbay/tnc_car.S create mode 100644 arch/x86/cpu/queensbay/tnc_dram.c create mode 100644 arch/x86/cpu/queensbay/tnc_pci.c create mode 100644 arch/x86/cpu/queensbay/topcliff.c create mode 100644 arch/x86/dts/crownbay.dts create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h create mode 100644 arch/x86/include/asm/arch-queensbay/gpio.h create mode 100644 arch/x86/include/asm/arch-queensbay/tnc.h create mode 100644 arch/x86/include/asm/pnp_def.h create mode 100644 arch/x86/lib/cmd_hob.c create mode 100644 board/intel/crownbay/Kconfig create mode 100644 board/intel/crownbay/MAINTAINERS create mode 100644 board/intel/crownbay/Makefile create mode 100644 board/intel/crownbay/crownbay.c create mode 100644 board/intel/crownbay/start.S create mode 100644 configs/crownbay_defconfig create mode 100644 doc/README.x86 create mode 100644 drivers/misc/smsc_lpc47m.c rename drivers/serial/{serial_coreboot.c => serial_x86.c} (67%) create mode 100644 include/configs/crownbay.h create mode 100644 include/smsc_lpc47m.h

Currently the ROM_SIZE is hardcoded to 8MB in arch/x86/Kconfig. This will not be the case when adding additional board support. Hence we make ROM_SIZE configurable (512KB/1MB/2MB/4MB/8MB/16MB) and have the board Kconfig file select the default ROM_SIZE.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/Kconfig | 78 +++++++++++++++++++++++++++++++++++- board/google/chromebook_link/Kconfig | 1 + 2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4f5ce38..fdfb618 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -61,9 +61,85 @@ config SMM_TSEG config SMM_TSEG_SIZE hex
+config BOARD_ROMSIZE_KB_512 + bool +config BOARD_ROMSIZE_KB_1024 + bool +config BOARD_ROMSIZE_KB_2048 + bool +config BOARD_ROMSIZE_KB_4096 + bool +config BOARD_ROMSIZE_KB_8192 + bool +config BOARD_ROMSIZE_KB_16384 + bool + +choice + prompt "ROM chip size" + default UBOOT_ROMSIZE_KB_512 if BOARD_ROMSIZE_KB_512 + default UBOOT_ROMSIZE_KB_1024 if BOARD_ROMSIZE_KB_1024 + default UBOOT_ROMSIZE_KB_2048 if BOARD_ROMSIZE_KB_2048 + default UBOOT_ROMSIZE_KB_4096 if BOARD_ROMSIZE_KB_4096 + default UBOOT_ROMSIZE_KB_8192 if BOARD_ROMSIZE_KB_8192 + default UBOOT_ROMSIZE_KB_16384 if BOARD_ROMSIZE_KB_16384 + help + Select the size of the ROM chip you intend to flash U-Boot on. + + The build system will take care of creating a u-boot.rom file + of the matching size. + +config UBOOT_ROMSIZE_KB_512 + bool "512 KB" + help + Choose this option if you have a 512 KB ROM chip. + +config UBOOT_ROMSIZE_KB_1024 + bool "1024 KB (1 MB)" + help + Choose this option if you have a 1024 KB (1 MB) ROM chip. + +config UBOOT_ROMSIZE_KB_2048 + bool "2048 KB (2 MB)" + help + Choose this option if you have a 2048 KB (2 MB) ROM chip. + +config UBOOT_ROMSIZE_KB_4096 + bool "4096 KB (4 MB)" + help + Choose this option if you have a 4096 KB (4 MB) ROM chip. + +config UBOOT_ROMSIZE_KB_8192 + bool "8192 KB (8 MB)" + help + Choose this option if you have a 8192 KB (8 MB) ROM chip. + +config UBOOT_ROMSIZE_KB_16384 + bool "16384 KB (16 MB)" + help + Choose this option if you have a 16384 KB (16 MB) ROM chip. + +endchoice + +# Map the config names to an integer (KB). +config UBOOT_ROMSIZE_KB + int + default 512 if UBOOT_ROMSIZE_KB_512 + default 1024 if UBOOT_ROMSIZE_KB_1024 + default 2048 if UBOOT_ROMSIZE_KB_2048 + default 4096 if UBOOT_ROMSIZE_KB_4096 + default 8192 if UBOOT_ROMSIZE_KB_8192 + default 16384 if UBOOT_ROMSIZE_KB_16384 + +# Map the config names to a hex value (bytes). config ROM_SIZE hex - default 0x800000 + default 0x80000 if UBOOT_ROMSIZE_KB_512 + default 0x100000 if UBOOT_ROMSIZE_KB_1024 + default 0x200000 if UBOOT_ROMSIZE_KB_2048 + default 0x400000 if UBOOT_ROMSIZE_KB_4096 + default 0x800000 if UBOOT_ROMSIZE_KB_8192 + default 0xc00000 if UBOOT_ROMSIZE_KB_12288 + default 0x1000000 if UBOOT_ROMSIZE_KB_16384
config HAVE_INTEL_ME bool "Platform requires Intel Management Engine" diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig index 3a4f557..7f79fd2 100644 --- a/board/google/chromebook_link/Kconfig +++ b/board/google/chromebook_link/Kconfig @@ -19,6 +19,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SOUTHBRIDGE_INTEL_C216 select HAVE_ACPI_RESUME select MARK_GRAPHICS_MEM_WRCOMB + select BOARD_ROMSIZE_KB_8192
config MMCONF_BASE_ADDRESS hex

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Currently the ROM_SIZE is hardcoded to 8MB in arch/x86/Kconfig. This will not be the case when adding additional board support. Hence we make ROM_SIZE configurable (512KB/1MB/2MB/4MB/8MB/16MB) and have the board Kconfig file select the default ROM_SIZE.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/Kconfig | 78 +++++++++++++++++++++++++++++++++++- board/google/chromebook_link/Kconfig | 1 + 2 files changed, 78 insertions(+), 1 deletion(-)
Applied to u-boot-x86, thanks!

Currently ifdtool only supports writing one file (-w) at a time. This looks verbose when generating u-boot.rom for x86 targets. This change allows at most 16 files to be written simultaneously.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - tools/ifdtool: Change WRITE_NUM to WRITE_MAX - tools/ifdtool: Remove the unnecessary initialiser of addr and wr_fname
tools/ifdtool.c | 31 ++++++++++++++++++++++++------- tools/ifdtool.h | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/tools/ifdtool.c b/tools/ifdtool.c index a4b481f..f81e5c8 100644 --- a/tools/ifdtool.c +++ b/tools/ifdtool.c @@ -732,6 +732,7 @@ static void print_usage(const char *name) " -x | --extract: extract intel fd modules\n" " -i | --inject <region>:<module> inject file <module> into region <region>\n" " -w | --write <addr>:<file> write file to appear at memory address <addr>\n" + " multiple files can be written simultaneously\n" " -s | --spifreq <20|33|50> set the SPI frequency\n" " -e | --em100 set SPI frequency to 20MHz and disable\n" " Dual Output Fast Read Support\n" @@ -782,7 +783,9 @@ int main(int argc, char *argv[]) char *addr_str = NULL; int region_type = -1, inputfreq = 0; enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ; - unsigned int addr = 0; + unsigned int addr[WRITE_MAX]; + char *wr_fname[WRITE_MAX]; + unsigned char wr_idx, wr_num = 0; int rom_size = -1; bool write_it; char *filename; @@ -886,11 +889,19 @@ int main(int argc, char *argv[]) break; case 'w': mode_write = 1; - if (get_two_words(optarg, &addr_str, &src_fname)) { - print_usage(argv[0]); - exit(EXIT_FAILURE); + if (wr_num < WRITE_MAX) { + if (get_two_words(optarg, &addr_str, + &wr_fname[wr_num])) { + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + addr[wr_num] = strtol(optarg, NULL, 0); + wr_num++; + } else { + fprintf(stderr, + "The number of files to write simultaneously exceeds the limitation (%d)\n", + WRITE_MAX); } - addr = strtol(optarg, NULL, 0); break; case 'x': mode_extract = 1; @@ -1002,8 +1013,14 @@ int main(int argc, char *argv[]) if (mode_inject) ret = inject_region(image, size, region_type, src_fname);
- if (mode_write) - ret = write_data(image, size, addr, src_fname); + if (mode_write) { + for (wr_idx = 0; wr_idx < wr_num; wr_idx++) { + ret = write_data(image, size, + addr[wr_idx], wr_fname[wr_idx]); + if (ret) + break; + } + }
if (mode_spifreq) set_spi_frequency(image, size, spifreq); diff --git a/tools/ifdtool.h b/tools/ifdtool.h index fbec421..0d0cc36 100644 --- a/tools/ifdtool.h +++ b/tools/ifdtool.h @@ -14,6 +14,8 @@
#define IFDTOOL_VERSION "1.1-U-Boot"
+#define WRITE_MAX 16 + enum spi_frequency { SPI_FREQUENCY_20MHZ = 0, SPI_FREQUENCY_33MHZ = 1,

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Currently ifdtool only supports writing one file (-w) at a time. This looks verbose when generating u-boot.rom for x86 targets. This change allows at most 16 files to be written simultaneously.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- tools/ifdtool: Change WRITE_NUM to WRITE_MAX
- tools/ifdtool: Remove the unnecessary initialiser of addr and wr_fname
tools/ifdtool.c | 31 ++++++++++++++++++++++++------- tools/ifdtool.h | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-)
Applied to u-boot-x86, thanks!

Refactor u-boot.rom build rules by utilizing quiet_cmd_ and cmd_ macros. Also make writing mrc.bin and pci option rom to u-boot.rom optional and remove mrc.bin from its dependent file list as not every x86 board port needs mrc binary blob.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
Makefile | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/Makefile b/Makefile index 44d468e..c9ae77b 100644 --- a/Makefile +++ b/Makefile @@ -963,27 +963,33 @@ u-boot-nand.gph: u-boot.bin FORCE ifneq ($(CONFIG_X86_RESET_VECTOR),) rom: u-boot.rom FORCE
-u-boot.rom: u-boot-x86-16bit.bin u-boot-dtb.bin \ - $(srctree)/board/$(BOARDDIR)/mrc.bin - $(objtree)/tools/ifdtool -c -r $(CONFIG_ROM_SIZE) u-boot.tmp - if [ -n "$(CONFIG_HAVE_INTEL_ME)" ]; then \ - $(objtree)/tools/ifdtool -D \ - $(srctree)/board/$(BOARDDIR)/descriptor.bin u-boot.tmp; \ - $(objtree)/tools/ifdtool \ - -i ME:$(srctree)/board/$(BOARDDIR)/me.bin u-boot.tmp; \ - fi - $(objtree)/tools/ifdtool -w \ - $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot-dtb.bin u-boot.tmp - $(objtree)/tools/ifdtool -w \ - $(CONFIG_X86_MRC_START):$(srctree)/board/$(BOARDDIR)/mrc.bin \ - u-boot.tmp - $(objtree)/tools/ifdtool -w \ - $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin \ - u-boot.tmp - $(objtree)/tools/ifdtool -w \ - $(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILENAME) \ - u-boot.tmp - mv u-boot.tmp $@ +IFDTOOL=$(objtree)/tools/ifdtool +IFDTOOL_FLAGS = -w $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot-dtb.bin +IFDTOOL_FLAGS += -w $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin + +ifneq ($(CONFIG_HAVE_INTEL_ME),) +IFDTOOL_ME_FLAGS = -D $(srctree)/board/$(BOARDDIR)/descriptor.bin +IFDTOOL_ME_FLAGS += -i ME:$(srctree)/board/$(BOARDDIR)/me.bin +endif + +ifneq ($(CONFIG_HAVE_MRC),) +IFDTOOL_FLAGS += -w $(CONFIG_X86_MRC_START):$(srctree)/board/$(BOARDDIR)/mrc.bin +endif + +ifneq ($(CONFIG_X86_OPTION_ROM_ADDR),) +IFDTOOL_FLAGS += -w $(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILENAME) +endif + +quiet_cmd_ifdtool = IFDTOOL $@ +cmd_ifdtool = $(IFDTOOL) -c -r $(CONFIG_ROM_SIZE) u-boot.tmp; +ifneq ($(CONFIG_HAVE_INTEL_ME),) +cmd_ifdtool += $(IFDTOOL) $(IFDTOOL_ME_FLAGS) u-boot.tmp; +endif +cmd_ifdtool += $(IFDTOOL) $(IFDTOOL_FLAGS) u-boot.tmp; +cmd_ifdtool += mv u-boot.tmp $@ + +u-boot.rom: u-boot-x86-16bit.bin u-boot-dtb.bin + $(call if_changed,ifdtool)
OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec u-boot-x86-16bit.bin: u-boot FORCE

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Refactor u-boot.rom build rules by utilizing quiet_cmd_ and cmd_ macros. Also make writing mrc.bin and pci option rom to u-boot.rom optional and remove mrc.bin from its dependent file list as not every x86 board port needs mrc binary blob.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
Makefile | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-)
Applied to u-boot-x86, thanks!

Move GD_BIST from lib/asm-offsets.c to arch/x86/lib/asm-offsets.c as it is x86 arch specific stuff. Also remove GENERATED_GD_RELOC_OFF which is not referenced anymore.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/cpu/start.S | 3 ++- arch/x86/lib/asm-offsets.c | 2 +- lib/asm-offsets.c | 3 --- 3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index b0d0ac0..f9662fb 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -1,5 +1,5 @@ /* - * U-boot - x86 Startup Code + * U-Boot - x86 Startup Code * * (C) Copyright 2008-2011 * Graeme Russ, graeme.russ@gmail.com @@ -17,6 +17,7 @@ #include <asm/processor.h> #include <asm/processor-flags.h> #include <generated/generic-asm-offsets.h> +#include <generated/asm-offsets.h>
.section .text .code32 diff --git a/arch/x86/lib/asm-offsets.c b/arch/x86/lib/asm-offsets.c index d65c6ab..50a488f 100644 --- a/arch/x86/lib/asm-offsets.c +++ b/arch/x86/lib/asm-offsets.c @@ -17,6 +17,6 @@
int main(void) { - DEFINE(GENERATED_GD_RELOC_OFF, offsetof(gd_t, reloc_off)); + DEFINE(GD_BIST, offsetof(gd_t, arch.bist)); return 0; } diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c index 580f763..129bc3e 100644 --- a/lib/asm-offsets.c +++ b/lib/asm-offsets.c @@ -31,9 +31,6 @@ int main(void) #ifdef CONFIG_SYS_MALLOC_F_LEN DEFINE(GD_MALLOC_BASE, offsetof(struct global_data, malloc_base)); #endif -#ifdef CONFIG_X86 - DEFINE(GD_BIST, offsetof(struct global_data, arch.bist)); -#endif
#if defined(CONFIG_ARM)

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Move GD_BIST from lib/asm-offsets.c to arch/x86/lib/asm-offsets.c as it is x86 arch specific stuff. Also remove GENERATED_GD_RELOC_OFF which is not referenced anymore.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/cpu/start.S | 3 ++- arch/x86/lib/asm-offsets.c | 2 +- lib/asm-offsets.c | 3 --- 3 files changed, 3 insertions(+), 5 deletions(-)
Applied to u-boot-x86, thanks!

Movie setup_pch_gpios() in the ich6-gpio driver to the board support codes, so that the driver does not need to know any platform specific stuff (ie: include the platform specifc chipset header file).
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Move setup_pch_gpios() to board support codes instead of making it a weak function
arch/x86/include/asm/arch-coreboot/gpio.h | 3 ++ arch/x86/include/asm/arch-ivybridge/gpio.h | 3 ++ arch/x86/include/asm/gpio.h | 1 + board/coreboot/coreboot/coreboot.c | 6 ++++ board/google/chromebook_link/link.c | 40 ++++++++++++++++++++++ drivers/gpio/intel_ich6_gpio.c | 53 ++---------------------------- 6 files changed, 55 insertions(+), 51 deletions(-)
diff --git a/arch/x86/include/asm/arch-coreboot/gpio.h b/arch/x86/include/asm/arch-coreboot/gpio.h index 4951a8c..31edef9 100644 --- a/arch/x86/include/asm/arch-coreboot/gpio.h +++ b/arch/x86/include/asm/arch-coreboot/gpio.h @@ -7,4 +7,7 @@ #ifndef _X86_ARCH_GPIO_H_ #define _X86_ARCH_GPIO_H_
+/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x48 + #endif /* _X86_ARCH_GPIO_H_ */ diff --git a/arch/x86/include/asm/arch-ivybridge/gpio.h b/arch/x86/include/asm/arch-ivybridge/gpio.h index 4951a8c..31edef9 100644 --- a/arch/x86/include/asm/arch-ivybridge/gpio.h +++ b/arch/x86/include/asm/arch-ivybridge/gpio.h @@ -7,4 +7,7 @@ #ifndef _X86_ARCH_GPIO_H_ #define _X86_ARCH_GPIO_H_
+/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x48 + #endif /* _X86_ARCH_GPIO_H_ */ diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h index 5540d42..1787e52 100644 --- a/arch/x86/include/asm/gpio.h +++ b/arch/x86/include/asm/gpio.h @@ -147,6 +147,7 @@ struct pch_gpio_map { } set3; };
+void setup_pch_gpios(u32 gpiobase, const struct pch_gpio_map *gpio); void ich_gpio_set_gpio_map(const struct pch_gpio_map *map);
#endif /* _X86_GPIO_H_ */ diff --git a/board/coreboot/coreboot/coreboot.c b/board/coreboot/coreboot/coreboot.c index 0240c34..b260f9a 100644 --- a/board/coreboot/coreboot/coreboot.c +++ b/board/coreboot/coreboot/coreboot.c @@ -6,6 +6,7 @@
#include <common.h> #include <cros_ec.h> +#include <asm/gpio.h>
int arch_early_init_r(void) { @@ -14,3 +15,8 @@ int arch_early_init_r(void)
return 0; } + +void setup_pch_gpios(u32 gpiobase, const struct pch_gpio_map *gpio) +{ + return; +} diff --git a/board/google/chromebook_link/link.c b/board/google/chromebook_link/link.c index 1822237..4d95c1c 100644 --- a/board/google/chromebook_link/link.c +++ b/board/google/chromebook_link/link.c @@ -7,6 +7,9 @@ #include <common.h> #include <cros_ec.h> #include <asm/gpio.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/arch/pch.h>
int arch_early_init_r(void) { @@ -121,3 +124,40 @@ int board_early_init_f(void)
return 0; } + +void setup_pch_gpios(u32 gpiobase, const struct pch_gpio_map *gpio) +{ + /* GPIO Set 1 */ + if (gpio->set1.level) + outl(*((u32 *)gpio->set1.level), gpiobase + GP_LVL); + if (gpio->set1.mode) + outl(*((u32 *)gpio->set1.mode), gpiobase + GPIO_USE_SEL); + if (gpio->set1.direction) + outl(*((u32 *)gpio->set1.direction), gpiobase + GP_IO_SEL); + if (gpio->set1.reset) + outl(*((u32 *)gpio->set1.reset), gpiobase + GP_RST_SEL1); + if (gpio->set1.invert) + outl(*((u32 *)gpio->set1.invert), gpiobase + GPI_INV); + if (gpio->set1.blink) + outl(*((u32 *)gpio->set1.blink), gpiobase + GPO_BLINK); + + /* GPIO Set 2 */ + if (gpio->set2.level) + outl(*((u32 *)gpio->set2.level), gpiobase + GP_LVL2); + if (gpio->set2.mode) + outl(*((u32 *)gpio->set2.mode), gpiobase + GPIO_USE_SEL2); + if (gpio->set2.direction) + outl(*((u32 *)gpio->set2.direction), gpiobase + GP_IO_SEL2); + if (gpio->set2.reset) + outl(*((u32 *)gpio->set2.reset), gpiobase + GP_RST_SEL2); + + /* GPIO Set 3 */ + if (gpio->set3.level) + outl(*((u32 *)gpio->set3.level), gpiobase + GP_LVL3); + if (gpio->set3.mode) + outl(*((u32 *)gpio->set3.mode), gpiobase + GPIO_USE_SEL3); + if (gpio->set3.direction) + outl(*((u32 *)gpio->set3.direction), gpiobase + GP_IO_SEL3); + if (gpio->set3.reset) + outl(*((u32 *)gpio->set3.reset), gpiobase + GP_RST_SEL3); +} diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c index b095d17..1f0d9df 100644 --- a/drivers/gpio/intel_ich6_gpio.c +++ b/drivers/gpio/intel_ich6_gpio.c @@ -34,16 +34,9 @@ #include <asm/gpio.h> #include <asm/io.h> #include <asm/pci.h> -#ifdef CONFIG_X86_RESET_VECTOR -#include <asm/arch/pch.h> -#define SUPPORT_GPIO_SETUP -#endif
#define GPIO_PER_BANK 32
-/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x48 - struct ich6_bank_priv { /* These are I/O addresses */ uint32_t use_sel; @@ -51,52 +44,11 @@ struct ich6_bank_priv { uint32_t lvl; };
-#ifdef SUPPORT_GPIO_SETUP -static void setup_pch_gpios(const struct pch_gpio_map *gpio) -{ - u16 gpiobase = pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc; - - /* GPIO Set 1 */ - if (gpio->set1.level) - outl(*((u32 *)gpio->set1.level), gpiobase + GP_LVL); - if (gpio->set1.mode) - outl(*((u32 *)gpio->set1.mode), gpiobase + GPIO_USE_SEL); - if (gpio->set1.direction) - outl(*((u32 *)gpio->set1.direction), gpiobase + GP_IO_SEL); - if (gpio->set1.reset) - outl(*((u32 *)gpio->set1.reset), gpiobase + GP_RST_SEL1); - if (gpio->set1.invert) - outl(*((u32 *)gpio->set1.invert), gpiobase + GPI_INV); - if (gpio->set1.blink) - outl(*((u32 *)gpio->set1.blink), gpiobase + GPO_BLINK); - - /* GPIO Set 2 */ - if (gpio->set2.level) - outl(*((u32 *)gpio->set2.level), gpiobase + GP_LVL2); - if (gpio->set2.mode) - outl(*((u32 *)gpio->set2.mode), gpiobase + GPIO_USE_SEL2); - if (gpio->set2.direction) - outl(*((u32 *)gpio->set2.direction), gpiobase + GP_IO_SEL2); - if (gpio->set2.reset) - outl(*((u32 *)gpio->set2.reset), gpiobase + GP_RST_SEL2); - - /* GPIO Set 3 */ - if (gpio->set3.level) - outl(*((u32 *)gpio->set3.level), gpiobase + GP_LVL3); - if (gpio->set3.mode) - outl(*((u32 *)gpio->set3.mode), gpiobase + GPIO_USE_SEL3); - if (gpio->set3.direction) - outl(*((u32 *)gpio->set3.direction), gpiobase + GP_IO_SEL3); - if (gpio->set3.reset) - outl(*((u32 *)gpio->set3.reset), gpiobase + GP_RST_SEL3); -} - /* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map(const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -#endif /* SUPPORT_GPIO_SETUP */
static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) { @@ -198,12 +150,11 @@ static int ich6_gpio_probe(struct udevice *dev) struct gpio_dev_priv *uc_priv = dev->uclass_priv; struct ich6_bank_priv *bank = dev_get_priv(dev);
-#ifdef SUPPORT_GPIO_SETUP if (gd->arch.gpio_map) { - setup_pch_gpios(gd->arch.gpio_map); + setup_pch_gpios(plat->base_addr, gd->arch.gpio_map); gd->arch.gpio_map = NULL; } -#endif + uc_priv->gpio_count = GPIO_PER_BANK; uc_priv->bank_name = plat->bank_name; bank->use_sel = plat->base_addr;

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Movie setup_pch_gpios() in the ich6-gpio driver to the board support codes, so that the driver does not need to know any platform specific stuff (ie: include the platform specifc chipset header file).
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Move setup_pch_gpios() to board support codes instead of making it a weak function
arch/x86/include/asm/arch-coreboot/gpio.h | 3 ++ arch/x86/include/asm/arch-ivybridge/gpio.h | 3 ++ arch/x86/include/asm/gpio.h | 1 + board/coreboot/coreboot/coreboot.c | 6 ++++ board/google/chromebook_link/link.c | 40 ++++++++++++++++++++++ drivers/gpio/intel_ich6_gpio.c | 53 ++---------------------------- 6 files changed, 55 insertions(+), 51 deletions(-)
Applied to u-boot-x86, thanks!

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/dts/Makefile | 3 ++- arch/x86/dts/crownbay.dts | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 arch/x86/dts/crownbay.dts
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index bb3b116..3b5d6da 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -1,6 +1,7 @@ dtb-y += link.dtb \ chromebook_link.dtb \ - alex.dtb + alex.dtb \ + crownbay.dtb
targets += $(dtb-y)
diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts new file mode 100644 index 0000000..399dafb --- /dev/null +++ b/arch/x86/dts/crownbay.dts @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/include/ "coreboot.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "Intel Crown Bay"; + compatible = "intel,crownbay", "intel,queensbay"; + + config { + silent_console = <0>; + }; + + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + serial { + reg = <0x3f8 8>; + clock-frequency = <115200>; + }; + + chosen { }; + memory { device_type = "memory"; reg = <0 0>; }; + + spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich7"; + spi-flash@0 { + reg = <0>; + compatible = "sst,25vf016b", "spi-flash"; + memory-map = <0xffe00000 0x00200000>; + }; + }; +};

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/dts/Makefile | 3 ++- arch/x86/dts/crownbay.dts | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 arch/x86/dts/crownbay.dts
Applied to u-boot-x86, thanks!

On most x86 boards, the legacy serial ports (io address 0x3f8/0x2f8) are provided by a superio chip connected to the LPC bus. We must program the superio chip so that serial ports are available for us.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Add a comment to describe PNP_DEV - Change pnp device inline routine parameters to use proper size
arch/x86/include/asm/pnp_def.h | 90 ++++++++++++++++++++++++++++++++++++++++++ drivers/misc/Makefile | 1 + drivers/misc/smsc_lpc47m.c | 33 ++++++++++++++++ include/smsc_lpc47m.h | 19 +++++++++ 4 files changed, 143 insertions(+) create mode 100644 arch/x86/include/asm/pnp_def.h create mode 100644 drivers/misc/smsc_lpc47m.c create mode 100644 include/smsc_lpc47m.h
diff --git a/arch/x86/include/asm/pnp_def.h b/arch/x86/include/asm/pnp_def.h new file mode 100644 index 0000000..24b038d --- /dev/null +++ b/arch/x86/include/asm/pnp_def.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * Adapted from coreboot src/include/device/pnp_def.h + * and arch/x86/include/arch/io.h + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_PNP_DEF_H_ +#define _ASM_PNP_DEF_H_ + +#include <asm/io.h> + +#define PNP_IDX_EN 0x30 +#define PNP_IDX_IO0 0x60 +#define PNP_IDX_IO1 0x62 +#define PNP_IDX_IO2 0x64 +#define PNP_IDX_IO3 0x66 +#define PNP_IDX_IRQ0 0x70 +#define PNP_IDX_IRQ1 0x72 +#define PNP_IDX_DRQ0 0x74 +#define PNP_IDX_DRQ1 0x75 +#define PNP_IDX_MSC0 0xf0 +#define PNP_IDX_MSC1 0xf1 + +/* Generic functions for pnp devices */ + +/* + * pnp device is a 16-bit integer composed of its i/o port address at high byte + * and logic function number at low byte. + */ +#define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC)) + +static inline void pnp_write_config(uint16_t dev, uint8_t reg, uint8_t value) +{ + uint8_t port = dev >> 8; + + outb(reg, port); + outb(value, port + 1); +} + +static inline uint8_t pnp_read_config(uint16_t dev, uint8_t reg) +{ + uint8_t port = dev >> 8; + + outb(reg, port); + return inb(port + 1); +} + +static inline void pnp_set_logical_device(uint16_t dev) +{ + uint8_t device = dev & 0xff; + + pnp_write_config(dev, 0x07, device); +} + +static inline void pnp_set_enable(uint16_t dev, int enable) +{ + pnp_write_config(dev, PNP_IDX_EN, enable ? 1 : 0); +} + +static inline int pnp_read_enable(uint16_t dev) +{ + return !!pnp_read_config(dev, PNP_IDX_EN); +} + +static inline void pnp_set_iobase(uint16_t dev, uint8_t index, uint16_t iobase) +{ + pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff); + pnp_write_config(dev, index + 1, iobase & 0xff); +} + +static inline uint16_t pnp_read_iobase(uint16_t dev, uint8_t index) +{ + return ((uint16_t)(pnp_read_config(dev, index)) << 8) | + pnp_read_config(dev, index + 1); +} + +static inline void pnp_set_irq(uint16_t dev, uint8_t index, unsigned irq) +{ + pnp_write_config(dev, index, irq); +} + +static inline void pnp_set_drq(uint16_t dev, uint8_t index, unsigned drq) +{ + pnp_write_config(dev, index, drq & 0xff); +} + +#endif /* _ASM_PNP_DEF_H_ */ diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 2f2e48f..eb57497 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NS87308) += ns87308.o obj-$(CONFIG_PDSP188x) += pdsp188x.o +obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o obj-$(CONFIG_STATUS_LED) += status_led.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o diff --git a/drivers/misc/smsc_lpc47m.c b/drivers/misc/smsc_lpc47m.c new file mode 100644 index 0000000..d51f8e3 --- /dev/null +++ b/drivers/misc/smsc_lpc47m.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/pnp_def.h> + +static void pnp_enter_conf_state(u16 dev) +{ + u16 port = dev >> 8; + + outb(0x55, port); +} + +static void pnp_exit_conf_state(u16 dev) +{ + u16 port = dev >> 8; + + outb(0xaa, port); +} + +void lpc47m_enable_serial(u16 dev, u16 iobase) +{ + pnp_enter_conf_state(dev); + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); + pnp_set_iobase(dev, PNP_IDX_IO0, iobase); + pnp_set_enable(dev, 1); + pnp_exit_conf_state(dev); +} diff --git a/include/smsc_lpc47m.h b/include/smsc_lpc47m.h new file mode 100644 index 0000000..bffd622 --- /dev/null +++ b/include/smsc_lpc47m.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SMSC_LPC47M_H_ +#define _SMSC_LPC47M_H_ + +/** + * Configure the base I/O port of the specified serial device and enable the + * serial device. + * + * @dev: High 8 bits = Super I/O port, low 8 bits = logical device number. + * @iobase: Processor I/O port address to assign to this serial device. + */ +void lpc47m_enable_serial(u16 dev, u16 iobase); + +#endif /* _SMSC_LPC47M_H_ */

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
On most x86 boards, the legacy serial ports (io address 0x3f8/0x2f8) are provided by a superio chip connected to the LPC bus. We must program the superio chip so that serial ports are available for us.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Add a comment to describe PNP_DEV
- Change pnp device inline routine parameters to use proper size
arch/x86/include/asm/pnp_def.h | 90 ++++++++++++++++++++++++++++++++++++++++++ drivers/misc/Makefile | 1 + drivers/misc/smsc_lpc47m.c | 33 ++++++++++++++++ include/smsc_lpc47m.h | 19 +++++++++ 4 files changed, 143 insertions(+) create mode 100644 arch/x86/include/asm/pnp_def.h create mode 100644 drivers/misc/smsc_lpc47m.c create mode 100644 include/smsc_lpc47m.h
Applied to u-boot-x86, thanks!

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
include/pci_ids.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/pci_ids.h b/include/pci_ids.h index ee98bee..26f4748 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2998,6 +2998,14 @@ #define PCI_DEVICE_ID_INTEL_82454NX 0x84cb #define PCI_DEVICE_ID_INTEL_84460GX 0x84ea #define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500 +#define PCI_DEVICE_ID_INTEL_TCF_GBE 0x8802 +#define PCI_DEVICE_ID_INTEL_TCF_SDIO_0 0x8809 +#define PCI_DEVICE_ID_INTEL_TCF_SDIO_1 0x880a +#define PCI_DEVICE_ID_INTEL_TCF_SATA 0x880b +#define PCI_DEVICE_ID_INTEL_TCF_UART_0 0x8811 +#define PCI_DEVICE_ID_INTEL_TCF_UART_1 0x8812 +#define PCI_DEVICE_ID_INTEL_TCF_UART_2 0x8813 +#define PCI_DEVICE_ID_INTEL_TCF_UART_3 0x8814 #define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
include/pci_ids.h | 8 ++++++++ 1 file changed, 8 insertions(+)
Applied to u-boot-x86, thanks!

Add Intel Tunnel Creek SPI controller support which is an ICH7 compatible device.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
drivers/spi/ich.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index f5c6f3e..0e00edf 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -158,7 +158,8 @@ void spi_free_slave(struct spi_slave *slave) */ static int get_ich_version(uint16_t device_id) { - if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC) + if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC || + device_id == PCI_DEVICE_ID_INTEL_ITC_LPC) return 7;
if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN &&

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Add Intel Tunnel Creek SPI controller support which is an ICH7 compatible device.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
drivers/spi/ich.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Applied to u-boot-x86, thanks!

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

Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
This is the initial import from Intel FSP release for Queensbay platform (Tunnel Creek processor and Topcliff Platform Controller Hub), which can be downloaded from Intel website.
For more details, check http://www.intel.com/fsp.
Note: U-Boot coding convention was applied to these codes, so it looks completely different from the original Intel release. Also update FSP support codes license header to use SPDX ID.
I'm sorry to report that now that you have moved it to U-Boot coding conventions various other issues have been revealed. I would really like to get this patch cleaned up at some point. If you'd like to do it by respinning the next patch in the series, or by sending a new patch I don't mind. But at the moment, it's not very nice code - I wonder if it was originally an entry in an obfuscation competition :-)
I know you have already done a lot to improve it, hopefully what I am asking for will not take too long.
I only got part way down the below code review. Maybe we can tidy it up later. Let me know what you think.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v3:
- Apply U-Boot coding conventions to typedefs
Changes in v2:
- Apply U-Boot coding convention to the FSP support codes
arch/x86/cpu/queensbay/fsp_configs.c | 21 ++ arch/x86/cpu/queensbay/fsp_support.c | 405 +++++++++++++++++++++ arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h | 59 +++ .../include/asm/arch-queensbay/fsp/fsp_bootmode.h | 24 ++ arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h | 158 ++++++++ arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h | 137 +++++++ arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h | 310 ++++++++++++++++ .../asm/arch-queensbay/fsp/fsp_infoheader.h | 36 ++ .../include/asm/arch-queensbay/fsp/fsp_platform.h | 19 + .../include/asm/arch-queensbay/fsp/fsp_support.h | 198 ++++++++++ .../x86/include/asm/arch-queensbay/fsp/fsp_types.h | 97 +++++ arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h | 58 +++ 12 files changed, 1522 insertions(+) create mode 100644 arch/x86/cpu/queensbay/fsp_configs.c create mode 100644 arch/x86/cpu/queensbay/fsp_support.c create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h create mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h
diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c new file mode 100644 index 0000000..a7bb314 --- /dev/null +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -0,0 +1,21 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#include <types.h> +#include <string.h> +#include "fsp_support.h"
+void update_fsp_upd(struct upd_region_t *fsp_upd) +{
/* Override any UPD setting if required */
/* Uncomment the line below to enable DEBUG message */
/* fsp_upd->serial_dbgport_type = 1; */
/* Examples on how to initialize the pointers in UPD region */
/* fsp_upd->pcd_example = (EXAMPLE_DATA *)&example; */
+} diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c new file mode 100644 index 0000000..2048030 --- /dev/null +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -0,0 +1,405 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#include <types.h> +#include <string.h> +#include "fsp_support.h"
+/**
- Reads a 64-bit value from memory that may be unaligned.
- This function returns the 64-bit value pointed to by buf. The function
- guarantees that the read operation does not produce an alignment fault.
I don't see how - anyway I didn't think Intel generated these faults?
- If the buf is NULL, then ASSERT().
- @buf: Pointer to a 64-bit value that may be unaligned.
- @return: The 64-bit value read from buf.
- */
+static u64 read_unaligned64(const u64 *buf)
Can we use U-Boot's get_unaligned_le64()?
+{
ASSERT(buf != NULL);
Can we replace ASSERT with U-Boot's assert() globally?
return *buf;
+}
+/**
- Compares two GUIDs
- If the GUIDs are identical then TRUE is returned.
- If there are any bit differences in the two GUIDs, then FALSE is returned.
- If guid1 is NULL, then ASSERT().
- If guid2 is NULL, then ASSERT().
- @guid1: A pointer to a 128 bit GUID.
- @guid2: A pointer to a 128 bit GUID.
- @retval TRUE: guid1 and guid2 are identical.
- @retval FALSE: guid1 and guid2 are not identical.
- */
+static unsigned char compare_guid(const struct efi_guid_t *guid1,
const struct efi_guid_t *guid2)
+{
This seems really odd. The structure consists of this:
struct efi_guid_t { u32 data1; u16 data2; u16 data3; u8 data4[8]; };
but then to compare we use all this code.
How about memcmp(guid1, guid2, sizeof(struct efi_guid))?
u64 guid1_low;
u64 guid2_low;
u64 guid1_high;
u64 guid2_high;
guid1_low = read_unaligned64((const u64 *)guid1);
guid2_low = read_unaligned64((const u64 *)guid2);
guid1_high = read_unaligned64((const u64 *)guid1 + 1);
guid2_high = read_unaligned64((const u64 *)guid2 + 1);
This casting is ugly, I wonder if we can fix it?
return (unsigned char)(guid1_low == guid2_low && guid1_high == guid2_high);
+}
+u32 __attribute__((optimize("O0"))) find_fsp_header(void)
Do you need this attribute?
+{
volatile register u8 *fsp asm("eax");
What is that line for? Do we need it?
/* Initalize the FSP base */
fsp = (u8 *)CONFIG_FSP_LOCATION;
This function is awful, we should reduce the number of custs. Can we do something like:
struct fv_header_t *hdr = (struct fv_header_t *)CONFIG_FSP_LOCATION; struct ffs_file_header_t *ffs; void *ptr;
if (!hdr || hdr->sign != 0x4856465F) return 0; ptr = fsp; ptr += fdt->ext_hdr_off + fsp->ext_hdr_size; ptr = ALIGN(ptr)
ffs = ptr; if (ffs->name[0] != 0x912740BE || ...
/* Check the FV signature, _FVH */
if (((struct fv_header_t *)fsp)->sign == 0x4856465F) {
/* Go to the end of the FV header and align the address */
fsp += ((struct fv_header_t *)fsp)->ext_hdr_off;
fsp += ((struct fv_ext_header_t *)fsp)->ext_hdr_size;
fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8);
} else {
fsp = 0;
}
/* Check the FFS GUID */
if (fsp &&
(((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[0] == 0x912740BE) &&
(((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[1] == 0x47342284) &&
(((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[2] == 0xB08471B9) &&
(((u32 *)&(((struct ffs_file_header_t *)fsp)->name))[3] == 0x0C3F3527)) {
/* Add the FFS header size to find the raw section header */
fsp += sizeof(struct ffs_file_header_t);
} else {
fsp = 0;
}
if (fsp &&
((struct raw_section_t *)fsp)->type == EFI_SECTION_RAW) {
/* Add the raw section header size to find the FSP header */
fsp += sizeof(struct raw_section_t);
} else {
fsp = 0;
}
return (u32)fsp;
+}
+#ifdef __PRE_RAM__
I think you already remove this in the next patch, which is fine.
+void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list)
Can we drop the 'status' parameter?
+{
u32 stack_len;
u32 stack_base;
u32 stack_top;
ASSERT(status == 0);
/* Get the migrated stack in normal memory */
stack_base = (u32)get_bootloader_tmp_mem(hob_list, &stack_len);
ASSERT(stack_base != 0);
stack_top = stack_base + stack_len - sizeof(u32);
/*
* Old stack base is stored at the very end of the stack top,
* use it to calculate the migrated shared data base
*/
shared_data = (struct shared_data_t *)(stack_base +
((u32)shared_data - *(u32 *)stack_top));
Confusing to add and subtract stack_base, but OK.
/* The boot loader main function entry */
bl_main_continue(hob_list, shared_data);
+}
+void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) +{
struct shared_data_t shared_data;
fsp_init_f init;
struct fsp_init_params_t params;
struct fspinit_rtbuf_t rt_buf;
struct vpd_region_t *fsp_vpd;
struct fsp_header_t *fsp_hdr;
struct fsp_init_params_t *params_ptr;
struct upd_region_t *fsp_upd;
As mentioned can we drop the _t suffix, perhaps in a later patch?
fsp_hdr = (struct fsp_header_t *)find_fsp_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header was found */
ASSERT(FALSE);
Maybe return error here? Or panic()?
Should use lower case assert(), but assert(false) is silly.
}
fsp_upd = (struct upd_region_t *)&shared_data.fsp_upd;
memset((void *)&rt_buf, 0, sizeof(struct fspinit_rtbuf_t));
You can drop the cast I think.
/* Reserve a gap in stack top */
rt_buf.common.stack_top = (u32 *)stack_top - 32;
rt_buf.common.boot_mode = boot_mode;
rt_buf.common.upd_data = (struct upd_region_t *)fsp_upd;
/* Get VPD region start */
fsp_vpd = (struct vpd_region_t *)(fsp_hdr->img_base +
fsp_hdr->cfg_region_off);
/* Verifify the VPD data region is valid */
ASSERT((fsp_vpd->img_rev == VPD_IMAGE_REV) &&
(fsp_vpd->sign == VPD_IMAGE_ID));
/* Copy default data from Flash */
memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
sizeof(struct upd_region_t));
/* Verifify the UPD data region is valid */
ASSERT(fsp_upd->terminator == 0x55AA);
Magic number?
/* Override any UPD setting if required */
update_fsp_upd(fsp_upd);
memset((void *)¶ms, 0, sizeof(struct fsp_init_params_t));
Cast again.
params.nvs_buf = nvs_buf;
params.rt_buf = (struct fspinit_rtbuf_t *)&rt_buf;
params.continuation = (fsp_continuation_f)asm_continuation;
init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init);
params_ptr = ¶ms;
Can we drop this params_ptr variable?
shared_data.fsp_hdr = fsp_hdr;
shared_data.stack_top = (u32 *)stack_top;
/*
* Use ASM code to ensure the register value in EAX & ECX
* will be passed into BlContinuationFunc
*/
asm volatile (
"pushl %0;"
"call *%%eax;"
".global asm_continuation;"
"asm_continuation:;"
"popl %%eax;" /* pop out return address */
"pushl %%ecx;" /* push shared_data pointer */
"pushl %%eax;" /* push back return address */
"jmp fsp_continue;"
: : "m"(params_ptr), "a"(init), "c"(&shared_data)
);
This looks a bit like what you have in the car_init code. I wonder if it should be moved into start.S or similar and called from here? Up to you though.
/*
* Should never get here.
* Control will continue from romstage_main_continue_asm.
* This line below is to prevent the compiler from optimizing
* structure intialization.
*/
init(¶ms);
You should be able to drop this, since params is used.
/*
* Should never return.
* Control will continue from ContinuationFunc
*/
ASSERT(FALSE);
Drop this
+}
+#else
+u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) +{
fsp_notify_f notify;
struct fsp_notify_params_t params;
u32 status;
if (!fsp_hdr)
fsp_hdr = (struct fsp_header_t *)find_fsp_header();
if (fsp_hdr == NULL) {
/* No valid FSP info header */
ASSERT(FALSE);
panic()?
}
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify);
params.phase = phase;
status = notify(¶ms);
return status;
+}
+#endif /* __PRE_RAM__ */
+u32 get_usable_lowmem_top(const void *hob_list) +{
union hob_pointers_t hob;
phys_addr_t phys_start;
u32 top;
/* Get the HOB list for processing */
hob.raw = (void *)hob_list;
Gosh this is strange code.
/* * Collect memory ranges */
top = 0x100000;
What is this magic number? Can we have a define?
while (!END_OF_HOB(hob)) {
if (hob.hdr->type == HOB_TYPE_RES_DESC) {
if (hob.res_desc->type == RES_SYS_MEM) {
phys_start = hob.res_desc->phys_start;
/* Need memory above 1MB to be collected here */
if (phys_start >= 0x100000 &&
phys_start < (phys_addr_t)0x100000000)
top += (u32)(hob.res_desc->len);
}
}
hob.raw = GET_NEXT_HOB(hob);
}
return top;
+}
+u64 get_usable_highmem_top(const void *hob_list) +{
union hob_pointers_t hob;
phys_addr_t phys_start;
u64 top;
/* Get the HOB list for processing */
hob.raw = (void *)hob_list;
/* Collect memory ranges */
top = 0x100000000;
What is this magic number? Can we have a define?
while (!END_OF_HOB(hob)) {
if (hob.hdr->type == HOB_TYPE_RES_DESC) {
if (hob.res_desc->type == RES_SYS_MEM) {
phys_start = hob.res_desc->phys_start;
/* Need memory above 1MB to be collected here */
if (phys_start >= (phys_addr_t)0x100000000)
top += (u32)(hob.res_desc->len);
}
}
hob.raw = GET_NEXT_HOB(hob);
}
return top;
+}
+u64 get_fsp_reserved_mem_from_guid(const void *hob_list, u64 *len,
struct efi_guid_t *guid)
+{
union hob_pointers_t hob;
/* Get the HOB list for processing */
hob.raw = (void *)hob_list;
/* Collect memory ranges */
while (!END_OF_HOB(hob)) {
if (hob.hdr->type == HOB_TYPE_RES_DESC) {
if (hob.res_desc->type == RES_MEM_RESERVED) {
if (compare_guid(&hob.res_desc->owner, guid)) {
if (len)
*len = (u32)(hob.res_desc->len);
return (u64)(hob.res_desc->phys_start);
}
}
}
hob.raw = GET_NEXT_HOB(hob);
}
return 0;
+}
+u32 get_fsp_reserved_mem(const void *hob_list, u32 *len) +{
const struct efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID;
u64 length;
u32 base;
base = (u32)get_fsp_reserved_mem_from_guid(hob_list,
&length, (struct efi_guid_t *)&guid);
if ((len != 0) && (base != 0))
*len = (u32)length;
return base;
+}
+u32 get_tseg_reserved_mem(const void *hob_list, u32 *len)
I wonder if we should put an fsp_ prefix on all these functions?
+{
const struct efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID;
u64 length;
u32 base;
base = (u32)get_fsp_reserved_mem_from_guid(hob_list,
&length, (struct efi_guid_t *)&guid);
if ((len != 0) && (base != 0))
*len = (u32)length;
return base;
+}
+void *get_next_hob(u16 type, const void *hob_list) +{
union hob_pointers_t hob;
ASSERT(hob_list != NULL);
hob.raw = (u8 *)hob_list;
/* Parse the HOB list until end of list or matching type is found */
while (!END_OF_HOB(hob)) {
if (hob.hdr->type == type)
return hob.raw;
hob.raw = GET_NEXT_HOB(hob);
}
return NULL;
+}
+void *get_next_guid_hob(const struct efi_guid_t *guid, const void *hob_list) +{
union hob_pointers_t hob;
hob.raw = (u8 *)hob_list;
while ((hob.raw = get_next_hob(HOB_TYPE_GUID_EXT,
hob.raw)) != NULL) {
if (compare_guid(guid, &hob.guid->name))
break;
hob.raw = GET_NEXT_HOB(hob);
}
return hob.raw;
+}
+void *get_guid_hob_data(const void *hob_list, u32 *len, struct efi_guid_t *guid) +{
u8 *guid_hob;
guid_hob = get_next_guid_hob(guid, hob_list);
if (guid_hob == NULL) {
return NULL;
} else {
if (len)
*len = GET_GUID_HOB_DATA_SIZE(guid_hob);
return GET_GUID_HOB_DATA(guid_hob);
}
+}
+void *get_fsp_nvs_data(const void *hob_list, u32 *len) +{
const struct efi_guid_t guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
return get_guid_hob_data(hob_list, len, (struct efi_guid_t *)&guid);
+}
+void *get_bootloader_tmp_mem(const void *hob_list, u32 *len) +{
const struct efi_guid_t guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID;
return get_guid_hob_data(hob_list, len, (struct efi_guid_t *)&guid);
+} diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h new file mode 100644 index 0000000..25b938f --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h @@ -0,0 +1,59 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_API_H__ +#define __FSP_API_H__
+/*
- FspInit continuation function prototype.
- Control will be returned to this callback function after FspInit API call.
- */
+typedef void (*fsp_continuation_f)(u32 status, void *hob_list);
+#pragma pack(1)
+struct fsp_init_params_t {
/* Non-volatile storage buffer pointer */
void *nvs_buf;
/* Runtime buffer pointer */
void *rt_buf;
/* Continuation function address */
fsp_continuation_f continuation;
+};
+struct common_buf_t {
/*
* Stack top pointer used by the bootloader. The new stack frame will be
* set up at this location after FspInit API call.
*/
u32 *stack_top;
u32 boot_mode; /* Current system boot mode */
void *upd_data; /* User platform configuraiton data region */
u32 reserved[7]; /* Reserved */
+};
+enum fsp_phase_t {
/* Notification code for post PCI enuermation */
INIT_PHASE_PCI = 0x20,
/* Notification code before transfering control to the payload */
INIT_PHASE_BOOT = 0x40
+};
+struct fsp_notify_params_t {
/* Notification phase used for NotifyPhase API */
enum fsp_phase_t phase;
+};
+#pragma pack()
+/* FspInit API function prototype */ +typedef u32 (*fsp_init_f)(struct fsp_init_params_t *param);
+/* FspNotify API function prototype */ +typedef u32 (*fsp_notify_f)(struct fsp_notify_params_t *param);
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h new file mode 100644 index 0000000..c3f8b49 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h @@ -0,0 +1,24 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_BOOT_MODE_H__ +#define __FSP_BOOT_MODE_H__
+/* 0x21 - 0xf..f are reserved */ +#define BOOT_FULL_CONFIG 0x00 +#define BOOT_MINIMAL_CONFIG 0x01 +#define BOOT_NO_CONFIG_CHANGES 0x02 +#define BOOT_FULL_CONFIG_PLUS_DIAG 0x03 +#define BOOT_DEFAULT_SETTINGS 0x04 +#define BOOT_ON_S4_RESUME 0x05 +#define BOOT_ON_S5_RESUME 0x06 +#define BOOT_ON_S2_RESUME 0x10 +#define BOOT_ON_S3_RESUME 0x11 +#define BOOT_ON_FLASH_UPDATE 0x12 +#define BOOT_IN_RECOVERY_MODE 0x20
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h new file mode 100644 index 0000000..1f73680 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h @@ -0,0 +1,158 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_FFS_H__ +#define __FSP_FFS_H__
+#pragma pack(1)
+/* Used to verify the integrity of the file */ +union ffs_integrity_t {
struct {
/*
* The IntegrityCheck.checksum.header field is an 8-bit
* checksum of the file header. The State and
* IntegrityCheck.checksum.file fields are assumed to be zero
* and the checksum is calculated such that the entire header
* sums to zero.
*/
u8 header;
/*
* If the FFS_ATTRIB_CHECKSUM (see definition below) bit of
* the Attributes field is set to one, the
* IntegrityCheck.checksum.file field is an 8-bit checksum of
* the file data. If the FFS_ATTRIB_CHECKSUM bit of the
* Attributes field is cleared to zero, the
* IntegrityCheck.checksum.file field must be initialized with
* a value of 0xAA. The IntegrityCheck.checksum.file field is
* valid any time the EFI_FILE_DATA_VALID bit is set in the
* State field.
*/
u8 file;
} checksum;
/* This is the full 16 bits of the IntegrityCheck field */
u16 checksum16;
+};
+/*
- Each file begins with the header that describe the
- contents and state of the files.
- */
+struct ffs_file_header_t {
/*
* This GUID is the file name.
* It is used to uniquely identify the file.
*/
struct efi_guid_t name;
/* Used to verify the integrity of the file */
union ffs_integrity_t integrity;
/* Identifies the type of file */
u8 type;
/* Declares various file attribute bits */
u8 attr;
/* The length of the file in bytes, including the FFS header */
u8 size[3];
/*
* Used to track the state of the file throughout the life of
* the file from creation to deletion.
*/
u8 state;
+};
+struct ffs_file_header2_t {
/*
* This GUID is the file name. It is used to uniquely identify the file.
* There may be only one instance of a file with the file name GUID of
* Name in any given firmware volume, except if the file type is
* EFI_FV_FILE_TYPE_FFS_PAD.
*/
struct efi_guid_t name;
/* Used to verify the integrity of the file */
union ffs_integrity_t integrity;
/* Identifies the type of file */
u8 type;
/* Declares various file attribute bits */
u8 attr;
/*
* The length of the file in bytes, including the FFS header.
* The length of the file data is either
* (size - sizeof(struct ffs_file_header_t)). This calculation means a
* zero-length file has a size of 24 bytes, which is
* sizeof(struct ffs_file_header_t). Size is not required to be a
* multiple of 8 bytes. Given a file F, the next file header is located
* at the next 8-byte aligned firmware volume offset following the last
* byte of the file F.
*/
u8 size[3];
/*
* Used to track the state of the file throughout the life of
* the file from creation to deletion.
*/
u8 state;
/*
* If FFS_ATTRIB_LARGE_FILE is set in attr, then ext_size exists
* and size must be set to zero.
* If FFS_ATTRIB_LARGE_FILE is not set then
* struct ffs_file_header_t is used.
*/
u32 ext_size;
+};
+/*
- Pseudo type. It is used as a wild card when retrieving sections.
- The section type EFI_SECTION_ALL matches all section types.
- */
+#define EFI_SECTION_ALL 0x00
+/* Encapsulation section Type values */ +#define EFI_SECTION_COMPRESSION 0x01 +#define EFI_SECTION_GUID_DEFINED 0x02 +#define EFI_SECTION_DISPOSABLE 0x03
+/* Leaf section Type values */ +#define EFI_SECTION_PE32 0x10 +#define EFI_SECTION_PIC 0x11 +#define EFI_SECTION_TE 0x12 +#define EFI_SECTION_DXE_DEPEX 0x13 +#define EFI_SECTION_VERSION 0x14 +#define EFI_SECTION_USER_INTERFACE 0x15 +#define EFI_SECTION_COMPATIBILITY16 0x16 +#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define EFI_SECTION_RAW 0x19 +#define EFI_SECTION_PEI_DEPEX 0x1B +#define EFI_SECTION_SMM_DEPEX 0x1C
+/* Common section header */ +struct raw_section_t {
/*
* A 24-bit unsigned integer that contains the total size of
* the section in bytes, including the EFI_COMMON_SECTION_HEADER.
*/
u8 size[3];
u8 type;
+};
+struct raw_section2_t {
/*
* A 24-bit unsigned integer that contains the total size of
* the section in bytes, including the EFI_COMMON_SECTION_HEADER.
*/
u8 size[3];
u8 type;
/*
* If size is 0xFFFFFF, then ext_size contains the size of
* the section. If size is not equal to 0xFFFFFF, then this
* field does not exist.
*/
u32 ext_size;
+};
+#pragma pack()
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h new file mode 100644 index 0000000..01300db --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h @@ -0,0 +1,137 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_FV___ +#define __FSP_FV___
+/* Value of EFI_FV_FILE_ATTRIBUTES */ +#define EFI_FV_FILE_ATTR_ALIGNMENT 0x0000001F +#define EFI_FV_FILE_ATTR_FIXED 0x00000100 +#define EFI_FV_FILE_ATTR_MEMORY_MAPPED 0x00000200
+/* Attributes bit definitions */ +#define EFI_FVB2_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB2_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB2_READ_STATUS 0x00000004 +#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB2_WRITE_STATUS 0x00000020 +#define EFI_FVB2_LOCK_CAP 0x00000040 +#define EFI_FVB2_LOCK_STATUS 0x00000080 +#define EFI_FVB2_STICKY_WRITE 0x00000200 +#define EFI_FVB2_MEMORY_MAPPED 0x00000400 +#define EFI_FVB2_ERASE_POLARITY 0x00000800 +#define EFI_FVB2_READ_LOCK_CAP 0x00001000 +#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 +#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 +#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 +#define EFI_FVB2_ALIGNMENT 0x001F0000 +#define EFI_FVB2_ALIGNMENT_1 0x00000000 +#define EFI_FVB2_ALIGNMENT_2 0x00010000 +#define EFI_FVB2_ALIGNMENT_4 0x00020000 +#define EFI_FVB2_ALIGNMENT_8 0x00030000 +#define EFI_FVB2_ALIGNMENT_16 0x00040000 +#define EFI_FVB2_ALIGNMENT_32 0x00050000 +#define EFI_FVB2_ALIGNMENT_64 0x00060000 +#define EFI_FVB2_ALIGNMENT_128 0x00070000 +#define EFI_FVB2_ALIGNMENT_256 0x00080000 +#define EFI_FVB2_ALIGNMENT_512 0x00090000 +#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 +#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 +#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 +#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 +#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 +#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 +#define EFI_FVB2_ALIGNMENT_64K 0x00100000 +#define EFI_FVB2_ALIGNMENT_128K 0x00110000 +#define EFI_FVB2_ALIGNMENT_256K 0x00120000 +#define EFI_FVB2_ALIGNMENT_512K 0x00130000 +#define EFI_FVB2_ALIGNMENT_1M 0x00140000 +#define EFI_FVB2_ALIGNMENT_2M 0x00150000 +#define EFI_FVB2_ALIGNMENT_4M 0x00160000 +#define EFI_FVB2_ALIGNMENT_8M 0x00170000 +#define EFI_FVB2_ALIGNMENT_16M 0x00180000 +#define EFI_FVB2_ALIGNMENT_32M 0x00190000 +#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 +#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 +#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 +#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 +#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 +#define EFI_FVB2_ALIGNMENT_2G 0x001F0000
+struct fv_blkmap_entry_t {
/* The number of sequential blocks which are of the same size */
u32 num_blocks;
/* The size of the blocks */
u32 length;
+};
+/* Describes the features and layout of the firmware volume */ +struct fv_header_t {
/*
* The first 16 bytes are reserved to allow for the reset vector of
* processors whose reset vector is at address 0.
*/
u8 zero_vec[16];
/*
* Declares the file system with which the firmware volume
* is formatted.
*/
struct efi_guid_t fs_guid;
/*
* Length in bytes of the complete firmware volume, including
* the header.
*/
u64 fv_len;
/* Set to EFI_FVH_SIGNATURE */
u32 sign;
/*
* Declares capabilities and power-on defaults for the firmware
* volume.
*/
u32 attr;
/* Length in bytes of the complete firmware volume header */
u16 hdr_len;
/*
* A 16-bit checksum of the firmware volume header.
* A valid header sums to zero.
*/
u16 checksum;
/*
* Offset, relative to the start of the header, of the extended
* header (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is
* no extended header.
*/
u16 ext_hdr_off;
/* This field must always be set to zero */
u8 reserved[1];
/*
* Set to 2. Future versions of this specification may define new
* header fields and will increment the Revision field accordingly.
*/
u8 rev;
/*
* An array of run-length encoded FvBlockMapEntry structures.
* The array is terminated with an entry of {0,0}.
*/
struct fv_blkmap_entry_t block_map[1];
+};
+#define EFI_FVH_SIGNATURE SIGNATURE_32('_', 'F', 'V', 'H')
+/* Firmware Volume Header Revision definition */ +#define EFI_FVH_REVISION 0x02
+/* Extension header pointed by ExtHeaderOffset of volume header */ +struct fv_ext_header_t {
/* firmware volume name */
struct efi_guid_t fv_name;
/* Size of the rest of the extension header including this structure */
u32 ext_hdr_size;
+};
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h new file mode 100644 index 0000000..44c0f90 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h @@ -0,0 +1,310 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_HOB_H__ +#define __FSP_HOB_H__
+/* Type of HOB Header */ +#define HOB_TYPE_MEM_ALLOC 0x0002 +#define HOB_TYPE_RES_DESC 0x0003 +#define HOB_TYPE_GUID_EXT 0x0004 +#define HOB_TYPE_UNUSED 0xFFFE +#define HOB_TYPE_EOH 0xFFFF
+/*
- Describes the format and size of the data inside the HOB.
- All HOBs must contain this generic HOB header.
- */
+struct hob_header_t {
u16 type; /* HOB type */
u16 len; /* HOB length */
u32 reserved; /* always zero */
+};
+/* Enumeration of memory types introduced in UEFI */ +enum efi_mem_type_t {
EFI_RESERVED_MEMORY_TYPE,
/*
* The code portions of a loaded application.
* (Note that UEFI OS loaders are UEFI applications.)
*/
EFI_LOADER_CODE,
/*
* The data portions of a loaded application and
* the default data allocation type used by an application
* to allocate pool memory.
*/
EFI_LOADER_DATA,
/* The code portions of a loaded Boot Services Driver */
EFI_BOOT_SERVICES_CODE,
/*
* The data portions of a loaded Boot Serves Driver and
* the default data allocation type used by a Boot Services
* Driver to allocate pool memory.
*/
EFI_BOOT_SERVICES_DATA,
/* The code portions of a loaded Runtime Services Driver */
EFI_RUNTIME_SERVICES_CODE,
/*
* The data portions of a loaded Runtime Services Driver and
* the default data allocation type used by a Runtime Services
* Driver to allocate pool memory.
*/
EFI_RUNTIME_SERVICES_DATA,
/* Free (unallocated) memory */
EFI_CONVENTIONAL_MEMORY,
/* Memory in which errors have been detected */
EFI_UNUSABLE_MEMORY,
/* Memory that holds the ACPI tables */
EFI_ACPI_RECLAIM_MEMORY,
/* Address space reserved for use by the firmware */
EFI_ACPI_MEMORY_NVS,
/*
* Used by system firmware to request that a memory-mapped IO region
* be mapped by the OS to a virtual address so it can be accessed by
* EFI runtime services.
*/
EFI_MMAP_IO,
/*
* System memory-mapped IO region that is used to translate
* memory cycles to IO cycles by the processor.
*/
EFI_MMAP_IO_PORT,
/*
* Address space reserved by the firmware for code that is
* part of the processor.
*/
EFI_PAL_CODE,
EFI_MAX_MEMORY_TYPE
+};
+/*
- Describes all memory ranges used during the HOB producer phase that
- exist outside the HOB list. This HOB type describes how memory is used,
- not the physical attributes of memory.
- */
+struct hob_mem_alloc_t {
struct hob_header_t hdr;
/*
* A GUID that defines the memory allocation region's type and purpose,
* as well as other fields within the memory allocation HOB. This GUID
* is used to define the additional data within the HOB that may be
* present for the memory allocation HOB. Type efi_guid_t is defined in
* InstallProtocolInterface() in the UEFI 2.0 specification.
*/
struct efi_guid_t name;
/*
* The base address of memory allocated by this HOB.
* Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0
* specification.
*/
phys_addr_t mem_base;
/* The length in bytes of memory allocated by this HOB */
phys_size_t mem_len;
/*
* Defines the type of memory allocated by this HOB.
* The memory type definition follows the EFI_MEMORY_TYPE definition.
* Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0
* specification.
*/
enum efi_mem_type_t mem_type;
/* padding */
u8 reserved[4];
+};
+/* Value of ResourceType in HOB_RES_DESC */ +#define RES_SYS_MEM 0x00000000 +#define RES_MMAP_IO 0x00000001 +#define RES_IO 0x00000002 +#define RES_FW_DEVICE 0x00000003 +#define RES_MMAP_IO_PORT 0x00000004 +#define RES_MEM_RESERVED 0x00000005 +#define RES_IO_RESERVED 0x00000006 +#define RES_MAX_MEM_TYPE 0x00000007
+/*
- These types can be ORed together as needed.
- The first three enumerations describe settings
- The rest of the settings describe capabilities
- */
+#define RES_ATTR_PRESENT 0x00000001 +#define RES_ATTR_INITIALIZED 0x00000002 +#define RES_ATTR_TESTED 0x00000004 +#define RES_ATTR_SINGLE_BIT_ECC 0x00000008 +#define RES_ATTR_MULTIPLE_BIT_ECC 0x00000010 +#define RES_ATTR_ECC_RESERVED_1 0x00000020 +#define RES_ATTR_ECC_RESERVED_2 0x00000040 +#define RES_ATTR_READ_PROTECTED 0x00000080 +#define RES_ATTR_WRITE_PROTECTED 0x00000100 +#define RES_ATTR_EXECUTION_PROTECTED 0x00000200 +#define RES_ATTR_UNCACHEABLE 0x00000400 +#define RES_ATTR_WRITE_COMBINEABLE 0x00000800 +#define RES_ATTR_WRITE_THROUGH_CACHEABLE 0x00001000 +#define RES_ATTR_WRITE_BACK_CACHEABLE 0x00002000 +#define RES_ATTR_16_BIT_IO 0x00004000 +#define RES_ATTR_32_BIT_IO 0x00008000 +#define RES_ATTR_64_BIT_IO 0x00010000 +#define RES_ATTR_UNCACHED_EXPORTED 0x00020000
+/*
- Describes the resource properties of all fixed, nonrelocatable resource
- ranges found on the processor host bus during the HOB producer phase.
- */
+struct hob_res_desc_t {
struct hob_header_t hdr;
/*
* A GUID representing the owner of the resource. This GUID is
* used by HOB consumer phase components to correlate device
* ownership of a resource.
*/
struct efi_guid_t owner;
u32 type;
u32 attr;
/* The physical start address of the resource region */
phys_addr_t phys_start;
/* The number of bytes of the resource region */
phys_size_t len;
+};
+/*
- Allows writers of executable content in the HOB producer phase to
- maintain and manage HOBs with specific GUID.
- */
+struct hob_guid_t {
struct hob_header_t hdr;
/* A GUID that defines the contents of this HOB */
struct efi_guid_t name;
/* GUID specific data goes here */
+};
+/* Union of all the possible HOB Types */ +union hob_pointers_t {
struct hob_header_t *hdr;
struct hob_mem_alloc_t *mem_alloc;
struct hob_res_desc_t *res_desc;
struct hob_guid_t *guid;
u8 *raw;
+};
+/**
- Returns the type of a HOB.
- This macro returns the type field from the HOB header for the
- HOB specified by hob.
- @hob: A pointer to a HOB.
- @return: HOB type.
- */
+#define GET_HOB_TYPE(hob) \
((*(struct hob_header_t **)&(hob))->type)
+/**
- Returns the length, in bytes, of a HOB.
- This macro returns the len field from the HOB header for the
- HOB specified by hob.
- @hob: A pointer to a HOB.
- @return: HOB length.
- */
+#define GET_HOB_LENGTH(hob) \
((*(struct hob_header_t **)&(hob))->len)
+/**
- Returns a pointer to the next HOB in the HOB list.
- This macro returns a pointer to HOB that follows the HOB specified by hob
- in the HOB List.
- @hob: A pointer to a HOB.
- @return: A pointer to the next HOB in the HOB list.
- */
+#define GET_NEXT_HOB(hob) \
(void *)(*(u8 **)&(hob) + GET_HOB_LENGTH(hob))
+/**
- Determines if a HOB is the last HOB in the HOB list.
- This macro determine if the HOB specified by hob is the last HOB in the
- HOB list. If hob is last HOB in the HOB list, then TRUE is returned.
- Otherwise, FALSE is returned.
- @hob: A pointer to a HOB.
- @retval TRUE: The HOB specified by hob is the last HOB in the HOB list.
- @retval FALSE: The HOB specified by hob is not the last HOB in the HOB list.
- */
+#define END_OF_HOB(hob) (GET_HOB_TYPE(hob) == (u16)HOB_TYPE_EOH)
+/**
- Returns a pointer to data buffer from a HOB of type HOB_TYPE_GUID_EXT.
- This macro returns a pointer to the data buffer in a HOB specified by hob.
- hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT.
- @hob: A pointer to a HOB.
- @return: A pointer to the data buffer in a HOB.
- */
+#define GET_GUID_HOB_DATA(hob) \
(void *)(*(u8 **)&(hob) + sizeof(struct hob_guid_t))
+/**
- Returns the size of the data buffer from a HOB of type HOB_TYPE_GUID_EXT.
- This macro returns the size, in bytes, of the data buffer in a HOB
- specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT.
- @hob: A pointer to a HOB.
- @return: The size of the data buffer.
- */
+#define GET_GUID_HOB_DATA_SIZE(hob) \
(u16)(GET_HOB_LENGTH(hob) - sizeof(struct hob_guid_t))
+/* FSP specific GUID HOB definitions */ +#define FSP_HEADER_GUID \
{ \
0x912740be, 0x2284, 0x4734, \
{0xb9, 0x71, 0x84, 0xb0, 0x27, 0x35, 0x3f, 0x0c} \
}
+#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
{ \
0x721acf02, 0x4d77, 0x4c2a, \
{ 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
}
+#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \
{ \
0xbbcff46c, 0xc8d3, 0x4113, \
{ 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } \
}
+#define FSP_HOB_RESOURCE_OWNER_FSP_GUID \
{ \
0x69a79759, 0x1373, 0x4367, \
{ 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } \
}
+#define FSP_HOB_RESOURCE_OWNER_TSEG_GUID \
{ \
0xd038747c, 0xd00c, 0x4980, \
{ 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } \
}
+#define FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID \
{ \
0x9c7c3aa7, 0x5332, 0x4917, \
{ 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } \
}
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h new file mode 100644 index 0000000..ad78bcd --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h @@ -0,0 +1,36 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef _FSP_HEADER_H_ +#define _FSP_HEADER_H_
+#define FSP_HEADER_OFF 0x94 /* Fixed FSP header offset in the FSP image */
+#pragma pack(1)
+struct fsp_header_t {
u32 sign; /* 'FSPH' */
u32 hdr_len; /* header length */
u8 reserved1[3];
u8 hdr_rev; /* header rev */
u32 img_rev; /* image rev */
char img_id[8]; /* signature string */
u32 img_size; /* image size */
u32 img_base; /* image base */
u32 img_attr; /* image attribute */
u32 cfg_region_off; /* configuration region offset */
u32 cfg_region_size; /* configuration region size */
u32 api_num; /* number of API entries */
u32 fsp_tempram_init; /* tempram_init offset */
u32 fsp_init; /* fsp_init offset */
u32 fsp_notify; /* fsp_notify offset */
u32 reserved2;
+};
+#pragma pack()
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h new file mode 100644 index 0000000..a7b6e6b --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h @@ -0,0 +1,19 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_PLATFORM_H__ +#define __FSP_PLATFORM_H__
+#pragma pack(1)
+struct fspinit_rtbuf_t {
struct common_buf_t common; /* FSP common runtime data structure */
+};
+#pragma pack()
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h new file mode 100644 index 0000000..3e53ea1 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h @@ -0,0 +1,198 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_SUPPORT_H__ +#define __FSP_SUPPORT_H__
+#include "fsp_types.h" +#include "fsp_fv.h" +#include "fsp_ffs.h" +#include "fsp_api.h" +#include "fsp_hob.h" +#include "fsp_platform.h" +#include "fsp_infoheader.h" +#include "fsp_bootmode.h" +#include "fsp_vpd.h"
+struct shared_data_t {
struct fsp_header_t *fsp_hdr;
u32 *stack_top;
struct upd_region_t fsp_upd;
+};
+void asm_continuation(void);
+void bl_main_continue(void *hob_list, struct shared_data_t *shared_data);
Function comments?
+/**
- FSP Continuation function
- @shared_data: Shared data base before stack migration
- @status: Always 0
- @hob_list: HOB list pointer
- @retval: Never returns
- */
+void fsp_continue(struct shared_data_t *shared_data, u32 status,
void *hob_list);
+/**
- Find FSP header offset in FSP image
- If this function is called before the a stack is established, special care
- must be taken. First, it cannot declare any local variable using stack.
- Only register variable can be used here. Secondly, some compiler version
- will add prolog or epilog code for the C function. If so the function call
- may not work before stack is ready. GCC 4.8.1 has been verified to be
- working for the following code.
- @retval: the offset of FSP header. If signature is invalid, returns 0.
- */
+u32 find_fsp_header(void);
+/**
- FSP initialization wrapper function.
- @stack_top: bootloader stack top address
- @boot_mode: boot mode defined in fsp_bootmode.h
- @nvs_buf: Non-volatile memory buffer pointer
- */
+void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf);
+/**
- FSP notification wrapper function
- @fsp_hdr: Pointer to FSP information header
- @phase: FSP initialization phase defined in enum fsp_phase_t
- @retval: compatible status code with EFI_STATUS defined in PI spec
- */
+u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase);
+/**
- This function retrieves the top of usable low memory.
- @hob_list: A HOB list pointer.
- @retval: Usable low memory top.
- */
+u32 get_usable_lowmem_top(const void *hob_list);
+/**
- This function retrieves the top of usable high memory.
- @hob_list: A HOB list pointer.
- @retval: Usable high memory top.
- */
+u64 get_usable_highmem_top(const void *hob_list);
+/**
- This function retrieves a special reserved memory region.
- @hob_list: A HOB list pointer.
- @len: A pointer to the GUID HOB data buffer length.
If the GUID HOB is located, the length will be updated.
- @guid: A pointer to the owner guild.
- @retval: Reserved region start address.
0 if this region does not exist.
- */
+u64 get_fsp_reserved_mem_from_guid(const void *hob_list,
u64 *len, struct efi_guid_t *guid);
+/**
- This function retrieves the FSP reserved normal memory.
- @hob_list: A HOB list pointer.
- @len: A pointer to the FSP reserved memory length buffer.
If the GUID HOB is located, the length will be updated.
- @retval: FSP reserved memory base
0 if this region does not exist.
- */
+u32 get_fsp_reserved_mem(const void *hob_list, u32 *len);
+/**
- This function retrieves the TSEG reserved normal memory.
- @hob_list: A HOB list pointer.
- @len: A pointer to the TSEG reserved memory length buffer.
If the GUID HOB is located, the length will be updated.
- @retval NULL: Failed to find the TSEG reserved memory.
- @retval others: TSEG reserved memory base.
- */
+u32 get_tseg_reserved_mem(const void *hob_list, u32 *len);
+/**
- Returns the next instance of a HOB type from the starting HOB.
- @type: HOB type to search
- @hob_list: A pointer to the HOB list
- @retval: A HOB object with matching type; Otherwise NULL.
- */
+void *get_next_hob(u16 type, const void *hob_list);
+/**
- Returns the next instance of the matched GUID HOB from the starting HOB.
- @guid: GUID to search
- @hob_list: A pointer to the HOB list
- @retval: A HOB object with matching GUID; Otherwise NULL.
- */
+void *get_next_guid_hob(const struct efi_guid_t *guid, const void *hob_list);
+/**
- This function retrieves a GUID HOB data buffer and size.
- @hob_list: A HOB list pointer.
- @len: A pointer to the GUID HOB data buffer length.
If the GUID HOB is located, the length will be updated.
- @guid A pointer to HOB GUID.
- @retval NULL: Failed to find the GUID HOB.
- @retval others: GUID HOB data buffer pointer.
- */
+void *get_guid_hob_data(const void *hob_list, u32 *len,
struct efi_guid_t *guid);
+/**
- This function retrieves FSP Non-volatile Storage HOB buffer and size.
- @hob_list: A HOB list pointer.
- @len: A pointer to the NVS data buffer length.
If the HOB is located, the length will be updated.
- @retval NULL: Failed to find the NVS HOB.
- @retval others: FSP NVS data buffer pointer.
- */
+void *get_fsp_nvs_data(const void *hob_list, u32 *len);
+/**
- This function retrieves Bootloader temporary stack buffer and size.
- @hob_list: A HOB list pointer.
- @len: A pointer to the bootloader temporary stack length.
If the HOB is located, the length will be updated.
- @retval NULL: Failed to find the bootloader temporary stack HOB.
- @retval others: Bootloader temporary stackbuffer pointer.
- */
+void *get_bootloader_tmp_mem(const void *hob_list, u32 *len);
+/**
- This function overrides the default configurations in the UPD data region.
- @fsp_upd: A pointer to the upd_region_t data strcture
- @return: None
- */
+void update_fsp_upd(struct upd_region_t *fsp_upd);
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h new file mode 100644 index 0000000..12ebbfd --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h @@ -0,0 +1,97 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: Intel
- */
+#ifndef __FSP_TYPES_H__ +#define __FSP_TYPES_H__
+/*
- Boolean true value. UEFI Specification defines this value to be 1,
- but this form is more portable.
- */
+#define TRUE ((unsigned char)(1 == 1))
+/*
- Boolean false value. UEFI Specification defines this value to be 0,
- but this form is more portable.
- */
+#define FALSE ((unsigned char)(0 == 1))
+/* 128 bit buffer containing a unique identifier value */ +struct efi_guid_t {
u32 data1;
u16 data2;
u16 data3;
u8 data4[8];
+};
+/**
- Returns a 16-bit signature built from 2 ASCII characters.
- This macro returns a 16-bit value built from the two ASCII characters
- specified by A and B.
- @A: The first ASCII character.
- @B: The second ASCII character.
- @return: A 16-bit value built from the two ASCII characters specified by
A and B.
- */
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
+/**
- Returns a 32-bit signature built from 4 ASCII characters.
- This macro returns a 32-bit value built from the four ASCII characters
- specified by A, B, C, and D.
- @A: The first ASCII character.
- @B: The second ASCII character.
- @C: The third ASCII character.
- @D: The fourth ASCII character.
- @return: A 32-bit value built from the two ASCII characters specified by
A, B, C and D.
- */
+#define SIGNATURE_32(A, B, C, D) \
(SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16))
+/**
- Returns a 64-bit signature built from 8 ASCII characters.
- This macro returns a 64-bit value built from the eight ASCII characters
- specified by A, B, C, D, E, F, G,and H.
- @A: The first ASCII character.
- @B: The second ASCII character.
- @C: The third ASCII character.
- @D: The fourth ASCII character.
- @E: The fifth ASCII character.
- @F: The sixth ASCII character.
- @G: The seventh ASCII character.
- @H: The eighth ASCII character.
- @return: A 64-bit value built from the two ASCII characters specified by
A, B, C, D, E, F, G and H.
- */
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
(SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
+/* Assertion for debug */ +#define ASSERT(exp) do { if (!(exp)) for (;;); } while (FALSE)
+/*
- Define FSP API return status code.
- Compatiable with EFI_STATUS defined in PI Spec.
- */
+#define FSP_SUCCESS 0 +#define FSP_INVALID_PARAM 0x80000002 +#define FSP_UNSUPPORTED 0x80000003 +#define FSP_DEVICE_ERROR 0x80000007 +#define FSP_NOT_FOUND 0x8000000E +#define FSP_ALREADY_STARTED 0x80000014
+#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h new file mode 100644 index 0000000..11cc32f --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h @@ -0,0 +1,58 @@ +/*
- Copyright (C) 2013, Intel Corporation
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- This file is automatically generated. Please do NOT modify !!!
- SPDX-License-Identifier: Intel
- */
+#ifndef __VPDHEADER_H__ +#define __VPDHEADER_H__
+#pragma pack(1)
+struct upd_region_t {
u64 sign; /* Offset 0x0000 */
u64 reserved; /* Offset 0x0008 */
u8 dummy[240]; /* Offset 0x0010 */
u8 hda_verb_header[12]; /* Offset 0x0100 */
u32 hda_verb_length; /* Offset 0x010C */
u8 hda_verb_data0[16]; /* Offset 0x0110 */
u8 hda_verb_data1[16]; /* Offset 0x0120 */
u8 hda_verb_data2[16]; /* Offset 0x0130 */
u8 hda_verb_data3[16]; /* Offset 0x0140 */
u8 hda_verb_data4[16]; /* Offset 0x0150 */
u8 hda_verb_data5[16]; /* Offset 0x0160 */
u8 hda_verb_data6[16]; /* Offset 0x0170 */
u8 hda_verb_data7[16]; /* Offset 0x0180 */
u8 hda_verb_data8[16]; /* Offset 0x0190 */
u8 hda_verb_data9[16]; /* Offset 0x01A0 */
u8 hda_verb_data10[16]; /* Offset 0x01B0 */
u8 hda_verb_data11[16]; /* Offset 0x01C0 */
u8 hda_verb_data12[16]; /* Offset 0x01D0 */
u8 hda_verb_data13[16]; /* Offset 0x01E0 */
u8 hda_verb_pad[47]; /* Offset 0x01F0 */
u16 terminator; /* Offset 0x021F */
+};
+#define VPD_IMAGE_ID 0x445056574F4E4E4D /* 'MNNOWVPD' */ +#define VPD_IMAGE_REV 0x00000301
+struct vpd_region_t {
u64 sign; /* Offset 0x0000 */
u32 img_rev; /* Offset 0x0008 */
u32 upd_offset; /* Offset 0x000C */
u8 unused[16]; /* Offset 0x0010 */
u32 fsp_res_memlen; /* Offset 0x0020 */
u8 disable_pcie1; /* Offset 0x0024 */
u8 disable_pcie2; /* Offset 0x0025 */
u8 disable_pcie3; /* Offset 0x0026 */
u8 enable_azalia; /* Offset 0x0027 */
u8 legacy_seg_decode; /* Offset 0x0028 */
u8 pcie_port_ioh; /* Offset 0x0029 */
+};
+#pragma pack()
+#endif
1.8.2.1
Regards, Simon

Hi Simon
On Sat, Dec 13, 2014 at 5:27 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
This is the initial import from Intel FSP release for Queensbay platform (Tunnel Creek processor and Topcliff Platform Controller Hub), which can be downloaded from Intel website.
For more details, check http://www.intel.com/fsp.
Note: U-Boot coding convention was applied to these codes, so it looks completely different from the original Intel release. Also update FSP support codes license header to use SPDX ID.
I'm sorry to report that now that you have moved it to U-Boot coding conventions various other issues have been revealed. I would really like to get this patch cleaned up at some point. If you'd like to do it by respinning the next patch in the series, or by sending a new patch I don't mind. But at the moment, it's not very nice code - I wonder if it was originally an entry in an obfuscation competition :-)
I know you have already done a lot to improve it, hopefully what I am asking for will not take too long.
I only got part way down the below code review. Maybe we can tidy it up later. Let me know what you think.
I think I can fix those issues in a follow-on patch. Will you apply this series for now?
[snip]
Regards, Bin

Hi Simon,
On Sat, Dec 13, 2014 at 12:53 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon
On Sat, Dec 13, 2014 at 5:27 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
This is the initial import from Intel FSP release for Queensbay platform (Tunnel Creek processor and Topcliff Platform Controller Hub), which can be downloaded from Intel website.
For more details, check http://www.intel.com/fsp.
Note: U-Boot coding convention was applied to these codes, so it looks completely different from the original Intel release. Also update FSP support codes license header to use SPDX ID.
I'm sorry to report that now that you have moved it to U-Boot coding conventions various other issues have been revealed. I would really like to get this patch cleaned up at some point. If you'd like to do it by respinning the next patch in the series, or by sending a new patch I don't mind. But at the moment, it's not very nice code - I wonder if it was originally an entry in an obfuscation competition :-)
I know you have already done a lot to improve it, hopefully what I am asking for will not take too long.
I only got part way down the below code review. Maybe we can tidy it up later. Let me know what you think.
I think I can fix those issues in a follow-on patch. Will you apply this series for now?
These issues are fixed in the follow-on patch @ http://patchwork.ozlabs.org/patch/420827/, except the following:
- find_fsp_header() is not rewritten to remove those casts, because only register variable can be used in a stackless environment - 'status' parameter cannot removed in the fsp_continue() as there is a check on the status - params_ptr cannot be dropped in fsp_init() due to different ABI call into the FSP - init(¶ms) cannot be removed due to compiler optimization will break this function
I've added some comments in the codes to explain. Please have a look.
Regards, Bin

On 13 December 2014 at 21:23, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sat, Dec 13, 2014 at 12:53 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon
On Sat, Dec 13, 2014 at 5:27 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
This is the initial import from Intel FSP release for Queensbay platform (Tunnel Creek processor and Topcliff Platform Controller Hub), which can be downloaded from Intel website.
For more details, check http://www.intel.com/fsp.
Note: U-Boot coding convention was applied to these codes, so it looks completely different from the original Intel release. Also update FSP support codes license header to use SPDX ID.
I'm sorry to report that now that you have moved it to U-Boot coding conventions various other issues have been revealed. I would really like to get this patch cleaned up at some point. If you'd like to do it by respinning the next patch in the series, or by sending a new patch I don't mind. But at the moment, it's not very nice code - I wonder if it was originally an entry in an obfuscation competition :-)
I know you have already done a lot to improve it, hopefully what I am asking for will not take too long.
I only got part way down the below code review. Maybe we can tidy it up later. Let me know what you think.
I think I can fix those issues in a follow-on patch. Will you apply this series for now?
These issues are fixed in the follow-on patch @ http://patchwork.ozlabs.org/patch/420827/, except the following:
- find_fsp_header() is not rewritten to remove those casts, because
only register variable can be used in a stackless environment
- 'status' parameter cannot removed in the fsp_continue() as there is
a check on the status
- params_ptr cannot be dropped in fsp_init() due to different ABI call
into the FSP
- init(¶ms) cannot be removed due to compiler optimization will
break this function
I've added some comments in the codes to explain. Please have a look.
Regards, Bin
Applied to u-boot-x86, thanks!

Use inline assembly codes to call FspNotify() to make sure parameters are passed on the stack as required by the FSP calling convention.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v3: - Move license header changes to last commit
Changes in v2: - Update the codes to use U-Boot coding style
arch/x86/cpu/queensbay/fsp_configs.c | 5 ++- arch/x86/cpu/queensbay/fsp_support.c | 39 ++++++++++++++-------- .../include/asm/arch-queensbay/fsp/fsp_support.h | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c index a7bb314..aef18fc 100644 --- a/arch/x86/cpu/queensbay/fsp_configs.c +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -5,9 +5,8 @@ * SPDX-License-Identifier: Intel */
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h>
void update_fsp_upd(struct upd_region_t *fsp_upd) { diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c index 2048030..df3bbd0 100644 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -5,9 +5,9 @@ * SPDX-License-Identifier: Intel */
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/post.h>
/** * Reads a 64-bit value from memory that may be unaligned. @@ -99,13 +99,14 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) return (u32)fsp; }
-#ifdef __PRE_RAM__ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) { u32 stack_len; u32 stack_base; u32 stack_top;
+ post_code(POST_MRC); + ASSERT(status == 0);
/* Get the migrated stack in normal memory */ @@ -121,7 +122,7 @@ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) ((u32)shared_data - *(u32 *)stack_top));
/* The boot loader main function entry */ - bl_main_continue(hob_list, shared_data); + fsp_init_done(hob_list); }
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) @@ -178,6 +179,8 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) shared_data.fsp_hdr = fsp_hdr; shared_data.stack_top = (u32 *)stack_top;
+ post_code(POST_PRE_MRC); + /* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc @@ -187,11 +190,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) "call *%%eax;" ".global asm_continuation;" "asm_continuation:;" - "popl %%eax;" /* pop out return address */ - "pushl %%ecx;" /* push shared_data pointer */ - "pushl %%eax;" /* push back return address */ + "movl %%ebx, %%eax;" /* shared_data */ + "movl 4(%%esp), %%edx;" /* status */ + "movl 8(%%esp), %%ecx;" /* hob_list */ "jmp fsp_continue;" - : : "m"(params_ptr), "a"(init), "c"(&shared_data) + : : "m"(params_ptr), "a"(init), "b"(&shared_data) );
/* @@ -209,12 +212,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) ASSERT(FALSE); }
-#else - u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) { fsp_notify_f notify; struct fsp_notify_params_t params; + struct fsp_notify_params_t *params_ptr; u32 status;
if (!fsp_hdr) @@ -227,13 +229,22 @@ u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase)
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); params.phase = phase; - status = notify(¶ms); + params_ptr = ¶ms; + + /* + * Use ASM code to ensure correct parameter is on the stack for + * FspNotify as U-Boot is using different ABI from FSP + */ + asm volatile ( + "pushl %1;" /* push notify phase */ + "call *%%eax;" /* call FspNotify */ + "addl $4, %%esp;" /* clean up the stack */ + : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) + );
return status; }
-#endif /* __PRE_RAM__ */ - u32 get_usable_lowmem_top(const void *hob_list) { union hob_pointers_t hob; diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h index 3e53ea1..3296a2b 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h @@ -26,7 +26,7 @@ struct shared_data_t {
void asm_continuation(void);
-void bl_main_continue(void *hob_list, struct shared_data_t *shared_data); +void fsp_init_done(void *hob_list);
/** * FSP Continuation function

Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Use inline assembly codes to call FspNotify() to make sure parameters are passed on the stack as required by the FSP calling convention.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v3:
- Move license header changes to last commit
Changes in v2:
- Update the codes to use U-Boot coding style
arch/x86/cpu/queensbay/fsp_configs.c | 5 ++- arch/x86/cpu/queensbay/fsp_support.c | 39 ++++++++++++++-------- .../include/asm/arch-queensbay/fsp/fsp_support.h | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c index a7bb314..aef18fc 100644 --- a/arch/x86/cpu/queensbay/fsp_configs.c +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -5,9 +5,8 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h>
void update_fsp_upd(struct upd_region_t *fsp_upd) { diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c index 2048030..df3bbd0 100644 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -5,9 +5,9 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/post.h>
/**
- Reads a 64-bit value from memory that may be unaligned.
@@ -99,13 +99,14 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) return (u32)fsp; }
-#ifdef __PRE_RAM__ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) { u32 stack_len; u32 stack_base; u32 stack_top;
post_code(POST_MRC);
ASSERT(status == 0); /* Get the migrated stack in normal memory */
@@ -121,7 +122,7 @@ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) ((u32)shared_data - *(u32 *)stack_top));
/* The boot loader main function entry */
bl_main_continue(hob_list, shared_data);
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) @@ -178,6 +179,8 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) shared_data.fsp_hdr = fsp_hdr; shared_data.stack_top = (u32 *)stack_top;
post_code(POST_PRE_MRC);
/* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc
@@ -187,11 +190,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) "call *%%eax;" ".global asm_continuation;" "asm_continuation:;"
"popl %%eax;" /* pop out return address */
"pushl %%ecx;" /* push shared_data pointer */
"pushl %%eax;" /* push back return address */
"movl %%ebx, %%eax;" /* shared_data */
"movl 4(%%esp), %%edx;" /* status */
"movl 8(%%esp), %%ecx;" /* hob_list */ "jmp fsp_continue;"
: : "m"(params_ptr), "a"(init), "c"(&shared_data)
: : "m"(params_ptr), "a"(init), "b"(&shared_data) ); /*
@@ -209,12 +212,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) ASSERT(FALSE); }
-#else
u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) { fsp_notify_f notify; struct fsp_notify_params_t params;
struct fsp_notify_params_t *params_ptr; u32 status; if (!fsp_hdr)
@@ -227,13 +229,22 @@ u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase)
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); params.phase = phase;
status = notify(¶ms);
params_ptr = ¶ms;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
); return status;
}
-#endif /* __PRE_RAM__ */
u32 get_usable_lowmem_top(const void *hob_list) { union hob_pointers_t hob; diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h index 3e53ea1..3296a2b 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h @@ -26,7 +26,7 @@ struct shared_data_t {
Can we get rid of the _t suffix on these structures? A follow-on patch would be OK if you prefer.
void asm_continuation(void);
-void bl_main_continue(void *hob_list, struct shared_data_t *shared_data); +void fsp_init_done(void *hob_list);
Function comments for these?
Regards, Simon

Hi Simon,
On Sat, Dec 13, 2014 at 2:49 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Use inline assembly codes to call FspNotify() to make sure parameters are passed on the stack as required by the FSP calling convention.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v3:
- Move license header changes to last commit
Changes in v2:
- Update the codes to use U-Boot coding style
arch/x86/cpu/queensbay/fsp_configs.c | 5 ++- arch/x86/cpu/queensbay/fsp_support.c | 39 ++++++++++++++-------- .../include/asm/arch-queensbay/fsp/fsp_support.h | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c index a7bb314..aef18fc 100644 --- a/arch/x86/cpu/queensbay/fsp_configs.c +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -5,9 +5,8 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h>
void update_fsp_upd(struct upd_region_t *fsp_upd) { diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c index 2048030..df3bbd0 100644 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -5,9 +5,9 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/post.h>
/**
- Reads a 64-bit value from memory that may be unaligned.
@@ -99,13 +99,14 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) return (u32)fsp; }
-#ifdef __PRE_RAM__ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) { u32 stack_len; u32 stack_base; u32 stack_top;
post_code(POST_MRC);
ASSERT(status == 0); /* Get the migrated stack in normal memory */
@@ -121,7 +122,7 @@ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) ((u32)shared_data - *(u32 *)stack_top));
/* The boot loader main function entry */
bl_main_continue(hob_list, shared_data);
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) @@ -178,6 +179,8 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) shared_data.fsp_hdr = fsp_hdr; shared_data.stack_top = (u32 *)stack_top;
post_code(POST_PRE_MRC);
/* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc
@@ -187,11 +190,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) "call *%%eax;" ".global asm_continuation;" "asm_continuation:;"
"popl %%eax;" /* pop out return address */
"pushl %%ecx;" /* push shared_data pointer */
"pushl %%eax;" /* push back return address */
"movl %%ebx, %%eax;" /* shared_data */
"movl 4(%%esp), %%edx;" /* status */
"movl 8(%%esp), %%ecx;" /* hob_list */ "jmp fsp_continue;"
: : "m"(params_ptr), "a"(init), "c"(&shared_data)
: : "m"(params_ptr), "a"(init), "b"(&shared_data) ); /*
@@ -209,12 +212,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) ASSERT(FALSE); }
-#else
u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) { fsp_notify_f notify; struct fsp_notify_params_t params;
struct fsp_notify_params_t *params_ptr; u32 status; if (!fsp_hdr)
@@ -227,13 +229,22 @@ u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase)
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); params.phase = phase;
status = notify(¶ms);
params_ptr = ¶ms;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
); return status;
}
-#endif /* __PRE_RAM__ */
u32 get_usable_lowmem_top(const void *hob_list) { union hob_pointers_t hob; diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h index 3e53ea1..3296a2b 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h @@ -26,7 +26,7 @@ struct shared_data_t {
Can we get rid of the _t suffix on these structures? A follow-on patch would be OK if you prefer.
Yes, I will send a follow-on patch.
void asm_continuation(void);
-void bl_main_continue(void *hob_list, struct shared_data_t *shared_data); +void fsp_init_done(void *hob_list);
Function comments for these?
Will be fixed in the follow-on patch.
Regards, Bin

Hi Simon,
On Sat, Dec 13, 2014 at 12:50 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sat, Dec 13, 2014 at 2:49 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Use inline assembly codes to call FspNotify() to make sure parameters are passed on the stack as required by the FSP calling convention.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v3:
- Move license header changes to last commit
Changes in v2:
- Update the codes to use U-Boot coding style
arch/x86/cpu/queensbay/fsp_configs.c | 5 ++- arch/x86/cpu/queensbay/fsp_support.c | 39 ++++++++++++++-------- .../include/asm/arch-queensbay/fsp/fsp_support.h | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c index a7bb314..aef18fc 100644 --- a/arch/x86/cpu/queensbay/fsp_configs.c +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -5,9 +5,8 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h>
void update_fsp_upd(struct upd_region_t *fsp_upd) { diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c index 2048030..df3bbd0 100644 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -5,9 +5,9 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/post.h>
/**
- Reads a 64-bit value from memory that may be unaligned.
@@ -99,13 +99,14 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) return (u32)fsp; }
-#ifdef __PRE_RAM__ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) { u32 stack_len; u32 stack_base; u32 stack_top;
post_code(POST_MRC);
ASSERT(status == 0); /* Get the migrated stack in normal memory */
@@ -121,7 +122,7 @@ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) ((u32)shared_data - *(u32 *)stack_top));
/* The boot loader main function entry */
bl_main_continue(hob_list, shared_data);
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) @@ -178,6 +179,8 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) shared_data.fsp_hdr = fsp_hdr; shared_data.stack_top = (u32 *)stack_top;
post_code(POST_PRE_MRC);
/* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc
@@ -187,11 +190,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) "call *%%eax;" ".global asm_continuation;" "asm_continuation:;"
"popl %%eax;" /* pop out return address */
"pushl %%ecx;" /* push shared_data pointer */
"pushl %%eax;" /* push back return address */
"movl %%ebx, %%eax;" /* shared_data */
"movl 4(%%esp), %%edx;" /* status */
"movl 8(%%esp), %%ecx;" /* hob_list */ "jmp fsp_continue;"
: : "m"(params_ptr), "a"(init), "c"(&shared_data)
: : "m"(params_ptr), "a"(init), "b"(&shared_data) ); /*
@@ -209,12 +212,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) ASSERT(FALSE); }
-#else
u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) { fsp_notify_f notify; struct fsp_notify_params_t params;
struct fsp_notify_params_t *params_ptr; u32 status; if (!fsp_hdr)
@@ -227,13 +229,22 @@ u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase)
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); params.phase = phase;
status = notify(¶ms);
params_ptr = ¶ms;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
); return status;
}
-#endif /* __PRE_RAM__ */
u32 get_usable_lowmem_top(const void *hob_list) { union hob_pointers_t hob; diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h index 3e53ea1..3296a2b 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h @@ -26,7 +26,7 @@ struct shared_data_t {
Can we get rid of the _t suffix on these structures? A follow-on patch would be OK if you prefer.
Yes, I will send a follow-on patch.
void asm_continuation(void);
-void bl_main_continue(void *hob_list, struct shared_data_t *shared_data); +void fsp_init_done(void *hob_list);
Function comments for these?
Will be fixed in the follow-on patch.
These two issues are fixed in the follow-on patch @ http://patchwork.ozlabs.org/patch/420827/
Regards, Bin

On 13 December 2014 at 21:17, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sat, Dec 13, 2014 at 12:50 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sat, Dec 13, 2014 at 2:49 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Use inline assembly codes to call FspNotify() to make sure parameters are passed on the stack as required by the FSP calling convention.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v3:
- Move license header changes to last commit
Changes in v2:
- Update the codes to use U-Boot coding style
arch/x86/cpu/queensbay/fsp_configs.c | 5 ++- arch/x86/cpu/queensbay/fsp_support.c | 39 ++++++++++++++-------- .../include/asm/arch-queensbay/fsp/fsp_support.h | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c index a7bb314..aef18fc 100644 --- a/arch/x86/cpu/queensbay/fsp_configs.c +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -5,9 +5,8 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h>
void update_fsp_upd(struct upd_region_t *fsp_upd) { diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c index 2048030..df3bbd0 100644 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -5,9 +5,9 @@
- SPDX-License-Identifier: Intel
*/
-#include <types.h> -#include <string.h> -#include "fsp_support.h" +#include <common.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/post.h>
/**
- Reads a 64-bit value from memory that may be unaligned.
@@ -99,13 +99,14 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) return (u32)fsp; }
-#ifdef __PRE_RAM__ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) { u32 stack_len; u32 stack_base; u32 stack_top;
post_code(POST_MRC);
ASSERT(status == 0); /* Get the migrated stack in normal memory */
@@ -121,7 +122,7 @@ void fsp_continue(struct shared_data_t *shared_data, u32 status, void *hob_list) ((u32)shared_data - *(u32 *)stack_top));
/* The boot loader main function entry */
bl_main_continue(hob_list, shared_data);
fsp_init_done(hob_list);
}
void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) @@ -178,6 +179,8 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) shared_data.fsp_hdr = fsp_hdr; shared_data.stack_top = (u32 *)stack_top;
post_code(POST_PRE_MRC);
/* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc
@@ -187,11 +190,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) "call *%%eax;" ".global asm_continuation;" "asm_continuation:;"
"popl %%eax;" /* pop out return address */
"pushl %%ecx;" /* push shared_data pointer */
"pushl %%eax;" /* push back return address */
"movl %%ebx, %%eax;" /* shared_data */
"movl 4(%%esp), %%edx;" /* status */
"movl 8(%%esp), %%ecx;" /* hob_list */ "jmp fsp_continue;"
: : "m"(params_ptr), "a"(init), "c"(&shared_data)
: : "m"(params_ptr), "a"(init), "b"(&shared_data) ); /*
@@ -209,12 +212,11 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) ASSERT(FALSE); }
-#else
u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase) { fsp_notify_f notify; struct fsp_notify_params_t params;
struct fsp_notify_params_t *params_ptr; u32 status; if (!fsp_hdr)
@@ -227,13 +229,22 @@ u32 fsp_notify(struct fsp_header_t *fsp_hdr, u32 phase)
notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); params.phase = phase;
status = notify(¶ms);
params_ptr = ¶ms;
/*
* Use ASM code to ensure correct parameter is on the stack for
* FspNotify as U-Boot is using different ABI from FSP
*/
asm volatile (
"pushl %1;" /* push notify phase */
"call *%%eax;" /* call FspNotify */
"addl $4, %%esp;" /* clean up the stack */
: "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
); return status;
}
-#endif /* __PRE_RAM__ */
u32 get_usable_lowmem_top(const void *hob_list) { union hob_pointers_t hob; diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h index 3e53ea1..3296a2b 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h @@ -26,7 +26,7 @@ struct shared_data_t {
Can we get rid of the _t suffix on these structures? A follow-on patch would be OK if you prefer.
Yes, I will send a follow-on patch.
void asm_continuation(void);
-void bl_main_continue(void *hob_list, struct shared_data_t *shared_data); +void fsp_init_done(void *hob_list);
Function comments for these?
Will be fixed in the follow-on patch.
These two issues are fixed in the follow-on patch @ http://patchwork.ozlabs.org/patch/420827/
Applied to u-boot-x86, thanks!

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/include/asm/post.h | 2 ++ 2 files changed, 3 insertions(+)
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index 60976db..969b07b 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -263,6 +263,7 @@ static void enable_usb_bar(void) static int report_bist_failure(void) { if (gd->arch.bist != 0) { + post_code(POST_BIST_FAILURE); printf("BIST failed: %08x\n", gd->arch.bist); return -EFAULT; } diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h index 6d2ae5d..f49ce99 100644 --- a/arch/x86/include/asm/post.h +++ b/arch/x86/include/asm/post.h @@ -33,6 +33,8 @@ #define POST_LAPIC 0x30
#define POST_RAM_FAILURE 0xea +#define POST_BIST_FAILURE 0xeb +#define POST_CAR_FAILURE 0xec
/* Output a post code using al - value must be 0 to 0xff */ #ifdef __ASSEMBLY__

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/cpu/ivybridge/cpu.c | 1 + arch/x86/include/asm/post.h | 2 ++ 2 files changed, 3 insertions(+)
Applied to u-boot-x86, thanks!

Per Intel FSP architecture specification, FSP provides 3 routines for bootloader to call. The first one is the TempRamInit (aka Cache-As-Ram initialization) and the second one is the FspInit which does the memory bring up (like MRC for other x86 targets) and chipset initialization. Those two routines have to be called before U-Boot jumping to board_init_f in start.S.
The FspInit() will return several memory blocks called Hand Off Blocks (HOBs) whose format is described in Platform Initialization (PI) specification (part of the UEFI specication) to the bootloader. Save this HOB address to the U-Boot global data for later use.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Move FspInit call from start.S to car_init
arch/x86/cpu/start.S | 14 ++++++++++++++ arch/x86/include/asm/global_data.h | 3 +++ arch/x86/lib/asm-offsets.c | 3 +++ 3 files changed, 20 insertions(+)
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index f9662fb..125782c 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -75,6 +75,7 @@ early_board_init_ret: jmp car_init .globl car_init_ret car_init_ret: +#ifndef CONFIG_HAVE_FSP /* * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM, * or fully initialised SDRAM - we really don't care which) @@ -95,6 +96,12 @@ car_init_ret: #ifdef CONFIG_DCACHE_RAM_MRC_VAR_SIZE subl $CONFIG_DCACHE_RAM_MRC_VAR_SIZE, %esp #endif +#else + /* + * When we get here after car_init, esp points to a temporary stack + * and esi holds the HOB list address returned by the FSP. + */ +#endif
/* Reserve space on stack for global data */ subl $GENERATED_GBL_DATA_SIZE, %esp @@ -109,6 +116,13 @@ car_init_ret: movl %esp, %edi rep stosb
+#ifdef CONFIG_HAVE_FSP + /* Store HOB list */ + movl %esp, %edx + addl $GD_HOB_LIST, %edx + movl %esi, (%edx) +#endif + /* Setup first parameter to setup_gdt, pointer to global_data */ movl %esp, %eax
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 48bbd1a..03d491a 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -47,6 +47,9 @@ struct arch_global_data { enum pei_boot_mode_t pei_boot_mode; const struct pch_gpio_map *gpio_map; /* board GPIO map */ struct memory_info meminfo; /* Memory information */ +#ifdef CONFIG_HAVE_FSP + void *hob_list; /* FSP HOB list */ +#endif };
#endif diff --git a/arch/x86/lib/asm-offsets.c b/arch/x86/lib/asm-offsets.c index 50a488f..70ccf1b 100644 --- a/arch/x86/lib/asm-offsets.c +++ b/arch/x86/lib/asm-offsets.c @@ -18,5 +18,8 @@ int main(void) { DEFINE(GD_BIST, offsetof(gd_t, arch.bist)); +#ifdef CONFIG_HAVE_FSP + DEFINE(GD_HOB_LIST, offsetof(gd_t, arch.hob_list)); +#endif return 0; }

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
Per Intel FSP architecture specification, FSP provides 3 routines for bootloader to call. The first one is the TempRamInit (aka Cache-As-Ram initialization) and the second one is the FspInit which does the memory bring up (like MRC for other x86 targets) and chipset initialization. Those two routines have to be called before U-Boot jumping to board_init_f in start.S.
The FspInit() will return several memory blocks called Hand Off Blocks (HOBs) whose format is described in Platform Initialization (PI) specification (part of the UEFI specication) to the bootloader. Save this HOB address to the U-Boot global data for later use.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Move FspInit call from start.S to car_init
arch/x86/cpu/start.S | 14 ++++++++++++++ arch/x86/include/asm/global_data.h | 3 +++ arch/x86/lib/asm-offsets.c | 3 +++ 3 files changed, 20 insertions(+)
Applied to u-boot-x86, thanks!

FSP builds a series of data structures called the Hand-Off-Blocks (HOBs) as it progresses through initializing the silicon. These data structures conform to the HOB format as described in the Platform Initialization (PI) specification Volume 3 Shared Architectual Elements specification, which is part of the UEFI specification.
Create a simple command to parse the HOB list to display the HOB address, type and length in bytes.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Use ARRAY_SIZE to indicate the maximum number of HOB tyeps - Remove some unnecessary spaces in the do_hob command output
arch/x86/lib/Makefile | 1 + arch/x86/lib/cmd_hob.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 arch/x86/lib/cmd_hob.c
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 55de788..73262d7 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -10,6 +10,7 @@ obj-y += bios_asm.o obj-y += bios_interrupts.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += cmd_boot.o +obj-$(CONFIG_HAVE_FSP) += cmd_hob.o obj-y += gcc.o obj-y += init_helpers.o obj-y += interrupts.o diff --git a/arch/x86/lib/cmd_hob.c b/arch/x86/lib/cmd_hob.c new file mode 100644 index 0000000..2fdff2b --- /dev/null +++ b/arch/x86/lib/cmd_hob.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <linux/compiler.h> +#include <asm/arch/fsp/fsp_support.h> + +DECLARE_GLOBAL_DATA_PTR; + +static char *hob_type[] = { + "reserved", + "Hand-off", + "Memory Allocation", + "Resource Descriptor", + "GUID Extension", + "Firmware Volumn", + "CPU", + "Memory Pool", + "reserved", + "Firmware Volumn 2", + "Load PEIM Unused", + "UEFI Capsule", +}; + +int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + union hob_pointers_t hob; + u16 type; + char *desc; + int i = 0; + + hob.raw = (u8 *)gd->arch.hob_list; + + printf("HOB list address: 0x%08x\n\n", (unsigned int)hob.raw); + + printf("No. | Address | Type | Length in Bytes\n"); + printf("----|----------|---------------------|----------------\n"); + while (!END_OF_HOB(hob)) { + printf("%-3d | %08x | ", i, (unsigned int)hob.raw); + type = hob.hdr->type; + if (type == HOB_TYPE_UNUSED) + desc = "*Unused*"; + else if (type == HOB_TYPE_EOH) + desc = "**END OF HOB**"; + else if (type >= 0 && type <= ARRAY_SIZE(hob_type)) + desc = hob_type[type]; + else + desc = "!!!Invalid Type!!!"; + printf("%-19s | %-15d\n", desc, hob.hdr->len); + hob.raw = GET_NEXT_HOB(hob); + i++; + } + + return 0; +} + +/* -------------------------------------------------------------------- */ + +U_BOOT_CMD( + hob, 1, 1, do_hob, + "print FSP Hand-Off Block information", + "" +);

On 12 December 2014 at 06:05, Bin Meng bmeng.cn@gmail.com wrote:
FSP builds a series of data structures called the Hand-Off-Blocks (HOBs) as it progresses through initializing the silicon. These data structures conform to the HOB format as described in the Platform Initialization (PI) specification Volume 3 Shared Architectual Elements specification, which is part of the UEFI specification.
Create a simple command to parse the HOB list to display the HOB address, type and length in bytes.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Use ARRAY_SIZE to indicate the maximum number of HOB tyeps
- Remove some unnecessary spaces in the do_hob command output
arch/x86/lib/Makefile | 1 + arch/x86/lib/cmd_hob.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 arch/x86/lib/cmd_hob.c
Applied to u-boot-x86, thanks!

Integrate the processor microcode version 1.05 for Tunnel Creek, CPUID device 20661h.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: None
arch/x86/cpu/queensbay/M0220661105.inc | 1288 ++++++++++++++++++++++++++++++++ 1 file changed, 1288 insertions(+) create mode 100644 arch/x86/cpu/queensbay/M0220661105.inc
diff --git a/arch/x86/cpu/queensbay/M0220661105.inc b/arch/x86/cpu/queensbay/M0220661105.inc new file mode 100644 index 0000000..f2b2b4e --- /dev/null +++ b/arch/x86/cpu/queensbay/M0220661105.inc @@ -0,0 +1,1288 @@ +/* + * Copyright (C) 2013, Intel Corporation + * + * SPDX-License-Identifier: Intel + */ + +/* External Header */ +.long 0x00000001 /* Header Version */ +.long 0x00000105 /* Update Revision */ +.long 0x07182011 /* Date */ +.long 0x00020661 /* Processor Signature */ +.long 0x52558795 /* Checksum */ +.long 0x00000001 /* Loader Revision */ +.long 0x00000002 /* Processor Flags */ +.long 0x000013d0 /* Data Size (excluding headers) */ +.long 0x00001400 /* Total Size (including headers) */ +.long 0x00000000 /* Reserved */ +.long 0x00000000 /* Reserved */ +.long 0x00000000 /* Reserved */ +/* Data */ +.long 0x00000000 +.long 0x000000a1 +.long 0x00020001 +.long 0x00000105 +.long 0x00000019 +.long 0x00050100 +.long 0x20110715 +.long 0x00000401 +.long 0x00000001 +.long 0x00020661 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x00000000 +.long 0x57a55795 +.long 0xe30f7a7d +.long 0x53be2f8e +.long 0x46e3b90d +.long 0xd6005cd3 +.long 0xb734bb21 +.long 0x06642b66 +.long 0x355042a0 +.long 0x0882023d +.long 0x953684cb +.long 0x0abe06ee +.long 0xa7ef1798 +.long 0x160d6cb8 +.long 0x930cf745 +.long 0xafc3fd79 +.long 0xa70df3d5 +.long 0xb0620f46 +.long 0x70048a23 +.long 0xbf95ecf0 +.long 0x76c1b997 +.long 0x5128616d +.long 0xb6b4b969 +.long 0xcc69f71d +.long 0xdf7416e1 +.long 0xdf9a571b +.long 0x50c0bcc8 +.long 0x85e2b3cd +.long 0xc1927532 +.long 0x7a04b6be +.long 0xe56b7f97 +.long 0x524085c4 +.long 0x668bf327 +.long 0xb3eaa54c +.long 0xccde06f8 +.long 0x09b4e42b +.long 0x033b0a46 +.long 0x0f6e2fde +.long 0xb308ce53 +.long 0x93eff03e +.long 0x8830014e +.long 0x5c8a6f22 +.long 0x91d2f757 +.long 0xf70b648d +.long 0x0789998a +.long 0xd84d4640 +.long 0xe5f34e80 +.long 0xf3357e64 +.long 0xd1e2beea +.long 0xc7e95c3a +.long 0x30e57e4d +.long 0xec214356 +.long 0x7e10859e +.long 0x1d5895d5 +.long 0xdeeff6cb +.long 0xed1030ed +.long 0x827e603d +.long 0x6b4b2de3 +.long 0x83ec6fd0 +.long 0xa64092f3 +.long 0x8d9887e4 +.long 0xbefcbedd +.long 0x2111afef +.long 0xcb9abf96 +.long 0x5c79ceac +.long 0x9bf8a57f +.long 0x5d0e44be +.long 0xdca3d3b6 +.long 0x9072d1ca +.long 0x48e73a50 +.long 0x8d0bc804 +.long 0x6aea94d3 +.long 0xc372403e +.long 0x00000011 +.long 0x5de60a0b +.long 0xbd3cc5c6 +.long 0x2d6c2ad5 +.long 0x2f19cc84 +.long 0x7d8e4989 +.long 0x86062789 +.long 0xe00581e6 +.long 0x70a57340 +.long 0x8e8d33d3 +.long 0x52311951 +.long 0x2f186672 +.long 0xfa530598 +.long 0x909cb851 +.long 0x51613bd1 +.long 0x910ae4e6 +.long 0xd897b90a +.long 0x3b440a2d +.long 0x6d563d9d +.long 0xd1020482 +.long 0xcc9fe7db +.long 0x450b5e7c +.long 0x6d2194af +.long 0x507971bf +.long 0xd43d0b52 +.long 0x96336a56 +.long 0x4f796f0b +.long 0xa5eddfc5 +.long 0x020fba71 +.long 0xeda53948 +.long 0xa6e4a439 +.long 0x52c667e5 +.long 0x9749040e +.long 0xfdefa084 +.long 0x7871c609 +.long 0xc815a889 +.long 0x551582ac +.long 0x039371d6 +.long 0x4e962b58 +.long 0xf6533afe +.long 0x8b9b1b24 +.long 0x5754e6c6 +.long 0x0a4e3a62 +.long 0x037d0d59 +.long 0xe17c0ee5 +.long 0x0047ca4b +.long 0xff5e4ff2 +.long 0xd9201b1f +.long 0x7e22e377 +.long 0x5d5e9b69 +.long 0x21f6a59a +.long 0xa0bb08ff +.long 0x16e77cf1 +.long 0xf536530f +.long 0xa755e0bc +.long 0xac9dea8c +.long 0x6cd2098e +.long 0xf0ddc366 +.long 0x6016c7be +.long 0xd28c2475 +.long 0x8dcfaf29 +.long 0xcee5ada5 +.long 0xe5ac8bf6 +.long 0xcd13b563 +.long 0x42a83647 +.long 0xdf80bf4d +.long 0xdffb854e +.long 0x563dce4d +.long 0xdc0f15f2 +.long 0x092723c4 +.long 0x3a3edcff +.long 0x3d2ab792 +.long 0x15e7fc9f +.long 0xd1592968 +.long 0x3ca31b09 +.long 0x29c71d0f +.long 0x24a9292f +.long 0x2924f71d +.long 0x5d36b019 +.long 0xd83c5a2d +.long 0x51736120 +.long 0xf9749010 +.long 0x4a8732f2 +.long 0x6995d740 +.long 0xc6e4db97 +.long 0x4568b6a3 +.long 0xaa2f4da0 +.long 0x969ace6d +.long 0x673c96d4 +.long 0x766f51d4 +.long 0x4db0a064 +.long 0xfedd870b +.long 0x5d30a5d8 +.long 0x67cf7e71 +.long 0x35901877 +.long 0xd42e5440 +.long 0xf10f185a +.long 0x2c2e04b2 +.long 0x9b813966 +.long 0xc356070f +.long 0x70bd39f9 +.long 0xd6e0ef25 +.long 0xe95ab63e +.long 0xd257a039 +.long 0x555659b2 +.long 0xfdb408f8 +.long 0x93052de2 +.long 0x00652576 +.long 0xeee6ee0e +.long 0xcfd19568 +.long 0xa717c19f +.long 0x155f9ed1 +.long 0x85f077f6 +.long 0x0db3cd1e +.long 0x75094d70 +.long 0x2ef49990 +.long 0xb2e01b42 +.long 0xbd4825d0 +.long 0x75e6163a +.long 0x1d058b7d +.long 0x0f48249d +.long 0x326400bc +.long 0xeca94d18 +.long 0xefabd7ba +.long 0xaa589f29 +.long 0xfa49a2c1 +.long 0xf3319d8d +.long 0x17da3ce7 +.long 0x93c91af4 +.long 0xbbd3887b +.long 0x76c649f3 +.long 0x611334b8 +.long 0x01bc691b +.long 0xd2bfe098 +.long 0xd9b81df3 +.long 0x75b249eb +.long 0x3301c4ab +.long 0x01077dfb +.long 0x53f35fcd +.long 0x8debac4e +.long 0x55c5aa67 +.long 0x3b69816d +.long 0x5d551ce8 +.long 0x88367f5d +.long 0x837034d4 +.long 0x1d1b86cd +.long 0xcbf232d3 +.long 0x28001343 +.long 0x511c1a7f +.long 0xf23acee2 +.long 0x6e07f5df +.long 0x3712f26e +.long 0xc4c85ff6 +.long 0x14ff28bd +.long 0xa3490fd7 +.long 0x4992554f +.long 0x3075fed6 +.long 0x4a9be81f +.long 0x7589ccc1 +.long 0xc505d72f +.long 0x773d99f2 +.long 0xdae3f260 +.long 0x443ccae3 +.long 0xb1700fbd +.long 0x103d330d +.long 0xa16a9aa2 +.long 0xd4a6b543 +.long 0x085ad130 +.long 0x4a56f96d +.long 0x5d0409ea +.long 0x5a3fca54 +.long 0x37a0cffb +.long 0x1b4dd66d +.long 0x5c99a8a4 +.long 0xf098421f +.long 0x869a4d3f +.long 0x46e14e92 +.long 0x64f4e3c2 +.long 0x7f7447c2 +.long 0xd7c7f58b +.long 0x5db0f0f8 +.long 0x5f115af6 +.long 0xe5e41a4b +.long 0x87e131e1 +.long 0xc113f7fa +.long 0x6086f85f +.long 0xb01649cd +.long 0xe0288044 +.long 0xca110714 +.long 0x7575e7ff +.long 0xbd40778b +.long 0x95edb682 +.long 0x47964dd9 +.long 0x11c02326 +.long 0x11ba4fd5 +.long 0x0b05a730 +.long 0x6940fe28 +.long 0x7dbfb870 +.long 0x6deb86f7 +.long 0x34b79de3 +.long 0x690629a3 +.long 0xd6e14787 +.long 0x424a8035 +.long 0x60ed261c +.long 0x0f88a830 +.long 0x77a27081 +.long 0x5776d9a1 +.long 0xedb3bc6e +.long 0x89ceb63b +.long 0x1b8c80ff +.long 0x1efd19c9 +.long 0x148b1d91 +.long 0x241af4cb +.long 0x38c7ab82 +.long 0x8e985efb +.long 0x23a18a32 +.long 0xe34691f1 +.long 0x80aa7b58 +.long 0x11e805d1 +.long 0x8993b083 +.long 0x54c59fa2 +.long 0x281a83e3 +.long 0xe78d3f18 +.long 0x6e65f54e +.long 0xaf0b94cc +.long 0xb4f48b93 +.long 0xae7b6290 +.long 0xdb3cfc14 +.long 0x8156e475 +.long 0xb3c112f9 +.long 0x0f8a5b7a +.long 0x2405973b +.long 0x4ad3746a +.long 0xe69fdab3 +.long 0xd83b7a84 +.long 0xd67d4ffc +.long 0x3b7ffd88 +.long 0x154ad7bc +.long 0x36d8fe3a +.long 0xd01ce317 +.long 0xcb6d865d +.long 0x0896b60a +.long 0xfbf034e3 +.long 0xa3d48171 +.long 0x6075c88d +.long 0x6f4dc9d9 +.long 0x912c1c49 +.long 0xd65e29ca +.long 0x79cd8dfb +.long 0x893f4deb +.long 0x711058ec +.long 0xc6eb5704 +.long 0x0b59636b +.long 0x794bde9d +.long 0xaaa0c03d +.long 0x1e8aec41 +.long 0x0eb82afb +.long 0x29c6ad07 +.long 0x4f4a53b8 +.long 0x0139d2d0 +.long 0xda24d0cf +.long 0x3a16c447 +.long 0xbb269dc8 +.long 0x8cc4cae5 +.long 0xbafbc717 +.long 0x2ef492d9 +.long 0x355e6f46 +.long 0x4e3048ce +.long 0xc8834639 +.long 0x7a6b6eef +.long 0x2d24d1b9 +.long 0xbdde61b9 +.long 0xff3d2a43 +.long 0xa71e93a4 +.long 0x0739f0d9 +.long 0xe69c9ec2 +.long 0xc9f4cc4f +.long 0x554523bf +.long 0x71676a0b +.long 0xef299fb2 +.long 0xfd4bdc7e +.long 0x74cf1d78 +.long 0x2010e34a +.long 0x9b2db71a +.long 0xe257c40a +.long 0x091e29f9 +.long 0x184908d4 +.long 0x99d940a5 +.long 0xd3083422 +.long 0xaa39d00b +.long 0x04d90daf +.long 0x016afd9c +.long 0xca6b6c82 +.long 0x6da9418e +.long 0xeec46fa5 +.long 0xfb09756a +.long 0xfce6d25c +.long 0x58a19ab8 +.long 0xf5d3e5b1 +.long 0x5ed0cc92 +.long 0xcb5a5d99 +.long 0x08dcd15e +.long 0xac8d0375 +.long 0x35c87743 +.long 0xd8665d26 +.long 0x6f099236 +.long 0x59ee69cd +.long 0x51f30d31 +.long 0x33317e08 +.long 0x582d9ee8 +.long 0x54d07f13 +.long 0x2b56f300 +.long 0xe504e32a +.long 0x6d31b09d +.long 0xc6ce6868 +.long 0xeccc49b2 +.long 0x902c609f +.long 0x7c5e71d3 +.long 0x628acc3f +.long 0x65e0c1a1 +.long 0xd481425b +.long 0x7efd4d12 +.long 0x6214d2e9 +.long 0x40c9cb77 +.long 0xa5f215f9 +.long 0xfc82df66 +.long 0x567cc6a8 +.long 0x1b464dac +.long 0x52eb6d83 +.long 0x8db4fb95 +.long 0xbdb65434 +.long 0x647a7dd8 +.long 0xb8324de6 +.long 0xa02a4cc4 +.long 0x1f3c213e +.long 0x4db9314d +.long 0x5ebe4046 +.long 0x4b2327e1 +.long 0x5648a59c +.long 0x3f097dac +.long 0x8b50d003 +.long 0x1d12f530 +.long 0x917d346e +.long 0x12237747 +.long 0x6ea28e31 +.long 0x02693fad +.long 0x468759b5 +.long 0x5bb6e38b +.long 0x1dd3bbc8 +.long 0x64156924 +.long 0xe8d277ee +.long 0x4e948135 +.long 0xd5eef8ef +.long 0x6ca89ea2 +.long 0x927459c2 +.long 0x18c1c123 +.long 0x79c01078 +.long 0x47ee66b9 +.long 0x54993e82 +.long 0x0a8c559e +.long 0x129c7574 +.long 0x4e6b3c19 +.long 0x7d594475 +.long 0x8abfc965 +.long 0x63e2f568 +.long 0x9b678c71 +.long 0xba50dcc8 +.long 0x41b85a5f +.long 0x79f5eac3 +.long 0x582307c2 +.long 0x39194862 +.long 0x86e6e7ff +.long 0x15321f20 +.long 0x8edc881d +.long 0x0240fb28 +.long 0xc56ec540 +.long 0x00cebcb7 +.long 0x42502fd5 +.long 0x048e4984 +.long 0x7dfb97cc +.long 0x935e0364 +.long 0xa47834cd +.long 0x0933d615 +.long 0x857be4a9 +.long 0x5fe435e8 +.long 0xb798e59d +.long 0xf769f594 +.long 0x0c9b6856 +.long 0x73911f38 +.long 0x523e8b70 +.long 0x49061fc8 +.long 0x41301112 +.long 0xe2aa9446 +.long 0xc00f0469 +.long 0xf47bbae4 +.long 0x2957dcfa +.long 0x1f3868c1 +.long 0x18f18519 +.long 0x20a70cab +.long 0x990715f0 +.long 0x4a0e6942 +.long 0xe93baf71 +.long 0xb8f32593 +.long 0x96595736 +.long 0xa7dcc14d +.long 0x374c537e +.long 0x210a8301 +.long 0x4fef1e22 +.long 0x22836918 +.long 0x3708a857 +.long 0xd8e23a48 +.long 0x545b90ef +.long 0xde2718e0 +.long 0xf18f9aae +.long 0x7bbe5800 +.long 0xad322605 +.long 0x0bc9f59d +.long 0x7afc63b7 +.long 0x5cc93555 +.long 0x6a91b58e +.long 0xcce5fd75 +.long 0xabeed857 +.long 0xc635cc0d +.long 0x8fc811bf +.long 0x18211469 +.long 0x28c9354f +.long 0x6c066679 +.long 0x4b3bd1b2 +.long 0x346dd0da +.long 0xc7f5d8b5 +.long 0xe611bbe0 +.long 0x5d32368a +.long 0x642d12c1 +.long 0xa5a107cf +.long 0xb1e97cfe +.long 0x4b626b17 +.long 0xfd83e84d +.long 0x4b02a900 +.long 0x71723f3d +.long 0x5d897250 +.long 0x58e13426 +.long 0x359a3c2f +.long 0xd174e395 +.long 0x2865e665 +.long 0x33647647 +.long 0xff05b84c +.long 0x19038fbc +.long 0xa555506d +.long 0xc2e83249 +.long 0x4dbb3fa9 +.long 0xd98bf087 +.long 0x6e70e5f5 +.long 0x0ef49a40 +.long 0x5cdf7e01 +.long 0x714c39c5 +.long 0x6d7bb96f +.long 0x6bdb5d7b +.long 0xfead5602 +.long 0xe237d376 +.long 0x137132a3 +.long 0x29cbb4fb +.long 0x27ca68ea +.long 0x5e866aa7 +.long 0xd32ddb8c +.long 0xbd422690 +.long 0x69227716 +.long 0xaf1e34b2 +.long 0x43a98f85 +.long 0xc9fa87b0 +.long 0x5be87dd1 +.long 0x8a249c3d +.long 0xd0f2dc0b +.long 0x3cc04f87 +.long 0x91259ff1 +.long 0xa9060c19 +.long 0xeac3b5c6 +.long 0x45622b47 +.long 0x01829fdb +.long 0x0d7ad246 +.long 0xfe8f2152 +.long 0x448ce7ec +.long 0x8ae3f63e +.long 0x659bf1fc +.long 0x0c846c53 +.long 0xe863d386 +.long 0x262885aa +.long 0xece317de +.long 0x5bb4c3a9 +.long 0x2a3022d3 +.long 0x2837f048 +.long 0x1ad0602f +.long 0x5267353b +.long 0xd49f868a +.long 0xf4045d05 +.long 0xfb745076 +.long 0xd1c2b5b0 +.long 0x60d35a86 +.long 0xe8c6b60c +.long 0x99cfe95d +.long 0xd3383986 +.long 0xeaaed9d4 +.long 0x86faab0b +.long 0x57fb2c17 +.long 0x4f8f2d97 +.long 0x95ebaee9 +.long 0x97e2cb6a +.long 0x429e45f2 +.long 0x12dd5f41 +.long 0x7be6b284 +.long 0x66d4d247 +.long 0xa485bc44 +.long 0x57b9551a +.long 0x4211d0e4 +.long 0x87a34ebf +.long 0xa2e15156 +.long 0x03471219 +.long 0xb2d1ae8a +.long 0xcd3e1f84 +.long 0x4fccd6c6 +.long 0x65852d1f +.long 0x4ae708ba +.long 0xf4ece568 +.long 0xf45eaf07 +.long 0xa9435add +.long 0x05c78660 +.long 0x45d0ce37 +.long 0xa65cb00f +.long 0x3b9ff335 +.long 0xefcb1eda +.long 0x766daf1d +.long 0xedd78154 +.long 0x85831ec5 +.long 0x1ee105a7 +.long 0x7f2a7d12 +.long 0x10474d65 +.long 0x0e37341a +.long 0xa46e49f8 +.long 0xecb69243 +.long 0x3399202f +.long 0x17b05a9c +.long 0x37b8f7a4 +.long 0xd0a7e033 +.long 0x3506fb98 +.long 0x2a04fcde +.long 0xb5f6a1c7 +.long 0x66771047 +.long 0xbacf6ad0 +.long 0x932aacb8 +.long 0x44ca1ce2 +.long 0x920415f0 +.long 0x012eded4 +.long 0xa5e9d6e0 +.long 0xdfb558a7 +.long 0xc0311c2e +.long 0x954479c4 +.long 0x57c19c3d +.long 0xf7a44af9 +.long 0x555832c2 +.long 0x12dd9dcf +.long 0x11e670aa +.long 0xb804242b +.long 0x387fd875 +.long 0x72f7a6a2 +.long 0x04faab61 +.long 0xb01fb623 +.long 0x7f06f487 +.long 0x99bf5a35 +.long 0x486c4e2c +.long 0xb2a3c82d +.long 0xb5089b11 +.long 0x096d1f3f +.long 0xf0724337 +.long 0x329dd724 +.long 0xbe582bef +.long 0x1cb91a46 +.long 0x7e26311d +.long 0x7e2c1b8b +.long 0x03f1a427 +.long 0xc3c78616 +.long 0x870daf55 +.long 0x3b50c261 +.long 0x7fcafc9f +.long 0x07ddcbc3 +.long 0x3c4f9ad4 +.long 0xc92adc9d +.long 0x2a1b5e33 +.long 0x08fcdcd8 +.long 0x1cf1836e +.long 0x309ede53 +.long 0x7046777b +.long 0x7175a915 +.long 0x66cfca1e +.long 0x20155826 +.long 0x6b49e3ee +.long 0x7481df1f +.long 0x613cdd4d +.long 0xc24f50aa +.long 0x2e79090b +.long 0xc7d1819b +.long 0x955c7610 +.long 0xd1b9e7d3 +.long 0xf938dbef +.long 0x8ed3444c +.long 0x08fdf8aa +.long 0x7c2eb2ce +.long 0x4242c75a +.long 0x2de0ae6b +.long 0x5baa7e5c +.long 0xca5d2627 +.long 0x5e3b4c61 +.long 0x4d879429 +.long 0xa3486d48 +.long 0xf9c44559 +.long 0x43f365e4 +.long 0xde554e93 +.long 0xa2993163 +.long 0xcc227214 +.long 0x160cbb9b +.long 0xf17e7e6a +.long 0xb5e9bcb7 +.long 0x183d4113 +.long 0xaf318262 +.long 0x8cd5d20f +.long 0xa0fbba4c +.long 0xe6fa30a9 +.long 0x23387391 +.long 0xc3996fe0 +.long 0xb7573bda +.long 0xdda9b804 +.long 0x331e4553 +.long 0xfde5fd11 +.long 0xb8bc350e +.long 0xd499573a +.long 0xc0f99338 +.long 0x1d0e9d6b +.long 0xce48d9f8 +.long 0x28663aa3 +.long 0x2d79097d +.long 0x19374bd7 +.long 0xe04dfb0a +.long 0x85a6a5fa +.long 0xacf8f7ec +.long 0x55b834cf +.long 0x4d3b4589 +.long 0xc328f012 +.long 0xfdc3ed45 +.long 0xfc432c79 +.long 0x6249052b +.long 0x929a79b8 +.long 0x618db30a +.long 0x6da7c6a6 +.long 0xbdcd7076 +.long 0x11b578f8 +.long 0xba74349a +.long 0xf0738647 +.long 0xa8bb9873 +.long 0xf50fa14f +.long 0x1c93a1f0 +.long 0x038e93d5 +.long 0x283ca2e9 +.long 0x5b2aea7b +.long 0x22dba8f7 +.long 0xe3e04ab9 +.long 0x8563be2a +.long 0x36ccf20e +.long 0x4475996b +.long 0xf1c48c1e +.long 0x82b1a569 +.long 0xc7b7f954 +.long 0xba6ce58f +.long 0xcc2fc1c7 +.long 0x6598688d +.long 0x11f06e2d +.long 0x40b7a1c6 +.long 0x760aaf66 +.long 0xdd8c0176 +.long 0x77136630 +.long 0x93cf1fcf +.long 0x23640408 +.long 0xc87193df +.long 0x3eec9517 +.long 0xc609eaf5 +.long 0x69de62e4 +.long 0xa178dad7 +.long 0xeba1bdd8 +.long 0x3af57911 +.long 0x6747392b +.long 0xa753a13b +.long 0xd75bc8f9 +.long 0x27c80057 +.long 0x99ac7884 +.long 0x522f0a08 +.long 0xf1181cdd +.long 0x67ea9c57 +.long 0xce565c34 +.long 0x6af16345 +.long 0x745b1afa +.long 0x3e236e0b +.long 0x9abdc7ad +.long 0xf0d2e6be +.long 0xeff349a2 +.long 0x779beacd +.long 0x2ed8aeea +.long 0xa74844cc +.long 0xfbcaf734 +.long 0x44bb2176 +.long 0xebb06549 +.long 0xbfb8d6e6 +.long 0x253b683c +.long 0xfeb5bc33 +.long 0x4962373f +.long 0x67dc405b +.long 0xaaf68b65 +.long 0x0d5d0c7f +.long 0x91455161 +.long 0x3fb83beb +.long 0xdd08e2c2 +.long 0xf2082fe8 +.long 0xe55af76e +.long 0x0dbc119c +.long 0x53059c28 +.long 0x5dce7815 +.long 0x0e5cf0b7 +.long 0xbd5e8c81 +.long 0x9bec66e5 +.long 0x3f5b99c6 +.long 0xc3aa020c +.long 0xb364422b +.long 0x04d3caf9 +.long 0xfb79045b +.long 0x6f8dcef8 +.long 0x8b0dd8b7 +.long 0x23d2a041 +.long 0x7a8aec71 +.long 0x414dd7c9 +.long 0x88595c24 +.long 0x59fc07f6 +.long 0xabb6c7f1 +.long 0x12f72e14 +.long 0x007860bf +.long 0x11591e28 +.long 0x633e9aad +.long 0x8493b587 +.long 0x4cc0bd7e +.long 0x7b86476f +.long 0xac04a3b6 +.long 0xe7659f28 +.long 0x66c85f33 +.long 0xb311eb77 +.long 0xb2250cb7 +.long 0x523db470 +.long 0xc0464d68 +.long 0x9b454009 +.long 0xde9e73de +.long 0x298a430b +.long 0x7ee713b7 +.long 0xb739f571 +.long 0x7b0f2f8b +.long 0x5db98a8d +.long 0xc9e8cd42 +.long 0xd159c208 +.long 0x69da1e02 +.long 0xdc1df82a +.long 0x2830d1c7 +.long 0x20faab05 +.long 0x8b00616a +.long 0x7f5562fc +.long 0xb231d7d6 +.long 0xa3ac80b0 +.long 0xa3e4ca6a +.long 0xbcd233ab +.long 0x77c18379 +.long 0x7d350cdf +.long 0x56b9dcb8 +.long 0x6044219c +.long 0x755db7fe +.long 0x8b463d9b +.long 0x6c10c3d2 +.long 0x8e11bdb1 +.long 0xa8f66df2 +.long 0xd2c4b911 +.long 0xf9571303 +.long 0x128aaff7 +.long 0x6cf2fe70 +.long 0xd5b8d8e5 +.long 0xd86f74f6 +.long 0x6632ccd6 +.long 0x9fe55841 +.long 0xcbbf8fa3 +.long 0xf61fc601 +.long 0xe6c4c744 +.long 0xaab36df2 +.long 0x846dbb46 +.long 0x3545790a +.long 0x72ab5e1d +.long 0xe75d3442 +.long 0x476d7e0c +.long 0x23c2ac8b +.long 0x8d4b33b7 +.long 0x1b959d3d +.long 0xc4aff418 +.long 0x08b70c9c +.long 0x821bb753 +.long 0x50833e60 +.long 0x78f92d6f +.long 0x0f3f6f0c +.long 0xa9bc1e66 +.long 0xd08b7830 +.long 0xc0592998 +.long 0x5113aa50 +.long 0xc1972267 +.long 0x56a790a4 +.long 0x11e9c921 +.long 0x2e177e97 +.long 0x50db4604 +.long 0xc111b749 +.long 0xc7546dbc +.long 0xb4ade00f +.long 0xe40fecc4 +.long 0xb6096dae +.long 0x53fa6c31 +.long 0x8bcc68ba +.long 0xe9db4b10 +.long 0xa33916c3 +.long 0xfb972a81 +.long 0x4b88c6a1 +.long 0x73d484c8 +.long 0x157c05e3 +.long 0xa379e85e +.long 0x6282be5a +.long 0xdebb06b9 +.long 0xbdfc98fd +.long 0x965ce16a +.long 0x0e7ea144 +.long 0x15faac28 +.long 0x2c1245b3 +.long 0x4442dc6d +.long 0x69b35e00 +.long 0xbc38d022 +.long 0x4f6e220d +.long 0x6cedc764 +.long 0xd9b86479 +.long 0x8d665dbc +.long 0x565e1599 +.long 0x1c157999 +.long 0x002a3165 +.long 0x38d37102 +.long 0x93728664 +.long 0xfb260ded +.long 0x025f9ce6 +.long 0x7168fd93 +.long 0x562670f5 +.long 0x2b1cad4f +.long 0x72c2f820 +.long 0x4a968b43 +.long 0xa23fff87 +.long 0x7a530667 +.long 0x09577b43 +.long 0xdd97b76f +.long 0xab9f6785 +.long 0x516bda00 +.long 0x4055ccee +.long 0x1c799829 +.long 0xef406dc3 +.long 0x34e345b5 +.long 0x065ece9a +.long 0x546c9e8a +.long 0xcdd041c3 +.long 0xd4a27814 +.long 0xbd1314b8 +.long 0x721f6080 +.long 0xb950b2a1 +.long 0xcef5b71c +.long 0x0c63adef +.long 0xcc5f3232 +.long 0x4d47e329 +.long 0x43e07a6a +.long 0x30e69e87 +.long 0x558a1edc +.long 0xa894e77a +.long 0x3980e34e +.long 0x7a94f42f +.long 0xb184bb53 +.long 0x7d070b8f +.long 0x3b544caa +.long 0x4384a89a +.long 0x17a031eb +.long 0x835948f3 +.long 0x5c853be5 +.long 0xc6ae176e +.long 0xa6586472 +.long 0x4543cf5a +.long 0x5a5cb9a1 +.long 0x678c6630 +.long 0xc75dfb47 +.long 0xf4bfaf8a +.long 0x01ef944b +.long 0x3162bd07 +.long 0xf3fc4a54 +.long 0x2fcafffd +.long 0x717484ce +.long 0x6ebc0ae9 +.long 0xc13c5ef0 +.long 0xc8a902f6 +.long 0x514b108f +.long 0x07dae31a +.long 0x04fc7dd0 +.long 0x73931d56 +.long 0x33c86c6f +.long 0x892498ac +.long 0xfd8a0f3c +.long 0xd074b9fa +.long 0x5e137e39 +.long 0xb43edb8e +.long 0x09952b45 +.long 0x9d827239 +.long 0x81399e63 +.long 0xc18e751c +.long 0xa58f4211 +.long 0xa78f30e8 +.long 0xb9711d57 +.long 0x2b0ce494 +.long 0x97a3aa1a +.long 0xae8392ce +.long 0x93bb9b59 +.long 0xf74bc051 +.long 0x4fc76b55 +.long 0x99e7e6f6 +.long 0xe09141c3 +.long 0xe6bc065f +.long 0xd1ec639f +.long 0x05794354 +.long 0x50bdf9f8 +.long 0xf6cb82de +.long 0x49991ae1 +.long 0xfa2b319d +.long 0xdbe312e7 +.long 0xc9ab7eb5 +.long 0x68206857 +.long 0x3c2e1cc9 +.long 0xbd4f1e68 +.long 0x5234cd0e +.long 0x483289cc +.long 0x00063ff1 +.long 0x94918a9a +.long 0x29cdc1b4 +.long 0xf2d804d5 +.long 0x8a5b6cee +.long 0x58991c21 +.long 0x309c4f7a +.long 0x08577732 +.long 0x03bf97da +.long 0x575e03f7 +.long 0x47d577be +.long 0x1ecdac37 +.long 0x7577536c +.long 0x52b7638d +.long 0x3c4aec7f +.long 0x9e1d2194 +.long 0x2aebbf60 +.long 0x3071d4eb +.long 0xfc527d74 +.long 0x87f43484 +.long 0xcc9190ac +.long 0x8f228b8f +.long 0xa1967fb7 +.long 0xe9ed1fc2 +.long 0x8a67e2a9 +.long 0x945181bc +.long 0xac77d654 +.long 0xaf1fc166 +.long 0x956566fb +.long 0x73e9e501 +.long 0x0c0d995c +.long 0x25a4cef2 +.long 0xf86f515b +.long 0x8427938c +.long 0x32eb8fd1 +.long 0xd3d3acb5 +.long 0x9ab80317 +.long 0x2c51fb34 +.long 0x8633c80a +.long 0x28578cd5 +.long 0xd68e015c +.long 0xa00809be +.long 0xe9b090d4 +.long 0x2745c90e +.long 0x9914282f +.long 0x23f71d47 +.long 0x08dced03 +.long 0x75d9999b +.long 0x705b5311 +.long 0x8c280258 +.long 0x422d51b3 +.long 0x0d9c5a41 +.long 0x46d1db52 +.long 0xbf590c8b +.long 0xc70c16d8 +.long 0x6eee7de3 +.long 0xcc1152fd +.long 0x4dff3556 +.long 0x9833788d +.long 0x625d1fc1 +.long 0xb473ca54 +.long 0x96dfebc3 +.long 0x83785e83 +.long 0x3731d09c +.long 0x09f7b4e4 +.long 0x866ddedb +.long 0x2d2b562b +.long 0xf50dccfe +.long 0xc25e2a17 +.long 0xb9528b56 +.long 0x7c9542f5 +.long 0x25b338d7 +.long 0xaf9ac449 +.long 0xadc9b46e +.long 0x78493f36 +.long 0xb30c4bac +.long 0xa8dcc84e +.long 0xbac22e7a +.long 0xbc39ff10 +.long 0xd548878b +.long 0x7be6866a +.long 0xb6e2810d +.long 0x38e1bdf4 +.long 0x33932402 +.long 0xcf7a0cab +.long 0x94e8e54c +.long 0xd7da5616 +.long 0x2993c546 +.long 0xa0fe49a8 +.long 0xbe00043d +.long 0xf7c49868 +.long 0x9aff66d8 +.long 0x70b1a584 +.long 0x9e0097c9 +.long 0x6e4f5280 +.long 0xddb50fc8 +.long 0x8101de5b +.long 0xa8c8b00b +.long 0xe4b9a6e5 +.long 0x0a3f75d4 +.long 0xc6f09bda +.long 0x1b04ddd6 +.long 0xf038734c +.long 0x71bd23a2 +.long 0x4a8fb523 +.long 0xdc27e1f6 +.long 0x3d037717 +.long 0x0f7a055b +.long 0xbff08ae0 +.long 0x3270c017 +.long 0x7ff2c3bb +.long 0x8bc96dac +.long 0x122f1e92 +.long 0x6d2332cf +.long 0xa800b76c +.long 0xcce5b4a3 +.long 0x735db6e9 +.long 0x446f7dca +.long 0xf617597b +.long 0x21dd807b +.long 0x457ee85e +.long 0x719f7986 +.long 0x36e06706 +.long 0xcadc978f +.long 0xd9d5bfc4 +.long 0xed7e7390 +.long 0x57a4b541 +.long 0x0163c9c6 +.long 0x953e93f8 +.long 0x56241ce5 +.long 0xf461c600 +.long 0xaa1a0e8a +.long 0x8141aa92 +.long 0x38863f1e +.long 0x4aa181d4 +.long 0x897163af +.long 0xb32f6291 +.long 0x5d865044 +.long 0x31b40242 +.long 0x2b344852 +.long 0x3b71ff01 +.long 0xc55e3be3 +.long 0x56682d91 +.long 0xacb2de10 +.long 0x80c17290 +.long 0xaf92d724 +.long 0xfd5d9ca3 +.long 0x4041c9b4 +.long 0x0420b3fe +.long 0xe8da74a1 +.long 0xfc7dda49 +.long 0x9010dba4 +.long 0x8b992a7d +.long 0x9ba6ebb7 +.long 0x7148829b +.long 0x1dbd5735 +.long 0x9b3da7d3 +.long 0x0b3125f2 +.long 0xf6fc1fad +.long 0x5b075f2d +.long 0xf4e62d59 +.long 0xf438e469 +.long 0xc4cad84e +.long 0x7f949ca7 +.long 0x90955fb9 +.long 0xc9e5edb8 +.long 0x29921c0b +.long 0x0eb3a485 +.long 0x20991465 +.long 0xa8613443 +.long 0x4fda6f18 +.long 0x9770eeba +.long 0xbdc1cad3 +.long 0xa22cc38b +.long 0x12154f91 +.long 0x7894619b +.long 0xc9532a58 +.long 0x004a624e +.long 0xec45e477 +.long 0x5931826f +.long 0x6b76c4a9 +.long 0x28add60d +.long 0xc5adbdfa +.long 0x95fd4b70 +.long 0x56506408 +.long 0x219893e1 +.long 0x620b6576 +.long 0x1a947688 +.long 0x9f2312f8 +.long 0x13ce6928 +.long 0xc792d2a4 +.long 0xfd40baec +.long 0x8ffdd283 +.long 0xc0cc45dd +.long 0xcbb7127c +.long 0xbb200adc +.long 0x4de39b0d +.long 0x9d6ad14d +.long 0x46548325 +.long 0x218c4db9 +.long 0x1080ca97 +.long 0x2493d0dd +.long 0x1fe3ff95 +.long 0xc93661a8 +.long 0x71c58a82 +.long 0x00fca79a +.long 0x8cc42c38 +.long 0x86715f01 +.long 0x0d04fdc3 +.long 0xe0085450 +.long 0x4cc3cd21 +.long 0x596026bd +.long 0x3e672f6e +.long 0x1b3c52e4 +.long 0xb36ba53b +.long 0x3839341c +.long 0x54dfc0ab +.long 0xe8f1a48b +.long 0x92c5d4fb +.long 0x84c878b6 +.long 0xf1e23bff +.long 0x703501ca +.long 0xdf9805fb +.long 0x1dccb93c +.long 0xa38cbae3 +.long 0xeeecd7c3 +.long 0x0b4ae80a +.long 0xc3f0700d +.long 0xff103196

Implement minimum required functions for the basic support to queensbay platform and crownbay board.
Currently the implementation is to call fsp_init() in the car_init(). We may move that call to cpu_init_f() in the future.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v3: - Update to use u-boot coding convention for fsp codes - Use jnz to jump to the car_init error code at the end of tnc_car.S file instead of being in the normal path flow - Add a TODO comment block to document the fsp_init() call - Change label xxx_stack to xxx_romstack - Add a comment block to explain the ROM stack
Changes in v2: - Replace 0xcf9 with macro PORT_RESET from processor.h - Move FspInit call from start.S to car_init - Add UART0_BASE and UART1_BASE to ibmpc.h
arch/x86/cpu/queensbay/Makefile | 9 +++ arch/x86/cpu/queensbay/tnc.c | 48 ++++++++++++++ arch/x86/cpu/queensbay/tnc_car.S | 127 ++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/queensbay/tnc_dram.c | 78 +++++++++++++++++++++++ arch/x86/cpu/queensbay/tnc_pci.c | 61 ++++++++++++++++++ arch/x86/include/asm/ibmpc.h | 3 + board/intel/crownbay/MAINTAINERS | 6 ++ board/intel/crownbay/Makefile | 7 +++ board/intel/crownbay/crownbay.c | 21 +++++++ board/intel/crownbay/start.S | 9 +++ 10 files changed, 369 insertions(+) create mode 100644 arch/x86/cpu/queensbay/Makefile create mode 100644 arch/x86/cpu/queensbay/tnc.c create mode 100644 arch/x86/cpu/queensbay/tnc_car.S create mode 100644 arch/x86/cpu/queensbay/tnc_dram.c create mode 100644 arch/x86/cpu/queensbay/tnc_pci.c create mode 100644 board/intel/crownbay/MAINTAINERS create mode 100644 board/intel/crownbay/Makefile create mode 100644 board/intel/crownbay/crownbay.c create mode 100644 board/intel/crownbay/start.S
diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile new file mode 100644 index 0000000..ace04ca --- /dev/null +++ b/arch/x86/cpu/queensbay/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += tnc_car.o tnc_dram.o tnc.o +obj-y += fsp_configs.o fsp_support.o +obj-$(CONFIG_PCI) += tnc_pci.o diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c new file mode 100644 index 0000000..8b9815f --- /dev/null +++ b/arch/x86/cpu/queensbay/tnc.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/post.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/processor.h> + +int arch_cpu_init(void) +{ + post_code(POST_CPU_INIT); +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(rdtsc()); +#endif + + return x86_cpu_init_f(); +} + +int print_cpuinfo(void) +{ + post_code(POST_CPU_INFO); + return default_print_cpuinfo(); +} + +void reset_cpu(ulong addr) +{ + /* cold reset */ + outb(0x06, PORT_RESET); +} + +void board_final_cleanup(void) +{ + u32 status; + + /* call into FspNotify */ + debug("Calling into FSP (notify phase INIT_PHASE_BOOT): "); + status = fsp_notify(NULL, INIT_PHASE_BOOT); + if (status != FSP_SUCCESS) + debug("fail, error code %x\n", status); + else + debug("OK\n"); + + return; +} diff --git a/arch/x86/cpu/queensbay/tnc_car.S b/arch/x86/cpu/queensbay/tnc_car.S new file mode 100644 index 0000000..6834a64 --- /dev/null +++ b/arch/x86/cpu/queensbay/tnc_car.S @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/post.h> + +.globl car_init +car_init: + /* + * Note: ebp holds the BIST value (built-in self test) so far, but ebp + * will be destroyed through the FSP call, thus we have to test the + * BIST value here before we call into FSP. + */ + test %ebp, %ebp + jz car_init_start + post_code(POST_BIST_FAILURE) + jmp die + +car_init_start: + post_code(POST_CAR_START) + lea find_fsp_header_romstack, %esp + jmp find_fsp_header + +find_fsp_header_ret: + /* EAX points to FSP_INFO_HEADER */ + mov %eax, %ebp + + /* sanity test */ + cmp $CONFIG_FSP_LOCATION, %eax + jb die + + /* calculate TempRamInitEntry address */ + mov 0x30(%ebp), %eax + add 0x1c(%ebp), %eax + + /* call FSP TempRamInitEntry to setup temporary stack */ + lea temp_ram_init_romstack, %esp + jmp *%eax + +temp_ram_init_ret: + addl $4, %esp + cmp $0, %eax + jnz car_init_fail + + post_code(POST_CAR_CPU_CACHE) + + /* + * The FSP TempRamInit initializes the ecx and edx registers to + * point to a temporary but writable memory range (Cache-As-RAM). + * ecx: the start of this temporary memory range, + * edx: the end of this range. + */ + + /* stack grows down from top of CAR */ + movl %edx, %esp + + /* + * TODO: + * + * According to FSP architecture spec, the fsp_init() will not return + * to its caller, instead it requires the bootloader to provide a + * so-called continuation function to pass into the FSP as a parameter + * of fsp_init, and fsp_init() will call that continuation function + * directly. + * + * The call to fsp_init() may need to be moved out of the car_init() + * to cpu_init_f() with the help of some inline assembly codes. + * Note there is another issue that fsp_init() will setup another stack + * using the fsp_init parameter stack_top after DRAM is initialized, + * which means any data on the previous stack (on the CAR) gets lost + * (ie: U-Boot global_data). FSP is supposed to support such scenario, + * however it does not work. This should be revisited in the future. + */ + movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax + xorl %edx, %edx + xorl %ecx, %ecx + call fsp_init + +.global fsp_init_done +fsp_init_done: + /* + * We come here from FspInit with eax pointing to the HOB list. + * Save eax to esi temporarily. + */ + movl %eax, %esi + /* + * Re-initialize the ebp (BIST) to zero, as we already reach here + * which means we passed BIST testing before. + */ + xorl %ebp, %ebp + jmp car_init_ret + +car_init_fail: + post_code(POST_CAR_FAILURE) + +die: + hlt + jmp die + hlt + + /* + * The function call before CAR initialization is tricky. It cannot + * be called using the 'call' instruction but only the 'jmp' with + * the help of a handcrafted stack in the ROM. The stack needs to + * contain the function return address as well as the parameters. + */ + .balign 4 +find_fsp_header_romstack: + .long find_fsp_header_ret + + .balign 4 +temp_ram_init_romstack: + .long temp_ram_init_ret + .long temp_ram_init_params +temp_ram_init_params: + .long ucode_start /* microcode base */ + .long ucode_size /* microcode size */ + .long CONFIG_SYS_MONITOR_BASE /* code region base */ + .long CONFIG_SYS_MONITOR_LEN /* code region size */ + + .balign 4 +ucode_start: + .include "arch/x86/cpu/queensbay/M0220661105.inc" +ucode_size = ( . - ucode_start) diff --git a/arch/x86/cpu/queensbay/tnc_dram.c b/arch/x86/cpu/queensbay/tnc_dram.c new file mode 100644 index 0000000..dbc1710 --- /dev/null +++ b/arch/x86/cpu/queensbay/tnc_dram.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/fsp/fsp_support.h> +#include <asm/e820.h> +#include <asm/post.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + phys_size_t ram_size = 0; + union hob_pointers_t hob; + + hob.raw = gd->arch.hob_list; + while (!END_OF_HOB(hob)) { + if (hob.hdr->type == HOB_TYPE_RES_DESC) { + if (hob.res_desc->type == RES_SYS_MEM || + hob.res_desc->type == RES_MEM_RESERVED) { + ram_size += hob.res_desc->len; + } + } + hob.raw = GET_NEXT_HOB(hob); + } + + gd->ram_size = ram_size; + post_code(POST_DRAM); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; +} + +/* + * 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 get_usable_lowmem_top(gd->arch.hob_list); +} + +unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) +{ + unsigned num_entries = 0; + + union hob_pointers_t hob; + + hob.raw = gd->arch.hob_list; + + while (!END_OF_HOB(hob)) { + if (hob.hdr->type == HOB_TYPE_RES_DESC) { + entries[num_entries].addr = hob.res_desc->phys_start; + entries[num_entries].size = hob.res_desc->len; + + if (hob.res_desc->type == RES_SYS_MEM) + entries[num_entries].type = E820_RAM; + else if (hob.res_desc->type == RES_MEM_RESERVED) + entries[num_entries].type = E820_RESERVED; + } + hob.raw = GET_NEXT_HOB(hob); + num_entries++; + } + + return num_entries; +} diff --git a/arch/x86/cpu/queensbay/tnc_pci.c b/arch/x86/cpu/queensbay/tnc_pci.c new file mode 100644 index 0000000..39bff49 --- /dev/null +++ b/arch/x86/cpu/queensbay/tnc_pci.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <pci.h> +#include <asm/pci.h> +#include <asm/arch/fsp/fsp_support.h> + +DECLARE_GLOBAL_DATA_PTR; + +void board_pci_setup_hose(struct pci_controller *hose) +{ + hose->first_busno = 0; + hose->last_busno = 0; + + /* PCI memory space */ + pci_set_region(hose->regions + 0, + CONFIG_PCI_MEM_BUS, + CONFIG_PCI_MEM_PHYS, + CONFIG_PCI_MEM_SIZE, + PCI_REGION_MEM); + + /* PCI IO space */ + pci_set_region(hose->regions + 1, + CONFIG_PCI_IO_BUS, + CONFIG_PCI_IO_PHYS, + CONFIG_PCI_IO_SIZE, + PCI_REGION_IO); + + pci_set_region(hose->regions + 2, + CONFIG_PCI_PREF_BUS, + CONFIG_PCI_PREF_PHYS, + CONFIG_PCI_PREF_SIZE, + PCI_REGION_PREFETCH); + + pci_set_region(hose->regions + 3, + 0, + 0, + gd->ram_size, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 4; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + u32 status; + + /* call into FspNotify */ + debug("Calling into FSP (notify phase INIT_PHASE_PCI): "); + status = fsp_notify(NULL, INIT_PHASE_PCI); + if (status != FSP_SUCCESS) + debug("fail, error code %x\n", status); + else + debug("OK\n"); + + return 0; +} diff --git a/arch/x86/include/asm/ibmpc.h b/arch/x86/include/asm/ibmpc.h index e6d183b..c3b5187 100644 --- a/arch/x86/include/asm/ibmpc.h +++ b/arch/x86/include/asm/ibmpc.h @@ -18,4 +18,7 @@ #define SYSCTLA 0x92 #define SLAVE_PIC 0xa0
+#define UART0_BASE 0x3f8 +#define UART1_BASE 0x2f8 + #endif diff --git a/board/intel/crownbay/MAINTAINERS b/board/intel/crownbay/MAINTAINERS new file mode 100644 index 0000000..1eb6869 --- /dev/null +++ b/board/intel/crownbay/MAINTAINERS @@ -0,0 +1,6 @@ +INTEL CROWNBAY BOARD +M: Bin Meng bmeng.cn@gmail.com +S: Maintained +F: board/intel/crownbay/ +F: include/configs/crownbay.h +F: configs/crownbay_defconfig diff --git a/board/intel/crownbay/Makefile b/board/intel/crownbay/Makefile new file mode 100644 index 0000000..aeb219b --- /dev/null +++ b/board/intel/crownbay/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += crownbay.o start.o diff --git a/board/intel/crownbay/crownbay.c b/board/intel/crownbay/crownbay.c new file mode 100644 index 0000000..8c6df98 --- /dev/null +++ b/board/intel/crownbay/crownbay.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/ibmpc.h> +#include <asm/pnp_def.h> +#include <smsc_lpc47m.h> + +#define SERIAL_DEV PNP_DEV(0x2e, 4) + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + lpc47m_enable_serial(SERIAL_DEV, UART0_BASE); + + return 0; +} diff --git a/board/intel/crownbay/start.S b/board/intel/crownbay/start.S new file mode 100644 index 0000000..cf92b4c --- /dev/null +++ b/board/intel/crownbay/start.S @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl early_board_init +early_board_init: + jmp early_board_init_ret

Intel Tunnel Creek GPIO register block is compatible with current ich6-gpio driver, except the offset and content of GPIO block base address register in the LPC PCI configuration space are different.
Use u16 instead of u32 to store the 16-bit I/O address of the GPIO registers so that it could support both Ivybridge and Tunnel Creek.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Add a comment to explain we don't need check bit0 in GPIO base address register - Add setup_pch_gpios() in crownbay.c
arch/x86/include/asm/arch-queensbay/gpio.h | 13 +++++++++++++ arch/x86/include/asm/gpio.h | 4 ++-- board/coreboot/coreboot/coreboot.c | 2 +- board/google/chromebook_link/link.c | 2 +- board/intel/crownbay/crownbay.c | 5 +++++ drivers/gpio/intel_ich6_gpio.c | 20 ++++++++++++-------- 6 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 arch/x86/include/asm/arch-queensbay/gpio.h
diff --git a/arch/x86/include/asm/arch-queensbay/gpio.h b/arch/x86/include/asm/arch-queensbay/gpio.h new file mode 100644 index 0000000..ab4e059 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/gpio.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_ + +/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44 + +#endif /* _X86_ARCH_GPIO_H_ */ diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h index 1787e52..1099427 100644 --- a/arch/x86/include/asm/gpio.h +++ b/arch/x86/include/asm/gpio.h @@ -11,7 +11,7 @@ #include <asm-generic/gpio.h>
struct ich6_bank_platdata { - uint32_t base_addr; + uint16_t base_addr; const char *bank_name; };
@@ -147,7 +147,7 @@ struct pch_gpio_map { } set3; };
-void setup_pch_gpios(u32 gpiobase, const struct pch_gpio_map *gpio); +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio); void ich_gpio_set_gpio_map(const struct pch_gpio_map *map);
#endif /* _X86_GPIO_H_ */ diff --git a/board/coreboot/coreboot/coreboot.c b/board/coreboot/coreboot/coreboot.c index b260f9a..154faf6 100644 --- a/board/coreboot/coreboot/coreboot.c +++ b/board/coreboot/coreboot/coreboot.c @@ -16,7 +16,7 @@ int arch_early_init_r(void) return 0; }
-void setup_pch_gpios(u32 gpiobase, const struct pch_gpio_map *gpio) +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) { return; } diff --git a/board/google/chromebook_link/link.c b/board/google/chromebook_link/link.c index 4d95c1c..9978e92 100644 --- a/board/google/chromebook_link/link.c +++ b/board/google/chromebook_link/link.c @@ -125,7 +125,7 @@ int board_early_init_f(void) return 0; }
-void setup_pch_gpios(u32 gpiobase, const struct pch_gpio_map *gpio) +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) { /* GPIO Set 1 */ if (gpio->set1.level) diff --git a/board/intel/crownbay/crownbay.c b/board/intel/crownbay/crownbay.c index 8c6df98..54670d3 100644 --- a/board/intel/crownbay/crownbay.c +++ b/board/intel/crownbay/crownbay.c @@ -19,3 +19,8 @@ int board_early_init_f(void)
return 0; } + +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) +{ + return; +} diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c index 1f0d9df..5f67b3f 100644 --- a/drivers/gpio/intel_ich6_gpio.c +++ b/drivers/gpio/intel_ich6_gpio.c @@ -39,9 +39,9 @@
struct ich6_bank_priv { /* These are I/O addresses */ - uint32_t use_sel; - uint32_t io_sel; - uint32_t lvl; + uint16_t use_sel; + uint16_t io_sel; + uint16_t lvl; };
/* TODO: Move this to device tree, or platform data */ @@ -57,7 +57,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) u8 tmpbyte; u16 tmpword; u32 tmplong; - u32 gpiobase; + u16 gpiobase; int offset;
/* Where should it be? */ @@ -116,11 +116,15 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) /* * GPIOBASE moved to its current offset with ICH6, but prior to * that it was unused (or undocumented). Check that it looks - * okay: not all ones or zeros, and mapped to I/O space (bit 0). + * okay: not all ones or zeros. + * + * Note we don't need check bit0 here, because the Tunnel Creek + * GPIO base address register bit0 is reserved (read returns 0), + * while on the Ivybridge the bit0 is used to indicate it is an + * I/O space. */ tmplong = pci_read_config32(pci_dev, PCI_CFG_GPIOBASE); - if (tmplong == 0x00000000 || tmplong == 0xffffffff || - !(tmplong & 0x00000001)) { + if (tmplong == 0x00000000 || tmplong == 0xffffffff) { debug("%s: unexpected GPIOBASE value\n", __func__); return -ENODEV; } @@ -131,7 +135,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) * at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong & 0xfffffffe; + gpiobase = tmplong & 0xfffe; offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); if (offset == -1) { debug("%s: Invalid register offset %d\n", __func__, offset);

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/cpu/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 7f09db5..5033d2b 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -15,6 +15,7 @@ obj-y += interrupts.o cpu.o call64.o obj-$(CONFIG_SYS_COREBOOT) += coreboot/ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ +obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/ obj-y += lapic.o obj-$(CONFIG_PCI) += pci.o obj-y += turbo.o

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Fix several typos in queensbay/Kconfig - Change FSP_FILE and CMC_FILE description to indicate the file is in the board directory - Add help for FSP_TEMP_RAM_ADDR - Add more help for CMC_FILE
arch/x86/Kconfig | 13 +++++++ arch/x86/cpu/queensbay/Kconfig | 79 ++++++++++++++++++++++++++++++++++++++++++ board/intel/crownbay/Kconfig | 20 +++++++++++ 3 files changed, 112 insertions(+) create mode 100644 arch/x86/cpu/queensbay/Kconfig create mode 100644 board/intel/crownbay/Kconfig
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index fdfb618..ebf72b3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -32,6 +32,15 @@ config TARGET_CHROMEBOOK_LINK and it provides a 2560x1700 high resolution touch-enabled LCD display.
+config TARGET_CROWNBAY + bool "Support Intel Crown Bay CRB" + help + This is the Intel Crown Bay Customer Reference Board. It contains + the Intel Atom Processor E6xx populated on the COM Express module + with 1GB DDR2 soldered down memory and a carrier board with the + Intel Platform Controller Hub EG20T, other system components and + peripheral connectors for PCIe/SATA/USB/LAN/SD/UART/Audio/LVDS. + endchoice
config RAMBASE @@ -310,8 +319,12 @@ endmenu
source "arch/x86/cpu/ivybridge/Kconfig"
+source "arch/x86/cpu/queensbay/Kconfig" + source "board/coreboot/coreboot/Kconfig"
source "board/google/chromebook_link/Kconfig"
+source "board/intel/crownbay/Kconfig" + endmenu diff --git a/arch/x86/cpu/queensbay/Kconfig b/arch/x86/cpu/queensbay/Kconfig new file mode 100644 index 0000000..56fe85c --- /dev/null +++ b/arch/x86/cpu/queensbay/Kconfig @@ -0,0 +1,79 @@ +# +# Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +config INTEL_QUEENSBAY + bool + select HAVE_FSP + select HAVE_CMC + +if INTEL_QUEENSBAY + +config HAVE_FSP + bool "Add an Firmware Support Package binary" + help + Select this option to add an Firmware Support Package binary to + the resulting U-Boot image. It is a binary blob which U-Boot uses + to set up SDRAM and other chipset specific initialization. + + Note: Without this binary U-Boot will not be able to set up its + SDRAM so will not boot. + +config FSP_FILE + string "Firmware Support Package binary filename" + depends on HAVE_FSP + default "fsp.bin" + help + The filename of the file to use as Firmware Support Package binary + in the board directory. + +config FSP_LOCATION + hex "Firmware Support Package binary location" + depends on HAVE_FSP + default 0xfffc0000 + help + FSP is not Position Independent Code (PIC) and the whole FSP has to + be rebased if it is placed at a location which is different from the + perferred base address specified during the FSP build. Use Intel's + Binary Configuration Tool (BCT) to do the rebase. + + The default base address of 0xfffc0000 indicates that the binary must + be located at offset 0xc0000 from the beginning of a 1MB flash device. + +config FSP_TEMP_RAM_ADDR + hex + default 0x2000000 + help + Stack top address which is used in FspInit after DRAM is ready and + CAR is disabled. + +config HAVE_CMC + bool "Add a Chipset Micro Code state machine binary" + help + Select this option to add a Chipset Micro Code state machine binary + to the resulting U-Boot image. It is a 64K data block of machine + specific code which must be put in the flash for the processor to + access when powered up before system BIOS is executed. + +config CMC_FILE + string "Chipset Micro Code state machine filename" + depends on HAVE_CMC + default "cmc.bin" + help + The filename of the file to use as Chipset Micro Code state machine + binary in the board directory. + +config CMC_LOCATION + hex "Chipset Micro Code state machine binary location" + depends on HAVE_CMC + default 0xfffb0000 + help + The location of the CMC binary is determined by a strap. It must be + put in flash at a location matching the strap-determined base address. + + The default base address of 0xfffb0000 indicates that the binary must + be located at offset 0xb0000 from the beginning of a 1MB flash device. + +endif diff --git a/board/intel/crownbay/Kconfig b/board/intel/crownbay/Kconfig new file mode 100644 index 0000000..4709f9b --- /dev/null +++ b/board/intel/crownbay/Kconfig @@ -0,0 +1,20 @@ +if TARGET_CROWNBAY + +config SYS_BOARD + default "crownbay" + +config SYS_VENDOR + default "intel" + +config SYS_SOC + default "queensbay" + +config SYS_CONFIG_NAME + default "crownbay" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select INTEL_QUEENSBAY + select BOARD_ROMSIZE_KB_1024 + +endif

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
configs/crownbay_defconfig | 6 ++++++ include/configs/crownbay.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 configs/crownbay_defconfig create mode 100644 include/configs/crownbay.h
diff --git a/configs/crownbay_defconfig b/configs/crownbay_defconfig new file mode 100644 index 0000000..ce90553 --- /dev/null +++ b/configs/crownbay_defconfig @@ -0,0 +1,6 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff00000" +CONFIG_X86=y +CONFIG_TARGET_CROWNBAY=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="crownbay" diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h new file mode 100644 index 0000000..2314e62 --- /dev/null +++ b/include/configs/crownbay.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <configs/x86-common.h> + +#define CONFIG_SYS_MONITOR_LEN (1 << 20) +#define CONFIG_SYS_X86_START16 0xfffff800 +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_X86_RESET_VECTOR +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_COREBOOT_SERIAL +#define CONFIG_SMSC_LPC47M + +#define CONFIG_PCI_MEM_BUS 0x40000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x80000000 + +#define CONFIG_PCI_PREF_BUS 0xc0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x20000000 + +#define CONFIG_PCI_IO_BUS 0x2000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xe000 + +#define CONFIG_SYS_EARLY_PCI_INIT +#define CONFIG_PCI_PNP + +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" + +#define CONFIG_SCSI_DEV_LIST \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SATA} + +/* Video is not supported */ +#undef CONFIG_VIDEO +#undef CONFIG_CFB_CONSOLE + +#endif /* __CONFIG_H */

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - New patch to use consistent name XXX_ADDR for binary blobs
Makefile | 2 +- arch/x86/cpu/ivybridge/sdram.c | 2 +- arch/x86/cpu/queensbay/Kconfig | 4 ++-- arch/x86/cpu/queensbay/fsp_support.c | 2 +- arch/x86/cpu/queensbay/tnc_car.S | 2 +- include/configs/chromebook_link.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile index c9ae77b..ff4c4aa 100644 --- a/Makefile +++ b/Makefile @@ -973,7 +973,7 @@ IFDTOOL_ME_FLAGS += -i ME:$(srctree)/board/$(BOARDDIR)/me.bin endif
ifneq ($(CONFIG_HAVE_MRC),) -IFDTOOL_FLAGS += -w $(CONFIG_X86_MRC_START):$(srctree)/board/$(BOARDDIR)/mrc.bin +IFDTOOL_FLAGS += -w $(CONFIG_X86_MRC_ADDR):$(srctree)/board/$(BOARDDIR)/mrc.bin endif
ifneq ($(CONFIG_X86_OPTION_ROM_ADDR),) diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index df2b990..b95e781 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -177,7 +177,7 @@ int sdram_initialise(struct pei_data *pei_data)
debug("PEI data at %p, size %x:\n", pei_data, sizeof(*pei_data));
- data = (char *)CONFIG_X86_MRC_START; + data = (char *)CONFIG_X86_MRC_ADDR; if (data) { int rv; int (*func)(struct pei_data *); diff --git a/arch/x86/cpu/queensbay/Kconfig b/arch/x86/cpu/queensbay/Kconfig index 56fe85c..f6b5201 100644 --- a/arch/x86/cpu/queensbay/Kconfig +++ b/arch/x86/cpu/queensbay/Kconfig @@ -29,7 +29,7 @@ config FSP_FILE The filename of the file to use as Firmware Support Package binary in the board directory.
-config FSP_LOCATION +config FSP_ADDR hex "Firmware Support Package binary location" depends on HAVE_FSP default 0xfffc0000 @@ -65,7 +65,7 @@ config CMC_FILE The filename of the file to use as Chipset Micro Code state machine binary in the board directory.
-config CMC_LOCATION +config CMC_ADDR hex "Chipset Micro Code state machine binary location" depends on HAVE_CMC default 0xfffb0000 diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c index df3bbd0..f830eeb 100644 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ b/arch/x86/cpu/queensbay/fsp_support.c @@ -64,7 +64,7 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) volatile register u8 *fsp asm("eax");
/* Initalize the FSP base */ - fsp = (u8 *)CONFIG_FSP_LOCATION; + fsp = (u8 *)CONFIG_FSP_ADDR;
/* Check the FV signature, _FVH */ if (((struct fv_header_t *)fsp)->sign == 0x4856465F) { diff --git a/arch/x86/cpu/queensbay/tnc_car.S b/arch/x86/cpu/queensbay/tnc_car.S index 6834a64..ce001ed 100644 --- a/arch/x86/cpu/queensbay/tnc_car.S +++ b/arch/x86/cpu/queensbay/tnc_car.S @@ -29,7 +29,7 @@ find_fsp_header_ret: mov %eax, %ebp
/* sanity test */ - cmp $CONFIG_FSP_LOCATION, %eax + cmp $CONFIG_FSP_ADDR, %eax jb die
/* calculate TempRamInitEntry address */ diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 645b31c..c9d84e4 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -25,7 +25,7 @@
#define CONFIG_X86_RESET_VECTOR #define CONFIG_NR_DRAM_BANKS 8 -#define CONFIG_X86_MRC_START 0xfffa0000 +#define CONFIG_X86_MRC_ADDR 0xfffa0000 #define CONFIG_CACHE_MRC_SIZE_KB 512
#define CONFIG_COREBOOT_SERIAL

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Update ifdtool flags to indicate FSP and CMC files are in the board directory - Use consistent XXX_FILE name for binary blob file
Makefile | 10 +++++++++- include/configs/chromebook_link.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile index ff4c4aa..81d27cf 100644 --- a/Makefile +++ b/Makefile @@ -976,8 +976,16 @@ ifneq ($(CONFIG_HAVE_MRC),) IFDTOOL_FLAGS += -w $(CONFIG_X86_MRC_ADDR):$(srctree)/board/$(BOARDDIR)/mrc.bin endif
+ifneq ($(CONFIG_HAVE_FSP),) +IFDTOOL_FLAGS += -w $(CONFIG_FSP_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_FSP_FILE) +endif + +ifneq ($(CONFIG_HAVE_CMC),) +IFDTOOL_FLAGS += -w $(CONFIG_CMC_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_CMC_FILE) +endif + ifneq ($(CONFIG_X86_OPTION_ROM_ADDR),) -IFDTOOL_FLAGS += -w $(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILENAME) +IFDTOOL_FLAGS += -w $(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILE) endif
quiet_cmd_ifdtool = IFDTOOL $@ diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index c9d84e4..b311f4c 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -39,7 +39,7 @@ {PCI_VENDOR_ID_INTEL, \ PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}
-#define CONFIG_X86_OPTION_ROM_FILENAME pci8086,0166.bin +#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin #define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000 #define CONFIG_VIDEO_X86

The Crown Bay board has an SST25VF016B flash connected to the Tunnel Creek processor SPI controller used as the BIOS media where U-Boot is stored. Enable this flash support.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: - Add a commit message for the SPI support
Changes in v2: - Move PCH_LPC_DEV to arch/x86/include/asm/arch-queensbay/tnc.h - Check return value of x86_cpu_init_f()
arch/x86/cpu/queensbay/tnc.c | 26 +++++++++++++++++++++++++- arch/x86/include/asm/arch-queensbay/tnc.h | 15 +++++++++++++++ include/configs/crownbay.h | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/arch-queensbay/tnc.h
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 8b9815f..8637cdc 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -6,18 +6,42 @@
#include <common.h> #include <asm/io.h> +#include <asm/pci.h> #include <asm/post.h> +#include <asm/arch/tnc.h> #include <asm/arch/fsp/fsp_support.h> #include <asm/processor.h>
+static void unprotect_spi_flash(void) +{ + u32 bc; + + bc = pci_read_config32(PCH_LPC_DEV, 0xd8); + bc |= 0x1; /* unprotect the flash */ + pci_write_config32(PCH_LPC_DEV, 0xd8, bc); +} + int arch_cpu_init(void) { + struct pci_controller *hose; + int ret; + post_code(POST_CPU_INIT); #ifdef CONFIG_SYS_X86_TSC_TIMER timer_set_base(rdtsc()); #endif
- return x86_cpu_init_f(); + ret = x86_cpu_init_f(); + if (ret) + return ret; + + ret = pci_early_init_hose(&hose); + if (ret) + return ret; + + unprotect_spi_flash(); + + return 0; }
int print_cpuinfo(void) diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h new file mode 100644 index 0000000..67c5e05 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/tnc.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_TNC_H_ +#define _X86_ARCH_TNC_H_ + +#include <pci.h> + +/* PCI Configuration Space (D31:F0): LPC */ +#define PCH_LPC_DEV PCI_BDF(0, 0x1f, 0) + +#endif /* _X86_ARCH_TNC_H_ */ diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 2314e62..a051b11 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -45,6 +45,8 @@ #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SATA}
+#define CONFIG_SPI_FLASH_SST + /* Video is not supported */ #undef CONFIG_VIDEO #undef CONFIG_CFB_CONSOLE

On 12 December 2014 at 18:35, Bin Meng bmeng.cn@gmail.com wrote:
The Crown Bay board has an SST25VF016B flash connected to the Tunnel Creek processor SPI controller used as the BIOS media where U-Boot is stored. Enable this flash support.
Is this necessary to enable flash at BIOS media?
How about other flash media's, is this specific to x86 cpu to store u-boot always in spi flash.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add a commit message for the SPI support
Changes in v2:
- Move PCH_LPC_DEV to arch/x86/include/asm/arch-queensbay/tnc.h
- Check return value of x86_cpu_init_f()
arch/x86/cpu/queensbay/tnc.c | 26 +++++++++++++++++++++++++- arch/x86/include/asm/arch-queensbay/tnc.h | 15 +++++++++++++++ include/configs/crownbay.h | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/arch-queensbay/tnc.h
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 8b9815f..8637cdc 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -6,18 +6,42 @@
#include <common.h> #include <asm/io.h> +#include <asm/pci.h> #include <asm/post.h> +#include <asm/arch/tnc.h> #include <asm/arch/fsp/fsp_support.h> #include <asm/processor.h>
+static void unprotect_spi_flash(void) +{
u32 bc;
bc = pci_read_config32(PCH_LPC_DEV, 0xd8);
bc |= 0x1; /* unprotect the flash */
pci_write_config32(PCH_LPC_DEV, 0xd8, bc);
+}
int arch_cpu_init(void) {
struct pci_controller *hose;
int ret;
post_code(POST_CPU_INIT);
#ifdef CONFIG_SYS_X86_TSC_TIMER timer_set_base(rdtsc()); #endif
return x86_cpu_init_f();
ret = x86_cpu_init_f();
if (ret)
return ret;
ret = pci_early_init_hose(&hose);
if (ret)
return ret;
unprotect_spi_flash();
return 0;
}
int print_cpuinfo(void) diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h new file mode 100644 index 0000000..67c5e05 --- /dev/null +++ b/arch/x86/include/asm/arch-queensbay/tnc.h @@ -0,0 +1,15 @@ +/*
- Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _X86_ARCH_TNC_H_ +#define _X86_ARCH_TNC_H_
+#include <pci.h>
+/* PCI Configuration Space (D31:F0): LPC */ +#define PCH_LPC_DEV PCI_BDF(0, 0x1f, 0)
+#endif /* _X86_ARCH_TNC_H_ */ diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 2314e62..a051b11 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -45,6 +45,8 @@ #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SATA}
+#define CONFIG_SPI_FLASH_SST
/* Video is not supported */ #undef CONFIG_VIDEO
#undef CONFIG_CFB_CONSOLE
1.8.2.1
thanks!

Hi Jagan,
On Thu, Dec 18, 2014 at 3:06 PM, Jagan Teki jagannadh.teki@gmail.com wrote:
On 12 December 2014 at 18:35, Bin Meng bmeng.cn@gmail.com wrote:
The Crown Bay board has an SST25VF016B flash connected to the Tunnel Creek processor SPI controller used as the BIOS media where U-Boot is stored. Enable this flash support.
Is this necessary to enable flash at BIOS media?
Yes, so that we can use 'sf probe/erase/read/write' command from U-Boot shell.
How about other flash media's, is this specific to x86 cpu to store u-boot always in spi flash.
Do you mean NOR/NAND? Modern x86 boards always have the SPI flash as its BIOS media. Normally there is no NOR/NAND flash on x86 boards.
[snip]
Regards, Bin

On 18 December 2014 at 12:48, Bin Meng bmeng.cn@gmail.com wrote:
Hi Jagan,
On Thu, Dec 18, 2014 at 3:06 PM, Jagan Teki jagannadh.teki@gmail.com wrote:
On 12 December 2014 at 18:35, Bin Meng bmeng.cn@gmail.com wrote:
The Crown Bay board has an SST25VF016B flash connected to the Tunnel Creek processor SPI controller used as the BIOS media where U-Boot is stored. Enable this flash support.
Is this necessary to enable flash at BIOS media?
Yes, so that we can use 'sf probe/erase/read/write' command from U-Boot shell.
How about other flash media's, is this specific to x86 cpu to store u-boot always in spi flash.
Do you mean NOR/NAND? Modern x86 boards always have the SPI flash as its BIOS media. Normally there is no NOR/NAND flash on x86 boards.
Ok.
Reviewed-by: Jagannadha Sutradharudu Teki jagannadh.teki@gmail.com
thanks!

We don't have driver for the Intel Topcliff PCH Gigabit Ethernet controller for now, so enable the Intle E1000 NIC support, which can be plugged into any PCIe slot on the Crown Bay board.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
board/intel/crownbay/crownbay.c | 6 ++++++ include/configs/crownbay.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/board/intel/crownbay/crownbay.c b/board/intel/crownbay/crownbay.c index 54670d3..2a254ef 100644 --- a/board/intel/crownbay/crownbay.c +++ b/board/intel/crownbay/crownbay.c @@ -7,6 +7,7 @@ #include <common.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> +#include <netdev.h> #include <smsc_lpc47m.h>
#define SERIAL_DEV PNP_DEV(0x2e, 4) @@ -24,3 +25,8 @@ void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) { return; } + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index a051b11..09a52ab 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -37,6 +37,7 @@
#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP +#define CONFIG_E1000
#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ "stdout=serial\0" \

There are two standard SD card slots on the Crown Bay board, which are connected to the Topcliff PCH SDIO controllers. Enable the SDHC support so that we can use them.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Use ARRAY_SIZE(mmc_supported) instead of 2 - Check return value of add_sdhci()
arch/x86/cpu/queensbay/Makefile | 2 +- arch/x86/cpu/queensbay/topcliff.c | 47 +++++++++++++++++++++++++++++++++++++++ include/configs/crownbay.h | 6 +++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/queensbay/topcliff.c
diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile index ace04ca..2c2ec01 100644 --- a/arch/x86/cpu/queensbay/Makefile +++ b/arch/x86/cpu/queensbay/Makefile @@ -4,6 +4,6 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y += tnc_car.o tnc_dram.o tnc.o +obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o obj-y += fsp_configs.o fsp_support.o obj-$(CONFIG_PCI) += tnc_pci.o diff --git a/arch/x86/cpu/queensbay/topcliff.c b/arch/x86/cpu/queensbay/topcliff.c new file mode 100644 index 0000000..b01422a --- /dev/null +++ b/arch/x86/cpu/queensbay/topcliff.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <pci.h> +#include <pci_ids.h> +#include <sdhci.h> + +static struct pci_device_id mmc_supported[] = { + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 }, + { } +}; + +int cpu_mmc_init(bd_t *bis) +{ + struct sdhci_host *mmc_host; + pci_dev_t devbusfn; + u32 iobase; + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(mmc_supported); i++) { + devbusfn = pci_find_devices(mmc_supported, i); + if (devbusfn == -1) + return -ENODEV; + + mmc_host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); + if (!mmc_host) + return -ENOMEM; + + mmc_host->name = "Topcliff SDHCI"; + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase); + mmc_host->ioaddr = (void *)iobase; + mmc_host->quirks = 0; + ret = add_sdhci(mmc_host, 0, 0); + if (ret) + return ret; + } + + return 0; +} diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 09a52ab..b9db6b7 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -48,6 +48,12 @@
#define CONFIG_SPI_FLASH_SST
+#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC_SDMA +#define CONFIG_CMD_MMC + /* Video is not supported */ #undef CONFIG_VIDEO #undef CONFIG_CFB_CONSOLE

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - New patch to rename coreboot-serial to x86-serial
arch/x86/dts/coreboot.dtsi | 2 +- drivers/serial/Makefile | 2 +- drivers/serial/{serial_coreboot.c => serial_x86.c} | 12 ++++++------ include/configs/chromebook_link.h | 2 +- include/configs/coreboot.h | 2 +- include/configs/crownbay.h | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) rename drivers/serial/{serial_coreboot.c => serial_x86.c} (67%)
diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi index c8dc4ce..65a93ac 100644 --- a/arch/x86/dts/coreboot.dtsi +++ b/arch/x86/dts/coreboot.dtsi @@ -6,7 +6,7 @@ };
serial { - compatible = "coreboot-uart"; + compatible = "x86-uart"; reg = <0x3f8 0x10>; reg-shift = <0>; io-mapped = <1>; diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8c84942..4cc00cd 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_ARC_SERIAL) += serial_arc.o obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o -obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o +obj-$(CONFIG_X86_SERIAL) += serial_x86.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_x86.c similarity index 67% rename from drivers/serial/serial_coreboot.c rename to drivers/serial/serial_x86.c index 5c6a76c..e81e035 100644 --- a/drivers/serial/serial_coreboot.c +++ b/drivers/serial/serial_x86.c @@ -9,12 +9,12 @@ #include <ns16550.h> #include <serial.h>
-static const struct udevice_id coreboot_serial_ids[] = { - { .compatible = "coreboot-uart" }, +static const struct udevice_id x86_serial_ids[] = { + { .compatible = "x86-uart" }, { } };
-static int coreboot_serial_ofdata_to_platdata(struct udevice *dev) +static int x86_serial_ofdata_to_platdata(struct udevice *dev) { struct ns16550_platdata *plat = dev_get_platdata(dev); int ret; @@ -27,10 +27,10 @@ static int coreboot_serial_ofdata_to_platdata(struct udevice *dev) return 0; } U_BOOT_DRIVER(serial_ns16550) = { - .name = "serial_coreboot", + .name = "serial_x86", .id = UCLASS_SERIAL, - .of_match = coreboot_serial_ids, - .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata, + .of_match = x86_serial_ids, + .ofdata_to_platdata = x86_serial_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), .priv_auto_alloc_size = sizeof(struct NS16550), .probe = ns16550_serial_probe, diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index b311f4c..8930210 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -28,7 +28,7 @@ #define CONFIG_X86_MRC_ADDR 0xfffa0000 #define CONFIG_CACHE_MRC_SIZE_KB 512
-#define CONFIG_COREBOOT_SERIAL +#define CONFIG_X86_SERIAL
#define CONFIG_SCSI_DEV_LIST {PCI_VENDOR_ID_INTEL, \ PCI_DEVICE_ID_INTEL_NM10_AHCI}, \ diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index 2581380..990a2d1 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -49,7 +49,7 @@ {PCI_VENDOR_ID_INTEL, \ PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}
-#define CONFIG_COREBOOT_SERIAL +#define CONFIG_X86_SERIAL
#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ "stdout=vga,serial,cbmem\0" \ diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index b9db6b7..eadb339 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -20,7 +20,7 @@ #define CONFIG_X86_RESET_VECTOR #define CONFIG_NR_DRAM_BANKS 1
-#define CONFIG_COREBOOT_SERIAL +#define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M
#define CONFIG_PCI_MEM_BUS 0x40000000

Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: - Remove the 'make menuconfig' in the crownbay build instructions - Indicate all the binary blobs should be put in the board directory
doc/README.x86 | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 doc/README.x86
diff --git a/doc/README.x86 b/doc/README.x86 new file mode 100644 index 0000000..902aa7e --- /dev/null +++ b/doc/README.x86 @@ -0,0 +1,126 @@ +# +# Copyright (C) 2014, Simon Glass sjg@chromium.org +# Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +U-Boot on x86 +============= + +This document describes the information about U-Boot running on x86 targets, +including supported boards, build instructions, todo list, etc. + +Status +------ +U-Boot supports running as a coreboot [1] payload on x86. So far only link +(Chromebook pixel) has been tested, but it should work with minimal adjustments +on other x86 boards since coreboot deals with most of the low-level details. + +U-Boot also supports booting directly from x86 reset vector without coreboot, +aka raw support or bare support. Currently Google Chromebook link and Intel +Crown Bay board support running U-Boot 'bare metal'. + +As for loading OS, U-Boot supports directly booting a 32-bit or 64-bit Linux +kernel as part of a FIT image. It also supports a compressed zImage. + +Build Instructions +------------------ +Building U-Boot as a coreboot payload is just like building U-Boot for targets +on other architectures, like below: + +$ make coreboot-x86_defconfig +$ make all + +Building rom version U-Boot (hereafter referred to as u-boot.rom) is a little +bit tricky, as generally it requires several binary blobs which are not shipped +in the U-Boot source tree. Due to this reason, the u-boot.rom build is not +turned on by default in the U-Boot source tree. Firstly, you need turn it on +by uncommenting the following line in the main U-Boot Makefile: + +# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom + +Google Chromebook link specific instructions: + +Firstly, you need the following binary blobs: + +* descriptor.bin - Intel flash descriptor +* me.bin - Intel Management Engine +* mrc.bin - Memory Reference Code, which sets up SDRAM +* video ROM - sets up the display + +You can get these binary blobs by: + +$ git clone http://review.coreboot.org/p/blobs.git +$ cd blobs + +Find the following files: + +* ./mainboard/google/link/descriptor.bin +* ./mainboard/google/link/me.bin +* ./northbridge/intel/sandybridge/systemagent-ivybridge.bin + +The 3rd one should be renamed to mrc.bin. +As for the video ROM, you can get it here [2]. +Make sure all these binary blobs are put in the board directory. + +Now you can build U-Boot and obtain u-boot.rom: + +$ make chromebook_link_defconfig +$ make all + +Intel Crown Bay specific instructions: + +U-Boot support of Intel Crown Bay board [3] relies on a binary blob called +Firmware Support Package [4] to perform all the necessary initialization steps +as documented in the BIOS Writer Guide including initialization of the CPU, +memory controller, chipset and certain bus interfaces. + +Downalod the Intel FSP for Atom E6xx series and Platform Controller Hub EG20T, +install it on your host and locate the FSP binary blob. Note this platform +also requires a Chipset Micro Code (CMC) state machine binary to be present in +the SPI flash where u-boot.rom resides, and this CMC binary blob can be found +in this FSP package too. + +* ./FSP/QUEENSBAY_FSP_GOLD_001_20-DECEMBER-2013.fd +* ./Microcode/C0_22211.BIN + +Rename the first one to fsp.bin and second one to cmc.bin and put them in the +board directory. + +Now you can build U-Boot and obtaim u-boot.rom + +$ make crownbay_defconfig +$ make all + +CPU Microcode +------------- +Modern CPU usually requires a special bit stream called microcode [5] to be +loaded on the processor after power up in order to function properly. U-Boot +has already integrated these as hex dumps in the source tree. + +Driver Model +------------ +x86 has been converted to use driver model for serial and GPIO. + +Device Tree +----------- +x86 uses device tree to configure the board thus requires CONFIG_OF_CONTROL to +be turned on. Not every device on the board is configured via devie tree, but +more and more devices will be added as time goes by. Check out the directory +arch/x86/dts/ for these device tree source files. + +TODO List +--------- +- MTRR support (for performance) +- Audio +- Chrome OS verified boot +- SMI and ACPI support, to provide platform info and facilities to Linux + +References +---------- +[1] http://www.coreboot.org +[2] http://www.coreboot.org/~stepan/pci8086,0166.rom +[3] http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-plat... +[4] http://www.intel.com/fsp +[5] http://en.wikipedia.org/wiki/Microcode
participants (3)
-
Bin Meng
-
Jagan Teki
-
Simon Glass