mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <ahmad@a3f.at>
To: barebox@lists.infradead.org
Subject: [PATCH 4/5] commands: smc: verify PSCI_POWER_ON with interprocessor handshake
Date: Fri, 15 Nov 2019 08:52:56 +0100	[thread overview]
Message-ID: <20191115075257.24079-4-ahmad@a3f.at> (raw)
In-Reply-To: <20191115075257.24079-1-ahmad@a3f.at>

The use of psci_printf here, at least for the phytec-phycore-imx7,
is racy, because access to the UART is not synchronized. This may
lead to characters being swallowed and most certainly to garbled
text. One way around this would be using separate UART ports for
each core or even more generically, just dropping psci_printf and
resorting to inter-core communication over shared-memory to check
whether code execution succeeded.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 arch/arm/cpu/Makefile |  2 +-
 commands/smc.c        | 61 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 09b3bc2eeab9..75cd42a5e271 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -2,7 +2,7 @@ obj-y += cpu.o
 
 obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions$(S64).o interrupts$(S64).o
 obj-$(CONFIG_MMU) += mmu$(S64).o mmu-common.o
-lwl-y += lowlevel$(S64).o
+obj-pbl-y += lowlevel$(S64).o
 obj-pbl-$(CONFIG_MMU) += mmu-early$(S64).o
 obj-pbl-$(CONFIG_CPU_32v7) += hyp.o
 AFLAGS_hyp.o :=-Wa,-march=armv7-a -Wa,-mcpu=all
diff --git a/commands/smc.c b/commands/smc.c
index eb96e581dc02..997103676eba 100644
--- a/commands/smc.c
+++ b/commands/smc.c
@@ -3,23 +3,47 @@
 #include <common.h>
 #include <command.h>
 #include <getopt.h>
+#include <dma.h>
+#include <linux/iopoll.h>
+#include <asm/barebox-arm-head.h>
 
 #include <asm/psci.h>
 #include <asm/secure.h>
 #include <linux/arm-smccc.h>
 
-static void second_entry(void)
+#define STACK_SIZE 100
+#define HANDSHAKE_MAGIC	0xBA12EB0C
+#define ERROR_MAGIC	0xDEADBEEF
+
+struct cpu_context {
+	unsigned long stack[STACK_SIZE];
+	long handshake;
+};
+
+static void noinline cpu_handshake(long *handshake)
 {
 	struct arm_smccc_res res;
 
-	psci_printf("2nd CPU online, now turn off again\n");
+	writel(HANDSHAKE_MAGIC, handshake);
 
 	arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_OFF,
 		      0, 0, 0, 0, 0, 0, 0, &res);
 
-	psci_printf("2nd CPU still alive?\n");
+	writel(ERROR_MAGIC, handshake);
+
+	while (1)
+		;
+}
+
+static void __naked second_entry(unsigned long arg0)
+{
+	struct cpu_context *context = (void*)arg0;
+
+	arm_cpu_lowlevel_init();
+	arm_setup_stack((unsigned long)&context->stack[STACK_SIZE]);
+	barrier();
 
-	while (1);
+	cpu_handshake(&context->handshake);
 }
 
 static const char *psci_xlate_str(long err)
@@ -54,6 +78,8 @@ static const char *psci_xlate_str(long err)
        return errno_string;
 }
 
+static struct cpu_context *context;
+
 static int do_smc(int argc, char *argv[])
 {
 	long ret;
@@ -79,12 +105,35 @@ static int do_smc(int argc, char *argv[])
 			printf("found psci version %ld.%ld\n", res.a0 >> 16, res.a0 & 0xffff);
 			break;
 		case 'c':
+			if (!context)
+				context = dma_alloc_coherent(sizeof(*context),
+							     DMA_ADDRESS_BROKEN);
+
+			if (!context) {
+				printf("Out of memory\n");
+				return COMMAND_ERROR;
+			}
+
 			arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_ON,
-				      1, (unsigned long)second_entry, 0, 0, 0, 0, 0, &res);
+				      1, (unsigned long)second_entry, (unsigned long)context,
+				      0, 0, 0, 0, &res);
 			ret = (long)res.a0;
 			printf("CPU_ON returns with: %s\n", psci_xlate_str(ret));
-			if (ret)
+			if (ret) {
+				unsigned long magic = readl(&context->handshake);
+				if (magic == ERROR_MAGIC)
+					printf("Turning off CPU had failed\n");
 				return COMMAND_ERROR;
+			}
+
+			readl_poll_timeout(&context->handshake, ret,
+					   ret != HANDSHAKE_MAGIC, USEC_PER_SEC);
+			if (ret == 0) {
+				printf("Second CPU handshake timed out.\n");
+				return COMMAND_ERROR;
+			}
+
+			printf("Second CPU handshake successful.\n");
 		}
 	}
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2019-11-15  7:53 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-15  7:52 [PATCH 1/5] ARM: psci: factor out smc command into commands/ Ahmad Fatoum
2019-11-15  7:52 ` [PATCH 2/5] ARM: psci: properly wire in command help Ahmad Fatoum
2019-11-15  7:52 ` [PATCH 3/5] commands: psci: make locally-used function static Ahmad Fatoum
2019-11-15  7:52 ` Ahmad Fatoum [this message]
2019-11-15  7:52 ` [PATCH 5/5] commands: smc: make command usable when ARM_PSCI is undefined Ahmad Fatoum
2019-11-19 10:58 ` [PATCH 1/5] ARM: psci: factor out smc command into commands/ Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191115075257.24079-4-ahmad@a3f.at \
    --to=ahmad@a3f.at \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox