- 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:
parent
7f1944a478
commit
3d6bcf0792
|
@ -1,100 +1,100 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2006 by Magnus Lundin *
|
* Copyright (C) 2006 by Magnus Lundin *
|
||||||
* lundin@mlu.mine.nu *
|
* lundin@mlu.mine.nu *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef AT91SAM7_H
|
#ifndef AT91SAM7_H
|
||||||
#define AT91SAM7_H
|
#define AT91SAM7_H
|
||||||
|
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
typedef struct at91sam7_flash_bank_s
|
typedef struct at91sam7_flash_bank_s
|
||||||
{
|
{
|
||||||
u32 working_area;
|
u32 working_area;
|
||||||
u32 working_area_size;
|
u32 working_area_size;
|
||||||
|
|
||||||
/* chip id register */
|
/* chip id register */
|
||||||
u32 cidr;
|
u32 cidr;
|
||||||
u16 cidr_ext;
|
u16 cidr_ext;
|
||||||
u16 cidr_nvptyp;
|
u16 cidr_nvptyp;
|
||||||
u16 cidr_arch;
|
u16 cidr_arch;
|
||||||
u16 cidr_sramsiz;
|
u16 cidr_sramsiz;
|
||||||
u16 cidr_nvpsiz;
|
u16 cidr_nvpsiz;
|
||||||
u16 cidr_nvpsiz2;
|
u16 cidr_nvpsiz2;
|
||||||
u16 cidr_eproc;
|
u16 cidr_eproc;
|
||||||
u16 cidr_version;
|
u16 cidr_version;
|
||||||
char * target_name;
|
char * target_name;
|
||||||
|
|
||||||
/* flash geometry */
|
/* flash geometry */
|
||||||
u16 num_pages;
|
u16 num_pages;
|
||||||
u16 pagesize;
|
u16 pagesize;
|
||||||
u16 pages_in_lockregion;
|
u16 pages_in_lockregion;
|
||||||
u8 num_erase_regions;
|
u8 num_erase_regions;
|
||||||
u8 num_planes;
|
u8 num_planes;
|
||||||
u32 *erase_region_info;
|
u32 *erase_region_info;
|
||||||
|
|
||||||
/* nv memory bits */
|
/* nv memory bits */
|
||||||
u16 num_lockbits;
|
u16 num_lockbits;
|
||||||
u16 lockbits[4];
|
u16 lockbits[4];
|
||||||
u16 num_nvmbits;
|
u16 num_nvmbits;
|
||||||
u16 nvmbits;
|
u16 nvmbits;
|
||||||
u8 securitybit;
|
u8 securitybit;
|
||||||
u8 flashmode[4]; /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */
|
u8 flashmode[4]; /* 0: not init, 1: fmcn for nvbits (1uS), 2: fmcn for flash (1.5uS) */
|
||||||
|
|
||||||
/* main clock status */
|
/* main clock status */
|
||||||
u8 mck_valid;
|
u8 mck_valid;
|
||||||
u32 mck_freq;
|
u32 mck_freq;
|
||||||
|
|
||||||
int probed;
|
int probed;
|
||||||
|
|
||||||
} at91sam7_flash_bank_t;
|
} at91sam7_flash_bank_t;
|
||||||
|
|
||||||
/* AT91SAM7 control registers */
|
/* AT91SAM7 control registers */
|
||||||
#define DBGU_CIDR 0xFFFFF240
|
#define DBGU_CIDR 0xFFFFF240
|
||||||
#define CKGR_MCFR 0xFFFFFC24
|
#define CKGR_MCFR 0xFFFFFC24
|
||||||
#define CKGR_MCFR_MAINRDY 0x10000
|
#define CKGR_MCFR_MAINRDY 0x10000
|
||||||
#define CKGR_PLLR 0xFFFFFC2c
|
#define CKGR_PLLR 0xFFFFFC2c
|
||||||
#define CKGR_PLLR_DIV 0xff
|
#define CKGR_PLLR_DIV 0xff
|
||||||
#define CKGR_PLLR_MUL 0x07ff0000
|
#define CKGR_PLLR_MUL 0x07ff0000
|
||||||
#define PMC_MCKR 0xFFFFFC30
|
#define PMC_MCKR 0xFFFFFC30
|
||||||
#define PMC_MCKR_CSS 0x03
|
#define PMC_MCKR_CSS 0x03
|
||||||
#define PMC_MCKR_PRES 0x1c
|
#define PMC_MCKR_PRES 0x1c
|
||||||
|
|
||||||
/* Flash Controller Commands */
|
/* Flash Controller Commands */
|
||||||
#define WP 0x01
|
#define WP 0x01
|
||||||
#define SLB 0x02
|
#define SLB 0x02
|
||||||
#define WPL 0x03
|
#define WPL 0x03
|
||||||
#define CLB 0x04
|
#define CLB 0x04
|
||||||
#define EA 0x08
|
#define EA 0x08
|
||||||
#define SGPB 0x0B
|
#define SGPB 0x0B
|
||||||
#define CGPB 0x0D
|
#define CGPB 0x0D
|
||||||
#define SSB 0x0F
|
#define SSB 0x0F
|
||||||
|
|
||||||
/* MC_FSR bit definitions */
|
/* MC_FSR bit definitions */
|
||||||
#define MC_FSR_FRDY 1
|
#define MC_FSR_FRDY 1
|
||||||
#define MC_FSR_EOL 2
|
#define MC_FSR_EOL 2
|
||||||
|
|
||||||
/* AT91SAM7 constants */
|
/* AT91SAM7 constants */
|
||||||
#define RC_FREQ 32000
|
#define RC_FREQ 32000
|
||||||
|
|
||||||
/* FLASH_TIMING_MODES */
|
/* FLASH_TIMING_MODES */
|
||||||
#define FMR_TIMING_NONE 0
|
#define FMR_TIMING_NONE 0
|
||||||
#define FMR_TIMING_NVBITS 1
|
#define FMR_TIMING_NVBITS 1
|
||||||
#define FMR_TIMING_FLASH 2
|
#define FMR_TIMING_FLASH 2
|
||||||
|
|
||||||
#endif /* AT91SAM7_H */
|
#endif /* AT91SAM7_H */
|
||||||
|
|
4710
src/flash/cfi.c
4710
src/flash/cfi.c
File diff suppressed because it is too large
Load Diff
|
@ -1,179 +1,179 @@
|
||||||
/* src/flash/s3c2440_nand.c
|
/* src/flash/s3c2440_nand.c
|
||||||
*
|
*
|
||||||
* S3C2440 OpenOCD NAND Flash controller support.
|
* S3C2440 OpenOCD NAND Flash controller support.
|
||||||
*
|
*
|
||||||
* Copyright 2007,2008 Ben Dooks <ben@fluff.org>
|
* Copyright 2007,2008 Ben Dooks <ben@fluff.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Many thanks to Simtec Electronics for sponsoring this work.
|
* Many thanks to Simtec Electronics for sponsoring this work.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "replacements.h"
|
#include "replacements.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
#include "s3c24xx_nand.h"
|
#include "s3c24xx_nand.h"
|
||||||
#include "target.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_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_init(struct nand_device_s *device);
|
||||||
int s3c2440_nand_ready(struct nand_device_s *device, int timeout);
|
int s3c2440_nand_ready(struct nand_device_s *device, int timeout);
|
||||||
|
|
||||||
nand_flash_controller_t s3c2440_nand_controller =
|
nand_flash_controller_t s3c2440_nand_controller =
|
||||||
{
|
{
|
||||||
.name = "s3c2440",
|
.name = "s3c2440",
|
||||||
.nand_device_command = s3c2440_nand_device_command,
|
.nand_device_command = s3c2440_nand_device_command,
|
||||||
.register_commands = s3c24xx_register_commands,
|
.register_commands = s3c24xx_register_commands,
|
||||||
.init = s3c2440_init,
|
.init = s3c2440_init,
|
||||||
.reset = s3c24xx_reset,
|
.reset = s3c24xx_reset,
|
||||||
.command = s3c24xx_command,
|
.command = s3c24xx_command,
|
||||||
.address = s3c24xx_address,
|
.address = s3c24xx_address,
|
||||||
.write_data = s3c24xx_write_data,
|
.write_data = s3c24xx_write_data,
|
||||||
.read_data = s3c24xx_read_data,
|
.read_data = s3c24xx_read_data,
|
||||||
.write_page = s3c24xx_write_page,
|
.write_page = s3c24xx_write_page,
|
||||||
.read_page = s3c24xx_read_page,
|
.read_page = s3c24xx_read_page,
|
||||||
.write_block_data = s3c2440_write_block_data,
|
.write_block_data = s3c2440_write_block_data,
|
||||||
.read_block_data = s3c2440_read_block_data,
|
.read_block_data = s3c2440_read_block_data,
|
||||||
.controller_ready = s3c24xx_controller_ready,
|
.controller_ready = s3c24xx_controller_ready,
|
||||||
.nand_ready = s3c2440_nand_ready,
|
.nand_ready = s3c2440_nand_ready,
|
||||||
};
|
};
|
||||||
|
|
||||||
int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
|
int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||||
char **args, int argc,
|
char **args, int argc,
|
||||||
struct nand_device_s *device)
|
struct nand_device_s *device)
|
||||||
{
|
{
|
||||||
s3c24xx_nand_controller_t *info;
|
s3c24xx_nand_controller_t *info;
|
||||||
|
|
||||||
info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
|
info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
|
||||||
if (info == NULL) {
|
if (info == NULL) {
|
||||||
return ERROR_NAND_DEVICE_INVALID;
|
return ERROR_NAND_DEVICE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in the address fields for the core device */
|
/* fill in the address fields for the core device */
|
||||||
info->cmd = S3C2440_NFCMD;
|
info->cmd = S3C2440_NFCMD;
|
||||||
info->addr = S3C2440_NFADDR;
|
info->addr = S3C2440_NFADDR;
|
||||||
info->data = S3C2440_NFDATA;
|
info->data = S3C2440_NFDATA;
|
||||||
info->nfstat = S3C2440_NFSTAT;
|
info->nfstat = S3C2440_NFSTAT;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int s3c2440_init(struct nand_device_s *device)
|
int s3c2440_init(struct nand_device_s *device)
|
||||||
{
|
{
|
||||||
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
||||||
target_t *target = s3c24xx_info->target;
|
target_t *target = s3c24xx_info->target;
|
||||||
u32 version;
|
u32 version;
|
||||||
|
|
||||||
target_write_u32(target, S3C2410_NFCONF,
|
target_write_u32(target, S3C2410_NFCONF,
|
||||||
S3C2440_NFCONF_TACLS(3) |
|
S3C2440_NFCONF_TACLS(3) |
|
||||||
S3C2440_NFCONF_TWRPH0(7) |
|
S3C2440_NFCONF_TWRPH0(7) |
|
||||||
S3C2440_NFCONF_TWRPH1(7));
|
S3C2440_NFCONF_TWRPH1(7));
|
||||||
|
|
||||||
target_write_u32(target, S3C2440_NFCONT,
|
target_write_u32(target, S3C2440_NFCONT,
|
||||||
S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE);
|
S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int s3c2440_nand_ready(struct nand_device_s *device, int timeout)
|
int s3c2440_nand_ready(struct nand_device_s *device, int timeout)
|
||||||
{
|
{
|
||||||
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
||||||
target_t *target = s3c24xx_info->target;
|
target_t *target = s3c24xx_info->target;
|
||||||
u8 status;
|
u8 status;
|
||||||
|
|
||||||
if (target->state != TARGET_HALTED) {
|
if (target->state != TARGET_HALTED) {
|
||||||
ERROR("target must be halted to use S3C24XX NAND flash controller");
|
ERROR("target must be halted to use S3C24XX NAND flash controller");
|
||||||
return ERROR_NAND_OPERATION_FAILED;
|
return ERROR_NAND_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
target_read_u8(target, s3c24xx_info->nfstat, &status);
|
target_read_u8(target, s3c24xx_info->nfstat, &status);
|
||||||
|
|
||||||
if (status & S3C2440_NFSTAT_READY)
|
if (status & S3C2440_NFSTAT_READY)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
} while (timeout-- > 0);
|
} while (timeout-- > 0);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use the fact we can read/write 4 bytes in one go via a single 32bit op */
|
/* 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)
|
int s3c2440_read_block_data(struct nand_device_s *device, u8 *data, int data_size)
|
||||||
{
|
{
|
||||||
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
||||||
target_t *target = s3c24xx_info->target;
|
target_t *target = s3c24xx_info->target;
|
||||||
u32 nfdata = s3c24xx_info->data;
|
u32 nfdata = s3c24xx_info->data;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
INFO("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size);
|
INFO("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size);
|
||||||
|
|
||||||
if (target->state != TARGET_HALTED) {
|
if (target->state != TARGET_HALTED) {
|
||||||
ERROR("target must be halted to use S3C24XX NAND flash controller");
|
ERROR("target must be halted to use S3C24XX NAND flash controller");
|
||||||
return ERROR_NAND_OPERATION_FAILED;
|
return ERROR_NAND_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_size >= 4) {
|
while (data_size >= 4) {
|
||||||
target_read_u32(target, nfdata, &tmp);
|
target_read_u32(target, nfdata, &tmp);
|
||||||
|
|
||||||
data[0] = tmp;
|
data[0] = tmp;
|
||||||
data[1] = tmp >> 8;
|
data[1] = tmp >> 8;
|
||||||
data[2] = tmp >> 16;
|
data[2] = tmp >> 16;
|
||||||
data[3] = tmp >> 24;
|
data[3] = tmp >> 24;
|
||||||
|
|
||||||
data_size -= 4;
|
data_size -= 4;
|
||||||
data += 4;
|
data += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_size > 0) {
|
while (data_size > 0) {
|
||||||
target_read_u8(target, nfdata, data);
|
target_read_u8(target, nfdata, data);
|
||||||
|
|
||||||
data_size -= 1;
|
data_size -= 1;
|
||||||
data += 1;
|
data += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int s3c2440_write_block_data(struct nand_device_s *device, u8 *data, int data_size)
|
int s3c2440_write_block_data(struct nand_device_s *device, u8 *data, int data_size)
|
||||||
{
|
{
|
||||||
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
|
||||||
target_t *target = s3c24xx_info->target;
|
target_t *target = s3c24xx_info->target;
|
||||||
u32 nfdata = s3c24xx_info->data;
|
u32 nfdata = s3c24xx_info->data;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
if (target->state != TARGET_HALTED) {
|
if (target->state != TARGET_HALTED) {
|
||||||
ERROR("target must be halted to use S3C24XX NAND flash controller");
|
ERROR("target must be halted to use S3C24XX NAND flash controller");
|
||||||
return ERROR_NAND_OPERATION_FAILED;
|
return ERROR_NAND_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_size >= 4) {
|
while (data_size >= 4) {
|
||||||
tmp = le_to_h_u32(data);
|
tmp = le_to_h_u32(data);
|
||||||
target_write_u32(target, nfdata, tmp);
|
target_write_u32(target, nfdata, tmp);
|
||||||
|
|
||||||
data_size -= 4;
|
data_size -= 4;
|
||||||
data += 4;
|
data += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_size > 0) {
|
while (data_size > 0) {
|
||||||
target_write_u8(target, nfdata, *data);
|
target_write_u8(target, nfdata, *data);
|
||||||
|
|
||||||
data_size -= 1;
|
data_size -= 1;
|
||||||
data += 1;
|
data += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
2696
src/flash/str9xpec.c
2696
src/flash/str9xpec.c
File diff suppressed because it is too large
Load Diff
1214
src/helper/command.c
1214
src/helper/command.c
File diff suppressed because it is too large
Load Diff
|
@ -1,104 +1,104 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static size_t num_config_files;
|
static size_t num_config_files;
|
||||||
static char** config_file_names;
|
static char** config_file_names;
|
||||||
|
|
||||||
static size_t num_script_dirs;
|
static size_t num_script_dirs;
|
||||||
static char** script_search_dirs;
|
static char** script_search_dirs;
|
||||||
|
|
||||||
|
|
||||||
void add_script_search_dir (const char *dir)
|
void add_script_search_dir (const char *dir)
|
||||||
{
|
{
|
||||||
num_script_dirs++;
|
num_script_dirs++;
|
||||||
script_search_dirs = (char **)realloc(script_search_dirs, (num_script_dirs+1) * sizeof (char *));
|
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-1] = strdup(dir);
|
||||||
script_search_dirs[num_script_dirs] = NULL;
|
script_search_dirs[num_script_dirs] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_config_file_name (const char *cfg)
|
void add_config_file_name (const char *cfg)
|
||||||
{
|
{
|
||||||
num_config_files++;
|
num_config_files++;
|
||||||
config_file_names = (char **)realloc(config_file_names, (num_config_files+1) * sizeof (char *));
|
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-1] = strdup(cfg);
|
||||||
config_file_names[num_config_files] = NULL;
|
config_file_names[num_config_files] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *open_file_from_path (command_context_t *cmd_ctx, char *file, char *mode)
|
FILE *open_file_from_path (command_context_t *cmd_ctx, char *file, char *mode)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
char **search_dirs = script_search_dirs;
|
char **search_dirs = script_search_dirs;
|
||||||
char *dir;
|
char *dir;
|
||||||
char full_path[1024];
|
char full_path[1024];
|
||||||
|
|
||||||
/* Check absolute and relative to current working dir first.
|
/* Check absolute and relative to current working dir first.
|
||||||
* This keeps full_path reporting belowing working. */
|
* This keeps full_path reporting belowing working. */
|
||||||
snprintf(full_path, 1024, "%s", file);
|
snprintf(full_path, 1024, "%s", file);
|
||||||
fp = fopen(full_path, mode);
|
fp = fopen(full_path, mode);
|
||||||
|
|
||||||
while (!fp)
|
while (!fp)
|
||||||
{
|
{
|
||||||
dir = *search_dirs++;
|
dir = *search_dirs++;
|
||||||
|
|
||||||
if (!dir)
|
if (!dir)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
snprintf(full_path, 1024, "%s/%s", dir, file);
|
snprintf(full_path, 1024, "%s/%s", dir, file);
|
||||||
fp = fopen(full_path, mode);
|
fp = fopen(full_path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
command_print(cmd_ctx, "opened %s", full_path);
|
command_print(cmd_ctx, "opened %s", full_path);
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_config_file(struct command_context_s *cmd_ctx)
|
int parse_config_file(struct command_context_s *cmd_ctx)
|
||||||
{
|
{
|
||||||
char **cfg;
|
char **cfg;
|
||||||
FILE *config_file;
|
FILE *config_file;
|
||||||
|
|
||||||
if (!config_file_names)
|
if (!config_file_names)
|
||||||
add_config_file_name ("script openocd.cfg");
|
add_config_file_name ("script openocd.cfg");
|
||||||
|
|
||||||
cfg = config_file_names;
|
cfg = config_file_names;
|
||||||
|
|
||||||
while (*cfg)
|
while (*cfg)
|
||||||
{
|
{
|
||||||
command_run_line(cmd_ctx, *cfg);
|
command_run_line(cmd_ctx, *cfg);
|
||||||
cfg++;
|
cfg++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
496
src/helper/log.c
496
src/helper/log.c
|
@ -1,248 +1,248 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
int debug_level = -1;
|
int debug_level = -1;
|
||||||
|
|
||||||
static FILE* log_output;
|
static FILE* log_output;
|
||||||
static log_callback_t *log_callbacks = NULL;
|
static log_callback_t *log_callbacks = NULL;
|
||||||
|
|
||||||
static time_t start;
|
static time_t start;
|
||||||
|
|
||||||
static char *log_strings[5] =
|
static char *log_strings[5] =
|
||||||
{
|
{
|
||||||
"User: ",
|
"User: ",
|
||||||
"Error: ",
|
"Error: ",
|
||||||
"Warning:",
|
"Warning:",
|
||||||
"Info: ",
|
"Info: ",
|
||||||
"Debug: "
|
"Debug: "
|
||||||
};
|
};
|
||||||
|
|
||||||
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
|
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
|
||||||
{
|
{
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
count++;
|
count++;
|
||||||
va_list args;
|
va_list args;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
log_callback_t *cb;
|
log_callback_t *cb;
|
||||||
|
|
||||||
if (level > debug_level)
|
if (level > debug_level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsnprintf(buffer, 512, format, args);
|
vsnprintf(buffer, 512, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (level == LOG_OUTPUT)
|
if (level == LOG_OUTPUT)
|
||||||
{
|
{
|
||||||
/* do not prepend any headers, just print out what we were given and return */
|
/* do not prepend any headers, just print out what we were given and return */
|
||||||
fputs(buffer, log_output);
|
fputs(buffer, log_output);
|
||||||
fflush(log_output);
|
fflush(log_output);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *f = strrchr(file, '/');
|
char *f = strrchr(file, '/');
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
file = f + 1;
|
file = f + 1;
|
||||||
|
|
||||||
if (debug_level >= LOG_DEBUG)
|
if (debug_level >= LOG_DEBUG)
|
||||||
{
|
{
|
||||||
/* print with count and time information */
|
/* print with count and time information */
|
||||||
time_t t=time(NULL)-start;
|
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);
|
fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, t, file, line, function, buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* do not print count and time */
|
/* do not print count and time */
|
||||||
fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);
|
fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(log_output);
|
fflush(log_output);
|
||||||
|
|
||||||
/* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
|
/* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
|
||||||
if (level <= LOG_INFO)
|
if (level <= LOG_INFO)
|
||||||
{
|
{
|
||||||
for (cb = log_callbacks; cb; cb = cb->next)
|
for (cb = log_callbacks; cb; cb = cb->next)
|
||||||
{
|
{
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
cb->fn(cb->priv, file, line, function, format, args);
|
cb->fn(cb->priv, file, line, function, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change the current debug level on the fly
|
/* change the current debug level on the fly
|
||||||
* 0: only ERRORS
|
* 0: only ERRORS
|
||||||
* 1: + WARNINGS
|
* 1: + WARNINGS
|
||||||
* 2: + INFORMATIONAL MSGS
|
* 2: + INFORMATIONAL MSGS
|
||||||
* 3: + DEBUG MSGS
|
* 3: + DEBUG MSGS
|
||||||
*/
|
*/
|
||||||
int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
command_print(cmd_ctx, "debug_level: %i", debug_level);
|
command_print(cmd_ctx, "debug_level: %i", debug_level);
|
||||||
|
|
||||||
if (argc > 0)
|
if (argc > 0)
|
||||||
debug_level = strtoul(args[0], NULL, 0);
|
debug_level = strtoul(args[0], NULL, 0);
|
||||||
|
|
||||||
if (debug_level < 0)
|
if (debug_level < 0)
|
||||||
debug_level = 0;
|
debug_level = 0;
|
||||||
|
|
||||||
if (debug_level > 3)
|
if (debug_level > 3)
|
||||||
debug_level = 3;
|
debug_level = 3;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
FILE* file = fopen(args[0], "w");
|
FILE* file = fopen(args[0], "w");
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
log_output = file;
|
log_output = file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int log_register_commands(struct command_context_s *cmd_ctx)
|
int log_register_commands(struct command_context_s *cmd_ctx)
|
||||||
{
|
{
|
||||||
start = time(NULL);
|
start = time(NULL);
|
||||||
register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,
|
register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,
|
||||||
COMMAND_ANY, "redirect logging to <file> (default: stderr)");
|
COMMAND_ANY, "redirect logging to <file> (default: stderr)");
|
||||||
register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,
|
register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,
|
||||||
COMMAND_ANY, "adjust debug level <0-3>");
|
COMMAND_ANY, "adjust debug level <0-3>");
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int log_init(struct command_context_s *cmd_ctx)
|
int log_init(struct command_context_s *cmd_ctx)
|
||||||
{
|
{
|
||||||
/* set defaults for daemon configuration, if not set by cmdline or cfgfile */
|
/* set defaults for daemon configuration, if not set by cmdline or cfgfile */
|
||||||
if (debug_level == -1)
|
if (debug_level == -1)
|
||||||
debug_level = LOG_INFO;
|
debug_level = LOG_INFO;
|
||||||
|
|
||||||
if (log_output == NULL)
|
if (log_output == NULL)
|
||||||
{
|
{
|
||||||
log_output = stderr;
|
log_output = stderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
|
int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
|
||||||
{
|
{
|
||||||
log_output = output;
|
log_output = output;
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add/remove log callback handler */
|
/* add/remove log callback handler */
|
||||||
int log_add_callback(log_callback_fn fn, void *priv)
|
int log_add_callback(log_callback_fn fn, void *priv)
|
||||||
{
|
{
|
||||||
log_callback_t *cb;
|
log_callback_t *cb;
|
||||||
|
|
||||||
/* prevent the same callback to be registered more than once, just for sure */
|
/* prevent the same callback to be registered more than once, just for sure */
|
||||||
for (cb = log_callbacks; cb; cb = cb->next)
|
for (cb = log_callbacks; cb; cb = cb->next)
|
||||||
{
|
{
|
||||||
if (cb->fn == fn && cb->priv == priv)
|
if (cb->fn == fn && cb->priv == priv)
|
||||||
return ERROR_INVALID_ARGUMENTS;
|
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 */
|
/* 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)
|
if ((cb = malloc(sizeof(log_callback_t))) == NULL)
|
||||||
return ERROR_BUF_TOO_SMALL;
|
return ERROR_BUF_TOO_SMALL;
|
||||||
|
|
||||||
/* add item to the beginning of the linked list */
|
/* add item to the beginning of the linked list */
|
||||||
cb->fn = fn;
|
cb->fn = fn;
|
||||||
cb->priv = priv;
|
cb->priv = priv;
|
||||||
cb->next = log_callbacks;
|
cb->next = log_callbacks;
|
||||||
log_callbacks = cb;
|
log_callbacks = cb;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int log_remove_callback(log_callback_fn fn, void *priv)
|
int log_remove_callback(log_callback_fn fn, void *priv)
|
||||||
{
|
{
|
||||||
log_callback_t *cb, **p;
|
log_callback_t *cb, **p;
|
||||||
|
|
||||||
for (p = &log_callbacks; cb = *p; p = &(*p)->next)
|
for (p = &log_callbacks; cb = *p; p = &(*p)->next)
|
||||||
{
|
{
|
||||||
if (cb->fn == fn && cb->priv == priv)
|
if (cb->fn == fn && cb->priv == priv)
|
||||||
{
|
{
|
||||||
*p = cb->next;
|
*p = cb->next;
|
||||||
free(cb);
|
free(cb);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no such item */
|
/* no such item */
|
||||||
return ERROR_INVALID_ARGUMENTS;
|
return ERROR_INVALID_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return allocated string w/printf() result */
|
/* return allocated string w/printf() result */
|
||||||
char *alloc_printf(const char *fmt, va_list ap)
|
char *alloc_printf(const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
char *string = NULL;
|
char *string = NULL;
|
||||||
|
|
||||||
/* start by 0 to exercise all the code paths. Need minimum 2 bytes to
|
/* start by 0 to exercise all the code paths. Need minimum 2 bytes to
|
||||||
* fit 1 char and 0 terminator. */
|
* fit 1 char and 0 terminator. */
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if ((string == NULL) || (!first))
|
if ((string == NULL) || (!first))
|
||||||
{
|
{
|
||||||
size = size * 2 + 2;
|
size = size * 2 + 2;
|
||||||
char *t = string;
|
char *t = string;
|
||||||
string = realloc(string, size);
|
string = realloc(string, size);
|
||||||
if (string == NULL)
|
if (string == NULL)
|
||||||
{
|
{
|
||||||
if (t != NULL)
|
if (t != NULL)
|
||||||
free(t);
|
free(t);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
ret = vsnprintf(string, size, fmt, ap);
|
ret = vsnprintf(string, size, fmt, ap);
|
||||||
/* NB! The result of the vsnprintf() might be an *EMPTY* string! */
|
/* NB! The result of the vsnprintf() might be an *EMPTY* string! */
|
||||||
if ((ret >= 0) && ((ret + 1) < size))
|
if ((ret >= 0) && ((ret + 1) < size))
|
||||||
{
|
{
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
/* there was just enough or not enough space, allocate more. */
|
/* there was just enough or not enough space, allocate more. */
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
226
src/helper/log.h
226
src/helper/log.h
|
@ -1,113 +1,113 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef ERROR_H
|
#ifndef ERROR_H
|
||||||
#define ERROR_H
|
#define ERROR_H
|
||||||
|
|
||||||
#include "replacements.h"
|
#include "replacements.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* logging priorities
|
/* logging priorities
|
||||||
* LOG_USER - user messages. Could be anything from information
|
* LOG_USER - user messages. Could be anything from information
|
||||||
* to progress messags. These messages do not represent
|
* to progress messags. These messages do not represent
|
||||||
* incorrect or unexpected behaviour, just normal execution.
|
* incorrect or unexpected behaviour, just normal execution.
|
||||||
* LOG_ERROR - fatal errors, that are likely to cause program abort
|
* LOG_ERROR - fatal errors, that are likely to cause program abort
|
||||||
* LOG_WARNING - non-fatal errors, that may be resolved later
|
* LOG_WARNING - non-fatal errors, that may be resolved later
|
||||||
* LOG_INFO - state information, etc.
|
* LOG_INFO - state information, etc.
|
||||||
* LOG_DEBUG - debug statements, execution trace
|
* LOG_DEBUG - debug statements, execution trace
|
||||||
*/
|
*/
|
||||||
enum log_levels
|
enum log_levels
|
||||||
{
|
{
|
||||||
LOG_OUTPUT = -2,
|
LOG_OUTPUT = -2,
|
||||||
LOG_USER = -1,
|
LOG_USER = -1,
|
||||||
LOG_ERROR = 0,
|
LOG_ERROR = 0,
|
||||||
LOG_WARNING = 1,
|
LOG_WARNING = 1,
|
||||||
LOG_INFO = 2,
|
LOG_INFO = 2,
|
||||||
LOG_DEBUG = 3
|
LOG_DEBUG = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void log_printf(enum log_levels level, const char *file, int line,
|
extern void log_printf(enum log_levels level, const char *file, int line,
|
||||||
const char *function, const char *format, ...)
|
const char *function, const char *format, ...)
|
||||||
__attribute__ ((format (printf, 5, 6)));
|
__attribute__ ((format (printf, 5, 6)));
|
||||||
extern int log_register_commands(struct command_context_s *cmd_ctx);
|
extern int log_register_commands(struct command_context_s *cmd_ctx);
|
||||||
extern int log_init(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);
|
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,
|
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
|
||||||
const char *function, const char *format, va_list args);
|
const char *function, const char *format, va_list args);
|
||||||
|
|
||||||
typedef struct log_callback_s
|
typedef struct log_callback_s
|
||||||
{
|
{
|
||||||
log_callback_fn fn;
|
log_callback_fn fn;
|
||||||
void *priv;
|
void *priv;
|
||||||
struct log_callback_s *next;
|
struct log_callback_s *next;
|
||||||
} log_callback_t;
|
} log_callback_t;
|
||||||
|
|
||||||
extern int log_add_callback(log_callback_fn fn, void *priv);
|
extern int log_add_callback(log_callback_fn fn, void *priv);
|
||||||
extern int log_remove_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);
|
char *alloc_printf(const char *fmt, va_list ap);
|
||||||
|
|
||||||
extern int debug_level;
|
extern int debug_level;
|
||||||
|
|
||||||
/* Avoid fn call and building parameter list if we're not outputting the information.
|
/* 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 */
|
* Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */
|
||||||
|
|
||||||
#define DEBUG(expr ...) \
|
#define DEBUG(expr ...) \
|
||||||
do { if (debug_level >= LOG_DEBUG) \
|
do { if (debug_level >= LOG_DEBUG) \
|
||||||
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define INFO(expr ...) \
|
#define INFO(expr ...) \
|
||||||
do { if (debug_level >= LOG_INFO) \
|
do { if (debug_level >= LOG_INFO) \
|
||||||
log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define WARNING(expr ...) \
|
#define WARNING(expr ...) \
|
||||||
do { \
|
do { \
|
||||||
log_printf (LOG_WARNING, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_WARNING, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define ERROR(expr ...) \
|
#define ERROR(expr ...) \
|
||||||
do { \
|
do { \
|
||||||
log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define USER(expr ...) \
|
#define USER(expr ...) \
|
||||||
do { \
|
do { \
|
||||||
log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define OUTPUT(expr ...) \
|
#define OUTPUT(expr ...) \
|
||||||
do { \
|
do { \
|
||||||
log_printf (LOG_OUTPUT, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_OUTPUT, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* general failures
|
/* general failures
|
||||||
* error codes < 100
|
* error codes < 100
|
||||||
*/
|
*/
|
||||||
#define ERROR_OK (0)
|
#define ERROR_OK (0)
|
||||||
#define ERROR_INVALID_ARGUMENTS (-1)
|
#define ERROR_INVALID_ARGUMENTS (-1)
|
||||||
#define ERROR_NO_CONFIG_FILE (-2)
|
#define ERROR_NO_CONFIG_FILE (-2)
|
||||||
#define ERROR_BUF_TOO_SMALL (-3)
|
#define ERROR_BUF_TOO_SMALL (-3)
|
||||||
|
|
||||||
#endif /* LOG_H */
|
#endif /* LOG_H */
|
||||||
|
|
|
@ -1,153 +1,153 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2004, 2005 by Dominic Rath *
|
* Copyright (C) 2004, 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
static int help_flag;
|
static int help_flag;
|
||||||
|
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
{
|
{
|
||||||
{"help", no_argument, &help_flag, 1},
|
{"help", no_argument, &help_flag, 1},
|
||||||
|
|
||||||
{"debug", optional_argument, 0, 'd'},
|
{"debug", optional_argument, 0, 'd'},
|
||||||
{"file", required_argument, 0, 'f'},
|
{"file", required_argument, 0, 'f'},
|
||||||
{"search", required_argument, 0, 's'},
|
{"search", required_argument, 0, 's'},
|
||||||
{"log_output", required_argument, 0, 'l'},
|
{"log_output", required_argument, 0, 'l'},
|
||||||
{"command", required_argument, 0, 'c'},
|
{"command", required_argument, 0, 'c'},
|
||||||
|
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int configuration_output_handler(struct command_context_s *context, char* line)
|
int configuration_output_handler(struct command_context_s *context, char* line)
|
||||||
{
|
{
|
||||||
INFO(line);
|
INFO(line);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[])
|
int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
char command_buffer[128];
|
char command_buffer[128];
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* getopt_long stores the option index here. */
|
/* getopt_long stores the option index here. */
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
||||||
c = getopt_long(argc, argv, "hd::l:f:s:c:", long_options, &option_index);
|
c = getopt_long(argc, argv, "hd::l:f:s:c:", long_options, &option_index);
|
||||||
|
|
||||||
/* Detect the end of the options. */
|
/* Detect the end of the options. */
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 'h': /* --help | -h */
|
case 'h': /* --help | -h */
|
||||||
help_flag = 1;
|
help_flag = 1;
|
||||||
break;
|
break;
|
||||||
case 'f': /* --file | -f */
|
case 'f': /* --file | -f */
|
||||||
snprintf(command_buffer, 128, "script %s", optarg);
|
snprintf(command_buffer, 128, "script %s", optarg);
|
||||||
add_config_file_name(command_buffer);
|
add_config_file_name(command_buffer);
|
||||||
break;
|
break;
|
||||||
case 's': /* --search | -s */
|
case 's': /* --search | -s */
|
||||||
add_script_search_dir(optarg);
|
add_script_search_dir(optarg);
|
||||||
break;
|
break;
|
||||||
case 'd': /* --debug | -d */
|
case 'd': /* --debug | -d */
|
||||||
if (optarg)
|
if (optarg)
|
||||||
snprintf(command_buffer, 128, "debug_level %s", optarg);
|
snprintf(command_buffer, 128, "debug_level %s", optarg);
|
||||||
else
|
else
|
||||||
snprintf(command_buffer, 128, "debug_level 3");
|
snprintf(command_buffer, 128, "debug_level 3");
|
||||||
command_run_line(cmd_ctx, command_buffer);
|
command_run_line(cmd_ctx, command_buffer);
|
||||||
break;
|
break;
|
||||||
case 'l': /* --log_output | -l */
|
case 'l': /* --log_output | -l */
|
||||||
if (optarg)
|
if (optarg)
|
||||||
{
|
{
|
||||||
snprintf(command_buffer, 128, "log_output %s", optarg);
|
snprintf(command_buffer, 128, "log_output %s", optarg);
|
||||||
command_run_line(cmd_ctx, command_buffer);
|
command_run_line(cmd_ctx, command_buffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'c': /* --command | -c */
|
case 'c': /* --command | -c */
|
||||||
if (optarg)
|
if (optarg)
|
||||||
{
|
{
|
||||||
add_config_file_name(optarg);
|
add_config_file_name(optarg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (help_flag)
|
if (help_flag)
|
||||||
{
|
{
|
||||||
OUTPUT("Open On-Chip Debugger\n(c) 2005 by Dominic Rath\n\n");
|
OUTPUT("Open On-Chip Debugger\n(c) 2005 by Dominic Rath\n\n");
|
||||||
OUTPUT("--help | -h\tdisplay this help\n");
|
OUTPUT("--help | -h\tdisplay this help\n");
|
||||||
OUTPUT("--file | -f\tuse configuration file <name>\n");
|
OUTPUT("--file | -f\tuse configuration file <name>\n");
|
||||||
OUTPUT("--search | -s\tdir to search for config files and scripts.\n");
|
OUTPUT("--search | -s\tdir to search for config files and scripts.\n");
|
||||||
OUTPUT("--debug | -d\tset debug level <0-3>\n");
|
OUTPUT("--debug | -d\tset debug level <0-3>\n");
|
||||||
OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
|
OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
|
||||||
OUTPUT("--command | -c\trun <command>\n");
|
OUTPUT("--command | -c\trun <command>\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* Add the parent of the directory where openocd.exe resides to the
|
/* Add the parent of the directory where openocd.exe resides to the
|
||||||
* config script search path.
|
* config script search path.
|
||||||
* Directory layout:
|
* Directory layout:
|
||||||
* bin\openocd.exe
|
* bin\openocd.exe
|
||||||
* lib\openocd
|
* lib\openocd
|
||||||
* event\at91eb40a_reset.cfg
|
* event\at91eb40a_reset.cfg
|
||||||
* target\at91eb40a.cfg
|
* target\at91eb40a.cfg
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
char strExePath [MAX_PATH];
|
char strExePath [MAX_PATH];
|
||||||
GetModuleFileName (NULL, strExePath, MAX_PATH);
|
GetModuleFileName (NULL, strExePath, MAX_PATH);
|
||||||
/* Either this code will *always* work or it will SEGFAULT giving
|
/* Either this code will *always* work or it will SEGFAULT giving
|
||||||
* excellent information on the culprit.
|
* excellent information on the culprit.
|
||||||
*/
|
*/
|
||||||
*strrchr(strExePath, '\\')=0;
|
*strrchr(strExePath, '\\')=0;
|
||||||
strcat(strExePath, "\\..");
|
strcat(strExePath, "\\..");
|
||||||
add_script_search_dir(strExePath);
|
add_script_search_dir(strExePath);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Add dir for openocd supplied scripts last so that user can over
|
/* Add dir for openocd supplied scripts last so that user can over
|
||||||
ride those scripts if desired. */
|
ride those scripts if desired. */
|
||||||
add_script_search_dir(PKGDATADIR);
|
add_script_search_dir(PKGDATADIR);
|
||||||
add_script_search_dir(PKGLIBDIR);
|
add_script_search_dir(PKGLIBDIR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,38 +67,38 @@ struct timezone {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
|
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**** clear_malloc & fill_malloc ****/
|
/**** clear_malloc & fill_malloc ****/
|
||||||
void *clear_malloc(size_t size);
|
void *clear_malloc(size_t size);
|
||||||
void *fill_malloc(size_t size);
|
void *fill_malloc(size_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now you have 3 ways for the malloc function:
|
* Now you have 3 ways for the malloc function:
|
||||||
*
|
*
|
||||||
* 1. Do not change anything, use the original malloc
|
* 1. Do not change anything, use the original malloc
|
||||||
*
|
*
|
||||||
* 2. Use the clear_malloc function instead of the original malloc.
|
* 2. Use the clear_malloc function instead of the original malloc.
|
||||||
* In this case you must use the following define:
|
* In this case you must use the following define:
|
||||||
* #define malloc((_a)) clear_malloc((_a))
|
* #define malloc((_a)) clear_malloc((_a))
|
||||||
*
|
*
|
||||||
* 3. Use the fill_malloc function instead of the original malloc.
|
* 3. Use the fill_malloc function instead of the original malloc.
|
||||||
* In this case you must use the following define:
|
* In this case you must use the following define:
|
||||||
* #define malloc((_a)) fill_malloc((_a))
|
* #define malloc((_a)) fill_malloc((_a))
|
||||||
*
|
*
|
||||||
* We have figured out that there could exist some malloc problems
|
* We have figured out that there could exist some malloc problems
|
||||||
* where variables are using without to be initialise. To find this
|
* where variables are using without to be initialise. To find this
|
||||||
* places, use the fill_malloc function. With this function we want
|
* places, use the fill_malloc function. With this function we want
|
||||||
* to initialize memory to some known bad state. This is quite easily
|
* to initialize memory to some known bad state. This is quite easily
|
||||||
* spotted in the debugger and will trap to an invalid address.
|
* spotted in the debugger and will trap to an invalid address.
|
||||||
*
|
*
|
||||||
* clear_malloc can be used if you want to set not initialise
|
* clear_malloc can be used if you want to set not initialise
|
||||||
* variable to 0.
|
* variable to 0.
|
||||||
*
|
*
|
||||||
* If you do not want to change the malloc function, to not use one of
|
* If you do not want to change the malloc function, to not use one of
|
||||||
* the following macros. Which is the default way.
|
* the following macros. Which is the default way.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define malloc(_a) clear_malloc(_a)
|
//#define malloc(_a) clear_malloc(_a)
|
||||||
//#define malloc(_a) fill_malloc(_a)
|
//#define malloc(_a) fill_malloc(_a)
|
||||||
|
|
||||||
|
|
732
src/jtag/bitq.c
732
src/jtag/bitq.c
|
@ -1,366 +1,366 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Pavel Chromy *
|
* Copyright (C) 2007 by Pavel Chromy *
|
||||||
* chromy@asix.cz *
|
* chromy@asix.cz *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "bitq.h"
|
#include "bitq.h"
|
||||||
|
|
||||||
/* project specific includes */
|
/* project specific includes */
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "jtag.h"
|
#include "jtag.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
/* system includes */
|
/* system includes */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
bitq_interface_t *bitq_interface; /* low level bit queue interface */
|
bitq_interface_t *bitq_interface; /* low level bit queue interface */
|
||||||
|
|
||||||
bitq_state_t bitq_in_state; /* state of input queue */
|
bitq_state_t bitq_in_state; /* state of input queue */
|
||||||
|
|
||||||
u8 *bitq_in_buffer; /* buffer dynamically reallocated as needed */
|
u8 *bitq_in_buffer; /* buffer dynamically reallocated as needed */
|
||||||
unsigned long bitq_in_bufsize=32; /* min. buffer size */
|
unsigned long bitq_in_bufsize=32; /* min. buffer size */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
|
* input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
|
||||||
* also the buffer for incomming data is reallocated only if necessary
|
* also the buffer for incomming data is reallocated only if necessary
|
||||||
* no parameters, makes use of stored state information
|
* no parameters, makes use of stored state information
|
||||||
*/
|
*/
|
||||||
void bitq_in_proc(void)
|
void bitq_in_proc(void)
|
||||||
{
|
{
|
||||||
/* static information preserved between calls to increase performance */
|
/* static information preserved between calls to increase performance */
|
||||||
static u8 *in_buff; /* pointer to buffer for scanned data */
|
static u8 *in_buff; /* pointer to buffer for scanned data */
|
||||||
static int in_idx; /* index of byte being scanned */
|
static int in_idx; /* index of byte being scanned */
|
||||||
static u8 in_mask; /* mask of next bit to be scanned */
|
static u8 in_mask; /* mask of next bit to be scanned */
|
||||||
|
|
||||||
scan_field_t *field;
|
scan_field_t *field;
|
||||||
int tdo;
|
int tdo;
|
||||||
|
|
||||||
/* loop through the queue */
|
/* loop through the queue */
|
||||||
while (bitq_in_state.cmd) {
|
while (bitq_in_state.cmd) {
|
||||||
/* only JTAG_SCAN command may return data */
|
/* only JTAG_SCAN command may return data */
|
||||||
if (bitq_in_state.cmd->type==JTAG_SCAN) {
|
if (bitq_in_state.cmd->type==JTAG_SCAN) {
|
||||||
/* loop through the fields */
|
/* loop through the fields */
|
||||||
while (bitq_in_state.field_idx<bitq_in_state.cmd->cmd.scan->num_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];
|
field=&bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
|
||||||
if ( field->in_value || field->in_handler) {
|
if ( field->in_value || field->in_handler) {
|
||||||
|
|
||||||
if (bitq_in_state.bit_pos==0) {
|
if (bitq_in_state.bit_pos==0) {
|
||||||
/* initialize field scanning */
|
/* initialize field scanning */
|
||||||
in_mask=0x01;
|
in_mask=0x01;
|
||||||
in_idx=0;
|
in_idx=0;
|
||||||
if (field->in_value) in_buff=field->in_value;
|
if (field->in_value) in_buff=field->in_value;
|
||||||
else {
|
else {
|
||||||
/* buffer reallocation needed? */
|
/* buffer reallocation needed? */
|
||||||
if (field->num_bits>bitq_in_bufsize*8) {
|
if (field->num_bits>bitq_in_bufsize*8) {
|
||||||
/* buffer previously allocated? */
|
/* buffer previously allocated? */
|
||||||
if (bitq_in_buffer!=NULL) {
|
if (bitq_in_buffer!=NULL) {
|
||||||
/* free it */
|
/* free it */
|
||||||
free(bitq_in_buffer);
|
free(bitq_in_buffer);
|
||||||
bitq_in_buffer=NULL;
|
bitq_in_buffer=NULL;
|
||||||
}
|
}
|
||||||
/* double the buffer size until it fits */
|
/* double the buffer size until it fits */
|
||||||
while (field->num_bits>bitq_in_bufsize*8) bitq_in_bufsize*=2;
|
while (field->num_bits>bitq_in_bufsize*8) bitq_in_bufsize*=2;
|
||||||
}
|
}
|
||||||
/* if necessary, allocate buffer and check for malloc error */
|
/* if necessary, allocate buffer and check for malloc error */
|
||||||
if (bitq_in_buffer==NULL && (bitq_in_buffer=malloc(bitq_in_bufsize))==NULL) {
|
if (bitq_in_buffer==NULL && (bitq_in_buffer=malloc(bitq_in_bufsize))==NULL) {
|
||||||
ERROR("malloc error");
|
ERROR("malloc error");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
in_buff=(void *)bitq_in_buffer;
|
in_buff=(void *)bitq_in_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* field scanning */
|
/* field scanning */
|
||||||
while (bitq_in_state.bit_pos<field->num_bits) {
|
while (bitq_in_state.bit_pos<field->num_bits) {
|
||||||
if ((tdo=bitq_interface->in())<0) {
|
if ((tdo=bitq_interface->in())<0) {
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("bitq in EOF");
|
DEBUG("bitq in EOF");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (in_mask==0x01) in_buff[in_idx]=0;
|
if (in_mask==0x01) in_buff[in_idx]=0;
|
||||||
if (tdo) in_buff[in_idx]|=in_mask;
|
if (tdo) in_buff[in_idx]|=in_mask;
|
||||||
if (in_mask==0x80) {
|
if (in_mask==0x80) {
|
||||||
in_mask=0x01;
|
in_mask=0x01;
|
||||||
in_idx++;
|
in_idx++;
|
||||||
}
|
}
|
||||||
else in_mask<<=1;
|
else in_mask<<=1;
|
||||||
bitq_in_state.bit_pos++;
|
bitq_in_state.bit_pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (field->in_handler && bitq_in_state.status==ERROR_OK) {
|
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.status=(*field->in_handler)(in_buff, field->in_handler_priv, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bitq_in_state.field_idx++; /* advance to next 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.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.cmd=bitq_in_state.cmd->next; /* advance to next command */
|
||||||
bitq_in_state.field_idx=0; /* preselect first field */
|
bitq_in_state.field_idx=0; /* preselect first field */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void bitq_io(int tms, int tdi, int tdo_req)
|
void bitq_io(int tms, int tdi, int tdo_req)
|
||||||
{
|
{
|
||||||
bitq_interface->out(tms, tdi, tdo_req);
|
bitq_interface->out(tms, tdi, tdo_req);
|
||||||
/* check and process the input queue */
|
/* check and process the input queue */
|
||||||
if (bitq_interface->in_rdy()) bitq_in_proc();
|
if (bitq_interface->in_rdy()) bitq_in_proc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_end_state(enum tap_state state)
|
void bitq_end_state(enum tap_state state)
|
||||||
{
|
{
|
||||||
if (state==-1) return;
|
if (state==-1) return;
|
||||||
if (tap_move_map[state]==-1) {
|
if (tap_move_map[state]==-1) {
|
||||||
ERROR("BUG: %i is not a valid end state", state);
|
ERROR("BUG: %i is not a valid end state", state);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
end_state = state;
|
end_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_state_move(enum tap_state new_state)
|
void bitq_state_move(enum tap_state new_state)
|
||||||
{
|
{
|
||||||
int i=0;
|
int i=0;
|
||||||
u8 tms_scan;
|
u8 tms_scan;
|
||||||
|
|
||||||
if (tap_move_map[cur_state]==-1 || tap_move_map[new_state]==-1) {
|
if (tap_move_map[cur_state]==-1 || tap_move_map[new_state]==-1) {
|
||||||
ERROR("TAP move from or to unstable state");
|
ERROR("TAP move from or to unstable state");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tms_scan=TAP_MOVE(cur_state, new_state);
|
tms_scan=TAP_MOVE(cur_state, new_state);
|
||||||
|
|
||||||
for (i=0; i<7; i++) {
|
for (i=0; i<7; i++) {
|
||||||
bitq_io(tms_scan&1, 0, 0);
|
bitq_io(tms_scan&1, 0, 0);
|
||||||
tms_scan>>=1;
|
tms_scan>>=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_state = new_state;
|
cur_state = new_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_path_move(pathmove_command_t *cmd)
|
void bitq_path_move(pathmove_command_t *cmd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<=cmd->num_states; i++) {
|
for (i=0; i<=cmd->num_states; i++) {
|
||||||
if (tap_transitions[cur_state].low == cmd->path[i]) bitq_io(0, 0, 0);
|
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 if (tap_transitions[cur_state].high == cmd->path[i]) bitq_io(1, 0, 0);
|
||||||
else {
|
else {
|
||||||
ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[i]]);
|
ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[i]]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_state = cmd->path[i];
|
cur_state = cmd->path[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
end_state = cur_state;
|
end_state = cur_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_runtest(int num_cycles)
|
void bitq_runtest(int num_cycles)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* only do a state_move when we're not already in RTI */
|
/* only do a state_move when we're not already in RTI */
|
||||||
if (cur_state != TAP_RTI) bitq_state_move(TAP_RTI);
|
if (cur_state != TAP_RTI) bitq_state_move(TAP_RTI);
|
||||||
|
|
||||||
/* execute num_cycles */
|
/* execute num_cycles */
|
||||||
for (i = 0; i < num_cycles; i++)
|
for (i = 0; i < num_cycles; i++)
|
||||||
bitq_io(0, 0, 0);
|
bitq_io(0, 0, 0);
|
||||||
|
|
||||||
/* finish in end_state */
|
/* finish in end_state */
|
||||||
if (cur_state != end_state) bitq_state_move(end_state);
|
if (cur_state != end_state) bitq_state_move(end_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_scan_field(scan_field_t *field, int pause)
|
void bitq_scan_field(scan_field_t *field, int pause)
|
||||||
{
|
{
|
||||||
int bit_cnt;
|
int bit_cnt;
|
||||||
int tdo_req;
|
int tdo_req;
|
||||||
|
|
||||||
u8 *out_ptr;
|
u8 *out_ptr;
|
||||||
u8 out_mask;
|
u8 out_mask;
|
||||||
|
|
||||||
if ( field->in_value || field->in_handler) tdo_req=1;
|
if ( field->in_value || field->in_handler) tdo_req=1;
|
||||||
else tdo_req=0;
|
else tdo_req=0;
|
||||||
|
|
||||||
if (field->out_value==NULL) {
|
if (field->out_value==NULL) {
|
||||||
/* just send zeros and request data from TDO */
|
/* just send zeros and request data from TDO */
|
||||||
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--)
|
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--)
|
||||||
bitq_io(0, 0, tdo_req);
|
bitq_io(0, 0, tdo_req);
|
||||||
bitq_io(pause, 0, tdo_req);
|
bitq_io(pause, 0, tdo_req);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* send data, and optionally request TDO */
|
/* send data, and optionally request TDO */
|
||||||
out_mask=0x01;
|
out_mask=0x01;
|
||||||
out_ptr=field->out_value;
|
out_ptr=field->out_value;
|
||||||
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--) {
|
for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--) {
|
||||||
bitq_io(0, ((*out_ptr)&out_mask)!=0, tdo_req);
|
bitq_io(0, ((*out_ptr)&out_mask)!=0, tdo_req);
|
||||||
if (out_mask==0x80) {
|
if (out_mask==0x80) {
|
||||||
out_mask=0x01;
|
out_mask=0x01;
|
||||||
out_ptr++;
|
out_ptr++;
|
||||||
}
|
}
|
||||||
else out_mask<<=1;
|
else out_mask<<=1;
|
||||||
}
|
}
|
||||||
bitq_io(pause, ((*out_ptr)&out_mask)!=0, tdo_req);
|
bitq_io(pause, ((*out_ptr)&out_mask)!=0, tdo_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pause) {
|
if (pause) {
|
||||||
bitq_io(0,0,0);
|
bitq_io(0,0,0);
|
||||||
if (cur_state==TAP_SI) cur_state=TAP_PI;
|
if (cur_state==TAP_SI) cur_state=TAP_PI;
|
||||||
else if (cur_state==TAP_SD) cur_state=TAP_PD;
|
else if (cur_state==TAP_SD) cur_state=TAP_PD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_scan(scan_command_t *cmd)
|
void bitq_scan(scan_command_t *cmd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (cmd->ir_scan) bitq_state_move(TAP_SI);
|
if (cmd->ir_scan) bitq_state_move(TAP_SI);
|
||||||
else bitq_state_move(TAP_SD);
|
else bitq_state_move(TAP_SD);
|
||||||
|
|
||||||
for (i=0; i < cmd->num_fields-1; i++)
|
for (i=0; i < cmd->num_fields-1; i++)
|
||||||
bitq_scan_field(&cmd->fields[i], 0);
|
bitq_scan_field(&cmd->fields[i], 0);
|
||||||
bitq_scan_field(&cmd->fields[i], 1);
|
bitq_scan_field(&cmd->fields[i], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int bitq_execute_queue(void)
|
int bitq_execute_queue(void)
|
||||||
{
|
{
|
||||||
jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
|
jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
|
||||||
|
|
||||||
bitq_in_state.cmd = jtag_command_queue;
|
bitq_in_state.cmd = jtag_command_queue;
|
||||||
bitq_in_state.field_idx = 0;
|
bitq_in_state.field_idx = 0;
|
||||||
bitq_in_state.bit_pos = 0;
|
bitq_in_state.bit_pos = 0;
|
||||||
bitq_in_state.status = ERROR_OK;
|
bitq_in_state.status = ERROR_OK;
|
||||||
|
|
||||||
while (cmd) {
|
while (cmd) {
|
||||||
|
|
||||||
switch (cmd->type) {
|
switch (cmd->type) {
|
||||||
|
|
||||||
case JTAG_END_STATE:
|
case JTAG_END_STATE:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
|
DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
|
||||||
#endif
|
#endif
|
||||||
bitq_end_state(cmd->cmd.end_state->end_state);
|
bitq_end_state(cmd->cmd.end_state->end_state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JTAG_RESET:
|
case JTAG_RESET:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
|
DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
|
||||||
#endif
|
#endif
|
||||||
bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
|
bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
|
||||||
if (bitq_interface->in_rdy()) bitq_in_proc();
|
if (bitq_interface->in_rdy()) bitq_in_proc();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JTAG_RUNTEST:
|
case JTAG_RUNTEST:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
|
DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
|
||||||
#endif
|
#endif
|
||||||
bitq_end_state(cmd->cmd.runtest->end_state);
|
bitq_end_state(cmd->cmd.runtest->end_state);
|
||||||
bitq_runtest(cmd->cmd.runtest->num_cycles);
|
bitq_runtest(cmd->cmd.runtest->num_cycles);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JTAG_STATEMOVE:
|
case JTAG_STATEMOVE:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
|
DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
|
||||||
#endif
|
#endif
|
||||||
bitq_end_state(cmd->cmd.statemove->end_state);
|
bitq_end_state(cmd->cmd.statemove->end_state);
|
||||||
bitq_state_move(end_state); /* uncoditional TAP move */
|
bitq_state_move(end_state); /* uncoditional TAP move */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JTAG_PATHMOVE:
|
case JTAG_PATHMOVE:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#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]);
|
DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
|
||||||
#endif
|
#endif
|
||||||
bitq_path_move(cmd->cmd.pathmove);
|
bitq_path_move(cmd->cmd.pathmove);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JTAG_SCAN:
|
case JTAG_SCAN:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("scan end in %i", cmd->cmd.scan->end_state);
|
DEBUG("scan end in %i", cmd->cmd.scan->end_state);
|
||||||
if (cmd->cmd.scan->ir_scan) DEBUG("scan ir");
|
if (cmd->cmd.scan->ir_scan) DEBUG("scan ir");
|
||||||
else DEBUG("scan dr");
|
else DEBUG("scan dr");
|
||||||
#endif
|
#endif
|
||||||
bitq_end_state(cmd->cmd.scan->end_state);
|
bitq_end_state(cmd->cmd.scan->end_state);
|
||||||
bitq_scan(cmd->cmd.scan);
|
bitq_scan(cmd->cmd.scan);
|
||||||
if (cur_state != end_state) bitq_state_move(end_state);
|
if (cur_state != end_state) bitq_state_move(end_state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JTAG_SLEEP:
|
case JTAG_SLEEP:
|
||||||
#ifdef _DEBUG_JTAG_IO_
|
#ifdef _DEBUG_JTAG_IO_
|
||||||
DEBUG("sleep %i", cmd->cmd.sleep->us);
|
DEBUG("sleep %i", cmd->cmd.sleep->us);
|
||||||
#endif
|
#endif
|
||||||
bitq_interface->sleep(cmd->cmd.sleep->us);
|
bitq_interface->sleep(cmd->cmd.sleep->us);
|
||||||
if (bitq_interface->in_rdy()) bitq_in_proc();
|
if (bitq_interface->in_rdy()) bitq_in_proc();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERROR("BUG: unknown JTAG command type encountered");
|
ERROR("BUG: unknown JTAG command type encountered");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = cmd->next;
|
cmd = cmd->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitq_interface->flush();
|
bitq_interface->flush();
|
||||||
bitq_in_proc();
|
bitq_in_proc();
|
||||||
|
|
||||||
if (bitq_in_state.cmd) {
|
if (bitq_in_state.cmd) {
|
||||||
ERROR("missing data from bitq interface");
|
ERROR("missing data from bitq interface");
|
||||||
return ERROR_JTAG_QUEUE_FAILED;
|
return ERROR_JTAG_QUEUE_FAILED;
|
||||||
}
|
}
|
||||||
if (bitq_interface->in()>=0) {
|
if (bitq_interface->in()>=0) {
|
||||||
ERROR("extra data from bitq interface");
|
ERROR("extra data from bitq interface");
|
||||||
return ERROR_JTAG_QUEUE_FAILED;
|
return ERROR_JTAG_QUEUE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bitq_in_state.status;
|
return bitq_in_state.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bitq_cleanup(void)
|
void bitq_cleanup(void)
|
||||||
{
|
{
|
||||||
if (bitq_in_buffer!=NULL)
|
if (bitq_in_buffer!=NULL)
|
||||||
{
|
{
|
||||||
free(bitq_in_buffer);
|
free(bitq_in_buffer);
|
||||||
bitq_in_buffer=NULL;
|
bitq_in_buffer=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,237 +1,237 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "jtag.h"
|
#include "jtag.h"
|
||||||
#include "bitbang.h"
|
#include "bitbang.h"
|
||||||
|
|
||||||
#define TDO_BIT 1
|
#define TDO_BIT 1
|
||||||
#define TDI_BIT 2
|
#define TDI_BIT 2
|
||||||
#define TCK_BIT 4
|
#define TCK_BIT 4
|
||||||
#define TMS_BIT 8
|
#define TMS_BIT 8
|
||||||
#define TRST_BIT 16
|
#define TRST_BIT 16
|
||||||
#define SRST_BIT 32
|
#define SRST_BIT 32
|
||||||
#define VCC_BIT 64
|
#define VCC_BIT 64
|
||||||
|
|
||||||
/* system includes */
|
/* system includes */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
static u8 output_value = 0x0;
|
static u8 output_value = 0x0;
|
||||||
static int dev_mem_fd;
|
static int dev_mem_fd;
|
||||||
static void *gpio_controller;
|
static void *gpio_controller;
|
||||||
static volatile u8 *gpio_data_register;
|
static volatile u8 *gpio_data_register;
|
||||||
static volatile u8 *gpio_data_direction_register;
|
static volatile u8 *gpio_data_direction_register;
|
||||||
|
|
||||||
/* low level command set
|
/* low level command set
|
||||||
*/
|
*/
|
||||||
int ep93xx_read(void);
|
int ep93xx_read(void);
|
||||||
void ep93xx_write(int tck, int tms, int tdi);
|
void ep93xx_write(int tck, int tms, int tdi);
|
||||||
void ep93xx_reset(int trst, int srst);
|
void ep93xx_reset(int trst, int srst);
|
||||||
|
|
||||||
int ep93xx_speed(int speed);
|
int ep93xx_speed(int speed);
|
||||||
int ep93xx_register_commands(struct command_context_s *cmd_ctx);
|
int ep93xx_register_commands(struct command_context_s *cmd_ctx);
|
||||||
int ep93xx_init(void);
|
int ep93xx_init(void);
|
||||||
int ep93xx_quit(void);
|
int ep93xx_quit(void);
|
||||||
|
|
||||||
struct timespec ep93xx_zzzz;
|
struct timespec ep93xx_zzzz;
|
||||||
|
|
||||||
jtag_interface_t ep93xx_interface =
|
jtag_interface_t ep93xx_interface =
|
||||||
{
|
{
|
||||||
.name = "ep93xx",
|
.name = "ep93xx",
|
||||||
|
|
||||||
.execute_queue = bitbang_execute_queue,
|
.execute_queue = bitbang_execute_queue,
|
||||||
|
|
||||||
.speed = ep93xx_speed,
|
.speed = ep93xx_speed,
|
||||||
.register_commands = ep93xx_register_commands,
|
.register_commands = ep93xx_register_commands,
|
||||||
.init = ep93xx_init,
|
.init = ep93xx_init,
|
||||||
.quit = ep93xx_quit,
|
.quit = ep93xx_quit,
|
||||||
};
|
};
|
||||||
|
|
||||||
bitbang_interface_t ep93xx_bitbang =
|
bitbang_interface_t ep93xx_bitbang =
|
||||||
{
|
{
|
||||||
.read = ep93xx_read,
|
.read = ep93xx_read,
|
||||||
.write = ep93xx_write,
|
.write = ep93xx_write,
|
||||||
.reset = ep93xx_reset,
|
.reset = ep93xx_reset,
|
||||||
.blink = 0;
|
.blink = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int ep93xx_read(void)
|
int ep93xx_read(void)
|
||||||
{
|
{
|
||||||
return !!(*gpio_data_register & TDO_BIT);
|
return !!(*gpio_data_register & TDO_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ep93xx_write(int tck, int tms, int tdi)
|
void ep93xx_write(int tck, int tms, int tdi)
|
||||||
{
|
{
|
||||||
if (tck)
|
if (tck)
|
||||||
output_value |= TCK_BIT;
|
output_value |= TCK_BIT;
|
||||||
else
|
else
|
||||||
output_value &= TCK_BIT;
|
output_value &= TCK_BIT;
|
||||||
|
|
||||||
if (tms)
|
if (tms)
|
||||||
output_value |= TMS_BIT;
|
output_value |= TMS_BIT;
|
||||||
else
|
else
|
||||||
output_value &= TMS_BIT;
|
output_value &= TMS_BIT;
|
||||||
|
|
||||||
if (tdi)
|
if (tdi)
|
||||||
output_value |= TDI_BIT;
|
output_value |= TDI_BIT;
|
||||||
else
|
else
|
||||||
output_value &= TDI_BIT;
|
output_value &= TDI_BIT;
|
||||||
|
|
||||||
*gpio_data_register = output_value;
|
*gpio_data_register = output_value;
|
||||||
nanosleep(ep93xx_zzzz);
|
nanosleep(ep93xx_zzzz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (1) assert or (0) deassert reset lines */
|
/* (1) assert or (0) deassert reset lines */
|
||||||
void ep93xx_reset(int trst, int srst)
|
void ep93xx_reset(int trst, int srst)
|
||||||
{
|
{
|
||||||
if (trst == 0)
|
if (trst == 0)
|
||||||
output_value |= TRST_BIT;
|
output_value |= TRST_BIT;
|
||||||
else if (trst == 1)
|
else if (trst == 1)
|
||||||
output_value &= TRST_BIT;
|
output_value &= TRST_BIT;
|
||||||
|
|
||||||
if (srst == 0)
|
if (srst == 0)
|
||||||
output_value |= SRST_BIT;
|
output_value |= SRST_BIT;
|
||||||
else if (srst == 1)
|
else if (srst == 1)
|
||||||
output_value &= SRST_BIT;
|
output_value &= SRST_BIT;
|
||||||
|
|
||||||
*gpio_data_register = output_value;
|
*gpio_data_register = output_value;
|
||||||
nanosleep(ep93xx_zzzz);
|
nanosleep(ep93xx_zzzz);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ep93xx_speed(int speed)
|
int ep93xx_speed(int speed)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ep93xx_register_commands(struct command_context_s *cmd_ctx)
|
int ep93xx_register_commands(struct command_context_s *cmd_ctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_gonk_mode(void)
|
static int set_gonk_mode(void)
|
||||||
{
|
{
|
||||||
void *syscon;
|
void *syscon;
|
||||||
u32 devicecfg;
|
u32 devicecfg;
|
||||||
|
|
||||||
syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
|
syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, dev_mem_fd, 0x80930000);
|
MAP_SHARED, dev_mem_fd, 0x80930000);
|
||||||
if (syscon == MAP_FAILED) {
|
if (syscon == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap");
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
return ERROR_JTAG_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
devicecfg = *((volatile int *)(syscon + 0x80));
|
devicecfg = *((volatile int *)(syscon + 0x80));
|
||||||
*((volatile int *)(syscon + 0xc0)) = 0xaa;
|
*((volatile int *)(syscon + 0xc0)) = 0xaa;
|
||||||
*((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;
|
*((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;
|
||||||
|
|
||||||
munmap(syscon, 4096);
|
munmap(syscon, 4096);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ep93xx_init(void)
|
int ep93xx_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bitbang_interface = &ep93xx_bitbang;
|
bitbang_interface = &ep93xx_bitbang;
|
||||||
|
|
||||||
ep93xx_zzzz.tv_sec = 0;
|
ep93xx_zzzz.tv_sec = 0;
|
||||||
ep93xx_zzzz.tv_nsec = 10000000;
|
ep93xx_zzzz.tv_nsec = 10000000;
|
||||||
|
|
||||||
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||||||
if (dev_mem_fd < 0) {
|
if (dev_mem_fd < 0) {
|
||||||
perror("open");
|
perror("open");
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
return ERROR_JTAG_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
|
gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, dev_mem_fd, 0x80840000);
|
MAP_SHARED, dev_mem_fd, 0x80840000);
|
||||||
if (gpio_controller == MAP_FAILED) {
|
if (gpio_controller == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap");
|
||||||
close(dev_mem_fd);
|
close(dev_mem_fd);
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
return ERROR_JTAG_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = set_gonk_mode();
|
ret = set_gonk_mode();
|
||||||
if (ret != ERROR_OK) {
|
if (ret != ERROR_OK) {
|
||||||
munmap(gpio_controller, 4096);
|
munmap(gpio_controller, 4096);
|
||||||
close(dev_mem_fd);
|
close(dev_mem_fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Use GPIO port A. */
|
/* Use GPIO port A. */
|
||||||
gpio_data_register = gpio_controller + 0x00;
|
gpio_data_register = gpio_controller + 0x00;
|
||||||
gpio_data_direction_register = gpio_controller + 0x10;
|
gpio_data_direction_register = gpio_controller + 0x10;
|
||||||
|
|
||||||
|
|
||||||
/* Use GPIO port B. */
|
/* Use GPIO port B. */
|
||||||
gpio_data_register = gpio_controller + 0x04;
|
gpio_data_register = gpio_controller + 0x04;
|
||||||
gpio_data_direction_register = gpio_controller + 0x14;
|
gpio_data_direction_register = gpio_controller + 0x14;
|
||||||
|
|
||||||
/* Use GPIO port C. */
|
/* Use GPIO port C. */
|
||||||
gpio_data_register = gpio_controller + 0x08;
|
gpio_data_register = gpio_controller + 0x08;
|
||||||
gpio_data_direction_register = gpio_controller + 0x18;
|
gpio_data_direction_register = gpio_controller + 0x18;
|
||||||
|
|
||||||
/* Use GPIO port D. */
|
/* Use GPIO port D. */
|
||||||
gpio_data_register = gpio_controller + 0x0c;
|
gpio_data_register = gpio_controller + 0x0c;
|
||||||
gpio_data_direction_register = gpio_controller + 0x1c;
|
gpio_data_direction_register = gpio_controller + 0x1c;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Use GPIO port C. */
|
/* Use GPIO port C. */
|
||||||
gpio_data_register = gpio_controller + 0x08;
|
gpio_data_register = gpio_controller + 0x08;
|
||||||
gpio_data_direction_register = gpio_controller + 0x18;
|
gpio_data_direction_register = gpio_controller + 0x18;
|
||||||
|
|
||||||
INFO("gpio_data_register = %p\n", gpio_data_register);
|
INFO("gpio_data_register = %p\n", gpio_data_register);
|
||||||
INFO("gpio_data_direction_reg = %p\n", gpio_data_direction_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
|
* 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) as outputs. Drive TDI and TCK low, and
|
||||||
* TMS/TRST/SRST high.
|
* TMS/TRST/SRST high.
|
||||||
*/
|
*/
|
||||||
output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
|
output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
|
||||||
*gpio_data_register = output_value;
|
*gpio_data_register = output_value;
|
||||||
nanosleep(ep93xx_zzzz);
|
nanosleep(ep93xx_zzzz);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the direction register. 1 = output, 0 = input.
|
* Configure the direction register. 1 = output, 0 = input.
|
||||||
*/
|
*/
|
||||||
*gpio_data_direction_register =
|
*gpio_data_direction_register =
|
||||||
TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
|
TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
|
||||||
|
|
||||||
nanosleep(ep93xx_zzzz);
|
nanosleep(ep93xx_zzzz);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ep93xx_quit(void)
|
int ep93xx_quit(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
4278
src/jtag/ft2232.c
4278
src/jtag/ft2232.c
File diff suppressed because it is too large
Load Diff
3682
src/jtag/jtag.c
3682
src/jtag/jtag.c
File diff suppressed because it is too large
Load Diff
1362
src/jtag/usbprog.c
1362
src/jtag/usbprog.c
File diff suppressed because it is too large
Load Diff
314
src/openocd.c
314
src/openocd.c
|
@ -1,157 +1,157 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
|
#define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "jtag.h"
|
#include "jtag.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
#include "xsvf.h"
|
#include "xsvf.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
#include "pld.h"
|
#include "pld.h"
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "telnet_server.h"
|
#include "telnet_server.h"
|
||||||
#include "gdb_server.h"
|
#include "gdb_server.h"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/* Give TELNET a way to find out what version this is */
|
/* 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)
|
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, OPENOCD_VERSION);
|
command_print(cmd_ctx, OPENOCD_VERSION);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_handler(void)
|
void exit_handler(void)
|
||||||
{
|
{
|
||||||
/* close JTAG interface */
|
/* close JTAG interface */
|
||||||
if (jtag && jtag->quit)
|
if (jtag && jtag->quit)
|
||||||
jtag->quit();
|
jtag->quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* initialize commandline interface */
|
/* initialize commandline interface */
|
||||||
command_context_t *cmd_ctx, *cfg_cmd_ctx;
|
command_context_t *cmd_ctx, *cfg_cmd_ctx;
|
||||||
cmd_ctx = command_init();
|
cmd_ctx = command_init();
|
||||||
|
|
||||||
register_command(cmd_ctx, NULL, "version", handle_version_command,
|
register_command(cmd_ctx, NULL, "version", handle_version_command,
|
||||||
COMMAND_EXEC, "show OpenOCD version");
|
COMMAND_EXEC, "show OpenOCD version");
|
||||||
|
|
||||||
/* register subsystem commands */
|
/* register subsystem commands */
|
||||||
server_register_commands(cmd_ctx);
|
server_register_commands(cmd_ctx);
|
||||||
telnet_register_commands(cmd_ctx);
|
telnet_register_commands(cmd_ctx);
|
||||||
gdb_register_commands(cmd_ctx);
|
gdb_register_commands(cmd_ctx);
|
||||||
log_register_commands(cmd_ctx);
|
log_register_commands(cmd_ctx);
|
||||||
jtag_register_commands(cmd_ctx);
|
jtag_register_commands(cmd_ctx);
|
||||||
interpreter_register_commands(cmd_ctx);
|
interpreter_register_commands(cmd_ctx);
|
||||||
xsvf_register_commands(cmd_ctx);
|
xsvf_register_commands(cmd_ctx);
|
||||||
target_register_commands(cmd_ctx);
|
target_register_commands(cmd_ctx);
|
||||||
flash_register_commands(cmd_ctx);
|
flash_register_commands(cmd_ctx);
|
||||||
nand_register_commands(cmd_ctx);
|
nand_register_commands(cmd_ctx);
|
||||||
pld_register_commands(cmd_ctx);
|
pld_register_commands(cmd_ctx);
|
||||||
|
|
||||||
if (log_init(cmd_ctx) != ERROR_OK)
|
if (log_init(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("log init complete");
|
DEBUG("log init complete");
|
||||||
|
|
||||||
printf( OPENOCD_VERSION );
|
printf( OPENOCD_VERSION );
|
||||||
printf( "\n$URL$\n");
|
printf( "\n$URL$\n");
|
||||||
|
|
||||||
DEBUG( OPENOCD_VERSION );
|
DEBUG( OPENOCD_VERSION );
|
||||||
DEBUG( "$URL$");
|
DEBUG( "$URL$");
|
||||||
|
|
||||||
cfg_cmd_ctx = copy_command_context(cmd_ctx);
|
cfg_cmd_ctx = copy_command_context(cmd_ctx);
|
||||||
cfg_cmd_ctx->mode = COMMAND_CONFIG;
|
cfg_cmd_ctx->mode = COMMAND_CONFIG;
|
||||||
command_set_output_handler(cfg_cmd_ctx, configuration_output_handler, NULL);
|
command_set_output_handler(cfg_cmd_ctx, configuration_output_handler, NULL);
|
||||||
|
|
||||||
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
|
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
|
if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
command_done(cfg_cmd_ctx);
|
command_done(cfg_cmd_ctx);
|
||||||
|
|
||||||
command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
|
command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
|
||||||
|
|
||||||
atexit(exit_handler);
|
atexit(exit_handler);
|
||||||
|
|
||||||
if (jtag_init(cmd_ctx) != ERROR_OK)
|
if (jtag_init(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("jtag init complete");
|
DEBUG("jtag init complete");
|
||||||
|
|
||||||
if (target_init(cmd_ctx) != ERROR_OK)
|
if (target_init(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("target init complete");
|
DEBUG("target init complete");
|
||||||
|
|
||||||
if (flash_init_drivers(cmd_ctx) != ERROR_OK)
|
if (flash_init_drivers(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("flash init complete");
|
DEBUG("flash init complete");
|
||||||
|
|
||||||
if (nand_init(cmd_ctx) != ERROR_OK)
|
if (nand_init(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("NAND init complete");
|
DEBUG("NAND init complete");
|
||||||
|
|
||||||
if (pld_init(cmd_ctx) != ERROR_OK)
|
if (pld_init(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("pld init complete");
|
DEBUG("pld init complete");
|
||||||
|
|
||||||
/* initialize tcp server */
|
/* initialize tcp server */
|
||||||
server_init();
|
server_init();
|
||||||
|
|
||||||
/* initialize telnet subsystem */
|
/* initialize telnet subsystem */
|
||||||
telnet_init("Open On-Chip Debugger");
|
telnet_init("Open On-Chip Debugger");
|
||||||
gdb_init();
|
gdb_init();
|
||||||
|
|
||||||
/* call any target resets */
|
/* call any target resets */
|
||||||
if (target_init_reset(cmd_ctx) != ERROR_OK)
|
if (target_init_reset(cmd_ctx) != ERROR_OK)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
DEBUG("target init reset complete");
|
DEBUG("target init reset complete");
|
||||||
|
|
||||||
/* handle network connections */
|
/* handle network connections */
|
||||||
server_loop(cmd_ctx);
|
server_loop(cmd_ctx);
|
||||||
|
|
||||||
/* shut server down */
|
/* shut server down */
|
||||||
server_quit();
|
server_quit();
|
||||||
|
|
||||||
/* free commandline interface */
|
/* free commandline interface */
|
||||||
command_done(cmd_ctx);
|
command_done(cmd_ctx);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,264 +1,264 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2006 by Dominic Rath *
|
* Copyright (C) 2006 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "virtex2.h"
|
#include "virtex2.h"
|
||||||
|
|
||||||
#include "pld.h"
|
#include "pld.h"
|
||||||
#include "xilinx_bit.h"
|
#include "xilinx_bit.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "jtag.h"
|
#include "jtag.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int virtex2_register_commands(struct command_context_s *cmd_ctx);
|
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_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);
|
int virtex2_load(struct pld_device_s *pld_device, char *filename);
|
||||||
|
|
||||||
pld_driver_t virtex2_pld =
|
pld_driver_t virtex2_pld =
|
||||||
{
|
{
|
||||||
.name = "virtex2",
|
.name = "virtex2",
|
||||||
.register_commands = virtex2_register_commands,
|
.register_commands = virtex2_register_commands,
|
||||||
.pld_device_command = virtex2_pld_device_command,
|
.pld_device_command = virtex2_pld_device_command,
|
||||||
.load = virtex2_load,
|
.load = virtex2_load,
|
||||||
};
|
};
|
||||||
|
|
||||||
int virtex2_set_instr(int chain_pos, u32 new_instr)
|
int virtex2_set_instr(int chain_pos, u32 new_instr)
|
||||||
{
|
{
|
||||||
jtag_device_t *device = jtag_get_device(chain_pos);
|
jtag_device_t *device = jtag_get_device(chain_pos);
|
||||||
|
|
||||||
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
||||||
{
|
{
|
||||||
scan_field_t field;
|
scan_field_t field;
|
||||||
|
|
||||||
field.device = chain_pos;
|
field.device = chain_pos;
|
||||||
field.num_bits = device->ir_length;
|
field.num_bits = device->ir_length;
|
||||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||||
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
||||||
field.out_mask = NULL;
|
field.out_mask = NULL;
|
||||||
field.in_value = NULL;
|
field.in_value = NULL;
|
||||||
field.in_check_value = NULL;
|
field.in_check_value = NULL;
|
||||||
field.in_check_mask = NULL;
|
field.in_check_mask = NULL;
|
||||||
field.in_handler = NULL;
|
field.in_handler = NULL;
|
||||||
field.in_handler_priv = NULL;
|
field.in_handler_priv = NULL;
|
||||||
|
|
||||||
jtag_add_ir_scan(1, &field, TAP_RTI);
|
jtag_add_ir_scan(1, &field, TAP_RTI);
|
||||||
|
|
||||||
free(field.out_value);
|
free(field.out_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_send_32(struct pld_device_s *pld_device, int num_words, u32 *words)
|
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;
|
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||||
scan_field_t scan_field;
|
scan_field_t scan_field;
|
||||||
u8 *values;
|
u8 *values;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
values = malloc(num_words * 4);
|
values = malloc(num_words * 4);
|
||||||
|
|
||||||
scan_field.device = virtex2_info->chain_pos;
|
scan_field.device = virtex2_info->chain_pos;
|
||||||
scan_field.num_bits = num_words * 32;
|
scan_field.num_bits = num_words * 32;
|
||||||
scan_field.out_value = values;
|
scan_field.out_value = values;
|
||||||
scan_field.out_mask = NULL;
|
scan_field.out_mask = NULL;
|
||||||
scan_field.in_value = NULL;
|
scan_field.in_value = NULL;
|
||||||
scan_field.in_check_value = NULL;
|
scan_field.in_check_value = NULL;
|
||||||
scan_field.in_check_mask = NULL;
|
scan_field.in_check_mask = NULL;
|
||||||
scan_field.in_handler = NULL;
|
scan_field.in_handler = NULL;
|
||||||
scan_field.in_handler_priv = NULL;
|
scan_field.in_handler_priv = NULL;
|
||||||
|
|
||||||
for (i = 0; i < num_words; i++)
|
for (i = 0; i < num_words; i++)
|
||||||
buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
|
buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
|
||||||
|
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
||||||
|
|
||||||
jtag_add_dr_scan(1, &scan_field, TAP_PD);
|
jtag_add_dr_scan(1, &scan_field, TAP_PD);
|
||||||
|
|
||||||
free(values);
|
free(values);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
int virtex2_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||||
{
|
{
|
||||||
u32 *dest = priv;
|
u32 *dest = priv;
|
||||||
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_receive_32(struct pld_device_s *pld_device, int num_words, u32 *words)
|
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;
|
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||||
scan_field_t scan_field;
|
scan_field_t scan_field;
|
||||||
|
|
||||||
scan_field.device = virtex2_info->chain_pos;
|
scan_field.device = virtex2_info->chain_pos;
|
||||||
scan_field.num_bits = 32;
|
scan_field.num_bits = 32;
|
||||||
scan_field.out_value = NULL;
|
scan_field.out_value = NULL;
|
||||||
scan_field.out_mask = NULL;
|
scan_field.out_mask = NULL;
|
||||||
scan_field.in_value = NULL;
|
scan_field.in_value = NULL;
|
||||||
scan_field.in_check_value = NULL;
|
scan_field.in_check_value = NULL;
|
||||||
scan_field.in_check_mask = NULL;
|
scan_field.in_check_mask = NULL;
|
||||||
scan_field.in_handler = virtex2_jtag_buf_to_u32;
|
scan_field.in_handler = virtex2_jtag_buf_to_u32;
|
||||||
|
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0x4); /* CFG_OUT */
|
virtex2_set_instr(virtex2_info->chain_pos, 0x4); /* CFG_OUT */
|
||||||
|
|
||||||
while (num_words--)
|
while (num_words--)
|
||||||
{
|
{
|
||||||
scan_field.in_handler_priv = words++;
|
scan_field.in_handler_priv = words++;
|
||||||
jtag_add_dr_scan(1, &scan_field, TAP_PD);
|
jtag_add_dr_scan(1, &scan_field, TAP_PD);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_read_stat(struct pld_device_s *pld_device, u32 *status)
|
int virtex2_read_stat(struct pld_device_s *pld_device, u32 *status)
|
||||||
{
|
{
|
||||||
u32 data[5];
|
u32 data[5];
|
||||||
|
|
||||||
jtag_add_statemove(TAP_TLR);
|
jtag_add_statemove(TAP_TLR);
|
||||||
|
|
||||||
data[0] = 0xaa995566; /* synch word */
|
data[0] = 0xaa995566; /* synch word */
|
||||||
data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
|
data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
|
||||||
data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
|
data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
|
||||||
data[3] = 0x20000000; /* NOOP */
|
data[3] = 0x20000000; /* NOOP */
|
||||||
data[4] = 0x20000000; /* NOOP */
|
data[4] = 0x20000000; /* NOOP */
|
||||||
virtex2_send_32(pld_device, 5, data);
|
virtex2_send_32(pld_device, 5, data);
|
||||||
|
|
||||||
virtex2_receive_32(pld_device, 1, status);
|
virtex2_receive_32(pld_device, 1, status);
|
||||||
|
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
|
|
||||||
DEBUG("status: 0x%8.8x", *status);
|
DEBUG("status: 0x%8.8x", *status);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_load(struct pld_device_s *pld_device, char *filename)
|
int virtex2_load(struct pld_device_s *pld_device, char *filename)
|
||||||
{
|
{
|
||||||
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
|
||||||
xilinx_bit_file_t bit_file;
|
xilinx_bit_file_t bit_file;
|
||||||
int retval;
|
int retval;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
scan_field_t field;
|
scan_field_t field;
|
||||||
|
|
||||||
field.device = virtex2_info->chain_pos;
|
field.device = virtex2_info->chain_pos;
|
||||||
field.out_mask = NULL;
|
field.out_mask = NULL;
|
||||||
field.in_value = NULL;
|
field.in_value = NULL;
|
||||||
field.in_check_value = NULL;
|
field.in_check_value = NULL;
|
||||||
field.in_check_mask = NULL;
|
field.in_check_mask = NULL;
|
||||||
field.in_handler = NULL;
|
field.in_handler = NULL;
|
||||||
field.in_handler_priv = NULL;
|
field.in_handler_priv = NULL;
|
||||||
|
|
||||||
if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
|
if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
jtag_add_end_state(TAP_RTI);
|
jtag_add_end_state(TAP_RTI);
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0xb); /* JPROG_B */
|
virtex2_set_instr(virtex2_info->chain_pos, 0xb); /* JPROG_B */
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
jtag_add_sleep(1000);
|
jtag_add_sleep(1000);
|
||||||
|
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
|
|
||||||
for (i = 0; i < bit_file.length; i++)
|
for (i = 0; i < bit_file.length; i++)
|
||||||
bit_file.data[i] = flip_u32(bit_file.data[i], 8);
|
bit_file.data[i] = flip_u32(bit_file.data[i], 8);
|
||||||
|
|
||||||
field.num_bits = bit_file.length * 8;
|
field.num_bits = bit_file.length * 8;
|
||||||
field.out_value = bit_file.data;
|
field.out_value = bit_file.data;
|
||||||
|
|
||||||
jtag_add_dr_scan(1, &field, TAP_PD);
|
jtag_add_dr_scan(1, &field, TAP_PD);
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
|
|
||||||
jtag_add_statemove(TAP_TLR);
|
jtag_add_statemove(TAP_TLR);
|
||||||
|
|
||||||
jtag_add_end_state(TAP_RTI);
|
jtag_add_end_state(TAP_RTI);
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
||||||
jtag_add_runtest(13, TAP_RTI);
|
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, 0x3f); /* BYPASS */
|
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
virtex2_set_instr(virtex2_info->chain_pos, 0xc); /* JSTART */
|
||||||
jtag_add_runtest(13, TAP_RTI);
|
jtag_add_runtest(13, TAP_RTI);
|
||||||
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
virtex2_set_instr(virtex2_info->chain_pos, 0x3f); /* BYPASS */
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_handle_read_stat_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int virtex2_handle_read_stat_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
pld_device_t *device;
|
pld_device_t *device;
|
||||||
virtex2_pld_device_t *virtex2_info;
|
virtex2_pld_device_t *virtex2_info;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
|
command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = get_pld_device_by_num(strtoul(args[0], NULL, 0));
|
device = get_pld_device_by_num(strtoul(args[0], NULL, 0));
|
||||||
if (!device)
|
if (!device)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
|
command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtex2_info = device->driver_priv;
|
virtex2_info = device->driver_priv;
|
||||||
|
|
||||||
virtex2_read_stat(device, &status);
|
virtex2_read_stat(device, &status);
|
||||||
|
|
||||||
command_print(cmd_ctx, "virtex2 status register: 0x%8.8x", status);
|
command_print(cmd_ctx, "virtex2 status register: 0x%8.8x", status);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virtex2_register_commands(struct command_context_s *cmd_ctx)
|
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");
|
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,
|
register_command(cmd_ctx, virtex2_cmd, "read_stat", virtex2_handle_read_stat_command, COMMAND_EXEC,
|
||||||
"read Virtex-II status register");
|
"read Virtex-II status register");
|
||||||
|
|
||||||
return ERROR_OK;
|
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)
|
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;
|
virtex2_pld_device_t *virtex2_info;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
WARNING("incomplete pld device 'virtex2' configuration");
|
WARNING("incomplete pld device 'virtex2' configuration");
|
||||||
return ERROR_PLD_DEVICE_INVALID;
|
return ERROR_PLD_DEVICE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtex2_info = malloc(sizeof(virtex2_pld_device_t));
|
virtex2_info = malloc(sizeof(virtex2_pld_device_t));
|
||||||
pld_device->driver_priv = virtex2_info;
|
pld_device->driver_priv = virtex2_info;
|
||||||
|
|
||||||
virtex2_info->chain_pos = strtoul(args[1], NULL, 0);
|
virtex2_info->chain_pos = strtoul(args[1], NULL, 0);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,450 +1,450 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "replacements.h"
|
#include "replacements.h"
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "telnet_server.h"
|
#include "telnet_server.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
service_t *services = NULL;
|
service_t *services = NULL;
|
||||||
|
|
||||||
/* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
|
/* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
|
||||||
static int shutdown_openocd = 0;
|
static int shutdown_openocd = 0;
|
||||||
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
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)
|
int add_connection(service_t *service, command_context_t *cmd_ctx)
|
||||||
{
|
{
|
||||||
unsigned int address_size;
|
unsigned int address_size;
|
||||||
connection_t *c, **p;
|
connection_t *c, **p;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
c = malloc(sizeof(connection_t));
|
c = malloc(sizeof(connection_t));
|
||||||
c->fd = -1;
|
c->fd = -1;
|
||||||
memset(&c->sin, 0, sizeof(c->sin));
|
memset(&c->sin, 0, sizeof(c->sin));
|
||||||
c->cmd_ctx = copy_command_context(cmd_ctx);
|
c->cmd_ctx = copy_command_context(cmd_ctx);
|
||||||
c->service = service;
|
c->service = service;
|
||||||
c->input_pending = 0;
|
c->input_pending = 0;
|
||||||
c->priv = NULL;
|
c->priv = NULL;
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
|
|
||||||
address_size = sizeof(c->sin);
|
address_size = sizeof(c->sin);
|
||||||
c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
||||||
|
|
||||||
if ((retval = service->new_connection(c)) == ERROR_OK)
|
if ((retval = service->new_connection(c)) == ERROR_OK)
|
||||||
{
|
{
|
||||||
INFO("accepted '%s' connection from %i", service->name, c->sin.sin_port);
|
INFO("accepted '%s' connection from %i", service->name, c->sin.sin_port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
close_socket(c->fd);
|
close_socket(c->fd);
|
||||||
INFO("attempted '%s' connection rejected", service->name);
|
INFO("attempted '%s' connection rejected", service->name);
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to the end of linked list */
|
/* add to the end of linked list */
|
||||||
for (p = &service->connections; *p; p = &(*p)->next);
|
for (p = &service->connections; *p; p = &(*p)->next);
|
||||||
*p = c;
|
*p = c;
|
||||||
|
|
||||||
service->max_connections--;
|
service->max_connections--;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remove_connection(service_t *service, connection_t *connection)
|
int remove_connection(service_t *service, connection_t *connection)
|
||||||
{
|
{
|
||||||
connection_t **p = &service->connections;
|
connection_t **p = &service->connections;
|
||||||
connection_t *c;
|
connection_t *c;
|
||||||
|
|
||||||
/* find connection */
|
/* find connection */
|
||||||
while(c = *p)
|
while(c = *p)
|
||||||
{
|
{
|
||||||
if (c->fd == connection->fd)
|
if (c->fd == connection->fd)
|
||||||
{
|
{
|
||||||
service->connection_closed(c);
|
service->connection_closed(c);
|
||||||
close_socket(c->fd);
|
close_socket(c->fd);
|
||||||
command_done(c->cmd_ctx);
|
command_done(c->cmd_ctx);
|
||||||
|
|
||||||
/* delete connection */
|
/* delete connection */
|
||||||
*p = c->next;
|
*p = c->next;
|
||||||
free(c);
|
free(c);
|
||||||
|
|
||||||
service->max_connections++;
|
service->max_connections++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* redirect p to next list pointer */
|
/* redirect p to next list pointer */
|
||||||
p = &(*p)->next;
|
p = &(*p)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
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)
|
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;
|
service_t *c, **p;
|
||||||
int so_reuseaddr_option = 1;
|
int so_reuseaddr_option = 1;
|
||||||
|
|
||||||
c = malloc(sizeof(service_t));
|
c = malloc(sizeof(service_t));
|
||||||
|
|
||||||
c->name = strdup(name);
|
c->name = strdup(name);
|
||||||
c->type = type;
|
c->type = type;
|
||||||
c->port = port;
|
c->port = port;
|
||||||
c->max_connections = max_connections;
|
c->max_connections = max_connections;
|
||||||
c->fd = -1;
|
c->fd = -1;
|
||||||
c->connections = NULL;
|
c->connections = NULL;
|
||||||
c->new_connection = new_connection_handler;
|
c->new_connection = new_connection_handler;
|
||||||
c->input = input_handler;
|
c->input = input_handler;
|
||||||
c->connection_closed = connection_closed_handler;
|
c->connection_closed = connection_closed_handler;
|
||||||
c->priv = priv;
|
c->priv = priv;
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
|
|
||||||
if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||||
{
|
{
|
||||||
ERROR("error creating socket: %s", strerror(errno));
|
ERROR("error creating socket: %s", strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
|
setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
|
||||||
|
|
||||||
socket_nonblock(c->fd);
|
socket_nonblock(c->fd);
|
||||||
|
|
||||||
memset(&c->sin, 0, sizeof(c->sin));
|
memset(&c->sin, 0, sizeof(c->sin));
|
||||||
c->sin.sin_family = AF_INET;
|
c->sin.sin_family = AF_INET;
|
||||||
c->sin.sin_addr.s_addr = INADDR_ANY;
|
c->sin.sin_addr.s_addr = INADDR_ANY;
|
||||||
c->sin.sin_port = htons(port);
|
c->sin.sin_port = htons(port);
|
||||||
|
|
||||||
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
|
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
|
||||||
{
|
{
|
||||||
ERROR("couldn't bind to socket: %s", strerror(errno));
|
ERROR("couldn't bind to socket: %s", strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(c->fd, 1) == -1)
|
if (listen(c->fd, 1) == -1)
|
||||||
{
|
{
|
||||||
ERROR("couldn't listen on socket: %s", strerror(errno));
|
ERROR("couldn't listen on socket: %s", strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to the end of linked list */
|
/* add to the end of linked list */
|
||||||
for (p = &services; *p; p = &(*p)->next);
|
for (p = &services; *p; p = &(*p)->next);
|
||||||
*p = c;
|
*p = c;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remove_service(unsigned short port)
|
int remove_service(unsigned short port)
|
||||||
{
|
{
|
||||||
service_t **p = &services;
|
service_t **p = &services;
|
||||||
service_t *c;
|
service_t *c;
|
||||||
|
|
||||||
/* find service */
|
/* find service */
|
||||||
while(c = *p)
|
while(c = *p)
|
||||||
{
|
{
|
||||||
if (c->port == port)
|
if (c->port == port)
|
||||||
{
|
{
|
||||||
if (c->name)
|
if (c->name)
|
||||||
free(c->name);
|
free(c->name);
|
||||||
|
|
||||||
if (c->priv)
|
if (c->priv)
|
||||||
free(c->priv);
|
free(c->priv);
|
||||||
|
|
||||||
/* delete service */
|
/* delete service */
|
||||||
*p = c->next;
|
*p = c->next;
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* redirect p to next list pointer */
|
/* redirect p to next list pointer */
|
||||||
p = &(*p)->next;
|
p = &(*p)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remove_services()
|
int remove_services()
|
||||||
{
|
{
|
||||||
service_t *c = services;
|
service_t *c = services;
|
||||||
|
|
||||||
/* loop service */
|
/* loop service */
|
||||||
while(c)
|
while(c)
|
||||||
{
|
{
|
||||||
service_t *next = c->next;
|
service_t *next = c->next;
|
||||||
|
|
||||||
if (c->name)
|
if (c->name)
|
||||||
free(c->name);
|
free(c->name);
|
||||||
|
|
||||||
if (c->priv)
|
if (c->priv)
|
||||||
free(c->priv);
|
free(c->priv);
|
||||||
|
|
||||||
/* delete service */
|
/* delete service */
|
||||||
free(c);
|
free(c);
|
||||||
|
|
||||||
/* remember the last service for unlinking */
|
/* remember the last service for unlinking */
|
||||||
c = next;
|
c = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
services = NULL;
|
services = NULL;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int server_loop(command_context_t *command_context)
|
int server_loop(command_context_t *command_context)
|
||||||
{
|
{
|
||||||
service_t *service;
|
service_t *service;
|
||||||
|
|
||||||
/* used in select() */
|
/* used in select() */
|
||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int fd_max;
|
int fd_max;
|
||||||
|
|
||||||
/* used in accept() */
|
/* used in accept() */
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||||
ERROR("couldn't set SIGPIPE to SIG_IGN");
|
ERROR("couldn't set SIGPIPE to SIG_IGN");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* do regular tasks after at most 10ms */
|
/* do regular tasks after at most 10ms */
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 10000;
|
tv.tv_usec = 10000;
|
||||||
|
|
||||||
while(!shutdown_openocd)
|
while(!shutdown_openocd)
|
||||||
{
|
{
|
||||||
/* monitor sockets for acitvity */
|
/* monitor sockets for acitvity */
|
||||||
fd_max = 0;
|
fd_max = 0;
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
|
|
||||||
/* add service and connection fds to read_fds */
|
/* add service and connection fds to read_fds */
|
||||||
for (service = services; service; service = service->next)
|
for (service = services; service; service = service->next)
|
||||||
{
|
{
|
||||||
if (service->fd != -1)
|
if (service->fd != -1)
|
||||||
{
|
{
|
||||||
/* listen for new connections */
|
/* listen for new connections */
|
||||||
FD_SET(service->fd, &read_fds);
|
FD_SET(service->fd, &read_fds);
|
||||||
|
|
||||||
if (service->fd > fd_max)
|
if (service->fd > fd_max)
|
||||||
fd_max = service->fd;
|
fd_max = service->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service->connections)
|
if (service->connections)
|
||||||
{
|
{
|
||||||
connection_t *c;
|
connection_t *c;
|
||||||
|
|
||||||
for (c = service->connections; c; c = c->next)
|
for (c = service->connections; c; c = c->next)
|
||||||
{
|
{
|
||||||
/* check for activity on the connection */
|
/* check for activity on the connection */
|
||||||
FD_SET(c->fd, &read_fds);
|
FD_SET(c->fd, &read_fds);
|
||||||
if (c->fd > fd_max)
|
if (c->fd > fd_max)
|
||||||
fd_max = c->fd;
|
fd_max = c->fd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* add STDIN to read_fds */
|
/* add STDIN to read_fds */
|
||||||
FD_SET(fileno(stdin), &read_fds);
|
FD_SET(fileno(stdin), &read_fds);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
if (retval == -1)
|
if (retval == -1)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
|
|
||||||
if (errno == WSAEINTR)
|
if (errno == WSAEINTR)
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR("error during select: %s", strerror(errno));
|
ERROR("error during select: %s", strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
{
|
{
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR("error during select: %s", strerror(errno));
|
ERROR("error during select: %s", strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
target_call_timer_callbacks();
|
target_call_timer_callbacks();
|
||||||
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
{
|
{
|
||||||
/* do regular tasks after at most 100ms */
|
/* do regular tasks after at most 100ms */
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 10000;
|
tv.tv_usec = 10000;
|
||||||
FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */
|
FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */
|
||||||
}
|
}
|
||||||
|
|
||||||
for (service = services; service; service = service->next)
|
for (service = services; service; service = service->next)
|
||||||
{
|
{
|
||||||
/* handle new connections on listeners */
|
/* handle new connections on listeners */
|
||||||
if ((service->fd != -1)
|
if ((service->fd != -1)
|
||||||
&& (FD_ISSET(service->fd, &read_fds)))
|
&& (FD_ISSET(service->fd, &read_fds)))
|
||||||
{
|
{
|
||||||
if (service->max_connections > 0)
|
if (service->max_connections > 0)
|
||||||
{
|
{
|
||||||
add_connection(service, command_context);
|
add_connection(service, command_context);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
unsigned int address_size = sizeof(sin);
|
unsigned int address_size = sizeof(sin);
|
||||||
int tmp_fd;
|
int tmp_fd;
|
||||||
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
|
||||||
close_socket(tmp_fd);
|
close_socket(tmp_fd);
|
||||||
INFO("rejected '%s' connection, no more connections allowed", service->name);
|
INFO("rejected '%s' connection, no more connections allowed", service->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle activity on connections */
|
/* handle activity on connections */
|
||||||
if (service->connections)
|
if (service->connections)
|
||||||
{
|
{
|
||||||
connection_t *c;
|
connection_t *c;
|
||||||
|
|
||||||
for (c = service->connections; c;)
|
for (c = service->connections; c;)
|
||||||
{
|
{
|
||||||
if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
|
if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
|
||||||
{
|
{
|
||||||
if (service->input(c) != ERROR_OK)
|
if (service->input(c) != ERROR_OK)
|
||||||
{
|
{
|
||||||
connection_t *next = c->next;
|
connection_t *next = c->next;
|
||||||
remove_connection(service, c);
|
remove_connection(service, c);
|
||||||
INFO("dropped '%s' connection", service->name);
|
INFO("dropped '%s' connection", service->name);
|
||||||
c = next;
|
c = next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = c->next;
|
c = c->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (FD_ISSET(fileno(stdin), &read_fds))
|
if (FD_ISSET(fileno(stdin), &read_fds))
|
||||||
{
|
{
|
||||||
if (getc(stdin) == 'x')
|
if (getc(stdin) == 'x')
|
||||||
{
|
{
|
||||||
shutdown_openocd = 1;
|
shutdown_openocd = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
|
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
|
||||||
{
|
{
|
||||||
if (msg.message == WM_QUIT)
|
if (msg.message == WM_QUIT)
|
||||||
shutdown_openocd = 1;
|
shutdown_openocd = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
|
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
|
||||||
{
|
{
|
||||||
shutdown_openocd = 1;
|
shutdown_openocd = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sig_handler(int sig) {
|
void sig_handler(int sig) {
|
||||||
shutdown_openocd = 1;
|
shutdown_openocd = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int server_init()
|
int server_init()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WORD wVersionRequested;
|
WORD wVersionRequested;
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
|
||||||
wVersionRequested = MAKEWORD( 2, 2 );
|
wVersionRequested = MAKEWORD( 2, 2 );
|
||||||
|
|
||||||
if (WSAStartup(wVersionRequested, &wsaData) != 0)
|
if (WSAStartup(wVersionRequested, &wsaData) != 0)
|
||||||
{
|
{
|
||||||
ERROR("Failed to Open Winsock");
|
ERROR("Failed to Open Winsock");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConsoleCtrlHandler( ControlHandler, TRUE );
|
SetConsoleCtrlHandler( ControlHandler, TRUE );
|
||||||
|
|
||||||
signal(SIGINT, sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
signal(SIGTERM, sig_handler);
|
signal(SIGTERM, sig_handler);
|
||||||
signal(SIGBREAK, sig_handler);
|
signal(SIGBREAK, sig_handler);
|
||||||
signal(SIGABRT, sig_handler);
|
signal(SIGABRT, sig_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int server_quit()
|
int server_quit()
|
||||||
{
|
{
|
||||||
remove_services();
|
remove_services();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
SetConsoleCtrlHandler( ControlHandler, FALSE );
|
SetConsoleCtrlHandler( ControlHandler, FALSE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int server_register_commands(command_context_t *context)
|
int server_register_commands(command_context_t *context)
|
||||||
{
|
{
|
||||||
register_command(context, NULL, "shutdown", handle_shutdown_command,
|
register_command(context, NULL, "shutdown", handle_shutdown_command,
|
||||||
COMMAND_ANY, "shut the server down");
|
COMMAND_ANY, "shut the server down");
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tell the server we want to shut down */
|
/* tell the server we want to shut down */
|
||||||
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
shutdown_openocd = 1;
|
shutdown_openocd = 1;
|
||||||
|
|
||||||
return ERROR_COMMAND_CLOSE_CONNECTION;
|
return ERROR_COMMAND_CLOSE_CONNECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
2716
src/target/arm11.c
2716
src/target/arm11.c
File diff suppressed because it is too large
Load Diff
|
@ -1,250 +1,250 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2008 digenius technology GmbH. *
|
* Copyright (C) 2008 digenius technology GmbH. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef ARM11_H
|
#ifndef ARM11_H
|
||||||
#define ARM11_H
|
#define ARM11_H
|
||||||
|
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "embeddedice.h"
|
#include "embeddedice.h"
|
||||||
#include "arm_jtag.h"
|
#include "arm_jtag.h"
|
||||||
|
|
||||||
|
|
||||||
#define bool int
|
#define bool int
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
|
|
||||||
#define asizeof(x) (sizeof(x) / sizeof((x)[0]))
|
#define asizeof(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
#define NEW(type, variable, items) \
|
#define NEW(type, variable, items) \
|
||||||
type * variable = malloc(sizeof(type) * items)
|
type * variable = malloc(sizeof(type) * items)
|
||||||
|
|
||||||
|
|
||||||
#define ARM11_REGCACHE_MODEREGS 0
|
#define ARM11_REGCACHE_MODEREGS 0
|
||||||
#define ARM11_REGCACHE_FREGS 0
|
#define ARM11_REGCACHE_FREGS 0
|
||||||
|
|
||||||
#define ARM11_REGCACHE_COUNT (20 + \
|
#define ARM11_REGCACHE_COUNT (20 + \
|
||||||
23 * ARM11_REGCACHE_MODEREGS + \
|
23 * ARM11_REGCACHE_MODEREGS + \
|
||||||
9 * ARM11_REGCACHE_FREGS)
|
9 * ARM11_REGCACHE_FREGS)
|
||||||
|
|
||||||
|
|
||||||
typedef struct arm11_register_history_s
|
typedef struct arm11_register_history_s
|
||||||
{
|
{
|
||||||
u32 value;
|
u32 value;
|
||||||
u8 valid;
|
u8 valid;
|
||||||
}arm11_register_history_t;
|
}arm11_register_history_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct arm11_common_s
|
typedef struct arm11_common_s
|
||||||
{
|
{
|
||||||
target_t * target;
|
target_t * target;
|
||||||
|
|
||||||
arm_jtag_t jtag_info;
|
arm_jtag_t jtag_info;
|
||||||
|
|
||||||
/** \name Processor type detection */
|
/** \name Processor type detection */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
u32 device_id; /**< IDCODE readout */
|
u32 device_id; /**< IDCODE readout */
|
||||||
u32 didr; /**< DIDR readout (debug capabilities) */
|
u32 didr; /**< DIDR readout (debug capabilities) */
|
||||||
u8 implementor; /**< DIDR Implementor readout */
|
u8 implementor; /**< DIDR Implementor readout */
|
||||||
|
|
||||||
size_t brp; /**< Number of Breakpoint Register Pairs */
|
size_t brp; /**< Number of Breakpoint Register Pairs */
|
||||||
size_t wrp; /**< Number of Watchpoint Register Pairs */
|
size_t wrp; /**< Number of Watchpoint Register Pairs */
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
u32 last_dscr; /**< Last retrieved DSCR value;
|
u32 last_dscr; /**< Last retrieved DSCR value;
|
||||||
* Can be used to detect changes */
|
* Can be used to detect changes */
|
||||||
|
|
||||||
u8 trst_active;
|
u8 trst_active;
|
||||||
u8 halt_requested;
|
u8 halt_requested;
|
||||||
|
|
||||||
/** \name Shadow registers to save processor state */
|
/** \name Shadow registers to save processor state */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
reg_t * reg_list; /**< target register list */
|
reg_t * reg_list; /**< target register list */
|
||||||
u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */
|
u32 reg_values[ARM11_REGCACHE_COUNT]; /**< data for registers */
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
arm11_register_history_t
|
arm11_register_history_t
|
||||||
reg_history[ARM11_REGCACHE_COUNT]; /**< register state before last resume */
|
reg_history[ARM11_REGCACHE_COUNT]; /**< register state before last resume */
|
||||||
|
|
||||||
|
|
||||||
} arm11_common_t;
|
} arm11_common_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ARM11 DBGTAP instructions
|
* ARM11 DBGTAP instructions
|
||||||
*
|
*
|
||||||
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html
|
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html
|
||||||
*/
|
*/
|
||||||
enum arm11_instructions
|
enum arm11_instructions
|
||||||
{
|
{
|
||||||
ARM11_EXTEST = 0x00,
|
ARM11_EXTEST = 0x00,
|
||||||
ARM11_SCAN_N = 0x02,
|
ARM11_SCAN_N = 0x02,
|
||||||
ARM11_RESTART = 0x04,
|
ARM11_RESTART = 0x04,
|
||||||
ARM11_HALT = 0x08,
|
ARM11_HALT = 0x08,
|
||||||
ARM11_INTEST = 0x0C,
|
ARM11_INTEST = 0x0C,
|
||||||
ARM11_ITRSEL = 0x1D,
|
ARM11_ITRSEL = 0x1D,
|
||||||
ARM11_IDCODE = 0x1E,
|
ARM11_IDCODE = 0x1E,
|
||||||
ARM11_BYPASS = 0x1F,
|
ARM11_BYPASS = 0x1F,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum arm11_dscr
|
enum arm11_dscr
|
||||||
{
|
{
|
||||||
ARM11_DSCR_CORE_HALTED = 1 << 0,
|
ARM11_DSCR_CORE_HALTED = 1 << 0,
|
||||||
ARM11_DSCR_CORE_RESTARTED = 1 << 1,
|
ARM11_DSCR_CORE_RESTARTED = 1 << 1,
|
||||||
|
|
||||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
|
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
|
||||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 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_BREAKPOINT = 0x01 << 2,
|
||||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 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_BKPT_INSTRUCTION = 0x03 << 2,
|
||||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
|
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
|
||||||
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
|
ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
|
||||||
|
|
||||||
ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6,
|
ARM11_DSCR_STICKY_PRECISE_DATA_ABORT = 1 << 6,
|
||||||
ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7,
|
ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT = 1 << 7,
|
||||||
ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13,
|
ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE = 1 << 13,
|
||||||
ARM11_DSCR_MODE_SELECT = 1 << 14,
|
ARM11_DSCR_MODE_SELECT = 1 << 14,
|
||||||
ARM11_DSCR_WDTR_FULL = 1 << 29,
|
ARM11_DSCR_WDTR_FULL = 1 << 29,
|
||||||
ARM11_DSCR_RDTR_FULL = 1 << 30,
|
ARM11_DSCR_RDTR_FULL = 1 << 30,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum arm11_cpsr
|
enum arm11_cpsr
|
||||||
{
|
{
|
||||||
ARM11_CPSR_T = 1 << 5,
|
ARM11_CPSR_T = 1 << 5,
|
||||||
ARM11_CPSR_J = 1 << 24,
|
ARM11_CPSR_J = 1 << 24,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum arm11_sc7
|
enum arm11_sc7
|
||||||
{
|
{
|
||||||
ARM11_SC7_NULL = 0,
|
ARM11_SC7_NULL = 0,
|
||||||
ARM11_SC7_VCR = 7,
|
ARM11_SC7_VCR = 7,
|
||||||
ARM11_SC7_PC = 8,
|
ARM11_SC7_PC = 8,
|
||||||
ARM11_SC7_BVR0 = 64,
|
ARM11_SC7_BVR0 = 64,
|
||||||
ARM11_SC7_BCR0 = 80,
|
ARM11_SC7_BCR0 = 80,
|
||||||
ARM11_SC7_WVR0 = 96,
|
ARM11_SC7_WVR0 = 96,
|
||||||
ARM11_SC7_WCR0 = 112,
|
ARM11_SC7_WCR0 = 112,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct arm11_reg_state_s
|
typedef struct arm11_reg_state_s
|
||||||
{
|
{
|
||||||
u32 def_index;
|
u32 def_index;
|
||||||
target_t * target;
|
target_t * target;
|
||||||
} arm11_reg_state_t;
|
} arm11_reg_state_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* poll current target status */
|
/* poll current target status */
|
||||||
int arm11_poll(struct target_s *target);
|
int arm11_poll(struct target_s *target);
|
||||||
/* architecture specific status reply */
|
/* architecture specific status reply */
|
||||||
int arm11_arch_state(struct target_s *target);
|
int arm11_arch_state(struct target_s *target);
|
||||||
|
|
||||||
/* target request support */
|
/* target request support */
|
||||||
int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer);
|
int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer);
|
||||||
|
|
||||||
/* target execution control */
|
/* target execution control */
|
||||||
int arm11_halt(struct target_s *target);
|
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_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);
|
int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
|
||||||
|
|
||||||
/* target reset control */
|
/* target reset control */
|
||||||
int arm11_assert_reset(struct target_s *target);
|
int arm11_assert_reset(struct target_s *target);
|
||||||
int arm11_deassert_reset(struct target_s *target);
|
int arm11_deassert_reset(struct target_s *target);
|
||||||
int arm11_soft_reset_halt(struct target_s *target);
|
int arm11_soft_reset_halt(struct target_s *target);
|
||||||
int arm11_prepare_reset_halt(struct target_s *target);
|
int arm11_prepare_reset_halt(struct target_s *target);
|
||||||
|
|
||||||
/* target register access for gdb */
|
/* target register access for gdb */
|
||||||
int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
|
int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
|
||||||
|
|
||||||
/* target memory access
|
/* target memory access
|
||||||
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
|
* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
|
||||||
* count: number of items of <size>
|
* count: number of items of <size>
|
||||||
*/
|
*/
|
||||||
int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
|
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);
|
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 */
|
/* 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_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);
|
int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
|
||||||
|
|
||||||
/* target break-/watchpoint control
|
/* target break-/watchpoint control
|
||||||
* rw: 0 = write, 1 = read, 2 = access
|
* rw: 0 = write, 1 = read, 2 = access
|
||||||
*/
|
*/
|
||||||
int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
|
int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
|
||||||
int arm11_remove_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_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
|
||||||
int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
|
int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
|
||||||
|
|
||||||
/* target algorithm support */
|
/* 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_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_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_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_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
|
||||||
int arm11_quit(void);
|
int arm11_quit(void);
|
||||||
|
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
void arm11_build_reg_cache(target_t *target);
|
void arm11_build_reg_cache(target_t *target);
|
||||||
|
|
||||||
|
|
||||||
/* internals */
|
/* internals */
|
||||||
|
|
||||||
void arm11_setup_field (arm11_common_t * arm11, int num_bits, void * in_data, void * out_data, scan_field_t * field);
|
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_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_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);
|
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);
|
u32 arm11_read_DSCR (arm11_common_t * arm11);
|
||||||
void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr);
|
void arm11_write_DSCR (arm11_common_t * arm11, u32 dscr);
|
||||||
|
|
||||||
enum target_debug_reason arm11_get_DSCR_debug_reason(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_prepare (arm11_common_t * arm11);
|
||||||
void arm11_run_instr_data_finish (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_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_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_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_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 (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_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);
|
void arm11_run_instr_data_to_core_via_r0 (arm11_common_t * arm11, u32 opcode, u32 data);
|
||||||
|
|
||||||
|
|
||||||
typedef struct arm11_sc7_action_s
|
typedef struct arm11_sc7_action_s
|
||||||
{
|
{
|
||||||
bool write;
|
bool write;
|
||||||
u8 address;
|
u8 address;
|
||||||
u32 value;
|
u32 value;
|
||||||
} arm11_sc7_action_t;
|
} arm11_sc7_action_t;
|
||||||
|
|
||||||
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count);
|
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);
|
void arm11_sc7_clear_bw(arm11_common_t * arm11);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ARM11_H */
|
#endif /* ARM11_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
1252
src/target/arm720t.c
1252
src/target/arm720t.c
File diff suppressed because it is too large
Load Diff
|
@ -676,7 +676,7 @@ int arm7_9_handle_target_request(void *priv)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm7_9_poll(target_t *target)
|
int arm7_9_poll(target_t *target)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
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);
|
embeddedice_read_reg(dbg_stat);
|
||||||
if ((retval = jtag_execute_queue()) != ERROR_OK)
|
if ((retval = jtag_execute_queue()) != ERROR_OK)
|
||||||
{
|
{
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
|
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));
|
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))
|
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);
|
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
|
||||||
}
|
}
|
||||||
if (target->state != TARGET_HALTED)
|
if (target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
|
WARNING("DBGACK set, but the target did not end up in the halted stated %d", target->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (target->state != TARGET_DEBUG_RUNNING)
|
if (target->state != TARGET_DEBUG_RUNNING)
|
||||||
target->state = TARGET_RUNNING;
|
target->state = TARGET_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm7_9_assert_reset(target_t *target)
|
int arm7_9_assert_reset(target_t *target)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
2970
src/target/arm920t.c
2970
src/target/arm920t.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,364 +1,364 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "arm966e.h"
|
#include "arm966e.h"
|
||||||
|
|
||||||
#include "arm7_9_common.h"
|
#include "arm7_9_common.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "armv4_5.h"
|
#include "armv4_5.h"
|
||||||
#include "embeddedice.h"
|
#include "embeddedice.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "jtag.h"
|
#include "jtag.h"
|
||||||
#include "arm_jtag.h"
|
#include "arm_jtag.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define _DEBUG_INSTRUCTION_EXECUTION_
|
#define _DEBUG_INSTRUCTION_EXECUTION_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* cli handling */
|
/* cli handling */
|
||||||
int arm966e_register_commands(struct command_context_s *cmd_ctx);
|
int arm966e_register_commands(struct command_context_s *cmd_ctx);
|
||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
|
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_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
|
||||||
int arm966e_quit(void);
|
int arm966e_quit(void);
|
||||||
|
|
||||||
target_type_t arm966e_target =
|
target_type_t arm966e_target =
|
||||||
{
|
{
|
||||||
.name = "arm966e",
|
.name = "arm966e",
|
||||||
|
|
||||||
.poll = arm7_9_poll,
|
.poll = arm7_9_poll,
|
||||||
.arch_state = armv4_5_arch_state,
|
.arch_state = armv4_5_arch_state,
|
||||||
|
|
||||||
.target_request_data = arm7_9_target_request_data,
|
.target_request_data = arm7_9_target_request_data,
|
||||||
|
|
||||||
.halt = arm7_9_halt,
|
.halt = arm7_9_halt,
|
||||||
.resume = arm7_9_resume,
|
.resume = arm7_9_resume,
|
||||||
.step = arm7_9_step,
|
.step = arm7_9_step,
|
||||||
|
|
||||||
.assert_reset = arm7_9_assert_reset,
|
.assert_reset = arm7_9_assert_reset,
|
||||||
.deassert_reset = arm7_9_deassert_reset,
|
.deassert_reset = arm7_9_deassert_reset,
|
||||||
.soft_reset_halt = arm7_9_soft_reset_halt,
|
.soft_reset_halt = arm7_9_soft_reset_halt,
|
||||||
.prepare_reset_halt = arm7_9_prepare_reset_halt,
|
.prepare_reset_halt = arm7_9_prepare_reset_halt,
|
||||||
|
|
||||||
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
|
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
|
||||||
|
|
||||||
.read_memory = arm7_9_read_memory,
|
.read_memory = arm7_9_read_memory,
|
||||||
.write_memory = arm7_9_write_memory,
|
.write_memory = arm7_9_write_memory,
|
||||||
.bulk_write_memory = arm7_9_bulk_write_memory,
|
.bulk_write_memory = arm7_9_bulk_write_memory,
|
||||||
.checksum_memory = arm7_9_checksum_memory,
|
.checksum_memory = arm7_9_checksum_memory,
|
||||||
|
|
||||||
.run_algorithm = armv4_5_run_algorithm,
|
.run_algorithm = armv4_5_run_algorithm,
|
||||||
|
|
||||||
.add_breakpoint = arm7_9_add_breakpoint,
|
.add_breakpoint = arm7_9_add_breakpoint,
|
||||||
.remove_breakpoint = arm7_9_remove_breakpoint,
|
.remove_breakpoint = arm7_9_remove_breakpoint,
|
||||||
.add_watchpoint = arm7_9_add_watchpoint,
|
.add_watchpoint = arm7_9_add_watchpoint,
|
||||||
.remove_watchpoint = arm7_9_remove_watchpoint,
|
.remove_watchpoint = arm7_9_remove_watchpoint,
|
||||||
|
|
||||||
.register_commands = arm966e_register_commands,
|
.register_commands = arm966e_register_commands,
|
||||||
.target_command = arm966e_target_command,
|
.target_command = arm966e_target_command,
|
||||||
.init_target = arm966e_init_target,
|
.init_target = arm966e_init_target,
|
||||||
.quit = arm966e_quit,
|
.quit = arm966e_quit,
|
||||||
};
|
};
|
||||||
|
|
||||||
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
|
int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
|
||||||
{
|
{
|
||||||
arm9tdmi_init_target(cmd_ctx, target);
|
arm9tdmi_init_target(cmd_ctx, target);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_quit(void)
|
int arm966e_quit(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
|
int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
|
||||||
{
|
{
|
||||||
arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
|
arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
|
||||||
arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
|
arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
|
||||||
|
|
||||||
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
|
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
|
||||||
|
|
||||||
arm9tdmi->arch_info = arm966e;
|
arm9tdmi->arch_info = arm966e;
|
||||||
arm966e->common_magic = ARM966E_COMMON_MAGIC;
|
arm966e->common_magic = ARM966E_COMMON_MAGIC;
|
||||||
|
|
||||||
/* The ARM966E-S implements the ARMv5TE architecture which
|
/* The ARM966E-S implements the ARMv5TE architecture which
|
||||||
* has the BKPT instruction, so we don't have to use a watchpoint comparator
|
* has the BKPT instruction, so we don't have to use a watchpoint comparator
|
||||||
*/
|
*/
|
||||||
arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
|
arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
|
||||||
arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
|
arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
|
||||||
|
|
||||||
arm7_9->sw_bkpts_use_wp = 0;
|
arm7_9->sw_bkpts_use_wp = 0;
|
||||||
arm7_9->sw_bkpts_enabled = 1;
|
arm7_9->sw_bkpts_enabled = 1;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
|
int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
|
||||||
{
|
{
|
||||||
int chain_pos;
|
int chain_pos;
|
||||||
char *variant = NULL;
|
char *variant = NULL;
|
||||||
arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
|
arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
|
||||||
|
|
||||||
if (argc < 4)
|
if (argc < 4)
|
||||||
{
|
{
|
||||||
ERROR("'target arm966e' requires at least one additional argument");
|
ERROR("'target arm966e' requires at least one additional argument");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
chain_pos = strtoul(args[3], NULL, 0);
|
chain_pos = strtoul(args[3], NULL, 0);
|
||||||
|
|
||||||
if (argc >= 5)
|
if (argc >= 5)
|
||||||
variant = args[4];
|
variant = args[4];
|
||||||
|
|
||||||
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
|
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
|
||||||
|
|
||||||
arm966e_init_arch_info(target, arm966e, chain_pos, variant);
|
arm966e_init_arch_info(target, arm966e, chain_pos, variant);
|
||||||
|
|
||||||
return ERROR_OK;
|
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)
|
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;
|
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||||
arm7_9_common_t *arm7_9;
|
arm7_9_common_t *arm7_9;
|
||||||
arm9tdmi_common_t *arm9tdmi;
|
arm9tdmi_common_t *arm9tdmi;
|
||||||
arm966e_common_t *arm966e;
|
arm966e_common_t *arm966e;
|
||||||
|
|
||||||
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
|
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
arm7_9 = armv4_5->arch_info;
|
arm7_9 = armv4_5->arch_info;
|
||||||
if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
|
if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
arm9tdmi = arm7_9->arch_info;
|
arm9tdmi = arm7_9->arch_info;
|
||||||
if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
|
if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
arm966e = arm9tdmi->arch_info;
|
arm966e = arm9tdmi->arch_info;
|
||||||
if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
|
if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*armv4_5_p = armv4_5;
|
*armv4_5_p = armv4_5;
|
||||||
*arm7_9_p = arm7_9;
|
*arm7_9_p = arm7_9;
|
||||||
*arm9tdmi_p = arm9tdmi;
|
*arm9tdmi_p = arm9tdmi;
|
||||||
*arm966e_p = arm966e;
|
*arm966e_p = arm966e;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
|
int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
|
||||||
{
|
{
|
||||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||||
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
||||||
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
||||||
scan_field_t fields[3];
|
scan_field_t fields[3];
|
||||||
u8 reg_addr_buf = reg_addr & 0x3f;
|
u8 reg_addr_buf = reg_addr & 0x3f;
|
||||||
u8 nr_w_buf = 0;
|
u8 nr_w_buf = 0;
|
||||||
|
|
||||||
jtag_add_end_state(TAP_RTI);
|
jtag_add_end_state(TAP_RTI);
|
||||||
arm_jtag_scann(jtag_info, 0xf);
|
arm_jtag_scann(jtag_info, 0xf);
|
||||||
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
||||||
|
|
||||||
fields[0].device = jtag_info->chain_pos;
|
fields[0].device = jtag_info->chain_pos;
|
||||||
fields[0].num_bits = 32;
|
fields[0].num_bits = 32;
|
||||||
fields[0].out_value = NULL;
|
fields[0].out_value = NULL;
|
||||||
fields[0].out_mask = NULL;
|
fields[0].out_mask = NULL;
|
||||||
fields[0].in_value = NULL;
|
fields[0].in_value = NULL;
|
||||||
fields[0].in_check_value = NULL;
|
fields[0].in_check_value = NULL;
|
||||||
fields[0].in_check_mask = NULL;
|
fields[0].in_check_mask = NULL;
|
||||||
fields[0].in_handler = NULL;
|
fields[0].in_handler = NULL;
|
||||||
fields[0].in_handler_priv = NULL;
|
fields[0].in_handler_priv = NULL;
|
||||||
|
|
||||||
fields[1].device = jtag_info->chain_pos;
|
fields[1].device = jtag_info->chain_pos;
|
||||||
fields[1].num_bits = 6;
|
fields[1].num_bits = 6;
|
||||||
fields[1].out_value = ®_addr_buf;
|
fields[1].out_value = ®_addr_buf;
|
||||||
fields[1].out_mask = NULL;
|
fields[1].out_mask = NULL;
|
||||||
fields[1].in_value = NULL;
|
fields[1].in_value = NULL;
|
||||||
fields[1].in_check_value = NULL;
|
fields[1].in_check_value = NULL;
|
||||||
fields[1].in_check_mask = NULL;
|
fields[1].in_check_mask = NULL;
|
||||||
fields[1].in_handler = NULL;
|
fields[1].in_handler = NULL;
|
||||||
fields[1].in_handler_priv = NULL;
|
fields[1].in_handler_priv = NULL;
|
||||||
|
|
||||||
fields[2].device = jtag_info->chain_pos;
|
fields[2].device = jtag_info->chain_pos;
|
||||||
fields[2].num_bits = 1;
|
fields[2].num_bits = 1;
|
||||||
fields[2].out_value = &nr_w_buf;
|
fields[2].out_value = &nr_w_buf;
|
||||||
fields[2].out_mask = NULL;
|
fields[2].out_mask = NULL;
|
||||||
fields[2].in_value = NULL;
|
fields[2].in_value = NULL;
|
||||||
fields[2].in_check_value = NULL;
|
fields[2].in_check_value = NULL;
|
||||||
fields[2].in_check_mask = NULL;
|
fields[2].in_check_mask = NULL;
|
||||||
fields[2].in_handler = NULL;
|
fields[2].in_handler = NULL;
|
||||||
fields[2].in_handler_priv = NULL;
|
fields[2].in_handler_priv = NULL;
|
||||||
|
|
||||||
jtag_add_dr_scan(3, fields, -1);
|
jtag_add_dr_scan(3, fields, -1);
|
||||||
|
|
||||||
fields[0].in_handler_priv = value;
|
fields[0].in_handler_priv = value;
|
||||||
fields[0].in_handler = arm_jtag_buf_to_u32;
|
fields[0].in_handler = arm_jtag_buf_to_u32;
|
||||||
|
|
||||||
jtag_add_dr_scan(3, fields, -1);
|
jtag_add_dr_scan(3, fields, -1);
|
||||||
|
|
||||||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
|
DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
|
int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
|
||||||
{
|
{
|
||||||
armv4_5_common_t *armv4_5 = target->arch_info;
|
armv4_5_common_t *armv4_5 = target->arch_info;
|
||||||
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
|
||||||
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
|
||||||
scan_field_t fields[3];
|
scan_field_t fields[3];
|
||||||
u8 reg_addr_buf = reg_addr & 0x3f;
|
u8 reg_addr_buf = reg_addr & 0x3f;
|
||||||
u8 nr_w_buf = 1;
|
u8 nr_w_buf = 1;
|
||||||
u8 value_buf[4];
|
u8 value_buf[4];
|
||||||
|
|
||||||
buf_set_u32(value_buf, 0, 32, value);
|
buf_set_u32(value_buf, 0, 32, value);
|
||||||
|
|
||||||
jtag_add_end_state(TAP_RTI);
|
jtag_add_end_state(TAP_RTI);
|
||||||
arm_jtag_scann(jtag_info, 0xf);
|
arm_jtag_scann(jtag_info, 0xf);
|
||||||
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
|
||||||
|
|
||||||
fields[0].device = jtag_info->chain_pos;
|
fields[0].device = jtag_info->chain_pos;
|
||||||
fields[0].num_bits = 32;
|
fields[0].num_bits = 32;
|
||||||
fields[0].out_value = value_buf;
|
fields[0].out_value = value_buf;
|
||||||
fields[0].out_mask = NULL;
|
fields[0].out_mask = NULL;
|
||||||
fields[0].in_value = NULL;
|
fields[0].in_value = NULL;
|
||||||
fields[0].in_check_value = NULL;
|
fields[0].in_check_value = NULL;
|
||||||
fields[0].in_check_mask = NULL;
|
fields[0].in_check_mask = NULL;
|
||||||
fields[0].in_handler = NULL;
|
fields[0].in_handler = NULL;
|
||||||
fields[0].in_handler_priv = NULL;
|
fields[0].in_handler_priv = NULL;
|
||||||
|
|
||||||
fields[1].device = jtag_info->chain_pos;
|
fields[1].device = jtag_info->chain_pos;
|
||||||
fields[1].num_bits = 6;
|
fields[1].num_bits = 6;
|
||||||
fields[1].out_value = ®_addr_buf;
|
fields[1].out_value = ®_addr_buf;
|
||||||
fields[1].out_mask = NULL;
|
fields[1].out_mask = NULL;
|
||||||
fields[1].in_value = NULL;
|
fields[1].in_value = NULL;
|
||||||
fields[1].in_check_value = NULL;
|
fields[1].in_check_value = NULL;
|
||||||
fields[1].in_check_mask = NULL;
|
fields[1].in_check_mask = NULL;
|
||||||
fields[1].in_handler = NULL;
|
fields[1].in_handler = NULL;
|
||||||
fields[1].in_handler_priv = NULL;
|
fields[1].in_handler_priv = NULL;
|
||||||
|
|
||||||
fields[2].device = jtag_info->chain_pos;
|
fields[2].device = jtag_info->chain_pos;
|
||||||
fields[2].num_bits = 1;
|
fields[2].num_bits = 1;
|
||||||
fields[2].out_value = &nr_w_buf;
|
fields[2].out_value = &nr_w_buf;
|
||||||
fields[2].out_mask = NULL;
|
fields[2].out_mask = NULL;
|
||||||
fields[2].in_value = NULL;
|
fields[2].in_value = NULL;
|
||||||
fields[2].in_check_value = NULL;
|
fields[2].in_check_value = NULL;
|
||||||
fields[2].in_check_mask = NULL;
|
fields[2].in_check_mask = NULL;
|
||||||
fields[2].in_handler = NULL;
|
fields[2].in_handler = NULL;
|
||||||
fields[2].in_handler_priv = NULL;
|
fields[2].in_handler_priv = NULL;
|
||||||
|
|
||||||
jtag_add_dr_scan(3, fields, -1);
|
jtag_add_dr_scan(3, fields, -1);
|
||||||
|
|
||||||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
|
||||||
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
|
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
target_t *target = get_current_target(cmd_ctx);
|
target_t *target = get_current_target(cmd_ctx);
|
||||||
armv4_5_common_t *armv4_5;
|
armv4_5_common_t *armv4_5;
|
||||||
arm7_9_common_t *arm7_9;
|
arm7_9_common_t *arm7_9;
|
||||||
arm9tdmi_common_t *arm9tdmi;
|
arm9tdmi_common_t *arm9tdmi;
|
||||||
arm966e_common_t *arm966e;
|
arm966e_common_t *arm966e;
|
||||||
arm_jtag_t *jtag_info;
|
arm_jtag_t *jtag_info;
|
||||||
|
|
||||||
if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
|
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");
|
command_print(cmd_ctx, "current target isn't an ARM966e target");
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
jtag_info = &arm7_9->jtag_info;
|
jtag_info = &arm7_9->jtag_info;
|
||||||
|
|
||||||
if (target->state != TARGET_HALTED)
|
if (target->state != TARGET_HALTED)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
|
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* one or more argument, access a single register (write if second argument is given */
|
/* one or more argument, access a single register (write if second argument is given */
|
||||||
if (argc >= 1)
|
if (argc >= 1)
|
||||||
{
|
{
|
||||||
int address = strtoul(args[0], NULL, 0);
|
int address = strtoul(args[0], NULL, 0);
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
u32 value;
|
u32 value;
|
||||||
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
|
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "couldn't access reg %i", address);
|
command_print(cmd_ctx, "couldn't access reg %i", address);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
jtag_execute_queue();
|
jtag_execute_queue();
|
||||||
|
|
||||||
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
||||||
}
|
}
|
||||||
else if (argc == 2)
|
else if (argc == 2)
|
||||||
{
|
{
|
||||||
u32 value = strtoul(args[1], NULL, 0);
|
u32 value = strtoul(args[1], NULL, 0);
|
||||||
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
|
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "couldn't access reg %i", address);
|
command_print(cmd_ctx, "couldn't access reg %i", address);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
command_print(cmd_ctx, "%i: %8.8x", address, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm966e_register_commands(struct command_context_s *cmd_ctx)
|
int arm966e_register_commands(struct command_context_s *cmd_ctx)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
command_t *arm966e_cmd;
|
command_t *arm966e_cmd;
|
||||||
|
|
||||||
retval = arm9tdmi_register_commands(cmd_ctx);
|
retval = arm9tdmi_register_commands(cmd_ctx);
|
||||||
arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
|
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]");
|
register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,207 +1,207 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Dominic Rath *
|
* Copyright (C) 2005 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "arm_jtag.h"
|
#include "arm_jtag.h"
|
||||||
|
|
||||||
#include "binarybuffer.h"
|
#include "binarybuffer.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "jtag.h"
|
#include "jtag.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define _ARM_JTAG_SCAN_N_CHECK_
|
#define _ARM_JTAG_SCAN_N_CHECK_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, in_handler_t handler)
|
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);
|
jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);
|
||||||
|
|
||||||
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
|
||||||
{
|
{
|
||||||
scan_field_t field;
|
scan_field_t field;
|
||||||
|
|
||||||
field.device = jtag_info->chain_pos;
|
field.device = jtag_info->chain_pos;
|
||||||
field.num_bits = device->ir_length;
|
field.num_bits = device->ir_length;
|
||||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||||
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
|
||||||
field.out_mask = NULL;
|
field.out_mask = NULL;
|
||||||
field.in_value = NULL;
|
field.in_value = NULL;
|
||||||
field.in_check_value = NULL;
|
field.in_check_value = NULL;
|
||||||
field.in_check_mask = NULL;
|
field.in_check_mask = NULL;
|
||||||
field.in_handler = handler;
|
field.in_handler = handler;
|
||||||
field.in_handler_priv = NULL;
|
field.in_handler_priv = NULL;
|
||||||
jtag_add_ir_scan(1, &field, -1);
|
jtag_add_ir_scan(1, &field, -1);
|
||||||
|
|
||||||
|
|
||||||
free(field.out_value);
|
free(field.out_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
|
int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
|
||||||
{
|
{
|
||||||
if(jtag_info->cur_scan_chain != new_scan_chain)
|
if(jtag_info->cur_scan_chain != new_scan_chain)
|
||||||
{
|
{
|
||||||
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
||||||
u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);
|
u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);
|
||||||
#endif
|
#endif
|
||||||
scan_field_t field;
|
scan_field_t field;
|
||||||
|
|
||||||
field.device = jtag_info->chain_pos;
|
field.device = jtag_info->chain_pos;
|
||||||
field.num_bits = jtag_info->scann_size;
|
field.num_bits = jtag_info->scann_size;
|
||||||
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
field.out_value = calloc(CEIL(field.num_bits, 8), 1);
|
||||||
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
|
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
|
||||||
field.out_mask = NULL;
|
field.out_mask = NULL;
|
||||||
field.in_value = NULL;
|
field.in_value = NULL;
|
||||||
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
#ifdef _ARM_JTAG_SCAN_N_CHECK_
|
||||||
jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);
|
jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
field.in_handler = NULL;
|
field.in_handler = NULL;
|
||||||
field.in_handler_priv = NULL;
|
field.in_handler_priv = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
|
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
|
||||||
jtag_add_dr_scan(1, &field, -1);
|
jtag_add_dr_scan(1, &field, -1);
|
||||||
|
|
||||||
jtag_info->cur_scan_chain = new_scan_chain;
|
jtag_info->cur_scan_chain = new_scan_chain;
|
||||||
|
|
||||||
free(field.out_value);
|
free(field.out_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm_jtag_reset_callback(enum jtag_event event, void *priv)
|
int arm_jtag_reset_callback(enum jtag_event event, void *priv)
|
||||||
{
|
{
|
||||||
arm_jtag_t *jtag_info = priv;
|
arm_jtag_t *jtag_info = priv;
|
||||||
|
|
||||||
if (event == JTAG_TRST_ASSERTED)
|
if (event == JTAG_TRST_ASSERTED)
|
||||||
{
|
{
|
||||||
jtag_info->cur_scan_chain = 0;
|
jtag_info->cur_scan_chain = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm_jtag_setup_connection(arm_jtag_t *jtag_info)
|
int arm_jtag_setup_connection(arm_jtag_t *jtag_info)
|
||||||
{
|
{
|
||||||
jtag_info->scann_instr = 0x2;
|
jtag_info->scann_instr = 0x2;
|
||||||
jtag_info->cur_scan_chain = 0;
|
jtag_info->cur_scan_chain = 0;
|
||||||
jtag_info->intest_instr = 0xc;
|
jtag_info->intest_instr = 0xc;
|
||||||
|
|
||||||
jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);
|
jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into host-endian u32, flipping bit-order */
|
/* 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)
|
int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||||
{
|
{
|
||||||
u32 *dest = priv;
|
u32 *dest = priv;
|
||||||
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
*dest = flip_u32(le_to_h_u32(in_buf), 32);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into little-endian u32, flipping bit-order */
|
/* 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)
|
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));
|
h_u32_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into little-endian u16, flipping bit-order */
|
/* 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)
|
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);
|
h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into big-endian u32, flipping bit-order */
|
/* 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)
|
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));
|
h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into big-endian u16, flipping bit-order */
|
/* 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)
|
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);
|
h_u16_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into u8, flipping bit-order */
|
/* 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)
|
int arm_jtag_buf_to_8_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||||
{
|
{
|
||||||
u8 *dest = priv;
|
u8 *dest = priv;
|
||||||
*dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;
|
*dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not-flipping variants */
|
/* not-flipping variants */
|
||||||
/* read JTAG buffer into host-endian u32 */
|
/* read JTAG buffer into host-endian u32 */
|
||||||
int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||||
{
|
{
|
||||||
u32 *dest = priv;
|
u32 *dest = priv;
|
||||||
*dest = le_to_h_u32(in_buf);
|
*dest = le_to_h_u32(in_buf);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into little-endian u32 */
|
/* read JTAG buffer into little-endian u32 */
|
||||||
int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
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));
|
h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into little-endian u16 */
|
/* read JTAG buffer into little-endian u16 */
|
||||||
int arm_jtag_buf_to_le16(u8 *in_buf, void *priv, struct scan_field_s *field)
|
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);
|
h_u16_to_le(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into big-endian u32 */
|
/* read JTAG buffer into big-endian u32 */
|
||||||
int arm_jtag_buf_to_be32(u8 *in_buf, void *priv, struct scan_field_s *field)
|
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));
|
h_u32_to_be(((u8*)priv), le_to_h_u32(in_buf));
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into big-endian u16 */
|
/* read JTAG buffer into big-endian u16 */
|
||||||
int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)
|
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);
|
h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read JTAG buffer into u8 */
|
/* read JTAG buffer into u8 */
|
||||||
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
|
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
|
||||||
{
|
{
|
||||||
u8 *dest = priv;
|
u8 *dest = priv;
|
||||||
*dest = le_to_h_u32(in_buf) & 0xff;
|
*dest = le_to_h_u32(in_buf) & 0xff;
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1482
src/target/etb.c
1482
src/target/etb.c
File diff suppressed because it is too large
Load Diff
150
src/target/etb.h
150
src/target/etb.h
|
@ -1,75 +1,75 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Dominic Rath *
|
* Copyright (C) 2007 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef ETB_H
|
#ifndef ETB_H
|
||||||
#define ETB_H
|
#define ETB_H
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "arm_jtag.h"
|
#include "arm_jtag.h"
|
||||||
|
|
||||||
#include "etb.h"
|
#include "etb.h"
|
||||||
#include "etm.h"
|
#include "etm.h"
|
||||||
|
|
||||||
/* ETB registers */
|
/* ETB registers */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ETB_ID = 0x00,
|
ETB_ID = 0x00,
|
||||||
ETB_RAM_DEPTH = 0x01,
|
ETB_RAM_DEPTH = 0x01,
|
||||||
ETB_RAM_WIDTH = 0x02,
|
ETB_RAM_WIDTH = 0x02,
|
||||||
ETB_STATUS = 0x03,
|
ETB_STATUS = 0x03,
|
||||||
ETB_RAM_DATA = 0x04,
|
ETB_RAM_DATA = 0x04,
|
||||||
ETB_RAM_READ_POINTER = 0x05,
|
ETB_RAM_READ_POINTER = 0x05,
|
||||||
ETB_RAM_WRITE_POINTER = 0x06,
|
ETB_RAM_WRITE_POINTER = 0x06,
|
||||||
ETB_TRIGGER_COUNTER = 0x07,
|
ETB_TRIGGER_COUNTER = 0x07,
|
||||||
ETB_CTRL = 0x08,
|
ETB_CTRL = 0x08,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct etb_s
|
typedef struct etb_s
|
||||||
{
|
{
|
||||||
etm_context_t *etm_ctx;
|
etm_context_t *etm_ctx;
|
||||||
int chain_pos;
|
int chain_pos;
|
||||||
int cur_scan_chain;
|
int cur_scan_chain;
|
||||||
reg_cache_t *reg_cache;
|
reg_cache_t *reg_cache;
|
||||||
|
|
||||||
/* ETB parameters */
|
/* ETB parameters */
|
||||||
int ram_depth;
|
int ram_depth;
|
||||||
int ram_width;
|
int ram_width;
|
||||||
} etb_t;
|
} etb_t;
|
||||||
|
|
||||||
typedef struct etb_reg_s
|
typedef struct etb_reg_s
|
||||||
{
|
{
|
||||||
int addr;
|
int addr;
|
||||||
etb_t *etb;
|
etb_t *etb;
|
||||||
} etb_reg_t;
|
} etb_reg_t;
|
||||||
|
|
||||||
extern etm_capture_driver_t etb_capture_driver;
|
extern etm_capture_driver_t etb_capture_driver;
|
||||||
|
|
||||||
extern reg_cache_t* etb_build_reg_cache(etb_t *etb);
|
extern reg_cache_t* etb_build_reg_cache(etb_t *etb);
|
||||||
extern int etb_read_reg(reg_t *reg);
|
extern int etb_read_reg(reg_t *reg);
|
||||||
extern int etb_write_reg(reg_t *reg, u32 value);
|
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_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
|
||||||
extern int etb_store_reg(reg_t *reg);
|
extern int etb_store_reg(reg_t *reg);
|
||||||
extern int etb_set_reg(reg_t *reg, u32 value);
|
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_set_reg_w_exec(reg_t *reg, u8 *buf);
|
||||||
|
|
||||||
extern int etb_register_commands(struct command_context_s *cmd_ctx);
|
extern int etb_register_commands(struct command_context_s *cmd_ctx);
|
||||||
|
|
||||||
#endif /* ETB_H */
|
#endif /* ETB_H */
|
||||||
|
|
3726
src/target/etm.c
3726
src/target/etm.c
File diff suppressed because it is too large
Load Diff
428
src/target/etm.h
428
src/target/etm.h
|
@ -1,214 +1,214 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005, 2007 by Dominic Rath *
|
* Copyright (C) 2005, 2007 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2007 by Vincent Palatin *
|
* Copyright (C) 2007 by Vincent Palatin *
|
||||||
* vincent.palatin_openocd@m4x.org *
|
* vincent.palatin_openocd@m4x.org *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef ETM_H
|
#ifndef ETM_H
|
||||||
#define ETM_H
|
#define ETM_H
|
||||||
|
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "arm_jtag.h"
|
#include "arm_jtag.h"
|
||||||
|
|
||||||
#include "armv4_5.h"
|
#include "armv4_5.h"
|
||||||
|
|
||||||
/* ETM registers (V1.3 protocol) */
|
/* ETM registers (V1.3 protocol) */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ETM_CTRL = 0x00,
|
ETM_CTRL = 0x00,
|
||||||
ETM_CONFIG = 0x01,
|
ETM_CONFIG = 0x01,
|
||||||
ETM_TRIG_EVENT = 0x02,
|
ETM_TRIG_EVENT = 0x02,
|
||||||
ETM_MMD_CTRL = 0x03,
|
ETM_MMD_CTRL = 0x03,
|
||||||
ETM_STATUS = 0x04,
|
ETM_STATUS = 0x04,
|
||||||
ETM_SYS_CONFIG = 0x05,
|
ETM_SYS_CONFIG = 0x05,
|
||||||
ETM_TRACE_RESOURCE_CTRL = 0x06,
|
ETM_TRACE_RESOURCE_CTRL = 0x06,
|
||||||
ETM_TRACE_EN_CTRL2 = 0x07,
|
ETM_TRACE_EN_CTRL2 = 0x07,
|
||||||
ETM_TRACE_EN_EVENT = 0x08,
|
ETM_TRACE_EN_EVENT = 0x08,
|
||||||
ETM_TRACE_EN_CTRL1 = 0x09,
|
ETM_TRACE_EN_CTRL1 = 0x09,
|
||||||
ETM_FIFOFULL_REGION = 0x0a,
|
ETM_FIFOFULL_REGION = 0x0a,
|
||||||
ETM_FIFOFULL_LEVEL = 0x0b,
|
ETM_FIFOFULL_LEVEL = 0x0b,
|
||||||
ETM_VIEWDATA_EVENT = 0x0c,
|
ETM_VIEWDATA_EVENT = 0x0c,
|
||||||
ETM_VIEWDATA_CTRL1 = 0x0d,
|
ETM_VIEWDATA_CTRL1 = 0x0d,
|
||||||
ETM_VIEWDATA_CTRL2 = 0x0e,
|
ETM_VIEWDATA_CTRL2 = 0x0e,
|
||||||
ETM_VIEWDATA_CTRL3 = 0x0f,
|
ETM_VIEWDATA_CTRL3 = 0x0f,
|
||||||
ETM_ADDR_COMPARATOR_VALUE = 0x10,
|
ETM_ADDR_COMPARATOR_VALUE = 0x10,
|
||||||
ETM_ADDR_ACCESS_TYPE = 0x20,
|
ETM_ADDR_ACCESS_TYPE = 0x20,
|
||||||
ETM_DATA_COMPARATOR_VALUE = 0x30,
|
ETM_DATA_COMPARATOR_VALUE = 0x30,
|
||||||
ETM_DATA_COMPARATOR_MASK = 0x40,
|
ETM_DATA_COMPARATOR_MASK = 0x40,
|
||||||
ETM_COUNTER_INITAL_VALUE = 0x50,
|
ETM_COUNTER_INITAL_VALUE = 0x50,
|
||||||
ETM_COUNTER_ENABLE = 0x54,
|
ETM_COUNTER_ENABLE = 0x54,
|
||||||
ETM_COUNTER_RELOAD_VALUE = 0x58,
|
ETM_COUNTER_RELOAD_VALUE = 0x58,
|
||||||
ETM_COUNTER_VALUE = 0x5c,
|
ETM_COUNTER_VALUE = 0x5c,
|
||||||
ETM_SEQUENCER_CTRL = 0x60,
|
ETM_SEQUENCER_CTRL = 0x60,
|
||||||
ETM_SEQUENCER_STATE = 0x67,
|
ETM_SEQUENCER_STATE = 0x67,
|
||||||
ETM_EXTERNAL_OUTPUT = 0x68,
|
ETM_EXTERNAL_OUTPUT = 0x68,
|
||||||
ETM_CONTEXTID_COMPARATOR_VALUE = 0x6c,
|
ETM_CONTEXTID_COMPARATOR_VALUE = 0x6c,
|
||||||
ETM_CONTEXTID_COMPARATOR_MASK = 0x6f,
|
ETM_CONTEXTID_COMPARATOR_MASK = 0x6f,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct etm_reg_s
|
typedef struct etm_reg_s
|
||||||
{
|
{
|
||||||
int addr;
|
int addr;
|
||||||
arm_jtag_t *jtag_info;
|
arm_jtag_t *jtag_info;
|
||||||
} etm_reg_t;
|
} etm_reg_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
/* Port width */
|
/* Port width */
|
||||||
ETM_PORT_4BIT = 0x00,
|
ETM_PORT_4BIT = 0x00,
|
||||||
ETM_PORT_8BIT = 0x10,
|
ETM_PORT_8BIT = 0x10,
|
||||||
ETM_PORT_16BIT = 0x20,
|
ETM_PORT_16BIT = 0x20,
|
||||||
ETM_PORT_WIDTH_MASK = 0x70,
|
ETM_PORT_WIDTH_MASK = 0x70,
|
||||||
/* Port modes */
|
/* Port modes */
|
||||||
ETM_PORT_NORMAL = 0x00000,
|
ETM_PORT_NORMAL = 0x00000,
|
||||||
ETM_PORT_MUXED = 0x10000,
|
ETM_PORT_MUXED = 0x10000,
|
||||||
ETM_PORT_DEMUXED = 0x20000,
|
ETM_PORT_DEMUXED = 0x20000,
|
||||||
ETM_PORT_MODE_MASK = 0x30000,
|
ETM_PORT_MODE_MASK = 0x30000,
|
||||||
/* Clocking modes */
|
/* Clocking modes */
|
||||||
ETM_PORT_FULL_CLOCK = 0x0000,
|
ETM_PORT_FULL_CLOCK = 0x0000,
|
||||||
ETM_PORT_HALF_CLOCK = 0x1000,
|
ETM_PORT_HALF_CLOCK = 0x1000,
|
||||||
ETM_PORT_CLOCK_MASK = 0x1000,
|
ETM_PORT_CLOCK_MASK = 0x1000,
|
||||||
} etm_portmode_t;
|
} etm_portmode_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
/* Data trace */
|
/* Data trace */
|
||||||
ETMV1_TRACE_NONE = 0x00,
|
ETMV1_TRACE_NONE = 0x00,
|
||||||
ETMV1_TRACE_DATA = 0x01,
|
ETMV1_TRACE_DATA = 0x01,
|
||||||
ETMV1_TRACE_ADDR = 0x02,
|
ETMV1_TRACE_ADDR = 0x02,
|
||||||
ETMV1_TRACE_MASK = 0x03,
|
ETMV1_TRACE_MASK = 0x03,
|
||||||
/* ContextID */
|
/* ContextID */
|
||||||
ETMV1_CONTEXTID_NONE = 0x00,
|
ETMV1_CONTEXTID_NONE = 0x00,
|
||||||
ETMV1_CONTEXTID_8 = 0x10,
|
ETMV1_CONTEXTID_8 = 0x10,
|
||||||
ETMV1_CONTEXTID_16 = 0x20,
|
ETMV1_CONTEXTID_16 = 0x20,
|
||||||
ETMV1_CONTEXTID_32 = 0x30,
|
ETMV1_CONTEXTID_32 = 0x30,
|
||||||
ETMV1_CONTEXTID_MASK = 0x30,
|
ETMV1_CONTEXTID_MASK = 0x30,
|
||||||
/* Misc */
|
/* Misc */
|
||||||
ETMV1_CYCLE_ACCURATE = 0x100,
|
ETMV1_CYCLE_ACCURATE = 0x100,
|
||||||
ETMV1_BRANCH_OUTPUT = 0x200
|
ETMV1_BRANCH_OUTPUT = 0x200
|
||||||
} etmv1_tracemode_t;
|
} etmv1_tracemode_t;
|
||||||
|
|
||||||
/* forward-declare ETM context */
|
/* forward-declare ETM context */
|
||||||
struct etm_context_s;
|
struct etm_context_s;
|
||||||
|
|
||||||
typedef struct etm_capture_driver_s
|
typedef struct etm_capture_driver_s
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int (*register_commands)(struct command_context_s *cmd_ctx);
|
int (*register_commands)(struct command_context_s *cmd_ctx);
|
||||||
int (*init)(struct etm_context_s *etm_ctx);
|
int (*init)(struct etm_context_s *etm_ctx);
|
||||||
trace_status_t (*status)(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 (*read_trace)(struct etm_context_s *etm_ctx);
|
||||||
int (*start_capture)(struct etm_context_s *etm_ctx);
|
int (*start_capture)(struct etm_context_s *etm_ctx);
|
||||||
int (*stop_capture)(struct etm_context_s *etm_ctx);
|
int (*stop_capture)(struct etm_context_s *etm_ctx);
|
||||||
} etm_capture_driver_t;
|
} etm_capture_driver_t;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ETMV1_TRACESYNC_CYCLE = 0x1,
|
ETMV1_TRACESYNC_CYCLE = 0x1,
|
||||||
ETMV1_TRIGGER_CYCLE = 0x2,
|
ETMV1_TRIGGER_CYCLE = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct etmv1_trace_data_s
|
typedef struct etmv1_trace_data_s
|
||||||
{
|
{
|
||||||
u8 pipestat; /* bits 0-2 pipeline status */
|
u8 pipestat; /* bits 0-2 pipeline status */
|
||||||
u16 packet; /* packet data (4, 8 or 16 bit) */
|
u16 packet; /* packet data (4, 8 or 16 bit) */
|
||||||
int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */
|
int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */
|
||||||
} etmv1_trace_data_t;
|
} etmv1_trace_data_t;
|
||||||
|
|
||||||
/* describe a trace context
|
/* describe a trace context
|
||||||
* if support for ETMv2 or ETMv3 is to be implemented,
|
* if support for ETMv2 or ETMv3 is to be implemented,
|
||||||
* this will have to be split into version independent elements
|
* this will have to be split into version independent elements
|
||||||
* and a version specific part
|
* and a version specific part
|
||||||
*/
|
*/
|
||||||
typedef struct etm_context_s
|
typedef struct etm_context_s
|
||||||
{
|
{
|
||||||
target_t *target; /* target this ETM is connected to */
|
target_t *target; /* target this ETM is connected to */
|
||||||
reg_cache_t *reg_cache; /* ETM register cache */
|
reg_cache_t *reg_cache; /* ETM register cache */
|
||||||
etm_capture_driver_t *capture_driver; /* driver used to access ETM data */
|
etm_capture_driver_t *capture_driver; /* driver used to access ETM data */
|
||||||
void *capture_driver_priv; /* capture driver private data */
|
void *capture_driver_priv; /* capture driver private data */
|
||||||
u32 trigger_percent; /* percent of trace buffer to be filled after the trigger */
|
u32 trigger_percent; /* percent of trace buffer to be filled after the trigger */
|
||||||
trace_status_t capture_status; /* current state of capture run */
|
trace_status_t capture_status; /* current state of capture run */
|
||||||
etmv1_trace_data_t *trace_data; /* trace data */
|
etmv1_trace_data_t *trace_data; /* trace data */
|
||||||
u32 trace_depth; /* number of trace cycles to be analyzed, 0 if no trace data available */
|
u32 trace_depth; /* number of trace cycles to be analyzed, 0 if no trace data available */
|
||||||
etm_portmode_t portmode; /* normal, multiplexed or demultiplexed */
|
etm_portmode_t portmode; /* normal, multiplexed or demultiplexed */
|
||||||
etmv1_tracemode_t tracemode; /* type of information the trace contains (data, addres, contextID, ...) */
|
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) */
|
armv4_5_state_t core_state; /* current core state (ARM, Thumb, Jazelle) */
|
||||||
image_t *image; /* source for target opcodes */
|
image_t *image; /* source for target opcodes */
|
||||||
u32 pipe_index; /* current trace cycle */
|
u32 pipe_index; /* current trace cycle */
|
||||||
u32 data_index; /* cycle holding next data packet */
|
u32 data_index; /* cycle holding next data packet */
|
||||||
int data_half; /* port half on a 16 bit port */
|
int data_half; /* port half on a 16 bit port */
|
||||||
u32 current_pc; /* current program counter */
|
u32 current_pc; /* current program counter */
|
||||||
u32 pc_ok; /* full PC has been acquired */
|
u32 pc_ok; /* full PC has been acquired */
|
||||||
u32 last_branch; /* last branch address output */
|
u32 last_branch; /* last branch address output */
|
||||||
u32 last_branch_reason; /* branch reason code for the last branch encountered */
|
u32 last_branch_reason; /* branch reason code for the last branch encountered */
|
||||||
u32 last_ptr; /* address of the last data access */
|
u32 last_ptr; /* address of the last data access */
|
||||||
u32 ptr_ok; /* whether last_ptr is valid */
|
u32 ptr_ok; /* whether last_ptr is valid */
|
||||||
u32 context_id; /* context ID of the code being traced */
|
u32 context_id; /* context ID of the code being traced */
|
||||||
u32 last_instruction; /* index of last instruction executed (to calculate cycle timings) */
|
u32 last_instruction; /* index of last instruction executed (to calculate cycle timings) */
|
||||||
} etm_context_t;
|
} etm_context_t;
|
||||||
|
|
||||||
/* PIPESTAT values */
|
/* PIPESTAT values */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
STAT_IE = 0x0,
|
STAT_IE = 0x0,
|
||||||
STAT_ID = 0x1,
|
STAT_ID = 0x1,
|
||||||
STAT_IN = 0x2,
|
STAT_IN = 0x2,
|
||||||
STAT_WT = 0x3,
|
STAT_WT = 0x3,
|
||||||
STAT_BE = 0x4,
|
STAT_BE = 0x4,
|
||||||
STAT_BD = 0x5,
|
STAT_BD = 0x5,
|
||||||
STAT_TR = 0x6,
|
STAT_TR = 0x6,
|
||||||
STAT_TD = 0x7
|
STAT_TD = 0x7
|
||||||
} etmv1_pipestat_t;
|
} etmv1_pipestat_t;
|
||||||
|
|
||||||
/* branch reason values */
|
/* branch reason values */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */
|
BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */
|
||||||
BR_ENABLE = 0x1, /* Trace has been enabled */
|
BR_ENABLE = 0x1, /* Trace has been enabled */
|
||||||
BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */
|
BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */
|
||||||
BR_NODEBUG = 0x3, /* ARM has exited for debug state */
|
BR_NODEBUG = 0x3, /* ARM has exited for debug state */
|
||||||
BR_PERIOD = 0x4, /* Peridioc synchronization point (ETM>=v1.2)*/
|
BR_PERIOD = 0x4, /* Peridioc synchronization point (ETM>=v1.2)*/
|
||||||
BR_RSVD5 = 0x5, /* reserved */
|
BR_RSVD5 = 0x5, /* reserved */
|
||||||
BR_RSVD6 = 0x6, /* reserved */
|
BR_RSVD6 = 0x6, /* reserved */
|
||||||
BR_RSVD7 = 0x7, /* reserved */
|
BR_RSVD7 = 0x7, /* reserved */
|
||||||
} etmv1_branch_reason_t;
|
} etmv1_branch_reason_t;
|
||||||
|
|
||||||
extern char *etmv1v1_branch_reason_strings[];
|
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 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_read_reg(reg_t *reg);
|
||||||
extern int etm_write_reg(reg_t *reg, u32 value);
|
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_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
|
||||||
extern int etm_store_reg(reg_t *reg);
|
extern int etm_store_reg(reg_t *reg);
|
||||||
extern int etm_set_reg(reg_t *reg, u32 value);
|
extern int etm_set_reg(reg_t *reg, u32 value);
|
||||||
extern int etm_set_reg_w_exec(reg_t *reg, u8 *buf);
|
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_commands(struct command_context_s *cmd_ctx);
|
||||||
int etm_register_user_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);
|
extern etm_context_t* etm_create_context(etm_portmode_t portmode, char *capture_driver_name);
|
||||||
|
|
||||||
#define ERROR_ETM_INVALID_DRIVER (-1300)
|
#define ERROR_ETM_INVALID_DRIVER (-1300)
|
||||||
#define ERROR_ETM_PORTMODE_NOT_SUPPORTED (-1301)
|
#define ERROR_ETM_PORTMODE_NOT_SUPPORTED (-1301)
|
||||||
#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302)
|
#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302)
|
||||||
#define ERROR_ETM_ANALYSIS_FAILED (-1303)
|
#define ERROR_ETM_ANALYSIS_FAILED (-1303)
|
||||||
|
|
||||||
#endif /* ETM_H */
|
#endif /* ETM_H */
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Dominic Rath *
|
* Copyright (C) 2007 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef ETM_DUMMY_H
|
#ifndef ETM_DUMMY_H
|
||||||
#define ETM_DUMMY_H
|
#define ETM_DUMMY_H
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "arm_jtag.h"
|
#include "arm_jtag.h"
|
||||||
|
|
||||||
#include "etm.h"
|
#include "etm.h"
|
||||||
|
|
||||||
extern etm_capture_driver_t etm_dummy_capture_driver;
|
extern etm_capture_driver_t etm_dummy_capture_driver;
|
||||||
extern int etm_dummy_register_commands(struct command_context_s *cmd_ctx);
|
extern int etm_dummy_register_commands(struct command_context_s *cmd_ctx);
|
||||||
|
|
||||||
#endif /* ETB_H */
|
#endif /* ETB_H */
|
||||||
|
|
|
@ -1,64 +1,64 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Dominic Rath *
|
* Copyright (C) 2007 by Dominic Rath *
|
||||||
* Dominic.Rath@gmx.de *
|
* Dominic.Rath@gmx.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* This program is distributed in the hope that it will be useful, *
|
* This program is distributed in the hope that it will be useful, *
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
* GNU General Public License for more details. *
|
* GNU General Public License for more details. *
|
||||||
* *
|
* *
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program; if not, write to the *
|
* along with this program; if not, write to the *
|
||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef OOCD_TRACE_H
|
#ifndef OOCD_TRACE_H
|
||||||
#define OOCD_TRACE_H
|
#define OOCD_TRACE_H
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
#include "etm.h"
|
#include "etm.h"
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* registers */
|
/* registers */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OOCD_TRACE_ID = 0x7,
|
OOCD_TRACE_ID = 0x7,
|
||||||
OOCD_TRACE_ADDRESS = 0x0,
|
OOCD_TRACE_ADDRESS = 0x0,
|
||||||
OOCD_TRACE_TRIGGER_COUNTER = 0x01,
|
OOCD_TRACE_TRIGGER_COUNTER = 0x01,
|
||||||
OOCD_TRACE_CONTROL = 0x2,
|
OOCD_TRACE_CONTROL = 0x2,
|
||||||
OOCD_TRACE_STATUS = 0x3,
|
OOCD_TRACE_STATUS = 0x3,
|
||||||
OOCD_TRACE_SDRAM_COUNTER = 0x4,
|
OOCD_TRACE_SDRAM_COUNTER = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* commands */
|
/* commands */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OOCD_TRACE_NOP = 0x0,
|
OOCD_TRACE_NOP = 0x0,
|
||||||
OOCD_TRACE_READ_REG = 0x10,
|
OOCD_TRACE_READ_REG = 0x10,
|
||||||
OOCD_TRACE_WRITE_REG = 0x18,
|
OOCD_TRACE_WRITE_REG = 0x18,
|
||||||
OOCD_TRACE_READ_RAM = 0x20,
|
OOCD_TRACE_READ_RAM = 0x20,
|
||||||
/* OOCD_TRACE_WRITE_RAM = 0x28, */
|
/* OOCD_TRACE_WRITE_RAM = 0x28, */
|
||||||
OOCD_TRACE_RESYNC = 0xf0,
|
OOCD_TRACE_RESYNC = 0xf0,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct oocd_trace_s
|
typedef struct oocd_trace_s
|
||||||
{
|
{
|
||||||
etm_context_t *etm_ctx;
|
etm_context_t *etm_ctx;
|
||||||
char *tty;
|
char *tty;
|
||||||
int tty_fd;
|
int tty_fd;
|
||||||
struct termios oldtio, newtio;
|
struct termios oldtio, newtio;
|
||||||
} oocd_trace_t;
|
} oocd_trace_t;
|
||||||
|
|
||||||
extern etm_capture_driver_t oocd_trace_capture_driver;
|
extern etm_capture_driver_t oocd_trace_capture_driver;
|
||||||
|
|
||||||
extern int oocd_trace_register_commands(struct command_context_s *cmd_ctx);
|
extern int oocd_trace_register_commands(struct command_context_s *cmd_ctx);
|
||||||
|
|
||||||
#endif /* OOCD_TRACE_TRACE_H */
|
#endif /* OOCD_TRACE_TRACE_H */
|
||||||
|
|
4664
src/target/target.c
4664
src/target/target.c
File diff suppressed because it is too large
Load Diff
7598
src/target/xscale.c
7598
src/target/xscale.c
File diff suppressed because it is too large
Load Diff
1002
src/xsvf/xsvf.c
1002
src/xsvf/xsvf.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue