[U-Boot] [PATCH 2/9] arm64: Make full va map code more dynamic

Stephen Warren swarren at wwwdotorg.org
Wed Feb 24 18:01:11 CET 2016


On 02/24/2016 03:55 AM, Alexander Graf wrote:
>
>
> On 23.02.16 14:17, Simon Glass wrote:
>> Hi Alex,
>>
>> On 21 February 2016 at 18:57, Alexander Graf <agraf at suse.de> wrote:
>>> The idea to generate our pages tables from an array of memory ranges
>>> is very sound. However, instead of hard coding the code to create up
>>> to 2 levels of 64k granule page tables, we really should just create
>>> normal 4k page tables that allow us to set caching attributes on 2M
>>> or 4k level later on.
>>>
>>> So this patch moves the full_va mapping code to 4k page size and
>>> makes it fully flexible to dynamically create as many levels as
>>> necessary for a map (including dynamic 1G/2M pages). It also adds
>>> support to dynamically split a large map into smaller ones when
>>> some code wants to set dcache attributes.
>>>
>>> With all this in place, there is very little reason to create your
>>> own page tables in board specific files.
>>>
>>> Signed-off-by: Alexander Graf <agraf at suse.de>
>>> ---
>>>   arch/arm/cpu/armv8/cache_v8.c      | 346 +++++++++++++++++++++++++++++++------
>>>   arch/arm/include/asm/armv8/mmu.h   |  68 ++++----
>>>   arch/arm/include/asm/global_data.h |   4 +-
>>>   arch/arm/include/asm/system.h      |   3 +-
>>>   include/configs/thunderx_88xx.h    |  14 +-
>>>   5 files changed, 332 insertions(+), 103 deletions(-)
>>>
>>
>> Should the change to the thunderx file go in a separate patch?
>
> We're changing semantics for some defines from "this define acts in
> L1/L2 page table entries" to "this define is for level/block type PTEs".
> So it's tied to this patch :).
>
>>
>>> diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
>>> index 9229532..4369a83 100644
>>> --- a/arch/arm/cpu/armv8/cache_v8.c
>>> +++ b/arch/arm/cpu/armv8/cache_v8.c
>>> @@ -2,6 +2,9 @@
>>>    * (C) Copyright 2013
>>>    * David Feng <fenghua at phytium.com.cn>
>>>    *
>>> + * (C) Copyright 2016
>>> + * Alexander Graf <agraf at suse.de>
>>> + *
>>>    * SPDX-License-Identifier:    GPL-2.0+
>>>    */
>>>
>>> @@ -9,35 +12,40 @@
>>>   #include <asm/system.h>
>>>   #include <asm/armv8/mmu.h>
>>>
>>> -DECLARE_GLOBAL_DATA_PTR;
>>> -
>>> -#ifndef CONFIG_SYS_DCACHE_OFF
>>> +/* #define DEBUG_MMU */
>>>
>>> -#ifdef CONFIG_SYS_FULL_VA
>>> -static void set_ptl1_entry(u64 index, u64 ptl2_entry)
>>> -{
>>> -       u64 *pgd = (u64 *)gd->arch.tlb_addr;
>>> -       u64 value;
>>> +#ifdef DEBUG_MMU
>>> +#define DPRINTF(a, ...) printf("%s:%d: " a, __func__, __LINE__, __VA_ARGS__)
>>> +#else
>>> +#define DPRINTF(a, ...) do { } while(0)
>>> +#endif
>>
>> Can you use the normal DEBUG and debug()?
>
> Uh, I guess so, yeah.
>
>>
>>>
>>> -       value = ptl2_entry | PTL1_TYPE_TABLE;
>>> -       pgd[index] = value;
>>> -}
>>> +DECLARE_GLOBAL_DATA_PTR;
>>>
>>> -static void set_ptl2_block(u64 ptl1, u64 bfn, u64 address, u64 memory_attrs)
>>> -{
>>> -       u64 *pmd = (u64 *)ptl1;
>>> -       u64 value;
>>> +#ifndef CONFIG_SYS_DCACHE_OFF
>>>
>>> -       value = address | PTL2_TYPE_BLOCK | PTL2_BLOCK_AF;
>>> -       value |= memory_attrs;
>>> -       pmd[bfn] = value;
>>> -}
>>> +/*
>>> + *  With 4k page granule, a virtual address is split into 4 lookup parts
>>> + *  spanning 9 bits each:
>>> + *
>>> + *    _______________________________________________
>>> + *   |       |       |       |       |       |       |
>>> + *   |   0   |  Lv0  |  Lv1  |  Lv2  |  Lv3  |  off  |
>>> + *   |_______|_______|_______|_______|_______|_______|
>>> + *     63-48   47-39   38-30   29-21   20-12   11-00
>>> + *
>>> + *             mask        page size
>>> + *
>>> + *    Lv0: FF8000000000       --
>>> + *    Lv1:   7FC0000000       1G
>>> + *    Lv2:     3FE00000       2M
>>> + *    Lv3:       1FF000       4K
>>> + *    off:          FFF
>>> + */
>>>
>>> +#ifdef CONFIG_SYS_FULL_VA
>>>   static struct mm_region mem_map[] = CONFIG_SYS_MEM_MAP;
>>
>> I am not ken on the idea of using a big #define table on these boards.
>> Is there not a device-tree binding for this that we can use? It is
>> just a data table, We are moving to Kconfig and eventually want to
>> drop the config files.
>
> I'll move this into board files which then can do whatever they like
> with it - take if from a #define in a header, populate it dynamically
> from device tree, do something halfway in between, whatever fits your
> needs best :).
>
> Btw, if you want to use dt for it, you don't need to add any new
> bindings at all. Simply take all of your device regs/ranges and memory
> ranges and gobble them into the memory map.

That's only true if every single MMIO region that the code accesses is 
already represented in DT already, or any DT conversion patches also add 
any missing devices. It's quite unlikely that even on heavily 
DT-dependant platforms that /all/ in-use MMIO regions are already 
represented in DT. Such a conversion would need quite significant testing.


More information about the U-Boot mailing list