From f76cf27380af20a6e1d46448c146140234d914f9 Mon Sep 17 00:00:00 2001 From: oharboe Date: Thu, 28 Feb 2008 07:25:06 +0000 Subject: [PATCH] Uwe Hermann fixed some warnings. git-svn-id: svn://svn.berlios.de/openocd/trunk@360 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/flash/s3c2412_nand.c | 173 +++--- src/flash/s3c2440_nand.c | 357 ++++++------ src/flash/s3c2443_nand.c | 177 +++--- src/jtag/amt_jtagaccel.c | 1154 ++++++++++++++++++------------------- src/jtag/gw16012.c | 1157 +++++++++++++++++++------------------- src/jtag/parport.c | 982 ++++++++++++++++---------------- 6 files changed, 1998 insertions(+), 2002 deletions(-) diff --git a/src/flash/s3c2412_nand.c b/src/flash/s3c2412_nand.c index ab7a7bed3a..6137d0d146 100644 --- a/src/flash/s3c2412_nand.c +++ b/src/flash/s3c2412_nand.c @@ -1,87 +1,86 @@ -/* src/flash/s3c2412_nand.c - * - * S3C2412 OpenOCD NAND Flash controller support. - * - * Copyright 2007,2008 Ben Dooks - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "replacements.h" -#include "log.h" - -#include -#include - -#include "nand.h" -#include "s3c24xx_nand.h" -#include "target.h" - -int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device); -int s3c2412_init(struct nand_device_s *device); - -nand_flash_controller_t s3c2412_nand_controller = -{ - .name = "s3c2412", - .nand_device_command = s3c2412_nand_device_command, - .register_commands = s3c24xx_register_commands, - .init = s3c2412_init, - .reset = s3c24xx_reset, - .command = s3c24xx_command, - .address = s3c24xx_address, - .write_data = s3c24xx_write_data, - .read_data = s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = s3c2440_write_block_data, - .read_block_data = s3c2440_read_block_data, - .controller_ready = s3c24xx_controller_ready, - .nand_ready = s3c2440_nand_ready, -}; - -int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, - char **args, int argc, - struct nand_device_s *device) -{ - s3c24xx_nand_controller_t *info; - - info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device); - if (info == NULL) { - return ERROR_NAND_DEVICE_INVALID; - } - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2412_NFSTAT; - - return ERROR_OK; -} - -int s3c2412_init(struct nand_device_s *device) -{ - s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; - target_t *target = s3c24xx_info->target; - u32 version; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7)); - - target_write_u32(target, S3C2440_NFCONT, - S3C2412_NFCONT_INIT_MAIN_ECC | - S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} +/* src/flash/s3c2412_nand.c + * + * S3C2412 OpenOCD NAND Flash controller support. + * + * Copyright 2007,2008 Ben Dooks + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Many thanks to Simtec Electronics for sponsoring this work. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" +#include "log.h" + +#include +#include + +#include "nand.h" +#include "s3c24xx_nand.h" +#include "target.h" + +int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device); +int s3c2412_init(struct nand_device_s *device); + +nand_flash_controller_t s3c2412_nand_controller = +{ + .name = "s3c2412", + .nand_device_command = s3c2412_nand_device_command, + .register_commands = s3c24xx_register_commands, + .init = s3c2412_init, + .reset = s3c24xx_reset, + .command = s3c24xx_command, + .address = s3c24xx_address, + .write_data = s3c24xx_write_data, + .read_data = s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = s3c2440_write_block_data, + .read_block_data = s3c2440_read_block_data, + .controller_ready = s3c24xx_controller_ready, + .nand_ready = s3c2440_nand_ready, +}; + +int s3c2412_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, + char **args, int argc, + struct nand_device_s *device) +{ + s3c24xx_nand_controller_t *info; + + info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device); + if (info == NULL) { + return ERROR_NAND_DEVICE_INVALID; + } + + /* fill in the address fields for the core device */ + info->cmd = S3C2440_NFCMD; + info->addr = S3C2440_NFADDR; + info->data = S3C2440_NFDATA; + info->nfstat = S3C2412_NFSTAT; + + return ERROR_OK; +} + +int s3c2412_init(struct nand_device_s *device) +{ + s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; + target_t *target = s3c24xx_info->target; + + target_write_u32(target, S3C2410_NFCONF, + S3C2440_NFCONF_TACLS(3) | + S3C2440_NFCONF_TWRPH0(7) | + S3C2440_NFCONF_TWRPH1(7)); + + target_write_u32(target, S3C2440_NFCONT, + S3C2412_NFCONT_INIT_MAIN_ECC | + S3C2440_NFCONT_ENABLE); + + return ERROR_OK; +} diff --git a/src/flash/s3c2440_nand.c b/src/flash/s3c2440_nand.c index 4e3234f8a4..f08e76104c 100644 --- a/src/flash/s3c2440_nand.c +++ b/src/flash/s3c2440_nand.c @@ -1,179 +1,178 @@ -/* src/flash/s3c2440_nand.c - * - * S3C2440 OpenOCD NAND Flash controller support. - * - * Copyright 2007,2008 Ben Dooks - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "replacements.h" -#include "log.h" - -#include -#include - -#include "nand.h" -#include "s3c24xx_nand.h" -#include "target.h" - -int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device); -int s3c2440_init(struct nand_device_s *device); -int s3c2440_nand_ready(struct nand_device_s *device, int timeout); - -nand_flash_controller_t s3c2440_nand_controller = -{ - .name = "s3c2440", - .nand_device_command = s3c2440_nand_device_command, - .register_commands = s3c24xx_register_commands, - .init = s3c2440_init, - .reset = s3c24xx_reset, - .command = s3c24xx_command, - .address = s3c24xx_address, - .write_data = s3c24xx_write_data, - .read_data = s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = s3c2440_write_block_data, - .read_block_data = s3c2440_read_block_data, - .controller_ready = s3c24xx_controller_ready, - .nand_ready = s3c2440_nand_ready, -}; - -int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, - char **args, int argc, - struct nand_device_s *device) -{ - s3c24xx_nand_controller_t *info; - - info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device); - if (info == NULL) { - return ERROR_NAND_DEVICE_INVALID; - } - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2440_NFSTAT; - - return ERROR_OK; -} - -int s3c2440_init(struct nand_device_s *device) -{ - s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; - target_t *target = s3c24xx_info->target; - u32 version; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7)); - - target_write_u32(target, S3C2440_NFCONT, - S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} - -int s3c2440_nand_ready(struct nand_device_s *device, int timeout) -{ - s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; - target_t *target = s3c24xx_info->target; - u8 status; - - if (target->state != TARGET_HALTED) { - ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - do { - target_read_u8(target, s3c24xx_info->nfstat, &status); - - if (status & S3C2440_NFSTAT_READY) - return 1; - - usleep(1000); - } while (timeout-- > 0); - - - return 0; -} - -/* use the fact we can read/write 4 bytes in one go via a single 32bit op */ - -int s3c2440_read_block_data(struct nand_device_s *device, u8 *data, int data_size) -{ - s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; - target_t *target = s3c24xx_info->target; - u32 nfdata = s3c24xx_info->data; - u32 tmp; - - INFO("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size); - - if (target->state != TARGET_HALTED) { - ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - while (data_size >= 4) { - target_read_u32(target, nfdata, &tmp); - - data[0] = tmp; - data[1] = tmp >> 8; - data[2] = tmp >> 16; - data[3] = tmp >> 24; - - data_size -= 4; - data += 4; - } - - while (data_size > 0) { - target_read_u8(target, nfdata, data); - - data_size -= 1; - data += 1; - } - - return ERROR_OK; -} - -int s3c2440_write_block_data(struct nand_device_s *device, u8 *data, int data_size) -{ - s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; - target_t *target = s3c24xx_info->target; - u32 nfdata = s3c24xx_info->data; - u32 tmp; - - if (target->state != TARGET_HALTED) { - ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - while (data_size >= 4) { - tmp = le_to_h_u32(data); - target_write_u32(target, nfdata, tmp); - - data_size -= 4; - data += 4; - } - - while (data_size > 0) { - target_write_u8(target, nfdata, *data); - - data_size -= 1; - data += 1; - } - - return ERROR_OK; -} +/* src/flash/s3c2440_nand.c + * + * S3C2440 OpenOCD NAND Flash controller support. + * + * Copyright 2007,2008 Ben Dooks + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Many thanks to Simtec Electronics for sponsoring this work. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" +#include "log.h" + +#include +#include + +#include "nand.h" +#include "s3c24xx_nand.h" +#include "target.h" + +int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device); +int s3c2440_init(struct nand_device_s *device); +int s3c2440_nand_ready(struct nand_device_s *device, int timeout); + +nand_flash_controller_t s3c2440_nand_controller = +{ + .name = "s3c2440", + .nand_device_command = s3c2440_nand_device_command, + .register_commands = s3c24xx_register_commands, + .init = s3c2440_init, + .reset = s3c24xx_reset, + .command = s3c24xx_command, + .address = s3c24xx_address, + .write_data = s3c24xx_write_data, + .read_data = s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = s3c2440_write_block_data, + .read_block_data = s3c2440_read_block_data, + .controller_ready = s3c24xx_controller_ready, + .nand_ready = s3c2440_nand_ready, +}; + +int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, + char **args, int argc, + struct nand_device_s *device) +{ + s3c24xx_nand_controller_t *info; + + info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device); + if (info == NULL) { + return ERROR_NAND_DEVICE_INVALID; + } + + /* fill in the address fields for the core device */ + info->cmd = S3C2440_NFCMD; + info->addr = S3C2440_NFADDR; + info->data = S3C2440_NFDATA; + info->nfstat = S3C2440_NFSTAT; + + return ERROR_OK; +} + +int s3c2440_init(struct nand_device_s *device) +{ + s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; + target_t *target = s3c24xx_info->target; + + target_write_u32(target, S3C2410_NFCONF, + S3C2440_NFCONF_TACLS(3) | + S3C2440_NFCONF_TWRPH0(7) | + S3C2440_NFCONF_TWRPH1(7)); + + target_write_u32(target, S3C2440_NFCONT, + S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE); + + return ERROR_OK; +} + +int s3c2440_nand_ready(struct nand_device_s *device, int timeout) +{ + s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; + target_t *target = s3c24xx_info->target; + u8 status; + + if (target->state != TARGET_HALTED) { + ERROR("target must be halted to use S3C24XX NAND flash controller"); + return ERROR_NAND_OPERATION_FAILED; + } + + do { + target_read_u8(target, s3c24xx_info->nfstat, &status); + + if (status & S3C2440_NFSTAT_READY) + return 1; + + usleep(1000); + } while (timeout-- > 0); + + + return 0; +} + +/* use the fact we can read/write 4 bytes in one go via a single 32bit op */ + +int s3c2440_read_block_data(struct nand_device_s *device, u8 *data, int data_size) +{ + s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; + target_t *target = s3c24xx_info->target; + u32 nfdata = s3c24xx_info->data; + u32 tmp; + + INFO("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size); + + if (target->state != TARGET_HALTED) { + ERROR("target must be halted to use S3C24XX NAND flash controller"); + return ERROR_NAND_OPERATION_FAILED; + } + + while (data_size >= 4) { + target_read_u32(target, nfdata, &tmp); + + data[0] = tmp; + data[1] = tmp >> 8; + data[2] = tmp >> 16; + data[3] = tmp >> 24; + + data_size -= 4; + data += 4; + } + + while (data_size > 0) { + target_read_u8(target, nfdata, data); + + data_size -= 1; + data += 1; + } + + return ERROR_OK; +} + +int s3c2440_write_block_data(struct nand_device_s *device, u8 *data, int data_size) +{ + s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; + target_t *target = s3c24xx_info->target; + u32 nfdata = s3c24xx_info->data; + u32 tmp; + + if (target->state != TARGET_HALTED) { + ERROR("target must be halted to use S3C24XX NAND flash controller"); + return ERROR_NAND_OPERATION_FAILED; + } + + while (data_size >= 4) { + tmp = le_to_h_u32(data); + target_write_u32(target, nfdata, tmp); + + data_size -= 4; + data += 4; + } + + while (data_size > 0) { + target_write_u8(target, nfdata, *data); + + data_size -= 1; + data += 1; + } + + return ERROR_OK; +} diff --git a/src/flash/s3c2443_nand.c b/src/flash/s3c2443_nand.c index 56e84b6800..a17ae7e18f 100644 --- a/src/flash/s3c2443_nand.c +++ b/src/flash/s3c2443_nand.c @@ -1,89 +1,88 @@ -/* src/flash/s3c2443_nand.c - * - * S3C2443 OpenOCD NAND Flash controller support. - * - * Copyright 2007,2008 Ben Dooks - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "replacements.h" -#include "log.h" - -#include -#include - -#include "nand.h" -#include "s3c24xx_nand.h" -#include "target.h" - -int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device); -int s3c2443_init(struct nand_device_s *device); -int s3c2443_nand_ready(struct nand_device_s *device, int timeout); - -nand_flash_controller_t s3c2443_nand_controller = -{ - .name = "s3c2443", - .nand_device_command = s3c2443_nand_device_command, - .register_commands = s3c24xx_register_commands, - .init = s3c2443_init, - .reset = s3c24xx_reset, - .command = s3c24xx_command, - .address = s3c24xx_address, - .write_data = s3c24xx_write_data, - .read_data = s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = s3c2440_write_block_data, - .read_block_data = s3c2440_read_block_data, - .controller_ready = s3c24xx_controller_ready, - .nand_ready = s3c2440_nand_ready, -}; - -int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, - char **args, int argc, - struct nand_device_s *device) -{ - s3c24xx_nand_controller_t *info; - - info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device); - if (info == NULL) { - return ERROR_NAND_DEVICE_INVALID; - } - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2412_NFSTAT; - - return ERROR_OK; -} - -int s3c2443_init(struct nand_device_s *device) -{ - s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; - target_t *target = s3c24xx_info->target; - u32 version; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7)); - - target_write_u32(target, S3C2440_NFCONT, - S3C2412_NFCONT_INIT_MAIN_ECC | - S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} +/* src/flash/s3c2443_nand.c + * + * S3C2443 OpenOCD NAND Flash controller support. + * + * Copyright 2007,2008 Ben Dooks + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Many thanks to Simtec Electronics for sponsoring this work. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" +#include "log.h" + +#include +#include + +#include "nand.h" +#include "s3c24xx_nand.h" +#include "target.h" + +int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device); +int s3c2443_init(struct nand_device_s *device); +int s3c2443_nand_ready(struct nand_device_s *device, int timeout); + +nand_flash_controller_t s3c2443_nand_controller = +{ + .name = "s3c2443", + .nand_device_command = s3c2443_nand_device_command, + .register_commands = s3c24xx_register_commands, + .init = s3c2443_init, + .reset = s3c24xx_reset, + .command = s3c24xx_command, + .address = s3c24xx_address, + .write_data = s3c24xx_write_data, + .read_data = s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = s3c2440_write_block_data, + .read_block_data = s3c2440_read_block_data, + .controller_ready = s3c24xx_controller_ready, + .nand_ready = s3c2440_nand_ready, +}; + +int s3c2443_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, + char **args, int argc, + struct nand_device_s *device) +{ + s3c24xx_nand_controller_t *info; + + info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device); + if (info == NULL) { + return ERROR_NAND_DEVICE_INVALID; + } + + /* fill in the address fields for the core device */ + info->cmd = S3C2440_NFCMD; + info->addr = S3C2440_NFADDR; + info->data = S3C2440_NFDATA; + info->nfstat = S3C2412_NFSTAT; + + return ERROR_OK; +} + +int s3c2443_init(struct nand_device_s *device) +{ + s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; + target_t *target = s3c24xx_info->target; + + target_write_u32(target, S3C2410_NFCONF, + S3C2440_NFCONF_TACLS(3) | + S3C2440_NFCONF_TWRPH0(7) | + S3C2440_NFCONF_TWRPH1(7)); + + target_write_u32(target, S3C2440_NFCONT, + S3C2412_NFCONT_INIT_MAIN_ECC | + S3C2440_NFCONT_ENABLE); + + return ERROR_OK; +} diff --git a/src/jtag/amt_jtagaccel.c b/src/jtag/amt_jtagaccel.c index 500f1797d6..dc40226d31 100644 --- a/src/jtag/amt_jtagaccel.c +++ b/src/jtag/amt_jtagaccel.c @@ -1,577 +1,577 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "replacements.h" - -#include "jtag.h" - -/* system includes */ - -#ifdef _WIN32 -#include "errno.h" -#endif /* _WIN32 */ - -#include -#include - -#include -#include - -#if PARPORT_USE_PPDEV == 1 -#include -#include -#include -#include -#include -#else /* not PARPORT_USE_PPDEV */ -#ifndef _WIN32 -#include -#endif -#endif - -#if PARPORT_USE_GIVEIO == 1 -#if IS_CYGWIN == 1 -#include -#include -#undef ERROR -#endif -#endif - -#include "log.h" - -/* configuration */ -unsigned long amt_jtagaccel_port; - -/* interface variables - */ -static u8 aw_control_rst = 0x00; -static u8 aw_control_fsm = 0x10; -static u8 aw_control_baudrate = 0x20; - -static int rtck_enabled = 0; - -#if PARPORT_USE_PPDEV == 1 -static int device_handle; -int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR ; -int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA ; -#define AMT_AW(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0) -#define AMT_AR(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0) -#define AMT_DW(val) do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0) -#define AMT_DR(val) do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0) -#else -#define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0) -#define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0) -#define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0) -#define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0) -#endif - -int amt_jtagaccel_execute_queue(void); -int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx); -int amt_jtagaccel_speed(int speed); -int amt_jtagaccel_init(void); -int amt_jtagaccel_quit(void); - -int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); - -/* tap_move[i][j]: tap movement command to go from state i to state j - * 0: Test-Logic-Reset - * 1: Run-Test/Idle - * 2: Shift-DR - * 3: Pause-DR - * 4: Shift-IR - * 5: Pause-IR - */ -u8 amt_jtagaccel_tap_move[6][6][2] = -{ - /* TLR RTI SD PD SI PI */ - {{0x1f, 0x00}, {0x0f, 0x00}, {0x8a, 0x04}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* TLR */ - {{0x1f, 0x00}, {0x00, 0x00}, {0x85, 0x08}, {0x05, 0x00}, {0x8b, 0x08}, {0x0b, 0x00}}, /* RTI */ - {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* SD */ - {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* PD */ - {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* SI */ - {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* PI */ -}; - -jtag_interface_t amt_jtagaccel_interface = -{ - .name = "amt_jtagaccel", - - .execute_queue = amt_jtagaccel_execute_queue, - - .speed = amt_jtagaccel_speed, - .register_commands = amt_jtagaccel_register_commands, - .init = amt_jtagaccel_init, - .quit = amt_jtagaccel_quit, -}; - -int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx) -{ - register_command(cmd_ctx, NULL, "parport_port", amt_jtagaccel_handle_parport_port_command, - COMMAND_CONFIG, NULL); - register_command(cmd_ctx, NULL, "rtck", amt_jtagaccel_handle_rtck_command, - COMMAND_CONFIG, NULL); - - return ERROR_OK; -} - -void amt_jtagaccel_reset(int trst, int srst) -{ - if (trst == 1) - aw_control_rst |= 0x4; - else if (trst == 0) - aw_control_rst &= ~0x4; - - if (srst == 1) - aw_control_rst |= 0x1; - else if (srst == 0) - aw_control_rst &= ~0x1; - - AMT_AW(aw_control_rst); -} - -int amt_jtagaccel_speed(int speed) -{ - aw_control_baudrate &= 0xf0; - aw_control_baudrate |= speed & 0x0f; - AMT_AW(aw_control_baudrate); - - return ERROR_OK; -} - -void amt_jtagaccel_end_state(state) -{ - if (tap_move_map[state] != -1) - end_state = state; - else - { - ERROR("BUG: %i is not a valid end state", state); - exit(-1); - } -} - -void amt_wait_scan_busy() -{ - int timeout = 4096; - u8 ar_status; - - AMT_AR(ar_status); - while (((ar_status) & 0x80) && (timeout-- > 0)) - AMT_AR(ar_status); - - if (ar_status & 0x80) - { - ERROR("amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x", (rtck_enabled) ? "enabled" : "disabled", ar_status); - exit(-1); - } -} - -void amt_jtagaccel_state_move(void) -{ - u8 aw_scan_tms_5; - u8 tms_scan[2]; - - tms_scan[0] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][0]; - tms_scan[1] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][1]; - - aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f); - AMT_AW(aw_scan_tms_5); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if (tms_scan[0] & 0x80) - { - aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f); - AMT_AW(aw_scan_tms_5); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - } - - cur_state = end_state; -} - -void amt_jtagaccel_runtest(int num_cycles) -{ - int i = 0; - u8 aw_scan_tms_5; - u8 aw_scan_tms_1to4; - - enum tap_state saved_end_state = end_state; - - /* only do a state_move when we're not already in RTI */ - if (cur_state != TAP_RTI) - { - amt_jtagaccel_end_state(TAP_RTI); - amt_jtagaccel_state_move(); - } - - while (num_cycles - i >= 5) - { - aw_scan_tms_5 = 0x40; - AMT_AW(aw_scan_tms_5); - i += 5; - } - - if (num_cycles - i > 0) - { - aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4; - AMT_AW(aw_scan_tms_1to4); - } - - amt_jtagaccel_end_state(saved_end_state); - if (cur_state != end_state) - amt_jtagaccel_state_move(); -} - -void amt_jtagaccel_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) -{ - int bits_left = scan_size; - int bit_count = 0; - enum tap_state saved_end_state = end_state; - u8 aw_tdi_option; - u8 dw_tdi_scan; - u8 dr_tdo; - u8 aw_tms_scan; - u8 tms_scan[2]; - - if (ir_scan) - amt_jtagaccel_end_state(TAP_SI); - else - amt_jtagaccel_end_state(TAP_SD); - - amt_jtagaccel_state_move(); - amt_jtagaccel_end_state(saved_end_state); - - /* handle unaligned bits at the beginning */ - if ((scan_size - 1) % 8) - { - aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1); - AMT_AW(aw_tdi_option); - - dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff; - AMT_DW(dw_tdi_scan); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if ((type == SCAN_IN) || (type == SCAN_IO)) - { - AMT_DR(dr_tdo); - dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8)); - buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo); - } - - bit_count += (scan_size - 1) % 8; - bits_left -= (scan_size - 1) % 8; - } - - while (bits_left - 1 >= 8) - { - dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff; - AMT_DW(dw_tdi_scan); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if ((type == SCAN_IN) || (type == SCAN_IO)) - { - AMT_DR(dr_tdo); - buf_set_u32(buffer, bit_count, 8, dr_tdo); - } - - bit_count += 8; - bits_left -= 8; - } - - tms_scan[0] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][0]; - tms_scan[1] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][1]; - aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5); - AMT_AW(aw_tms_scan); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if ((type == SCAN_IN) || (type == SCAN_IO)) - { - AMT_DR(dr_tdo); - dr_tdo = dr_tdo >> 7; - buf_set_u32(buffer, bit_count, 1, dr_tdo); - } - - if (tms_scan[0] & 0x80) - { - aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f); - AMT_AW(aw_tms_scan); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - } - cur_state = end_state; -} - -int amt_jtagaccel_execute_queue(void) -{ - jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - u8 *buffer; - int retval; - - /* return ERROR_OK, unless a jtag_read_buffer returns a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - while (cmd) - { - switch (cmd->type) - { - case JTAG_END_STATE: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("end_state: %i", cmd->cmd.end_state->end_state); -#endif - if (cmd->cmd.end_state->end_state != -1) - amt_jtagaccel_end_state(cmd->cmd.end_state->end_state); - break; - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); -#endif - if (cmd->cmd.reset->trst == 1) - { - cur_state = TAP_TLR; - } - amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); -#endif - if (cmd->cmd.runtest->end_state != -1) - amt_jtagaccel_end_state(cmd->cmd.runtest->end_state); - amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_STATEMOVE: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - if (cmd->cmd.statemove->end_state != -1) - amt_jtagaccel_end_state(cmd->cmd.statemove->end_state); - amt_jtagaccel_state_move(); - break; - case JTAG_SCAN: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("scan end in %i", cmd->cmd.scan->end_state); -#endif - if (cmd->cmd.scan->end_state != -1) - amt_jtagaccel_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("sleep %i", cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return retval; -} - -#if PARPORT_USE_GIVEIO == 1 -int amt_jtagaccel_get_giveio_access() -{ - HANDLE h; - OSVERSIONINFO version; - - version.dwOSVersionInfoSize = sizeof version; - if (!GetVersionEx( &version )) { - errno = EINVAL; - return -1; - } - if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) - return 0; - - h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - if (h == INVALID_HANDLE_VALUE) { - errno = ENODEV; - return -1; - } - - CloseHandle( h ); - - return 0; -} -#endif - -int amt_jtagaccel_init(void) -{ -#if PARPORT_USE_PPDEV == 1 - char buffer[256]; - int i = 0; - u8 control_port; -#else - u8 status_port; -#endif - u8 ar_status; - -#if PARPORT_USE_PPDEV == 1 - if (device_handle > 0) - { - ERROR("device is already opened"); - return ERROR_JTAG_INIT_FAILED; - } - - snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port); - device_handle = open(buffer, O_RDWR); - - if (device_handle < 0) - { - ERROR("cannot open device. check it exists and that user read and write rights are set"); - return ERROR_JTAG_INIT_FAILED; - } - - i = ioctl(device_handle, PPCLAIM); - if (i < 0) - { - ERROR("cannot claim device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = IEEE1284_MODE_EPP; - i = ioctl(device_handle, PPSETMODE, & i); - if (i < 0) - { - ERROR(" cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - - control_port = 0x00; - i = ioctl(device_handle, PPWCONTROL, &control_port); - - control_port = 0x04; - i = ioctl(device_handle, PPWCONTROL, &control_port); - -#else - if (amt_jtagaccel_port == 0) - { - amt_jtagaccel_port = 0x378; - WARNING("No parport port specified, using default '0x378' (LPT1)"); - } - -#if PARPORT_USE_GIVEIO == 1 - if (amt_jtagaccel_get_giveio_access() != 0) { -#else /* PARPORT_USE_GIVEIO */ - if (ioperm(amt_jtagaccel_port, 5, 1) != 0) { -#endif /* PARPORT_USE_GIVEIO */ - ERROR("missing privileges for direct i/o"); - return ERROR_JTAG_INIT_FAILED; - } - - /* prepare epp port */ - /* clear timeout */ - status_port = inb(amt_jtagaccel_port + 1); - outb(status_port | 0x1, amt_jtagaccel_port + 1); - - /* reset epp port */ - outb(0x00, amt_jtagaccel_port + 2); - outb(0x04, amt_jtagaccel_port + 2); -#endif - - if (rtck_enabled) - { - /* set RTCK enable bit */ - aw_control_fsm |= 0x02; - } - - /* enable JTAG port */ - aw_control_fsm |= 0x04; - AMT_AW(aw_control_fsm); - - amt_jtagaccel_speed(jtag_speed); - - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - aw_control_rst &= ~0x8; - else - aw_control_rst |= 0x8; - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - aw_control_rst &= ~0x2; - else - aw_control_rst |= 0x2; - - amt_jtagaccel_reset(0, 0); - - /* read status register */ - AMT_AR(ar_status); - DEBUG("AR_STATUS: 0x%2.2x", ar_status); - - return ERROR_OK; -} - -int amt_jtagaccel_quit(void) -{ - - return ERROR_OK; -} - -int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) -{ - if (argc == 0) - return ERROR_OK; - - /* only if the port wasn't overwritten by cmdline */ - if (amt_jtagaccel_port == 0) - amt_jtagaccel_port = strtoul(args[0], NULL, 0); - - return ERROR_OK; -} - -int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) -{ - if (argc == 0) - { - command_print(cmd_ctx, "amt_jtagaccel RTCK feature %s", (rtck_enabled) ? "enabled" : "disabled"); - return ERROR_OK; - } - else - { - if (strcmp(args[0], "enabled") == 0) - { - rtck_enabled = 1; - } - else - { - rtck_enabled = 0; - } - } - - return ERROR_OK; -} +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" + +#include "jtag.h" + +/* system includes */ + +#ifdef _WIN32 +#include "errno.h" +#endif /* _WIN32 */ + +#include +#include + +#include +#include + +#if PARPORT_USE_PPDEV == 1 +#include +#include +#include +#include +#include +#else /* not PARPORT_USE_PPDEV */ +#ifndef _WIN32 +#include +#endif +#endif + +#if PARPORT_USE_GIVEIO == 1 +#if IS_CYGWIN == 1 +#include +#include +#undef ERROR +#endif +#endif + +#include "log.h" + +/* configuration */ +u16 amt_jtagaccel_port; + +/* interface variables + */ +static u8 aw_control_rst = 0x00; +static u8 aw_control_fsm = 0x10; +static u8 aw_control_baudrate = 0x20; + +static int rtck_enabled = 0; + +#if PARPORT_USE_PPDEV == 1 +static int device_handle; +int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR ; +int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA ; +#define AMT_AW(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0) +#define AMT_AR(val) do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0) +#define AMT_DW(val) do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0) +#define AMT_DR(val) do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0) +#else +#define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0) +#define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0) +#define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0) +#define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0) +#endif + +int amt_jtagaccel_execute_queue(void); +int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx); +int amt_jtagaccel_speed(int speed); +int amt_jtagaccel_init(void); +int amt_jtagaccel_quit(void); + +int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); + +/* tap_move[i][j]: tap movement command to go from state i to state j + * 0: Test-Logic-Reset + * 1: Run-Test/Idle + * 2: Shift-DR + * 3: Pause-DR + * 4: Shift-IR + * 5: Pause-IR + */ +u8 amt_jtagaccel_tap_move[6][6][2] = +{ + /* TLR RTI SD PD SI PI */ + {{0x1f, 0x00}, {0x0f, 0x00}, {0x8a, 0x04}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}}, /* TLR */ + {{0x1f, 0x00}, {0x00, 0x00}, {0x85, 0x08}, {0x05, 0x00}, {0x8b, 0x08}, {0x0b, 0x00}}, /* RTI */ + {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* SD */ + {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}}, /* PD */ + {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}}, /* SI */ + {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}}, /* PI */ +}; + +jtag_interface_t amt_jtagaccel_interface = +{ + .name = "amt_jtagaccel", + + .execute_queue = amt_jtagaccel_execute_queue, + + .speed = amt_jtagaccel_speed, + .register_commands = amt_jtagaccel_register_commands, + .init = amt_jtagaccel_init, + .quit = amt_jtagaccel_quit, +}; + +int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx) +{ + register_command(cmd_ctx, NULL, "parport_port", amt_jtagaccel_handle_parport_port_command, + COMMAND_CONFIG, NULL); + register_command(cmd_ctx, NULL, "rtck", amt_jtagaccel_handle_rtck_command, + COMMAND_CONFIG, NULL); + + return ERROR_OK; +} + +void amt_jtagaccel_reset(int trst, int srst) +{ + if (trst == 1) + aw_control_rst |= 0x4; + else if (trst == 0) + aw_control_rst &= ~0x4; + + if (srst == 1) + aw_control_rst |= 0x1; + else if (srst == 0) + aw_control_rst &= ~0x1; + + AMT_AW(aw_control_rst); +} + +int amt_jtagaccel_speed(int speed) +{ + aw_control_baudrate &= 0xf0; + aw_control_baudrate |= speed & 0x0f; + AMT_AW(aw_control_baudrate); + + return ERROR_OK; +} + +void amt_jtagaccel_end_state(state) +{ + if (tap_move_map[state] != -1) + end_state = state; + else + { + ERROR("BUG: %i is not a valid end state", state); + exit(-1); + } +} + +void amt_wait_scan_busy() +{ + int timeout = 4096; + u8 ar_status; + + AMT_AR(ar_status); + while (((ar_status) & 0x80) && (timeout-- > 0)) + AMT_AR(ar_status); + + if (ar_status & 0x80) + { + ERROR("amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x", (rtck_enabled) ? "enabled" : "disabled", ar_status); + exit(-1); + } +} + +void amt_jtagaccel_state_move(void) +{ + u8 aw_scan_tms_5; + u8 tms_scan[2]; + + tms_scan[0] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][0]; + tms_scan[1] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][1]; + + aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f); + AMT_AW(aw_scan_tms_5); + if (jtag_speed > 3 || rtck_enabled) + amt_wait_scan_busy(); + + if (tms_scan[0] & 0x80) + { + aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f); + AMT_AW(aw_scan_tms_5); + if (jtag_speed > 3 || rtck_enabled) + amt_wait_scan_busy(); + } + + cur_state = end_state; +} + +void amt_jtagaccel_runtest(int num_cycles) +{ + int i = 0; + u8 aw_scan_tms_5; + u8 aw_scan_tms_1to4; + + enum tap_state saved_end_state = end_state; + + /* only do a state_move when we're not already in RTI */ + if (cur_state != TAP_RTI) + { + amt_jtagaccel_end_state(TAP_RTI); + amt_jtagaccel_state_move(); + } + + while (num_cycles - i >= 5) + { + aw_scan_tms_5 = 0x40; + AMT_AW(aw_scan_tms_5); + i += 5; + } + + if (num_cycles - i > 0) + { + aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4; + AMT_AW(aw_scan_tms_1to4); + } + + amt_jtagaccel_end_state(saved_end_state); + if (cur_state != end_state) + amt_jtagaccel_state_move(); +} + +void amt_jtagaccel_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) +{ + int bits_left = scan_size; + int bit_count = 0; + enum tap_state saved_end_state = end_state; + u8 aw_tdi_option; + u8 dw_tdi_scan; + u8 dr_tdo; + u8 aw_tms_scan; + u8 tms_scan[2]; + + if (ir_scan) + amt_jtagaccel_end_state(TAP_SI); + else + amt_jtagaccel_end_state(TAP_SD); + + amt_jtagaccel_state_move(); + amt_jtagaccel_end_state(saved_end_state); + + /* handle unaligned bits at the beginning */ + if ((scan_size - 1) % 8) + { + aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1); + AMT_AW(aw_tdi_option); + + dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff; + AMT_DW(dw_tdi_scan); + if (jtag_speed > 3 || rtck_enabled) + amt_wait_scan_busy(); + + if ((type == SCAN_IN) || (type == SCAN_IO)) + { + AMT_DR(dr_tdo); + dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8)); + buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo); + } + + bit_count += (scan_size - 1) % 8; + bits_left -= (scan_size - 1) % 8; + } + + while (bits_left - 1 >= 8) + { + dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff; + AMT_DW(dw_tdi_scan); + if (jtag_speed > 3 || rtck_enabled) + amt_wait_scan_busy(); + + if ((type == SCAN_IN) || (type == SCAN_IO)) + { + AMT_DR(dr_tdo); + buf_set_u32(buffer, bit_count, 8, dr_tdo); + } + + bit_count += 8; + bits_left -= 8; + } + + tms_scan[0] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][0]; + tms_scan[1] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][1]; + aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5); + AMT_AW(aw_tms_scan); + if (jtag_speed > 3 || rtck_enabled) + amt_wait_scan_busy(); + + if ((type == SCAN_IN) || (type == SCAN_IO)) + { + AMT_DR(dr_tdo); + dr_tdo = dr_tdo >> 7; + buf_set_u32(buffer, bit_count, 1, dr_tdo); + } + + if (tms_scan[0] & 0x80) + { + aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f); + AMT_AW(aw_tms_scan); + if (jtag_speed > 3 || rtck_enabled) + amt_wait_scan_busy(); + } + cur_state = end_state; +} + +int amt_jtagaccel_execute_queue(void) +{ + jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ + int scan_size; + enum scan_type type; + u8 *buffer; + int retval; + + /* return ERROR_OK, unless a jtag_read_buffer returns a failed check + * that wasn't handled by a caller-provided error handler + */ + retval = ERROR_OK; + + while (cmd) + { + switch (cmd->type) + { + case JTAG_END_STATE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("end_state: %i", cmd->cmd.end_state->end_state); +#endif + if (cmd->cmd.end_state->end_state != -1) + amt_jtagaccel_end_state(cmd->cmd.end_state->end_state); + break; + case JTAG_RESET: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); +#endif + if (cmd->cmd.reset->trst == 1) + { + cur_state = TAP_TLR; + } + amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + break; + case JTAG_RUNTEST: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); +#endif + if (cmd->cmd.runtest->end_state != -1) + amt_jtagaccel_end_state(cmd->cmd.runtest->end_state); + amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles); + break; + case JTAG_STATEMOVE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); +#endif + if (cmd->cmd.statemove->end_state != -1) + amt_jtagaccel_end_state(cmd->cmd.statemove->end_state); + amt_jtagaccel_state_move(); + break; + case JTAG_SCAN: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("scan end in %i", cmd->cmd.scan->end_state); +#endif + if (cmd->cmd.scan->end_state != -1) + amt_jtagaccel_end_state(cmd->cmd.scan->end_state); + scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); + type = jtag_scan_type(cmd->cmd.scan); + amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); + if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) + retval = ERROR_JTAG_QUEUE_FAILED; + if (buffer) + free(buffer); + break; + case JTAG_SLEEP: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("sleep %i", cmd->cmd.sleep->us); +#endif + jtag_sleep(cmd->cmd.sleep->us); + break; + default: + ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } + cmd = cmd->next; + } + + return retval; +} + +#if PARPORT_USE_GIVEIO == 1 +int amt_jtagaccel_get_giveio_access() +{ + HANDLE h; + OSVERSIONINFO version; + + version.dwOSVersionInfoSize = sizeof version; + if (!GetVersionEx( &version )) { + errno = EINVAL; + return -1; + } + if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) + return 0; + + h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + if (h == INVALID_HANDLE_VALUE) { + errno = ENODEV; + return -1; + } + + CloseHandle( h ); + + return 0; +} +#endif + +int amt_jtagaccel_init(void) +{ +#if PARPORT_USE_PPDEV == 1 + char buffer[256]; + int i = 0; + u8 control_port; +#else + u8 status_port; +#endif + u8 ar_status; + +#if PARPORT_USE_PPDEV == 1 + if (device_handle > 0) + { + ERROR("device is already opened"); + return ERROR_JTAG_INIT_FAILED; + } + + snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port); + device_handle = open(buffer, O_RDWR); + + if (device_handle < 0) + { + ERROR("cannot open device. check it exists and that user read and write rights are set"); + return ERROR_JTAG_INIT_FAILED; + } + + i = ioctl(device_handle, PPCLAIM); + if (i < 0) + { + ERROR("cannot claim device"); + return ERROR_JTAG_INIT_FAILED; + } + + i = IEEE1284_MODE_EPP; + i = ioctl(device_handle, PPSETMODE, & i); + if (i < 0) + { + ERROR(" cannot set compatible mode to device"); + return ERROR_JTAG_INIT_FAILED; + } + + control_port = 0x00; + i = ioctl(device_handle, PPWCONTROL, &control_port); + + control_port = 0x04; + i = ioctl(device_handle, PPWCONTROL, &control_port); + +#else + if (amt_jtagaccel_port == 0) + { + amt_jtagaccel_port = 0x378; + WARNING("No parport port specified, using default '0x378' (LPT1)"); + } + +#if PARPORT_USE_GIVEIO == 1 + if (amt_jtagaccel_get_giveio_access() != 0) { +#else /* PARPORT_USE_GIVEIO */ + if (ioperm(amt_jtagaccel_port, 5, 1) != 0) { +#endif /* PARPORT_USE_GIVEIO */ + ERROR("missing privileges for direct i/o"); + return ERROR_JTAG_INIT_FAILED; + } + + /* prepare epp port */ + /* clear timeout */ + status_port = inb(amt_jtagaccel_port + 1); + outb(status_port | 0x1, amt_jtagaccel_port + 1); + + /* reset epp port */ + outb(0x00, amt_jtagaccel_port + 2); + outb(0x04, amt_jtagaccel_port + 2); +#endif + + if (rtck_enabled) + { + /* set RTCK enable bit */ + aw_control_fsm |= 0x02; + } + + /* enable JTAG port */ + aw_control_fsm |= 0x04; + AMT_AW(aw_control_fsm); + + amt_jtagaccel_speed(jtag_speed); + + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + aw_control_rst &= ~0x8; + else + aw_control_rst |= 0x8; + + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + aw_control_rst &= ~0x2; + else + aw_control_rst |= 0x2; + + amt_jtagaccel_reset(0, 0); + + /* read status register */ + AMT_AR(ar_status); + DEBUG("AR_STATUS: 0x%2.2x", ar_status); + + return ERROR_OK; +} + +int amt_jtagaccel_quit(void) +{ + + return ERROR_OK; +} + +int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 0) + return ERROR_OK; + + /* only if the port wasn't overwritten by cmdline */ + if (amt_jtagaccel_port == 0) + amt_jtagaccel_port = strtoul(args[0], NULL, 0); + + return ERROR_OK; +} + +int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 0) + { + command_print(cmd_ctx, "amt_jtagaccel RTCK feature %s", (rtck_enabled) ? "enabled" : "disabled"); + return ERROR_OK; + } + else + { + if (strcmp(args[0], "enabled") == 0) + { + rtck_enabled = 1; + } + else + { + rtck_enabled = 0; + } + } + + return ERROR_OK; +} diff --git a/src/jtag/gw16012.c b/src/jtag/gw16012.c index aff43de1ea..0f2cb7109e 100644 --- a/src/jtag/gw16012.c +++ b/src/jtag/gw16012.c @@ -1,579 +1,578 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "replacements.h" - -#include "jtag.h" - -#if 1 -#define _DEBUG_GW16012_IO_ -#endif - -/* system includes */ -// -ino: 060521-1036 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - -#include -#include -#include -#define ioperm(startport,length,enable)\ - i386_set_ioperm((startport), (length), (enable)) - -#else - -#ifdef _WIN32 -#include "errno.h" -#endif /* _WIN32 */ - -#endif /* __FreeBSD__, __FreeBSD_kernel__ */ - -#include -#include - -#include -#include - -#if PARPORT_USE_PPDEV == 1 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#define PPRSTATUS PPIGSTATUS -#define PPWDATA PPISDATA -#else -#include -#include -#endif -#include -#include -#else /* not PARPORT_USE_PPDEV */ -#ifndef _WIN32 -#include -#endif -#endif - -#if PARPORT_USE_GIVEIO == 1 -#if IS_CYGWIN == 1 -#include -#include -#undef ERROR -#endif -#endif - -#include "log.h" - -/* configuration */ -unsigned long gw16012_port; - -/* interface variables - */ -static u8 gw16012_msb = 0x0; -static u8 gw16012_control_value = 0x0; - -#if PARPORT_USE_PPDEV == 1 -static int device_handle; -#endif - -int gw16012_execute_queue(void); -int gw16012_register_commands(struct command_context_s *cmd_ctx); -int gw16012_speed(int speed); -int gw16012_init(void); -int gw16012_quit(void); - -int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); - -jtag_interface_t gw16012_interface = -{ - .name = "gw16012", - - .execute_queue = gw16012_execute_queue, - - .speed = gw16012_speed, - .register_commands = gw16012_register_commands, - .init = gw16012_init, - .quit = gw16012_quit, -}; - -int gw16012_register_commands(struct command_context_s *cmd_ctx) -{ - register_command(cmd_ctx, NULL, "parport_port", gw16012_handle_parport_port_command, - COMMAND_CONFIG, NULL); - - return ERROR_OK; -} - -void gw16012_data(u8 value) -{ - value = (value & 0x7f) | gw16012_msb; - gw16012_msb ^= 0x80; /* toggle MSB */ - -#ifdef _DEBUG_GW16012_IO_ - DEBUG("%2.2x", value); -#endif - - #if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPWDATA, &value); - #else - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(gw16012_port, value); - #else - outb(value, gw16012_port); - #endif - #endif -} - -void gw16012_control(u8 value) -{ - if (value != gw16012_control_value) - { - gw16012_control_value = value; - -#ifdef _DEBUG_GW16012_IO_ - DEBUG("%2.2x", gw16012_control_value); -#endif - - #if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPWCONTROL, &gw16012_control_value); - #else - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(gw16012_port + 2, gw16012_control_value); - #else - outb(gw16012_control_value, gw16012_port + 2); - #endif - #endif - } -} - -void gw16012_input(u8 *value) -{ - #if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPRSTATUS, value); - #else - *value = inb(gw16012_port + 1); - #endif - -#ifdef _DEBUG_GW16012_IO_ - DEBUG("%2.2x", *value); -#endif -} - -/* (1) assert or (0) deassert reset lines */ -void gw16012_reset(int trst, int srst) -{ - DEBUG("trst: %i, srst: %i", trst, srst); - - if (trst == 0) - gw16012_control(0x0d); - else if (trst == 1) - gw16012_control(0x0c); - - if (srst == 0) - gw16012_control(0x0a); - else if (srst == 1) - gw16012_control(0x0b); -} - -int gw16012_speed(int speed) -{ - - return ERROR_OK; -} - -void gw16012_end_state(state) -{ - if (tap_move_map[state] != -1) - end_state = state; - else - { - ERROR("BUG: %i is not a valid end state", state); - exit(-1); - } -} - -void gw16012_state_move(void) -{ - int i=0, tms=0; - u8 tms_scan = TAP_MOVE(cur_state, end_state); - - gw16012_control(0x0); /* single-bit mode */ - - for (i = 0; i < 7; i++) - { - tms = (tms_scan >> i) & 1; - gw16012_data(tms << 1); /* output next TMS bit */ - } - - cur_state = end_state; -} - -void gw16012_path_move(pathmove_command_t *cmd) -{ - int num_states = cmd->num_states; - int state_count; - - state_count = 0; - while (num_states) - { - gw16012_control(0x0); /* single-bit mode */ - if (tap_transitions[cur_state].low == cmd->path[state_count]) - { - gw16012_data(0x0); /* TCK cycle with TMS low */ - } - else if (tap_transitions[cur_state].high == cmd->path[state_count]) - { - gw16012_data(0x2); /* TCK cycle with TMS high */ - } - else - { - ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]); - exit(-1); - } - - cur_state = cmd->path[state_count]; - state_count++; - num_states--; - } - - end_state = cur_state; -} - -void gw16012_runtest(int num_cycles) -{ - enum tap_state saved_end_state = end_state; - int i; - - /* only do a state_move when we're not already in RTI */ - if (cur_state != TAP_RTI) - { - gw16012_end_state(TAP_RTI); - gw16012_state_move(); - } - - for (i = 0; i < num_cycles; i++) - { - gw16012_control(0x0); /* single-bit mode */ - gw16012_data(0x0); /* TMS cycle with TMS low */ - } - - gw16012_end_state(saved_end_state); - if (cur_state != end_state) - gw16012_state_move(); -} - -void gw16012_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) -{ - int bits_left = scan_size; - int bit_count = 0; - enum tap_state saved_end_state = end_state; - u8 scan_out, scan_in; - - /* only if we're not already in the correct Shift state */ - if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI)))) - { - if (ir_scan) - gw16012_end_state(TAP_SI); - else - gw16012_end_state(TAP_SD); - - gw16012_state_move(); - gw16012_end_state(saved_end_state); - } - - while (type == SCAN_OUT && ((bits_left - 1) > 7)) - { - gw16012_control(0x2); /* seven-bit mode */ - scan_out = buf_get_u32(buffer, bit_count, 7); - gw16012_data(scan_out); - bit_count += 7; - bits_left -= 7; - } - - gw16012_control(0x0); /* single-bit mode */ - while (bits_left-- > 0) - { - u8 tms = 0; - - scan_out = buf_get_u32(buffer, bit_count, 1); - - if (bits_left == 0) /* last bit */ - { - if ((ir_scan && (end_state == TAP_SI)) - || (!ir_scan && (end_state == TAP_SD))) - { - tms = 0; - } - else - { - tms = 2; - } - } - - gw16012_data(scan_out | tms); - - if (type != SCAN_OUT) - { - gw16012_input(&scan_in); - buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3)); - } - - bit_count++; - } - - if (!((ir_scan && (end_state == TAP_SI)) || - (!ir_scan && (end_state == TAP_SD)))) - { - gw16012_data(0x0); - if (ir_scan) - cur_state = TAP_PI; - else - cur_state = TAP_PD; - - if (cur_state != end_state) - gw16012_state_move(); - } -} - -int gw16012_execute_queue(void) -{ - jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - u8 *buffer; - int retval; - - /* return ERROR_OK, unless a jtag_read_buffer returns a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - while (cmd) - { - switch (cmd->type) - { - case JTAG_END_STATE: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("end_state: %i", cmd->cmd.end_state->end_state); -#endif - if (cmd->cmd.end_state->end_state != -1) - gw16012_end_state(cmd->cmd.end_state->end_state); - break; - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); -#endif - if (cmd->cmd.reset->trst == 1) - { - cur_state = TAP_TLR; - } - gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); -#endif - if (cmd->cmd.runtest->end_state != -1) - gw16012_end_state(cmd->cmd.runtest->end_state); - gw16012_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_STATEMOVE: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - if (cmd->cmd.statemove->end_state != -1) - gw16012_end_state(cmd->cmd.statemove->end_state); - gw16012_state_move(); - break; - case JTAG_PATHMOVE: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); -#endif - gw16012_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: - if (cmd->cmd.scan->end_state != -1) - gw16012_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); -#ifdef _DEBUG_JTAG_IO_ - DEBUG("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr", - type, scan_size, cmd->cmd.scan->end_state); -#endif - gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - DEBUG("sleep %i", cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return retval; -} - -#if PARPORT_USE_GIVEIO == 1 -int gw16012_get_giveio_access() -{ - HANDLE h; - OSVERSIONINFO version; - - version.dwOSVersionInfoSize = sizeof version; - if (!GetVersionEx( &version )) { - errno = EINVAL; - return -1; - } - if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) - return 0; - - h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - if (h == INVALID_HANDLE_VALUE) { - errno = ENODEV; - return -1; - } - - CloseHandle( h ); - - return 0; -} -#endif - -int gw16012_init(void) -{ -#if PARPORT_USE_PPDEV == 1 - char buffer[256]; - int i = 0; - u8 control_port; -#endif - u8 status_port; - -#if PARPORT_USE_PPDEV == 1 - if (device_handle>0) - { - ERROR("device is already opened"); - return ERROR_JTAG_INIT_FAILED; - } - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - DEBUG("opening /dev/ppi%d...", gw16012_port); - - snprintf(buffer, 256, "/dev/ppi%d", gw16012_port); - device_handle = open(buffer, O_WRONLY); -#else - DEBUG("opening /dev/parport%d...", gw16012_port); - - snprintf(buffer, 256, "/dev/parport%d", gw16012_port); - device_handle = open(buffer, O_WRONLY); -#endif - if (device_handle<0) - { - ERROR("cannot open device. check it exists and that user read and write rights are set"); - return ERROR_JTAG_INIT_FAILED; - } - - DEBUG("...open"); - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - i=ioctl(device_handle, PPCLAIM); - if (i<0) - { - ERROR("cannot claim device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = PARPORT_MODE_COMPAT; - i= ioctl(device_handle, PPSETMODE, & i); - if (i<0) - { - ERROR(" cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = IEEE1284_MODE_COMPAT; - i = ioctl(device_handle, PPNEGOT, & i); - if (i<0) - { - ERROR("cannot set compatible 1284 mode to device"); - return ERROR_JTAG_INIT_FAILED; - } -#endif -#else - if (gw16012_port == 0) - { - gw16012_port = 0x378; - WARNING("No gw16012 port specified, using default '0x378' (LPT1)"); - } - - DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port); -#if PARPORT_USE_GIVEIO == 1 - if (gw16012_get_giveio_access() != 0) -#else /* PARPORT_USE_GIVEIO */ - if (ioperm(gw16012_port, 3, 1) != 0) -#endif /* PARPORT_USE_GIVEIO */ - { - ERROR("missing privileges for direct i/o"); - return ERROR_JTAG_INIT_FAILED; - } - DEBUG("...privileges granted"); - - /* make sure parallel port is in right mode (clear tristate and interrupt */ -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(gw16012_port + 2, 0x0); -#else - outb(0x0, gw16012_port + 2); -#endif -#endif /* PARPORT_USE_PPDEV */ - - gw16012_input(&status_port); - gw16012_msb = (status_port & 0x80) ^ 0x80; - - gw16012_speed(jtag_speed); - gw16012_reset(0, 0); - - return ERROR_OK; -} - -int gw16012_quit(void) -{ - - return ERROR_OK; -} - -int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) -{ - if (argc == 0) - return ERROR_OK; - - /* only if the port wasn't overwritten by cmdline */ - if (gw16012_port == 0) - gw16012_port = strtoul(args[0], NULL, 0); - - return ERROR_OK; -} +/*************************************************************************** + * Copyright (C) 2006 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" + +#include "jtag.h" + +#if 1 +#define _DEBUG_GW16012_IO_ +#endif + +/* system includes */ +// -ino: 060521-1036 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + +#include +#include +#include +#define ioperm(startport,length,enable)\ + i386_set_ioperm((startport), (length), (enable)) + +#else + +#ifdef _WIN32 +#include "errno.h" +#endif /* _WIN32 */ + +#endif /* __FreeBSD__, __FreeBSD_kernel__ */ + +#include +#include + +#include +#include + +#if PARPORT_USE_PPDEV == 1 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include +#include +#define PPRSTATUS PPIGSTATUS +#define PPWDATA PPISDATA +#else +#include +#include +#endif +#include +#include +#else /* not PARPORT_USE_PPDEV */ +#ifndef _WIN32 +#include +#endif +#endif + +#if PARPORT_USE_GIVEIO == 1 +#if IS_CYGWIN == 1 +#include +#include +#undef ERROR +#endif +#endif + +#include "log.h" + +/* configuration */ +u16 gw16012_port; + +/* interface variables + */ +static u8 gw16012_msb = 0x0; +static u8 gw16012_control_value = 0x0; + +#if PARPORT_USE_PPDEV == 1 +static int device_handle; +#endif + +int gw16012_execute_queue(void); +int gw16012_register_commands(struct command_context_s *cmd_ctx); +int gw16012_speed(int speed); +int gw16012_init(void); +int gw16012_quit(void); + +int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); + +jtag_interface_t gw16012_interface = +{ + .name = "gw16012", + + .execute_queue = gw16012_execute_queue, + + .speed = gw16012_speed, + .register_commands = gw16012_register_commands, + .init = gw16012_init, + .quit = gw16012_quit, +}; + +int gw16012_register_commands(struct command_context_s *cmd_ctx) +{ + register_command(cmd_ctx, NULL, "parport_port", gw16012_handle_parport_port_command, + COMMAND_CONFIG, NULL); + + return ERROR_OK; +} + +void gw16012_data(u8 value) +{ + value = (value & 0x7f) | gw16012_msb; + gw16012_msb ^= 0x80; /* toggle MSB */ + +#ifdef _DEBUG_GW16012_IO_ + DEBUG("%2.2x", value); +#endif + + #if PARPORT_USE_PPDEV == 1 + ioctl(device_handle, PPWDATA, &value); + #else + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + outb(gw16012_port, value); + #else + outb(value, gw16012_port); + #endif + #endif +} + +void gw16012_control(u8 value) +{ + if (value != gw16012_control_value) + { + gw16012_control_value = value; + +#ifdef _DEBUG_GW16012_IO_ + DEBUG("%2.2x", gw16012_control_value); +#endif + + #if PARPORT_USE_PPDEV == 1 + ioctl(device_handle, PPWCONTROL, &gw16012_control_value); + #else + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + outb(gw16012_port + 2, gw16012_control_value); + #else + outb(gw16012_control_value, gw16012_port + 2); + #endif + #endif + } +} + +void gw16012_input(u8 *value) +{ + #if PARPORT_USE_PPDEV == 1 + ioctl(device_handle, PPRSTATUS, value); + #else + *value = inb(gw16012_port + 1); + #endif + +#ifdef _DEBUG_GW16012_IO_ + DEBUG("%2.2x", *value); +#endif +} + +/* (1) assert or (0) deassert reset lines */ +void gw16012_reset(int trst, int srst) +{ + DEBUG("trst: %i, srst: %i", trst, srst); + + if (trst == 0) + gw16012_control(0x0d); + else if (trst == 1) + gw16012_control(0x0c); + + if (srst == 0) + gw16012_control(0x0a); + else if (srst == 1) + gw16012_control(0x0b); +} + +int gw16012_speed(int speed) +{ + + return ERROR_OK; +} + +void gw16012_end_state(state) +{ + if (tap_move_map[state] != -1) + end_state = state; + else + { + ERROR("BUG: %i is not a valid end state", state); + exit(-1); + } +} + +void gw16012_state_move(void) +{ + int i=0, tms=0; + u8 tms_scan = TAP_MOVE(cur_state, end_state); + + gw16012_control(0x0); /* single-bit mode */ + + for (i = 0; i < 7; i++) + { + tms = (tms_scan >> i) & 1; + gw16012_data(tms << 1); /* output next TMS bit */ + } + + cur_state = end_state; +} + +void gw16012_path_move(pathmove_command_t *cmd) +{ + int num_states = cmd->num_states; + int state_count; + + state_count = 0; + while (num_states) + { + gw16012_control(0x0); /* single-bit mode */ + if (tap_transitions[cur_state].low == cmd->path[state_count]) + { + gw16012_data(0x0); /* TCK cycle with TMS low */ + } + else if (tap_transitions[cur_state].high == cmd->path[state_count]) + { + gw16012_data(0x2); /* TCK cycle with TMS high */ + } + else + { + ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]); + exit(-1); + } + + cur_state = cmd->path[state_count]; + state_count++; + num_states--; + } + + end_state = cur_state; +} + +void gw16012_runtest(int num_cycles) +{ + enum tap_state saved_end_state = end_state; + int i; + + /* only do a state_move when we're not already in RTI */ + if (cur_state != TAP_RTI) + { + gw16012_end_state(TAP_RTI); + gw16012_state_move(); + } + + for (i = 0; i < num_cycles; i++) + { + gw16012_control(0x0); /* single-bit mode */ + gw16012_data(0x0); /* TMS cycle with TMS low */ + } + + gw16012_end_state(saved_end_state); + if (cur_state != end_state) + gw16012_state_move(); +} + +void gw16012_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) +{ + int bits_left = scan_size; + int bit_count = 0; + enum tap_state saved_end_state = end_state; + u8 scan_out, scan_in; + + /* only if we're not already in the correct Shift state */ + if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI)))) + { + if (ir_scan) + gw16012_end_state(TAP_SI); + else + gw16012_end_state(TAP_SD); + + gw16012_state_move(); + gw16012_end_state(saved_end_state); + } + + while (type == SCAN_OUT && ((bits_left - 1) > 7)) + { + gw16012_control(0x2); /* seven-bit mode */ + scan_out = buf_get_u32(buffer, bit_count, 7); + gw16012_data(scan_out); + bit_count += 7; + bits_left -= 7; + } + + gw16012_control(0x0); /* single-bit mode */ + while (bits_left-- > 0) + { + u8 tms = 0; + + scan_out = buf_get_u32(buffer, bit_count, 1); + + if (bits_left == 0) /* last bit */ + { + if ((ir_scan && (end_state == TAP_SI)) + || (!ir_scan && (end_state == TAP_SD))) + { + tms = 0; + } + else + { + tms = 2; + } + } + + gw16012_data(scan_out | tms); + + if (type != SCAN_OUT) + { + gw16012_input(&scan_in); + buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3)); + } + + bit_count++; + } + + if (!((ir_scan && (end_state == TAP_SI)) || + (!ir_scan && (end_state == TAP_SD)))) + { + gw16012_data(0x0); + if (ir_scan) + cur_state = TAP_PI; + else + cur_state = TAP_PD; + + if (cur_state != end_state) + gw16012_state_move(); + } +} + +int gw16012_execute_queue(void) +{ + jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ + int scan_size; + enum scan_type type; + u8 *buffer; + int retval; + + /* return ERROR_OK, unless a jtag_read_buffer returns a failed check + * that wasn't handled by a caller-provided error handler + */ + retval = ERROR_OK; + + while (cmd) + { + switch (cmd->type) + { + case JTAG_END_STATE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("end_state: %i", cmd->cmd.end_state->end_state); +#endif + if (cmd->cmd.end_state->end_state != -1) + gw16012_end_state(cmd->cmd.end_state->end_state); + break; + case JTAG_RESET: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); +#endif + if (cmd->cmd.reset->trst == 1) + { + cur_state = TAP_TLR; + } + gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + break; + case JTAG_RUNTEST: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); +#endif + if (cmd->cmd.runtest->end_state != -1) + gw16012_end_state(cmd->cmd.runtest->end_state); + gw16012_runtest(cmd->cmd.runtest->num_cycles); + break; + case JTAG_STATEMOVE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); +#endif + if (cmd->cmd.statemove->end_state != -1) + gw16012_end_state(cmd->cmd.statemove->end_state); + gw16012_state_move(); + break; + case JTAG_PATHMOVE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); +#endif + gw16012_path_move(cmd->cmd.pathmove); + break; + case JTAG_SCAN: + if (cmd->cmd.scan->end_state != -1) + gw16012_end_state(cmd->cmd.scan->end_state); + scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); + type = jtag_scan_type(cmd->cmd.scan); +#ifdef _DEBUG_JTAG_IO_ + DEBUG("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr", + type, scan_size, cmd->cmd.scan->end_state); +#endif + gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); + if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) + retval = ERROR_JTAG_QUEUE_FAILED; + if (buffer) + free(buffer); + break; + case JTAG_SLEEP: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("sleep %i", cmd->cmd.sleep->us); +#endif + jtag_sleep(cmd->cmd.sleep->us); + break; + default: + ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } + cmd = cmd->next; + } + + return retval; +} + +#if PARPORT_USE_GIVEIO == 1 +int gw16012_get_giveio_access() +{ + HANDLE h; + OSVERSIONINFO version; + + version.dwOSVersionInfoSize = sizeof version; + if (!GetVersionEx( &version )) { + errno = EINVAL; + return -1; + } + if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) + return 0; + + h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + if (h == INVALID_HANDLE_VALUE) { + errno = ENODEV; + return -1; + } + + CloseHandle( h ); + + return 0; +} +#endif + +int gw16012_init(void) +{ +#if PARPORT_USE_PPDEV == 1 + char buffer[256]; + int i = 0; +#endif + u8 status_port; + +#if PARPORT_USE_PPDEV == 1 + if (device_handle>0) + { + ERROR("device is already opened"); + return ERROR_JTAG_INIT_FAILED; + } + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + DEBUG("opening /dev/ppi%d...", gw16012_port); + + snprintf(buffer, 256, "/dev/ppi%d", gw16012_port); + device_handle = open(buffer, O_WRONLY); +#else + DEBUG("opening /dev/parport%d...", gw16012_port); + + snprintf(buffer, 256, "/dev/parport%d", gw16012_port); + device_handle = open(buffer, O_WRONLY); +#endif + if (device_handle<0) + { + ERROR("cannot open device. check it exists and that user read and write rights are set"); + return ERROR_JTAG_INIT_FAILED; + } + + DEBUG("...open"); + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + i=ioctl(device_handle, PPCLAIM); + if (i<0) + { + ERROR("cannot claim device"); + return ERROR_JTAG_INIT_FAILED; + } + + i = PARPORT_MODE_COMPAT; + i= ioctl(device_handle, PPSETMODE, & i); + if (i<0) + { + ERROR(" cannot set compatible mode to device"); + return ERROR_JTAG_INIT_FAILED; + } + + i = IEEE1284_MODE_COMPAT; + i = ioctl(device_handle, PPNEGOT, & i); + if (i<0) + { + ERROR("cannot set compatible 1284 mode to device"); + return ERROR_JTAG_INIT_FAILED; + } +#endif +#else + if (gw16012_port == 0) + { + gw16012_port = 0x378; + WARNING("No gw16012 port specified, using default '0x378' (LPT1)"); + } + + DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port); +#if PARPORT_USE_GIVEIO == 1 + if (gw16012_get_giveio_access() != 0) +#else /* PARPORT_USE_GIVEIO */ + if (ioperm(gw16012_port, 3, 1) != 0) +#endif /* PARPORT_USE_GIVEIO */ + { + ERROR("missing privileges for direct i/o"); + return ERROR_JTAG_INIT_FAILED; + } + DEBUG("...privileges granted"); + + /* make sure parallel port is in right mode (clear tristate and interrupt */ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + outb(gw16012_port + 2, 0x0); +#else + outb(0x0, gw16012_port + 2); +#endif +#endif /* PARPORT_USE_PPDEV */ + + gw16012_input(&status_port); + gw16012_msb = (status_port & 0x80) ^ 0x80; + + gw16012_speed(jtag_speed); + gw16012_reset(0, 0); + + return ERROR_OK; +} + +int gw16012_quit(void) +{ + + return ERROR_OK; +} + +int gw16012_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 0) + return ERROR_OK; + + /* only if the port wasn't overwritten by cmdline */ + if (gw16012_port == 0) + gw16012_port = strtoul(args[0], NULL, 0); + + return ERROR_OK; +} diff --git a/src/jtag/parport.c b/src/jtag/parport.c index f9d7b0292b..7311bad80d 100644 --- a/src/jtag/parport.c +++ b/src/jtag/parport.c @@ -1,491 +1,491 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "replacements.h" - -#include "jtag.h" -#include "bitbang.h" - -/* system includes */ -// -ino: 060521-1036 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - -#include -#include -#include -#define ioperm(startport,length,enable)\ - i386_set_ioperm((startport), (length), (enable)) - -#else - -#ifdef _WIN32 -#include "errno.h" -#endif /* _WIN32 */ - -#endif /* __FreeBSD__ */ - -#include -#include -#include - -#if PARPORT_USE_PPDEV == 1 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#define PPRSTATUS PPIGSTATUS -#define PPWDATA PPISDATA -#else -#include -#include -#endif -#include -#include -#else /* not PARPORT_USE_PPDEV */ -#ifndef _WIN32 -#include -#endif -#endif - -#if PARPORT_USE_GIVEIO == 1 -#if IS_CYGWIN == 1 -#include -#include -#undef ERROR -#endif -#endif - -#include "log.h" - -/* parallel port cable description - */ -typedef struct cable_s -{ - char* name; - u8 TDO_MASK; /* status port bit containing current TDO value */ - u8 TRST_MASK; /* data port bit for TRST */ - u8 TMS_MASK; /* data port bit for TMS */ - u8 TCK_MASK; /* data port bit for TCK */ - u8 TDI_MASK; /* data port bit for TDI */ - u8 SRST_MASK; /* data port bit for SRST */ - u8 OUTPUT_INVERT; /* data port bits that should be inverted */ - u8 INPUT_INVERT; /* status port that should be inverted */ - u8 PORT_INIT; /* initialize data port with this value */ - u8 PORT_EXIT; /* de-initialize data port with this value */ - u8 LED_MASK; /* data port bit for LED */ -} cable_t; - -cable_t cables[] = -{ - /* name tdo trst tms tck tdi srst o_inv i_inv init exit led */ - { "wiggler", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x80, 0x00 }, - { "wiggler2", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x00, 0x20 }, - { "wiggler_ntrst_inverted", - 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 }, - { "old_amt_wiggler", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x80, 0x80, 0x80, 0x00 }, - { "chameleon", 0x80, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, - { "dlc5", 0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 }, - { "triton", 0x80, 0x08, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, - { "lattice", 0x40, 0x10, 0x04, 0x02, 0x01, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00 }, - { "flashlink", 0x20, 0x10, 0x02, 0x01, 0x04, 0x20, 0x30, 0x20, 0x00, 0x00, 0x00 }, -/* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire to target as follows: - HARD TCK - Target TCK - HARD TMS - Target TMS - HARD TDI - Target TDI - HARD TDO - Target TDO - SOFT TCK - Target TRST - SOFT TDI - Target SRST -*/ - { "altium", 0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 }, - { NULL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -/* configuration */ -char* parport_cable = NULL; -unsigned long parport_port; -static int parport_exit = 0; - -/* interface variables - */ -static cable_t* cable; -static u8 dataport_value = 0x0; - -#if PARPORT_USE_PPDEV == 1 -static int device_handle; -#else -static unsigned long dataport; -static unsigned long statusport; -#endif - -/* low level command set - */ -int parport_read(void); -void parport_write(int tck, int tms, int tdi); -void parport_reset(int trst, int srst); -void parport_led(int on); - -int parport_speed(int speed); -int parport_register_commands(struct command_context_s *cmd_ctx); -int parport_init(void); -int parport_quit(void); - -/* interface commands */ -int parport_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int parport_handle_parport_cable_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int parport_handle_write_on_exit_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); - -jtag_interface_t parport_interface = -{ - .name = "parport", - - .execute_queue = bitbang_execute_queue, - - .speed = parport_speed, - .register_commands = parport_register_commands, - .init = parport_init, - .quit = parport_quit, -}; - -bitbang_interface_t parport_bitbang = -{ - .read = parport_read, - .write = parport_write, - .reset = parport_reset, - .blink = parport_led -}; - -int parport_read(void) -{ - int data = 0; - -#if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPRSTATUS, & data); -#else - data = inb(statusport); -#endif - - if ((data ^ cable->INPUT_INVERT) & cable->TDO_MASK) - return 1; - else - return 0; -} - -static inline void parport_write_data(void) -{ - u8 output; - output = dataport_value ^ cable->OUTPUT_INVERT; - -#if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPWDATA, &output); -#else -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(dataport, output); -#else - outb(output, dataport); -#endif -#endif -} - -void parport_write(int tck, int tms, int tdi) -{ - int i = jtag_speed + 1; - - if (tck) - dataport_value |= cable->TCK_MASK; - else - dataport_value &= ~cable->TCK_MASK; - - if (tms) - dataport_value |= cable->TMS_MASK; - else - dataport_value &= ~cable->TMS_MASK; - - if (tdi) - dataport_value |= cable->TDI_MASK; - else - dataport_value &= ~cable->TDI_MASK; - - while (i-- > 0) - parport_write_data(); -} - -/* (1) assert or (0) deassert reset lines */ -void parport_reset(int trst, int srst) -{ - DEBUG("trst: %i, srst: %i", trst, srst); - - if (trst == 0) - dataport_value |= cable->TRST_MASK; - else if (trst == 1) - dataport_value &= ~cable->TRST_MASK; - - if (srst == 0) - dataport_value |= cable->SRST_MASK; - else if (srst == 1) - dataport_value &= ~cable->SRST_MASK; - - parport_write_data(); -} - -/* turn LED on parport adapter on (1) or off (0) */ -void parport_led(int on) -{ - if (on) - dataport_value |= cable->LED_MASK; - else - dataport_value &= ~cable->LED_MASK; - - parport_write_data(); -} - -int parport_speed(int speed) -{ - jtag_speed = speed; - - return ERROR_OK; -} - -int parport_register_commands(struct command_context_s *cmd_ctx) -{ - register_command(cmd_ctx, NULL, "parport_port", parport_handle_parport_port_command, - COMMAND_CONFIG, NULL); - register_command(cmd_ctx, NULL, "parport_cable", parport_handle_parport_cable_command, - COMMAND_CONFIG, NULL); - register_command(cmd_ctx, NULL, "parport_write_on_exit", parport_handle_write_on_exit_command, - COMMAND_CONFIG, NULL); - - return ERROR_OK; -} - -#if PARPORT_USE_GIVEIO == 1 -int parport_get_giveio_access() -{ - HANDLE h; - OSVERSIONINFO version; - - version.dwOSVersionInfoSize = sizeof version; - if (!GetVersionEx( &version )) { - errno = EINVAL; - return -1; - } - if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) - return 0; - - h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - if (h == INVALID_HANDLE_VALUE) { - errno = ENODEV; - return -1; - } - - CloseHandle( h ); - - return 0; -} -#endif - -int parport_init(void) -{ - cable_t *cur_cable; -#if PARPORT_USE_PPDEV == 1 - char buffer[256]; - int i = 0; -#endif - - cur_cable = cables; - - if ((parport_cable == NULL) || (parport_cable[0] == 0)) - { - parport_cable = "wiggler"; - WARNING("No parport cable specified, using default 'wiggler'"); - } - - while (cur_cable->name) - { - if (strcmp(cur_cable->name, parport_cable) == 0) - { - cable = cur_cable; - break; - } - cur_cable++; - } - - if (!cable) - { - ERROR("No matching cable found for %s", parport_cable); - return ERROR_JTAG_INIT_FAILED; - } - - dataport_value = cable->PORT_INIT; - -#if PARPORT_USE_PPDEV == 1 - if (device_handle > 0) - { - ERROR("device is already opened"); - return ERROR_JTAG_INIT_FAILED; - } - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - DEBUG("opening /dev/ppi%d...", parport_port); - - snprintf(buffer, 256, "/dev/ppi%d", parport_port); - device_handle = open(buffer, O_WRONLY); -#else /* not __FreeBSD__, __FreeBSD_kernel__ */ - DEBUG("opening /dev/parport%d...", parport_port); - - snprintf(buffer, 256, "/dev/parport%d", parport_port); - device_handle = open(buffer, O_WRONLY); -#endif /* __FreeBSD__, __FreeBSD_kernel__ */ - - if (device_handle < 0) - { - ERROR("cannot open device. check it exists and that user read and write rights are set"); - return ERROR_JTAG_INIT_FAILED; - } - - DEBUG("...open"); - -#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) - i=ioctl(device_handle, PPCLAIM); - if (i<0) - { - ERROR("cannot claim device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = PARPORT_MODE_COMPAT; - i= ioctl(device_handle, PPSETMODE, & i); - if (i<0) - { - ERROR(" cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = IEEE1284_MODE_COMPAT; - i = ioctl(device_handle, PPNEGOT, & i); - if (i<0) - { - ERROR("cannot set compatible 1284 mode to device"); - return ERROR_JTAG_INIT_FAILED; - } -#endif /* not __FreeBSD__, __FreeBSD_kernel__ */ - -#else /* not PARPORT_USE_PPDEV */ - if (parport_port == 0) - { - parport_port = 0x378; - WARNING("No parport port specified, using default '0x378' (LPT1)"); - } - - dataport = parport_port; - statusport = parport_port + 1; - - DEBUG("requesting privileges for parallel port 0x%lx...", dataport); -#if PARPORT_USE_GIVEIO == 1 - if (parport_get_giveio_access() != 0) -#else /* PARPORT_USE_GIVEIO */ - if (ioperm(dataport, 3, 1) != 0) -#endif /* PARPORT_USE_GIVEIO */ - { - ERROR("missing privileges for direct i/o"); - return ERROR_JTAG_INIT_FAILED; - } - DEBUG("...privileges granted"); - - /* make sure parallel port is in right mode (clear tristate and interrupt */ - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(parport_port + 2, 0x0); - #else - outb(0x0, parport_port + 2); - #endif - -#endif /* PARPORT_USE_PPDEV */ - - parport_reset(0, 0); - parport_write(0, 0, 0); - parport_led(1); - - bitbang_interface = &parport_bitbang; - - return ERROR_OK; -} - -int parport_quit(void) -{ - parport_led(0); - - if (parport_exit) - { - dataport_value = cable->PORT_EXIT; - parport_write_data(); - } - - if (parport_cable) - { - free(parport_cable); - parport_cable = NULL; - } - - return ERROR_OK; -} - -int parport_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) -{ - if (argc == 0) - return ERROR_OK; - - /* only if the port wasn't overwritten by cmdline */ - if (parport_port == 0) - parport_port = strtoul(args[0], NULL, 0); - - return ERROR_OK; -} - -int parport_handle_parport_cable_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) -{ - if (argc == 0) - return ERROR_OK; - - /* only if the cable name wasn't overwritten by cmdline */ - if (parport_cable == 0) - { - parport_cable = malloc(strlen(args[0]) + sizeof(char)); - strcpy(parport_cable, args[0]); - } - - return ERROR_OK; -} - -int parport_handle_write_on_exit_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) -{ - if (argc != 1) - { - command_print(cmd_ctx, "usage: parport_write_on_exit "); - return ERROR_OK; - } - - if (strcmp(args[0], "on") == 0) - parport_exit = 1; - else if (strcmp(args[0], "off") == 0) - parport_exit = 0; - - return ERROR_OK; -} +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" + +#include "jtag.h" +#include "bitbang.h" + +/* system includes */ +// -ino: 060521-1036 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + +#include +#include +#include +#define ioperm(startport,length,enable)\ + i386_set_ioperm((startport), (length), (enable)) + +#else + +#ifdef _WIN32 +#include "errno.h" +#endif /* _WIN32 */ + +#endif /* __FreeBSD__ */ + +#include +#include +#include + +#if PARPORT_USE_PPDEV == 1 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include +#include +#define PPRSTATUS PPIGSTATUS +#define PPWDATA PPISDATA +#else +#include +#include +#endif +#include +#include +#else /* not PARPORT_USE_PPDEV */ +#ifndef _WIN32 +#include +#endif +#endif + +#if PARPORT_USE_GIVEIO == 1 +#if IS_CYGWIN == 1 +#include +#include +#undef ERROR +#endif +#endif + +#include "log.h" + +/* parallel port cable description + */ +typedef struct cable_s +{ + char* name; + u8 TDO_MASK; /* status port bit containing current TDO value */ + u8 TRST_MASK; /* data port bit for TRST */ + u8 TMS_MASK; /* data port bit for TMS */ + u8 TCK_MASK; /* data port bit for TCK */ + u8 TDI_MASK; /* data port bit for TDI */ + u8 SRST_MASK; /* data port bit for SRST */ + u8 OUTPUT_INVERT; /* data port bits that should be inverted */ + u8 INPUT_INVERT; /* status port that should be inverted */ + u8 PORT_INIT; /* initialize data port with this value */ + u8 PORT_EXIT; /* de-initialize data port with this value */ + u8 LED_MASK; /* data port bit for LED */ +} cable_t; + +cable_t cables[] = +{ + /* name tdo trst tms tck tdi srst o_inv i_inv init exit led */ + { "wiggler", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x80, 0x00 }, + { "wiggler2", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x00, 0x20 }, + { "wiggler_ntrst_inverted", + 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 }, + { "old_amt_wiggler", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x80, 0x80, 0x80, 0x00 }, + { "chameleon", 0x80, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, + { "dlc5", 0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 }, + { "triton", 0x80, 0x08, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, + { "lattice", 0x40, 0x10, 0x04, 0x02, 0x01, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00 }, + { "flashlink", 0x20, 0x10, 0x02, 0x01, 0x04, 0x20, 0x30, 0x20, 0x00, 0x00, 0x00 }, +/* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire to target as follows: + HARD TCK - Target TCK + HARD TMS - Target TMS + HARD TDI - Target TDI + HARD TDO - Target TDO + SOFT TCK - Target TRST + SOFT TDI - Target SRST +*/ + { "altium", 0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 }, + { NULL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +/* configuration */ +char* parport_cable = NULL; +u16 parport_port; +static int parport_exit = 0; + +/* interface variables + */ +static cable_t* cable; +static u8 dataport_value = 0x0; + +#if PARPORT_USE_PPDEV == 1 +static int device_handle; +#else +static unsigned long dataport; +static unsigned long statusport; +#endif + +/* low level command set + */ +int parport_read(void); +void parport_write(int tck, int tms, int tdi); +void parport_reset(int trst, int srst); +void parport_led(int on); + +int parport_speed(int speed); +int parport_register_commands(struct command_context_s *cmd_ctx); +int parport_init(void); +int parport_quit(void); + +/* interface commands */ +int parport_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int parport_handle_parport_cable_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int parport_handle_write_on_exit_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); + +jtag_interface_t parport_interface = +{ + .name = "parport", + + .execute_queue = bitbang_execute_queue, + + .speed = parport_speed, + .register_commands = parport_register_commands, + .init = parport_init, + .quit = parport_quit, +}; + +bitbang_interface_t parport_bitbang = +{ + .read = parport_read, + .write = parport_write, + .reset = parport_reset, + .blink = parport_led +}; + +int parport_read(void) +{ + int data = 0; + +#if PARPORT_USE_PPDEV == 1 + ioctl(device_handle, PPRSTATUS, & data); +#else + data = inb(statusport); +#endif + + if ((data ^ cable->INPUT_INVERT) & cable->TDO_MASK) + return 1; + else + return 0; +} + +static inline void parport_write_data(void) +{ + u8 output; + output = dataport_value ^ cable->OUTPUT_INVERT; + +#if PARPORT_USE_PPDEV == 1 + ioctl(device_handle, PPWDATA, &output); +#else +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + outb(dataport, output); +#else + outb(output, dataport); +#endif +#endif +} + +void parport_write(int tck, int tms, int tdi) +{ + int i = jtag_speed + 1; + + if (tck) + dataport_value |= cable->TCK_MASK; + else + dataport_value &= ~cable->TCK_MASK; + + if (tms) + dataport_value |= cable->TMS_MASK; + else + dataport_value &= ~cable->TMS_MASK; + + if (tdi) + dataport_value |= cable->TDI_MASK; + else + dataport_value &= ~cable->TDI_MASK; + + while (i-- > 0) + parport_write_data(); +} + +/* (1) assert or (0) deassert reset lines */ +void parport_reset(int trst, int srst) +{ + DEBUG("trst: %i, srst: %i", trst, srst); + + if (trst == 0) + dataport_value |= cable->TRST_MASK; + else if (trst == 1) + dataport_value &= ~cable->TRST_MASK; + + if (srst == 0) + dataport_value |= cable->SRST_MASK; + else if (srst == 1) + dataport_value &= ~cable->SRST_MASK; + + parport_write_data(); +} + +/* turn LED on parport adapter on (1) or off (0) */ +void parport_led(int on) +{ + if (on) + dataport_value |= cable->LED_MASK; + else + dataport_value &= ~cable->LED_MASK; + + parport_write_data(); +} + +int parport_speed(int speed) +{ + jtag_speed = speed; + + return ERROR_OK; +} + +int parport_register_commands(struct command_context_s *cmd_ctx) +{ + register_command(cmd_ctx, NULL, "parport_port", parport_handle_parport_port_command, + COMMAND_CONFIG, NULL); + register_command(cmd_ctx, NULL, "parport_cable", parport_handle_parport_cable_command, + COMMAND_CONFIG, NULL); + register_command(cmd_ctx, NULL, "parport_write_on_exit", parport_handle_write_on_exit_command, + COMMAND_CONFIG, NULL); + + return ERROR_OK; +} + +#if PARPORT_USE_GIVEIO == 1 +int parport_get_giveio_access() +{ + HANDLE h; + OSVERSIONINFO version; + + version.dwOSVersionInfoSize = sizeof version; + if (!GetVersionEx( &version )) { + errno = EINVAL; + return -1; + } + if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) + return 0; + + h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + if (h == INVALID_HANDLE_VALUE) { + errno = ENODEV; + return -1; + } + + CloseHandle( h ); + + return 0; +} +#endif + +int parport_init(void) +{ + cable_t *cur_cable; +#if PARPORT_USE_PPDEV == 1 + char buffer[256]; + int i = 0; +#endif + + cur_cable = cables; + + if ((parport_cable == NULL) || (parport_cable[0] == 0)) + { + parport_cable = "wiggler"; + WARNING("No parport cable specified, using default 'wiggler'"); + } + + while (cur_cable->name) + { + if (strcmp(cur_cable->name, parport_cable) == 0) + { + cable = cur_cable; + break; + } + cur_cable++; + } + + if (!cable) + { + ERROR("No matching cable found for %s", parport_cable); + return ERROR_JTAG_INIT_FAILED; + } + + dataport_value = cable->PORT_INIT; + +#if PARPORT_USE_PPDEV == 1 + if (device_handle > 0) + { + ERROR("device is already opened"); + return ERROR_JTAG_INIT_FAILED; + } + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + DEBUG("opening /dev/ppi%d...", parport_port); + + snprintf(buffer, 256, "/dev/ppi%d", parport_port); + device_handle = open(buffer, O_WRONLY); +#else /* not __FreeBSD__, __FreeBSD_kernel__ */ + DEBUG("opening /dev/parport%d...", parport_port); + + snprintf(buffer, 256, "/dev/parport%d", parport_port); + device_handle = open(buffer, O_WRONLY); +#endif /* __FreeBSD__, __FreeBSD_kernel__ */ + + if (device_handle < 0) + { + ERROR("cannot open device. check it exists and that user read and write rights are set"); + return ERROR_JTAG_INIT_FAILED; + } + + DEBUG("...open"); + +#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) + i=ioctl(device_handle, PPCLAIM); + if (i<0) + { + ERROR("cannot claim device"); + return ERROR_JTAG_INIT_FAILED; + } + + i = PARPORT_MODE_COMPAT; + i= ioctl(device_handle, PPSETMODE, & i); + if (i<0) + { + ERROR(" cannot set compatible mode to device"); + return ERROR_JTAG_INIT_FAILED; + } + + i = IEEE1284_MODE_COMPAT; + i = ioctl(device_handle, PPNEGOT, & i); + if (i<0) + { + ERROR("cannot set compatible 1284 mode to device"); + return ERROR_JTAG_INIT_FAILED; + } +#endif /* not __FreeBSD__, __FreeBSD_kernel__ */ + +#else /* not PARPORT_USE_PPDEV */ + if (parport_port == 0) + { + parport_port = 0x378; + WARNING("No parport port specified, using default '0x378' (LPT1)"); + } + + dataport = parport_port; + statusport = parport_port + 1; + + DEBUG("requesting privileges for parallel port 0x%lx...", dataport); +#if PARPORT_USE_GIVEIO == 1 + if (parport_get_giveio_access() != 0) +#else /* PARPORT_USE_GIVEIO */ + if (ioperm(dataport, 3, 1) != 0) +#endif /* PARPORT_USE_GIVEIO */ + { + ERROR("missing privileges for direct i/o"); + return ERROR_JTAG_INIT_FAILED; + } + DEBUG("...privileges granted"); + + /* make sure parallel port is in right mode (clear tristate and interrupt */ + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + outb(parport_port + 2, 0x0); + #else + outb(0x0, parport_port + 2); + #endif + +#endif /* PARPORT_USE_PPDEV */ + + parport_reset(0, 0); + parport_write(0, 0, 0); + parport_led(1); + + bitbang_interface = &parport_bitbang; + + return ERROR_OK; +} + +int parport_quit(void) +{ + parport_led(0); + + if (parport_exit) + { + dataport_value = cable->PORT_EXIT; + parport_write_data(); + } + + if (parport_cable) + { + free(parport_cable); + parport_cable = NULL; + } + + return ERROR_OK; +} + +int parport_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 0) + return ERROR_OK; + + /* only if the port wasn't overwritten by cmdline */ + if (parport_port == 0) + parport_port = strtoul(args[0], NULL, 0); + + return ERROR_OK; +} + +int parport_handle_parport_cable_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 0) + return ERROR_OK; + + /* only if the cable name wasn't overwritten by cmdline */ + if (parport_cable == 0) + { + parport_cable = malloc(strlen(args[0]) + sizeof(char)); + strcpy(parport_cable, args[0]); + } + + return ERROR_OK; +} + +int parport_handle_write_on_exit_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc != 1) + { + command_print(cmd_ctx, "usage: parport_write_on_exit "); + return ERROR_OK; + } + + if (strcmp(args[0], "on") == 0) + parport_exit = 1; + else if (strcmp(args[0], "off") == 0) + parport_exit = 0; + + return ERROR_OK; +} -- 2.30.2