Merge git://git.denx.de/u-boot-x86
This commit is contained in:
commit
f4e7e2d121
3
Makefile
3
Makefile
@ -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
|
||||
|
149
arch/x86/Kconfig
149
arch/x86/Kconfig
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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)"
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
146
arch/x86/cpu/ivybridge/bd82x6x.c
Normal file
146
arch/x86/cpu/ivybridge/bd82x6x.c
Normal 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;
|
||||
}
|
756
arch/x86/cpu/ivybridge/gma.c
Normal file
756
arch/x86/cpu/ivybridge/gma.c
Normal 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;
|
||||
}
|
156
arch/x86/cpu/ivybridge/gma.h
Normal file
156
arch/x86/cpu/ivybridge/gma.h
Normal 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
|
@ -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);
|
||||
}
|
||||
|
514
arch/x86/cpu/ivybridge/model_206ax.c
Normal file
514
arch/x86/cpu/ivybridge/model_206ax.c
Normal 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;
|
||||
}
|
188
arch/x86/cpu/ivybridge/northbridge.c
Normal file
188
arch/x86/cpu/ivybridge/northbridge.c
Normal 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
|
||||
}
|
123
arch/x86/cpu/ivybridge/pch.c
Normal file
123
arch/x86/cpu/ivybridge/pch.c
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
225
arch/x86/cpu/ivybridge/sata.c
Normal file
225
arch/x86/cpu/ivybridge/sata.c
Normal 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);
|
||||
}
|
29
arch/x86/cpu/ivybridge/usb_ehci.c
Normal file
29
arch/x86/cpu/ivybridge/usb_ehci.c
Normal 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");
|
||||
}
|
32
arch/x86/cpu/ivybridge/usb_xhci.c
Normal file
32
arch/x86/cpu/ivybridge/usb_xhci.c
Normal 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
57
arch/x86/cpu/lapic.c
Normal 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);
|
||||
}
|
@ -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
98
arch/x86/cpu/turbo.c
Normal 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");
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -163,21 +163,51 @@
|
||||
};
|
||||
};
|
||||
|
||||
lpc {
|
||||
compatible = "intel,lpc";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
cros-ec@200 {
|
||||
compatible = "google,cros-ec";
|
||||
reg = <0x204 1 0x200 1 0x880 0x80>;
|
||||
pci {
|
||||
sata {
|
||||
compatible = "intel,pantherpoint-ahci";
|
||||
intel,sata-mode = "ahci";
|
||||
intel,sata-port-map = <1>;
|
||||
intel,sata-port0-gen3-tx = <0x00880a7f>;
|
||||
};
|
||||
|
||||
/* This describes the flash memory within the EC */
|
||||
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>;
|
||||
flash@8000000 {
|
||||
reg = <0x08000000 0x20000>;
|
||||
erase-value = <0xff>;
|
||||
gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
intel,gen-dec = <0x800 0xfc 0x900 0xfc>;
|
||||
intel,pirq-routing = <0x8b 0x8a 0x8b 0x8b
|
||||
0x80 0x80 0x80 0x80>;
|
||||
intel,gpi-routing = <0 0 0 0 0 0 0 2
|
||||
1 0 0 0 0 0 0 0>;
|
||||
/* Enable EC SMI source */
|
||||
intel,alt-gp-smi-enable = <0x0100>;
|
||||
|
||||
cros-ec@200 {
|
||||
compatible = "google,cros-ec";
|
||||
reg = <0x204 1 0x200 1 0x880 0x80>;
|
||||
|
||||
/* Describes the flash memory within the EC */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
flash@8000000 {
|
||||
reg = <0x08000000 0x20000>;
|
||||
erase-value = <0xff>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
24
arch/x86/include/asm/acpi.h
Normal file
24
arch/x86/include/asm/acpi.h
Normal 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
|
23
arch/x86/include/asm/arch-ivybridge/bd82x6x.h
Normal file
23
arch/x86/include/asm/arch-ivybridge/bd82x6x.h
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -69,4 +69,6 @@
|
||||
#define ICW4_AEOI 0x02 /* Automatic EOI Mode */
|
||||
#define ICW4_PM 0x01 /* Microprocessor Mode */
|
||||
|
||||
int i8259_init(void);
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
38
arch/x86/include/asm/ioapic.h
Normal file
38
arch/x86/include/asm/ioapic.h
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -8,25 +8,18 @@
|
||||
#ifndef __ASM_PROCESSOR_H_
|
||||
#define __ASM_PROCESSOR_H_ 1
|
||||
|
||||
#define X86_GDT_ENTRY_SIZE 8
|
||||
#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_32BIT_DS 3
|
||||
#define X86_GDT_NUM_ENTRIES 7
|
||||
#endif
|
||||
#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_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)
|
||||
|
||||
|
89
arch/x86/include/asm/speedstep.h
Normal file
89
arch/x86/include/asm/speedstep.h
Normal 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
|
31
arch/x86/include/asm/turbo.h
Normal file
31
arch/x86/include/asm/turbo.h
Normal 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
|
@ -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);
|
||||
|
@ -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
347
arch/x86/lib/bios.c
Normal 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 = ®_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
98
arch/x86/lib/bios.h
Normal 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
281
arch/x86/lib/bios_asm.S
Normal 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
|
217
arch/x86/lib/bios_interrupts.c
Normal file
217
arch/x86/lib/bios_interrupts.c
Normal 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;
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
26
doc/device-tree-bindings/ata/intel-sata.txt
Normal file
26
doc/device-tree-bindings/ata/intel-sata.txt
Normal 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>;
|
||||
};
|
@ -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>;
|
||||
};
|
||||
|
40
doc/device-tree-bindings/video/intel-gma.txt
Normal file
40
doc/device-tree-bindings/video/intel-gma.txt
Normal 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>;
|
||||
};
|
@ -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__)
|
||||
|
@ -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, ®s, &sregs);
|
||||
|
||||
/*Cleanup and exit*/
|
||||
BE_getVGA(VGAInfo);
|
||||
BE_getVGA(vga_info);
|
||||
|
||||
if (vesa_mode != -1)
|
||||
atibios_set_vesa_mode(®s, 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) {
|
||||
printf("videoboot: Video ROM failed to map!\n");
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
bios_image_len = mapped_bios[2] * 512;
|
||||
|
||||
copy_of_bios = malloc(bios_image_len);
|
||||
if (copy_of_bios == NULL) {
|
||||
printf("videoboot: Out of memory!\n");
|
||||
return false;
|
||||
}
|
||||
memcpy(copy_of_bios, mapped_bios, bios_image_len);
|
||||
PCI_unmapBIOSImage(pcidev, mapped_bios);
|
||||
}
|
||||
|
||||
BIOSImageLen = mappedBIOS[2] * 512;
|
||||
|
||||
if ((copyOfBIOS = malloc(BIOSImageLen)) == NULL) {
|
||||
printf("videoboot: Out of memory!\n");
|
||||
return false;
|
||||
}
|
||||
memcpy(copyOfBIOS, mappedBIOS, BIOSImageLen);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 (IS_VGA_PORT(port)) {
|
||||
VGA_outpb(port, val);
|
||||
VGA_outpb(port + 1, val >> 8);
|
||||
} 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,
|
||||
val);)
|
||||
LOG_outpw(port, val);
|
||||
} else
|
||||
#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)) {
|
||||
PCI_outp(port, val, REG_WRITE_WORD);
|
||||
} else if (port < 0x100) {
|
||||
DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16)port,
|
||||
val);)
|
||||
LOG_outpw(port, val);
|
||||
} else
|
||||
#endif
|
||||
LOG_outpw(port, val);
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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++)
|
||||
@ -229,7 +227,7 @@ void X86EMU_dump_memory(u16 seg, u16 off, u32 amt)
|
||||
void x86emu_single_step(void)
|
||||
{
|
||||
char s[1024];
|
||||
int ps[10];
|
||||
int ps[10];
|
||||
int ntok;
|
||||
int cmd;
|
||||
int done;
|
||||
@ -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':
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
278
drivers/pci/pci_rom.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
37
drivers/video/x86_fb.c
Normal 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
66
include/bios_emul.h
Normal 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
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
@ -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
58
include/pci_rom.h
Normal 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
|
@ -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
103
include/vbe.h
Normal 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
|
@ -40,7 +40,7 @@
|
||||
/* Export Graphic Driver Control */
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
typedef struct graphic_device {
|
||||
unsigned int isaBase;
|
||||
unsigned int pciBase;
|
||||
unsigned int dprBase;
|
||||
|
@ -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)
|
||||
|
@ -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
1
tools/.gitignore
vendored
@ -4,6 +4,7 @@
|
||||
/fit_check_sign
|
||||
/fit_info
|
||||
/gen_eth_addr
|
||||
/ifdtool
|
||||
/img2srec
|
||||
/kwboot
|
||||
/dumpimage
|
||||
|
Loading…
Reference in New Issue
Block a user