diff options
author | Mariusz Szafranski <mariuszx.szafranski@intel.com> | 2017-08-02 17:28:17 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2017-09-05 13:39:54 +0000 |
commit | a404133547c98094a326f60b83e1576ba94b8c06 (patch) | |
tree | 59847d084c0462833878627491cfbf3e67fca4af | |
parent | 84c4987eae9f8686e6d92e38ee18744d69576f2d (diff) | |
download | coreboot-a404133547c98094a326f60b83e1576ba94b8c06.tar.xz |
soc/intel/denverton_ns: Add support for Intel Atom C3000 SoC
This change adds support for Intel Atom C3000 SoC
("Denverton" and "Denverton-NS").
Code is partially based on Apollo Lake/Skylake code.
Change-Id: I53d69aede3b92f1fe06b74a96cc40187fb9825f1
Signed-off-by: Mariusz Szafranski <mariuszx.szafranski@intel.com>
Reviewed-on: https://review.coreboot.org/20861
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: FEI WANG <wangfei.jimei@gmail.com>
72 files changed, 9426 insertions, 0 deletions
diff --git a/src/soc/intel/denverton_ns/Kconfig b/src/soc/intel/denverton_ns/Kconfig new file mode 100644 index 0000000000..cb13f3f56b --- /dev/null +++ b/src/soc/intel/denverton_ns/Kconfig @@ -0,0 +1,182 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2014 - 2017 Intel Corporation. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +config SOC_INTEL_DENVERTON_NS + bool + help + Intel Denverton-NS SoC support + +if SOC_INTEL_DENVERTON_NS + +config CPU_SPECIFIC_OPTIONS + def_bool y + select ARCH_BOOTBLOCK_X86_32 + select ARCH_RAMSTAGE_X86_32 + select ARCH_ROMSTAGE_X86_32 + select ARCH_VERSTAGE_X86_32 + select BOOTBLOCK_CONSOLE + select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH + select BOOT_DEVICE_SUPPORTS_WRITES + select POSTCAR_CONSOLE + select SOC_INTEL_COMMON + select SOC_INTEL_COMMON_RESET + select PLATFORM_USES_FSP2_0 + select HAVE_HARD_RESET + select POSTCAR_STAGE + select C_ENVIRONMENT_BOOTBLOCK + select IOAPIC + select HAVE_SMI_HANDLER + select SMM_TSEG + select CACHE_MRC_SETTINGS + select RELOCATABLE_RAMSTAGE # Build fails if this is not selected + select PARALLEL_MP + select SMP + select SOC_INTEL_COMMON_BLOCK +# select SOC_INTEL_COMMON_BLOCK_SA + select SOC_INTEL_COMMON_BLOCK_FAST_SPI + select TSC_CONSTANT_RATE + select TSC_MONOTONIC_TIMER + select TSC_SYNC_MFENCE + select UDELAY_TSC + +config FSP_T_ADDR + hex "Intel FSP-T (temp ram init) binary location" + depends on ADD_FSP_BINARIES && FSP_CAR + default 0xfff30000 + help + The memory location of the Intel FSP-T binary for this platform. + +config FSP_M_ADDR + hex "Intel FSP-M (memory init) binary location" + depends on ADD_FSP_BINARIES + default 0xfff32000 + help + The memory location of the Intel FSP-M binary for this platform. + +config FSP_S_ADDR + hex "Intel FSP-S (silicon init) binary location" + depends on ADD_FSP_BINARIES + default 0xfffc3000 + help + The memory location of the Intel FSP-S binary for this platform. + +# CAR memory layout on DENVERTON_NS hardware: +## CAR base address - 0xfef00000 +## CAR size 1MB - 0x100 (0xfff00) +## coreboot usage: +## DCACHE base - 0xfef00000 +## DCACHE size - 0xb0000 +## FSP usage: +## FSP base - 0xfefb0000 +## FSP size - 0x50000 - 0x100 (0x4ff00) +config MAX_CPUS + int + default 16 + +config DCACHE_RAM_BASE + hex + default 0xfef00000 + +config DCACHE_RAM_SIZE + hex + default 0xb0000 if FSP_CAR + default 0x100000 if !FSP_CAR + +config DCACHE_BSP_STACK_SIZE + hex + default 0x10000 + +config CPU_MICROCODE_CBFS_LOC + hex + default 0xfff20040 + +config CPU_MICROCODE_CBFS_LEN + hex + default 0x0ff80 + +config SMM_TSEG_SIZE + hex + default 0x200000 + +config SMM_RESERVED_SIZE + hex + default 0x000000 + +config IQAT_ENABLE + bool "Enable IQAT" + default y + +config IQAT_MEMORY_REGION_SIZE + depends on IQAT_ENABLE + hex + default 0x100000 + help + Do not change this value + +config HSUART_DEV + hex + default 0x1a + +config HSUART_FUNC + hex + default 0x0 + +choice + prompt "UART mode selection" + default NON_LEGACY_UART_MODE + +config NON_LEGACY_UART_MODE + bool "Non Legacy Mode" + help + Disable legacy UART mode + +config LEGACY_UART_MODE + bool "Legacy Mode" + help + Enable legacy UART mode +endchoice + +config ENABLE_HSUART + depends on (!DRIVERS_UART_8250IO && NON_LEGACY_UART_MODE) + bool "Enable High-speed UART debug port selected by UART_FOR_CONSOLE." + default n + select CONSOLE_SERIAL + select DRIVERS_UART + select DRIVERS_UART_8250MEM + +config CONSOLE_UART_BASE_ADDRESS + depends on ENABLE_HSUART + hex "MMIO base address for UART" + default 0xd4000000 + +config C_ENV_BOOTBLOCK_SIZE + hex + default 0x8000 + +config DENVERTON_NS_CAR_NEM_ENHANCED + bool "Enhanced Non-evict mode" + depends on !FSP_CAR + default y + select SOC_INTEL_COMMON_BLOCK_CAR + select INTEL_CAR_NEM_ENHANCED + help + A current limitation of NEM (Non-Evict mode) is that code and data sizes + are derived from the requirement to not write out any modified cache line. + With NEM, if there is no physical memory behind the cached area, + the modified data will be lost and NEM results will be inconsistent. + ENHANCED NEM guarantees that modified data is always + kept in cache while clean data is replaced. + +endif ## SOC_INTEL_DENVERTON_NS diff --git a/src/soc/intel/denverton_ns/Makefile.inc b/src/soc/intel/denverton_ns/Makefile.inc new file mode 100644 index 0000000000..5feea13398 --- /dev/null +++ b/src/soc/intel/denverton_ns/Makefile.inc @@ -0,0 +1,94 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2014 - 2017 Intel Corporation. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +ifeq ($(CONFIG_SOC_INTEL_DENVERTON_NS),y) + +subdirs-y += ../../../cpu/intel/microcode +subdirs-y += ../../../cpu/intel/turbo +subdirs-y += ../../../cpu/x86/lapic +subdirs-y += ../../../cpu/x86/mtrr +subdirs-$(CONFIG_HAVE_SMI_HANDLER) += ../../../cpu/x86/smm +subdirs-y += ../../../cpu/x86/tsc +subdirs-y += ../../../cpu/x86/cache + +bootblock-$(CONFIG_FSP_CAR)+= bootblock/cache_as_ram_fsp.S +bootblock-y += bootblock/bootblock.c +bootblock-y += spi.c +bootblock-y += tsc_freq.c +bootblock-$(CONFIG_CONSOLE_SERIAL) += bootblock/uart.c +bootblock-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c + +postcar-y += memmap.c +postcar-$(CONFIG_FSP_CAR) += exit_car_fsp.S +postcar-y += spi.c +postcar-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c + +romstage-y += memmap.c +romstage-y += reset.c +romstage-y += romstage.c +romstage-y += tsc_freq.c +romstage-y += gpio.c +romstage-y += soc_util.c +romstage-y += spi.c +romstage-y += fiamux.c +romstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c +romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c +romstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c + +ramstage-y += memmap.c +ramstage-y += systemagent.c +ramstage-y += reset.c +ramstage-y += chip.c +ramstage-y += soc_util.c +ramstage-y += uart.c +ramstage-y += xhci.c +ramstage-y += csme_ie_kt.c +ramstage-y += lpc.c +ramstage-y += pmc.c +ramstage-y += npk.c +ramstage-y += sata.c +ramstage-y += cpu.c +ramstage-y += tsc_freq.c +ramstage-y += spi.c +ramstage-y += fiamux.c +ramstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c +ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c +ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smm.c +ramstage-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c +ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c +ramstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c + +smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += soc_util.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c +smm-$(CONFIG_SPI_FLASH_SMM) += spi.c +smm-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c + +verstage-y += memmap.c +verstage-y += reset.c +verstage-y += spi.c +verstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c + +CPPFLAGS_common += -I$(src)/soc/intel/denverton_ns/include +CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp2_0/denverton_ns + +##Set FSP binary blobs memory location + +$(CONFIG_FSP_T_CBFS)-options := -b $(CONFIG_FSP_T_ADDR) --xip +$(CONFIG_FSP_M_CBFS)-options := -b $(CONFIG_FSP_M_ADDR) --xip +$(CONFIG_FSP_S_CBFS)-options := -b $(CONFIG_FSP_S_ADDR) --xip + +endif ## CONFIG_SOC_INTEL_DENVERTON_NS diff --git a/src/soc/intel/denverton_ns/acpi.c b/src/soc/intel/denverton_ns/acpi.c new file mode 100644 index 0000000000..7386db34b8 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi.c @@ -0,0 +1,332 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <arch/acpi.h> +#include <arch/acpigen.h> +#include <arch/smp/mpspec.h> +#include <cpu/x86/smm.h> +#include <string.h> +#include <device/pci.h> +#include <cpu/cpu.h> +#include <cbmem.h> + +#include <soc/acpi.h> +#include <soc/cpu.h> +#include <soc/soc_util.h> +#include <soc/pmc.h> +#include <soc/systemagent.h> + +void acpi_init_gnvs(global_nvs_t *gnvs) +{ + /* CPU core count */ + gnvs->pcnt = dev_count_cpu(); + + /* Top of Low Memory (start of resource allocation) */ + gnvs->tolm = top_of_32bit_ram(); + +#if IS_ENABLED(CONFIG_CONSOLE_CBMEM) + /* Update the mem console pointer. */ + gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE); +#endif + + /* MMIO Low/High & TSEG base and length */ + gnvs->mmiob = (u32)get_top_of_low_memory(); + gnvs->mmiol = (u32)(get_pciebase() - 1); + gnvs->mmiohb = (u64)get_top_of_upper_memory(); + gnvs->mmiohl = (u64)(((u64)1 << CONFIG_CPU_ADDR_BITS) - 1); + gnvs->tsegb = (u32)get_tseg_memory(); + gnvs->tsegl = (u32)(get_top_of_low_memory() - get_tseg_memory()); +} + +static int acpi_sci_irq(void) +{ + int scis, sci_irq; + device_t dev = get_pmc_dev(); + + if (!dev) + return 0; + + /* Determine how SCI is routed. */ + scis = pci_read_config32(dev, PMC_ACPI_CNT) & PMC_ACPI_CNT_SCIS_MASK; + switch (scis) { + case PMC_ACPI_CNT_SCIS_IRQ9: + case PMC_ACPI_CNT_SCIS_IRQ10: + case PMC_ACPI_CNT_SCIS_IRQ11: + sci_irq = scis - PMC_ACPI_CNT_SCIS_IRQ9 + 9; + break; + case PMC_ACPI_CNT_SCIS_IRQ20: + case PMC_ACPI_CNT_SCIS_IRQ21: + case PMC_ACPI_CNT_SCIS_IRQ22: + case PMC_ACPI_CNT_SCIS_IRQ23: + sci_irq = scis - PMC_ACPI_CNT_SCIS_IRQ20 + 20; + break; + default: + printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n"); + sci_irq = 9; + break; + } + + printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq); + return sci_irq; +} + +unsigned long acpi_fill_mcfg(unsigned long current) +{ + u32 pciexbar_reg; + int max_buses; + + pciexbar_reg = get_pciebase(); + max_buses = get_pcielength(); + + if (!pciexbar_reg) + return current; + + current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, + pciexbar_reg, 0x0, 0x0, + (u8)(max_buses - 1)); + + return current; +} + +void acpi_fill_in_fadt(acpi_fadt_t *fadt) +{ + u16 pmbase = get_pmbase(); + + /* System Management */ + fadt->sci_int = acpi_sci_irq(); +#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) + fadt->smi_cmd = APM_CNT; + fadt->acpi_enable = APM_CNT_ACPI_ENABLE; + fadt->acpi_disable = APM_CNT_ACPI_DISABLE; +#else + fadt->smi_cmd = 0x00; + fadt->acpi_enable = 0x00; + fadt->acpi_disable = 0x00; +#endif + + /* Power Control */ + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = 0; + + fadt->pm1a_evt_blk = pmbase + PM1_STS; + fadt->pm1b_evt_blk = 0x0; + fadt->pm1a_cnt_blk = pmbase + PM1_CNT; + fadt->pm1b_cnt_blk = 0x0; + fadt->pm2_cnt_blk = pmbase + PM2_CNT; + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->gpe0_blk = pmbase + GPE0_STS; + fadt->gpe1_blk = 0; + + /* Control Registers - Length */ + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 8; + fadt->gpe1_blk_len = 0; + fadt->gpe1_base = 0; + fadt->cst_cnt = 0; + fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; + fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; + fadt->flush_size = 0; /* set to 0 if WBINVD is 1 in flags */ + fadt->flush_stride = 0; /* set to 0 if WBINVD is 1 in flags */ + fadt->duty_offset = 1; + fadt->duty_width = 0; + + /* RTC Registers */ + fadt->day_alrm = 0x0D; + fadt->mon_alrm = 0x00; + fadt->century = 0x00; + fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042; + + fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | + ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | + ACPI_FADT_RESET_REGISTER | ACPI_FADT_SLEEP_TYPE | + ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK; + + /* Reset Register */ + fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->reset_reg.bit_width = 8; + fadt->reset_reg.bit_offset = 0; + fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; + fadt->reset_reg.addrl = 0xCF9; + fadt->reset_reg.addrh = 0x00; + fadt->reset_value = 6; + + /* PM1 Status & PM1 Enable */ + fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm1a_evt_blk.bit_width = 32; + fadt->x_pm1a_evt_blk.bit_offset = 0; + fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk; + fadt->x_pm1a_evt_blk.addrh = 0x00; + + fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm1b_evt_blk.bit_width = 0; + fadt->x_pm1b_evt_blk.bit_offset = 0; + fadt->x_pm1b_evt_blk.access_size = 0; + fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk; + fadt->x_pm1b_evt_blk.addrh = 0x00; + + /* PM1 Control Registers */ + fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm1a_cnt_blk.bit_width = 16; + fadt->x_pm1a_cnt_blk.bit_offset = 0; + fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; + fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk; + fadt->x_pm1a_cnt_blk.addrh = 0x00; + + fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm1b_cnt_blk.bit_width = 0; + fadt->x_pm1b_cnt_blk.bit_offset = 0; + fadt->x_pm1b_cnt_blk.access_size = 0; + fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk; + fadt->x_pm1b_cnt_blk.addrh = 0x00; + + /* PM2 Control Registers */ + fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm2_cnt_blk.bit_width = 8; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; + fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk; + fadt->x_pm2_cnt_blk.addrh = 0x00; + + /* PM1 Timer Register */ + fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm_tmr_blk.bit_width = 32; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk; + fadt->x_pm_tmr_blk.addrh = 0x00; + + /* General-Purpose Event Registers */ + fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + EventEnable */ + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + fadt->x_gpe0_blk.addrl = fadt->gpe0_blk; + fadt->x_gpe0_blk.addrh = 0x00; + + fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_gpe1_blk.bit_width = 0; + fadt->x_gpe1_blk.bit_offset = 0; + fadt->x_gpe1_blk.access_size = 0; + fadt->x_gpe1_blk.addrl = fadt->gpe1_blk; + fadt->x_gpe1_blk.addrh = 0x00; +} + +void generate_cpu_entries(device_t device) +{ + int core; + int pcontrol_blk = get_pmbase(), plen = 6; + int num_cpus = get_cpu_count(); + + for (core = 0; core < num_cpus; core++) { + if (core > 0) { + pcontrol_blk = 0; + plen = 0; + } + + /* Generate processor \_PR.CPUx */ + acpigen_write_processor(core, pcontrol_blk, plen); + + /* Generate P-state tables */ + + /* Generate C-state tables */ + + /* Generate T-state tables */ + + acpigen_pop_len(); + } +} + +unsigned long acpi_madt_irq_overrides(unsigned long current) +{ + int sci_irq = acpi_sci_irq(); + acpi_madt_irqoverride_t *irqovr; + uint16_t sci_flags = MP_IRQ_TRIGGER_LEVEL; + + /* INT_SRC_OVR */ + irqovr = (acpi_madt_irqoverride_t *)current; + current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0); + + if (sci_irq >= 20) + sci_flags |= MP_IRQ_POLARITY_LOW; + else + sci_flags |= MP_IRQ_POLARITY_HIGH; + + irqovr = (acpi_madt_irqoverride_t *)current; + current += acpi_create_madt_irqoverride(irqovr, 0, (u8)sci_irq, sci_irq, + sci_flags); + + return current; +} + +unsigned long southcluster_write_acpi_tables(device_t device, + unsigned long current, + struct acpi_rsdp *rsdp) +{ + acpi_header_t *ssdt2; + + current = acpi_write_hpet(device, current, rsdp); + current = (ALIGN(current, 16)); + + ssdt2 = (acpi_header_t *)current; + memset(ssdt2, 0, sizeof(acpi_header_t)); + acpi_create_serialio_ssdt(ssdt2); + if (ssdt2->length) { + current += ssdt2->length; + acpi_add_table(rsdp, ssdt2); + printk(BIOS_DEBUG, "ACPI: * SSDT2 @ %p Length %x\n", ssdt2, + ssdt2->length); + current = (ALIGN(current, 16)); + } else { + ssdt2 = NULL; + printk(BIOS_DEBUG, "ACPI: * SSDT2 not generated.\n"); + } + + printk(BIOS_DEBUG, "current = %lx\n", current); + + return current; +} + +void southcluster_inject_dsdt(device_t device) +{ + global_nvs_t *gnvs; + + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + if (!gnvs) { + gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(*gnvs)); + if (gnvs) + memset(gnvs, 0, sizeof(*gnvs)); + } + + if (gnvs) { + acpi_create_gnvs(gnvs); + acpi_save_gnvs((unsigned long)gnvs); + /* And tell SMI about it */ + smm_setup_structures(gnvs, NULL, NULL); + + /* Add it to DSDT. */ + acpigen_write_scope("\\"); + acpigen_write_name_dword("NVSA", (u32)gnvs); + acpigen_pop_len(); + } +} + +__attribute__((weak)) void acpi_create_serialio_ssdt(acpi_header_t *ssdt) {} diff --git a/src/soc/intel/denverton_ns/acpi/cpu.asl b/src/soc/intel/denverton_ns/acpi/cpu.asl new file mode 100644 index 0000000000..00dc6c792d --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/cpu.asl @@ -0,0 +1,141 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* These devices are created at runtime */ +External (\_PR.CP00, DeviceObj) +External (\_PR.CP01, DeviceObj) +External (\_PR.CP02, DeviceObj) +External (\_PR.CP03, DeviceObj) +External (\_PR.CP04, DeviceObj) +External (\_PR.CP05, DeviceObj) +External (\_PR.CP06, DeviceObj) +External (\_PR.CP07, DeviceObj) +External (\_PR.CP08, DeviceObj) +External (\_PR.CP09, DeviceObj) +External (\_PR.CP10, DeviceObj) +External (\_PR.CP11, DeviceObj) +External (\_PR.CP12, DeviceObj) +External (\_PR.CP13, DeviceObj) +External (\_PR.CP14, DeviceObj) +External (\_PR.CP15, DeviceObj) + +/* Notify OS to re-read CPU tables, assuming ^2 CPU count */ +Method (PNOT) +{ + If (LGreaterEqual (\PCNT, 2)) { + Notify (\_PR.CP00, 0x81) // _CST + Notify (\_PR.CP01, 0x81) // _CST + } + If (LGreaterEqual (\PCNT, 4)) { + Notify (\_PR.CP02, 0x81) // _CST + Notify (\_PR.CP03, 0x81) // _CST + } + If (LGreaterEqual (\PCNT, 8)) { + Notify (\_PR.CP04, 0x81) // _CST + Notify (\_PR.CP05, 0x81) // _CST + Notify (\_PR.CP06, 0x81) // _CST + Notify (\_PR.CP07, 0x81) // _CST + } + If (LGreaterEqual (\PCNT, 16)) { + Notify (\_PR.CP08, 0x81) // _CST + Notify (\_PR.CP09, 0x81) // _CST + Notify (\_PR.CP10, 0x81) // _CST + Notify (\_PR.CP11, 0x81) // _CST + Notify (\_PR.CP12, 0x81) // _CST + Notify (\_PR.CP13, 0x81) // _CST + Notify (\_PR.CP14, 0x81) // _CST + Notify (\_PR.CP15, 0x81) // _CST + } +} + +/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */ +Method (PPCN) +{ + If (LGreaterEqual (\PCNT, 2)) { + Notify (\_PR.CP00, 0x80) // _PPC + Notify (\_PR.CP01, 0x80) // _PPC + } + If (LGreaterEqual (\PCNT, 4)) { + Notify (\_PR.CP02, 0x80) // _PPC + Notify (\_PR.CP03, 0x80) // _PPC + } + If (LGreaterEqual (\PCNT, 8)) { + Notify (\_PR.CP04, 0x80) // _PPC + Notify (\_PR.CP05, 0x80) // _PPC + Notify (\_PR.CP06, 0x80) // _PPC + Notify (\_PR.CP07, 0x80) // _PPC + } + If (LGreaterEqual (\PCNT, 16)) { + Notify (\_PR.CP08, 0x80) // _PPC + Notify (\_PR.CP09, 0x80) // _PPC + Notify (\_PR.CP10, 0x80) // _PPC + Notify (\_PR.CP11, 0x80) // _PPC + Notify (\_PR.CP12, 0x80) // _PPC + Notify (\_PR.CP13, 0x80) // _PPC + Notify (\_PR.CP14, 0x80) // _PPC + Notify (\_PR.CP15, 0x80) // _PPC + } +} + +/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */ +Method (TNOT) +{ + If (LGreaterEqual (\PCNT, 2)) { + Notify (\_PR.CP00, 0x82) // _TPC + Notify (\_PR.CP01, 0x82) // _TPC + } + If (LGreaterEqual (\PCNT, 4)) { + Notify (\_PR.CP02, 0x82) // _TPC + Notify (\_PR.CP03, 0x82) // _TPC + } + If (LGreaterEqual (\PCNT, 8)) { + Notify (\_PR.CP04, 0x82) // _TPC + Notify (\_PR.CP05, 0x82) // _TPC + Notify (\_PR.CP06, 0x82) // _TPC + Notify (\_PR.CP07, 0x82) // _TPC + } + If (LGreaterEqual (\PCNT, 16)) { + Notify (\_PR.CP08, 0x82) // _TPC + Notify (\_PR.CP09, 0x82) // _TPC + Notify (\_PR.CP10, 0x82) // _TPC + Notify (\_PR.CP11, 0x82) // _TPC + Notify (\_PR.CP12, 0x82) // _TPC + Notify (\_PR.CP13, 0x82) // _TPC + Notify (\_PR.CP14, 0x82) // _TPC + Notify (\_PR.CP15, 0x82) // _TPC + } +} + +/* Return a package containing enabled processor entries */ +Method (PPKG) +{ + If (LGreaterEqual (\PCNT, 16)) { + Return (Package() {\_PR.CP00, \_PR.CP01, \_PR.CP02, \_PR.CP03, + \_PR.CP04, \_PR.CP05, \_PR.CP06, \_PR.CP07, + \_PR.CP08, \_PR.CP09, \_PR.CP10, \_PR.CP11, + \_PR.CP12, \_PR.CP13, \_PR.CP14, \_PR.CP15}) + } ElseIf (LGreaterEqual (\PCNT, 8)) { + Return (Package() {\_PR.CP00, \_PR.CP01, \_PR.CP02, \_PR.CP03, + \_PR.CP04, \_PR.CP05, \_PR.CP06, \_PR.CP07}) + } ElseIf (LGreaterEqual (\PCNT, 4)) { + Return (Package() {\_PR.CP00, \_PR.CP01, \_PR.CP02, \_PR.CP03}) + } ElseIf (LGreaterEqual (\PCNT, 2)) { + Return (Package() {\_PR.CP00, \_PR.CP01}) + } Else { + Return (Package() {\_PR.CP00}) + } +} diff --git a/src/soc/intel/denverton_ns/acpi/globalnvs.asl b/src/soc/intel/denverton_ns/acpi/globalnvs.asl new file mode 100644 index 0000000000..5ef029e344 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/globalnvs.asl @@ -0,0 +1,103 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* Global Variables */ + +Name(\PICM, 0) // IOAPIC/8259 + +/* Global ACPI memory region. This region is used for passing information + * between coreboot (aka "the system bios"), ACPI, and the SMI handler. + * Since we don't know where this will end up in memory at ACPI compile time, + * we have to fix it up in coreboot's ACPI creation phase. + */ + + +External(NVSA) +OperationRegion (GNVS, SystemMemory, NVSA, 0x2000) +Field (GNVS, ByteAcc, NoLock, Preserve) +{ + /* Miscellaneous */ + Offset (0x00), + OSYS, 16, // 0x00 - Operating System + SMIF, 8, // 0x02 - SMI function + PRM0, 8, // 0x03 - SMI function parameter + PRM1, 8, // 0x04 - SMI function parameter + SCIF, 8, // 0x05 - SCI function + PRM2, 8, // 0x06 - SCI function parameter + PRM3, 8, // 0x07 - SCI function parameter + LCKF, 8, // 0x08 - Global Lock function for EC + PRM4, 8, // 0x09 - Lock function parameter + PRM5, 8, // 0x0a - Lock function parameter + P80D, 32, // 0x0b - Debug port (IO 0x80) value + LIDS, 8, // 0x0f - LID state (open = 1) + PWRS, 8, // 0x10 - Power State (AC = 1) + PCNT, 8, // 0x11 - Processor count + TPMP, 8, // 0x12 - TPM Present and Enabled + TLVL, 8, // 0x13 - Throttle Level + PPCM, 8, // 0x14 - Maximum P-state usable by OS + + /* Device Config */ + Offset (0x20), + S5U0, 8, // 0x20 - Enable USB0 in S5 + S5U1, 8, // 0x21 - Enable USB1 in S5 + S3U0, 8, // 0x22 - Enable USB0 in S3 + S3U1, 8, // 0x23 - Enable USB1 in S3 + TACT, 8, // 0x24 - Thermal Active trip point + TPSV, 8, // 0x25 - Thermal Passive trip point + TCRT, 8, // 0x26 - Thermal Critical trip point + DPTE, 8, // 0x27 - Enable DPTF + + /* Base addresses */ + Offset (0x30), + CMEM, 32, // 0x30 - CBMEM TOC + TOLM, 32, // 0x34 - Top of Low Memory + CBMC, 32, // 0x38 - coreboot mem console pointer + MMOB, 32, // 0x3c - MMIO Base Low Base + MMOL, 32, // 0x40 - MMIO Base Low Limit + MMHB, 64, // 0x44 - MMIO Base High Base + MMHL, 64, // 0x4c - MMIO Base High Limit + TSGB, 32, // 0x54 - TSEG Base + TSSZ, 32, // 0x58 - TSEG Size +} + +/* Set flag to enable USB charging in S3 */ +Method (S3UE) +{ + Store (One, \S3U0) + Store (One, \S3U1) +} + +/* Set flag to disable USB charging in S3 */ +Method (S3UD) +{ + Store (Zero, \S3U0) + Store (Zero, \S3U1) +} + +/* Set flag to enable USB charging in S5 */ +Method (S5UE) +{ + Store (One, \S5U0) + Store (One, \S5U1) +} + +/* Set flag to disable USB charging in S5 */ +Method (S5UD) +{ + Store (Zero, \S5U0) + Store (Zero, \S5U1) +} diff --git a/src/soc/intel/denverton_ns/acpi/irqlinks.asl b/src/soc/intel/denverton_ns/acpi/irqlinks.asl new file mode 100644 index 0000000000..308ef1e688 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/irqlinks.asl @@ -0,0 +1,488 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2015 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +Device (LNKA) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 1) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTA) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLA, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLA, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTA + ShiftLeft(1, And(PRTA, 0x0f), IRQ0) + + Return (RTLA) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTA) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTA, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKB) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 2) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTB) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLB, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLB, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTB + ShiftLeft(1, And(PRTB, 0x0f), IRQ0) + + Return (RTLB) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTB) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTB, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKC) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 3) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTC) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLC, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLC, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTC + ShiftLeft(1, And(PRTC, 0x0f), IRQ0) + + Return (RTLC) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTC) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTC, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKD) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 4) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTD) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLD, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLD, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTD + ShiftLeft(1, And(PRTD, 0x0f), IRQ0) + + Return (RTLD) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTD) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTD, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKE) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 5) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTE) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLE, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLE, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTE + ShiftLeft(1, And(PRTE, 0x0f), IRQ0) + + Return (RTLE) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTE) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTE, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKF) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 6) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTF) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLF, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLF, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTF + ShiftLeft(1, And(PRTF, 0x0f), IRQ0) + + Return (RTLF) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTF) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTF, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKG) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 7) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTG) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLG, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLG, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTG + ShiftLeft(1, And(PRTG, 0x0f), IRQ0) + + Return (RTLG) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTG) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTG, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKH) +{ + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 8) + + // Disable method + Method (_DIS, 0, Serialized) + { + Store (0x80, PRTH) + } + + // Possible Resource Settings for this Link + Name (_PRS, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) + { 6, 7, 10, 11, 12, 14, 15 } + }) + + // Current Resource Settings for this link + Method (_CRS, 0, Serialized) + { + Name (RTLH, ResourceTemplate() + { + IRQ(Level, ActiveLow, Shared) {} + }) + CreateWordField(RTLH, 1, IRQ0) + + // Clear the WordField + Store (Zero, IRQ0) + + // Set the bit from PRTH + ShiftLeft(1, And(PRTH, 0x0f), IRQ0) + + Return (RTLH) + } + + // Set Resource Setting for this IRQ link + Method (_SRS, 1, Serialized) + { + CreateWordField(Arg0, 1, IRQ0) + + // Which bit is set? + FindSetRightBit(IRQ0, Local0) + + Decrement(Local0) + Store(Local0, PRTH) + } + + // Status + Method (_STA, 0, Serialized) + { + If(And(PRTH, 0x80)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} diff --git a/src/soc/intel/denverton_ns/acpi/lpc.asl b/src/soc/intel/denverton_ns/acpi/lpc.asl new file mode 100644 index 0000000000..262ac55cba --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/lpc.asl @@ -0,0 +1,232 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel LPC Bus Device - 0:1f.0 + +Device (LPCB) +{ + Name(_ADR, 0x001f0000) + + OperationRegion(LPC0, PCI_Config, 0x00, 0x100) + Field (LPC0, AnyAcc, NoLock, Preserve) + { + Offset (0x80), // IO Decode Ranges + IOD0, 8, + IOD1, 8, + } + + #include "irqlinks.asl" + + Device(APIC) // IO APIC + { + Name(_HID,EISAID("PNP0003")) + Name(_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, 0xFEC00000, 0x1000) + }) + } + + Device (HPET) + { + Name (_HID, EISAID("PNP0103")) + Name (_CID, 0x010CD041) + + Method (_STA, 0) // Device Status + { + Return (0xF) // Enable and show device + } + + Name(_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, DEFAULT_HPET_ADDR, 0x400) + }) + } + + Device(PIC) // 8259 Interrupt Controller + { + Name(_HID,EISAID("PNP0000")) + Name(_CRS, ResourceTemplate() + { + IO (Decode16, 0x20, 0x20, 0x01, 0x02) + IO (Decode16, 0x24, 0x24, 0x01, 0x02) + IO (Decode16, 0x28, 0x28, 0x01, 0x02) + IO (Decode16, 0x2c, 0x2c, 0x01, 0x02) + IO (Decode16, 0x30, 0x30, 0x01, 0x02) + IO (Decode16, 0x34, 0x34, 0x01, 0x02) + IO (Decode16, 0x38, 0x38, 0x01, 0x02) + IO (Decode16, 0x3c, 0x3c, 0x01, 0x02) + IO (Decode16, 0xa0, 0xa0, 0x01, 0x02) + IO (Decode16, 0xa4, 0xa4, 0x01, 0x02) + IO (Decode16, 0xa8, 0xa8, 0x01, 0x02) + IO (Decode16, 0xac, 0xac, 0x01, 0x02) + IO (Decode16, 0xb0, 0xb0, 0x01, 0x02) + IO (Decode16, 0xb4, 0xb4, 0x01, 0x02) + IO (Decode16, 0xb8, 0xb8, 0x01, 0x02) + IO (Decode16, 0xbc, 0xbc, 0x01, 0x02) + IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02) + IRQNoFlags () { 2 } + }) + } + + Device(LDRC) // LPC device: Resource consumption + { + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 2) + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO + IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO + IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status + IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0x70, 0x70, 0x1, 0x01) // NMI Enable. + IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post + IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI + //IO (Decode16, 0x800, 0x800, 0x1, 0x10) // ACPI I/O trap + + // BIOS ROM shadow memory range + Memory32Fixed(ReadOnly, 0x000E0000, 0x20000) + + // BIOS flash 16MB + Memory32Fixed(ReadOnly,0xFF000000,0x1000000) + }) + } + + Device (RTC) // Real Time Clock + { + Name (_HID, EISAID("PNP0B00")) + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x70, 0x70, 1, 8) +// Disable as Windows doesn't like it, and systems don't seem to use it. +// IRQNoFlags() { 8 } + }) + } + + Device (TIMR) // Intel 8254 timer + { + Name(_HID, EISAID("PNP0100")) + Name(_CRS, ResourceTemplate() + { + IO (Decode16, 0x40, 0x40, 0x01, 0x04) + IO (Decode16, 0x50, 0x50, 0x10, 0x04) + IRQNoFlags() {0} + }) + } + + Device(IUR3) // Internal UART 1 + { + Name(_HID, EISAID("PNP0501")) + + Name(_UID,1) + + // Status Method for internal UART 1. + + Method(_STA,0,Serialized) + { + Return(0x000F) + } + + // Current Resource Setting Method for internal UART 1. + + Method(_CRS,0,Serialized) + { + // Create the Buffer that stores the Resources to + // be returned. + + Name(BUF0,ResourceTemplate() + { + IO(Decode16,0x03F8,0x03F8,0x01,0x08) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16} + }) + + Return(BUF0) + } + } + + Device(IUR4) // Internal UART 2 + { + Name(_HID, EISAID("PNP0501")) + Name(_UID,2) + // Status Method for internal UART 2. + Method(_STA,0,Serialized) + { + Return(0x000F) + } + // Current Resource Setting Method for internal UART 2. + Method(_CRS,0,Serialized) + { + // Create the Buffer that stores the Resources to + // be returned. + Name(BUF0,ResourceTemplate() + { + IO(Decode16,0x02F8,0x02F8,0x01,0x08) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {17} + }) + Return(BUF0) + } + } + + Device(IUR5) // Internal UART 3 + { + Name(_HID, EISAID("PNP0501")) + Name(_UID,3) + // Status Method for internal UART 3. + Method(_STA,0,Serialized) + { + Return(0x000F) + } + // Current Resource Setting Method for internal UART 3. + Method(_CRS,0,Serialized) + { + // Create the Buffer that stores the Resources to + // be returned. + Name(BUF0,ResourceTemplate() + { + IO(Decode16,0x03E8,0x03E8,0x01,0x08) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {18} + }) + Return(BUF0) + } + } + +#ifdef ENABLE_TPM + Device (TPM) // Trusted Platform Module + { + Name(_HID, EISAID("IFX0102")) + Name(_CID, 0x310cd041) + Name(_UID, 1) + + Method(_STA, 0) + { + If (TPMP) { + Return (0xf) + } + Return (0x0) + } + + Name(_CRS, ResourceTemplate() { + IO (Decode16, 0x2e, 0x2e, 0x01, 0x02) + IO (Decode16, 0x6f0, 0x6f0, 0x01, 0x10) + Memory32Fixed (ReadWrite, 0xfed40000, 0x5000) + IRQ (Edge, Activehigh, Exclusive) { 6 } + }) + } +#endif +} diff --git a/src/soc/intel/denverton_ns/acpi/northcluster.asl b/src/soc/intel/denverton_ns/acpi/northcluster.asl new file mode 100644 index 0000000000..bbfa13313a --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/northcluster.asl @@ -0,0 +1,171 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../include/soc/iomap.h" + +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 (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 (0xa8), // Top of Upper Memory + TUUD, 64, + + Offset (0xb8), // TSEGMB + TSEG, 32, + + Offset (0xbc), // Top of Low Used Memory + TLUD, 32, + } +} + +// Current Resource Settings + +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) + + // RAM (0xc0000-0xdffff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c0000, 0x000dffff, 0x00000000, + 0x00020000,,, OPR0) + + // PCI Memory Region (Top of memory-PCIEXBAR) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, 0x00000000, 0xfebfffff, 0x00000000, + 0xfec00000,,, PM01) + +#ifdef ENABLE_TPM + // TPM Area (0xfed40000-0xfed44fff) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000, + 0x00005000,,, TPMR) +#endif + + // PCI Memory Region (TOUUD - 64G) + QWORDMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, 0x00000000, 0x1ffffffff, 0x00000000, + 0x200000000,,, PM02) + +}) // End MCRS + +Method (_CRS, 0, Serialized) +{ + // Find PCI resource area in MCRS + CreateDwordField(MCRS, ^PM01._MIN, PMIN) + CreateDwordField(MCRS, ^PM01._MAX, PMAX) + CreateDwordField(MCRS, ^PM01._LEN, PLEN) + + // MMIO Low is saved in NVS + Store (\MMOB, PMIN) + Store (\MMOL, PMAX) + Add (Subtract (PMAX, PMIN), 1, PLEN) + + // Find PCI resource area in MCRS + CreateQWordField(MCRS, ^PM02._MIN, P2MN) + CreateQWordField(MCRS, ^PM02._MAX, P2MX) + CreateQWordField(MCRS, ^PM02._LEN, P2LN) + + // MMIO High is saved in NVS + Store(\MMHB, P2MN) + Store(\MMHL, P2MX) + Add(Subtract(P2MX,P2MN),1,P2LN) + + Return (MCRS) +} // End _CRS + +/* PCI Device Resource Consumption */ +Device (PDRC) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 1) + + Name (PDRS, ResourceTemplate() { + // PCIEXBAR memory range + Memory32Fixed(ReadOnly, DEFAULT_PCIEXBAR, 0x10000000) + // TSEG + Memory32Fixed(ReadOnly, 0x00000000, 0x00000000, TSMB) + }) + + // Current Resource Settings + Method (_CRS, 0, Serialized) + { + // Fix up 32-bit TSEG + CreateDWordField(PDRS, ^TSMB._BAS, TSMN) + Store(\TSGB, TSMN) + CreateDWordField(PDRS, ^TSMB._LEN, TSLN) + Store(\TSSZ, TSLN) + Return(PDRS) + } +} + +// Global Registers +Device (GREG) { + Name (_ADR, 0x00040000) +} + +// Root Complex Event Collector +Device (RCEC) { + Name (_ADR, 0x00050000) +} + +// Virtual root port 2 +Device (VRP2) { + Name (_ADR, 0x00060000) +} diff --git a/src/soc/intel/denverton_ns/acpi/npk.asl b/src/soc/intel/denverton_ns/acpi/npk.asl new file mode 100644 index 0000000000..dfb5d9c7f1 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/npk.asl @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel NPK Controller 0:1f.7 + +Device (NPK0) +{ + Name (_ADR, 0x001f0007) + + // Northpeak DFX + Method(_STA, 0, NotSerialized) + { + Return(0x0B) + } +} diff --git a/src/soc/intel/denverton_ns/acpi/pcie.asl b/src/soc/intel/denverton_ns/acpi/pcie.asl new file mode 100644 index 0000000000..cb14cf8bb3 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/pcie.asl @@ -0,0 +1,298 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2012 The Chromium OS Authors. All Rights Reserved. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* Intel 6/7 Series PCH PCIe support */ + +// PCI Express Ports + +Method (IRQM, 1, Serialized) { + + /* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */ + Name (IQAA, Package() { + Package() { 0x0000ffff, 0, 0, 16 }, + Package() { 0x0000ffff, 1, 0, 17 }, + Package() { 0x0000ffff, 2, 0, 18 }, + Package() { 0x0000ffff, 3, 0, 19 } }) + Name (IQAP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 } }) + + /* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */ + Name (IQBA, Package() { + Package() { 0x0000ffff, 0, 0, 17 }, + Package() { 0x0000ffff, 1, 0, 18 }, + Package() { 0x0000ffff, 2, 0, 19 }, + Package() { 0x0000ffff, 3, 0, 16 } }) + Name (IQBP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 } }) + + /* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */ + Name (IQCA, Package() { + Package() { 0x0000ffff, 0, 0, 18 }, + Package() { 0x0000ffff, 1, 0, 19 }, + Package() { 0x0000ffff, 2, 0, 16 }, + Package() { 0x0000ffff, 3, 0, 17 } }) + Name (IQCP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 } }) + + /* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */ + Name (IQDA, Package() { + Package() { 0x0000ffff, 0, 0, 19 }, + Package() { 0x0000ffff, 1, 0, 16 }, + Package() { 0x0000ffff, 2, 0, 17 }, + Package() { 0x0000ffff, 3, 0, 18 } }) + Name (IQDP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 } }) + + /* Interrupt Map INTA->INTE, INTB->INTF, INTC->INTG, INTD->INTH */ + Name (IQEA, Package() { + Package() { 0x0000ffff, 0, 0, 20 }, + Package() { 0x0000ffff, 1, 0, 21 }, + Package() { 0x0000ffff, 2, 0, 22 }, + Package() { 0x0000ffff, 3, 0, 23 } }) + Name (IQEP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKF, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKG, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKH, 0 } }) + + /* Interrupt Map INTA->INTF, INTB->INTG, INTC->INTH, INTD->INTE */ + Name (IQFA, Package() { + Package() { 0x0000ffff, 0, 0, 21 }, + Package() { 0x0000ffff, 1, 0, 22 }, + Package() { 0x0000ffff, 2, 0, 23 }, + Package() { 0x0000ffff, 3, 0, 20 } }) + Name (IQFP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKF, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKG, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKH, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKE, 0 } }) + + /* Interrupt Map INTA->INTG, INTB->INTH, INTC->INTE, INTD->INTF */ + Name (IQGA, Package() { + Package() { 0x0000ffff, 0, 0, 22 }, + Package() { 0x0000ffff, 1, 0, 23 }, + Package() { 0x0000ffff, 2, 0, 20 }, + Package() { 0x0000ffff, 3, 0, 21 } }) + Name (IQGP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKG, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKH, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKE, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKF, 0 } }) + + /* Interrupt Map INTA->INTH, INTB->INTE, INTC->INTF, INTD->INTG */ + Name (IQHA, Package() { + Package() { 0x0000ffff, 0, 0, 23 }, + Package() { 0x0000ffff, 1, 0, 20 }, + Package() { 0x0000ffff, 2, 0, 21 }, + Package() { 0x0000ffff, 3, 0, 22 } }) + Name (IQHP, Package() { + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKH, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKE, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKF, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKG, 0 } }) + + Switch (ToInteger (Arg0)) { + /* PCIe Root Port 1 */ + Case (Package() { 1 }) { + If (PICM) { + Return (IQAA) + } Else { + Return (IQAP) + } + } + + /* PCIe Root Port 2 */ + Case (Package() { 2 }) { + If (PICM) { + Return (IQBA) + } Else { + Return (IQBP) + } + } + + /* PCIe Root Port 3 */ + Case (Package() { 3 }) { + If (PICM) { + Return (IQCA) + } Else { + Return (IQCP) + } + } + + /* PCIe Root Port 4 */ + Case (Package() { 4 }) { + If (PICM) { + Return (IQDA) + } Else { + Return (IQDP) + } + } + + /* PCIe Root Port 5 */ + Case (Package() { 5 }) { + If (PICM) { + Return (IQEA) + } Else { + Return (IQEP) + } + } + + /* PCIe Root Port 6 */ + Case (Package() { 6 }) { + If (PICM) { + Return (IQFA) + } Else { + Return (IQFP) + } + } + + /* PCIe Root Port 7 */ + Case (Package() { 7 }) { + If (PICM) { + Return (IQGA) + } Else { + Return (IQGP) + } + } + + /* PCIe Root Port 8 */ + Case (Package() { 8 }) { + If (PICM) { + Return (IQHA) + } Else { + Return (IQHP) + } + } + + Default { + If (PICM) { + Return (IQDA) + } Else { + Return (IQDP) + } + } + } +} + +Device (RP01) +{ + Name (_ADR, 0x00090000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP02) +{ + Name (_ADR, 0x000A0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP03) +{ + Name (_ADR, 0x000B0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP04) +{ + Name (_ADR, 0x000C0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP05) +{ + Name (_ADR, 0x000E0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP06) +{ + Name (_ADR, 0x000F0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP07) +{ + Name (_ADR, 0x00100000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP08) +{ + Name (_ADR, 0x00110000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} diff --git a/src/soc/intel/denverton_ns/acpi/pcie_port.asl b/src/soc/intel/denverton_ns/acpi/pcie_port.asl new file mode 100644 index 0000000000..e0132caa7a --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/pcie_port.asl @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 The Chromium OS Authors. All Rights Reserved. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* Included in each PCIe Root Port device */ + +OperationRegion (RPCS, PCI_Config, 0x00, 0xFF) +Field (RPCS, AnyAcc, NoLock, Preserve) +{ + Offset (0x4c), // Link Capabilities + , 24, + RPPN, 8, // Root Port Number +} diff --git a/src/soc/intel/denverton_ns/acpi/pmc.asl b/src/soc/intel/denverton_ns/acpi/pmc.asl new file mode 100644 index 0000000000..1b85ac8e2f --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/pmc.asl @@ -0,0 +1,39 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel PMC Controller 0:1f.2 + +Device (PMC0) +{ + Name (_ADR, 0x001F0002) + + Device(PDRC) // PMC Device Resource Consumption + { + Name(_HID,EISAID("PNP0C02")) + Name(_UID, 0x10) + + Name(PMCR,ResourceTemplate() + { + IO (Decode16, DEFAULT_PMBASE, DEFAULT_PMBASE, 0x1, 0x80) // ACPI Base + Memory32Fixed(ReadOnly, DEFAULT_PWRM_BASE, 0x1000) // PMC memory range + }) + + Method(_CRS, 0) + { + return(PMCR) + } + } +} diff --git a/src/soc/intel/denverton_ns/acpi/sata.asl b/src/soc/intel/denverton_ns/acpi/sata.asl new file mode 100644 index 0000000000..a210bcc0ba --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/sata.asl @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel SATA Controller 0:13.0 + +Device (SATA) +{ + Name (_ADR, 0x00130000) + + /* TODO */ +} diff --git a/src/soc/intel/denverton_ns/acpi/sata2.asl b/src/soc/intel/denverton_ns/acpi/sata2.asl new file mode 100644 index 0000000000..46be4e4db2 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/sata2.asl @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel SATA Controller 0:14.0 + +Device (SAT2) +{ + Name (_ADR, 0x00140000) + + /* TODO */ +} diff --git a/src/soc/intel/denverton_ns/acpi/sleepstates.asl b/src/soc/intel/denverton_ns/acpi/sleepstates.asl new file mode 100644 index 0000000000..7da84135c2 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/sleepstates.asl @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +Name(\_S0, Package(){0x0,0x0,0x0,0x0}) +//Name(\_S1, Package(){0x1,0x1,0x0,0x0}) +Name(\_S3, Package(){0x5,0x5,0x0,0x0}) +Name(\_S4, Package(){0x6,0x6,0x0,0x0}) +Name(\_S5, Package(){0x7,0x7,0x0,0x0}) diff --git a/src/soc/intel/denverton_ns/acpi/smbus.asl b/src/soc/intel/denverton_ns/acpi/smbus.asl new file mode 100644 index 0000000000..ca0e96323b --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/smbus.asl @@ -0,0 +1,237 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel SMBus Controller 0:1f.4 + +Device (SBUS) +{ + Name (_ADR, 0x001f0004) + +#ifdef ENABLE_SMBUS_METHODS + OperationRegion (SMBP, PCI_Config, 0x00, 0x100) + Field(SMBP, DWordAcc, NoLock, Preserve) + { + Offset(0x40), + , 2, + I2CE, 1 + } + + OperationRegion (SMBI, SystemIO, SMBUS_IO_BASE, 0x20) + Field (SMBI, ByteAcc, NoLock, Preserve) + { + HSTS, 8, // Host Status + , 8, + HCNT, 8, // Host Control + HCMD, 8, // Host Command + TXSA, 8, // Transmit Slave Address + DAT0, 8, // Host Data 0 + DAT1, 8, // Host Data 1 + HBDB, 8, // Host Block Data Byte + PECK, 8, // Packet Error Check + RXSA, 8, // Receive Slave Address + RXDA, 16, // Receive Slave Data + AUXS, 8, // Auxiliary Status + AUXC, 8, // Auxiliary Control + SLPC, 8, // SMLink Pin Control + SBPC, 8, // SMBus Pin Control + SSTS, 8, // Slave Status + SCMD, 8, // Slave Command + NADR, 8, // Notify Device Address + NDLB, 8, // Notify Data Low Byte + NDLH, 8, // Notify Data High Byte + } + + // Kill all SMBus communication + Method (KILL, 0, Serialized) + { + Or (HCNT, 0x02, HCNT) // Send Kill + Or (HSTS, 0xff, HSTS) // Clean Status + } + + // Check if last operation completed + // return Failure = 0, Success = 1 + Method (CMPL, 0, Serialized) + { + Store (4000, Local0) // Timeout 200ms in 50us steps + While (Local0) { + If (And(HSTS, 0x02)) { // Completion Status? + Return (1) // Operation Completed + } Else { + Stall (50) + Decrement (Local0) + If (LEqual(Local0, 0)) { + KILL() + } + } + } + + Return (0) // Failure + } + + + // Wait for SMBus to become ready + Method (SRDY, 0, Serialized) + { + Store (200, Local0) // Timeout 200ms + While (Local0) { + If (And(HSTS, 0x40)) { // IN_USE? + Sleep(1) // Wait 1ms + Decrement(Local0) // timeout-- + If (LEqual(Local0, 0)) { + Return (1) + } + } Else { + Store (0, Local0) // We're ready + } + } + + Store (4000, Local0) // Timeout 200ms (50us * 4000) + While (Local0) { + If (And (HSTS, 0x01)) { // Host Busy? + Stall(50) // Wait 50us + Decrement(Local0) // timeout-- + If (LEqual(Local0, 0)) { + KILL() + } + } Else { + Return (0) // Success + } + } + + Return (1) // Failure + } + + // SMBus Send Byte + // Arg0: Address + // Arg1: Data + // Return: 1 = Success, 0=Failure + + Method (SSXB, 2, Serialized) + { + + // Is the SMBus Controller Ready? + If (SRDY()) { + Return (0) + } + + // Send Byte + Store (0, I2CE) // SMBus Enable + Store (0xbf, HSTS) + Store (Arg0, TXSA) // Write Address + Store (Arg1, HCMD) // Write Data + + Store (0x48, HCNT) // Start + Byte Data Protocol + + If (CMPL()) { + Or (HSTS, 0xff, HSTS) // Clean up + Return (1) // Success + } + + Return (0) + } + + + // SMBus Receive Byte + // Arg0: Address + // Return: 0xffff = Failure, Data (8bit) = Success + + Method (SRXB, 2, Serialized) + { + + // Is the SMBus Controller Ready? + If (SRDY()) { + Return (0xffff) + } + + // Receive Byte + Store (0, I2CE) // SMBus Enable + Store (0xbf, HSTS) + Store (Or (Arg0, 1), TXSA) // Write Address + + Store (0x44, HCNT) // Start + + If (CMPL()) { + Or (HSTS, 0xff, HSTS) // Clean up + Return (DAT0) // Success + } + + Return (0xffff) + } + + + // SMBus Write Byte + // Arg0: Address + // Arg1: Command + // Arg2: Data + // Return: 1 = Success, 0=Failure + + Method (SWRB, 3, Serialized) + { + + // Is the SMBus Controller Ready? + If (SRDY()) { + Return (0) + } + + // Send Byte + Store (0, I2CE) // SMBus Enable + Store (0xbf, HSTS) + Store (Arg0, TXSA) // Write Address + Store (Arg1, HCMD) // Write Command + Store (Arg2, DAT0) // Write Data + + Store (0x48, HCNT) // Start + Byte Protocol + + If (CMPL()) { + Or (HSTS, 0xff, HSTS) // Clean up + Return (1) // Success + } + + Return (0) + } + + + // SMBus Read Byte + // Arg0: Address + // Arg1: Command + // Return: 0xffff = Failure, Data (8bit) = Success + + Method (SRDB, 2, Serialized) + { + + // Is the SMBus Controller Ready? + If (SRDY()) { + Return (0xffff) + } + + // Receive Byte + Store (0, I2CE) // SMBus Enable + Store (0xbf, HSTS) + Store (Or (Arg0, 1), TXSA) // Write Address + Store (Arg1, HCMD) // Command + + Store (0x48, HCNT) // Start + + If (CMPL()) { + Or (HSTS, 0xff, HSTS) // Clean up + Return (DAT0) // Success + } + + Return (0xffff) + } +#endif +} diff --git a/src/soc/intel/denverton_ns/acpi/smbus2.asl b/src/soc/intel/denverton_ns/acpi/smbus2.asl new file mode 100644 index 0000000000..4b315ded1c --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/smbus2.asl @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// Intel SMBus Controller 0:12.0 + +Device (SMB2) +{ + Name (_ADR, 0x00120000) + + /* TODO */ +} diff --git a/src/soc/intel/denverton_ns/acpi/southcluster.asl b/src/soc/intel/denverton_ns/acpi/southcluster.asl new file mode 100644 index 0000000000..bcc8a5ca31 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/southcluster.asl @@ -0,0 +1,148 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../include/soc/iomap.h" + +Scope(\) +{ + // IO-Trap at 0x800. This is the ACPI->SMI communication interface. + + OperationRegion(IO_T, SystemIO, 0x800, 0x10) + Field(IO_T, ByteAcc, NoLock, Preserve) + { + Offset(0x8), + TRP0, 8 // IO-Trap at 0x808 + } + + // Private Chipset Register(PCR). Memory Mapped through ILB + OperationRegion(PCRR, SystemMemory, DEFAULT_PCR_BASE, 0x01000000) + Field(PCRR, DWordAcc, Lock, Preserve) + { + Offset (0xD03100), // Interrupt Routing Registers + PRTA, 8, + PRTB, 8, + PRTC, 8, + PRTD, 8, + PRTE, 8, + PRTF, 8, + PRTG, 8, + PRTH, 8, + } +} + +// PCI Express Ports 0:[9-11].0 +#include "pcie.asl" + +// SMBus 0:12.0 +#include "smbus2.asl" + +// SATA 0:13.0 +#include "sata.asl" + +// SATA 0:14.0 +#include "sata2.asl" + +// xHCI 0:15.0 +#include "xhci.asl" + +// Virtual root port 0 +Device (VRP0) { + Name (_ADR, 0x00160000) +} + +// Virtual root port 1 +Device (VRP1) { + Name (_ADR, 0x00170000) +} + +// ME HECI +Device (HECI) { + Name (_ADR, 0x00180000) +} + +// ME HECI2 +Device (HEC2) { + Name (_ADR, 0x00180001) +} + +// MEKT on PCH +Device (MEKT) { + Name (_ADR, 0x00180003) +} + +// ME HECI3 +Device (HEC3) { + Name (_ADR, 0x00180004) +} + +// UART 0 +Device (UAR0) { + Name (_ADR, 0x001A0000) +} + +// UART 1 +Device (UAR1) { + Name (_ADR, 0x001A0001) +} + +// UART 2 +Device (UAR2) { + Name (_ADR, 0x001A0002) +} + +// eMMC +Device (EMMC) { + Name (_ADR, 0x001C0000) +} + +// LPC Bridge 0:1f.0 +#include "lpc.asl" + +// P2SB 0:1f.1 +Device (P2SB) +{ + Name (_ADR, 0x001F0001) +} + +// PMC 0:1f.2 +#include "pmc.asl" + +// SMBus 0:1f.4 +#include "smbus.asl" + +// Northpeak 0:1f.7 +#include "npk.asl" + +/* IRQ assignment is mainboard specific. Get it from mainboard ACPI code */ +#include "acpi/mainboard_pci_irqs.asl" + +Method (_OSC, 4) +{ + /* Check for proper GUID */ + If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) + { + /* Let OS control everything */ + Return (Arg3) + } + Else + { + /* Unrecognized UUID */ + CreateDWordField (Arg3, 0, CDW1) + Or (CDW1, 4, CDW1) + Return (Arg3) + } +} diff --git a/src/soc/intel/denverton_ns/acpi/xhci.asl b/src/soc/intel/denverton_ns/acpi/xhci.asl new file mode 100644 index 0000000000..8f29aba145 --- /dev/null +++ b/src/soc/intel/denverton_ns/acpi/xhci.asl @@ -0,0 +1,45 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +// XHCI Controller 0:15.0 + +Device (XHC1) +{ + Name(_ADR, 0x00150000) + + Name (_PRW, Package(){ 0x0D, 3 }) // Power Resources for Wake + + // Leave USB ports on for to allow Wake from USB + + Method(_S3D,0) // Highest D State in S3 State + { + Return (2) + } + + Device (HUB7) + { + Name (_ADR, 0x00000000) + + // How many are there? + Device (PRT1) { Name (_ADR, 1) } // USB Port 0 + Device (PRT2) { Name (_ADR, 2) } // USB Port 1 + Device (PRT3) { Name (_ADR, 3) } // USB Port 2 + Device (PRT4) { Name (_ADR, 4) } // USB Port 3 + Device (PRT5) { Name (_ADR, 5) } // USB Port 4 + Device (PRT6) { Name (_ADR, 6) } // USB Port 5 + } +} diff --git a/src/soc/intel/denverton_ns/bootblock/bootblock.c b/src/soc/intel/denverton_ns/bootblock/bootblock.c new file mode 100644 index 0000000000..6179bf7c21 --- /dev/null +++ b/src/soc/intel/denverton_ns/bootblock/bootblock.c @@ -0,0 +1,72 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/cpu.h> +#include <bootblock_common.h> +#include <cpu/x86/mtrr.h> +#include <device/pci.h> +#include <FsptUpd.h> +#include <intelblocks/fast_spi.h> +#include <lib.h> +#include <soc/bootblock.h> +#include <soc/iomap.h> +#include <spi-generic.h> +#include <timestamp.h> +#include <console/console.h> + +const FSPT_UPD temp_ram_init_params = { + .FspUpdHeader = { + .Signature = 0x545F445055564E44ULL, + .Revision = 1, + .Reserved = {0}, + }, + .FsptCoreUpd = { + .MicrocodeRegionBase = + (UINT32)CONFIG_CPU_MICROCODE_CBFS_LOC, + .MicrocodeRegionLength = + (UINT32)CONFIG_CPU_MICROCODE_CBFS_LEN, + .CodeRegionBase = + (UINT32)(0x100000000ULL - CONFIG_CBFS_SIZE), + .CodeRegionLength = (UINT32)CONFIG_CBFS_SIZE, + .Reserved1 = {0}, + }, + .FsptConfig = { + .PcdFsptPort80RouteDisable = 0, + .ReservedTempRamInitUpd = {0}, + }, + .UnusedUpdSpace0 = {0}, + .UpdTerminator = 0x55AA, +}; + +asmlinkage void bootblock_c_entry(uint64_t base_timestamp) +{ + /* Call lib/bootblock.c main */ + bootblock_main_with_timestamp(base_timestamp); +}; + +void bootblock_soc_early_init(void) +{ + +#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) + early_uart_init(); +#endif +}; + +void bootblock_soc_init(void) +{ + if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) + printk(BIOS_DEBUG, "FSP TempRamInit successful...\n"); +}; diff --git a/src/soc/intel/denverton_ns/bootblock/cache_as_ram_fsp.S b/src/soc/intel/denverton_ns/bootblock/cache_as_ram_fsp.S new file mode 100644 index 0000000000..b998c21ff7 --- /dev/null +++ b/src/soc/intel/denverton_ns/bootblock/cache_as_ram_fsp.S @@ -0,0 +1,122 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <device/pci_def.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/cr.h> +#include <cpu/x86/post_code.h> + +#include <../../../arch/x86/walkcbfs.S> + +#define FSP_HDR_OFFSET 0x94 + +.extern temp_ram_init_params + +.global bootblock_pre_c_entry +bootblock_pre_c_entry: + +.global cache_as_ram +cache_as_ram: + post_code(0x2f) + + /* find fsp in cbfs */ + lea fsp_name, %esi + mov $1f, %esp + jmp walkcbfs_asm +1: + cmp $0, %eax + jz .halt_forever + mov CBFS_FILE_OFFSET(%eax), %ebx + bswap %ebx + add %eax, %ebx + + addl $FSP_HDR_OFFSET, %ebx + + /* + * save mm2 into ebp, because TempRamInit API doesn't preserve + * mm2 register + */ + movd %mm2, %ebp + + /* + * ebx = FSP INFO HEADER + * Calculate entry into FSP + */ + movl 0x30(%ebx), %eax /* Load TempRamInitEntryOffset */ + addl 0x1c(%ebx), %eax /* add the FSP ImageBase */ + + /* + * Pass early init variables on a fake stack (no memory yet) + * as well as the return location + */ + leal CAR_init_stack, %esp + + /* call FSP binary to setup temporary stack */ + jmp *%eax + +/* + * If the TempRamInit API is successful, then when returning, the ECX and + * EDX registers will point to the temporary but writeable memory range + * available to the bootloader where ECX is the start and EDX is the end of + * the range i.e. [ECX,EDX). See Denverton_ns FSP Integration Guide for more + * information. + * + * Return Values: + * EAX | Return Status + * ECX | Temporary Memory Start + * EDX | Temporary Memory End + * EBX, EDI, ESI, EBP, MM0, MM1 | Preserved Through API Call + */ + +CAR_init_done: + cmp $0, %eax + jnz .halt_forever + + /* clear CAR_GLOBAL area as it is not shared */ + cld + xor %eax, %eax + movl $(_car_global_end), %ecx + movl $(_car_global_start), %edi + sub %edi, %ecx + shrl $2, %ecx + rep stosl + + /* Setup bootblock stack */ + movl $(_car_stack_end), %esp + + /* Restore the timestamp from bootblock_crt0.S (ebp:mm1) */ + push %ebp + movd %mm1, %eax + push %eax + + /* We can call into C functions now */ + call bootblock_c_entry + + /* Never reached */ + +.halt_forever: + post_code(POST_DEAD_CODE) + hlt + jmp .halt_forever + + .align 4 +CAR_init_stack: + .long CAR_init_done + .long temp_ram_init_params + +fsp_name: + .ascii "fspt.bin\x00" diff --git a/src/soc/intel/denverton_ns/bootblock/uart.c b/src/soc/intel/denverton_ns/bootblock/uart.c new file mode 100644 index 0000000000..bad16de6b7 --- /dev/null +++ b/src/soc/intel/denverton_ns/bootblock/uart.c @@ -0,0 +1,198 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <device/pci_def.h> +#include <fsp/soc_binding.h> +#include <commonlib/helpers.h> + +#include <soc/bootblock.h> +#include <soc/gpio_defs.h> +#include <soc/uart.h> + +static uint16_t legacy_uart_ioadr_tab[] = {0x3F8, 0x2F8, 0x3E8, 0x2E8}; + +#define ELEM_OF_UART_TAB ARRAY_SIZE(legacy_uart_ioadr_tab) + +static void pci_early_hsuart_device_probe(u8 bus, u8 dev, u8 func, + u32 mmio_base) +{ + register uint16_t reg16; + + device_t uart_dev = PCI_DEV(bus, dev, func); + + /* We're using MMIO for HSUARTs. This section is needed for logging + * from FSP only + */ + /* Decode IOBASE at IOBA (BAR0). */ + reg16 = pci_read_config16(uart_dev, PCI_BASE_ADDRESS_0) | mmio_base; + pci_write_config16(uart_dev, PCI_BASE_ADDRESS_0, reg16); + +#if (IS_ENABLED(CONFIG_NON_LEGACY_UART_MODE)) + /* Decode MMIO at MEMBA (BAR1) */ + pci_write_config32(uart_dev, PCI_BASE_ADDRESS_1, + CONFIG_CONSOLE_UART_BASE_ADDRESS + + SIZE_OF_HSUART_RES * func); +#endif + + /* Enable memory/io space and allow to initiate + * a transaction as a master + */ + pci_write_config16(uart_dev, PCI_COMMAND, + pci_read_config16(uart_dev, PCI_COMMAND) | +#if (IS_ENABLED(CONFIG_NON_LEGACY_UART_MODE)) + PCI_COMMAND_MEMORY | +#endif + PCI_COMMAND_MASTER | PCI_COMMAND_IO); + +#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL_230400)) + /* Change the highest speed to 230400 */ + uint32_t *psr_reg = + (uint32_t *)(CONFIG_CONSOLE_UART_BASE_ADDRESS + + SIZE_OF_HSUART_RES * func + PSR_OFFSET); + *psr_reg >>= 1; +#endif + +#if (IS_ENABLED(CONFIG_LEGACY_UART_MODE)) + /* Hide HSUART on PCI to prevent re-enumeration + * and enable legacy mode. + */ + pci_write_config32(uart_dev, PCI_FUNC_RDCFG_HIDE, + pci_read_config32(uart_dev, PCI_FUNC_RDCFG_HIDE) | + 1); +#endif +} + +static void early_config_gpio(void) +{ + uint32_t reg32; + + // HSUART0: + // UART0_RXD + reg32 = read32( + (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_RXD)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_1) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_UART0_RXD), + reg32); + } + // UART0_TXD + reg32 = read32( + (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_TXD)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_1) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_UART0_TXD), + reg32); + } + // UART0_CTS + reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_SMB3_CLTT_CLK)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_2) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_2 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_SMB3_CLTT_CLK), + reg32); + } + // UART0_RTS + reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_PCIE_CLKREQ5_N)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_3) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_3 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_PCIE_CLKREQ5_N), + reg32); + } + + // HSUART1: + // UART1_RXD + reg32 = read32( + (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_RXD)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_1) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_UART1_RXD), + reg32); + } + // UART1_TXD + reg32 = read32( + (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_TXD)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_1) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_UART1_TXD), + reg32); + } + // UART1_CTS + reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_SATA1_SDOUT)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_1) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_SATA1_SDOUT), + reg32); + } + // UART1_RTS + reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_SATA0_SDOUT)); + if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) != + V_PCH_GPIO_PAD_MODE_NAT_1) { + reg32 &= ~B_PCH_GPIO_PAD_MODE; + reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1 + << N_PCH_GPIO_PAD_MODE); + write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, + R_PAD_CFG_DW0_SATA0_SDOUT), + reg32); + } +} + +void early_uart_init(void) +{ + register int i; + + /* Check: do we have enought elements to init. ? */ + BUILD_BUG_ON(HARCUVAR_UARTS_TO_INI > ELEM_OF_UART_TAB); + + /* HSUART(B0:D26:0-1) GPIO init. */ + early_config_gpio(); + + for (i = HARCUVAR_UARTS_TO_INI - 1; i >= 0; --i) { + pci_early_hsuart_device_probe(0, CONFIG_HSUART_DEV, i, + legacy_uart_ioadr_tab[i]); + } +} diff --git a/src/soc/intel/denverton_ns/chip.c b/src/soc/intel/denverton_ns/chip.c new file mode 100644 index 0000000000..9547bec275 --- /dev/null +++ b/src/soc/intel/denverton_ns/chip.c @@ -0,0 +1,167 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/acpi.h> +#include <bootstate.h> +#include <cbfs.h> +#include <cbmem.h> +#include <console/console.h> +#include <cpu/cpu.h> +#include <device/device.h> +#include <device/pci.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <intelblocks/fast_spi.h> +#include <soc/iomap.h> +#include <soc/intel/common/vbt.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/fiamux.h> +#include <spi-generic.h> +#include <hsio.h> +#include <harcuvar_boardid.h> + +static void pci_domain_set_resources(device_t dev) +{ + assign_resources(dev->link_list); +} + +static struct device_operations pci_domain_ops = { + .read_resources = &pci_domain_read_resources, + .set_resources = &pci_domain_set_resources, + .scan_bus = &pci_domain_scan_bus, + .ops_pci_bus = &pci_bus_default_ops, +}; + +static struct device_operations cpu_bus_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, + .init = denverton_init_cpus, + .scan_bus = NULL, +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_fill_ssdt_generator = generate_cpu_entries, +#endif +}; + +static void soc_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 soc_init(void *data) { fsp_silicon_init(false); } + +static void soc_final(void *data) {} + +static void soc_silicon_init_params(FSPS_UPD *silupd) +{ + size_t num; + uint16_t supported_hsio_lanes; + uint8_t boardid = board_id(); + BL_HSIO_INFORMATION *hsio_config; + BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data = get_fiamux_hob_data(); + + /* Configure FIA MUX PCD */ + supported_hsio_lanes = + (uint16_t)fiamux_hob_data->FiaMuxConfig.SkuNumLanesAllowed; + + switch (boardid) { + case BoardIdHarcuvar: + num = ARRAY_SIZE(harcuvar_hsio_config); + hsio_config = (BL_HSIO_INFORMATION *)harcuvar_hsio_config; + break; + default: + num = 0; + hsio_config = NULL; + break; + } + + if (get_fiamux_hsio_info(supported_hsio_lanes, num, &hsio_config)) + die("HSIO Configuration is invalid, please correct it!"); + + /* Check the requested FIA MUX Configuration */ + if (!(&hsio_config->FiaConfig)) { + die("Requested FIA MUX Configuration is invalid," + " please correct it!"); + } + + /* Initialize PCIE Bifurcation & HSIO configuration */ + silupd->FspsConfig.PcdBifurcationPcie0 = hsio_config->PcieBifCtr[0]; + silupd->FspsConfig.PcdBifurcationPcie1 = hsio_config->PcieBifCtr[1]; + + silupd->FspsConfig.PcdFiaMuxConfigRequestPtr = + (uint32_t)&hsio_config->FiaConfig; +} + +void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd) +{ + const struct microcode *microcode_file; + size_t microcode_len; + + microcode_file = cbfs_boot_map_with_leak("cpu_microcode_blob.bin", + CBFS_TYPE_MICROCODE, µcode_len); + + if ((microcode_file != NULL) && (microcode_len != 0)) { + /* Update CPU Microcode patch base address/size */ + silupd->FspsConfig.PcdCpuMicrocodePatchBase = + (uint32_t)microcode_file; + silupd->FspsConfig.PcdCpuMicrocodePatchSize = + (uint32_t)microcode_len; + } + + soc_silicon_init_params(silupd); + mainboard_silicon_init_params(silupd); +} + +struct chip_operations soc_intel_denverton_ns_ops = { + CHIP_NAME("Intel Denverton-NS SOC") + .enable_dev = &soc_enable_dev, + .init = &soc_init, + .final = &soc_final +}; + +static void soc_set_subsystem(device_t dev, uint32_t vendor, uint32_t device) +{ + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | + (vendor & 0xffff)); + } +} + +struct pci_operations soc_pci_ops = { + .set_subsystem = soc_set_subsystem, +}; + +/* + * spi_flash init() needs to run unconditionally on every boot (including + * resume) to allow write protect to be disabled for eventlog and nvram + * updates. This needs to be done as early as possible in ramstage. Thus, add a + * callback for entry into BS_PRE_DEVICE. + */ +static void spi_flash_init_cb(void *unused) +{ + fast_spi_init(); +} + +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_flash_init_cb, NULL); diff --git a/src/soc/intel/denverton_ns/chip.h b/src/soc/intel/denverton_ns/chip.h new file mode 100644 index 0000000000..bfa6a0132f --- /dev/null +++ b/src/soc/intel/denverton_ns/chip.h @@ -0,0 +1,77 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef SOC_INTEL_DENVERTON_NS_CHIP_H +#define SOC_INTEL_DENVERTON_NS_CHIP_H + +struct soc_intel_denverton_ns_config { + /** + * Interrupt Routing configuration + * If bit7 is 1, the interrupt is disabled. + */ + uint8_t pirqa_routing; + uint8_t pirqb_routing; + uint8_t pirqc_routing; + uint8_t pirqd_routing; + uint8_t pirqe_routing; + uint8_t pirqf_routing; + uint8_t pirqg_routing; + uint8_t pirqh_routing; + + /** + * Device Interrupt Routing configuration + * Interrupt Pin x Route. + * 0h = PIRQA# + * 1h = PIRQB# + * 2h = PIRQC# + * 3h = PIRQD# + * 4h = PIRQE# + * 5h = PIRQF# + * 6h = PIRQG# + * 7h = PIRQH# + */ + uint16_t ir00_routing; + uint16_t ir01_routing; + uint16_t ir02_routing; + uint16_t ir03_routing; + uint16_t ir04_routing; + uint16_t ir05_routing; + uint16_t ir06_routing; + uint16_t ir07_routing; + uint16_t ir08_routing; + uint16_t ir09_routing; + uint16_t ir10_routing; + uint16_t ir11_routing; + uint16_t ir12_routing; + + /** + * Device Interrupt Polarity Control + * ipc0 - IRQ-00-31 - 1: Active low to IOAPIC, 0: Active high to IOAPIC + * ipc1 - IRQ-32-63 - 1: Active low to IOAPIC, 0: Active high to IOAPIC + * ipc2 - IRQ-64-95 - 1: Active low to IOAPIC, 0: Active high to IOAPIC + * ipc3 - IRQ-96-119 - 1: Active low to IOAPIC, 0: Active high to IOAPIC + */ + uint32_t ipc0; + uint32_t ipc1; + uint32_t ipc2; + uint32_t ipc3; +}; + +extern struct chip_operations soc_intel_denverton_ns_ops; + +typedef struct soc_intel_denverton_ns_config config_t; + +#endif /* SOC_INTEL_FSP_DENVERTON_NS_CHIP_H */ diff --git a/src/soc/intel/denverton_ns/cpu.c b/src/soc/intel/denverton_ns/cpu.c new file mode 100644 index 0000000000..b6c05e754c --- /dev/null +++ b/src/soc/intel/denverton_ns/cpu.c @@ -0,0 +1,254 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <cpu/cpu.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/intel/turbo.h> +#include <device/device.h> +#include <device/pci.h> +#include <reg_script.h> + +#include <soc/msr.h> +#include <soc/cpu.h> +#include <soc/iomap.h> +#include <soc/smm.h> +#include <soc/soc_util.h> + +static struct smm_relocation_attrs relo_attrs; + +static void denverton_core_init(device_t cpu) +{ + msr_t msr; + + printk(BIOS_DEBUG, "Init Denverton-NS SoC cores.\n"); + + /* Enable Turbo */ + enable_turbo(); + + /* Enable speed step. */ + if (get_turbo_state() == TURBO_ENABLED) { + msr = rdmsr(MSR_IA32_MISC_ENABLES); + msr.lo |= SPEED_STEP_ENABLE_BIT; + wrmsr(MSR_IA32_MISC_ENABLES, msr); + } +} + +static struct device_operations cpu_dev_ops = { + .init = denverton_core_init, +}; + +static struct cpu_device_id cpu_table[] = { + {X86_VENDOR_INTEL, + CPUID_DENVERTON_A0_A1}, /* Denverton-NS A0/A1 CPUID */ + {X86_VENDOR_INTEL, CPUID_DENVERTON_B0}, /* Denverton-NS B0 CPUID */ + {0, 0}, +}; + +static const struct cpu_driver driver __cpu_driver = { + .ops = &cpu_dev_ops, + .id_table = cpu_table, +}; + +/* + * MP and SMM loading initialization. + */ + +static void relocation_handler(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase) +{ + msr_t smrr; + em64t100_smm_state_save_area_t *smm_state; + (void)cpu; + + /* Set up SMRR. */ + smrr.lo = relo_attrs.smrr_base; + smrr.hi = 0; + wrmsr(SMRR_PHYS_BASE, smrr); + smrr.lo = relo_attrs.smrr_mask; + smrr.hi = 0; + wrmsr(SMRR_PHYS_MASK, smrr); + smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); + smm_state->smbase = staggered_smbase; +} + +static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size) +{ + void *smm_base; + size_t smm_size; + void *handler_base; + size_t handler_size; + + /* All range registers are aligned to 4KiB */ + const uint32_t rmask = ~((1 << 12) - 1); + + /* Initialize global tracking state. */ + smm_region(&smm_base, &smm_size); + smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size); + + relo_attrs.smbase = (uint32_t)smm_base; + relo_attrs.smrr_base = relo_attrs.smbase | MTRR_TYPE_WRBACK; + relo_attrs.smrr_mask = ~(smm_size - 1) & rmask; + relo_attrs.smrr_mask |= MTRR_PHYS_MASK_VALID; + + *perm_smbase = (uintptr_t)handler_base; + *perm_smsize = handler_size; + *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); +} + +static int detect_num_cpus_via_cpuid(void) +{ + register int ecx = 0; + struct cpuid_result leaf_b; + + while (1) { + leaf_b = cpuid_ext(0xb, ecx); + + /* Processor doesn't have hyperthreading so just determine the + * number of cores by from level type (ecx[15:8] == * 2). */ + if ((leaf_b.ecx & 0xff00) == 0x0200) + break; + ecx++; + } + return (leaf_b.ebx & 0xffff); +} + +static int detect_num_cpus_via_mch(void) +{ + /* Assumes that FSP has already programmed the cores disabled register + */ + u32 core_exists_mask, active_cores_mask; + u32 core_disable_mask; + register int active_cores = 0, total_cores = 0; + register int counter = 0; + + /* Get Masks for Total Existing SOC Cores and Core Disable Mask */ + core_exists_mask = MMIO32(DEFAULT_MCHBAR + MCH_BAR_CORE_EXISTS_MASK); + core_disable_mask = MMIO32(DEFAULT_MCHBAR + MCH_BAR_CORE_DISABLE_MASK); + active_cores_mask = (~core_disable_mask) & core_exists_mask; + + /* Calculate Number of Active Cores */ + for (; counter < CONFIG_MAX_CPUS; + counter++, active_cores_mask >>= 1, core_exists_mask >>= 1) { + active_cores += (active_cores_mask & CORE_BIT_MSK); + total_cores += (core_exists_mask & CORE_BIT_MSK); + } + + printk(BIOS_DEBUG, "Number of Active Cores: %d of %d total.\n", + active_cores, total_cores); + + return active_cores; +} + +/* Find CPU topology */ +int get_cpu_count(void) +{ + int num_cpus = detect_num_cpus_via_mch(); + + if (num_cpus <= 0 || num_cpus > CONFIG_MAX_CPUS) { + num_cpus = detect_num_cpus_via_cpuid(); + printk(BIOS_DEBUG, "Number of Cores (CPUID): %d.\n", num_cpus); + } + return num_cpus; +} + +static int cpu_config_tdp_levels(void) +{ + msr_t platform_info; + + /* Bits 34:33 indicate how many levels supported */ + platform_info = rdmsr(MSR_PLATFORM_INFO); + return (platform_info.hi >> 1) & 3; +} + +static void set_max_turbo_freq(void) +{ + msr_t msr, perf_ctl; + + perf_ctl.hi = 0; + + /* Check for configurable TDP option */ + if (get_turbo_state() == TURBO_ENABLED) { + msr = rdmsr(MSR_TURBO_RATIO_LIMIT); + perf_ctl.lo = (msr.lo & 0xff) << 8; + + } else if (cpu_config_tdp_levels()) { + /* Set to nominal TDP ratio */ + msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = rdmsr(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + wrmsr(IA32_PERF_CTL, perf_ctl); + + printk(BIOS_DEBUG, "cpu: frequency set to %d\n", + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); +} + +/* + * Do essential initialization tasks before APs can be fired up + * + * 1. Prevent race condition in MTRR solution. Enable MTRRs on the BSP. This + * creates the MTRR solution that the APs will use. Otherwise APs will try to + * apply the incomplete solution as the BSP is calculating it. + */ +static void pre_mp_init(void) +{ + x86_setup_mtrrs_with_detect(); + x86_mtrr_check(); +} + +static void post_mp_init(void) +{ + /* Set Max Ratio */ + set_max_turbo_freq(); + + /* + * Now that all APs have been relocated as well as the BSP let SMIs + * start flowing. + */ + southcluster_smm_enable_smi(); +} + +/* + * CPU initialization recipe + * + * Note that no microcode update is passed to the init function. CSE updates + * the microcode on all cores before releasing them from reset. That means that + * the BSP and all APs will come up with the same microcode revision. + */ +static const struct mp_ops mp_ops = { + .pre_mp_init = pre_mp_init, + .get_cpu_count = get_cpu_count, + .get_smm_info = get_smm_info, + .pre_mp_smm_init = southcluster_smm_clear_state, + .relocation_handler = relocation_handler, + .post_mp_init = post_mp_init, +}; + +void denverton_init_cpus(device_t dev) +{ + /* Clear for take-off */ + if (mp_init_with_smm(dev->link_list, &mp_ops) < 0) + printk(BIOS_ERR, "MP initialization failure.\n"); +} diff --git a/src/soc/intel/denverton_ns/csme_ie_kt.c b/src/soc/intel/denverton_ns/csme_ie_kt.c new file mode 100644 index 0000000000..78488835a2 --- /dev/null +++ b/src/soc/intel/denverton_ns/csme_ie_kt.c @@ -0,0 +1,90 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <console/console.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> + +/** +* Read the base address registers for a given device. +* +* @param dev Pointer to the dev structure. +* @param howmany How many registers to read. +*/ +static void pci_read_bases(struct device *dev, unsigned int howmany) +{ + unsigned long index; + + for (index = PCI_BASE_ADDRESS_0; + (index < PCI_BASE_ADDRESS_0 + (howmany << 2));) { + struct resource *resource; + resource = pci_get_resource(dev, index); + /** + * Workarond for Denverton-NS silicon (Rev A0/A1 for CSME/IE, + * Rev B0 for CSME only) + * CSME&IEs KT IO bar must be 16-byte aligned + */ + if ((resource->flags & IORESOURCE_IO) && + (resource->align != 4)) { + printk(BIOS_DEBUG, + "CSME&IEs KT IO bar must be 16-byte aligned!\n"); + resource->align = 4; + resource->gran = 4; + resource->size = 16; + } + index += (resource->flags & IORESOURCE_PCI64) ? 8 : 4; + } + + compact_resources(dev); +} + +static void pci_csme_ie_kt_read_resources(device_t dev) +{ + /** + * CSME/IE KT has 2 BARs to chec: + * 0x10 - KT IO BAR + * 0x14 - KT Memory BAR + * CSME/IE KT has no Expansion ROM BAR to check: + * 0x30 - KT Host XRBAR, READ ONLY + */ + pci_read_bases(dev, 2); +} + +static struct device_operations csme_ie_kt_ops = { + .read_resources = pci_csme_ie_kt_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .scan_bus = 0, + .init = 0, + .ops_pci = &soc_pci_ops, +}; + +static const unsigned short pci_device_ids[] = { + ME_MEKT_DEVID, /* DVN CSME KT */ + IE_MEKT_DEVID, /* DVN IE KT */ + 0 +}; + +static const struct pci_driver csme_ie_kt __pci_driver = { + .ops = &csme_ie_kt_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +}; diff --git a/src/soc/intel/denverton_ns/exit_car_fsp.S b/src/soc/intel/denverton_ns/exit_car_fsp.S new file mode 100644 index 0000000000..2ec625b4d2 --- /dev/null +++ b/src/soc/intel/denverton_ns/exit_car_fsp.S @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016-2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cpu/x86/mtrr.h> +#include <cpu/x86/cr.h> +//#include <soc/cpu.h> + +/* + * This path for CAR teardown is taken when CONFIG_FSP_CAR is employed. + * This version of chipset_teardown_car sets up the stack, then bypasses + * the rest of arch/x86/exit_car.S and calls main() itself instead of + * returning to _start. In main(), the TempRamExit FSP API is called + * to tear down the CAR and set up caching which can be overwritten + * after the API call. More info can be found in the Denverton-NS FSP + * Integration Guide included with the FSP binary. The below + * caching settings are based on an 8MiB Flash Size given as a + * parameter to TempRamInit. + * + * TempRamExit MTRR Settings: + * 0x00000000 - 0x0009FFFF | Write Back + * 0x000C0000 - Top of Low Memory | Write Back + * 0xFF800000 - 0xFFFFFFFF Flash Reg | Write Protect + * 0x100000000 - Top of High Memory | Write Back + */ + +.text +.global chipset_teardown_car +chipset_teardown_car: + + /* Set up new stack. */ + mov post_car_stack_top, %esp + + /* Call C code */ + call main diff --git a/src/soc/intel/denverton_ns/fiamux.c b/src/soc/intel/denverton_ns/fiamux.c new file mode 100644 index 0000000000..282ba030e8 --- /dev/null +++ b/src/soc/intel/denverton_ns/fiamux.c @@ -0,0 +1,140 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <console/console.h> +#include <soc/fiamux.h> + +#define FSP_FIAMUX_HOB_GUID \ + { \ + 0x26ad492e, 0xf951, 0x4e43, \ + { \ + 0xbc, 0x72, 0x22, 0x76, 0x58, 0xb1, 0xf6, 0x23 \ + } \ + } + +int get_fiamux_hsio_info(uint16_t num_of_lanes, size_t num_of_entry, + BL_HSIO_INFORMATION **config) +{ + uint8_t entry; + + if ((num_of_lanes == 0) || (num_of_entry == 0) || (*config == NULL)) + return 1; + + for (entry = 0; entry < num_of_entry; entry++) { + if ((*config)[entry].NumLanesSupported == num_of_lanes) { + *config = &(*config)[entry]; + return 0; + } + } + + return 1; +} + +/* +* Display the FIA MUX HOB. +* +* @param Pointer of FIA MUX HOB data +* +* @return None +* +*/ +void print_fiamux_config_hob(BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data) +{ + /* Display the FIA MUX Configuration */ + printk(BIOS_DEBUG, "FIA MUX Configuration in FSP HOB is:\n"); + + printk(BIOS_DEBUG, " FiaMuxConfig.SkuNumLanesAllowed = 0x%x\n", + (uint32_t)(fiamux_hob_data->FiaMuxConfig.SkuNumLanesAllowed)); + + printk(BIOS_DEBUG, " FiaMuxConfig.FiaMuxConfig = 0x%llx\n", + (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfig + .MuxConfiguration.MeFiaMuxLaneConfig)); + + printk(BIOS_DEBUG, + " FiaMuxConfig.FiaMuxConfig.SataLaneConfiguration = 0x%llx\n", + (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfig + .SataLaneConfiguration.MeFiaSataLaneConfig)); + + printk(BIOS_DEBUG, " FiaMuxConfig.FiaMuxConfig." + "PcieRootPortsConfiguration = 0x%llx\n", + (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfig + .PcieRootPortsConfiguration + .MeFiaPcieRootPortsConfig)); + + printk(BIOS_DEBUG, " FiaMuxConfig.FiaMuxConfigRequest = 0x%llx\n", + (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfigRequest + .MuxConfiguration.MeFiaMuxLaneConfig)); + + printk(BIOS_DEBUG, " FiaMuxConfig.FiaMuxConfigRequest." + "SataLaneConfiguration = 0x%llx\n", + (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfigRequest + .SataLaneConfiguration.MeFiaSataLaneConfig)); + + printk(BIOS_DEBUG, " FiaMuxConfig.FiaMuxConfigRequest." + "PcieRootPortsConfiguration = 0x%llx\n", + (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfigRequest + .PcieRootPortsConfiguration + .MeFiaPcieRootPortsConfig)); + printk(BIOS_DEBUG, + " FiaMuxConfigStatus.FiaMuxConfigGetStatus = 0x%x\n", + (uint32_t)(fiamux_hob_data->FiaMuxConfigStatus + .FiaMuxConfigGetStatus)); + + printk(BIOS_DEBUG, + " FiaMuxConfigStatus.FiaMuxConfigSetStatus = 0x%x\n", + (uint32_t)(fiamux_hob_data->FiaMuxConfigStatus + .FiaMuxConfigSetStatus)); + + printk(BIOS_DEBUG, + " FiaMuxConfigStatus.FiaMuxConfigSetRequired = 0x%x\n", + (uint8_t)(fiamux_hob_data->FiaMuxConfigStatus + .FiaMuxConfigSetRequired)); +} + +/* +* Get the pointer of FIA MUX HOB data +* +* @param Pointer of FIA MUX HOB data +* +* @return: +* Non-zero - FIA MUX configuration correct. +* Zero - Either FIA MUX configuration incorrect or +* it can not be verified. +*/ +BL_FIA_MUX_CONFIG_HOB *get_fiamux_hob_data(void) +{ + u32 const *fiamux_hob = NULL; + BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data = NULL; + const EFI_GUID fiamux_guid = FSP_FIAMUX_HOB_GUID; + size_t size; + + /* Parse FIA MUX configuration HOB */ + fiamux_hob = fsp_find_extension_hob_by_guid( + (uint8_t const *)&fiamux_guid, &size); + + if (fiamux_hob == NULL) { + /* FIA MUX configuration HOB not exist */ + die("FIA MUX Configuration Data Hob does not present!\n"); + } else { + /* Get FIA MUX configuration HOB */ + fiamux_hob_data = (BL_FIA_MUX_CONFIG_HOB *)(fiamux_hob); + + /* Display FIA MUX configuration HOB */ + print_fiamux_config_hob(fiamux_hob_data); + } + + return fiamux_hob_data; +} diff --git a/src/soc/intel/denverton_ns/gpio.c b/src/soc/intel/denverton_ns/gpio.c new file mode 100644 index 0000000000..3030fbb98b --- /dev/null +++ b/src/soc/intel/denverton_ns/gpio.c @@ -0,0 +1,509 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> + +#include <soc/iomap.h> +#include <soc/pcr.h> +#include <soc/soc_util.h> +#include <soc/gpio.h> + +// Community PadOwnOffset HostOwnOffset +// GpiIsOffset +// GpiIeOffset GpiGpeStsOffset GpiGpeEnOffset +// SmiStsOffset +// SmiEnOffset NmiStsOffset NmiEnOffset +// PadCfgLockOffset +// PadCfgLockTxOffset PadCfgOffset PadPerGroup +static const struct GPIO_GROUP_INFO mGpioGroupInfo[] = { + {PID_GPIOCOM0, R_PCH_PCR_GPIO_NC_PAD_OWN, R_PCH_PCR_GPIO_NC_HOSTSW_OWN, + R_PCH_PCR_GPIO_NC_GPI_IS, R_PCH_PCR_GPIO_NC_GPI_IE, + R_PCH_PCR_GPIO_NC_GPI_GPE_STS, R_PCH_PCR_GPIO_NC_GPI_GPE_EN, + R_PCH_PCR_GPIO_NC_SMI_STS, R_PCH_PCR_GPIO_NC_SMI_EN, + R_PCH_PCR_GPIO_NC_NMI_STS, R_PCH_PCR_GPIO_NC_NMI_EN, + R_PCH_PCR_GPIO_NC_PADCFGLOCK, R_PCH_PCR_GPIO_NC_PADCFGLOCKTX, + R_PCH_PCR_GPIO_NC_PADCFG_OFFSET, + V_PCH_GPIO_NC_PAD_MAX}, // DNV NORTH_ALL + {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC_DFX_PAD_OWN, + R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, R_PCH_PCR_GPIO_SC_DFX_GPI_IS, + R_PCH_PCR_GPIO_SC_DFX_GPI_IE, R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS, + R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY, + NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, + NO_REGISTER_FOR_PROPERTY, R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK, + R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX, + R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET, + V_PCH_GPIO_SC_DFX_PAD_MAX}, // DNV SOUTH_DFX + {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC0_PAD_OWN, + R_PCH_PCR_GPIO_SC0_HOSTSW_OWN, R_PCH_PCR_GPIO_SC0_GPI_IS, + R_PCH_PCR_GPIO_SC0_GPI_IE, R_PCH_PCR_GPIO_SC0_GPI_GPE_STS, + R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, R_PCH_PCR_GPIO_SC0_SMI_STS, + R_PCH_PCR_GPIO_SC0_SMI_EN, R_PCH_PCR_GPIO_SC0_NMI_STS, + R_PCH_PCR_GPIO_SC0_NMI_EN, R_PCH_PCR_GPIO_SC0_PADCFGLOCK, + R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET, + V_PCH_GPIO_SC0_PAD_MAX}, // DNV South Community 0 + {PID_GPIOCOM1, R_PCH_PCR_GPIO_SC1_PAD_OWN, + R_PCH_PCR_GPIO_SC1_HOSTSW_OWN, R_PCH_PCR_GPIO_SC1_GPI_IS, + R_PCH_PCR_GPIO_SC1_GPI_IE, R_PCH_PCR_GPIO_SC1_GPI_GPE_STS, + R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, R_PCH_PCR_GPIO_SC1_SMI_STS, + R_PCH_PCR_GPIO_SC1_SMI_EN, R_PCH_PCR_GPIO_SC1_NMI_STS, + R_PCH_PCR_GPIO_SC1_NMI_EN, R_PCH_PCR_GPIO_SC1_PADCFGLOCK, + R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET, + V_PCH_GPIO_SC1_PAD_MAX}, // DNV South Community 1 +}; + +/* Retrieve address and length of GPIO info table */ +static struct GPIO_GROUP_INFO * +GpioGetGroupInfoTable(uint32_t *GpioGroupInfoTableLength) +{ + *GpioGroupInfoTableLength = + sizeof(mGpioGroupInfo) / sizeof(struct GPIO_GROUP_INFO); + return (struct GPIO_GROUP_INFO *)mGpioGroupInfo; +} + +/* Get Gpio Pad Ownership */ +static void GpioGetPadOwnership(GPIO_PAD GpioPad, GPIO_PAD_OWN *PadOwnVal) +{ + uint32_t Mask; + uint32_t RegOffset; + uint32_t GroupIndex; + uint32_t PadNumber; + struct GPIO_GROUP_INFO *GpioGroupInfo; + uint32_t GpioGroupInfoLength; + uint32_t PadOwnRegValue; + + GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad); + PadNumber = GPIO_GET_PAD_NUMBER(GpioPad); + + GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength); + + // + // Check if group argument exceeds GPIO GROUP INFO array + // + if ((uint32_t)GroupIndex >= GpioGroupInfoLength) { + printk(BIOS_ERR, "GPIO ERROR: Group argument (%d) exceeds GPIO " + "group range\n", + GroupIndex); + return; + } + + // + // Check if legal pin number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + printk(BIOS_ERR, "GPIO ERROR: Pin number (%d) exceeds possible " + "range for this group\n", + PadNumber); + return; + } + // + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. + // One DWord register contains information for 8 pads. + // + RegOffset = + GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4; + + // + // Calculate pad bit position within DWord register + // + PadNumber %= 8; + Mask = ((1 << 1) | (1 << 0)) << (PadNumber * 4); + + PadOwnRegValue = read32((void *)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, RegOffset)); + + *PadOwnVal = (GPIO_PAD_OWN)((PadOwnRegValue & Mask) >> (PadNumber * 4)); +} + +void gpio_configure_pads(const struct pad_config *gpio, size_t num) +{ + /* Return if gpio not valid */ + if ((gpio == NULL) || (num == 0)) + return; + + uint32_t Index; + uint32_t Dw0Reg; + uint32_t Dw0RegMask; + uint32_t Dw1Reg; + uint32_t Dw1RegMask; + uint32_t PadCfgReg; + uint64_t HostSoftOwnReg[V_PCH_GPIO_GROUP_MAX]; + uint64_t HostSoftOwnRegMask[V_PCH_GPIO_GROUP_MAX]; + uint64_t GpiGpeEnReg[V_PCH_GPIO_GROUP_MAX]; + uint64_t GpiGpeEnRegMask[V_PCH_GPIO_GROUP_MAX]; + struct GPIO_GROUP_INFO *GpioGroupInfo; + uint32_t GpioGroupInfoLength; + GPIO_PAD GpioGroupOffset; + uint32_t NumberOfGroups; + GPIO_PAD_OWN PadOwnVal; + struct pad_config *GpioData; + GPIO_PAD Group; + uint32_t GroupIndex; + uint32_t PadNumber; + uint32_t FinalValue; + uint32_t Data32; + uint32_t PadMode1, PadMode2; + + PadOwnVal = GpioPadOwnHost; + + memset(HostSoftOwnReg, 0, sizeof(HostSoftOwnReg)); + memset(HostSoftOwnRegMask, 0, sizeof(HostSoftOwnRegMask)); + memset(GpiGpeEnReg, 0, sizeof(GpiGpeEnReg)); + memset(GpiGpeEnRegMask, 0, sizeof(GpiGpeEnRegMask)); + + GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength); + + GpioGroupOffset = GPIO_DNV_GROUP_MIN; + NumberOfGroups = V_PCH_GPIO_GROUP_MAX; + + for (Index = 0; Index < (uint32_t)num; Index++) { + + Dw0RegMask = 0; + Dw0Reg = 0; + Dw1RegMask = 0; + Dw1Reg = 0; + + GpioData = (struct pad_config *)&(gpio[Index]); + + Group = GPIO_GET_GROUP_FROM_PAD(GpioData->GpioPad); + GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioData->GpioPad); + PadNumber = GPIO_GET_PAD_NUMBER(GpioData->GpioPad); + + // + // Check if group index argument exceeds GPIO group index range + // + if (GroupIndex >= V_PCH_GPIO_GROUP_MAX) { + printk(BIOS_ERR, "GPIO ERROR: Invalid Group Index " + "(GroupIndex=%d, Pad=%d)!\n", + GroupIndex, PadNumber); + continue; + } + + // + // Check if group argument exceeds GPIO group range + // + if ((Group < GpioGroupOffset) || + (Group >= NumberOfGroups + GpioGroupOffset)) { + printk(BIOS_ERR, + "GPIO ERROR: Invalid Group (Group=%d)!\n", + Group); + return; + } + + // + // Check if legal pin number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + printk(BIOS_ERR, "GPIO ERROR: Invalid PadNumber " + "(PadNumber=%d)!\n", + PadNumber); + return; + } + + // + // Check if selected GPIO Pad is not owned by CSME/ISH + // + GpioGetPadOwnership(GpioData->GpioPad, &PadOwnVal); + + if (PadOwnVal != GpioPadOwnHost) { + printk(BIOS_ERR, "GPIO WARNING: Accessing pad not " + "owned by host (Group=%d, Pad=%d)!", + GroupIndex, PadNumber); + if (PadOwnVal == GpioPadOwnCsme) + printk(BIOS_ERR, "The owner is CSME\n"); + else if (PadOwnVal == GpioPadOwnIsh) + printk(BIOS_ERR, "The owner is ISH\n"); + printk(BIOS_ERR, "** Please make sure the GPIO usage " + "in sync between CSME/ISH and Host IA " + "FW configuration.\n"); + printk(BIOS_ERR, "** All the GPIO occupied by CSME/ISH " + "should not do any configuration by " + "Host IA FW.\n"); + continue; + } + + // + // Configure Reset Type (PadRstCfg) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.PowerConfig & + GPIO_CONF_RESET_MASK) >> + GPIO_CONF_RESET_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RST_CONF); + Dw0Reg |= (((GpioData->GpioConfig.PowerConfig & + GPIO_CONF_RESET_MASK) >> + (GPIO_CONF_RESET_BIT_POS + 1)) + << N_PCH_GPIO_RST_CONF); + + // + // Configure how interrupt is triggered (RxEvCfg) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_TRIG_MASK) >> + GPIO_CONF_INT_TRIG_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RX_LVL_EDG); + Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_TRIG_MASK) >> + (GPIO_CONF_INT_TRIG_BIT_POS + 1)) + << N_PCH_GPIO_RX_LVL_EDG); + + // + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_ROUTE_MASK) >> + GPIO_CONF_INT_ROUTE_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : (B_PCH_GPIO_RX_NMI_ROUTE | + B_PCH_GPIO_RX_SCI_ROUTE | + B_PCH_GPIO_RX_SMI_ROUTE | + B_PCH_GPIO_RX_APIC_ROUTE)); + Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig & + GPIO_CONF_INT_ROUTE_MASK) >> + (GPIO_CONF_INT_ROUTE_BIT_POS + 1)) + << N_PCH_GPIO_RX_NMI_ROUTE); + + // If CFIO is not Working as GPIO mode, Don't move TxDisabe and + // RxDisable + if (GpioData->GpioConfig.PadMode == GpioPadModeGpio) { + // + // Configure GPIO direction (GPIORxDis and GPIOTxDis) + // + Dw0RegMask |= ((((GpioData->GpioConfig.Direction & + GPIO_CONF_DIR_MASK) >> + GPIO_CONF_DIR_BIT_POS) == + GpioHardwareDefault) + ? 0x0 + : (B_PCH_GPIO_RXDIS | + B_PCH_GPIO_TXDIS)); + Dw0Reg |= (((GpioData->GpioConfig.Direction & + GPIO_CONF_DIR_MASK) >> + (GPIO_CONF_DIR_BIT_POS + 1)) + << N_PCH_GPIO_TXDIS); + } + + // + // Configure GPIO input inversion (RXINV) + // + Dw0RegMask |= ((((GpioData->GpioConfig.Direction & + GPIO_CONF_INV_MASK) >> + GPIO_CONF_INV_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RXINV); + Dw0Reg |= (((GpioData->GpioConfig.Direction & + GPIO_CONF_INV_MASK) >> + (GPIO_CONF_INV_BIT_POS + 1)) + << N_PCH_GPIO_RXINV); + + // + // Configure GPIO output state (GPIOTxState) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.OutputState & + GPIO_CONF_OUTPUT_MASK) >> + GPIO_CONF_OUTPUT_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_TX_STATE); + Dw0Reg |= (((GpioData->GpioConfig.OutputState & + GPIO_CONF_OUTPUT_MASK) >> + (GPIO_CONF_OUTPUT_BIT_POS + 1)) + << N_PCH_GPIO_TX_STATE); + + // + // Configure GPIO RX raw override to '1' (RXRAW1) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.OtherSettings & + GPIO_CONF_RXRAW_MASK) >> + GPIO_CONF_RXRAW_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_RX_RAW1); + Dw0Reg |= (((GpioData->GpioConfig.OtherSettings & + GPIO_CONF_RXRAW_MASK) >> + (GPIO_CONF_RXRAW_BIT_POS + 1)) + << N_PCH_GPIO_RX_RAW1); + + // + // Configure GPIO Pad Mode (PMode) + // + Dw0RegMask |= + ((((GpioData->GpioConfig.PadMode & + GPIO_CONF_PAD_MODE_MASK) >> + GPIO_CONF_PAD_MODE_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_PAD_MODE); + Dw0Reg |= (((GpioData->GpioConfig.PadMode & + GPIO_CONF_PAD_MODE_MASK) >> + (GPIO_CONF_PAD_MODE_BIT_POS + 1)) + << N_PCH_GPIO_PAD_MODE); + + // + // Configure GPIO termination (Term) + // + Dw1RegMask |= ((((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_TERM_MASK) >> + GPIO_CONF_TERM_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_TERM); + Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_TERM_MASK) >> + (GPIO_CONF_TERM_BIT_POS + 1)) + << N_PCH_GPIO_TERM); + + // + // Configure GPIO pad tolerance (padtol) + // + Dw1RegMask |= + ((((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_PADTOL_MASK) >> + GPIO_CONF_PADTOL_BIT_POS) == GpioHardwareDefault) + ? 0x0 + : B_PCH_GPIO_PADTOL); + Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig & + GPIO_CONF_PADTOL_MASK) >> + (GPIO_CONF_PADTOL_BIT_POS + 1)) + << N_PCH_GPIO_PADTOL); + + // + // Check for additional requirements on setting PADCFG register + // + + // + // Create PADCFG register offset using group and pad number + // + PadCfgReg = 0x8 * PadNumber + + GpioGroupInfo[GroupIndex].PadCfgOffset; + Data32 = read32((void *)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, PadCfgReg)); + + FinalValue = ((Data32 & (~Dw0RegMask)) | Dw0Reg); + + PadMode1 = + (Data32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE; + PadMode2 = + (Dw0Reg & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE; + + if (((Data32 & B_PCH_GPIO_PAD_MODE) != + (FinalValue & B_PCH_GPIO_PAD_MODE)) || + (PadMode2 == 0)) { + printk(BIOS_DEBUG, "Changing GpioPad PID: %x Offset: " + "0x%x PadModeP1: %d P2: %d ", + GpioGroupInfo[GroupIndex].Community, PadCfgReg, + PadMode1, PadMode2); + printk(BIOS_DEBUG, "R: 0x%08x Fx%08x !\n", Data32, + FinalValue); + // + // Write PADCFG DW0 register`` + // + mmio_andthenor32( + (void *)(uint32_t)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, + PadCfgReg), + ~(uint32_t)Dw0RegMask, (uint32_t)Dw0Reg); + } + + Data32 = read32((void *)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, PadCfgReg + 0x4)); + FinalValue = ((Data32 & (~Dw1RegMask)) | Dw1Reg); + if (Data32 != FinalValue) { + // + // Write PADCFG DW1 register + // + mmio_andthenor32( + (void *)(uint32_t)PCH_PCR_ADDRESS( + GpioGroupInfo[GroupIndex].Community, + PadCfgReg + 0x4), + ~(uint32_t)Dw1RegMask, (uint32_t)Dw1Reg); + } + + // + // Update value to be programmed in HOSTSW_OWN register + // + HostSoftOwnRegMask[GroupIndex] |= LShiftU64( + (uint64_t)GpioData->GpioConfig.HostSoftPadOwn & 0x1, + PadNumber); + HostSoftOwnReg[GroupIndex] |= LShiftU64( + (uint64_t)GpioData->GpioConfig.HostSoftPadOwn >> 0x1, + PadNumber); + + // + // Update value to be programmed in GPI_GPE_EN register + // + GpiGpeEnRegMask[GroupIndex] |= LShiftU64( + (uint64_t)(GpioData->GpioConfig.InterruptConfig & 0x1), + PadNumber); + GpiGpeEnReg[GroupIndex] |= LShiftU64( + (uint64_t)(GpioData->GpioConfig.InterruptConfig & + GpioIntSci) >> + 3, + PadNumber); + } + + for (Index = 0; Index < NumberOfGroups; Index++) { + // + // Write HOSTSW_OWN registers + // + if (GpioGroupInfo[Index].HostOwnOffset != + NO_REGISTER_FOR_PROPERTY) { + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].HostOwnOffset), + ~(uint32_t)(HostSoftOwnRegMask[Index] & + 0xFFFFFFFF), + (uint32_t)(HostSoftOwnReg[Index] & 0xFFFFFFFF)); + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].HostOwnOffset + + 0x4), + ~(uint32_t)(RShiftU64(HostSoftOwnRegMask[Index], + 32)), + (uint32_t)( + RShiftU64(HostSoftOwnReg[Index], 32))); + } + + // + // Write GPI_GPE_EN registers + // + if (GpioGroupInfo[Index].GpiGpeEnOffset != + NO_REGISTER_FOR_PROPERTY) { + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].GpiGpeEnOffset), + ~(uint32_t)(GpiGpeEnRegMask[Index] & + 0xFFFFFFFF), + (uint32_t)(GpiGpeEnReg[Index] & 0xFFFFFFFF)); + mmio_andthenor32( + (void *)PCH_PCR_ADDRESS( + GpioGroupInfo[Index].Community, + GpioGroupInfo[Index].GpiGpeEnOffset + + 0x4), + ~(uint32_t)( + RShiftU64(GpiGpeEnRegMask[Index], 32)), + (uint32_t)(RShiftU64(GpiGpeEnReg[Index], 32))); + } + } +} diff --git a/src/soc/intel/denverton_ns/hob_display.c b/src/soc/intel/denverton_ns/hob_display.c new file mode 100644 index 0000000000..39b799d522 --- /dev/null +++ b/src/soc/intel/denverton_ns/hob_display.c @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <fsp/util.h> +#include <lib.h> + +static const uint8_t fsp_hob_resource_owner_graphics_guid[16] = { + 0xa7, 0x3a, 0x7c, 0x9c, 0x32, 0x55, 0x17, 0x49, + 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 +}; + +static const uint8_t fsp_hob_resource_owner_fiamux_guid[16] = { + 0x2e, 0x49, 0xad, 0x26, 0x51, 0xf9, 0x43, 0x4e, + 0xbc, 0x72, 0x22, 0x76, 0x58, 0xb1, 0xf6, 0x23 +}; + +static const uint8_t fsp_hob_fast_boot_checker_guid[16] = { + 0x7b, 0xf0, 0x97, 0x78, 0xda, 0x0c, 0xe3, 0x40, + 0xb4, 0xe4, 0x51, 0x5f, 0x47, 0x3b, 0x04, 0xb6 +}; + +struct guid_name_map { + const void *guid; + const char *name; +}; + +static const struct guid_name_map guid_names[] = { + { fsp_hob_resource_owner_graphics_guid, + "FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID" }, + { fsp_hob_resource_owner_fiamux_guid, + "FSP_HOB_RESOURCE_OWNER_FIAMUX_GUID" }, + { fsp_hob_fast_boot_checker_guid, + "FSP_HOB_FAST_BOOT_CHECKER_GUID" }, +}; + +const char *soc_get_hob_type_name( + const struct hob_header *hob) +{ + return NULL; +} + +const char *soc_get_guid_name(const uint8_t *guid) +{ + size_t index; + + /* Compare the GUID values in this module */ + for (index = 0; index < ARRAY_SIZE(guid_names); index++) + if (fsp_guid_compare(guid, guid_names[index].guid)) + return guid_names[index].name; + + return NULL; +} + +void soc_display_hob(const struct hob_header *hob) +{ + hexdump(hob, hob->length); +} diff --git a/src/soc/intel/denverton_ns/include/soc/acpi.h b/src/soc/intel/denverton_ns/include/soc/acpi.h new file mode 100644 index 0000000000..dd2be4dd42 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/acpi.h @@ -0,0 +1,34 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_ACPI_H_ +#define _DENVERTON_NS_ACPI_H_ + +#include <arch/acpi.h> +#include <soc/nvs.h> + +void acpi_create_intel_hpet(acpi_hpet_t *hpet); +void acpi_create_serialio_ssdt(acpi_header_t *ssdt); +void acpi_fill_in_fadt(acpi_fadt_t *fadt); +unsigned long acpi_madt_irq_overrides(unsigned long current); +void acpi_init_gnvs(global_nvs_t *gnvs); +unsigned long southcluster_write_acpi_tables(device_t device, + unsigned long current, + struct acpi_rsdp *rsdp); +void southcluster_inject_dsdt(device_t device); + +#endif /* _DENVERTON_NS_ACPI_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/bootblock.h b/src/soc/intel/denverton_ns/include/soc/bootblock.h new file mode 100644 index 0000000000..8e58529770 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/bootblock.h @@ -0,0 +1,33 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016-2017 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_DENVERTON_NS_BOOTBLOCK_H_ +#define _SOC_DENVERTON_NS_BOOTBLOCK_H_ + +/* Bootblock pre console init programing */ +//void bootblock_cpu_init(void); +//void bootblock_pch_early_init(void); +//void bootblock_systemagent_early_init(void); +void early_uart_init(void); + +/* Bootblock post console init programing */ +//void enable_smbus(void); +//void i2c_early_init(void); +//void pch_early_init(void); +//void report_platform_info(void); +//void report_memory_config(void); +//void set_max_freq(void); + +#endif diff --git a/src/soc/intel/denverton_ns/include/soc/cpu.h b/src/soc/intel/denverton_ns/include/soc/cpu.h new file mode 100644 index 0000000000..7fd2e94af0 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/cpu.h @@ -0,0 +1,45 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _CPU_INTEL_DENVERTON_NS_H +#define _CPU_INTEL_DENVERTON_NS_H + +int get_cpu_count(void); + +#ifndef __ASSEMBLER__ +#include <device/device.h> + +void denverton_init_cpus(struct device *dev); +#endif + +/* Everything below this line is ignored in the DSDT */ +#ifndef __ACPI__ + +/* Denverton-NS CPUID */ +#define CPUID_DENVERTON_A0_A1 0x506f0 +#define CPUID_DENVERTON_B0 0x506f1 + +#define MSR_CORE_THREAD_COUNT 0x35 +#define CORE_BIT_MSK 0x1 +#define MCH_BAR_CORE_EXISTS_MASK 0x7164 +#define MCH_BAR_CORE_DISABLE_MASK 0x7168 + +/* CPU bus clock is fixed at 100MHz */ +#define CPU_BCLK 100 + +#endif /* __ACPI__ */ + +#endif /* _CPU_INTEL_DENVERTON_NS_H */ diff --git a/src/soc/intel/denverton_ns/include/soc/fiamux.h b/src/soc/intel/denverton_ns/include/soc/fiamux.h new file mode 100644 index 0000000000..e8aaf65f11 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/fiamux.h @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MAINBOARD_HARCUVAR_FIAMUX_H +#define _MAINBOARD_HARCUVAR_FIAMUX_H + +#include <fsp/util.h> + +int get_fiamux_hsio_info(uint16_t num_of_lanes, size_t num_of_entry, + BL_HSIO_INFORMATION **config); + +BL_FIA_MUX_CONFIG_HOB *get_fiamux_hob_data(void); +void print_fiamux_config_hob(BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data); + +#endif // _MAINBOARD_HARCUVAR_FIAMUX_H diff --git a/src/soc/intel/denverton_ns/include/soc/gpio.h b/src/soc/intel/denverton_ns/include/soc/gpio.h new file mode 100644 index 0000000000..964b5e0715 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/gpio.h @@ -0,0 +1,309 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_GPIO_H_ +#define _DENVERTON_NS_GPIO_H_ + +#define RShiftU64(Operand, Count) (Operand >> Count) +#define LShiftU64(Operand, Count) (Operand << Count) + +#include <soc/gpio_defs.h> + +#ifndef __ACPI__ +#include <stdint.h> +#include <stddef.h> + +// +// Structure for storing information about registers offset, community, +// maximal pad number for available groups +// +struct GPIO_GROUP_INFO { + uint32_t Community; + uint32_t PadOwnOffset; + uint32_t HostOwnOffset; + uint32_t GpiIsOffset; + uint32_t GpiIeOffset; + uint32_t GpiGpeStsOffset; + uint32_t GpiGpeEnOffset; + uint32_t SmiStsOffset; + uint32_t SmiEnOffset; + uint32_t NmiStsOffset; + uint32_t NmiEnOffset; + uint32_t PadCfgLockOffset; + uint32_t PadCfgLockTxOffset; + uint32_t PadCfgOffset; + uint32_t PadPerGroup; +}; + +// +// If in GPIO_GROUP_INFO structure certain register doesn't exist +// it will have value equal to NO_REGISTER_FOR_PROPERTY +// +#define NO_REGISTER_FOR_PROPERTY (~0u) + +// +// Below defines are based on GPIO_CONFIG structure fields +// +#define GPIO_CONF_PAD_MODE_MASK 0xF +#define GPIO_CONF_PAD_MODE_BIT_POS 0 +#define GPIO_CONF_HOST_OWN_MASK 0x3 +#define GPIO_CONF_HOST_OWN_BIT_POS 0 +#define GPIO_CONF_DIR_MASK 0x7 +#define GPIO_CONF_DIR_BIT_POS 0 +#define GPIO_CONF_INV_MASK 0x18 +#define GPIO_CONF_INV_BIT_POS 3 +#define GPIO_CONF_OUTPUT_MASK 0x3 +#define GPIO_CONF_OUTPUT_BIT_POS 0 +#define GPIO_CONF_INT_ROUTE_MASK 0x1F +#define GPIO_CONF_INT_ROUTE_BIT_POS 0 +#define GPIO_CONF_INT_TRIG_MASK 0xE0 +#define GPIO_CONF_INT_TRIG_BIT_POS 5 +#define GPIO_CONF_RESET_MASK 0x7 +#define GPIO_CONF_RESET_BIT_POS 0 +#define GPIO_CONF_TERM_MASK 0x1F +#define GPIO_CONF_TERM_BIT_POS 0 +#define GPIO_CONF_PADTOL_MASK 0x60 +#define GPIO_CONF_PADTOL_BIT_POS 5 +#define GPIO_CONF_LOCK_MASK 0x7 +#define GPIO_CONF_LOCK_BIT_POS 0 +#define GPIO_CONF_RXRAW_MASK 0x3 +#define GPIO_CONF_RXRAW_BIT_POS 0 + +/** +GPIO configuration structure used for pin programming. +Structure contains fields that can be used to configure pad. +**/ +struct GPIO_CONFIG { + /** + Pad Mode + Pad can be set as GPIO or one of its native functions. + When in native mode setting Direction (except Inversion), OutputState, + InterruptConfig and Host Software Pad Ownership are unnecessary. + Refer to definition of GPIO_PAD_MODE. + Refer to EDS for each native mode according to the pad. + **/ + uint32_t PadMode : 4; + /** + Host Software Pad Ownership + Set pad to ACPI mode or GPIO Driver Mode. + Refer to definition of GPIO_HOSTSW_OWN. + **/ + uint32_t HostSoftPadOwn : 2; + /** + GPIO Direction + Can choose between In, In with inversion Out, both In and Out, both In + with inversion and out or disabling both. + Refer to definition of GPIO_DIRECTION for supported settings. + **/ + uint32_t Direction : 5; + /** + Output State + Set Pad output value. + Refer to definition of GPIO_OUTPUT_STATE for supported settings. + This setting takes place when output is enabled. + **/ + uint32_t OutputState : 2; + /** + GPIO Interrupt Configuration + Set Pad to cause one of interrupts (IOxAPIC/SCI/SMI/NMI). This setting + is applicable only if GPIO is in input mode. + If GPIO is set to cause an SCI then also Gpe is enabled for this pad. + Refer to definition of GPIO_INT_CONFIG for supported settings. + **/ + uint32_t InterruptConfig : 8; + /** + GPIO Power Configuration. + This setting controls Pad Reset Configuration. + Refer to definition of GPIO_RESET_CONFIG for supported settings. + **/ + uint32_t PowerConfig : 4; + + /** + GPIO Electrical Configuration + This setting controls pads termination and voltage tolerance. + Refer to definition of GPIO_ELECTRICAL_CONFIG for supported settings. + **/ + uint32_t ElectricalConfig : 7; + + /** + GPIO Lock Configuration + This setting controls pads lock. + Refer to definition of GPIO_LOCK_CONFIG for supported settings. + **/ + uint32_t LockConfig : 3; + /** + Additional GPIO configuration + Refer to definition of GPIO_OTHER_CONFIG for supported settings. + **/ + uint32_t OtherSettings : 2; + uint32_t RsvdBits : 27; ///< Reserved bits for future extension +} __attribute__((packed)); + +typedef enum { GpioHardwareDefault = 0x0 } GPIO_HARDWARE_DEFAULT; + +/// +/// GPIO Pad Mode +/// +typedef enum { + GpioPadModeGpio = 0x1, + GpioPadModeNative1 = 0x3, + GpioPadModeNative2 = 0x5, + GpioPadModeNative3 = 0x7, + GpioPadModeNative4 = 0x9 +} GPIO_PAD_MODE; + +/// +/// Host Software Pad Ownership modes +/// +typedef enum { + GpioHostOwnDefault = 0x0, ///< Leave ownership value unmodified + GpioHostOwnAcpi = 0x1, ///< Set HOST ownership to ACPI + GpioHostOwnGpio = 0x3 ///< Set HOST ownership to GPIO +} GPIO_HOSTSW_OWN; + +/// +/// GPIO Direction +/// +typedef enum { + GpioDirDefault = 0x0, ///< Leave pad direction setting unmodified + GpioDirInOut = + (0x1 | (0x1 << 3)), ///< Set pad for both output and input + GpioDirInInvOut = (0x1 | (0x3 << 3)), ///< Set pad for both output and + ///input with inversion + GpioDirIn = (0x3 | (0x1 << 3)), ///< Set pad for input only + GpioDirInInv = (0x3 | (0x3 << 3)), ///< Set pad for input with inversion + GpioDirOut = 0x5, ///< Set pad for output only + GpioDirNone = 0x7 ///< Disable both output and input +} GPIO_DIRECTION; + +/// +/// GPIO Output State +/// +typedef enum { + GpioOutDefault = 0x0, ///< Leave output value unmodified + GpioOutLow = 0x1, ///< Set output to low + GpioOutHigh = 0x3 ///< Set output to high +} GPIO_OUTPUT_STATE; + +/// +/// GPIO interrupt configuration +/// This setting is applicable only if GPIO is in input mode. +/// GPIO_INT_CONFIG allows to choose which interrupt is generated +/// (IOxAPIC/SCI/SMI/NMI) +/// and how it is triggered (edge or level). +/// Field from GpioIntNmi to GpioIntApic can be OR'ed with GpioIntLevel to +/// GpioIntBothEdgecan +/// to describe an interrupt e.g. GpioIntApic | GpioIntLevel +/// If GPIO is set to cause an SCI then also Gpe is enabled for this pad. +/// Not all GPIO are capable of generating an SMI or NMI interrupt +/// + +typedef enum { + GpioIntDefault = 0x0, ///< Leave value of interrupt routing unmodified + GpioIntDis = 0x1, ///< Disable IOxAPIC/SCI/SMI/NMI interrupt generation + GpioIntNmi = 0x3, ///< Enable NMI interrupt only + GpioIntSmi = 0x5, ///< Enable SMI interrupt only + GpioIntSci = 0x9, ///< Enable SCI interrupt only + GpioIntApic = 0x11, ///< Enable IOxAPIC interrupt only + GpioIntLevel = (0x1 << 5), ///< Set interrupt as level triggered + GpioIntEdge = (0x3 << 5), ///< Set interrupt as edge triggered (type of + ///edge depends on input inversion) + GpioIntLvlEdgDis = (0x5 << 5), ///< Disable interrupt trigger + GpioIntBothEdge = (0x7 << 5) ///< Set interrupt as both edge triggered +} GPIO_INT_CONFIG; + +/// +/// GPIO Power Configuration +/// GPIO_RESET_CONFIG allows to set GPIO Reset (used to reset the specified +/// Pad Register fields). +/// +typedef enum { + GpioResetDefault = 0x0, ///< Leave value of pad reset unmodified + GpioResetPwrGood = 0x1, ///< Powergood reset + GpioResetDeep = 0x3, ///< Deep GPIO Reset + GpioResetNormal = 0x5, ///< GPIO Reset + GpioResetResume = 0x7 ///< Resume Reset (applicable only for GPD group) +} GPIO_RESET_CONFIG; + +/// +/// GPIO Electrical Configuration +/// Set GPIO termination and Pad Tolerance (applicable only for some pads) +/// Field from GpioTermDefault to GpioTermNative can be OR'ed with +/// GpioTolerance1v8. +/// +typedef enum { + GpioTermDefault = 0x0, ///< Leave termination setting unmodified + GpioTermNone = 0x1, ///< none + GpioTermWpd5K = 0x5, ///< 5kOhm weak pull-down + GpioTermWpd20K = 0x9, ///< 20kOhm weak pull-down + GpioTermWpu1K = 0x13, ///< 1kOhm weak pull-up + GpioTermWpu2K = 0x17, ///< 2kOhm weak pull-up + GpioTermWpu5K = 0x15, ///< 5kOhm weak pull-up + GpioTermWpu20K = 0x19, ///< 20kOhm weak pull-up + GpioTermWpu1K2K = 0x1B, ///< 1kOhm & 2kOhm weak pull-up + GpioTermNative = 0x1F, ///< Native function controls pads termination + GpioNoTolerance1v8 = (0x1 << 5), ///< Disable 1.8V pad tolerance + GpioTolerance1v8 = (0x3 << 5) ///< Enable 1.8V pad tolerance +} GPIO_ELECTRICAL_CONFIG; + +/// +/// GPIO LockConfiguration +/// Set GPIO configuration lock and output state lock +/// GpioLockPadConfig and GpioLockOutputState can be OR'ed +/// +typedef enum { + GpioLockDefault = 0x0, ///< Leave lock setting unmodified + GpioPadConfigLock = 0x3, ///< Lock Pad Configuration + GpioOutputStateLock = 0x5 ///< Lock GPIO pad output value +} GPIO_LOCK_CONFIG; + +/// +/// Other GPIO Configuration +/// GPIO_OTHER_CONFIG is used for less often settings and for future extensions +/// Supported settings: +/// - RX raw override to '1' - allows to override input value to '1' +/// This setting is applicable only if in input mode (both in GPIO and +/// native usage). +/// The override takes place at the internal pad state directly from buffer +/// and before the RXINV. +/// +typedef enum { + GpioRxRaw1Default = 0x0, ///< Use default input override value + GpioRxRaw1Dis = 0x1, ///< Don't override input + GpioRxRaw1En = 0x3 ///< Override input to '1' +} GPIO_OTHER_CONFIG; + +// +// Possible values of Pad Ownership +// +typedef enum { + GpioPadOwnHost = 0x0, + GpioPadOwnCsme = 0x1, + GpioPadOwnIsh = 0x2, +} GPIO_PAD_OWN; + +typedef uint32_t GPIO_PAD; + +struct pad_config { + GPIO_PAD GpioPad; + struct GPIO_CONFIG GpioConfig; +}; + +/* Configure GPIOs with mainboard provided settings */ +void gpio_configure_pads(const struct pad_config *gpio, size_t num); + +#endif /* __ACPI__ */ +#endif /* _DENVERTON_NS_GPIO_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/gpio_defs.h b/src/soc/intel/denverton_ns/include/soc/gpio_defs.h new file mode 100644 index 0000000000..9b63a0837c --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/gpio_defs.h @@ -0,0 +1,500 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc. + * Copyright (C) 2015-2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_GPIO_DEFS_H_ +#define _DENVERTON_NS_GPIO_DEFS_H_ + +#include <soc/pcr.h> + +/* +* There are 3 GPIO groups. North Community, South Community DFX/Group0/Group1. +* The GPIO groups are accessed through register blocks called communities. +*/ + +#define V_PCH_GPIO_NC_PAD_MAX 41 +#define V_PCH_GPIO_SC_DFX_PAD_MAX 18 +#define V_PCH_GPIO_SC0_PAD_MAX 53 +#define V_PCH_GPIO_SC1_PAD_MAX 42 +#define V_PCH_GPIO_GROUP_MAX 4 + +// +// GPIO Community 0 Private Configuration Registers +// + +// +// Power Group NORTH_ALL +// +#define R_PCH_PCR_GPIO_NC_PAD_OWN 0x20 +#define R_PCH_PCR_GPIO_NC_GPI_VWM_EN 0x70 +#define R_PCH_PCR_GPIO_NC_PADCFGLOCK 0x90 +#define R_PCH_PCR_GPIO_NC_PADCFGLOCKTX 0x94 +#define R_PCH_PCR_GPIO_NC1_PADCFGLOCK_1 0x98 +#define R_PCH_PCR_GPIO_NC1_PADCFGLOCKTX_1 0x9C +#define R_PCH_PCR_GPIO_NC_HOSTSW_OWN 0xC0 +#define R_PCH_PCR_GPIO_NC_GPI_IS 0x0100 +#define R_PCH_PCR_GPIO_NC_GPI_IE 0x0120 +#define R_PCH_PCR_GPIO_NC_GPI_GPE_STS 0x0140 +#define R_PCH_PCR_GPIO_NC_GPI_GPE_EN 0x0160 +#define R_PCH_PCR_GPIO_NC_SMI_STS 0x0180 +#define R_PCH_PCR_GPIO_NC_SMI_EN 0x01A0 +#define R_PCH_PCR_GPIO_NC_NMI_STS 0x01C0 +#define R_PCH_PCR_GPIO_NC_NMI_EN 0x01E0 +#define R_PCH_PCR_GPIO_NC_PADCFG_OFFSET 0x400 + +// +// GPIO Community 1 Private Configuration Registers +// + +// +// Power Group SOUTH_DFX +// +#define R_PCH_PCR_GPIO_SC_DFX_PAD_OWN 0x20 +#define R_PCH_PCR_GPIO_SC_DFX_GPI_VWM_EN 0x70 +#define R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK 0x90 +#define R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX 0x94 +#define R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN 0xC0 +#define R_PCH_PCR_GPIO_SC_DFX_GPI_IS 0x0100 +#define R_PCH_PCR_GPIO_SC_DFX_GPI_IE 0x0120 +#define R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS 0x0140 +#define R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN 0x0160 +#define R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET 0x400 +// +// Power Group SOUTH_GROUP0 +// +#define R_PCH_PCR_GPIO_SC0_PAD_OWN 0x2C +#define R_PCH_PCR_GPIO_SC0_GPI_VWM_EN 0x74 +#define R_PCH_PCR_GPIO_SC0_PADCFGLOCK 0x98 +#define R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX 0x9C +#define R_PCH_PCR_GPIO_SC0_HOSTSW_OWN 0xC4 +#define R_PCH_PCR_GPIO_SC0_GPI_IS 0x0104 +#define R_PCH_PCR_GPIO_SC0_GPI_IE 0x0124 +#define R_PCH_PCR_GPIO_SC0_GPI_GPE_STS 0x0144 +#define R_PCH_PCR_GPIO_SC0_GPI_GPE_EN 0x0164 +#define R_PCH_PCR_GPIO_SC0_SMI_STS 0x0184 +#define R_PCH_PCR_GPIO_SC0_SMI_EN 0x01A4 +#define R_PCH_PCR_GPIO_SC0_NMI_STS 0x01C4 +#define R_PCH_PCR_GPIO_SC0_NMI_EN 0x01E4 +#define R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET 0x490 +// +// Power Group SOUTH_GROUP1 +// +#define R_PCH_PCR_GPIO_SC1_PAD_OWN 0x48 +#define R_PCH_PCR_GPIO_SC1_GPI_VWM_EN 0x7C +#define R_PCH_PCR_GPIO_SC1_PADCFGLOCK 0xA8 +#define R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX 0xAC +#define R_PCH_PCR_GPIO_SC1_HOSTSW_OWN 0xCC +#define R_PCH_PCR_GPIO_SC1_GPI_IS 0x010C +#define R_PCH_PCR_GPIO_SC1_GPI_IE 0x012C +#define R_PCH_PCR_GPIO_SC1_GPI_GPE_STS 0x014C +#define R_PCH_PCR_GPIO_SC1_GPI_GPE_EN 0x016C +#define R_PCH_PCR_GPIO_SC1_SMI_STS 0x018C +#define R_PCH_PCR_GPIO_SC1_SMI_EN 0x01AC +#define R_PCH_PCR_GPIO_SC1_NMI_STS 0x01CC +#define R_PCH_PCR_GPIO_SC1_NMI_EN 0x01EC +#define R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET 0x638 + +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_NORTH_ALL_0 0x90 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_NORTH_ALL_0 0x94 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_NORTH_ALL_1 0x98 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_NORTH_ALL_1 0x9C + +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_DFX_0 0x90 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_DFX_0 0x94 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP0_0 0x98 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP0_0 0x9C +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP0_1 0xA0 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP0_1 0xA4 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP1_0 0xA8 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP1_0 0xAC +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP1_1 0xB0 +#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP1_1 0xB4 + +// +// Pad Configuration Register DW0 +// + +// Pad Reset Config +#define B_PCH_GPIO_RST_CONF ((1 << 31) | (1 << 30)) +#define N_PCH_GPIO_RST_CONF 30 +#define V_PCH_GPIO_RST_CONF_POW_GOOD 0x00 +#define V_PCH_GPIO_RST_CONF_DEEP_RST 0x01 +#define V_PCH_GPIO_RST_CONF_GPIO_RST 0x02 +#define V_PCH_GPIO_RST_CONF_RESUME_RST 0x03 // Only for GPD Group + +// RX Pad State Select +#define B_PCH_GPIO_RX_PAD_STATE (1 << 29) +#define N_PCH_GPIO_RX_PAD_STATE 29 +#define V_PCH_GPIO_RX_PAD_STATE_RAW 0x00 +#define V_PCH_GPIO_RX_PAD_STATE_INT 0x01 + +// RX Raw Overrride to 1 +#define B_PCH_GPIO_RX_RAW1 (1 << 28) +#define N_PCH_GPIO_RX_RAW1 28 +#define V_PCH_GPIO_RX_RAW1_DIS 0x00 +#define V_PCH_GPIO_RX_RAW1_EN 0x01 + +// RX Level/Edge Configuration +#define B_PCH_GPIO_RX_LVL_EDG ((1 << 26) | (1 << 25)) +#define N_PCH_GPIO_RX_LVL_EDG 25 +#define V_PCH_GPIO_RX_LVL_EDG_LVL 0x00 +#define V_PCH_GPIO_RX_LVL_EDG_EDG 0x01 +#define V_PCH_GPIO_RX_LVL_EDG_0 0x02 +#define V_PCH_GPIO_RX_LVL_EDG_RIS_FAL 0x03 + +// RX Level/Edge Configuration +#define B_PCH_GPIO_PRE_GFRX_SEL (1 << 24) +#define N_PCH_GPIO_PRE_GFRX_SEL 24 +#define V_PCH_GPIO_PRE_GFRX_SEL_DIS 0x00 +#define V_PCH_GPIO_PRE_GFRX_SEL_EN 0x01 + +// RX Invert +#define B_PCH_GPIO_RXINV (1 << 23) +#define N_PCH_GPIO_RXINV 23 +#define V_PCH_GPIO_RXINV_NO 0x00 +#define V_PCH_GPIO_RXINV_YES 0x01 + +// RXTXENCFG +#define B_PCH_GPIO_RXTXENCFG ((1 << 22) | (1 << 21)) +#define N_PCH_GPIO_RXTXENCFG 21 +#define V_PCH_GPIO_RXTXENCFG_DEF_FUN 0x00 +#define V_PCH_GPIO_RXTXENCFG_TX_EN_L 0x01 +#define V_PCH_GPIO_RXTXENCFG_TX_EN_H 0x02 +#define V_PCH_GPIO_RXTXENCFG_TXRXEN 0x03 + +// GPIO Input Route IOxAPIC +#define B_PCH_GPIO_RX_APIC_ROUTE (1 << 20) +#define N_PCH_GPIO_RX_APIC_ROUTE 20 +#define V_PCH_GPIO_RX_APIC_ROUTE_DIS 0x00 +#define V_PCH_GPIO_RX_APIC_ROUTE_EN 0x01 + +// GPIO Input Route SCI +#define B_PCH_GPIO_RX_SCI_ROUTE (1 << 10) +#define N_PCH_GPIO_RX_SCI_ROUTE 19 +#define V_PCH_GPIO_RX_SCI_ROUTE_DIS 0x00 +#define V_PCH_GPIO_RX_SCI_ROUTE_EN 0x01 + +// GPIO Input Route SMI +#define B_PCH_GPIO_RX_SMI_ROUTE (1 << 18) +#define N_PCH_GPIO_RX_SMI_ROUTE 18 +#define V_PCH_GPIO_RX_SMI_ROUTE_DIS 0x00 +#define V_PCH_GPIO_RX_SMI_ROUTE_EN 0x01 + +// GPIO Input Route NMI +#define B_PCH_GPIO_RX_NMI_ROUTE (1 << 17) +#define N_PCH_GPIO_RX_NMI_ROUTE 17 +#define V_PCH_GPIO_RX_NMI_ROUTE_DIS 0x00 +#define V_PCH_GPIO_RX_NMI_ROUTE_EN 0x01 + +// GPIO Pad Mode +#define B_PCH_GPIO_PAD_MODE ((1 << 12) | (1 << 11) | (1 << 10)) +#define N_PCH_GPIO_PAD_MODE 10 +#define V_PCH_GPIO_PAD_MODE_GPIO 0 +#define V_PCH_GPIO_PAD_MODE_NAT_1 1 +#define V_PCH_GPIO_PAD_MODE_NAT_2 2 +#define V_PCH_GPIO_PAD_MODE_NAT_3 3 +#define V_PCH_GPIO_PAD_MODE_NAT_4 4 +#define V_PCH_GPIO_PAD_MODE_NAT_5 5 +#define V_PCH_GPIO_PAD_MODE_NAT_6 6 +#define V_PCH_GPIO_PAD_MODE_NAT_7 7 + +// GPIO RX Disable +#define B_PCH_GPIO_RXDIS (1 << 9) +#define N_PCH_GPIO_RXDIS 9 +#define V_PCH_GPIO_RXDIS_EN 0x00 +#define V_PCH_GPIO_RXDIS_DIS 0x01 + +// GPIO TX Disable +#define B_PCH_GPIO_TXDIS (1 << 8) +#define N_PCH_GPIO_TXDIS 8 +#define V_PCH_GPIO_TXDIS_EN 0x00 +#define V_PCH_GPIO_TXDIS_DIS 0x01 + +// GPIO RX State +#define B_PCH_GPIO_RX_STATE (1 << 1) +#define N_PCH_GPIO_RX_STATE 1 +#define V_PCH_GPIO_RX_STATE_LOW 0x00 +#define V_PCH_GPIO_RX_STATE_HIGH 0x01 + +// GPIO TX State +#define B_PCH_GPIO_TX_STATE (1 << 0) +#define N_PCH_GPIO_TX_STATE 0 +#define V_PCH_GPIO_TX_STATE_LOW 0x00 +#define V_PCH_GPIO_TX_STATE_HIGH 0x01 + +// +// Pad Configuration Register DW1 +// + +// Padtol +#define B_PCH_GPIO_PADTOL (1 << 25) +#define N_PCH_GPIO_PADTOL 25 +#define V_PCH_GPIO_PADTOL_NONE 0x00 +#define V_PCH_GPIO_PADTOL_CLEAR 0x00 +#define V_PCH_GPIO_PADTOL_SET 0x01 + +// Termination +#define B_PCH_GPIO_TERM ((1 << 13) | (1 << 12) | (1 << 11) | (1 << 10)) +#define N_PCH_GPIO_TERM 10 +#define V_PCH_GPIO_TERM_WPD_NONE 0x00 +#define V_PCH_GPIO_TERM_WPD_5K 0x02 +#define V_PCH_GPIO_TERM_WPD_20K 0x04 +#define V_PCH_GPIO_TERM_WPU_NONE 0x08 +#define V_PCH_GPIO_TERM_WPU_1K 0x09 +#define V_PCH_GPIO_TERM_WPU_2K 0x0B +#define V_PCH_GPIO_TERM_WPU_5K 0x0A +#define V_PCH_GPIO_TERM_WPU_20K 0x0C +#define V_PCH_GPIO_TERM_WPU_1K_2K 0x0D +#define V_PCH_GPIO_TERM_NATIVE 0x0F + +#define PID_NorthCommunity PID_GPIOCOM0 +#define PID_SouthCommunity PID_GPIOCOM1 + +// GPIO_MISC0 +// HSUART0: 101, 102, 13, 98 +// HSUART1: 96, 97,95 94 + +#define GPIO_SMB3_CLTT_DATA 12 +#define R_PAD_CFG_DW0_SMB3_CLTT_DATA 0x490 +#define PID_SMB3_CLTT_DATA PID_SouthCommunity + +#define GPIO_SMB3_CLTT_CLK 13 +#define R_PAD_CFG_DW0_SMB3_CLTT_CLK 0x498 +#define PID_SMB3_CLTT_CLK PID_SouthCommunity + +#define GPIO_PCIE_CLKREQ5_N 98 +#define R_PAD_CFG_DW0_PCIE_CLKREQ5_N 0x4A0 +#define PID_PCIE_CLKREQ5_N PID_SouthCommunity + +#define GPIO_PCIE_CLKREQ6_N 99 +#define R_PAD_CFG_DW0_PCIE_CLKREQ6_N 0x4a8 +#define PID_PCIE_CLKREQ6_N PID_SouthCommunity + +#define GPIO_PCIE_CLKREQ7_N 100 +#define R_PAD_CFG_DW0_PCIE_CLKREQ7_N 0x4b0 +#define PID_PCIE_CLKREQ7_N PID_SouthCommunity + +#define GPIO_UART0_RXD 101 +#define R_PAD_CFG_DW0_UART0_RXD 0x4b8 +#define PID_UART0_RXD PID_SouthCommunity + +#define GPIO_UART0_TXD 102 +#define R_PAD_CFG_DW0_UART0_TXD 0x4c0 +#define PID_UART0_TXD PID_SouthCommunity + +#define GPIO_UART1_RXD 96 +#define R_PAD_CFG_DW0_UART1_RXD 0x5b8 +#define PID_UART1_RXD PID_SouthCommunity + +#define GPIO_UART1_TXD 97 +#define R_PAD_CFG_DW0_UART1_TXD 0x5c0 +#define PID_UART1_TXD PID_SouthCommunity + +#define GPIO_SATA1_SDOUT 95 +#define R_PAD_CFG_DW0_SATA1_SDOUT 0x5b0 +#define PID_SATA1_SDOUT PID_SouthCommunity + +#define GPIO_SATA0_SDOUT 94 +#define R_PAD_CFG_DW0_SATA0_SDOUT 0x5a8 +#define PID_SATA0_SDOUT PID_SouthCommunity + +/// +/// Denverton GPIO Groups +/// + +#define GPIO_DNV_GROUP_NC 0x0100 +#define GPIO_DNV_GROUP_SC_DFX 0x0101 +#define GPIO_DNV_GROUP_SC0 0x0102 +#define GPIO_DNV_GROUP_SC1 0x0103 +#define GPIO_DNV_GROUP_MIN GPIO_DNV_GROUP_NC +#define GPIO_DNV_GROUP_MAX GPIO_DNV_GROUP_SC1 +#define NORTH_ALL_GBE0_SDP0 0x01000000 +#define NORTH_ALL_GBE1_SDP0 0x01000001 +#define NORTH_ALL_GBE0_SDP1 0x01000002 +#define NORTH_ALL_GBE1_SDP1 0x01000003 +#define NORTH_ALL_GBE0_SDP2 0x01000004 +#define NORTH_ALL_GBE1_SDP2 0x01000005 +#define NORTH_ALL_GBE0_SDP3 0x01000006 +#define NORTH_ALL_GBE1_SDP3 0x01000007 +#define NORTH_ALL_GBE2_LED0 0x01000008 +#define NORTH_ALL_GBE2_LED1 0x01000009 +#define NORTH_ALL_GBE0_I2C_CLK 0x0100000A +#define NORTH_ALL_GBE0_I2C_DATA 0x0100000B +#define NORTH_ALL_GBE1_I2C_CLK 0x0100000C +#define NORTH_ALL_GBE1_I2C_DATA 0x0100000D +#define NORTH_ALL_NCSI_RXD0 0x0100000E +#define NORTH_ALL_NCSI_CLK_IN 0x0100000F +#define NORTH_ALL_NCSI_RXD1 0x01000010 +#define NORTH_ALL_NCSI_CRS_DV 0x01000011 +#define NORTH_ALL_NCSI_ARB_IN 0x01000012 +#define NORTH_ALL_NCSI_TX_EN 0x01000013 +#define NORTH_ALL_NCSI_TXD0 0x01000014 +#define NORTH_ALL_NCSI_TXD1 0x01000015 +#define NORTH_ALL_NCSI_ARB_OUT 0x01000016 +#define NORTH_ALL_GBE0_LED0 0x01000017 +#define NORTH_ALL_GBE0_LED1 0x01000018 +#define NORTH_ALL_GBE1_LED0 0x01000019 +#define NORTH_ALL_GBE1_LED1 0x0100001A +#define NORTH_ALL_GPIO_0 0x0100001B +#define NORTH_ALL_PCIE_CLKREQ0_N 0x0100001C +#define NORTH_ALL_PCIE_CLKREQ1_N 0x0100001D +#define NORTH_ALL_PCIE_CLKREQ2_N 0x0100001E +#define NORTH_ALL_PCIE_CLKREQ3_N 0x0100001F +#define NORTH_ALL_PCIE_CLKREQ4_N 0x01000020 +#define NORTH_ALL_GPIO_1 0x01000021 +#define NORTH_ALL_GPIO_2 0x01000022 +#define NORTH_ALL_SVID_ALERT_N 0x01000023 +#define NORTH_ALL_SVID_DATA 0x01000024 +#define NORTH_ALL_SVID_CLK 0x01000025 +#define NORTH_ALL_THERMTRIP_N 0x01000026 +#define NORTH_ALL_PROCHOT_N 0x01000027 +#define NORTH_ALL_MEMHOT_N 0x01000028 +#define SOUTH_DFX_DFX_PORT_CLK0 0x01010000 +#define SOUTH_DFX_DFX_PORT_CLK1 0x01010001 +#define SOUTH_DFX_DFX_PORT0 0x01010002 +#define SOUTH_DFX_DFX_PORT1 0x01010003 +#define SOUTH_DFX_DFX_PORT2 0x01010004 +#define SOUTH_DFX_DFX_PORT3 0x01010005 +#define SOUTH_DFX_DFX_PORT4 0x01010006 +#define SOUTH_DFX_DFX_PORT5 0x01010007 +#define SOUTH_DFX_DFX_PORT6 0x01010008 +#define SOUTH_DFX_DFX_PORT7 0x01010009 +#define SOUTH_DFX_DFX_PORT8 0x0101000A +#define SOUTH_DFX_DFX_PORT9 0x0101000B +#define SOUTH_DFX_DFX_PORT10 0x0101000C +#define SOUTH_DFX_DFX_PORT11 0x0101000D +#define SOUTH_DFX_DFX_PORT12 0x0101000E +#define SOUTH_DFX_DFX_PORT13 0x0101000F +#define SOUTH_DFX_DFX_PORT14 0x01010010 +#define SOUTH_DFX_DFX_PORT15 0x01010011 +#define SOUTH_GROUP0_SMB3_CLTT_DATA 0x01020000 +#define SOUTH_GROUP0_SMB3_CLTT_CLK 0x01020001 +#define SOUTH_GROUP0_GPIO_12 0x01020000 +#define SOUTH_GROUP0_SMB5_GBE_ALRT_N 0x01020001 +#define SOUTH_GROUP0_PCIE_CLKREQ5_N 0x01020002 +#define SOUTH_GROUP0_PCIE_CLKREQ6_N 0x01020003 +#define SOUTH_GROUP0_PCIE_CLKREQ7_N 0x01020004 +#define SOUTH_GROUP0_UART0_RXD 0x01020005 +#define SOUTH_GROUP0_UART0_TXD 0x01020006 +#define SOUTH_GROUP0_SMB5_GBE_CLK 0x01020007 +#define SOUTH_GROUP0_SMB5_GBE_DATA 0x01020008 +#define SOUTH_GROUP0_ERROR2_N 0x01020009 +#define SOUTH_GROUP0_ERROR1_N 0x0102000A +#define SOUTH_GROUP0_ERROR0_N 0x0102000B +#define SOUTH_GROUP0_IERR_N 0x0102000C +#define SOUTH_GROUP0_MCERR_N 0x0102000D +#define SOUTH_GROUP0_SMB0_LEG_CLK 0x0102000E +#define SOUTH_GROUP0_SMB0_LEG_DATA 0x0102000F +#define SOUTH_GROUP0_SMB0_LEG_ALRT_N 0x01020010 +#define SOUTH_GROUP0_SMB1_HOST_DATA 0x01020011 +#define SOUTH_GROUP0_SMB1_HOST_CLK 0x01020012 +#define SOUTH_GROUP0_SMB2_PECI_DATA 0x01020013 +#define SOUTH_GROUP0_SMB2_PECI_CLK 0x01020014 +#define SOUTH_GROUP0_SMB4_CSME0_DATA 0x01020015 +#define SOUTH_GROUP0_SMB4_CSME0_CLK 0x01020016 +#define SOUTH_GROUP0_SMB4_CSME0_ALRT_N 0x01020017 +#define SOUTH_GROUP0_USB_OC0_N 0x01020018 +#define SOUTH_GROUP0_FLEX_CLK_SE0 0x01020019 +#define SOUTH_GROUP0_FLEX_CLK_SE1 0x0102001A +#define SOUTH_GROUP0_GPIO_4 0x0102001B +#define SOUTH_GROUP0_GPIO_5 0x0102001C +#define SOUTH_GROUP0_GPIO_6 0x0102001D +#define SOUTH_GROUP0_GPIO_7 0x0102001E +#define SOUTH_GROUP0_SATA0_LED_N 0x0102001F +#define SOUTH_GROUP0_SATA1_LED_N 0x01020020 +#define SOUTH_GROUP0_SATA_PDETECT0 0x01020021 +#define SOUTH_GROUP0_SATA_PDETECT1 0x01020022 +#define SOUTH_GROUP0_SATA0_SDOUT 0x01020023 +#define SOUTH_GROUP0_SATA1_SDOUT 0x01020024 +#define SOUTH_GROUP0_UART1_RXD 0x01020025 +#define SOUTH_GROUP0_UART1_TXD 0x01020026 +#define SOUTH_GROUP0_GPIO_8 0x01020027 +#define SOUTH_GROUP0_GPIO_9 0x01020028 +#define SOUTH_GROUP0_TCK 0x01020029 +#define SOUTH_GROUP0_TRST_N 0x0102002A +#define SOUTH_GROUP0_TMS 0x0102002B +#define SOUTH_GROUP0_TDI 0x0102002C +#define SOUTH_GROUP0_TDO 0x0102002D +#define SOUTH_GROUP0_CX_PRDY_N 0x0102002E +#define SOUTH_GROUP0_CX_PREQ_N 0x0102002F +#define SOUTH_GROUP0_CTBTRIGINOUT 0x01020030 +#define SOUTH_GROUP0_CTBTRIGOUT 0x01020031 +#define SOUTH_GROUP0_DFX_SPARE2 0x01020032 +#define SOUTH_GROUP0_DFX_SPARE3 0x01020033 +#define SOUTH_GROUP0_DFX_SPARE4 0x01020034 +#define SOUTH_GROUP1_SUSPWRDNACK 0x01030000 +#define SOUTH_GROUP1_PMU_SUSCLK 0x01030001 +#define SOUTH_GROUP1_ADR_TRIGGER 0x01030002 +#define SOUTH_GROUP1_PMU_AC_PRESENT 0x01030002 +#define SOUTH_GROUP1_PMU_SLP_S45_N 0x01030003 +#define SOUTH_GROUP1_PMU_SLP_S3_N 0x01030004 +#define SOUTH_GROUP1_PMU_WAKE_N 0x01030005 +#define SOUTH_GROUP1_PMU_PWRBTN_N 0x01030006 +#define SOUTH_GROUP1_PMU_RESETBUTTON_N 0x01030007 +#define SOUTH_GROUP1_PMU_PLTRST_N 0x01030008 +#define SOUTH_GROUP1_SUS_STAT_N 0x01030009 +#define SOUTH_GROUP1_SLP_S0IX_N 0x0103000A +#define SOUTH_GROUP1_SPI_CS0_N 0x0103000B +#define SOUTH_GROUP1_SPI_CS1_N 0x0103000C +#define SOUTH_GROUP1_SPI_MOSI_IO0 0x0103000D +#define SOUTH_GROUP1_SPI_MISO_IO1 0x0103000E +#define SOUTH_GROUP1_SPI_IO2 0x0103000F +#define SOUTH_GROUP1_SPI_IO3 0x01030010 +#define SOUTH_GROUP1_SPI_CLK 0x01030011 +#define SOUTH_GROUP1_SPI_CLK_LOOPBK 0x01030012 +#define SOUTH_GROUP1_ESPI_IO0 0x01030013 +#define SOUTH_GROUP1_ESPI_IO1 0x01030014 +#define SOUTH_GROUP1_ESPI_IO2 0x01030015 +#define SOUTH_GROUP1_ESPI_IO3 0x01030016 +#define SOUTH_GROUP1_ESPI_CS0_N 0x01030017 +#define SOUTH_GROUP1_ESPI_CLK 0x01030018 +#define SOUTH_GROUP1_ESPI_RST_N 0x01030019 +#define SOUTH_GROUP1_ESPI_ALRT0_N 0x0103001A +#define SOUTH_GROUP1_GPIO_10 0x0103001B +#define SOUTH_GROUP1_GPIO_11 0x0103001C +#define SOUTH_GROUP1_ESPI_CLK_LOOPBK 0x0103001D +#define SOUTH_GROUP1_EMMC_CMD 0x0103001E +#define SOUTH_GROUP1_EMMC_STROBE 0x0103001F +#define SOUTH_GROUP1_EMMC_CLK 0x01030020 +#define SOUTH_GROUP1_EMMC_D0 0x01030021 +#define SOUTH_GROUP1_EMMC_D1 0x01030022 +#define SOUTH_GROUP1_EMMC_D2 0x01030023 +#define SOUTH_GROUP1_EMMC_D3 0x01030024 +#define SOUTH_GROUP1_EMMC_D4 0x01030025 +#define SOUTH_GROUP1_EMMC_D5 0x01030026 +#define SOUTH_GROUP1_EMMC_D6 0x01030027 +#define SOUTH_GROUP1_EMMC_D7 0x01030028 +#define SOUTH_GROUP1_GPIO_3 0x01030029 + +// BIT15-0 - pad number +// BIT31-16 - group info +// BIT23- 16 - group index +// BIT31- 24 - chipset ID (default to 0x01) +#define PAD_INFO_MASK 0x0000FFFF +#define GROUP_INFO_POSITION 16 +#define GROUP_INFO_MASK 0xFFFF0000 +#define GROUP_INDEX_MASK 0x00FF0000 +#define UNIQUE_ID_MASK 0xFF000000 +#define UNIQUE_ID_POSITION 24 + +#define GPIO_PAD_DEF(Group, Pad) (uint32_t)((Group << 16) + Pad) +#define GPIO_GET_GROUP_INDEX(Group) (Group & 0xFF) +#define GPIO_GET_GROUP_FROM_PAD(Pad) (Pad >> 16) +#define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad) GPIO_GET_GROUP_INDEX((Pad >> 16)) +#define GPIO_GET_PAD_NUMBER(Pad) (Pad & 0xFFFF) +#define GPIO_GET_CHIPSET_ID(Pad) (Pad >> 24) + +#endif /* _DENVERTON_NS_GPIO_DEFS_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/iomap.h b/src/soc/intel/denverton_ns/include/soc/iomap.h new file mode 100644 index 0000000000..29b231f10d --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/iomap.h @@ -0,0 +1,40 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014-2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_IOMAP_H_ +#define _DENVERTON_NS_IOMAP_H_ + +/* + * Memory Mapped IO bases. + */ + +/* Northbridge BARs */ +#define DEFAULT_PCIEXBAR CONFIG_MMCONF_BASE_ADDRESS /* 4 KB per PCIe device */ +#define DEFAULT_MCHBAR 0xfed10000 /* 16 KB */ + +/* Southbridge internal device IO BARs (Set to match FSP settings) */ +#define DEFAULT_PMBASE 0x1800 +#define DEFAULT_ACPI_BASE DEFAULT_PMBASE +#define DEFAULT_TCO_BASE 0x400 + +/* Southbridge internal device MEM BARs (Set to match FSP settings) */ +#define DEFAULT_PCR_BASE 0xfd000000 +#define DEFAULT_PWRM_BASE 0xfe000000 +#define DEFAULT_HPET_ADDR CONFIG_HPET_ADDRESS +#define DEFAULT_SPI_BASE 0xfed01000 + +#endif /* _DENVERTON_NS_IOMAP_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/lpc.h b/src/soc/intel/denverton_ns/include/soc/lpc.h new file mode 100644 index 0000000000..b1b4462c14 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/lpc.h @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2013 - 2014 Sage Electronic Engineering, LLC. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_LPC_H_ +#define _DENVERTON_NS_LPC_H_ + +/* PCI Configuration Space (D31:F0): LPC */ +#define PCH_LPC_DEV PCI_DEV(0, LPC_DEV, LPC_FUNC) + +#define SERIRQ_CNTL 0x64 +#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ +#define FDD_LPC_SHIFT 12 /* LPC_IO_DEC[12] */ +#define FDD_DEC_MASK 1 +#define FDD_DEC_3F8 0 /* 3F0h - 3F5Fh, 3F7h (Primary) */ +#define FDD_DEC_2F8 1 /* 370h - 375h, 377h (Secondary) */ +#define LPT_LPC_SHIFT 8 /* LPC_IO_DEC[9:8] */ +#define LPT_DEC_MASK 3 +#define LPT_DEC_378 0 /* 378h - 37Fh and 778h - 77Fh */ +#define LPT_DEC_278 1 /* 278h - 27Fh and 678h - 67Fh */ +#define LPT_DEC_3BC 2 /* 3BCh - 3BEh and 7BCh - 7BEh */ +#define COMB_LPC_SHIFT 4 /* LPC_IO_DEC[6:4] */ +#define COMA_LPC_SHIFT 0 /* LPC_IO_DEC[2:0] */ +#define COM_DEC_MASK 7 +#define COM_DEC_3F8 0 /* 3F8h - 3FFh (COM1) */ +#define COM_DEC_2F8 1 /* 2F8h - 2FFh (COM2) */ +#define COM_DEC_220 2 /* 220h - 227h */ +#define COM_DEC_228 3 /* 228h - 22Fh */ +#define COM_DEC_238 4 /* 238h - 23Fh */ +#define COM_DEC_2E8 5 /* 2E8h - 2EFh (COM4) */ +#define COM_DEC_338 6 /* 338h - 33Fh */ +#define COM_DEC_3E8 7 /* 3E8h - 3EFh (COM3) */ +#define LPC_EN 0x82 /* LPC IF Enables Register */ +#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ +#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ +#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ +#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ +#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ +#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ +#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ +#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ +#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ +#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[2:0] */ +#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ +#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ +#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ +#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ + +#endif /* _DENVERTON_NS_LPC_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/msr.h b/src/soc/intel/denverton_ns/include/soc/msr.h new file mode 100644 index 0000000000..4d1ac70c3a --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/msr.h @@ -0,0 +1,114 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_MSR_H_ +#define _DENVERTON_NS_MSR_H_ + +#define MSR_PLATFORM_ID 0x17 +#define MSR_PIC_MSG_CONTROL 0x2e +#define CORE_THREAD_COUNT_MSR 0x35 +#define IA32_FEATURE_CONTROL 0x3a +#define CPUID_VMX (1 << 5) +#define CPUID_SMX (1 << 6) +#define MSR_PLATFORM_INFO 0xce +#define PLATFORM_INFO_SET_TDP (1 << 29) +#define MSR_PMG_CST_CONFIG_CONTROL 0xe2 +#define MSR_PMG_IO_CAPTURE_BASE 0xe4 +#define MSR_FEATURE_CONFIG 0x13c +#define SMM_MCA_CAP_MSR 0x17d +#define SMM_CPU_SVRSTR_BIT 57 +#define SMM_CPU_SVRSTR_MASK (1 << (SMM_CPU_SVRSTR_BIT - 32)) +#define MSR_FLEX_RATIO 0x194 +#define FLEX_RATIO_LOCK (1 << 20) +#define FLEX_RATIO_EN (1 << 16) +#define IA32_MISC_ENABLE 0x1a0 +#define MSR_MISC_PWR_MGMT 0x1aa +#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) +#define MSR_TURBO_RATIO_LIMIT 0x1ad +#define MSR_TEMPERATURE_TARGET 0x1a2 +#define IA32_PERF_CTL 0x199 +#define IA32_THERM_INTERRUPT 0x19b +#define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 +#define ENERGY_POLICY_PERFORMANCE 0 +#define ENERGY_POLICY_NORMAL 6 +#define ENERGY_POLICY_POWERSAVE 15 +#define IA32_PACKAGE_THERM_INTERRUPT 0x1b2 +#define EMRR_PHYS_BASE_MSR 0x1f4 +#define EMRR_PHYS_MASK_MSR 0x1f5 +#define IA32_PLATFORM_DCA_CAP 0x1f8 +#define MSR_POWER_CTL 0x1fc +#define MSR_LT_LOCK_MEMORY 0x2e7 +#define UNCORE_PRMRR_PHYS_BASE_MSR 0x2f4 +#define UNCORE_PRMRR_PHYS_MASK_MSR 0x2f5 +#define IA32_MC0_STATUS 0x401 +#define SMM_FEATURE_CONTROL_MSR 0x4e0 +#define SMM_CPU_SAVE_EN (1 << 1) + +#define MSR_C_STATE_LATENCY_CONTROL_0 0x60a +#define MSR_C_STATE_LATENCY_CONTROL_1 0x60b +#define MSR_C_STATE_LATENCY_CONTROL_2 0x60c +#define MSR_C_STATE_LATENCY_CONTROL_3 0x633 +#define MSR_C_STATE_LATENCY_CONTROL_4 0x634 +#define MSR_C_STATE_LATENCY_CONTROL_5 0x635 +#define IRTL_VALID (1 << 15) +#define IRTL_1_NS (0 << 10) +#define IRTL_32_NS (1 << 10) +#define IRTL_1024_NS (2 << 10) +#define IRTL_32768_NS (3 << 10) +#define IRTL_1048576_NS (4 << 10) +#define IRTL_33554432_NS (5 << 10) +#define IRTL_RESPONSE_MASK (0x3ff) +#define MSR_COUNTER_24_MHZ 0x637 + +/* long duration in low dword, short duration in high dword */ +#define MSR_PKG_POWER_LIMIT 0x610 +#define PKG_POWER_LIMIT_MASK 0x7fff +#define PKG_POWER_LIMIT_EN (1 << 15) +#define PKG_POWER_LIMIT_CLAMP (1 << 16) +#define PKG_POWER_LIMIT_TIME_SHIFT 17 +#define PKG_POWER_LIMIT_TIME_MASK 0x7f + +#define MSR_VR_CURRENT_CONFIG 0x601 +#define MSR_VR_MISC_CONFIG 0x603 +#define MSR_PKG_POWER_SKU_UNIT 0x606 +#define MSR_PKG_POWER_SKU 0x614 +#define MSR_DDR_RAPL_LIMIT 0x618 +#define MSR_VR_MISC_CONFIG2 0x636 +#define MSR_PP0_POWER_LIMIT 0x638 +#define MSR_PP1_POWER_LIMIT 0x640 + +#define MSR_CONFIG_TDP_NOMINAL 0x648 +#define MSR_CONFIG_TDP_LEVEL1 0x649 +#define MSR_CONFIG_TDP_LEVEL2 0x64a +#define MSR_CONFIG_TDP_CONTROL 0x64b +#define MSR_TURBO_ACTIVATION_RATIO 0x64c + +/* SMM save state MSRs */ +#define SMBASE_MSR 0xc20 +#define IEDBASE_MSR 0xc22 + +/* MTRRcap_MSR bits */ +#define SMRR_SUPPORTED (1 << 11) +#define PRMRR_SUPPORTED (1 << 12) + +/* IA32_MISC_ENABLE bits */ +#define SPEED_STEP_ENABLE_BIT (1 << 16) + +/* Read BCLK from MSR */ +unsigned int bus_freq_khz(void); + +#endif /* _DENVERTON_NS_MSR_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/nvs.h b/src/soc/intel/denverton_ns/include/soc/nvs.h new file mode 100644 index 0000000000..cf10823ca1 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/nvs.h @@ -0,0 +1,74 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 - 2009 coresystems GmbH + * Copyright (C) 2011 Google Inc + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_NVS_H_ +#define _DENVERTON_NS_NVS_H_ + +typedef struct { + /* Miscellaneous */ + u16 osys; /* 0x00 - Operating System */ + u8 smif; /* 0x02 - SMI function call ("TRAP") */ + u8 prm0; /* 0x03 - SMI function call parameter */ + u8 prm1; /* 0x04 - SMI function call parameter */ + u8 scif; /* 0x05 - SCI function call (via _L00) */ + u8 prm2; /* 0x06 - SCI function call parameter */ + u8 prm3; /* 0x07 - SCI function call parameter */ + u8 lckf; /* 0x08 - Global Lock function for EC */ + u8 prm4; /* 0x09 - Lock function parameter */ + u8 prm5; /* 0x0a - Lock function parameter */ + u32 p80d; /* 0x0b - Debug port (IO 0x80) value */ + u8 lids; /* 0x0f - LID state (open = 1) */ + u8 pwrs; /* 0x10 - Power state (AC = 1) */ + u8 pcnt; /* 0x11 - Processor Count */ + u8 tpmp; /* 0x12 - TPM Present and Enabled */ + u8 tlvl; /* 0x13 - Throttle Level */ + u8 ppcm; /* 0x14 - Maximum P-state usable by OS */ + u8 rsvd1[11]; + + /* Device Config */ + u8 s5u0; /* 0x20 - Enable USB0 in S5 */ + u8 s5u1; /* 0x21 - Enable USB1 in S5 */ + u8 s3u0; /* 0x22 - Enable USB0 in S3 */ + u8 s3u1; /* 0x23 - Enable USB1 in S3 */ + u8 tact; /* 0x24 - Thermal Active trip point */ + u8 tpsv; /* 0x25 - Thermal Passive trip point */ + u8 tcrt; /* 0x26 - Thermal Critical trip point */ + u8 dpte; /* 0x27 - Enable DPTF */ + u8 rsvd2[8]; + + /* Base Addresses */ + u32 obsolete_cmem; /* 0x30 - CBMEM TOC */ + u32 tolm; /* 0x34 - Top of Low Memory */ + u32 cbmc; /* 0x38 - coreboot memconsole */ + u32 mmiob; /* 0x3c - MMIO Base Low */ + u32 mmiol; /* 0x40 - MMIO Base Limit */ + u64 mmiohb; /* 0x44 - MMIO Base High */ + u64 mmiohl; /* 0x4c - MMIO Base Limit */ + u32 tsegb; /* 0x54 - TSEG Base Low */ + u32 tsegl; /* 0x58 - TSEG Length/Size */ + u8 rsvd3[164]; + +} __attribute__((packed)) global_nvs_t; + +void acpi_create_gnvs(global_nvs_t *gnvs); +#ifdef __SMM__ +/* Used in SMM to find the ACPI GNVS address */ +global_nvs_t *smm_get_gnvs(void); +#endif + +#endif /* _DENVERTON_NS_NVS_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/p2sb.h b/src/soc/intel/denverton_ns/include/soc/p2sb.h new file mode 100644 index 0000000000..6d5a41528a --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/p2sb.h @@ -0,0 +1,67 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_P2SB_H_ +#define _DENVERTON_NS_P2SB_H_ + +/* Generate MP-table IRQ numbers for PCI devices. */ +#define IO_APIC0 1 + +/* P2SB Bridge Registers (D31:F1) */ +#define PCH_P2SB_DEV PCI_DEV(0, P2SB_DEV, P2SB_FUNC) + +/* IO/MEM BARs */ +#define SBREG_LO 0x10 +#define MASK_SBREG_LO 0xff000000 +#define SBREG_HI 0x14 +#define MASK_SBREG_HI 0xffffffff + +/* ITSS PCRs (PID:ITSS) */ +#define PCR_ITSS_PIRQA_ROUT 0x3100 +#define PCR_ITSS_PIRQB_ROUT 0x3101 +#define PCR_ITSS_PIRQC_ROUT 0x3102 +#define PCR_ITSS_PIRQD_ROUT 0x3103 +#define PCR_ITSS_PIRQE_ROUT 0x3104 +#define PCR_ITSS_PIRQF_ROUT 0x3105 +#define PCR_ITSS_PIRQG_ROUT 0x3106 +#define PCR_ITSS_PIRQH_ROUT 0x3107 + +#define PCR_ITSS_PIR00 0x3140 +#define PCR_ITSS_PIR01 0x3142 +#define PCR_ITSS_PIR02 0x3144 +#define PCR_ITSS_PIR03 0x3146 +#define PCR_ITSS_PIR04 0x3148 +#define PCR_ITSS_PIR05 0x314A +#define PCR_ITSS_PIR06 0x314C +#define PCR_ITSS_PIR07 0x314E +#define PCR_ITSS_PIR08 0x3150 +#define PCR_ITSS_PIR09 0x3152 +#define PCR_ITSS_PIR10 0x3154 +#define PCR_ITSS_PIR11 0x3156 +#define PCR_ITSS_PIR12 0x3158 + +#define PCH_PCR_ITSS_GIC 0x31FC ///< General Interrupt Control +///< Max IRQ entry size, 1 = 24 entry size, 0 = 120 entry size +#define PCH_PCR_ITSS_GIC_MAX_IRQ_24 \ + (1 << 9) +#define PCH_PCR_ITSS_GIC_AME (1 << 17) ///< Alternate Access Mode Enable +#define PCH_PCR_ITSS_GIC_SPS (1 << 16) ///< Shutdown Policy Select +#define PCH_PCR_ITSS_IPC0 0x3200 ///< Interrupt Polarity Control 0 +#define PCH_PCR_ITSS_IPC1 0x3204 ///< Interrupt Polarity Control 1 +#define PCH_PCR_ITSS_IPC2 0x3208 ///< Interrupt Polarity Control 2 +#define PCH_PCR_ITSS_IPC3 0x320C ///< Interrupt Polarity Control 3 + +#endif /* _DENVERTON_NS_P2SB_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/pattrs.h b/src/soc/intel/denverton_ns/include/soc/pattrs.h new file mode 100644 index 0000000000..b558e24afe --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/pattrs.h @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_PATTRS_H_ +#define _DENVERTON_NS_PATTRS_H_ + +#include <stdint.h> +#include <cpu/x86/msr.h> + +enum { IACORE_MIN, IACORE_LFM, IACORE_MAX, IACORE_TURBO, IACORE_END }; + +/* The pattrs structure is a common place to stash pertinent information + * about the processor or platform. Instead of going to the source (msrs, cpuid) + * every time an attribute is needed use the pattrs structure. + */ +struct pattrs { + msr_t platform_id; + msr_t platform_info; + int iacore_ratios[IACORE_END]; + int iacore_vids[IACORE_END]; + uint32_t cpuid; + int revid; + int stepping; + const void *microcode_patch; + int address_bits; + int num_cpus; + unsigned int bclk_khz; +}; + +/* This is just to hide the abstraction w/o relying on how the underlying + * storage is allocated. */ +#define PATTRS_GLOB_NAME __global_pattrs +#define DEFINE_PATTRS struct pattrs PATTRS_GLOB_NAME +extern DEFINE_PATTRS; + +static inline const struct pattrs *pattrs_get(void) +{ + return &PATTRS_GLOB_NAME; +} + +#endif /* _DENVERTON_NS_PATTRS_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/pci_devs.h b/src/soc/intel/denverton_ns/include/soc/pci_devs.h new file mode 100644 index 0000000000..138b6f6081 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/pci_devs.h @@ -0,0 +1,204 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014-2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_PCI_DEVS_H_ +#define _DENVERTON_NS_PCI_DEVS_H_ + +/* All these devices live on bus 0 with the associated device and function */ + +#include <rules.h> + +#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_##slot, 0) +#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_##slot, func) + +#if ENV_RAMSTAGE +#include <device/device.h> +#include <device/pci_def.h> +#define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot)) +#define _PCH_DEV(slot, func) dev_find_slot(0, _PCH_DEVFN(slot, func)) +#else +#include <arch/io.h> +#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_##slot, 0) +#define _PCH_DEV(slot, func) PCI_DEV(0, PCH_DEV_SLOT_##slot, func) +#endif + +/* SoC transaction router */ +#define SA_DEV 0x0 +#define SA_FUNC 0 +#define SA_DEVID 0x1980 +#define SOC_DEV SA_DEV +#define SOC_FUNC SA_FUNC +#define SOC_DEVID SA_DEVID + +/* RAS */ +#define RAS_DEV 0x4 +#define RAS_FUNC 0 +#define RAS_DEVID 0x19a1 + +/* Root Complex Event Collector */ +#define RCEC_DEV 0x5 +#define RCEC_FUNC 0 +#define RCEC_DEVID 0x19a2 + +/* Virtual Root Port 2 */ +#define VRP2_DEV 0x6 +#define VRP2_FUNC 0 +#define VRP2_DEVID 0x19a3 + +/* PCIe Root Ports */ +#define PCIE_DEV 0x09 +#define MAX_PCIE_PORT 0x8 +#define PCIE_PORT1_DEV 0x09 +#define PCIE_PORT1_FUNC 0 +#define PCIE_PORT1_DEVID 0x19a4 +#define PCIE_PORT2_DEV 0x0a +#define PCIE_PORT2_FUNC 0 +#define PCIE_PORT2_DEVID 0x19a5 +#define PCIE_PORT3_DEV 0x0b +#define PCIE_PORT3_FUNC 0 +#define PCIE_PORT3_DEVID 0x19a6 +#define PCIE_PORT4_DEV 0x0c +#define PCIE_PORT4_FUNC 0 +#define PCIE_PORT4_DEVID 0x19a7 +#define PCIE_PORT5_DEV 0x0e +#define PCIE_PORT5_FUNC 0 +#define PCIE_PORT5_DEVID 0x19a8 +#define PCIE_PORT6_DEV 0x0f +#define PCIE_PORT6_FUNC 0 +#define PCIE_PORT6_DEVID 0x19a9 +#define PCIE_PORT7_DEV 0x10 +#define PCIE_PORT7_FUNC 0 +#define PCIE_PORT7_DEVID 0x19aa +#define PCIE_PORT8_DEV 0x11 +#define PCIE_PORT8_FUNC 0 +#define PCIE_PORT8_DEVID 0x19ab + +/* SMBUS 2 */ +#define SMBUS2_DEV 0x12 +#define SMBUS2_FUNC 0 +#define SMBUS2_DEVID 0x19ac + +/* SATA */ +#define SATA_DEV 0x13 +#define SATA_FUNC 0 +#define AHCI_DEVID 0x19b2 +#define SATA2_DEV 0x14 +#define SATA2_FUNC 0 +#define AHCI2_DEVID 0x19c2 + +/* xHCI */ +#define XHCI_DEV 0x15 +#define XHCI_FUNC 0 +#define XHCI_DEVID 0x19d0 + +/* Virtual Root Port 0 */ +#define VRP0_DEV 0x16 +#define VRP0_FUNC 0 +#define VRP0_DEVID 0x19d1 + +/* Virtual Root Port 1 */ +#define VRP1_DEV 0x17 +#define VRP1_FUNC 0 +#define VRP1_DEVID 0x19d2 + +/* CSME */ +#define ME_HECI_DEV 0x18 +#define ME_HECI1_DEV ME_HECI_DEV +#define ME_HECI1_FUNC 0 +#define ME_HECI1_DEVID 0x19d3 +#define ME_HECI2_DEV ME_HECI_DEV +#define ME_HECI2_FUNC 1 +#define ME_HECI2_DEVID 0x19d4 +#define ME_IEDR_DEV ME_HECI_DEV +#define ME_IEDR_FUNC 2 +#define ME_IEDR_DEVID 0x19ea +#define ME_MEKT_DEV ME_HECI_DEV +#define ME_MEKT_FUNC 3 +#define ME_MEKT_DEVID 0x19d5 +#define ME_HECI3_DEV ME_HECI_DEV +#define ME_HECI3_FUNC 4 +#define ME_HECI3_DEVID 0x19d6 + +/* HSUART */ +#define HSUART_DEV 0x1a +#define HSUART_DEVID 0x19d8 +#define HSUART1_DEV HSUART_DEV +#define HSUART1_FUNC 0 +#define HSUART1_DEVID HSUART_DEVID +#define HSUART2_DEV HSUART_DEV +#define HSUART2_FUNC 1 +#define HSUART2_DEVID HSUART_DEVID +#define HSUART3_DEV HSUART_DEV +#define HSUART3_FUNC 2 +#define HSUART3_DEVID HSUART_DEVID + +/* IE */ +#define IE_HECI_DEV 0x1b +#define IE_HECI1_DEV IE_HECI_DEV +#define IE_HECI1_FUNC 0 +#define IE_HECI1_DEVID 0x19e5 +#define IE_HECI2_DEV IE_HECI_DEV +#define IE_HECI2_FUNC 1 +#define IE_HECI2_DEVID 0x19e6 +#define IE_IEDR_DEV IE_HECI_DEV +#define IE_IEDR_FUNC 2 +#define IE_IEDR_DEVID 0x19e7 +#define IE_MEKT_DEV IE_HECI_DEV +#define IE_MEKT_FUNC 3 +#define IE_MEKT_DEVID 0x19e8 +#define IE_HECI3_DEV IE_HECI_DEV +#define IE_HECI3_FUNC 4 +#define IE_HECI3_DEVID 0x19e9 + +/* MMC Port */ +#define MMC_DEV 0x1c +#define MMC_FUNC 0 +#define MMC_DEVID 0x19db + +/* Platform Controller Unit */ +#define PCU_DEV 0x1f +#define LPC_DEV PCU_DEV +#define LPC_FUNC 0 +#define LPC_DEVID 0x19dc +#define P2SB_DEV PCU_DEV +#define P2SB_FUNC 1 +#define P2SB_DEVID 0x19dd +#define PMC_DEV PCU_DEV +#define PMC_FUNC 2 +#define PMC_DEVID 0x19de +#define SMBUS_DEV PCU_DEV +#define SMBUS_FUNC 4 +#define SMBUS_DEVID 0x19df +#define SPI_DEV PCU_DEV +#define SPI_FUNC 5 +#define SPI_DEVID 0x19e0 +#define NPK_DEV PCU_DEV +#define NPK_FUNC 7 +#define NPK_DEVID 0x19e1 + +/* TODO - New added */ +#define SA_DEV_SLOT_ROOT 0x00 +#define SA_DEVFN_ROOT _SA_DEVFN(ROOT) +#define SA_DEV_ROOT _SA_DEV(ROOT) + +#define PCH_DEV_SLOT_LPC 0x1f +#define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0) +#define PCH_DEVFN_SPI _PCH_DEVFN(LPC, 5) +#define PCH_DEV_LPC _PCH_DEV(LPC, 0) +#define PCH_DEV_SPI _PCH_DEV(LPC, 5) + +#endif /* _DENVERTON_NS_PCI_DEVS_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/pcr.h b/src/soc/intel/denverton_ns/include/soc/pcr.h new file mode 100644 index 0000000000..601577640b --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/pcr.h @@ -0,0 +1,35 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_PCR_H_ +#define _DENVERTON_NS_PCR_H_ + +/* PCR BASE */ +#include <soc/iomap.h> + +/* PCR address */ +#define PCH_PCR_ADDRESS(Pid, Offset) \ + (DEFAULT_PCR_BASE | ((uint8_t)(Pid) << 16) | (uint16_t)(Offset)) + +/* PID for PCR and SBI */ +typedef enum { + PID_SMB = 0xCF, + PID_ITSS = 0xD0, + PID_GPIOCOM0 = 0xC2, + PID_GPIOCOM1 = 0xC5, +} PCH_SBI_PID; + +#endif /* _DENVERTON_NS_PCR_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/pm.h b/src/soc/intel/denverton_ns/include/soc/pm.h new file mode 100644 index 0000000000..2dc8781804 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/pm.h @@ -0,0 +1,59 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_PM_H_ +#define _DENVERTON_NS_PM_H_ + +#include <arch/io.h> +#include <soc/pmc.h> + +#define SLEEP_STATE_S0 0 +#define SLEEP_STATE_S3 3 +#define SLEEP_STATE_S5 5 + +struct chipset_power_state { + uint16_t pm1_sts; + uint16_t pm1_en; + uint32_t pm1_cnt; + uint16_t tco1_sts; + uint16_t tco2_sts; + uint32_t gpe0_sts[4]; + uint32_t gpe0_en[4]; + uint32_t gen_pmcon_a; + uint32_t gen_pmcon_b; + uint32_t gblrst_cause[2]; + uint32_t prev_sleep_state; +} __attribute__((packed)); + +struct chipset_power_state *fill_power_state(void); + +/* Power Management Utility Functions. */ +uint32_t clear_smi_status(void); +uint16_t clear_pm1_status(void); +uint32_t clear_tco_status(void); +uint32_t clear_gpe_status(void); +void clear_pmc_status(void); +void enable_smi(uint32_t mask); +void disable_smi(uint32_t mask); +void enable_pm1(uint16_t events); +void enable_pm1_control(uint32_t mask); +void disable_pm1_control(uint32_t mask); +void enable_gpe(uint32_t mask); +void disable_gpe(uint32_t mask); +void disable_all_gpe(void); + +#endif /* _DENVERTON_NS_PM_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/pmc.h b/src/soc/intel/denverton_ns/include/soc/pmc.h new file mode 100644 index 0000000000..edb5c55df6 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/pmc.h @@ -0,0 +1,255 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_PMC_H_ +#define _DENVERTON_NS_PMC_H_ + +/* PCI Configuration Space (D31:F2): PMC/ACPI */ +#define PCH_PMC_DEV PCI_DEV(0, PMC_DEV, PMC_FUNC) + +/* Memory mapped IO registers behind PMC_BASE_ADDRESS */ +#define PMC_ACPI_BASE 0x40 /* IO BAR */ +#define MASK_PMC_ACPI_BASE 0xfffc +#define PMC_ACPI_CNT 0x44 +#define PMC_ACPI_CNT_PWRM_EN (1 << 8) /* PWRM enable */ +#define PMC_ACPI_CNT_ACPI_EN (1 << 7) /* ACPI eanble */ +#define PMC_ACPI_CNT_SCIS ((1 << 2) | (1 << 1) | (1 << 0)) /* SCI IRQ select \ + */ +#define PMC_ACPI_CNT_SCIS_MASK 0x07 +#define PMC_ACPI_CNT_SCIS_IRQ9 0x00 +#define PMC_ACPI_CNT_SCIS_IRQ10 0x01 +#define PMC_ACPI_CNT_SCIS_IRQ11 0x02 +#define PMC_ACPI_CNT_SCIS_DISABLE 0x03 +#define PMC_ACPI_CNT_SCIS_IRQ20 0x04 +#define PMC_ACPI_CNT_SCIS_IRQ21 0x05 +#define PMC_ACPI_CNT_SCIS_IRQ22 0x06 +#define PMC_ACPI_CNT_SCIS_IRQ23 0x07 +#define PMC_PWRM_BASE 0x48 /* MEM BAR */ +#define MASK_PMC_PWRM_BASE 0xfffff000 /* 4K alignment */ +#define PMC_GEN_PMCON_A 0xA0 +#define PMC_GEN_PMCON_B 0xA4 +#define PMC_GEN_PMCON_B_RTC_PWR_STS 0x04 +#define PMC_GEN_PMCON_B_PWR_FLR 0x02 +#define PMC_GEN_PMCON_B_AFTERG3_EN 0x00 +#define PMC_ETR3 0xAC +#define PMC_ETR3_CF9LOCK BIT31 ///< CF9h Lockdown +#define PMC_ETR3_CF9GR BIT20 ///< CF9h Global Reset + +/* IO Mapped registers behind ACPI_BASE_ADDRESS */ +#define PM1_STS 0x00 +#define WAK_STS (1 << 15) +#define PCIEXPWAK_STS (1 << 14) +#define PRBTNOR_STS (1 << 11) +#define RTC_STS (1 << 10) +#define PWRBTN_STS (1 << 8) +#define GBL_STS (1 << 5) +#define BM_STS (1 << 4) +#define TMROF_STS (1 << 0) +#define PM1_EN 0x02 +#define PCIEXPWAK_DIS (1 << 14) +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) +#define PM1_CNT 0x04 +#define SLP_EN (1 << 13) +#define SLP_TYP_SHIFT 10 +#define SLP_TYP (7 << SLP_TYP_SHIFT) +#define SLP_TYP_S0 0 +#define SLP_TYP_S1 1 +#define SLP_TYP_S3 5 +#define SLP_TYP_S4 6 +#define SLP_TYP_S5 7 +#define GBL_RLS (1 << 2) +#define BM_RLD (1 << 1) +#define SCI_EN (1 << 0) +#define PM1_TMR 0x08 +#define SMI_EN 0x30 +#define LEGACY_USB3_EN (1 << 31) // Legacy USB3 SMI logic +#define GPIO_UNLOCK_EN (1 << 27) // GPIO unlock SMI +#define INTEL_USB2_EN (1 << 18) // Intel-Specific USB2 SMI logic +#define LEGACY_USB2_EN (1 << 17) // Legacy USB2 SMI logic +#define PERIODIC_EN (1 << 14) // SMI on PERIODIC_STS in SMI_STS +#define TCO_EN (1 << 13) // Enable TCO Logic (BIOSWE et al) +#define MCSMI_EN (1 << 11) // Trap microcontroller range access +#define BIOS_RLS (1 << 7) // asserts SCI on bit set +#define SWSMI_TMR_EN (1 << 6) // start software smi timer on bit set +#define APMC_EN (1 << 5) // Writes to APM_CNT cause SMI# +#define SLP_SMI_EN (1 << 4) // Write to SLP_EN in PM1_CNT asserts SMI# +#define LEGACY_USB_EN (1 << 3) // Legacy USB circuit SMI logic +#define BIOS_EN (1 << 2) // Assert SMI# on setting GBL_RLS bit +#define EOS (1 << 1) // End of SMI (deassert SMI#) +#define GBL_SMI_EN (1 << 0) // SMI# generation at all? +#define SMI_STS 0x34 +#define SMI_STS_LEGACY_USB3 (1 << 31) +#define SMI_STS_GPIO_UNLOCK (1 << 27) +#define SMI_STS_SPI (1 << 26) +#define SMI_STS_MONITOR (1 << 21) +#define SMI_STS_PCI_EXP (1 << 20) +#define SMI_STS_PATCH (1 << 19) +#define SMI_STS_INTEL_USB2 (1 << 18) +#define SMI_STS_LEGACY_USB2 (1 << 17) +#define SMI_STS_SMBUS (1 << 16) +#define SMI_STS_SERIRQ (1 << 15) +#define SMI_STS_PERIODIC (1 << 14) +#define SMI_STS_TCO (1 << 13) +#define SMI_STS_DEVMON (1 << 12) +#define SMI_STS_MCSMI (1 << 11) +#define SMI_STS_GPE1 (1 << 10) +#define SMI_STS_GPE0 (1 << 9) +#define SMI_STS_PM1 (1 << 8) +#define SMI_STS_SWSMI_TMR (1 << 6) +#define SMI_STS_APMC (1 << 5) +#define SMI_STS_SLP_SMI (1 << 4) +#define SMI_STS_LEGACY_USB (1 << 3) +#define SMI_STS_BIOS (1 << 2) +#define GPE_CTRL 0x40 +#define SWGPE_CTRL (1 << 17) +#define PM2_CNT 0x50 +#define GPE0_STS 0x80 +#define GPIO31_STS (1 << 31) +#define GPIO30_STS (1 << 30) +#define GPIO29_STS (1 << 29) +#define GPIO28_STS (1 << 28) +#define GPIO27_STS (1 << 27) +#define GPIO26_STS (1 << 26) +#define GPIO25_STS (1 << 25) +#define GPIO24_STS (1 << 24) +#define GPIO23_STS (1 << 23) +#define GPIO22_STS (1 << 22) +#define GPIO21_STS (1 << 21) +#define GPIO20_STS (1 << 20) +#define GPIO19_STS (1 << 19) +#define GPIO18_STS (1 << 18) +#define GPIO17_STS (1 << 17) +#define GPIO16_STS (1 << 16) +#define GPIO15_STS (1 << 15) +#define GPIO14_STS (1 << 14) +#define GPIO13_STS (1 << 13) +#define GPIO12_STS (1 << 12) +#define GPIO11_STS (1 << 11) +#define GPIO10_STS (1 << 10) +#define GPIO09_STS (1 << 09) +#define GPIO08_STS (1 << 08) +#define GPIO07_STS (1 << 07) +#define GPIO06_STS (1 << 06) +#define GPIO05_STS (1 << 05) +#define GPIO04_STS (1 << 04) +#define GPIO03_STS (1 << 03) +#define GPIO02_STS (1 << 02) +#define GPIO01_STS (1 << 01) +#define GPIO00_STS (1 << 00) +#define GPE0_STS_63_32 0x84 +#define GPE0_STS_95_64 0x88 +#define GPE0_STS_127_96 0x8c +#define PME_B0_STS (1 << 13) +#define ME_SCI_STS (1 << 12) +#define PME_STS (1 << 11) +#define PCI_EXP_STS (1 << 9) +#define RI_STS (1 << 8) +#define SMB_WAK_STS (1 << 7) +#define TCOSCI_STS (1 << 6) +#define IE_SCI_STS (1 << 3) +#define SWGPE_STS (1 << 2) +#define HOT_PLUG_STS (1 << 1) +#define GPE0_EN 0x90 +#define GPIO31_EN (1 << 31) +#define GPIO30_EN (1 << 30) +#define GPIO29_EN (1 << 29) +#define GPIO28_EN (1 << 28) +#define GPIO27_EN (1 << 27) +#define GPIO26_EN (1 << 26) +#define GPIO25_EN (1 << 25) +#define GPIO24_EN (1 << 24) +#define GPIO23_EN (1 << 23) +#define GPIO22_EN (1 << 22) +#define GPIO21_EN (1 << 21) +#define GPIO20_EN (1 << 20) +#define GPIO19_EN (1 << 19) +#define GPIO18_EN (1 << 18) +#define GPIO17_EN (1 << 17) +#define GPIO16_EN (1 << 16) +#define GPIO15_EN (1 << 15) +#define GPIO14_EN (1 << 14) +#define GPIO13_EN (1 << 13) +#define GPIO12_EN (1 << 12) +#define GPIO11_EN (1 << 11) +#define GPIO10_EN (1 << 10) +#define GPIO09_EN (1 << 09) +#define GPIO08_EN (1 << 08) +#define GPIO07_EN (1 << 07) +#define GPIO06_EN (1 << 06) +#define GPIO05_EN (1 << 05) +#define GPIO04_EN (1 << 04) +#define GPIO03_EN (1 << 03) +#define GPIO02_EN (1 << 02) +#define GPIO01_EN (1 << 01) +#define GPIO00_EN (1 << 00) +#define GPE0_EN_63_32 0x94 +#define GPE0_EN_95_64 0x98 +#define GPE0_EN_127_96 0x9c +#define PME_B0_EN (1 << 13) +#define ME_SCI_EN (1 << 12) +#define PME_EN (1 << 11) +#define PCI_EXP_EN (1 << 9) +#define RI_EN (1 << 8) +#define SMB_WAK_EN (1 << 7) +#define TCOSCI_EN (1 << 6) +#define IE_SCI_EN (1 << 3) +#define SWGPE_EN (1 << 2) +#define HOT_PLUG_EN (1 << 1) + +/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */ +#define TCO_RLD 0x00 +#define TCO1_STS 0x04 +#define TCO1_STS_TCO_SLVSEL (1 << 13) +#define TCO1_STS_CPUSERR (1 << 12) +#define TCO1_STS_CPUSMI (1 << 10) +#define TCO1_STS_CPUSCI (1 << 9) +#define TCO1_STS_BIOSWR (1 << 8) +#define TCO1_STS_NEWCENTURY (1 << 7) +#define TCO1_STS_TIMEOUT (1 << 3) +#define TCO1_STS_TCO_INT (1 << 2) +#define TCO1_STS_OS_TCO_SMI (1 << 1) +#define TCO1_STS_NMI2SMI (1 << 0) +#define TCO2_STS 0x06 +#define TCO2_STS_SMLINK_SLAVE_SMI 0x04 +#define TCO2_STS_SECOND_TO 0x02 +#define TCO2_STS_INTRD_DET 0x01 +#define TCO1_CNT 0x08 +#define TCO_LOCK (1 << 12) +#define TCO_TMR_HLT (1 << 11) +#define TCO2_CNT 0x0a +#define TCO_TMR 0x12 + +/* I/O ports */ +#define RST_CNT 0xcf9 +#define FULL_RST (1 << 3) +#define RST_CPU (1 << 2) +#define SYS_RST (1 << 1) + +#if !defined(__ASSEMBLER__) && !defined(__ACPI__) + +#if IS_ENABLED(CONFIG_ELOG) +void southcluster_log_state(void); +#else +static inline void southcluster_log_state(void) {} +#endif + +#endif /* !defined(__ASSEMBLER__) && !defined(__ACPI__) */ + +#endif /* _DENVERTON_NS_PMC_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/ramstage.h b/src/soc/intel/denverton_ns/include/soc/ramstage.h new file mode 100644 index 0000000000..63ed4327f2 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/ramstage.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DENVERTON_NS_SOC_RAMSTAGE_H_ +#define _DENVERTON_NS_SOC_RAMSTAGE_H_ + +#include <device/device.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <soc/intel/common/opregion.h> + +void denverton_init_cpus(device_t dev); +void mainboard_silicon_init_params(FSPS_UPD *params); +void southcluster_enable_dev(device_t dev); + +extern struct pci_operations soc_pci_ops; + +#endif diff --git a/src/soc/intel/denverton_ns/include/soc/romstage.h b/src/soc/intel/denverton_ns/include/soc/romstage.h new file mode 100644 index 0000000000..2c6c5ce890 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/romstage.h @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _SOC_DENVERTON_NS_ROMSTAGE_H_ +#define _SOC_DENVERTON_NS_ROMSTAGE_H_ + +#include <arch/cpu.h> +#include <fsp/api.h> + +/* These functions are weak and can be overridden by a mainboard functions. */ +void mainboard_memory_init_params(FSPM_UPD *mupd); +void mainboard_config_gpios(void); + +#endif /* _SOC_DENVERTON_NS_ROMSTAGE_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/sata.h b/src/soc/intel/denverton_ns/include/soc/sata.h new file mode 100644 index 0000000000..afa39b5d65 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/sata.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_SATA_H +#define _DENVERTON_NS_SATA_H + +/* PCI Configuration Space (D19:F0): SATA #0 */ +/* PCI Configuration Space (D20:F0): SATA #1 */ +#define PCH_SATA0_DEV PCI_DEV(0, SATA_DEV, SATA_FUNC) +#define PCH_SATA1_DEV PCI_DEV(0, SATA2_DEV, SATA2_FUNC) + +#define SATA_MAP 0x90 +#define SATA_MAP_AHCI (0 << 6) +#define SATA_MAP_RAID (1 << 6) +#define SATA_PSC 0x92 + +#endif //_DENVERTON_NS_SATA_H diff --git a/src/soc/intel/denverton_ns/include/soc/smbus.h b/src/soc/intel/denverton_ns/include/soc/smbus.h new file mode 100644 index 0000000000..5dbeecc0cf --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/smbus.h @@ -0,0 +1,85 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com> + * Copyright (C) 2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DENVERTON_NS_SMBUS_H_ +#define _DENVERTON_NS_SMBUS_H_ + +/* PCI Configuration Space (D31:F4): SMBus */ +#define SMB_BASE 0x20 +#define HOSTC 0x40 +#define HST_EN (1 << 0) +#define HOSTC_SMI_EN (1 << 1) +#define HOSTC_I2C_EN (1 << 2) +#define SMB_RCV_SLVA 0x09 +/* SMBUS TCO base address. */ +#define TCOBASE 0x50 +#define MASK_TCOBASE 0xffe0 +#define TCOCTL 0x54 +#define TCOBASE_EN (1 << 8) +#define TCOBASE_LOCK (1 << 0) + +/* SMBus I/O bits. */ +#define SMBHSTSTAT 0x0 +#define HST_HBSY (1 << 0) +#define HST_INTR (1 << 1) +#define HST_DERR (1 << 2) +#define HST_BERR (1 << 3) +#define HST_BYTE_DONE_STS (1 << 7) +#define HST_HSTS_ALL 0xFF +#define SMBHSTCTL 0x2 +#define HST_LAST_BYTE (1 << 5) +#define HST_START (1 << 6) +#define HST_CMD_IIC_READ 0x18 +#define HST_READ 0x01 // RW +#define SMBHSTCMD 0x3 +#define SMBXMITADD 0x4 +#define SMBHSTDAT0 0x5 +#define SMBHSTDAT1 0x6 +#define SMBBLKDAT 0x7 +#define SMBTRNSADD 0x9 +#define SMBSLVDATA 0xa +#define SMBHSTAUXC 0xd +#define SMLINK_PIN_CTL 0xe +#define SMBUS_PIN_CTL 0xf + +/* + * SMBus Private Config Registers (PID:SMB) + */ +#define PCR_SMBUS_TCOCFG 0x00 /* TCO Configuration register */ +#define PCR_SMBUS_TCOCFG_IE (1 << 7) /* TCO IRQ Enable */ +#define PCR_SMBUS_TCOCFG_IS 7 /* TCO IRQ Select */ +#define PCR_SMBUS_TCOCFG_IRQ_9 0x00 +#define PCR_SMBUS_TCOCFG_IRQ_10 0x01 +#define PCR_SMBUS_TCOCFG_IRQ_11 0x02 +#define PCR_SMBUS_TCOCFG_IRQ_20 0x04 /* only if APIC enabled */ +#define PCR_SMBUS_TCOCFG_IRQ_21 0x05 /* only if APIC enabled */ +#define PCR_SMBUS_TCOCFG_IRQ_22 0x06 /* only if APIC enabled */ +#define PCR_SMBUS_TCOCFG_IRQ_23 0x07 /* only if APIC enabled */ +#define PCR_SMBUS_SMBTM 0x04 /* SMBus Test Mode */ +#define PCR_SMBUS_SMBTM_SMBCT (1 << 1) /* SMBus Counter */ +#define PCR_SMBUS_SMBTM_SMBDG (1 << 0) /* SMBus Deglitch */ +#define PCR_SMBUS_SCTM 0x08 /* Short Counter Test Mode */ +#define PCR_SMBUS_SCTM_SSU (1 << 31) /* Simulation Speed-Up */ +#define PCR_SMBUS_GC 0x0C /* General Control */ +#define PCR_SMBUS_GC_FD (1 << 0) /* Function Disable */ +#define PCR_SMBUS_GC_NR (1 << 1) /* No Reboot */ +#define PCR_SMBUS_GC_SMBSCGE (1 << 2) /* SMB Static Clock Gating Enable */ +#define PCR_SMBUS_PCE 0x10 /* Power Control Enable */ +#define PCR_SMBUS_PCE_HAE (1 << 5) /* Hardware Autonomous Enable */ + +#endif /* _DENVERTON_NS_SMBUS_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/smm.h b/src/soc/intel/denverton_ns/include/soc/smm.h new file mode 100644 index 0000000000..fe6dc826d1 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/smm.h @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_SMM_H_ +#define _DENVERTON_NS_SMM_H_ + +struct smm_relocation_attrs { + uint32_t smbase; + uint32_t smrr_base; + uint32_t smrr_mask; +}; + +/* + * mmap_region_granularity must to return a size which is a positive non-zero + * integer multiple of the SMM size when SMM is in use. When not using SMM, + * this value should be set to 8 MiB. + */ +size_t mmap_region_granularity(void); + +/* Fills in the arguments for the entire SMM region covered by chipset + * protections. e.g. TSEG. */ +void smm_region(void **start, size_t *size); + +enum { + /* SMM handler area. */ + SMM_SUBREGION_HANDLER, + /* SMM cache region. */ + SMM_SUBREGION_CACHE, + /* Chipset specific area. */ + SMM_SUBREGION_CHIPSET, + /* Total sub regions supported. */ + SMM_SUBREGION_NUM, +}; + +/* Fills in the start and size for the requested SMM subregion. Returns + * 0 on susccess, < 0 on failure. */ +int smm_subregion(int sub, void **start, size_t *size); + +#if !defined(__PRE_RAM__) && !defined(__SMM___) +#include <stdint.h> +void southcluster_smm_clear_state(void); +void southcluster_smm_enable_smi(void); +void southcluster_smm_save_gpio_route(uint32_t route); +#endif + +#endif /* _DENVERTON_NS_SMM_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/soc_util.h b/src/soc/intel/denverton_ns/include/soc/soc_util.h new file mode 100644 index 0000000000..074ec16933 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/soc_util.h @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_SOC_UTIL_H_ +#define _DENVERTON_NS_SOC_UTIL_H_ + +#ifndef __ACPI__ +#include <device/device.h> + +/* Silicon revisions */ +typedef enum { + SILICON_REV_DENVERTON_A0 = 0x00, + SILICON_REV_DENVERTON_A1 = 0x01, + SILICON_REV_DENVERTON_B0 = 0x02, +} silicon_revision; + +/* soc_util.c */ +device_t get_hostbridge_dev(void); +device_t get_lpc_dev(void); +device_t get_pmc_dev(void); +device_t get_smbus_dev(void); + +uint32_t get_pciebase(void); +uint32_t get_pcielength(void); +uint32_t get_tseg_memory(void); +uint32_t get_top_of_low_memory(void); +uint64_t get_top_of_upper_memory(void); +uint16_t get_pmbase(void); +uint16_t get_tcobase(void); + +/* +* Secure functions. +*/ +void *memcpy_s(void *dest, const void *src, size_t n); + +void mmio_andthenor32(void *addr, uint32_t val2and, uint32_t val2or); +uint8_t silicon_stepping(void); + +/* +* MMIO Read/Write +*/ +#define MMIO8(x) (*((volatile u8 *)(x))) +#define MMIO16(x) (*((volatile u16 *)(x))) +#define MMIO32(x) (*((volatile u32 *)(x))) + +#define MMIO_AND_OR(bits, x, and, or) \ + (MMIO##bits(x) = ((MMIO##bits(x) & (and)) | (or))) + +#define MMIO8_AND_OR(x, and, or) MMIO_AND_OR(8, x, and, or) +#define MMIO16_AND_OR(x, and, or) MMIO_AND_OR(16, x, and, or) +#define MMIO32_AND_OR(x, and, or) MMIO_AND_OR(32, x, and, or) +#define MMIO32_OR(x, or) MMIO_AND_OR(32, x, ~0UL, or) +#define MMIO32_AND(x, and) MMIO_AND_OR(32, x, and, 0UL) + +#endif //__ACPI__ + +#endif /* _DENVERTON_NS_SOC_UTIL_H_ */ diff --git a/src/soc/intel/denverton_ns/include/soc/systemagent.h b/src/soc/intel/denverton_ns/include/soc/systemagent.h new file mode 100644 index 0000000000..a02aea34d4 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/systemagent.h @@ -0,0 +1,89 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 - 2008 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_SYSTEMAGENT_H_ +#define _DENVERTON_NS_SYSTEMAGENT_H_ + +#include <soc/iomap.h> + +/* Device 0:0.0 PCI configuration space (Host Bridge) */ +#define PCH_SA_DEV PCI_DEV(0, SA_DEV, SA_FUNC) + +#define MCHBAR 0x48 /* MCH space. */ +#define PCIEXBAR 0x60 /* PCI express space. */ +#define MASK_PCIEXBAR_256M 0xF0000000 +#define MASK_PCIEXBAR_128M 0xF8000000 +#define MASK_PCIEXBAR_64M 0xFC000000 +#define MASK_PCIEXBAR_LENGTH 0x6 +#define SHIFT_PCIEXBAR_LENGTH 0x1 +#define MASK_PCIEXBAR_LENGTH_256M (0x0 << SHIFT_PCIEXBAR_LENGTH) +#define MASK_PCIEXBAR_LENGTH_128M (0x1 << SHIFT_PCIEXBAR_LENGTH) +#define MASK_PCIEXBAR_LENGTH_64M (0x2 << SHIFT_PCIEXBAR_LENGTH) + +#define TOUUD_LO 0xa8 /* Top of Upper Usable DRAM - Low */ +#define MASK_TOUUD_LO 0xFFF00000 +#define TOUUD_HI 0xac /* Top of Upper Usable DRAM - High */ +#define MASK_TOUUD_HI 0x0000007F +#define TOUUD TOUUD_LO /* Top of Upper Usable DRAM */ +#define MASK_TOUUD 0x7FFFF00000 + +#define TSEGMB 0xb8 /* TSEG base */ +#define MASK_TSEGMB 0xFFF00000 +#define TOLUD 0xbc /* Top of Low Used Memory */ +#define MASK_TOLUD 0xFFF00000 + +/* SideBand B-UNIT */ +#define B_UNIT 3 + +/* SideBand C-UNIT */ +#define C_UNIT 8 + +/* SideBand D-UNIT */ +#define D_UNIT 1 + +/* SideBand P-UNIT */ +#define P_UNIT 4 + +/* + * MCHBAR + */ +#define MCH_BASE_SIZE 0x8000 +#define MCH_BMISC 0x6800 +#define MCH_BMISC_SBVDRAM \ + 0x08 /* Bit 3: 1 - reads targeting boot vector are routed to DRAM. */ +#define MCH_BMISC_ABSEGINDRAM \ + 0x04 /* Bit 2: 1 - reads targeting A/B-segment are routed to DRAM. */ +#define MCH_BMISC_RFSDRAM \ + 0x02 /* Bit 1: 1 - reads targeting E-segment are routed to DRAM. */ +#define MCH_BMISC_RESDRAM \ + 0x01 /* Bit 0: 1 - reads targeting E-segment are routed to DRAM. */ + +#define MCH_BAR_BIOS_RESET_CPL 0x7078 +#define RST_CPL_BIT (1 << 0) +#define PCODE_INIT_DONE (1 << 8) +#define MCH_BAR_CORE_EXISTS_MASK 0x7164 +#define MCH_BAR_CORE_DISABLE_MASK 0x7168 + +/* Device 0:4.0 PCI configuration space (RAS) */ + +/* Device 0:5.0 PCI configuration space (RCEC) */ + +/* Top of 32bit usable memory */ +u32 top_of_32bit_ram(void); + +#endif //_DENVERTON_NS_SYSTEMAGENT_H_ diff --git a/src/soc/intel/denverton_ns/include/soc/uart.h b/src/soc/intel/denverton_ns/include/soc/uart.h new file mode 100644 index 0000000000..29e9024d87 --- /dev/null +++ b/src/soc/intel/denverton_ns/include/soc/uart.h @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DENVERTON_NS_UART_H +#define _DENVERTON_NS_UART_H + +#define SIZE_OF_HSUART_RES 0x100 +#define HARCUVAR_UARTS_TO_INI 3 +#define PSR_OFFSET 0x30 +#define PCI_FUNC_RDCFG_HIDE 0x74 + +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)])) + +#endif /* _DENVERTON_NS_UART_H */ diff --git a/src/soc/intel/denverton_ns/lpc.c b/src/soc/intel/denverton_ns/lpc.c new file mode 100644 index 0000000000..48e81e5783 --- /dev/null +++ b/src/soc/intel/denverton_ns/lpc.c @@ -0,0 +1,336 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/acpi.h> +#include <cpu/cpu.h> +#include <cpu/x86/smm.h> +#include <bootstate.h> + +#include <soc/lpc.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/iomap.h> +#include <soc/pcr.h> +#include <soc/p2sb.h> +#include <soc/acpi.h> + +#include "chip.h" + +/* PCH-LP redirection entries */ +#define PCH_LP_REDIR_ETR 120 + +/** + * Set miscellanous static southbridge features. + * + * @param dev PCI device with I/O APIC control registers + */ +static void pch_enable_ioapic(struct device *dev) +{ + u32 reg32; + + set_ioapic_id((void *)IO_APIC_ADDR, IO_APIC0); + + /* affirm full set of redirection table entries ("write once") */ + reg32 = io_apic_read((void *)IO_APIC_ADDR, 0x01); + + reg32 &= ~0x00ff0000; + reg32 |= (PCH_LP_REDIR_ETR - 1) << 16; + + io_apic_write((void *)IO_APIC_ADDR, 0x01, reg32); + + /* + * Select Boot Configuration register (0x03) and + * use Processor System Bus (0x01) to deliver interrupts. + */ + io_apic_write((void *)IO_APIC_ADDR, 0x03, 0x01); +} + +/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control + * 0x00 - 0000 = Reserved + * 0x01 - 0001 = Reserved + * 0x02 - 0010 = Reserved + * 0x03 - 0011 = IRQ3 + * 0x04 - 0100 = IRQ4 + * 0x05 - 0101 = IRQ5 + * 0x06 - 0110 = IRQ6 + * 0x07 - 0111 = IRQ7 + * 0x08 - 1000 = Reserved + * 0x09 - 1001 = IRQ9 + * 0x0A - 1010 = IRQ10 + * 0x0B - 1011 = IRQ11 + * 0x0C - 1100 = IRQ12 + * 0x0D - 1101 = Reserved + * 0x0E - 1110 = IRQ14 + * 0x0F - 1111 = IRQ15 + * PIRQ[n]_ROUT[7] - PIRQ Routing Control + * 0x80 - The PIRQ is not routed. + */ + +static void pch_pirq_init(device_t dev) +{ + device_t irq_dev; + /* Get the chip configuration */ + config_t *config = dev->chip_info; + + /* Initialize PIRQ Routings */ + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQA_ROUT), + config->pirqa_routing); + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQB_ROUT), + config->pirqb_routing); + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQC_ROUT), + config->pirqc_routing); + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQD_ROUT), + config->pirqd_routing); + + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQE_ROUT), + config->pirqe_routing); + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQF_ROUT), + config->pirqf_routing); + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQG_ROUT), + config->pirqg_routing); + write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQH_ROUT), + config->pirqh_routing); + + /* Initialize device's Interrupt Routings */ + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR00), + config->ir00_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR01), + config->ir01_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR02), + config->ir02_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR03), + config->ir03_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR04), + config->ir04_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR05), + config->ir05_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR06), + config->ir06_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR07), + config->ir07_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR08), + config->ir08_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR09), + config->ir09_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR10), + config->ir10_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR11), + config->ir11_routing); + write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR12), + config->ir12_routing); + + /* Initialize device's Interrupt Polarity Control */ + write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC0), + config->ipc0); + write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC1), + config->ipc1); + write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC2), + config->ipc2); + write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC3), + config->ipc3); + + for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) { + u8 int_pin = 0, int_line = 0; + + if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI) + continue; + + int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN); + + switch (int_pin) { + case 1: /* INTA# */ + int_line = config->pirqa_routing; + break; + case 2: /* INTB# */ + int_line = config->pirqb_routing; + break; + case 3: /* INTC# */ + int_line = config->pirqc_routing; + break; + case 4: /* INTD# */ + int_line = config->pirqd_routing; + break; + } + + if (!int_line) + continue; + + pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line); + } +} + +static void pci_p2sb_read_resources(device_t dev) +{ + struct resource *res; + + /* Add MMIO resource + * Use 0xda as an unused index for PCR BAR. + */ + res = new_resource(dev, 0xda); + res->base = DEFAULT_PCR_BASE; + res->size = 16 * 1024 * 1024; /* 16MB PCR config space */ + res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | + IORESOURCE_ASSIGNED; + printk(BIOS_DEBUG, + "Adding P2SB PCR config space BAR 0x%08lx-0x%08lx.\n", + (unsigned long)(res->base), + (unsigned long)(res->base + res->size)); + + /* Add MMIO resource + * Use 0xdb as an unused index for IOAPIC. + */ + res = new_resource(dev, 0xdb); /* IOAPIC */ + res->base = IO_APIC_ADDR; + res->size = 0x00001000; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void pch_enable_serial_irqs(struct device *dev) +{ + /* Set packet length and toggle silent mode bit for one frame. */ + pci_write_config8(dev, SERIRQ_CNTL, + (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0)); +#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE) + pci_write_config8(dev, SERIRQ_CNTL, + (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0)); +#endif +} + +static void lpc_init(struct device *dev) +{ + printk(BIOS_DEBUG, "pch: lpc_init\n"); + + /* Get the base address */ + + /* Set the value for PCI command register. */ + pci_write_config16(dev, PCI_COMMAND, + PCI_COMMAND_SPECIAL | PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | PCI_COMMAND_IO); + + /* Serial IRQ initialization. */ + pch_enable_serial_irqs(dev); + + /* IO APIC initialization. */ + pch_enable_ioapic(dev); + + /* Setup the PIRQ. */ + pch_pirq_init(dev); +} + +static void pch_lpc_add_mmio_resources(device_t dev) { /* TODO */ } + +static void pch_lpc_add_io_resources(device_t dev) +{ + struct resource *res; + u8 io_index = 0; + + /* Add an extra subtractive resource for both memory and I/O. */ + res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0)); + res->base = 0; + res->size = 0x1000; + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | + IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + + res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0)); + res->base = 0xff000000; + res->size = 0x01000000; /* 16 MB for flash */ + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | + IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void lpc_read_resources(device_t dev) +{ + /* Get the normal PCI resources of this device. */ + pci_dev_read_resources(dev); + + /* Add non-standard MMIO resources. */ + pch_lpc_add_mmio_resources(dev); + + /* Add IO resources. */ + pch_lpc_add_io_resources(dev); + + /* Add MMIO resource for IOAPIC. */ + pci_p2sb_read_resources(dev); +} + +static void pch_decode_init(struct device *dev) { /* TODO */ } + +static void lpc_enable_resources(device_t dev) +{ + pch_decode_init(dev); + pci_dev_enable_resources(dev); +} + +/* Set bit in Function Disable register to hide this device */ +static void pch_hide_devfn(uint32_t devfn) { /* TODO */ } + +void southcluster_enable_dev(device_t dev) +{ + u32 reg32; + + if (!dev->enabled) { + printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev)); + + /* Ensure memory, io, and bus master are all disabled */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | + PCI_COMMAND_IO); + pci_write_config32(dev, PCI_COMMAND, reg32); + + /* Hide this device if possible */ + pch_hide_devfn(dev->path.pci.devfn); + } else { + /* Enable SERR */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 |= PCI_COMMAND_SERR; + pci_write_config32(dev, PCI_COMMAND, reg32); + } +} + +static struct device_operations device_ops = { + .read_resources = lpc_read_resources, + .set_resources = pci_dev_set_resources, +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_inject_dsdt_generator = southcluster_inject_dsdt, + .write_acpi_tables = southcluster_write_acpi_tables, +#endif + .enable_resources = lpc_enable_resources, + .init = lpc_init, + .enable = southcluster_enable_dev, + .scan_bus = scan_lpc_bus, + .ops_pci = &soc_pci_ops, +}; + +static const struct pci_driver lpc_driver __pci_driver = { + .ops = &device_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = LPC_DEVID, +}; + +static void finalize_chipset(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing SMM.\n"); + outb(APM_CNT_FINALIZE, APM_CNT); +} + +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL); +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, finalize_chipset, NULL); diff --git a/src/soc/intel/denverton_ns/memmap.c b/src/soc/intel/denverton_ns/memmap.c new file mode 100644 index 0000000000..3fe41d2088 --- /dev/null +++ b/src/soc/intel/denverton_ns/memmap.c @@ -0,0 +1,108 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <cbfs.h> +#include <cbmem.h> +#include <assert.h> +#include <device/device.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <console/console.h> +#include <soc/pci_devs.h> +#include <soc/systemagent.h> +#include <soc/smm.h> +#include <lib.h> + +/* Returns base of requested region encoded in the system agent. */ +static inline uintptr_t system_agent_region_base(size_t reg) +{ + device_t dev = SA_DEV_ROOT; + + /* All regions concerned for have 1 MiB alignment. */ + return ALIGN_DOWN(pci_read_config32(dev, reg), 1 * MiB); +} + +/* Returns min power of 2 >= size */ +static inline u32 power_of_2(u32 size) +{ + return size ? 1 << (1 + log2(size - 1)) : 0; +} + +u32 top_of_32bit_ram(void) +{ + u32 iqat_region_size = 0; + u32 tseg_region_size = system_agent_region_base(TOLUD) - + system_agent_region_base(TSEGMB); + +/* + * Add IQAT region size if enabled. + */ +#if IS_ENABLED(CONFIG_IQAT_ENABLE) + iqat_region_size = CONFIG_IQAT_MEMORY_REGION_SIZE; +#endif + return system_agent_region_base(TOLUD) - + power_of_2(iqat_region_size + tseg_region_size); +} + +void *cbmem_top(void) { return (void *)top_of_32bit_ram(); } + +static inline uintptr_t smm_region_start(void) +{ + return system_agent_region_base(TSEGMB); +} + +static inline size_t smm_region_size(void) +{ + return system_agent_region_base(TOLUD) - smm_region_start(); +} + +void smm_region(void **start, size_t *size) +{ + *start = (void *)smm_region_start(); + *size = smm_region_size(); +} + +int smm_subregion(int sub, void **start, size_t *size) +{ + uintptr_t sub_base; + size_t sub_size; + const size_t cache_size = CONFIG_SMM_RESERVED_SIZE; + + sub_base = smm_region_start(); + sub_size = smm_region_size(); + + assert(sub_size > CONFIG_SMM_RESERVED_SIZE); + + switch (sub) { + case SMM_SUBREGION_HANDLER: + /* Handler starts at the base of TSEG. */ + sub_size -= cache_size; + break; + case SMM_SUBREGION_CACHE: + /* External cache is in the middle of TSEG. */ + sub_base += sub_size - cache_size; + sub_size = cache_size; + break; + default: + return -1; + } + + *start = (void *)sub_base; + *size = sub_size; + + return 0; +} diff --git a/src/soc/intel/denverton_ns/npk.c b/src/soc/intel/denverton_ns/npk.c new file mode 100644 index 0000000000..46e5c7ef74 --- /dev/null +++ b/src/soc/intel/denverton_ns/npk.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <arch/io.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include <soc/pci_devs.h> +#include <soc/ramstage.h> + +static void npk_init(device_t dev) +{ + printk(BIOS_DEBUG, "pch: npk_init\n"); + + /* TODO */ +} + +static void pci_npk_read_resources(device_t dev) +{ + /* Skip NorthPeak enumeration. */ +} + +static struct device_operations pmc_ops = { + .read_resources = pci_npk_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .scan_bus = 0, + .init = npk_init, + .ops_pci = &soc_pci_ops, +}; + +static const struct pci_driver pch_pmc __pci_driver = { + .ops = &pmc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = NPK_DEVID, +}; diff --git a/src/soc/intel/denverton_ns/pmc.c b/src/soc/intel/denverton_ns/pmc.c new file mode 100644 index 0000000000..90237a0de3 --- /dev/null +++ b/src/soc/intel/denverton_ns/pmc.c @@ -0,0 +1,116 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <arch/acpi.h> +#include <arch/io.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include <soc/iomap.h> +#include <soc/pmc.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <cpu/x86/smm.h> + +/* While we read BAR dynamically in case it changed, let's + * initialize it with a same value + */ +static u16 acpi_base = DEFAULT_ACPI_BASE; +static u32 pwrm_base = DEFAULT_PWRM_BASE; + +static void pch_power_options(device_t dev) { /* TODO */ } + +static void pch_set_acpi_mode(void) +{ + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && !acpi_is_wakeup_s3()) { + printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n"); + outb(APM_CNT_ACPI_DISABLE, APM_CNT); + printk(BIOS_DEBUG, "done.\n"); + } +} + +static void pmc_init(device_t dev) +{ + printk(BIOS_DEBUG, "pch: pmc_init\n"); + + /* Get the base address */ + acpi_base = pci_read_config16(dev, PMC_ACPI_BASE) & MASK_PMC_ACPI_BASE; + pwrm_base = pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE; + + /* Set the value for PCI command register. */ + pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_IO); + + /* Setup power options. */ + pch_power_options(dev); + + /* Configure ACPI mode. */ + pch_set_acpi_mode(); +} + +static void pci_pmc_read_resources(device_t dev) +{ + struct resource *res; + + /* Get the normal PCI resources of this device. */ + pci_dev_read_resources(dev); + + /* Add MMIO resource + * Use 0xaa as an unused index for PWRM BAR. + */ + u32 reg32 = pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE; + if ((reg32 != 0x0) && (reg32 != 0xffffffff)) { + res = new_resource(dev, 0xaa); + res->base = reg32; + res->size = 64 * 1024; /* 64K bytes memory config space */ + res->flags = + IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + printk(BIOS_DEBUG, + "Adding PMC PWRM config space BAR 0x%08lx-0x%08lx.\n", + (unsigned long)(res->base), + (unsigned long)(res->base + res->size)); + } + + /* Add MMIO resource + * Use 0xab as an unused index for ACPI BAR. + */ + u16 reg16 = pci_read_config16(dev, PMC_ACPI_BASE) & MASK_PMC_ACPI_BASE; + if ((reg16 != 0x0) && (reg16 != 0xffff)) { + res = new_resource(dev, 0xab); + res->base = reg16; + res->size = 0x100; /* 256 bytes I/O config space */ + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | + IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + } +} + +static struct device_operations pmc_ops = { + .read_resources = pci_pmc_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .scan_bus = 0, + .init = pmc_init, + .ops_pci = &soc_pci_ops, +}; + +static const struct pci_driver pch_pmc __pci_driver = { + .ops = &pmc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PMC_DEVID, +}; diff --git a/src/soc/intel/denverton_ns/pmutil.c b/src/soc/intel/denverton_ns/pmutil.c new file mode 100644 index 0000000000..542997c6c6 --- /dev/null +++ b/src/soc/intel/denverton_ns/pmutil.c @@ -0,0 +1,248 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdint.h> +#include <arch/io.h> +#include <console/console.h> + +#include <soc/iomap.h> +#include <soc/soc_util.h> +#include <soc/pm.h> + +static void print_num_status_bits(int num_bits, uint32_t status, + const char * const bit_names[]) +{ + int i; + + if (!status) + return; + + for (i = num_bits - 1; i >= 0; i--) { + if (status & (1 << i)) { + if (bit_names[i]) + printk(BIOS_DEBUG, "%s ", bit_names[i]); + else + printk(BIOS_DEBUG, "BIT%d ", i); + } + } +} + +static uint32_t print_smi_status(uint32_t smi_sts) +{ + static const char * const smi_sts_bits[] = { + [2] = "BIOS", + [4] = "SLP_SMI", + [5] = "APM", + [6] = "SWSMI_TMR", + [8] = "PM1", + [9] = "GPE0", + [10] = "GPE1", + [11] = "MC_SMI", + [12] = "DEVMON", + [13] = "TCO", + [14] = "PERIODIC", + [15] = "SERIRQ", + [16] = "SMBUS_SMI", + [17] = "LEGACY_USB2", + [18] = "INTEL_USB2", + [19] = "PATCH", + [20] = "PCI_EXP_SMI", + [21] = "MONITOR", + [26] = "SPI", + [27] = "GPIO_UNLOCK", + [31] = "LEGACY_USB3", + }; + + if (!smi_sts) + return 0; + + printk(BIOS_DEBUG, "SMI_STS: "); + print_num_status_bits(ARRAY_SIZE(smi_sts_bits), smi_sts, smi_sts_bits); + printk(BIOS_DEBUG, "\n"); + + return smi_sts; +} + +static uint32_t reset_smi_status(void) +{ + uint16_t pmbase = get_pmbase(); + uint32_t smi_sts = inl((uint16_t)(pmbase + SMI_STS)); + outl(smi_sts, (uint16_t)(pmbase + SMI_STS)); + return smi_sts; +} + +uint32_t clear_smi_status(void) { return print_smi_status(reset_smi_status()); } + +void enable_smi(uint32_t mask) +{ + uint16_t pmbase = get_pmbase(); + uint32_t smi_en = inl((uint16_t)(pmbase + SMI_EN)); + smi_en |= mask; + outl(smi_en, (uint16_t)(pmbase + SMI_EN)); +} + +void disable_smi(uint32_t mask) +{ + uint16_t pmbase = get_pmbase(); + uint32_t smi_en = inl((uint16_t)(pmbase + SMI_EN)); + smi_en &= ~mask; + outl(smi_en, (uint16_t)(pmbase + SMI_EN)); +} + +void enable_pm1_control(uint32_t mask) +{ + uint16_t pmbase = get_pmbase(); + uint32_t pm1_cnt = inl((uint16_t)(pmbase + PM1_CNT)); + pm1_cnt |= mask; + outl(pm1_cnt, (uint16_t)(pmbase + PM1_CNT)); +} + +void disable_pm1_control(uint32_t mask) +{ + uint16_t pmbase = get_pmbase(); + uint32_t pm1_cnt = inl((uint16_t)(pmbase + PM1_CNT)); + pm1_cnt &= ~mask; + outl(pm1_cnt, (uint16_t)(pmbase + PM1_CNT)); +} + +static uint16_t reset_pm1_status(void) +{ + uint16_t pmbase = get_pmbase(); + uint16_t pm1_sts = inw((uint16_t)(pmbase + PM1_STS)); + outw(pm1_sts, (uint16_t)(pmbase + PM1_STS)); + return pm1_sts; +} + +static uint16_t print_pm1_status(uint16_t pm1_sts) +{ + static const char * const pm1_sts_bits[] = { + [0] = "TMROF", [4] = "BM", [5] = "GBL", + [8] = "PWRBTN", [10] = "RTC", [11] = "PRBTNOR", + [15] = "WAK", + }; + + if (!pm1_sts) + return 0; + + printk(BIOS_SPEW, "PM1_STS: "); + print_num_status_bits(ARRAY_SIZE(pm1_sts_bits), pm1_sts, pm1_sts_bits); + printk(BIOS_SPEW, "\n"); + + return pm1_sts; +} + +uint16_t clear_pm1_status(void) { return print_pm1_status(reset_pm1_status()); } + +void enable_pm1(uint16_t events) +{ + uint16_t pmbase = get_pmbase(); + outw(events, (uint16_t)(pmbase + PM1_EN)); +} + +static uint32_t print_tco_status(uint32_t tco_sts) +{ + static const char * const tco_sts_bits[] = { + [0] = "NMI2SMI", [1] = "OS_TCO_SMI", + [2] = "TCO_INIT", [3] = "TIMEOUT", + [7] = "NEWCENTURY ", [8] = "BIOSWR ", + [9] = "CPUSCI ", [10] = "CPUSMI ", + [12] = "CPUSERR ", [16] = "INTRD_DET ", + [17] = "SECOND_TO", [20] = "SMLINK_SLV_SMI", + }; + + if (!tco_sts) + return 0; + + printk(BIOS_DEBUG, "TCO_STS: "); + print_num_status_bits(ARRAY_SIZE(tco_sts_bits), tco_sts, tco_sts_bits); + printk(BIOS_DEBUG, "\n"); + + return tco_sts; +} + +static uint32_t reset_tco_status(void) +{ + uint16_t tcobase = get_tcobase(); + uint32_t tco_sts = inl((uint16_t)(tcobase + TCO1_STS)); + uint32_t tco_en = inl((uint16_t)(tcobase + TCO1_CNT)); + + outl(tco_sts, (uint16_t)(tcobase + TCO1_STS)); + return tco_sts & tco_en; +} + +uint32_t clear_tco_status(void) { return print_tco_status(reset_tco_status()); } + +void enable_gpe(uint32_t mask) +{ + uint16_t pmbase = get_pmbase(); + uint32_t gpe0_en = inl((uint16_t)(pmbase + GPE0_EN)); + gpe0_en |= mask; + outl(gpe0_en, (uint16_t)(pmbase + GPE0_EN)); +} + +void disable_gpe(uint32_t mask) +{ + uint16_t pmbase = get_pmbase(); + uint32_t gpe0_en = inl((uint16_t)(pmbase + GPE0_EN)); + gpe0_en &= ~mask; + outl(gpe0_en, (uint16_t)(pmbase + GPE0_EN)); +} + +void disable_all_gpe(void) { disable_gpe(~0); } + +static uint32_t reset_gpe_status(void) +{ + uint16_t pmbase = get_pmbase(); + uint32_t gpe_sts = inl((uint16_t)(pmbase + GPE0_STS)); + outl(gpe_sts, (uint16_t)(pmbase + GPE0_STS)); + return gpe_sts; +} + +static uint32_t print_gpe_sts(uint32_t gpe_sts) +{ + static const char * const gpe_sts_bits[] = { + [0] = "GPIO_0", [1] = "GPIO_1", + [2] = "GPIO_2", [3] = "GPIO_3", + [4] = "GPIO_4", [5] = "GPIO_5", + [6] = "GPIO_6", [7] = "GPIO_7", + [8] = "GPIO_8", [9] = "GPIO_9", + [10] = "GPIO_10", [11] = "GPIO_11", + [12] = "GPIO_12", [13] = "GPIO_13", + [14] = "GPIO_14", [15] = "GPIO_15", + [16] = "GPIO_16", [17] = "GPIO_17", + [18] = "GPIO_18", [19] = "GPIO_19", + [20] = "GPIO_20", [21] = "GPIO_21", + [22] = "GPIO_22", [23] = "GPIO_23", + [24] = "GPIO_24", [25] = "GPIO_25", + [26] = "GPIO_26", [27] = "GPIO_27", + [28] = "GPIO_28", [29] = "GPIO_29", + [30] = "GPIO_30", [31] = "GPIO_31", + }; + + if (!gpe_sts) + return gpe_sts; + + printk(BIOS_DEBUG, "GPE0a_STS: "); + print_num_status_bits(ARRAY_SIZE(gpe_sts_bits), gpe_sts, gpe_sts_bits); + printk(BIOS_DEBUG, "\n"); + + return gpe_sts; +} + +uint32_t clear_gpe_status(void) { return print_gpe_sts(reset_gpe_status()); } + +void clear_pmc_status(void) { /* TODO */ } diff --git a/src/soc/intel/denverton_ns/reset.c b/src/soc/intel/denverton_ns/reset.c new file mode 100644 index 0000000000..97955a574a --- /dev/null +++ b/src/soc/intel/denverton_ns/reset.c @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <fsp/util.h> +#include <reset.h> + +void chipset_handle_reset(uint32_t status) +{ + switch (status) { + case FSP_STATUS_RESET_REQUIRED_5: /* Global Reset */ + global_reset(); + break; + default: + printk(BIOS_ERR, "unhandled reset type %x\n", status); + die("unknown reset type"); + break; + } +} diff --git a/src/soc/intel/denverton_ns/romstage.c b/src/soc/intel/denverton_ns/romstage.c new file mode 100644 index 0000000000..512d8ccb3c --- /dev/null +++ b/src/soc/intel/denverton_ns/romstage.c @@ -0,0 +1,295 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cbmem.h> +#include <console/console.h> +#include <cpu/x86/mtrr.h> +#include <harcuvar_boardid.h> +#include <hsio.h> +#include <reset.h> +#include <soc/fiamux.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pcr.h> +#include <soc/pmc.h> +#include <soc/romstage.h> +#include <soc/smbus.h> +#include <soc/smm.h> +#include <soc/soc_util.h> + +void __attribute__((weak)) mainboard_config_gpios(void) {} + +#if IS_ENABLED(CONFIG_DISPLAY_HOBS) +static void display_fsp_smbios_memory_info_hob(void) +{ + int channel, dimm; + size_t hob_size; + const DIMM_INFO *dimm_info; + const CHANNEL_INFO *channel_info; + const FSP_SMBIOS_MEMORY_INFO *memory_info_hob; + + /* Locate the memory info HOB */ + memory_info_hob = fsp_find_smbios_memory_info(&hob_size); + + /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */ + if (memory_info_hob) { + printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n"); + printk(BIOS_DEBUG, " 0x%02x: Revision\n", + memory_info_hob->Revision); + printk(BIOS_DEBUG, " 0x%02x: MemoryType\n", + memory_info_hob->MemoryType); + printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n", + memory_info_hob->MemoryFrequencyInMHz); + printk(BIOS_DEBUG, " %d: DataWidth in bits\n", + memory_info_hob->DataWidth); + printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n", + memory_info_hob->ErrorCorrectionType); + printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n", + memory_info_hob->ChannelCount); + for (channel = 0; channel < memory_info_hob->ChannelCount; + channel++) { + channel_info = &memory_info_hob->ChannelInfo[channel]; + printk(BIOS_DEBUG, " Channel %d\n", channel); + printk(BIOS_DEBUG, " 0x%02x: ChannelId\n", + channel_info->ChannelId); + printk(BIOS_DEBUG, " 0x%02x: DimmCount\n", + channel_info->DimmCount); + for (dimm = 0; dimm < channel_info->DimmCount; + dimm++) { + dimm_info = &channel_info->DimmInfo[dimm]; + printk(BIOS_DEBUG, " DIMM %d\n", dimm); + printk(BIOS_DEBUG, " 0x%02x: DimmId\n", + dimm_info->DimmId); + printk(BIOS_DEBUG, " %d: SizeInMb\n", + dimm_info->SizeInMb); + printk(BIOS_DEBUG, " 0x%04x: MfgId\n", + dimm_info->MfgId); + printk(BIOS_DEBUG, "%*.*s: ModulePartNum\n", + (int)sizeof(dimm_info->ModulePartNum), + (int)sizeof(dimm_info->ModulePartNum), + dimm_info->ModulePartNum); + } + } + } else { + printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB not found!!!\n"); + } +} +#endif + +static void early_pmc_init(void) +{ + /* PMC (B0:D31:F2). */ + device_t dev = PCH_PMC_DEV; + + /* Is PMC present */ + if (pci_read_config16(dev, 0) == 0xffff) { + printk(BIOS_ERR, "PMC controller (B0:D31:F2) does not present!\n"); + return; + } + + uint32_t pwrm_base = + pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE; + if (!pwrm_base) { + printk(BIOS_ERR, "PWRM base address is not configured!\n"); + return; + } + + /* Workaround for sighting report (doc#: 560805) v1.86. + 42. System Might Hang In AC Power Loss + Problem : + When removing and reapplying AC power to the board, + the system might hang at serial output + 'RESET required : change of frequency' + due to PMC ROM change on B0. + Implication : + 1. This issue is only shown in B0 stepping. + 2. This issue does not impact a system without an RTC battery. + Alternative workaround : + Remove RTC battery on the board if possible. + Status : Plan Fix. + */ + if (silicon_stepping() == SILICON_REV_DENVERTON_B0) { + if (!(pci_read_config32(dev, PMC_GEN_PMCON_B) + & PMC_GEN_PMCON_B_RTC_PWR_STS)) { + if (read32((void *)(pwrm_base + 0x124)) + & ((1 << 11) | (1 << 12))) { + /* Performs a global reset */ + printk(BIOS_DEBUG, + "Requesting Global Reset...\n"); + pci_write_config32(dev, PMC_ETR3, + pci_read_config32(dev, PMC_ETR3) + | PMC_ETR3_CF9GR); + hard_reset(); + } + } + } +} + +static void early_tco_init(void) +{ + /* SMBUS (B0:D31:F4). */ + device_t dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC); + + /* Configure TCO base address */ + if (pci_read_config16(dev, TCOBASE) == 0xffff) { + printk(BIOS_ERR, "SMBus controller (B0:D31:F4) does not present!\n"); + return; + } + uint16_t tco_ctl = pci_read_config16(dev, TCOCTL); + if (tco_ctl & TCOBASE_LOCK) { + printk(BIOS_ERR, "TCO base register already has been locked!\n"); + } else { + pci_write_config16(dev, TCOCTL, tco_ctl & (~TCOBASE_EN)); + pci_write_config16(dev, TCOBASE, DEFAULT_TCO_BASE | 0x1); + pci_write_config16(dev, TCOCTL, tco_ctl | TCOBASE_EN); + } + + uint16_t tco_base = pci_read_config16(dev, TCOBASE) & MASK_TCOBASE; + printk(BIOS_DEBUG, "TCO base address set to 0x%x!\n", tco_base); + + /* Disable the TCO timer expiration from causing a system reset */ + MMIO32_OR(PCH_PCR_ADDRESS(PID_SMB, PCR_SMBUS_GC), + (uint32_t)PCR_SMBUS_GC_NR); + + /* Halt the TCO timer */ + uint16_t reg16 = inw(tco_base + TCO1_CNT); + reg16 |= TCO_TMR_HLT; + outw(reg16, tco_base + TCO1_CNT); + + /* Clear the Second TCO status bit */ + reg16 = inw(tco_base + TCO2_STS); + reg16 |= TCO2_STS_SECOND_TO; + outw(reg16, tco_base + TCO2_STS); +} + +asmlinkage void car_stage_entry(void) +{ + + struct postcar_frame pcf; + uintptr_t top_of_ram; + +#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) + void *smm_base; + size_t smm_size; + uintptr_t tseg_base; +#endif + + console_init(); + + printk(BIOS_DEBUG, "FSP TempRamInit was successful...\n"); + + mainboard_config_gpios(); + early_tco_init(); + early_pmc_init(); + + fsp_memory_init(false); + +#if IS_ENABLED(CONFIG_DISPLAY_HOBS) + display_fsp_smbios_memory_info_hob(); +#endif + + if (postcar_frame_init(&pcf, 1 * KiB)) + die("Unable to initialize postcar frame.\n"); + + /* + * We need to make sure ramstage will be run cached. At this point exact + * location of ramstage in cbmem is not known. Instruct postcar to cache + * 16 megs under cbmem top which is a safe bet to cover ramstage. + */ + top_of_ram = (uintptr_t)cbmem_top(); + postcar_frame_add_mtrr(&pcf, top_of_ram - 16 * MiB, 16 * MiB, + MTRR_TYPE_WRBACK); + + /* Cache the memory-mapped boot media. */ + if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED)) + postcar_frame_add_mtrr(&pcf, -CONFIG_ROM_SIZE, CONFIG_ROM_SIZE, + MTRR_TYPE_WRPROT); +#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) + /* + * Cache the TSEG region at the top of ram. This region is + * not restricted to SMM mode until SMM has been relocated. + * By setting the region to cacheable it provides faster access + * when relocating the SMM handler as well as using the TSEG + * region for other purposes. + */ + smm_region(&smm_base, &smm_size); + tseg_base = (uintptr_t)smm_base; + postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK); +#endif + + run_postcar_phase(&pcf); +} + +static void soc_memory_init_params(FSP_M_CONFIG *m_cfg) +{ + FSPM_UPD *mupd = container_of(m_cfg, FSPM_UPD, FspmConfig); + size_t num; + uint16_t supported_hsio_lanes; + uint8_t boardid = board_id(); + BL_HSIO_INFORMATION *hsio_config; + + /* Set the parameters for MemoryInit */ + m_cfg->PcdEnableIQAT = IS_ENABLED(CONFIG_IQAT_ENABLE); + + /* if ME HECI communication is disabled, apply default one*/ + if (mupd->FspmConfig.PcdMeHeciCommunication == 0) { + + /* Configure FIA MUX PCD */ + /* Assume the validating silicon has max lanes. */ + supported_hsio_lanes = BL_ME_FIA_MUX_LANE_NUM_MAX; + + switch (boardid) { + case BoardIdHarcuvar: + num = ARRAY_SIZE(harcuvar_hsio_config); + hsio_config = + (BL_HSIO_INFORMATION *)harcuvar_hsio_config; + break; + default: + num = 0; + hsio_config = NULL; + break; + } + + if (get_fiamux_hsio_info(supported_hsio_lanes, num, + &hsio_config)) + die("HSIO Configuration is invalid, please correct " + "it!"); + + /* Check the requested FIA MUX Configuration */ + if (!(&hsio_config->FiaConfig)) { + die("Requested FIA MUX Configuration is invalid," + " please correct it!"); + } + + mupd->FspmConfig.PcdHsioLanesNumber = + (uint32_t)hsio_config->NumLanesSupported; + mupd->FspmConfig.PcdFiaMuxConfigPtr = + (uint32_t)&hsio_config->FiaConfig; + } +} + +__attribute__((weak)) void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + /* Do nothing */ +} + +void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) +{ + FSP_M_CONFIG *m_cfg = &mupd->FspmConfig; + + soc_memory_init_params(m_cfg); + + mainboard_memory_init_params(mupd); +} diff --git a/src/soc/intel/denverton_ns/sata.c b/src/soc/intel/denverton_ns/sata.c new file mode 100644 index 0000000000..421b6e35ca --- /dev/null +++ b/src/soc/intel/denverton_ns/sata.c @@ -0,0 +1,93 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 - 2009 coresystems GmbH + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <arch/io.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/sata.h> + +#include "chip.h" + +static void sata_init(struct device *dev) +{ + u32 reg32; + u16 reg16; + u32 abar; + + /* Get the chip configuration */ + config_t *config = dev->chip_info; + + printk(BIOS_DEBUG, "SATA: Initializing...\n"); + + if (config == NULL) { + printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n"); + return; + } + + /* SATA configuration is handled by the FSP */ + + /* Enable BARs */ + pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_IO); + + printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n"); + + /* Set the controller mode */ + reg16 = pci_read_config16(dev, SATA_MAP); + reg16 &= ~(3 << 6); + reg16 |= SATA_MAP_AHCI; + pci_write_config16(dev, SATA_MAP, reg16); + + /* Initialize AHCI memory-mapped space */ + abar = pci_read_config32(dev, PCI_BASE_ADDRESS_5); + printk(BIOS_DEBUG, "ABAR: %08X\n", abar); + + /* Enable AHCI Mode */ + reg32 = read32((void *)(abar + 0x04)); + reg32 |= (1 << 31); + write32((void *)(abar + 0x04), reg32); +} + +static void sata_enable(device_t dev) { /* TODO */ } + +static struct device_operations sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sata_init, + .enable = sata_enable, + .scan_bus = 0, + .ops_pci = &soc_pci_ops, +}; + +static const unsigned short pci_device_ids[] = { + AHCI_DEVID, /* DVN SATA AHCI */ + AHCI2_DEVID, /* DVN SATA2 AHCI */ + 0 +}; + +static const struct pci_driver soc_sata __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +}; diff --git a/src/soc/intel/denverton_ns/smihandler.c b/src/soc/intel/denverton_ns/smihandler.c new file mode 100644 index 0000000000..e434c1cd3f --- /dev/null +++ b/src/soc/intel/denverton_ns/smihandler.c @@ -0,0 +1,372 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdint.h> +#include <stdlib.h> +#include <arch/hlt.h> +#include <arch/io.h> +#include <console/console.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/smm.h> +#include <device/pci_def.h> +#include <elog.h> +#include <intelblocks/fast_spi.h> +#include <spi-generic.h> +#include <soc/iomap.h> +#include <soc/soc_util.h> +#include <soc/pm.h> +#include <soc/nvs.h> + +/* GNVS needs to be set by coreboot initiating a software SMI. */ +static global_nvs_t *gnvs; +static int smm_initialized; + +int southbridge_io_trap_handler(int smif) +{ + switch (smif) { + case 0x32: + printk(BIOS_DEBUG, "OS Init\n"); + /* gnvs->smif: + * On success, the IO Trap Handler returns 0 + * On failure, the IO Trap Handler returns a value != 0 + */ + gnvs->smif = 0; + return 1; /* IO trap handled */ + } + + /* Not handled */ + return 0; +} + +void southbridge_smi_set_eos(void) { enable_smi(EOS); } + +global_nvs_t *smm_get_gnvs(void) { return gnvs; } + +static void busmaster_disable_on_bus(int bus) +{ + int slot, func; + unsigned int val; + unsigned char hdr; + + for (slot = 0; slot < 0x20; slot++) { + for (func = 0; func < 8; func++) { + u32 reg32; + device_t dev = PCI_DEV(bus, slot, func); + + val = pci_read_config32(dev, PCI_VENDOR_ID); + + if (val == 0xffffffff || val == 0x00000000 || + val == 0x0000ffff || val == 0xffff0000) + continue; + + /* Disable Bus Mastering for this one device */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 &= ~PCI_COMMAND_MASTER; + pci_write_config32(dev, PCI_COMMAND, reg32); + + /* If this is a bridge, then follow it. */ + hdr = pci_read_config8(dev, PCI_HEADER_TYPE); + hdr &= 0x7f; + if (hdr == PCI_HEADER_TYPE_BRIDGE || + hdr == PCI_HEADER_TYPE_CARDBUS) { + unsigned int buses; + buses = pci_read_config32(dev, PCI_PRIMARY_BUS); + busmaster_disable_on_bus((buses >> 8) & 0xff); + } + } + } +} + +static void southbridge_smi_sleep(void) +{ + uint32_t reg32; + uint8_t slp_typ; + uint16_t pmbase = get_pmbase(); + + /* First, disable further SMIs */ + disable_smi(SLP_SMI_EN); + + /* Figure out SLP_TYP */ + reg32 = inl((uint16_t)(pmbase + PM1_CNT)); + printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32); + slp_typ = (reg32 >> 10) & 7; + + /* Do any mainboard sleep handling */ + mainboard_smi_sleep((uint8_t)(slp_typ - 2)); + + /* Next, do the deed. + */ + + switch (slp_typ) { + case SLP_TYP_S0: + printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); + break; + case SLP_TYP_S1: + printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); + break; + case SLP_TYP_S3: + printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n"); + + /* Invalidate the cache before going to S3 */ + wbinvd(); + break; + case SLP_TYP_S4: + printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); + break; + case SLP_TYP_S5: + printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n"); + + /* Disable all GPE */ + disable_all_gpe(); + + /* also iterates over all bridges on bus 0 */ + busmaster_disable_on_bus(0); + break; + default: + printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); + break; + } + + /* Write back to the SLP register to cause the originally intended + * event again. We need to set BIT13 (SLP_EN) though to make the + * sleep happen. + */ + enable_pm1_control(SLP_EN); + + /* Make sure to stop executing code here for S3/S4/S5 */ + if (slp_typ > 1) + hlt(); + + /* In most sleep states, the code flow of this function ends at + * the line above. However, if we entered sleep state S1 and wake + * up again, we will continue to execute code in this function. + */ + reg32 = inl((uint16_t)(pmbase + PM1_CNT)); + if (reg32 & SCI_EN) { + /* The OS is not an ACPI OS, so we set the state to S0 */ + disable_pm1_control(SLP_EN | SLP_TYP); + } +} + +/* + * Look for Synchronous IO SMI and use save state from that + * core in case we are not running on the same core that + * initiated the IO transaction. + */ +static em64t100_smm_state_save_area_t *smi_apmc_find_state_save(uint8_t cmd) +{ + em64t100_smm_state_save_area_t *state; + int node; + + /* Check all nodes looking for the one that issued the IO */ + for (node = 0; node < CONFIG_MAX_CPUS; node++) { + state = smm_get_save_state(node); + + /* Check for Synchronous IO (bit0==1) */ + if (!(state->io_misc_info & (1 << 0))) + continue; + + /* Make sure it was a write (bit4==0) */ + if (state->io_misc_info & (1 << 4)) + continue; + + /* Check for APMC IO port */ + if (((state->io_misc_info >> 16) & 0xff) != APM_CNT) + continue; + + /* Check AX against the requested command */ + if ((state->rax & 0xff) != cmd) + continue; + + return state; + } + + return NULL; +} + +static void finalize(void) +{ + static int finalize_done; + + if (finalize_done) { + printk(BIOS_DEBUG, "SMM already finalized.\n"); + return; + } + finalize_done = 1; + + if (IS_ENABLED(CONFIG_SPI_FLASH_SMM)) + /* Re-init SPI driver to handle locked BAR */ + fast_spi_init(); +} + +static void southbridge_smi_apmc(void) +{ + uint8_t reg8; + em64t100_smm_state_save_area_t *state; + + /* Emulate B2 register as the FADT / Linux expects it */ + + reg8 = inb(APM_CNT); + switch (reg8) { + case APM_CNT_CST_CONTROL: + /* Calling this function seems to cause + * some kind of race condition in Linux + * and causes a kernel oops + */ + printk(BIOS_DEBUG, "C-state control\n"); + break; + case APM_CNT_PST_CONTROL: + /* Calling this function seems to cause + * some kind of race condition in Linux + * and causes a kernel oops + */ + printk(BIOS_DEBUG, "P-state control\n"); + break; + case APM_CNT_ACPI_DISABLE: + disable_pm1_control(SCI_EN); + printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n"); + break; + case APM_CNT_ACPI_ENABLE: + enable_pm1_control(SCI_EN); + printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n"); + break; + case APM_CNT_FINALIZE: + finalize(); + break; + case APM_CNT_GNVS_UPDATE: + if (smm_initialized) { + printk(BIOS_DEBUG, + "SMI#: SMM structures already initialized!\n"); + return; + } + state = smi_apmc_find_state_save(reg8); + if (state) { + /* EBX in the state save contains the GNVS pointer */ + gnvs = (global_nvs_t *)((uint32_t)state->rbx); + smm_initialized = 1; + printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs); + } + break; + } + + mainboard_smi_apmc(reg8); +} + +static void southbridge_smi_pm1(void) +{ + uint16_t pm1_sts = clear_pm1_status(); + + /* While OSPM is not active, poweroff immediately + * on a power button event. + */ + if (pm1_sts & PWRBTN_STS) { + // power button pressed + disable_pm1_control(-1UL); + enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT)); + } +} + +static void southbridge_smi_gpe0(void) { clear_gpe_status(); } + +static void southbridge_smi_tco(void) +{ + uint32_t tco_sts = clear_tco_status(); + + /* Any TCO event? */ + if (!tco_sts) + return; + + if (tco_sts & TCO1_STS_TIMEOUT) { /* TIMEOUT */ + /* Handle TCO timeout */ + printk(BIOS_DEBUG, "TCO Timeout.\n"); + } +} + +static void southbridge_smi_periodic(void) +{ + uint32_t reg32; + + reg32 = inl((uint16_t)(get_pmbase() + SMI_EN)); + + /* Are periodic SMIs enabled? */ + if ((reg32 & PERIODIC_EN) == 0) + return; + + printk(BIOS_DEBUG, "Periodic SMI.\n"); +} + +typedef void (*smi_handler_t)(void); + +static const smi_handler_t southbridge_smi[32] = { + NULL, // [0] reserved + NULL, // [1] reserved + NULL, // [2] BIOS_STS + NULL, // [3] LEGACY_USB_STS + southbridge_smi_sleep, // [4] SLP_SMI_STS + southbridge_smi_apmc, // [5] APM_STS + NULL, // [6] SWSMI_TMR_STS + NULL, // [7] reserved + southbridge_smi_pm1, // [8] PM1_STS + southbridge_smi_gpe0, // [9] GPE0_STS + NULL, // [10] reserved + NULL, // [11] reserved + NULL, // [12] reserved + southbridge_smi_tco, // [13] TCO_STS + southbridge_smi_periodic, // [14] PERIODIC_STS + NULL, // [15] SERIRQ_SMI_STS + NULL, // [16] SMBUS_SMI_STS + NULL, // [17] LEGACY_USB2_STS + NULL, // [18] INTEL_USB2_STS + NULL, // [19] reserved + NULL, // [20] PCI_EXP_SMI_STS + NULL, // [21] reserved + NULL, // [22] reserved + NULL, // [23] reserved + NULL, // [24] reserved + NULL, // [25] reserved + NULL, // [26] SPI_STS + NULL, // [27] reserved + NULL, // [28] PUNIT + NULL, // [29] GUNIT + NULL, // [30] reserved + NULL // [31] reserved +}; + +void southbridge_smi_handler(void) +{ + int i; + uint32_t smi_sts; + + /* We need to clear the SMI status registers, or we won't see what's + * happening in the following calls. + */ + smi_sts = clear_smi_status(); + + /* Call SMI sub handler for each of the status bits */ + for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) { + if (!(smi_sts & (1 << i))) + continue; + + if (southbridge_smi[i] != NULL) { + southbridge_smi[i](); + } else { + printk(BIOS_DEBUG, "SMI_STS[%d] occurred, but no " + "handler available.\n", + i); + } + } +} diff --git a/src/soc/intel/denverton_ns/smm.c b/src/soc/intel/denverton_ns/smm.c new file mode 100644 index 0000000000..732aed4326 --- /dev/null +++ b/src/soc/intel/denverton_ns/smm.c @@ -0,0 +1,92 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <device/device.h> +#include <device/pci.h> +#include <console/console.h> +#include <arch/io.h> +#include <cpu/cpu.h> +#include <cpu/x86/smm.h> +#include <string.h> + +#include <soc/iomap.h> +#include <soc/soc_util.h> +#include <soc/pm.h> +#include <soc/smm.h> + +/* Save the gpio route register. The settings are committed from + * southcluster_smm_enable_smi(). */ +static uint32_t gpio_route; + +void southcluster_smm_save_gpio_route(uint32_t route) { gpio_route = route; } + +void southcluster_smm_clear_state(void) +{ + uint32_t smi_en; + + printk(BIOS_DEBUG, "Initializing Southbridge SMI..."); + printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase()); + + smi_en = inl((uint16_t)(get_pmbase() + SMI_EN)); + if (smi_en & APMC_EN) { + printk(BIOS_INFO, "SMI# handler already enabled?\n"); + return; + } + + /* Dump and clear status registers */ + clear_smi_status(); + clear_pm1_status(); + clear_tco_status(); + clear_gpe_status(); + clear_pmc_status(); +} + +void southcluster_smm_enable_smi(void) +{ + + printk(BIOS_DEBUG, "Enabling SMIs.\n"); + /* Configure events Disable pcie wake. */ + enable_pm1(PWRBTN_EN | GBL_EN | PCIEXPWAK_DIS); + disable_gpe(PME_B0_EN); + + /* Enable SMI generation: + * - on APMC writes (io 0xb2) + * - on writes to SLP_EN (sleep states) + * - on writes to GBL_RLS (bios commands) + * No SMIs: + * - on TCO events + * - on microcontroller writes (io 0x62/0x66) + */ + enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS); +} + +void smm_setup_structures(void *gnvs, void *tcg, void *smi1) +{ + /* + * Issue SMI to set the gnvs pointer in SMM. + * tcg and smi1 are unused. + * + * EAX = APM_CNT_GNVS_UPDATE + * EBX = gnvs pointer + * EDX = APM_CNT + */ + asm volatile("outb %%al, %%dx\n\t" + : /* ignore result */ + : "a"(APM_CNT_GNVS_UPDATE), "b"((uint32_t)gnvs), + "d"(APM_CNT)); +} diff --git a/src/soc/intel/denverton_ns/soc_util.c b/src/soc/intel/denverton_ns/soc_util.c new file mode 100644 index 0000000000..1626927ef2 --- /dev/null +++ b/src/soc/intel/denverton_ns/soc_util.c @@ -0,0 +1,254 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdint.h> +#include <arch/io.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <device/device.h> +#include <console/console.h> + +#include <soc/iomap.h> +#include <soc/soc_util.h> +#include <soc/pmc.h> +#include <soc/smbus.h> +#include <soc/lpc.h> +#include <soc/pci_devs.h> +#include <soc/systemagent.h> + +device_t get_hostbridge_dev(void) +{ +#if defined(__PRE_RAM__) || defined(__SMM__) + return PCI_DEV(0, SA_DEV, SA_FUNC); +#else + return dev_find_slot(0, PCI_DEVFN(SA_DEV, SA_FUNC)); +#endif +} + +device_t get_lpc_dev(void) +{ +#if defined(__PRE_RAM__) || defined(__SMM__) + return PCI_DEV(0, LPC_DEV, LPC_FUNC); +#else + return dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC)); +#endif +} + +device_t get_pmc_dev(void) +{ +#if defined(__PRE_RAM__) || defined(__SMM__) + return PCI_DEV(0, PMC_DEV, PMC_FUNC); +#else + return dev_find_slot(0, PCI_DEVFN(PMC_DEV, PMC_FUNC)); +#endif +} + +device_t get_smbus_dev(void) +{ +#if defined(__PRE_RAM__) || defined(__SMM__) + return PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC); +#else + return dev_find_slot(0, PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC)); +#endif +} + +uint32_t get_pciebase(void) +{ + device_t dev; + u32 pciexbar_reg; + + dev = get_hostbridge_dev(); + if (!dev) + return 0; + + pciexbar_reg = pci_read_config32(dev, PCIEXBAR); + + if (!(pciexbar_reg & (1 << 0))) + return 0; + + switch (pciexbar_reg & MASK_PCIEXBAR_LENGTH) { + case MASK_PCIEXBAR_LENGTH_256M: + pciexbar_reg &= MASK_PCIEXBAR_256M; + break; + case MASK_PCIEXBAR_LENGTH_128M: + pciexbar_reg &= MASK_PCIEXBAR_128M; + break; + case MASK_PCIEXBAR_LENGTH_64M: + pciexbar_reg &= MASK_PCIEXBAR_64M; + break; + default: + pciexbar_reg &= MASK_PCIEXBAR_256M; + break; + } + + return pciexbar_reg; +} + +uint32_t get_pcielength(void) +{ + device_t dev; + u32 pciexbar_reg; + + dev = get_hostbridge_dev(); + if (!dev) + return 0; + + pciexbar_reg = pci_read_config32(dev, PCIEXBAR); + + if (!(pciexbar_reg & (1 << 0))) + return 0; + + switch (pciexbar_reg & MASK_PCIEXBAR_LENGTH) { + case MASK_PCIEXBAR_LENGTH_256M: + pciexbar_reg = 256; + break; + case MASK_PCIEXBAR_LENGTH_128M: + pciexbar_reg = 128; + break; + case MASK_PCIEXBAR_LENGTH_64M: + pciexbar_reg = 64; + break; + default: + pciexbar_reg = 64; + break; + } + + return pciexbar_reg; +} + +uint32_t get_tseg_memory(void) +{ + device_t dev = get_hostbridge_dev(); + + if (!dev) + return 0; + + return pci_read_config32(dev, TSEGMB) & MASK_TSEGMB; +} + +uint32_t get_top_of_low_memory(void) +{ + device_t dev = get_hostbridge_dev(); + + if (!dev) + return 0; + + return pci_read_config32(dev, TOLUD) & MASK_TOLUD; +} + +uint64_t get_top_of_upper_memory(void) +{ + device_t dev = get_hostbridge_dev(); + + if (!dev) + return 0; + + return ((uint64_t)(pci_read_config32(dev, TOUUD_HI) & MASK_TOUUD_HI) + << 32) + + (uint64_t)(pci_read_config32(dev, TOUUD_LO) & MASK_TOUUD_LO); +} + +uint16_t get_pmbase(void) +{ + device_t dev = get_pmc_dev(); + + if (!dev) + return 0; + + return pci_read_config16(dev, PMC_ACPI_BASE) & 0xfff8; +} + +uint16_t get_tcobase(void) +{ + device_t dev = get_smbus_dev(); + + if (!dev) + return 0; + + return pci_read_config16(dev, TCOBASE) & MASK_TCOBASE; +} + +void mmio_andthenor32(void *addr, uint32_t val2and, uint32_t val2or) +{ + uint32_t reg32; + + reg32 = read32(addr); + reg32 &= (uint32_t)val2and; + reg32 |= (uint32_t)val2or; + write32(addr, reg32); +} + +uint8_t silicon_stepping(void) +{ + uint8_t revision_id; + device_t dev = get_lpc_dev(); + + if (!dev) + return 0; + + revision_id = pci_read_config8(dev, PCI_REVISION_ID); + + return revision_id; +} + +void *memcpy_s(void *dest, const void *src, size_t n) +{ + uint8_t *dp; + const uint8_t *sp; + + dp = (uint8_t *)dest; + sp = (uint8_t *)src; + + if (!n) + return dest; + + if (n > UINT32_MAX) + return dest; + + if (!dp) + return dest; + + if (!sp) + return dest; + + /* + * overlap is undefined behavior, do not allow + */ + if (((dp > sp) && (dp < (sp + n))) || ((sp > dp) && (sp < (dp + n)))) + return dest; + + /* + * now perform the copy + */ + + /* Original memcpy() function */ + unsigned long d0, d1, d2; + + asm volatile( +#ifdef __x86_64__ + "rep ; movsd\n\t" + "mov %4,%%rcx\n\t" +#else + "rep ; movsl\n\t" + "movl %4,%%ecx\n\t" +#endif + "rep ; movsb\n\t" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(n >> 2), "g"(n & 3), "1"(dest), "2"(src) + : "memory"); + + return dest; +} diff --git a/src/soc/intel/denverton_ns/spi.c b/src/soc/intel/denverton_ns/spi.c new file mode 100644 index 0000000000..9a651ee048 --- /dev/null +++ b/src/soc/intel/denverton_ns/spi.c @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <intelblocks/fast_spi.h> +#include <spi-generic.h> + +const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { + { .ctrlr = &fast_spi_flash_ctrlr, .bus_start = 0, .bus_end = 0 }, +}; + +const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); diff --git a/src/soc/intel/denverton_ns/systemagent.c b/src/soc/intel/denverton_ns/systemagent.c new file mode 100644 index 0000000000..bb5f81a81c --- /dev/null +++ b/src/soc/intel/denverton_ns/systemagent.c @@ -0,0 +1,356 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <arch/acpi.h> +#include <arch/io.h> +#include <stdint.h> +#include <delay.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <stdlib.h> +#include <string.h> +#include <cbmem.h> +#include <romstage_handoff.h> +#include <delay.h> +#include <timer.h> + +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/systemagent.h> + +#define _1ms 1 +#define WAITING_STEP 100 + +static int get_pcie_bar(device_t dev, unsigned int index, u32 *base, u32 *len) +{ + u32 pciexbar_reg; + + *base = 0; + *len = 0; + + pciexbar_reg = pci_read_config32(dev, index); + + 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 int get_bar(device_t dev, unsigned int index, u32 *base, u32 *len) +{ + u32 bar; + + bar = pci_read_config32(dev, index); + + /* If not enabled don't report it. */ + if (!(bar & 0x1)) + return 0; + + /* Knock down the enable bit. */ + *base = bar & ~1; + + return 1; +} + +struct fixed_mmio_descriptor { + unsigned int index; + u32 size; + int (*get_resource)(device_t dev, unsigned int index, u32 *base, + u32 *size); + const char *description; +}; + +struct fixed_mmio_descriptor mc_fixed_resources[] = { + {PCIEXBAR, 0, get_pcie_bar, "PCIEXBAR"}, + {MCHBAR, MCH_BASE_SIZE, get_bar, "MCHBAR"}, +}; + +/* + * Add all known fixed MMIO ranges that hang off the host bridge/memory + * controller device. + */ +static void mc_add_fixed_mmio_resources(device_t dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mc_fixed_resources); i++) { + u32 base; + u32 size; + struct resource *resource; + unsigned int index; + + size = mc_fixed_resources[i].size; + index = mc_fixed_resources[i].index; + if (!mc_fixed_resources[i].get_resource(dev, index, &base, + &size)) + continue; + + resource = new_resource(dev, mc_fixed_resources[i].index); + resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_RESERVE | + IORESOURCE_ASSIGNED; + resource->base = base; + resource->size = size; + printk(BIOS_DEBUG, "%s: Adding %s @ %x 0x%08lx-0x%08lx.\n", + __func__, mc_fixed_resources[i].description, index, + (unsigned long)base, (unsigned long)(base + size - 1)); + } +} + +struct map_entry { + int reg; + int is_64_bit; + int is_limit; + const char *description; +}; + +static void read_map_entry(device_t dev, struct map_entry *entry, + uint64_t *result) +{ + uint64_t value; + uint64_t mask; + + /* All registers are on a 1MiB granularity. */ + mask = ((1ULL << 20) - 1); + mask = ~mask; + + value = 0; + + if (entry->is_64_bit) { + value = pci_read_config32(dev, entry->reg + 4); + value <<= 32; + } + + value |= (uint64_t)pci_read_config32(dev, entry->reg); + value &= mask; + + if (entry->is_limit) + value |= ~mask; + + *result = value; +} + +#define MAP_ENTRY(reg_, is_64_, is_limit_, desc_) \ + { \ + .reg = reg_, .is_64_bit = is_64_, .is_limit = is_limit_, \ + .description = desc_, \ + } + +#define MAP_ENTRY_BASE_64(reg_, desc_) MAP_ENTRY(reg_, 1, 0, desc_) +#define MAP_ENTRY_LIMIT_64(reg_, desc_) MAP_ENTRY(reg_, 1, 1, desc_) +#define MAP_ENTRY_BASE_32(reg_, desc_) MAP_ENTRY(reg_, 0, 0, desc_) + +enum { + TOUUD_REG, + TOLUD_REG, + TSEG_REG, + /* Must be last. */ + NUM_MAP_ENTRIES +}; + +static struct map_entry memory_map[NUM_MAP_ENTRIES] = { + [TOUUD_REG] = MAP_ENTRY_BASE_64(TOUUD, "TOUUD"), + [TOLUD_REG] = MAP_ENTRY_BASE_32(TOLUD, "TOLUD"), + [TSEG_REG] = MAP_ENTRY_BASE_32(TSEGMB, "TSEGMB"), +}; + +static void mc_read_map_entries(device_t dev, uint64_t *values) +{ + int i; + for (i = 0; i < NUM_MAP_ENTRIES; i++) + read_map_entry(dev, &memory_map[i], &values[i]); +} + +static void mc_report_map_entries(device_t dev, uint64_t *values) +{ + int i; + for (i = 0; i < NUM_MAP_ENTRIES; i++) { + printk(BIOS_DEBUG, "MC MAP: %s: 0x%llx\n", + memory_map[i].description, values[i]); + } +} + +static void mc_add_dram_resources(device_t dev) +{ + unsigned long base_k, size_k; + unsigned long touud_k; + unsigned long index; + struct resource *resource; + uint64_t mc_values[NUM_MAP_ENTRIES]; + + /* Read in the MAP registers and report their values. */ + mc_read_map_entries(dev, &mc_values[0]); + mc_report_map_entries(dev, &mc_values[0]); + + /* + * These are the host memory ranges that should be added: + * - 0 -> 0xa0000: cacheable + * - 0xc0000 -> 0x100000 : reserved + * - 0x100000 -> top_of_ram : cacheable + * - top_of_ram -> TSEG: uncacheable + * - TESG -> TOLUD: cacheable with standard MTRRs and reserved + * - 4GiB -> TOUUD: cacheable + * + * The default SMRAM space is reserved so that the range doesn't + * have to be saved during S3 Resume. Once marked reserved the OS + * cannot use the memory. This is a bit of an odd place to reserve + * the region, but the CPU devices don't have dev_ops->read_resources() + * called on them. + * + * The range 0xa0000 -> 0xc0000 does not have any resources + * associated with it to handle legacy VGA memory. If this range + * is not omitted the mtrr code will setup the area as cacheable + * causing VGA access to not work. + * + * The TSEG region is mapped as cacheable so that one can perform + * SMRAM relocation faster. Once the SMRR is enabled the SMRR takes + * precedence over the existing MTRRs covering this region. + * + * It should be noted that cacheable entry types need to be added in + * order. The reason is that the current MTRR code assumes this and + * falls over itself if it isn't. + * + * The resource index starts low and should not meet or exceed + * PCI_BASE_ADDRESS_0. + */ + index = 0; + + /* 0 - > 0xa0000 */ + base_k = 0; + size_k = (0xa0000 >> 10) - base_k; + ram_resource(dev, index++, base_k, size_k); + + /* 0x100000 -> top_of_ram */ + base_k = 0x100000 >> 10; + size_k = (top_of_32bit_ram() >> 10) - base_k; + ram_resource(dev, index++, base_k, size_k); + + /* top_of_ram -> TSEG */ + resource = new_resource(dev, index++); + resource->base = top_of_32bit_ram(); + resource->size = mc_values[TSEG_REG] - resource->base; + resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_RESERVE | + IORESOURCE_ASSIGNED; + + /* TSEG -> TOLUD */ + resource = new_resource(dev, index++); + resource->base = mc_values[TSEG_REG]; + resource->size = mc_values[TOLUD_REG] - resource->base; + resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_RESERVE | + IORESOURCE_ASSIGNED | IORESOURCE_CACHEABLE; + printk(BIOS_DEBUG, + "SMM memory location: 0x%llx SMM memory size: 0x%llx\n", + resource->base, resource->size); + + /* 4GiB -> TOUUD */ + base_k = 4096 * 1024; /* 4GiB */ + touud_k = mc_values[TOUUD_REG] >> 10; + size_k = touud_k - base_k; + if (touud_k > base_k) + ram_resource(dev, index++, base_k, size_k); + + /* + * Reserve everything between A segment and 1MB: + * + * 0xa0000 - 0xbffff: legacy VGA + * 0xc0000 - 0xfffff: reserved RAM + */ + mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10); + reserved_ram_resource(dev, index++, (0xc0000 >> 10), + (0x100000 - 0xc0000) >> 10); +} + +static void systemagent_read_resources(device_t dev) +{ + /* Read standard PCI resources. */ + pci_dev_read_resources(dev); + + /* Add all fixed MMIO resources. */ + mc_add_fixed_mmio_resources(dev); + + /* Calculate and add DRAM resources. */ + mc_add_dram_resources(dev); +} + +static void systemagent_init(struct device *dev) +{ + struct stopwatch sw; + void *bios_reset_cpl = + (void *)(DEFAULT_MCHBAR + MCH_BAR_BIOS_RESET_CPL); + uint32_t reg = read32(bios_reset_cpl); + + /* Stage0 BIOS Reset Complete (RST_CPL) */ + reg |= RST_CPL_BIT; + write32(bios_reset_cpl, reg); + + /* + * Poll for bit 8 in same reg (RST_CPL). + * We wait here till 1 ms for the bit to get set. + */ + stopwatch_init_msecs_expire(&sw, _1ms); + while (!(read32(bios_reset_cpl) & PCODE_INIT_DONE)) { + if (stopwatch_expired(&sw)) { + printk(BIOS_DEBUG, "Failed to set RST_CPL bit\n"); + return; + } + udelay(WAITING_STEP); + } + printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n"); +} + +static struct device_operations systemagent_ops = { + .read_resources = &systemagent_read_resources, + .set_resources = &pci_dev_set_resources, + .enable_resources = &pci_dev_enable_resources, + .init = &systemagent_init, + .ops_pci = &soc_pci_ops, +}; + +/* IDs for System Agent device of Intel Denverton SoC */ +static const unsigned short systemagent_ids[] = { + SA_DEVID, /* DVN System Agent */ + 0 +}; + +static const struct pci_driver systemagent_driver __pci_driver = { + .ops = &systemagent_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = systemagent_ids +}; diff --git a/src/soc/intel/denverton_ns/tsc_freq.c b/src/soc/intel/denverton_ns/tsc_freq.c new file mode 100644 index 0000000000..6bf2a48d13 --- /dev/null +++ b/src/soc/intel/denverton_ns/tsc_freq.c @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2014 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <cpu/x86/msr.h> +#include <cpu/x86/tsc.h> +#include <arch/cpu.h> + +#include <soc/cpu.h> +#include <soc/msr.h> + +unsigned long tsc_freq_mhz(void) +{ + msr_t platform_info; + + platform_info = rdmsr(MSR_PLATFORM_INFO); + return CPU_BCLK * ((platform_info.lo >> 8) & 0xff); +} diff --git a/src/soc/intel/denverton_ns/uart.c b/src/soc/intel/denverton_ns/uart.c new file mode 100644 index 0000000000..ca4e8b5979 --- /dev/null +++ b/src/soc/intel/denverton_ns/uart.c @@ -0,0 +1,53 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * The sole purpose of this driver is to avoid BAR to be changed during + * resource allocation. Since configuration space is just 32 bytes it + * shouldn't cause any fragmentation. + */ + +#include <console/uart.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <soc/pci_devs.h> +#include <console/console.h> + +static void dnv_ns_uart_read_resources(struct device *dev) +{ + /* read resources to be visible in the log*/ + pci_dev_read_resources(dev); +} + +static struct device_operations uart_ops = { + .read_resources = dnv_ns_uart_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pci_dev_init, + .enable = DEVICE_NOOP +}; + +static const unsigned short uart_ids[] = { + HSUART_DEVID, /* HSUART 0/1/2 */ + 0 +}; + +static const struct pci_driver uart_driver __pci_driver = { + .ops = &uart_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = uart_ids +}; diff --git a/src/soc/intel/denverton_ns/uart_debug.c b/src/soc/intel/denverton_ns/uart_debug.c new file mode 100644 index 0000000000..f909d56232 --- /dev/null +++ b/src/soc/intel/denverton_ns/uart_debug.c @@ -0,0 +1,34 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdint.h> +#include <device/pci_def.h> +#include <io.h> +#include <arch/pci_io_cfg.h> +#include <soc/uart.h> + +#define MY_PCI_DEV(SEGBUS, DEV, FN) \ + ((((SEGBUS)&0xFFF) << 20) | (((DEV)&0x1F) << 15) | (((FN)&0x07) << 12)) + +uintptr_t uart_platform_base(int idx); + +uintptr_t uart_platform_base(int idx) +{ + return (uintptr_t)pci_io_read_config32( + MY_PCI_DEV(0, CONFIG_HSUART_DEV, idx), + PCI_BASE_ADDRESS_1) + + SIZE_OF_HSUART_RES * idx; +} diff --git a/src/soc/intel/denverton_ns/upd_display.c b/src/soc/intel/denverton_ns/upd_display.c new file mode 100644 index 0000000000..076ffec8d7 --- /dev/null +++ b/src/soc/intel/denverton_ns/upd_display.c @@ -0,0 +1,141 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/cpu.h> +#include <console/console.h> +#include <fsp/util.h> +#include <lib.h> + +/* Display the UPD parameters for MemoryInit */ +void soc_display_fspm_upd_params( + const FSPM_UPD *fspm_old_upd, + const FSPM_UPD *fspm_new_upd) +{ + const FSP_M_CONFIG *new; + const FSP_M_CONFIG *old; + + old = &fspm_old_upd->FspmConfig; + new = &fspm_new_upd->FspmConfig; + + printk(BIOS_SPEW, "UPD values for MemoryInit:\n"); + + #define DISPLAY_UPD(field) \ + fsp_display_upd_value(#field, sizeof(old->field), \ + old->field, new->field) + + DISPLAY_UPD(PcdSmmTsegSize); + DISPLAY_UPD(PcdFspDebugPrintErrorLevel); + DISPLAY_UPD(PcdSpdSmbusAddress_0_0); + DISPLAY_UPD(PcdSpdSmbusAddress_0_1); + DISPLAY_UPD(PcdSpdSmbusAddress_1_0); + DISPLAY_UPD(PcdSpdSmbusAddress_1_1); + DISPLAY_UPD(PcdMrcRmtSupport); + DISPLAY_UPD(PcdMrcRmtCpgcExpLoopCntValue); + DISPLAY_UPD(PcdMrcRmtCpgcNumBursts); + DISPLAY_UPD(PcdMemoryPreservation); + DISPLAY_UPD(PcdFastBoot); + DISPLAY_UPD(PcdEccSupport); + DISPLAY_UPD(PcdHsuartDevice); + DISPLAY_UPD(PcdMemoryDown); + DISPLAY_UPD(PcdEnableSATA0); + DISPLAY_UPD(PcdEnableSATA1); + DISPLAY_UPD(PcdEnableIQAT); + DISPLAY_UPD(PcdSmbusSpdWriteDisable); + DISPLAY_UPD(PcdEnableMeShutdown); + DISPLAY_UPD(PcdEnableXhci); + DISPLAY_UPD(PcdDdrFreq); + DISPLAY_UPD(PcdMmioSize); + DISPLAY_UPD(PcdMeHeciCommunication); + DISPLAY_UPD(PcdHsioLanesNumber); + DISPLAY_UPD(PcdFiaMuxConfigPtr); + DISPLAY_UPD(PcdHalfWidthEnable); + DISPLAY_UPD(PcdTclIdle); + DISPLAY_UPD(PcdInterleaveMode); + DISPLAY_UPD(PcdMemoryThermalThrottling); + DISPLAY_UPD(PcdSkipMemoryTest); + DISPLAY_UPD(PcdUsb2Port1Pin); + DISPLAY_UPD(PcdUsb2Port2Pin); + DISPLAY_UPD(PcdUsb2Port3Pin); + DISPLAY_UPD(PcdUsb2Port4Pin); + DISPLAY_UPD(PcdUsb3Port1Pin); + DISPLAY_UPD(PcdUsb3Port2Pin); + DISPLAY_UPD(PcdUsb3Port3Pin); + DISPLAY_UPD(PcdUsb3Port4Pin); + DISPLAY_UPD(PcdIOxAPIC0_199); + DISPLAY_UPD(PcdDmapX16); + + #undef DISPLAY_UPD + + hexdump(fspm_new_upd, sizeof(*fspm_new_upd)); +} + +/* Display the UPD parameters for SiliconInit */ +void soc_display_fsps_upd_params( + const FSPS_UPD *fsps_old_upd, + const FSPS_UPD *fsps_new_upd) +{ + const FSP_S_CONFIG *new; + const FSP_S_CONFIG *old; + + old = &fsps_old_upd->FspsConfig; + new = &fsps_new_upd->FspsConfig; + + printk(BIOS_SPEW, "UPD values for SiliconInit:\n"); + + #define DISPLAY_UPD(field) \ + fsp_display_upd_value(#field, sizeof(old->field), \ + old->field, new->field) + + DISPLAY_UPD(PcdBifurcationPcie0); + DISPLAY_UPD(PcdBifurcationPcie1); + DISPLAY_UPD(PcdActiveCoreCount); + DISPLAY_UPD(PcdCpuMicrocodePatchBase); + DISPLAY_UPD(PcdCpuMicrocodePatchSize); + DISPLAY_UPD(PcdEnablePcie0); + DISPLAY_UPD(PcdEnablePcie1); + DISPLAY_UPD(PcdEnableEmmc); + DISPLAY_UPD(PcdEnableGbE); + DISPLAY_UPD(PcdFiaMuxConfigRequestPtr); + DISPLAY_UPD(PcdPcieRootPort0DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort1DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort2DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort3DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort4DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort5DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort6DeEmphasis); + DISPLAY_UPD(PcdPcieRootPort7DeEmphasis); + DISPLAY_UPD(PcdEMMCDLLConfigPtr); + DISPLAY_UPD(PcdPcieRootPort0LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort1LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort2LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort3LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort4LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort5LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort6LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort7LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort0Aspm); + DISPLAY_UPD(PcdPcieRootPort1Aspm); + DISPLAY_UPD(PcdPcieRootPort2Aspm); + DISPLAY_UPD(PcdPcieRootPort3Aspm); + DISPLAY_UPD(PcdPcieRootPort4Aspm); + DISPLAY_UPD(PcdPcieRootPort5Aspm); + DISPLAY_UPD(PcdPcieRootPort6Aspm); + DISPLAY_UPD(PcdPcieRootPort7Aspm); + + #undef DISPLAY_UPD + + hexdump(fsps_new_upd, sizeof(*fsps_new_upd)); +} diff --git a/src/soc/intel/denverton_ns/xhci.c b/src/soc/intel/denverton_ns/xhci.c new file mode 100644 index 0000000000..5f8482e644 --- /dev/null +++ b/src/soc/intel/denverton_ns/xhci.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 - 2017 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <arch/io.h> + +#include <soc/pci_devs.h> +#include <soc/ramstage.h> + +static void usb_xhci_init(struct device *dev) +{ + /* USB XHCI configuration is handled by the FSP */ + + printk(BIOS_NOTICE, "pch: %s\n", __func__); + + /* Set the value for PCI command register. */ + pci_write_config16(dev, PCI_COMMAND, + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); +} + +static struct device_operations usb_xhci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = usb_xhci_init, + .enable = pci_dev_enable_resources, + .scan_bus = 0, + .ops_pci = &soc_pci_ops, +}; + +static const struct pci_driver pch_usb_xhci __pci_driver = { + .ops = &usb_xhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = XHCI_DEVID, +}; |