mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-11-04 07:00:39 +01:00 
			
		
		
		
	flashrom.c: Supplement chip->unlock() calls with wp unlocking
				
					
				
			The full writeprotect implementation has proper support and
ability to unlock flash over spi25_statusreg.c. Therefore if
the required bits are available for the given chip prefer
proper writeprotect support instead of adhoc spi25_statusreg.c
helpers.
BUG=b:237485865
BRANCH=none
TEST=Tested on grunt DUT (prog: sb600spi, flash: W25Q128.W):
     `flashrom --wp-range 0x0,0x1000000 \
      flashrom --wp-status     # Result: range=0x0,0x1000000 \
      flashrom -w random.bin   # Result: success \
      flashrom -v random.bin   # Result: success \
      flashrom --wp-status     # Result: range=0x0,0x1000000`
TEST=Tested that chips without WP support can still be unlocked
     by deleting decode_range for W25Q128.W flashchip and
     retesting on the grunt DUT.
Change-Id: I74b3f5d3a17749ea60485b916b2d87467a5d8b2f
CoAuthored-by: Nikolai Artemiev <nartemiev@google.com>
Signed-off-by: Nikolai Artemiev <nartemiev@google.com>
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/69517
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
			
			
This commit is contained in:
		
				
					committed by
					
						
						Anastasia Klimchuk
					
				
			
			
				
	
			
			
			
						parent
						
							7ffa626d12
						
					
				
				
					commit
					7d888a3082
				
			
							
								
								
									
										60
									
								
								flashrom.c
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								flashrom.c
									
									
									
									
									
								
							@@ -1907,6 +1907,53 @@ static int chip_safety_check(const struct flashctx *flash, int force,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int restore_flash_wp(struct flashctx *const flash, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct flashrom_wp_cfg *wp_cfg = data;
 | 
				
			||||||
 | 
						enum flashrom_wp_result ret = flashrom_wp_write_cfg(flash, wp_cfg);
 | 
				
			||||||
 | 
						flashrom_wp_cfg_release(wp_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (ret == FLASHROM_WP_OK) ? 0 : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int save_initial_flash_wp(struct flashctx *const flash)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct flashrom_wp_cfg *initial_wp_cfg;
 | 
				
			||||||
 | 
						if (flashrom_wp_cfg_new(&initial_wp_cfg) != FLASHROM_WP_OK)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flashrom_wp_read_cfg(initial_wp_cfg, flash) != FLASHROM_WP_OK) {
 | 
				
			||||||
 | 
							flashrom_wp_cfg_release(initial_wp_cfg);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (register_chip_restore(restore_flash_wp, flash, initial_wp_cfg)) {
 | 
				
			||||||
 | 
							flashrom_wp_cfg_release(initial_wp_cfg);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int unlock_flash_wp(struct flashctx *const flash)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Save original WP state to be restored later */
 | 
				
			||||||
 | 
						if (save_initial_flash_wp(flash))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Disable WP */
 | 
				
			||||||
 | 
						struct flashrom_wp_cfg *unlocked_wp_cfg;
 | 
				
			||||||
 | 
						if (flashrom_wp_cfg_new(&unlocked_wp_cfg) != FLASHROM_WP_OK)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flashrom_wp_set_range(unlocked_wp_cfg, 0, 0);
 | 
				
			||||||
 | 
						flashrom_wp_set_mode(unlocked_wp_cfg, FLASHROM_WP_MODE_DISABLED);
 | 
				
			||||||
 | 
						enum flashrom_wp_result ret = flashrom_wp_write_cfg(flash, unlocked_wp_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flashrom_wp_cfg_release(unlocked_wp_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (ret == FLASHROM_WP_OK) ? 0 : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int prepare_flash_access(struct flashctx *const flash,
 | 
					int prepare_flash_access(struct flashctx *const flash,
 | 
				
			||||||
			 const bool read_it, const bool write_it,
 | 
								 const bool read_it, const bool write_it,
 | 
				
			||||||
			 const bool erase_it, const bool verify_it)
 | 
								 const bool erase_it, const bool verify_it)
 | 
				
			||||||
@@ -1927,10 +1974,16 @@ int prepare_flash_access(struct flashctx *const flash,
 | 
				
			|||||||
	/* Initialize chip_restore_fn_count before chip unlock calls. */
 | 
						/* Initialize chip_restore_fn_count before chip unlock calls. */
 | 
				
			||||||
	flash->chip_restore_fn_count = 0;
 | 
						flash->chip_restore_fn_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Given the existence of read locks, we want to unlock for read,
 | 
						/* Given the existence of read locks, we want to unlock for read, erase and write. */
 | 
				
			||||||
	   erase and write. */
 | 
						int ret = 1;
 | 
				
			||||||
	if (flash->chip->unlock)
 | 
						if (flash->chip->decode_range != NO_DECODE_RANGE_FUNC) {
 | 
				
			||||||
 | 
							ret = unlock_flash_wp(flash);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								msg_cerr("Failed to unlock flash status reg with wp support.\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (ret && flash->chip->unlock) {
 | 
				
			||||||
		flash->chip->unlock(flash);
 | 
							flash->chip->unlock(flash);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flash->address_high_byte = -1;
 | 
						flash->address_high_byte = -1;
 | 
				
			||||||
	flash->in_4ba_mode = false;
 | 
						flash->in_4ba_mode = false;
 | 
				
			||||||
@@ -1947,7 +2000,6 @@ int prepare_flash_access(struct flashctx *const flash,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Enable/disable 4-byte addressing mode if flash chip supports it */
 | 
						/* Enable/disable 4-byte addressing mode if flash chip supports it */
 | 
				
			||||||
	if (spi_chip_4ba(flash)) {
 | 
						if (spi_chip_4ba(flash)) {
 | 
				
			||||||
		int ret;
 | 
					 | 
				
			||||||
		if (spi_master_4ba(flash))
 | 
							if (spi_master_4ba(flash))
 | 
				
			||||||
			ret = spi_enter_4ba(flash);
 | 
								ret = spi_enter_4ba(flash);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user