mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-11-04 07:00:39 +01:00 
			
		
		
		
	flashrom.c: Plumb 'all_skipped' global state into func param
The 'all_skipped' global state can be made into a function parameter if one just follows though the CFG. Running `flashrom -p dummy:emulate=SST25VF032B,image=r.bin -w r.bin` displays the message "Warning: Chip content is identical to the requested image." Change-Id: I2346c869c47b48604360b0facf9313aae086c8dd Signed-off-by: Edward O'Callaghan <quasisec@google.com> Co-authored-by: Aarya Chaumal <aarya.chaumal@gmail.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/67093 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Anastasia Klimchuk <aklm@chromium.org> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
This commit is contained in:
		
				
					committed by
					
						
						Anastasia Klimchuk
					
				
			
			
				
	
			
			
			
						parent
						
							78e121b014
						
					
				
				
					commit
					f2d20cf713
				
			
							
								
								
									
										42
									
								
								flashrom.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								flashrom.c
									
									
									
									
									
								
							@@ -62,9 +62,6 @@ static struct shutdown_func_data {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
static bool may_register_shutdown = false;
 | 
					static bool may_register_shutdown = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Did we change something or was every erase/write skipped (if any)? */
 | 
					 | 
				
			||||||
static bool all_skipped = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct programmer_cfg {
 | 
					struct programmer_cfg {
 | 
				
			||||||
	char *params;
 | 
						char *params;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -1314,11 +1311,12 @@ struct walk_info {
 | 
				
			|||||||
	chipoff_t erase_end;
 | 
						chipoff_t erase_end;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
/* returns 0 on success, 1 to retry with another erase function, 2 for immediate abort */
 | 
					/* returns 0 on success, 1 to retry with another erase function, 2 for immediate abort */
 | 
				
			||||||
typedef int (*per_blockfn_t)(struct flashctx *, const struct walk_info *, erasefn_t);
 | 
					typedef int (*per_blockfn_t)(struct flashctx *, const struct walk_info *, erasefn_t, bool *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int walk_eraseblocks(struct flashctx *const flashctx,
 | 
					static int walk_eraseblocks(struct flashctx *const flashctx,
 | 
				
			||||||
			    struct walk_info *const info,
 | 
								    struct walk_info *const info,
 | 
				
			||||||
			    const size_t erasefunction, const per_blockfn_t per_blockfn)
 | 
								    const size_t erasefunction, const per_blockfn_t per_blockfn,
 | 
				
			||||||
 | 
								    bool *all_skipped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	size_t i, j;
 | 
						size_t i, j;
 | 
				
			||||||
@@ -1346,7 +1344,7 @@ static int walk_eraseblocks(struct flashctx *const flashctx,
 | 
				
			|||||||
			msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end);
 | 
								msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			erasefunc_t *erase_func = lookup_erase_func_ptr(eraser);
 | 
								erasefunc_t *erase_func = lookup_erase_func_ptr(eraser);
 | 
				
			||||||
			ret = per_blockfn(flashctx, info, erase_func);
 | 
								ret = per_blockfn(flashctx, info, erase_func, all_skipped);
 | 
				
			||||||
			if (ret)
 | 
								if (ret)
 | 
				
			||||||
				return ret;
 | 
									return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -1358,12 +1356,12 @@ static int walk_eraseblocks(struct flashctx *const flashctx,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *const info,
 | 
					static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *const info,
 | 
				
			||||||
			  const per_blockfn_t per_blockfn)
 | 
								  const per_blockfn_t per_blockfn, bool *all_skipped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct flashrom_layout *const layout = get_layout(flashctx);
 | 
						const struct flashrom_layout *const layout = get_layout(flashctx);
 | 
				
			||||||
	const struct romentry *entry = NULL;
 | 
						const struct romentry *entry = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	all_skipped = true;
 | 
						*all_skipped = true;
 | 
				
			||||||
	msg_cinfo("Erasing and writing flash chip... ");
 | 
						msg_cinfo("Erasing and writing flash chip... ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((entry = layout_next_included(layout, entry))) {
 | 
						while ((entry = layout_next_included(layout, entry))) {
 | 
				
			||||||
@@ -1380,7 +1378,7 @@ static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *con
 | 
				
			|||||||
			if (check_block_eraser(flashctx, j, 1))
 | 
								if (check_block_eraser(flashctx, j, 1))
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			error = walk_eraseblocks(flashctx, info, j, per_blockfn);
 | 
								error = walk_eraseblocks(flashctx, info, j, per_blockfn, all_skipped);
 | 
				
			||||||
			if (error != 1)
 | 
								if (error != 1)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1404,14 +1402,15 @@ static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *con
 | 
				
			|||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (all_skipped)
 | 
						if (*all_skipped)
 | 
				
			||||||
		msg_cinfo("\nWarning: Chip content is identical to the requested image.\n");
 | 
							msg_cinfo("\nWarning: Chip content is identical to the requested image.\n");
 | 
				
			||||||
	msg_cinfo("Erase/write done.\n");
 | 
						msg_cinfo("Erase/write done.\n");
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int erase_block(struct flashctx *const flashctx,
 | 
					static int erase_block(struct flashctx *const flashctx,
 | 
				
			||||||
		       const struct walk_info *const info, const erasefn_t erasefn)
 | 
							       const struct walk_info *const info, const erasefn_t erasefn,
 | 
				
			||||||
 | 
							       bool *all_skipped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
 | 
						const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
 | 
				
			||||||
	const bool region_unaligned = info->region_start > info->erase_start ||
 | 
						const bool region_unaligned = info->region_start > info->erase_start ||
 | 
				
			||||||
@@ -1457,7 +1456,7 @@ static int erase_block(struct flashctx *const flashctx,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = 1;
 | 
						ret = 1;
 | 
				
			||||||
	all_skipped = false;
 | 
						*all_skipped = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msg_cdbg("E");
 | 
						msg_cdbg("E");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1529,11 +1528,13 @@ _free_ret:
 | 
				
			|||||||
static int erase_by_layout(struct flashctx *const flashctx)
 | 
					static int erase_by_layout(struct flashctx *const flashctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct walk_info info = { 0 };
 | 
						struct walk_info info = { 0 };
 | 
				
			||||||
	return walk_by_layout(flashctx, &info, &erase_block);
 | 
						bool all_skipped = true;
 | 
				
			||||||
 | 
						return walk_by_layout(flashctx, &info, &erase_block, &all_skipped);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int read_erase_write_block(struct flashctx *const flashctx,
 | 
					static int read_erase_write_block(struct flashctx *const flashctx,
 | 
				
			||||||
				  const struct walk_info *const info, const erasefn_t erasefn)
 | 
									  const struct walk_info *const info, const erasefn_t erasefn,
 | 
				
			||||||
 | 
									  bool *all_skipped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const chipsize_t erase_len = info->erase_end + 1 - info->erase_start;
 | 
						const chipsize_t erase_len = info->erase_end + 1 - info->erase_start;
 | 
				
			||||||
	const bool region_unaligned = info->region_start > info->erase_start ||
 | 
						const bool region_unaligned = info->region_start > info->erase_start ||
 | 
				
			||||||
@@ -1591,7 +1592,7 @@ static int read_erase_write_block(struct flashctx *const flashctx,
 | 
				
			|||||||
	const uint8_t erased_value = ERASED_VALUE(flashctx);
 | 
						const uint8_t erased_value = ERASED_VALUE(flashctx);
 | 
				
			||||||
	if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) &&
 | 
						if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) &&
 | 
				
			||||||
			need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) {
 | 
								need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) {
 | 
				
			||||||
		if (erase_block(flashctx, info, erasefn))
 | 
							if (erase_block(flashctx, info, erasefn, all_skipped))
 | 
				
			||||||
			goto _free_ret;
 | 
								goto _free_ret;
 | 
				
			||||||
		/* Erase was successful. Adjust curcontents. */
 | 
							/* Erase was successful. Adjust curcontents. */
 | 
				
			||||||
		memset(curcontents, erased_value, erase_len);
 | 
							memset(curcontents, erased_value, erase_len);
 | 
				
			||||||
@@ -1614,7 +1615,7 @@ static int read_erase_write_block(struct flashctx *const flashctx,
 | 
				
			|||||||
	if (skipped)
 | 
						if (skipped)
 | 
				
			||||||
		msg_cdbg("S");
 | 
							msg_cdbg("S");
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		all_skipped = false;
 | 
							*all_skipped = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update curcontents, other regions with overlapping erase blocks
 | 
						/* Update curcontents, other regions with overlapping erase blocks
 | 
				
			||||||
	   might rely on this. */
 | 
						   might rely on this. */
 | 
				
			||||||
@@ -1640,12 +1641,13 @@ _free_ret:
 | 
				
			|||||||
 *	   1 if anything has gone wrong.
 | 
					 *	   1 if anything has gone wrong.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int write_by_layout(struct flashctx *const flashctx,
 | 
					static int write_by_layout(struct flashctx *const flashctx,
 | 
				
			||||||
			   void *const curcontents, const void *const newcontents)
 | 
								   void *const curcontents, const void *const newcontents,
 | 
				
			||||||
 | 
								   bool *all_skipped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct walk_info info;
 | 
						struct walk_info info;
 | 
				
			||||||
	info.curcontents = curcontents;
 | 
						info.curcontents = curcontents;
 | 
				
			||||||
	info.newcontents = newcontents;
 | 
						info.newcontents = newcontents;
 | 
				
			||||||
	return walk_by_layout(flashctx, &info, read_erase_write_block);
 | 
						return walk_by_layout(flashctx, &info, read_erase_write_block, all_skipped);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -2097,7 +2099,9 @@ int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, co
 | 
				
			|||||||
		msg_cinfo("done.\n");
 | 
							msg_cinfo("done.\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (write_by_layout(flashctx, curcontents, newcontents)) {
 | 
						bool all_skipped = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (write_by_layout(flashctx, curcontents, newcontents, &all_skipped)) {
 | 
				
			||||||
		msg_cerr("Uh oh. Erase/write failed. ");
 | 
							msg_cerr("Uh oh. Erase/write failed. ");
 | 
				
			||||||
		ret = 2;
 | 
							ret = 2;
 | 
				
			||||||
		if (verify_all) {
 | 
							if (verify_all) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user