All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs
@ 2020-07-17 14:48 Simon Glass
  2020-07-17 14:48 ` [PATCH v6 01/25] x86: mp_init: Switch to livetree Simon Glass
                   ` (25 more replies)
  0 siblings, 26 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

At present MTRRs are mirrored to the secondary CPUs only once, as those
CPUs are started up. But U-Boot may add more MTRRs later, e.g. if it
decides that a video console must be set up.

This series enhances the x86 multi-processor support to allow MTRRs to
be updated at any time. It also updates the 'mtrr' command to support
setting the MTRRs on CPUs other than the boot CPU.

Changes in v6:
- Rebase to x86/master

Changes in v5:
- Drop timing in mp_park_aps()

Changes in v4:
- Update get_bsp() to return zero when SMP is not inited
- Add a Kconfig to control this feature, enabled only on APL
- Only enable this feature of CONFIG_SMP_AP_WORK is enabled
- Allow running on the BSP if SMP is not enabled
- Update mp_next_cpu() to stop if CONFIG_SMP_AP_WORK is not enabled

Changes in v3:
- Update bsp_do_flight_plan() to say 'on the BSP'
- s/slow/slot/
- Use C code instead of assembler to read/write callback pointers
- Update commit message to mention dropping of cpu_map
- Rename flag to GD_FLG_SMP_READY
- Rename flag to GD_FLG_SMP_READY
- Add a comment to run_ap_work()
- Rename flag to GD_FLG_SMP_READY
- Update the comment for run_ap_work() to explain logical_cpu_number
- Clarify meaning of @cpu_select in mp_run_on_cpus() comment
- Update the comment for mp_park_aps()
- Add more comments on how the iterators work
- Mention that the CPU number is in hex
- Remove stray asterisk from comments
- Drop mention of cpu_map which was handled in a previous patch

Changes in v2:
- Add comments to explain what start_aps() does
- Drop change to include/dm/uclass.h
- Mention error return in get_bsp()
- Add more comments
- Rename mtrr_save_all() to mtrr_read_all()
- Add a new patch to avoid enabling SMP in SPL
- Add new patch to add AP_DEFAULT_BASE to coral's memory map
- Rename function to mtrr_write_all()
- Keep things building by temporarily renaming the function in cmd/
- Drop the renamed mtrr_set_valid_() instead of mtrr_set_valid()
- Add a new patch with more comments

Simon Glass (25):
  x86: mp_init: Switch to livetree
  x86: Move MP code into mp_init
  x86: mp_init: Avoid declarations in header files
  x86: mp_init: Switch parameter names in start_aps()
  x86: mp_init: Drop the num_cpus static variable
  x86: mtrr: Fix 'ensable' typo
  x86: mp_init: Set up the CPU numbers at the start
  x86: mp_init: Adjust bsp_init() to return more information
  x86: cpu: Remove unnecessary #ifdefs
  x86: mp: Support APs waiting for instructions
  global_data: Add a generic global_data flag for SMP state
  x86: Set the SMP flag when MP init is complete
  x86: mp: Allow running functions on multiple CPUs
  x86: mp: Park CPUs before running the OS
  x86: mp: Add iterators for CPUs
  x86: mtrr: Use MP calls to list the MTRRs
  x86: Don't enable SMP in SPL
  x86: coral: Update the memory map
  x86: mtrr: Update MTRRs on all CPUs
  x86: mtrr: Add support for writing to MTRRs on any CPU
  x86: mtrr: Update the command to use the new mtrr calls
  x86: mtrr: Restructure so command execution is in one place
  x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU
  x86: mp: Add more comments to the module
  x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU

 arch/x86/Kconfig                      |   7 +
 arch/x86/cpu/Makefile                 |   2 +-
 arch/x86/cpu/apollolake/Kconfig       |   1 +
 arch/x86/cpu/cpu.c                    |  58 +--
 arch/x86/cpu/i386/cpu.c               |  26 +-
 arch/x86/cpu/mp_init.c                | 528 ++++++++++++++++++++++----
 arch/x86/cpu/mtrr.c                   | 149 ++++++++
 arch/x86/include/asm/mp.h             | 137 ++++++-
 arch/x86/include/asm/mtrr.h           |  51 +++
 cmd/x86/mtrr.c                        | 148 +++++---
 doc/board/google/chromebook_coral.rst |   1 +
 include/asm-generic/global_data.h     |   1 +
 12 files changed, 924 insertions(+), 185 deletions(-)

-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 01/25] x86: mp_init: Switch to livetree
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 02/25] x86: Move MP code into mp_init Simon Glass
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Update this code to use livetree calls instead of flat-tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 7fde4ff7e1..c25d17c647 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -507,8 +507,7 @@ int mp_init_cpu(struct udevice *cpu, void *unused)
 	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
 	 * this, set req_seq to the reg number in the device tree in advance.
 	 */
-	cpu->req_seq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(cpu), "reg",
-				      -1);
+	cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
 	plat->ucode_version = microcode_read_rev();
 	plat->device_id = gd->arch.x86_device;
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 02/25] x86: Move MP code into mp_init
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
  2020-07-17 14:48 ` [PATCH v6 01/25] x86: mp_init: Switch to livetree Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 03/25] x86: mp_init: Avoid declarations in header files Simon Glass
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

At present the 'flight plan' for CPUs is passed into mp_init. But it is
always the same. Move it into the mp_init file so everything is in one
place. Also drop the SMI function since it does nothing. If we implement
SMIs, more refactoring will be needed anyway.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 arch/x86/cpu/i386/cpu.c   | 24 +++++-------------------
 arch/x86/cpu/mp_init.c    | 22 ++++++++++------------
 arch/x86/include/asm/mp.h | 17 +----------------
 3 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index a6a6afec8c..55a0907bc8 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -21,6 +21,7 @@
 #include <common.h>
 #include <cpu_func.h>
 #include <init.h>
+#include <log.h>
 #include <malloc.h>
 #include <spl.h>
 #include <asm/control_regs.h>
@@ -631,29 +632,14 @@ int cpu_jump_to_64bit_uboot(ulong target)
 }
 
 #ifdef CONFIG_SMP
-static int enable_smis(struct udevice *cpu, void *unused)
-{
-	return 0;
-}
-
-static struct mp_flight_record mp_steps[] = {
-	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-	/* Wait for APs to finish initialization before proceeding */
-	MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
-};
-
 int x86_mp_init(void)
 {
-	struct mp_params mp_params;
-
-	mp_params.parallel_microcode_load = 0,
-	mp_params.flight_plan = &mp_steps[0];
-	mp_params.num_records = ARRAY_SIZE(mp_steps);
-	mp_params.microcode_pointer = 0;
+	int ret;
 
-	if (mp_init(&mp_params)) {
+	ret = mp_init();
+	if (ret) {
 		printf("Warning: MP init failure\n");
-		return -EIO;
+		return log_ret(ret);
 	}
 
 	return 0;
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index c25d17c647..831fd7035d 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -41,6 +41,9 @@ struct saved_msr {
 	uint32_t hi;
 } __packed;
 
+static struct mp_flight_record mp_steps[] = {
+	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+};
 
 struct mp_flight_plan {
 	int num_records;
@@ -372,7 +375,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
 	return 0;
 }
 
-static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params)
+static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
 {
 	int i;
 	int ret = 0;
@@ -380,8 +383,8 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params)
 	const int step_us = 100;
 	int num_aps = num_cpus - 1;
 
-	for (i = 0; i < mp_params->num_records; i++) {
-		struct mp_flight_record *rec = &mp_params->flight_plan[i];
+	for (i = 0; i < plan->num_records; i++) {
+		struct mp_flight_record *rec = &plan->records[i];
 
 		/* Wait for APs if the record is not released */
 		if (atomic_read(&rec->barrier) == 0) {
@@ -420,7 +423,7 @@ static int init_bsp(struct udevice **devp)
 	return 0;
 }
 
-int mp_init(struct mp_params *p)
+int mp_init(void)
 {
 	int num_aps;
 	atomic_t *ap_count;
@@ -445,11 +448,6 @@ int mp_init(struct mp_params *p)
 		return ret;
 	}
 
-	if (p == NULL || p->flight_plan == NULL || p->num_records < 1) {
-		printf("Invalid MP parameters\n");
-		return -EINVAL;
-	}
-
 	num_cpus = cpu_get_count(cpu);
 	if (num_cpus < 0) {
 		debug("Cannot get number of CPUs: err=%d\n", num_cpus);
@@ -464,8 +462,8 @@ int mp_init(struct mp_params *p)
 		debug("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n");
 
 	/* Copy needed parameters so that APs have a reference to the plan */
-	mp_info.num_records = p->num_records;
-	mp_info.records = p->flight_plan;
+	mp_info.num_records = ARRAY_SIZE(mp_steps);
+	mp_info.records = mp_steps;
 
 	/* Load the SIPI vector */
 	ret = load_sipi_vector(&ap_count, num_cpus);
@@ -489,7 +487,7 @@ int mp_init(struct mp_params *p)
 	}
 
 	/* Walk the flight plan for the BSP */
-	ret = bsp_do_flight_plan(cpu, p);
+	ret = bsp_do_flight_plan(cpu, &mp_info);
 	if (ret) {
 		debug("CPU init failed: err=%d\n", ret);
 		return ret;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 9dddf88b5a..db02904ecb 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -51,21 +51,6 @@ struct mp_flight_record {
 #define MP_FR_NOBLOCK_APS(ap_func, ap_arg, bsp_func, bsp_arg) \
 	MP_FLIGHT_RECORD(1, ap_func, ap_arg, bsp_func, bsp_arg)
 
-/*
- * The mp_params structure provides the arguments to the mp subsystem
- * for bringing up APs.
- *
- * At present this is overkill for U-Boot, but it may make it easier to add
- * SMM support.
- */
-struct mp_params {
-	int parallel_microcode_load;
-	const void *microcode_pointer;
-	/* Flight plan  for APs and BSP */
-	struct mp_flight_record *flight_plan;
-	int num_records;
-};
-
 /*
  * 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
@@ -85,7 +70,7 @@ struct mp_params {
  *
  * mp_init() returns < 0 on error, 0 on success.
  */
-int mp_init(struct mp_params *params);
+int mp_init(void);
 
 /* Probes the CPU device */
 int mp_init_cpu(struct udevice *cpu, void *unused);
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 03/25] x86: mp_init: Avoid declarations in header files
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
  2020-07-17 14:48 ` [PATCH v6 01/25] x86: mp_init: Switch to livetree Simon Glass
  2020-07-17 14:48 ` [PATCH v6 02/25] x86: Move MP code into mp_init Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 04/25] x86: mp_init: Switch parameter names in start_aps() Simon Glass
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

The functions used by the flight plan are declared in the header file but
are not used in any other file.

Move the flight plan steps down to just above where it is used so that we
can make these function static.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 arch/x86/cpu/mp_init.c    | 40 +++++++++++++++++++--------------------
 arch/x86/include/asm/mp.h |  3 ---
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 831fd7035d..e77d7f2cd6 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -41,10 +41,6 @@ struct saved_msr {
 	uint32_t hi;
 } __packed;
 
-static struct mp_flight_record mp_steps[] = {
-	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-};
-
 struct mp_flight_plan {
 	int num_records;
 	struct mp_flight_record *records;
@@ -423,6 +419,26 @@ static int init_bsp(struct udevice **devp)
 	return 0;
 }
 
+static int mp_init_cpu(struct udevice *cpu, void *unused)
+{
+	struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
+
+	/*
+	 * Multiple APs are brought up simultaneously and they may get the same
+	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
+	 * this, set req_seq to the reg number in the device tree in advance.
+	 */
+	cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
+	plat->ucode_version = microcode_read_rev();
+	plat->device_id = gd->arch.x86_device;
+
+	return device_probe(cpu);
+}
+
+static struct mp_flight_record mp_steps[] = {
+	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+};
+
 int mp_init(void)
 {
 	int num_aps;
@@ -495,19 +511,3 @@ int mp_init(void)
 
 	return 0;
 }
-
-int mp_init_cpu(struct udevice *cpu, void *unused)
-{
-	struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
-
-	/*
-	 * Multiple APs are brought up simultaneously and they may get the same
-	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
-	 * this, set req_seq to the reg number in the device tree in advance.
-	 */
-	cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
-	plat->ucode_version = microcode_read_rev();
-	plat->device_id = gd->arch.x86_device;
-
-	return device_probe(cpu);
-}
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index db02904ecb..94af819ad9 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -72,9 +72,6 @@ struct mp_flight_record {
  */
 int mp_init(void);
 
-/* Probes the CPU device */
-int mp_init_cpu(struct udevice *cpu, void *unused);
-
 /* Set up additional CPUs */
 int x86_mp_init(void);
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 04/25] x86: mp_init: Switch parameter names in start_aps()
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (2 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 03/25] x86: mp_init: Avoid declarations in header files Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 05/25] x86: mp_init: Drop the num_cpus static variable Simon Glass
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

These parameters are named differently from elsewhere in this file. Switch
them to avoid confusion.

Also add comments to this function.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v2)

Changes in v2:
- Add comments to explain what start_aps() does

 arch/x86/cpu/mp_init.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index e77d7f2cd6..8b00d57c88 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -308,13 +308,26 @@ static int apic_wait_timeout(int total_delay, const char *msg)
 	return 0;
 }
 
-static int start_aps(int ap_count, atomic_t *num_aps)
+/**
+ * start_aps() - Start up the APs and count how many we find
+ *
+ * This is called on the boot processor to start up all the other processors
+ * (here called APs).
+ *
+ * @num_aps: Number of APs we expect to find
+ * @ap_count: Initially zero. Incremented by this function for each AP found
+ * @return 0 if all APs were set up correctly or there are none to set up,
+ *	-ENOSPC if the SIPI vector is too high in memory,
+ *	-ETIMEDOUT if the ICR is busy or the second SIPI fails to complete
+ *	-EIO if not all APs check in correctly
+ */
+static int start_aps(int num_aps, atomic_t *ap_count)
 {
 	int sipi_vector;
 	/* Max location is 4KiB below 1MiB */
 	const int max_vector_loc = ((1 << 20) - (1 << 12)) >> 12;
 
-	if (ap_count == 0)
+	if (num_aps == 0)
 		return 0;
 
 	/* The vector is sent as a 4k aligned address in one byte */
@@ -326,7 +339,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
 		return -ENOSPC;
 	}
 
-	debug("Attempting to start %d APs\n", ap_count);
+	debug("Attempting to start %d APs\n", num_aps);
 
 	if (apic_wait_timeout(1000, "ICR not to be busy"))
 		return -ETIMEDOUT;
@@ -349,7 +362,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
 		return -ETIMEDOUT;
 
 	/* Wait for CPUs to check in up to 200 us */
-	wait_for_aps(num_aps, ap_count, 200, 15);
+	wait_for_aps(ap_count, num_aps, 200, 15);
 
 	/* Send 2nd SIPI */
 	if (apic_wait_timeout(1000, "ICR not to be busy"))
@@ -362,9 +375,9 @@ static int start_aps(int ap_count, atomic_t *num_aps)
 		return -ETIMEDOUT;
 
 	/* Wait for CPUs to check in */
-	if (wait_for_aps(num_aps, ap_count, 10000, 50)) {
+	if (wait_for_aps(ap_count, num_aps, 10000, 50)) {
 		debug("Not all APs checked in: %d/%d\n",
-		      atomic_read(num_aps), ap_count);
+		      atomic_read(ap_count), num_aps);
 		return -EIO;
 	}
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 05/25] x86: mp_init: Drop the num_cpus static variable
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (3 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 04/25] x86: mp_init: Switch parameter names in start_aps() Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 06/25] x86: mtrr: Fix 'ensable' typo Simon Glass
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

This does not need to be global across all functions in this file. Pass a
parameter instead.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v3)

Changes in v3:
- Update bsp_do_flight_plan() to say 'on the BSP'

 arch/x86/cpu/mp_init.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 8b00d57c88..df43f71572 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -31,9 +31,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Total CPUs include BSP */
-static int num_cpus;
-
 /* This also needs to match the sipi.S assembly code for saved MSR encoding */
 struct saved_msr {
 	uint32_t index;
@@ -384,13 +381,23 @@ static int start_aps(int num_aps, atomic_t *ap_count)
 	return 0;
 }
 
-static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
+/**
+ * bsp_do_flight_plan() - Do the flight plan on the BSP
+ *
+ * This runs the flight plan on the main CPU used to boot U-Boot
+ *
+ * @cpu: Device for the main CPU
+ * @plan: Flight plan to run
+ * @num_aps: Number of APs (CPUs other than the BSP)
+ * @returns 0 on success, -ETIMEDOUT if an AP failed to come up
+ */
+static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan,
+			      int num_aps)
 {
 	int i;
 	int ret = 0;
 	const int timeout_us = 100000;
 	const int step_us = 100;
-	int num_aps = num_cpus - 1;
 
 	for (i = 0; i < plan->num_records; i++) {
 		struct mp_flight_record *rec = &plan->records[i];
@@ -410,6 +417,7 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
 
 		release_barrier(&rec->barrier);
 	}
+
 	return ret;
 }
 
@@ -454,7 +462,7 @@ static struct mp_flight_record mp_steps[] = {
 
 int mp_init(void)
 {
-	int num_aps;
+	int num_aps, num_cpus;
 	atomic_t *ap_count;
 	struct udevice *cpu;
 	int ret;
@@ -516,7 +524,7 @@ int mp_init(void)
 	}
 
 	/* Walk the flight plan for the BSP */
-	ret = bsp_do_flight_plan(cpu, &mp_info);
+	ret = bsp_do_flight_plan(cpu, &mp_info, num_aps);
 	if (ret) {
 		debug("CPU init failed: err=%d\n", ret);
 		return ret;
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 06/25] x86: mtrr: Fix 'ensable' typo
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (4 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 05/25] x86: mp_init: Drop the num_cpus static variable Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 07/25] x86: mp_init: Set up the CPU numbers at the start Simon Glass
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Fix a typo in the command help.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 cmd/x86/mtrr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 084d7315f4..5d25c5802a 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -135,5 +135,5 @@ U_BOOT_CMD(
 	"set <reg> <type> <start> <size>   - set a register\n"
 	"\t<type> is Uncacheable, Combine, Through, Protect, Back\n"
 	"disable <reg>      - disable a register\n"
-	"ensable <reg>      - enable a register"
+	"enable <reg>       - enable a register"
 );
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 07/25] x86: mp_init: Set up the CPU numbers at the start
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (5 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 06/25] x86: mtrr: Fix 'ensable' typo Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 08/25] x86: mp_init: Adjust bsp_init() to return more information Simon Glass
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

At present each CPU is given a number when it starts itself up. While this
saves a tiny amount of time by doing the device-tree read in parallel, it
is confusing that the numbering happens on the fly.

Move this code into mp_init() and do it at the start.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index df43f71572..6f6de49df0 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -444,12 +444,6 @@ static int mp_init_cpu(struct udevice *cpu, void *unused)
 {
 	struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
 
-	/*
-	 * Multiple APs are brought up simultaneously and they may get the same
-	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
-	 * this, set req_seq to the reg number in the device tree in advance.
-	 */
-	cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
 	plat->ucode_version = microcode_read_rev();
 	plat->device_id = gd->arch.x86_device;
 
@@ -465,13 +459,8 @@ int mp_init(void)
 	int num_aps, num_cpus;
 	atomic_t *ap_count;
 	struct udevice *cpu;
-	int ret;
-
-	/* This will cause the CPUs devices to be bound */
 	struct uclass *uc;
-	ret = uclass_get(UCLASS_CPU, &uc);
-	if (ret)
-		return ret;
+	int ret;
 
 	if (IS_ENABLED(CONFIG_QFW)) {
 		ret = qemu_cpu_fixup();
@@ -479,6 +468,14 @@ int mp_init(void)
 			return ret;
 	}
 
+	/*
+	 * Multiple APs are brought up simultaneously and they may get the same
+	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
+	 * this, set req_seq to the reg number in the device tree in advance.
+	 */
+	uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
+		cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
+
 	ret = init_bsp(&cpu);
 	if (ret) {
 		debug("Cannot init boot CPU: err=%d\n", ret);
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 08/25] x86: mp_init: Adjust bsp_init() to return more information
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (6 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 07/25] x86: mp_init: Set up the CPU numbers at the start Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 09/25] x86: cpu: Remove unnecessary #ifdefs Simon Glass
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

This function is misnamed since it does not actually init the BSP. Also
it is convenient to adjust it to return a little more information.

Rename and update the function, to allow it to return the BSP CPU device
and number, as well as the total number of CPUs.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v4)

Changes in v4:
- Update get_bsp() to return zero when SMP is not inited

Changes in v2:
- Drop change to include/dm/uclass.h
- Mention error return in get_bsp()

 arch/x86/cpu/mp_init.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 6f6de49df0..9fdde7832a 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -421,9 +421,18 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan,
 	return ret;
 }
 
-static int init_bsp(struct udevice **devp)
+/**
+ * get_bsp() - Get information about the bootstrap processor
+ *
+ * @devp: If non-NULL, returns CPU device corresponding to the BSP
+ * @cpu_countp: If non-NULL, returns the total number of CPUs
+ * @return CPU number of the BSP, or -ve on error. If multiprocessing is not
+ *	enabled, returns 0
+ */
+static int get_bsp(struct udevice **devp, int *cpu_countp)
 {
 	char processor_name[CPU_MAX_NAME_LEN];
+	struct udevice *dev;
 	int apic_id;
 	int ret;
 
@@ -431,13 +440,20 @@ static int init_bsp(struct udevice **devp)
 	debug("CPU: %s\n", processor_name);
 
 	apic_id = lapicid();
-	ret = find_cpu_by_apic_id(apic_id, devp);
-	if (ret) {
+	ret = find_cpu_by_apic_id(apic_id, &dev);
+	if (ret < 0) {
 		printf("Cannot find boot CPU, APIC ID %d\n", apic_id);
 		return ret;
 	}
+	ret = cpu_get_count(dev);
+	if (ret < 0)
+		return log_msg_ret("count", ret);
+	if (devp)
+		*devp = dev;
+	if (cpu_countp)
+		*cpu_countp = ret;
 
-	return 0;
+	return dev->req_seq >= 0 ? dev->req_seq : 0;
 }
 
 static int mp_init_cpu(struct udevice *cpu, void *unused)
@@ -476,24 +492,18 @@ int mp_init(void)
 	uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
 		cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
 
-	ret = init_bsp(&cpu);
-	if (ret) {
+	ret = get_bsp(&cpu, &num_cpus);
+	if (ret < 0) {
 		debug("Cannot init boot CPU: err=%d\n", ret);
 		return ret;
 	}
 
-	num_cpus = cpu_get_count(cpu);
-	if (num_cpus < 0) {
-		debug("Cannot get number of CPUs: err=%d\n", num_cpus);
-		return num_cpus;
-	}
-
 	if (num_cpus < 2)
 		debug("Warning: Only 1 CPU is detected\n");
 
 	ret = check_cpu_devices(num_cpus);
 	if (ret)
-		debug("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n");
+		log_warning("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n");
 
 	/* Copy needed parameters so that APs have a reference to the plan */
 	mp_info.num_records = ARRAY_SIZE(mp_steps);
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 09/25] x86: cpu: Remove unnecessary #ifdefs
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (7 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 08/25] x86: mp_init: Adjust bsp_init() to return more information Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 10/25] x86: mp: Support APs waiting for instructions Simon Glass
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Drop some #ifdefs that are not needed or can be converted to compile-time
checks.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 arch/x86/cpu/cpu.c      | 53 ++++++++++++++++++++---------------------
 arch/x86/cpu/i386/cpu.c |  2 --
 2 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 98ed66e67d..c343586e04 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -67,10 +67,8 @@ static const char *const x86_vendor_name[] = {
 
 int __weak x86_cleanup_before_linux(void)
 {
-#ifdef CONFIG_BOOTSTAGE_STASH
 	bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
 			CONFIG_BOOTSTAGE_STASH_SIZE);
-#endif
 
 	return 0;
 }
@@ -201,18 +199,19 @@ int last_stage_init(void)
 
 	write_tables();
 
-#ifdef CONFIG_GENERATE_ACPI_TABLE
-	fadt = acpi_find_fadt();
+	if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
+		fadt = acpi_find_fadt();
 
-	/* Don't touch ACPI hardware on HW reduced platforms */
-	if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
-		/*
-		 * Other than waiting for OSPM to request us to switch to ACPI
-		 * mode, do it by ourselves, since SMI will not be triggered.
-		 */
-		enter_acpi_mode(fadt->pm1a_cnt_blk);
+		/* Don't touch ACPI hardware on HW reduced platforms */
+		if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
+			/*
+			 * Other than waiting for OSPM to request us to switch
+			 * to ACPI * mode, do it by ourselves, since SMI will
+			 * not be triggered.
+			 */
+			enter_acpi_mode(fadt->pm1a_cnt_blk);
+		}
 	}
-#endif
 
 	return 0;
 }
@@ -220,19 +219,20 @@ int last_stage_init(void)
 
 static int x86_init_cpus(void)
 {
-#ifdef CONFIG_SMP
-	debug("Init additional CPUs\n");
-	x86_mp_init();
-#else
-	struct udevice *dev;
+	if (IS_ENABLED(CONFIG_SMP)) {
+		debug("Init additional CPUs\n");
+		x86_mp_init();
+	} else {
+		struct udevice *dev;
 
-	/*
-	 * This causes the cpu-x86 driver to be probed.
-	 * We don't check return value here as we want to allow boards
-	 * which have not been converted to use cpu uclass driver to boot.
-	 */
-	uclass_first_device(UCLASS_CPU, &dev);
-#endif
+		/*
+		 * This causes the cpu-x86 driver to be probed.
+		 * We don't check return value here as we want to allow boards
+		 * which have not been converted to use cpu uclass driver to
+		 * boot.
+		 */
+		uclass_first_device(UCLASS_CPU, &dev);
+	}
 
 	return 0;
 }
@@ -276,9 +276,8 @@ int reserve_arch(void)
 	if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
 		mrccache_reserve();
 
-#ifdef CONFIG_SEABIOS
-	high_table_reserve();
-#endif
+	if (IS_ENABLED(CONFIG_SEABIOS))
+		high_table_reserve();
 
 	if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
 		acpi_s3_reserve();
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 55a0907bc8..8f342dd06e 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -631,7 +631,6 @@ int cpu_jump_to_64bit_uboot(ulong target)
 	return -EFAULT;
 }
 
-#ifdef CONFIG_SMP
 int x86_mp_init(void)
 {
 	int ret;
@@ -644,4 +643,3 @@ int x86_mp_init(void)
 
 	return 0;
 }
-#endif
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 10/25] x86: mp: Support APs waiting for instructions
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (8 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 09/25] x86: cpu: Remove unnecessary #ifdefs Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:22   ` Bin Meng
  2020-07-17 14:48 ` [PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state Simon Glass
                   ` (15 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

At present the APs (non-boot CPUs) are inited once and then parked ready
for the OS to use them. However in some cases we want to send new requests
through, such as to change MTRRs and keep them consistent across CPUs.

Change the last state of the flight plan to go into a wait loop, accepting
instructions from the main CPU.

Drop cpu_map since it is not used.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v4)

Changes in v4:
- Add a Kconfig to control this feature, enabled only on APL

Changes in v3:
- s/slow/slot/
- Use C code instead of assembler to read/write callback pointers
- Update commit message to mention dropping of cpu_map

Changes in v2:
- Add more comments

 arch/x86/Kconfig                |   7 ++
 arch/x86/cpu/apollolake/Kconfig |   1 +
 arch/x86/cpu/mp_init.c          | 123 +++++++++++++++++++++++++++++---
 arch/x86/include/asm/mp.h       |  11 +++
 4 files changed, 134 insertions(+), 8 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 27295ef384..ff4f06ed79 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -603,6 +603,13 @@ config SMP
 	  only one CPU will be enabled regardless of the number of CPUs
 	  available.
 
+config SMP_AP_WORK
+	bool
+	depends on SMP
+	help
+	 Allow APs to do other work after initialisation instead of going
+	 to sleep.
+
 config MAX_CPUS
 	int "Maximum number of CPUs permitted"
 	depends on SMP
diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig
index 942f11f566..99d4e105c2 100644
--- a/arch/x86/cpu/apollolake/Kconfig
+++ b/arch/x86/cpu/apollolake/Kconfig
@@ -15,6 +15,7 @@ config INTEL_APOLLOLAKE
 	select TPL_PCH_SUPPORT
 	select PCH_SUPPORT
 	select P2SB
+	select SMP_AP_WORK
 	imply ENABLE_MRC_CACHE
 	imply AHCI_PCI
 	imply SCSI
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 9fdde7832a..787de92fa3 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -15,6 +15,7 @@
 #include <asm/atomic.h>
 #include <asm/cpu.h>
 #include <asm/interrupt.h>
+#include <asm/io.h>
 #include <asm/lapic.h>
 #include <asm/microcode.h>
 #include <asm/mp.h>
@@ -43,13 +44,38 @@ struct mp_flight_plan {
 	struct mp_flight_record *records;
 };
 
+/**
+ * struct mp_callback - Callback information for APs
+ *
+ * @func: Function to run
+ * @arg: Argument to pass to the function
+ * @logical_cpu_number: Either a CPU number (i.e. dev->req_seq) or a special
+ *	value like MP_SELECT_BSP. It tells the AP whether it should process this
+ *	callback
+ */
+struct mp_callback {
+	/**
+	 * func() - Function to call on the AP
+	 *
+	 * @arg: Argument to pass
+	 */
+	void (*func)(void *arg);
+	void *arg;
+	int logical_cpu_number;
+};
+
 static struct mp_flight_plan mp_info;
 
-struct cpu_map {
-	struct udevice *dev;
-	int apic_id;
-	int err_code;
-};
+/*
+ * ap_callbacks - Callback mailbox array
+ *
+ * Array of callback, one entry for each available CPU, indexed by the CPU
+ * number, which is dev->req_seq. The entry for the main CPU is never used.
+ * When this is NULL, there is no pending work for the CPU to run. When
+ * non-NULL it points to the mp_callback structure. This is shared between all
+ * CPUs, so should only be written by the main CPU.
+ */
+static struct mp_callback **ap_callbacks;
 
 static inline void barrier_wait(atomic_t *b)
 {
@@ -147,11 +173,12 @@ static void ap_init(unsigned int cpu_index)
 	debug("AP: slot %d apic_id %x, dev %s\n", cpu_index, apic_id,
 	      dev ? dev->name : "(apic_id not found)");
 
-	/* Walk the flight plan */
+	/*
+	 * Walk the flight plan, which only returns if CONFIG_SMP_AP_WORK is not
+	 * enabled
+	 */
 	ap_do_flight_plan(dev);
 
-	/* Park the AP */
-	debug("parking\n");
 done:
 	stop_this_cpu();
 }
@@ -456,6 +483,81 @@ static int get_bsp(struct udevice **devp, int *cpu_countp)
 	return dev->req_seq >= 0 ? dev->req_seq : 0;
 }
 
+/**
+ * read_callback() - Read the pointer in a callback slot
+ *
+ * This is called by APs to read their callback slot to see if there is a
+ * pointer to new instructions
+ *
+ * @slot: Pointer to the AP's callback slot
+ * @return value of that pointer
+ */
+static struct mp_callback *read_callback(struct mp_callback **slot)
+{
+	dmb();
+
+	return *slot;
+}
+
+/**
+ * store_callback() - Store a pointer to the callback slot
+ *
+ * This is called by APs to write NULL into the callback slot when they have
+ * finished the work requested by the BSP.
+ *
+ * @slot: Pointer to the AP's callback slot
+ * @val: Value to write (e.g. NULL)
+ */
+static void store_callback(struct mp_callback **slot, struct mp_callback *val)
+{
+	*slot = val;
+	dmb();
+}
+
+/**
+ * ap_wait_for_instruction() - Wait for and process requests from the main CPU
+ *
+ * This is called by APs (here, everything other than the main boot CPU) to
+ * await instructions. They arrive in the form of a function call and argument,
+ * which is then called. This uses a simple mailbox with atomic read/set
+ *
+ * @cpu: CPU that is waiting
+ * @unused: Optional argument provided by struct mp_flight_record, not used here
+ * @return Does not return
+ */
+static int ap_wait_for_instruction(struct udevice *cpu, void *unused)
+{
+	struct mp_callback lcb;
+	struct mp_callback **per_cpu_slot;
+
+	if (!IS_ENABLED(CONFIG_SMP_AP_WORK))
+		return 0;
+
+	per_cpu_slot = &ap_callbacks[cpu->req_seq];
+
+	while (1) {
+		struct mp_callback *cb = read_callback(per_cpu_slot);
+
+		if (!cb) {
+			asm ("pause");
+			continue;
+		}
+
+		/* Copy to local variable before using the value */
+		memcpy(&lcb, cb, sizeof(lcb));
+		mfence();
+		if (lcb.logical_cpu_number == MP_SELECT_ALL ||
+		    lcb.logical_cpu_number == MP_SELECT_APS ||
+		    cpu->req_seq == lcb.logical_cpu_number)
+			lcb.func(lcb.arg);
+
+		/* Indicate we are finished */
+		store_callback(per_cpu_slot, NULL);
+	}
+
+	return 0;
+}
+
 static int mp_init_cpu(struct udevice *cpu, void *unused)
 {
 	struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
@@ -468,6 +570,7 @@ static int mp_init_cpu(struct udevice *cpu, void *unused)
 
 static struct mp_flight_record mp_steps[] = {
 	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+	MP_FR_BLOCK_APS(ap_wait_for_instruction, NULL, NULL, NULL),
 };
 
 int mp_init(void)
@@ -505,6 +608,10 @@ int mp_init(void)
 	if (ret)
 		log_warning("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n");
 
+	ap_callbacks = calloc(num_cpus, sizeof(struct mp_callback *));
+	if (!ap_callbacks)
+		return -ENOMEM;
+
 	/* Copy needed parameters so that APs have a reference to the plan */
 	mp_info.num_records = ARRAY_SIZE(mp_steps);
 	mp_info.records = mp_steps;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 94af819ad9..41b1575f4b 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -11,6 +11,17 @@
 #include <asm/atomic.h>
 #include <asm/cache.h>
 
+enum {
+	/* Indicates that the function should run on all CPUs */
+	MP_SELECT_ALL	= -1,
+
+	/* Run on boot CPUs */
+	MP_SELECT_BSP	= -2,
+
+	/* Run on non-boot CPUs */
+	MP_SELECT_APS	= -3,
+};
+
 typedef int (*mp_callback_t)(struct udevice *cpu, void *arg);
 
 /*
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (9 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 10/25] x86: mp: Support APs waiting for instructions Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:23   ` Bin Meng
  2020-07-17 14:48 ` [PATCH v6 12/25] x86: Set the SMP flag when MP init is complete Simon Glass
                   ` (14 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Allow keeping track of whether all CPUs have been enabled yet. This allows
us to know whether other CPUs need to be considered when updating
CPU-specific settings such as MTRRs on x86.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v3)

Changes in v3:
- Rename flag to GD_FLG_SMP_READY

 include/asm-generic/global_data.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 8c78792cc9..d4a4e2215d 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -167,5 +167,6 @@ typedef struct global_data {
 #define GD_FLG_LOG_READY	0x08000 /* Log system is ready for use	   */
 #define GD_FLG_WDT_READY	0x10000 /* Watchdog is ready for use	   */
 #define GD_FLG_SKIP_LL_INIT	0x20000	/* Don't perform low-level init	   */
+#define GD_FLG_SMP_READY	0x40000	/* SMP init is complete		   */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 12/25] x86: Set the SMP flag when MP init is complete
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (10 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs Simon Glass
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Set this flag so we can track when it is safe to use CPUs other than the
main one.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v3)

Changes in v3:
- Rename flag to GD_FLG_SMP_READY

 arch/x86/cpu/mp_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 787de92fa3..69a23829b9 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -643,6 +643,7 @@ int mp_init(void)
 		debug("CPU init failed: err=%d\n", ret);
 		return ret;
 	}
+	gd->flags |= GD_FLG_SMP_READY;
 
 	return 0;
 }
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (11 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 12/25] x86: Set the SMP flag when MP init is complete Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:25   ` Bin Meng
  2020-07-17 14:48 ` [PATCH v6 14/25] x86: mp: Park CPUs before running the OS Simon Glass
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Add a way to run a function on a selection of CPUs. This supports either
a single CPU, all CPUs, just the main CPU or just the 'APs', in Intel
terminology.

It works by writing into a mailbox and then waiting for the CPUs to notice
it, take action and indicate they are done.

When SMP is not yet enabled, this just calls the function on the main CPU.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v4)

Changes in v4:
- Only enable this feature of CONFIG_SMP_AP_WORK is enabled
- Allow running on the BSP if SMP is not enabled

Changes in v3:
- Add a comment to run_ap_work()
- Rename flag to GD_FLG_SMP_READY
- Update the comment for run_ap_work() to explain logical_cpu_number
- Clarify meaning of @cpu_select in mp_run_on_cpus() comment

 arch/x86/cpu/mp_init.c    | 107 +++++++++++++++++++++++++++++++++++---
 arch/x86/include/asm/mp.h |  33 ++++++++++++
 2 files changed, 134 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 69a23829b9..dd6d6bfab7 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -54,12 +54,7 @@ struct mp_flight_plan {
  *	callback
  */
 struct mp_callback {
-	/**
-	 * func() - Function to call on the AP
-	 *
-	 * @arg: Argument to pass
-	 */
-	void (*func)(void *arg);
+	mp_run_func func;
 	void *arg;
 	int logical_cpu_number;
 };
@@ -514,6 +509,70 @@ static void store_callback(struct mp_callback **slot, struct mp_callback *val)
 	dmb();
 }
 
+/**
+ * run_ap_work() - Run a callback on selected APs
+ *
+ * This writes @callback to all APs and waits for them all to acknowledge it,
+ * Note that whether each AP actually calls the callback depends on the value
+ * of logical_cpu_number (see struct mp_callback). The logical CPU number is
+ * the CPU device's req->seq value.
+ *
+ * @callback: Callback information to pass to all APs
+ * @bsp: CPU device for the BSP
+ * @num_cpus: The number of CPUs in the system (= number of APs + 1)
+ * @expire_ms: Timeout to wait for all APs to finish, in milliseconds, or 0 for
+ *	no timeout
+ * @return 0 if OK, -ETIMEDOUT if one or more APs failed to respond in time
+ */
+static int run_ap_work(struct mp_callback *callback, struct udevice *bsp,
+		       int num_cpus, uint expire_ms)
+{
+	int cur_cpu = bsp->req_seq;
+	int num_aps = num_cpus - 1; /* number of non-BSPs to get this message */
+	int cpus_accepted;
+	ulong start;
+	int i;
+
+	if (!IS_ENABLED(CONFIG_SMP_AP_WORK)) {
+		printf("APs already parked. CONFIG_SMP_AP_WORK not enabled\n");
+		return -ENOTSUPP;
+	}
+
+	/* Signal to all the APs to run the func. */
+	for (i = 0; i < num_cpus; i++) {
+		if (cur_cpu != i)
+			store_callback(&ap_callbacks[i], callback);
+	}
+	mfence();
+
+	/* Wait for all the APs to signal back that call has been accepted. */
+	start = get_timer(0);
+
+	do {
+		mdelay(1);
+		cpus_accepted = 0;
+
+		for (i = 0; i < num_cpus; i++) {
+			if (cur_cpu == i)
+				continue;
+			if (!read_callback(&ap_callbacks[i]))
+				cpus_accepted++;
+		}
+
+		if (expire_ms && get_timer(start) >= expire_ms) {
+			log(UCLASS_CPU, LOGL_CRIT,
+			    "AP call expired; %d/%d CPUs accepted\n",
+			    cpus_accepted, num_aps);
+			return -ETIMEDOUT;
+		}
+	} while (cpus_accepted != num_aps);
+
+	/* Make sure we can see any data written by the APs */
+	mfence();
+
+	return 0;
+}
+
 /**
  * ap_wait_for_instruction() - Wait for and process requests from the main CPU
  *
@@ -573,6 +632,42 @@ static struct mp_flight_record mp_steps[] = {
 	MP_FR_BLOCK_APS(ap_wait_for_instruction, NULL, NULL, NULL),
 };
 
+int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
+{
+	struct mp_callback lcb = {
+		.func = func,
+		.arg = arg,
+		.logical_cpu_number = cpu_select,
+	};
+	struct udevice *dev;
+	int num_cpus;
+	int ret;
+
+	ret = get_bsp(&dev, &num_cpus);
+	if (ret < 0)
+		return log_msg_ret("bsp", ret);
+	if (cpu_select == MP_SELECT_ALL || cpu_select == MP_SELECT_BSP ||
+	    cpu_select == ret) {
+		/* Run on BSP first */
+		func(arg);
+	}
+
+	if (!IS_ENABLED(CONFIG_SMP_AP_WORK) ||
+	    !(gd->flags & GD_FLG_SMP_READY)) {
+		/* Allow use of this function on the BSP only */
+		if (cpu_select == MP_SELECT_BSP || !cpu_select)
+			return 0;
+		return -ENOTSUPP;
+	}
+
+	/* Allow up to 1 second for all APs to finish */
+	ret = run_ap_work(&lcb, dev, num_cpus, 1000 /* ms */);
+	if (ret)
+		return log_msg_ret("aps", ret);
+
+	return 0;
+}
+
 int mp_init(void)
 {
 	int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 41b1575f4b..eb49e690f2 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -86,4 +86,37 @@ int mp_init(void);
 /* Set up additional CPUs */
 int x86_mp_init(void);
 
+/**
+ * mp_run_func() - Function to call on the AP
+ *
+ * @arg: Argument to pass
+ */
+typedef void (*mp_run_func)(void *arg);
+
+#if defined(CONFIG_SMP) && !CONFIG_IS_ENABLED(X86_64)
+/**
+ * mp_run_on_cpus() - Run a function on one or all CPUs
+ *
+ * This does not return until all CPUs have completed the work
+ *
+ * Running on anything other than the boot CPU is only supported if
+ * CONFIG_SMP_AP_WORK is enabled
+ *
+ * @cpu_select: CPU to run on (its dev->req_seq value), or MP_SELECT_ALL for
+ *	all, or MP_SELECT_BSP for BSP
+ * @func: Function to run
+ * @arg: Argument to pass to the function
+ * @return 0 on success, -ve on error
+ */
+int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg);
+#else
+static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
+{
+	/* There is only one CPU, so just call the function here */
+	func(arg);
+
+	return 0;
+}
+#endif
+
 #endif /* _X86_MP_H_ */
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 14/25] x86: mp: Park CPUs before running the OS
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (12 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:26   ` Bin Meng
  2020-07-17 14:48 ` [PATCH v6 15/25] x86: mp: Add iterators for CPUs Simon Glass
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

With the new MP features the CPUs are no-longer parked when the OS is run.
Fix this by calling a special function to park them, just before the OS is
started.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v5)

Changes in v5:
- Drop timing in mp_park_aps()

Changes in v3:
- Update the comment for mp_park_aps()

 arch/x86/cpu/cpu.c        |  5 +++++
 arch/x86/cpu/mp_init.c    | 16 ++++++++++++++++
 arch/x86/include/asm/mp.h | 17 +++++++++++++++++
 3 files changed, 38 insertions(+)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index c343586e04..69c14189d1 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -67,6 +67,11 @@ static const char *const x86_vendor_name[] = {
 
 int __weak x86_cleanup_before_linux(void)
 {
+	int ret;
+
+	ret = mp_park_aps();
+	if (ret)
+		return log_msg_ret("park", ret);
 	bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
 			CONFIG_BOOTSTAGE_STASH_SIZE);
 
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index dd6d6bfab7..427ec8fc23 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -668,6 +668,22 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 	return 0;
 }
 
+static void park_this_cpu(void *unused)
+{
+	stop_this_cpu();
+}
+
+int mp_park_aps(void)
+{
+	int ret;
+
+	ret = mp_run_on_cpus(MP_SELECT_APS, park_this_cpu, NULL);
+	if (ret)
+		return log_ret(ret);
+
+	return 0;
+}
+
 int mp_init(void)
 {
 	int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index eb49e690f2..f9d6c8e6bf 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -109,6 +109,15 @@ typedef void (*mp_run_func)(void *arg);
  * @return 0 on success, -ve on error
  */
 int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg);
+
+/**
+ * mp_park_aps() - Park the APs ready for the OS
+ *
+ * This halts all CPUs except the main one, ready for the OS to use them
+ *
+ * @return 0 if OK, -ve on error
+ */
+int mp_park_aps(void);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -117,6 +126,14 @@ static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 
 	return 0;
 }
+
+static inline int mp_park_aps(void)
+{
+	/* No APs to park */
+
+	return 0;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 15/25] x86: mp: Add iterators for CPUs
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (13 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 14/25] x86: mp: Park CPUs before running the OS Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:26   ` Bin Meng
  2020-07-17 14:48 ` [PATCH v6 16/25] x86: mtrr: Use MP calls to list the MTRRs Simon Glass
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

It is convenient to iterate through the CPUs performing work on each one
and processing the result. Add a few iterator functions which handle this.
These can be used by any client code. It can call mp_run_on_cpus() on
each CPU that is returned, handling them one at a time.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v4)

Changes in v4:
- Update mp_next_cpu() to stop if CONFIG_SMP_AP_WORK is not enabled

Changes in v3:
- Add more comments on how the iterators work

 arch/x86/cpu/mp_init.c    | 63 +++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/mp.h | 42 ++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 427ec8fc23..c373c3099a 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -684,6 +684,69 @@ int mp_park_aps(void)
 	return 0;
 }
 
+int mp_first_cpu(int cpu_select)
+{
+	struct udevice *dev;
+	int num_cpus;
+	int ret;
+
+	/*
+	 * This assumes that CPUs are numbered from 0. This function tries to
+	 * avoid assuming the CPU 0 is the boot CPU
+	 */
+	if (cpu_select == MP_SELECT_ALL)
+		return 0;   /* start with the first one */
+
+	ret = get_bsp(&dev, &num_cpus);
+	if (ret < 0)
+		return log_msg_ret("bsp", ret);
+
+	/* Return boot CPU if requested */
+	if (cpu_select == MP_SELECT_BSP)
+		return ret;
+
+	/* Return something other than the boot CPU, if APs requested */
+	if (cpu_select == MP_SELECT_APS && num_cpus > 1)
+		return ret == 0 ? 1 : 0;
+
+	/* Try to check for an invalid value */
+	if (cpu_select < 0 || cpu_select >= num_cpus)
+		return -EINVAL;
+
+	return cpu_select;  /* return the only selected one */
+}
+
+int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+	struct udevice *dev;
+	int num_cpus;
+	int ret;
+	int bsp;
+
+	/* If we selected the BSP or a particular single CPU, we are done */
+	if (!IS_ENABLED(CONFIG_SMP_AP_WORK) || cpu_select == MP_SELECT_BSP ||
+	    cpu_select >= 0)
+		return -EFBIG;
+
+	/* Must be doing MP_SELECT_ALL or MP_SELECT_APS; return the next CPU */
+	ret = get_bsp(&dev, &num_cpus);
+	if (ret < 0)
+		return log_msg_ret("bsp", ret);
+	bsp = ret;
+
+	/* Move to the next CPU */
+	assert(prev_cpu >= 0);
+	ret = prev_cpu + 1;
+
+	/* Skip the BSP if needed */
+	if (cpu_select == MP_SELECT_APS && ret == bsp)
+		ret++;
+	if (ret >= num_cpus)
+		return -EFBIG;
+
+	return ret;
+}
+
 int mp_init(void)
 {
 	int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index f9d6c8e6bf..9379826b6b 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -118,6 +118,33 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg);
  * @return 0 if OK, -ve on error
  */
 int mp_park_aps(void);
+
+/**
+ * mp_first_cpu() - Get the first CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. Call this function first, then
+ * call mp_next_cpu() repeatedly (with the same @cpu_select) until it returns
+ * -EFBIG.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_first_cpu(int cpu_select);
+
+/**
+ * mp_next_cpu() - Get the next CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. After first calling
+ * mp_first_cpu() once, call this function repeatedly until it returns -EFBIG.
+ *
+ * The value of @cpu_select must be the same for all calls and must match the
+ * value passed to mp_first_cpu(), otherwise the behaviour is undefined.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @prev_cpu: Previous value returned by mp_first_cpu()/mp_next_cpu()
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_next_cpu(int cpu_select, int prev_cpu);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -134,6 +161,21 @@ static inline int mp_park_aps(void)
 	return 0;
 }
 
+static inline int mp_first_cpu(int cpu_select)
+{
+	/* We cannot run on any APs, nor a selected CPU */
+	return cpu_select == MP_SELECT_APS ? -EFBIG : MP_SELECT_BSP;
+}
+
+static inline int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+	/*
+	 * When MP is not enabled, there is only one CPU and we did it in
+	 * mp_first_cpu()
+	 */
+	return -EFBIG;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 16/25] x86: mtrr: Use MP calls to list the MTRRs
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (14 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 15/25] x86: mp: Add iterators for CPUs Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 17/25] x86: Don't enable SMP in SPL Simon Glass
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Update the mtrr command to use mp_run_on_cpus() to obtain its information.
Since the selected CPU is the boot CPU this does not change the result,
but it sets the stage for supporting other CPUs.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v2)

Changes in v2:
- Rename mtrr_save_all() to mtrr_read_all()

 arch/x86/cpu/mtrr.c         | 11 +++++++++++
 arch/x86/include/asm/mtrr.h | 30 ++++++++++++++++++++++++++++++
 cmd/x86/mtrr.c              | 25 +++++++++++++++++++++----
 3 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 7ec0733337..c9b4e7d06e 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -21,6 +21,7 @@
 #include <log.h>
 #include <asm/cache.h>
 #include <asm/io.h>
+#include <asm/mp.h>
 #include <asm/msr.h>
 #include <asm/mtrr.h>
 
@@ -63,6 +64,16 @@ static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
 	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
 }
 
+void mtrr_read_all(struct mtrr_info *info)
+{
+	int i;
+
+	for (i = 0; i < MTRR_COUNT; i++) {
+		info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
+		info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
+	}
+}
+
 int mtrr_commit(bool do_caches)
 {
 	struct mtrr_request *req = gd->arch.mtrr_req;
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 212a699c1b..e1f1a44643 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -70,6 +70,26 @@ struct mtrr_state {
 	bool enable_cache;
 };
 
+/**
+ * struct mtrr - Information about a single MTRR
+ *
+ * @base: Base address and MTRR_BASE_TYPE_MASK
+ * @mask: Mask and MTRR_PHYS_MASK_VALID
+ */
+struct mtrr {
+	u64 base;
+	u64 mask;
+};
+
+/**
+ * struct mtrr_info - Information about all MTRRs
+ *
+ * @mtrr: Information about each mtrr
+ */
+struct mtrr_info {
+	struct mtrr mtrr[MTRR_COUNT];
+};
+
 /**
  * mtrr_open() - Prepare to adjust MTRRs
  *
@@ -129,6 +149,16 @@ int mtrr_commit(bool do_caches);
  */
 int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);
 
+/**
+ * mtrr_read_all() - Save all the MTRRs
+ *
+ * This reads all MTRRs from the boot CPU into a struct so they can be loaded
+ * onto other CPUs
+ *
+ * @info: Place to put the MTRR info
+ */
+void mtrr_read_all(struct mtrr_info *info);
+
 #endif
 
 #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 5d25c5802a..f357f58767 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -5,7 +5,9 @@
 
 #include <common.h>
 #include <command.h>
+#include <log.h>
 #include <asm/msr.h>
+#include <asm/mp.h>
 #include <asm/mtrr.h>
 
 static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
@@ -18,19 +20,32 @@ static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
 	"Back",
 };
 
-static int do_mtrr_list(void)
+static void read_mtrrs(void *arg)
 {
+	struct mtrr_info *info = arg;
+
+	mtrr_read_all(info);
+}
+
+static int do_mtrr_list(int cpu_select)
+{
+	struct mtrr_info info;
+	int ret;
 	int i;
 
 	printf("Reg Valid Write-type   %-16s %-16s %-16s\n", "Base   ||",
 	       "Mask   ||", "Size   ||");
+	memset(&info, '\0', sizeof(info));
+	ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
+	if (ret)
+		return log_msg_ret("run", ret);
 	for (i = 0; i < MTRR_COUNT; i++) {
 		const char *type = "Invalid";
 		uint64_t base, mask, size;
 		bool valid;
 
-		base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
-		mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
+		base = info.mtrr[i].base;
+		mask = info.mtrr[i].mask;
 		size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
 		size |= (1 << 12) - 1;
 		size += 1;
@@ -102,11 +117,13 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 		   char *const argv[])
 {
 	const char *cmd;
+	int cpu_select;
 	uint reg;
 
+	cpu_select = MP_SELECT_BSP;
 	cmd = argv[1];
 	if (argc < 2 || *cmd == 'l')
-		return do_mtrr_list();
+		return do_mtrr_list(cpu_select);
 	argc -= 2;
 	argv += 2;
 	if (argc <= 0)
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 17/25] x86: Don't enable SMP in SPL
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (15 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 16/25] x86: mtrr: Use MP calls to list the MTRRs Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 18/25] x86: coral: Update the memory map Simon Glass
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

SMP should be set up in U-Boot where possible, not SPL. Disable it in SPL.
For 64-bit U-Boot we should find a way to allow SMP operations in U-Boot,
but this is somewhat more complicated. For now that is disabled too.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v2)

Changes in v2:
- Add a new patch to avoid enabling SMP in SPL

 arch/x86/cpu/Makefile     | 2 +-
 arch/x86/include/asm/mp.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index ee0499f5d7..16e67e3da2 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -60,7 +60,7 @@ ifndef CONFIG_SYS_COREBOOT
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += irq.o
 endif
 ifndef CONFIG_$(SPL_)X86_64
-obj-$(CONFIG_SMP) += mp_init.o
+obj-$(CONFIG_$(SPL_)SMP) += mp_init.o
 endif
 obj-y += mtrr.o
 obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 9379826b6b..ff49004222 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -93,7 +93,7 @@ int x86_mp_init(void);
  */
 typedef void (*mp_run_func)(void *arg);
 
-#if defined(CONFIG_SMP) && !CONFIG_IS_ENABLED(X86_64)
+#if CONFIG_IS_ENABLED(SMP) && !CONFIG_IS_ENABLED(X86_64)
 /**
  * mp_run_on_cpus() - Run a function on one or all CPUs
  *
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 18/25] x86: coral: Update the memory map
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (16 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 17/25] x86: Don't enable SMP in SPL Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs Simon Glass
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

This currently excludes the temporary memory used to start up the APs.
Add it.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v2)

Changes in v2:
- Add new patch to add AP_DEFAULT_BASE to coral's memory map

 doc/board/google/chromebook_coral.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/board/google/chromebook_coral.rst b/doc/board/google/chromebook_coral.rst
index 40bd9397d4..c39f1e310c 100644
--- a/doc/board/google/chromebook_coral.rst
+++ b/doc/board/google/chromebook_coral.rst
@@ -188,6 +188,7 @@ Partial memory map
     fef00000  1000 CONFIG_BOOTSTAGE_STASH_ADDR
     fef00000       Base of CAR region
 
+       30000       AP_DEFAULT_BASE (used to start up additional CPUs)
        f0000       CONFIG_ROM_TABLE_ADDR
       120000       BSS (defined in u-boot-spl.lds)
       200000       FSP-S (which is run after U-Boot is relocated)
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (17 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 18/25] x86: coral: Update the memory map Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:27   ` Bin Meng
  2020-07-17 14:48 ` [PATCH v6 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU Simon Glass
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

When the boot CPU MTRRs are updated, perform the same update on all other
CPUs so they are kept in sync.

This avoids kernel warnings about mismatched MTRRs.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v2)

Changes in v2:
- Rename function to mtrr_write_all()

 arch/x86/cpu/mtrr.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index c9b4e7d06e..5c567551e5 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -74,10 +74,61 @@ void mtrr_read_all(struct mtrr_info *info)
 	}
 }
 
+void mtrr_write_all(struct mtrr_info *info)
+{
+	struct mtrr_state state;
+	int i;
+
+	for (i = 0; i < MTRR_COUNT; i++) {
+		mtrr_open(&state, true);
+		wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
+		wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
+		mtrr_close(&state, true);
+	}
+}
+
+static void write_mtrrs(void *arg)
+{
+	struct mtrr_info *info = arg;
+
+	mtrr_write_all(info);
+}
+
+static void read_mtrrs(void *arg)
+{
+	struct mtrr_info *info = arg;
+
+	mtrr_read_all(info);
+}
+
+/**
+ * mtrr_copy_to_aps() - Copy the MTRRs from the boot CPU to other CPUs
+ *
+ * @return 0 on success, -ve on failure
+ */
+static int mtrr_copy_to_aps(void)
+{
+	struct mtrr_info info;
+	int ret;
+
+	ret = mp_run_on_cpus(MP_SELECT_BSP, read_mtrrs, &info);
+	if (ret == -ENXIO)
+		return 0;
+	else if (ret)
+		return log_msg_ret("bsp", ret);
+
+	ret = mp_run_on_cpus(MP_SELECT_APS, write_mtrrs, &info);
+	if (ret)
+		return log_msg_ret("bsp", ret);
+
+	return 0;
+}
+
 int mtrr_commit(bool do_caches)
 {
 	struct mtrr_request *req = gd->arch.mtrr_req;
 	struct mtrr_state state;
+	int ret;
 	int i;
 
 	debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
@@ -99,6 +150,12 @@ int mtrr_commit(bool do_caches)
 	mtrr_close(&state, do_caches);
 	debug("mtrr done\n");
 
+	if (gd->flags & GD_FLG_RELOC) {
+		ret = mtrr_copy_to_aps();
+		if (ret)
+			return log_msg_ret("copy", ret);
+	}
+
 	return 0;
 }
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (18 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 21/25] x86: mtrr: Update the command to use the new mtrr calls Simon Glass
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

To enable support for the 'mtrr' command, add a way to perform MTRR
operations on selected CPUs.

This works by setting up a little 'operation' structure and sending it
around the CPUs for action.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

(no changes since v2)

Changes in v2:
- Keep things building by temporarily renaming the function in cmd/

 arch/x86/cpu/mtrr.c         | 81 +++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/mtrr.h | 21 ++++++++++
 cmd/x86/mtrr.c              |  6 +--
 3 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 5c567551e5..2468d88a80 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -221,3 +221,84 @@ int mtrr_set_next_var(uint type, uint64_t start, uint64_t size)
 
 	return 0;
 }
+
+/** enum mtrr_opcode - supported operations for mtrr_do_oper() */
+enum mtrr_opcode {
+	MTRR_OP_SET,
+	MTRR_OP_SET_VALID,
+};
+
+/**
+ * struct mtrr_oper - An MTRR operation to perform on a CPU
+ *
+ * @opcode: Indicates operation to perform
+ * @reg: MTRR reg number to select (0-7, -1 = all)
+ * @valid: Valid value to write for MTRR_OP_SET_VALID
+ * @base: Base value to write for MTRR_OP_SET
+ * @mask: Mask value to write for MTRR_OP_SET
+ */
+struct mtrr_oper {
+	enum mtrr_opcode opcode;
+	int reg;
+	bool valid;
+	u64 base;
+	u64 mask;
+};
+
+static void mtrr_do_oper(void *arg)
+{
+	struct mtrr_oper *oper = arg;
+	u64 mask;
+
+	switch (oper->opcode) {
+	case MTRR_OP_SET_VALID:
+		mask = native_read_msr(MTRR_PHYS_MASK_MSR(oper->reg));
+		if (oper->valid)
+			mask |= MTRR_PHYS_MASK_VALID;
+		else
+			mask &= ~MTRR_PHYS_MASK_VALID;
+		wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), mask);
+		break;
+	case MTRR_OP_SET:
+		wrmsrl(MTRR_PHYS_BASE_MSR(oper->reg), oper->base);
+		wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), oper->mask);
+		break;
+	}
+}
+
+static int mtrr_start_op(int cpu_select, struct mtrr_oper *oper)
+{
+	struct mtrr_state state;
+	int ret;
+
+	mtrr_open(&state, true);
+	ret = mp_run_on_cpus(cpu_select, mtrr_do_oper, oper);
+	mtrr_close(&state, true);
+	if (ret)
+		return log_msg_ret("run", ret);
+
+	return 0;
+}
+
+int mtrr_set_valid(int cpu_select, int reg, bool valid)
+{
+	struct mtrr_oper oper;
+
+	oper.opcode = MTRR_OP_SET_VALID;
+	oper.reg = reg;
+	oper.valid = valid;
+
+	return mtrr_start_op(cpu_select, &oper);
+}
+
+int mtrr_set(int cpu_select, int reg, u64 base, u64 mask)
+{
+	struct mtrr_oper oper;
+
+	oper.opcode = MTRR_OP_SET;
+	oper.reg = reg;
+	oper.base = base;
+	oper.mask = mask;
+
+	return mtrr_start_op(cpu_select, &oper);
+}
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index e1f1a44643..48db1dd82f 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -159,6 +159,27 @@ int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);
  */
 void mtrr_read_all(struct mtrr_info *info);
 
+/**
+ * mtrr_set_valid() - Set the valid flag for a selected MTRR and CPU(s)
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @reg: MTRR register to write (0-7)
+ * @valid: Valid flag to write
+ * @return 0 on success, -ve on error
+ */
+int mtrr_set_valid(int cpu_select, int reg, bool valid);
+
+/**
+ * mtrr_set() - Set the valid flag for a selected MTRR and CPU(s)
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @reg: MTRR register to write (0-7)
+ * @base: Base address and MTRR_BASE_TYPE_MASK
+ * @mask: Mask and MTRR_PHYS_MASK_VALID
+ * @return 0 on success, -ve on error
+ */
+int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
+
 #endif
 
 #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index f357f58767..46ef6a2830 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -96,7 +96,7 @@ static int do_mtrr_set(uint reg, int argc, char *const argv[])
 	return 0;
 }
 
-static int mtrr_set_valid(int reg, bool valid)
+static int mtrr_set_valid_(int reg, bool valid)
 {
 	struct mtrr_state state;
 	uint64_t mask;
@@ -134,9 +134,9 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 		return CMD_RET_USAGE;
 	}
 	if (*cmd == 'e')
-		return mtrr_set_valid(reg, true);
+		return mtrr_set_valid_(reg, true);
 	else if (*cmd == 'd')
-		return mtrr_set_valid(reg, false);
+		return mtrr_set_valid_(reg, false);
 	else if (*cmd == 's')
 		return do_mtrr_set(reg, argc - 1, argv + 1);
 	else
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 21/25] x86: mtrr: Update the command to use the new mtrr calls
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (19 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 22/25] x86: mtrr: Restructure so command execution is in one place Simon Glass
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Use the multi-CPU calls to set the MTRR values. This still supports only
the boot CPU for now.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v2)

Changes in v2:
- Drop the renamed mtrr_set_valid_() instead of mtrr_set_valid()

 cmd/x86/mtrr.c | 34 ++++++++--------------------------
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 46ef6a2830..b047a9897c 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -59,14 +59,14 @@ static int do_mtrr_list(int cpu_select)
 	return 0;
 }
 
-static int do_mtrr_set(uint reg, int argc, char *const argv[])
+static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
 {
 	const char *typename = argv[0];
-	struct mtrr_state state;
 	uint32_t start, size;
 	uint64_t base, mask;
 	int i, type = -1;
 	bool valid;
+	int ret;
 
 	if (argc < 3)
 		return CMD_RET_USAGE;
@@ -88,27 +88,9 @@ static int do_mtrr_set(uint reg, int argc, char *const argv[])
 	if (valid)
 		mask |= MTRR_PHYS_MASK_VALID;
 
-	mtrr_open(&state, true);
-	wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
-	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-	mtrr_close(&state, true);
-
-	return 0;
-}
-
-static int mtrr_set_valid_(int reg, bool valid)
-{
-	struct mtrr_state state;
-	uint64_t mask;
-
-	mtrr_open(&state, true);
-	mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
-	if (valid)
-		mask |= MTRR_PHYS_MASK_VALID;
-	else
-		mask &= ~MTRR_PHYS_MASK_VALID;
-	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-	mtrr_close(&state, true);
+	ret = mtrr_set(cpu_select, reg, base, mask);
+	if (ret)
+		return CMD_RET_FAILURE;
 
 	return 0;
 }
@@ -134,11 +116,11 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 		return CMD_RET_USAGE;
 	}
 	if (*cmd == 'e')
-		return mtrr_set_valid_(reg, true);
+		return mtrr_set_valid(cpu_select, reg, true);
 	else if (*cmd == 'd')
-		return mtrr_set_valid_(reg, false);
+		return mtrr_set_valid(cpu_select, reg, false);
 	else if (*cmd == 's')
-		return do_mtrr_set(reg, argc - 1, argv + 1);
+		return do_mtrr_set(cpu_select, reg, argc - 1, argv + 1);
 	else
 		return CMD_RET_USAGE;
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 22/25] x86: mtrr: Restructure so command execution is in one place
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (20 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 21/25] x86: mtrr: Update the command to use the new mtrr calls Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU Simon Glass
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

At present do_mtrr() does the 'list' subcommand at the top and the rest
below. Update it to do them all in the same place so we can (in a later
patch) add parsing of the CPU number for all subcommands.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v1)

 cmd/x86/mtrr.c | 55 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b047a9897c..b51b1cd7e2 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -98,31 +98,48 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
 static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 		   char *const argv[])
 {
-	const char *cmd;
+	int cmd;
 	int cpu_select;
 	uint reg;
+	int ret;
 
 	cpu_select = MP_SELECT_BSP;
-	cmd = argv[1];
-	if (argc < 2 || *cmd == 'l')
+	argc--;
+	argv++;
+	cmd = argv[0] ? *argv[0] : 0;
+	if (argc < 1 || !cmd) {
+		cmd = 'l';
+		reg = 0;
+	} else {
+		if (argc < 2)
+			return CMD_RET_USAGE;
+		reg = simple_strtoul(argv[1], NULL, 16);
+		if (reg >= MTRR_COUNT) {
+			printf("Invalid register number\n");
+			return CMD_RET_USAGE;
+		}
+	}
+	if (cmd == 'l') {
 		return do_mtrr_list(cpu_select);
-	argc -= 2;
-	argv += 2;
-	if (argc <= 0)
-		return CMD_RET_USAGE;
-	reg = simple_strtoul(argv[0], NULL, 16);
-	if (reg >= MTRR_COUNT) {
-		printf("Invalid register number\n");
-		return CMD_RET_USAGE;
+	} else {
+		switch (cmd) {
+		case 'e':
+			ret = mtrr_set_valid(cpu_select, reg, true);
+			break;
+		case 'd':
+			ret = mtrr_set_valid(cpu_select, reg, false);
+			break;
+		case 's':
+			ret = do_mtrr_set(cpu_select, reg, argc - 2, argv + 2);
+			break;
+		default:
+			return CMD_RET_USAGE;
+		}
+		if (ret) {
+			printf("Operation failed (err=%d)\n", ret);
+			return CMD_RET_FAILURE;
+		}
 	}
-	if (*cmd == 'e')
-		return mtrr_set_valid(cpu_select, reg, true);
-	else if (*cmd == 'd')
-		return mtrr_set_valid(cpu_select, reg, false);
-	else if (*cmd == 's')
-		return do_mtrr_set(cpu_select, reg, argc - 1, argv + 1);
-	else
-		return CMD_RET_USAGE;
 
 	return 0;
 }
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (21 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 22/25] x86: mtrr: Restructure so command execution is in one place Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 24/25] x86: mp: Add more comments to the module Simon Glass
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Add a -c option to mtrr to allow any CPU to be updated with this command.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v3)

Changes in v3:
- Mention that the CPU number is in hex

 cmd/x86/mtrr.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b51b1cd7e2..d8a7e56d5a 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -104,6 +104,17 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 	int ret;
 
 	cpu_select = MP_SELECT_BSP;
+	if (argc >= 3 && !strcmp("-c", argv[1])) {
+		const char *cpustr;
+
+		cpustr = argv[2];
+		if (*cpustr == 'a')
+			cpu_select = MP_SELECT_ALL;
+		else
+			cpu_select = simple_strtol(cpustr, NULL, 16);
+		argc -= 2;
+		argv += 2;
+	}
 	argc--;
 	argv++;
 	cmd = argv[0] ? *argv[0] : 0;
@@ -145,11 +156,14 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 }
 
 U_BOOT_CMD(
-	mtrr,	6,	1,	do_mtrr,
+	mtrr,	8,	1,	do_mtrr,
 	"Use x86 memory type range registers (32-bit only)",
 	"[list]        - list current registers\n"
 	"set <reg> <type> <start> <size>   - set a register\n"
 	"\t<type> is Uncacheable, Combine, Through, Protect, Back\n"
 	"disable <reg>      - disable a register\n"
-	"enable <reg>       - enable a register"
+	"enable <reg>       - enable a register\n"
+	"\n"
+	"Precede command with '-c <n>|all' to access a particular hex CPU, e.g.\n"
+	"   mtrr -c all list; mtrr -c 2e list"
 );
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 24/25] x86: mp: Add more comments to the module
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (22 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-17 14:48 ` [PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU Simon Glass
  2020-07-20  1:46 ` [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Bin Meng
  25 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Add a description of how this module works and also some missing function
comments.

Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

(no changes since v3)

Changes in v3:
- Remove stray asterisk from comments
- Drop mention of cpu_map which was handled in a previous patch

Changes in v2:
- Add a new patch with more comments

 arch/x86/cpu/mp_init.c    | 91 ++++++++++++++++++++++++++++++++++++++-
 arch/x86/include/asm/mp.h | 14 +++++-
 2 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index c373c3099a..d2f1ee38cf 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -32,13 +32,99 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * Setting up multiprocessing
+ *
+ * See https://www.intel.com/content/www/us/en/intelligent-systems/intel-boot-loader-development-kit/minimal-intel-architecture-boot-loader-paper.html
+ *
+ * Note that this file refers to the boot CPU (the one U-Boot is running on) as
+ * the BSP (BootStrap Processor) and the others as APs (Application Processors).
+ *
+ * This module works by loading some setup code into RAM at AP_DEFAULT_BASE and
+ * telling each AP to execute it. The code that each AP runs is in
+ * sipi_vector.S (see ap_start16) which includes a struct sipi_params at the
+ * end of it. Those parameters are set up by the C code.
+
+ * Setting up is handled by load_sipi_vector(). It inits the common block of
+ * parameters (sipi_params) which tell the APs what to do. This block includes
+ * microcode and the MTTRs (Memory-Type-Range Registers) from the main CPU.
+ * There is also an ap_count which each AP increments as it starts up, so the
+ * BSP can tell how many checked in.
+ *
+ * The APs are started with a SIPI (Startup Inter-Processor Interrupt) which
+ * tells an AP to start executing at a particular address, in this case
+ * AP_DEFAULT_BASE which contains the code copied from ap_start16. This protocol
+ * is handled by start_aps().
+ *
+ * After being started, each AP runs the code in ap_start16, switches to 32-bit
+ * mode, runs the code at ap_start, then jumps to c_handler which is ap_init().
+ * This runs a very simple 'flight plan' described in mp_steps(). This sets up
+ * the CPU and waits for further instructions by looking at its entry in
+ * ap_callbacks[]. Note that the flight plan is only actually run for each CPU
+ * in bsp_do_flight_plan(): once the BSP completes each flight record, it sets
+ * mp_flight_record->barrier to 1 to allow the APs to executed the record one
+ * by one.
+ *
+ * CPUS are numbered sequentially from 0 using the device tree:
+ *
+ *	cpus {
+ *		u-boot,dm-pre-reloc;
+ *		#address-cells = <1>;
+ *		#size-cells = <0>;
+ *
+ *		cpu at 0 {
+ *			u-boot,dm-pre-reloc;
+ *			device_type = "cpu";
+ *			compatible = "intel,apl-cpu";
+ *			reg = <0>;
+ *			intel,apic-id = <0>;
+ *		};
+ *
+ *		cpu at 1 {
+ *			device_type = "cpu";
+ *			compatible = "intel,apl-cpu";
+ *			reg = <1>;
+ *			intel,apic-id = <2>;
+ *		};
+ *
+ * Here the 'reg' property is the CPU number and then is placed in dev->req_seq
+ * so that we can index into ap_callbacks[] using that. The APIC ID is different
+ * and may not be sequential (it typically is if hyperthreading is supported).
+ *
+ * Once APs are inited they wait in ap_wait_for_instruction() for instructions.
+ * Instructions come in the form of a function to run. This logic is in
+ * mp_run_on_cpus() which supports running on any one AP, all APs, just the BSP
+ * or all CPUs. The BSP logic is handled directly in mp_run_on_cpus(), by
+ * calling the function. For the APs, callback information is stored in a
+ * single, common struct mp_callback and a pointer to this is written to each
+ * AP's slot in ap_callbacks[] by run_ap_work(). All APs get the message even
+ * if it is only for one of them. When an AP notices a message it checks whether
+ * it should call the function (see check in ap_wait_for_instruction()) and then
+ * does so if needed. After that it sets its slot to NULL to indicate it is
+ * done.
+ *
+ * While U-Boot is running it can use mp_run_on_cpus() to run code on the APs.
+ * An example of this is the 'mtrr' command which allows reading and changing
+ * the MTRRs on all CPUs.
+ *
+ * Before U-Boot exits it calls mp_park_aps() which tells all CPUs to halt by
+ * executing a 'hlt' instruction. That allows them to be used by Linux when it
+ * starts up.
+ */
+
 /* This also needs to match the sipi.S assembly code for saved MSR encoding */
-struct saved_msr {
+struct __packed saved_msr {
 	uint32_t index;
 	uint32_t lo;
 	uint32_t hi;
-} __packed;
+};
 
+/**
+ * struct mp_flight_plan - Holds the flight plan
+ *
+ * @num_records: Number of flight records
+ * @records: Pointer to each record
+ */
 struct mp_flight_plan {
 	int num_records;
 	struct mp_flight_record *records;
@@ -59,6 +145,7 @@ struct mp_callback {
 	int logical_cpu_number;
 };
 
+/* Stores the flight plan so that APs can find it */
 static struct mp_flight_plan mp_info;
 
 /*
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index ff49004222..5f9b8c6564 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -36,6 +36,14 @@ typedef int (*mp_callback_t)(struct udevice *cpu, void *arg);
  *
  * Note that ap_call() and bsp_call() can be NULL. In the NULL case the
  * callback will just not be called.
+ *
+ * @barrier: Ensures that the BSP and AP don't run the flight record at the same
+ *	time
+ * @cpus_entered: Counts the number of APs that have run this record
+ * @ap_call: Function for the APs to call
+ * @ap_arg: Argument to pass to @ap_call
+ * @bsp_call: Function for the BSP to call
+ * @bsp_arg: Argument to pass to @bsp_call
  */
 struct mp_flight_record {
 	atomic_t barrier;
@@ -83,7 +91,11 @@ struct mp_flight_record {
  */
 int mp_init(void);
 
-/* Set up additional CPUs */
+/**
+ * x86_mp_init() - Set up additional CPUs
+ *
+ * @returns < 0 on error, 0 on success.
+ */
 int x86_mp_init(void);
 
 /**
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (23 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 24/25] x86: mp: Add more comments to the module Simon Glass
@ 2020-07-17 14:48 ` Simon Glass
  2020-07-20  1:28   ` Bin Meng
  2020-07-20  1:46 ` [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Bin Meng
  25 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2020-07-17 14:48 UTC (permalink / raw)
  To: u-boot

Update this command so it can list the MTRRs on a selected CPU. If
'-c all' is used, then all CPUs are listed.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
---

Changes in v6:
- Rebase to x86/master

 cmd/x86/mtrr.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index d8a7e56d5a..e118bba5a2 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -131,7 +131,27 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
 		}
 	}
 	if (cmd == 'l') {
-		return do_mtrr_list(cpu_select);
+		bool first;
+		int i;
+
+		i = mp_first_cpu(cpu_select);
+		if (i < 0) {
+			printf("Invalid CPU (err=%d)\n", i);
+			return CMD_RET_FAILURE;
+		}
+		first = true;
+		for (; i >= 0; i = mp_next_cpu(cpu_select, i)) {
+			if (!first)
+				printf("\n");
+			printf("CPU %d:\n", i);
+			ret = do_mtrr_list(i);
+			if (ret) {
+				printf("Failed to read CPU %d (err=%d)\n", i,
+				       ret);
+				return CMD_RET_FAILURE;
+			}
+			first = false;
+		}
 	} else {
 		switch (cmd) {
 		case 'e':
-- 
2.28.0.rc0.105.gf9edc3c819-goog

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 10/25] x86: mp: Support APs waiting for instructions
  2020-07-17 14:48 ` [PATCH v6 10/25] x86: mp: Support APs waiting for instructions Simon Glass
@ 2020-07-20  1:22   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:22 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> At present the APs (non-boot CPUs) are inited once and then parked ready
> for the OS to use them. However in some cases we want to send new requests
> through, such as to change MTRRs and keep them consistent across CPUs.
>
> Change the last state of the flight plan to go into a wait loop, accepting
> instructions from the main CPU.
>
> Drop cpu_map since it is not used.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> (no changes since v4)
>
> Changes in v4:
> - Add a Kconfig to control this feature, enabled only on APL
>
> Changes in v3:
> - s/slow/slot/
> - Use C code instead of assembler to read/write callback pointers
> - Update commit message to mention dropping of cpu_map
>
> Changes in v2:
> - Add more comments
>
>  arch/x86/Kconfig                |   7 ++
>  arch/x86/cpu/apollolake/Kconfig |   1 +
>  arch/x86/cpu/mp_init.c          | 123 +++++++++++++++++++++++++++++---
>  arch/x86/include/asm/mp.h       |  11 +++
>  4 files changed, 134 insertions(+), 8 deletions(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state
  2020-07-17 14:48 ` [PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state Simon Glass
@ 2020-07-20  1:23   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:23 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> Allow keeping track of whether all CPUs have been enabled yet. This allows
> us to know whether other CPUs need to be considered when updating
> CPU-specific settings such as MTRRs on x86.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Rename flag to GD_FLG_SMP_READY
>
>  include/asm-generic/global_data.h | 1 +
>  1 file changed, 1 insertion(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs
  2020-07-17 14:48 ` [PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs Simon Glass
@ 2020-07-20  1:25   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:25 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> Add a way to run a function on a selection of CPUs. This supports either
> a single CPU, all CPUs, just the main CPU or just the 'APs', in Intel
> terminology.
>
> It works by writing into a mailbox and then waiting for the CPUs to notice
> it, take action and indicate they are done.
>
> When SMP is not yet enabled, this just calls the function on the main CPU.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> (no changes since v4)
>
> Changes in v4:
> - Only enable this feature of CONFIG_SMP_AP_WORK is enabled
> - Allow running on the BSP if SMP is not enabled
>
> Changes in v3:
> - Add a comment to run_ap_work()
> - Rename flag to GD_FLG_SMP_READY
> - Update the comment for run_ap_work() to explain logical_cpu_number
> - Clarify meaning of @cpu_select in mp_run_on_cpus() comment
>
>  arch/x86/cpu/mp_init.c    | 107 +++++++++++++++++++++++++++++++++++---
>  arch/x86/include/asm/mp.h |  33 ++++++++++++
>  2 files changed, 134 insertions(+), 6 deletions(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 14/25] x86: mp: Park CPUs before running the OS
  2020-07-17 14:48 ` [PATCH v6 14/25] x86: mp: Park CPUs before running the OS Simon Glass
@ 2020-07-20  1:26   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:26 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> With the new MP features the CPUs are no-longer parked when the OS is run.
> Fix this by calling a special function to park them, just before the OS is
> started.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> (no changes since v5)
>
> Changes in v5:
> - Drop timing in mp_park_aps()
>
> Changes in v3:
> - Update the comment for mp_park_aps()
>
>  arch/x86/cpu/cpu.c        |  5 +++++
>  arch/x86/cpu/mp_init.c    | 16 ++++++++++++++++
>  arch/x86/include/asm/mp.h | 17 +++++++++++++++++
>  3 files changed, 38 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 15/25] x86: mp: Add iterators for CPUs
  2020-07-17 14:48 ` [PATCH v6 15/25] x86: mp: Add iterators for CPUs Simon Glass
@ 2020-07-20  1:26   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:26 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> It is convenient to iterate through the CPUs performing work on each one
> and processing the result. Add a few iterator functions which handle this.
> These can be used by any client code. It can call mp_run_on_cpus() on
> each CPU that is returned, handling them one at a time.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> (no changes since v4)
>
> Changes in v4:
> - Update mp_next_cpu() to stop if CONFIG_SMP_AP_WORK is not enabled
>
> Changes in v3:
> - Add more comments on how the iterators work
>
>  arch/x86/cpu/mp_init.c    | 63 +++++++++++++++++++++++++++++++++++++++
>  arch/x86/include/asm/mp.h | 42 ++++++++++++++++++++++++++
>  2 files changed, 105 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs
  2020-07-17 14:48 ` [PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs Simon Glass
@ 2020-07-20  1:27   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:27 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> When the boot CPU MTRRs are updated, perform the same update on all other
> CPUs so they are kept in sync.
>
> This avoids kernel warnings about mismatched MTRRs.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Rename function to mtrr_write_all()
>
>  arch/x86/cpu/mtrr.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU
  2020-07-17 14:48 ` [PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU Simon Glass
@ 2020-07-20  1:28   ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:28 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> Update this command so it can list the MTRRs on a selected CPU. If
> '-c all' is used, then all CPUs are listed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
> ---
>
> Changes in v6:
> - Rebase to x86/master
>
>  cmd/x86/mtrr.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs
  2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
                   ` (24 preceding siblings ...)
  2020-07-17 14:48 ` [PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU Simon Glass
@ 2020-07-20  1:46 ` Bin Meng
  25 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2020-07-20  1:46 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 17, 2020 at 10:48 PM Simon Glass <sjg@chromium.org> wrote:
>
> At present MTRRs are mirrored to the secondary CPUs only once, as those
> CPUs are started up. But U-Boot may add more MTRRs later, e.g. if it
> decides that a video console must be set up.
>
> This series enhances the x86 multi-processor support to allow MTRRs to
> be updated at any time. It also updates the 'mtrr' command to support
> setting the MTRRs on CPUs other than the boot CPU.
>
> Changes in v6:
> - Rebase to x86/master
>
> Changes in v5:
> - Drop timing in mp_park_aps()
>

series applied to u-boot-x86, thanks!

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2020-07-20  1:46 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-17 14:48 [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Simon Glass
2020-07-17 14:48 ` [PATCH v6 01/25] x86: mp_init: Switch to livetree Simon Glass
2020-07-17 14:48 ` [PATCH v6 02/25] x86: Move MP code into mp_init Simon Glass
2020-07-17 14:48 ` [PATCH v6 03/25] x86: mp_init: Avoid declarations in header files Simon Glass
2020-07-17 14:48 ` [PATCH v6 04/25] x86: mp_init: Switch parameter names in start_aps() Simon Glass
2020-07-17 14:48 ` [PATCH v6 05/25] x86: mp_init: Drop the num_cpus static variable Simon Glass
2020-07-17 14:48 ` [PATCH v6 06/25] x86: mtrr: Fix 'ensable' typo Simon Glass
2020-07-17 14:48 ` [PATCH v6 07/25] x86: mp_init: Set up the CPU numbers at the start Simon Glass
2020-07-17 14:48 ` [PATCH v6 08/25] x86: mp_init: Adjust bsp_init() to return more information Simon Glass
2020-07-17 14:48 ` [PATCH v6 09/25] x86: cpu: Remove unnecessary #ifdefs Simon Glass
2020-07-17 14:48 ` [PATCH v6 10/25] x86: mp: Support APs waiting for instructions Simon Glass
2020-07-20  1:22   ` Bin Meng
2020-07-17 14:48 ` [PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state Simon Glass
2020-07-20  1:23   ` Bin Meng
2020-07-17 14:48 ` [PATCH v6 12/25] x86: Set the SMP flag when MP init is complete Simon Glass
2020-07-17 14:48 ` [PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs Simon Glass
2020-07-20  1:25   ` Bin Meng
2020-07-17 14:48 ` [PATCH v6 14/25] x86: mp: Park CPUs before running the OS Simon Glass
2020-07-20  1:26   ` Bin Meng
2020-07-17 14:48 ` [PATCH v6 15/25] x86: mp: Add iterators for CPUs Simon Glass
2020-07-20  1:26   ` Bin Meng
2020-07-17 14:48 ` [PATCH v6 16/25] x86: mtrr: Use MP calls to list the MTRRs Simon Glass
2020-07-17 14:48 ` [PATCH v6 17/25] x86: Don't enable SMP in SPL Simon Glass
2020-07-17 14:48 ` [PATCH v6 18/25] x86: coral: Update the memory map Simon Glass
2020-07-17 14:48 ` [PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs Simon Glass
2020-07-20  1:27   ` Bin Meng
2020-07-17 14:48 ` [PATCH v6 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU Simon Glass
2020-07-17 14:48 ` [PATCH v6 21/25] x86: mtrr: Update the command to use the new mtrr calls Simon Glass
2020-07-17 14:48 ` [PATCH v6 22/25] x86: mtrr: Restructure so command execution is in one place Simon Glass
2020-07-17 14:48 ` [PATCH v6 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU Simon Glass
2020-07-17 14:48 ` [PATCH v6 24/25] x86: mp: Add more comments to the module Simon Glass
2020-07-17 14:48 ` [PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU Simon Glass
2020-07-20  1:28   ` Bin Meng
2020-07-20  1:46 ` [PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs Bin Meng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.