X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fecosboard.c;h=0805e6fcb93c2c88c5db1d606750cef2dc39021e;hp=019eb0e853c3777a948157684baae91c6679e1d9;hb=559d08c19ed838f7bb2a77ce56a5a274641111f8;hpb=bb563397616a67320b7dbc786195ca52693b880b diff --git a/src/ecosboard.c b/src/ecosboard.c index 019eb0e853..0805e6fcb9 100644 --- a/src/ecosboard.c +++ b/src/ecosboard.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2008 by Øyvind Harboe * + * Copyright (C) 2007-2010 by Øyvind Harboe * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -21,25 +21,20 @@ #include "config.h" #endif -#include "log.h" -#include "types.h" -#include "jtag.h" -#include "configuration.h" -#include "xsvf.h" -#include "target.h" -#include "flash.h" -#include "nand.h" -#include "pld.h" - -#include "command.h" -#include "server.h" -#include "telnet_server.h" -#include "gdb_server.h" - -#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + #include -#include -#include #include #include #include @@ -60,29 +55,22 @@ #include #include #include -#include -#include -#include #include +#include #include +#include + #include "rom.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifdef CYGPKG_HAL_NIOS2 +#include +#define ZY1000_SER_DEV "/dev/uart_0" +#else +#define ZY1000_SER_DEV "/dev/ser0" + +#endif + + #define MAX_IFS 64 #if defined(CYGPKG_NET_FREEBSD_STACK) #include @@ -92,7 +80,7 @@ struct tftpd_fileops fileops = (int (*)(const char *, int))open, close, (int (*)(int, const void *, int))write, - ( int (*)(int, void *, int))read + (int (*)(int, void *, int))read }; #endif @@ -112,10 +100,6 @@ static bool writeLog = true; char hwaddr[512]; - -extern flash_driver_t *flash_drivers[]; -extern target_type_t *target_types[]; - #ifdef CYGPKG_PROFILE_GPROF #include @@ -147,7 +131,6 @@ void start_profile(void) } #endif -extern int eth0_up; static FILE *log; static char reboot_stack[2048]; @@ -155,12 +138,19 @@ static char reboot_stack[2048]; static void zylinjtag_reboot(cyg_addrword_t data) { serialLog = true; - diag_printf("Rebooting in 100 ticks..\n"); - cyg_thread_delay(100); + diag_printf("Rebooting in 500 ticks..\n"); + cyg_thread_delay(500); diag_printf("Unmounting /config..\n"); umount("/config"); diag_printf("Rebooting..\n"); +#ifdef CYGPKG_HAL_NIOS2 + /* This will reboot & reconfigure the FPGA from the bootloader + * and on. + */ + IOWR(REMOTE_UPDATE_BASE, 0x20, 0x1); +#else HAL_PLATFORM_RESET(); +#endif } static cyg_thread zylinjtag_thread_object; static cyg_handle_t zylinjtag_thread_handle; @@ -173,7 +163,63 @@ void reboot(void) cyg_thread_resume(zylinjtag_thread_handle); } -int configuration_output_handler(struct command_context_s *context, +static char zylinjtag_reboot_port_stack[2048]; +static cyg_thread zylinjtag_reboot_port_thread_object; +static cyg_handle_t zylinjtag_reboot_port_thread_handle; + +static void zylinjtag_reboot_port_task(cyg_addrword_t data) +{ + int so_reuseaddr_option = 1; + + int fd; + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + LOG_ERROR("error creating socket: %s", strerror(errno)); + exit(-1); + } + + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option, + sizeof(int)); + + struct sockaddr_in sin; + unsigned int address_size; + address_size = sizeof(sin); + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(1234); + + if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1) + { + LOG_ERROR("couldn't bind to socket: %s", strerror(errno)); + exit(-1); + } + + if (listen(fd, 1) == -1) + { + LOG_ERROR("couldn't listen on socket: %s", strerror(errno)); + exit(-1); + } + // socket_nonblock(fd); + + + accept(fd, (struct sockaddr *) &sin, &address_size); + + diag_printf("Got reboot signal on port 1234"); + + reboot(); + +} + +void reboot_port(void) +{ + cyg_thread_create(1, zylinjtag_reboot_port_task, (cyg_addrword_t) 0, "wait for reboot signal on port 1234", + (void *) zylinjtag_reboot_port_stack, sizeof(zylinjtag_reboot_port_stack), + &zylinjtag_reboot_port_thread_handle, &zylinjtag_reboot_port_thread_object); + cyg_thread_resume(zylinjtag_reboot_port_thread_handle); +} + +int configuration_output_handler(struct command_context *context, const char* line) { diag_printf("%s", line); @@ -181,7 +227,7 @@ int configuration_output_handler(struct command_context_s *context, return ERROR_OK; } -int zy1000_configuration_output_handler_log(struct command_context_s *context, +int zy1000_configuration_output_handler_log(struct command_context *context, const char* line) { LOG_USER_N("%s", line); @@ -190,24 +236,33 @@ int zy1000_configuration_output_handler_log(struct command_context_s *context, } #ifdef CYGPKG_PROFILE_GPROF -extern void start_profile(); +//extern int64_t totaltime; -int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +static int zylinjtag_Jim_Command_profile(Jim_Interp *interp, int argc, + Jim_Obj * const *argv) { - command_print(cmd_ctx, "Profiling started"); - start_profile(); + if ((argc == 2) && (strcmp(Jim_GetString(argv[1], NULL), "stats")==0)) + { +// profile_off(); + //LOG_USER("Stats %dms sleeping in select()", (int)totaltime); + } else + { + LOG_USER("Profiling started"); + start_profile(); + //totaltime = 0; + } return ERROR_OK; } #endif -externC void phi_init_all_network_interfaces(); +externC void phi_init_all_network_interfaces(void); -command_context_t *cmd_ctx; +struct command_context *cmd_ctx; static bool webRunning = false; -void keep_webserver() +void keep_webserver(void) { // Target initialisation is only attempted at startup, so we sleep forever and // let the http server bail us out(i.e. get config files set up). @@ -254,25 +309,26 @@ void copyfile(char *name2, char *name1); void copydir(char *name, char *destdir); #if 0 -MTAB_ENTRY( romfs_mte1, +MTAB_ENTRY(romfs_mte1, "/rom", "romfs", "", - (CYG_ADDRWORD) &filedata[0] ); + (CYG_ADDRWORD) &filedata[0]); #endif -void openocd_sleep_prelude() +void openocd_sleep_prelude(void) { cyg_mutex_unlock(&httpstate.jim_lock); } -void openocd_sleep_postlude() +void openocd_sleep_postlude(void) { cyg_mutex_lock(&httpstate.jim_lock); } void format(void) { +#ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1 diag_printf("Formatting JFFS2...\n"); cyg_io_handle_t handle; @@ -296,22 +352,21 @@ void format(void) } cyg_io_flash_getconfig_erase_t e; - void *err_addr; len = sizeof(e); e.offset = 0; e.len = ds.dev_size; - e.err_address = &err_addr; - diag_printf("Formatting 0x%08x bytes\n", ds.dev_size); + diag_printf("Formatting 0x%08x bytes\n", (int)ds.dev_size); err = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_FLASH_ERASE, &e, &len); if (err != ENOERR) { - diag_printf("Flash erase error %d offset 0x%p\n", err, err_addr); + diag_printf("Flash erase error %d offset 0x%08x\n", err, e.err_address); reboot(); } diag_printf("Flash formatted successfully\n"); +#endif reboot(); } @@ -419,10 +474,7 @@ static int zylinjtag_Jim_Command_reboot(Jim_Interp *interp, int argc, return JIM_OK; } - -extern Jim_Interp *interp; - -static void zylinjtag_startNetwork() +static void zylinjtag_startNetwork(void) { // Bring TCP/IP up immediately before we're ready to accept commands. // @@ -437,6 +489,10 @@ static void zylinjtag_startNetwork() diag_printf("Network not up and running\n"); exit(-1); } + + /* very first thing we want is a reboot capability */ + reboot_port(); + #if defined(CYGPKG_NET_FREEBSD_STACK) /*start TFTP*/ tftpd_start(69, &fileops); @@ -444,11 +500,13 @@ static void zylinjtag_startNetwork() cyg_httpd_init_tcl_interpreter(); - interp = httpstate.jim_interp; + // Kludge! Why can't I do this from httpd.c??? I get linker errors... + // some of that --start/end-group stuff? + Jim_InitStaticExtensions(httpstate.jim_interp); Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log, NULL, NULL); - Jim_CreateCommand(httpstate.jim_interp, "reboot", + Jim_CreateCommand(httpstate.jim_interp, "zy1000_reboot", zylinjtag_Jim_Command_reboot, NULL, NULL); Jim_CreateCommand(httpstate.jim_interp, "threads", zylinjtag_Jim_Command_threads, NULL, NULL); @@ -534,6 +592,7 @@ static void print_exception_handler(cyg_addrword_t data, cyg_code_t exception, } +#ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION static void setHandler(cyg_code_t exception) { cyg_exception_handler_t *old_handler; @@ -542,6 +601,7 @@ static void setHandler(cyg_code_t exception) cyg_exception_set_handler(exception, print_exception_handler, 0, &old_handler, &old_data); } +#endif static cyg_thread zylinjtag_uart_thread_object; static cyg_handle_t zylinjtag_uart_thread_handle; @@ -568,6 +628,9 @@ void setNoDelay(int session, int flag) #endif } +#define TEST_TCPIP() 0 + +#if TEST_TCPIP struct { int req; @@ -576,6 +639,7 @@ struct int actual2; } tcpipSent[512 * 1024]; int cur; +#endif static void zylinjtag_uart(cyg_addrword_t data) { @@ -625,7 +689,7 @@ static void zylinjtag_uart(cyg_addrword_t data) int oldopts = fcntl(session, F_GETFL, 0); fcntl(session, F_SETFL, oldopts | O_NONBLOCK); // - int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK); + int serHandle = open(ZY1000_SER_DEV, O_RDWR | O_NONBLOCK); if (serHandle < 0) { close(session); @@ -635,12 +699,14 @@ static void zylinjtag_uart(cyg_addrword_t data) #ifdef CYGPKG_PROFILE_GPROF start_profile(); #endif - int actual = 0; - int actual2 = 0; - int pos, pos2; + size_t actual = 0; + size_t actual2 = 0; + size_t pos, pos2; pos = 0; pos2 = 0; +#if TEST_TCPIP cur = 0; +#endif for (;;) { fd_set write_fds; @@ -670,9 +736,11 @@ static void zylinjtag_uart(cyg_addrword_t data) if (actual2 <= 0) { memset(backwardBuffer, 's', sizeof(backwardBuffer)); - actual2 = read(serHandle, backwardBuffer, + int t; + t = read(serHandle, backwardBuffer, sizeof(backwardBuffer)); - if (actual2 < 0) + actual2 = t; + if (t < 0) { if (errno != EAGAIN) { @@ -683,8 +751,7 @@ static void zylinjtag_uart(cyg_addrword_t data) pos2 = 0; } - int x = actual2; - int y = 0; + size_t y = 0; if (actual2 > 0) { int written = write(session, backwardBuffer + pos2, actual2); @@ -713,7 +780,6 @@ static void zylinjtag_uart(cyg_addrword_t data) actual += t; } - int x2 = actual; int y2 = 0; if (actual > 0) { @@ -739,6 +805,7 @@ static void zylinjtag_uart(cyg_addrword_t data) } y2 = written; } +#if TEST_TCPIP if (cur < 1024) { tcpipSent[cur].req = x; @@ -747,11 +814,12 @@ static void zylinjtag_uart(cyg_addrword_t data) tcpipSent[cur].actual2 = y2; cur++; } - +#endif } closeSession: close(session); close(serHandle); +#if TEST_TCPIP int i; for (i = 0; i < 1024; i++) { @@ -759,6 +827,7 @@ static void zylinjtag_uart(cyg_addrword_t data) tcpipSent[i].req2, tcpipSent[i].actual2); } +#endif } close(fd); @@ -773,21 +842,25 @@ void startUart(void) cyg_thread_resume(zylinjtag_uart_thread_handle); } -int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, - char **args, int argc) +static int zylinjtag_Jim_Command_uart(Jim_Interp *interp, int argc, + Jim_Obj * const *argv) { static int current_baud = 38400; - if (argc == 0) + if (argc == 1) { - command_print(cmd_ctx, "%d", current_baud); - return ERROR_OK; + Jim_SetResult(interp, Jim_NewIntObj(interp, current_baud)); + return JIM_OK; } - else if (argc != 1) + else if (argc != 2) { - return ERROR_INVALID_ARGUMENTS; + return JIM_ERR; } - current_baud = atol(args[0]); + long new_baudrate; + if (Jim_GetLong(interp, argv[1], &new_baudrate) != JIM_OK) + return JIM_ERR; + + current_baud = new_baudrate; int baud; switch (current_baud) @@ -811,8 +884,8 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, baud = CYGNUM_SERIAL_BAUD_230400; break; default: - command_print(cmd_ctx, "unsupported baudrate"); - return ERROR_INVALID_ARGUMENTS; + Jim_SetResult(interp, Jim_NewStringObj(interp, "unsupported baudrate", -1)); + return JIM_ERR; } cyg_serial_info_t buf; @@ -822,11 +895,11 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, int err; cyg_io_handle_t serial_handle; - err = cyg_io_lookup("/dev/ser0", &serial_handle); + err = cyg_io_lookup(ZY1000_SER_DEV, &serial_handle); if (err != ENOERR) { - LOG_ERROR("/dev/ser0 not found\n"); - return ERROR_FAIL; + Jim_SetResult(interp, Jim_NewStringObj(interp, "Could not open serial port", -1)); + return JIM_ERR; } err = cyg_io_get_config(serial_handle, @@ -835,8 +908,8 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, &len); if (err != ENOERR) { - command_print(cmd_ctx, "Failed to get serial port settings %d", err); - return ERROR_OK; + Jim_SetResult(interp, Jim_NewStringObj(interp, "Failed to get serial port settings", -1)); + return JIM_ERR; } buf.baud = baud; @@ -844,11 +917,11 @@ int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, &len); if (err != ENOERR) { - command_print(cmd_ctx, "Failed to set serial port settings %d", err); - return ERROR_OK; + Jim_SetResult(interp, Jim_NewStringObj(interp, "Failed to set serial port settings", -1)); + return JIM_ERR; } - return ERROR_OK; + return JIM_OK; } bool logAllToSerial = false; @@ -857,11 +930,9 @@ bool logAllToSerial = false; int boolParam(char *var); -command_context_t *setup_command_handler(); +static const char *zylin_config_dir="/config/settings"; -extern const char *zylin_config_dir; - -int add_default_dirs(void) +static int add_default_dirs(void) { add_script_search_dir(zylin_config_dir); add_script_search_dir("/rom/lib/openocd"); @@ -886,7 +957,11 @@ int main(int argc, char *argv[]) diag_init_putc(_zylinjtag_diag_write_char); // We want this in the log. - diag_printf("Zylin ZY1000.\n"); +#ifdef CYGPKG_HAL_NIOS2 + diag_printf("Zylin ZY1000 PCB revc.\n"); +#else + diag_printf("Zylin ZY1000 PCB revb.\n"); +#endif err = mount("", "/ram", "ramfs"); if (err < 0) @@ -925,6 +1000,20 @@ int main(int argc, char *argv[]) copydir("/rom", "/ram/cgi"); +#ifdef CYGPKG_HAL_NIOS2 + cyg_flashaddr_t err_address; +#define UNCACHED_EXT_FLASH_BASE (0x80000000 + EXT_FLASH_BASE) + /* The revc flash is locked upon reset, unlock it */ +#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING + if ((err = flash_unlock((void *) UNCACHED_EXT_FLASH_BASE, EXT_FLASH_SPAN, + (void **) &err_address)) != 0) + { + diag_printf("Error: could not unlock flash\n"); + } +#endif +#endif + + err = mount("/dev/flash1", "/config", "jffs2"); if (err < 0) { @@ -976,10 +1065,13 @@ int main(int argc, char *argv[]) } mkdir(zylin_config_dir, 0777); - char *dirname=alloc_printf("%s/target", zylin_config_dir); + char *dirname = alloc_printf("%s/target", zylin_config_dir); + mkdir(dirname, 0777); + free(dirname); + dirname = alloc_printf("%s/board", zylin_config_dir); mkdir(dirname, 0777); free(dirname); - dirname=alloc_printf("%s/event", zylin_config_dir); + dirname = alloc_printf("%s/event", zylin_config_dir); mkdir(dirname, 0777); free(dirname); @@ -996,26 +1088,27 @@ int main(int argc, char *argv[]) add_default_dirs(); /* initialize commandline interface */ - command_context_t * cmd_ctx; - cmd_ctx = setup_command_handler(); + struct command_context * cmd_ctx; + struct command_context *setup_command_handler(Jim_Interp *interp); + cmd_ctx = setup_command_handler(httpstate.jim_interp); command_set_output_handler(cmd_ctx, configuration_output_handler, NULL); command_context_mode(cmd_ctx, COMMAND_CONFIG); + if (util_init(cmd_ctx) != ERROR_OK) + return EXIT_FAILURE; + + if (ioutil_init(cmd_ctx) != ERROR_OK) + return EXIT_FAILURE; + #ifdef CYGPKG_PROFILE_GPROF - register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command, - COMMAND_ANY, NULL); + Jim_CreateCommand(httpstate.jim_interp, "zy1000_profile", zylinjtag_Jim_Command_profile, + NULL, NULL); #endif - register_command(cmd_ctx, NULL, "uart", handle_uart_command, COMMAND_ANY, - "uart - forward uart on port 5555"); + Jim_CreateCommand(httpstate.jim_interp, "zy1000_uart", zylinjtag_Jim_Command_uart, NULL, NULL); - int errVal; - errVal = log_init(cmd_ctx); - if (errVal != ERROR_OK) - { - diag_printf("log_init() failed %d\n", errVal); - exit(-1); - } + + log_init(); set_log_output(cmd_ctx, log); @@ -1026,12 +1119,20 @@ int main(int argc, char *argv[]) if (logAllToSerial) { diag_printf( - "%s/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir); + "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir); command_run_line(cmd_ctx, "debug_level 3"); } command_run_linef(cmd_ctx, "script /rom/openocd.cfg"); + int ret; + ret = server_init(cmd_ctx); + if (ERROR_OK != ret) + return EXIT_FAILURE; + + /* we MUST always run the init command as it will launch telnet sessions */ + command_run_line(cmd_ctx, "init"); + // FIX!!! Yuk! // diag_printf() is really invoked from many more places than we trust it // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*). @@ -1083,20 +1184,7 @@ CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream"); #include // base kernel types #include // tracing macros #include // assertion macros -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - #include - #include #include @@ -1130,7 +1218,7 @@ static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence); // For simplicity we use _FILESYSTEM synchronization for all accesses since // we should never block in any filesystem operations. #if 1 -FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0, +FSTAB_ENTRY(tftpfs_fste, "tftpfs", 0, CYG_SYNCMODE_NONE, tftpfs_mount, tftpfs_umount, @@ -1151,12 +1239,12 @@ FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0, // mtab entry. // This defines a single ROMFS loaded into ROM at the configured address // -// MTAB_ENTRY( rom_mte, // structure name +// MTAB_ENTRY(rom_mte, // structure name // "/rom", // mount point // "romfs", // FIlesystem type // "", // hardware device // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM -// ); +//); // ------------------------------------------------------------------------- @@ -1193,6 +1281,7 @@ struct Tftp cyg_uint8 *mem; int actual; char *server; + int port; char *file; }; @@ -1249,6 +1338,15 @@ static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name, strncpy(tftp->server, name, server - name); tftp->server[server - name] = 0; + tftp->port = 0; /* default port 69 */ + char *port; + port = strchr(tftp->server, ':'); + if (port != NULL) + { + tftp->port = atoi(port + 1); + *port = 0; + } + tftp->file = strdup(server + 1); if (tftp->file == NULL) { @@ -1266,7 +1364,7 @@ static int fetchTftp(struct Tftp *tftp) if (!tftp->readFile) { int err; - tftp->actual = tftp_client_get(tftp->file, tftp->server, 0, tftp->mem, + tftp->actual = tftp_client_get(tftp->file, tftp->server, tftp->port, tftp->mem, tftpMaxSize, TFTP_OCTET, &err); if (tftp->actual < 0) @@ -1459,8 +1557,8 @@ static int logfs_fo_close(struct CYG_FILE_TAG *fp); // This defines the entry in the filesystem table. // For simplicity we use _FILESYSTEM synchronization for all accesses since // we should never block in any filesystem operations. -FSTAB_ENTRY( logfs_fste, "logfs", 0, - CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM, +FSTAB_ENTRY(logfs_fste, "logfs", 0, + CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM, logfs_mount, logfs_umount, logfs_open, @@ -1547,3 +1645,26 @@ static int logfs_fo_close(struct CYG_FILE_TAG *fp) return ENOERR; } +int loadFile(const char *fileName, void **data, int *len); + +/* boolean parameter stored on config */ +int boolParam(char *var) +{ + bool result = false; + char *name = alloc_printf("%s/%s", zylin_config_dir, var); + if (name == NULL) + return result; + + void *data; + int len; + if (loadFile(name, &data, &len) == ERROR_OK) + { + if (len > 1) + len = 1; + result = strncmp((char *) data, "1", len) == 0; + free(data); + } + free(name); + return result; +} +