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/fixed_code.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 * Copyright 2007-2008 Analog Devices Inc.
  11 *
  12 * Licensed under the GPL-2 or later.
  13 */
  14
  15#include <linux/linkage.h>
  16#include <linux/init.h>
  17#include <linux/unistd.h>
  18#include <asm/entry.h>
  19
  20__INIT
  21
  22ENTRY(_fixed_code_start)
  23
  24.align 16
  25ENTRY(_sigreturn_stub)
  26        P0 = __NR_rt_sigreturn;
  27        EXCPT 0;
  28        /* Speculative execution paranoia.  */
  290:      JUMP.S 0b;
  30ENDPROC (_sigreturn_stub)
  31
  32.align 16
  33        /*
  34         * Atomic swap, 8 bit.
  35         * Inputs:      P0: memory address to use
  36         *              R1: value to store
  37         * Output:      R0: old contents of the memory address, zero extended.
  38         */
  39ENTRY(_atomic_xchg32)
  40        R0 = [P0];
  41        [P0] = R1;
  42        rts;
  43ENDPROC (_atomic_xchg32)
  44
  45.align 16
  46        /*
  47         * Compare and swap, 32 bit.
  48         * Inputs:      P0: memory address to use
  49         *              R1: compare value
  50         *              R2: new value to store
  51         * The new value is stored if the contents of the memory
  52         * address is equal to the compare value.
  53         * Output:      R0: old contents of the memory address.
  54         */
  55ENTRY(_atomic_cas32)
  56        R0 = [P0];
  57        CC = R0 == R1;
  58        IF !CC JUMP 1f;
  59        [P0] = R2;
  601:
  61        rts;
  62ENDPROC (_atomic_cas32)
  63
  64.align 16
  65        /*
  66         * Atomic add, 32 bit.
  67         * Inputs:      P0: memory address to use
  68         *              R0: value to add
  69         * Outputs:     R0: new contents of the memory address.
  70         *              R1: previous contents of the memory address.
  71         */
  72ENTRY(_atomic_add32)
  73        R1 = [P0];
  74        R0 = R1 + R0;
  75        [P0] = R0;
  76        rts;
  77ENDPROC (_atomic_add32)
  78
  79.align 16
  80        /*
  81         * Atomic sub, 32 bit.
  82         * Inputs:      P0: memory address to use
  83         *              R0: value to subtract
  84         * Outputs:     R0: new contents of the memory address.
  85         *              R1: previous contents of the memory address.
  86         */
  87ENTRY(_atomic_sub32)
  88        R1 = [P0];
  89        R0 = R1 - R0;
  90        [P0] = R0;
  91        rts;
  92ENDPROC (_atomic_sub32)
  93
  94.align 16
  95        /*
  96         * Atomic ior, 32 bit.
  97         * Inputs:      P0: memory address to use
  98         *              R0: value to ior
  99         * Outputs:     R0: new contents of the memory address.
 100         *              R1: previous contents of the memory address.
 101         */
 102ENTRY(_atomic_ior32)
 103        R1 = [P0];
 104        R0 = R1 | R0;
 105        [P0] = R0;
 106        rts;
 107ENDPROC (_atomic_ior32)
 108
 109.align 16
 110        /*
 111         * Atomic and, 32 bit.
 112         * Inputs:      P0: memory address to use
 113         *              R0: value to and
 114         * Outputs:     R0: new contents of the memory address.
 115         *              R1: previous contents of the memory address.
 116         */
 117ENTRY(_atomic_and32)
 118        R1 = [P0];
 119        R0 = R1 & R0;
 120        [P0] = R0;
 121        rts;
 122ENDPROC (_atomic_and32)
 123
 124.align 16
 125        /*
 126         * Atomic xor, 32 bit.
 127         * Inputs:      P0: memory address to use
 128         *              R0: value to xor
 129         * Outputs:     R0: new contents of the memory address.
 130         *              R1: previous contents of the memory address.
 131         */
 132ENTRY(_atomic_xor32)
 133        R1 = [P0];
 134        R0 = R1 ^ R0;
 135        [P0] = R0;
 136        rts;
 137ENDPROC (_atomic_xor32)
 138
 139.align 16
 140        /*
 141         * safe_user_instruction
 142         * Four NOPS are enough to allow the pipeline to speculativily load
 143         * execute anything it wants. After that, things have gone bad, and
 144         * we are stuck - so panic. Since we might be in user space, we can't
 145         * call panic, so just cause a unhandled exception, this should cause
 146         * a dump of the trace buffer so we can tell were we are, and a reboot
 147         */
 148ENTRY(_safe_user_instruction)
 149        NOP; NOP; NOP; NOP;
 150        EXCPT 0x4;
 151ENDPROC(_safe_user_instruction)
 152
 153ENTRY(_fixed_code_end)
 154
 155__FINIT
 156