- convert all files to unix line-ending

git-svn-id: svn://svn.berlios.de/openocd/trunk@347 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
drath 2008-02-25 17:48:04 +00:00
parent 7f1944a478
commit 3d6bcf0792
42 changed files with 32837 additions and 32837 deletions

View File

@ -1,100 +1,100 @@
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin *
* lundin@mlu.mine.nu *
* *
* 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. *
***************************************************************************/
#ifndef AT91SAM7_H
#define AT91SAM7_H
#include "flash.h"
#include "target.h"
typedef struct at91sam7_flash_bank_s
{
u32 working_area;
u32 working_area_size;
/* chip id register */
u32 cidr;
u16 cidr_ext;
u16 cidr_nvptyp;
u16 cidr_arch;
u16 cidr_sramsiz;
u16 cidr_nvpsiz;
u16 cidr_nvpsiz2;
u16 cidr_eproc;
u16 cidr_version;
char * target_name;
/* flash geometry */
u16 num_pages;
u16 pagesize;
u16 pages_in_lockregion;
u8 num_erase_regions;
u8 num_planes;
u32 *erase_region_info;
/* nv memory bits */
u16 num_lockbits;
u16 lockbits[4];
u16 num_nvmbits;
u16 nvmbits;
u8 securitybit;
u8 flashmode[4]; /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */
/* main clock status */
u8 mck_valid;
u32 mck_freq;
int probed;
} at91sam7_flash_bank_t;
/* AT91SAM7 control registers */
#define DBGU_CIDR 0xFFFFF240
#define CKGR_MCFR 0xFFFFFC24
#define CKGR_MCFR_MAINRDY 0x10000
#define CKGR_PLLR 0xFFFFFC2c
#define CKGR_PLLR_DIV 0xff
#define CKGR_PLLR_MUL 0x07ff0000
#define PMC_MCKR 0xFFFFFC30
#define PMC_MCKR_CSS 0x03
#define PMC_MCKR_PRES 0x1c
/* Flash Controller Commands */
#define WP 0x01
#define SLB 0x02
#define WPL 0x03
#define CLB 0x04
#define EA 0x08
#define SGPB 0x0B
#define CGPB 0x0D
#define SSB 0x0F
/* MC_FSR bit definitions */
#define MC_FSR_FRDY 1
#define MC_FSR_EOL 2
/* AT91SAM7 constants */
#define RC_FREQ 32000
/* FLASH_TIMING_MODES */
#define FMR_TIMING_NONE 0
#define FMR_TIMING_NVBITS 1
#define FMR_TIMING_FLASH 2
#endif /* AT91SAM7_H */
/***************************************************************************
* Copyright (C) 2006 by Magnus Lundin *
* lundin@mlu.mine.nu *
* *
* 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. *
***************************************************************************/
#ifndef AT91SAM7_H
#define AT91SAM7_H
#include "flash.h"
#include "target.h"
typedef struct at91sam7_flash_bank_s
{
u32 working_area;
u32 working_area_size;
/* chip id register */
u32 cidr;
u16 cidr_ext;
u16 cidr_nvptyp;
u16 cidr_arch;
u16 cidr_sramsiz;
u16 cidr_nvpsiz;
u16 cidr_nvpsiz2;
u16 cidr_eproc;
u16 cidr_version;
char * target_name;
/* flash geometry */
u16 num_pages;
u16 pagesize;
u16 pages_in_lockregion;
u8 num_erase_regions;
u8 num_planes;
u32 *erase_region_info;
/* nv memory bits */
u16 num_lockbits;
u16 lockbits[4];
u16 num_nvmbits;
u16 nvmbits;
u8 securitybit;
u8 flashmode[4]; /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */
/* main clock status */
u8 mck_valid;
u32 mck_freq;
int probed;
} at91sam7_flash_bank_t;
/* AT91SAM7 control registers */
#define DBGU_CIDR 0xFFFFF240
#define CKGR_MCFR 0xFFFFFC24
#define CKGR_MCFR_MAINRDY 0x10000
#define CKGR_PLLR 0xFFFFFC2c
#define CKGR_PLLR_DIV 0xff
#define CKGR_PLLR_MUL 0x07ff0000
#define PMC_MCKR 0xFFFFFC30
#define PMC_MCKR_CSS 0x03
#define PMC_MCKR_PRES 0x1c
/* Flash Controller Commands */
#define WP 0x01
#define SLB 0x02
#define WPL 0x03
#define CLB 0x04
#define EA 0x08
#define SGPB 0x0B
#define CGPB 0x0D
#define SSB 0x0F
/* MC_FSR bit definitions */
#define MC_FSR_FRDY 1
#define MC_FSR_EOL 2
/* AT91SAM7 constants */
#define RC_FREQ 32000
/* FLASH_TIMING_MODES */
#define FMR_TIMING_NONE 0
#define FMR_TIMING_NVBITS 1
#define FMR_TIMING_FLASH 2
#endif /* AT91SAM7_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +1,179 @@
/* src/flash/s3c2440_nand.c
*
* S3C2440 OpenOCD NAND Flash controller support.
*
* Copyright 2007,2008 Ben Dooks <ben@fluff.org>
*
* 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 <stdlib.h>
#include <string.h>
#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 <ben@fluff.org>
*
* 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 <stdlib.h>
#include <string.h>
#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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,104 +1,104 @@
/***************************************************************************
* Copyright (C) 2004, 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 "types.h"
#include "command.h"
#include "configuration.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static size_t num_config_files;
static char** config_file_names;
static size_t num_script_dirs;
static char** script_search_dirs;
void add_script_search_dir (const char *dir)
{
num_script_dirs++;
script_search_dirs = (char **)realloc(script_search_dirs, (num_script_dirs+1) * sizeof (char *));
script_search_dirs[num_script_dirs-1] = strdup(dir);
script_search_dirs[num_script_dirs] = NULL;
}
void add_config_file_name (const char *cfg)
{
num_config_files++;
config_file_names = (char **)realloc(config_file_names, (num_config_files+1) * sizeof (char *));
config_file_names[num_config_files-1] = strdup(cfg);
config_file_names[num_config_files] = NULL;
}
FILE *open_file_from_path (command_context_t *cmd_ctx, char *file, char *mode)
{
FILE *fp = NULL;
char **search_dirs = script_search_dirs;
char *dir;
char full_path[1024];
/* Check absolute and relative to current working dir first.
* This keeps full_path reporting belowing working. */
snprintf(full_path, 1024, "%s", file);
fp = fopen(full_path, mode);
while (!fp)
{
dir = *search_dirs++;
if (!dir)
break;
snprintf(full_path, 1024, "%s/%s", dir, file);
fp = fopen(full_path, mode);
}
if (fp)
command_print(cmd_ctx, "opened %s", full_path);
return fp;
}
int parse_config_file(struct command_context_s *cmd_ctx)
{
char **cfg;
FILE *config_file;
if (!config_file_names)
add_config_file_name ("script openocd.cfg");
cfg = config_file_names;
while (*cfg)
{
command_run_line(cmd_ctx, *cfg);
cfg++;
}
return ERROR_OK;
}
/***************************************************************************
* Copyright (C) 2004, 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 "types.h"
#include "command.h"
#include "configuration.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static size_t num_config_files;
static char** config_file_names;
static size_t num_script_dirs;
static char** script_search_dirs;
void add_script_search_dir (const char *dir)
{
num_script_dirs++;
script_search_dirs = (char **)realloc(script_search_dirs, (num_script_dirs+1) * sizeof (char *));
script_search_dirs[num_script_dirs-1] = strdup(dir);
script_search_dirs[num_script_dirs] = NULL;
}
void add_config_file_name (const char *cfg)
{
num_config_files++;
config_file_names = (char **)realloc(config_file_names, (num_config_files+1) * sizeof (char *));
config_file_names[num_config_files-1] = strdup(cfg);
config_file_names[num_config_files] = NULL;
}
FILE *open_file_from_path (command_context_t *cmd_ctx, char *file, char *mode)
{
FILE *fp = NULL;
char **search_dirs = script_search_dirs;
char *dir;
char full_path[1024];
/* Check absolute and relative to current working dir first.
* This keeps full_path reporting belowing working. */
snprintf(full_path, 1024, "%s", file);
fp = fopen(full_path, mode);
while (!fp)
{
dir = *search_dirs++;
if (!dir)
break;
snprintf(full_path, 1024, "%s/%s", dir, file);
fp = fopen(full_path, mode);
}
if (fp)
command_print(cmd_ctx, "opened %s", full_path);
return fp;
}
int parse_config_file(struct command_context_s *cmd_ctx)
{
char **cfg;
FILE *config_file;
if (!config_file_names)
add_config_file_name ("script openocd.cfg");
cfg = config_file_names;
while (*cfg)
{
command_run_line(cmd_ctx, *cfg);
cfg++;
}
return ERROR_OK;
}

View File

@ -1,248 +1,248 @@
/***************************************************************************
* 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 "log.h"
#include "configuration.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
int debug_level = -1;
static FILE* log_output;
static log_callback_t *log_callbacks = NULL;
static time_t start;
static char *log_strings[5] =
{
"User: ",
"Error: ",
"Warning:",
"Info: ",
"Debug: "
};
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
{
static int count = 0;
count++;
va_list args;
char buffer[512];
log_callback_t *cb;
if (level > debug_level)
return;
va_start(args, format);
vsnprintf(buffer, 512, format, args);
va_end(args);
if (level == LOG_OUTPUT)
{
/* do not prepend any headers, just print out what we were given and return */
fputs(buffer, log_output);
fflush(log_output);
return;
}
char *f = strrchr(file, '/');
if (f != NULL)
file = f + 1;
if (debug_level >= LOG_DEBUG)
{
/* print with count and time information */
time_t t=time(NULL)-start;
fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, t, file, line, function, buffer);
}
else
{
/* do not print count and time */
fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);
}
fflush(log_output);
/* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
if (level <= LOG_INFO)
{
for (cb = log_callbacks; cb; cb = cb->next)
{
va_start(args, format);
cb->fn(cb->priv, file, line, function, format, args);
va_end(args);
}
}
}
/* change the current debug level on the fly
* 0: only ERRORS
* 1: + WARNINGS
* 2: + INFORMATIONAL MSGS
* 3: + DEBUG MSGS
*/
int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc == 0)
command_print(cmd_ctx, "debug_level: %i", debug_level);
if (argc > 0)
debug_level = strtoul(args[0], NULL, 0);
if (debug_level < 0)
debug_level = 0;
if (debug_level > 3)
debug_level = 3;
return ERROR_OK;
}
int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc == 1)
{
FILE* file = fopen(args[0], "w");
if (file)
{
log_output = file;
}
}
return ERROR_OK;
}
int log_register_commands(struct command_context_s *cmd_ctx)
{
start = time(NULL);
register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,
COMMAND_ANY, "redirect logging to <file> (default: stderr)");
register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,
COMMAND_ANY, "adjust debug level <0-3>");
return ERROR_OK;
}
int log_init(struct command_context_s *cmd_ctx)
{
/* set defaults for daemon configuration, if not set by cmdline or cfgfile */
if (debug_level == -1)
debug_level = LOG_INFO;
if (log_output == NULL)
{
log_output = stderr;
}
return ERROR_OK;
}
int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
{
log_output = output;
return ERROR_OK;
}
/* add/remove log callback handler */
int log_add_callback(log_callback_fn fn, void *priv)
{
log_callback_t *cb;
/* prevent the same callback to be registered more than once, just for sure */
for (cb = log_callbacks; cb; cb = cb->next)
{
if (cb->fn == fn && cb->priv == priv)
return ERROR_INVALID_ARGUMENTS;
}
/* alloc memory, it is safe just to return in case of an error, no need for the caller to check this */
if ((cb = malloc(sizeof(log_callback_t))) == NULL)
return ERROR_BUF_TOO_SMALL;
/* add item to the beginning of the linked list */
cb->fn = fn;
cb->priv = priv;
cb->next = log_callbacks;
log_callbacks = cb;
return ERROR_OK;
}
int log_remove_callback(log_callback_fn fn, void *priv)
{
log_callback_t *cb, **p;
for (p = &log_callbacks; cb = *p; p = &(*p)->next)
{
if (cb->fn == fn && cb->priv == priv)
{
*p = cb->next;
free(cb);
return ERROR_OK;
}
}
/* no such item */
return ERROR_INVALID_ARGUMENTS;
}
/* return allocated string w/printf() result */
char *alloc_printf(const char *fmt, va_list ap)
{
char *string = NULL;
/* start by 0 to exercise all the code paths. Need minimum 2 bytes to
* fit 1 char and 0 terminator. */
int size = 0;
int first = 1;
for (;;)
{
if ((string == NULL) || (!first))
{
size = size * 2 + 2;
char *t = string;
string = realloc(string, size);
if (string == NULL)
{
if (t != NULL)
free(t);
return NULL;
}
}
int ret;
ret = vsnprintf(string, size, fmt, ap);
/* NB! The result of the vsnprintf() might be an *EMPTY* string! */
if ((ret >= 0) && ((ret + 1) < size))
{
return string;
}
/* there was just enough or not enough space, allocate more. */
first = 0;
}
}
/***************************************************************************
* 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 "log.h"
#include "configuration.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
int debug_level = -1;
static FILE* log_output;
static log_callback_t *log_callbacks = NULL;
static time_t start;
static char *log_strings[5] =
{
"User: ",
"Error: ",
"Warning:",
"Info: ",
"Debug: "
};
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
{
static int count = 0;
count++;
va_list args;
char buffer[512];
log_callback_t *cb;
if (level > debug_level)
return;
va_start(args, format);
vsnprintf(buffer, 512, format, args);
va_end(args);
if (level == LOG_OUTPUT)
{
/* do not prepend any headers, just print out what we were given and return */
fputs(buffer, log_output);
fflush(log_output);
return;
}
char *f = strrchr(file, '/');
if (f != NULL)
file = f + 1;
if (debug_level >= LOG_DEBUG)
{
/* print with count and time information */
time_t t=time(NULL)-start;
fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, t, file, line, function, buffer);
}
else
{
/* do not print count and time */
fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);
}
fflush(log_output);
/* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
if (level <= LOG_INFO)
{
for (cb = log_callbacks; cb; cb = cb->next)
{
va_start(args, format);
cb->fn(cb->priv, file, line, function, format, args);
va_end(args);
}
}
}
/* change the current debug level on the fly
* 0: only ERRORS
* 1: + WARNINGS
* 2: + INFORMATIONAL MSGS
* 3: + DEBUG MSGS
*/
int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc == 0)
command_print(cmd_ctx, "debug_level: %i", debug_level);
if (argc > 0)
debug_level = strtoul(args[0], NULL, 0);
if (debug_level < 0)
debug_level = 0;
if (debug_level > 3)
debug_level = 3;
return ERROR_OK;
}
int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc == 1)
{
FILE* file = fopen(args[0], "w");
if (file)
{
log_output = file;
}
}
return ERROR_OK;
}
int log_register_commands(struct command_context_s *cmd_ctx)
{
start = time(NULL);
register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,
COMMAND_ANY, "redirect logging to <file> (default: stderr)");
register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,
COMMAND_ANY, "adjust debug level <0-3>");
return ERROR_OK;
}
int log_init(struct command_context_s *cmd_ctx)
{
/* set defaults for daemon configuration, if not set by cmdline or cfgfile */
if (debug_level == -1)
debug_level = LOG_INFO;
if (log_output == NULL)
{
log_output = stderr;
}
return ERROR_OK;
}
int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
{
log_output = output;
return ERROR_OK;
}
/* add/remove log callback handler */
int log_add_callback(log_callback_fn fn, void *priv)
{
log_callback_t *cb;
/* prevent the same callback to be registered more than once, just for sure */
for (cb = log_callbacks; cb; cb = cb->next)
{
if (cb->fn == fn && cb->priv == priv)
return ERROR_INVALID_ARGUMENTS;
}
/* alloc memory, it is safe just to return in case of an error, no need for the caller to check this */
if ((cb = malloc(sizeof(log_callback_t))) == NULL)
return ERROR_BUF_TOO_SMALL;
/* add item to the beginning of the linked list */
cb->fn = fn;
cb->priv = priv;
cb->next = log_callbacks;
log_callbacks = cb;
return ERROR_OK;
}
int log_remove_callback(log_callback_fn fn, void *priv)
{
log_callback_t *cb, **p;
for (p = &log_callbacks; cb = *p; p = &(*p)->next)
{
if (cb->fn == fn && cb->priv == priv)
{
*p = cb->next;
free(cb);
return ERROR_OK;
}
}
/* no such item */
return ERROR_INVALID_ARGUMENTS;
}
/* return allocated string w/printf() result */
char *alloc_printf(const char *fmt, va_list ap)
{
char *string = NULL;
/* start by 0 to exercise all the code paths. Need minimum 2 bytes to
* fit 1 char and 0 terminator. */
int size = 0;
int first = 1;
for (;;)
{
if ((string == NULL) || (!first))
{
size = size * 2 + 2;
char *t = string;
string = realloc(string, size);
if (string == NULL)
{
if (t != NULL)
free(t);
return NULL;
}
}
int ret;
ret = vsnprintf(string, size, fmt, ap);
/* NB! The result of the vsnprintf() might be an *EMPTY* string! */
if ((ret >= 0) && ((ret + 1) < size))
{
return string;
}
/* there was just enough or not enough space, allocate more. */
first = 0;
}
}

View File

@ -1,113 +1,113 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef ERROR_H
#define ERROR_H
#include "replacements.h"
#include "command.h"
#include <stdarg.h>
/* logging priorities
* LOG_USER - user messages. Could be anything from information
* to progress messags. These messages do not represent
* incorrect or unexpected behaviour, just normal execution.
* LOG_ERROR - fatal errors, that are likely to cause program abort
* LOG_WARNING - non-fatal errors, that may be resolved later
* LOG_INFO - state information, etc.
* LOG_DEBUG - debug statements, execution trace
*/
enum log_levels
{
LOG_OUTPUT = -2,
LOG_USER = -1,
LOG_ERROR = 0,
LOG_WARNING = 1,
LOG_INFO = 2,
LOG_DEBUG = 3
};
extern void log_printf(enum log_levels level, const char *file, int line,
const char *function, const char *format, ...)
__attribute__ ((format (printf, 5, 6)));
extern int log_register_commands(struct command_context_s *cmd_ctx);
extern int log_init(struct command_context_s *cmd_ctx);
extern int set_log_output(struct command_context_s *cmd_ctx, FILE *output);
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
const char *function, const char *format, va_list args);
typedef struct log_callback_s
{
log_callback_fn fn;
void *priv;
struct log_callback_s *next;
} log_callback_t;
extern int log_add_callback(log_callback_fn fn, void *priv);
extern int log_remove_callback(log_callback_fn fn, void *priv);
char *alloc_printf(const char *fmt, va_list ap);
extern int debug_level;
/* Avoid fn call and building parameter list if we're not outputting the information.
* Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */
#define DEBUG(expr ...) \
do { if (debug_level >= LOG_DEBUG) \
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define INFO(expr ...) \
do { if (debug_level >= LOG_INFO) \
log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define WARNING(expr ...) \
do { \
log_printf (LOG_WARNING, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define ERROR(expr ...) \
do { \
log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define USER(expr ...) \
do { \
log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define OUTPUT(expr ...) \
do { \
log_printf (LOG_OUTPUT, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
/* general failures
* error codes < 100
*/
#define ERROR_OK (0)
#define ERROR_INVALID_ARGUMENTS (-1)
#define ERROR_NO_CONFIG_FILE (-2)
#define ERROR_BUF_TOO_SMALL (-3)
#endif /* LOG_H */
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef ERROR_H
#define ERROR_H
#include "replacements.h"
#include "command.h"
#include <stdarg.h>
/* logging priorities
* LOG_USER - user messages. Could be anything from information
* to progress messags. These messages do not represent
* incorrect or unexpected behaviour, just normal execution.
* LOG_ERROR - fatal errors, that are likely to cause program abort
* LOG_WARNING - non-fatal errors, that may be resolved later
* LOG_INFO - state information, etc.
* LOG_DEBUG - debug statements, execution trace
*/
enum log_levels
{
LOG_OUTPUT = -2,
LOG_USER = -1,
LOG_ERROR = 0,
LOG_WARNING = 1,
LOG_INFO = 2,
LOG_DEBUG = 3
};
extern void log_printf(enum log_levels level, const char *file, int line,
const char *function, const char *format, ...)
__attribute__ ((format (printf, 5, 6)));
extern int log_register_commands(struct command_context_s *cmd_ctx);
extern int log_init(struct command_context_s *cmd_ctx);
extern int set_log_output(struct command_context_s *cmd_ctx, FILE *output);
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
const char *function, const char *format, va_list args);
typedef struct log_callback_s
{
log_callback_fn fn;
void *priv;
struct log_callback_s *next;
} log_callback_t;
extern int log_add_callback(log_callback_fn fn, void *priv);
extern int log_remove_callback(log_callback_fn fn, void *priv);
char *alloc_printf(const char *fmt, va_list ap);
extern int debug_level;
/* Avoid fn call and building parameter list if we're not outputting the information.
* Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */
#define DEBUG(expr ...) \
do { if (debug_level >= LOG_DEBUG) \
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define INFO(expr ...) \
do { if (debug_level >= LOG_INFO) \
log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define WARNING(expr ...) \
do { \
log_printf (LOG_WARNING, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define ERROR(expr ...) \
do { \
log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define USER(expr ...) \
do { \
log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define OUTPUT(expr ...) \
do { \
log_printf (LOG_OUTPUT, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
/* general failures
* error codes < 100
*/
#define ERROR_OK (0)
#define ERROR_INVALID_ARGUMENTS (-1)
#define ERROR_NO_CONFIG_FILE (-2)
#define ERROR_BUF_TOO_SMALL (-3)
#endif /* LOG_H */

View File

@ -1,153 +1,153 @@
/***************************************************************************
* Copyright (C) 2004, 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 "types.h"
#include "command.h"
#include "configuration.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
static int help_flag;
static struct option long_options[] =
{
{"help", no_argument, &help_flag, 1},
{"debug", optional_argument, 0, 'd'},
{"file", required_argument, 0, 'f'},
{"search", required_argument, 0, 's'},
{"log_output", required_argument, 0, 'l'},
{"command", required_argument, 0, 'c'},
{0, 0, 0, 0}
};
int configuration_output_handler(struct command_context_s *context, char* line)
{
INFO(line);
return ERROR_OK;
}
int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[])
{
int c;
char command_buffer[128];
while (1)
{
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long(argc, argv, "hd::l:f:s:c:", long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 0:
break;
case 'h': /* --help | -h */
help_flag = 1;
break;
case 'f': /* --file | -f */
snprintf(command_buffer, 128, "script %s", optarg);
add_config_file_name(command_buffer);
break;
case 's': /* --search | -s */
add_script_search_dir(optarg);
break;
case 'd': /* --debug | -d */
if (optarg)
snprintf(command_buffer, 128, "debug_level %s", optarg);
else
snprintf(command_buffer, 128, "debug_level 3");
command_run_line(cmd_ctx, command_buffer);
break;
case 'l': /* --log_output | -l */
if (optarg)
{
snprintf(command_buffer, 128, "log_output %s", optarg);
command_run_line(cmd_ctx, command_buffer);
}
break;
case 'c': /* --command | -c */
if (optarg)
{
add_config_file_name(optarg);
}
break;
}
}
if (help_flag)
{
OUTPUT("Open On-Chip Debugger\n(c) 2005 by Dominic Rath\n\n");
OUTPUT("--help | -h\tdisplay this help\n");
OUTPUT("--file | -f\tuse configuration file <name>\n");
OUTPUT("--search | -s\tdir to search for config files and scripts.\n");
OUTPUT("--debug | -d\tset debug level <0-3>\n");
OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
OUTPUT("--command | -c\trun <command>\n");
exit(-1);
}
#ifdef _WIN32
/* Add the parent of the directory where openocd.exe resides to the
* config script search path.
* Directory layout:
* bin\openocd.exe
* lib\openocd
* event\at91eb40a_reset.cfg
* target\at91eb40a.cfg
*/
{
char strExePath [MAX_PATH];
GetModuleFileName (NULL, strExePath, MAX_PATH);
/* Either this code will *always* work or it will SEGFAULT giving
* excellent information on the culprit.
*/
*strrchr(strExePath, '\\')=0;
strcat(strExePath, "\\..");
add_script_search_dir(strExePath);
}
#else
/* Add dir for openocd supplied scripts last so that user can over
ride those scripts if desired. */
add_script_search_dir(PKGDATADIR);
add_script_search_dir(PKGLIBDIR);
#endif
return ERROR_OK;
}
/***************************************************************************
* Copyright (C) 2004, 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 "types.h"
#include "command.h"
#include "configuration.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
static int help_flag;
static struct option long_options[] =
{
{"help", no_argument, &help_flag, 1},
{"debug", optional_argument, 0, 'd'},
{"file", required_argument, 0, 'f'},
{"search", required_argument, 0, 's'},
{"log_output", required_argument, 0, 'l'},
{"command", required_argument, 0, 'c'},
{0, 0, 0, 0}
};
int configuration_output_handler(struct command_context_s *context, char* line)
{
INFO(line);
return ERROR_OK;
}
int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[])
{
int c;
char command_buffer[128];
while (1)
{
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long(argc, argv, "hd::l:f:s:c:", long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 0:
break;
case 'h': /* --help | -h */
help_flag = 1;
break;
case 'f': /* --file | -f */
snprintf(command_buffer, 128, "script %s", optarg);
add_config_file_name(command_buffer);
break;
case 's': /* --search | -s */
add_script_search_dir(optarg);
break;
case 'd': /* --debug | -d */
if (optarg)
snprintf(command_buffer, 128, "debug_level %s", optarg);
else
snprintf(command_buffer, 128, "debug_level 3");
command_run_line(cmd_ctx, command_buffer);
break;
case 'l': /* --log_output | -l */
if (optarg)
{
snprintf(command_buffer, 128, "log_output %s", optarg);
command_run_line(cmd_ctx, command_buffer);
}
break;
case 'c': /* --command | -c */
if (optarg)
{
add_config_file_name(optarg);
}
break;
}
}
if (help_flag)
{
OUTPUT("Open On-Chip Debugger\n(c) 2005 by Dominic Rath\n\n");
OUTPUT("--help | -h\tdisplay this help\n");
OUTPUT("--file | -f\tuse configuration file <name>\n");
OUTPUT("--search | -s\tdir to search for config files and scripts.\n");
OUTPUT("--debug | -d\tset debug level <0-3>\n");
OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
OUTPUT("--command | -c\trun <command>\n");
exit(-1);
}
#ifdef _WIN32
/* Add the parent of the directory where openocd.exe resides to the
* config script search path.
* Directory layout:
* bin\openocd.exe
* lib\openocd
* event\at91eb40a_reset.cfg
* target\at91eb40a.cfg
*/
{
char strExePath [MAX_PATH];
GetModuleFileName (NULL, strExePath, MAX_PATH);
/* Either this code will *always* work or it will SEGFAULT giving
* excellent information on the culprit.
*/
*strrchr(strExePath, '\\')=0;
strcat(strExePath, "\\..");
add_script_search_dir(strExePath);
}
#else
/* Add dir for openocd supplied scripts last so that user can over
ride those scripts if desired. */
add_script_search_dir(PKGDATADIR);
add_script_search_dir(PKGLIBDIR);
#endif
return ERROR_OK;
}

View File

@ -67,38 +67,38 @@ struct timezone {
};
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif
#endif
/**** clear_malloc & fill_malloc ****/
void *clear_malloc(size_t size);
void *fill_malloc(size_t size);
/*
* Now you have 3 ways for the malloc function:
*
* 1. Do not change anything, use the original malloc
*
* 2. Use the clear_malloc function instead of the original malloc.
* In this case you must use the following define:
* #define malloc((_a)) clear_malloc((_a))
*
* 3. Use the fill_malloc function instead of the original malloc.
* In this case you must use the following define:
* #define malloc((_a)) fill_malloc((_a))
*
* We have figured out that there could exist some malloc problems
* where variables are using without to be initialise. To find this
* places, use the fill_malloc function. With this function we want
* to initialize memory to some known bad state. This is quite easily
* spotted in the debugger and will trap to an invalid address.
*
* clear_malloc can be used if you want to set not initialise
* variable to 0.
*
* If you do not want to change the malloc function, to not use one of
* the following macros. Which is the default way.
*/
/*
* Now you have 3 ways for the malloc function:
*
* 1. Do not change anything, use the original malloc
*
* 2. Use the clear_malloc function instead of the original malloc.
* In this case you must use the following define:
* #define malloc((_a)) clear_malloc((_a))
*
* 3. Use the fill_malloc function instead of the original malloc.
* In this case you must use the following define:
* #define malloc((_a)) fill_malloc((_a))
*
* We have figured out that there could exist some malloc problems
* where variables are using without to be initialise. To find this
* places, use the fill_malloc function. With this function we want
* to initialize memory to some known bad state. This is quite easily
* spotted in the debugger and will trap to an invalid address.
*
* clear_malloc can be used if you want to set not initialise
* variable to 0.
*
* If you do not want to change the malloc function, to not use one of
* the following macros. Which is the default way.
*/
//#define malloc(_a) clear_malloc(_a)
//#define malloc(_a) fill_malloc(_a)

View File

@ -1,366 +1,366 @@
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
* *
* 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 "bitq.h"
/* project specific includes */
#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
/* system includes */
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
bitq_interface_t *bitq_interface; /* low level bit queue interface */
bitq_state_t bitq_in_state; /* state of input queue */
u8 *bitq_in_buffer; /* buffer dynamically reallocated as needed */
unsigned long bitq_in_bufsize=32; /* min. buffer size */
/*
* input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
* also the buffer for incomming data is reallocated only if necessary
* no parameters, makes use of stored state information
*/
void bitq_in_proc(void)
{
/* static information preserved between calls to increase performance */
static u8 *in_buff; /* pointer to buffer for scanned data */
static int in_idx; /* index of byte being scanned */
static u8 in_mask; /* mask of next bit to be scanned */
scan_field_t *field;
int tdo;
/* loop through the queue */
while (bitq_in_state.cmd) {
/* only JTAG_SCAN command may return data */
if (bitq_in_state.cmd->type==JTAG_SCAN) {
/* loop through the fields */
while (bitq_in_state.field_idx<bitq_in_state.cmd->cmd.scan->num_fields) {
field=&bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
if ( field->in_value || field->in_handler) {
if (bitq_in_state.bit_pos==0) {
/* initialize field scanning */
in_mask=0x01;
in_idx=0;
if (field->in_value) in_buff=field->in_value;
else {
/* buffer reallocation needed? */
if (field->num_bits>bitq_in_bufsize*8) {
/* buffer previously allocated? */
if (bitq_in_buffer!=NULL) {
/* free it */
free(bitq_in_buffer);
bitq_in_buffer=NULL;
}
/* double the buffer size until it fits */
while (field->num_bits>bitq_in_bufsize*8) bitq_in_bufsize*=2;
}
/* if necessary, allocate buffer and check for malloc error */
if (bitq_in_buffer==NULL && (bitq_in_buffer=malloc(bitq_in_bufsize))==NULL) {
ERROR("malloc error");
exit(-1);
}
in_buff=(void *)bitq_in_buffer;
}
}
/* field scanning */
while (bitq_in_state.bit_pos<field->num_bits) {
if ((tdo=bitq_interface->in())<0) {
#ifdef _DEBUG_JTAG_IO_
DEBUG("bitq in EOF");
#endif
return;
}
if (in_mask==0x01) in_buff[in_idx]=0;
if (tdo) in_buff[in_idx]|=in_mask;
if (in_mask==0x80) {
in_mask=0x01;
in_idx++;
}
else in_mask<<=1;
bitq_in_state.bit_pos++;
}
if (field->in_handler && bitq_in_state.status==ERROR_OK) {
bitq_in_state.status=(*field->in_handler)(in_buff, field->in_handler_priv, field);
}
}
bitq_in_state.field_idx++; /* advance to next field */
bitq_in_state.bit_pos=0; /* start next field from the first bit */
}
}
bitq_in_state.cmd=bitq_in_state.cmd->next; /* advance to next command */
bitq_in_state.field_idx=0; /* preselect first field */
}
}
void bitq_io(int tms, int tdi, int tdo_req)
{
bitq_interface->out(tms, tdi, tdo_req);
/* check and process the input queue */
if (bitq_interface->in_rdy()) bitq_in_proc();
}
void bitq_end_state(enum tap_state state)
{
if (state==-1) return;
if (tap_move_map[state]==-1) {
ERROR("BUG: %i is not a valid end state", state);
exit(-1);
}
end_state = state;
}
void bitq_state_move(enum tap_state new_state)
{
int i=0;
u8 tms_scan;
if (tap_move_map[cur_state]==-1 || tap_move_map[new_state]==-1) {
ERROR("TAP move from or to unstable state");
exit(-1);
}
tms_scan=TAP_MOVE(cur_state, new_state);
for (i=0; i<7; i++) {
bitq_io(tms_scan&1, 0, 0);
tms_scan>>=1;
}
cur_state = new_state;
}
void bitq_path_move(pathmove_command_t *cmd)
{
int i;
for (i=0; i<=cmd->num_states; i++) {
if (tap_transitions[cur_state].low == cmd->path[i]) bitq_io(0, 0, 0);
else if (tap_transitions[cur_state].high == cmd->path[i]) bitq_io(1, 0, 0);
else {
ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[i]]);
exit(-1);
}
cur_state = cmd->path[i];
}
end_state = cur_state;
}
void bitq_runtest(int num_cycles)
{
int i;
/* only do a state_move when we're not already in RTI */
if (cur_state != TAP_RTI) bitq_state_move(TAP_RTI);
/* execute num_cycles */
for (i = 0; i < num_cycles; i++)
bitq_io(0, 0, 0);
/* finish in end_state */
if (cur_state != end_state) bitq_state_move(end_state);
}
void bitq_scan_field(scan_field_t *field, int pause)
{
int bit_cnt;
int tdo_req;
u8 *out_ptr;
u8 out_mask;
if ( field->in_value || field->in_handler) tdo_req=1;
else tdo_req=0;
if (field->out_value==NULL) {
/* just send zeros and request data from TDO */
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--)
bitq_io(0, 0, tdo_req);
bitq_io(pause, 0, tdo_req);
}
else {
/* send data, and optionally request TDO */
out_mask=0x01;
out_ptr=field->out_value;
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--) {
bitq_io(0, ((*out_ptr)&out_mask)!=0, tdo_req);
if (out_mask==0x80) {
out_mask=0x01;
out_ptr++;
}
else out_mask<<=1;
}
bitq_io(pause, ((*out_ptr)&out_mask)!=0, tdo_req);
}
if (pause) {
bitq_io(0,0,0);
if (cur_state==TAP_SI) cur_state=TAP_PI;
else if (cur_state==TAP_SD) cur_state=TAP_PD;
}
}
void bitq_scan(scan_command_t *cmd)
{
int i;
if (cmd->ir_scan) bitq_state_move(TAP_SI);
else bitq_state_move(TAP_SD);
for (i=0; i < cmd->num_fields-1; i++)
bitq_scan_field(&cmd->fields[i], 0);
bitq_scan_field(&cmd->fields[i], 1);
}
int bitq_execute_queue(void)
{
jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
bitq_in_state.cmd = jtag_command_queue;
bitq_in_state.field_idx = 0;
bitq_in_state.bit_pos = 0;
bitq_in_state.status = 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
bitq_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
bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
if (bitq_interface->in_rdy()) bitq_in_proc();
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
bitq_end_state(cmd->cmd.runtest->end_state);
bitq_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
bitq_end_state(cmd->cmd.statemove->end_state);
bitq_state_move(end_state); /* uncoditional TAP 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
bitq_path_move(cmd->cmd.pathmove);
break;
case JTAG_SCAN:
#ifdef _DEBUG_JTAG_IO_
DEBUG("scan end in %i", cmd->cmd.scan->end_state);
if (cmd->cmd.scan->ir_scan) DEBUG("scan ir");
else DEBUG("scan dr");
#endif
bitq_end_state(cmd->cmd.scan->end_state);
bitq_scan(cmd->cmd.scan);
if (cur_state != end_state) bitq_state_move(end_state);
break;
case JTAG_SLEEP:
#ifdef _DEBUG_JTAG_IO_
DEBUG("sleep %i", cmd->cmd.sleep->us);
#endif
bitq_interface->sleep(cmd->cmd.sleep->us);
if (bitq_interface->in_rdy()) bitq_in_proc();
break;
default:
ERROR("BUG: unknown JTAG command type encountered");
exit(-1);
}
cmd = cmd->next;
}
bitq_interface->flush();
bitq_in_proc();
if (bitq_in_state.cmd) {
ERROR("missing data from bitq interface");
return ERROR_JTAG_QUEUE_FAILED;
}
if (bitq_interface->in()>=0) {
ERROR("extra data from bitq interface");
return ERROR_JTAG_QUEUE_FAILED;
}
return bitq_in_state.status;
}
void bitq_cleanup(void)
{
if (bitq_in_buffer!=NULL)
{
free(bitq_in_buffer);
bitq_in_buffer=NULL;
}
}
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
* *
* 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 "bitq.h"
/* project specific includes */
#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
/* system includes */
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
bitq_interface_t *bitq_interface; /* low level bit queue interface */
bitq_state_t bitq_in_state; /* state of input queue */
u8 *bitq_in_buffer; /* buffer dynamically reallocated as needed */
unsigned long bitq_in_bufsize=32; /* min. buffer size */
/*
* input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
* also the buffer for incomming data is reallocated only if necessary
* no parameters, makes use of stored state information
*/
void bitq_in_proc(void)
{
/* static information preserved between calls to increase performance */
static u8 *in_buff; /* pointer to buffer for scanned data */
static int in_idx; /* index of byte being scanned */
static u8 in_mask; /* mask of next bit to be scanned */
scan_field_t *field;
int tdo;
/* loop through the queue */
while (bitq_in_state.cmd) {
/* only JTAG_SCAN command may return data */
if (bitq_in_state.cmd->type==JTAG_SCAN) {
/* loop through the fields */
while (bitq_in_state.field_idx<bitq_in_state.cmd->cmd.scan->num_fields) {
field=&bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
if ( field->in_value || field->in_handler) {
if (bitq_in_state.bit_pos==0) {
/* initialize field scanning */
in_mask=0x01;
in_idx=0;
if (field->in_value) in_buff=field->in_value;
else {
/* buffer reallocation needed? */
if (field->num_bits>bitq_in_bufsize*8) {
/* buffer previously allocated? */
if (bitq_in_buffer!=NULL) {
/* free it */
free(bitq_in_buffer);
bitq_in_buffer=NULL;
}
/* double the buffer size until it fits */
while (field->num_bits>bitq_in_bufsize*8) bitq_in_bufsize*=2;
}
/* if necessary, allocate buffer and check for malloc error */
if (bitq_in_buffer==NULL && (bitq_in_buffer=malloc(bitq_in_bufsize))==NULL) {
ERROR("malloc error");
exit(-1);
}
in_buff=(void *)bitq_in_buffer;
}
}
/* field scanning */
while (bitq_in_state.bit_pos<field->num_bits) {
if ((tdo=bitq_interface->in())<0) {
#ifdef _DEBUG_JTAG_IO_
DEBUG("bitq in EOF");
#endif
return;
}
if (in_mask==0x01) in_buff[in_idx]=0;
if (tdo) in_buff[in_idx]|=in_mask;
if (in_mask==0x80) {
in_mask=0x01;
in_idx++;
}
else in_mask<<=1;
bitq_in_state.bit_pos++;
}
if (field->in_handler && bitq_in_state.status==ERROR_OK) {
bitq_in_state.status=(*field->in_handler)(in_buff, field->in_handler_priv, field);
}
}
bitq_in_state.field_idx++; /* advance to next field */
bitq_in_state.bit_pos=0; /* start next field from the first bit */
}
}
bitq_in_state.cmd=bitq_in_state.cmd->next; /* advance to next command */
bitq_in_state.field_idx=0; /* preselect first field */
}
}
void bitq_io(int tms, int tdi, int tdo_req)
{
bitq_interface->out(tms, tdi, tdo_req);
/* check and process the input queue */
if (bitq_interface->in_rdy()) bitq_in_proc();
}
void bitq_end_state(enum tap_state state)
{
if (state==-1) return;
if (tap_move_map[state]==-1) {
ERROR("BUG: %i is not a valid end state", state);
exit(-1);
}
end_state = state;
}
void bitq_state_move(enum tap_state new_state)
{
int i=0;
u8 tms_scan;
if (tap_move_map[cur_state]==-1 || tap_move_map[new_state]==-1) {
ERROR("TAP move from or to unstable state");
exit(-1);
}
tms_scan=TAP_MOVE(cur_state, new_state);
for (i=0; i<7; i++) {
bitq_io(tms_scan&1, 0, 0);
tms_scan>>=1;
}
cur_state = new_state;
}
void bitq_path_move(pathmove_command_t *cmd)
{
int i;
for (i=0; i<=cmd->num_states; i++) {
if (tap_transitions[cur_state].low == cmd->path[i]) bitq_io(0, 0, 0);
else if (tap_transitions[cur_state].high == cmd->path[i]) bitq_io(1, 0, 0);
else {
ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[i]]);
exit(-1);
}
cur_state = cmd->path[i];
}
end_state = cur_state;
}
void bitq_runtest(int num_cycles)
{
int i;
/* only do a state_move when we're not already in RTI */
if (cur_state != TAP_RTI) bitq_state_move(TAP_RTI);
/* execute num_cycles */
for (i = 0; i < num_cycles; i++)
bitq_io(0, 0, 0);
/* finish in end_state */
if (cur_state != end_state) bitq_state_move(end_state);
}
void bitq_scan_field(scan_field_t *field, int pause)
{
int bit_cnt;
int tdo_req;
u8 *out_ptr;
u8 out_mask;
if ( field->in_value || field->in_handler) tdo_req=1;
else tdo_req=0;
if (field->out_value==NULL) {
/* just send zeros and request data from TDO */
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--)
bitq_io(0, 0, tdo_req);
bitq_io(pause, 0, tdo_req);
}
else {
/* send data, and optionally request TDO */
out_mask=0x01;
out_ptr=field->out_value;
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--) {
bitq_io(0, ((*out_ptr)&out_mask)!=0, tdo_req);
if (out_mask==0x80) {
out_mask=0x01;
out_ptr++;
}
else out_mask<<=1;
}
bitq_io(pause, ((*out_ptr)&out_mask)!=0, tdo_req);
}
if (pause) {
bitq_io(0,0,0);
if (cur_state==TAP_SI) cur_state=TAP_PI;
else if (cur_state==TAP_SD) cur_state=TAP_PD;
}
}
void bitq_scan(scan_command_t *cmd)
{
int i;
if (cmd->ir_scan) bitq_state_move(TAP_SI);
else bitq_state_move(TAP_SD);
for (i=0; i < cmd->num_fields-1; i++)
bitq_scan_field(&cmd->fields[i], 0);
bitq_scan_field(&cmd->fields[i], 1);
}
int bitq_execute_queue(void)
{
jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
bitq_in_state.cmd = jtag_command_queue;
bitq_in_state.field_idx = 0;
bitq_in_state.bit_pos = 0;
bitq_in_state.status = 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
bitq_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
bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
if (bitq_interface->in_rdy()) bitq_in_proc();
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
bitq_end_state(cmd->cmd.runtest->end_state);
bitq_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
bitq_end_state(cmd->cmd.statemove->end_state);
bitq_state_move(end_state); /* uncoditional TAP 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
bitq_path_move(cmd->cmd.pathmove);
break;
case JTAG_SCAN:
#ifdef _DEBUG_JTAG_IO_
DEBUG("scan end in %i", cmd->cmd.scan->end_state);
if (cmd->cmd.scan->ir_scan) DEBUG("scan ir");
else DEBUG("scan dr");
#endif
bitq_end_state(cmd->cmd.scan->end_state);
bitq_scan(cmd->cmd.scan);
if (cur_state != end_state) bitq_state_move(end_state);
break;
case JTAG_SLEEP:
#ifdef _DEBUG_JTAG_IO_
DEBUG("sleep %i", cmd->cmd.sleep->us);
#endif
bitq_interface->sleep(cmd->cmd.sleep->us);
if (bitq_interface->in_rdy()) bitq_in_proc();
break;
default:
ERROR("BUG: unknown JTAG command type encountered");
exit(-1);
}
cmd = cmd->next;
}
bitq_interface->flush();
bitq_in_proc();
if (bitq_in_state.cmd) {
ERROR("missing data from bitq interface");
return ERROR_JTAG_QUEUE_FAILED;
}
if (bitq_interface->in()>=0) {
ERROR("extra data from bitq interface");
return ERROR_JTAG_QUEUE_FAILED;
}
return bitq_in_state.status;
}
void bitq_cleanup(void)
{
if (bitq_in_buffer!=NULL)
{
free(bitq_in_buffer);
bitq_in_buffer=NULL;
}
}

View File

@ -1,237 +1,237 @@
/***************************************************************************
* 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 "log.h"
#include "jtag.h"
#include "bitbang.h"
#define TDO_BIT 1
#define TDI_BIT 2
#define TCK_BIT 4
#define TMS_BIT 8
#define TRST_BIT 16
#define SRST_BIT 32
#define VCC_BIT 64
/* system includes */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
static u8 output_value = 0x0;
static int dev_mem_fd;
static void *gpio_controller;
static volatile u8 *gpio_data_register;
static volatile u8 *gpio_data_direction_register;
/* low level command set
*/
int ep93xx_read(void);
void ep93xx_write(int tck, int tms, int tdi);
void ep93xx_reset(int trst, int srst);
int ep93xx_speed(int speed);
int ep93xx_register_commands(struct command_context_s *cmd_ctx);
int ep93xx_init(void);
int ep93xx_quit(void);
struct timespec ep93xx_zzzz;
jtag_interface_t ep93xx_interface =
{
.name = "ep93xx",
.execute_queue = bitbang_execute_queue,
.speed = ep93xx_speed,
.register_commands = ep93xx_register_commands,
.init = ep93xx_init,
.quit = ep93xx_quit,
};
bitbang_interface_t ep93xx_bitbang =
{
.read = ep93xx_read,
.write = ep93xx_write,
.reset = ep93xx_reset,
.blink = 0;
};
int ep93xx_read(void)
{
return !!(*gpio_data_register & TDO_BIT);
}
void ep93xx_write(int tck, int tms, int tdi)
{
if (tck)
output_value |= TCK_BIT;
else
output_value &= TCK_BIT;
if (tms)
output_value |= TMS_BIT;
else
output_value &= TMS_BIT;
if (tdi)
output_value |= TDI_BIT;
else
output_value &= TDI_BIT;
*gpio_data_register = output_value;
nanosleep(ep93xx_zzzz);
}
/* (1) assert or (0) deassert reset lines */
void ep93xx_reset(int trst, int srst)
{
if (trst == 0)
output_value |= TRST_BIT;
else if (trst == 1)
output_value &= TRST_BIT;
if (srst == 0)
output_value |= SRST_BIT;
else if (srst == 1)
output_value &= SRST_BIT;
*gpio_data_register = output_value;
nanosleep(ep93xx_zzzz);
}
int ep93xx_speed(int speed)
{
return ERROR_OK;
}
int ep93xx_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
static int set_gonk_mode(void)
{
void *syscon;
u32 devicecfg;
syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, 0x80930000);
if (syscon == MAP_FAILED) {
perror("mmap");
return ERROR_JTAG_INIT_FAILED;
}
devicecfg = *((volatile int *)(syscon + 0x80));
*((volatile int *)(syscon + 0xc0)) = 0xaa;
*((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;
munmap(syscon, 4096);
return ERROR_OK;
}
int ep93xx_init(void)
{
int ret;
bitbang_interface = &ep93xx_bitbang;
ep93xx_zzzz.tv_sec = 0;
ep93xx_zzzz.tv_nsec = 10000000;
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (dev_mem_fd < 0) {
perror("open");
return ERROR_JTAG_INIT_FAILED;
}
gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, 0x80840000);
if (gpio_controller == MAP_FAILED) {
perror("mmap");
close(dev_mem_fd);
return ERROR_JTAG_INIT_FAILED;
}
ret = set_gonk_mode();
if (ret != ERROR_OK) {
munmap(gpio_controller, 4096);
close(dev_mem_fd);
return ret;
}
#if 0
/* Use GPIO port A. */
gpio_data_register = gpio_controller + 0x00;
gpio_data_direction_register = gpio_controller + 0x10;
/* Use GPIO port B. */
gpio_data_register = gpio_controller + 0x04;
gpio_data_direction_register = gpio_controller + 0x14;
/* Use GPIO port C. */
gpio_data_register = gpio_controller + 0x08;
gpio_data_direction_register = gpio_controller + 0x18;
/* Use GPIO port D. */
gpio_data_register = gpio_controller + 0x0c;
gpio_data_direction_register = gpio_controller + 0x1c;
#endif
/* Use GPIO port C. */
gpio_data_register = gpio_controller + 0x08;
gpio_data_direction_register = gpio_controller + 0x18;
INFO("gpio_data_register = %p\n", gpio_data_register);
INFO("gpio_data_direction_reg = %p\n", gpio_data_direction_register);
/*
* Configure bit 0 (TDO) as an input, and bits 1-5 (TDI, TCK
* TMS, TRST, SRST) as outputs. Drive TDI and TCK low, and
* TMS/TRST/SRST high.
*/
output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
*gpio_data_register = output_value;
nanosleep(ep93xx_zzzz);
/*
* Configure the direction register. 1 = output, 0 = input.
*/
*gpio_data_direction_register =
TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
nanosleep(ep93xx_zzzz);
return ERROR_OK;
}
int ep93xx_quit(void)
{
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 "log.h"
#include "jtag.h"
#include "bitbang.h"
#define TDO_BIT 1
#define TDI_BIT 2
#define TCK_BIT 4
#define TMS_BIT 8
#define TRST_BIT 16
#define SRST_BIT 32
#define VCC_BIT 64
/* system includes */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
static u8 output_value = 0x0;
static int dev_mem_fd;
static void *gpio_controller;
static volatile u8 *gpio_data_register;
static volatile u8 *gpio_data_direction_register;
/* low level command set
*/
int ep93xx_read(void);
void ep93xx_write(int tck, int tms, int tdi);
void ep93xx_reset(int trst, int srst);
int ep93xx_speed(int speed);
int ep93xx_register_commands(struct command_context_s *cmd_ctx);
int ep93xx_init(void);
int ep93xx_quit(void);
struct timespec ep93xx_zzzz;
jtag_interface_t ep93xx_interface =
{
.name = "ep93xx",
.execute_queue = bitbang_execute_queue,
.speed = ep93xx_speed,
.register_commands = ep93xx_register_commands,
.init = ep93xx_init,
.quit = ep93xx_quit,
};
bitbang_interface_t ep93xx_bitbang =
{
.read = ep93xx_read,
.write = ep93xx_write,
.reset = ep93xx_reset,
.blink = 0;
};
int ep93xx_read(void)
{
return !!(*gpio_data_register & TDO_BIT);
}
void ep93xx_write(int tck, int tms, int tdi)
{
if (tck)
output_value |= TCK_BIT;
else
output_value &= TCK_BIT;
if (tms)
output_value |= TMS_BIT;
else
output_value &= TMS_BIT;
if (tdi)
output_value |= TDI_BIT;
else
output_value &= TDI_BIT;
*gpio_data_register = output_value;
nanosleep(ep93xx_zzzz);
}
/* (1) assert or (0) deassert reset lines */
void ep93xx_reset(int trst, int srst)
{
if (trst == 0)
output_value |= TRST_BIT;
else if (trst == 1)
output_value &= TRST_BIT;
if (srst == 0)
output_value |= SRST_BIT;
else if (srst == 1)
output_value &= SRST_BIT;
*gpio_data_register = output_value;
nanosleep(ep93xx_zzzz);
}
int ep93xx_speed(int speed)
{
return ERROR_OK;
}
int ep93xx_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
static int set_gonk_mode(void)
{
void *syscon;
u32 devicecfg;
syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, 0x80930000);
if (syscon == MAP_FAILED) {
perror("mmap");
return ERROR_JTAG_INIT_FAILED;
}
devicecfg = *((volatile int *)(syscon + 0x80));
*((volatile int *)(syscon + 0xc0)) = 0xaa;
*((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;
munmap(syscon, 4096);
return ERROR_OK;
}
int ep93xx_init(void)
{
int ret;
bitbang_interface = &ep93xx_bitbang;
ep93xx_zzzz.tv_sec = 0;
ep93xx_zzzz.tv_nsec = 10000000;
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (dev_mem_fd < 0) {
perror("open");
return ERROR_JTAG_INIT_FAILED;
}
gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, 0x80840000);
if (gpio_controller == MAP_FAILED) {
perror("mmap");
close(dev_mem_fd);
return ERROR_JTAG_INIT_FAILED;
}
ret = set_gonk_mode();
if (ret != ERROR_OK) {
munmap(gpio_controller, 4096);
close(dev_mem_fd);
return ret;
}
#if 0
/* Use GPIO port A. */
gpio_data_register = gpio_controller + 0x00;
gpio_data_direction_register = gpio_controller + 0x10;
/* Use GPIO port B. */
gpio_data_register = gpio_controller + 0x04;
gpio_data_direction_register = gpio_controller + 0x14;
/* Use GPIO port C. */
gpio_data_register = gpio_controller + 0x08;
gpio_data_direction_register = gpio_controller + 0x18;
/* Use GPIO port D. */
gpio_data_register = gpio_controller + 0x0c;
gpio_data_direction_register = gpio_controller + 0x1c;
#endif
/* Use GPIO port C. */
gpio_data_register = gpio_controller + 0x08;
gpio_data_direction_register = gpio_controller + 0x18;
INFO("gpio_data_register = %p\n", gpio_data_register);
INFO("gpio_data_direction_reg = %p\n", gpio_data_direction_register);
/*
* Configure bit 0 (TDO) as an input, and bits 1-5 (TDI, TCK
* TMS, TRST, SRST) as outputs. Drive TDI and TCK low, and
* TMS/TRST/SRST high.
*/
output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
*gpio_data_register = output_value;
nanosleep(ep93xx_zzzz);
/*
* Configure the direction register. 1 = output, 0 = input.
*/
*gpio_data_direction_register =
TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
nanosleep(ep93xx_zzzz);
return ERROR_OK;
}
int ep93xx_quit(void)
{
return ERROR_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,157 +1,157 @@
/***************************************************************************
* 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. *
***************************************************************************/
#define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
#include "interpreter.h"
#include "xsvf.h"
#include "target.h"
#include "flash.h"
#include "nand.h"
#include "pld.h"
#include "command.h"
#include "server.h"
#include "telnet_server.h"
#include "gdb_server.h"
#include <sys/time.h>
#include <sys/types.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
/* Give TELNET a way to find out what version this is */
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
command_print(cmd_ctx, OPENOCD_VERSION);
return ERROR_OK;
}
void exit_handler(void)
{
/* close JTAG interface */
if (jtag && jtag->quit)
jtag->quit();
}
int main(int argc, char *argv[])
{
/* initialize commandline interface */
command_context_t *cmd_ctx, *cfg_cmd_ctx;
cmd_ctx = command_init();
register_command(cmd_ctx, NULL, "version", handle_version_command,
COMMAND_EXEC, "show OpenOCD version");
/* register subsystem commands */
server_register_commands(cmd_ctx);
telnet_register_commands(cmd_ctx);
gdb_register_commands(cmd_ctx);
log_register_commands(cmd_ctx);
jtag_register_commands(cmd_ctx);
interpreter_register_commands(cmd_ctx);
xsvf_register_commands(cmd_ctx);
target_register_commands(cmd_ctx);
flash_register_commands(cmd_ctx);
nand_register_commands(cmd_ctx);
pld_register_commands(cmd_ctx);
if (log_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("log init complete");
printf( OPENOCD_VERSION );
printf( "\n$URL$\n");
DEBUG( OPENOCD_VERSION );
DEBUG( "$URL$");
cfg_cmd_ctx = copy_command_context(cmd_ctx);
cfg_cmd_ctx->mode = COMMAND_CONFIG;
command_set_output_handler(cfg_cmd_ctx, configuration_output_handler, NULL);
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
return EXIT_FAILURE;
if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
command_done(cfg_cmd_ctx);
command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
atexit(exit_handler);
if (jtag_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("jtag init complete");
if (target_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("target init complete");
if (flash_init_drivers(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("flash init complete");
if (nand_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("NAND init complete");
if (pld_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("pld init complete");
/* initialize tcp server */
server_init();
/* initialize telnet subsystem */
telnet_init("Open On-Chip Debugger");
gdb_init();
/* call any target resets */
if (target_init_reset(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("target init reset complete");
/* handle network connections */
server_loop(cmd_ctx);
/* shut server down */
server_quit();
/* free commandline interface */
command_done(cmd_ctx);
return EXIT_SUCCESS;
}
/***************************************************************************
* 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. *
***************************************************************************/
#define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
#include "interpreter.h"
#include "xsvf.h"
#include "target.h"
#include "flash.h"
#include "nand.h"
#include "pld.h"
#include "command.h"
#include "server.h"
#include "telnet_server.h"
#include "gdb_server.h"
#include <sys/time.h>
#include <sys/types.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
/* Give TELNET a way to find out what version this is */
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
command_print(cmd_ctx, OPENOCD_VERSION);
return ERROR_OK;
}
void exit_handler(void)
{
/* close JTAG interface */
if (jtag && jtag->quit)
jtag->quit();
}
int main(int argc, char *argv[])
{
/* initialize commandline interface */
command_context_t *cmd_ctx, *cfg_cmd_ctx;
cmd_ctx = command_init();
register_command(cmd_ctx, NULL, "version", handle_version_command,
COMMAND_EXEC, "show OpenOCD version");
/* register subsystem commands */
server_register_commands(cmd_ctx);
telnet_register_commands(cmd_ctx);
gdb_register_commands(cmd_ctx);
log_register_commands(cmd_ctx);
jtag_register_commands(cmd_ctx);
interpreter_register_commands(cmd_ctx);
xsvf_register_commands(cmd_ctx);
target_register_commands(cmd_ctx);
flash_register_commands(cmd_ctx);
nand_register_commands(cmd_ctx);
pld_register_commands(cmd_ctx);
if (log_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("log init complete");
printf( OPENOCD_VERSION );
printf( "\n$URL$\n");
DEBUG( OPENOCD_VERSION );
DEBUG( "$URL$");
cfg_cmd_ctx = copy_command_context(cmd_ctx);
cfg_cmd_ctx->mode = COMMAND_CONFIG;
command_set_output_handler(cfg_cmd_ctx, configuration_output_handler, NULL);
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
return EXIT_FAILURE;
if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
command_done(cfg_cmd_ctx);
command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
atexit(exit_handler);
if (jtag_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("jtag init complete");
if (target_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("target init complete");
if (flash_init_drivers(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("flash init complete");
if (nand_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("NAND init complete");
if (pld_init(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("pld init complete");
/* initialize tcp server */
server_init();
/* initialize telnet subsystem */
telnet_init("Open On-Chip Debugger");
gdb_init();
/* call any target resets */
if (target_init_reset(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
DEBUG("target init reset complete");
/* handle network connections */
server_loop(cmd_ctx);
/* shut server down */
server_quit();
/* free commandline interface */
command_done(cmd_ctx);
return EXIT_SUCCESS;
}

View File

@ -1,264 +1,264 @@
/***************************************************************************
* 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 "virtex2.h"
#include "pld.h"
#include "xilinx_bit.h"
#include "command.h"
#include "log.h"
#include "jtag.h"
#include <stdlib.h>
int virtex2_register_commands(struct command_context_s *cmd_ctx);
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device);
int virtex2_load(struct pld_device_s *pld_device, char *filename);
pld_driver_t virtex2_pld =
{
.name = "virtex2",
.register_commands = virtex2_register_commands,
.pld_device_command = virtex2_pld_device_command,
.load = virtex2_load,
};
int virtex2_set_instr(int chain_pos, u32 new_instr)
{
jtag_device_t *device = jtag_get_device(chain_pos);
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
{
scan_field_t field;
field.device = chain_pos;
field.num_bits = device->ir_length;
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
field.out_mask = NULL;
field.in_value = NULL;
field.in_check_value = NULL;
field.in_check_mask = NULL;
field.in_handler = NULL;
field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, TAP_RTI);
free(field.out_value);
}
return ERROR_OK;
}
int virtex2_send_32(struct pld_device_s *pld_device, int num_words, u32 *words)
{
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
scan_field_t scan_field;
u8 *values;
int i;
values = malloc(num_words * 4);
scan_field.device = virtex2_info->chain_pos;
scan_field.num_bits = num_words * 32;
scan_field.out_value = values;
scan_field.out_mask = NULL;
scan_field.in_value = NULL;
scan_field.in_check_value = NULL;
scan_field.in_check_mask = NULL;
scan_field.in_handler = NULL;
scan_field.in_handler_priv = NULL;
for (i = 0; i < num_words; i++)
buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
jtag_add_dr_scan(1, &scan_field, TAP_PD);
free(values);
return ERROR_OK;
}
int virtex2_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u32 *dest = priv;
*dest = flip_u32(le_to_h_u32(in_buf), 32);
return ERROR_OK;
}
int virtex2_receive_32(struct pld_device_s *pld_device, int num_words, u32 *words)
{
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
scan_field_t scan_field;
scan_field.device = virtex2_info->chain_pos;
scan_field.num_bits = 32;
scan_field.out_value = NULL;
scan_field.out_mask = NULL;
scan_field.in_value = NULL;
scan_field.in_check_value = NULL;
scan_field.in_check_mask = NULL;
scan_field.in_handler = virtex2_jtag_buf_to_u32;
virtex2_set_instr(virtex2_info->chain_pos, 0x4); /* CFG_OUT */
while (num_words--)
{
scan_field.in_handler_priv = words++;
jtag_add_dr_scan(1, &scan_field, TAP_PD);
}
return ERROR_OK;
}
int virtex2_read_stat(struct pld_device_s *pld_device, u32 *status)
{
u32 data[5];
jtag_add_statemove(TAP_TLR);
data[0] = 0xaa995566; /* synch word */
data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
data[3] = 0x20000000; /* NOOP */
data[4] = 0x20000000; /* NOOP */
virtex2_send_32(pld_device, 5, data);
virtex2_receive_32(pld_device, 1, status);
jtag_execute_queue();
DEBUG("status: 0x%8.8x", *status);
return ERROR_OK;
}
int virtex2_load(struct pld_device_s *pld_device, char *filename)
{
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
xilinx_bit_file_t bit_file;
int retval;
int i;
scan_field_t field;
field.device = virtex2_info->chain_pos;
field.out_mask = NULL;
field.in_value = NULL;
field.in_check_value = NULL;
field.in_check_mask = NULL;
field.in_handler = NULL;
field.in_handler_priv = NULL;
if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
return retval;
jtag_add_end_state(TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0xb); /* JPROG_B */
jtag_execute_queue();
jtag_add_sleep(1000);
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
jtag_execute_queue();
for (i = 0; i < bit_file.length; i++)
bit_file.data[i] = flip_u32(bit_file.data[i], 8);
field.num_bits = bit_file.length * 8;
field.out_value = bit_file.data;
jtag_add_dr_scan(1, &field, TAP_PD);
jtag_execute_queue();
jtag_add_statemove(TAP_TLR);
jtag_add_end_state(TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
jtag_add_runtest(13, TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
jtag_add_runtest(13, TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
jtag_execute_queue();
return ERROR_OK;
}
int virtex2_handle_read_stat_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
pld_device_t *device;
virtex2_pld_device_t *virtex2_info;
u32 status;
if (argc < 1)
{
command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
return ERROR_OK;
}
device = get_pld_device_by_num(strtoul(args[0], NULL, 0));
if (!device)
{
command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
virtex2_info = device->driver_priv;
virtex2_read_stat(device, &status);
command_print(cmd_ctx, "virtex2 status register: 0x%8.8x", status);
return ERROR_OK;
}
int virtex2_register_commands(struct command_context_s *cmd_ctx)
{
command_t *virtex2_cmd = register_command(cmd_ctx, NULL, "virtex2", NULL, COMMAND_ANY, "virtex2 specific commands");
register_command(cmd_ctx, virtex2_cmd, "read_stat", virtex2_handle_read_stat_command, COMMAND_EXEC,
"read Virtex-II status register");
return ERROR_OK;
}
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device)
{
virtex2_pld_device_t *virtex2_info;
if (argc < 2)
{
WARNING("incomplete pld device 'virtex2' configuration");
return ERROR_PLD_DEVICE_INVALID;
}
virtex2_info = malloc(sizeof(virtex2_pld_device_t));
pld_device->driver_priv = virtex2_info;
virtex2_info->chain_pos = strtoul(args[1], 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 "virtex2.h"
#include "pld.h"
#include "xilinx_bit.h"
#include "command.h"
#include "log.h"
#include "jtag.h"
#include <stdlib.h>
int virtex2_register_commands(struct command_context_s *cmd_ctx);
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device);
int virtex2_load(struct pld_device_s *pld_device, char *filename);
pld_driver_t virtex2_pld =
{
.name = "virtex2",
.register_commands = virtex2_register_commands,
.pld_device_command = virtex2_pld_device_command,
.load = virtex2_load,
};
int virtex2_set_instr(int chain_pos, u32 new_instr)
{
jtag_device_t *device = jtag_get_device(chain_pos);
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
{
scan_field_t field;
field.device = chain_pos;
field.num_bits = device->ir_length;
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
field.out_mask = NULL;
field.in_value = NULL;
field.in_check_value = NULL;
field.in_check_mask = NULL;
field.in_handler = NULL;
field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, TAP_RTI);
free(field.out_value);
}
return ERROR_OK;
}
int virtex2_send_32(struct pld_device_s *pld_device, int num_words, u32 *words)
{
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
scan_field_t scan_field;
u8 *values;
int i;
values = malloc(num_words * 4);
scan_field.device = virtex2_info->chain_pos;
scan_field.num_bits = num_words * 32;
scan_field.out_value = values;
scan_field.out_mask = NULL;
scan_field.in_value = NULL;
scan_field.in_check_value = NULL;
scan_field.in_check_mask = NULL;
scan_field.in_handler = NULL;
scan_field.in_handler_priv = NULL;
for (i = 0; i < num_words; i++)
buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
jtag_add_dr_scan(1, &scan_field, TAP_PD);
free(values);
return ERROR_OK;
}
int virtex2_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u32 *dest = priv;
*dest = flip_u32(le_to_h_u32(in_buf), 32);
return ERROR_OK;
}
int virtex2_receive_32(struct pld_device_s *pld_device, int num_words, u32 *words)
{
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
scan_field_t scan_field;
scan_field.device = virtex2_info->chain_pos;
scan_field.num_bits = 32;
scan_field.out_value = NULL;
scan_field.out_mask = NULL;
scan_field.in_value = NULL;
scan_field.in_check_value = NULL;
scan_field.in_check_mask = NULL;
scan_field.in_handler = virtex2_jtag_buf_to_u32;
virtex2_set_instr(virtex2_info->chain_pos, 0x4); /* CFG_OUT */
while (num_words--)
{
scan_field.in_handler_priv = words++;
jtag_add_dr_scan(1, &scan_field, TAP_PD);
}
return ERROR_OK;
}
int virtex2_read_stat(struct pld_device_s *pld_device, u32 *status)
{
u32 data[5];
jtag_add_statemove(TAP_TLR);
data[0] = 0xaa995566; /* synch word */
data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
data[3] = 0x20000000; /* NOOP */
data[4] = 0x20000000; /* NOOP */
virtex2_send_32(pld_device, 5, data);
virtex2_receive_32(pld_device, 1, status);
jtag_execute_queue();
DEBUG("status: 0x%8.8x", *status);
return ERROR_OK;
}
int virtex2_load(struct pld_device_s *pld_device, char *filename)
{
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
xilinx_bit_file_t bit_file;
int retval;
int i;
scan_field_t field;
field.device = virtex2_info->chain_pos;
field.out_mask = NULL;
field.in_value = NULL;
field.in_check_value = NULL;
field.in_check_mask = NULL;
field.in_handler = NULL;
field.in_handler_priv = NULL;
if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
return retval;
jtag_add_end_state(TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0xb); /* JPROG_B */
jtag_execute_queue();
jtag_add_sleep(1000);
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
jtag_execute_queue();
for (i = 0; i < bit_file.length; i++)
bit_file.data[i] = flip_u32(bit_file.data[i], 8);
field.num_bits = bit_file.length * 8;
field.out_value = bit_file.data;
jtag_add_dr_scan(1, &field, TAP_PD);
jtag_execute_queue();
jtag_add_statemove(TAP_TLR);
jtag_add_end_state(TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
jtag_add_runtest(13, TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
jtag_add_runtest(13, TAP_RTI);
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
jtag_execute_queue();
return ERROR_OK;
}
int virtex2_handle_read_stat_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
pld_device_t *device;
virtex2_pld_device_t *virtex2_info;
u32 status;
if (argc < 1)
{
command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
return ERROR_OK;
}
device = get_pld_device_by_num(strtoul(args[0], NULL, 0));
if (!device)
{
command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
return ERROR_OK;
}
virtex2_info = device->driver_priv;
virtex2_read_stat(device, &status);
command_print(cmd_ctx, "virtex2 status register: 0x%8.8x", status);
return ERROR_OK;
}
int virtex2_register_commands(struct command_context_s *cmd_ctx)
{
command_t *virtex2_cmd = register_command(cmd_ctx, NULL, "virtex2", NULL, COMMAND_ANY, "virtex2 specific commands");
register_command(cmd_ctx, virtex2_cmd, "read_stat", virtex2_handle_read_stat_command, COMMAND_EXEC,
"read Virtex-II status register");
return ERROR_OK;
}
int virtex2_pld_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct pld_device_s *pld_device)
{
virtex2_pld_device_t *virtex2_info;
if (argc < 2)
{
WARNING("incomplete pld device 'virtex2' configuration");
return ERROR_PLD_DEVICE_INVALID;
}
virtex2_info = malloc(sizeof(virtex2_pld_device_t));
pld_device->driver_priv = virtex2_info;
virtex2_info->chain_pos = strtoul(args[1], NULL, 0);
return ERROR_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,450 +1,450 @@
/***************************************************************************
* 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 "server.h"
#include "log.h"
#include "telnet_server.h"
#include "target.h"
#include <command.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
service_t *services = NULL;
/* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
static int shutdown_openocd = 0;
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int add_connection(service_t *service, command_context_t *cmd_ctx)
{
unsigned int address_size;
connection_t *c, **p;
int retval;
c = malloc(sizeof(connection_t));
c->fd = -1;
memset(&c->sin, 0, sizeof(c->sin));
c->cmd_ctx = copy_command_context(cmd_ctx);
c->service = service;
c->input_pending = 0;
c->priv = NULL;
c->next = NULL;
address_size = sizeof(c->sin);
c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
if ((retval = service->new_connection(c)) == ERROR_OK)
{
INFO("accepted '%s' connection from %i", service->name, c->sin.sin_port);
}
else
{
close_socket(c->fd);
INFO("attempted '%s' connection rejected", service->name);
free(c);
}
/* add to the end of linked list */
for (p = &service->connections; *p; p = &(*p)->next);
*p = c;
service->max_connections--;
return ERROR_OK;
}
int remove_connection(service_t *service, connection_t *connection)
{
connection_t **p = &service->connections;
connection_t *c;
/* find connection */
while(c = *p)
{
if (c->fd == connection->fd)
{
service->connection_closed(c);
close_socket(c->fd);
command_done(c->cmd_ctx);
/* delete connection */
*p = c->next;
free(c);
service->max_connections++;
break;
}
/* redirect p to next list pointer */
p = &(*p)->next;
}
return ERROR_OK;
}
int add_service(char *name, enum connection_type type, unsigned short port, int max_connections, new_connection_handler_t new_connection_handler, input_handler_t input_handler, connection_closed_handler_t connection_closed_handler, void *priv)
{
service_t *c, **p;
int so_reuseaddr_option = 1;
c = malloc(sizeof(service_t));
c->name = strdup(name);
c->type = type;
c->port = port;
c->max_connections = max_connections;
c->fd = -1;
c->connections = NULL;
c->new_connection = new_connection_handler;
c->input = input_handler;
c->connection_closed = connection_closed_handler;
c->priv = priv;
c->next = NULL;
if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
ERROR("error creating socket: %s", strerror(errno));
exit(-1);
}
setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
socket_nonblock(c->fd);
memset(&c->sin, 0, sizeof(c->sin));
c->sin.sin_family = AF_INET;
c->sin.sin_addr.s_addr = INADDR_ANY;
c->sin.sin_port = htons(port);
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
{
ERROR("couldn't bind to socket: %s", strerror(errno));
exit(-1);
}
if (listen(c->fd, 1) == -1)
{
ERROR("couldn't listen on socket: %s", strerror(errno));
exit(-1);
}
/* add to the end of linked list */
for (p = &services; *p; p = &(*p)->next);
*p = c;
return ERROR_OK;
}
int remove_service(unsigned short port)
{
service_t **p = &services;
service_t *c;
/* find service */
while(c = *p)
{
if (c->port == port)
{
if (c->name)
free(c->name);
if (c->priv)
free(c->priv);
/* delete service */
*p = c->next;
free(c);
}
/* redirect p to next list pointer */
p = &(*p)->next;
}
return ERROR_OK;
}
int remove_services()
{
service_t *c = services;
/* loop service */
while(c)
{
service_t *next = c->next;
if (c->name)
free(c->name);
if (c->priv)
free(c->priv);
/* delete service */
free(c);
/* remember the last service for unlinking */
c = next;
}
services = NULL;
return ERROR_OK;
}
int server_loop(command_context_t *command_context)
{
service_t *service;
/* used in select() */
fd_set read_fds;
struct timeval tv;
int fd_max;
/* used in accept() */
int retval;
#ifndef _WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
ERROR("couldn't set SIGPIPE to SIG_IGN");
#endif
/* do regular tasks after at most 10ms */
tv.tv_sec = 0;
tv.tv_usec = 10000;
while(!shutdown_openocd)
{
/* monitor sockets for acitvity */
fd_max = 0;
FD_ZERO(&read_fds);
/* add service and connection fds to read_fds */
for (service = services; service; service = service->next)
{
if (service->fd != -1)
{
/* listen for new connections */
FD_SET(service->fd, &read_fds);
if (service->fd > fd_max)
fd_max = service->fd;
}
if (service->connections)
{
connection_t *c;
for (c = service->connections; c; c = c->next)
{
/* check for activity on the connection */
FD_SET(c->fd, &read_fds);
if (c->fd > fd_max)
fd_max = c->fd;
}
}
}
#ifndef _WIN32
/* add STDIN to read_fds */
FD_SET(fileno(stdin), &read_fds);
#endif
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
if (retval == -1)
{
#ifdef _WIN32
errno = WSAGetLastError();
if (errno == WSAEINTR)
FD_ZERO(&read_fds);
else
{
ERROR("error during select: %s", strerror(errno));
exit(-1);
}
#else
if (errno == EINTR)
{
FD_ZERO(&read_fds);
}
else
{
ERROR("error during select: %s", strerror(errno));
exit(-1);
}
#endif
}
target_call_timer_callbacks();
if (retval == 0)
{
/* do regular tasks after at most 100ms */
tv.tv_sec = 0;
tv.tv_usec = 10000;
FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */
}
for (service = services; service; service = service->next)
{
/* handle new connections on listeners */
if ((service->fd != -1)
&& (FD_ISSET(service->fd, &read_fds)))
{
if (service->max_connections > 0)
{
add_connection(service, command_context);
}
else
{
struct sockaddr_in sin;
unsigned int address_size = sizeof(sin);
int tmp_fd;
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
close_socket(tmp_fd);
INFO("rejected '%s' connection, no more connections allowed", service->name);
}
}
/* handle activity on connections */
if (service->connections)
{
connection_t *c;
for (c = service->connections; c;)
{
if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
{
if (service->input(c) != ERROR_OK)
{
connection_t *next = c->next;
remove_connection(service, c);
INFO("dropped '%s' connection", service->name);
c = next;
continue;
}
}
c = c->next;
}
}
}
#ifndef _WIN32
if (FD_ISSET(fileno(stdin), &read_fds))
{
if (getc(stdin) == 'x')
{
shutdown_openocd = 1;
}
}
#else
MSG msg;
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
shutdown_openocd = 1;
}
#endif
}
return ERROR_OK;
}
#ifdef _WIN32
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
{
shutdown_openocd = 1;
return TRUE;
}
void sig_handler(int sig) {
shutdown_openocd = 1;
}
#endif
int server_init()
{
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
ERROR("Failed to Open Winsock");
exit(-1);
}
SetConsoleCtrlHandler( ControlHandler, TRUE );
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGBREAK, sig_handler);
signal(SIGABRT, sig_handler);
#endif
return ERROR_OK;
}
int server_quit()
{
remove_services();
#ifdef _WIN32
WSACleanup();
SetConsoleCtrlHandler( ControlHandler, FALSE );
#endif
return ERROR_OK;
}
int server_register_commands(command_context_t *context)
{
register_command(context, NULL, "shutdown", handle_shutdown_command,
COMMAND_ANY, "shut the server down");
return ERROR_OK;
}
/* tell the server we want to shut down */
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
shutdown_openocd = 1;
return ERROR_COMMAND_CLOSE_CONNECTION;
}
/***************************************************************************
* 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 "server.h"
#include "log.h"
#include "telnet_server.h"
#include "target.h"
#include <command.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
service_t *services = NULL;
/* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
static int shutdown_openocd = 0;
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int add_connection(service_t *service, command_context_t *cmd_ctx)
{
unsigned int address_size;
connection_t *c, **p;
int retval;
c = malloc(sizeof(connection_t));
c->fd = -1;
memset(&c->sin, 0, sizeof(c->sin));
c->cmd_ctx = copy_command_context(cmd_ctx);
c->service = service;
c->input_pending = 0;
c->priv = NULL;
c->next = NULL;
address_size = sizeof(c->sin);
c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
if ((retval = service->new_connection(c)) == ERROR_OK)
{
INFO("accepted '%s' connection from %i", service->name, c->sin.sin_port);
}
else
{
close_socket(c->fd);
INFO("attempted '%s' connection rejected", service->name);
free(c);
}
/* add to the end of linked list */
for (p = &service->connections; *p; p = &(*p)->next);
*p = c;
service->max_connections--;
return ERROR_OK;
}
int remove_connection(service_t *service, connection_t *connection)
{
connection_t **p = &service->connections;
connection_t *c;
/* find connection */
while(c = *p)
{
if (c->fd == connection->fd)
{
service->connection_closed(c);
close_socket(c->fd);
command_done(c->cmd_ctx);
/* delete connection */
*p = c->next;
free(c);
service->max_connections++;
break;
}
/* redirect p to next list pointer */
p = &(*p)->next;
}
return ERROR_OK;
}
int add_service(char *name, enum connection_type type, unsigned short port, int max_connections, new_connection_handler_t new_connection_handler, input_handler_t input_handler, connection_closed_handler_t connection_closed_handler, void *priv)
{
service_t *c, **p;
int so_reuseaddr_option = 1;
c = malloc(sizeof(service_t));
c->name = strdup(name);
c->type = type;
c->port = port;
c->max_connections = max_connections;
c->fd = -1;
c->connections = NULL;
c->new_connection = new_connection_handler;
c->input = input_handler;
c->connection_closed = connection_closed_handler;
c->priv = priv;
c->next = NULL;
if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
ERROR("error creating socket: %s", strerror(errno));
exit(-1);
}
setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
socket_nonblock(c->fd);
memset(&c->sin, 0, sizeof(c->sin));
c->sin.sin_family = AF_INET;
c->sin.sin_addr.s_addr = INADDR_ANY;
c->sin.sin_port = htons(port);
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
{
ERROR("couldn't bind to socket: %s", strerror(errno));
exit(-1);
}
if (listen(c->fd, 1) == -1)
{
ERROR("couldn't listen on socket: %s", strerror(errno));
exit(-1);
}
/* add to the end of linked list */
for (p = &services; *p; p = &(*p)->next);
*p = c;
return ERROR_OK;
}
int remove_service(unsigned short port)
{
service_t **p = &services;
service_t *c;
/* find service */
while(c = *p)
{
if (c->port == port)
{
if (c->name)
free(c->name);
if (c->priv)
free(c->priv);
/* delete service */
*p = c->next;
free(c);
}
/* redirect p to next list pointer */
p = &(*p)->next;
}
return ERROR_OK;
}
int remove_services()
{
service_t *c = services;
/* loop service */
while(c)
{
service_t *next = c->next;
if (c->name)
free(c->name);
if (c->priv)
free(c->priv);
/* delete service */
free(c);
/* remember the last service for unlinking */
c = next;
}
services = NULL;
return ERROR_OK;
}
int server_loop(command_context_t *command_context)
{
service_t *service;
/* used in select() */
fd_set read_fds;
struct timeval tv;
int fd_max;
/* used in accept() */
int retval;
#ifndef _WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
ERROR("couldn't set SIGPIPE to SIG_IGN");
#endif
/* do regular tasks after at most 10ms */
tv.tv_sec = 0;
tv.tv_usec = 10000;
while(!shutdown_openocd)
{
/* monitor sockets for acitvity */
fd_max = 0;
FD_ZERO(&read_fds);
/* add service and connection fds to read_fds */
for (service = services; service; service = service->next)
{
if (service->fd != -1)
{
/* listen for new connections */
FD_SET(service->fd, &read_fds);
if (service->fd > fd_max)
fd_max = service->fd;
}
if (service->connections)
{
connection_t *c;
for (c = service->connections; c; c = c->next)
{
/* check for activity on the connection */
FD_SET(c->fd, &read_fds);
if (c->fd > fd_max)
fd_max = c->fd;
}
}
}
#ifndef _WIN32
/* add STDIN to read_fds */
FD_SET(fileno(stdin), &read_fds);
#endif
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
if (retval == -1)
{
#ifdef _WIN32
errno = WSAGetLastError();
if (errno == WSAEINTR)
FD_ZERO(&read_fds);
else
{
ERROR("error during select: %s", strerror(errno));
exit(-1);
}
#else
if (errno == EINTR)
{
FD_ZERO(&read_fds);
}
else
{
ERROR("error during select: %s", strerror(errno));
exit(-1);
}
#endif
}
target_call_timer_callbacks();
if (retval == 0)
{
/* do regular tasks after at most 100ms */
tv.tv_sec = 0;
tv.tv_usec = 10000;
FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */
}
for (service = services; service; service = service->next)
{
/* handle new connections on listeners */
if ((service->fd != -1)
&& (FD_ISSET(service->fd, &read_fds)))
{
if (service->max_connections > 0)
{
add_connection(service, command_context);
}
else
{
struct sockaddr_in sin;
unsigned int address_size = sizeof(sin);
int tmp_fd;
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
close_socket(tmp_fd);
INFO("rejected '%s' connection, no more connections allowed", service->name);
}
}
/* handle activity on connections */
if (service->connections)
{
connection_t *c;
for (c = service->connections; c;)
{
if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
{
if (service->input(c) != ERROR_OK)
{
connection_t *next = c->next;
remove_connection(service, c);
INFO("dropped '%s' connection", service->name);
c = next;
continue;
}
}
c = c->next;
}
}
}
#ifndef _WIN32
if (FD_ISSET(fileno(stdin), &read_fds))
{
if (getc(stdin) == 'x')
{
shutdown_openocd = 1;
}
}
#else
MSG msg;
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
shutdown_openocd = 1;
}
#endif
}
return ERROR_OK;
}
#ifdef _WIN32
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
{
shutdown_openocd = 1;
return TRUE;
}
void sig_handler(int sig) {
shutdown_openocd = 1;
}
#endif
int server_init()
{
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
ERROR("Failed to Open Winsock");
exit(-1);
}
SetConsoleCtrlHandler( ControlHandler, TRUE );
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGBREAK, sig_handler);
signal(SIGABRT, sig_handler);
#endif
return ERROR_OK;
}
int server_quit()
{
remove_services();
#ifdef _WIN32
WSACleanup();
SetConsoleCtrlHandler( ControlHandler, FALSE );
#endif
return ERROR_OK;
}
int server_register_commands(command_context_t *context)
{
register_command(context, NULL, "shutdown", handle_shutdown_command,
COMMAND_ANY, "shut the server down");
return ERROR_OK;
}
/* tell the server we want to shut down */
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
shutdown_openocd = 1;
return ERROR_COMMAND_CLOSE_CONNECTION;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,250 +1,250 @@
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* *
* 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. *
***************************************************************************/
#ifndef ARM11_H
#define ARM11_H
#include "target.h"
#include "register.h"
#include "embeddedice.h"
#include "arm_jtag.h"
#define bool int
#define true 1
#define false 0
#define asizeof(x) (sizeof(x) / sizeof((x)[0]))
#define NEW(type, variable, items) \
type * variable = malloc(sizeof(type) * items)
#define ARM11_REGCACHE_MODEREGS 0
#define ARM11_REGCACHE_FREGS 0
#define ARM11_REGCACHE_COUNT (20 + \
23 * ARM11_REGCACHE_MODEREGS + \
9 * ARM11_REGCACHE_FREGS)
typedef struct arm11_register_history_s
{
u32 value;
u8 valid;
}arm11_register_history_t;
typedef struct arm11_common_s
{
target_t * target;
arm_jtag_t jtag_info;
/** \name Processor type detection */
/*@{*/
u32 device_id; /**< IDCODE readout */
u32 didr; /**< DIDR readout (debug capabilities) */
u8 implementor; /**< DIDR Implementor readout */
size_t brp; /**< Number of Breakpoint Register Pairs */
size_t wrp; /**< Number of Watchpoint Register Pairs */
/*@}*/
u32 last_dscr; /**< Last retrieved DSCR value;
* Can be used to detect changes */
u8 trst_active;
u8 halt_requested;
/** \name Shadow registers to save processor state */
/*@{*/
reg_t * reg_list; /**< target register list */
u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */
/*@}*/
arm11_register_history_t
reg_history[ARM11_REGCACHE_COUNT]; /**< register state before last resume */
} arm11_common_t;
/**
* ARM11 DBGTAP instructions
*
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html
*/
enum arm11_instructions
{
ARM11_EXTEST = 0x00,
ARM11_SCAN_N = 0x02,
ARM11_RESTART = 0x04,
ARM11_HALT = 0x08,
ARM11_INTEST = 0x0C,
ARM11_ITRSEL = 0x1D,
ARM11_IDCODE = 0x1E,
ARM11_BYPASS = 0x1F,
};
enum arm11_dscr
{
ARM11_DSCR_CORE_HALTED = 1 << 0,
ARM11_DSCR_CORE_RESTARTED = 1 << 1,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6,
ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7,
ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13,
ARM11_DSCR_MODE_SELECT = 1 << 14,
ARM11_DSCR_WDTR_FULL = 1 << 29,
ARM11_DSCR_RDTR_FULL = 1 << 30,
};
enum arm11_cpsr
{
ARM11_CPSR_T = 1 << 5,
ARM11_CPSR_J = 1 << 24,
};
enum arm11_sc7
{
ARM11_SC7_NULL = 0,
ARM11_SC7_VCR = 7,
ARM11_SC7_PC = 8,
ARM11_SC7_BVR0 = 64,
ARM11_SC7_BCR0 = 80,
ARM11_SC7_WVR0 = 96,
ARM11_SC7_WCR0 = 112,
};
typedef struct arm11_reg_state_s
{
u32 def_index;
target_t * target;
} arm11_reg_state_t;
/* poll current target status */
int arm11_poll(struct target_s *target);
/* architecture specific status reply */
int arm11_arch_state(struct target_s *target);
/* target request support */
int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer);
/* target execution control */
int arm11_halt(struct target_s *target);
int arm11_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
/* target reset control */
int arm11_assert_reset(struct target_s *target);
int arm11_deassert_reset(struct target_s *target);
int arm11_soft_reset_halt(struct target_s *target);
int arm11_prepare_reset_halt(struct target_s *target);
/* target register access for gdb */
int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
/* target memory access
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
* count: number of items of <size>
*/
int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
int arm11_bulk_write_memory(struct target_s *target, u32 address, u32 count, u8 *buffer);
int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
/* target break-/watchpoint control
* rw: 0 = write, 1 = read, 2 = access
*/
int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
/* target algorithm support */
int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info);
int arm11_register_commands(struct command_context_s *cmd_ctx);
int arm11_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
int arm11_quit(void);
/* helpers */
void arm11_build_reg_cache(target_t *target);
/* internals */
void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field);
void arm11_add_IR (arm11_common_t * arm11, u8 instr, enum tap_state state);
void arm11_add_debug_SCAN_N (arm11_common_t * arm11, u8 chain, enum tap_state state);
void arm11_add_debug_INST (arm11_common_t * arm11, u32 inst, u8 * flag, enum tap_state state);
u32 arm11_read_DSCR (arm11_common_t * arm11);
void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr);
enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr);
void arm11_run_instr_data_prepare (arm11_common_t * arm11);
void arm11_run_instr_data_finish (arm11_common_t * arm11);
void arm11_run_instr_no_data (arm11_common_t * arm11, u32 * opcode, size_t count);
void arm11_run_instr_no_data1 (arm11_common_t * arm11, u32 opcode);
void arm11_run_instr_data_to_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_to_core1 (arm11_common_t * arm11, u32 opcode, u32 data);
void arm11_run_instr_data_from_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_from_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 * data);
void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 data);
typedef struct arm11_sc7_action_s
{
bool write;
u8 address;
u32 value;
} arm11_sc7_action_t;
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count);
void arm11_sc7_clear_bw(arm11_common_t * arm11);
#endif /* ARM11_H */
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* *
* 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. *
***************************************************************************/
#ifndef ARM11_H
#define ARM11_H
#include "target.h"
#include "register.h"
#include "embeddedice.h"
#include "arm_jtag.h"
#define bool int
#define true 1
#define false 0
#define asizeof(x) (sizeof(x) / sizeof((x)[0]))
#define NEW(type, variable, items) \
type * variable = malloc(sizeof(type) * items)
#define ARM11_REGCACHE_MODEREGS 0
#define ARM11_REGCACHE_FREGS 0
#define ARM11_REGCACHE_COUNT (20 + \
23 * ARM11_REGCACHE_MODEREGS + \
9 * ARM11_REGCACHE_FREGS)
typedef struct arm11_register_history_s
{
u32 value;
u8 valid;
}arm11_register_history_t;
typedef struct arm11_common_s
{
target_t * target;
arm_jtag_t jtag_info;
/** \name Processor type detection */
/*@{*/
u32 device_id; /**< IDCODE readout */
u32 didr; /**< DIDR readout (debug capabilities) */
u8 implementor; /**< DIDR Implementor readout */
size_t brp; /**< Number of Breakpoint Register Pairs */
size_t wrp; /**< Number of Watchpoint Register Pairs */
/*@}*/
u32 last_dscr; /**< Last retrieved DSCR value;
* Can be used to detect changes */
u8 trst_active;
u8 halt_requested;
/** \name Shadow registers to save processor state */
/*@{*/
reg_t * reg_list; /**< target register list */
u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */
/*@}*/
arm11_register_history_t
reg_history[ARM11_REGCACHE_COUNT]; /**< register state before last resume */
} arm11_common_t;
/**
* ARM11 DBGTAP instructions
*
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html
*/
enum arm11_instructions
{
ARM11_EXTEST = 0x00,
ARM11_SCAN_N = 0x02,
ARM11_RESTART = 0x04,
ARM11_HALT = 0x08,
ARM11_INTEST = 0x0C,
ARM11_ITRSEL = 0x1D,
ARM11_IDCODE = 0x1E,
ARM11_BYPASS = 0x1F,
};
enum arm11_dscr
{
ARM11_DSCR_CORE_HALTED = 1 << 0,
ARM11_DSCR_CORE_RESTARTED = 1 << 1,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6,
ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7,
ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13,
ARM11_DSCR_MODE_SELECT = 1 << 14,
ARM11_DSCR_WDTR_FULL = 1 << 29,
ARM11_DSCR_RDTR_FULL = 1 << 30,
};
enum arm11_cpsr
{
ARM11_CPSR_T = 1 << 5,
ARM11_CPSR_J = 1 << 24,
};
enum arm11_sc7
{
ARM11_SC7_NULL = 0,
ARM11_SC7_VCR = 7,
ARM11_SC7_PC = 8,
ARM11_SC7_BVR0 = 64,
ARM11_SC7_BCR0 = 80,
ARM11_SC7_WVR0 = 96,
ARM11_SC7_WCR0 = 112,
};
typedef struct arm11_reg_state_s
{
u32 def_index;
target_t * target;
} arm11_reg_state_t;
/* poll current target status */
int arm11_poll(struct target_s *target);
/* architecture specific status reply */
int arm11_arch_state(struct target_s *target);
/* target request support */
int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer);
/* target execution control */
int arm11_halt(struct target_s *target);
int arm11_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
/* target reset control */
int arm11_assert_reset(struct target_s *target);
int arm11_deassert_reset(struct target_s *target);
int arm11_soft_reset_halt(struct target_s *target);
int arm11_prepare_reset_halt(struct target_s *target);
/* target register access for gdb */
int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
/* target memory access
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
* count: number of items of <size>
*/
int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
int arm11_bulk_write_memory(struct target_s *target, u32 address, u32 count, u8 *buffer);
int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
/* target break-/watchpoint control
* rw: 0 = write, 1 = read, 2 = access
*/
int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
/* target algorithm support */
int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info);
int arm11_register_commands(struct command_context_s *cmd_ctx);
int arm11_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
int arm11_quit(void);
/* helpers */
void arm11_build_reg_cache(target_t *target);
/* internals */
void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field);
void arm11_add_IR (arm11_common_t * arm11, u8 instr, enum tap_state state);
void arm11_add_debug_SCAN_N (arm11_common_t * arm11, u8 chain, enum tap_state state);
void arm11_add_debug_INST (arm11_common_t * arm11, u32 inst, u8 * flag, enum tap_state state);
u32 arm11_read_DSCR (arm11_common_t * arm11);
void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr);
enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr);
void arm11_run_instr_data_prepare (arm11_common_t * arm11);
void arm11_run_instr_data_finish (arm11_common_t * arm11);
void arm11_run_instr_no_data (arm11_common_t * arm11, u32 * opcode, size_t count);
void arm11_run_instr_no_data1 (arm11_common_t * arm11, u32 opcode);
void arm11_run_instr_data_to_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_to_core1 (arm11_common_t * arm11, u32 opcode, u32 data);
void arm11_run_instr_data_from_core (arm11_common_t * arm11, u32 opcode, u32 * data, size_t count);
void arm11_run_instr_data_from_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 * data);
void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 data);
typedef struct arm11_sc7_action_s
{
bool write;
u8 address;
u32 value;
} arm11_sc7_action_t;
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count);
void arm11_sc7_clear_bw(arm11_common_t * arm11);
#endif /* ARM11_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -676,7 +676,7 @@ int arm7_9_handle_target_request(void *priv)
return ERROR_OK;
}
int arm7_9_poll(target_t *target)
int arm7_9_poll(target_t *target)
{
int retval;
armv4_5_common_t *armv4_5 = target->arch_info;
@ -692,15 +692,15 @@ int arm7_9_poll(target_t *target)
embeddedice_read_reg(dbg_stat);
if ((retval = jtag_execute_queue()) != ERROR_OK)
{
return retval;
return retval;
}
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
{
DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));
if (target->state == TARGET_UNKNOWN)
if (target->state == TARGET_UNKNOWN)
{
WARNING("DBGACK set while target was in unknown state. Reset or initialize target.");
WARNING("DBGACK set while target was in unknown state. Reset or initialize target.");
}
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
{
@ -718,18 +718,18 @@ int arm7_9_poll(target_t *target)
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
}
if (target->state != TARGET_HALTED)
{
WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
if (target->state != TARGET_HALTED)
{
WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
}
}
}
else
{
if (target->state != TARGET_DEBUG_RUNNING)
target->state = TARGET_RUNNING;
}
return ERROR_OK;
return ERROR_OK;
}
int arm7_9_assert_reset(target_t *target)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,364 +1,364 @@
/***************************************************************************
* 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 "arm966e.h"
#include "arm7_9_common.h"
#include "register.h"
#include "target.h"
#include "armv4_5.h"
#include "embeddedice.h"
#include "log.h"
#include "jtag.h"
#include "arm_jtag.h"
#include <stdlib.h>
#include <string.h>
#if 0
#define _DEBUG_INSTRUCTION_EXECUTION_
#endif
/* cli handling */
int arm966e_register_commands(struct command_context_s *cmd_ctx);
/* forward declarations */
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
int arm966e_quit(void);
target_type_t arm966e_target =
{
.name = "arm966e",
.poll = arm7_9_poll,
.arch_state = armv4_5_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,
.assert_reset = arm7_9_assert_reset,
.deassert_reset = arm7_9_deassert_reset,
.soft_reset_halt = arm7_9_soft_reset_halt,
.prepare_reset_halt = arm7_9_prepare_reset_halt,
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
.read_memory = arm7_9_read_memory,
.write_memory = arm7_9_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
.checksum_memory = arm7_9_checksum_memory,
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
.remove_breakpoint = arm7_9_remove_breakpoint,
.add_watchpoint = arm7_9_add_watchpoint,
.remove_watchpoint = arm7_9_remove_watchpoint,
.register_commands = arm966e_register_commands,
.target_command = arm966e_target_command,
.init_target = arm966e_init_target,
.quit = arm966e_quit,
};
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
{
arm9tdmi_init_target(cmd_ctx, target);
return ERROR_OK;
}
int arm966e_quit(void)
{
return ERROR_OK;
}
int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
{
arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
arm9tdmi->arch_info = arm966e;
arm966e->common_magic = ARM966E_COMMON_MAGIC;
/* The ARM966E-S implements the ARMv5TE architecture which
* has the BKPT instruction, so we don't have to use a watchpoint comparator
*/
arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
arm7_9->sw_bkpts_use_wp = 0;
arm7_9->sw_bkpts_enabled = 1;
return ERROR_OK;
}
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
{
int chain_pos;
char *variant = NULL;
arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
if (argc < 4)
{
ERROR("'target arm966e' requires at least one additional argument");
exit(-1);
}
chain_pos = strtoul(args[3], NULL, 0);
if (argc >= 5)
variant = args[4];
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
arm966e_init_arch_info(target, arm966e, chain_pos, variant);
return ERROR_OK;
}
int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9;
arm9tdmi_common_t *arm9tdmi;
arm966e_common_t *arm966e;
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
{
return -1;
}
arm7_9 = armv4_5->arch_info;
if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
{
return -1;
}
arm9tdmi = arm7_9->arch_info;
if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
{
return -1;
}
arm966e = arm9tdmi->arch_info;
if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
{
return -1;
}
*armv4_5_p = armv4_5;
*arm7_9_p = arm7_9;
*arm9tdmi_p = arm9tdmi;
*arm966e_p = arm966e;
return ERROR_OK;
}
int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
scan_field_t fields[3];
u8 reg_addr_buf = reg_addr & 0x3f;
u8 nr_w_buf = 0;
jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32;
fields[0].out_value = NULL;
fields[0].out_mask = NULL;
fields[0].in_value = NULL;
fields[0].in_check_value = NULL;
fields[0].in_check_mask = NULL;
fields[0].in_handler = NULL;
fields[0].in_handler_priv = NULL;
fields[1].device = jtag_info->chain_pos;
fields[1].num_bits = 6;
fields[1].out_value = &reg_addr_buf;
fields[1].out_mask = NULL;
fields[1].in_value = NULL;
fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL;
fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL;
fields[2].device = jtag_info->chain_pos;
fields[2].num_bits = 1;
fields[2].out_value = &nr_w_buf;
fields[2].out_mask = NULL;
fields[2].in_value = NULL;
fields[2].in_check_value = NULL;
fields[2].in_check_mask = NULL;
fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1);
fields[0].in_handler_priv = value;
fields[0].in_handler = arm_jtag_buf_to_u32;
jtag_add_dr_scan(3, fields, -1);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
jtag_execute_queue();
DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
#endif
return ERROR_OK;
}
int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
scan_field_t fields[3];
u8 reg_addr_buf = reg_addr & 0x3f;
u8 nr_w_buf = 1;
u8 value_buf[4];
buf_set_u32(value_buf, 0, 32, value);
jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32;
fields[0].out_value = value_buf;
fields[0].out_mask = NULL;
fields[0].in_value = NULL;
fields[0].in_check_value = NULL;
fields[0].in_check_mask = NULL;
fields[0].in_handler = NULL;
fields[0].in_handler_priv = NULL;
fields[1].device = jtag_info->chain_pos;
fields[1].num_bits = 6;
fields[1].out_value = &reg_addr_buf;
fields[1].out_mask = NULL;
fields[1].in_value = NULL;
fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL;
fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL;
fields[2].device = jtag_info->chain_pos;
fields[2].num_bits = 1;
fields[2].out_value = &nr_w_buf;
fields[2].out_mask = NULL;
fields[2].in_value = NULL;
fields[2].in_check_value = NULL;
fields[2].in_check_mask = NULL;
fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
#endif
return ERROR_OK;
}
int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
int retval;
target_t *target = get_current_target(cmd_ctx);
armv4_5_common_t *armv4_5;
arm7_9_common_t *arm7_9;
arm9tdmi_common_t *arm9tdmi;
arm966e_common_t *arm966e;
arm_jtag_t *jtag_info;
if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
{
command_print(cmd_ctx, "current target isn't an ARM966e target");
return ERROR_OK;
}
jtag_info = &arm7_9->jtag_info;
if (target->state != TARGET_HALTED)
{
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
return ERROR_OK;
}
/* one or more argument, access a single register (write if second argument is given */
if (argc >= 1)
{
int address = strtoul(args[0], NULL, 0);
if (argc == 1)
{
u32 value;
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
{
command_print(cmd_ctx, "couldn't access reg %i", address);
return ERROR_OK;
}
jtag_execute_queue();
command_print(cmd_ctx, "%i: %8.8x", address, value);
}
else if (argc == 2)
{
u32 value = strtoul(args[1], NULL, 0);
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
{
command_print(cmd_ctx, "couldn't access reg %i", address);
return ERROR_OK;
}
command_print(cmd_ctx, "%i: %8.8x", address, value);
}
}
return ERROR_OK;
}
int arm966e_register_commands(struct command_context_s *cmd_ctx)
{
int retval;
command_t *arm966e_cmd;
retval = arm9tdmi_register_commands(cmd_ctx);
arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
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 "arm966e.h"
#include "arm7_9_common.h"
#include "register.h"
#include "target.h"
#include "armv4_5.h"
#include "embeddedice.h"
#include "log.h"
#include "jtag.h"
#include "arm_jtag.h"
#include <stdlib.h>
#include <string.h>
#if 0
#define _DEBUG_INSTRUCTION_EXECUTION_
#endif
/* cli handling */
int arm966e_register_commands(struct command_context_s *cmd_ctx);
/* forward declarations */
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
int arm966e_quit(void);
target_type_t arm966e_target =
{
.name = "arm966e",
.poll = arm7_9_poll,
.arch_state = armv4_5_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,
.assert_reset = arm7_9_assert_reset,
.deassert_reset = arm7_9_deassert_reset,
.soft_reset_halt = arm7_9_soft_reset_halt,
.prepare_reset_halt = arm7_9_prepare_reset_halt,
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
.read_memory = arm7_9_read_memory,
.write_memory = arm7_9_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
.checksum_memory = arm7_9_checksum_memory,
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
.remove_breakpoint = arm7_9_remove_breakpoint,
.add_watchpoint = arm7_9_add_watchpoint,
.remove_watchpoint = arm7_9_remove_watchpoint,
.register_commands = arm966e_register_commands,
.target_command = arm966e_target_command,
.init_target = arm966e_init_target,
.quit = arm966e_quit,
};
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
{
arm9tdmi_init_target(cmd_ctx, target);
return ERROR_OK;
}
int arm966e_quit(void)
{
return ERROR_OK;
}
int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
{
arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
arm9tdmi->arch_info = arm966e;
arm966e->common_magic = ARM966E_COMMON_MAGIC;
/* The ARM966E-S implements the ARMv5TE architecture which
* has the BKPT instruction, so we don't have to use a watchpoint comparator
*/
arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
arm7_9->sw_bkpts_use_wp = 0;
arm7_9->sw_bkpts_enabled = 1;
return ERROR_OK;
}
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
{
int chain_pos;
char *variant = NULL;
arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
if (argc < 4)
{
ERROR("'target arm966e' requires at least one additional argument");
exit(-1);
}
chain_pos = strtoul(args[3], NULL, 0);
if (argc >= 5)
variant = args[4];
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
arm966e_init_arch_info(target, arm966e, chain_pos, variant);
return ERROR_OK;
}
int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9;
arm9tdmi_common_t *arm9tdmi;
arm966e_common_t *arm966e;
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
{
return -1;
}
arm7_9 = armv4_5->arch_info;
if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
{
return -1;
}
arm9tdmi = arm7_9->arch_info;
if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
{
return -1;
}
arm966e = arm9tdmi->arch_info;
if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
{
return -1;
}
*armv4_5_p = armv4_5;
*arm7_9_p = arm7_9;
*arm9tdmi_p = arm9tdmi;
*arm966e_p = arm966e;
return ERROR_OK;
}
int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
scan_field_t fields[3];
u8 reg_addr_buf = reg_addr & 0x3f;
u8 nr_w_buf = 0;
jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32;
fields[0].out_value = NULL;
fields[0].out_mask = NULL;
fields[0].in_value = NULL;
fields[0].in_check_value = NULL;
fields[0].in_check_mask = NULL;
fields[0].in_handler = NULL;
fields[0].in_handler_priv = NULL;
fields[1].device = jtag_info->chain_pos;
fields[1].num_bits = 6;
fields[1].out_value = &reg_addr_buf;
fields[1].out_mask = NULL;
fields[1].in_value = NULL;
fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL;
fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL;
fields[2].device = jtag_info->chain_pos;
fields[2].num_bits = 1;
fields[2].out_value = &nr_w_buf;
fields[2].out_mask = NULL;
fields[2].in_value = NULL;
fields[2].in_check_value = NULL;
fields[2].in_check_mask = NULL;
fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1);
fields[0].in_handler_priv = value;
fields[0].in_handler = arm_jtag_buf_to_u32;
jtag_add_dr_scan(3, fields, -1);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
jtag_execute_queue();
DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
#endif
return ERROR_OK;
}
int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
scan_field_t fields[3];
u8 reg_addr_buf = reg_addr & 0x3f;
u8 nr_w_buf = 1;
u8 value_buf[4];
buf_set_u32(value_buf, 0, 32, value);
jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32;
fields[0].out_value = value_buf;
fields[0].out_mask = NULL;
fields[0].in_value = NULL;
fields[0].in_check_value = NULL;
fields[0].in_check_mask = NULL;
fields[0].in_handler = NULL;
fields[0].in_handler_priv = NULL;
fields[1].device = jtag_info->chain_pos;
fields[1].num_bits = 6;
fields[1].out_value = &reg_addr_buf;
fields[1].out_mask = NULL;
fields[1].in_value = NULL;
fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL;
fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL;
fields[2].device = jtag_info->chain_pos;
fields[2].num_bits = 1;
fields[2].out_value = &nr_w_buf;
fields[2].out_mask = NULL;
fields[2].in_value = NULL;
fields[2].in_check_value = NULL;
fields[2].in_check_mask = NULL;
fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
#endif
return ERROR_OK;
}
int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
int retval;
target_t *target = get_current_target(cmd_ctx);
armv4_5_common_t *armv4_5;
arm7_9_common_t *arm7_9;
arm9tdmi_common_t *arm9tdmi;
arm966e_common_t *arm966e;
arm_jtag_t *jtag_info;
if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
{
command_print(cmd_ctx, "current target isn't an ARM966e target");
return ERROR_OK;
}
jtag_info = &arm7_9->jtag_info;
if (target->state != TARGET_HALTED)
{
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
return ERROR_OK;
}
/* one or more argument, access a single register (write if second argument is given */
if (argc >= 1)
{
int address = strtoul(args[0], NULL, 0);
if (argc == 1)
{
u32 value;
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
{
command_print(cmd_ctx, "couldn't access reg %i", address);
return ERROR_OK;
}
jtag_execute_queue();
command_print(cmd_ctx, "%i: %8.8x", address, value);
}
else if (argc == 2)
{
u32 value = strtoul(args[1], NULL, 0);
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
{
command_print(cmd_ctx, "couldn't access reg %i", address);
return ERROR_OK;
}
command_print(cmd_ctx, "%i: %8.8x", address, value);
}
}
return ERROR_OK;
}
int arm966e_register_commands(struct command_context_s *cmd_ctx)
{
int retval;
command_t *arm966e_cmd;
retval = arm9tdmi_register_commands(cmd_ctx);
arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
return ERROR_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,207 +1,207 @@
/***************************************************************************
* 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 "arm_jtag.h"
#include "binarybuffer.h"
#include "log.h"
#include "jtag.h"
#include <stdlib.h>
#if 0
#define _ARM_JTAG_SCAN_N_CHECK_
#endif
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, in_handler_t handler)
{
jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
{
scan_field_t field;
field.device = jtag_info->chain_pos;
field.num_bits = device->ir_length;
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
field.out_mask = NULL;
field.in_value = NULL;
field.in_check_value = NULL;
field.in_check_mask = NULL;
field.in_handler = handler;
field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, -1);
free(field.out_value);
}
return ERROR_OK;
}
int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
{
if(jtag_info->cur_scan_chain != new_scan_chain)
{
#ifdef _ARM_JTAG_SCAN_N_CHECK_
u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);
#endif
scan_field_t field;
field.device = jtag_info->chain_pos;
field.num_bits = jtag_info->scann_size;
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
field.out_mask = NULL;
field.in_value = NULL;
#ifdef _ARM_JTAG_SCAN_N_CHECK_
jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);
#else
field.in_handler = NULL;
field.in_handler_priv = NULL;
#endif
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
jtag_add_dr_scan(1, &field, -1);
jtag_info->cur_scan_chain = new_scan_chain;
free(field.out_value);
}
return ERROR_OK;
}
int arm_jtag_reset_callback(enum jtag_event event, void *priv)
{
arm_jtag_t *jtag_info = priv;
if (event == JTAG_TRST_ASSERTED)
{
jtag_info->cur_scan_chain = 0;
}
return ERROR_OK;
}
int arm_jtag_setup_connection(arm_jtag_t *jtag_info)
{
jtag_info->scann_instr = 0x2;
jtag_info->cur_scan_chain = 0;
jtag_info->intest_instr = 0xc;
jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);
return ERROR_OK;
}
/* read JTAG buffer into host-endian u32, flipping bit-order */
int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u32 *dest = priv;
*dest = flip_u32(le_to_h_u32(in_buf), 32);
return ERROR_OK;
}
/* read JTAG buffer into little-endian u32, flipping bit-order */
int arm_jtag_buf_to_le32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
return ERROR_OK;
}
/* read JTAG buffer into little-endian u16, flipping bit-order */
int arm_jtag_buf_to_le16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into big-endian u32, flipping bit-order */
int arm_jtag_buf_to_be32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
return ERROR_OK;
}
/* read JTAG buffer into big-endian u16, flipping bit-order */
int arm_jtag_buf_to_be16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into u8, flipping bit-order */
int arm_jtag_buf_to_8_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u8 *dest = priv;
*dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;
return ERROR_OK;
}
/* not-flipping variants */
/* read JTAG buffer into host-endian u32 */
int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u32 *dest = priv;
*dest = le_to_h_u32(in_buf);
return ERROR_OK;
}
/* read JTAG buffer into little-endian u32 */
int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));
return ERROR_OK;
}
/* read JTAG buffer into little-endian u16 */
int arm_jtag_buf_to_le16(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_le(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into big-endian u32 */
int arm_jtag_buf_to_be32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_be(((u8*)priv), le_to_h_u32(in_buf));
return ERROR_OK;
}
/* read JTAG buffer into big-endian u16 */
int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into u8 */
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u8 *dest = priv;
*dest = le_to_h_u32(in_buf) & 0xff;
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 "arm_jtag.h"
#include "binarybuffer.h"
#include "log.h"
#include "jtag.h"
#include <stdlib.h>
#if 0
#define _ARM_JTAG_SCAN_N_CHECK_
#endif
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, in_handler_t handler)
{
jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
{
scan_field_t field;
field.device = jtag_info->chain_pos;
field.num_bits = device->ir_length;
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
field.out_mask = NULL;
field.in_value = NULL;
field.in_check_value = NULL;
field.in_check_mask = NULL;
field.in_handler = handler;
field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, -1);
free(field.out_value);
}
return ERROR_OK;
}
int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
{
if(jtag_info->cur_scan_chain != new_scan_chain)
{
#ifdef _ARM_JTAG_SCAN_N_CHECK_
u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);
#endif
scan_field_t field;
field.device = jtag_info->chain_pos;
field.num_bits = jtag_info->scann_size;
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
field.out_mask = NULL;
field.in_value = NULL;
#ifdef _ARM_JTAG_SCAN_N_CHECK_
jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);
#else
field.in_handler = NULL;
field.in_handler_priv = NULL;
#endif
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
jtag_add_dr_scan(1, &field, -1);
jtag_info->cur_scan_chain = new_scan_chain;
free(field.out_value);
}
return ERROR_OK;
}
int arm_jtag_reset_callback(enum jtag_event event, void *priv)
{
arm_jtag_t *jtag_info = priv;
if (event == JTAG_TRST_ASSERTED)
{
jtag_info->cur_scan_chain = 0;
}
return ERROR_OK;
}
int arm_jtag_setup_connection(arm_jtag_t *jtag_info)
{
jtag_info->scann_instr = 0x2;
jtag_info->cur_scan_chain = 0;
jtag_info->intest_instr = 0xc;
jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);
return ERROR_OK;
}
/* read JTAG buffer into host-endian u32, flipping bit-order */
int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u32 *dest = priv;
*dest = flip_u32(le_to_h_u32(in_buf), 32);
return ERROR_OK;
}
/* read JTAG buffer into little-endian u32, flipping bit-order */
int arm_jtag_buf_to_le32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
return ERROR_OK;
}
/* read JTAG buffer into little-endian u16, flipping bit-order */
int arm_jtag_buf_to_le16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into big-endian u32, flipping bit-order */
int arm_jtag_buf_to_be32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
return ERROR_OK;
}
/* read JTAG buffer into big-endian u16, flipping bit-order */
int arm_jtag_buf_to_be16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into u8, flipping bit-order */
int arm_jtag_buf_to_8_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u8 *dest = priv;
*dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;
return ERROR_OK;
}
/* not-flipping variants */
/* read JTAG buffer into host-endian u32 */
int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u32 *dest = priv;
*dest = le_to_h_u32(in_buf);
return ERROR_OK;
}
/* read JTAG buffer into little-endian u32 */
int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));
return ERROR_OK;
}
/* read JTAG buffer into little-endian u16 */
int arm_jtag_buf_to_le16(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_le(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into big-endian u32 */
int arm_jtag_buf_to_be32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u32_to_be(((u8*)priv), le_to_h_u32(in_buf));
return ERROR_OK;
}
/* read JTAG buffer into big-endian u16 */
int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)
{
h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
return ERROR_OK;
}
/* read JTAG buffer into u8 */
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
{
u8 *dest = priv;
*dest = le_to_h_u32(in_buf) & 0xff;
return ERROR_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2007 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. *
***************************************************************************/
#ifndef ETB_H
#define ETB_H
#include "command.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
#include "etb.h"
#include "etm.h"
/* ETB registers */
enum
{
ETB_ID = 0x00,
ETB_RAM_DEPTH = 0x01,
ETB_RAM_WIDTH = 0x02,
ETB_STATUS = 0x03,
ETB_RAM_DATA = 0x04,
ETB_RAM_READ_POINTER = 0x05,
ETB_RAM_WRITE_POINTER = 0x06,
ETB_TRIGGER_COUNTER = 0x07,
ETB_CTRL = 0x08,
};
typedef struct etb_s
{
etm_context_t *etm_ctx;
int chain_pos;
int cur_scan_chain;
reg_cache_t *reg_cache;
/* ETB parameters */
int ram_depth;
int ram_width;
} etb_t;
typedef struct etb_reg_s
{
int addr;
etb_t *etb;
} etb_reg_t;
extern etm_capture_driver_t etb_capture_driver;
extern reg_cache_t* etb_build_reg_cache(etb_t *etb);
extern int etb_read_reg(reg_t *reg);
extern int etb_write_reg(reg_t *reg, u32 value);
extern int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
extern int etb_store_reg(reg_t *reg);
extern int etb_set_reg(reg_t *reg, u32 value);
extern int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
extern int etb_register_commands(struct command_context_s *cmd_ctx);
#endif /* ETB_H */
/***************************************************************************
* Copyright (C) 2007 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. *
***************************************************************************/
#ifndef ETB_H
#define ETB_H
#include "command.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
#include "etb.h"
#include "etm.h"
/* ETB registers */
enum
{
ETB_ID = 0x00,
ETB_RAM_DEPTH = 0x01,
ETB_RAM_WIDTH = 0x02,
ETB_STATUS = 0x03,
ETB_RAM_DATA = 0x04,
ETB_RAM_READ_POINTER = 0x05,
ETB_RAM_WRITE_POINTER = 0x06,
ETB_TRIGGER_COUNTER = 0x07,
ETB_CTRL = 0x08,
};
typedef struct etb_s
{
etm_context_t *etm_ctx;
int chain_pos;
int cur_scan_chain;
reg_cache_t *reg_cache;
/* ETB parameters */
int ram_depth;
int ram_width;
} etb_t;
typedef struct etb_reg_s
{
int addr;
etb_t *etb;
} etb_reg_t;
extern etm_capture_driver_t etb_capture_driver;
extern reg_cache_t* etb_build_reg_cache(etb_t *etb);
extern int etb_read_reg(reg_t *reg);
extern int etb_write_reg(reg_t *reg, u32 value);
extern int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
extern int etb_store_reg(reg_t *reg);
extern int etb_set_reg(reg_t *reg, u32 value);
extern int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
extern int etb_register_commands(struct command_context_s *cmd_ctx);
#endif /* ETB_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,214 +1,214 @@
/***************************************************************************
* Copyright (C) 2005, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007 by Vincent Palatin *
* vincent.palatin_openocd@m4x.org *
* *
* 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. *
***************************************************************************/
#ifndef ETM_H
#define ETM_H
#include "image.h"
#include "trace.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
#include "armv4_5.h"
/* ETM registers (V1.3 protocol) */
enum
{
ETM_CTRL = 0x00,
ETM_CONFIG = 0x01,
ETM_TRIG_EVENT = 0x02,
ETM_MMD_CTRL = 0x03,
ETM_STATUS = 0x04,
ETM_SYS_CONFIG = 0x05,
ETM_TRACE_RESOURCE_CTRL = 0x06,
ETM_TRACE_EN_CTRL2 = 0x07,
ETM_TRACE_EN_EVENT = 0x08,
ETM_TRACE_EN_CTRL1 = 0x09,
ETM_FIFOFULL_REGION = 0x0a,
ETM_FIFOFULL_LEVEL = 0x0b,
ETM_VIEWDATA_EVENT = 0x0c,
ETM_VIEWDATA_CTRL1 = 0x0d,
ETM_VIEWDATA_CTRL2 = 0x0e,
ETM_VIEWDATA_CTRL3 = 0x0f,
ETM_ADDR_COMPARATOR_VALUE = 0x10,
ETM_ADDR_ACCESS_TYPE = 0x20,
ETM_DATA_COMPARATOR_VALUE = 0x30,
ETM_DATA_COMPARATOR_MASK = 0x40,
ETM_COUNTER_INITAL_VALUE = 0x50,
ETM_COUNTER_ENABLE = 0x54,
ETM_COUNTER_RELOAD_VALUE = 0x58,
ETM_COUNTER_VALUE = 0x5c,
ETM_SEQUENCER_CTRL = 0x60,
ETM_SEQUENCER_STATE = 0x67,
ETM_EXTERNAL_OUTPUT = 0x68,
ETM_CONTEXTID_COMPARATOR_VALUE = 0x6c,
ETM_CONTEXTID_COMPARATOR_MASK = 0x6f,
};
typedef struct etm_reg_s
{
int addr;
arm_jtag_t *jtag_info;
} etm_reg_t;
typedef enum
{
/* Port width */
ETM_PORT_4BIT = 0x00,
ETM_PORT_8BIT = 0x10,
ETM_PORT_16BIT = 0x20,
ETM_PORT_WIDTH_MASK = 0x70,
/* Port modes */
ETM_PORT_NORMAL = 0x00000,
ETM_PORT_MUXED = 0x10000,
ETM_PORT_DEMUXED = 0x20000,
ETM_PORT_MODE_MASK = 0x30000,
/* Clocking modes */
ETM_PORT_FULL_CLOCK = 0x0000,
ETM_PORT_HALF_CLOCK = 0x1000,
ETM_PORT_CLOCK_MASK = 0x1000,
} etm_portmode_t;
typedef enum
{
/* Data trace */
ETMV1_TRACE_NONE = 0x00,
ETMV1_TRACE_DATA = 0x01,
ETMV1_TRACE_ADDR = 0x02,
ETMV1_TRACE_MASK = 0x03,
/* ContextID */
ETMV1_CONTEXTID_NONE = 0x00,
ETMV1_CONTEXTID_8 = 0x10,
ETMV1_CONTEXTID_16 = 0x20,
ETMV1_CONTEXTID_32 = 0x30,
ETMV1_CONTEXTID_MASK = 0x30,
/* Misc */
ETMV1_CYCLE_ACCURATE = 0x100,
ETMV1_BRANCH_OUTPUT = 0x200
} etmv1_tracemode_t;
/* forward-declare ETM context */
struct etm_context_s;
typedef struct etm_capture_driver_s
{
char *name;
int (*register_commands)(struct command_context_s *cmd_ctx);
int (*init)(struct etm_context_s *etm_ctx);
trace_status_t (*status)(struct etm_context_s *etm_ctx);
int (*read_trace)(struct etm_context_s *etm_ctx);
int (*start_capture)(struct etm_context_s *etm_ctx);
int (*stop_capture)(struct etm_context_s *etm_ctx);
} etm_capture_driver_t;
enum
{
ETMV1_TRACESYNC_CYCLE = 0x1,
ETMV1_TRIGGER_CYCLE = 0x2,
};
typedef struct etmv1_trace_data_s
{
u8 pipestat; /* bits 0-2 pipeline status */
u16 packet; /* packet data (4, 8 or 16 bit) */
int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */
} etmv1_trace_data_t;
/* describe a trace context
* if support for ETMv2 or ETMv3 is to be implemented,
* this will have to be split into version independent elements
* and a version specific part
*/
typedef struct etm_context_s
{
target_t *target; /* target this ETM is connected to */
reg_cache_t *reg_cache; /* ETM register cache */
etm_capture_driver_t *capture_driver; /* driver used to access ETM data */
void *capture_driver_priv; /* capture driver private data */
u32 trigger_percent; /* percent of trace buffer to be filled after the trigger */
trace_status_t capture_status; /* current state of capture run */
etmv1_trace_data_t *trace_data; /* trace data */
u32 trace_depth; /* number of trace cycles to be analyzed, 0 if no trace data available */
etm_portmode_t portmode; /* normal, multiplexed or demultiplexed */
etmv1_tracemode_t tracemode; /* type of information the trace contains (data, addres, contextID, ...) */
armv4_5_state_t core_state; /* current core state (ARM, Thumb, Jazelle) */
image_t *image; /* source for target opcodes */
u32 pipe_index; /* current trace cycle */
u32 data_index; /* cycle holding next data packet */
int data_half; /* port half on a 16 bit port */
u32 current_pc; /* current program counter */
u32 pc_ok; /* full PC has been acquired */
u32 last_branch; /* last branch address output */
u32 last_branch_reason; /* branch reason code for the last branch encountered */
u32 last_ptr; /* address of the last data access */
u32 ptr_ok; /* whether last_ptr is valid */
u32 context_id; /* context ID of the code being traced */
u32 last_instruction; /* index of last instruction executed (to calculate cycle timings) */
} etm_context_t;
/* PIPESTAT values */
typedef enum
{
STAT_IE = 0x0,
STAT_ID = 0x1,
STAT_IN = 0x2,
STAT_WT = 0x3,
STAT_BE = 0x4,
STAT_BD = 0x5,
STAT_TR = 0x6,
STAT_TD = 0x7
} etmv1_pipestat_t;
/* branch reason values */
typedef enum
{
BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */
BR_ENABLE = 0x1, /* Trace has been enabled */
BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */
BR_NODEBUG = 0x3, /* ARM has exited for debug state */
BR_PERIOD = 0x4, /* Peridioc synchronization point (ETM>=v1.2)*/
BR_RSVD5 = 0x5, /* reserved */
BR_RSVD6 = 0x6, /* reserved */
BR_RSVD7 = 0x7, /* reserved */
} etmv1_branch_reason_t;
extern char *etmv1v1_branch_reason_strings[];
extern reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_context_t *etm_ctx);
extern int etm_read_reg(reg_t *reg);
extern int etm_write_reg(reg_t *reg, u32 value);
extern int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
extern int etm_store_reg(reg_t *reg);
extern int etm_set_reg(reg_t *reg, u32 value);
extern int etm_set_reg_w_exec(reg_t *reg, u8 *buf);
int etm_register_commands(struct command_context_s *cmd_ctx);
int etm_register_user_commands(struct command_context_s *cmd_ctx);
extern etm_context_t* etm_create_context(etm_portmode_t portmode, char *capture_driver_name);
#define ERROR_ETM_INVALID_DRIVER (-1300)
#define ERROR_ETM_PORTMODE_NOT_SUPPORTED (-1301)
#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302)
#define ERROR_ETM_ANALYSIS_FAILED (-1303)
#endif /* ETM_H */
/***************************************************************************
* Copyright (C) 2005, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007 by Vincent Palatin *
* vincent.palatin_openocd@m4x.org *
* *
* 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. *
***************************************************************************/
#ifndef ETM_H
#define ETM_H
#include "image.h"
#include "trace.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
#include "armv4_5.h"
/* ETM registers (V1.3 protocol) */
enum
{
ETM_CTRL = 0x00,
ETM_CONFIG = 0x01,
ETM_TRIG_EVENT = 0x02,
ETM_MMD_CTRL = 0x03,
ETM_STATUS = 0x04,
ETM_SYS_CONFIG = 0x05,
ETM_TRACE_RESOURCE_CTRL = 0x06,
ETM_TRACE_EN_CTRL2 = 0x07,
ETM_TRACE_EN_EVENT = 0x08,
ETM_TRACE_EN_CTRL1 = 0x09,
ETM_FIFOFULL_REGION = 0x0a,
ETM_FIFOFULL_LEVEL = 0x0b,
ETM_VIEWDATA_EVENT = 0x0c,
ETM_VIEWDATA_CTRL1 = 0x0d,
ETM_VIEWDATA_CTRL2 = 0x0e,
ETM_VIEWDATA_CTRL3 = 0x0f,
ETM_ADDR_COMPARATOR_VALUE = 0x10,
ETM_ADDR_ACCESS_TYPE = 0x20,
ETM_DATA_COMPARATOR_VALUE = 0x30,
ETM_DATA_COMPARATOR_MASK = 0x40,
ETM_COUNTER_INITAL_VALUE = 0x50,
ETM_COUNTER_ENABLE = 0x54,
ETM_COUNTER_RELOAD_VALUE = 0x58,
ETM_COUNTER_VALUE = 0x5c,
ETM_SEQUENCER_CTRL = 0x60,
ETM_SEQUENCER_STATE = 0x67,
ETM_EXTERNAL_OUTPUT = 0x68,
ETM_CONTEXTID_COMPARATOR_VALUE = 0x6c,
ETM_CONTEXTID_COMPARATOR_MASK = 0x6f,
};
typedef struct etm_reg_s
{
int addr;
arm_jtag_t *jtag_info;
} etm_reg_t;
typedef enum
{
/* Port width */
ETM_PORT_4BIT = 0x00,
ETM_PORT_8BIT = 0x10,
ETM_PORT_16BIT = 0x20,
ETM_PORT_WIDTH_MASK = 0x70,
/* Port modes */
ETM_PORT_NORMAL = 0x00000,
ETM_PORT_MUXED = 0x10000,
ETM_PORT_DEMUXED = 0x20000,
ETM_PORT_MODE_MASK = 0x30000,
/* Clocking modes */
ETM_PORT_FULL_CLOCK = 0x0000,
ETM_PORT_HALF_CLOCK = 0x1000,
ETM_PORT_CLOCK_MASK = 0x1000,
} etm_portmode_t;
typedef enum
{
/* Data trace */
ETMV1_TRACE_NONE = 0x00,
ETMV1_TRACE_DATA = 0x01,
ETMV1_TRACE_ADDR = 0x02,
ETMV1_TRACE_MASK = 0x03,
/* ContextID */
ETMV1_CONTEXTID_NONE = 0x00,
ETMV1_CONTEXTID_8 = 0x10,
ETMV1_CONTEXTID_16 = 0x20,
ETMV1_CONTEXTID_32 = 0x30,
ETMV1_CONTEXTID_MASK = 0x30,
/* Misc */
ETMV1_CYCLE_ACCURATE = 0x100,
ETMV1_BRANCH_OUTPUT = 0x200
} etmv1_tracemode_t;
/* forward-declare ETM context */
struct etm_context_s;
typedef struct etm_capture_driver_s
{
char *name;
int (*register_commands)(struct command_context_s *cmd_ctx);
int (*init)(struct etm_context_s *etm_ctx);
trace_status_t (*status)(struct etm_context_s *etm_ctx);
int (*read_trace)(struct etm_context_s *etm_ctx);
int (*start_capture)(struct etm_context_s *etm_ctx);
int (*stop_capture)(struct etm_context_s *etm_ctx);
} etm_capture_driver_t;
enum
{
ETMV1_TRACESYNC_CYCLE = 0x1,
ETMV1_TRIGGER_CYCLE = 0x2,
};
typedef struct etmv1_trace_data_s
{
u8 pipestat; /* bits 0-2 pipeline status */
u16 packet; /* packet data (4, 8 or 16 bit) */
int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */
} etmv1_trace_data_t;
/* describe a trace context
* if support for ETMv2 or ETMv3 is to be implemented,
* this will have to be split into version independent elements
* and a version specific part
*/
typedef struct etm_context_s
{
target_t *target; /* target this ETM is connected to */
reg_cache_t *reg_cache; /* ETM register cache */
etm_capture_driver_t *capture_driver; /* driver used to access ETM data */
void *capture_driver_priv; /* capture driver private data */
u32 trigger_percent; /* percent of trace buffer to be filled after the trigger */
trace_status_t capture_status; /* current state of capture run */
etmv1_trace_data_t *trace_data; /* trace data */
u32 trace_depth; /* number of trace cycles to be analyzed, 0 if no trace data available */
etm_portmode_t portmode; /* normal, multiplexed or demultiplexed */
etmv1_tracemode_t tracemode; /* type of information the trace contains (data, addres, contextID, ...) */
armv4_5_state_t core_state; /* current core state (ARM, Thumb, Jazelle) */
image_t *image; /* source for target opcodes */
u32 pipe_index; /* current trace cycle */
u32 data_index; /* cycle holding next data packet */
int data_half; /* port half on a 16 bit port */
u32 current_pc; /* current program counter */
u32 pc_ok; /* full PC has been acquired */
u32 last_branch; /* last branch address output */
u32 last_branch_reason; /* branch reason code for the last branch encountered */
u32 last_ptr; /* address of the last data access */
u32 ptr_ok; /* whether last_ptr is valid */
u32 context_id; /* context ID of the code being traced */
u32 last_instruction; /* index of last instruction executed (to calculate cycle timings) */
} etm_context_t;
/* PIPESTAT values */
typedef enum
{
STAT_IE = 0x0,
STAT_ID = 0x1,
STAT_IN = 0x2,
STAT_WT = 0x3,
STAT_BE = 0x4,
STAT_BD = 0x5,
STAT_TR = 0x6,
STAT_TD = 0x7
} etmv1_pipestat_t;
/* branch reason values */
typedef enum
{
BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */
BR_ENABLE = 0x1, /* Trace has been enabled */
BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */
BR_NODEBUG = 0x3, /* ARM has exited for debug state */
BR_PERIOD = 0x4, /* Peridioc synchronization point (ETM>=v1.2)*/
BR_RSVD5 = 0x5, /* reserved */
BR_RSVD6 = 0x6, /* reserved */
BR_RSVD7 = 0x7, /* reserved */
} etmv1_branch_reason_t;
extern char *etmv1v1_branch_reason_strings[];
extern reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_context_t *etm_ctx);
extern int etm_read_reg(reg_t *reg);
extern int etm_write_reg(reg_t *reg, u32 value);
extern int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
extern int etm_store_reg(reg_t *reg);
extern int etm_set_reg(reg_t *reg, u32 value);
extern int etm_set_reg_w_exec(reg_t *reg, u8 *buf);
int etm_register_commands(struct command_context_s *cmd_ctx);
int etm_register_user_commands(struct command_context_s *cmd_ctx);
extern etm_context_t* etm_create_context(etm_portmode_t portmode, char *capture_driver_name);
#define ERROR_ETM_INVALID_DRIVER (-1300)
#define ERROR_ETM_PORTMODE_NOT_SUPPORTED (-1301)
#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302)
#define ERROR_ETM_ANALYSIS_FAILED (-1303)
#endif /* ETM_H */

View File

@ -1,33 +1,33 @@
/***************************************************************************
* Copyright (C) 2007 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. *
***************************************************************************/
#ifndef ETM_DUMMY_H
#define ETM_DUMMY_H
#include "command.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
#include "etm.h"
extern etm_capture_driver_t etm_dummy_capture_driver;
extern int etm_dummy_register_commands(struct command_context_s *cmd_ctx);
#endif /* ETB_H */
/***************************************************************************
* Copyright (C) 2007 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. *
***************************************************************************/
#ifndef ETM_DUMMY_H
#define ETM_DUMMY_H
#include "command.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
#include "etm.h"
extern etm_capture_driver_t etm_dummy_capture_driver;
extern int etm_dummy_register_commands(struct command_context_s *cmd_ctx);
#endif /* ETB_H */

View File

@ -1,64 +1,64 @@
/***************************************************************************
* Copyright (C) 2007 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. *
***************************************************************************/
#ifndef OOCD_TRACE_H
#define OOCD_TRACE_H
#include "command.h"
#include "etm.h"
#include <termios.h>
#include <unistd.h>
/* registers */
enum
{
OOCD_TRACE_ID = 0x7,
OOCD_TRACE_ADDRESS = 0x0,
OOCD_TRACE_TRIGGER_COUNTER = 0x01,
OOCD_TRACE_CONTROL = 0x2,
OOCD_TRACE_STATUS = 0x3,
OOCD_TRACE_SDRAM_COUNTER = 0x4,
};
/* commands */
enum
{
OOCD_TRACE_NOP = 0x0,
OOCD_TRACE_READ_REG = 0x10,
OOCD_TRACE_WRITE_REG = 0x18,
OOCD_TRACE_READ_RAM = 0x20,
/* OOCD_TRACE_WRITE_RAM = 0x28, */
OOCD_TRACE_RESYNC = 0xf0,
};
typedef struct oocd_trace_s
{
etm_context_t *etm_ctx;
char *tty;
int tty_fd;
struct termios oldtio, newtio;
} oocd_trace_t;
extern etm_capture_driver_t oocd_trace_capture_driver;
extern int oocd_trace_register_commands(struct command_context_s *cmd_ctx);
#endif /* OOCD_TRACE_TRACE_H */
/***************************************************************************
* Copyright (C) 2007 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. *
***************************************************************************/
#ifndef OOCD_TRACE_H
#define OOCD_TRACE_H
#include "command.h"
#include "etm.h"
#include <termios.h>
#include <unistd.h>
/* registers */
enum
{
OOCD_TRACE_ID = 0x7,
OOCD_TRACE_ADDRESS = 0x0,
OOCD_TRACE_TRIGGER_COUNTER = 0x01,
OOCD_TRACE_CONTROL = 0x2,
OOCD_TRACE_STATUS = 0x3,
OOCD_TRACE_SDRAM_COUNTER = 0x4,
};
/* commands */
enum
{
OOCD_TRACE_NOP = 0x0,
OOCD_TRACE_READ_REG = 0x10,
OOCD_TRACE_WRITE_REG = 0x18,
OOCD_TRACE_READ_RAM = 0x20,
/* OOCD_TRACE_WRITE_RAM = 0x28, */
OOCD_TRACE_RESYNC = 0xf0,
};
typedef struct oocd_trace_s
{
etm_context_t *etm_ctx;
char *tty;
int tty_fd;
struct termios oldtio, newtio;
} oocd_trace_t;
extern etm_capture_driver_t oocd_trace_capture_driver;
extern int oocd_trace_register_commands(struct command_context_s *cmd_ctx);
#endif /* OOCD_TRACE_TRACE_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff