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