You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2473 lines
55 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007-2008 by Øyvind Harboe *
  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 *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "log.h"
  23. #include "types.h"
  24. #include "jtag.h"
  25. #include "configuration.h"
  26. #include "xsvf.h"
  27. #include "target.h"
  28. #include "flash.h"
  29. #include "nand.h"
  30. #include "pld.h"
  31. #include "command.h"
  32. #include "server.h"
  33. #include "telnet_server.h"
  34. #include "gdb_server.h"
  35. #include <time_support.h>
  36. #include <sys/time.h>
  37. #include <sys/types.h>
  38. #include <strings.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <unistd.h>
  43. #include <errno.h>
  44. #include <cyg/io/flash.h>
  45. #include <pkgconf/fs_jffs2.h> // Address of JFFS2
  46. #include <network.h>
  47. #include <fcntl.h>
  48. #include <sys/stat.h>
  49. #include <cyg/fileio/fileio.h>
  50. #include <dirent.h>
  51. #include <cyg/athttpd/http.h>
  52. #include <cyg/athttpd/socket.h>
  53. #include <cyg/athttpd/handler.h>
  54. #include <cyg/athttpd/cgi.h>
  55. #include <cyg/athttpd/forms.h>
  56. #include <cyg/hal/hal_diag.h>
  57. #include <cyg/kernel/kapi.h>
  58. #include <cyg/io/serialio.h>
  59. #include <cyg/io/io.h>
  60. #include <netinet/tcp.h>
  61. #include "rom.h"
  62. #include <sys/ioctl.h>
  63. #include <sys/socket.h>
  64. #include <netinet/in.h>
  65. #include <net/if.h>
  66. #include <arpa/inet.h>
  67. #include <sys/types.h>
  68. #include <sys/socket.h>
  69. #include <netdb.h>
  70. #include <netinet/in.h>
  71. #include <unistd.h>
  72. #include <arpa/inet.h>
  73. #include <stdio.h>
  74. #include <ifaddrs.h>
  75. #include <string.h>
  76. #include <unistd.h>
  77. #include <stdio.h>
  78. #define MAX_IFS 64
  79. #if defined(CYGPKG_NET_FREEBSD_STACK)
  80. #include <tftp_support.h>
  81. /* posix compatibility broken*/
  82. struct tftpd_fileops fileops =
  83. {
  84. (int (*)(const char *, int))open,
  85. close,
  86. (int (*)(int, const void *, int))write,
  87. ( int (*)(int, void *, int))read
  88. };
  89. #endif
  90. #define ZYLIN_VERSION "1.44"
  91. #define ZYLIN_DATE __DATE__
  92. #define ZYLIN_TIME __TIME__
  93. /* hmmm.... we can't pick up the right # during build if we've checked this out
  94. * in Eclipse... arrggghh...*/
  95. #define ZYLIN_OPENOCD 1033
  96. #define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME
  97. #define ZYLIN_CONFIG_DIR "/config/settings"
  98. void diag_write(char *buf, int len)
  99. {
  100. int j;
  101. for (j = 0; j < len; j++)
  102. {
  103. diag_printf("%c", buf[j]);
  104. }
  105. }
  106. static bool serialLog = true;
  107. static bool writeLog = true;
  108. struct FastLoad
  109. {
  110. u32 address;
  111. u8 *data;
  112. int length;
  113. };
  114. static int fastload_num;
  115. static struct FastLoad *fastload;
  116. static void free_fastload()
  117. {
  118. if (fastload!=NULL)
  119. {
  120. int i;
  121. for (i=0; i<fastload_num; i++)
  122. {
  123. if (fastload[i].data)
  124. free(fastload[i].data);
  125. }
  126. free(fastload);
  127. fastload=NULL;
  128. }
  129. }
  130. int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  131. {
  132. u8 *buffer;
  133. u32 buf_cnt;
  134. u32 image_size;
  135. u32 min_address=0;
  136. u32 max_address=0xffffffff;
  137. int i;
  138. int retval;
  139. image_t image;
  140. duration_t duration;
  141. char *duration_text;
  142. if ((argc < 1)||(argc > 5))
  143. {
  144. return ERROR_COMMAND_SYNTAX_ERROR;
  145. }
  146. /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
  147. if (argc >= 2)
  148. {
  149. image.base_address_set = 1;
  150. image.base_address = strtoul(args[1], NULL, 0);
  151. }
  152. else
  153. {
  154. image.base_address_set = 0;
  155. }
  156. image.start_address_set = 0;
  157. if (argc>=4)
  158. {
  159. min_address=strtoul(args[3], NULL, 0);
  160. }
  161. if (argc>=5)
  162. {
  163. max_address=strtoul(args[4], NULL, 0)+min_address;
  164. }
  165. if (min_address>max_address)
  166. {
  167. return ERROR_COMMAND_SYNTAX_ERROR;
  168. }
  169. duration_start_measure(&duration);
  170. if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
  171. {
  172. return ERROR_OK;
  173. }
  174. image_size = 0x0;
  175. retval = ERROR_OK;
  176. fastload_num=image.num_sections;
  177. fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
  178. if (fastload==NULL)
  179. {
  180. image_close(&image);
  181. return ERROR_FAIL;
  182. }
  183. memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
  184. for (i = 0; i < image.num_sections; i++)
  185. {
  186. buffer = malloc(image.sections[i].size);
  187. if (buffer == NULL)
  188. {
  189. command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
  190. break;
  191. }
  192. if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
  193. {
  194. free(buffer);
  195. break;
  196. }
  197. u32 offset=0;
  198. u32 length=buf_cnt;
  199. /* DANGER!!! beware of unsigned comparision here!!! */
  200. if ((image.sections[i].base_address+buf_cnt>=min_address)&&
  201. (image.sections[i].base_address<max_address))
  202. {
  203. if (image.sections[i].base_address<min_address)
  204. {
  205. /* clip addresses below */
  206. offset+=min_address-image.sections[i].base_address;
  207. length-=offset;
  208. }
  209. if (image.sections[i].base_address+buf_cnt>max_address)
  210. {
  211. length-=(image.sections[i].base_address+buf_cnt)-max_address;
  212. }
  213. fastload[i].address=image.sections[i].base_address+offset;
  214. fastload[i].data=malloc(length);
  215. if (fastload[i].data==NULL)
  216. {
  217. free(buffer);
  218. break;
  219. }
  220. memcpy(fastload[i].data, buffer+offset, length);
  221. fastload[i].length=length;
  222. image_size += length;
  223. command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
  224. }
  225. free(buffer);
  226. }
  227. duration_stop_measure(&duration, &duration_text);
  228. if (retval==ERROR_OK)
  229. {
  230. command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
  231. }
  232. free(duration_text);
  233. image_close(&image);
  234. if (retval!=ERROR_OK)
  235. {
  236. free_fastload();
  237. }
  238. return retval;
  239. }
  240. int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  241. {
  242. if (argc>0)
  243. return ERROR_COMMAND_SYNTAX_ERROR;
  244. if (fastload==NULL)
  245. {
  246. LOG_ERROR("No image in memory");
  247. return ERROR_FAIL;
  248. }
  249. int i;
  250. int ms=timeval_ms();
  251. int size=0;
  252. for (i=0; i<fastload_num;i++)
  253. {
  254. int retval;
  255. target_t *target = get_current_target(cmd_ctx);
  256. if ((retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data)) != ERROR_OK)
  257. {
  258. return retval;
  259. }
  260. size+=fastload[i].length;
  261. }
  262. int after=timeval_ms();
  263. command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
  264. return ERROR_OK;
  265. }
  266. /* Give TELNET a way to find out what version this is */
  267. int handle_zy1000_version_command(struct command_context_s *cmd_ctx, char *cmd,
  268. char **args, int argc)
  269. {
  270. if (argc > 1)
  271. {
  272. return ERROR_COMMAND_SYNTAX_ERROR;
  273. }
  274. if (argc == 0)
  275. {
  276. command_print(cmd_ctx, ZYLIN_OPENOCD_VERSION);
  277. } else if (strcmp("openocd", args[0])==0)
  278. {
  279. command_print(cmd_ctx, "%d", ZYLIN_OPENOCD);
  280. } else if (strcmp("zy1000", args[0])==0)
  281. {
  282. command_print(cmd_ctx, "%s", ZYLIN_VERSION);
  283. } else if (strcmp("date", args[0])==0)
  284. {
  285. command_print(cmd_ctx, "%s", ZYLIN_DATE);
  286. } else
  287. {
  288. return ERROR_COMMAND_SYNTAX_ERROR;
  289. }
  290. return ERROR_OK;
  291. }
  292. extern flash_driver_t *flash_drivers[];
  293. extern target_type_t *target_types[];
  294. #ifdef CYGPKG_PROFILE_GPROF
  295. #include <cyg/profile/profile.h>
  296. extern char _stext, _etext; // Defined by the linker
  297. void start_profile(void)
  298. {
  299. // This starts up the system-wide profiling, gathering
  300. // profile information on all of the code, with a 16 byte
  301. // "bucket" size, at a rate of 100us/profile hit.
  302. // Note: a bucket size of 16 will give pretty good function
  303. // resolution. Much smaller and the buffer becomes
  304. // much too large for very little gain.
  305. // Note: a timer period of 100us is also a reasonable
  306. // compromise. Any smaller and the overhead of
  307. // handling the timter (profile) interrupt could
  308. // swamp the system. A fast processor might get
  309. // by with a smaller value, but a slow one could
  310. // even be swamped by this value. If the value is
  311. // too large, the usefulness of the profile is reduced.
  312. // no more interrupts than 1/10ms.
  313. // profile_on(&_stext, &_etext, 16, 10000); // DRAM
  314. //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
  315. profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
  316. }
  317. #endif
  318. // launch GDB server if a config file exists
  319. bool zylinjtag_parse_config_file(struct command_context_s *cmd_ctx, const char *config_file_name)
  320. {
  321. bool foundFile = false;
  322. FILE *config_file = NULL;
  323. command_print(cmd_ctx, "executing config file %s", config_file_name);
  324. config_file = fopen(config_file_name, "r");
  325. if (config_file)
  326. {
  327. fclose(config_file);
  328. int retval;
  329. retval = command_run_linef(cmd_ctx, "script %s", config_file_name);
  330. if (retval == ERROR_OK)
  331. {
  332. foundFile = true;
  333. }
  334. else
  335. {
  336. command_print(cmd_ctx, "Failed executing %s %d", config_file_name, retval);
  337. }
  338. }
  339. else
  340. {
  341. command_print(cmd_ctx, "No %s found", config_file_name);
  342. }
  343. return foundFile;
  344. }
  345. extern int eth0_up;
  346. static FILE *log;
  347. static char reboot_stack[2048];
  348. static void
  349. zylinjtag_reboot(cyg_addrword_t data)
  350. {
  351. serialLog = true;
  352. diag_printf("Rebooting in 100 ticks..\n");
  353. cyg_thread_delay(100);
  354. diag_printf("Unmounting /config..\n");
  355. umount("/config");
  356. diag_printf("Rebooting..\n");
  357. HAL_PLATFORM_RESET();
  358. }
  359. static cyg_thread zylinjtag_thread_object;
  360. static cyg_handle_t zylinjtag_thread_handle;
  361. void reboot(void)
  362. {
  363. cyg_thread_create(1,
  364. zylinjtag_reboot,
  365. (cyg_addrword_t)0,
  366. "reboot Thread",
  367. (void *)reboot_stack,
  368. sizeof(reboot_stack),
  369. &zylinjtag_thread_handle,
  370. &zylinjtag_thread_object);
  371. cyg_thread_resume(zylinjtag_thread_handle);
  372. }
  373. int configuration_output_handler(struct command_context_s *context, const char* line)
  374. {
  375. diag_printf("%s", line);
  376. return ERROR_OK;
  377. }
  378. int zy1000_configuration_output_handler_log(struct command_context_s *context, const char* line)
  379. {
  380. LOG_USER_N("%s", line);
  381. return ERROR_OK;
  382. }
  383. int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
  384. char **args, int argc)
  385. {
  386. if (argc != 1)
  387. {
  388. command_print(cmd_ctx, "rm <filename>");
  389. return ERROR_INVALID_ARGUMENTS;
  390. }
  391. if (unlink(args[0]) != 0)
  392. {
  393. command_print(cmd_ctx, "failed: %d", errno);
  394. }
  395. return ERROR_OK;
  396. }
  397. int loadFile(const char *fileName, void **data, int *len);
  398. int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
  399. char **args, int argc)
  400. {
  401. if (argc != 1)
  402. {
  403. command_print(cmd_ctx, "cat <filename>");
  404. return ERROR_INVALID_ARGUMENTS;
  405. }
  406. // NOTE!!! we only have line printing capability so we print the entire file as a single line.
  407. void *data;
  408. int len;
  409. int retval = loadFile(args[0], &data, &len);
  410. if (retval == ERROR_OK)
  411. {
  412. command_print(cmd_ctx, "%s", data);
  413. free(data);
  414. }
  415. else
  416. {
  417. command_print(cmd_ctx, "%s not found %d", args[0], retval);
  418. }
  419. return ERROR_OK;
  420. }
  421. int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
  422. char **args, int argc)
  423. {
  424. if (argc != 1)
  425. {
  426. command_print(cmd_ctx, "trunc <filename>");
  427. return ERROR_INVALID_ARGUMENTS;
  428. }
  429. FILE *config_file = NULL;
  430. config_file = fopen(args[0], "w");
  431. if (config_file != NULL)
  432. fclose(config_file);
  433. return ERROR_OK;
  434. }
  435. int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  436. {
  437. static int prev = 0;
  438. struct mallinfo info;
  439. if (argc != 0)
  440. {
  441. command_print(cmd_ctx, "meminfo");
  442. return ERROR_INVALID_ARGUMENTS;
  443. }
  444. info = mallinfo();
  445. if (prev > 0)
  446. {
  447. command_print(cmd_ctx, "Diff: %d", prev - info.fordblks);
  448. }
  449. prev = info.fordblks;
  450. command_print(cmd_ctx, "Available ram: %d", info.fordblks );
  451. return ERROR_OK;
  452. }
  453. static bool savePower;
  454. static void setPower(bool power)
  455. {
  456. savePower = power;
  457. if (power)
  458. {
  459. HAL_WRITE_UINT32(0x08000014, 0x8);
  460. } else
  461. {
  462. HAL_WRITE_UINT32(0x08000010, 0x8);
  463. }
  464. }
  465. int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  466. {
  467. if (argc > 1)
  468. {
  469. return ERROR_INVALID_ARGUMENTS;
  470. }
  471. if (argc == 1)
  472. {
  473. if (strcmp(args[0], "on") == 0)
  474. {
  475. setPower(1);
  476. }
  477. else if (strcmp(args[0], "off") == 0)
  478. {
  479. setPower(0);
  480. } else
  481. {
  482. command_print(cmd_ctx, "arg is \"on\" or \"off\"");
  483. return ERROR_INVALID_ARGUMENTS;
  484. }
  485. }
  486. command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
  487. return ERROR_OK;
  488. }
  489. int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
  490. char **args, int argc)
  491. {
  492. if (argc < 1)
  493. {
  494. command_print(cmd_ctx,
  495. "append <filename> [<string1>, [<string2>, ...]]");
  496. return ERROR_INVALID_ARGUMENTS;
  497. }
  498. FILE *config_file = NULL;
  499. config_file = fopen(args[0], "a");
  500. if (config_file != NULL)
  501. {
  502. int i;
  503. fseek(config_file, 0, SEEK_END);
  504. for (i = 1; i < argc; i++)
  505. {
  506. fwrite(args[i], strlen(args[i]), 1, config_file);
  507. if (i != argc - 1)
  508. {
  509. fwrite(" ", 1, 1, config_file);
  510. }
  511. }
  512. fwrite("\n", 1, 1, config_file);
  513. fclose(config_file);
  514. }
  515. return ERROR_OK;
  516. }
  517. extern int telnet_socket;
  518. int readMore(int fd, void *data, int length)
  519. {
  520. /* used in select() */
  521. fd_set read_fds;
  522. /* monitor sockets for acitvity */
  523. int fd_max = 1;
  524. FD_ZERO(&read_fds);
  525. /* listen for new connections */
  526. FD_SET(fd, &read_fds);
  527. // Maximum 5 seconds.
  528. struct timeval tv;
  529. tv.tv_sec = 5;
  530. tv.tv_usec = 0;
  531. int retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
  532. if (retval == 0)
  533. {
  534. diag_printf("Timed out waiting for binary payload\n");
  535. return -1;
  536. }
  537. if (retval != 1)
  538. return -1;
  539. return read_socket(fd, data, length);
  540. }
  541. int readAll(int fd, void *data, int length)
  542. {
  543. int pos = 0;
  544. for (;;)
  545. {
  546. int actual = readMore(fd, ((char *) data) + pos, length - pos);
  547. // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
  548. if (actual <= 0)
  549. return -1;
  550. pos += actual;
  551. if (pos == length)
  552. break;
  553. }
  554. return length;
  555. }
  556. int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  557. {
  558. cyg_uint32 value;
  559. if (argc != 1)
  560. {
  561. return ERROR_INVALID_ARGUMENTS;
  562. }
  563. HAL_READ_UINT32(strtoul(args[0], NULL, 0), value);
  564. command_print(cmd_ctx, "0x%x : 0x%x", strtoul(args[0], NULL, 0), value);
  565. return ERROR_OK;
  566. }
  567. int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  568. {
  569. if (argc != 2)
  570. {
  571. return ERROR_INVALID_ARGUMENTS;
  572. }
  573. HAL_WRITE_UINT32(strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0));
  574. return ERROR_OK;
  575. }
  576. int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  577. {
  578. if (argc != 2)
  579. {
  580. return ERROR_INVALID_ARGUMENTS;
  581. }
  582. // NOTE!!! we only have line printing capability so we print the entire file as a single line.
  583. void *data;
  584. int len;
  585. int retval = loadFile(args[0], &data, &len);
  586. if (retval != ERROR_OK)
  587. return retval;
  588. FILE *f = fopen(args[1], "wb");
  589. if (f == NULL)
  590. retval = ERROR_INVALID_ARGUMENTS;
  591. int pos = 0;
  592. for (;;)
  593. {
  594. int chunk = len - pos;
  595. static const int maxChunk = 512 * 1024; // ~1/sec
  596. if (chunk > maxChunk)
  597. {
  598. chunk = maxChunk;
  599. }
  600. if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
  601. retval = ERROR_INVALID_ARGUMENTS;
  602. if (retval != ERROR_OK)
  603. {
  604. break;
  605. }
  606. command_print(cmd_ctx, "%d", len - pos);
  607. pos += chunk;
  608. if (pos == len)
  609. break;
  610. }
  611. if (retval == ERROR_OK)
  612. {
  613. command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
  614. } else
  615. {
  616. command_print(cmd_ctx, "Failed: %d", retval);
  617. }
  618. if (data != NULL)
  619. free(data);
  620. if (f != NULL)
  621. fclose(f);
  622. if (retval != ERROR_OK)
  623. unlink(args[1]);
  624. return retval;
  625. }
  626. #ifdef CYGPKG_PROFILE_GPROF
  627. extern void start_profile();
  628. int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  629. {
  630. command_print(cmd_ctx, "Profiling started");
  631. start_profile();
  632. return ERROR_OK;
  633. }
  634. #endif
  635. externC void phi_init_all_network_interfaces();
  636. command_context_t *cmd_ctx;
  637. static bool webRunning = false;
  638. void keep_webserver()
  639. {
  640. // Target initialisation is only attempted at startup, so we sleep forever and
  641. // let the http server bail us out(i.e. get config files set up).
  642. diag_printf("OpenOCD has invoked exit().\n"
  643. "Use web server to correct any configuration settings and reboot.\n");
  644. if (!webRunning)
  645. reboot();
  646. // exit() will terminate the current thread and we we'll then sleep eternally or
  647. // we'll have a reboot scheduled.
  648. }
  649. extern void printDccChar(char c);
  650. static char logBuffer[128 * 1024];
  651. static const int logSize = sizeof(logBuffer);
  652. int writePtr = 0;
  653. int logCount = 0;
  654. void _zylinjtag_diag_write_char(char c, void **param)
  655. {
  656. if (writeLog)
  657. {
  658. logBuffer[writePtr] = c;
  659. writePtr = (writePtr + 1) % logSize;
  660. logCount++;
  661. }
  662. if (serialLog)
  663. {
  664. if (c == '\n')
  665. {
  666. HAL_DIAG_WRITE_CHAR('\r');
  667. }
  668. HAL_DIAG_WRITE_CHAR(c);
  669. }
  670. printDccChar(c);
  671. }
  672. #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
  673. #define IOSIZE 512
  674. static void copyfile(char *name2, char *name1)
  675. {
  676. int err;
  677. char buf[IOSIZE];
  678. int fd1, fd2;
  679. ssize_t done, wrote;
  680. fd1 = open(name1, O_WRONLY | O_CREAT);
  681. if (fd1 < 0)
  682. SHOW_RESULT( open, fd1 );
  683. fd2 = open(name2, O_RDONLY);
  684. if (fd2 < 0)
  685. SHOW_RESULT( open, fd2 );
  686. for (;;)
  687. {
  688. done = read(fd2, buf, IOSIZE );
  689. if (done < 0)
  690. {
  691. SHOW_RESULT( read, done );
  692. break;
  693. }
  694. if( done == 0 ) break;
  695. wrote = write(fd1, buf, done);
  696. if( wrote != done ) SHOW_RESULT( write, wrote );
  697. if( wrote != done ) break;
  698. }
  699. err = close(fd1);
  700. if( err < 0 ) SHOW_RESULT( close, err );
  701. err = close(fd2);
  702. if( err < 0 ) SHOW_RESULT( close, err );
  703. }
  704. static void copydir(char *name)
  705. {
  706. int err;
  707. DIR *dirp;
  708. mkdir("/ram/cgi", 0777);
  709. dirp = opendir(name);
  710. if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
  711. for (;;)
  712. {
  713. struct dirent *entry = readdir(dirp);
  714. if (entry == NULL)
  715. break;
  716. if (strcmp(entry->d_name, ".") == 0)
  717. continue;
  718. if (strcmp(entry->d_name, "..") == 0)
  719. continue;
  720. bool isDir = false;
  721. struct stat buf;
  722. char fullPath[PATH_MAX];
  723. strncpy(fullPath, name, PATH_MAX);
  724. strcat(fullPath, "/");
  725. strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
  726. if (stat(fullPath, &buf) == -1)
  727. {
  728. diag_printf("unable to read status from %s", fullPath);
  729. break;
  730. }
  731. isDir = S_ISDIR(buf.st_mode) != 0;
  732. if (isDir)
  733. continue;
  734. // diag_printf("<INFO>: entry %14s",entry->d_name);
  735. char fullname[PATH_MAX];
  736. char fullname2[PATH_MAX];
  737. strcpy(fullname, name);
  738. strcat(fullname, entry->d_name);
  739. strcpy(fullname2, "/ram/cgi/");
  740. strcat(fullname2, entry->d_name);
  741. // diag_printf("from %s to %s\n", fullname, fullname2);
  742. copyfile(fullname, fullname2);
  743. // diag_printf("\n");
  744. }
  745. err = closedir(dirp);
  746. if( err < 0 ) SHOW_RESULT( stat, err );
  747. }
  748. #if 0
  749. MTAB_ENTRY( romfs_mte1,
  750. "/rom",
  751. "romfs",
  752. "",
  753. (CYG_ADDRWORD) &filedata[0] );
  754. #endif
  755. void openocd_sleep_prelude()
  756. {
  757. cyg_mutex_unlock(&httpstate.jim_lock);
  758. }
  759. void openocd_sleep_postlude()
  760. {
  761. cyg_mutex_lock(&httpstate.jim_lock);
  762. }
  763. static int
  764. zylinjtag_Jim_Command_rm(Jim_Interp *interp,
  765. int argc,
  766. Jim_Obj * const *argv)
  767. {
  768. int del;
  769. if (argc != 2)
  770. {
  771. Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
  772. return JIM_ERR;
  773. }
  774. del = 0;
  775. if (unlink(Jim_GetString(argv[1], NULL)) == 0)
  776. del = 1;
  777. if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
  778. del = 1;
  779. return del ? JIM_OK : JIM_ERR;
  780. }
  781. static int zylinjtag_Jim_Command_threads(Jim_Interp *interp, int argc,
  782. Jim_Obj * const *argv)
  783. {
  784. cyg_handle_t thread = 0;
  785. cyg_uint16 id = 0;
  786. Jim_Obj *threads = Jim_NewListObj(interp, NULL, 0);
  787. /* Loop over the threads, and generate a table row for
  788. * each.
  789. */
  790. while (cyg_thread_get_next(&thread, &id))
  791. {
  792. Jim_Obj *threadObj = Jim_NewListObj(interp, NULL, 0);
  793. cyg_thread_info info;
  794. char *state_string;
  795. cyg_thread_get_info(thread, id, &info);
  796. if (info.name == NULL)
  797. info.name = "<no name>";
  798. Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
  799. info.name, strlen(info.name)));
  800. /* Translate the state into a string.
  801. */
  802. if (info.state == 0)
  803. state_string = "RUN";
  804. else if (info.state & 0x04)
  805. state_string = "SUSP";
  806. else
  807. switch (info.state & 0x1b)
  808. {
  809. case 0x01:
  810. state_string = "SLEEP";
  811. break;
  812. case 0x02:
  813. state_string = "CNTSLEEP";
  814. break;
  815. case 0x08:
  816. state_string = "CREATE";
  817. break;
  818. case 0x10:
  819. state_string = "EXIT";
  820. break;
  821. default:
  822. state_string = "????";
  823. break;
  824. }
  825. Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
  826. state_string, strlen(state_string)));
  827. Jim_ListAppendElement (interp, threadObj, Jim_NewIntObj(interp, id));
  828. Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, info.set_pri));
  829. Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, info.cur_pri));
  830. Jim_ListAppendElement(interp, threads, threadObj);
  831. }
  832. Jim_SetResult( interp, threads);
  833. return JIM_OK;
  834. }
  835. static int
  836. zylinjtag_Jim_Command_ls(Jim_Interp *interp,
  837. int argc,
  838. Jim_Obj * const *argv)
  839. {
  840. if (argc != 2)
  841. {
  842. Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
  843. return JIM_ERR;
  844. }
  845. char *name = (char*) Jim_GetString(argv[1], NULL);
  846. DIR *dirp = NULL;
  847. dirp = opendir(name);
  848. if (dirp == NULL)
  849. {
  850. return JIM_ERR;
  851. }
  852. Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
  853. for (;;)
  854. {
  855. struct dirent *entry = NULL;
  856. entry = readdir(dirp);
  857. if (entry == NULL)
  858. break;
  859. if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
  860. continue;
  861. Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
  862. }
  863. closedir(dirp);
  864. Jim_SetResult(interp, objPtr);
  865. return JIM_OK;
  866. }
  867. static int
  868. zylinjtag_Jim_Command_getmem(Jim_Interp *interp,
  869. int argc,
  870. Jim_Obj * const *argv)
  871. {
  872. if (argc != 3)
  873. {
  874. Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
  875. return JIM_ERR;
  876. }
  877. long address;
  878. long length;
  879. if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
  880. return JIM_ERR;
  881. if (Jim_GetLong(interp, argv[2], &length) != JIM_OK)
  882. return JIM_ERR;
  883. if (length < 0 && length > (4096 * 1024))
  884. {
  885. Jim_WrongNumArgs(interp, 1, argv, "getmem ?dir?");
  886. return JIM_ERR;
  887. }
  888. void *mem = malloc(length);
  889. if (mem == NULL)
  890. return JIM_ERR;
  891. target_t *target = get_current_target(cmd_ctx);
  892. int retval;
  893. int size = 1;
  894. int count = length;
  895. if ((address % 4 == 0) && (count % 4 == 0))
  896. {
  897. size = 4;
  898. count /= 4;
  899. }
  900. if ((retval = target->type->read_memory(target, address, size, count, mem)) != ERROR_OK)
  901. {
  902. free(mem);
  903. return JIM_ERR;
  904. }
  905. Jim_Obj *objPtr = Jim_NewStringObj(interp, mem, length);
  906. Jim_SetResult(interp, objPtr);
  907. free(mem);
  908. return JIM_OK;
  909. }
  910. static int
  911. zylinjtag_Jim_Command_peek(Jim_Interp *interp,
  912. int argc,
  913. Jim_Obj * const *argv)
  914. {
  915. if (argc != 2)
  916. {
  917. Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
  918. return JIM_ERR;
  919. }
  920. long address;
  921. if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
  922. return JIM_ERR;
  923. int value = *((volatile int *) address);
  924. Jim_SetResult(interp, Jim_NewIntObj(interp, value));
  925. return JIM_OK;
  926. }
  927. static int
  928. zylinjtag_Jim_Command_poke(Jim_Interp *interp,
  929. int argc,
  930. Jim_Obj * const *argv)
  931. {
  932. if (argc != 3)
  933. {
  934. Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
  935. return JIM_ERR;
  936. }
  937. long address;
  938. if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
  939. return JIM_ERR;
  940. long value;
  941. if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
  942. return JIM_ERR;
  943. *((volatile int *) address) = value;
  944. return JIM_OK;
  945. }
  946. static int
  947. zylinjtag_Jim_Command_flash(Jim_Interp *interp,
  948. int argc,
  949. Jim_Obj * const *argv)
  950. {
  951. int retval;
  952. u32 base = 0;
  953. flash_bank_t *t = get_flash_bank_by_num_noprobe(0);
  954. if (t != NULL)
  955. {
  956. base = t->base;
  957. retval = JIM_OK;
  958. } else
  959. {
  960. retval = JIM_ERR;
  961. }
  962. if (retval == JIM_OK)
  963. {
  964. Jim_SetResult(interp, Jim_NewIntObj(interp, base));
  965. }
  966. return retval;
  967. }
  968. static int
  969. zylinjtag_Jim_Command_log(Jim_Interp *interp,
  970. int argc,
  971. Jim_Obj * const *argv)
  972. {
  973. Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
  974. if (logCount >= logSize)
  975. {
  976. Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer+logCount%logSize, logSize-logCount%logSize);
  977. }
  978. Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);
  979. Jim_SetResult(interp, tclOutput);
  980. return JIM_OK;
  981. }
  982. static int
  983. zylinjtag_Jim_Command_reboot(Jim_Interp *interp,
  984. int argc,
  985. Jim_Obj * const *argv)
  986. {
  987. reboot();
  988. return JIM_OK;
  989. }
  990. static int
  991. zylinjtag_Jim_Command_mac(Jim_Interp *interp,
  992. int argc,
  993. Jim_Obj * const *argv)
  994. {
  995. int s;
  996. struct ifreq ifr;
  997. s = socket(AF_INET, SOCK_DGRAM, 0);
  998. if (s >= 0)
  999. {
  1000. strcpy(ifr.ifr_name, "eth0");
  1001. int res;
  1002. res = ioctl(s, SIOCGIFHWADDR, &ifr);
  1003. close(s);
  1004. if (res < 0)
  1005. {
  1006. return JIM_OK;
  1007. }
  1008. }
  1009. Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
  1010. char hwaddr[512];
  1011. sprintf(hwaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
  1012. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[0],
  1013. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[1],
  1014. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[2],
  1015. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[3],
  1016. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[4],
  1017. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[5]);
  1018. Jim_AppendString(httpstate.jim_interp, tclOutput, hwaddr, strlen(hwaddr));
  1019. Jim_SetResult(interp, tclOutput);
  1020. return JIM_OK;
  1021. }
  1022. static int
  1023. zylinjtag_Jim_Command_ip(Jim_Interp *interp,
  1024. int argc,
  1025. Jim_Obj * const *argv)
  1026. {
  1027. Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
  1028. struct ifaddrs *ifa = NULL, *ifp = NULL;
  1029. if (getifaddrs(&ifp) < 0)
  1030. {
  1031. return JIM_ERR;
  1032. }
  1033. for (ifa = ifp; ifa; ifa = ifa->ifa_next)
  1034. {
  1035. char ip[200];
  1036. socklen_t salen;
  1037. if (ifa->ifa_addr->sa_family == AF_INET)
  1038. salen = sizeof(struct sockaddr_in);
  1039. else if (ifa->ifa_addr->sa_family == AF_INET6)
  1040. salen = sizeof(struct sockaddr_in6);
  1041. else
  1042. continue;
  1043. if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
  1044. NI_NUMERICHOST) < 0)
  1045. {
  1046. continue;
  1047. }
  1048. Jim_AppendString(httpstate.jim_interp, tclOutput, ip, strlen(ip));
  1049. break;
  1050. }
  1051. freeifaddrs(ifp);
  1052. Jim_SetResult(interp, tclOutput);
  1053. return JIM_OK;
  1054. }
  1055. extern Jim_Interp *interp;
  1056. static void zylinjtag_startNetwork()
  1057. {
  1058. // Bring TCP/IP up immediately before we're ready to accept commands.
  1059. //
  1060. // That is as soon as a PING responds, we're accepting telnet sessions.
  1061. #if defined(CYGPKG_NET_FREEBSD_STACK)
  1062. phi_init_all_network_interfaces();
  1063. #else
  1064. lwip_init();
  1065. #endif
  1066. if (!eth0_up)
  1067. {
  1068. diag_printf("Network not up and running\n");
  1069. exit(-1);
  1070. }
  1071. #if defined(CYGPKG_NET_FREEBSD_STACK)
  1072. /*start TFTP*/
  1073. tftpd_start(69, &fileops);
  1074. #endif
  1075. cyg_httpd_init_tcl_interpreter();
  1076. interp = httpstate.jim_interp;
  1077. Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log, NULL, NULL);
  1078. Jim_CreateCommand(httpstate.jim_interp, "reboot", zylinjtag_Jim_Command_reboot, NULL, NULL);
  1079. Jim_CreateCommand(httpstate.jim_interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);
  1080. Jim_CreateCommand(httpstate.jim_interp, "zy1000_flash", zylinjtag_Jim_Command_flash, NULL, NULL);
  1081. Jim_CreateCommand(httpstate.jim_interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);
  1082. Jim_CreateCommand(httpstate.jim_interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);
  1083. Jim_CreateCommand(httpstate.jim_interp, "threads", zylinjtag_Jim_Command_threads, NULL, NULL);
  1084. Jim_CreateCommand(httpstate.jim_interp, "getmem", zylinjtag_Jim_Command_getmem, NULL, NULL);
  1085. Jim_CreateCommand(httpstate.jim_interp, "mac", zylinjtag_Jim_Command_mac, NULL, NULL);
  1086. Jim_CreateCommand(httpstate.jim_interp, "ip", zylinjtag_Jim_Command_ip, NULL, NULL);
  1087. Jim_CreateCommand(httpstate.jim_interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
  1088. cyg_httpd_start();
  1089. webRunning = true;
  1090. diag_printf("Web server running\n");
  1091. }
  1092. static bool readPowerDropout()
  1093. {
  1094. cyg_uint32 state;
  1095. // sample and clear power dropout
  1096. HAL_WRITE_UINT32(0x08000010, 0x80);
  1097. HAL_READ_UINT32(0x08000010, state);
  1098. bool powerDropout;
  1099. powerDropout = (state & 0x80) != 0;
  1100. return powerDropout;
  1101. }
  1102. bool readSRST()
  1103. {
  1104. cyg_uint32 state;
  1105. // sample and clear SRST sensing
  1106. HAL_WRITE_UINT32(0x08000010, 0x00000040);
  1107. HAL_READ_UINT32(0x08000010, state);
  1108. bool srstAsserted;
  1109. srstAsserted = (state & 0x40) != 0;
  1110. return srstAsserted;
  1111. }
  1112. // every 300ms we check for reset & powerdropout and issue a "reset halt" if
  1113. // so.
  1114. static int sense_handler(void *priv)
  1115. {
  1116. struct command_context_s *cmd_ctx;
  1117. cmd_ctx = (struct command_context_s *) priv;
  1118. static bool prevSrstAsserted = false;
  1119. static bool prevPowerdropout = false;
  1120. bool powerDropout;
  1121. powerDropout = readPowerDropout();
  1122. bool powerRestored;
  1123. powerRestored = prevPowerdropout && !powerDropout;
  1124. if (powerRestored)
  1125. {
  1126. LOG_USER("Sensed power restore.");
  1127. }
  1128. cyg_tick_count_t current = cyg_current_time();
  1129. static cyg_tick_count_t lastPower = 0;
  1130. bool waitMore = lastPower + 200 > current;
  1131. if (powerDropout && !waitMore)
  1132. {
  1133. LOG_USER("Sensed power dropout.");
  1134. lastPower = current;
  1135. }
  1136. bool srstAsserted = readSRST();
  1137. bool srstDeasserted;
  1138. srstDeasserted = prevSrstAsserted && !srstAsserted;
  1139. static cyg_tick_count_t lastSrst = 0;
  1140. waitMore = lastSrst + 200 > current;
  1141. if (srstDeasserted && !waitMore)
  1142. {
  1143. LOG_USER("Sensed nSRST deasserted");
  1144. lastSrst = current;
  1145. }
  1146. if (!prevSrstAsserted && srstAsserted)
  1147. {
  1148. LOG_USER("Sensed nSRST asserted");
  1149. }
  1150. prevSrstAsserted = srstAsserted;
  1151. prevPowerdropout = powerDropout;
  1152. if (srstDeasserted || powerRestored)
  1153. {
  1154. /* Other than logging the event we can't do anything here.
  1155. * Issuing a reset is a particularly bad idea as we might
  1156. * be inside a reset already.
  1157. */
  1158. }
  1159. return ERROR_OK;
  1160. }
  1161. static void
  1162. print_exception_handler(cyg_addrword_t data, cyg_code_t exception, cyg_addrword_t info)
  1163. {
  1164. writeLog = false;
  1165. serialLog = true;
  1166. char *infoStr = "unknown";
  1167. switch (exception)
  1168. {
  1169. case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:
  1170. infoStr = "undefined instruction";
  1171. break;
  1172. case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:
  1173. infoStr = "software interrupt";
  1174. break;
  1175. case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:
  1176. infoStr = "abort prefetch";
  1177. break;
  1178. case CYGNUM_HAL_VECTOR_ABORT_DATA:
  1179. infoStr = "abort data";
  1180. break;
  1181. default:
  1182. break;
  1183. }
  1184. diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
  1185. diag_printf("Dumping log\n---\n");
  1186. if (logCount >= logSize)
  1187. {
  1188. diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);
  1189. }
  1190. diag_write(logBuffer, writePtr);
  1191. diag_printf("---\nLogdump complete.\n");
  1192. diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
  1193. diag_printf("\n---\nRebooting\n");
  1194. HAL_PLATFORM_RESET();
  1195. }
  1196. static void setHandler(cyg_code_t exception)
  1197. {
  1198. cyg_exception_handler_t *old_handler;
  1199. cyg_addrword_t old_data;
  1200. cyg_exception_set_handler(exception,
  1201. print_exception_handler,
  1202. 0,
  1203. &old_handler,
  1204. &old_data);
  1205. }
  1206. static cyg_thread zylinjtag_uart_thread_object;
  1207. static cyg_handle_t zylinjtag_uart_thread_handle;
  1208. static char uart_stack[4096];
  1209. static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
  1210. static char backwardBuffer[1024];
  1211. static cyg_io_handle_t serial_handle;
  1212. void setNoDelay(int session, int flag)
  1213. {
  1214. #if 1
  1215. // This decreases latency dramatically for e.g. GDB load which
  1216. // does not have a sliding window protocol
  1217. //
  1218. // Can cause *lots* of TCP/IP packets to be sent and it would have
  1219. // to be enabled/disabled on the fly to avoid the CPU being
  1220. // overloaded...
  1221. setsockopt(session, /* socket affected */
  1222. IPPROTO_TCP, /* set option at TCP level */
  1223. TCP_NODELAY, /* name of option */
  1224. (char *) &flag, /* the cast is historical
  1225. cruft */
  1226. sizeof(int)); /* length of option value */
  1227. #endif
  1228. }
  1229. struct
  1230. {
  1231. int req;
  1232. int actual;
  1233. int req2;
  1234. int actual2;
  1235. } tcpipSent[512 * 1024];
  1236. int cur;
  1237. static void
  1238. zylinjtag_uart(cyg_addrword_t data)
  1239. {
  1240. int so_reuseaddr_option = 1;
  1241. int fd;
  1242. if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  1243. {
  1244. LOG_ERROR("error creating socket: %s", strerror(errno));
  1245. exit(-1);
  1246. }
  1247. setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
  1248. struct sockaddr_in sin;
  1249. unsigned int address_size;
  1250. address_size = sizeof(sin);
  1251. memset(&sin, 0, sizeof(sin));
  1252. sin.sin_family = AF_INET;
  1253. sin.sin_addr.s_addr = INADDR_ANY;
  1254. sin.sin_port = htons(5555);
  1255. if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
  1256. {
  1257. LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
  1258. exit(-1);
  1259. }
  1260. if (listen(fd, 1) == -1)
  1261. {
  1262. LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
  1263. exit(-1);
  1264. }
  1265. // socket_nonblock(fd);
  1266. for (;;)
  1267. {
  1268. int session = accept(fd, (struct sockaddr *) &sin, &address_size);
  1269. if (session < 0)
  1270. {
  1271. continue;
  1272. }
  1273. setNoDelay(session, 1);
  1274. int oldopts = fcntl(session, F_GETFL, 0);
  1275. fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
  1276. int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);
  1277. if (serHandle < 0)
  1278. {
  1279. close(session);
  1280. continue;
  1281. }
  1282. start_profile();
  1283. int actual = 0;
  1284. int actual2 = 0;
  1285. int pos, pos2;
  1286. pos = 0;
  1287. pos2 = 0;
  1288. cur = 0;
  1289. for (;;)
  1290. {
  1291. fd_set write_fds;
  1292. fd_set read_fds;
  1293. FD_ZERO(&write_fds);
  1294. FD_ZERO(&read_fds);
  1295. int fd_max = -1;
  1296. FD_SET(session, &read_fds);
  1297. fd_max = session;
  1298. FD_SET(serHandle, &read_fds);
  1299. if (serHandle > fd_max)
  1300. {
  1301. fd_max = serHandle;
  1302. }
  1303. /* Wait... */
  1304. cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
  1305. if ((actual == 0) && (actual2 == 0))
  1306. {
  1307. int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);
  1308. if (retval <= 0)
  1309. {
  1310. break;
  1311. }
  1312. }
  1313. if (actual2 <= 0)
  1314. {
  1315. memset(backwardBuffer, 's', sizeof(backwardBuffer));
  1316. actual2=read(serHandle, backwardBuffer, sizeof(backwardBuffer));
  1317. if (actual2 < 0)
  1318. {
  1319. if (errno != EAGAIN)
  1320. {
  1321. goto closeSession;
  1322. }
  1323. actual2 = 0;
  1324. }
  1325. pos2 = 0;
  1326. }
  1327. int x = actual2;
  1328. int y = 0;
  1329. if (actual2 > 0)
  1330. {
  1331. int written = write(session, backwardBuffer + pos2, actual2);
  1332. if (written <= 0)
  1333. goto closeSession;
  1334. actual2 -= written;
  1335. pos2 += written;
  1336. y = written;
  1337. }
  1338. if (FD_ISSET(session, &read_fds)&&(sizeof(forwardBuffer)>actual))
  1339. {
  1340. // NB! Here it is important that we empty the TCP/IP read buffer
  1341. // to make transmission tick right
  1342. memmove(forwardBuffer, forwardBuffer + pos, actual);
  1343. pos = 0;
  1344. int t;
  1345. // this will block if there is no data at all
  1346. t=read_socket(session, forwardBuffer+actual, sizeof(forwardBuffer)-actual);
  1347. if (t <= 0)
  1348. {
  1349. goto closeSession;
  1350. }
  1351. actual += t;
  1352. }
  1353. int x2 = actual;
  1354. int y2 = 0;
  1355. if (actual > 0)
  1356. {
  1357. /* Do not put things into the serial buffer if it has something to send
  1358. * as that can cause a single byte to be sent at the time.
  1359. *
  1360. *
  1361. */
  1362. int written = write(serHandle, forwardBuffer + pos, actual);
  1363. if (written < 0)
  1364. {
  1365. if (errno != EAGAIN)
  1366. {
  1367. goto closeSession;
  1368. }
  1369. // The serial buffer is full
  1370. written = 0;
  1371. } else
  1372. {
  1373. actual -= written;
  1374. pos += written;
  1375. }
  1376. y2 = written;
  1377. }
  1378. if (cur < 1024)
  1379. {
  1380. tcpipSent[cur].req = x;
  1381. tcpipSent[cur].actual = y;
  1382. tcpipSent[cur].req2 = x2;
  1383. tcpipSent[cur].actual2 = y2;
  1384. cur++;
  1385. }
  1386. }
  1387. closeSession:
  1388. close(session);
  1389. close(serHandle);
  1390. int i;
  1391. for (i = 0; i < 1024; i++)
  1392. {
  1393. diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual, tcpipSent[i].req2, tcpipSent[i].actual2);
  1394. }
  1395. }
  1396. close(fd);
  1397. }
  1398. void startUart(void)
  1399. {
  1400. cyg_thread_create(1,
  1401. zylinjtag_uart,
  1402. (cyg_addrword_t)0,
  1403. "uart thread",
  1404. (void *)uart_stack,
  1405. sizeof(uart_stack),
  1406. &zylinjtag_uart_thread_handle,
  1407. &zylinjtag_uart_thread_object);
  1408. cyg_thread_set_priority(zylinjtag_uart_thread_handle, 1); // low priority as it sits in a busy loop
  1409. cyg_thread_resume(zylinjtag_uart_thread_handle);
  1410. }
  1411. int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  1412. {
  1413. if (argc != 1)
  1414. {
  1415. command_print(cmd_ctx, "usage: uart <baudrate>");
  1416. return ERROR_INVALID_ARGUMENTS;
  1417. }
  1418. int baud = atol(args[0]);
  1419. switch (baud)
  1420. {
  1421. case 9600:
  1422. baud = CYGNUM_SERIAL_BAUD_9600;
  1423. break;
  1424. case 19200:
  1425. baud = CYGNUM_SERIAL_BAUD_19200;
  1426. break;
  1427. case 38400:
  1428. baud = CYGNUM_SERIAL_BAUD_38400;
  1429. break;
  1430. case 57600:
  1431. baud = CYGNUM_SERIAL_BAUD_57600;
  1432. break;
  1433. case 115200:
  1434. baud = CYGNUM_SERIAL_BAUD_115200;
  1435. break;
  1436. case 230400:
  1437. baud = CYGNUM_SERIAL_BAUD_230400;
  1438. break;
  1439. default:
  1440. command_print(cmd_ctx, "unsupported baudrate");
  1441. return ERROR_INVALID_ARGUMENTS;
  1442. }
  1443. cyg_serial_info_t buf;
  1444. cyg_uint32 len = 1;
  1445. //get existing serial configuration
  1446. len = sizeof(cyg_serial_info_t);
  1447. int err;
  1448. err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buf, &len);
  1449. err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &buf, &len);
  1450. if (err != ENOERR)
  1451. {
  1452. command_print(cmd_ctx, "Failed to get serial port settings %d", err);
  1453. return ERROR_OK;
  1454. }
  1455. buf.baud = baud;
  1456. err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf, &len);
  1457. if (err != ENOERR)
  1458. {
  1459. command_print(cmd_ctx, "Failed to set serial port settings %d", err);
  1460. return ERROR_OK;
  1461. }
  1462. return ERROR_OK;
  1463. }
  1464. bool logAllToSerial = false;
  1465. /* boolean parameter stored on config */
  1466. bool boolParam(char *var)
  1467. {
  1468. bool result = false;
  1469. char *name = alloc_printf(ZYLIN_CONFIG_DIR "/%s", var);
  1470. if (name == NULL)
  1471. return result;
  1472. void *data;
  1473. int len;
  1474. if (loadFile(name, &data, &len) == ERROR_OK)
  1475. {
  1476. if (len > 1)
  1477. len = 1;
  1478. result = strncmp((char *) data, "1", len) == 0;
  1479. free(data);
  1480. }
  1481. free(name);
  1482. return result;
  1483. }
  1484. command_context_t *setup_command_handler();
  1485. int add_default_dirs(void)
  1486. {
  1487. add_script_search_dir(ZYLIN_CONFIG_DIR);
  1488. add_script_search_dir("/rom/lib/openocd");
  1489. add_script_search_dir("/rom");
  1490. return ERROR_OK;
  1491. }
  1492. int main(int argc, char *argv[])
  1493. {
  1494. setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION);
  1495. setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH);
  1496. setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA);
  1497. int err;
  1498. err = cyg_io_lookup("/dev/ser0", &serial_handle);
  1499. if (err != ENOERR)
  1500. {
  1501. diag_printf("/dev/ser0 not found\n");
  1502. reboot();
  1503. }
  1504. setPower(true); // on by default
  1505. atexit(keep_webserver);
  1506. err = mount("", "/ram", "ramfs");
  1507. if (err < 0)
  1508. {
  1509. diag_printf("unable to mount ramfs\n");
  1510. }
  1511. chdir("/ram");
  1512. char address[16];
  1513. sprintf(address, "%p", &filedata[0]);
  1514. err = mount(address, "/rom", "romfs");
  1515. if (err < 0)
  1516. {
  1517. diag_printf("unable to mount /rom\n");
  1518. }
  1519. err = mount("", "/log", "logfs");
  1520. if (err < 0)
  1521. {
  1522. diag_printf("unable to mount logfs\n");
  1523. }
  1524. err = mount("", "/tftp", "tftpfs");
  1525. if (err < 0)
  1526. {
  1527. diag_printf("unable to mount logfs\n");
  1528. }
  1529. log = fopen("/log/log", "w");
  1530. if (log == NULL)
  1531. {
  1532. diag_printf("Could not open log file /ram/log\n");
  1533. exit(-1);
  1534. }
  1535. diag_init_putc(_zylinjtag_diag_write_char);
  1536. // We want this in the log.
  1537. diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
  1538. diag_printf("%s\n", ZYLIN_OPENOCD_VERSION);
  1539. copydir("/rom/");
  1540. err = mount("/dev/flash1", "/config", "jffs2");
  1541. if (err < 0)
  1542. {
  1543. diag_printf("unable to mount jffs\n");
  1544. }
  1545. mkdir(ZYLIN_CONFIG_DIR, 0777);
  1546. mkdir(ZYLIN_CONFIG_DIR "/target", 0777);
  1547. mkdir(ZYLIN_CONFIG_DIR "/event", 0777);
  1548. logAllToSerial = boolParam("logserial");
  1549. // We need the network & web server in case there is something wrong with
  1550. // the config files that invoke exit()
  1551. zylinjtag_startNetwork();
  1552. /* we're going to access the jim interpreter from here on... */
  1553. openocd_sleep_postlude();
  1554. startUart();
  1555. add_default_dirs();
  1556. /* initialize commandline interface */
  1557. command_context_t *cmd_ctx;
  1558. cmd_ctx = setup_command_handler();
  1559. command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
  1560. command_context_mode(cmd_ctx, COMMAND_CONFIG);
  1561. register_command(cmd_ctx, NULL, "zy1000_version", handle_zy1000_version_command,
  1562. COMMAND_EXEC, "show zy1000 version numbers");
  1563. register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
  1564. "rm <filname>");
  1565. register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
  1566. "same args as load_image, image stored in memory");
  1567. register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
  1568. "loads active fast load image to current target");
  1569. register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
  1570. "cat <filname>");
  1571. register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
  1572. "trunc <filname>");
  1573. register_command(cmd_ctx, NULL, "append_file", handle_append_command,
  1574. COMMAND_ANY, "append <filname>");
  1575. register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
  1576. "power <on/off> - turn power switch to target on/off. No arguments - print status.");
  1577. register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
  1578. COMMAND_ANY, "meminfo");
  1579. register_command(cmd_ctx, NULL, "cp", handle_cp_command,
  1580. COMMAND_ANY, "cp <from> <to>");
  1581. #ifdef CYGPKG_PROFILE_GPROF
  1582. register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,
  1583. COMMAND_ANY, NULL);
  1584. #endif
  1585. register_command(cmd_ctx, NULL, "uart", handle_uart_command,
  1586. COMMAND_ANY, "uart <baud> - forward uart on port 5555");
  1587. int errVal;
  1588. errVal = log_init(cmd_ctx);
  1589. if (errVal != ERROR_OK)
  1590. {
  1591. diag_printf("log_init() failed %d\n", errVal);
  1592. exit(-1);
  1593. }
  1594. set_log_output(cmd_ctx, log);
  1595. LOG_DEBUG("log init complete");
  1596. // diag_printf("Executing config files\n");
  1597. if (logAllToSerial)
  1598. {
  1599. diag_printf(ZYLIN_CONFIG_DIR "/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
  1600. command_run_line(cmd_ctx, "debug_level 3");
  1601. }
  1602. zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
  1603. target_register_timer_callback(sense_handler, 200, 1, cmd_ctx);
  1604. // FIX!!! Yuk!
  1605. // diag_printf() is really invoked from many more places than we trust it
  1606. // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
  1607. //
  1608. // Disabling it here is safe and gives us enough logged debug output for now. Crossing
  1609. // fingers that it doesn't cause any crashes.
  1610. diag_printf("Init complete, GDB & telnet servers launched.\n");
  1611. command_set_output_handler(cmd_ctx, zy1000_configuration_output_handler_log, NULL);
  1612. if (!logAllToSerial)
  1613. {
  1614. serialLog = false;
  1615. }
  1616. /* handle network connections */
  1617. server_loop(cmd_ctx);
  1618. openocd_sleep_prelude();
  1619. /* shut server down */
  1620. server_quit();
  1621. /* free commandline interface */
  1622. command_done(cmd_ctx);
  1623. umount("/config");
  1624. exit(0);
  1625. for (;;);
  1626. }
  1627. cyg_int32
  1628. cyg_httpd_exec_cgi_tcl(char *file_name);
  1629. cyg_int32 homeForm(CYG_HTTPD_STATE *p)
  1630. {
  1631. cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
  1632. return 0;
  1633. }
  1634. CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);
  1635. CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label, "text", "text/plain");
  1636. CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream");
  1637. #include <pkgconf/system.h>
  1638. #include <pkgconf/hal.h>
  1639. #include <pkgconf/kernel.h>
  1640. #include <pkgconf/io_fileio.h>
  1641. #include <pkgconf/fs_rom.h>
  1642. #include <cyg/kernel/ktypes.h> // base kernel types
  1643. #include <cyg/infra/cyg_trac.h> // tracing macros
  1644. #include <cyg/infra/cyg_ass.h> // assertion macros
  1645. #include <unistd.h>
  1646. #include <sys/types.h>
  1647. #include <fcntl.h>
  1648. #include <sys/stat.h>
  1649. #include <errno.h>
  1650. #include <dirent.h>
  1651. #include <stdarg.h>
  1652. #include <stdio.h>
  1653. #include <stdlib.h>
  1654. #include <string.h>
  1655. #include <cyg/fileio/fileio.h>
  1656. #include <cyg/kernel/kapi.h>
  1657. #include <cyg/infra/diag.h>
  1658. //==========================================================================
  1659. // Eventually we want to eXecute In Place from the ROM in a protected
  1660. // environment, so we'll need executables to be aligned to a boundary
  1661. // suitable for MMU protection. A suitable boundary would be the 4k
  1662. // boundary in all the CPU architectures I am currently aware of.
  1663. // Forward definitions
  1664. // Filesystem operations
  1665. static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
  1666. static int tftpfs_umount(cyg_mtab_entry *mte);
  1667. static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  1668. int mode, cyg_file *fte);
  1669. static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
  1670. static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
  1671. // File operations
  1672. static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
  1673. static int tftpfs_fo_close(struct CYG_FILE_TAG *fp);
  1674. static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence);
  1675. //==========================================================================
  1676. // Filesystem table entries
  1677. // -------------------------------------------------------------------------
  1678. // Fstab entry.
  1679. // This defines the entry in the filesystem table.
  1680. // For simplicity we use _FILESYSTEM synchronization for all accesses since
  1681. // we should never block in any filesystem operations.
  1682. #if 1
  1683. FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0,
  1684. CYG_SYNCMODE_NONE,
  1685. tftpfs_mount,
  1686. tftpfs_umount,
  1687. tftpfs_open,
  1688. (cyg_fsop_unlink *)cyg_fileio_erofs,
  1689. (cyg_fsop_mkdir *)cyg_fileio_erofs,
  1690. (cyg_fsop_rmdir *)cyg_fileio_erofs,
  1691. (cyg_fsop_rename *)cyg_fileio_erofs,
  1692. (cyg_fsop_link *)cyg_fileio_erofs,
  1693. (cyg_fsop_opendir *)cyg_fileio_erofs,
  1694. (cyg_fsop_chdir *)cyg_fileio_erofs,
  1695. (cyg_fsop_stat *)cyg_fileio_erofs,
  1696. (cyg_fsop_getinfo *)cyg_fileio_erofs,
  1697. (cyg_fsop_setinfo *)cyg_fileio_erofs);
  1698. #endif
  1699. // -------------------------------------------------------------------------
  1700. // mtab entry.
  1701. // This defines a single ROMFS loaded into ROM at the configured address
  1702. //
  1703. // MTAB_ENTRY( rom_mte, // structure name
  1704. // "/rom", // mount point
  1705. // "romfs", // FIlesystem type
  1706. // "", // hardware device
  1707. // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
  1708. // );
  1709. // -------------------------------------------------------------------------
  1710. // File operations.
  1711. // This set of file operations are used for normal open files.
  1712. static cyg_fileops tftpfs_fileops =
  1713. {
  1714. tftpfs_fo_read,
  1715. tftpfs_fo_write,
  1716. tftpfs_fo_lseek,
  1717. (cyg_fileop_ioctl *)cyg_fileio_erofs,
  1718. cyg_fileio_seltrue,
  1719. tftpfs_fo_fsync,
  1720. tftpfs_fo_close,
  1721. (cyg_fileop_fstat *) cyg_fileio_erofs,
  1722. (cyg_fileop_getinfo *) cyg_fileio_erofs,
  1723. (cyg_fileop_setinfo *)cyg_fileio_erofs,
  1724. };
  1725. // -------------------------------------------------------------------------
  1726. // tftpfs_mount()
  1727. // Process a mount request. This mainly finds root for the
  1728. // filesystem.
  1729. static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
  1730. {
  1731. return ENOERR;
  1732. }
  1733. static int tftpfs_umount(cyg_mtab_entry *mte)
  1734. {
  1735. return ENOERR;
  1736. }
  1737. struct Tftp
  1738. {
  1739. int write;
  1740. int readFile;
  1741. cyg_uint8 *mem;
  1742. int actual;
  1743. char *server;
  1744. char *file;
  1745. };
  1746. static void freeTftp(struct Tftp *t)
  1747. {
  1748. if (t == NULL)
  1749. return;
  1750. if (t->mem)
  1751. free(t->mem);
  1752. if (t->server)
  1753. free(t->server);
  1754. if (t->file)
  1755. free(t->file);
  1756. free(t);
  1757. }
  1758. static const int tftpMaxSize = 8192 * 1024;
  1759. static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  1760. int mode, cyg_file *file)
  1761. {
  1762. struct Tftp *tftp;
  1763. tftp = malloc(sizeof(struct Tftp));
  1764. if (tftp == NULL)
  1765. return EMFILE;
  1766. memset(tftp, 0, sizeof(struct Tftp));
  1767. file->f_flag |= mode & CYG_FILE_MODE_MASK;
  1768. file->f_type = CYG_FILE_TYPE_FILE;
  1769. file->f_ops = &tftpfs_fileops;
  1770. file->f_offset = 0;
  1771. file->f_data = 0;
  1772. file->f_xops = 0;
  1773. tftp->mem = malloc(tftpMaxSize);
  1774. if (tftp->mem == NULL)
  1775. {
  1776. freeTftp(tftp);
  1777. return EMFILE;
  1778. }
  1779. char *server = strchr(name, '/');
  1780. if (server == NULL)
  1781. {
  1782. freeTftp(tftp);
  1783. return EMFILE;
  1784. }
  1785. tftp->server = malloc(server - name + 1);
  1786. if (tftp->server == NULL)
  1787. {
  1788. freeTftp(tftp);
  1789. return EMFILE;
  1790. }
  1791. strncpy(tftp->server, name, server - name);
  1792. tftp->server[server - name] = 0;
  1793. tftp->file = strdup(server + 1);
  1794. if (tftp->file == NULL)
  1795. {
  1796. freeTftp(tftp);
  1797. return EMFILE;
  1798. }
  1799. file->f_data = (CYG_ADDRWORD) tftp;
  1800. return ENOERR;
  1801. }
  1802. static int fetchTftp(struct Tftp *tftp)
  1803. {
  1804. if (!tftp->readFile)
  1805. {
  1806. int err;
  1807. tftp->actual = tftp_client_get( tftp->file, tftp->server, 0, tftp->mem, tftpMaxSize, TFTP_OCTET, &err);
  1808. if (tftp->actual < 0)
  1809. {
  1810. return EMFILE;
  1811. }
  1812. tftp->readFile = 1;
  1813. }
  1814. return ENOERR;
  1815. }
  1816. // -------------------------------------------------------------------------
  1817. // tftpfs_fo_write()
  1818. // Read data from file.
  1819. static int
  1820. tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
  1821. {
  1822. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1823. if (fetchTftp(tftp) != ENOERR)
  1824. return EMFILE;
  1825. int i;
  1826. off_t pos = fp->f_offset;
  1827. int resid = 0;
  1828. for (i = 0; i < uio->uio_iovcnt; i++)
  1829. {
  1830. cyg_iovec *iov = &uio->uio_iov[i];
  1831. char *buf = (char *) iov->iov_base;
  1832. off_t len = iov->iov_len;
  1833. if (len + pos > tftp->actual)
  1834. {
  1835. len = tftp->actual - pos;
  1836. }
  1837. resid += iov->iov_len - len;
  1838. memcpy(buf, tftp->mem + pos, len);
  1839. pos += len;
  1840. }
  1841. uio->uio_resid = resid;
  1842. fp->f_offset = pos;
  1843. return ENOERR;
  1844. }
  1845. static int
  1846. tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
  1847. {
  1848. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1849. int i;
  1850. off_t pos = fp->f_offset;
  1851. int resid = 0;
  1852. for (i = 0; i < uio->uio_iovcnt; i++)
  1853. {
  1854. cyg_iovec *iov = &uio->uio_iov[i];
  1855. char *buf = (char *) iov->iov_base;
  1856. off_t len = iov->iov_len;
  1857. if (len + pos > tftpMaxSize)
  1858. {
  1859. len = tftpMaxSize - pos;
  1860. }
  1861. resid += iov->iov_len - len;
  1862. memcpy(tftp->mem + pos, buf, len);
  1863. pos += len;
  1864. }
  1865. uio->uio_resid = resid;
  1866. fp->f_offset = pos;
  1867. tftp->write = 1;
  1868. return ENOERR;
  1869. }
  1870. static int
  1871. tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
  1872. {
  1873. int error = ENOERR;
  1874. return error;
  1875. }
  1876. // -------------------------------------------------------------------------
  1877. // romfs_fo_close()
  1878. // Close a file. We just clear out the data pointer.
  1879. static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)
  1880. {
  1881. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1882. int error = ENOERR;
  1883. if (tftp->write)
  1884. {
  1885. tftp_client_put( tftp->file, tftp->server, 0, tftp->mem, fp->f_offset, TFTP_OCTET, &error);
  1886. }
  1887. freeTftp(tftp);
  1888. fp->f_data = 0;
  1889. return error;
  1890. }
  1891. // -------------------------------------------------------------------------
  1892. // romfs_fo_lseek()
  1893. // Seek to a new file position.
  1894. static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)
  1895. {
  1896. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1897. off_t pos = *apos;
  1898. if (fetchTftp(tftp) != ENOERR)
  1899. return EMFILE;
  1900. switch (whence)
  1901. {
  1902. case SEEK_SET:
  1903. // Pos is already where we want to be.
  1904. break;
  1905. case SEEK_CUR:
  1906. // Add pos to current offset.
  1907. pos += fp->f_offset;
  1908. break;
  1909. case SEEK_END:
  1910. // Add pos to file size.
  1911. pos += tftp->actual;
  1912. break;
  1913. default:
  1914. return EINVAL;
  1915. }
  1916. // Check that pos is still within current file size, or at the
  1917. // very end.
  1918. if (pos < 0 || pos > tftp->actual)
  1919. return EINVAL;
  1920. // All OK, set fp offset and return new position.
  1921. *apos = fp->f_offset = pos;
  1922. return ENOERR;
  1923. }
  1924. void usleep(int us)
  1925. {
  1926. if (us > 10000)
  1927. cyg_thread_delay(us / 10000 + 1);
  1928. else
  1929. HAL_DELAY_US(us);
  1930. }
  1931. // Chunked version.
  1932. cyg_int32
  1933. show_log_entry(CYG_HTTPD_STATE *phttpstate)
  1934. {
  1935. cyg_httpd_start_chunked("text");
  1936. if (logCount >= logSize)
  1937. {
  1938. cyg_httpd_write_chunked(logBuffer+logCount%logSize, logSize-logCount%logSize);
  1939. }
  1940. cyg_httpd_write_chunked(logBuffer, writePtr);
  1941. cyg_httpd_end_chunked();
  1942. return -1;
  1943. }
  1944. CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);
  1945. // Filesystem operations
  1946. static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
  1947. static int logfs_umount(cyg_mtab_entry *mte);
  1948. static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  1949. int mode, cyg_file *fte);
  1950. static int
  1951. logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
  1952. // File operations
  1953. static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
  1954. static int logfs_fo_close(struct CYG_FILE_TAG *fp);
  1955. //==========================================================================
  1956. // Filesystem table entries
  1957. // -------------------------------------------------------------------------
  1958. // Fstab entry.
  1959. // This defines the entry in the filesystem table.
  1960. // For simplicity we use _FILESYSTEM synchronization for all accesses since
  1961. // we should never block in any filesystem operations.
  1962. FSTAB_ENTRY( logfs_fste, "logfs", 0,
  1963. CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,
  1964. logfs_mount,
  1965. logfs_umount,
  1966. logfs_open,
  1967. (cyg_fsop_unlink *)cyg_fileio_erofs,
  1968. (cyg_fsop_mkdir *)cyg_fileio_erofs,
  1969. (cyg_fsop_rmdir *)cyg_fileio_erofs,
  1970. (cyg_fsop_rename *)cyg_fileio_erofs,
  1971. (cyg_fsop_link *)cyg_fileio_erofs,
  1972. (cyg_fsop_opendir *)cyg_fileio_erofs,
  1973. (cyg_fsop_chdir *)cyg_fileio_erofs,
  1974. (cyg_fsop_stat *)cyg_fileio_erofs,
  1975. (cyg_fsop_getinfo *)cyg_fileio_erofs,
  1976. (cyg_fsop_setinfo *)cyg_fileio_erofs);
  1977. // -------------------------------------------------------------------------
  1978. // File operations.
  1979. // This set of file operations are used for normal open files.
  1980. static cyg_fileops logfs_fileops =
  1981. {
  1982. (cyg_fileop_read *)cyg_fileio_erofs,
  1983. (cyg_fileop_write *)logfs_fo_write,
  1984. (cyg_fileop_lseek *) cyg_fileio_erofs,
  1985. (cyg_fileop_ioctl *)cyg_fileio_erofs,
  1986. cyg_fileio_seltrue,
  1987. logfs_fo_fsync,
  1988. logfs_fo_close,
  1989. (cyg_fileop_fstat *)cyg_fileio_erofs,
  1990. (cyg_fileop_getinfo *) cyg_fileio_erofs,
  1991. (cyg_fileop_setinfo *)cyg_fileio_erofs,
  1992. };
  1993. // -------------------------------------------------------------------------
  1994. // logfs_mount()
  1995. // Process a mount request. This mainly finds root for the
  1996. // filesystem.
  1997. static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
  1998. {
  1999. return ENOERR;
  2000. }
  2001. static int logfs_umount(cyg_mtab_entry *mte)
  2002. {
  2003. return ENOERR;
  2004. }
  2005. static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  2006. int mode, cyg_file *file)
  2007. {
  2008. file->f_flag |= mode & CYG_FILE_MODE_MASK;
  2009. file->f_type = CYG_FILE_TYPE_FILE;
  2010. file->f_ops = &logfs_fileops;
  2011. file->f_offset = 0;
  2012. file->f_data = 0;
  2013. file->f_xops = 0;
  2014. return ENOERR;
  2015. }
  2016. // -------------------------------------------------------------------------
  2017. // logfs_fo_write()
  2018. // Write data to file.
  2019. static int
  2020. logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
  2021. {
  2022. int i;
  2023. for (i = 0; i < uio->uio_iovcnt; i++)
  2024. {
  2025. cyg_iovec *iov = &uio->uio_iov[i];
  2026. char *buf = (char *) iov->iov_base;
  2027. off_t len = iov->iov_len;
  2028. diag_write(buf, len);
  2029. }
  2030. uio->uio_resid = 0;
  2031. return ENOERR;
  2032. }
  2033. static int
  2034. logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
  2035. {
  2036. return ENOERR;
  2037. }
  2038. // -------------------------------------------------------------------------
  2039. // romfs_fo_close()
  2040. // Close a file. We just clear out the data pointer.
  2041. static int logfs_fo_close(struct CYG_FILE_TAG *fp)
  2042. {
  2043. return ENOERR;
  2044. }