Merge git://git.denx.de/u-boot-x86
This commit is contained in:
commit
5f88ed5cde
@ -47,13 +47,10 @@ config RAMBASE
|
||||
hex
|
||||
default 0x100000
|
||||
|
||||
config RAMTOP
|
||||
hex
|
||||
default 0x200000
|
||||
|
||||
config XIP_ROM_SIZE
|
||||
hex
|
||||
default 0x10000
|
||||
depends on X86_RESET_VECTOR
|
||||
default ROM_SIZE
|
||||
|
||||
config CPU_ADDR_BITS
|
||||
int
|
||||
@ -70,6 +67,15 @@ config SMM_TSEG
|
||||
config SMM_TSEG_SIZE
|
||||
hex
|
||||
|
||||
config X86_RESET_VECTOR
|
||||
bool
|
||||
default n
|
||||
|
||||
config SYS_X86_START16
|
||||
hex
|
||||
depends on X86_RESET_VECTOR
|
||||
default 0xfffff800
|
||||
|
||||
config BOARD_ROMSIZE_KB_512
|
||||
bool
|
||||
config BOARD_ROMSIZE_KB_1024
|
||||
@ -85,6 +91,7 @@ config BOARD_ROMSIZE_KB_16384
|
||||
|
||||
choice
|
||||
prompt "ROM chip size"
|
||||
depends on X86_RESET_VECTOR
|
||||
default UBOOT_ROMSIZE_KB_512 if BOARD_ROMSIZE_KB_512
|
||||
default UBOOT_ROMSIZE_KB_1024 if BOARD_ROMSIZE_KB_1024
|
||||
default UBOOT_ROMSIZE_KB_2048 if BOARD_ROMSIZE_KB_2048
|
||||
@ -317,6 +324,28 @@ config FRAMEBUFFER_VESA_MODE
|
||||
|
||||
endmenu
|
||||
|
||||
config TSC_CALIBRATION_BYPASS
|
||||
bool "Bypass Time-Stamp Counter (TSC) calibration"
|
||||
default n
|
||||
help
|
||||
By default U-Boot automatically calibrates Time-Stamp Counter (TSC)
|
||||
running frequency via Model-Specific Register (MSR) and Programmable
|
||||
Interval Timer (PIT). If the calibration does not work on your board,
|
||||
select this option and provide a hardcoded TSC running frequency with
|
||||
CONFIG_TSC_FREQ_IN_MHZ below.
|
||||
|
||||
Normally this option should be turned on in a simulation environment
|
||||
like qemu.
|
||||
|
||||
config TSC_FREQ_IN_MHZ
|
||||
int "Time-Stamp Counter (TSC) running frequency in MHz"
|
||||
depends on TSC_CALIBRATION_BYPASS
|
||||
default 1000
|
||||
help
|
||||
The running frequency in MHz of Time-Stamp Counter (TSC).
|
||||
|
||||
source "arch/x86/cpu/coreboot/Kconfig"
|
||||
|
||||
source "arch/x86/cpu/ivybridge/Kconfig"
|
||||
|
||||
source "arch/x86/cpu/queensbay/Kconfig"
|
||||
|
@ -17,5 +17,6 @@ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
|
||||
obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
|
||||
obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
|
||||
obj-y += lapic.o
|
||||
obj-y += mtrr.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
obj-y += turbo.o
|
||||
|
15
arch/x86/cpu/coreboot/Kconfig
Normal file
15
arch/x86/cpu/coreboot/Kconfig
Normal file
@ -0,0 +1,15 @@
|
||||
if TARGET_COREBOOT
|
||||
|
||||
config SYS_COREBOOT
|
||||
bool
|
||||
default y
|
||||
|
||||
config CBMEM_CONSOLE
|
||||
bool
|
||||
default y
|
||||
|
||||
config VIDEO_COREBOOT
|
||||
bool
|
||||
default y
|
||||
|
||||
endif
|
@ -15,6 +15,7 @@
|
||||
#include <asm/cache.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/arch/tables.h>
|
||||
#include <asm/arch/sysinfo.h>
|
||||
#include <asm/arch/timestamp.h>
|
||||
@ -64,11 +65,6 @@ int board_eth_init(bd_t *bis)
|
||||
return pci_eth_init(bis);
|
||||
}
|
||||
|
||||
#define MTRR_TYPE_WP 5
|
||||
#define MTRRcap_MSR 0xfe
|
||||
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
void board_final_cleanup(void)
|
||||
{
|
||||
/* Un-cache the ROM so the kernel has one
|
||||
@ -77,15 +73,17 @@ void board_final_cleanup(void)
|
||||
* Coreboot should have assigned this to the
|
||||
* top available variable MTRR.
|
||||
*/
|
||||
u8 top_mtrr = (native_read_msr(MTRRcap_MSR) & 0xff) - 1;
|
||||
u8 top_type = native_read_msr(MTRRphysBase_MSR(top_mtrr)) & 0xff;
|
||||
u8 top_mtrr = (native_read_msr(MTRR_CAP_MSR) & 0xff) - 1;
|
||||
u8 top_type = native_read_msr(MTRR_PHYS_BASE_MSR(top_mtrr)) & 0xff;
|
||||
|
||||
/* Make sure this MTRR is the correct Write-Protected type */
|
||||
if (top_type == MTRR_TYPE_WP) {
|
||||
disable_caches();
|
||||
wrmsrl(MTRRphysBase_MSR(top_mtrr), 0);
|
||||
wrmsrl(MTRRphysMask_MSR(top_mtrr), 0);
|
||||
enable_caches();
|
||||
if (top_type == MTRR_TYPE_WRPROT) {
|
||||
struct mtrr_state state;
|
||||
|
||||
mtrr_open(&state);
|
||||
wrmsrl(MTRR_PHYS_BASE_MSR(top_mtrr), 0);
|
||||
wrmsrl(MTRR_PHYS_MASK_MSR(top_mtrr), 0);
|
||||
mtrr_close(&state);
|
||||
}
|
||||
|
||||
/* Issue SMI to Coreboot to lock down ME and registers */
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <pci.h>
|
||||
#include <asm/pci.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
|
||||
struct pci_config_table *table)
|
||||
{
|
||||
@ -35,7 +37,31 @@ void board_pci_setup_hose(struct pci_controller *hose)
|
||||
hose->first_busno = 0;
|
||||
hose->last_busno = 0;
|
||||
|
||||
pci_set_region(hose->regions + 0, 0x0, 0x0, 0xffffffff,
|
||||
/* PCI memory space */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_PCI_MEM_BUS,
|
||||
CONFIG_PCI_MEM_PHYS,
|
||||
CONFIG_PCI_MEM_SIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
|
||||
/* PCI IO space */
|
||||
pci_set_region(hose->regions + 1,
|
||||
CONFIG_PCI_IO_BUS,
|
||||
CONFIG_PCI_IO_PHYS,
|
||||
CONFIG_PCI_IO_SIZE,
|
||||
PCI_REGION_IO);
|
||||
|
||||
pci_set_region(hose->regions + 2,
|
||||
CONFIG_PCI_PREF_BUS,
|
||||
CONFIG_PCI_PREF_PHYS,
|
||||
CONFIG_PCI_PREF_SIZE,
|
||||
PCI_REGION_PREFETCH);
|
||||
|
||||
pci_set_region(hose->regions + 3,
|
||||
0,
|
||||
0,
|
||||
gd->ram_size,
|
||||
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
|
||||
|
||||
hose->region_count = 4;
|
||||
}
|
||||
|
@ -3,18 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
@ -38,9 +27,27 @@ static struct timestamp_table *ts_table __attribute__((section(".data")));
|
||||
|
||||
void timestamp_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_X86_TSC_TIMER
|
||||
uint64_t base_time;
|
||||
#endif
|
||||
|
||||
ts_table = lib_sysinfo.tstamp_table;
|
||||
#ifdef CONFIG_SYS_X86_TSC_TIMER
|
||||
timer_set_base(ts_table->base_time);
|
||||
/*
|
||||
* If coreboot is built with CONFIG_COLLECT_TIMESTAMPS, use the value
|
||||
* of base_time in coreboot's timestamp table as our timer base,
|
||||
* otherwise TSC counter value will be used.
|
||||
*
|
||||
* Sometimes even coreboot is built with CONFIG_COLLECT_TIMESTAMPS,
|
||||
* the value of base_time in the timestamp table is still zero, so
|
||||
* we must exclude this case too (this is currently seen on booting
|
||||
* coreboot in qemu)
|
||||
*/
|
||||
if (ts_table && ts_table->base_time)
|
||||
base_time = ts_table->base_time;
|
||||
else
|
||||
base_time = rdtsc();
|
||||
timer_set_base(base_time);
|
||||
#endif
|
||||
timestamp_add_now(TS_U_BOOT_INITTED);
|
||||
}
|
||||
|
@ -12,9 +12,11 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/msr-index.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/arch/microcode.h>
|
||||
|
||||
#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
@ -45,6 +47,14 @@ car_init:
|
||||
movl $0xFEE00300, %esi
|
||||
movl %eax, (%esi)
|
||||
|
||||
/* TODO: Load microcode later - the 'no eviction' mode breaks this */
|
||||
movl $MSR_IA32_UCODE_WRITE, %ecx
|
||||
xorl %edx, %edx
|
||||
movl $_dt_ucode_base_size, %eax
|
||||
movl (%eax), %eax
|
||||
addl $UCODE_HEADER_LEN, %eax
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_SIPI)
|
||||
/* Zero out all fixed range and variable range MTRRs */
|
||||
movl $mtrr_table, %esi
|
||||
@ -61,7 +71,7 @@ clear_mtrrs:
|
||||
|
||||
post_code(POST_CAR_MTRR)
|
||||
/* Configure the default memory type to uncacheable */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(~0x00000cff), %eax
|
||||
wrmsr
|
||||
@ -76,16 +86,16 @@ clear_mtrrs:
|
||||
post_code(POST_CAR_BASE_ADDRESS)
|
||||
/* Set Cache-as-RAM mask */
|
||||
movl $(MTRR_PHYS_MASK_MSR(0)), %ecx
|
||||
movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_MASK)
|
||||
|
||||
/* Enable MTRR */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
orl $MTRRdefTypeEn, %eax
|
||||
orl $MTRR_DEF_TYPE_EN, %eax
|
||||
wrmsr
|
||||
|
||||
/* Enable cache (CR0.CD = 0, CR0.NW = 0) */
|
||||
@ -130,7 +140,7 @@ clear_mtrrs:
|
||||
|
||||
movl $MTRR_PHYS_MASK_MSR(1), %ecx
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_ROM_CACHE)
|
||||
@ -141,7 +151,7 @@ clear_mtrrs:
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
movl $MTRR_PHYS_MASK_MSR(2), %ecx
|
||||
movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
|
||||
movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
#endif
|
||||
@ -163,6 +173,52 @@ wait_for_sipi:
|
||||
/* return */
|
||||
jmp car_init_ret
|
||||
|
||||
.globl car_uninit
|
||||
car_uninit:
|
||||
/* Disable cache */
|
||||
movl %cr0, %eax
|
||||
orl $X86_CR0_CD, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable MTRRs */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(~MTRR_DEF_TYPE_EN), %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable the no-eviction run state */
|
||||
movl NOEVICTMOD_MSR, %ecx
|
||||
rdmsr
|
||||
andl $~2, %eax
|
||||
wrmsr
|
||||
|
||||
invd
|
||||
|
||||
/* Disable the no-eviction mode */
|
||||
rdmsr
|
||||
andl $~1, %eax
|
||||
wrmsr
|
||||
|
||||
#ifdef CONFIG_CACHE_MRC_BIN
|
||||
/* Clear the MTRR that was used to cache MRC */
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
movl $MTRR_PHYS_BASE_MSR(2), %ecx
|
||||
wrmsr
|
||||
movl $MTRR_PHYS_MASK_MSR(2), %ecx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
/* Enable MTRRs */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
orl $MTRR_DEF_TYPE_EN, %eax
|
||||
wrmsr
|
||||
|
||||
invd
|
||||
|
||||
ret
|
||||
|
||||
mtrr_table:
|
||||
/* Fixed MTRRs */
|
||||
.word 0x250, 0x258, 0x259
|
||||
@ -176,3 +232,9 @@ mtrr_table:
|
||||
.word 0x20C, 0x20D, 0x20E, 0x20F
|
||||
.word 0x210, 0x211, 0x212, 0x213
|
||||
mtrr_table_end:
|
||||
|
||||
.align 4
|
||||
_dt_ucode_base_size:
|
||||
/* These next two fields are filled in by ifdtool */
|
||||
.long 0 /* microcode base */
|
||||
.long 0 /* microcode size */
|
||||
|
@ -49,27 +49,6 @@ static void enable_spi_prefetch(struct pci_controller *hose, pci_dev_t dev)
|
||||
pci_hose_write_config_byte(hose, dev, 0xdc, reg8);
|
||||
}
|
||||
|
||||
static void set_var_mtrr(
|
||||
unsigned reg, unsigned base, unsigned size, unsigned type)
|
||||
|
||||
{
|
||||
/* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
|
||||
/* FIXME: It only support 4G less range */
|
||||
wrmsr(MTRRphysBase_MSR(reg), base | type, 0);
|
||||
wrmsr(MTRRphysMask_MSR(reg), ~(size - 1) | MTRRphysMaskValid,
|
||||
(1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1);
|
||||
}
|
||||
|
||||
static void enable_rom_caching(void)
|
||||
{
|
||||
disable_caches();
|
||||
set_var_mtrr(1, 0xffc00000, 4 << 20, MTRR_TYPE_WRPROT);
|
||||
enable_caches();
|
||||
|
||||
/* Enable Variable MTRRs */
|
||||
wrmsr(MTRRdefType_MSR, 0x800, 0);
|
||||
}
|
||||
|
||||
static int set_flex_ratio_to_tdp_nominal(void)
|
||||
{
|
||||
msr_t flex_ratio, msr;
|
||||
@ -165,10 +144,6 @@ int arch_cpu_init(void)
|
||||
/* This is already done in start.S, but let's do it in C */
|
||||
enable_port80_on_lpc(hose, PCH_LPC_DEV);
|
||||
|
||||
/* already done in car.S */
|
||||
if (false)
|
||||
enable_rom_caching();
|
||||
|
||||
set_spi_speed();
|
||||
|
||||
/*
|
||||
@ -288,7 +263,7 @@ int print_cpuinfo(void)
|
||||
enable_lapic();
|
||||
|
||||
ret = microcode_update_intel();
|
||||
if (ret && ret != -ENOENT && ret != -EEXIST)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable upper 128bytes of CMOS */
|
||||
|
@ -12,9 +12,11 @@
|
||||
#include <fdtdec.h>
|
||||
#include <pci_rom.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/pci.h>
|
||||
#include <asm/arch/pch.h>
|
||||
#include <asm/arch/sandybridge.h>
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
struct gt_powermeter {
|
||||
u16 reg;
|
||||
@ -730,7 +732,11 @@ static int int15_handler(void)
|
||||
int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
|
||||
const void *blob, int node)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO
|
||||
ulong start;
|
||||
#endif
|
||||
void *gtt_bar;
|
||||
ulong base;
|
||||
u32 reg32;
|
||||
int ret;
|
||||
|
||||
@ -739,14 +745,22 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
|
||||
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
||||
pci_write_config32(dev, PCI_COMMAND, reg32);
|
||||
|
||||
/* Use write-combining for the graphics memory, 256MB */
|
||||
base = pci_read_bar32(hose, dev, 2);
|
||||
mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
|
||||
mtrr_commit(true);
|
||||
|
||||
gtt_bar = (void *)pci_read_bar32(pci_bus_to_hose(0), dev, 0);
|
||||
debug("GT bar %p\n", gtt_bar);
|
||||
ret = gma_pm_init_pre_vbios(gtt_bar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_VIDEO
|
||||
start = get_timer(0);
|
||||
ret = pci_run_vga_bios(dev, int15_handler, false);
|
||||
|
||||
debug("BIOS ran in %lums\n", get_timer(start));
|
||||
#endif
|
||||
/* Post VBIOS init */
|
||||
ret = gma_pm_init_post_vbios(gtt_bar, blob, node);
|
||||
if (ret)
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include <libfdt.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/msr-index.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/microcode.h>
|
||||
|
||||
/**
|
||||
* struct microcode_update - standard microcode header from Intel
|
||||
@ -40,8 +42,8 @@ static int microcode_decode_node(const void *blob, int node,
|
||||
update->data = fdt_getprop(blob, node, "data", &update->size);
|
||||
if (!update->data)
|
||||
return -EINVAL;
|
||||
update->data += 48;
|
||||
update->size -= 48;
|
||||
update->data += UCODE_HEADER_LEN;
|
||||
update->size -= UCODE_HEADER_LEN;
|
||||
|
||||
update->header_version = fdtdec_get_int(blob, node,
|
||||
"intel,header-version", 0);
|
||||
@ -71,15 +73,16 @@ static inline uint32_t microcode_read_rev(void)
|
||||
asm volatile (
|
||||
"xorl %%eax, %%eax\n"
|
||||
"xorl %%edx, %%edx\n"
|
||||
"movl $0x8b, %%ecx\n"
|
||||
"movl %2, %%ecx\n"
|
||||
"wrmsr\n"
|
||||
"movl $0x01, %%eax\n"
|
||||
"cpuid\n"
|
||||
"movl $0x8b, %%ecx\n"
|
||||
"movl %2, %%ecx\n"
|
||||
"rdmsr\n"
|
||||
: /* outputs */
|
||||
"=a" (low), "=d" (high)
|
||||
: /* inputs */
|
||||
"i" (MSR_IA32_UCODE_REV)
|
||||
: /* clobbers */
|
||||
"ebx", "ecx"
|
||||
);
|
||||
@ -94,9 +97,9 @@ static void microcode_read_cpu(struct microcode_update *cpu)
|
||||
struct cpuid_result result;
|
||||
uint32_t low, high;
|
||||
|
||||
wrmsr(0x8b, 0, 0);
|
||||
wrmsr(MSR_IA32_UCODE_REV, 0, 0);
|
||||
result = cpuid(1);
|
||||
rdmsr(0x8b, low, cpu->update_revision);
|
||||
rdmsr(MSR_IA32_UCODE_REV, low, cpu->update_revision);
|
||||
x86_model = (result.eax >> 4) & 0x0f;
|
||||
x86_family = (result.eax >> 8) & 0x0f;
|
||||
cpu->processor_signature = result.eax;
|
||||
@ -120,6 +123,7 @@ int microcode_update_intel(void)
|
||||
int count;
|
||||
int node;
|
||||
int ret;
|
||||
int rev;
|
||||
|
||||
microcode_read_cpu(&cpu);
|
||||
node = 0;
|
||||
@ -147,12 +151,16 @@ int microcode_update_intel(void)
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
ret = microcode_read_rev();
|
||||
wrmsr(0x79, (ulong)update.data, 0);
|
||||
wrmsr(MSR_IA32_UCODE_WRITE, (ulong)update.data, 0);
|
||||
rev = microcode_read_rev();
|
||||
debug("microcode: updated to revision 0x%x date=%04x-%02x-%02x\n",
|
||||
microcode_read_rev(), update.date_code & 0xffff,
|
||||
rev, update.date_code & 0xffff,
|
||||
(update.date_code >> 24) & 0xff,
|
||||
(update.date_code >> 16) & 0xff);
|
||||
if (update.update_revision != rev) {
|
||||
printf("Microcode update failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
count++;
|
||||
} while (1);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/pci.h>
|
||||
#include <asm/arch/me.h>
|
||||
#include <asm/arch/pei_data.h>
|
||||
@ -430,6 +431,15 @@ static int sdram_find(pci_dev_t dev)
|
||||
add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28);
|
||||
add_memory_area(info, (4 << 28) + (2 << 20), tseg_base);
|
||||
add_memory_area(info, 1ULL << 32, touud);
|
||||
|
||||
/* Add MTRRs for memory */
|
||||
mtrr_add_request(MTRR_TYPE_WRBACK, 0, 2ULL << 30);
|
||||
mtrr_add_request(MTRR_TYPE_WRBACK, 2ULL << 30, 512 << 20);
|
||||
mtrr_add_request(MTRR_TYPE_WRBACK, 0xaULL << 28, 256 << 20);
|
||||
mtrr_add_request(MTRR_TYPE_UNCACHEABLE, tseg_base, 16 << 20);
|
||||
mtrr_add_request(MTRR_TYPE_UNCACHEABLE, tseg_base + (16 << 20),
|
||||
32 << 20);
|
||||
|
||||
/*
|
||||
* If >= 4GB installed then memory from TOLUD to 4GB
|
||||
* is remapped above TOM, TOUUD will account for both
|
||||
|
81
arch/x86/cpu/mtrr.c
Normal file
81
arch/x86/cpu/mtrr.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Memory Type Range Regsters - these are used to tell the CPU whether
|
||||
* memory is cacheable and if so the cache write mode to use.
|
||||
*
|
||||
* These can speed up booting. See the mtrr command.
|
||||
*
|
||||
* Reference: Intel Architecture Software Developer's Manual, Volume 3:
|
||||
* System Programming
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/mtrr.h>
|
||||
|
||||
/* Prepare to adjust MTRRs */
|
||||
void mtrr_open(struct mtrr_state *state)
|
||||
{
|
||||
state->enable_cache = dcache_status();
|
||||
|
||||
if (state->enable_cache)
|
||||
disable_caches();
|
||||
state->deftype = native_read_msr(MTRR_DEF_TYPE_MSR);
|
||||
wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype & ~MTRR_DEF_TYPE_EN);
|
||||
}
|
||||
|
||||
/* Clean up after adjusting MTRRs, and enable them */
|
||||
void mtrr_close(struct mtrr_state *state)
|
||||
{
|
||||
wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
|
||||
if (state->enable_cache)
|
||||
enable_caches();
|
||||
}
|
||||
|
||||
int mtrr_commit(bool do_caches)
|
||||
{
|
||||
struct mtrr_request *req = gd->arch.mtrr_req;
|
||||
struct mtrr_state state;
|
||||
uint64_t mask;
|
||||
int i;
|
||||
|
||||
mtrr_open(&state);
|
||||
for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) {
|
||||
mask = ~(req->size - 1);
|
||||
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
|
||||
wrmsrl(MTRR_PHYS_BASE_MSR(i), req->start | req->type);
|
||||
wrmsrl(MTRR_PHYS_MASK_MSR(i), mask | MTRR_PHYS_MASK_VALID);
|
||||
}
|
||||
|
||||
/* Clear the ones that are unused */
|
||||
for (; i < MTRR_COUNT; i++)
|
||||
wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
|
||||
mtrr_close(&state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtrr_add_request(int type, uint64_t start, uint64_t size)
|
||||
{
|
||||
struct mtrr_request *req;
|
||||
uint64_t mask;
|
||||
|
||||
if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS)
|
||||
return -ENOSPC;
|
||||
req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++];
|
||||
req->type = type;
|
||||
req->start = start;
|
||||
req->size = size;
|
||||
debug("%d: type=%d, %08llx %08llx\n", gd->arch.mtrr_req_count - 1,
|
||||
req->type, req->start, req->size);
|
||||
mask = ~(req->size - 1);
|
||||
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
|
||||
mask |= MTRR_PHYS_MASK_VALID;
|
||||
debug(" %016llx %016llx\n", req->start | req->type, mask);
|
||||
|
||||
return 0;
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
#include <pci.h>
|
||||
#include <asm/pci.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static struct pci_controller x86_hose;
|
||||
|
||||
int pci_early_init_hose(struct pci_controller **hosep)
|
||||
@ -27,7 +29,8 @@ int pci_early_init_hose(struct pci_controller **hosep)
|
||||
|
||||
board_pci_setup_hose(hose);
|
||||
pci_setup_type1(hose);
|
||||
gd->arch.hose = hose;
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
gd->hose = hose;
|
||||
*hosep = hose;
|
||||
|
||||
return 0;
|
||||
@ -48,7 +51,7 @@ void pci_init_board(void)
|
||||
struct pci_controller *hose = &x86_hose;
|
||||
|
||||
/* Stop using the early hose */
|
||||
gd->arch.hose = NULL;
|
||||
gd->hose = NULL;
|
||||
|
||||
board_pci_setup_hose(hose);
|
||||
pci_setup_type1(hose);
|
||||
@ -61,8 +64,8 @@ void pci_init_board(void)
|
||||
|
||||
static struct pci_controller *get_hose(void)
|
||||
{
|
||||
if (gd->arch.hose)
|
||||
return gd->arch.hose;
|
||||
if (gd->hose)
|
||||
return gd->hose;
|
||||
|
||||
return pci_bus_to_hose(0);
|
||||
}
|
||||
|
@ -231,26 +231,28 @@ u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase)
|
||||
|
||||
u32 fsp_get_usable_lowmem_top(const void *hob_list)
|
||||
{
|
||||
union hob_pointers hob;
|
||||
const struct hob_header *hdr;
|
||||
struct hob_res_desc *res_desc;
|
||||
phys_addr_t phys_start;
|
||||
u32 top;
|
||||
|
||||
/* Get the HOB list for processing */
|
||||
hob.raw = (void *)hob_list;
|
||||
hdr = hob_list;
|
||||
|
||||
/* * Collect memory ranges */
|
||||
top = FSP_LOWMEM_BASE;
|
||||
while (!end_of_hob(hob)) {
|
||||
if (get_hob_type(hob) == HOB_TYPE_RES_DESC) {
|
||||
if (hob.res_desc->type == RES_SYS_MEM) {
|
||||
phys_start = hob.res_desc->phys_start;
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == HOB_TYPE_RES_DESC) {
|
||||
res_desc = (struct hob_res_desc *)hdr;
|
||||
if (res_desc->type == RES_SYS_MEM) {
|
||||
phys_start = res_desc->phys_start;
|
||||
/* Need memory above 1MB to be collected here */
|
||||
if (phys_start >= FSP_LOWMEM_BASE &&
|
||||
phys_start < (phys_addr_t)FSP_HIGHMEM_BASE)
|
||||
top += (u32)(hob.res_desc->len);
|
||||
top += (u32)(res_desc->len);
|
||||
}
|
||||
}
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return top;
|
||||
@ -258,25 +260,27 @@ u32 fsp_get_usable_lowmem_top(const void *hob_list)
|
||||
|
||||
u64 fsp_get_usable_highmem_top(const void *hob_list)
|
||||
{
|
||||
union hob_pointers hob;
|
||||
const struct hob_header *hdr;
|
||||
struct hob_res_desc *res_desc;
|
||||
phys_addr_t phys_start;
|
||||
u64 top;
|
||||
|
||||
/* Get the HOB list for processing */
|
||||
hob.raw = (void *)hob_list;
|
||||
hdr = hob_list;
|
||||
|
||||
/* Collect memory ranges */
|
||||
top = FSP_HIGHMEM_BASE;
|
||||
while (!end_of_hob(hob)) {
|
||||
if (get_hob_type(hob) == HOB_TYPE_RES_DESC) {
|
||||
if (hob.res_desc->type == RES_SYS_MEM) {
|
||||
phys_start = hob.res_desc->phys_start;
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == HOB_TYPE_RES_DESC) {
|
||||
res_desc = (struct hob_res_desc *)hdr;
|
||||
if (res_desc->type == RES_SYS_MEM) {
|
||||
phys_start = res_desc->phys_start;
|
||||
/* Need memory above 1MB to be collected here */
|
||||
if (phys_start >= (phys_addr_t)FSP_HIGHMEM_BASE)
|
||||
top += (u32)(hob.res_desc->len);
|
||||
top += (u32)(res_desc->len);
|
||||
}
|
||||
}
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return top;
|
||||
@ -285,24 +289,26 @@ u64 fsp_get_usable_highmem_top(const void *hob_list)
|
||||
u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len,
|
||||
struct efi_guid *guid)
|
||||
{
|
||||
union hob_pointers hob;
|
||||
const struct hob_header *hdr;
|
||||
struct hob_res_desc *res_desc;
|
||||
|
||||
/* Get the HOB list for processing */
|
||||
hob.raw = (void *)hob_list;
|
||||
hdr = hob_list;
|
||||
|
||||
/* Collect memory ranges */
|
||||
while (!end_of_hob(hob)) {
|
||||
if (get_hob_type(hob) == HOB_TYPE_RES_DESC) {
|
||||
if (hob.res_desc->type == RES_MEM_RESERVED) {
|
||||
if (compare_guid(&hob.res_desc->owner, guid)) {
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == HOB_TYPE_RES_DESC) {
|
||||
res_desc = (struct hob_res_desc *)hdr;
|
||||
if (res_desc->type == RES_MEM_RESERVED) {
|
||||
if (compare_guid(&res_desc->owner, guid)) {
|
||||
if (len)
|
||||
*len = (u32)(hob.res_desc->len);
|
||||
*len = (u32)(res_desc->len);
|
||||
|
||||
return (u64)(hob.res_desc->phys_start);
|
||||
return (u64)(res_desc->phys_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -336,44 +342,45 @@ u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len)
|
||||
return base;
|
||||
}
|
||||
|
||||
void *fsp_get_next_hob(u16 type, const void *hob_list)
|
||||
const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list)
|
||||
{
|
||||
union hob_pointers hob;
|
||||
const struct hob_header *hdr;
|
||||
|
||||
assert(hob_list != NULL);
|
||||
|
||||
hob.raw = (u8 *)hob_list;
|
||||
hdr = hob_list;
|
||||
|
||||
/* Parse the HOB list until end of list or matching type is found */
|
||||
while (!end_of_hob(hob)) {
|
||||
if (get_hob_type(hob) == type)
|
||||
return hob.raw;
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == type)
|
||||
return hdr;
|
||||
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *fsp_get_next_guid_hob(const struct efi_guid *guid, const void *hob_list)
|
||||
const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid,
|
||||
const void *hob_list)
|
||||
{
|
||||
union hob_pointers hob;
|
||||
const struct hob_header *hdr;
|
||||
struct hob_guid *guid_hob;
|
||||
|
||||
hob.raw = (u8 *)hob_list;
|
||||
while ((hob.raw = fsp_get_next_hob(HOB_TYPE_GUID_EXT,
|
||||
hob.raw)) != NULL) {
|
||||
if (compare_guid(guid, &hob.guid->name))
|
||||
hdr = hob_list;
|
||||
while ((hdr = fsp_get_next_hob(HOB_TYPE_GUID_EXT,
|
||||
hdr)) != NULL) {
|
||||
guid_hob = (struct hob_guid *)hdr;
|
||||
if (compare_guid(guid, &(guid_hob->name)))
|
||||
break;
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
return hob.raw;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
void *fsp_get_guid_hob_data(const void *hob_list, u32 *len,
|
||||
struct efi_guid *guid)
|
||||
{
|
||||
u8 *guid_hob;
|
||||
const struct hob_header *guid_hob;
|
||||
|
||||
guid_hob = fsp_get_next_guid_hob(guid, hob_list);
|
||||
if (guid_hob == NULL) {
|
||||
|
@ -14,17 +14,19 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
int dram_init(void)
|
||||
{
|
||||
phys_size_t ram_size = 0;
|
||||
union hob_pointers hob;
|
||||
const struct hob_header *hdr;
|
||||
struct hob_res_desc *res_desc;
|
||||
|
||||
hob.raw = gd->arch.hob_list;
|
||||
while (!end_of_hob(hob)) {
|
||||
if (get_hob_type(hob) == HOB_TYPE_RES_DESC) {
|
||||
if (hob.res_desc->type == RES_SYS_MEM ||
|
||||
hob.res_desc->type == RES_MEM_RESERVED) {
|
||||
ram_size += hob.res_desc->len;
|
||||
hdr = gd->arch.hob_list;
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == HOB_TYPE_RES_DESC) {
|
||||
res_desc = (struct hob_res_desc *)hdr;
|
||||
if (res_desc->type == RES_SYS_MEM ||
|
||||
res_desc->type == RES_MEM_RESERVED) {
|
||||
ram_size += res_desc->len;
|
||||
}
|
||||
}
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
}
|
||||
|
||||
gd->ram_size = ram_size;
|
||||
@ -55,22 +57,23 @@ ulong board_get_usable_ram_top(ulong total_size)
|
||||
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
|
||||
{
|
||||
unsigned num_entries = 0;
|
||||
const struct hob_header *hdr;
|
||||
struct hob_res_desc *res_desc;
|
||||
|
||||
union hob_pointers hob;
|
||||
hdr = gd->arch.hob_list;
|
||||
|
||||
hob.raw = gd->arch.hob_list;
|
||||
while (!end_of_hob(hdr)) {
|
||||
if (hdr->type == HOB_TYPE_RES_DESC) {
|
||||
res_desc = (struct hob_res_desc *)hdr;
|
||||
entries[num_entries].addr = res_desc->phys_start;
|
||||
entries[num_entries].size = res_desc->len;
|
||||
|
||||
while (!end_of_hob(hob)) {
|
||||
if (get_hob_type(hob) == HOB_TYPE_RES_DESC) {
|
||||
entries[num_entries].addr = hob.res_desc->phys_start;
|
||||
entries[num_entries].size = hob.res_desc->len;
|
||||
|
||||
if (hob.res_desc->type == RES_SYS_MEM)
|
||||
if (res_desc->type == RES_SYS_MEM)
|
||||
entries[num_entries].type = E820_RAM;
|
||||
else if (hob.res_desc->type == RES_MEM_RESERVED)
|
||||
else if (res_desc->type == RES_MEM_RESERVED)
|
||||
entries[num_entries].type = E820_RESERVED;
|
||||
}
|
||||
hob.raw = get_next_hob(hob);
|
||||
hdr = get_next_hob(hdr);
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,14 @@ board_init_f_r_trampoline:
|
||||
/* Setup global descriptor table so gd->xyz works */
|
||||
call setup_gdt
|
||||
|
||||
/* Set if we need to disable CAR */
|
||||
.weak car_uninit
|
||||
movl $car_uninit, %eax
|
||||
cmpl $0, %eax
|
||||
jz 1f
|
||||
|
||||
call car_uninit
|
||||
1:
|
||||
/* Re-enter U-Boot by calling board_init_f_r */
|
||||
call board_init_f_r
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
dtb-y += link.dtb \
|
||||
chromebook_link.dtb \
|
||||
alex.dtb \
|
||||
dtb-y += chromebook_link.dtb \
|
||||
crownbay.dtb
|
||||
|
||||
targets += $(dtb-y)
|
||||
|
@ -1,24 +0,0 @@
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "coreboot.dtsi"
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
model = "Google Alex";
|
||||
compatible = "google,alex", "intel,atom-pineview";
|
||||
|
||||
config {
|
||||
silent_console = <0>;
|
||||
};
|
||||
|
||||
gpio: gpio {};
|
||||
|
||||
serial {
|
||||
reg = <0x3f8 8>;
|
||||
clock-frequency = <115200>;
|
||||
};
|
||||
|
||||
chosen { };
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
};
|
@ -1 +0,0 @@
|
||||
link.dts
|
216
arch/x86/dts/chromebook_link.dts
Normal file
216
arch/x86/dts/chromebook_link.dts
Normal file
@ -0,0 +1,216 @@
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
/include/ "serial.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Google Link";
|
||||
compatible = "google,link", "intel,celeron-ivybridge";
|
||||
|
||||
config {
|
||||
silent_console = <0>;
|
||||
};
|
||||
|
||||
gpioa {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0 0x10>;
|
||||
bank-name = "A";
|
||||
};
|
||||
|
||||
gpiob {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x30 0x10>;
|
||||
bank-name = "B";
|
||||
};
|
||||
|
||||
gpioc {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x40 0x10>;
|
||||
bank-name = "C";
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "/serial";
|
||||
};
|
||||
|
||||
spd {
|
||||
compatible = "memory-spd";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
elpida_4Gb_1600_x16 {
|
||||
reg = <0>;
|
||||
data = [92 10 0b 03 04 19 02 02
|
||||
03 52 01 08 0a 00 fe 00
|
||||
69 78 69 3c 69 11 18 81
|
||||
20 08 3c 3c 01 40 83 81
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 0f 11 42 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 02 fe 00
|
||||
11 52 00 00 00 07 7f 37
|
||||
45 42 4a 32 30 55 47 36
|
||||
45 42 55 30 2d 47 4e 2d
|
||||
46 20 30 20 02 fe 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00];
|
||||
};
|
||||
samsung_4Gb_1600_1.35v_x16 {
|
||||
reg = <1>;
|
||||
data = [92 11 0b 03 04 19 02 02
|
||||
03 11 01 08 0a 00 fe 00
|
||||
69 78 69 3c 69 11 18 81
|
||||
f0 0a 3c 3c 01 40 83 01
|
||||
00 80 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 0f 11 02 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 80 ce 01
|
||||
00 00 00 00 00 00 6a 04
|
||||
4d 34 37 31 42 35 36 37
|
||||
34 42 48 30 2d 59 4b 30
|
||||
20 20 00 00 80 ce 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00];
|
||||
};
|
||||
micron_4Gb_1600_1.35v_x16 {
|
||||
reg = <2>;
|
||||
data = [92 11 0b 03 04 19 02 02
|
||||
03 11 01 08 0a 00 fe 00
|
||||
69 78 69 3c 69 11 18 81
|
||||
20 08 3c 3c 01 40 83 05
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 0f 01 02 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 80 2c 00
|
||||
00 00 00 00 00 00 ad 75
|
||||
34 4b 54 46 32 35 36 36
|
||||
34 48 5a 2d 31 47 36 45
|
||||
31 20 45 31 80 2c 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff];
|
||||
};
|
||||
};
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "intel,ich9";
|
||||
spi-flash@0 {
|
||||
reg = <0>;
|
||||
compatible = "winbond,w25q64", "spi-flash";
|
||||
memory-map = <0xff800000 0x00800000>;
|
||||
};
|
||||
};
|
||||
|
||||
pci {
|
||||
sata {
|
||||
compatible = "intel,pantherpoint-ahci";
|
||||
intel,sata-mode = "ahci";
|
||||
intel,sata-port-map = <1>;
|
||||
intel,sata-port0-gen3-tx = <0x00880a7f>;
|
||||
};
|
||||
|
||||
gma {
|
||||
compatible = "intel,gma";
|
||||
intel,dp_hotplug = <0 0 0x06>;
|
||||
intel,panel-port-select = <1>;
|
||||
intel,panel-power-cycle-delay = <6>;
|
||||
intel,panel-power-up-delay = <2000>;
|
||||
intel,panel-power-down-delay = <500>;
|
||||
intel,panel-power-backlight-on-delay = <2000>;
|
||||
intel,panel-power-backlight-off-delay = <2000>;
|
||||
intel,cpu-backlight = <0x00000200>;
|
||||
intel,pch-backlight = <0x04000000>;
|
||||
};
|
||||
|
||||
lpc {
|
||||
compatible = "intel,lpc";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
intel,gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
intel,pirq-routing = <0x8b 0x8a 0x8b 0x8b
|
||||
0x80 0x80 0x80 0x80>;
|
||||
intel,gpi-routing = <0 0 0 0 0 0 0 2
|
||||
1 0 0 0 0 0 0 0>;
|
||||
/* Enable EC SMI source */
|
||||
intel,alt-gp-smi-enable = <0x0100>;
|
||||
|
||||
cros-ec@200 {
|
||||
compatible = "google,cros-ec";
|
||||
reg = <0x204 1 0x200 1 0x880 0x80>;
|
||||
|
||||
/* Describes the flash memory within the EC */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
flash@8000000 {
|
||||
reg = <0x08000000 0x20000>;
|
||||
erase-value = <0xff>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
microcode {
|
||||
update@0 {
|
||||
#include "microcode/m12306a9_0000001b.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = "/serial";
|
||||
};
|
||||
|
||||
serial {
|
||||
compatible = "x86-uart";
|
||||
reg = <0x3f8 0x10>;
|
||||
reg-shift = <0>;
|
||||
io-mapped = <1>;
|
||||
multiplier = <1>;
|
||||
baudrate = <115200>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
@ -6,11 +6,10 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "coreboot.dtsi"
|
||||
/include/ "skeleton.dtsi"
|
||||
/include/ "serial.dtsi"
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
model = "Intel Crown Bay";
|
||||
compatible = "intel,crownbay", "intel,queensbay";
|
||||
|
||||
@ -32,14 +31,18 @@
|
||||
bank-name = "B";
|
||||
};
|
||||
|
||||
serial {
|
||||
reg = <0x3f8 8>;
|
||||
clock-frequency = <115200>;
|
||||
chosen {
|
||||
/*
|
||||
* By default the legacy superio serial port is used as the
|
||||
* U-Boot serial console. If we want to use UART from Topcliff
|
||||
* PCH as the console, change this property to &pciuart#.
|
||||
*
|
||||
* For example, stdout-path = &pciuart0 will use the first
|
||||
* UART on Topcliff PCH.
|
||||
*/
|
||||
stdout-path = "/serial";
|
||||
};
|
||||
|
||||
chosen { };
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@ -57,4 +60,77 @@
|
||||
};
|
||||
};
|
||||
|
||||
pci {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "intel,pci";
|
||||
device_type = "pci";
|
||||
|
||||
pcie@17,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "intel,pci";
|
||||
device_type = "pci";
|
||||
|
||||
topcliff@0,0 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
compatible = "intel,pci";
|
||||
device_type = "pci";
|
||||
|
||||
pciuart0: uart@a,1 {
|
||||
compatible = "pci8086,8811.00",
|
||||
"pci8086,8811",
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
reg = <0x00025100 0x0 0x0 0x0 0x0
|
||||
0x01025110 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
clock-frequency = <1843200>;
|
||||
current-speed = <115200>;
|
||||
};
|
||||
|
||||
pciuart1: uart@a,2 {
|
||||
compatible = "pci8086,8812.00",
|
||||
"pci8086,8812",
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
reg = <0x00025200 0x0 0x0 0x0 0x0
|
||||
0x01025210 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
clock-frequency = <1843200>;
|
||||
current-speed = <115200>;
|
||||
};
|
||||
|
||||
pciuart2: uart@a,3 {
|
||||
compatible = "pci8086,8813.00",
|
||||
"pci8086,8813",
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
reg = <0x00025300 0x0 0x0 0x0 0x0
|
||||
0x01025310 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
clock-frequency = <1843200>;
|
||||
current-speed = <115200>;
|
||||
};
|
||||
|
||||
pciuart3: uart@a,4 {
|
||||
compatible = "pci8086,8814.00",
|
||||
"pci8086,8814",
|
||||
"pciclass,070002",
|
||||
"pciclass,0700",
|
||||
"x86-uart";
|
||||
reg = <0x00025400 0x0 0x0 0x0 0x0
|
||||
0x01025410 0x0 0x0 0x0 0x0>;
|
||||
reg-shift = <0>;
|
||||
clock-frequency = <1843200>;
|
||||
current-speed = <115200>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -1,224 +0,0 @@
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "coreboot.dtsi"
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
model = "Google Link";
|
||||
compatible = "google,link", "intel,celeron-ivybridge";
|
||||
|
||||
config {
|
||||
silent_console = <0>;
|
||||
};
|
||||
|
||||
gpioa {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0 0x10>;
|
||||
bank-name = "A";
|
||||
};
|
||||
|
||||
gpiob {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x30 0x10>;
|
||||
bank-name = "B";
|
||||
};
|
||||
|
||||
gpioc {
|
||||
compatible = "intel,ich6-gpio";
|
||||
u-boot,dm-pre-reloc;
|
||||
reg = <0x40 0x10>;
|
||||
bank-name = "C";
|
||||
};
|
||||
|
||||
serial {
|
||||
reg = <0x3f8 8>;
|
||||
clock-frequency = <115200>;
|
||||
};
|
||||
|
||||
chosen { };
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
|
||||
spd {
|
||||
compatible = "memory-spd";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
elpida_4Gb_1600_x16 {
|
||||
reg = <0>;
|
||||
data = [92 10 0b 03 04 19 02 02
|
||||
03 52 01 08 0a 00 fe 00
|
||||
69 78 69 3c 69 11 18 81
|
||||
20 08 3c 3c 01 40 83 81
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 0f 11 42 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 02 fe 00
|
||||
11 52 00 00 00 07 7f 37
|
||||
45 42 4a 32 30 55 47 36
|
||||
45 42 55 30 2d 47 4e 2d
|
||||
46 20 30 20 02 fe 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00];
|
||||
};
|
||||
samsung_4Gb_1600_1.35v_x16 {
|
||||
reg = <1>;
|
||||
data = [92 11 0b 03 04 19 02 02
|
||||
03 11 01 08 0a 00 fe 00
|
||||
69 78 69 3c 69 11 18 81
|
||||
f0 0a 3c 3c 01 40 83 01
|
||||
00 80 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 0f 11 02 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 80 ce 01
|
||||
00 00 00 00 00 00 6a 04
|
||||
4d 34 37 31 42 35 36 37
|
||||
34 42 48 30 2d 59 4b 30
|
||||
20 20 00 00 80 ce 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00];
|
||||
};
|
||||
micron_4Gb_1600_1.35v_x16 {
|
||||
reg = <2>;
|
||||
data = [92 11 0b 03 04 19 02 02
|
||||
03 11 01 08 0a 00 fe 00
|
||||
69 78 69 3c 69 11 18 81
|
||||
20 08 3c 3c 01 40 83 05
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 0f 01 02 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 80 2c 00
|
||||
00 00 00 00 00 00 ad 75
|
||||
34 4b 54 46 32 35 36 36
|
||||
34 48 5a 2d 31 47 36 45
|
||||
31 20 45 31 80 2c 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff
|
||||
ff ff ff ff ff ff ff ff];
|
||||
};
|
||||
};
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "intel,ich9";
|
||||
spi-flash@0 {
|
||||
reg = <0>;
|
||||
compatible = "winbond,w25q64", "spi-flash";
|
||||
memory-map = <0xff800000 0x00800000>;
|
||||
};
|
||||
};
|
||||
|
||||
pci {
|
||||
sata {
|
||||
compatible = "intel,pantherpoint-ahci";
|
||||
intel,sata-mode = "ahci";
|
||||
intel,sata-port-map = <1>;
|
||||
intel,sata-port0-gen3-tx = <0x00880a7f>;
|
||||
};
|
||||
|
||||
gma {
|
||||
compatible = "intel,gma";
|
||||
intel,dp_hotplug = <0 0 0x06>;
|
||||
intel,panel-port-select = <1>;
|
||||
intel,panel-power-cycle-delay = <6>;
|
||||
intel,panel-power-up-delay = <2000>;
|
||||
intel,panel-power-down-delay = <500>;
|
||||
intel,panel-power-backlight-on-delay = <2000>;
|
||||
intel,panel-power-backlight-off-delay = <2000>;
|
||||
intel,cpu-backlight = <0x00000200>;
|
||||
intel,pch-backlight = <0x04000000>;
|
||||
};
|
||||
|
||||
lpc {
|
||||
compatible = "intel,lpc";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
intel,gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
intel,pirq-routing = <0x8b 0x8a 0x8b 0x8b
|
||||
0x80 0x80 0x80 0x80>;
|
||||
intel,gpi-routing = <0 0 0 0 0 0 0 2
|
||||
1 0 0 0 0 0 0 0>;
|
||||
/* Enable EC SMI source */
|
||||
intel,alt-gp-smi-enable = <0x0100>;
|
||||
|
||||
cros-ec@200 {
|
||||
compatible = "google,cros-ec";
|
||||
reg = <0x204 1 0x200 1 0x880 0x80>;
|
||||
|
||||
/* Describes the flash memory within the EC */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
flash@8000000 {
|
||||
reg = <0x08000000 0x20000>;
|
||||
erase-value = <0xff>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
microcode {
|
||||
update@0 {
|
||||
#include "microcode/m12206a7_00000029.dtsi"
|
||||
};
|
||||
update@1 {
|
||||
#include "microcode/m12306a9_0000001b.dtsi"
|
||||
};
|
||||
};
|
||||
|
||||
};
|
9
arch/x86/dts/serial.dtsi
Normal file
9
arch/x86/dts/serial.dtsi
Normal file
@ -0,0 +1,9 @@
|
||||
/ {
|
||||
serial {
|
||||
compatible = "x86-uart";
|
||||
reg = <0x3f8 8>;
|
||||
reg-shift = <0>;
|
||||
clock-frequency = <1843200>;
|
||||
current-speed = <115200>;
|
||||
};
|
||||
};
|
@ -7,6 +7,11 @@
|
||||
#ifndef __ASM_ARCH_MICROCODE_H
|
||||
#define __ASM_ARCH_MICROCODE_H
|
||||
|
||||
/* Length of the public header on Intel microcode blobs */
|
||||
#define UCODE_HEADER_LEN 0x30
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/**
|
||||
* microcode_update_intel() - Apply microcode updates
|
||||
*
|
||||
@ -16,5 +21,6 @@
|
||||
* not updates were found, -EINVAL if an update was invalid
|
||||
*/
|
||||
int microcode_update_intel(void);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
@ -182,58 +182,19 @@ struct hob_guid {
|
||||
/* GUID specific data goes here */
|
||||
};
|
||||
|
||||
/* Union of all the possible HOB Types */
|
||||
union hob_pointers {
|
||||
struct hob_header *hdr;
|
||||
struct hob_mem_alloc *mem_alloc;
|
||||
struct hob_res_desc *res_desc;
|
||||
struct hob_guid *guid;
|
||||
u8 *raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* get_hob_type() - return the type of a HOB
|
||||
*
|
||||
* This macro returns the type field from the HOB header for the
|
||||
* HOB specified by hob.
|
||||
*
|
||||
* @hob: A pointer to a HOB.
|
||||
*
|
||||
* @return: HOB type.
|
||||
*/
|
||||
static inline u16 get_hob_type(union hob_pointers hob)
|
||||
{
|
||||
return hob.hdr->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_hob_length() - return the length, in bytes, of a HOB
|
||||
*
|
||||
* This macro returns the len field from the HOB header for the
|
||||
* HOB specified by hob.
|
||||
*
|
||||
* @hob: A pointer to a HOB.
|
||||
*
|
||||
* @return: HOB length.
|
||||
*/
|
||||
static inline u16 get_hob_length(union hob_pointers hob)
|
||||
{
|
||||
return hob.hdr->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_next_hob() - return a pointer to the next HOB in the HOB list
|
||||
*
|
||||
* This macro returns a pointer to HOB that follows the HOB specified by hob
|
||||
* in the HOB List.
|
||||
*
|
||||
* @hob: A pointer to a HOB.
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: A pointer to the next HOB in the HOB list.
|
||||
*/
|
||||
static inline void *get_next_hob(union hob_pointers hob)
|
||||
static inline const struct hob_header *get_next_hob(const struct hob_header *hdr)
|
||||
{
|
||||
return (void *)(*(u8 **)&(hob) + get_hob_length(hob));
|
||||
return (const struct hob_header *)((u32)hdr + hdr->len);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,14 +204,14 @@ static inline void *get_next_hob(union hob_pointers hob)
|
||||
* HOB list. If hob is last HOB in the HOB list, then true is returned.
|
||||
* Otherwise, false is returned.
|
||||
*
|
||||
* @hob: A pointer to a HOB.
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @retval true: The HOB specified by hob is the last HOB in the HOB list.
|
||||
* @retval false: The HOB specified by hob is not the last HOB in the HOB list.
|
||||
* @retval true: The HOB specified by hdr is the last HOB in the HOB list.
|
||||
* @retval false: The HOB specified by hdr is not the last HOB in the HOB list.
|
||||
*/
|
||||
static inline bool end_of_hob(union hob_pointers hob)
|
||||
static inline bool end_of_hob(const struct hob_header *hdr)
|
||||
{
|
||||
return get_hob_type(hob) == HOB_TYPE_EOH;
|
||||
return hdr->type == HOB_TYPE_EOH;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,13 +221,13 @@ static inline bool end_of_hob(union hob_pointers hob)
|
||||
* This macro returns a pointer to the data buffer in a HOB specified by hob.
|
||||
* hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT.
|
||||
*
|
||||
* @hob: A pointer to a HOB.
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: A pointer to the data buffer in a HOB.
|
||||
*/
|
||||
static inline void *get_guid_hob_data(u8 *hob)
|
||||
static inline void *get_guid_hob_data(const struct hob_header *hdr)
|
||||
{
|
||||
return (void *)(hob + sizeof(struct hob_guid));
|
||||
return (void *)((u32)hdr + sizeof(struct hob_guid));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -276,14 +237,13 @@ static inline void *get_guid_hob_data(u8 *hob)
|
||||
* This macro returns the size, in bytes, of the data buffer in a HOB
|
||||
* specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT.
|
||||
*
|
||||
* @hob: A pointer to a HOB.
|
||||
* @hdr: A pointer to a HOB.
|
||||
*
|
||||
* @return: The size of the data buffer.
|
||||
*/
|
||||
static inline u16 get_guid_hob_data_size(u8 *hob)
|
||||
static inline u16 get_guid_hob_data_size(const struct hob_header *hdr)
|
||||
{
|
||||
union hob_pointers hob_p = *(union hob_pointers *)hob;
|
||||
return get_hob_length(hob_p) - sizeof(struct hob_guid);
|
||||
return hdr->len - sizeof(struct hob_guid);
|
||||
}
|
||||
|
||||
/* FSP specific GUID HOB definitions */
|
||||
|
@ -145,7 +145,7 @@ u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len);
|
||||
*
|
||||
* @retval: A HOB object with matching type; Otherwise NULL.
|
||||
*/
|
||||
void *fsp_get_next_hob(u16 type, const void *hob_list);
|
||||
const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list);
|
||||
|
||||
/**
|
||||
* Returns the next instance of the matched GUID HOB from the starting HOB.
|
||||
@ -155,7 +155,8 @@ void *fsp_get_next_hob(u16 type, const void *hob_list);
|
||||
*
|
||||
* @retval: A HOB object with matching GUID; Otherwise NULL.
|
||||
*/
|
||||
void *fsp_get_next_guid_hob(const struct efi_guid *guid, const void *hob_list);
|
||||
const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid,
|
||||
const void *hob_list);
|
||||
|
||||
/**
|
||||
* This function retrieves a GUID HOB data buffer and size.
|
||||
|
@ -29,6 +29,19 @@ struct memory_info {
|
||||
struct memory_area area[CONFIG_NR_DRAM_BANKS];
|
||||
};
|
||||
|
||||
#define MAX_MTRR_REQUESTS 8
|
||||
|
||||
/**
|
||||
* A request for a memory region to be set up in a particular way. These
|
||||
* requests are processed before board_init_r() is called. They are generally
|
||||
* optional and can be ignored with some performance impact.
|
||||
*/
|
||||
struct mtrr_request {
|
||||
int type; /* MTRR_TYPE_... */
|
||||
uint64_t start;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
/* Architecture-specific global data */
|
||||
struct arch_global_data {
|
||||
struct global_data *gd_addr; /* Location of Global Data */
|
||||
@ -43,13 +56,14 @@ struct arch_global_data {
|
||||
uint32_t tsc_mhz; /* TSC frequency in MHz */
|
||||
void *new_fdt; /* Relocated FDT */
|
||||
uint32_t bist; /* Built-in self test value */
|
||||
struct pci_controller *hose; /* PCI hose for early use */
|
||||
enum pei_boot_mode_t pei_boot_mode;
|
||||
const struct pch_gpio_map *gpio_map; /* board GPIO map */
|
||||
struct memory_info meminfo; /* Memory information */
|
||||
#ifdef CONFIG_HAVE_FSP
|
||||
void *hob_list; /* FSP HOB list */
|
||||
#endif
|
||||
struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS];
|
||||
int mtrr_req_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -9,99 +9,86 @@
|
||||
#ifndef _ASM_MTRR_H
|
||||
#define _ASM_MTRR_H
|
||||
|
||||
/* These are the region types */
|
||||
#define MTRR_TYPE_UNCACHEABLE 0
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
/*#define MTRR_TYPE_ 2*/
|
||||
/*#define MTRR_TYPE_ 3*/
|
||||
#define MTRR_TYPE_WRTHROUGH 4
|
||||
#define MTRR_TYPE_WRPROT 5
|
||||
#define MTRR_TYPE_WRBACK 6
|
||||
#define MTRR_NUM_TYPES 7
|
||||
/* MTRR region types */
|
||||
#define MTRR_TYPE_UNCACHEABLE 0
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
#define MTRR_TYPE_WRTHROUGH 4
|
||||
#define MTRR_TYPE_WRPROT 5
|
||||
#define MTRR_TYPE_WRBACK 6
|
||||
|
||||
#define MTRRcap_MSR 0x0fe
|
||||
#define MTRRdefType_MSR 0x2ff
|
||||
#define MTRR_TYPE_COUNT 7
|
||||
|
||||
#define MTRRdefTypeEn (1 << 11)
|
||||
#define MTRRdefTypeFixEn (1 << 10)
|
||||
#define MTRR_CAP_MSR 0x0fe
|
||||
#define MTRR_DEF_TYPE_MSR 0x2ff
|
||||
|
||||
#define SMRRphysBase_MSR 0x1f2
|
||||
#define SMRRphysMask_MSR 0x1f3
|
||||
#define MTRR_DEF_TYPE_EN (1 << 11)
|
||||
#define MTRR_DEF_TYPE_FIX_EN (1 << 10)
|
||||
|
||||
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
#define MTRRphysMaskValid (1 << 11)
|
||||
#define MTRR_PHYS_MASK_VALID (1 << 11)
|
||||
|
||||
#define NUM_FIXED_RANGES 88
|
||||
#define RANGES_PER_FIXED_MTRR 8
|
||||
#define MTRRfix64K_00000_MSR 0x250
|
||||
#define MTRRfix16K_80000_MSR 0x258
|
||||
#define MTRRfix16K_A0000_MSR 0x259
|
||||
#define MTRRfix4K_C0000_MSR 0x268
|
||||
#define MTRRfix4K_C8000_MSR 0x269
|
||||
#define MTRRfix4K_D0000_MSR 0x26a
|
||||
#define MTRRfix4K_D8000_MSR 0x26b
|
||||
#define MTRRfix4K_E0000_MSR 0x26c
|
||||
#define MTRRfix4K_E8000_MSR 0x26d
|
||||
#define MTRRfix4K_F0000_MSR 0x26e
|
||||
#define MTRRfix4K_F8000_MSR 0x26f
|
||||
#define MTRR_BASE_TYPE_MASK 0x7
|
||||
|
||||
/* Number of MTRRs supported */
|
||||
#define MTRR_COUNT 8
|
||||
|
||||
#if !defined(__ASSEMBLER__)
|
||||
|
||||
/*
|
||||
* The MTRR code has some side effects that the callers should be aware for.
|
||||
* 1. The call sequence matters. x86_setup_mtrrs() calls
|
||||
* x86_setup_fixed_mtrrs_no_enable() then enable_fixed_mtrrs() (equivalent
|
||||
* of x86_setup_fixed_mtrrs()) then x86_setup_var_mtrrs(). If the callers
|
||||
* want to call the components of x86_setup_mtrrs() because of other
|
||||
* rquirements the ordering should still preserved.
|
||||
* 2. enable_fixed_mtrr() will enable both variable and fixed MTRRs because
|
||||
* of the nature of the global MTRR enable flag. Therefore, all direct
|
||||
* or indirect callers of enable_fixed_mtrr() should ensure that the
|
||||
* variable MTRR MSRs do not contain bad ranges.
|
||||
* 3. If CONFIG_CACHE_ROM is selected an MTRR is allocated for enabling
|
||||
* the caching of the ROM. However, it is set to uncacheable (UC). It
|
||||
* is the responsiblity of the caller to enable it by calling
|
||||
* x86_mtrr_enable_rom_caching().
|
||||
/**
|
||||
* Information about the previous MTRR state, set up by mtrr_open()
|
||||
*
|
||||
* @deftype: Previous value of MTRR_DEF_TYPE_MSR
|
||||
* @enable_cache: true if cache was enabled
|
||||
*/
|
||||
void x86_setup_mtrrs(void);
|
||||
/*
|
||||
* x86_setup_var_mtrrs() parameters:
|
||||
* address_bits - number of physical address bits supported by cpu
|
||||
* above4gb - 2 means dynamically detect number of variable MTRRs available.
|
||||
* non-zero means handle memory ranges above 4GiB.
|
||||
* 0 means ignore memory ranges above 4GiB
|
||||
struct mtrr_state {
|
||||
uint64_t deftype;
|
||||
bool enable_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
* mtrr_open() - Prepare to adjust MTRRs
|
||||
*
|
||||
* Use mtrr_open() passing in a structure - this function will init it. Then
|
||||
* when done, pass the same structure to mtrr_close() to re-enable MTRRs and
|
||||
* possibly the cache.
|
||||
*
|
||||
* @state: Empty structure to pass in to hold settings
|
||||
*/
|
||||
void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb);
|
||||
void enable_fixed_mtrr(void);
|
||||
void x86_setup_fixed_mtrrs(void);
|
||||
/* Set up fixed MTRRs but do not enable them. */
|
||||
void x86_setup_fixed_mtrrs_no_enable(void);
|
||||
int x86_mtrr_check(void);
|
||||
/* ROM caching can be used after variable MTRRs are set up. Beware that
|
||||
* enabling CONFIG_CACHE_ROM will eat through quite a few MTRRs based on
|
||||
* one's IO hole size and WRCOMB resources. Be sure to check the console
|
||||
* log when enabling CONFIG_CACHE_ROM or adding WRCOMB resources. Beware that
|
||||
* on CPUs with core-scoped MTRR registers such as hyperthreaded CPUs the
|
||||
* rom caching will be disabled if all threads run the MTRR code. Therefore,
|
||||
* one needs to call x86_mtrr_enable_rom_caching() after all threads of the
|
||||
* same core have run the MTRR code. */
|
||||
#if CONFIG_CACHE_ROM
|
||||
void x86_mtrr_enable_rom_caching(void);
|
||||
void x86_mtrr_disable_rom_caching(void);
|
||||
/* Return the variable range MTRR index of the ROM cache. */
|
||||
long x86_mtrr_rom_cache_var_index(void);
|
||||
#else
|
||||
static inline void x86_mtrr_enable_rom_caching(void) {}
|
||||
static inline void x86_mtrr_disable_rom_caching(void) {}
|
||||
static inline long x86_mtrr_rom_cache_var_index(void) { return -1; }
|
||||
#endif /* CONFIG_CACHE_ROM */
|
||||
void mtrr_open(struct mtrr_state *state);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* mtrr_open() - Clean up after adjusting MTRRs, and enable them
|
||||
*
|
||||
* This uses the structure containing information returned from mtrr_open().
|
||||
*
|
||||
* @state: Structure from mtrr_open()
|
||||
*/
|
||||
/* */
|
||||
void mtrr_close(struct mtrr_state *state);
|
||||
|
||||
/**
|
||||
* mtrr_add_request() - Add a new MTRR request
|
||||
*
|
||||
* This adds a request for a memory region to be set up in a particular way.
|
||||
*
|
||||
* @type: Requested type (MTRR_TYPE_)
|
||||
* @start: Start address
|
||||
* @size: Size
|
||||
*/
|
||||
int mtrr_add_request(int type, uint64_t start, uint64_t size);
|
||||
|
||||
/**
|
||||
* mtrr_commit() - set up the MTRR registers based on current requests
|
||||
*
|
||||
* This sets up MTRRs for the available DRAM and the requests received so far.
|
||||
* It must be called with caches disabled.
|
||||
*
|
||||
* @do_caches: true if caches are currently on
|
||||
*/
|
||||
int mtrr_commit(bool do_caches);
|
||||
|
||||
#if !defined(CONFIG_RAMTOP)
|
||||
# error "CONFIG_RAMTOP not defined"
|
||||
#endif
|
||||
|
||||
#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
|
||||
@ -114,8 +101,4 @@ static inline long x86_mtrr_rom_cache_var_index(void) { return -1; }
|
||||
|
||||
#define CACHE_ROM_BASE (((1 << 20) - (CONFIG_CACHE_ROM_SIZE >> 12)) << 12)
|
||||
|
||||
#if (CONFIG_RAMTOP & (CONFIG_RAMTOP - 1)) != 0
|
||||
# error "CONFIG_RAMTOP must be a power of 2"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@ void board_pci_setup_hose(struct pci_controller *hose);
|
||||
* pci_early_init_hose() - Set up PCI host before relocation
|
||||
*
|
||||
* This allocates memory for, sets up and returns the PCI hose. It can be
|
||||
* called before relocation. The hose will be stored in gd->arch.hose for
|
||||
* called before relocation. The hose will be stored in gd->hose for
|
||||
* later use, but will become invalid one DRAM is available.
|
||||
*/
|
||||
int pci_early_init_hose(struct pci_controller **hosep);
|
||||
|
@ -14,6 +14,7 @@ obj-$(CONFIG_HAVE_FSP) += cmd_hob.o
|
||||
obj-y += gcc.o
|
||||
obj-y += init_helpers.o
|
||||
obj-y += interrupts.o
|
||||
obj-y += cmd_mtrr.o
|
||||
obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
|
||||
obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o
|
||||
obj-$(CONFIG_PCI) += pci_type1.o
|
||||
|
@ -207,12 +207,14 @@ static u8 vbe_get_mode_info(struct vbe_mode_info *mi)
|
||||
|
||||
static u8 vbe_set_mode(struct vbe_mode_info *mi)
|
||||
{
|
||||
debug("VBE: Setting VESA mode %#04x\n", mi->video_mode);
|
||||
int video_mode = mi->video_mode;
|
||||
|
||||
debug("VBE: Setting VESA mode %#04x\n", video_mode);
|
||||
/* request linear framebuffer mode */
|
||||
mi->video_mode |= (1 << 14);
|
||||
/* request clearing of framebuffer */
|
||||
mi->video_mode &= ~(1 << 15);
|
||||
realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode,
|
||||
video_mode |= (1 << 14);
|
||||
/* don't clear the framebuffer, we do that later */
|
||||
video_mode |= (1 << 15);
|
||||
realmode_interrupt(0x10, VESA_SET_MODE, video_mode,
|
||||
0x0000, 0x0000, 0x0000, 0x0000);
|
||||
|
||||
return 0;
|
||||
@ -236,6 +238,7 @@ static void vbe_set_graphics(int vesa_mode, struct vbe_mode_info *mode_info)
|
||||
return;
|
||||
}
|
||||
|
||||
mode_info->video_mode &= 0x3ff;
|
||||
vbe_set_mode(mode_info);
|
||||
}
|
||||
|
||||
@ -262,7 +265,6 @@ void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode,
|
||||
/* Make sure the code is placed. */
|
||||
setup_realmode_code();
|
||||
|
||||
disable_caches();
|
||||
debug("Calling Option ROM at %lx, pci device %#x...", addr, num_dev);
|
||||
|
||||
/* Option ROM entry point is at OPROM start + 3 */
|
||||
|
@ -28,20 +28,20 @@ static char *hob_type[] = {
|
||||
|
||||
int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
union hob_pointers hob;
|
||||
u16 type;
|
||||
const struct hob_header *hdr;
|
||||
uint type;
|
||||
char *desc;
|
||||
int i = 0;
|
||||
|
||||
hob.raw = (u8 *)gd->arch.hob_list;
|
||||
hdr = gd->arch.hob_list;
|
||||
|
||||
printf("HOB list address: 0x%08x\n\n", (unsigned int)hob.raw);
|
||||
printf("HOB list address: 0x%08x\n\n", (unsigned int)hdr);
|
||||
|
||||
printf("No. | Address | Type | Length in Bytes\n");
|
||||
printf("----|----------|---------------------|----------------\n");
|
||||
while (!end_of_hob(hob)) {
|
||||
printf("%-3d | %08x | ", i, (unsigned int)hob.raw);
|
||||
type = get_hob_type(hob);
|
||||
while (!end_of_hob(hdr)) {
|
||||
printf("%-3d | %08x | ", i, (unsigned int)hdr);
|
||||
type = hdr->type;
|
||||
if (type == HOB_TYPE_UNUSED)
|
||||
desc = "*Unused*";
|
||||
else if (type == HOB_TYPE_EOH)
|
||||
@ -50,8 +50,8 @@ int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
desc = hob_type[type];
|
||||
else
|
||||
desc = "*Invalid Type*";
|
||||
printf("%-19s | %-15d\n", desc, get_hob_length(hob));
|
||||
hob.raw = get_next_hob(hob);
|
||||
printf("%-19s | %-15d\n", desc, hdr->len);
|
||||
hdr = get_next_hob(hdr);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
138
arch/x86/lib/cmd_mtrr.c
Normal file
138
arch/x86/lib/cmd_mtrr.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/mtrr.h>
|
||||
|
||||
static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
|
||||
"Uncacheable",
|
||||
"Combine",
|
||||
"2",
|
||||
"3",
|
||||
"Through",
|
||||
"Protect",
|
||||
"Back",
|
||||
};
|
||||
|
||||
static int do_mtrr_list(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Reg Valid Write-type %-16s %-16s %-16s\n", "Base ||",
|
||||
"Mask ||", "Size ||");
|
||||
for (i = 0; i < MTRR_COUNT; i++) {
|
||||
const char *type = "Invalid";
|
||||
uint64_t base, mask, size;
|
||||
bool valid;
|
||||
|
||||
base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
|
||||
mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
|
||||
size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
|
||||
size |= (1 << 12) - 1;
|
||||
size += 1;
|
||||
valid = mask & MTRR_PHYS_MASK_VALID;
|
||||
type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK];
|
||||
printf("%d %-5s %-12s %016llx %016llx %016llx\n", i,
|
||||
valid ? "Y" : "N", type, base, mask, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_mtrr_set(uint reg, int argc, char * const argv[])
|
||||
{
|
||||
const char *typename = argv[0];
|
||||
struct mtrr_state state;
|
||||
uint32_t start, size;
|
||||
uint64_t base, mask;
|
||||
int i, type = -1;
|
||||
bool valid;
|
||||
|
||||
if (argc < 3)
|
||||
return CMD_RET_USAGE;
|
||||
for (i = 0; i < MTRR_TYPE_COUNT; i++) {
|
||||
if (*typename == *mtrr_type_name[i])
|
||||
type = i;
|
||||
}
|
||||
if (type == -1) {
|
||||
printf("Invalid type name %s\n", typename);
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
start = simple_strtoul(argv[1], NULL, 16);
|
||||
size = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
base = start | type;
|
||||
valid = native_read_msr(MTRR_PHYS_MASK_MSR(reg)) & MTRR_PHYS_MASK_VALID;
|
||||
mask = ~((uint64_t)size - 1);
|
||||
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
|
||||
if (valid)
|
||||
mask |= MTRR_PHYS_MASK_VALID;
|
||||
|
||||
printf("base=%llx, mask=%llx\n", base, mask);
|
||||
mtrr_open(&state);
|
||||
wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
|
||||
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
|
||||
mtrr_close(&state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtrr_set_valid(int reg, bool valid)
|
||||
{
|
||||
struct mtrr_state state;
|
||||
uint64_t mask;
|
||||
|
||||
mtrr_open(&state);
|
||||
mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
|
||||
if (valid)
|
||||
mask |= MTRR_PHYS_MASK_VALID;
|
||||
else
|
||||
mask &= ~MTRR_PHYS_MASK_VALID;
|
||||
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
|
||||
mtrr_close(&state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_mtrr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
const char *cmd;
|
||||
uint reg;
|
||||
|
||||
cmd = argv[1];
|
||||
if (argc < 2 || *cmd == 'l')
|
||||
return do_mtrr_list();
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if (argc <= 0)
|
||||
return CMD_RET_USAGE;
|
||||
reg = simple_strtoul(argv[0], NULL, 16);
|
||||
if (reg >= MTRR_COUNT) {
|
||||
printf("Invalid register number\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
if (*cmd == 'e')
|
||||
return mtrr_set_valid(reg, true);
|
||||
else if (*cmd == 'd')
|
||||
return mtrr_set_valid(reg, false);
|
||||
else if (*cmd == 's')
|
||||
return do_mtrr_set(reg, argc - 1, argv + 1);
|
||||
else
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
mtrr, 6, 1, do_mtrr,
|
||||
"Use x86 memory type range registers (32-bit only)",
|
||||
"[list] - list current registers\n"
|
||||
"set <reg> <type> <start> <size> - set a register\n"
|
||||
"\t<type> is Uncacheable, Combine, Through, Protect, Back\n"
|
||||
"disable <reg> - disable a register\n"
|
||||
"ensable <reg> - enable a register"
|
||||
);
|
@ -7,6 +7,7 @@
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <spi.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@ -66,6 +67,13 @@ int calculate_relocation_address(void)
|
||||
|
||||
int init_cache_f_r(void)
|
||||
{
|
||||
#if defined(CONFIG_X86_RESET_VECTOR) & !defined(CONFIG_HAVE_FSP)
|
||||
int ret;
|
||||
|
||||
ret = mtrr_commit(false);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
/* Initialise the CPU cache(s) */
|
||||
return init_cache();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ static int match_cpu(u8 family, u8 model)
|
||||
*
|
||||
* Returns the calibration value or 0 if MSR calibration failed.
|
||||
*/
|
||||
static unsigned long try_msr_calibrate_tsc(void)
|
||||
static unsigned long __maybe_unused try_msr_calibrate_tsc(void)
|
||||
{
|
||||
u32 lo, hi, ratio, freq_id, freq;
|
||||
unsigned long res;
|
||||
@ -199,7 +199,7 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp,
|
||||
#define MAX_QUICK_PIT_MS 50
|
||||
#define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
|
||||
|
||||
static unsigned long quick_pit_calibrate(void)
|
||||
static unsigned long __maybe_unused quick_pit_calibrate(void)
|
||||
{
|
||||
int i;
|
||||
u64 tsc, delta;
|
||||
@ -306,6 +306,9 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
|
||||
if (gd->arch.tsc_mhz)
|
||||
return gd->arch.tsc_mhz;
|
||||
|
||||
#ifdef CONFIG_TSC_CALIBRATION_BYPASS
|
||||
fast_calibrate = CONFIG_TSC_FREQ_IN_MHZ;
|
||||
#else
|
||||
fast_calibrate = try_msr_calibrate_tsc();
|
||||
if (!fast_calibrate) {
|
||||
|
||||
@ -313,6 +316,7 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
|
||||
if (!fast_calibrate)
|
||||
panic("TSC frequency is ZERO");
|
||||
}
|
||||
#endif
|
||||
|
||||
gd->arch.tsc_mhz = fast_calibrate;
|
||||
return fast_calibrate;
|
||||
|
@ -9,7 +9,32 @@ config SYS_VENDOR
|
||||
config SYS_SOC
|
||||
default "coreboot"
|
||||
|
||||
comment "coreboot-specific options"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "coreboot"
|
||||
string "Board configuration file"
|
||||
default "chromebook_link"
|
||||
help
|
||||
This option selects the board configuration file in include/configs/
|
||||
directory to be used to build U-Boot for coreboot.
|
||||
|
||||
config DEFAULT_DEVICE_TREE
|
||||
string "Board Device Tree Source (dts) file"
|
||||
default "chromebook_link"
|
||||
help
|
||||
This option selects the board Device Tree Source (dts) file in
|
||||
arch/x86/dts/ directory to be used to build U-Boot for coreboot.
|
||||
|
||||
config SYS_CAR_ADDR
|
||||
hex "Board specific Cache-As-RAM (CAR) address"
|
||||
default 0x19200000
|
||||
help
|
||||
This option specifies the board specific Cache-As-RAM (CAR) address.
|
||||
|
||||
config SYS_CAR_SIZE
|
||||
hex "Board specific Cache-As-RAM (CAR) size"
|
||||
default 0x4000
|
||||
help
|
||||
This option specifies the board specific Cache-As-RAM (CAR) size.
|
||||
|
||||
endif
|
||||
|
@ -2,5 +2,5 @@ COREBOOT BOARD
|
||||
M: Simon Glass <sjg@chromium.org>
|
||||
S: Maintained
|
||||
F: board/coreboot/coreboot/
|
||||
F: include/configs/coreboot.h
|
||||
F: include/configs/chromebook_link.h
|
||||
F: configs/coreboot-x86_defconfig
|
||||
|
@ -10,8 +10,10 @@
|
||||
|
||||
int arch_early_init_r(void)
|
||||
{
|
||||
#ifdef CONFIG_CROS_EC
|
||||
if (cros_ec_board_init())
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ config SYS_CONFIG_NAME
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select X86_RESET_VECTOR
|
||||
select CPU_INTEL_SOCKET_RPGA989
|
||||
select NORTHBRIDGE_INTEL_IVYBRIDGE
|
||||
select SOUTHBRIDGE_INTEL_C216
|
||||
@ -29,4 +30,12 @@ config EARLY_POST_CROS_EC
|
||||
bool "Enable early post to Chrome OS EC"
|
||||
default y
|
||||
|
||||
config SYS_CAR_ADDR
|
||||
hex
|
||||
default 0xff7e0000
|
||||
|
||||
config SYS_CAR_SIZE
|
||||
hex
|
||||
default 0x20000
|
||||
|
||||
endif
|
||||
|
@ -14,6 +14,7 @@ config SYS_CONFIG_NAME
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select X86_RESET_VECTOR
|
||||
select INTEL_QUEENSBAY
|
||||
select BOARD_ROMSIZE_KB_1024
|
||||
|
||||
|
@ -985,6 +985,11 @@ static init_fnc_t init_sequence_f[] = {
|
||||
INIT_FUNC_WATCHDOG_RESET
|
||||
reloc_fdt,
|
||||
setup_reloc,
|
||||
#ifdef CONFIG_X86
|
||||
copy_uboot_to_ram,
|
||||
clear_bss,
|
||||
do_elf_reloc_fixups,
|
||||
#endif
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
|
||||
jump_to_copy,
|
||||
#endif
|
||||
@ -1044,9 +1049,6 @@ void board_init_f(ulong boot_flags)
|
||||
*/
|
||||
static init_fnc_t init_sequence_f_r[] = {
|
||||
init_cache_f_r,
|
||||
copy_uboot_to_ram,
|
||||
clear_bss,
|
||||
do_elf_reloc_fixups,
|
||||
|
||||
NULL,
|
||||
};
|
||||
|
@ -6,5 +6,6 @@ CONFIG_OF_SEPARATE=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="chromebook_link"
|
||||
CONFIG_HAVE_MRC=y
|
||||
CONFIG_SMM_TSEG_SIZE=0x800000
|
||||
CONFIG_VIDEO_X86=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
|
||||
|
@ -2,4 +2,3 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0x01110000"
|
||||
CONFIG_X86=y
|
||||
CONFIG_TARGET_COREBOOT=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="link"
|
||||
|
@ -32,6 +32,21 @@ on other architectures, like below:
|
||||
$ make coreboot-x86_defconfig
|
||||
$ make all
|
||||
|
||||
Note this default configuration will build a U-Boot payload for the Link board.
|
||||
To build a coreboot payload against another board, you can change the build
|
||||
configuration during the 'make menuconfig' process.
|
||||
|
||||
x86 architecture --->
|
||||
...
|
||||
(chromebook_link) Board configuration file
|
||||
(chromebook_link) Board Device Tree Source (dts) file
|
||||
(0x19200000) Board specific Cache-As-RAM (CAR) address
|
||||
(0x4000) Board specific Cache-As-RAM (CAR) size
|
||||
|
||||
Change the 'Board configuration file' and 'Board Device Tree Source (dts) file'
|
||||
to point to a new board. You can also change the Cache-As-RAM (CAR) related
|
||||
settings here if the default values do not fit your new board.
|
||||
|
||||
Building ROM version of U-Boot (hereafter referred to as u-boot.rom) is a
|
||||
little bit tricky, as generally it requires several binary blobs which are not
|
||||
shipped in the U-Boot source tree. Due to this reason, the u-boot.rom build is
|
||||
@ -88,11 +103,31 @@ in this FSP package too.
|
||||
Rename the first one to fsp.bin and second one to cmc.bin and put them in the
|
||||
board directory.
|
||||
|
||||
Now you can build U-Boot and obtaim u-boot.rom
|
||||
Now you can build U-Boot and obtain u-boot.rom
|
||||
|
||||
$ make crownbay_defconfig
|
||||
$ make all
|
||||
|
||||
Test with coreboot
|
||||
------------------
|
||||
For testing U-Boot as the coreboot payload, there are things that need be paid
|
||||
attention to. coreboot supports loading an ELF executable and a 32-bit plain
|
||||
binary, as well as other supported payloads. With the default configuration,
|
||||
U-Boot is set up to use a separate Device Tree Blob (dtb). As of today, the
|
||||
generated u-boot-dtb.bin needs to be packaged by the cbfstool utility (a tool
|
||||
provided by coreboot) manually as coreboot's 'make menuconfig' does not provide
|
||||
this capability yet. The command is as follows:
|
||||
|
||||
# in the coreboot root directory
|
||||
$ ./build/util/cbfstool/cbfstool build/coreboot.rom add-flat-binary \
|
||||
-f u-boot-dtb.bin -n fallback/payload -c lzma -l 0x1110000 -e 0x1110015
|
||||
|
||||
Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the
|
||||
symbol address of _start (in arch/x86/cpu/start.S).
|
||||
|
||||
If you want to use ELF as the coreboot payload, change U-Boot configuration to
|
||||
use CONFIG_OF_EMBED.
|
||||
|
||||
CPU Microcode
|
||||
-------------
|
||||
Modern CPU usually requires a special bit stream called microcode [5] to be
|
||||
@ -106,13 +141,29 @@ x86 has been converted to use driver model for serial and GPIO.
|
||||
Device Tree
|
||||
-----------
|
||||
x86 uses device tree to configure the board thus requires CONFIG_OF_CONTROL to
|
||||
be turned on. Not every device on the board is configured via devie tree, but
|
||||
be turned on. Not every device on the board is configured via device tree, but
|
||||
more and more devices will be added as time goes by. Check out the directory
|
||||
arch/x86/dts/ for these device tree source files.
|
||||
|
||||
Useful Commands
|
||||
---------------
|
||||
|
||||
In keeping with the U-Boot philosophy of providing functions to check and
|
||||
adjust internal settings, there are several x86-specific commands that may be
|
||||
useful:
|
||||
|
||||
hob - Display information about Firmware Support Package (FSP) Hand-off
|
||||
Block. This is only available on platforms which use FSP, mostly
|
||||
Atom.
|
||||
iod - Display I/O memory
|
||||
iow - Write I/O memory
|
||||
mtrr - List and set the Memory Type Range Registers (MTRR). These are used to
|
||||
tell the CPU whether memory is cacheable and if so the cache write
|
||||
mode to use. U-Boot sets up some reasonable values but you can
|
||||
adjust then with this command.
|
||||
|
||||
TODO List
|
||||
---------
|
||||
- MTRR support (for performance)
|
||||
- Audio
|
||||
- Chrome OS verified boot
|
||||
- SMI and ACPI support, to provide platform info and facilities to Linux
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <asm/io.h>
|
||||
#include <pci.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define PCI_HOSE_OP(rw, size, type) \
|
||||
int pci_hose_##rw##_config_##size(struct pci_controller *hose, \
|
||||
pci_dev_t dev, \
|
||||
@ -123,6 +125,14 @@ void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
|
||||
|
||||
static struct pci_controller* hose_head;
|
||||
|
||||
struct pci_controller *pci_get_hose_head(void)
|
||||
{
|
||||
if (gd->hose)
|
||||
return gd->hose;
|
||||
|
||||
return hose_head;
|
||||
}
|
||||
|
||||
void pci_register_hose(struct pci_controller* hose)
|
||||
{
|
||||
struct pci_controller **phose = &hose_head;
|
||||
@ -139,7 +149,7 @@ struct pci_controller *pci_bus_to_hose(int bus)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
|
||||
for (hose = hose_head; hose; hose = hose->next) {
|
||||
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
|
||||
if (bus >= hose->first_busno && bus <= hose->last_busno)
|
||||
return hose;
|
||||
}
|
||||
@ -152,7 +162,7 @@ struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
|
||||
for (hose = hose_head; hose; hose = hose->next) {
|
||||
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
|
||||
if (hose->cfg_addr == cfg_addr)
|
||||
return hose;
|
||||
}
|
||||
@ -162,7 +172,7 @@ struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr)
|
||||
|
||||
int pci_last_busno(void)
|
||||
{
|
||||
struct pci_controller *hose = hose_head;
|
||||
struct pci_controller *hose = pci_get_hose_head();
|
||||
|
||||
if (!hose)
|
||||
return -1;
|
||||
@ -181,7 +191,7 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
|
||||
pci_dev_t bdf;
|
||||
int i, bus, found_multi = 0;
|
||||
|
||||
for (hose = hose_head; hose; hose = hose->next) {
|
||||
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
|
||||
#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
|
||||
for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
|
||||
#else
|
||||
@ -233,7 +243,7 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
|
||||
|
||||
pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
|
||||
{
|
||||
static struct pci_device_id ids[2] = {{}, {0, 0}};
|
||||
struct pci_device_id ids[2] = { {}, {0, 0} };
|
||||
|
||||
ids[0].vendor = vendor;
|
||||
ids[0].device = device;
|
||||
@ -709,11 +719,10 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus)
|
||||
int pci_hose_scan(struct pci_controller *hose)
|
||||
{
|
||||
#if defined(CONFIG_PCI_BOOTDELAY)
|
||||
static int pcidelay_done;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
if (!pcidelay_done) {
|
||||
if (!gd->pcidelay_done) {
|
||||
/* wait "pcidelay" ms (if defined)... */
|
||||
s = getenv("pcidelay");
|
||||
if (s) {
|
||||
@ -721,7 +730,7 @@ int pci_hose_scan(struct pci_controller *hose)
|
||||
for (i = 0; i < val; i++)
|
||||
udelay(1000);
|
||||
}
|
||||
pcidelay_done = 1;
|
||||
gd->pcidelay_done = 1;
|
||||
}
|
||||
#endif /* CONFIG_PCI_BOOTDELAY */
|
||||
|
||||
|
@ -156,6 +156,8 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header,
|
||||
|
||||
target = (void *)PCI_VGA_RAM_IMAGE_START;
|
||||
if (target != rom_header) {
|
||||
ulong start = get_timer(0);
|
||||
|
||||
debug("Copying VGA ROM Image from %p to %p, 0x%x bytes\n",
|
||||
rom_header, target, rom_size);
|
||||
memcpy(target, rom_header, rom_size);
|
||||
@ -163,6 +165,7 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header,
|
||||
printf("VGA ROM copy failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
debug("Copy took %lums\n", get_timer(start));
|
||||
}
|
||||
*ram_headerp = target;
|
||||
|
||||
@ -205,7 +208,7 @@ int vbe_get_video_info(struct graphic_device *gdev)
|
||||
gdev->vprBase = vesa->phys_base_ptr;
|
||||
gdev->cprBase = vesa->phys_base_ptr;
|
||||
|
||||
return 0;
|
||||
return gdev->winSizeX ? 0 : -ENOSYS;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
@ -244,7 +247,7 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
|
||||
defined(CONFIG_FRAMEBUFFER_VESA_MODE)
|
||||
vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE;
|
||||
#endif
|
||||
debug("Selected vesa mode %d\b", vesa_mode);
|
||||
debug("Selected vesa mode %#x\n", vesa_mode);
|
||||
if (emulate) {
|
||||
#ifdef CONFIG_BIOSEMU
|
||||
BE_VGAInfo *info;
|
||||
@ -272,7 +275,7 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
debug("Final vesa mode %d\n", mode_info.video_mode);
|
||||
debug("Final vesa mode %#x\n", mode_info.video_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -458,6 +458,7 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,
|
||||
unsigned int *index,
|
||||
unsigned int *lanes)
|
||||
{
|
||||
struct fdt_pci_addr addr;
|
||||
pci_dev_t bdf;
|
||||
int err;
|
||||
|
||||
@ -469,7 +470,7 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,
|
||||
|
||||
*lanes = err;
|
||||
|
||||
err = fdtdec_pci_get_bdf(fdt, node, &bdf);
|
||||
err = fdtdec_get_pci_bdf(fdt, node, &addr, &bdf);
|
||||
if (err < 0) {
|
||||
error("failed to parse \"reg\" property");
|
||||
return err;
|
||||
|
@ -289,7 +289,38 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
|
||||
struct ns16550_platdata *plat = dev->platdata;
|
||||
fdt_addr_t addr;
|
||||
|
||||
/* try Processor Local Bus device first */
|
||||
addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
|
||||
#ifdef CONFIG_PCI
|
||||
if (addr == FDT_ADDR_T_NONE) {
|
||||
/* then try pci device */
|
||||
struct fdt_pci_addr pci_addr;
|
||||
u32 bar;
|
||||
int ret;
|
||||
|
||||
/* we prefer to use a memory-mapped register */
|
||||
ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
|
||||
FDT_PCI_SPACE_MEM32, "reg",
|
||||
&pci_addr);
|
||||
if (ret) {
|
||||
/* try if there is any i/o-mapped register */
|
||||
ret = fdtdec_get_pci_addr(gd->fdt_blob,
|
||||
dev->of_offset,
|
||||
FDT_PCI_SPACE_IO,
|
||||
"reg", &pci_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fdtdec_get_pci_bar32(gd->fdt_blob, dev->of_offset,
|
||||
&pci_addr, &bar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = bar;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -6,9 +6,12 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <ns16550.h>
|
||||
#include <serial.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct udevice_id x86_serial_ids[] = {
|
||||
{ .compatible = "x86-uart" },
|
||||
{ }
|
||||
@ -22,10 +25,13 @@ static int x86_serial_ofdata_to_platdata(struct udevice *dev)
|
||||
ret = ns16550_serial_ofdata_to_platdata(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
plat->clock = 1843200;
|
||||
|
||||
plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
|
||||
"clock-frequency", 1843200);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(serial_ns16550) = {
|
||||
.name = "serial_x86",
|
||||
.id = UCLASS_SERIAL,
|
||||
|
@ -0,0 +1,8 @@
|
||||
config VIDEO_X86
|
||||
bool "Enable x86 video driver support"
|
||||
depends on X86
|
||||
default n
|
||||
help
|
||||
Turn on this option to enable a very simple driver which uses vesa
|
||||
to discover the video mode and then provides a frame buffer for use
|
||||
by U-Boot.
|
@ -32,6 +32,7 @@ void *video_hw_init(void)
|
||||
sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
|
||||
bits_per_pixel);
|
||||
printf("%s\n", gdev->modeIdent);
|
||||
debug("Frame buffer at %x\n", gdev->frameAdrs);
|
||||
|
||||
return (void *)gdev;
|
||||
}
|
||||
|
@ -90,6 +90,12 @@ typedef struct global_data {
|
||||
unsigned long malloc_base; /* base address of early malloc() */
|
||||
unsigned long malloc_limit; /* limit address */
|
||||
unsigned long malloc_ptr; /* current address */
|
||||
#endif
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller *hose; /* PCI hose for early use */
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_BOOTDELAY
|
||||
int pcidelay_done;
|
||||
#endif
|
||||
struct udevice *cur_serial_dev; /* current serial device */
|
||||
struct arch_global_data arch; /* architecture-specific data */
|
||||
|
@ -15,15 +15,12 @@
|
||||
|
||||
#include <configs/x86-common.h>
|
||||
|
||||
#define CONFIG_SYS_CAR_ADDR 0xff7e0000
|
||||
#define CONFIG_SYS_CAR_SIZE (128 * 1024)
|
||||
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
|
||||
#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000
|
||||
#define CONFIG_SYS_X86_START16 0xfffff800
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
|
||||
#define CONFIG_X86_RESET_VECTOR
|
||||
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
|
||||
|
||||
#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_NR_DRAM_BANKS 8
|
||||
#define CONFIG_X86_MRC_ADDR 0xfffa0000
|
||||
#define CONFIG_CACHE_MRC_SIZE_KB 512
|
||||
@ -41,7 +38,6 @@
|
||||
|
||||
#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin
|
||||
#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000
|
||||
#define CONFIG_VIDEO_X86
|
||||
|
||||
#define CONFIG_PCI_MEM_BUS 0xe0000000
|
||||
#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The Chromium OS Authors.
|
||||
* (C) Copyright 2008
|
||||
* Graeme Russ, graeme.russ@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>
|
||||
|
||||
/*
|
||||
* High Level Configuration Options
|
||||
* (easy to change)
|
||||
*/
|
||||
#define CONFIG_SYS_COREBOOT
|
||||
#define CONFIG_LAST_STAGE_INIT
|
||||
#define CONFIG_SYS_EARLY_PCI_INIT
|
||||
|
||||
#define CONFIG_SYS_CAR_ADDR 0x19200000
|
||||
#define CONFIG_SYS_CAR_SIZE (16 * 1024)
|
||||
#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
|
||||
|
||||
#define CONFIG_TRACE_EARLY_SIZE (8 << 20)
|
||||
#define CONFIG_TRACE_EARLY
|
||||
#define CONFIG_TRACE_EARLY_ADDR 0x01400000
|
||||
|
||||
#define CONFIG_BOOTSTAGE
|
||||
#define CONFIG_BOOTSTAGE_REPORT
|
||||
#define CONFIG_BOOTSTAGE_FDT
|
||||
#define CONFIG_CMD_BOOTSTAGE
|
||||
/* Place to stash bootstage data from first-stage U-Boot */
|
||||
#define CONFIG_BOOTSTAGE_STASH 0x0110f000
|
||||
#define CONFIG_BOOTSTAGE_STASH_SIZE 0x7fc
|
||||
#define CONFIG_BOOTSTAGE_USER_COUNT 60
|
||||
|
||||
#define CONFIG_SCSI_DEV_LIST {PCI_VENDOR_ID_INTEL, \
|
||||
PCI_DEVICE_ID_INTEL_NM10_AHCI}, \
|
||||
{PCI_VENDOR_ID_INTEL, \
|
||||
PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE}, \
|
||||
{PCI_VENDOR_ID_INTEL, \
|
||||
PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6}, \
|
||||
{PCI_VENDOR_ID_INTEL, \
|
||||
PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}
|
||||
|
||||
#define CONFIG_X86_SERIAL
|
||||
|
||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
|
||||
"stdout=vga,serial,cbmem\0" \
|
||||
"stderr=vga,serial,cbmem\0"
|
||||
|
||||
#define CONFIG_CBMEM_CONSOLE
|
||||
|
||||
#define CONFIG_VIDEO_COREBOOT
|
||||
|
||||
#define CONFIG_NR_DRAM_BANKS 4
|
||||
|
||||
#define CONFIG_TRACE
|
||||
#define CONFIG_CMD_TRACE
|
||||
#define CONFIG_TRACE_BUFFER_SIZE (16 << 20)
|
||||
|
||||
#define CONFIG_BOOTDELAY 2
|
||||
|
||||
#define CONFIG_CROS_EC
|
||||
#define CONFIG_CROS_EC_LPC
|
||||
#define CONFIG_CMD_CROS_EC
|
||||
#define CONFIG_ARCH_EARLY_INIT_R
|
||||
|
||||
#endif /* __CONFIG_H */
|
@ -14,10 +14,8 @@
|
||||
#include <configs/x86-common.h>
|
||||
|
||||
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
|
||||
#define CONFIG_SYS_X86_START16 0xfffff800
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_X86_RESET_VECTOR
|
||||
#define CONFIG_NR_DRAM_BANKS 1
|
||||
|
||||
#define CONFIG_X86_SERIAL
|
||||
|
109
include/fdtdec.h
109
include/fdtdec.h
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <libfdt.h>
|
||||
#include <pci.h>
|
||||
|
||||
/*
|
||||
* A typedef for a physical address. Note that fdt data is always big
|
||||
@ -50,6 +51,49 @@ struct fdt_resource {
|
||||
fdt_addr_t end;
|
||||
};
|
||||
|
||||
enum fdt_pci_space {
|
||||
FDT_PCI_SPACE_CONFIG = 0,
|
||||
FDT_PCI_SPACE_IO = 0x01000000,
|
||||
FDT_PCI_SPACE_MEM32 = 0x02000000,
|
||||
FDT_PCI_SPACE_MEM64 = 0x03000000,
|
||||
FDT_PCI_SPACE_MEM32_PREF = 0x42000000,
|
||||
FDT_PCI_SPACE_MEM64_PREF = 0x43000000,
|
||||
};
|
||||
|
||||
#define FDT_PCI_ADDR_CELLS 3
|
||||
#define FDT_PCI_SIZE_CELLS 2
|
||||
#define FDT_PCI_REG_SIZE \
|
||||
((FDT_PCI_ADDR_CELLS + FDT_PCI_SIZE_CELLS) * sizeof(u32))
|
||||
|
||||
/*
|
||||
* The Open Firmware spec defines PCI physical address as follows:
|
||||
*
|
||||
* bits# 31 .... 24 23 .... 16 15 .... 08 07 .... 00
|
||||
*
|
||||
* phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr
|
||||
* phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
|
||||
* phys.lo cell: llllllll llllllll llllllll llllllll
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* n: is 0 if the address is relocatable, 1 otherwise
|
||||
* p: is 1 if addressable region is prefetchable, 0 otherwise
|
||||
* t: is 1 if the address is aliased (for non-relocatable I/O) below 1MB
|
||||
* (for Memory), or below 64KB (for relocatable I/O)
|
||||
* ss: is the space code, denoting the address space
|
||||
* bbbbbbbb: is the 8-bit Bus Number
|
||||
* ddddd: is the 5-bit Device Number
|
||||
* fff: is the 3-bit Function Number
|
||||
* rrrrrrrr: is the 8-bit Register Number
|
||||
* hhhhhhhh: is a 32-bit unsigned number
|
||||
* llllllll: is a 32-bit unsigned number
|
||||
*/
|
||||
struct fdt_pci_addr {
|
||||
u32 phys_hi;
|
||||
u32 phys_mid;
|
||||
u32 phys_lo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the size of a resource.
|
||||
*
|
||||
@ -257,6 +301,60 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
|
||||
fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
|
||||
const char *prop_name, fdt_size_t *sizep);
|
||||
|
||||
/**
|
||||
* Look at an address property in a node and return the pci address which
|
||||
* corresponds to the given type in the form of fdt_pci_addr.
|
||||
* The property must hold one fdt_pci_addr with a lengh.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node node to examine
|
||||
* @param type pci address type (FDT_PCI_SPACE_xxx)
|
||||
* @param prop_name name of property to find
|
||||
* @param addr returns pci address in the form of fdt_pci_addr
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
|
||||
const char *prop_name, struct fdt_pci_addr *addr);
|
||||
|
||||
/**
|
||||
* Look at the compatible property of a device node that represents a PCI
|
||||
* device and extract pci vendor id and device id from it.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node node to examine
|
||||
* @param vendor vendor id of the pci device
|
||||
* @param device device id of the pci device
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int fdtdec_get_pci_vendev(const void *blob, int node,
|
||||
u16 *vendor, u16 *device);
|
||||
|
||||
/**
|
||||
* Look at the pci address of a device node that represents a PCI device
|
||||
* and parse the bus, device and function number from it.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node node to examine
|
||||
* @param addr pci address in the form of fdt_pci_addr
|
||||
* @param bdf returns bus, device, function triplet
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int fdtdec_get_pci_bdf(const void *blob, int node,
|
||||
struct fdt_pci_addr *addr, pci_dev_t *bdf);
|
||||
|
||||
/**
|
||||
* Look at the pci address of a device node that represents a PCI device
|
||||
* and return base address of the pci device's registers.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node node to examine
|
||||
* @param addr pci address in the form of fdt_pci_addr
|
||||
* @param bar returns base address of the pci device's registers
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int fdtdec_get_pci_bar32(const void *blob, int node,
|
||||
struct fdt_pci_addr *addr, u32 *bar);
|
||||
|
||||
/**
|
||||
* Look up a 32-bit integer property in a node and return it. The property
|
||||
* must have at least 4 bytes of data. The value of the first cell is
|
||||
@ -682,17 +780,6 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property,
|
||||
const char *prop_names, const char *name,
|
||||
struct fdt_resource *res);
|
||||
|
||||
/**
|
||||
* Look at the reg property of a device node that represents a PCI device
|
||||
* and parse the bus, device and function number from it.
|
||||
*
|
||||
* @param fdt FDT blob
|
||||
* @param node node to examine
|
||||
* @param bdf returns bus, device, function triplet
|
||||
* @return 0 if ok, negative on error
|
||||
*/
|
||||
int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf);
|
||||
|
||||
/**
|
||||
* Decode a named region within a memory bank of a given type.
|
||||
*
|
||||
|
171
lib/fdtdec.c
171
lib/fdtdec.c
@ -126,6 +126,163 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
|
||||
return fdtdec_get_addr_size(blob, node, prop_name, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
|
||||
const char *prop_name, struct fdt_pci_addr *addr)
|
||||
{
|
||||
const u32 *cell;
|
||||
int len;
|
||||
int ret = -ENOENT;
|
||||
|
||||
debug("%s: %s: ", __func__, prop_name);
|
||||
|
||||
/*
|
||||
* If we follow the pci bus bindings strictly, we should check
|
||||
* the value of the node's parent node's #address-cells and
|
||||
* #size-cells. They need to be 3 and 2 accordingly. However,
|
||||
* for simplicity we skip the check here.
|
||||
*/
|
||||
cell = fdt_getprop(blob, node, prop_name, &len);
|
||||
if (!cell)
|
||||
goto fail;
|
||||
|
||||
if ((len % FDT_PCI_REG_SIZE) == 0) {
|
||||
int num = len / FDT_PCI_REG_SIZE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
debug("pci address #%d: %08lx %08lx %08lx\n", i,
|
||||
(ulong)fdt_addr_to_cpu(cell[0]),
|
||||
(ulong)fdt_addr_to_cpu(cell[1]),
|
||||
(ulong)fdt_addr_to_cpu(cell[2]));
|
||||
if ((fdt_addr_to_cpu(*cell) & type) == type) {
|
||||
addr->phys_hi = fdt_addr_to_cpu(cell[0]);
|
||||
addr->phys_mid = fdt_addr_to_cpu(cell[1]);
|
||||
addr->phys_lo = fdt_addr_to_cpu(cell[2]);
|
||||
break;
|
||||
} else {
|
||||
cell += (FDT_PCI_ADDR_CELLS +
|
||||
FDT_PCI_SIZE_CELLS);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == num)
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
fail:
|
||||
debug("(not found)\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device)
|
||||
{
|
||||
const char *list, *end;
|
||||
int len;
|
||||
|
||||
list = fdt_getprop(blob, node, "compatible", &len);
|
||||
if (!list)
|
||||
return -ENOENT;
|
||||
|
||||
end = list + len;
|
||||
while (list < end) {
|
||||
char *s;
|
||||
|
||||
len = strlen(list);
|
||||
if (len >= strlen("pciVVVV,DDDD")) {
|
||||
s = strstr(list, "pci");
|
||||
|
||||
/*
|
||||
* check if the string is something like pciVVVV,DDDD.RR
|
||||
* or just pciVVVV,DDDD
|
||||
*/
|
||||
if (s && s[7] == ',' &&
|
||||
(s[12] == '.' || s[12] == 0)) {
|
||||
s += 3;
|
||||
*vendor = simple_strtol(s, NULL, 16);
|
||||
|
||||
s += 5;
|
||||
*device = simple_strtol(s, NULL, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
list += (len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int fdtdec_get_pci_bdf(const void *blob, int node,
|
||||
struct fdt_pci_addr *addr, pci_dev_t *bdf)
|
||||
{
|
||||
u16 dt_vendor, dt_device, vendor, device;
|
||||
int ret;
|
||||
|
||||
/* get vendor id & device id from the compatible string */
|
||||
ret = fdtdec_get_pci_vendev(blob, node, &dt_vendor, &dt_device);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* extract the bdf from fdt_pci_addr */
|
||||
*bdf = addr->phys_hi & 0xffff00;
|
||||
|
||||
/* read vendor id & device id based on bdf */
|
||||
pci_read_config_word(*bdf, PCI_VENDOR_ID, &vendor);
|
||||
pci_read_config_word(*bdf, PCI_DEVICE_ID, &device);
|
||||
|
||||
/*
|
||||
* Note there are two places in the device tree to fully describe
|
||||
* a pci device: one is via compatible string with a format of
|
||||
* "pciVVVV,DDDD" and the other one is the bdf numbers encoded in
|
||||
* the device node's reg address property. We read the vendor id
|
||||
* and device id based on bdf and compare the values with the
|
||||
* "VVVV,DDDD". If they are the same, then we are good to use bdf
|
||||
* to read device's bar. But if they are different, we have to rely
|
||||
* on the vendor id and device id extracted from the compatible
|
||||
* string and locate the real bdf by pci_find_device(). This is
|
||||
* because normally we may only know device's device number and
|
||||
* function number when writing device tree. The bus number is
|
||||
* dynamically assigned during the pci enumeration process.
|
||||
*/
|
||||
if ((dt_vendor != vendor) || (dt_device != device)) {
|
||||
*bdf = pci_find_device(dt_vendor, dt_device, 0);
|
||||
if (*bdf == -1)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdtdec_get_pci_bar32(const void *blob, int node,
|
||||
struct fdt_pci_addr *addr, u32 *bar)
|
||||
{
|
||||
pci_dev_t bdf;
|
||||
int barnum;
|
||||
int ret;
|
||||
|
||||
/* get pci devices's bdf */
|
||||
ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* extract the bar number from fdt_pci_addr */
|
||||
barnum = addr->phys_hi & 0xff;
|
||||
if ((barnum < PCI_BASE_ADDRESS_0) || (barnum > PCI_CARDBUS_CIS))
|
||||
return -EINVAL;
|
||||
|
||||
barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
|
||||
*bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,
|
||||
uint64_t default_val)
|
||||
{
|
||||
@ -795,20 +952,6 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property,
|
||||
return fdt_get_resource(fdt, node, property, index, res);
|
||||
}
|
||||
|
||||
int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf)
|
||||
{
|
||||
const fdt32_t *prop;
|
||||
int len;
|
||||
|
||||
prop = fdt_getprop(fdt, node, "reg", &len);
|
||||
if (!prop)
|
||||
return len;
|
||||
|
||||
*bdf = fdt32_to_cpu(*prop) & 0xffffff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdtdec_decode_memory_region(const void *blob, int config_node,
|
||||
const char *mem_type, const char *suffix,
|
||||
fdt_addr_t *basep, fdt_size_t *sizep)
|
||||
|
@ -788,9 +788,9 @@ static int write_uboot(char *image, int size, struct input_file *uboot,
|
||||
fdt_strerror(data_size));
|
||||
return -ENOENT;
|
||||
}
|
||||
offset = ucode_ptr - uboot->addr;
|
||||
offset = (uint32_t)(ucode_ptr + size);
|
||||
ptr = (void *)image + offset;
|
||||
ptr[0] = uboot->addr + (data - image);
|
||||
ptr[0] = (data - image) - size;
|
||||
ptr[1] = data_size;
|
||||
debug("Wrote microcode pointer at %x: addr=%x, size=%x\n",
|
||||
ucode_ptr, ptr[0], ptr[1]);
|
||||
|
Loading…
Reference in New Issue
Block a user