59318044015421ad0eb7f41757f1f36cbcb3af67
[soc-cxxrtl-sim.git] / small_jtag_test / main.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/select.h>
6 #include <sys/types.h> /* See NOTES */
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <sys/fcntl.h>
11 #include <netinet/in.h>
12 #include <netinet/tcp.h>
13
14 #include <iostream>
15 #include "add.cpp"
16
17 using namespace std;
18
19 extern "C" {
20
21 /* reads from a socket if it is ready (a single byte) and returns 1 if success
22 */
23 int read_handler(int fdread, char *buffer)
24 {
25 ssize_t read_len;
26 fd_set read_fds;
27 FD_ZERO(&read_fds);
28 struct timeval tv;
29 FD_SET(fdread, &read_fds);
30 int status;
31
32 tv.tv_sec = 0;
33 tv.tv_usec = 1;
34
35 status = select(fdread+1, &read_fds, NULL, NULL, &tv);
36 switch (status)
37 {
38 case -1:
39 printf("Error reading on socket\n");
40 exit(status); // error
41 return 0;
42 case 0:
43 return 0; // timeout (nothing read)
44 default:
45 return read(fdread, buffer, 1);
46 }
47 }
48
49 /* nothing sophisticated: wait for an incoming connection
50 */
51 int get_connection()
52 {
53 int listenfd = 0, connfd = 0;
54 int flag = 1;
55 struct sockaddr_in serv_addr;
56
57 listenfd = socket(AF_INET, SOCK_STREAM, 0);
58 memset(&serv_addr, '0', sizeof(serv_addr));
59
60 serv_addr.sin_family = AF_INET;
61 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
62 serv_addr.sin_port = htons(5000);
63
64 bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
65
66 listen(listenfd, 1);
67
68 connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
69 close(listenfd);
70
71 setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
72 return connfd;
73 }
74
75 /*
76
77 static void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *address, int socklen, void *ctx)
78 {
79 struct session_s *s = (struct session_s*)ctx;
80 struct timeval tv = {1, 0};
81
82 s->fd = fd;
83 s->ev = event_new(base, fd, EV_READ | EV_PERSIST , event_handler, s);
84 event_add(s->ev, &tv);
85 }
86
87 static int jtagremote_new(void **sess, char *args)
88 {
89 int ret = RC_OK;
90 struct session_s *s = NULL;
91 char *cport = NULL;
92 int port;
93 struct evconnlistener *listener;
94 struct sockaddr_in sin;
95
96 if(!sess) {
97 ret = RC_INVARG;
98 goto out;
99 }
100
101 ret = litex_sim_module_get_args(args, "port", &cport);
102 if(RC_OK != ret)
103 goto out;
104
105 printf("Found port %s\n", cport);
106 sscanf(cport, "%d", &port);
107 free(cport);
108 if(!port) {
109 ret = RC_ERROR;
110 fprintf(stderr, "Invalid port selected!\n");
111 goto out;
112 }
113
114 s=(struct session_s*)malloc(sizeof(struct session_s));
115 if(!s) {
116 ret = RC_NOENMEM;
117 goto out;
118 }
119 memset(s, 0, sizeof(struct session_s));
120
121 memset(&sin, 0, sizeof(sin));
122 sin.sin_family = AF_INET;
123 sin.sin_addr.s_addr = htonl(0);
124 sin.sin_port = htons(port);
125 listener = evconnlistener_new_bind(base, accept_conn_cb, s, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&sin, sizeof(sin));
126 if (!listener) {
127 ret=RC_ERROR;
128 eprintf("Can't bind port %d\n!\n", port);
129 goto out;
130 }
131 evconnlistener_set_error_cb(listener, accept_error_cb);
132
133 out:
134 *sess=(void*)s;
135 return ret;
136 }
137
138 */
139
140 } // extern "C"
141
142 void read_openocd_jtagremote(cxxrtl_design::p_add &top, int sock)
143 {
144 char c;
145 if (read_handler(sock, &c) != 1) {
146 return;
147 }
148 printf ("read %c\n", c);
149 if ((c >= '0') && (c <= '7'))
150 {
151 top.p_tck.set<bool>(((c - '0') >> 2) & 1);
152 top.p_tms.set<bool>(((c - '0') >> 1) & 1);
153 top.p_tdi.set<bool>((c - '0') & 1);
154 }
155 if (c == 'R')
156 {
157 uint8_t val = top.p_tdo.get<uint8_t>() + '0';
158 if(-1 == write(sock, &val, 1))
159 {
160 printf("Error writing on socket\n");
161 exit(-1);
162 }
163 }
164 if (c == 'Q') {
165 printf("disconnect request\n");
166 exit(-1);
167 }
168 }
169
170 int main()
171 {
172 cxxrtl_design::p_add top;
173
174 int sock = get_connection();
175
176 top.step();
177 while (true) {
178
179 top.p_clk.set<bool>(false);
180 top.step();
181 top.p_clk.set<bool>(true);
182 top.step();
183
184 /* read and process incoming jtag */
185 read_openocd_jtagremote(top, sock);
186
187 // check that the output is correct
188 /*
189 top.p_a.set<uint8_t>(5);
190 top.p_b.set<uint8_t>(3);
191 uint32_t f = top.p_f.get<uint32_t>();
192
193 cout << "f " << f << endl;
194 */
195 }
196 }
197