Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/25526
Change subject: soc/amd/stoneyridege: Create AP jump structure ......................................................................
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 richard.spiegel@silverbackltd.com --- M src/soc/amd/stoneyridge/bootblock/bootblock.c M src/soc/amd/stoneyridge/include/soc/northbridge.h M src/soc/amd/stoneyridge/romstage.c 3 files changed, 62 insertions(+), 14 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/26/25526/1
diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c index fafaf07..8f1ac5d 100644 --- a/src/soc/amd/stoneyridge/bootblock/bootblock.c +++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c @@ -30,19 +30,11 @@ #include <amdblocks/psp.h> #include <timestamp.h>
-asmlinkage void bootblock_c_entry(uint64_t base_timestamp) +static uintptr_t get_ap_ptr(void) { - /* - * 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()); + /* Use the first IOAPIC scratch register */ + pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, NB_IOAPIC_SCRATCH0); + return pci_read_config32(SOC_GNB_DEV, NB_IOAPIC_DATA); }
/* Set the MMIO Configuration Base Address and Bus Range. */ @@ -65,10 +57,43 @@ set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT); }
-void bootblock_soc_early_init(void) +asmlinkage void bootblock_c_entry(uint64_t base_timestamp) { amd_initmmio(); + /* + * Call lib/bootblock.c main with BSP, shortcut for APs + */ + if (!boot_cpu()) { + /* + * Before AGESA is moved to romstage, AP cores will + * reach this code before BSP can set the jump address, + * so ap_romstage_entry will be NULL. + */ + void (*ap_romstage_entry)(void) = (void (*)(void))get_ap_ptr();
+ /* + * TODO: Once AGESA calls are moved to romstage, remove + * this section of code. + */ + if (ap_romstage_entry == NULL) + bootblock_soc_early_init(); /* APs will not return */ + + printk(BIOS_DEBUG, "AP calling directly to romstage @%p\n", + ap_romstage_entry); + ap_romstage_entry(); /* execution does not return */ + } + + /* TSC cannot be relied upon. Override the TSC value passed in. */ + bootblock_main_with_timestamp(timestamp_get()); +} + +void bootblock_soc_early_init(void) +{ + /* + * TODO: Once AGESA calls are moved to romstage, remove the + * if and bootblock_soc_init() as APs will never execute + * bootblock_soc_early_init(). + */ if (!boot_cpu()) bootblock_soc_init(); /* APs will not return */
@@ -117,6 +142,10 @@ u32 val = cpuid_eax(1); printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
+ /* + * TODO: Once AGESA calls are moved to romstage, remove boot_cpu() + * from the if as APs will never execute bootblock_soc_init(). + */ if (boot_cpu() && IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW)) load_smu_fw1();
diff --git a/src/soc/amd/stoneyridge/include/soc/northbridge.h b/src/soc/amd/stoneyridge/include/soc/northbridge.h index d649ada..6e42b39 100644 --- a/src/soc/amd/stoneyridge/include/soc/northbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/northbridge.h @@ -27,6 +27,13 @@ #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_ADDRESS 0x01 +#define NB_IOAPIC_SCRATCH0 0x3e +#define NB_IOAPIC_SCRATCH1 0x3f + /* D18F1 - Address Map Registers */
/* MMIO base and limit */ diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c index 490fd9e..7911079 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 <arch/io.h> #include <arch/cpu.h> #include <arch/acpi.h> #include <cpu/x86/msr.h> @@ -31,6 +32,14 @@ #include <soc/northbridge.h> #include <soc/southbridge.h> #include <amdblocks/psp.h> +#include <smp/node.h> + +static void set_ap_ptr(void *entry) +{ + /* Use the first IOAPIC scratch register */ + pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, NB_IOAPIC_SCRATCH0); + pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_DATA, (u32)entry); +}
asmlinkage void car_stage_entry(void) { @@ -45,7 +54,10 @@ int s3_resume = acpi_s3_resume_allowed() && acpi_is_wakeup_s3(); int i;
- console_init(); + if (boot_cpu()) { + console_init(); + set_ap_ptr(car_stage_entry); + }
if (!s3_resume) { post_code(0x40);