Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Assembly macros and definitions

This patch introduces several assembly macros and definitions used in
the .S files across arch/arm64/ like IRQ disabling/enabling, together
with asm-offsets.c.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Olof Johansson <olof@lixom.net>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

+273
+1
arch/arm64/include/asm/asm-offsets.h
··· 1 + #include <generated/asm-offsets.h>
+109
arch/arm64/include/asm/assembler.h
··· 1 + /* 2 + * Based on arch/arm/include/asm/assembler.h 3 + * 4 + * Copyright (C) 1996-2000 Russell King 5 + * Copyright (C) 2012 ARM Ltd. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #ifndef __ASSEMBLY__ 20 + #error "Only include this from assembly code" 21 + #endif 22 + 23 + #include <asm/ptrace.h> 24 + 25 + /* 26 + * Stack pushing/popping (register pairs only). Equivalent to store decrement 27 + * before, load increment after. 28 + */ 29 + .macro push, xreg1, xreg2 30 + stp \xreg1, \xreg2, [sp, #-16]! 31 + .endm 32 + 33 + .macro pop, xreg1, xreg2 34 + ldp \xreg1, \xreg2, [sp], #16 35 + .endm 36 + 37 + /* 38 + * Enable and disable interrupts. 39 + */ 40 + .macro disable_irq 41 + msr daifset, #2 42 + .endm 43 + 44 + .macro enable_irq 45 + msr daifclr, #2 46 + .endm 47 + 48 + /* 49 + * Save/disable and restore interrupts. 50 + */ 51 + .macro save_and_disable_irqs, olddaif 52 + mrs \olddaif, daif 53 + disable_irq 54 + .endm 55 + 56 + .macro restore_irqs, olddaif 57 + msr daif, \olddaif 58 + .endm 59 + 60 + /* 61 + * Enable and disable debug exceptions. 62 + */ 63 + .macro disable_dbg 64 + msr daifset, #8 65 + .endm 66 + 67 + .macro enable_dbg 68 + msr daifclr, #8 69 + .endm 70 + 71 + .macro disable_step, tmp 72 + mrs \tmp, mdscr_el1 73 + bic \tmp, \tmp, #1 74 + msr mdscr_el1, \tmp 75 + .endm 76 + 77 + .macro enable_step, tmp 78 + mrs \tmp, mdscr_el1 79 + orr \tmp, \tmp, #1 80 + msr mdscr_el1, \tmp 81 + .endm 82 + 83 + .macro enable_dbg_if_not_stepping, tmp 84 + mrs \tmp, mdscr_el1 85 + tbnz \tmp, #1, 9990f 86 + enable_dbg 87 + 9990: 88 + .endm 89 + 90 + /* 91 + * SMP data memory barrier 92 + */ 93 + .macro smp_dmb, opt 94 + #ifdef CONFIG_SMP 95 + dmb \opt 96 + #endif 97 + .endm 98 + 99 + #define USER(l, x...) \ 100 + 9999: x; \ 101 + .section __ex_table,"a"; \ 102 + .align 3; \ 103 + .quad 9999b,l; \ 104 + .previous 105 + 106 + /* 107 + * Register aliases. 108 + */ 109 + lr .req x30 // link register
+108
arch/arm64/kernel/asm-offsets.c
··· 1 + /* 2 + * Based on arch/arm/kernel/asm-offsets.c 3 + * 4 + * Copyright (C) 1995-2003 Russell King 5 + * 2001-2002 Keith Owens 6 + * Copyright (C) 2012 ARM Ltd. 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #include <linux/sched.h> 22 + #include <linux/mm.h> 23 + #include <linux/dma-mapping.h> 24 + #include <asm/thread_info.h> 25 + #include <asm/memory.h> 26 + #include <asm/cputable.h> 27 + #include <asm/vdso_datapage.h> 28 + #include <linux/kbuild.h> 29 + 30 + int main(void) 31 + { 32 + DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); 33 + BLANK(); 34 + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 35 + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 36 + DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); 37 + DEFINE(TI_TASK, offsetof(struct thread_info, task)); 38 + DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); 39 + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); 40 + BLANK(); 41 + DEFINE(THREAD_CPU_CONTEXT, offsetof(struct task_struct, thread.cpu_context)); 42 + BLANK(); 43 + DEFINE(S_X0, offsetof(struct pt_regs, regs[0])); 44 + DEFINE(S_X1, offsetof(struct pt_regs, regs[1])); 45 + DEFINE(S_X2, offsetof(struct pt_regs, regs[2])); 46 + DEFINE(S_X3, offsetof(struct pt_regs, regs[3])); 47 + DEFINE(S_X4, offsetof(struct pt_regs, regs[4])); 48 + DEFINE(S_X5, offsetof(struct pt_regs, regs[5])); 49 + DEFINE(S_X6, offsetof(struct pt_regs, regs[6])); 50 + DEFINE(S_X7, offsetof(struct pt_regs, regs[7])); 51 + DEFINE(S_LR, offsetof(struct pt_regs, regs[30])); 52 + DEFINE(S_SP, offsetof(struct pt_regs, sp)); 53 + #ifdef CONFIG_COMPAT 54 + DEFINE(S_COMPAT_SP, offsetof(struct pt_regs, compat_sp)); 55 + #endif 56 + DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate)); 57 + DEFINE(S_PC, offsetof(struct pt_regs, pc)); 58 + DEFINE(S_ORIG_X0, offsetof(struct pt_regs, orig_x0)); 59 + DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno)); 60 + DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); 61 + BLANK(); 62 + DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); 63 + BLANK(); 64 + DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); 65 + DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags)); 66 + BLANK(); 67 + DEFINE(VM_EXEC, VM_EXEC); 68 + BLANK(); 69 + DEFINE(PAGE_SZ, PAGE_SIZE); 70 + BLANK(); 71 + DEFINE(CPU_INFO_SZ, sizeof(struct cpu_info)); 72 + DEFINE(CPU_INFO_SETUP, offsetof(struct cpu_info, cpu_setup)); 73 + BLANK(); 74 + DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL); 75 + DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); 76 + DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE); 77 + BLANK(); 78 + DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); 79 + DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); 80 + DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); 81 + DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); 82 + DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE); 83 + DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC); 84 + DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); 85 + BLANK(); 86 + DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last)); 87 + DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec)); 88 + DEFINE(VDSO_XTIME_CLK_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); 89 + DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec)); 90 + DEFINE(VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec)); 91 + DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec)); 92 + DEFINE(VDSO_WTM_CLK_NSEC, offsetof(struct vdso_data, wtm_clock_nsec)); 93 + DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count)); 94 + DEFINE(VDSO_CS_MULT, offsetof(struct vdso_data, cs_mult)); 95 + DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift)); 96 + DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest)); 97 + DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); 98 + DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall)); 99 + BLANK(); 100 + DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec)); 101 + DEFINE(TVAL_TV_USEC, offsetof(struct timeval, tv_usec)); 102 + DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec)); 103 + DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec)); 104 + BLANK(); 105 + DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); 106 + DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); 107 + return 0; 108 + }
+55
arch/arm64/mm/proc-macros.S
··· 1 + /* 2 + * Based on arch/arm/mm/proc-macros.S 3 + * 4 + * Copyright (C) 2012 ARM Ltd. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + */ 18 + 19 + #include <asm/asm-offsets.h> 20 + #include <asm/thread_info.h> 21 + 22 + /* 23 + * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm) 24 + */ 25 + .macro vma_vm_mm, rd, rn 26 + ldr \rd, [\rn, #VMA_VM_MM] 27 + .endm 28 + 29 + /* 30 + * mmid - get context id from mm pointer (mm->context.id) 31 + */ 32 + .macro mmid, rd, rn 33 + ldr \rd, [\rn, #MM_CONTEXT_ID] 34 + .endm 35 + 36 + /* 37 + * dcache_line_size - get the minimum D-cache line size from the CTR register. 38 + */ 39 + .macro dcache_line_size, reg, tmp 40 + mrs \tmp, ctr_el0 // read CTR 41 + lsr \tmp, \tmp, #16 42 + and \tmp, \tmp, #0xf // cache line size encoding 43 + mov \reg, #4 // bytes per word 44 + lsl \reg, \reg, \tmp // actual cache line size 45 + .endm 46 + 47 + /* 48 + * icache_line_size - get the minimum I-cache line size from the CTR register. 49 + */ 50 + .macro icache_line_size, reg, tmp 51 + mrs \tmp, ctr_el0 // read CTR 52 + and \tmp, \tmp, #0xf // cache line size encoding 53 + mov \reg, #4 // bytes per word 54 + lsl \reg, \reg, \tmp // actual cache line size 55 + .endm