Extend ARMv8 support
Subsystems (2)
cover Extend ARMv8 support
This patchset is meant is created in preparation to submission of patch series which will add support of the Cavium ThunderX SoC. This series adds support of setting up 2-level page tables as well as functions which allow issuing firmware calls
PATCH 1/3 armv8:New MMU setup code allowing to set up 2-level page tables
This patch adds code which sets up 2-level page tables on ARM64 thus extending available VA space. CPUs implementing 64k translation granule are able to use direct PA-VA mapping of the whole 48 bit address space.
It also adds the ability to reset the SCTRL register at the very beginning of execution to avoid interference from stale mappings set up by early firmware/loaders/etc.
--- arch/arm/cpu/armv8/cache_v8.c | 95 ++++++++++++++++++++++++++++++++++++++ arch/arm/cpu/armv8/start.S | 36 +++++++++++++++ arch/arm/include/asm/armv8/mmu.h | 79 ++++++++++++++++++++++++++++--- arch/arm/include/asm/global_data.h | 1 + arch/arm/include/asm/system.h | 6 +++ arch/arm/lib/board.c | 6 ++- 6 files changed, 215 insertions(+), 8 deletions(-)
arch/arm/cpu/armv8/cache_v8.c +95 -0
@@ -12,6 +12,8 @@DECLARE_GLOBAL_DATA_PTR ; #ifndef CONFIG_SYS_DCACHE_OFF + +#ifndef CONFIG_SYS_FULL_VA void set_pgtable_section(u64 *page_table, u64 index, u64 section, u64 memory_type) {
@@ -65,6 +67,99 @@ static void mmu_setup(void)set_sctlr (get_sctlr () |CR_M ); } +#else + +static void set_ptl1_entry (u64 index,u64 ptl2_entry) +{ +u64 *pgd = (u64 *)gd->arch.tlb_addr; +u64 value; + + value = ptl2_entry |PTL1_TYPE_TABLE ; + pgd[index] = value; +} + +static void set_ptl2_block (u64 ptl1,u64 bfn,u64 address,u64 memory_type) +{ +u64 *pmd = (u64 *)ptl1; +u64 value; + + value = address |PTL2_TYPE_BLOCK |PTL2_BLOCK_AF ; + value |=PMD_ATTRINDX (memory_type); + pmd[bfn] = value; +} + +static struct mm_region mem_map[] =CONFIG_SYS_MEM_MAP ; + +#define PTL1_ENTRIES CONFIG_SYS_PTL1_ENTRIES +#define PTL2_ENTRIES CONFIG_SYS_PTL2_ENTRIES + +static void setup_pgtables (void ) +{ +int l1_e, l2_e; +unsigned long pmd =0 ; +unsigned long address; + +/* Setup the PMD pointers */ +for (l1_e =0 ; l1_e <CONFIG_SYS_MEM_MAP_SIZE ; l1_e++) { + gd->arch.pmd_addr[l1_e] = gd->arch.tlb_addr + +PTL1_ENTRIES *sizeof (u64); + gd->arch.pmd_addr[l1_e] +=PTL2_ENTRIES *sizeof (u64) * l1_e; + gd->arch.pmd_addr[l1_e] +=0xffffUL ; + gd->arch.pmd_addr[l1_e] &= ~0xffffUL ; + } + +/* Setup the page tables */ +for (l1_e =0 ; l1_e <PTL1_ENTRIES ; l1_e++) { +if (mem_map[pmd].base == + (uintptr_t )l1_e <<PTL1_BITS ) { +set_ptl1_entry (l1_e, gd->arch.pmd_addr[pmd]); + +for (l2_e =0 ; l2_e <PTL2_ENTRIES ; l2_e++) { + address = mem_map[pmd].base + + (uintptr_t )l2_e *BLOCK_SIZE ; +set_ptl2_block (gd->arch.pmd_addr[pmd], l2_e, + address, mem_map[pmd].attrs); + } + + pmd++; + }else { +set_ptl1_entry (l1_e,0 ); + } +} +} + +/* to activate the MMU we need to set up page tables */ +static void mmu_setup (void ) +{ +int el; +unsigned long coreid =read_mpidr () &CONFIG_COREID_MASK ; + +/* Set up page tables only on BSP */ +if (coreid ==BSP_COREID ) +setup_pgtables (); + +/* load TTBR0 */ + el =current_el (); + +if (el ==1 ) { +set_ttbr_tcr_mair (el, gd->arch.tlb_addr, +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 , +MEMORY_ATTRIBUTES ); + }else { +set_ttbr_tcr_mair (el, gd->arch.tlb_addr, +TCR_FLAGS |TCR_EL3_IPS_BITS , +MEMORY_ATTRIBUTES ); + } +/* enable the mmu */ +set_sctlr (get_sctlr () |CR_M ); +} + +#endif +/* * Performs a invalidation of the entire data cache at all levels */
arch/arm/cpu/armv8/start.S +36 -0
@@ -19,6 +19,9 @@ .globl _start _start: +#ifdef CONFIG_SYS_RESET_SCTRL + bl reset_sctrl +#endif b reset .align 3
@@ -97,6 +100,39 @@ master_cpu: bl _main +#ifdef CONFIG_SYS_RESET_SCTRL +reset_sctrl: + switch_el x1, 3f, 2f, 1f +3: + mrs x0, sctlr_el3 + b 0f +2: + mrs x0, sctlr_el2 + b 0f +1: + mrs x0, sctlr_el1 + +0: + ldr x1, =0xfdfffffa + and x0, x0, x1 + + switch_el x1, 6f, 5f, 4f +6: + msr sctlr_el3, x0 + b 7f +5: + msr sctlr_el2, x0 + b 7f +4: + msr sctlr_el1, x0 + +7: + dsb sy + isb + b __asm_invalidate_tlb_all + ret +#endif + /*-----------------------------------------------------------------------*/ WEAK(apply_core_errata)
arch/arm/include/asm/armv8/mmu.h +73 -6
134 lines not on this page · raw message
arch/arm/include/asm/global_data.h +1 -0
@@ -42,6 +42,7 @@ struct arch_global_data {unsigned long long timer_reset_value;#if !(defined(CONFIG_SYS_ICACHE_OFF ) && defined(CONFIG_SYS_DCACHE_OFF ))unsigned long tlb_addr; +unsigned long pmd_addr[CONFIG_SYS_PTL1_ENTRIES ];unsigned long tlb_size;#endif
arch/arm/include/asm/system.h +6 -0
@@ -14,7 +14,11 @@#define CR_WXN (1 << 19)/* Write Permision Imply XN */ #define CR_EE (1 << 25)/* Exception (Big) Endian */ +#ifndef CONFIG_SYS_FULL_VA #define PGTABLE_SIZE (0x10000) +#else +#define PGTABLE_SIZE CONFIG_SYS_PGTABLE_SIZE +#endif #ifndef __ASSEMBLY__
@@ -129,7 +133,9 @@ void flush_l3_cache(void);#define CR_AFE (1 << 29)/* Access flag enable */ #define CR_TE (1 << 30)/* Thumb exception enable */ +#ifndef PGTABLE_SIZE #define PGTABLE_SIZE (4096 * 4) +#endif /* * This is used to ensure the compiler did actually allocate the register we
arch/arm/lib/board.c +4 -2
@@ -327,10 +327,12 @@ void board_init_f(ulong bootflag)#if !(defined(CONFIG_SYS_ICACHE_OFF ) && defined(CONFIG_SYS_DCACHE_OFF ))/* reserve TLB table */ gd->arch.tlb_size =PGTABLE_SIZE ; - addr -= gd->arch.tlb_size; + gd->arch.tlb_size +=0xffff ; + gd->arch.tlb_size &= ~(0x10000 -1 ); -/* round down to next 64 kB limit */ + addr -= gd->arch.tlb_size; addr &= ~(0x10000 -1 ); +/* round down to next 64 kB limit */ gd->arch.tlb_addr = addr;debug ("TLB table from %08lx to %08lx\n" , addr, addr + gd->arch.tlb_size);
Signature · 1 line
2.3.3
PATCH 2/3 armv8:Add SMC calls infrastructure
In reply to Sergey TemerkhanovThis commit adds functions issuing calls to firmware. This allows to use services such as PSCI provided by firmware, e.g. ATF
--- arch/arm/cpu/armv8/Makefile | 1 + arch/arm/cpu/armv8/fwcall.c | 88 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/system.h | 8 ++++ 3 files changed, 97 insertions(+) create mode 100644 arch/arm/cpu/armv8/fwcall.c
arch/arm/cpu/armv8/Makefile +1 -0
@@ -14,6 +14,7 @@ obj-y += exceptions.o obj-y += cache.o obj-y += tlb.o obj-y += transition.o +obj-y += fwcall.o obj-$(CONFIG_FSL_LSCH3) += fsl-lsch3/ obj-$(CONFIG_TARGET_XILINX_ZYNQMP) += zynqmp/
arch/arm/cpu/armv8/fwcall.c new file +88 -0
88 lines not on this page · raw message
arch/arm/include/asm/system.h +8 -0
@@ -1,6 +1,9 @@#ifndef __ASM_ARM_SYSTEM_H#define __ASM_ARM_SYSTEM_H +#include <common.h> +#include <linux/compiler.h> +#ifdef CONFIG_ARM64 /*
@@ -85,6 +88,11 @@ void smp_kick_all_cpus(void);void flush_l3_cache (void ); +#define __asmeq (x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" + +void hvc_call (struct pt_regs *args); +void smc_call (struct pt_regs *args); +#endif /* __ASSEMBLY__ */ #else /* CONFIG_ARM64 */
Signature · 1 line
2.3.3
PATCH 2/3 armv8:Add SMC calls infrastructure
Quoted 2 lines · Sergey Temerkhanov
This commit adds functions issuing calls to firmware. This allows to use services such as PSCI provided by firmware, e.g. ATF
[snip]
arch/arm/cpu/armv8/fwcall.c line 8
Quoted 10 lines
+++
b/arch/arm/cpu/armv8/fwcall.carch/arm/cpu/armv8/fwcall.c new file +8
-0@@ -0,0 +1,88 @@ +/** @file +# +# Copyright (c) 2014, Cavium Inc. All rights reserved.<BR> +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD +# License which accompanies this distribution. The full text of the license +# may be found at +# http://opensource.org/licenses/bsd-license.php
Please use SPDX tags instead, thanks.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150401/2734cbe4/attachment.sig>
PATCH 3/3 armv8:Add psci.h from the Linux kernel
In reply to Sergey TemerkhanovThis commit adds the psci.h header file from Linux kernel which contains definitions related to the PSCI interface provided by firmware
--- include/linux/psci.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 include/linux/psci.h
include/linux/psci.h new file +90 -0
@@ -0,0 +1,90 @@ +/* +* ARM Power State and Coordination Interface (PSCI) header +* +* This header holds common PSCI defines and macros shared +* by: ARM kernel, ARM64 kernel, KVM ARM/ARM64 and user space. +* +* Copyright (C) 2014 Linaro Ltd. +* Author: Anup Patel <[email protected]> +*/ + +#ifndef _UAPI_LINUX_PSCI_H +#define _UAPI_LINUX_PSCI_H + +/* +* PSCI v0.1 interface +* +* The PSCI v0.1 function numbers are implementation defined. +* +* Only PSCI return values such as: SUCCESS, NOT_SUPPORTED, +* INVALID_PARAMS, and DENIED defined below are applicable +* to PSCI v0.1. +*/ + +/* PSCI v0.2 interface */ +#define PSCI_0_2_FN_BASE 0x84000000 +#define PSCI_0_2_FN (n) (PSCI_0_2_FN_BASE + (n)) +#define PSCI_0_2_64BIT 0x40000000 +#define PSCI_0_2_FN64_BASE \ + (PSCI_0_2_FN_BASE + PSCI_0_2_64BIT) +#define PSCI_0_2_FN64 (n) (PSCI_0_2_FN64_BASE + (n)) + +#define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0) +#define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1) +#define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2) +#define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3) +#define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4) +#define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5) +#define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6) +#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7) +#define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8) +#define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9) + +#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) +#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) +#define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) +#define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5) +#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) + +/* PSCI v0.2 power state encoding for CPU_SUSPEND function */ +#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff +#define PSCI_0_2_POWER_STATE_ID_SHIFT 0 +#define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16 +#define PSCI_0_2_POWER_STATE_TYPE_MASK \ + (0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT) +#define PSCI_0_2_POWER_STATE_AFFL_SHIFT 24 +#define PSCI_0_2_POWER_STATE_AFFL_MASK \ + (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) + +/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ +#define PSCI_0_2_AFFINITY_LEVEL_ON 0 +#define PSCI_0_2_AFFINITY_LEVEL_OFF 1 +#define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING 2 + +/* PSCI v0.2 multicore support in Trusted OS returned by MIGRATE_INFO_TYPE */ +#define PSCI_0_2_TOS_UP_MIGRATE 0 +#define PSCI_0_2_TOS_UP_NO_MIGRATE 1 +#define PSCI_0_2_TOS_MP 2 + +/* PSCI version decoding (independent of PSCI version) */ +#define PSCI_VERSION_MAJOR_SHIFT 16 +#define PSCI_VERSION_MINOR_MASK \ + ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) +#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK +#define PSCI_VERSION_MAJOR (ver) \ + (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) +#define PSCI_VERSION_MINOR (ver) \ + ((ver) & PSCI_VERSION_MINOR_MASK) + +/* PSCI return values (inclusive of all PSCI versions) */ +#define PSCI_RET_SUCCESS 0 +#define PSCI_RET_NOT_SUPPORTED -1 +#define PSCI_RET_INVALID_PARAMS -2 +#define PSCI_RET_DENIED -3 +#define PSCI_RET_ALREADY_ON -4 +#define PSCI_RET_ON_PENDING -5 +#define PSCI_RET_INTERNAL_FAILURE -6 +#define PSCI_RET_NOT_PRESENT -7 +#define PSCI_RET_DISABLED -8 + +#endif /* _UAPI_LINUX_PSCI_H */
Signature · 1 line
2.3.3
cover Extend ARMv8 support
In reply to Sergey TemerkhanovHello Sergey,
Quoted 4 lines · Sergey Temerkhanov
This patchset is meant is created in preparation to submission of patch series which will add support of the Cavium ThunderX SoC. This series adds support of setting up 2-level page tables as well as functions which allow issuing firmware calls
I'd rather you submitted a single series with both these and the ThunderX patches.
Amicalement,
Signature · 1 line
Albert.