Merge pull request #119 from gnu-mcu-eclipse/riscv-upd

Update to master (Aug 10, 2017)
This commit is contained in:
Tim Newsome
2017-10-02 11:56:19 -07:00
committed by GitHub
30 changed files with 1681 additions and 630 deletions
+11 -11
View File
@@ -464,7 +464,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@@ -499,7 +499,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -532,7 +532,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -565,7 +565,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -598,7 +598,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@@ -631,7 +631,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@@ -1279,7 +1279,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK0_BASE_SD,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -1295,7 +1295,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 1,
.base_address = FLASH_BANK1_BASE_1024K_SD,
.controller_address = 0x400e0c00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@@ -1305,10 +1305,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
/* at91samg53n19 */
/* atsamg53n19 */
{
.chipid_cidr = 0x247e0ae0,
.name = "at91samg53n19",
.name = "atsamg53n19",
.total_flash_size = 512 * 1024,
.total_sram_size = 96 * 1024,
.n_gpnvms = 2,
@@ -1323,7 +1323,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
+34 -49
View File
@@ -25,7 +25,7 @@
#include <target/cortex_m.h>
#define SAMD_NUM_SECTORS 16
#define SAMD_NUM_PROT_BLOCKS 16
#define SAMD_PAGE_SIZE_MAX 1024
#define SAMD_FLASH ((uint32_t)0x00000000) /* physical Flash memory */
@@ -286,6 +286,7 @@ struct samd_info {
uint32_t page_size;
int num_pages;
int sector_size;
int prot_block_size;
bool probed;
struct target *target;
@@ -319,7 +320,7 @@ static const struct samd_part *samd_find_part(uint32_t id)
static int samd_protect_check(struct flash_bank *bank)
{
int res;
int res, prot_block;
uint16_t lock;
res = target_read_u16(bank->target,
@@ -328,8 +329,8 @@ static int samd_protect_check(struct flash_bank *bank)
return res;
/* Lock bits are active-low */
for (int i = 0; i < bank->num_sectors; i++)
bank->sectors[i].is_protected = !(lock & (1<<i));
for (prot_block = 0; prot_block < bank->num_prot_blocks; prot_block++)
bank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));
return ERROR_OK;
}
@@ -380,8 +381,6 @@ static int samd_probe(struct flash_bank *bank)
bank->size = part->flash_kb * 1024;
chip->sector_size = bank->size / SAMD_NUM_SECTORS;
res = samd_get_flash_page_info(bank->target, &chip->page_size,
&chip->num_pages);
if (res != ERROR_OK) {
@@ -397,21 +396,23 @@ static int samd_probe(struct flash_bank *bank)
part->flash_kb, chip->num_pages, chip->page_size);
}
/* Erase granularity = 1 row = 4 pages */
chip->sector_size = chip->page_size * 4;
/* Allocate the sector table */
bank->num_sectors = SAMD_NUM_SECTORS;
bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0]));
bank->num_sectors = chip->num_pages / 4;
bank->sectors = alloc_block_array(0, chip->sector_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
/* Fill out the sector information: all SAMD sectors are the same size and
* there is always a fixed number of them. */
for (int i = 0; i < bank->num_sectors; i++) {
bank->sectors[i].size = chip->sector_size;
bank->sectors[i].offset = i * chip->sector_size;
/* mark as unknown */
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = -1;
}
/* 16 protection blocks per device */
chip->prot_block_size = bank->size / SAMD_NUM_PROT_BLOCKS;
/* Allocate the table of protection blocks */
bank->num_prot_blocks = SAMD_NUM_PROT_BLOCKS;
bank->prot_blocks = alloc_block_array(0, chip->prot_block_size, bank->num_prot_blocks);
if (!bank->prot_blocks)
return ERROR_FAIL;
samd_protect_check(bank);
@@ -606,9 +607,10 @@ out_user_row:
return res;
}
static int samd_protect(struct flash_bank *bank, int set, int first, int last)
static int samd_protect(struct flash_bank *bank, int set, int first_prot_bl, int last_prot_bl)
{
struct samd_info *chip = (struct samd_info *)bank->driver_priv;
int res = ERROR_OK;
int prot_block;
/* We can issue lock/unlock region commands with the target running but
* the settings won't persist unless we're able to modify the LOCK regions
@@ -618,18 +620,16 @@ static int samd_protect(struct flash_bank *bank, int set, int first, int last)
return ERROR_TARGET_NOT_HALTED;
}
int res = ERROR_OK;
for (int s = first; s <= last; s++) {
if (set != bank->sectors[s].is_protected) {
/* Load an address that is within this sector (we use offset 0) */
for (prot_block = first_prot_bl; prot_block <= last_prot_bl; prot_block++) {
if (set != bank->prot_blocks[prot_block].is_protected) {
/* Load an address that is within this protection block (we use offset 0) */
res = target_write_u32(bank->target,
SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR,
((s * chip->sector_size) >> 1));
bank->prot_blocks[prot_block].offset >> 1);
if (res != ERROR_OK)
goto exit;
/* Tell the controller to lock that sector */
/* Tell the controller to lock that block */
res = samd_issue_nvmctrl_command(bank->target,
set ? SAMD_NVM_CMD_LR : SAMD_NVM_CMD_UR);
if (res != ERROR_OK)
@@ -644,7 +644,7 @@ static int samd_protect(struct flash_bank *bank, int set, int first, int last)
* locked. See Table 9-3 in the SAMD20 datasheet for more details. */
res = samd_modify_user_row(bank->target, set ? 0x0000 : 0xFFFF,
48 + first, 48 + last);
48 + first_prot_bl, 48 + last_prot_bl);
if (res != ERROR_OK)
LOG_WARNING("SAMD: protect settings were not made persistent!");
@@ -656,10 +656,9 @@ exit:
return res;
}
static int samd_erase(struct flash_bank *bank, int first, int last)
static int samd_erase(struct flash_bank *bank, int first_sect, int last_sect)
{
int res;
int rows_in_sector;
int res, s;
struct samd_info *chip = (struct samd_info *)bank->driver_priv;
if (bank->target->state != TARGET_HALTED) {
@@ -673,26 +672,12 @@ static int samd_erase(struct flash_bank *bank, int first, int last)
return ERROR_FLASH_BANK_NOT_PROBED;
}
/* The SAMD NVM has row erase granularity. There are four pages in a row
* and the number of rows in a sector depends on the sector size, which in
* turn depends on the Flash capacity as there is a fixed number of
* sectors. */
rows_in_sector = chip->sector_size / (chip->page_size * 4);
/* For each sector to be erased */
for (int s = first; s <= last; s++) {
if (bank->sectors[s].is_protected) {
LOG_ERROR("SAMD: failed to erase sector %d. That sector is write-protected", s);
return ERROR_FLASH_OPERATION_FAILED;
}
/* For each row in that sector */
for (int r = s * rows_in_sector; r < (s + 1) * rows_in_sector; r++) {
res = samd_erase_row(bank->target, r * chip->page_size * 4);
if (res != ERROR_OK) {
LOG_ERROR("SAMD: failed to erase sector %d", s);
return res;
}
for (s = first_sect; s <= last_sect; s++) {
res = samd_erase_row(bank->target, bank->sectors[s].offset);
if (res != ERROR_OK) {
LOG_ERROR("SAMD: failed to erase sector %d at 0x%08" PRIx32, s, bank->sectors[s].offset);
return res;
}
}
+5 -1
View File
@@ -48,6 +48,7 @@
#define EFM_FAMILY_ID_HAPPY_GECKO 77
#define EZR_FAMILY_ID_WONDER_GECKO 120
#define EZR_FAMILY_ID_LEOPARD_GECKO 121
#define EZR_FAMILY_ID_HAPPY_GECKO 122
#define EFM32_FLASH_ERASE_TMO 100
#define EFM32_FLASH_WDATAREADY_TMO 100
@@ -178,7 +179,8 @@ static int efm32x_read_info(struct flash_bank *bank,
EFM_FAMILY_ID_TINY_GECKO == efm32_info->part_family)
efm32_info->page_size = 512;
else if (EFM_FAMILY_ID_ZERO_GECKO == efm32_info->part_family ||
EFM_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family)
EFM_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family ||
EZR_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family)
efm32_info->page_size = 1024;
else if (EFM_FAMILY_ID_GIANT_GECKO == efm32_info->part_family ||
EFM_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) {
@@ -236,6 +238,7 @@ static int efm32x_decode_info(struct efm32_info *info, char *buf, int buf_size)
switch (info->part_family) {
case EZR_FAMILY_ID_WONDER_GECKO:
case EZR_FAMILY_ID_LEOPARD_GECKO:
case EZR_FAMILY_ID_HAPPY_GECKO:
printed = snprintf(buf, buf_size, "EZR32 ");
break;
default:
@@ -270,6 +273,7 @@ static int efm32x_decode_info(struct efm32_info *info, char *buf, int buf_size)
printed = snprintf(buf, buf_size, "Zero Gecko");
break;
case EFM_FAMILY_ID_HAPPY_GECKO:
case EZR_FAMILY_ID_HAPPY_GECKO:
printed = snprintf(buf, buf_size, "Happy Gecko");
break;
}
+1016 -311
View File
File diff suppressed because it is too large Load Diff
+220 -56
View File
@@ -59,10 +59,14 @@
*
* Sector sizes in kiBytes:
* 1 MiByte part with 4 x 16, 1 x 64, 7 x 128.
* 1.5 MiByte part with 4 x 16, 1 x 64, 11 x 128.
* 2 MiByte part with 4 x 16, 1 x 64, 7 x 128, 4 x 16, 1 x 64, 7 x 128.
* 1 MiByte STM32F42x/43x part with DB1M Option set:
* 4 x 16, 1 x 64, 3 x 128, 4 x 16, 1 x 64, 3 x 128.
*
* STM32F7[2|3]
* 512 kiByte part with 4 x 16, 1 x 64, 3 x 128.
*
* STM32F7[4|5]
* 1 MiByte part with 4 x 32, 1 x 128, 3 x 256.
*
@@ -93,6 +97,12 @@
* RM0410
* http://www.st.com/resource/en/reference_manual/dm00224583.pdf
*
* RM0430
* http://www.st.com/resource/en/reference_manual/dm00305666.pdf
*
* RM0431
* http://www.st.com/resource/en/reference_manual/dm00305990.pdf
*
* STM32F1x series - notice that this code was copy, pasted and knocked
* into a stm32f2x driver, so in case something has been converted or
* bugs haven't been fixed, here are the original manuals:
@@ -121,6 +131,7 @@
#define STM32_FLASH_CR 0x40023c10
#define STM32_FLASH_OPTCR 0x40023c14
#define STM32_FLASH_OPTCR1 0x40023c18
#define STM32_FLASH_OPTCR2 0x40023c1c
/* FLASH_CR register bits */
#define FLASH_PG (1 << 0)
@@ -152,6 +163,10 @@
#define OPTCR_START (1 << 1)
#define OPTCR_NDBANK (1 << 29) /* not dual bank mode */
#define OPTCR_DB1M (1 << 30) /* 1 MiB devices dual flash bank option */
#define OPTCR_SPRMOD (1 << 31) /* switches PCROPi/nWPRi interpretation */
/* STM32_FLASH_OPTCR2 register bits */
#define OPTCR2_PCROP_RDP (1 << 31) /* erase PCROP zone when decreasing RDP */
/* register unlock keys */
#define KEY1 0x45670123
@@ -166,14 +181,17 @@ struct stm32x_options {
uint16_t user_options; /* bit 0-7 usual options, bit 8-11 extra options */
uint32_t protection;
uint32_t boot_addr;
uint32_t optcr2_pcrop;
};
struct stm32x_flash_bank {
struct stm32x_options option_bytes;
int probed;
bool has_large_mem; /* F42x/43x/469/479/7xx in dual bank mode */
bool has_boot_addr; /* F7xx */
bool has_extra_options; /* F42x/43x/469/479/7xx */
bool has_boot_addr; /* F7xx */
bool has_optcr2_pcrop; /* F72x/73x */
int protection_bits; /* F413/423 */
uint32_t user_bank_size;
};
@@ -328,11 +346,13 @@ static int stm32x_read_options(struct flash_bank *bank)
* whereas F7 6 bits (IWDG_SW and WWDG_SW) in user_options */
stm32x_info->option_bytes.user_options = optiondata & 0xfc;
stm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff;
stm32x_info->option_bytes.protection = (optiondata >> 16) & 0xfff;
stm32x_info->option_bytes.protection =
(optiondata >> 16) & (~(0xffff << stm32x_info->protection_bits) & 0xffff);
if (stm32x_info->has_extra_options) {
/* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */
stm32x_info->option_bytes.user_options |= (optiondata >> 20) & 0xf00;
stm32x_info->option_bytes.user_options |= (optiondata >> 20) &
((0xf00 << (stm32x_info->protection_bits - 12)) & 0xf00);
}
if (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {
@@ -350,6 +370,20 @@ static int stm32x_read_options(struct flash_bank *bank)
}
}
if (stm32x_info->has_optcr2_pcrop) {
retval = target_read_u32(target, STM32_FLASH_OPTCR2, &optiondata);
if (retval != ERROR_OK)
return retval;
stm32x_info->option_bytes.optcr2_pcrop = optiondata;
if (stm32x_info->has_optcr2_pcrop &&
(stm32x_info->option_bytes.optcr2_pcrop & ~OPTCR2_PCROP_RDP)) {
LOG_INFO("PCROP Engaged");
}
} else {
stm32x_info->option_bytes.optcr2_pcrop = 0x0;
}
if (stm32x_info->option_bytes.RDP != 0xAA)
LOG_INFO("Device Security Bit Set");
@@ -371,11 +405,13 @@ static int stm32x_write_options(struct flash_bank *bank)
/* rebuild option data */
optiondata = stm32x_info->option_bytes.user_options & 0xfc;
optiondata |= stm32x_info->option_bytes.RDP << 8;
optiondata |= (stm32x_info->option_bytes.protection & 0x0fff) << 16;
optiondata |= (stm32x_info->option_bytes.protection &
(~(0xffff << stm32x_info->protection_bits))) << 16;
if (stm32x_info->has_extra_options) {
/* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */
optiondata |= (stm32x_info->option_bytes.user_options & 0xf00) << 20;
optiondata |= (stm32x_info->option_bytes.user_options &
((0xf00 << (stm32x_info->protection_bits - 12)) & 0xf00)) << 20;
}
if (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {
@@ -392,6 +428,14 @@ static int stm32x_write_options(struct flash_bank *bank)
return retval;
}
/* program extra pcrop register */
if (stm32x_info->has_optcr2_pcrop) {
retval = target_write_u32(target, STM32_FLASH_OPTCR2,
stm32x_info->option_bytes.optcr2_pcrop);
if (retval != ERROR_OK)
return retval;
}
/* program options */
retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata);
if (retval != ERROR_OK)
@@ -418,6 +462,8 @@ static int stm32x_write_options(struct flash_bank *bank)
static int stm32x_protect_check(struct flash_bank *bank)
{
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
struct flash_sector *prot_blocks;
int num_prot_blocks;
/* read write protection settings */
int retval = stm32x_read_options(bank);
@@ -426,27 +472,18 @@ static int stm32x_protect_check(struct flash_bank *bank)
return retval;
}
if (stm32x_info->has_boot_addr && stm32x_info->has_large_mem) {
/* F76x/77x: bit k protects sectors 2*k and 2*k+1 */
for (int i = 0; i < (bank->num_sectors >> 1); i++) {
if (stm32x_info->option_bytes.protection & (1 << i)) {
bank->sectors[i << 1].is_protected = 0;
bank->sectors[(i << 1) + 1].is_protected = 0;
} else {
bank->sectors[i << 1].is_protected = 1;
bank->sectors[(i << 1) + 1].is_protected = 1;
}
}
if (bank->prot_blocks) {
num_prot_blocks = bank->num_prot_blocks;
prot_blocks = bank->prot_blocks;
} else {
/* one protection bit per sector */
for (int i = 0; i < bank->num_sectors; i++) {
if (stm32x_info->option_bytes.protection & (1 << i))
bank->sectors[i].is_protected = 0;
else
bank->sectors[i].is_protected = 1;
}
num_prot_blocks = bank->num_sectors;
prot_blocks = bank->sectors;
}
for (int i = 0; i < num_prot_blocks; i++)
prot_blocks[i].is_protected =
~(stm32x_info->option_bytes.protection >> i) & 1;
return ERROR_OK;
}
@@ -515,17 +552,6 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
return retval;
}
if (stm32x_info->has_boot_addr && stm32x_info->has_large_mem) {
/* F76x/77x: bit k protects sectors 2*k and 2*k+1 */
if ((first & 1) != 0 || (last & 1) != 1) {
LOG_ERROR("sector protection must be double sector aligned");
return ERROR_FAIL;
} else {
first >>= 1;
last >>= 1;
}
}
for (int i = first; i <= last; i++) {
if (set)
stm32x_info->option_bytes.protection &= ~(1 << i);
@@ -829,7 +855,7 @@ static int stm32x_probe(struct flash_bank *bank)
{
struct target *target = bank->target;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
int i;
int i, num_prot_blocks;
uint16_t flash_size_in_kb;
uint32_t flash_size_reg = 0x1FFF7A22;
uint16_t max_sector_size_in_kb = 128;
@@ -841,15 +867,31 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->has_large_mem = false;
stm32x_info->has_boot_addr = false;
stm32x_info->has_extra_options = false;
stm32x_info->has_optcr2_pcrop = false;
stm32x_info->protection_bits = 12; /* max. number of nWRPi bits (in FLASH_OPTCR !!!) */
num_prot_blocks = 0;
if (bank->sectors) {
free(bank->sectors);
bank->num_sectors = 0;
bank->sectors = NULL;
}
if (bank->prot_blocks) {
free(bank->prot_blocks);
bank->num_prot_blocks = 0;
bank->prot_blocks = NULL;
}
/* read stm32 device id register */
int retval = stm32x_get_device_id(bank, &device_id);
if (retval != ERROR_OK)
return retval;
LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
device_id &= 0xfff; /* only bits 0-11 are used further on */
/* set max flash size depending on family, id taken from AN2606 */
switch (device_id & 0xfff) {
switch (device_id) {
case 0x411: /* F20x/21x */
case 0x413: /* F40x/41x */
max_flash_size_in_kb = 1024;
@@ -892,6 +934,21 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->has_boot_addr = true;
break;
case 0x452: /* F72x/73x */
max_flash_size_in_kb = 512;
flash_size_reg = 0x1FF07A22; /* yes, 0x1FF*0*7A22, not 0x1FF*F*7A22 */
stm32x_info->has_extra_options = true;
stm32x_info->has_boot_addr = true;
stm32x_info->has_optcr2_pcrop = true;
break;
case 0x463: /* F413x/423x */
max_flash_size_in_kb = 1536;
stm32x_info->has_extra_options = true;
stm32x_info->protection_bits = 15;
num_prot_blocks = 15;
break;
default:
LOG_WARNING("Cannot identify target as a STM32 family.");
return ERROR_FAIL;
@@ -920,12 +977,8 @@ static int stm32x_probe(struct flash_bank *bank)
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
/* Devices with > 1024 kiByte always are dual-banked */
if (flash_size_in_kb > 1024)
stm32x_info->has_large_mem = true;
/* F42x/43x/469/479 1024 kiByte devices have a dual bank option */
if ((device_id & 0xfff) == 0x419 || (device_id & 0xfff) == 0x434) {
if ((device_id == 0x419) || (device_id == 0x434)) {
uint32_t optiondata;
retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
if (retval != ERROR_OK) {
@@ -942,7 +995,7 @@ static int stm32x_probe(struct flash_bank *bank)
}
/* F76x/77x devices have a dual bank option */
if ((device_id & 0xfff) == 0x451) {
if (device_id == 0x451) {
uint32_t optiondata;
retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
if (retval != ERROR_OK) {
@@ -963,11 +1016,6 @@ static int stm32x_probe(struct flash_bank *bank)
int num_pages = flash_size_in_kb / max_sector_size_in_kb
+ (stm32x_info->has_large_mem ? 8 : 4);
if (bank->sectors) {
free(bank->sectors);
bank->sectors = NULL;
}
bank->base = base_address;
bank->num_sectors = num_pages;
bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
@@ -978,15 +1026,44 @@ static int stm32x_probe(struct flash_bank *bank)
bank->size = 0;
LOG_DEBUG("allocated %d sectors", num_pages);
/* F76x/77x in dual bank mode */
if ((device_id == 0x451) && stm32x_info->has_large_mem)
num_prot_blocks = num_pages >> 1;
if (num_prot_blocks) {
bank->prot_blocks = malloc(sizeof(struct flash_sector) * num_prot_blocks);
for (i = 0; i < num_prot_blocks; i++)
bank->prot_blocks[i].is_protected = 0;
LOG_DEBUG("allocated %d prot blocks", num_prot_blocks);
}
if (stm32x_info->has_large_mem) {
/* dual-bank */
setup_bank(bank, 0, flash_size_in_kb >> 1, max_sector_size_in_kb);
setup_bank(bank, num_pages >> 1, flash_size_in_kb >> 1,
max_sector_size_in_kb);
/* F767x/F77x in dual mode, one protection bit refers to two adjacent sectors */
if (device_id == 0x451) {
for (i = 0; i < num_prot_blocks; i++) {
bank->prot_blocks[i].offset = bank->sectors[i << 1].offset;
bank->prot_blocks[i].size = bank->sectors[i << 1].size << 1;
}
}
} else {
/* single-bank */
setup_bank(bank, 0, flash_size_in_kb, max_sector_size_in_kb);
/* F413/F423, sectors 14 and 15 share one common protection bit */
if (device_id == 0x463) {
for (i = 0; i < num_prot_blocks; i++) {
bank->prot_blocks[i].offset = bank->sectors[i].offset;
bank->prot_blocks[i].size = bank->sectors[i].size;
}
bank->prot_blocks[num_prot_blocks - 1].size <<= 1;
}
}
bank->num_prot_blocks = num_prot_blocks;
assert((bank->size >> 10) == flash_size_in_kb);
stm32x_info->probed = 1;
@@ -1107,6 +1184,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
case 0x1001:
rev_str = "Z";
break;
case 0x2000:
rev_str = "B";
break;
case 0x3000:
rev_str = "C";
break;
}
break;
@@ -1134,6 +1219,26 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
}
break;
case 0x452:
device_str = "STM32F7[2|3]x";
switch (rev_id) {
case 0x1000:
rev_str = "A";
break;
}
break;
case 0x463:
device_str = "STM32F4[1|2]3";
switch (rev_id) {
case 0x1000:
rev_str = "A";
break;
}
break;
default:
snprintf(buf, buf_size, "Cannot identify target as a STM32F2/4/7\n");
return ERROR_FAIL;
@@ -1164,8 +1269,8 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
target = bank->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
LOG_INFO("Target not halted");
/* return ERROR_TARGET_NOT_HALTED; */
}
if (stm32x_read_options(bank) != ERROR_OK) {
@@ -1203,8 +1308,8 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
target = bank->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
LOG_INFO("Target not halted");
/* return ERROR_TARGET_NOT_HALTED; */
}
if (stm32x_read_options(bank) != ERROR_OK) {
@@ -1215,6 +1320,9 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
/* clear readout protection and complementary option bytes
* this will also force a device unlock if set */
stm32x_info->option_bytes.RDP = 0xAA;
if (stm32x_info->has_optcr2_pcrop) {
stm32x_info->option_bytes.optcr2_pcrop = OPTCR2_PCROP_RDP | (~1 << bank->num_sectors);
}
if (stm32x_write_options(bank) != ERROR_OK) {
command_print(CMD_CTX, "%s failed to unlock device", bank->driver->name);
@@ -1327,8 +1435,12 @@ COMMAND_HANDLER(stm32f2x_handle_options_read_command)
" boot_add0 0x%04X, boot_add1 0x%04X",
stm32x_info->option_bytes.user_options,
boot_addr & 0xffff, (boot_addr & 0xffff0000) >> 16);
if (stm32x_info->has_optcr2_pcrop) {
command_print(CMD_CTX, "stm32f2x optcr2_pcrop 0x%08X",
stm32x_info->option_bytes.optcr2_pcrop);
}
} else {
command_print(CMD_CTX, "stm32f2x user_options 0x%03X,",
command_print(CMD_CTX, "stm32f2x user_options 0x%03X",
stm32x_info->option_bytes.user_options);
}
} else {
@@ -1345,7 +1457,7 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
int retval;
struct flash_bank *bank;
struct stm32x_flash_bank *stm32x_info = NULL;
uint16_t user_options, boot_addr0, boot_addr1;
uint16_t user_options, boot_addr0, boot_addr1, options_mask;
if (CMD_ARGC < 1) {
command_print(CMD_CTX, "stm32f2x options_write <bank> ...");
@@ -1378,9 +1490,11 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
}
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], user_options);
if (user_options & (stm32x_info->has_extra_options ? ~0xffc : ~0xfc)) {
options_mask = !stm32x_info->has_extra_options ? ~0xfc :
~(((0xf00 << (stm32x_info->protection_bits - 12)) | 0xff) & 0xffc);
if (user_options & options_mask) {
command_print(CMD_CTX, "stm32f2x invalid user_options");
return ERROR_COMMAND_SYNTAX_ERROR;
return ERROR_COMMAND_ARGUMENT_INVALID;
}
stm32x_info->option_bytes.user_options = user_options;
@@ -1400,6 +1514,48 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
return retval;
}
COMMAND_HANDLER(stm32f2x_handle_optcr2_write_command)
{
int retval;
struct flash_bank *bank;
struct stm32x_flash_bank *stm32x_info = NULL;
uint32_t optcr2_pcrop;
if (CMD_ARGC != 2) {
command_print(CMD_CTX, "stm32f2x optcr2_write <bank> <optcr2_value>");
return ERROR_COMMAND_SYNTAX_ERROR;
}
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
stm32x_info = bank->driver_priv;
if (!stm32x_info->has_optcr2_pcrop) {
command_print(CMD_CTX, "no optcr2 register");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
command_print(CMD_CTX, "INFO: To disable PCROP, set PCROP_RDP"
" with PCROPi bits STILL SET, then\nlock device and"
" finally unlock it. Clears PCROP and mass erases flash.");
retval = stm32x_read_options(bank);
if (ERROR_OK != retval)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], optcr2_pcrop);
stm32x_info->option_bytes.optcr2_pcrop = optcr2_pcrop;
if (stm32x_write_options(bank) != ERROR_OK) {
command_print(CMD_CTX, "stm32f2x failed to write options");
return ERROR_OK;
}
command_print(CMD_CTX, "stm32f2x optcr2_write complete.");
return retval;
}
static const struct command_registration stm32x_exec_command_handlers[] = {
{
.name = "lock",
@@ -1433,9 +1589,17 @@ static const struct command_registration stm32x_exec_command_handlers[] = {
.name = "options_write",
.handler = stm32f2x_handle_options_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id user_options [ boot_add0 boot_add1]",
.usage = "bank_id user_options [ boot_add0 boot_add1 ]",
.help = "Write option bytes",
},
{
.name = "optcr2_write",
.handler = stm32f2x_handle_optcr2_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id optcr2",
.help = "Write optcr2 word",
},
COMMAND_REGISTRATION_DONE
};
+5
View File
@@ -790,6 +790,11 @@ static int stm32lx_probe(struct flash_bank *bank)
flash_size_in_kb = 256;
}
/* 0x429 devices only use the lowest 8 bits of the flash size register */
if (retval == ERROR_OK && (device_id & 0xfff) == 0x429) {
flash_size_in_kb &= 0xff;
}
/* Failed reading flash size or flash size invalid (early silicon),
* default to max target family */
if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {
+86 -27
View File
@@ -583,9 +583,10 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
{
uint32_t offset;
uint8_t *buffer;
size_t length;
struct fileio *fileio;
if (CMD_ARGC != 3)
if (CMD_ARGC < 2 || CMD_ARGC > 3)
return ERROR_COMMAND_SYNTAX_ERROR;
struct duration bench;
@@ -596,7 +597,16 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
if (ERROR_OK != retval)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
offset = 0;
if (CMD_ARGC > 2)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
if (offset > p->size) {
LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
offset);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
return ERROR_FAIL;
@@ -608,20 +618,38 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
return retval;
}
buffer = malloc(filesize);
length = MIN(filesize, p->size - offset);
if (!length) {
LOG_INFO("Nothing to write to flash bank");
fileio_close(fileio);
return ERROR_OK;
}
if (length != filesize)
LOG_INFO("File content exceeds flash bank size. Only writing the "
"first %zu bytes of the file", length);
buffer = malloc(length);
if (buffer == NULL) {
fileio_close(fileio);
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
size_t buf_cnt;
if (fileio_read(fileio, filesize, buffer, &buf_cnt) != ERROR_OK) {
if (fileio_read(fileio, length, buffer, &buf_cnt) != ERROR_OK) {
free(buffer);
fileio_close(fileio);
return ERROR_FAIL;
}
retval = flash_driver_write(p, buffer, offset, buf_cnt);
if (buf_cnt != length) {
LOG_ERROR("Short read");
free(buffer);
return ERROR_FAIL;
}
retval = flash_driver_write(p, buffer, offset, length);
free(buffer);
buffer = NULL;
@@ -629,8 +657,8 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
command_print(CMD_CTX, "wrote %zu bytes from file %s to flash bank %u"
" at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
filesize, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, filesize));
length, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, length));
}
fileio_close(fileio);
@@ -646,7 +674,7 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
uint32_t length;
size_t written;
if (CMD_ARGC != 4)
if (CMD_ARGC < 2 || CMD_ARGC > 4)
return ERROR_COMMAND_SYNTAX_ERROR;
struct duration bench;
@@ -654,11 +682,31 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
struct flash_bank *p;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
if (ERROR_OK != retval)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
offset = 0;
if (CMD_ARGC > 2)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
if (offset > p->size) {
LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
offset);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
length = p->size - offset;
if (CMD_ARGC > 3)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
if (offset + length > p->size) {
LOG_ERROR("Length of %" PRIu32 " bytes with offset 0x%8.8" PRIx32
" is out of range of the flash bank", length, offset);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
buffer = malloc(length);
if (buffer == NULL) {
@@ -705,6 +753,7 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
struct fileio *fileio;
size_t read_cnt;
size_t filesize;
size_t length;
int differ;
if (CMD_ARGC < 2 || CMD_ARGC > 3)
@@ -741,14 +790,26 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
return retval;
}
buffer_file = malloc(filesize);
length = MIN(filesize, p->size - offset);
if (!length) {
LOG_INFO("Nothing to compare with flash bank");
fileio_close(fileio);
return ERROR_OK;
}
if (length != filesize)
LOG_INFO("File content exceeds flash bank size. Only comparing the "
"first %zu bytes of the file", length);
buffer_file = malloc(length);
if (buffer_file == NULL) {
LOG_ERROR("Out of memory");
fileio_close(fileio);
return ERROR_FAIL;
}
retval = fileio_read(fileio, filesize, buffer_file, &read_cnt);
retval = fileio_read(fileio, length, buffer_file, &read_cnt);
fileio_close(fileio);
if (retval != ERROR_OK) {
LOG_ERROR("File read failure");
@@ -756,20 +817,20 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
return retval;
}
if (read_cnt != filesize) {
if (read_cnt != length) {
LOG_ERROR("Short read");
free(buffer_file);
return ERROR_FAIL;
}
buffer_flash = malloc(filesize);
buffer_flash = malloc(length);
if (buffer_flash == NULL) {
LOG_ERROR("Out of memory");
free(buffer_file);
return ERROR_FAIL;
}
retval = flash_driver_read(p, buffer_flash, offset, read_cnt);
retval = flash_driver_read(p, buffer_flash, offset, length);
if (retval != ERROR_OK) {
LOG_ERROR("Flash read error");
free(buffer_flash);
@@ -780,15 +841,15 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
if (duration_measure(&bench) == ERROR_OK)
command_print(CMD_CTX, "read %zd bytes from file %s and flash bank %u"
" at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
read_cnt, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, read_cnt));
length, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, length));
differ = memcmp(buffer_file, buffer_flash, read_cnt);
differ = memcmp(buffer_file, buffer_flash, length);
command_print(CMD_CTX, "contents %s", differ ? "differ" : "match");
if (differ) {
uint32_t t;
int diffs = 0;
for (t = 0; t < read_cnt; t++) {
for (t = 0; t < length; t++) {
if (buffer_flash[t] == buffer_file[t])
continue;
command_print(CMD_CTX, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
@@ -908,10 +969,9 @@ static const struct command_registration flash_exec_command_handlers[] = {
.name = "write_bank",
.handler = handle_flash_write_bank_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset",
.help = "Write binary data from file to flash bank, "
"starting at specified byte offset from the "
"beginning of the bank.",
.usage = "bank_id filename [offset]",
.help = "Write binary data from file to flash bank. Allow optional "
"offset from beginning of the bank (defaults to zero).",
},
{
.name = "write_image",
@@ -926,10 +986,9 @@ static const struct command_registration flash_exec_command_handlers[] = {
.name = "read_bank",
.handler = handle_flash_read_bank_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset length",
.help = "Read binary data from flash bank to file, "
"starting at specified byte offset from the "
"beginning of the bank.",
.usage = "bank_id filename [offset [length]]",
.help = "Read binary data from flash bank to file. Allow optional "
"offset from beginning of the bank (defaults to zero).",
},
{
.name = "verify_bank",
+7 -5
View File
@@ -50,11 +50,12 @@ static int64_t current_time;
static int64_t start;
static const char * const log_strings[5] = {
static const char * const log_strings[6] = {
"User : ",
"Error: ",
"Warn : ", /* want a space after each colon, all same width, colons aligned */
"Info : ",
"Debug: ",
"Debug: "
};
@@ -234,8 +235,8 @@ COMMAND_HANDLER(handle_debug_level_command)
if (CMD_ARGC == 1) {
int new_level;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
if ((new_level > LOG_LVL_DEBUG) || (new_level < LOG_LVL_SILENT)) {
LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG);
if ((new_level > LOG_LVL_DEBUG_IO) || (new_level < LOG_LVL_SILENT)) {
LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG_IO);
return ERROR_COMMAND_SYNTAX_ERROR;
}
debug_level = new_level;
@@ -279,7 +280,8 @@ static struct command_registration log_command_handlers[] = {
.mode = COMMAND_ANY,
.help = "Sets the verbosity level of debugging output. "
"0 shows errors only; 1 adds warnings; "
"2 (default) adds other info; 3 adds debugging.",
"2 (default) adds other info; 3 adds debugging; "
"4 adds extra verbose debugging.",
.usage = "number",
},
COMMAND_REGISTRATION_DONE
@@ -303,7 +305,7 @@ void log_init(void)
int retval = parse_int(debug_env, &value);
if (ERROR_OK == retval &&
debug_level >= LOG_LVL_SILENT &&
debug_level <= LOG_LVL_DEBUG)
debug_level <= LOG_LVL_DEBUG_IO)
debug_level = value;
}
+11 -1
View File
@@ -46,6 +46,7 @@
* LOG_LVL_WARNING - non-fatal errors, that may be resolved later
* LOG_LVL_INFO - state information, etc.
* LOG_LVL_DEBUG - debug statements, execution trace
* LOG_LVL_DEBUG_IO - verbose debug, low-level I/O trace
*/
enum log_levels {
LOG_LVL_SILENT = -3,
@@ -54,7 +55,8 @@ enum log_levels {
LOG_LVL_ERROR = 0,
LOG_LVL_WARNING = 1,
LOG_LVL_INFO = 2,
LOG_LVL_DEBUG = 3
LOG_LVL_DEBUG = 3,
LOG_LVL_DEBUG_IO = 4,
};
void log_printf(enum log_levels level, const char *file, unsigned line,
@@ -102,6 +104,14 @@ extern int debug_level;
#define LOG_LEVEL_IS(FOO) ((debug_level) >= (FOO))
#define LOG_DEBUG_IO(expr ...) \
do { \
if (debug_level >= LOG_LVL_DEBUG_IO) \
log_printf_lf(LOG_LVL_DEBUG, \
__FILE__, __LINE__, __func__, \
expr); \
} while (0)
#define LOG_DEBUG(expr ...) \
do { \
if (debug_level >= LOG_LVL_DEBUG) \
+3 -3
View File
@@ -596,7 +596,7 @@ static int cmsis_dap_swd_run_queue(void)
{
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
LOG_DEBUG("Executing %d queued transactions", pending_transfer_count);
LOG_DEBUG_IO("Executing %d queued transactions", pending_transfer_count);
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
@@ -616,7 +616,7 @@ static int cmsis_dap_swd_run_queue(void)
uint8_t cmd = pending_transfers[i].cmd;
uint32_t data = pending_transfers[i].data;
LOG_DEBUG("%s %s reg %x %"PRIx32,
LOG_DEBUG_IO("%s %s reg %x %"PRIx32,
cmd & SWD_CMD_APnDP ? "AP" : "DP",
cmd & SWD_CMD_RnW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1, data);
@@ -674,7 +674,7 @@ static int cmsis_dap_swd_run_queue(void)
uint32_t tmp = data;
idx += 4;
LOG_DEBUG("Read result: %"PRIx32, data);
LOG_DEBUG_IO("Read result: %"PRIx32, data);
/* Imitate posted AP reads */
if ((pending_transfers[i].cmd & SWD_CMD_APnDP) ||
+3 -3
View File
@@ -1109,12 +1109,12 @@ static void ftdi_swd_swdio_en(bool enable)
*/
static int ftdi_swd_run_queue(void)
{
LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length);
LOG_DEBUG_IO("Executing %zu queued transactions", swd_cmd_queue_length);
int retval;
struct signal *led = find_signal_by_name("LED");
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
LOG_DEBUG_IO("Skipping due to previous errors: %d", queued_retval);
goto skip;
}
@@ -1135,7 +1135,7 @@ static int ftdi_swd_run_queue(void)
for (size_t i = 0; i < swd_cmd_queue_length; i++) {
int ack = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1, 3);
LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
LOG_DEBUG_IO("%s %s %s reg %X = %08"PRIx32,
ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
swd_cmd_queue[i].cmd & SWD_CMD_APnDP ? "AP" : "DP",
swd_cmd_queue[i].cmd & SWD_CMD_RnW ? "read" : "write",
+28 -27
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2016 by Square, Inc. *
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -20,34 +20,35 @@
#include "config.h"
#endif
#include "rtos.h"
#include "rtos_standard_stackings.h"
#include "target/armv7m.h"
#include <helper/types.h>
#include <rtos/rtos.h>
#include <rtos/rtos_standard_stackings.h>
#include <target/armv7m.h>
static const struct stack_register_offset rtos_uCOS_III_Cortex_M_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
{ 0x20, 32 }, /* r0 */
{ 0x24, 32 }, /* r1 */
{ 0x28, 32 }, /* r2 */
{ 0x2c, 32 }, /* r3 */
{ 0x00, 32 }, /* r4 */
{ 0x04, 32 }, /* r5 */
{ 0x08, 32 }, /* r6 */
{ 0x0c, 32 }, /* r7 */
{ 0x10, 32 }, /* r8 */
{ 0x14, 32 }, /* r9 */
{ 0x18, 32 }, /* r10 */
{ 0x1c, 32 }, /* r11 */
{ 0x30, 32 }, /* r12 */
{ -2, 32 }, /* sp */
{ 0x34, 32 }, /* lr */
{ 0x38, 32 }, /* pc */
{ 0x3c, 32 }, /* xPSR */
static const struct stack_register_offset rtos_uCOS_III_Cortex_M_stack_offsets[] = {
{ 0x20, 32 }, /* r0 */
{ 0x24, 32 }, /* r1 */
{ 0x28, 32 }, /* r2 */
{ 0x2c, 32 }, /* r3 */
{ 0x00, 32 }, /* r4 */
{ 0x04, 32 }, /* r5 */
{ 0x08, 32 }, /* r6 */
{ 0x0c, 32 }, /* r7 */
{ 0x10, 32 }, /* r8 */
{ 0x14, 32 }, /* r9 */
{ 0x18, 32 }, /* r10 */
{ 0x1c, 32 }, /* r11 */
{ 0x30, 32 }, /* r12 */
{ -2, 32 }, /* sp */
{ 0x34, 32 }, /* lr */
{ 0x38, 32 }, /* pc */
{ 0x3c, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_uCOS_III_Cortex_M_stacking = {
0x40, /* stack_registers_size */
-1, /* stack_growth_direction */
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
rtos_generic_stack_align8, /* stack_alignment */
rtos_uCOS_III_Cortex_M_stack_offsets /* register_offsets */
0x40, /* stack_registers_size */
-1, /* stack_growth_direction */
ARRAY_SIZE(rtos_uCOS_III_Cortex_M_stack_offsets), /* num_output_registers */
rtos_generic_stack_align8, /* stack_alignment */
rtos_uCOS_III_Cortex_M_stack_offsets /* register_offsets */
};
+2 -2
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2016 by Square, Inc. *
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -23,7 +23,7 @@
#include "config.h"
#endif
#include "rtos.h"
#include <rtos/rtos.h>
extern const struct rtos_register_stacking rtos_uCOS_III_Cortex_M_stacking;
+70 -68
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2016 by Square, Inc. *
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -20,14 +20,14 @@
#include "config.h"
#endif
#include <helper/log.h>
#include <helper/time_support.h>
#include <jtag/jtag.h>
#include "target/target.h"
#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
#include "rtos/rtos_ucos_iii_stackings.h"
#include <helper/types.h>
#include <rtos/rtos.h>
#include <target/target.h>
#include <target/target_type.h>
#include "rtos_ucos_iii_stackings.h"
#ifndef UCOS_III_MAX_STRLEN
#define UCOS_III_MAX_STRLEN 64
@@ -55,18 +55,18 @@ struct uCOS_III_params {
static const struct uCOS_III_params uCOS_III_params_list[] = {
{
"cortex_m", /* target_name */
sizeof(uint32_t), /* pointer_width */
0, /* thread_stack_offset */
0, /* thread_name_offset */
0, /* thread_state_offset */
0, /* thread_priority_offset */
0, /* thread_prev_offset */
0, /* thread_next_offset */
false, /* thread_offsets_updated */
1, /* threadid_start */
"cortex_m", /* target_name */
sizeof(uint32_t), /* pointer_width */
0, /* thread_stack_offset */
0, /* thread_name_offset */
0, /* thread_state_offset */
0, /* thread_priority_offset */
0, /* thread_prev_offset */
0, /* thread_next_offset */
false, /* thread_offsets_updated */
1, /* threadid_start */
&rtos_uCOS_III_Cortex_M_stacking, /* stacking_info */
0, /* num_threads */
0, /* num_threads */
},
};
@@ -159,10 +159,10 @@ static int uCOS_III_find_last_thread_address(struct rtos *rtos, symbol_address_t
symbol_address_t thread_list_address = 0;
retval = target_read_memory(rtos->target,
rtos->symbols[uCOS_III_VAL_OSTaskDbgListPtr].address,
params->pointer_width,
1,
(void *)&thread_list_address);
rtos->symbols[uCOS_III_VAL_OSTaskDbgListPtr].address,
params->pointer_width,
1,
(void *)&thread_list_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread list address");
return retval;
@@ -173,10 +173,10 @@ static int uCOS_III_find_last_thread_address(struct rtos *rtos, symbol_address_t
*thread_address = thread_list_address;
retval = target_read_memory(rtos->target,
thread_list_address + params->thread_next_offset,
params->pointer_width,
1,
(void *)&thread_list_address);
thread_list_address + params->thread_next_offset,
params->pointer_width,
1,
(void *)&thread_list_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read next thread address");
return retval;
@@ -227,10 +227,10 @@ static int uCOS_III_update_thread_offsets(struct rtos *rtos)
const struct thread_offset_map *thread_offset_map = &thread_offset_maps[i];
int retval = target_read_memory(rtos->target,
rtos->symbols[thread_offset_map->symbol_value].address,
params->pointer_width,
1,
(void *)thread_offset_map->thread_offset);
rtos->symbols[thread_offset_map->symbol_value].address,
params->pointer_width,
1,
(void *)thread_offset_map->thread_offset);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread offset");
return retval;
@@ -244,7 +244,7 @@ static int uCOS_III_update_thread_offsets(struct rtos *rtos)
static int uCOS_III_detect_rtos(struct target *target)
{
return target->rtos->symbols != NULL &&
target->rtos->symbols[uCOS_III_VAL_OSRunning].address != 0;
target->rtos->symbols[uCOS_III_VAL_OSRunning].address != 0;
}
static int uCOS_III_reset_handler(struct target *target, enum target_reset_mode reset_mode, void *priv)
@@ -263,8 +263,7 @@ static int uCOS_III_create(struct target *target)
for (size_t i = 0; i < ARRAY_SIZE(uCOS_III_params_list); i++)
if (strcmp(uCOS_III_params_list[i].target_name, target->type->name) == 0) {
params = malloc(sizeof(*params) +
UCOS_III_MAX_THREADS * sizeof(*params->threads));
params = malloc(sizeof(*params) + (UCOS_III_MAX_THREADS * sizeof(*params->threads)));
if (params == NULL) {
LOG_ERROR("uCOS-III: out of memory");
return ERROR_FAIL;
@@ -294,13 +293,18 @@ static int uCOS_III_update_threads(struct rtos *rtos)
uint8_t rtos_running;
retval = target_read_u8(rtos->target,
rtos->symbols[uCOS_III_VAL_OSRunning].address,
&rtos_running);
rtos->symbols[uCOS_III_VAL_OSRunning].address,
&rtos_running);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read RTOS running");
return retval;
}
if (rtos_running != 1 && rtos_running != 0) {
LOG_ERROR("uCOS-III: invalid RTOS running value");
return ERROR_FAIL;
}
if (!rtos_running) {
rtos->thread_details = calloc(1, sizeof(struct thread_detail));
if (rtos->thread_details == NULL) {
@@ -327,10 +331,10 @@ static int uCOS_III_update_threads(struct rtos *rtos)
symbol_address_t current_thread_address = 0;
retval = target_read_memory(rtos->target,
rtos->symbols[uCOS_III_VAL_OSTCBCurPtr].address,
params->pointer_width,
1,
(void *)&current_thread_address);
rtos->symbols[uCOS_III_VAL_OSTCBCurPtr].address,
params->pointer_width,
1,
(void *)&current_thread_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read current thread address");
return retval;
@@ -338,8 +342,8 @@ static int uCOS_III_update_threads(struct rtos *rtos)
/* read number of tasks */
retval = target_read_u16(rtos->target,
rtos->symbols[uCOS_III_VAL_OSTaskQty].address,
(void *)&rtos->thread_count);
rtos->symbols[uCOS_III_VAL_OSTaskQty].address,
(void *)&rtos->thread_count);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread count");
return retval;
@@ -368,9 +372,7 @@ static int uCOS_III_update_threads(struct rtos *rtos)
char thread_str_buffer[UCOS_III_MAX_STRLEN + 1];
/* find or create new threadid */
retval = uCOS_III_find_or_create_thread(rtos,
thread_address,
&thread_detail->threadid);
retval = uCOS_III_find_or_create_thread(rtos, thread_address, &thread_detail->threadid);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to find or create thread");
return retval;
@@ -385,19 +387,19 @@ static int uCOS_III_update_threads(struct rtos *rtos)
symbol_address_t thread_name_address = 0;
retval = target_read_memory(rtos->target,
thread_address + params->thread_name_offset,
params->pointer_width,
1,
(void *)&thread_name_address);
thread_address + params->thread_name_offset,
params->pointer_width,
1,
(void *)&thread_name_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to name address");
return retval;
}
retval = target_read_buffer(rtos->target,
thread_name_address,
sizeof(thread_str_buffer),
(void *)thread_str_buffer);
thread_name_address,
sizeof(thread_str_buffer),
(void *)thread_str_buffer);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread name");
return retval;
@@ -411,16 +413,16 @@ static int uCOS_III_update_threads(struct rtos *rtos)
uint8_t thread_priority;
retval = target_read_u8(rtos->target,
thread_address + params->thread_state_offset,
&thread_state);
thread_address + params->thread_state_offset,
&thread_state);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread state");
return retval;
}
retval = target_read_u8(rtos->target,
thread_address + params->thread_priority_offset,
&thread_priority);
thread_address + params->thread_priority_offset,
&thread_priority);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread priority");
return retval;
@@ -434,15 +436,15 @@ static int uCOS_III_update_threads(struct rtos *rtos)
thread_state_str = "Unknown";
snprintf(thread_str_buffer, sizeof(thread_str_buffer), "State: %s, Priority: %d",
thread_state_str, thread_priority);
thread_state_str, thread_priority);
thread_detail->extra_info_str = strdup(thread_str_buffer);
/* read previous thread address */
retval = target_read_memory(rtos->target,
thread_address + params->thread_prev_offset,
params->pointer_width,
1,
(void *)&thread_address);
thread_address + params->thread_prev_offset,
params->pointer_width,
1,
(void *)&thread_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read previous thread address");
return retval;
@@ -470,19 +472,19 @@ static int uCOS_III_get_thread_reg_list(struct rtos *rtos, threadid_t threadid,
symbol_address_t stack_address = 0;
retval = target_read_memory(rtos->target,
thread_address + params->thread_stack_offset,
params->pointer_width,
1,
(void *)&stack_address);
thread_address + params->thread_stack_offset,
params->pointer_width,
1,
(void *)&stack_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read stack address");
return retval;
}
return rtos_generic_stack_read(rtos->target,
params->stacking_info,
stack_address,
hex_reg_list);
params->stacking_info,
stack_address,
hex_reg_list);
}
static int uCOS_III_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
+4 -4
View File
@@ -3037,16 +3037,16 @@ static void handle_md_output(struct command_context *cmd_ctx,
const char *value_fmt;
switch (size) {
case 8:
value_fmt = "%16.16llx ";
value_fmt = "%16.16"PRIx64" ";
break;
case 4:
value_fmt = "%8.8x ";
value_fmt = "%8.8"PRIx64" ";
break;
case 2:
value_fmt = "%4.4x ";
value_fmt = "%4.4"PRIx64" ";
break;
case 1:
value_fmt = "%2.2x ";
value_fmt = "%2.2"PRIx64" ";
break;
default:
/* "can't happen", caller checked */