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.

Reply via email to