Merge git://git.denx.de/u-boot-x86

This commit is contained in:
Tom Rini 2014-12-01 15:24:07 -05:00
commit f4e7e2d121
89 changed files with 5873 additions and 364 deletions

View file

@ -980,6 +980,9 @@ u-boot.rom: u-boot-x86-16bit.bin u-boot-dtb.bin \
$(objtree)/tools/ifdtool -w \
$(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin \
u-boot.tmp
$(objtree)/tools/ifdtool -w \
$(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILENAME) \
u-boot.tmp
mv u-boot.tmp $@
OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec

View file

@ -83,6 +83,155 @@ config X86_RAMTEST
to work correctly. It is not exhaustive but can save time by
detecting obvious failures.
config MARK_GRAPHICS_MEM_WRCOMB
bool "Mark graphics memory as write-combining."
default n
help
The graphics performance may increase if the graphics
memory is set as write-combining cache type. This option
enables marking the graphics memory as write-combining.
menu "Display"
config FRAMEBUFFER_SET_VESA_MODE
prompt "Set framebuffer graphics resolution"
bool
help
Set VESA/native framebuffer mode (needed for bootsplash and graphical framebuffer console)
choice
prompt "framebuffer graphics resolution"
default FRAMEBUFFER_VESA_MODE_117
depends on FRAMEBUFFER_SET_VESA_MODE
help
This option sets the resolution used for the coreboot framebuffer (and
bootsplash screen).
config FRAMEBUFFER_VESA_MODE_100
bool "640x400 256-color"
config FRAMEBUFFER_VESA_MODE_101
bool "640x480 256-color"
config FRAMEBUFFER_VESA_MODE_102
bool "800x600 16-color"
config FRAMEBUFFER_VESA_MODE_103
bool "800x600 256-color"
config FRAMEBUFFER_VESA_MODE_104
bool "1024x768 16-color"
config FRAMEBUFFER_VESA_MODE_105
bool "1024x7686 256-color"
config FRAMEBUFFER_VESA_MODE_106
bool "1280x1024 16-color"
config FRAMEBUFFER_VESA_MODE_107
bool "1280x1024 256-color"
config FRAMEBUFFER_VESA_MODE_108
bool "80x60 text"
config FRAMEBUFFER_VESA_MODE_109
bool "132x25 text"
config FRAMEBUFFER_VESA_MODE_10A
bool "132x43 text"
config FRAMEBUFFER_VESA_MODE_10B
bool "132x50 text"
config FRAMEBUFFER_VESA_MODE_10C
bool "132x60 text"
config FRAMEBUFFER_VESA_MODE_10D
bool "320x200 32k-color (1:5:5:5)"
config FRAMEBUFFER_VESA_MODE_10E
bool "320x200 64k-color (5:6:5)"
config FRAMEBUFFER_VESA_MODE_10F
bool "320x200 16.8M-color (8:8:8)"
config FRAMEBUFFER_VESA_MODE_110
bool "640x480 32k-color (1:5:5:5)"
config FRAMEBUFFER_VESA_MODE_111
bool "640x480 64k-color (5:6:5)"
config FRAMEBUFFER_VESA_MODE_112
bool "640x480 16.8M-color (8:8:8)"
config FRAMEBUFFER_VESA_MODE_113
bool "800x600 32k-color (1:5:5:5)"
config FRAMEBUFFER_VESA_MODE_114
bool "800x600 64k-color (5:6:5)"
config FRAMEBUFFER_VESA_MODE_115
bool "800x600 16.8M-color (8:8:8)"
config FRAMEBUFFER_VESA_MODE_116
bool "1024x768 32k-color (1:5:5:5)"
config FRAMEBUFFER_VESA_MODE_117
bool "1024x768 64k-color (5:6:5)"
config FRAMEBUFFER_VESA_MODE_118
bool "1024x768 16.8M-color (8:8:8)"
config FRAMEBUFFER_VESA_MODE_119
bool "1280x1024 32k-color (1:5:5:5)"
config FRAMEBUFFER_VESA_MODE_11A
bool "1280x1024 64k-color (5:6:5)"
config FRAMEBUFFER_VESA_MODE_11B
bool "1280x1024 16.8M-color (8:8:8)"
config FRAMEBUFFER_VESA_MODE_USER
bool "Manually select VESA mode"
endchoice
# Map the config names to an integer (KB).
config FRAMEBUFFER_VESA_MODE
prompt "VESA mode" if FRAMEBUFFER_VESA_MODE_USER
hex
default 0x100 if FRAMEBUFFER_VESA_MODE_100
default 0x101 if FRAMEBUFFER_VESA_MODE_101
default 0x102 if FRAMEBUFFER_VESA_MODE_102
default 0x103 if FRAMEBUFFER_VESA_MODE_103
default 0x104 if FRAMEBUFFER_VESA_MODE_104
default 0x105 if FRAMEBUFFER_VESA_MODE_105
default 0x106 if FRAMEBUFFER_VESA_MODE_106
default 0x107 if FRAMEBUFFER_VESA_MODE_107
default 0x108 if FRAMEBUFFER_VESA_MODE_108
default 0x109 if FRAMEBUFFER_VESA_MODE_109
default 0x10A if FRAMEBUFFER_VESA_MODE_10A
default 0x10B if FRAMEBUFFER_VESA_MODE_10B
default 0x10C if FRAMEBUFFER_VESA_MODE_10C
default 0x10D if FRAMEBUFFER_VESA_MODE_10D
default 0x10E if FRAMEBUFFER_VESA_MODE_10E
default 0x10F if FRAMEBUFFER_VESA_MODE_10F
default 0x110 if FRAMEBUFFER_VESA_MODE_110
default 0x111 if FRAMEBUFFER_VESA_MODE_111
default 0x112 if FRAMEBUFFER_VESA_MODE_112
default 0x113 if FRAMEBUFFER_VESA_MODE_113
default 0x114 if FRAMEBUFFER_VESA_MODE_114
default 0x115 if FRAMEBUFFER_VESA_MODE_115
default 0x116 if FRAMEBUFFER_VESA_MODE_116
default 0x117 if FRAMEBUFFER_VESA_MODE_117
default 0x118 if FRAMEBUFFER_VESA_MODE_118
default 0x119 if FRAMEBUFFER_VESA_MODE_119
default 0x11A if FRAMEBUFFER_VESA_MODE_11A
default 0x11B if FRAMEBUFFER_VESA_MODE_11B
default 0x117 if FRAMEBUFFER_VESA_MODE_USER
endmenu
source "arch/x86/cpu/ivybridge/Kconfig"
source "board/coreboot/coreboot/Kconfig"

View file

@ -13,4 +13,8 @@ obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_SYS_COREBOOT) += coreboot/
obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
obj-y += lapic.o
obj-$(CONFIG_PCI) += pci.o
obj-y += turbo.o

View file

@ -12,5 +12,6 @@ PLATFORM_CPPFLAGS += -D__I386__ -Werror
# DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!
LDPPFLAGS += -DRESET_SEG_START=0xffff0000
LDPPFLAGS += -DRESET_SEG_SIZE=0x10000
LDPPFLAGS += -DRESET_VEC_LOC=0xfff0
LDPPFLAGS += -DSTART_16=0xf800
LDPPFLAGS += -DRESET_VEC_LOC=0xfffffff0
LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16)
LDPPFLAGS += -DRESET_BASE="CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE)"

View file

@ -39,17 +39,6 @@ int board_early_init_f(void)
return 0;
}
int board_early_init_r(void)
{
/* CPU Speed to 100MHz */
gd->cpu_clk = 100000000;
/* Crystal is 33.000MHz */
gd->bus_clk = 33000000;
return 0;
}
int print_cpuinfo(void)
{
return default_print_cpuinfo();

View file

@ -124,7 +124,7 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries)
{
struct gdt_ptr gdt;
gdt.len = (num_entries * 8) - 1;
gdt.len = (num_entries * X86_GDT_ENTRY_SIZE) - 1;
gdt.ptr = (u32)boot_gdt;
asm volatile("lgdtl %0\n" : : "m" (gdt));
@ -144,10 +144,13 @@ void setup_gdt(gd_t *id, u64 *gdt_addr)
(ulong)&id->arch.gd_addr, 0xfffff);
/* 16-bit CS: code, read/execute, 64 kB, base 0 */
gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff);
gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
/* 16-bit DS: data, read/write, 64 kB, base 0 */
gdt_addr[X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x1093, 0, 0x0ffff);
gdt_addr[X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x0093, 0, 0x0ffff);
gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_CS] = GDT_ENTRY(0x809b, 0, 0xfffff);
gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_DS] = GDT_ENTRY(0x8093, 0, 0xfffff);
load_gdt(gdt_addr, X86_GDT_NUM_ENTRIES);
load_ds(X86_GDT_ENTRY_32BIT_DS);
@ -320,14 +323,6 @@ int x86_cpu_init_f(void)
return 0;
}
int x86_cpu_init_r(void)
{
/* Initialize core interrupt and exception functionality of CPU */
cpu_init_interrupts();
return 0;
}
int cpu_init_r(void) __attribute__((weak, alias("x86_cpu_init_r")));
void x86_enable_caches(void)
{
unsigned long cr0;

View file

@ -20,6 +20,7 @@
#include <linux/compiler.h>
#include <asm/msr.h>
#include <asm/u-boot-x86.h>
#include <asm/i8259.h>
DECLARE_GLOBAL_DATA_PTR;
@ -128,9 +129,6 @@ int cpu_init_interrupts(void)
int irq_entry_size = irq_1 - irq_0;
void *irq_entry = (void *)irq_0;
/* Just in case... */
disable_interrupts();
/* Setup the IDT */
for (i = 0; i < 256; i++) {
idt[i].access = 0x8e;
@ -146,9 +144,6 @@ int cpu_init_interrupts(void)
load_idt(&idt_ptr);
/* It is now safe to enable interrupts */
enable_interrupts();
return 0;
}
@ -172,6 +167,25 @@ int disable_interrupts(void)
return flags & X86_EFLAGS_IF;
}
int interrupt_init(void)
{
/* Just in case... */
disable_interrupts();
#ifdef CONFIG_SYS_PCAT_INTERRUPTS
/* Initialize the master/slave i8259 pic */
i8259_init();
#endif
/* Initialize core interrupt and exception functionality of CPU */
cpu_init_interrupts();
/* It is now safe to enable interrupts */
enable_interrupts();
return 0;
}
/* IRQ Low-Level Service Routine */
void irq_llsr(struct irq_regs *regs)
{
@ -603,31 +617,3 @@ asm(".globl irq_common_entry\n" \
DECLARE_INTERRUPT(253) \
DECLARE_INTERRUPT(254) \
DECLARE_INTERRUPT(255));
#if defined(CONFIG_INTEL_CORE_ARCH)
/*
* Get the number of CPU time counter ticks since it was read first time after
* restart. This yields a free running counter guaranteed to take almost 6
* years to wrap around even at 100GHz clock rate.
*/
u64 get_ticks(void)
{
u64 now_tick = rdtsc();
if (!gd->arch.tsc_base)
gd->arch.tsc_base = now_tick;
return now_tick - gd->arch.tsc_base;
}
#define PLATFORM_INFO_MSR 0xce
unsigned long get_tbclk(void)
{
u32 ratio;
u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
ratio = (platform_info >> 8) & 0xff;
return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */
}
#endif

View file

@ -4,13 +4,21 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += bd82x6x.o
obj-y += car.o
obj-y += cpu.o
obj-y += early_init.o
obj-y += early_me.o
obj-y += gma.o
obj-y += lpc.o
obj-y += me_status.o
obj-y += model_206ax.o
obj-y += microcode_intel.o
obj-y += northbridge.o
obj-y += pch.o
obj-y += pci.o
obj-y += report_platform.o
obj-y += sata.o
obj-y += sdram.o
obj-y += usb_ehci.o
obj-y += usb_xhci.o

View file

@ -0,0 +1,146 @@
/*
* Copyright (C) 2014 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
#include <asm/lapic.h>
#include <asm/pci.h>
#include <asm/arch/bd82x6x.h>
#include <asm/arch/model_206ax.h>
#include <asm/arch/pch.h>
#include <asm/arch/sandybridge.h>
void bd82x6x_pci_init(pci_dev_t dev)
{
u16 reg16;
u8 reg8;
debug("bd82x6x PCI init.\n");
/* Enable Bus Master */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 |= PCI_COMMAND_MASTER;
pci_write_config16(dev, PCI_COMMAND, reg16);
/* This device has no interrupt */
pci_write_config8(dev, INTR, 0xff);
/* disable parity error response and SERR */
reg16 = pci_read_config16(dev, BCTRL);
reg16 &= ~(1 << 0);
reg16 &= ~(1 << 1);
pci_write_config16(dev, BCTRL, reg16);
/* Master Latency Count must be set to 0x04! */
reg8 = pci_read_config8(dev, SMLT);
reg8 &= 0x07;
reg8 |= (0x04 << 3);
pci_write_config8(dev, SMLT, reg8);
/* Will this improve throughput of bus masters? */
pci_write_config8(dev, PCI_MIN_GNT, 0x06);
/* Clear errors in status registers */
reg16 = pci_read_config16(dev, PSTS);
/* reg16 |= 0xf900; */
pci_write_config16(dev, PSTS, reg16);
reg16 = pci_read_config16(dev, SECSTS);
/* reg16 |= 0xf900; */
pci_write_config16(dev, SECSTS, reg16);
}
#define PCI_BRIDGE_UPDATE_COMMAND
void bd82x6x_pci_dev_enable_resources(pci_dev_t dev)
{
uint16_t command;
command = pci_read_config16(dev, PCI_COMMAND);
command |= PCI_COMMAND_IO;
#ifdef PCI_BRIDGE_UPDATE_COMMAND
/*
* If we write to PCI_COMMAND, on some systems this will cause the
* ROM and APICs to become invisible.
*/
debug("%x cmd <- %02x\n", dev, command);
pci_write_config16(dev, PCI_COMMAND, command);
#else
printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command);
#endif
}
void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
{
uint16_t ctrl;
ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
ctrl |= PCI_COMMAND_IO;
ctrl |= PCI_BRIDGE_CTL_VGA;
debug("%x bridge ctrl <- %04x\n", dev, ctrl);
pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
bd82x6x_pci_dev_enable_resources(dev);
}
int bd82x6x_init_pci_devices(void)
{
const void *blob = gd->fdt_blob;
struct pci_controller *hose;
struct x86_cpu_priv *cpu;
int sata_node, gma_node;
int ret;
hose = pci_bus_to_hose(0);
lpc_enable(PCH_LPC_DEV);
lpc_init(hose, PCH_LPC_DEV);
sata_node = fdtdec_next_compatible(blob, 0,
COMPAT_INTEL_PANTHERPOINT_AHCI);
if (sata_node < 0) {
debug("%s: Cannot find SATA node\n", __func__);
return -EINVAL;
}
bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
bd82x6x_usb_ehci_init(PCH_EHCI1_DEV);
bd82x6x_usb_ehci_init(PCH_EHCI2_DEV);
cpu = calloc(1, sizeof(*cpu));
if (!cpu)
return -ENOMEM;
model_206ax_init(cpu);
gma_node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_GMA);
if (gma_node < 0) {
debug("%s: Cannot find GMA node\n", __func__);
return -EINVAL;
}
ret = gma_func0_init(PCH_VIDEO_DEV, pci_bus_to_hose(0), blob,
gma_node);
if (ret)
return ret;
return 0;
}
int bd82x6x_init(void)
{
const void *blob = gd->fdt_blob;
int sata_node;
sata_node = fdtdec_next_compatible(blob, 0,
COMPAT_INTEL_PANTHERPOINT_AHCI);
if (sata_node < 0) {
debug("%s: Cannot find SATA node\n", __func__);
return -EINVAL;
}
bd82x6x_pci_init(PCH_DEV);
bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
northbridge_enable(PCH_DEV);
northbridge_init(PCH_DEV);
return 0;
}

View file

@ -0,0 +1,756 @@
/*
* From Coreboot file of the same name
*
* Copyright (C) 2011 Chromium OS Authors
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <bios_emul.h>
#include <errno.h>
#include <fdtdec.h>
#include <pci_rom.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
#include <asm/arch/sandybridge.h>
struct gt_powermeter {
u16 reg;
u32 value;
};
static const struct gt_powermeter snb_pm_gt1[] = {
{ 0xa200, 0xcc000000 },
{ 0xa204, 0x07000040 },
{ 0xa208, 0x0000fe00 },
{ 0xa20c, 0x00000000 },
{ 0xa210, 0x17000000 },
{ 0xa214, 0x00000021 },
{ 0xa218, 0x0817fe19 },
{ 0xa21c, 0x00000000 },
{ 0xa220, 0x00000000 },
{ 0xa224, 0xcc000000 },
{ 0xa228, 0x07000040 },
{ 0xa22c, 0x0000fe00 },
{ 0xa230, 0x00000000 },
{ 0xa234, 0x17000000 },
{ 0xa238, 0x00000021 },
{ 0xa23c, 0x0817fe19 },
{ 0xa240, 0x00000000 },
{ 0xa244, 0x00000000 },
{ 0xa248, 0x8000421e },
{ 0 }
};
static const struct gt_powermeter snb_pm_gt2[] = {
{ 0xa200, 0x330000a6 },
{ 0xa204, 0x402d0031 },
{ 0xa208, 0x00165f83 },
{ 0xa20c, 0xf1000000 },
{ 0xa210, 0x00000000 },
{ 0xa214, 0x00160016 },
{ 0xa218, 0x002a002b },
{ 0xa21c, 0x00000000 },
{ 0xa220, 0x00000000 },
{ 0xa224, 0x330000a6 },
{ 0xa228, 0x402d0031 },
{ 0xa22c, 0x00165f83 },
{ 0xa230, 0xf1000000 },
{ 0xa234, 0x00000000 },
{ 0xa238, 0x00160016 },
{ 0xa23c, 0x002a002b },
{ 0xa240, 0x00000000 },
{ 0xa244, 0x00000000 },
{ 0xa248, 0x8000421e },
{ 0 }
};
static const struct gt_powermeter ivb_pm_gt1[] = {
{ 0xa800, 0x00000000 },
{ 0xa804, 0x00021c00 },
{ 0xa808, 0x00000403 },
{ 0xa80c, 0x02001700 },
{ 0xa810, 0x05000200 },
{ 0xa814, 0x00000000 },
{ 0xa818, 0x00690500 },
{ 0xa81c, 0x0000007f },
{ 0xa820, 0x01002501 },
{ 0xa824, 0x00000300 },
{ 0xa828, 0x01000331 },
{ 0xa82c, 0x0000000c },
{ 0xa830, 0x00010016 },
{ 0xa834, 0x01100101 },
{ 0xa838, 0x00010103 },
{ 0xa83c, 0x00041300 },
{ 0xa840, 0x00000b30 },
{ 0xa844, 0x00000000 },
{ 0xa848, 0x7f000000 },
{ 0xa84c, 0x05000008 },
{ 0xa850, 0x00000001 },
{ 0xa854, 0x00000004 },
{ 0xa858, 0x00000007 },
{ 0xa85c, 0x00000000 },
{ 0xa860, 0x00010000 },
{ 0xa248, 0x0000221e },
{ 0xa900, 0x00000000 },
{ 0xa904, 0x00001c00 },
{ 0xa908, 0x00000000 },
{ 0xa90c, 0x06000000 },
{ 0xa910, 0x09000200 },
{ 0xa914, 0x00000000 },
{ 0xa918, 0x00590000 },
{ 0xa91c, 0x00000000 },
{ 0xa920, 0x04002501 },
{ 0xa924, 0x00000100 },
{ 0xa928, 0x03000410 },
{ 0xa92c, 0x00000000 },
{ 0xa930, 0x00020000 },
{ 0xa934, 0x02070106 },
{ 0xa938, 0x00010100 },
{ 0xa93c, 0x00401c00 },
{ 0xa940, 0x00000000 },
{ 0xa944, 0x00000000 },
{ 0xa948, 0x10000e00 },
{ 0xa94c, 0x02000004 },
{ 0xa950, 0x00000001 },
{ 0xa954, 0x00000004 },
{ 0xa960, 0x00060000 },
{ 0xaa3c, 0x00001c00 },
{ 0xaa54, 0x00000004 },
{ 0xaa60, 0x00060000 },
{ 0 }
};
static const struct gt_powermeter ivb_pm_gt2[] = {
{ 0xa800, 0x10000000 },
{ 0xa804, 0x00033800 },
{ 0xa808, 0x00000902 },
{ 0xa80c, 0x0c002f00 },
{ 0xa810, 0x12000400 },
{ 0xa814, 0x00000000 },
{ 0xa818, 0x00d20800 },
{ 0xa81c, 0x00000002 },
{ 0xa820, 0x03004b02 },
{ 0xa824, 0x00000600 },
{ 0xa828, 0x07000773 },
{ 0xa82c, 0x00000000 },
{ 0xa830, 0x00010032 },
{ 0xa834, 0x1520040d },
{ 0xa838, 0x00020105 },
{ 0xa83c, 0x00083700 },
{ 0xa840, 0x0000151d },
{ 0xa844, 0x00000000 },
{ 0xa848, 0x20001b00 },
{ 0xa84c, 0x0a000010 },
{ 0xa850, 0x00000000 },
{ 0xa854, 0x00000008 },
{ 0xa858, 0x00000008 },
{ 0xa85c, 0x00000000 },
{ 0xa860, 0x00020000 },
{ 0xa248, 0x0000221e },
{ 0xa900, 0x00000000 },
{ 0xa904, 0x00003500 },
{ 0xa908, 0x00000000 },
{ 0xa90c, 0x0c000000 },
{ 0xa910, 0x12000500 },
{ 0xa914, 0x00000000 },
{ 0xa918, 0x00b20000 },
{ 0xa91c, 0x00000000 },
{ 0xa920, 0x08004b02 },
{ 0xa924, 0x00000200 },
{ 0xa928, 0x07000820 },
{ 0xa92c, 0x00000000 },
{ 0xa930, 0x00030000 },
{ 0xa934, 0x050f020d },
{ 0xa938, 0x00020300 },
{ 0xa93c, 0x00903900 },
{ 0xa940, 0x00000000 },
{ 0xa944, 0x00000000 },
{ 0xa948, 0x20001b00 },
{ 0xa94c, 0x0a000010 },
{ 0xa950, 0x00000000 },
{ 0xa954, 0x00000008 },
{ 0xa960, 0x00110000 },
{ 0xaa3c, 0x00003900 },
{ 0xaa54, 0x00000008 },
{ 0xaa60, 0x00110000 },
{ 0 }
};
static const struct gt_powermeter ivb_pm_gt2_17w[] = {
{ 0xa800, 0x20000000 },
{ 0xa804, 0x000e3800 },
{ 0xa808, 0x00000806 },
{ 0xa80c, 0x0c002f00 },
{ 0xa810, 0x0c000800 },
{ 0xa814, 0x00000000 },
{ 0xa818, 0x00d20d00 },
{ 0xa81c, 0x000000ff },
{ 0xa820, 0x03004b02 },
{ 0xa824, 0x00000600 },
{ 0xa828, 0x07000773 },
{ 0xa82c, 0x00000000 },
{ 0xa830, 0x00020032 },
{ 0xa834, 0x1520040d },
{ 0xa838, 0x00020105 },
{ 0xa83c, 0x00083700 },
{ 0xa840, 0x000016ff },
{ 0xa844, 0x00000000 },
{ 0xa848, 0xff000000 },
{ 0xa84c, 0x0a000010 },
{ 0xa850, 0x00000002 },
{ 0xa854, 0x00000008 },
{ 0xa858, 0x0000000f },
{ 0xa85c, 0x00000000 },
{ 0xa860, 0x00020000 },
{ 0xa248, 0x0000221e },
{ 0xa900, 0x00000000 },
{ 0xa904, 0x00003800 },
{ 0xa908, 0x00000000 },
{ 0xa90c, 0x0c000000 },
{ 0xa910, 0x12000800 },
{ 0xa914, 0x00000000 },
{ 0xa918, 0x00b20000 },
{ 0xa91c, 0x00000000 },
{ 0xa920, 0x08004b02 },
{ 0xa924, 0x00000300 },
{ 0xa928, 0x01000820 },
{ 0xa92c, 0x00000000 },
{ 0xa930, 0x00030000 },
{ 0xa934, 0x15150406 },
{ 0xa938, 0x00020300 },
{ 0xa93c, 0x00903900 },
{ 0xa940, 0x00000000 },
{ 0xa944, 0x00000000 },
{ 0xa948, 0x20001b00 },
{ 0xa94c, 0x0a000010 },
{ 0xa950, 0x00000000 },
{ 0xa954, 0x00000008 },
{ 0xa960, 0x00110000 },
{ 0xaa3c, 0x00003900 },
{ 0xaa54, 0x00000008 },
{ 0xaa60, 0x00110000 },
{ 0 }
};
static const struct gt_powermeter ivb_pm_gt2_35w[] = {
{ 0xa800, 0x00000000 },
{ 0xa804, 0x00030400 },
{ 0xa808, 0x00000806 },
{ 0xa80c, 0x0c002f00 },
{ 0xa810, 0x0c000300 },
{ 0xa814, 0x00000000 },
{ 0xa818, 0x00d20d00 },
{ 0xa81c, 0x000000ff },
{ 0xa820, 0x03004b02 },
{ 0xa824, 0x00000600 },
{ 0xa828, 0x07000773 },
{ 0xa82c, 0x00000000 },
{ 0xa830, 0x00020032 },
{ 0xa834, 0x1520040d },
{ 0xa838, 0x00020105 },
{ 0xa83c, 0x00083700 },
{ 0xa840, 0x000016ff },
{ 0xa844, 0x00000000 },
{ 0xa848, 0xff000000 },
{ 0xa84c, 0x0a000010 },
{ 0xa850, 0x00000001 },
{ 0xa854, 0x00000008 },
{ 0xa858, 0x00000008 },
{ 0xa85c, 0x00000000 },
{ 0xa860, 0x00020000 },
{ 0xa248, 0x0000221e },
{ 0xa900, 0x00000000 },
{ 0xa904, 0x00003800 },
{ 0xa908, 0x00000000 },
{ 0xa90c, 0x0c000000 },
{ 0xa910, 0x12000800 },
{ 0xa914, 0x00000000 },
{ 0xa918, 0x00b20000 },
{ 0xa91c, 0x00000000 },
{ 0xa920, 0x08004b02 },
{ 0xa924, 0x00000300 },
{ 0xa928, 0x01000820 },
{ 0xa92c, 0x00000000 },
{ 0xa930, 0x00030000 },
{ 0xa934, 0x15150406 },
{ 0xa938, 0x00020300 },
{ 0xa93c, 0x00903900 },
{ 0xa940, 0x00000000 },
{ 0xa944, 0x00000000 },
{ 0xa948, 0x20001b00 },
{ 0xa94c, 0x0a000010 },
{ 0xa950, 0x00000000 },
{ 0xa954, 0x00000008 },
{ 0xa960, 0x00110000 },
{ 0xaa3c, 0x00003900 },
{ 0xaa54, 0x00000008 },
{ 0xaa60, 0x00110000 },
{ 0 }
};
/*
* Some vga option roms are used for several chipsets but they only have one
* PCI ID in their header. If we encounter such an option rom, we need to do
* the mapping ourselves.
*/
u32 map_oprom_vendev(u32 vendev)
{
u32 new_vendev = vendev;
switch (vendev) {
case 0x80860102: /* GT1 Desktop */
case 0x8086010a: /* GT1 Server */
case 0x80860112: /* GT2 Desktop */
case 0x80860116: /* GT2 Mobile */
case 0x80860122: /* GT2 Desktop >=1.3GHz */
case 0x80860126: /* GT2 Mobile >=1.3GHz */
case 0x80860156: /* IVB */
case 0x80860166: /* IVB */
/* Set to GT1 Mobile */
new_vendev = 0x80860106;
break;
}
return new_vendev;
}
static inline u32 gtt_read(void *bar, u32 reg)
{
return readl(bar + reg);
}
static inline void gtt_write(void *bar, u32 reg, u32 data)
{
writel(data, bar + reg);
}
static void gtt_write_powermeter(void *bar, const struct gt_powermeter *pm)
{
for (; pm && pm->reg; pm++)
gtt_write(bar, pm->reg, pm->value);
}
#define GTT_RETRY 1000
static int gtt_poll(void *bar, u32 reg, u32 mask, u32 value)
{
unsigned try = GTT_RETRY;
u32 data;
while (try--) {
data = gtt_read(bar, reg);
if ((data & mask) == value)
return 1;
udelay(10);
}
printf("GT init timeout\n");
return 0;
}
static int gma_pm_init_pre_vbios(void *gtt_bar)
{
u32 reg32;
debug("GT Power Management Init, silicon = %#x\n",
bridge_silicon_revision());
if (bridge_silicon_revision() < IVB_STEP_C0) {
/* 1: Enable force wake */
gtt_write(gtt_bar, 0xa18c, 0x00000001);
gtt_poll(gtt_bar, 0x130090, (1 << 0), (1 << 0));
} else {
gtt_write(gtt_bar, 0xa180, 1 << 5);
gtt_write(gtt_bar, 0xa188, 0xffff0001);
gtt_poll(gtt_bar, 0x130040, (1 << 0), (1 << 0));
}
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
/* 1d: Set GTT+0x42004 [15:14]=11 (SnB C1+) */
reg32 = gtt_read(gtt_bar, 0x42004);
reg32 |= (1 << 14) | (1 << 15);
gtt_write(gtt_bar, 0x42004, reg32);
}
if (bridge_silicon_revision() >= IVB_STEP_A0) {
/* Display Reset Acknowledge Settings */
reg32 = gtt_read(gtt_bar, 0x45010);
reg32 |= (1 << 1) | (1 << 0);
gtt_write(gtt_bar, 0x45010, reg32);
}
/* 2: Get GT SKU from GTT+0x911c[13] */
reg32 = gtt_read(gtt_bar, 0x911c);
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
if (reg32 & (1 << 13)) {
debug("SNB GT1 Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, snb_pm_gt1);
} else {
debug("SNB GT2 Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, snb_pm_gt2);
}
} else {
u32 unit = readl(MCHBAR_REG(0x5938)) & 0xf;
if (reg32 & (1 << 13)) {
/* GT1 SKU */
debug("IVB GT1 Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, ivb_pm_gt1);
} else {
/* GT2 SKU */
u32 tdp = readl(MCHBAR_REG(0x5930)) & 0x7fff;
tdp /= (1 << unit);
if (tdp <= 17) {
/* <=17W ULV */
debug("IVB GT2 17W Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, ivb_pm_gt2_17w);
} else if ((tdp >= 25) && (tdp <= 35)) {
/* 25W-35W */
debug("IVB GT2 25W-35W Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, ivb_pm_gt2_35w);
} else {
/* All others */
debug("IVB GT2 35W Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, ivb_pm_gt2_35w);
}
}
}
/* 3: Gear ratio map */
gtt_write(gtt_bar, 0xa004, 0x00000010);
/* 4: GFXPAUSE */
gtt_write(gtt_bar, 0xa000, 0x00070020);
/* 5: Dynamic EU trip control */
gtt_write(gtt_bar, 0xa080, 0x00000004);
/* 6: ECO bits */
reg32 = gtt_read(gtt_bar, 0xa180);
reg32 |= (1 << 26) | (1 << 31);
/* (bit 20=1 for SNB step D1+ / IVB A0+) */
if (bridge_silicon_revision() >= SNB_STEP_D1)
reg32 |= (1 << 20);
gtt_write(gtt_bar, 0xa180, reg32);
/* 6a: for SnB step D2+ only */
if (((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) &&
(bridge_silicon_revision() >= SNB_STEP_D2)) {
reg32 = gtt_read(gtt_bar, 0x9400);
reg32 |= (1 << 7);
gtt_write(gtt_bar, 0x9400, reg32);
reg32 = gtt_read(gtt_bar, 0x941c);
reg32 &= 0xf;
reg32 |= (1 << 1);
gtt_write(gtt_bar, 0x941c, reg32);
gtt_poll(gtt_bar, 0x941c, (1 << 1), (0 << 1));
}
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
reg32 = gtt_read(gtt_bar, 0x907c);
reg32 |= (1 << 16);
gtt_write(gtt_bar, 0x907c, reg32);
/* 6b: Clocking reset controls */
gtt_write(gtt_bar, 0x9424, 0x00000001);
} else {
/* 6b: Clocking reset controls */
gtt_write(gtt_bar, 0x9424, 0x00000000);
}
/* 7 */
if (gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31))) {
gtt_write(gtt_bar, 0x138128, 0x00000029); /* Mailbox Data */
/* Mailbox Cmd for RC6 VID */
gtt_write(gtt_bar, 0x138124, 0x80000004);
if (gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31)))
gtt_write(gtt_bar, 0x138124, 0x8000000a);
gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31));
}
/* 8 */
gtt_write(gtt_bar, 0xa090, 0x00000000); /* RC Control */
gtt_write(gtt_bar, 0xa098, 0x03e80000); /* RC1e Wake Rate Limit */
gtt_write(gtt_bar, 0xa09c, 0x0028001e); /* RC6/6p Wake Rate Limit */
gtt_write(gtt_bar, 0xa0a0, 0x0000001e); /* RC6pp Wake Rate Limit */
gtt_write(gtt_bar, 0xa0a8, 0x0001e848); /* RC Evaluation Interval */
gtt_write(gtt_bar, 0xa0ac, 0x00000019); /* RC Idle Hysteresis */
/* 9 */
gtt_write(gtt_bar, 0x2054, 0x0000000a); /* Render Idle Max Count */
gtt_write(gtt_bar, 0x12054, 0x0000000a); /* Video Idle Max Count */
gtt_write(gtt_bar, 0x22054, 0x0000000a); /* Blitter Idle Max Count */
/* 10 */
gtt_write(gtt_bar, 0xa0b0, 0x00000000); /* Unblock Ack to Busy */
gtt_write(gtt_bar, 0xa0b4, 0x000003e8); /* RC1e Threshold */
gtt_write(gtt_bar, 0xa0b8, 0x0000c350); /* RC6 Threshold */
gtt_write(gtt_bar, 0xa0bc, 0x000186a0); /* RC6p Threshold */
gtt_write(gtt_bar, 0xa0c0, 0x0000fa00); /* RC6pp Threshold */
/* 11 */
gtt_write(gtt_bar, 0xa010, 0x000f4240); /* RP Down Timeout */
gtt_write(gtt_bar, 0xa014, 0x12060000); /* RP Interrupt Limits */
gtt_write(gtt_bar, 0xa02c, 0x00015f90); /* RP Up Threshold */
gtt_write(gtt_bar, 0xa030, 0x000186a0); /* RP Down Threshold */
gtt_write(gtt_bar, 0xa068, 0x000186a0); /* RP Up EI */
gtt_write(gtt_bar, 0xa06c, 0x000493e0); /* RP Down EI */
gtt_write(gtt_bar, 0xa070, 0x0000000a); /* RP Idle Hysteresis */
/* 11a: Enable Render Standby (RC6) */
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
/*
* IvyBridge should also support DeepRenderStandby.
*
* Unfortunately it does not work reliably on all SKUs so
* disable it here and it can be enabled by the kernel.
*/
gtt_write(gtt_bar, 0xa090, 0x88040000); /* HW RC Control */
} else {
gtt_write(gtt_bar, 0xa090, 0x88040000); /* HW RC Control */
}
/* 12: Normal Frequency Request */
/* RPNFREQ_VAL comes from MCHBAR 0x5998 23:16 (8 bits!? use 7) */
reg32 = readl(MCHBAR_REG(0x5998));
reg32 >>= 16;
reg32 &= 0xef;
reg32 <<= 25;
gtt_write(gtt_bar, 0xa008, reg32);
/* 13: RP Control */
gtt_write(gtt_bar, 0xa024, 0x00000592);
/* 14: Enable PM Interrupts */
gtt_write(gtt_bar, 0x4402c, 0x03000076);
/* Clear 0x6c024 [8:6] */
reg32 = gtt_read(gtt_bar, 0x6c024);
reg32 &= ~0x000001c0;
gtt_write(gtt_bar, 0x6c024, reg32);
return 0;
}
int gma_pm_init_post_vbios(void *gtt_bar, const void *blob, int node)
{
u32 reg32, cycle_delay;
debug("GT Power Management Init (post VBIOS)\n");
/* 15: Deassert Force Wake */
if (bridge_silicon_revision() < IVB_STEP_C0) {
gtt_write(gtt_bar, 0xa18c, gtt_read(gtt_bar, 0xa18c) & ~1);
gtt_poll(gtt_bar, 0x130090, (1 << 0), (0 << 0));
} else {
gtt_write(gtt_bar, 0xa188, 0x1fffe);
if (gtt_poll(gtt_bar, 0x130040, (1 << 0), (0 << 0))) {
gtt_write(gtt_bar, 0xa188,
gtt_read(gtt_bar, 0xa188) | 1);
}
}
/* 16: SW RC Control */
gtt_write(gtt_bar, 0xa094, 0x00060000);
/* Setup Digital Port Hotplug */
reg32 = gtt_read(gtt_bar, 0xc4030);
if (!reg32) {
u32 dp_hotplug[3];
if (fdtdec_get_int_array(blob, node, "intel,dp_hotplug",
dp_hotplug, ARRAY_SIZE(dp_hotplug)))
return -EINVAL;
reg32 = (dp_hotplug[0] & 0x7) << 2;
reg32 |= (dp_hotplug[0] & 0x7) << 10;
reg32 |= (dp_hotplug[0] & 0x7) << 18;
gtt_write(gtt_bar, 0xc4030, reg32);
}
/* Setup Panel Power On Delays */
reg32 = gtt_read(gtt_bar, 0xc7208);
if (!reg32) {
reg32 = (unsigned)fdtdec_get_int(blob, node,
"panel-port-select", 0) << 30;
reg32 |= fdtdec_get_int(blob, node, "panel-power-up-delay", 0)
<< 16;
reg32 |= fdtdec_get_int(blob, node,
"panel-power-backlight-on-delay", 0);
gtt_write(gtt_bar, 0xc7208, reg32);
}
/* Setup Panel Power Off Delays */
reg32 = gtt_read(gtt_bar, 0xc720c);
if (!reg32) {
reg32 = fdtdec_get_int(blob, node, "panel-power-down-delay", 0)
<< 16;
reg32 |= fdtdec_get_int(blob, node,
"panel-power-backlight-off-delay", 0);
gtt_write(gtt_bar, 0xc720c, reg32);
}
/* Setup Panel Power Cycle Delay */
cycle_delay = fdtdec_get_int(blob, node,
"intel,panel-power-cycle-delay", 0);
if (cycle_delay) {
reg32 = gtt_read(gtt_bar, 0xc7210);
reg32 &= ~0xff;
reg32 |= cycle_delay;
gtt_write(gtt_bar, 0xc7210, reg32);
}
/* Enable Backlight if needed */
reg32 = fdtdec_get_int(blob, node, "intel,cpu-backlight", 0);
if (reg32) {
gtt_write(gtt_bar, 0x48250, (1 << 31));
gtt_write(gtt_bar, 0x48254, reg32);
}
reg32 = fdtdec_get_int(blob, node, "intel,pch-backlight", 0);
if (reg32) {
gtt_write(gtt_bar, 0xc8250, (1 << 31));
gtt_write(gtt_bar, 0xc8254, reg32);
}
return 0;
}
/*
* Some vga option roms are used for several chipsets but they only have one
* PCI ID in their header. If we encounter such an option rom, we need to do
* the mapping ourselves.
*/
uint32_t board_map_oprom_vendev(uint32_t vendev)
{
switch (vendev) {
case 0x80860102: /* GT1 Desktop */
case 0x8086010a: /* GT1 Server */
case 0x80860112: /* GT2 Desktop */
case 0x80860116: /* GT2 Mobile */
case 0x80860122: /* GT2 Desktop >=1.3GHz */
case 0x80860126: /* GT2 Mobile >=1.3GHz */
case 0x80860156: /* IVB */
case 0x80860166: /* IVB */
return 0x80860106; /* GT1 Mobile */
}
return vendev;
}
static int int15_handler(void)
{
int res = 0;
debug("%s: INT15 function %04x!\n", __func__, M.x86.R_AX);
switch (M.x86.R_AX) {
case 0x5f34:
/*
* Set Panel Fitting Hook:
* bit 2 = Graphics Stretching
* bit 1 = Text Stretching
* bit 0 = Centering (do not set with bit1 or bit2)
* 0 = video bios default
*/
M.x86.R_AX = 0x005f;
M.x86.R_CL = 0x00; /* Use video bios default */
res = 1;
break;
case 0x5f35:
/*
* Boot Display Device Hook:
* bit 0 = CRT
* bit 1 = TV (eDP)
* bit 2 = EFP
* bit 3 = LFP
* bit 4 = CRT2
* bit 5 = TV2 (eDP)
* bit 6 = EFP2
* bit 7 = LFP2
*/
M.x86.R_AX = 0x005f;
M.x86.R_CX = 0x0000; /* Use video bios default */
res = 1;
break;
case 0x5f51:
/*
* Hook to select active LFP configuration:
* 00h = No LVDS, VBIOS does not enable LVDS
* 01h = Int-LVDS, LFP driven by integrated LVDS decoder
* 02h = SVDO-LVDS, LFP driven by SVDO decoder
* 03h = eDP, LFP Driven by Int-DisplayPort encoder
*/
M.x86.R_AX = 0x005f;
M.x86.R_CX = 0x0003; /* eDP */
res = 1;
break;
case 0x5f70:
switch (M.x86.R_CH) {
case 0:
/* Get Mux */
M.x86.R_AX = 0x005f;
M.x86.R_CX = 0x0000;
res = 1;
break;
case 1:
/* Set Mux */
M.x86.R_AX = 0x005f;
M.x86.R_CX = 0x0000;
res = 1;
break;
case 2:
/* Get SG/Non-SG mode */
M.x86.R_AX = 0x005f;
M.x86.R_CX = 0x0000;
res = 1;
break;
default:
/* Interrupt was not handled */
debug("Unknown INT15 5f70 function: 0x%02x\n",
M.x86.R_CH);
break;
}
break;
case 0x5fac:
res = 1;
break;
default:
debug("Unknown INT15 function %04x!\n", M.x86.R_AX);
break;
}
return res;
}
int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
const void *blob, int node)
{
void *gtt_bar;
u32 reg32;
int ret;
/* IGD needs to be Bus Master */
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
pci_write_config32(dev, PCI_COMMAND, reg32);
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;
ret = pci_run_vga_bios(dev, int15_handler, false);
/* Post VBIOS init */
ret = gma_pm_init_post_vbios(gtt_bar, blob, node);
if (ret)
return ret;
return 0;
}

View file

@ -0,0 +1,156 @@
/*
* From Coreboot file of the same name
*
* Copyright (C) 2012 Chromium OS Authors
*
* SPDX-License-Identifier: GPL-2.0
*/
/* mailbox 0: header */
__packed struct opregion_header {
u8 signature[16];
u32 size;
u32 version;
u8 sbios_version[32];
u8 vbios_version[16];
u8 driver_version[16];
u32 mailboxes;
u8 reserved[164];
};
#define IGD_OPREGION_SIGNATURE "IntelGraphicsMem"
#define IGD_OPREGION_VERSION 2
#define IGD_MBOX1 (1 << 0)
#define IGD_MBOX2 (1 << 1)
#define IGD_MBOX3 (1 << 2)
#define IGD_MBOX4 (1 << 3)
#define IGD_MBOX5 (1 << 4)
#define MAILBOXES_MOBILE (IGD_MBOX1 | IGD_MBOX2 | IGD_MBOX3 | \
IGD_MBOX4 | IGD_MBOX5)
#define MAILBOXES_DESKTOP (IGD_MBOX2 | IGD_MBOX4)
#define SBIOS_VERSION_SIZE 32
/* mailbox 1: public acpi methods */
__packed struct opregion_mailbox1 {
u32 drdy;
u32 csts;
u32 cevt;
u8 reserved1[20];
u32 didl[8];
u32 cpdl[8];
u32 cadl[8];
u32 nadl[8];
u32 aslp;
u32 tidx;
u32 chpd;
u32 clid;
u32 cdck;
u32 sxsw;
u32 evts;
u32 cnot;
u32 nrdy;
u8 reserved2[60];
};
/* mailbox 2: software sci interface */
__packed struct opregion_mailbox2 {
u32 scic;
u32 parm;
u32 dslp;
u8 reserved[244];
};
/* mailbox 3: power conservation */
__packed struct opregion_mailbox3 {
u32 ardy;
u32 aslc;
u32 tche;
u32 alsi;
u32 bclp;
u32 pfit;
u32 cblv;
u16 bclm[20];
u32 cpfm;
u32 epfm;
u8 plut[74];
u32 pfmb;
u32 ccdv;
u32 pcft;
u8 reserved[94];
};
#define IGD_BACKLIGHT_BRIGHTNESS 0xff
#define IGD_INITIAL_BRIGHTNESS 0x64
#define IGD_FIELD_VALID (1 << 31)
#define IGD_WORD_FIELD_VALID (1 << 15)
#define IGD_PFIT_STRETCH 6
/* mailbox 4: vbt */
__packed struct {
u8 gvd1[7168];
} opregion_vbt_t;
/* IGD OpRegion */
__packed struct igd_opregion {
opregion_header_t header;
opregion_mailbox1_t mailbox1;
opregion_mailbox2_t mailbox2;
opregion_mailbox3_t mailbox3;
opregion_vbt_t vbt;
};
/* Intel Video BIOS (Option ROM) */
__packed struct optionrom_header {
u16 signature;
u8 size;
u8 reserved[21];
u16 pcir_offset;
u16 vbt_offset;
};
#define OPROM_SIGNATURE 0xaa55
__packed struct optionrom_pcir {
u32 signature;
u16 vendor;
u16 device;
u16 reserved1;
u16 length;
u8 revision;
u8 classcode[3];
u16 imagelength;
u16 coderevision;
u8 codetype;
u8 indicator;
u16 reserved2;
};
__packed struct optionrom_vbt {
u8 hdr_signature[20];
u16 hdr_version;
u16 hdr_size;
u16 hdr_vbt_size;
u8 hdr_vbt_checksum;
u8 hdr_reserved;
u32 hdr_vbt_datablock;
u32 hdr_aim[4];
u8 datahdr_signature[16];
u16 datahdr_version;
u16 datahdr_size;
u16 datahdr_datablocksize;
u8 coreblock_id;
u16 coreblock_size;
u16 coreblock_biossize;
u8 coreblock_biostype;
u8 coreblock_releasestatus;
u8 coreblock_hwsupported;
u8 coreblock_integratedhw;
u8 coreblock_biosbuild[4];
u8 coreblock_biossignon[155];
};
#define VBT_SIGNATURE 0x54425624

View file

@ -9,10 +9,460 @@
#include <common.h>
#include <errno.h>
#include <fdtdec.h>
#include <rtc.h>
#include <pci.h>
#include <asm/acpi.h>
#include <asm/interrupt.h>
#include <asm/io.h>
#include <asm/ioapic.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
#define NMI_OFF 0
#define ENABLE_ACPI_MODE_IN_COREBOOT 0
#define TEST_SMM_FLASH_LOCKDOWN 0
static int pch_enable_apic(pci_dev_t dev)
{
u32 reg32;
int i;
/* Enable ACPI I/O and power management. Set SCI IRQ to IRQ9 */
pci_write_config8(dev, ACPI_CNTL, 0x80);
writel(0, IO_APIC_INDEX);
writel(1 << 25, IO_APIC_DATA);
/* affirm full set of redirection table entries ("write once") */
writel(1, IO_APIC_INDEX);
reg32 = readl(IO_APIC_DATA);
writel(1, IO_APIC_INDEX);
writel(reg32, IO_APIC_DATA);
writel(0, IO_APIC_INDEX);
reg32 = readl(IO_APIC_DATA);
debug("PCH APIC ID = %x\n", (reg32 >> 24) & 0x0f);
if (reg32 != (1 << 25)) {
printf("APIC Error - cannot write to registers\n");
return -EPERM;
}
debug("Dumping IOAPIC registers\n");
for (i = 0; i < 3; i++) {
writel(i, IO_APIC_INDEX);
debug(" reg 0x%04x:", i);
reg32 = readl(IO_APIC_DATA);
debug(" 0x%08x\n", reg32);
}
/* Select Boot Configuration register. */
writel(3, IO_APIC_INDEX);
/* Use Processor System Bus to deliver interrupts. */
writel(1, IO_APIC_DATA);
return 0;
}
static void pch_enable_serial_irqs(pci_dev_t dev)
{
u32 value;
/* Set packet length and toggle silent mode bit for one frame. */
value = (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0);
#ifdef CONFIG_SERIRQ_CONTINUOUS_MODE
pci_write_config8(dev, SERIRQ_CNTL, value);
#else
pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6));
#endif
}
static int pch_pirq_init(const void *blob, int node, pci_dev_t dev)
{
uint8_t route[8], *ptr;
if (fdtdec_get_byte_array(blob, node, "intel,pirq-routing", route,
sizeof(route)))
return -EINVAL;
ptr = route;
pci_write_config8(dev, PIRQA_ROUT, *ptr++);
pci_write_config8(dev, PIRQB_ROUT, *ptr++);
pci_write_config8(dev, PIRQC_ROUT, *ptr++);
pci_write_config8(dev, PIRQD_ROUT, *ptr++);
pci_write_config8(dev, PIRQE_ROUT, *ptr++);
pci_write_config8(dev, PIRQF_ROUT, *ptr++);
pci_write_config8(dev, PIRQG_ROUT, *ptr++);
pci_write_config8(dev, PIRQH_ROUT, *ptr++);
/*
* TODO(sjg@chromium.org): U-Boot does not set up the interrupts
* here. It's unclear if it is needed
*/
return 0;
}
static int pch_gpi_routing(const void *blob, int node, pci_dev_t dev)
{
u8 route[16];
u32 reg;
int gpi;
if (fdtdec_get_byte_array(blob, node, "intel,gpi-routing", route,
sizeof(route)))
return -EINVAL;
for (reg = 0, gpi = 0; gpi < ARRAY_SIZE(route); gpi++)
reg |= route[gpi] << (gpi * 2);
pci_write_config32(dev, 0xb8, reg);
return 0;
}
static int pch_power_options(const void *blob, int node, pci_dev_t dev)
{
u8 reg8;
u16 reg16, pmbase;
u32 reg32;
const char *state;
int pwr_on;
int nmi_option;
int ret;
/*
* Which state do we want to goto after g3 (power restored)?
* 0 == S0 Full On
* 1 == S5 Soft Off
*
* If the option is not existent (Laptops), use Kconfig setting.
* TODO(sjg@chromium.org): Make this configurable
*/
pwr_on = MAINBOARD_POWER_ON;
reg16 = pci_read_config16(dev, GEN_PMCON_3);
reg16 &= 0xfffe;
switch (pwr_on) {
case MAINBOARD_POWER_OFF:
reg16 |= 1;
state = "off";
break;
case MAINBOARD_POWER_ON:
reg16 &= ~1;
state = "on";
break;
case MAINBOARD_POWER_KEEP:
reg16 &= ~1;
state = "state keep";
break;
default:
state = "undefined";
}
reg16 &= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */
reg16 |= (1 << 3); /* SLP_S4# Assertion Stretch Enable */
reg16 &= ~(1 << 10);
reg16 |= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */
reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */
pci_write_config16(dev, GEN_PMCON_3, reg16);
debug("Set power %s after power failure.\n", state);
/* Set up NMI on errors. */
reg8 = inb(0x61);
reg8 &= 0x0f; /* Higher Nibble must be 0 */
reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
reg8 |= (1 << 2); /* PCI SERR# Disable for now */
outb(reg8, 0x61);
reg8 = inb(0x70);
/* TODO(sjg@chromium.org): Make this configurable */
nmi_option = NMI_OFF;
if (nmi_option) {
debug("NMI sources enabled.\n");
reg8 &= ~(1 << 7); /* Set NMI. */
} else {
debug("NMI sources disabled.\n");
/* Can't mask NMI from PCI-E and NMI_NOW */
reg8 |= (1 << 7);
}
outb(reg8, 0x70);
/* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
reg16 = pci_read_config16(dev, GEN_PMCON_1);
reg16 &= ~(3 << 0); /* SMI# rate 1 minute */
reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */
#if DEBUG_PERIODIC_SMIS
/* Set DEBUG_PERIODIC_SMIS in pch.h to debug using periodic SMIs */
reg16 |= (3 << 0); /* Periodic SMI every 8s */
#endif
pci_write_config16(dev, GEN_PMCON_1, reg16);
/* Set the board's GPI routing. */
ret = pch_gpi_routing(blob, node, dev);
if (ret)
return ret;
pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node,
"intel,gpe0-enable", 0));
writew(pmbase + ALT_GP_SMI_EN, fdtdec_get_int(blob, node,
"intel,alt-gp-smi-enable", 0));
/* Set up power management block and determine sleep mode */
reg32 = inl(pmbase + 0x04); /* PM1_CNT */
reg32 &= ~(7 << 10); /* SLP_TYP */
reg32 |= (1 << 0); /* SCI_EN */
outl(reg32, pmbase + 0x04);
/* Clear magic status bits to prevent unexpected wake */
setbits_le32(RCB_REG(0x3310), (1 << 4) | (1 << 5) | (1 << 0));
clrbits_le32(RCB_REG(0x3f02), 0xf);
return 0;
}
static void pch_rtc_init(pci_dev_t dev)
{
int rtc_failed;
u8 reg8;
reg8 = pci_read_config8(dev, GEN_PMCON_3);
rtc_failed = reg8 & RTC_BATTERY_DEAD;
if (rtc_failed) {
reg8 &= ~RTC_BATTERY_DEAD;
pci_write_config8(dev, GEN_PMCON_3, reg8);
}
debug("rtc_failed = 0x%x\n", rtc_failed);
#if CONFIG_HAVE_ACPI_RESUME
/* Avoid clearing pending interrupts and resetting the RTC control
* register in the resume path because the Linux kernel relies on
* this to know if it should restart the RTC timerqueue if the wake
* was due to the RTC alarm.
*/
if (acpi_get_slp_type() == 3)
return;
#endif
/* TODO: Handle power failure */
if (rtc_failed)
printf("RTC power failed\n");
rtc_init();
}
/* CougarPoint PCH Power Management init */
static void cpt_pm_init(pci_dev_t dev)
{
debug("CougarPoint PM init\n");
pci_write_config8(dev, 0xa9, 0x47);
setbits_le32(RCB_REG(0x2238), (1 << 6) | (1 << 0));
setbits_le32(RCB_REG(0x228c), 1 << 0);
setbits_le32(RCB_REG(0x1100), (1 << 13) | (1 << 14));
setbits_le32(RCB_REG(0x0900), 1 << 14);
writel(0xc0388400, RCB_REG(0x2304));
setbits_le32(RCB_REG(0x2314), (1 << 5) | (1 << 18));
setbits_le32(RCB_REG(0x2320), (1 << 15) | (1 << 1));
clrsetbits_le32(RCB_REG(0x3314), ~0x1f, 0xf);
writel(0x050f0000, RCB_REG(0x3318));
writel(0x04000000, RCB_REG(0x3324));
setbits_le32(RCB_REG(0x3340), 0xfffff);
setbits_le32(RCB_REG(0x3344), 1 << 1);
writel(0x0001c000, RCB_REG(0x3360));
writel(0x00061100, RCB_REG(0x3368));
writel(0x7f8fdfff, RCB_REG(0x3378));
writel(0x000003fc, RCB_REG(0x337c));
writel(0x00001000, RCB_REG(0x3388));
writel(0x0001c000, RCB_REG(0x3390));
writel(0x00000800, RCB_REG(0x33a0));
writel(0x00001000, RCB_REG(0x33b0));
writel(0x00093900, RCB_REG(0x33c0));
writel(0x24653002, RCB_REG(0x33cc));
writel(0x062108fe, RCB_REG(0x33d0));
clrsetbits_le32(RCB_REG(0x33d4), 0x0fff0fff, 0x00670060);
writel(0x01010000, RCB_REG(0x3a28));
writel(0x01010404, RCB_REG(0x3a2c));
writel(0x01041041, RCB_REG(0x3a80));
clrsetbits_le32(RCB_REG(0x3a84), 0x0000ffff, 0x00001001);
setbits_le32(RCB_REG(0x3a84), 1 << 24); /* SATA 2/3 disabled */
setbits_le32(RCB_REG(0x3a88), 1 << 0); /* SATA 4/5 disabled */
writel(0x00000001, RCB_REG(0x3a6c));
clrsetbits_le32(RCB_REG(0x2344), ~0x00ffff00, 0xff00000c);
clrsetbits_le32(RCB_REG(0x80c), 0xff << 20, 0x11 << 20);
writel(0, RCB_REG(0x33c8));
setbits_le32(RCB_REG(0x21b0), 0xf);
}
/* PantherPoint PCH Power Management init */
static void ppt_pm_init(pci_dev_t dev)
{
debug("PantherPoint PM init\n");
pci_write_config8(dev, 0xa9, 0x47);
setbits_le32(RCB_REG(0x2238), 1 << 0);
setbits_le32(RCB_REG(0x228c), 1 << 0);
setbits_le16(RCB_REG(0x1100), (1 << 13) | (1 << 14));
setbits_le16(RCB_REG(0x0900), 1 << 14);
writel(0xc03b8400, RCB_REG(0x2304));
setbits_le32(RCB_REG(0x2314), (1 << 5) | (1 << 18));
setbits_le32(RCB_REG(0x2320), (1 << 15) | (1 << 1));
clrsetbits_le32(RCB_REG(0x3314), 0x1f, 0xf);
writel(0x054f0000, RCB_REG(0x3318));
writel(0x04000000, RCB_REG(0x3324));
setbits_le32(RCB_REG(0x3340), 0xfffff);
setbits_le32(RCB_REG(0x3344), (1 << 1) | (1 << 0));
writel(0x0001c000, RCB_REG(0x3360));
writel(0x00061100, RCB_REG(0x3368));
writel(0x7f8fdfff, RCB_REG(0x3378));
writel(0x000003fd, RCB_REG(0x337c));
writel(0x00001000, RCB_REG(0x3388));
writel(0x0001c000, RCB_REG(0x3390));
writel(0x00000800, RCB_REG(0x33a0));
writel(0x00001000, RCB_REG(0x33b0));
writel(0x00093900, RCB_REG(0x33c0));
writel(0x24653002, RCB_REG(0x33cc));
writel(0x067388fe, RCB_REG(0x33d0));
clrsetbits_le32(RCB_REG(0x33d4), 0x0fff0fff, 0x00670060);
writel(0x01010000, RCB_REG(0x3a28));
writel(0x01010404, RCB_REG(0x3a2c));
writel(0x01040000, RCB_REG(0x3a80));
clrsetbits_le32(RCB_REG(0x3a84), 0x0000ffff, 0x00001001);
/* SATA 2/3 disabled */
setbits_le32(RCB_REG(0x3a84), 1 << 24);
/* SATA 4/5 disabled */
setbits_le32(RCB_REG(0x3a88), 1 << 0);
writel(0x00000001, RCB_REG(0x3a6c));
clrsetbits_le32(RCB_REG(0x2344), 0xff0000ff, 0xff00000c);
clrsetbits_le32(RCB_REG(0x80c), 0xff << 20, 0x11 << 20);
setbits_le32(RCB_REG(0x33a4), (1 << 0));
writel(0, RCB_REG(0x33c8));
setbits_le32(RCB_REG(0x21b0), 0xf);
}
static void enable_hpet(void)
{
/* Move HPET to default address 0xfed00000 and enable it */
clrsetbits_le32(RCB_REG(HPTC), 3 << 0, 1 << 7);
}
static void enable_clock_gating(pci_dev_t dev)
{
u32 reg32;
u16 reg16;
setbits_le32(RCB_REG(0x2234), 0xf);
reg16 = pci_read_config16(dev, GEN_PMCON_1);
reg16 |= (1 << 2) | (1 << 11);
pci_write_config16(dev, GEN_PMCON_1, reg16);
pch_iobp_update(0xEB007F07, ~0UL, (1 << 31));
pch_iobp_update(0xEB004000, ~0UL, (1 << 7));
pch_iobp_update(0xEC007F07, ~0UL, (1 << 31));
pch_iobp_update(0xEC004000, ~0UL, (1 << 7));
reg32 = readl(RCB_REG(CG));
reg32 |= (1 << 31);
reg32 |= (1 << 29) | (1 << 28);
reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
reg32 |= (1 << 16);
reg32 |= (1 << 17);
reg32 |= (1 << 18);
reg32 |= (1 << 22);
reg32 |= (1 << 23);
reg32 &= ~(1 << 20);
reg32 |= (1 << 19);
reg32 |= (1 << 0);
reg32 |= (0xf << 1);
writel(reg32, RCB_REG(CG));
setbits_le32(RCB_REG(0x38c0), 0x7);
setbits_le32(RCB_REG(0x36d4), 0x6680c004);
setbits_le32(RCB_REG(0x3564), 0x3);
}
#if CONFIG_HAVE_SMI_HANDLER
static void pch_lock_smm(pci_dev_t dev)
{
#if TEST_SMM_FLASH_LOCKDOWN
u8 reg8;
#endif
if (acpi_slp_type != 3) {
#if ENABLE_ACPI_MODE_IN_COREBOOT
debug("Enabling ACPI via APMC:\n");
outb(0xe1, 0xb2); /* Enable ACPI mode */
debug("done.\n");
#else
debug("Disabling ACPI via APMC:\n");
outb(0x1e, 0xb2); /* Disable ACPI mode */
debug("done.\n");
#endif
}
/* Don't allow evil boot loaders, kernels, or
* userspace applications to deceive us:
*/
smm_lock();
#if TEST_SMM_FLASH_LOCKDOWN
/* Now try this: */
debug("Locking BIOS to RO... ");
reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
(reg8 & 1) ? "rw" : "ro");
reg8 &= ~(1 << 0); /* clear BIOSWE */
pci_write_config8(dev, 0xdc, reg8);
reg8 |= (1 << 1); /* set BLE */
pci_write_config8(dev, 0xdc, reg8);
debug("ok.\n");
reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
(reg8 & 1) ? "rw" : "ro");
debug("Writing:\n");
writeb(0, 0xfff00000);
debug("Testing:\n");
reg8 |= (1 << 0); /* set BIOSWE */
pci_write_config8(dev, 0xdc, reg8);
reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
(reg8 & 1) ? "rw" : "ro");
debug("Done.\n");
#endif
}
#endif
static void pch_disable_smm_only_flashing(pci_dev_t dev)
{
u8 reg8;
debug("Enabling BIOS updates outside of SMM... ");
reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
reg8 &= ~(1 << 5);
pci_write_config8(dev, 0xdc, reg8);
}
static void pch_fixups(pci_dev_t dev)
{
u8 gen_pmcon_2;
/* Indicate DRAM init done for MRC S3 to know it can resume */
gen_pmcon_2 = pci_read_config8(dev, GEN_PMCON_2);
gen_pmcon_2 |= (1 << 7);
pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
/* Enable DMI ASPM in the PCH */
clrbits_le32(RCB_REG(0x2304), 1 << 10);
setbits_le32(RCB_REG(0x21a4), (1 << 11) | (1 << 10));
setbits_le32(RCB_REG(0x21a8), 0x3);
}
int lpc_early_init(const void *blob, int node, pci_dev_t dev)
{
struct reg_info {
@ -22,7 +472,7 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
int count;
int i;
count = fdtdec_get_int_array_count(blob, node, "gen-dec",
count = fdtdec_get_int_array_count(blob, node, "intel,gen-dec",
(u32 *)values, sizeof(values) / sizeof(u32));
if (count < 0)
return -EINVAL;
@ -46,3 +496,74 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
return 0;
}
int lpc_init(struct pci_controller *hose, pci_dev_t dev)
{
const void *blob = gd->fdt_blob;
int node;
debug("pch: lpc_init\n");
pci_write_bar32(hose, dev, 0, 0);
pci_write_bar32(hose, dev, 1, 0xff800000);
pci_write_bar32(hose, dev, 2, 0xfec00000);
pci_write_bar32(hose, dev, 3, 0x800);
pci_write_bar32(hose, dev, 4, 0x900);
node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC);
if (node < 0)
return -ENOENT;
/* Set the value for PCI command register. */
pci_write_config16(dev, PCI_COMMAND, 0x000f);
/* IO APIC initialization. */
pch_enable_apic(dev);
pch_enable_serial_irqs(dev);
/* Setup the PIRQ. */
pch_pirq_init(blob, node, dev);
/* Setup power options. */
pch_power_options(blob, node, dev);
/* Initialize power management */
switch (pch_silicon_type()) {
case PCH_TYPE_CPT: /* CougarPoint */
cpt_pm_init(dev);
break;
case PCH_TYPE_PPT: /* PantherPoint */
ppt_pm_init(dev);
break;
default:
printf("Unknown Chipset: %#02x.%dx\n", PCI_DEV(dev),
PCI_FUNC(dev));
return -ENOSYS;
}
/* Initialize the real time clock. */
pch_rtc_init(dev);
/* Initialize the High Precision Event Timers, if present. */
enable_hpet();
/* Initialize Clock Gating */
enable_clock_gating(dev);
pch_disable_smm_only_flashing(dev);
#if CONFIG_HAVE_SMI_HANDLER
pch_lock_smm(dev);
#endif
pch_fixups(dev);
return 0;
}
void lpc_enable(pci_dev_t dev)
{
/* Enable PCH Display Port */
writew(0x0010, RCB_REG(DISPBDF));
setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF);
}

View file

@ -0,0 +1,514 @@
/*
* From Coreboot file of same name
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 The Chromium Authors
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <fdtdec.h>
#include <malloc.h>
#include <asm/acpi.h>
#include <asm/cpu.h>
#include <asm/lapic.h>
#include <asm/lapic_def.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
#include <asm/processor.h>
#include <asm/speedstep.h>
#include <asm/turbo.h>
#include <asm/arch/model_206ax.h>
static void enable_vmx(void)
{
struct cpuid_result regs;
#ifdef CONFIG_ENABLE_VMX
int enable = true;
#else
int enable = false;
#endif
msr_t msr;
regs = cpuid(1);
/* Check that the VMX is supported before reading or writing the MSR. */
if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX)))
return;
msr = msr_read(MSR_IA32_FEATURE_CONTROL);
if (msr.lo & (1 << 0)) {
debug("VMX is locked, so %s will do nothing\n", __func__);
/* VMX locked. If we set it again we get an illegal
* instruction
*/
return;
}
/* The IA32_FEATURE_CONTROL MSR may initialize with random values.
* It must be cleared regardless of VMX config setting.
*/
msr.hi = 0;
msr.lo = 0;
debug("%s VMX\n", enable ? "Enabling" : "Disabling");
/*
* Even though the Intel manual says you must set the lock bit in
* addition to the VMX bit in order for VMX to work, it is incorrect.
* Thus we leave it unlocked for the OS to manage things itself.
* This is good for a few reasons:
* - No need to reflash the bios just to toggle the lock bit.
* - The VMX bits really really should match each other across cores,
* so hard locking it on one while another has the opposite setting
* can easily lead to crashes as code using VMX migrates between
* them.
* - Vendors that want to "upsell" from a bios that disables+locks to
* one that doesn't is sleazy.
* By leaving this to the OS (e.g. Linux), people can do exactly what
* they want on the fly, and do it correctly (e.g. across multiple
* cores).
*/
if (enable) {
msr.lo |= (1 << 2);
if (regs.ecx & CPUID_SMX)
msr.lo |= (1 << 1);
}
msr_write(MSR_IA32_FEATURE_CONTROL, msr);
}
/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
static const u8 power_limit_time_sec_to_msr[] = {
[0] = 0x00,
[1] = 0x0a,
[2] = 0x0b,
[3] = 0x4b,
[4] = 0x0c,
[5] = 0x2c,
[6] = 0x4c,
[7] = 0x6c,
[8] = 0x0d,
[10] = 0x2d,
[12] = 0x4d,
[14] = 0x6d,
[16] = 0x0e,
[20] = 0x2e,
[24] = 0x4e,
[28] = 0x6e,
[32] = 0x0f,
[40] = 0x2f,
[48] = 0x4f,
[56] = 0x6f,
[64] = 0x10,
[80] = 0x30,
[96] = 0x50,
[112] = 0x70,
[128] = 0x11,
};
/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
static const u8 power_limit_time_msr_to_sec[] = {
[0x00] = 0,
[0x0a] = 1,
[0x0b] = 2,
[0x4b] = 3,
[0x0c] = 4,
[0x2c] = 5,
[0x4c] = 6,
[0x6c] = 7,
[0x0d] = 8,
[0x2d] = 10,
[0x4d] = 12,
[0x6d] = 14,
[0x0e] = 16,
[0x2e] = 20,
[0x4e] = 24,
[0x6e] = 28,
[0x0f] = 32,
[0x2f] = 40,
[0x4f] = 48,
[0x6f] = 56,
[0x10] = 64,
[0x30] = 80,
[0x50] = 96,
[0x70] = 112,
[0x11] = 128,
};
int cpu_config_tdp_levels(void)
{
struct cpuid_result result;
msr_t platform_info;
/* Minimum CPU revision */
result = cpuid(1);
if (result.eax < IVB_CONFIG_TDP_MIN_CPUID)
return 0;
/* Bits 34:33 indicate how many levels supported */
platform_info = msr_read(MSR_PLATFORM_INFO);
return (platform_info.hi >> 1) & 3;
}
/*
* Configure processor power limits if possible
* This must be done AFTER set of BIOS_RESET_CPL
*/
void set_power_limits(u8 power_limit_1_time)
{
msr_t msr = msr_read(MSR_PLATFORM_INFO);
msr_t limit;
unsigned power_unit;
unsigned tdp, min_power, max_power, max_time;
u8 power_limit_1_val;
if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr))
return;
if (!(msr.lo & PLATFORM_INFO_SET_TDP))
return;
/* Get units */
msr = msr_read(MSR_PKG_POWER_SKU_UNIT);
power_unit = 2 << ((msr.lo & 0xf) - 1);
/* Get power defaults for this SKU */
msr = msr_read(MSR_PKG_POWER_SKU);
tdp = msr.lo & 0x7fff;
min_power = (msr.lo >> 16) & 0x7fff;
max_power = msr.hi & 0x7fff;
max_time = (msr.hi >> 16) & 0x7f;
debug("CPU TDP: %u Watts\n", tdp / power_unit);
if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time)
power_limit_1_time = power_limit_time_msr_to_sec[max_time];
if (min_power > 0 && tdp < min_power)
tdp = min_power;
if (max_power > 0 && tdp > max_power)
tdp = max_power;
power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time];
/* Set long term power limit to TDP */
limit.lo = 0;
limit.lo |= tdp & PKG_POWER_LIMIT_MASK;
limit.lo |= PKG_POWER_LIMIT_EN;
limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) <<
PKG_POWER_LIMIT_TIME_SHIFT;
/* Set short term power limit to 1.25 * TDP */
limit.hi = 0;
limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK;
limit.hi |= PKG_POWER_LIMIT_EN;
/* Power limit 2 time is only programmable on SNB EP/EX */
msr_write(MSR_PKG_POWER_LIMIT, limit);
/* Use nominal TDP values for CPUs with configurable TDP */
if (cpu_config_tdp_levels()) {
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
limit.hi = 0;
limit.lo = msr.lo & 0xff;
msr_write(MSR_TURBO_ACTIVATION_RATIO, limit);
}
}
static void configure_c_states(void)
{
struct cpuid_result result;
msr_t msr;
msr = msr_read(MSR_PMG_CST_CONFIG_CTL);
msr.lo |= (1 << 28); /* C1 Auto Undemotion Enable */
msr.lo |= (1 << 27); /* C3 Auto Undemotion Enable */
msr.lo |= (1 << 26); /* C1 Auto Demotion Enable */
msr.lo |= (1 << 25); /* C3 Auto Demotion Enable */
msr.lo &= ~(1 << 10); /* Disable IO MWAIT redirection */
msr.lo |= 7; /* No package C-state limit */
msr_write(MSR_PMG_CST_CONFIG_CTL, msr);
msr = msr_read(MSR_PMG_IO_CAPTURE_ADR);
msr.lo &= ~0x7ffff;
msr.lo |= (PMB0_BASE + 4); /* LVL_2 base address */
msr.lo |= (2 << 16); /* CST Range: C7 is max C-state */
msr_write(MSR_PMG_IO_CAPTURE_ADR, msr);
msr = msr_read(MSR_MISC_PWR_MGMT);
msr.lo &= ~(1 << 0); /* Enable P-state HW_ALL coordination */
msr_write(MSR_MISC_PWR_MGMT, msr);
msr = msr_read(MSR_POWER_CTL);
msr.lo |= (1 << 18); /* Enable Energy Perf Bias MSR 0x1b0 */
msr.lo |= (1 << 1); /* C1E Enable */
msr.lo |= (1 << 0); /* Bi-directional PROCHOT# */
msr_write(MSR_POWER_CTL, msr);
/* C3 Interrupt Response Time Limit */
msr.hi = 0;
msr.lo = IRTL_VALID | IRTL_1024_NS | 0x50;
msr_write(MSR_PKGC3_IRTL, msr);
/* C6 Interrupt Response Time Limit */
msr.hi = 0;
msr.lo = IRTL_VALID | IRTL_1024_NS | 0x68;
msr_write(MSR_PKGC6_IRTL, msr);
/* C7 Interrupt Response Time Limit */
msr.hi = 0;
msr.lo = IRTL_VALID | IRTL_1024_NS | 0x6D;
msr_write(MSR_PKGC7_IRTL, msr);
/* Primary Plane Current Limit */
msr = msr_read(MSR_PP0_CURRENT_CONFIG);
msr.lo &= ~0x1fff;
msr.lo |= PP0_CURRENT_LIMIT;
msr_write(MSR_PP0_CURRENT_CONFIG, msr);
/* Secondary Plane Current Limit */
msr = msr_read(MSR_PP1_CURRENT_CONFIG);
msr.lo &= ~0x1fff;
result = cpuid(1);
if (result.eax >= 0x30600)
msr.lo |= PP1_CURRENT_LIMIT_IVB;
else
msr.lo |= PP1_CURRENT_LIMIT_SNB;
msr_write(MSR_PP1_CURRENT_CONFIG, msr);
}
static int configure_thermal_target(void)
{
int tcc_offset;
msr_t msr;
int node;
/* Find pointer to CPU configuration */
node = fdtdec_next_compatible(gd->fdt_blob, 0,
COMPAT_INTEL_MODEL_206AX);
if (node < 0)
return -ENOENT;
tcc_offset = fdtdec_get_int(gd->fdt_blob, node, "tcc-offset", 0);
/* Set TCC activaiton offset if supported */
msr = msr_read(MSR_PLATFORM_INFO);
if ((msr.lo & (1 << 30)) && tcc_offset) {
msr = msr_read(MSR_TEMPERATURE_TARGET);
msr.lo &= ~(0xf << 24); /* Bits 27:24 */
msr.lo |= (tcc_offset & 0xf) << 24;
msr_write(MSR_TEMPERATURE_TARGET, msr);
}
return 0;
}
static void configure_misc(void)
{
msr_t msr;
msr = msr_read(IA32_MISC_ENABLE);
msr.lo |= (1 << 0); /* Fast String enable */
msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
msr_write(IA32_MISC_ENABLE, msr);
/* Disable Thermal interrupts */
msr.lo = 0;
msr.hi = 0;
msr_write(IA32_THERM_INTERRUPT, msr);
/* Enable package critical interrupt only */
msr.lo = 1 << 4;
msr.hi = 0;
msr_write(IA32_PACKAGE_THERM_INTERRUPT, msr);
}
static void enable_lapic_tpr(void)
{
msr_t msr;
msr = msr_read(MSR_PIC_MSG_CONTROL);
msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
msr_write(MSR_PIC_MSG_CONTROL, msr);
}
static void configure_dca_cap(void)
{
struct cpuid_result cpuid_regs;
msr_t msr;
/* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
cpuid_regs = cpuid(1);
if (cpuid_regs.ecx & (1 << 18)) {
msr = msr_read(IA32_PLATFORM_DCA_CAP);
msr.lo |= 1;
msr_write(IA32_PLATFORM_DCA_CAP, msr);
}
}
static void set_max_ratio(void)
{
msr_t msr, perf_ctl;
perf_ctl.hi = 0;
/* Check for configurable TDP option */
if (cpu_config_tdp_levels()) {
/* Set to nominal TDP ratio */
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
perf_ctl.lo = (msr.lo & 0xff) << 8;
} else {
/* Platform Info bits 15:8 give max ratio */
msr = msr_read(MSR_PLATFORM_INFO);
perf_ctl.lo = msr.lo & 0xff00;
}
msr_write(IA32_PERF_CTL, perf_ctl);
debug("model_x06ax: frequency set to %d\n",
((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
}
static void set_energy_perf_bias(u8 policy)
{
msr_t msr;
/* Energy Policy is bits 3:0 */
msr = msr_read(IA32_ENERGY_PERFORMANCE_BIAS);
msr.lo &= ~0xf;
msr.lo |= policy & 0xf;
msr_write(IA32_ENERGY_PERFORMANCE_BIAS, msr);
debug("model_x06ax: energy policy set to %u\n", policy);
}
static void configure_mca(void)
{
msr_t msr;
int i;
msr.lo = 0;
msr.hi = 0;
/* This should only be done on a cold boot */
for (i = 0; i < 7; i++)
msr_write(IA32_MC0_STATUS + (i * 4), msr);
}
#if CONFIG_USBDEBUG
static unsigned ehci_debug_addr;
#endif
/*
* Initialize any extra cores/threads in this package.
*/
static int intel_cores_init(struct x86_cpu_priv *cpu)
{
struct cpuid_result result;
unsigned threads_per_package, threads_per_core, i;
/* Logical processors (threads) per core */
result = cpuid_ext(0xb, 0);
threads_per_core = result.ebx & 0xffff;
/* Logical processors (threads) per package */
result = cpuid_ext(0xb, 1);
threads_per_package = result.ebx & 0xffff;
debug("CPU: %u has %u cores, %u threads per core\n",
cpu->apic_id, threads_per_package / threads_per_core,
threads_per_core);
for (i = 1; i < threads_per_package; ++i) {
struct x86_cpu_priv *new_cpu;
new_cpu = calloc(1, sizeof(*new_cpu));
if (!new_cpu)
return -ENOMEM;
new_cpu->apic_id = cpu->apic_id + i;
/* Update APIC ID if no hyperthreading */
if (threads_per_core == 1)
new_cpu->apic_id <<= 1;
debug("CPU: %u has core %u\n", cpu->apic_id, new_cpu->apic_id);
#if CONFIG_SMP && CONFIG_MAX_CPUS > 1
/* Start the new cpu */
if (!start_cpu(new_cpu)) {
/* Record the error in cpu? */
printk(BIOS_ERR, "CPU %u would not start!\n",
new_cpu->apic_id);
new_cpu->start_err = 1;
}
#endif
}
return 0;
}
int model_206ax_init(struct x86_cpu_priv *cpu)
{
int ret;
/* Clear out pending MCEs */
configure_mca();
#if CONFIG_USBDEBUG
/* Is this caution really needed? */
if (!ehci_debug_addr)
ehci_debug_addr = get_ehci_debug();
set_ehci_debug(0);
#endif
/* Setup MTRRs based on physical address size */
#if 0 /* TODO: Implement this */
struct cpuid_result cpuid_regs;
cpuid_regs = cpuid(0x80000008);
x86_setup_fixed_mtrrs();
x86_setup_var_mtrrs(cpuid_regs.eax & 0xff, 2);
x86_mtrr_check();
#endif
#if CONFIG_USBDEBUG
set_ehci_debug(ehci_debug_addr);
#endif
/* Enable the local cpu apics */
enable_lapic_tpr();
lapic_setup();
/* Enable virtualization if enabled in CMOS */
enable_vmx();
/* Configure C States */
configure_c_states();
/* Configure Enhanced SpeedStep and Thermal Sensors */
configure_misc();
/* Thermal throttle activation offset */
ret = configure_thermal_target();
if (ret)
return ret;
/* Enable Direct Cache Access */
configure_dca_cap();
/* Set energy policy */
set_energy_perf_bias(ENERGY_POLICY_NORMAL);
/* Set Max Ratio */
set_max_ratio();
/* Enable Turbo */
turbo_enable();
/* Start up extra cores */
intel_cores_init(cpu);
return 0;
}

View file

@ -0,0 +1,188 @@
/*
* From Coreboot northbridge/intel/sandybridge/northbridge.c
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 The Chromium Authors
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/msr.h>
#include <asm/acpi.h>
#include <asm/cpu.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/processor.h>
#include <asm/arch/pch.h>
#include <asm/arch/model_206ax.h>
#include <asm/arch/sandybridge.h>
static int bridge_revision_id = -1;
int bridge_silicon_revision(void)
{
if (bridge_revision_id < 0) {
struct cpuid_result result;
uint8_t stepping, bridge_id;
pci_dev_t dev;
result = cpuid(1);
stepping = result.eax & 0xf;
dev = PCI_BDF(0, 0, 0);
bridge_id = pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0;
bridge_revision_id = bridge_id | stepping;
}
return bridge_revision_id;
}
/*
* Reserve everything between A segment and 1MB:
*
* 0xa0000 - 0xbffff: legacy VGA
* 0xc0000 - 0xcffff: VGA OPROM (needed by kernel)
* 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI
*/
static const int legacy_hole_base_k = 0xa0000 / 1024;
static const int legacy_hole_size_k = 384;
static int get_pcie_bar(u32 *base, u32 *len)
{
pci_dev_t dev = PCI_BDF(0, 0, 0);
u32 pciexbar_reg;
*base = 0;
*len = 0;
pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
if (!(pciexbar_reg & (1 << 0)))
return 0;
switch ((pciexbar_reg >> 1) & 3) {
case 0: /* 256MB */
*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
(1 << 28));
*len = 256 * 1024 * 1024;
return 1;
case 1: /* 128M */
*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
(1 << 28) | (1 << 27));
*len = 128 * 1024 * 1024;
return 1;
case 2: /* 64M */
*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
(1 << 28) | (1 << 27) | (1 << 26));
*len = 64 * 1024 * 1024;
return 1;
}
return 0;
}
static void add_fixed_resources(pci_dev_t dev, int index)
{
u32 pcie_config_base, pcie_config_size;
if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) {
debug("Adding PCIe config bar base=0x%08x size=0x%x\n",
pcie_config_base, pcie_config_size);
}
}
static void northbridge_dmi_init(pci_dev_t dev)
{
/* Clear error status bits */
writel(0xffffffff, DMIBAR_REG(0x1c4));
writel(0xffffffff, DMIBAR_REG(0x1d0));
/* Steps prior to DMI ASPM */
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
clrsetbits_le32(DMIBAR_REG(0x250), (1 << 22) | (1 << 20),
1 << 21);
}
setbits_le32(DMIBAR_REG(0x238), 1 << 29);
if (bridge_silicon_revision() >= SNB_STEP_D0) {
setbits_le32(DMIBAR_REG(0x1f8), 1 << 16);
} else if (bridge_silicon_revision() >= SNB_STEP_D1) {
clrsetbits_le32(DMIBAR_REG(0x1f8), 1 << 26, 1 << 16);
setbits_le32(DMIBAR_REG(0x1fc), (1 << 12) | (1 << 23));
}
/* Enable ASPM on SNB link, should happen before PCH link */
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB)
setbits_le32(DMIBAR_REG(0xd04), 1 << 4);
setbits_le32(DMIBAR_REG(0x88), (1 << 1) | (1 << 0));
}
void northbridge_init(pci_dev_t dev)
{
u32 bridge_type;
add_fixed_resources(dev, 6);
northbridge_dmi_init(dev);
bridge_type = readl(MCHBAR_REG(0x5f10));
bridge_type &= ~0xff;
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
/* Enable Power Aware Interrupt Routing - fixed priority */
clrsetbits_8(MCHBAR_REG(0x5418), 0xf, 0x4);
/* 30h for IvyBridge */
bridge_type |= 0x30;
} else {
/* 20h for Sandybridge */
bridge_type |= 0x20;
}
writel(bridge_type, MCHBAR_REG(0x5f10));
/*
* Set bit 0 of BIOS_RESET_CPL to indicate to the CPU
* that BIOS has initialized memory and power management
*/
setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 1);
debug("Set BIOS_RESET_CPL\n");
/* Configure turbo power limits 1ms after reset complete bit */
mdelay(1);
set_power_limits(28);
/*
* CPUs with configurable TDP also need power limits set
* in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT.
*/
if (cpu_config_tdp_levels()) {
msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);
writel(msr.lo, MCHBAR_REG(0x59A0));
writel(msr.hi, MCHBAR_REG(0x59A4));
}
/* Set here before graphics PM init */
writel(0x00100001, MCHBAR_REG(0x5500));
}
void northbridge_enable(pci_dev_t dev)
{
#if CONFIG_HAVE_ACPI_RESUME
switch (pci_read_config32(dev, SKPAD)) {
case 0xcafebabe:
debug("Normal boot.\n");
apci_set_slp_type(0);
break;
case 0xcafed00d:
debug("S3 Resume.\n");
apci_set_slp_type(3);
break;
default:
debug("Unknown boot method, assuming normal.\n");
apci_set_slp_type(0);
break;
}
#endif
}

View file

@ -0,0 +1,123 @@
/*
* From Coreboot
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2012 The Chromium OS Authors.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
static int pch_revision_id = -1;
static int pch_type = -1;
int pch_silicon_revision(void)
{
pci_dev_t dev;
dev = PCH_LPC_DEV;
if (pch_revision_id < 0)
pch_revision_id = pci_read_config8(dev, PCI_REVISION_ID);
return pch_revision_id;
}
int pch_silicon_type(void)
{
pci_dev_t dev;
dev = PCH_LPC_DEV;
if (pch_type < 0)
pch_type = pci_read_config8(dev, PCI_DEVICE_ID + 1);
return pch_type;
}
int pch_silicon_supported(int type, int rev)
{
int cur_type = pch_silicon_type();
int cur_rev = pch_silicon_revision();
switch (type) {
case PCH_TYPE_CPT:
/* CougarPoint minimum revision */
if (cur_type == PCH_TYPE_CPT && cur_rev >= rev)
return 1;
/* PantherPoint any revision */
if (cur_type == PCH_TYPE_PPT)
return 1;
break;
case PCH_TYPE_PPT:
/* PantherPoint minimum revision */
if (cur_type == PCH_TYPE_PPT && cur_rev >= rev)
return 1;
break;
}
return 0;
}
#define IOBP_RETRY 1000
static inline int iobp_poll(void)
{
unsigned try = IOBP_RETRY;
u32 data;
while (try--) {
data = readl(RCB_REG(IOBPS));
if ((data & 1) == 0)
return 1;
udelay(10);
}
printf("IOBP timeout\n");
return 0;
}
void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
{
u32 data;
/* Set the address */
writel(address, RCB_REG(IOBPIRI));
/* READ OPCODE */
if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
writel(IOBPS_RW_BX, RCB_REG(IOBPS));
else
writel(IOBPS_READ_AX, RCB_REG(IOBPS));
if (!iobp_poll())
return;
/* Read IOBP data */
data = readl(RCB_REG(IOBPD));
if (!iobp_poll())
return;
/* Check for successful transaction */
if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) {
printf("IOBP read 0x%08x failed\n", address);
return;
}
/* Update the data */
data &= andvalue;
data |= orvalue;
/* WRITE OPCODE */
if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
writel(IOBPS_RW_BX, RCB_REG(IOBPS));
else
writel(IOBPS_WRITE_AX, RCB_REG(IOBPS));
if (!iobp_poll())
return;
/* Write IOBP data */
writel(data, RCB_REG(IOBPD));
if (!iobp_poll())
return;
}

View file

@ -12,6 +12,8 @@
#include <common.h>
#include <pci.h>
#include <asm/pci.h>
#include <asm/arch/bd82x6x.h>
#include <asm/arch/pch.h>
static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
struct pci_config_table *table)
@ -58,3 +60,41 @@ void board_pci_setup_hose(struct pci_controller *hose)
hose->region_count = 3;
}
int board_pci_pre_scan(struct pci_controller *hose)
{
pci_dev_t dev;
u16 reg16;
bd82x6x_init();
reg16 = 0xff;
dev = PCH_DEV;
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_write_config16(dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
pci_write_bar32(hose, dev, 0, 0xf0000000);
return 0;
}
int board_pci_post_scan(struct pci_controller *hose)
{
int ret;
ret = bd82x6x_init_pci_devices();
if (ret) {
printf("bd82x6x_init_pci_devices() failed: %d\n", ret);
return ret;
}
return 0;
}

View file

@ -0,0 +1,225 @@
/*
* From Coreboot
* Copyright (C) 2008-2009 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
#include <asm/arch/bd82x6x.h>
static inline u32 sir_read(pci_dev_t dev, int idx)
{
pci_write_config32(dev, SATA_SIRI, idx);
return pci_read_config32(dev, SATA_SIRD);
}
static inline void sir_write(pci_dev_t dev, int idx, u32 value)
{
pci_write_config32(dev, SATA_SIRI, idx);
pci_write_config32(dev, SATA_SIRD, value);
}
static void common_sata_init(pci_dev_t dev, unsigned int port_map)
{
u32 reg32;
u16 reg16;
/* Set IDE I/O Configuration */
reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
pci_write_config32(dev, IDE_CONFIG, reg32);
/* Port enable */
reg16 = pci_read_config16(dev, 0x92);
reg16 &= ~0x3f;
reg16 |= port_map;
pci_write_config16(dev, 0x92, reg16);
/* SATA Initialization register */
port_map &= 0xff;
pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
}
void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
{
unsigned int port_map, speed_support, port_tx;
struct pci_controller *hose = pci_bus_to_hose(0);
const char *mode;
u32 reg32;
u16 reg16;
debug("SATA: Initializing...\n");
/* SATA configuration */
port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
speed_support = fdtdec_get_int(blob, node,
"sata_interface_speed_support", 0);
/* Enable BARs */
pci_write_config16(dev, PCI_COMMAND, 0x0007);
mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
if (!mode || !strcmp(mode, "ahci")) {
u32 abar;
debug("SATA: Controller in AHCI mode\n");
/* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
pci_write_config8(dev, INTR_LN, 0x0a);
/* Set timings */
pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
/* Sync DMA */
pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
common_sata_init(dev, 0x8000 | port_map);
/* Initialize AHCI memory-mapped space */
abar = pci_read_bar32(hose, dev, 5);
debug("ABAR: %08X\n", abar);
/* CAP (HBA Capabilities) : enable power management */
reg32 = readl(abar + 0x00);
reg32 |= 0x0c006000; /* set PSC+SSC+SALP+SSS */
reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
/* Set ISS, if available */
if (speed_support) {
reg32 &= ~0x00f00000;
reg32 |= (speed_support & 0x03) << 20;
}
writel(reg32, abar + 0x00);
/* PI (Ports implemented) */
writel(port_map, abar + 0x0c);
(void) readl(abar + 0x0c); /* Read back 1 */
(void) readl(abar + 0x0c); /* Read back 2 */
/* CAP2 (HBA Capabilities Extended)*/
reg32 = readl(abar + 0x24);
reg32 &= ~0x00000002;
writel(reg32, abar + 0x24);
/* VSP (Vendor Specific Register */
reg32 = readl(abar + 0xa0);
reg32 &= ~0x00000005;
writel(reg32, abar + 0xa0);
} else if (!strcmp(mode, "combined")) {
debug("SATA: Controller in combined mode\n");
/* No AHCI: clear AHCI base */
pci_write_bar32(hose, dev, 5, 0x00000000);
/* And without AHCI BAR no memory decoding */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MEMORY;
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_write_config8(dev, 0x09, 0x80);
/* Set timings */
pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
/* Sync DMA */
pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
common_sata_init(dev, port_map);
} else {
debug("SATA: Controller in plain-ide mode\n");
/* No AHCI: clear AHCI base */
pci_write_bar32(hose, dev, 5, 0x00000000);
/* And without AHCI BAR no memory decoding */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MEMORY;
pci_write_config16(dev, PCI_COMMAND, reg16);
/*
* Native mode capable on both primary and secondary (0xa)
* OR'ed with enabled (0x50) = 0xf
*/
pci_write_config8(dev, 0x09, 0x8f);
/* Set Interrupt Line */
/* Interrupt Pin is set by D31IP.PIP */
pci_write_config8(dev, INTR_LN, 0xff);
/* Set timings */
pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_SITRE | IDE_ISP_3_CLOCKS |
IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
/* Sync DMA */
pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
common_sata_init(dev, port_map);
}
/* Set Gen3 Transmitter settings if needed */
port_tx = fdtdec_get_int(blob, node, "intel,sata-port0-gen3-tx", 0);
if (port_tx)
pch_iobp_update(SATA_IOBP_SP0G3IR, 0, port_tx);
port_tx = fdtdec_get_int(blob, node, "intel,sata-port1-gen3-tx", 0);
if (port_tx)
pch_iobp_update(SATA_IOBP_SP1G3IR, 0, port_tx);
/* Additional Programming Requirements */
sir_write(dev, 0x04, 0x00001600);
sir_write(dev, 0x28, 0xa0000033);
reg32 = sir_read(dev, 0x54);
reg32 &= 0xff000000;
reg32 |= 0x5555aa;
sir_write(dev, 0x54, reg32);
sir_write(dev, 0x64, 0xcccc8484);
reg32 = sir_read(dev, 0x68);
reg32 &= 0xffff0000;
reg32 |= 0xcccc;
sir_write(dev, 0x68, reg32);
reg32 = sir_read(dev, 0x78);
reg32 &= 0x0000ffff;
reg32 |= 0x88880000;
sir_write(dev, 0x78, reg32);
sir_write(dev, 0x84, 0x001c7000);
sir_write(dev, 0x88, 0x88338822);
sir_write(dev, 0xa0, 0x001c7000);
sir_write(dev, 0xc4, 0x0c0c0c0c);
sir_write(dev, 0xc8, 0x0c0c0c0c);
sir_write(dev, 0xd4, 0x10000000);
pch_iobp_update(0xea004001, 0x3fffffff, 0xc0000000);
pch_iobp_update(0xea00408a, 0xfffffcff, 0x00000100);
}
void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
{
unsigned port_map;
const char *mode;
u16 map = 0;
/*
* Set SATA controller mode early so the resource allocator can
* properly assign IO/Memory resources for the controller.
*/
mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
if (mode && !strcmp(mode, "ahci"))
map = 0x0060;
port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
map |= (port_map ^ 0x3f) << 8;
pci_write_config16(dev, 0x90, map);
}

View file

@ -0,0 +1,29 @@
/*
* From Coreboot
* Copyright (C) 2008-2009 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
void bd82x6x_usb_ehci_init(pci_dev_t dev)
{
u32 reg32;
/* Disable Wake on Disconnect in RMH */
reg32 = readl(RCB_REG(0x35b0));
reg32 |= 0x22;
writel(reg32, RCB_REG(0x35b0));
debug("EHCI: Setting up controller.. ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER;
/* reg32 |= PCI_COMMAND_SERR; */
pci_write_config32(dev, PCI_COMMAND, reg32);
debug("done.\n");
}

View file

@ -0,0 +1,32 @@
/*
* From Coreboot
* Copyright (C) 2008-2009 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
void bd82x6x_usb_xhci_init(pci_dev_t dev)
{
u32 reg32;
debug("XHCI: Setting up controller.. ");
/* lock overcurrent map */
reg32 = pci_read_config32(dev, 0x44);
reg32 |= 1;
pci_write_config32(dev, 0x44, reg32);
/* Enable clock gating */
reg32 = pci_read_config32(dev, 0x40);
reg32 &= ~((1 << 20) | (1 << 21));
reg32 |= (1 << 19) | (1 << 18) | (1 << 17);
reg32 |= (1 << 10) | (1 << 9) | (1 << 8);
reg32 |= (1 << 31); /* lock */
pci_write_config32(dev, 0x40, reg32);
debug("done.\n");
}

57
arch/x86/cpu/lapic.c Normal file
View file

@ -0,0 +1,57 @@
/*
* From coreboot file of same name
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2014 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/msr.h>
#include <asm/io.h>
#include <asm/lapic.h>
#include <asm/post.h>
void lapic_setup(void)
{
#if NEED_LAPIC == 1
/* Only Pentium Pro and later have those MSR stuff */
debug("Setting up local apic: ");
/* Enable the local apic */
enable_lapic();
/*
* Set Task Priority to 'accept all'.
*/
lapic_write_around(LAPIC_TASKPRI,
lapic_read_around(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK);
/* Put the local apic in virtual wire mode */
lapic_write_around(LAPIC_SPIV, (lapic_read_around(LAPIC_SPIV) &
~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE);
lapic_write_around(LAPIC_LVT0, (lapic_read_around(LAPIC_LVT0) &
~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 |
LAPIC_DELIVERY_MODE_MASK)) |
(LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING |
LAPIC_DELIVERY_MODE_EXTINT));
lapic_write_around(LAPIC_LVT1, (lapic_read_around(LAPIC_LVT1) &
~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 |
LAPIC_DELIVERY_MODE_MASK)) |
(LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING |
LAPIC_DELIVERY_MODE_NMI));
debug("apic_id: 0x%02lx, ", lapicid());
#else /* !NEED_LLAPIC */
/* Only Pentium Pro and later have those MSR stuff */
debug("Disabling local apic: ");
disable_lapic();
#endif /* !NEED_LAPIC */
debug("done.\n");
post_code(POST_LAPIC);
}

View file

@ -33,6 +33,16 @@ int pci_early_init_hose(struct pci_controller **hosep)
return 0;
}
__weak int board_pci_pre_scan(struct pci_controller *hose)
{
return 0;
}
__weak int board_pci_post_scan(struct pci_controller *hose)
{
return 0;
}
void pci_init_board(void)
{
struct pci_controller *hose = &x86_hose;
@ -44,7 +54,9 @@ void pci_init_board(void)
pci_setup_type1(hose);
pci_register_hose(hose);
board_pci_pre_scan(hose);
hose->last_busno = pci_hose_scan(hose);
board_pci_post_scan(hose);
}
static struct pci_controller *get_hose(void)

98
arch/x86/cpu/turbo.c Normal file
View file

@ -0,0 +1,98 @@
/*
* From Coreboot file of the same name
*
* Copyright (C) 2011 The Chromium Authors.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/cpu.h>
#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/turbo.h>
#if CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
static inline int get_global_turbo_state(void)
{
return TURBO_UNKNOWN;
}
static inline void set_global_turbo_state(int state)
{
}
#else
static int g_turbo_state = TURBO_UNKNOWN;
static inline int get_global_turbo_state(void)
{
return g_turbo_state;
}
static inline void set_global_turbo_state(int state)
{
g_turbo_state = state;
}
#endif
static const char *const turbo_state_desc[] = {
[TURBO_UNKNOWN] = "unknown",
[TURBO_UNAVAILABLE] = "unavailable",
[TURBO_DISABLED] = "available but hidden",
[TURBO_ENABLED] = "available and visible"
};
/*
* Determine the current state of Turbo and cache it for later.
* Turbo is a package level config so it does not need to be
* enabled on every core.
*/
int turbo_get_state(void)
{
struct cpuid_result cpuid_regs;
int turbo_en, turbo_cap;
msr_t msr;
int turbo_state = get_global_turbo_state();
/* Return cached state if available */
if (turbo_state != TURBO_UNKNOWN)
return turbo_state;
cpuid_regs = cpuid(CPUID_LEAF_PM);
turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE);
msr = msr_read(MSR_IA32_MISC_ENABLES);
turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO);
if (!turbo_cap && turbo_en) {
/* Unavailable */
turbo_state = TURBO_UNAVAILABLE;
} else if (!turbo_cap && !turbo_en) {
/* Available but disabled */
turbo_state = TURBO_DISABLED;
} else if (turbo_cap && turbo_en) {
/* Available */
turbo_state = TURBO_ENABLED;
}
set_global_turbo_state(turbo_state);
debug("Turbo is %s\n", turbo_state_desc[turbo_state]);
return turbo_state;
}
void turbo_enable(void)
{
msr_t msr;
/* Only possible if turbo is available but hidden */
if (turbo_get_state() == TURBO_DISABLED) {
/* Clear Turbo Disable bit in Misc Enables */
msr = msr_read(MSR_IA32_MISC_ENABLES);
msr.hi &= ~H_MISC_DISABLE_TURBO;
msr_write(MSR_IA32_MISC_ENABLES, msr);
/* Update cached turbo state */
set_global_turbo_state(TURBO_ENABLED);
debug("Turbo has been enabled\n");
}
}

View file

@ -44,7 +44,9 @@ SECTIONS
. = ALIGN(4);
__rel_dyn_start = .;
.rel.dyn : { *(.rel.dyn) }
.rel.dyn : {
*(.rel*)
}
__rel_dyn_end = .;
. = ALIGN(4);
_end = .;
@ -64,15 +66,19 @@ SECTIONS
/DISCARD/ : { *(.gnu*) }
#ifdef CONFIG_X86_RESET_VECTOR
/*
* The following expressions place the 16-bit Real-Mode code and
* Reset Vector at the end of the Flash ROM
*/
. = START_16;
.start16 : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + START_16)) { KEEP(*(.start16)); }
. = START_16 - RESET_SEG_START;
.start16 : AT (START_16) {
KEEP(*(.start16));
}
. = RESET_VEC_LOC;
.resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
. = RESET_VEC_LOC - RESET_SEG_START;
.resetvec : AT (RESET_VEC_LOC) {
KEEP(*(.resetvec));
}
#endif
}

View file

@ -163,16 +163,45 @@
};
};
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>;
/* This describes the flash memory within the EC */
/* Describes the flash memory within the EC */
#address-cells = <1>;
#size-cells = <1>;
flash@8000000 {
@ -181,6 +210,7 @@
};
};
};
};
microcode {
update@0 {

View file

@ -0,0 +1,24 @@
/*
* From coreboot
*
* Copyright (C) 2004 SUSE LINUX AG
* Copyright (C) 2004 Nick Barker
* Copyright (C) 2008-2009 coresystems GmbH
* (Written by Stefan Reinauer <stepan@coresystems.de>)
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef __ASM_ACPI_H
#define __ASM_ACPI_H
#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
#define ACPI_TABLE_CREATOR "U-BootAC" /* Must be exactly 8 bytes long! */
#define OEM_ID "U-Boot" /* Must be exactly 6 bytes long! */
#define ASLC "U-Bo" /* Must be exactly 4 bytes long! */
/* 0 = S0, 1 = S1 ...*/
int acpi_get_slp_type(void);
void apci_set_slp_type(int type);
#endif

View file

@ -0,0 +1,23 @@
/*
* Copyright (C) 2014 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_BD82X6X_H
#define _ASM_ARCH_BD82X6X_H
void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node);
void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
void bd82x6x_pci_init(pci_dev_t dev);
void bd82x6x_usb_ehci_init(pci_dev_t dev);
void bd82x6x_usb_xhci_init(pci_dev_t dev);
int bd82x6x_init_pci_devices(void);
int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
const void *blob, int node);
int bd82x6x_init(void);
struct x86_cpu_priv;
int model_206ax_init(struct x86_cpu_priv *cpu);
#endif

View file

@ -79,4 +79,8 @@
#define PSS_LATENCY_TRANSITION 10
#define PSS_LATENCY_BUSMASTER 10
/* Configure power limits for turbo mode */
void set_power_limits(u8 power_limit_1_time);
int cpu_config_tdp_levels(void);
#endif

View file

@ -14,11 +14,41 @@
#include <pci.h>
/* PCH types */
#define PCH_TYPE_CPT 0x1c /* CougarPoint */
#define PCH_TYPE_PPT 0x1e /* IvyBridge */
/* PCH stepping values for LPC device */
#define PCH_STEP_A0 0
#define PCH_STEP_A1 1
#define PCH_STEP_B0 2
#define PCH_STEP_B1 3
#define PCH_STEP_B2 4
#define PCH_STEP_B3 5
#define DEFAULT_GPIOBASE 0x0480
#define DEFAULT_PMBASE 0x0500
#define SMBUS_IO_BASE 0x0400
int pch_silicon_revision(void);
int pch_silicon_type(void);
int pch_silicon_supported(int type, int rev);
void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue);
#define MAINBOARD_POWER_OFF 0
#define MAINBOARD_POWER_ON 1
#define MAINBOARD_POWER_KEEP 2
/* PCI Configuration Space (D30:F0): PCI2PCI */
#define PSTS 0x06
#define SMLT 0x1b
#define SECSTS 0x1e
#define INTR 0x3c
#define BCTRL 0x3e
#define SBR (1 << 6)
#define SEE (1 << 1)
#define PERE (1 << 0)
#define PCH_EHCI1_DEV PCI_BDF(0, 0x1d, 0)
#define PCH_EHCI2_DEV PCI_BDF(0, 0x1a, 0)
#define PCH_XHCI_DEV PCI_BDF(0, 0x14, 0)
@ -30,6 +60,35 @@
/* PCI Configuration Space (D31:F0): LPC */
#define PCH_LPC_DEV PCI_BDF(0, 0x1f, 0)
#define SERIRQ_CNTL 0x64
#define GEN_PMCON_1 0xa0
#define GEN_PMCON_2 0xa2
#define GEN_PMCON_3 0xa4
#define ETR3 0xac
#define ETR3_CWORWRE (1 << 18)
#define ETR3_CF9GR (1 << 20)
/* GEN_PMCON_3 bits */
#define RTC_BATTERY_DEAD (1 << 2)
#define RTC_POWER_FAILED (1 << 1)
#define SLEEP_AFTER_POWER_FAIL (1 << 0)
#define PMBASE 0x40
#define ACPI_CNTL 0x44
#define BIOS_CNTL 0xDC
#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */
#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */
#define GPIO_ROUT 0xb8
#define PIRQA_ROUT 0x60
#define PIRQB_ROUT 0x61
#define PIRQC_ROUT 0x62
#define PIRQD_ROUT 0x63
#define PIRQE_ROUT 0x68
#define PIRQF_ROUT 0x69
#define PIRQG_ROUT 0x6A
#define PIRQH_ROUT 0x6B
#define GEN_PMCON_1 0xa0
#define GEN_PMCON_2 0xa2
@ -63,6 +122,64 @@
#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */
#define LPC_GENX_DEC(x) (0x84 + 4 * (x))
/* PCI Configuration Space (D31:F1): IDE */
#define PCH_IDE_DEV PCI_BDF(0, 0x1f, 1)
#define PCH_SATA_DEV PCI_BDF(0, 0x1f, 2)
#define PCH_SATA2_DEV PCI_BDF(0, 0x1f, 5)
#define INTR_LN 0x3c
#define IDE_TIM_PRI 0x40 /* IDE timings, primary */
#define IDE_DECODE_ENABLE (1 << 15)
#define IDE_SITRE (1 << 14)
#define IDE_ISP_5_CLOCKS (0 << 12)
#define IDE_ISP_4_CLOCKS (1 << 12)
#define IDE_ISP_3_CLOCKS (2 << 12)
#define IDE_RCT_4_CLOCKS (0 << 8)
#define IDE_RCT_3_CLOCKS (1 << 8)
#define IDE_RCT_2_CLOCKS (2 << 8)
#define IDE_RCT_1_CLOCKS (3 << 8)
#define IDE_DTE1 (1 << 7)
#define IDE_PPE1 (1 << 6)
#define IDE_IE1 (1 << 5)
#define IDE_TIME1 (1 << 4)
#define IDE_DTE0 (1 << 3)
#define IDE_PPE0 (1 << 2)
#define IDE_IE0 (1 << 1)
#define IDE_TIME0 (1 << 0)
#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */
#define IDE_SDMA_CNT 0x48 /* Synchronous DMA control */
#define IDE_SSDE1 (1 << 3)
#define IDE_SSDE0 (1 << 2)
#define IDE_PSDE1 (1 << 1)
#define IDE_PSDE0 (1 << 0)
#define IDE_SDMA_TIM 0x4a
#define IDE_CONFIG 0x54 /* IDE I/O Configuration Register */
#define SIG_MODE_SEC_NORMAL (0 << 18)
#define SIG_MODE_SEC_TRISTATE (1 << 18)
#define SIG_MODE_SEC_DRIVELOW (2 << 18)
#define SIG_MODE_PRI_NORMAL (0 << 16)
#define SIG_MODE_PRI_TRISTATE (1 << 16)
#define SIG_MODE_PRI_DRIVELOW (2 << 16)
#define FAST_SCB1 (1 << 15)
#define FAST_SCB0 (1 << 14)
#define FAST_PCB1 (1 << 13)
#define FAST_PCB0 (1 << 12)
#define SCB1 (1 << 3)
#define SCB0 (1 << 2)
#define PCB1 (1 << 1)
#define PCB0 (1 << 0)
#define SATA_SIRI 0xa0 /* SATA Indexed Register Index */
#define SATA_SIRD 0xa4 /* SATA Indexed Register Data */
#define SATA_SP 0xd0 /* Scratchpad */
/* SATA IOBP Registers */
#define SATA_IOBP_SP0G3IR 0xea000151
#define SATA_IOBP_SP1G3IR 0xea000051
/* PCI Configuration Space (D31:F3): SMBus */
#define PCH_SMBUS_DEV PCI_BDF(0, 0x1f, 3)
#define SMB_BASE 0x20
@ -343,6 +460,9 @@
#define DMISCI_STS (1 << 9)
#define TCO2_STS 0x66
int lpc_init(struct pci_controller *hose, pci_dev_t dev);
void lpc_enable(pci_dev_t dev);
/**
* lpc_early_init() - set up LPC serial ports and other early things
*

View file

@ -97,11 +97,22 @@
/*
* MCHBAR
*/
#define MCHBAR_REG(reg) (DEFAULT_RCBA + (reg))
#define MCHBAR_REG(reg) (DEFAULT_MCHBAR + (reg))
#define SSKPD 0x5d14 /* 16bit (scratchpad) */
#define BIOS_RESET_CPL 0x5da8 /* 8bit */
/*
* DMIBAR
*/
#define DMIBAR_REG(x) (DEFAULT_DMIBAR + x)
int bridge_silicon_revision(void);
void northbridge_enable(pci_dev_t dev);
void northbridge_init(pci_dev_t dev);
void report_platform_info(void);
void sandybridge_early_init(int chipset_type);

View file

@ -69,4 +69,6 @@
#define ICW4_AEOI 0x02 /* Automatic EOI Mode */
#define ICW4_PM 0x01 /* Microprocessor Mode */
int i8259_init(void);
#endif

View file

@ -27,4 +27,15 @@ void specific_eoi(int irq);
extern char exception_stack[];
/**
* configure_irq_trigger() - Configure IRQ triggering
*
* Switch the given interrupt to be level / edge triggered
*
* @param int_num legacy interrupt number (3-7, 9-15)
* @param is_level_triggered true for level triggered interrupt, false for
* edge triggered interrupt
*/
void configure_irq_trigger(int int_num, bool is_level_triggered);
#endif

View file

@ -0,0 +1,38 @@
/*
* From coreboot file of the same name
*
* Copyright (C) 2010 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef __ASM_IOAPIC_H
#define __ASM_IOAPIC_H
#define IO_APIC_ADDR 0xfec00000
#define IO_APIC_INDEX IO_APIC_ADDR
#define IO_APIC_DATA (IO_APIC_ADDR + 0x10)
#define IO_APIC_INTERRUPTS 24
#define ALL (0xff << 24)
#define NONE 0
#define DISABLED (1 << 16)
#define ENABLED (0 << 16)
#define TRIGGER_EDGE (0 << 15)
#define TRIGGER_LEVEL (1 << 15)
#define POLARITY_HIGH (0 << 13)
#define POLARITY_LOW (1 << 13)
#define PHYSICAL_DEST (0 << 11)
#define LOGICAL_DEST (1 << 11)
#define ExtINT (7 << 8)
#define NMI (4 << 8)
#define SMI (2 << 8)
#define INT (1 << 8)
u32 io_apic_read(u32 ioapic_base, u32 reg);
void io_apic_write(u32 ioapic_base, u32 reg, u32 value);
void set_ioapic_id(u32 ioapic_base, u8 ioapic_id);
void setup_ioapic(u32 ioapic_base, u8 ioapic_id);
void clear_ioapic(u32 ioapic_base);
#endif

View file

@ -14,6 +14,13 @@
#include <asm/msr.h>
#include <asm/processor.h>
/* See if I need to initialize the local apic */
#if CONFIG_SMP || CONFIG_IOAPIC
# define NEED_LAPIC 1
#else
# define NEED_LAPIC 0
#endif
static inline __attribute__((always_inline))
unsigned long lapic_read(unsigned long reg)
{
@ -37,8 +44,9 @@ static inline void enable_lapic(void)
msr = msr_read(LAPIC_BASE_MSR);
msr.hi &= 0xffffff00;
msr.lo &= 0x000007ff;
msr.lo |= LAPIC_DEFAULT_BASE | (1 << 11);
msr.lo |= LAPIC_BASE_MSR_ENABLE;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE;
msr_write(LAPIC_BASE_MSR, msr);
}
@ -56,4 +64,116 @@ static inline __attribute__((always_inline)) unsigned long lapicid(void)
return lapic_read(LAPIC_ID) >> 24;
}
#if !CONFIG_AP_IN_SIPI_WAIT
/* If we need to go back to sipi wait, we use the long non-inlined version of
* this function in lapic_cpu_init.c
*/
static inline __attribute__((always_inline)) void stop_this_cpu(void)
{
/* Called by an AP when it is ready to halt and wait for a new task */
for (;;)
cpu_hlt();
}
#else
void stop_this_cpu(void);
#endif
#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \
sizeof(*(ptr))))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway
* Note 2: xchg has side effect, so that attribute volatile is necessary,
* but generally the primitive is invalid, *ptr is output argument. --ANK
*/
static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
int size)
{
switch (size) {
case 1:
__asm__ __volatile__("xchgb %b0,%1"
: "=q" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
case 2:
__asm__ __volatile__("xchgw %w0,%1"
: "=r" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
case 4:
__asm__ __volatile__("xchgl %0,%1"
: "=r" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
}
return x;
}
static inline void lapic_write_atomic(unsigned long reg, unsigned long v)
{
(void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v);
}
#ifdef X86_GOOD_APIC
# define FORCE_READ_AROUND_WRITE 0
# define lapic_read_around(x) lapic_read(x)
# define lapic_write_around(x, y) lapic_write((x), (y))
#else
# define FORCE_READ_AROUND_WRITE 1
# define lapic_read_around(x) lapic_read(x)
# define lapic_write_around(x, y) lapic_write_atomic((x), (y))
#endif
static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue)
{
int timeout;
unsigned long status;
int result;
lapic_wait_icr_idle();
lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4));
timeout = 0;
do {
status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK;
} while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000);
result = -1;
if (status == LAPIC_ICR_RR_VALID) {
*pvalue = lapic_read(LAPIC_RRR);
result = 0;
}
return result;
}
void lapic_setup(void);
#if CONFIG_SMP
struct device;
int start_cpu(struct device *cpu);
#endif /* CONFIG_SMP */
int boot_cpu(void);
/**
* struct x86_cpu_priv - Information about a single CPU
*
* @apic_id: Advanced Programmable Interrupt Controller Identifier, which is
* just a number representing the CPU core
*
* TODO: Move this to driver model once lifecycle is understood
*/
struct x86_cpu_priv {
int apic_id;
int start_err;
};
#endif

View file

@ -326,6 +326,8 @@
#define MSR_AMD_PERF_STATUS 0xc0010063
#define MSR_AMD_PERF_CTL 0xc0010062
#define MSR_PMG_CST_CONFIG_CTL 0x000000e2
#define MSR_PMG_IO_CAPTURE_ADR 0x000000e4
#define MSR_IA32_MPERF 0x000000e7
#define MSR_IA32_APERF 0x000000e8

View file

@ -229,17 +229,6 @@ do { \
struct msr *msrs_alloc(void);
void msrs_free(struct msr *msrs);
#ifdef CONFIG_SMP
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
#endif /* CONFIG_SMP */
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_MSR_H */

View file

@ -34,6 +34,9 @@ void board_pci_setup_hose(struct pci_controller *hose);
*/
int pci_early_init_hose(struct pci_controller **hosep);
int board_pci_pre_scan(struct pci_controller *hose);
int board_pci_post_scan(struct pci_controller *hose);
/*
* Simple PCI access routines - these work from either the early PCI hose
* or the 'real' one, created after U-Boot has memory available

View file

@ -30,6 +30,7 @@
#define POST_PRE_MRC 0x2e
#define POST_MRC 0x2f
#define POST_DRAM 0x2f
#define POST_LAPIC 0x30
#define POST_RAM_FAILURE 0xea

View file

@ -10,23 +10,16 @@
#define X86_GDT_ENTRY_SIZE 8
#ifndef __ASSEMBLY__
enum {
X86_GDT_ENTRY_NULL = 0,
X86_GDT_ENTRY_UNUSED,
X86_GDT_ENTRY_32BIT_CS,
X86_GDT_ENTRY_32BIT_DS,
X86_GDT_ENTRY_32BIT_FS,
X86_GDT_ENTRY_16BIT_CS,
X86_GDT_ENTRY_16BIT_DS,
X86_GDT_NUM_ENTRIES
};
#else
/* NOTE: If the above enum is modified, this define must be checked */
#define X86_GDT_ENTRY_NULL 0
#define X86_GDT_ENTRY_UNUSED 1
#define X86_GDT_ENTRY_32BIT_CS 2
#define X86_GDT_ENTRY_32BIT_DS 3
#define X86_GDT_NUM_ENTRIES 7
#endif
#define X86_GDT_ENTRY_32BIT_FS 4
#define X86_GDT_ENTRY_16BIT_CS 5
#define X86_GDT_ENTRY_16BIT_DS 6
#define X86_GDT_ENTRY_16BIT_FLAT_CS 7
#define X86_GDT_ENTRY_16BIT_FLAT_DS 8
#define X86_GDT_NUM_ENTRIES 9
#define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE)

View file

@ -0,0 +1,89 @@
/*
* From Coreboot file of same name
*
* Copyright (C) 2007-2009 coresystems GmbH
* 2012 secunet Security Networks AG
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _ASM_SPEEDSTEP_H
#define _ASM_SPEEDSTEP_H
/* Magic value used to locate speedstep configuration in the device tree */
#define SPEEDSTEP_APIC_MAGIC 0xACAC
/* MWAIT coordination I/O base address. This must match
* the \_PR_.CPU0 PM base address.
*/
#define PMB0_BASE 0x510
/* PMB1: I/O port that triggers SMI once cores are in the same state.
* See CSM Trigger, at PMG_CST_CONFIG_CONTROL[6:4]
*/
#define PMB1_BASE 0x800
struct sst_state {
uint8_t dynfsb:1; /* whether this is SLFM */
uint8_t nonint:1; /* add .5 to ratio */
uint8_t ratio:6;
uint8_t vid;
uint8_t is_turbo;
uint8_t is_slfm;
uint32_t power;
};
#define SPEEDSTEP_RATIO_SHIFT 8
#define SPEEDSTEP_RATIO_DYNFSB_SHIFT (7 + SPEEDSTEP_RATIO_SHIFT)
#define SPEEDSTEP_RATIO_DYNFSB (1 << SPEEDSTEP_RATIO_DYNFSB_SHIFT)
#define SPEEDSTEP_RATIO_NONINT_SHIFT (6 + SPEEDSTEP_RATIO_SHIFT)
#define SPEEDSTEP_RATIO_NONINT (1 << SPEEDSTEP_RATIO_NONINT_SHIFT)
#define SPEEDSTEP_RATIO_VALUE_MASK (0x1f << SPEEDSTEP_RATIO_SHIFT)
#define SPEEDSTEP_VID_MASK 0x3f
#define SPEEDSTEP_STATE_FROM_MSR(val, mask) ((struct sst_state){ \
0, /* dynfsb won't be read. */ \
((val & mask) & SPEEDSTEP_RATIO_NONINT) ? 1 : 0, \
(((val & mask) & SPEEDSTEP_RATIO_VALUE_MASK) \
>> SPEEDSTEP_RATIO_SHIFT), \
(val & mask) & SPEEDSTEP_VID_MASK, \
0, /* not turbo by default */ \
0, /* not slfm by default */ \
0 /* power is hardcoded in software. */ \
})
#define SPEEDSTEP_ENCODE_STATE(state) ( \
((uint16_t)(state).dynfsb << SPEEDSTEP_RATIO_DYNFSB_SHIFT) | \
((uint16_t)(state).nonint << SPEEDSTEP_RATIO_NONINT_SHIFT) | \
((uint16_t)(state).ratio << SPEEDSTEP_RATIO_SHIFT) | \
((uint16_t)(state).vid & SPEEDSTEP_VID_MASK))
#define SPEEDSTEP_DOUBLE_RATIO(state) ( \
((uint8_t)(state).ratio * 2) + (state).nonint)
struct sst_params {
struct sst_state slfm;
struct sst_state min;
struct sst_state max;
struct sst_state turbo;
};
/* Looking at core2's spec, the highest normal bus ratio for an eist enabled
processor is 14, the lowest is always 6. This makes 5 states with the
minimal step width of 2. With turbo mode and super LFM we have at most 7. */
#define SPEEDSTEP_MAX_NORMAL_STATES 5
#define SPEEDSTEP_MAX_STATES (SPEEDSTEP_MAX_NORMAL_STATES + 2)
struct sst_table {
/* Table of p-states for EMTTM and ACPI by decreasing performance. */
struct sst_state states[SPEEDSTEP_MAX_STATES];
int num_states;
};
void speedstep_gen_pstates(struct sst_table *);
#define SPEEDSTEP_MAX_POWER_YONAH 31000
#define SPEEDSTEP_MIN_POWER_YONAH 13100
#define SPEEDSTEP_MAX_POWER_MEROM 35000
#define SPEEDSTEP_MIN_POWER_MEROM 25000
#define SPEEDSTEP_SLFM_POWER_MEROM 12000
#define SPEEDSTEP_MAX_POWER_PENRYN 35000
#define SPEEDSTEP_MIN_POWER_PENRYN 15000
#define SPEEDSTEP_SLFM_POWER_PENRYN 12000
#endif

View file

@ -0,0 +1,31 @@
/*
* From coreboot file of the same name
*
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _ASM_TURBO_H
#define _ASM_TURBO_H
#define CPUID_LEAF_PM 6
#define PM_CAP_TURBO_MODE (1 << 1)
#define MSR_IA32_MISC_ENABLES 0x1a0
#define H_MISC_DISABLE_TURBO (1 << 6)
enum {
TURBO_UNKNOWN,
TURBO_UNAVAILABLE,
TURBO_DISABLED,
TURBO_ENABLED,
};
/* Return current turbo state */
int turbo_get_state(void);
/* Enable turbo */
void turbo_enable(void);
#endif

View file

@ -10,8 +10,6 @@
/* cpu/.../cpu.c */
int arch_cpu_init(void);
int x86_cpu_init_r(void);
int cpu_init_r(void);
int x86_cpu_init_f(void);
int cpu_init_f(void);
void init_gd(gd_t *id, u64 *gdt_addr);

View file

@ -5,6 +5,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += bios.o
obj-y += bios_asm.o
obj-y += bios_interrupts.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-y += cmd_boot.o
obj-y += gcc.o

347
arch/x86/lib/bios.c Normal file
View file

@ -0,0 +1,347 @@
/*
* From Coreboot file device/oprom/realmode/x86.c
*
* Copyright (C) 2007 Advanced Micro Devices, Inc.
* Copyright (C) 2009-2010 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <bios_emul.h>
#include <vbe.h>
#include <asm/cache.h>
#include <asm/processor.h>
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/post.h>
#include "bios.h"
/* Interrupt handlers for each interrupt the ROM can call */
static int (*int_handler[256])(void);
/* to have a common register file for interrupt handlers */
X86EMU_sysEnv _X86EMU_env;
asmlinkage void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
u32 esi, u32 edi);
asmlinkage void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx,
u32 edx, u32 esi, u32 edi);
static void setup_realmode_code(void)
{
memcpy((void *)REALMODE_BASE, &asm_realmode_code,
asm_realmode_code_size);
/* Ensure the global pointers are relocated properly. */
realmode_call = PTR_TO_REAL_MODE(asm_realmode_call);
realmode_interrupt = PTR_TO_REAL_MODE(__realmode_interrupt);
debug("Real mode stub @%x: %d bytes\n", REALMODE_BASE,
asm_realmode_code_size);
}
static void setup_rombios(void)
{
const char date[] = "06/11/99";
memcpy((void *)0xffff5, &date, 8);
const char ident[] = "PCI_ISA";
memcpy((void *)0xfffd9, &ident, 7);
/* system model: IBM-AT */
writeb(0xfc, 0xffffe);
}
static int int_exception_handler(void)
{
/* compatibility shim */
struct eregs reg_info = {
.eax = M.x86.R_EAX,
.ecx = M.x86.R_ECX,
.edx = M.x86.R_EDX,
.ebx = M.x86.R_EBX,
.esp = M.x86.R_ESP,
.ebp = M.x86.R_EBP,
.esi = M.x86.R_ESI,
.edi = M.x86.R_EDI,
.vector = M.x86.intno,
.error_code = 0,
.eip = M.x86.R_EIP,
.cs = M.x86.R_CS,
.eflags = M.x86.R_EFLG
};
struct eregs *regs = &reg_info;
debug("Oops, exception %d while executing option rom\n", regs->vector);
cpu_hlt();
return 0;
}
static int int_unknown_handler(void)
{
debug("Unsupported software interrupt #0x%x eax 0x%x\n",
M.x86.intno, M.x86.R_EAX);
return -1;
}
/* setup interrupt handlers for mainboard */
void bios_set_interrupt_handler(int intnum, int (*int_func)(void))
{
int_handler[intnum] = int_func;
}
static void setup_interrupt_handlers(void)
{
int i;
/*
* The first 16 int_handler functions are not BIOS services,
* but the CPU-generated exceptions ("hardware interrupts")
*/
for (i = 0; i < 0x10; i++)
int_handler[i] = &int_exception_handler;
/* Mark all other int_handler calls as unknown first */
for (i = 0x10; i < 0x100; i++) {
/* Skip if bios_set_interrupt_handler() isn't called first */
if (int_handler[i])
continue;
/*
* Now set the default functions that are actually needed
* to initialize the option roms. The board may override
* these with bios_set_interrupt_handler()
*/
switch (i) {
case 0x10:
int_handler[0x10] = &int10_handler;
break;
case 0x12:
int_handler[0x12] = &int12_handler;
break;
case 0x16:
int_handler[0x16] = &int16_handler;
break;
case 0x1a:
int_handler[0x1a] = &int1a_handler;
break;
default:
int_handler[i] = &int_unknown_handler;
break;
}
}
}
static void write_idt_stub(void *target, u8 intnum)
{
unsigned char *codeptr;
codeptr = (unsigned char *)target;
memcpy(codeptr, &__idt_handler, __idt_handler_size);
codeptr[3] = intnum; /* modify int# in the code stub. */
}
static void setup_realmode_idt(void)
{
struct realmode_idt *idts = NULL;
int i;
/*
* Copy IDT stub code for each interrupt. This might seem wasteful
* but it is really simple
*/
for (i = 0; i < 256; i++) {
idts[i].cs = 0;
idts[i].offset = 0x1000 + (i * __idt_handler_size);
write_idt_stub((void *)((u32)idts[i].offset), i);
}
/*
* Many option ROMs use the hard coded interrupt entry points in the
* system bios. So install them at the known locations.
*/
/* int42 is the relocated int10 */
write_idt_stub((void *)0xff065, 0x42);
/* BIOS Int 11 Handler F000:F84D */
write_idt_stub((void *)0xff84d, 0x11);
/* BIOS Int 12 Handler F000:F841 */
write_idt_stub((void *)0xff841, 0x12);
/* BIOS Int 13 Handler F000:EC59 */
write_idt_stub((void *)0xfec59, 0x13);
/* BIOS Int 14 Handler F000:E739 */
write_idt_stub((void *)0xfe739, 0x14);
/* BIOS Int 15 Handler F000:F859 */
write_idt_stub((void *)0xff859, 0x15);
/* BIOS Int 16 Handler F000:E82E */
write_idt_stub((void *)0xfe82e, 0x16);
/* BIOS Int 17 Handler F000:EFD2 */
write_idt_stub((void *)0xfefd2, 0x17);
/* ROM BIOS Int 1A Handler F000:FE6E */
write_idt_stub((void *)0xffe6e, 0x1a);
}
static u8 vbe_get_mode_info(struct vbe_mode_info *mi)
{
u16 buffer_seg;
u16 buffer_adr;
char *buffer;
debug("VBE: Getting information about VESA mode %04x\n",
mi->video_mode);
buffer = PTR_TO_REAL_MODE(asm_realmode_buffer);
buffer_seg = (((unsigned long)buffer) >> 4) & 0xff00;
buffer_adr = ((unsigned long)buffer) & 0xffff;
realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000, mi->video_mode,
0x0000, buffer_seg, buffer_adr);
memcpy(mi->mode_info_block, buffer, sizeof(struct vbe_mode_info));
mi->valid = true;
return 0;
}
static u8 vbe_set_mode(struct vbe_mode_info *mi)
{
debug("VBE: Setting VESA mode %#04x\n", mi->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,
0x0000, 0x0000, 0x0000, 0x0000);
return 0;
}
static void vbe_set_graphics(int vesa_mode, struct vbe_mode_info *mode_info)
{
unsigned char *framebuffer;
mode_info->video_mode = (1 << 14) | vesa_mode;
vbe_get_mode_info(mode_info);
framebuffer = (unsigned char *)mode_info->vesa.phys_base_ptr;
debug("VBE: resolution: %dx%d@%d\n",
le16_to_cpu(mode_info->vesa.x_resolution),
le16_to_cpu(mode_info->vesa.y_resolution),
mode_info->vesa.bits_per_pixel);
debug("VBE: framebuffer: %p\n", framebuffer);
if (!framebuffer) {
debug("VBE: Mode does not support linear framebuffer\n");
return;
}
vbe_set_mode(mode_info);
}
void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode,
struct vbe_mode_info *mode_info)
{
u32 num_dev;
num_dev = PCI_BUS(pcidev) << 8 | PCI_DEV(pcidev) << 3 |
PCI_FUNC(pcidev);
/* Needed to avoid exceptions in some ROMs */
interrupt_init();
/* Set up some legacy information in the F segment */
setup_rombios();
/* Set up C interrupt handlers */
setup_interrupt_handlers();
/* Set up real-mode IDT */
setup_realmode_idt();
/* 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 */
realmode_call(addr + 0x0003, num_dev, 0xffff, 0x0000, 0xffff, 0x0,
0x0);
debug("done\n");
if (vesa_mode != -1)
vbe_set_graphics(vesa_mode, mode_info);
}
asmlinkage int interrupt_handler(u32 intnumber, u32 gsfs, u32 dses,
u32 edi, u32 esi, u32 ebp, u32 esp,
u32 ebx, u32 edx, u32 ecx, u32 eax,
u32 cs_ip, u16 stackflags)
{
u32 ip;
u32 cs;
u32 flags;
int ret = 0;
ip = cs_ip & 0xffff;
cs = cs_ip >> 16;
flags = stackflags;
#ifdef CONFIG_REALMODE_DEBUG
debug("oprom: INT# 0x%x\n", intnumber);
debug("oprom: eax: %08x ebx: %08x ecx: %08x edx: %08x\n",
eax, ebx, ecx, edx);
debug("oprom: ebp: %08x esp: %08x edi: %08x esi: %08x\n",
ebp, esp, edi, esi);
debug("oprom: ip: %04x cs: %04x flags: %08x\n",
ip, cs, flags);
debug("oprom: stackflags = %04x\n", stackflags);
#endif
/*
* Fetch arguments from the stack and put them to a place
* suitable for the interrupt handlers
*/
M.x86.R_EAX = eax;
M.x86.R_ECX = ecx;
M.x86.R_EDX = edx;
M.x86.R_EBX = ebx;
M.x86.R_ESP = esp;
M.x86.R_EBP = ebp;
M.x86.R_ESI = esi;
M.x86.R_EDI = edi;
M.x86.intno = intnumber;
M.x86.R_EIP = ip;
M.x86.R_CS = cs;
M.x86.R_EFLG = flags;
/* Call the interrupt handler for this interrupt number */
ret = int_handler[intnumber]();
/*
* This code is quite strange...
*
* Put registers back on the stack. The assembler code will pop them
* later. We force (volatile!) changing the values of the parameters
* of this function. We know that they stay alive on the stack after
* we leave this function.
*/
*(volatile u32 *)&eax = M.x86.R_EAX;
*(volatile u32 *)&ecx = M.x86.R_ECX;
*(volatile u32 *)&edx = M.x86.R_EDX;
*(volatile u32 *)&ebx = M.x86.R_EBX;
*(volatile u32 *)&esi = M.x86.R_ESI;
*(volatile u32 *)&edi = M.x86.R_EDI;
flags = M.x86.R_EFLG;
/* Pass success or error back to our caller via the CARRY flag */
if (ret) {
flags &= ~1; /* no error: clear carry */
} else {
debug("int%02x call returned error\n", intnumber);
flags |= 1; /* error: set carry */
}
*(volatile u16 *)&stackflags = flags;
return ret;
}

98
arch/x86/lib/bios.h Normal file
View file

@ -0,0 +1,98 @@
/*
* From Coreboot file device/oprom/realmode/x86.h
*
* Copyright (C) 2007 Advanced Micro Devices, Inc.
* Copyright (C) 2009-2010 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _X86_LIB_BIOS_H
#define _X86_LIB_BIOS_H
#define REALMODE_BASE 0x600
#ifdef __ASSEMBLY__
#define PTR_TO_REAL_MODE(x) (x - asm_realmode_code + REALMODE_BASE)
#else
/* Convert a symbol address to our real mode area */
#define PTR_TO_REAL_MODE(sym)\
(void *)(REALMODE_BASE + ((char *)&(sym) - (char *)&asm_realmode_code))
/*
* The following symbols cannot be used directly. They need to be fixed up
* to point to the correct address location after the code has been copied
* to REALMODE_BASE. Absolute symbols are not used because those symbols are
* relocated by U-Boot.
*/
extern unsigned char asm_realmode_call, __realmode_interrupt;
extern unsigned char asm_realmode_buffer;
#define DOWNTO8(A) \
union { \
struct { \
union { \
struct { \
uint8_t A##l; \
uint8_t A##h; \
} __packed; \
uint16_t A##x; \
} __packed; \
uint16_t h##A##x; \
} __packed; \
uint32_t e##A##x; \
} __packed;
#define DOWNTO16(A) \
union { \
struct { \
uint16_t A; \
uint16_t h##A; \
} __packed; \
uint32_t e##A; \
} __packed;
struct eregs {
DOWNTO8(a);
DOWNTO8(c);
DOWNTO8(d);
DOWNTO8(b);
DOWNTO16(sp);
DOWNTO16(bp);
DOWNTO16(si);
DOWNTO16(di);
uint32_t vector;
uint32_t error_code;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
};
struct realmode_idt {
u16 offset, cs;
};
void x86_exception(struct eregs *info);
/* From x86_asm.S */
extern unsigned char __idt_handler;
extern unsigned int __idt_handler_size;
extern unsigned char asm_realmode_code;
extern unsigned int asm_realmode_code_size;
asmlinkage void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
u32 esi, u32 edi);
asmlinkage void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx,
u32 edx, u32 esi, u32 edi);
int int10_handler(void);
int int12_handler(void);
int int16_handler(void);
int int1a_handler(void);
#endif /*__ASSEMBLY__ */
#endif

281
arch/x86/lib/bios_asm.S Normal file
View file

@ -0,0 +1,281 @@
/*
* From coreboot x86_asm.S, cleaned up substantially
*
* Copyright (C) 2009-2010 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <asm/processor.h>
#include <asm/processor-flags.h>
#include "bios.h"
#define SEG(segment) $segment * X86_GDT_ENTRY_SIZE
/*
* This is the interrupt handler stub code. It gets copied to the IDT and
* to some fixed addresses in the F segment. Before the code can used,
* it gets patched up by the C function copying it: byte 3 (the $0 in
* movb $0, %al) is overwritten with the interrupt numbers.
*/
.code16
.globl __idt_handler
__idt_handler:
pushal
movb $0, %al /* This instruction gets modified */
ljmp $0, $__interrupt_handler_16bit
.globl __idt_handler_size
__idt_handler_size:
.long . - __idt_handler
.macro setup_registers
/* initial register values */
movl 44(%ebp), %eax
movl %eax, __registers + 0 /* eax */
movl 48(%ebp), %eax
movl %eax, __registers + 4 /* ebx */
movl 52(%ebp), %eax
movl %eax, __registers + 8 /* ecx */
movl 56(%ebp), %eax
movl %eax, __registers + 12 /* edx */
movl 60(%ebp), %eax
movl %eax, __registers + 16 /* esi */
movl 64(%ebp), %eax
movl %eax, __registers + 20 /* edi */
.endm
.macro enter_real_mode
/* Activate the right segment descriptor real mode. */
ljmp SEG(X86_GDT_ENTRY_16BIT_CS), $PTR_TO_REAL_MODE(1f)
1:
.code16
/*
* Load the segment registers with properly configured segment
* descriptors. They will retain these configurations (limits,
* writability, etc.) once protected mode is turned off.
*/
mov SEG(X86_GDT_ENTRY_16BIT_DS), %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
/* Turn off protection */
movl %cr0, %eax
andl $~X86_CR0_PE, %eax
movl %eax, %cr0
/* Now really going into real mode */
ljmp $0, $PTR_TO_REAL_MODE(1f)
1:
/*
* Set up a stack: Put the stack at the end of page zero. That way
* we can easily share it between real and protected, since the
* 16-bit ESP at segment 0 will work for any case.
*/
mov $0x0, %ax
mov %ax, %ss
/* Load 16 bit IDT */
xor %ax, %ax
mov %ax, %ds
lidt __realmode_idt
.endm
.macro prepare_for_irom
movl $0x1000, %eax
movl %eax, %esp
/* Initialise registers for option rom lcall */
movl __registers + 0, %eax
movl __registers + 4, %ebx
movl __registers + 8, %ecx
movl __registers + 12, %edx
movl __registers + 16, %esi
movl __registers + 20, %edi
/* Set all segments to 0x0000, ds to 0x0040 */
push %ax
xor %ax, %ax
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov SEG(X86_GDT_ENTRY_16BIT_FLAT_DS), %ax
mov %ax, %ds
pop %ax
.endm
.macro enter_protected_mode
/* Go back to protected mode */
movl %cr0, %eax
orl $X86_CR0_PE, %eax
movl %eax, %cr0
/* Now that we are in protected mode jump to a 32 bit code segment */
data32 ljmp SEG(X86_GDT_ENTRY_32BIT_CS), $PTR_TO_REAL_MODE(1f)
1:
.code32
mov SEG(X86_GDT_ENTRY_32BIT_DS), %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %gs
mov %ax, %ss
mov SEG(X86_GDT_ENTRY_32BIT_FS), %ax
mov %ax, %fs
/* restore proper idt */
lidt idt_ptr
.endm
/*
* In order to be independent of U-Boot's position in RAM we relocate a part
* of the code to the first megabyte of RAM, so the CPU can use it in
* real-mode. This code lives at asm_realmode_code.
*/
.globl asm_realmode_code
asm_realmode_code:
/* Realmode IDT pointer structure. */
__realmode_idt = PTR_TO_REAL_MODE(.)
.word 1023 /* 16 bit limit */
.long 0 /* 24 bit base */
.word 0
/* Preserve old stack */
__stack = PTR_TO_REAL_MODE(.)
.long 0
/* Register store for realmode_call and realmode_interrupt */
__registers = PTR_TO_REAL_MODE(.)
.long 0 /* 0 - EAX */
.long 0 /* 4 - EBX */
.long 0 /* 8 - ECX */
.long 0 /* 12 - EDX */
.long 0 /* 16 - ESI */
.long 0 /* 20 - EDI */
/* 256 byte buffer, used by int10 */
.globl asm_realmode_buffer
asm_realmode_buffer:
.skip 256
.code32
.globl asm_realmode_call
asm_realmode_call:
/* save all registers to the stack */
pusha
pushf
movl %esp, __stack
movl %esp, %ebp
/*
* This function is called with regparm=0 and we have to skip the
* 36 bytes from pushf+pusha. Hence start at 40.
* Set up our call instruction.
*/
movl 40(%ebp), %eax
mov %ax, __lcall_instr + 1
andl $0xffff0000, %eax
shrl $4, %eax
mov %ax, __lcall_instr + 3
wbinvd
setup_registers
enter_real_mode
prepare_for_irom
__lcall_instr = PTR_TO_REAL_MODE(.)
.byte 0x9a
.word 0x0000, 0x0000
enter_protected_mode
/* restore stack pointer, eflags and register values and exit */
movl __stack, %esp
popf
popa
ret
.globl __realmode_interrupt
__realmode_interrupt:
/* save all registers to the stack and store the stack pointer */
pusha
pushf
movl %esp, __stack
movl %esp, %ebp
/*
* This function is called with regparm=0 and we have to skip the
* 36 bytes from pushf+pusha. Hence start at 40.
* Prepare interrupt calling code.
*/
movl 40(%ebp), %eax
movb %al, __intXX_instr + 1 /* intno */
setup_registers
enter_real_mode
prepare_for_irom
__intXX_instr = PTR_TO_REAL_MODE(.)
.byte 0xcd, 0x00 /* This becomes intXX */
enter_protected_mode
/* restore stack pointer, eflags and register values and exit */
movl __stack, %esp
popf
popa
ret
/*
* This is the 16-bit interrupt entry point called by the IDT stub code.
*
* Before this code code is called, %eax is pushed to the stack, and the
* interrupt number is loaded into %al. On return this function cleans up
* for its caller.
*/
.code16
__interrupt_handler_16bit = PTR_TO_REAL_MODE(.)
push %ds
push %es
push %fs
push %gs
/* Clear DF to not break ABI assumptions */
cld
/*
* Clean up the interrupt number. We could do this in the stub, but
* it would cost two more bytes per stub entry.
*/
andl $0xff, %eax
pushl %eax /* ... and make it the first parameter */
enter_protected_mode
/* Call the C interrupt handler */
movl $interrupt_handler, %eax
call *%eax
enter_real_mode
/*
* Restore all registers, including those manipulated by the C
* handler
*/
popl %eax
pop %gs
pop %fs
pop %es
pop %ds
popal
iret
.globl asm_realmode_code_size
asm_realmode_code_size:
.long . - asm_realmode_code

View file

@ -0,0 +1,217 @@
/*
* From Coreboot
*
* Copyright (C) 2001 Ronald G. Minnich
* Copyright (C) 2005 Nick.Barker9@btinternet.com
* Copyright (C) 2007-2009 coresystems GmbH
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/pci.h>
#include "bios_emul.h"
/* errors go in AH. Just set these up so that word assigns will work */
enum {
PCIBIOS_SUCCESSFUL = 0x0000,
PCIBIOS_UNSUPPORTED = 0x8100,
PCIBIOS_BADVENDOR = 0x8300,
PCIBIOS_NODEV = 0x8600,
PCIBIOS_BADREG = 0x8700
};
int int10_handler(void)
{
static u8 cursor_row, cursor_col;
int res = 0;
switch ((M.x86.R_EAX & 0xff00) >> 8) {
case 0x01: /* Set cursor shape */
res = 1;
break;
case 0x02: /* Set cursor position */
if (cursor_row != ((M.x86.R_EDX >> 8) & 0xff) ||
cursor_col >= (M.x86.R_EDX & 0xff)) {
debug("\n");
}
cursor_row = (M.x86.R_EDX >> 8) & 0xff;
cursor_col = M.x86.R_EDX & 0xff;
res = 1;
break;
case 0x03: /* Get cursor position */
M.x86.R_EAX &= 0x00ff;
M.x86.R_ECX = 0x0607;
M.x86.R_EDX = (cursor_row << 8) | cursor_col;
res = 1;
break;
case 0x06: /* Scroll up */
debug("\n");
res = 1;
break;
case 0x08: /* Get Character and Mode at Cursor Position */
M.x86.R_EAX = 0x0f00 | 'A'; /* White on black 'A' */
res = 1;
break;
case 0x09: /* Write Character and attribute */
case 0x0e: /* Write Character */
debug("%c", M.x86.R_EAX & 0xff);
res = 1;
break;
case 0x0f: /* Get video mode */
M.x86.R_EAX = 0x5002; /*80 x 25 */
M.x86.R_EBX &= 0x00ff;
res = 1;
break;
default:
printf("Unknown INT10 function %04x\n", M.x86.R_EAX & 0xffff);
break;
}
return res;
}
int int12_handler(void)
{
M.x86.R_EAX = 64 * 1024;
return 1;
}
int int16_handler(void)
{
int res = 0;
switch ((M.x86.R_EAX & 0xff00) >> 8) {
case 0x00: /* Check for Keystroke */
M.x86.R_EAX = 0x6120; /* Space Bar, Space */
res = 1;
break;
case 0x01: /* Check for Keystroke */
M.x86.R_EFLG |= 1 << 6; /* Zero Flag set (no key available) */
res = 1;
break;
default:
printf("Unknown INT16 function %04x\n", M.x86.R_EAX & 0xffff);
break;
}
return res;
}
#define PCI_CONFIG_SPACE_TYPE1 (1 << 0)
#define PCI_SPECIAL_CYCLE_TYPE1 (1 << 4)
int int1a_handler(void)
{
unsigned short func = (unsigned short)M.x86.R_EAX;
int retval = 1;
unsigned short devid, vendorid, devfn;
/* Use short to get rid of gabage in upper half of 32-bit register */
short devindex;
unsigned char bus;
pci_dev_t dev;
u32 dword;
u16 word;
u8 byte, reg;
switch (func) {
case 0xb101: /* PCIBIOS Check */
M.x86.R_EDX = 0x20494350; /* ' ICP' */
M.x86.R_EAX &= 0xffff0000; /* Clear AH / AL */
M.x86.R_EAX |= PCI_CONFIG_SPACE_TYPE1 |
PCI_SPECIAL_CYCLE_TYPE1;
/*
* last bus in the system. Hard code to 255 for now.
* dev_enumerate() does not seem to tell us (publically)
*/
M.x86.R_ECX = 0xff;
M.x86.R_EDI = 0x00000000; /* protected mode entry */
retval = 1;
break;
case 0xb102: /* Find Device */
devid = M.x86.R_ECX;
vendorid = M.x86.R_EDX;
devindex = M.x86.R_ESI;
dev = pci_find_device(vendorid, devid, devindex);
if (dev != -1) {
unsigned short busdevfn;
M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
M.x86.R_EAX |= PCIBIOS_SUCCESSFUL;
/*
* busnum is an unsigned char;
* devfn is an int, so we mask it off.
*/
busdevfn = (PCI_BUS(dev) << 8) | PCI_DEV(dev) << 3 |
PCI_FUNC(dev);
debug("0x%x: return 0x%x\n", func, busdevfn);
M.x86.R_EBX = busdevfn;
retval = 1;
} else {
M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
M.x86.R_EAX |= PCIBIOS_NODEV;
retval = 0;
}
break;
case 0xb10a: /* Read Config Dword */
case 0xb109: /* Read Config Word */
case 0xb108: /* Read Config Byte */
case 0xb10d: /* Write Config Dword */
case 0xb10c: /* Write Config Word */
case 0xb10b: /* Write Config Byte */
devfn = M.x86.R_EBX & 0xff;
bus = M.x86.R_EBX >> 8;
reg = M.x86.R_EDI;
dev = PCI_BDF(bus, devfn >> 3, devfn & 7);
if (!dev) {
debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func,
bus, devfn);
/* Or are we supposed to return PCIBIOS_NODEV? */
M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
M.x86.R_EAX |= PCIBIOS_BADREG;
retval = 0;
return retval;
}
switch (func) {
case 0xb108: /* Read Config Byte */
byte = pci_read_config8(dev, reg);
M.x86.R_ECX = byte;
break;
case 0xb109: /* Read Config Word */
word = pci_read_config16(dev, reg);
M.x86.R_ECX = word;
break;
case 0xb10a: /* Read Config Dword */
dword = pci_read_config32(dev, reg);
M.x86.R_ECX = dword;
break;
case 0xb10b: /* Write Config Byte */
byte = M.x86.R_ECX;
pci_write_config8(dev, reg, byte);
break;
case 0xb10c: /* Write Config Word */
word = M.x86.R_ECX;
pci_write_config16(dev, reg, word);
break;
case 0xb10d: /* Write Config Dword */
dword = M.x86.R_ECX;
pci_write_config32(dev, reg, dword);
break;
}
#ifdef CONFIG_REALMODE_DEBUG
debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", func,
bus, devfn, reg, M.x86.R_ECX);
#endif
M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
M.x86.R_EAX |= PCIBIOS_SUCCESSFUL;
retval = 1;
break;
default:
printf("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
M.x86.R_EAX |= PCIBIOS_UNSUPPORTED;
retval = 0;
break;
}
return retval;
}

View file

@ -24,12 +24,10 @@
#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined"
#endif
int interrupt_init(void)
int i8259_init(void)
{
u8 i;
disable_interrupts();
/* Mask all interrupts */
outb(0xff, MASTER_PIC + IMR);
outb(0xff, SLAVE_PIC + IMR);
@ -62,7 +60,8 @@ int interrupt_init(void)
*/
unmask_irq(2);
enable_interrupts();
/* Interrupt 9 should be level triggered (SCI). The OS might do this */
configure_irq_trigger(9, true);
return 0;
}
@ -114,3 +113,38 @@ void specific_eoi(int irq)
outb(OCW2_SEOI | irq, MASTER_PIC + OCW2);
}
#define ELCR1 0x4d0
#define ELCR2 0x4d1
void configure_irq_trigger(int int_num, bool is_level_triggered)
{
u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8);
debug("%s: current interrupts are 0x%x\n", __func__, int_bits);
if (is_level_triggered)
int_bits |= (1 << int_num);
else
int_bits &= ~(1 << int_num);
/* Write new values */
debug("%s: try to set interrupts 0x%x\n", __func__, int_bits);
outb((u8)(int_bits & 0xff), ELCR1);
outb((u8)(int_bits >> 8), ELCR2);
#ifdef PARANOID_IRQ_TRIGGERS
/*
* Try reading back the new values. This seems like an error but is
* not
*/
if (inb(ELCR1) != (int_bits & 0xff)) {
printf("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
__func__, (int_bits & 0xff), inb(ELCR1));
}
if (inb(ELCR2) != (int_bits >> 8)) {
printf("%s: higher order bits are wrong: want 0x%x, got 0x%x\n",
__func__, (int_bits>>8), inb(ELCR2));
}
#endif
}

View file

@ -76,6 +76,9 @@ int do_elf_reloc_fixups(void)
/* The size of the region of u-boot that runs out of RAM. */
uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
if (re_src == re_end)
panic("No relocation data");
do {
/* Get the location from the relocation entry */
offset_ptr_rom = (Elf32_Addr *)re_src->r_offset;

View file

@ -5,15 +5,14 @@
*/
#include <common.h>
#include <cros_ec.h>
#include <asm/gpio.h>
int arch_early_init_r(void)
{
return 0;
}
if (cros_ec_board_init())
return -1;
int board_early_init_r(void)
{
return 0;
}

View file

@ -775,7 +775,7 @@ init_fnc_t init_sequence_r[] = {
initr_flash,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PPC) || defined(CONFIG_X86)
#if defined(CONFIG_PPC)
/* initialize higher level parts of CPU like time base and timers */
cpu_init_r,
#endif
@ -837,12 +837,9 @@ init_fnc_t init_sequence_r[] = {
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_CMD_KGDB
initr_kgdb,
#endif
#ifdef CONFIG_X86
board_early_init_r,
#endif
interrupt_init,
#if defined(CONFIG_ARM) || defined(CONFIG_x86)
#if defined(CONFIG_ARM)
initr_enable_interrupts,
#endif
#ifdef CONFIG_X86

View file

@ -0,0 +1,26 @@
Intel Pantherpoint SATA Device Binding
======================================
The device tree node which describes the operation of the Intel Pantherpoint
SATA device is as follows:
Required properties :
- compatible = "intel,pantherpoint-ahci"
- intel,sata-mode : string, one of:
"ahci" : Use AHCI mode (default)
"combined" : Use combined IDE + legacy mode
"plain-ide" : Use plain IDE mode
- intel,sata-port-map : Which SATA ports are enabled, bit 0=enable first port,
bit 1=enable second port, etc.
- intel,sata-port0-gen3-tx : Value for the IOBP_SP0G3IR register
- intel,sata-port1-gen3-tx : Value for the IOBP_SP1G3IR register
Example
-------
sata {
compatible = "intel,pantherpoint-ahci";
intel,sata-mode = "ahci";
intel,sata-port-map = <1>;
intel,sata-port0-gen3-tx = <0x00880a7f>;
};

View file

@ -6,10 +6,37 @@ Count device is as follows:
Required properties :
- compatible = "intel,lpc"
- gen-dec : Specifies the values for the gen-dec registers. Up to four cell
pairs can be provided - the first of each pair is the base address and
- intel,alt-gp-smi-enable : Enable SMI sources. This cell is written to the
ALT_GP_SMI_EN register
- intel,gen-dec : Specifies the values for the gen-dec registers. Up to four
cell pairs can be provided - the first of each pair is the base address and
the second is the size. These are written into the GENx_DEC registers of
the LPC device
- intel,gpi-routing : Specifies the GPI routing. There are 16 cells, valid
values are:
0 No effect (default)
1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set)
2 SCI (if corresponding GPIO_EN bit is also set)
- intel,pirq-routing : Speciffies the routing IRQ number for each of PIRQA-H,
one cell for each.
0x00 - 0000 = Reserved
0x01 - 0001 = Reserved
0x02 - 0010 = Reserved
0x03 - 0011 = IRQ3
0x04 - 0100 = IRQ4
0x05 - 0101 = IRQ5
0x06 - 0110 = IRQ6
0x07 - 0111 = IRQ7
0x08 - 1000 = Reserved
0x09 - 1001 = IRQ9
0x0A - 1010 = IRQ10
0x0B - 1011 = IRQ11
0x0C - 1100 = IRQ12
0x0D - 1101 = Reserved
0x0E - 1110 = IRQ14
0x0F - 1111 = IRQ15
PIRQ[n]_ROUT[7] - PIRQ Routing Control
0x80 - The PIRQ is not routed.
Example
@ -19,5 +46,19 @@ 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>;
/*
* GPI routing
* 0 No effect (default)
* 1 SMI# (if corresponding ALT_GPI_SMI_EN bit is
* also set)
* 2 SCI (if corresponding GPIO_EN bit is also set)
*/
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>;
};

View file

@ -0,0 +1,40 @@
Intel GMA Bindings
==================
This is the Intel Graphics Media Accelerator. This binding supports selection
of display parameters only.
Required properties:
- compatible : "intel,gma";
Optional properties:
- intel,dp-hotplug : values for digital port hotplug, one cell per value for
ports B, C and D
- intel,panel-port-select : output port to use: 0=LVDS 1=DP_B 2=DP_C 3=DP_D
- intel,panel-power-cycle-delay : T4 time sequence (6 = 500ms)
The following delays are in units of 0.1ms:
- intel,panel-power-up-delay : T1+T2 time sequence
- intel,panel-power-down-delay : T3 time sequence
- intel,panel-power-backlight-on-delay : T5 time sequence
- intel,panel-power-backlight-off-delay : Tx time sequence
- intel,cpu-backlight : Value for CPU Backlight PWM
- intel,pch-backlight : Value for PCH Backlight PWM
Example
-------
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>;
};

View file

@ -9,4 +9,4 @@ obj-y = atibios.o biosemu.o besys.o bios.o \
$(X86DIR)/debug.o
ccflags-y := -I$(srctree)/$(src) -I$(srctree)/$(src)/include \
-D__PPC__ -D__BIG_ENDIAN__
$(if $(CONFIG_PPC),-D__PPC__ -D__BIG_ENDIAN__)

View file

@ -46,8 +46,11 @@
* BIOS in u-boot.
****************************************************************************/
#include <common.h>
#include "biosemui.h"
#include <bios_emul.h>
#include <errno.h>
#include <malloc.h>
#include <vbe.h>
#include "biosemui.h"
/* Length of the BIOS image */
#define MAX_BIOSLEN (128 * 1024L)
@ -59,17 +62,54 @@ static u32 saveBaseAddress14;
static u32 saveBaseAddress18;
static u32 saveBaseAddress20;
static void atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
struct vbe_mode_info *mode_info)
{
debug("VBE: Setting VESA mode %#04x\n", vesa_mode);
/* request linear framebuffer mode */
vesa_mode |= (1 << 14);
/* request clearing of framebuffer */
vesa_mode &= ~(1 << 15);
regs->e.eax = VESA_SET_MODE;
regs->e.ebx = vesa_mode;
BE_int86(0x10, regs, regs);
int offset = 0x2000;
void *buffer = (void *)(M.mem_base + offset);
u16 buffer_seg = (((unsigned long)offset) >> 4) & 0xff00;
u16 buffer_adr = ((unsigned long)offset) & 0xffff;
regs->e.eax = VESA_GET_MODE_INFO;
regs->e.ebx = 0;
regs->e.ecx = vesa_mode;
regs->e.edx = 0;
regs->e.esi = buffer_seg;
regs->e.edi = buffer_adr;
BE_int86(0x10, regs, regs);
memcpy(mode_info->mode_info_block, buffer,
sizeof(struct vbe_mode_info));
mode_info->valid = true;
vesa_mode |= (1 << 14);
/* request clearing of framebuffer */
vesa_mode &= ~(1 << 15);
regs->e.eax = VESA_SET_MODE;
regs->e.ebx = vesa_mode;
BE_int86(0x10, regs, regs);
}
/****************************************************************************
PARAMETERS:
pcidev - PCI device info for the video card on the bus to boot
VGAInfo - BIOS emulator VGA info structure
vga_info - BIOS emulator VGA info structure
REMARKS:
This function executes the BIOS POST code on the controller. We assume that
at this stage the controller has its I/O and memory space enabled and
that all other controllers are in a disabled state.
****************************************************************************/
static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo)
static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info,
int vesa_mode, struct vbe_mode_info *mode_info)
{
RMREGS regs;
RMSREGS sregs;
@ -84,13 +124,16 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo)
((int)PCI_DEV(pcidev) << 3) | (int)PCI_FUNC(pcidev);
/*Setup the X86 emulator for the VGA BIOS*/
BE_setVGA(VGAInfo);
BE_setVGA(vga_info);
/*Execute the BIOS POST code*/
BE_callRealMode(0xC000, 0x0003, &regs, &sregs);
/*Cleanup and exit*/
BE_getVGA(VGAInfo);
BE_getVGA(vga_info);
if (vesa_mode != -1)
atibios_set_vesa_mode(&regs, vesa_mode, mode_info);
}
/****************************************************************************
@ -244,49 +287,109 @@ REMARKS:
Loads and POST's the display controllers BIOS, directly from the BIOS
image we can extract over the PCI bus.
****************************************************************************/
static int PCI_postController(pci_dev_t pcidev, BE_VGAInfo * VGAInfo)
static int PCI_postController(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
BE_VGAInfo *vga_info, int vesa_mode,
struct vbe_mode_info *mode_info)
{
u32 BIOSImageLen;
uchar *mappedBIOS;
uchar *copyOfBIOS;
u32 bios_image_len;
uchar *mapped_bios;
uchar *copy_of_bios;
/*Allocate memory to store copy of BIOS from display controller*/
if ((mappedBIOS = PCI_mapBIOSImage(pcidev)) == NULL) {
if (bios_rom) {
copy_of_bios = bios_rom;
bios_image_len = bios_len;
} else {
/*
* Allocate memory to store copy of BIOS from display
* controller
*/
mapped_bios = PCI_mapBIOSImage(pcidev);
if (mapped_bios == NULL) {
printf("videoboot: Video ROM failed to map!\n");
return false;
}
BIOSImageLen = mappedBIOS[2] * 512;
bios_image_len = mapped_bios[2] * 512;
if ((copyOfBIOS = malloc(BIOSImageLen)) == NULL) {
copy_of_bios = malloc(bios_image_len);
if (copy_of_bios == NULL) {
printf("videoboot: Out of memory!\n");
return false;
}
memcpy(copyOfBIOS, mappedBIOS, BIOSImageLen);
memcpy(copy_of_bios, mapped_bios, bios_image_len);
PCI_unmapBIOSImage(pcidev, mapped_bios);
}
PCI_unmapBIOSImage(pcidev, mappedBIOS);
/*Save information in VGAInfo structure*/
VGAInfo->function = PCI_FUNC(pcidev);
VGAInfo->device = PCI_DEV(pcidev);
VGAInfo->bus = PCI_BUS(pcidev);
VGAInfo->pcidev = pcidev;
VGAInfo->BIOSImage = copyOfBIOS;
VGAInfo->BIOSImageLen = BIOSImageLen;
/*Save information in vga_info structure*/
vga_info->function = PCI_FUNC(pcidev);
vga_info->device = PCI_DEV(pcidev);
vga_info->bus = PCI_BUS(pcidev);
vga_info->pcidev = pcidev;
vga_info->BIOSImage = copy_of_bios;
vga_info->BIOSImageLen = bios_image_len;
/*Now execute the BIOS POST for the device*/
if (copyOfBIOS[0] != 0x55 || copyOfBIOS[1] != 0xAA) {
if (copy_of_bios[0] != 0x55 || copy_of_bios[1] != 0xAA) {
printf("videoboot: Video ROM image is invalid!\n");
return false;
}
PCI_doBIOSPOST(pcidev, VGAInfo);
PCI_doBIOSPOST(pcidev, vga_info, vesa_mode, mode_info);
/*Reset the size of the BIOS image to the final size*/
VGAInfo->BIOSImageLen = copyOfBIOS[2] * 512;
vga_info->BIOSImageLen = copy_of_bios[2] * 512;
return true;
}
int biosemu_setup(pci_dev_t pcidev, BE_VGAInfo **vga_infop)
{
BE_VGAInfo *VGAInfo;
printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
PCI_BUS(pcidev), PCI_FUNC(pcidev), PCI_DEV(pcidev));
/*Initialise the x86 BIOS emulator*/
if ((VGAInfo = malloc(sizeof(*VGAInfo))) == NULL) {
printf("videoboot: Out of memory!\n");
return -ENOMEM;
}
memset(VGAInfo, 0, sizeof(*VGAInfo));
BE_init(0, 65536, VGAInfo, 0);
*vga_infop = VGAInfo;
return 0;
}
void biosemu_set_interrupt_handler(int intnum, int (*int_func)(void))
{
X86EMU_setupIntrFunc(intnum, (X86EMU_intrFuncs)int_func);
}
int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
struct vbe_mode_info *mode_info)
{
/*Post all the display controller BIOS'es*/
if (!PCI_postController(pcidev, bios_rom, bios_len, vga_info,
vesa_mode, mode_info))
return -EINVAL;
/*
* Cleanup and exit the emulator if requested. If the BIOS emulator
* is needed after booting the card, we will not call BE_exit and
* leave it enabled for further use (ie: VESA driver etc).
*/
if (clean_up) {
BE_exit();
if (vga_info->BIOSImage)
free(vga_info->BIOSImage);
free(vga_info);
vga_info = NULL;
}
return 0;
}
/****************************************************************************
PARAMETERS:
pcidev - PCI device info for the video card on the bus to boot
@ -297,38 +400,21 @@ REMARKS:
Boots the PCI/AGP video card on the bus using the Video ROM BIOS image
and the X86 BIOS emulator module.
****************************************************************************/
int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp)
int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int clean_up)
{
BE_VGAInfo *VGAInfo;
int ret;
printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
PCI_BUS(pcidev), PCI_FUNC(pcidev), PCI_DEV(pcidev));
/*Initialise the x86 BIOS emulator*/
if ((VGAInfo = malloc(sizeof(*VGAInfo))) == NULL) {
printf("videoboot: Out of memory!\n");
ret = biosemu_setup(pcidev, &VGAInfo);
if (ret)
return false;
}
memset(VGAInfo, 0, sizeof(*VGAInfo));
BE_init(0, 65536, VGAInfo, 0);
/*Post all the display controller BIOS'es*/
if (!PCI_postController(pcidev, VGAInfo))
ret = biosemu_run(pcidev, NULL, 0, VGAInfo, clean_up, -1, NULL);
if (ret)
return false;
/*Cleanup and exit the emulator if requested. If the BIOS emulator
is needed after booting the card, we will not call BE_exit and
leave it enabled for further use (ie: VESA driver etc).
*/
if (cleanUp) {
BE_exit();
if (VGAInfo->BIOSImage)
free(VGAInfo->BIOSImage);
free(VGAInfo);
VGAInfo = NULL;
}
/*Return VGA info pointer if the caller requested it*/
/* Return VGA info pointer if the caller requested it*/
if (pVGAInfo)
*pVGAInfo = VGAInfo;
return true;
}

View file

@ -54,12 +54,20 @@
/*------------------------- Global Variables ------------------------------*/
#ifndef __i386__
#ifndef CONFIG_X86EMU_RAW_IO
static char *BE_biosDate = "08/14/99";
static u8 BE_model = 0xFC;
static u8 BE_submodel = 0x00;
#endif
#undef DEBUG_IO_ACCESS
#ifdef DEBUG_IO_ACCESS
#define debug_io(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define debug_io(x, b...)
#endif
/*----------------------------- Implementation ----------------------------*/
/****************************************************************************
@ -80,38 +88,40 @@ static u8 *BE_memaddr(u32 addr)
if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
return (u8*)(_BE_env.biosmem_base + addr - 0xC0000);
} else if (addr > _BE_env.biosmem_limit && addr < 0xD0000) {
DB(printf("BE_memaddr: address %#lx may be invalid!\n", addr);)
return M.mem_base;
DB(printf("BE_memaddr: address %#lx may be invalid!\n",
(ulong)addr);)
return (u8 *)M.mem_base;
} else if (addr >= 0xA0000 && addr <= 0xBFFFF) {
return (u8*)(_BE_env.busmem_base + addr - 0xA0000);
}
#ifdef __i386__
#ifdef CONFIG_X86EMU_RAW_IO
else if (addr >= 0xD0000 && addr <= 0xFFFFF) {
/* We map the real System BIOS directly on real PC's */
DB(printf("BE_memaddr: System BIOS address %#lx\n", addr);)
return _BE_env.busmem_base + addr - 0xA0000;
DB(printf("BE_memaddr: System BIOS address %#lx\n",
(ulong)addr);)
return (u8 *)_BE_env.busmem_base + addr - 0xA0000;
}
#else
else if (addr >= 0xFFFF5 && addr < 0xFFFFE) {
/* Return a faked BIOS date string for non-x86 machines */
DB(printf("BE_memaddr - Returning BIOS date\n");)
debug_io("BE_memaddr - Returning BIOS date\n");
return (u8 *)(BE_biosDate + addr - 0xFFFF5);
} else if (addr == 0xFFFFE) {
/* Return system model identifier for non-x86 machines */
DB(printf("BE_memaddr - Returning model\n");)
debug_io("BE_memaddr - Returning model\n");
return &BE_model;
} else if (addr == 0xFFFFF) {
/* Return system submodel identifier for non-x86 machines */
DB(printf("BE_memaddr - Returning submodel\n");)
debug_io("BE_memaddr - Returning submodel\n");
return &BE_submodel;
}
#endif
else if (addr > M.mem_size - 1) {
HALT_SYS();
return M.mem_base;
return (u8 *)M.mem_base;
}
return M.mem_base + addr;
return (u8 *)(M.mem_base + addr);
}
/****************************************************************************
@ -230,7 +240,7 @@ void X86API BE_wrl(u32 addr, u32 val)
}
}
#if defined(DEBUG) || !defined(__i386__)
#if !defined(CONFIG_X86EMU_RAW_IO)
/* For Non-Intel machines we may need to emulate some I/O port accesses that
* the BIOS may try to access, such as the PCI config registers.
@ -258,6 +268,7 @@ static u8 VGA_inpb (const int port)
{
u8 val = 0xff;
debug_io("vga_inb.%04X -> ", (u16) port);
switch (port) {
case 0x3C0:
/* 3C0 has funky characteristics because it can act as either
@ -560,7 +571,7 @@ u8 X86API BE_inb(X86EMU_pioAddr port)
{
u8 val = 0;
#if defined(DEBUG) || !defined(__i386__)
#if !defined(CONFIG_X86EMU_RAW_IO)
if (IS_VGA_PORT(port)){
/*seems reading port 0x3c3 return the high 16 bit of io port*/
if(port == 0x3c3)
@ -581,7 +592,12 @@ u8 X86API BE_inb(X86EMU_pioAddr port)
val = LOG_inpb(port);
} else
#endif
{
debug_io("inb.%04X -> ", (u16) port);
val = LOG_inpb(port);
debug_io("%02X\n", val);
}
return val;
}
@ -601,7 +617,7 @@ u16 X86API BE_inw(X86EMU_pioAddr port)
{
u16 val = 0;
#if defined(DEBUG) || !defined(__i386__)
#if !defined(CONFIG_X86EMU_RAW_IO)
if (IS_PCI_PORT(port))
val = PCI_inp(port, REG_READ_WORD);
else if (port < 0x100) {
@ -609,7 +625,12 @@ u16 X86API BE_inw(X86EMU_pioAddr port)
val = LOG_inpw(port);
} else
#endif
{
debug_io("inw.%04X -> ", (u16) port);
val = LOG_inpw(port);
debug_io("%04X\n", val);
}
return val;
}
@ -629,14 +650,19 @@ u32 X86API BE_inl(X86EMU_pioAddr port)
{
u32 val = 0;
#if defined(DEBUG) || !defined(__i386__)
#if !defined(CONFIG_X86EMU_RAW_IO)
if (IS_PCI_PORT(port))
val = PCI_inp(port, REG_READ_DWORD);
else if (port < 0x100) {
val = LOG_inpd(port);
} else
#endif
{
debug_io("inl.%04X -> ", (u16) port);
val = LOG_inpd(port);
debug_io("%08X\n", val);
}
return val;
}
@ -652,7 +678,7 @@ through to the real hardware if we don't need to special case it.
****************************************************************************/
void X86API BE_outb(X86EMU_pioAddr port, u8 val)
{
#if defined(DEBUG) || !defined(__i386__)
#if !defined(CONFIG_X86EMU_RAW_IO)
if (IS_VGA_PORT(port))
VGA_outpb(port, val);
else if (IS_TIMER_PORT(port))
@ -668,7 +694,11 @@ void X86API BE_outb(X86EMU_pioAddr port, u8 val)
LOG_outpb(port, val);
} else
#endif
{
debug_io("outb.%04X <- %02X", (u16) port, val);
LOG_outpb(port, val);
debug_io("\n");
}
}
/****************************************************************************
@ -683,19 +713,23 @@ through to the real hardware if we don't need to special case it.
****************************************************************************/
void X86API BE_outw(X86EMU_pioAddr port, u16 val)
{
#if defined(DEBUG) || !defined(__i386__)
#if !defined(CONFIG_X86EMU_RAW_IO)
if (IS_VGA_PORT(port)) {
VGA_outpb(port, val);
VGA_outpb(port + 1, val >> 8);
} else if (IS_PCI_PORT(port))
} else if (IS_PCI_PORT(port)) {
PCI_outp(port, val, REG_WRITE_WORD);
else if (port < 0x100) {
DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16) port,
} else if (port < 0x100) {
DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16)port,
val);)
LOG_outpw(port, val);
} else
#endif
{
debug_io("outw.%04X <- %04X", (u16) port, val);
LOG_outpw(port, val);
debug_io("\n");
}
}
/****************************************************************************
@ -710,13 +744,17 @@ through to the real hardware if we don't need to special case it.
****************************************************************************/
void X86API BE_outl(X86EMU_pioAddr port, u32 val)
{
#if defined(DEBUG) || !defined(__i386__)
if (IS_PCI_PORT(port))
#if !defined(CONFIG_X86EMU_RAW_IO)
if (IS_PCI_PORT(port)) {
PCI_outp(port, val, REG_WRITE_DWORD);
else if (port < 0x100) {
} else if (port < 0x100) {
DB(printf("WARN: INVALID outl.%04X <- %08X\n", (u16) port,val);)
LOG_outpd(port, val);
} else
#endif
{
debug_io("outl.%04X <- %08X", (u16) port, val);
LOG_outpd(port, val);
debug_io("\n");
}
}

View file

@ -84,14 +84,14 @@ static void X86API int42(int intno)
PM_outpb(0x3c2, PM_inpb(0x3cc) & (u8) ~ 0x02);
return;
}
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
else {
printf("int42: unknown function AH=0x12, BL=0x32, AL=%#02x\n",
M.x86.R_AL);
}
#endif
}
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
else {
printf("int42: unknown function AH=%#02x, AL=%#02x, BL=%#02x\n",
M.x86.R_AH, M.x86.R_AL, M.x86.R_BL);

View file

@ -48,7 +48,7 @@
#include <asm/io.h>
/*---------------------- Macros and type definitions ----------------------*/
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
#define DB(x) x
#else
#define DB(x) do{}while(0);

View file

@ -43,6 +43,8 @@
#ifndef __BIOSEMU_H
#define __BIOSEMU_H
#include <bios_emul.h>
#ifdef __KERNEL__
#include "x86emu.h"
#else
@ -55,57 +57,6 @@
#pragma pack(1)
#ifndef __KERNEL__
/****************************************************************************
REMARKS:
Data structure used to describe the details specific to a particular VGA
controller. This information is used to allow the VGA controller to be
swapped on the fly within the BIOS emulator.
HEADER:
biosemu.h
MEMBERS:
pciInfo - PCI device information block for the controller
BIOSImage - Pointer to a read/write copy of the BIOS image
BIOSImageLen - Length of the BIOS image
LowMem - Copy of key low memory areas
****************************************************************************/
typedef struct {
PCIDeviceInfo *pciInfo;
void *BIOSImage;
ulong BIOSImageLen;
uchar LowMem[1536];
} BE_VGAInfo;
#else
/****************************************************************************
REMARKS:
Data structure used to describe the details for the BIOS emulator system
environment as used by the X86 emulator library.
HEADER:
biosemu.h
MEMBERS:
vgaInfo - VGA BIOS information structure
biosmem_base - Base of the BIOS image
biosmem_limit - Limit of the BIOS image
busmem_base - Base of the VGA bus memory
****************************************************************************/
typedef struct {
int function;
int device;
int bus;
u32 VendorID;
u32 DeviceID;
pci_dev_t pcidev;
void *BIOSImage;
u32 BIOSImageLen;
u8 LowMem[1536];
} BE_VGAInfo;
#endif /* __KERNEL__ */
#define CRT_C 24 /* 24 CRT Controller Registers */
#define ATT_C 21 /* 21 Attribute Controller Registers */
#define GRA_C 9 /* 9 Graphics Controller Registers */

View file

@ -53,9 +53,9 @@ typedef u16 X86EMU_pioAddr;
/*---------------------- Macros and type definitions ----------------------*/
#if defined (CONFIG_ARM)
#if defined(CONFIG_ARM)
#define GAS_LINE_COMMENT "@"
#elif defined(CONFIG_MIPS) || defined(CONFIG_PPC)
#elif defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_X86)
#define GAS_LINE_COMMENT "#"
#elif defined (CONFIG_SH)
#define GAS_LINE_COMMENT "!"
@ -153,6 +153,7 @@ extern "C" { /* Use "C" linkage when in C++ mode */
void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs);
void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs);
void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
void X86EMU_setupIntrFunc(int intnum, X86EMU_intrFuncs func);
void X86EMU_prepareForInt(int num);
/* decode.c */
@ -160,7 +161,7 @@ extern "C" { /* Use "C" linkage when in C++ mode */
void X86EMU_exec(void);
void X86EMU_halt_sys(void);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
#define HALT_SYS() \
printf("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \
X86EMU_halt_sys()

View file

@ -48,7 +48,7 @@
#define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */
#define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset */
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
# define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F)
# define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F)
# define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F)
@ -60,7 +60,7 @@
# define CHECK_DATA_ACCESS()
#endif
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
# define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F)
# define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F)
# define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F)
@ -99,7 +99,11 @@
# define DEBUG_DECODE_NOPRINT() 0
#endif
#ifdef DEBUG
# define ERR_PRINTF(x) printf(x)
# define ERR_PRINTF2(x, y) printf(x, y)
#ifdef CONFIG_X86EMU_DEBUG103
# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
x86emu_decode_printf(x)
@ -129,7 +133,7 @@
# define SAVE_IP_CS(x,y)
#endif
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
#define TRACE_REGS() \
if (DEBUG_DISASSEMBLE()) { \
x86emu_just_disassemble(); \
@ -140,7 +144,7 @@
# define TRACE_REGS()
#endif
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
# define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step()
#else
# define SINGLE_STEP()
@ -150,7 +154,7 @@
TRACE_REGS(); \
SINGLE_STEP()
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
# define START_OF_INSTR()
# define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr();
# define END_OF_INSTR_NO_TRACE() x86emu_end_instr();
@ -160,7 +164,7 @@
# define END_OF_INSTR_NO_TRACE()
#endif
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
# define CALL_TRACE(u,v,w,x,s) \
if (DEBUG_TRACECALLREGS()) \
x86emu_dump_regs(); \
@ -176,7 +180,7 @@
# define RETURN_TRACE(n,u,v)
#endif
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
#define DB(x) x
#else
#define DB(x)

View file

@ -282,7 +282,7 @@ typedef struct {
u8 intno;
volatile int intr; /* mask of pending interrupts */
int debug;
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
int check;
u16 saved_ip;
u16 saved_cs;

View file

@ -44,7 +44,7 @@
/*----------------------------- Implementation ----------------------------*/
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
static void print_encoded_bytes(u16 s, u16 o);
static void print_decoded_instruction(void);
@ -211,9 +211,7 @@ void X86EMU_dump_memory(u16 seg, u16 off, u32 amt)
u32 start = off & 0xfffffff0;
u32 end = (off + 16) & 0xfffffff0;
u32 i;
u32 current;
current = start;
while (end <= off + amt) {
printk("%04x:%04x ", seg, start);
for (i = start; i < off; i++)
@ -238,8 +236,6 @@ void x86emu_single_step(void)
static int breakpoint;
static int noDecode = 1;
char *p;
if (DEBUG_BREAK()) {
if (M.x86.saved_ip != breakpoint) {
return;
@ -255,6 +251,8 @@ void x86emu_single_step(void)
offset = M.x86.saved_ip;
while (!done) {
printk("-");
ps[1] = 0; /* Avoid dodgy compiler warnings */
ps[2] = 0;
cmd = x86emu_parse_line(s, ps, &ntok);
switch (cmd) {
case 'u':

View file

@ -303,7 +303,7 @@ NOTE: Do not inline this function as (*sys_rdX) is already inline!
u8 fetch_data_byte(
uint offset)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
@ -322,7 +322,7 @@ NOTE: Do not inline this function as (*sys_rdX) is already inline!
u16 fetch_data_word(
uint offset)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
@ -341,7 +341,7 @@ NOTE: Do not inline this function as (*sys_rdX) is already inline!
u32 fetch_data_long(
uint offset)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
@ -362,7 +362,7 @@ u8 fetch_data_byte_abs(
uint segment,
uint offset)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access(segment, offset);
#endif
@ -383,7 +383,7 @@ u16 fetch_data_word_abs(
uint segment,
uint offset)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access(segment, offset);
#endif
@ -404,7 +404,7 @@ u32 fetch_data_long_abs(
uint segment,
uint offset)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access(segment, offset);
#endif
@ -426,7 +426,7 @@ void store_data_byte(
uint offset,
u8 val)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
@ -448,7 +448,7 @@ void store_data_word(
uint offset,
u16 val)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
@ -470,7 +470,7 @@ void store_data_long(
uint offset,
u32 val)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
@ -493,7 +493,7 @@ void store_data_byte_abs(
uint offset,
u8 val)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access(segment, offset);
#endif
@ -516,7 +516,7 @@ void store_data_word_abs(
uint offset,
u16 val)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access(segment, offset);
#endif
@ -539,7 +539,7 @@ void store_data_long_abs(
uint offset,
u32 val)
{
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (CHECK_DATA_ACCESS())
x86emu_check_data_access(segment, offset);
#endif

View file

@ -79,7 +79,7 @@
/* constant arrays to do several instructions in just one function */
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
static char *x86emu_GenOpName[8] = {
"ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
#endif
@ -160,7 +160,7 @@ static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
sar_long,
};
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
static char *opF6_names[8] =
{ "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
@ -179,7 +179,7 @@ void x86emuOp_illegal_op(
{
START_OF_INSTR();
if (M.x86.R_SP != 0) {
DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
ERR_PRINTF("ILLEGAL X86 OPCODE\n");
TRACE_REGS();
DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
M.x86.R_CS, M.x86.R_IP-1,op1));
@ -1281,7 +1281,7 @@ void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -1359,7 +1359,7 @@ void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -1475,7 +1475,7 @@ void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -1551,7 +1551,7 @@ void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -2148,7 +2148,7 @@ void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("POP\t");
FETCH_DECODE_MODRM(mod, rh, rl);
if (rh != 0) {
DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
ERR_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
HALT_SYS();
}
if (mod < 3) {
@ -3083,7 +3083,7 @@ void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -3158,7 +3158,7 @@ void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -3347,7 +3347,7 @@ void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("MOV\t");
FETCH_DECODE_MODRM(mod, rh, rl);
if (rh != 0) {
DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
ERR_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
HALT_SYS();
}
if (mod < 3) {
@ -3381,7 +3381,7 @@ void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("MOV\t");
FETCH_DECODE_MODRM(mod, rh, rl);
if (rh != 0) {
DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
ERR_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
HALT_SYS();
}
if (mod < 3) {
@ -3630,7 +3630,7 @@ void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -3701,7 +3701,7 @@ void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -3803,7 +3803,7 @@ void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -3876,7 +3876,7 @@ void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -3968,7 +3968,7 @@ void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("AAM\n");
a = fetch_byte_imm(); /* this is a stupid encoding. */
if (a != 10) {
DECODE_PRINTF("ERROR DECODING AAM\n");
ERR_PRINTF("ERROR DECODING AAM\n");
TRACE_REGS();
HALT_SYS();
}
@ -4443,7 +4443,7 @@ void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
test_byte(destval, srcval);
break;
case 1:
DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
HALT_SYS();
break;
case 2:
@ -4490,7 +4490,7 @@ void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
test_byte(*destreg, srcval);
break;
case 1:
DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
HALT_SYS();
break;
case 2:
@ -4559,7 +4559,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
test_long(destval, srcval);
break;
case 1:
DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
HALT_SYS();
break;
case 2:
@ -4611,7 +4611,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
test_word(destval, srcval);
break;
case 1:
DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
HALT_SYS();
break;
case 2:
@ -4666,7 +4666,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
test_long(*destreg, srcval);
break;
case 1:
DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
HALT_SYS();
break;
case 2:
@ -4715,7 +4715,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
test_word(*destreg, srcval);
break;
case 1:
DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
HALT_SYS();
break;
case 2:
@ -4859,7 +4859,7 @@ void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
/* Yet another special case instruction. */
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -4879,7 +4879,7 @@ void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
case 5:
case 6:
case 7:
DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
ERR_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x\n", mod);
HALT_SYS();
break;
}
@ -4923,7 +4923,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
/* Yet another special case instruction. */
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef CONFIG_X86EMU_DEBUG
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@ -4961,7 +4961,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF("PUSH\t");
break;
case 7:
DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
ERR_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
HALT_SYS();
break;
}
@ -5092,7 +5092,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
M.x86.R_IP = *destreg;
break;
case 3: /* jmp far ptr ... */
DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
ERR_PRINTF("OPERATION UNDEFINED 0XFF\n");
TRACE_AND_STEP();
HALT_SYS();
break;
@ -5104,7 +5104,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
M.x86.R_IP = (u16) (*destreg);
break;
case 5: /* jmp far ptr ... */
DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
ERR_PRINTF("OPERATION UNDEFINED 0XFF\n");
TRACE_AND_STEP();
HALT_SYS();
break;

View file

@ -58,7 +58,7 @@ void x86emuOp2_illegal_op(
u8 op2)
{
START_OF_INSTR();
DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
TRACE_REGS();
printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
M.x86.R_CS, M.x86.R_IP-2,op2);
@ -1089,7 +1089,7 @@ void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
DECODE_PRINTF("BTC\t");
break;
default:
DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
TRACE_REGS();
printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);

View file

@ -273,6 +273,11 @@ void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)
sys_outl = funcs->outl;
}
void X86EMU_setupIntrFunc(int intnum, X86EMU_intrFuncs func)
{
_X86EMU_intrTab[intnum] = func;
}
/****************************************************************************
PARAMETERS:
funcs - New interrupt vector table to make active

View file

@ -6,7 +6,7 @@
#
obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
obj-$(CONFIG_PCI) += pci.o pci_auto.o
obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o
obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
obj-$(CONFIG_PCI_MSC01) += pci_msc01.o

View file

@ -366,9 +366,27 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
return phys_addr;
}
/*
*
*/
void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
u32 addr_and_ctrl)
{
int bar;
bar = PCI_BASE_ADDRESS_0 + barnum * 4;
pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
}
u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
{
u32 addr;
int bar;
bar = PCI_BASE_ADDRESS_0 + barnum * 4;
pci_hose_read_config_dword(hose, dev, bar, &addr);
if (addr & PCI_BASE_ADDRESS_SPACE_IO)
return addr & PCI_BASE_ADDRESS_IO_MASK;
else
return addr & PCI_BASE_ADDRESS_MEM_MASK;
}
int pci_hose_config_device(struct pci_controller *hose,
pci_dev_t dev,

278
drivers/pci/pci_rom.c Normal file
View file

@ -0,0 +1,278 @@
/*
* Copyright (C) 2014 Google, Inc
*
* From coreboot, originally based on the Linux kernel (drivers/pci/pci.c).
*
* Modifications are:
* Copyright (C) 2003-2004 Linux Networx
* (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
* Copyright (C) 2003-2006 Ronald G. Minnich <rminnich@gmail.com>
* Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov>
* Copyright (C) 2005-2006 Tyan
* (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
* Copyright (C) 2005-2009 coresystems GmbH
* (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
*
* PCI Bus Services, see include/linux/pci.h for further explanation.
*
* Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
* David Mosberger-Tang
*
* Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <bios_emul.h>
#include <errno.h>
#include <malloc.h>
#include <pci.h>
#include <pci_rom.h>
#include <vbe.h>
#include <video_fb.h>
#ifdef CONFIG_HAVE_ACPI_RESUME
#include <asm/acpi.h>
#endif
__weak bool board_should_run_oprom(pci_dev_t dev)
{
return true;
}
static bool should_load_oprom(pci_dev_t dev)
{
#ifdef CONFIG_HAVE_ACPI_RESUME
if (acpi_get_slp_type() == 3)
return false;
#endif
if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM))
return 1;
if (board_should_run_oprom(dev))
return 1;
return 0;
}
__weak uint32_t board_map_oprom_vendev(uint32_t vendev)
{
return vendev;
}
static int pci_rom_probe(pci_dev_t dev, uint class,
struct pci_rom_header **hdrp)
{
struct pci_rom_header *rom_header;
struct pci_rom_data *rom_data;
u16 vendor, device;
u32 vendev;
u32 mapped_vendev;
u32 rom_address;
pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
pci_read_config_word(dev, PCI_DEVICE_ID, &device);
vendev = vendor << 16 | device;
mapped_vendev = board_map_oprom_vendev(vendev);
if (vendev != mapped_vendev)
debug("Device ID mapped to %#08x\n", mapped_vendev);
#ifdef CONFIG_X86_OPTION_ROM_ADDR
rom_address = CONFIG_X86_OPTION_ROM_ADDR;
#else
pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK);
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address);
if (rom_address == 0x00000000 || rom_address == 0xffffffff) {
debug("%s: rom_address=%x\n", __func__, rom_address);
return -ENOENT;
}
/* Enable expansion ROM address decoding. */
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
rom_address | PCI_ROM_ADDRESS_ENABLE);
#endif
debug("Option ROM address %x\n", rom_address);
rom_header = (struct pci_rom_header *)rom_address;
debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n",
le32_to_cpu(rom_header->signature),
rom_header->size * 512, le32_to_cpu(rom_header->data));
if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
printf("Incorrect expansion ROM header signature %04x\n",
le32_to_cpu(rom_header->signature));
return -EINVAL;
}
rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
debug("PCI ROM image, vendor ID %04x, device ID %04x,\n",
rom_data->vendor, rom_data->device);
/* If the device id is mapped, a mismatch is expected */
if ((vendor != rom_data->vendor || device != rom_data->device) &&
(vendev == mapped_vendev)) {
printf("ID mismatch: vendor ID %04x, device ID %04x\n",
rom_data->vendor, rom_data->device);
return -EPERM;
}
debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n",
rom_data->class_hi, rom_data->class_lo, rom_data->type);
if (class != ((rom_data->class_hi << 8) | rom_data->class_lo)) {
debug("Class Code mismatch ROM %08x, dev %08x\n",
(rom_data->class_hi << 8) | rom_data->class_lo,
class);
}
*hdrp = rom_header;
return 0;
}
int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header,
struct pci_rom_header **ram_headerp)
{
struct pci_rom_data *rom_data;
unsigned int rom_size;
unsigned int image_size = 0;
void *target;
do {
/* Get next image, until we see an x86 version */
rom_header = (struct pci_rom_header *)((void *)rom_header +
image_size);
rom_data = (struct pci_rom_data *)((void *)rom_header +
le32_to_cpu(rom_header->data));
image_size = le32_to_cpu(rom_data->ilen) * 512;
} while ((rom_data->type != 0) && (rom_data->indicator != 0));
if (rom_data->type != 0)
return -EACCES;
rom_size = rom_header->size * 512;
target = (void *)PCI_VGA_RAM_IMAGE_START;
if (target != rom_header) {
debug("Copying VGA ROM Image from %p to %p, 0x%x bytes\n",
rom_header, target, rom_size);
memcpy(target, rom_header, rom_size);
if (memcmp(target, rom_header, rom_size)) {
printf("VGA ROM copy failed\n");
return -EFAULT;
}
}
*ram_headerp = target;
return 0;
}
static struct vbe_mode_info mode_info;
int vbe_get_video_info(struct graphic_device *gdev)
{
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
struct vesa_mode_info *vesa = &mode_info.vesa;
gdev->winSizeX = vesa->x_resolution;
gdev->winSizeY = vesa->y_resolution;
gdev->plnSizeX = vesa->x_resolution;
gdev->plnSizeY = vesa->y_resolution;
gdev->gdfBytesPP = vesa->bits_per_pixel / 8;
switch (vesa->bits_per_pixel) {
case 24:
gdev->gdfIndex = GDF_32BIT_X888RGB;
break;
case 16:
gdev->gdfIndex = GDF_16BIT_565RGB;
break;
default:
gdev->gdfIndex = GDF__8BIT_INDEX;
break;
}
gdev->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
gdev->pciBase = vesa->phys_base_ptr;
gdev->frameAdrs = vesa->phys_base_ptr;
gdev->memSize = vesa->bytes_per_scanline * vesa->y_resolution;
gdev->vprBase = vesa->phys_base_ptr;
gdev->cprBase = vesa->phys_base_ptr;
return 0;
#else
return -ENOSYS;
#endif
}
int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
{
struct pci_rom_header *rom, *ram;
int vesa_mode = -1;
uint16_t class;
int ret;
/* Only execute VGA ROMs */
pci_read_config_word(dev, PCI_CLASS_DEVICE, &class);
if ((class ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) {
debug("%s: Class %#x, should be %#x\n", __func__, class,
PCI_CLASS_DISPLAY_VGA);
return -ENODEV;
}
if (!should_load_oprom(dev))
return -ENXIO;
ret = pci_rom_probe(dev, class, &rom);
if (ret)
return ret;
ret = pci_rom_load(class, rom, &ram);
if (ret)
return ret;
if (!board_should_run_oprom(dev))
return -ENXIO;
#if defined(CONFIG_FRAMEBUFFER_SET_VESA_MODE) && \
defined(CONFIG_FRAMEBUFFER_VESA_MODE)
vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE;
#endif
debug("Selected vesa mode %d\b", vesa_mode);
if (emulate) {
#ifdef CONFIG_BIOSEMU
BE_VGAInfo *info;
ret = biosemu_setup(dev, &info);
if (ret)
return ret;
biosemu_set_interrupt_handler(0x15, int15_handler);
ret = biosemu_run(dev, (uchar *)ram, 1 << 16, info, true,
vesa_mode, &mode_info);
if (ret)
return ret;
#else
printf("BIOS emulation not available - see CONFIG_BIOSEMU\n");
return -ENOSYS;
#endif
} else {
#ifdef CONFIG_X86
bios_set_interrupt_handler(0x15, int15_handler);
bios_run_on_x86(dev, (unsigned long)ram, vesa_mode,
&mode_info);
#else
printf("BIOS native execution is only available on x86\n");
return -ENOSYS;
#endif
}
debug("Final vesa mode %d\n", mode_info.video_mode);
return 0;
}

View file

@ -27,7 +27,7 @@
#define NUM_SECS_IN_DAY DAYS_TO_SECS(1)
/* Enable the RTC prescaler enable register */
static void rtc_init(void)
void rtc_init(void)
{
if (!(bfin_read_RTC_PREN() & 0x1))
bfin_write_RTC_PREN(0x1);

View file

@ -14,6 +14,7 @@
#include <common.h>
#include <command.h>
#include <rtc.h>
#include <version.h>
#if defined(__I386__) || defined(CONFIG_MALTA)
#include <asm/io.h>
@ -23,6 +24,9 @@
#if defined(CONFIG_CMD_DATE)
/* Set this to 1 to clear the CMOS RAM */
#define CLEAR_CMOS 0
static uchar rtc_read (uchar reg);
static void rtc_write (uchar reg, uchar val);
@ -41,7 +45,14 @@ static void rtc_write (uchar reg, uchar val);
#define RTC_CONFIG_B 0x0B
#define RTC_CONFIG_C 0x0C
#define RTC_CONFIG_D 0x0D
#define RTC_REG_SIZE 0x80
#define RTC_CONFIG_A_REF_CLCK_32KHZ (1 << 5)
#define RTC_CONFIG_A_RATE_1024HZ 6
#define RTC_CONFIG_B_24H (1 << 1)
#define RTC_CONFIG_D_VALID_RAM_AND_TIME 0x80
/* ------------------------------------------------------------------------- */
@ -128,25 +139,49 @@ void rtc_reset (void)
*/
static uchar rtc_read (uchar reg)
{
return(in8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg));
return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg);
}
static void rtc_write (uchar reg, uchar val)
{
out8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg, val);
out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val);
}
#else
static uchar rtc_read (uchar reg)
{
out8(RTC_PORT_MC146818,reg);
return(in8(RTC_PORT_MC146818+1));
return in8(RTC_PORT_MC146818 + 1);
}
static void rtc_write (uchar reg, uchar val)
{
out8(RTC_PORT_MC146818,reg);
out8(RTC_PORT_MC146818+1,val);
out8(RTC_PORT_MC146818+1, val);
}
#endif
void rtc_init(void)
{
#if CLEAR_CMOS
int i;
rtc_write(RTC_SECONDS_ALARM, 0);
rtc_write(RTC_MINUTES_ALARM, 0);
rtc_write(RTC_HOURS_ALARM, 0);
for (i = RTC_CONFIG_A; i < RTC_REG_SIZE; i++)
rtc_write(i, 0);
printf("RTC: zeroing CMOS RAM\n");
#endif
/* Setup the real time clock */
rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H);
/* Setup the frequency it operates at */
rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ |
RTC_CONFIG_A_RATE_1024HZ);
/* Ensure all reserved bits are 0 in register D */
rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME);
/* Clear any pending interrupts */
rtc_read(RTC_CONFIG_C);
}
#endif

View file

@ -42,6 +42,7 @@ obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o
obj-$(CONFIG_VIDEO_TEGRA) += tegra.o
obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
obj-$(CONFIG_VIDEO_X86) += x86_fb.o
obj-$(CONFIG_FORMIKE) += formike.o
obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
obj-$(CONFIG_VIDEO_PARADE) += parade.o

View file

@ -19,6 +19,7 @@
#include <common.h>
#include <command.h>
#include <bios_emul.h>
#include <pci.h>
#include <asm/processor.h>
#include <asm/errno.h>
@ -544,7 +545,6 @@ void radeon_setmode_9200(int vesa_idx, int bpp)
}
#include "../bios_emulator/include/biosemu.h"
extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
int radeon_probe(struct radeonfb_info *rinfo)
{

37
drivers/video/x86_fb.c Normal file
View file

@ -0,0 +1,37 @@
/*
*
* Vesa frame buffer driver for x86
*
* Copyright (C) 2014 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <video_fb.h>
#include <vbe.h>
#include "videomodes.h"
/*
* The Graphic Device
*/
GraphicDevice ctfb;
void *video_hw_init(void)
{
GraphicDevice *gdev = &ctfb;
int bits_per_pixel;
printf("Video: ");
if (vbe_get_video_info(gdev)) {
printf("No video mode configured\n");
return NULL;
}
bits_per_pixel = gdev->gdfBytesPP * 8;
sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
bits_per_pixel);
printf("%s\n", gdev->modeIdent);
return (void *)gdev;
}

66
include/bios_emul.h Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 1996-1999 SciTech Software, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _BIOS_EMUL_H
#define _BIOS_EMUL_H
/* Include the register header directly here */
#include "../drivers/bios_emulator/include/x86emu/regs.h"
#include <pci.h>
/****************************************************************************
REMARKS:
Data structure used to describe the details for the BIOS emulator system
environment as used by the X86 emulator library.
HEADER:
biosemu.h
MEMBERS:
vgaInfo - VGA BIOS information structure
biosmem_base - Base of the BIOS image
biosmem_limit - Limit of the BIOS image
busmem_base - Base of the VGA bus memory
****************************************************************************/
typedef struct {
int function;
int device;
int bus;
u32 VendorID;
u32 DeviceID;
pci_dev_t pcidev;
void *BIOSImage;
u32 BIOSImageLen;
u8 LowMem[1536];
} BE_VGAInfo;
struct vbe_mode_info;
int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int cleanUp);
/* Run a BIOS ROM natively (only supported on x86 machines) */
void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode,
struct vbe_mode_info *mode_info);
/**
* bios_set_interrupt_handler() - Install an interrupt handler for the BIOS
*
* This installs an interrupt handler that the BIOS will call when needed.
*
* @intnum: Interrupt number to install a handler for
* @int_handler_func: Function to call to handle interrupt
*/
void bios_set_interrupt_handler(int intnum, int (*int_handler_func)(void));
void biosemu_set_interrupt_handler(int intnum, int (*int_func)(void));
int biosemu_setup(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo);
int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
struct vbe_mode_info *mode_info);
#endif

View file

@ -73,6 +73,9 @@ typedef volatile unsigned char vu_char;
#ifdef CONFIG_ARM
#define asmlinkage /* nothing */
#endif
#ifdef CONFIG_X86
#define asmlinkage __attribute__((regparm(0)))
#endif
#ifdef CONFIG_BLACKFIN
#include <asm/blackfin.h>
#endif

View file

@ -21,7 +21,6 @@
#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000
#define CONFIG_SYS_X86_START16 0xfffff800
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_BOARD_EARLY_INIT_R
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_X86_RESET_VECTOR
@ -40,20 +39,9 @@
{PCI_VENDOR_ID_INTEL, \
PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}
/*
* These common x86 features are not yet supported, but are added in
* follow-on patches in this series. Add undefs here to avoid every patch
* having to put things back into x86-common.h
*/
#undef CONFIG_VIDEO
#undef CONFIG_CFB_CONSOLE
#undef CONFIG_ICH_SPI
#undef CONFIG_SPI
#undef CONFIG_CMD_SPI
#undef CONFIG_CMD_SF
#undef CONFIG_USB_EHCI
#undef CONFIG_CMD_USB
#undef CONFIG_CMD_SCSI
#define CONFIG_X86_OPTION_ROM_FILENAME 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
@ -67,6 +55,18 @@
#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
#define CONFIG_PCI_IO_SIZE 0xefff
#define CONFIG_SYS_EARLY_PCI_INIT
#define CONFIG_PCI_PNP
#define CONFIG_BIOSEMU
#define VIDEO_IO_OFFSET 0
#define CONFIG_X86EMU_RAW_IO
#define CONFIG_CROS_EC
#define CONFIG_CROS_EC_LPC
#define CONFIG_CMD_CROS_EC
#define CONFIG_ARCH_EARLY_INIT_R
#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
"stdout=vga,serial\0" \
"stderr=vga,serial\0"

View file

@ -120,6 +120,9 @@ enum fdt_compat_id {
COMPAT_INTEL_LPC, /* Intel Low Pin Count I/F */
COMPAT_INTEL_MICROCODE, /* Intel microcode update */
COMPAT_MEMORY_SPD, /* Memory SPD information */
COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */
COMPAT_INTEL_MODEL_206AX, /* Intel Model 206AX CPU */
COMPAT_INTEL_GMA, /* Intel Graphics Media Accelerator */
COMPAT_COUNT,
};

View file

@ -16,7 +16,9 @@
#define LLONG_MAX ((long long)(~0ULL>>1))
#define LLONG_MIN (-LLONG_MAX - 1)
#define ULLONG_MAX (~0ULL)
#ifndef SIZE_MAX
#define SIZE_MAX (~(size_t)0)
#endif
#define U8_MAX ((u8)~0U)
#define S8_MAX ((s8)(U8_MAX>>1))

View file

@ -678,5 +678,28 @@ extern void pci_mpc824x_init (struct pci_controller *hose);
extern void pci_mpc85xx_init (struct pci_controller *hose);
#endif
/**
* pci_write_bar32() - Write the address of a BAR including control bits
*
* This writes a raw address (with control bits) to a bar
*
* @hose: PCI hose to use
* @dev: PCI device to update
* @barnum: BAR number (0-5)
* @addr: BAR address with control bits
*/
void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
u32 addr_and_ctrl);
/**
* pci_read_bar32() - read the address of a bar
*
* @hose: PCI hose to use
* @dev: PCI device to inspect
* @barnum: BAR number (0-5)
* @return address of the bar, masking out any control bits
* */
u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum);
#endif /* __ASSEMBLY__ */
#endif /* _PCI_H */

View file

@ -526,7 +526,19 @@
#define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302
#define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303
#define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304
#define PCI_DEVICE_ID_AMD_15H_NB_MISC 0x1603
#define PCI_DEVICE_ID_AMD_15H_M10H_F3 0x1403
#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F3 0x141d
#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F4 0x141e
#define PCI_DEVICE_ID_AMD_15H_NB_F0 0x1600
#define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601
#define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602
#define PCI_DEVICE_ID_AMD_15H_NB_F3 0x1603
#define PCI_DEVICE_ID_AMD_15H_NB_F4 0x1604
#define PCI_DEVICE_ID_AMD_15H_NB_F5 0x1605
#define PCI_DEVICE_ID_AMD_16H_NB_F3 0x1533
#define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534
#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F3 0x1583
#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F4 0x1584
#define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
@ -569,8 +581,9 @@
#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
#define PCI_DEVICE_ID_AMD_LX_AES 0x2082
#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c
#define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE 0x7800
#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b
#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
@ -616,6 +629,8 @@
#define PCI_DEVICE_ID_MATROX_G550 0x2527
#define PCI_DEVICE_ID_MATROX_VIA 0x4536
#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS 0x14f2
#define PCI_VENDOR_ID_CT 0x102c
#define PCI_DEVICE_ID_CT_69000 0x00c0
#define PCI_DEVICE_ID_CT_65545 0x00d8
@ -724,6 +739,7 @@
#define PCI_DEVICE_ID_SI_7018 0x7018
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_VENDOR_ID_HP_3PAR 0x1590
#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005
#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006
#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008
@ -755,6 +771,8 @@
#define PCI_DEVICE_ID_HP_CISSD 0x3238
#define PCI_DEVICE_ID_HP_CISSE 0x323a
#define PCI_DEVICE_ID_HP_CISSF 0x323b
#define PCI_DEVICE_ID_HP_CISSH 0x323c
#define PCI_DEVICE_ID_HP_CISSI 0x3239
#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
#define PCI_VENDOR_ID_PCTECH 0x1042
@ -779,6 +797,29 @@
#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
#define PCI_VENDOR_ID_STMICRO 0x104A
#define PCI_DEVICE_ID_STMICRO_USB_HOST 0xCC00
#define PCI_DEVICE_ID_STMICRO_USB_OHCI 0xCC01
#define PCI_DEVICE_ID_STMICRO_USB_OTG 0xCC02
#define PCI_DEVICE_ID_STMICRO_UART_HWFC 0xCC03
#define PCI_DEVICE_ID_STMICRO_UART_NO_HWFC 0xCC04
#define PCI_DEVICE_ID_STMICRO_SOC_DMA 0xCC05
#define PCI_DEVICE_ID_STMICRO_SATA 0xCC06
#define PCI_DEVICE_ID_STMICRO_I2C 0xCC07
#define PCI_DEVICE_ID_STMICRO_SPI_HS 0xCC08
#define PCI_DEVICE_ID_STMICRO_MAC 0xCC09
#define PCI_DEVICE_ID_STMICRO_SDIO_EMMC 0xCC0A
#define PCI_DEVICE_ID_STMICRO_SDIO 0xCC0B
#define PCI_DEVICE_ID_STMICRO_GPIO 0xCC0C
#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_DMA 0xCC0E
#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_SRCS 0xCC0F
#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_MSPS 0xCC10
#define PCI_DEVICE_ID_STMICRO_CAN 0xCC11
#define PCI_DEVICE_ID_STMICRO_MLB 0xCC12
#define PCI_DEVICE_ID_STMICRO_DBP 0xCC13
#define PCI_DEVICE_ID_STMICRO_SATA_PHY 0xCC14
#define PCI_DEVICE_ID_STMICRO_ESRAM 0xCC15
#define PCI_DEVICE_ID_STMICRO_VIC 0xCC16
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
@ -1294,6 +1335,8 @@
#define PCI_VENDOR_ID_TUNDRA 0x10e3
#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
#define PCI_VENDOR_ID_AMCC 0x10e8
#define PCI_VENDOR_ID_INTERG 0x10ea
#define PCI_DEVICE_ID_INTERG_1682 0x1682
#define PCI_DEVICE_ID_INTERG_2000 0x2000
@ -1322,6 +1365,7 @@
#define PCI_SUBDEVICE_ID_CREATIVE_SB08801 0x0041
#define PCI_SUBDEVICE_ID_CREATIVE_SB08802 0x0042
#define PCI_SUBDEVICE_ID_CREATIVE_SB08803 0x0043
#define PCI_SUBDEVICE_ID_CREATIVE_SB1270 0x0062
#define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX 0x6000
#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */
@ -1411,6 +1455,7 @@
#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581
#define PCI_DEVICE_ID_VIA_VX800 0x8353
#define PCI_DEVICE_ID_VIA_VX855 0x8409
#define PCI_DEVICE_ID_VIA_VX900 0x8410
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
@ -1551,6 +1596,8 @@
#define PCI_DEVICE_ID_RICOH_RL5C476 0x0476
#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478
#define PCI_DEVICE_ID_RICOH_R5C822 0x0822
#define PCI_DEVICE_ID_RICOH_R5CE822 0xe822
#define PCI_DEVICE_ID_RICOH_R5CE823 0xe823
#define PCI_DEVICE_ID_RICOH_R5C832 0x0832
#define PCI_DEVICE_ID_RICOH_R5C843 0x0843
@ -1586,6 +1633,7 @@
#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334
#define PCI_VENDOR_ID_MARVELL 0x11ab
#define PCI_VENDOR_ID_MARVELL_EXT 0x1b4b
#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146
#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
@ -1798,6 +1846,8 @@
#define PCI_VENDOR_ID_ESDGMBH 0x12fe
#define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111
#define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */
#define PCI_VENDOR_ID_SIIG 0x131f
#define PCI_SUBVENDOR_ID_SIIG 0x131f
#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000
@ -1860,8 +1910,23 @@
#define PCI_VENDOR_ID_QUATECH 0x135C
#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010
#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020
#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030
#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040
#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050
#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060
#define PCI_DEVICE_ID_QUATECH_QSCP100 0x0120
#define PCI_DEVICE_ID_QUATECH_DSCP100 0x0130
#define PCI_DEVICE_ID_QUATECH_QSCP200 0x0140
#define PCI_DEVICE_ID_QUATECH_DSCP200 0x0150
#define PCI_DEVICE_ID_QUATECH_QSCLP100 0x0170
#define PCI_DEVICE_ID_QUATECH_DSCLP100 0x0180
#define PCI_DEVICE_ID_QUATECH_DSC100E 0x0181
#define PCI_DEVICE_ID_QUATECH_SSCLP100 0x0190
#define PCI_DEVICE_ID_QUATECH_QSCLP200 0x01A0
#define PCI_DEVICE_ID_QUATECH_DSCLP200 0x01B0
#define PCI_DEVICE_ID_QUATECH_DSC200E 0x01B1
#define PCI_DEVICE_ID_QUATECH_SSCLP200 0x01C0
#define PCI_DEVICE_ID_QUATECH_ESCLP100 0x01E0
#define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278
#define PCI_VENDOR_ID_SEALEVEL 0x135e
@ -1978,6 +2043,9 @@
#define PCI_DEVICE_ID_EXAR_XR17C152 0x0152
#define PCI_DEVICE_ID_EXAR_XR17C154 0x0154
#define PCI_DEVICE_ID_EXAR_XR17C158 0x0158
#define PCI_DEVICE_ID_EXAR_XR17V352 0x0352
#define PCI_DEVICE_ID_EXAR_XR17V354 0x0354
#define PCI_DEVICE_ID_EXAR_XR17V358 0x0358
#define PCI_VENDOR_ID_MICROGATE 0x13c0
#define PCI_DEVICE_ID_MICROGATE_USC 0x0010
@ -2002,6 +2070,10 @@
#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
#define PCI_VENDOR_ID_ADVANTECH 0x13fe
#define PCI_VENDOR_ID_MEILHAUS 0x1402
#define PCI_VENDOR_ID_LAVA 0x1407
#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */
#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */
@ -2047,6 +2119,8 @@
#define PCI_VENDOR_ID_CHELSIO 0x1425
#define PCI_VENDOR_ID_ADLINK 0x144a
#define PCI_VENDOR_ID_SAMSUNG 0x144d
#define PCI_VENDOR_ID_GIGABYTE 0x1458
@ -2080,6 +2154,8 @@
#define PCI_DEVICE_ID_AFAVLAB_P030 0x2182
#define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150
#define PCI_VENDOR_ID_AMPLICON 0x14dc
#define PCI_VENDOR_ID_BCM_GVC 0x14a4
#define PCI_VENDOR_ID_BROADCOM 0x14e4
#define PCI_DEVICE_ID_TIGON3_5752 0x1600
@ -2100,19 +2176,25 @@
#define PCI_DEVICE_ID_NX2_57711E 0x1650
#define PCI_DEVICE_ID_TIGON3_5705 0x1653
#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654
#define PCI_DEVICE_ID_TIGON3_5719 0x1657
#define PCI_DEVICE_ID_TIGON3_5721 0x1659
#define PCI_DEVICE_ID_TIGON3_5722 0x165a
#define PCI_DEVICE_ID_TIGON3_5723 0x165b
#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
#define PCI_DEVICE_ID_NX2_57712 0x1662
#define PCI_DEVICE_ID_NX2_57712E 0x1663
#define PCI_DEVICE_ID_NX2_57712_MF 0x1663
#define PCI_DEVICE_ID_TIGON3_5714 0x1668
#define PCI_DEVICE_ID_TIGON3_5714S 0x1669
#define PCI_DEVICE_ID_TIGON3_5780 0x166a
#define PCI_DEVICE_ID_TIGON3_5780S 0x166b
#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
#define PCI_DEVICE_ID_NX2_57712_VF 0x166f
#define PCI_DEVICE_ID_TIGON3_5754M 0x1672
#define PCI_DEVICE_ID_TIGON3_5755M 0x1673
#define PCI_DEVICE_ID_TIGON3_5756 0x1674
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
#define PCI_DEVICE_ID_TIGON3_5715 0x1678
#define PCI_DEVICE_ID_TIGON3_5715S 0x1679
@ -2124,6 +2206,9 @@
#define PCI_DEVICE_ID_TIGON3_5761E 0x1680
#define PCI_DEVICE_ID_TIGON3_5761 0x1681
#define PCI_DEVICE_ID_TIGON3_5764 0x1684
#define PCI_DEVICE_ID_NX2_57800 0x168a
#define PCI_DEVICE_ID_NX2_57840 0x168d
#define PCI_DEVICE_ID_NX2_57810 0x168e
#define PCI_DEVICE_ID_TIGON3_5787M 0x1693
#define PCI_DEVICE_ID_TIGON3_5782 0x1696
#define PCI_DEVICE_ID_TIGON3_5784 0x1698
@ -2131,11 +2216,19 @@
#define PCI_DEVICE_ID_TIGON3_5787 0x169b
#define PCI_DEVICE_ID_TIGON3_5788 0x169c
#define PCI_DEVICE_ID_TIGON3_5789 0x169d
#define PCI_DEVICE_ID_NX2_57840_4_10 0x16a1
#define PCI_DEVICE_ID_NX2_57840_2_20 0x16a2
#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4
#define PCI_DEVICE_ID_NX2_57800_MF 0x16a5
#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
#define PCI_DEVICE_ID_NX2_57800_VF 0x16a9
#define PCI_DEVICE_ID_NX2_5706S 0x16aa
#define PCI_DEVICE_ID_NX2_5708S 0x16ac
#define PCI_DEVICE_ID_NX2_57840_VF 0x16ad
#define PCI_DEVICE_ID_NX2_57810_MF 0x16ae
#define PCI_DEVICE_ID_NX2_57810_VF 0x16af
#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6
#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7
#define PCI_DEVICE_ID_TIGON3_5781 0x16dd
@ -2307,6 +2400,8 @@
#define PCI_VENDOR_ID_TOPSPIN 0x1867
#define PCI_VENDOR_ID_COMMTECH 0x18f7
#define PCI_VENDOR_ID_SILAN 0x1904
#define PCI_VENDOR_ID_RENESAS 0x1912
@ -2316,6 +2411,11 @@
#define PCI_DEVICE_ID_RENESAS_SH7785 0x0007
#define PCI_DEVICE_ID_RENESAS_SH7786 0x0010
#define PCI_VENDOR_ID_SOLARFLARE 0x1924
#define PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0 0x0703
#define PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1 0x6703
#define PCI_DEVICE_ID_SOLARFLARE_SFC4000B 0x0710
#define PCI_VENDOR_ID_TDI 0x192E
#define PCI_DEVICE_ID_TDI_EHCI 0x0101
@ -2414,6 +2514,11 @@
#define PCI_VENDOR_ID_AZWAVE 0x1a3b
#define PCI_VENDOR_ID_ASMEDIA 0x1b21
#define PCI_VENDOR_ID_CIRCUITCO 0x1cc8
#define PCI_SUBSYSTEM_ID_CIRCUITCO_MINNOWBOARD 0x0001
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
@ -2463,6 +2568,9 @@
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_EESSC 0x0008
#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154
#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00
#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320
#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321
#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
@ -2485,6 +2593,7 @@
#define PCI_DEVICE_ID_INTEL_MRST_SD2 0x084F
#define PCI_DEVICE_ID_INTEL_I960 0x0960
#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
#define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c60
#define PCI_DEVICE_ID_INTEL_82541ER 0x1078
#define PCI_DEVICE_ID_INTEL_82541GI_LF 0x107c
#define PCI_DEVICE_ID_INTEL_82542 0x1000
@ -2564,13 +2673,50 @@
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA 0x1c20
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_Z68 0x1c44
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_P67 0x1c46
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_UM67 0x1c47
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_HM65 0x1c49
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_H67 0x1c4a
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_HM67 0x1c4b
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_Q65 0x1c4c
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_QS67 0x1c4d
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_Q67 0x1c4e
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_QM67 0x1c4f
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_B65 0x1c50
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_C202 0x1c52
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_C204 0x1c54
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_C206 0x1c56
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_H61 0x1c5c
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE 0x1e03
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA 0x1e20
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e41
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40
#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40
#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE 0x1e03
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA 0x1e20
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI 0x1e31
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e41
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_B75 0x1e49
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_C216 0x1e53
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_H77 0x1e4A
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM70 0x1e5e
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM75 0x1e5d
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM76 0x1e59
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM77 0x1e57
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MBL_SAMPLE 0x1e42
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_NM70 0x1e5f
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Q75 0x1e48
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Q77 0x1e47
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_QM77 0x1e55
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_QS77 0x1e56
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_SFF_SAMPLE 0x1e43
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_UM77 0x1e58
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Z75 0x1e46
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Z77 0x1e44
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f
#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310
#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
@ -2783,8 +2929,30 @@
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
#define PCI_DEVICE_ID_INTEL_IOAT_SNB0 0x3c20
#define PCI_DEVICE_ID_INTEL_IOAT_SNB1 0x3c21
#define PCI_DEVICE_ID_INTEL_IOAT_SNB2 0x3c22
#define PCI_DEVICE_ID_INTEL_IOAT_SNB3 0x3c23
#define PCI_DEVICE_ID_INTEL_IOAT_SNB4 0x3c24
#define PCI_DEVICE_ID_INTEL_IOAT_SNB5 0x3c25
#define PCI_DEVICE_ID_INTEL_IOAT_SNB6 0x3c26
#define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27
#define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e
#define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f
#define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46
#define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0
#define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1
#define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4
#define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5
#define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c41
#define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c42
#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c43
#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c44
#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45
#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0
#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0
#define PCI_DEVICE_ID_INTEL_5100_19 0x65f3
#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5
#define PCI_DEVICE_ID_INTEL_5100_22 0x65f6
#define PCI_DEVICE_ID_INTEL_5400_ERR 0x4030
@ -2823,6 +2991,7 @@
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119
#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a
#define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186
#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
@ -2905,7 +3074,11 @@
#define PCI_DEVICE_ID_NETMOS_9845 0x9845
#define PCI_DEVICE_ID_NETMOS_9855 0x9855
#define PCI_DEVICE_ID_NETMOS_9865 0x9865
#define PCI_DEVICE_ID_NETMOS_9900 0x9900
#define PCI_DEVICE_ID_NETMOS_9901 0x9901
#define PCI_DEVICE_ID_NETMOS_9904 0x9904
#define PCI_DEVICE_ID_NETMOS_9912 0x9912
#define PCI_DEVICE_ID_NETMOS_9922 0x9922
#define PCI_VENDOR_ID_3COM_2 0xa727
@ -2927,3 +3100,5 @@
#define PCI_VENDOR_ID_XEN 0x5853
#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
#define PCI_VENDOR_ID_OCZ 0x1b85

58
include/pci_rom.h Normal file
View file

@ -0,0 +1,58 @@
/*
* From coreboot file of same name
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _PCI_ROM_H
#define _PCI_ROM_H
#define PCI_ROM_HDR 0xaa55
#define PCI_VGA_RAM_IMAGE_START 0xc0000
struct pci_rom_header {
uint16_t signature;
uint8_t size;
uint8_t init[3];
uint8_t reserved[0x12];
uint16_t data;
};
struct pci_rom_data {
uint32_t signature;
uint16_t vendor;
uint16_t device;
uint16_t reserved_1;
uint16_t dlen;
uint8_t drevision;
uint8_t class_lo;
uint16_t class_hi;
uint16_t ilen;
uint16_t irevision;
uint8_t type;
uint8_t indicator;
uint16_t reserved_2;
};
/**
* pci_run_vga_bios() - Run the VGA BIOS in an x86 PC
*
* @dev: Video device containing the BIOS
* @int15_handler: Function to call to handle int 0x15
* @emulate: true to use the x86 emulator, false to run native
*/
int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate);
/**
* board_map_oprom_vendev() - map several PCI IDs to the one the ROM expects
*
* Some VGA option roms are used for several chipsets but they only have one
* PCI ID in their header. If we encounter such an option rom, we need to do
* the mapping ourselves.
*
* @vendev: Vendor and device for the video device
* @return standard vendor and device expected by the ROM
*/
uint32_t board_map_oprom_vendev(uint32_t vendev);
#endif

View file

@ -50,4 +50,9 @@ void to_tm (int, struct rtc_time *);
unsigned long mktime (unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int);
/**
* rtc_init() - Set up the real time clock ready for use
*/
void rtc_init(void);
#endif /* _RTC_H_ */

103
include/vbe.h Normal file
View file

@ -0,0 +1,103 @@
/******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation
* Copyright (c) 2009 Pattrick Hueper <phueper@hueper.net>
* All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Contributors:
* IBM Corporation - initial implementation
*****************************************************************************/
#ifndef _VBE_H
#define _VBE_H
/* these structs are for input from and output to OF */
struct __packed screen_info {
u8 display_type; /* 0=NONE, 1= analog, 2=digital */
u16 screen_width;
u16 screen_height;
/* bytes per line in framebuffer, may be more than screen_width */
u16 screen_linebytes;
u8 color_depth; /* color depth in bits per pixel */
u32 framebuffer_address;
u8 edid_block_zero[128];
};
struct __packed screen_info_input {
u8 signature[4];
u16 size_reserved;
u8 monitor_number;
u16 max_screen_width;
u8 color_depth;
};
/* these structs only store the required a subset of the VBE-defined fields */
struct __packed vbe_info {
char signature[4];
u16 version;
u8 *oem_string_ptr;
u32 capabilities;
u16 video_mode_list[256];
u16 total_memory;
};
struct __packed vesa_mode_info {
u16 mode_attributes; /* 00 */
u8 win_a_attributes; /* 02 */
u8 win_b_attributes; /* 03 */
u16 win_granularity; /* 04 */
u16 win_size; /* 06 */
u16 win_a_segment; /* 08 */
u16 win_b_segment; /* 0a */
u32 win_func_ptr; /* 0c */
u16 bytes_per_scanline; /* 10 */
u16 x_resolution; /* 12 */
u16 y_resolution; /* 14 */
u8 x_charsize; /* 16 */
u8 y_charsize; /* 17 */
u8 number_of_planes; /* 18 */
u8 bits_per_pixel; /* 19 */
u8 number_of_banks; /* 20 */
u8 memory_model; /* 21 */
u8 bank_size; /* 22 */
u8 number_of_image_pages; /* 23 */
u8 reserved_page;
u8 red_mask_size;
u8 red_mask_pos;
u8 green_mask_size;
u8 green_mask_pos;
u8 blue_mask_size;
u8 blue_mask_pos;
u8 reserved_mask_size;
u8 reserved_mask_pos;
u8 direct_color_mode_info;
u32 phys_base_ptr;
u32 offscreen_mem_offset;
u16 offscreen_mem_size;
u8 reserved[206];
};
struct vbe_mode_info {
u16 video_mode;
bool valid;
union {
struct vesa_mode_info vesa;
u8 mode_info_block[256];
};
};
struct vbe_ddc_info {
u8 port_number; /* i.e. monitor number */
u8 edid_transfer_time;
u8 ddc_level;
u8 edid_block_zero[128];
};
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
struct graphic_device;
int vbe_get_video_info(struct graphic_device *gdev);
#endif

View file

@ -40,7 +40,7 @@
/* Export Graphic Driver Control */
/******************************************************************************/
typedef struct {
typedef struct graphic_device {
unsigned int isaBase;
unsigned int pciBase;
unsigned int dprBase;

View file

@ -75,6 +75,9 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
COMPAT(INTEL_MICROCODE, "intel,microcode"),
COMPAT(MEMORY_SPD, "memory-spd"),
COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"),
COMPAT(INTEL_GMA, "intel,gma"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)

View file

@ -260,11 +260,13 @@ quiet_cmd_dt_S_dtb= DTB $@
cmd_dt_S_dtb= \
( \
echo '.section .dtb.init.rodata,"a"'; \
echo '.balign 16'; \
echo '.global __dtb_$(*F)_begin'; \
echo '__dtb_$(*F)_begin:'; \
echo '.incbin "$<" '; \
echo '__dtb_$(*F)_end:'; \
echo '.global __dtb_$(*F)_end'; \
echo '.balign 16'; \
) > $@
$(obj)/%.dtb.S: $(obj)/%.dtb

1
tools/.gitignore vendored
View file

@ -4,6 +4,7 @@
/fit_check_sign
/fit_info
/gen_eth_addr
/ifdtool
/img2srec
/kwboot
/dumpimage