Commit | Line | Data |
---|---|---|
c906108c SS |
1 | /* communicate.c -- ARMulator RDP comms code: ARM6 Instruction Emulator. |
2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | |
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 | |
3fd725ef | 6 | the Free Software Foundation; either version 3 of the License, or |
c906108c SS |
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 | |
51b318de | 15 | along with this program; if not, see <http://www.gnu.org/licenses/>. */ |
c906108c SS |
16 | |
17 | /**************************************************************************/ | |
18 | /* Functions to read and write characters or groups of characters */ | |
19 | /* down sockets or pipes. Those that return a value return -1 on failure */ | |
20 | /* and 0 on success. */ | |
21 | /**************************************************************************/ | |
22 | ||
23 | #include <sys/time.h> | |
24 | #include <sys/types.h> | |
25 | #include <sys/socket.h> | |
26 | #include <netinet/in.h> | |
27 | ||
28 | #include "armdefs.h" | |
29 | ||
30 | /* The socket to the debugger */ | |
31 | int debugsock; | |
32 | ||
33 | /* The maximum number of file descriptors */ | |
34 | extern int nfds; | |
35 | ||
36 | /* The socket handle */ | |
37 | extern int sockethandle; | |
38 | ||
39 | /* Read and Write routines down a pipe or socket */ | |
40 | ||
41 | /****************************************************************/ | |
42 | /* Read an individual character. */ | |
43 | /* All other read functions rely on this one. */ | |
44 | /* It waits 15 seconds until there is a character available: if */ | |
45 | /* no character is available, then it timeouts and returns -1. */ | |
46 | /****************************************************************/ | |
dfcd3bfb JM |
47 | int |
48 | MYread_char (int sock, unsigned char *c) | |
49 | { | |
c906108c SS |
50 | int i; |
51 | fd_set readfds; | |
dfcd3bfb | 52 | struct timeval timeout = { 15, 0 }; |
c906108c SS |
53 | struct sockaddr_in isa; |
54 | ||
dfcd3bfb JM |
55 | retry: |
56 | ||
57 | FD_ZERO (&readfds); | |
58 | FD_SET (sock, &readfds); | |
59 | ||
60 | i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout); | |
61 | ||
62 | if (i < 0) | |
63 | { | |
64 | perror ("select"); | |
65 | exit (1); | |
66 | } | |
67 | ||
68 | if (!i) | |
69 | { | |
70 | fprintf (stderr, "read: Timeout\n"); | |
c906108c | 71 | return -1; |
c906108c | 72 | } |
dfcd3bfb JM |
73 | |
74 | if ((i = read (sock, c, 1)) < 1) | |
75 | { | |
76 | if (!i && sock == debugsock) | |
77 | { | |
78 | fprintf (stderr, "Connection with debugger severed.\n"); | |
79 | /* This shouldn't be necessary for a detached armulator, but | |
80 | the armulator cannot be cold started a second time, so | |
81 | this is probably preferable to locking up. */ | |
82 | return -1; | |
83 | fprintf (stderr, "Waiting for connection from debugger..."); | |
84 | debugsock = accept (sockethandle, &isa, &i); | |
363a6e9f | 85 | if (debugsock == -1) |
dfcd3bfb JM |
86 | { /* Now we are in serious trouble... */ |
87 | perror ("accept"); | |
88 | return -1; | |
89 | } | |
90 | fprintf (stderr, " done.\nConnection Established.\n"); | |
91 | sock = debugsock; | |
92 | goto retry; | |
93 | } | |
94 | perror ("read"); | |
95 | return -1; | |
96 | } | |
97 | ||
c906108c | 98 | #ifdef DEBUG |
dfcd3bfb JM |
99 | if (sock == debugsock) |
100 | fprintf (stderr, "<%02x ", *c); | |
c906108c | 101 | #endif |
dfcd3bfb | 102 | |
c906108c SS |
103 | return 0; |
104 | } | |
105 | ||
106 | /****************************************************************/ | |
107 | /* Read an individual character. */ | |
108 | /* It waits until there is a character available. Returns -1 if */ | |
109 | /* an error occurs. */ | |
110 | /****************************************************************/ | |
dfcd3bfb JM |
111 | int |
112 | MYread_charwait (int sock, unsigned char *c) | |
113 | { | |
c906108c SS |
114 | int i; |
115 | fd_set readfds; | |
116 | struct sockaddr_in isa; | |
117 | ||
dfcd3bfb JM |
118 | retry: |
119 | ||
120 | FD_ZERO (&readfds); | |
121 | FD_SET (sock, &readfds); | |
122 | ||
123 | i = select (nfds, &readfds, | |
124 | (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); | |
125 | ||
126 | if (i < 0) | |
127 | { | |
128 | perror ("select"); | |
129 | exit (-1); | |
130 | } | |
131 | ||
132 | if ((i = read (sock, c, 1)) < 1) | |
133 | { | |
134 | if (!i && sock == debugsock) | |
135 | { | |
136 | fprintf (stderr, "Connection with debugger severed.\n"); | |
137 | return -1; | |
138 | fprintf (stderr, "Waiting for connection from debugger..."); | |
139 | debugsock = accept (sockethandle, &isa, &i); | |
363a6e9f | 140 | if (debugsock == -1) |
dfcd3bfb JM |
141 | { /* Now we are in serious trouble... */ |
142 | perror ("accept"); | |
143 | return -1; | |
144 | } | |
145 | fprintf (stderr, " done.\nConnection Established.\n"); | |
146 | sock = debugsock; | |
147 | goto retry; | |
148 | } | |
149 | perror ("read"); | |
c906108c | 150 | return -1; |
c906108c | 151 | } |
dfcd3bfb | 152 | |
c906108c | 153 | #ifdef DEBUG |
dfcd3bfb JM |
154 | if (sock == debugsock) |
155 | fprintf (stderr, "<%02x ", *c); | |
c906108c | 156 | #endif |
dfcd3bfb | 157 | |
c906108c SS |
158 | return 0; |
159 | } | |
160 | ||
dfcd3bfb JM |
161 | void |
162 | MYwrite_char (int sock, unsigned char c) | |
163 | { | |
c906108c | 164 | |
dfcd3bfb JM |
165 | if (write (sock, &c, 1) < 1) |
166 | perror ("write"); | |
c906108c | 167 | #ifdef DEBUG |
dfcd3bfb JM |
168 | if (sock == debugsock) |
169 | fprintf (stderr, ">%02x ", c); | |
c906108c SS |
170 | #endif |
171 | } | |
172 | ||
dfcd3bfb JM |
173 | int |
174 | MYread_word (int sock, ARMword * here) | |
175 | { | |
c906108c | 176 | unsigned char a, b, c, d; |
dfcd3bfb JM |
177 | |
178 | if (MYread_char (sock, &a) < 0) | |
179 | return -1; | |
180 | if (MYread_char (sock, &b) < 0) | |
181 | return -1; | |
182 | if (MYread_char (sock, &c) < 0) | |
183 | return -1; | |
184 | if (MYread_char (sock, &d) < 0) | |
185 | return -1; | |
c906108c SS |
186 | *here = a | b << 8 | c << 16 | d << 24; |
187 | return 0; | |
188 | } | |
189 | ||
dfcd3bfb JM |
190 | void |
191 | MYwrite_word (int sock, ARMword i) | |
192 | { | |
193 | MYwrite_char (sock, i & 0xff); | |
194 | MYwrite_char (sock, (i & 0xff00) >> 8); | |
195 | MYwrite_char (sock, (i & 0xff0000) >> 16); | |
196 | MYwrite_char (sock, (i & 0xff000000) >> 24); | |
c906108c SS |
197 | } |
198 | ||
dfcd3bfb JM |
199 | void |
200 | MYwrite_string (int sock, char *s) | |
201 | { | |
202 | int i; | |
203 | for (i = 0; MYwrite_char (sock, s[i]), s[i]; i++); | |
c906108c SS |
204 | } |
205 | ||
dfcd3bfb JM |
206 | int |
207 | MYread_FPword (int sock, char *putinhere) | |
208 | { | |
c906108c SS |
209 | int i; |
210 | for (i = 0; i < 16; i++) | |
dfcd3bfb JM |
211 | if (MYread_char (sock, &putinhere[i]) < 0) |
212 | return -1; | |
c906108c SS |
213 | return 0; |
214 | } | |
215 | ||
dfcd3bfb JM |
216 | void |
217 | MYwrite_FPword (int sock, char *fromhere) | |
218 | { | |
c906108c SS |
219 | int i; |
220 | for (i = 0; i < 16; i++) | |
dfcd3bfb | 221 | MYwrite_char (sock, fromhere[i]); |
c906108c SS |
222 | } |
223 | ||
224 | /* Takes n bytes from source and those n bytes */ | |
225 | /* down to dest */ | |
dfcd3bfb JM |
226 | int |
227 | passon (int source, int dest, int n) | |
228 | { | |
c906108c SS |
229 | char *p; |
230 | int i; | |
dfcd3bfb JM |
231 | |
232 | p = (char *) malloc (n); | |
233 | if (!p) | |
234 | { | |
235 | perror ("Out of memory\n"); | |
236 | exit (1); | |
237 | } | |
238 | if (n) | |
239 | { | |
240 | for (i = 0; i < n; i++) | |
241 | if (MYread_char (source, &p[i]) < 0) | |
242 | return -1; | |
243 | ||
c906108c | 244 | #ifdef DEBUG |
dfcd3bfb JM |
245 | if (dest == debugsock) |
246 | for (i = 0; i < n; i++) | |
247 | fprintf (stderr, ")%02x ", (unsigned char) p[i]); | |
c906108c | 248 | #endif |
dfcd3bfb JM |
249 | |
250 | write (dest, p, n); | |
251 | } | |
252 | free (p); | |
c906108c SS |
253 | return 0; |
254 | } |