radix: reading first page table entry
[soc.git] / src / soc / debug / jtagutils.py
1 #The server code
2 import socket
3 from socket import close, AF_INET, SOCK_STREAM
4 import sys
5 import select
6 import time
7
8
9 def client_sync(dut):
10 tck = yield dut.cbus.tck
11 tms = yield dut.cbus.tms
12 tdi = yield dut.cbus.tdi
13 dut.c.jtagremote_client_send((tck, tms, tdi))
14 #print ("about to client recv")
15 while True:
16 tdo = dut.c.jtagremote_client_recv(timeout=0)
17 if tdo is not None:
18 break
19 yield
20 yield dut.cbus.tdo.eq(tdo)
21
22
23 def tms_state_set(dut, bits):
24 for bit in bits:
25 yield dut.cbus.tck.eq(1)
26 yield dut.cbus.tms.eq(bit)
27 yield from client_sync(dut)
28 yield
29 yield dut.cbus.tck.eq(0)
30 yield from client_sync(dut)
31 yield
32 yield from client_sync(dut)
33 yield dut.cbus.tms.eq(0)
34 yield from client_sync(dut)
35
36
37 def tms_data_getset(dut, tms, d_len, d_in=0):
38 res = 0
39 yield dut.cbus.tms.eq(tms)
40 for i in range(d_len):
41 tdi = 1 if (d_in & (1<<i)) else 0
42 yield dut.cbus.tck.eq(1)
43 yield from client_sync(dut)
44 res |= (1<<i) if (yield dut.cbus.tdo) else 0
45 yield
46 yield from client_sync(dut)
47 yield dut.cbus.tdi.eq(tdi)
48 yield dut.cbus.tck.eq(0)
49 yield from client_sync(dut)
50 yield
51 yield from client_sync(dut)
52 yield dut.cbus.tms.eq(0)
53 yield from client_sync(dut)
54
55 return res
56
57
58 def jtag_set_reset(dut):
59 yield from tms_state_set(dut, [1, 1, 1, 1, 1])
60
61 def jtag_set_shift_dr(dut):
62 yield from tms_state_set(dut, [1, 0, 0])
63
64 def jtag_set_shift_ir(dut):
65 yield from tms_state_set(dut, [1, 1, 0])
66
67 def jtag_set_run(dut):
68 yield from tms_state_set(dut, [0])
69
70 def jtag_set_idle(dut):
71 yield from tms_state_set(dut, [1, 1, 0])
72
73
74 def jtag_set_ir(dut, addr):
75 yield from jtag_set_run(dut)
76 yield from jtag_set_shift_ir(dut)
77 result = yield from tms_data_getset(dut, 0, dut._ir_width, addr)
78 yield from jtag_set_idle(dut)
79 return result
80
81
82 def jtag_set_get_dr(dut, d_len, d_in=0):
83 yield from jtag_set_shift_dr(dut)
84 result = yield from tms_data_getset(dut, 0, d_len, d_in)
85 yield from jtag_set_idle(dut)
86 return result
87
88 def jtag_read_write_reg(dut, addr, d_len, d_in=0):
89 yield from jtag_set_ir(dut, addr)
90 return (yield from jtag_set_get_dr(dut, d_len, d_in))
91
92
93 def jtag_srv(dut):
94 while not dut.stop:
95 # loop and receive data from client
96 tdo = yield dut.bus.tdo
97 #print ("server tdo data", tdo)
98 data = dut.s.jtagremote_server_recv(tdo)
99 #print ("server recv data", data)
100 if not data:
101 yield
102 continue
103 tck, tms, tdi = data
104 yield dut.bus.tck.eq(tck)
105 yield dut.bus.tms.eq(tms)
106 yield dut.bus.tdi.eq(tdi)
107 yield
108 print ("jtag srv stopping")
109
110
111 def get_data(s, length=1024, timeout=None):
112 r, w, e = select.select( [s], [], [], timeout)
113
114 for sock in r:
115 #incoming message from remote server
116 if sock == s:
117 return sock.recv(length)
118 return None
119
120 class JTAGServer:
121 def __init__(self, debug=False):
122 self.debug = debug
123 HOST = ''
124 PORT = 44853
125 s = socket.socket(AF_INET, SOCK_STREAM)
126 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
127 s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
128 s.bind((HOST, PORT))
129 s.listen(1) #only needs to receive one connection (the client)
130 self.s = s
131 self.conn = None
132
133 def close(self):
134 self.s.close()
135 if self.conn:
136 self.conn.close()
137
138 def get_connection(self, timeout=0):
139 r, w, e = select.select( [self.s], [], [], timeout)
140 for sock in r:
141 #incoming message from remote server
142 if sock == self.s:
143 conn, addr = self.s.accept() #accepts the connection
144 if self.debug:
145 print("Connected by: ", addr) #prints the connection
146 conn.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
147 self.conn = conn
148 return conn
149 return None
150
151 def get_data(self, length=1024, timeout=None):
152 return get_data(self.conn, length, timeout)
153
154 def send(self, data):
155 return self.conn.sendall(data)
156
157 def jtagremote_server_recv(self, tdo):
158 data = self.get_data(1, 0) # read 1 byte, non-blocking
159 if data is None:
160 return None # no data read
161 data = bytes.decode(data)
162 if self.debug:
163 print ("jtagremote_server_recv", data)
164 # request to read TDO
165 if data == 'R':
166 self.send(str.encode(chr(ord('0') + tdo)))
167 return [] # no data
168 # decode tck, tms, tdi
169 data = ord(data) - ord('0')
170 # encode tck, tms and tdi as number from 0-7
171 tdi = 1 if (data & 1) else 0
172 tms = 1 if (data & 2) else 0
173 tck = 1 if (data & 4) else 0
174
175 return (tck, tms, tdi)
176
177
178
179 class JTAGClient:
180 def __init__(self, debug=False):
181 self.debug = debug
182 HOST = 'localhost'
183 PORT = 44853
184 s = socket.socket(AF_INET, SOCK_STREAM)
185 s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
186 s.connect((HOST, PORT))
187 self.s = s
188
189 def close(self):
190 self.s.close()
191
192 def get_data(self, length=1024, timeout=None):
193 return get_data(self.s, length, timeout)
194
195 def send(self, data):
196 return self.s.sendall(data)
197
198 def jtagremote_client_send(self, to_send):
199 # encode tck, tms and tdi as number from 0-7
200 tck, tms, tdi = to_send
201 data = 0
202 if tdi: data |= 1
203 if tms: data |= 2
204 if tck: data |= 4
205 data = chr(ord('0') + data)
206 self.send(str.encode(data))
207 if self.debug:
208 print ("jtagremote_client_send", data)
209 # now read tdo
210 self.send(str.encode('R'))
211
212
213 def jtagremote_client_recv(self, timeout=None):
214 data = self.get_data(1, timeout) # read 1 byte, blocking
215 if data is None:
216 return None
217 if self.debug:
218 print ("client recv", data)
219 data = bytes.decode(data)
220 return ord(data) - ord('0') # subtract ASCII for "0" to give 0 or 1
221
222