Martin Roth (gaumless@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6369
-gerrit
commit b4c31939eacfaafe2aa1ae73fc6a86c5dc86a372 Author: Martin Roth gaumless@gmail.com Date: Wed May 21 14:20:38 2014 -0600
northbridge/intel: Add fsp_rangeley northbridge support
This adds the northbridge initialization pieces for Intel's Atom C2000 processor (Formerly Rangeley). It is intended to be used with the Intel Atom C2000 FSP and does not contain all of the pieces that would otherwise be required for initialization.
Not currently supported: S3 suspend/resume CAR memory Migration (No early cbmem console) SMM
Change-Id: I7665212c892d9a08ecf35d7be70d0afe5fd2c77b Signed-off-by: Martin Roth gaumless@gmail.com --- src/northbridge/intel/Kconfig | 1 + src/northbridge/intel/Makefile.inc | 1 + src/northbridge/intel/fsp_rangeley/Kconfig | 92 +++++++ src/northbridge/intel/fsp_rangeley/Makefile.inc | 39 +++ src/northbridge/intel/fsp_rangeley/acpi.c | 66 +++++ .../intel/fsp_rangeley/acpi/hostbridge.asl | 138 ++++++++++ .../intel/fsp_rangeley/acpi/rangeley.asl | 41 +++ src/northbridge/intel/fsp_rangeley/chip.h | 63 +++++ src/northbridge/intel/fsp_rangeley/fsp/Kconfig | 49 ++++ .../intel/fsp_rangeley/fsp/Makefile.inc | 21 ++ .../intel/fsp_rangeley/fsp/chipset_fsp_util.c | 177 ++++++++++++ .../intel/fsp_rangeley/fsp/chipset_fsp_util.h | 52 ++++ src/northbridge/intel/fsp_rangeley/northbridge.c | 302 +++++++++++++++++++++ src/northbridge/intel/fsp_rangeley/northbridge.h | 78 ++++++ src/northbridge/intel/fsp_rangeley/port_access.c | 72 +++++ src/northbridge/intel/fsp_rangeley/raminit.c | 44 +++ src/northbridge/intel/fsp_rangeley/udelay.c | 68 +++++ 17 files changed, 1304 insertions(+)
diff --git a/src/northbridge/intel/Kconfig b/src/northbridge/intel/Kconfig index b9ee5c6..001e875 100644 --- a/src/northbridge/intel/Kconfig +++ b/src/northbridge/intel/Kconfig @@ -16,3 +16,4 @@ source src/northbridge/intel/nehalem/Kconfig source src/northbridge/intel/sandybridge/Kconfig source src/northbridge/intel/haswell/Kconfig source src/northbridge/intel/fsp_sandybridge/Kconfig +source src/northbridge/intel/fsp_rangeley/Kconfig diff --git a/src/northbridge/intel/Makefile.inc b/src/northbridge/intel/Makefile.inc index 808a1b2..b4fdefe 100644 --- a/src/northbridge/intel/Makefile.inc +++ b/src/northbridge/intel/Makefile.inc @@ -18,3 +18,4 @@ subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += sandybridge subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE) += fsp_sandybridge subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_IVYBRIDGE) += fsp_sandybridge +subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_RANGELEY) += fsp_rangeley diff --git a/src/northbridge/intel/fsp_rangeley/Kconfig b/src/northbridge/intel/fsp_rangeley/Kconfig new file mode 100644 index 0000000..c1353ca --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/Kconfig @@ -0,0 +1,92 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2010 Google Inc. +## Copyright (C) 2013 Sage Electronic Engineering, LLC. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +config NORTHBRIDGE_INTEL_FSP_RANGELEY + bool + select CPU_INTEL_FSP_MODEL_406DX + +if NORTHBRIDGE_INTEL_FSP_RANGELEY + +config MMCONF_BASE_ADDRESS + hex + default 0xe0000000 + +choice + prompt "Set TSEG Size" + default SET_TSEG_1MB if SET_DEFAULT_TSEG_1MB + default SET_TSEG_2MB if SET_DEFAULT_TSEG_2MB + default SET_TSEG_4MB if SET_DEFAULT_TSEG_4MB + default SET_TSEG_8MB if SET_DEFAULT_TSEG_8MB + +config SET_TSEG_1MB + bool "1 MB" + help + Set the TSEG area to 1 MB. + +config SET_TSEG_2MB + bool "2 MB" + help + Set the TSEG area to 2 MB. + +config SET_TSEG_4MB + bool "4 MB" + help + Set the TSEG area to 4 MB. + +config SET_TSEG_8MB + bool "8 MB" + help + Set the TSEG area to 8 MB. +endchoice + +config SMM_TSEG_SIZE + hex + default 0x200000 if SET_TSEG_2MB + default 0x400000 if SET_TSEG_4MB + default 0x800000 if SET_TSEG_8MB + default 0x100000 # SET_TSEG_1MB + +config SMM_RESERVED_SIZE + hex + default 0x200000 if SET_TSEG_2MB + default 0x400000 if SET_TSEG_4MB + default 0x800000 if SET_TSEG_8MB + default 0x100000 # SET_TSEG_1MB + +config SET_DEFAULT_TSEG_1MB + bool + default n + +config SET_DEFAULT_TSEG_2MB + bool + default n + +config SET_DEFAULT_TSEG_4MB + bool + default n + +config SET_DEFAULT_TSEG_8MB + bool + default n + +# Rangeley Specific FSP Kconfig +source src/northbridge/intel/fsp_rangeley/fsp/Kconfig + +endif # NORTHBRIDGE_INTEL_FSP_RANGELEY diff --git a/src/northbridge/intel/fsp_rangeley/Makefile.inc b/src/northbridge/intel/fsp_rangeley/Makefile.inc new file mode 100644 index 0000000..d9955fe --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/Makefile.inc @@ -0,0 +1,39 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2010 Google Inc. +# Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +subdirs-y += fsp +ramstage-y += northbridge.c +ramstage-y += raminit.c + +ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c +ramstage-y += port_access.c + +romstage-y += raminit.c +romstage-y += ../../../arch/x86/lib/walkcbfs.S +romstage-y += port_access.c + +smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR) + +CPPFLAGS_common += -I$(src)/northbridge/intel/fsp_rangeley/ +CPPFLAGS_common += -I$(src)/northbridge/intel/fsp_rangeley/fsp + +$(obj)/northbridge/intel/fsp_rangeley/acpi.ramstage.o : $(obj)/build.h diff --git a/src/northbridge/intel/fsp_rangeley/acpi.c b/src/northbridge/intel/fsp_rangeley/acpi.c new file mode 100644 index 0000000..895f5b4 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/acpi.c @@ -0,0 +1,66 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2012 The Chromium OS Authors + * Copyright (C) 2013 Sage Electronic Engineering, LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <types.h> +#include <string.h> +#include <console/console.h> +#include <arch/io.h> +#include <arch/acpi.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <build.h> +#include "northbridge.h" + +unsigned long acpi_fill_mcfg(unsigned long current) +{ + device_t dev; + u32 pciexbar = 0; + u32 pciexbar_reg; + int max_buses; + int pci_dev_id; + + for (pci_dev_id = PCI_DEVICE_ID_RG_MIN; pci_dev_id <= PCI_DEVICE_ID_RG_MAX; pci_dev_id++) { + dev = dev_find_device(PCI_VENDOR_ID_INTEL, pci_dev_id, 0); + if (dev) + break; + } + + if (!dev) + return current; + + pciexbar_reg = sideband_read(B_UNIT, BECREG); + + /* MMCFG not supported or not enabled. */ + if (!(pciexbar_reg & (1 << 0))) + return current; + + /* 256MB ECAM range */ + pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)); + max_buses = 256; + + current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current, + pciexbar, 0x0, 0x0, max_buses - 1); + + return current; +} diff --git a/src/northbridge/intel/fsp_rangeley/acpi/hostbridge.asl b/src/northbridge/intel/fsp_rangeley/acpi/hostbridge.asl new file mode 100644 index 0000000..5cefaeb --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/acpi/hostbridge.asl @@ -0,0 +1,138 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <arch/ioapic.h> + +Name(_HID,EISAID("PNP0A08")) // PCIe +Name(_CID,EISAID("PNP0A03")) // PCI + +Name(_ADR, 0) +Name(_BBN, 0) + +// This is in the SSDT and can be accessed by the DSDT +External (BMBD) + +// Current Resource Settings + +Method (_CRS, 0, Serialized) +{ + Name (MCRS, ResourceTemplate() + { + // Bus Numbers + WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100,,, 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, 0xffff, 0x0000, 0xf300,,, PI01) + + // VGA memory (0xa0000-0xbffff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000a0000, 0x000bffff, 0x00000000, + 0x00020000,,, ASEG) + + // OPROM reserved (0xd0000-0xd3fff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000, + 0x00004000,,, OPR0) + + // OPROM reserved (0xd4000-0xd7fff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000, + 0x00004000,,, OPR1) + + // OPROM reserved (0xd8000-0xdbfff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000, + 0x00004000,,, OPR2) + + // OPROM reserved (0xdc000-0xdffff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000dc000, 0x000dffff, 0x00000000, + 0x00004000,,, OPR3) + + // 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-0xfebfffff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x00000000, 0xfebfffff, 0x00000000, + 0xfec00000,,, PM01) + + // TPM Area (0xfed40000-0xfed44fff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000, + 0x00005000,,, TPMR) + }) // End MCRS + + // Find PCI resource area in MCRS + CreateDwordField(MCRS, PM01._MIN, PMIN) + CreateDwordField(MCRS, PM01._MAX, PMAX) + CreateDwordField(MCRS, PM01._LEN, PLEN) + + // Fix up PCI memory region + // Start with Top of Lower Usable DRAM + Store (BMBD, PMIN) // Memory goes from BMBOUND to 0xfebfffff (PM01 above) + Add(Subtract(PMAX, PMIN), 1, PLEN) // Store Memory Size + + Return (MCRS) +} // End _CRS diff --git a/src/northbridge/intel/fsp_rangeley/acpi/rangeley.asl b/src/northbridge/intel/fsp_rangeley/acpi/rangeley.asl new file mode 100644 index 0000000..6a8c2e0 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/acpi/rangeley.asl @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2013 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "../northbridge.h" +#include "hostbridge.asl" + +/* PCI Device Resource Consumption */ +Device (PDRC) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 1) + + Name (PDRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, DEFAULT_ECBASE, 0x04000000) + }) + + // Current Resource Settings + Method (_CRS, 0, Serialized) + { + Return(PDRS) + } +} diff --git a/src/northbridge/intel/fsp_rangeley/chip.h b/src/northbridge/intel/fsp_rangeley/chip.h new file mode 100644 index 0000000..24609a1 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/chip.h @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FSP_RANGELEY_CHIP_H_ +#define _FSP_RANGELEY_CHIP_H_ + +#include <arch/acpi.h> + +struct northbridge_intel_fsp_rangeley_config { + + /* Set the CPGC exp_loop_cnt field for RMT execution 2^(exp_loop_cnt -1) */ + /* Valid values: 0 - 15 */ + uint8_t MrcRmtCpgcExpLoopCntValue; + /* Set the CPGC num_bursts field for RMT execution 2^(num_bursts -1) */ + /* Valid values: 0 - 15 */ + uint8_t MrcRmtCpgcNumBursts; + /* DIMM SPD SMBus Addresses */ + uint8_t SpdBaseAddress_0_0; + uint8_t SpdBaseAddress_0_1; + uint8_t SpdBaseAddress_1_0; + uint8_t SpdBaseAddress_1_1; + +#define UPD_ENABLE 1 +#define UPD_DISABLE 0 + uint8_t EnableLan; + uint8_t EnableSata2; + uint8_t EnableSata3; + uint8_t EnableIQAT; + uint8_t EnableUsb20; + uint8_t PrintDebugMessages; + uint8_t Fastboot; + uint8_t EccSupport; + uint8_t SpdWriteProtect; + /* Enable = Memory Down, Disable = DIMM */ + uint8_t MemoryDown; + /* Enable the Rank Margin Tool, needs PrintDebugMessages */ + uint8_t MrcRmtSupport; + +#define BIFURCATION_4_4_4_4 0 +#define BIFURCATION_4_4_8 1 +#define BIFURCATION_8_4_4 2 +#define BIFURCATION_8_8 3 +#define BIFURCATION_16 4 + uint8_t Bifurcation; +}; + +#endif diff --git a/src/northbridge/intel/fsp_rangeley/fsp/Kconfig b/src/northbridge/intel/fsp_rangeley/fsp/Kconfig new file mode 100644 index 0000000..82eceda --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/fsp/Kconfig @@ -0,0 +1,49 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2014 Sage Electronic Engineering, LLC. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +config RANGELEY_FSP_SPECIFIC_OPTIONS + def_bool y + select PLATFORM_USES_FSP + select USE_GENERIC_FSP_CAR_INC + select FSP_USES_UPD + select ENABLE_MRC_CACHE #rangeley FSP always needs MRC data + +config FSP_FILE + string + default "../intel/fsp/rangeley/FvFsp.bin" + help + The path and filename of the Intel FSP binary for this platform. + +config FSP_LOC + hex + default 0xfff80000 + 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 Rangeley FSP is built with a preferred base address of 0xFFF80000 + +config DCACHE_RAM_BASE + hex + default 0xfef00000 + +config DCACHE_RAM_SIZE + hex + default 0x4000 diff --git a/src/northbridge/intel/fsp_rangeley/fsp/Makefile.inc b/src/northbridge/intel/fsp_rangeley/fsp/Makefile.inc new file mode 100644 index 0000000..05620ae --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/fsp/Makefile.inc @@ -0,0 +1,21 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2014 Sage Electronic Engineering, LLC. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +ramstage-y += chipset_fsp_util.c +romstage-y += chipset_fsp_util.c diff --git a/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c new file mode 100644 index 0000000..bd196a5 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c @@ -0,0 +1,177 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <types.h> +#include <string.h> +#include <cpu/x86/stack.h> +#include <console/console.h> +#include <bootstate.h> +#include <cbmem.h> +#include <device/device.h> +#include <southbridge/intel/fsp_rangeley/pci_devs.h> +#include <drivers/intel/fsp/fsp_util.h> +#include <fspvpd.h> +#include <fspbootmode.h> +#include <reset.h> +#include "../chip.h" + +#ifdef __PRE_RAM__ +#include <southbridge/intel/fsp_rangeley/romstage.h> +#endif + +#ifdef __PRE_RAM__ + +/* 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 northbridge_intel_fsp_rangeley_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) +{ + ROMSTAGE_CONST struct device *dev; + ROMSTAGE_CONST config_t *config; + printk(BIOS_DEBUG, "Configure Default UPD Data\n"); + + dev = dev_find_slot(0, SOC_DEV_FUNC); + config = dev->chip_info; + + /* Set SPD addresses */ + if(config->SpdBaseAddress_0_0) { + UpdData->PcdSpdBaseAddress_0_0 = config->SpdBaseAddress_0_0; + } + if(config->SpdBaseAddress_0_1) { + UpdData->PcdSpdBaseAddress_0_1 = config->SpdBaseAddress_0_1; + } + if(config->SpdBaseAddress_1_0) { + UpdData->PcdSpdBaseAddress_1_0 = config->SpdBaseAddress_1_0; + } + if(config->SpdBaseAddress_1_1) { + UpdData->PcdSpdBaseAddress_1_1 = config->SpdBaseAddress_1_1; + } + if(config->EccSupport) { + UpdData->PcdEccSupport = config->EccSupport; + } + if(config->PrintDebugMessages) { + UpdData->PcdPrintDebugMessages = config->PrintDebugMessages; + } + if(config->Bifurcation) { + UpdData->PcdBifurcation = config->Bifurcation; + } + if(config->MemoryDown) { + UpdData->PcdMemoryDown = config->MemoryDown; + } + + UpdData->PcdMrcInitTsegSize = CONFIG_SMM_TSEG_SIZE >> 20; + + if(config->MrcRmtCpgcExpLoopCntValue) { + UpdData->PcdMrcRmtCpgcExpLoopCntValue = + config->MrcRmtCpgcExpLoopCntValue; + } + if(config->MrcRmtCpgcNumBursts) { + UpdData->PcdMrcRmtCpgcNumBursts = config->MrcRmtCpgcNumBursts; + } +#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT) + UpdData->PcdFastboot = UPD_ENABLE; +#endif + /* + * Loop through all the SOC devices in the devicetree + * enabling and disabling them as requested. + */ + for (; dev; dev = dev->sibling) { + + if (dev->path.type != DEVICE_PATH_PCI) + continue; + + switch (dev->path.pci.devfn) { + case GBE1_DEV_FUNC: + case GBE2_DEV_FUNC: + case GBE3_DEV_FUNC: + case GBE4_DEV_FUNC: + UpdData->PcdEnableLan |= dev->enabled; + printk(BIOS_DEBUG, "PcdEnableLan %d\n", + UpdData->PcdEnableLan); + break; + case SATA2_DEV_FUNC: + UpdData->PcdEnableSata2 = dev->enabled; + printk(BIOS_DEBUG, "PcdEnableSata2 %d\n", + UpdData->PcdEnableSata2); + break; + case SATA3_DEV_FUNC: + UpdData->PcdEnableSata3 = dev->enabled; + printk(BIOS_DEBUG, "PcdEnableSata3 %d\n", + UpdData->PcdEnableSata3); + break; + case IQAT_DEV_FUNC: + UpdData->PcdEnableIQAT |= dev->enabled; + printk(BIOS_DEBUG, "PcdEnableIQAT %d\n", + UpdData->PcdEnableIQAT); + break; + case USB2_DEV_FUNC: + UpdData->PcdEnableUsb20 = dev->enabled; + printk(BIOS_DEBUG, "PcdEnableUsb20 %d\n", + UpdData->PcdEnableUsb20); + break; + } + } +} + +/* Set up the Rangeley 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; + pFspRtBuffer->Common.BootMode = BOOT_WITH_FULL_CONFIGURATION; + + /* Find the fastboot cache that was saved in the ROM */ + pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache(); + + return; +} + +/* The FSP returns here after the fsp_early_init call */ +void ChipsetFspReturnPoint(EFI_STATUS Status, + VOID *HobListPtr) +{ + if (Status == 0xFFFFFFFF) { + soft_reset(); + } + romstage_main_continue(Status, HobListPtr); +} + +#endif /* __PRE_RAM__ */ diff --git a/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.h b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.h new file mode 100644 index 0000000..3057865 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.h @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CHIPSET_FSP_UTIL_H +#define CHIPSET_FSP_UTIL_H + +#include <fsptypes.h> +#include <fspfv.h> +#include <fspffs.h> +#include <fspapi.h> +#include <fspplatform.h> +#include <fspinfoheader.h> +#include <fsphob.h> +#include <fspvpd.h> + +#define FSP_RESERVE_MEMORY_SIZE 0x200000 + +#define FSP_INFO_HEADER_GUID \ + { \ + 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \ + } + +#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \ + { \ + 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0} \ + } + +/* + *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 Rangeley FSP, the Image Id is "AVN-FSP0". + */ +#define FSP_IMAGE_ID_DWORD0 0x2d4e5641 /* 'AVN-' */ +#define FSP_IMAGE_ID_DWORD1 0x30505346 /* 'FSP0' */ + +#endif /* CHIPSET_FSP_UTIL_H */ diff --git a/src/northbridge/intel/fsp_rangeley/northbridge.c b/src/northbridge/intel/fsp_rangeley/northbridge.c new file mode 100644 index 0000000..98c0b9c --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/northbridge.c @@ -0,0 +1,302 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <console/console.h> +#include <arch/acpi.h> +#include <arch/io.h> +#include <stdint.h> +#include <delay.h> +#include <cpu/intel/fsp_model_406dx/model_406dx.h> +#include <cpu/x86/msr.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <stdlib.h> +#include <string.h> +#include <cpu/cpu.h> +#include <cbmem.h> +#include "chip.h" +#include "northbridge.h" +#include <drivers/intel/fsp/fsp_util.h> +#include <cpu/x86/lapic.h> + +static int bridge_revision_id = -1; + +int bridge_silicon_revision(void) +{ + if (bridge_revision_id < 0) { + uint8_t stepping = cpuid_eax(1) & 0xf; + uint8_t bridge_id = pci_read_config16( + dev_find_slot(0, PCI_DEVFN(0, 0)), + PCI_DEVICE_ID) & 0xf0; + bridge_revision_id = bridge_id | stepping; + } + return bridge_revision_id; +} + +/* Reserve everything between A segment and 1MB: + * + * 0xa0000 - 0xbffff: legacy VGA + * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel) + * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI + */ +static const int legacy_hole_base_k = 0xa0000 / 1024; +static const int legacy_hole_size_k = 384; + +static int get_pcie_bar(u32 *base, u32 *len) +{ + device_t dev; + u32 pciexbar_reg; + + *base = 0; + *len = 0; + + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (!dev) + return 0; + + pciexbar_reg = sideband_read(B_UNIT, BECREG); + + if (!(pciexbar_reg & (1 << 0))) + return 0; + + *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) | + (1 << 28)); + *len = 256 * 1024 * 1024; /* 256MB ECAM range */ + return 1; + +} + +static int add_fixed_resources(struct device *dev, int index) +{ + struct resource *resource; + u32 pcie_config_base, pcie_config_size; + + + if (get_pcie_bar(&pcie_config_base, &pcie_config_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 finalize_dev (device_t dev) +{ + /* + * Notify FSP for PostPciEnumeration. + * Northbridge APIC init should be early and late enough... + */ + printk(BIOS_DEBUG, "FspNotify(EnumInitPhaseAfterPciEnumeration)\n"); + FspNotify(EnumInitPhaseAfterPciEnumeration); + printk(BIOS_DEBUG, "Returned from FspNotify(EnumInitPhaseAfterPciEnumeration)\n"); +} + +static void mc_add_dram_resources(device_t dev) +{ + u32 tomlow, bmbound, bsmmrrl, bsmmrrh; + u64 bmbound_hi; + int index = 0; + + /* + * These are the host memory ranges : + * - 0 -> SMM (SMMRRL) : cacheable + * - SMM -> LOW TOM (BMBOUND) : cacheable WP + * - 4GB -> HIGH TOM (BMBOUND_HI): cacheable + * + */ + + tomlow = bmbound = sideband_read(B_UNIT, BMBOUND); + printk(BIOS_SPEW, "Top of Low Used DRAM (BMBOUND): 0x%08x\n", bmbound); + + bmbound_hi = (u64)(sideband_read(B_UNIT, BMBOUND_HI)) << 4; + printk(BIOS_SPEW, "Top of Upper Used DRAM (BMBOUND_HI): 0x%llx\n", bmbound_hi); + + bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20; + bsmmrrh = ((sideband_read(B_UNIT, BSMMRRH) + 1) << 20) - 1; + if (bsmmrrl) { + tomlow = bsmmrrl; + printk(BIOS_DEBUG, "SMM memory location: 0x%x SMM memory size: 0x%x\n", bsmmrrl, (bsmmrrh - bsmmrrl + 1)); + printk(BIOS_DEBUG, "Subtracting %dM for SMM\n", (bmbound - bsmmrrl) >> 20); + } + tomlow -= FSP_RESERVE_MEMORY_SIZE; + printk(BIOS_SPEW, "Available memory below 4GB: 0x%08x (%dM)\n", tomlow, tomlow >> 20); + + /* 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, + ((tomlow >> 10) - (legacy_hole_base_k + legacy_hole_size_k))); + + mmio_resource(dev, index++, tomlow >> 10, (bmbound - bsmmrrl) >> 10); + + if (bmbound_hi > 0x100000000) { + ram_resource(dev, index++, 0x100000000 >> 10, (bmbound_hi - 0x100000000) >> 10 ); + printk(BIOS_INFO, "Available memory above 4GB: %lluM\n", (bmbound_hi - 0x100000000) >> 20); + } + + index = add_fixed_resources(dev, index); +} + +static void mc_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 pci_domain_set_resources(device_t dev) +{ + /* + * Assign memory resources for PCI devices + */ + mc_add_dram_resources(dev); + + assign_resources(dev->link_list); +} + +static void mc_set_resources(device_t dev) +{ + /* Call the normal set_resources */ + pci_dev_set_resources(dev); +} + +static void intel_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)); + } +} + +static void northbridge_init(struct device *dev) +{ +} + +static void northbridge_enable(device_t dev) +{ +} + +static struct pci_operations intel_pci_ops = { + .set_subsystem = intel_set_subsystem, +}; + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = NULL, + .init = NULL, + .final = finalize_dev, + .scan_bus = pci_domain_scan_bus, + .ops_pci_bus = pci_bus_default_ops, +}; + +static struct device_operations mc_ops = { + .read_resources = mc_read_resources, + .set_resources = mc_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = northbridge_init, + .enable = northbridge_enable, + .scan_bus = 0, + .ops_pci = &intel_pci_ops, +}; + +/* + * The following entries are taken from Intel document number 510524, rev 1.6: + * Rangeley SoC External Design Specification (EDS) + * Section 10.3 PCI Configuration Space + * Table 10-6. PCI Devices and Functions + * + * These are the Device ID values for the item at bus 0, device 0, function 0. + */ +static const unsigned short pci_device_ids[] = { + 0x1f00, 0x1f01, 0x1f02, 0x1f03, + 0x1f04, 0x1f05, 0x1f06, 0x1f07, + 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, + 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, + 0, /* -- END OF LIST -- */ +}; + +static const struct pci_driver mc_driver __pci_driver = { + .ops = &mc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(dev->link_list); +} + + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + +static void enable_dev(device_t dev) +{ + /* 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; + } +} + +static void finalize_chip(void *chip_info) +{ + /* Notify FSP for ReadyToBoot */ + printk(BIOS_DEBUG, "FspNotify(EnumInitPhaseReadyToBoot)\n"); + print_fsp_info(); + FspNotify(EnumInitPhaseReadyToBoot); + printk(BIOS_DEBUG, "Returned from FspNotify(EnumInitPhaseReadyToBoot)\n"); +} + +struct chip_operations northbridge_intel_fsp_rangeley_ops = { + CHIP_NAME("Intel Rangeley Northbridge") + .enable_dev = enable_dev, + .final = finalize_chip, +}; diff --git a/src/northbridge/intel/fsp_rangeley/northbridge.h b/src/northbridge/intel/fsp_rangeley/northbridge.h new file mode 100644 index 0000000..855a056 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/northbridge.h @@ -0,0 +1,78 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 coresystems GmbH + * Copyright (C) 2011 Google Inc. + * Copyright (C) 2013 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __NORTHBRIDGE_INTEL_RANGELEY_NORTHBRIDGE_H__ +#define __NORTHBRIDGE_INTEL_RANGELEY_NORTHBRIDGE_H__ 1 + +#define DEFAULT_ECBASE CONFIG_MMCONF_BASE_ADDRESS + +/* Everything below this line is ignored in the DSDT */ +#ifndef __ACPI__ + +/* Device 0:0.0 PCI configuration space (Host Bridge) */ + +/* SideBand B-UNIT */ +#define B_UNIT 3 + #define BNOCACHE 0x23 + #define BNOCACHECTL 0x24 + #define BMBOUND 0x25 + #define BMBOUND_HI 0x26 + #define BECREG 0x27 + #define BMISC 0x28 + #define BSMMRRL 0x2E + #define BSMMRRH 0x2F + #define BIMR0L 0x80 + #define BIMR0H 0x81 + #define BIMR0RAC 0x82 + #define BIMR0WAC 0x83 + +/* SideBand C-UNIT */ +#define C_UNIT 8 + +/* SideBand D-UNIT */ +#define D_UNIT 1 + +/* SideBand P-UNIT */ +#define P_UNIT 4 + +#ifndef __ASSEMBLER__ +static inline void barrier(void) { asm("" ::: "memory"); } + +#define PCI_DEVICE_ID_RG_MIN 0x1F00 +#define PCI_DEVICE_ID_RG_MAX 0x1F0F +#define SKPAD 0xFC + +int bridge_silicon_revision(void); +void rangeley_late_initialization(void); +u32 sideband_read(int port, int reg); +void sideband_write(int port, int reg, long data); + +/* debugging functions */ +void print_pci_devices(void); +void dump_pci_device(unsigned dev); +void dump_pci_devices(void); +void dump_spd_registers(void); +void dump_mem(unsigned start, unsigned end); +void report_platform_info(void); + +#endif /* #ifndef __ASSEMBLER__ */ +#endif /* #ifndef __ACPI__ */ +#endif /* #ifndef __NORTHBRIDGE_INTEL_RANGELEY_NORTHBRIDGE_H__ */ diff --git a/src/northbridge/intel/fsp_rangeley/port_access.c b/src/northbridge/intel/fsp_rangeley/port_access.c new file mode 100644 index 0000000..508630e --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/port_access.c @@ -0,0 +1,72 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009-2010 iWave Systems + * Copyright (C) 2013 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __PRE_RAM__ +#define __PRE_RAM__ // Use simple device model for this file even in ramstage +#endif + +#include <stdint.h> +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pnp_def.h> +#include <cpu/x86/lapic.h> +#include "northbridge.h" + +/* + * Restricted Access Regions: + * + * MCR - Message Control Register + * 31 24 16 8 4 0 + * ---------------------------------------------------------------------------- + * | | | Target | Write | | + * | Opcode | Port | register | byte | Reserved | + * | | | Address | Enables | | + * ---------------------------------------------------------------------------- + * + * MDR - Message Data Register + * 31 0 + * ---------------------------------------------------------------------------- + * | | + * | Data | + * | | + * ---------------------------------------------------------------------------- + */ + +#define MSG_OPCODE_READ 0x10 << 24 +#define MSG_OPCODE_WRITE 0x11 << 24 + +#define MCR 0xD0 +#define MDR 0xD4 +#define MCRE 0xD8 + +u32 sideband_read(int port, int reg) +{ + pci_write_config32(PCI_DEV(0, 0, 0), MCR, + (MSG_OPCODE_READ | (port << 16) | (reg << 8))); + return pci_read_config32(PCI_DEV(0, 0, 0), MDR); +} + +void sideband_write(int port, int reg, long data) +{ + pci_write_config32(PCI_DEV(0, 0, 0), MDR, data); + pci_write_config32(PCI_DEV(0, 0, 0), MCR, + (MSG_OPCODE_WRITE | (port << 16) | (reg << 8) | (0xF << 4))); + pci_read_config32(PCI_DEV(0, 0, 0), MDR); +} diff --git a/src/northbridge/intel/fsp_rangeley/raminit.c b/src/northbridge/intel/fsp_rangeley/raminit.c new file mode 100644 index 0000000..3513c0f --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/raminit.c @@ -0,0 +1,44 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Google Inc. + * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <console/console.h> +#include <string.h> +#include <arch/io.h> +#include <cbmem.h> +#include <device/pci_def.h> +#include "northbridge.h" +#include <drivers/intel/fsp/fsp_util.h> + +unsigned long get_top_of_ram(void) +{ + /* + * Calculate the top of usable (low) DRAM. + * The FSP's reserved memory sits just below the SMM region, + * allowing calculation of the top of usable memory. + */ + u32 tom = sideband_read(B_UNIT, BMBOUND); + u32 bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20; + if (bsmmrrl) { + tom = bsmmrrl; + } + tom -= FSP_RESERVE_MEMORY_SIZE; + + return (unsigned long) tom; +} diff --git a/src/northbridge/intel/fsp_rangeley/udelay.c b/src/northbridge/intel/fsp_rangeley/udelay.c new file mode 100644 index 0000000..bdd9f78 --- /dev/null +++ b/src/northbridge/intel/fsp_rangeley/udelay.c @@ -0,0 +1,68 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <delay.h> +#include <stdint.h> +#include <cpu/x86/tsc.h> +#include <cpu/x86/msr.h> + +/** + * Intel Rangeley CPUs always run the TSC at BCLK=100MHz + */ + +/* Simple 32- to 64-bit multiplication. Uses 16-bit words to avoid overflow. + * This code is used to prevent use of libgcc's umoddi3. + */ +static inline void multiply_to_tsc(tsc_t *const tsc, const u32 a, const u32 b) +{ + tsc->lo = (a & 0xffff) * (b & 0xffff); + tsc->hi = ((tsc->lo >> 16) + + ((a & 0xffff) * (b >> 16)) + + ((b & 0xffff) * (a >> 16))); + tsc->lo = ((tsc->hi & 0xffff) << 16) | (tsc->lo & 0xffff); + tsc->hi = ((a >> 16) * (b >> 16)) + (tsc->hi >> 16); +} + +void udelay(u32 us) +{ + u32 dword; + tsc_t tsc, tsc1, tscd; + msr_t msr; + u32 fsb = 100, divisor; + u32 d; /* ticks per us */ + + msr = rdmsr(0xce); + divisor = (msr.lo >> 8) & 0xff; + + d = fsb * divisor; + multiply_to_tsc(&tscd, us, d); + + tsc1 = rdtsc(); + dword = tsc1.lo + tscd.lo; + if ((dword < tsc1.lo) || (dword < tscd.lo)) { + tsc1.hi++; + } + tsc1.lo = dword; + tsc1.hi += tscd.hi; + + do { + tsc = rdtsc(); + } while ((tsc.hi < tsc1.hi) + || ((tsc.hi == tsc1.hi) && (tsc.lo <= tsc1.lo))); +}