1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * SPI NOR Software Write Protection logic. 4 * 5 * Copyright (C) 2005, Intec Automation Inc. 6 * Copyright (C) 2014, Freescale Semiconductor, Inc. 7 */ 8 #include <linux/mtd/mtd.h> 9 #include <linux/mtd/spi-nor.h> 10 11 #include "core.h" 12 13 static u8 spi_nor_get_sr_bp_mask(struct spi_nor *nor) 14 { 15 u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 16 17 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6) 18 return mask | SR_BP3_BIT6; 19 20 if (nor->flags & SNOR_F_HAS_4BIT_BP) 21 return mask | SR_BP3; 22 23 return mask; 24 } 25 26 static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor) 27 { 28 if (nor->flags & SNOR_F_HAS_SR_TB_BIT6) 29 return SR_TB_BIT6; 30 else 31 return SR_TB_BIT5; 32 } 33 34 static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor) 35 { 36 unsigned int bp_slots, bp_slots_needed; 37 /* 38 * sector_size will eventually be replaced with the max erase size of 39 * the flash. For now, we need to have that ugly default. 40 */ 41 unsigned int sector_size = nor->info->sector_size ?: SPI_NOR_DEFAULT_SECTOR_SIZE; 42 u64 n_sectors = div_u64(nor->params->size, sector_size); 43 u8 mask = spi_nor_get_sr_bp_mask(nor); 44 45 /* Reserved one for "protect none" and one for "protect all". */ 46 bp_slots = (1 << hweight8(mask)) - 2; 47 bp_slots_needed = ilog2(n_sectors); 48 49 if (bp_slots_needed > bp_slots) 50 return sector_size << (bp_slots_needed - bp_slots); 51 else 52 return sector_size; 53 } 54 55 static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs, 56 uint64_t *len) 57 { 58 struct mtd_info *mtd = &nor->mtd; 59 u64 min_prot_len; 60 u8 mask = spi_nor_get_sr_bp_mask(nor); 61 u8 tb_mask = spi_nor_get_sr_tb_mask(nor); 62 u8 bp, val = sr & mask; 63 64 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6) 65 val = (val & ~SR_BP3_BIT6) | SR_BP3; 66 67 bp = val >> SR_BP_SHIFT; 68 69 if (!bp) { 70 /* No protection */ 71 *ofs = 0; 72 *len = 0; 73 return; 74 } 75 76 min_prot_len = spi_nor_get_min_prot_length_sr(nor); 77 *len = min_prot_len << (bp - 1); 78 79 if (*len > mtd->size) 80 *len = mtd->size; 81 82 if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask) 83 *ofs = 0; 84 else 85 *ofs = mtd->size - *len; 86 } 87 88 /* 89 * Return true if the entire region is locked (if @locked is true) or unlocked 90 * (if @locked is false); false otherwise. 91 */ 92 static bool spi_nor_check_lock_status_sr(struct spi_nor *nor, loff_t ofs, 93 uint64_t len, u8 sr, bool locked) 94 { 95 loff_t lock_offs, lock_offs_max, offs_max; 96 uint64_t lock_len; 97 98 if (!len) 99 return true; 100 101 spi_nor_get_locked_range_sr(nor, sr, &lock_offs, &lock_len); 102 103 lock_offs_max = lock_offs + lock_len; 104 offs_max = ofs + len; 105 106 if (locked) 107 /* Requested range is a sub-range of locked range */ 108 return (offs_max <= lock_offs_max) && (ofs >= lock_offs); 109 else 110 /* Requested range does not overlap with locked range */ 111 return (ofs >= lock_offs_max) || (offs_max <= lock_offs); 112 } 113 114 static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, 115 u8 sr) 116 { 117 return spi_nor_check_lock_status_sr(nor, ofs, len, sr, true); 118 } 119 120 static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, 121 uint64_t len, u8 sr) 122 { 123 return spi_nor_check_lock_status_sr(nor, ofs, len, sr, false); 124 } 125 126 /* 127 * Lock a region of the flash. Compatible with ST Micro and similar flash. 128 * Supports the block protection bits BP{0,1,2}/BP{0,1,2,3} in the status 129 * register 130 * (SR). Does not support these features found in newer SR bitfields: 131 * - SEC: sector/block protect - only handle SEC=0 (block protect) 132 * - CMP: complement protect - only support CMP=0 (range is not complemented) 133 * 134 * Support for the following is provided conditionally for some flash: 135 * - TB: top/bottom protect 136 * 137 * Sample table portion for 8MB flash (Winbond w25q64fw): 138 * 139 * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion 140 * -------------------------------------------------------------------------- 141 * X | X | 0 | 0 | 0 | NONE | NONE 142 * 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 143 * 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 144 * 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 145 * 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 146 * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 147 * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 148 * X | X | 1 | 1 | 1 | 8 MB | ALL 149 * ------|-------|-------|-------|-------|---------------|------------------- 150 * 0 | 1 | 0 | 0 | 1 | 128 KB | Lower 1/64 151 * 0 | 1 | 0 | 1 | 0 | 256 KB | Lower 1/32 152 * 0 | 1 | 0 | 1 | 1 | 512 KB | Lower 1/16 153 * 0 | 1 | 1 | 0 | 0 | 1 MB | Lower 1/8 154 * 0 | 1 | 1 | 0 | 1 | 2 MB | Lower 1/4 155 * 0 | 1 | 1 | 1 | 0 | 4 MB | Lower 1/2 156 * 157 * Returns negative on errors, 0 on success. 158 */ 159 static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) 160 { 161 struct mtd_info *mtd = &nor->mtd; 162 u64 min_prot_len; 163 int ret, status_old, status_new; 164 u8 mask = spi_nor_get_sr_bp_mask(nor); 165 u8 tb_mask = spi_nor_get_sr_tb_mask(nor); 166 u8 pow, val; 167 loff_t lock_len; 168 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB; 169 bool use_top; 170 171 ret = spi_nor_read_sr(nor, nor->bouncebuf); 172 if (ret) 173 return ret; 174 175 status_old = nor->bouncebuf[0]; 176 177 /* If nothing in our range is unlocked, we don't need to do anything */ 178 if (spi_nor_is_locked_sr(nor, ofs, len, status_old)) 179 return 0; 180 181 /* If anything below us is unlocked, we can't use 'bottom' protection */ 182 if (!spi_nor_is_locked_sr(nor, 0, ofs, status_old)) 183 can_be_bottom = false; 184 185 /* If anything above us is unlocked, we can't use 'top' protection */ 186 if (!spi_nor_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len), 187 status_old)) 188 can_be_top = false; 189 190 if (!can_be_bottom && !can_be_top) 191 return -EINVAL; 192 193 /* Prefer top, if both are valid */ 194 use_top = can_be_top; 195 196 /* lock_len: length of region that should end up locked */ 197 if (use_top) 198 lock_len = mtd->size - ofs; 199 else 200 lock_len = ofs + len; 201 202 if (lock_len == mtd->size) { 203 val = mask; 204 } else { 205 min_prot_len = spi_nor_get_min_prot_length_sr(nor); 206 pow = ilog2(lock_len) - ilog2(min_prot_len) + 1; 207 val = pow << SR_BP_SHIFT; 208 209 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) 210 val = (val & ~SR_BP3) | SR_BP3_BIT6; 211 212 if (val & ~mask) 213 return -EINVAL; 214 215 /* Don't "lock" with no region! */ 216 if (!(val & mask)) 217 return -EINVAL; 218 } 219 220 status_new = (status_old & ~mask & ~tb_mask) | val; 221 222 /* 223 * Disallow further writes if WP# pin is neither left floating nor 224 * wrongly tied to GND (that includes internal pull-downs). 225 * WP# pin hard strapped to GND can be a valid use case. 226 */ 227 if (!(nor->flags & SNOR_F_NO_WP)) 228 status_new |= SR_SRWD; 229 230 if (!use_top) 231 status_new |= tb_mask; 232 233 /* Don't bother if they're the same */ 234 if (status_new == status_old) 235 return 0; 236 237 /* Only modify protection if it will not unlock other areas */ 238 if ((status_new & mask) < (status_old & mask)) 239 return -EINVAL; 240 241 return spi_nor_write_sr_and_check(nor, status_new); 242 } 243 244 /* 245 * Unlock a region of the flash. See spi_nor_sr_lock() for more info 246 * 247 * Returns negative on errors, 0 on success. 248 */ 249 static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) 250 { 251 struct mtd_info *mtd = &nor->mtd; 252 u64 min_prot_len; 253 int ret, status_old, status_new; 254 u8 mask = spi_nor_get_sr_bp_mask(nor); 255 u8 tb_mask = spi_nor_get_sr_tb_mask(nor); 256 u8 pow, val; 257 loff_t lock_len; 258 bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB; 259 bool use_top; 260 261 ret = spi_nor_read_sr(nor, nor->bouncebuf); 262 if (ret) 263 return ret; 264 265 status_old = nor->bouncebuf[0]; 266 267 /* If nothing in our range is locked, we don't need to do anything */ 268 if (spi_nor_is_unlocked_sr(nor, ofs, len, status_old)) 269 return 0; 270 271 /* If anything below us is locked, we can't use 'top' protection */ 272 if (!spi_nor_is_unlocked_sr(nor, 0, ofs, status_old)) 273 can_be_top = false; 274 275 /* If anything above us is locked, we can't use 'bottom' protection */ 276 if (!spi_nor_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len), 277 status_old)) 278 can_be_bottom = false; 279 280 if (!can_be_bottom && !can_be_top) 281 return -EINVAL; 282 283 /* Prefer top, if both are valid */ 284 use_top = can_be_top; 285 286 /* lock_len: length of region that should remain locked */ 287 if (use_top) 288 lock_len = mtd->size - (ofs + len); 289 else 290 lock_len = ofs; 291 292 if (lock_len == 0) { 293 val = 0; /* fully unlocked */ 294 } else { 295 min_prot_len = spi_nor_get_min_prot_length_sr(nor); 296 pow = ilog2(lock_len) - ilog2(min_prot_len) + 1; 297 val = pow << SR_BP_SHIFT; 298 299 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) 300 val = (val & ~SR_BP3) | SR_BP3_BIT6; 301 302 /* Some power-of-two sizes are not supported */ 303 if (val & ~mask) 304 return -EINVAL; 305 } 306 307 status_new = (status_old & ~mask & ~tb_mask) | val; 308 309 /* Don't protect status register if we're fully unlocked */ 310 if (lock_len == 0) 311 status_new &= ~SR_SRWD; 312 313 if (!use_top) 314 status_new |= tb_mask; 315 316 /* Don't bother if they're the same */ 317 if (status_new == status_old) 318 return 0; 319 320 /* Only modify protection if it will not lock other areas */ 321 if ((status_new & mask) > (status_old & mask)) 322 return -EINVAL; 323 324 return spi_nor_write_sr_and_check(nor, status_new); 325 } 326 327 /* 328 * Check if a region of the flash is (completely) locked. See spi_nor_sr_lock() 329 * for more info. 330 * 331 * Returns 1 if entire region is locked, 0 if any portion is unlocked, and 332 * negative on errors. 333 */ 334 static int spi_nor_sr_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) 335 { 336 int ret; 337 338 ret = spi_nor_read_sr(nor, nor->bouncebuf); 339 if (ret) 340 return ret; 341 342 return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]); 343 } 344 345 static const struct spi_nor_locking_ops spi_nor_sr_locking_ops = { 346 .lock = spi_nor_sr_lock, 347 .unlock = spi_nor_sr_unlock, 348 .is_locked = spi_nor_sr_is_locked, 349 }; 350 351 void spi_nor_init_default_locking_ops(struct spi_nor *nor) 352 { 353 nor->params->locking_ops = &spi_nor_sr_locking_ops; 354 } 355 356 static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 357 { 358 struct spi_nor *nor = mtd_to_spi_nor(mtd); 359 int ret; 360 361 ret = spi_nor_prep_and_lock(nor); 362 if (ret) 363 return ret; 364 365 ret = nor->params->locking_ops->lock(nor, ofs, len); 366 367 spi_nor_unlock_and_unprep(nor); 368 return ret; 369 } 370 371 static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 372 { 373 struct spi_nor *nor = mtd_to_spi_nor(mtd); 374 int ret; 375 376 ret = spi_nor_prep_and_lock(nor); 377 if (ret) 378 return ret; 379 380 ret = nor->params->locking_ops->unlock(nor, ofs, len); 381 382 spi_nor_unlock_and_unprep(nor); 383 return ret; 384 } 385 386 static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) 387 { 388 struct spi_nor *nor = mtd_to_spi_nor(mtd); 389 int ret; 390 391 ret = spi_nor_prep_and_lock(nor); 392 if (ret) 393 return ret; 394 395 ret = nor->params->locking_ops->is_locked(nor, ofs, len); 396 397 spi_nor_unlock_and_unprep(nor); 398 return ret; 399 } 400 401 /** 402 * spi_nor_try_unlock_all() - Tries to unlock the entire flash memory array. 403 * @nor: pointer to a 'struct spi_nor'. 404 * 405 * Some SPI NOR flashes are write protected by default after a power-on reset 406 * cycle, in order to avoid inadvertent writes during power-up. Backward 407 * compatibility imposes to unlock the entire flash memory array at power-up 408 * by default. 409 * 410 * Unprotecting the entire flash array will fail for boards which are hardware 411 * write-protected. Thus any errors are ignored. 412 */ 413 void spi_nor_try_unlock_all(struct spi_nor *nor) 414 { 415 int ret; 416 417 if (!(nor->flags & SNOR_F_HAS_LOCK)) 418 return; 419 420 dev_dbg(nor->dev, "Unprotecting entire flash array\n"); 421 422 ret = spi_nor_unlock(&nor->mtd, 0, nor->params->size); 423 if (ret) 424 dev_dbg(nor->dev, "Failed to unlock the entire flash memory array\n"); 425 } 426 427 void spi_nor_set_mtd_locking_ops(struct spi_nor *nor) 428 { 429 struct mtd_info *mtd = &nor->mtd; 430 431 if (!nor->params->locking_ops) 432 return; 433 434 mtd->_lock = spi_nor_lock; 435 mtd->_unlock = spi_nor_unlock; 436 mtd->_is_locked = spi_nor_is_locked; 437 } 438