diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 7cf4a75575..10b42dc992 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -371,6 +372,27 @@ static void configure_c_states(void) wrmsr(MSR_C_STATE_LATENCY_CONTROL_5, msr); } +/* + * The emulated ACPI timer allows disabling of the ACPI timer + * (PM1_TMR) to have no impart on the system. + */ +static void enable_pm_timer_emulation(void) +{ + /* ACPI PM timer emulation */ + msr_t msr; + /* + * The derived frequency is calculated as follows: + * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. + * Back solve the multiplier so the 3.579545MHz ACPI timer + * frequency is used. + */ + msr.hi = (3579545ULL << 32) / CTC_FREQ; + /* Set PM1 timer IO port and enable*/ + msr.lo = (EMULATE_DELAY_VALUE << EMULATE_DELAY_OFFSET_VALUE) | + EMULATE_PM_TMR_EN | (ACPI_BASE_ADDRESS + PM1_TMR); + wrmsr(MSR_EMULATE_PM_TMR, msr); +} + /* All CPUs including BSP will run the following function. */ static void cpu_core_init(device_t cpu) { @@ -390,6 +412,9 @@ static void cpu_core_init(device_t cpu) /* Configure Intel Speed Shift */ configure_isst(); + /* Enable ACPI Timer Emulation via MSR 0x121 */ + enable_pm_timer_emulation(); + /* Enable Direct Cache Access */ configure_dca_cap(); @@ -570,8 +595,6 @@ int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id) (current_patch_id == new_patch_id - 1); } -/* - * Do CPU MP Init before FSP Silicon Init - */ +/* Do CPU MP Init before FSP Silicon Init */ BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, soc_init_cpus, NULL); BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, soc_post_cpus_init, NULL); diff --git a/src/soc/intel/skylake/include/soc/cpu.h b/src/soc/intel/skylake/include/soc/cpu.h index 7bfd8bae2b..6419bf8506 100644 --- a/src/soc/intel/skylake/include/soc/cpu.h +++ b/src/soc/intel/skylake/include/soc/cpu.h @@ -51,6 +51,9 @@ #define C9_POWER 0xc8 #define C10_POWER 0xc8 +/* Common Timer Copy (CTC) frequency - 19.2MHz. */ +#define CTC_FREQ 19200000 + #define C_STATE_LATENCY_MICRO_SECONDS(limit, base) \ (((1 << ((base)*5)) * (limit)) / 1000) #define C_STATE_LATENCY_FROM_LAT_REG(reg) \ diff --git a/src/soc/intel/skylake/include/soc/msr.h b/src/soc/intel/skylake/include/soc/msr.h index 98f25a153e..bb4b8e72ac 100644 --- a/src/soc/intel/skylake/include/soc/msr.h +++ b/src/soc/intel/skylake/include/soc/msr.h @@ -21,6 +21,10 @@ #define MSR_PIC_MSG_CONTROL 0x2e #define MSR_BIOS_UPGD_TRIG 0x7a +#define MSR_EMULATE_PM_TIMER 0x121 +#define EMULATE_PM_TMR_EN (1 << 16) +#define EMULATE_DELAY_OFFSET_VALUE 20 +#define EMULATE_DELAY_VALUE 0x13 #define IA32_THERM_INTERRUPT 0x19b #define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 #define ENERGY_POLICY_PERFORMANCE 0