- tms470_flash_bank_t *tms470_info = bank->driver_priv;
- target_t *target = bank->target;
- u32 device_ident_reg;
- u32 silicon_version;
- u32 technology_family;
- u32 rom_flash;
- u32 part_number;
- char * part_name;
-
- if (target->state != TARGET_HALTED)
- {
- WARNING( "Cannot communicate... target not halted." );
- return ERROR_TARGET_NOT_HALTED;
- }
-
- /* read and parse the device identification register */
- target_read_u32( target, 0xFFFFFFF0, &device_ident_reg );
-
- INFO( "device_ident_reg=0x%08x", device_ident_reg );
-
- if ((device_ident_reg & 7) == 0)
- {
- WARNING( "Cannot identify target as a TMS470 family." );
- return ERROR_FLASH_OPERATION_FAILED;
- }
-
- silicon_version = (device_ident_reg >> 12) & 0xF;
- technology_family = (device_ident_reg >> 11) & 1;
- rom_flash = (device_ident_reg >> 10) & 1;
- part_number = (device_ident_reg >> 3) & 0x7f;
-
- /*
- * If the part number is known, determine if the flash bank is valid
- * based on the base address being within the known flash bank
- * ranges. Then fixup/complete the remaining fields of the flash
- * bank structure.
- */
- switch( part_number )
- {
- case 0x0a:
- part_name = "TMS470R1A256";
-
- if (bank->base >= 0x00040000)
- {
- ERROR( "No %s flash bank contains base address 0x%08x.",
- part_name, bank->base );
- return ERROR_FLASH_OPERATION_FAILED;
- }
- tms470_info->ordinal = 0;
- bank->base = 0x00000000;
- bank->size = 256*1024;
- bank->num_sectors = TMS470R1A256_NUM_SECTORS;
- bank->sectors = malloc( sizeof( TMS470R1A256_SECTORS ) );
- if (!bank->sectors)
- {
- return ERROR_FLASH_OPERATION_FAILED;
- }
- (void) memcpy( bank->sectors,
- TMS470R1A256_SECTORS,
- sizeof( TMS470R1A256_SECTORS ) );
- break;
-
- case 0x2b:
- part_name = "TMS470R1A288";
-
- if ((bank->base >= 0x00000000) && (bank->base < 0x00008000))
- {
- tms470_info->ordinal = 0;
- bank->base = 0x00000000;
- bank->size = 32*1024;
- bank->num_sectors = TMS470R1A288_BANK0_NUM_SECTORS;
- bank->sectors = malloc( sizeof( TMS470R1A288_BANK0_SECTORS ) );
- if (!bank->sectors)
- {
- return ERROR_FLASH_OPERATION_FAILED;
- }
- (void) memcpy( bank->sectors,
- TMS470R1A288_BANK0_SECTORS,
- sizeof( TMS470R1A288_BANK0_SECTORS ) );
- }
- else if ((bank->base >= 0x00040000) && (bank->base < 0x00080000))
- {
- tms470_info->ordinal = 1;
- bank->base = 0x00040000;
- bank->size = 256*1024;
- bank->num_sectors = TMS470R1A288_BANK1_NUM_SECTORS;
- bank->sectors = malloc( sizeof( TMS470R1A288_BANK1_SECTORS ) );
- if (!bank->sectors)
- {
- return ERROR_FLASH_OPERATION_FAILED;
- }
- (void) memcpy( bank->sectors,
- TMS470R1A288_BANK1_SECTORS,
- sizeof( TMS470R1A288_BANK1_SECTORS ) );
- }
- else
- {
- ERROR( "No %s flash bank contains base address 0x%08x.",
- part_name, bank->base );
- return ERROR_FLASH_OPERATION_FAILED;
- }
- break;
-
- default:
- WARNING( "Could not identify part 0x%02x as a member of the TMS470 family.",
- part_number );
- return ERROR_FLASH_OPERATION_FAILED;
- }
-
- /* turn off memory selects */
- target_write_u32( target, 0xFFFFFFE4, 0x00000000 );
- target_write_u32( target, 0xFFFFFFE0, 0x00000000 );
-
- bank->chip_width = 32;
- bank->bus_width = 32;
-
- INFO( "Identified %s, ver=%d, core=%s, nvmem=%s.",
- part_name,
- silicon_version,
- (technology_family ? "1.8v" : "3.3v"),
- (rom_flash ? "rom" : "flash") );
-
- tms470_info->device_ident_reg = device_ident_reg;
- tms470_info->silicon_version = silicon_version;
- tms470_info->technology_family = technology_family;
- tms470_info->rom_flash = rom_flash;
- tms470_info->part_number = part_number;
- tms470_info->part_name = part_name;
-
- /*
- * Disable reset on address access violation.
- */
- target_write_u32( target, 0xFFFFFFE0, 0x00004007 );
-
- return ERROR_OK;
+ tms470_flash_bank_t *tms470_info = bank->driver_priv;
+ target_t *target = bank->target;
+ u32 device_ident_reg;
+ u32 silicon_version;
+ u32 technology_family;
+ u32 rom_flash;
+ u32 part_number;
+ char *part_name;
+
+ /* we shall not rely on the caller in this test, this function allocates memory,
+ thus and executing the code more than once may cause memory leak */
+ if (tms470_info->device_ident_reg)
+ return ERROR_OK;
+
+ /* read and parse the device identification register */
+ target_read_u32(target, 0xFFFFFFF0, &device_ident_reg);
+
+ LOG_INFO("device_ident_reg=0x%08x", device_ident_reg);
+
+ if ((device_ident_reg & 7) == 0)
+ {
+ LOG_WARNING("Cannot identify target as a TMS470 family.");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ silicon_version = (device_ident_reg >> 12) & 0xF;
+ technology_family = (device_ident_reg >> 11) & 1;
+ rom_flash = (device_ident_reg >> 10) & 1;
+ part_number = (device_ident_reg >> 3) & 0x7f;
+
+ /*
+ * If the part number is known, determine if the flash bank is valid
+ * based on the base address being within the known flash bank
+ * ranges. Then fixup/complete the remaining fields of the flash
+ * bank structure.
+ */
+ switch (part_number)
+ {
+ case 0x0a:
+ part_name = "TMS470R1A256";
+
+ if (bank->base >= 0x00040000)
+ {
+ LOG_ERROR("No %s flash bank contains base address 0x%08x.", part_name, bank->base);
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ tms470_info->ordinal = 0;
+ bank->base = 0x00000000;
+ bank->size = 256 * 1024;
+ bank->num_sectors = TMS470R1A256_NUM_SECTORS;
+ bank->sectors = malloc(sizeof(TMS470R1A256_SECTORS));
+ if (!bank->sectors)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ (void)memcpy(bank->sectors, TMS470R1A256_SECTORS, sizeof(TMS470R1A256_SECTORS));
+ break;
+
+ case 0x2b:
+ part_name = "TMS470R1A288";
+
+ if (bank->base < 0x00008000)
+ {
+ tms470_info->ordinal = 0;
+ bank->base = 0x00000000;
+ bank->size = 32 * 1024;
+ bank->num_sectors = TMS470R1A288_BANK0_NUM_SECTORS;
+ bank->sectors = malloc(sizeof(TMS470R1A288_BANK0_SECTORS));
+ if (!bank->sectors)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ (void)memcpy(bank->sectors, TMS470R1A288_BANK0_SECTORS, sizeof(TMS470R1A288_BANK0_SECTORS));
+ }
+ else if ((bank->base >= 0x00040000) && (bank->base < 0x00080000))
+ {
+ tms470_info->ordinal = 1;
+ bank->base = 0x00040000;
+ bank->size = 256 * 1024;
+ bank->num_sectors = TMS470R1A288_BANK1_NUM_SECTORS;
+ bank->sectors = malloc(sizeof(TMS470R1A288_BANK1_SECTORS));
+ if (!bank->sectors)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ (void)memcpy(bank->sectors, TMS470R1A288_BANK1_SECTORS, sizeof(TMS470R1A288_BANK1_SECTORS));
+ }
+ else
+ {
+ LOG_ERROR("No %s flash bank contains base address 0x%08x.", part_name, bank->base);
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ break;
+
+ case 0x2d:
+ part_name = "TMS470R1A384";
+
+ if (bank->base < 0x00020000)
+ {
+ tms470_info->ordinal = 0;
+ bank->base = 0x00000000;
+ bank->size = 128 * 1024;
+ bank->num_sectors = TMS470R1A384_BANK0_NUM_SECTORS;
+ bank->sectors = malloc(sizeof(TMS470R1A384_BANK0_SECTORS));
+ if (!bank->sectors)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ (void)memcpy(bank->sectors, TMS470R1A384_BANK0_SECTORS, sizeof(TMS470R1A384_BANK0_SECTORS));
+ }
+ else if ((bank->base >= 0x00020000) && (bank->base < 0x00040000))
+ {
+ tms470_info->ordinal = 1;
+ bank->base = 0x00020000;
+ bank->size = 128 * 1024;
+ bank->num_sectors = TMS470R1A384_BANK1_NUM_SECTORS;
+ bank->sectors = malloc(sizeof(TMS470R1A384_BANK1_SECTORS));
+ if (!bank->sectors)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ (void)memcpy(bank->sectors, TMS470R1A384_BANK1_SECTORS, sizeof(TMS470R1A384_BANK1_SECTORS));
+ }
+ else if ((bank->base >= 0x00040000) && (bank->base < 0x00060000))
+ {
+ tms470_info->ordinal = 2;
+ bank->base = 0x00040000;
+ bank->size = 128 * 1024;
+ bank->num_sectors = TMS470R1A384_BANK2_NUM_SECTORS;
+ bank->sectors = malloc(sizeof(TMS470R1A384_BANK2_SECTORS));
+ if (!bank->sectors)
+ {
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ (void)memcpy(bank->sectors, TMS470R1A384_BANK2_SECTORS, sizeof(TMS470R1A384_BANK2_SECTORS));
+ }
+ else
+ {
+ LOG_ERROR("No %s flash bank contains base address 0x%08x.", part_name, bank->base);
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ break;
+
+ default:
+ LOG_WARNING("Could not identify part 0x%02x as a member of the TMS470 family.", part_number);
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ /* turn off memory selects */
+ target_write_u32(target, 0xFFFFFFE4, 0x00000000);
+ target_write_u32(target, 0xFFFFFFE0, 0x00000000);
+
+ bank->chip_width = 32;
+ bank->bus_width = 32;
+
+ LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.", part_name, silicon_version, (technology_family ? "1.8v" : "3.3v"), (rom_flash ? "rom" : "flash"));
+
+ tms470_info->device_ident_reg = device_ident_reg;
+ tms470_info->silicon_version = silicon_version;
+ tms470_info->technology_family = technology_family;
+ tms470_info->rom_flash = rom_flash;
+ tms470_info->part_number = part_number;
+ tms470_info->part_name = part_name;
+
+ /*
+ * Disable reset on address access violation.
+ */
+ target_write_u32(target, 0xFFFFFFE0, 0x00004007);
+
+ return ERROR_OK;