[PATCH v2 04/31] arm64: MMU definitions
The virtual memory layout is described in Documentation/arm64/memory.txt. This patch adds the MMU definitions for the 4KB and 64KB translation table configurations. The SECTION_SIZE is 2MB with 4KB page and 512MB with 64KB page configuration. PHYS_OFFSET is calculated at run-time and stored in a variable (no run-time code patching at this stage). On the current implementation, both user and kernel address spaces are 512G (39-bit) each with a maximum of 256G for the RAM linear mapping. Linux uses 3 levels of translation tables with the 4K page configuration and 2 levels with the 64K configuration. Extending the memory space beyond 39-bit with the 4K pages or 42-bit with 64K pages requires an additional level of translation tables. The SPARSEMEM configuration is global to all AArch64 platforms and allows for 1GB sections with SPARSEMEM_VMEMMAP enabled by default. Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- Documentation/arm64/memory.txt| 69 + arch/arm64/include/asm/memory.h | 144 +++ arch/arm64/include/asm/mmu.h | 27 ++ arch/arm64/include/asm/pgtable-2level-hwdef.h | 43 arch/arm64/include/asm/pgtable-2level-types.h | 60 + arch/arm64/include/asm/pgtable-3level-hwdef.h | 50 arch/arm64/include/asm/pgtable-3level-types.h | 66 + arch/arm64/include/asm/pgtable-hwdef.h| 94 +++ arch/arm64/include/asm/pgtable.h | 328 + arch/arm64/include/asm/sparsemem.h| 24 ++ 10 files changed, 905 insertions(+), 0 deletions(-) create mode 100644 Documentation/arm64/memory.txt create mode 100644 arch/arm64/include/asm/memory.h create mode 100644 arch/arm64/include/asm/mmu.h create mode 100644 arch/arm64/include/asm/pgtable-2level-hwdef.h create mode 100644 arch/arm64/include/asm/pgtable-2level-types.h create mode 100644 arch/arm64/include/asm/pgtable-3level-hwdef.h create mode 100644 arch/arm64/include/asm/pgtable-3level-types.h create mode 100644 arch/arm64/include/asm/pgtable-hwdef.h create mode 100644 arch/arm64/include/asm/pgtable.h create mode 100644 arch/arm64/include/asm/sparsemem.h diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt new file mode 100644 index 000..7210af7 --- /dev/null +++ b/Documentation/arm64/memory.txt @@ -0,0 +1,69 @@ +Memory Layout on AArch64 Linux +== + +Author: Catalin Marinas +Date : 20 February 2012 + +This document describes the virtual memory layout used by the AArch64 +Linux kernel. The architecture allows up to 4 levels of translation +tables with a 4KB page size and up to 3 levels with a 64KB page size. + +AArch64 Linux uses 3 levels of translation tables with the 4KB page +configuration, allowing 39-bit (512GB) virtual addresses for both user +and kernel. With 64KB pages, only 2 levels of translation tables are +used but the memory layout is the same. + +User addresses have bits 63:39 set to 0 while the kernel addresses have +the same bits set to 1. TTBRx selection is given by bit 63 of the +virtual address. The swapper_pg_dir contains only kernel (global) +mappings while the user pgd contains only user (non-global) mappings. +The swapper_pgd_dir address is written to TTBR1 and never written to +TTBR0. + + +AArch64 Linux memory layout: + +Start End SizeUse +--- + 007f 512GB user + +ff80 ffbbfffe~240GB vmalloc + +ffbb ffbc 64KB [guard page] + +ffbc ffbd 8GB vmemmap + +ffbe ffbffbff ~8GB [guard, future vmmemap] + +ffbffc00 ffbf 64MB modules + +ffc0 256GB memory + + +Translation table lookup with 4KB pages: + ++++++++++ +|6356|5548|4740|3932|3124|2316|15 8|7 0| ++++++++++ + | | | | | | + | | | | | v + | | | | | [11:0] in-page offset + | | | | +-> [20:12] L3 index + | | | +---> [29:21] L2 index + | | +-> [38:30] L1 index + | +---> [47:39] L0 index (not used) + +-> [63] TTBR0/1 + + +Translation table lookup with 64KB pages: + +++++--
Re: [PATCH v2 04/31] arm64: MMU definitions
On Tuesday 14 August 2012, Catalin Marinas wrote: > > +/* > + * TCR flags. > + */ > +#define TCR_TxSZ(x) (((64 - (x)) << 16) | ((64 - (x)) << 0)) > +#define TCR_IRGN_NC ((0 << 8) | (0 << 24)) > +#define TCR_IRGN_WBWA((1 << 8) | (1 << 24)) > +#define TCR_IRGN_WT ((2 << 8) | (2 << 24)) > +#define TCR_IRGN_WBnWA ((3 << 8) | (3 << 24)) > +#define TCR_IRGN_MASK((3 << 8) | (3 << 24)) > +#define TCR_ORGN_NC ((0 << 10) | (0 << 26)) > +#define TCR_ORGN_WBWA((1 << 10) | (1 << 26)) > +#define TCR_ORGN_WT ((2 << 10) | (2 << 26)) > +#define TCR_ORGN_WBnWA ((3 << 10) | (3 << 26)) > +#define TCR_ORGN_MASK((3 << 10) | (3 << 26)) > +#define TCR_SHARED ((3 << 12) | (3 << 28)) > +#define TCR_TG0_64K (1 << 14) > +#define TCR_TG1_64K (1 << 30) > +#define TCR_IPS_40BIT(2 << 32) > +#define TCR_ASID16 (1 << 36) > + As a matter of coding style, I would much prefer tables like this to be written as #define TCR_IRGN_MASK 0x03000300 #define TCR_IRGN_WBnWA 0x03000300 #define TCR_IRGN_WT 0x02000200 #define TCR_IRGN_WBWA 0x01000100 #define TCR_IRGN_NC 0x #define TCR_ORGN_MASK 0x0c000c00 #define TCR_ORGN_WBnWA 0x0c000c00 #define TCR_ORGN_WT 0x08000800 #define TCR_ORGN_WBWA 0x04000400 #define TCR_ORGN_NC 0x The advantage of this is that you can visually compare the bitmasks to a hex dump, and if you are suffering from endian-confused documentation authors, there is no ambiguity about which end of the word is bit zero. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 04/31] arm64: MMU definitions
Hi Arnd, On Wed, Aug 15, 2012 at 02:30:01PM +0100, Arnd Bergmann wrote: > On Tuesday 14 August 2012, Catalin Marinas wrote: > > +/* > > + * TCR flags. > > + */ > > +#define TCR_TxSZ(x)(((64 - (x)) << 16) | ((64 - (x)) << 0)) > > +#define TCR_IRGN_NC((0 << 8) | (0 << 24)) > > +#define TCR_IRGN_WBWA ((1 << 8) | (1 << 24)) > > +#define TCR_IRGN_WT((2 << 8) | (2 << 24)) > > +#define TCR_IRGN_WBnWA ((3 << 8) | (3 << 24)) > > +#define TCR_IRGN_MASK ((3 << 8) | (3 << 24)) > > +#define TCR_ORGN_NC((0 << 10) | (0 << 26)) > > +#define TCR_ORGN_WBWA ((1 << 10) | (1 << 26)) > > +#define TCR_ORGN_WT((2 << 10) | (2 << 26)) > > +#define TCR_ORGN_WBnWA ((3 << 10) | (3 << 26)) > > +#define TCR_ORGN_MASK ((3 << 10) | (3 << 26)) > > +#define TCR_SHARED ((3 << 12) | (3 << 28)) > > +#define TCR_TG0_64K(1 << 14) > > +#define TCR_TG1_64K(1 << 30) > > +#define TCR_IPS_40BIT (2 << 32) > > +#define TCR_ASID16 (1 << 36) > > + > > As a matter of coding style, I would much prefer tables like this to be > written as > > #define TCR_IRGN_MASK 0x03000300 > #define TCR_IRGN_WBnWA0x03000300 > #define TCR_IRGN_WT 0x02000200 > #define TCR_IRGN_WBWA 0x01000100 > #define TCR_IRGN_NC 0x > > #define TCR_ORGN_MASK 0x0c000c00 > #define TCR_ORGN_WBnWA0x0c000c00 > #define TCR_ORGN_WT 0x08000800 > #define TCR_ORGN_WBWA 0x04000400 > #define TCR_ORGN_NC 0x > > The advantage of this is that you can visually compare the bitmasks > to a hex dump, and if you are suffering from endian-confused documentation > authors, there is no ambiguity about which end of the word is bit zero. That depends on the case, in some places it's more readable like this. In the above case, I find it easier to compare against the documentation which, for example, has groups of 2 bits at position 8 and 24 or 10 and 26 (for TTBR0 and TTBR1). The meaning of a group of 2 bits is described separately as 0b00 (NC), 0b01(WBWA) etc. Same goes for the shareability bits (12 and 28). So I think at least for code writing it's less error-prone to write the explicit bit position than a magic long hex. -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 04/31] arm64: MMU definitions
On Wed, Aug 15, 2012 at 3:30 PM, Arnd Bergmann wrote: >> +#define TCR_IPS_40BIT(2 << 32) By default, constants are int, i.e. 32-bit. So you must write 2ULL << 32 >> +#define TCR_ASID16 (1 << 36) 1ULL > As a matter of coding style, I would much prefer tables like this to be > written as > > #define TCR_IRGN_MASK 0x03000300 0x03000300ULL, to be safe Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 04/31] arm64: MMU definitions
On Wed, Aug 15, 2012 at 05:34:46PM +0100, Geert Uytterhoeven wrote: > On Wed, Aug 15, 2012 at 3:30 PM, Arnd Bergmann wrote: > >> +#define TCR_IPS_40BIT(2 << 32) > > By default, constants are int, i.e. 32-bit. So you must write > > 2ULL << 32 > > >> +#define TCR_ASID16 (1 << 36) > > 1ULL Those higher constants are only used in assembly currently, so no side-effects. But I agree that I should use something like: (_AC(1, UL) << 36) (UL is sufficient on a 64-bit system) Thanks. -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 04/31] arm64: MMU definitions
* Catalin Marinas [120814 10:57]: > The virtual memory layout is described in > Documentation/arm64/memory.txt. This patch adds the MMU definitions for > the 4KB and 64KB translation table configurations. The SECTION_SIZE is > 2MB with 4KB page and 512MB with 64KB page configuration. > > PHYS_OFFSET is calculated at run-time and stored in a variable (no > run-time code patching at this stage). Care to clarify this part a bit? Is the memory standardized somehow now and not needed? Or do we still need to add that for various SoCs later on? Other than that: Acked-by: Tony Lindgren -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 04/31] arm64: MMU definitions
On Fri, Aug 17, 2012 at 10:04:52AM +0100, Tony Lindgren wrote: > * Catalin Marinas [120814 10:57]: > > The virtual memory layout is described in > > Documentation/arm64/memory.txt. This patch adds the MMU definitions for > > the 4KB and 64KB translation table configurations. The SECTION_SIZE is > > 2MB with 4KB page and 512MB with 64KB page configuration. > > > > PHYS_OFFSET is calculated at run-time and stored in a variable (no > > run-time code patching at this stage). > > Care to clarify this part a bit? Is the memory standardized somehow > now and not needed? Or do we still need to add that for various SoCs > later on? The memory is not standardised but we have FDT to fully specify it. The PHYS_OFFSET does not need to be defined, it is automatically detected at boo-time based on the kernel load address and stored in a variable to be used later. > Other than that: > > Acked-by: Tony Lindgren Thanks. -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 04/31] arm64: MMU definitions
* Catalin Marinas [120817 02:21]: > On Fri, Aug 17, 2012 at 10:04:52AM +0100, Tony Lindgren wrote: > > * Catalin Marinas [120814 10:57]: > > > The virtual memory layout is described in > > > Documentation/arm64/memory.txt. This patch adds the MMU definitions for > > > the 4KB and 64KB translation table configurations. The SECTION_SIZE is > > > 2MB with 4KB page and 512MB with 64KB page configuration. > > > > > > PHYS_OFFSET is calculated at run-time and stored in a variable (no > > > run-time code patching at this stage). > > > > Care to clarify this part a bit? Is the memory standardized somehow > > now and not needed? Or do we still need to add that for various SoCs > > later on? > > The memory is not standardised but we have FDT to fully specify it. The > PHYS_OFFSET does not need to be defined, it is automatically detected at > boo-time based on the kernel load address and stored in a variable to be > used later. OK nice thanks. Tony -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/