Sergii Dmytruk has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/59405 )
Change subject: [RFC] flashchips: add support for OTP to several chip models ......................................................................
[RFC] flashchips: add support for OTP to several chip models
Added configurations matches new chips in dummyflasher.
Change-Id: I98491ed00d1e5fa6682bcdc4d5e132ec76447f21 Signed-off-by: Hatim Kanchwala <hatim at hatimak.me> Signed-off-by: Sergii Dmytruk sergii.dmytruk@3mdeb.com --- M Makefile M flashchips.c M meson.build M otp.h A otp_layouts.c 5 files changed, 227 insertions(+), 27 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/05/59405/1
diff --git a/Makefile b/Makefile index 74acbfc..7e8d0b0 100644 --- a/Makefile +++ b/Makefile @@ -314,7 +314,7 @@ sst28sf040.o 82802ab.o \ sst49lfxxxc.o sst_fwhub.o edi.o flashchips.o spi.o spi25.o spi25_statusreg.o \ spi95.o opaque.o sfdp.o en29lv640b.o at45db.o s25f.o \ - otp.o writeprotect.o writeprotect_ranges.o + otp.o otp_layouts.o writeprotect.o writeprotect_ranges.o
############################################################################### # Library code. diff --git a/flashchips.c b/flashchips.c index b26681d..6bad720 100644 --- a/flashchips.c +++ b/flashchips.c @@ -21,6 +21,7 @@ #include "flash.h" #include "flashchips.h" #include "chipdrivers.h" +#include "otp.h"
/** * List of supported flash chips. @@ -4955,8 +4956,8 @@ .model_id = EON_EN25Q16, .total_size = 2048, .page_size = 256, - /* OTP: D16 512B/Q16 128B total; enter 0x3A */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + /* OTP: D16 512B/Q16 128B total */ + .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -4985,6 +4986,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en128_2048otp, },
{ @@ -4995,8 +4997,7 @@ .model_id = EON_EN25Q32, .total_size = 4096, .page_size = 256, - /* OTP: 512B total; enter 0x3A */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5021,6 +5022,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en512_4096otp, },
{ @@ -5031,8 +5033,7 @@ .model_id = EON_EN25Q40, .total_size = 512, .page_size = 256, - /* OTP: 256B total; enter 0x3A */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5057,6 +5058,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en256_512otp, },
{ @@ -5067,8 +5069,7 @@ .model_id = EON_EN25Q64, .total_size = 8192, .page_size = 256, - /* OTP: 512B total; enter 0x3A */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5093,6 +5094,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en512_8192otp, },
{ @@ -5103,8 +5105,7 @@ .model_id = EON_EN25Q80, .total_size = 1024, .page_size = 256, - /* OTP: 256B total; enter 0x3A */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5129,6 +5130,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en256_1024otp, },
{ @@ -5140,9 +5142,8 @@ .total_size = 16384, .page_size = 256, /* supports SFDP */ - /* OTP: 512B total; enter 0x3A */ /* QPI enable 0x38, disable 0xFF */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5167,6 +5168,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en512_16384otp, },
{ @@ -5178,9 +5180,8 @@ .total_size = 2048, .page_size = 256, /* supports SFDP */ - /* OTP: 512B total; enter 0x3A */ /* QPI enable 0x38, disable 0xFF */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5205,6 +5206,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en512_2048otp, },
{ @@ -5216,9 +5218,8 @@ .total_size = 4096, .page_size = 256, /* supports SFDP */ - /* OTP: 512B total; enter 0x3A */ /* QPI enable 0x38, disable 0xFF */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5243,6 +5244,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en512_4096otp, },
{ @@ -5254,9 +5256,8 @@ .total_size = 8192, .page_size = 256, /* supports SFDP */ - /* OTP: 512B total; enter 0x3A */ /* QPI enable 0x38, disable 0xFF */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -5281,6 +5282,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .otp = &en512_8192otp, },
{ @@ -6588,9 +6590,9 @@ .model_id = GIGADEVICE_GD25Q128, .total_size = 16384, .page_size = 256, - /* OTP: 1536B total; read 0x48; write 0x42, erase 0x44 */ /* QPI: enable 0x38, disable 0xFF */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI | + FEATURE_RDSR2 | FEATURE_WRSR2, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -6619,6 +6621,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, + .otp = &gd512_3_otp, },
{ @@ -7022,8 +7025,7 @@ .model_id = GIGADEVICE_GD25VQ21B, .total_size = 256, .page_size = 256, - /* OTP: 1536B total; read 0x48, write 0x42, erase 0x44 */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -7051,6 +7053,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2300, 3600}, + .otp = &gd512_3_otp, },
{ @@ -7101,8 +7104,8 @@ .model_id = GIGADEVICE_GD25VQ41B, .total_size = 512, .page_size = 256, - /* OTP: 1536B total; read 0x48, write 0x42, erase 0x44 */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_QPI | + FEATURE_RDSR2 | FEATURE_WRSR2, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -7130,6 +7133,7 @@ .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2300, 3600}, + .otp = &gd512_3_otp, },
{ @@ -17684,8 +17688,9 @@ .total_size = 512, .page_size = 256, /* supports SFDP */ - /* OTP: 756B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + /* OTP: read ID 0x4B */ + .feature_bits = FEATURE_WRSR_WREN | FEATURE_RDSR2 | + FEATURE_WRSR_EXT, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -17713,6 +17718,7 @@ .write = spi_chip_write_256, /* Multi I/O supported */ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, + .otp = &gd_w256_3_otp, },
{ diff --git a/meson.build b/meson.build index 7520943..31c12e8 100644 --- a/meson.build +++ b/meson.build @@ -386,6 +386,7 @@ srcs += 'libflashrom.c' srcs += 'opaque.c' srcs += 'otp.c' +srcs += 'otp_layouts.c' srcs += 'print.c' srcs += 'programmer.c' srcs += 'programmer_table.c' diff --git a/otp.h b/otp.h index cd8f7bd..5782f70 100644 --- a/otp.h +++ b/otp.h @@ -60,4 +60,14 @@ } regions[FLASHROM_OTP_MAX_REGIONS + 1]; /* We need one more than maximum */ };
+extern struct otp en128_2048otp; +extern struct otp en256_512otp; +extern struct otp en512_4096otp; +extern struct otp en256_1024otp; +extern struct otp en512_2048otp; +extern struct otp en512_16384otp; +extern struct otp en512_8192otp; +extern struct otp gd_w256_3_otp; +extern struct otp gd512_3_otp; + #endif /* !__OTP_H__ */ diff --git a/otp_layouts.c b/otp_layouts.c new file mode 100644 index 0000000..114ac2d --- /dev/null +++ b/otp_layouts.c @@ -0,0 +1,183 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2016 Hatim Kanchwala hatim@hatimak.me + * Copyright (C) 2021 3mdeb Embedded Systems Consulting + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "otp.h" +#include "spi.h" + +/* + * Eon (OTP mode) + * + * Because OTP region is mapped at the end of address space, structures differ + * based on region and flash sizes. + */ + +/* EN25Q16 */ +struct otp en128_2048otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0x1FF000, + .size = 128, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* EN25Q40 */ +struct otp en256_512otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0x07F000, + .size = 256, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* EN25Q80(A) */ +struct otp en256_1024otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0x0FF000, + .size = 256, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* EN25QH16 */ +struct otp en512_2048otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0x1FF000, + .size = 512, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* EN25Q32(A/B), EN25QH32 */ +struct otp en512_4096otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0x3FF000, + .size = 512, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* EN25Q64, EN25QH64 */ +struct otp en512_8192otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0x7FF000, + .size = 512, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* EN25Q128, EN25QH128 */ +struct otp en512_16384otp = { + .feature_bits = OTP_KIND_MODE | OTP_MODE_CLEAR_BP | OTP_MODE_LOCK_WHILE_IN, + .otp_enter_opcode = JEDEC_ENTER_OTP, + .otp_exit_opcode = JEDEC_WRDI, + .regions = + { + { + .addr = 0xFFF000, + .size = 512, + .status_bit = {STATUS1, 7, OTP}, + }, + }, +}; + +/* + * GigaDevice and Winbond (secure registers) + * + * Sizes and addresses differ, although all regions tend to be of the same size. + */ + +/* W25Q40.V */ +struct otp gd_w256_3_otp = { + .feature_bits = OTP_KIND_REGS, + .regions = + { + { + .addr = 0x001000, + .size = 256, + .status_bit = {STATUS2, 3, OTP}, + }, { + .addr = 0x002000, + .size = 256, + .status_bit = {STATUS2, 4, OTP}, + }, { + .addr = 0x003000, + .size = 256, + .status_bit = {STATUS2, 5, OTP}, + }, + }, +}; + +/* GD25VQ21B, GD25VQ41B, GD25Q128C */ +struct otp gd512_3_otp = { + .feature_bits = OTP_KIND_REGS, + .regions = + { + { + .addr = 0x001000, + .size = 512, + .status_bit = {STATUS2, 3, OTP}, + }, { + .addr = 0x002000, + .size = 512, + .status_bit = {STATUS2, 4, OTP}, + }, { + .addr = 0x003000, + .size = 512, + .status_bit = {STATUS2, 5, OTP}, + }, + }, +};