Showing with 61 additions and 2 deletions.
  1. +6 −1 CHANGELOG.md
  2. +1 −0 include/flash_access.h
  3. +6 −0 include/spi/spi_flash.h
  4. +22 −0 spi/winbond.c
  5. +5 −0 utils/flash_access.c
  6. +21 −1 utils/sec_reg_menu.c
7 changes: 6 additions & 1 deletion CHANGELOG.md
Expand Up @@ -8,6 +8,10 @@ Releases 4.5.x and 4.6.x are based on mainline support submitted in

## [Unreleased]

## [v4.6.9] - 2018-06-08
### Added
- erase security registers content option in hidden menu

## [v4.6.8] - 2018-04-06
### Added
- Support for APU1 target
Expand Down Expand Up @@ -132,7 +136,8 @@ initial commit based on [coreboot_140908](http://pcengines.ch/tmp/coreboot_14090
### Fixed
- used proper way to access extended SPI registers

[Unreleased]: https://github.com/pcengines/sortbootorder/compare/v4.6.8...master
[Unreleased]: https://github.com/pcengines/sortbootorder/compare/v4.6.9...master
[v4.6.9]: https://github.com/pcengines/sortbootorder/compare/v4.6.8...v4.6.9
[v4.6.8]: https://github.com/pcengines/sortbootorder/compare/v4.6.5...v4.6.8
[v4.6.5]: https://github.com/pcengines/sortbootorder/compare/v4.6.4...v4.6.5
[v4.6.4]: https://github.com/pcengines/sortbootorder/compare/v4.6.3...v4.6.4
Expand Down
1 change: 1 addition & 0 deletions include/flash_access.h
Expand Up @@ -31,6 +31,7 @@ int lock_flash(void);
int unlock_flash(void);
int read_sec_status(void);
int read_sec(u8 reg, u8 addr, void *buf, size_t len);
int erase_sec(u8 reg, u8 addr, size_t len);
int prog_sec(u8 reg, u8 addr, const void *buf, size_t len);
int lock_sec(u8 reg);
void save_flash(int flash_address, char buffer[MAX_DEVICES][MAX_LENGTH], u8 max_lines, u8 spi_wp_toggle);
Expand Down
6 changes: 6 additions & 0 deletions include/spi/spi_flash.h
Expand Up @@ -63,6 +63,7 @@ struct spi_flash {
int (*sec_read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
int (*sec_prog)(struct spi_flash *flash, u32 offset, size_t len,
const void *buf);
int (*sec_erase)(struct spi_flash *flash, u32 offset, size_t len);
int (*sec_lock)(struct spi_flash *flash, u8 reg);
};

Expand Down Expand Up @@ -118,6 +119,11 @@ static inline int spi_flash_sec_prog(struct spi_flash *flash, u32 offset, size_t
return flash->sec_prog(flash, offset, len, buf);
}

static inline int spi_flash_sec_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return flash->sec_erase(flash, offset, len);
}

static inline int spi_flash_sec_lock(struct spi_flash *flash, u8 reg)
{
return flash->sec_lock(flash, reg);
Expand Down
22 changes: 22 additions & 0 deletions spi/winbond.c
Expand Up @@ -386,6 +386,27 @@ static int winbond_sec_program(struct spi_flash *flash, u32 offset, size_t len,
return ret;
}

static int winbond_sec_erase(struct spi_flash *flash, u32 offset, size_t len)
{
int ret = 1;
u8 reg = (offset >> 8) & 0xFF;
u32 tmp_sect_size = flash->sector_size;

if (reg != ADDR_W25_SEC1 && reg != ADDR_W25_SEC2 && reg != ADDR_W25_SEC3) {
spi_debug("SF: Wrong security register\n");
return 1;
}

flash->sector_size = 1;
ret = spi_flash_cmd_erase(flash, CMD_W25_ER_SEC, offset & (0xFF << 8), 1);
flash->sector_size = tmp_sect_size;

if (ret)
spi_debug("SF: Can't erase sec reg\n");

return ret;
}

static int winbond_sec_sts(struct spi_flash *flash)
{
u8 status = 0;
Expand Down Expand Up @@ -494,6 +515,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
stm->flash.sec_sts = winbond_sec_sts;
stm->flash.sec_read = winbond_sec_read;
stm->flash.sec_prog = winbond_sec_program;
stm->flash.sec_erase = winbond_sec_erase;
stm->flash.sec_lock = winbond_sec_lock;
#if CONFIG_SPI_FLASH_NO_FAST_READ
stm->flash.read = spi_flash_cmd_read_slow;
Expand Down
5 changes: 5 additions & 0 deletions utils/flash_access.c
Expand Up @@ -63,6 +63,11 @@ inline int read_sec(u8 reg, u8 addr, void *buf, size_t len)
return spi_flash_sec_read(flash_device, sec_addr(reg, addr), len, buf);
}

inline int erase_sec(u8 reg, u8 addr, size_t len)
{
return spi_flash_sec_erase(flash_device, sec_addr(reg, addr), len);
}

inline int prog_sec(u8 reg, u8 addr, const void *buf, size_t len)
{
return spi_flash_sec_prog(flash_device, sec_addr(reg, addr), len, buf);
Expand Down
22 changes: 21 additions & 1 deletion utils/sec_reg_menu.c
Expand Up @@ -30,8 +30,9 @@ static void print_reg_sec_menu(void) {
printf("\n\n--- Security registers menu ---\n\n");
printf(" r - read serial from security register 1\n");
printf(" w serial - write serial to security register 1\n");
printf(" e - erase security registers content\n");
printf(" s - get security registers OTP status\n");
/* printf(" l reg - lock security register reg\n"); */
/* printf(" l reg - lock security register reg\n"); */
printf(" q - exit menu\n");
printf("\n");
}
Expand Down Expand Up @@ -80,6 +81,22 @@ static void cmd_read_sec_sts(void)
printf(" reg 3 = %s\n", (status & 0x4) ? "locked" : "writeable");
}


static void cmd_erase_sec(void)
{
u8 reg = SERIAL_REG_NO;
u8 offset = SERIAL_OFFSET;
int ret;

ret = erase_sec(reg, offset, MAX_SERIAL_LEN);
if (ret) {
printf("can't erase security registers\n");
return;
}

printf("serial erased\n");
}

static void cmd_lock_sec(char *cmd)
{
u8 reg;
Expand Down Expand Up @@ -124,6 +141,9 @@ void handle_reg_sec_menu(void) {
case 'w':
cmd_write_serial(command);
break;
case 'e':
cmd_erase_sec();
break;
case 's':
cmd_read_sec_sts();
break;
Expand Down