- added svn props

- fixed mixed line endings on flash.c, log.c, gdb_server.c

git-svn-id: svn://svn.berlios.de/openocd/trunk@371 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
ntfreak 2008-02-28 10:07:54 +00:00
parent 76ebc78358
commit 9e5a6679ca
16 changed files with 1015 additions and 1015 deletions

10
NEWS
View File

@ -1,5 +1,5 @@
2008-01-21 : 2008-01-21 :
xscale big-endian branch closed and all changes moved to xscale big-endian branch closed and all changes moved to
trunk. trunk.

View File

@ -1,28 +1,28 @@
#daemon configuration #daemon configuration
telnet_port 4444 telnet_port 4444
gdb_port 3333 gdb_port 3333
#interface #interface
interface ft2232 interface ft2232
ft2232_device_desc "Stellaris Evaluation Board A" ft2232_device_desc "Stellaris Evaluation Board A"
ft2232_layout evb_lm3s811 ft2232_layout evb_lm3s811
ft2232_vid_pid 0x0403 0xbcd9 ft2232_vid_pid 0x0403 0xbcd9
jtag_speed 40 jtag_speed 40
#LM3S811 Evaluation Board has only srst #LM3S811 Evaluation Board has only srst
reset_config srst_only separate reset_config srst_only separate
#jtag scan chain #jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) #format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 4 0x1 0xf 0xe jtag_device 4 0x1 0xf 0xe
#target configuration #target configuration
daemon_startup attach daemon_startup attach
#target <type> <startup mode> #target <type> <startup mode>
#target arm7tdmi <reset mode> <chainpos> <endianness> <variant> #target arm7tdmi <reset mode> <chainpos> <endianness> <variant>
target cortex_m3 little run_and_halt 0 target cortex_m3 little run_and_halt 0
# 4k working area at base of ram # 4k working area at base of ram
working_area 0 0x20000800 0x1200 nobackup working_area 0 0x20000800 0x1200 nobackup
#target_script 0 reset ../doc/scripts/evb_lm3s811_test.script #target_script 0 reset ../doc/scripts/evb_lm3s811_test.script
#flash configuration #flash configuration
flash bank stellaris 0 0 0 0 0 flash bank stellaris 0 0 0 0 0

View File

@ -1,9 +1,9 @@
# Resets and unlocks the MSM of TMS470R1A288 (an others with an MSM). # Resets and unlocks the MSM of TMS470R1A288 (an others with an MSM).
# Assumes default MSM keys (all 0xFFFFFFFF). # Assumes default MSM keys (all 0xFFFFFFFF).
# #
resume resume
jtag_reset 0 1 jtag_reset 0 1
halt halt
jtag_reset 0 0 jtag_reset 0 0
poll # hack-ish, but effective version of 'reset halt' poll # hack-ish, but effective version of 'reset halt'
mdw 0x1fe0 4 # unlock MSM mdw 0x1fe0 4 # unlock MSM

0
ecosflash/at91eb40a.elf Normal file → Executable file
View File

0
ecosflash/debug_at91eb40a.elf Normal file → Executable file
View File

View File

@ -1,111 +1,111 @@
1. GDB startup script for debugging purposes. 1. GDB startup script for debugging purposes.
# startup script for debugging flash erase # startup script for debugging flash erase
target remote 10.0.0.56:2001 target remote 10.0.0.56:2001
monitor halt monitor halt
monitor reset monitor reset
load load
# stack # stack
monitor rm 13 0x7000 monitor rm 13 0x7000
# pc # pc
monitor rm 15 0x8000 monitor rm 15 0x8000
# arg1 to erase() # arg1 to erase()
monitor rm 0 0x1030000 monitor rm 0 0x1030000
# arg2 to erase() # arg2 to erase()
monitor rm 1 0x10000 monitor rm 1 0x10000
stepi stepi
2. Uploading flash driver via tftp 2. Uploading flash driver via tftp
$ tftp 10.0.0.108 $ tftp 10.0.0.108
tftp> binary tftp> binary
tftp> put at91fr40162.bin 10.0.0.108:/config/flashdriver.bin tftp> put at91fr40162.bin 10.0.0.108:/config/flashdriver.bin
Sent 4048 bytes in 0.1 seconds Sent 4048 bytes in 0.1 seconds
tftp> tftp>
4. Programming flash 4. Programming flash
eCosBoard_prog 0x1000000 /config/testdata.bin eCosBoard_prog 0x1000000 /config/testdata.bin
tftp> put /cygdrive/c/workspace/ecosboard/ecosboard/phi/bootloader/images/bootloader.bin 10.0.0.108:/config/test.bin tftp> put /cygdrive/c/workspace/ecosboard/ecosboard/phi/bootloader/images/bootloader.bin 10.0.0.108:/config/test.bin
Sent 165724 bytes in 3.9 seconds Sent 165724 bytes in 3.9 seconds
halt halt
reg cpsr 0x000000D3 reg cpsr 0x000000D3
mww 0xFFE00020 0x1 mww 0xFFE00020 0x1
mww 0xFFE00024 0x00000000 mww 0xFFE00024 0x00000000
mww 0xFFE00000 0x01002539 mww 0xFFE00000 0x01002539
eCosBoard_profile eCosBoard_profile
eCosBoard_prog /config/test.bin 0x1000000 eCosBoard_prog /config/test.bin 0x1000000
eCosBoard_profile_done eCosBoard_profile_done
set remote memory-write-packet-size fixed set remote memory-write-packet-size fixed
set remote memory-write-packet-size 8192 set remote memory-write-packet-size 8192
set remote memory-map-packet on set remote memory-map-packet on
target remote 10.0.0.108:3333 target remote 10.0.0.108:3333
monitor halt monitor halt
monitor reg cpsr 0x000000D3 monitor reg cpsr 0x000000D3
monitor mww 0xFFE00020 0x1 monitor mww 0xFFE00020 0x1
monitor mww 0xFFE00024 0x00000000 monitor mww 0xFFE00024 0x00000000
monitor mww 0xFFE00000 0x01002539 monitor mww 0xFFE00000 0x01002539
monitor eCosBoard_profile monitor eCosBoard_profile
load load
monitor eCosBoard_profile_done monitor eCosBoard_profile_done
source /tmp/ecosboard/packages/services/profile/gprof/current/host/gprof.gdb source /tmp/ecosboard/packages/services/profile/gprof/current/host/gprof.gdb
gprof_dump gprof_dump
shell cp gmon.out /tmp/ecosboard/build/src shell cp gmon.out /tmp/ecosboard/build/src
echo To view: cd /tmp/ecosboard/build/src && gprof openocd echo To view: cd /tmp/ecosboard/build/src && gprof openocd
Performance problems: Performance problems:
It seems the problem is that the actual flash programming takes time. It seems the problem is that the actual flash programming takes time.
hal_delay_us() is invoked between each time the hal_delay_us() is invoked between each time the
CPU is polled for whether flash programming has completed. CPU is polled for whether flash programming has completed.
Flat profile: Flat profile:
Each sample counts as 0.01 seconds. Each sample counts as 0.01 seconds.
% cumulative self self total % cumulative self self total
time seconds seconds calls Ts/call Ts/call name time seconds seconds calls Ts/call Ts/call name
35.82 37.66 37.66 hal_delay_us 35.82 37.66 37.66 hal_delay_us
11.90 50.17 12.51 arm7tdmi_clock_out 11.90 50.17 12.51 arm7tdmi_clock_out
9.86 60.54 10.37 gdb_get_packet 9.86 60.54 10.37 gdb_get_packet
5.36 66.17 5.63 memcpy 5.36 66.17 5.63 memcpy
4.34 70.73 4.56 target_buffer_get_u32 4.34 70.73 4.56 target_buffer_get_u32
3.34 74.25 3.51 embeddedice_read_reg_w_che 3.34 74.25 3.51 embeddedice_read_reg_w_che
ck ck
1.39 75.71 1.46 arm7_9_write_memory 1.39 75.71 1.46 arm7_9_write_memory
1.34 77.11 1.40 cyg_tcp_output 1.34 77.11 1.40 cyg_tcp_output
1.33 78.51 1.40 __udivsi3 1.33 78.51 1.40 __udivsi3
1.11 79.68 1.17 cyg_tcp_input 1.11 79.68 1.17 cyg_tcp_input
1.07 80.80 1.13 arm7tdmi_store_word_regs 1.07 80.80 1.13 arm7tdmi_store_word_regs
0.95 81.81 1.00 __udivdi3 0.95 81.81 1.00 __udivdi3
0.95 82.80 1.00 __umodsi3 0.95 82.80 1.00 __umodsi3
0.93 83.78 0.98 arm7tdmi_write_core_regs 0.93 83.78 0.98 arm7tdmi_write_core_regs
0.86 84.68 0.91 arm7_9_poll 0.86 84.68 0.91 arm7_9_poll
0.85 85.57 0.89 memset 0.85 85.57 0.89 memset
0.77 86.38 0.81 cyg_splx 0.77 86.38 0.81 cyg_splx
0.64 87.05 0.67 cyg_in_cksumdata 0.64 87.05 0.67 cyg_in_cksumdata
0.63 87.71 0.66 openeth_deliver 0.63 87.71 0.66 openeth_deliver
0.57 88.31 0.60 strstr 0.57 88.31 0.60 strstr
0.51 88.85 0.53 eth_drv_recv 0.51 88.85 0.53 eth_drv_recv
0.49 89.36 0.52 cyg_splinternal 0.49 89.36 0.52 cyg_splinternal
0.49 89.88 0.52 cyg_splimp 0.49 89.88 0.52 cyg_splimp
0.46 90.36 0.48 cyg_ip_input 0.46 90.36 0.48 cyg_ip_input

View File

@ -1,485 +1,485 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2008 Øyvind Harboe * * Copyright (C) 2008 Øyvind Harboe *
* oyvind.harboe@zylin.com * * oyvind.harboe@zylin.com *
* * * *
* 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 "flash.h" #include "flash.h"
#include "target.h" #include "target.h"
#include "flash.h" #include "flash.h"
#include "target.h" #include "target.h"
#include "log.h" #include "log.h"
#include "binarybuffer.h" #include "binarybuffer.h"
#include "../target/embeddedice.h" #include "../target/embeddedice.h"
#include "types.h" #include "types.h"
int ecosflash_register_commands(struct command_context_s *cmd_ctx); int ecosflash_register_commands(struct command_context_s *cmd_ctx);
int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank); int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
int ecosflash_erase(struct flash_bank_s *bank, int first, int last); int ecosflash_erase(struct flash_bank_s *bank, int first, int last);
int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last); int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last);
int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
int ecosflash_probe(struct flash_bank_s *bank); int ecosflash_probe(struct flash_bank_s *bank);
int ecosflash_erase_check(struct flash_bank_s *bank); int ecosflash_erase_check(struct flash_bank_s *bank);
int ecosflash_protect_check(struct flash_bank_s *bank); int ecosflash_protect_check(struct flash_bank_s *bank);
int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size); int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size);
u32 ecosflash_get_flash_status(flash_bank_t *bank); u32 ecosflash_get_flash_status(flash_bank_t *bank);
void ecosflash_set_flash_mode(flash_bank_t *bank,int mode); void ecosflash_set_flash_mode(flash_bank_t *bank,int mode);
u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout); u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_driver_t ecosflash_flash = flash_driver_t ecosflash_flash =
{ {
.name = "ecosflash", .name = "ecosflash",
.register_commands = ecosflash_register_commands, .register_commands = ecosflash_register_commands,
.flash_bank_command = ecosflash_flash_bank_command, .flash_bank_command = ecosflash_flash_bank_command,
.erase = ecosflash_erase, .erase = ecosflash_erase,
.protect = ecosflash_protect, .protect = ecosflash_protect,
.write = ecosflash_write, .write = ecosflash_write,
.probe = ecosflash_probe, .probe = ecosflash_probe,
.auto_probe = ecosflash_probe, .auto_probe = ecosflash_probe,
.erase_check = ecosflash_erase_check, .erase_check = ecosflash_erase_check,
.protect_check = ecosflash_protect_check, .protect_check = ecosflash_protect_check,
.info = ecosflash_info .info = ecosflash_info
}; };
typedef struct ecosflash_flash_bank_s typedef struct ecosflash_flash_bank_s
{ {
struct target_s *target; struct target_s *target;
working_area_t *write_algorithm; working_area_t *write_algorithm;
working_area_t *erase_check_algorithm; working_area_t *erase_check_algorithm;
char *driverPath; char *driverPath;
u32 start_address; u32 start_address;
} ecosflash_flash_bank_t; } ecosflash_flash_bank_t;
static const int sectorSize=0x10000; static const int sectorSize=0x10000;
char * char *
flash_errmsg(int err); flash_errmsg(int err);
#ifndef __ECOS #ifndef __ECOS
#define FLASH_ERR_OK 0x00 // No error - operation complete #define FLASH_ERR_OK 0x00 // No error - operation complete
#define FLASH_ERR_INVALID 0x01 // Invalid FLASH address #define FLASH_ERR_INVALID 0x01 // Invalid FLASH address
#define FLASH_ERR_ERASE 0x02 // Error trying to erase #define FLASH_ERR_ERASE 0x02 // Error trying to erase
#define FLASH_ERR_LOCK 0x03 // Error trying to lock/unlock #define FLASH_ERR_LOCK 0x03 // Error trying to lock/unlock
#define FLASH_ERR_PROGRAM 0x04 // Error trying to program #define FLASH_ERR_PROGRAM 0x04 // Error trying to program
#define FLASH_ERR_PROTOCOL 0x05 // Generic error #define FLASH_ERR_PROTOCOL 0x05 // Generic error
#define FLASH_ERR_PROTECT 0x06 // Device/region is write-protected #define FLASH_ERR_PROTECT 0x06 // Device/region is write-protected
#define FLASH_ERR_NOT_INIT 0x07 // FLASH info not yet initialized #define FLASH_ERR_NOT_INIT 0x07 // FLASH info not yet initialized
#define FLASH_ERR_HWR 0x08 // Hardware (configuration?) problem #define FLASH_ERR_HWR 0x08 // Hardware (configuration?) problem
#define FLASH_ERR_ERASE_SUSPEND 0x09 // Device is in erase suspend mode #define FLASH_ERR_ERASE_SUSPEND 0x09 // Device is in erase suspend mode
#define FLASH_ERR_PROGRAM_SUSPEND 0x0a // Device is in in program suspend mode #define FLASH_ERR_PROGRAM_SUSPEND 0x0a // Device is in in program suspend mode
#define FLASH_ERR_DRV_VERIFY 0x0b // Driver failed to verify data #define FLASH_ERR_DRV_VERIFY 0x0b // Driver failed to verify data
#define FLASH_ERR_DRV_TIMEOUT 0x0c // Driver timed out waiting for device #define FLASH_ERR_DRV_TIMEOUT 0x0c // Driver timed out waiting for device
#define FLASH_ERR_DRV_WRONG_PART 0x0d // Driver does not support device #define FLASH_ERR_DRV_WRONG_PART 0x0d // Driver does not support device
#define FLASH_ERR_LOW_VOLTAGE 0x0e // Not enough juice to complete job #define FLASH_ERR_LOW_VOLTAGE 0x0e // Not enough juice to complete job
char * char *
flash_errmsg(int err) flash_errmsg(int err)
{ {
switch (err) { switch (err) {
case FLASH_ERR_OK: case FLASH_ERR_OK:
return "No error - operation complete"; return "No error - operation complete";
case FLASH_ERR_ERASE_SUSPEND: case FLASH_ERR_ERASE_SUSPEND:
return "Device is in erase suspend state"; return "Device is in erase suspend state";
case FLASH_ERR_PROGRAM_SUSPEND: case FLASH_ERR_PROGRAM_SUSPEND:
return "Device is in program suspend state"; return "Device is in program suspend state";
case FLASH_ERR_INVALID: case FLASH_ERR_INVALID:
return "Invalid FLASH address"; return "Invalid FLASH address";
case FLASH_ERR_ERASE: case FLASH_ERR_ERASE:
return "Error trying to erase"; return "Error trying to erase";
case FLASH_ERR_LOCK: case FLASH_ERR_LOCK:
return "Error trying to lock/unlock"; return "Error trying to lock/unlock";
case FLASH_ERR_PROGRAM: case FLASH_ERR_PROGRAM:
return "Error trying to program"; return "Error trying to program";
case FLASH_ERR_PROTOCOL: case FLASH_ERR_PROTOCOL:
return "Generic error"; return "Generic error";
case FLASH_ERR_PROTECT: case FLASH_ERR_PROTECT:
return "Device/region is write-protected"; return "Device/region is write-protected";
case FLASH_ERR_NOT_INIT: case FLASH_ERR_NOT_INIT:
return "FLASH sub-system not initialized"; return "FLASH sub-system not initialized";
case FLASH_ERR_DRV_VERIFY: case FLASH_ERR_DRV_VERIFY:
return "Data verify failed after operation"; return "Data verify failed after operation";
case FLASH_ERR_DRV_TIMEOUT: case FLASH_ERR_DRV_TIMEOUT:
return "Driver timed out waiting for device"; return "Driver timed out waiting for device";
case FLASH_ERR_DRV_WRONG_PART: case FLASH_ERR_DRV_WRONG_PART:
return "Driver does not support device"; return "Driver does not support device";
case FLASH_ERR_LOW_VOLTAGE: case FLASH_ERR_LOW_VOLTAGE:
return "Device reports low voltage"; return "Device reports low voltage";
default: default:
return "Unknown error"; return "Unknown error";
} }
} }
#endif #endif
/* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath> /* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath>
*/ */
int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
{ {
ecosflash_flash_bank_t *info; ecosflash_flash_bank_t *info;
if (argc < 7) if (argc < 7)
{ {
WARNING("incomplete flash_bank ecosflash configuration"); WARNING("incomplete flash_bank ecosflash configuration");
return ERROR_FLASH_BANK_INVALID; return ERROR_FLASH_BANK_INVALID;
} }
info = malloc(sizeof(ecosflash_flash_bank_t)); info = malloc(sizeof(ecosflash_flash_bank_t));
if(info == NULL) if(info == NULL)
{ {
ERROR("no memory for flash bank info"); ERROR("no memory for flash bank info");
exit(-1); exit(-1);
} }
bank->driver_priv = info; bank->driver_priv = info;
info->driverPath=strdup(args[6]); info->driverPath=strdup(args[6]);
// eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as // eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as
// a way to improve impeadance matach between OpenOCD and eCos flash // a way to improve impeadance matach between OpenOCD and eCos flash
// driver // driver
int i = 0; int i = 0;
u32 offset = 0; u32 offset = 0;
bank->num_sectors=bank->size/sectorSize; bank->num_sectors=bank->size/sectorSize;
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors); bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
for (i = 0; i < bank->num_sectors; i++) for (i = 0; i < bank->num_sectors; i++)
{ {
bank->sectors[i].offset = offset; bank->sectors[i].offset = offset;
bank->sectors[i].size = sectorSize; bank->sectors[i].size = sectorSize;
offset += bank->sectors[i].size; offset += bank->sectors[i].size;
bank->sectors[i].is_erased = -1; bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = 0; bank->sectors[i].is_protected = 0;
} }
info->target = get_target_by_num(strtoul(args[5], NULL, 0)); info->target = get_target_by_num(strtoul(args[5], NULL, 0));
if (info->target == NULL) if (info->target == NULL)
{ {
ERROR("no target '%i' configured", (int)strtoul(args[5], NULL, 0)); ERROR("no target '%i' configured", (int)strtoul(args[5], NULL, 0));
exit(-1); exit(-1);
} }
return ERROR_OK; return ERROR_OK;
} }
int loadDriver(ecosflash_flash_bank_t *info) int loadDriver(ecosflash_flash_bank_t *info)
{ {
u32 buf_cnt; u32 buf_cnt;
u32 image_size; u32 image_size;
image_t image; image_t image;
image.base_address_set = 0; image.base_address_set = 0;
image.start_address_set = 0; image.start_address_set = 0;
target_t *target=info->target; target_t *target=info->target;
if (image_open(&image, info->driverPath, NULL) != ERROR_OK) if (image_open(&image, info->driverPath, NULL) != ERROR_OK)
{ {
ERROR("load_image error: %s", image.error_str); ERROR("load_image error: %s", image.error_str);
return ERROR_FLASH_BANK_INVALID; return ERROR_FLASH_BANK_INVALID;
} }
info->start_address=image.start_address; info->start_address=image.start_address;
image_size = 0x0; image_size = 0x0;
int i; int i;
for (i = 0; i < image.num_sections; i++) for (i = 0; i < image.num_sections; i++)
{ {
void *buffer = malloc(image.sections[i].size); void *buffer = malloc(image.sections[i].size);
int retval; int retval;
if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK) if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
{ {
ERROR("image_read_section failed with error code: %i", retval); ERROR("image_read_section failed with error code: %i", retval);
free(buffer); free(buffer);
image_close(&image); image_close(&image);
return ERROR_FLASH_BANK_INVALID; return ERROR_FLASH_BANK_INVALID;
} }
target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer); target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
image_size += buf_cnt; image_size += buf_cnt;
DEBUG("%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address); DEBUG("%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
free(buffer); free(buffer);
} }
image_close(&image); image_close(&image);
return ERROR_OK; return ERROR_OK;
} }
static int const OFFSET_ERASE=0x0; static int const OFFSET_ERASE=0x0;
static int const OFFSET_ERASE_SIZE=0x8; static int const OFFSET_ERASE_SIZE=0x8;
static int const OFFSET_FLASH=0xc; static int const OFFSET_FLASH=0xc;
static int const OFFSET_FLASH_SIZE=0x8; static int const OFFSET_FLASH_SIZE=0x8;
static int const OFFSET_GET_WORKAREA=0x18; static int const OFFSET_GET_WORKAREA=0x18;
static int const OFFSET_GET_WORKAREA_SIZE=0x4; static int const OFFSET_GET_WORKAREA_SIZE=0x4;
int runCode(ecosflash_flash_bank_t *info, int runCode(ecosflash_flash_bank_t *info,
u32 codeStart, u32 codeStop, u32 r0, u32 r1, u32 r2, u32 codeStart, u32 codeStop, u32 r0, u32 r1, u32 r2,
u32 *result, u32 *result,
// timeout in ms // timeout in ms
int timeout) int timeout)
{ {
target_t *target=info->target; target_t *target=info->target;
reg_param_t reg_params[3]; reg_param_t reg_params[3];
armv4_5_algorithm_t armv4_5_info; armv4_5_algorithm_t armv4_5_info;
armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC; armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
armv4_5_info.core_mode = ARMV4_5_MODE_SVC; armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
armv4_5_info.core_state = ARMV4_5_STATE_ARM; armv4_5_info.core_state = ARMV4_5_STATE_ARM;
init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
buf_set_u32(reg_params[0].value, 0, 32, r0); buf_set_u32(reg_params[0].value, 0, 32, r0);
buf_set_u32(reg_params[1].value, 0, 32, r1); buf_set_u32(reg_params[1].value, 0, 32, r1);
buf_set_u32(reg_params[2].value, 0, 32, r2); buf_set_u32(reg_params[2].value, 0, 32, r2);
int retval; int retval;
if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
codeStart, codeStart,
codeStop, timeout, codeStop, timeout,
&armv4_5_info)) != ERROR_OK) &armv4_5_info)) != ERROR_OK)
{ {
ERROR("error executing eCos flash algorithm"); ERROR("error executing eCos flash algorithm");
return retval; return retval;
} }
*result=buf_get_u32(reg_params[0].value, 0, 32); *result=buf_get_u32(reg_params[0].value, 0, 32);
destroy_reg_param(&reg_params[0]); destroy_reg_param(&reg_params[0]);
destroy_reg_param(&reg_params[1]); destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]); destroy_reg_param(&reg_params[2]);
return ERROR_OK; return ERROR_OK;
} }
int eCosBoard_erase(ecosflash_flash_bank_t *info, u32 address, u32 len) int eCosBoard_erase(ecosflash_flash_bank_t *info, u32 address, u32 len)
{ {
int retval; int retval;
int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/ int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/
retval=loadDriver(info); retval=loadDriver(info);
if (retval!=ERROR_OK) if (retval!=ERROR_OK)
return retval; return retval;
u32 flashErr; u32 flashErr;
retval=runCode(info, retval=runCode(info,
info->start_address+OFFSET_ERASE, info->start_address+OFFSET_ERASE,
info->start_address+OFFSET_ERASE+OFFSET_ERASE_SIZE, info->start_address+OFFSET_ERASE+OFFSET_ERASE_SIZE,
address, address,
len, len,
0, 0,
&flashErr, &flashErr,
timeout timeout
); );
if (retval!=ERROR_OK) if (retval!=ERROR_OK)
return retval; return retval;
if (flashErr != 0x0) if (flashErr != 0x0)
{ {
ERROR("Flash erase failed with %d (%s)\n", flashErr, flash_errmsg(flashErr)); ERROR("Flash erase failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
return ERROR_OK; return ERROR_OK;
} }
int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, u32 address, u32 len) int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, u32 address, u32 len)
{ {
target_t *target=info->target; target_t *target=info->target;
const int chunk=8192; const int chunk=8192;
int retval=ERROR_OK; int retval=ERROR_OK;
int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/ int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
retval=loadDriver(info); retval=loadDriver(info);
if (retval!=ERROR_OK) if (retval!=ERROR_OK)
return retval; return retval;
u32 buffer; u32 buffer;
retval=runCode(info, retval=runCode(info,
info->start_address+OFFSET_GET_WORKAREA, info->start_address+OFFSET_GET_WORKAREA,
info->start_address+OFFSET_GET_WORKAREA+OFFSET_GET_WORKAREA_SIZE, info->start_address+OFFSET_GET_WORKAREA+OFFSET_GET_WORKAREA_SIZE,
0, 0,
0, 0,
0, 0,
&buffer, &buffer,
1000); 1000);
if (retval!=ERROR_OK) if (retval!=ERROR_OK)
return retval; return retval;
int i; int i;
for (i=0; i<len; i+=chunk) for (i=0; i<len; i+=chunk)
{ {
int t=len-i; int t=len-i;
if (t>chunk) if (t>chunk)
{ {
t=chunk; t=chunk;
} }
int retval; int retval;
retval=target_write_buffer(target, buffer, t, ((char *)data)+i); retval=target_write_buffer(target, buffer, t, ((char *)data)+i);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
u32 flashErr; u32 flashErr;
retval=runCode(info, retval=runCode(info,
info->start_address+OFFSET_FLASH, info->start_address+OFFSET_FLASH,
info->start_address+OFFSET_FLASH+OFFSET_FLASH_SIZE, info->start_address+OFFSET_FLASH+OFFSET_FLASH_SIZE,
buffer, buffer,
address+i, address+i,
t, t,
&flashErr, &flashErr,
timeout); timeout);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (flashErr != 0x0) if (flashErr != 0x0)
{ {
ERROR("Flash prog failed with %d (%s)\n", flashErr, flash_errmsg(flashErr)); ERROR("Flash prog failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
} }
return ERROR_OK; return ERROR_OK;
} }
int ecosflash_probe(struct flash_bank_s *bank) int ecosflash_probe(struct flash_bank_s *bank)
{ {
return ERROR_OK; return ERROR_OK;
} }
int ecosflash_register_commands(struct command_context_s *cmd_ctx) int ecosflash_register_commands(struct command_context_s *cmd_ctx)
{ {
register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL); register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL);
return ERROR_OK; return ERROR_OK;
} }
/* /*
static void command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf) static void command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
{ {
ecosflash_flash_bank_t *info = bank->driver_priv; ecosflash_flash_bank_t *info = bank->driver_priv;
int i; int i;
if (info->target->endianness == TARGET_LITTLE_ENDIAN) if (info->target->endianness == TARGET_LITTLE_ENDIAN)
{ {
for (i = bank->bus_width; i > 0; i--) for (i = bank->bus_width; i > 0; i--)
{ {
*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd; *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
} }
} }
else else
{ {
for (i = 1; i <= bank->bus_width; i++) for (i = 1; i <= bank->bus_width; i++)
{ {
*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd; *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
} }
} }
} }
*/ */
u32 ecosflash_address(struct flash_bank_s *bank, u32 address) u32 ecosflash_address(struct flash_bank_s *bank, u32 address)
{ {
u32 retval = 0; u32 retval = 0;
switch(bank->bus_width) switch(bank->bus_width)
{ {
case 4: case 4:
retval = address & 0xfffffffc; retval = address & 0xfffffffc;
case 2: case 2:
retval = address & 0xfffffffe; retval = address & 0xfffffffe;
case 1: case 1:
retval = address; retval = address;
} }
return retval + bank->base; return retval + bank->base;
} }
int ecosflash_erase(struct flash_bank_s *bank, int first, int last) int ecosflash_erase(struct flash_bank_s *bank, int first, int last)
{ {
struct flash_bank_s *c=bank; struct flash_bank_s *c=bank;
ecosflash_flash_bank_t *info = bank->driver_priv; ecosflash_flash_bank_t *info = bank->driver_priv;
return eCosBoard_erase(info, c->base+first*sectorSize, sectorSize*(last-first+1)); return eCosBoard_erase(info, c->base+first*sectorSize, sectorSize*(last-first+1));
} }
int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last) int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last)
{ {
return ERROR_OK; return ERROR_OK;
} }
int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
{ {
ecosflash_flash_bank_t *info = bank->driver_priv; ecosflash_flash_bank_t *info = bank->driver_priv;
struct flash_bank_s *c=bank; struct flash_bank_s *c=bank;
return eCosBoard_flash(info, buffer, c->base+offset, count); return eCosBoard_flash(info, buffer, c->base+offset, count);
} }
int ecosflash_erase_check(struct flash_bank_s *bank) int ecosflash_erase_check(struct flash_bank_s *bank)
{ {
return ERROR_OK; return ERROR_OK;
} }
int ecosflash_protect_check(struct flash_bank_s *bank) int ecosflash_protect_check(struct flash_bank_s *bank)
{ {
return ERROR_OK; return ERROR_OK;
} }
int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size) int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size)
{ {
ecosflash_flash_bank_t *info = bank->driver_priv; ecosflash_flash_bank_t *info = bank->driver_priv;
snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath); snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath);
return ERROR_OK; return ERROR_OK;
} }
u32 ecosflash_get_flash_status(flash_bank_t *bank) u32 ecosflash_get_flash_status(flash_bank_t *bank)
{ {
return ERROR_OK; return ERROR_OK;
} }
void ecosflash_set_flash_mode(flash_bank_t *bank,int mode) void ecosflash_set_flash_mode(flash_bank_t *bank,int mode)
{ {
} }
u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout) u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
{ {
return ERROR_OK; return ERROR_OK;
} }
int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{ {
return ERROR_OK; return ERROR_OK;
} }

View File

@ -64,7 +64,7 @@ extern flash_driver_t stellaris_flash;
extern flash_driver_t str9xpec_flash; extern flash_driver_t str9xpec_flash;
extern flash_driver_t stm32x_flash; extern flash_driver_t stm32x_flash;
extern flash_driver_t tms470_flash; extern flash_driver_t tms470_flash;
extern flash_driver_t ecosflash_flash; extern flash_driver_t ecosflash_flash;
flash_driver_t *flash_drivers[] = flash_driver_t *flash_drivers[] =
{ {
@ -77,7 +77,7 @@ flash_driver_t *flash_drivers[] =
&str9xpec_flash, &str9xpec_flash,
&stm32x_flash, &stm32x_flash,
&tms470_flash, &tms470_flash,
&ecosflash_flash, &ecosflash_flash,
NULL, NULL,
}; };
@ -115,7 +115,7 @@ static int flash_driver_erase(struct flash_bank_s *bank, int first, int last)
{ {
ERROR("invalid flash sector"); ERROR("invalid flash sector");
retval=ERROR_FLASH_SECTOR_INVALID; retval=ERROR_FLASH_SECTOR_INVALID;
} else } else
{ {
retval=bank->driver->erase(bank, first, last); retval=bank->driver->erase(bank, first, last);
} }
@ -137,7 +137,7 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last
{ {
ERROR("invalid flash sector"); ERROR("invalid flash sector");
retval=ERROR_FLASH_SECTOR_INVALID; retval=ERROR_FLASH_SECTOR_INVALID;
} else } else
{ {
retval=bank->driver->protect(bank, set, first, last); retval=bank->driver->protect(bank, set, first, last);
} }
@ -152,7 +152,7 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last
int flash_register_commands(struct command_context_s *cmd_ctx) int flash_register_commands(struct command_context_s *cmd_ctx)
{ {
flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL); flash_cmd = register_command(cmd_ctx, NULL, "flash", NULL, COMMAND_ANY, NULL);
register_command(cmd_ctx, flash_cmd, "bank", handle_flash_bank_command, COMMAND_CONFIG, "flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]"); register_command(cmd_ctx, flash_cmd, "bank", handle_flash_bank_command, COMMAND_CONFIG, "flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]");
register_command(cmd_ctx, flash_cmd, "auto_erase", handle_flash_auto_erase_command, COMMAND_ANY, register_command(cmd_ctx, flash_cmd, "auto_erase", handle_flash_auto_erase_command, COMMAND_ANY,
"auto erase flash sectors <on|off>"); "auto erase flash sectors <on|off>");
@ -184,7 +184,7 @@ int flash_init_drivers(struct command_context_s *cmd_ctx)
register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC, register_command(cmd_ctx, flash_cmd, "protect", handle_flash_protect_command, COMMAND_EXEC,
"set protection of sectors at <bank> <first> <last> <on|off>"); "set protection of sectors at <bank> <first> <last> <on|off>");
} }
return ERROR_OK; return ERROR_OK;
} }
@ -208,12 +208,12 @@ flash_bank_t *get_flash_bank_by_num(int num)
{ {
flash_bank_t *p = get_flash_bank_by_num_noprobe(num); flash_bank_t *p = get_flash_bank_by_num_noprobe(num);
int retval; int retval;
if (p == NULL) if (p == NULL)
return NULL; return NULL;
retval = p->driver->auto_probe(p); retval = p->driver->auto_probe(p);
if (retval != ERROR_OK) if (retval != ERROR_OK)
{ {
ERROR("auto_probe failed %d\n", retval); ERROR("auto_probe failed %d\n", retval);
@ -227,31 +227,31 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
int i; int i;
int found = 0; int found = 0;
target_t *target; target_t *target;
if (argc < 6) if (argc < 6)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL) if ((target = get_target_by_num(strtoul(args[5], NULL, 0))) == NULL)
{ {
ERROR("target %lu not defined", strtoul(args[5], NULL, 0)); ERROR("target %lu not defined", strtoul(args[5], NULL, 0));
return ERROR_OK; return ERROR_OK;
} }
for (i = 0; flash_drivers[i]; i++) for (i = 0; flash_drivers[i]; i++)
{ {
if (strcmp(args[0], flash_drivers[i]->name) == 0) if (strcmp(args[0], flash_drivers[i]->name) == 0)
{ {
flash_bank_t *p, *c; flash_bank_t *p, *c;
/* register flash specific commands */ /* register flash specific commands */
if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK) if (flash_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)
{ {
ERROR("couldn't register '%s' commands", args[0]); ERROR("couldn't register '%s' commands", args[0]);
exit(-1); exit(-1);
} }
c = malloc(sizeof(flash_bank_t)); c = malloc(sizeof(flash_bank_t));
c->target = target; c->target = target;
c->driver = flash_drivers[i]; c->driver = flash_drivers[i];
@ -263,14 +263,14 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
c->num_sectors = 0; c->num_sectors = 0;
c->sectors = NULL; c->sectors = NULL;
c->next = NULL; c->next = NULL;
if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK) if (flash_drivers[i]->flash_bank_command(cmd_ctx, cmd, args, argc, c) != ERROR_OK)
{ {
ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base); ERROR("'%s' driver rejected flash bank at 0x%8.8x", args[0], c->base);
free(c); free(c);
return ERROR_OK; return ERROR_OK;
} }
/* put flash bank in linked list */ /* put flash bank in linked list */
if (flash_banks) if (flash_banks)
{ {
@ -283,18 +283,18 @@ int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char
{ {
flash_banks = c; flash_banks = c;
} }
found = 1; found = 1;
} }
} }
/* no matching flash driver found */ /* no matching flash driver found */
if (!found) if (!found)
{ {
ERROR("flash driver '%s' not found", args[0]); ERROR("flash driver '%s' not found", args[0]);
exit(-1); exit(-1);
} }
return ERROR_OK; return ERROR_OK;
} }
@ -302,19 +302,19 @@ int handle_flash_banks_command(struct command_context_s *cmd_ctx, char *cmd, cha
{ {
flash_bank_t *p; flash_bank_t *p;
int i = 0; int i = 0;
if (!flash_banks) if (!flash_banks)
{ {
command_print(cmd_ctx, "no flash banks configured"); command_print(cmd_ctx, "no flash banks configured");
return ERROR_OK; return ERROR_OK;
} }
for (p = flash_banks; p; p = p->next) for (p = flash_banks; p; p = p->next)
{ {
command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i", command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width); i++, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
} }
return ERROR_OK; return ERROR_OK;
} }
@ -323,34 +323,34 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
flash_bank_t *p; flash_bank_t *p;
int i = 0; int i = 0;
int j = 0; int j = 0;
if (argc != 1) if (argc != 1)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
for (p = flash_banks; p; p = p->next, i++) for (p = flash_banks; p; p = p->next, i++)
{ {
if (i == strtoul(args[0], NULL, 0)) if (i == strtoul(args[0], NULL, 0))
{ {
char buf[1024]; char buf[1024];
/* attempt auto probe */ /* attempt auto probe */
p->driver->auto_probe(p); p->driver->auto_probe(p);
command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i", command_print(cmd_ctx, "#%i: %s at 0x%8.8x, size 0x%8.8x, buswidth %i, chipwidth %i",
i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width); i, p->driver->name, p->base, p->size, p->bus_width, p->chip_width);
for (j = 0; j < p->num_sectors; j++) for (j = 0; j < p->num_sectors; j++)
{ {
char *erase_state, *protect_state; char *erase_state, *protect_state;
if (p->sectors[j].is_erased == 0) if (p->sectors[j].is_erased == 0)
erase_state = "not erased"; erase_state = "not erased";
else if (p->sectors[j].is_erased == 1) else if (p->sectors[j].is_erased == 1)
erase_state = "erased"; erase_state = "erased";
else else
erase_state = "erase state unknown"; erase_state = "erase state unknown";
if (p->sectors[j].is_protected == 0) if (p->sectors[j].is_protected == 0)
protect_state = "not protected"; protect_state = "not protected";
else if (p->sectors[j].is_protected == 1) else if (p->sectors[j].is_protected == 1)
@ -362,12 +362,12 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10, j, p->sectors[j].offset, p->sectors[j].size, p->sectors[j].size>>10,
erase_state, protect_state); erase_state, protect_state);
} }
p->driver->info(p, buf, 1024); p->driver->info(p, buf, 1024);
command_print(cmd_ctx, "%s", buf); command_print(cmd_ctx, "%s", buf);
} }
} }
return ERROR_OK; return ERROR_OK;
} }
@ -375,12 +375,12 @@ int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, cha
{ {
flash_bank_t *p; flash_bank_t *p;
int retval; int retval;
if (argc != 1) if (argc != 1)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0)); p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
if (p) if (p)
{ {
@ -403,7 +403,7 @@ int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, cha
{ {
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
} }
return ERROR_OK; return ERROR_OK;
} }
@ -411,12 +411,12 @@ int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cm
{ {
flash_bank_t *p; flash_bank_t *p;
int retval; int retval;
if (argc != 1) if (argc != 1)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (p) if (p)
{ {
@ -430,7 +430,7 @@ int handle_flash_erase_check_command(struct command_context_s *cmd_ctx, char *cm
args[0], p->base); args[0], p->base);
} }
} }
return ERROR_OK; return ERROR_OK;
} }
@ -442,14 +442,14 @@ int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *
int length; int length;
duration_t duration; duration_t duration;
char *duration_text; char *duration_text;
target_t *target = get_current_target(cmd_ctx); target_t *target = get_current_target(cmd_ctx);
if (argc != 2) if (argc != 2)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
address = strtoul(args[0], NULL, 0); address = strtoul(args[0], NULL, 0);
length = strtoul(args[1], NULL, 0); length = strtoul(args[1], NULL, 0);
if (length <= 0) if (length <= 0)
@ -463,19 +463,19 @@ int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
/* We can't know if we did a resume + halt, in which case we no longer know the erased state */ /* We can't know if we did a resume + halt, in which case we no longer know the erased state */
flash_set_dirty(); flash_set_dirty();
duration_start_measure(&duration); duration_start_measure(&duration);
if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK) if ((retval = flash_erase_address_range(target, address, length)) == ERROR_OK)
{ {
duration_stop_measure(&duration, &duration_text); duration_stop_measure(&duration, &duration_text);
command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text); command_print(cmd_ctx, "erased address 0x%8.8x length %i in %s", address, length, duration_text);
free(duration_text); free(duration_text);
} }
return retval; return retval;
} }
@ -483,12 +483,12 @@ int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *
{ {
flash_bank_t *p; flash_bank_t *p;
int retval; int retval;
if (argc != 1) if (argc != 1)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (p) if (p)
{ {
@ -509,7 +509,7 @@ int handle_flash_protect_check_command(struct command_context_s *cmd_ctx, char *
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
return ERROR_OK; return ERROR_OK;
} }
@ -523,18 +523,18 @@ int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, cha
flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
duration_t duration; duration_t duration;
char *duration_text; char *duration_text;
duration_start_measure(&duration); duration_start_measure(&duration);
if (!p) if (!p)
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK) if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)
{ {
duration_stop_measure(&duration, &duration_text); duration_stop_measure(&duration, &duration_text);
command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text); command_print(cmd_ctx, "erased sectors %i through %i on flash bank %i in %s", first, last, strtoul(args[0], 0, 0), duration_text);
free(duration_text); free(duration_text);
} }
@ -561,7 +561,7 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK; return ERROR_OK;
} }
if (strcmp(args[3], "on") == 0) if (strcmp(args[3], "on") == 0)
set = 1; set = 1;
else if (strcmp(args[3], "off") == 0) else if (strcmp(args[3], "off") == 0)
@ -570,7 +570,7 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
retval = flash_driver_protect(p, set, first, last); retval = flash_driver_protect(p, set, first, last);
if (retval == ERROR_OK) if (retval == ERROR_OK)
{ {
@ -589,13 +589,13 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c
int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{ {
target_t *target = get_current_target(cmd_ctx); target_t *target = get_current_target(cmd_ctx);
image_t image; image_t image;
u32 written; u32 written;
duration_t duration; duration_t duration;
char *duration_text; char *duration_text;
int retval; int retval;
if (argc < 1) if (argc < 1)
@ -603,15 +603,15 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (!target) if (!target)
{ {
ERROR("no target selected"); ERROR("no target selected");
return ERROR_OK; return ERROR_OK;
} }
duration_start_measure(&duration); duration_start_measure(&duration);
if (argc >= 2) if (argc >= 2)
{ {
image.base_address_set = 1; image.base_address_set = 1;
@ -622,7 +622,7 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
image.base_address_set = 0; image.base_address_set = 0;
image.base_address = 0x0; image.base_address = 0x0;
} }
image.start_address_set = 0; image.start_address_set = 0;
retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL); retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);
@ -631,7 +631,7 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
command_print(cmd_ctx, "image_open error: %s", image.error_str); command_print(cmd_ctx, "image_open error: %s", image.error_str);
return retval; return retval;
} }
retval = flash_write(target, &image, &written, auto_erase); retval = flash_write(target, &image, &written, auto_erase);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -639,7 +639,7 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
image_close(&image); image_close(&image);
return retval; return retval;
} }
duration_stop_measure(&duration, &duration_text); duration_stop_measure(&duration, &duration_text);
if (retval == ERROR_OK) if (retval == ERROR_OK)
{ {
@ -650,7 +650,7 @@ int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cm
free(duration_text); free(duration_text);
image_close(&image); image_close(&image);
return retval; return retval;
} }
@ -661,10 +661,10 @@ int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd
u32 buf_cnt; u32 buf_cnt;
fileio_t fileio; fileio_t fileio;
duration_t duration; duration_t duration;
char *duration_text; char *duration_text;
int retval; int retval;
flash_bank_t *p; flash_bank_t *p;
@ -672,9 +672,9 @@ int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd
{ {
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
duration_start_measure(&duration); duration_start_measure(&duration);
offset = strtoul(args[2], NULL, 0); offset = strtoul(args[2], NULL, 0);
p = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!p) if (!p)
@ -682,24 +682,24 @@ int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
return ERROR_OK; return ERROR_OK;
} }
if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
{ {
command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str); command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str);
return ERROR_OK; return ERROR_OK;
} }
buffer = malloc(fileio.size); buffer = malloc(fileio.size);
if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK) if (fileio_read(&fileio, fileio.size, buffer, &buf_cnt) != ERROR_OK)
{ {
command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str); command_print(cmd_ctx, "flash write_binary error: %s", fileio.error_str);
return ERROR_OK; return ERROR_OK;
} }
retval = flash_driver_write(p, buffer, offset, buf_cnt); retval = flash_driver_write(p, buffer, offset, buf_cnt);
free(buffer); free(buffer);
duration_stop_measure(&duration, &duration_text); duration_stop_measure(&duration, &duration_text);
if (retval!=ERROR_OK) if (retval!=ERROR_OK)
{ {
@ -710,7 +710,7 @@ int handle_flash_write_bank_command(struct command_context_s *cmd_ctx, char *cmd
free(duration_text); free(duration_text);
fileio_close(&fileio); fileio_close(&fileio);
return retval; return retval;
} }
@ -718,13 +718,13 @@ void flash_set_dirty(void)
{ {
flash_bank_t *c; flash_bank_t *c;
int i; int i;
/* set all flash to require erasing */ /* set all flash to require erasing */
for (c = flash_banks; c; c = c->next) for (c = flash_banks; c; c = c->next)
{ {
for (i = 0; i < c->num_sectors; i++) for (i = 0; i < c->num_sectors; i++)
{ {
c->sectors[i].is_erased = 0; c->sectors[i].is_erased = 0;
} }
} }
} }
@ -739,7 +739,7 @@ flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)
{ {
int retval; int retval;
retval = c->driver->auto_probe(c); retval = c->driver->auto_probe(c);
if (retval != ERROR_OK) if (retval != ERROR_OK)
{ {
ERROR("auto_probe failed %d\n", retval); ERROR("auto_probe failed %d\n", retval);
@ -760,30 +760,30 @@ int flash_erase_address_range(target_t *target, u32 addr, u32 length)
int first = -1; int first = -1;
int last = -1; int last = -1;
int i; int i;
if ((c = get_flash_bank_by_addr(target, addr)) == NULL) if ((c = get_flash_bank_by_addr(target, addr)) == NULL)
return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */ return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */
if (c->size == 0 || c->num_sectors == 0) if (c->size == 0 || c->num_sectors == 0)
return ERROR_FLASH_BANK_INVALID; return ERROR_FLASH_BANK_INVALID;
if (length == 0) if (length == 0)
{ {
/* special case, erase whole bank when length is zero */ /* special case, erase whole bank when length is zero */
if (addr != c->base) if (addr != c->base)
return ERROR_FLASH_DST_BREAKS_ALIGNMENT; return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
return flash_driver_erase(c, 0, c->num_sectors - 1); return flash_driver_erase(c, 0, c->num_sectors - 1);
} }
/* check whether it fits */ /* check whether it fits */
if (addr + length > c->base + c->size) if (addr + length > c->base + c->size)
return ERROR_FLASH_DST_BREAKS_ALIGNMENT; return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
addr -= c->base; addr -= c->base;
for (i = 0; i < c->num_sectors; i++) for (i = 0; i < c->num_sectors; i++)
{ {
/* check whether sector overlaps with the given range and is not yet erased */ /* check whether sector overlaps with the given range and is not yet erased */
if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) { if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) {
/* if first is not set yet then this is the first sector */ /* if first is not set yet then this is the first sector */
@ -792,10 +792,10 @@ int flash_erase_address_range(target_t *target, u32 addr, u32 length)
last = i; /* and it is the last one so far in any case */ last = i; /* and it is the last one so far in any case */
} }
} }
if( first == -1 || last == -1 ) if( first == -1 || last == -1 )
return ERROR_OK; return ERROR_OK;
return flash_driver_erase(c, first, last); return flash_driver_erase(c, first, last);
} }
@ -807,21 +807,21 @@ int flash_write(target_t *target, image_t *image, u32 *written, int erase)
int section; int section;
u32 section_offset; u32 section_offset;
flash_bank_t *c; flash_bank_t *c;
section = 0; section = 0;
section_offset = 0; section_offset = 0;
if (written) if (written)
*written = 0; *written = 0;
if (erase) if (erase)
{ {
/* assume all sectors need erasing - stops any problems /* assume all sectors need erasing - stops any problems
* when flash_write is called multiple times */ * when flash_write is called multiple times */
flash_set_dirty(); flash_set_dirty();
} }
/* loop until we reach end of the image */ /* loop until we reach end of the image */
while (section < image->num_sections) while (section < image->num_sections)
{ {
@ -876,17 +876,17 @@ int flash_write(target_t *target, image_t *image, u32 *written, int erase)
while (buffer_size < run_size) while (buffer_size < run_size)
{ {
u32 size_read; u32 size_read;
if (buffer_size - run_size <= image->sections[section].size - section_offset) if (buffer_size - run_size <= image->sections[section].size - section_offset)
size_read = buffer_size - run_size; size_read = buffer_size - run_size;
else else
size_read = image->sections[section].size - section_offset; size_read = image->sections[section].size - section_offset;
if ((retval = image_read_section(image, section, section_offset, if ((retval = image_read_section(image, section, section_offset,
size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0) size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
{ {
free(buffer); free(buffer);
return retval; return retval;
} }
@ -901,19 +901,19 @@ int flash_write(target_t *target, image_t *image, u32 *written, int erase)
} }
retval = ERROR_OK; retval = ERROR_OK;
if (erase) if (erase)
{ {
/* calculate and erase sectors */ /* calculate and erase sectors */
retval = flash_erase_address_range( target, run_address, run_size ); retval = flash_erase_address_range( target, run_address, run_size );
} }
if (retval == ERROR_OK) if (retval == ERROR_OK)
{ {
/* write flash sectors */ /* write flash sectors */
retval = flash_driver_write(c, buffer, run_address - c->base, run_size); retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
} }
free(buffer); free(buffer);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -935,13 +935,13 @@ int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (strcmp(args[0], "on") == 0) if (strcmp(args[0], "on") == 0)
auto_erase = 1; auto_erase = 1;
else if (strcmp(args[0], "off") == 0) else if (strcmp(args[0], "off") == 0)
auto_erase = 0; auto_erase = 0;
else else
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
return ERROR_OK; return ERROR_OK;
} }

View File

@ -1,8 +1,8 @@
INCLUDES = $(all_includes) INCLUDES = $(all_includes)
METASOURCES = AUTO METASOURCES = AUTO
AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@ AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@
noinst_LIBRARIES = libhelper.a noinst_LIBRARIES = libhelper.a
libhelper_a_SOURCES = binarybuffer.c configuration.c options.c log.c interpreter.c command.c time_support.c \ libhelper_a_SOURCES = binarybuffer.c configuration.c options.c log.c interpreter.c command.c time_support.c \
replacements.c fileio.c replacements.c fileio.c
noinst_HEADERS = binarybuffer.h configuration.h types.h log.h command.h \ noinst_HEADERS = binarybuffer.h configuration.h types.h log.h command.h \
interpreter.h time_support.h replacements.h fileio.h interpreter.h time_support.h replacements.h fileio.h

View File

@ -70,8 +70,8 @@ static void log_printfv(enum log_levels level, const char *file, int line, const
if (debug_level >= LOG_DEBUG) if (debug_level >= LOG_DEBUG)
{ {
/* print with count and time information */ /* print with count and time information */
int t=(int)(time(NULL)-start); int t=(int)(time(NULL)-start);
fprintf(log_output, "%s %d %d %s:%d %s(): %s\n", log_strings[level+1], count, t, file, line, function, buffer); fprintf(log_output, "%s %d %d %s:%d %s(): %s\n", log_strings[level+1], count, t, file, line, function, buffer);
} }
else else
{ {
@ -80,7 +80,7 @@ static void log_printfv(enum log_levels level, const char *file, int line, const
} }
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)
{ {
@ -101,7 +101,7 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f
va_start(args, format); va_start(args, format);
log_printfv(level, file, line, function, format, args); log_printfv(level, file, line, function, format, args);
va_end(args); va_end(args);
} }
void log_printfnl(enum log_levels level, const char *file, int line, const char *function, const char *format, ...) void log_printfnl(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
@ -109,11 +109,11 @@ void log_printfnl(enum log_levels level, const char *file, int line, const char
count++; count++;
if (level > debug_level) if (level > debug_level)
return; return;
char *t=malloc(strlen(format)+2); char *t=malloc(strlen(format)+2);
strcpy(t, format); strcpy(t, format);
strcat(t, "\n"); strcat(t, "\n");
va_list args; va_list args;
va_start(args, format); va_start(args, format);
log_printfv(level, file, line, function, t, args); log_printfv(level, file, line, function, t, args);
@ -148,7 +148,7 @@ int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char
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;
@ -174,15 +174,15 @@ 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;
@ -236,7 +236,7 @@ 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)
{ {
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;
@ -255,7 +255,7 @@ char *alloc_printf(const char *fmt, va_list ap)
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! */

View File

@ -46,7 +46,7 @@
static unsigned short gdb_port; static unsigned short gdb_port;
static const char *DIGITS = "0123456789abcdef"; static const char *DIGITS = "0123456789abcdef";
static void gdb_log_callback(void *priv, const char *file, int line, static void gdb_log_callback(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);
enum gdb_detach_mode enum gdb_detach_mode
@ -120,10 +120,10 @@ int gdb_get_char(connection_t *connection, int* next_char)
*/ */
struct timeval tv; struct timeval tv;
fd_set read_fds; fd_set read_fds;
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
FD_SET(connection->fd, &read_fds); FD_SET(connection->fd, &read_fds);
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
if (select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0) if (select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0)
@ -131,7 +131,7 @@ int gdb_get_char(connection_t *connection, int* next_char)
/* This can typically be because a "monitor" command took too long /* This can typically be because a "monitor" command took too long
* before printing any progress messages * before printing any progress messages
*/ */
return ERROR_GDB_TIMEOUT; return ERROR_GDB_TIMEOUT;
} }
#endif #endif
gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE); gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
@ -192,7 +192,7 @@ int gdb_get_char(connection_t *connection, int* next_char)
if (gdb_con->buf_cnt > 0) if (gdb_con->buf_cnt > 0)
connection->input_pending = 1; connection->input_pending = 1;
else else
connection->input_pending = 0; connection->input_pending = 0;
#ifdef _DEBUG_GDB_IO_ #ifdef _DEBUG_GDB_IO_
DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char); DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char);
#endif #endif
@ -211,7 +211,7 @@ int gdb_putback_char(connection_t *connection, int last_char)
} }
else else
{ {
ERROR("BUG: couldn't put character back"); ERROR("BUG: couldn't put character back");
} }
return ERROR_OK; return ERROR_OK;
@ -263,9 +263,9 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
if (len > 0) if (len > 0)
gdb_write(connection, buffer, len); gdb_write(connection, buffer, len);
gdb_write(connection, "#", 1); gdb_write(connection, "#", 1);
snprintf(checksum, 3, "%2.2x", my_checksum); snprintf(checksum, 3, "%2.2x", my_checksum);
gdb_write(connection, checksum, 2); gdb_write(connection, checksum, 2);
#else #else
void *allocated = NULL; void *allocated = NULL;
@ -287,9 +287,9 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
t[1 + len] = '#'; t[1 + len] = '#';
t[1 + len + 1] = DIGITS[(my_checksum >> 4) & 0xf]; t[1 + len + 1] = DIGITS[(my_checksum >> 4) & 0xf];
t[1 + len + 2] = DIGITS[my_checksum & 0xf]; t[1 + len + 2] = DIGITS[my_checksum & 0xf];
gdb_write(connection, t, totalLen); gdb_write(connection, t, totalLen);
if (allocated) if (allocated)
{ {
free(allocated); free(allocated);
@ -387,21 +387,21 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
} while (character != '$'); } while (character != '$');
my_checksum = 0; my_checksum = 0;
count = 0; count = 0;
gdb_connection_t *gdb_con = connection->priv; gdb_connection_t *gdb_con = connection->priv;
for (;;) for (;;)
{ {
/* The common case is that we have an entire packet with no escape chars. /* The common case is that we have an entire packet with no escape chars.
* We need to leave at least 2 bytes in the buffer to have * We need to leave at least 2 bytes in the buffer to have
* gdb_get_char() update various bits and bobs correctly. * gdb_get_char() update various bits and bobs correctly.
*/ */
if ((gdb_con->buf_cnt > 2) && ((gdb_con->buf_cnt+count) < *len)) if ((gdb_con->buf_cnt > 2) && ((gdb_con->buf_cnt+count) < *len))
{ {
/* The compiler will struggle a bit with constant propagation and /* The compiler will struggle a bit with constant propagation and
* aliasing, so we help it by showing that these values do not * aliasing, so we help it by showing that these values do not
* change inside the loop * change inside the loop
*/ */
int i; int i;
char *buf = gdb_con->buf_p; char *buf = gdb_con->buf_p;
int run = gdb_con->buf_cnt - 2; int run = gdb_con->buf_cnt - 2;
@ -413,13 +413,13 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
i++; i++;
if (character == '#') if (character == '#')
{ {
/* Danger! character can be '#' when esc is /* Danger! character can be '#' when esc is
* used so we need an explicit boolean for done here. * used so we need an explicit boolean for done here.
*/ */
done = 1; done = 1;
break; break;
} }
if (character == '}') if (character == '}')
{ {
/* data transmitted in binary mode (X packet) /* data transmitted in binary mode (X packet)
@ -437,15 +437,15 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
} }
gdb_con->buf_p += i; gdb_con->buf_p += i;
gdb_con->buf_cnt -= i; gdb_con->buf_cnt -= i;
if (done) if (done)
break; break;
} }
if (count > *len) if (count > *len)
{ {
ERROR("packet buffer too small"); ERROR("packet buffer too small");
return ERROR_GDB_BUFFER_TOO_SMALL; return ERROR_GDB_BUFFER_TOO_SMALL;
} }
if ((retval = gdb_get_char(connection, &character)) != ERROR_OK) if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
return retval; return retval;
@ -503,7 +503,7 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len)
gdb_con->busy = 0; gdb_con->busy = 0;
return retval; return retval;
} }
int gdb_output_con(connection_t *connection, char* line) int gdb_output_con(connection_t *connection, char* line)
{ {
char *hex_buffer; char *hex_buffer;
@ -527,7 +527,7 @@ int gdb_output_con(connection_t *connection, char* line)
int gdb_output(struct command_context_s *context, char* line) int gdb_output(struct command_context_s *context, char* line)
{ {
/* this will be dumped to the log and also sent as an O packet if possible */ /* this will be dumped to the log and also sent as an O packet if possible */
USER_SAMELINE(line); USER_SAMELINE(line);
return ERROR_OK; return ERROR_OK;
} }
@ -535,7 +535,7 @@ int gdb_program_handler(struct target_s *target, enum target_event event, void *
{ {
FILE *script; FILE *script;
struct command_context_s *cmd_ctx = priv; struct command_context_s *cmd_ctx = priv;
if (target->gdb_program_script) if (target->gdb_program_script)
{ {
script = open_file_from_path(cmd_ctx, target->gdb_program_script, "r"); script = open_file_from_path(cmd_ctx, target->gdb_program_script, "r");
@ -548,10 +548,10 @@ int gdb_program_handler(struct target_s *target, enum target_event event, void *
INFO("executing gdb_program script '%s'", target->gdb_program_script); INFO("executing gdb_program script '%s'", target->gdb_program_script);
command_run_file(cmd_ctx, script, COMMAND_EXEC); command_run_file(cmd_ctx, script, COMMAND_EXEC);
fclose(script); fclose(script);
jtag_execute_queue(); jtag_execute_queue();
} }
return ERROR_OK; return ERROR_OK;
} }
@ -566,10 +566,10 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event
{ {
case TARGET_EVENT_HALTED: case TARGET_EVENT_HALTED:
/* In the GDB protocol when we are stepping or coninuing execution, /* In the GDB protocol when we are stepping or coninuing execution,
* we have a lingering reply. Upon receiving a halted event * we have a lingering reply. Upon receiving a halted event
* when we have that lingering packet, we reply to the original * when we have that lingering packet, we reply to the original
* step or continue packet. * step or continue packet.
* *
* Executing monitor commands can bring the target in and * Executing monitor commands can bring the target in and
* out of the running state so we'll see lots of TARGET_EVENT_XXX * out of the running state so we'll see lots of TARGET_EVENT_XXX
* that are to be ignored. * that are to be ignored.
@ -578,7 +578,7 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event
{ {
/* stop forwarding log packets! */ /* stop forwarding log packets! */
log_remove_callback(gdb_log_callback, connection); log_remove_callback(gdb_log_callback, connection);
if (gdb_connection->ctrl_c) if (gdb_connection->ctrl_c)
{ {
signal = 0x2; signal = 0x2;
@ -603,8 +603,8 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event
return ERROR_OK; return ERROR_OK;
} }
int gdb_new_connection(connection_t *connection) int gdb_new_connection(connection_t *connection)
{ {
gdb_connection_t *gdb_connection = malloc(sizeof(gdb_connection_t)); gdb_connection_t *gdb_connection = malloc(sizeof(gdb_connection_t));
@ -622,12 +622,12 @@ int gdb_new_connection(connection_t *connection)
gdb_connection->vflash_image = NULL; gdb_connection->vflash_image = NULL;
gdb_connection->closed = 0; gdb_connection->closed = 0;
gdb_connection->busy = 0; gdb_connection->busy = 0;
/* output goes through gdb connection */ /* output goes through gdb connection */
command_set_output_handler(connection->cmd_ctx, gdb_output, connection); command_set_output_handler(connection->cmd_ctx, gdb_output, connection);
/* register callback to be informed about target events */ /* register callback to be informed about target events */
target_register_event_callback(gdb_target_callback_event_handler, connection); target_register_event_callback(gdb_target_callback_event_handler, connection);
/* a gdb session just attached, put the target in halt mode */ /* a gdb session just attached, put the target in halt mode */
if (((retval = gdb_service->target->type->halt(gdb_service->target)) != ERROR_OK) && if (((retval = gdb_service->target->type->halt(gdb_service->target)) != ERROR_OK) &&
@ -665,7 +665,7 @@ int gdb_connection_closed(connection_t *connection)
/* if this connection registered a debug-message receiver delete it */ /* if this connection registered a debug-message receiver delete it */
delete_debug_msg_receiver(connection->cmd_ctx, gdb_service->target); delete_debug_msg_receiver(connection->cmd_ctx, gdb_service->target);
if (connection->priv) if (connection->priv)
{ {
free(connection->priv); free(connection->priv);
@ -712,7 +712,7 @@ void gdb_str_to_target(target_t *target, char *tstr, reg_t *reg)
u8 *buf; u8 *buf;
int buf_len; int buf_len;
buf = reg->value; buf = reg->value;
buf_len = CEIL(reg->size, 8); buf_len = CEIL(reg->size, 8);
if (target->endianness == TARGET_LITTLE_ENDIAN) if (target->endianness == TARGET_LITTLE_ENDIAN)
{ {
@ -729,7 +729,7 @@ void gdb_str_to_target(target_t *target, char *tstr, reg_t *reg)
tstr[(buf_len-1-i)*2] = DIGITS[(buf[i]>>4)&0xf]; tstr[(buf_len-1-i)*2] = DIGITS[(buf[i]>>4)&0xf];
tstr[(buf_len-1-i)*2+1] = DIGITS[buf[i]&0xf]; tstr[(buf_len-1-i)*2+1] = DIGITS[buf[i]&0xf];
} }
} }
} }
void gdb_target_to_str(target_t *target, char *tstr, char *str) void gdb_target_to_str(target_t *target, char *tstr, char *str)
@ -757,7 +757,7 @@ void gdb_target_to_str(target_t *target, char *tstr, char *str)
{ {
str[i] = tstr[i]; str[i] = tstr[i];
} }
} }
} }
int gdb_get_registers_packet(connection_t *connection, target_t *target, char* packet, int packet_size) int gdb_get_registers_packet(connection_t *connection, target_t *target, char* packet, int packet_size)
@ -870,7 +870,7 @@ int gdb_set_registers_packet(connection_t *connection, target_t *target, char *p
bin_buf = malloc(CEIL(reg_list[i]->size, 8)); bin_buf = malloc(CEIL(reg_list[i]->size, 8));
str_to_buf(hex_buf, CEIL(reg_list[i]->size, 8) * 2, bin_buf, reg_list[i]->size, 16); str_to_buf(hex_buf, CEIL(reg_list[i]->size, 8) * 2, bin_buf, reg_list[i]->size, 16);
/* get register arch_type, and call set method */ /* get register arch_type, and call set method */
arch_type = register_get_arch_type(reg_list[i]->arch_type); arch_type = register_get_arch_type(reg_list[i]->arch_type);
if (arch_type == NULL) if (arch_type == NULL)
{ {
@ -879,14 +879,14 @@ int gdb_set_registers_packet(connection_t *connection, target_t *target, char *p
} }
arch_type->set(reg_list[i], bin_buf); arch_type->set(reg_list[i], bin_buf);
/* advance packet pointer */ /* advance packet pointer */
packet_p += (CEIL(reg_list[i]->size, 8) * 2); packet_p += (CEIL(reg_list[i]->size, 8) * 2);
free(bin_buf); free(bin_buf);
free(hex_buf); free(hex_buf);
} }
/* free reg_t *reg_list[] array allocated by get_gdb_reg_list */ /* free reg_t *reg_list[] array allocated by get_gdb_reg_list */
free(reg_list); free(reg_list);
gdb_put_packet(connection, "OK", 2); gdb_put_packet(connection, "OK", 2);
@ -985,7 +985,7 @@ int gdb_set_register_packet(connection_t *connection, target_t *target, char *pa
bin_buf = malloc(CEIL(reg_list[reg_num]->size, 8)); bin_buf = malloc(CEIL(reg_list[reg_num]->size, 8));
str_to_buf(hex_buf, CEIL(reg_list[reg_num]->size, 8) * 2, bin_buf, reg_list[reg_num]->size, 16); str_to_buf(hex_buf, CEIL(reg_list[reg_num]->size, 8) * 2, bin_buf, reg_list[reg_num]->size, 16);
/* get register arch_type, and call set method */ /* get register arch_type, and call set method */
arch_type = register_get_arch_type(reg_list[reg_num]->arch_type); arch_type = register_get_arch_type(reg_list[reg_num]->arch_type);
if (arch_type == NULL) if (arch_type == NULL)
{ {
@ -1030,7 +1030,7 @@ int gdb_memory_packet_error(connection_t *connection, int retval)
/* We don't have to worry about the default 2 second timeout for GDB packets, /* We don't have to worry about the default 2 second timeout for GDB packets,
* because GDB breaks up large memory reads into smaller reads. * because GDB breaks up large memory reads into smaller reads.
* *
* 8191 bytes by the looks of it. Why 8191 bytes instead of 8192????? * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192?????
*/ */
int gdb_read_memory_packet(connection_t *connection, target_t *target, char *packet, int packet_size) int gdb_read_memory_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
@ -1067,11 +1067,11 @@ int gdb_read_memory_packet(connection_t *connection, target_t *target, char *pac
{ {
/* TODO : Here we have to lie and send back all zero's lest stack traces won't work. /* TODO : Here we have to lie and send back all zero's lest stack traces won't work.
* At some point this might be fixed in GDB, in which case this code can be removed. * At some point this might be fixed in GDB, in which case this code can be removed.
* *
* OpenOCD developers are acutely aware of this problem, but there is nothing * OpenOCD developers are acutely aware of this problem, but there is nothing
* gained by involving the user in this problem that hopefully will get resolved * gained by involving the user in this problem that hopefully will get resolved
* eventually * eventually
* *
* http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395 * http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395
* *
* For now, the default is to fix up things to make current GDB versions work. * For now, the default is to fix up things to make current GDB versions work.
@ -1157,7 +1157,7 @@ int gdb_write_memory_packet(connection_t *connection, target_t *target, char *pa
else else
{ {
if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK) if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
return retval; return retval;
} }
free(buffer); free(buffer);
@ -1207,7 +1207,7 @@ int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, c
else else
{ {
if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK) if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
return retval; return retval;
} }
return ERROR_OK; return ERROR_OK;
@ -1362,14 +1362,14 @@ void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, .
return; return;
} }
int first = 1; int first = 1;
for (;;) for (;;)
{ {
if ((*xml == NULL) || (!first)) if ((*xml == NULL) || (!first))
{ {
/* start by 0 to exercise all the code paths. /* start by 0 to exercise all the code paths.
* Need minimum 2 bytes to fit 1 char and 0 terminator. */ * Need minimum 2 bytes to fit 1 char and 0 terminator. */
*size = *size * 2 + 2; *size = *size * 2 + 2;
char *t = *xml; char *t = *xml;
*xml = realloc(*xml, *size); *xml = realloc(*xml, *size);
@ -1381,7 +1381,7 @@ void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, .
return; return;
} }
} }
va_list ap; va_list ap;
int ret; int ret;
va_start(ap, fmt); va_start(ap, fmt);
@ -1400,7 +1400,7 @@ void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, .
static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len) static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len)
{ {
char *separator; char *separator;
/* Extract and NUL-terminate the annex. */ /* Extract and NUL-terminate the annex. */
*annex = buf; *annex = buf;
while (*buf && *buf != ':') while (*buf && *buf != ':')
@ -1408,17 +1408,17 @@ static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len
if (*buf == '\0') if (*buf == '\0')
return -1; return -1;
*buf++ = 0; *buf++ = 0;
/* After the read marker and annex, qXfer looks like a /* After the read marker and annex, qXfer looks like a
* traditional 'm' packet. */ * traditional 'm' packet. */
*ofs = strtoul(buf, &separator, 16); *ofs = strtoul(buf, &separator, 16);
if (*separator != ',') if (*separator != ',')
return -1; return -1;
*len = strtoul(separator+1, NULL, 16); *len = strtoul(separator+1, NULL, 16);
return 0; return 0;
} }
@ -1426,22 +1426,22 @@ int gdb_calc_blocksize(flash_bank_t *bank)
{ {
int i; int i;
int block_size = 0xffffffff; int block_size = 0xffffffff;
/* loop through all sectors and return smallest sector size */ /* loop through all sectors and return smallest sector size */
for (i = 0; i < bank->num_sectors; i++) for (i = 0; i < bank->num_sectors; i++)
{ {
if (bank->sectors[i].size < block_size) if (bank->sectors[i].size < block_size)
block_size = bank->sectors[i].size; block_size = bank->sectors[i].size;
} }
return block_size; return block_size;
} }
int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size) int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{ {
command_context_t *cmd_ctx = connection->cmd_ctx; command_context_t *cmd_ctx = connection->cmd_ctx;
if (strstr(packet, "qRcmd,")) if (strstr(packet, "qRcmd,"))
{ {
if (packet_size > 6) if (packet_size > 6)
@ -1456,7 +1456,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
cmd[i] = tmp; cmd[i] = tmp;
} }
cmd[(packet_size - 6)/2] = 0x0; cmd[(packet_size - 6)/2] = 0x0;
/* We want to print all debug output to GDB connection */ /* We want to print all debug output to GDB connection */
log_add_callback(gdb_log_callback, connection); log_add_callback(gdb_log_callback, connection);
target_call_timer_callbacks(); target_call_timer_callbacks();
@ -1476,22 +1476,22 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
u32 checksum; u32 checksum;
u32 addr = 0; u32 addr = 0;
u32 len = 0; u32 len = 0;
/* skip command character */ /* skip command character */
packet += 5; packet += 5;
addr = strtoul(packet, &separator, 16); addr = strtoul(packet, &separator, 16);
if (*separator != ',') if (*separator != ',')
{ {
ERROR("incomplete read memory packet received, dropping connection"); ERROR("incomplete read memory packet received, dropping connection");
return ERROR_SERVER_REMOTE_CLOSED; return ERROR_SERVER_REMOTE_CLOSED;
} }
len = strtoul(separator + 1, NULL, 16); len = strtoul(separator + 1, NULL, 16);
retval = target_checksum_memory(target, addr, len, &checksum); retval = target_checksum_memory(target, addr, len, &checksum);
if (retval == ERROR_OK) if (retval == ERROR_OK)
{ {
snprintf(gdb_reply, 10, "C%8.8x", checksum); snprintf(gdb_reply, 10, "C%8.8x", checksum);
@ -1500,9 +1500,9 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
else else
{ {
if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK) if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
return retval; return retval;
} }
return ERROR_OK; return ERROR_OK;
} }
} }
@ -1515,66 +1515,66 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
int pos = 0; int pos = 0;
int size = 0; int size = 0;
xml_printf(&retval, &buffer, &pos, &size, xml_printf(&retval, &buffer, &pos, &size,
"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-", "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-",
(GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-'); (GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-');
if (retval != ERROR_OK) if (retval != ERROR_OK)
{ {
gdb_send_error(connection, 01); gdb_send_error(connection, 01);
return ERROR_OK; return ERROR_OK;
} }
gdb_put_packet(connection, buffer, strlen(buffer)); gdb_put_packet(connection, buffer, strlen(buffer));
free(buffer); free(buffer);
return ERROR_OK; return ERROR_OK;
} }
else if (strstr(packet, "qXfer:memory-map:read::")) else if (strstr(packet, "qXfer:memory-map:read::"))
{ {
/* We get away with only specifying flash here. Regions that are not /* We get away with only specifying flash here. Regions that are not
* specified are treated as if we provided no memory map(if not we * specified are treated as if we provided no memory map(if not we
* could detect the holes and mark them as RAM). * could detect the holes and mark them as RAM).
* Normally we only execute this code once, but no big deal if we * Normally we only execute this code once, but no big deal if we
* have to regenerate it a couple of times. */ * have to regenerate it a couple of times. */
flash_bank_t *p; flash_bank_t *p;
char *xml = NULL; char *xml = NULL;
int size = 0; int size = 0;
int pos = 0; int pos = 0;
int retval = ERROR_OK; int retval = ERROR_OK;
int offset; int offset;
int length; int length;
char *separator; char *separator;
int blocksize; int blocksize;
/* skip command character */ /* skip command character */
packet += 23; packet += 23;
offset = strtoul(packet, &separator, 16); offset = strtoul(packet, &separator, 16);
length = strtoul(separator + 1, &separator, 16); length = strtoul(separator + 1, &separator, 16);
xml_printf(&retval, &xml, &pos, &size, "<memory-map>\n"); xml_printf(&retval, &xml, &pos, &size, "<memory-map>\n");
int i = 0; int i = 0;
for (;;) for (;;)
{ {
p = get_flash_bank_by_num(i); p = get_flash_bank_by_num(i);
if (p == NULL) if (p == NULL)
break; break;
/* if device has uneven sector sizes, eg. str7, lpc /* if device has uneven sector sizes, eg. str7, lpc
* we pass the smallest sector size to gdb memory map */ * we pass the smallest sector size to gdb memory map */
blocksize = gdb_calc_blocksize(p); blocksize = gdb_calc_blocksize(p);
xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \ xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
"<property name=\"blocksize\">0x%x</property>\n" \ "<property name=\"blocksize\">0x%x</property>\n" \
"</memory>\n", \ "</memory>\n", \
p->base, p->size, blocksize); p->base, p->size, blocksize);
i++; i++;
} }
xml_printf(&retval, &xml, &pos, &size, "</memory-map>\n"); xml_printf(&retval, &xml, &pos, &size, "</memory-map>\n");
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -1582,7 +1582,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
gdb_send_error(connection, retval); gdb_send_error(connection, retval);
return retval; return retval;
} }
if (offset + length > pos) if (offset + length > pos)
{ {
length = pos - offset; length = pos - offset;
@ -1592,52 +1592,52 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
t[0] = 'l'; t[0] = 'l';
memcpy(t + 1, xml + offset, length); memcpy(t + 1, xml + offset, length);
gdb_put_packet(connection, t, length + 1); gdb_put_packet(connection, t, length + 1);
free(t); free(t);
free(xml); free(xml);
return ERROR_OK; return ERROR_OK;
} }
else if (strstr(packet, "qXfer:features:read:")) else if (strstr(packet, "qXfer:features:read:"))
{ {
char *xml = NULL; char *xml = NULL;
int size = 0; int size = 0;
int pos = 0; int pos = 0;
int retval = ERROR_OK; int retval = ERROR_OK;
int offset; int offset;
unsigned int length; unsigned int length;
char *annex; char *annex;
/* skip command character */ /* skip command character */
packet += 20; packet += 20;
if (decode_xfer_read(packet, &annex, &offset, &length) < 0) if (decode_xfer_read(packet, &annex, &offset, &length) < 0)
{ {
gdb_send_error(connection, 01); gdb_send_error(connection, 01);
return ERROR_OK; return ERROR_OK;
} }
if (strcmp(annex, "target.xml") != 0) if (strcmp(annex, "target.xml") != 0)
{ {
gdb_send_error(connection, 01); gdb_send_error(connection, 01);
return ERROR_OK; return ERROR_OK;
} }
xml_printf(&retval, &xml, &pos, &size, \ xml_printf(&retval, &xml, &pos, &size, \
"l<target version=\"1.0\">\n<architecture>arm</architecture>\n</target>\n"); "l<target version=\"1.0\">\n<architecture>arm</architecture>\n</target>\n");
if (retval != ERROR_OK) if (retval != ERROR_OK)
{ {
gdb_send_error(connection, retval); gdb_send_error(connection, retval);
return retval; return retval;
} }
gdb_put_packet(connection, xml, strlen(xml) + 1); gdb_put_packet(connection, xml, strlen(xml) + 1);
free(xml); free(xml);
return ERROR_OK; return ERROR_OK;
} }
gdb_put_packet(connection, "", 0); gdb_put_packet(connection, "", 0);
return ERROR_OK; return ERROR_OK;
} }
@ -1649,18 +1649,18 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
int result; int result;
/* if flash programming disabled - send a empty reply */ /* if flash programming disabled - send a empty reply */
if (gdb_flash_program == 0) if (gdb_flash_program == 0)
{ {
gdb_put_packet(connection, "", 0); gdb_put_packet(connection, "", 0);
return ERROR_OK; return ERROR_OK;
} }
if (strstr(packet, "vFlashErase:")) if (strstr(packet, "vFlashErase:"))
{ {
unsigned long addr; unsigned long addr;
unsigned long length; unsigned long length;
char *parse = packet + 12; char *parse = packet + 12;
if (*parse == '\0') if (*parse == '\0')
{ {
@ -1683,14 +1683,14 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
ERROR("incomplete vFlashErase packet received, dropping connection"); ERROR("incomplete vFlashErase packet received, dropping connection");
return ERROR_SERVER_REMOTE_CLOSED; return ERROR_SERVER_REMOTE_CLOSED;
} }
/* assume all sectors need erasing - stops any problems /* assume all sectors need erasing - stops any problems
* when flash_write is called multiple times */ * when flash_write is called multiple times */
flash_set_dirty(); flash_set_dirty();
/* perform any target specific operations before the erase */ /* perform any target specific operations before the erase */
target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_PROGRAM); target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_PROGRAM);
/* perform erase */ /* perform erase */
if ((result = flash_erase_address_range(gdb_service->target, addr, length)) != ERROR_OK) if ((result = flash_erase_address_range(gdb_service->target, addr, length)) != ERROR_OK)
{ {
@ -1702,7 +1702,7 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
} }
else else
gdb_put_packet(connection, "OK", 2); gdb_put_packet(connection, "OK", 2);
return ERROR_OK; return ERROR_OK;
} }
@ -1724,7 +1724,7 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
return ERROR_SERVER_REMOTE_CLOSED; return ERROR_SERVER_REMOTE_CLOSED;
} }
length = packet_size - (parse - packet); length = packet_size - (parse - packet);
/* create a new image if there isn't already one */ /* create a new image if there isn't already one */
if (gdb_connection->vflash_image == NULL) if (gdb_connection->vflash_image == NULL)
{ {
@ -1758,11 +1758,11 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
DEBUG("wrote %u bytes from vFlash image to flash", written); DEBUG("wrote %u bytes from vFlash image to flash", written);
gdb_put_packet(connection, "OK", 2); gdb_put_packet(connection, "OK", 2);
} }
image_close(gdb_connection->vflash_image); image_close(gdb_connection->vflash_image);
free(gdb_connection->vflash_image); free(gdb_connection->vflash_image);
gdb_connection->vflash_image = NULL; gdb_connection->vflash_image = NULL;
return ERROR_OK; return ERROR_OK;
} }
@ -1777,30 +1777,30 @@ int gdb_detach(connection_t *connection, target_t *target)
case GDB_DETACH_RESUME: case GDB_DETACH_RESUME:
target->type->resume(target, 1, 0, 1, 0); target->type->resume(target, 1, 0, 1, 0);
break; break;
case GDB_DETACH_RESET: case GDB_DETACH_RESET:
target_process_reset(connection->cmd_ctx); target_process_reset(connection->cmd_ctx);
break; break;
case GDB_DETACH_HALT: case GDB_DETACH_HALT:
target->type->halt(target); target->type->halt(target);
break; break;
case GDB_DETACH_NOTHING: case GDB_DETACH_NOTHING:
break; break;
} }
gdb_put_packet(connection, "OK", 2); gdb_put_packet(connection, "OK", 2);
return ERROR_OK; return ERROR_OK;
} }
static void gdb_log_callback(void *priv, const char *file, int line, static void gdb_log_callback(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)
{ {
connection_t *connection = priv; connection_t *connection = priv;
gdb_connection_t *gdb_con = connection->priv; gdb_connection_t *gdb_con = connection->priv;
if (gdb_con->busy) if (gdb_con->busy)
{ {
/* do not reply this using the O packet */ /* do not reply this using the O packet */
@ -1810,9 +1810,9 @@ static void gdb_log_callback(void *priv, const char *file, int line,
char *t = alloc_printf(format, args); char *t = alloc_printf(format, args);
if (t == NULL) if (t == NULL)
return; return;
gdb_output_con(connection, t); gdb_output_con(connection, t);
free(t); free(t);
} }
@ -1846,7 +1846,7 @@ int gdb_input_inner(connection_t *connection)
switch (packet[0]) switch (packet[0])
{ {
case 'H': case 'H':
/* Hct... -- set thread /* Hct... -- set thread
* we don't have threads, send empty reply */ * we don't have threads, send empty reply */
gdb_put_packet(connection, NULL, 0); gdb_put_packet(connection, NULL, 0);
break; break;
@ -1881,7 +1881,7 @@ int gdb_input_inner(connection_t *connection)
case 'c': case 'c':
case 's': case 's':
{ {
/* We're running/stepping, in which case we can /* We're running/stepping, in which case we can
* forward log output until the target is halted */ * forward log output until the target is halted */
gdb_connection_t *gdb_con = connection->priv; gdb_connection_t *gdb_con = connection->priv;
gdb_con->frontend_state = TARGET_RUNNING; gdb_con->frontend_state = TARGET_RUNNING;
@ -2025,7 +2025,7 @@ int handle_gdb_detach_command(struct command_context_s *cmd_ctx, char *cmd, char
return ERROR_OK; return ERROR_OK;
} }
} }
WARNING("invalid gdb_detach configuration directive: %s", args[0]); WARNING("invalid gdb_detach configuration directive: %s", args[0]);
return ERROR_OK; return ERROR_OK;
} }
@ -2045,7 +2045,7 @@ int handle_gdb_memory_map_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_OK; return ERROR_OK;
} }
} }
WARNING("invalid gdb_memory_map configuration directive: %s", args[0]); WARNING("invalid gdb_memory_map configuration directive: %s", args[0]);
return ERROR_OK; return ERROR_OK;
} }
@ -2065,7 +2065,7 @@ int handle_gdb_flash_program_command(struct command_context_s *cmd_ctx, char *cm
return ERROR_OK; return ERROR_OK;
} }
} }
WARNING("invalid gdb_memory_map configuration directive: %s", args[0]); WARNING("invalid gdb_memory_map configuration directive: %s", args[0]);
return ERROR_OK; return ERROR_OK;
} }
@ -2085,7 +2085,7 @@ int handle_gdb_report_data_abort_command(struct command_context_s *cmd_ctx, char
return ERROR_OK; return ERROR_OK;
} }
} }
WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]); WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -1,23 +1,23 @@
if OOCD_TRACE if OOCD_TRACE
OOCD_TRACE_FILES = oocd_trace.c OOCD_TRACE_FILES = oocd_trace.c
else else
OOCD_TRACE_FILES = OOCD_TRACE_FILES =
endif endif
INCLUDES = -I$(top_srcdir)/src/gdb -I$(top_srcdir)/src/helper -I$(top_srcdir)/src/jtag -I$(top_srcdir)/src/xsvf $(all_includes) INCLUDES = -I$(top_srcdir)/src/gdb -I$(top_srcdir)/src/helper -I$(top_srcdir)/src/jtag -I$(top_srcdir)/src/xsvf $(all_includes)
METASOURCES = AUTO METASOURCES = AUTO
AM_CPPFLAGS = -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@ AM_CPPFLAGS = -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@
noinst_LIBRARIES = libtarget.a noinst_LIBRARIES = libtarget.a
libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \ libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \
arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \ arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \
arm966e.c arm926ejs.c feroceon.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c \ arm966e.c arm926ejs.c feroceon.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c \
etm_dummy.c $(OOCD_TRACE_FILES) target_request.c trace.c etm_dummy.c $(OOCD_TRACE_FILES) target_request.c trace.c
noinst_HEADERS = target.h trace.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \ noinst_HEADERS = target.h trace.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \
arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \ arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \
arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h \ arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h \
etm_dummy.h oocd_trace.h target_request.h trace.h etm_dummy.h oocd_trace.h target_request.h trace.h
nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.cfg target/at91eb40a.cfg nobase_dist_pkglib_DATA = xscale/debug_handler.bin event/at91eb40a_reset.cfg target/at91eb40a.cfg

View File

@ -1,8 +1,8 @@
# Reset script for AT91EB40a # Reset script for AT91EB40a
reg cpsr 0x000000D3 reg cpsr 0x000000D3
mww 0xFFE00020 0x1 mww 0xFFE00020 0x1
mww 0xFFE00024 0x00000000 mww 0xFFE00024 0x00000000
mww 0xFFE00000 0x01002539 mww 0xFFE00000 0x01002539
mww 0xFFFFF124 0xFFFFFFFF mww 0xFFFFF124 0xFFFFFFFF
mww 0xffff0010 0x100 mww 0xffff0010 0x100
mww 0xffff0034 0x100 mww 0xffff0034 0x100

View File

@ -1,34 +1,34 @@
#Script for AT91EB40a #Script for AT91EB40a
#Atmel ties SRST & TRST together, at which point it makes #Atmel ties SRST & TRST together, at which point it makes
#no sense to use TRST, but use TMS instead. #no sense to use TRST, but use TMS instead.
# #
#The annoying thing with tying SRST & TRST together is that #The annoying thing with tying SRST & TRST together is that
#there is no way to halt the CPU *before and during* the #there is no way to halt the CPU *before and during* the
#SRST reset, which means that the CPU will run a number #SRST reset, which means that the CPU will run a number
#of cycles before it can be halted(as much as milliseconds). #of cycles before it can be halted(as much as milliseconds).
reset_config srst_only srst_pulls_trst reset_config srst_only srst_pulls_trst
#jtag scan chain #jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) #format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 4 0x1 0xf 0xe jtag_device 4 0x1 0xf 0xe
#target configuration #target configuration
#target arm7tdmi <endianness> <reset mode> <chainpos> <variant> #target arm7tdmi <endianness> <reset mode> <chainpos> <variant>
target arm7tdmi little reset_init 0 arm7tdmi-s_r4 target arm7tdmi little reset_init 0 arm7tdmi-s_r4
# speed up memory downloads # speed up memory downloads
arm7 fast_memory_access enable arm7 fast_memory_access enable
arm7_9 dcc_downloads enable arm7_9 dcc_downloads enable
# OpenOCD does not have a flash driver for for AT91FR40162S # OpenOCD does not have a flash driver for for AT91FR40162S
target_script 0 reset event/at91eb40a_reset.cfg target_script 0 reset event/at91eb40a_reset.cfg
# required for usable performance. Used for lots of # required for usable performance. Used for lots of
# other things than flash programming. # other things than flash programming.
working_area 0 0x00000000 0x20000 nobackup working_area 0 0x00000000 0x20000 nobackup
#force hardware values - we're running out of flash more #force hardware values - we're running out of flash more
#often than not. The user can disable this in his #often than not. The user can disable this in his
#subsequent config script. #subsequent config script.
arm7_9 force_hw_bkpts enable arm7_9 force_hw_bkpts enable

0
src/target/xscale/build.sh Normal file → Executable file
View File

View File

@ -1,80 +1,80 @@
<html> <html>
<body> <body>
<h1>Testing</h1> <h1>Testing</h1>
A test should be done on code committed to svn. Commit, then test. That way A test should be done on code committed to svn. Commit, then test. That way
one can know for sure *what* code was actually tested. one can know for sure *what* code was actually tested.
<h1>Release procedure</h1> <h1>Release procedure</h1>
OpenOCD trunk is work in progress. Expect it to change daily and to have OpenOCD trunk is work in progress. Expect it to change daily and to have
some work in progress. some work in progress.
<p> <p>
If you need the latest released and tested version, look for binary snapshots of If you need the latest released and tested version, look for binary snapshots of
OpenOCD. Worst case look up the test result table below for the features OpenOCD. Worst case look up the test result table below for the features
that are important to you and extract and build the version that has the right that are important to you and extract and build the version that has the right
cocktail of working features for you. You can also work with the community cocktail of working features for you. You can also work with the community
to address the problems you are seing. Testing work and bug reports are to address the problems you are seing. Testing work and bug reports are
highly appreciated. highly appreciated.
<p> <p>
The OpenOCD community may decide to create release branches. If The OpenOCD community may decide to create release branches. If
this happens, then a branch will be created from OpenOCD trunk. The particular this happens, then a branch will be created from OpenOCD trunk. The particular
version to create that branch might be an older version rather than the latest version to create that branch might be an older version rather than the latest
and greatest. Fixes are then ported to that release branch from OpenOCD trunk. and greatest. Fixes are then ported to that release branch from OpenOCD trunk.
<h2>Vocabulary</h2> <h2>Vocabulary</h2>
<table border=1> <table border=1>
<tr><td>Passed version</td><td>The latest version on which the test is known to pass</td></tr> <tr><td>Passed version</td><td>The latest version on which the test is known to pass</td></tr>
<tr><td>Broken version</td><td>The latest version on which the test is known to fail. n/a when older than passed version.</td></tr> <tr><td>Broken version</td><td>The latest version on which the test is known to fail. n/a when older than passed version.</td></tr>
<tr><td>ID</td><td>A unqiue ID to refer to a test. The unique numbers are maintained in this file.</td></tr> <tr><td>ID</td><td>A unqiue ID to refer to a test. The unique numbers are maintained in this file.</td></tr>
</table> </table>
<h1>OpenOCD test results</h1> <h1>OpenOCD test results</h1>
These tests can be performed on any JTAG device as long These tests can be performed on any JTAG device as long
as they are executed using the unmodified code from SVN. as they are executed using the unmodified code from SVN.
<p> <p>
The latest version in which the test is known to have The latest version in which the test is known to have
passed is in the table below. passed is in the table below.
<table border=1> <table border=1>
<tr><th>ID</th><th>Synopsis</th><th>Passed version</th><th>Broken version</th></tr> <tr><th>ID</th><th>Synopsis</th><th>Passed version</th><th>Broken version</th></tr>
<tr><td>ocd1</td><td>Telnet Windows</td><td>291</td><td>n/a</td></tr> <tr><td>ocd1</td><td>Telnet Windows</td><td>291</td><td>n/a</td></tr>
<tr><td>ocd2</td><td>Telnet Linux</td><td>291</td><td>n/a</td></tr> <tr><td>ocd2</td><td>Telnet Linux</td><td>291</td><td>n/a</td></tr>
<tr><td>ocd3</td><td>Telnet Cygwin</td><td>291</td><td>n/a</td></tr> <tr><td>ocd3</td><td>Telnet Cygwin</td><td>291</td><td>n/a</td></tr>
<tr><td><a href="#test_ocd4">ocd4</a></td><td>ARM7 debugging</td><td>291</td></tr> <tr><td><a href="#test_ocd4">ocd4</a></td><td>ARM7 debugging</td><td>291</td></tr>
<tr><td>xscale1</a></td><td>XScale debugging</td><td>291</td></tr> <tr><td>xscale1</a></td><td>XScale debugging</td><td>291</td></tr>
<tr><td>xscale2</a></td><td>XScale MMU</td><td>291</td></tr> <tr><td>xscale2</a></td><td>XScale MMU</td><td>291</td></tr>
</table> </table>
<h1>OpenOCD JTAG device test results</h1> <h1>OpenOCD JTAG device test results</h1>
Each JTAG device must be tested Each JTAG device must be tested
<table border=1> <table border=1>
<tr><th>ID</th><th>Synopsis</th><th>Passed version</th><th>Broken version</th></tr> <tr><th>ID</th><th>Synopsis</th><th>Passed version</th><th>Broken version</th></tr>
<tr><td>jtag1</td><td>Wiggler</td><td>291</td><td>n/a</td></tr> <tr><td>jtag1</td><td>Wiggler</td><td>291</td><td>n/a</td></tr>
<tr><td>jtag2</td><td>Parport</td><td>291</td><td>n/a</td></tr> <tr><td>jtag2</td><td>Parport</td><td>291</td><td>n/a</td></tr>
<tr><td>jtag3</td><td>...</td><td>291</td><td>n/a</td></tr> <tr><td>jtag3</td><td>...</td><td>291</td><td>n/a</td></tr>
</table> </table>
<h1>Policy on removing features from OpenOCD</h1> <h1>Policy on removing features from OpenOCD</h1>
If a feature in OpenOCD is known to be broken and nobody has If a feature in OpenOCD is known to be broken and nobody has
submitted a fix and the feature is causing trouble for submitted a fix and the feature is causing trouble for
maintainence, it can be removed from OpenOCD trunk. The threshold maintainence, it can be removed from OpenOCD trunk. The threshold
for temporarily removing something from OpenOCD trunk is low to for temporarily removing something from OpenOCD trunk is low to
ease maintainence and place the burden of maintainence on ease maintainence and place the burden of maintainence on
those that care about a feature. those that care about a feature.
<p> <p>
Note that code is never deleted from OpenOCD svn, it remains Note that code is never deleted from OpenOCD svn, it remains
in svn so if somebody sees a feature removed that they would in svn so if somebody sees a feature removed that they would
like kept, they have but to port and fix that feature like kept, they have but to port and fix that feature
back up to main trunk. This document can be helpful in this back up to main trunk. This document can be helpful in this
regard in that the latest working version and the known broken regard in that the latest working version and the known broken
version may be listed. version may be listed.
<h1>Policy on adding features from OpenOCD</h1> <h1>Policy on adding features from OpenOCD</h1>
To add a feature to OpenOCD, generally it should not break any existing To add a feature to OpenOCD, generally it should not break any existing
features and it should be functional and the code reasonably readable features and it should be functional and the code reasonably readable
and useful to others in the OpenOCD community. The code does not and useful to others in the OpenOCD community. The code does not
have to be completed. Work in progress is fine for OpenOCD trunk. have to be completed. Work in progress is fine for OpenOCD trunk.
<p> <p>
Also new tests should be defined. Note that the code does not have Also new tests should be defined. Note that the code does not have
to pass all the tests. In fact it can be helpful to have tests to pass all the tests. In fact it can be helpful to have tests
to describe facets that really should be working, but aren't to describe facets that really should be working, but aren't
done yet. done yet.
<a name="test_ocd4"> <a name="test_ocd4">
<h1>ocd4 - ARM7 debugging</h1> <h1>ocd4 - ARM7 debugging</h1>
Connect to ARM7 device(any), use GDB load to load a program into RAM and single halt, resume and single step. Connect to ARM7 device(any), use GDB load to load a program into RAM and single halt, resume and single step.
</body> </body>
</html> </html>