linux/arch/blackfin/kernel/fixed_code.S
<<
>>
Prefs
   1/*
   2 * This file contains sequences of code that will be copied to a
   3 * fixed location, defined in <asm/atomic_seq.h>.  The interrupt
   4 * handlers ensure that these sequences appear to be atomic when
   5 * executed from userspace.
   6 * These are aligned to 16 bytes, so that we have some space to replace
   7 * these sequences with something else (e.g. kernel traps if we ever do
   8 * BF561 SMP).
   9 */
  10#include <linux/linkage.h>
  11#include <linux/unistd.h>
  12#include <asm/entry.h>
  13
  14.text
  15ENTRY(_fixed_code_start)
  16
  17.align 16
  18ENTRY(_sigreturn_stub)
  19        P0 = __NR_rt_sigreturn;
  20        EXCPT 0;
  21        /* Speculative execution paranoia.  */
  220:      JUMP.S 0b;
  23ENDPROC (_sigreturn_stub)
  24
  25.align 16
  26        /*
  27         * Atomic swap, 8 bit.
  28         * Inputs:      P0: memory address to use
  29         *              R1: value to store
  30         * Output:      R0: old contents of the memory address, zero extended.
  31         */
  32ENTRY(_atomic_xchg32)
  33        R0 = [P0];
  34        [P0] = R1;
  35        rts;
  36ENDPROC (_atomic_xchg32)
  37
  38.align 16
  39        /*
  40         * Compare and swap, 32 bit.
  41         * Inputs:      P0: memory address to use
  42         *              R1: compare value
  43         *              R2: new value to store
  44         * The new value is stored if the contents of the memory
  45         * address is equal to the compare value.
  46         * Output:      R0: old contents of the memory address.
  47         */
  48ENTRY(_atomic_cas32)
  49        R0 = [P0];
  50        CC = R0 == R1;
  51        IF !CC JUMP 1f;
  52        [P0] = R2;
  531:
  54        rts;
  55ENDPROC (_atomic_cas32)
  56
  57.align 16
  58        /*
  59         * Atomic add, 32 bit.
  60         * Inputs:      P0: memory address to use
  61         *              R0: value to add
  62         * Outputs:     R0: new contents of the memory address.
  63         *              R1: previous contents of the memory address.
  64         */
  65ENTRY(_atomic_add32)
  66        R1 = [P0];
  67        R0 = R1 + R0;
  68        [P0] = R0;
  69        rts;
  70ENDPROC (_atomic_add32)
  71
  72.align 16
  73        /*
  74         * Atomic sub, 32 bit.
  75         * Inputs:      P0: memory address to use
  76         *              R0: value to subtract
  77         * Outputs:     R0: new contents of the memory address.
  78         *              R1: previous contents of the memory address.
  79         */
  80ENTRY(_atomic_sub32)
  81        R1 = [P0];
  82        R0 = R1 - R0;
  83        [P0] = R0;
  84        rts;
  85ENDPROC (_atomic_sub32)
  86
  87.align 16
  88        /*
  89         * Atomic ior, 32 bit.
  90         * Inputs:      P0: memory address to use
  91         *              R0: value to ior
  92         * Outputs:     R0: new contents of the memory address.
  93         *              R1: previous contents of the memory address.
  94         */
  95ENTRY(_atomic_ior32)
  96        R1 = [P0];
  97        R0 = R1 | R0;
  98        [P0] = R0;
  99        rts;
 100ENDPROC (_atomic_ior32)
 101
 102.align 16
 103        /*
 104         * Atomic ior, 32 bit.
 105         * Inputs:      P0: memory address to use
 106         *              R0: value to ior
 107         * Outputs:     R0: new contents of the memory address.
 108         *              R1: previous contents of the memory address.
 109         */
 110ENTRY(_atomic_and32)
 111        R1 = [P0];
 112        R0 = R1 & R0;
 113        [P0] = R0;
 114        rts;
 115ENDPROC (_atomic_ior32)
 116
 117.align 16
 118        /*
 119         * Atomic ior, 32 bit.
 120         * Inputs:      P0: memory address to use
 121         *              R0: value to ior
 122         * Outputs:     R0: new contents of the memory address.
 123         *              R1: previous contents of the memory address.
 124         */
 125ENTRY(_atomic_xor32)
 126        R1 = [P0];
 127        R0 = R1 ^ R0;
 128        [P0] = R0;
 129        rts;
 130ENDPROC (_atomic_ior32)
 131
 132.align 16
 133        /*
 134         * safe_user_instruction
 135         * Four NOPS are enough to allow the pipeline to speculativily load
 136         * execute anything it wants. After that, things have gone bad, and
 137         * we are stuck - so panic. Since we might be in user space, we can't
 138         * call panic, so just cause a unhandled exception, this should cause
 139         * a dump of the trace buffer so we can tell were we are, and a reboot
 140         */
 141ENTRY(_safe_user_instruction)
 142        NOP; NOP; NOP; NOP;
 143        EXCPT 0x4;
 144ENDPROC(_safe_user_instruction)
 145
 146ENTRY(_fixed_code_end)
 147