[coreboot-gerrit] New patch to review for coreboot: cpu/x86: combine multiprocessor and SMM initialization

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Sat Apr 30 06:18:27 CEST 2016


Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14557

-gerrit

commit 72d633279a1fa0be5ce1475c215a495a48f82476
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Fri Apr 29 22:55:49 2016 -0500

    cpu/x86: combine multiprocessor and SMM initialization
    
    In order to reduce code duplication provide a common flow
    through callback functions that performs the multiprocessor
    and SMM initialization.
    
    Change-Id: I6f70969631012982126f0d0d76e5fac6880c24f0
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/include/cpu/x86/mp.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h
index 3227975..37f8e62 100644
--- a/src/include/cpu/x86/mp.h
+++ b/src/include/cpu/x86/mp.h
@@ -17,6 +17,7 @@
 #define _X86_MP_H_
 
 #include <arch/smp/atomic.h>
+#include <cpu/x86/smm.h>
 
 #define CACHELINE_SIZE 64
 
@@ -78,6 +79,80 @@ struct mp_params {
 	int num_records;
 };
 
+struct mp_ops {
+	/*
+	 * Return the number of logical x86 execution contexts that
+	 * need to be brought out of SIPI state as well as have SMM
+	 * handlers installed.
+	 */
+	int (*get_cpu_count)(void);
+	/*
+	 * Fill in permanent SMM region and save state size.
+	 */
+	void (*get_smm_info)(uintptr_t *perm_smbase, size_t *perm_smsize,
+				size_t *smm_save_state_size);
+	/*
+	 * Optionally provide a function which adjusts the APIC id
+	 * map to cpu number. By default the cpu number and APIC id
+	 * are 1:1. To change the APIC id for a given cpu return the
+	 * new APIC id. It's called for each cpu as indicated by
+	 * get_cpu_count().
+	 */
+	int (*adjust_cpu_apic_entry)(int cpu, int cur_apic_id);
+	/*
+	 * Optionally fill in pointer to microcode and indicate if the APs
+	 * can load the microcode in parallel.
+	 */
+	void (*get_microcode_info)(const void **microcode, int *parallel);
+	/*
+	 * Optionally adjust SMM handler parameters to override the default
+	 * values.  The is_perm variable indicates if the parameters to adjust
+	 * are for the relocation handler or the permanent handler. This
+	 * function is therefore called twice -- once for each handler.
+	 * By default the parameters for each SMM handler are:
+	 *       stack_size     num_concurrent_stacks num_concurrent_save_states
+	 * relo: save_state_size    get_cpu_count()          1
+	 * perm: save_state_size    get_cpu_count()          get_cpu_count()
+	 */
+	void (*adjust_smm_params)(struct smm_loader_params *slp, int is_perm);
+	/*
+	 * This function is called while each cpu is in the SMM relocation
+	 * handler. Its primary purpose is to adjust the SMBASE for the
+	 * permanent handler. The parameters passed are the current cpu
+	 * running the relocation handler adn the pre-calculated staggered cpu
+	 * SMBASE address to allow parallel permanent SMM handlers.
+	 */
+	void (*relocation_handler)(int cpu, uintptr_t staggered_smbase);
+	/*
+	 * Optional function to use to trigger SMM to perform relocation. If
+	 * not provided, smm_initiate_relocation() is used.
+	 */
+	void (*per_cpu_smm_trigger)(void);
+	/*
+	 * Optionally provide a callback prior to starting the multiprocessor
+	 * sequence. This callback is called after SMM handlers have been
+	 * loaded.
+	 */
+	void (*pre_mp_init)(void);
+};
+
+/*
+ * mp_init_with_smm() returns < 0 on failure and 0 on success. The mp_ops
+ * argument is used to drive the multiprocess initialization. The sequence of
+ * operations is the following:
+ * 1. get_cpu_count()
+ * 2. get_smm_info()
+ * 3. adjust_cpu_apic_entry()
+ * 4. get_microcode_info()
+ * 5. adjust_smm_params(is_perm=0)
+ * 6. adjust_smm_params(is_perm=1)
+ * 7. pre_mp_init()
+ * 8. per_cpu_smm_trigger() in parallel for all cpus which calls
+ *    relocation_handler() in SMM.
+ * 9. mp_initialize_cpu() for each cpu
+ */
+int mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops);
+
 /*
  * mp_init() will set up the SIPI vector and bring up the APs according to
  * mp_params. Each flight record will be executed according to the plan. Note



More information about the coreboot-gerrit mailing list