-
Notifications
You must be signed in to change notification settings - Fork 100
/
sim_jtag_socket_c.c
174 lines (153 loc) · 3.49 KB
/
sim_jtag_socket_c.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "sim_vhpi_c.h"
/* XXX Make that some parameter */
#define TCP_PORT 13245
#define MAX_PACKET 32
static int fd = -1;
static int cfd = -1;
static void open_socket(void)
{
struct sockaddr_in addr;
int opt, rc, flags;
if (fd >= 0 || fd < -1)
return;
signal(SIGPIPE, SIG_IGN);
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "Failed to open debug socket !\r\n");
goto fail;
}
rc = 0;
flags = fcntl(fd, F_GETFL);
if (flags >= 0)
rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if (flags < 0 || rc < 0) {
fprintf(stderr, "Failed to configure debug socket !\r\n");
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(TCP_PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
opt = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
if (rc < 0) {
fprintf(stderr, "Failed to bind debug socket !\r\n");
goto fail;
}
rc = listen(fd,1);
if (rc < 0) {
fprintf(stderr, "Failed to listen to debug socket !\r\n");
goto fail;
}
fprintf(stdout, "Debug socket ready\r\n");
return;
fail:
if (fd >= 0)
close(fd);
fd = -2;
}
static void check_connection(void)
{
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
cfd = accept(fd, (struct sockaddr *)&addr, &addr_len);
if (cfd < 0)
return;
fprintf(stdout, "Debug client connected !\r\n");
}
void sim_jtag_read_msg(unsigned char *out_msg, unsigned char *out_size)
{
unsigned char data[MAX_PACKET];
unsigned char size = 0;
struct pollfd fdset[1];
int rc, i;
if (fd == -1)
open_socket();
if (fd < 0)
goto finish;
if (cfd < 0)
check_connection();
if (cfd < 0)
goto finish;
memset(fdset, 0, sizeof(fdset));
fdset[0].fd = cfd;
fdset[0].events = POLLIN;
rc = poll(fdset, 1, 0);
if (rc <= 0)
goto finish;
rc = read(cfd, data, MAX_PACKET);
if (rc < 0)
fprintf(stderr, "Debug read error, assuming client disconnected !\r\n");
if (rc == 0)
fprintf(stdout, "Debug client disconnected !\r\n");
if (rc <= 0) {
close(cfd);
cfd = -1;
goto finish;
}
#if 0
fprintf(stderr, "Got message:\n\r");
{
for (i=0; i<rc; i++)
fprintf(stderr, "%02x ", data[i]);
fprintf(stderr, "\n\r");
}
#endif
size = data[0]; /* Size in bits */
/* Special sizes */
if (size == 255) {
/* JTAG reset, message to translate */
goto finish;
}
if (((rc - 1) * 8) < size) {
fprintf(stderr, "Debug short read: %d bytes for %d bits, truncating\r\n",
rc - 1, size);
size = (rc - 1) * 8;
}
for (i = 0; i < size; i++) {
int byte = i >> 3;
int bit = 1 << (i & 7);
out_msg[i] = (data[byte+1] & bit) ? vhpi1 : vhpi0;
}
finish:
to_std_logic_vector(size, out_size, 8);
}
void sim_jtag_write_msg(unsigned char *in_msg, unsigned char *in_size)
{
unsigned char data[MAX_PACKET];
unsigned char size;
int rc, i;
size = from_std_logic_vector(in_size, 8);
data[0] = size;
for (i = 0; i < size; i++) {
int byte = i >> 3;
int bit = 1 << (i & 7);
if (in_msg[i] == vhpi1)
data[byte+1] |= bit;
else
data[byte+1] &= ~bit;
}
rc = (size + 7) / 8;
#if 0
fprintf(stderr, "Sending response:\n\r");
{
for (i=0; i<rc; i++)
fprintf(stderr, "%02x ", data[i]);
fprintf(stderr, "\n\r");
}
#endif
rc = write(cfd, data, rc);
if (rc < 0)
fprintf(stderr, "Debug write error, ignoring\r\n");
}