FreeCalypso > hg > fc-tourmaline
comparison src/cs/drivers/drv_app/ffs/board/tmffs.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4e78acac3d88 |
---|---|
1 /****************************************************************************** | |
2 * Flash File System (ffs) | |
3 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com | |
4 * | |
5 * ffs testmode interface | |
6 * | |
7 * $Id: tmffs.c 1.51 Thu, 18 Dec 2003 10:50:52 +0100 tsj $ | |
8 * | |
9 ******************************************************************************/ | |
10 | |
11 #ifndef TARGET | |
12 #include "ffs.cfg" | |
13 #endif | |
14 | |
15 #if (TARGET == 1) | |
16 #include "etm/etm.h" | |
17 #include "etm/etm_api.h" | |
18 #include "ffs/board/task.h" | |
19 #endif | |
20 | |
21 #include "ffs/board/ffstrace.h" | |
22 #include "ffs/board/tmffs.h" | |
23 #include "ffs/ffs.h" | |
24 #include "ffs/pcm.h" | |
25 | |
26 #include <string.h> | |
27 | |
28 /****************************************************************************** | |
29 * Local globals for all protocols | |
30 ******************************************************************************/ | |
31 | |
32 static int32 bufsize, tmpsize; | |
33 static uint8 stringsize; | |
34 | |
35 effs_t ffs_initialize(void); | |
36 effs_t ffs_exit(void); | |
37 | |
38 #define tmffs_put8(x) *outp++ = x; | |
39 #define tmffs_put16(x) *outp++ = (x & 0xff); *outp++ = (x>>8); | |
40 | |
41 #if (TARGET == 1) | |
42 int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize); | |
43 | |
44 // Not in use | |
45 //#define tmffs_put32(x) tmffs_put16(x); tmffs_put16(x >> 16); | |
46 | |
47 | |
48 /****************************************************************************** | |
49 * TM FFS registration to ETM database | |
50 *****************************************************************************/ | |
51 /* Callback function registered in ETM database */ | |
52 int etm_ffs1_pkt_receive(uint8 *data, int size) | |
53 { | |
54 int mid; | |
55 T_ETM_PKT *pkt; | |
56 | |
57 ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(*, %d)" NL, size)); | |
58 | |
59 /* Create TestMode return Packet */ | |
60 if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) { | |
61 ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(): Limit of memory bank reached" NL)); | |
62 return ETM_NOMEM; | |
63 } | |
64 | |
65 // Max packet size for TM3 is 128 bytes | |
66 size = tm_ffs(pkt->data, TM3_PACKET_SIZE, data, size); | |
67 | |
68 pkt->size = size; | |
69 pkt->status = ETM_OK; | |
70 pkt->mid = ETM_FFS1; | |
71 | |
72 etm_pkt_send(pkt); | |
73 target_free(pkt); | |
74 | |
75 return ETM_OK; | |
76 } | |
77 | |
78 /* Callback function registered in ETM database */ | |
79 int etm_ffs2_pkt_receive(uint8 *data, int size) | |
80 { | |
81 int status; | |
82 T_ETM_PKT *pkt = NULL; | |
83 | |
84 ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(*, %d)" NL, size)); | |
85 | |
86 /* Create TestMode return Packet */ | |
87 if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) { | |
88 ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(): Limit of memory bank reached" NL)); | |
89 return ETM_NOMEM; | |
90 } | |
91 | |
92 status = etm_ffs2(pkt, data, size); | |
93 return status; | |
94 } | |
95 | |
96 /* Init of FFS in the ETM database */ | |
97 int etm_ffs_init(void) | |
98 { | |
99 int status; | |
100 | |
101 status = etm_register("FFS1", ETM_FFS1, 0, 0, etm_ffs1_pkt_receive); | |
102 status = etm_register("FFS2", ETM_FFS2, 0, 0, etm_ffs2_pkt_receive); | |
103 return status; | |
104 } | |
105 #endif // (TARGET == 1) | |
106 | |
107 /****************************************************************************** | |
108 * FFS1 Protocol | |
109 ******************************************************************************/ | |
110 | |
111 #ifndef TMFFS1 | |
112 | |
113 int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize) | |
114 { | |
115 return -1; // FIXME handle error better | |
116 } | |
117 | |
118 // Note these functions must be presented because ffs_query() use them but | |
119 // they are only valid if FFS1_PROTOCOL is used. | |
120 int tmffs_bufsize(void) | |
121 { | |
122 return EFFS_NOSYS; | |
123 } | |
124 | |
125 unsigned char *tmffs_bufaddr(void) | |
126 { | |
127 return 0; | |
128 } | |
129 | |
130 #else | |
131 | |
132 #if (GSMLITE == 1) | |
133 #define TMFFS1_BUFFER_SIZE 4000 //previously 8192 | |
134 #else | |
135 #define TMFFS1_BUFFER_SIZE 8192 | |
136 #endif | |
137 | |
138 #define TMFFS1_STRING_SIZE 127 | |
139 | |
140 /****************************************************************************** | |
141 * Macros | |
142 ******************************************************************************/ | |
143 | |
144 #define tmffs1_putdata(outp, src, size) \ | |
145 tmffs_put8(FPI_DATA); \ | |
146 tmffs_put16(size); \ | |
147 memcpy(outp, src, size); \ | |
148 outp += size; | |
149 | |
150 /****************************************************************************** | |
151 * Local globals | |
152 ******************************************************************************/ | |
153 | |
154 static unsigned char buffer[TMFFS1_BUFFER_SIZE]; | |
155 static bufindex; | |
156 | |
157 static char string[TMFFS1_STRING_SIZE]; | |
158 | |
159 static effs_t tm_ffs_overflowck(void) | |
160 { | |
161 if (bufsize > TMFFS1_BUFFER_SIZE || | |
162 stringsize > TMFFS1_STRING_SIZE) | |
163 return EFFS_TOOBIG; | |
164 | |
165 return EFFS_OK; | |
166 } | |
167 | |
168 | |
169 /****************************************************************************** | |
170 * tm_ffs | |
171 ******************************************************************************/ | |
172 | |
173 /** | |
174 * NOTEME: This has been introduced when the ffs 1MB device limit was | |
175 * broken. This made location_t go from uint16 to uint32, messing up | |
176 * with PCTM. | |
177 * | |
178 * This makes the xstat_s look the same to PCTM PC side, though | |
179 * location will be forced to 0. | |
180 */ | |
181 void hack_xstat_2_look_like_old_xstat(struct xstat_s *xstat) | |
182 { | |
183 int i; | |
184 char *location; | |
185 | |
186 xstat->location = 0; | |
187 | |
188 for (location = (char *) &(xstat->location) + 2; location <= (char *) &(xstat->sequence); location++) | |
189 *location = location[2]; | |
190 } | |
191 | |
192 // Parse input message and execute function. Then fill output buffer with | |
193 // return values from the called function and transmit the message. Return | |
194 // number of bytes inserted into output buffer. If return value is negative, | |
195 // it represents an error code. | |
196 int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize) | |
197 { | |
198 int error; | |
199 tmffs_cid_t fid; | |
200 | |
201 unsigned char *outp_start = outp; | |
202 unsigned char *inp_start = inp; | |
203 | |
204 static uint8 i8[2]; static uint16 i8i; | |
205 static uint16 i16[2]; static uint16 i16i; | |
206 static uint32 i32[2]; static uint16 i32i; | |
207 | |
208 tw(tr(TR_BEGIN, TrTmffs, "TMFFS:\n")); | |
209 | |
210 while((fid = *inp++) != FPI_END) | |
211 { | |
212 switch(fid) | |
213 { | |
214 /********************************************************** | |
215 * Generic Protocol Functions | |
216 **********************************************************/ | |
217 | |
218 case FPI_BEGIN: | |
219 // for (i8i = 0; i8i < TMFFS1_STRING_SIZE; i8i++) // DEBUG | |
220 // string[i8i] = '#'; | |
221 // for (i8i = 0; i8i < TMFFS1_BUFFER_SIZE; i8i++) // DEBUG | |
222 // buffer[i8i] = '$'; | |
223 i8i = i16i = i32i = bufsize = stringsize = 0; | |
224 bufindex = 0; | |
225 i8[0] = i8[1] = 0; | |
226 i16[0] = i16[1] = 0; | |
227 i32[0] = i32[1] = 0; | |
228 string[0] = buffer[0] = 0; | |
229 tw(tr(TR_FUNC, TrTmffs, "FPI_BEGIN\n")); | |
230 ttw(ttr(TTrTmffs, "tm1" NL)); | |
231 break; | |
232 case FPI_TMFFS_VERSION: | |
233 // NULL -> UINT16 | |
234 tmffs_put16(TMFFS1_VERSION); | |
235 break; | |
236 | |
237 case FPI_INT8: | |
238 i8[i8i++] = inp[0]; inp += 1; | |
239 tw(tr(TR_FUNC, TrTmffs, "FPI_INT8(%d/0x%x)\n", | |
240 i8[i8i-1], i8[i8i-1])); | |
241 ttw(ttr(TTrTmffs, "tm_i8" NL)); | |
242 break; | |
243 case FPI_INT16: | |
244 i16[i16i++] = (inp[0]) | (inp[1] << 8); inp += 2; | |
245 tw(tr(TR_FUNC, TrTmffs, "FPI_INT16(%d/0x%x)\n", | |
246 i16[i16i-1], i16[i16i-1])); | |
247 ttw(ttr(TTrTmffs, "tm_i16" NL)); | |
248 break; | |
249 case FPI_INT32: | |
250 i32[i32i++] = inp[0] | (inp[1] << 8) | |
251 | (inp[2] << 16) | (inp[3] << 24); | |
252 inp += 4; | |
253 tw(tr(TR_FUNC, TrTmffs, "FPI_INT32(%d/0x%x)\n", | |
254 i32[i32i-1], i32[i32i-1])); | |
255 ttw(ttr(TTrTmffs, "tm_i32" NL)); | |
256 break; | |
257 case FPI_BUFFER: | |
258 bufsize = inp[0] | (inp[1] << 8); inp += 2; | |
259 tw(tr(TR_FUNC, TrTmffs, "FPI_BUFFER(%d)\n", bufsize)); | |
260 ttw(ttr(TTrTmffs, "tm_buf" NL)); | |
261 break; | |
262 case FPI_DATA: | |
263 bufsize = inp[0] | (inp[1] << 8); inp += 2; | |
264 memcpy(buffer, inp, bufsize); inp += bufsize; | |
265 tw(tr(TR_FUNC, TrTmffs, "FPI_DATA(%d)\n", bufsize)); | |
266 ttw(ttr(TTrTmffs, "tm_data" NL)); | |
267 break; | |
268 case FPI_STRBUF: | |
269 // string buffer size MUST include null-terminator! | |
270 stringsize = inp[0]; inp += 1; | |
271 tw(tr(TR_FUNC, TrTmffs, "FPI_STRBUF(%d)\n", stringsize)); | |
272 ttw(ttr(TTrTmffs, "tm_sbuf" NL)); | |
273 break; | |
274 case FPI_STRING: | |
275 // stringsize MUST include null-terminator! | |
276 // <INT8>, <BYTES> -> NULL (or ERROR) | |
277 stringsize = inp[0]; inp += 1; | |
278 if (stringsize <= TMFFS1_STRING_SIZE) | |
279 memcpy(string, inp, stringsize); | |
280 inp += stringsize; | |
281 tw(tr(TR_FUNC, TrTmffs, "FPI_STRING(%d,'%s')\n", | |
282 stringsize, string)); | |
283 ttw(ttr(TTrTmffs, "tm_s" NL)); | |
284 break; | |
285 | |
286 case FPI_BUFREAD: | |
287 // <INT16> -> DATA | |
288 tmpsize = inp[0] | (inp[1] << 8); inp += 2; | |
289 tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_READ(%d)\n", tmpsize)); | |
290 tmffs1_putdata(outp, &buffer[bufindex], tmpsize); | |
291 bufindex += tmpsize; | |
292 ttw(ttr(TTrTmffs, "tm_bufrd" NL)); | |
293 break; | |
294 case FPI_BUFWRITE: | |
295 // <INT16>, <BYTES> -> NULL (or ERROR) | |
296 tmpsize = inp[0] | (inp[1] << 8); inp += 2; | |
297 tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_WRITE(%d)\n", tmpsize)); | |
298 if (bufsize + tmpsize <= TMFFS1_BUFFER_SIZE) | |
299 memcpy(&buffer[bufsize], inp, tmpsize); | |
300 inp += tmpsize; | |
301 bufsize += tmpsize; | |
302 ttw(ttr(TTrTmffs, "tm_bufwr" NL)); | |
303 break; | |
304 case FPI_BUFSET: | |
305 bufindex = inp[0] | (inp[1] << 8); inp += 2; | |
306 tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_SET(%d)\n", bufindex)); | |
307 ttw(ttr(TTrTmffs, "tm_bufset" NL)); | |
308 break; | |
309 | |
310 /********************************************************** | |
311 * FFS Functions | |
312 **********************************************************/ | |
313 | |
314 case FPI_PREFORMAT: | |
315 // NULL -> ERROR | |
316 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
317 error = ffs_preformat_nb(i16[0], 0); | |
318 if (error > 0) | |
319 error = 0; // ignore request id | |
320 tmffs_put8(error); | |
321 tw(tr(TR_FUNC, TrTmffs, "FPI_PREFORMAT(0x%x)\n", i16[0])); | |
322 ttw(ttr(TTrTmffs, "tm_pfmt" NL)); | |
323 break; | |
324 case FPI_FORMAT: | |
325 // STRING -> ERROR | |
326 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
327 error = ffs_format_nb(&string[0], i16[0], 0); | |
328 if (error > 0) | |
329 error = 0; // ignore request id | |
330 tmffs_put8(error); | |
331 tw(tr(TR_FUNC, TrTmffs, "FPI_FORMAT(0x%x)\n", i16[0])); | |
332 ttw(ttr(TTrTmffs, "tm_fmt" NL)); | |
333 break; | |
334 | |
335 | |
336 case FPI_FCREATE: | |
337 // STRING, DATA -> ERROR | |
338 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
339 error = ffs_fcreate_nb(string, buffer, bufsize, 0); | |
340 if (error > 0) | |
341 error = 0; // ignore request id | |
342 tmffs_put8(error); | |
343 tw(tr(TR_FUNC, TrTmffs, "FPI_FCREATE('%s', 0x%x, %d/0x%x)\n", | |
344 string, buffer, bufsize, bufsize)); | |
345 ttw(ttr(TTrTmffs, "tm_fcr" NL)); | |
346 break; | |
347 case FPI_FUPDATE: | |
348 // STRING, DATA -> ERROR | |
349 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
350 error = ffs_fupdate_nb(string, buffer, bufsize, 0); | |
351 if (error > 0) | |
352 error = 0; // ignore request id | |
353 tmffs_put8(error); | |
354 tw(tr(TR_FUNC, TrTmffs, "FPI_FUPDATE('%s', 0x%x, %d/0x%x)\n", | |
355 string, buffer, bufsize, bufsize)); | |
356 ttw(ttr(TTrTmffs, "tm_fup" NL)); | |
357 break; | |
358 case FPI_FWRITE: | |
359 // STRING, DATA -> ERROR | |
360 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
361 error = ffs_fwrite_nb(string, buffer, bufsize, 0); | |
362 if (error > 0) | |
363 error = 0; // ignore request id | |
364 tmffs_put8(error); | |
365 tw(tr(TR_FUNC, TrTmffs, "FPI_FWRITE('%s', 0x%x, %d/0x%x)\n", | |
366 string, buffer, bufsize, bufsize)); | |
367 ttw(ttr(TTrTmffs, "tm_fwr" NL)); | |
368 break; | |
369 case FPI_FREAD: | |
370 // STRING, BUFFER -> ERROR | |
371 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
372 error = ffs_file_read(string, buffer, TMFFS1_BUFFER_SIZE); | |
373 // Because a 32-bit integer is returned, we have to saturate it | |
374 // into an 8-bit value. | |
375 if (error >= 0) | |
376 error = 0; | |
377 tmffs_put8(error); | |
378 tw(tr(TR_FUNC, TrTmffs, "FPI_FREAD('%s', 0x%x, %d/0x%x)\n", | |
379 string, buffer, bufsize, bufsize)); | |
380 ttw(ttr(TTrTmffs, "tm_frd" NL)); | |
381 break; | |
382 case FPI_REMOVE: | |
383 // STRING -> ERROR | |
384 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
385 error = ffs_remove_nb(string, 0); | |
386 if (error > 0) | |
387 error = 0; // ignore request id | |
388 tmffs_put8(error); | |
389 tw(tr(TR_FUNC, TrTmffs, "FPI_REMOVE()\n")); | |
390 ttw(ttr(TTrTmffs, "tm_rm" NL)); | |
391 break; | |
392 | |
393 | |
394 case FPI_MKDIR: | |
395 // STRING -> ERROR | |
396 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
397 error = ffs_mkdir_nb(string, 0); | |
398 if (error > 0) | |
399 error = 0; // ignore request id | |
400 tmffs_put8(error); | |
401 tw(tr(TR_FUNC, TrTmffs, "FPI_MKDIR()\n")); | |
402 ttw(ttr(TTrTmffs, "tm_mkd" NL)); | |
403 break; | |
404 case FPI_OPENDIR: | |
405 // STRING, BUFFER -> ERROR, DATA | |
406 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
407 error = ffs_opendir(string, (struct dir_s *) buffer); | |
408 // Because a 32-bit integer is returned, we have to saturate it | |
409 // into an 8-bit value. | |
410 if (error >= 0) | |
411 error = 0; | |
412 tmffs_put8(error); | |
413 tmffs1_putdata(outp, buffer, sizeof(struct dir_s)); | |
414 tw(tr(TR_FUNC, TrTmffs, "FPI_OPENDIR()\n")); | |
415 ttw(ttr(TTrTmffs, "tm_od" NL)); | |
416 break; | |
417 case FPI_READDIR: | |
418 // DATA, STRBUF -> ERROR, DATA, STRING | |
419 string[0] = 0; | |
420 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
421 error = ffs_readdir((struct dir_s *) buffer, string, stringsize); | |
422 | |
423 // Saturate error(i) in order to let it fit in type int8. | |
424 if (error > 127) | |
425 error = 127; | |
426 tmffs_put8(error); | |
427 tmffs1_putdata(outp, buffer, sizeof(struct dir_s)); | |
428 stringsize = strlen(string) + 1; | |
429 tmffs_put8(FPI_STRING); // put directory entry's name... | |
430 tmffs_put8(stringsize); | |
431 memcpy(outp, string, stringsize); | |
432 outp += stringsize; | |
433 tw(tr(TR_FUNC, TrTmffs, "FPI_READDIR()\n")); | |
434 ttw(ttr(TTrTmffs, "tm_rdd" NL)); | |
435 break; | |
436 | |
437 | |
438 case FPI_STAT: | |
439 // STRING, BUFFER -> ERROR, DATA | |
440 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
441 error = ffs_stat(&string[0], (struct stat_s *) buffer); | |
442 tmffs_put8(error); | |
443 tmffs1_putdata(outp, buffer, sizeof(struct stat_s)); | |
444 tw(tr(TR_FUNC, TrTmffs, "FPI_STAT()\n")); | |
445 ttw(ttr(TTrTmffs, "tm_st" NL)); | |
446 break; | |
447 case FPI_LINKSTAT: | |
448 // STRING, BUFFER -> ERROR, DATA | |
449 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
450 error = ffs_xlstat(&string[0], (struct xstat_s *) buffer); | |
451 tmffs_put8(error); | |
452 | |
453 hack_xstat_2_look_like_old_xstat((struct xstat_s *) buffer); | |
454 | |
455 tmffs1_putdata(outp, buffer, sizeof(struct xstat_s) - 2); | |
456 tw(tr(TR_FUNC, TrTmffs, "FPI_()\n")); | |
457 ttw(ttr(TTrTmffs, "tm_lst" NL)); | |
458 break; | |
459 | |
460 | |
461 case FPI_SYMLINK: | |
462 // STRING, DATA -> ERROR | |
463 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
464 error = ffs_symlink_nb(string, (char *) buffer, 0); | |
465 if (error > 0) | |
466 error = 0; // ignore request id | |
467 tmffs_put8(error); | |
468 tw(tr(TR_FUNC, TrTmffs, "FPI_SYMLINK()\n")); | |
469 ttw(ttr(TTrTmffs, "tm_sym" NL)); | |
470 break; | |
471 case FPI_READLINK: | |
472 // STRING, BUFFER -> ERROR, DATA | |
473 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
474 error = ffs_readlink(string, (char *) buffer, TMFFS1_BUFFER_SIZE); | |
475 // Because a 32-bit integer is returned, we have to saturate it | |
476 // into an 8-bit value. | |
477 if (error >= 0) | |
478 error = 0; | |
479 tmffs_put8(error); | |
480 tmffs1_putdata(outp, buffer, bufsize); // put link contents | |
481 tw(tr(TR_FUNC, TrTmffs, "FPI_READLINK()\n")); | |
482 ttw(ttr(TTrTmffs, "tm_rdl" NL)); | |
483 break; | |
484 | |
485 | |
486 case FPI_QUERY: | |
487 // INT8 -> ERROR, DATA | |
488 error = ffs_query(i8[0], buffer); | |
489 tmffs_put8(error); | |
490 tmffs1_putdata(outp, buffer, 16); | |
491 tw(tr(TR_FUNC, TrTmffs, "FPI_QUERY()\n")); | |
492 ttw(ttr(TTrTmffs, "tm_q" NL)); | |
493 break; | |
494 case FPI_FCONTROL: | |
495 // STRING INT8 INT32 -> ERROR | |
496 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
497 error = ffs_fcontrol_nb(string, i8[0], i32[0], 0); | |
498 if (error > 0) | |
499 error = 0; // ignore request id | |
500 tmffs_put8(error); | |
501 tw(tr(TR_FUNC, TrTmffs, "FPI_FCONTROL()\n")); | |
502 ttw(ttr(TTrTmffs, "tm_fc" NL)); | |
503 break; | |
504 | |
505 case FPI_INIT: | |
506 // NULL -> ERROR | |
507 error =ffs_initialize(); | |
508 tmffs_put8(error); | |
509 tw(tr(TR_FUNC, TrTmffs, "FPI_INIT()\n")); | |
510 ttw(ttr(TTrTmffs, "tm_init" NL)); | |
511 break; | |
512 case FPI_EXIT: | |
513 // NULL -> ERROR | |
514 error = ffs_exit(); | |
515 tmffs_put8(error); | |
516 tw(tr(TR_FUNC, TrTmffs, "FPI_EXIT()\n")); | |
517 ttw(ttr(TTrTmffs, "tm_exit" NL)); | |
518 break; | |
519 | |
520 | |
521 case FPI_TFFS: | |
522 { | |
523 // STRING -> ERROR | |
524 #if (WITH_TFFS == 1) | |
525 extern char ffs_test_string[]; // defined in task.c | |
526 | |
527 memcpy(ffs_test_string, string, stringsize); | |
528 tw(tr(TR_FUNC, TrTmffs, "FPI_TFFS()\n")); | |
529 ttw(ttr(TTrTmffs, "tm_tffs" NL)); | |
530 #else | |
531 tmffs_put8(EFFS_NOSYS); | |
532 #endif | |
533 break; | |
534 } | |
535 default: | |
536 tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n")); | |
537 ttw(ttr(TTrTmffs, "tm?" NL)); | |
538 break; | |
539 } | |
540 // check if we read beyond buffer end | |
541 if (inp > inp_start + insize) { | |
542 tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n")); | |
543 ttw(ttr(TTrTmffs, "tm_fatal" NL)); | |
544 // NOTEME: We really should reset output buffer and put a return | |
545 // code that tells us what went wrong! | |
546 return 0; | |
547 } | |
548 } | |
549 | |
550 tw(tr(TR_END, TrTmffs, "")); | |
551 | |
552 return outp - outp_start; | |
553 } | |
554 | |
555 int tmffs_bufsize(void) | |
556 { | |
557 return TMFFS1_BUFFER_SIZE; | |
558 } | |
559 | |
560 unsigned char *tmffs_bufaddr(void) | |
561 { | |
562 return buffer; | |
563 } | |
564 | |
565 #endif // TMFFS1 | |
566 | |
567 /****************************************************************************** | |
568 * FFS2 protocol | |
569 ******************************************************************************/ | |
570 | |
571 #ifndef TMFFS2 | |
572 | |
573 #if (TARGET == 1) | |
574 | |
575 int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize) | |
576 { | |
577 int error; | |
578 | |
579 tw(tr(TR_BEGIN, TrTmffs, "FFS2 protocol not represented in target\n")); | |
580 error = -1; // FIXME other error? | |
581 | |
582 #if 0 // Note we can only use this if etm is in target | |
583 // We return a packet instead of waiting for timeout. | |
584 pkt->size = 0; | |
585 pkt->status = -error; | |
586 pkt->mid = ETM_FFS2; | |
587 etm_pkt_send(pkt); | |
588 #endif | |
589 | |
590 target_free(pkt); | |
591 tw(tr(TR_END, TrTmffs, "")); | |
592 | |
593 return error; | |
594 } | |
595 | |
596 #endif // (TARGET == 1) | |
597 | |
598 #else | |
599 | |
600 #define TMFFS_BUFFER_SIZE 256 // FIXME change to packet size | |
601 #define TMFFS_STRING_SIZE 127 | |
602 | |
603 /****************************************************************************** | |
604 * Macros | |
605 ******************************************************************************/ | |
606 | |
607 #define tmffs_get8() inp[0]; inp += 1; | |
608 #define tmffs_get16() (inp[0]) | (inp[1] << 8); inp += 2; | |
609 #define tmffs_get32() inp[0] | (inp[1] << 8) | (inp[2] << 16)\ | |
610 | (inp[3] << 24); inp += 4; | |
611 | |
612 #define tmffs_getdata() bufsize = inp[0]; inp += 1; \ | |
613 memcpy(buffer, inp, bufsize); inp += bufsize; | |
614 | |
615 | |
616 /****************************************************************************** | |
617 * Helper function | |
618 ******************************************************************************/ | |
619 | |
620 // If size is less than zero it is because of a error and we dont have to put any | |
621 // data if size is returned in status. | |
622 int tmffs_putdata(unsigned char **buf, unsigned char *src, int size) | |
623 { | |
624 unsigned char *p = *buf; | |
625 | |
626 if (size > 0) { | |
627 *p++ = size; | |
628 memcpy(p, src, size); | |
629 *buf += 1 + size; | |
630 } | |
631 return size; | |
632 } | |
633 | |
634 int tmffs_putstring(unsigned char **buf, char *src, int size) | |
635 { | |
636 unsigned char *p = *buf; | |
637 | |
638 if (size > 0) { | |
639 *p++ = size; | |
640 memcpy(p, src, size); | |
641 *buf += 1 + size; | |
642 } | |
643 return size; | |
644 } | |
645 | |
646 int tmffs_getstring(unsigned char ** buf, char *string) | |
647 { | |
648 unsigned char *p = *buf; | |
649 | |
650 stringsize = *p++; | |
651 | |
652 if (stringsize > TMFFS_STRING_SIZE) | |
653 return EFFS_TOOBIG; | |
654 | |
655 memcpy(string, p, stringsize); | |
656 *buf += 1 + stringsize; | |
657 | |
658 return stringsize; | |
659 } | |
660 | |
661 /****************************************************************************** | |
662 * tm_ffs | |
663 ******************************************************************************/ | |
664 | |
665 // Parse input message and execute function. Then fill output buffer with | |
666 // return values from the called function and transmit the message. Return | |
667 // number of bytes inserted into output buffer. If return value is negative, | |
668 // it represents an error code. | |
669 int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize) | |
670 { | |
671 tmffs2_cid_t fid; | |
672 unsigned char buffer[TMFFS_BUFFER_SIZE]; | |
673 char string[TMFFS_STRING_SIZE]; | |
674 | |
675 unsigned char *outp_start; | |
676 unsigned char *inp_start = inp; | |
677 unsigned char *outp; | |
678 | |
679 int error = 0, i, fdi, size, param, flags; | |
680 uint8 type; | |
681 | |
682 bufsize = stringsize = tmpsize = 0; | |
683 | |
684 tw(tr(TR_BEGIN, TrTmffs, "TmFFS2\n")); | |
685 | |
686 outp_start = outp = pkt->data; | |
687 | |
688 fid = *inp++; | |
689 ttw(ttr(TTrTmffs, "etm_ffs2 0x%x" NL, fid)); | |
690 switch(fid) | |
691 { | |
692 /********************************************************** | |
693 * Generic Protocol Functions | |
694 **********************************************************/ | |
695 | |
696 case TMFFS_VERSION: | |
697 tmffs_put16(TMFFS2_VERSION); | |
698 break; | |
699 | |
700 /********************************************************** | |
701 * FFS Functions | |
702 **********************************************************/ | |
703 | |
704 case TMFFS_PREFORMAT: | |
705 param = tmffs_get16(); | |
706 error = ffs_preformat(param); | |
707 tw(tr(TR_FUNC, TrTmffs, "TMFFS_PREFORMAT(0x%x)\n", param)); | |
708 ttw(ttr(TTrTmffs, "tm_pfmt" NL)); | |
709 break; | |
710 case TMFFS_FORMAT: | |
711 error = tmffs_getstring(&inp, string); | |
712 param = tmffs_get16(); | |
713 if (error >= 0) | |
714 error = ffs_format(&string[0], param); | |
715 tw(tr(TR_FUNC, TrTmffs, "TMFFS_FORMAT(0x%x)\n", param)); | |
716 ttw(ttr(TTrTmffs, "tm_fmt" NL)); | |
717 break; | |
718 | |
719 | |
720 case TMFFS_FILE_WRITE: | |
721 error = tmffs_getstring(&inp, string); | |
722 tmffs_getdata(); | |
723 flags = tmffs_get8(); | |
724 if (error >= 0) | |
725 error = ffs_file_write(string, buffer, bufsize, flags); | |
726 ttw(ttr(TTrTmffs, "tm_fwr" NL)); | |
727 break; | |
728 | |
729 | |
730 case TMFFS_FILE_READ: | |
731 error = tmffs_getstring(&inp, string); | |
732 bufsize = tmffs_get8(); | |
733 if (error >= 0) | |
734 size = ffs_file_read(string, buffer, bufsize); | |
735 error = tmffs_putdata(&outp, &buffer[0], size); | |
736 tw(tr(TR_FUNC, TrTmffs, "TMFFS_FREAD('%s', 0x%x, %d/0x%x)\n", | |
737 string, buffer, bufsize, bufsize)); | |
738 ttw(ttr(TTrTmffs, "tm_frd" NL)); | |
739 break; | |
740 case TMFFS_REMOVE: | |
741 error = tmffs_getstring(&inp, string); | |
742 if (error >= 0) | |
743 error = ffs_remove(string); | |
744 tw(tr(TR_FUNC, TrTmffs, "TMFFS_REMOVE()\n")); | |
745 ttw(ttr(TTrTmffs, "tm_rm" NL)); | |
746 break; | |
747 | |
748 | |
749 case TMFFS_OPEN: | |
750 error = tmffs_getstring(&inp, string); | |
751 flags = tmffs_get8(); | |
752 if (error >= 0) | |
753 error = ffs_open(string, flags); | |
754 tmffs_put8(error); // fdi | |
755 tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPEN('%s', %d)\n", string, flags)); | |
756 ttw(ttr(TTrTmffs, "tm_open" NL)); | |
757 break; | |
758 case TMFFS_CLOSE: | |
759 fdi = tmffs_get8(); | |
760 error = ffs_close(fdi); | |
761 tw(tr(TR_FUNC, TrTmffs, "TMFFS_CLOSE(%d)\n", fdi)); | |
762 ttw(ttr(TTrTmffs, "tm_close" NL)); | |
763 break; | |
764 case TMFFS_WRITE: | |
765 fdi = tmffs_get8(); | |
766 tmffs_getdata(); | |
767 error = ffs_write(fdi, buffer, bufsize); | |
768 tmffs_put8(error); // put size | |
769 tw(tr(TR_FUNC, TrTmffs, "TMFFS_WRITE(%d, %d)\n", fdi, bufsize)); | |
770 ttw(ttr(TTrTmffs, "tm_write" NL)); | |
771 break; | |
772 case TMFFS_READ: | |
773 fdi = tmffs_get8(); | |
774 size = tmffs_get8(); | |
775 size = ffs_read(fdi, &buffer[0], size); | |
776 error = tmffs_putdata(&outp, &buffer[0], size); | |
777 tw(tr(TR_FUNC, TrTmffs, "TMFFS_READ(%d, %d)\n", fdi, size)); | |
778 ttw(ttr(TTrTmffs, "tm_read" NL)); | |
779 break; | |
780 | |
781 | |
782 case TMFFS_MKDIR: | |
783 error = tmffs_getstring(&inp, string); | |
784 if (error >= 0) | |
785 error = ffs_mkdir(string); | |
786 tw(tr(TR_FUNC, TrTmffs, "TMFFS_MKDIR()\n")); | |
787 ttw(ttr(TTrTmffs, "tm_mkd" NL)); | |
788 break; | |
789 case TMFFS_OPENDIR: | |
790 error = tmffs_getstring(&inp, string); | |
791 if (error >= 0) { | |
792 error = ffs_opendir(string, (struct dir_s *) buffer); | |
793 tmffs_put8(error); // Note: we must put error/number of objects. | |
794 } | |
795 if (error >= 0) | |
796 tmffs_putdata(&outp, buffer, sizeof(struct dir_s)); | |
797 | |
798 tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPENDIR()\n")); | |
799 ttw(ttr(TTrTmffs, "tm_od" NL)); | |
800 break; | |
801 case TMFFS_READDIR: | |
802 tmffs_getdata(); | |
803 stringsize = tmffs_get8(); | |
804 error = ffs_readdir((struct dir_s *) buffer, string, stringsize); | |
805 tmffs_put8(error); // Note: we have to return bytes read. | |
806 if (error >= 0) { | |
807 tmffs_putdata(&outp, buffer, sizeof(struct dir_s)); | |
808 stringsize = strlen(string) + 1; | |
809 tmffs_putstring(&outp, string, stringsize); | |
810 } | |
811 tw(tr(TR_FUNC, TrTmffs, "TMFFS_READDIR()\n")); | |
812 ttw(ttr(TTrTmffs, "tm_rdd" NL)); | |
813 break; | |
814 | |
815 case TMFFS_STAT: | |
816 error = tmffs_getstring(&inp, string); | |
817 if (error >= 0) | |
818 error = ffs_stat(string, (struct stat_s *) buffer); | |
819 if (error >= 0) | |
820 tmffs_putdata(&outp, buffer, sizeof(struct stat_s)); | |
821 | |
822 tw(tr(TR_FUNC, TrTmffs, "TMFFS_STAT()\n")); | |
823 ttw(ttr(TTrTmffs, "tm_st" NL)); | |
824 break; | |
825 case TMFFS_XLSTAT: | |
826 error = tmffs_getstring(&inp, string); | |
827 if (error >= 0) | |
828 error = ffs_xlstat(&string[0], (struct xstat_s *) buffer); | |
829 if (error >= 0) | |
830 tmffs_putdata(&outp, buffer, sizeof(struct xstat_s)); | |
831 tw(tr(TR_FUNC, TrTmffs, "TMFFS_()\n")); | |
832 ttw(ttr(TTrTmffs, "tm_xlst" NL)); | |
833 break; | |
834 | |
835 | |
836 case TMFFS_SYMLINK: | |
837 error = tmffs_getstring(&inp, string); | |
838 tmffs_getdata(); | |
839 if (error >= 0) | |
840 error = ffs_symlink(string, (char *) buffer); | |
841 tw(tr(TR_FUNC, TrTmffs, "TMFFS_SYMLINK()\n")); | |
842 ttw(ttr(TTrTmffs, "tm_sym" NL)); | |
843 break; | |
844 case TMFFS_READLINK: | |
845 error = tmffs_getstring(&inp, string); | |
846 tmffs_getdata(); | |
847 if (error >= 0) { | |
848 size = ffs_readlink(string, (char *) buffer, TMFFS_BUFFER_SIZE); | |
849 error = tmffs_putdata(&outp, buffer, size); // put link contents | |
850 } | |
851 tw(tr(TR_FUNC, TrTmffs, "TMFFS_READLINK()\n")); | |
852 ttw(ttr(TTrTmffs, "tm_rdl" NL)); | |
853 break; | |
854 | |
855 | |
856 case TMFFS_QUERY: | |
857 param = tmffs_get8(); | |
858 error = ffs_query(param, buffer); | |
859 if (error >= 0) | |
860 tmffs_putdata(&outp, buffer, 16); | |
861 tw(tr(TR_FUNC, TrTmffs, "TMFFS_QUERY(%d)\n", param)); | |
862 ttw(ttr(TTrTmffs, "tm_q" NL)); | |
863 break; | |
864 case TMFFS_FCONTROL: | |
865 error = tmffs_getstring(&inp, string); | |
866 type = tmffs_get8(); | |
867 param = tmffs_get32(); | |
868 if (error >= 0) | |
869 error = ffs_fcontrol(string, type, param); | |
870 tw(tr(TR_FUNC, TrTmffs, "TMFFS_FCONTROL()\n")); | |
871 ttw(ttr(TTrTmffs, "tm_fc" NL)); | |
872 break; | |
873 | |
874 case TMFFS_TFFS: | |
875 { | |
876 #if (WITH_TFFS == 1) | |
877 extern char ffs_test_string[]; // defined in task.c | |
878 error = tmffs_getstring(&inp, string); | |
879 memcpy(ffs_test_string, string, stringsize); | |
880 tw(tr(TR_FUNC, TrTmffs, "TMFFS_TFFS()\n")); | |
881 ttw(ttr(TTrTmffs, "tm_tffs" NL)); | |
882 tmffs_put8(EFFS_OK); | |
883 #else | |
884 tmffs_put8(EFFS_NOSYS); | |
885 #endif | |
886 break; | |
887 } | |
888 default: | |
889 error = EFFS_NOSYS; | |
890 tmffs_put8(EFFS_NOSYS); | |
891 tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n")); | |
892 ttw(ttr(TTrTmffs, "tm?" NL)); | |
893 break; | |
894 } | |
895 | |
896 // check if we read beyond buffer end | |
897 if (inp > inp_start + insize) { | |
898 tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n")); | |
899 ttw(ttr(TTrTmffs, "tm_fatal" NL)); | |
900 ttw(ttr(TTrTmffs, "insize: %d, diff: %d" NL, insize, | |
901 inp - (inp_start + insize))); | |
902 // NOTEME: We really should reset output buffer and put a return | |
903 // code that tells us what went wrong! | |
904 error = ETM_PACKET; // FIXME find another error | |
905 } | |
906 | |
907 ttw(ttr(TTrTmffs, "error %d" NL, error)); | |
908 if (error > 0) | |
909 error = 0; | |
910 | |
911 pkt->mid = ETM_FFS2; | |
912 pkt->size = outp - outp_start; | |
913 pkt->status = -error; | |
914 | |
915 etm_pkt_send(pkt); | |
916 etm_free(pkt); | |
917 | |
918 tw(tr(TR_END, TrTmffs, "")); | |
919 | |
920 return ETM_OK; | |
921 } | |
922 | |
923 #endif // TMFFS2 | |
924 |