#include "general.h"
#include "target.h"
#include "target_internal.h"
#include "cortexm.h"
#include "adiv5.h"
#define RENESAS_PARTID_RA2A1 0x01b0U
#define RENESAS_PARTID_RA4M2 0x0340U
#define RENESAS_PARTID_RA4M3 0x0310U
#define RENESAS_PARTID_RA6M2 0x0150U
#define PNR_FAMILY_INDEX 3U
#define PNR_SERIES(pnr3, pnr4, pnr5, pnr6) (((pnr3) << 24U) | ((pnr4) << 16U) | ((pnr5) << 8U) | (pnr6))
typedef enum {
PNR_SERIES_RA2L1 = PNR_SERIES('A', '2', 'L', '1'),
PNR_SERIES_RA2E1 = PNR_SERIES('A', '2', 'E', '1'),
PNR_SERIES_RA2E2 = PNR_SERIES('A', '2', 'E', '2'),
PNR_SERIES_RA2A1 = PNR_SERIES('A', '2', 'A', '1'),
PNR_SERIES_RA4M1 = PNR_SERIES('A', '4', 'M', '1'),
PNR_SERIES_RA4M2 = PNR_SERIES('A', '4', 'M', '2'),
PNR_SERIES_RA4M3 = PNR_SERIES('A', '4', 'M', '3'),
PNR_SERIES_RA4E1 = PNR_SERIES('A', '4', 'E', '1'),
PNR_SERIES_RA4E2 = PNR_SERIES('A', '4', 'E', '2'),
PNR_SERIES_RA4W1 = PNR_SERIES('A', '4', 'W', '1'),
PNR_SERIES_RA6M1 = PNR_SERIES('A', '6', 'M', '1'),
PNR_SERIES_RA6M2 = PNR_SERIES('A', '6', 'M', '2'),
PNR_SERIES_RA6M3 = PNR_SERIES('A', '6', 'M', '3'),
PNR_SERIES_RA6M4 = PNR_SERIES('A', '6', 'M', '4'),
PNR_SERIES_RA6M5 = PNR_SERIES('A', '6', 'M', '5'),
PNR_SERIES_RA6E1 = PNR_SERIES('A', '6', 'E', '1'),
PNR_SERIES_RA6E2 = PNR_SERIES('A', '6', 'E', '2'),
PNR_SERIES_RA6T1 = PNR_SERIES('A', '6', 'T', '1'),
PNR_SERIES_RA6T2 = PNR_SERIES('A', '6', 'T', '2'),
} renesas_pnr_series_e;
#define PNR_MEMSIZE_INDEX 8U
typedef enum {
PNR_MEMSIZE_16KB = '3',
PNR_MEMSIZE_32KB = '5',
PNR_MEMSIZE_64KB = '7',
PNR_MEMSIZE_128KB = '9',
PNR_MEMSIZE_256KB = 'B',
PNR_MEMSIZE_384KB = 'C',
PNR_MEMSIZE_512KB = 'D',
PNR_MEMSIZE_768KB = 'E',
PNR_MEMSIZE_1MB = 'F',
PNR_MEMSIZE_1_5MB = 'G',
PNR_MEMSIZE_2MB = 'H',
} renesas_pnr_memsize_e;
#define RENESAS_FIXED1_UID UINT32_C(0x01001c00)
#define RENESAS_FIXED1_PNR UINT32_C(0x01001c10)
#define RENESAS_FIXED1_MCUVER UINT32_C(0x01001c20)
#define RENESAS_FIXED2_UID UINT32_C(0x01008190)
#define RENESAS_FIXED2_PNR UINT32_C(0x010080f0)
#define RENESAS_FIXED2_MCUVER UINT32_C(0x010081b0)
#define RENESAS_FMIFRT UINT32_C(0x407fb19c)
#define RENESAS_FMIFRT_UID(frt) ((frt) + 0x14U)
#define RENESAS_FMIFRT_PNR(frt) ((frt) + 0x24U)
#define RENESAS_FMIFRT_MCUVER(frt) ((frt) + 0x44U)
#define SYSC_BASE UINT32_C(0x4001e000)
#define SYSC_SYOCDCR (SYSC_BASE + 0x40eU)
#define SYOCDCR_DBGEN (1U << 7U)
#define SYSC_FWEPROR (SYSC_BASE + 0x416U)
#define SYSC_FWEPROR_PERMIT (0x01U)
#define SYSC_FWEPROR_PROHIBIT (0x10U)
#define FENTRYR_KEY_OFFSET 8U
#define FENTRYR_KEY (0xaaU << FENTRYR_KEY_OFFSET)
#define FENTRYR_PE_CF (1U)
#define FENTRYR_PE_DF (1U << 7U)
#define RENESAS_CF_END UINT32_C(0x00300000)
#define MF3_CF_BLOCK_SIZE (0x800U)
#define MF3_RA2A1_CF_BLOCK_SIZE (0x400U)
#define MF3_DF_BLOCK_SIZE (0x400U)
#define MF3_CF_WRITE_SIZE (0x40U)
#define MF3_DF_WRITE_SIZE (0x1U)
#define RV40_CF_REGION0_SIZE (0x10000U)
#define RV40_CF_REGION0_BLOCK_SIZE (0x2000U)
#define RV40_CF_REGION1_BLOCK_SIZE (0x8000U)
#define RV40_DF_BLOCK_SIZE (0x40U)
#define RV40_CF_WRITE_SIZE (0x80U)
#define RV40_DF_WRITE_SIZE (0x4U)
#define RV40_CMD UINT32_C(0x407e0000)
#define RV40_CMD_PROGRAM 0xe8U
#define RV40_CMD_PROGRAM_CF 0x80U
#define RV40_CMD_PROGRAM_DF 0x02U
#define RV40_CMD_BLOCK_ERASE 0x20U
#define RV40_CMD_PE_SUSPEND 0xb0U
#define RV40_CMD_PE_RESUME 0xd0U
#define RV40_CMD_STATUS_CLEAR 0x50U
#define RV40_CMD_FORCED_STOP 0xb3U
#define RV40_CMD_BLANK_CHECK 0x71U
#define RV40_CMD_CONFIG_SET_1 0x40U
#define RV40_CMD_CONFIG_SET_2 0x08U
#define RV40_CMD_LOCK_BIT_PGM 0x77U
#define RV40_CMD_LOCK_BIT_READ 0x71U
#define RV40_CMD_FINAL 0xd0U
#define RV40_BASE UINT32_C(0x407fe000)
#define RV40_FASTAT (RV40_BASE + 0x10U)
#define RV40_FASTAT_CMDLK (1U << 4U)
#define RV40_FSTATR (RV40_BASE + 0x80U)
#define RV40_FSTATR_DBFULL (1U << 10U)
#define RV40_FSTATR_RDY (1U << 15U)
#define RV40_FSTATR_PRGERR (1U << 12U)
#define RV40_FSTATR_ERSERR (1U << 13U)
#define RV40_FSTATR_ILGLERR (1U << 14U)
#define RV40_FSTATR_OTERR (1U << 20U)
#define RV40_FSTATR_SECERR (1U << 21U)
#define RV40_FSTATR_FESETERR (1U << 22U)
#define RV40_FSTATR_ILGCOMERR (1U << 23U)
#define RV40_FSADDR (RV40_BASE + 0x30U)
#define RV40_FMEPROT (RV40_BASE + 0x44U)
#define RV40_FMEPROT_LOCK (0xd901U)
#define RV40_FMEPROT_UNLOCK (0xd900U)
#define RV40_FENTRYR (RV40_BASE + 0x84U)
#define RV40_FENTRYR_KEY_OFFSET 8U
#define RV40_FENTRYR_KEY (0xaaU << RV40_FENTRYR_KEY_OFFSET)
#define RV40_FENTRYR_PE_CF (1U)
#define RV40_FENTRYR_PE_DF (1U << 7U)
#define RV40_FCPSR (RV40_BASE + 0xe0U)
#define RV40_FCPSR_ESUSPMD 1U
static bool renesas_uid(target_s *t, int argc, const char **argv);
const command_s renesas_cmd_list[] = {
{"uid", renesas_uid, "Prints unique id"},
{NULL, NULL, NULL},
};
typedef struct renesas_priv {
uint8_t pnr[17];
renesas_pnr_series_e series;
target_addr_t flash_root_table;
} renesas_priv_s;
static target_addr_t renesas_fmifrt_read(target_s *t)
{
return target_mem_read32(t, RENESAS_FMIFRT);
}
static void renesas_uid_read(target_s *const t, const target_addr_t base, uint8_t *const uid)
{
uint32_t uidr[4];
for (size_t i = 0U; i < 4U; i++)
uidr[i] = target_mem_read32(t, base + i * 4U);
for (size_t i = 0U; i < 16U; i++)
uid[i] = uidr[i / 4U] >> (i & 3U) * 8U;
}
static bool renesas_pnr_read(target_s *const t, const target_addr_t base, uint8_t *const pnr)
{
uint32_t pnrr[4];
for (size_t i = 0U; i < 4U; i++)
pnrr[i] = target_mem_read32(t, base + i * 4U);
if (base == RENESAS_FIXED1_PNR) {
for (size_t i = 0U; i < 13U; i++)
pnr[i] = pnrr[3U - (i + 3U) / 4U] >> (24U - ((i + 3U) & 3U) * 8U);
memset(pnr + 13U, 0x20, 3);
} else {
for (size_t i = 0; i < 16U; i++)
pnr[i] = pnrr[i / 4U] >> (i & 3U) * 8U;
}
return pnr[0] == 'R' && pnr[1] == '7';
}
static renesas_pnr_series_e renesas_series(const uint8_t *const pnr)
{
uint32_t series = 0;
for (size_t i = 0; i < 4U; i++)
series = (series << 8U) | pnr[PNR_FAMILY_INDEX + i];
return (renesas_pnr_series_e)series;
}
static uint32_t renesas_flash_size(const uint8_t *const pnr)
{
switch (pnr[PNR_MEMSIZE_INDEX]) {
case PNR_MEMSIZE_16KB:
return UINT32_C(16 * 1024);
case PNR_MEMSIZE_32KB:
return UINT32_C(32 * 1024);
case PNR_MEMSIZE_64KB:
return UINT32_C(64 * 1024);
case PNR_MEMSIZE_128KB:
return UINT32_C(128 * 1024);
case PNR_MEMSIZE_256KB:
return UINT32_C(256 * 1024);
case PNR_MEMSIZE_384KB:
return UINT32_C(384 * 1024);
case PNR_MEMSIZE_512KB:
return UINT32_C(512 * 1024);
case PNR_MEMSIZE_768KB:
return UINT32_C(768 * 1024);
case PNR_MEMSIZE_1MB:
return UINT32_C(1024 * 1024);
case PNR_MEMSIZE_1_5MB:
return UINT32_C(1536 * 1024);
case PNR_MEMSIZE_2MB:
return UINT32_C(2048 * 1024);
default:
return 0;
}
}
static bool renesas_enter_flash_mode(target_s *const t)
{
target_reset(t);
target_mem_write8(t, SYSC_FWEPROR, SYSC_FWEPROR_PERMIT);
return true;
}
typedef enum pe_mode {
PE_MODE_READ,
PE_MODE_CF,
PE_MODE_DF,
} pe_mode_e;
static bool renesas_rv40_pe_mode(target_s *const t, const pe_mode_e pe_mode)
{
const renesas_priv_s *const priv_storage = (renesas_priv_s *)t->target_storage;
if (!priv_storage)
return false;
bool has_fmeprot = false;
switch (priv_storage->series) {
case PNR_SERIES_RA4E1:
case PNR_SERIES_RA4E2:
case PNR_SERIES_RA4M2:
case PNR_SERIES_RA4M3:
case PNR_SERIES_RA6M4:
case PNR_SERIES_RA6M5:
case PNR_SERIES_RA6E1:
case PNR_SERIES_RA6E2:
case PNR_SERIES_RA6T2:
has_fmeprot = true;
default:
break;
}
if (has_fmeprot)
target_mem_write16(t, RV40_FMEPROT, RV40_FMEPROT_UNLOCK);
uint16_t fentryr = 0;
switch (pe_mode) {
case PE_MODE_CF:
fentryr |= FENTRYR_PE_CF;
break;
case PE_MODE_DF:
fentryr |= FENTRYR_PE_DF;
break;
default:
break;
}
target_mem_write16(t, RV40_FENTRYR, FENTRYR_KEY | fentryr);
platform_timeout_s timeout;
platform_timeout_set(&timeout, 10);
while (target_mem_read16(t, RV40_FENTRYR) != fentryr || !(target_mem_read32(t, RV40_FSTATR) & RV40_FSTATR_RDY)) {
if (target_check_error(t) || platform_timeout_is_expired(&timeout))
return false;
}
if (has_fmeprot && pe_mode == PE_MODE_READ)
target_mem_write16(t, RV40_FMEPROT, RV40_FMEPROT_LOCK);
return true;
}
static bool renesas_rv40_error_check(target_s *const t, const uint32_t error_bits)
{
bool error = false;
const uint8_t fstatr = target_mem_read32(t, RV40_FSTATR);
if (target_mem_read8(t, RV40_FASTAT) & RV40_FASTAT_CMDLK) {
if (fstatr & RV40_FSTATR_ILGLERR) {
target_mem_read8(t, RV40_FASTAT);
target_mem_write8(t, RV40_FASTAT, 0);
}
error = true;
}
if (fstatr & error_bits)
error = true;
if (error) {
target_mem_write8(t, RV40_CMD, RV40_CMD_FORCED_STOP);
platform_timeout_s timeout;
platform_timeout_set(&timeout, 10);
while (!(target_mem_read32(t, RV40_FSTATR) & RV40_FSTATR_RDY)) {
if (target_check_error(t) || platform_timeout_is_expired(&timeout))
return error;
}
if (target_mem_read8(t, RV40_FASTAT) & RV40_FASTAT_CMDLK)
return error;
}
return error;
}
static bool renesas_rv40_prepare(target_flash_s *const f)
{
target_s *const t = f->t;
if (!(target_mem_read32(t, RV40_FSTATR) & RV40_FSTATR_RDY) || target_mem_read16(t, RV40_FENTRYR) != 0) {
DEBUG_WARN("flash is not ready, may be hanging mid unfinished command due to something going wrong, "
"please power on reset the device\n");
return false;
}
const bool code_flash = f->start < RENESAS_CF_END;
const pe_mode_e pe_mode = code_flash ? PE_MODE_CF : PE_MODE_DF;
return renesas_rv40_pe_mode(t, pe_mode) && !renesas_rv40_error_check(t, RV40_FSTATR_ILGLERR);
}
static bool renesas_rv40_done(target_flash_s *const f)
{
target_s *const t = f->t;
return renesas_rv40_pe_mode(t, PE_MODE_READ);
}
static bool renesas_rv40_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
{
target_s *const t = f->t;
const bool code_flash = addr < RENESAS_CF_END;
target_mem_write16(t, RV40_FCPSR, RV40_FCPSR_ESUSPMD);
while (len) {
target_mem_write32(t, RV40_FSADDR, addr);
uint16_t block_size;
if (code_flash)
block_size = addr < RV40_CF_REGION0_SIZE ? RV40_CF_REGION0_BLOCK_SIZE : RV40_CF_REGION1_BLOCK_SIZE;
else
block_size = RV40_DF_BLOCK_SIZE;
addr += block_size;
len -= block_size;
target_mem_write8(t, RV40_CMD, RV40_CMD_BLOCK_ERASE);
target_mem_write8(t, RV40_CMD, RV40_CMD_FINAL);
platform_timeout_s timeout;
platform_timeout_set(&timeout, 1100);
while (!(target_mem_read32(t, RV40_FSTATR) & RV40_FSTATR_RDY)) {
if (target_check_error(t) || platform_timeout_is_expired(&timeout))
return false;
}
if (renesas_rv40_error_check(t, RV40_FSTATR_ERSERR | RV40_FSTATR_ILGLERR))
return false;
}
return true;
}
static bool renesas_rv40_flash_write(target_flash_s *const f, target_addr_t dest, const void *src, size_t len)
{
target_s *const t = f->t;
const bool code_flash = dest < RENESAS_CF_END;
const uint8_t write_size = code_flash ? RV40_CF_WRITE_SIZE : RV40_DF_WRITE_SIZE;
while (len) {
target_mem_write32(t, RV40_FSADDR, dest);
dest += write_size;
len -= write_size;
target_mem_write8(t, RV40_CMD, RV40_CMD_PROGRAM);
target_mem_write8(t, RV40_CMD, (uint8_t)(write_size / 2U));
platform_timeout_s timeout;
platform_timeout_set(&timeout, 10);
for (size_t i = 0U; i < (write_size / 2U); i++) {
target_mem_write16(t, RV40_CMD, *(uint16_t *)src);
src += 2U;
}
target_mem_write8(t, RV40_CMD, RV40_CMD_FINAL);
while (!(target_mem_read32(t, RV40_FSTATR) & RV40_FSTATR_RDY)) {
if (target_check_error(t) || platform_timeout_is_expired(&timeout))
return false;
}
}
return !renesas_rv40_error_check(t, RV40_FSTATR_PRGERR | RV40_FSTATR_ILGLERR);
}
static void renesas_add_rv40_flash(target_s *t, target_addr_t addr, size_t length)
{
target_flash_s *f = calloc(1, sizeof(*f));
if (!f)
return;
const bool code_flash = addr < RENESAS_CF_END;
f->start = addr;
f->length = length;
f->erased = 0xffU;
f->erase = renesas_rv40_flash_erase;
f->write = renesas_rv40_flash_write;
f->prepare = renesas_rv40_prepare;
f->done = renesas_rv40_done;
if (code_flash) {
f->blocksize = RV40_CF_REGION1_BLOCK_SIZE;
f->writesize = RV40_CF_WRITE_SIZE;
} else {
f->blocksize = RV40_DF_BLOCK_SIZE;
f->writesize = RV40_DF_WRITE_SIZE;
}
target_add_flash(t, f);
}
static void renesas_add_flash(target_s *t, target_addr_t addr, size_t length)
{
renesas_priv_s *priv_storage = (renesas_priv_s *)t->target_storage;
if (!priv_storage)
return;
switch (priv_storage->series) {
case PNR_SERIES_RA2L1:
case PNR_SERIES_RA2E1:
case PNR_SERIES_RA2E2:
case PNR_SERIES_RA2A1:
case PNR_SERIES_RA4M1:
case PNR_SERIES_RA4W1:
return;
case PNR_SERIES_RA4M2:
case PNR_SERIES_RA4M3:
case PNR_SERIES_RA4E1:
case PNR_SERIES_RA4E2:
case PNR_SERIES_RA6M1:
case PNR_SERIES_RA6M2:
case PNR_SERIES_RA6M3:
case PNR_SERIES_RA6M4:
case PNR_SERIES_RA6E1:
case PNR_SERIES_RA6E2:
case PNR_SERIES_RA6M5:
case PNR_SERIES_RA6T1:
case PNR_SERIES_RA6T2:
t->enter_flash_mode = renesas_enter_flash_mode;
renesas_add_rv40_flash(t, addr, length);
return;
default:
return;
}
}
bool renesas_probe(target_s *t)
{
uint8_t pnr[16];
target_addr_t flash_root_table = 0;
target_mem_write8(t, SYSC_SYOCDCR, SYOCDCR_DBGEN);
switch (t->part_id) {
case RENESAS_PARTID_RA4M2:
case RENESAS_PARTID_RA4M3:
if (!renesas_pnr_read(t, RENESAS_FIXED2_PNR, pnr))
return false;
break;
case RENESAS_PARTID_RA2A1:
case RENESAS_PARTID_RA6M2:
flash_root_table = renesas_fmifrt_read(t);
if (!renesas_pnr_read(t, RENESAS_FMIFRT_PNR(flash_root_table), pnr))
return false;
break;
default:
if (renesas_pnr_read(t, RENESAS_FIXED2_PNR, pnr)) {
DEBUG_WARN("Found renesas chip (%.*s) with pnr location RENESAS_FIXED2_PNR and unsupported Part ID %x "
"please report it\n",
(int)sizeof(pnr), pnr, t->part_id);
break;
}
if (renesas_pnr_read(t, RENESAS_FIXED1_PNR, pnr)) {
DEBUG_WARN("Found renesas chip (%.*s) with pnr location RENESAS_FIXED1_PNR and unsupported Part ID 0x%x "
"please report it\n",
(int)sizeof(pnr), pnr, t->part_id);
break;
}
flash_root_table = renesas_fmifrt_read(t);
if (renesas_pnr_read(t, RENESAS_FMIFRT_PNR(flash_root_table), pnr)) {
DEBUG_WARN("Found renesas chip (%.*s) with Flash Root Table and unsupported Part ID 0x%x "
"please report it\n",
(int)sizeof(pnr), pnr, t->part_id);
break;
}
return false;
}
renesas_priv_s *const priv_storage = calloc(1, sizeof(renesas_priv_s));
if (!priv_storage)
return false;
memcpy(priv_storage->pnr, pnr, sizeof(pnr));
priv_storage->series = renesas_series(pnr);
priv_storage->flash_root_table = flash_root_table;
t->target_storage = (void *)priv_storage;
t->driver = (char *)priv_storage->pnr;
switch (priv_storage->series) {
case PNR_SERIES_RA2L1:
case PNR_SERIES_RA2A1:
case PNR_SERIES_RA4M1:
renesas_add_flash(t, 0x40100000, 8U * 1024U);
target_add_ram(t, 0x20000000, 32U * 1024U);
break;
case PNR_SERIES_RA2E1:
renesas_add_flash(t, 0x40100000, 4U * 1024U);
target_add_ram(t, 0x20004000, 16U * 1024U);
break;
case PNR_SERIES_RA2E2:
renesas_add_flash(t, 0x40100000, 2U * 1024U);
target_add_ram(t, 0x20004000, 8U * 1024U);
break;
case PNR_SERIES_RA4M2:
case PNR_SERIES_RA4M3:
case PNR_SERIES_RA4E1:
renesas_add_flash(t, 0x08000000, 8U * 1024U);
target_add_ram(t, 0x20000000, 128U * 1024U);
target_add_ram(t, 0x28000000, 1024U);
break;
case PNR_SERIES_RA4E2:
case PNR_SERIES_RA6E2:
renesas_add_flash(t, 0x08000000, 4U * 1024U);
target_add_ram(t, 0x20000000, 40U * 1024U);
target_add_ram(t, 0x28000000, 1024U);
break;
case PNR_SERIES_RA4W1:
renesas_add_flash(t, 0x40100000, 8U * 1024U);
target_add_ram(t, 0x20000000, 96U * 1024U);
break;
case PNR_SERIES_RA6M1:
renesas_add_flash(t, 0x40100000, 8U * 1024U);
target_add_ram(t, 0x20000000, 128U * 1024U);
target_add_ram(t, 0x1ffe0000, 128U * 1024U);
target_add_ram(t, 0x200fe000, 8U * 1024U);
break;
case PNR_SERIES_RA6M2:
renesas_add_flash(t, 0x40100000, 32U * 1024U);
target_add_ram(t, 0x20000000, 256U * 1024U);
target_add_ram(t, 0x1ffe0000, 128U * 1024U);
target_add_ram(t, 0x200fe000, 8U * 1024U);
break;
case PNR_SERIES_RA6M3:
renesas_add_flash(t, 0x40100000, 64U * 1024U);
target_add_ram(t, 0x20000000, 256U * 1024U);
target_add_ram(t, 0x20040000, 256U * 1024U);
target_add_ram(t, 0x1ffe0000, 128U * 1024U);
target_add_ram(t, 0x200fe000, 8U * 1024U);
break;
case PNR_SERIES_RA6M4:
case PNR_SERIES_RA6E1:
renesas_add_flash(t, 0x08000000, 8U * 1024U);
target_add_ram(t, 0x20000000, 256U * 1024U);
target_add_ram(t, 0x28000000, 1024U);
break;
case PNR_SERIES_RA6M5:
renesas_add_flash(t, 0x08000000, 8U * 1024U);
target_add_ram(t, 0x20000000, 512U * 1024U);
target_add_ram(t, 0x28000000, 1024U);
break;
case PNR_SERIES_RA6T1:
renesas_add_flash(t, 0x40100000, 8U * 1024U);
target_add_ram(t, 0x1ffe0000, 64U * 1024U);
break;
case PNR_SERIES_RA6T2:
renesas_add_flash(t, 0x08000000, 16U * 1024U);
target_add_ram(t, 0x20000000, 64U * 1024U);
target_add_ram(t, 0x28000000, 1024U);
break;
default:
return false;
}
renesas_add_flash(t, 0x00000000, renesas_flash_size(pnr));
target_add_commands(t, renesas_cmd_list, t->driver);
return true;
}
static bool renesas_uid(target_s *t, int argc, const char **argv)
{
(void)argc;
(void)argv;
renesas_priv_s *priv_storage = (renesas_priv_s *)t->target_storage;
if (!priv_storage)
return false;
uint8_t uid[16];
target_addr_t uid_addr;
switch (priv_storage->series) {
case PNR_SERIES_RA2L1:
case PNR_SERIES_RA2E1:
case PNR_SERIES_RA2E2:
uid_addr = RENESAS_FIXED1_UID;
break;
case PNR_SERIES_RA2A1:
case PNR_SERIES_RA4M2:
case PNR_SERIES_RA4M3:
case PNR_SERIES_RA4E1:
case PNR_SERIES_RA4E2:
case PNR_SERIES_RA6M4:
case PNR_SERIES_RA6M5:
case PNR_SERIES_RA6E1:
case PNR_SERIES_RA6E2:
case PNR_SERIES_RA6T2:
uid_addr = RENESAS_FIXED2_UID;
break;
case PNR_SERIES_RA4M1:
case PNR_SERIES_RA4W1:
case PNR_SERIES_RA6M1:
case PNR_SERIES_RA6M2:
case PNR_SERIES_RA6M3:
case PNR_SERIES_RA6T1:
uid_addr = RENESAS_FMIFRT_UID(priv_storage->flash_root_table);
break;
default:
return false;
}
renesas_uid_read(t, uid_addr, uid);
tc_printf(t, "Unique id: 0x");
for (size_t i = 0U; i < 16U; i++)
tc_printf(t, "%02" PRIx8, uid[i]);
tc_printf(t, "\n");
return true;
}