diff --git a/src/northbridge/intel/Kconfig b/src/northbridge/intel/Kconfig index b9ee5c69fd..001e875df7 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 f1c25405c8..4fb91e8964 100644 --- a/src/northbridge/intel/Makefile.inc +++ b/src/northbridge/intel/Makefile.inc @@ -19,3 +19,4 @@ subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE) += 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 0000000000..c1353ca165 --- /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 0000000000..d9955fec17 --- /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 0000000000..895f5b4861 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#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 0000000000..5cefaeb939 --- /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 + +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 0000000000..6a8c2e07a7 --- /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 0000000000..24609a107e --- /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 + +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 0000000000..82ecedaf7b --- /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 0000000000..05620aedcc --- /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 0000000000..bd196a5059 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../chip.h" + +#ifdef __PRE_RAM__ +#include +#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 0000000000..3057865b89 --- /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 +#include +#include +#include +#include +#include +#include +#include + +#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 0000000000..98c0b9c353 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "chip.h" +#include "northbridge.h" +#include +#include + +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 0000000000..855a056789 --- /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 0000000000..508630e86c --- /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 +#include +#include +#include +#include +#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 0000000000..3513c0f33d --- /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 +#include +#include +#include +#include +#include "northbridge.h" +#include + +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 0000000000..bdd9f78211 --- /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 +#include +#include +#include + +/** + * 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))); +}