From bf6b83abe06ff53033e7cd74134972de6791cf26 Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Sun, 11 Oct 2015 10:37:02 +0200 Subject: Revert "Remove sandybridge and ivybridge FSP code path" Please don't remove chipsets and mainboards without discussion and input from the owners. Someone was asking about cougar canyon 2 just a couple of weeks ago - there's obviously still interest. This reverts commit fb50124d22014742b6990a95df87a7a828e891b6. Change-Id: Icd7dcea21fa4a7808b25bb8727020701aeebffc9 Signed-off-by: Martin Roth Signed-off-by: Ronald G. Minnich Reviewed-on: http://review.coreboot.org/12128 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/northbridge/intel/fsp_sandybridge/Kconfig | 46 +++ src/northbridge/intel/fsp_sandybridge/Makefile.inc | 41 +++ src/northbridge/intel/fsp_sandybridge/acpi.c | 212 +++++++++++ .../intel/fsp_sandybridge/acpi/hostbridge.asl | 359 ++++++++++++++++++ .../intel/fsp_sandybridge/acpi/sandybridge.asl | 58 +++ src/northbridge/intel/fsp_sandybridge/chip.h | 45 +++ src/northbridge/intel/fsp_sandybridge/early_init.c | 88 +++++ src/northbridge/intel/fsp_sandybridge/finalize.c | 56 +++ src/northbridge/intel/fsp_sandybridge/fsp/Kconfig | 40 ++ .../intel/fsp_sandybridge/fsp/Makefile.inc | 21 ++ .../intel/fsp_sandybridge/fsp/chipset_fsp_util.c | 113 ++++++ .../intel/fsp_sandybridge/fsp/chipset_fsp_util.h | 68 ++++ src/northbridge/intel/fsp_sandybridge/gma.c | 110 ++++++ src/northbridge/intel/fsp_sandybridge/gma.h | 167 +++++++++ .../intel/fsp_sandybridge/northbridge.c | 407 +++++++++++++++++++++ .../intel/fsp_sandybridge/northbridge.h | 231 ++++++++++++ .../intel/fsp_sandybridge/northbridge_pci_devs.h | 47 +++ src/northbridge/intel/fsp_sandybridge/ram_calc.c | 38 ++ src/northbridge/intel/fsp_sandybridge/raminit.c | 76 ++++ src/northbridge/intel/fsp_sandybridge/raminit.h | 25 ++ .../intel/fsp_sandybridge/report_platform.c | 114 ++++++ src/northbridge/intel/fsp_sandybridge/udelay.c | 55 +++ 22 files changed, 2417 insertions(+) create mode 100644 src/northbridge/intel/fsp_sandybridge/Kconfig create mode 100644 src/northbridge/intel/fsp_sandybridge/Makefile.inc create mode 100644 src/northbridge/intel/fsp_sandybridge/acpi.c create mode 100644 src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl create mode 100644 src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl create mode 100644 src/northbridge/intel/fsp_sandybridge/chip.h create mode 100644 src/northbridge/intel/fsp_sandybridge/early_init.c create mode 100644 src/northbridge/intel/fsp_sandybridge/finalize.c create mode 100644 src/northbridge/intel/fsp_sandybridge/fsp/Kconfig create mode 100644 src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc create mode 100644 src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c create mode 100644 src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h create mode 100644 src/northbridge/intel/fsp_sandybridge/gma.c create mode 100644 src/northbridge/intel/fsp_sandybridge/gma.h create mode 100644 src/northbridge/intel/fsp_sandybridge/northbridge.c create mode 100644 src/northbridge/intel/fsp_sandybridge/northbridge.h create mode 100644 src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h create mode 100644 src/northbridge/intel/fsp_sandybridge/ram_calc.c create mode 100644 src/northbridge/intel/fsp_sandybridge/raminit.c create mode 100644 src/northbridge/intel/fsp_sandybridge/raminit.h create mode 100644 src/northbridge/intel/fsp_sandybridge/report_platform.c create mode 100644 src/northbridge/intel/fsp_sandybridge/udelay.c (limited to 'src/northbridge/intel/fsp_sandybridge') diff --git a/src/northbridge/intel/fsp_sandybridge/Kconfig b/src/northbridge/intel/fsp_sandybridge/Kconfig new file mode 100644 index 0000000000..e1f2e888fd --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/Kconfig @@ -0,0 +1,46 @@ +## +## 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. +## + +config NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE + bool + select CPU_INTEL_FSP_MODEL_206AX + select INTEL_GMA_ACPI + +config NORTHBRIDGE_INTEL_FSP_IVYBRIDGE + bool + select CPU_INTEL_FSP_MODEL_306AX + select INTEL_GMA_ACPI + +if NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE + +config VGA_BIOS_ID + string + default "8086,0106" + help + This is the default PCI ID for the sandybridge/ivybridge graphics + devices. This string names the vbios ROM in cbfs. The following + PCI IDs will be remapped to load this ROM: + 0x80860102, 0x8086010a, 0x80860112, 0x80860116 + 0x80860122, 0x80860126, 0x80860166 + +# Ivybridge Specific FSP Kconfig +source src/northbridge/intel/fsp_sandybridge/fsp/Kconfig + +endif # NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE diff --git a/src/northbridge/intel/fsp_sandybridge/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/Makefile.inc new file mode 100644 index 0000000000..6c5e09f9b4 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/Makefile.inc @@ -0,0 +1,41 @@ +# +# 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. +# + +ifeq ($(CONFIG_NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE)$(CONFIG_NORTHBRIDGE_INTEL_FSP_IVYBRIDGE),y) + +subdirs-y += fsp +ramstage-y += northbridge.c +ramstage-y += ram_calc.c +ramstage-y += gma.c + +ramstage-y += acpi.c + +romstage-y += raminit.c +romstage-y += ram_calc.c +romstage-y += early_init.c +romstage-y += report_platform.c +romstage-y += ../../../arch/x86/walkcbfs.S + +smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c + +CPPFLAGS_common += -I$(src)/northbridge/intel/fsp_sandybridge/fsp + +endif diff --git a/src/northbridge/intel/fsp_sandybridge/acpi.c b/src/northbridge/intel/fsp_sandybridge/acpi.c new file mode 100644 index 0000000000..1e20945138 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/acpi.c @@ -0,0 +1,212 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2012 The Chromium OS Authors + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "northbridge.h" +#include + +unsigned long acpi_fill_mcfg(unsigned long current) +{ + device_t dev; + u32 pciexbar = 0; + u32 pciexbar_reg; + int max_buses; + + dev = dev_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SB, 0); + if (!dev) + dev = dev_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IB, 0); + if (!dev) + return current; + + pciexbar_reg=pci_read_config32(dev, PCIEXBAR); + + // MMCFG not supported or not enabled. + if (!(pciexbar_reg & (1 << 0))) + return current; + + switch ((pciexbar_reg >> 1) & 3) { + case 0: // 256MB + pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)); + max_buses = 256; + break; + case 1: // 128M + pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)); + max_buses = 128; + break; + case 2: // 64M + pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)); + max_buses = 64; + break; + default: // RSVD + return current; + } + + if (!pciexbar) + return current; + + current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current, + pciexbar, 0x0, 0x0, max_buses - 1); + + return current; +} + +static void *get_intel_vbios(void) +{ + /* This should probably be looking at CBFS or we should always + * deploy the VBIOS on Intel systems, even if we don't run it + * in coreboot (e.g. SeaBIOS only scenarios). + */ + u8 *vbios = (u8 *)0xc0000; + + optionrom_header_t *oprom = (optionrom_header_t *)vbios; + optionrom_pcir_t *pcir = (optionrom_pcir_t *)(vbios + + oprom->pcir_offset); + + + printk(BIOS_DEBUG, "GET_VBIOS: %x %x %x %x %x\n", + oprom->signature, pcir->vendor, pcir->classcode[0], + pcir->classcode[1], pcir->classcode[2]); + + + if ((oprom->signature == OPROM_SIGNATURE) && + (pcir->vendor == PCI_VENDOR_ID_INTEL) && + (pcir->classcode[0] == 0x00) && + (pcir->classcode[1] == 0x00) && + (pcir->classcode[2] == 0x03)) + return (void *)vbios; + + return NULL; +} + +static int init_opregion_vbt(igd_opregion_t *opregion) +{ + void *vbios; + vbios = get_intel_vbios(); + if (!vbios) { + printk(BIOS_DEBUG, "VBIOS not found.\n"); + return 1; + } + + printk(BIOS_DEBUG, " ... VBIOS found at %p\n", vbios); + optionrom_header_t *oprom = (optionrom_header_t *)vbios; + optionrom_vbt_t *vbt = (optionrom_vbt_t *)(vbios + + oprom->vbt_offset); + + if (read32(vbt->hdr_signature) != VBT_SIGNATURE) { + printk(BIOS_DEBUG, "VBT not found!\n"); + return 1; + } + + memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, 4); + memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size < 7168 ? + vbt->hdr_vbt_size : 7168); + + return 0; +} + + +/* Initialize IGD OpRegion, called from ACPI code */ +int init_igd_opregion(igd_opregion_t *opregion) +{ + device_t igd; + u16 reg16; + + memset((void *)opregion, 0, sizeof(igd_opregion_t)); + + // FIXME if IGD is disabled, we should exit here. + + memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE, + sizeof(opregion->header.signature)); + + /* 8kb */ + opregion->header.size = sizeof(igd_opregion_t) / 1024; + opregion->header.version = IGD_OPREGION_VERSION; + + // FIXME We just assume we're mobile for now + opregion->header.mailboxes = MAILBOXES_MOBILE; + + // TODO Initialize Mailbox 1 + + // TODO Initialize Mailbox 3 + opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS; + opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH; + opregion->mailbox3.pcft = 0; // should be (IMON << 1) & 0x3e + opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS; + opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000; + opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19; + opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433; + opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c; + opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866; + opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f; + opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99; + opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2; + opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc; + opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5; + opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff; + + init_opregion_vbt(opregion); + + /* TODO This needs to happen in S3 resume, too. + * Maybe it should move to the finalize handler + */ + igd = dev_find_slot(0, PCI_DEVFN(0x2, 0)); + + pci_write_config32(igd, ASLS, (u32)opregion); + reg16 = pci_read_config16(igd, SWSCI); + reg16 &= ~(1 << 0); + reg16 |= (1 << 15); + pci_write_config16(igd, SWSCI, reg16); + + /* clear dmisci status */ + reg16 = inw(DEFAULT_PMBASE + TCO1_STS); + reg16 |= DMISCI_STS; // reference code does an &= + outw(DEFAULT_PMBASE + TCO1_STS, reg16); + + /* clear acpi tco status */ + outl(DEFAULT_PMBASE + GPE0_STS, TCOSCI_STS); + + /* enable acpi tco scis */ + reg16 = inw(DEFAULT_PMBASE + GPE0_EN); + reg16 |= TCOSCI_EN; + outw(DEFAULT_PMBASE + GPE0_EN, reg16); + + return 0; +} + +void *igd_make_opregion(void) +{ + igd_opregion_t *opregion; + + printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n"); + opregion = cbmem_add(CBMEM_ID_IGD_OPREGION, sizeof (*opregion)); + if (opregion) + init_igd_opregion(opregion); + return opregion; +} diff --git a/src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl b/src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl new file mode 100644 index 0000000000..a1b99b899c --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl @@ -0,0 +1,359 @@ +/* + * 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. + */ + + +Name(_HID,EISAID("PNP0A08")) // PCIe +Name(_CID,EISAID("PNP0A03")) // PCI + +Name(_ADR, 0) +Name(_BBN, 0) + +Device (MCHC) +{ + Name(_ADR, 0x00000000) // 0:0.0 + + OperationRegion(MCHP, PCI_Config, 0x00, 0x100) + Field (MCHP, DWordAcc, NoLock, Preserve) + { + Offset (0x40), // EPBAR + EPEN, 1, // Enable + , 11, // + EPBR, 24, // EPBAR + + Offset (0x48), // MCHBAR + MHEN, 1, // Enable + , 13, // + MHBR, 22, // MCHBAR + + Offset (0x60), // PCIe BAR + PXEN, 1, // Enable + PXSZ, 2, // BAR size + , 23, // + PXBR, 10, // PCIe BAR + + Offset (0x68), // DMIBAR + DMEN, 1, // Enable + , 11, // + DMBR, 24, // DMIBAR + + Offset (0x70), // ME Base Address + MEBA, 64, + + // ... + + Offset (0x80), // PAM0 + , 4, + PM0H, 2, + , 2, + Offset (0x81), // PAM1 + PM1L, 2, + , 2, + PM1H, 2, + , 2, + Offset (0x82), // PAM2 + PM2L, 2, + , 2, + PM2H, 2, + , 2, + Offset (0x83), // PAM3 + PM3L, 2, + , 2, + PM3H, 2, + , 2, + Offset (0x84), // PAM4 + PM4L, 2, + , 2, + PM4H, 2, + , 2, + Offset (0x85), // PAM5 + PM5L, 2, + , 2, + PM5H, 2, + , 2, + Offset (0x86), // PAM6 + PM6L, 2, + , 2, + PM6H, 2, + , 2, + + Offset (0xa0), // Top of Used Memory + TOM, 64, + + Offset (0xbc), // Top of Low Used Memory + TLUD, 32, + } + + Mutex (CTCM, 1) /* CTDP Switch Mutex (sync level 1) */ + Name (CTCC, 0) /* CTDP Current Selection */ + Name (CTCN, 0) /* CTDP Nominal Select */ + Name (CTCD, 1) /* CTDP Down Select */ + Name (CTCU, 2) /* CTDP Up Select */ + + OperationRegion (MCHB, SystemMemory, DEFAULT_MCHBAR, 0x8000) + Field (MCHB, DWordAcc, Lock, Preserve) + { + Offset (0x5930), + CTDN, 15, /* CTDP Nominal PL1 */ + Offset (0x59a0), + PL1V, 15, /* Power Limit 1 Value */ + PL1E, 1, /* Power Limit 1 Enable */ + PL1C, 1, /* Power Limit 1 Clamp */ + PL1T, 7, /* Power Limit 1 Time */ + Offset (0x59a4), + PL2V, 15, /* Power Limit 2 Value */ + PL2E, 1, /* Power Limit 2 Enable */ + PL2C, 1, /* Power Limit 2 Clamp */ + PL2T, 7, /* Power Limit 2 Time */ + Offset (0x5f3c), + TARN, 8, /* CTDP Nominal Turbo Activation Ratio */ + Offset (0x5f40), + CTDD, 15, /* CTDP Down PL1 */ + , 1, + TARD, 8, /* CTDP Down Turbo Activation Ratio */ + Offset (0x5f48), + CTDU, 15, /* CTDP Up PL1 */ + , 1, + TARU, 8, /* CTDP Up Turbo Activation Ratio */ + Offset (0x5f50), + CTCS, 2, /* CTDP Select */ + Offset (0x5f54), + TARS, 8, /* Turbo Activation Ratio Select */ + } + + /* + * Search CPU0 _PSS looking for control=arg0 and then + * return previous P-state entry number for new _PPC + * + * Format of _PSS: + * Name (_PSS, Package () { + * Package (6) { freq, power, tlat, blat, control, status } + * } + */ + External (\_PR.CP00._PSS) + Method (PSSS, 1, NotSerialized) + { + Store (One, Local0) /* Start at P1 */ + Store (SizeOf (\_PR.CP00._PSS), Local1) + + While (LLess (Local0, Local1)) { + /* Store _PSS entry Control value to Local2 */ + ShiftRight (DeRefOf (Index (DeRefOf (Index + (\_PR.CP00._PSS, Local0)), 4)), 8, Local2) + If (LEqual (Local2, Arg0)) { + Return (Subtract (Local0, 1)) + } + Increment (Local0) + } + + Return (0) + } + + /* Set TDP Down */ + Method (STND, 0, Serialized) + { + If (Acquire (CTCM, 100)) { + Return (0) + } + If (LEqual (CTCD, CTCC)) { + Release (CTCM) + Return (0) + } + + Store ("Set TDP Down", Debug) + + /* Set CTC */ + Store (CTCD, CTCS) + + /* Set TAR */ + Store (TARD, TARS) + + /* Set PPC limit and notify OS */ + Store (PSSS (TARD), PPCM) + PPCN () + + /* Set PL2 to 1.25 * PL1 */ + Divide (Multiply (CTDD, 125), 100, Local0, PL2V) + + /* Set PL1 */ + Store (CTDD, PL1V) + + /* Store the new TDP Down setting */ + Store (CTCD, CTCC) + + Release (CTCM) + Return (1) + } + + /* Set TDP Nominal from Down */ + Method (STDN, 0, Serialized) + { + If (Acquire (CTCM, 100)) { + Return (0) + } + If (LEqual (CTCN, CTCC)) { + Release (CTCM) + Return (0) + } + + Store ("Set TDP Nominal", Debug) + + /* Set PL1 */ + Store (CTDN, PL1V) + + /* Set PL2 to 1.25 * PL1 */ + Divide (Multiply (CTDN, 125), 100, Local0, PL2V) + + /* Set PPC limit and notify OS */ + Store (PSSS (TARN), PPCM) + PPCN () + + /* Set TAR */ + Store (TARN, TARS) + + /* Set CTC */ + Store (CTCN, CTCS) + + /* Store the new TDP Nominal setting */ + Store (CTCN, CTCC) + + Release (CTCM) + Return (1) + } +} + +// 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-CONFIG_MMCONF_BASE_ADDRESS) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000,,, PM01) + + // TPM Area (0xfed40000-0xfed44fff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000, + 0x00005000,,, TPMR) + }) + + // 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 (^MCHC.TLUD, Local0) + Store (^MCHC.MEBA, Local1) + + // Check if ME base is equal + If (LEqual (Local0, Local1)) { + // Use Top Of Memory instead + Store (^MCHC.TOM, Local0) + } + + Store (Local0, PMIN) + Store (Subtract(CONFIG_MMCONF_BASE_ADDRESS, 1), PMAX) + Add(Subtract(PMAX, PMIN), 1, PLEN) + + Return (MCRS) +} + +/* IRQ assignment is mainboard specific. Get it from mainboard ACPI code */ +#include "acpi/hostbridge_pci_irqs.asl" diff --git a/src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl b/src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl new file mode 100644 index 0000000000..b7595f2dd1 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#include "../northbridge.h" +#include "hostbridge.asl" + +/* PCI Device Resource Consumption */ +Device (PDRC) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 1) + + Name (PDRS, ResourceTemplate() { + Memory32Fixed(ReadWrite, 0xfed1c000, 0x00004000) // RCBA + Memory32Fixed(ReadWrite, DEFAULT_MCHBAR, 0x00008000) + Memory32Fixed(ReadWrite, DEFAULT_DMIBAR, 0x00001000) + Memory32Fixed(ReadWrite, DEFAULT_EPBAR, 0x00001000) + Memory32Fixed(ReadWrite, DEFAULT_PCIEXBAR, 0x04000000) + Memory32Fixed(ReadWrite, 0xfed20000, 0x00020000) // Misc ICH + Memory32Fixed(ReadWrite, 0xfed40000, 0x00005000) // Misc ICH + Memory32Fixed(ReadWrite, 0xfed45000, 0x0004b000) // Misc ICH + +#if CONFIG_CHROMEOS_RAMOOPS + Memory32Fixed(ReadWrite, CONFIG_CHROMEOS_RAMOOPS_RAM_START, + CONFIG_CHROMEOS_RAMOOPS_RAM_SIZE) +#endif + + /* Required for SandyBridge sighting 3715511 */ + Memory32Fixed(ReadWrite, 0x20000000, 0x00200000) + Memory32Fixed(ReadWrite, 0x40000000, 0x00200000) + }) + + // Current Resource Settings + Method (_CRS, 0, Serialized) + { + Return(PDRS) + } +} + +// Integrated graphics 0:2.0 +#include diff --git a/src/northbridge/intel/fsp_sandybridge/chip.h b/src/northbridge/intel/fsp_sandybridge/chip.h new file mode 100644 index 0000000000..6e823dc986 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/chip.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#include + +/* + * Digital Port Hotplug Enable: + * 0x04 = Enabled, 2ms short pulse + * 0x05 = Enabled, 4.5ms short pulse + * 0x06 = Enabled, 6ms short pulse + * 0x07 = Enabled, 100ms short pulse + */ +struct northbridge_intel_fsp_sandybridge_config { + u8 gpu_dp_b_hotplug; /* Digital Port B Hotplug Config */ + u8 gpu_dp_c_hotplug; /* Digital Port C Hotplug Config */ + u8 gpu_dp_d_hotplug; /* Digital Port D Hotplug Config */ + + u8 gpu_panel_port_select; /* 0=LVDS 1=DP_B 2=DP_C 3=DP_D */ + u8 gpu_panel_power_cycle_delay; /* T4 time sequence */ + u16 gpu_panel_power_up_delay; /* T1+T2 time sequence */ + u16 gpu_panel_power_down_delay; /* T3 time sequence */ + u16 gpu_panel_power_backlight_on_delay; /* T5 time sequence */ + u16 gpu_panel_power_backlight_off_delay; /* Tx time sequence */ + + u32 gpu_cpu_backlight; /* CPU Backlight PWM value */ + u32 gpu_pch_backlight; /* PCH Backlight PWM value */ + + struct i915_gpu_controller_info gfx; +}; diff --git a/src/northbridge/intel/fsp_sandybridge/early_init.c b/src/northbridge/intel/fsp_sandybridge/early_init.c new file mode 100644 index 0000000000..6ba1ab6828 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/early_init.c @@ -0,0 +1,88 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2010 coresystems GmbH + * Copyright (C) 2011 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "northbridge.h" + +static void sandybridge_setup_bars(void) +{ + printk(BIOS_DEBUG, "Setting up static northbridge registers..."); + /* Set up all hardcoded northbridge BARs */ + pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR, DEFAULT_EPBAR | 1); + pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR + 4, (0LL+DEFAULT_EPBAR) >> 32); + pci_write_config32(PCI_DEV(0, 0x00, 0), MCHBAR, (uintptr_t)DEFAULT_MCHBAR | 1); + pci_write_config32(PCI_DEV(0, 0x00, 0), MCHBAR + 4, (0LL+(uintptr_t)DEFAULT_MCHBAR) >> 32); + pci_write_config32(PCI_DEV(0, 0x00, 0), PCIEXBAR, DEFAULT_PCIEXBAR | 5); /* 64MB - busses 0-63 */ + pci_write_config32(PCI_DEV(0, 0x00, 0), PCIEXBAR + 4, (0LL+DEFAULT_PCIEXBAR) >> 32); + pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR, (uintptr_t)DEFAULT_DMIBAR | 1); + pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR + 4, (0LL+(uintptr_t)DEFAULT_DMIBAR) >> 32); + + /* Set C0000-FFFFF to access RAM on both reads and writes */ + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM0, 0x30); + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM1, 0x33); + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM2, 0x33); + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM3, 0x33); + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM4, 0x33); + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM5, 0x33); + pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33); + +#if CONFIG_ELOG_BOOT_COUNT + /* Increment Boot Counter for non-S3 resume */ + if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) && + ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) != SLP_TYP_S3) + boot_count_increment(); +#endif + + printk(BIOS_DEBUG, " done.\n"); + +#if CONFIG_ELOG_BOOT_COUNT + /* Increment Boot Counter except when resuming from S3 */ + if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) && + ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3) + return; + boot_count_increment(); +#endif +} + +void sandybridge_early_initialization(int chipset_type) +{ + u32 capid0_a; + u8 reg8; + + /* Device ID Override Enable should be done very early */ + capid0_a = pci_read_config32(PCI_DEV(0, 0, 0), 0xe4); + if (capid0_a & (1 << 10)) { + reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xf3); + reg8 &= ~7; /* Clear 2:0 */ + + if (chipset_type == SANDYBRIDGE_MOBILE) + reg8 |= 1; /* Set bit 0 */ + + pci_write_config8(PCI_DEV(0, 0, 0), 0xf3, reg8); + } + + /* Setup all BARs required for early PCIe and raminit */ + sandybridge_setup_bars(); +} diff --git a/src/northbridge/intel/fsp_sandybridge/finalize.c b/src/northbridge/intel/fsp_sandybridge/finalize.c new file mode 100644 index 0000000000..90c3635a7c --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/finalize.c @@ -0,0 +1,56 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 The Chromium OS Authors. 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. + * + * 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. + */ + +#include +#include +#include "northbridge.h" + +#define PCI_DEV_SNB PCI_DEV(0, 0, 0) + +void intel_sandybridge_finalize_smm(void) +{ + pcie_or_config16(PCI_DEV_SNB, 0x50, 1 << 0); /* GGC */ + pcie_or_config32(PCI_DEV_SNB, 0x5c, 1 << 0); /* DPR */ + pcie_or_config32(PCI_DEV_SNB, 0x78, 1 << 10); /* ME */ + pcie_or_config32(PCI_DEV_SNB, 0x90, 1 << 0); /* REMAPBASE */ + pcie_or_config32(PCI_DEV_SNB, 0x98, 1 << 0); /* REMAPLIMIT */ + pcie_or_config32(PCI_DEV_SNB, 0xa0, 1 << 0); /* TOM */ + pcie_or_config32(PCI_DEV_SNB, 0xa8, 1 << 0); /* TOUUD */ + pcie_or_config32(PCI_DEV_SNB, 0xb0, 1 << 0); /* BDSM */ + pcie_or_config32(PCI_DEV_SNB, 0xb4, 1 << 0); /* BGSM */ + pcie_or_config32(PCI_DEV_SNB, 0xb8, 1 << 0); /* TSEGMB */ + pcie_or_config32(PCI_DEV_SNB, 0xbc, 1 << 0); /* TOLUD */ + + MCHBAR32_OR(0x5500, 1 << 0); /* PAVP */ + MCHBAR32_OR(0x5f00, 1 << 31); /* SA PM */ + MCHBAR32_OR(0x6020, 1 << 0); /* UMA GFX */ + MCHBAR32_OR(0x63fc, 1 << 0); /* VTDTRK */ + MCHBAR32_OR(0x6800, 1 << 31); + MCHBAR32_OR(0x7000, 1 << 31); + MCHBAR32_OR(0x77fc, 1 << 0); + + /* Memory Controller Lockdown */ + MCHBAR8(0x50fc) = 0x8f; + + /* Read+write the following */ + MCHBAR32(0x6030) = MCHBAR32(0x6030); + MCHBAR32(0x6034) = MCHBAR32(0x6034); + MCHBAR32(0x6008) = MCHBAR32(0x6008); +} diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig new file mode 100644 index 0000000000..82e5361505 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig @@ -0,0 +1,40 @@ +## +## 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. +## + +config SANDYBRIDGE_FSP_SPECIFIC_OPTIONS + def_bool y + select PLATFORM_USES_FSP1_0 + select USE_GENERIC_FSP_CAR_INC + +config FSP_FILE + string + default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_BD82X6X + help + The path and filename of the Intel FSP binary for this platform. + +config FSP_LOC + hex "Intel FSP Binary location in CBFS" + 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 the Intel's BCT (tool). + + The Ivy Bridge Processor/Panther Point FSP is built with a preferred + base address of 0xFFF80000 diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc new file mode 100644 index 0000000000..282570351b --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/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. +# + +ramstage-y += chipset_fsp_util.c +romstage-y += chipset_fsp_util.c diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c new file mode 100644 index 0000000000..e9dad29f4c --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c @@ -0,0 +1,113 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../chip.h" +#include + +#ifndef CONFIG_ENABLE_FSP_FAST_BOOT +# error "CONFIG_ENABLE_FSP_FAST_BOOT must be set." +#endif + +#ifdef __PRE_RAM__ + +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) +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)); +} + +static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData) +{ + UpdData->HTEnable = TRUE; + UpdData->TurboEnable = FALSE; + UpdData->MemoryDownEnable = FALSE; + UpdData->FastBootEnable = CONFIG_ENABLE_FSP_FAST_BOOT; +} +#else /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */ +const PLATFORM_CONFIG DefaultPlatformConfig = { + TRUE, /* Hyperthreading */ + FALSE, /* Turbo Mode */ + FALSE, /* Memory Down */ +#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT) + TRUE, /* Fast Boot */ +#else + FALSE, /* Fast Boot */ +#endif /* CONFIG_ENABLE_FSP_FAST_BOOT */ +}; +#endif /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */ + +/* + * + * Call the FSP to do memory init. The FSP doesn't return to this function. + * The FSP returns to the romstage_main_continue(). + * + */ +void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams, + FSP_INFO_HEADER *fsp_ptr) +{ + FSP_INIT_RT_BUFFER *pFspRtBuffer = FspInitParams->RtBufferPtr; +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) + UPD_DATA_REGION *fsp_upd_data = pFspRtBuffer->Common.UpdDataRgnPtr; +#else + MEM_CONFIG MemoryConfig; + memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG)); +#endif + FspInitParams->NvsBufferPtr = NULL; + +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) + /* Initialize the UPD Data */ + GetUpdDefaultFromFsp (fsp_ptr, fsp_upd_data); + ConfigureDefaultUpdData(fsp_upd_data); +#else + pFspRtBuffer->Platform.MemoryConfig = &MemoryConfig; + pFspRtBuffer->PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig; +#endif + +#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT) + /* Find the fastboot cache that was saved in the ROM */ + FspInitParams->NvsBufferPtr = find_and_set_fastboot_cache(); +#endif + + pFspRtBuffer->Common.BootMode = 0; +} + +/* 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) { + hard_reset(); + } + romstage_main_continue(Status, HobListPtr); +} + +#endif /* __PRE_RAM__ */ diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h new file mode 100644 index 0000000000..cb0434776b --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h @@ -0,0 +1,68 @@ +/* + * 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. + */ + +#ifndef CHIPSET_FSP_UTIL_H +#define CHIPSET_FSP_UTIL_H + +#include +#include +#include +#include +#include +#include +#include +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) +#include +#include +#endif + +#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. + */ + +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) +/* ST2-FSP0 */ +#define FSP_IMAGE_ID_DWORD0 0x2D325453 +#define FSP_IMAGE_ID_DWORD1 0x30505346 +#elif IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X) +/* CC2-FSP\0 */ +#define FSP_IMAGE_ID_DWORD0 0x2D324343 +#define FSP_IMAGE_ID_DWORD1 0x00505346 +#endif + +#ifdef __PRE_RAM__ +void main(FSP_INFO_HEADER *fsp_info_header); +void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr); +#endif + +#endif /* CHIPSET_FSP_UTIL_H */ diff --git a/src/northbridge/intel/fsp_sandybridge/gma.c b/src/northbridge/intel/fsp_sandybridge/gma.c new file mode 100644 index 0000000000..132a1b869b --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/gma.c @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Chromium OS Authors + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "northbridge.h" + + +/* some vga option roms are used for several chipsets but they only have one + * PCI ID in their header. If we encounter such an option rom, we need to do + * the mapping ourselfes + */ + +u32 map_oprom_vendev(u32 vendev) +{ + u32 new_vendev=vendev; + + switch (vendev) { + case 0x80860102: /* GT1 Desktop */ + case 0x8086010a: /* GT1 Server */ + case 0x80860112: /* GT2 Desktop */ + case 0x80860116: /* GT2 Mobile */ + case 0x80860122: /* GT2 Desktop >=1.3GHz */ + case 0x80860126: /* GT2 Mobile >=1.3GHz */ + case 0x80860166: /* IVB */ + new_vendev=0x80860106; /* GT1 Mobile */ + break; + } + + return new_vendev; +} + +static void gma_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)); + } +} + +const struct i915_gpu_controller_info * +intel_gma_get_controller_info(void) +{ + device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0)); + if (!dev) { + return NULL; + } + struct northbridge_intel_fsp_sandybridge_config *chip = dev->chip_info; + return &chip->gfx; +} + +static void gma_ssdt(device_t device) +{ + const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info(); + if (!gfx) { + return; + } + + drivers_intel_gma_displays_ssdt_generate(gfx); +} + +static struct pci_operations gma_pci_ops = { + .set_subsystem = gma_set_subsystem, +}; + +static struct device_operations gma_func0_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .acpi_fill_ssdt_generator = gma_ssdt, + .init = pci_dev_init, + .scan_bus = 0, + .enable = 0, + .ops_pci = &gma_pci_ops, +}; + +static const unsigned short gma_ids[] = { + 0x0102, 0x0106, 0x010a, 0x0112, 0x0116, 0x0122, 0x0126, 0x166, + 0, +}; +static const struct pci_driver gma_gt1_desktop __pci_driver = { + .ops = &gma_func0_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices= gma_ids, +}; diff --git a/src/northbridge/intel/fsp_sandybridge/gma.h b/src/northbridge/intel/fsp_sandybridge/gma.h new file mode 100644 index 0000000000..9cc2241410 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/gma.h @@ -0,0 +1,167 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Chromium OS Authors + * + * 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. + */ + +/* mailbox 0: header */ +typedef struct { + u8 signature[16]; + u32 size; + u32 version; + u8 sbios_version[32]; + u8 vbios_version[16]; + u8 driver_version[16]; + u32 mailboxes; + u8 reserved[164]; +} __attribute__((packed)) opregion_header_t; + +#define IGD_OPREGION_SIGNATURE "IntelGraphicsMem" +#define IGD_OPREGION_VERSION 2 + +#define IGD_MBOX1 (1 << 0) +#define IGD_MBOX2 (1 << 1) +#define IGD_MBOX3 (1 << 2) +#define IGD_MBOX4 (1 << 3) +#define IGD_MBOX5 (1 << 4) + +#define MAILBOXES_MOBILE (IGD_MBOX1 | IGD_MBOX2 | IGD_MBOX3 | \ + IGD_MBOX4 | IGD_MBOX5) +#define MAILBOXES_DESKTOP (IGD_MBOX2 | IGD_MBOX4) + +#define SBIOS_VERSION_SIZE 32 + +/* mailbox 1: public acpi methods */ +typedef struct { + u32 drdy; + u32 csts; + u32 cevt; + u8 reserved1[20]; + u32 didl[8]; + u32 cpdl[8]; + u32 cadl[8]; + u32 nadl[8]; + u32 aslp; + u32 tidx; + u32 chpd; + u32 clid; + u32 cdck; + u32 sxsw; + u32 evts; + u32 cnot; + u32 nrdy; + u8 reserved2[60]; +} __attribute__((packed)) opregion_mailbox1_t; + +/* mailbox 2: software sci interface */ +typedef struct { + u32 scic; + u32 parm; + u32 dslp; + u8 reserved[244]; +} __attribute__((packed)) opregion_mailbox2_t; + +/* mailbox 3: power conservation */ +typedef struct { + u32 ardy; + u32 aslc; + u32 tche; + u32 alsi; + u32 bclp; + u32 pfit; + u32 cblv; + u16 bclm[20]; + u32 cpfm; + u32 epfm; + u8 plut[74]; + u32 pfmb; + u32 ccdv; + u32 pcft; + u8 reserved[94]; +} __attribute__((packed)) opregion_mailbox3_t; + +#define IGD_BACKLIGHT_BRIGHTNESS 0xff +#define IGD_INITIAL_BRIGHTNESS 0x64 + +#define IGD_FIELD_VALID (1 << 31) +#define IGD_WORD_FIELD_VALID (1 << 15) +#define IGD_PFIT_STRETCH 6 + +/* mailbox 4: vbt */ +typedef struct { + u8 gvd1[7168]; +} __attribute__((packed)) opregion_vbt_t; + +/* IGD OpRegion */ +typedef struct { + opregion_header_t header; + opregion_mailbox1_t mailbox1; + opregion_mailbox2_t mailbox2; + opregion_mailbox3_t mailbox3; + opregion_vbt_t vbt; +} __attribute__((packed)) igd_opregion_t; + +/* Intel Video BIOS (Option ROM) */ +typedef struct { + u16 signature; + u8 size; + u8 reserved[21]; + u16 pcir_offset; + u16 vbt_offset; +} __attribute__((packed)) optionrom_header_t; + +#define OPROM_SIGNATURE 0xaa55 + +typedef struct { + u32 signature; + u16 vendor; + u16 device; + u16 reserved1; + u16 length; + u8 revision; + u8 classcode[3]; + u16 imagelength; + u16 coderevision; + u8 codetype; + u8 indicator; + u16 reserved2; +} __attribute__((packed)) optionrom_pcir_t; + +typedef struct { + u8 hdr_signature[20]; + u16 hdr_version; + u16 hdr_size; + u16 hdr_vbt_size; + u8 hdr_vbt_checksum; + u8 hdr_reserved; + u32 hdr_vbt_datablock; + u32 hdr_aim[4]; + u8 datahdr_signature[16]; + u16 datahdr_version; + u16 datahdr_size; + u16 datahdr_datablocksize; + u8 coreblock_id; + u16 coreblock_size; + u16 coreblock_biossize; + u8 coreblock_biostype; + u8 coreblock_releasestatus; + u8 coreblock_hwsupported; + u8 coreblock_integratedhw; + u8 coreblock_biosbuild[4]; + u8 coreblock_biossignon[155]; +} __attribute__((packed)) optionrom_vbt_t; + +#define VBT_SIGNATURE 0x54425624 diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.c b/src/northbridge/intel/fsp_sandybridge/northbridge.c new file mode 100644 index 0000000000..3f982c4a17 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/northbridge.c @@ -0,0 +1,407 @@ +/* + * 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 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. + */ + +#include +#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; + +/* IGD UMA memory */ +static uint64_t uma_memory_base = 0; +static uint64_t uma_memory_size = 0; + +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 = pci_read_config32(dev, PCIEXBAR); + + if (!(pciexbar_reg & (1 << 0))) + return 0; + + switch ((pciexbar_reg >> 1) & 3) { + case 0: // 256MB + *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)); + *len = 256 * 1024 * 1024; + return 1; + case 1: // 128M + *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)); + *len = 128 * 1024 * 1024; + return 1; + case 2: // 64M + *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)); + *len = 64 * 1024 * 1024; + return 1; + } + + return 0; +} + +static void add_fixed_resources(struct device *dev, int index) +{ + struct resource *resource; + u32 pcie_config_base, pcie_config_size; + + mmio_resource(dev, index++, uma_memory_base >> 10, uma_memory_size >> 10); + + 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; + } + + mmio_resource(dev, index++, legacy_hole_base_k, legacy_hole_size_k); +} + +static void pci_domain_set_resources(device_t dev) +{ + uint64_t tom, me_base, touud; + uint32_t tseg_base, uma_size, tolud; + uint16_t ggc; + unsigned long long tomk; + + tomk = ggc = tseg_base = uma_size = tolud = tom = me_base = touud = 0; + + /* Total Memory 2GB example: + * + * 00000000 0000MB-1992MB 1992MB RAM (writeback) + * 7c800000 1992MB-2000MB 8MB TSEG (SMRR) + * 7d000000 2000MB-2002MB 2MB GFX GTT (uncached) + * 7d200000 2002MB-2034MB 32MB GFX UMA (uncached) + * 7f200000 2034MB TOLUD + * 7f800000 2040MB MEBASE + * 7f800000 2040MB-2048MB 8MB ME UMA (uncached) + * 80000000 2048MB TOM + * 100000000 4096MB-4102MB 6MB RAM (writeback) + * + * Total Memory 4GB example: + * + * 00000000 0000MB-2768MB 2768MB RAM (writeback) + * ad000000 2768MB-2776MB 8MB TSEG (SMRR) + * ad800000 2776MB-2778MB 2MB GFX GTT (uncached) + * ada00000 2778MB-2810MB 32MB GFX UMA (uncached) + * afa00000 2810MB TOLUD + * ff800000 4088MB MEBASE + * ff800000 4088MB-4096MB 8MB ME UMA (uncached) + * 100000000 4096MB TOM + * 100000000 4096MB-5374MB 1278MB RAM (writeback) + * 14fe00000 5368MB TOUUD + */ + + /* Top of Upper Usable DRAM, including remap */ + touud = pci_read_config32(dev, TOUUD+4); + touud <<= 32; + touud |= pci_read_config32(dev, TOUUD) & ~(1UL << 0); + + /* Top of Lower Usable DRAM */ + tolud = pci_read_config32(dev, TOLUD) & ~(1UL << 0); + + /* Top of Memory - does not account for any UMA */ + tom = pci_read_config32(dev, 0xa4); + tom <<= 32; + tom |= pci_read_config32(dev, 0xa0) & ~(1UL << 0); + + printk(BIOS_DEBUG, "TOUUD 0x%llx TOLUD 0x%08x TOM 0x%llx\n", + touud, tolud, tom); + + /* ME UMA needs excluding if total memory <4GB */ + me_base = pci_read_config32(dev, 0x74); + me_base <<= 32; + me_base |= pci_read_config32(dev, 0x70); + + printk(BIOS_DEBUG, "MEBASE 0x%llx\n", me_base); + + tomk = tolud >> 10; + if (me_base == tolud) { + /* ME is from MEBASE-TOM */ + uma_size = (tom - me_base) >> 10; + /* Increment TOLUD to account for ME as RAM */ + tolud += uma_size << 10; + /* UMA starts at old TOLUD */ + uma_memory_base = tomk * 1024ULL; + uma_memory_size = uma_size * 1024ULL; + printk(BIOS_DEBUG, "ME UMA base 0x%llx size %uM\n", + me_base, uma_size >> 10); + } + + /* Graphics memory comes next */ + ggc = pci_read_config16(dev, GGC); + if (!(ggc & 2)) { + printk(BIOS_DEBUG, "IGD decoded, subtracting "); + + /* Graphics memory */ + uma_size = ((ggc >> 3) & 0x1f) * 32 * 1024ULL; + printk(BIOS_DEBUG, "%uM UMA", uma_size >> 10); + tomk -= uma_size; + uma_memory_base = tomk * 1024ULL; + uma_memory_size += uma_size * 1024ULL; + + /* GTT Graphics Stolen Memory Size (GGMS) */ + uma_size = ((ggc >> 8) & 0x3) * 1024ULL; + tomk -= uma_size; + uma_memory_base = tomk * 1024ULL; + uma_memory_size += uma_size * 1024ULL; + printk(BIOS_DEBUG, " and %uM GTT\n", uma_size >> 10); + } + + /* Calculate TSEG size from its base which must be below GTT */ + uma_memory_base = tomk * 1024ULL; + tseg_base = pci_read_config32(dev, 0xb8) & ~(1UL << 0); + uma_size = (uma_memory_base - tseg_base) >> 10; + tomk -= uma_size; + uma_memory_base = tomk * 1024ULL; + uma_memory_size += uma_size * 1024ULL; + printk(BIOS_DEBUG, "TSEG base 0x%08x size %uM\n", + tseg_base, uma_size >> 10); + + printk(BIOS_INFO, "Available memory below 4GB: %lluM\n", tomk >> 10); + + /* Report the memory regions */ + ram_resource(dev, 3, 0, legacy_hole_base_k); + ram_resource(dev, 4, legacy_hole_base_k + legacy_hole_size_k, + (tomk - (legacy_hole_base_k + legacy_hole_size_k))); + + /* + * If >= 4GB installed then memory from TOLUD to 4GB + * is remapped above TOM, TOUUD will account for both + */ + touud >>= 10; /* Convert to KB */ + if (touud > 4096 * 1024) { + ram_resource(dev, 5, 4096 * 1024, touud - (4096 * 1024)); + printk(BIOS_INFO, "Available memory above 4GB: %lluM\n", + (touud >> 10) - 4096); + } + + add_fixed_resources(dev, 6); + + assign_resources(dev->link_list); +} + + /* TODO We could determine how many PCIe busses we need in + * the bar. For now that number is hardcoded to a max of 64. + * See e7525/northbridge.c for an example. + */ +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 void mc_read_resources(device_t dev) +{ + struct resource *resource; + + pci_dev_read_resources(dev); + + /* So, this is one of the big mysteries in the coreboot resource + * allocator. This resource should make sure that the address space + * of the PCIe memory mapped config space bar. But it does not. + */ + + /* We use 0xcf as an unused index for our PCIe bar so that we find it again */ + resource = new_resource(dev, 0xcf); + resource->base = DEFAULT_PCIEXBAR; + resource->size = 64 * 1024 * 1024; /* 64MB hard coded PCIe config space */ + resource->flags = + IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | + IORESOURCE_ASSIGNED; + printk(BIOS_DEBUG, "Adding PCIe enhanced config space BAR 0x%08lx-0x%08lx.\n", + (unsigned long)(resource->base), (unsigned long)(resource->base + resource->size)); +} + +static void mc_set_resources(device_t dev) +{ + struct resource *resource; + + /* Report the PCIe BAR */ + resource = find_resource(dev, 0xcf); + if (resource) { + report_resource_stored(dev, resource, ""); + } + + /* And 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) +{ + u8 bios_reset_cpl; + + /* + * Set bit 0 of BIOS_RESET_CPL to indicate to the CPU + * that BIOS has initialized memory and power management + */ + bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL); + bios_reset_cpl |= 1; + MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl; + printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n"); +} + +static u32 northbridge_get_base_reg(device_t dev, int reg) +{ + u32 value; + + value = pci_read_config32(dev, reg); + /* Base registers are at 1MiB granularity. */ + value &= ~((1 << 20) - 1); + return value; +} + +void +northbridge_get_tseg_base_and_size(u32 *tsegmb, u32 *tseg_size) +{ + device_t dev; + u32 bgsm; + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + + *tsegmb = northbridge_get_base_reg(dev, TSEG); + bgsm = northbridge_get_base_reg(dev, BGSM); + *tseg_size = bgsm - *tsegmb; +} + +void northbridge_write_smram(u8 smram) +{ + pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM, smram); +} + +static struct pci_operations intel_pci_ops = { + .set_subsystem = intel_set_subsystem, +}; + +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, + .scan_bus = 0, + .ops_pci = &intel_pci_ops, + .acpi_fill_ssdt_generator = generate_cpu_entries, +}; + +static const struct pci_driver mc_driver_0100 __pci_driver = { + .ops = &mc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x0100, +}; + +static const struct pci_driver mc_driver __pci_driver = { + .ops = &mc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x0104, /* Sandy bridge */ +}; + +static const struct pci_driver mc_driver_1 __pci_driver = { + .ops = &mc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x0154, /* Ivy bridge */ +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(dev->link_list); +} + +static struct device_operations cpu_bus_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_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; + } +} + +struct chip_operations northbridge_intel_fsp_sandybridge_ops = { + CHIP_NAME("Intel i7 (SandyBridge/IvyBridge) integrated Northbridge") + .enable_dev = enable_dev, +}; diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.h b/src/northbridge/intel/fsp_sandybridge/northbridge.h new file mode 100644 index 0000000000..4861254902 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/northbridge.h @@ -0,0 +1,231 @@ +/* + * 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. + */ + +#ifndef __NORTHBRIDGE_INTEL_SANDYBRIDGE_SANDYBRIDGE_H__ +#define __NORTHBRIDGE_INTEL_SANDYBRIDGE_SANDYBRIDGE_H__ + +/* Chipset types */ +#define SANDYBRIDGE_MOBILE 0 +#define SANDYBRIDGE_DESKTOP 1 +#define SANDYBRIDGE_SERVER 2 + +/* Device ID for SandyBridge and IvyBridge */ +#define BASE_REV_SNB 0x00 +#define BASE_REV_IVB 0x50 +#define BASE_REV_MASK 0x50 + +/* SandyBridge CPU stepping */ +#define SNB_STEP_D0 (BASE_REV_SNB + 5) /* Also J0 */ +#define SNB_STEP_D1 (BASE_REV_SNB + 6) +#define SNB_STEP_D2 (BASE_REV_SNB + 7) /* Also J1/Q0 */ + +/* IvyBridge CPU stepping */ +#define IVB_STEP_A0 (BASE_REV_IVB + 0) +#define IVB_STEP_B0 (BASE_REV_IVB + 2) +#define IVB_STEP_C0 (BASE_REV_IVB + 4) +#define IVB_STEP_K0 (BASE_REV_IVB + 5) +#define IVB_STEP_D0 (BASE_REV_IVB + 6) + +/* Intel Enhanced Debug region must be 4MB */ +#define IED_SIZE 0x400000 + +/* Northbridge BARs */ +#define DEFAULT_PCIEXBAR CONFIG_MMCONF_BASE_ADDRESS /* 4 KB per PCIe device */ +#ifndef __ACPI__ +#define DEFAULT_MCHBAR ((u8 *)0xfed10000) /* 16 KB */ +#define DEFAULT_DMIBAR ((u8 *)0xfed18000) /* 4 KB */ +#else +#define DEFAULT_MCHBAR 0xfed10000 /* 16 KB */ +#define DEFAULT_DMIBAR 0xfed18000 /* 4 KB */ +#endif +#define DEFAULT_EPBAR 0xfed19000 /* 4 KB */ +#define DEFAULT_RCBABASE ((u8 *)0xfed1c000) + +#if CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X +#include +#endif + +/* Everything below this line is ignored in the DSDT */ +#ifndef __ACPI__ + +/* Device 0:0.0 PCI configuration space (Host Bridge) */ + +#define EPBAR 0x40 +#define MCHBAR 0x48 +#define PCIEXBAR 0x60 +#define DMIBAR 0x68 +#define X60BAR 0x60 + +#define GGC 0x50 /* GMCH Graphics Control */ + +#define DEVEN 0x54 /* Device Enable */ +#define DEVEN_PEG60 (1 << 13) +#define DEVEN_IGD (1 << 4) +#define DEVEN_PEG10 (1 << 3) +#define DEVEN_PEG11 (1 << 2) +#define DEVEN_PEG12 (1 << 1) +#define DEVEN_HOST (1 << 0) + +#define PAM0 0x80 +#define PAM1 0x81 +#define PAM2 0x82 +#define PAM3 0x83 +#define PAM4 0x84 +#define PAM5 0x85 +#define PAM6 0x86 + +#define LAC 0x87 /* Legacy Access Control */ +#define SMRAM 0x88 /* System Management RAM Control */ + +#define TOM 0xa0 +#define TOUUD 0xa8 /* Top of Upper Usable DRAM */ +#define BGSM 0xb4 /* Base GTT Stolen Memory */ +#define TSEG 0xb8 /* TSEG base */ +#define TOLUD 0xbc /* Top of Low Used Memory */ + +#define SKPAD 0xdc /* Scratchpad Data */ + +/* Device 0:1.0 PCI configuration space (PCI Express) */ + +#define BCTRL1 0x3e /* 16bit */ + + +/* Device 0:2.0 PCI configuration space (Graphics Device) */ + +#define MSAC 0x62 /* Multi Size Aperture Control */ +#define SWSCI 0xe8 /* SWSCI enable */ +#define ASLS 0xfc /* OpRegion Base */ + +/* + * MCHBAR + */ + +#define MCHBAR8(x) *((volatile u8 *)(DEFAULT_MCHBAR + x)) +#define MCHBAR16(x) *((volatile u16 *)(DEFAULT_MCHBAR + x)) +#define MCHBAR32(x) *((volatile u32 *)(DEFAULT_MCHBAR + x)) +#define MCHBAR32_OR(x, or) MCHBAR32(x) = (MCHBAR32(x) | (or)) + +#define SSKPD 0x5d14 /* 16bit (scratchpad) */ +#define BIOS_RESET_CPL 0x5da8 /* 8bit */ + +/* + * EPBAR - Egress Port Root Complex Register Block + */ + +#define EPBAR8(x) *((volatile u8 *)(DEFAULT_EPBAR + x)) +#define EPBAR16(x) *((volatile u16 *)(DEFAULT_EPBAR + x)) +#define EPBAR32(x) *((volatile u32 *)(DEFAULT_EPBAR + x)) + +#define EPPVCCAP1 0x004 /* 32bit */ +#define EPPVCCAP2 0x008 /* 32bit */ + +#define EPVC0RCAP 0x010 /* 32bit */ +#define EPVC0RCTL 0x014 /* 32bit */ +#define EPVC0RSTS 0x01a /* 16bit */ + +#define EPVC1RCAP 0x01c /* 32bit */ +#define EPVC1RCTL 0x020 /* 32bit */ +#define EPVC1RSTS 0x026 /* 16bit */ + +#define EPVC1MTS 0x028 /* 32bit */ +#define EPVC1IST 0x038 /* 64bit */ + +#define EPESD 0x044 /* 32bit */ + +#define EPLE1D 0x050 /* 32bit */ +#define EPLE1A 0x058 /* 64bit */ +#define EPLE2D 0x060 /* 32bit */ +#define EPLE2A 0x068 /* 64bit */ + +#define PORTARB 0x100 /* 256bit */ + +/* + * DMIBAR + */ + +#define DMIBAR8(x) *((volatile u8 *)(DEFAULT_DMIBAR + x)) +#define DMIBAR16(x) *((volatile u16 *)(DEFAULT_DMIBAR + x)) +#define DMIBAR32(x) *((volatile u32 *)(DEFAULT_DMIBAR + x)) + +#define DMIVCECH 0x000 /* 32bit */ +#define DMIPVCCAP1 0x004 /* 32bit */ +#define DMIPVCCAP2 0x008 /* 32bit */ + +#define DMIPVCCCTL 0x00c /* 16bit */ + +#define DMIVC0RCAP 0x010 /* 32bit */ +#define DMIVC0RCTL0 0x014 /* 32bit */ +#define DMIVC0RSTS 0x01a /* 16bit */ + +#define DMIVC1RCAP 0x01c /* 32bit */ +#define DMIVC1RCTL 0x020 /* 32bit */ +#define DMIVC1RSTS 0x026 /* 16bit */ + +#define DMILE1D 0x050 /* 32bit */ +#define DMILE1A 0x058 /* 64bit */ +#define DMILE2D 0x060 /* 32bit */ +#define DMILE2A 0x068 /* 64bit */ + +#define DMILCAP 0x084 /* 32bit */ +#define DMILCTL 0x088 /* 16bit */ +#define DMILSTS 0x08a /* 16bit */ + +#define DMICTL1 0x0f0 /* 32bit */ +#define DMICTL2 0x0fc /* 32bit */ + +#define DMICC 0x208 /* 32bit */ + +#define DMIDRCCFG 0xeb4 /* 32bit */ + +#ifndef __ASSEMBLER__ +static inline void barrier(void) { asm("" ::: "memory"); } + +#define PCI_DEVICE_ID_SB 0x0104 +#define PCI_DEVICE_ID_IB 0x0154 + +#ifdef __SMM__ +void intel_sandybridge_finalize_smm(void); +#else /* !__SMM__ */ +int bridge_silicon_revision(void); +void sandybridge_early_initialization(int chipset_type); +void sandybridge_late_initialization(void); + +/* 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 /* !__SMM__ */ + + +#define MRC_DATA_ALIGN 0x1000 +#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24)) + +#if !defined(__PRE_RAM__) +#include "gma.h" +int init_igd_opregion(igd_opregion_t *igd_opregion); +#endif + +#endif +#endif +#endif /* __NORTHBRIDGE_INTEL_SANDYBRIDGE_SANDYBRIDGE_H__ */ diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h new file mode 100644 index 0000000000..b63149f61f --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * 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. + */ + +#ifndef _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ +#define _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ + +#include + +#define BUS0 0 + +/* NB PCIe PEG slot */ +#define NB_PEG_DEV 0x01 +#define NB_PEG_FUNC 0 +# define NB_PEG_DEVFN PCI_DEVFN(NB_PEG_DEV, NB_PEG_FUNC) +#define PCIE_CTRL1_FUNC 1 +# define PCIE_CTRL1_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL1_FUNC) +#define PCIE_CTRL2_FUNC 2 +# define PCIE_CTRL2_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL2_FUNC) + +/* Onboard Graphics */ +#define GFX_DEV 0x02 +#define GFX_FUNC 0 +# define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC) + +/* NB PCIe slot */ +#define NB_PCIE_DEV 0x06 +#define NB_PCIE_FUNC 0 +# define NB_PCIE_DEVFN PCI_DEVFN(NB_PCIE_DEV, NB_PCIE_FUNC) + +#endif /* _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ */ diff --git a/src/northbridge/intel/fsp_sandybridge/ram_calc.c b/src/northbridge/intel/fsp_sandybridge/ram_calc.c new file mode 100644 index 0000000000..37d74fc617 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/ram_calc.c @@ -0,0 +1,38 @@ +/* + * This file is part of the coreboot project. + * + * 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. + */ + +#define __SIMPLE_DEVICE__ + +#include +#include +#include +#include "northbridge.h" + +static uintptr_t smm_region_start(void) +{ + /* Base of TSEG is top of usable DRAM */ + uintptr_t tom = pci_read_config32(PCI_DEV(0,0,0), TSEG) & ~(1UL << 0); + return tom; +} + +void *cbmem_top(void) +{ + return (void *) (smm_region_start() - FSP_RESERVE_MEMORY_SIZE); +} diff --git a/src/northbridge/intel/fsp_sandybridge/raminit.c b/src/northbridge/intel/fsp_sandybridge/raminit.c new file mode 100644 index 0000000000..408b4b0611 --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/raminit.c @@ -0,0 +1,76 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "raminit.h" +#include "northbridge.h" + +static const char* ecc_decoder[] = { + "inactive", + "active on IO", + "disabled on IO", + "active" +}; + +/* + * Dump in the log memory controller configuration as read from the memory + * controller registers. + */ +void report_memory_config(void) +{ + u32 addr_decoder_common, addr_decode_ch[2]; + int i; + + addr_decoder_common = MCHBAR32(0x5000); + addr_decode_ch[0] = MCHBAR32(0x5004); + addr_decode_ch[1] = MCHBAR32(0x5008); + + printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", + (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100); + printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n", + addr_decoder_common & 3, + (addr_decoder_common >> 2) & 3, + (addr_decoder_common >> 4) & 3); + + for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { + u32 ch_conf = addr_decode_ch[i]; + printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", + i, ch_conf); + printk(BIOS_DEBUG, " ECC %s\n", + ecc_decoder[(ch_conf >> 24) & 3]); + printk(BIOS_DEBUG, " enhanced interleave mode %s\n", + ((ch_conf >> 22) & 1) ? "on" : "off"); + printk(BIOS_DEBUG, " rank interleave %s\n", + ((ch_conf >> 21) & 1) ? "on" : "off"); + printk(BIOS_DEBUG, " DIMMA %d MB width x%d %s rank%s\n", + ((ch_conf >> 0) & 0xff) * 256, + ((ch_conf >> 19) & 1) ? 16 : 8, + ((ch_conf >> 17) & 1) ? "dual" : "single", + ((ch_conf >> 16) & 1) ? "" : ", selected"); + printk(BIOS_DEBUG, " DIMMB %d MB width x%d %s rank%s\n", + ((ch_conf >> 8) & 0xff) * 256, + ((ch_conf >> 20) & 1) ? 16 : 8, + ((ch_conf >> 18) & 1) ? "dual" : "single", + ((ch_conf >> 16) & 1) ? ", selected" : ""); + } +} diff --git a/src/northbridge/intel/fsp_sandybridge/raminit.h b/src/northbridge/intel/fsp_sandybridge/raminit.h new file mode 100644 index 0000000000..c97b64cb2c --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/raminit.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 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. + * + * 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. + */ + +#ifndef RAMINIT_H +#define RAMINIT_H + +void report_memory_config(void); + +#endif /* RAMINIT_H */ diff --git a/src/northbridge/intel/fsp_sandybridge/report_platform.c b/src/northbridge/intel/fsp_sandybridge/report_platform.c new file mode 100644 index 0000000000..e661487a6f --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/report_platform.c @@ -0,0 +1,114 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 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. + */ + +#include +#include +#include + +#if CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X +#include +#endif + +#include +#include "northbridge.h" + +static void report_cpu_info(void) +{ + struct cpuid_result cpuidr; + u32 i, index; + char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */ + int vt, txt, aes; + const char *mode[] = {"NOT ", ""}; + + index = 0x80000000; + cpuidr = cpuid(index); + if (cpuidr.eax < 0x80000004) { + strcpy(cpu_string, "Platform info not available"); + } else { + u32 *p = (u32*) cpu_string; + for (i = 2; i <= 4 ; i++) { + cpuidr = cpuid(index + i); + *p++ = cpuidr.eax; + *p++ = cpuidr.ebx; + *p++ = cpuidr.ecx; + *p++ = cpuidr.edx; + } + } + /* Skip leading spaces in CPU name string */ + while (cpu_name[0] == ' ') + cpu_name++; + + cpuidr = cpuid(1); + printk(BIOS_DEBUG, "CPU id(%x): %s\n", cpuidr.eax, cpu_name); + aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0; + txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0; + vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0; + printk(BIOS_DEBUG, "AES %ssupported, TXT %ssupported, VT %ssupported\n", + mode[aes], mode[txt], mode[vt]); +} + +/* The PCI id name match comes from Intel document 472178 */ +static struct { + u16 dev_id; + const char *dev_name; +} pch_table [] = { + {0x1E41, "Desktop Sample"}, + {0x1E42, "Mobile Sample"}, + {0x1E43, "SFF Sample"}, + {0x1E44, "Z77"}, + {0x1E45, "H71"}, + {0x1E46, "Z75"}, + {0x1E47, "Q77"}, + {0x1E48, "Q75"}, + {0x1E49, "B75"}, + {0x1E4A, "H77"}, + {0x1E53, "C216"}, + {0x1E55, "QM77"}, + {0x1E56, "QS77"}, + {0x1E58, "UM77"}, + {0x1E57, "HM77"}, + {0x1E59, "HM76"}, + {0x1E5D, "HM75"}, + {0x1E5E, "HM70"}, + {0x1E5F, "NM70"}, +}; + +static void report_pch_info(void) +{ + int i; + u16 dev_id = pci_read_config16(PCH_LPC_DEV, 2); + + + const char *pch_type = "Unknown"; + for (i = 0; i < ARRAY_SIZE(pch_table); i++) { + if (pch_table[i].dev_id == dev_id) { + pch_type = pch_table[i].dev_name; + break; + } + } + printk (BIOS_DEBUG, "PCH type: %s, device id: %x, rev id %x\n", + pch_type, dev_id, pci_read_config8(PCH_LPC_DEV, 8)); +} + +void report_platform_info(void) +{ + report_cpu_info(); + report_pch_info(); +} diff --git a/src/northbridge/intel/fsp_sandybridge/udelay.c b/src/northbridge/intel/fsp_sandybridge/udelay.c new file mode 100644 index 0000000000..e6dcbf180e --- /dev/null +++ b/src/northbridge/intel/fsp_sandybridge/udelay.c @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +/** + * Intel SandyBridge/IvyBridge CPUs always run the TSC at BCLK=100MHz + */ + +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; /* On Core/Core2 this is divided by 4 */ + 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))); +} -- cgit v1.2.3