Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
soc/amd/genoa: Hook SMP and SMM init
All CPUs properly come out of reset and relocate SMM. Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Change-Id: I8c2d976addacd5a2ba70eb629510128853b9f847 Reviewed-on: https://review.coreboot.org/c/coreboot/+/76523 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
- Loading branch information
1 parent
2edcd93
commit 2e2f166
Showing
6 changed files
with
142 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
|
||
#include <amdblocks/cpu.h> | ||
#include <cpu/cpu.h> | ||
#include <device/device.h> | ||
#include <soc/cpu.h> | ||
|
||
static void model_19_init(struct device *dev) | ||
{ | ||
set_cstate_io_addr(); | ||
} | ||
|
||
static struct device_operations cpu_dev_ops = { | ||
.init = model_19_init, | ||
}; | ||
|
||
static struct cpu_device_id cpu_table[] = { | ||
{ X86_VENDOR_AMD, GENOA_A0_CPUID, CPUID_ALL_STEPPINGS_MASK }, | ||
{ X86_VENDOR_AMD, GENOA_B0_CPUID, CPUID_ALL_STEPPINGS_MASK }, | ||
CPU_TABLE_END | ||
}; | ||
|
||
static const struct cpu_driver model_19 __cpu_driver = { | ||
.ops = &cpu_dev_ops, | ||
.id_table = cpu_table, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
|
||
#ifndef AMD_GENOA_CPU_H | ||
#define AMD_GENOA_CPU_H | ||
|
||
#define GENOA_A0_CPUID CPUID_FROM_FMS(0x19, 0x10, 0) | ||
#define GENOA_B0_CPUID CPUID_FROM_FMS(0x19, 0x11, 0) | ||
|
||
#endif /* AMD_GENOA_CPU_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
|
||
#include <acpi/acpi.h> | ||
#include <amdblocks/acpi.h> | ||
#include <amdblocks/acpimmio.h> | ||
#include <amdblocks/psp.h> | ||
#include <amdblocks/smi.h> | ||
#include <amdblocks/smm.h> | ||
#include <arch/hlt.h> | ||
#include <arch/io.h> | ||
#include <console/console.h> | ||
#include <cpu/x86/cache.h> | ||
#include <cpu/x86/smm.h> | ||
#include <elog.h> | ||
#include <soc/smi.h> | ||
#include <soc/smu.h> | ||
#include <soc/southbridge.h> | ||
#include <types.h> | ||
|
||
/* | ||
* Both the psp_notify_sx_info and the smu_sx_entry call will clobber the SMN index register | ||
* during the SMN accesses. Since the SMI handler is the last thing that gets called before | ||
* entering S3, this won't interfere with any indirect SMN accesses via the same register pair. | ||
*/ | ||
static void fch_slp_typ_handler(void) | ||
{ | ||
uint32_t pci_ctrl; | ||
uint16_t pm1cnt; | ||
uint8_t slp_typ, rst_ctrl; | ||
|
||
/* Figure out SLP_TYP */ | ||
pm1cnt = acpi_read16(MMIO_ACPI_PM1_CNT_BLK); | ||
printk(BIOS_SPEW, "SMI#: SLP = 0x%04x\n", pm1cnt); | ||
slp_typ = acpi_sleep_from_pm1(pm1cnt); | ||
|
||
/* Do any mainboard sleep handling */ | ||
mainboard_smi_sleep(slp_typ); | ||
|
||
switch (slp_typ) { | ||
case ACPI_S0: | ||
printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); | ||
break; | ||
case ACPI_S3: | ||
printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n"); | ||
break; | ||
case ACPI_S4: | ||
printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); | ||
break; | ||
case ACPI_S5: | ||
printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n"); | ||
break; | ||
default: | ||
printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); | ||
break; | ||
} | ||
|
||
if (slp_typ >= ACPI_S3) { | ||
wbinvd(); | ||
|
||
clear_all_smi_status(); | ||
|
||
/* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */ | ||
pci_ctrl = pm_read32(PM_PCI_CTRL); | ||
pci_ctrl &= ~FORCE_SLPSTATE_RETRY; | ||
pm_write32(PM_PCI_CTRL, pci_ctrl); | ||
|
||
/* Enable SlpTyp */ | ||
rst_ctrl = pm_read8(PM_RST_CTRL1); | ||
rst_ctrl |= SLPTYPE_CONTROL_EN; | ||
pm_write8(PM_RST_CTRL1, rst_ctrl); | ||
|
||
smu_sx_entry(); /* Leave SlpTypeEn clear, SMU will set */ | ||
printk(BIOS_ERR, "System did not go to sleep\n"); | ||
hlt(); | ||
} | ||
} | ||
|
||
/* | ||
* Table of functions supported in the SMI handler. Note that SMI source setup | ||
* in fch.c is unrelated to this list. | ||
*/ | ||
static const struct smi_sources_t smi_sources[] = { | ||
{ .type = SMITYPE_SMI_CMD_PORT, .handler = fch_apmc_smi_handler }, | ||
{ .type = SMITYPE_SLP_TYP, .handler = fch_slp_typ_handler}, | ||
}; | ||
|
||
void *get_smi_source_handler(int source) | ||
{ | ||
size_t i; | ||
|
||
for (i = 0 ; i < ARRAY_SIZE(smi_sources) ; i++) | ||
if (smi_sources[i].type == source) | ||
return smi_sources[i].handler; | ||
|
||
return NULL; | ||
} |