14baa9922SRussell King /* 24baa9922SRussell King * arch/arm/include/asm/assembler.h 34baa9922SRussell King * 44baa9922SRussell King * Copyright (C) 1996-2000 Russell King 54baa9922SRussell King * 64baa9922SRussell King * This program is free software; you can redistribute it and/or modify 74baa9922SRussell King * it under the terms of the GNU General Public License version 2 as 84baa9922SRussell King * published by the Free Software Foundation. 94baa9922SRussell King * 104baa9922SRussell King * This file contains arm architecture specific defines 114baa9922SRussell King * for the different processors. 124baa9922SRussell King * 134baa9922SRussell King * Do not include any C declarations in this file - it is included by 144baa9922SRussell King * assembler source. 154baa9922SRussell King */ 162bc58a6fSMagnus Damm #ifndef __ASM_ASSEMBLER_H__ 172bc58a6fSMagnus Damm #define __ASM_ASSEMBLER_H__ 182bc58a6fSMagnus Damm 194baa9922SRussell King #ifndef __ASSEMBLY__ 204baa9922SRussell King #error "Only include this from assembly code" 214baa9922SRussell King #endif 224baa9922SRussell King 234baa9922SRussell King #include <asm/ptrace.h> 24247055aaSCatalin Marinas #include <asm/domain.h> 2580c59dafSDave Martin #include <asm/opcodes-virt.h> 260b1f68e8SCatalin Marinas #include <asm/asm-offsets.h> 279a2b51b6SAndrey Ryabinin #include <asm/page.h> 289a2b51b6SAndrey Ryabinin #include <asm/thread_info.h> 294baa9922SRussell King 306f6f6a70SRob Herring #define IOMEM(x) (x) 316f6f6a70SRob Herring 324baa9922SRussell King /* 334baa9922SRussell King * Endian independent macros for shifting bytes within registers. 344baa9922SRussell King */ 354baa9922SRussell King #ifndef __ARMEB__ 36d98b90eaSVictor Kamensky #define lspull lsr 37d98b90eaSVictor Kamensky #define lspush lsl 384baa9922SRussell King #define get_byte_0 lsl #0 394baa9922SRussell King #define get_byte_1 lsr #8 404baa9922SRussell King #define get_byte_2 lsr #16 414baa9922SRussell King #define get_byte_3 lsr #24 424baa9922SRussell King #define put_byte_0 lsl #0 434baa9922SRussell King #define put_byte_1 lsl #8 444baa9922SRussell King #define put_byte_2 lsl #16 454baa9922SRussell King #define put_byte_3 lsl #24 464baa9922SRussell King #else 47d98b90eaSVictor Kamensky #define lspull lsl 48d98b90eaSVictor Kamensky #define lspush lsr 494baa9922SRussell King #define get_byte_0 lsr #24 504baa9922SRussell King #define get_byte_1 lsr #16 514baa9922SRussell King #define get_byte_2 lsr #8 524baa9922SRussell King #define get_byte_3 lsl #0 534baa9922SRussell King #define put_byte_0 lsl #24 544baa9922SRussell King #define put_byte_1 lsl #16 554baa9922SRussell King #define put_byte_2 lsl #8 564baa9922SRussell King #define put_byte_3 lsl #0 574baa9922SRussell King #endif 584baa9922SRussell King 59457c2403SBen Dooks /* Select code for any configuration running in BE8 mode */ 60457c2403SBen Dooks #ifdef CONFIG_CPU_ENDIAN_BE8 61457c2403SBen Dooks #define ARM_BE8(code...) code 62457c2403SBen Dooks #else 63457c2403SBen Dooks #define ARM_BE8(code...) 64457c2403SBen Dooks #endif 65457c2403SBen Dooks 664baa9922SRussell King /* 674baa9922SRussell King * Data preload for architectures that support it 684baa9922SRussell King */ 694baa9922SRussell King #if __LINUX_ARM_ARCH__ >= 5 704baa9922SRussell King #define PLD(code...) code 714baa9922SRussell King #else 724baa9922SRussell King #define PLD(code...) 734baa9922SRussell King #endif 744baa9922SRussell King 754baa9922SRussell King /* 764baa9922SRussell King * This can be used to enable code to cacheline align the destination 774baa9922SRussell King * pointer when bulk writing to memory. Experiments on StrongARM and 784baa9922SRussell King * XScale didn't show this a worthwhile thing to do when the cache is not 794baa9922SRussell King * set to write-allocate (this would need further testing on XScale when WA 804baa9922SRussell King * is used). 814baa9922SRussell King * 824baa9922SRussell King * On Feroceon there is much to gain however, regardless of cache mode. 834baa9922SRussell King */ 844baa9922SRussell King #ifdef CONFIG_CPU_FEROCEON 854baa9922SRussell King #define CALGN(code...) code 864baa9922SRussell King #else 874baa9922SRussell King #define CALGN(code...) 884baa9922SRussell King #endif 894baa9922SRussell King 90ffa47aa6SArnd Bergmann #define IMM12_MASK 0xfff 91ffa47aa6SArnd Bergmann 924baa9922SRussell King /* 934baa9922SRussell King * Enable and disable interrupts 944baa9922SRussell King */ 954baa9922SRussell King #if __LINUX_ARM_ARCH__ >= 6 960d928b0bSUwe Kleine-König .macro disable_irq_notrace 974baa9922SRussell King cpsid i 984baa9922SRussell King .endm 994baa9922SRussell King 1000d928b0bSUwe Kleine-König .macro enable_irq_notrace 1014baa9922SRussell King cpsie i 1024baa9922SRussell King .endm 1034baa9922SRussell King #else 1040d928b0bSUwe Kleine-König .macro disable_irq_notrace 1054baa9922SRussell King msr cpsr_c, #PSR_I_BIT | SVC_MODE 1064baa9922SRussell King .endm 1074baa9922SRussell King 1080d928b0bSUwe Kleine-König .macro enable_irq_notrace 1094baa9922SRussell King msr cpsr_c, #SVC_MODE 1104baa9922SRussell King .endm 1114baa9922SRussell King #endif 1124baa9922SRussell King 1133302caddSRussell King .macro asm_trace_hardirqs_off, save=1 1140d928b0bSUwe Kleine-König #if defined(CONFIG_TRACE_IRQFLAGS) 1153302caddSRussell King .if \save 1160d928b0bSUwe Kleine-König stmdb sp!, {r0-r3, ip, lr} 1173302caddSRussell King .endif 1180d928b0bSUwe Kleine-König bl trace_hardirqs_off 1193302caddSRussell King .if \save 1200d928b0bSUwe Kleine-König ldmia sp!, {r0-r3, ip, lr} 1213302caddSRussell King .endif 1220d928b0bSUwe Kleine-König #endif 1230d928b0bSUwe Kleine-König .endm 1240d928b0bSUwe Kleine-König 1253302caddSRussell King .macro asm_trace_hardirqs_on, cond=al, save=1 1260d928b0bSUwe Kleine-König #if defined(CONFIG_TRACE_IRQFLAGS) 1270d928b0bSUwe Kleine-König /* 1280d928b0bSUwe Kleine-König * actually the registers should be pushed and pop'd conditionally, but 1290d928b0bSUwe Kleine-König * after bl the flags are certainly clobbered 1300d928b0bSUwe Kleine-König */ 1313302caddSRussell King .if \save 1320d928b0bSUwe Kleine-König stmdb sp!, {r0-r3, ip, lr} 1333302caddSRussell King .endif 1340d928b0bSUwe Kleine-König bl\cond trace_hardirqs_on 1353302caddSRussell King .if \save 1360d928b0bSUwe Kleine-König ldmia sp!, {r0-r3, ip, lr} 1373302caddSRussell King .endif 1380d928b0bSUwe Kleine-König #endif 1390d928b0bSUwe Kleine-König .endm 1400d928b0bSUwe Kleine-König 1413302caddSRussell King .macro disable_irq, save=1 1420d928b0bSUwe Kleine-König disable_irq_notrace 1433302caddSRussell King asm_trace_hardirqs_off \save 1440d928b0bSUwe Kleine-König .endm 1450d928b0bSUwe Kleine-König 1460d928b0bSUwe Kleine-König .macro enable_irq 1470d928b0bSUwe Kleine-König asm_trace_hardirqs_on 1480d928b0bSUwe Kleine-König enable_irq_notrace 1490d928b0bSUwe Kleine-König .endm 1504baa9922SRussell King /* 1514baa9922SRussell King * Save the current IRQ state and disable IRQs. Note that this macro 1524baa9922SRussell King * assumes FIQs are enabled, and that the processor is in SVC mode. 1534baa9922SRussell King */ 1544baa9922SRussell King .macro save_and_disable_irqs, oldcpsr 15555bdd694SCatalin Marinas #ifdef CONFIG_CPU_V7M 15655bdd694SCatalin Marinas mrs \oldcpsr, primask 15755bdd694SCatalin Marinas #else 1584baa9922SRussell King mrs \oldcpsr, cpsr 15955bdd694SCatalin Marinas #endif 1604baa9922SRussell King disable_irq 1614baa9922SRussell King .endm 1624baa9922SRussell King 1638e43a905SRabin Vincent .macro save_and_disable_irqs_notrace, oldcpsr 164b2bf482aSVladimir Murzin #ifdef CONFIG_CPU_V7M 165b2bf482aSVladimir Murzin mrs \oldcpsr, primask 166b2bf482aSVladimir Murzin #else 1678e43a905SRabin Vincent mrs \oldcpsr, cpsr 168b2bf482aSVladimir Murzin #endif 1698e43a905SRabin Vincent disable_irq_notrace 1708e43a905SRabin Vincent .endm 1718e43a905SRabin Vincent 1724baa9922SRussell King /* 1734baa9922SRussell King * Restore interrupt state previously stored in a register. We don't 1744baa9922SRussell King * guarantee that this will preserve the flags. 1754baa9922SRussell King */ 1760d928b0bSUwe Kleine-König .macro restore_irqs_notrace, oldcpsr 17755bdd694SCatalin Marinas #ifdef CONFIG_CPU_V7M 17855bdd694SCatalin Marinas msr primask, \oldcpsr 17955bdd694SCatalin Marinas #else 1804baa9922SRussell King msr cpsr_c, \oldcpsr 18155bdd694SCatalin Marinas #endif 1824baa9922SRussell King .endm 1834baa9922SRussell King 1840d928b0bSUwe Kleine-König .macro restore_irqs, oldcpsr 1850d928b0bSUwe Kleine-König tst \oldcpsr, #PSR_I_BIT 18601e09a28SRussell King asm_trace_hardirqs_on cond=eq 1870d928b0bSUwe Kleine-König restore_irqs_notrace \oldcpsr 1880d928b0bSUwe Kleine-König .endm 1890d928b0bSUwe Kleine-König 19039ad04ccSCatalin Marinas /* 19114327c66SRussell King * Assembly version of "adr rd, BSYM(sym)". This should only be used to 19214327c66SRussell King * reference local symbols in the same assembly file which are to be 19314327c66SRussell King * resolved by the assembler. Other usage is undefined. 19414327c66SRussell King */ 19514327c66SRussell King .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo 19614327c66SRussell King .macro badr\c, rd, sym 19714327c66SRussell King #ifdef CONFIG_THUMB2_KERNEL 19814327c66SRussell King adr\c \rd, \sym + 1 19914327c66SRussell King #else 20014327c66SRussell King adr\c \rd, \sym 20114327c66SRussell King #endif 20214327c66SRussell King .endm 20314327c66SRussell King .endr 20414327c66SRussell King 20514327c66SRussell King /* 20639ad04ccSCatalin Marinas * Get current thread_info. 20739ad04ccSCatalin Marinas */ 20839ad04ccSCatalin Marinas .macro get_thread_info, rd 2099a2b51b6SAndrey Ryabinin ARM( mov \rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT ) 21039ad04ccSCatalin Marinas THUMB( mov \rd, sp ) 2119a2b51b6SAndrey Ryabinin THUMB( lsr \rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT ) 2129a2b51b6SAndrey Ryabinin mov \rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT 21339ad04ccSCatalin Marinas .endm 21439ad04ccSCatalin Marinas 2150b1f68e8SCatalin Marinas /* 2160b1f68e8SCatalin Marinas * Increment/decrement the preempt count. 2170b1f68e8SCatalin Marinas */ 2180b1f68e8SCatalin Marinas #ifdef CONFIG_PREEMPT_COUNT 2190b1f68e8SCatalin Marinas .macro inc_preempt_count, ti, tmp 2200b1f68e8SCatalin Marinas ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count 2210b1f68e8SCatalin Marinas add \tmp, \tmp, #1 @ increment it 2220b1f68e8SCatalin Marinas str \tmp, [\ti, #TI_PREEMPT] 2230b1f68e8SCatalin Marinas .endm 2240b1f68e8SCatalin Marinas 2250b1f68e8SCatalin Marinas .macro dec_preempt_count, ti, tmp 2260b1f68e8SCatalin Marinas ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count 2270b1f68e8SCatalin Marinas sub \tmp, \tmp, #1 @ decrement it 2280b1f68e8SCatalin Marinas str \tmp, [\ti, #TI_PREEMPT] 2290b1f68e8SCatalin Marinas .endm 2300b1f68e8SCatalin Marinas 2310b1f68e8SCatalin Marinas .macro dec_preempt_count_ti, ti, tmp 2320b1f68e8SCatalin Marinas get_thread_info \ti 2330b1f68e8SCatalin Marinas dec_preempt_count \ti, \tmp 2340b1f68e8SCatalin Marinas .endm 2350b1f68e8SCatalin Marinas #else 2360b1f68e8SCatalin Marinas .macro inc_preempt_count, ti, tmp 2370b1f68e8SCatalin Marinas .endm 2380b1f68e8SCatalin Marinas 2390b1f68e8SCatalin Marinas .macro dec_preempt_count, ti, tmp 2400b1f68e8SCatalin Marinas .endm 2410b1f68e8SCatalin Marinas 2420b1f68e8SCatalin Marinas .macro dec_preempt_count_ti, ti, tmp 2430b1f68e8SCatalin Marinas .endm 2440b1f68e8SCatalin Marinas #endif 2450b1f68e8SCatalin Marinas 246f441882aSVincent Whitchurch #define USERL(l, x...) \ 2474baa9922SRussell King 9999: x; \ 2484260415fSRussell King .pushsection __ex_table,"a"; \ 2494baa9922SRussell King .align 3; \ 250f441882aSVincent Whitchurch .long 9999b,l; \ 2514260415fSRussell King .popsection 252bac4e960SRussell King 253f441882aSVincent Whitchurch #define USER(x...) USERL(9001f, x) 254f441882aSVincent Whitchurch 255f00ec48fSRussell King #ifdef CONFIG_SMP 256f00ec48fSRussell King #define ALT_SMP(instr...) \ 257f00ec48fSRussell King 9998: instr 258ed3768a8SDave Martin /* 259ed3768a8SDave Martin * Note: if you get assembler errors from ALT_UP() when building with 260ed3768a8SDave Martin * CONFIG_THUMB2_KERNEL, you almost certainly need to use 261ed3768a8SDave Martin * ALT_SMP( W(instr) ... ) 262ed3768a8SDave Martin */ 263f00ec48fSRussell King #define ALT_UP(instr...) \ 264f00ec48fSRussell King .pushsection ".alt.smp.init", "a" ;\ 265f00ec48fSRussell King .long 9998b ;\ 266ed3768a8SDave Martin 9997: instr ;\ 26789c6bc58SRussell King .if . - 9997b == 2 ;\ 26889c6bc58SRussell King nop ;\ 26989c6bc58SRussell King .endif ;\ 270ed3768a8SDave Martin .if . - 9997b != 4 ;\ 271ed3768a8SDave Martin .error "ALT_UP() content must assemble to exactly 4 bytes";\ 272ed3768a8SDave Martin .endif ;\ 273f00ec48fSRussell King .popsection 274f00ec48fSRussell King #define ALT_UP_B(label) \ 275f00ec48fSRussell King .equ up_b_offset, label - 9998b ;\ 276f00ec48fSRussell King .pushsection ".alt.smp.init", "a" ;\ 277f00ec48fSRussell King .long 9998b ;\ 278ed3768a8SDave Martin W(b) . + up_b_offset ;\ 279f00ec48fSRussell King .popsection 280f00ec48fSRussell King #else 281f00ec48fSRussell King #define ALT_SMP(instr...) 282f00ec48fSRussell King #define ALT_UP(instr...) instr 283f00ec48fSRussell King #define ALT_UP_B(label) b label 284f00ec48fSRussell King #endif 285f00ec48fSRussell King 286bac4e960SRussell King /* 287d675d0bcSWill Deacon * Instruction barrier 288d675d0bcSWill Deacon */ 289d675d0bcSWill Deacon .macro instr_sync 290d675d0bcSWill Deacon #if __LINUX_ARM_ARCH__ >= 7 291d675d0bcSWill Deacon isb 292d675d0bcSWill Deacon #elif __LINUX_ARM_ARCH__ == 6 293d675d0bcSWill Deacon mcr p15, 0, r0, c7, c5, 4 294d675d0bcSWill Deacon #endif 295d675d0bcSWill Deacon .endm 296d675d0bcSWill Deacon 297d675d0bcSWill Deacon /* 298bac4e960SRussell King * SMP data memory barrier 299bac4e960SRussell King */ 300ed3768a8SDave Martin .macro smp_dmb mode 301bac4e960SRussell King #ifdef CONFIG_SMP 302bac4e960SRussell King #if __LINUX_ARM_ARCH__ >= 7 303ed3768a8SDave Martin .ifeqs "\mode","arm" 3043ea12806SWill Deacon ALT_SMP(dmb ish) 305ed3768a8SDave Martin .else 3063ea12806SWill Deacon ALT_SMP(W(dmb) ish) 307ed3768a8SDave Martin .endif 308bac4e960SRussell King #elif __LINUX_ARM_ARCH__ == 6 309f00ec48fSRussell King ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb 310f00ec48fSRussell King #else 311f00ec48fSRussell King #error Incompatible SMP platform 312bac4e960SRussell King #endif 313ed3768a8SDave Martin .ifeqs "\mode","arm" 314f00ec48fSRussell King ALT_UP(nop) 315ed3768a8SDave Martin .else 316ed3768a8SDave Martin ALT_UP(W(nop)) 317ed3768a8SDave Martin .endif 318bac4e960SRussell King #endif 319bac4e960SRussell King .endm 320b86040a5SCatalin Marinas 32155bdd694SCatalin Marinas #if defined(CONFIG_CPU_V7M) 32255bdd694SCatalin Marinas /* 32355bdd694SCatalin Marinas * setmode is used to assert to be in svc mode during boot. For v7-M 32455bdd694SCatalin Marinas * this is done in __v7m_setup, so setmode can be empty here. 32555bdd694SCatalin Marinas */ 32655bdd694SCatalin Marinas .macro setmode, mode, reg 32755bdd694SCatalin Marinas .endm 32855bdd694SCatalin Marinas #elif defined(CONFIG_THUMB2_KERNEL) 329b86040a5SCatalin Marinas .macro setmode, mode, reg 330b86040a5SCatalin Marinas mov \reg, #\mode 331b86040a5SCatalin Marinas msr cpsr_c, \reg 332b86040a5SCatalin Marinas .endm 333b86040a5SCatalin Marinas #else 334b86040a5SCatalin Marinas .macro setmode, mode, reg 335b86040a5SCatalin Marinas msr cpsr_c, #\mode 336b86040a5SCatalin Marinas .endm 337b86040a5SCatalin Marinas #endif 3388b592783SCatalin Marinas 3398b592783SCatalin Marinas /* 34080c59dafSDave Martin * Helper macro to enter SVC mode cleanly and mask interrupts. reg is 34180c59dafSDave Martin * a scratch register for the macro to overwrite. 34280c59dafSDave Martin * 34380c59dafSDave Martin * This macro is intended for forcing the CPU into SVC mode at boot time. 34480c59dafSDave Martin * you cannot return to the original mode. 34580c59dafSDave Martin */ 34680c59dafSDave Martin .macro safe_svcmode_maskall reg:req 3470e0779daSLorenzo Pieralisi #if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M) 34880c59dafSDave Martin mrs \reg , cpsr 3498e9c24a2SRussell King eor \reg, \reg, #HYP_MODE 3508e9c24a2SRussell King tst \reg, #MODE_MASK 35180c59dafSDave Martin bic \reg , \reg , #MODE_MASK 3528e9c24a2SRussell King orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE 35380c59dafSDave Martin THUMB( orr \reg , \reg , #PSR_T_BIT ) 35480c59dafSDave Martin bne 1f 3552a552d5eSMarc Zyngier orr \reg, \reg, #PSR_A_BIT 35614327c66SRussell King badr lr, 2f 3572a552d5eSMarc Zyngier msr spsr_cxsf, \reg 35880c59dafSDave Martin __MSR_ELR_HYP(14) 35980c59dafSDave Martin __ERET 3602a552d5eSMarc Zyngier 1: msr cpsr_c, \reg 36180c59dafSDave Martin 2: 3621ecec696SDave Martin #else 3631ecec696SDave Martin /* 3641ecec696SDave Martin * workaround for possibly broken pre-v6 hardware 3651ecec696SDave Martin * (akita, Sharp Zaurus C-1000, PXA270-based) 3661ecec696SDave Martin */ 3671ecec696SDave Martin setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, \reg 3681ecec696SDave Martin #endif 36980c59dafSDave Martin .endm 37080c59dafSDave Martin 37180c59dafSDave Martin /* 3728b592783SCatalin Marinas * STRT/LDRT access macros with ARM and Thumb-2 variants 3738b592783SCatalin Marinas */ 3748b592783SCatalin Marinas #ifdef CONFIG_THUMB2_KERNEL 3758b592783SCatalin Marinas 3764e7682d0SCatalin Marinas .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER() 3778b592783SCatalin Marinas 9999: 3788b592783SCatalin Marinas .if \inc == 1 379247055aaSCatalin Marinas \instr\cond\()b\()\t\().w \reg, [\ptr, #\off] 3808b592783SCatalin Marinas .elseif \inc == 4 381247055aaSCatalin Marinas \instr\cond\()\t\().w \reg, [\ptr, #\off] 3828b592783SCatalin Marinas .else 3838b592783SCatalin Marinas .error "Unsupported inc macro argument" 3848b592783SCatalin Marinas .endif 3858b592783SCatalin Marinas 3864260415fSRussell King .pushsection __ex_table,"a" 3878b592783SCatalin Marinas .align 3 3888b592783SCatalin Marinas .long 9999b, \abort 3894260415fSRussell King .popsection 3908b592783SCatalin Marinas .endm 3918b592783SCatalin Marinas 3928b592783SCatalin Marinas .macro usracc, instr, reg, ptr, inc, cond, rept, abort 3938b592783SCatalin Marinas @ explicit IT instruction needed because of the label 3948b592783SCatalin Marinas @ introduced by the USER macro 3958b592783SCatalin Marinas .ifnc \cond,al 3968b592783SCatalin Marinas .if \rept == 1 3978b592783SCatalin Marinas itt \cond 3988b592783SCatalin Marinas .elseif \rept == 2 3998b592783SCatalin Marinas ittt \cond 4008b592783SCatalin Marinas .else 4018b592783SCatalin Marinas .error "Unsupported rept macro argument" 4028b592783SCatalin Marinas .endif 4038b592783SCatalin Marinas .endif 4048b592783SCatalin Marinas 4058b592783SCatalin Marinas @ Slightly optimised to avoid incrementing the pointer twice 4068b592783SCatalin Marinas usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort 4078b592783SCatalin Marinas .if \rept == 2 4081142b71dSWill Deacon usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort 4098b592783SCatalin Marinas .endif 4108b592783SCatalin Marinas 4118b592783SCatalin Marinas add\cond \ptr, #\rept * \inc 4128b592783SCatalin Marinas .endm 4138b592783SCatalin Marinas 4148b592783SCatalin Marinas #else /* !CONFIG_THUMB2_KERNEL */ 4158b592783SCatalin Marinas 4164e7682d0SCatalin Marinas .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER() 4178b592783SCatalin Marinas .rept \rept 4188b592783SCatalin Marinas 9999: 4198b592783SCatalin Marinas .if \inc == 1 420247055aaSCatalin Marinas \instr\cond\()b\()\t \reg, [\ptr], #\inc 4218b592783SCatalin Marinas .elseif \inc == 4 422247055aaSCatalin Marinas \instr\cond\()\t \reg, [\ptr], #\inc 4238b592783SCatalin Marinas .else 4248b592783SCatalin Marinas .error "Unsupported inc macro argument" 4258b592783SCatalin Marinas .endif 4268b592783SCatalin Marinas 4274260415fSRussell King .pushsection __ex_table,"a" 4288b592783SCatalin Marinas .align 3 4298b592783SCatalin Marinas .long 9999b, \abort 4304260415fSRussell King .popsection 4318b592783SCatalin Marinas .endr 4328b592783SCatalin Marinas .endm 4338b592783SCatalin Marinas 4348b592783SCatalin Marinas #endif /* CONFIG_THUMB2_KERNEL */ 4358b592783SCatalin Marinas 4368b592783SCatalin Marinas .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f 4378b592783SCatalin Marinas usracc str, \reg, \ptr, \inc, \cond, \rept, \abort 4388b592783SCatalin Marinas .endm 4398b592783SCatalin Marinas 4408b592783SCatalin Marinas .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f 4418b592783SCatalin Marinas usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort 4428b592783SCatalin Marinas .endm 4438f51965eSDave Martin 4448f51965eSDave Martin /* Utility macro for declaring string literals */ 4458f51965eSDave Martin .macro string name:req, string 4468f51965eSDave Martin .type \name , #object 4478f51965eSDave Martin \name: 4488f51965eSDave Martin .asciz "\string" 4498f51965eSDave Martin .size \name , . - \name 4508f51965eSDave Martin .endm 4518f51965eSDave Martin 452a78d1565SRussell King .macro csdb 453a78d1565SRussell King #ifdef CONFIG_THUMB2_KERNEL 454a78d1565SRussell King .inst.w 0xf3af8014 455a78d1565SRussell King #else 456a78d1565SRussell King .inst 0xe320f014 457a78d1565SRussell King #endif 458a78d1565SRussell King .endm 459a78d1565SRussell King 4608404663fSRussell King .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req 4618404663fSRussell King #ifndef CONFIG_CPU_USE_DOMAINS 4628404663fSRussell King adds \tmp, \addr, #\size - 1 4638404663fSRussell King sbcccs \tmp, \tmp, \limit 4648404663fSRussell King bcs \bad 465a3c0f847SRussell King #ifdef CONFIG_CPU_SPECTRE 466a3c0f847SRussell King movcs \addr, #0 467a3c0f847SRussell King csdb 468a3c0f847SRussell King #endif 4698404663fSRussell King #endif 4708404663fSRussell King .endm 4718404663fSRussell King 472afaf6838SJulien Thierry .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req 473afaf6838SJulien Thierry #ifdef CONFIG_CPU_SPECTRE 474afaf6838SJulien Thierry sub \tmp, \limit, #1 475afaf6838SJulien Thierry subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr 476afaf6838SJulien Thierry addhs \tmp, \tmp, #1 @ if (tmp >= 0) { 477afaf6838SJulien Thierry subhss \tmp, \tmp, \size @ tmp = limit - (addr + size) } 478afaf6838SJulien Thierry movlo \addr, #0 @ if (tmp < 0) addr = NULL 479afaf6838SJulien Thierry csdb 480afaf6838SJulien Thierry #endif 481afaf6838SJulien Thierry .endm 482afaf6838SJulien Thierry 4832190fed6SRussell King .macro uaccess_disable, tmp, isb=1 484a5e090acSRussell King #ifdef CONFIG_CPU_SW_DOMAIN_PAN 485a5e090acSRussell King /* 486a5e090acSRussell King * Whenever we re-enter userspace, the domains should always be 487a5e090acSRussell King * set appropriately. 488a5e090acSRussell King */ 489a5e090acSRussell King mov \tmp, #DACR_UACCESS_DISABLE 490a5e090acSRussell King mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register 491a5e090acSRussell King .if \isb 492a5e090acSRussell King instr_sync 493a5e090acSRussell King .endif 494a5e090acSRussell King #endif 4952190fed6SRussell King .endm 4962190fed6SRussell King 4972190fed6SRussell King .macro uaccess_enable, tmp, isb=1 498a5e090acSRussell King #ifdef CONFIG_CPU_SW_DOMAIN_PAN 499a5e090acSRussell King /* 500a5e090acSRussell King * Whenever we re-enter userspace, the domains should always be 501a5e090acSRussell King * set appropriately. 502a5e090acSRussell King */ 503a5e090acSRussell King mov \tmp, #DACR_UACCESS_ENABLE 504a5e090acSRussell King mcr p15, 0, \tmp, c3, c0, 0 505a5e090acSRussell King .if \isb 506a5e090acSRussell King instr_sync 507a5e090acSRussell King .endif 508a5e090acSRussell King #endif 5092190fed6SRussell King .endm 5102190fed6SRussell King 5112190fed6SRussell King .macro uaccess_save, tmp 512a5e090acSRussell King #ifdef CONFIG_CPU_SW_DOMAIN_PAN 513a5e090acSRussell King mrc p15, 0, \tmp, c3, c0, 0 514e6a9dc61SRussell King str \tmp, [sp, #SVC_DACR] 515a5e090acSRussell King #endif 5162190fed6SRussell King .endm 5172190fed6SRussell King 5182190fed6SRussell King .macro uaccess_restore 519a5e090acSRussell King #ifdef CONFIG_CPU_SW_DOMAIN_PAN 520e6a9dc61SRussell King ldr r0, [sp, #SVC_DACR] 521a5e090acSRussell King mcr p15, 0, r0, c3, c0, 0 522a5e090acSRussell King #endif 5232190fed6SRussell King .endm 5242190fed6SRussell King 5256ebbf2ceSRussell King .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo 5266ebbf2ceSRussell King .macro ret\c, reg 5276ebbf2ceSRussell King #if __LINUX_ARM_ARCH__ < 6 5286ebbf2ceSRussell King mov\c pc, \reg 5296ebbf2ceSRussell King #else 5306ebbf2ceSRussell King .ifeqs "\reg", "lr" 5316ebbf2ceSRussell King bx\c \reg 5326ebbf2ceSRussell King .else 5336ebbf2ceSRussell King mov\c pc, \reg 5346ebbf2ceSRussell King .endif 5356ebbf2ceSRussell King #endif 5366ebbf2ceSRussell King .endm 5376ebbf2ceSRussell King .endr 5386ebbf2ceSRussell King 5396ebbf2ceSRussell King .macro ret.w, reg 5406ebbf2ceSRussell King ret \reg 5416ebbf2ceSRussell King #ifdef CONFIG_THUMB2_KERNEL 5426ebbf2ceSRussell King nop 5436ebbf2ceSRussell King #endif 5446ebbf2ceSRussell King .endm 5456ebbf2ceSRussell King 5468bafae20SRussell King .macro bug, msg, line 5478bafae20SRussell King #ifdef CONFIG_THUMB2_KERNEL 5488bafae20SRussell King 1: .inst 0xde02 5498bafae20SRussell King #else 5508bafae20SRussell King 1: .inst 0xe7f001f2 5518bafae20SRussell King #endif 5528bafae20SRussell King #ifdef CONFIG_DEBUG_BUGVERBOSE 5538bafae20SRussell King .pushsection .rodata.str, "aMS", %progbits, 1 5548bafae20SRussell King 2: .asciz "\msg" 5558bafae20SRussell King .popsection 5568bafae20SRussell King .pushsection __bug_table, "aw" 5578bafae20SRussell King .align 2 5588bafae20SRussell King .word 1b, 2b 5598bafae20SRussell King .hword \line 5608bafae20SRussell King .popsection 5618bafae20SRussell King #endif 5628bafae20SRussell King .endm 5638bafae20SRussell King 5640d73c3f8SMasami Hiramatsu #ifdef CONFIG_KPROBES 5650d73c3f8SMasami Hiramatsu #define _ASM_NOKPROBE(entry) \ 5660d73c3f8SMasami Hiramatsu .pushsection "_kprobe_blacklist", "aw" ; \ 5670d73c3f8SMasami Hiramatsu .balign 4 ; \ 5680d73c3f8SMasami Hiramatsu .long entry; \ 5690d73c3f8SMasami Hiramatsu .popsection 5700d73c3f8SMasami Hiramatsu #else 5710d73c3f8SMasami Hiramatsu #define _ASM_NOKPROBE(entry) 5720d73c3f8SMasami Hiramatsu #endif 5730d73c3f8SMasami Hiramatsu 5742bc58a6fSMagnus Damm #endif /* __ASM_ASSEMBLER_H__ */ 575