Skip to content

Commit

Permalink
lmi: Nomenclature fixes for the LM3S/TM4C support
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonmux committed Jan 27, 2024
1 parent 51fca89 commit 659db42
Showing 1 changed file with 63 additions and 61 deletions.
124 changes: 63 additions & 61 deletions src/target/lmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,142 +100,144 @@
#define LMI_FLASH_FMC_COMT (1U << 3U)
#define LMI_FLASH_FMC_WRKEY 0xa4420000U

static bool lmi_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
static bool lmi_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
static bool lmi_mass_erase(target_s *t);
static bool lmi_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len);
static bool lmi_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len);
static bool lmi_mass_erase(target_s *target);

static const uint16_t lmi_flash_write_stub[] = {
#include "flashstub/lmi.stub"
};

static void lmi_add_flash(target_s *t, size_t length)
static void lmi_add_flash(target_s *target, size_t length)
{
target_flash_s *f = calloc(1, sizeof(*f));
if (!f) { /* calloc failed: heap exhaustion */
target_flash_s *flash = calloc(1, sizeof(*flash));
if (!flash) { /* calloc failed: heap exhaustion */
DEBUG_ERROR("calloc: failed in %s\n", __func__);
return;
}

f->start = 0;
f->length = length;
f->blocksize = 0x400;
f->erase = lmi_flash_erase;
f->write = lmi_flash_write;
f->erased = 0xff;
target_add_flash(t, f);
flash->start = 0;
flash->length = length;
flash->blocksize = 0x400;
flash->erase = lmi_flash_erase;
flash->write = lmi_flash_write;
flash->erased = 0xff;
target_add_flash(target, flash);
}

bool lm3s_probe(target_s *const t, const uint16_t did1)
bool lm3s_probe(target_s *const target, const uint16_t did1)
{
switch (did1) {
case DID1_LM3S3748:
case DID1_LM3S5732:
target_add_ram(t, 0x20000000U, 0x10000U);
lmi_add_flash(t, 0x20000U);
target_add_ram(target, 0x20000000U, 0x10000U);
lmi_add_flash(target, 0x20000U);
break;
case DID1_LM3S8962:
target_add_ram(t, 0x2000000U, 0x10000U);
lmi_add_flash(t, 0x40000U);
target_add_ram(target, 0x2000000U, 0x10000U);
lmi_add_flash(target, 0x40000U);
break;
default:
return false;
}
t->driver = "Stellaris";
t->mass_erase = lmi_mass_erase;
target->driver = "Stellaris";
target->mass_erase = lmi_mass_erase;
return true;
}

bool tm4c_probe(target_s *const t, const uint16_t did1)
bool tm4c_probe(target_s *const target, const uint16_t did1)
{
switch (did1) {
case DID1_TM4C123GH6PM:
target_add_ram(t, 0x20000000, 0x10000);
lmi_add_flash(t, 0x80000);
/* On Tiva targets, asserting nRST results in the debug
* logic also being reset. We can't assert nRST and must
* only use the AIRCR SYSRESETREQ. */
t->target_options |= TOPT_INHIBIT_NRST;
target_add_ram(target, 0x20000000, 0x10000);
lmi_add_flash(target, 0x80000);
/*
* On Tiva targets, asserting nRST results in the debug
* logic also being reset. We can't assert nRST and must
* only use the AIRCR SYSRESETREQ.
*/
target->target_options |= TOPT_INHIBIT_NRST;
break;
case DID1_TM4C1230C3PM:
target_add_ram(t, 0x20000000, 0x6000);
lmi_add_flash(t, 0x10000);
t->target_options |= TOPT_INHIBIT_NRST;
target_add_ram(target, 0x20000000, 0x6000);
lmi_add_flash(target, 0x10000);
target->target_options |= TOPT_INHIBIT_NRST;
break;
case DID1_TM4C1294KCPDT:
target_add_ram(t, 0x20000000, 0x40000);
lmi_add_flash(t, 0x80000);
t->target_options |= TOPT_INHIBIT_NRST;
target_add_ram(target, 0x20000000, 0x40000);
lmi_add_flash(target, 0x80000);
target->target_options |= TOPT_INHIBIT_NRST;
break;
case DID1_TM4C1294NCPDT:
target_add_ram(t, 0x20000000, 0x40000);
lmi_add_flash(t, 0x100000);
t->target_options |= TOPT_INHIBIT_NRST;
target_add_ram(target, 0x20000000, 0x40000);
lmi_add_flash(target, 0x100000);
target->target_options |= TOPT_INHIBIT_NRST;
break;
default:
return false;
}
t->driver = "Tiva-C";
t->mass_erase = lmi_mass_erase;
cortex_ap(t)->dp->quirks |= ADIV5_DP_QUIRK_DUPED_AP;
target->driver = "Tiva-C";
target->mass_erase = lmi_mass_erase;
cortex_ap(target)->dp->quirks |= ADIV5_DP_QUIRK_DUPED_AP;
return true;
}

bool lmi_probe(target_s *const t)
bool lmi_probe(target_s *const target)
{
const uint32_t did0 = target_mem_read32(t, LMI_SCB_DID0);
const uint16_t did1 = target_mem_read32(t, LMI_SCB_DID1) >> 16U;
const uint32_t did0 = target_mem_read32(target, LMI_SCB_DID0);
const uint16_t did1 = target_mem_read32(target, LMI_SCB_DID1) >> 16U;

switch (did0 & DID0_CLASS_MASK) {
case DID0_CLASS_STELLARIS_FURY:
case DID0_CLASS_STELLARIS_DUSTDEVIL:
return lm3s_probe(t, did1);
return lm3s_probe(target, did1);
case DID0_CLASS_TIVA_BLIZZARD:
case DID0_CLASS_TIVA_SNOWFLAKE:
return tm4c_probe(t, did1);
return tm4c_probe(target, did1);
default:
return false;
}
}

static bool lmi_flash_erase(target_flash_s *f, target_addr_t addr, const size_t len)
static bool lmi_flash_erase(target_flash_s *flash, target_addr_t addr, const size_t len)
{
target_s *t = f->t;
target_check_error(t);
target_s *target = flash->t;
target_check_error(target);

const bool full_erase = addr == f->start && len == f->length;
const bool full_erase = addr == flash->start && len == flash->length;
platform_timeout_s timeout;
platform_timeout_set(&timeout, 500);

for (size_t erased = 0; erased < len; erased += BLOCK_SIZE) {
target_mem_write32(t, LMI_FLASH_FMA, addr);
target_mem_write32(t, LMI_FLASH_FMC, LMI_FLASH_FMC_WRKEY | LMI_FLASH_FMC_ERASE);
target_mem_write32(target, LMI_FLASH_FMA, addr);
target_mem_write32(target, LMI_FLASH_FMC, LMI_FLASH_FMC_WRKEY | LMI_FLASH_FMC_ERASE);

while (target_mem_read32(t, LMI_FLASH_FMC) & LMI_FLASH_FMC_ERASE) {
while (target_mem_read32(target, LMI_FLASH_FMC) & LMI_FLASH_FMC_ERASE) {
if (full_erase)
target_print_progress(&timeout);
}

if (target_check_error(t))
if (target_check_error(target))
return false;

addr += BLOCK_SIZE;
}
return true;
}

static bool lmi_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len)
static bool lmi_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len)
{
target_s *t = f->t;
target_check_error(t);
target_mem_write(t, SRAM_BASE, lmi_flash_write_stub, sizeof(lmi_flash_write_stub));
target_mem_write(t, STUB_BUFFER_BASE, src, len);
if (target_check_error(t))
target_s *target = flash->t;
target_check_error(target);
target_mem_write(target, SRAM_BASE, lmi_flash_write_stub, sizeof(lmi_flash_write_stub));
target_mem_write(target, STUB_BUFFER_BASE, src, len);
if (target_check_error(target))
return false;

return cortexm_run_stub(t, SRAM_BASE, dest, STUB_BUFFER_BASE, len, 0) == 0;
return cortexm_run_stub(target, SRAM_BASE, dest, STUB_BUFFER_BASE, len, 0) == 0;
}

static bool lmi_mass_erase(target_s *t)
static bool lmi_mass_erase(target_s *target)
{
return lmi_flash_erase(t->flash, t->flash->start, t->flash->length);
return lmi_flash_erase(target->flash, target->flash->start, target->flash->length);
}

0 comments on commit 659db42

Please sign in to comment.