Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/blackfin/lib/ins.S
10817 views
1
/*
2
* arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
3
*
4
* Copyright 2004-2008 Analog Devices Inc.
5
* Copyright (C) 2005 Bas Vermeulen, BuyWays BV <[email protected]>
6
* Licensed under the GPL-2 or later.
7
*/
8
9
#include <linux/linkage.h>
10
#include <asm/blackfin.h>
11
12
.align 2
13
14
#ifdef CONFIG_IPIPE
15
# define DO_CLI \
16
[--sp] = rets; \
17
[--sp] = (P5:0); \
18
sp += -12; \
19
call ___ipipe_disable_root_irqs_hw; \
20
sp += 12; \
21
(P5:0) = [sp++];
22
# define CLI_INNER_NOP
23
#else
24
# define DO_CLI cli R3;
25
# define CLI_INNER_NOP nop; nop; nop;
26
#endif
27
28
#ifdef CONFIG_IPIPE
29
# define DO_STI \
30
sp += -12; \
31
call ___ipipe_enable_root_irqs_hw; \
32
sp += 12; \
33
2: rets = [sp++];
34
#else
35
# define DO_STI 2: sti R3;
36
#endif
37
38
#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
39
# define CLI_OUTER DO_CLI;
40
# define STI_OUTER DO_STI;
41
# define CLI_INNER 1:
42
# if ANOMALY_05000416
43
# define STI_INNER nop; 2: nop;
44
# else
45
# define STI_INNER 2:
46
# endif
47
#else
48
# define CLI_OUTER
49
# define STI_OUTER
50
# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
51
# define STI_INNER DO_STI;
52
#endif
53
54
/*
55
* Reads on the Blackfin are speculative. In Blackfin terms, this means they
56
* can be interrupted at any time (even after they have been issued on to the
57
* external bus), and re-issued after the interrupt occurs.
58
*
59
* If a FIFO is sitting on the end of the read, it will see two reads,
60
* when the core only sees one. The FIFO receives the read which is cancelled,
61
* and not delivered to the core.
62
*
63
* To solve this, interrupts are turned off before reads occur to I/O space.
64
* There are 3 versions of all these functions
65
* - turns interrupts off every read (higher overhead, but lower latency)
66
* - turns interrupts off every loop (low overhead, but longer latency)
67
* - DMA version, which do not suffer from this issue. DMA versions have
68
* different name (prefixed by dma_ ), and are located in
69
* ../kernel/bfin_dma_5xx.c
70
* Using the dma related functions are recommended for transferring large
71
* buffers in/out of FIFOs.
72
*/
73
74
#define COMMON_INS(func, ops) \
75
ENTRY(_ins##func) \
76
P0 = R0; /* P0 = port */ \
77
CLI_OUTER; /* 3 instructions before first read access */ \
78
P1 = R1; /* P1 = address */ \
79
P2 = R2; /* P2 = count */ \
80
SSYNC; \
81
\
82
LSETUP(1f, 2f) LC0 = P2; \
83
CLI_INNER; \
84
ops; \
85
STI_INNER; \
86
\
87
STI_OUTER; \
88
RTS; \
89
ENDPROC(_ins##func)
90
91
COMMON_INS(l, \
92
R0 = [P0]; \
93
[P1++] = R0; \
94
)
95
96
COMMON_INS(w, \
97
R0 = W[P0]; \
98
W[P1++] = R0; \
99
)
100
101
COMMON_INS(w_8, \
102
R0 = W[P0]; \
103
B[P1++] = R0; \
104
R0 = R0 >> 8; \
105
B[P1++] = R0; \
106
)
107
108
COMMON_INS(b, \
109
R0 = B[P0]; \
110
B[P1++] = R0; \
111
)
112
113
COMMON_INS(l_16, \
114
R0 = [P0]; \
115
W[P1++] = R0; \
116
R0 = R0 >> 16; \
117
W[P1++] = R0; \
118
)
119
120