X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fjtag%2Fzy1000%2Fzy1000.c;h=7c5f4407553dc14f13b9eb22cebb7582b02bf6b9;hb=2bc7446bb8caf751f7d6900af26384f6c64cc791;hp=f2a5aa942c08620da0b86e56e7f3f5bde655cba1;hpb=83104648e6a1834244eb1b1bb6324f729532906c;p=openocd diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index f2a5aa94..7c5f4407 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2008 by Øyvind Harboe * + * Copyright (C) 2007-2009 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 * @@ -16,36 +16,56 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + +/* This file supports the zy1000 debugger: http://www.zylin.com/zy1000.html + * + * The zy1000 is a standalone debugger that has a web interface and + * requires no drivers on the developer host as all communication + * is via TCP/IP. The zy1000 gets it performance(~400-700kBytes/s + * DCC downloads @ 16MHz target) as it has an FPGA to hardware + * accelerate the JTAG commands, while offering *very* low latency + * between OpenOCD and the FPGA registers. + * + * The disadvantage of the zy1000 is that it has a feeble CPU compared to + * a PC(ca. 50-500 DMIPS depending on how one counts it), whereas a PC + * is on the order of 10000 DMIPS(i.e. at a factor of 20-200). + * + * The zy1000 revc hardware is using an Altera Nios CPU, whereas the + * revb is using ARM7 + Xilinx. + * + * See Zylin web pages or contact Zylin for more information. + * + * The reason this code is in OpenOCD rather than OpenOCD linked with the + * ZY1000 code is that OpenOCD is the long road towards getting + * libopenocd into place. libopenocd will support both low performance, + * low latency systems(embedded) and high performance high latency + * systems(PCs). + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "embeddedice.h" -#include "minidriver.h" -#include "interface.h" +#include +#include +#include #include "zy1000_version.h" #include // low level i/o #include +#include + +#ifdef CYGPKG_HAL_NIOS2 +#include +#include +#endif + #define ZYLIN_VERSION GIT_ZY1000_VERSION #define ZYLIN_DATE __DATE__ #define ZYLIN_TIME __TIME__ #define ZYLIN_OPENOCD GIT_OPENOCD_VERSION #define ZYLIN_OPENOCD_VERSION "ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE -/* low level command set - */ -void zy1000_reset(int trst, int srst); - - -int zy1000_speed(int speed); -int zy1000_register_commands(struct command_context *cmd_ctx); -int zy1000_init(void); -int zy1000_quit(void); - -/* interface commands */ -int zy1000_handle_zy1000_port_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc); static int zy1000_khz(int khz, int *jtag_speed) { @@ -78,8 +98,8 @@ static bool readPowerDropout(void) { cyg_uint32 state; // sample and clear power dropout - HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x80); - HAL_READ_UINT32(ZY1000_JTAG_BASE + 0x10, state); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x80); + ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state); bool powerDropout; powerDropout = (state & 0x80) != 0; return powerDropout; @@ -90,8 +110,8 @@ static bool readSRST(void) { cyg_uint32 state; // sample and clear SRST sensing - HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x00000040); - HAL_READ_UINT32(ZY1000_JTAG_BASE + 0x10, state); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000040); + ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state); bool srstAsserted; srstAsserted = (state & 0x40) != 0; return srstAsserted; @@ -109,21 +129,6 @@ static int zy1000_power_dropout(int *dropout) return ERROR_OK; } - -struct jtag_interface zy1000_interface = -{ - .name = "ZY1000", - .execute_queue = NULL, - .speed = zy1000_speed, - .register_commands = zy1000_register_commands, - .init = zy1000_init, - .quit = zy1000_quit, - .khz = zy1000_khz, - .speed_div = zy1000_speed_div, - .power_dropout = zy1000_power_dropout, - .srst_asserted = zy1000_srst_asserted, -}; - void zy1000_reset(int trst, int srst) { LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst); @@ -218,38 +223,30 @@ static void setPower(bool power) savePower = power; if (power) { - HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x14, 0x8); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x8); } else { - HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x8); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x8); } } -int handle_power_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_power_command) { - if (argc > 1) + switch (CMD_ARGC) { - return ERROR_INVALID_ARGUMENTS; + case 1: { + bool enable; + COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable); + setPower(enable); + // fall through } - - if (argc == 1) - { - if (strcmp(args[0], "on") == 0) - { - setPower(1); - } - else if (strcmp(args[0], "off") == 0) - { - setPower(0); - } else - { - command_print(cmd_ctx, "arg is \"on\" or \"off\""); - return ERROR_INVALID_ARGUMENTS; - } + case 0: + LOG_INFO("Target power %s", savePower ? "on" : "off"); + break; + default: + return ERROR_INVALID_ARGUMENTS; } - command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off"); - return ERROR_OK; } @@ -257,9 +254,8 @@ int handle_power_command(struct command_context *cmd_ctx, char *cmd, char **args /* Give TELNET a way to find out what version this is */ static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if ((argc < 1) || (argc > 2)) + if ((argc < 1) || (argc > 3)) return JIM_ERR; - char buff[128]; const char *version_str = NULL; if (argc == 1) @@ -268,6 +264,9 @@ static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv } else { const char *str = Jim_GetString(argv[1], NULL); + const char *str2 = NULL; + if (argc > 2) + str2 = Jim_GetString(argv[2], NULL); if (strcmp("openocd", str) == 0) { version_str = ZYLIN_OPENOCD; @@ -292,6 +291,29 @@ static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv version_str="b"; #endif } +#ifdef CYGPKG_HAL_NIOS2 + else if (strcmp("fpga", str) == 0) + { + + /* return a list of 32 bit integers to describe the expected + * and actual FPGA + */ + static char *fpga_id = "0x12345678 0x12345678 0x12345678 0x12345678"; + cyg_uint32 id, timestamp; + HAL_READ_UINT32(SYSID_BASE, id); + HAL_READ_UINT32(SYSID_BASE+4, timestamp); + sprintf(fpga_id, "0x%08x 0x%08x 0x%08x 0x%08x", id, timestamp, SYSID_ID, SYSID_TIMESTAMP); + version_str = fpga_id; + if ((argc>2) && (strcmp("time", str2) == 0)) + { + time_t last_mod = timestamp; + char * t = ctime (&last_mod) ; + t[strlen(t)-1] = 0; + version_str = t; + } + } +#endif + else { return JIM_ERR; @@ -305,33 +327,57 @@ static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv #ifdef CYGPKG_HAL_NIOS2 + + +struct info_forward +{ + void *data; + struct cyg_upgrade_info *upgraded_file; +}; + +static void report_info(void *data, const char * format, va_list args) +{ + char *s = alloc_vprintf(format, args); + LOG_USER_N("%s", s); + free(s); +} + +struct cyg_upgrade_info firmware_info = +{ + (cyg_uint8 *)0x84000000, + "/ram/firmware.phi", + "Firmware", + 0x0300000, + 0x1f00000 - + 0x0300000, + "ZylinNiosFirmware\n", + report_info, +}; + static int jim_zy1000_writefirmware(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc != 2) return JIM_ERR; int length; - int stat; const char *str = Jim_GetString(argv[1], &length); - /* BUG!!!! skip header! */ - void *firmware_address=0x4000000; - int firmware_length=0x100000; - - if (length>firmware_length) + /* */ + int tmpFile; + if ((tmpFile = open(firmware_info.file, O_RDWR | O_CREAT | O_TRUNC)) <= 0) + { + return JIM_ERR; + } + bool success; + success = write(tmpFile, str, length) == length; + close(tmpFile); + if (!success) return JIM_ERR; - void *err_addr; - - if ((stat = flash_erase((void *)firmware_address, firmware_length, (void **)&err_addr)) != 0) - { - return JIM_ERR; - } - - if ((stat = flash_program(firmware_address, str, length, (void **)&err_addr)) != 0) - return JIM_ERR; + if (!cyg_firmware_upgrade(NULL, firmware_info)) + return JIM_ERR; - return JIM_OK; + return JIM_OK; } #endif @@ -354,24 +400,6 @@ zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp, return JIM_OK; } -int zy1000_register_commands(struct command_context *cmd_ctx) -{ - register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY, - "power - turn power switch to target on/off. No arguments - print status."); - - Jim_CreateCommand(interp, "zy1000_version", jim_zy1000_version, NULL, NULL); - - - Jim_CreateCommand(interp, "powerstatus", zylinjtag_Jim_Command_powerstatus, NULL, NULL); - -#ifdef CYGPKG_HAL_NIOS2 - Jim_CreateCommand(interp, "updatezy1000firmware", jim_zy1000_writefirmware, NULL, NULL); -#endif - - - return ERROR_OK; -} - @@ -801,3 +829,50 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, } +static const struct command_registration zy1000_commands[] = { + { + .name = "power", + .handler = &handle_power_command, + .mode = COMMAND_ANY, + .help = "turn power switch to target on/off. No arguments - print status.", + .usage = "power ", + }, + { + .name = "zy1000_version", + .mode = COMMAND_ANY, + .jim_handler = &jim_zy1000_version, + .help = "print version info for zy1000", + }, + { + .name = "powerstatus", + .mode = COMMAND_ANY, + .jim_handler = & zylinjtag_Jim_Command_powerstatus, + .help = "print power status of target", + }, +#ifdef CYGPKG_HAL_NIOS2 + { + .name = "updatezy1000firmware", + .mode = COMMAND_ANY, + .jim_handler = &jim_zy1000_writefirmware, + .help = "writes firmware to flash", + }, +#endif + COMMAND_REGISTRATION_DONE +}; + + + +struct jtag_interface zy1000_interface = +{ + .name = "ZY1000", + .execute_queue = NULL, + .speed = zy1000_speed, + .commands = zy1000_commands, + .init = zy1000_init, + .quit = zy1000_quit, + .khz = zy1000_khz, + .speed_div = zy1000_speed_div, + .power_dropout = zy1000_power_dropout, + .srst_asserted = zy1000_srst_asserted, +}; +