Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2008-2009 coresystems GmbH |
| 5 | * Copyright (C) 2014 Google Inc. |
| 6 | * Copyright (C) 2015 Intel Corporation. |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; version 2 of the License. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | * GNU General Public License for more details. |
| 16 | */ |
| 17 | |
Duncan Laurie | 4460829 | 2018-11-07 11:36:35 -0700 | [diff] [blame] | 18 | #include <bootstate.h> |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 19 | #include <console/console.h> |
| 20 | #include <cpu/x86/smm.h> |
Shaunak Saha | 83e9823 | 2017-06-22 10:38:30 -0700 | [diff] [blame] | 21 | #include <intelblocks/pmclib.h> |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 22 | #include <intelblocks/smm.h> |
Subrata Banik | 4f62d16 | 2017-08-29 19:04:11 +0530 | [diff] [blame] | 23 | #include <intelblocks/systemagent.h> |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 24 | #include <soc/pm.h> |
| 25 | |
| 26 | void smm_southbridge_clear_state(void) |
| 27 | { |
| 28 | printk(BIOS_DEBUG, "Clearing SMI status registers\n"); |
| 29 | |
Shaunak Saha | 83e9823 | 2017-06-22 10:38:30 -0700 | [diff] [blame] | 30 | if (pmc_get_smi_en() & APMC_EN) { |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 31 | printk(BIOS_INFO, "SMI# handler already enabled?\n"); |
| 32 | return; |
| 33 | } |
| 34 | |
| 35 | /* Dump and clear status registers */ |
Shaunak Saha | 83e9823 | 2017-06-22 10:38:30 -0700 | [diff] [blame] | 36 | pmc_clear_smi_status(); |
| 37 | pmc_clear_pm1_status(); |
| 38 | pmc_clear_tco_status(); |
Furquan Shaikh | c4e652f | 2017-10-11 14:44:29 -0700 | [diff] [blame] | 39 | pmc_clear_all_gpe_status(); |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 40 | } |
| 41 | |
Subrata Banik | 47a655c | 2017-12-14 18:22:13 +0530 | [diff] [blame] | 42 | void smm_southbridge_enable(uint16_t pm1_events) |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 43 | { |
| 44 | printk(BIOS_DEBUG, "Enabling SMIs.\n"); |
| 45 | /* Configure events */ |
Subrata Banik | 47a655c | 2017-12-14 18:22:13 +0530 | [diff] [blame] | 46 | pmc_enable_pm1(pm1_events); |
Furquan Shaikh | c4e652f | 2017-10-11 14:44:29 -0700 | [diff] [blame] | 47 | pmc_disable_std_gpe(PME_B0_EN); |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 48 | |
| 49 | /* |
Furquan Shaikh | a00c777 | 2018-06-26 18:10:07 -0700 | [diff] [blame] | 50 | * GPEs need to be disabled before enabling SMI. Otherwise, it could |
| 51 | * lead to SMIs being triggered in coreboot preventing the progress of |
| 52 | * normal boot-up. This is done as late as possible so that |
| 53 | * pmc_fill_power_state can read the correct state of GPE0_EN* registers |
| 54 | * and not lose information about the wake source. |
| 55 | */ |
| 56 | pmc_disable_all_gpe(); |
| 57 | |
| 58 | /* |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 59 | * Enable SMI generation: |
| 60 | * - on APMC writes (io 0xb2) |
| 61 | * - on writes to SLP_EN (sleep states) |
| 62 | * - on writes to GBL_RLS (bios commands) |
| 63 | * - on eSPI events (does nothing on LPC systems) |
| 64 | * No SMIs: |
| 65 | * - on microcontroller writes (io 0x62/0x66) |
| 66 | * - on TCO events |
| 67 | */ |
| 68 | |
| 69 | /* Enable SMI generation: */ |
Shaunak Saha | 83e9823 | 2017-06-22 10:38:30 -0700 | [diff] [blame] | 70 | pmc_enable_smi(ENABLE_SMI_PARAMS); |
Brandon Breitenstein | a86d1b8 | 2017-06-08 17:32:02 -0700 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | void smm_setup_structures(void *gnvs, void *tcg, void *smi1) |
| 74 | { |
| 75 | /* |
| 76 | * Issue SMI to set the gnvs pointer in SMM. |
| 77 | * tcg and smi1 are unused. |
| 78 | * |
| 79 | * EAX = APM_CNT_GNVS_UPDATE |
| 80 | * EBX = gnvs pointer |
| 81 | * EDX = APM_CNT |
| 82 | */ |
| 83 | asm volatile ( |
| 84 | "outb %%al, %%dx\n\t" |
| 85 | : /* ignore result */ |
| 86 | : "a" (APM_CNT_GNVS_UPDATE), |
| 87 | "b" ((u32)gnvs), |
| 88 | "d" (APM_CNT) |
| 89 | ); |
| 90 | } |
Subrata Banik | 4f62d16 | 2017-08-29 19:04:11 +0530 | [diff] [blame] | 91 | |
| 92 | void smm_region_info(void **start, size_t *size) |
| 93 | { |
| 94 | *start = (void *)sa_get_tseg_base(); |
| 95 | *size = sa_get_tseg_size(); |
| 96 | } |
Duncan Laurie | 4460829 | 2018-11-07 11:36:35 -0700 | [diff] [blame] | 97 | |
Julius Werner | cd49cce | 2019-03-05 16:53:33 -0800 | [diff] [blame^] | 98 | #if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_ESPI_ACPI_DIS) |
Duncan Laurie | 4460829 | 2018-11-07 11:36:35 -0700 | [diff] [blame] | 99 | static void smm_disable_espi(void *dest) |
| 100 | { |
| 101 | pmc_disable_smi(ESPI_SMI_EN); |
| 102 | } |
| 103 | BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, smm_disable_espi, NULL); |
| 104 | #endif |