[U-Boot] [PATCH 1/6] armv8/cache: Fix page table creation

From: Thierry Reding treding@nvidia.com
While generating the page tables, a running integer index is shifted by SECTION_SHIFT (29) and causes overflow for any integer bigger than 7. The page tables therefore alias to the same 8 sections and cause U-Boot to hang once the MMU is enabled.
Fix this by making the index a 64-bit unsigned integer and so avoid the overflow.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com --- arch/arm/cpu/armv8/cache_v8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index c5ec5297cd39..254a629a3b8c 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -25,9 +25,9 @@ void set_pgtable_section(u64 *page_table, u64 index, u64 section, /* to activate the MMU we need to set up virtual memory */ static void mmu_setup(void) { - int i, j, el; bd_t *bd = gd->bd; - u64 *page_table = (u64 *)gd->arch.tlb_addr; + u64 *page_table = (u64 *)gd->arch.tlb_addr, i, j; + int el;
/* Setup an identity-mapping for all spaces */ for (i = 0; i < (PGTABLE_SIZE >> 3); i++) {

From: Thierry Reding treding@nvidia.com
Implement early malloc() support in a similar way as on 32-bit ARM. This is required for 64-bit Tegra SoCs that initialize from the device tree just like the earlier 32-bit SoCs.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com --- arch/arm/include/asm/config.h | 4 ---- arch/arm/lib/crt0_64.S | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index be80434dee4d..7a34a0186cb1 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -7,10 +7,6 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_
-#ifdef __aarch64__ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -#endif - #define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 77563967e517..010efdbf8f3f 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -62,9 +62,21 @@ ENTRY(_main) * Set up initial C runtime environment and call board_init_f(0). */ ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) + mov x1, x0 sub x0, x0, #GD_SIZE /* allocate one GD above SP */ - bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ - mov x18, sp /* GD is above SP */ + bic x0, x0, #0xf /* 16-byte alignment for ABI compliance */ + mov x18, x0 /* GD is above SP */ + mov sp, x0 +clr_gd: + str xzr, [x0], #8 + cmp x0, x1 + b.lo clr_gd +#if defined(CONFIG_SYS_MALLOC_F_LEN) + ldr x0, =CONFIG_SYS_MALLOC_F_LEN + sub x0, sp, x0 + str x0, [x18, #GD_MALLOC_BASE] +#endif +3: mov x0, #0 bl board_init_f

hi Thierry,
-----Original Messages----- From: "Thierry Reding" thierry.reding@gmail.com Sent Time: 2015-03-20 19:47:49 (Friday) To: u-boot@lists.denx.de Cc: "Marc Zyngier" marc.zyngier@arm.com Subject: [U-Boot] [PATCH 2/6] armv8: Implement CONFIG_SYS_MALLOC_F_LEN support
From: Thierry Reding treding@nvidia.com
Implement early malloc() support in a similar way as on 32-bit ARM. This is required for 64-bit Tegra SoCs that initialize from the device tree just like the earlier 32-bit SoCs.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/include/asm/config.h | 4 ---- arch/arm/lib/crt0_64.S | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index be80434dee4d..7a34a0186cb1 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -7,10 +7,6 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_
-#ifdef __aarch64__ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA -#endif
#define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 77563967e517..010efdbf8f3f 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -62,9 +62,21 @@ ENTRY(_main)
- Set up initial C runtime environment and call board_init_f(0).
*/ ldr x0, =(CONFIG_SYS_INIT_SP_ADDR)
- mov x1, x0 sub x0, x0, #GD_SIZE /* allocate one GD above SP */
- bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
- mov x18, sp /* GD is above SP */
- bic x0, x0, #0xf /* 16-byte alignment for ABI compliance */
- mov x18, x0 /* GD is above SP */
- mov sp, x0
+clr_gd:
- str xzr, [x0], #8
- cmp x0, x1
- b.lo clr_gd
+#if defined(CONFIG_SYS_MALLOC_F_LEN)
- ldr x0, =CONFIG_SYS_MALLOC_F_LEN
- sub x0, sp, x0
- str x0, [x18, #GD_MALLOC_BASE]
sp should substract CONFIG_SYS_MALLOC_F_LEN also. Actually my previous patch did the same work, but got no reply.
+#endif +3: mov x0, #0 bl board_init_f
-- 2.3.2
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

From: Thierry Reding treding@nvidia.com
Use the inner shareable attribute for memory, which makes more sense considering that this code is called when caches are being enabled.
While at it, fix the values for the shareability attribute field to match the documentation.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com --- arch/arm/include/asm/armv8/mmu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 4b9cb5296572..6d42f5533a74 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -93,8 +93,8 @@ #define TCR_ORGN_WBNWA (3 << 10) #define TCR_ORGN_MASK (3 << 10) #define TCR_SHARED_NON (0 << 12) -#define TCR_SHARED_OUTER (1 << 12) -#define TCR_SHARED_INNER (2 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) @@ -102,9 +102,9 @@ #define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ #define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
-/* PTWs cacheable, inner/outer WBWA and non-shareable */ +/* PTWs cacheable, inner/outer WBWA and inner shareable */ #define TCR_FLAGS (TCR_TG0_64K | \ - TCR_SHARED_NON | \ + TCR_SHARED_INNER | \ TCR_ORGN_WBWA | \ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))

On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
Use the inner shareable attribute for memory, which makes more sense considering that this code is called when caches are being enabled.
While at it, fix the values for the shareability attribute field to match the documentation.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/include/asm/armv8/mmu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 4b9cb5296572..6d42f5533a74 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -93,8 +93,8 @@ #define TCR_ORGN_WBNWA (3 << 10) #define TCR_ORGN_MASK (3 << 10) #define TCR_SHARED_NON (0 << 12) -#define TCR_SHARED_OUTER (1 << 12) -#define TCR_SHARED_INNER (2 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) @@ -102,9 +102,9 @@ #define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ #define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
-/* PTWs cacheable, inner/outer WBWA and non-shareable */ +/* PTWs cacheable, inner/outer WBWA and inner shareable */ #define TCR_FLAGS (TCR_TG0_64K | \
TCR_SHARED_NON | \
TCR_SHARED_INNER | \ TCR_ORGN_WBWA | \ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
Acked-by: Marc Zyngier marc.zyngier@arm.com
One thing though: the architecture doesn't mandate 64k pages to be implemented by the HW. Actually, it doesn't mandate any particular page size, you just have to implement at least one (4k, 16k or 64k).
It would be good to test if 64k pages are implemented (by testing ID_AA64MMFR0_EL1) and not try to enable caches if not, possibly displaying a warning for the unsuspecting u-boot hacker.
Thanks,
M.

Hello Marc,
On Fri, 20 Mar 2015 18:13:26 +0000, Marc Zyngier marc.zyngier@arm.com wrote:
On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
Use the inner shareable attribute for memory, which makes more sense considering that this code is called when caches are being enabled.
While at it, fix the values for the shareability attribute field to match the documentation.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/include/asm/armv8/mmu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 4b9cb5296572..6d42f5533a74 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -93,8 +93,8 @@ #define TCR_ORGN_WBNWA (3 << 10) #define TCR_ORGN_MASK (3 << 10) #define TCR_SHARED_NON (0 << 12) -#define TCR_SHARED_OUTER (1 << 12) -#define TCR_SHARED_INNER (2 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) @@ -102,9 +102,9 @@ #define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ #define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
-/* PTWs cacheable, inner/outer WBWA and non-shareable */ +/* PTWs cacheable, inner/outer WBWA and inner shareable */ #define TCR_FLAGS (TCR_TG0_64K | \
TCR_SHARED_NON | \
TCR_SHARED_INNER | \ TCR_ORGN_WBWA | \ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
Acked-by: Marc Zyngier marc.zyngier@arm.com
One thing though: the architecture doesn't mandate 64k pages to be implemented by the HW. Actually, it doesn't mandate any particular page size, you just have to implement at least one (4k, 16k or 64k).
It would be good to test if 64k pages are implemented (by testing ID_AA64MMFR0_EL1) and not try to enable caches if not, possibly displaying a warning for the unsuspecting u-boot hacker.
So Marc, is this a request for a change, or is the patch applicable as it is?
Amicalement,

Hi Albert,
On 02/07/15 22:06, Albert ARIBAUD wrote:
Hello Marc,
On Fri, 20 Mar 2015 18:13:26 +0000, Marc Zyngier marc.zyngier@arm.com wrote:
On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
Use the inner shareable attribute for memory, which makes more sense considering that this code is called when caches are being enabled.
While at it, fix the values for the shareability attribute field to match the documentation.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/include/asm/armv8/mmu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 4b9cb5296572..6d42f5533a74 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -93,8 +93,8 @@ #define TCR_ORGN_WBNWA (3 << 10) #define TCR_ORGN_MASK (3 << 10) #define TCR_SHARED_NON (0 << 12) -#define TCR_SHARED_OUTER (1 << 12) -#define TCR_SHARED_INNER (2 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) @@ -102,9 +102,9 @@ #define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ #define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
-/* PTWs cacheable, inner/outer WBWA and non-shareable */ +/* PTWs cacheable, inner/outer WBWA and inner shareable */ #define TCR_FLAGS (TCR_TG0_64K | \
TCR_SHARED_NON | \
TCR_SHARED_INNER | \ TCR_ORGN_WBWA | \ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
Acked-by: Marc Zyngier marc.zyngier@arm.com
One thing though: the architecture doesn't mandate 64k pages to be implemented by the HW. Actually, it doesn't mandate any particular page size, you just have to implement at least one (4k, 16k or 64k).
It would be good to test if 64k pages are implemented (by testing ID_AA64MMFR0_EL1) and not try to enable caches if not, possibly displaying a warning for the unsuspecting u-boot hacker.
So Marc, is this a request for a change, or is the patch applicable as it is?
No, the patch is extremely valuable as it is, and should be applied. My remark is probably not applicable for generally available CPUs, and could be implemented as a later improvement.
Thanks,
M.

-----Original Messages----- From: "Thierry Reding" thierry.reding@gmail.com Sent Time: 2015-03-20 19:47:50 (Friday) To: u-boot@lists.denx.de Cc: "Marc Zyngier" marc.zyngier@arm.com Subject: [U-Boot] [PATCH 3/6] armv8/mmu: Clean up TCR programming
From: Thierry Reding treding@nvidia.com
Use the inner shareable attribute for memory, which makes more sense considering that this code is called when caches are being enabled.
While at it, fix the values for the shareability attribute field to match the documentation.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/include/asm/armv8/mmu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 4b9cb5296572..6d42f5533a74 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -93,8 +93,8 @@ #define TCR_ORGN_WBNWA (3 << 10) #define TCR_ORGN_MASK (3 << 10) #define TCR_SHARED_NON (0 << 12) -#define TCR_SHARED_OUTER (1 << 12) -#define TCR_SHARED_INNER (2 << 12) +#define TCR_SHARED_OUTER (2 << 12) +#define TCR_SHARED_INNER (3 << 12) #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) @@ -102,9 +102,9 @@ #define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ #define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
-/* PTWs cacheable, inner/outer WBWA and non-shareable */ +/* PTWs cacheable, inner/outer WBWA and inner shareable */ #define TCR_FLAGS (TCR_TG0_64K | \
TCR_SHARED_NON | \
TCR_SHARED_INNER | \ TCR_ORGN_WBWA | \ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
-- 2.3.2
Acked-by: david.feng fenghua@phytium.com.cn

From: Thierry Reding treding@nvidia.com
For EL3 and EL2, the documentation says that bits 31 and 23 are reserved but should be written as 1.
For EL1, only bit 23 is not reserved, so only write bit 31 as 1.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com --- arch/arm/cpu/armv8/cache_v8.c | 6 +++--- arch/arm/include/asm/armv8/mmu.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 254a629a3b8c..f9b04057f696 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -50,15 +50,15 @@ static void mmu_setup(void) el = current_el(); if (el == 1) { set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TCR_FLAGS | TCR_EL1_IPS_BITS, + TCR_EL1_RSVD | TCR_FLAGS | TCR_EL1_IPS_BITS, MEMORY_ATTRIBUTES); } else if (el == 2) { set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TCR_FLAGS | TCR_EL2_IPS_BITS, + TCR_EL2_RSVD | TCR_FLAGS | TCR_EL2_IPS_BITS, MEMORY_ATTRIBUTES); } else { set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TCR_FLAGS | TCR_EL3_IPS_BITS, + TCR_EL3_RSVD | TCR_FLAGS | TCR_EL3_IPS_BITS, MEMORY_ATTRIBUTES); } /* enable the mmu */ diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 6d42f5533a74..8e577b34e4ba 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -109,6 +109,10 @@ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
+#define TCR_EL1_RSVD (1 << 31) +#define TCR_EL2_RSVD (1 << 31 | 1 << 23) +#define TCR_EL3_RSVD (1 << 31 | 1 << 23) + #ifndef __ASSEMBLY__ void set_pgtable_section(u64 *page_table, u64 index, u64 section, u64 memory_type);

On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
For EL3 and EL2, the documentation says that bits 31 and 23 are reserved but should be written as 1.
For EL1, only bit 23 is not reserved, so only write bit 31 as 1.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/cpu/armv8/cache_v8.c | 6 +++--- arch/arm/include/asm/armv8/mmu.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 254a629a3b8c..f9b04057f696 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -50,15 +50,15 @@ static void mmu_setup(void) el = current_el(); if (el == 1) { set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
TCR_FLAGS | TCR_EL1_IPS_BITS,
} else if (el == 2) { set_ttbr_tcr_mair(el, gd->arch.tlb_addr,TCR_EL1_RSVD | TCR_FLAGS | TCR_EL1_IPS_BITS, MEMORY_ATTRIBUTES);
TCR_FLAGS | TCR_EL2_IPS_BITS,
} else { set_ttbr_tcr_mair(el, gd->arch.tlb_addr,TCR_EL2_RSVD | TCR_FLAGS | TCR_EL2_IPS_BITS, MEMORY_ATTRIBUTES);
TCR_FLAGS | TCR_EL3_IPS_BITS,
} /* enable the mmu */TCR_EL3_RSVD | TCR_FLAGS | TCR_EL3_IPS_BITS, MEMORY_ATTRIBUTES);
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 6d42f5533a74..8e577b34e4ba 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -109,6 +109,10 @@ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
+#define TCR_EL1_RSVD (1 << 31) +#define TCR_EL2_RSVD (1 << 31 | 1 << 23) +#define TCR_EL3_RSVD (1 << 31 | 1 << 23)
#ifndef __ASSEMBLY__ void set_pgtable_section(u64 *page_table, u64 index, u64 section, u64 memory_type);
Acked-by: Marc Zyngier marc.zyngier@arm.com
M.

-----Original Messages----- From: "Thierry Reding" thierry.reding@gmail.com Sent Time: 2015-03-20 19:47:51 (Friday) To: u-boot@lists.denx.de Cc: "Marc Zyngier" marc.zyngier@arm.com Subject: [U-Boot] [PATCH 4/6] armv8/mmu: Set bits marked RES1 in TCR
From: Thierry Reding treding@nvidia.com
For EL3 and EL2, the documentation says that bits 31 and 23 are reserved but should be written as 1.
For EL1, only bit 23 is not reserved, so only write bit 31 as 1.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/cpu/armv8/cache_v8.c | 6 +++--- arch/arm/include/asm/armv8/mmu.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 254a629a3b8c..f9b04057f696 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -50,15 +50,15 @@ static void mmu_setup(void) el = current_el(); if (el == 1) { set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
TCR_FLAGS | TCR_EL1_IPS_BITS,
} else if (el == 2) { set_ttbr_tcr_mair(el, gd->arch.tlb_addr,TCR_EL1_RSVD | TCR_FLAGS | TCR_EL1_IPS_BITS, MEMORY_ATTRIBUTES);
TCR_FLAGS | TCR_EL2_IPS_BITS,
} else { set_ttbr_tcr_mair(el, gd->arch.tlb_addr,TCR_EL2_RSVD | TCR_FLAGS | TCR_EL2_IPS_BITS, MEMORY_ATTRIBUTES);
TCR_FLAGS | TCR_EL3_IPS_BITS,
} /* enable the mmu */TCR_EL3_RSVD | TCR_FLAGS | TCR_EL3_IPS_BITS, MEMORY_ATTRIBUTES);
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 6d42f5533a74..8e577b34e4ba 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -109,6 +109,10 @@ TCR_IRGN_WBWA | \ TCR_T0SZ(VA_BITS))
+#define TCR_EL1_RSVD (1 << 31) +#define TCR_EL2_RSVD (1 << 31 | 1 << 23) +#define TCR_EL3_RSVD (1 << 31 | 1 << 23)
#ifndef __ASSEMBLY__ void set_pgtable_section(u64 *page_table, u64 index, u64 section, u64 memory_type); -- 2.3.2
Acked-by: david.feng fenghua@phytium.com.cn

From: Thierry Reding treding@nvidia.com
Initialize all GICD_IGROUPRn registers and set up GICC_CTLR to enable interrupts to the primary CPU. This fixes issues seen after booting a Linux kernel from U-Boot.
Suggested-by: Marc Zyngier marc.zyngier@arm.com Suggested-by: Mark Rutland mark.rutland@arm.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Mark Rutland mark.rutland@arm.com Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com --- arch/arm/lib/gic_64.S | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/lib/gic_64.S b/arch/arm/lib/gic_64.S index a3e18f7713e5..62d0022408bc 100644 --- a/arch/arm/lib/gic_64.S +++ b/arch/arm/lib/gic_64.S @@ -46,11 +46,19 @@ ENTRY(gic_init_secure) ldr w9, [x0, GICD_TYPER] and w10, w9, #0x1f /* ITLinesNumber */ cbz w10, 1f /* No SPIs */ - add x11, x0, (GICD_IGROUPRn + 4) + add x11, x0, GICD_IGROUPRn mov w9, #~0 /* Config SPIs as Grp1 */ + str w9, [x11], #0x4 0: str w9, [x11], #0x4 sub w10, w10, #0x1 cbnz w10, 0b + + ldr x1, =GICC_BASE /* GICC_CTLR */ + mov w0, #3 /* EnableGrp0 | EnableGrp1 */ + str w0, [x1] + + mov w0, #1 << 7 /* allow NS access to GICC_PMR */ + str w0, [x1, #4] /* GICC_PMR */ #endif 1: ret

Hi Thierry,
On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
Initialize all GICD_IGROUPRn registers and set up GICC_CTLR to enable interrupts to the primary CPU. This fixes issues seen after booting a Linux kernel from U-Boot.
Suggested-by: Marc Zyngier marc.zyngier@arm.com Suggested-by: Mark Rutland mark.rutland@arm.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Mark Rutland mark.rutland@arm.com Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/lib/gic_64.S | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/lib/gic_64.S b/arch/arm/lib/gic_64.S index a3e18f7713e5..62d0022408bc 100644 --- a/arch/arm/lib/gic_64.S +++ b/arch/arm/lib/gic_64.S @@ -46,11 +46,19 @@ ENTRY(gic_init_secure) ldr w9, [x0, GICD_TYPER] and w10, w9, #0x1f /* ITLinesNumber */ cbz w10, 1f /* No SPIs */
- add x11, x0, (GICD_IGROUPRn + 4)
- add x11, x0, GICD_IGROUPRn mov w9, #~0 /* Config SPIs as Grp1 */
- str w9, [x11], #0x4
0: str w9, [x11], #0x4 sub w10, w10, #0x1 cbnz w10, 0b
- ldr x1, =GICC_BASE /* GICC_CTLR */
- mov w0, #3 /* EnableGrp0 | EnableGrp1 */
- str w0, [x1]
- mov w0, #1 << 7 /* allow NS access to GICC_PMR */
- str w0, [x1, #4] /* GICC_PMR */
#endif 1: ret
Looking at the code that currently sits in the u-boot repo, it looks like you are duplicating functionality that is provided by gic_init_secure_percpu.
Could your boot failure be a case of this function not being called on all CPUs?
Thanks,
M.

From: Thierry Reding treding@nvidia.com
Some SoCs come with a custom timer interface, so allow them to use that instead.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com --- arch/arm/cpu/armv8/generic_timer.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c index 223b95e210ed..ab8573fc7cef 100644 --- a/arch/arm/cpu/armv8/generic_timer.c +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -9,6 +9,7 @@ #include <command.h> #include <asm/system.h>
+#ifndef CONFIG_SYS_TIMER_COUNTER /* * Generic timer implementation of get_tbclk() */ @@ -29,3 +30,4 @@ unsigned long timer_read_counter(void) asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); return cntpct; } +#endif

On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
Some SoCs come with a custom timer interface, so allow them to use that instead.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/cpu/armv8/generic_timer.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c index 223b95e210ed..ab8573fc7cef 100644 --- a/arch/arm/cpu/armv8/generic_timer.c +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -9,6 +9,7 @@ #include <command.h> #include <asm/system.h>
+#ifndef CONFIG_SYS_TIMER_COUNTER /*
- Generic timer implementation of get_tbclk()
*/ @@ -29,3 +30,4 @@ unsigned long timer_read_counter(void) asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); return cntpct; } +#endif
Does it mean that in this case, the generic timers are not in a working state? For ARMv8, it would make a lot more sense to make sure that the basic CPU stuff is actually in a working state, and avoid the madness that we have on ARMv7...
Thanks,
M.

hi Thierry,
-----Original Messages----- From: "Thierry Reding" thierry.reding@gmail.com Sent Time: 2015-03-20 19:47:53 (Friday) To: u-boot@lists.denx.de Cc: "Marc Zyngier" marc.zyngier@arm.com Subject: [U-Boot] [PATCH 6/6] armv8: Allow SoCs to override the generic timer
From: Thierry Reding treding@nvidia.com
Some SoCs come with a custom timer interface, so allow them to use that instead.
Arch timer is always available when core running, It's better to use arch timer instead of other custom timer interface.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/cpu/armv8/generic_timer.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c index 223b95e210ed..ab8573fc7cef 100644 --- a/arch/arm/cpu/armv8/generic_timer.c +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -9,6 +9,7 @@ #include <command.h> #include <asm/system.h>
+#ifndef CONFIG_SYS_TIMER_COUNTER /*
- Generic timer implementation of get_tbclk()
*/ @@ -29,3 +30,4 @@ unsigned long timer_read_counter(void) asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); return cntpct; }
+#endif
2.3.2
Yours.

On 20/03/15 11:47, Thierry Reding wrote:
From: Thierry Reding treding@nvidia.com
While generating the page tables, a running integer index is shifted by SECTION_SHIFT (29) and causes overflow for any integer bigger than 7. The page tables therefore alias to the same 8 sections and cause U-Boot to hang once the MMU is enabled.
Fix this by making the index a 64-bit unsigned integer and so avoid the overflow.
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
Acked-by: Marc Zyngier marc.zyngier@arm.com
arch/arm/cpu/armv8/cache_v8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index c5ec5297cd39..254a629a3b8c 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -25,9 +25,9 @@ void set_pgtable_section(u64 *page_table, u64 index, u64 section, /* to activate the MMU we need to set up virtual memory */ static void mmu_setup(void) {
- int i, j, el; bd_t *bd = gd->bd;
- u64 *page_table = (u64 *)gd->arch.tlb_addr;
u64 *page_table = (u64 *)gd->arch.tlb_addr, i, j;
int el;
/* Setup an identity-mapping for all spaces */ for (i = 0; i < (PGTABLE_SIZE >> 3); i++) {

-----Original Messages----- From: "Thierry Reding" thierry.reding@gmail.com Sent Time: 2015-03-20 19:47:48 (Friday) To: u-boot@lists.denx.de Cc: "Marc Zyngier" marc.zyngier@arm.com Subject: [U-Boot] [PATCH 1/6] armv8/cache: Fix page table creation
From: Thierry Reding treding@nvidia.com
While generating the page tables, a running integer index is shifted by SECTION_SHIFT (29) and causes overflow for any integer bigger than 7. The page tables therefore alias to the same 8 sections and cause U-Boot to hang once the MMU is enabled.
Fix this by making the index a 64-bit unsigned integer and so avoid the overflow.
Acked-by: david.feng fenghua@phytium.com.cn
Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Thierry Reding treding@nvidia.com
arch/arm/cpu/armv8/cache_v8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index c5ec5297cd39..254a629a3b8c 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -25,9 +25,9 @@ void set_pgtable_section(u64 *page_table, u64 index, u64 section, /* to activate the MMU we need to set up virtual memory */ static void mmu_setup(void) {
- int i, j, el; bd_t *bd = gd->bd;
- u64 *page_table = (u64 *)gd->arch.tlb_addr;
u64 *page_table = (u64 *)gd->arch.tlb_addr, i, j;
int el;
/* Setup an identity-mapping for all spaces */ for (i = 0; i < (PGTABLE_SIZE >> 3); i++) {
-- 2.3.2
A previous patch did the same work, but got no reply.
Yours.

Hello Thierry,
I assume there will be a v2 series?
(asking so that I can mark the series "Changes Requested")
Amicalement,

Hello Albert,
On Thu, 16 Apr 2015 13:24:50 +0200, Albert ARIBAUD albert.u.boot@aribaud.net wrote:
Hello Thierry,
I assume there will be a v2 series?
(asking so that I can mark the series "Changes Requested")
Ping.
Amicalement,
participants (4)
-
Albert ARIBAUD
-
FengHua
-
Marc Zyngier
-
Thierry Reding