On 2018-05-11 12:19, Peng Fan wrote:
> On ARM64 Big/Little Platform, such as i.MX8QM,
> there are two types of Cortex-A CPUs, Cortex-A53 and Cortex-A72.
> A53 ID_AA64MMFR0_EL1 shows its physical address range supported is 40bits.
> A72 ID_AA64MMFR0_EL1 shows its physical address range supported is 44bits.
>
> The minimal value 40 needs to be used as cpu parange, if using 44,
> A53 will be broken. So need to iterate the cpu parange of all the
> CPUs to find out the smallest one.
>
> Add a new percpu entry id_aa64mmfr0 whose low 4 bits holds parange.
> Fill id_aa64mmfr0 before runs into entry
> Move arm64 get_cpu_parange out to a new file
> Use percpu id_aa64mmfr0 in get_cpu_parange and choose the smallest value
>
> Then each time using get_cpu_parange, the smallest one will
> be chosen.
>
> Signed-off-by: Peng Fan <[email protected]>
> ---
>
> V3:
> Use unsigned int in get_cpu_parange
> Use similar logic in gicv3_cell_init following Jan's comments.
> Add a comments to 0x10
>
> V2:
> Refine commit log
> Use Jailhouse common header
> Use Doxygen format
>
> hypervisor/arch/arm64/Kbuild | 2 +-
> hypervisor/arch/arm64/asm-defines.c | 1 +
> hypervisor/arch/arm64/entry.S | 3 ++
> hypervisor/arch/arm64/include/asm/paging.h | 27 +-------------
> hypervisor/arch/arm64/include/asm/percpu.h | 1 +
> hypervisor/arch/arm64/paging.c | 60
> ++++++++++++++++++++++++++++++
> 6 files changed, 67 insertions(+), 27 deletions(-)
> create mode 100644 hypervisor/arch/arm64/paging.c
>
> diff --git a/hypervisor/arch/arm64/Kbuild b/hypervisor/arch/arm64/Kbuild
> index b0ef924e..7283a008 100644
> --- a/hypervisor/arch/arm64/Kbuild
> +++ b/hypervisor/arch/arm64/Kbuild
> @@ -20,4 +20,4 @@ always := lib.a
> # irqchip (common-objs-y), <generic units>
>
> lib-y := $(common-objs-y)
> -lib-y += entry.o setup.o control.o mmio.o caches.o traps.o
> +lib-y += entry.o setup.o control.o mmio.o paging.o caches.o traps.o
> diff --git a/hypervisor/arch/arm64/asm-defines.c
> b/hypervisor/arch/arm64/asm-defines.c
> index 58669a4b..81141dc9 100644
> --- a/hypervisor/arch/arm64/asm-defines.c
> +++ b/hypervisor/arch/arm64/asm-defines.c
> @@ -27,6 +27,7 @@ void common(void)
> debug_console.address);
> OFFSET(SYSCONFIG_HYPERVISOR_PHYS, jailhouse_system,
> hypervisor_memory.phys_start);
> + OFFSET(PERCPU_ID_AA64MMFR0, per_cpu, id_aa64mmfr0);
> BLANK();
>
> DEFINE(PERCPU_STACK_END,
> diff --git a/hypervisor/arch/arm64/entry.S b/hypervisor/arch/arm64/entry.S
> index 61c5dc49..d5b34f17 100644
> --- a/hypervisor/arch/arm64/entry.S
> +++ b/hypervisor/arch/arm64/entry.S
> @@ -157,6 +157,9 @@ el2_entry:
> */
> sub sp, sp, 20 * 8
>
> + mrs x29, id_aa64mmfr0_el1
> + str x29, [x1, #PERCPU_ID_AA64MMFR0]
> +
> mov x29, xzr /* reset fp,lr */
> mov x30, xzr
>
> diff --git a/hypervisor/arch/arm64/include/asm/paging.h
> b/hypervisor/arch/arm64/include/asm/paging.h
> index 0fe1429d..1a5ea0ed 100644
> --- a/hypervisor/arch/arm64/include/asm/paging.h
> +++ b/hypervisor/arch/arm64/include/asm/paging.h
> @@ -178,32 +178,7 @@ typedef u64 *pt_entry_t;
>
> extern unsigned int cpu_parange;
>
> -/* return the bits supported for the physical address range for this
> - * machine; in arch_paging_init this value will be kept in
> - * cpu_parange for later reference */
> -static inline unsigned int get_cpu_parange(void)
> -{
> - unsigned long id_aa64mmfr0;
> -
> - arm_read_sysreg(ID_AA64MMFR0_EL1, id_aa64mmfr0);
> -
> - switch (id_aa64mmfr0 & 0xf) {
> - case PARANGE_32B:
> - return 32;
> - case PARANGE_36B:
> - return 36;
> - case PARANGE_40B:
> - return 40;
> - case PARANGE_42B:
> - return 42;
> - case PARANGE_44B:
> - return 44;
> - case PARANGE_48B:
> - return 48;
> - default:
> - return 0;
> - }
> -}
> +unsigned int get_cpu_parange(void);
>
> /* The size of the cpu_parange, determines from which level we can
> * start from the S2 translations, and the size of the first level
> diff --git a/hypervisor/arch/arm64/include/asm/percpu.h
> b/hypervisor/arch/arm64/include/asm/percpu.h
> index a88ed477..f8b9f77b 100644
> --- a/hypervisor/arch/arm64/include/asm/percpu.h
> +++ b/hypervisor/arch/arm64/include/asm/percpu.h
> @@ -34,6 +34,7 @@ struct per_cpu {
> u32 stats[JAILHOUSE_NUM_CPU_STATS];
> int shutdown_state;
> bool failed;
> + unsigned long id_aa64mmfr0;
>
> struct pending_irqs pending_irqs;
>
> diff --git a/hypervisor/arch/arm64/paging.c b/hypervisor/arch/arm64/paging.c
> new file mode 100644
> index 00000000..d775ff9f
> --- /dev/null
> +++ b/hypervisor/arch/arm64/paging.c
> @@ -0,0 +1,60 @@
> +/*
> + * Jailhouse, a Linux-based partitioning hypervisor
> + *
> + * Copyright 2018 NXP
> + *
> + * Authors:
> + * Peng Fan <[email protected]>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + */
> +
> +#include <jailhouse/control.h>
> +#include <asm/percpu.h>
> +#include <asm/paging.h>
> +
> +/**
> + * Return the physical address bits.
> + *
> + * In arch_paging_init this value will be kept in cpu_parange
> + * for later reference
> + *
> + * @return The physical address bits.
> + */
> +unsigned int get_cpu_parange(void)
> +{
> + /* Larger than any possible value */
> + unsigned int parange = 0x10;
> + unsigned int cpu;
> +
> + /*
> + * early_init calls paging_init, which will indirectly call
> + * get_cpu_parange, prior to cell_init, we cannot use
> + * for_each_cpu yet. So we need to iterate over the configuration
> + * of the root cell.
> + */
> + for (cpu = 0; cpu < system_config->root_cell.cpu_set_size * 8; cpu++) {
> + if (!cpu_id_valid(cpu))
> + continue;
I made this loop slightly more compact by inverting the condition and
combining it with the succeeding one. Result in next.
Thanks!
Jan
> + if ((per_cpu(cpu)->id_aa64mmfr0 & 0xf) < parange)
> + parange = per_cpu(cpu)->id_aa64mmfr0 & 0xf;
> + }
> +
> + switch (parange) {
> + case PARANGE_32B:
> + return 32;
> + case PARANGE_36B:
> + return 36;
> + case PARANGE_40B:
> + return 40;
> + case PARANGE_42B:
> + return 42;
> + case PARANGE_44B:
> + return 44;
> + case PARANGE_48B:
> + return 48;
> + default:
> + return 0;
> + }
> +}
>
--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.