core: Move cpu_suspended setting into arch_panic_stop

cpu_suspended is an x86-specific control, nothing every arch needs to
provide. Leave it up to the arch how to set the CPU's state on panic.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Refactor struct mmio_access to mmio_instruction

The current mmio_access rather contains information about the accessing
instruction. ARM's mmio_access hold data about the actual access. To
clarify the meaning and release the namespace, rework the preexisting
struct to mmio_instruction.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Move mmio_parse and struct mmio_instruction into arch header

There will be no need for and implementation of this service outside of
x86 in the foreseeable future. So make it arch-private until we have
more users.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: build with virtualisation support

Most armv7-compatible toolchains still need an additional flag to
recognise instructions such as ERET or an MSR to banked registers.
This patch allows to includes the virt flag in files that require it.
It also forces the hypervisor image to only use the ARM instruction
set.
Support for Thumb2 hypervisor and kernel will be added later.
Guests should still be able to run in Thumb2, as long as they allow
to be entered in ARM mode.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: hypervisor entry point

Each CPU saves its general-purpose registers on the stack, switches to
the hypervisor stack and saves the return context in the per-cpu datas.
After that, it jumps to the core entry which will do the necessary
initialisation to setup EL2.

Clusters are not supported yet: they will require the entry code to
fetch the total number of possible CPUs from the header, in order to
deduce an efficient base address for the per-cpu datas.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: provide an interface for accessing system registers

To avoid using inline asm directly in the setup and control code, to
provide clear names for system registers, and to allow easier
refactoring for a future arm64 port, this patch introduces some useful
macros for accessing the core system registers.

For a 64bit port, a couple of wrappers would still need to be added to
modify system registers that are of different sizes on the two
architectures (e.g. HCR)

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: implement some base functions

memcpy and phys_processor_id implementations are required before going
any further. This patch introduces a very trivial version of those
functions.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: add SMP barriers and utilities

This patch adds a few simple macros that allow the C code to use
specific ARM instructions.
The memory_barrier helper is only used to commit the changes of cpu_init
on the last core before allowing the others to return to EL1.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: spinlock implementation

Instead of attempting to reinvent the wheel, this patch copies the
ticket spinlock implementation from Linux, that will allow for optimal
locking between heterogeneous cores.
It contains a few subtleties, such as a preload instruction that ensures
that the cache line is immediately loaded in exclusive state.

Big endian is not supported for the moment, but as soon as we have a
macro that declares the use of this mode, the change will be trivial
here.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: implement atomic bitops

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: implement the debug routines for the pl011 UART

This patch uses the kernel config to detect which UART is available.
Currently, only the vexpress platform is implemented.
It assumes that the first UART uses the default, fixed VA->PA mapping
set by the kernel for the vexpress low-level printk.

This is far from ideal: a clean implementation would either need to
communicate the uart address from the driver, or postpone all debug
printks until the hypervisor is able to use its own mappings, as linux
does when earlyprintk is disabled.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
[Jan: removed kernel config dependencies, switched to mmio accessors]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: hyp vectors installation

The EL2 installation is done in two times:
- First, an HVC is issued to jump into the kernel stub and install the
  bootstrap vectors.
- Then, a second HVC allows the setup code to switch to physical address
  space.
Execution continues at EL2. Once the whole initialisation is done, the
final vectors are installed, and arch_cpu_activate_vmm will do an ERET
to jump back to the kernel, which is now a guest.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: Implement per-cpu accessors

TPIDR_EL2 already holds a reference to the current per_cpu data
structure. Return it from this_cpu_data and build the other accessors on
top.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: implement the paging callbacks

This patch adds the ability to implement EL2 stage-1 and EL1 stage-2
MMU, using the struct paging defined by the core.
In the future, it may be useful to separate the stage1 and stage2
functions, like the x86 implementation, in order to use less translation
levels for the IPA->PA translation. For the moment, we keep the
hv_paging = arm_paging definition.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
[Jan: adjustments to recent paging subsystem changes]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: add the ability to use arch-specific linker scripts

This patch adds an optional include inside the hypervisor's linker
script in order to add sections specific to the architecture.
For instance on ARM, a trampoline section will need to be added to
safely enable and disable the EL2 MMU. To avoid overlapping
complications, it will be less than one page, and aligned.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: initialise hypervisor stage 1 MMU

This patch enables the EL2 stage-1 MMU, after the core initialisation of
all the paging structures needed by the hypervisor.
The arm backend also needs to map the needed devices for MMIOs. In order
to stay compatible with the linux ioremaps (which is quite dodgy, cf.
ecfa8d1a), the UART is still accessed through high memory, but the GIC
should be accessed at its real address.

Some temporary mappings allow the mmu setup code to run at its physical
address while enabling the translations. Given the current hypervisor
configuration, there shouldn't be any conflict with existing mappings.
Once the PE runs at EL2, the HTTBR is installed, setup_mmu jumps back to
the virtual addresses, and the identity mappings are deleted.

This patch attempts to make most of the process 64bit-compatible. Only a
small bit of assembly is needed, which calls phys2hvirt and hvirt2phys
to translate the lr and sp addresses. Since these functions consist of
simple additions, they are currently harmless. This code would blow up
if they needed to dereference some pointers one day, but it should be
safe for the time being.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
[Jan: adjustments to recent paging subsystem changes]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: setup stage 2 MMU for the cells

This patch adds the necessary MMU setup code for the cells. They use the
same paging functions as the hypervisor, but their flags are slightly
different.

As an improvement, it would be good to use only two levels of page
tables on 32bit instead of three. This would limit the memory accessible
from EL1 to 16GB instead of the current 256.
This doesn't really matter for the moment: since the core handles virtual
addresses with unsigned longs, LPAE cannot be used.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
[Jan: adjustments to recent paging subsystem changes]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: check architecture features

Verify that virtualization is actually supported before going any further
in the initialisation process.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: dispatch hypercalls

Initial code for handling hypervisor traps. Only the non-banked registers
need to be saved in the low-level handler, the rest of the context won't
be overwritten.
The per-cpu datas are loaded from TPIDR_EL2 and the general-purpose
registers are saved directly on the stack and supplied as 'struct
registers' to the dispatcher.
The latter then inspects the ESR value and calls the core accordingly.
The return value and the general-purpose registers are passed back to the
driver by retrieving 'struct registers' from the stack, before doing the
final ERET.
This patch allows to handle all status querying hypercalls.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
arm: Pass through init_late

The only thing we need to in init_late for the moment is to trigger the
root cell memory mapping to be build. This allows to run a complete
hypervisor setup from the driver and return to the kernel normally.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>