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.
 
 
 
 
 
 

1631 lines
38 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007-2009 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 <helper/types.h>
  23. #include <jtag/jtag.h>
  24. #include <helper/ioutil.h>
  25. #include <helper/configuration.h>
  26. #include <server/server.h>
  27. #include <server/telnet_server.h>
  28. #include <server/gdb_server.h>
  29. #include <openocd.h>
  30. #include <helper/time_support.h>
  31. #include <sys/time.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include <errno.h>
  37. #include <cyg/io/flash.h>
  38. #include <pkgconf/fs_jffs2.h> // Address of JFFS2
  39. #include <network.h>
  40. #include <fcntl.h>
  41. #include <sys/stat.h>
  42. #include <cyg/fileio/fileio.h>
  43. #include <dirent.h>
  44. #include <cyg/athttpd/http.h>
  45. #include <cyg/athttpd/socket.h>
  46. #include <cyg/athttpd/handler.h>
  47. #include <cyg/athttpd/cgi.h>
  48. #include <cyg/athttpd/forms.h>
  49. #include <cyg/discover/discover.h>
  50. #include <cyg/io/io.h>
  51. #include <cyg/io/serialio.h>
  52. #include <netinet/tcp.h>
  53. #include <cyg/hal/hal_diag.h>
  54. #include "rom.h"
  55. #ifdef CYGPKG_HAL_NIOS2
  56. #define ZY1000_SER_DEV "/dev/uart_0"
  57. #else
  58. #define ZY1000_SER_DEV "/dev/ser0"
  59. #endif
  60. #define MAX_IFS 64
  61. #if defined(CYGPKG_NET_FREEBSD_STACK)
  62. #include <tftp_support.h>
  63. /* posix compatibility broken*/
  64. struct tftpd_fileops fileops =
  65. {
  66. (int (*)(const char *, int))open,
  67. close,
  68. (int (*)(int, const void *, int))write,
  69. (int (*)(int, void *, int))read
  70. };
  71. #endif
  72. void diag_write(char *buf, int len)
  73. {
  74. int j;
  75. for (j = 0; j < len; j++)
  76. {
  77. diag_printf("%c", buf[j]);
  78. }
  79. }
  80. static bool serialLog = true;
  81. static bool writeLog = true;
  82. char hwaddr[512];
  83. extern struct flash_driver *flash_drivers[];
  84. extern struct target_type *target_types[];
  85. #ifdef CYGPKG_PROFILE_GPROF
  86. #include <cyg/profile/profile.h>
  87. extern char _stext, _etext; // Defined by the linker
  88. static char *start_of_code=&_stext;
  89. static char *end_of_code=&_etext;
  90. void start_profile(void)
  91. {
  92. // This starts up the system-wide profiling, gathering
  93. // profile information on all of the code, with a 16 byte
  94. // "bucket" size, at a rate of 100us/profile hit.
  95. // Note: a bucket size of 16 will give pretty good function
  96. // resolution. Much smaller and the buffer becomes
  97. // much too large for very little gain.
  98. // Note: a timer period of 100us is also a reasonable
  99. // compromise. Any smaller and the overhead of
  100. // handling the timter (profile) interrupt could
  101. // swamp the system. A fast processor might get
  102. // by with a smaller value, but a slow one could
  103. // even be swamped by this value. If the value is
  104. // too large, the usefulness of the profile is reduced.
  105. // no more interrupts than 1/10ms.
  106. //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
  107. // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
  108. profile_on(start_of_code, end_of_code, 16, 10000); // Nios DRAM
  109. }
  110. #endif
  111. static FILE *log;
  112. static char reboot_stack[2048];
  113. static void zylinjtag_reboot(cyg_addrword_t data)
  114. {
  115. serialLog = true;
  116. diag_printf("Rebooting in 500 ticks..\n");
  117. cyg_thread_delay(500);
  118. diag_printf("Unmounting /config..\n");
  119. umount("/config");
  120. diag_printf("Rebooting..\n");
  121. HAL_PLATFORM_RESET();
  122. }
  123. static cyg_thread zylinjtag_thread_object;
  124. static cyg_handle_t zylinjtag_thread_handle;
  125. void reboot(void)
  126. {
  127. cyg_thread_create(1, zylinjtag_reboot, (cyg_addrword_t) 0, "reboot Thread",
  128. (void *) reboot_stack, sizeof(reboot_stack),
  129. &zylinjtag_thread_handle, &zylinjtag_thread_object);
  130. cyg_thread_resume(zylinjtag_thread_handle);
  131. }
  132. static char zylinjtag_reboot_port_stack[2048];
  133. static cyg_thread zylinjtag_reboot_port_thread_object;
  134. static cyg_handle_t zylinjtag_reboot_port_thread_handle;
  135. static void zylinjtag_reboot_port_task(cyg_addrword_t data)
  136. {
  137. int so_reuseaddr_option = 1;
  138. int fd;
  139. if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  140. {
  141. LOG_ERROR("error creating socket: %s", strerror(errno));
  142. exit(-1);
  143. }
  144. setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option,
  145. sizeof(int));
  146. struct sockaddr_in sin;
  147. unsigned int address_size;
  148. address_size = sizeof(sin);
  149. memset(&sin, 0, sizeof(sin));
  150. sin.sin_family = AF_INET;
  151. sin.sin_addr.s_addr = INADDR_ANY;
  152. sin.sin_port = htons(1234);
  153. if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
  154. {
  155. LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
  156. exit(-1);
  157. }
  158. if (listen(fd, 1) == -1)
  159. {
  160. LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
  161. exit(-1);
  162. }
  163. // socket_nonblock(fd);
  164. accept(fd, (struct sockaddr *) &sin, &address_size);
  165. diag_printf("Got reboot signal on port 1234");
  166. reboot();
  167. }
  168. void reboot_port(void)
  169. {
  170. cyg_thread_create(1, zylinjtag_reboot_port_task, (cyg_addrword_t) 0, "wait for reboot signal on port 1234",
  171. (void *) zylinjtag_reboot_port_stack, sizeof(zylinjtag_reboot_port_stack),
  172. &zylinjtag_reboot_port_thread_handle, &zylinjtag_reboot_port_thread_object);
  173. cyg_thread_resume(zylinjtag_reboot_port_thread_handle);
  174. }
  175. int configuration_output_handler(struct command_context *context,
  176. const char* line)
  177. {
  178. diag_printf("%s", line);
  179. return ERROR_OK;
  180. }
  181. int zy1000_configuration_output_handler_log(struct command_context *context,
  182. const char* line)
  183. {
  184. LOG_USER_N("%s", line);
  185. return ERROR_OK;
  186. }
  187. #ifdef CYGPKG_PROFILE_GPROF
  188. //extern int64_t totaltime;
  189. static int zylinjtag_Jim_Command_profile(Jim_Interp *interp, int argc,
  190. Jim_Obj * const *argv)
  191. {
  192. if ((argc == 2) && (strcmp(Jim_GetString(argv[1], NULL), "stats")==0))
  193. {
  194. // profile_off();
  195. //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
  196. } else
  197. {
  198. LOG_USER("Profiling started");
  199. start_profile();
  200. //totaltime = 0;
  201. }
  202. return ERROR_OK;
  203. }
  204. #endif
  205. externC void phi_init_all_network_interfaces(void);
  206. struct command_context *cmd_ctx;
  207. static bool webRunning = false;
  208. void keep_webserver(void)
  209. {
  210. // Target initialisation is only attempted at startup, so we sleep forever and
  211. // let the http server bail us out(i.e. get config files set up).
  212. diag_printf("OpenOCD has invoked exit().\n"
  213. "Use web server to correct any configuration settings and reboot.\n");
  214. if (!webRunning)
  215. reboot();
  216. // exit() will terminate the current thread and we we'll then sleep eternally or
  217. // we'll have a reboot scheduled.
  218. }
  219. extern void printDccChar(char c);
  220. static char logBuffer[128 * 1024];
  221. static const int logSize = sizeof(logBuffer);
  222. int writePtr = 0;
  223. int logCount = 0;
  224. void _zylinjtag_diag_write_char(char c, void **param)
  225. {
  226. if (writeLog)
  227. {
  228. logBuffer[writePtr] = c;
  229. writePtr = (writePtr + 1) % logSize;
  230. logCount++;
  231. }
  232. if (serialLog)
  233. {
  234. if (c == '\n')
  235. {
  236. HAL_DIAG_WRITE_CHAR('\r');
  237. }
  238. HAL_DIAG_WRITE_CHAR(c);
  239. }
  240. #ifdef CYGPKG_HAL_ZYLIN_PHI
  241. printDccChar(c);
  242. #endif
  243. }
  244. void copyfile(char *name2, char *name1);
  245. void copydir(char *name, char *destdir);
  246. #if 0
  247. MTAB_ENTRY(romfs_mte1,
  248. "/rom",
  249. "romfs",
  250. "",
  251. (CYG_ADDRWORD) &filedata[0]);
  252. #endif
  253. void openocd_sleep_prelude(void)
  254. {
  255. cyg_mutex_unlock(&httpstate.jim_lock);
  256. }
  257. void openocd_sleep_postlude(void)
  258. {
  259. cyg_mutex_lock(&httpstate.jim_lock);
  260. }
  261. void format(void)
  262. {
  263. #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
  264. diag_printf("Formatting JFFS2...\n");
  265. cyg_io_handle_t handle;
  266. Cyg_ErrNo err;
  267. err = cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, &handle);
  268. if (err != ENOERR)
  269. {
  270. diag_printf("Flash Error cyg_io_lookup: %d\n", err);
  271. reboot();
  272. }
  273. cyg_uint32 len;
  274. cyg_io_flash_getconfig_devsize_t ds;
  275. len = sizeof(ds);
  276. err = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_FLASH_DEVSIZE, &ds, &len);
  277. if (err != ENOERR)
  278. {
  279. diag_printf("Flash error cyg_io_get_config %d\n", err);
  280. reboot();
  281. }
  282. cyg_io_flash_getconfig_erase_t e;
  283. len = sizeof(e);
  284. e.offset = 0;
  285. e.len = ds.dev_size;
  286. diag_printf("Formatting 0x%08x bytes\n", (int)ds.dev_size);
  287. err = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_FLASH_ERASE, &e, &len);
  288. if (err != ENOERR)
  289. {
  290. diag_printf("Flash erase error %d offset 0x%08x\n", err, e.err_address);
  291. reboot();
  292. }
  293. diag_printf("Flash formatted successfully\n");
  294. #endif
  295. reboot();
  296. }
  297. static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp *interp, int argc,
  298. Jim_Obj * const *argv)
  299. {
  300. if (argc != 1)
  301. {
  302. return JIM_ERR;
  303. }
  304. format();
  305. for (;;)
  306. ;
  307. }
  308. static int zylinjtag_Jim_Command_threads(Jim_Interp *interp, int argc,
  309. Jim_Obj * const *argv)
  310. {
  311. cyg_handle_t thread = 0;
  312. cyg_uint16 id = 0;
  313. Jim_Obj *threads = Jim_NewListObj(interp, NULL, 0);
  314. /* Loop over the threads, and generate a table row for
  315. * each.
  316. */
  317. while (cyg_thread_get_next(&thread, &id))
  318. {
  319. Jim_Obj *threadObj = Jim_NewListObj(interp, NULL, 0);
  320. cyg_thread_info info;
  321. char *state_string;
  322. cyg_thread_get_info(thread, id, &info);
  323. if (info.name == NULL)
  324. info.name = "<no name>";
  325. Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
  326. info.name, strlen(info.name)));
  327. /* Translate the state into a string.
  328. */
  329. if (info.state == 0)
  330. state_string = "RUN";
  331. else if (info.state & 0x04)
  332. state_string = "SUSP";
  333. else
  334. switch (info.state & 0x1b)
  335. {
  336. case 0x01:
  337. state_string = "SLEEP";
  338. break;
  339. case 0x02:
  340. state_string = "CNTSLEEP";
  341. break;
  342. case 0x08:
  343. state_string = "CREATE";
  344. break;
  345. case 0x10:
  346. state_string = "EXIT";
  347. break;
  348. default:
  349. state_string = "????";
  350. break;
  351. }
  352. Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
  353. state_string, strlen(state_string)));
  354. Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, id));
  355. Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp,
  356. info.set_pri));
  357. Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp,
  358. info.cur_pri));
  359. Jim_ListAppendElement(interp, threads, threadObj);
  360. }
  361. Jim_SetResult(interp, threads);
  362. return JIM_OK;
  363. }
  364. static int zylinjtag_Jim_Command_log(Jim_Interp *interp, int argc,
  365. Jim_Obj * const *argv)
  366. {
  367. Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
  368. if (logCount >= logSize)
  369. {
  370. Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer + logCount
  371. % logSize, logSize - logCount % logSize);
  372. }
  373. Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);
  374. Jim_SetResult(interp, tclOutput);
  375. return JIM_OK;
  376. }
  377. static int zylinjtag_Jim_Command_reboot(Jim_Interp *interp, int argc,
  378. Jim_Obj * const *argv)
  379. {
  380. reboot();
  381. return JIM_OK;
  382. }
  383. static void zylinjtag_startNetwork(void)
  384. {
  385. // Bring TCP/IP up immediately before we're ready to accept commands.
  386. //
  387. // That is as soon as a PING responds, we're accepting telnet sessions.
  388. #if defined(CYGPKG_NET_FREEBSD_STACK)
  389. phi_init_all_network_interfaces();
  390. #else
  391. lwip_init();
  392. #endif
  393. if (!eth0_up)
  394. {
  395. diag_printf("Network not up and running\n");
  396. exit(-1);
  397. }
  398. /* very first thing we want is a reboot capability */
  399. reboot_port();
  400. #if defined(CYGPKG_NET_FREEBSD_STACK)
  401. /*start TFTP*/
  402. tftpd_start(69, &fileops);
  403. #endif
  404. cyg_httpd_init_tcl_interpreter();
  405. Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log,
  406. NULL, NULL);
  407. Jim_CreateCommand(httpstate.jim_interp, "zy1000_reboot",
  408. zylinjtag_Jim_Command_reboot, NULL, NULL);
  409. Jim_CreateCommand(httpstate.jim_interp, "threads",
  410. zylinjtag_Jim_Command_threads, NULL, NULL);
  411. Jim_CreateCommand(httpstate.jim_interp, "format_jffs2",
  412. zylinjtag_Jim_Command_format_jffs2, NULL, NULL);
  413. cyg_httpd_start();
  414. webRunning = true;
  415. diag_printf("Web server running\n");
  416. int s;
  417. struct ifreq ifr;
  418. s = socket(AF_INET, SOCK_DGRAM, 0);
  419. if (s >= 0)
  420. {
  421. strcpy(ifr.ifr_name, "eth0");
  422. int res;
  423. res = ioctl(s, SIOCGIFHWADDR, &ifr);
  424. close(s);
  425. if (res < 0)
  426. {
  427. diag_printf("Can't obtain MAC address\n");
  428. reboot();
  429. }
  430. }
  431. sprintf(hwaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
  432. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[0],
  433. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[1],
  434. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[2],
  435. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[3],
  436. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[4],
  437. (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[5]);
  438. discover_message
  439. = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr);
  440. discover_launch();
  441. }
  442. static void print_exception_handler(cyg_addrword_t data, cyg_code_t exception,
  443. cyg_addrword_t info)
  444. {
  445. writeLog = false;
  446. serialLog = true;
  447. char *infoStr = "unknown";
  448. switch (exception)
  449. {
  450. #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
  451. case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:
  452. infoStr = "undefined instruction";
  453. break;
  454. case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:
  455. infoStr = "software interrupt";
  456. break;
  457. case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:
  458. infoStr = "abort prefetch";
  459. break;
  460. case CYGNUM_HAL_VECTOR_ABORT_DATA:
  461. infoStr = "abort data";
  462. break;
  463. #endif
  464. default:
  465. break;
  466. }
  467. diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
  468. diag_printf("Dumping log\n---\n");
  469. if (logCount >= logSize)
  470. {
  471. diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);
  472. }
  473. diag_write(logBuffer, writePtr);
  474. diag_printf("---\nLogdump complete.\n");
  475. diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
  476. diag_printf("\n---\nRebooting\n");
  477. HAL_PLATFORM_RESET();
  478. }
  479. #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
  480. static void setHandler(cyg_code_t exception)
  481. {
  482. cyg_exception_handler_t *old_handler;
  483. cyg_addrword_t old_data;
  484. cyg_exception_set_handler(exception, print_exception_handler, 0,
  485. &old_handler, &old_data);
  486. }
  487. #endif
  488. static cyg_thread zylinjtag_uart_thread_object;
  489. static cyg_handle_t zylinjtag_uart_thread_handle;
  490. static char uart_stack[4096];
  491. static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
  492. static char backwardBuffer[1024];
  493. void setNoDelay(int session, int flag)
  494. {
  495. #if 1
  496. // This decreases latency dramatically for e.g. GDB load which
  497. // does not have a sliding window protocol
  498. //
  499. // Can cause *lots* of TCP/IP packets to be sent and it would have
  500. // to be enabled/disabled on the fly to avoid the CPU being
  501. // overloaded...
  502. setsockopt(session, /* socket affected */
  503. IPPROTO_TCP, /* set option at TCP level */
  504. TCP_NODELAY, /* name of option */
  505. (char *) &flag, /* the cast is historical
  506. cruft */
  507. sizeof(int)); /* length of option value */
  508. #endif
  509. }
  510. #define TEST_TCPIP() 0
  511. #if TEST_TCPIP
  512. struct
  513. {
  514. int req;
  515. int actual;
  516. int req2;
  517. int actual2;
  518. } tcpipSent[512 * 1024];
  519. int cur;
  520. #endif
  521. static void zylinjtag_uart(cyg_addrword_t data)
  522. {
  523. int so_reuseaddr_option = 1;
  524. int fd;
  525. if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  526. {
  527. LOG_ERROR("error creating socket: %s", strerror(errno));
  528. exit(-1);
  529. }
  530. setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option,
  531. sizeof(int));
  532. struct sockaddr_in sin;
  533. unsigned int address_size;
  534. address_size = sizeof(sin);
  535. memset(&sin, 0, sizeof(sin));
  536. sin.sin_family = AF_INET;
  537. sin.sin_addr.s_addr = INADDR_ANY;
  538. sin.sin_port = htons(5555);
  539. if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
  540. {
  541. LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
  542. exit(-1);
  543. }
  544. if (listen(fd, 1) == -1)
  545. {
  546. LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
  547. exit(-1);
  548. }
  549. // socket_nonblock(fd);
  550. for (;;)
  551. {
  552. int session = accept(fd, (struct sockaddr *) &sin, &address_size);
  553. if (session < 0)
  554. {
  555. continue;
  556. }
  557. setNoDelay(session, 1);
  558. int oldopts = fcntl(session, F_GETFL, 0);
  559. fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
  560. int serHandle = open(ZY1000_SER_DEV, O_RDWR | O_NONBLOCK);
  561. if (serHandle < 0)
  562. {
  563. close(session);
  564. continue;
  565. }
  566. #ifdef CYGPKG_PROFILE_GPROF
  567. start_profile();
  568. #endif
  569. size_t actual = 0;
  570. size_t actual2 = 0;
  571. size_t pos, pos2;
  572. pos = 0;
  573. pos2 = 0;
  574. #if TEST_TCPIP
  575. cur = 0;
  576. #endif
  577. for (;;)
  578. {
  579. fd_set write_fds;
  580. fd_set read_fds;
  581. FD_ZERO(&write_fds);
  582. FD_ZERO(&read_fds);
  583. int fd_max = -1;
  584. FD_SET(session, &read_fds);
  585. fd_max = session;
  586. FD_SET(serHandle, &read_fds);
  587. if (serHandle > fd_max)
  588. {
  589. fd_max = serHandle;
  590. }
  591. /* Wait... */
  592. cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
  593. if ((actual == 0) && (actual2 == 0))
  594. {
  595. int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);
  596. if (retval <= 0)
  597. {
  598. break;
  599. }
  600. }
  601. if (actual2 <= 0)
  602. {
  603. memset(backwardBuffer, 's', sizeof(backwardBuffer));
  604. int t;
  605. t = read(serHandle, backwardBuffer,
  606. sizeof(backwardBuffer));
  607. actual2 = t;
  608. if (t < 0)
  609. {
  610. if (errno != EAGAIN)
  611. {
  612. goto closeSession;
  613. }
  614. actual2 = 0;
  615. }
  616. pos2 = 0;
  617. }
  618. size_t y = 0;
  619. if (actual2 > 0)
  620. {
  621. int written = write(session, backwardBuffer + pos2, actual2);
  622. if (written <= 0)
  623. goto closeSession;
  624. actual2 -= written;
  625. pos2 += written;
  626. y = written;
  627. }
  628. if (FD_ISSET(session, &read_fds)
  629. && (sizeof(forwardBuffer) > actual))
  630. {
  631. // NB! Here it is important that we empty the TCP/IP read buffer
  632. // to make transmission tick right
  633. memmove(forwardBuffer, forwardBuffer + pos, actual);
  634. pos = 0;
  635. int t;
  636. // this will block if there is no data at all
  637. t = read_socket(session, forwardBuffer + actual,
  638. sizeof(forwardBuffer) - actual);
  639. if (t <= 0)
  640. {
  641. goto closeSession;
  642. }
  643. actual += t;
  644. }
  645. int y2 = 0;
  646. if (actual > 0)
  647. {
  648. /* Do not put things into the serial buffer if it has something to send
  649. * as that can cause a single byte to be sent at the time.
  650. *
  651. *
  652. */
  653. int written = write(serHandle, forwardBuffer + pos, actual);
  654. if (written < 0)
  655. {
  656. if (errno != EAGAIN)
  657. {
  658. goto closeSession;
  659. }
  660. // The serial buffer is full
  661. written = 0;
  662. }
  663. else
  664. {
  665. actual -= written;
  666. pos += written;
  667. }
  668. y2 = written;
  669. }
  670. #if TEST_TCPIP
  671. if (cur < 1024)
  672. {
  673. tcpipSent[cur].req = x;
  674. tcpipSent[cur].actual = y;
  675. tcpipSent[cur].req2 = x2;
  676. tcpipSent[cur].actual2 = y2;
  677. cur++;
  678. }
  679. #endif
  680. }
  681. closeSession: close(session);
  682. close(serHandle);
  683. #if TEST_TCPIP
  684. int i;
  685. for (i = 0; i < 1024; i++)
  686. {
  687. diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual,
  688. tcpipSent[i].req2, tcpipSent[i].actual2);
  689. }
  690. #endif
  691. }
  692. close(fd);
  693. }
  694. void startUart(void)
  695. {
  696. cyg_thread_create(1, zylinjtag_uart, (cyg_addrword_t) 0, "uart thread",
  697. (void *) uart_stack, sizeof(uart_stack),
  698. &zylinjtag_uart_thread_handle, &zylinjtag_uart_thread_object);
  699. cyg_thread_set_priority(zylinjtag_uart_thread_handle, 1); // low priority as it sits in a busy loop
  700. cyg_thread_resume(zylinjtag_uart_thread_handle);
  701. }
  702. static int zylinjtag_Jim_Command_uart(Jim_Interp *interp, int argc,
  703. Jim_Obj * const *argv)
  704. {
  705. static int current_baud = 38400;
  706. if (argc == 1)
  707. {
  708. command_print(cmd_ctx, "%d", current_baud);
  709. return JIM_OK;
  710. }
  711. else if (argc != 2)
  712. {
  713. return JIM_ERR;
  714. }
  715. long new_baudrate;
  716. if (Jim_GetLong(interp, argv[1], &new_baudrate) != JIM_OK)
  717. return JIM_ERR;
  718. current_baud = new_baudrate;
  719. int baud;
  720. switch (current_baud)
  721. {
  722. case 9600:
  723. baud = CYGNUM_SERIAL_BAUD_9600;
  724. break;
  725. case 19200:
  726. baud = CYGNUM_SERIAL_BAUD_19200;
  727. break;
  728. case 38400:
  729. baud = CYGNUM_SERIAL_BAUD_38400;
  730. break;
  731. case 57600:
  732. baud = CYGNUM_SERIAL_BAUD_57600;
  733. break;
  734. case 115200:
  735. baud = CYGNUM_SERIAL_BAUD_115200;
  736. break;
  737. case 230400:
  738. baud = CYGNUM_SERIAL_BAUD_230400;
  739. break;
  740. default:
  741. command_print(cmd_ctx, "unsupported baudrate");
  742. return ERROR_INVALID_ARGUMENTS;
  743. }
  744. cyg_serial_info_t buf;
  745. cyg_uint32 len = 1;
  746. //get existing serial configuration
  747. len = sizeof(cyg_serial_info_t);
  748. int err;
  749. cyg_io_handle_t serial_handle;
  750. err = cyg_io_lookup(ZY1000_SER_DEV, &serial_handle);
  751. if (err != ENOERR)
  752. {
  753. LOG_ERROR("Could not open serial port\n");
  754. return JIM_ERR;
  755. }
  756. err = cyg_io_get_config(serial_handle,
  757. CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buf, &len);
  758. err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &buf,
  759. &len);
  760. if (err != ENOERR)
  761. {
  762. LOG_ERROR("Failed to get serial port settings %d", err);
  763. return JIM_ERR;
  764. }
  765. buf.baud = baud;
  766. err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf,
  767. &len);
  768. if (err != ENOERR)
  769. {
  770. LOG_ERROR("Failed to set serial port settings %d", err);
  771. return JIM_ERR;
  772. }
  773. return JIM_OK;
  774. }
  775. bool logAllToSerial = false;
  776. int boolParam(char *var);
  777. static const char *zylin_config_dir="/config/settings";
  778. static int add_default_dirs(void)
  779. {
  780. add_script_search_dir(zylin_config_dir);
  781. add_script_search_dir("/rom/lib/openocd");
  782. add_script_search_dir("/rom");
  783. return ERROR_OK;
  784. }
  785. int main(int argc, char *argv[])
  786. {
  787. /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
  788. * need to allocate towards the end of the heap. */
  789. #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
  790. setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION);
  791. setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH);
  792. setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA);
  793. #endif
  794. int err;
  795. atexit(keep_webserver);
  796. diag_init_putc(_zylinjtag_diag_write_char);
  797. // We want this in the log.
  798. diag_printf("Zylin ZY1000.\n");
  799. err = mount("", "/ram", "ramfs");
  800. if (err < 0)
  801. {
  802. diag_printf("unable to mount ramfs\n");
  803. }
  804. chdir("/ram");
  805. char address[16];
  806. sprintf(address, "%p", &filedata[0]);
  807. err = mount(address, "/rom", "romfs");
  808. if (err < 0)
  809. {
  810. diag_printf("unable to mount /rom\n");
  811. }
  812. err = mount("", "/log", "logfs");
  813. if (err < 0)
  814. {
  815. diag_printf("unable to mount logfs\n");
  816. }
  817. err = mount("", "/tftp", "tftpfs");
  818. if (err < 0)
  819. {
  820. diag_printf("unable to mount logfs\n");
  821. }
  822. log = fopen("/log/log", "w");
  823. if (log == NULL)
  824. {
  825. diag_printf("Could not open log file /ram/log\n");
  826. exit(-1);
  827. }
  828. copydir("/rom", "/ram/cgi");
  829. err = mount("/dev/flash1", "/config", "jffs2");
  830. if (err < 0)
  831. {
  832. diag_printf("unable to mount jffs2, falling back to ram disk..\n");
  833. err = mount("", "/config", "ramfs");
  834. if (err < 0)
  835. {
  836. diag_printf("unable to mount /config as ramdisk.\n");
  837. reboot();
  838. }
  839. }
  840. else
  841. {
  842. /* are we using a ram disk instead of a flash disk? This is used
  843. * for ZY1000 live demo...
  844. *
  845. * copy over flash disk to ram block device
  846. */
  847. if (boolParam("ramdisk"))
  848. {
  849. diag_printf("Unmounting /config from flash and using ram instead\n");
  850. err = umount("/config");
  851. if (err < 0)
  852. {
  853. diag_printf("unable to unmount jffs\n");
  854. reboot();
  855. }
  856. err = mount("/dev/flash1", "/config2", "jffs2");
  857. if (err < 0)
  858. {
  859. diag_printf("unable to mount jffs\n");
  860. reboot();
  861. }
  862. err = mount("", "/config", "ramfs");
  863. if (err < 0)
  864. {
  865. diag_printf("unable to mount ram block device\n");
  866. reboot();
  867. }
  868. // copydir("/config2", "/config");
  869. copyfile("/config2/ip", "/config/ip");
  870. copydir("/config2/settings", "/config/settings");
  871. umount("/config2");
  872. }
  873. }
  874. mkdir(zylin_config_dir, 0777);
  875. char *dirname = alloc_printf("%s/target", zylin_config_dir);
  876. mkdir(dirname, 0777);
  877. free(dirname);
  878. dirname = alloc_printf("%s/board", zylin_config_dir);
  879. mkdir(dirname, 0777);
  880. free(dirname);
  881. dirname = alloc_printf("%s/event", zylin_config_dir);
  882. mkdir(dirname, 0777);
  883. free(dirname);
  884. logAllToSerial = boolParam("logserial");
  885. // We need the network & web server in case there is something wrong with
  886. // the config files that invoke exit()
  887. zylinjtag_startNetwork();
  888. /* we're going to access the jim interpreter from here on... */
  889. openocd_sleep_postlude();
  890. startUart();
  891. add_default_dirs();
  892. /* initialize commandline interface */
  893. struct command_context * cmd_ctx;
  894. struct command_context *setup_command_handler(Jim_Interp *interp);
  895. cmd_ctx = setup_command_handler(httpstate.jim_interp);
  896. command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
  897. command_context_mode(cmd_ctx, COMMAND_CONFIG);
  898. if (ioutil_init(cmd_ctx) != ERROR_OK)
  899. return EXIT_FAILURE;
  900. #ifdef CYGPKG_PROFILE_GPROF
  901. Jim_CreateCommand(httpstate.jim_interp, "zy1000_profile", zylinjtag_Jim_Command_profile,
  902. NULL, NULL);
  903. #endif
  904. Jim_CreateCommand(httpstate.jim_interp, "uart", zylinjtag_Jim_Command_uart, NULL, NULL);
  905. log_init();
  906. set_log_output(cmd_ctx, log);
  907. LOG_DEBUG("log init complete");
  908. // diag_printf("Executing config files\n");
  909. if (logAllToSerial)
  910. {
  911. diag_printf(
  912. "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir);
  913. command_run_line(cmd_ctx, "debug_level 3");
  914. }
  915. command_run_linef(cmd_ctx, "script /rom/openocd.cfg");
  916. int ret;
  917. ret = server_init(cmd_ctx);
  918. if (ERROR_OK != ret)
  919. return EXIT_FAILURE;
  920. /* we MUST always run the init command as it will launch telnet sessions */
  921. command_run_line(cmd_ctx, "init");
  922. // FIX!!! Yuk!
  923. // diag_printf() is really invoked from many more places than we trust it
  924. // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
  925. //
  926. // Disabling it here is safe and gives us enough logged debug output for now. Crossing
  927. // fingers that it doesn't cause any crashes.
  928. diag_printf("Init complete, GDB & telnet servers launched.\n");
  929. command_set_output_handler(cmd_ctx,
  930. zy1000_configuration_output_handler_log, NULL);
  931. if (!logAllToSerial)
  932. {
  933. serialLog = false;
  934. }
  935. /* handle network connections */
  936. server_loop(cmd_ctx);
  937. openocd_sleep_prelude();
  938. /* shut server down */
  939. server_quit();
  940. /* free commandline interface */
  941. command_done(cmd_ctx);
  942. umount("/config");
  943. exit(0);
  944. for (;;)
  945. ;
  946. }
  947. cyg_int32 cyg_httpd_exec_cgi_tcl(char *file_name);
  948. cyg_int32 homeForm(CYG_HTTPD_STATE *p)
  949. {
  950. cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
  951. return 0;
  952. }
  953. CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);
  954. CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label, "text", "text/plain");
  955. CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream");
  956. #include <pkgconf/system.h>
  957. #include <pkgconf/hal.h>
  958. #include <pkgconf/kernel.h>
  959. #include <pkgconf/io_fileio.h>
  960. #include <pkgconf/fs_rom.h>
  961. #include <cyg/kernel/ktypes.h> // base kernel types
  962. #include <cyg/infra/cyg_trac.h> // tracing macros
  963. #include <cyg/infra/cyg_ass.h> // assertion macros
  964. #include <cyg/fileio/fileio.h>
  965. #include <cyg/kernel/kapi.h>
  966. #include <cyg/infra/diag.h>
  967. //==========================================================================
  968. // Eventually we want to eXecute In Place from the ROM in a protected
  969. // environment, so we'll need executables to be aligned to a boundary
  970. // suitable for MMU protection. A suitable boundary would be the 4k
  971. // boundary in all the CPU architectures I am currently aware of.
  972. // Forward definitions
  973. // Filesystem operations
  974. static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
  975. static int tftpfs_umount(cyg_mtab_entry *mte);
  976. static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  977. int mode, cyg_file *fte);
  978. static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
  979. static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
  980. // File operations
  981. static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
  982. static int tftpfs_fo_close(struct CYG_FILE_TAG *fp);
  983. static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence);
  984. //==========================================================================
  985. // Filesystem table entries
  986. // -------------------------------------------------------------------------
  987. // Fstab entry.
  988. // This defines the entry in the filesystem table.
  989. // For simplicity we use _FILESYSTEM synchronization for all accesses since
  990. // we should never block in any filesystem operations.
  991. #if 1
  992. FSTAB_ENTRY(tftpfs_fste, "tftpfs", 0,
  993. CYG_SYNCMODE_NONE,
  994. tftpfs_mount,
  995. tftpfs_umount,
  996. tftpfs_open,
  997. (cyg_fsop_unlink *)cyg_fileio_erofs,
  998. (cyg_fsop_mkdir *)cyg_fileio_erofs,
  999. (cyg_fsop_rmdir *)cyg_fileio_erofs,
  1000. (cyg_fsop_rename *)cyg_fileio_erofs,
  1001. (cyg_fsop_link *)cyg_fileio_erofs,
  1002. (cyg_fsop_opendir *)cyg_fileio_erofs,
  1003. (cyg_fsop_chdir *)cyg_fileio_erofs,
  1004. (cyg_fsop_stat *)cyg_fileio_erofs,
  1005. (cyg_fsop_getinfo *)cyg_fileio_erofs,
  1006. (cyg_fsop_setinfo *)cyg_fileio_erofs);
  1007. #endif
  1008. // -------------------------------------------------------------------------
  1009. // mtab entry.
  1010. // This defines a single ROMFS loaded into ROM at the configured address
  1011. //
  1012. // MTAB_ENTRY(rom_mte, // structure name
  1013. // "/rom", // mount point
  1014. // "romfs", // FIlesystem type
  1015. // "", // hardware device
  1016. // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
  1017. //);
  1018. // -------------------------------------------------------------------------
  1019. // File operations.
  1020. // This set of file operations are used for normal open files.
  1021. static cyg_fileops tftpfs_fileops =
  1022. { tftpfs_fo_read, tftpfs_fo_write, tftpfs_fo_lseek,
  1023. (cyg_fileop_ioctl *) cyg_fileio_erofs, cyg_fileio_seltrue,
  1024. tftpfs_fo_fsync, tftpfs_fo_close,
  1025. (cyg_fileop_fstat *) cyg_fileio_erofs,
  1026. (cyg_fileop_getinfo *) cyg_fileio_erofs,
  1027. (cyg_fileop_setinfo *) cyg_fileio_erofs, };
  1028. // -------------------------------------------------------------------------
  1029. // tftpfs_mount()
  1030. // Process a mount request. This mainly finds root for the
  1031. // filesystem.
  1032. static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
  1033. {
  1034. return ENOERR;
  1035. }
  1036. static int tftpfs_umount(cyg_mtab_entry *mte)
  1037. {
  1038. return ENOERR;
  1039. }
  1040. struct Tftp
  1041. {
  1042. int write;
  1043. int readFile;
  1044. cyg_uint8 *mem;
  1045. int actual;
  1046. char *server;
  1047. char *file;
  1048. };
  1049. static void freeTftp(struct Tftp *t)
  1050. {
  1051. if (t == NULL)
  1052. return;
  1053. if (t->mem)
  1054. free(t->mem);
  1055. if (t->server)
  1056. free(t->server);
  1057. if (t->file)
  1058. free(t->file);
  1059. free(t);
  1060. }
  1061. static const int tftpMaxSize = 8192 * 1024;
  1062. static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  1063. int mode, cyg_file *file)
  1064. {
  1065. struct Tftp *tftp;
  1066. tftp = malloc(sizeof(struct Tftp));
  1067. if (tftp == NULL)
  1068. return EMFILE;
  1069. memset(tftp, 0, sizeof(struct Tftp));
  1070. file->f_flag |= mode & CYG_FILE_MODE_MASK;
  1071. file->f_type = CYG_FILE_TYPE_FILE;
  1072. file->f_ops = &tftpfs_fileops;
  1073. file->f_offset = 0;
  1074. file->f_data = 0;
  1075. file->f_xops = 0;
  1076. tftp->mem = malloc(tftpMaxSize);
  1077. if (tftp->mem == NULL)
  1078. {
  1079. freeTftp(tftp);
  1080. return EMFILE;
  1081. }
  1082. char *server = strchr(name, '/');
  1083. if (server == NULL)
  1084. {
  1085. freeTftp(tftp);
  1086. return EMFILE;
  1087. }
  1088. tftp->server = malloc(server - name + 1);
  1089. if (tftp->server == NULL)
  1090. {
  1091. freeTftp(tftp);
  1092. return EMFILE;
  1093. }
  1094. strncpy(tftp->server, name, server - name);
  1095. tftp->server[server - name] = 0;
  1096. tftp->file = strdup(server + 1);
  1097. if (tftp->file == NULL)
  1098. {
  1099. freeTftp(tftp);
  1100. return EMFILE;
  1101. }
  1102. file->f_data = (CYG_ADDRWORD) tftp;
  1103. return ENOERR;
  1104. }
  1105. static int fetchTftp(struct Tftp *tftp)
  1106. {
  1107. if (!tftp->readFile)
  1108. {
  1109. int err;
  1110. tftp->actual = tftp_client_get(tftp->file, tftp->server, 0, tftp->mem,
  1111. tftpMaxSize, TFTP_OCTET, &err);
  1112. if (tftp->actual < 0)
  1113. {
  1114. return EMFILE;
  1115. }
  1116. tftp->readFile = 1;
  1117. }
  1118. return ENOERR;
  1119. }
  1120. // -------------------------------------------------------------------------
  1121. // tftpfs_fo_write()
  1122. // Read data from file.
  1123. static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
  1124. {
  1125. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1126. if (fetchTftp(tftp) != ENOERR)
  1127. return EMFILE;
  1128. int i;
  1129. off_t pos = fp->f_offset;
  1130. int resid = 0;
  1131. for (i = 0; i < uio->uio_iovcnt; i++)
  1132. {
  1133. cyg_iovec *iov = &uio->uio_iov[i];
  1134. char *buf = (char *) iov->iov_base;
  1135. off_t len = iov->iov_len;
  1136. if (len + pos > tftp->actual)
  1137. {
  1138. len = tftp->actual - pos;
  1139. }
  1140. resid += iov->iov_len - len;
  1141. memcpy(buf, tftp->mem + pos, len);
  1142. pos += len;
  1143. }
  1144. uio->uio_resid = resid;
  1145. fp->f_offset = pos;
  1146. return ENOERR;
  1147. }
  1148. static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
  1149. {
  1150. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1151. int i;
  1152. off_t pos = fp->f_offset;
  1153. int resid = 0;
  1154. for (i = 0; i < uio->uio_iovcnt; i++)
  1155. {
  1156. cyg_iovec *iov = &uio->uio_iov[i];
  1157. char *buf = (char *) iov->iov_base;
  1158. off_t len = iov->iov_len;
  1159. if (len + pos > tftpMaxSize)
  1160. {
  1161. len = tftpMaxSize - pos;
  1162. }
  1163. resid += iov->iov_len - len;
  1164. memcpy(tftp->mem + pos, buf, len);
  1165. pos += len;
  1166. }
  1167. uio->uio_resid = resid;
  1168. fp->f_offset = pos;
  1169. tftp->write = 1;
  1170. return ENOERR;
  1171. }
  1172. static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
  1173. {
  1174. int error = ENOERR;
  1175. return error;
  1176. }
  1177. // -------------------------------------------------------------------------
  1178. // romfs_fo_close()
  1179. // Close a file. We just clear out the data pointer.
  1180. static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)
  1181. {
  1182. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1183. int error = ENOERR;
  1184. if (tftp->write)
  1185. {
  1186. tftp_client_put(tftp->file, tftp->server, 0, tftp->mem, fp->f_offset,
  1187. TFTP_OCTET, &error);
  1188. }
  1189. freeTftp(tftp);
  1190. fp->f_data = 0;
  1191. return error;
  1192. }
  1193. // -------------------------------------------------------------------------
  1194. // romfs_fo_lseek()
  1195. // Seek to a new file position.
  1196. static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)
  1197. {
  1198. struct Tftp *tftp = (struct Tftp *) fp->f_data;
  1199. off_t pos = *apos;
  1200. if (fetchTftp(tftp) != ENOERR)
  1201. return EMFILE;
  1202. switch (whence)
  1203. {
  1204. case SEEK_SET:
  1205. // Pos is already where we want to be.
  1206. break;
  1207. case SEEK_CUR:
  1208. // Add pos to current offset.
  1209. pos += fp->f_offset;
  1210. break;
  1211. case SEEK_END:
  1212. // Add pos to file size.
  1213. pos += tftp->actual;
  1214. break;
  1215. default:
  1216. return EINVAL;
  1217. }
  1218. // Check that pos is still within current file size, or at the
  1219. // very end.
  1220. if (pos < 0 || pos > tftp->actual)
  1221. return EINVAL;
  1222. // All OK, set fp offset and return new position.
  1223. *apos = fp->f_offset = pos;
  1224. return ENOERR;
  1225. }
  1226. void usleep(int us)
  1227. {
  1228. if (us > 10000)
  1229. cyg_thread_delay(us / 10000 + 1);
  1230. else
  1231. HAL_DELAY_US(us);
  1232. }
  1233. // Chunked version.
  1234. cyg_int32 show_log_entry(CYG_HTTPD_STATE *phttpstate)
  1235. {
  1236. cyg_httpd_start_chunked("text");
  1237. if (logCount >= logSize)
  1238. {
  1239. cyg_httpd_write_chunked(logBuffer + logCount % logSize, logSize
  1240. - logCount % logSize);
  1241. }
  1242. cyg_httpd_write_chunked(logBuffer, writePtr);
  1243. cyg_httpd_end_chunked();
  1244. return -1;
  1245. }
  1246. CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);
  1247. // Filesystem operations
  1248. static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
  1249. static int logfs_umount(cyg_mtab_entry *mte);
  1250. static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  1251. int mode, cyg_file *fte);
  1252. static int logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
  1253. // File operations
  1254. static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
  1255. static int logfs_fo_close(struct CYG_FILE_TAG *fp);
  1256. #include <cyg/io/devtab.h>
  1257. //==========================================================================
  1258. // Filesystem table entries
  1259. // -------------------------------------------------------------------------
  1260. // Fstab entry.
  1261. // This defines the entry in the filesystem table.
  1262. // For simplicity we use _FILESYSTEM synchronization for all accesses since
  1263. // we should never block in any filesystem operations.
  1264. FSTAB_ENTRY(logfs_fste, "logfs", 0,
  1265. CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM,
  1266. logfs_mount,
  1267. logfs_umount,
  1268. logfs_open,
  1269. (cyg_fsop_unlink *)cyg_fileio_erofs,
  1270. (cyg_fsop_mkdir *)cyg_fileio_erofs,
  1271. (cyg_fsop_rmdir *)cyg_fileio_erofs,
  1272. (cyg_fsop_rename *)cyg_fileio_erofs,
  1273. (cyg_fsop_link *)cyg_fileio_erofs,
  1274. (cyg_fsop_opendir *)cyg_fileio_erofs,
  1275. (cyg_fsop_chdir *)cyg_fileio_erofs,
  1276. (cyg_fsop_stat *)cyg_fileio_erofs,
  1277. (cyg_fsop_getinfo *)cyg_fileio_erofs,
  1278. (cyg_fsop_setinfo *)cyg_fileio_erofs);
  1279. // -------------------------------------------------------------------------
  1280. // File operations.
  1281. // This set of file operations are used for normal open files.
  1282. static cyg_fileops logfs_fileops =
  1283. { (cyg_fileop_read *) cyg_fileio_erofs, (cyg_fileop_write *) logfs_fo_write,
  1284. (cyg_fileop_lseek *) cyg_fileio_erofs,
  1285. (cyg_fileop_ioctl *) cyg_fileio_erofs, cyg_fileio_seltrue,
  1286. logfs_fo_fsync, logfs_fo_close, (cyg_fileop_fstat *) cyg_fileio_erofs,
  1287. (cyg_fileop_getinfo *) cyg_fileio_erofs,
  1288. (cyg_fileop_setinfo *) cyg_fileio_erofs, };
  1289. // -------------------------------------------------------------------------
  1290. // logfs_mount()
  1291. // Process a mount request. This mainly finds root for the
  1292. // filesystem.
  1293. static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
  1294. {
  1295. return ENOERR;
  1296. }
  1297. static int logfs_umount(cyg_mtab_entry *mte)
  1298. {
  1299. return ENOERR;
  1300. }
  1301. static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
  1302. int mode, cyg_file *file)
  1303. {
  1304. file->f_flag |= mode & CYG_FILE_MODE_MASK;
  1305. file->f_type = CYG_FILE_TYPE_FILE;
  1306. file->f_ops = &logfs_fileops;
  1307. file->f_offset = 0;
  1308. file->f_data = 0;
  1309. file->f_xops = 0;
  1310. return ENOERR;
  1311. }
  1312. // -------------------------------------------------------------------------
  1313. // logfs_fo_write()
  1314. // Write data to file.
  1315. static int logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
  1316. {
  1317. int i;
  1318. for (i = 0; i < uio->uio_iovcnt; i++)
  1319. {
  1320. cyg_iovec *iov = &uio->uio_iov[i];
  1321. char *buf = (char *) iov->iov_base;
  1322. off_t len = iov->iov_len;
  1323. diag_write(buf, len);
  1324. }
  1325. uio->uio_resid = 0;
  1326. return ENOERR;
  1327. }
  1328. static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
  1329. {
  1330. return ENOERR;
  1331. }
  1332. // -------------------------------------------------------------------------
  1333. // romfs_fo_close()
  1334. // Close a file. We just clear out the data pointer.
  1335. static int logfs_fo_close(struct CYG_FILE_TAG *fp)
  1336. {
  1337. return ENOERR;
  1338. }
  1339. int loadFile(const char *fileName, void **data, int *len);
  1340. /* boolean parameter stored on config */
  1341. int boolParam(char *var)
  1342. {
  1343. bool result = false;
  1344. char *name = alloc_printf("%s/%s", zylin_config_dir, var);
  1345. if (name == NULL)
  1346. return result;
  1347. void *data;
  1348. int len;
  1349. if (loadFile(name, &data, &len) == ERROR_OK)
  1350. {
  1351. if (len > 1)
  1352. len = 1;
  1353. result = strncmp((char *) data, "1", len) == 0;
  1354. free(data);
  1355. }
  1356. free(name);
  1357. return result;
  1358. }