summaryrefslogtreecommitdiff
path: root/src/arch/arm64/include/armv8
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-09-06 02:31:30 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-03-27 08:05:20 +0100
commit9fd4dc73bc1fb0fc7d146c6bf2d0e6a9db1fc22c (patch)
treebb659d35aeba31c47cfe77c872cadebf41c3ada4 /src/arch/arm64/include/armv8
parent27d4266a44a2a39a589145dd234526f94a206eec (diff)
arm64: add devicetree based CPU startup
This adds SMP bring up support for arm64 cpus. It's reliant on DEVICE_PATH_CPU devices in the devicetree. Then for each enabled device it attempts to start then initialize each CPU. Additionally, there is a cpu_action construct which allows for running actions on an individual cpu. BUG=chrome-os-partner:31761 BRANCH=None TEST=Booted both cores on ryu into linux. Change-Id: I3e42fb668034c27808d706427a26be1558ad2af1 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: a733fd566a8e5793da5ff28f9c16c213f411372e Original-Change-Id: I407eabd0b6985fc4e86de57a9e034548ec8f3d81 Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/216925 Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9042 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/arch/arm64/include/armv8')
-rw-r--r--src/arch/arm64/include/armv8/arch/cpu.h83
1 files changed, 69 insertions, 14 deletions
diff --git a/src/arch/arm64/include/armv8/arch/cpu.h b/src/arch/arm64/include/armv8/arch/cpu.h
index b2c28f6d02..8a8e3b6c91 100644
--- a/src/arch/arm64/include/armv8/arch/cpu.h
+++ b/src/arch/arm64/include/armv8/arch/cpu.h
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright 2012 Google Inc.
+ * Copyright 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,32 +25,77 @@
#if !defined(__PRE_RAM__)
#include <device/device.h>
+enum {
+ CPU_ID_END = 0x00000000,
+};
+
+struct cpu_device_id {
+ uint32_t midr;
+};
+
struct cpu_driver {
+ /* This is excessive as init() is the only one called. */
struct device_operations *ops;
- struct cpu_device_id *id_table;
+ const struct cpu_device_id *id_table;
};
-struct thread;
+/* Action to run. */
+struct cpu_action {
+ void (*run)(void *arg);
+ void *arg;
+};
+
+/*
+ * Actions are queued to 'todo'. When picked up 'todo' is cleared. The
+ * 'completed' field is set to the original 'todo' value when the action
+ * is complete.
+ */
+struct cpu_action_queue {
+ struct cpu_action *todo;
+ struct cpu_action *completed;
+};
struct cpu_info {
device_t cpu;
- unsigned long index;
-#if CONFIG_COOP_MULTITASKING
- struct thread *thread;
-#endif
+ struct cpu_action_queue action_queue;
+ unsigned int online;
+ /* Current assumption is that id matches smp_processor_id(). */
+ unsigned int id;
};
-#endif
-
+/* Obtain cpu_info for current executing CPU. */
struct cpu_info *cpu_info(void);
+/* Control routines for starting CPUs. */
+struct cpu_control_ops {
+ /* Return the maximum number of CPUs supported. */
+ size_t (*total_cpus)(void);
+ /*
+ * Start the requested CPU and have it start running entry().
+ * Returns 0 on success, < 0 on error.
+ */
+ int (*start_cpu)(unsigned int id, void (*entry)(void));
+};
+
/*
- * Returns logical cpu in range [0:MAX_CPUS). SoC should define this.
- * Additionally, this is needed early in arm64 init so it should not
- * rely on a stack. Standard clobber list is fair game: x0-x7 and x0
- * returns the logical cpu number.
+ * Initialize all DEVICE_PATH_CPUS under the DEVICE_PATH_CPU_CLUSTER cluster.
+ * type DEVICE_PATH_CPUS. Start up is controlled by cntrl_ops.
*/
-unsigned int smp_processor_id(void);
+void arch_initialize_cpus(device_t cluster, struct cpu_control_ops *cntrl_ops);
+
+/*
+ * Run cpu_action returning < 0 on error, 0 on success. There are synchronous
+ * and asynchronous methods. Both cases ensure the action has been picked up
+ * by the target cpu. The synchronous variants will wait for the action to
+ * be completed before returning.
+ *
+ * Though the current implementation allows queuing actions on the main cpu,
+ * the main cpu doesn't process its own queue.
+ */
+int arch_run_on_cpu(unsigned int cpu, struct cpu_action *action);
+int arch_run_on_all_cpus(struct cpu_action *action);
+int arch_run_on_cpu_async(unsigned int cpu, struct cpu_action *action);
+int arch_run_on_all_cpus_async(struct cpu_action *action);
/*
* Do the necessary work to prepare for secondary CPUs coming up. The
@@ -65,4 +110,14 @@ void *prepare_secondary_cpu_startup(void);
*/
void soc_secondary_cpu_init(void);
+#endif /* !__PRE_RAM__ */
+
+/*
+ * Returns logical cpu in range [0:MAX_CPUS). SoC should define this.
+ * Additionally, this is needed early in arm64 init so it should not
+ * rely on a stack. Standard clobber list is fair game: x0-x7 and x0
+ * returns the logical cpu number.
+ */
+unsigned int smp_processor_id(void);
+
#endif /* __ARCH_CPU_H__ */