static int aduc702x_build_sector_list(struct flash_bank_s *bank)
{
//aduc7026_flash_bank_t *aduc7026_info = bank->driver_priv;
-
+
int i = 0;
uint32_t offset = 0;
-
+
// sector size is 512
bank->num_sectors = bank->size / 512;
bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
reg_param_t reg_params[6];
armv4_5_algorithm_t armv4_5_info;
int retval = ERROR_OK;
-
+
/* parameters:
r0 - address of source data (absolute)
//<done>:
0xeafffffe // b 1003c <done>
};
-
+
/* flash write code */
if (target_alloc_working_area(target, sizeof(aduc702x_flash_write_code),
&aduc702x_info->write_algorithm) != ERROR_OK)
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
};
-
- target_write_buffer(target, aduc702x_info->write_algorithm->address,
+
+ target_write_buffer(target, aduc702x_info->write_algorithm->address,
sizeof(aduc702x_flash_write_code), (uint8_t*)aduc702x_flash_write_code);
/* memory buffer */
/* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
if (aduc702x_info->write_algorithm)
target_free_working_area(target, aduc702x_info->write_algorithm);
-
+
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
}
-
+
armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
-
+
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
init_reg_param(®_params[2], "r2", 32, PARAM_OUT);
init_reg_param(®_params[3], "r3", 32, PARAM_IN);
init_reg_param(®_params[4], "r4", 32, PARAM_OUT);
-
+
while (count > 0)
{
uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
-
+
target_write_buffer(target, source->address, thisrun_count * 2, buffer);
buf_set_u32(reg_params[0].value, 0, 32, source->address);
buf_set_u32(reg_params[2].value, 0, 32, address);
buf_set_u32(reg_params[4].value, 0, 32, 0xFFFFF800);
- if ((retval = target_run_algorithm(target, 0, NULL, 5,
- reg_params, aduc702x_info->write_algorithm->address,
- aduc702x_info->write_algorithm->address + sizeof(aduc702x_flash_write_code) - 4,
+ if ((retval = target_run_algorithm(target, 0, NULL, 5,
+ reg_params, aduc702x_info->write_algorithm->address,
+ aduc702x_info->write_algorithm->address + sizeof(aduc702x_flash_write_code) - 4,
10000, &armv4_5_info)) != ERROR_OK)
{
LOG_ERROR("error executing aduc702x flash write algorithm");
retval = ERROR_FLASH_OPERATION_FAILED;
break;
}
-
+
if ((buf_get_u32(reg_params[3].value, 0, 32) & 1) != 1) {
retval = ERROR_FLASH_OPERATION_FAILED;
break;
target_free_working_area(target, source);
target_free_working_area(target, aduc702x_info->write_algorithm);
-
+
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
destroy_reg_param(®_params[3]);
destroy_reg_param(®_params[4]);
-
+
return retval;
}
-/* All-JTAG, single-access method. Very slow. Used only if there is no
+/* All-JTAG, single-access method. Very slow. Used only if there is no
* working area available. */
static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
{
uint32_t x;
uint8_t b;
target_t *target = bank->target;
-
+
aduc702x_set_write_enable(target, 1);
for (x = 0; x < count; x += 2) {
if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
{
/* if block write failed (no sufficient working area),
- * use normal (slow) JTAG method */
+ * use normal (slow) JTAG method */
LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
if ((retval = aduc702x_write_single(bank, buffer, offset, count)) != ERROR_OK)
{
LOG_ERROR("slow write failed");
- return ERROR_FLASH_OPERATION_FAILED;
+ return ERROR_FLASH_OPERATION_FAILED;
}
}
else if (retval == ERROR_FLASH_OPERATION_FAILED)
static uint32_t at91sam7_get_flash_status(target_t *target, int bank_number);
static void at91sam7_set_flash_mode(flash_bank_t *bank, int mode);
static uint32_t at91sam7_wait_status_busy(flash_bank_t *bank, uint32_t waitbits, int timeout);
-static int at91sam7_flash_command(struct flash_bank_s *bank, uint8_t cmd, uint16_t pagen);
+static int at91sam7_flash_command(struct flash_bank_s *bank, uint8_t cmd, uint16_t pagen);
static int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
flash_driver_t at91sam7_flash =
static long SRAMSIZ[16] = {
-1,
0x0400, /* 1K */
- 0x0800, /* 2K */
- -1,
+ 0x0800, /* 2K */
+ -1,
0x1c000, /* 112K */
0x1000, /* 4K */
0x14000, /* 80K */
target_read_u32(target, PMC_MCKR, &mckr);
/* Read Clock Generator PLL Register */
target_read_u32(target, CKGR_PLLR, &pllr);
-
+
at91sam7_info->mck_valid = 0;
at91sam7_info->mck_freq = 0;
- switch (mckr & PMC_MCKR_CSS)
+ switch (mckr & PMC_MCKR_CSS)
{
case 0: /* Slow Clock */
at91sam7_info->mck_valid = 1;
break;
case 1: /* Main Clock */
- if ((mcfr & CKGR_MCFR_MAINRDY) &&
+ if ((mcfr & CKGR_MCFR_MAINRDY) &&
(at91sam7_info->ext_freq == 0))
{
at91sam7_info->mck_valid = 1;
break;
case 3: /* PLL Clock */
- if ((mcfr & CKGR_MCFR_MAINRDY) &&
- (at91sam7_info->ext_freq == 0))
+ if ((mcfr & CKGR_MCFR_MAINRDY) &&
+ (at91sam7_info->ext_freq == 0))
{
target_read_u32(target, CKGR_PLLR, &pllr);
if (!(pllr & CKGR_PLLR_DIV))
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
target_t *target = bank->target;
- fcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd;
+ fcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd;
target_write_u32(target, MC_FCR[bank->bank_number], fcr);
LOG_DEBUG("Flash command: 0x%" PRIx32 ", flash bank: %i, page number: %u", fcr, bank->bank_number + 1, pagen);
return ERROR_OK;
}
- if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)
+ if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)
{
return ERROR_FLASH_OPERATION_FAILED;
}
}
/* Configure the flash controller timing */
- at91sam7_read_clock_info(bank);
+ at91sam7_read_clock_info(bank);
at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
fast_check = 1;
if (erase_all)
{
- if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)
+ if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)
{
return ERROR_FLASH_OPERATION_FAILED;
}
buf += printed;
buf_size -= printed;
- printed = snprintf(buf,
+ printed = snprintf(buf,
buf_size,
" Cidr: 0x%8.8" PRIx32 " | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | Flashsize: 0x%8.8" PRIx32 "\n",
- at91sam7_info->cidr,
- at91sam7_info->cidr_arch,
+ at91sam7_info->cidr,
+ at91sam7_info->cidr_arch,
EPROC[at91sam7_info->cidr_eproc],
- at91sam7_info->cidr_version,
+ at91sam7_info->cidr_version,
bank->size);
buf += printed;
return ERROR_OK;
}
-/*
-* On AT91SAM7S: When the gpnvm bits are set with
+/*
+* On AT91SAM7S: When the gpnvm bits are set with
* > at91sam7 gpnvm bitnr set
-* the changes are not visible in the flash controller status register MC_FSR
+* the changes are not visible in the flash controller status register MC_FSR
* until the processor has been reset.
* On the Olimex board this requires a power cycle.
* Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
/* Configure the flash controller timing */
at91sam7_read_clock_info(bank);
at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
-
+
if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
{
return ERROR_FLASH_OPERATION_FAILED;
/* check protect state */
at91sam7_protect_check(bank);
-
+
return ERROR_OK;
}
pri_ext->suspend_cmd_support = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9);
pri_ext->blk_status_reg_mask = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xa);
- LOG_DEBUG("feature_support: 0x%" PRIx32 ", suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x",
- pri_ext->feature_support,
- pri_ext->suspend_cmd_support,
+ LOG_DEBUG("feature_support: 0x%" PRIx32 ", suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x",
+ pri_ext->feature_support,
+ pri_ext->suspend_cmd_support,
pri_ext->blk_status_reg_mask);
pri_ext->vcc_optimal = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xc);
/* Check for valid range */
if (address & buffermask)
{
- LOG_ERROR("Write address at base 0x%" PRIx32 ", address %" PRIx32 " not aligned to 2^%d boundary",
+ LOG_ERROR("Write address at base 0x%" PRIx32 ", address %" PRIx32 " not aligned to 2^%d boundary",
bank->base, address, cfi_info->max_buf_write_size);
return ERROR_FLASH_OPERATION_FAILED;
}
for (i = 0; i < cfi_info->num_erase_regions; i++)
{
cfi_info->erase_region_info[i] = cfi_query_u32(bank, 0, 0x2d + (4 * i));
- LOG_DEBUG("erase region[%i]: %" PRIu32 " blocks of size 0x%" PRIx32 "",
- i,
- (cfi_info->erase_region_info[i] & 0xffff) + 1,
+ LOG_DEBUG("erase region[%i]: %" PRIu32 " blocks of size 0x%" PRIx32 "",
+ i,
+ (cfi_info->erase_region_info[i] & 0xffff) + 1,
(cfi_info->erase_region_info[i] >> 16) * 256);
}
}
retval = bank->driver->write(bank, buffer, offset, count);
if (retval != ERROR_OK)
{
- LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)",
+ LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)",
bank->base, offset, retval);
}
if ((retval = p->driver->auto_probe(p)) != ERROR_OK)
return retval;
- command_print(cmd_ctx,
+ command_print(cmd_ctx,
"#%" PRIi32 " : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", buswidth %i, chipwidth %i",
i,
- p->driver->name,
- p->base,
- p->size,
- p->bus_width,
+ p->driver->name,
+ p->base,
+ p->size,
+ p->bus_width,
p->chip_width);
for (j = 0; j < p->num_sectors; j++)
{
else
protect_state = "protection state unknown";
- command_print(cmd_ctx,
+ command_print(cmd_ctx,
"\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
j,
- p->sectors[j].offset,
- p->sectors[j].size,
+ p->sectors[j].offset,
+ p->sectors[j].size,
p->sectors[j].size >> 10,
protect_state);
}
command_print(cmd_ctx,
"\t#%3i: 0x%8.8" PRIx32 " (0x%" PRIx32 " %" PRIi32 "kB) %s",
- j,
- p->sectors[j].offset,
- p->sectors[j].size,
+ j,
+ p->sectors[j].offset,
+ p->sectors[j].size,
p->sectors[j].size >> 10,
erase_state);
}
}
if (retval == ERROR_OK)
{
- command_print(cmd_ctx,
+ command_print(cmd_ctx,
"wrote %" PRIu32 " byte from file %s in %s (%f kb/s)",
written,
- args[0],
+ args[0],
duration_text,
(float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
}
{
if (readback[i]!=chunk[i])
{
- LOG_ERROR("Verfication error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x",
+ LOG_ERROR("Verfication error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x",
address + wrote + i, readback[i], chunk[i]);
return ERROR_FAIL;
}
float speed;
speed = wrote / 1024.0;
speed/=((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0));
- command_print(cmd_ctx,
+ command_print(cmd_ctx,
"wrote %" PRId32 " bytes to 0x%8.8" PRIx32 " in %s (%f kb/s)",
- count*wordsize,
- address,
+ count*wordsize,
+ address,
duration_text,
speed);
}
}
if (retval == ERROR_OK)
{
- command_print(cmd_ctx,
+ command_print(cmd_ctx,
"wrote %lld byte from file %s to flash bank %li at offset 0x%8.8" PRIx32 " in %s (%f kb/s)",
- fileio.size,
- args[1],
- strtoul(args[0], NULL, 0),
- offset,
+ fileio.size,
+ args[1],
+ strtoul(args[0], NULL, 0),
+ offset,
duration_text,
(float)fileio.size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
}
*/
typedef struct flash_driver_s
{
- /**
+ /**
* Gives a human-readable name of this flash driver,
* This field is used to select and initialize the driver.
*/
char *name;
- /**
+ /**
* Registers driver-specific commands. When called (during the
* "flash bank" command), the driver may register addition
* commands to support new flash chip functions.
*/
int (*register_commands)(struct command_context_s *cmd_ctx);
- /**
+ /**
* Finish the "flash bank" command for @a bank. The
* @a bank parameter will have been filled in by the core flash
* layer when this routine is called, and the driver can store
* additional information in its flash_bank_t::driver_priv field.
- *
+ *
* @param cmd_ctx - the command context
* @param cmd - the command, in this case 'flash'
* @param args - parameters, see below
* @code
* args[0] = bank
* args[1] = drivername {name above}
- * args[2] = baseaddress
+ * args[2] = baseaddress
* args[3] = lengthbytes
* args[4] = chip_width_in bytes
* args[5] = bus_width_bytes
*/
int (*flash_bank_command)(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
- /**
+ /**
* Bank/sector erase routine (target-specific). When
* called, the flash driver should erase the specified sectors
* using whatever means are at its disposal.
*/
int (*erase)(struct flash_bank_s *bank, int first, int last);
- /**
+ /**
* Bank/sector protection routine (target-specific).
* When called, the driver should disable 'flash write' bits (or
* enable 'erase protection' bits) for the given @a bank and @a
*/
int (*protect)(struct flash_bank_s *bank, int set, int first, int last);
- /**
+ /**
* Program data into the flash. Note CPU address will be
* "bank->base + offset", while the physical address is
* dependent upon current target MMU mappings.
*/
int (*write)(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
- /**
+ /**
* Probe to determine what kind of flash is present.
* This is invoked by the "probe" script command.
*
* @returns ERROR_OK if successful; otherwise, an error code.
*/
int (*probe)(struct flash_bank_s *bank);
-
- /**
+
+ /**
* Check the erasure status of a flash bank.
* When called, the driver routine must perform the required
* checks and then set the @c flash_sector_s::is_erased field
* @param char - where to put the text for the human to read
* @param buf_size - the size of the human buffer.
* @returns ERROR_OK if successful; otherwise, an error code.
- */
+ */
int (*info)(struct flash_bank_s *bank, char *buf, int buf_size);
/**
int (*auto_probe)(struct flash_bank_s *bank);
} flash_driver_t;
-/**
+/**
* Provides details of a flash bank, available either on-chip or through
* a major interface.
*
extern int flash_erase_address_range(struct target_s *target, uint32_t addr, uint32_t length);
/**
* Writes @a image into the @a target flash. The @a written parameter
- * will contain the
+ * will contain the
* @param target The target with the flash to be programmed.
* @param image The image that will be programmed to flash.
* @param written On return, contains the number of bytes written.
residue = sect_cnt % 256;
for (i = 0; i < quotient; i++) {
- LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : 0x%0lx", sect_num,
+ LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : 0x%0lx", sect_num,
(unsigned long)buff_ptr);
ret = mg_mflash_do_read_sects(buff_ptr, sect_num, 256);
if (ret != ERROR_OK)
}
if (residue) {
- LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %0lx", sect_num,
+ LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %0lx", sect_num,
(unsigned long)buff_ptr);
return mg_mflash_do_read_sects(buff_ptr, sect_num, residue);
}
ret = target_write_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
if (ret != ERROR_OK)
return ret;
-
+
buff_ptr += MG_MFLASH_SECTOR_SIZE;
ret = target_write_u8(target, mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, mg_io_cmd_confirm_write);
residue = sect_cnt % 256;
for (i = 0; i < quotient; i++) {
- LOG_DEBUG("mflash: sect num : %" PRIu32 "buff : %p", sect_num,
+ LOG_DEBUG("mflash: sect num : %" PRIu32 "buff : %p", sect_num,
buff_ptr);
ret = mg_mflash_do_write_sects(buff_ptr, sect_num, 256, mg_io_cmd_write);
if (ret != ERROR_OK)
}
if (residue) {
- LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", sect_num,
+ LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", sect_num,
buff_ptr);
return mg_mflash_do_write_sects(buff_ptr, sect_num, residue, mg_io_cmd_write);
}
goto mg_write_cmd_err;
address += MG_FILEIO_CHUNK;
}
-
+
if (res) {
if ((ret = fileio_read(&fileio, res, buffer, &buf_cnt)) != ERROR_OK)
- goto mg_write_cmd_err;
+ goto mg_write_cmd_err;
if ((ret = mg_mflash_write(address, buffer, res)) != ERROR_OK)
goto mg_write_cmd_err;
}
ret = fileio_open(&fileio, args[1], FILEIO_WRITE, FILEIO_BINARY);
if (ret != ERROR_OK)
return ret;
-
+
buffer = malloc(MG_FILEIO_CHUNK);
if (!buffer) {
fileio_close(&fileio);
cnt = size / MG_FILEIO_CHUNK;
res = size % MG_FILEIO_CHUNK;
-
+
duration_start_measure(&duration);
for (i = 0; i < cnt; i++) {
goto mg_dump_cmd_err;
address += MG_FILEIO_CHUNK;
}
-
+
if (res) {
if ((ret = mg_mflash_read(address, buffer, res)) != ERROR_OK)
goto mg_dump_cmd_err;
free(duration_text);
free(buffer);
fileio_close(&fileio);
-
- return ret;
+
+ return ret;
}
static int mg_set_feature(mg_feature_id feature, mg_feature_val config)
switch (argc) {
case 2:
- if (!strcmp(args[1], "boot"))
+ if (!strcmp(args[1], "boot"))
return mg_boot_config();
else if (!strcmp(args[1], "storage"))
return mg_storage_config();
return ERROR_MG_INVALID_PLL;
}
- LOG_INFO("mflash: Fout=%" PRIu32 " Hz, feedback=%u,"
+ LOG_INFO("mflash: Fout=%" PRIu32 " Hz, feedback=%u,"
"indiv=%u, outdiv=%u, lock=%u",
(uint32_t)fout, pll.feedback_div,
pll.input_div, pll.output_div,
else
bad_state = " (block condition unknown)";
- command_print(cmd_ctx,
+ command_print(cmd_ctx,
"\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s",
j,
- p->blocks[j].offset,
+ p->blocks[j].offset,
p->blocks[j].size / 1024,
- erase_state,
+ erase_state,
bad_state);
}
}
int flash_erase_all(void)
{
int result;
-
+
if ((result = flash_erase_plane(0)) != FLASH_STAT_OK) return result;
/* the second flash controller, if any */
pic32mx_info->probed = 0;
device_id = ejtag_info->idcode;
- LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 0x%03x)",
+ LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 0x%03x)",
device_id,
- (unsigned)((device_id >> 1)&0x7ff),
- (unsigned)((device_id >> 12)&0xff),
+ (unsigned)((device_id >> 1)&0x7ff),
+ (unsigned)((device_id >> 12)&0xff),
(unsigned)((device_id >> 20)&0xfff));
if (((device_id >> 1)&0x7ff) != PIC32MX_MANUF_ID) {
device_id = ejtag_info->idcode;
if (((device_id >> 1)&0x7ff) != PIC32MX_MANUF_ID) {
- snprintf(buf, buf_size,
- "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n",
- (unsigned)((device_id >> 1)&0x7ff),
+ snprintf(buf, buf_size,
+ "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n",
+ (unsigned)((device_id >> 1)&0x7ff),
PIC32MX_MANUF_ID);
return ERROR_FLASH_OPERATION_FAILED;
}
}
buf += printed;
buf_size -= printed;
- printed = snprintf(buf, buf_size, " Ver: 0x%03x",
+ printed = snprintf(buf, buf_size, " Ver: 0x%03x",
(unsigned)((device_id >> 20)&0xfff));
return ERROR_OK;
{
device_class = 0;
}
- printed = snprintf(buf,
+ printed = snprintf(buf,
buf_size,
"\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
- device_class,
- StellarisClassname[device_class],
+ device_class,
+ StellarisClassname[device_class],
stellaris_info->target_name,
(int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)),
(int)((stellaris_info->did0) & 0xFF));
buf += printed;
buf_size -= printed;
- printed = snprintf(buf,
- buf_size,
+ printed = snprintf(buf,
+ buf_size,
"did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32 ", eproc: %s, ramsize:%ik, flashsize: %ik\n",
- stellaris_info->did1,
- stellaris_info->did1,
- "ARMV7M",
+ stellaris_info->did1,
+ stellaris_info->did1,
+ "ARMV7M",
(int)((1 + ((stellaris_info->dc0 >> 16) & 0xFFFF))/4),
(int)((1 + (stellaris_info->dc0 & 0xFFFF))*2));
buf += printed;
buf_size -= printed;
- printed = snprintf(buf,
+ printed = snprintf(buf,
buf_size,
"master clock(estimated): %ikHz, rcc is 0x%" PRIx32 " \n",
- (int)(stellaris_info->mck_freq / 1000),
+ (int)(stellaris_info->mck_freq / 1000),
stellaris_info->rcc);
buf += printed;
buf_size -= printed;
{
printed = snprintf(buf,
buf_size,
- "pagesize: %" PRIi32 ", lockbits: %i 0x%4.4" PRIx32 ", pages in lock region: %i \n",
- stellaris_info->pagesize,
- stellaris_info->num_lockbits,
+ "pagesize: %" PRIi32 ", lockbits: %i 0x%4.4" PRIx32 ", pages in lock region: %i \n",
+ stellaris_info->pagesize,
+ stellaris_info->num_lockbits,
stellaris_info->lockbits,
(int)(stellaris_info->num_pages/stellaris_info->num_lockbits));
buf += printed;
static int str7x_register_commands(struct command_context_s *cmd_ctx)
{
command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
-
+
register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
"disable jtag access");
-
+
return ERROR_OK;
}
int i;
int num_sectors;
int b0_sectors = 0, b1_sectors = 0;
-
+
switch (bank->size)
{
case 16 * 1024:
LOG_ERROR("BUG: unknown bank->size encountered");
exit(-1);
}
-
+
num_sectors = b0_sectors + b1_sectors;
-
+
bank->num_sectors = num_sectors;
bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
-
+
num_sectors = 0;
-
+
for (i = 0; i < b0_sectors; i++)
{
bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
bank->sectors[num_sectors].is_protected = 1;
str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
}
-
+
for (i = 0; i < b1_sectors; i++)
{
bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
bank->sectors[num_sectors].is_protected = 1;
str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
}
-
+
return ERROR_OK;
}
static int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
{
str7x_flash_bank_t *str7x_info;
-
+
if (argc < 7)
{
LOG_WARNING("incomplete flash_bank str7x configuration");
return ERROR_FLASH_BANK_INVALID;
}
-
+
str7x_info = malloc(sizeof(str7x_flash_bank_t));
bank->driver_priv = str7x_info;
-
+
/* set default bits for str71x flash */
str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
str7x_info->disable_bit = (1 << 1);
-
+
if (strcmp(args[6], "STR71x") == 0)
{
str7x_info->register_base = 0x40100000;
}
str7x_build_block_list(bank);
-
+
str7x_info->write_algorithm = NULL;
-
+
return ERROR_OK;
}
uint32_t retval;
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
-
+
return retval;
}
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
target_t *target = bank->target;
-
+
int i;
uint32_t retval;
{
str7x_flash_bank_t *str7x_info = bank->driver_priv;
target_t *target = bank->target;
-
+
int i;
uint32_t cmd;
uint32_t retval;
uint32_t sectors = 0;
-
+
if (bank->target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
{
sectors |= str7x_info->sector_bits[i];
}
-
+
LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
-
- /* clear FLASH_ER register */
+
+ /* clear FLASH_ER register */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
-
+
cmd = FLASH_SER;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
cmd = sectors;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
-
+
cmd = FLASH_SER | FLASH_WMS;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
while (((retval = str7x_status(bank)) & str7x_info->busy_bits)) {
alive_sleep(1);
}
-
+
retval = str7x_result(bank);
-
+
if (retval)
{
LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%" PRIx32 "", retval);
return ERROR_FLASH_OPERATION_FAILED;
}
-
+
for (i = first; i <= last; i++)
bank->sectors[i].is_erased = 1;
uint32_t cmd;
uint32_t retval;
uint32_t protect_blocks;
-
+
if (bank->target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
-
+
protect_blocks = 0xFFFFFFFF;
if (set)
for (i = first; i <= last; i++)
protect_blocks &= ~(str7x_info->sector_bits[i]);
}
-
- /* clear FLASH_ER register */
+
+ /* clear FLASH_ER register */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
cmd = FLASH_SPR;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
-
+
cmd = protect_blocks;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
-
+
cmd = FLASH_SPR | FLASH_WMS;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
while (((retval = str7x_status(bank)) & str7x_info->busy_bits)) {
alive_sleep(1);
}
-
+
retval = str7x_result(bank);
-
+
LOG_DEBUG("retval: 0x%8.8" PRIx32 "", retval);
-
+
if (retval & FLASH_ERER)
return ERROR_FLASH_SECTOR_NOT_ERASED;
else if (retval & FLASH_WPF)
reg_param_t reg_params[6];
armv4_5_algorithm_t armv4_5_info;
int retval = ERROR_OK;
-
+
uint32_t str7x_flash_write_code[] = {
/* write: */
0xe3a04201, /* mov r4, #0x10000000 */
/* exit: */
0xeafffffe, /* b exit */
};
-
+
/* flash write code */
if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
{
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
};
-
+
target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (uint8_t*)str7x_flash_write_code);
/* memory buffer */
/* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
if (str7x_info->write_algorithm)
target_free_working_area(target, str7x_info->write_algorithm);
-
+
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
}
-
+
armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
-
+
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
init_reg_param(®_params[2], "r2", 32, PARAM_OUT);
init_reg_param(®_params[3], "r3", 32, PARAM_OUT);
init_reg_param(®_params[4], "r4", 32, PARAM_IN);
init_reg_param(®_params[5], "r5", 32, PARAM_OUT);
-
+
while (count > 0)
{
uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
-
+
target_write_buffer(target, source->address, thisrun_count * 8, buffer);
-
+
buf_set_u32(reg_params[0].value, 0, 32, source->address);
buf_set_u32(reg_params[1].value, 0, 32, address);
buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
-
+
if ((retval = target_run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
{
LOG_ERROR("error executing str7x flash write algorithm");
retval = ERROR_FLASH_OPERATION_FAILED;
break;
}
-
+
if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
{
retval = ERROR_FLASH_OPERATION_FAILED;
break;
}
-
+
buffer += thisrun_count * 8;
address += thisrun_count * 8;
count -= thisrun_count;
}
-
+
target_free_working_area(target, source);
target_free_working_area(target, str7x_info->write_algorithm);
-
+
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
destroy_reg_param(®_params[3]);
destroy_reg_param(®_params[4]);
destroy_reg_param(®_params[5]);
-
+
return retval;
}
int retval;
uint32_t check_address = offset;
int i;
-
+
if (bank->target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
-
+
for (i = 0; i < bank->num_sectors; i++)
{
uint32_t sec_start = bank->sectors[i].offset;
uint32_t sec_end = sec_start + bank->sectors[i].size;
-
+
/* check if destination falls within the current sector */
if ((check_address >= sec_start) && (check_address < sec_end))
{
check_address = sec_end;
}
}
-
+
if (check_address != offset + count)
return ERROR_FLASH_DST_OUT_OF_BANK;
-
- /* clear FLASH_ER register */
+
+ /* clear FLASH_ER register */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
/* multiple dwords (8-byte) to be programmed? */
- if (dwords_remaining > 0)
+ if (dwords_remaining > 0)
{
/* try using a block write */
if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
{
/* if block write failed (no sufficient working area),
- * we use normal (slow) single dword accesses */
+ * we use normal (slow) single dword accesses */
LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
}
else if (retval == ERROR_FLASH_OPERATION_FAILED)
{
/* if an error occured, we examine the reason, and quit */
retval = str7x_result(bank);
-
+
LOG_ERROR("flash writing failed with error code: 0x%x", retval);
return ERROR_FLASH_OPERATION_FAILED;
}
/* command */
cmd = FLASH_DWPG;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
/* address */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
-
+
/* data word 1 */
target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
bytes_written += 4;
-
+
/* data word 2 */
target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
bytes_written += 4;
-
+
/* start programming cycle */
cmd = FLASH_DWPG | FLASH_WMS;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
{
alive_sleep(1);
}
-
+
retval = str7x_result(bank);
-
+
if (retval & FLASH_PGER)
return ERROR_FLASH_OPERATION_FAILED;
else if (retval & FLASH_WPF)
dwords_remaining--;
address += 8;
}
-
+
if (bytes_remaining)
{
uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int i = 0;
-
+
while (bytes_remaining > 0)
{
- last_dword[i++] = *(buffer + bytes_written);
+ last_dword[i++] = *(buffer + bytes_written);
bytes_remaining--;
bytes_written++;
}
-
+
/* command */
cmd = FLASH_DWPG;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
/* address */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
-
+
/* data word 1 */
target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
bytes_written += 4;
-
+
/* data word 2 */
target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
bytes_written += 4;
-
+
/* start programming cycle */
cmd = FLASH_DWPG | FLASH_WMS;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
-
+
while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
{
alive_sleep(1);
}
-
+
retval = str7x_result(bank);
-
+
if (retval & FLASH_PGER)
return ERROR_FLASH_OPERATION_FAILED;
else if (retval & FLASH_WPF)
return ERROR_FLASH_OPERATION_FAILED;
}
-
+
return ERROR_OK;
}
flash_bank_t *bank;
target_t *target = NULL;
str7x_flash_bank_t *str7x_info = NULL;
-
+
uint32_t flash_cmd;
uint32_t retval;
uint16_t ProtectionLevel = 0;
uint16_t ProtectionRegs;
-
+
if (argc < 1)
{
command_print(cmd_ctx, "str7x disable_jtag <bank>");
- return ERROR_OK;
+ return ERROR_OK;
}
-
+
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
if (!bank)
{
command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
return ERROR_OK;
}
-
+
str7x_info = bank->driver_priv;
-
+
target = bank->target;
-
+
if (target->state != TARGET_HALTED)
{
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
-
+
/* first we get protection status */
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
{
ProtectionLevel = 1;
}
-
+
target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
ProtectionRegs = ~(retval >> 16);
ProtectionRegs >>= 1;
ProtectionLevel++;
}
-
+
if (ProtectionLevel == 0)
{
flash_cmd = FLASH_SPR;
flash_cmd = FLASH_SPR | FLASH_WMS;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
}
-
+
return ERROR_OK;
}
.info = tms470_info
};
-/* ----------------------------------------------------------------------
+/* ----------------------------------------------------------------------
Internal Support, Helpers
---------------------------------------------------------------------- */
bank->chip_width = 32;
bank->bus_width = 32;
- LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.",
+ LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.",
part_name,
(int)(silicon_version),
- (technology_family ? "1.8v" : "3.3v"),
+ (technology_family ? "1.8v" : "3.3v"),
(rom_flash ? "rom" : "flash"));
tms470_info->device_ident_reg = device_ident_reg;
if (keysSet)
{
- command_print(cmd_ctx, "using flash keys 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "",
+ command_print(cmd_ctx, "using flash keys 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "",
flashKeys[0], flashKeys[1], flashKeys[2], flashKeys[3]);
}
else
if (ERROR_OK == tms470_check_flash_unlocked(target))
{
- /*
+ /*
* There seems to be a side-effect of reading the FMPKEY
* register in that it re-enables the protection. So we
* re-enable it.
uint32_t flashAddr = bank->base + bank->sectors[sector].offset;
int result = ERROR_OK;
- /*
+ /*
* Set the bit GLBCTRL4 of the GLBCTRL register (in the System
* module) to enable writing to the flash registers }.
*/
}
bank->sectors[sector].is_protected = 0;
- /*
- * clear status regiser, sent erase command, kickoff erase
+ /*
+ * clear status regiser, sent erase command, kickoff erase
*/
target_write_u16(target, flashAddr, 0x0040);
LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0040", flashAddr);
return result;
}
-/* ----------------------------------------------------------------------
+/* ----------------------------------------------------------------------
Implementation of Flash Driver Interfaces
---------------------------------------------------------------------- */
target_read_u32(target, 0xFFE88004, &fmbac2);
target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
- /*
+ /*
* The TI primitives inspect the flash memory by reading one 32-bit
* word at a time. Here we read an entire sector and inspect it in
* an attempt to reduce the JTAG overhead.
uint32_t size;
uint8_t *value;
enum param_direction direction;
-} mem_param_t;
+} mem_param_t;
typedef struct reg_param_s
{
if (values[i] > arm11_coproc_instruction_limits[i])
{
LOG_ERROR("Parameter %ld out of bounds (%" PRId32 " max). %s",
- (long)(i + 2),
+ (long)(i + 2),
arm11_coproc_instruction_limits[i],
read ? arm11_mrc_syntax : arm11_mcr_syntax);
return -1;
arm11_run_instr_data_from_core_via_r0(arm11, instr, &result);
LOG_INFO("MRC p%d, %d, R0, c%d, c%d, %d = 0x%08" PRIx32 " (%" PRId32 ")",
- (int)(values[0]),
- (int)(values[1]),
- (int)(values[2]),
- (int)(values[3]),
+ (int)(values[0]),
+ (int)(values[1]),
+ (int)(values[2]),
+ (int)(values[3]),
(int)(values[4]), result, result);
}
else
} arm926ejs_common_t;
extern int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, jtag_tap_t *tap);
-extern int arm926ejs_register_commands(struct command_context_s *cmd_ctx);
-extern int arm926ejs_arch_state(struct target_s *target);
-extern int arm926ejs_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+extern int arm926ejs_register_commands(struct command_context_s *cmd_ctx);
+extern int arm926ejs_arch_state(struct target_s *target);
+extern int arm926ejs_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
extern int arm926ejs_soft_reset_halt(struct target_s *target);
#endif /* ARM926EJS_H */
extern int arm9tdmi_clock_out(arm_jtag_t *jtag_info, uint32_t instr, uint32_t out, uint32_t *in, int sysspeed);
extern int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, uint32_t *in);
-extern int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be);
+extern int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be);
extern void arm9tdmi_read_core_regs(target_t *target, uint32_t mask, uint32_t* core_regs[16]);
extern void arm9tdmi_write_core_regs(target_t *target, uint32_t mask, uint32_t core_regs[16]);
} swjdp_common_t;
-/* Accessor function for currently selected DAP-AP number */
+/* Accessor function for currently selected DAP-AP number */
static inline uint8_t dap_ap_get_select(swjdp_common_t *swjdp)
{
return (uint8_t)(swjdp ->apsel >> 24);
};
/* make up for C's missing ROR */
-uint32_t ror(uint32_t value, int places)
-{
- return (value >> places) | (value << (32 - places));
+uint32_t ror(uint32_t value, int places)
+{
+ return (value >> places) | (value << (32 - places));
}
int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
if ((opcode & 0x0d70f0000) == 0x0550f000)
{
instruction->type = ARM_PLD;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode);
-
+
return ERROR_OK;
}
else
instruction->type = ARM_UNDEFINED_INSTRUCTION;
return ERROR_OK;
}
-
+
LOG_ERROR("should never reach this point");
return -1;
}
int evaluate_swi(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
{
instruction->type = ARM_SWI;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI 0x%6.6" PRIx32 "", address, opcode, (opcode & 0xffffff));
-
+
return ERROR_OK;
}
int offset;
uint32_t immediate;
uint32_t target_address;
-
+
instruction->type = ARM_BLX;
immediate = opcode & 0x00ffffff;
-
+
/* sign extend 24-bit immediate */
if (immediate & 0x00800000)
offset = 0xff000000 | immediate;
else
offset = immediate;
-
+
/* shift two bits left */
offset <<= 2;
-
+
/* odd/event halfword */
if (opcode & 0x01000000)
offset |= 0x2;
-
+
target_address = address + 8 + offset;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", address, opcode, target_address);
-
+
instruction->info.b_bl_bx_blx.reg_operand = -1;
instruction->info.b_bl_bx_blx.target_address = target_address;
-
+
return ERROR_OK;
}
uint32_t immediate;
int offset;
uint32_t target_address;
-
+
immediate = opcode & 0x00ffffff;
L = (opcode & 0x01000000) >> 24;
-
+
/* sign extend 24-bit immediate */
if (immediate & 0x00800000)
offset = 0xff000000 | immediate;
else
offset = immediate;
-
+
/* shift two bits left */
offset <<= 2;
-
+
target_address = address + 8 + offset;
if (L)
instruction->type = ARM_BL;
else
instruction->type = ARM_B;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32 , address, opcode,
(L) ? "L" : "", COND(opcode), target_address);
-
+
instruction->info.b_bl_bx_blx.reg_operand = -1;
instruction->info.b_bl_bx_blx.target_address = target_address;
-
+
return ERROR_OK;
}
int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
{
uint8_t cp_num = (opcode & 0xf00) >> 8;
-
+
/* MCRR or MRRC */
if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
{
uint8_t cp_opcode, Rd, Rn, CRm;
char *mnemonic;
-
+
cp_opcode = (opcode & 0xf0) >> 4;
Rd = (opcode & 0xf000) >> 12;
Rn = (opcode & 0xf0000) >> 16;
CRm = (opcode & 0xf);
-
+
/* MCRR */
if ((opcode & 0x0ff00000) == 0x0c400000)
{
instruction->type = ARM_MCRR;
mnemonic = "MCRR";
}
-
+
/* MRRC */
if ((opcode & 0x0ff00000) == 0x0c500000)
{
instruction->type = ARM_MRRC;
mnemonic = "MRRC";
}
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, %x, r%i, r%i, c%i",
address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
}
uint8_t U, N;
char *mnemonic;
char addressing_mode[32];
-
+
CRd = (opcode & 0xf000) >> 12;
Rn = (opcode & 0xf0000) >> 16;
offset = (opcode & 0xff);
-
+
/* load/store */
if (opcode & 0x00100000)
{
instruction->type = ARM_STC;
mnemonic = "STC";
}
-
+
U = (opcode & 0x00800000) >> 23;
N = (opcode & 0x00400000) >> 22;
-
+
/* addressing modes */
if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */
snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset);
(N) ? "L" : "",
cp_num, CRd, addressing_mode);
}
-
+
return ERROR_OK;
}
char* cond;
char* mnemonic;
uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
-
+
cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
cp_num = (opcode & 0xf00) >> 8;
CRd_Rd = (opcode & 0xf000) >> 12;
CRn = (opcode & 0xf0000) >> 16;
CRm = (opcode & 0xf);
opcode_2 = (opcode & 0xe0) >> 5;
-
+
/* CDP or MRC/MCR */
if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */
{
instruction->type = ARM_MCR;
mnemonic = "MCR";
}
-
+
opcode_1 = (opcode & 0x00e00000) >> 21;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x",
address, opcode, mnemonic, cond,
cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
{
instruction->type = ARM_CDP;
mnemonic = "CDP";
-
+
opcode_1 = (opcode & 0x00f00000) >> 20;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x",
address, opcode, mnemonic, cond,
cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
}
-
+
return ERROR_OK;
}
char *operation; /* "LDR" or "STR" */
char *suffix; /* "", "B", "T", "BT" */
char offset[32];
-
+
/* examine flags */
I = (opcode & 0x02000000) >> 25;
P = (opcode & 0x01000000) >> 24;
B = (opcode & 0x00400000) >> 22;
W = (opcode & 0x00200000) >> 21;
L = (opcode & 0x00100000) >> 20;
-
+
/* target register */
Rd = (opcode & 0xf000) >> 12;
-
+
/* base register */
Rn = (opcode & 0xf0000) >> 16;
-
+
instruction->info.load_store.Rd = Rd;
instruction->info.load_store.Rn = Rn;
instruction->info.load_store.U = U;
operation = "LDR";
else
operation = "STR";
-
+
/* determine instruction type and suffix */
if (B)
{
suffix = "";
}
}
-
+
if (!I) /* #+-<offset_12> */
{
uint32_t offset_12 = (opcode & 0xfff);
snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
else
snprintf(offset, 32, "%s", "");
-
+
instruction->info.load_store.offset_mode = 0;
instruction->info.load_store.offset.offset = offset_12;
}
{
uint8_t shift_imm, shift;
uint8_t Rm;
-
+
shift_imm = (opcode & 0xf80) >> 7;
shift = (opcode & 0x60) >> 5;
Rm = (opcode & 0xf);
-
+
/* LSR encodes a shift by 32 bit as 0x0 */
if ((shift == 0x1) && (shift_imm == 0x0))
shift_imm = 0x20;
-
+
/* ASR encodes a shift by 32 bit as 0x0 */
if ((shift == 0x2) && (shift_imm == 0x0))
shift_imm = 0x20;
/* ROR by 32 bit is actually a RRX */
if ((shift == 0x3) && (shift_imm == 0x0))
shift = 0x4;
-
+
instruction->info.load_store.offset_mode = 1;
instruction->info.load_store.offset.reg.Rm = Rm;
instruction->info.load_store.offset.reg.shift = shift;
}
}
}
-
+
if (P == 1)
{
if (W == 0) /* offset */
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
address, opcode, operation, COND(opcode), suffix,
Rd, Rn, offset);
-
+
instruction->info.load_store.index_mode = 0;
}
else /* pre-indexed */
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
address, opcode, operation, COND(opcode), suffix,
Rd, Rn, offset);
-
+
instruction->info.load_store.index_mode = 1;
}
}
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
address, opcode, operation, COND(opcode), suffix,
Rd, Rn, offset);
-
+
instruction->info.load_store.index_mode = 2;
}
-
+
return ERROR_OK;
}
char *operation; /* "LDR" or "STR" */
char *suffix; /* "H", "SB", "SH", "D" */
char offset[32];
-
+
/* examine flags */
P = (opcode & 0x01000000) >> 24;
U = (opcode & 0x00800000) >> 23;
L = (opcode & 0x00100000) >> 20;
S = (opcode & 0x00000040) >> 6;
H = (opcode & 0x00000020) >> 5;
-
+
/* target register */
Rd = (opcode & 0xf000) >> 12;
-
+
/* base register */
Rn = (opcode & 0xf0000) >> 16;
-
+
instruction->info.load_store.Rd = Rd;
instruction->info.load_store.Rn = Rn;
instruction->info.load_store.U = U;
-
+
/* determine instruction type and suffix */
if (S) /* signed */
{
instruction->type = ARM_STRH;
}
}
-
+
if (I) /* Immediate offset/index (#+-<offset_8>)*/
{
uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
-
+
instruction->info.load_store.offset_mode = 0;
instruction->info.load_store.offset.offset = offset_8;
}
uint8_t Rm;
Rm = (opcode & 0xf);
snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
-
+
instruction->info.load_store.offset_mode = 1;
instruction->info.load_store.offset.reg.Rm = Rm;
instruction->info.load_store.offset.reg.shift = 0x0;
instruction->info.load_store.offset.reg.shift_imm = 0x0;
}
-
+
if (P == 1)
{
if (W == 0) /* offset */
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
address, opcode, operation, COND(opcode), suffix,
Rd, Rn, offset);
-
+
instruction->info.load_store.index_mode = 0;
}
else /* pre-indexed */
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
address, opcode, operation, COND(opcode), suffix,
Rd, Rn, offset);
-
+
instruction->info.load_store.index_mode = 1;
}
}
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
address, opcode, operation, COND(opcode), suffix,
Rd, Rn, offset);
-
+
instruction->info.load_store.index_mode = 2;
}
-
+
return ERROR_OK;
}
char *reg_list_p;
int i;
int first_reg = 1;
-
+
P = (opcode & 0x01000000) >> 24;
U = (opcode & 0x00800000) >> 23;
S = (opcode & 0x00400000) >> 22;
L = (opcode & 0x00100000) >> 20;
register_list = (opcode & 0xffff);
Rn = (opcode & 0xf0000) >> 16;
-
+
instruction->info.load_store_multiple.Rn = Rn;
instruction->info.load_store_multiple.register_list = register_list;
instruction->info.load_store_multiple.S = S;
instruction->info.load_store_multiple.W = W;
-
+
if (L)
{
instruction->type = ARM_LDM;
instruction->type = ARM_STM;
mnemonic = "STM";
}
-
+
if (P)
{
if (U)
addressing_mode = "DA";
}
}
-
+
reg_list_p = reg_list;
for (i = 0; i <= 15; i++)
{
}
}
}
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i%s, {%s}%s",
address, opcode, mnemonic, COND(opcode), addressing_mode,
Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
-
+
return ERROR_OK;
}
Rn = (opcode & 0xf000) >> 12;
Rd = (opcode & 0xf0000) >> 16;
S = (opcode & 0x00100000) >> 20;
-
+
/* examine A bit (accumulate) */
if (opcode & 0x00200000)
{
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
}
-
+
return ERROR_OK;
}
-
+
/* Multiply (accumulate) long */
if ((opcode & 0x0f800000) == 0x00800000)
{
RdHi = (opcode & 0xf000) >> 12;
RdLow = (opcode & 0xf0000) >> 16;
S = (opcode & 0x00100000) >> 20;
-
+
switch ((opcode & 0x00600000) >> 21)
{
case 0x0:
mnemonic = "SMLAL";
break;
}
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
RdLow, RdHi, Rm, Rs);
-
+
return ERROR_OK;
}
-
+
/* Swap/swap byte */
if ((opcode & 0x0f800000) == 0x01000000)
{
Rm = opcode & 0xf;
Rd = (opcode & 0xf000) >> 12;
Rn = (opcode & 0xf0000) >> 16;
-
+
/* examine B flag */
instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
return ERROR_OK;
}
-
+
}
-
+
return evaluate_misc_load_store(opcode, address, instruction);
}
{
int R = (opcode & 0x00400000) >> 22;
char *PSR = (R) ? "SPSR" : "CPSR";
-
+
/* Move register to status register (MSR) */
if (opcode & 0x00200000)
{
instruction->type = ARM_MSR;
-
+
/* immediate variant */
if (opcode & 0x02000000)
{
uint8_t immediate = (opcode & 0xff);
uint8_t rotate = (opcode & 0xf00);
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 ,
address, opcode, COND(opcode), PSR,
(opcode & 0x10000) ? "c" : "",
Rm
);
}
-
+
}
else /* Move status register to register (MRS) */
{
uint8_t Rd;
-
+
instruction->type = ARM_MRS;
Rd = (opcode & 0x0000f000) >> 12;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
address, opcode, COND(opcode), Rd, PSR);
}
-
+
return ERROR_OK;
}
{
evaluate_mrs_msr(opcode, address, instruction);
}
-
+
/* BX */
if ((opcode & 0x006000f0) == 0x00200010)
{
uint8_t Rm;
instruction->type = ARM_BX;
Rm = opcode & 0xf;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
address, opcode, COND(opcode), Rm);
-
+
instruction->info.b_bl_bx_blx.reg_operand = Rm;
instruction->info.b_bl_bx_blx.target_address = -1;
}
-
+
/* CLZ */
if ((opcode & 0x006000f0) == 0x00600010)
{
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
address, opcode, COND(opcode), Rd, Rm);
}
-
+
/* BLX(2) */
if ((opcode & 0x006000f0) == 0x00200030)
{
uint8_t Rm;
instruction->type = ARM_BLX;
Rm = opcode & 0xf;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
address, opcode, COND(opcode), Rm);
-
+
instruction->info.b_bl_bx_blx.reg_operand = Rm;
instruction->info.b_bl_bx_blx.target_address = -1;
}
-
+
/* Enhanced DSP add/subtracts */
if ((opcode & 0x0000000f0) == 0x00000050)
{
Rm = opcode & 0xf;
Rd = (opcode & 0xf000) >> 12;
Rn = (opcode & 0xf0000) >> 16;
-
+
switch ((opcode & 0x00600000) >> 21)
{
case 0x0:
mnemonic = "QDSUB";
break;
}
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
}
-
+
/* Software breakpoints */
if ((opcode & 0x0000000f0) == 0x00000070)
{
uint32_t immediate;
instruction->type = ARM_BKPT;
immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
- address, opcode, immediate);
+ address, opcode, immediate);
}
-
+
/* Enhanced DSP multiplies */
if ((opcode & 0x000000090) == 0x00000080)
{
int x = (opcode & 0x20) >> 5;
int y = (opcode & 0x40) >> 6;
-
+
/* SMLA < x><y> */
if ((opcode & 0x00600000) == 0x00000000)
{
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8;
Rn = (opcode & 0xf000) >> 12;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
Rd, Rm, Rs, Rn);
}
-
+
/* SMLAL < x><y> */
if ((opcode & 0x00600000) == 0x00400000)
{
RdLow = (opcode & 0xf000) >> 12;
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
RdLow, RdHi, Rm, Rs);
}
-
+
/* SMLAW < y> */
if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
{
address, opcode, (y) ? "T" : "B", COND(opcode),
Rd, Rm, Rs, Rn);
}
-
+
/* SMUL < x><y> */
if ((opcode & 0x00600000) == 0x00300000)
{
Rd = (opcode & 0xf0000) >> 16;
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
Rd, Rm, Rs);
}
-
+
/* SMULW < y> */
if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
{
Rd = (opcode & 0xf0000) >> 16;
Rm = (opcode & 0xf);
Rs = (opcode & 0xf00) >> 8;
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
address, opcode, (y) ? "T" : "B", COND(opcode),
Rd, Rm, Rs);
}
}
-
+
return ERROR_OK;
}
uint8_t I, op, S, Rn, Rd;
char *mnemonic = NULL;
char shifter_operand[32];
-
+
I = (opcode & 0x02000000) >> 25;
op = (opcode & 0x01e00000) >> 21;
S = (opcode & 0x00100000) >> 20;
-
+
Rd = (opcode & 0xf000) >> 12;
Rn = (opcode & 0xf0000) >> 16;
-
+
instruction->info.data_proc.Rd = Rd;
instruction->info.data_proc.Rn = Rn;
instruction->info.data_proc.S = S;
mnemonic = "MVN";
break;
}
-
+
if (I) /* immediate shifter operand (#<immediate>)*/
{
uint8_t immed_8 = opcode & 0xff;
uint8_t rotate_imm = (opcode & 0xf00) >> 8;
uint32_t immediate;
-
+
immediate = ror(immed_8, rotate_imm * 2);
-
+
snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
-
+
instruction->info.data_proc.variant = 0;
instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
}
uint8_t shift, Rm;
shift = (opcode & 0x60) >> 5;
Rm = (opcode & 0xf);
-
+
if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
{
uint8_t shift_imm;
instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
-
+
/* LSR encodes a shift by 32 bit as 0x0 */
if ((shift == 0x1) && (shift_imm == 0x0))
shift_imm = 0x20;
-
+
/* ASR encodes a shift by 32 bit as 0x0 */
if ((shift == 0x2) && (shift_imm == 0x0))
shift_imm = 0x20;
/* ROR by 32 bit is actually a RRX */
if ((shift == 0x3) && (shift_imm == 0x0))
shift = 0x4;
-
+
if ((shift_imm == 0x0) && (shift == 0x0))
{
snprintf(shifter_operand, 32, "r%i", Rm);
else /* Register shifts ("<Rm>, <shift> <Rs>") */
{
uint8_t Rs = (opcode & 0xf00) >> 8;
-
+
instruction->info.data_proc.variant = 2;
instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
-
+
if (shift == 0x0) /* LSL */
{
snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
}
}
}
-
+
if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
{
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
address, opcode, mnemonic, COND(opcode),
Rn, shifter_operand);
}
-
+
return ERROR_OK;
}
-
+
int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
{
/* clear fields, to avoid confusion */
memset(instruction, 0, sizeof(arm_instruction_t));
instruction->opcode = opcode;
-
+
/* catch opcodes with condition field [31:28] = b1111 */
if ((opcode & 0xf0000000) == 0xf0000000)
{
/* Undefined instruction (or ARMv5E cache preload PLD) */
if ((opcode & 0x08000000) == 0x00000000)
return evaluate_pld(opcode, address, instruction);
-
+
/* Undefined instruction */
if ((opcode & 0x0e000000) == 0x08000000)
{
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
return ERROR_OK;
}
-
+
/* Branch and branch with link and change to Thumb */
if ((opcode & 0x0e000000) == 0x0a000000)
return evaluate_blx_imm(opcode, address, instruction);
-
+
/* Extended coprocessor opcode space (ARMv5 and higher)*/
/* Coprocessor load/store and double register transfers */
if ((opcode & 0x0e000000) == 0x0c000000)
return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
-
+
/* Coprocessor data processing */
if ((opcode & 0x0f000100) == 0x0c000000)
return evaluate_cdp_mcr_mrc(opcode, address, instruction);
-
+
/* Coprocessor register transfers */
if ((opcode & 0x0f000010) == 0x0c000010)
return evaluate_cdp_mcr_mrc(opcode, address, instruction);
-
+
/* Undefined instruction */
if ((opcode & 0x0f000000) == 0x0f000000)
{
return ERROR_OK;
}
}
-
+
/* catch opcodes with [27:25] = b000 */
if ((opcode & 0x0e000000) == 0x00000000)
{
/* Multiplies, extra load/stores */
if ((opcode & 0x00000090) == 0x00000090)
return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
-
+
/* Miscellaneous instructions */
if ((opcode & 0x0f900000) == 0x01000000)
return evaluate_misc_instr(opcode, address, instruction);
-
+
return evaluate_data_proc(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b001 */
if ((opcode & 0x0e000000) == 0x02000000)
{
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
return ERROR_OK;
}
-
+
/* Move immediate to status register */
if ((opcode & 0x0fb00000) == 0x03200000)
return evaluate_mrs_msr(opcode, address, instruction);
-
+
return evaluate_data_proc(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b010 */
if ((opcode & 0x0e000000) == 0x04000000)
{
/* Load/store immediate offset */
return evaluate_load_store(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b011 */
if ((opcode & 0x0e000000) == 0x06000000)
{
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
return ERROR_OK;
}
-
+
/* Load/store register offset */
return evaluate_load_store(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b100 */
if ((opcode & 0x0e000000) == 0x08000000)
{
/* Load/store multiple */
return evaluate_ldm_stm(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b101 */
if ((opcode & 0x0e000000) == 0x0a000000)
{
/* Branch and branch with link */
return evaluate_b_bl(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b110 */
if ((opcode & 0x0e000000) == 0x0a000000)
{
/* Coprocessor load/store and double register transfers */
return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
}
-
+
/* catch opcodes with [27:25] = b111 */
if ((opcode & 0x0e000000) == 0x0e000000)
{
/* Software interrupt */
if ((opcode & 0x0f000000) == 0x0f000000)
return evaluate_swi(opcode, address, instruction);
-
+
/* Coprocessor data processing */
if ((opcode & 0x0f000010) == 0x0e000000)
return evaluate_cdp_mcr_mrc(opcode, address, instruction);
-
+
/* Coprocessor register transfers */
if ((opcode & 0x0f000010) == 0x0e000010)
return evaluate_cdp_mcr_mrc(opcode, address, instruction);
}
-
+
LOG_ERROR("should never reach this point");
return -1;
}
uint32_t opc = (opcode >> 11) & 0x3;
uint32_t target_address;
char *mnemonic = NULL;
-
+
/* sign extend 11-bit offset */
if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
offset = 0xfffff800 | offset;
-
+
target_address = address + 4 + (offset << 1);
switch (opc)
/* TODO: deals correctly with dual opcodes BL/BLX ... */
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s 0x%8.8" PRIx32 , address, opcode,mnemonic, target_address);
-
+
instruction->info.b_bl_bx_blx.reg_operand = -1;
instruction->info.b_bl_bx_blx.target_address = target_address;
uint32_t opc = opcode & (1 << 9);
uint32_t reg_imm = opcode & (1 << 10);
char *mnemonic;
-
+
if (opc)
{
instruction->type = ARM_SUB;
instruction->type = ARM_ADD;
mnemonic = "ADDS";
}
-
+
instruction->info.data_proc.Rd = Rd;
instruction->info.data_proc.Rn = Rn;
instruction->info.data_proc.S = 1;
uint8_t imm = (opcode >> 6) & 0x1f;
uint8_t opc = (opcode >> 11) & 0x3;
char *mnemonic = NULL;
-
+
switch (opc)
{
case 0:
uint8_t Rd = (opcode >> 8) & 0x7;
uint32_t opc = (opcode >> 11) & 0x3;
char *mnemonic = NULL;
-
+
instruction->info.data_proc.Rd = Rd;
instruction->info.data_proc.Rn = Rd;
instruction->info.data_proc.S = 1;
instruction->info.data_proc.variant = 0; /*immediate*/
instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
-
+
switch (opc)
{
case 0:
mnemonic = "SUBS";
break;
}
-
+
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, #0x%02x" ,
address, opcode, mnemonic, Rd, imm);
{
uint8_t high_reg, op, Rm, Rd,H1,H2;
char *mnemonic = NULL;
-
+
high_reg = (opcode & 0x0400) >> 10;
op = (opcode & 0x03C0) >> 6;
-
+
Rd = (opcode & 0x0007);
Rm = (opcode & 0x0038) >> 3;
H1 = (opcode & 0x0080) >> 7;
H2 = (opcode & 0x0040) >> 6;
-
+
instruction->info.data_proc.Rd = Rd;
instruction->info.data_proc.Rn = Rd;
instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
Rd |= H1 << 3;
Rm |= H2 << 3;
op >>= 2;
-
+
switch (op)
{
case 0x0:
instruction->type = ARM_UNDEFINED_INSTRUCTION;
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
}
- return ERROR_OK;
+ return ERROR_OK;
break;
}
}
int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
{
uint32_t immediate;
- uint8_t Rd = (opcode >> 8) & 0x7;
+ uint8_t Rd = (opcode >> 8) & 0x7;
instruction->type = ARM_LDR;
immediate = opcode & 0x000000ff;
int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
{
- uint8_t Rd = (opcode >> 0) & 0x7;
- uint8_t Rn = (opcode >> 3) & 0x7;
- uint8_t Rm = (opcode >> 6) & 0x7;
- uint8_t opc = (opcode >> 9) & 0x7;
+ uint8_t Rd = (opcode >> 0) & 0x7;
+ uint8_t Rn = (opcode >> 3) & 0x7;
+ uint8_t Rm = (opcode >> 6) & 0x7;
+ uint8_t opc = (opcode >> 9) & 0x7;
char *mnemonic = NULL;
switch (opc)
}
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [r%i, r%i]", address, opcode, mnemonic, Rd, Rn, Rm);
-
+
instruction->info.load_store.Rd = Rd;
instruction->info.load_store.Rn = Rn;
instruction->info.load_store.index_mode = 0; /*offset*/
int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
{
uint32_t offset = (opcode >> 6) & 0x1f;
- uint8_t Rd = (opcode >> 0) & 0x7;
- uint8_t Rn = (opcode >> 3) & 0x7;
+ uint8_t Rd = (opcode >> 0) & 0x7;
+ uint8_t Rn = (opcode >> 3) & 0x7;
uint32_t L = opcode & (1 << 11);
uint32_t B = opcode & (1 << 12);
char *mnemonic;
}
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s%c r%i, [r%i, #0x%" PRIx32 "]", address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
-
+
instruction->info.load_store.Rd = Rd;
instruction->info.load_store.Rn = Rn;
instruction->info.load_store.index_mode = 0; /*offset*/
int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
{
uint32_t offset = opcode & 0xff;
- uint8_t Rd = (opcode >> 8) & 0x7;
+ uint8_t Rd = (opcode >> 8) & 0x7;
uint32_t L = opcode & (1 << 11);
char *mnemonic;
}
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [SP, #0x%" PRIx32 "]", address, opcode, mnemonic, Rd, offset*4);
-
+
instruction->info.load_store.Rd = Rd;
instruction->info.load_store.Rn = 13 /*SP*/;
instruction->info.load_store.index_mode = 0; /*offset*/
int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
{
uint32_t imm = opcode & 0xff;
- uint8_t Rd = (opcode >> 8) & 0x7;
+ uint8_t Rd = (opcode >> 8) & 0x7;
uint8_t Rn;
uint32_t SP = opcode & (1 << 11);
char *reg_name;
instruction->type = ARM_ADD;
-
+
if (SP)
{
reg_name = "SP";
uint8_t opc = opcode & (1 << 7);
char *mnemonic;
-
+
if (opc)
{
instruction->type = ARM_SUB;
int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
{
uint32_t imm = opcode & 0xff;
-
+
instruction->type = ARM_BKPT;
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBKPT 0x%02" PRIx32 "", address, opcode, imm);
char *reg_names_p;
char *mnemonic;
char ptr_name[7] = "";
- int i;
+ int i;
if ((opcode & 0xf000) == 0xc000)
{ /* generic load/store multiple */
/* sign extend 8-bit offset */
if (offset & 0x00000080)
offset = 0xffffff00 | offset;
-
+
target_address = address + 4 + (offset << 1);
snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tB%s 0x%8.8" PRIx32 , address, opcode,
arm_condition_strings[cond], target_address);
-
+
instruction->type = ARM_B;
instruction->info.b_bl_bx_blx.reg_operand = -1;
instruction->info.b_bl_bx_blx.target_address = target_address;
/* clear fields, to avoid confusion */
memset(instruction, 0, sizeof(arm_instruction_t));
instruction->opcode = opcode;
-
+
if ((opcode & 0xe000) == 0x0000)
{
/* add/substract register or immediate */
else
return evaluate_shift_imm_thumb(opcode, address, instruction);
}
-
+
/* Add/substract/compare/move immediate */
if ((opcode & 0xe000) == 0x2000)
{
return evaluate_data_proc_imm_thumb(opcode, address, instruction);
}
-
+
/* Data processing instructions */
if ((opcode & 0xf800) == 0x4000)
{
return evaluate_data_proc_thumb(opcode, address, instruction);
}
-
+
/* Load from literal pool */
if ((opcode & 0xf800) == 0x4800)
{
{
return evaluate_load_store_imm_thumb(opcode, address, instruction);
}
-
+
/* Load/Store from/to stack */
if ((opcode & 0xf000) == 0x9000)
{
{
return evaluate_cond_branch_thumb(opcode, address, instruction);
}
-
+
if ((opcode & 0xe000) == 0xe000)
{
/* Undefined instructions */
enum arm_instruction_type
{
ARM_UNKNOWN_INSTUCTION,
-
+
/* Branch instructions */
ARM_B,
ARM_BL,
ARM_BX,
ARM_BLX,
-
+
/* Data processing instructions */
ARM_AND,
ARM_EOR,
ARM_MOV,
ARM_BIC,
ARM_MVN,
-
+
/* Load/store instructions */
ARM_LDR,
ARM_LDRB,
ARM_LDRT,
ARM_LDRBT,
-
+
ARM_LDRH,
ARM_LDRSB,
ARM_LDRSH,
-
+
ARM_LDM,
ARM_STR,
ARM_STRB,
ARM_STRT,
ARM_STRBT,
-
+
ARM_STRH,
-
+
ARM_STM,
-
+
/* Status register access instructions */
ARM_MRS,
ARM_MSR,
-
+
/* Multiply instructions */
ARM_MUL,
ARM_MLA,
ARM_SMLAL,
ARM_UMULL,
ARM_UMLAL,
-
+
/* Miscellaneous instructions */
ARM_CLZ,
-
+
/* Exception generating instructions */
ARM_BKPT,
ARM_SWI,
-
+
/* Coprocessor instructions */
ARM_CDP,
ARM_LDC,
ARM_STC,
ARM_MCR,
ARM_MRC,
-
+
/* Semaphore instructions */
ARM_SWP,
ARM_SWPB,
-
+
/* Enhanced DSP extensions */
ARM_MCRR,
ARM_MRRC,
enum arm_instruction_type type;
char text[128];
uint32_t opcode;
-
+
union {
arm_b_bl_bx_blx_instr_t b_bl_bx_blx;
arm_data_proc_instr_t data_proc;
field.out_value = t;
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
field.in_value = NULL;
-
+
if (no_verify_capture == NULL)
{
uint32_t return_value = 0;
shift_amount &= 0xff;
-
+
if (shift == 0x0) /* LSL */
{
if ((shift_amount > 0) && (shift_amount <= 32))
Rm |= 0x80000000;
*carry = Rm & 0x1;
}
-
+
return return_value;
}
{
uint32_t return_value;
int instruction_size;
-
+
if (armv4_5->core_state == ARMV4_5_STATE_ARM)
instruction_size = 4;
else
instruction_size = 2;
-
+
*shifter_carry_out = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
-
+
if (variant == 0) /* 32-bit immediate */
{
return_value = shifter_operand.immediate.immediate;
else if (variant == 1) /* immediate shift */
{
uint32_t Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.immediate_shift.Rm).value, 0, 32);
-
+
/* adjust RM in case the PC is being read */
if (shifter_operand.immediate_shift.Rm == 15)
Rm += 2 * instruction_size;
-
+
return_value = arm_shift(shifter_operand.immediate_shift.shift, Rm, shifter_operand.immediate_shift.shift_imm, shifter_carry_out);
}
else if (variant == 2) /* register shift */
{
uint32_t Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.register_shift.Rm).value, 0, 32);
uint32_t Rs = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.register_shift.Rs).value, 0, 32);
-
+
/* adjust RM in case the PC is being read */
if (shifter_operand.register_shift.Rm == 15)
Rm += 2 * instruction_size;
-
+
return_value = arm_shift(shifter_operand.immediate_shift.shift, Rm, Rs, shifter_carry_out);
}
else
LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2");
return_value = 0xffffffff;
}
-
+
return return_value;
}
case 0xe:
case 0xf:
return 1;
-
+
}
-
+
LOG_ERROR("BUG: should never get here");
return 0;
}
int thumb_pass_branch_condition(uint32_t cpsr, uint16_t opcode)
{
- return pass_condition(cpsr, (opcode & 0x0f00) << 20);
+ return pass_condition(cpsr, (opcode & 0x0f00) << 20);
}
/* simulate a single step (if possible)
arm_instruction_t instruction;
int instruction_size;
int retval = ERROR_OK;
-
+
if (armv4_5->core_state == ARMV4_5_STATE_ARM)
{
uint32_t opcode;
-
+
/* get current instruction, and identify it */
if ((retval = target_read_u32(target, current_pc, &opcode)) != ERROR_OK)
{
return retval;
}
instruction_size = 4;
-
+
/* check condition code (for all instructions) */
if (!pass_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode))
{
{
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
}
-
+
return ERROR_OK;
}
}
else
{
uint16_t opcode;
-
+
if ((retval = target_read_u16(target, current_pc, &opcode)) != ERROR_OK)
{
return retval;
return retval;
}
instruction_size = 2;
-
+
/* check condition code (only for branch instructions) */
if ((!thumb_pass_branch_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode)) &&
(instruction.type == ARM_B))
{
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
}
-
+
return ERROR_OK;
}
}
-
+
/* examine instruction type */
/* branch instructions */
if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX))
{
uint32_t target;
-
+
if (instruction.info.b_bl_bx_blx.reg_operand == -1)
{
target = instruction.info.b_bl_bx_blx.target_address;
}
else
{
- target = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.b_bl_bx_blx.reg_operand).value, 0, 32);
+ target = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.b_bl_bx_blx.reg_operand).value, 0, 32);
if (instruction.info.b_bl_bx_blx.reg_operand == 15)
{
target += 2 * instruction_size;
}
}
-
+
if (dry_run_pc)
- {
+ {
*dry_run_pc = target;
return ERROR_OK;
}
}
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target & 0xfffffffe);
}
-
+
return ERROR_OK;
}
}
uint32_t Rd, Rn, shifter_operand;
uint8_t C = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
uint8_t carry_out;
-
+
Rd = 0x0;
/* ARM_MOV and ARM_MVN does not use Rn */
if ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN))
/* adjust Rn in case the PC is being read */
if (instruction.info.data_proc.Rn == 15)
Rn += 2 * instruction_size;
-
+
if (instruction.type == ARM_AND)
Rd = Rn & shifter_operand;
else if (instruction.type == ARM_EOR)
Rd = ~shifter_operand;
else
LOG_WARNING("unhandled instruction type");
-
+
if (dry_run_pc)
{
if (instruction.info.data_proc.Rd == 15)
{
*dry_run_pc = current_pc + instruction_size;
}
-
+
return ERROR_OK;
}
else
buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rd).value, 0, 32, Rd);
LOG_WARNING("no updating of flags yet");
- if (instruction.info.data_proc.Rd == 15)
+ if (instruction.info.data_proc.Rd == 15)
return ERROR_OK;
}
}
{
uint32_t load_address = 0, modified_address = 0, load_value;
uint32_t Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rn).value, 0, 32);
-
+
/* adjust Rn in case the PC is being read */
if (instruction.info.load_store.Rn == 15)
Rn += 2 * instruction_size;
-
+
if (instruction.info.load_store.offset_mode == 0)
{
if (instruction.info.load_store.U)
uint8_t shift = instruction.info.load_store.offset.reg.shift;
uint8_t shift_imm = instruction.info.load_store.offset.reg.shift_imm;
uint8_t carry = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
-
+
offset = arm_shift(shift, Rm, shift_imm, &carry);
-
+
if (instruction.info.load_store.U)
modified_address = Rn + offset;
else
{
LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)");
}
-
+
if (instruction.info.load_store.index_mode == 0)
{
/* offset mode
* we load from the unmodified address, and write the modified address back */
load_address = Rn;
}
-
+
if ((!dry_run_pc) || (instruction.info.load_store.Rd == 15))
{
if ((retval = target_read_u32(target, load_address, &load_value)) != ERROR_OK)
return retval;
}
}
-
+
if (dry_run_pc)
{
if (instruction.info.load_store.Rd == 15)
{
*dry_run_pc = current_pc + instruction_size;
}
-
+
return ERROR_OK;
}
else
(instruction.info.load_store.index_mode == 2))
{
buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rn).value, 0, 32, modified_address);
- }
+ }
buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rd).value, 0, 32, load_value);
-
+
if (instruction.info.load_store.Rd == 15)
return ERROR_OK;
}
if (instruction.info.load_store_multiple.register_list & (1 << i))
bits_set++;
}
-
+
switch (instruction.info.load_store_multiple.addressing_mode)
{
case 0: /* Increment after */
Rn = Rn + 4;
break;
case 2: /* Decrement after */
- Rn = Rn - (bits_set * 4) + 4;
+ Rn = Rn - (bits_set * 4) + 4;
break;
case 3: /* Decrement before */
Rn = Rn - (bits_set * 4);
Rn += 4;
}
}
-
+
if (dry_run_pc)
{
if (instruction.info.load_store_multiple.register_list & 0x8000)
buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, i).value, 0, 32, load_values[i]);
}
}
-
+
if (update_cpsr)
{
uint32_t spsr = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32);
buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, spsr);
}
-
+
/* base register writeback */
if (instruction.info.load_store_multiple.W)
- buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
-
+ buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
+
if (instruction.info.load_store_multiple.register_list & 0x8000)
return ERROR_OK;
}
if (instruction.info.load_store_multiple.register_list & (1 << i))
bits_set++;
}
-
+
if (instruction.info.load_store_multiple.S)
{
mode = ARMV4_5_MODE_USR;
}
-
+
switch (instruction.info.load_store_multiple.addressing_mode)
{
case 0: /* Increment after */
Rn = Rn + 4;
break;
case 2: /* Decrement after */
- Rn = Rn - (bits_set * 4) + 4;
+ Rn = Rn - (bits_set * 4) + 4;
break;
case 3: /* Decrement before */
Rn = Rn - (bits_set * 4);
break;
}
-
+
for (i = 0; i < 16; i++)
{
if (instruction.info.load_store_multiple.register_list & (1 << i))
Rn += 4;
}
}
-
+
/* base register writeback */
if (instruction.info.load_store_multiple.W)
- buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
-
+ buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
+
}
}
else if (!dry_run_pc)
*/
return ERROR_ARM_SIMULATOR_NOT_IMPLEMENTED;
}
-
+
if (dry_run_pc)
{
*dry_run_pc = current_pc + instruction_size;
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
return ERROR_OK;
}
-
+
}
{
armv4_5->full_context(target);
}
- output_len += snprintf(output + output_len,
- 128 - output_len,
- "%8s: %8.8" PRIx32 " ",
+ output_len += snprintf(output + output_len,
+ 128 - output_len,
+ "%8s: %8.8" PRIx32 " ",
ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
}
{
command_t *arm_adi_v5_dap_cmd;
- arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap", NULL, COMMAND_ANY, "cortex dap specific commands");
+ arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap", NULL, COMMAND_ANY, "cortex dap specific commands");
register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info", handle_dap_info_command, COMMAND_EXEC, "Displays dap info for ap [num], default currently selected AP");
register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel", handle_dap_apsel_command, COMMAND_EXEC, "Select a different AP [num] (default 0)");
register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid", handle_dap_apid_command, COMMAND_EXEC, "Displays id reg from AP [num], default currently selected AP");
apsel = swjdp->apsel;
apselsave = swjdp->apsel;
if (argc > 0)
- {
+ {
apsel = strtoul(args[0], NULL, 0);
}
if (apselsave != apsel)
apsel = swjdp->apsel;
apselsave = swjdp->apsel;
if (argc > 0)
- {
+ {
apsel = strtoul(args[0], NULL, 0);
}
apsel = 0;
if (argc > 0)
- {
+ {
apsel = strtoul(args[0], NULL, 0);
}
memaccess_tck = swjdp->memaccess_tck;
if (argc > 0)
- {
+ {
memaccess_tck = strtoul(args[0], NULL, 0);
}
apsel = swjdp->apsel;
if (argc > 0)
- {
+ {
apsel = strtoul(args[0], NULL, 0);
}
-
+
retval = dap_info_command(cmd_ctx, swjdp, apsel);
return retval;
extern char *armv7m_exception_string(int number);
/* offsets into armv7m core register cache */
-enum
+enum
{
ARMV7M_PC = 15,
ARMV7M_xPSR = 16,
int exception_number;
swjdp_common_t swjdp_info;
-
+
/* Direct processor core register read and writes */
int (*load_core_reg_u32)(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t *value);
int (*store_core_reg_u32)(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t value);
/* register cache to processor synchronization */
int (*read_core_reg)(struct target_s *target, int num);
int (*write_core_reg)(struct target_s *target, int num);
-
+
int (*examine_debug_reason)(target_t *target);
void (*pre_debug_entry)(target_t *target);
void (*post_debug_entry)(target_t *target);
-
+
void (*pre_restore_context)(target_t *target);
void (*post_restore_context)(target_t *target);
typedef struct armv7m_algorithm_s
{
int common_magic;
-
+
enum armv7m_mode core_mode;
} armv7m_algorithm_t;
/* Thumb mode instructions
*/
-
+
/* Move to Register from Special Register (Thumb mode) 32 bit Thumb2 instruction
* Rd: destination register
* SYSm: source special register
*/
-#define ARMV7M_T_MRS(Rd, SYSm) ((0xF3EF) | ((0x8000 | (Rd << 8) | SYSm) << 16))
+#define ARMV7M_T_MRS(Rd, SYSm) ((0xF3EF) | ((0x8000 | (Rd << 8) | SYSm) << 16))
/* Move from Register from Special Register (Thumb mode) 32 bit Thumb2 instruction
* Rd: source register
* SYSm: destination special register
*/
-#define ARMV7M_T_MSR(SYSm, Rn) ((0xF380 | (Rn << 8)) | ((0x8800 | SYSm) << 16))
+#define ARMV7M_T_MSR(SYSm, Rn) ((0xF380 | (Rn << 8)) | ((0x8800 | SYSm) << 16))
-/* Change Processor State. The instruction modifies the PRIMASK and FAULTMASK
+/* Change Processor State. The instruction modifies the PRIMASK and FAULTMASK
* special-purpose register values (Thumb mode) 16 bit Thumb2 instruction
* Rd: source register
- * IF:
+ * IF:
*/
#define I_FLAG 2
-#define F_FLAG 1
-#define ARMV7M_T_CPSID(IF) ((0xB660 | (1 << 8) | (IF&0x3)) | ((0xB660 | (1 << 8) | (IF&0x3)) << 16))
-#define ARMV7M_T_CPSIE(IF) ((0xB660 | (0 << 8) | (IF&0x3)) | ((0xB660 | (0 << 8) | (IF&0x3)) << 16))
+#define F_FLAG 1
+#define ARMV7M_T_CPSID(IF) ((0xB660 | (1 << 8) | (IF&0x3)) | ((0xB660 | (1 << 8) | (IF&0x3)) << 16))
+#define ARMV7M_T_CPSIE(IF) ((0xB660 | (0 << 8) | (IF&0x3)) | ((0xB660 | (0 << 8) | (IF&0x3)) << 16))
/* Breakpoint (Thumb mode) v5 onwards
* Im: immediate value used by debugger
* List: for each bit in list: store register
*/
#define ARMV7M_T_LDMIA(Rn, List) ((0xc800 | (Rn << 8) | List) | ((0xc800 | (Rn << 8) | List) << 16))
-
+
/* Load register with PC relative addressing
* Rd: register to load
*/
-#define ARMV7M_T_LDR_PCREL(Rd) ((0x4800 | (Rd << 8)) | ((0x4800 | (Rd << 8)) << 16))
-
+#define ARMV7M_T_LDR_PCREL(Rd) ((0x4800 | (Rd << 8)) | ((0x4800 | (Rd << 8)) << 16))
+
/* Move hi register (Thumb mode)
* Rd: destination register
* Rm: source register
breakpoint_t *breakpoint = target->breakpoints;
breakpoint_t **breakpoint_p = &target->breakpoints;
int retval;
-
+
while (breakpoint)
{
if (breakpoint->address == address)
breakpoint_p = &breakpoint->next;
breakpoint = breakpoint->next;
}
-
+
(*breakpoint_p) = malloc(sizeof(breakpoint_t));
(*breakpoint_p)->address = address;
(*breakpoint_p)->length = length;
(*breakpoint_p)->set = 0;
(*breakpoint_p)->orig_instr = malloc(length);
(*breakpoint_p)->next = NULL;
-
+
if ((retval = target_add_breakpoint(target, *breakpoint_p)) != ERROR_OK)
{
switch (retval)
break;
}
}
-
- LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x",
+
+ LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x",
breakpoint_type_strings[(*breakpoint_p)->type],
(*breakpoint_p)->address, (*breakpoint_p)->length);
-
+
return ERROR_OK;
}
{
breakpoint_t *breakpoint = target->breakpoints;
breakpoint_t **breakpoint_p = &target->breakpoints;
-
+
while (breakpoint)
{
if (breakpoint == breakpoint_remove)
breakpoint_p = &breakpoint->next;
breakpoint = breakpoint->next;
}
-
+
if (breakpoint == NULL)
return;
-
+
target_remove_breakpoint(target, breakpoint);
-
+
(*breakpoint_p) = breakpoint->next;
free(breakpoint->orig_instr);
free(breakpoint);
{
breakpoint_t *breakpoint = target->breakpoints;
breakpoint_t **breakpoint_p = &target->breakpoints;
-
+
while (breakpoint)
{
if (breakpoint->address == address)
breakpoint_p = &breakpoint->next;
breakpoint = breakpoint->next;
}
-
+
if (breakpoint)
{
breakpoint_free(target, breakpoint);
breakpoint_t* breakpoint_find(target_t *target, uint32_t address)
{
breakpoint_t *breakpoint = target->breakpoints;
-
+
while (breakpoint)
{
if (breakpoint->address == address)
return breakpoint;
breakpoint = breakpoint->next;
}
-
+
return NULL;
}
watchpoint_t *watchpoint = target->watchpoints;
watchpoint_t **watchpoint_p = &target->watchpoints;
int retval;
-
+
while (watchpoint)
{
if (watchpoint->address == address)
watchpoint_p = &watchpoint->next;
watchpoint = watchpoint->next;
}
-
+
(*watchpoint_p) = malloc(sizeof(watchpoint_t));
(*watchpoint_p)->address = address;
(*watchpoint_p)->length = length;
(*watchpoint_p)->rw = rw;
(*watchpoint_p)->set = 0;
(*watchpoint_p)->next = NULL;
-
+
if ((retval = target_add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
{
switch (retval)
break;
}
}
-
+
LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32 " of length 0x%8.8x",
watchpoint_rw_strings[(*watchpoint_p)->rw],
(*watchpoint_p)->address, (*watchpoint_p)->length);
-
+
return ERROR_OK;
}
watchpoint_p = &watchpoint->next;
watchpoint = watchpoint->next;
}
-
+
if (watchpoint == NULL)
return;
target_remove_watchpoint(target, watchpoint);
{
watchpoint_t *watchpoint = target->watchpoints;
watchpoint_t **watchpoint_p = &target->watchpoints;
-
+
while (watchpoint)
{
if (watchpoint->address == address)
watchpoint_p = &watchpoint->next;
watchpoint = watchpoint->next;
}
-
+
if (watchpoint)
{
watchpoint_free(target, watchpoint);
#define DCB_DCRDR 0xE000EDF8
#define DCB_DEMCR 0xE000EDFC
-#define DCRSR_WnR (1 << 16)
+#define DCRSR_WnR (1 << 16)
#define DWT_CTRL 0xE0001000
#define DWT_COMP0 0xE0001020
{
int common_magic;
arm_jtag_t jtag_info;
-
+
/* Context information */
uint32_t dcb_dhcsr;
uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */
uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */
-
+
/* Flash Patch and Breakpoint (FPB) */
int fp_num_lit;
int fp_num_code;
int fpb_enabled;
int auto_bp_type;
cortex_m3_fp_comparator_t *fp_comparator_list;
-
+
/* Data Watchpoint and Trace (DWT) */
int dwt_num_comp;
int dwt_comp_available;
cortex_m3_dwt_comparator_t *dwt_comparator_list;
-
+
/* Interrupts */
int intlinesnum;
uint32_t *intsetenable;
-
+
armv7m_common_t armv7m;
// swjdp_common_t swjdp_info;
void *arch_info;
fields[0].tap = jtag_info->tap;
fields[0].num_bits = 32;
fields[0].out_value = out_buf;
-
+
fields[0].in_value = NULL;
-
-
-
-
+
+
+
+
fields[1].tap = jtag_info->tap;
fields[1].num_bits = 3;
fields[1].out_value = &sysspeed_buf;
-
+
fields[1].in_value = NULL;
-
-
-
-
+
+
+
+
fields[2].tap = jtag_info->tap;
fields[2].num_bits = 32;
fields[2].out_value = instr_buf;
-
+
fields[2].in_value = NULL;
-
-
-
-
+
+
+
+
jtag_add_dr_scan(3, fields, jtag_get_end_state());
"status", "lo", "hi", "badvaddr", "cause", "pc"
};
-mips32_core_reg_t mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] =
+mips32_core_reg_t mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] =
{
{0, NULL, NULL},
{1, NULL, NULL},
{29, NULL, NULL},
{30, NULL, NULL},
{31, NULL, NULL},
-
+
{32, NULL, NULL},
{33, NULL, NULL},
{34, NULL, NULL},
mips32_core_reg_t *mips32_reg = reg->arch_info;
target_t *target = mips32_reg->target;
mips32_common_t *mips32_target = target->arch_info;
-
+
if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
}
retval = mips32_target->read_core_reg(target, mips32_reg->num);
-
+
return retval;
}
mips32_core_reg_t *mips32_reg = reg->arch_info;
target_t *target = mips32_reg->target;
uint32_t value = buf_get_u32(buf, 0, 32);
-
+
if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
}
-
+
buf_set_u32(reg->value, 0, 32, value);
reg->dirty = 1;
reg->valid = 1;
{
uint32_t reg_value;
mips32_core_reg_t *mips_core_reg;
-
+
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
-
+
if ((num < 0) || (num >= MIPS32NUMCOREREGS))
return ERROR_INVALID_ARGUMENTS;
buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
mips32->core_cache->reg_list[num].valid = 1;
mips32->core_cache->reg_list[num].dirty = 0;
-
- return ERROR_OK;
+
+ return ERROR_OK;
}
int mips32_write_core_reg(struct target_s *target, int num)
{
uint32_t reg_value;
mips32_core_reg_t *mips_core_reg;
-
+
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
if ((num < 0) || (num >= MIPS32NUMCOREREGS))
return ERROR_INVALID_ARGUMENTS;
-
+
reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
mips_core_reg = mips32->core_cache->reg_list[num].arch_info;
mips32->core_regs[num] = reg_value;
LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
mips32->core_cache->reg_list[num].valid = 1;
mips32->core_cache->reg_list[num].dirty = 0;
-
+
return ERROR_OK;
}
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
int i;
-
+
for (i = 0; i < mips32->core_cache->num_regs; i++)
{
mips32->core_cache->reg_list[i].valid = 0;
mips32->core_cache->reg_list[i].dirty = 0;
}
-
+
return ERROR_OK;
}
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
int i;
-
+
/* include floating point registers */
*reg_list_size = MIPS32NUMCOREREGS + MIPS32NUMFPREGS;
*reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
-
+
for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
(*reg_list)[i] = &mips32->core_cache->reg_list[i];
}
-
+
/* add dummy floating points regs */
for (i = MIPS32NUMCOREREGS; i < (MIPS32NUMCOREREGS + MIPS32NUMFPREGS); i++)
{
int mips32_save_context(target_t *target)
{
int i;
-
+
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
-
+
/* read core registers */
mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
-
+
for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
if (!mips32->core_cache->reg_list[i].valid)
mips32->read_core_reg(target, i);
}
}
-
- return ERROR_OK;
+
+ return ERROR_OK;
}
int mips32_restore_context(target_t *target)
{
int i;
-
+
/* get pointers to arch-specific information */
mips32_common_t *mips32 = target->arch_info;
mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
-
+
for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
if (mips32->core_cache->reg_list[i].dirty)
mips32->write_core_reg(target, i);
}
}
-
+
/* write core regs */
mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
-
- return ERROR_OK;
+
+ return ERROR_OK;
}
int mips32_arch_state(struct target_s *target)
{
mips32_common_t *mips32 = target->arch_info;
-
+
if (mips32->common_magic != MIPS32_COMMON_MAGIC)
{
LOG_ERROR("BUG: called for a non-MIPS32 target");
exit(-1);
}
-
+
LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
-
+
return ERROR_OK;
}
reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
mips32_core_reg_t *arch_info = malloc(sizeof(mips32_core_reg_t) * num_regs);
int i;
-
+
if (mips32_core_reg_arch_type == -1)
mips32_core_reg_arch_type = register_reg_arch_type(mips32_get_core_reg, mips32_set_core_reg);
register_init_dummy(&mips32_gdb_dummy_fp_reg);
- /* Build the process context cache */
+ /* Build the process context cache */
cache->name = "mips32 registers";
cache->next = NULL;
cache->reg_list = reg_list;
cache->num_regs = num_regs;
(*cache_p) = cache;
mips32->core_cache = cache;
-
+
for (i = 0; i < num_regs; i++)
{
arch_info[i] = mips32_core_reg_list_arch_info[i];
reg_list[i].arch_type = mips32_core_reg_arch_type;
reg_list[i].arch_info = &arch_info[i];
}
-
+
return cache;
}
{
target->arch_info = mips32;
mips32->common_magic = MIPS32_COMMON_MAGIC;
-
+
/* has breakpoint/watchpint unit been scanned */
mips32->bp_scanned = 0;
mips32->data_break_list = NULL;
-
+
mips32->ejtag_info.tap = tap;
mips32->read_core_reg = mips32_read_core_reg;
mips32->write_core_reg = mips32_write_core_reg;
-
+
return ERROR_OK;
}
int mips32_examine(struct target_s *target)
{
mips32_common_t *mips32 = target->arch_info;
-
+
if (!target_was_examined(target))
{
target_set_examined(target);
-
+
/* we will configure later */
mips32->bp_scanned = 0;
mips32->num_inst_bpoints = 0;
mips32->num_inst_bpoints_avail = 0;
mips32->num_data_bpoints_avail = 0;
}
-
+
return ERROR_OK;
}
int retval;
uint32_t dcr, bpinfo;
int i;
-
+
if (mips32->bp_scanned)
return ERROR_OK;
-
+
/* get info about breakpoint support */
if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK)
return retval;
-
+
if (dcr & (1 << 16))
{
/* get number of inst breakpoints */
if ((retval = target_read_u32(target, EJTAG_IBS, &bpinfo)) != ERROR_OK)
return retval;
-
+
mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(mips32_comparator_t));
{
mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i);
}
-
+
/* clear IBIS reg */
if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
return retval;
}
-
+
if (dcr & (1 << 17))
{
/* get number of data breakpoints */
if ((retval = target_read_u32(target, EJTAG_DBS, &bpinfo)) != ERROR_OK)
return retval;
-
+
mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(mips32_comparator_t));
{
mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i);
}
-
+
/* clear DBIS reg */
if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK)
return retval;
}
-
+
LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, mips32->num_data_bpoints);
-
+
mips32->bp_scanned = 1;
-
+
return ERROR_OK;
}
int retval;
int update = 0;
uint32_t dcr;
-
+
/* read debug control register */
if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK)
return retval;
-
+
if (enable)
{
if (!(dcr & (1 << 4)))
update = 1;
}
}
-
+
if (update)
{
if ((retval = target_write_u32(target, EJTAG_DCR, dcr)) != ERROR_OK)
return retval;
}
-
+
return ERROR_OK;
}
#define MIPS32_COMMON_MAGIC 0xB320B320
/* offsets into mips32 core register cache */
-enum
+enum
{
MIPS32_PC = 37,
MIPS32NUMCOREREGS
reg_cache_t *core_cache;
mips_ejtag_t ejtag_info;
uint32_t core_regs[MIPS32NUMCOREREGS];
-
+
int bp_scanned;
int num_inst_bpoints;
int num_data_bpoints;
int num_data_bpoints_avail;
mips32_comparator_t *inst_break_list;
mips32_comparator_t *data_break_list;
-
+
/* register cache to processor synchronization */
int (*read_core_reg)(struct target_s *target, int num);
int (*write_core_reg)(struct target_s *target, int num);
case 2:
*data = (v >> 16) & 0xff;
break;
- case 3:
+ case 3:
*data = (v >> 24) & 0xff;
break;
}
- write word
- write array of words
-One thing to be aware of is that the MIPS32 cpu will execute the
+One thing to be aware of is that the MIPS32 cpu will execute the
instruction after a branch instruction (one delay slot).
For example:
B foo
LW $1, ($2 +100)
-The LW $1, ($2 +100) instruction is also executed. If this is
+The LW $1, ($2 +100) instruction is also executed. If this is
not wanted a NOP can be inserted:
LW $2, ($5 +10)
static int wait_for_pracc_rw(mips_ejtag_t *ejtag_info, uint32_t *ctrl)
{
uint32_t ejtag_ctrl;
-
- while (1)
+
+ while (1)
{
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
ejtag_ctrl = ejtag_info->ejtag_ctrl;
LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
return ERROR_JTAG_DEVICE_ERROR;
}
-
+
*ctrl = ejtag_ctrl;
return ERROR_OK;
}
{
/* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
* to start of debug vector */
-
+
data = 0;
LOG_ERROR("Error reading unexpected address %8.8" PRIx32 "", address);
return ERROR_JTAG_DEVICE_ERROR;
}
-
+
/* Send the data out */
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
mips_ejtag_drscan_32(ctx->ejtag_info, &data);
jtag_add_clocks(5);
jtag_execute_queue();
-
+
return ERROR_OK;
}
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
mips_ejtag_drscan_32(ctx->ejtag_info, &data);
-
+
/* Clear access pending bit */
ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
jtag_add_clocks(5);
jtag_execute_queue();
-
+
if ((address >= MIPS32_PRACC_PARAM_IN)
&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
{
LOG_ERROR("Error writing unexpected address %8.8" PRIx32 "", address);
return ERROR_JTAG_DEVICE_ERROR;
}
-
+
return ERROR_OK;
}
mips32_pracc_context ctx;
int retval;
int pass = 0;
-
+
ctx.local_iparam = param_in;
ctx.local_oparam = param_out;
ctx.num_iparam = num_param_in;
ctx.code_len = code_len;
ctx.ejtag_info = ejtag_info;
ctx.stack_offset = 0;
-
+
while (1)
{
if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
return retval;
-
+
address = data = 0;
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
mips_ejtag_drscan_32(ejtag_info, &address);
// printf("Adres: %.8x\n", address);
-
+
/* Check for read or write */
if (ejtag_ctrl & EJTAG_CTRL_PRNW)
{
{
break;
}
-
+
if ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK)
return retval;
}
-
+
if (cycle == 0)
break;
}
-
+
/* stack sanity check */
if (ctx.stack_offset != 0)
{
LOG_DEBUG("Pracc Stack not zero");
}
-
+
return ERROR_OK;
}
else
return mips32_pracc_read_mem32(ejtag_info, addr, count, (uint32_t*)buf);
}
-
+
return ERROR_OK;
}
int mips32_pracc_read_mem32(mips_ejtag_t *ejtag_info, uint32_t addr, int count, uint32_t *buf)
-{
+{
uint32_t code[] = {
/* start: */
MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
MIPS32_SW(9,0,15), /* sw $9,($15) */
MIPS32_SW(10,0,15), /* sw $10,($15) */
MIPS32_SW(11,0,15), /* sw $11,($15) */
-
+
MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */
/* loop: */
MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
MIPS32_NOP,
-
+
MIPS32_LW(8,0,9), /* lw $8,0($9), Load $8 with the word @mem[$9] */
MIPS32_SW(8,0,11), /* sw $8,0($11) */
-
+
MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
MIPS32_ADDI(9,9,4), /* $1 += 4 */
MIPS32_ADDI(11,11,4), /* $11 += 4 */
-
+
MIPS32_NOP,
MIPS32_B(NEG16(9)), /* b loop */
MIPS32_NOP,
MIPS32_B(NEG16(31)), /* b start */
MIPS32_NOP,
};
-
+
int retval = ERROR_OK;
int blocksize;
int bytesread;
uint32_t param_in[2];
-
+
bytesread = 0;
-
+
while (count > 0)
- {
+ {
blocksize = count;
if (count > 0x400)
blocksize = 0x400;
-
+
param_in[0] = addr;
param_in[1] = blocksize;
-
- if ((retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code,
+
+ if ((retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code,
sizeof(param_in)/sizeof(param_in[0]), param_in, blocksize, &buf[bytesread], 1)) != ERROR_OK)
{
return retval;
}
-
+
count -= blocksize;
addr += blocksize;
bytesread += blocksize;
param_in[0] = addr;
- if ((retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code,
+ if ((retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code,
sizeof(param_in)/sizeof(param_in[0]), param_in, sizeof(uint32_t), buf, 1)) != ERROR_OK)
{
return retval;
MIPS32_SW(9,0,15), /* sw $9,($15) */
MIPS32_SW(10,0,15), /* sw $10,($15) */
MIPS32_SW(11,0,15), /* sw $11,($15) */
-
+
MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */
/* loop: */
MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
MIPS32_NOP,
-
+
MIPS32_LHU(8,0,9), /* lw $8,0($9), Load $8 with the halfword @mem[$9] */
MIPS32_SW(8,0,11), /* sw $8,0($11) */
-
+
MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
MIPS32_ADDI(9,9,2), /* $9 += 2 */
MIPS32_ADDI(11,11,4), /* $11 += 4 */
// /* TODO remove array */
uint32_t param_out[count];
int i;
-
+
// int retval;
int blocksize;
int bytesread;
uint32_t param_in[2];
-
+
bytesread = 0;
-
+
//while (count > 0)
- {
+ {
blocksize = count;
if (count > 0x400)
blocksize = 0x400;
-
+
param_in[0] = addr;
param_in[1] = blocksize;
-
+
mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
sizeof(param_in)/sizeof(param_in[0]), param_in, count, param_out, 1);
-
+
// count -= blocksize;
// addr += blocksize;
// bytesread += blocksize;
}
-
+
for (i = 0; i < count; i++)
{
buf[i] = param_out[i];
}
-
+
return ERROR_OK;
}
MIPS32_SW(9,0,15), /* sw $9,($15) */
MIPS32_SW(10,0,15), /* sw $10,($15) */
MIPS32_SW(11,0,15), /* sw $11,($15) */
-
+
MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */
/* loop: */
MIPS32_BEQ(0,10,9), /* beq 0, $10, end */
MIPS32_NOP,
-
+
MIPS32_LBU(8,0,9), /* lw $8,0($9), Load t4 with the byte @mem[t1] */
MIPS32_SW(8,0,11), /* sw $8,0($11) */
-
+
MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
MIPS32_ADDI(9,9,1), /* $9 += 1 */
MIPS32_ADDI(11,11,4), /* $11 += 4 */
MIPS32_B(NEG16(31)), /* b start */
MIPS32_NOP,
};
-
+
// /* TODO remove array */
uint32_t param_out[count];
int i;
-
+
// int retval;
int blocksize;
int bytesread;
uint32_t param_in[2];
-
+
bytesread = 0;
-
+
// while (count > 0)
- {
+ {
blocksize = count;
if (count > 0x400)
blocksize = 0x400;
-
+
param_in[0] = addr;
param_in[1] = blocksize;
-
+
mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
sizeof(param_in)/sizeof(param_in[0]), param_in, count, param_out, 1);
-
+
// count -= blocksize;
// addr += blocksize;
// bytesread += blocksize;
}
-
+
for (i = 0; i < count; i++)
{
buf[i] = param_out[i];
else
return mips32_pracc_write_mem32(ejtag_info, addr, count, (uint32_t*)buf);
}
-
+
return ERROR_OK;
}
MIPS32_SW(9,0,15), /* sw $9,($15) */
MIPS32_SW(10,0,15), /* sw $10,($15) */
MIPS32_SW(11,0,15), /* sw $11,($15) */
-
+
MIPS32_ADDI(8,15,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)), //$8= MIPS32_PRACC_PARAM_IN
MIPS32_LW(9,0,8), /* Load write addr to $9 */
MIPS32_LW(10,4,8), //last address /* Load write count to $10 */
//loop:
MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
MIPS32_SW(11,0,9), /* sw $11,0($9) */
-
+
MIPS32_ADDI(9,9,4), /* $9 += 4 */
MIPS32_BNE(10,9,NEG16(4)), //was 9 BNE $10, 9, loop /* b loop */
MIPS32_ADDI(8,8,4), //this instruction is part of the loop (one delay slot)! /* $8 += 4 */
MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
MIPS32_NOP, //this one will not be executed
};
-
+
/* TODO remove array */
uint32_t param_in[count + 2];
param_in[0] = addr;
param_in[1] = addr + count * sizeof(uint32_t); //last address
-
+
memcpy(¶m_in[2], buf, count * sizeof(uint32_t));
-
+
mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
sizeof(param_in)/sizeof(param_in[0]),param_in, 0, NULL, 1);
MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
MIPS32_SW(8,0,15), /* sw $8,($15) */
MIPS32_SW(9,0,15), /* sw $9,($15) */
-
+
MIPS32_LW(8,NEG16((MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)-4), 15), //load R8 @ param_in[1] = data
MIPS32_LW(9,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN), 15), //load R9 @ param_in[0] = address
MIPS32_SW(9,0,15), /* sw $9,($15) */
MIPS32_SW(10,0,15), /* sw $10,($15) */
MIPS32_SW(11,0,15), /* sw $11,($15) */
-
+
MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
MIPS32_LW(9,0,8), /* Load write addr to $9 */
/* loop: */
MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
MIPS32_NOP,
-
+
MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
MIPS32_SH(11,0,9), /* sh $11,0($9) */
-
+
MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
MIPS32_ADDI(9,9,2), /* $9 += 2 */
MIPS32_ADDI(8,8,4), /* $8 += 4 */
-
+
MIPS32_NOP,
MIPS32_B(NEG16(9)), /* b loop */
MIPS32_NOP,
MIPS32_B(NEG16(30)), /* b start */
MIPS32_NOP,
};
-
+
/* TODO remove array */
uint32_t param_in[count + 2];
int i;
param_in[0] = addr;
param_in[1] = count;
-
+
for (i = 0; i < count; i++)
{
param_in[i + 2] = buf[i];
}
-
+
mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
sizeof(param_in)/sizeof(param_in[0]), param_in, 0, NULL, 1);
MIPS32_SW(9,0,15), /* sw $9,($15) */
MIPS32_SW(10,0,15), /* sw $10,($15) */
MIPS32_SW(11,0,15), /* sw $11,($15) */
-
+
MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
MIPS32_LW(9,0,8), /* Load write addr to $9 */
/* loop: */
MIPS32_BEQ(0,10,9), /* beq $0, $10, end */
MIPS32_NOP,
-
+
MIPS32_LW(11,0,8), /* lw $11,0($8), Load $11 with the word @mem[$8] */
MIPS32_SB(11,0,9), /* sb $11,0($9) */
-
+
MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */
MIPS32_ADDI(9,9,1), /* $9 += 1 */
MIPS32_ADDI(8,8,4), /* $8 += 4 */
-
+
MIPS32_NOP,
MIPS32_B(NEG16(9)), /* b loop */
MIPS32_NOP,
MIPS32_B(NEG16(30)), /* b start */
MIPS32_NOP,
};
-
+
/* TODO remove array */
uint32_t param_in[count + 2];
int retval;
int i;
param_in[0] = addr;
param_in[1] = count;
-
+
for (i = 0; i < count; i++)
{
param_in[i + 2] = buf[i];
}
-
+
retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
sizeof(param_in)/sizeof(param_in[0]), param_in, 0, NULL, 1);
MIPS32_LW(29,29*4,1), /* lw $29,29*4($1) */
MIPS32_LW(30,30*4,1), /* lw $30,30*4($1) */
MIPS32_LW(31,31*4,1), /* lw $31,31*4($1) */
-
+
MIPS32_LW(2,32*4,1), /* lw $2,32*4($1) */
MIPS32_MTC0(2,12,0), /* move $2 to status */
MIPS32_LW(2,33*4,1), /* lw $2,33*4($1) */
MIPS32_MTC0(2,13,0), /* move $2 to cause*/
MIPS32_LW(2,37*4,1), /* lw $2,37*4($1) */
MIPS32_MTC0(2,24,0), /* move $2 to pc */
-
+
MIPS32_LW(2,2*4,1), /* lw $2,2*4($1) */
MIPS32_LW(1,0,15), /* lw $1,($15) */
MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
MIPS32_B(NEG16(55)), /* b start */
MIPS32_NOP,
};
-
+
int retval;
-
+
retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
38, regs, 0, NULL, 1);
-
+
return retval;
}
MIPS32_SW(29,29*4,1), /* sw $29,29*4($1) */
MIPS32_SW(30,30*4,1), /* sw $30,30*4($1) */
MIPS32_SW(31,31*4,1), /* sw $31,31*4($1) */
-
+
MIPS32_MFC0(2,12,0), /* move status to $2 */
MIPS32_SW(2,32*4,1), /* sw $2,32*4($1) */
MIPS32_MFLO(2), /* move lo to $2 */
MIPS32_SW(2,36*4,1), /* sw $2,36*4($1) */
MIPS32_MFC0(2,24,0), /* move pc to $2 */
MIPS32_SW(2,37*4,1), /* sw $2,37*4($1) */
-
+
MIPS32_LW(2,0,15), /* lw $2,($15) */
MIPS32_LW(1,0,15), /* lw $1,($15) */
MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
MIPS32_B(NEG16(60)), /* b start */
MIPS32_NOP,
};
-
+
int retval;
-
+
retval = mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
0, NULL, 38, regs, 1);
-
+
return retval;
}
buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
field.in_value = NULL;
-
-
-
-
+
+
+
+
jtag_add_ir_scan(1, &field, jtag_get_end_state());
}
field.out_value = NULL;
field.in_value = (void*)idcode;
-
-
-
-
+
+
+
+
jtag_add_dr_scan(1, &field, jtag_get_end_state());
if (jtag_execute_queue() != ERROR_OK)
field.out_value = NULL;
field.in_value = (void*)impcode;
-
-
-
-
+
+
+
+
jtag_add_dr_scan(1, &field, jtag_get_end_state());
if (jtag_execute_queue() != ERROR_OK)
buf_set_u32(field.out_value, 0, field.num_bits, *data);
field.in_value = r;
-
-
-
-
+
+
+
+
jtag_add_dr_scan(1, &field, jtag_get_end_state());
if ((retval = jtag_execute_queue()) != ERROR_OK)
{
uint32_t inst;
inst = MIPS32_DRET;
-
+
/* execute our dret instruction */
mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
/* disable interrupts while stepping */
mips32_enable_interrupts(target, 0);
-
+
/* exit debug mode */
mips_ejtag_exit_debug(ejtag_info);
/* enable interrupts if we are running */
mips32_enable_interrupts(target, !debug_execution);
-
+
/* exit debug mode */
mips_ejtag_exit_debug(ejtag_info);
target->debug_reason = DBG_REASON_NOTHALTED;
/* disable interrupts while stepping */
mips32_enable_interrupts(target, 0);
-
+
/* exit debug mode */
mips_ejtag_exit_debug(ejtag_info);
mips32_common_t *mips32 = target->arch_info;
mips32_comparator_t * comparator_list = mips32->inst_break_list;
int retval;
-
+
if (breakpoint->set)
{
LOG_WARNING("breakpoint already set");
if (breakpoint->length == 4)
{
uint32_t verify = 0xffffffff;
-
+
if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
{
return retval;
{
return retval;
}
-
+
if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
{
return retval;
else
{
uint16_t verify = 0xffff;
-
+
if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
{
return retval;
{
return retval;
}
-
+
if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
{
return retval;
return ERROR_OK;
}
}
-
+
breakpoint->set = 20; /* Any nice value but 0 */
}
mips32_common_t *mips32 = target->arch_info;
mips32_comparator_t * comparator_list = mips32->inst_break_list;
int retval;
-
+
if (!breakpoint->set)
{
LOG_WARNING("breakpoint not set");
if (breakpoint->length == 4)
{
uint32_t current_instr;
-
+
/* check that user program has not modified breakpoint instruction */
if ((retval = target_read_memory(target, breakpoint->address, 4, 1, (uint8_t*)¤t_instr)) != ERROR_OK)
{
else
{
uint16_t current_instr;
-
+
/* check that user program has not modified breakpoint instruction */
if ((retval = target_read_memory(target, breakpoint->address, 2, 1, (uint8_t*)¤t_instr)) != ERROR_OK)
{
return retval;
}
-
+
if (current_instr == MIPS16_SDBBP)
{
if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
LOG_INFO("no hardware breakpoint available");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
-
+
mips32->num_inst_bpoints_avail--;
- }
+ }
mips_m4k_set_breakpoint(target, breakpoint);
return retval;
/* TAP data register is loaded LSB first (little endian) */
- if (target->endianness == TARGET_BIG_ENDIAN)
+ if (target->endianness == TARGET_BIG_ENDIAN)
{
uint32_t i, t32;
uint16_t t16;
for (i = 0; i < (count*size); i += size)
{
- switch (size)
+ switch (size)
{
case 4:
t32 = be_to_h_u32(&buffer[i]);
break;
}
}
- }
+ }
/* if noDMA off, use DMAACC mode for memory write */
if (ejtag_info->impcode & EJTAG_IMP_NODMA)
{
mips_ejtag_get_idcode(ejtag_info, &idcode);
ejtag_info->idcode = idcode;
-
+
if (((idcode >> 1) & 0x7FF) == 0x29)
{
/* we are using a pic32mx so select ejtag port
if (free_size < size)
{
- LOG_WARNING("not enough working area available(requested %u, free %u)",
+ LOG_WARNING("not enough working area available(requested %u, free %u)",
(unsigned)(size), (unsigned)(free_size));
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
int target_write_buffer(struct target_s *target, uint32_t address, uint32_t size, uint8_t *buffer)
{
int retval;
- LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
+ LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
(int)size, (unsigned)address);
if (!target_was_examined(target))
if ((address + size - 1) < address)
{
/* GDB can request this when e.g. PC is 0xfffffffc*/
- LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
- (unsigned)address,
+ LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
+ (unsigned)address,
(unsigned)size);
return ERROR_FAIL;
}
int target_read_buffer(struct target_s *target, uint32_t address, uint32_t size, uint8_t *buffer)
{
int retval;
- LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
+ LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
(int)size, (unsigned)address);
if (!target_was_examined(target))
if ((address + size - 1) < address)
{
/* GDB can request this when e.g. PC is 0xfffffffc*/
- LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
- address,
+ LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
+ address,
size);
return ERROR_FAIL;
}
if (retval == ERROR_OK)
{
*value = target_buffer_get_u32(target, value_buf);
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
- address,
+ LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
+ address,
*value);
}
else
{
*value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
+ LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
address);
}
if (retval == ERROR_OK)
{
*value = target_buffer_get_u16(target, value_buf);
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
- address,
+ LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
+ address,
*value);
}
else
{
*value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
+ LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
address);
}
if (retval == ERROR_OK)
{
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
- address,
+ LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
+ address,
*value);
}
else
{
*value = 0x0;
- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
+ LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
address);
}
return ERROR_FAIL;
}
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
- address,
+ LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
+ address,
value);
target_buffer_set_u32(target, value_buf, value);
return ERROR_FAIL;
}
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
- address,
+ LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
+ address,
value);
target_buffer_set_u16(target, value_buf, value);
return ERROR_FAIL;
}
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
+ LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
address, value);
if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
for (i = 0; i < cache->num_regs; i++)
{
value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);
- command_print(cmd_ctx, "(%i) %s (/%i): 0x%s (dirty: %i, valid: %i)",
- count++,
- cache->reg_list[i].name,
+ command_print(cmd_ctx, "(%i) %s (/%i): 0x%s (dirty: %i, valid: %i)",
+ count++,
+ cache->reg_list[i].name,
(int)(cache->reg_list[i].size),
- value,
- cache->reg_list[i].dirty,
+ value,
+ cache->reg_list[i].dirty,
cache->reg_list[i].valid);
free(value);
}
{
output_len += snprintf(output + output_len,
sizeof(output) - output_len,
- "0x%8.8x: ",
+ "0x%8.8x: ",
(unsigned)(address + (i*size)));
}
duration_t duration;
char *duration_text;
-
+
int retval = parse_load_image_command_args(args, argc,
&image, &min_address, &max_address);
if (ERROR_OK != retval)
buffer = malloc(image.sections[i].size);
if (buffer == NULL)
{
- command_print(cmd_ctx,
- "error allocating buffer for section (%d bytes)",
+ command_print(cmd_ctx,
+ "error allocating buffer for section (%d bytes)",
(int)(image.sections[i].size));
break;
}
break;
}
image_size += length;
- command_print(cmd_ctx, "%u byte written at address 0x%8.8" PRIx32 "",
- (unsigned int)length,
+ command_print(cmd_ctx, "%u byte written at address 0x%8.8" PRIx32 "",
+ (unsigned int)length,
image.sections[i].base_address + offset);
}
if (retval == ERROR_OK)
{
- command_print(cmd_ctx, "downloaded %u byte in %s",
- (unsigned int)image_size,
+ command_print(cmd_ctx, "downloaded %u byte in %s",
+ (unsigned int)image_size,
duration_text);
}
free(duration_text);
buffer = malloc(image.sections[i].size);
if (buffer == NULL)
{
- command_print(cmd_ctx,
- "error allocating buffer for section (%d bytes)",
+ command_print(cmd_ctx,
+ "error allocating buffer for section (%d bytes)",
(int)(image.sections[i].size));
break;
}
{
if (data[t] != buffer[t])
{
- command_print(cmd_ctx,
- "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n",
- (unsigned)(t + image.sections[i].base_address),
- data[t],
+ command_print(cmd_ctx,
+ "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n",
+ (unsigned)(t + image.sections[i].base_address),
+ data[t],
buffer[t]);
free(data);
free(buffer);
}
} else
{
- command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "",
- image.sections[i].base_address,
+ command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "",
+ image.sections[i].base_address,
buf_cnt);
}
if (retval == ERROR_OK)
{
- command_print(cmd_ctx, "verified %u bytes in %s",
- (unsigned int)image_size,
+ command_print(cmd_ctx, "verified %u bytes in %s",
+ (unsigned int)image_size,
duration_text);
}
free(duration_text);
char* buf = buf_to_str(breakpoint->orig_instr,
breakpoint->length, 16);
command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i, 0x%s",
- breakpoint->address,
+ breakpoint->address,
breakpoint->length,
breakpoint->set, buf);
free(buf);
else
{
command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i",
- breakpoint->address,
+ breakpoint->address,
breakpoint->length, breakpoint->set);
}
while (watchpoint)
{
- command_print(cmd_ctx,
- "address: 0x%8.8" PRIx32 ", len: 0x%8.8x, r/w/a: %i, value: 0x%8.8" PRIx32 ", mask: 0x%8.8" PRIx32 "",
- watchpoint->address,
+ command_print(cmd_ctx,
+ "address: 0x%8.8" PRIx32 ", len: 0x%8.8x, r/w/a: %i, value: 0x%8.8" PRIx32 ", mask: 0x%8.8" PRIx32 "",
+ watchpoint->address,
watchpoint->length,
(int)(watchpoint->rw),
watchpoint->value,
} else {
char buf[100];
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
- addr,
+ sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
+ addr,
width);
Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
return JIM_ERR;
retval = target_read_memory(target, addr, width, count, buffer);
if (retval != ERROR_OK) {
/* BOO !*/
- LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
- (unsigned int)addr,
- (int)width,
+ LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
+ (unsigned int)addr,
+ (int)width,
(int)count);
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
} else {
char buf[100];
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads",
- (unsigned int)addr,
+ sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads",
+ (unsigned int)addr,
(int)width);
Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
return JIM_ERR;
retval = target_write_memory(target, addr, width, count, buffer);
if (retval != ERROR_OK) {
/* BOO !*/
- LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed",
- (unsigned int)addr,
- (int)width,
+ LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed",
+ (unsigned int)addr,
+ (int)width,
(int)count);
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
buffer = malloc(image.sections[i].size);
if (buffer == NULL)
{
- command_print(cmd_ctx, "error allocating buffer for section (%d bytes)",
+ command_print(cmd_ctx, "error allocating buffer for section (%d bytes)",
(int)(image.sections[i].size));
break;
}
fastload[i].length = length;
image_size += length;
- command_print(cmd_ctx, "%u byte written at address 0x%8.8x",
- (unsigned int)length,
+ command_print(cmd_ctx, "%u byte written at address 0x%8.8x",
+ (unsigned int)length,
((unsigned int)(image.sections[i].base_address + offset)));
}
for (i = 0; i < fastload_num;i++)
{
target_t *target = get_current_target(cmd_ctx);
- command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x",
- (unsigned int)(fastload[i].address),
+ command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x",
+ (unsigned int)(fastload[i].address),
(unsigned int)(fastload[i].length));
if (retval == ERROR_OK)
{
/*
- * Local Variables:
+ * Local Variables:
* c-basic-offset: 4
* tab-width: 4
* End:
trace_t *trace = target->trace_info;
LOG_DEBUG("tracepoint: %i", (int)number);
-
+
if (number < trace->num_trace_points)
trace->trace_points[number].hit_counter++;
trace->trace_history_overflowed = 1;
}
}
-
+
return ERROR_OK;
}
{
target_t *target = get_current_target(cmd_ctx);
trace_t *trace = target->trace_info;
-
+
if (argc == 0)
{
uint32_t i;
-
+
for (i = 0; i < trace->num_trace_points; i++)
{
command_print(cmd_ctx, "trace point 0x%8.8" PRIx32 " (%lld times hit)",
return ERROR_OK;
}
-
+
if (!strcmp(args[0], "clear"))
{
if (trace->trace_points)
}
trace->num_trace_points = 0;
trace->trace_points_size = 0;
-
+
return ERROR_OK;
}
-
+
/* resize array if necessary */
if (!trace->trace_points || (trace->trace_points_size == trace->num_trace_points))
{
trace->trace_points = realloc(trace->trace_points, sizeof(trace_point_t) * (trace->trace_points_size + 32));
trace->trace_points_size += 32;
}
-
+
trace->trace_points[trace->num_trace_points].address = strtoul(args[0], NULL, 0);
trace->trace_points[trace->num_trace_points].hit_counter = 0;
trace->num_trace_points++;
-
+
return ERROR_OK;
}
{
target_t *target = get_current_target(cmd_ctx);
trace_t *trace = target->trace_info;
-
+
if (argc > 0)
{
trace->trace_history_pos = 0;
/* clearing is implicit, we've just reset position anyway */
return ERROR_OK;
}
-
+
if (trace->trace_history)
free(trace->trace_history);
-
+
trace->trace_history_size = strtoul(args[0], NULL, 0);
trace->trace_history = malloc(sizeof(uint32_t) * trace->trace_history_size);
-
+
command_print(cmd_ctx, "new trace history size: %i", (int)(trace->trace_history_size));
}
else
first = trace->trace_history_pos;
last = trace->trace_history_pos - 1;
}
-
+
for (i = first; (i % trace->trace_history_size) != last; i++)
{
if (trace->trace_history[i % trace->trace_history_size] < trace->num_trace_points)
{
command_t *trace_cmd =
register_command(cmd_ctx, NULL, "trace", NULL, COMMAND_ANY, "trace commands");
-
+
register_command(cmd_ctx, trace_cmd, "history", handle_trace_history_command,
COMMAND_EXEC, "display trace history, ['clear'] history or set [size]");
/* position in JTAG scan chain */
jtag_tap_t *tap;
- /* IR length and instructions */
+ /* IR length and instructions */
int ir_length;
uint32_t dbgrx;
uint32_t dbgtx;
typedef struct xscale_common_s
{
int common_magic;
-
+
/* XScale registers (CP15, DBG) */
reg_cache_t *reg_cache;
char *variant;
xscale_jtag_t jtag_info;
-
+
/* current state of the debug handler */
int handler_installed;
int handler_running;
uint32_t handler_address;
-
+
/* target-endian buffers with exception vectors */
uint32_t low_vectors[8];
uint32_t high_vectors[8];
-
+
/* static low vectors */
uint8_t static_low_vectors_set; /* bit field with static vectors set by the user */
uint8_t static_high_vectors_set; /* bit field with static vectors set by the user */
uint32_t static_low_vectors[8];
uint32_t static_high_vectors[8];
- /* DCache cleaning */
+ /* DCache cleaning */
uint32_t cache_clean_address;
-
+
/* whether hold_rst and ext_dbg_break should be set */
int hold_rst;
int external_debug_break;
-
+
/* breakpoint / watchpoint handling */
int dbr_available;
int dbr0_used;
int ibcr1_used;
uint32_t arm_bkpt;
uint16_t thumb_bkpt;
-
+
uint8_t vector_catch;
xscale_trace_t trace;
-
+
int arch_debug_reason;
-
+
/* armv4/5 common stuff */
armv4_5_common_t armv4_5_common;
-
+
/* MMU/Caches */
armv4_5_mmu_common_t armv4_5_mmu;
uint32_t cp15_control_reg;
-
+
/* possible future enhancements that go beyond XScale common stuff */
void *arch_info;
-
+
int fast_memory_access;
} xscale_common_t;
#define REG_CPSR 16
#define REG_SPSR 17
-#define MODE_USR 0x10
+#define MODE_USR 0x10
#define MODE_FIQ 0x11
-#define MODE_IRQ 0x12
-#define MODE_SVC 0x13
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
#define MODE_ABT 0x17
#define MODE_UND 0x1b
#define MODE_SYS 0x1f