Blackfin arch: cleanup and unify the ins functions
authorMike Frysinger <vapier.adi@gmail.com>
Wed, 7 Jan 2009 15:14:38 +0000 (23:14 +0800)
committerBryan Wu <cooloney@kernel.org>
Wed, 7 Jan 2009 15:14:38 +0000 (23:14 +0800)
this also fixes some errors in the ipipe merge

Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
arch/blackfin/lib/ins.S

index 1b84b21ca7d1f7f653c9532ba85523d14bee8923..1863a6ba507c5426b07d02cacd4b105f676dffe1 100644 (file)
@@ -1,31 +1,9 @@
 /*
- * File:         arch/blackfin/lib/ins.S
- * Based on:
- * Author:       Bas Vermeulen <bas@buyways.nl>
+ * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
  *
- * Created:      Tue Mar 22 15:27:24 CEST 2005
- * Description:  Implementation of ins{bwl} for BlackFin processors using zero overhead loops.
- *
- * Modified:
- *               Copyright 2004-2008 Analog Devices Inc.
- *               Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/linkage.h>
 
 .align 2
 
+#ifdef CONFIG_IPIPE
+# define DO_CLI \
+       [--sp] = rets; \
+       [--sp] = (P5:0); \
+       sp += -12; \
+       call ___ipipe_stall_root_raw; \
+       sp += 12; \
+       (P5:0) = [sp++];
+# define CLI_INNER_NOP
+#else
+# define DO_CLI cli R3;
+# define CLI_INNER_NOP nop; nop; nop;
+#endif
+
+#ifdef CONFIG_IPIPE
+# define DO_STI \
+       sp += -12; \
+       call ___ipipe_unstall_root_raw; \
+       sp += 12; \
+2:     rets = [sp++];
+#else
+# define DO_STI 2: sti R3;
+#endif
+
+#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
+# define CLI_OUTER DO_CLI;
+# define STI_OUTER DO_STI;
+# define CLI_INNER 1:
+# if ANOMALY_05000416
+#  define STI_INNER nop; 2: nop;
+# else
+#  define STI_INNER 2:
+# endif
+#else
+# define CLI_OUTER
+# define STI_OUTER
+# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
+# define STI_INNER DO_STI;
+#endif
+
 /*
  * Reads on the Blackfin are speculative. In Blackfin terms, this means they
  * can be interrupted at any time (even after they have been issued on to the
  * buffers in/out of FIFOs.
  */
 
-ENTRY(_insl)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-       P0 = R0;        /* P0 = port */
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       cli R3;
-#endif
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
-.Llong_loop_s:  R0 = [P0];
-               [P1++] = R0;
-               NOP;
-.Llong_loop_e:         NOP;
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       sti R3;
-#endif
-       RTS;
-#else
-       P0 = R0;        /* P0 = port */
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
-.Llong_loop_s:
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       CLI R3;
-#endif
-       NOP; NOP; NOP;
-       R0 = [P0];
-       [P1++] = R0;
-.Llong_loop_e:
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       STI R3;
-#endif
-       RTS;
-#endif
-ENDPROC(_insl)
+#define COMMON_INS(func, ops) \
+ENTRY(_ins##func) \
+       P0 = R0;        /* P0 = port */ \
+       CLI_OUTER;      /* 3 instructions before first read access */ \
+       P1 = R1;        /* P1 = address */ \
+       P2 = R2;        /* P2 = count */ \
+       SSYNC; \
+ \
+       LSETUP(1f, 2f) LC0 = P2; \
+       CLI_INNER; \
+       ops; \
+       STI_INNER; \
+ \
+       STI_OUTER; \
+       RTS; \
+ENDPROC(_ins##func)
 
-ENTRY(_insw)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-       P0 = R0;        /* P0 = port */
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       cli R3;
-#endif
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
-.Lword_loop_s:  R0 = W[P0];
-               W[P1++] = R0;
-               NOP;
-.Lword_loop_e:         NOP;
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       sti R3;
-#endif
-       RTS;
-#else
-       P0 = R0;        /* P0 = port */
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
-.Lword_loop_s:
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       CLI R3;
-#endif
-       NOP; NOP; NOP;
-       R0 = W[P0];
-       W[P1++] = R0;
-.Lword_loop_e:
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       STI R3;
-#endif
-       RTS;
+COMMON_INS(l, \
+       R0 = [P0]; \
+       [P1++] = R0; \
+)
 
-#endif
-ENDPROC(_insw)
+COMMON_INS(w, \
+       R0 = W[P0]; \
+       W[P1++] = R0; \
+)
 
-ENTRY(_insw_8)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-       P0 = R0;        /* P0 = port */
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       cli R3;
-#endif
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2;
-.Lword8_loop_s:  R0 = W[P0];
-               B[P1++] = R0;
-               R0 = R0 >> 8;
-               B[P1++] = R0;
-               NOP;
-.Lword8_loop_e: NOP;
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       sti R3;
-#endif
-       RTS;
-#else
-       P0 = R0;        /* P0 = port */
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2;
-.Lword8_loop_s:
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       CLI R3;
-#endif
-       NOP; NOP; NOP;
-       R0 = W[P0];
-       B[P1++] = R0;
-       R0 = R0 >> 8;
-       B[P1++] = R0;
-       NOP;
-.Lword8_loop_e:
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       STI R3;
-#endif
-       RTS;
-#endif
-ENDPROC(_insw_8)
+COMMON_INS(w_8, \
+       R0 = W[P0]; \
+       B[P1++] = R0; \
+       R0 = R0 >> 8; \
+       B[P1++] = R0; \
+)
 
-ENTRY(_insb)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-       P0 = R0;        /* P0 = port */
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       cli R3;
-#endif
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
-.Lbyte_loop_s:  R0 = B[P0];
-               B[P1++] = R0;
-               NOP;
-.Lbyte_loop_e:  NOP;
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       sti R3;
-#endif
-       RTS;
-#else
-       P0 = R0;        /* P0 = port */
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
-.Lbyte_loop_s:
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       CLI R3;
-#endif
-       NOP; NOP; NOP;
-       R0 = B[P0];
-       B[P1++] = R0;
-.Lbyte_loop_e:
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       STI R3;
-#endif
-       RTS;
-#endif
-ENDPROC(_insb)
+COMMON_INS(b, \
+       R0 = B[P0]; \
+       B[P1++] = R0; \
+)
 
-ENTRY(_insl_16)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-       P0 = R0;        /* P0 = port */
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       cli R3;
-#endif
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2;
-.Llong16_loop_s:  R0 = [P0];
-                 W[P1++] = R0;
-                 R0 = R0 >> 16;
-                 W[P1++] = R0;
-                 NOP;
-.Llong16_loop_e:  NOP;
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       sti R3;
-#endif
-       RTS;
-#else
-       P0 = R0;        /* P0 = port */
-       P1 = R1;        /* P1 = address */
-       P2 = R2;        /* P2 = count */
-       SSYNC;
-       LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2;
-.Llong16_loop_s:
-#ifdef CONFIG_IPIPE
-       [--sp] = rets
-       [--sp] = (P5:0);
-       sp += -12
-       call ___ipipe_stall_root_raw
-       sp += 12
-       (P5:0) = [sp++];
-#else
-       CLI R3;
-#endif
-       NOP; NOP; NOP;
-       R0 = [P0];
-       W[P1++] = R0;
-       R0 = R0 >> 16;
-       W[P1++] = R0;
-.Llong16_loop_e:
-#ifdef CONFIG_IPIPE
-       sp += -12
-       call ___ipipe_unstall_root_raw
-       sp += 12
-       rets = [sp++]
-#else
-       STI R3;
-#endif
-       RTS;
-#endif
-ENDPROC(_insl_16)
+COMMON_INS(l_16, \
+       R0 = [P0]; \
+       W[P1++] = R0; \
+       R0 = R0 >> 16; \
+       W[P1++] = R0; \
+)