Path: blob/master/arch/arm/include/asm/assembler.h
17302 views
/*1* arch/arm/include/asm/assembler.h2*3* Copyright (C) 1996-2000 Russell King4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* published by the Free Software Foundation.8*9* This file contains arm architecture specific defines10* for the different processors.11*12* Do not include any C declarations in this file - it is included by13* assembler source.14*/15#ifndef __ASM_ASSEMBLER_H__16#define __ASM_ASSEMBLER_H__1718#ifndef __ASSEMBLY__19#error "Only include this from assembly code"20#endif2122#include <asm/ptrace.h>23#include <asm/domain.h>2425/*26* Endian independent macros for shifting bytes within registers.27*/28#ifndef __ARMEB__29#define pull lsr30#define push lsl31#define get_byte_0 lsl #032#define get_byte_1 lsr #833#define get_byte_2 lsr #1634#define get_byte_3 lsr #2435#define put_byte_0 lsl #036#define put_byte_1 lsl #837#define put_byte_2 lsl #1638#define put_byte_3 lsl #2439#else40#define pull lsl41#define push lsr42#define get_byte_0 lsr #2443#define get_byte_1 lsr #1644#define get_byte_2 lsr #845#define get_byte_3 lsl #046#define put_byte_0 lsl #2447#define put_byte_1 lsl #1648#define put_byte_2 lsl #849#define put_byte_3 lsl #050#endif5152/*53* Data preload for architectures that support it54*/55#if __LINUX_ARM_ARCH__ >= 556#define PLD(code...) code57#else58#define PLD(code...)59#endif6061/*62* This can be used to enable code to cacheline align the destination63* pointer when bulk writing to memory. Experiments on StrongARM and64* XScale didn't show this a worthwhile thing to do when the cache is not65* set to write-allocate (this would need further testing on XScale when WA66* is used).67*68* On Feroceon there is much to gain however, regardless of cache mode.69*/70#ifdef CONFIG_CPU_FEROCEON71#define CALGN(code...) code72#else73#define CALGN(code...)74#endif7576/*77* Enable and disable interrupts78*/79#if __LINUX_ARM_ARCH__ >= 680.macro disable_irq_notrace81cpsid i82.endm8384.macro enable_irq_notrace85cpsie i86.endm87#else88.macro disable_irq_notrace89msr cpsr_c, #PSR_I_BIT | SVC_MODE90.endm9192.macro enable_irq_notrace93msr cpsr_c, #SVC_MODE94.endm95#endif9697.macro asm_trace_hardirqs_off98#if defined(CONFIG_TRACE_IRQFLAGS)99stmdb sp!, {r0-r3, ip, lr}100bl trace_hardirqs_off101ldmia sp!, {r0-r3, ip, lr}102#endif103.endm104105.macro asm_trace_hardirqs_on_cond, cond106#if defined(CONFIG_TRACE_IRQFLAGS)107/*108* actually the registers should be pushed and pop'd conditionally, but109* after bl the flags are certainly clobbered110*/111stmdb sp!, {r0-r3, ip, lr}112bl\cond trace_hardirqs_on113ldmia sp!, {r0-r3, ip, lr}114#endif115.endm116117.macro asm_trace_hardirqs_on118asm_trace_hardirqs_on_cond al119.endm120121.macro disable_irq122disable_irq_notrace123asm_trace_hardirqs_off124.endm125126.macro enable_irq127asm_trace_hardirqs_on128enable_irq_notrace129.endm130/*131* Save the current IRQ state and disable IRQs. Note that this macro132* assumes FIQs are enabled, and that the processor is in SVC mode.133*/134.macro save_and_disable_irqs, oldcpsr135mrs \oldcpsr, cpsr136disable_irq137.endm138139/*140* Restore interrupt state previously stored in a register. We don't141* guarantee that this will preserve the flags.142*/143.macro restore_irqs_notrace, oldcpsr144msr cpsr_c, \oldcpsr145.endm146147.macro restore_irqs, oldcpsr148tst \oldcpsr, #PSR_I_BIT149asm_trace_hardirqs_on_cond eq150restore_irqs_notrace \oldcpsr151.endm152153#define USER(x...) \1549999: x; \155.pushsection __ex_table,"a"; \156.align 3; \157.long 9999b,9001f; \158.popsection159160#ifdef CONFIG_SMP161#define ALT_SMP(instr...) \1629998: instr163/*164* Note: if you get assembler errors from ALT_UP() when building with165* CONFIG_THUMB2_KERNEL, you almost certainly need to use166* ALT_SMP( W(instr) ... )167*/168#define ALT_UP(instr...) \169.pushsection ".alt.smp.init", "a" ;\170.long 9998b ;\1719997: instr ;\172.if . - 9997b != 4 ;\173.error "ALT_UP() content must assemble to exactly 4 bytes";\174.endif ;\175.popsection176#define ALT_UP_B(label) \177.equ up_b_offset, label - 9998b ;\178.pushsection ".alt.smp.init", "a" ;\179.long 9998b ;\180W(b) . + up_b_offset ;\181.popsection182#else183#define ALT_SMP(instr...)184#define ALT_UP(instr...) instr185#define ALT_UP_B(label) b label186#endif187188/*189* SMP data memory barrier190*/191.macro smp_dmb mode192#ifdef CONFIG_SMP193#if __LINUX_ARM_ARCH__ >= 7194.ifeqs "\mode","arm"195ALT_SMP(dmb)196.else197ALT_SMP(W(dmb))198.endif199#elif __LINUX_ARM_ARCH__ == 6200ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb201#else202#error Incompatible SMP platform203#endif204.ifeqs "\mode","arm"205ALT_UP(nop)206.else207ALT_UP(W(nop))208.endif209#endif210.endm211212#ifdef CONFIG_THUMB2_KERNEL213.macro setmode, mode, reg214mov \reg, #\mode215msr cpsr_c, \reg216.endm217#else218.macro setmode, mode, reg219msr cpsr_c, #\mode220.endm221#endif222223/*224* STRT/LDRT access macros with ARM and Thumb-2 variants225*/226#ifdef CONFIG_THUMB2_KERNEL227228.macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()2299999:230.if \inc == 1231\instr\cond\()b\()\t\().w \reg, [\ptr, #\off]232.elseif \inc == 4233\instr\cond\()\t\().w \reg, [\ptr, #\off]234.else235.error "Unsupported inc macro argument"236.endif237238.pushsection __ex_table,"a"239.align 3240.long 9999b, \abort241.popsection242.endm243244.macro usracc, instr, reg, ptr, inc, cond, rept, abort245@ explicit IT instruction needed because of the label246@ introduced by the USER macro247.ifnc \cond,al248.if \rept == 1249itt \cond250.elseif \rept == 2251ittt \cond252.else253.error "Unsupported rept macro argument"254.endif255.endif256257@ Slightly optimised to avoid incrementing the pointer twice258usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort259.if \rept == 2260usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort261.endif262263add\cond \ptr, #\rept * \inc264.endm265266#else /* !CONFIG_THUMB2_KERNEL */267268.macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()269.rept \rept2709999:271.if \inc == 1272\instr\cond\()b\()\t \reg, [\ptr], #\inc273.elseif \inc == 4274\instr\cond\()\t \reg, [\ptr], #\inc275.else276.error "Unsupported inc macro argument"277.endif278279.pushsection __ex_table,"a"280.align 3281.long 9999b, \abort282.popsection283.endr284.endm285286#endif /* CONFIG_THUMB2_KERNEL */287288.macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f289usracc str, \reg, \ptr, \inc, \cond, \rept, \abort290.endm291292.macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f293usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort294.endm295#endif /* __ASM_ASSEMBLER_H__ */296297298