Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/79823?usp=email )
Change subject: [WIP,UNTESTED]Add 64bit support to Intel Alderlake ......................................................................
[WIP,UNTESTED]Add 64bit support to Intel Alderlake
With FSP being 32bit and expecting 32bit PPI we need some 32/64bit dance to hook up coreboot MP services.
Signed-off-by: Arthur Heymans arthur@aheymans.xyz Change-Id: Ib5cce9503b5b12d6f0d9b44720ac94006ed16602 --- M src/cpu/x86/64bit/mode_switch2.S M src/cpu/x86/64bit/prot2long.inc M src/drivers/intel/fsp2_0/Makefile.inc A src/drivers/intel/fsp2_0/fsp_debug_event_as.S M src/drivers/intel/fsp2_0/ppi/Makefile.inc A src/drivers/intel/fsp2_0/ppi/mp_service1_as.S M src/drivers/intel/fsp2_0/ppi/mp_service2.c A src/drivers/intel/fsp2_0/ppi/mp_service2_as.S M src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c M src/northbridge/intel/sandybridge/raminit_common.c M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/fsp_params.c M src/soc/intel/alderlake/romstage/fsp_params.c 13 files changed, 192 insertions(+), 27 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/23/79823/1
diff --git a/src/cpu/x86/64bit/mode_switch2.S b/src/cpu/x86/64bit/mode_switch2.S index 65e9d94..bb9781e 100644 --- a/src/cpu/x86/64bit/mode_switch2.S +++ b/src/cpu/x86/64bit/mode_switch2.S @@ -6,9 +6,9 @@
.text .code32 - .section ".text.long_mode_call_3arg", "ax", @progbits - .global long_mode_call_3arg -long_mode_call_3arg: + .section ".text.long_mode_call_5arg", "ax", @progbits + .global long_mode_call_5arg +long_mode_call_5arg:
/* Function to call is passed in EAX. */
@@ -29,6 +29,8 @@ movl 36(%rbp), %edi /* 1st arg */ movl 40(%rbp), %esi /* 2nd arg */ movl 44(%rbp), %edx /* 3rd arg */ + movl 48(%rbp), %edx /* 4rd arg */ + movl 52(%rbp), %edx /* 5rd arg */
call *%rbx
diff --git a/src/cpu/x86/64bit/prot2long.inc b/src/cpu/x86/64bit/prot2long.inc index 96c44a86..d9ce9d5 100644 --- a/src/cpu/x86/64bit/prot2long.inc +++ b/src/cpu/x86/64bit/prot2long.inc @@ -21,7 +21,7 @@ * Jump to function instead of call. * It will return directly to caller. */ - jmp long_mode_call_3arg + jmp long_mode_call_5arg
/* Not reachable */ .endm diff --git a/src/drivers/intel/fsp2_0/Makefile.inc b/src/drivers/intel/fsp2_0/Makefile.inc index 5463405..968af27 100644 --- a/src/drivers/intel/fsp2_0/Makefile.inc +++ b/src/drivers/intel/fsp2_0/Makefile.inc @@ -5,7 +5,7 @@ bootblock-$(CONFIG_FSP_CAR) += fspt_report.c
romstage-y += debug.c -romstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c +romstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c fsp_debug_event_as.S romstage-y += hand_off_block.c romstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c romstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c @@ -19,7 +19,7 @@ romstage-$(CONFIG_CACHE_MRC_SETTINGS) += save_mrc_data.c
ramstage-y += debug.c -ramstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c +ramstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c fsp_debug_event_as.S ramstage-$(CONFIG_USE_INTEL_FSP_MP_INIT) += fsp_mpinit.c ramstage-$(CONFIG_DISPLAY_FSP_TIMESTAMPS) += fsp_timestamp.c ramstage-$(CONFIG_RUN_FSP_GOP) += graphics.c diff --git a/src/drivers/intel/fsp2_0/fsp_debug_event_as.S b/src/drivers/intel/fsp2_0/fsp_debug_event_as.S new file mode 100644 index 0000000..fd07b83 --- /dev/null +++ b/src/drivers/intel/fsp2_0/fsp_debug_event_as.S @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +.code32 +.text + +#if ENV_X86_64 && CONFIG(PLATFORM_USES_FSP2_X86_32) + +#include <cpu/x86/64bit/prot2long.inc> + +prot2lm_wrapper fsp_debug_event_handler + +#endif diff --git a/src/drivers/intel/fsp2_0/ppi/Makefile.inc b/src/drivers/intel/fsp2_0/ppi/Makefile.inc index 823718b..774012a 100644 --- a/src/drivers/intel/fsp2_0/ppi/Makefile.inc +++ b/src/drivers/intel/fsp2_0/ppi/Makefile.inc @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only
ramstage-$(CONFIG_MP_SERVICES_PPI) += mp_service_ppi.c -ramstage-$(CONFIG_MP_SERVICES_PPI_V1) += mp_service1.c -ramstage-$(CONFIG_MP_SERVICES_PPI_V2) += mp_service2.c +ramstage-$(CONFIG_MP_SERVICES_PPI_V1) += mp_service1.c mp_service1_as.S +ramstage-$(CONFIG_MP_SERVICES_PPI_V2) += mp_service2.c mp_service2_as.S ramstage-$(CONFIG_MP_SERVICES_PPI_V2_NOOP) += mp_service2_noop.c diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service1_as.S b/src/drivers/intel/fsp2_0/ppi/mp_service1_as.S new file mode 100644 index 0000000..523c1b6 --- /dev/null +++ b/src/drivers/intel/fsp2_0/ppi/mp_service1_as.S @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +.text +.code32 + +#if ENV_X86_64 && CONFIG(PLATFORM_USES_FSP2_X86_32) + +#include <src/cpu/x86/64bit/prot2long.inc> + +prot2lm_wrapper mps1_get_number_of_processors +prot2lm_wrapper mps1_get_processor_info +prot2lm_wrapper mps1_startup_all_aps +prot2lm_wrapper mps1_startup_this_ap +prot2lm_wrapper mps1_switch_bsp +prot2lm_wrapper mps1_enable_disable_ap +prot2lm_wrapper mps1_identify_processor + +#endif diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service2.c b/src/drivers/intel/fsp2_0/ppi/mp_service2.c index fd91b46..8fde017 100644 --- a/src/drivers/intel/fsp2_0/ppi/mp_service2.c +++ b/src/drivers/intel/fsp2_0/ppi/mp_service2.c @@ -6,7 +6,11 @@
typedef EDKII_PEI_MP_SERVICES2_PPI efi_pei_mp_services_ppi;
-static efi_return_status_t mps2_get_number_of_processors( +efi_return_status_t mps2_get_number_of_processors( + efi_pei_mp_services_ppi *ignored1, + efi_uintn_t *number_of_processors, + efi_uintn_t *number_of_enabled_processors); +efi_return_status_t mps2_get_number_of_processors( efi_pei_mp_services_ppi *ignored1, efi_uintn_t *number_of_processors, efi_uintn_t *number_of_enabled_processors) @@ -14,7 +18,11 @@ return mp_get_number_of_processors(number_of_processors, number_of_enabled_processors); }
-static efi_return_status_t mps2_get_processor_info( +efi_return_status_t mps2_get_processor_info( + efi_pei_mp_services_ppi *ignored1, + efi_uintn_t processor_number, + efi_processor_information *processor_info_buffer); +efi_return_status_t mps2_get_processor_info( efi_pei_mp_services_ppi *ignored1, efi_uintn_t processor_number, efi_processor_information *processor_info_buffer) @@ -22,7 +30,11 @@ return mp_get_processor_info(processor_number, processor_info_buffer); }
-static efi_return_status_t mps2_startup_all_aps( +efi_return_status_t mps2_startup_all_aps( + efi_pei_mp_services_ppi *ignored1, + efi_ap_procedure procedure, efi_boolean_t run_serial, + efi_uintn_t timeout_usec, void *argument); +efi_return_status_t mps2_startup_all_aps( efi_pei_mp_services_ppi *ignored1, efi_ap_procedure procedure, efi_boolean_t run_serial, efi_uintn_t timeout_usec, void *argument) @@ -30,7 +42,11 @@ return mp_startup_all_aps(procedure, run_serial, timeout_usec, argument); }
-static efi_return_status_t mps2_startup_all_cpus( +efi_return_status_t mps2_startup_all_cpus( + efi_pei_mp_services_ppi *ignored1, + efi_ap_procedure procedure, + efi_uintn_t timeout_usec, void *argument); +efi_return_status_t mps2_startup_all_cpus( efi_pei_mp_services_ppi *ignored1, efi_ap_procedure procedure, efi_uintn_t timeout_usec, void *argument) @@ -38,7 +54,11 @@ return mp_startup_all_cpus(procedure, timeout_usec, argument); }
-static efi_return_status_t mps2_startup_this_ap( +efi_return_status_t mps2_startup_this_ap( + efi_pei_mp_services_ppi *ignored1, + efi_ap_procedure procedure, efi_uintn_t processor_number, + efi_uintn_t timeout_usec, void *argument); +efi_return_status_t mps2_startup_this_ap( efi_pei_mp_services_ppi *ignored1, efi_ap_procedure procedure, efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument) @@ -46,21 +66,30 @@ return mp_startup_this_ap(procedure, processor_number, timeout_usec, argument); }
-static efi_return_status_t mps2_switch_bsp( +efi_return_status_t mps2_switch_bsp( + efi_pei_mp_services_ppi *ignored1, efi_uintn_t ignored2, + efi_boolean_t ignored3); +efi_return_status_t mps2_switch_bsp( efi_pei_mp_services_ppi *ignored1, efi_uintn_t ignored2, efi_boolean_t ignored3) { return mp_api_unsupported(); }
-static efi_return_status_t mps2_enable_disable_ap( +efi_return_status_t mps2_enable_disable_ap( + efi_pei_mp_services_ppi *ignored1, + efi_uintn_t ignored2, efi_boolean_t ignored3, efi_uint32_t *ignored4); +efi_return_status_t mps2_enable_disable_ap( efi_pei_mp_services_ppi *ignored1, efi_uintn_t ignored2, efi_boolean_t ignored3, efi_uint32_t *ignored4) { return mp_api_unsupported(); }
-static efi_return_status_t mps2_identify_processor( +efi_return_status_t mps2_identify_processor( + efi_pei_mp_services_ppi *ignored1, + efi_uintn_t *processor_number); +efi_return_status_t mps2_identify_processor( efi_pei_mp_services_ppi *ignored1, efi_uintn_t *processor_number) { @@ -68,8 +97,42 @@ }
/* edk2 UEFIPKG Open Source MP Services 2 PPI to be installed */ +#if ENV_X86_64 && CONFIG(PLATFORM_USES_FSP2_X86_32) +efi_return_status_t __prot2lm_mps2_get_number_of_processors(efi_pei_mp_services_ppi *ignored1, + efi_uintn_t *number_of_processors, + efi_uintn_t *number_of_enabled_processors); +efi_return_status_t __prot2lm_mps2_get_processor_info(efi_pei_mp_services_ppi *ignored1, + efi_uintn_t processor_number, + efi_processor_information *processor_info_buffer); +efi_return_status_t __prot2lm_mps2_startup_all_aps(efi_pei_mp_services_ppi *ignored1, + efi_ap_procedure procedure, efi_boolean_t run_serial, + efi_uintn_t timeout_usec, void *argument); +efi_return_status_t __prot2lm_mps2_startup_this_ap(efi_pei_mp_services_ppi *ignored1, + efi_ap_procedure procedure, efi_uintn_t processor_number, + efi_uintn_t timeout_usec, void *argument); +efi_return_status_t __prot2lm_mps2_switch_bsp(efi_pei_mp_services_ppi *ignored1, efi_uintn_t ignored2, + efi_boolean_t ignored3); +efi_return_status_t __prot2lm_mps2_enable_disable_ap(efi_pei_mp_services_ppi *ignored1, + efi_uintn_t ignored2, efi_boolean_t ignored3, + efi_uint32_t *ignored4); +efi_return_status_t __prot2lm_mps2_identify_processor(efi_pei_mp_services_ppi *ignored1, + efi_uintn_t *processor_number); +efi_return_status_t __prot2lm_mps2_startup_all_cpus(efi_pei_mp_services_ppi *ignored1, + efi_ap_procedure procedure, + efi_uintn_t timeout_usec, void *argument);
static efi_pei_mp_services_ppi mp_service2_ppi = { + __prot2lm_mps2_get_number_of_processors, + __prot2lm_mps2_get_processor_info, + __prot2lm_mps2_startup_all_aps, + __prot2lm_mps2_startup_this_ap, + __prot2lm_mps2_switch_bsp, + __prot2lm_mps2_enable_disable_ap, + __prot2lm_mps2_identify_processor, + __prot2lm_mps2_startup_all_cpus, +}; +#else +static efi_pei_mp_services_ppi mp_service2_ppi = { mps2_get_number_of_processors, mps2_get_processor_info, mps2_startup_all_aps, @@ -79,6 +142,7 @@ mps2_identify_processor, mps2_startup_all_cpus, }; +#endif
void *mp_fill_ppi_services_data(void) { diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service2_as.S b/src/drivers/intel/fsp2_0/ppi/mp_service2_as.S new file mode 100644 index 0000000..6caf791 --- /dev/null +++ b/src/drivers/intel/fsp2_0/ppi/mp_service2_as.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +.text +.code32 + +#if ENV_X86_64 && CONFIG(PLATFORM_USES_FSP2_X86_32) + +#include <cpu/x86/64bit/prot2long.inc> + +prot2lm_wrapper mps2_get_number_of_processors +prot2lm_wrapper mps2_get_processor_info +prot2lm_wrapper mps2_startup_all_aps +prot2lm_wrapper mps2_startup_this_ap +prot2lm_wrapper mps2_switch_bsp +prot2lm_wrapper mps2_enable_disable_ap +prot2lm_wrapper mps2_identify_processor +prot2lm_wrapper mps2_startup_all_cpus + +#endif diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c index a891ba0..0431e92 100644 --- a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c +++ b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c @@ -8,6 +8,7 @@ #include <fsp/ppi/mp_service_ppi.h> #include <intelblocks/cpulib.h> #include <intelblocks/mp_init.h> +#include <mode_switch.h> #include <types.h>
#define BSP_CPU_SLOT 0 @@ -55,6 +56,16 @@ return FSP_SUCCESS; }
+struct function_call_wrapper { + void *procedure; + void *argument; +}; + +static void protected_mode_wrapper_call(struct function_call_wrapper *arg) +{ + protected_mode_call_1arg(arg->procedure, (uint32_t)(uintptr_t)arg->argument); +} + efi_return_status_t mp_startup_all_aps(efi_ap_procedure procedure, bool run_serial, efi_uintn_t timeout_usec, void *argument) { @@ -64,7 +75,12 @@ if (procedure == NULL) return FSP_INVALID_PARAMETER;
- if (mp_run_on_all_aps((void *)procedure, argument, timeout_usec, !run_serial) != + struct function_call_wrapper arg = { + .procedure = (void *)procedure, + .argument = argument, + }; + + if (mp_run_on_all_aps((void *)protected_mode_wrapper_call, &arg, timeout_usec, !run_serial) != CB_SUCCESS) { printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__); return FSP_NOT_STARTED; @@ -82,8 +98,13 @@ if (procedure == NULL) return FSP_INVALID_PARAMETER;
+ struct function_call_wrapper arg = { + .procedure = (void *)procedure, + .argument = argument, + }; + /* Run on BSP */ - procedure(argument); + protected_mode_wrapper_call(&arg);
/* * Run on APs Serially @@ -99,7 +120,7 @@ * due to lack of acquiring a spin lock while accessing common data structure in * multiprocessor environment. */ - if (mp_run_on_all_aps((void *)procedure, argument, timeout_usec, false) != + if (mp_run_on_all_aps((void *)protected_mode_wrapper_call, &arg, timeout_usec, false) != CB_SUCCESS) { printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__); return FSP_NOT_STARTED; @@ -123,7 +144,12 @@ if (procedure == NULL) return FSP_INVALID_PARAMETER;
- if (mp_run_on_aps((void *)procedure, argument, + struct function_call_wrapper arg = { + .procedure = (void *)procedure, + .argument = argument, + }; + + if (mp_run_on_aps((void *)protected_mode_wrapper_call, &arg, processor_number, timeout_usec) != CB_SUCCESS) { printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__); return FSP_NOT_STARTED; diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index c2a3051..1b174d4 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -676,7 +676,7 @@ return PDM_PPD;
if (CONFIG(RAMINIT_ALWAYS_ALLOW_DLL_OFF) || get_platform_type() == PLATFORM_MOBILE) - return PDM_DLL_OFF; + return PDM_APD_DLL_OFF;
return PDM_APD_PPD; } diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index fd95f9e..44dd070 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -1,5 +1,6 @@ config SOC_INTEL_ALDERLAKE bool + select HAVE_EXP_X86_64_SUPPORT select ACPI_INTEL_HARDWARE_SLEEP_VALUES select ARCH_X86 select BOOT_DEVICE_SUPPORTS_WRITES diff --git a/src/soc/intel/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c index 5edfbcc..57a9de0 100644 --- a/src/soc/intel/alderlake/fsp_params.c +++ b/src/soc/intel/alderlake/fsp_params.c @@ -748,13 +748,25 @@ s_cfg->XdciEnable = xdci_can_enable(PCH_DEVFN_USBOTG); }
+efi_return_status_t __prot2lm_fsp_debug_event_handler(efi_status_code_type_t ignored1, + efi_status_code_value_t ignored2, + efi_uint32_t ignored3, + efi_guid_t *ignored4, + efi_status_code_data_t *data); + static void fill_fsps_uart_params(FSP_S_CONFIG *s_cfg, const struct soc_intel_alderlake_config *config) { if (CONFIG(FSP_USES_CB_DEBUG_EVENT_HANDLER) && CONFIG(CONSOLE_SERIAL) && - CONFIG(FSP_ENABLE_SERIAL_DEBUG)) - s_cfg->FspEventHandler = (UINT32)((FSP_EVENT_HANDLER *) - fsp_debug_event_handler); + CONFIG(FSP_ENABLE_SERIAL_DEBUG)) { + if (ENV_X86_64 && CONFIG(PLATFORM_USES_FSP2_X86_32)) { + s_cfg->FspEventHandler = (UINT32)(uintptr_t)((FSP_EVENT_HANDLER *) + __prot2lm_fsp_debug_event_handler); + } else { + s_cfg->FspEventHandler = (UINT32)(uintptr_t)((FSP_EVENT_HANDLER *) + fsp_debug_event_handler); + } + } /* PCH UART selection for FSP Debug */ s_cfg->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE; ASSERT(ARRAY_SIZE(s_cfg->SerialIoUartAutoFlow) > CONFIG_UART_FOR_CONSOLE); @@ -1301,7 +1313,7 @@ return;
bar0 = pci_s_read_config32(SA_DEV_IGD, PCI_BASE_ADDRESS_0); - mmio = (void *)(bar0 & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK); + mmio = (void *)(uintptr_t)(bar0 & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK); if (!mmio) return;
diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 84f83e3..83f2fd6 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -404,6 +404,13 @@ debug_get_pch_cpu_tracehub_modes(&mupd->CpuTraceHubMode, &mupd->PchTraceHubMode); }
+ +efi_return_status_t __prot2lm_fsp_debug_event_handler(efi_status_code_type_t ignored1, + efi_status_code_value_t ignored2, + efi_uint32_t ignored3, + efi_guid_t *ignored4, + efi_status_code_data_t *data); + void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { const struct soc_intel_alderlake_config *config; @@ -413,8 +420,12 @@ if (CONFIG(FSP_USES_CB_DEBUG_EVENT_HANDLER)) { if (CONFIG(CONSOLE_SERIAL) && CONFIG(FSP_ENABLE_SERIAL_DEBUG)) { enum fsp_log_level log_level = fsp_map_console_log_level(); - arch_upd->FspEventHandler = (UINT32)((FSP_EVENT_HANDLER *) - fsp_debug_event_handler); + if (ENV_X86_64 && CONFIG(PLATFORM_USES_FSP2_X86_32)) + arch_upd->FspEventHandler = (UINT32)(uintptr_t)((FSP_EVENT_HANDLER *) + __prot2lm_fsp_debug_event_handler); + else + arch_upd->FspEventHandler = (UINT32)(uintptr_t)((FSP_EVENT_HANDLER *) + fsp_debug_event_handler); /* Set Serial debug message level */ m_cfg->PcdSerialDebugLevel = log_level; /* Set MRC debug level */