From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexander Graf Date: Wed, 24 Feb 2016 18:04:10 +0100 Subject: [U-Boot] [PATCH 2/9] arm64: Make full va map code more dynamic In-Reply-To: <56CDE1D7.8050509@wwwdotorg.org> References: <1456106232-233210-1-git-send-email-agraf@suse.de> <1456106232-233210-3-git-send-email-agraf@suse.de> <56CD8C2B.9090102@suse.de> <56CDE1D7.8050509@wwwdotorg.org> Message-ID: <56CDE28A.7070909@suse.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 02/24/2016 06:01 PM, Stephen Warren wrote: > 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 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 >>>> --- >>>> 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 >>>> * >>>> + * (C) Copyright 2016 >>>> + * Alexander Graf >>>> + * >>>> * SPDX-License-Identifier: GPL-2.0+ >>>> */ >>>> >>>> @@ -9,35 +12,40 @@ >>>> #include >>>> #include >>>> >>>> -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. Well, it's something I'd leave to the SoC / board maintainer really. With v2 you can now fiddle with the map as much as you like inside your code. The important bit to me is that we have a standardized path on how we map the mem_map table into the MMU. I don't care how we fetch the table. Alex