From f14f84ca1e5d4fbab00c52100859af5ec8226753 Mon Sep 17 00:00:00 2001
From: oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Wed, 5 Mar 2008 13:27:50 +0000
Subject: [PATCH] Pavel Chromy: memory leak in at91sam7 flash driver, possible
 incorrect pointer conversion in gpnvm command handling, uninitialized buffer
 issue in handle_flash_info_command in flash.c, some formatting.

git-svn-id: svn://svn.berlios.de/openocd/trunk@446 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/flash/at91sam7.c  | 165 ++++++++++++++++--------------------------
 src/flash/at91sam7.h  |   4 +-
 src/flash/flash.c     |  13 ++--
 src/flash/flash.h     |   1 +
 src/flash/stellaris.c |  90 +++++++++++------------
 5 files changed, 117 insertions(+), 156 deletions(-)

diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c
index 99a8a9af9..0c7a7c0a3 100644
--- a/src/flash/at91sam7.c
+++ b/src/flash/at91sam7.c
@@ -77,7 +77,7 @@ flash_driver_t at91sam7_flash =
 	.protect = at91sam7_protect,
 	.write = at91sam7_write,
 	.probe = at91sam7_probe,
-	.auto_probe = at91sam7_auto_probe,
+	.auto_probe = at91sam7_probe,
 	.erase_check = at91sam7_erase_check,
 	.protect_check = at91sam7_protect_check,
 	.info = at91sam7_info
@@ -145,7 +145,7 @@ u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane)
 	return fsr;
 }
 
-/** Read clock configuration and set at91sam7_info->usec_clocks*/ 
+/* Read clock configuration and set at91sam7_info->usec_clocks*/
 void at91sam7_read_clock_info(flash_bank_t *bank)
 {
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
@@ -180,7 +180,7 @@ void at91sam7_read_clock_info(flash_bank_t *bank)
 
 		case 2:			/* Reserved */
 			break;
-		case 3:		/* PLL Clock */
+		case 3:			/* PLL Clock */
 			if (mcfr & CKGR_MCFR_MAINRDY) 
 			{
 				target_read_u32(target, CKGR_PLLR, &pllr);
@@ -313,6 +313,9 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
 	target_t *target = bank->target;
 	u32 cidr, status;
 	int sectornum;
+
+	if (at91sam7_info->cidr != 0)
+		return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
 	
 	/* Read and parse chip identification register */
 	target_read_u32(target, DBGU_CIDR, &cidr);
@@ -553,9 +556,8 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
 		return ERROR_OK;
 	}
 	
-   WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
-	
-   return ERROR_OK;
+	WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
+	return ERROR_OK;
 }
 
 int at91sam7_erase_check(struct flash_bank_s *bank)
@@ -579,20 +581,14 @@ int at91sam7_protect_check(struct flash_bank_s *bank)
 	
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
 
-	if (bank->target->state != TARGET_HALTED)
-	{
-		return ERROR_TARGET_NOT_HALTED;
-	}
-
 	if (at91sam7_info->cidr == 0)
 	{
-		at91sam7_read_part_info(bank);
+		return ERROR_FLASH_BANK_NOT_PROBED;
 	}
 
-	if (at91sam7_info->cidr == 0)
+	if (bank->target->state != TARGET_HALTED)
 	{
-		WARNING("Cannot identify target as an AT91SAM");
-		return ERROR_FLASH_OPERATION_FAILED;
+		return ERROR_TARGET_NOT_HALTED;
 	}
 
 	for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
@@ -619,7 +615,6 @@ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch
 	
 	at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
 	bank->driver_priv = at91sam7_info;
-	at91sam7_info->probed = 0;
 	
 	/* part wasn't probed for info yet */
 	at91sam7_info->cidr = 0;
@@ -634,21 +629,15 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
 	u8 flashplane;
 
-	if (bank->target->state != TARGET_HALTED)
-	{
-		return ERROR_TARGET_NOT_HALTED;
-	}
-	
 	if (at91sam7_info->cidr == 0)
 	{
-		at91sam7_read_part_info(bank);
+		return ERROR_FLASH_BANK_NOT_PROBED;
 	}
 
-	if (at91sam7_info->cidr == 0)
+	if (bank->target->state != TARGET_HALTED)
 	{
-		WARNING("Cannot identify target as an AT91SAM");
-		return ERROR_FLASH_OPERATION_FAILED;
-	}	
+		return ERROR_TARGET_NOT_HALTED;
+	}
 	
 	if ((first < 0) || (last < first) || (last >= bank->num_sectors))
 	{
@@ -683,6 +672,11 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
 	
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
 	
+	if (at91sam7_info->cidr == 0)
+	{
+		return ERROR_FLASH_BANK_NOT_PROBED;
+	}
+
 	if (bank->target->state != TARGET_HALTED)
 	{
 		return ERROR_TARGET_NOT_HALTED;
@@ -693,17 +687,6 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
 		return ERROR_FLASH_SECTOR_INVALID;
 	}
 	
-	if (at91sam7_info->cidr == 0)
-	{
-		at91sam7_read_part_info(bank);
-	}
-
-	if (at91sam7_info->cidr == 0)
-	{
-		WARNING("Cannot identify target as an AT91SAM");
-		return ERROR_FLASH_OPERATION_FAILED;
-	}
-	
 	at91sam7_read_clock_info(bank);	
 	
 	for (lockregion=first;lockregion<=last;lockregion++) 
@@ -738,22 +721,16 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
 	u32 first_page, last_page, pagen, buffer_pos;
 	u8 flashplane;
 	
-	if (bank->target->state != TARGET_HALTED)
-	{
-		return ERROR_TARGET_NOT_HALTED;
-	}
-
 	if (at91sam7_info->cidr == 0)
 	{
-		at91sam7_read_part_info(bank);
+		return ERROR_FLASH_BANK_NOT_PROBED;
 	}
 
-	if (at91sam7_info->cidr == 0)
+	if (bank->target->state != TARGET_HALTED)
 	{
-		WARNING("Cannot identify target as an AT91SAM");
-		return ERROR_FLASH_OPERATION_FAILED;
+		return ERROR_TARGET_NOT_HALTED;
 	}
-	
+
 	if (offset + count > bank->size)
 		return ERROR_FLASH_DST_OUT_OF_BANK;
 	
@@ -809,56 +786,34 @@ int at91sam7_probe(struct flash_bank_s *bank)
 	 * if this is an at91sam7, it has the configured flash
 	 */
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-	at91sam7_info->probed = 0;
+	int retval;
 	
-	if (bank->target->state != TARGET_HALTED)
+	if (at91sam7_info->cidr != 0)
 	{
-		return ERROR_TARGET_NOT_HALTED;
+		return ERROR_OK; /* already probed */
 	}
 
-	if (at91sam7_info->cidr == 0)
+	if (bank->target->state != TARGET_HALTED)
 	{
-		at91sam7_read_part_info(bank);
+		return ERROR_TARGET_NOT_HALTED;
 	}
 
-	if (at91sam7_info->cidr == 0)
-	{
-		WARNING("Cannot identify target as an AT91SAM");
-		return ERROR_FLASH_OPERATION_FAILED;
-	}
-	
-	at91sam7_info->probed = 1;
+	retval = at91sam7_read_part_info(bank);
+	if (retval != ERROR_OK)
+		return retval;
 	
 	return ERROR_OK;
 }
 
 
-int at91sam7_auto_probe(struct flash_bank_s *bank)
-{
-	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
-	if (at91sam7_info->probed)
-		return ERROR_OK;
-	return at91sam7_probe(bank);
-}
-
 int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
 {
 	int printed, flashplane;
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
 	
-	if (bank->target->state != TARGET_HALTED)
-	{
-		return ERROR_TARGET_NOT_HALTED;
-	}
-
-	at91sam7_read_part_info(bank);
-
 	if (at91sam7_info->cidr == 0)
 	{
-		printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n");
-		buf += printed;
-		buf_size -= printed;
-		return ERROR_FLASH_OPERATION_FAILED;
+		return ERROR_FLASH_BANK_NOT_PROBED;
 	}
 	
 	printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
@@ -894,7 +849,7 @@ int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
 		buf_size -= printed;
 	}
 			
-	printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits);
+	printed = snprintf(buf, buf_size, "securitybit: %i,  nvmbits(%i): 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->nvmbits);
 	buf += printed;
 	buf_size -= printed;
 
@@ -919,6 +874,7 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
 	u32 status;
 	char *value;
 	at91sam7_flash_bank_t *at91sam7_info;
+	int retval;
 
 	if (argc < 3)
 	{
@@ -926,32 +882,48 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
 		return ERROR_OK;
 	}
 	
-	bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+	bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
 	bit = atoi(args[1]);
 	value = args[2];
 
-	if (!bank)
+	if (bank ==  NULL)
 	{
-		command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
-		return ERROR_OK;
+		return ERROR_FLASH_BANK_INVALID;
+	}
+
+	if (bank->driver != &at91sam7_flash)
+	{
+		command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
+		return ERROR_FLASH_BANK_INVALID;
+	}
+
+	if (strcmp(value, "set") == 0)
+	{
+		flashcmd = SGPB;
+	}
+	else if (strcmp(value, "clear") == 0)
+	{
+		flashcmd = CGPB;
+	}
+	else
+	{
+		return ERROR_COMMAND_SYNTAX_ERROR;
 	}
 
 	at91sam7_info = bank->driver_priv;
 
 	if (bank->target->state != TARGET_HALTED)
 	{
+		ERROR("target has to be halted to perform flash operation");
 		return ERROR_TARGET_NOT_HALTED;
 	}
 	
 	if (at91sam7_info->cidr == 0)
 	{
-		at91sam7_read_part_info(bank);
-	}
-
-	if (at91sam7_info->cidr == 0)
-	{
-		WARNING("Cannot identify target as an AT91SAM");
-		return ERROR_FLASH_OPERATION_FAILED;
+		retval = at91sam7_read_part_info(bank);
+		if (retval != ERROR_OK) {
+			return retval;
+		}
 	}
 
 	if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
@@ -960,19 +932,6 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
 		return ERROR_OK;
 	}
 
-	if (strcmp(value, "set") == 0)
-	{
-		flashcmd = SGPB;
-	}
-	else if (strcmp(value, "clear") == 0)
-	{
-		flashcmd = CGPB;
-	}
-	else
-	{
-		return ERROR_COMMAND_SYNTAX_ERROR;
-	}
-
 	/* Configure the flash controller timing */
 	at91sam7_read_clock_info(bank);	
 	at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
diff --git a/src/flash/at91sam7.h b/src/flash/at91sam7.h
index eb0213c03..ecb567014 100644
--- a/src/flash/at91sam7.h
+++ b/src/flash/at91sam7.h
@@ -59,9 +59,7 @@ typedef struct at91sam7_flash_bank_s
 	/* main clock status */
 	u8  mck_valid;
 	u32 mck_freq;
-	
-	int probed;
-	
+
 } at91sam7_flash_bank_t;
 
 /* AT91SAM7 control registers */
diff --git a/src/flash/flash.c b/src/flash/flash.c
index 92ac6fd6c..1c6773dbb 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -93,7 +93,7 @@ static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset,
 	retval=bank->driver->write(bank, buffer, offset, count);
 	if (retval!=ERROR_OK)
 	{
-		ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x", bank->base, offset);
+		ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank->base, offset, retval);
 	}
 
 	return retval;
@@ -106,7 +106,7 @@ static int flash_driver_erase(struct flash_bank_s *bank, int first, int last)
 	retval=bank->driver->erase(bank, first, last);
 	if (retval!=ERROR_OK)
 	{
-		ERROR("failed erasing sectors %d to %d", first, last);
+		ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
 	}
 
 	return retval;
@@ -119,7 +119,7 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last
 	retval=bank->driver->protect(bank, set, first, last);
 	if (retval!=ERROR_OK)
 	{
-		ERROR("failed setting protection for areas %d to %d", first, last);
+		ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
 	}
 
 	return retval;
@@ -311,6 +311,7 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
 	flash_bank_t *p;
 	int i = 0;
 	int j = 0;
+	int retval;
 
 	if (argc != 1)
 	{
@@ -351,8 +352,11 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
 							erase_state, protect_state);
 			}
 
-			p->driver->info(p, buf, 1024);
+			*buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
+			retval = p->driver->info(p, buf, sizeof(buf));
 			command_print(cmd_ctx, "%s", buf);
+			if (retval != ERROR_OK)
+				ERROR("error retrieving flash info (%d)", retval);
 		}
 	}
 
@@ -918,7 +922,6 @@ int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd
 	if (argc != 1)
 	{
 		return ERROR_COMMAND_SYNTAX_ERROR;
-
 	}
 
 	if (strcmp(args[0], "on") == 0)
diff --git a/src/flash/flash.h b/src/flash/flash.h
index 2e6c1ec09..846ddc4b1 100644
--- a/src/flash/flash.h
+++ b/src/flash/flash.h
@@ -80,6 +80,7 @@ extern void flash_set_dirty(void);
 extern int flash_get_bank_count();
 
 extern flash_bank_t *get_flash_bank_by_num(int num);
+extern flash_bank_t *get_flash_bank_by_num_noprobe(int num);
 extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
 
 #define		ERROR_FLASH_BANK_INVALID		(-900)
diff --git a/src/flash/stellaris.c b/src/flash/stellaris.c
index 2eca290cb..2f91e564e 100644
--- a/src/flash/stellaris.c
+++ b/src/flash/stellaris.c
@@ -77,7 +77,7 @@ flash_driver_t stellaris_flash =
 
 struct {
 	u32 partno;
-    char *partname;
+	char *partname;
 }	StellarisParts[] =
 {
 	{0x01,"LM3S101"},
@@ -269,9 +269,9 @@ int stellaris_info(struct flash_bank_s *bank, char *buf, int buf_size)
 	{
 		device_class = 0;
 	}	
-    printed = snprintf(buf, buf_size, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
-         device_class, StellarisClassname[device_class], stellaris_info->target_name,
-         'A' + (stellaris_info->did0>>8)&0xFF, (stellaris_info->did0)&0xFF);
+	printed = snprintf(buf, buf_size, "\nLMI Stellaris information: Chip is class %i(%s) %s v%c.%i\n",
+	  device_class, StellarisClassname[device_class], stellaris_info->target_name,
+	  'A' + (stellaris_info->did0>>8)&0xFF, (stellaris_info->did0)&0xFF);
 	buf += printed;
 	buf_size -= printed;
 
@@ -352,7 +352,7 @@ void stellaris_read_clock_info(flash_bank_t *bank)
 		stellaris_info->mck_freq = mainfreq;
 	
 	/* Forget old flash timing */
-       stellaris_set_flash_mode(bank,0);
+	stellaris_set_flash_mode(bank,0);
 }
 
 /* Setup the timimg registers */
@@ -407,7 +407,7 @@ int stellaris_read_part_info(struct flash_bank_s *bank)
 {
 	stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
 	target_t *target = bank->target;
-    u32 did0,did1, ver, fam, status;
+	u32 did0,did1, ver, fam, status;
 	int i;
 	
 	/* Read and parse chip identification register */
@@ -417,10 +417,10 @@ int stellaris_read_part_info(struct flash_bank_s *bank)
 	target_read_u32(target, SCB_BASE|DC1, &stellaris_info->dc1);
 	DEBUG("did0 0x%x, did1 0x%x, dc0 0x%x, dc1 0x%x",did0, did1, stellaris_info->dc0,stellaris_info->dc1);
 
-    ver = did0 >> 28;
-    if((ver != 0) && (ver != 1))
+	ver = did0 >> 28;
+	if((ver != 0) && (ver != 1))
 	{
-        WARNING("Unknown did0 version, cannot identify target");
+		WARNING("Unknown did0 version, cannot identify target");
 		return ERROR_FLASH_OPERATION_FAILED;	
 	}
 
@@ -430,11 +430,11 @@ int stellaris_read_part_info(struct flash_bank_s *bank)
 		return ERROR_FLASH_OPERATION_FAILED;
 	}
 
-    ver = did1 >> 28;
-    fam = (did1 >> 24) & 0xF;
-    if(((ver != 0) && (ver != 1)) || (fam != 0))
+	ver = did1 >> 28;
+	fam = (did1 >> 24) & 0xF;
+	if(((ver != 0) && (ver != 1)) || (fam != 0))
 	{
-        WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
+		WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
 	}
 
 	for (i=0;StellarisParts[i].partno;i++)
@@ -464,7 +464,7 @@ int stellaris_read_part_info(struct flash_bank_s *bank)
 }
 
 /***************************************************************************
-*	flash operations                                         *
+*	flash operations                                                       *
 ***************************************************************************/
 
 int stellaris_erase_check(struct flash_bank_s *bank)
@@ -527,7 +527,7 @@ int stellaris_erase(struct flash_bank_s *bank, int first, int last)
 
 	if (stellaris_info->did1 == 0)
 	{
-        WARNING("Cannot identify target as Stellaris");
+		WARNING("Cannot identify target as Stellaris");
 		return ERROR_FLASH_OPERATION_FAILED;
 	}	
 	
@@ -546,7 +546,7 @@ int stellaris_erase(struct flash_bank_s *bank, int first, int last)
 
 	if ((first == 0) && (last == (stellaris_info->num_pages-1)))
 	{
-        target_write_u32(target, FLASH_FMA, 0);
+		target_write_u32(target, FLASH_FMA, 0);
 		target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
 		/* Wait until erase complete */
 		do
@@ -555,18 +555,18 @@ int stellaris_erase(struct flash_bank_s *bank, int first, int last)
 		}
 		while(flash_fmc & FMC_MERASE);
 		
-        /* if device has > 128k, then second erase cycle is needed */
-        if(stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
-        {
-            target_write_u32(target, FLASH_FMA, 0x20000);
-            target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
-            /* Wait until erase complete */
-            do
-            {
-                target_read_u32(target, FLASH_FMC, &flash_fmc);
-            }
-            while(flash_fmc & FMC_MERASE);
-        }
+		/* if device has > 128k, then second erase cycle is needed */
+		if(stellaris_info->num_pages * stellaris_info->pagesize > 0x20000)
+		{
+			target_write_u32(target, FLASH_FMA, 0x20000);
+			target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);
+			/* Wait until erase complete */
+			do
+			{
+				target_read_u32(target, FLASH_FMC, &flash_fmc);
+			}
+			while(flash_fmc & FMC_MERASE);
+		}
 
 		return ERROR_OK;
 	}
@@ -687,26 +687,26 @@ u8 stellaris_write_code[] =
 	r6 = bytes written
 	r7 = temp reg
 */
-	0x07,0x4B,     		/* ldr r3,pFLASH_CTRL_BASE */
-	0x08,0x4C,     		/* ldr r4,FLASHWRITECMD */
-	0x01,0x25,     		/* movs r5, 1 */
-	0x00,0x26,     		/* movs r6, #0 */
+	0x07,0x4B,			/* ldr r3,pFLASH_CTRL_BASE */
+	0x08,0x4C,			/* ldr r4,FLASHWRITECMD */
+	0x01,0x25,			/* movs r5, 1 */
+	0x00,0x26,			/* movs r6, #0 */
 /* mainloop: */
-	0x19,0x60,     		/* str	r1, [r3, #0] */
-	0x87,0x59,     		/* ldr	r7, [r0, r6] */
-	0x5F,0x60,     		/* str	r7, [r3, #4] */
-	0x9C,0x60,     		/* str	r4, [r3, #8] */
+	0x19,0x60,			/* str	r1, [r3, #0] */
+	0x87,0x59,			/* ldr	r7, [r0, r6] */
+	0x5F,0x60,			/* str	r7, [r3, #4] */
+	0x9C,0x60,			/* str	r4, [r3, #8] */
 /* waitloop: */
-	0x9F,0x68,     		/* ldr	r7, [r3, #8] */
-	0x2F,0x42,     		/* tst	r7, r5 */
-	0xFC,0xD1,     		/* bne	waitloop */
-	0x04,0x31,     		/* adds	r1, r1, #4 */
-	0x04,0x36,     		/* adds	r6, r6, #4 */
-	0x96,0x42,     		/* cmp	r6, r2 */
-	0xF4,0xD1,     		/* bne	mainloop */
-	0x00,0xBE,     		/* bkpt #0 */
+	0x9F,0x68,			/* ldr	r7, [r3, #8] */
+	0x2F,0x42,			/* tst	r7, r5 */
+	0xFC,0xD1,			/* bne	waitloop */
+	0x04,0x31,			/* adds	r1, r1, #4 */
+	0x04,0x36,			/* adds	r6, r6, #4 */
+	0x96,0x42,			/* cmp	r6, r2 */
+	0xF4,0xD1,			/* bne	mainloop */
+	0x00,0xBE,			/* bkpt #0 */
 /* pFLASH_CTRL_BASE: */
-	0x00,0xD0,0x0F,0x40, 	/* .word	0x400FD000 */
+	0x00,0xD0,0x0F,0x40,	/* .word	0x400FD000 */
 /* FLASHWRITECMD: */
 	0x01,0x00,0x42,0xA4 	/* .word	0xA4420001 */
 };
-- 
GitLab