mirror of
https://github.com/torvalds/linux.git
synced 2024-11-20 02:51:44 +00:00
7af8a0f808
- Support for execute-only page permissions - Support for hibernate and DEBUG_PAGEALLOC - Support for heterogeneous systems with mismatches cache line sizes - Errata workarounds (A53 843419 update and QorIQ A-008585 timer bug) - arm64 PMU perf updates, including cpumasks for heterogeneous systems - Set UTS_MACHINE for building rpm packages - Yet another head.S tidy-up - Some cleanups and refactoring, particularly in the NUMA code - Lots of random, non-critical fixes across the board -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABCgAGBQJX7k31AAoJELescNyEwWM0XX0H/iOaWCfKlWOhvBsStGUCsLrK XryTzQT2KjdnLKf3jwP+1ateCuBR5ROurYxoDCX5/7mD63c5KiI338Vbv61a1lE1 AAwjt1stmQVUg/j+kqnuQwB/0DYg+2C8se3D3q5Iyn7zc19cDZJEGcBHNrvLMufc XgHrgHgl/rzBDDlHJXleknDFge/MfhU5/Q1vJMRRb4JYrpAtmIokzCO75CYMRcCT ND2QbmppKtsyuFPGUTVbAFzJlP6dGKb3eruYta7/ct5d0pJQxav3u98D2yWGfjdM YaYq1EmX5Pol7rWumqLtk0+mA9yCFcKLLc+PrJu20Vx0UkvOq8G8Xt70sHNvZU8= =gdPM -----END PGP SIGNATURE----- Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux Pull arm64 updates from Will Deacon: "It's a bit all over the place this time with no "killer feature" to speak of. Support for mismatched cache line sizes should help people seeing whacky JIT failures on some SoCs, and the big.LITTLE perf updates have been a long time coming, but a lot of the changes here are cleanups. We stray outside arch/arm64 in a few areas: the arch/arm/ arch_timer workaround is acked by Russell, the DT/OF bits are acked by Rob, the arch_timer clocksource changes acked by Marc, CPU hotplug by tglx and jump_label by Peter (all CC'd). Summary: - Support for execute-only page permissions - Support for hibernate and DEBUG_PAGEALLOC - Support for heterogeneous systems with mismatches cache line sizes - Errata workarounds (A53 843419 update and QorIQ A-008585 timer bug) - arm64 PMU perf updates, including cpumasks for heterogeneous systems - Set UTS_MACHINE for building rpm packages - Yet another head.S tidy-up - Some cleanups and refactoring, particularly in the NUMA code - Lots of random, non-critical fixes across the board" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (100 commits) arm64: tlbflush.h: add __tlbi() macro arm64: Kconfig: remove SMP dependence for NUMA arm64: Kconfig: select OF/ACPI_NUMA under NUMA config arm64: fix dump_backtrace/unwind_frame with NULL tsk arm/arm64: arch_timer: Use archdata to indicate vdso suitability arm64: arch_timer: Work around QorIQ Erratum A-008585 arm64: arch_timer: Add device tree binding for A-008585 erratum arm64: Correctly bounds check virt_addr_valid arm64: migrate exception table users off module.h and onto extable.h arm64: pmu: Hoist pmu platform device name arm64: pmu: Probe default hw/cache counters arm64: pmu: add fallback probe table MAINTAINERS: Update ARM PMU PROFILING AND DEBUGGING entry arm64: Improve kprobes test for atomic sequence arm64/kvm: use alternative auto-nop arm64: use alternative auto-nop arm64: alternative: add auto-nop infrastructure arm64: lse: convert lse alternatives NOP padding to use __nops arm64: barriers: introduce nops and __nops macros for NOP sequences arm64: sysreg: replace open-coded mrs_s/msr_s with {read,write}_sysreg_s ...
268 lines
6.3 KiB
ArmAsm
268 lines
6.3 KiB
ArmAsm
/*
|
|
* Based on arch/arm/mm/proc.S
|
|
*
|
|
* Copyright (C) 2001 Deep Blue Solutions Ltd.
|
|
* Copyright (C) 2012 ARM Ltd.
|
|
* Author: Catalin Marinas <catalin.marinas@arm.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/linkage.h>
|
|
#include <asm/assembler.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/hwcap.h>
|
|
#include <asm/pgtable.h>
|
|
#include <asm/pgtable-hwdef.h>
|
|
#include <asm/cpufeature.h>
|
|
#include <asm/alternative.h>
|
|
|
|
#ifdef CONFIG_ARM64_64K_PAGES
|
|
#define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K
|
|
#elif defined(CONFIG_ARM64_16K_PAGES)
|
|
#define TCR_TG_FLAGS TCR_TG0_16K | TCR_TG1_16K
|
|
#else /* CONFIG_ARM64_4K_PAGES */
|
|
#define TCR_TG_FLAGS TCR_TG0_4K | TCR_TG1_4K
|
|
#endif
|
|
|
|
#define TCR_SMP_FLAGS TCR_SHARED
|
|
|
|
/* PTWs cacheable, inner/outer WBWA */
|
|
#define TCR_CACHE_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA
|
|
|
|
#define MAIR(attr, mt) ((attr) << ((mt) * 8))
|
|
|
|
/*
|
|
* cpu_do_idle()
|
|
*
|
|
* Idle the processor (wait for interrupt).
|
|
*/
|
|
ENTRY(cpu_do_idle)
|
|
dsb sy // WFI may enter a low-power mode
|
|
wfi
|
|
ret
|
|
ENDPROC(cpu_do_idle)
|
|
|
|
#ifdef CONFIG_CPU_PM
|
|
/**
|
|
* cpu_do_suspend - save CPU registers context
|
|
*
|
|
* x0: virtual address of context pointer
|
|
*/
|
|
ENTRY(cpu_do_suspend)
|
|
mrs x2, tpidr_el0
|
|
mrs x3, tpidrro_el0
|
|
mrs x4, contextidr_el1
|
|
mrs x5, cpacr_el1
|
|
mrs x6, tcr_el1
|
|
mrs x7, vbar_el1
|
|
mrs x8, mdscr_el1
|
|
mrs x9, oslsr_el1
|
|
mrs x10, sctlr_el1
|
|
stp x2, x3, [x0]
|
|
stp x4, xzr, [x0, #16]
|
|
stp x5, x6, [x0, #32]
|
|
stp x7, x8, [x0, #48]
|
|
stp x9, x10, [x0, #64]
|
|
ret
|
|
ENDPROC(cpu_do_suspend)
|
|
|
|
/**
|
|
* cpu_do_resume - restore CPU register context
|
|
*
|
|
* x0: Address of context pointer
|
|
*/
|
|
.pushsection ".idmap.text", "ax"
|
|
ENTRY(cpu_do_resume)
|
|
ldp x2, x3, [x0]
|
|
ldp x4, x5, [x0, #16]
|
|
ldp x6, x8, [x0, #32]
|
|
ldp x9, x10, [x0, #48]
|
|
ldp x11, x12, [x0, #64]
|
|
msr tpidr_el0, x2
|
|
msr tpidrro_el0, x3
|
|
msr contextidr_el1, x4
|
|
msr cpacr_el1, x6
|
|
|
|
/* Don't change t0sz here, mask those bits when restoring */
|
|
mrs x5, tcr_el1
|
|
bfi x8, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
|
|
|
|
msr tcr_el1, x8
|
|
msr vbar_el1, x9
|
|
|
|
/*
|
|
* __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking
|
|
* debug exceptions. By restoring MDSCR_EL1 here, we may take a debug
|
|
* exception. Mask them until local_dbg_restore() in cpu_suspend()
|
|
* resets them.
|
|
*/
|
|
disable_dbg
|
|
msr mdscr_el1, x10
|
|
|
|
msr sctlr_el1, x12
|
|
/*
|
|
* Restore oslsr_el1 by writing oslar_el1
|
|
*/
|
|
ubfx x11, x11, #1, #1
|
|
msr oslar_el1, x11
|
|
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
|
|
isb
|
|
ret
|
|
ENDPROC(cpu_do_resume)
|
|
.popsection
|
|
#endif
|
|
|
|
/*
|
|
* cpu_do_switch_mm(pgd_phys, tsk)
|
|
*
|
|
* Set the translation table base pointer to be pgd_phys.
|
|
*
|
|
* - pgd_phys - physical address of new TTB
|
|
*/
|
|
ENTRY(cpu_do_switch_mm)
|
|
mmid x1, x1 // get mm->context.id
|
|
bfi x0, x1, #48, #16 // set the ASID
|
|
msr ttbr0_el1, x0 // set TTBR0
|
|
isb
|
|
alternative_if ARM64_WORKAROUND_CAVIUM_27456
|
|
ic iallu
|
|
dsb nsh
|
|
isb
|
|
alternative_else_nop_endif
|
|
ret
|
|
ENDPROC(cpu_do_switch_mm)
|
|
|
|
.pushsection ".idmap.text", "ax"
|
|
/*
|
|
* void idmap_cpu_replace_ttbr1(phys_addr_t new_pgd)
|
|
*
|
|
* This is the low-level counterpart to cpu_replace_ttbr1, and should not be
|
|
* called by anything else. It can only be executed from a TTBR0 mapping.
|
|
*/
|
|
ENTRY(idmap_cpu_replace_ttbr1)
|
|
mrs x2, daif
|
|
msr daifset, #0xf
|
|
|
|
adrp x1, empty_zero_page
|
|
msr ttbr1_el1, x1
|
|
isb
|
|
|
|
tlbi vmalle1
|
|
dsb nsh
|
|
isb
|
|
|
|
msr ttbr1_el1, x0
|
|
isb
|
|
|
|
msr daif, x2
|
|
|
|
ret
|
|
ENDPROC(idmap_cpu_replace_ttbr1)
|
|
.popsection
|
|
|
|
/*
|
|
* __cpu_setup
|
|
*
|
|
* Initialise the processor for turning the MMU on. Return in x0 the
|
|
* value of the SCTLR_EL1 register.
|
|
*/
|
|
.pushsection ".idmap.text", "ax"
|
|
ENTRY(__cpu_setup)
|
|
tlbi vmalle1 // Invalidate local TLB
|
|
dsb nsh
|
|
|
|
mov x0, #3 << 20
|
|
msr cpacr_el1, x0 // Enable FP/ASIMD
|
|
mov x0, #1 << 12 // Reset mdscr_el1 and disable
|
|
msr mdscr_el1, x0 // access to the DCC from EL0
|
|
isb // Unmask debug exceptions now,
|
|
enable_dbg // since this is per-cpu
|
|
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
|
|
/*
|
|
* Memory region attributes for LPAE:
|
|
*
|
|
* n = AttrIndx[2:0]
|
|
* n MAIR
|
|
* DEVICE_nGnRnE 000 00000000
|
|
* DEVICE_nGnRE 001 00000100
|
|
* DEVICE_GRE 010 00001100
|
|
* NORMAL_NC 011 01000100
|
|
* NORMAL 100 11111111
|
|
* NORMAL_WT 101 10111011
|
|
*/
|
|
ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
|
|
MAIR(0x04, MT_DEVICE_nGnRE) | \
|
|
MAIR(0x0c, MT_DEVICE_GRE) | \
|
|
MAIR(0x44, MT_NORMAL_NC) | \
|
|
MAIR(0xff, MT_NORMAL) | \
|
|
MAIR(0xbb, MT_NORMAL_WT)
|
|
msr mair_el1, x5
|
|
/*
|
|
* Prepare SCTLR
|
|
*/
|
|
adr x5, crval
|
|
ldp w5, w6, [x5]
|
|
mrs x0, sctlr_el1
|
|
bic x0, x0, x5 // clear bits
|
|
orr x0, x0, x6 // set bits
|
|
/*
|
|
* Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
|
|
* both user and kernel.
|
|
*/
|
|
ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
|
|
TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0
|
|
tcr_set_idmap_t0sz x10, x9
|
|
|
|
/*
|
|
* Read the PARange bits from ID_AA64MMFR0_EL1 and set the IPS bits in
|
|
* TCR_EL1.
|
|
*/
|
|
mrs x9, ID_AA64MMFR0_EL1
|
|
bfi x10, x9, #32, #3
|
|
#ifdef CONFIG_ARM64_HW_AFDBM
|
|
/*
|
|
* Hardware update of the Access and Dirty bits.
|
|
*/
|
|
mrs x9, ID_AA64MMFR1_EL1
|
|
and x9, x9, #0xf
|
|
cbz x9, 2f
|
|
cmp x9, #2
|
|
b.lt 1f
|
|
orr x10, x10, #TCR_HD // hardware Dirty flag update
|
|
1: orr x10, x10, #TCR_HA // hardware Access flag update
|
|
2:
|
|
#endif /* CONFIG_ARM64_HW_AFDBM */
|
|
msr tcr_el1, x10
|
|
ret // return to head.S
|
|
ENDPROC(__cpu_setup)
|
|
|
|
/*
|
|
* We set the desired value explicitly, including those of the
|
|
* reserved bits. The values of bits EE & E0E were set early in
|
|
* el2_setup, which are left untouched below.
|
|
*
|
|
* n n T
|
|
* U E WT T UD US IHBS
|
|
* CE0 XWHW CZ ME TEEA S
|
|
* .... .IEE .... NEAI TE.I ..AD DEN0 ACAM
|
|
* 0011 0... 1101 ..0. ..0. 10.. .0.. .... < hardware reserved
|
|
* .... .1.. .... 01.1 11.1 ..01 0.01 1101 < software settings
|
|
*/
|
|
.type crval, #object
|
|
crval:
|
|
.word 0xfcffffff // clear
|
|
.word 0x34d5d91d // set
|
|
.popsection
|