From 6d61db0d2cec4a3b141da77bcf5675b8b154c8b7 Mon Sep 17 00:00:00 2001 From: Richard Spiegel Date: Wed, 4 Apr 2018 10:35:21 -0700 Subject: soc/amd/stoneyridege: Create AP jump structure As part of moving AGESA calls from bootblock to romstage, create infrastructure to pass a pointer to the AP cores, so they can jump directly to romstage. BUG=b:74236170 TEST=Build and boot grunt, actual test will be performed at a later patch. Change-Id: If716d1c1970746f2ad90ef71ae9062c99f219897 Signed-off-by: Richard Spiegel Reviewed-on: https://review.coreboot.org/25526 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/amd/stoneyridge/Makefile.inc | 7 ++- src/soc/amd/stoneyridge/bootblock/bootblock.c | 66 ++++++++++++++--------- src/soc/amd/stoneyridge/include/soc/northbridge.h | 24 +++++++++ src/soc/amd/stoneyridge/nb_util.c | 39 ++++++++++++++ src/soc/amd/stoneyridge/romstage.c | 6 +++ 5 files changed, 115 insertions(+), 27 deletions(-) create mode 100644 src/soc/amd/stoneyridge/nb_util.c (limited to 'src/soc/amd') diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc index 61704eaca6..31dc439397 100644 --- a/src/soc/amd/stoneyridge/Makefile.inc +++ b/src/soc/amd/stoneyridge/Makefile.inc @@ -48,7 +48,7 @@ bootblock-y += reset.c bootblock-y += sb_util.c bootblock-y += tsc_freq.c bootblock-y += southbridge.c -bootblock-y += sb_util.c +bootblock-y += nb_util.c romstage-y += BiosCallOuts.c romstage-y += i2c.c @@ -66,6 +66,7 @@ romstage-y += ramtop.c romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c romstage-y += tsc_freq.c romstage-y += southbridge.c +romstage-y += nb_util.c verstage-y += gpio.c verstage-y += i2c.c @@ -75,11 +76,13 @@ verstage-y += pmutil.c verstage-y += reset.c verstage-$(CONFIG_STONEYRIDGE_UART) += uart.c verstage-y += tsc_freq.c +verstage-y += nb_util.c postcar-y += monotonic_timer.c postcar-$(CONFIG_STONEYRIDGE_UART) += uart.c postcar-y += ramtop.c postcar-y += sb_util.c +postcar-y += nb_util.c ramstage-y += BiosCallOuts.c ramstage-y += i2c.c @@ -108,6 +111,7 @@ ramstage-y += usb.c ramstage-y += tsc_freq.c ramstage-$(CONFIG_SPI_FLASH) += spi.c ramstage-y += finalize.c +ramstage-y += nb_util.c smm-y += monotonic_timer.c smm-y += smihandler.c @@ -116,6 +120,7 @@ smm-y += sb_util.c smm-y += tsc_freq.c smm-$(CONFIG_DEBUG_SMI) += uart.c smm-$(CONFIG_SPI_FLASH) += spi.c +smm-y += nb_util.c CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge/include diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c index db5c9b62b9..6ee2095b23 100644 --- a/src/soc/amd/stoneyridge/bootblock/bootblock.c +++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c @@ -30,21 +30,7 @@ #include #include #include - -asmlinkage void bootblock_c_entry(uint64_t base_timestamp) -{ - /* - * Call lib/bootblock.c main with BSP, shortcut for APs - * todo: rearchitect AGESA entry points to remove need - * to run amdinitreset, amdinitearly from bootblock. - * Remove AP shortcut. - */ - if (!boot_cpu()) - bootblock_soc_early_init(); /* APs will not return */ - - /* TSC cannot be relied upon. Override the TSC value passed in. */ - bootblock_main_with_timestamp(timestamp_get()); -} +#include /* Set the MMIO Configuration Base Address and Bus Range. */ static void amd_initmmio(void) @@ -66,15 +52,48 @@ static void amd_initmmio(void) set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT); } -void bootblock_soc_early_init(void) +/* + * To move AGESA calls to romstage, just move agesa_call() and bsp_agesa_call() + * to romstage.c. Also move the call to bsp_agesa_call() to the marked location + * in romstage.c. + */ +static void agesa_call(void) +{ + post_code(0x37); + do_agesawrapper(agesawrapper_amdinitreset, "amdinitreset"); + + post_code(0x38); + /* APs will not exit amdinitearly */ + do_agesawrapper(agesawrapper_amdinitearly, "amdinitearly"); +} + +static void bsp_agesa_call(void) +{ + set_ap_entry_ptr(agesa_call); /* indicate the path to the AP */ + agesa_call(); +} + +asmlinkage void bootblock_c_entry(uint64_t base_timestamp) { amd_initmmio(); + /* + * Call lib/bootblock.c main with BSP, shortcut for APs + */ + if (!boot_cpu()) { + void (*ap_romstage_entry)(void) = + (void (*)(void))get_ap_entry_ptr(); - if (!boot_cpu()) - bootblock_soc_init(); /* APs will not return */ + ap_romstage_entry(); /* execution does not return */ + halt(); + } - bootblock_fch_early_init(); + /* TSC cannot be relied upon. Override the TSC value passed in. */ + bootblock_main_with_timestamp(timestamp_get()); +} +void bootblock_soc_early_init(void) +{ + bootblock_fch_early_init(); post_code(0x90); } @@ -118,15 +137,10 @@ void bootblock_soc_init(void) u32 val = cpuid_eax(1); printk(BIOS_DEBUG, "Family_Model: %08x\n", val); - if (boot_cpu() && IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW)) + if (IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW)) load_smu_fw1(); - post_code(0x37); - do_agesawrapper(agesawrapper_amdinitreset, "amdinitreset"); - - post_code(0x38); - /* APs will not exit amdinitearly */ - do_agesawrapper(agesawrapper_amdinitearly, "amdinitearly"); + bsp_agesa_call(); /* Initialize any early i2c buses. */ i2c_soc_early_init(); diff --git a/src/soc/amd/stoneyridge/include/soc/northbridge.h b/src/soc/amd/stoneyridge/include/soc/northbridge.h index d649ada241..92bce98780 100644 --- a/src/soc/amd/stoneyridge/include/soc/northbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/northbridge.h @@ -27,6 +27,26 @@ #define HT_INIT_CONTROL 0x6c # define HTIC_BIOSR_DETECT ((1 << 5) | (1 << 9) | (1 << 10)) +/* NB IOAPIC registers */ +#define NB_IOAPIC_INDEX 0xf8 +#define NB_IOAPIC_DATA 0xfc +#define NB_IOAPIC_FEATURE_CTRL 0x00 +#define NB_IOAPIC_ADDRESS_LOW 0x01 +#define NB_IOAPIC_ADDRESS_HIGH 0x02 +#define NB_IOAPIC_GBIF_IRR 0x0f +#define NB_IOAPIC_BR0_IRR 0x10 +#define NB_IOAPIC_BR1_IRR 0x11 +#define NB_IOAPIC_BR2_IRR 0x12 +#define NB_IOAPIC_BR3_IRR 0x13 +#define NB_IOAPIC_BR4_IRR 0x14 +#define NB_IOAPIC_APG_IRR 0x2f +#define NB_IOAPIC_SPG_IRR 0x30 +#define NB_IOAPIC_SER_IRQ_IRR 0x31 +#define NB_IOAPIC_SCRATCH0 0x3e +#define NB_IOAPIC_SCRATCH1 0x3f + +#define AP_SCRATCH_REG NB_IOAPIC_SCRATCH0 + /* D18F1 - Address Map Registers */ /* MMIO base and limit */ @@ -88,5 +108,9 @@ void domain_read_resources(device_t dev); void domain_set_resources(device_t dev); void fam15_finalize(void *chip_info); void setup_uma_memory(void); +uint32_t nb_ioapic_read(unsigned int index); +void nb_ioapic_write(unsigned int index, uint32_t value); +void *get_ap_entry_ptr(void); +void set_ap_entry_ptr(void *entry); #endif /* __PI_STONEYRIDGE_NORTHBRIDGE_H__ */ diff --git a/src/soc/amd/stoneyridge/nb_util.c b/src/soc/amd/stoneyridge/nb_util.c new file mode 100644 index 0000000000..4d3e53faf3 --- /dev/null +++ b/src/soc/amd/stoneyridge/nb_util.c @@ -0,0 +1,39 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Advanced Micro Devices + * + * 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 + +uint32_t nb_ioapic_read(unsigned int index) +{ + pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, index); + return pci_read_config32(SOC_GNB_DEV, NB_IOAPIC_DATA); +} + +void nb_ioapic_write(unsigned int index, uint32_t value) +{ + pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, index); + pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_DATA, value); +} + +void *get_ap_entry_ptr(void) +{ + return (void *)nb_ioapic_read(AP_SCRATCH_REG); +} + +void set_ap_entry_ptr(void *entry) +{ + nb_ioapic_write(AP_SCRATCH_REG, (uintptr_t)entry); +} diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c index 490fd9ee9c..cb24756baa 100644 --- a/src/soc/amd/stoneyridge/romstage.c +++ b/src/soc/amd/stoneyridge/romstage.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -45,6 +46,11 @@ asmlinkage void car_stage_entry(void) int s3_resume = acpi_s3_resume_allowed() && acpi_is_wakeup_s3(); int i; + /* + * When moving AGESA calls to romstage, place the call to + * bsp_agesa_call() here. + */ + console_init(); if (!s3_resume) { -- cgit v1.2.3