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.
 
 
 
 
 
 

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