From ef139a3a5e41fbcbabdf4be0ecbbb5591448ad2e Mon Sep 17 00:00:00 2001 From: drath Date: Fri, 23 Jun 2006 07:54:01 +0000 Subject: - added support for AT91SAM7A3 flash (patch from andre renaud, thanks) - fix trunk build for mac os x (patch from Lauri Leukkunen, thanks) - added check for host endianness, defines WORDS_BIGENDIAN on a big-endian host (e.g. mac os-x) - fixed bug where endianness of memory accesses could be swapped on BE hosts - added space for zero termination of ftd2xx_layout string (from Magnus Ludin, tahnks) git-svn-id: svn://svn.berlios.de/openocd/trunk@73 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- configure.in | 4 ++++ src/flash/at91sam7.c | 32 ++++++++++++++++++++++------- src/helper/types.h | 51 +++++++++++++++++++++++++++++++++++++++++++++- src/jtag/ftd2xx.c | 2 +- src/jtag/jtag.h | 2 +- src/server/gdb_server.c | 5 ++++- src/target/arm7_9_common.c | 30 ++++++++++----------------- src/target/target.c | 36 ++++++++++++++++++++++++++++++++ src/target/target.h | 5 +++++ 9 files changed, 137 insertions(+), 30 deletions(-) diff --git a/configure.in b/configure.in index db37806..8de2b83 100644 --- a/configure.in +++ b/configure.in @@ -4,6 +4,10 @@ AC_SEARCH_LIBS([ioperm], [ioperm]) AC_CANONICAL_HOST +AC_C_BIGENDIAN + +AC_CHECK_FUNCS(strndup) + build_bitbang=no is_cygwin=no diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c index 8a602a3..348a865 100644 --- a/src/flash/at91sam7.c +++ b/src/flash/at91sam7.c @@ -244,7 +244,8 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) at91sam7_info->lockbits = status>>16; at91sam7_info->securitybit = (status>>4)&0x01; - if (at91sam7_info->cidr_arch == 0x70 ) { + if (at91sam7_info->cidr_arch == 0x70 ) + { at91sam7_info->num_nvmbits = 2; at91sam7_info->nvmbits = (status>>8)&0x03; bank->base = 0x100000; @@ -281,7 +282,8 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) return ERROR_OK; } - if (at91sam7_info->cidr_arch == 0x71 ) { + if (at91sam7_info->cidr_arch == 0x71 ) + { at91sam7_info->num_nvmbits = 2; at91sam7_info->nvmbits = (status>>8)&0x03; bank->base = 0x100000; @@ -304,7 +306,8 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) return ERROR_OK; } - if (at91sam7_info->cidr_arch == 0x75 ) { + if (at91sam7_info->cidr_arch == 0x75 ) + { at91sam7_info->num_nvmbits = 3; at91sam7_info->nvmbits = (status>>8)&0x07; bank->base = 0x100000; @@ -327,11 +330,26 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) return ERROR_OK; } - if (at91sam7_info->cidr_arch != 0x70 ) + if (at91sam7_info->cidr_arch == 0x60 ) { - WARNING("at91sam7 flash only tested for AT91SAM7Sxx series"); + at91sam7_info->num_nvmbits = 3; + at91sam7_info->nvmbits = (status>>8)&0x07; + bank->base = 0x100000; + bank->bus_width = 4; + + if (bank->size == 0x40000) /* AT91SAM7A3 */ + { + at91sam7_info->num_lockbits = 16; + at91sam7_info->pagesize = 256; + at91sam7_info->pages_in_lockregion = 64; + at91sam7_info->num_pages = 16*64; + } + return ERROR_OK; } - return ERROR_OK; + + WARNING("at91sam7 flash only tested for AT91SAM7Sxx series"); + + return ERROR_OK; } int at91sam7_erase_check(struct flash_bank_s *bank) @@ -377,7 +395,7 @@ int at91sam7_protect_check(struct flash_bank_s *bank) int at91sam7_register_commands(struct command_context_s *cmd_ctx) { - command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL); + command_t *at91sam7_cmd = register_command(cmd_ctx, NULL, "at91sam7", NULL, COMMAND_ANY, "at91sam7 specific commands"); return ERROR_OK; } diff --git a/src/helper/types.h b/src/helper/types.h index 6d49bbb..90f4939 100644 --- a/src/helper/types.h +++ b/src/helper/types.h @@ -17,10 +17,11 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ - #ifndef TYPES_H #define TYPES_H +#include "config.h" + #ifndef u8 typedef unsigned char u8; #endif @@ -33,4 +34,52 @@ typedef unsigned short u16; typedef unsigned int u32; #endif +#ifdef WORDS_BIGENDIAN /* big endian host */ + +#define le_to_h_u32(x) (u32)(x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24) +#define le_to_h_u16(x) (u16)(x[0] | x[1] << 8) +#define be_to_h_u32(x) (*(u32*)(x)) +#define be_to_h_u16(x) (*(u16*)(x)) + +#define h_u32_to_le(buf, val) \ + do { \ + buf[3] = (val & 0xff000000) >> 24; \ + buf[2] = (val & 0x00ff0000) >> 16; \ + buf[1] = (val & 0x0000ff00) >> 8; \ + buf[0] = (val & 0x000000ff); \ + } while (0) + +#define h_u16_to_le(buf, val) \ + do { \ + buf[0] = (val & 0xff000) >> 8; \ + buf[1] = (val & 0x00ff); \ + } while (0) + +#define h_u32_to_be(buf, val) do { *(u32*)(buf) = (val); } while (0) +#define h_u16_to_be(buf, val) do { *(u16*)(buf) = (val); } while (0) + +#else /* little endian host */ +#define le_to_h_u32(x) (*(u32*)(x)) +#define le_to_h_u16(x) (*(u16*)(x)) +#define be_to_h_u32(x) (u32)(x[3] | x[2] << 8 | x[1] << 16 | x[0] << 24) +#define be_to_h_u16(x) (u16)(x[1] | x[0] << 8) + +#define h_u32_to_le(buf, val) do { *(u32*)(buf) = (val); } while (0) +#define h_u16_to_le(buf, val) do { *(u16*)(buf) = (val); } while (0) + +#define h_u32_to_be(buf, val) \ + do { \ + buf[0] = (val & 0xff000000) >> 24; \ + buf[1] = (val & 0x00ff0000) >> 16; \ + buf[2] = (val & 0x0000ff00) >> 8; \ + buf[3] = (val & 0x000000ff); \ + } while (0) + +#define h_u16_to_be(buf, val) \ + do { \ + buf[0] = (val & 0xff000) >> 8; \ + buf[1] = (val & 0x00ff); \ + } while (0) +#endif + #endif /* TYPES_H */ diff --git a/src/jtag/ftd2xx.c b/src/jtag/ftd2xx.c index c73c8d5..a14d039 100644 --- a/src/jtag/ftd2xx.c +++ b/src/jtag/ftd2xx.c @@ -982,7 +982,7 @@ int ftd2xx_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, c if (argc == 0) return ERROR_OK; - ftd2xx_layout = malloc(strlen(args[0])); + ftd2xx_layout = malloc(strlen(args[0]) + 1); strcpy(ftd2xx_layout, args[0]); return ERROR_OK; diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 124150c..a2cc01b 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -25,7 +25,7 @@ #include "command.h" -#if 0 +#if 1 #define _DEBUG_JTAG_IO_ #endif diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 125206d..e8664bb 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -17,6 +17,8 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include "config.h" + #include "gdb_server.h" #include "server.h" @@ -31,7 +33,7 @@ #include // -ino: 060521-1116 -#ifdef __FreeBSD__ +#ifndef HAVE_STRNDUP #include char * strndup(char * str, int n) { unsigned char * tmp = malloc((size_t)n+1); @@ -40,6 +42,7 @@ char * strndup(char * str, int n) { return tmp; } #endif + #if 0 #define _DEBUG_GDB_IO_ #endif diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index d167041..e0ccd7a 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -1610,9 +1610,6 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count u32 *reg_p[16]; int num_accesses = 0; int thisrun_accesses; - u32 *buf32; - u16 *buf16; - u8 *buf8; int i; u32 cpsr; int retval; @@ -1645,7 +1642,6 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count switch (size) { case 4: - buf32 = (u32*)buffer; while (num_accesses < count) { u32 reg_list; @@ -1662,13 +1658,13 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count { if (i > last_reg) last_reg = i; - *(buf32++) = reg[i]; + target_buffer_set_u32(target, buffer, reg[i]); + buffer += 4; } num_accesses += thisrun_accesses; } break; case 2: - buf16 = (u16*)buffer; while (num_accesses < count) { u32 reg_list; @@ -1688,13 +1684,13 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count for (i = 1; i <= thisrun_accesses; i++) { - *(buf16++) = reg[i] & 0xffff; + target_buffer_set_u16(target, buffer, reg[i]); + buffer += 2; } num_accesses += thisrun_accesses; } break; case 1: - buf8 = buffer; while (num_accesses < count) { u32 reg_list; @@ -1714,7 +1710,7 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count for (i = 1; i <= thisrun_accesses; i++) { - *(buf8++) = reg[i] & 0xff; + *(buffer++) = reg[i] & 0xff; } num_accesses += thisrun_accesses; } @@ -1755,9 +1751,6 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun u32 reg[16]; int num_accesses = 0; int thisrun_accesses; - u32 *buf32; - u16 *buf16; - u8 *buf8; int i; u32 cpsr; int retval; @@ -1785,7 +1778,6 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun switch (size) { case 4: - buf32 = (u32*)buffer; while (num_accesses < count) { u32 reg_list; @@ -1796,7 +1788,8 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun { if (i > last_reg) last_reg = i; - reg[i] = *buf32++; + reg[i] = target_buffer_get_u32(target, buffer); + buffer += 4; } arm7_9->write_core_regs(target, reg_list, reg); @@ -1815,7 +1808,6 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun } break; case 2: - buf16 = (u16*)buffer; while (num_accesses < count) { u32 reg_list; @@ -1826,7 +1818,8 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun { if (i > last_reg) last_reg = i; - reg[i] = *buf16++ & 0xffff; + reg[i] = target_buffer_get_u16(target, buffer) & 0xffff; + buffer += 2; } arm7_9->write_core_regs(target, reg_list, reg); @@ -1848,7 +1841,6 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun } break; case 1: - buf8 = buffer; while (num_accesses < count) { u32 reg_list; @@ -1859,7 +1851,7 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun { if (i > last_reg) last_reg = i; - reg[i] = *buf8++ & 0xff; + reg[i] = *buffer++ & 0xff; } arm7_9->write_core_regs(target, reg_list, reg); @@ -1955,7 +1947,7 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe for (i = 0; i < count; i++) { - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], buf_get_u32(buffer, 0, 32)); + embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], target_buffer_get_u32(target, buffer)); buffer += 4; } diff --git a/src/target/target.c b/src/target/target.c index 98407af..34dc60a 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -111,6 +111,42 @@ enum daemon_startup_mode startup_mode = DAEMON_ATTACH; static int target_continous_poll = 1; +/* read a u32 from a buffer in target memory endianness */ +u32 target_buffer_get_u32(target_t *target, u8 *buffer) +{ + if (target->endianness == TARGET_LITTLE_ENDIAN) + return le_to_h_u32(buffer); + else + return be_to_h_u32(buffer); +} + +/* read a u16 from a buffer in target memory endianness */ +u16 target_buffer_get_u16(target_t *target, u8 *buffer) +{ + if (target->endianness == TARGET_LITTLE_ENDIAN) + return le_to_h_u16(buffer); + else + return be_to_h_u16(buffer); +} + +/* write a u32 to a buffer in target memory endianness */ +void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value) +{ + if (target->endianness == TARGET_LITTLE_ENDIAN) + h_u32_to_le(buffer, value); + else + h_u32_to_be(buffer, value); +} + +/* write a u16 to a buffer in target memory endianness */ +void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value) +{ + if (target->endianness == TARGET_LITTLE_ENDIAN) + h_u16_to_le(buffer, value); + else + h_u16_to_be(buffer, value); +} + /* returns a pointer to the n-th configured target */ target_t* get_target_by_num(int num) { diff --git a/src/target/target.h b/src/target/target.h index 6d3b6d1..dc6d8ce 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -217,6 +217,11 @@ extern target_t *targets; extern target_event_callback_t *target_event_callbacks; extern target_timer_callback_t *target_timer_callbacks; +extern u32 target_buffer_get_u32(target_t *target, u8 *buffer); +extern u16 target_buffer_get_u16(target_t *target, u8 *buffer); +extern void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value); +extern void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value); + #define ERROR_TARGET_INVALID (-300) #define ERROR_TARGET_INIT_FAILED (-301) #define ERROR_TARGET_TIMEOUT (-302) -- cgit v1.1