soc/intel: Add Broadwell-DE SoC support

Initial files to support Broadwell-DE SoC. This is FSP 1.0 based
project and is based on Broadwell-DE Gold release. Change has been
verified on Intel Camelback Mountain CRB.

Change-Id: I20ce8ee8dd1113a7a20a96910292697421f1ca57
Signed-off-by: York Yang <york.yang@intel.com>
Reviewed-on: https://review.coreboot.org/14014
Tested-by: build bot (Jenkins)
Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
York Yang 2016-03-09 10:54:26 -08:00 committed by Martin Roth
parent cd9aec6fb0
commit d7cba288e4
37 changed files with 4563 additions and 0 deletions

View File

@ -0,0 +1,85 @@
config SOC_INTEL_FSP_BROADWELL_DE
bool
help
Broadwell-DE support using the Intel FSP.
if SOC_INTEL_FSP_BROADWELL_DE
config CPU_SPECIFIC_OPTIONS
def_bool y
select ARCH_BOOTBLOCK_X86_32
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select HAVE_HARD_RESET
select MMCONF_SUPPORT
select MMCONF_SUPPORT_DEFAULT
select RELOCATABLE_MODULES
select PARALLEL_MP
select SMP
select IOAPIC
select SPI_FLASH
select UDELAY_TSC
select SUPPORT_CPU_UCODE_IN_CBFS
# Microcode header files are delivered in FSP package
select USES_MICROCODE_HEADER_FILES if HAVE_FSP_BIN
config CBFS_SIZE
hex
default 0x200000
config RAMTOP
hex
default 0x400000
config HEAP_SIZE
hex
default 0x100000
config BOOTBLOCK_CPU_INIT
string
default "soc/intel/fsp_broadwell_de/bootblock/bootblock.c"
config MMCONF_BASE_ADDRESS
hex
default 0x80000000
config MAX_CPUS
int
default 16
config CPU_ADDR_BITS
int
default 36
config VGA_BIOS
bool
default n
config INTEGRATED_UART
bool "Integrated UART ports"
default y
select HAVE_UART_SPECIAL
select CONSOLE_SERIAL
help
Use Broadwell-DE Integrated UART ports @3F8h and 2F8h.
config DRIVERS_UART_8250IO
bool "Serial port on SuperIO (Broadwell-DE's UART ports unselected)"
depends on !INTEGRATED_UART
help
Select to choose SuperIO's serial port for console output.
CANNOT select if intend to use SoC integrated serial ports.
config CONSOLE_CBMEM
bool "Send console output to a CBMEM buffer"
default n
config CPU_MICROCODE_HEADER_FILES
string
default "../intel/cpu/broadwell_de/microcode/M1050663_07000001.h ../intel/cpu/broadwell_de/microcode/M1050662_0000000A.h ../intel/cpu/broadwell_de/microcode/MFF50661_F1000008.h"
## Broadwell-DE Specific FSP Kconfig
source src/soc/intel/fsp_broadwell_de/fsp/Kconfig
endif # SOC_INTEL_FSP_BROADWELL_DE

View File

@ -0,0 +1,35 @@
ifeq ($(CONFIG_SOC_INTEL_FSP_BROADWELL_DE),y)
subdirs-y += romstage
subdirs-y += ../../../cpu/intel/microcode
subdirs-y += ../../../cpu/intel/turbo
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
subdirs-y += ../../../cpu/x86/tsc
subdirs-y += ../../../cpu/x86/cache
subdirs-y += ../../../lib/fsp
subdirs-y += fsp
ramstage-y += spi.c
ramstage-y += cpu.c
ramstage-y += chip.c
ramstage-y += northcluster.c
ramstage-y += ramstage.c
romstage-y += memmap.c
ramstage-y += memmap.c
ramstage-y += southcluster.c
romstage-y += reset.c
ramstage-y += reset.c
ramstage-y += acpi.c
ifeq ($(CONFIG_INTEGRATED_UART),y)
romstage-y += uart.c
ramstage-y += uart.c
smm-$(CONFIG_DEBUG_SMI) += uart.c
endif
CPPFLAGS_common += -I$(src)/soc/intel/fsp_broadwell_de/include
CPPFLAGS_common += -I$(src)/soc/intel/fsp_broadwell_de/fsp
CPPFLAGS_common += -I$(src)/soc/intel/fsp_broadwell_de/
endif # ifeq ($(CONFIG_SOC_INTEL_FSP_BROADWELL_DE),y)

View File

@ -0,0 +1,454 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <string.h>
#include <types.h>
#include <arch/acpigen.h>
#include <arch/cpu.h>
#include <arch/io.h>
#include <arch/smp/mpspec.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
#include <cpu/intel/speedstep.h>
#include <cpu/intel/turbo.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <soc/acpi.h>
#include <soc/iomap.h>
#include <soc/irq.h>
#include <soc/lpc.h>
#include <soc/msr.h>
#include <soc/pattrs.h>
#include <soc/pci_devs.h>
#include <chip.h>
uint16_t get_pmbase(void)
{
return ACPI_BASE_ADDRESS;
}
#define MWAIT_RES(state, sub_state) \
{ \
.addrl = (((state) << 4) | (sub_state)), \
.space_id = ACPI_ADDRESS_SPACE_FIXED, \
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
.access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
}
/* C-state map */
static acpi_cstate_t cstate_map[] = {
{
/* C1 */
.ctype = 1, /* ACPI C1 */
.latency = 1,
.power = 1000,
.resource = MWAIT_RES(0, 0),
},
{
/* C3 */
.ctype = 2, /* ACPI C2 */
.latency = 15,
.power = 500,
.resource = MWAIT_RES(1, 0),
},
{
/* C6 */
.ctype = 3, /* ACPI C3 */
.latency = 41,
.power = 350,
.resource = MWAIT_RES(2, 0),
}
};
static int acpi_sci_irq(void)
{
return 9;
}
void acpi_create_intel_hpet(acpi_hpet_t *hpet)
{
acpi_header_t *header = &(hpet->header);
acpi_addr_t *addr = &(hpet->addr);
memset((void *) hpet, 0, sizeof(acpi_hpet_t));
/* fill out header fields */
memcpy(header->signature, "HPET", 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->length = sizeof(acpi_hpet_t);
header->revision = 1;
/* fill out HPET address */
addr->space_id = 0; /* Memory */
addr->bit_width = 64;
addr->bit_offset = 0;
addr->addrl = (unsigned long long)HPET_BASE_ADDRESS & 0xffffffff;
addr->addrh = (unsigned long long)HPET_BASE_ADDRESS >> 32;
hpet->id = 0x8086a201; /* Intel */
hpet->number = 0x00;
hpet->min_tick = 0x0080;
header->checksum = acpi_checksum((void *) hpet, sizeof(acpi_hpet_t));
}
unsigned long acpi_fill_mcfg(unsigned long current)
{
current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
MCFG_BASE_ADDRESS, 0, 0, 255);
return current;
}
/**
* Fill in the fadt with generic values that can be overridden later.
*/
void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
{
acpi_header_t *header = &(fadt->header);
u16 pmbase = get_pmbase();
memset((void *) fadt, 0, sizeof(acpi_fadt_t));
/*
* Reference section 5.2.9 Fixed ACPI Description Table (FADT)
* in the ACPI 3.0b specification.
*/
/* FADT Header Structure */
memcpy(header->signature, "FACP", 4);
header->length = sizeof(acpi_fadt_t);
header->revision = ACPI_FADT_REV_ACPI_3_0;
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->asl_compiler_revision = 1;
/* ACPI Pointers */
fadt->firmware_ctrl = (unsigned long) facs;
fadt->dsdt = (unsigned long) dsdt;
fadt->model = 0; /* reserved, should be 0 ACPI 3.0 */
fadt->preferred_pm_profile = 0;
fadt->sci_int = acpi_sci_irq();
/* System Management */
fadt->smi_cmd = 0x00; /* disable SMM */
fadt->acpi_enable = 0x00; /* unused if SMI_CMD = 0 */
fadt->acpi_disable = 0x00; /* unused if SMI_CMD = 0 */
/* Enable ACPI */
outl(inl(pmbase + 4) | 0x01, pmbase + 4);
/* Power Control */
fadt->s4bios_req = 0x00;
fadt->pstate_cnt = 0x00;
/* Control Registers - Base Address */
fadt->pm1a_evt_blk = pmbase + PM1_STS;
fadt->pm1b_evt_blk = 0x00; /* Not Used */
fadt->pm1a_cnt_blk = pmbase + PM1_CNT;
fadt->pm1b_cnt_blk = 0x00; /* Not Used */
fadt->pm2_cnt_blk = pmbase + PM2A_CNT_BLK;
fadt->pm_tmr_blk = pmbase + PM1_TMR;
fadt->gpe0_blk = pmbase + GPE0_STS;
fadt->gpe1_blk = 0x00; /* Not Used */
/* Control Registers - Length */
fadt->pm1_evt_len = 4; /* 32 bits */
fadt->pm1_cnt_len = 2; /* 32 bit register, 16 bits used */
fadt->pm2_cnt_len = 1; /* 8 bits */
fadt->pm_tmr_len = 4; /* 32 bits */
fadt->gpe0_blk_len = 8; /* 64 bits */
fadt->gpe1_blk_len = 0;
fadt->gpe1_base = 0;
fadt->cst_cnt = 0;
fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
fadt->flush_size = 0; /* set to 0 if WBINVD is 1 in flags */
fadt->flush_stride = 0; /* set to 0 if WBINVD is 1 in flags */
fadt->duty_offset = 1;
fadt->duty_width = 0;
/* RTC Registers */
fadt->day_alrm = 0x0D;
fadt->mon_alrm = 0x00;
fadt->century = 0x00;
fadt->iapc_boot_arch = 0;
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
ACPI_FADT_RESET_REGISTER | ACPI_FADT_SLEEP_TYPE |
ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
/* Reset Register */
fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->reset_reg.bit_width = 8;
fadt->reset_reg.bit_offset = 0;
fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
fadt->reset_reg.addrl = 0xCF9;
fadt->reset_reg.addrh = 0x00;
fadt->reset_value = 6;
/* Reserved Bits */
fadt->res3 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */
fadt->res4 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */
fadt->res5 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */
/* Extended ACPI Pointers */
fadt->x_firmware_ctl_l = (unsigned long)facs;
fadt->x_firmware_ctl_h = 0x00;
fadt->x_dsdt_l = (unsigned long)dsdt;
fadt->x_dsdt_h = 0x00;
/* PM1 Status & PM1 Enable */
fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
fadt->x_pm1a_evt_blk.bit_offset = 0;
fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
fadt->x_pm1a_evt_blk.addrh = 0x00;
fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm1b_evt_blk.bit_width = 0;
fadt->x_pm1b_evt_blk.bit_offset = 0;
fadt->x_pm1b_evt_blk.access_size = 0;
fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
fadt->x_pm1b_evt_blk.addrh = 0x00;
/* PM1 Control Registers */
fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm1a_cnt_blk.bit_width = 16;
fadt->x_pm1a_cnt_blk.bit_offset = 0;
fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
fadt->x_pm1a_cnt_blk.addrh = 0x00;
fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm1b_cnt_blk.bit_width = 0;
fadt->x_pm1b_cnt_blk.bit_offset = 0;
fadt->x_pm1b_cnt_blk.access_size = 0;
fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
fadt->x_pm1b_cnt_blk.addrh = 0x00;
/* PM2 Control Registers */
fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm2_cnt_blk.bit_width = 8;
fadt->x_pm2_cnt_blk.bit_offset = 0;
fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
fadt->x_pm2_cnt_blk.addrh = 0x00;
/* PM1 Timer Register */
fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm_tmr_blk.bit_width = 32;
fadt->x_pm_tmr_blk.bit_offset = 0;
fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
fadt->x_pm_tmr_blk.addrh = 0x00;
/* General-Purpose Event Registers */
fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + EventEnable */
fadt->x_gpe0_blk.bit_offset = 0;
fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
fadt->x_gpe0_blk.addrh = 0x00;
fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_gpe1_blk.bit_width = 0;
fadt->x_gpe1_blk.bit_offset = 0;
fadt->x_gpe1_blk.access_size = 0;
fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
fadt->x_gpe1_blk.addrh = 0x00;
header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
}
static int calculate_power(int tdp, int p1_ratio, int ratio)
{
u32 m;
u32 power;
/*
* M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
*
* Power = (ratio / p1_ratio) * m * tdp
*/
m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
m = (m * m) / 1000;
power = ((ratio * 100000 / p1_ratio) / 100);
power *= (m / 100) * (tdp / 1000);
power /= 1000;
return (int)power;
}
static void generate_P_state_entries(int core, int cores_per_package)
{
int ratio_min, ratio_max, ratio_step;
int coord_type, power_max, power_unit, num_entries;
int ratio, power, clock, clock_max;
int turbo;
u32 control_status;
msr_t msr;
/* Hardware coordination of P-states */
coord_type = HW_ALL;
/* Check for Turbo Mode */
turbo = get_turbo_state() == TURBO_ENABLED;
/* CPU attributes */
msr = rdmsr(MSR_PLATFORM_INFO);
ratio_min = (msr.hi >> 8) & 0xff; // LFM
ratio_max = (msr.lo >> 8) & 0xff; // HFM
clock_max = (ratio_max * 100);
/* Calculate CPU TDP in mW */
msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
power_unit = 1 << (msr.lo & 0xf);
msr = rdmsr(MSR_PKG_POWER_LIMIT);
power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
/* Write _PCT indicating use of FFixedHW */
acpigen_write_empty_PCT();
/* Write _PPC starting from first supported P-state */
acpigen_write_PPC(0);
/* Write PSD indicating configured coordination type */
acpigen_write_PSD_package(core, 1, coord_type);
/* Add P-state entries in _PSS table */
acpigen_write_name("_PSS");
/* Determine ratio points */
/* Note: There should be at most 16 performance states. If Turbo Mode
is enabled, the Max Turbo Ratio will occupy one of these states. */
ratio_step = 1;
num_entries = (ratio_max - ratio_min) / ratio_step;
while (num_entries > (15-turbo)) {
ratio_step <<= 1;
num_entries >>= 1;
}
if (turbo) {
/* _PSS package count (with turbo) */
acpigen_write_package(num_entries + 2);
/* Get Max Turbo Ratio */
msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
ratio = msr.lo & 0xff;
acpigen_write_PSS_package(
ratio * 100, /* MHz */
power_max, /* mW */
10, /* lat1 */
10, /* lat2 */
ratio << 8, /* control */
ratio << 8); /* status */
} else {
/* _PSS package count (without turbo) */
acpigen_write_package(num_entries + 1);
}
/* Generate the _PSS entries */
for (ratio = ratio_min + (num_entries * ratio_step);
ratio >= ratio_min; ratio -= ratio_step) {
/* Calculate power at this ratio */
power = calculate_power(power_max, ratio_max, ratio);
clock = ratio * 100;
control_status = ratio << 8;
acpigen_write_PSS_package(
clock, /* MHz */
power, /* mW */
10, /* lat1 */
10, /* lat2 */
control_status, /* control */
control_status); /* status */
}
/* Fix package length */
acpigen_pop_len();
}
void generate_cpu_entries(device_t device)
{
int core;
int pcontrol_blk = get_pmbase(), plen = 6;
const struct pattrs *pattrs = pattrs_get();
for (core = 0; core < pattrs->num_cpus; core++) {
if (core > 0) {
pcontrol_blk = 0;
plen = 0;
}
/* Generate processor \_PR.CP0x */
acpigen_write_processor(core, pcontrol_blk, plen);
/* Generate P-state tables */
generate_P_state_entries(core, pattrs->num_cpus);
/* Generate C-state tables */
acpigen_write_CST_package(cstate_map, ARRAY_SIZE(cstate_map));
acpigen_pop_len();
}
}
unsigned long acpi_madt_irq_overrides(unsigned long current)
{
int sci_irq = acpi_sci_irq();
acpi_madt_irqoverride_t *irqovr;
uint16_t sci_flags = MP_IRQ_TRIGGER_LEVEL;
/* INT_SRC_OVR */
irqovr = (void *)current;
current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
if (sci_irq >= 20)
sci_flags |= MP_IRQ_POLARITY_LOW;
else
sci_flags |= MP_IRQ_POLARITY_HIGH;
irqovr = (void *)current;
current += acpi_create_madt_irqoverride(irqovr, 0, sci_irq, sci_irq,
sci_flags);
irqovr = (void *)current;
current += acpi_create_madt_irqoverride(irqovr, 0, 3, 3,
(MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW));
irqovr = (void *)current;
current += acpi_create_madt_irqoverride(irqovr, 0, 4, 4,
(MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW));
return current;
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#undef PCI_DEV_PIRQ_ROUTES
#undef ACPI_DEV_IRQ
#undef PCI_DEV_PIRQ_ROUTE
#undef PIRQ_PIC_ROUTES
#undef PIRQ_PIC
#undef IRQROUTE_H
#if defined(PIC_MODE)
#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
{ Package() { ## dev_ ## ffff, pin_, \_SB.PCI0.LPCB.LNK ## pin_name_, 0 } }
#else /* defined(PIC_MODE) */
#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
{ Package() { ## dev_ ## ffff, pin_, 0, PIRQ ## pin_name_ ## _APIC_IRQ } }
#endif
#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
{ ACPI_DEV_IRQ(dev_, 0, a_), \
ACPI_DEV_IRQ(dev_, 1, b_), \
ACPI_DEV_IRQ(dev_, 2, c_), \
ACPI_DEV_IRQ(dev_, 3, d_) }
/* Empty PIRQ_PIC definition. */
#define PIRQ_PIC(pirq_, pic_irq_)
/* Include the mainboard irq route definition */
#include "irqroute.h"

View File

@ -0,0 +1,464 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
OperationRegion (PRR0, PCI_Config, 0x00, 0x100)
Field (PRR0, AnyAcc, NoLock, Preserve) {
Offset(0x60),
PIRA, 8,
PIRB, 8,
PIRC, 8,
PIRD, 8,
Offset(0x68),
PIRE, 8,
PIRF, 8,
PIRG, 8,
PIRH, 8
}
Device (LNKA) { // PCI IRQ link A
Name (_HID,EISAID("PNP0C0F"))
//Name(_UID, 1)
Method (_STA,0,NotSerialized) {
If(And(PIRA, 0x80)) {
Return (0x9)
} Else {
Return (0xB)
} // Don't display
}
Method (_DIS,0,NotSerialized) {
Or (PIRA, 0x80, PIRA)
}
Method (_CRS,0,Serialized) {
Name (BUF0, ResourceTemplate() {IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And(PIRA, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One,Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0,And (PIRA,0x0F),IRQW) // Save in buffer
Return (BUF0) // Return Buf0
} // End of _CRS method
Name (_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit(IRQW,Local0) // Set IRQ
If (LNotEqual (IRQW,Zero)){
And (Local0, 0x7F,Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80,Local0)
}
Store (Local0, PIRA)
} // End of _SRS Method
}
Device(LNKB) { // PCI IRQ link B
Name (_HID,EISAID("PNP0C0F"))
//Name(_UID, 2)
Method (_STA,0,NotSerialized) {
If (And (PIRB, 0x80)) {
Return (0x9)
} Else {
Return (0xB)
} // Don't display
}
Method (_DIS,0,NotSerialized) {
Or (PIRB, 0x80,PIRB)
}
Method (_CRS,0,Serialized) {
Name(BUF0, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And (PIRB, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One,Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0,And (PIRB,0x0F),IRQW) // Save in buffer
Return (BUF0) // Return Buf0
} // End of _CRS method
Name (_PRS,
ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit(IRQW,Local0) // Set IRQ
If (LNotEqual(IRQW,Zero)) {
And (Local0, 0x7F, Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80, Local0)
}
Store (Local0, PIRB)
} // End of _SRS Method
}
Device(LNKC) { // PCI IRQ link C
Name(_HID, EISAID("PNP0C0F"))
//Name(_UID, 3)
Method (_STA,0,NotSerialized) {
If (And (PIRC, 0x80)) {
Return (0x9)
} Else {
Return (0xB)
} // Don't display
}
Method (_DIS, 0, NotSerialized) {
Or (PIRC, 0x80, PIRC)
}
Method (_CRS, 0, Serialized) {
Name (BUF0, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And (PIRC, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One,Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0,And (PIRC,0x0F),IRQW)
Return (BUF0)
} // End of _CRS method
Name (_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit(IRQW,Local0) // Set IRQ
If (LNotEqual (IRQW,Zero)) {
And (Local0, 0x7F, Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80,Local0)
}
Store (Local0, PIRC)
} // End of _SRS Method
}
Device (LNKD) { // PCI IRQ link D
Name (_HID,EISAID ("PNP0C0F"))
//Name(_UID, 4)
Method (_STA, 0, NotSerialized) {
If (And (PIRD, 0x80)) {
Return (0x9)
} Else {
Return (0xB)
} // Don't display
}
Method (_DIS, 0, NotSerialized) {
Or(PIRD, 0x80,PIRD)
}
Method (_CRS,0,Serialized) {
Name (BUF0, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And (PIRD, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One,Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0, And (PIRD,0x0F), IRQW)
Return (BUF0) // Return Buf0
} // End of _CRS method
Name (_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit (IRQW, Local0)// Set IRQ
If (LNotEqual (IRQW, Zero)) {
And (Local0, 0x7F, Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80, Local0)
}
Store(Local0, PIRD)
} // End of _SRS Method
}
Device(LNKE) { // PCI IRQ link E
Name(_HID,EISAID("PNP0C0F"))
//Name(_UID, 5)
Method (_STA,0,NotSerialized) {
If (And (PIRE, 0x80)) {
Return(0x9)
} Else {
Return(0xB)
} // Don't display
}
Method (_DIS,0,NotSerialized) {
Or (PIRE, 0x80, PIRE)
}
Method (_CRS, 0, Serialized) {
Name (BUF0, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And (PIRE, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One, Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0, And (PIRE,0x0F), IRQW)
Return (BUF0) // Return Buf0
} // End of _CRS method
Name(_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit (IRQW, Local0) // Set IRQ
If (LNotEqual (IRQW, Zero)) {
And (Local0, 0x7F, Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80, Local0)
}
Store (Local0, PIRE)
} // End of _SRS Method
}
Device(LNKF) { // PCI IRQ link F
Name (_HID,EISAID("PNP0C0F"))
//Name(_UID, 6)
Method (_STA,0,NotSerialized) {
If (And (PIRF, 0x80)) {
Return (0x9)
} Else {
Return (0xB)
} // Don't display
}
Method (_DIS,0,NotSerialized) {
Or (PIRB, 0x80, PIRF)
}
Method (_CRS,0,Serialized) {
Name(BUF0, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And (PIRF, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One, Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0, And (PIRF, 0x0F),IRQW)
Return (BUF0)
} // End of _CRS method
Name(_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit (IRQW,Local0) // Set IRQ
If (LNotEqual (IRQW,Zero)) {
And (Local0, 0x7F,Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80, Local0)
}
Store (Local0, PIRF)
} // End of _SRS Method
}
Device(LNKG) { // PCI IRQ link G
Name(_HID,EISAID("PNP0C0F"))
//Name(_UID, 7)
Method(_STA,0,NotSerialized) {
If (And (PIRG, 0x80)) {
Return (0x9)
} Else {
Return (0xB)
} // Don't display
}
Method (_DIS, 0, NotSerialized) {
Or(PIRG, 0x80,PIRG)
}
Method (_CRS,0,Serialized){
Name(BUF0,ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And(PIRG, 0x80)) {
Store(Zero, Local0)
} Else {
Store(One,Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0,And(PIRG,0x0F),IRQW)
Return (BUF0)
} // End of _CRS method
Name (_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit(IRQW,Local0) // Set IRQ
If (LNotEqual (IRQW,Zero)) {
And (Local0, 0x7F,Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80,Local0)
}
Store (Local0, PIRG)
} // End of _SRS Method
}
Device(LNKH) { // PCI IRQ link H
Name (_HID,EISAID("PNP0C0F"))
//Name(_UID, 8)
Method (_STA,0,NotSerialized) {
If (And(PIRH, 0x80)) {
Return(0x9)
} Else {
Return(0xB)
} // Don't display
}
Method (_DIS,0,NotSerialized) {
Or(PIRH, 0x80,PIRH)
}
Method (_CRS,0,Serialized) {
Name(BUF0, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){0}})
//
// Define references to buffer elements
//
CreateWordField (BUF0, 0x01, IRQW) // IRQ low
//
// Write current settings into IRQ descriptor
//
If (And (PIRH, 0x80)) {
Store (Zero, Local0)
} Else {
Store (One,Local0)
}
//
// Shift 1 by value in register 70, Save in buffer
//
ShiftLeft (Local0,And(PIRH,0x0F),IRQW)
Return (BUF0)
} // End of _CRS method
Name(_PRS, ResourceTemplate()
{IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
Method (_SRS,1,NotSerialized) {
CreateWordField (ARG0, 0x01, IRQW) // IRQ low
FindSetRightBit (IRQW,Local0)// Set IRQ
If (LNotEqual (IRQW,Zero)) {
And (Local0, 0x7F,Local0)
Decrement (Local0)
} Else {
Or (Local0, 0x80,Local0)
}
Store (Local0, PIRH)
}
}

View File

@ -0,0 +1,39 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/* PCI Interrupt Routing */
Method(_PRT)
{
/*
* PICM comes from _PIC, which returns the following:
* 0 PIC mode
* 1 APIC mode
* 2 SAPIC mode
*/
If (PICM) {
Return (Package() {
#undef PIC_MODE
#include "irq_helper.h"
PCI_DEV_PIRQ_ROUTES
})
} Else {
Return (Package() {
#define PIC_MODE
#include "irq_helper.h"
PCI_DEV_PIRQ_ROUTES
})
}
}

View File

@ -0,0 +1,92 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/* Intel LPC Bus Device - 0:1f.0 */
Device (LPC0)
{
Name(_ADR, 0x001f0000)
#include "irqlinks.asl"
Device (FWH) // Firmware Hub
{
Name (_HID, EISAID("INT0800"))
Name (_CRS, ResourceTemplate()
{
Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
})
}
Device (HPET)
{
Name (_HID, EISAID("PNP0103"))
Name (_CID, 0x010CD041)
Method (_STA, 0) // Device Status
{
Return (0xf) // Enable and show device
}
Name(_CRS, ResourceTemplate()
{
Memory32Fixed(ReadOnly, 0xfed00000, 0x400)
})
}
Device(LDRC) // LPC device: Resource consumption
{
Name (_HID, EISAID("PNP0C02"))
Name (_UID, 2)
Name (RBUF, ResourceTemplate()
{
IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
})
Method (_CRS, 0, NotSerialized)
{
Return (RBUF)
}
}
Device (RTC) // Real Time Clock
{
Name (_HID, EISAID("PNP0B00"))
Name (_CRS, ResourceTemplate()
{
IO (Decode16, 0x70, 0x70, 1, 8)
})
}
Device (TIMR) // Intel 8254 timer
{
Name(_HID, EISAID("PNP0100"))
Name(_CRS, ResourceTemplate()
{
IO (Decode16, 0x40, 0x40, 0x01, 0x04)
IO (Decode16, 0x50, 0x50, 0x10, 0x04)
IRQNoFlags() {0}
})
}
}

View File

@ -0,0 +1,465 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
Name (PR01, Package() {
// [SL01]: PCI Express Slot 1 on 1A on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR01, Package() {
// [SL01]: PCI Express Slot 1 on 1A on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH01, Package() {
// [SL01]: PCI Express Slot 1 on 1A on PCI0
Package() { 0x0000FFFF, 0, 0, 26 },
Package() { 0x0000FFFF, 1, 0, 28 },
Package() { 0x0000FFFF, 2, 0, 29 },
Package() { 0x0000FFFF, 3, 0, 30 },
})
Name (PR02, Package() {
// [SL02]: PCI Express Slot 2 on 1B on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR02, Package() {
// [SL02]: PCI Express Slot 2 on 1B on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH02, Package() {
// [SL02]: PCI Express Slot 2 on 1B on PCI0
Package() { 0x0000FFFF, 0, 0, 27 },
Package() { 0x0000FFFF, 1, 0, 30 },
Package() { 0x0000FFFF, 2, 0, 28 },
Package() { 0x0000FFFF, 3, 0, 29 },
})
Name (PR03, Package() {
// [CB0I]: CB3DMA on IOSF
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [CB0J]: CB3DMA on IOSF
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
// [CB0K]: CB3DMA on IOSF
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
// [CB0L]: CB3DMA on IOSF
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR03, Package() {
// [CB0I]: CB3DMA on IOSF
Package() { 0x0000FFFF, 0, 0, 16 },
// [CB0J]: CB3DMA on IOSF
Package() { 0x0000FFFF, 1, 0, 17 },
// [CB0K]: CB3DMA on IOSF
Package() { 0x0000FFFF, 2, 0, 18 },
// [CB0L]: CB3DMA on IOSF
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH03, Package() {
// [CB0I]: CB3DMA on IOSF
Package() { 0x0000FFFF, 0, 0, 32 },
// [CB0J]: CB3DMA on IOSF
Package() { 0x0000FFFF, 1, 0, 36 },
// [CB0K]: CB3DMA on IOSF
Package() { 0x0000FFFF, 2, 0, 37 },
// [CB0L]: CB3DMA on IOSF
Package() { 0x0000FFFF, 3, 0, 38 },
})
Name (PR04, Package() {
// [SL04]: PCI Express Slot 4 on 2B on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR04, Package() {
// [SL04]: PCI Express Slot 4 on 2B on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH04, Package() {
// [SL04]: PCI Express Slot 4 on 2B on PCI0
Package() { 0x0000FFFF, 0, 0, 33 },
Package() { 0x0000FFFF, 1, 0, 37 },
Package() { 0x0000FFFF, 2, 0, 38 },
Package() { 0x0000FFFF, 3, 0, 36 },
})
Name (PR05, Package() {
// [SL05]: PCI Express Slot 5 on 2C on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR05, Package() {
// [SL05]: PCI Express Slot 5 on 2C on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH05, Package() {
// [SL05]: PCI Express Slot 5 on 2C on PCI0
Package() { 0x0000FFFF, 0, 0, 34 },
Package() { 0x0000FFFF, 1, 0, 37 },
Package() { 0x0000FFFF, 2, 0, 36 },
Package() { 0x0000FFFF, 3, 0, 38 },
})
Name (PR06, Package() {
// [SL06]: PCI Express Slot 6 on 2D on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR06, Package() {
// [SL06]: PCI Express Slot 6 on 2D on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH06, Package() {
// [SL06]: PCI Express Slot 6 on 2D on PCI0
Package() { 0x0000FFFF, 0, 0, 35 },
Package() { 0x0000FFFF, 1, 0, 36 },
Package() { 0x0000FFFF, 2, 0, 38 },
Package() { 0x0000FFFF, 3, 0, 37 },
})
Name (PR07, Package() {
// [SL07]: PCI Express Slot 7 on 3A on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR07, Package() {
// [SL07]: PCI Express Slot 7 on 3A on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH07, Package() {
// [SL07]: PCI Express Slot 7 on 3A on PCI0
Package() { 0x0000FFFF, 0, 0, 40 },
Package() { 0x0000FFFF, 1, 0, 44 },
Package() { 0x0000FFFF, 2, 0, 45 },
Package() { 0x0000FFFF, 3, 0, 46 },
})
Name (PR08, Package() {
// [SL08]: PCI Express Slot 8 on 3B on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR08, Package() {
// [SL08]: PCI Express Slot 8 on 3B on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH08, Package() {
// [SL08]: PCI Express Slot 8 on 3B on PCI0
Package() { 0x0000FFFF, 0, 0, 41 },
Package() { 0x0000FFFF, 1, 0, 45 },
Package() { 0x0000FFFF, 2, 0, 46 },
Package() { 0x0000FFFF, 3, 0, 44 },
})
Name (PR09, Package() {
// [SL09]: PCI Express Slot 9 on 3C on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR09, Package() {
// [SL09]: PCI Express Slot 9 on 3C on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH09, Package() {
// [SL09]: PCI Express Slot 9 on 3C on PCI0
Package() { 0x0000FFFF, 0, 0, 42 },
Package() { 0x0000FFFF, 1, 0, 45 },
Package() { 0x0000FFFF, 2, 0, 44 },
Package() { 0x0000FFFF, 3, 0, 46 },
})
Name (PR0A, Package() {
// [SL0A]: PCI Express Slot 10 on 3D on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
})
Name (AR0A, Package() {
// [SL0A]: PCI Express Slot 10 on 3D on PCI0
Package() { 0x0000FFFF, 0, 0, 16 },
Package() { 0x0000FFFF, 1, 0, 17 },
Package() { 0x0000FFFF, 2, 0, 18 },
Package() { 0x0000FFFF, 3, 0, 19 },
})
Name (AH0A, Package() {
// [SL0A]: PCI Express Slot 10 on 3D on PCI0
Package() { 0x0000FFFF, 0, 0, 43 },
Package() { 0x0000FFFF, 1, 0, 44 },
Package() { 0x0000FFFF, 2, 0, 46 },
Package() { 0x0000FFFF, 3, 0, 45 },
})
// PCI Express Port 1A on PCI0
Device (BR1A) {
Name (_ADR, 0x00010000)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR01)
}
If (LEqual(APC1, One)) {
Return (AH01)
}
Return (AR01)
}
}
// PCI Express Port 1B on PCI0
Device (BR1B) {
Name (_ADR, 0x00010001)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR02)
}
If (LEqual(APC1, One)) {
Return (AH02)
}
Return (AR02)
}
}
// PCI Express Port 2A on PCI0
Device (BR2A) {
Name (_ADR, 0x00020000)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR03)
}
If (LEqual(APC1, One)) {
Return (AH03)
}
Return (AR03)
}
// CB3DMA on IOSF
Device (CB0I) {
Name (_ADR, 0x00000000)
}
// CB3DMA on IOSF
Device (CB0J) {
Name (_ADR, 0x00000001)
}
// CB3DMA on IOSF
Device (CB0K) {
Name (_ADR, 0x00000002)
}
// CB3DMA on IOSF
Device (CB0L) {
Name (_ADR, 0x00000003)
}
}
// PCI Express Port 2B on PCI0
Device (BR2B) {
Name (_ADR, 0x00020001)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR04)
}
If (LEqual(APC1, One)) {
Return (AH04)
}
Return (AR04)
}
}
// PCI Express Port 2C on PCI0
Device (BR2C) {
Name (_ADR, 0x00020002)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR05)
}
If (LEqual(APC1, One)) {
Return (AH05)
}
Return (AR05)
}
}
// PCI Express Port 2D on PCI0
Device (BR2D) {
Name (_ADR, 0x00020003)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR06)
}
If (LEqual(APC1, One)) {
Return (AH06)
}
Return (AR06)
}
}
// PCI Express Port 3A on PCI0
Device (BR3A) {
Name (_ADR, 0x00030000)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR07)
}
If (LEqual(APC1, One)) {
Return (AH07)
}
Return (AR07)
}
}
// PCI Express Port 3B on PCI0
Device (BR3B) {
Name (_ADR, 0x00030001)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR08)
}
If (LEqual(APC1, One)) {
Return (AH08)
}
Return (AR08)
}
}
// PCI Express Port 3C on PCI0
Device (BR3C) {
Name (_ADR, 0x00030002)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR09)
}
If (LEqual(APC1, One)) {
Return (AH09)
}
Return (AR09)
}
}
// PCI Express Port 3D on PCI0
Device (BR3D) {
Name (_ADR, 0x00030003)
Method (_PRW, 0) {
Return (Package (0x02) {0x09, 0x04})
}
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR0A)
}
If (LEqual(APC1, One)) {
Return (AH0A)
}
Return (AR0A)
}
}

View File

@ -0,0 +1,350 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <soc/iomap.h>
#include <soc/irq.h>
Name(_HID,EISAID("PNP0A08")) // PCIe
Name(_CID,EISAID("PNP0A03")) // PCI
Name(_ADR, 0)
Name(_BBN, 0)
Name (MCRS, ResourceTemplate() {
// Bus Numbers
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, 0x0000, 0x00fe, 0x0000, 0xff,,, PB00)
// IO Region 0
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8,,, PI00)
// PCI Config Space
Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
// IO Region 1
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, 0x0d00, 0xefff, 0x0000, 0xE300,,, PI01)
// VGA memory (0xa0000-0xbffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
0x00020000,,, ASEG)
// OPROM reserved (0xc0000-0xc3fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
0x00004000,,, OPR0)
// OPROM reserved (0xc4000-0xc7fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
0x00004000,,, OPR1)
// OPROM reserved (0xc8000-0xcbfff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
0x00004000,,, OPR2)
// OPROM reserved (0xcc000-0xcffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
0x00004000,,, OPR3)
// OPROM reserved (0xd0000-0xd3fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
0x00004000,,, OPR4)
// OPROM reserved (0xd4000-0xd7fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
0x00004000,,, OPR5)
// OPROM reserved (0xd8000-0xdbfff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
0x00004000,,, OPR6)
// OPROM reserved (0xdc000-0xdffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
0x00004000,,, OPR7)
// BIOS Extension (0xe0000-0xe3fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
0x00004000,,, ESG0)
// BIOS Extension (0xe4000-0xe7fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
0x00004000,,, ESG1)
// BIOS Extension (0xe8000-0xebfff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
0x00004000,,, ESG2)
// BIOS Extension (0xec000-0xeffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000ec000, 0x000effff, 0x00000000,
0x00004000,,, ESG3)
// System BIOS (0xf0000-0xfffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
0x00010000,,, FSEG)
// PCI Memory Region (Top of memory-0xfeafffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x90000000, 0xFEAFFFFF, 0x00000000,
0x6EB00000,,, PMEM)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0xfec00000, 0xfecfffff, 0x00000000,
0x00100000,,, APIC)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0xfed00000, 0xfedfffff, 0x00000000,
0x00100000,,, PCHR)
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0x0000000000000000, // Granularity
0x0000380000000000, // Range Minimum
0x0000383FFFFFFFFF, // Range Maximum
0x0000000000000000, // Translation Offset
0x0000004000000000, // Length
,,, AddressRangeMemory, TypeStatic)
})
Method (_CRS, 0, Serialized) {
Return (MCRS)
}
/* Device Resource Consumption */
Device (PDRC) {
Name (_HID, EISAID("PNP0C02"))
Name (_UID, 1)
Name (PDRS, ResourceTemplate() {
Memory32Fixed(ReadWrite, ABORT_BASE_ADDRESS, ABORT_BASE_SIZE)
Memory32Fixed(ReadWrite, PSEG_BASE_ADDRESS, PSEG_BASE_SIZE)
Memory32Fixed(ReadWrite, IOXAPIC1_BASE_ADDRESS, IOXAPIC1_BASE_SIZE)
Memory32Fixed(ReadWrite, IOXAPIC2_BASE_ADDRESS, IOXAPIC2_BASE_SIZE)
Memory32Fixed(ReadWrite, PCH_BASE_ADDRESS, PCH_BASE_SIZE)
Memory32Fixed(ReadWrite, LXAPIC_BASE_ADDRESS, LXAPIC_BASE_SIZE)
Memory32Fixed(ReadWrite, FIRMWARE_BASE_ADDRESS, FIRMWARE_BASE_SIZE)
})
// Current Resource Settings
Method (_CRS, 0, Serialized)
{
Return(PDRS)
}
}
Method (_OSC, 4) {
/* Check for proper GUID */
If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
{
/* Let OS control everything */
Return (Arg3)
}
Else
{
/* Unrecognized UUID */
CreateDWordField (Arg3, 0, CDW1)
Or (CDW1, 4, CDW1)
Return (Arg3)
}
}
Name (PR00, Package() {
// [DMI0]: Legacy PCI Express Port 0 on PCI0
Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [BR1A]: PCI Express Port 1A on PCI0
// [BR1B]: PCI Express Port 1B on PCI0
Package() { 0x0001FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [BR2A]: PCI Express Port 2A on PCI0
// [BR2B]: PCI Express Port 2B on PCI0
// [BR2C]: PCI Express Port 2C on PCI0
// [BR2D]: PCI Express Port 2D on PCI0
Package() { 0x0002FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [BR3A]: PCI Express Port 3A on PCI0
// [BR3B]: PCI Express Port 3B on PCI0
// [BR3C]: PCI Express Port 3C on PCI0
// [BR3D]: PCI Express Port 3D on PCI0
Package() { 0x0003FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [CB0A]: CB3DMA on PCI0
// [CB0E]: CB3DMA on PCI0
Package() { 0x0004FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [CB0B]: CB3DMA on PCI0
// [CB0F]: CB3DMA on PCI0
Package() { 0x0004FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
// [CB0C]: CB3DMA on PCI0
// [CB0G]: CB3DMA on PCI0
Package() { 0x0004FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
// [CB0D]: CB3DMA on PCI0
// [CB0H]: CB3DMA on PCI0
Package() { 0x0004FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
// [IIM0]: IIOMISC on PCI0
Package() { 0x0005FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0005FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0005FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0005FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
// [IID0]: IIODFX0 on PCI0
Package() { 0x0006FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
Package() { 0x0006FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
Package() { 0x0006FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
Package() { 0x0006FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
// [XHCI]: xHCI controller 1 on PCH
Package() { 0x0014FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
// [HECI]: ME HECI on PCH
// [IDER]: ME IDE redirect on PCH
Package() { 0x0016FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [HEC2]: ME HECI2 on PCH
// [MEKT]: MEKT on PCH
Package() { 0x0016FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
// [GBEM]: GbE Controller VPRO
Package() { 0x0019FFFF, 0, \_SB.PCI0.LPC0.LNKE, 0 },
// [EHC2]: EHCI controller #2 on PCH
Package() { 0x001AFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
// [ALZA]: High definition Audio Controller
Package() { 0x001BFFFF, 0, \_SB.PCI0.LPC0.LNKG, 0 },
// [RP01]: Pci Express Port 1 on PCH
// [RP05]: Pci Express Port 5 on PCH
Package() { 0x001CFFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [RP02]: Pci Express Port 2 on PCH
// [RP06]: Pci Express Port 6 on PCH
Package() { 0x001CFFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
// [RP03]: Pci Express Port 3 on PCH
// [RP07]: Pci Express Port 7 on PCH
Package() { 0x001CFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
// [RP04]: Pci Express Port 4 on PCH
// [RP08]: Pci Express Port 8 on ICH
Package() { 0x001CFFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
// [EHC1]: EHCI controller #1 on PCH
Package() { 0x001DFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
// [SAT1]: SATA controller 1 on PCH
// [SAT2]: SATA Host controller 2 on PCH
Package() { 0x001FFFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
// [SMBS]: SMBus controller on PCH
// [TERM]: Thermal Subsystem on ICH
Package() { 0x001FFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
})
Name (AR00, Package() {
// [DMI0]: Legacy PCI Express Port 0 on PCI0
Package() { 0x0000FFFF, 0, 0, 47 },
// [BR1A]: PCI Express Port 1A on PCI0
// [BR1B]: PCI Express Port 1B on PCI0
Package() { 0x0001FFFF, 0, 0, 47 },
// [BR2A]: PCI Express Port 2A on PCI0
// [BR2B]: PCI Express Port 2B on PCI0
// [BR2C]: PCI Express Port 2C on PCI0
// [BR2D]: PCI Express Port 2D on PCI0
Package() { 0x0002FFFF, 0, 0, 47 },
// [BR3A]: PCI Express Port 3A on PCI0
// [BR3B]: PCI Express Port 3B on PCI0
// [BR3C]: PCI Express Port 3C on PCI0
// [BR3D]: PCI Express Port 3D on PCI0
Package() { 0x0003FFFF, 0, 0, 47 },
// [CB0A]: CB3DMA on PCI0
// [CB0E]: CB3DMA on PCI0
Package() { 0x0004FFFF, 0, 0, 31 },
// [CB0B]: CB3DMA on PCI0
// [CB0F]: CB3DMA on PCI0
Package() { 0x0004FFFF, 1, 0, 39 },
// [CB0C]: CB3DMA on PCI0
// [CB0G]: CB3DMA on PCI0
Package() { 0x0004FFFF, 2, 0, 31 },
// [CB0D]: CB3DMA on PCI0
// [CB0H]: CB3DMA on PCI0
Package() { 0x0004FFFF, 3, 0, 39 },
// [IIM0]: IIOMISC on PCI0
Package() { 0x0005FFFF, 0, 0, 16 },
Package() { 0x0005FFFF, 1, 0, 17 },
Package() { 0x0005FFFF, 2, 0, 18 },
Package() { 0x0005FFFF, 3, 0, 19 },
// [IID0]: IIODFX0 on PCI0
Package() { 0x0006FFFF, 0, 0, 16 },
Package() { 0x0006FFFF, 1, 0, 17 },
Package() { 0x0006FFFF, 2, 0, 18 },
Package() { 0x0006FFFF, 3, 0, 19 },
// [XHCI]: xHCI controller 1 on PCH
Package() { 0x0014FFFF, 3, 0, 19 },
// [HECI]: ME HECI on PCH
// [IDER]: ME IDE redirect on PCH
Package() { 0x0016FFFF, 0, 0, 16 },
// [HEC2]: ME HECI2 on PCH
// [MEKT]: MEKT on PCH
Package() { 0x0016FFFF, 1, 0, 17 },
// [GBEM]: GbE Controller VPRO
Package() { 0x0019FFFF, 0, 0, 20 },
// [EHC2]: EHCI controller #2 on PCH
Package() { 0x001AFFFF, 2, 0, 18 },
// [ALZA]: High definition Audio Controller
Package() { 0x001BFFFF, 0, 0, 22 },
// [RP01]: Pci Express Port 1 on PCH
// [RP05]: Pci Express Port 5 on PCH
Package() { 0x001CFFFF, 0, 0, 16 },
// [RP02]: Pci Express Port 2 on PCH
// [RP06]: Pci Express Port 6 on PCH
Package() { 0x001CFFFF, 1, 0, 17 },
// [RP03]: Pci Express Port 3 on PCH
// [RP07]: Pci Express Port 7 on PCH
Package() { 0x001CFFFF, 2, 0, 18 },
// [RP04]: Pci Express Port 4 on PCH
// [RP08]: Pci Express Port 8 on ICH
Package() { 0x001CFFFF, 3, 0, 19 },
// [EHC1]: EHCI controller #1 on PCH
Package() { 0x001DFFFF, 2, 0, 18 },
// [SAT1]: SATA controller 1 on PCH
// [SAT2]: SATA Host controller 2 on PCH
Package() { 0x001FFFFF, 0, 0, 16 },
// [SMBS]: SMBus controller on PCH
// [TERM]: Thermal Subsystem on ICH
Package() { 0x001FFFFF, 2, 0, 18 },
})
// Socket 0 Root bridge
Method (_PRT, 0) {
If (LEqual(PICM, Zero)) {
Return (PR00)
}
Return (AR00) // If you disable the IOxAPIC in IIO, you should return AR00
}
#include "lpc.asl"

View File

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <cpu/intel/microcode/microcode.c>
static void bootblock_cpu_init(void)
{
/* Load microcode before any caching. */
intel_update_microcode_from_cbfs();
}

View File

@ -0,0 +1,106 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <lib.h>
#include <string.h>
#include <bootstate.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
#include <chip.h>
static void pci_domain_set_resources(device_t dev)
{
assign_resources(dev->link_list);
}
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = NULL,
.init = NULL,
.scan_bus = pci_domain_scan_bus,
.ops_pci_bus = pci_bus_default_ops,
};
static struct device_operations cpu_bus_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.init = broadwell_de_init_cpus,
.scan_bus = NULL,
};
static void enable_dev(device_t dev)
{
printk(BIOS_DEBUG, "enable_dev(%s, %d)\n",
dev_name(dev), dev->path.type);
/* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_DOMAIN) {
dev->ops = &pci_domain_ops;
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
dev->ops = &cpu_bus_ops;
} else if (dev->path.type == DEVICE_PATH_PCI) {
/* Handle south cluster enablement. */
if (PCI_SLOT(dev->path.pci.devfn) > 0 &&
(dev->ops == NULL || dev->ops->enable == NULL)) {
southcluster_enable_dev(dev);
}
}
}
static void fsp_notify(void *arg)
{
FspNotify (*(uint32_t *)arg);
}
static uint32_t gFspNotifyAfterPciEnumeration = EnumInitPhaseAfterPciEnumeration;
static uint32_t gFspNotifyReadtToBoot = EnumInitPhaseReadyToBoot;
static BOOT_STATE_CALLBACK(bscb_fspnotify1, fsp_notify, &gFspNotifyAfterPciEnumeration);
static BOOT_STATE_CALLBACK(bscb_fspnotify2, fsp_notify, &gFspNotifyReadtToBoot);
/* Called at BS_DEV_INIT_CHIPS time -- very early. Just after BS_PRE_DEVICE. */
static void soc_init(void *chip_info)
{
boot_state_sched_on_exit(&bscb_fspnotify1, BS_DEV_RESOURCES);
boot_state_sched_on_exit(&bscb_fspnotify2, BS_PAYLOAD_LOAD);
broadwell_de_init_pre_device();
}
struct chip_operations soc_intel_fsp_broadwell_de_ops = {
CHIP_NAME("Intel(R) Xeon(R) Processor D-1500 Product Family")
.enable_dev = enable_dev,
.init = soc_init,
};
static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
struct pci_operations soc_pci_ops = {
.set_subsystem = &pci_set_subsystem,
};

View File

@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_CHIP_H_
#define _SOC_CHIP_H_
#include <arch/acpi.h>
/* The devicetree parser expects chip.h to reside directly in the path
* specified by the devicetree. */
struct soc_intel_fsp_broadwell_de_config {
};
extern struct chip_operations soc_intel_fsp_broadwell_de_ops;
#endif /* _SOC_CHIP_H_ */

View File

@ -0,0 +1,110 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdlib.h>
#include <console/console.h>
#include <cpu/cpu.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <soc/msr.h>
#include <soc/pattrs.h>
#include <soc/ramstage.h>
static void configure_mca(void);
static struct mp_flight_record mp_steps[] = {
MP_FR_BLOCK_APS(mp_initialize_cpu, NULL, mp_initialize_cpu, NULL),
};
static int adjust_apic_id(int index, int apic_id)
{
return index;
}
static void configure_mca(void)
{
msr_t msr;
const unsigned int mcg_cap_msr = 0x179;
int i;
int num_banks;
msr = rdmsr(mcg_cap_msr);
num_banks = msr.lo & 0xff;
/* TODO(adurbin): This should only be done on a cold boot. Also, some
* of these banks are core vs package scope. For now every CPU clears
* every bank. */
msr.lo = msr.hi = 0;
for (i = 0; i < num_banks; i++) {
wrmsr(MSR_IA32_MC0_STATUS + (i * 4) + 1, msr);
wrmsr(MSR_IA32_MC0_STATUS + (i * 4) + 2, msr);
wrmsr(MSR_IA32_MC0_STATUS + (i * 4) + 3, msr);
}
msr.lo = msr.hi = 0xffffffff;
for (i = 0; i < num_banks; i++)
wrmsr(MSR_IA32_MC0_STATUS + (i * 4), msr);
}
void broadwell_de_init_cpus(device_t dev)
{
struct bus *cpu_bus = dev->link_list;
const struct pattrs *pattrs = pattrs_get();
struct mp_params mp_params;
x86_mtrr_check();
/* Enable the local cpu apics */
setup_lapic();
mp_params.num_cpus = pattrs->num_cpus,
mp_params.parallel_microcode_load = 1,
mp_params.adjust_apic_id = adjust_apic_id;
mp_params.flight_plan = &mp_steps[0];
mp_params.num_records = ARRAY_SIZE(mp_steps);
mp_params.microcode_pointer = pattrs->microcode_patch;
if (mp_init(cpu_bus, &mp_params)) {
printk(BIOS_ERR, "MP initialization failure.\n");
}
}
static void broadwell_de_core_init(device_t cpu)
{
printk(BIOS_DEBUG, "Init Broadwell-DE core.\n");
configure_mca();
}
static struct device_operations cpu_dev_ops = {
.init = broadwell_de_core_init,
};
static struct cpu_device_id cpu_table[] = {
{ X86_VENDOR_INTEL, 0x50661 },
{ X86_VENDOR_INTEL, 0x50662 },
{ X86_VENDOR_INTEL, 0x50663 },
{ X86_VENDOR_INTEL, 0x50664 },
{ 0, 0 },
};
static const struct cpu_driver driver __cpu_driver = {
.ops = &cpu_dev_ops,
.id_table = cpu_table,
};

View File

@ -0,0 +1,93 @@
config BROADWELL_DE_FSP_SPECIFIC_OPTIONS
def_bool y
select PLATFORM_USES_FSP1_0
select USE_GENERIC_FSP_CAR_INC
select FSP_USES_UPD
config FSP_FILE
string
default "../intel/fsp/broadwell_de/BROADWELLDE_FSP.bin"
help
The path and filename of the Intel FSP binary for this platform.
config FSP_LOC
hex
default 0xffeb0000
help
The location in CBFS that the FSP is located. This must match the
value that is set in the FSP binary. If the FSP needs to be moved,
rebase the FSP with Intel's BCT (tool).
The Broadwell-DE FSP is built with a preferred base address of
0xffeb0000.
config FSP_MEMORY_DOWN
bool "Enable Memory Down"
default n
help
Load SPD data from ROM instead of trying to read from SMBus.
If the platform has DIMM sockets, say N. If memory is down, say Y and
supply the appropriate SPD data for each Channel/DIMM.
config FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT
bool "Channel 0, DIMM 0 Present"
default n
depends on FSP_MEMORY_DOWN
help
Select Y if Channel 0, DIMM 0 is present.
config FSP_MEMORY_DOWN_CH0DIMM0_SPD_FILE
string "Channel 0, DIMM 0 SPD File"
default "spd_ch0_dimm0.bin"
depends on FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT
help
Path to the file which contains the SPD data for Channel 0, DIMM 0.
config FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT
bool "Channel 0, DIMM 1 Present"
default n
depends on FSP_MEMORY_DOWN
help
Select Y if Channel 0, DIMM 1 is present.
config FSP_MEMORY_DOWN_CH0DIMM1_SPD_FILE
string "Channel 0, DIMM 1 SPD File"
default "spd_ch0_dimm1.bin"
depends on FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT
help
Path to the file which contains the SPD data for Channel 0, DIMM 1.
config FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT
bool "Channel 1, DIMM 0 Present"
default n
depends on FSP_MEMORY_DOWN
help
Select Y if Channel 1, DIMM 0 is present.
config FSP_MEMORY_DOWN_CH1DIMM0_SPD_FILE
string "Channel 1, DIMM 0 SPD File"
default "spd_ch1_dimm0.bin"
depends on FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT
help
Path to the file which contains the SPD data for Channel 1, DIMM 0.
config FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT
bool "Channel 1, DIMM 1 Present"
default n
depends on FSP_MEMORY_DOWN
help
Select Y if Channel 1, DIMM 1 is present.
config FSP_MEMORY_DOWN_CH1DIMM1_SPD_FILE
string "Channel 1, DIMM 1 SPD File"
default "spd_ch1_dimm1.bin"
depends on FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT
help
Path to the file which contains the SPD data for Channel 1, DIMM 1.
config FSP_HYPERTHREADING
bool "Enable Hyper-Threading"
default y
help
Enable Intel(r) Hyper-Threading Technology for the Broadwell-DE SoC.

View File

@ -0,0 +1,17 @@
romstage-y += chipset_fsp_util.c
cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT) += spd_ch0_dimm0.bin
spd_ch0_dimm0.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_FILE))
spd_ch0_dimm0.bin-type := spd
cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT) += spd_ch0_dimm1.bin
spd_ch0_dimm1.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_FILE))
spd_ch0_dimm1.bin-type := spd
cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT) += spd_ch1_dimm0.bin
spd_ch1_dimm0.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_FILE))
spd_ch1_dimm0.bin-type := spd
cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT) += spd_ch1_dimm1.bin
spd_ch1_dimm1.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_FILE))
spd_ch1_dimm1.bin-type := spd

View File

@ -0,0 +1,126 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
* Copyright (C) 2015-2016 Intel Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <types.h>
#include <string.h>
#include <console/console.h>
#include <bootstate.h>
#include <cbfs.h>
#include <cbmem.h>
#include <device/device.h>
#include <device/pci_def.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
#include <soc/pci_devs.h>
#include <soc/reset.h>
#include <soc/romstage.h>
#include <chip.h>
#include <fsp.h>
/* Copy the default UPD region and settings to a buffer for modification */
static void GetUpdDefaultFromFsp (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData)
{
VPD_DATA_REGION *VpdDataRgnPtr;
UPD_DATA_REGION *UpdDataRgnPtr;
VpdDataRgnPtr = (VPD_DATA_REGION *)(UINT32)(FspInfo->CfgRegionOffset + FspInfo->ImageBase);
UpdDataRgnPtr = (UPD_DATA_REGION *)(UINT32)(VpdDataRgnPtr->PcdUpdRegionOffset + FspInfo->ImageBase);
memcpy((void *)UpdData, (void *)UpdDataRgnPtr, sizeof(UPD_DATA_REGION));
}
typedef struct soc_intel_fsp_broadwell_de_config config_t;
/**
* Update the UPD data based on values from devicetree.cb
*
* @param UpdData Pointer to the UPD Data structure
*/
static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
{
/*
* Serial Port
*/
if (IS_ENABLED(CONFIG_INTEGRATED_UART))
UpdData->SerialPortConfigure = 1;
/*
* Memory Down
*/
if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN)) {
UpdData->MemDownEnable = 1;
if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT))
UpdData->MemDownCh0Dimm0SpdPtr
= (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm0.bin", CBFS_TYPE_RAW, NULL);
if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT))
UpdData->MemDownCh0Dimm1SpdPtr
= (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm1.bin", CBFS_TYPE_RAW, NULL);
if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT))
UpdData->MemDownCh1Dimm0SpdPtr
= (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm0.bin", CBFS_TYPE_RAW, NULL);
if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT))
UpdData->MemDownCh1Dimm1SpdPtr
= (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm1.bin", CBFS_TYPE_RAW, NULL);
} else {
UpdData->MemDownEnable = 0;
}
printk(FSP_INFO_LEVEL, "Memory Down Support: %s\n",
UpdData->MemDownEnable ? "Enabled" : "Disabled");
/*
* Fast Boot
*/
if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
UpdData->MemFastBoot = 1;
else
UpdData->MemFastBoot = 0;
/*
* Hyper-Threading
*/
if (IS_ENABLED(CONFIG_FSP_HYPERTHREADING))
UpdData->HyperThreading = 1;
else
UpdData->HyperThreading = 0;
}
/* Set up the Broadwell-DE specific structures for the call into the FSP */
void chipset_fsp_early_init(FSP_INIT_PARAMS *pFspInitParams, FSP_INFO_HEADER *fsp_ptr)
{
FSP_INIT_RT_BUFFER *pFspRtBuffer = pFspInitParams->RtBufferPtr;
/* Initialize the UPD Data */
GetUpdDefaultFromFsp (fsp_ptr, pFspRtBuffer->Common.UpdDataRgnPtr);
ConfigureDefaultUpdData(pFspRtBuffer->Common.UpdDataRgnPtr);
pFspInitParams->NvsBufferPtr = NULL;
#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
/* Find the fastboot cache that was saved in the ROM */
pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
#endif
return;
}
/* The FSP returns here after the fsp_early_init call */
void ChipsetFspReturnPoint(EFI_STATUS Status, VOID *HobListPtr)
{
*(void **)CBMEM_FSP_HOB_PTR = HobListPtr;
if (Status == 0xFFFFFFFF) {
warm_reset();
}
romstage_main_continue(Status, HobListPtr);
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
* Copyright (C) 2015-2016 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CHIPSET_FSP_UTIL_H
#define CHIPSET_FSP_UTIL_H
#include <fsp.h>
#define FSP_INFO_HEADER_GUID \
{ \
0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
}
/*
* The FSP Image ID is different for each platform's FSP and
* can be used to verify that the right FSP binary is loaded.
* For the Broadwell-DE FSP, the Image Id is "BDX-DE".
*/
#define FSP_IMAGE_ID_DWORD0 ((unsigned int)(FSP_IMAGE_ID))
#define FSP_IMAGE_ID_DWORD1 ((unsigned int)(FSP_IMAGE_ID >> 32))
#endif /* CHIPSET_FSP_UTIL_H */

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_ACPI_H_
#define _SOC_ACPI_H_
#include <arch/acpi.h>
void acpi_create_intel_hpet(acpi_hpet_t *hpet);
void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt);
unsigned long acpi_madt_irq_overrides(unsigned long current);
uint16_t get_pmbase(void);
#endif /* _SOC_ACPI_H_ */

View File

@ -0,0 +1,20 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_BROADWELL_DE_H_
#define _SOC_BROADWELL_DE_H_
#endif /* _SOC_BROADWELL_DE_H_ */

View File

@ -0,0 +1,66 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_IOMAP_H_
#define _SOC_IOMAP_H_
/*
* Memory Mapped IO bases.
*/
/* PCI Configuration Space */
#define MCFG_BASE_ADDRESS CONFIG_MMCONF_BASE_ADDRESS
#define MCFG_BASE_SIZE 0x10000000
/* Transactions in this range will abort */
#define ABORT_BASE_ADDRESS 0xfeb00000
#define ABORT_BASE_SIZE 0x00010000
/* PSEG */
#define PSEG_BASE_ADDRESS 0xfeb80000
#define PSEG_BASE_SIZE 0x00080000
/* IOxAPIC */
#define IOXAPIC1_BASE_ADDRESS 0xfec00000
#define IOXAPIC1_BASE_SIZE 0x00100000
#define IOXAPIC2_BASE_ADDRESS 0xfec01000
#define IOXAPIC2_BASE_SIZE 0x00100000
/* PCH (HPET/LT/TPM/Others) */
#define PCH_BASE_ADDRESS 0xfed00000
#define PCH_BASE_SIZE 0x00100000
/* Local XAPIC */
#define LXAPIC_BASE_ADDRESS 0xfee00000
#define LXAPIC_BASE_SIZE 0x00100000
/* High Performance Event Timer */
#define HPET_BASE_ADDRESS 0xfed00000
#define HPET_BASE_SIZE 0x400
/* Firmware */
#define FIRMWARE_BASE_ADDRESS 0xff000000
#define FIRMWARE_BASE_SIZE 0x01000000
/*
* IO Port bases.
*/
/* ACPI Base Address */
#define ACPI_BASE_ADDRESS 0x400
#define ACPI_BASE_SIZE 0x80
#endif /* _SOC_IOMAP_H_ */

View File

@ -0,0 +1,88 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_IRQ_H_
#define _SOC_IRQ_H_
#define PIRQA_APIC_IRQ 16
#define PIRQB_APIC_IRQ 17
#define PIRQC_APIC_IRQ 18
#define PIRQD_APIC_IRQ 19
#define PIRQE_APIC_IRQ 20
#define PIRQF_APIC_IRQ 21
#define PIRQG_APIC_IRQ 22
#define PIRQH_APIC_IRQ 23
/* PIC IRQ settings. */
#define PIRQ_PIC_IRQ3 0x3
#define PIRQ_PIC_IRQ4 0x4
#define PIRQ_PIC_IRQ5 0x5
#define PIRQ_PIC_IRQ6 0x6
#define PIRQ_PIC_IRQ7 0x7
#define PIRQ_PIC_IRQ9 0x9
#define PIRQ_PIC_IRQ10 0xa
#define PIRQ_PIC_IRQ11 0xb
#define PIRQ_PIC_IRQ12 0xc
#define PIRQ_PIC_IRQ14 0xe
#define PIRQ_PIC_IRQ15 0xf
#define PIRQ_PIC_IRQDISABLE 0x80
#define PIRQ_PIC_UNKNOWN_UNUSED 0xff
/* Overloaded term, but these values determine the per device route. */
#define PIRQA 0
#define PIRQB 1
#define PIRQC 2
#define PIRQD 3
#define PIRQE 4
#define PIRQF 5
#define PIRQG 6
#define PIRQH 7
/* In each mainboard directory there should exist a header file irqroute.h that
* defines the PCI_DEV_PIRQ_ROUTES and PIRQ_PIC_ROUTES macros which
* consist of PCI_DEV_PIRQ_ROUTE and PIRQ_PIC entries. */
#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
#include <stdint.h>
#define NUM_OF_PCI_DEVS 32
#define NUM_PIRQS 8
struct broadwell_de_irq_route {
/* Per device configuration. */
uint16_t pcidev[NUM_OF_PCI_DEVS];
/* Route path for each internal PIRQx in PIC mode. */
uint8_t pic[NUM_PIRQS];
};
extern const struct broadwell_de_irq_route global_broadwell_de_irq_route;
#define DEFINE_IRQ_ROUTES \
const struct broadwell_de_irq_route global_broadwell_de_irq_route = { \
.pcidev = { PCI_DEV_PIRQ_ROUTES, }, \
.pic = { PIRQ_PIC_ROUTES, }, \
}
#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
[dev_] = ((PIRQ ## d_) << 12) | ((PIRQ ## c_) << 8) | \
((PIRQ ## b_) << 4) | ((PIRQ ## a_) << 0)
#define PIRQ_PIC(pirq_, pic_irq_) \
[PIRQ ## pirq_] = PIRQ_PIC_IRQ ## pic_irq_
#endif /* !defined(__ASSEMBLER__) && !defined(__ACPI__) */
#endif /* _SOC_IRQ_H_ */

View File

@ -0,0 +1,86 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_LPC_H_
#define _SOC_LPC_H_
/* LPC Interface Bridge PCI Configuration Registers */
#define REVID 0x08
#define PIRQ_RCR1 0x60
#define PIRQ_RCR2 0x68
#define GEN_PMCON_1 0xA0
#define GEN_PMCON_2 0xA2
#define GEN_PMCON_3 0xA4
#define RTC_PWR_STS (1 << 2)
/* Default IO range claimed by the LPC device. The upper bound is exclusive. */
#define LPC_DEFAULT_IO_RANGE_LOWER 0
#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
/* IO Mapped registers behind ACPI_BASE_ADDRESS */
#define PM1_STS 0x00
#define WAK_STS (1 << 15)
#define PCIEXPWAK_STS (1 << 14)
#define USB_STS (1 << 13)
#define PRBTNOR_STS (1 << 11)
#define RTC_STS (1 << 10)
#define PWRBTN_STS (1 << 8)
#define GBL_STS (1 << 5)
#define TMROF_STS (1 << 0)
#define PM1_EN 0x02
#define PCIEXPWAK_DIS (1 << 14)
#define RTC_EN (1 << 10)
#define PWRBTN_EN (1 << 8)
#define GBL_EN (1 << 5)
#define TMROF_EN (1 << 0)
#define PM1_CNT 0x04
#define SLP_EN (1 << 13)
#define SLP_TYP_SHIFT 10
#define SLP_TYP (7 << SLP_TYP_SHIFT)
#define SLP_TYP_S0 0
#define SLP_TYP_S1 1
#define SLP_TYP_S3 5
#define SLP_TYP_S4 6
#define SLP_TYP_S5 7
#define GBL_RLS (1 << 2)
#define BM_RLD (1 << 1)
#define SCI_EN (1 << 0)
#define PM1_TMR 0x08
#define GPE0_STS 0x20
#define PCI_EXP_STS (1 << 9)
#define RI_STS (1 << 8)
#define SMB_WAK_STS (1 << 7)
#define TCOSCI_STS (1 << 6)
#define SWGPE_STS (1 << 2)
#define HOT_PLUG_STS (1 << 1)
#define GPE0_EN 0x28
#define SMI_EN 0x30
#define SMI_STS 0x34
#define ALT_GPIO_SMI 0x38
#define UPRWC 0x3c
#define UPRWC_WR_EN (1 << 1) // USB Per-Port Registers Write Enable
#define GPE_CTRL 0x40
#define PM2A_CNT_BLK 0x50
#define TCO_RLD 0x60
#define TCO_STS 0x64
#define SECOND_TO_STS (1 << 17)
#define TCO_TIMEOUT (1 << 3)
#define TCO1_CNT 0x68
#define TCO_LOCK (1 << 12)
#define TCO_TMR_HALT (1 << 11)
#define TCO_TMR 0x70
#endif /* _SOC_LPC_H_ */

View File

@ -0,0 +1,28 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_MSR_H_
#define _SOC_MSR_H_
#define MSR_IA32_PLATFORM_ID 0x17
#define MSR_CORE_THREAD_COUNT 0x35
#define MSR_PLATFORM_INFO 0xce
#define MSR_TURBO_RATIO_LIMIT 0x1ad
#define MSR_IA32_MC0_STATUS 0x400
#define MSR_PKG_POWER_SKU_UNIT 0x606
#define MSR_PKG_POWER_LIMIT 0x610
#endif /* _SOC_MSR_H_ */

View File

@ -0,0 +1,52 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_PATTRS_H_
#define _SOC_PATTRS_H_
#include <stdint.h>
#include <cpu/x86/msr.h>
/*
* The pattrs structure is a common place to stash pertinent information
* about the processor or platform. Instead of going to the source (msrs, cpuid)
* every time an attribute is needed use the pattrs structure.
*/
struct pattrs {
msr_t platform_id;
msr_t platform_info;
uint32_t cpuid;
int revid;
int stepping;
const void *microcode_patch;
int address_bits;
int num_cpus;
};
/*
* This is just to hide the abstraction w/o relying on how the underlying
* storage is allocated.
*/
#define PATTRS_GLOB_NAME __global_pattrs
#define DEFINE_PATTRS struct pattrs PATTRS_GLOB_NAME
extern DEFINE_PATTRS;
static inline const struct pattrs *pattrs_get(void)
{
return &PATTRS_GLOB_NAME;
}
#endif /* _SOC_PATTRS_H_ */

View File

@ -0,0 +1,110 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_PCI_DEVS_H_
#define _SOC_PCI_DEVS_H_
#define BUS0 0
#define SOC_DEV 0
#define SOC_FUNC 0
#define SOC_DEVID 0x2F00
#define SOC_DEVID_ES2 0x6F00
#define SOC_DEV_FUNC DEV_FUNC(SOC_DEV, SOC_FUNC)
#define LPC_DEV 31
#define LPC_FUNC 0
#define LPC_DEVID 0x8C42
#define LPC_DEVID_ES2 0x8C54
#define LPC_DEV_FUNC DEV_FUNC(LPC_DEV, LPC_FUNC)
#define SATA_DEV 31
#define SATA_FUNC 2
#define AHCI_DEVID 0x8C02
#define SATA_DEV_FUNC DEV_FUNC(SATA_DEV, SATA_FUNC)
#define SATA2_DEV 31
#define SATA2_FUNC 5
#define SATA2_DEV_FUNC DEV_FUNC(SATA2_DEV, SATA2_FUNC)
#define EHCI1_DEV 29
#define EHCI1_FUNC 0
#define EHCI1_DEVID 0x8C26
#define EHCI1_DEV_FUNC DEV_FUNC(EHCI_DEV1, EHCI_FUNC1)
#define EHCI2_DEV 26
#define EHCI2_FUNC 0
#define EHCI2_DEVID 0x8C2D
#define EHCI2_DEV_FUNC DEV_FUNC(EHCI_DEV2, EHCI_FUNC2)
#define XHCI_DEV 20
#define XHCI_FUNC 0
#define XHCI_DEVID 0x8C31
#define XHCI_FUS_REG 0xE0
#define XHCI_FUNC_DISABLE (1 << 0)
#define XHCI_USB2PR_REG 0xD0
#define XHCI_DEV_FUNC DEV_FUNC(XHCI_DEV, XHCI_FUNC)
#define GBE_DEV 25
#define GBE_FUNC 0
#define GBE_DEVID 0x8C33
#define GBE_DEV_FUNC DEV_FUNC(GBE_DEV, GBE_FUNC)
#define ME_DEV 22
#define ME_FUNC 0
#define ME_DEVID 0x8C3A
#define ME_DEV_FUNC DEV_FUNC(ME_DEV, ME_FUNC)
#define HDA_DEV 27
#define HDA_FUNC 0
#define HDA_DEVID 0x8C20
#define HDA_DEV_FUNC DEV_FUNC(HDA_DEV, HDA_FUNC)
#define PCIE_DEV 28
#define PCIE_PORT1_DEV PCIE_DEV
#define PCIE_PORT1_FUNC 0
#define PCIE_PORT1_DEVID 0x8C10
#define PCIE_PORT2_DEV PCIE_DEV
#define PCIE_PORT2_FUNC 1
#define PCIE_PORT2_DEVID 0x8C12
#define PCIE_PORT3_DEV PCIE_DEV
#define PCIE_PORT3_FUNC 2
#define PCIE_PORT3_DEVID 0x8C14
#define PCIE_PORT4_DEV PCIE_DEV
#define PCIE_PORT4_FUNC 3
#define PCIE_PORT4_DEVID 0x8C16
#define PCIE_PORT5_DEV PCIE_DEV
#define PCIE_PORT5_FUNC 4
#define PCIE_PORT5_DEVID 0x8C18
#define PCIE_PORT6_DEV PCIE_DEV
#define PCIE_PORT6_FUNC 5
#define PCIE_PORT6_DEVID 0x8C1A
#define PCIE_PORT7_DEV PCIE_DEV
#define PCIE_PORT7_FUNC 6
#define PCIE_PORT7_DEVID 0x8C1C
#define PCIE_PORT8_DEV PCIE_DEV
#define PCIE_PORT8_FUNC 7
#define PCIE_PORT8_DEVID 0x8C1E
#define PCIE_PORT1_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT1_FUNC)
#define PCIE_PORT2_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT2_FUNC)
#define PCIE_PORT3_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT3_FUNC)
#define PCIE_PORT4_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT4_FUNC)
#define PCIE_PORT5_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT5_FUNC)
#define PCIE_PORT6_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT6_FUNC)
#define PCIE_PORT7_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT7_FUNC)
#define PCIE_PORT8_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT8_FUNC)
#endif /* _SOC_PCI_DEVS_H_ */

View File

@ -0,0 +1,30 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_RAMSTAGE_H_
#define _SOC_RAMSTAGE_H_
#include <device/device.h>
/* The broadwell_de_init_pre_device() function is called prior to device
* initialization, but it's after console and cbmem has been reinitialized. */
void broadwell_de_init_pre_device(void);
void broadwell_de_init_cpus(device_t dev);
void southcluster_enable_dev(device_t dev);
extern struct pci_operations soc_pci_ops;
#endif /* _SOC_RAMSTAGE_H_ */

View File

@ -0,0 +1,24 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_RESET_H_
#define _SOC_RESET_H_
#include <reset.h>
void warm_reset(void);
#endif /* _SOC_RESET_H_ */

View File

@ -0,0 +1,35 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_ROMSTAGE_H_
#define _SOC_ROMSTAGE_H_
#if !defined(__PRE_RAM__)
#error "Don't include romstage.h from a ramstage compilation unit!"
#endif
#include <stdint.h>
#include <arch/cpu.h>
#include <fsp.h>
void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr);
#define NUM_ROMSTAGE_TS 4
void early_mainboard_romstage_entry(void);
void late_mainboard_romstage_entry(void);
#endif /* _SOC_ROMSTAGE_H_ */

View File

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <cbmem.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
void *cbmem_top(void)
{
return find_fsp_reserved_mem(*(void **)CBMEM_FSP_HOB_PTR);
}

View File

@ -0,0 +1,156 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <arch/acpi.h>
#include <console/console.h>
#include <cpu/x86/lapic.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
static const int legacy_hole_base_k = 0xa0000 / 1024;
static const int legacy_hole_size_k = 384;
static int add_fixed_resources(struct device *dev, int index)
{
struct resource *resource;
u32 pcie_config_base, pcie_config_size;
pcie_config_base = MCFG_BASE_ADDRESS;
pcie_config_size = MCFG_BASE_SIZE;
printk(BIOS_DEBUG, "Adding PCIe config bar base=0x%08x "
"size=0x%x\n", pcie_config_base, pcie_config_size);
resource = new_resource(dev, index++);
resource->base = (resource_t) pcie_config_base;
resource->size = (resource_t) pcie_config_size;
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
resource = new_resource(dev, index++); /* Local APIC */
resource->base = LAPIC_DEFAULT_BASE;
resource->size = 0x00001000;
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
mmio_resource(dev, index++, legacy_hole_base_k, legacy_hole_size_k);
return index;
}
static void mc_add_dram_resources(device_t dev)
{
u32 fsp_mem_base, fsp_mem_len;
u32 tseg_base, tseg_length;
u32 rsv_base, rsv_length;
u32 tolm;
int index = 0;
uint64_t highmem_size = 0;
fsp_mem_base = GetFspReservedMemory(FspHobListPtr, &fsp_mem_len);
highmem_size = GetUsableHighMemTop(FspHobListPtr) - 0x100000000L;
tseg_base = GetTsegReservedMemory(FspHobListPtr, &tseg_length);
tolm = GetPhysicalLowMemTop(FspHobListPtr);
printk(BIOS_DEBUG, "\n\n");
printk(BIOS_DEBUG, "fsp_mem_base: 0x%.8x\n", fsp_mem_base);
printk(BIOS_DEBUG, "fsp_mem_len: 0x%.8x\n", fsp_mem_len);
printk(BIOS_DEBUG, "tseg_base: 0x%.8x\n", tseg_base);
printk(BIOS_DEBUG, "tseg_len: 0x%.8x\n", tseg_length);
printk(BIOS_DEBUG, "highmem_size: 0x%.8x %.8x\n",
(u32)(highmem_size>>32),
(u32)(highmem_size&0xffffffff));
printk(BIOS_DEBUG, "tolm: 0x%.8x\n", tolm);
printk(BIOS_DEBUG, "Top of system low memory: 0x%08x\n", tolm);
printk(BIOS_DEBUG, "FSP memory location: 0x%x\n (size: %dM)\n",
fsp_mem_base, fsp_mem_len >> 20);
printk(BIOS_DEBUG, "tseg: 0x%08x (size: 0x%.8x)\n",
tseg_base, tseg_length);
/* Report the memory regions. */
ram_resource(dev, index++, 0, legacy_hole_base_k);
ram_resource(dev, index++, legacy_hole_base_k + legacy_hole_size_k,
((fsp_mem_base >> 10) - (legacy_hole_base_k + legacy_hole_size_k)));
/* Mark SMM & FSP regions reserved */
mmio_resource(dev, index++, tseg_base >> 10, tseg_length >> 10);
mmio_resource(dev, index++, fsp_mem_base >> 10, fsp_mem_len >> 10);
/* Reserve MMIO space */
rsv_base = fsp_mem_base + fsp_mem_len;
rsv_length = tseg_base - rsv_base;
if (rsv_length) {
mmio_resource(dev, index++, rsv_base >> 10, rsv_length >> 10);
printk(BIOS_DEBUG, "Reserved MMIO : 0x%08x length 0x%08x\n",
rsv_base, rsv_length);
}
rsv_base = tseg_base + tseg_length;
rsv_length = tolm - rsv_base;
if (rsv_length) {
mmio_resource(dev, index++, rsv_base >> 10, rsv_length >> 10);
printk(BIOS_DEBUG, "Reserved MMIO : 0x%08x length 0x%08x\n",
rsv_base, rsv_length);
}
if (highmem_size) {
ram_resource(dev, index++, 0x100000000 >> 10, highmem_size >> 10);
}
printk(BIOS_INFO, "Available memory above 4GB: %lluM\n",
highmem_size >> 20);
index = add_fixed_resources(dev, index);
}
static void nc_read_resources(device_t dev)
{
/* Call the normal read_resources */
pci_dev_read_resources(dev);
/* Calculate and add DRAM resources. */
mc_add_dram_resources(dev);
}
static void nc_enable(device_t dev)
{
print_fsp_info();
}
static struct device_operations nc_ops = {
.read_resources = nc_read_resources,
.acpi_fill_ssdt_generator = generate_cpu_entries,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = NULL,
.enable = &nc_enable,
.scan_bus = 0,
.ops_pci = &soc_pci_ops,
};
static const struct pci_driver nc_driver __pci_driver = {
.ops = &nc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = SOC_DEVID,
};
static const struct pci_driver nc_driver_es2 __pci_driver = {
.ops = &nc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = SOC_DEVID_ES2,
};

View File

@ -0,0 +1,86 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdlib.h>
#include <arch/cpu.h>
#include <arch/acpi.h>
#include <console/console.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cr.h>
#include <cpu/x86/msr.h>
#include <device/device.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <romstage_handoff.h>
#include <soc/lpc.h>
#include <soc/msr.h>
#include <soc/pattrs.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
/* Global PATTRS */
DEFINE_PATTRS;
#define SHOW_PATTRS 1
static void detect_num_cpus(struct pattrs *attrs)
{
msr_t core_thread_count = rdmsr(MSR_CORE_THREAD_COUNT);
attrs->num_cpus = core_thread_count.lo & 0xffff;
}
static inline void fill_in_msr(msr_t *msr, int idx)
{
*msr = rdmsr(idx);
if (SHOW_PATTRS) {
printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
idx, msr->hi, msr->lo);
}
}
static const char *stepping_str[] = {
"U0", "V1", "V2", "Y0"
};
static void fill_in_pattrs(void)
{
device_t dev;
struct pattrs *attrs = (struct pattrs *)pattrs_get();
attrs->cpuid = cpuid_eax(1);
attrs->stepping = (attrs->cpuid & 0x0F) - 1;
dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
attrs->revid = pci_read_config8(dev, REVID);
attrs->microcode_patch = intel_microcode_find();
attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
detect_num_cpus(attrs);
if (SHOW_PATTRS) {
printk(BIOS_DEBUG, "CPUID: %08x\n", attrs->cpuid);
printk(BIOS_DEBUG, "Cores: %d\n", attrs->num_cpus);
printk(BIOS_DEBUG, "Stepping: %s\n", (attrs->stepping >= ARRAY_SIZE(stepping_str))
? "??" : stepping_str[attrs->stepping]);
printk(BIOS_DEBUG, "Revision ID: %02x\n", attrs->revid);
}
fill_in_msr(&attrs->platform_id, MSR_IA32_PLATFORM_ID);
fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
}
void broadwell_de_init_pre_device(void)
{
fill_in_pattrs();
}

View File

@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <arch/io.h>
#include <soc/reset.h>
void warm_reset(void)
{
outb(0x00, 0xcf9);
outb(0x06, 0xcf9);
}
void hard_reset(void)
{
warm_reset();
}

View File

@ -0,0 +1,3 @@
romstage-y += romstage.c
$(obj)/soc/intel/fsp_broadwell_de/romstage/romstage.romstage.o : $(obj)/build.h

View File

@ -0,0 +1,120 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stddef.h>
#include <arch/cpu.h>
#include <lib.h>
#include <arch/io.h>
#include <arch/cbfs.h>
#include <arch/stages.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
#include <romstage_handoff.h>
#include <timestamp.h>
#include <version.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
#include <pc80/mc146818rtc.h>
#include <soc/iomap.h>
#include <soc/lpc.h>
#include <soc/pci_devs.h>
#include <soc/romstage.h>
#include <build.h>
static void init_rtc(void)
{
u16 gen_pmcon3 = pci_read_config16(PCI_DEV(0, LPC_DEV, LPC_FUNC), GEN_PMCON_3);
if (gen_pmcon3 & RTC_PWR_STS) {
printk(BIOS_DEBUG, "RTC Failure detected. Resetting Date to %s\n",
coreboot_dmi_date);
}
cmos_init(gen_pmcon3 & RTC_PWR_STS);
}
/* Entry from cache-as-ram.inc. */
void *asmlinkage main(FSP_INFO_HEADER *fsp_info_header)
{
post_code(0x40);
console_init();
init_rtc();
post_code(0x41);
timestamp_init(get_initial_timestamp());
timestamp_add_now(TS_START_ROMSTAGE);
/* Call into mainboard. */
early_mainboard_romstage_entry();
/*
* Call early init to initialize memory and chipset. This function returns
* to the romstage_main_continue function with a pointer to the HOB
* structure.
*/
post_code(0x48);
timestamp_add_now(TS_BEFORE_INITRAM);
printk(BIOS_DEBUG, "Starting the Intel FSP (early_init)\n");
fsp_early_init(fsp_info_header);
die("Uh Oh! fsp_early_init should not return here.\n");
}
/*******************************************************************************
* The FSP early_init function returns to this function.
* Memory is setup and the stack is set by the FSP.
*/
void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr)
{
int cbmem_was_initted;
void *cbmem_hob_ptr;
post_code(0x4a);
timestamp_add_now(TS_AFTER_INITRAM);
printk(BIOS_DEBUG, "%s status: %x hob_list_ptr: %x\n",
__func__, (u32) status, (u32) hob_list_ptr);
#if IS_ENABLED(CONFIG_USBDEBUG_IN_ROMSTAGE)
/* FSP reconfigures USB, so reinit it to have debug */
usbdebug_init();
#endif /* IS_ENABLED(CONFIG_USBDEBUG_IN_ROMSTAGE) */
printk(BIOS_DEBUG, "FSP Status: 0x%0x\n", (u32)status);
post_code(0x4b);
late_mainboard_romstage_entry();
post_code(0x4c);
quick_ram_check();
post_code(0x4d);
cbmem_was_initted = !cbmem_recovery(0);
/* Save the HOB pointer in CBMEM to be used in ramstage*/
cbmem_hob_ptr = cbmem_add (CBMEM_ID_HOB_POINTER, sizeof(*hob_list_ptr));
if (cbmem_hob_ptr == NULL) {
printk(BIOS_DEBUG, "Failed to save HOB pointer in CBMEM.\n");
return;
}
*(u32 *)cbmem_hob_ptr = (u32)hob_list_ptr;
/* Load the ramstage. */
post_code(0x4e);
copy_and_run();
while (1);
}
uint64_t get_initial_timestamp(void)
{
return 0;
}

View File

@ -0,0 +1,267 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdint.h>
#include <arch/io.h>
#include <arch/ioapic.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_def.h>
#include <pc80/mc146818rtc.h>
#include <pc80/i8254.h>
#include <pc80/i8259.h>
#include <pc80/isa-dma.h>
#include <romstage_handoff.h>
#include <soc/iomap.h>
#include <soc/irq.h>
#include <soc/lpc.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
#include <chip.h>
typedef struct soc_intel_fsp_broadwell_de_config config_t;
static inline void
add_mmio_resource(device_t dev, int i, unsigned long addr, unsigned long size)
{
mmio_resource(dev, i, addr >> 10, size >> 10);
}
static void sc_add_mmio_resources(device_t dev)
{
add_mmio_resource(dev, 0xfeb0,
ABORT_BASE_ADDRESS,
ABORT_BASE_SIZE);
add_mmio_resource(dev, 0xfeb8,
PSEG_BASE_ADDRESS,
PSEG_BASE_SIZE);
add_mmio_resource(dev, 0xfec0,
IOXAPIC1_BASE_ADDRESS,
IOXAPIC1_BASE_SIZE);
add_mmio_resource(dev, 0xfec1,
IOXAPIC2_BASE_ADDRESS,
IOXAPIC2_BASE_SIZE);
add_mmio_resource(dev, 0xfed0,
PCH_BASE_ADDRESS,
PCH_BASE_SIZE);
add_mmio_resource(dev, 0xfee0,
LXAPIC_BASE_ADDRESS,
LXAPIC_BASE_SIZE);
add_mmio_resource(dev, 0xff00,
FIRMWARE_BASE_ADDRESS,
FIRMWARE_BASE_SIZE);
}
/*
* Write PCI config space IRQ assignments. PCI devices have the INT_LINE
* (0x3C) and INT_PIN (0x3D) registers which report interrupt routing
* information to operating systems and drivers. The INT_PIN register is
* generally read only and reports which interrupt pin A - D it uses. The
* INT_LINE register is configurable and reports which IRQ (generally the
* PIC IRQs 1 - 15) it will use. This needs to take interrupt pin swizzling
* on devices that are downstream on a PCI bridge into account.
*
* This function will loop through all enabled PCI devices and program the
* INT_LINE register with the correct PIC IRQ number for the INT_PIN that it
* uses. It then configures each interrupt in the pic to be level triggered.
*/
static void write_pci_config_irqs(void)
{
device_t irq_dev;
device_t targ_dev;
uint8_t int_line = 0;
uint8_t original_int_pin = 0;
uint8_t new_int_pin = 0;
uint16_t current_bdf = 0;
uint16_t parent_bdf = 0;
uint8_t pirq = 0;
uint8_t device_num = 0;
const struct broadwell_de_irq_route *ir = &global_broadwell_de_irq_route;
if (ir == NULL) {
printk(BIOS_WARNING, "Warning: Can't write PCI IRQ assignments because"
" 'global_broadwell_de_irq_route' structure does not exist\n");
return;
}
/*
* Loop through all enabled devices and program their
* INT_LINE, INT_PIN registers from values taken from
* the Interrupt Route registers in the ILB
*/
printk(BIOS_DEBUG, "PCI_CFG IRQ: Write PCI config space IRQ assignments\n");
for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
if ((irq_dev->path.type != DEVICE_PATH_PCI) ||
(!irq_dev->enabled))
continue;
current_bdf = irq_dev->path.pci.devfn |
irq_dev->bus->secondary << 8;
/*
* Step 1: Get the INT_PIN and device structure to look for
* in the pirq_data table defined in the mainboard directory.
*/
targ_dev = NULL;
new_int_pin = get_pci_irq_pins(irq_dev, &targ_dev);
if (targ_dev == NULL || new_int_pin < 1)
continue;
/* Get the original INT_PIN for record keeping */
original_int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
parent_bdf = targ_dev->path.pci.devfn
| targ_dev->bus->secondary << 8;
device_num = PCI_SLOT(parent_bdf);
if (ir->pcidev[device_num] == 0) {
printk(BIOS_WARNING,
"Warning: PCI Device %d does not have an IRQ entry, skipping it\n",
device_num);
continue;
}
/* Find the PIRQ that is attached to the INT_PIN this device uses */
pirq = (ir->pcidev[device_num] >> ((new_int_pin - 1) * 4)) & 0xF;
/* Get the INT_LINE this device/function will use */
int_line = ir->pic[pirq];
if (int_line != PIRQ_PIC_IRQDISABLE) {
/* Set this IRQ to level triggered since it is used by a PCI device */
i8259_configure_irq_trigger(int_line, IRQ_LEVEL_TRIGGERED);
/* Set the Interrupt Line register in PCI config space */
pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
} else {
/* Set the Interrupt line register as "unknown or unused" */
pci_write_config8(irq_dev, PCI_INTERRUPT_LINE,
PIRQ_PIC_UNKNOWN_UNUSED);
}
printk(BIOS_SPEW, "\tINT_PIN\t\t: %d (%s)\n",
original_int_pin, pin_to_str(original_int_pin));
if (parent_bdf != current_bdf)
printk(BIOS_SPEW, "\tSwizzled to\t: %d (%s)\n",
new_int_pin, pin_to_str(new_int_pin));
printk(BIOS_SPEW, "\tPIRQ\t\t: %c\n"
"\tINT_LINE\t: 0x%X (IRQ %d)\n",
'A' + pirq, int_line, int_line);
}
printk(BIOS_DEBUG, "PCI_CFG IRQ: Finished writing PCI config space IRQ assignments\n");
}
static void sc_pirq_init(device_t dev)
{
int i;
const uint8_t *pirq = global_broadwell_de_irq_route.pic;
printk(BIOS_DEBUG, "Programming PIRQ[A-H] Routing Control Register\n");
for (i = 0; i < 8; i++) {
pci_write_config8(dev, (i < 4) ? (PIRQ_RCR1+i) : (PIRQ_RCR2+i-4), pirq[i]);
printk(BIOS_DEBUG, " PIRQ[%c]: %.2x\n"
, 'A'+i
, pci_read_config8(dev, (i < 4) ? (PIRQ_RCR1+i) : (PIRQ_RCR2+i-4))
);
}
}
static void sc_add_io_resources(device_t dev)
{
struct resource *res;
u8 io_index = 0;
/*
* Add the default claimed IO range for the LPC device
* and mark it as subtractive decode.
*/
res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
res->base = LPC_DEFAULT_IO_RANGE_LOWER;
res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER;
res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
static void sc_read_resources(device_t dev)
{
pci_dev_read_resources(dev);
sc_add_mmio_resources(dev);
sc_add_io_resources(dev);
}
static void sc_init(struct device *dev)
{
printk(BIOS_DEBUG, "soc: southcluster_init\n");
/* Set the value for PCI command register. */
pci_write_config16(dev, PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
/* Program Serial IRQ register. */
pci_write_config16(dev, 0x64, 0xd0);
sc_pirq_init(dev);
write_pci_config_irqs();
isa_dma_init();
setup_i8259();
setup_i8254();
}
/*
* Common code for the south cluster devices.
*/
void southcluster_enable_dev(device_t dev)
{
uint32_t reg32;
if (!dev->enabled) {
int slot = PCI_SLOT(dev->path.pci.devfn);
int func = PCI_FUNC(dev->path.pci.devfn);
printk(BIOS_DEBUG, "%s: Disabling device: %02x.%01x\n",
dev_path(dev), slot, func);
/* Ensure memory, io, and bus master are all disabled */
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
pci_write_config32(dev, PCI_COMMAND, reg32);
}
}
static struct device_operations device_ops = {
.read_resources = sc_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = NULL,
.init = sc_init,
.enable = southcluster_enable_dev,
.scan_bus = scan_lpc_bus,
.ops_pci = &soc_pci_ops,
};
static const struct pci_driver southcluster __pci_driver = {
.ops = &device_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = LPC_DEVID,
};
static const struct pci_driver southcluster_es2 __pci_driver = {
.ops = &device_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = LPC_DEVID_ES2,
};

View File

@ -0,0 +1,633 @@
/*
* Copyright (c) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but without any warranty; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/* This file is derived from the flashrom project. */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <delay.h>
#include <arch/io.h>
#include <console/console.h>
#include <device/pci_ids.h>
#include <spi_flash.h>
#include <spi-generic.h>
#ifdef __SMM__
#define pci_read_config_byte(dev, reg, targ)\
*(targ) = pci_read_config8(dev, reg)
#define pci_read_config_word(dev, reg, targ)\
*(targ) = pci_read_config16(dev, reg)
#define pci_read_config_dword(dev, reg, targ)\
*(targ) = pci_read_config32(dev, reg)
#define pci_write_config_byte(dev, reg, val)\
pci_write_config8(dev, reg, val)
#define pci_write_config_word(dev, reg, val)\
pci_write_config16(dev, reg, val)
#define pci_write_config_dword(dev, reg, val)\
pci_write_config32(dev, reg, val)
#else /* !__SMM__ */
#include <device/device.h>
#include <device/pci.h>
#define pci_read_config_byte(dev, reg, targ)\
*(targ) = pci_read_config8(dev, reg)
#define pci_read_config_word(dev, reg, targ)\
*(targ) = pci_read_config16(dev, reg)
#define pci_read_config_dword(dev, reg, targ)\
*(targ) = pci_read_config32(dev, reg)
#define pci_write_config_byte(dev, reg, val)\
pci_write_config8(dev, reg, val)
#define pci_write_config_word(dev, reg, val)\
pci_write_config16(dev, reg, val)
#define pci_write_config_dword(dev, reg, val)\
pci_write_config32(dev, reg, val)
#endif /* !__SMM__ */
typedef struct spi_slave ich_spi_slave;
static int ichspi_lock = 0;
typedef struct ich9_spi_regs {
uint32_t bfpr;
uint16_t hsfs;
uint16_t hsfc;
uint32_t faddr;
uint32_t _reserved0;
uint32_t fdata[16];
uint32_t frap;
uint32_t freg[5];
uint32_t _reserved1[3];
uint32_t pr[5];
uint32_t _reserved2[2];
uint8_t ssfs;
uint8_t ssfc[3];
uint16_t preop;
uint16_t optype;
uint8_t opmenu[8];
uint32_t bbar;
uint8_t _reserved3[12];
uint32_t fdoc;
uint32_t fdod;
uint8_t _reserved4[8];
uint32_t afc;
uint32_t lvscc;
uint32_t uvscc;
uint8_t _reserved5[4];
uint32_t fpb;
uint8_t _reserved6[28];
uint32_t srdl;
uint32_t srdc;
uint32_t srd;
} __attribute__((packed)) ich9_spi_regs;
typedef struct ich_spi_controller {
int locked;
uint8_t *opmenu;
int menubytes;
uint16_t *preop;
uint16_t *optype;
uint32_t *addr;
uint8_t *data;
unsigned databytes;
uint8_t *status;
uint16_t *control;
uint32_t *bbar;
} ich_spi_controller;
static ich_spi_controller cntlr;
enum {
SPIS_SCIP = 0x0001,
SPIS_GRANT = 0x0002,
SPIS_CDS = 0x0004,
SPIS_FCERR = 0x0008,
SSFS_AEL = 0x0010,
SPIS_LOCK = 0x8000,
SPIS_RESERVED_MASK = 0x7ff0,
SSFS_RESERVED_MASK = 0x7fe2
};
enum {
SPIC_SCGO = 0x000002,
SPIC_ACS = 0x000004,
SPIC_SPOP = 0x000008,
SPIC_DBC = 0x003f00,
SPIC_DS = 0x004000,
SPIC_SME = 0x008000,
SSFC_SCF_MASK = 0x070000,
SSFC_RESERVED = 0xf80000
};
enum {
HSFS_FDONE = 0x0001,
HSFS_FCERR = 0x0002,
HSFS_AEL = 0x0004,
HSFS_BERASE_MASK = 0x0018,
HSFS_BERASE_SHIFT = 3,
HSFS_SCIP = 0x0020,
HSFS_FDOPSS = 0x2000,
HSFS_FDV = 0x4000,
HSFS_FLOCKDN = 0x8000
};
enum {
HSFC_FGO = 0x0001,
HSFC_FCYCLE_MASK = 0x0006,
HSFC_FCYCLE_SHIFT = 1,
HSFC_FDBC_MASK = 0x3f00,
HSFC_FDBC_SHIFT = 8,
HSFC_FSMIE = 0x8000
};
enum {
SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0,
SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1,
SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2,
SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3
};
#if IS_ENABLED(CONFIG_DEBUG_SPI_FLASH)
static u8 readb_(const void *addr)
{
u8 v = read8(addr);
printk(BIOS_DEBUG, "read %2.2x from %4.4x\n",
v, ((unsigned) addr & 0xffff) - 0xf020);
return v;
}
static u16 readw_(const void *addr)
{
u16 v = read16(addr);
printk(BIOS_DEBUG, "read %4.4x from %4.4x\n",
v, ((unsigned) addr & 0xffff) - 0xf020);
return v;
}
static u32 readl_(const void *addr)
{
u32 v = read32(addr);
printk(BIOS_DEBUG, "read %8.8x from %4.4x\n",
v, ((unsigned) addr & 0xffff) - 0xf020);
return v;
}
static void writeb_(u8 b, const void *addr)
{
write8(addr, b);
printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n",
b, ((unsigned) addr & 0xffff) - 0xf020);
}
static void writew_(u16 b, const void *addr)
{
write16(addr, b);
printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n",
b, ((unsigned) addr & 0xffff) - 0xf020);
}
static void writel_(u32 b, const void *addr)
{
write32(addr, b);
printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n",
b, ((unsigned) addr & 0xffff) - 0xf020);
}
#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */
#define readb_(a) read8(a)
#define readw_(a) read16(a)
#define readl_(a) read32(a)
#define writeb_(val, addr) write8(addr, val)
#define writew_(val, addr) write16(addr, val)
#define writel_(val, addr) write32(addr, val)
#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */
static void write_reg(const void *value, void *dest, uint32_t size)
{
const uint8_t *bvalue = value;
uint8_t *bdest = dest;
while (size >= 4) {
writel_(*(const uint32_t *)bvalue, bdest);
bdest += 4; bvalue += 4; size -= 4;
}
while (size) {
writeb_(*bvalue, bdest);
bdest++; bvalue++; size--;
}
}
static void read_reg(const void *src, void *value, uint32_t size)
{
const uint8_t *bsrc = src;
uint8_t *bvalue = value;
while (size >= 4) {
*(uint32_t *)bvalue = readl_(bsrc);
bsrc += 4; bvalue += 4; size -= 4;
}
while (size) {
*bvalue = readb_(bsrc);
bsrc++; bvalue++; size--;
}
}
static void ich_set_bbar(uint32_t minaddr)
{
const uint32_t bbar_mask = 0x00ffff00;
uint32_t ichspi_bbar;
minaddr &= bbar_mask;
ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask;
ichspi_bbar |= minaddr;
writel_(ichspi_bbar, cntlr.bbar);
}
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
{
ich_spi_slave *slave = malloc(sizeof(*slave));
if (!slave) {
printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
return NULL;
}
memset(slave, 0, sizeof(*slave));
slave->bus = bus;
slave->cs = cs;
return slave;
}
void spi_init(void)
{
uint8_t *rcrb; /* Root Complex Register Block */
uint32_t rcba; /* Root Complex Base Address */
uint8_t bios_cntl;
device_t dev;
ich9_spi_regs *ich9_spi;
#ifdef __SMM__
dev = PCI_DEV(0, 31, 0);
#else
dev = dev_find_slot(0, PCI_DEVFN(31, 0));
#endif
pci_read_config_dword(dev, 0xf0, &rcba);
/* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
rcrb = (uint8_t *)(rcba & 0xffffc000);
ich9_spi = (ich9_spi_regs *)(rcrb + 0x3800);
ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN;
cntlr.opmenu = ich9_spi->opmenu;
cntlr.menubytes = sizeof(ich9_spi->opmenu);
cntlr.optype = &ich9_spi->optype;
cntlr.addr = &ich9_spi->faddr;
cntlr.data = (uint8_t *)ich9_spi->fdata;
cntlr.databytes = sizeof(ich9_spi->fdata);
cntlr.status = &ich9_spi->ssfs;
cntlr.control = (uint16_t *)ich9_spi->ssfc;
cntlr.bbar = &ich9_spi->bbar;
cntlr.preop = &ich9_spi->preop;
ich_set_bbar(0);
/* Disable the BIOS write protect so write commands are allowed. */
pci_read_config_byte(dev, 0xdc, &bios_cntl);
bios_cntl &= ~(1 << 5);
pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1);
}
int spi_claim_bus(struct spi_slave *slave)
{
/* Handled by ICH automatically. */
return 0;
}
void spi_release_bus(struct spi_slave *slave)
{
/* Handled by ICH automatically. */
}
typedef struct spi_transaction {
const uint8_t *out;
uint32_t bytesout;
uint8_t *in;
uint32_t bytesin;
uint8_t type;
uint8_t opcode;
uint32_t offset;
} spi_transaction;
static inline void spi_use_out(spi_transaction *trans, unsigned bytes)
{
trans->out += bytes;
trans->bytesout -= bytes;
}
static inline void spi_use_in(spi_transaction *trans, unsigned bytes)
{
trans->in += bytes;
trans->bytesin -= bytes;
}
static void spi_setup_type(spi_transaction *trans)
{
trans->type = 0xFF;
/* Try to guess spi type from read/write sizes. */
if (trans->bytesin == 0) {
if (trans->bytesout > 4)
/*
* If bytesin = 0 and bytesout > 4, we presume this is
* a write data operation, which is accompanied by an
* address.
*/
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
else
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
return;
}
if (trans->bytesout == 1) { /* and bytesin is > 0 */
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
return;
}
if (trans->bytesout == 4) { /* and bytesin is > 0 */
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
}
/* Fast read command is called with 5 bytes instead of 4 */
if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
--trans->bytesout;
}
}
static int spi_setup_opcode(spi_transaction *trans)
{
uint16_t optypes;
uint8_t opmenu[cntlr.menubytes];
trans->opcode = trans->out[0];
spi_use_out(trans, 1);
if (!ichspi_lock) {
/* The lock is off, so just use index 0. */
writeb_(trans->opcode, cntlr.opmenu);
optypes = readw_(cntlr.optype);
optypes = (optypes & 0xfffc) | (trans->type & 0x3);
writew_(optypes, cntlr.optype);
return 0;
} else {
/* The lock is on. See if what we need is on the menu. */
uint8_t optype;
uint16_t opcode_index;
/* Write Enable is handled as atomic prefix */
if (trans->opcode == SPI_OPCODE_WREN)
return 0;
read_reg(cntlr.opmenu, opmenu, sizeof(opmenu));
for (opcode_index = 0; opcode_index < cntlr.menubytes;
opcode_index++) {
if (opmenu[opcode_index] == trans->opcode)
break;
}
if (opcode_index == cntlr.menubytes) {
printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n",
trans->opcode);
return -1;
}
optypes = readw_(cntlr.optype);
optype = (optypes >> (opcode_index * 2)) & 0x3;
if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
trans->bytesout >= 3) {
/* We guessed wrong earlier. Fix it up. */
trans->type = optype;
}
if (optype != trans->type) {
printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n",
optype);
return -1;
}
return opcode_index;
}
}
static int spi_setup_offset(spi_transaction *trans)
{
/* Separate the SPI address and data. */
switch (trans->type) {
case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
return 0;
case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
trans->offset = ((uint32_t)trans->out[0] << 16) |
((uint32_t)trans->out[1] << 8) |
((uint32_t)trans->out[2] << 0);
spi_use_out(trans, 3);
return 1;
default:
printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type);
return -1;
}
}
/*
* Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set
* below is True) or 0. In case the wait was for the bit(s) to set - write
* those bits back, which would cause resetting them.
*
* Return the last read status value on success or -1 on failure.
*/
static int ich_status_poll(u16 bitmask, int wait_til_set)
{
int timeout = 40000; /* This will result in 400 ms */
u16 status = 0;
while (timeout--) {
status = readw_(cntlr.status);
if (wait_til_set ^ ((status & bitmask) == 0)) {
if (wait_til_set)
writew_((status & bitmask), cntlr.status);
return status;
}
udelay(10);
}
printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n",
status, bitmask);
return -1;
}
unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
{
return min(cntlr.databytes, buf_len);
}
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bytesout, void *din, unsigned int bytesin)
{
uint16_t control;
int16_t opcode_index;
int with_address;
int status;
spi_transaction trans = {
dout, bytesout,
din, bytesin,
0xff, 0xff, 0
};
/* There has to always at least be an opcode. */
if (!bytesout || !dout) {
printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n");
return -1;
}
/* Make sure if we read something we have a place to put it. */
if (bytesin != 0 && !din) {
printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n");
return -1;
}
if (ich_status_poll(SPIS_SCIP, 0) == -1)
return -1;
writew_(SPIS_CDS | SPIS_FCERR, cntlr.status);
spi_setup_type(&trans);
opcode_index = spi_setup_opcode(&trans);
if (opcode_index < 0)
return -1;
with_address = spi_setup_offset(&trans);
if (with_address < 0)
return -1;
if (!ichspi_lock && trans.opcode == SPI_OPCODE_WREN) {
/*
* Treat Write Enable as Atomic Pre-Op if possible
* in order to prevent the Management Engine from
* issuing a transaction between WREN and DATA.
*/
writew_(trans.opcode, cntlr.preop);
return 0;
}
/* Preset control fields */
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
/* Issue atomic preop cycle if needed */
if (readw_(cntlr.preop))
control |= SPIC_ACS;
if (!trans.bytesout && !trans.bytesin) {
/* SPI addresses are 24 bit only */
if (with_address)
writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
/*
* This is a 'no data' command (like Write Enable), its
* bitesout size was 1, decremented to zero while executing
* spi_setup_opcode() above. Tell the chip to send the
* command.
*/
writew_(control, cntlr.control);
/* wait for the result */
status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
if (status == -1)
return -1;
if (status & SPIS_FCERR) {
printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n");
return -1;
}
goto spi_xfer_exit;
}
/*
* Check if this is a write command attempting to transfer more bytes
* than the controller can handle. Iterations for writes are not
* supported here because each SPI write command needs to be preceded
* and followed by other SPI commands, and this sequence is controlled
* by the SPI chip driver.
*/
if (trans.bytesout > cntlr.databytes) {
printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
" spi_crop_chunk()?\n");
return -1;
}
/*
* Read or write up to databytes bytes at a time until everything has
* been sent.
*/
while (trans.bytesout || trans.bytesin) {
uint32_t data_length;
/* SPI addresses are 24 bit only */
writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
if (trans.bytesout)
data_length = min(trans.bytesout, cntlr.databytes);
else
data_length = min(trans.bytesin, cntlr.databytes);
/* Program data into FDATA0 to N */
if (trans.bytesout) {
write_reg(trans.out, cntlr.data, data_length);
spi_use_out(&trans, data_length);
if (with_address)
trans.offset += data_length;
}
/* Add proper control fields' values */
control &= ~((cntlr.databytes - 1) << 8);
control |= SPIC_DS;
control |= (data_length - 1) << 8;
/* write it */
writew_(control, cntlr.control);
/* Wait for Cycle Done Status or Flash Cycle Error. */
status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
if (status == -1)
return -1;
if (status & SPIS_FCERR) {
printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n");
return -1;
}
if (trans.bytesin) {
read_reg(cntlr.data, trans.in, data_length);
spi_use_in(&trans, data_length);
if (with_address)
trans.offset += data_length;
}
}
spi_xfer_exit:
/* Clear atomic preop now that xfer is done */
writew_(0, cntlr.preop);
return 0;
}

View File

@ -0,0 +1,112 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2003 Eric Biederman
* Copyright (C) 2006-2010 coresystems GmbH
* Copyright (C) 2015-2016 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <rules.h>
#include <stdlib.h>
#include <arch/io.h>
#include <console/uart.h>
#include <trace.h>
#include <drivers/uart/uart8250reg.h>
#ifndef __ROMCC__
#include <boot/coreboot_tables.h>
#endif
/* Expected character delay at 1200bps is 9ms for a working UART
* and no flow-control. Assume UART as stuck if shift register
* or FIFO takes more than 50ms per character to appear empty.
*
* Estimated that inb() from UART takes 1 microsecond.
*/
#define SINGLE_CHAR_TIMEOUT (50 * 1000)
#define FIFO_TIMEOUT (16 * SINGLE_CHAR_TIMEOUT)
static int uart8250_can_tx_byte(unsigned base_port)
{
return inb(base_port + UART8250_LSR) & UART8250_LSR_THRE;
}
static void uart8250_tx_byte(unsigned base_port, unsigned char data)
{
unsigned long int i = SINGLE_CHAR_TIMEOUT;
while (i-- && !uart8250_can_tx_byte(base_port));
outb(data, base_port + UART8250_TBR);
}
static void uart8250_tx_flush(unsigned base_port)
{
unsigned long int i = FIFO_TIMEOUT;
while (i-- && !(inb(base_port + UART8250_LSR) & UART8250_LSR_TEMT));
}
static int uart8250_can_rx_byte(unsigned base_port)
{
return inb(base_port + UART8250_LSR) & UART8250_LSR_DR;
}
static unsigned char uart8250_rx_byte(unsigned base_port)
{
unsigned long int i = SINGLE_CHAR_TIMEOUT;
while (i-- && !uart8250_can_rx_byte(base_port));
if (i)
return inb(base_port + UART8250_RBR);
else
return 0x0;
}
static const unsigned bases[] = { 0x3f8, 0x2f8 };
uintptr_t uart_platform_base(int idx)
{
if (idx < ARRAY_SIZE(bases))
return bases[idx];
return 0;
}
void uart_init(int idx)
{
// No needed to configure as setting has been done in BDX-DE FSP
}
void uart_tx_byte(int idx, unsigned char data)
{
uart8250_tx_byte(uart_platform_base(idx), data);
}
unsigned char uart_rx_byte(int idx)
{
return uart8250_rx_byte(uart_platform_base(idx));
}
void uart_tx_flush(int idx)
{
uart8250_tx_flush(uart_platform_base(idx));
}
#if ENV_RAMSTAGE
void uart_fill_lb(void *data)
{
struct lb_serial serial;
serial.type = LB_SERIAL_TYPE_IO_MAPPED;
serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
serial.baud = default_baudrate();
lb_add_serial(&serial, data);
lb_add_console(LB_TAG_CONSOLE_SERIAL8250, data);
}
#endif