flash/nor/nrf5: split chip and bank probes
nrf5_auto_probe() always re-probed chip hardware to get flash geometry. Introduce nrf5_probe_chip() and move chip related probing to it. Save all flash parameters needed for bank setup to struct nrf5_info. Introduce nrf5_setup_bank() and move bank setup code to it. Call both chip probe and bank setup unconditionally from nrf5_probe(): in case of manual issuing 'flash probe' command, we should refresh actual values from the device. Call chip probe and bank setup only if not done before from nrf5_auto_probe(). Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Change-Id: Ib090a97fd7a41579b3d4f6e6634a5fdf93836c83 Reviewed-on: https://review.openocd.org/c/openocd/+/8322 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
c322060fbd
commit
f09ccc817b
|
@ -117,20 +117,24 @@ struct nrf5_map {
|
||||||
|
|
||||||
struct nrf5_info {
|
struct nrf5_info {
|
||||||
unsigned int refcount;
|
unsigned int refcount;
|
||||||
|
bool chip_probed;
|
||||||
|
|
||||||
struct nrf5_bank {
|
struct nrf5_bank {
|
||||||
struct nrf5_info *chip;
|
struct nrf5_info *chip;
|
||||||
bool probed;
|
bool probed;
|
||||||
} bank[2];
|
} bank[2];
|
||||||
|
|
||||||
struct target *target;
|
struct target *target;
|
||||||
|
|
||||||
/* chip identification stored in nrf5_probe() for use in nrf5_info() */
|
/* chip identification stored in nrf5_probe_chip()
|
||||||
|
* for use in nrf5_info() and nrf5_setup_bank() */
|
||||||
bool ficr_info_valid;
|
bool ficr_info_valid;
|
||||||
struct nrf52_ficr_info ficr_info;
|
struct nrf52_ficr_info ficr_info;
|
||||||
const struct nrf5_device_spec *spec;
|
const struct nrf5_device_spec *spec;
|
||||||
uint16_t hwid;
|
uint16_t hwid;
|
||||||
enum nrf5_features features;
|
enum nrf5_features features;
|
||||||
unsigned int flash_size_kb;
|
uint32_t flash_page_size;
|
||||||
|
uint32_t flash_num_sectors;
|
||||||
unsigned int ram_size_kb;
|
unsigned int ram_size_kb;
|
||||||
|
|
||||||
const struct nrf5_map *map;
|
const struct nrf5_map *map;
|
||||||
|
@ -346,6 +350,16 @@ static bool nrf5_bank_is_probed(const struct flash_bank *bank)
|
||||||
return nbank->probed;
|
return nbank->probed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool nrf5_chip_is_probed(const struct flash_bank *bank)
|
||||||
|
{
|
||||||
|
struct nrf5_bank *nbank = bank->driver_priv;
|
||||||
|
assert(nbank);
|
||||||
|
struct nrf5_info *chip = nbank->chip;
|
||||||
|
assert(chip);
|
||||||
|
|
||||||
|
return chip->chip_probed;
|
||||||
|
}
|
||||||
|
|
||||||
static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
|
static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
|
||||||
{
|
{
|
||||||
struct nrf5_info *chip = nbank->chip;
|
struct nrf5_info *chip = nbank->chip;
|
||||||
|
@ -709,8 +723,9 @@ static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd)
|
||||||
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
|
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
|
unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
|
||||||
command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM",
|
command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM",
|
||||||
chip_type_str, chip->flash_size_kb, chip->ram_size_kb);
|
chip_type_str, flash_size_kb, chip->ram_size_kb);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,7 +853,7 @@ static int nrf51_get_ram_size(struct target *target, uint32_t *ram_size)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nrf5_probe(struct flash_bank *bank)
|
static int nrf5_probe_chip(struct flash_bank *bank)
|
||||||
{
|
{
|
||||||
int res = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
int res = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
@ -968,9 +983,8 @@ static int nrf5_probe(struct flash_bank *bank)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The value stored in FICR CODEPAGESIZE is the number of bytes in one page of FLASH. */
|
/* The value stored in FICR CODEPAGESIZE is the number of bytes in one page of FLASH. */
|
||||||
uint32_t flash_page_size;
|
|
||||||
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codepagesize,
|
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codepagesize,
|
||||||
&flash_page_size);
|
&chip->flash_page_size);
|
||||||
if (res != ERROR_OK) {
|
if (res != ERROR_OK) {
|
||||||
LOG_ERROR("Couldn't read code page size");
|
LOG_ERROR("Couldn't read code page size");
|
||||||
return res;
|
return res;
|
||||||
|
@ -978,69 +992,95 @@ static int nrf5_probe(struct flash_bank *bank)
|
||||||
|
|
||||||
/* Note the register name is misleading,
|
/* Note the register name is misleading,
|
||||||
* FICR CODESIZE is the number of pages in flash memory, not the number of bytes! */
|
* FICR CODESIZE is the number of pages in flash memory, not the number of bytes! */
|
||||||
uint32_t num_sectors;
|
|
||||||
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codesize,
|
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codesize,
|
||||||
&num_sectors);
|
&chip->flash_num_sectors);
|
||||||
if (res != ERROR_OK) {
|
if (res != ERROR_OK) {
|
||||||
LOG_ERROR("Couldn't read code memory size");
|
LOG_ERROR("Couldn't read code memory size");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
chip->flash_size_kb = num_sectors * flash_page_size / 1024;
|
char chip_type_str[256];
|
||||||
|
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
|
||||||
|
return ERROR_FAIL;
|
||||||
|
|
||||||
if (!chip->bank[0].probed && !chip->bank[1].probed) {
|
unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
|
||||||
char chip_type_str[256];
|
const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
|
||||||
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
|
LOG_INFO("%s%s %ukB Flash, %ukB RAM",
|
||||||
return ERROR_FAIL;
|
device_is_unknown ? "Unknown device: " : "",
|
||||||
const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
|
chip_type_str,
|
||||||
LOG_INFO("%s%s %ukB Flash, %ukB RAM",
|
flash_size_kb,
|
||||||
device_is_unknown ? "Unknown device: " : "",
|
chip->ram_size_kb);
|
||||||
chip_type_str,
|
|
||||||
chip->flash_size_kb,
|
|
||||||
chip->ram_size_kb);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(bank->sectors);
|
chip->chip_probed = true;
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nrf5_setup_bank(struct flash_bank *bank)
|
||||||
|
{
|
||||||
|
struct nrf5_bank *nbank = bank->driver_priv;
|
||||||
|
assert(nbank);
|
||||||
|
struct nrf5_info *chip = nbank->chip;
|
||||||
|
assert(chip);
|
||||||
|
|
||||||
if (bank->base == chip->map->flash_base) {
|
if (bank->base == chip->map->flash_base) {
|
||||||
|
unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb)
|
if (chip->spec && flash_size_kb != chip->spec->flash_size_kb)
|
||||||
LOG_WARNING("Chip's reported Flash capacity does not match expected one");
|
LOG_WARNING("Chip's reported Flash capacity does not match expected one");
|
||||||
if (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash)
|
if (chip->ficr_info_valid && flash_size_kb != chip->ficr_info.flash)
|
||||||
LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
|
LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
|
||||||
|
|
||||||
bank->num_sectors = num_sectors;
|
bank->num_sectors = chip->flash_num_sectors;
|
||||||
bank->size = num_sectors * flash_page_size;
|
bank->size = chip->flash_num_sectors * chip->flash_page_size;
|
||||||
|
|
||||||
bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
|
bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
|
||||||
if (!bank->sectors)
|
if (!bank->sectors)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
chip->bank[0].probed = true;
|
chip->bank[0].probed = true;
|
||||||
|
|
||||||
} else {
|
} else if (bank->base == chip->map->uicr_base) {
|
||||||
/* UICR bank */
|
/* UICR bank */
|
||||||
bank->num_sectors = 1;
|
bank->num_sectors = 1;
|
||||||
bank->size = flash_page_size;
|
bank->size = chip->flash_page_size;
|
||||||
|
|
||||||
bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
|
bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
|
||||||
if (!bank->sectors)
|
if (!bank->sectors)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
bank->sectors[0].is_protected = 0;
|
bank->sectors[0].is_protected = 0;
|
||||||
|
|
||||||
chip->bank[1].probed = true;
|
chip->bank[1].probed = true;
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
|
||||||
|
return ERROR_FLASH_BANK_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nrf5_probe(struct flash_bank *bank)
|
||||||
|
{
|
||||||
|
/* probe always reads actual info from the device */
|
||||||
|
int res = nrf5_probe_chip(bank);
|
||||||
|
if (res != ERROR_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return nrf5_setup_bank(bank);
|
||||||
|
}
|
||||||
|
|
||||||
static int nrf5_auto_probe(struct flash_bank *bank)
|
static int nrf5_auto_probe(struct flash_bank *bank)
|
||||||
{
|
{
|
||||||
if (nrf5_bank_is_probed(bank))
|
if (nrf5_bank_is_probed(bank))
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
||||||
return nrf5_probe(bank);
|
if (!nrf5_chip_is_probed(bank)) {
|
||||||
|
int res = nrf5_probe_chip(bank);
|
||||||
|
if (res != ERROR_OK)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nrf5_setup_bank(bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1372,8 +1412,8 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
|
||||||
case NRF53NET_UICR_BASE:
|
case NRF53NET_UICR_BASE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
|
LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
|
||||||
return ERROR_FAIL;
|
return ERROR_FLASH_BANK_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
chip = nrf5_get_chip(bank->target);
|
chip = nrf5_get_chip(bank->target);
|
||||||
|
|
Loading…
Reference in New Issue