This reuses the control.c module, shared with 32-bit ARM.

There is more commodity in headers, setup.c etc. to be consolidated
later on.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---
 hypervisor/arch/arm64/Makefile              |   1 +
 hypervisor/arch/arm64/control.c             | 129 +++++++++++++---------------
 hypervisor/arch/arm64/include/asm/control.h |   6 ++
 hypervisor/arch/arm64/include/asm/percpu.h  |  29 ++++++-
 hypervisor/arch/arm64/setup.c               |  24 ++++++
 5 files changed, 119 insertions(+), 70 deletions(-)

diff --git a/hypervisor/arch/arm64/Makefile b/hypervisor/arch/arm64/Makefile
index e6c8e30..095212a 100644
--- a/hypervisor/arch/arm64/Makefile
+++ b/hypervisor/arch/arm64/Makefile
@@ -21,6 +21,7 @@ always := built-in.o
 obj-y := entry.o setup.o control.o mmio.o caches.o
 obj-y += exception.o traps.o
 obj-y += $(COMMON)/dbg-write.o $(COMMON)/lib.o
+obj-y += $(COMMON)/control.o
 obj-y += $(COMMON)/mmu_cell.o $(COMMON)/paging.o
 obj-y += $(COMMON)/irqchip.o $(COMMON)/gic-common.o
 
diff --git a/hypervisor/arch/arm64/control.c b/hypervisor/arch/arm64/control.c
index fc0a8f3..289e382 100644
--- a/hypervisor/arch/arm64/control.c
+++ b/hypervisor/arch/arm64/control.c
@@ -12,19 +12,74 @@
 
 #include <jailhouse/control.h>
 #include <jailhouse/printk.h>
+#include <jailhouse/string.h>
 #include <asm/control.h>
 #include <asm/irqchip.h>
 #include <asm/traps.h>
 
-int arch_cell_create(struct cell *cell)
+void arm_cpu_reset(unsigned long pc)
 {
-       return trace_error(-EINVAL);
+       struct per_cpu *cpu_data = this_cpu_data();
+       struct registers *regs = guest_regs(cpu_data);
+
+       /* put the cpu in a reset state */
+       /* AARCH64_TODO: handle big endian support */
+       arm_write_sysreg(SPSR_EL2, RESET_PSR);
+       arm_write_sysreg(SCTLR_EL1, SCTLR_EL1_RES1);
+       arm_write_sysreg(CNTKCTL_EL1, 0);
+       arm_write_sysreg(PMCR_EL0, 0);
+
+       /* wipe any other state to avoid leaking information accross cells */
+       memset(regs, 0, sizeof(struct registers));
+
+       /* AARCH64_TODO: wipe floating point registers */
+
+       /* wipe special registers */
+       arm_write_sysreg(SP_EL0, 0);
+       arm_write_sysreg(SP_EL1, 0);
+       arm_write_sysreg(SPSR_EL1, 0);
+
+       /* wipe the system registers */
+       arm_write_sysreg(AFSR0_EL1, 0);
+       arm_write_sysreg(AFSR1_EL1, 0);
+       arm_write_sysreg(AMAIR_EL1, 0);
+       arm_write_sysreg(CONTEXTIDR_EL1, 0);
+       arm_write_sysreg(CPACR_EL1, 0);
+       arm_write_sysreg(CSSELR_EL1, 0);
+       arm_write_sysreg(ESR_EL1, 0);
+       arm_write_sysreg(FAR_EL1, 0);
+       arm_write_sysreg(MAIR_EL1, 0);
+       arm_write_sysreg(PAR_EL1, 0);
+       arm_write_sysreg(TCR_EL1, 0);
+       arm_write_sysreg(TPIDRRO_EL0, 0);
+       arm_write_sysreg(TPIDR_EL0, 0);
+       arm_write_sysreg(TPIDR_EL1, 0);
+       arm_write_sysreg(TTBR0_EL1, 0);
+       arm_write_sysreg(TTBR1_EL1, 0);
+       arm_write_sysreg(VBAR_EL1, 0);
+
+       /* wipe timer registers */
+       arm_write_sysreg(CNTP_CTL_EL0, 0);
+       arm_write_sysreg(CNTP_CVAL_EL0, 0);
+       arm_write_sysreg(CNTP_TVAL_EL0, 0);
+       arm_write_sysreg(CNTV_CTL_EL0, 0);
+       arm_write_sysreg(CNTV_CVAL_EL0, 0);
+       arm_write_sysreg(CNTV_TVAL_EL0, 0);
+
+       /* AARCH64_TODO: handle PMU registers */
+       /* AARCH64_TODO: handle debug registers */
+       /* AARCH64_TODO: handle system registers for AArch32 state */
+
+       arm_write_sysreg(ELR_EL2, pc);
+
+       arm_paging_vcpu_init(&cpu_data->cell->arch.mm);
+
+       irqchip_cpu_reset(cpu_data);
 }
 
-void arch_flush_cell_vcpu_caches(struct cell *cell)
+int arch_cell_create(struct cell *cell)
 {
-       /* AARCH64_TODO */
-       trace_error(-EINVAL);
+       return trace_error(-EINVAL);
 }
 
 void arch_cell_destroy(struct cell *cell)
@@ -33,70 +88,6 @@ void arch_cell_destroy(struct cell *cell)
        while (1);
 }
 
-void arch_cell_reset(struct cell *cell)
-{
-}
-
-void arch_config_commit(struct cell *cell_added_removed)
-{
-}
-
-void arch_shutdown(void)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void arch_suspend_cpu(unsigned int cpu_id)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void arch_resume_cpu(unsigned int cpu_id)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void arch_reset_cpu(unsigned int cpu_id)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void arch_park_cpu(unsigned int cpu_id)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void __attribute__((noreturn)) arch_panic_stop(void)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void arch_panic_park(void)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn,
-                    unsigned int count_event)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
-bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn,
-                         unsigned int count_event)
-{
-       trace_error(-EINVAL);
-       while (1);
-}
-
 /*
  * We get rid of the virt_id in the AArch64 implementation, since it
  * doesn't really fit with the MPIDR CPU identification scheme on ARM.
diff --git a/hypervisor/arch/arm64/include/asm/control.h 
b/hypervisor/arch/arm64/include/asm/control.h
index 93fdbbe..d7cd82c 100644
--- a/hypervisor/arch/arm64/include/asm/control.h
+++ b/hypervisor/arch/arm64/include/asm/control.h
@@ -18,6 +18,8 @@
 
 #include <asm/percpu.h>
 
+extern struct paging_structures parking_mm;
+
 void arch_cpu_tlb_flush(struct per_cpu *cpu_data);
 void arch_cell_caches_flush(struct cell *cell);
 void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn,
@@ -33,4 +35,8 @@ unsigned int arm_cpu_by_mpidr(struct cell *cell, unsigned 
long mpidr);
 void __attribute__((noreturn)) vmreturn(struct registers *guest_regs);
 void __attribute__((noreturn)) arch_shutdown_mmu(struct per_cpu *cpu_data);
 
+void arm_cpu_reset(unsigned long pc);
+void arm_cpu_park(void);
+void arm_cpu_kick(unsigned int cpu_id);
+
 #endif /* !_JAILHOUSE_ASM_CONTROL_H */
diff --git a/hypervisor/arch/arm64/include/asm/percpu.h 
b/hypervisor/arch/arm64/include/asm/percpu.h
index 4b645d6..507d86d 100644
--- a/hypervisor/arch/arm64/include/asm/percpu.h
+++ b/hypervisor/arch/arm64/include/asm/percpu.h
@@ -45,8 +45,35 @@ struct per_cpu {
        /* Only GICv3: redistributor base */
        void *gicr_base;
 
-       bool flush_vcpu_caches;
        unsigned long mpidr;
+
+       /**
+        * Lock protecting CPU state changes done for control tasks.
+        *
+        * The lock protects the following fields (unless CPU is suspended):
+        * @li per_cpu::suspend_cpu
+        * @li per_cpu::cpu_suspended (except for spinning on it to become
+        *                             true)
+        * @li per_cpu::flush_vcpu_caches
+        */
+       spinlock_t control_lock;
+
+       /** Set to true for instructing the CPU to suspend. */
+       volatile bool suspend_cpu;
+       /** True if CPU is waiting for power-on. */
+       volatile bool wait_for_poweron;
+       /** True if CPU is suspended. */
+       volatile bool cpu_suspended;
+       /** Set to true for pending reset. */
+       bool reset;
+       /** Set to true for pending park. */
+       bool park;
+       /** Set to true for a pending TLB flush for the paging layer that does
+        *  host physical <-> guest physical memory mappings. */
+       bool flush_vcpu_caches;
+
+       unsigned long cpu_on_entry;
+       unsigned long cpu_on_context;
 } __attribute__((aligned(PAGE_SIZE)));
 
 static inline struct per_cpu *this_cpu_data(void)
diff --git a/hypervisor/arch/arm64/setup.c b/hypervisor/arch/arm64/setup.c
index 8f1fc69..78a245b 100644
--- a/hypervisor/arch/arm64/setup.c
+++ b/hypervisor/arch/arm64/setup.c
@@ -12,13 +12,37 @@
 
 #include <jailhouse/cell.h>
 #include <jailhouse/entry.h>
+#include <jailhouse/paging.h>
 #include <jailhouse/printk.h>
 #include <asm/control.h>
 #include <asm/irqchip.h>
 #include <asm/setup.h>
 
+static u32 __attribute__((aligned(PAGE_SIZE))) parking_code[PAGE_SIZE / 4] = {
+       0xd503207f, /* 1: wfi  */
+       0x17ffffff, /*    b 1b */
+};
+
+struct paging_structures parking_mm;
+
 int arch_init_early(void)
 {
+       int err;
+
+       parking_mm.root_paging = cell_paging;
+       parking_mm.root_table =
+               page_alloc_aligned(&mem_pool, ARM_CELL_ROOT_PT_SZ);
+       if (!parking_mm.root_table)
+               return -ENOMEM;
+
+       err = paging_create(&parking_mm, paging_hvirt2phys(parking_code),
+                           PAGE_SIZE, 0,
+                           (PTE_FLAG_VALID | PTE_ACCESS_FLAG |
+                            S2_PTE_ACCESS_RO | S2_PTE_FLAG_NORMAL),
+                           PAGING_COHERENT);
+       if (err)
+               return err;
+
        return arm_paging_cell_init(&root_cell);
 }
 
-- 
2.1.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to