Add support for multiple host CPUs.
Change-Id: I0fd2fd85732e8e7beeacc595a9ca92c3cd98e73a
diff --git a/src/cpu.c b/src/cpu.c
index 581bc11..6cd0a2b 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -1,5 +1,6 @@
#include "cpu.h"
+#include "api.h"
#include "arch_cpu.h"
#include "dlog.h"
#include "std.h"
@@ -24,14 +25,14 @@
for (i = 0; i < MAX_CPUS; i++) {
struct cpu *c = cpus + i;
cpu_init(c);
- c->id = i; /* TODO: Initialize ID. */
+ c->id = i; /* TODO: Initialize ID based on fdt. */
c->stack_bottom = callstacks + STACK_SIZE * (i + 1);
}
}
size_t cpu_index(struct cpu *c)
{
- return cpus - c;
+ return c - cpus;
}
void cpu_init(struct cpu *c)
@@ -60,7 +61,7 @@
/**
* Turns CPU on and returns the previous state.
*/
-bool cpu_on(struct cpu *c)
+bool cpu_on(struct cpu *c, size_t entry, size_t arg)
{
bool prev;
@@ -70,23 +71,38 @@
sl_unlock(&c->lock);
if (!prev) {
- /* The CPU is currently off, we need to turn it on. */
- arch_cpu_on(c->id, c);
+ struct vcpu *vcpu = primary_vm.vcpus + cpu_index(c);
+ arch_regs_init(&vcpu->regs, entry, arg, true);
+ vcpu_on(vcpu);
}
return prev;
}
-/*
- * This must be called only from the same CPU.
+/**
+ * Prepares the CPU for turning itself off.
*/
void cpu_off(struct cpu *c)
{
sl_lock(&c->lock);
c->is_on = false;
sl_unlock(&c->lock);
+}
- arch_cpu_off();
+/**
+ * Searches for a CPU based on its id.
+ */
+struct cpu *cpu_find(size_t id)
+{
+ size_t i;
+
+ for (i = 0; i < MAX_CPUS; i++) {
+ if (cpus[i].id == id) {
+ return cpus + i;
+ }
+ }
+
+ return NULL;
}
void vcpu_init(struct vcpu *vcpu, struct vm *vm)
@@ -95,7 +111,8 @@
sl_init(&vcpu->lock);
vcpu->vm = vm;
vcpu->state = vcpu_state_off;
- /* TODO: Initialize vmid register. */
+ /* TODO: This needs to be moved to arch-dependent code. */
+ vcpu->regs.lazy.vmpidr_el2 = vcpu - vm->vcpus;
}
void vcpu_on(struct vcpu *vcpu)