summaryrefslogtreecommitdiff
path: root/src/soc/intel/common
diff options
context:
space:
mode:
authorShaunak Saha <shaunak.saha@intel.com>2017-07-18 00:19:33 -0700
committerAaron Durbin <adurbin@chromium.org>2017-09-08 19:01:04 +0000
commitbd427803ab18576462c2c179c94ec0fec819221c (patch)
treea441902068336e7d83bd2ad94efc2153e00bd1a1 /src/soc/intel/common
parentaf896d071b5d0c6ffabc1f4a5cda1429fb6754b6 (diff)
soc/intel/common/block: Common ACPI
This patch adds the common acpi code.ACPI code is very similar accross different intel chipsets.This patch is an effort to move those code in common place so that it can be shared accross different intel platforms instead of duplicating for each platform. We are removing the common acpi files in src/soc/intel/common. This removes the acpi.c file which was previously in src/soc/common/acpi. The config for common acpi is SOC_INTEL_COMMON_BLOCK_ACPI which can be defined in SOC's Kconfig file in order to use the common ACPI code. This patch also includes the changes in APL platform to use the common ACPI block. TEST= Tested the patch as below: 1.Builds and system boots up with the patch. 2.Check all the ACPI tables are present in /sys/firmware/acpi/tables 3.Check SCI's are properly working as we are modifying the function to override madt. 4.Extract acpi tables like DSDT,APIC, FACP, FACS and decompile the by iasl and compare with good known tables. 5.Execute the extracted tables in aciexec to check acpi methods are working properly. Change-Id: Ib6eb6fd5366e6e28fd81bc22d050b0efa05a2e5d Signed-off-by: Shaunak Saha <shaunak.saha@intel.com> Reviewed-on: https://review.coreboot.org/20630 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Sumeet R Pawnikar <sumeet.r.pawnikar@intel.com>
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r--src/soc/intel/common/Makefile.inc1
-rw-r--r--src/soc/intel/common/acpi.h24
-rw-r--r--src/soc/intel/common/acpi/acpi.c243
-rw-r--r--src/soc/intel/common/block/acpi/Kconfig6
-rw-r--r--src/soc/intel/common/block/acpi/Makefile.inc1
-rw-r--r--src/soc/intel/common/block/acpi/acpi.c497
-rw-r--r--src/soc/intel/common/block/include/intelblocks/acpi.h87
-rw-r--r--src/soc/intel/common/block/lpc/lpc.c2
-rw-r--r--src/soc/intel/common/reset.c7
9 files changed, 593 insertions, 275 deletions
diff --git a/src/soc/intel/common/Makefile.inc b/src/soc/intel/common/Makefile.inc
index cd942580a6..450473006f 100644
--- a/src/soc/intel/common/Makefile.inc
+++ b/src/soc/intel/common/Makefile.inc
@@ -28,7 +28,6 @@ ramstage-$(CONFIG_MMA) += mma.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE) += acpi_wake_source.c
ramstage-y += vbt.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_GFX_OPREGION) += opregion.c
-ramstage-$(CONFIG_SOC_INTEL_COMMON_ACPI) += ./acpi/acpi.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_NHLT) += nhlt.c
bootblock-$(CONFIG_MAINBOARD_HAS_TPM_CR50) += tpm_tis.c
diff --git a/src/soc/intel/common/acpi.h b/src/soc/intel/common/acpi.h
index 19ab92666b..4547204894 100644
--- a/src/soc/intel/common/acpi.h
+++ b/src/soc/intel/common/acpi.h
@@ -1,8 +1,4 @@
/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015 Google Inc.
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
@@ -29,24 +25,4 @@
*/
int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0);
-#if IS_ENABLED(CONFIG_SOC_INTEL_COMMON_ACPI)
-
-/*
- * get_cstate_map returns a table of processor specific acpi_cstate_t entries
- * and number of entries in the table
- */
-acpi_cstate_t *soc_get_cstate_map(int *num_entries);
-
-/*
- * get_soc_tss_table returns a table of processor specific acpi_tstate_t entries
- * and number of entries in the table
- */
-acpi_tstate_t *soc_get_tss_table(int *num_entries);
-
-/*
- * soc_get_acpi_base_address returns the ACPI base address for the SOC
- */
-uint16_t soc_get_acpi_base_address(void);
-
#endif /* CONFIG_SOC_INTEL_COMMON_ACPI */
-#endif
diff --git a/src/soc/intel/common/acpi/acpi.c b/src/soc/intel/common/acpi/acpi.c
deleted file mode 100644
index 0934dbd2ae..0000000000
--- a/src/soc/intel/common/acpi/acpi.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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; 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 <arch/acpigen.h>
-#include <arch/cpu.h>
-#include <cpu/intel/turbo.h>
-#include <cpu/x86/msr.h>
-#include <intelblocks/cpulib.h>
-#include <soc/intel/common/acpi.h>
-#include <soc/pm.h>
-
-#define MSR_PLATFORM_INFO 0xce
-#define MSR_TURBO_RATIO_LIMIT 0x1ad
-#define MSR_CONFIG_TDP_NOMINAL 0x648
-#define MSR_RAPL_POWER_UNIT 0x606
-#define MSR_PKG_POWER_INFO 0x614
-
-/* P-state configuration */
-#define PSS_MAX_ENTRIES 8
-#define PSS_RATIO_STEP 2
-#define PSS_LATENCY_TRANSITION 10
-#define PSS_LATENCY_BUSMASTER 10
-
-
-__attribute__((weak)) acpi_cstate_t *soc_get_cstate_map(int *entries)
-{
- *entries = 0;
- return NULL;
-}
-
-__attribute__((weak)) acpi_tstate_t *soc_get_tss_table(int *entries)
-{
- *entries = 0;
- return NULL;
-}
-
-__attribute__((weak)) uint16_t soc_get_acpi_base_address(void)
-{
-#define ACPI_BASE_ADDR 0x400
- return ACPI_BASE_ADDR;
-}
-
-static int calculate_power(int tdp, int p1_ratio, int ratio)
-{
- u32 m;
- u32 power;
-
- /*
- * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
- *
- * Power = (ratio / p1_ratio) * m * tdp
- */
-
- m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
- m = (m * m) / 1000;
-
- power = ((ratio * 100000 / p1_ratio) / 100);
- power *= (m / 100) * (tdp / 1000);
- power /= 1000;
- return power;
-}
-
-static int get_cores_per_package(void)
-{
- struct cpuinfo_x86 c;
- struct cpuid_result result;
- int cores = 1;
-
- get_fms(&c, cpuid_eax(1));
- if (c.x86 != 6)
- return 1;
-
- result = cpuid_ext(0xb, 1);
- cores = result.ebx & 0xff;
-
- return cores;
-}
-
-static void generate_p_state_entries(int core, int cores_per_package)
-{
- int ratio_min, ratio_max, ratio_turbo, ratio_step;
- int coord_type, power_max, num_entries;
- int ratio, power, clock, clock_max;
-
- coord_type = cpu_get_coord_type();
- ratio_min = cpu_get_min_ratio();
- ratio_max = cpu_get_max_ratio();
- clock_max = (ratio_max * cpu_get_bus_clock()) / KHz;
-
- /* Calculate CPU TDP in mW */
- power_max = cpu_get_power_max();
-
- /* Write _PCT indicating use of FFixedHW */
- acpigen_write_empty_PCT();
-
- /* Write _PPC with no limit on supported P-state */
- acpigen_write_PPC_NVS();
- /* Write PSD indicating configured coordination type */
- acpigen_write_PSD_package(core, 1, coord_type);
-
- /* Add P-state entries in _PSS table */
- acpigen_write_name("_PSS");
-
- /* Determine ratio points */
- ratio_step = PSS_RATIO_STEP;
- num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
- if (num_entries > PSS_MAX_ENTRIES) {
- ratio_step += 1;
- num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
- }
-
- /* P[T] is Turbo state if enabled */
- if (get_turbo_state() == TURBO_ENABLED) {
- /* _PSS package count including Turbo */
- acpigen_write_package(num_entries + 2);
- ratio_turbo = cpu_get_max_turbo_ratio();
-
- /* Add entry for Turbo ratio */
- acpigen_write_PSS_package(
- clock_max + 1, /* MHz */
- power_max, /* mW */
- PSS_LATENCY_TRANSITION, /* lat1 */
- PSS_LATENCY_BUSMASTER, /* lat2 */
- ratio_turbo << 8, /* control */
- ratio_turbo << 8); /* status */
- } else {
- /* _PSS package count without Turbo */
- acpigen_write_package(num_entries + 1);
- }
-
- /* First regular entry is max non-turbo ratio */
- acpigen_write_PSS_package(
- clock_max, /* MHz */
- power_max, /* mW */
- PSS_LATENCY_TRANSITION, /* lat1 */
- PSS_LATENCY_BUSMASTER, /* lat2 */
- ratio_max << 8, /* control */
- ratio_max << 8); /* status */
-
- /* Generate the remaining entries */
- for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
- ratio >= ratio_min; ratio -= ratio_step) {
-
- /* Calculate power at this ratio */
- power = calculate_power(power_max, ratio_max, ratio);
- clock = (ratio * cpu_get_bus_clock()) / KHz;
-
- acpigen_write_PSS_package(
- clock, /* MHz */
- power, /* mW */
- PSS_LATENCY_TRANSITION, /* lat1 */
- PSS_LATENCY_BUSMASTER, /* lat2 */
- ratio << 8, /* control */
- ratio << 8); /* status */
- }
- /* Fix package length */
- acpigen_pop_len();
-}
-
-static void generate_c_state_entries(void)
-{
- acpi_cstate_t *c_state_map;
- int entries;
-
- c_state_map = soc_get_cstate_map(&entries);
-
- /* Generate C-state tables */
- acpigen_write_CST_package(c_state_map, entries);
-}
-
-static void generate_t_state_entries(int core, int cores_per_package)
-{
- acpi_tstate_t *soc_tss_table;
- int entries;
-
- soc_tss_table = soc_get_tss_table(&entries);
- if (entries == 0)
- return;
-
- /* Indicate SW_ALL coordination for T-states */
- acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
-
- /* Indicate FFixedHW so OS will use MSR */
- acpigen_write_empty_PTC();
-
- /* Set NVS controlled T-state limit */
- acpigen_write_TPC("\\TLVL");
-
- /* Write TSS table for MSR access */
- acpigen_write_TSS_package(entries, soc_tss_table);
-}
-
-void generate_cpu_entries(device_t device)
-{
- int core_id, cpu_id, pcontrol_blk = soc_get_acpi_base_address();
- int plen = 6;
- int totalcores = dev_count_cpu();
- int cores_per_package = get_cores_per_package();
- int numcpus = totalcores / cores_per_package;
-
- printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
- numcpus, cores_per_package);
-
- for (cpu_id = 0; cpu_id < numcpus; cpu_id++) {
- for (core_id = 0; core_id < cores_per_package; core_id++) {
- if (core_id > 0) {
- pcontrol_blk = 0;
- plen = 0;
- }
-
- /* Generate processor \_PR.CPUx */
- acpigen_write_processor(
- (cpu_id)*cores_per_package + core_id,
- pcontrol_blk, plen);
-
- /* Generate P-state tables */
- generate_p_state_entries(
- core_id, cores_per_package);
-
- /* Generate C-state tables */
- generate_c_state_entries();
-
- /* Generate T-state tables */
- generate_t_state_entries(
- core_id, cores_per_package);
-
- acpigen_pop_len();
- }
- }
-}
diff --git a/src/soc/intel/common/block/acpi/Kconfig b/src/soc/intel/common/block/acpi/Kconfig
new file mode 100644
index 0000000000..ff59172f3b
--- /dev/null
+++ b/src/soc/intel/common/block/acpi/Kconfig
@@ -0,0 +1,6 @@
+config SOC_INTEL_COMMON_BLOCK_ACPI
+ depends on SOC_INTEL_COMMON_BLOCK_CPU
+ depends on SOC_INTEL_COMMON_BLOCK_PMC
+ bool
+ help
+ Intel Processor common code for ACPI
diff --git a/src/soc/intel/common/block/acpi/Makefile.inc b/src/soc/intel/common/block/acpi/Makefile.inc
new file mode 100644
index 0000000000..c6bdac5d3e
--- /dev/null
+++ b/src/soc/intel/common/block/acpi/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI) += acpi.c
diff --git a/src/soc/intel/common/block/acpi/acpi.c b/src/soc/intel/common/block/acpi/acpi.c
new file mode 100644
index 0000000000..e216f2e001
--- /dev/null
+++ b/src/soc/intel/common/block/acpi/acpi.c
@@ -0,0 +1,497 @@
+/*
+ * 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 <arch/acpigen.h>
+#include <arch/ioapic.h>
+#include <arch/smp/mpspec.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include <cpu/intel/reset.h>
+#include <cpu/intel/turbo.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/smm.h>
+#include <intelblocks/acpi.h>
+#include <intelblocks/msr.h>
+#include <intelblocks/pmclib.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/nvs.h>
+#include <soc/pm.h>
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+ /* PCI Segment Group 0, Start Bus Number 0, End Bus Number is 255 */
+ current += acpi_create_mcfg_mmconfig((void *)current,
+ CONFIG_MMCONF_BASE_ADDRESS, 0, 0,
+ 255);
+ return current;
+}
+
+static int acpi_sci_irq(void)
+{
+ int sci_irq = 9;
+ uint32_t scis;
+
+ scis = soc_read_sci_irq_select();
+ scis &= SCI_IRQ_SEL;
+ scis >>= SCI_IRQ_ADJUST;
+
+ /* Determine how SCI is routed. */
+ switch (scis) {
+ case SCIS_IRQ9:
+ case SCIS_IRQ10:
+ case SCIS_IRQ11:
+ sci_irq = scis - SCIS_IRQ9 + 9;
+ break;
+ case SCIS_IRQ20:
+ case SCIS_IRQ21:
+ case SCIS_IRQ22:
+ case SCIS_IRQ23:
+ sci_irq = scis - 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;
+}
+
+static unsigned long acpi_madt_irq_overrides(unsigned long current)
+{
+ int sci = acpi_sci_irq();
+ uint16_t flags = MP_IRQ_TRIGGER_LEVEL;
+
+ /* INT_SRC_OVR */
+ current += acpi_create_madt_irqoverride((void *)current, 0, 0, 2, 0);
+
+ flags |= soc_madt_sci_irq_polarity(sci);
+
+ /* SCI */
+ current +=
+ acpi_create_madt_irqoverride((void *)current, 0, sci, sci, flags);
+
+ return current;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+ /* Local APICs */
+ current = acpi_create_madt_lapics(current);
+
+ /* IOAPIC */
+ current += acpi_create_madt_ioapic((void *)current, 2, IO_APIC_ADDR, 0);
+
+ return acpi_madt_irq_overrides(current);
+}
+
+__attribute__ ((weak)) void soc_fill_fadt(acpi_fadt_t *fadt)
+{
+}
+
+void acpi_fill_fadt(acpi_fadt_t *fadt)
+{
+ const uint16_t pmbase = ACPI_BASE_ADDRESS;
+
+ /* Use ACPI 3.0 revision. */
+ fadt->header.revision = ACPI_FADT_REV_ACPI_3_0;
+
+ fadt->sci_int = acpi_sci_irq();
+ fadt->smi_cmd = APM_CNT;
+ fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+ fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+ 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->gpe0_blk = pmbase + GPE0_STS(0);
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+
+ /* GPE0 STS/EN pairs each 32 bits wide. */
+ fadt->gpe0_blk_len = 2 * GPE0_REG_MAX * sizeof(uint32_t);
+
+ fadt->flush_size = 0x400; /* twice of cache size */
+ fadt->flush_stride = 0x10; /* Cache line width */
+ fadt->duty_offset = 1;
+ fadt->day_alrm = 0xd;
+
+ fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+ ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
+ ACPI_FADT_RESET_REGISTER | ACPI_FADT_SEALED_CASE |
+ ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
+
+ fadt->reset_reg.space_id = 1;
+ fadt->reset_reg.bit_width = 8;
+ fadt->reset_reg.addrl = RST_CNT;
+ fadt->reset_value = RST_CPU | SYS_RST;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1a_evt_blk.addrl = pmbase + PM1_STS;
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1a_cnt_blk.addrl = pmbase + PM1_CNT;
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+
+ fadt->x_gpe1_blk.space_id = 1;
+
+ soc_fill_fadt(fadt);
+}
+
+unsigned long southbridge_write_acpi_tables(device_t device,
+ unsigned long current,
+ struct acpi_rsdp *rsdp)
+{
+ return acpi_write_hpet(device, current, rsdp);
+}
+
+__attribute__ ((weak))
+uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en,
+ const struct chipset_power_state *ps)
+{
+ return generic_pm1_en;
+}
+
+/*
+ * Save wake source information for calculating ACPI _SWS values
+ *
+ * @pm1: PM1_STS register with only enabled events set
+ * @gpe0: GPE0_STS registers with only enabled events set
+ *
+ * return the number of registers in the gpe0 array or -1 if nothing
+ * is provided by this function.
+ */
+
+static int acpi_fill_wake(uint32_t *pm1, uint32_t **gpe0)
+{
+ struct chipset_power_state *ps;
+ static uint32_t gpe0_sts[GPE0_REG_MAX];
+ uint32_t pm1_en;
+ int i;
+
+ ps = cbmem_find(CBMEM_ID_POWER_STATE);
+ if (ps == NULL)
+ return -1;
+
+ /*
+ * PM1_EN to check the basic wake events which can happen through
+ * powerbtn or any other wake source like lidopen, key board press etc.
+ */
+ pm1_en = ps->pm1_en;
+
+ pm1_en = acpi_fill_soc_wake(pm1_en, ps);
+
+ *pm1 = ps->pm1_sts & pm1_en;
+
+ /* Mask off GPE0 status bits that are not enabled */
+ *gpe0 = &gpe0_sts[0];
+ for (i = 0; i < GPE0_REG_MAX; i++)
+ gpe0_sts[i] = ps->gpe0_sts[i] & ps->gpe0_en[i];
+
+ return GPE0_REG_MAX;
+}
+
+__attribute__ ((weak)) void acpi_create_gnvs(struct global_nvs_t *gnvs)
+{
+}
+
+void southbridge_inject_dsdt(device_t device)
+{
+ struct 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((uintptr_t) gnvs);
+ /* And tell SMI about it */
+ smm_setup_structures(gnvs, NULL, NULL);
+
+ /* Add it to DSDT. */
+ acpigen_write_scope("\\");
+ acpigen_write_name_dword("NVSA", (uintptr_t) gnvs);
+ acpigen_pop_len();
+ }
+}
+
+static int calculate_power(int tdp, int p1_ratio, int ratio)
+{
+ u32 m;
+ u32 power;
+
+ /*
+ * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
+ *
+ * Power = (ratio / p1_ratio) * m * tdp
+ */
+
+ m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
+ m = (m * m) / 1000;
+
+ power = ((ratio * 100000 / p1_ratio) / 100);
+ power *= (m / 100) * (tdp / 1000);
+ power /= 1000;
+
+ return power;
+}
+
+static int get_cores_per_package(void)
+{
+ struct cpuinfo_x86 c;
+ struct cpuid_result result;
+ int cores = 1;
+
+ get_fms(&c, cpuid_eax(1));
+ if (c.x86 != 6)
+ return 1;
+
+ result = cpuid_ext(0xb, 1);
+ cores = result.ebx & 0xff;
+
+ return cores;
+}
+
+static void generate_c_state_entries(void)
+{
+ acpi_cstate_t *c_state_map;
+ size_t entries;
+
+ c_state_map = soc_get_cstate_map(&entries);
+
+ /* Generate C-state tables */
+ acpigen_write_CST_package(c_state_map, entries);
+}
+
+void generate_p_state_entries(int core, int cores_per_package)
+{
+ int ratio_min, ratio_max, ratio_turbo, ratio_step;
+ int coord_type, power_max, num_entries;
+ int ratio, power, clock, clock_max;
+
+ coord_type = cpu_get_coord_type();
+ ratio_min = cpu_get_min_ratio();
+ ratio_max = cpu_get_max_ratio();
+ clock_max = (ratio_max * cpu_get_bus_clock()) / KHz;
+
+ /* Calculate CPU TDP in mW */
+ power_max = cpu_get_power_max();
+
+ /* Write _PCT indicating use of FFixedHW */
+ acpigen_write_empty_PCT();
+
+ /* Write _PPC with no limit on supported P-state */
+ acpigen_write_PPC_NVS();
+ /* Write PSD indicating configured coordination type */
+ acpigen_write_PSD_package(core, 1, coord_type);
+
+ /* Add P-state entries in _PSS table */
+ acpigen_write_name("_PSS");
+
+ /* Determine ratio points */
+ ratio_step = PSS_RATIO_STEP;
+ num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
+ if (num_entries > PSS_MAX_ENTRIES) {
+ ratio_step += 1;
+ num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
+ }
+
+ /* P[T] is Turbo state if enabled */
+ if (get_turbo_state() == TURBO_ENABLED) {
+ /* _PSS package count including Turbo */
+ acpigen_write_package(num_entries + 2);
+ ratio_turbo = cpu_get_max_turbo_ratio();
+
+ /* Add entry for Turbo ratio */
+ acpigen_write_PSS_package(clock_max + 1, /* MHz */
+ power_max, /* mW */
+ PSS_LATENCY_TRANSITION,/* lat1 */
+ PSS_LATENCY_BUSMASTER,/* lat2 */
+ ratio_turbo << 8, /* control */
+ ratio_turbo << 8); /* status */
+ } else {
+ /* _PSS package count without Turbo */
+ acpigen_write_package(num_entries + 1);
+ }
+
+ /* First regular entry is max non-turbo ratio */
+ acpigen_write_PSS_package(clock_max, /* MHz */
+ power_max, /* mW */
+ PSS_LATENCY_TRANSITION,/* lat1 */
+ PSS_LATENCY_BUSMASTER,/* lat2 */
+ ratio_max << 8, /* control */
+ ratio_max << 8); /* status */
+
+ /* Generate the remaining entries */
+ for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
+ ratio >= ratio_min; ratio -= ratio_step) {
+
+ /* Calculate power at this ratio */
+ power = calculate_power(power_max, ratio_max, ratio);
+ clock = (ratio * cpu_get_bus_clock()) / KHz;
+
+ acpigen_write_PSS_package(clock, /* MHz */
+ power, /* mW */
+ PSS_LATENCY_TRANSITION,/* lat1 */
+ PSS_LATENCY_BUSMASTER,/* lat2 */
+ ratio << 8, /* control */
+ ratio << 8); /* status */
+ }
+ /* Fix package length */
+ acpigen_pop_len();
+}
+
+static acpi_tstate_t *soc_get_tss_table(int *entries)
+{
+ *entries = 0;
+ return NULL;
+}
+
+void generate_t_state_entries(int core, int cores_per_package)
+{
+ acpi_tstate_t *soc_tss_table;
+ int entries;
+
+ soc_tss_table = soc_get_tss_table(&entries);
+ if (entries == 0)
+ return;
+
+ /* Indicate SW_ALL coordination for T-states */
+ acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
+
+ /* Indicate FixedHW so OS will use MSR */
+ acpigen_write_empty_PTC();
+
+ /* Set NVS controlled T-state limit */
+ acpigen_write_TPC("\\TLVL");
+
+ /* Write TSS table for MSR access */
+ acpigen_write_TSS_package(entries, soc_tss_table);
+}
+
+__attribute__ ((weak)) void soc_power_states_generation(int core_id,
+ int cores_per_package)
+{
+}
+
+void generate_cpu_entries(device_t device)
+{
+ int core_id, cpu_id, pcontrol_blk = ACPI_BASE_ADDRESS;
+ int plen = 6;
+ int totalcores = dev_count_cpu();
+ int cores_per_package = get_cores_per_package();
+ int numcpus = totalcores / cores_per_package;
+
+ printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
+ numcpus, cores_per_package);
+
+ for (cpu_id = 0; cpu_id < numcpus; cpu_id++) {
+ for (core_id = 0; core_id < cores_per_package; core_id++) {
+ if (core_id > 0) {
+ pcontrol_blk = 0;
+ plen = 0;
+ }
+
+ /* Generate processor \_PR.CPUx */
+ acpigen_write_processor((cpu_id) * cores_per_package +
+ core_id, pcontrol_blk, plen);
+
+ /* Generate C-state tables */
+ generate_c_state_entries();
+
+ /* Soc specific power states generation */
+ soc_power_states_generation(core_id, cores_per_package);
+
+ acpigen_pop_len();
+ }
+ }
+}
+
+#if IS_ENABLED(CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE)
+/* Save wake source data for ACPI _SWS methods in NVS */
+static void acpi_save_wake_source(void *unused)
+{
+ global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+ uint32_t pm1, *gpe0;
+ int gpe_reg, gpe_reg_count;
+ int reg_size = sizeof(uint32_t) * 8;
+
+ if (!gnvs)
+ return;
+
+ gnvs->pm1i = -1;
+ gnvs->gpei = -1;
+
+ gpe_reg_count = acpi_fill_wake(&pm1, &gpe0);
+ if (gpe_reg_count < 0)
+ return;
+
+ /* Scan for first set bit in PM1 */
+ for (gnvs->pm1i = 0; gnvs->pm1i < reg_size; gnvs->pm1i++) {
+ if (pm1 & 1)
+ break;
+ pm1 >>= 1;
+ }
+
+ /* If unable to determine then return -1 */
+ if (gnvs->pm1i >= 16)
+ gnvs->pm1i = -1;
+
+ /* Scan for first set bit in GPE registers */
+ for (gpe_reg = 0; gpe_reg < gpe_reg_count; gpe_reg++) {
+ uint32_t gpe = gpe0[gpe_reg];
+ int start = gpe_reg * reg_size;
+ int end = start + reg_size;
+
+ if (gpe == 0) {
+ if (!gnvs->gpei)
+ gnvs->gpei = end;
+ continue;
+ }
+
+ for (gnvs->gpei = start; gnvs->gpei < end; gnvs->gpei++) {
+ if (gpe & 1)
+ break;
+ gpe >>= 1;
+ }
+ }
+
+ /* If unable to determine then return -1 */
+ if (gnvs->gpei >= gpe_reg_count * reg_size)
+ gnvs->gpei = -1;
+
+ printk(BIOS_DEBUG, "ACPI _SWS is PM1 Index %lld GPE Index %lld\n",
+ (long long)gnvs->pm1i, (long long)gnvs->gpei);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, acpi_save_wake_source, NULL);
+
+#endif
diff --git a/src/soc/intel/common/block/include/intelblocks/acpi.h b/src/soc/intel/common/block/include/intelblocks/acpi.h
new file mode 100644
index 0000000000..010773b52a
--- /dev/null
+++ b/src/soc/intel/common/block/include/intelblocks/acpi.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef SOC_INTEL_COMMON_BLOCK_ACPI_H
+#define SOC_INTEL_COMMON_BLOCK_ACPI_H
+
+#include <arch/acpi.h>
+#include <device/device.h>
+#include <intelblocks/cpulib.h>
+#include <stdint.h>
+
+/* Forward declare the power state struct here */
+struct chipset_power_state;
+
+/* Forward declare the global nvs structure here */
+struct global_nvs_t;
+
+/* Read the scis from soc specific register. Returns int scis value */
+uint32_t soc_read_sci_irq_select(void);
+
+/*
+ * Calls acpi_write_hpet which creates and fills HPET table and
+ * adds it to the RSDT (and XSDT) structure.
+ */
+unsigned long southbridge_write_acpi_tables(device_t device,
+ unsigned long current,
+ struct acpi_rsdp *rsdp);
+
+/*
+ * Craetes acpi gnvs and adds it to the DSDT table.
+ * GNVS creation is chipset specific and is done in soc specific acpi.c file.
+ */
+void southbridge_inject_dsdt(device_t device);
+
+/*
+ * This function populates the gnvs structure in acpi table.
+ * Defined as weak in common acpi as gnvs structure definition is
+ * chipset specific.
+ */
+void acpi_create_gnvs(struct global_nvs_t *gnvs);
+
+/*
+ * get_cstate_map returns a table of processor specific acpi_cstate_t entries
+ * and number of entries in the table
+ */
+acpi_cstate_t *soc_get_cstate_map(size_t *num_entries);
+
+/*
+ * Chipset specific quirks for the wake enable bits.
+ * Returns wake events for the soc.
+ */
+uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en,
+ const struct chipset_power_state *ps);
+
+/* Chipset specific settings for filling up fadt table */
+void soc_fill_fadt(acpi_fadt_t *fadt);
+
+/* Return the polarity flag for SCI IRQ */
+int soc_madt_sci_irq_polarity(int sci);
+
+/* Generate P-state tables */
+void generate_p_state_entries(int core, int cores_per_package);
+
+/* Generate T-state tables */
+void generate_t_state_entries(int core, int cores_per_package);
+
+/*
+ * soc specific power states generation. We need this to be defined by soc
+ * as the state generations varies in chipsets e.g. APL generates T and P
+ * states while SKL generates * P state only depening on a devicetree config
+ */
+void soc_power_states_generation(int core_id, int cores_per_package);
+
+#endif /* _SOC_INTEL_COMMON_BLOCK_ACPI_H_ */
diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c
index 0559d95399..1c4e2ce785 100644
--- a/src/soc/intel/common/block/lpc/lpc.c
+++ b/src/soc/intel/common/block/lpc/lpc.c
@@ -17,8 +17,8 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
+#include <intelblocks/acpi.h>
#include <intelblocks/lpc_lib.h>
-#include <soc/acpi.h>
#include <soc/pm.h>
/* Common weak definition, needs to be implemented in each soc LPC driver. */
diff --git a/src/soc/intel/common/reset.c b/src/soc/intel/common/reset.c
index 06a534ce99..bdd7d9198e 100644
--- a/src/soc/intel/common/reset.c
+++ b/src/soc/intel/common/reset.c
@@ -17,14 +17,9 @@
#include <arch/hlt.h>
#include <arch/io.h>
+#include <cpu/intel/reset.h>
#include <reset.h>
-/* Reset control port */
-#define RST_CNT 0xcf9
-#define FULL_RST (1 << 3)
-#define RST_CPU (1 << 2)
-#define SYS_RST (1 << 1)
-
#if IS_ENABLED(CONFIG_HAVE_HARD_RESET)
void do_hard_reset(void)
{