Remove FSF address from GPL notices
[fw/openocd] / src / jtag / zy1000 / jtag_minidriver.h
1 /***************************************************************************
2  *   Copyright (C) 2007-2010 by Ã˜yvind Harboe                              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
16  ***************************************************************************/
17
18 /* used to test manual mode */
19 #define TEST_MANUAL() 0
20 #define VERBOSE(a)
21
22 #if BUILD_ZY1000_MASTER
23
24 #define ZY1000_PEEK(a, b) do {b = *((volatile uint32_t *)(a)); } while (0)
25 #define ZY1000_POKE(a, b) do {*((volatile uint32_t *)(a)) = b; } while (0)
26 extern volatile void *zy1000_jtag_master;
27 #define ZY1000_JTAG_BASE ((unsigned long)zy1000_jtag_master)
28
29 #else
30
31 /* redirect this to TCP/IP */
32 #define ZY1000_JTAG_BASE 0
33 extern void zy1000_tcpout(uint32_t address, uint32_t data);
34 extern uint32_t zy1000_tcpin(uint32_t address);
35 #define ZY1000_PEEK(a, b) b = zy1000_tcpin(a)
36 #define ZY1000_POKE(a, b) zy1000_tcpout(a, b)
37
38 #endif
39
40 #if BUILD_ZY1000_MASTER
41 /* FIFO empty? */
42 static inline void waitIdle(void)
43 {
44         uint32_t empty;
45         do {
46                 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
47         } while ((empty & 0x100) == 0);
48 }
49
50 static inline void zy1000_flush_readqueue(void)
51 {
52         /* Not used w/hardware fifo */
53 }
54 static inline void zy1000_flush_callbackqueue(void)
55 {
56         /* Not used w/hardware fifo */
57 }
58 #else
59 extern void waitIdle(void);
60 void zy1000_flush_readqueue(void);
61 void zy1000_flush_callbackqueue(void);
62 void zy1000_jtag_add_callback4(jtag_callback_t callback,
63                 jtag_callback_data_t data0,
64                 jtag_callback_data_t data1,
65                 jtag_callback_data_t data2,
66                 jtag_callback_data_t data3);
67 void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0);
68 #endif
69
70 static inline void waitQueue(void)
71 {
72 /*      waitIdle(); */
73 }
74
75 static inline void sampleShiftRegister(void)
76 {
77 #if 0
78         uint32_t dummy;
79         waitIdle();
80         ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, dummy);
81 #endif
82 }
83
84 static inline void setCurrentState(enum tap_state state)
85 {
86         uint32_t a;
87         a = state;
88         int repeat = 0;
89         if (state == TAP_RESET) {
90                 /* The FPGA nor we know the current state of the CPU TAP */
91                 /* controller. This will move it to TAP for sure. */
92                 /*  */
93                 /* 5 should be enough here, 7 is what OpenOCD uses */
94                 repeat = 7;
95         }
96         waitQueue();
97         sampleShiftRegister();
98         ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | a);
99
100 }
101
102 /*
103  * Enter state and cause repeat transitions *out* of that state. So if the endState != state, then
104  * the transition from state to endState counts as a transition out of state.
105  */
106 static inline void shiftValueInner(const enum tap_state state,
107         const enum tap_state endState,
108         int repeat,
109         uint32_t value)
110 {
111         uint32_t a, b;
112         a = state;
113         b = endState;
114         waitQueue();
115         sampleShiftRegister();
116         ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value);
117 #if 1
118 #if TEST_MANUAL()
119         if ((state == TAP_DRSHIFT) && (endState != TAP_DRSHIFT)) {
120                 int i;
121                 setCurrentState(state);
122                 for (i = 0; i < repeat; i++) {
123                         int tms;
124                         tms = 0;
125                         if ((i == repeat-1) && (state != endState))
126                                 tms = 1;
127                                         /* shift out value */
128                         waitIdle();
129                         ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, (((value >> i)&1) << 1) | tms);
130                 }
131                 waitIdle();
132                 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
133                 waitIdle();
134                 /* ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); // set this state and things
135                  * break => expected */
136                 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRPAUSE);      /* set this and things will
137                                                                          * work => expected. Not
138                                                                          * setting this is not
139                                                                          * sufficient to make things
140                                                                          * break. */
141                 setCurrentState(endState);
142         } else
143                 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
144
145 #else
146         /* fast version */
147         ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
148 #endif
149 #else
150         /* maximum debug version */
151         if ((repeat > 0) && ((state == TAP_DRSHIFT) || (state == TAP_SI))) {
152                 int i;
153                 /* sample shift register for every bit. */
154                 for (i = 0; i < repeat-1; i++) {
155                         sampleShiftRegister();
156                         ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> i);
157                         ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | a);
158                 }
159                 sampleShiftRegister();
160                 ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> (repeat-1));
161                 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | b);
162         } else {
163                 sampleShiftRegister();
164                 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
165         }
166         sampleShiftRegister();
167 #endif
168 }
169
170 #if BUILD_ZY1000_MASTER
171 #define interface_jtag_add_callback(callback, in) callback(in)
172 #define interface_jtag_add_callback4(callback, in, data1, data2, \
173                 data3) jtag_set_error(callback(in, data1, data2, data3))
174 #else
175 #define interface_jtag_add_callback(callback, in) zy1000_jtag_add_callback(callback, in)
176 #define interface_jtag_add_callback4(callback, in, data1, data2, data3) zy1000_jtag_add_callback4( \
177         callback, \
178         in, \
179         data1, \
180         data2, \
181         data3)
182 #endif