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:
parent
cd9aec6fb0
commit
d7cba288e4
|
@ -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
|
|
@ -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)
|
|
@ -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;
|
||||||
|
}
|
|
@ -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"
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -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}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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"
|
|
@ -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();
|
||||||
|
}
|
|
@ -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,
|
||||||
|
};
|
|
@ -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_ */
|
|
@ -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,
|
||||||
|
};
|
|
@ -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.
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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);
|
||||||
|
}
|
|
@ -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,
|
||||||
|
};
|
|
@ -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();
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
romstage-y += romstage.c
|
||||||
|
|
||||||
|
$(obj)/soc/intel/fsp_broadwell_de/romstage/romstage.romstage.o : $(obj)/build.h
|
|
@ -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;
|
||||||
|
}
|
|
@ -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,
|
||||||
|
};
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue