diff options
47 files changed, 443 insertions, 135 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 18c7fb2d49..a1c18d26e1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -112,6 +112,7 @@ source "arch/x86/cpu/braswell/Kconfig" source "arch/x86/cpu/broadwell/Kconfig" source "arch/x86/cpu/coreboot/Kconfig" source "arch/x86/cpu/ivybridge/Kconfig" +source "arch/x86/cpu/efi/Kconfig" source "arch/x86/cpu/qemu/Kconfig" source "arch/x86/cpu/quark/Kconfig" source "arch/x86/cpu/queensbay/Kconfig" @@ -772,6 +773,4 @@ config HIGH_TABLE_SIZE Increse it if the default size does not fit the board's needs. This is most likely due to a large ACPI DSDT table is used. -source "arch/x86/lib/efi/Kconfig" - endmenu diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index af9e26caab..f862d8c071 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_INTEL_BRASWELL) += braswell/ obj-$(CONFIG_INTEL_BROADWELL) += broadwell/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ -obj-$(CONFIG_EFI_APP) += efi/ +obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_QEMU) += qemu/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ obj-$(CONFIG_INTEL_QUARK) += quark/ diff --git a/arch/x86/cpu/baytrail/Kconfig b/arch/x86/cpu/baytrail/Kconfig index 022a9f2e51..d2c3473d6a 100644 --- a/arch/x86/cpu/baytrail/Kconfig +++ b/arch/x86/cpu/baytrail/Kconfig @@ -4,10 +4,10 @@ config INTEL_BAYTRAIL bool - select HAVE_FSP if !EFI - select ARCH_MISC_INIT if !EFI + select HAVE_FSP + select ARCH_MISC_INIT select CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED - imply HAVE_INTEL_ME if !EFI + imply HAVE_INTEL_ME imply ENABLE_MRC_CACHE imply AHCI_PCI imply ICH_SPI diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 3194f8c653..b7d481ac56 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -17,7 +17,6 @@ #define BYT_TRIG_LVL BIT(24) #define BYT_TRIG_POS BIT(25) -#ifndef CONFIG_EFI_APP int arch_cpu_init(void) { post_code(POST_CPU_INIT); @@ -57,8 +56,6 @@ int arch_misc_init(void) return 0; } -#endif - void reset_cpu(ulong addr) { /* cold reset */ diff --git a/arch/x86/lib/efi/Kconfig b/arch/x86/cpu/efi/Kconfig index e0975d34d3..e0975d34d3 100644 --- a/arch/x86/lib/efi/Kconfig +++ b/arch/x86/cpu/efi/Kconfig diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile index 06d0480440..9716a4ebe0 100644 --- a/arch/x86/cpu/efi/Makefile +++ b/arch/x86/cpu/efi/Makefile @@ -2,5 +2,12 @@ # # Copyright (c) 2015 Google, Inc -obj-y += efi.o +ifdef CONFIG_EFI_APP +obj-y += app.o obj-y += sdram.o +endif + +ifdef CONFIG_EFI_STUB +obj-y += car.o +obj-y += payload.o +endif diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/app.c index cda4fabe15..ba7c02bd7e 100644 --- a/arch/x86/cpu/efi/efi.c +++ b/arch/x86/cpu/efi/app.c @@ -9,7 +9,7 @@ int arch_cpu_init(void) { - return 0; + return x86_cpu_init_f(); } int checkcpu(void) diff --git a/arch/x86/lib/efi/car.S b/arch/x86/cpu/efi/car.S index 488dcde66c..488dcde66c 100644 --- a/arch/x86/lib/efi/car.S +++ b/arch/x86/cpu/efi/car.S diff --git a/arch/x86/lib/efi/efi.c b/arch/x86/cpu/efi/payload.c index 81fb8b5f72..9fd9f57776 100644 --- a/arch/x86/lib/efi/efi.c +++ b/arch/x86/cpu/efi/payload.c @@ -5,11 +5,9 @@ */ #include <common.h> -#include <debug_uart.h> #include <efi.h> #include <errno.h> -#include <linux/err.h> -#include <linux/types.h> +#include <asm/post.h> DECLARE_GLOBAL_DATA_PTR; @@ -126,6 +124,13 @@ int dram_init_banksize(void) return 0; } +int arch_cpu_init(void) +{ + post_code(POST_CPU_INIT); + + return x86_cpu_init_f(); +} + int checkcpu(void) { return 0; diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index c0fcf0ce78..bf798c287f 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += mrc.o endif obj-y += cpu.o obj-y += lpc.o -ifndef CONFIG_TARGET_EFI +ifndef CONFIG_TARGET_EFI_APP obj-y += microcode.o endif obj-y += pch.o diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile index e5ea92545e..1761244178 100644 --- a/arch/x86/cpu/qemu/Makefile +++ b/arch/x86/cpu/qemu/Makefile @@ -2,8 +2,6 @@ # # Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> -ifndef CONFIG_EFI_STUB obj-y += car.o dram.o -endif obj-y += qemu.o obj-$(CONFIG_QFW) += cpu.o e820.o diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 1fdb11cc60..ca4b3f0833 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -143,10 +143,6 @@ int arch_cpu_init(void) return x86_cpu_init_f(); } -#endif - -#if !CONFIG_IS_ENABLED(EFI_STUB) && \ - !CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT) int checkcpu(void) { diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 73797746f8..37e4fdc760 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -10,7 +10,8 @@ dtb-y += bayleybay.dtb \ crownbay.dtb \ dfi-bt700-q7x-151.dtb \ edison.dtb \ - efi.dtb \ + efi-x86_app.dtb \ + efi-x86_payload.dtb \ galileo.dtb \ minnowmax.dtb \ qemu-x86_i440fx.dtb \ diff --git a/arch/x86/dts/cherryhill.dts b/arch/x86/dts/cherryhill.dts index c3a6aad77b..3e29683bd9 100644 --- a/arch/x86/dts/cherryhill.dts +++ b/arch/x86/dts/cherryhill.dts @@ -75,8 +75,6 @@ pch@1f,0 { reg = <0x0000f800 0 0 0 0>; compatible = "intel,pch9"; - #address-cells = <1>; - #size-cells = <1>; irq-router { compatible = "intel,irq-router"; diff --git a/arch/x86/dts/efi.dts b/arch/x86/dts/efi-x86_app.dts index 62ae96a3f3..e70e351618 100644 --- a/arch/x86/dts/efi.dts +++ b/arch/x86/dts/efi-x86_app.dts @@ -9,8 +9,8 @@ /include/ "tsc_timer.dtsi" / { - model = "EFI"; - compatible = "efi,app"; + model = "EFI x86 Application"; + compatible = "efi,x86-app"; chosen { stdout-path = &serial; diff --git a/arch/x86/dts/efi-x86_payload.dts b/arch/x86/dts/efi-x86_payload.dts new file mode 100644 index 0000000000..148b5871aa --- /dev/null +++ b/arch/x86/dts/efi-x86_payload.dts @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * Generic EFI payload device tree for x86 targets + */ + +/dts-v1/; + +/include/ "skeleton.dtsi" +/include/ "serial.dtsi" +/include/ "keyboard.dtsi" +/include/ "rtc.dtsi" +/include/ "tsc_timer.dtsi" + +/ { + model = "EFI x86 Payload"; + compatible = "efi,x86-payload"; + + aliases { + serial0 = &serial; + }; + + config { + silent_console = <0>; + }; + + chosen { + stdout-path = "/serial"; + }; + + pci { + compatible = "pci-x86"; + u-boot,dm-pre-reloc; + }; + + efi-fb { + compatible = "efi-fb"; + }; +}; diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 0e054da1e9..ba07ac728f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -14,7 +14,6 @@ endif obj-y += cmd_boot.o obj-$(CONFIG_SEABIOS) += coreboot_table.o obj-y += early_cmos.o -obj-$(CONFIG_EFI) += efi/ obj-y += e820.o obj-y += init_helpers.o obj-y += interrupts.o diff --git a/arch/x86/lib/crt0_x86_64_efi.S b/arch/x86/lib/crt0_x86_64_efi.S index 989799fb4a..bb8d3cf8a9 100644 --- a/arch/x86/lib/crt0_x86_64_efi.S +++ b/arch/x86/lib/crt0_x86_64_efi.S @@ -3,7 +3,7 @@ * crt0-efi-x86_64.S - x86_64 EFI startup code. * Copyright (C) 1999 Hewlett-Packard Co. * Contributed by David Mosberger <davidm@hpl.hp.com>. - * Copyright (C) 2005 Intel Co. + * Copyright (C) 2005 Intel Corporation * Contributed by Fenghua Yu <fenghua.yu@intel.com>. * * All rights reserved. @@ -14,26 +14,28 @@ .globl _start _start: subq $8, %rsp + pushq %rcx pushq %rdx -0: - lea image_base(%rip), %rdi - lea _DYNAMIC(%rip), %rsi + mov %rcx, %r8 + mov %rdx, %r9 + + lea image_base(%rip), %rcx + lea _DYNAMIC(%rip), %rdx - popq %rcx - popq %rdx - pushq %rcx - pushq %rdx call _relocate - popq %rdi - popq %rsi + popq %rdx + popq %rcx + + testq %rax, %rax + jnz .exit call efi_main +.exit: addq $8, %rsp -.exit: ret /* diff --git a/arch/x86/lib/efi/Makefile b/arch/x86/lib/efi/Makefile deleted file mode 100644 index f6c65235e2..0000000000 --- a/arch/x86/lib/efi/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2002-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. - -obj-$(CONFIG_EFI_STUB) += car.o -obj-$(CONFIG_EFI_STUB) += efi.o diff --git a/board/advantech/som-db5800-som-6867/Kconfig b/board/advantech/som-db5800-som-6867/Kconfig index fac562ad4f..35d58fcd01 100644 --- a/board/advantech/som-db5800-som-6867/Kconfig +++ b/board/advantech/som-db5800-som-6867/Kconfig @@ -13,12 +13,11 @@ config SYS_CONFIG_NAME default "som-db5800-som-6867" config SYS_TEXT_BASE - default 0xfff00000 if !EFI_STUB - default 0x01110000 if EFI_STUB + default 0xfff00000 config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select X86_RESET_VECTOR if !EFI_STUB + select X86_RESET_VECTOR select INTEL_BAYTRAIL select BOARD_ROMSIZE_KB_8192 select BOARD_EARLY_INIT_F diff --git a/board/congatec/conga-qeval20-qa3-e3845/Kconfig b/board/congatec/conga-qeval20-qa3-e3845/Kconfig index 9e44413c2c..64692509fd 100644 --- a/board/congatec/conga-qeval20-qa3-e3845/Kconfig +++ b/board/congatec/conga-qeval20-qa3-e3845/Kconfig @@ -12,12 +12,11 @@ config SYS_CONFIG_NAME default "theadorable-x86-conga-qa3-e3845" if TARGET_THEADORABLE_X86_CONGA_QA3_E3845 config SYS_TEXT_BASE - default 0xfff00000 if !EFI_STUB - default 0x01110000 if EFI_STUB + default 0xfff00000 config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select X86_RESET_VECTOR if !EFI_STUB + select X86_RESET_VECTOR select INTEL_BAYTRAIL select BOARD_ROMSIZE_KB_8192 select BOARD_EARLY_INIT_F diff --git a/board/dfi/dfi-bt700/Kconfig b/board/dfi/dfi-bt700/Kconfig index f92f50a448..50c7b2a2f4 100644 --- a/board/dfi/dfi-bt700/Kconfig +++ b/board/dfi/dfi-bt700/Kconfig @@ -12,12 +12,11 @@ config SYS_CONFIG_NAME default "theadorable-x86-dfi-bt700" if TARGET_THEADORABLE_X86_DFI_BT700 config SYS_TEXT_BASE - default 0xfff00000 if !EFI_STUB - default 0x01110000 if EFI_STUB + default 0xfff00000 config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select X86_RESET_VECTOR if !EFI_STUB + select X86_RESET_VECTOR select INTEL_BAYTRAIL select BOARD_ROMSIZE_KB_8192 select BOARD_EARLY_INIT_F diff --git a/board/efi/Kconfig b/board/efi/Kconfig index 6f86a48fa7..291bd2ca15 100644 --- a/board/efi/Kconfig +++ b/board/efi/Kconfig @@ -4,16 +4,25 @@ choice prompt "Mainboard model" optional -config TARGET_EFI - bool "efi" +config TARGET_EFI_APP + bool "efi application" help This target is used for running U-Boot on top of EFI. In this case EFI does the early initialisation, and U-Boot takes over once the RAM, video and CPU are fully running. U-Boot is loaded as an application from EFI. +config TARGET_EFI_PAYLOAD + bool "efi payload" + help + This target is used for running U-Boot on top of EFI. In + this case EFI does the early initialisation, and U-Boot + takes over once the RAM, video and CPU are fully running. + U-Boot is loaded as a payload from EFI. + endchoice -source "board/efi/efi-x86/Kconfig" +source "board/efi/efi-x86_app/Kconfig" +source "board/efi/efi-x86_payload/Kconfig" endif diff --git a/board/efi/efi-x86/Kconfig b/board/efi/efi-x86_app/Kconfig index fa609ba5d2..ae87bf34d3 100644 --- a/board/efi/efi-x86/Kconfig +++ b/board/efi/efi-x86_app/Kconfig @@ -1,7 +1,7 @@ -if TARGET_EFI +if TARGET_EFI_APP config SYS_BOARD - default "efi-x86" + default "efi-x86_app" config SYS_VENDOR default "efi" @@ -10,6 +10,6 @@ config SYS_SOC default "efi" config SYS_CONFIG_NAME - default "efi-x86" + default "efi-x86_app" endif diff --git a/board/efi/efi-x86/MAINTAINERS b/board/efi/efi-x86_app/MAINTAINERS index a44c7c64be..a44c7c64be 100644 --- a/board/efi/efi-x86/MAINTAINERS +++ b/board/efi/efi-x86_app/MAINTAINERS diff --git a/board/efi/efi-x86/Makefile b/board/efi/efi-x86_app/Makefile index 209728341b..cb48d1ccc2 100644 --- a/board/efi/efi-x86/Makefile +++ b/board/efi/efi-x86_app/Makefile @@ -2,4 +2,4 @@ # # Copyright (c) 2015 Google, Inc -obj-y += efi.o +obj-y += app.o diff --git a/board/efi/efi-x86/efi.c b/board/efi/efi-x86_app/app.c index da3445bb1d..da3445bb1d 100644 --- a/board/efi/efi-x86/efi.c +++ b/board/efi/efi-x86_app/app.c diff --git a/board/efi/efi-x86_payload/Kconfig b/board/efi/efi-x86_payload/Kconfig new file mode 100644 index 0000000000..b6e57b9ea7 --- /dev/null +++ b/board/efi/efi-x86_payload/Kconfig @@ -0,0 +1,39 @@ +if TARGET_EFI_PAYLOAD + +config SYS_BOARD + default "efi-x86_payload" + +config SYS_VENDOR + default "efi" + +config SYS_SOC + default "efi" + +config SYS_CONFIG_NAME + default "efi-x86_payload" + +config SYS_TEXT_BASE + default 0x00200000 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + imply SYS_NS16550 + imply SCSI + imply SCSI_AHCI + imply AHCI_PCI + imply MMC + imply MMC_PCI + imply MMC_SDHCI + imply MMC_SDHCI_SDMA + imply USB + imply USB_EHCI_HCD + imply USB_XHCI_HCD + imply USB_STORAGE + imply USB_KEYBOARD + imply VIDEO_EFI + imply E1000 + imply ETH_DESIGNWARE + imply PCH_GBE + imply RTL8169 + +endif diff --git a/board/efi/efi-x86_payload/MAINTAINERS b/board/efi/efi-x86_payload/MAINTAINERS new file mode 100644 index 0000000000..abf3a1574b --- /dev/null +++ b/board/efi/efi-x86_payload/MAINTAINERS @@ -0,0 +1,7 @@ +EFI-X86_PAYLOAD BOARD +M: Bin Meng <bmeng.cn@gmail.com> +S: Maintained +F: board/efi/efi-x86_payload/ +F: include/configs/efi-x86_payload.h +F: configs/efi-x86_payload32_defconfig +F: configs/efi-x86_payload64_defconfig diff --git a/board/efi/efi-x86_payload/Makefile b/board/efi/efi-x86_payload/Makefile new file mode 100644 index 0000000000..6982340f17 --- /dev/null +++ b/board/efi/efi-x86_payload/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + +obj-y += start.o diff --git a/board/efi/efi-x86_payload/start.S b/board/efi/efi-x86_payload/start.S new file mode 100644 index 0000000000..f7eaa7cb12 --- /dev/null +++ b/board/efi/efi-x86_payload/start.S @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +.globl early_board_init +early_board_init: + jmp early_board_init_ret diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig index a593f8cdc8..41a27dd933 100644 --- a/board/emulation/qemu-x86/Kconfig +++ b/board/emulation/qemu-x86/Kconfig @@ -13,12 +13,12 @@ config SYS_CONFIG_NAME default "qemu-x86" config SYS_TEXT_BASE - default 0xfff00000 if !EFI_STUB && !SUPPORT_SPL - default 0x01110000 if EFI_STUB || SUPPORT_SPL + default 0xfff00000 if !SUPPORT_SPL + default 0x01110000 if SUPPORT_SPL config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select X86_RESET_VECTOR if !EFI_STUB + select X86_RESET_VECTOR select QEMU select BOARD_ROMSIZE_KB_1024 diff --git a/board/emulation/qemu-x86/MAINTAINERS b/board/emulation/qemu-x86/MAINTAINERS index 4cf8ac90e7..9a99d38ca0 100644 --- a/board/emulation/qemu-x86/MAINTAINERS +++ b/board/emulation/qemu-x86/MAINTAINERS @@ -4,8 +4,6 @@ S: Maintained F: board/emulation/qemu-x86/ F: include/configs/qemu-x86.h F: configs/qemu-x86_defconfig -F: configs/qemu-x86_efi_payload32_defconfig -F: configs/qemu-x86_efi_payload64_defconfig QEMU X86 64-bit BOARD M: Bin Meng <bmeng.cn@gmail.com> diff --git a/board/intel/minnowmax/Kconfig b/board/intel/minnowmax/Kconfig index a8668e4efc..543468cab5 100644 --- a/board/intel/minnowmax/Kconfig +++ b/board/intel/minnowmax/Kconfig @@ -13,12 +13,11 @@ config SYS_CONFIG_NAME default "minnowmax" config SYS_TEXT_BASE - default 0xfff00000 if !EFI_STUB - default 0x01110000 if EFI_STUB + default 0xfff00000 config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select X86_RESET_VECTOR if !EFI_STUB + select X86_RESET_VECTOR select INTEL_BAYTRAIL select BOARD_ROMSIZE_KB_8192 select SPI_FLASH_STMICRO diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_app_defconfig index a2f072b2f2..9c1d5e786e 100644 --- a/configs/efi-x86_defconfig +++ b/configs/efi-x86_app_defconfig @@ -2,8 +2,8 @@ CONFIG_X86=y CONFIG_DEBUG_UART_BASE=0 CONFIG_DEBUG_UART_CLOCK=0 CONFIG_VENDOR_EFI=y -CONFIG_DEFAULT_DEVICE_TREE="efi" -CONFIG_TARGET_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi-x86_app" +CONFIG_TARGET_EFI_APP=y CONFIG_DEBUG_UART=y CONFIG_FIT=y CONFIG_USE_BOOTARGS=y diff --git a/configs/qemu-x86_efi_payload32_defconfig b/configs/efi-x86_payload32_defconfig index 36705db89a..7f0cab0ab1 100644 --- a/configs/qemu-x86_efi_payload32_defconfig +++ b/configs/efi-x86_payload32_defconfig @@ -1,31 +1,25 @@ CONFIG_X86=y -CONFIG_SYS_TEXT_BASE=0x1110000 -CONFIG_MAX_CPUS=2 -CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx" -CONFIG_SMP=y +CONFIG_VENDOR_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi-x86_payload" +CONFIG_TARGET_EFI_PAYLOAD=y CONFIG_FIT=y -CONFIG_BOOTSTAGE=y -CONFIG_BOOTSTAGE_REPORT=y +CONFIG_FIT_SIGNATURE=y CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro" CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_LAST_STAGE_INIT=y CONFIG_HUSH_PARSER=y -CONFIG_CMD_CPU=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_IDE=y +CONFIG_CMD_MMC=y CONFIG_CMD_PART=y -CONFIG_CMD_SF=y -CONFIG_CMD_SPI=y CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set CONFIG_CMD_PING=y CONFIG_CMD_TIME=y -CONFIG_CMD_QFW=y -CONFIG_CMD_BOOTSTAGE=y CONFIG_CMD_EXT2=y CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y @@ -36,12 +30,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_REGMAP=y CONFIG_SYSCON=y -CONFIG_CPU=y -CONFIG_SPI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_KEYBOARD=y -CONFIG_FRAMEBUFFER_SET_VESA_MODE=y -CONFIG_FRAMEBUFFER_VESA_MODE_112=y -CONFIG_CONSOLE_SCROLL_LINES=5 +# CONFIG_PCI_PNP is not set CONFIG_EFI=y CONFIG_EFI_STUB=y diff --git a/configs/qemu-x86_efi_payload64_defconfig b/configs/efi-x86_payload64_defconfig index 5b0806bad9..8d7f3f056e 100644 --- a/configs/qemu-x86_efi_payload64_defconfig +++ b/configs/efi-x86_payload64_defconfig @@ -1,31 +1,25 @@ CONFIG_X86=y -CONFIG_SYS_TEXT_BASE=0x1110000 -CONFIG_MAX_CPUS=2 -CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx" -CONFIG_SMP=y +CONFIG_VENDOR_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi-x86_payload" +CONFIG_TARGET_EFI_PAYLOAD=y CONFIG_FIT=y -CONFIG_BOOTSTAGE=y -CONFIG_BOOTSTAGE_REPORT=y +CONFIG_FIT_SIGNATURE=y CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro" CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_LAST_STAGE_INIT=y CONFIG_HUSH_PARSER=y -CONFIG_CMD_CPU=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_IDE=y +CONFIG_CMD_MMC=y CONFIG_CMD_PART=y -CONFIG_CMD_SF=y -CONFIG_CMD_SPI=y CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set CONFIG_CMD_PING=y CONFIG_CMD_TIME=y -CONFIG_CMD_QFW=y -CONFIG_CMD_BOOTSTAGE=y CONFIG_CMD_EXT2=y CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y @@ -36,13 +30,7 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_REGMAP=y CONFIG_SYSCON=y -CONFIG_CPU=y -CONFIG_SPI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_KEYBOARD=y -CONFIG_FRAMEBUFFER_SET_VESA_MODE=y -CONFIG_FRAMEBUFFER_VESA_MODE_112=y -CONFIG_CONSOLE_SCROLL_LINES=5 +# CONFIG_PCI_PNP is not set CONFIG_EFI=y CONFIG_EFI_STUB=y CONFIG_EFI_STUB_64BIT=y diff --git a/doc/README.u-boot_on_efi b/doc/README.u-boot_on_efi index d5903c7bd3..e12dd4e3e6 100644 --- a/doc/README.u-boot_on_efi +++ b/doc/README.u-boot_on_efi @@ -65,18 +65,19 @@ for that board. It will be either 32-bit or 64-bit. Alternatively, you can opt for using QEMU [1] and the OVMF [2], as detailed below. To build U-Boot as an EFI application (32-bit EFI required), enable CONFIG_EFI -and CONFIG_EFI_APP. The efi-x86 config (efi-x86_defconfig) is set up for this. -Just build U-Boot as normal, e.g. +and CONFIG_EFI_APP. The efi-x86_app config (efi-x86_app_defconfig) is set up +for this. Just build U-Boot as normal, e.g. - make efi-x86_defconfig + make efi-x86_app_defconfig make -To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust an -existing config (like qemu-x86_defconfig) to enable CONFIG_EFI, CONFIG_EFI_STUB -and either CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT. All of these are -boolean Kconfig options. Then build U-Boot as normal, e.g. +To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), enable +CONFIG_EFI, CONFIG_EFI_STUB, and select either CONFIG_EFI_STUB_32BIT or +CONFIG_EFI_STUB_64BIT. The efi-x86_payload configs (efi-x86_payload32_defconfig +and efi-x86_payload32_defconfig) are set up for this. Then build U-Boot as +normal, e.g. - make qemu-x86_defconfig + make efi-x86_payload32_defconfig (or efi-x86_payload64_defconfig) make You will end up with one of these files depending on what you build for: @@ -211,11 +212,6 @@ Future work ----------- This work could be extended in a number of ways: -- Add a generic x86 EFI payload configuration. At present you need to modify -an existing one, but mostly the low-level x86 code is disabled when booting -on EFI anyway, so a generic 'EFI' board could be created with a suitable set -of drivers enabled. - - Add ARM support - Add 64-bit application support @@ -235,16 +231,15 @@ Where is the code? lib/efi payload stub, application, support code. Mostly arch-neutral -arch/x86/lib/efi - helper functions for the fake DRAM init, etc. These can be used by - any board that runs as a payload. - arch/x86/cpu/efi - x86 support code for running as an EFI application + x86 support code for running as an EFI application and payload -board/efi/efi-x86/efi.c +board/efi/efi-x86_app/efi.c x86 board code for running as an EFI application +board/efi/efi-x86_payload + generic x86 EFI payload board support code + common/cmd_efi.c the 'efi' command diff --git a/doc/README.x86 b/doc/README.x86 index 78664c3d0a..9f657df6bf 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -1134,18 +1134,18 @@ the "Power" submenu from the Windows start menu. EFI Support ----------- U-Boot supports booting as a 32-bit or 64-bit EFI payload, e.g. with UEFI. -This is enabled with CONFIG_EFI_STUB. U-Boot can also run as an EFI -application, with CONFIG_EFI_APP. The CONFIG_EFI_LOADER option, where U-Booot -provides an EFI environment to the kernel (i.e. replaces UEFI completely but -provides the same EFI run-time services) is not currently supported on x86. +This is enabled with CONFIG_EFI_STUB to boot from both 32-bit and 64-bit +UEFI BIOS. U-Boot can also run as an EFI application, with CONFIG_EFI_APP. +The CONFIG_EFI_LOADER option, where U-Booot provides an EFI environment to +the kernel (i.e. replaces UEFI completely but provides the same EFI run-time +services) is not currently supported on x86. -See README.efi for details of EFI support in U-Boot. +See README.u-boot_on_efi and README.uefi for details of EFI support in U-Boot. 64-bit Support -------------- U-Boot supports booting a 64-bit kernel directly and is able to change to -64-bit mode to do so. It also supports (with CONFIG_EFI_STUB) booting from -both 32-bit and 64-bit UEFI. However, U-Boot itself is currently always built +64-bit mode to do so. However, U-Boot itself is currently always built in 32-bit mode. Some access to the full memory range is provided with arch_phys_memset(). diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4c4d2861fe..5ee9032dc9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -156,6 +156,15 @@ config VIDEO_COREBOOT coreboot already. This can in principle be used with any platform that coreboot supports. +config VIDEO_EFI + bool "Enable EFI framebuffer driver support" + depends on EFI_STUB + help + Turn on this option to enable a framebuffeer driver when U-Boot is + loaded as a payload (see README.u-boot_on_efi) by an EFI BIOS where + the graphics device is configured by the EFI BIOS already. This can + in principle be used with any platform that has an EFI BIOS. + config VIDEO_VESA bool "Enable VESA video driver support" default n diff --git a/drivers/video/Makefile b/drivers/video/Makefile index cf7ad281c3..7c89c67dce 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_LD9040) += ld9040.o obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o obj-$(CONFIG_VIDEO_COREBOOT) += coreboot.o obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o +obj-$(CONFIG_VIDEO_EFI) += efi.o obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o diff --git a/drivers/video/efi.c b/drivers/video/efi.c new file mode 100644 index 0000000000..653cb47265 --- /dev/null +++ b/drivers/video/efi.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * EFI framebuffer driver based on GOP + */ + +#include <common.h> +#include <dm.h> +#include <efi_api.h> +#include <vbe.h> +#include <video.h> + +struct pixel { + u8 pos; + u8 size; +}; + +static const struct efi_framebuffer { + struct pixel red; + struct pixel green; + struct pixel blue; + struct pixel rsvd; +} efi_framebuffer_format_map[] = { + [EFI_GOT_RGBA8] = { {0, 8}, {8, 8}, {16, 8}, {24, 8} }, + [EFI_GOT_BGRA8] = { {16, 8}, {8, 8}, {0, 8}, {24, 8} }, +}; + +static void efi_find_pixel_bits(u32 mask, u8 *pos, u8 *size) +{ + u8 first, len; + + first = 0; + len = 0; + + if (mask) { + while (!(mask & 0x1)) { + mask = mask >> 1; + first++; + } + + while (mask & 0x1) { + mask = mask >> 1; + len++; + } + } + + *pos = first; + *size = len; +} + +static int save_vesa_mode(struct vesa_mode_info *vesa) +{ + struct efi_entry_gopmode *mode; + const struct efi_framebuffer *fbinfo; + int size; + int ret; + + ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size); + if (ret == -ENOENT) { + debug("efi graphics output protocol mode not found\n"); + return -ENXIO; + } + + vesa->phys_base_ptr = mode->fb_base; + vesa->x_resolution = mode->info->width; + vesa->y_resolution = mode->info->height; + + if (mode->info->pixel_format < EFI_GOT_BITMASK) { + fbinfo = &efi_framebuffer_format_map[mode->info->pixel_format]; + vesa->red_mask_size = fbinfo->red.size; + vesa->red_mask_pos = fbinfo->red.pos; + vesa->green_mask_size = fbinfo->green.size; + vesa->green_mask_pos = fbinfo->green.pos; + vesa->blue_mask_size = fbinfo->blue.size; + vesa->blue_mask_pos = fbinfo->blue.pos; + vesa->reserved_mask_size = fbinfo->rsvd.size; + vesa->reserved_mask_pos = fbinfo->rsvd.pos; + + vesa->bits_per_pixel = 32; + vesa->bytes_per_scanline = mode->info->pixels_per_scanline * 4; + } else if (mode->info->pixel_format == EFI_GOT_BITMASK) { + efi_find_pixel_bits(mode->info->pixel_bitmask[0], + &vesa->red_mask_pos, + &vesa->red_mask_size); + efi_find_pixel_bits(mode->info->pixel_bitmask[1], + &vesa->green_mask_pos, + &vesa->green_mask_size); + efi_find_pixel_bits(mode->info->pixel_bitmask[2], + &vesa->blue_mask_pos, + &vesa->blue_mask_size); + efi_find_pixel_bits(mode->info->pixel_bitmask[3], + &vesa->reserved_mask_pos, + &vesa->reserved_mask_size); + vesa->bits_per_pixel = vesa->red_mask_size + + vesa->green_mask_size + + vesa->blue_mask_size + + vesa->reserved_mask_size; + vesa->bytes_per_scanline = (mode->info->pixels_per_scanline * + vesa->bits_per_pixel) / 8; + } else { + debug("efi set unknown framebuffer format: %d\n", + mode->info->pixel_format); + return -EINVAL; + } + + return 0; +} + +static int efi_video_probe(struct udevice *dev) +{ + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + struct vesa_mode_info *vesa = &mode_info.vesa; + int ret; + + /* Initialize vesa_mode_info structure */ + ret = save_vesa_mode(vesa); + if (ret) + goto err; + + ret = vbe_setup_video_priv(vesa, uc_priv, plat); + if (ret) + goto err; + + printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize, + vesa->bits_per_pixel); + + return 0; + +err: + printf("No video mode configured in EFI!\n"); + return ret; +} + +static const struct udevice_id efi_video_ids[] = { + { .compatible = "efi-fb" }, + { } +}; + +U_BOOT_DRIVER(efi_video) = { + .name = "efi_video", + .id = UCLASS_VIDEO, + .of_match = efi_video_ids, + .probe = efi_video_probe, +}; diff --git a/include/configs/efi-x86.h b/include/configs/efi-x86_app.h index 33418cfbec..33418cfbec 100644 --- a/include/configs/efi-x86.h +++ b/include/configs/efi-x86_app.h diff --git a/include/configs/efi-x86_payload.h b/include/configs/efi-x86_payload.h new file mode 100644 index 0000000000..9c62fd24b8 --- /dev/null +++ b/include/configs/efi-x86_payload.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +/* + * 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_STD_DEVICES_SETTINGS "stdin=serial,i8042-kbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +/* ATA/IDE support */ +#define CONFIG_SYS_IDE_MAXBUS 2 +#define CONFIG_SYS_IDE_MAXDEVICE 4 +#define CONFIG_SYS_ATA_BASE_ADDR 0 +#define CONFIG_SYS_ATA_DATA_OFFSET 0 +#define CONFIG_SYS_ATA_REG_OFFSET 0 +#define CONFIG_SYS_ATA_ALT_OFFSET 0 +#define CONFIG_SYS_ATA_IDE0_OFFSET 0x1f0 +#define CONFIG_SYS_ATA_IDE1_OFFSET 0x170 +#define CONFIG_ATAPI + +#endif /* __CONFIG_H */ diff --git a/include/efi.h b/include/efi.h index e30a3c51c6..2448dde3fe 100644 --- a/include/efi.h +++ b/include/efi.h @@ -241,6 +241,7 @@ struct efi_open_protocol_info_entry { enum efi_entry_t { EFIET_END, /* Signals this is the last (empty) entry */ EFIET_MEMORY_MAP, + EFIET_GOP_MODE, /* Number of entries */ EFIET_MEMORY_COUNT, @@ -297,6 +298,40 @@ struct efi_entry_memmap { struct efi_mem_desc desc[]; }; +/** + * struct efi_entry_gopmode - a GOP mode table passed to U-Boot + * + * @fb_base: EFI's framebuffer base address + * @fb_size: EFI's framebuffer size + * @info_size: GOP mode info structure size + * @info: Start address of the GOP mode info structure + */ +struct efi_entry_gopmode { + efi_physical_addr_t fb_base; + /* + * Not like the ones in 'struct efi_gop_mode' which are 'unsigned + * long', @fb_size and @info_size have to be 'u64' here. As the EFI + * stub codes may have different bit size from the U-Boot payload, + * using 'long' will cause mismatch between the producer (stub) and + * the consumer (payload). + */ + u64 fb_size; + u64 info_size; + /* + * We cannot directly use 'struct efi_gop_mode_info info[]' here as + * it causes compiler to complain: array type has incomplete element + * type 'struct efi_gop_mode_info'. + */ + struct /* efi_gop_mode_info */ { + u32 version; + u32 width; + u32 height; + u32 pixel_format; + u32 pixel_bitmask[4]; + u32 pixels_per_scanline; + } info[]; +}; + static inline struct efi_mem_desc *efi_get_next_mem_desc( struct efi_entry_memmap *map, struct efi_mem_desc *desc) { diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index c8280935c8..3eb8eeb677 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv) * U-Boot. If it returns, EFI will continue. Another way to get back to EFI * is via reset_cpu(). */ -efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table) +efi_status_t EFIAPI efi_main(efi_handle_t image, + struct efi_system_table *sys_table) { struct efi_priv local_priv, *priv = &local_priv; efi_status_t ret; diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c index 09023a2f67..262fc56562 100644 --- a/lib/efi/efi_stub.c +++ b/lib/efi/efi_stub.c @@ -268,12 +268,16 @@ static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, * This function is called by our EFI start-up code. It handles running * U-Boot. If it returns, EFI will continue. */ -efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table) +efi_status_t EFIAPI efi_main(efi_handle_t image, + struct efi_system_table *sys_table) { struct efi_priv local_priv, *priv = &local_priv; struct efi_boot_services *boot = sys_table->boottime; struct efi_mem_desc *desc; struct efi_entry_memmap map; + struct efi_gop *gop; + struct efi_entry_gopmode mode; + efi_guid_t efi_gop_guid = EFI_GOP_GUID; efi_uintn_t key, desc_size, size; efi_status_t ret; u32 version; @@ -312,6 +316,18 @@ efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table) if (ret) return ret; + ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop); + if (ret) { + puts(" GOP unavailable\n"); + } else { + mode.fb_base = gop->mode->fb_base; + mode.fb_size = gop->mode->fb_size; + mode.info_size = gop->mode->info_size; + add_entry_addr(priv, EFIET_GOP_MODE, &mode, sizeof(mode), + gop->mode->info, + sizeof(struct efi_gop_mode_info)); + } + ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version); if (ret) { printhex2(ret); |