Merge git://git.denx.de/u-boot-x86
This commit is contained in:
commit
1a2728ae4f
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -48,6 +48,7 @@
|
|||
/LOG
|
||||
/spl/
|
||||
/tpl/
|
||||
/defconfig
|
||||
|
||||
#
|
||||
# Generated include files
|
||||
|
|
1
Kconfig
1
Kconfig
|
@ -179,6 +179,7 @@ config SYS_EXTRA_OPTIONS
|
|||
|
||||
config SYS_TEXT_BASE
|
||||
depends on SPARC || ARC || X86 || ARCH_UNIPHIER || ARCH_ZYNQMP
|
||||
depends on !EFI_APP
|
||||
hex "Text Base"
|
||||
help
|
||||
TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
|
||||
|
|
37
Makefile
37
Makefile
|
@ -754,6 +754,8 @@ ifneq ($(CONFIG_SPL_TARGET),)
|
|||
ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
|
||||
endif
|
||||
ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
|
||||
ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
|
||||
ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi
|
||||
|
||||
ifneq ($(BUILD_ROM),)
|
||||
ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
|
||||
|
@ -780,8 +782,17 @@ ifneq ($(CONFIG_SYS_TEXT_BASE),)
|
|||
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
|
||||
endif
|
||||
|
||||
# Normally we fill empty space with 0xff
|
||||
quiet_cmd_objcopy = OBJCOPY $@
|
||||
cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
|
||||
cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
|
||||
$(OBJCOPYFLAGS_$(@F)) $< $@
|
||||
|
||||
# Provide a version which does not do this, for use by EFI
|
||||
quiet_cmd_zobjcopy = OBJCOPY $@
|
||||
cmd_zobjcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
|
||||
|
||||
quiet_cmd_efipayload = OBJCOPY $@
|
||||
cmd_efipayload = $(OBJCOPY) -I binary -O $(EFIPAYLOAD_BFDTARGET) -B $(EFIPAYLOAD_BFDARCH) $< $@
|
||||
|
||||
quiet_cmd_mkimage = MKIMAGE $@
|
||||
cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
|
||||
|
@ -1076,6 +1087,30 @@ u-boot-dtb-tegra.bin: u-boot-nodtb-tegra.bin dts/dt.dtb FORCE
|
|||
endif
|
||||
endif
|
||||
|
||||
OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
|
||||
u-boot-app.efi: u-boot FORCE
|
||||
$(call if_changed,zobjcopy)
|
||||
|
||||
u-boot-dtb.bin.o: u-boot-dtb.bin FORCE
|
||||
$(call if_changed,efipayload)
|
||||
|
||||
u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE
|
||||
$(call if_changed_dep,cpp_lds)
|
||||
|
||||
# Rule to link the EFI payload which contains a stub and a U-Boot binary
|
||||
quiet_cmd_u-boot_payload ?= LD $@
|
||||
cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
|
||||
-T u-boot-payload.lds arch/x86/cpu/call32.o \
|
||||
lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \
|
||||
$(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
|
||||
|
||||
u-boot-payload: u-boot-dtb.bin.o u-boot-payload.lds FORCE
|
||||
$(call if_changed,u-boot_payload)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-payload.efi := $(OBJCOPYFLAGS_EFI)
|
||||
u-boot-payload.efi: u-boot-payload FORCE
|
||||
$(call if_changed,zobjcopy)
|
||||
|
||||
u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
|
||||
$(call if_changed,cat)
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@ choice
|
|||
config VENDOR_COREBOOT
|
||||
bool "coreboot"
|
||||
|
||||
config VENDOR_EFI
|
||||
bool "efi"
|
||||
|
||||
config VENDOR_EMULATION
|
||||
bool "emulation"
|
||||
|
||||
|
@ -24,6 +27,7 @@ endchoice
|
|||
|
||||
# board-specific options below
|
||||
source "board/coreboot/Kconfig"
|
||||
source "board/efi/Kconfig"
|
||||
source "board/emulation/Kconfig"
|
||||
source "board/google/Kconfig"
|
||||
source "board/intel/Kconfig"
|
||||
|
@ -190,6 +194,7 @@ config X86_RAMTEST
|
|||
|
||||
config HAVE_FSP
|
||||
bool "Add an Firmware Support Package binary"
|
||||
depends on !EFI
|
||||
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
|
||||
|
@ -305,6 +310,7 @@ menu "System tables"
|
|||
|
||||
config GENERATE_PIRQ_TABLE
|
||||
bool "Generate a PIRQ table"
|
||||
depends on !EFI
|
||||
default n
|
||||
help
|
||||
Generate a PIRQ routing table for this board. The PIRQ routing table
|
||||
|
@ -315,6 +321,7 @@ config GENERATE_PIRQ_TABLE
|
|||
|
||||
config GENERATE_SFI_TABLE
|
||||
bool "Generate a SFI (Simple Firmware Interface) table"
|
||||
depends on !EFI
|
||||
help
|
||||
The Simple Firmware Interface (SFI) provides a lightweight method
|
||||
for platform firmware to pass information to the operating system
|
||||
|
@ -329,6 +336,7 @@ config GENERATE_SFI_TABLE
|
|||
|
||||
config GENERATE_MP_TABLE
|
||||
bool "Generate an MP (Multi-Processor) table"
|
||||
depends on !EFI
|
||||
default n
|
||||
help
|
||||
Generate an MP (Multi-Processor) table for this board. The MP table
|
||||
|
@ -379,4 +387,6 @@ config PCIE_ECAM_SIZE
|
|||
so a default 0x10000000 size covers all of the 256 buses which is the
|
||||
maximum number of PCI buses as defined by the PCI specification.
|
||||
|
||||
source "arch/x86/lib/efi/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_EFI_APP),)
|
||||
head-y := arch/x86/cpu/start.o
|
||||
endif
|
||||
ifeq ($(CONFIG_SPL_BUILD),y)
|
||||
head-y += arch/x86/cpu/start16.o
|
||||
head-y += arch/x86/cpu/resetvec.o
|
||||
|
|
|
@ -8,19 +8,60 @@
|
|||
CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
|
||||
|
||||
PLATFORM_CPPFLAGS += -fno-strict-aliasing
|
||||
PLATFORM_CPPFLAGS += -mregparm=3
|
||||
PLATFORM_CPPFLAGS += -fomit-frame-pointer
|
||||
PF_CPPFLAGS_X86 := $(call cc-option, -fno-toplevel-reorder, \
|
||||
$(call cc-option, -fno-unit-at-a-time)) \
|
||||
$(call cc-option, -mpreferred-stack-boundary=2)
|
||||
|
||||
PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
|
||||
PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
|
||||
PLATFORM_CPPFLAGS += -march=i386 -m32
|
||||
|
||||
PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
|
||||
|
||||
PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions -m elf_i386
|
||||
PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
|
||||
|
||||
LDFLAGS_FINAL += --gc-sections -pie
|
||||
LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
|
||||
LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
|
||||
|
||||
# This is used in the top-level Makefile which does not include
|
||||
# PLATFORM_LDFLAGS
|
||||
LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
|
||||
|
||||
OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
|
||||
-j .rel -j .rela -j .reloc
|
||||
|
||||
CFLAGS_NON_EFI := -mregparm=3
|
||||
CFLAGS_EFI := -fpic -fshort-wchar
|
||||
|
||||
ifeq ($(CONFIG_EFI_STUB_64BIT),)
|
||||
CFLAGS_EFI += $(call cc-option, -mno-red-zone)
|
||||
EFIARCH = ia32
|
||||
EFIPAYLOAD_BFDTARGET = elf32-i386
|
||||
else
|
||||
EFIARCH = x86_64
|
||||
EFIPAYLOAD_BFDTARGET = elf64-x86-64
|
||||
endif
|
||||
|
||||
EFIPAYLOAD_BFDARCH = i386
|
||||
|
||||
LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
|
||||
EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o
|
||||
OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
|
||||
|
||||
CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
|
||||
CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI)
|
||||
|
||||
ifeq ($(CONFIG_EFI_APP),y)
|
||||
|
||||
PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
|
||||
LDFLAGS_FINAL += -znocombreloc -shared
|
||||
LDSCRIPT := $(LDSCRIPT_EFI)
|
||||
|
||||
else
|
||||
|
||||
PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI)
|
||||
PLATFORM_LDFLAGS += --emit-relocs
|
||||
LDFLAGS_FINAL += --gc-sections -pie
|
||||
|
||||
endif
|
||||
|
|
|
@ -12,8 +12,15 @@ extra-y = start.o
|
|||
obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
|
||||
obj-y += interrupts.o cpu.o cpu_x86.o call64.o
|
||||
|
||||
AFLAGS_REMOVE_call32.o := -mregparm=3 \
|
||||
$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
|
||||
AFLAGS_call32.o := -fpic -fshort-wchar
|
||||
|
||||
extra-y += call32.o
|
||||
|
||||
obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
|
||||
obj-$(CONFIG_SYS_COREBOOT) += coreboot/
|
||||
obj-$(CONFIG_EFI_APP) += efi/
|
||||
obj-$(CONFIG_QEMU) += qemu/
|
||||
obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
|
||||
obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
config INTEL_BAYTRAIL
|
||||
bool
|
||||
select HAVE_FSP
|
||||
select HAVE_FSP if !EFI
|
||||
|
|
|
@ -45,6 +45,8 @@ static void set_max_freq(void)
|
|||
|
||||
static int cpu_x86_baytrail_probe(struct udevice *dev)
|
||||
{
|
||||
if (!ll_boot_init())
|
||||
return 0;
|
||||
debug("Init BayTrail core\n");
|
||||
|
||||
/*
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <common.h>
|
||||
#include <mmc.h>
|
||||
#include <pci_ids.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/post.h>
|
||||
|
||||
static struct pci_device_id mmc_supported[] = {
|
||||
|
@ -20,6 +21,7 @@ int cpu_mmc_init(bd_t *bis)
|
|||
ARRAY_SIZE(mmc_supported));
|
||||
}
|
||||
|
||||
#ifndef CONFIG_EFI_APP
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -35,3 +37,11 @@ int arch_cpu_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
pirq_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
64
arch/x86/cpu/call32.S
Normal file
64
arch/x86/cpu/call32.S
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/msr-index.h>
|
||||
#include <asm/processor-flags.h>
|
||||
|
||||
/*
|
||||
* rdi - 32-bit code segment selector
|
||||
* rsi - target address
|
||||
* rdx - table address (0 if none)
|
||||
*/
|
||||
.code64
|
||||
.globl cpu_call32
|
||||
cpu_call32:
|
||||
cli
|
||||
|
||||
/* Save table pointer */
|
||||
mov %edx, %ebx
|
||||
|
||||
/*
|
||||
* Debugging option, this outputs characters to the console UART
|
||||
* mov $0x3f8,%edx
|
||||
* mov $'a',%al
|
||||
* out %al,(%dx)
|
||||
*/
|
||||
|
||||
pushf
|
||||
push %rdi /* 32-bit code segment */
|
||||
lea compat(%rip), %rax
|
||||
push %rax
|
||||
.byte 0x48 /* REX prefix to force 64-bit far return */
|
||||
retf
|
||||
.code32
|
||||
compat:
|
||||
/*
|
||||
* We are now in compatibility mode with a default operand size of
|
||||
* 32 bits. First disable paging.
|
||||
*/
|
||||
movl %cr0, %eax
|
||||
andl $~X86_CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Invalidate TLB */
|
||||
xorl %eax, %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
/* Disable Long mode in EFER (Extended Feature Enable Register) */
|
||||
movl $MSR_EFER, %ecx
|
||||
rdmsr
|
||||
btr $_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Set up table pointer for _x86boot_start */
|
||||
mov %ebx, %ecx
|
||||
|
||||
/* Jump to the required target */
|
||||
pushl %edi /* 32-bit code segment */
|
||||
pushl %esi /* 32-bit target address */
|
||||
retf
|
|
@ -82,8 +82,8 @@ lret_target:
|
|||
|
||||
.data
|
||||
gdt:
|
||||
.word gdt_end - gdt
|
||||
.long gdt
|
||||
.word gdt_end - gdt - 1
|
||||
.long gdt /* Fixed up by code above */
|
||||
.word 0
|
||||
.quad 0x0000000000000000 /* NULL descriptor */
|
||||
.quad 0x00af9a000000ffff /* __KERNEL_CS */
|
||||
|
|
|
@ -330,13 +330,15 @@ int x86_cpu_init_f(void)
|
|||
const u32 em_rst = ~X86_CR0_EM;
|
||||
const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
|
||||
|
||||
/* initialize FPU, reset EM, set MP and NE */
|
||||
asm ("fninit\n" \
|
||||
"movl %%cr0, %%eax\n" \
|
||||
"andl %0, %%eax\n" \
|
||||
"orl %1, %%eax\n" \
|
||||
"movl %%eax, %%cr0\n" \
|
||||
: : "i" (em_rst), "i" (mp_ne_set) : "eax");
|
||||
if (ll_boot_init()) {
|
||||
/* initialize FPU, reset EM, set MP and NE */
|
||||
asm ("fninit\n" \
|
||||
"movl %%cr0, %%eax\n" \
|
||||
"andl %0, %%eax\n" \
|
||||
"orl %1, %%eax\n" \
|
||||
"movl %%eax, %%cr0\n" \
|
||||
: : "i" (em_rst), "i" (mp_ne_set) : "eax");
|
||||
}
|
||||
|
||||
/* identify CPU via cpuid and store the decoded info into gd->arch */
|
||||
if (has_cpuid()) {
|
||||
|
@ -456,7 +458,7 @@ void x86_full_reset(void)
|
|||
|
||||
int dcache_status(void)
|
||||
{
|
||||
return !(read_cr0() & 0x40000000);
|
||||
return !(read_cr0() & X86_CR0_CD);
|
||||
}
|
||||
|
||||
/* Define these functions to allow ehch-hcd to function */
|
||||
|
@ -712,5 +714,8 @@ __weak int x86_init_cpus(void)
|
|||
|
||||
int cpu_init_r(void)
|
||||
{
|
||||
return x86_init_cpus();
|
||||
if (ll_boot_init())
|
||||
return x86_init_cpus();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
8
arch/x86/cpu/efi/Makefile
Normal file
8
arch/x86/cpu/efi/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Copyright (c) 2015 Google, Inc
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += efi.o
|
||||
obj-y += sdram.o
|
42
arch/x86/cpu/efi/efi.c
Normal file
42
arch/x86/cpu/efi/efi.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <netdev.h>
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_X86_TSC_TIMER
|
||||
timer_set_base(rdtsc());
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
return default_print_cpuinfo();
|
||||
}
|
||||
|
||||
void board_final_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
94
arch/x86/cpu/efi/elf_ia32_efi.lds
Normal file
94
arch/x86/cpu/efi/elf_ia32_efi.lds
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* U-Boot EFI linker script
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
image_base = .;
|
||||
.hash : { *(.hash) } /* this MUST come first, EFI expects it */
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.sdata :
|
||||
{
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.srodata)
|
||||
*(.sdata)
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.data :
|
||||
{
|
||||
*(.rodata*)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.sdata)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
/*
|
||||
* the EFI loader doesn't seem to like a .bss section, so we
|
||||
* stick it all into .data:
|
||||
*/
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
|
||||
/* U-Boot lists and device tree */
|
||||
. = ALIGN(8);
|
||||
*(SORT(.u_boot_list*));
|
||||
. = ALIGN(8);
|
||||
*(.dtb*);
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rel :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.got)
|
||||
*(.rel.stab)
|
||||
*(.data.rel.ro.local)
|
||||
*(.data.rel.local)
|
||||
*(.data.rel.ro)
|
||||
*(.data.rel*)
|
||||
*(.rel.u_boot_list*)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.reloc : /* This is the PECOFF .reloc section! */
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
83
arch/x86/cpu/efi/elf_x86_64_efi.lds
Normal file
83
arch/x86/cpu/efi/elf_x86_64_efi.lds
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* U-Boot EFI linker script
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
image_base = .;
|
||||
.hash : { *(.hash) } /* this MUST come first, EFI expects it */
|
||||
. = ALIGN(4096);
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
|
||||
.reloc : {
|
||||
*(.reloc)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
|
||||
.data : {
|
||||
*(.rodata*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.data*)
|
||||
*(.sdata)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
* it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
*(.rel.local)
|
||||
|
||||
/* U-Boot lists and device tree */
|
||||
. = ALIGN(8);
|
||||
*(SORT(.u_boot_list*));
|
||||
. = ALIGN(8);
|
||||
*(.dtb*);
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
|
||||
.rela : {
|
||||
*(.rela.data*)
|
||||
*(.rela.got)
|
||||
*(.rela.stab)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.ignored.reloc : {
|
||||
*(.rela.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
29
arch/x86/cpu/efi/sdram.c
Normal file
29
arch/x86/cpu/efi/sdram.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <efi.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
ulong board_get_usable_ram_top(ulong total_size)
|
||||
{
|
||||
return (ulong)efi_get_ram_base() + gd->ram_size;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
/* gd->ram_size is set as part of EFI init */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dram_init_banksize(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = efi_get_ram_base();
|
||||
gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE;
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
#include <asm/processor-flags.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <asm/i8259.h>
|
||||
|
||||
|
@ -46,7 +47,7 @@ static char *exceptions[] = {
|
|||
"Invalid TSS",
|
||||
"Segment Not Present",
|
||||
"Stack Segment Fault",
|
||||
"Gerneral Protection",
|
||||
"General Protection",
|
||||
"Page Fault",
|
||||
"Reserved",
|
||||
"x87 FPU Floating-Point Error",
|
||||
|
@ -165,7 +166,6 @@ struct idt_entry {
|
|||
struct desc_ptr {
|
||||
unsigned short size;
|
||||
unsigned long address;
|
||||
unsigned short segment;
|
||||
} __packed;
|
||||
|
||||
struct idt_entry idt[256] __aligned(16);
|
||||
|
@ -202,14 +202,13 @@ int cpu_init_interrupts(void)
|
|||
for (i = 0; i < 256; i++) {
|
||||
idt[i].access = 0x8e;
|
||||
idt[i].res = 0;
|
||||
idt[i].selector = 0x10;
|
||||
idt[i].selector = X86_GDT_ENTRY_32BIT_CS * X86_GDT_ENTRY_SIZE;
|
||||
set_vector(i, irq_entry);
|
||||
irq_entry += irq_entry_size;
|
||||
}
|
||||
|
||||
idt_ptr.size = 256 * 8;
|
||||
idt_ptr.size = 256 * 8 - 1;
|
||||
idt_ptr.address = (unsigned long) idt;
|
||||
idt_ptr.segment = 0x18;
|
||||
|
||||
load_idt(&idt_ptr);
|
||||
|
||||
|
@ -243,6 +242,11 @@ int disable_interrupts(void)
|
|||
|
||||
int interrupt_init(void)
|
||||
{
|
||||
/*
|
||||
* When running as an EFI application we are not in control of
|
||||
* interrupts and should leave them alone.
|
||||
*/
|
||||
#ifndef CONFIG_EFI_APP
|
||||
/* Just in case... */
|
||||
disable_interrupts();
|
||||
|
||||
|
@ -254,8 +258,15 @@ int interrupt_init(void)
|
|||
/* Initialize core interrupt and exception functionality of CPU */
|
||||
cpu_init_interrupts();
|
||||
|
||||
/* It is now safe to enable interrupts */
|
||||
enable_interrupts();
|
||||
/*
|
||||
* It is now safe to enable interrupts.
|
||||
*
|
||||
* TODO(sjg@chromium.org): But we don't handle these correctly when
|
||||
* booted from EFI.
|
||||
*/
|
||||
if (ll_boot_init())
|
||||
enable_interrupts();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <dm/uclass-internal.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* Total CPUs include BSP */
|
||||
static int num_cpus;
|
||||
|
||||
|
|
|
@ -4,5 +4,8 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += car.o dram.o qemu.o
|
||||
ifndef CONFIG_EFI_STUB
|
||||
obj-y += car.o dram.o
|
||||
endif
|
||||
obj-y += qemu.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
|
|
|
@ -25,11 +25,13 @@ int arch_cpu_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_EFI_STUB
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
post_code(POST_CPU_INFO);
|
||||
return default_print_cpuinfo();
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
.globl _x86boot_start
|
||||
_x86boot_start:
|
||||
/*
|
||||
* This is the fail safe 32-bit bootstrap entry point. The
|
||||
* following code is not executed from a cold-reset (actually, a
|
||||
* lot of it is, but from real-mode after cold reset. It is
|
||||
* repeated here to put the board into a state as close to cold
|
||||
* reset as necessary)
|
||||
* This is the fail-safe 32-bit bootstrap entry point.
|
||||
*
|
||||
* This code is used when booting from another boot loader like
|
||||
* coreboot or EFI. So we repeat some of the same init found in
|
||||
* start16.
|
||||
*/
|
||||
cli
|
||||
cld
|
||||
|
@ -41,19 +41,34 @@ _x86boot_start:
|
|||
wbinvd
|
||||
|
||||
/* Tell 32-bit code it is being entered from an in-RAM copy */
|
||||
movw $GD_FLG_WARM_BOOT, %bx
|
||||
movl $GD_FLG_WARM_BOOT, %ebx
|
||||
|
||||
/*
|
||||
* Zero the BIST (Built-In Self Test) value since we don't have it.
|
||||
* It must be 0 or the previous loader would have reported an error.
|
||||
*/
|
||||
movl $0, %ebp
|
||||
|
||||
jmp 1f
|
||||
|
||||
/* Add a way for tools to discover the _start entry point */
|
||||
.align 4
|
||||
.long 0x12345678
|
||||
_start:
|
||||
/*
|
||||
* This is the 32-bit cold-reset entry point. Initialize %bx to 0
|
||||
* in case we're preceeded by some sort of boot stub.
|
||||
* This is the 32-bit cold-reset entry point, coming from start16.
|
||||
* Set %ebx to GD_FLG_COLD_BOOT to indicate this.
|
||||
*/
|
||||
movw $GD_FLG_COLD_BOOT, %bx
|
||||
1:
|
||||
movl $GD_FLG_COLD_BOOT, %ebx
|
||||
|
||||
/* Save BIST */
|
||||
movl %eax, %ebp
|
||||
1:
|
||||
|
||||
/* Load the segement registes to match the gdt loaded in start16.S */
|
||||
/* Save table pointer */
|
||||
movl %ecx, %esi
|
||||
|
||||
/* Load the segement registers to match the GDT loaded in start16.S */
|
||||
movl $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax
|
||||
movw %ax, %fs
|
||||
movw %ax, %ds
|
||||
|
@ -64,7 +79,11 @@ _start:
|
|||
/* Clear the interrupt vectors */
|
||||
lidt blank_idt_ptr
|
||||
|
||||
/* Early platform init (setup gpio, etc ) */
|
||||
/*
|
||||
* Critical early platform init - generally not used, we prefer init
|
||||
* to happen later when we have a console, in case something goes
|
||||
* wrong.
|
||||
*/
|
||||
jmp early_board_init
|
||||
.globl early_board_init_ret
|
||||
early_board_init_ret:
|
||||
|
@ -79,7 +98,7 @@ car_init_ret:
|
|||
* We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM,
|
||||
* or fully initialised SDRAM - we really don't care which)
|
||||
* starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack
|
||||
* and early malloc area. The MRC requires some space at the top.
|
||||
* and early malloc() area. The MRC requires some space at the top.
|
||||
*
|
||||
* Stack grows down from top of CAR. We have:
|
||||
*
|
||||
|
@ -97,7 +116,7 @@ car_init_ret:
|
|||
#endif
|
||||
#else
|
||||
/*
|
||||
* When we get here after car_init, esp points to a temporary stack
|
||||
* 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
|
||||
|
@ -125,7 +144,13 @@ car_init_ret:
|
|||
movl %esi, (%edx)
|
||||
|
||||
skip_hob:
|
||||
#else
|
||||
/* Store table pointer */
|
||||
movl %esp, %edx
|
||||
addl $GD_TABLE, %edx
|
||||
movl %esi, (%edx)
|
||||
#endif
|
||||
|
||||
/* Setup first parameter to setup_gdt, pointer to global_data */
|
||||
movl %esp, %eax
|
||||
|
||||
|
@ -137,17 +162,18 @@ skip_hob:
|
|||
movl %esp, %ecx
|
||||
|
||||
#if defined(CONFIG_SYS_MALLOC_F_LEN)
|
||||
/* Set up the pre-relocation malloc pool */
|
||||
subl $CONFIG_SYS_MALLOC_F_LEN, %esp
|
||||
movl %eax, %edx
|
||||
addl $GD_MALLOC_BASE, %edx
|
||||
movl %esp, (%edx)
|
||||
#endif
|
||||
/* Store BIST */
|
||||
/* Store BIST into global_data */
|
||||
movl %eax, %edx
|
||||
addl $GD_BIST, %edx
|
||||
movl %ebp, (%edx)
|
||||
|
||||
/* Set second parameter to setup_gdt */
|
||||
/* Set second parameter to setup_gdt() */
|
||||
movl %ecx, %edx
|
||||
|
||||
/* Setup global descriptor table so gd->xyz works */
|
||||
|
@ -157,7 +183,7 @@ skip_hob:
|
|||
post_code(POST_START_DONE)
|
||||
xorl %eax, %eax
|
||||
|
||||
/* Enter, U-boot! */
|
||||
/* Enter, U-Boot! */
|
||||
call board_init_f
|
||||
|
||||
/* indicate (lack of) progress */
|
||||
|
@ -184,13 +210,13 @@ board_init_f_r_trampoline:
|
|||
/* Align global data to 16-byte boundary */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
/* Setup first parameter to memcpy (and setup_gdt) */
|
||||
/* Setup first parameter to memcpy() and setup_gdt() */
|
||||
movl %esp, %eax
|
||||
|
||||
/* Setup second parameter to memcpy */
|
||||
/* Setup second parameter to memcpy() */
|
||||
fs movl 0, %edx
|
||||
|
||||
/* Set third parameter to memcpy */
|
||||
/* Set third parameter to memcpy() */
|
||||
movl $GENERATED_GBL_DATA_SIZE, %ecx
|
||||
|
||||
/* Copy global data from CAR to SDRAM stack */
|
||||
|
@ -202,7 +228,7 @@ board_init_f_r_trampoline:
|
|||
/* Align global descriptor table to 16-byte boundary */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
/* Set second parameter to setup_gdt */
|
||||
/* Set second parameter to setup_gdt() */
|
||||
movl %esp, %edx
|
||||
|
||||
/* Setup global descriptor table so gd->xyz works */
|
||||
|
@ -216,7 +242,7 @@ board_init_f_r_trampoline:
|
|||
|
||||
call car_uninit
|
||||
1:
|
||||
/* Re-enter U-Boot by calling board_init_f_r */
|
||||
/* Re-enter U-Boot by calling board_init_f_r() */
|
||||
call board_init_f_r
|
||||
|
||||
die:
|
||||
|
@ -230,9 +256,10 @@ blank_idt_ptr:
|
|||
|
||||
.p2align 2 /* force 4-byte alignment */
|
||||
|
||||
/* Add a multiboot header so U-Boot can be loaded by GRUB2 */
|
||||
multiboot_header:
|
||||
/* magic */
|
||||
.long 0x1BADB002
|
||||
.long 0x1badb002
|
||||
/* flags */
|
||||
.long (1 << 16)
|
||||
/* checksum */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
dtb-y += chromebook_link.dtb \
|
||||
dtb-y += bayleybay.dtb \
|
||||
chromebook_link.dtb \
|
||||
chromebox_panther.dtb \
|
||||
crownbay.dtb \
|
||||
efi.dtb \
|
||||
galileo.dtb \
|
||||
minnowmax.dtb \
|
||||
qemu-x86_i440fx.dtb \
|
||||
|
|
197
arch/x86/dts/bayleybay.dts
Normal file
197
arch/x86/dts/bayleybay.dts
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/x86-gpio.h>
|
||||
#include <dt-bindings/interrupt-router/intel-irq.h>
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
/include/ "serial.dtsi"
|
||||
/include/ "rtc.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Intel Bayley Bay";
|
||||
compatible = "intel,bayleybay", "intel,baytrail";
|
||||
|
||||
aliases {
|
||||
serial0 = &serial;
|
||||
spi0 = "/spi";
|
||||
};
|
||||
|
||||
config {
|
||||
silent_console = <0>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "/serial";
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "intel,baytrail-cpu";
|
||||
reg = <0>;
|
||||
intel,apic-id = <0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "intel,baytrail-cpu";
|
||||
reg = <1>;
|
||||
intel,apic-id = <2>;
|
||||
};
|
||||
|
||||
cpu@2 {
|
||||
device_type = "cpu";
|
||||
compatible = "intel,baytrail-cpu";
|
||||
reg = <2>;
|
||||
intel,apic-id = <4>;
|
||||
};
|
||||
|
||||
cpu@3 {
|
||||
device_type = "cpu";
|
||||
compatible = "intel,baytrail-cpu";
|
||||
reg = <3>;
|
||||
intel,apic-id = <6>;
|
||||
};
|
||||
};
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "intel,ich-spi";
|
||||
spi-flash@0 {
|
||||
reg = <0>;
|
||||
compatible = "winbond,w25q64dw", "spi-flash";
|
||||
memory-map = <0xff800000 0x00800000>;
|
||||
};
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
|
||||
gpioc {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x40 0x20>;
|
||||
bank-name = "C";
|
||||
};
|
||||
|
||||
gpiod {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x60 0x20>;
|
||||
bank-name = "D";
|
||||
};
|
||||
|
||||
gpioe {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x80 0x20>;
|
||||
bank-name = "E";
|
||||
};
|
||||
|
||||
gpiof {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0xA0 0x20>;
|
||||
bank-name = "F";
|
||||
};
|
||||
|
||||
pci {
|
||||
compatible = "pci-x86";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
u-boot,dm-pre-reloc;
|
||||
ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000
|
||||
0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
|
||||
0x01000000 0x0 0x2000 0x2000 0 0xe000>;
|
||||
|
||||
irq-router@1f,0 {
|
||||
reg = <0x0000f800 0 0 0 0>;
|
||||
compatible = "intel,irq-router";
|
||||
intel,pirq-config = "ibase";
|
||||
intel,ibase-offset = <0x50>;
|
||||
intel,pirq-link = <8 8>;
|
||||
intel,pirq-mask = <0xdee0>;
|
||||
intel,pirq-routing = <
|
||||
/* BayTrail PCI devices */
|
||||
PCI_BDF(0, 2, 0) INTA PIRQA
|
||||
PCI_BDF(0, 3, 0) INTA PIRQA
|
||||
PCI_BDF(0, 16, 0) INTA PIRQA
|
||||
PCI_BDF(0, 17, 0) INTA PIRQA
|
||||
PCI_BDF(0, 18, 0) INTA PIRQA
|
||||
PCI_BDF(0, 19, 0) INTA PIRQA
|
||||
PCI_BDF(0, 20, 0) INTA PIRQA
|
||||
PCI_BDF(0, 21, 0) INTA PIRQA
|
||||
PCI_BDF(0, 22, 0) INTA PIRQA
|
||||
PCI_BDF(0, 23, 0) INTA PIRQA
|
||||
PCI_BDF(0, 24, 0) INTA PIRQA
|
||||
PCI_BDF(0, 24, 1) INTC PIRQC
|
||||
PCI_BDF(0, 24, 2) INTD PIRQD
|
||||
PCI_BDF(0, 24, 3) INTB PIRQB
|
||||
PCI_BDF(0, 24, 4) INTA PIRQA
|
||||
PCI_BDF(0, 24, 5) INTC PIRQC
|
||||
PCI_BDF(0, 24, 6) INTD PIRQD
|
||||
PCI_BDF(0, 24, 7) INTB PIRQB
|
||||
PCI_BDF(0, 26, 0) INTA PIRQA
|
||||
PCI_BDF(0, 27, 0) INTA PIRQA
|
||||
PCI_BDF(0, 28, 0) INTA PIRQA
|
||||
PCI_BDF(0, 28, 1) INTB PIRQB
|
||||
PCI_BDF(0, 28, 2) INTC PIRQC
|
||||
PCI_BDF(0, 28, 3) INTD PIRQD
|
||||
PCI_BDF(0, 29, 0) INTA PIRQA
|
||||
PCI_BDF(0, 30, 0) INTA PIRQA
|
||||
PCI_BDF(0, 30, 1) INTD PIRQD
|
||||
PCI_BDF(0, 30, 2) INTB PIRQB
|
||||
PCI_BDF(0, 30, 3) INTC PIRQC
|
||||
PCI_BDF(0, 30, 4) INTD PIRQD
|
||||
PCI_BDF(0, 30, 5) INTB PIRQB
|
||||
PCI_BDF(0, 31, 3) INTB PIRQB
|
||||
|
||||
/* PCIe root ports downstream interrupts */
|
||||
PCI_BDF(1, 0, 0) INTA PIRQA
|
||||
PCI_BDF(1, 0, 0) INTB PIRQB
|
||||
PCI_BDF(1, 0, 0) INTC PIRQC
|
||||
PCI_BDF(1, 0, 0) INTD PIRQD
|
||||
PCI_BDF(2, 0, 0) INTA PIRQB
|
||||
PCI_BDF(2, 0, 0) INTB PIRQC
|
||||
PCI_BDF(2, 0, 0) INTC PIRQD
|
||||
PCI_BDF(2, 0, 0) INTD PIRQA
|
||||
PCI_BDF(3, 0, 0) INTA PIRQC
|
||||
PCI_BDF(3, 0, 0) INTB PIRQD
|
||||
PCI_BDF(3, 0, 0) INTC PIRQA
|
||||
PCI_BDF(3, 0, 0) INTD PIRQB
|
||||
PCI_BDF(4, 0, 0) INTA PIRQD
|
||||
PCI_BDF(4, 0, 0) INTB PIRQA
|
||||
PCI_BDF(4, 0, 0) INTC PIRQB
|
||||
PCI_BDF(4, 0, 0) INTD PIRQC
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
microcode {
|
||||
update@0 {
|
||||
#include "microcode/m0230671117.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
};
|
22
arch/x86/dts/efi.dts
Normal file
22
arch/x86/dts/efi.dts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
model = "EFI";
|
||||
compatible = "efi,app";
|
||||
|
||||
chosen {
|
||||
stdout-path = &serial;
|
||||
};
|
||||
|
||||
serial: serial {
|
||||
compatible = "efi,uart";
|
||||
};
|
||||
};
|
4244
arch/x86/dts/microcode/m0230671117.dtsi
Normal file
4244
arch/x86/dts/microcode/m0230671117.dtsi
Normal file
File diff suppressed because it is too large
Load diff
|
@ -34,6 +34,13 @@
|
|||
reg = <0>;
|
||||
intel,apic-id = <0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "cpu-x86";
|
||||
reg = <1>;
|
||||
intel,apic-id = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
pci {
|
||||
|
|
|
@ -45,6 +45,13 @@
|
|||
reg = <0>;
|
||||
intel,apic-id = <0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "cpu-x86";
|
||||
reg = <1>;
|
||||
intel,apic-id = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
pci {
|
||||
|
|
|
@ -75,7 +75,8 @@ struct __packed upd_region {
|
|||
uint8_t emmc45_ddr50_enabled; /* Offset 0x0051 */
|
||||
uint8_t emmc45_hs200_enabled; /* Offset 0x0052 */
|
||||
uint8_t emmc45_retune_timer_value; /* Offset 0x0053 */
|
||||
uint8_t unused_upd_space1[156]; /* Offset 0x0054 */
|
||||
uint8_t enable_igd; /* Offset 0x0054 */
|
||||
uint8_t unused_upd_space1[155]; /* Offset 0x0055 */
|
||||
struct memory_down_data memory_params; /* Offset 0x00f0 */
|
||||
uint16_t terminator; /* Offset 0x0100 */
|
||||
};
|
||||
|
|
10
arch/x86/include/asm/arch-efi/gpio.h
Normal file
10
arch/x86/include/asm/arch-efi/gpio.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _X86_ARCH_GPIO_H_
|
||||
#define _X86_ARCH_GPIO_H_
|
||||
|
||||
#endif /* _X86_ARCH_GPIO_H_ */
|
|
@ -27,6 +27,24 @@ enum {
|
|||
X86_VENDOR_UNKNOWN = 0xff
|
||||
};
|
||||
|
||||
/* Global descriptor table (GDT) bits */
|
||||
enum {
|
||||
GDT_4KB = 1ULL << 55,
|
||||
GDT_32BIT = 1ULL << 54,
|
||||
GDT_LONG = 1ULL << 53,
|
||||
GDT_PRESENT = 1ULL << 47,
|
||||
GDT_NOTSYS = 1ULL << 44,
|
||||
GDT_CODE = 1ULL << 43,
|
||||
GDT_LIMIT_LOW_SHIFT = 0,
|
||||
GDT_LIMIT_LOW_MASK = 0xffff,
|
||||
GDT_LIMIT_HIGH_SHIFT = 48,
|
||||
GDT_LIMIT_HIGH_MASK = 0xf,
|
||||
GDT_BASE_LOW_SHIFT = 16,
|
||||
GDT_BASE_LOW_MASK = 0xffff,
|
||||
GDT_BASE_HIGH_SHIFT = 56,
|
||||
GDT_BASE_HIGH_MASK = 0xf,
|
||||
};
|
||||
|
||||
struct cpuid_result {
|
||||
uint32_t eax;
|
||||
uint32_t ebx;
|
||||
|
@ -211,6 +229,15 @@ char *cpu_get_name(char *name);
|
|||
*/
|
||||
void cpu_call64(ulong pgtable, ulong setup_base, ulong target);
|
||||
|
||||
/**
|
||||
* cpu_call32() - Jump to a 32-bit entry point
|
||||
*
|
||||
* @code_seg32: 32-bit code segment to use (GDT offset, e.g. 0x20)
|
||||
* @target: Pointer to the start of the 32-bit U-Boot image/entry point
|
||||
* @table: Pointer to start of info table to pass to U-Boot
|
||||
*/
|
||||
void cpu_call32(ulong code_seg32, ulong target, ulong table);
|
||||
|
||||
/**
|
||||
* cpu_jump_to_64bit() - Jump to a 64-bit Linux kernel
|
||||
*
|
||||
|
|
46
arch/x86/include/asm/elf.h
Normal file
46
arch/x86/include/asm/elf.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Brought in from Linux 4.1, removed things not useful to U-Boot.
|
||||
* The definitions perhaps came from the GNU Library which is GPL.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_ELF_H
|
||||
#define _ASM_X86_ELF_H
|
||||
|
||||
/* ELF register definitions */
|
||||
#define R_386_NONE 0
|
||||
#define R_386_32 1
|
||||
#define R_386_PC32 2
|
||||
#define R_386_GOT32 3
|
||||
#define R_386_PLT32 4
|
||||
#define R_386_COPY 5
|
||||
#define R_386_GLOB_DAT 6
|
||||
#define R_386_JMP_SLOT 7
|
||||
#define R_386_RELATIVE 8
|
||||
#define R_386_GOTOFF 9
|
||||
#define R_386_GOTPC 10
|
||||
#define R_386_NUM 11
|
||||
|
||||
/* x86-64 relocation types */
|
||||
#define R_X86_64_NONE 0 /* No reloc */
|
||||
#define R_X86_64_64 1 /* Direct 64 bit */
|
||||
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
|
||||
#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
|
||||
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
|
||||
#define R_X86_64_COPY 5 /* Copy symbol at runtime */
|
||||
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
|
||||
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
|
||||
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
|
||||
/* 32 bit signed pc relative offset to GOT */
|
||||
#define R_X86_64_GOTPCREL 9
|
||||
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
|
||||
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
|
||||
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
|
||||
#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
|
||||
#define R_X86_64_8 14 /* Direct 8 bit sign extended */
|
||||
#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
|
||||
|
||||
#define R_X86_64_NUM 16
|
||||
|
||||
#endif
|
|
@ -8,6 +8,8 @@
|
|||
#ifndef __FSP_HOB_H__
|
||||
#define __FSP_HOB_H__
|
||||
|
||||
#include <efi.h>
|
||||
|
||||
/* Type of HOB Header */
|
||||
#define HOB_TYPE_MEM_ALLOC 0x0002
|
||||
#define HOB_TYPE_RES_DESC 0x0003
|
||||
|
@ -25,63 +27,6 @@ struct hob_header {
|
|||
u32 reserved; /* always zero */
|
||||
};
|
||||
|
||||
/* Enumeration of memory types introduced in UEFI */
|
||||
enum efi_mem_type {
|
||||
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,
|
||||
|
|
|
@ -69,6 +69,7 @@ struct arch_global_data {
|
|||
char *mrc_output;
|
||||
unsigned int mrc_output_len;
|
||||
void *gdt; /* Global descriptor table */
|
||||
ulong table; /* Table pointer from previous loader */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -76,6 +77,12 @@ struct arch_global_data {
|
|||
#include <asm-generic/global_data.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# ifdef CONFIG_EFI_APP
|
||||
|
||||
#define gd global_data_ptr
|
||||
|
||||
#define DECLARE_GLOBAL_DATA_PTR extern struct global_data *global_data_ptr
|
||||
# else
|
||||
static inline __attribute__((no_instrument_function)) gd_t *get_fs_gd_ptr(void)
|
||||
{
|
||||
gd_t *gd_ptr;
|
||||
|
@ -87,14 +94,15 @@ static inline __attribute__((no_instrument_function)) gd_t *get_fs_gd_ptr(void)
|
|||
|
||||
#define gd get_fs_gd_ptr()
|
||||
|
||||
#define DECLARE_GLOBAL_DATA_PTR
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Our private Global Data Flags
|
||||
*/
|
||||
#define GD_FLG_COLD_BOOT 0x00100 /* Cold Boot */
|
||||
#define GD_FLG_WARM_BOOT 0x00200 /* Warm Boot */
|
||||
|
||||
#define DECLARE_GLOBAL_DATA_PTR
|
||||
#define GD_FLG_COLD_BOOT 0x10000 /* Cold Boot */
|
||||
#define GD_FLG_WARM_BOOT 0x20000 /* Warm Boot */
|
||||
|
||||
#endif /* __ASM_GBL_DATA_H */
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <common.h>
|
||||
|
||||
int copy_uboot_to_ram(void);
|
||||
int copy_fdt_to_ram(void);
|
||||
int clear_bss(void);
|
||||
int do_elf_reloc_fixups(void);
|
||||
|
||||
|
|
|
@ -44,8 +44,11 @@ typedef __INT64_TYPE__ s64;
|
|||
typedef __UINT64_TYPE__ u64;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EFI_STUB_64BIT
|
||||
#define BITS_PER_LONG 64
|
||||
#else
|
||||
#define BITS_PER_LONG 32
|
||||
|
||||
#endif
|
||||
/* Dma addresses are 32-bits wide. */
|
||||
|
||||
typedef u32 dma_addr_t;
|
||||
|
|
|
@ -11,6 +11,7 @@ obj-y += bios_interrupts.o
|
|||
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
||||
obj-y += cmd_boot.o
|
||||
obj-$(CONFIG_HAVE_FSP) += cmd_hob.o
|
||||
obj-$(CONFIG_EFI) += efi/
|
||||
obj-y += gcc.o
|
||||
obj-y += init_helpers.o
|
||||
obj-y += interrupts.o
|
||||
|
@ -34,7 +35,7 @@ obj-$(CONFIG_SYS_X86_TSC_TIMER) += tsc_timer.o
|
|||
obj-$(CONFIG_CMD_ZBOOT) += zimage.o
|
||||
obj-$(CONFIG_HAVE_FSP) += fsp/
|
||||
|
||||
extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a
|
||||
extra-$(CONFIG_USE_PRIVATE_LIBGCC) += lib.a
|
||||
|
||||
NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
|
||||
OBJCOPYFLAGS := --prefix-symbols=__normal_
|
||||
|
|
|
@ -21,5 +21,6 @@ int main(void)
|
|||
#ifdef CONFIG_HAVE_FSP
|
||||
DEFINE(GD_HOB_LIST, offsetof(gd_t, arch.hob_list));
|
||||
#endif
|
||||
DEFINE(GD_TABLE, offsetof(gd_t, arch.table));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <asm/arch/timestamp.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define COMMAND_LINE_OFFSET 0x9000
|
||||
|
||||
/*
|
||||
|
@ -162,7 +164,11 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
|
|||
* the data segments are 0x18, 4GB flat, and read/write.
|
||||
* U-boot is setting them up that way for itself in
|
||||
* arch/i386/cpu/cpu.c.
|
||||
*
|
||||
* Note that we cannot currently boot a kernel while running as
|
||||
* an EFI application. Please use the payload option for that.
|
||||
*/
|
||||
#ifndef CONFIG_EFI_APP
|
||||
__asm__ __volatile__ (
|
||||
"movl $0, %%ebp\n"
|
||||
"cli\n"
|
||||
|
@ -171,6 +177,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
|
|||
[boot_params] "S"(setup_base),
|
||||
"b"(0), "D"(0)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We can't get to here */
|
||||
|
|
11
arch/x86/lib/efi/Kconfig
Normal file
11
arch/x86/lib/efi/Kconfig
Normal file
|
@ -0,0 +1,11 @@
|
|||
if EFI
|
||||
|
||||
config SYS_CAR_ADDR
|
||||
hex
|
||||
default 0x100000
|
||||
|
||||
config SYS_CAR_SIZE
|
||||
hex
|
||||
default 0x20000
|
||||
|
||||
endif
|
27
arch/x86/lib/efi/Makefile
Normal file
27
arch/x86/lib/efi/Makefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_EFI_STUB) += car.o
|
||||
obj-$(CONFIG_EFI_STUB) += efi.o
|
||||
|
||||
obj-$(CONFIG_EFI_APP) += crt0-efi-ia32.o reloc_ia32.o
|
||||
|
||||
ifneq ($(CONFIG_EFI_STUB),)
|
||||
|
||||
CFLAGS_REMOVE_reloc_ia32.o += -mregparm=3
|
||||
CFLAGS_reloc_ia32.o += -fpic -fshort-wchar
|
||||
|
||||
# When building for 64-bit we must remove the i386-specific flags
|
||||
CFLAGS_REMOVE_reloc_x86_64.o += -mregparm=3 -march=i386 -m32
|
||||
CFLAGS_reloc_x86_64.o += -fpic -fshort-wchar
|
||||
|
||||
AFLAGS_REMOVE_crt0-efi-x86_64.o += -mregparm=3 -march=i386 -m32
|
||||
AFLAGS_crt0-efi-x86_64.o += -fpic -fshort-wchar
|
||||
|
||||
extra-$(CONFIG_EFI_STUB_32BIT) += crt0-efi-ia32.o reloc_ia32.o
|
||||
extra-$(CONFIG_EFI_STUB_64BIT) += crt0-efi-x86_64.o reloc_x86_64.o
|
||||
endif
|
10
arch/x86/lib/efi/car.S
Normal file
10
arch/x86/lib/efi/car.S
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
.globl car_init
|
||||
car_init:
|
||||
jmp car_init_ret
|
52
arch/x86/lib/efi/crt0-efi-ia32.S
Normal file
52
arch/x86/lib/efi/crt0-efi-ia32.S
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* crt0-efi-ia32.S - x86 EFI startup code.
|
||||
*
|
||||
* Copyright (C) 1999 Hewlett-Packard Co.
|
||||
* Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
pushl 12(%ebp) # copy "image" argument
|
||||
pushl 8(%ebp) # copy "systab" argument
|
||||
|
||||
call 0f
|
||||
0: popl %eax
|
||||
movl %eax,%ebx
|
||||
|
||||
addl $image_base-0b,%eax # %eax = ldbase
|
||||
addl $_DYNAMIC-0b,%ebx # %ebx = _DYNAMIC
|
||||
|
||||
pushl %ebx # pass _DYNAMIC as second argument
|
||||
pushl %eax # pass ldbase as first argument
|
||||
call _relocate
|
||||
popl %ebx
|
||||
popl %ebx
|
||||
testl %eax,%eax
|
||||
jne .exit
|
||||
call efi_main # call app with "image" and "systab" argument
|
||||
|
||||
.exit: leave
|
||||
ret
|
||||
|
||||
/*
|
||||
* hand-craft a dummy .reloc section so EFI knows it's a relocatable
|
||||
* executable:
|
||||
*/
|
||||
.data
|
||||
dummy: .long 0
|
||||
|
||||
#define IMAGE_REL_ABSOLUTE 0
|
||||
.section .reloc
|
||||
.long dummy /* Page RVA */
|
||||
.long 10 /* Block Size (2*4+2) */
|
||||
.word (IMAGE_REL_ABSOLUTE << 12) + 0 /* reloc for dummy */
|
51
arch/x86/lib/efi/crt0-efi-x86_64.S
Normal file
51
arch/x86/lib/efi/crt0-efi-x86_64.S
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.
|
||||
* Contributed by Fenghua Yu <fenghua.yu@intel.com>.
|
||||
*
|
||||
* All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
subq $8, %rsp
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
|
||||
0:
|
||||
lea image_base(%rip), %rdi
|
||||
lea _DYNAMIC(%rip), %rsi
|
||||
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
call _relocate
|
||||
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
|
||||
call efi_main
|
||||
addq $8, %rsp
|
||||
|
||||
.exit:
|
||||
ret
|
||||
|
||||
/*
|
||||
* hand-craft a dummy .reloc section so EFI knows it's a relocatable
|
||||
* executable:
|
||||
*/
|
||||
.data
|
||||
dummy: .long 0
|
||||
|
||||
#define IMAGE_REL_ABSOLUTE 0
|
||||
.section .reloc, "a"
|
||||
label1:
|
||||
.long dummy-label1 /* Page RVA */
|
||||
.long 10 /* Block Size (2*4+2) */
|
||||
.word (IMAGE_REL_ABSOLUTE << 12) + 0 /* reloc for dummy */
|
151
arch/x86/lib/efi/efi.c
Normal file
151
arch/x86/lib/efi/efi.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <efi.h>
|
||||
#include <errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
struct efi_mem_desc *desc, *end;
|
||||
struct efi_entry_memmap *map;
|
||||
int ret, size;
|
||||
uintptr_t dest_addr = 0;
|
||||
struct efi_mem_desc *largest = NULL;
|
||||
|
||||
/*
|
||||
* Find largest area of memory below 4GB. We could
|
||||
* call efi_build_mem_table() for a more accurate picture since it
|
||||
* merges areas together where possible. But that function uses more
|
||||
* pre-relocation memory, and it's not critical that we find the
|
||||
* absolute largest region.
|
||||
*/
|
||||
ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
|
||||
if (ret) {
|
||||
/* We should have stopped in dram_init(), something is wrong */
|
||||
debug("%s: Missing memory map\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
end = (struct efi_mem_desc *)((ulong)map + size);
|
||||
desc = map->desc;
|
||||
for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
|
||||
if (desc->type != EFI_CONVENTIONAL_MEMORY ||
|
||||
desc->physical_start >= 1ULL << 32)
|
||||
continue;
|
||||
if (!largest || desc->num_pages > largest->num_pages)
|
||||
largest = desc;
|
||||
}
|
||||
|
||||
/* If no suitable area was found, return an error. */
|
||||
assert(largest);
|
||||
if (!largest || (largest->num_pages << EFI_PAGE_SHIFT) < (2 << 20))
|
||||
goto err;
|
||||
|
||||
dest_addr = largest->physical_start + (largest->num_pages <<
|
||||
EFI_PAGE_SHIFT);
|
||||
|
||||
return (ulong)dest_addr;
|
||||
err:
|
||||
panic("No available memory found for relocation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
struct efi_mem_desc *desc, *end;
|
||||
struct efi_entry_memmap *map;
|
||||
int size, ret;
|
||||
|
||||
ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
|
||||
if (ret) {
|
||||
printf("Cannot find EFI memory map tables, ret=%d\n", ret);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
end = (struct efi_mem_desc *)((ulong)map + size);
|
||||
gd->ram_size = 0;
|
||||
desc = map->desc;
|
||||
for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
|
||||
if (desc->type < EFI_MMAP_IO)
|
||||
gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dram_init_banksize(void)
|
||||
{
|
||||
struct efi_mem_desc *desc, *end;
|
||||
struct efi_entry_memmap *map;
|
||||
int ret, size;
|
||||
int num_banks;
|
||||
|
||||
ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
|
||||
if (ret) {
|
||||
/* We should have stopped in dram_init(), something is wrong */
|
||||
debug("%s: Missing memory map\n", __func__);
|
||||
return;
|
||||
}
|
||||
end = (struct efi_mem_desc *)((ulong)map + size);
|
||||
desc = map->desc;
|
||||
for (num_banks = 0;
|
||||
desc < end && num_banks < CONFIG_NR_DRAM_BANKS;
|
||||
desc = efi_get_next_mem_desc(map, desc)) {
|
||||
/*
|
||||
* We only use conventional memory below 4GB, and ignore
|
||||
* anything less than 1MB.
|
||||
*/
|
||||
if (desc->type != EFI_CONVENTIONAL_MEMORY ||
|
||||
desc->physical_start >= 1ULL << 32 ||
|
||||
(desc->num_pages << EFI_PAGE_SHIFT) < 1 << 20)
|
||||
continue;
|
||||
gd->bd->bi_dram[num_banks].start = desc->physical_start;
|
||||
gd->bd->bi_dram[num_banks].size = desc->num_pages <<
|
||||
EFI_PAGE_SHIFT;
|
||||
num_banks++;
|
||||
}
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
return default_print_cpuinfo();
|
||||
}
|
||||
|
||||
/* Find any available tables and copy them to a safe place */
|
||||
int reserve_arch(void)
|
||||
{
|
||||
struct efi_info_hdr *hdr;
|
||||
|
||||
debug("table=%lx\n", gd->arch.table);
|
||||
if (!gd->arch.table)
|
||||
return 0;
|
||||
|
||||
hdr = (struct efi_info_hdr *)gd->arch.table;
|
||||
|
||||
gd->start_addr_sp -= hdr->total_size;
|
||||
memcpy((void *)gd->start_addr_sp, hdr, hdr->total_size);
|
||||
debug("Stashing EFI table at %lx to %lx, size %x\n",
|
||||
gd->arch.table, gd->start_addr_sp, hdr->total_size);
|
||||
gd->arch.table = gd->start_addr_sp;
|
||||
|
||||
return 0;
|
||||
}
|
72
arch/x86/lib/efi/reloc_ia32.c
Normal file
72
arch/x86/lib/efi/reloc_ia32.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* reloc_ia32.c - position independent x86 ELF shared object relocator
|
||||
* Copyright (C) 1999 Hewlett-Packard Co.
|
||||
* Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <efi.h>
|
||||
#include <elf.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
|
||||
struct efi_system_table *systab)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf32_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_REL:
|
||||
rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr +
|
||||
ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELSZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELA:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF32_R_TYPE(rel->r_info)) {
|
||||
case R_386_NONE:
|
||||
break;
|
||||
|
||||
case R_386_RELATIVE:
|
||||
addr = (unsigned long *)(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf32_Rel *)((char *)rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
66
arch/x86/lib/efi/reloc_x86_64.c
Normal file
66
arch/x86/lib/efi/reloc_x86_64.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* reloc_x86_64.c - position independent x86_64 ELF shared object relocator
|
||||
* Copyright (C) 1999 Hewlett-Packard Co.
|
||||
* Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
* Copyright (C) 2005 Intel Co.
|
||||
* Contributed by Fenghua Yu <fenghua.yu@intel.com>.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <efi.h>
|
||||
#include <elf.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
|
||||
struct efi_system_table *systab)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf64_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_RELA:
|
||||
rel = (Elf64_Rel *)
|
||||
((unsigned long)dyn[i].d_un.d_ptr + ldbase);
|
||||
break;
|
||||
case DT_RELASZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_RELAENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF64_R_TYPE(rel->r_info)) {
|
||||
case R_X86_64_NONE:
|
||||
break;
|
||||
case R_X86_64_RELATIVE:
|
||||
addr = (unsigned long *)(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf64_Rel *)((char *)rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -11,6 +11,8 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/fsp/fsp_support.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
post_code(POST_CPU_INFO);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <dm.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int lpc_uclass_post_bind(struct udevice *bus)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <dm.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int pch_uclass_post_bind(struct udevice *bus)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <inttypes.h>
|
||||
#include <libfdt.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <asm/relocate.h>
|
||||
#include <asm/sections.h>
|
||||
|
@ -30,32 +28,20 @@ int copy_uboot_to_ram(void)
|
|||
{
|
||||
size_t len = (size_t)&__data_end - (size_t)&__text_start;
|
||||
|
||||
if (gd->flags & GD_FLG_SKIP_RELOC)
|
||||
return 0;
|
||||
memcpy((void *)gd->relocaddr, (void *)&__text_start, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_fdt_to_ram(void)
|
||||
{
|
||||
if (gd->new_fdt) {
|
||||
ulong fdt_size;
|
||||
|
||||
fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
|
||||
|
||||
memcpy(gd->new_fdt, gd->fdt_blob, fdt_size);
|
||||
debug("Relocated fdt from %p to %p, size %lx\n",
|
||||
gd->fdt_blob, gd->new_fdt, fdt_size);
|
||||
gd->fdt_blob = gd->new_fdt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clear_bss(void)
|
||||
{
|
||||
ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
|
||||
size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
|
||||
|
||||
if (gd->flags & GD_FLG_SKIP_RELOC)
|
||||
return 0;
|
||||
memset((void *)dst_addr, 0x00, len);
|
||||
|
||||
return 0;
|
||||
|
@ -72,36 +58,43 @@ int do_elf_reloc_fixups(void)
|
|||
|
||||
Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
|
||||
Elf32_Addr *offset_ptr_ram;
|
||||
unsigned int text_base = 0;
|
||||
|
||||
/* The size of the region of u-boot that runs out of RAM. */
|
||||
uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
|
||||
|
||||
if (gd->flags & GD_FLG_SKIP_RELOC)
|
||||
return 0;
|
||||
if (re_src == re_end)
|
||||
panic("No relocation data");
|
||||
|
||||
#ifdef CONFIG_SYS_TEXT_BASE
|
||||
text_base = CONFIG_SYS_TEXT_BASE;
|
||||
#else
|
||||
panic("No CONFIG_SYS_TEXT_BASE");
|
||||
#endif
|
||||
do {
|
||||
/* Get the location from the relocation entry */
|
||||
offset_ptr_rom = (Elf32_Addr *)re_src->r_offset;
|
||||
|
||||
/* Check that the location of the relocation is in .text */
|
||||
if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE &&
|
||||
offset_ptr_rom > last_offset) {
|
||||
if (offset_ptr_rom >= (Elf32_Addr *)text_base &&
|
||||
offset_ptr_rom > last_offset) {
|
||||
|
||||
/* Switch to the in-RAM version */
|
||||
offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom +
|
||||
gd->reloc_off);
|
||||
|
||||
/* Check that the target points into .text */
|
||||
if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE &&
|
||||
*offset_ptr_ram <=
|
||||
(CONFIG_SYS_TEXT_BASE + size)) {
|
||||
if (*offset_ptr_ram >= text_base &&
|
||||
*offset_ptr_ram <= text_base + size) {
|
||||
*offset_ptr_ram += gd->reloc_off;
|
||||
} else {
|
||||
debug(" %p: rom reloc %x, ram %p, value %x,"
|
||||
" limit %" PRIXPTR "\n", re_src,
|
||||
re_src->r_offset, offset_ptr_ram,
|
||||
*offset_ptr_ram,
|
||||
CONFIG_SYS_TEXT_BASE + size);
|
||||
text_base + size);
|
||||
}
|
||||
} else {
|
||||
debug(" %p: rom reloc %x, last %p\n", re_src,
|
||||
|
|
|
@ -355,7 +355,15 @@ void __udelay(unsigned long usec)
|
|||
stop = now + usec * get_tbclk_mhz();
|
||||
|
||||
while ((int64_t)(stop - get_ticks()) > 0)
|
||||
#if defined(CONFIG_QEMU) && defined(CONFIG_SMP)
|
||||
/*
|
||||
* Add a 'pause' instruction on qemu target,
|
||||
* to give other VCPUs a chance to run.
|
||||
*/
|
||||
asm volatile("pause");
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
|
|
19
board/efi/Kconfig
Normal file
19
board/efi/Kconfig
Normal file
|
@ -0,0 +1,19 @@
|
|||
if VENDOR_EFI
|
||||
|
||||
choice
|
||||
prompt "Mainboard model"
|
||||
optional
|
||||
|
||||
config TARGET_EFI
|
||||
bool "efi"
|
||||
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.
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/efi/efi-x86/Kconfig"
|
||||
|
||||
endif
|
15
board/efi/efi-x86/Kconfig
Normal file
15
board/efi/efi-x86/Kconfig
Normal file
|
@ -0,0 +1,15 @@
|
|||
if TARGET_EFI
|
||||
|
||||
config SYS_BOARD
|
||||
default "efi-x86"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "efi"
|
||||
|
||||
config SYS_SOC
|
||||
default "efi"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "efi-x86"
|
||||
|
||||
endif
|
6
board/efi/efi-x86/MAINTAINERS
Normal file
6
board/efi/efi-x86/MAINTAINERS
Normal file
|
@ -0,0 +1,6 @@
|
|||
EFI-X86 BOARD
|
||||
M: Simon Glass <sjg@chromium.org>
|
||||
S: Maintained
|
||||
F: board/efi/efi-x86/
|
||||
F: include/configs/efi-x86.h
|
||||
F: configs/efi-x86_defconfig
|
7
board/efi/efi-x86/Makefile
Normal file
7
board/efi/efi-x86/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Copyright (c) 2015 Google, Inc
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += efi.o
|
18
board/efi/efi-x86/efi.c
Normal file
18
board/efi/efi-x86/efi.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
int arch_early_init_r(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
|
||||
{
|
||||
return;
|
||||
}
|
|
@ -13,11 +13,12 @@ config SYS_CONFIG_NAME
|
|||
default "qemu-x86"
|
||||
|
||||
config SYS_TEXT_BASE
|
||||
default 0xfff00000
|
||||
default 0xfff00000 if !EFI_STUB
|
||||
default 0x01110000 if EFI_STUB
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select X86_RESET_VECTOR
|
||||
select X86_RESET_VECTOR if !EFI_STUB
|
||||
select QEMU
|
||||
select BOARD_ROMSIZE_KB_1024
|
||||
|
||||
|
|
|
@ -10,6 +10,14 @@ choice
|
|||
prompt "Mainboard model"
|
||||
optional
|
||||
|
||||
config TARGET_BAYLEYBAY
|
||||
bool "Bayley Bay"
|
||||
help
|
||||
This is the Intel Bayley Bay Customer Reference Board. It contains an
|
||||
Intel quad-core Atom Processor E3800 with dual-channel DDR3L SODIMM
|
||||
4GB memory, HDMI/DP/VGA display, HD audio, SATA, USB2, USB3, SD, eMMC,
|
||||
PCIe and some other sensor interfaces.
|
||||
|
||||
config TARGET_CROWNBAY
|
||||
bool "Crown Bay"
|
||||
help
|
||||
|
@ -45,6 +53,7 @@ config TARGET_MINNOWMAX
|
|||
|
||||
endchoice
|
||||
|
||||
source "board/intel/bayleybay/Kconfig"
|
||||
source "board/intel/crownbay/Kconfig"
|
||||
source "board/intel/galileo/Kconfig"
|
||||
source "board/intel/minnowmax/Kconfig"
|
||||
|
|
27
board/intel/bayleybay/Kconfig
Normal file
27
board/intel/bayleybay/Kconfig
Normal file
|
@ -0,0 +1,27 @@
|
|||
if TARGET_BAYLEYBAY
|
||||
|
||||
config SYS_BOARD
|
||||
default "bayleybay"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "intel"
|
||||
|
||||
config SYS_SOC
|
||||
default "baytrail"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "bayleybay"
|
||||
|
||||
config SYS_TEXT_BASE
|
||||
default 0xfff00000
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select X86_RESET_VECTOR
|
||||
select INTEL_BAYTRAIL
|
||||
select BOARD_ROMSIZE_KB_8192
|
||||
|
||||
config PCIE_ECAM_BASE
|
||||
default 0xe0000000
|
||||
|
||||
endif
|
6
board/intel/bayleybay/MAINTAINERS
Normal file
6
board/intel/bayleybay/MAINTAINERS
Normal file
|
@ -0,0 +1,6 @@
|
|||
Intel Bayley Bay
|
||||
M: Bin Meng <bmeng.cn@gmail.com>
|
||||
S: Maintained
|
||||
F: board/intel/bayleybay
|
||||
F: include/configs/bayleybay.h
|
||||
F: configs/bayleybay_defconfig
|
7
board/intel/bayleybay/Makefile
Normal file
7
board/intel/bayleybay/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += bayleybay.o start.o
|
19
board/intel/bayleybay/bayleybay.c
Normal file
19
board/intel/bayleybay/bayleybay.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <netdev.h>
|
||||
|
||||
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);
|
||||
}
|
9
board/intel/bayleybay/start.S
Normal file
9
board/intel/bayleybay/start.S
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
.globl early_board_init
|
||||
early_board_init:
|
||||
jmp early_board_init_ret
|
|
@ -13,11 +13,12 @@ config SYS_CONFIG_NAME
|
|||
default "minnowmax"
|
||||
|
||||
config SYS_TEXT_BASE
|
||||
default 0xfff00000
|
||||
default 0xfff00000 if !EFI_STUB
|
||||
default 0x01110000 if EFI_STUB
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select X86_RESET_VECTOR
|
||||
select X86_RESET_VECTOR if !EFI_STUB
|
||||
select INTEL_BAYTRAIL
|
||||
select BOARD_ROMSIZE_KB_8192
|
||||
|
||||
|
|
|
@ -6,12 +6,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/ibmpc.h>
|
||||
#include <asm/pnp_def.h>
|
||||
#include <netdev.h>
|
||||
#include <smsc_lpc47m.h>
|
||||
|
||||
#define SERIAL_DEV PNP_DEV(0x2e, 4)
|
||||
|
||||
int arch_early_init_r(void)
|
||||
{
|
||||
|
@ -21,13 +16,6 @@ int arch_early_init_r(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
lpc47m_enable_serial(SERIAL_DEV, UART0_BASE, UART0_IRQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -90,6 +90,7 @@ obj-$(CONFIG_CMD_DTT) += cmd_dtt.o
|
|||
obj-$(CONFIG_CMD_ECHO) += cmd_echo.o
|
||||
obj-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
|
||||
obj-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
|
||||
obj-$(CONFIG_EFI_STUB) += cmd_efi.o
|
||||
obj-$(CONFIG_CMD_ELF) += cmd_elf.o
|
||||
obj-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
|
||||
obj-$(CONFIG_CMD_EXT4) += cmd_ext4.o
|
||||
|
|
|
@ -144,7 +144,7 @@ static int init_baud_rate(void)
|
|||
|
||||
static int display_text_info(void)
|
||||
{
|
||||
#ifndef CONFIG_SANDBOX
|
||||
#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_EFI_APP)
|
||||
ulong bss_start, bss_end, text_base;
|
||||
|
||||
bss_start = (ulong)&__bss_start;
|
||||
|
@ -267,7 +267,7 @@ static int setup_mon_len(void)
|
|||
{
|
||||
#if defined(__ARM__) || defined(__MICROBLAZE__)
|
||||
gd->mon_len = (ulong)&__bss_end - (ulong)_start;
|
||||
#elif defined(CONFIG_SANDBOX)
|
||||
#elif defined(CONFIG_SANDBOX) || defined(CONFIG_EFI_APP)
|
||||
gd->mon_len = (ulong)&_end - (ulong)_init;
|
||||
#elif defined(CONFIG_BLACKFIN) || defined(CONFIG_NIOS2)
|
||||
gd->mon_len = CONFIG_SYS_MONITOR_LEN;
|
||||
|
@ -654,6 +654,8 @@ static int setup_dram_config(void)
|
|||
|
||||
static int reloc_fdt(void)
|
||||
{
|
||||
if (gd->flags & GD_FLG_SKIP_RELOC)
|
||||
return 0;
|
||||
if (gd->new_fdt) {
|
||||
memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
|
||||
gd->fdt_blob = gd->new_fdt;
|
||||
|
@ -664,6 +666,11 @@ static int reloc_fdt(void)
|
|||
|
||||
static int setup_reloc(void)
|
||||
{
|
||||
if (gd->flags & GD_FLG_SKIP_RELOC) {
|
||||
debug("Skipping relocation due to flag\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_TEXT_BASE
|
||||
gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
|
||||
#ifdef CONFIG_M68K
|
||||
|
@ -689,6 +696,8 @@ static int setup_reloc(void)
|
|||
|
||||
static int jump_to_copy(void)
|
||||
{
|
||||
if (gd->flags & GD_FLG_SKIP_RELOC)
|
||||
return 0;
|
||||
/*
|
||||
* x86 is special, but in a nice way. It uses a trampoline which
|
||||
* enables the dcache if possible.
|
||||
|
@ -968,7 +977,8 @@ void board_init_f(ulong boot_flags)
|
|||
if (initcall_run_list(init_sequence_f))
|
||||
hang();
|
||||
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
|
||||
!defined(CONFIG_EFI_APP)
|
||||
/* NOTREACHED - jump_to_copy() does not return */
|
||||
hang();
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
int __weak checkboard(void)
|
||||
{
|
||||
printf("Board: Unknown\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
257
common/cmd_efi.c
Normal file
257
common/cmd_efi.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <efi.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
|
||||
static const char *const type_name[] = {
|
||||
"reserved",
|
||||
"loader_code",
|
||||
"loader_data",
|
||||
"bs_code",
|
||||
"bs_data",
|
||||
"rt_code",
|
||||
"rt_data",
|
||||
"conv",
|
||||
"unusable",
|
||||
"acpi_reclaim",
|
||||
"acpi_nvs",
|
||||
"io",
|
||||
"io_port",
|
||||
"pal_code",
|
||||
};
|
||||
|
||||
static struct attr_info {
|
||||
int shift;
|
||||
const char *name;
|
||||
} mem_attr[] = {
|
||||
{ EFI_MEMORY_UC_SHIFT, "uncached" },
|
||||
{ EFI_MEMORY_WC_SHIFT, "write-coalescing" },
|
||||
{ EFI_MEMORY_WT_SHIFT, "write-through" },
|
||||
{ EFI_MEMORY_WB_SHIFT, "write-back" },
|
||||
{ EFI_MEMORY_UCE_SHIFT, "uncached & exported" },
|
||||
{ EFI_MEMORY_WP_SHIFT, "write-protect" },
|
||||
{ EFI_MEMORY_RP_SHIFT, "read-protect" },
|
||||
{ EFI_MEMORY_XP_SHIFT, "execute-protect" },
|
||||
{ EFI_MEMORY_RUNTIME_SHIFT, "needs runtime mapping" }
|
||||
};
|
||||
|
||||
/* Maximum different attribute values we can track */
|
||||
#define ATTR_SEEN_MAX 30
|
||||
|
||||
static inline bool is_boot_services(int type)
|
||||
{
|
||||
return type == EFI_LOADER_CODE || type == EFI_LOADER_DATA ||
|
||||
type == EFI_BOOT_SERVICES_CODE ||
|
||||
type == EFI_BOOT_SERVICES_DATA;
|
||||
}
|
||||
|
||||
static int h_cmp_entry(const void *v1, const void *v2)
|
||||
{
|
||||
const struct efi_mem_desc *desc1 = v1;
|
||||
const struct efi_mem_desc *desc2 = v2;
|
||||
int64_t diff = desc1->physical_start - desc2->physical_start;
|
||||
|
||||
/*
|
||||
* Manually calculate the difference to avoid sign loss in the 64-bit
|
||||
* to 32-bit conversion
|
||||
*/
|
||||
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
void *efi_build_mem_table(struct efi_entry_memmap *map, int size, bool skip_bs)
|
||||
{
|
||||
struct efi_mem_desc *desc, *end, *base, *dest, *prev;
|
||||
int count;
|
||||
u64 addr;
|
||||
|
||||
base = malloc(size + sizeof(*desc));
|
||||
if (!base) {
|
||||
debug("%s: Cannot allocate %#x bytes\n", __func__, size);
|
||||
return NULL;
|
||||
}
|
||||
end = (struct efi_mem_desc *)((ulong)map + size);
|
||||
count = ((ulong)end - (ulong)map->desc) / map->desc_size;
|
||||
memcpy(base, map->desc, (ulong)end - (ulong)map->desc);
|
||||
qsort(base, count, map->desc_size, h_cmp_entry);
|
||||
prev = NULL;
|
||||
addr = 0;
|
||||
dest = base;
|
||||
end = base + count;
|
||||
for (desc = base; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
|
||||
bool merge = true;
|
||||
int type = desc->type;
|
||||
|
||||
if (skip_bs && is_boot_services(desc->type))
|
||||
type = EFI_CONVENTIONAL_MEMORY;
|
||||
|
||||
memcpy(dest, desc, map->desc_size);
|
||||
dest->type = type;
|
||||
if (!skip_bs || !prev)
|
||||
merge = false;
|
||||
else if (desc->physical_start != addr)
|
||||
merge = false;
|
||||
else if (type != EFI_CONVENTIONAL_MEMORY)
|
||||
merge = false;
|
||||
else if (prev->type != EFI_CONVENTIONAL_MEMORY)
|
||||
merge = false;
|
||||
|
||||
if (merge) {
|
||||
prev->num_pages += desc->num_pages;
|
||||
} else {
|
||||
prev = dest;
|
||||
dest = efi_get_next_mem_desc(map, dest);
|
||||
}
|
||||
addr = desc->physical_start + (desc->num_pages <<
|
||||
EFI_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/* Mark the end */
|
||||
dest->type = EFI_TABLE_END;
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
static void efi_print_mem_table(struct efi_entry_memmap *map,
|
||||
struct efi_mem_desc *desc, bool skip_bs)
|
||||
{
|
||||
u64 attr_seen[ATTR_SEEN_MAX];
|
||||
int attr_seen_count;
|
||||
int upto, i;
|
||||
u64 addr;
|
||||
|
||||
printf(" # %-14s %10s %10s %10s %s\n", "Type", "Physical",
|
||||
"Virtual", "Size", "Attributes");
|
||||
|
||||
/* Keep track of all the different attributes we have seen */
|
||||
attr_seen_count = 0;
|
||||
addr = 0;
|
||||
for (upto = 0; desc->type != EFI_TABLE_END;
|
||||
upto++, desc = efi_get_next_mem_desc(map, desc)) {
|
||||
const char *name;
|
||||
u64 size;
|
||||
|
||||
if (skip_bs && is_boot_services(desc->type))
|
||||
continue;
|
||||
if (desc->physical_start != addr) {
|
||||
printf(" %-14s %010llx %10s %010llx\n", "<gap>",
|
||||
addr, "", desc->physical_start - addr);
|
||||
}
|
||||
size = desc->num_pages << EFI_PAGE_SHIFT;
|
||||
|
||||
name = desc->type < ARRAY_SIZE(type_name) ?
|
||||
type_name[desc->type] : "<invalid>";
|
||||
printf("%2d %x:%-12s %010llx %010llx %010llx ", upto,
|
||||
desc->type, name, desc->physical_start,
|
||||
desc->virtual_start, size);
|
||||
if (desc->attribute & EFI_MEMORY_RUNTIME)
|
||||
putc('r');
|
||||
printf("%llx", desc->attribute & ~EFI_MEMORY_RUNTIME);
|
||||
putc('\n');
|
||||
|
||||
for (i = 0; i < attr_seen_count; i++) {
|
||||
if (attr_seen[i] == desc->attribute)
|
||||
break;
|
||||
}
|
||||
if (i == attr_seen_count && i < ATTR_SEEN_MAX)
|
||||
attr_seen[attr_seen_count++] = desc->attribute;
|
||||
addr = desc->physical_start + size;
|
||||
}
|
||||
|
||||
printf("\nAttributes key:\n");
|
||||
for (i = 0; i < attr_seen_count; i++) {
|
||||
u64 attr = attr_seen[i];
|
||||
bool first;
|
||||
int j;
|
||||
|
||||
printf("%c%llx: ", attr & EFI_MEMORY_RUNTIME ? 'r' : ' ',
|
||||
attr & ~EFI_MEMORY_RUNTIME);
|
||||
for (j = 0, first = true; j < ARRAY_SIZE(mem_attr); j++) {
|
||||
if (attr & (1ULL << mem_attr[j].shift)) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
printf(", ");
|
||||
printf("%s", mem_attr[j].name);
|
||||
}
|
||||
}
|
||||
putc('\n');
|
||||
}
|
||||
if (skip_bs)
|
||||
printf("*Some areas are merged (use 'all' to see)\n");
|
||||
}
|
||||
|
||||
static int do_efi_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
struct efi_mem_desc *desc;
|
||||
struct efi_entry_memmap *map;
|
||||
int size, ret;
|
||||
bool skip_bs;
|
||||
|
||||
skip_bs = !argc || *argv[0] != 'a';
|
||||
ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
|
||||
switch (ret) {
|
||||
case -ENOENT:
|
||||
printf("No EFI table available\n");
|
||||
goto done;
|
||||
case -EPROTONOSUPPORT:
|
||||
printf("Incorrect EFI table version\n");
|
||||
goto done;
|
||||
}
|
||||
printf("EFI table at %lx, memory map %p, size %x, version %x, descr. size %#x\n",
|
||||
gd->arch.table, map, size, map->version, map->desc_size);
|
||||
if (map->version != EFI_MEM_DESC_VERSION) {
|
||||
printf("Incorrect memory map version\n");
|
||||
ret = -EPROTONOSUPPORT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
desc = efi_build_mem_table(map, size, skip_bs);
|
||||
if (!desc) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
efi_print_mem_table(map, desc, skip_bs);
|
||||
free(desc);
|
||||
done:
|
||||
if (ret)
|
||||
printf("Error: %d\n", ret);
|
||||
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
}
|
||||
|
||||
static cmd_tbl_t efi_commands[] = {
|
||||
U_BOOT_CMD_MKENT(mem, 1, 1, do_efi_mem, "", ""),
|
||||
};
|
||||
|
||||
static int do_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
cmd_tbl_t *efi_cmd;
|
||||
int ret;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
efi_cmd = find_cmd_tbl(argv[1], efi_commands, ARRAY_SIZE(efi_commands));
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if (!efi_cmd || argc > efi_cmd->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
ret = efi_cmd->cmd(efi_cmd, flag, argc, argv);
|
||||
|
||||
return cmd_process_error(efi_cmd, ret);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
efi, 3, 1, do_efi,
|
||||
"EFI access",
|
||||
"mem [all] Dump memory information [include boot services]"
|
||||
);
|
|
@ -492,7 +492,7 @@ static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
|
||||
result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
|
||||
if (result)
|
||||
debug("Command failed, result=%d", result);
|
||||
debug("Command failed, result=%d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,6 @@ endif
|
|||
|
||||
RELFLAGS := $(PLATFORM_RELFLAGS)
|
||||
|
||||
OBJCOPYFLAGS += --gap-fill=0xff
|
||||
|
||||
PLATFORM_CPPFLAGS += $(RELFLAGS)
|
||||
PLATFORM_CPPFLAGS += -pipe
|
||||
|
||||
|
|
27
configs/bayleybay_defconfig
Normal file
27
configs/bayleybay_defconfig
Normal file
|
@ -0,0 +1,27 @@
|
|||
CONFIG_X86=y
|
||||
CONFIG_VENDOR_INTEL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="bayleybay"
|
||||
CONFIG_TARGET_BAYLEYBAY=y
|
||||
CONFIG_HAVE_INTEL_ME=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_HAVE_VGA_BIOS=y
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_CMD_CPU=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_BOOTSTAGE=y
|
||||
CONFIG_BOOTSTAGE_REPORT=y
|
||||
CONFIG_CMD_BOOTSTAGE=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_CPU=y
|
||||
CONFIG_DM_PCI=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_VIDEO_VESA=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
|
||||
CONFIG_DM_RTC=y
|
||||
CONFIG_USE_PRIVATE_LIBGCC=y
|
||||
CONFIG_SYS_VSNPRINTF=y
|
|
@ -14,6 +14,9 @@ CONFIG_CMD_BOOTSTAGE=y
|
|||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DM_PCI=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_CMD_CROS_EC=y
|
||||
CONFIG_CROS_EC=y
|
||||
CONFIG_CROS_EC_LPC=y
|
||||
CONFIG_VIDEO_VESA=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
|
||||
|
|
|
@ -14,6 +14,9 @@ CONFIG_CMD_BOOTSTAGE=y
|
|||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DM_PCI=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_CMD_CROS_EC=y
|
||||
CONFIG_CROS_EC=y
|
||||
CONFIG_CROS_EC_LPC=y
|
||||
CONFIG_VIDEO_VESA=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
|
||||
|
|
16
configs/efi-x86_defconfig
Normal file
16
configs/efi-x86_defconfig
Normal file
|
@ -0,0 +1,16 @@
|
|||
CONFIG_X86=y
|
||||
CONFIG_VENDOR_EFI=y
|
||||
CONFIG_TARGET_EFI=y
|
||||
CONFIG_TSC_CALIBRATION_BYPASS=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_OF_EMBED=y
|
||||
CONFIG_DM_PCI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="efi"
|
||||
CONFIG_EFI=y
|
||||
CONFIG_EFI_APP=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_EFI_CONSOLE=y
|
||||
CONFIG_DEBUG_UART_BASE=0
|
||||
CONFIG_DEBUG_UART_CLOCK=0
|
||||
# CONFIG_CMD_NET is not set
|
||||
# CONFIG_CMD_BOOTM is not set
|
|
@ -1,5 +1,7 @@
|
|||
CONFIG_X86=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
|
||||
CONFIG_SMP=y
|
||||
CONFIG_MAX_CPUS=2
|
||||
CONFIG_GENERATE_PIRQ_TABLE=y
|
||||
CONFIG_GENERATE_MP_TABLE=y
|
||||
CONFIG_CMD_CPU=y
|
||||
|
|
237
doc/README.efi
Normal file
237
doc/README.efi
Normal file
|
@ -0,0 +1,237 @@
|
|||
#
|
||||
# Copyright (C) 2015 Google, Inc
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
U-Boot on EFI
|
||||
=============
|
||||
This document provides information about U-Boot running on top of EFI, either
|
||||
as an application or just as a means of getting U-Boot onto a new platform.
|
||||
|
||||
|
||||
In God's Name, Why?
|
||||
-------------------
|
||||
This is useful in several situations:
|
||||
|
||||
- You have EFI running on a board but U-Boot does not natively support it
|
||||
fully yet. You can boot into U-Boot from EFI and use that until U-Boot is
|
||||
fully ported
|
||||
|
||||
- You need to use an EFI implementation (e.g. UEFI) because your vendor
|
||||
requires it in order to provide support
|
||||
|
||||
- You plan to use coreboot to boot into U-Boot but coreboot support does
|
||||
not currently exist for your platform. In the meantime you can use U-Boot
|
||||
on EFI and then move to U-Boot on coreboot when ready
|
||||
|
||||
- You use EFI but want to experiment with a simpler alternative like U-Boot
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
Only x86 is supported at present. If you are using EFI on another architecture
|
||||
you may want to reconsider. However, much of the code is generic so could be
|
||||
ported.
|
||||
|
||||
U-Boot supports running as an EFI application for 32-bit EFI only. This is
|
||||
not very useful since only a serial port is provided. You can look around at
|
||||
memory and type 'help' but that is about it.
|
||||
|
||||
More usefully, U-Boot supports building itself as a payload for either 32-bit
|
||||
or 64-bit EFI. U-Boot is packaged up and loaded in its entirety by EFI. Once
|
||||
started, U-Boot changes to 32-bit mode (currently) and takes over the
|
||||
machine. You can use devices, boot a kernel, etc.
|
||||
|
||||
|
||||
Build Instructions
|
||||
------------------
|
||||
First choose a board that has EFI support and obtain an EFI implementation
|
||||
for that board. It will be either 32-bit or 64-bit.
|
||||
|
||||
To build U-Boot as an EFI application (32-bit EFI required), enable
|
||||
CONFIG_EFI and CONFIG_EFI_APP. The efi-x86 config is set up for this.
|
||||
|
||||
To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust
|
||||
an existing config to enable CONFIG_EFI, CONFIG_EFI_STUB and either
|
||||
CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT.
|
||||
|
||||
Then build U-Boot as normal, e.g.
|
||||
|
||||
make qemu-x86_defconfig
|
||||
make menuconfig (or make xconfig if you prefer)
|
||||
# change the settings as above
|
||||
make
|
||||
|
||||
You will end up with one of these files:
|
||||
|
||||
u-boot-app.efi - U-Boot EFI application
|
||||
u-boot-payload.efi - U-Boot EFI payload application
|
||||
|
||||
|
||||
Trying it out
|
||||
-------------
|
||||
Qemu is an emulator and it can emulate an x86 machine. You can run the
|
||||
payload with something like this:
|
||||
|
||||
mkdir /tmp/efi
|
||||
cp /path/to/u-boot*.efi /tmp/efi
|
||||
qemu-system-x86_64 -bios bios.bin -hda fat:/tmp/efi/
|
||||
|
||||
Add -nographic if you want to use the terminal for output. Once it starts
|
||||
type 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot-app.efi' to
|
||||
run the application. 'bios.bin' is the EFI 'BIOS'.
|
||||
|
||||
To try it on real hardware, put u-boot-app.efi on a suitable boot medium,
|
||||
such as a USB stick. Then you can type something like this to start it:
|
||||
|
||||
fs0:u-boot-payload.efi
|
||||
|
||||
(or fs0:u-boot-app.efi for the application)
|
||||
|
||||
This will start the payload, copy U-Boot into RAM and start U-Boot. Note
|
||||
that EFI does not support booting a 64-bit application from a 32-bit
|
||||
EFI (or vice versa). Also it will often fail to print an error message if
|
||||
you get this wrong.
|
||||
|
||||
|
||||
Inner workings
|
||||
==============
|
||||
Here follow a few implementation notes for those who want to fiddle with
|
||||
this and perhaps contribute patches.
|
||||
|
||||
The application and payload approaches sound similar but are in fact
|
||||
implemented completely differently.
|
||||
|
||||
EFI Application
|
||||
---------------
|
||||
For the application the whole of U-Boot is built as a shared library. The
|
||||
efi_main() function is in lib/efi/efi_app.c. It sets up some basic EFI
|
||||
functions with efi_init(), sets up U-Boot global_data, allocates memory for
|
||||
U-Boot's malloc(), etc. and enters the normal init sequence (board_init_f()
|
||||
and board_init_r()).
|
||||
|
||||
Since U-Boot limits its memory access to the allocated regions very little
|
||||
special code is needed. The CONFIG_EFI_APP option controls a few things
|
||||
that need to change so 'git grep CONFIG_EFI_APP' may be instructive.
|
||||
The CONFIG_EFI option controls more general EFI adjustments.
|
||||
|
||||
The only available driver is the serial driver. This calls back into EFI
|
||||
'boot services' to send and receive characters. Although it is implemented
|
||||
as a serial driver the console device is not necessarilly serial. If you
|
||||
boot EFI with video output then the 'serial' device will operate on your
|
||||
target devices's display instead and the device's USB keyboard will also
|
||||
work if connected. If you have both serial and video output, then both
|
||||
consoles will be active. Even though U-Boot does the same thing normally,
|
||||
These are features of EFI, not U-Boot.
|
||||
|
||||
Very little code is involved in implementing the EFI application feature.
|
||||
U-Boot is highly portable. Most of the difficulty is in modifying the
|
||||
Makefile settings to pass the right build flags. In particular there is very
|
||||
little x86-specific code involved - you can find most of it in
|
||||
arch/x86/cpu. Porting to ARM (which can also use EFI if you are brave
|
||||
enough) should be straightforward.
|
||||
|
||||
Use the 'reset' command to get back to EFI.
|
||||
|
||||
EFI Payload
|
||||
-----------
|
||||
The payload approach is a different kettle of fish. It works by building
|
||||
U-Boot exactly as normal for your target board, then adding the entire
|
||||
image (including device tree) into a small EFI stub application responsible
|
||||
for booting it. The stub application is built as a normal EFI application
|
||||
except that it has a lot of data attached to it.
|
||||
|
||||
The stub application is implemented in lib/efi/efi_stub.c. The efi_main()
|
||||
function is called by EFI. It is responsible for copying U-Boot from its
|
||||
original location into memory, disabling EFI boot services and starting
|
||||
U-Boot. U-Boot then starts as normal, relocates, starts all drivers, etc.
|
||||
|
||||
The stub application is architecture-dependent. At present it has some
|
||||
x86-specific code and a comment at the top of efi_stub.c describes this.
|
||||
|
||||
While the stub application does allocate some memory from EFI this is not
|
||||
used by U-Boot (the payload). In fact when U-Boot starts it has all of the
|
||||
memory available to it and can operate as it pleases (but see the next
|
||||
section).
|
||||
|
||||
Tables
|
||||
------
|
||||
The payload can pass information to U-Boot in the form of EFI tables. At
|
||||
present this feature is used to pass the EFI memory map, an inordinately
|
||||
large list of memory regions. You can use the 'efi mem all' command to
|
||||
display this list. U-Boot uses the list to work out where to relocate
|
||||
itself.
|
||||
|
||||
Although U-Boot can use any memory it likes, EFI marks some memory as used
|
||||
by 'run-time services', code that hangs around while U-Boot is running and
|
||||
is even present when Linux is running. This is common on x86 and provides
|
||||
a way for Linux to call back into the firmware to control things like CPU
|
||||
fan speed. U-Boot uses only 'conventional' memory, in EFI terminology. It
|
||||
will relocate itself to the top of the largest block of memory it can find
|
||||
below 4GB.
|
||||
|
||||
Interrupts
|
||||
----------
|
||||
U-Boot drivers typically don't use interrupts. Since EFI enables interrupts
|
||||
it is possible that an interrupt will fire that U-Boot cannot handle. This
|
||||
seems to cause problems. For this reason the U-Boot payload runs with
|
||||
interrupts disabled at present.
|
||||
|
||||
32/64-bit
|
||||
---------
|
||||
While the EFI application can in principle be built as either 32- or 64-bit,
|
||||
only 32-bit is currently supported. This means that the application can only
|
||||
be used with 32-bit EFI.
|
||||
|
||||
The payload stub can be build as either 32- or 64-bits. Only a small amount
|
||||
of code is built this way (see the extra- line in lib/efi/Makefile).
|
||||
Everything else is built as a normal U-Boot, so is always 32-bit on x86 at
|
||||
present.
|
||||
|
||||
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
|
||||
|
||||
- Figure out how to solve the interrupt problem
|
||||
|
||||
- Add more drivers to the application side (e.g. video, block devices, USB,
|
||||
environment access). This would mostly be an academic exercise as a strong
|
||||
use case is not readily apparent, but it might be fun.
|
||||
|
||||
- Avoid turning off boot services in the stub. Instead allow U-Boot to make
|
||||
use of boot services in case it wants to. It is unclear what it might want
|
||||
though.
|
||||
|
||||
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
|
||||
|
||||
board/efi/efi-x86/efi.c
|
||||
x86 board code for running as an EFI application
|
||||
|
||||
common/cmd_efi.c
|
||||
the 'efi' command
|
||||
|
||||
|
||||
--
|
||||
Ben Stoltz, Simon Glass
|
||||
Google, Inc
|
||||
July 2015
|
324
doc/README.x86
324
doc/README.x86
|
@ -281,6 +281,11 @@ QEMU emulates a graphic card which U-Boot supports. Removing '-nographic' will
|
|||
show QEMU's VGA console window. Note this will disable QEMU's serial output.
|
||||
If you want to check both consoles, use '-serial stdio'.
|
||||
|
||||
Multicore is also supported by QEMU via '-smp n' where n is the number of cores
|
||||
to instantiate. Currently the default U-Boot built for QEMU supports 2 cores.
|
||||
In order to support more cores, you need add additional cpu nodes in the device
|
||||
tree and change CONFIG_MAX_CPUS accordingly.
|
||||
|
||||
CPU Microcode
|
||||
-------------
|
||||
Modern CPUs usually require a special bit stream called microcode [8] to be
|
||||
|
@ -325,6 +330,281 @@ mtrr - List and set the Memory Type Range Registers (MTRR). These are used to
|
|||
mode to use. U-Boot sets up some reasonable values but you can
|
||||
adjust then with this command.
|
||||
|
||||
Booting Ubuntu
|
||||
--------------
|
||||
As an example of how to set up your boot flow with U-Boot, here are
|
||||
instructions for starting Ubuntu from U-Boot. These instructions have been
|
||||
tested on Minnowboard MAX with a SATA driver but are equally applicable on
|
||||
other platforms and other media. There are really only four steps and its a
|
||||
very simple script, but a more detailed explanation is provided here for
|
||||
completeness.
|
||||
|
||||
Note: It is possible to set up U-Boot to boot automatically using syslinux.
|
||||
It could also use the grub.cfg file (/efi/ubuntu/grub.cfg) to obtain the
|
||||
GUID. If you figure these out, please post patches to this README.
|
||||
|
||||
Firstly, you will need Ubunutu installed on an available disk. It should be
|
||||
possible to make U-Boot start a USB start-up disk but for now let's assume
|
||||
that you used another boot loader to install Ubuntu.
|
||||
|
||||
Use the U-Boot command line to find the UUID of the partition you want to
|
||||
boot. For example our disk is SCSI device 0:
|
||||
|
||||
=> part list scsi 0
|
||||
|
||||
Partition Map for SCSI device 0 -- Partition Type: EFI
|
||||
|
||||
Part Start LBA End LBA Name
|
||||
Attributes
|
||||
Type GUID
|
||||
Partition GUID
|
||||
1 0x00000800 0x001007ff ""
|
||||
attrs: 0x0000000000000000
|
||||
type: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
|
||||
guid: 9d02e8e4-4d59-408f-a9b0-fd497bc9291c
|
||||
2 0x00100800 0x037d8fff ""
|
||||
attrs: 0x0000000000000000
|
||||
type: 0fc63daf-8483-4772-8e79-3d69d8477de4
|
||||
guid: 965c59ee-1822-4326-90d2-b02446050059
|
||||
3 0x037d9000 0x03ba27ff ""
|
||||
attrs: 0x0000000000000000
|
||||
type: 0657fd6d-a4ab-43c4-84e5-0933c84b4f4f
|
||||
guid: 2c4282bd-1e82-4bcf-a5ff-51dedbf39f17
|
||||
=>
|
||||
|
||||
This shows that your SCSI disk has three partitions. The really long hex
|
||||
strings are called Globally Unique Identifiers (GUIDs). You can look up the
|
||||
'type' ones here [11]. On this disk the first partition is for EFI and is in
|
||||
VFAT format (DOS/Windows):
|
||||
|
||||
=> fatls scsi 0:1
|
||||
efi/
|
||||
|
||||
0 file(s), 1 dir(s)
|
||||
|
||||
|
||||
Partition 2 is 'Linux filesystem data' so that will be our root disk. It is
|
||||
in ext2 format:
|
||||
|
||||
=> ext2ls scsi 0:2
|
||||
<DIR> 4096 .
|
||||
<DIR> 4096 ..
|
||||
<DIR> 16384 lost+found
|
||||
<DIR> 4096 boot
|
||||
<DIR> 12288 etc
|
||||
<DIR> 4096 media
|
||||
<DIR> 4096 bin
|
||||
<DIR> 4096 dev
|
||||
<DIR> 4096 home
|
||||
<DIR> 4096 lib
|
||||
<DIR> 4096 lib64
|
||||
<DIR> 4096 mnt
|
||||
<DIR> 4096 opt
|
||||
<DIR> 4096 proc
|
||||
<DIR> 4096 root
|
||||
<DIR> 4096 run
|
||||
<DIR> 12288 sbin
|
||||
<DIR> 4096 srv
|
||||
<DIR> 4096 sys
|
||||
<DIR> 4096 tmp
|
||||
<DIR> 4096 usr
|
||||
<DIR> 4096 var
|
||||
<SYM> 33 initrd.img
|
||||
<SYM> 30 vmlinuz
|
||||
<DIR> 4096 cdrom
|
||||
<SYM> 33 initrd.img.old
|
||||
=>
|
||||
|
||||
and if you look in the /boot directory you will see the kernel:
|
||||
|
||||
=> ext2ls scsi 0:2 /boot
|
||||
<DIR> 4096 .
|
||||
<DIR> 4096 ..
|
||||
<DIR> 4096 efi
|
||||
<DIR> 4096 grub
|
||||
3381262 System.map-3.13.0-32-generic
|
||||
1162712 abi-3.13.0-32-generic
|
||||
165611 config-3.13.0-32-generic
|
||||
176500 memtest86+.bin
|
||||
178176 memtest86+.elf
|
||||
178680 memtest86+_multiboot.bin
|
||||
5798112 vmlinuz-3.13.0-32-generic
|
||||
165762 config-3.13.0-58-generic
|
||||
1165129 abi-3.13.0-58-generic
|
||||
5823136 vmlinuz-3.13.0-58-generic
|
||||
19215259 initrd.img-3.13.0-58-generic
|
||||
3391763 System.map-3.13.0-58-generic
|
||||
5825048 vmlinuz-3.13.0-58-generic.efi.signed
|
||||
28304443 initrd.img-3.13.0-32-generic
|
||||
=>
|
||||
|
||||
The 'vmlinuz' files contain a packaged Linux kernel. The format is a kind of
|
||||
self-extracting compressed file mixed with some 'setup' configuration data.
|
||||
Despite its size (uncompressed it is >10MB) this only includes a basic set of
|
||||
device drivers, enough to boot on most hardware types.
|
||||
|
||||
The 'initrd' files contain a RAM disk. This is something that can be loaded
|
||||
into RAM and will appear to Linux like a disk. Ubuntu uses this to hold lots
|
||||
of drivers for whatever hardware you might have. It is loaded before the
|
||||
real root disk is accessed.
|
||||
|
||||
The numbers after the end of each file are the version. Here it is Linux
|
||||
version 3.13. You can find the source code for this in the Linux tree with
|
||||
the tag v3.13. The '.0' allows for additional Linux releases to fix problems,
|
||||
but normally this is not needed. The '-58' is used by Ubuntu. Each time they
|
||||
release a new kernel they increment this number. New Ubuntu versions might
|
||||
include kernel patches to fix reported bugs. Stable kernels can exist for
|
||||
some years so this number can get quite high.
|
||||
|
||||
The '.efi.signed' kernel is signed for EFI's secure boot. U-Boot has its own
|
||||
secure boot mechanism - see [12] [13] and cannot read .efi files at present.
|
||||
|
||||
To boot Ubuntu from U-Boot the steps are as follows:
|
||||
|
||||
1. Set up the boot arguments. Use the GUID for the partition you want to
|
||||
boot:
|
||||
|
||||
=> setenv bootargs root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro
|
||||
|
||||
Here root= tells Linux the location of its root disk. The disk is specified
|
||||
by its GUID, using '/dev/disk/by-partuuid/', a Linux path to a 'directory'
|
||||
containing all the GUIDs Linux has found. When it starts up, there will be a
|
||||
file in that directory with this name in it. It is also possible to use a
|
||||
device name here, see later.
|
||||
|
||||
2. Load the kernel. Since it is an ext2/4 filesystem we can do:
|
||||
|
||||
=> ext2load scsi 0:2 03000000 /boot/vmlinuz-3.13.0-58-generic
|
||||
|
||||
The address 30000000 is arbitrary, but there seem to be problems with using
|
||||
small addresses (sometimes Linux cannot find the ramdisk). This is 48MB into
|
||||
the start of RAM (which is at 0 on x86).
|
||||
|
||||
3. Load the ramdisk (to 64MB):
|
||||
|
||||
=> ext2load scsi 0:2 04000000 /boot/initrd.img-3.13.0-58-generic
|
||||
|
||||
4. Start up the kernel. We need to know the size of the ramdisk, but can use
|
||||
a variable for that. U-Boot sets 'filesize' to the size of the last file it
|
||||
loaded.
|
||||
|
||||
=> zboot 03000000 0 04000000 ${filesize}
|
||||
|
||||
Type 'help zboot' if you want to see what the arguments are. U-Boot on x86 is
|
||||
quite verbose when it boots a kernel. You should see these messages from
|
||||
U-Boot:
|
||||
|
||||
Valid Boot Flag
|
||||
Setup Size = 0x00004400
|
||||
Magic signature found
|
||||
Using boot protocol version 2.0c
|
||||
Linux kernel version 3.13.0-58-generic (buildd@allspice) #97-Ubuntu SMP Wed Jul 8 02:56:15 UTC 2015
|
||||
Building boot_params at 0x00090000
|
||||
Loading bzImage at address 100000 (5805728 bytes)
|
||||
Magic signature found
|
||||
Initial RAM disk at linear address 0x04000000, size 19215259 bytes
|
||||
Kernel command line: "console=ttyS0,115200 root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro"
|
||||
|
||||
Starting kernel ...
|
||||
|
||||
U-Boot prints out some bootstage timing. This is more useful if you put the
|
||||
above commands into a script since then it will be faster.
|
||||
|
||||
Timer summary in microseconds:
|
||||
Mark Elapsed Stage
|
||||
0 0 reset
|
||||
241,535 241,535 board_init_r
|
||||
2,421,611 2,180,076 id=64
|
||||
2,421,790 179 id=65
|
||||
2,428,215 6,425 main_loop
|
||||
48,860,584 46,432,369 start_kernel
|
||||
|
||||
Accumulated time:
|
||||
240,329 ahci
|
||||
1,422,704 vesa display
|
||||
|
||||
Now the kernel actually starts:
|
||||
|
||||
[ 0.000000] Initializing cgroup subsys cpuset
|
||||
[ 0.000000] Initializing cgroup subsys cpu
|
||||
[ 0.000000] Initializing cgroup subsys cpuacct
|
||||
[ 0.000000] Linux version 3.13.0-58-generic (buildd@allspice) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #97-Ubuntu SMP Wed Jul 8 02:56:15 UTC 2015 (Ubuntu 3.13.0-58.97-generic 3.13.11-ckt22)
|
||||
[ 0.000000] Command line: console=ttyS0,115200 root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro
|
||||
|
||||
It continues for a long time. Along the way you will see it pick up your
|
||||
ramdisk:
|
||||
|
||||
[ 0.000000] RAMDISK: [mem 0x04000000-0x05253fff]
|
||||
...
|
||||
[ 0.788540] Trying to unpack rootfs image as initramfs...
|
||||
[ 1.540111] Freeing initrd memory: 18768K (ffff880004000000 - ffff880005254000)
|
||||
...
|
||||
|
||||
Later it actually starts using it:
|
||||
|
||||
Begin: Running /scripts/local-premount ... done.
|
||||
|
||||
You should also see your boot disk turn up:
|
||||
|
||||
[ 4.357243] scsi 1:0:0:0: Direct-Access ATA ADATA SP310 5.2 PQ: 0 ANSI: 5
|
||||
[ 4.366860] sd 1:0:0:0: [sda] 62533296 512-byte logical blocks: (32.0 GB/29.8 GiB)
|
||||
[ 4.375677] sd 1:0:0:0: Attached scsi generic sg0 type 0
|
||||
[ 4.381859] sd 1:0:0:0: [sda] Write Protect is off
|
||||
[ 4.387452] sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
|
||||
[ 4.399535] sda: sda1 sda2 sda3
|
||||
|
||||
Linux has found the three partitions (sda1-3). Mercifully it doesn't print out
|
||||
the GUIDs. In step 1 above we could have used:
|
||||
|
||||
setenv bootargs root=/dev/sda2 ro
|
||||
|
||||
instead of the GUID. However if you add another drive to your board the
|
||||
numbering may change whereas the GUIDs will not. So if your boot partition
|
||||
becomes sdb2, it will still boot. For embedded systems where you just want to
|
||||
boot the first disk, you have that option.
|
||||
|
||||
The last thing you will see on the console is mention of plymouth (which
|
||||
displays the Ubuntu start-up screen) and a lot of 'Starting' messages:
|
||||
|
||||
* Starting Mount filesystems on boot [ OK ]
|
||||
|
||||
After a pause you should see a login screen on your display and you are done.
|
||||
|
||||
If you want to put this in a script you can use something like this:
|
||||
|
||||
setenv bootargs root=UUID=b2aaf743-0418-4d90-94cc-3e6108d7d968 ro
|
||||
setenv boot zboot 03000000 0 04000000 \${filesize}
|
||||
setenv bootcmd "ext2load scsi 0:2 03000000 /boot/vmlinuz-3.13.0-58-generic; ext2load scsi 0:2 04000000 /boot/initrd.img-3.13.0-58-generic; run boot"
|
||||
saveenv
|
||||
|
||||
The \ is to tell the shell not to evaluate ${filesize} as part of the setenv
|
||||
command.
|
||||
|
||||
You will also need to add this to your board configuration file, e.g.
|
||||
include/configs/minnowmax.h:
|
||||
|
||||
#define CONFIG_BOOTDELAY 2
|
||||
|
||||
Now when you reset your board it wait a few seconds (in case you want to
|
||||
interrupt) and then should boot straight into Ubuntu.
|
||||
|
||||
You can also bake this behaviour into your build by hard-coding the
|
||||
environment variables if you add this to minnowmax.h:
|
||||
|
||||
#undef CONFIG_BOOTARGS
|
||||
#undef CONFIG_BOOTCOMMAND
|
||||
|
||||
#define CONFIG_BOOTARGS \
|
||||
"root=/dev/sda2 ro"
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"ext2load scsi 0:2 03000000 /boot/vmlinuz-3.13.0-58-generic; " \
|
||||
"ext2load scsi 0:2 04000000 /boot/initrd.img-3.13.0-58-generic; " \
|
||||
"run boot"
|
||||
|
||||
#undef CONFIG_EXTRA_ENV_SETTINGS
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS "boot=zboot 03000000 0 04000000 ${filesize}"
|
||||
|
||||
|
||||
Development Flow
|
||||
----------------
|
||||
These notes are for those who want to port U-Boot to a new x86 platform.
|
||||
|
@ -388,6 +668,46 @@ boot progress. This can be good for debugging.
|
|||
If not, you can try to get serial working as early as possible. The early
|
||||
debug serial port may be useful here. See setup_early_uart() for an example.
|
||||
|
||||
During the U-Boot porting, one of the important steps is to write correct PIRQ
|
||||
routing information in the board device tree. Without it, device drivers in the
|
||||
Linux kernel won't function correctly due to interrupt is not working. Please
|
||||
refer to U-Boot doc [14] for the device tree bindings of Intel interrupt router.
|
||||
Here we have more details on the intel,pirq-routing property below.
|
||||
|
||||
intel,pirq-routing = <
|
||||
PCI_BDF(0, 2, 0) INTA PIRQA
|
||||
...
|
||||
>;
|
||||
|
||||
As you see each entry has 3 cells. For the first one, we need describe all pci
|
||||
devices mounted on the board. For SoC devices, normally there is a chapter on
|
||||
the chipset datasheet which lists all the available PCI devices. For example on
|
||||
Bay Trail, this is chapter 4.3 (PCI configuration space). For the second one, we
|
||||
can get the interrupt pin either from datasheet or hardware via U-Boot shell.
|
||||
The reliable source is the hardware as sometimes chipset datasheet is not 100%
|
||||
up-to-date. Type 'pci header' plus the device's pci bus/device/function number
|
||||
from U-Boot shell below.
|
||||
|
||||
=> pci header 0.1e.1
|
||||
vendor ID = 0x8086
|
||||
device ID = 0x0f08
|
||||
...
|
||||
interrupt line = 0x09
|
||||
interrupt pin = 0x04
|
||||
...
|
||||
|
||||
It shows this PCI device is using INTD pin as it reports 4 in the interrupt pin
|
||||
register. Repeat this until you get interrupt pins for all the devices. The last
|
||||
cell is the PIRQ line which a particular interrupt pin is mapped to. On Intel
|
||||
chipset, the power-up default mapping is INTA/B/C/D maps to PIRQA/B/C/D. This
|
||||
can be changed by registers in LPC bridge. So far Intel FSP does not touch those
|
||||
registers so we can write down the PIRQ according to the default mapping rule.
|
||||
|
||||
Once we get the PIRQ routing information in the device tree, the interrupt
|
||||
allocation and assignment will be done by U-Boot automatically. Now you can
|
||||
enable CONFIG_GENERATE_PIRQ_TABLE for testing Linux kernel using i8259 PIC and
|
||||
CONFIG_GENERATE_MP_TABLE for testing Linux kernel using local APIC and I/O APIC.
|
||||
|
||||
TODO List
|
||||
---------
|
||||
- Audio
|
||||
|
@ -406,3 +726,7 @@ References
|
|||
[8] http://en.wikipedia.org/wiki/Microcode
|
||||
[9] http://simplefirmware.org
|
||||
[10] http://www.intel.com/design/archives/processors/pro/docs/242016.htm
|
||||
[11] https://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||
[12] http://events.linuxfoundation.org/sites/events/files/slides/chromeos_and_diy_vboot_0.pdf
|
||||
[13] http://events.linuxfoundation.org/sites/events/files/slides/elce-2014.pdf
|
||||
[14] doc/device-tree-bindings/misc/intel,irq-router.txt
|
||||
|
|
|
@ -17,8 +17,8 @@ Required properties :
|
|||
- intel,pirq-link : Specifies the PIRQ link information with two cells. The
|
||||
first cell is the register offset that controls the first PIRQ link routing.
|
||||
The second cell is the total number of PIRQ links the router supports.
|
||||
- intel,pirq-mask : Specifies the IRQ mask reprenting the 16 IRQs in 8259 PIC.
|
||||
Bit N is 1 means IRQ N is available to be routed.
|
||||
- intel,pirq-mask : Specifies the IRQ mask representing the 16 IRQs in the
|
||||
8259 PIC. Bit N is 1 means IRQ N is available to be routed.
|
||||
- intel,pirq-routing : Specifies all PCI devices' IRQ routing information,
|
||||
encoded as 3 cells a group for a device. The first cell is the device's PCI
|
||||
bus number, device number and function number encoding with PCI_BDF() macro.
|
||||
|
|
|
@ -6,7 +6,7 @@ How busses are scanned
|
|||
|
||||
Any config read will end up at pci_read_config(). This uses
|
||||
uclass_get_device_by_seq() to get the PCI bus for a particular bus number.
|
||||
Bus number 0 will need to be requested first, and the alias in the device
|
||||
Bus number 0 will need to be requested first, and the alias in the device
|
||||
tree file will point to the correct device:
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ tree file will point to the correct device:
|
|||
If there is no alias the devices will be numbered sequentially in the device
|
||||
tree.
|
||||
|
||||
The call to uclass_get_device by seq() will cause the PCI bus to be probed.
|
||||
The call to uclass_get_device() will cause the PCI bus to be probed.
|
||||
This does a scan of the bus to locate available devices. These devices are
|
||||
bound to their appropriate driver if available. If there is no driver, then
|
||||
they are bound to a generic PCI driver which does nothing.
|
||||
|
@ -32,7 +32,7 @@ After probing a bus, the available devices will appear in the device tree
|
|||
under that bus.
|
||||
|
||||
Note that this is all done on a lazy basis, as needed, so until something is
|
||||
touched on PCI it will not be probed.
|
||||
touched on PCI (eg: a call to pci_find_devices()) it will not be probed.
|
||||
|
||||
PCI devices can appear in the device tree. If they do this serves to specify
|
||||
the driver to use for the device. In this case they will be bound at
|
||||
|
|
|
@ -153,6 +153,8 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
|
|||
ret = uclass_get(id, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (list_empty(&uc->dev_head))
|
||||
return -ENODEV;
|
||||
|
||||
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
|
||||
if (!index--) {
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/pci.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define GPIO_PER_BANK 32
|
||||
|
||||
struct ich6_bank_priv {
|
||||
|
|
|
@ -641,10 +641,6 @@ static int pci_uclass_post_probe(struct udevice *bus)
|
|||
{
|
||||
int ret;
|
||||
|
||||
/* Don't scan buses before relocation */
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
return 0;
|
||||
|
||||
debug("%s: probing bus %d\n", __func__, bus->seq);
|
||||
ret = pci_bind_bus_devices(bus);
|
||||
if (ret)
|
||||
|
|
|
@ -269,7 +269,8 @@ int pci_hose_config_device(struct pci_controller *hose,
|
|||
/* Disable interrupt line, if device says it wants to use interrupts */
|
||||
pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (pin != 0) {
|
||||
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff);
|
||||
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE,
|
||||
PCI_INTERRUPT_LINE_DISABLE);
|
||||
}
|
||||
|
||||
pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
|
||||
|
|
|
@ -14,12 +14,6 @@
|
|||
#include <errno.h>
|
||||
#include <pci.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUGF(x...) printf(x)
|
||||
#else
|
||||
#define DEBUGF(x...)
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */
|
||||
#ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE
|
||||
#define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8
|
||||
|
@ -50,20 +44,21 @@ int pciauto_region_allocate(struct pci_region *res, pci_size_t size,
|
|||
pci_addr_t addr;
|
||||
|
||||
if (!res) {
|
||||
DEBUGF("No resource");
|
||||
debug("No resource");
|
||||
goto error;
|
||||
}
|
||||
|
||||
addr = ((res->bus_lower - 1) | (size - 1)) + 1;
|
||||
|
||||
if (addr - res->bus_start + size > res->size) {
|
||||
DEBUGF("No room in resource");
|
||||
debug("No room in resource");
|
||||
goto error;
|
||||
}
|
||||
|
||||
res->bus_lower = addr + size;
|
||||
|
||||
DEBUGF("address=0x%llx bus_lower=0x%llx", (u64)addr, (u64)res->bus_lower);
|
||||
debug("address=0x%llx bus_lower=0x%llx", (unsigned long long)addr,
|
||||
(unsigned long long)res->bus_lower);
|
||||
|
||||
*bar = addr;
|
||||
return 0;
|
||||
|
@ -87,9 +82,9 @@ void pciauto_setup_device(struct pci_controller *hose,
|
|||
pci_size_t bar_size;
|
||||
u16 cmdstat = 0;
|
||||
int bar, bar_nr = 0;
|
||||
#ifndef CONFIG_PCI_ENUM_ONLY
|
||||
u8 header_type;
|
||||
int rom_addr;
|
||||
#ifndef CONFIG_PCI_ENUM_ONLY
|
||||
pci_addr_t bar_value;
|
||||
struct pci_region *bar_res;
|
||||
int found_mem64 = 0;
|
||||
|
@ -122,7 +117,8 @@ void pciauto_setup_device(struct pci_controller *hose,
|
|||
bar_res = io;
|
||||
#endif
|
||||
|
||||
DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size);
|
||||
debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ",
|
||||
bar_nr, (unsigned long long)bar_size);
|
||||
} else {
|
||||
if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_64) {
|
||||
|
@ -152,7 +148,9 @@ void pciauto_setup_device(struct pci_controller *hose,
|
|||
bar_res = mem;
|
||||
#endif
|
||||
|
||||
DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size);
|
||||
debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ",
|
||||
bar_nr, bar_res == prefetch ? "Prf" : "Mem",
|
||||
(unsigned long long)bar_size);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PCI_ENUM_ONLY
|
||||
|
@ -179,11 +177,12 @@ void pciauto_setup_device(struct pci_controller *hose,
|
|||
cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
|
||||
PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
|
||||
|
||||
DEBUGF("\n");
|
||||
debug("\n");
|
||||
|
||||
bar_nr++;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PCI_ENUM_ONLY
|
||||
/* Configure the expansion ROM address */
|
||||
pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
|
||||
if (header_type != PCI_HEADER_TYPE_CARDBUS) {
|
||||
|
@ -193,16 +192,18 @@ void pciauto_setup_device(struct pci_controller *hose,
|
|||
pci_hose_read_config_dword(hose, dev, rom_addr, &bar_response);
|
||||
if (bar_response) {
|
||||
bar_size = -(bar_response & ~1);
|
||||
DEBUGF("PCI Autoconfig: ROM, size=%#x, ", bar_size);
|
||||
debug("PCI Autoconfig: ROM, size=%#x, ",
|
||||
(unsigned int)bar_size);
|
||||
if (pciauto_region_allocate(mem, bar_size,
|
||||
&bar_value) == 0) {
|
||||
pci_hose_write_config_dword(hose, dev, rom_addr,
|
||||
bar_value);
|
||||
}
|
||||
cmdstat |= PCI_COMMAND_MEMORY;
|
||||
DEBUGF("\n");
|
||||
debug("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat);
|
||||
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE,
|
||||
|
@ -411,7 +412,7 @@ void pciauto_config_init(struct pci_controller *hose)
|
|||
if (hose->pci_mem) {
|
||||
pciauto_region_init(hose->pci_mem);
|
||||
|
||||
DEBUGF("PCI Autoconfig: Bus Memory region: [0x%llx-0x%llx],\n"
|
||||
debug("PCI Autoconfig: Bus Memory region: [0x%llx-0x%llx],\n"
|
||||
"\t\tPhysical Memory [%llx-%llxx]\n",
|
||||
(u64)hose->pci_mem->bus_start,
|
||||
(u64)(hose->pci_mem->bus_start + hose->pci_mem->size - 1),
|
||||
|
@ -422,7 +423,7 @@ void pciauto_config_init(struct pci_controller *hose)
|
|||
if (hose->pci_prefetch) {
|
||||
pciauto_region_init(hose->pci_prefetch);
|
||||
|
||||
DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [0x%llx-0x%llx],\n"
|
||||
debug("PCI Autoconfig: Bus Prefetchable Mem: [0x%llx-0x%llx],\n"
|
||||
"\t\tPhysical Memory [%llx-%llx]\n",
|
||||
(u64)hose->pci_prefetch->bus_start,
|
||||
(u64)(hose->pci_prefetch->bus_start +
|
||||
|
@ -435,7 +436,7 @@ void pciauto_config_init(struct pci_controller *hose)
|
|||
if (hose->pci_io) {
|
||||
pciauto_region_init(hose->pci_io);
|
||||
|
||||
DEBUGF("PCI Autoconfig: Bus I/O region: [0x%llx-0x%llx],\n"
|
||||
debug("PCI Autoconfig: Bus I/O region: [0x%llx-0x%llx],\n"
|
||||
"\t\tPhysical Memory: [%llx-%llx]\n",
|
||||
(u64)hose->pci_io->bus_start,
|
||||
(u64)(hose->pci_io->bus_start + hose->pci_io->size - 1),
|
||||
|
@ -475,8 +476,8 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
|
|||
|
||||
switch (class) {
|
||||
case PCI_CLASS_BRIDGE_PCI:
|
||||
DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n",
|
||||
PCI_DEV(dev));
|
||||
debug("PCI Autoconfig: Found P2P bridge, device %d\n",
|
||||
PCI_DEV(dev));
|
||||
|
||||
pciauto_setup_device(hose, dev, 2, pci_mem,
|
||||
pci_prefetch, pci_io);
|
||||
|
@ -512,8 +513,8 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
|
|||
pciauto_setup_device(hose, dev, 0, pci_mem,
|
||||
pci_prefetch, pci_io);
|
||||
|
||||
DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
|
||||
PCI_DEV(dev));
|
||||
debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
|
||||
PCI_DEV(dev));
|
||||
|
||||
#ifndef CONFIG_DM_PCI
|
||||
hose->current_busno++;
|
||||
|
@ -522,8 +523,8 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
|
|||
|
||||
#if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE)
|
||||
case PCI_CLASS_BRIDGE_OTHER:
|
||||
DEBUGF("PCI Autoconfig: Skipping bridge device %d\n",
|
||||
PCI_DEV(dev));
|
||||
debug("PCI Autoconfig: Skipping bridge device %d\n",
|
||||
PCI_DEV(dev));
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_MPC834x) && !defined(CONFIG_VME8349)
|
||||
|
@ -534,14 +535,14 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
|
|||
* device claiming resources io/mem/irq.. we only allow for
|
||||
* the PIMMR window to be allocated (BAR0 - 1MB size)
|
||||
*/
|
||||
DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
|
||||
debug("PCI Autoconfig: Broken bridge found, only minimal config\n");
|
||||
pciauto_setup_device(hose, dev, 0, hose->pci_mem,
|
||||
hose->pci_prefetch, hose->pci_io);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */
|
||||
DEBUGF("PCI AutoConfig: Found PowerPC device\n");
|
||||
debug("PCI AutoConfig: Found PowerPC device\n");
|
||||
|
||||
default:
|
||||
pciauto_setup_device(hose, dev, 6, pci_mem,
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#define DEBUG
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
|
|
|
@ -235,6 +235,10 @@ void setup_video(struct screen_info *screen_info)
|
|||
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
|
||||
struct vesa_mode_info *vesa = &mode_info.vesa;
|
||||
|
||||
/* Sanity test on VESA parameters */
|
||||
if (!vesa->x_resolution || !vesa->y_resolution)
|
||||
return;
|
||||
|
||||
screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB;
|
||||
|
||||
screen_info->lfb_width = vesa->x_resolution;
|
||||
|
|
|
@ -44,6 +44,15 @@ config DEBUG_UART_NS16550
|
|||
will need to provide parameters to make this work. The driver will
|
||||
be available until the real driver model serial is running.
|
||||
|
||||
config DEBUG_EFI_CONSOLE
|
||||
bool "EFI"
|
||||
depends on EFI_APP
|
||||
help
|
||||
Select this to enable a debug console which calls back to EFI to
|
||||
output to the console. This can be useful for early debugging of
|
||||
U-Boot when running on top of EFI (Extensive Firmware Interface).
|
||||
This is a type of BIOS used by PCs.
|
||||
|
||||
endchoice
|
||||
|
||||
config DEBUG_UART_BASE
|
||||
|
@ -102,3 +111,13 @@ config UNIPHIER_SERIAL
|
|||
help
|
||||
If you have a UniPhier based board and want to use the on-chip
|
||||
serial ports, say Y to this option. If unsure, say N.
|
||||
|
||||
config X86_SERIAL
|
||||
bool "Support for 16550 serial port on x86 machines"
|
||||
depends on X86
|
||||
default y
|
||||
help
|
||||
Most x86 machines have a ns16550 UART or compatible. This can be
|
||||
enabled in the device tree with the correct input clock frequency
|
||||
provided (default 1843200). Enable this to obtain serial console
|
||||
output.
|
||||
|
|
|
@ -21,6 +21,7 @@ obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
|
|||
obj-$(CONFIG_ARM_DCC) += arm_dcc.o
|
||||
obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
|
||||
obj-$(CONFIG_DW_SERIAL) += serial_dw.o
|
||||
obj-$(CONFIG_EFI_APP) += serial_efi.o
|
||||
obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
|
||||
obj-$(CONFIG_MCFUART) += mcfuart.o
|
||||
obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
|
||||
|
|
|
@ -71,7 +71,7 @@ static void serial_find_console_or_panic(void)
|
|||
#endif
|
||||
if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
|
||||
!uclass_get_device(UCLASS_SERIAL, INDEX, &dev) ||
|
||||
(!uclass_first_device(UCLASS_SERIAL, &dev) || dev)) {
|
||||
(!uclass_first_device(UCLASS_SERIAL, &dev) && dev)) {
|
||||
gd->cur_serial_dev = dev;
|
||||
return;
|
||||
}
|
||||
|
|
157
drivers/serial/serial_efi.c
Normal file
157
drivers/serial/serial_efi.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <dm.h>
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/io.h>
|
||||
#include <serial.h>
|
||||
|
||||
/* Information about the efi console */
|
||||
struct serial_efi_priv {
|
||||
struct efi_simple_input_interface *con_in;
|
||||
struct efi_simple_text_output_protocol *con_out;
|
||||
struct efi_input_key key;
|
||||
bool have_key;
|
||||
};
|
||||
|
||||
int serial_efi_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_efi_get_key(struct serial_efi_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (priv->have_key)
|
||||
return 0;
|
||||
ret = priv->con_in->read_key_stroke(priv->con_in, &priv->key);
|
||||
if (ret == EFI_NOT_READY)
|
||||
return -EAGAIN;
|
||||
else if (ret != EFI_SUCCESS)
|
||||
return -EIO;
|
||||
|
||||
priv->have_key = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_efi_getc(struct udevice *dev)
|
||||
{
|
||||
struct serial_efi_priv *priv = dev_get_priv(dev);
|
||||
int ret, ch;
|
||||
|
||||
ret = serial_efi_get_key(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->have_key = false;
|
||||
ch = priv->key.unicode_char;
|
||||
|
||||
/*
|
||||
* Unicode char 8 (for backspace) is never returned. Instead we get a
|
||||
* key scan code of 8. Handle this so that backspace works correctly
|
||||
* in the U-Boot command line.
|
||||
*/
|
||||
if (!ch && priv->key.scan_code == 8)
|
||||
ch = 8;
|
||||
debug(" [%x %x %x] ", ch, priv->key.unicode_char, priv->key.scan_code);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
static int serial_efi_putc(struct udevice *dev, const char ch)
|
||||
{
|
||||
struct serial_efi_priv *priv = dev_get_priv(dev);
|
||||
uint16_t ucode[2];
|
||||
int ret;
|
||||
|
||||
ucode[0] = ch;
|
||||
ucode[1] = '\0';
|
||||
ret = priv->con_out->output_string(priv->con_out, ucode);
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_efi_pending(struct udevice *dev, bool input)
|
||||
{
|
||||
struct serial_efi_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
/* We assume that EFI will stall if its output buffer fills up */
|
||||
if (!input)
|
||||
return 0;
|
||||
|
||||
ret = serial_efi_get_key(priv);
|
||||
if (ret == -EAGAIN)
|
||||
return 0;
|
||||
else if (ret)
|
||||
return ret;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is nothing to init here since the EFI console is already running by
|
||||
* the time we enter U-Boot.
|
||||
*/
|
||||
void debug_uart_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void _debug_uart_putc(int ch)
|
||||
{
|
||||
struct efi_system_table *sys_table = efi_get_sys_table();
|
||||
uint16_t ucode[2];
|
||||
|
||||
ucode[0] = ch;
|
||||
ucode[1] = '\0';
|
||||
sys_table->con_out->output_string(sys_table->con_out, ucode);
|
||||
}
|
||||
|
||||
DEBUG_UART_FUNCS
|
||||
|
||||
static int serial_efi_probe(struct udevice *dev)
|
||||
{
|
||||
struct efi_system_table *table = efi_get_sys_table();
|
||||
struct serial_efi_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->con_in = table->con_in;
|
||||
priv->con_out = table->con_out;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_serial_ops serial_efi_ops = {
|
||||
.putc = serial_efi_putc,
|
||||
.getc = serial_efi_getc,
|
||||
.pending = serial_efi_pending,
|
||||
.setbrg = serial_efi_setbrg,
|
||||
};
|
||||
|
||||
static const struct udevice_id serial_efi_ids[] = {
|
||||
{ .compatible = "efi,uart" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_efi) = {
|
||||
.name = "serial_efi",
|
||||
.id = UCLASS_SERIAL,
|
||||
.of_match = serial_efi_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct serial_efi_priv),
|
||||
.probe = serial_efi_probe,
|
||||
.ops = &serial_efi_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
|
@ -24,6 +24,14 @@ void *video_hw_init(void)
|
|||
int ret;
|
||||
|
||||
printf("Video: ");
|
||||
if (!ll_boot_init()) {
|
||||
/*
|
||||
* If we are running from EFI or coreboot, this driver can't
|
||||
* work.
|
||||
*/
|
||||
printf("Not available (previous bootloader prevents it)\n");
|
||||
return NULL;
|
||||
}
|
||||
if (vbe_get_video_info(gdev)) {
|
||||
dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
|
||||
if (dev == -1) {
|
||||
|
|
|
@ -104,7 +104,7 @@ typedef struct global_data {
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Global Data Flags
|
||||
* Global Data Flags - the top 16 bits are reserved for arch-specific flags
|
||||
*/
|
||||
#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */
|
||||
#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
|
||||
|
@ -117,5 +117,6 @@ typedef struct global_data {
|
|||
#define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */
|
||||
#define GD_FLG_FULL_MALLOC_INIT 0x00200 /* Full malloc() is ready */
|
||||
#define GD_FLG_SPL_INIT 0x00400 /* spl_init() has been called */
|
||||
#define GD_FLG_SKIP_RELOC 0x00800 /* Don't relocate */
|
||||
|
||||
#endif /* __ASM_GENERIC_GBL_DATA_H */
|
||||
|
|
|
@ -1021,6 +1021,13 @@ int cpu_release(int nr, int argc, char * const argv[]);
|
|||
offsetof(struct structure, member) == offset, \
|
||||
"`struct " #structure "` offset for `" #member "` is not " #offset)
|
||||
|
||||
/* Avoid using CONFIG_EFI_STUB directly as we may boot from other loaders */
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
#define ll_boot_init() false
|
||||
#else
|
||||
#define ll_boot_init() true
|
||||
#endif
|
||||
|
||||
/* Pull in stuff for the build system */
|
||||
#ifdef DO_DEPS_ONLY
|
||||
# include <environment.h>
|
||||
|
|
44
include/configs/bayleybay.h
Normal file
44
include/configs/bayleybay.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2015, 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_ARCH_MISC_INIT
|
||||
|
||||
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
|
||||
#define CONFIG_SYS_EARLY_PCI_INIT
|
||||
#define CONFIG_PCI_PNP
|
||||
#define CONFIG_E1000
|
||||
|
||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga,usbkbd\0" \
|
||||
"stdout=serial,vga\0" \
|
||||
"stderr=serial,vga\0"
|
||||
|
||||
#define CONFIG_SCSI_DEV_LIST \
|
||||
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}
|
||||
|
||||
#define CONFIG_MMC
|
||||
#define CONFIG_SDHCI
|
||||
#define CONFIG_GENERIC_MMC
|
||||
#define CONFIG_MMC_SDMA
|
||||
#define CONFIG_CMD_MMC
|
||||
|
||||
/* BayTrail IGD support */
|
||||
#define CONFIG_VGA_AS_SINGLE_DEVICE
|
||||
|
||||
/* Environment configuration */
|
||||
#define CONFIG_ENV_SECT_SIZE 0x1000
|
||||
#define CONFIG_ENV_OFFSET 0x006ff000
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -17,7 +17,6 @@
|
|||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
#define CONFIG_ARCH_MISC_INIT
|
||||
|
||||
#define CONFIG_X86_SERIAL
|
||||
#define CONFIG_SMSC_LPC47M
|
||||
|
||||
#define CONFIG_PCI_MEM_BUS 0x40000000
|
||||
|
|
34
include/configs/efi-x86.h
Normal file
34
include/configs/efi-x86.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#include <configs/x86-common.h>
|
||||
|
||||
#undef CONFIG_CMD_SF_TEST
|
||||
|
||||
#undef CONFIG_TPM
|
||||
#undef CONFIG_TPM_TIS_LPC
|
||||
#undef CONFIG_TPM_TIS_BASE_ADDRESS
|
||||
|
||||
#undef CONFIG_CMD_IMLS
|
||||
|
||||
#undef CONFIG_SYS_NS16550
|
||||
#undef CONFIG_X86_SERIAL
|
||||
#undef CONFIG_ENV_IS_IN_SPI_FLASH
|
||||
#define CONFIG_ENV_IS_NOWHERE
|
||||
#undef CONFIG_VIDEO
|
||||
#undef CONFIG_CFB_CONSOLE
|
||||
#undef CONFIG_SCSI_AHCI
|
||||
#undef CONFIG_CMD_SCSI
|
||||
#undef CONFIG_INTEL_ICH6_GPIO
|
||||
|
||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
|
||||
"stdout=vga,serial\0" \
|
||||
"stderr=vga,serial\0"
|
||||
|
||||
#endif
|
|
@ -17,8 +17,6 @@
|
|||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
#define CONFIG_ARCH_MISC_INIT
|
||||
|
||||
#define CONFIG_X86_SERIAL
|
||||
|
||||
/* ns16550 UART is memory-mapped in Quark SoC */
|
||||
#undef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue