FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/services/ffs/tmffs.c @ 221:842c9fd828fd
gsm-fw: TMFFS integrated
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Tue, 07 Jan 2014 03:51:09 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
220:aa4ba71a1032 | 221:842c9fd828fd |
---|---|
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 #include "../../include/config.h" | |
12 #include "../../riviera/rv/rv_defined_swe.h" | |
13 | |
14 #ifdef RVM_ETM_SWE | |
15 #include "../etm/etm.h" | |
16 #include "../etm/etm_api.h" | |
17 #endif | |
18 | |
19 #include "ffs.h" | |
20 #include "task.h" | |
21 #include "ffstrace.h" | |
22 #include "tmffs.h" | |
23 | |
24 #include <string.h> | |
25 | |
26 /****************************************************************************** | |
27 * Local globals for all protocols | |
28 ******************************************************************************/ | |
29 | |
30 #if TMFFS1 || TMFFS2 | |
31 static int32 bufsize, tmpsize; | |
32 static uint8 stringsize; | |
33 #endif | |
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 // Not in use | |
42 //#define tmffs_put32(x) tmffs_put16(x); tmffs_put16(x >> 16); | |
43 | |
44 #ifdef RVM_ETM_SWE | |
45 | |
46 int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize); | |
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 #endif | |
96 | |
97 /* Init of FFS in the ETM database */ | |
98 int etm_ffs_init(void) | |
99 { | |
100 int status; | |
101 | |
102 #ifdef RVM_ETM_SWE | |
103 status = etm_register("FFS1", ETM_FFS1, 0, 0, etm_ffs1_pkt_receive); | |
104 status = etm_register("FFS2", ETM_FFS2, 0, 0, etm_ffs2_pkt_receive); | |
105 #else | |
106 status = 0; | |
107 #endif | |
108 return status; | |
109 } | |
110 | |
111 /****************************************************************************** | |
112 * FFS1 Protocol | |
113 ******************************************************************************/ | |
114 | |
115 #ifndef TMFFS1 | |
116 | |
117 int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize) | |
118 { | |
119 return -1; // FIXME handle error better | |
120 } | |
121 | |
122 // Note these functions must be presented because ffs_query() use them but | |
123 // they are only valid if FFS1_PROTOCOL is used. | |
124 int tmffs_bufsize(void) | |
125 { | |
126 return EFFS_NOSYS; | |
127 } | |
128 | |
129 unsigned char *tmffs_bufaddr(void) | |
130 { | |
131 return 0; | |
132 } | |
133 | |
134 #else | |
135 | |
136 #if (GSMLITE == 1) | |
137 #define TMFFS1_BUFFER_SIZE 4000 //previously 8192 | |
138 #else | |
139 #define TMFFS1_BUFFER_SIZE 8192 | |
140 #endif | |
141 | |
142 #define TMFFS1_STRING_SIZE 127 | |
143 | |
144 /****************************************************************************** | |
145 * Macros | |
146 ******************************************************************************/ | |
147 | |
148 #define tmffs1_putdata(outp, src, size) \ | |
149 tmffs_put8(FPI_DATA); \ | |
150 tmffs_put16(size); \ | |
151 memcpy(outp, src, size); \ | |
152 outp += size; | |
153 | |
154 /****************************************************************************** | |
155 * Local globals | |
156 ******************************************************************************/ | |
157 | |
158 static unsigned char buffer[TMFFS1_BUFFER_SIZE]; | |
159 static bufindex; | |
160 | |
161 static char string[TMFFS1_STRING_SIZE]; | |
162 | |
163 static effs_t tm_ffs_overflowck(void) | |
164 { | |
165 if (bufsize > TMFFS1_BUFFER_SIZE || | |
166 stringsize > TMFFS1_STRING_SIZE) | |
167 return EFFS_TOOBIG; | |
168 | |
169 return EFFS_OK; | |
170 } | |
171 | |
172 | |
173 /****************************************************************************** | |
174 * tm_ffs | |
175 ******************************************************************************/ | |
176 | |
177 /** | |
178 * NOTEME: This has been introduced when the ffs 1MB device limit was | |
179 * broken. This made location_t go from uint16 to uint32, messing up | |
180 * with PCTM. | |
181 * | |
182 * This makes the xstat_s look the same to PCTM PC side, though | |
183 * location will be forced to 0. | |
184 */ | |
185 void hack_xstat_2_look_like_old_xstat(struct xstat_s *xstat) | |
186 { | |
187 int i; | |
188 char *location; | |
189 | |
190 xstat->location = 0; | |
191 | |
192 for (location = (char *) &(xstat->location) + 2; location <= (char *) &(xstat->sequence); location++) | |
193 *location = location[2]; | |
194 } | |
195 | |
196 // Parse input message and execute function. Then fill output buffer with | |
197 // return values from the called function and transmit the message. Return | |
198 // number of bytes inserted into output buffer. If return value is negative, | |
199 // it represents an error code. | |
200 int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize) | |
201 { | |
202 int error; | |
203 tmffs_cid_t fid; | |
204 | |
205 unsigned char *outp_start = outp; | |
206 unsigned char *inp_start = inp; | |
207 | |
208 static uint8 i8[2]; static uint16 i8i; | |
209 static uint16 i16[2]; static uint16 i16i; | |
210 static uint32 i32[2]; static uint16 i32i; | |
211 | |
212 tw(tr(TR_BEGIN, TrTmffs, "TMFFS:\n")); | |
213 | |
214 while((fid = *inp++) != FPI_END) | |
215 { | |
216 switch(fid) | |
217 { | |
218 /********************************************************** | |
219 * Generic Protocol Functions | |
220 **********************************************************/ | |
221 | |
222 case FPI_BEGIN: | |
223 // for (i8i = 0; i8i < TMFFS1_STRING_SIZE; i8i++) // DEBUG | |
224 // string[i8i] = '#'; | |
225 // for (i8i = 0; i8i < TMFFS1_BUFFER_SIZE; i8i++) // DEBUG | |
226 // buffer[i8i] = '$'; | |
227 i8i = i16i = i32i = bufsize = stringsize = 0; | |
228 bufindex = 0; | |
229 i8[0] = i8[1] = 0; | |
230 i16[0] = i16[1] = 0; | |
231 i32[0] = i32[1] = 0; | |
232 string[0] = buffer[0] = 0; | |
233 tw(tr(TR_FUNC, TrTmffs, "FPI_BEGIN\n")); | |
234 ttw(ttr(TTrTmffs, "tm1" NL)); | |
235 break; | |
236 case FPI_TMFFS_VERSION: | |
237 // NULL -> UINT16 | |
238 tmffs_put16(TMFFS1_VERSION); | |
239 break; | |
240 | |
241 case FPI_INT8: | |
242 i8[i8i++] = inp[0]; inp += 1; | |
243 tw(tr(TR_FUNC, TrTmffs, "FPI_INT8(%d/0x%x)\n", | |
244 i8[i8i-1], i8[i8i-1])); | |
245 ttw(ttr(TTrTmffs, "tm_i8" NL)); | |
246 break; | |
247 case FPI_INT16: | |
248 i16[i16i++] = (inp[0]) | (inp[1] << 8); inp += 2; | |
249 tw(tr(TR_FUNC, TrTmffs, "FPI_INT16(%d/0x%x)\n", | |
250 i16[i16i-1], i16[i16i-1])); | |
251 ttw(ttr(TTrTmffs, "tm_i16" NL)); | |
252 break; | |
253 case FPI_INT32: | |
254 i32[i32i++] = inp[0] | (inp[1] << 8) | |
255 | (inp[2] << 16) | (inp[3] << 24); | |
256 inp += 4; | |
257 tw(tr(TR_FUNC, TrTmffs, "FPI_INT32(%d/0x%x)\n", | |
258 i32[i32i-1], i32[i32i-1])); | |
259 ttw(ttr(TTrTmffs, "tm_i32" NL)); | |
260 break; | |
261 case FPI_BUFFER: | |
262 bufsize = inp[0] | (inp[1] << 8); inp += 2; | |
263 tw(tr(TR_FUNC, TrTmffs, "FPI_BUFFER(%d)\n", bufsize)); | |
264 ttw(ttr(TTrTmffs, "tm_buf" NL)); | |
265 break; | |
266 case FPI_DATA: | |
267 bufsize = inp[0] | (inp[1] << 8); inp += 2; | |
268 memcpy(buffer, inp, bufsize); inp += bufsize; | |
269 tw(tr(TR_FUNC, TrTmffs, "FPI_DATA(%d)\n", bufsize)); | |
270 ttw(ttr(TTrTmffs, "tm_data" NL)); | |
271 break; | |
272 case FPI_STRBUF: | |
273 // string buffer size MUST include null-terminator! | |
274 stringsize = inp[0]; inp += 1; | |
275 tw(tr(TR_FUNC, TrTmffs, "FPI_STRBUF(%d)\n", stringsize)); | |
276 ttw(ttr(TTrTmffs, "tm_sbuf" NL)); | |
277 break; | |
278 case FPI_STRING: | |
279 // stringsize MUST include null-terminator! | |
280 // <INT8>, <BYTES> -> NULL (or ERROR) | |
281 stringsize = inp[0]; inp += 1; | |
282 if (stringsize <= TMFFS1_STRING_SIZE) | |
283 memcpy(string, inp, stringsize); | |
284 inp += stringsize; | |
285 tw(tr(TR_FUNC, TrTmffs, "FPI_STRING(%d,'%s')\n", | |
286 stringsize, string)); | |
287 ttw(ttr(TTrTmffs, "tm_s" NL)); | |
288 break; | |
289 | |
290 case FPI_BUFREAD: | |
291 // <INT16> -> DATA | |
292 tmpsize = inp[0] | (inp[1] << 8); inp += 2; | |
293 tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_READ(%d)\n", tmpsize)); | |
294 tmffs1_putdata(outp, &buffer[bufindex], tmpsize); | |
295 bufindex += tmpsize; | |
296 ttw(ttr(TTrTmffs, "tm_bufrd" NL)); | |
297 break; | |
298 case FPI_BUFWRITE: | |
299 // <INT16>, <BYTES> -> NULL (or ERROR) | |
300 tmpsize = inp[0] | (inp[1] << 8); inp += 2; | |
301 tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_WRITE(%d)\n", tmpsize)); | |
302 if (bufsize + tmpsize <= TMFFS1_BUFFER_SIZE) | |
303 memcpy(&buffer[bufsize], inp, tmpsize); | |
304 inp += tmpsize; | |
305 bufsize += tmpsize; | |
306 ttw(ttr(TTrTmffs, "tm_bufwr" NL)); | |
307 break; | |
308 case FPI_BUFSET: | |
309 bufindex = inp[0] | (inp[1] << 8); inp += 2; | |
310 tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_SET(%d)\n", bufindex)); | |
311 ttw(ttr(TTrTmffs, "tm_bufset" NL)); | |
312 break; | |
313 | |
314 /********************************************************** | |
315 * FFS Functions | |
316 **********************************************************/ | |
317 | |
318 case FPI_PREFORMAT: | |
319 // NULL -> ERROR | |
320 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
321 error = ffs_preformat_nb(i16[0], 0); | |
322 if (error > 0) | |
323 error = 0; // ignore request id | |
324 tmffs_put8(error); | |
325 tw(tr(TR_FUNC, TrTmffs, "FPI_PREFORMAT(0x%x)\n", i16[0])); | |
326 ttw(ttr(TTrTmffs, "tm_pfmt" NL)); | |
327 break; | |
328 case FPI_FORMAT: | |
329 // STRING -> ERROR | |
330 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
331 error = ffs_format_nb(&string[0], i16[0], 0); | |
332 if (error > 0) | |
333 error = 0; // ignore request id | |
334 tmffs_put8(error); | |
335 tw(tr(TR_FUNC, TrTmffs, "FPI_FORMAT(0x%x)\n", i16[0])); | |
336 ttw(ttr(TTrTmffs, "tm_fmt" NL)); | |
337 break; | |
338 | |
339 | |
340 case FPI_FCREATE: | |
341 // STRING, DATA -> ERROR | |
342 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
343 error = ffs_fcreate_nb(string, buffer, bufsize, 0); | |
344 if (error > 0) | |
345 error = 0; // ignore request id | |
346 tmffs_put8(error); | |
347 tw(tr(TR_FUNC, TrTmffs, "FPI_FCREATE('%s', 0x%x, %d/0x%x)\n", | |
348 string, buffer, bufsize, bufsize)); | |
349 ttw(ttr(TTrTmffs, "tm_fcr" NL)); | |
350 break; | |
351 case FPI_FUPDATE: | |
352 // STRING, DATA -> ERROR | |
353 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
354 error = ffs_fupdate_nb(string, buffer, bufsize, 0); | |
355 if (error > 0) | |
356 error = 0; // ignore request id | |
357 tmffs_put8(error); | |
358 tw(tr(TR_FUNC, TrTmffs, "FPI_FUPDATE('%s', 0x%x, %d/0x%x)\n", | |
359 string, buffer, bufsize, bufsize)); | |
360 ttw(ttr(TTrTmffs, "tm_fup" NL)); | |
361 break; | |
362 case FPI_FWRITE: | |
363 // STRING, DATA -> ERROR | |
364 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
365 error = ffs_fwrite_nb(string, buffer, bufsize, 0); | |
366 if (error > 0) | |
367 error = 0; // ignore request id | |
368 tmffs_put8(error); | |
369 tw(tr(TR_FUNC, TrTmffs, "FPI_FWRITE('%s', 0x%x, %d/0x%x)\n", | |
370 string, buffer, bufsize, bufsize)); | |
371 ttw(ttr(TTrTmffs, "tm_fwr" NL)); | |
372 break; | |
373 case FPI_FREAD: | |
374 // STRING, BUFFER -> ERROR | |
375 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
376 error = ffs_file_read(string, buffer, TMFFS1_BUFFER_SIZE); | |
377 // Because a 32-bit integer is returned, we have to saturate it | |
378 // into an 8-bit value. | |
379 if (error >= 0) | |
380 error = 0; | |
381 tmffs_put8(error); | |
382 tw(tr(TR_FUNC, TrTmffs, "FPI_FREAD('%s', 0x%x, %d/0x%x)\n", | |
383 string, buffer, bufsize, bufsize)); | |
384 ttw(ttr(TTrTmffs, "tm_frd" NL)); | |
385 break; | |
386 case FPI_REMOVE: | |
387 // STRING -> ERROR | |
388 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
389 error = ffs_remove_nb(string, 0); | |
390 if (error > 0) | |
391 error = 0; // ignore request id | |
392 tmffs_put8(error); | |
393 tw(tr(TR_FUNC, TrTmffs, "FPI_REMOVE()\n")); | |
394 ttw(ttr(TTrTmffs, "tm_rm" NL)); | |
395 break; | |
396 | |
397 | |
398 case FPI_MKDIR: | |
399 // STRING -> ERROR | |
400 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
401 error = ffs_mkdir_nb(string, 0); | |
402 if (error > 0) | |
403 error = 0; // ignore request id | |
404 tmffs_put8(error); | |
405 tw(tr(TR_FUNC, TrTmffs, "FPI_MKDIR()\n")); | |
406 ttw(ttr(TTrTmffs, "tm_mkd" NL)); | |
407 break; | |
408 case FPI_OPENDIR: | |
409 // STRING, BUFFER -> ERROR, DATA | |
410 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
411 error = ffs_opendir(string, (struct dir_s *) buffer); | |
412 // Because a 32-bit integer is returned, we have to saturate it | |
413 // into an 8-bit value. | |
414 if (error >= 0) | |
415 error = 0; | |
416 tmffs_put8(error); | |
417 tmffs1_putdata(outp, buffer, sizeof(struct dir_s)); | |
418 tw(tr(TR_FUNC, TrTmffs, "FPI_OPENDIR()\n")); | |
419 ttw(ttr(TTrTmffs, "tm_od" NL)); | |
420 break; | |
421 case FPI_READDIR: | |
422 // DATA, STRBUF -> ERROR, DATA, STRING | |
423 string[0] = 0; | |
424 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
425 error = ffs_readdir((struct dir_s *) buffer, string, stringsize); | |
426 | |
427 // Saturate error(i) in order to let it fit in type int8. | |
428 if (error > 127) | |
429 error = 127; | |
430 tmffs_put8(error); | |
431 tmffs1_putdata(outp, buffer, sizeof(struct dir_s)); | |
432 stringsize = strlen(string) + 1; | |
433 tmffs_put8(FPI_STRING); // put directory entry's name... | |
434 tmffs_put8(stringsize); | |
435 memcpy(outp, string, stringsize); | |
436 outp += stringsize; | |
437 tw(tr(TR_FUNC, TrTmffs, "FPI_READDIR()\n")); | |
438 ttw(ttr(TTrTmffs, "tm_rdd" NL)); | |
439 break; | |
440 | |
441 | |
442 case FPI_STAT: | |
443 // STRING, BUFFER -> ERROR, DATA | |
444 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
445 error = ffs_stat(&string[0], (struct stat_s *) buffer); | |
446 tmffs_put8(error); | |
447 tmffs1_putdata(outp, buffer, sizeof(struct stat_s)); | |
448 tw(tr(TR_FUNC, TrTmffs, "FPI_STAT()\n")); | |
449 ttw(ttr(TTrTmffs, "tm_st" NL)); | |
450 break; | |
451 case FPI_LINKSTAT: | |
452 // STRING, BUFFER -> ERROR, DATA | |
453 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
454 error = ffs_xlstat(&string[0], (struct xstat_s *) buffer); | |
455 tmffs_put8(error); | |
456 | |
457 hack_xstat_2_look_like_old_xstat((struct xstat_s *) buffer); | |
458 | |
459 tmffs1_putdata(outp, buffer, sizeof(struct xstat_s) - 2); | |
460 tw(tr(TR_FUNC, TrTmffs, "FPI_()\n")); | |
461 ttw(ttr(TTrTmffs, "tm_lst" NL)); | |
462 break; | |
463 | |
464 | |
465 case FPI_SYMLINK: | |
466 // STRING, DATA -> ERROR | |
467 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
468 error = ffs_symlink_nb(string, (char *) buffer, 0); | |
469 if (error > 0) | |
470 error = 0; // ignore request id | |
471 tmffs_put8(error); | |
472 tw(tr(TR_FUNC, TrTmffs, "FPI_SYMLINK()\n")); | |
473 ttw(ttr(TTrTmffs, "tm_sym" NL)); | |
474 break; | |
475 case FPI_READLINK: | |
476 // STRING, BUFFER -> ERROR, DATA | |
477 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
478 error = ffs_readlink(string, (char *) buffer, TMFFS1_BUFFER_SIZE); | |
479 // Because a 32-bit integer is returned, we have to saturate it | |
480 // into an 8-bit value. | |
481 if (error >= 0) | |
482 error = 0; | |
483 tmffs_put8(error); | |
484 tmffs1_putdata(outp, buffer, bufsize); // put link contents | |
485 tw(tr(TR_FUNC, TrTmffs, "FPI_READLINK()\n")); | |
486 ttw(ttr(TTrTmffs, "tm_rdl" NL)); | |
487 break; | |
488 | |
489 | |
490 case FPI_QUERY: | |
491 // INT8 -> ERROR, DATA | |
492 error = ffs_query(i8[0], buffer); | |
493 tmffs_put8(error); | |
494 tmffs1_putdata(outp, buffer, 16); | |
495 tw(tr(TR_FUNC, TrTmffs, "FPI_QUERY()\n")); | |
496 ttw(ttr(TTrTmffs, "tm_q" NL)); | |
497 break; | |
498 case FPI_FCONTROL: | |
499 // STRING INT8 INT32 -> ERROR | |
500 if ((error = tm_ffs_overflowck()) == EFFS_OK) | |
501 error = ffs_fcontrol_nb(string, i8[0], i32[0], 0); | |
502 if (error > 0) | |
503 error = 0; // ignore request id | |
504 tmffs_put8(error); | |
505 tw(tr(TR_FUNC, TrTmffs, "FPI_FCONTROL()\n")); | |
506 ttw(ttr(TTrTmffs, "tm_fc" NL)); | |
507 break; | |
508 | |
509 case FPI_INIT: | |
510 // NULL -> ERROR | |
511 error =ffs_initialize(); | |
512 tmffs_put8(error); | |
513 tw(tr(TR_FUNC, TrTmffs, "FPI_INIT()\n")); | |
514 ttw(ttr(TTrTmffs, "tm_init" NL)); | |
515 break; | |
516 case FPI_EXIT: | |
517 // NULL -> ERROR | |
518 error = ffs_exit(); | |
519 tmffs_put8(error); | |
520 tw(tr(TR_FUNC, TrTmffs, "FPI_EXIT()\n")); | |
521 ttw(ttr(TTrTmffs, "tm_exit" NL)); | |
522 break; | |
523 | |
524 | |
525 case FPI_TFFS: | |
526 { | |
527 // STRING -> ERROR | |
528 #if (WITH_TFFS == 1) | |
529 extern char ffs_test_string[]; // defined in task.c | |
530 | |
531 memcpy(ffs_test_string, string, stringsize); | |
532 tw(tr(TR_FUNC, TrTmffs, "FPI_TFFS()\n")); | |
533 ttw(ttr(TTrTmffs, "tm_tffs" NL)); | |
534 #else | |
535 tmffs_put8(EFFS_NOSYS); | |
536 #endif | |
537 break; | |
538 } | |
539 default: | |
540 tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n")); | |
541 ttw(ttr(TTrTmffs, "tm?" NL)); | |
542 break; | |
543 } | |
544 // check if we read beyond buffer end | |
545 if (inp > inp_start + insize) { | |
546 tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n")); | |
547 ttw(ttr(TTrTmffs, "tm_fatal" NL)); | |
548 // NOTEME: We really should reset output buffer and put a return | |
549 // code that tells us what went wrong! | |
550 return 0; | |
551 } | |
552 } | |
553 | |
554 tw(tr(TR_END, TrTmffs, "")); | |
555 | |
556 return outp - outp_start; | |
557 } | |
558 | |
559 int tmffs_bufsize(void) | |
560 { | |
561 return TMFFS1_BUFFER_SIZE; | |
562 } | |
563 | |
564 unsigned char *tmffs_bufaddr(void) | |
565 { | |
566 return buffer; | |
567 } | |
568 | |
569 #endif // TMFFS1 | |
570 | |
571 /****************************************************************************** | |
572 * FFS2 protocol | |
573 ******************************************************************************/ | |
574 | |
575 #ifndef TMFFS2 | |
576 | |
577 #ifdef RVM_ETM_SWE | |
578 int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize) | |
579 { | |
580 int error; | |
581 | |
582 tw(tr(TR_BEGIN, TrTmffs, "FFS2 protocol not represented in target\n")); | |
583 error = -1; // FIXME other error? | |
584 | |
585 // We return a packet instead of waiting for timeout. | |
586 pkt->size = 0; | |
587 pkt->status = -error; | |
588 pkt->mid = ETM_FFS2; | |
589 etm_pkt_send(pkt); | |
590 | |
591 target_free(pkt); | |
592 tw(tr(TR_END, TrTmffs, "")); | |
593 | |
594 return error; | |
595 } | |
596 #endif | |
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 |