From 87d7b110d6ed6d4ef0b61e777f2fee3c10808f0b Mon Sep 17 00:00:00 2001 From: Thomas Heijligen Date: Thu, 14 Apr 2022 13:50:55 +0200 Subject: Introduce an `include` directory for header files Move all header files to the new `include` directory. Adapt include directives and build systems to the new directory. Change-Id: Iaddd6bbfa0624b166d422f665877f096983bf4cf Signed-off-by: Felix Singer Signed-off-by: Thomas Heijligen Reviewed-on: https://review.coreboot.org/c/flashrom/+/58622 Tested-by: build bot (Jenkins) Reviewed-by: Anastasia Klimchuk --- include/chipdrivers.h | 220 ++++++++++ include/coreboot_tables.h | 146 +++++++ include/custom_baud.h | 31 ++ include/edi.h | 30 ++ include/ene.h | 51 +++ include/flash.h | 494 +++++++++++++++++++++ include/flashchips.h | 1033 ++++++++++++++++++++++++++++++++++++++++++++ include/fmap.h | 71 +++ include/hwaccess_physmap.h | 59 +++ include/hwaccess_x86_io.h | 37 ++ include/hwaccess_x86_msr.h | 28 ++ include/i2c_helper.h | 129 ++++++ include/ich_descriptors.h | 595 +++++++++++++++++++++++++ include/layout.h | 69 +++ include/libflashrom.h | 160 +++++++ include/platform.h | 117 +++++ include/platform/pci.h | 25 ++ include/programmer.h | 516 ++++++++++++++++++++++ include/spi.h | 224 ++++++++++ include/usb_device.h | 181 ++++++++ include/writeprotect.h | 89 ++++ 21 files changed, 4305 insertions(+) create mode 100644 include/chipdrivers.h create mode 100644 include/coreboot_tables.h create mode 100644 include/custom_baud.h create mode 100644 include/edi.h create mode 100644 include/ene.h create mode 100644 include/flash.h create mode 100644 include/flashchips.h create mode 100644 include/fmap.h create mode 100644 include/hwaccess_physmap.h create mode 100644 include/hwaccess_x86_io.h create mode 100644 include/hwaccess_x86_msr.h create mode 100644 include/i2c_helper.h create mode 100644 include/ich_descriptors.h create mode 100644 include/layout.h create mode 100644 include/libflashrom.h create mode 100644 include/platform.h create mode 100644 include/platform/pci.h create mode 100644 include/programmer.h create mode 100644 include/spi.h create mode 100644 include/usb_device.h create mode 100644 include/writeprotect.h (limited to 'include') diff --git a/include/chipdrivers.h b/include/chipdrivers.h new file mode 100644 index 00000000..0695993a --- /dev/null +++ b/include/chipdrivers.h @@ -0,0 +1,220 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009 Carl-Daniel Hailfinger + * + * 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; version 2 of the License. + * + * 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. + * + * Header file for flash chip drivers. Included from flash.h. + * As a general rule, every function listed here should take a pointer to + * struct flashctx as first parameter. + */ + +#ifndef __CHIPDRIVERS_H__ +#define __CHIPDRIVERS_H__ 1 + +#include "flash.h" /* for chipaddr and flashctx */ + +/* spi.c */ +int spi_aai_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int spi_chip_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len); + +/* spi25.c */ +int probe_spi_rdid(struct flashctx *flash); +int probe_spi_rdid4(struct flashctx *flash); +int probe_spi_rems(struct flashctx *flash); +int probe_spi_res1(struct flashctx *flash); +int probe_spi_res2(struct flashctx *flash); +int probe_spi_res3(struct flashctx *flash); +int probe_spi_at25f(struct flashctx *flash); +int spi_write_enable(struct flashctx *flash); +int spi_write_disable(struct flashctx *flash); +int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode); +int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int spi_nbyte_read(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); +int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize); +int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize); +int spi_enter_4ba(struct flashctx *flash); +int spi_exit_4ba(struct flashctx *flash); +int spi_set_extended_address(struct flashctx *, uint8_t addr_high); + + +/* spi25_statusreg.c */ +int spi_read_register(const struct flashctx *flash, enum flash_reg reg, uint8_t *value); +int spi_write_register(const struct flashctx *flash, enum flash_reg reg, uint8_t value); +void spi_prettyprint_status_register_bit(uint8_t status, int bit); +int spi_prettyprint_status_register_plain(struct flashctx *flash); +int spi_prettyprint_status_register_default_welwip(struct flashctx *flash); +int spi_prettyprint_status_register_bp1_srwd(struct flashctx *flash); +int spi_prettyprint_status_register_bp2_srwd(struct flashctx *flash); +int spi_prettyprint_status_register_bp3_srwd(struct flashctx *flash); +int spi_prettyprint_status_register_bp4_srwd(struct flashctx *flash); +int spi_prettyprint_status_register_bp2_bpl(struct flashctx *flash); +int spi_prettyprint_status_register_bp2_tb_bpl(struct flashctx *flash); +int spi_disable_blockprotect(struct flashctx *flash); +int spi_disable_blockprotect_bp1_srwd(struct flashctx *flash); +int spi_disable_blockprotect_bp2_srwd(struct flashctx *flash); +int spi_disable_blockprotect_bp3_srwd(struct flashctx *flash); +int spi_disable_blockprotect_bp4_srwd(struct flashctx *flash); +int spi_prettyprint_status_register_amic_a25l032(struct flashctx *flash); +int spi_prettyprint_status_register_at25df(struct flashctx *flash); +int spi_prettyprint_status_register_at25df_sec(struct flashctx *flash); +int spi_prettyprint_status_register_at25f(struct flashctx *flash); +int spi_prettyprint_status_register_at25f512a(struct flashctx *flash); +int spi_prettyprint_status_register_at25f512b(struct flashctx *flash); +int spi_prettyprint_status_register_at25f4096(struct flashctx *flash); +int spi_prettyprint_status_register_at25fs010(struct flashctx *flash); +int spi_prettyprint_status_register_at25fs040(struct flashctx *flash); +int spi_prettyprint_status_register_at26df081a(struct flashctx *flash); +int spi_disable_blockprotect_at2x_global_unprotect(struct flashctx *flash); +int spi_disable_blockprotect_at2x_global_unprotect_sec(struct flashctx *flash); +int spi_disable_blockprotect_at25f(struct flashctx *flash); +int spi_disable_blockprotect_at25f512a(struct flashctx *flash); +int spi_disable_blockprotect_at25f512b(struct flashctx *flash); +int spi_disable_blockprotect_at25fs010(struct flashctx *flash); +int spi_disable_blockprotect_at25fs040(struct flashctx *flash); +int spi_prettyprint_status_register_en25s_wp(struct flashctx *flash); +int spi_prettyprint_status_register_n25q(struct flashctx *flash); +int spi_disable_blockprotect_n25q(struct flashctx *flash); +int spi_prettyprint_status_register_bp2_ep_srwd(struct flashctx *flash); +int spi_disable_blockprotect_bp2_ep_srwd(struct flashctx *flash); +int spi_prettyprint_status_register_sst25(struct flashctx *flash); +int spi_prettyprint_status_register_sst25vf016(struct flashctx *flash); +int spi_prettyprint_status_register_sst25vf040b(struct flashctx *flash); +int spi_disable_blockprotect_sst26_global_unprotect(struct flashctx *flash); + +/* sfdp.c */ +int probe_spi_sfdp(struct flashctx *flash); + +/* opaque.c */ +int probe_opaque(struct flashctx *flash); +int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); +int write_opaque(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); + +/* at45db.c */ +int probe_spi_at45db(struct flashctx *flash); +int spi_prettyprint_status_register_at45db(struct flashctx *flash); +int spi_disable_blockprotect_at45db(struct flashctx *flash); +int spi_read_at45db(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); +int spi_read_at45db_e8(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); +int spi_write_at45db(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int spi_erase_at45db_page(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_erase_at45db_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen); + +/* 82802ab.c */ +uint8_t wait_82802ab(struct flashctx *flash); +int probe_82802ab(struct flashctx *flash); +int erase_block_82802ab(struct flashctx *flash, unsigned int page, unsigned int pagesize); +int write_82802ab(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +void print_status_82802ab(uint8_t status); +int unlock_28f004s5(struct flashctx *flash); +int unlock_lh28f008bjt(struct flashctx *flash); + +/* jedec.c */ +uint8_t oddparity(uint8_t val); +void toggle_ready_jedec(const struct flashctx *flash, chipaddr dst); +void data_polling_jedec(const struct flashctx *flash, chipaddr dst, uint8_t data); +int probe_jedec(struct flashctx *flash); +int probe_jedec_29gl(struct flashctx *flash); +int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int write_jedec_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int pagesize); +int erase_block_jedec(struct flashctx *flash, unsigned int page, unsigned int blocksize); +int erase_chip_block_jedec(struct flashctx *flash, unsigned int page, unsigned int blocksize); + +int unlock_regspace2_uniform_32k(struct flashctx *flash); +int unlock_regspace2_uniform_64k(struct flashctx *flash); +int unlock_regspace2_block_eraser_0(struct flashctx *flash); +int unlock_regspace2_block_eraser_1(struct flashctx *flash); +int printlock_regspace2_uniform_64k(struct flashctx *flash); +int printlock_regspace2_block_eraser_0(struct flashctx *flash); +int printlock_regspace2_block_eraser_1(struct flashctx *flash); + +/* sst28sf040.c */ +int erase_chip_28sf040(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int erase_sector_28sf040(struct flashctx *flash, unsigned int address, unsigned int sector_size); +int write_28sf040(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int unprotect_28sf040(struct flashctx *flash); +int protect_28sf040(struct flashctx *flash); + +/* sst49lfxxxc.c */ +int erase_sector_49lfxxxc(struct flashctx *flash, unsigned int address, unsigned int sector_size); + +/* sst_fwhub.c */ +int printlock_sst_fwhub(struct flashctx *flash); +int unlock_sst_fwhub(struct flashctx *flash); + +/* s25f.c */ +int probe_spi_big_spansion(struct flashctx *flash); +int s25fl_block_erase(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int s25fs_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen); + +/* w39.c */ +int printlock_w39f010(struct flashctx * flash); +int printlock_w39l010(struct flashctx * flash); +int printlock_w39l020(struct flashctx * flash); +int printlock_w39l040(struct flashctx * flash); +int printlock_w39v040a(struct flashctx *flash); +int printlock_w39v040b(struct flashctx *flash); +int printlock_w39v040c(struct flashctx *flash); +int printlock_w39v040fa(struct flashctx *flash); +int printlock_w39v040fb(struct flashctx *flash); +int printlock_w39v040fc(struct flashctx *flash); +int printlock_w39v080a(struct flashctx *flash); +int printlock_w39v080fa(struct flashctx *flash); +int printlock_w39v080fa_dual(struct flashctx *flash); +int printlock_at49f(struct flashctx *flash); + +/* w29ee011.c */ +int probe_w29ee011(struct flashctx *flash); + +/* stm50.c */ +int erase_sector_stm50(struct flashctx *flash, unsigned int block, unsigned int blocksize); + +/* en29lv640b.c */ +int probe_en29lv640b(struct flashctx *flash); +int write_en29lv640b(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); + +/* dummyflasher.c */ +int probe_variable_size(struct flashctx *flash); + +/* edi.c */ +int edi_chip_block_erase(struct flashctx *flash, unsigned int page, unsigned int size); +int edi_chip_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int edi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); +int edi_probe_kb9012(struct flashctx *flash); + +/* spi95.c */ +int probe_spi_st95(struct flashctx *flash); +int spi_block_erase_emulation(struct flashctx *flash, unsigned int addr, unsigned int blocklen); + +/* writeprotect_ranges.c */ +void decode_range_spi25(size_t *start, size_t *len, const struct wp_bits *, size_t chip_len); + +#endif /* !__CHIPDRIVERS_H__ */ diff --git a/include/coreboot_tables.h b/include/coreboot_tables.h new file mode 100644 index 00000000..e1f63a81 --- /dev/null +++ b/include/coreboot_tables.h @@ -0,0 +1,146 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2002 Linux Networx + * (Written by Eric Biederman for Linux Networx) + * Copyright (C) 2005-2007 coresystems GmbH + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef COREBOOT_TABLES_H +#define COREBOOT_TABLES_H + +#include + +/* The coreboot table information is for conveying information + * from the firmware to the loaded OS image. Primarily this + * is expected to be information that cannot be discovered by + * other means, such as querying the hardware directly. + * + * All of the information should be Position Independent Data. + * That is it should be safe to relocated any of the information + * without it's meaning/correctness changing. For table that + * can reasonably be used on multiple architectures the data + * size should be fixed. This should ease the transition between + * 32 bit and 64 bit architectures etc. + * + * The completeness test for the information in this table is: + * - Can all of the hardware be detected? + * - Are the per motherboard constants available? + * - Is there enough to allow a kernel to run that was written before + * a particular motherboard is constructed? (Assuming the kernel + * has drivers for all of the hardware but it does not have + * assumptions on how the hardware is connected together). + * + * With this test it should be straight forward to determine if a + * table entry is required or not. This should remove much of the + * long term compatibility burden as table entries which are + * irrelevant or have been replaced by better alternatives may be + * dropped. Of course it is polite and expedite to include extra + * table entries and be backwards compatible, but it is not required. + */ + +/* Since coreboot is usually compiled 32bit, gcc will align 64bit + * types to 32bit boundaries. If the coreboot table is dumped on a + * 64bit system, a uint64_t would be aligned to 64bit boundaries, + * breaking the table format. + * + * lb_uint64 will keep 64bit coreboot table values aligned to 32bit + * to ensure compatibility. They can be accessed with the two functions + * below: unpack_lb64() and pack_lb64() + * + * See also: util/lbtdump/lbtdump.c + */ + +struct lb_uint64 { + uint32_t lo; + uint32_t hi; +}; + +struct lb_header { + uint8_t signature[4]; /* LBIO */ + uint32_t header_bytes; + uint32_t header_checksum; + uint32_t table_bytes; + uint32_t table_checksum; + uint32_t table_entries; +}; + +/* Every entry in the boot environment list will correspond to a boot + * info record. Encoding both type and size. The type is obviously + * so you can tell what it is. The size allows you to skip that + * boot environment record if you don't know what it easy. This allows + * forward compatibility with records not yet defined. + */ +struct lb_record { + uint32_t tag; /* tag ID */ + uint32_t size; /* size of record (in bytes) */ +}; + +#define LB_TAG_UNUSED 0x0000 + +#define LB_TAG_MEMORY 0x0001 + +struct lb_memory_range { + struct lb_uint64 start; + struct lb_uint64 size; + uint32_t type; +#define LB_MEM_RAM 1 /* Memory anyone can use */ +#define LB_MEM_RESERVED 2 /* Don't use this memory region */ +#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ +}; + +struct lb_memory { + uint32_t tag; + uint32_t size; + struct lb_memory_range map[0]; +}; + +#define LB_TAG_HWRPB 0x0002 +struct lb_hwrpb { + uint32_t tag; + uint32_t size; + uint64_t hwrpb; +}; + +#define LB_TAG_MAINBOARD 0x0003 +struct lb_mainboard { + uint32_t tag; + uint32_t size; + uint8_t vendor_idx; + uint8_t part_number_idx; + uint8_t strings[0]; +}; + +#define LB_TAG_VERSION 0x0004 +#define LB_TAG_EXTRA_VERSION 0x0005 +#define LB_TAG_BUILD 0x0006 +#define LB_TAG_COMPILE_TIME 0x0007 +#define LB_TAG_COMPILE_BY 0x0008 +#define LB_TAG_COMPILE_HOST 0x0009 +#define LB_TAG_COMPILE_DOMAIN 0x000a +#define LB_TAG_COMPILER 0x000b +#define LB_TAG_LINKER 0x000c +#define LB_TAG_ASSEMBLER 0x000d +struct lb_string { + uint32_t tag; + uint32_t size; + uint8_t string[0]; +}; + +#define LB_TAG_FORWARD 0x0011 +struct lb_forward { + uint32_t tag; + uint32_t size; + uint64_t forward; +}; + +#endif /* COREBOOT_TABLES_H */ diff --git a/include/custom_baud.h b/include/custom_baud.h new file mode 100644 index 00000000..c8b8fc29 --- /dev/null +++ b/include/custom_baud.h @@ -0,0 +1,31 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2017 Urja Rannikko + * + * 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. + */ + +#ifndef __CUSTOM_BAUD_H__ +#define __CUSTOM_BAUD_H__ 1 + +struct baudentry { + int flag; + unsigned int baud; +}; + +int set_custom_baudrate(int fd, unsigned int baud); + +/* Returns 1 if non-exact rate would be used, and setting a custom rate is supported. + The baudtable must be in ascending order and terminated with a 0-baud entry. */ +int use_custom_baud(unsigned int baud, const struct baudentry *baudtable); + +#endif diff --git a/include/edi.h b/include/edi.h new file mode 100644 index 00000000..542bf26e --- /dev/null +++ b/include/edi.h @@ -0,0 +1,30 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2015 Paul Kocialkowski + * + * 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. + */ + +#ifndef __EDI_H__ +#define __EDI_H__ 1 + +#define EDI_READ 0x30 +#define EDI_WRITE 0x40 +#define EDI_DISABLE 0xf3 + +#define EDI_NOT_READY 0x5f +#define EDI_READY 0x50 + +#define EDI_READ_BUFFER_LENGTH_DEFAULT 3 +#define EDI_READ_BUFFER_LENGTH_MAX 32 + +#endif diff --git a/include/ene.h b/include/ene.h new file mode 100644 index 00000000..e03e49b2 --- /dev/null +++ b/include/ene.h @@ -0,0 +1,51 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2015 Paul Kocialkowski + * + * 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. + */ + +#ifndef __ENE_H__ +#define __ENE_H__ 1 + +#define ENE_XBI_EFA0 0xfea8 +#define ENE_XBI_EFA1 0xfea9 +#define ENE_XBI_EFA2 0xfeaa +#define ENE_XBI_EFDAT 0xfeab +#define ENE_XBI_EFCMD 0xfeac +#define ENE_XBI_EFCFG 0xfead + +#define ENE_XBI_EFCFG_CMD_WE (1 << 3) +#define ENE_XBI_EFCFG_BUSY (1 << 1) + +#define ENE_XBI_EFCMD_HVPL_LATCH 0x02 +#define ENE_XBI_EFCMD_READ 0x03 +#define ENE_XBI_EFCMD_ERASE 0x20 +#define ENE_XBI_EFCMD_PROGRAM 0x70 +#define ENE_XBI_EFCMD_HVPL_CLEAR 0x80 + +#define ENE_EC_PXCFG 0xff14 + +#define ENE_EC_PXCFG_8051_RESET 0x01 + +#define ENE_EC_HWVERSION 0xff00 +#define ENE_EC_EDIID 0xff24 + +#define ENE_KB9012_HWVERSION 0xc3 +#define ENE_KB9012_EDIID 0x04 + +struct ene_chip { + unsigned char hwversion; + unsigned char ediid; +}; + +#endif diff --git a/include/flash.h b/include/flash.h new file mode 100644 index 00000000..9493fd21 --- /dev/null +++ b/include/flash.h @@ -0,0 +1,494 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2000 Silicon Integrated System Corporation + * Copyright (C) 2000 Ronald G. Minnich + * Copyright (C) 2005-2009 coresystems GmbH + * Copyright (C) 2006-2009 Carl-Daniel Hailfinger + * + * 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. + */ + +#ifndef __FLASH_H__ +#define __FLASH_H__ 1 + +#include +#include +#include +#include +#include +#include +#if IS_WINDOWS +#include +#undef min +#undef max +#endif + +#include "libflashrom.h" +#include "layout.h" +#include "writeprotect.h" + +#define KiB (1024) +#define MiB (1024 * KiB) + +/* Assumes `n` and `a` are at most 64-bit wide (to avoid typeof() operator). */ +#define ALIGN_DOWN(n, a) ((n) & ~((uint64_t)(a) - 1)) + +#define ERROR_PTR ((void*)-1) + +/* Error codes */ +#define ERROR_OOM -100 +#define TIMEOUT_ERROR -101 + +/* TODO: check using code for correct usage of types */ +typedef uintptr_t chipaddr; +#define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2)) + +int register_shutdown(int (*function) (void *data), void *data); +void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len); +void programmer_unmap_flash_region(void *virt_addr, size_t len); +void programmer_delay(unsigned int usecs); + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +enum chipbustype { + BUS_NONE = 0, + BUS_PARALLEL = 1 << 0, + BUS_LPC = 1 << 1, + BUS_FWH = 1 << 2, + BUS_SPI = 1 << 3, + BUS_PROG = 1 << 4, + BUS_NONSPI = BUS_PARALLEL | BUS_LPC | BUS_FWH, +}; + +/* + * The following enum defines possible write granularities of flash chips. These tend to reflect the properties + * of the actual hardware not necesserily the write function(s) defined by the respective struct flashchip. + * The latter might (and should) be more precisely specified, e.g. they might bail out early if their execution + * would result in undefined chip contents. + */ +enum write_granularity { + /* We assume 256 byte granularity by default. */ + write_gran_256bytes = 0,/* If less than 256 bytes are written, the unwritten bytes are undefined. */ + write_gran_1bit, /* Each bit can be cleared individually. */ + write_gran_1byte, /* A byte can be written once. Further writes to an already written byte cause + * its contents to be either undefined or to stay unchanged. */ + write_gran_128bytes, /* If less than 128 bytes are written, the unwritten bytes are undefined. */ + write_gran_264bytes, /* If less than 264 bytes are written, the unwritten bytes are undefined. */ + write_gran_512bytes, /* If less than 512 bytes are written, the unwritten bytes are undefined. */ + write_gran_528bytes, /* If less than 528 bytes are written, the unwritten bytes are undefined. */ + write_gran_1024bytes, /* If less than 1024 bytes are written, the unwritten bytes are undefined. */ + write_gran_1056bytes, /* If less than 1056 bytes are written, the unwritten bytes are undefined. */ + write_gran_1byte_implicit_erase, /* EEPROMs and other chips with implicit erase and 1-byte writes. */ +}; + +/* + * How many different contiguous runs of erase blocks with one size each do + * we have for a given erase function? + */ +#define NUM_ERASEREGIONS 5 + +/* + * How many different erase functions do we have per chip? + * Macronix MX25L25635F has 8 different functions. + */ +#define NUM_ERASEFUNCTIONS 8 + +#define MAX_CHIP_RESTORE_FUNCTIONS 4 + +/* Feature bits used for non-SPI only */ +#define FEATURE_REGISTERMAP (1 << 0) +#define FEATURE_LONG_RESET (0 << 4) +#define FEATURE_SHORT_RESET (1 << 4) +#define FEATURE_EITHER_RESET FEATURE_LONG_RESET +#define FEATURE_RESET_MASK (FEATURE_LONG_RESET | FEATURE_SHORT_RESET) +#define FEATURE_ADDR_FULL (0 << 2) +#define FEATURE_ADDR_MASK (3 << 2) +#define FEATURE_ADDR_2AA (1 << 2) +#define FEATURE_ADDR_AAA (2 << 2) +#define FEATURE_ADDR_SHIFTED (1 << 5) +/* Feature bits used for SPI only */ +#define FEATURE_WRSR_EWSR (1 << 6) +#define FEATURE_WRSR_WREN (1 << 7) +#define FEATURE_WRSR_EITHER (FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN) +#define FEATURE_OTP (1 << 8) +#define FEATURE_QPI (1 << 9) +#define FEATURE_4BA_ENTER (1 << 10) /**< Can enter/exit 4BA mode with instructions 0xb7/0xe9 w/o WREN */ +#define FEATURE_4BA_ENTER_WREN (1 << 11) /**< Can enter/exit 4BA mode with instructions 0xb7/0xe9 after WREN */ +#define FEATURE_4BA_ENTER_EAR7 (1 << 12) /**< Can enter/exit 4BA mode by setting bit7 of the ext addr reg */ +#define FEATURE_4BA_EXT_ADDR (1 << 13) /**< Regular 3-byte operations can be used by writing the most + significant address byte into an extended address register. */ +#define FEATURE_4BA_READ (1 << 14) /**< Native 4BA read instruction (0x13) is supported. */ +#define FEATURE_4BA_FAST_READ (1 << 15) /**< Native 4BA fast read instruction (0x0c) is supported. */ +#define FEATURE_4BA_WRITE (1 << 16) /**< Native 4BA byte program (0x12) is supported. */ +/* 4BA Shorthands */ +#define FEATURE_4BA_NATIVE (FEATURE_4BA_READ | FEATURE_4BA_FAST_READ | FEATURE_4BA_WRITE) +#define FEATURE_4BA (FEATURE_4BA_ENTER | FEATURE_4BA_EXT_ADDR | FEATURE_4BA_NATIVE) +#define FEATURE_4BA_WREN (FEATURE_4BA_ENTER_WREN | FEATURE_4BA_EXT_ADDR | FEATURE_4BA_NATIVE) +#define FEATURE_4BA_EAR7 (FEATURE_4BA_ENTER_EAR7 | FEATURE_4BA_EXT_ADDR | FEATURE_4BA_NATIVE) +/* + * Most flash chips are erased to ones and programmed to zeros. However, some + * other flash chips, such as the ENE KB9012 internal flash, work the opposite way. + */ +#define FEATURE_ERASED_ZERO (1 << 17) +#define FEATURE_NO_ERASE (1 << 18) + +#define FEATURE_WRSR_EXT (1 << 19) +#define FEATURE_WRSR2 (1 << 20) + +#define ERASED_VALUE(flash) (((flash)->chip->feature_bits & FEATURE_ERASED_ZERO) ? 0x00 : 0xff) + +enum test_state { + OK = 0, + NT = 1, /* Not tested */ + BAD, /* Known to not work */ + DEP, /* Support depends on configuration (e.g. Intel flash descriptor) */ + NA, /* Not applicable (e.g. write support on ROM chips) */ +}; + +#define TEST_UNTESTED (struct tested){ .probe = NT, .read = NT, .erase = NT, .write = NT } + +#define TEST_OK_PROBE (struct tested){ .probe = OK, .read = NT, .erase = NT, .write = NT } +#define TEST_OK_PR (struct tested){ .probe = OK, .read = OK, .erase = NT, .write = NT } +#define TEST_OK_PRE (struct tested){ .probe = OK, .read = OK, .erase = OK, .write = NT } +#define TEST_OK_PREW (struct tested){ .probe = OK, .read = OK, .erase = OK, .write = OK } + +#define TEST_BAD_PROBE (struct tested){ .probe = BAD, .read = NT, .erase = NT, .write = NT } +#define TEST_BAD_PR (struct tested){ .probe = BAD, .read = BAD, .erase = NT, .write = NT } +#define TEST_BAD_PRE (struct tested){ .probe = BAD, .read = BAD, .erase = BAD, .write = NT } +#define TEST_BAD_PREW (struct tested){ .probe = BAD, .read = BAD, .erase = BAD, .write = BAD } + +struct flashrom_flashctx; +#define flashctx flashrom_flashctx /* TODO: Agree on a name and convert all occurences. */ +typedef int (erasefunc_t)(struct flashctx *flash, unsigned int addr, unsigned int blocklen); + +enum flash_reg { + INVALID_REG = 0, + STATUS1, + STATUS2, + STATUS3, + MAX_REGISTERS +}; + +struct reg_bit_info { + /* Register containing the bit */ + enum flash_reg reg; + + /* Bit index within register */ + uint8_t bit_index; + + /* + * Writability of the bit. RW does not guarantee the bit will be + * writable, for example if status register protection is enabled. + */ + enum { + RO, /* Read only */ + RW, /* Readable and writable */ + OTP /* One-time programmable */ + } writability; +}; + +struct wp_bits; + +struct flashchip { + const char *vendor; + const char *name; + + enum chipbustype bustype; + + /* + * With 32bit manufacture_id and model_id we can cover IDs up to + * (including) the 4th bank of JEDEC JEP106W Standard Manufacturer's + * Identification code. + */ + uint32_t manufacture_id; + uint32_t model_id; + + /* Total chip size in kilobytes */ + unsigned int total_size; + /* Chip page size in bytes */ + unsigned int page_size; + int feature_bits; + + /* Indicate how well flashrom supports different operations of this flash chip. */ + struct tested { + enum test_state probe; + enum test_state read; + enum test_state erase; + enum test_state write; + } tested; + + /* + * Group chips that have common command sets. This should ensure that + * no chip gets confused by a probing command for a very different class + * of chips. + */ + enum { + /* SPI25 is very common. Keep it at zero so we don't have + to specify it for each and every chip in the database.*/ + SPI25 = 0, + SPI_EDI = 1, + } spi_cmd_set; + + int (*probe) (struct flashctx *flash); + + /* Delay after "enter/exit ID mode" commands in microseconds. + * NB: negative values have special meanings, see TIMING_* below. + */ + signed int probe_timing; + + /* + * Erase blocks and associated erase function. Any chip erase function + * is stored as chip-sized virtual block together with said function. + * The first one that fits will be chosen. There is currently no way to + * influence that behaviour. For testing just comment out the other + * elements or set the function pointer to NULL. + */ + struct block_eraser { + struct eraseblock { + unsigned int size; /* Eraseblock size in bytes */ + unsigned int count; /* Number of contiguous blocks with that size */ + } eraseblocks[NUM_ERASEREGIONS]; + /* a block_erase function should try to erase one block of size + * 'blocklen' at address 'blockaddr' and return 0 on success. */ + int (*block_erase) (struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); + } block_erasers[NUM_ERASEFUNCTIONS]; + + int (*printlock) (struct flashctx *flash); + int (*unlock) (struct flashctx *flash); + int (*write) (struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); + int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); + uint8_t (*read_status) (const struct flashctx *flash); + int (*write_status) (const struct flashctx *flash, int status); + struct voltage { + uint16_t min; + uint16_t max; + } voltage; + enum write_granularity gran; + + /* SPI specific options (TODO: Make it a union in case other bustypes get specific options.) */ + uint8_t wrea_override; /**< override opcode for write extended address register */ + + struct reg_bit_map { + /* Status register protection bit (SRP) */ + struct reg_bit_info srp; + + /* Status register lock bit (SRP) */ + struct reg_bit_info srl; + + /* + * Note: some datasheets refer to configuration bits that + * function like TB/SEC/CMP bits as BP bits (e.g. BP3 for a bit + * that functions like TB). + * + * As a convention, any config bit that functions like a + * TB/SEC/CMP bit should be assigned to the respective + * tb/sec/cmp field in this structure, even if the datasheet + * uses a different name. + */ + + /* Block protection bits (BP) */ + /* Extra element for terminator */ + struct reg_bit_info bp[MAX_BP_BITS + 1]; + + /* Top/bottom protection bit (TB) */ + struct reg_bit_info tb; + + /* Sector/block protection bit (SEC) */ + struct reg_bit_info sec; + + /* Complement bit (CMP) */ + struct reg_bit_info cmp; + + /* Write Protect Selection (per sector protection when set) */ + struct reg_bit_info wps; + } reg_bits; + + /* Function that takes a set of WP config bits (e.g. BP, SEC, TB, etc) */ + /* and determines what protection range they select. */ + void (*decode_range)(size_t *start, size_t *len, const struct wp_bits *, size_t chip_len); +}; + +typedef int (*chip_restore_fn_cb_t)(struct flashctx *flash, uint8_t status); + +struct flashrom_flashctx { + struct flashchip *chip; + /* FIXME: The memory mappings should be saved in a more structured way. */ + /* The physical_* fields store the respective addresses in the physical address space of the CPU. */ + uintptr_t physical_memory; + /* The virtual_* fields store where the respective physical address is mapped into flashrom's address + * space. A value equivalent to (chipaddr)ERROR_PTR indicates an invalid mapping (or none at all). */ + chipaddr virtual_memory; + /* Some flash devices have an additional register space; semantics are like above. */ + uintptr_t physical_registers; + chipaddr virtual_registers; + struct registered_master *mst; + const struct flashrom_layout *layout; + struct flashrom_layout *default_layout; + struct { + bool force; + bool force_boardmismatch; + bool verify_after_write; + bool verify_whole_chip; + } flags; + /* We cache the state of the extended address register (highest byte + * of a 4BA for 3BA instructions) and the state of the 4BA mode here. + * If possible, we enter 4BA mode early. If that fails, we make use + * of the extended address register. + */ + int address_high_byte; + bool in_4ba_mode; + + int chip_restore_fn_count; + struct chip_restore_func_data { + chip_restore_fn_cb_t func; + uint8_t status; + } chip_restore_fn[MAX_CHIP_RESTORE_FUNCTIONS]; +}; + +/* Timing used in probe routines. ZERO is -2 to differentiate between an unset + * field and zero delay. + * + * SPI devices will always have zero delay and ignore this field. + */ +#define TIMING_FIXME -1 +/* this is intentionally same value as fixme */ +#define TIMING_IGNORED -1 +#define TIMING_ZERO -2 + +extern const struct flashchip flashchips[]; +extern const unsigned int flashchips_size; + +void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr); +void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr); +void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr); +void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len); +uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr); +uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr); +uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr); +void chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len); + +/* print.c */ +int print_supported(void); +void print_supported_wiki(void); + +/* helpers.c */ +uint32_t address_to_bits(uint32_t addr); +unsigned int bitcount(unsigned long a); +#undef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#undef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +int max(int a, int b); +int min(int a, int b); +char *strcat_realloc(char *dest, const char *src); +void tolower_string(char *str); +uint8_t reverse_byte(uint8_t x); +void reverse_bytes(uint8_t *dst, const uint8_t *src, size_t length); +#ifdef __MINGW32__ +char* strtok_r(char *str, const char *delim, char **nextp); +char *strndup(const char *str, size_t size); +#endif +#if defined(__DJGPP__) || (!defined(__LIBPAYLOAD__) && !defined(HAVE_STRNLEN)) +size_t strnlen(const char *str, size_t n); +#endif + +/* flashrom.c */ +extern const char flashrom_version[]; +extern const char *chip_to_probe; +char *flashbuses_to_text(enum chipbustype bustype); +int map_flash(struct flashctx *flash); +void unmap_flash(struct flashctx *flash); +int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); +int erase_flash(struct flashctx *flash); +int probe_flash(struct registered_master *mst, int startchip, struct flashctx *fill_flash, int force); +int read_flash_to_file(struct flashctx *flash, const char *filename); +int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len); +int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len, enum write_granularity gran, const uint8_t erased_value); +void emergency_help_message(void); +void print_version(void); +void print_buildinfo(void); +void print_banner(void); +void list_programmers_linebreak(int startcol, int cols, int paren); +int selfcheck(void); +int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename); +int read_buf_from_include_args(const struct flashctx *const flash, unsigned char *buf); +int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename); +int write_buf_to_include_args(const struct flashctx *const flash, unsigned char *buf); +int prepare_flash_access(struct flashctx *, bool read_it, bool write_it, bool erase_it, bool verify_it); +void finalize_flash_access(struct flashctx *); +int register_chip_restore(chip_restore_fn_cb_t func, struct flashctx *flash, uint8_t status); + +/* Something happened that shouldn't happen, but we can go on. */ +#define ERROR_NONFATAL 0x100 + +/* Something happened that shouldn't happen, we'll abort. */ +#define ERROR_FATAL -0xee +#define ERROR_FLASHROM_BUG -200 +/* We reached one of the hardcoded limits of flashrom. This can be fixed by + * increasing the limit of a compile-time allocation or by switching to dynamic + * allocation. + * Note: If this warning is triggered, check first for runaway registrations. + */ +#define ERROR_FLASHROM_LIMIT -201 + +/* cli_common.c */ +void print_chip_support_status(const struct flashchip *chip); + +/* cli_output.c */ +extern enum flashrom_log_level verbose_screen; +extern enum flashrom_log_level verbose_logfile; +int open_logfile(const char * const filename); +int close_logfile(void); +void start_logging(void); +int flashrom_print_cb(enum flashrom_log_level level, const char *fmt, va_list ap); +/* Let gcc and clang check for correct printf-style format strings. */ +int print(enum flashrom_log_level level, const char *fmt, ...) +#ifdef __MINGW32__ +# ifndef __MINGW_PRINTF_FORMAT +# define __MINGW_PRINTF_FORMAT gnu_printf +# endif +__attribute__((format(__MINGW_PRINTF_FORMAT, 2, 3))); +#else +__attribute__((format(printf, 2, 3))); +#endif +#define msg_gerr(...) print(FLASHROM_MSG_ERROR, __VA_ARGS__) /* general errors */ +#define msg_perr(...) print(FLASHROM_MSG_ERROR, __VA_ARGS__) /* programmer errors */ +#define msg_cerr(...) print(FLASHROM_MSG_ERROR, __VA_ARGS__) /* chip errors */ +#define msg_gwarn(...) print(FLASHROM_MSG_WARN, __VA_ARGS__) /* general warnings */ +#define msg_pwarn(...) print(FLASHROM_MSG_WARN, __VA_ARGS__) /* programmer warnings */ +#define msg_cwarn(...) print(FLASHROM_MSG_WARN, __VA_ARGS__) /* chip warnings */ +#define msg_ginfo(...) print(FLASHROM_MSG_INFO, __VA_ARGS__) /* general info */ +#define msg_pinfo(...) print(FLASHROM_MSG_INFO, __VA_ARGS__) /* programmer info */ +#define msg_cinfo(...) print(FLASHROM_MSG_INFO, __VA_ARGS__) /* chip info */ +#define msg_gdbg(...) print(FLASHROM_MSG_DEBUG, __VA_ARGS__) /* general debug */ +#define msg_pdbg(...) print(FLASHROM_MSG_DEBUG, __VA_ARGS__) /* programmer debug */ +#define msg_cdbg(...) print(FLASHROM_MSG_DEBUG, __VA_ARGS__) /* chip debug */ +#define msg_gdbg2(...) print(FLASHROM_MSG_DEBUG2, __VA_ARGS__) /* general debug2 */ +#define msg_pdbg2(...) print(FLASHROM_MSG_DEBUG2, __VA_ARGS__) /* programmer debug2 */ +#define msg_cdbg2(...) print(FLASHROM_MSG_DEBUG2, __VA_ARGS__) /* chip debug2 */ +#define msg_gspew(...) print(FLASHROM_MSG_SPEW, __VA_ARGS__) /* general debug spew */ +#define msg_pspew(...) print(FLASHROM_MSG_SPEW, __VA_ARGS__) /* programmer debug spew */ +#define msg_cspew(...) print(FLASHROM_MSG_SPEW, __VA_ARGS__) /* chip debug spew */ + +/* spi.c */ +struct spi_command { + unsigned int writecnt; + unsigned int readcnt; + const unsigned char *writearr; + unsigned char *readarr; +}; +#define NULL_SPI_CMD { 0, 0, NULL, NULL, } +int spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); +int spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds); + +enum chipbustype get_buses_supported(void); +#endif /* !__FLASH_H__ */ diff --git a/include/flashchips.h b/include/flashchips.h new file mode 100644 index 00000000..ba977199 --- /dev/null +++ b/include/flashchips.h @@ -0,0 +1,1033 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2000 Silicon Integrated System Corporation + * Copyright (C) 2000 Ronald G. Minnich + * Copyright (C) 2005-2007 coresystems GmbH + * Copyright (C) 2006-2009 Carl-Daniel Hailfinger + * + * 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. + */ + +#ifndef __FLASHCHIPS_H__ +#define __FLASHCHIPS_H__ 1 + +/* + * Please keep this list sorted alphabetically by manufacturer. The first + * entry of each section should be the manufacturer ID, followed by the + * list of devices from that manufacturer (sorted by device ID). + * + * Most LPC/FWH parts (parallel flash) have 8-bit device IDs if there is no + * continuation code. + * SPI parts have at least 16-bit device IDs if they support RDID. + */ + +#define GENERIC_MANUF_ID 0xFFFF /* Check if there is a vendor ID */ +#define GENERIC_DEVICE_ID 0xFFFF /* Only match the vendor ID */ +#define SFDP_DEVICE_ID 0xFFFE +#define PROGMANUF_ID 0xFFFE /* dummy ID for opaque chips behind a programmer */ +#define PROGDEV_ID 0x01 /* dummy ID for opaque chips behind a programmer */ + +#define ALLIANCE_ID 0x52 /* Alliance Semiconductor */ +#define ALLIANCE_AS29F002B 0x34 +#define ALLIANCE_AS29F002T 0xB0 +#define ALLIANCE_AS29F010 0x04 +#define ALLIANCE_AS29F040 0xA4 +#define ALLIANCE_AS29F200B 0x57 +#define ALLIANCE_AS29F200T 0x51 +#define ALLIANCE_AS29LV160B 0x49 +#define ALLIANCE_AS29LV160T 0xCA +#define ALLIANCE_AS29LV400B 0xBA +#define ALLIANCE_AS29LV400T 0xB9 +#define ALLIANCE_AS29LV800B 0x5B +#define ALLIANCE_AS29LV800T 0xDA + +#define AMD_ID 0x01 /* AMD */ +#define AMD_AM29DL400BT 0x0C +#define AMD_AM29DL400BB 0x0F +#define AMD_AM29DL800BT 0x4A +#define AMD_AM29DL800BB 0xCB +#define AMD_AM29F002BB 0x34 /* Same as Am29F002NBB */ +#define AMD_AM29F002BT 0xB0 /* Same as Am29F002NBT */ +#define AMD_AM29F004BB 0x7B +#define AMD_AM29F004BT 0x77 +#define AMD_AM29F016D 0xAD +#define AMD_AM29F010 0x20 /* Same as Am29F010A and Am29F010B */ +#define AMD_AM29F040 0xA4 /* Same as AM29F040B */ +#define AMD_AM29F080 0xD5 /* Same as Am29F080B */ +#define AMD_AM29F200BB 0x57 +#define AMD_AM29F200BT 0x51 +#define AMD_AM29F400BB 0xAB +#define AMD_AM29F400BT 0x23 +#define AMD_AM29F800BB 0x58 +#define AMD_AM29F800BT 0xD6 +#define AMD_AM29LV001BB 0x6D +#define AMD_AM29LV001BT 0xED +#define AMD_AM29LV010B 0x6E /* 1Mb, uniform */ +#define AMD_AM29LV002BB 0xC2 +#define AMD_AM29LV002BT 0x40 +#define AMD_AM29LV004BB 0xB6 +#define AMD_AM29LV004BT 0xB5 +#define AMD_AM29LV008BB 0x37 +#define AMD_AM29LV008BT 0x3E +#define AMD_AM29LV040B 0x4F +#define AMD_AM29LV080B 0x38 /* Same as Am29LV081B */ +#define AMD_AM29LV200BB 0xBF +#define AMD_AM29LV200BT 0x3B +#define AMD_AM29LV800BB 0x5B /* Same as Am29LV800DB */ +#define AMD_AM29LV400BT 0xB9 +#define AMD_AM29LV400BB 0xBA +#define AMD_AM29LV800BT 0xDA /* Same as Am29LV800DT */ + +#define AMIC_ID 0x7F37 /* AMIC */ +#define AMIC_ID_NOPREFIX 0x37 /* AMIC */ +#define AMIC_A25L05PT 0x2020 +#define AMIC_A25L05PU 0x2010 +#define AMIC_A25L10PT 0x2021 +#define AMIC_A25L10PU 0x2011 +#define AMIC_A25L20PT 0x2022 +#define AMIC_A25L20PU 0x2012 +#define AMIC_A25L40PT 0x2013 /* Datasheet says T and U have + same device ID. Confirmed by + hardware testing. */ +#define AMIC_A25L40PU 0x2013 +#define AMIC_A25L80P 0x2014 /* Seems that no A25L80PT exists */ +#define AMIC_A25L16PT 0x2025 +#define AMIC_A25L16PU 0x2015 +#define AMIC_A25L512 0x3010 +#define AMIC_A25L010 0x3011 +#define AMIC_A25L020 0x3012 +#define AMIC_A25L040 0x3013 +#define AMIC_A25L080 0x3014 +#define AMIC_A25L016 0x3015 +#define AMIC_A25L032 0x3016 +#define AMIC_A25LQ16 0x4015 +#define AMIC_A25LQ032 0x4016 /* Same as A25LQ32A, but the latter supports SFDP */ +#define AMIC_A25LQ64 0x4017 +#define AMIC_A29002B 0x0d +#define AMIC_A29002T 0x8C /* Same as A290021T */ +#define AMIC_A29040B 0x86 +#define AMIC_A29400T 0xB0 /* Same as 294001T */ +#define AMIC_A29400U 0x31 /* Same as A294001U */ +#define AMIC_A29800T 0x0E +#define AMIC_A29800U 0x8F +#define AMIC_A29L004T 0x34 /* Same as A29L400T */ +#define AMIC_A29L004U 0xB5 /* Same as A29L400U */ +#define AMIC_A29L008T 0x1A /* Same as A29L800T */ +#define AMIC_A29L008U 0x9B /* Same as A29L800U */ +#define AMIC_A29L040 0x92 +#define AMIC_A49LF040A 0x9d + +#define ATMEL_ID 0x1F /* Atmel (now used by Adesto) */ +#define ATMEL_AT25DF021 0x4300 +#define ATMEL_AT25DF021A 0x4301 +#define ATMEL_AT25DF041A 0x4401 +#define ATMEL_AT25DF081 0x4502 /* EDI 0x00. AT25DL081 has same ID + EDI 0x0100 */ +#define ATMEL_AT25DF081A 0x4501 /* Yes, 81A has a lower number than 81 */ +#define ATMEL_AT25DF161 0x4602 +#define ATMEL_AT25DF321 0x4700 /* Same as 26DF321 */ +#define ATMEL_AT25DF321A 0x4701 +#define ATMEL_AT25DF641 0x4800 +#define ATMEL_AT25DL161 0x4603 /* EDI 0x0100 */ +#define ATMEL_AT25DQ161 0x8600 /* EDI 0x0100 */ +#define ATMEL_AT25DQ321 0x8700 /* EDI 0x0100 */ +#define ATMEL_AT25F512 0x60 /* Needs AT25F_RDID. ID from PCN and actual HW. Seems to be a relabeled AT25F1024. */ +#define ATMEL_AT25F512A 0x65 /* Needs AT25F_RDID */ +#define ATMEL_AT25F512B 0x6500 +#define ATMEL_AT25F1024 0x60 /* Needs AT25F_RDID */ +#define ATMEL_AT25F2048 0x63 /* Needs AT25F_RDID */ +#define ATMEL_AT25F4096 0x64 /* Needs AT25F_RDID */ +#define ATMEL_AT25FS010 0x6601 +#define ATMEL_AT25FS040 0x6604 +#define ATMEL_AT25SF041 0x8401 +#define ATMEL_AT25SF081 0x8501 +#define ATMEL_AT25SF161 0x8601 +#define ATMEL_AT25SF321 0x8701 +#define ATMEL_AT25SL128A 0x4218 +#define ATMEL_AT25SF128A 0x8901 /* Adesto AT25SF128A */ +#define ATMEL_AT26DF041 0x4400 +#define ATMEL_AT26DF081 0x4500 /* guessed, no datasheet available */ +#define ATMEL_AT26DF081A 0x4501 +#define ATMEL_AT26DF161 0x4600 +#define ATMEL_AT26DF161A 0x4601 +#define ATMEL_AT26F004 0x0400 +#define ATMEL_AT29LV512 0x3D +#define ATMEL_AT29LV010A 0x35 /* Same as AT29BV010A, the latter works down to 2.7V */ +#define ATMEL_AT29LV020 0xBA +#define ATMEL_AT29BV040A 0xC4 +#define ATMEL_AT29C040A 0xA4 +#define ATMEL_AT29C010A 0xD5 +#define ATMEL_AT29C020 0xDA +#define ATMEL_AT29C512 0x5D +#define ATMEL_AT45BR3214B /* No ID available */ +#define ATMEL_AT45CS1282 0x2920 +#define ATMEL_AT45D011 /* No ID available */ +#define ATMEL_AT45D021A /* No ID available */ +#define ATMEL_AT45D041A /* No ID available */ +#define ATMEL_AT45D081A /* No ID available */ +#define ATMEL_AT45D161 /* No ID available */ +#define ATMEL_AT45DB011 /* No ID (opcode) available for AT45DB011, AT45DB011B */ +#define ATMEL_AT45DB011D 0x2200 +#define ATMEL_AT45DB021 /* No ID (opcode) available for AT45DB021, AT45DB021A, AT45DB021B */ +#define ATMEL_AT45DB021D 0x2300 +#define ATMEL_AT45DB021E /* same as above but with EDI 0x0100 */ +#define ATMEL_AT45DB041 /* No ID (opcode) available for AT45DB041, AT45DB041A, AT45DB041B */ +#define ATMEL_AT45DB041D 0x2400 +#define ATMEL_AT45DB041E /* same as above but with EDI 0x0100 */ +#define ATMEL_AT45DB081 /* No ID (opcode) available for AT45DB081, AT45DB081A, AT45DB081B */ +#define ATMEL_AT45DB081D 0x2500 +#define ATMEL_AT45DB081E /* same as above but with EDI 0x0100 */ +#define ATMEL_AT45DB161 /* No ID (opcode) available for AT45DB161, AT45DB161B */ +#define ATMEL_AT45DB161D 0x2600 +#define ATMEL_AT45DB161E /* same as above but with EDI 0x0100 */ +#define ATMEL_AT45DB321 /* No ID (opcode) available for AT45DB321, AT45DB321B */ +#define ATMEL_AT45DB321C 0x2700 +#define ATMEL_AT45DB321E /* same as above but with EDI 0x0100 */ +#define ATMEL_AT45DB321D 0x2701 /* Buggy data sheet */ +#define ATMEL_AT45DB642 /* No ID (opcode) available for AT45DB642 */ +#define ATMEL_AT45DB642D 0x2800 +#define ATMEL_AT49BV512 0x03 /* Same as AT49F512 */ +#define ATMEL_AT49F001N 0x05 /* Same as AT49F001 */ +#define ATMEL_AT49F001NT 0x04 /* Same as AT49F001T */ +#define ATMEL_AT49F002N 0x07 /* for AT49F002(N) */ +#define ATMEL_AT49LH002 0xE9 +#define ATMEL_AT49LH00B4 0xED +#define ATMEL_AT49LH004 0xEE +#define ATMEL_AT49F002NT 0x08 /* for AT49F002(N)T */ +#define ATMEL_AT49F010 0x17 /* Same as AT49HF010 (some erroneous datasheets say 0x87), AT49BV010, AT49HBV010, AT49HLV010 */ +#define ATMEL_AT49F020 0x0B +#define ATMEL_AT49F040 0x13 +#define ATMEL_AT49F080 0x23 +#define ATMEL_AT49F080T 0x27 + +/* Boya/BoHong Microelectronics Inc. */ +#define BOYA_BOHONG_ID 0x68 +#define BOYA_BOHONG_B_25D16A 0x4015 +#define BOYA_BOHONG_B_25Q128AS 0x4018 + +/* Bright Microelectronics has the same manufacturer ID as Hyundai... */ +#define BRIGHT_ID 0xAD /* Bright Microelectronics */ +#define BRIGHT_BM29F040 0x40 +#define BRIGHT_BM29F400B 0xAB +#define BRIGHT_BM29F400T 0xAD + +#define CATALYST_ID 0x31 /* Catalyst */ +#define CATALYST_CAT28F512 0xB8 + +#define ESMT_ID 0x8C /* Elite Semiconductor Memory Technology (ESMT) / EFST Elite Flash Storage */ +#define ESMT_F25L008A 0x2014 +#define ESMT_F25L32PA 0x2016 +#define ESMT_F25D08QA 0x2534 +#define ESMT_F25L16QA2S 0x4015 +#define ESMT_F25L32QA 0x4016 +#define ESMT_F25L32QA2S 0x4116 +#define ESMT_F25L64QA 0x4117 +#define ESMT_F25L128QA 0x4118 +#define ESMT_F49B002UA 0x00 + +/* + * EN25 chips are SPI, first byte of device ID is memory type, + * second byte of device ID is log(bitsize)-9. + * Vendor and device ID of EN29 series are both prefixed with 0x7F, which + * is the continuation code for IDs in bank 2. + * Vendor ID of EN25 series is NOT prefixed with 0x7F, this results in + * a collision with Mitsubishi. Mitsubishi once manufactured flash chips. + * Let's hope they are not manufacturing SPI flash chips as well. + */ +#define EON_ID 0x7F1C /* EON Silicon Devices */ +#define EON_ID_NOPREFIX 0x1C /* EON, missing 0x7F prefix */ +#define EON_EN25B05 0x2010 /* Same as EN25P05, can be distinguished by RES/REMS: */ +#define EON_EN25P05 0x05 +#define EON_EN25B05T 0x25 +#define EON_EN25B05B 0x95 +#define EON_EN25B10 0x2011 /* Same as EN25P10, can be distinguished by RES/REMS: */ +#define EON_EN25P10 0x10 +#define EON_EN25B10T 0x40 +#define EON_EN25B10B 0x30 +#define EON_EN25B20 0x2012 /* Same as EN25P20, can be distinguished by RES/REMS: */ +#define EON_EN25P20 0x11 +#define EON_EN25B20T 0x41 +#define EON_EN25B20B 0x31 +#define EON_EN25B40 0x2013 /* Same as EN25P40, can be distinguished by RES/REMS: */ +#define EON_EN25P40 0x12 +#define EON_EN25B40T 0x42 +#define EON_EN25B40B 0x32 +#define EON_EN25B80 0x2014 /* Same as EN25P80, can be distinguished by RES/REMS: */ +#define EON_EN25P80 0x13 +#define EON_EN25B80T 0x43 +#define EON_EN25B80B 0x33 +#define EON_EN25B16 0x2015 /* Same as EN25P16, can be distinguished by RES/REMS: */ +#define EON_EN25P16 0x14 +#define EON_EN25B16T 0x44 +#define EON_EN25B16B 0x34 +#define EON_EN25B32 0x2016 /* Same as EN25P32, can be distinguished by RES/REMS: */ +#define EON_EN25P32 0x15 +#define EON_EN25B32T 0x45 +#define EON_EN25B32B 0x35 +#define EON_EN25B64 0x2017 /* Same as EN25P64, can be distinguished by RES/REMS: */ +#define EON_EN25P64 0x16 +#define EON_EN25B64T 0x46 +#define EON_EN25B64B 0x36 +#define EON_EN25F05 0x3110 +#define EON_EN25F10 0x3111 +#define EON_EN25F20 0x3112 +#define EON_EN25F40 0x3113 +#define EON_EN25F80 0x3114 +#define EON_EN25F16 0x3115 +#define EON_EN25F32 0x3116 +#define EON_EN25F64 0x3117 +#define EON_EN25Q40 0x3013 +#define EON_EN25Q80 0x3014 +#define EON_EN25Q16 0x3015 /* Same as EN25D16 */ +#define EON_EN25Q32 0x3016 /* Same as EN25Q32A and EN25Q32B */ +#define EON_EN25Q64 0x3017 +#define EON_EN25Q128 0x3018 +#define EON_EN25QH16 0x7015 +#define EON_EN25QH32 0x7016 +#define EON_EN25QH64 0x7017 +#define EON_EN25QH128 0x7018 +#define EON_EN25QH256 0x7019 +#define EON_EN25S10 0x3811 +#define EON_EN25S20 0x3812 +#define EON_EN25S40 0x3813 +#define EON_EN25S80 0x3814 +#define EON_EN25S16 0x3815 +#define EON_EN25S32 0x3816 +#define EON_EN25S64 0x3817 +#define EON_EN25T80 0x5114 +#define EON_EN25T16 0x5115 +#define EON_EN29F512 0x7F21 +#define EON_EN29F010 0x20 +#define EON_EN29F040A 0x7F04 +#define EON_EN29LV010 0x7F6E +#define EON_EN29LV040 0x4F /* Same as EN29LV040A */ +#define EON_EN29LV640B 0xCB +#define EON_EN29LV640T 0xC9 +#define EON_EN29LV640U 0x7E +#define EON_EN29F002T 0x7F92 /* Same as EN29F002A */ +#define EON_EN29F002B 0x7F97 /* Same as EN29F002AN */ +#define EON_EN29GL064HL 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define EON_EN29GL064T 0x7E1001 /* Same ID as EN29GL064AT */ +#define EON_EN29GL064B 0x7E1000 /* Same ID as EN29GL064AB */ +#define EON_EN29GL128HL 0x7F2101 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define EON_EN29GL256HL 0x7F2201 /* Uniform Sectors, WP protects Top OR Bottom sector */ + +#define EXCEL_ID 0x7F7F7F7F4A /* Excel Semiconductor Inc. (ESI) resides in bank 5 */ +#define EXCEL_ID_NOPREFIX 0x4A /* ESI, missing 0x7F prefix */ +#define EXCEL_ES25P40 0x2013 +#define EXCEL_ES25P80 0x2014 +#define EXCEL_ES25P16 0x2015 + +#define FIDELIX_ID 0xF8 /* Fidelix */ +#define FIDELIX_FM25M16 0x4215 +#define FIDELIX_FM25M32 0x4216 +#define FIDELIX_FM25M64 0x4217 +#define FIDELIX_FM25Q08 0x3214 +#define FIDELIX_FM25Q16 0x3215 /* Same as FM25S16 (which is apparently single I/O only) */ +#define FIDELIX_FM25Q32 0x3216 +#define FIDELIX_FM25Q64 0x3217 + +#define FUDAN_ID 0x7F7F7F7F7F7F7FA1 /* Shanghai Fudan Microelectronics resides in bank 8 */ +#define FUDAN_ID_NOPREFIX 0xA1 /* Fudan, missing 0x7F prefix */ +#define FUDAN_FM25F005 0x3110 +#define FUDAN_FM25F01 0x3111 +#define FUDAN_FM25F02 0x3112 /* Same as FM25F02A */ +#define FUDAN_FM25F04 0x3113 /* Same as FM25F04A */ +#define FUDAN_FM25Q08 0x4014 +#define FUDAN_FM25Q16 0x4015 +#define FUDAN_FM25Q32 0x4016 + +#define FUJITSU_ID 0x04 /* Fujitsu */ +#define FUJITSU_MBM29DL400BC 0x0F +#define FUJITSU_MBM29DL400TC 0x0C +#define FUJITSU_MBM29DL800BA 0xCB +#define FUJITSU_MBM29DL800TA 0x4A +#define FUJITSU_MBM29F002BC 0x34 +#define FUJITSU_MBM29F002TC 0xB0 +#define FUJITSU_MBM29F004BC 0x7B +#define FUJITSU_MBM29F004TC 0x77 +#define FUJITSU_MBM29F040C 0xA4 +#define FUJITSU_MBM29F080A 0xD5 +#define FUJITSU_MBM29F200BC 0x57 +#define FUJITSU_MBM29F200TC 0x51 +#define FUJITSU_MBM29F400BC 0xAB +#define FUJITSU_MBM29F400TC 0x23 +#define FUJITSU_MBM29F800BA 0x58 +#define FUJITSU_MBM29F800TA 0xD6 +#define FUJITSU_MBM29LV002BC 0xC2 +#define FUJITSU_MBM29LV002TC 0x40 +#define FUJITSU_MBM29LV004BC 0xB6 +#define FUJITSU_MBM29LV004TC 0xB5 +#define FUJITSU_MBM29LV008BA 0x37 +#define FUJITSU_MBM29LV008TA 0x3E +#define FUJITSU_MBM29LV080A 0x38 +#define FUJITSU_MBM29LV200BC 0xBF +#define FUJITSU_MBM29LV200TC 0x3B +#define FUJITSU_MBM29LV400BC 0xBA +#define FUJITSU_MBM29LV400TC 0xB9 +#define FUJITSU_MBM29LV800BA 0x5B /* Same as MBM29LV800BE */ +#define FUJITSU_MBM29LV800TA 0xDA /* Same as MBM29LV800TE */ +#define FUJITSU_MBM29LV160BE 0x49 /* 16 b mode 0x2249 */ +#define FUJITSU_MBM29LV160TE 0xC4 /* 16 b mode 0x22C4 */ + +#define GIGADEVICE_ID 0xC8 /* GigaDevice */ +#define GIGADEVICE_GD25T80 0x3114 +#define GIGADEVICE_GD25Q512 0x4010 +#define GIGADEVICE_GD25Q10 0x4011 +#define GIGADEVICE_GD25Q20 0x4012 /* Same as GD25QB */ +#define GIGADEVICE_GD25Q40 0x4013 /* Same as GD25QB */ +#define GIGADEVICE_GD25Q80 0x4014 /* Same as GD25Q80B (which has OTP) */ +#define GIGADEVICE_GD25Q16 0x4015 /* Same as GD25Q16B (which has OTP) */ +#define GIGADEVICE_GD25Q32 0x4016 /* Same as GD25Q32B */ +#define GIGADEVICE_GD25Q64 0x4017 /* Same as GD25Q64B */ +#define GIGADEVICE_GD25Q128 0x4018 /* GD25Q128B and GD25Q128C only, can be distinguished by SFDP */ +#define GIGADEVICE_GD25Q256D 0x4019 +#define GIGADEVICE_GD25VQ21B 0x4212 +#define GIGADEVICE_GD25VQ41B 0x4213 /* Same as GD25VQ40C, can be distinguished by SFDP */ +#define GIGADEVICE_GD25VQ80C 0x4214 +#define GIGADEVICE_GD25VQ16C 0x4215 +#define GIGADEVICE_GD25LQ40 0x6013 +#define GIGADEVICE_GD25LQ80 0x6014 +#define GIGADEVICE_GD25LQ16 0x6015 +#define GIGADEVICE_GD25LQ32 0x6016 +#define GIGADEVICE_GD25LQ64 0x6017 /* Same as GD25LQ64B (which is faster) */ +#define GIGADEVICE_GD25LQ128CD 0x6018 +#define GIGADEVICE_GD25WQ80E 0x6514 +#define GIGADEVICE_GD29GL064CAB 0x7E0601 + +#define HYUNDAI_ID 0xAD /* Hyundai */ +#define HYUNDAI_HY29F400T 0x23 /* Same as HY29F400AT */ +#define HYUNDAI_HY29F800B 0x58 /* Same as HY29F800AB */ +#define HYUNDAI_HY29LV800B 0x5B +#define HYUNDAI_HY29F040A 0xA4 +#define HYUNDAI_HY29F400B 0xAB /* Same as HY29F400AB */ +#define HYUNDAI_HY29F002B 0x34 +#define HYUNDAI_HY29F002T 0xB0 +#define HYUNDAI_HY29LV400T 0xB9 +#define HYUNDAI_HY29LV400B 0xBA +#define HYUNDAI_HY29F080 0xD5 +#define HYUNDAI_HY29F800T 0xD6 /* Same as HY29F800AT */ +#define HYUNDAI_HY29LV800T 0xDA + +#define IMT_ID 0x7F1F /* Integrated Memory Technologies */ +#define IMT_IM29F004B 0xAE +#define IMT_IM29F004T 0xAF + +#define INTEL_ID 0x89 /* Intel */ +#define INTEL_28F320J5 0x14 +#define INTEL_28F640J5 0x15 +#define INTEL_28F320J3 0x16 +#define INTEL_28F640J3 0x17 +#define INTEL_28F128J3 0x18 +#define INTEL_28F256J3 0x1D +#define INTEL_28F400T 0x70 /* 28F400BV/BX/CE/CV-T */ +#define INTEL_28F400B 0x71 /* 28F400BV/BX/CE/CV-B */ +#define INTEL_28F200T 0x74 /* 28F200BL/BV/BX/CV-T */ +#define INTEL_28F200B 0x75 /* 28F200BL/BV/BX/CV-B */ +#define INTEL_28F004T 0x78 /* 28F004B5/BE/BV/BX-T */ +#define INTEL_28F004B 0x79 /* 28F004B5/BE/BV/BX-B */ +#define INTEL_28F002T 0x7C /* 28F002BC/BL/BV/BX-T */ +#define INTEL_28F002B 0x7D /* 28F002BL/BV/BX-B */ +#define INTEL_28F001T 0x94 /* 28F001BN/BX-T */ +#define INTEL_28F001B 0x95 /* 28F001BN/BX-B */ +#define INTEL_28F008T 0x98 /* 28F008BE/BV-T */ +#define INTEL_28F008B 0x99 /* 28F008BE/BV-B */ +#define INTEL_28F800T 0x9C /* 28F800B5/BV/CE/CV-T */ +#define INTEL_28F800B 0x9D /* 28F800B5/BV/CE/CV-B */ +#define INTEL_28F016SV 0xA0 /* 28F016SA/SV */ +#define INTEL_28F008SA 0xA2 +#define INTEL_28F008S3 0xA6 /* 28F008S3/S5/SC */ +#define INTEL_28F004S3 0xA7 /* 28F008S3/S5/SC */ +#define INTEL_28F016XS 0xA8 +#define INTEL_28F016S3 0xAA /* 28F016S3/S5/SC */ +#define INTEL_82802AC 0xAC +#define INTEL_82802AB 0xAD +#define INTEL_28F010 0xB4 +#define INTEL_28F512 0xB8 +#define INTEL_28F256A 0xB9 +#define INTEL_28F020 0xBD +#define INTEL_28F016B3T 0xD0 /* 28F016B3-T */ +#define INTEL_28F016B3B 0xD1 /* 28F016B3-B */ +#define INTEL_28F008B3T 0xD2 /* 28F008B3-T */ +#define INTEL_28F008B3B 0xD3 /* 28F008B3-B */ +#define INTEL_28F004B3T 0xD4 /* 28F004B3-T */ +#define INTEL_28F004B3B 0xD5 /* 28F004B3-B */ +#define INTEL_25F160S33B8 0x8911 /* Same as 25F016S33B8 */ +#define INTEL_25F320S33B8 0x8912 +#define INTEL_25F640S33B8 0x8913 +#define INTEL_25F160S33T8 0x8915 /* Same as 25F016S33T8 */ +#define INTEL_25F320S33T8 0x8916 +#define INTEL_25F640S33T8 0x8917 + +#define SHARP_LH28F008SA 0xA2 /* Sharp chip, Intel Vendor ID */ +#define SHARP_LH28F008SC 0xA6 /* Sharp chip, Intel Vendor ID */ + +#define ISSI_ID 0xD5 /* ISSI Integrated Silicon Solutions, see also PMC. */ +#define ISSI_ID_SPI 0x9D /* ISSI ID used for SPI flash, see also PMC_ID_NOPREFIX */ +#define ISSI_IS25LP064 0x6017 +#define ISSI_IS25LP128 0x6018 +#define ISSI_IS25LP256 0x6019 +#define ISSI_IS25WP032 0x7016 +#define ISSI_IS25WP064 0x7017 +#define ISSI_IS25WP128 0x7018 +#define ISSI_IS25WP256 0x7019 +#define ISSI_PMC_IS29GL032B 0xF9 +#define ISSI_PMC_IS29GL032T 0xF6 +#define ISSI_PMC_IS29GL064B 0x7E1000 +#define ISSI_PMC_IS29GL064T 0x7E1001 +#define ISSI_PMC_IS29GL064HL 0x7E0C01 +#define ISSI_PMC_IS29GL128HL 0x7E2101 +#define ISSI_PMC_IS29GL256HL 0x7E2201 + +#define MACRONIX_ID 0xC2 /* Macronix (MX) */ +/* Mask ROMs */ +#define MACRONIX_MX23L1654 0x0515 +#define MACRONIX_MX23L3254 0x0516 +#define MACRONIX_MX23L6454 0x0517 +#define MACRONIX_MX23L12854 0x0518 +/* MX25 chips are SPI, first byte of device ID is memory type, + * second byte of device ID is log(bitsize)-9. + * Generalplus SPI chips seem to be compatible with Macronix + * and use the same set of IDs. */ +#define MACRONIX_MX25L512 0x2010 /* Same as MX25L512E, MX25V512, MX25V512C */ +#define MACRONIX_MX25L5121E 0x2210 +#define MACRONIX_MX25L1005 0x2011 /* Same as MX25L1005C, MX25L1006E */ +#define MACRONIX_MX25L2005 0x2012 /* Same as MX25L2005C, MX25L2006E */ +#define MACRONIX_MX25L4005 0x2013 /* Same as MX25L4005A, MX25L4005C, MX25L4006E */ +#define MACRONIX_MX25L8005 0x2014 /* Same as MX25V8005, MX25L8006E, MX25L8008E, FIXME: MX25L8073E (4k 0x20) */ +#define MACRONIX_MX25L1605 0x2015 /* MX25L1605 (64k 0x20); MX25L1605A/MX25L1606E/MX25L1608E (4k 0x20, 64k 0x52); MX25L1605D/MX25L1608D/MX25L1673E (4k 0x20) */ +#define MACRONIX_MX25L3205 0x2016 /* MX25L3205, MX25L3205A (64k 0x20); MX25L3205D/MX25L3208D (4k 0x20); MX25L3206E/MX25L3208E (4k 0x20, 64k 0x52); MX25L3233F/MX25L3273E (4k 0x20, 32k 0x52) */ +#define MACRONIX_MX25L6405 0x2017 /* MX25L6405, MX25L6405D (64k 0x20); MX25L6406E/MX25L6408E (4k 0x20); MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E (4k 0x20, 32k 0x52) */ +#define MACRONIX_MX25L12805D 0x2018 /* MX25L12805D (no 32k); MX25L12865E, MX25L12835F, MX25L12845E, MX25L12873F, MX25L12833F (32k 0x52) */ +#define MACRONIX_MX25L25635F 0x2019 /* Same as MX25L25639F, but the latter seems to not support REMS */ +#define MACRONIX_MX25L1635D 0x2415 +#define MACRONIX_MX25L1635E 0x2515 /* MX25L1635{E} */ +#define MACRONIX_MX66L51235F 0x201a /* MX66L51235F, MX25L51245G */ +#define MACRONIX_MX66L1G45G 0x201b /* MX66L1G45G */ +#define MACRONIX_MX25U8032E 0x2534 +#define MACRONIX_MX25U1635E 0x2535 +#define MACRONIX_MX25U3235E 0x2536 /* Same as MX25U6435F */ +#define MACRONIX_MX25U6435E 0x2537 /* Same as MX25U6435F */ +#define MACRONIX_MX25U12835E 0x2538 /* Same as MX25U12835F */ +#define MACRONIX_MX25U25635F 0x2539 +#define MACRONIX_MX25U51245G 0x253a +#define MACRONIX_MX25L3235D 0x5E16 /* MX25L3225D/MX25L3235D/MX25L3237D */ +#define MACRONIX_MX25L6495F 0x9517 + +#define MACRONIX_MX25R3235F 0x2816 +#define MACRONIX_MX25R6435F 0x2817 + +#define MACRONIX_MX29F001B 0x19 +#define MACRONIX_MX29F001T 0x18 +#define MACRONIX_MX29F002B 0x34 /* Same as MX29F002NB; N has reset pin n/c. */ +#define MACRONIX_MX29F002T 0xB0 /* Same as MX29F002NT; N has reset pin n/c. */ +#define MACRONIX_MX29F004B 0x46 +#define MACRONIX_MX29F004T 0x45 +#define MACRONIX_MX29F022B 0x37 /* Same as MX29F022NB */ +#define MACRONIX_MX29F022T 0x36 /* Same as MX29F022NT */ +#define MACRONIX_MX29F040 0xA4 /* Same as MX29F040C */ +#define MACRONIX_MX29F080 0xD5 +#define MACRONIX_MX29F200B 0x57 /* Same as MX29F200CB */ +#define MACRONIX_MX29F200T 0x51 /* Same as MX29F200CT */ +#define MACRONIX_MX29F400B 0xAB /* Same as MX29F400CB */ +#define MACRONIX_MX29F400T 0x23 /* Same as MX29F400CT */ +#define MACRONIX_MX29F800B 0x58 +#define MACRONIX_MX29F800T 0xD6 +#define MACRONIX_MX29GL320EB 0x7E1A00 +#define MACRONIX_MX29GL320ET 0x7E1A01 +#define MACRONIX_MX29GL320EHL 0x7E1D00 +#define MACRONIX_MX29GL640EB 0x7E1000 +#define MACRONIX_MX29GL640ET 0x7E1001 +#define MACRONIX_MX29GL640EHL 0x7E0C01 +#define MACRONIX_MX29GL128F 0x7E2101 /* Same as MX29GL128E */ +#define MACRONIX_MX29GL256F 0x7E2201 /* Same as MX29GL256E */ +#define MACRONIX_MX29GL512F 0x7E2301 +#define MACRONIX_MX68GL1G0F 0x7E2801 +#define MACRONIX_MX29LV002CB 0x5A +#define MACRONIX_MX29LV002CT 0x59 +#define MACRONIX_MX29LV004B 0xB6 /* Same as MX29LV004CB */ +#define MACRONIX_MX29LV004T 0xB5 /* Same as MX29LV004CT */ +#define MACRONIX_MX29LV008B 0x37 /* Same as MX29LV008CB */ +#define MACRONIX_MX29LV008T 0x3E /* Same as MX29LV008CT */ +#define MACRONIX_MX29LV040 0x4F /* Same as MX29LV040C */ +#define MACRONIX_MX29LV081 0x38 +#define MACRONIX_MX29LV128DB 0x7A +#define MACRONIX_MX29LV128DT 0x7E +#define MACRONIX_MX29LV160DB 0x49 /* Same as MX29LV161DB/MX29LV160CB */ +#define MACRONIX_MX29LV160DT 0xC4 /* Same as MX29LV161DT/MX29LV160CT */ +#define MACRONIX_MX29LV320DB 0xA8 /* Same as MX29LV321DB */ +#define MACRONIX_MX29LV320DT 0xA7 /* Same as MX29LV321DT */ +#define MACRONIX_MX29LV400B 0xBA /* Same as MX29LV400CB */ +#define MACRONIX_MX29LV400T 0xB9 /* Same as MX29LV400CT */ +#define MACRONIX_MX29LV640DB 0xCB /* Same as MX29LV640EB */ +#define MACRONIX_MX29LV640DT 0xC9 /* Same as MX29LV640ET */ +#define MACRONIX_MX29LV800B 0x5B /* Same as MX29LV800CB */ +#define MACRONIX_MX29LV800T 0xDA /* Same as MX29LV800CT */ +#define MACRONIX_MX29SL402CB 0xF1 +#define MACRONIX_MX29SL402CT 0x70 +#define MACRONIX_MX29SL800CB 0x6B /* Same as MX29SL802CB */ +#define MACRONIX_MX29SL800CT 0xEA /* Same as MX29SL802CT */ + +/* Nantronics Semiconductors is listed in JEP106AJ in bank 7, so it should have 6 continuation codes in front + * of the manufacturer ID of 0xD5. http://www.nantronicssemi.com */ +#define NANTRONICS_ID 0x7F7F7F7F7F7FD5 /* Nantronics */ +#define NANTRONICS_ID_NOPREFIX 0xD5 /* Nantronics, missing prefix */ +#define NANTRONICS_N25S10 0x3011 +#define NANTRONICS_N25S20 0x3012 +#define NANTRONICS_N25S40 0x3013 +#define NANTRONICS_N25S80 0x3014 +#define NANTRONICS_N25S16 0x3015 + +/* + * Programmable Micro Corp is listed in JEP106W in bank 2, so it should + * have a 0x7F continuation code prefix. + * Apparently PMC was renamed to "Chingis Technology Corporation" http://www.chingistek.com which is now a + * subsidiary of ISSI. They continue to use the PMC manufacturer ID (instead of ISSI's) nevertheless, even for + * new chips with IS* model numbers. + */ +#define PMC_ID 0x7F9D /* PMC */ +#define PMC_ID_NOPREFIX 0x9D /* PMC, missing 0x7F prefix */ +#define PMC_PM25LD256C 0x2F +#define PMC_PM25LD512 0x20 /* Same as Pm25LD512C, but the latter has more locking options. */ +#define PMC_PM25LD010 0x21 /* Same as Pm25LD010C, but the latter has more locking options. */ +#define PMC_PM25LD020 0x22 /* Same as Pm25LD020C, but the latter has more locking options. */ +#define PMC_PM25LQ020 0x42 +#define PMC_PM25LQ040 0x43 +#define PMC_PM25LQ080 0x44 +#define PMC_PM25LQ016 0x45 +#define PMC_PM25LQ032C 0x46 +#define PMC_PM25LV512 0x7B /* Same as Pm25LV512A */ +#define PMC_PM25LV010 0x7C /* Same as Pm25LV010A, but the former does not support RDID but RES3 only. */ +#define PMC_PM25LV020 0x7D +#define PMC_PM25LV040 0x7E /* Same as PM25LD040(C), but the latter supports more features. */ +#define PMC_PM25LV080B 0x13 +#define PMC_PM25LV016B 0x14 +#define PMC_PM29F002T 0x1D +#define PMC_PM29F002B 0x2D +#define PMC_PM39LV512 0x1B /* Same as IS39LV512 */ +#define PMC_PM39F010 0x1C /* Same as Pm39LV010, IS39LV010 */ +#define PMC_PM39LV020 0x3D +#define PMC_PM39LV040 0x3E /* Same as IS39LV040 */ +#define PMC_PM39F020 0x4D +#define PMC_PM39F040 0x4E +#define PMC_PM49FL002 0x6D +#define PMC_PM49FL004 0x6E + +/* + * The Sanyo chip found so far uses SPI, first byte is manufacturer code, + * second byte is the device code, + * third byte is a dummy byte. + */ +#define SANYO_ID 0x62 /* Sanyo */ +#define SANYO_LE25FW203A 0x1600 +#define SANYO_LE25FW403A 0x1100 +#define SANYO_LE25FW106 0x15 +#define SANYO_LE25FW406 0x07 /* RES2 */ +#define SANYO_LE25FW418A 0x10 /* RES2 and some weird 1 byte RDID variant */ +#define SANYO_LE25FW406A 0x1A /* RES2, no datasheet */ +#define SANYO_LE25FU106B 0x1D +#define SANYO_LE25FU206 0x44 +#define SANYO_LE25FU206A 0x0612 +#define SANYO_LE25FU406B 0x1E /* LE25FW418A without HD_READ mode option variant */ +#define SANYO_LE25FU406C 0x0613 /* Also known as LE25U40CMC apparently */ +#define SANYO_LE25FW806 0x26 /* RES2 and some weird 1 byte RDID variant */ +#define SANYO_LE25FW808 0x20 /* RES2 and some weird 1 byte RDID variant */ + +#define SHARP_ID 0xB0 /* Sharp */ +#define SHARP_LH28F008BJ__PT 0xEC +#define SHARP_LH28F008BJ__PB 0xED +#define SHARP_LH28F800BV__BTL 0x4B +#define SHARP_LH28F800BV__BV 0x4D +#define SHARP_LH28F800BV__TV 0x4C +#define SHARP_LHF00L02 0xC9 /* Same as LHF00L06/LHF00L07 */ +#define SHARP_LHF00L04 0xCF /* Same as LHF00L03/LHF00L05 */ + +/* Spansion was previously a joint venture of AMD and Fujitsu. */ +#define SPANSION_ID 0x01 /* Spansion, same ID as AMD */ +/* S25 chips are SPI. The first device ID byte is memory type and + * the second device ID byte is memory capacity. */ +#define SPANSION_S25FL004A 0x0212 +#define SPANSION_S25FL008A 0x0213 +#define SPANSION_S25FL016A 0x0214 +#define SPANSION_S25FL032A 0x0215 /* Same as S25FL032P, but the latter supports EDI and CFI */ +#define SPANSION_S25FL064A 0x0216 /* Same as S25FL064P, but the latter supports EDI and CFI */ +#define SPANSION_S25FL128 0x2018 /* Same ID for various S25FL127S, S25FL128P, S25FL128S and S25FL129P (including dual-die S70FL256P) variants (EDI supported) */ +#define SPANSION_S25FL256 0x0219 +#define SPANSION_S25FL512 0x0220 +#define SPANSION_S25FL204 0x4013 +#define SPANSION_S25FL208 0x4014 +#define SPANSION_S25FL216 0x4015 /* Same as S25FL216K, but the latter supports OTP, 3 status regs, quad I/O, SFDP etc. */ +#define SPANSION_S25FL116K 0x4015 +#define SPANSION_S25FL132K 0x4016 +#define SPANSION_S25FL164K 0x4017 +#define SPANSION_S25FS128S_L 0x20180081 /* Large sectors. */ +#define SPANSION_S25FS128S_S 0x20180181 /* Small sectors. */ +#define SPANSION_S25FS256S_L 0x02190081 /* Large sectors. */ +#define SPANSION_S25FS256S_S 0x02190181 /* Small sectors. */ +#define SPANSION_S25FL128S_UL 0x20180080 /* Uniform Large (128kB) sectors */ +#define SPANSION_S25FL128S_US 0x20180180 /* Uniform Small (64kB) sectors */ +#define SPANSION_S25FL256S_UL 0x02190080 /* Uniform Large (128kB) sectors */ +#define SPANSION_S25FL256S_US 0x02190180 /* Uniform Small (64kB) sectors */ + +/* Spansion 29GL families got a suffix indicating the process technology but share the same 3-Byte IDs. They can + * however be differentiated by CFI byte 45h. Some versions exist which have special top or bottom boot sectors + * and various WP configurations (not heeded in the table below). + * + * Suf. Process Sector Sz Rd Page Wr Page Data Width OTP Sz Min Size Max Size + * A 200 nm 64 kB 8 B 32 B x8/x16 256 B 16Mb/ 2MB 64Mb/ 8MB + * M 230 nm 64 kB 8 B 32 B x8/x16 256 B 32Mb/ 4MB 256Mb/ 32MB + * N* 110 nm 64 kB 16 B 32 B x8/x16 256 B 32Mb/ 4MB 64Mb/ 8MB + * N* 110 nm 128 kB 16 B 32 B x8/x16 256 B 128Mb/16MB 256Mb/ 64MB + * P 90 nm 128 kB 16 B 64 B x8/x16 256 B 128Mb/16MB 2Gb/256MB + * S 65 nm 128 kB 32 B 512 B x8 only 512 B 128Mb/16MB 2Gb/256MB + * + * For the N series there are two subgroups: the 4 and 8MB devices (S29GL032N, S29GL064N) have 64 kB erase + * sectors while the bigger chips got 128 kB sectors. + * Each series includes multiple models varying in speedgrade, boot block configurations etc. + */ +#define SPANSION_S29GL016_1 0xC4 /* Top Boot Sector, WP protects Top 2 sectors */ +#define SPANSION_S29GL016_2 0x49 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +/* Same IDs for S29GL032A, S29GL032M, S29GL032N (variations) */ +#define SPANSION_S29GL032_1289 0x7E1D00 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define SPANSION_S29GL032_3 0x7E1A01 /* Top Boot Sector, WP protects Top 2 sectors */ +#define SPANSION_S29GL032_4 0x7E1A00 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +/* Same IDs for S29GL064A, S29GL064M, S29GL064N, S29GL064S (variations) */ +#define SPANSION_S29GL064_1289 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define SPANSION_S29GL064_3 0x7E1001 /* Top Boot Sector, WP protects Top 2 sectors */ +#define SPANSION_S29GL064_4 0x7E1000 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +#define SPANSION_S29GL064_567 0x7E1301 /* x16 only, Uniform Sectors */ + +#define SPANSION_S29GL128 0x7E2101 /* Same ID for S29GL128M, S29GL128N, S29GL128P, S29GL128S */ +#define SPANSION_S29GL256 0x7E2201 /* Same ID for S29GL256M, S29GL256N, S29GL256P, S29GL256S */ +#define SPANSION_S29GL512 0x7E2301 /* Same ID for S29GL512P, S29GL512S */ +#define SPANSION_S29GL01G 0x7E2801 /* Same ID for S29GL01GP, S29GL01GS */ +#define SPANSION_S70GL02G 0x7E4801 /* Same ID for S70GL02GP, S70GL02GS; based on two S29GL01G dies respectively */ + +/* + * SST25 chips are SPI, first byte of device ID is memory type, second + * byte of device ID is related to log(bitsize) at least for some chips. + */ +#define SST_ID 0xBF /* SST */ +#define SST_SST25LF020_REMS 0x43 /* REMS or RES opcode */ +#define SST_SST25WF512 0x2501 +#define SST_SST25WF010 0x2502 +#define SST_SST25WF020 0x2503 +#define SST_SST25WF040 0x2504 +#define SST_SST25WF080 0x2505 +/* There exist some successors to members of the SST25WF family with alphabetic suffixes. Their datasheets show + * a 4 byte long response w/o a vendor ID. The first byte is 0x62 that is actually Sanyo's and might be due to + * a collaboration in the mid 2000ies between Sanyo and SST. */ +#define SST_SST25WF020A 0x1612 +#define SST_SST25WF040B 0x1613 +#define SST_SST25WF080B 0x1614 +#define SST_SST25VF512_REMS 0x48 /* REMS or RES opcode, same as SST25VF512A */ +#define SST_SST25VF010_REMS 0x49 /* REMS or RES opcode, same as SST25VF010A */ +#define SST_SST25VF020_REMS 0x43 /* REMS or RES opcode, same as SST25LF020A */ +#define SST_SST25VF020B 0x258C +#define SST_SST25VF040_REMS 0x44 /* REMS or RES opcode, same as SST25LF040A */ +#define SST_SST25VF040B 0x258D +#define SST_SST25VF040B_REMS 0x8D /* REMS or RES opcode */ +#define SST_SST25VF080_REMS 0x80 /* REMS or RES opcode, same as SST25LF080A */ +#define SST_SST25VF080B 0x258E +#define SST_SST25VF080B_REMS 0x8E /* REMS or RES opcode */ +#define SST_SST25VF016B 0x2541 +#define SST_SST25VF032B 0x254A +#define SST_SST25VF032B_REMS 0x4A /* REMS or RES opcode */ +#define SST_SST25VF064C 0x254B +#define SST_SST26VF016 0x2601 +#define SST_SST26VF032 0x2602 +#define SST_SST26VF016B 0x2641 +#define SST_SST26VF032B 0x2642 +#define SST_SST26VF064B 0x2643 +#define SST_SST27SF512 0xA4 +#define SST_SST27SF010 0xA5 +#define SST_SST27SF020 0xA6 +#define SST_SST27VF010 0xA9 +#define SST_SST27VF020 0xAA +#define SST_SST28SF040 0x04 +#define SST_SST29LE512 0x3D /* Same as SST29VE512 */ +#define SST_SST29EE512 0x5D +#define SST_SST29EE010 0x07 +#define SST_SST29LE010 0x08 /* Same as SST29VE010 */ +#define SST_SST29EE020A 0x10 /* Same as SST29EE020 */ +#define SST_SST29LE020 0x12 /* Same as SST29VE020 */ +#define SST_SST29SF020 0x24 +#define SST_SST29VF020 0x25 +#define SST_SST29SF040 0x13 +#define SST_SST29VF040 0x14 +#define SST_SST39SF512 0xB4 +#define SST_SST39SF010 0xB5 +#define SST_SST39SF020 0xB6 /* Same as 39SF020A */ +#define SST_SST39SF040 0xB7 +#define SST_SST39VF512 0xD4 +#define SST_SST39VF010 0xD5 +#define SST_SST39VF020 0xD6 /* Same as 39LF020 */ +#define SST_SST39VF040 0xD7 /* Same as 39LF040 */ +#define SST_SST39VF080 0xD8 /* Same as 39LF080/39VF080/39VF088 */ +#define SST_SST45VF512 0x41 /* REMS, read opcode 0xFF */ +#define SST_SST45LF010 0x42 /* REMS, read opcode 0xFF, 'funny' other opcodes */ +#define SST_SST45VF010 0x45 /* REMS, read opcode 0xFF */ +#define SST_SST45VF020 0x43 /* REMS, read opcode 0xFF */ +#define SST_SST49LF040B 0x50 +#define SST_SST49LF040 0x51 +#define SST_SST49LF020 0x61 +#define SST_SST49LF020A 0x52 +#define SST_SST49LF030A 0x1C +#define SST_SST49LF080A 0x5B +#define SST_SST49LF002A 0x57 +#define SST_SST49LF003A 0x1B +#define SST_SST49LF004A 0x60 /* Same as 49LF004B */ +#define SST_SST49LF008A 0x5A +#define SST_SST49LF004C 0x54 +#define SST_SST49LF008C 0x59 +#define SST_SST49LF016C 0x5C +#define SST_SST49LF160C 0x4C + +/* + * ST25P chips are SPI, first byte of device ID is memory type, second + * byte of device ID is related to log(bitsize) at least for some chips. + */ +#define ST_ID 0x20 /* ST / SGS/Thomson / Numonyx / XMC(later acquired by Micron) */ +#define ST_M25P05A 0x2010 +#define ST_M25P05_RES 0x05 +#define ST_M25P10A 0x2011 +#define ST_M25P10_RES 0x10 +#define ST_M25P20 0x2012 +#define ST_M25P20_RES 0x11 +#define ST_M25P40 0x2013 +#define ST_M25P40_RES 0x12 +#define ST_M25P80 0x2014 +#define ST_M25P16 0x2015 +#define ST_M25P32 0x2016 +#define ST_M25P64 0x2017 +#define ST_M25P128 0x2018 +#define ST_M45PE10 0x4011 +#define ST_M45PE20 0x4012 +#define ST_M45PE40 0x4013 +#define ST_M45PE80 0x4014 +#define ST_M45PE16 0x4015 +#define XMC_XM25QH64C 0x4017 +#define XMC_XM25QU64C 0x4117 +#define XMC_XM25QH128C 0x4018 +#define XMC_XM25QU128C 0x4118 +#define XMC_XM25QH256C 0x4019 +#define XMC_XM25QU256C 0x4119 +#define ST_M25PX80 0x7114 +#define ST_M25PX16 0x7115 +#define ST_M25PX32 0x7116 +#define ST_M25PX64 0x7117 +#define ST_M25PE10 0x8011 +#define ST_M25PE20 0x8012 +#define ST_M25PE40 0x8013 +#define ST_M25PE80 0x8014 +#define ST_M25PE16 0x8015 +#define ST_M50FLW040A 0x08 +#define ST_M50FLW040B 0x28 +#define ST_M50FLW080A 0x80 +#define ST_M50FLW080B 0x81 +#define ST_M50FW002 0x29 +#define ST_M50FW040 0x2C +#define ST_M50FW080 0x2D +#define ST_M50FW016 0x2E +#define ST_M50LPW080 0x2F +#define ST_M50LPW116 0x30 +#define ST_M29F002B 0x34 /* Same as M29F002BB */ +#define ST_M29F002T 0xB0 /* Same as M29F002BT/M29F002NT/M29F002BNT */ +#define ST_M29F040B 0xE2 /* Same as M29F040 */ +#define ST_M29F080 0xF1 +#define ST_M29F200BT 0xD3 +#define ST_M29F200BB 0xD4 +#define ST_M29F400BT 0xD5 /* Same as M29F400T */ +#define ST_M29F400BB 0xD6 /* Same as M29F400B */ +#define ST_M29F800DB 0x58 +#define ST_M29F800DT 0xEC +#define ST_M29W010B 0x23 +#define ST_M29W040B 0xE3 +#define ST_M29W512B 0x27 +#define ST_M28W160ECB 0x88CF +#define ST_M28W160ECT 0x88CE +#define ST_M28W320FCB 0x88BB +#define ST_M28W320FCT 0x88BA +#define ST_M28W640HCB 0x8849 +#define ST_M28W640HCT 0x8848 +#define ST_M29DW127G 0x7E2004 +#define ST_M29W128GH 0x7E2101 +#define ST_M29W128GL 0x7E2100 +#define ST_M29W160EB 0x2249 +#define ST_M29W160ET 0x22C4 +#define ST_M29W256GH 0x7E21xx +#define ST_M29W256GL 0x7E21xx +#define ST_M29W320DB 0x88CB +#define ST_M29W320DT 0x88CA +#define ST_M29W400FB 0x00EF +#define ST_M29W400FT 0x00EE +#define ST_M29W512GH 0x7E2301 +#define ST_M29W640FB 0x22FD +#define ST_M29W640FT 0x22ED +#define ST_M29W640GB 0x7E1000 +#define ST_M29W640GH 0x7E0C01 +#define ST_M29W640GL 0x7E0C00 +#define ST_M29W640GT 0x7E1001 +#define ST_M29W800FB 0x225B +#define ST_M29W800FT 0x22D7 +#define ST_M58BW16FB 0x8839 +#define ST_M58BW16FT 0x883A +#define ST_M58BW32FB 0x8837 +#define ST_M58BW32FT 0x8838 +#define ST_M58WR016KB 0x8813 +#define ST_M58WR016KT 0x8812 +#define ST_M58WR032KB 0x8815 +#define ST_M58WR032KT 0x8814 +#define ST_M58WR064KB 0x8811 +#define ST_M58WR064KT 0x8810 + +#define ST_M95M02 0x0012 /* ST M95XXX 2Mbit (256KiB) */ + +#define ST_MT28GU01G___1 0x88B0 +#define ST_MT28GU01G___2 0x88B1 +#define ST_MT28GU256___1 0x8901 +#define ST_MT28GU256___2 0x8904 +#define ST_MT28GU512___1 0x887E +#define ST_MT28GU512___2 0x8881 +#define ST_N25Q016__1E 0xBB15 /* N25Q016, 1.8V, (uniform sectors expected) */ +#define ST_N25Q032__3E 0xBA16 /* N25Q032, 3.0V, (uniform sectors expected) */ +#define ST_N25Q032__1E 0xBB16 /* N25Q032, 1.8V, (uniform sectors expected) */ +#define ST_N25Q064__3E 0xBA17 /* N25Q064, 3.0V, (uniform sectors expected) */ +#define ST_N25Q064__1E 0xBB17 /* N25Q064, 1.8V, (uniform sectors expected) */ +#define ST_N25Q128__3E 0xBA18 /* N25Q128/MT25QL128, 3.0V, (uniform sectors expected) */ +#define ST_N25Q128__1E 0xBB18 /* N25Q128/MT25QU128, 1.8V, (uniform sectors expected) */ +#define ST_N25Q256__3E 0xBA19 /* N25Q256/MT25QL256, 3.0V, (uniform sectors expected) */ +#define ST_N25Q256__1E 0xBB19 /* N25Q256/MT25QU256, 1.8V, (uniform sectors expected) */ +#define ST_N25Q512__3G 0xBA20 /* N25Q512/MT25QL512, 3.0V, (uniform sectors expected) */ +#define ST_N25Q512__1G 0xBB20 /* N25Q512/MT25QU512, 1.8V, (uniform sectors expected) */ +#define ST_N25Q00A__3G 0xBA21 /* N25Q00A/MT25QL01G, 3.0V, (uniform sectors expected) */ +#define ST_N25Q00A__1G 0xBB21 /* N25Q00A/MT25QU01G, 1.8V, (uniform sectors expected) */ +#define ST_MT25QL02G 0xBA22 /* MT25QL02G, 3.0V, (uniform sectors expected) */ +#define ST_MT25QU02G 0xBB22 /* MT25QU02G, 1.8V, (uniform sectors expected) */ +#define ST_NP5Q032 0xDA16 /* Phase-change memory (PCM), 3V */ +#define ST_NP5Q064 0xDA17 /* Phase-change memory (PCM), 3V */ +#define ST_NP5Q128 0xDA18 /* Phase-change memory (PCM), 3V */ + +#define SYNCMOS_MVC_ID 0x40 /* SyncMOS (SM) and Mosel Vitelic Corporation (MVC) */ +#define MVC_V29C51000T 0x00 +#define MVC_V29C51400T 0x13 +#define MVC_V29LC51000 0x20 +#define MVC_V29LC51001 0x60 +#define MVC_V29LC51002 0x82 +#define MVC_V29C51000B 0xA0 +#define MVC_V29C51400B 0xB3 +#define SM_MVC_29C51001T 0x01 /* Identical chips: {F,S,V}29C51001T */ +#define SM_MVC_29C51002T 0x02 /* Identical chips: {F,S,V}29C51002T */ +#define SM_MVC_29C51004T 0x03 /* Identical chips: {F,S,V}29C51004T */ +#define SM_MVC_29C31004T 0x63 /* Identical chips: {S,V}29C31004T */ +#define SM_MVC_29C31004B 0x73 /* Identical chips: {S,V}29C31004B */ +#define SM_MVC_29C51001B 0xA1 /* Identical chips: {F,S,V}29C51001B */ +#define SM_MVC_29C51002B 0xA2 /* Identical chips: {F,S,V}29C51002B */ +#define SM_MVC_29C51004B 0xA3 /* Identical chips: {F,S,V}29C51004B */ + +#define TENX_ID 0x7F7F5E /* Tenx Technologies */ +#define TENX_ID_NOPREFIX 0x5E +#define TENX_ICE25P05 0x01 /* Maybe? */ + +#define TI_ID 0x97 /* Texas Instruments */ +#define TI_OLD_ID 0x01 /* TI chips from last century */ +#define TI_TMS29F002RT 0xB0 +#define TI_TMS29F002RB 0x34 + +/* + * W25X chips are SPI, first byte of device ID is memory type, second + * byte of device ID is related to log(bitsize). + */ +#define WINBOND_NEX_ID 0xEF /* Winbond (ex Nexcom) serial flashes */ +#define WINBOND_NEX_W25P80 0x2014 +#define WINBOND_NEX_W25P16 0x2015 +#define WINBOND_NEX_W25P32 0x2016 +#define WINBOND_NEX_W25X05 0x3010 /* W25X05CL */ +#define WINBOND_NEX_W25X10 0x3011 +#define WINBOND_NEX_W25X20 0x3012 +#define WINBOND_NEX_W25X40 0x3013 +#define WINBOND_NEX_W25X80 0x3014 +#define WINBOND_NEX_W25X16 0x3015 +#define WINBOND_NEX_W25X32 0x3016 +#define WINBOND_NEX_W25X64 0x3017 +#define WINBOND_NEX_W25Q40_V 0x4013 /* W25Q40BV; W25Q40BL (2.3-3.6V) */ +#define WINBOND_NEX_W25Q80_V 0x4014 /* W25Q80BV */ +#define WINBOND_NEX_W25Q16_V 0x4015 /* W25Q16CV; W25Q16DV */ +#define WINBOND_NEX_W25Q32_V 0x4016 /* W25Q32BV; W25Q32FV in SPI mode (default) */ +#define WINBOND_NEX_W25Q64_V 0x4017 /* W25Q64BV, W25Q64CV; W25Q64FV in SPI mode (default) */ +#define WINBOND_NEX_W25Q128_V 0x4018 /* W25Q128BV; W25Q128FV in SPI mode (default) */ +#define WINBOND_NEX_W25Q256_V 0x4019 /* W25Q256FV or W25Q256JV_Q (QE=1) */ +#define WINBOND_NEX_W25Q512JV 0x4020 /* W25Q512JV */ +#define WINBOND_NEX_W25Q20_W 0x5012 /* W25Q20BW */ +#define WINBOND_NEX_W25Q40BW 0x5013 /* W25Q40BW */ +#define WINBOND_NEX_W25Q80BW 0x5014 /* W25Q80BW */ +#define WINBOND_NEX_W25Q40EW 0x6013 /* W25Q40EW */ +#define WINBOND_NEX_W25Q80EW 0x6014 /* W25Q80EW */ +#define WINBOND_NEX_W25Q16_W 0x6015 /* W25Q16DW */ +#define WINBOND_NEX_W25Q32_W 0x6016 /* W25Q32DW; W25Q32FV in QPI mode */ +#define WINBOND_NEX_W25Q64_W 0x6017 /* W25Q64DW; W25Q64FV in QPI mode */ +#define WINBOND_NEX_W25Q128_W 0x6018 /* W25Q128FW; W25Q128FV in QPI mode */ +#define WINBOND_NEX_W25Q256_W 0x6019 /* W25Q256JW */ +#define WINBOND_NEX_W25Q64JV 0x7017 /* W25Q64JV */ +#define WINBOND_NEX_W25Q128_V_M 0x7018 /* W25Q128JVSM */ +#define WINBOND_NEX_W25Q256JV_M 0x7019 /* W25Q256JV_M (QE=0) */ +#define WINBOND_NEX_W25Q32JW_M 0x8016 /* W25Q32JW...M */ +#define WINBOND_NEX_W25Q64JW_M 0x8017 /* W25Q64JW...M */ +#define WINBOND_NEX_W25Q128_DTR 0x8018 /* W25Q128JW_DTR */ +#define WINBOND_NEX_W25Q256_DTR 0x8019 /* W25Q256JW_DTR aka W25Q256256JW-IM */ + +#define WINBOND_ID 0xDA /* Winbond */ +#define WINBOND_W19B160BB 0x49 +#define WINBOND_W19B160BT 0xC4 +#define WINBOND_W19B320SB 0x2A /* Same as W19L320SB */ +#define WINBOND_W19B320ST 0xBA /* Same as W19L320ST */ +#define WINBOND_W19B322MB 0x92 +#define WINBOND_W19B322MT 0x10 +#define WINBOND_W19B323MB 0x94 +#define WINBOND_W19B323MT 0x13 +#define WINBOND_W19B324MB 0x97 +#define WINBOND_W19B324MT 0x16 +#define WINBOND_W29C010 0xC1 /* Same as W29C010M, W29C011A, W29EE011, W29EE012, and ASD AE29F1008 */ +#define WINBOND_W29C020 0x45 /* Same as W29C020C, W29C022 and ASD AE29F2008 */ +#define WINBOND_W29C040 0x46 /* Same as W29C040P */ +#define WINBOND_W29C512A 0xC8 /* Same as W29EE512 */ +#define WINBOND_W29GL032CHL 0x7E1D01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W29GL032CB 0x7E1A00 /* Top Boot Sector, WP protects Top 2 sectors */ +#define WINBOND_W29GL032CT 0x7E1A01 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +#define WINBOND_W29GL064CHL 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W29GL064CB 0x7E1000 /* Top Boot Sector, WP protects Top 2 sectors */ +#define WINBOND_W29GL064CT 0x7E1001 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +#define WINBOND_W29GL128CHL 0x7E2101 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W29GL256HL 0x7E2201 /* Same ID for W29GL0256P and W29GL0256S; uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W39F010 0xA1 +#define WINBOND_W39L010 0x31 +#define WINBOND_W39L020 0xB5 +#define WINBOND_W39L040 0xB6 +#define WINBOND_W39L040A 0xD6 +#define WINBOND_W39L512 0x38 +#define WINBOND_W39V040A 0x3D +#define WINBOND_W39V040FA 0x34 +#define WINBOND_W39V040B 0x54 /* Same as W39V040FB */ +#define WINBOND_W39V040C 0x50 /* Same as W39V040FC */ +#define WINBOND_W39V080A 0xD0 +#define WINBOND_W39V080FA 0xD3 +#define WINBOND_W39V080FA_DM 0x93 /* W39V080FA dual mode */ +#define WINBOND_W49F002 0x25 /* Same as W49F002B */ +#define WINBOND_W49F002U 0x0B /* Same as W49F002N and ASD AE49F2008 */ +#define WINBOND_W49F020 0x8C +#define WINBOND_W49V002A 0xB0 +#define WINBOND_W49V002FA 0x32 + +#define ZETTADEVICE_ID 0xBA /* Zetta Device */ +#define ZETTADEVICE_ZD25D20 0x2012 +#define ZETTADEVICE_ZD25D40 0x2013 + +#endif /* !FLASHCHIPS_H */ diff --git a/include/fmap.h b/include/fmap.h new file mode 100644 index 00000000..924e11f6 --- /dev/null +++ b/include/fmap.h @@ -0,0 +1,71 @@ +/* + * Copyright 2010, Google LLC. + * Copyright 2018-present, Facebook Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#ifndef __FMAP_H__ +#define __FMAP_H__ 1 + +#include +#include + +#define FMAP_SIGNATURE "__FMAP__" +#define FMAP_VER_MAJOR 1 /* this header's FMAP minor version */ +#define FMAP_VER_MINOR 1 /* this header's FMAP minor version */ +#define FMAP_STRLEN 32 /* maximum length for strings */ + +struct fmap_area { + uint32_t offset; /* offset relative to base */ + uint32_t size; /* size in bytes */ + uint8_t name[FMAP_STRLEN]; /* descriptive name */ + uint16_t flags; /* flags for this area */ +} __attribute__((packed)); + +struct fmap { + uint8_t signature[8]; /* "__FMAP__" */ + uint8_t ver_major; /* major version */ + uint8_t ver_minor; /* minor version */ + uint64_t base; /* address of the firmware binary */ + uint32_t size; /* size of firmware binary in bytes */ + uint8_t name[FMAP_STRLEN]; /* name of this firmware binary */ + uint16_t nareas; /* number of areas described by + fmap_areas[] below */ + struct fmap_area areas[]; +} __attribute__((packed)); + +int fmap_read_from_buffer(struct fmap **fmap_out, const uint8_t *buf, size_t len); +int fmap_read_from_rom(struct fmap **fmap_out, struct flashctx *const flashctx, size_t rom_offset, size_t len); + + +#endif /* __FMAP_H__*/ diff --git a/include/hwaccess_physmap.h b/include/hwaccess_physmap.h new file mode 100644 index 00000000..a0a7e74d --- /dev/null +++ b/include/hwaccess_physmap.h @@ -0,0 +1,59 @@ +/* + * This file is part of the flashrom project. + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef __HWACCESS_PHYSMAP_H__ +#define __HWACCESS_PHYSMAP_H__ + +#include +#include + +void *physmap(const char *descr, uintptr_t phys_addr, size_t len); +void *rphysmap(const char *descr, uintptr_t phys_addr, size_t len); +void *physmap_ro(const char *descr, uintptr_t phys_addr, size_t len); +void *physmap_ro_unaligned(const char *descr, uintptr_t phys_addr, size_t len); +void physunmap(void *virt_addr, size_t len); +void physunmap_unaligned(void *virt_addr, size_t len); + +void mmio_writeb(uint8_t val, void *addr); +void mmio_writew(uint16_t val, void *addr); +void mmio_writel(uint32_t val, void *addr); +uint8_t mmio_readb(const void *addr); +uint16_t mmio_readw(const void *addr); +uint32_t mmio_readl(const void *addr); +void mmio_readn(const void *addr, uint8_t *buf, size_t len); +void mmio_le_writeb(uint8_t val, void *addr); +void mmio_le_writew(uint16_t val, void *addr); +void mmio_le_writel(uint32_t val, void *addr); +uint8_t mmio_le_readb(const void *addr); +uint16_t mmio_le_readw(const void *addr); +uint32_t mmio_le_readl(const void *addr); +#define pci_mmio_writeb mmio_le_writeb +#define pci_mmio_writew mmio_le_writew +#define pci_mmio_writel mmio_le_writel +#define pci_mmio_readb mmio_le_readb +#define pci_mmio_readw mmio_le_readw +#define pci_mmio_readl mmio_le_readl +void rmmio_writeb(uint8_t val, void *addr); +void rmmio_writew(uint16_t val, void *addr); +void rmmio_writel(uint32_t val, void *addr); +void rmmio_le_writeb(uint8_t val, void *addr); +void rmmio_le_writew(uint16_t val, void *addr); +void rmmio_le_writel(uint32_t val, void *addr); +#define pci_rmmio_writeb rmmio_le_writeb +#define pci_rmmio_writew rmmio_le_writew +#define pci_rmmio_writel rmmio_le_writel +void rmmio_valb(void *addr); +void rmmio_valw(void *addr); +void rmmio_vall(void *addr); + +#endif /* __HWACCESS_PHYSMAP_H__ */ \ No newline at end of file diff --git a/include/hwaccess_x86_io.h b/include/hwaccess_x86_io.h new file mode 100644 index 00000000..31d1e86c --- /dev/null +++ b/include/hwaccess_x86_io.h @@ -0,0 +1,37 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009 Carl-Daniel Hailfinger + * Copyright (C) 2022 secunet Security Networks AG + * (Written by Thomas Heijligen +/** + */ +int rget_io_perms(void); + +void OUTB(uint8_t value, uint16_t port); +void OUTW(uint16_t value, uint16_t port); +void OUTL(uint32_t value, uint16_t port); +uint8_t INB(uint16_t port); +uint16_t INW(uint16_t port); +uint32_t INL(uint16_t port); + +#endif /* __HWACCESS_X86_IO_H__ */ diff --git a/include/hwaccess_x86_msr.h b/include/hwaccess_x86_msr.h new file mode 100644 index 00000000..eda007e8 --- /dev/null +++ b/include/hwaccess_x86_msr.h @@ -0,0 +1,28 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009 Carl-Daniel Hailfinger + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef __HWACCESS_X86_MSR_H__ +#define __HWACCESS_X86_MSR_H__ 1 + +#include + +typedef struct { uint32_t hi, lo; } msr_t; + +msr_t msr_read(int addr); +int msr_write(int addr, msr_t msr); +int msr_setup(int cpu); +void msr_cleanup(void); + +#endif /* __HWACCESS_X86_MSR_H__ */ \ No newline at end of file diff --git a/include/i2c_helper.h b/include/i2c_helper.h new file mode 100644 index 00000000..709a748d --- /dev/null +++ b/include/i2c_helper.h @@ -0,0 +1,129 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2020 The Chromium OS Authors + * + * 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. + */ + +#ifndef I2C_HELPER_H +#define I2C_HELPER_H + +#include + +/** + * An convinent structure that contains the buffer size and the buffer + * pointer. Used to wrap buffer details while doing the I2C data + * transfer on both input and output. It is the client's responsibility + * to use i2c_buffer_t_fill to initialize this struct instead of + * trying to construct it directly. + */ +typedef struct { + void *buf; + uint16_t len; +} i2c_buffer_t; + +/** + * i2c_buffer_t_fill - fills in the i2c_buffer_t + * + * @i2c_buf: pointer to the be constructed. + * @buf: buffer contains data to be included in i2c_buffer_t. + * @len: length of buffer to be included in i2c_buffer_t. + * + * This function takes in a pointer to an initialized i2c_buffer_t + * object with related information, and fill in the i2c_buffer_t with + * some validation applied. The function does allow initialization with + * NULL buffer but will make sure len == 0 in such case. + * + * returns 0 on success, <0 to indicate failure + */ +static inline int i2c_buffer_t_fill(i2c_buffer_t *i2c_buf, void *buf, uint16_t len) +{ + if (!i2c_buf || (!buf && len)) + return -1; + + i2c_buf->buf = buf; + i2c_buf->len = len; + + return 0; +} + +/** + * i2c_open - opens the target I2C device and set the I2C slave address + * + * @bus: I2C bus number of the target device. + * @addr: I2C slave address. + * @force: whether to force set the I2C slave address. + * + * This function returns a file descriptor for the target device. It is + * the client's responsibility to pass the return value to i2c_close to + * clean up. + * + * returns fd of target device on success, <0 to indicate failure + */ +int i2c_open(int bus, uint16_t addr, int force); + +/** + * i2c_open_path: open an I2C device by device path + * + * This function behaves the same as i2c_open, but takes a filesystem + * path (assumed to be an I2C device file) instead of a bus number. + */ +int i2c_open_path(const char *path, uint16_t addr, int force); + +/** + * i2c_open_from_programmer_params: open an I2C device from programmer params + * + * This function is a wrapper for i2c_open and i2c_open_path that obtains the + * I2C device to use from programmer parameters. It is meant to be called + * from I2C-based programmers to avoid repeating parameter parsing code. + */ +int i2c_open_from_programmer_params(uint16_t addr, int force); + +/** + * i2c_close - closes the file descriptor returned by i2c_open + * + * @fd: file descriptor to be closed. + * + * It is the client's responsibility to set fd = -1 when it is + * done with it. + * + * returns 0 on success, <0 to indicate failure + */ +int i2c_close(int fd); + +/** + * i2c_read - reads data from the I2C device + * + * @fd: file descriptor of the target device. + * @addr: I2C slave address of the target device. + * @buf_read: data struct includes reading buffer and size. + * + * This function does accept empty read and do nothing on such case. + * + * returns read length on success, <0 to indicate failure + */ +int i2c_read(int fd, uint16_t addr, i2c_buffer_t *buf_read); + +/** + * i2c_write - writes command/data into the I2C device + * + * @fd: file descriptor of the target device. + * @addr: I2C slave address of the target device. + * @buf_write: data struct includes writting buffer and size. + * + * This function does accept empty write and do nothing on such case. + * + * returns wrote length on success, <0 to indicate failure. + */ +int i2c_write(int fd, uint16_t addr, const i2c_buffer_t *buf_write); + +#endif /* !I2C_HELPER_H */ diff --git a/include/ich_descriptors.h b/include/ich_descriptors.h new file mode 100644 index 00000000..cd5a45cb --- /dev/null +++ b/include/ich_descriptors.h @@ -0,0 +1,595 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (c) 2010 Matthias Wenzel + * Copyright (c) 2011 Stefan Tauner + * + * 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. + */ + +#ifndef __ICH_DESCRIPTORS_H__ +#define __ICH_DESCRIPTORS_H__ 1 + +#include +#include +#include "programmer.h" /* for enum ich_chipset */ + +/* FIXME: Replace with generic return codes */ +#define ICH_RET_OK 0 +#define ICH_RET_ERR -1 +#define ICH_RET_WARN -2 +#define ICH_RET_PARAM -3 +#define ICH_RET_OOB -4 + +#define ICH9_REG_FDOC 0xB0 /* 32 Bits Flash Descriptor Observability Control */ +#define PCH100_REG_FDOC 0xB4 /* New offset from Sunrise Point on */ + /* 0-1: reserved */ +#define FDOC_FDSI_OFF 2 /* 2-11: Flash Descriptor Section Index */ +#define FDOC_FDSI (0x3f << FDOC_FDSI_OFF) +#define FDOC_FDSS_OFF 12 /* 12-14: Flash Descriptor Section Select */ +#define FDOC_FDSS (0x3 << FDOC_FDSS_OFF) + /* 15-31: reserved */ + +#define ICH9_REG_FDOD 0xB4 /* 32 Bits Flash Descriptor Observability Data */ +#define PCH100_REG_FDOD 0xB8 /* New offset from Sunrise Point on */ + +/* Field locations and semantics for LVSCC, UVSCC and related words in the flash + * descriptor are equal therefore they all share the same macros below. */ +#define VSCC_BES_OFF 0 /* 0-1: Block/Sector Erase Size */ +#define VSCC_BES (0x3 << VSCC_BES_OFF) +#define VSCC_WG_OFF 2 /* 2: Write Granularity */ +#define VSCC_WG (0x1 << VSCC_WG_OFF) +#define VSCC_WSR_OFF 3 /* 3: Write Status Required */ +#define VSCC_WSR (0x1 << VSCC_WSR_OFF) +#define VSCC_WEWS_OFF 4 /* 4: Write Enable on Write Status */ +#define VSCC_WEWS (0x1 << VSCC_WEWS_OFF) + /* 5-7: reserved */ +#define VSCC_EO_OFF 8 /* 8-15: Erase Opcode */ +#define VSCC_EO (0xff << VSCC_EO_OFF) + /* 16-22: reserved */ +#define VSCC_VCL_OFF 23 /* 23: Vendor Component Lock */ +#define VSCC_VCL (0x1 << VSCC_VCL_OFF) + /* 24-31: reserved */ + +#define ICH_FREG_BASE(flreg) (((flreg) << 12) & 0x07fff000) +#define ICH_FREG_LIMIT(flreg) ((((flreg) >> 4) & 0x07fff000) | 0x00000fff) + +void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl); + +struct ich_desc_content { + uint32_t FLVALSIG; /* 0x00 */ + union { /* 0x04 */ + uint32_t FLMAP0; + struct { + uint32_t FCBA :8, /* Flash Component Base Address */ + NC :2, /* Number Of Components */ + :6, + FRBA :8, /* Flash Region Base Address */ + NR :3, /* Number Of Regions (reserved from Skylake on) */ + :5; + }; + }; + union { /* 0x08 */ + uint32_t FLMAP1; + struct { + uint32_t FMBA :8, /* Flash Master Base Address */ + NM :3, /* Number Of Masters */ + :5, + FISBA :8, /* Flash ICH Strap Base Address */ + ISL :8; /* ICH Strap Length */ + }; + }; + union { /* 0x0c */ + uint32_t FLMAP2; + struct { + uint32_t FMSBA :8, /* Flash (G)MCH Strap Base Addr. */ + MSL :8, /* MCH Strap Length */ + ICCRIBA :8, /* ICC Reg. Init Base Addr. (new since Sandy Bridge) */ + RIL :8; /* Register Init Length (new since Hawell) */ + }; + struct { /* new since Tiger Point */ + uint32_t :2, + CSSO :10, /* CPU Soft Strap Offset from PMC Base */ + :4, + CSSL :8, /* CPU Soft Strap Length */ + :8; + }; + }; +}; + +struct ich_desc_component { + union { /* 0x00 */ + uint32_t FLCOMP; /* Flash Components Register */ + /* FLCOMP encoding on various generations: + * + * Chipset/Generation max_speed dual_output density + * [MHz] bits max. bits + * ICH8: 33 N/A 5 0:2, 3:5 + * ICH9: 33 N/A 5 0:2, 3:5 + * ICH10: 33 N/A 5 0:2, 3:5 + * Ibex Peak/5: 50 N/A 5 0:2, 3:5 + * Cougar Point/6: 50 30 5 0:2, 3:5 + * Patsburg: 50 30 5 0:2, 3:5 + * Panther Point/7 50 30 5 0:2, 3:5 + * Lynx Point/8: 50 30 7 0:3, 4:7 + * Wildcat Point/9: 50 30 (multi I/O) 7 0:3, 4:7 + * Sunrise Point/100: 48 30 7 0:3, 4:7 + */ + struct { + uint32_t :17, + freq_read :3, + fastread :1, + freq_fastread :3, + freq_write :3, + freq_read_id :3, + dual_output :1, /* new since Cougar Point/6 */ + :1; + } modes; + struct { + uint32_t comp1_density :3, + comp2_density :3, + :26; + } dens_old; + struct { + uint32_t comp1_density :4, /* new since Lynx Point/8 */ + comp2_density :4, + :24; + } dens_new; + }; + union { /* 0x04 */ + uint32_t FLILL; /* Flash Invalid Instructions Register */ + struct { + uint32_t invalid_instr0 :8, + invalid_instr1 :8, + invalid_instr2 :8, + invalid_instr3 :8; + }; + }; + union { /* 0x08 */ + uint32_t FLPB; /* Flash Partition Boundary Register, until Panther Point/7 */ + struct { + uint32_t FPBA :13, /* Flash Partition Boundary Addr */ + :19; + }; + uint32_t FLILL1; /* Flash Invalid Instructions Register, new since Sunrise Point/100 */ + struct { + uint32_t invalid_instr4 :8, + invalid_instr5 :8, + invalid_instr6 :8, + invalid_instr7 :8; + }; + }; +}; + +#define MAX_NUM_FLREGS 16 +struct ich_desc_region { + /* + * Number of entries and width differ on various generations: + * + * Chipset/Generation #FLREGs width (bits) + * ICH8 .. Panther Point/7 5 13 + * Lynx Point/8 .. Wildcat Point/9 7 15 + * Sunrise Point/100 .. 200 Series 10 15 + * Lewisburg/100 .. 16 15 + * Cannon Point/300 .. 16 15 + */ + union { + uint32_t FLREGs[MAX_NUM_FLREGS]; /* Flash Descriptor Regions */ + + /* only used for bit-field check */ + struct { + uint32_t base :13, + :3, + limit :13, + :3; + } old_reg[MAX_NUM_FLREGS]; + }; +}; + +#define MAX_NUM_MASTERS 6 /* 5 prior to C620/Lewisburg PCH */ +struct ich_desc_master { + union { + uint32_t FLMSTRs[MAX_NUM_MASTERS]; /* Flash Masters */ + /* For pre-Skylake platforms */ + struct { + uint32_t BIOS_req_ID :16, + BIOS_descr_r :1, + BIOS_BIOS_r :1, + BIOS_ME_r :1, + BIOS_GbE_r :1, + BIOS_plat_r :1, + :3, + BIOS_descr_w :1, + BIOS_BIOS_w :1, + BIOS_ME_w :1, + BIOS_GbE_w :1, + BIOS_plat_w :1, + :3; + uint32_t ME_req_ID :16, + ME_descr_r :1, + ME_BIOS_r :1, + ME_ME_r :1, + ME_GbE_r :1, + ME_plat_r :1, + :3, + ME_descr_w :1, + ME_BIOS_w :1, + ME_ME_w :1, + ME_GbE_w :1, + ME_plat_w :1, + :3; + uint32_t GbE_req_ID :16, + GbE_descr_r :1, + GbE_BIOS_r :1, + GbE_ME_r :1, + GbE_GbE_r :1, + GbE_plat_r :1, + :3, + GbE_descr_w :1, + GbE_BIOS_w :1, + GbE_ME_w :1, + GbE_GbE_w :1, + GbE_plat_w :1, + :3; + }; + /* From Skylake on */ + struct { + uint32_t ext_read :4, + ext_write :4, + read :12, + write :12; + } mstr[MAX_NUM_MASTERS]; + }; +}; + +struct ich_desc_north_strap { + union { + uint32_t STRPs[1]; /* current maximum: ich8 */ + struct { /* ich8 */ + struct { /* STRP2 (in the datasheet) */ + uint32_t MDB :1, + :31; + }; + } ich8; + }; +}; + +struct ich_desc_south_strap { + union { + uint32_t STRPs[23]; /* current maximum: gemini lake */ + struct { /* ich8 */ + struct { /* STRP1 */ + uint32_t ME_DISABLE :1, + :6, + TCOMODE :1, + ASD :7, + BMCMODE :1, + :3, + GLAN_PCIE_SEL :1, + GPIO12_SEL :2, + SPICS1_LANPHYPC_SEL :1, + MESM2SEL :1, + :1, + ASD2 :7; + }; + } ich8; + struct { /* ibex peak */ + struct { /* STRP0 */ + uint32_t :1, + cs_ss2 :1, + :5, + SMB_EN :1, + SML0_EN :1, + SML1_EN :1, + SML1FRQ :2, + SMB0FRQ :2, + SML0FRQ :2, + :4, + LANPHYPC_GP12_SEL :1, + cs_ss1 :1, + :2, + DMI_REQID_DIS :1, + :4, + BBBS :2, + :1; + }; + struct { /* STRP1 */ + uint32_t cs_ss3 :4, + :28; + }; + struct { /* STRP2 */ + uint32_t :8, + MESMASDEN :1, + MESMASDA :7, + :8, + MESMI2CEN :1, + MESMI2CA :7; + }; + struct { /* STRP3 */ + uint32_t :32; + }; + struct { /* STRP4 */ + uint32_t PHYCON :2, + :6, + GBEMAC_SMBUS_ADDR_EN :1, + GBEMAC_SMBUS_ADDR :7, + :1, + GBEPHY_SMBUS_ADDR :7, + :8; + }; + struct { /* STRP5 */ + uint32_t :32; + }; + struct { /* STRP6 */ + uint32_t :32; + }; + struct { /* STRP7 */ + uint32_t MESMA2UDID_VENDOR :16, + MESMA2UDID_DEVICE :16; + }; + struct { /* STRP8 */ + uint32_t :32; + }; + struct { /* STRP9 */ + uint32_t PCIEPCS1 :2, + PCIEPCS2 :2, + PCIELR1 :1, + PCIELR2 :1, + DMILR :1, + :1, + PHY_PCIEPORTSEL :3, + PHY_PCIE_EN :1, + :20; + }; + struct { /* STRP10 */ + uint32_t :1, + ME_BOOT_FLASH :1, + cs_ss5 :1, + VE_EN :1, + :4, + MMDDE :1, + MMADDR :7, + cs_ss7 :1, + :1, + ICC_SEL :3, + MER_CL1 :1, + :10; + }; + struct { /* STRP11 */ + uint32_t SML1GPAEN :1, + SML1GPA :7, + :16, + SML1I2CAEN :1, + SML1I2CA :7; + }; + struct { /* STRP12 */ + uint32_t :32; + }; + struct { /* STRP13 */ + uint32_t :32; + }; + struct { /* STRP14 */ + uint32_t :8, + VE_EN2 :1, + :5, + VE_BOOT_FLASH :1, + :1, + BW_SSD :1, + NVMHCI_EN :1, + :14; + }; + struct { /* STRP15 */ + uint32_t :3, + cs_ss6 :2, + :1, + IWL_EN :1, + :1, + t209min :2, + :22; + }; + } ibex; + struct { /* cougar point */ + struct { /* STRP0 */ + uint32_t :1, + cs_ss1 :1, + :5, + SMB_EN :1, + SML0_EN :1, + SML1_EN :1, + SML1FRQ :2, + SMB0FRQ :2, + SML0FRQ :2, + :4, + LANPHYPC_GP12_SEL :1, + LINKSEC_DIS :1, + :2, + DMI_REQID_DIS :1, + :4, + BBBS :2, + :1; + }; + struct { /* STRP1 */ + uint32_t cs_ss3 :4, + :4, + cs_ss2 :1, + :28; + }; + struct { /* STRP2 */ + uint32_t :8, + MESMASDEN :1, + MESMASDA :7, + MESMMCTPAEN :1, + MESMMCTPA :7, + MESMI2CEN :1, + MESMI2CA :7; + }; + struct { /* STRP3 */ + uint32_t :32; + }; + struct { /* STRP4 */ + uint32_t PHYCON :2, + :6, + GBEMAC_SMBUS_ADDR_EN :1, + GBEMAC_SMBUS_ADDR :7, + :1, + GBEPHY_SMBUS_ADDR :7, + :8; + }; + struct { /* STRP5 */ + uint32_t :32; + }; + struct { /* STRP6 */ + uint32_t :32; + }; + struct { /* STRP7 */ + uint32_t MESMA2UDID_VENDOR :16, + MESMA2UDID_DEVICE :16; + }; + struct { /* STRP8 */ + uint32_t :32; + }; + struct { /* STRP9 */ + uint32_t PCIEPCS1 :2, + PCIEPCS2 :2, + PCIELR1 :1, + PCIELR2 :1, + DMILR :1, + cs_ss4 :1, + PHY_PCIEPORTSEL :3, + PHY_PCIE_EN :1, + :2, + SUB_DECODE_EN :1, + :7, + PCHHOT_SML1ALERT_SEL :1, + :9; + }; + struct { /* STRP10 */ + uint32_t :1, + ME_BOOT_FLASH :1, + :6, + MDSMBE_EN :1, + MDSMBE_ADD :7, + :2, + ICC_SEL :3, + MER_CL1 :1, + ICC_PRO_SEL :1, + Deep_SX_EN :1, + ME_DBG_LAN :1, + :7; + }; + struct { /* STRP11 */ + uint32_t SML1GPAEN :1, + SML1GPA :7, + :16, + SML1I2CAEN :1, + SML1I2CA :7; + }; + struct { /* STRP12 */ + uint32_t :32; + }; + struct { /* STRP13 */ + uint32_t :32; + }; + struct { /* STRP14 */ + uint32_t :32; + }; + struct { /* STRP15 */ + uint32_t cs_ss6 :6, + IWL_EN :1, + cs_ss5 :2, + :4, + SMLINK1_THERM_SEL :1, + SLP_LAN_GP29_SEL :1, + :16; + }; + struct { /* STRP16 */ + uint32_t :32; + }; + struct { /* STRP17 */ + uint32_t ICML :1, + cs_ss7 :1, + :30; + }; + } cougar; + }; +}; + +struct ich_desc_upper_map { + union { + uint32_t FLUMAP1; /* Flash Upper Map 1 */ + struct { + uint32_t VTBA :8, /* ME VSCC Table Base Address */ + VTL :8, /* ME VSCC Table Length */ + :8, + MDTBA :8; /* MIP Descr. Table Base Addr. (new since Cannon Point/300) */ + }; + }; + struct { + union { /* JEDEC-ID Register */ + uint32_t JID; + struct { + uint32_t vid :8, /* Vendor ID */ + cid0 :8, /* Component ID 0 */ + cid1 :8, /* Component ID 1 */ + :8; + }; + }; + union { /* Vendor Specific Component Capabilities */ + uint32_t VSCC; + struct { + uint32_t ubes :2, /* Upper Block/Sector Erase Size */ + uwg :1, /* Upper Write Granularity */ + uwsr :1, /* Upper Write Status Required */ + uwews :1, /* Upper Write Enable on Write Status */ + :3, + ueo :8, /* Upper Erase Opcode */ + lbes :2, /* Lower Block/Sector Erase Size */ + lwg :1, /* Lower Write Granularity */ + lwsr :1, /* Lower Write Status Required */ + lwews :1, /* Lower Write Enable on Write Status */ + :3, + leo :16; /* Lower Erase Opcode */ + }; + }; + } vscc_table[128]; +}; + +struct ich_descriptors { + struct ich_desc_content content; + struct ich_desc_component component; + struct ich_desc_region region; + struct ich_desc_master master; + struct ich_desc_north_strap north; + struct ich_desc_south_strap south; + struct ich_desc_upper_map upper; +}; + +ssize_t ich_number_of_regions(enum ich_chipset cs, const struct ich_desc_content *content); +ssize_t ich_number_of_masters(enum ich_chipset cs, const struct ich_desc_content *content); + +void prettyprint_ich_chipset(enum ich_chipset cs); +void prettyprint_ich_descriptors(enum ich_chipset cs, const struct ich_descriptors *desc); + +void prettyprint_ich_descriptor_content(enum ich_chipset cs, const struct ich_desc_content *content); +void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_descriptors *desc); +void prettyprint_ich_descriptor_region(enum ich_chipset cs, const struct ich_descriptors *desc); +void prettyprint_ich_descriptor_master(enum ich_chipset cs, const struct ich_descriptors *desc); + +void prettyprint_ich_descriptor_upper_map(const struct ich_desc_upper_map *umap); +void prettyprint_ich_descriptor_straps(enum ich_chipset cs, const struct ich_descriptors *desc); +int read_ich_descriptors_from_dump(const uint32_t *dump, size_t len, enum ich_chipset *cs, struct ich_descriptors *desc); + +int read_ich_descriptors_via_fdo(enum ich_chipset cs, void *spibar, struct ich_descriptors *desc); +int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx); + +int layout_from_ich_descriptors(struct flashrom_layout **, const void *dump, size_t len); + +#endif /* __ICH_DESCRIPTORS_H__ */ diff --git a/include/layout.h b/include/layout.h new file mode 100644 index 00000000..abbdc22c --- /dev/null +++ b/include/layout.h @@ -0,0 +1,69 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2005-2008 coresystems GmbH + * (Written by Stefan Reinauer for coresystems GmbH) + * Copyright (C) 2011-2013 Stefan Tauner + * Copyright (C) 2016 secunet Security Networks AG + * (Written by Nico Huber for secunet) + * + * 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. + */ + +#ifndef __LAYOUT_H__ +#define __LAYOUT_H__ 1 + +#include +#include +#include + +/* Types and macros regarding the maximum flash space size supported by generic code. */ +typedef uint32_t chipoff_t; /* Able to store any addressable offset within a supported flash memory. */ +typedef uint32_t chipsize_t; /* Able to store the number of bytes of any supported flash memory. */ +#define FL_MAX_CHIPOFF_BITS (24) +#define FL_MAX_CHIPOFF ((chipoff_t)(1ULL< for secunet) + * + * 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. + */ + +#ifndef __LIBFLASHROM_H__ +#define __LIBFLASHROM_H__ 1 + +#include +#include +#include +#include +#include + +int flashrom_init(int perform_selfcheck); +int flashrom_shutdown(void); +/** @ingroup flashrom-general */ +enum flashrom_log_level { + FLASHROM_MSG_ERROR = 0, + FLASHROM_MSG_WARN = 1, + FLASHROM_MSG_INFO = 2, + FLASHROM_MSG_DEBUG = 3, + FLASHROM_MSG_DEBUG2 = 4, + FLASHROM_MSG_SPEW = 5, +}; +/** @ingroup flashrom-general */ +typedef int(flashrom_log_callback)(enum flashrom_log_level, const char *format, va_list); +void flashrom_set_log_callback(flashrom_log_callback *); + +/** @ingroup flashrom-query */ +enum flashrom_test_state { + FLASHROM_TESTED_OK = 0, + FLASHROM_TESTED_NT = 1, + FLASHROM_TESTED_BAD = 2, + FLASHROM_TESTED_DEP = 3, + FLASHROM_TESTED_NA = 4, +}; + +struct flashrom_flashchip_info { + const char *vendor; + const char *name; + unsigned int total_size; + struct flashrom_tested { + enum flashrom_test_state probe; + enum flashrom_test_state read; + enum flashrom_test_state erase; + enum flashrom_test_state write; + } tested; +}; + +struct flashrom_board_info { + const char *vendor; + const char *name; + enum flashrom_test_state working; +}; + +struct flashrom_chipset_info { + const char *vendor; + const char *chipset; + uint16_t vendor_id; + uint16_t chipset_id; + enum flashrom_test_state status; +}; + +const char *flashrom_version_info(void); +struct flashrom_flashchip_info *flashrom_supported_flash_chips(void); +struct flashrom_board_info *flashrom_supported_boards(void); +struct flashrom_chipset_info *flashrom_supported_chipsets(void); +int flashrom_data_free(void *const p); + +/** @ingroup flashrom-prog */ +struct flashrom_programmer; +int flashrom_programmer_init(struct flashrom_programmer **, const char *prog_name, const char *prog_params); +int flashrom_programmer_shutdown(struct flashrom_programmer *); + +struct flashrom_flashctx; +int flashrom_flash_probe(struct flashrom_flashctx **, const struct flashrom_programmer *, const char *chip_name); +size_t flashrom_flash_getsize(const struct flashrom_flashctx *); +int flashrom_flash_erase(struct flashrom_flashctx *); +void flashrom_flash_release(struct flashrom_flashctx *); + +/** @ingroup flashrom-flash */ +enum flashrom_flag { + FLASHROM_FLAG_FORCE, + FLASHROM_FLAG_FORCE_BOARDMISMATCH, + FLASHROM_FLAG_VERIFY_AFTER_WRITE, + FLASHROM_FLAG_VERIFY_WHOLE_CHIP, +}; +void flashrom_flag_set(struct flashrom_flashctx *, enum flashrom_flag, bool value); +bool flashrom_flag_get(const struct flashrom_flashctx *, enum flashrom_flag); + +int flashrom_image_read(struct flashrom_flashctx *, void *buffer, size_t buffer_len); +int flashrom_image_write(struct flashrom_flashctx *, void *buffer, size_t buffer_len, const void *refbuffer); +int flashrom_image_verify(struct flashrom_flashctx *, const void *buffer, size_t buffer_len); + +struct flashrom_layout; +int flashrom_layout_new(struct flashrom_layout **); +int flashrom_layout_read_from_ifd(struct flashrom_layout **, struct flashrom_flashctx *, const void *dump, size_t len); +int flashrom_layout_read_fmap_from_rom(struct flashrom_layout **, + struct flashrom_flashctx *, size_t offset, size_t length); +int flashrom_layout_read_fmap_from_buffer(struct flashrom_layout **layout, + struct flashrom_flashctx *, const uint8_t *buf, size_t len); +int flashrom_layout_add_region(struct flashrom_layout *, size_t start, size_t end, const char *name); +int flashrom_layout_include_region(struct flashrom_layout *, const char *name); +int flashrom_layout_get_region_range(struct flashrom_layout *, const char *name, + unsigned int *start, unsigned int *len); +void flashrom_layout_release(struct flashrom_layout *); +void flashrom_layout_set(struct flashrom_flashctx *, const struct flashrom_layout *); + +/** @ingroup flashrom-wp */ +enum flashrom_wp_result { + FLASHROM_WP_OK = 0, + FLASHROM_WP_ERR_CHIP_UNSUPPORTED = 1, + FLASHROM_WP_ERR_OTHER = 2, + FLASHROM_WP_ERR_READ_FAILED = 3, + FLASHROM_WP_ERR_WRITE_FAILED = 4, + FLASHROM_WP_ERR_VERIFY_FAILED = 5, + FLASHROM_WP_ERR_RANGE_UNSUPPORTED = 6, + FLASHROM_WP_ERR_MODE_UNSUPPORTED = 7, + FLASHROM_WP_ERR_RANGE_LIST_UNAVAILABLE = 8 +}; + +enum flashrom_wp_mode { + FLASHROM_WP_MODE_DISABLED, + FLASHROM_WP_MODE_HARDWARE, + FLASHROM_WP_MODE_POWER_CYCLE, + FLASHROM_WP_MODE_PERMANENT +}; +struct flashrom_wp_cfg; +struct flashrom_wp_ranges; + +enum flashrom_wp_result flashrom_wp_cfg_new(struct flashrom_wp_cfg **); +void flashrom_wp_cfg_release(struct flashrom_wp_cfg *); +void flashrom_wp_set_mode(struct flashrom_wp_cfg *, enum flashrom_wp_mode); +enum flashrom_wp_mode flashrom_wp_get_mode(const struct flashrom_wp_cfg *); +void flashrom_wp_set_range(struct flashrom_wp_cfg *, size_t start, size_t len); +void flashrom_wp_get_range(size_t *start, size_t *len, const struct flashrom_wp_cfg *); + +enum flashrom_wp_result flashrom_wp_read_cfg(struct flashrom_wp_cfg *, struct flashrom_flashctx *); +enum flashrom_wp_result flashrom_wp_write_cfg(struct flashrom_flashctx *, const struct flashrom_wp_cfg *); + +enum flashrom_wp_result flashrom_wp_get_available_ranges(struct flashrom_wp_ranges **, struct flashrom_flashctx *); +size_t flashrom_wp_ranges_get_count(const struct flashrom_wp_ranges *); +enum flashrom_wp_result flashrom_wp_ranges_get_range(size_t *start, size_t *len, const struct flashrom_wp_ranges *, unsigned int index); +void flashrom_wp_ranges_release(struct flashrom_wp_ranges *); + +#endif /* !__LIBFLASHROM_H__ */ diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 00000000..d15082f0 --- /dev/null +++ b/include/platform.h @@ -0,0 +1,117 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009 Carl-Daniel Hailfinger + * Copyright (C) 2022 secunet Security Networks AG + * (written by Thomas Heijligen +#include + +/* swap bytes */ +/* OpenBSD has conflicting definitions for swapX and __swapX */ +static inline uint8_t ___swap8(const uint8_t value) +{ + return (value & (uint8_t)0xffU); +} + +static inline uint16_t ___swap16(const uint16_t value) +{ + return ((value & (uint16_t)0x00ffU) << 8) | + ((value & (uint16_t)0xff00U) >> 8); +} + +static inline uint32_t ___swap32(const uint32_t value) +{ + return ((value & (uint32_t)0x000000ffUL) << 24) | + ((value & (uint32_t)0x0000ff00UL) << 8) | + ((value & (uint32_t)0x00ff0000UL) >> 8) | + ((value & (uint32_t)0xff000000UL) >> 24); +} + +static inline uint64_t ___swap64(const uint64_t value) +{ + return ((value & (uint64_t)0x00000000000000ffULL) << 56) | + ((value & (uint64_t)0x000000000000ff00ULL) << 40) | + ((value & (uint64_t)0x0000000000ff0000ULL) << 24) | + ((value & (uint64_t)0x00000000ff000000ULL) << 8) | + ((value & (uint64_t)0x000000ff00000000ULL) >> 8) | + ((value & (uint64_t)0x0000ff0000000000ULL) >> 24) | + ((value & (uint64_t)0x00ff000000000000ULL) >> 40) | + ((value & (uint64_t)0xff00000000000000ULL) >> 56); +} + +/* + * macro to return the same value as passed. + * + * `___return_same(cpu_to_le, 8)` + * expands to + * `uint8_t cpu_to_le8 (const uint8_t value) { return value; }` + */ +#define ___return_same(name, bits) \ + uint##bits##_t name##bits (const uint##bits##_t value) { return value; } + +/* + * macro to return the swapped value as passed. + * + * `___return_swapped(cpu_to_be, 8)` + * expands to + * `uint8_t cpu_to_be8 (const uint8_t value) { return ___swap8 (value); }` + */ +#define ___return_swapped(name, bits) \ + uint##bits##_t name##bits (const uint##bits##_t value) { return ___swap##bits (value); } + +/* convert cpu native endian to little endian */ +uint8_t cpu_to_le8 (uint8_t value); +uint16_t cpu_to_le16(uint16_t value); +uint32_t cpu_to_le32(uint32_t value); +uint64_t cpu_to_le64(uint64_t value); + +/* convert cpu native endian to big endian */ +uint8_t cpu_to_be8 (uint8_t value); +uint16_t cpu_to_be16(uint16_t value); +uint32_t cpu_to_be32(uint32_t value); +uint64_t cpu_to_be64(uint64_t value); + +/* convert little endian to cpu native endian */ +uint8_t le_to_cpu8 (uint8_t value); +uint16_t le_to_cpu16(uint16_t value); +uint32_t le_to_cpu32(uint32_t value); +uint64_t le_to_cpu64(uint64_t value); + +/* convert big endian to cpu native endian */ +uint8_t be_to_cpu8 (uint8_t value); +uint16_t be_to_cpu16(uint16_t value); +uint32_t be_to_cpu32(uint32_t value); +uint64_t be_to_cpu64(uint64_t value); + +/* read value from base at offset in little endian */ +uint8_t read_le8 (const void *base, size_t offset); +uint16_t read_le16(const void *base, size_t offset); +uint32_t read_le32(const void *base, size_t offset); +uint64_t read_le64(const void *base, size_t offset); + +/* read value from base at offset in big endian */ +uint8_t read_be8 (const void *base, size_t offset); +uint16_t read_be16(const void *base, size_t offset); +uint32_t read_be32(const void *base, size_t offset); +uint64_t read_be64(const void *base, size_t offset); + +#endif /* !__PLATFORM_H__ */ diff --git a/include/platform/pci.h b/include/platform/pci.h new file mode 100644 index 00000000..93bc163b --- /dev/null +++ b/include/platform/pci.h @@ -0,0 +1,25 @@ +/* + * This is a wrapper for libpci. + * ... + */ + + +#ifndef __PLATFORM_PCI_H__ +#define __PLATFORM_PCI_H__ + +/* + * An old libpci version seems to use the variable name "index" which triggers + * shadowing warnings on systems which have the index() function in a default + * #include or as builtin. + */ +#define index shadow_workaround_index + +#if defined (__NetBSD__) +#include +#else +#include +#endif + +#undef index + +#endif /* __PLATFORM_PCI_H__ */ \ No newline at end of file diff --git a/include/programmer.h b/include/programmer.h new file mode 100644 index 00000000..5fb06260 --- /dev/null +++ b/include/programmer.h @@ -0,0 +1,516 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2000 Silicon Integrated System Corporation + * Copyright (C) 2000 Ronald G. Minnich + * Copyright (C) 2005-2009 coresystems GmbH + * Copyright (C) 2006-2009 Carl-Daniel Hailfinger + * + * 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. + */ + +#ifndef __PROGRAMMER_H__ +#define __PROGRAMMER_H__ 1 + +#include + +#include "flash.h" /* for chipaddr and flashctx */ + +enum programmer_type { + PCI = 1, /* to detect uninitialized values */ + USB, + OTHER, +}; + +struct dev_entry { + uint16_t vendor_id; + uint16_t device_id; + const enum test_state status; + const char *vendor_name; + const char *device_name; +}; + +struct programmer_entry { + const char *name; + const enum programmer_type type; + union { + const struct dev_entry *const dev; + const char *const note; + } devs; + + int (*init) (void); + + void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len); + void (*unmap_flash_region) (void *virt_addr, size_t len); + + void (*delay) (unsigned int usecs); +}; + +extern const struct programmer_entry *const programmer_table[]; +extern const size_t programmer_table_size; + +/* programmer drivers */ +extern const struct programmer_entry programmer_atahpt; +extern const struct programmer_entry programmer_atapromise; +extern const struct programmer_entry programmer_atavia; +extern const struct programmer_entry programmer_buspirate_spi; +extern const struct programmer_entry programmer_ch341a_spi; +extern const struct programmer_entry programmer_dediprog; +extern const struct programmer_entry programmer_developerbox; +extern const struct programmer_entry programmer_digilent_spi; +extern const struct programmer_entry programmer_drkaiser; +extern const struct programmer_entry programmer_dummy; +extern const struct programmer_entry programmer_ft2232_spi; +extern const struct programmer_entry programmer_gfxnvidia; +extern const struct programmer_entry programmer_internal; +extern const struct programmer_entry programmer_it8212; +extern const struct programmer_entry programmer_jlink_spi; +extern const struct programmer_entry programmer_linux_mtd; +extern const struct programmer_entry programmer_linux_spi; +extern const struct programmer_entry programmer_lspcon_i2c_spi; +extern const struct programmer_entry programmer_mediatek_i2c_spi; +extern const struct programmer_entry programmer_mstarddc_spi; +extern const struct programmer_entry programmer_ni845x_spi; +extern const struct programmer_entry programmer_nic3com; +extern const struct programmer_entry programmer_nicintel; +extern const struct programmer_entry programmer_nicintel_eeprom; +extern const struct programmer_entry programmer_nicintel_spi; +extern const struct programmer_entry programmer_nicnatsemi; +extern const struct programmer_entry programmer_nicrealtek; +extern const struct programmer_entry programmer_ogp_spi; +extern const struct programmer_entry programmer_pickit2_spi; +extern const struct programmer_entry programmer_pony_spi; +extern const struct programmer_entry programmer_raiden_debug_spi; +extern const struct programmer_entry programmer_rayer_spi; +extern const struct programmer_entry programmer_realtek_mst_i2c_spi; +extern const struct programmer_entry programmer_satamv; +extern const struct programmer_entry programmer_satasii; +extern const struct programmer_entry programmer_serprog; +extern const struct programmer_entry programmer_stlinkv3_spi; +extern const struct programmer_entry programmer_usbblaster_spi; + +int programmer_init(const struct programmer_entry *prog, const char *param); +int programmer_shutdown(void); + +struct bitbang_spi_master { + /* Note that CS# is active low, so val=0 means the chip is active. */ + void (*set_cs) (int val, void *spi_data); + void (*set_sck) (int val, void *spi_data); + void (*set_mosi) (int val, void *spi_data); + int (*get_miso) (void *spi_data); + void (*request_bus) (void *spi_data); + void (*release_bus) (void *spi_data); + /* optional functions to optimize xfers */ + void (*set_sck_set_mosi) (int sck, int mosi, void *spi_data); + int (*set_sck_get_miso) (int sck, void *spi_data); + /* Length of half a clock period in usecs. */ + unsigned int half_period; +}; + +struct pci_dev; +struct pci_filter; + +/* pcidev.c */ +// FIXME: This needs to be local, not global(?) +extern struct pci_access *pacc; +int pci_init_common(void); +uintptr_t pcidev_readbar(struct pci_dev *dev, int bar); +struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar); +struct pci_dev *pcidev_scandev(struct pci_filter *filter, struct pci_dev *start); +struct pci_dev *pcidev_getdevfn(struct pci_dev *dev, const int func); +struct pci_dev *pcidev_find_vendorclass(uint16_t vendor, uint16_t devclass); +struct pci_dev *pcidev_card_find(uint16_t vendor, uint16_t device, uint16_t card_vendor, uint16_t card_device); +struct pci_dev *pcidev_find(uint16_t vendor, uint16_t device); +/* rpci_write_* are reversible writes. The original PCI config space register + * contents will be restored on shutdown. + * To clone the pci_dev instances internally, the `pacc` global + * variable has to reference a pci_access method that is compatible + * with the given pci_dev handle. The referenced pci_access (not + * the variable) has to stay valid until the shutdown handlers are + * finished. + */ +int rpci_write_byte(struct pci_dev *dev, int reg, uint8_t data); +int rpci_write_word(struct pci_dev *dev, int reg, uint16_t data); +int rpci_write_long(struct pci_dev *dev, int reg, uint32_t data); + +#if CONFIG_INTERNAL == 1 +struct penable { + uint16_t vendor_id; + uint16_t device_id; + enum chipbustype buses; + const enum test_state status; + const char *vendor_name; + const char *device_name; + int (*doit) (struct pci_dev *dev, const char *name); +}; + +extern const struct penable chipset_enables[]; + +enum board_match_phase { + P1, + P2, + P3 +}; + +struct board_match { + /* Any device, but make it sensible, like the ISA bridge. */ + uint16_t first_vendor; + uint16_t first_device; + uint16_t first_card_vendor; + uint16_t first_card_device; + + /* Any device, but make it sensible, like + * the host bridge. May be NULL. + */ + uint16_t second_vendor; + uint16_t second_device; + uint16_t second_card_vendor; + uint16_t second_card_device; + + /* Pattern to match DMI entries. May be NULL. */ + const char *dmi_pattern; + + /* The vendor / part name from the coreboot table. May be NULL. */ + const char *lb_vendor; + const char *lb_part; + + enum board_match_phase phase; + + const char *vendor_name; + const char *board_name; + + int max_rom_decode_parallel; + const enum test_state status; + int (*enable) (void); /* May be NULL. */ +}; + +extern const struct board_match board_matches[]; + +struct board_info { + const char *vendor; + const char *name; + const enum test_state working; +#ifdef CONFIG_PRINT_WIKI + const char *url; + const char *note; +#endif +}; + +extern const struct board_info boards_known[]; +extern const struct board_info laptops_known[]; +#endif + +/* udelay.c */ +void myusec_delay(unsigned int usecs); +void myusec_calibrate_delay(void); +void internal_sleep(unsigned int usecs); +void internal_delay(unsigned int usecs); + +#if CONFIG_INTERNAL == 1 +/* board_enable.c */ +int selfcheck_board_enables(void); +int board_parse_parameter(const char *boardstring, char **vendor, char **model); +void w836xx_ext_enter(uint16_t port); +void w836xx_ext_leave(uint16_t port); +void probe_superio_winbond(void); +int it8705f_write_enable(uint8_t port); +uint8_t sio_read(uint16_t port, uint8_t reg); +void sio_write(uint16_t port, uint8_t reg, uint8_t data); +void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask); +void board_handle_before_superio(void); +void board_handle_before_laptop(void); +int board_flash_enable(const char *vendor, const char *model, const char *cb_vendor, const char *cb_model); + +/* chipset_enable.c */ +int chipset_flash_enable(void); + +/* processor_enable.c */ +int processor_flash_enable(void); +#endif + +#if CONFIG_INTERNAL == 1 +/* cbtable.c */ +int cb_parse_table(const char **vendor, const char **model); +int cb_check_image(const uint8_t *bios, unsigned int size); + +/* dmi.c */ +#if defined(__i386__) || defined(__x86_64__) +void dmi_init(void); +bool dmi_is_supported(void); +int dmi_match(const char *pattern); +#endif // defined(__i386__) || defined(__x86_64__) + +/* internal.c */ +struct superio { + uint16_t vendor; + uint16_t port; + uint16_t model; +}; +extern struct superio superios[]; +extern int superio_count; +#define SUPERIO_VENDOR_NONE 0x0 +#define SUPERIO_VENDOR_ITE 0x1 +#define SUPERIO_VENDOR_WINBOND 0x2 +#endif + +#if CONFIG_INTERNAL == 1 +extern int is_laptop; +extern int laptop_ok; +extern int force_boardenable; +extern int force_boardmismatch; +void probe_superio(void); +int register_superio(struct superio s); +extern enum chipbustype internal_buses_supported; +#endif + +/* bitbang_spi.c */ +int register_spi_bitbang_master(const struct bitbang_spi_master *master, void *spi_data); + + +/* flashrom.c */ +struct decode_sizes { + uint32_t parallel; + uint32_t lpc; + uint32_t fwh; + uint32_t spi; +}; +// FIXME: These need to be local, not global +extern struct decode_sizes max_rom_decode; +extern int programmer_may_write; +extern unsigned long flashbase; +unsigned int count_max_decode_exceedings(const struct flashctx *flash); +char *extract_programmer_param(const char *param_name); + +/* spi.c */ +#define MAX_DATA_UNSPECIFIED 0 +#define MAX_DATA_READ_UNLIMITED 64 * 1024 +#define MAX_DATA_WRITE_UNLIMITED 256 + +#define SPI_MASTER_4BA (1U << 0) /**< Can handle 4-byte addresses */ +#define SPI_MASTER_NO_4BA_MODES (1U << 1) /**< Compatibility modes (i.e. extended address + register, 4BA mode switch) don't work */ + +struct spi_master { + uint32_t features; + unsigned int max_data_read; // (Ideally,) maximum data read size in one go (excluding opcode+address). + unsigned int max_data_write; // (Ideally,) maximum data write size in one go (excluding opcode+address). + int (*command)(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr); + int (*multicommand)(const struct flashctx *flash, struct spi_command *cmds); + + /* Optimized functions for this master */ + int (*read)(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); + int (*write_256)(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); + int (*write_aai)(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); + int (*shutdown)(void *data); + void *data; +}; + +int default_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr); +int default_spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds); +int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); +int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int register_spi_master(const struct spi_master *mst, void *data); + +/* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */ +enum ich_chipset { + CHIPSET_ICH_UNKNOWN, + CHIPSET_ICH, + CHIPSET_ICH2345, + CHIPSET_ICH6, + CHIPSET_POULSBO, /* SCH U* */ + CHIPSET_TUNNEL_CREEK, /* Atom E6xx */ + CHIPSET_CENTERTON, /* Atom S1220 S1240 S1260 */ + CHIPSET_ICH7, + CHIPSET_ICH8, + CHIPSET_ICH9, + CHIPSET_ICH10, + CHIPSET_5_SERIES_IBEX_PEAK, + CHIPSET_6_SERIES_COUGAR_POINT, + CHIPSET_7_SERIES_PANTHER_POINT, + CHIPSET_8_SERIES_LYNX_POINT, + CHIPSET_BAYTRAIL, /* Actually all with Silvermont architecture: Bay Trail, Avoton/Rangeley */ + CHIPSET_8_SERIES_LYNX_POINT_LP, + CHIPSET_8_SERIES_WELLSBURG, + CHIPSET_9_SERIES_WILDCAT_POINT, + CHIPSET_9_SERIES_WILDCAT_POINT_LP, + CHIPSET_100_SERIES_SUNRISE_POINT, /* also 6th/7th gen Core i/o (LP) variants */ + CHIPSET_C620_SERIES_LEWISBURG, + CHIPSET_300_SERIES_CANNON_POINT, + CHIPSET_400_SERIES_COMET_POINT, + CHIPSET_500_SERIES_TIGER_POINT, + CHIPSET_600_SERIES_ALDER_POINT, + CHIPSET_METEOR_LAKE, + CHIPSET_APOLLO_LAKE, + CHIPSET_GEMINI_LAKE, + CHIPSET_JASPER_LAKE, + CHIPSET_ELKHART_LAKE, +}; + +/* ichspi.c */ +#if CONFIG_INTERNAL == 1 +int ich_init_spi(void *spibar, enum ich_chipset ich_generation); +int via_init_spi(uint32_t mmio_base); + +/* amd_imc.c */ +int amd_imc_shutdown(struct pci_dev *dev); + +/* it85spi.c */ +int it85xx_spi_init(struct superio s); + +/* it87spi.c */ +void enter_conf_mode_ite(uint16_t port); +void exit_conf_mode_ite(uint16_t port); +void probe_superio_ite(void); +int init_superio_ite(void); + +#if CONFIG_LINUX_MTD == 1 +/* trivial wrapper to avoid cluttering internal_init() with #if */ +static inline int try_mtd(void) { return programmer_linux_mtd.init(); }; +#else +static inline int try_mtd(void) { return 1; }; +#endif + +/* mcp6x_spi.c */ +int mcp6x_spi_init(int want_spi); + + + +/* sb600spi.c */ +int sb600_probe_spi(struct pci_dev *dev); + +/* wbsio_spi.c */ +int wbsio_check_for_spi(void); +#endif + +/* opaque.c */ +struct opaque_master { + int max_data_read; + int max_data_write; + /* Specific functions for this master */ + int (*probe) (struct flashctx *flash); + int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); + int (*write) (struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); + int (*erase) (struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); + enum flashrom_wp_result (*wp_write_cfg)(struct flashctx *, const struct flashrom_wp_cfg *); + enum flashrom_wp_result (*wp_read_cfg)(struct flashrom_wp_cfg *, struct flashctx *); + enum flashrom_wp_result (*wp_get_ranges)(struct flashrom_wp_ranges **, struct flashctx *); + int (*shutdown)(void *data); + void *data; +}; +int register_opaque_master(const struct opaque_master *mst, void *data); + +/* programmer.c */ +void *fallback_map(const char *descr, uintptr_t phys_addr, size_t len); +void fallback_unmap(void *virt_addr, size_t len); +void fallback_chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr); +void fallback_chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr); +void fallback_chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len); +uint16_t fallback_chip_readw(const struct flashctx *flash, const chipaddr addr); +uint32_t fallback_chip_readl(const struct flashctx *flash, const chipaddr addr); +void fallback_chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len); +struct par_master { + void (*chip_writeb) (const struct flashctx *flash, uint8_t val, chipaddr addr); + void (*chip_writew) (const struct flashctx *flash, uint16_t val, chipaddr addr); + void (*chip_writel) (const struct flashctx *flash, uint32_t val, chipaddr addr); + void (*chip_writen) (const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len); + uint8_t (*chip_readb) (const struct flashctx *flash, const chipaddr addr); + uint16_t (*chip_readw) (const struct flashctx *flash, const chipaddr addr); + uint32_t (*chip_readl) (const struct flashctx *flash, const chipaddr addr); + void (*chip_readn) (const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len); + int (*shutdown)(void *data); + void *data; +}; +int register_par_master(const struct par_master *mst, const enum chipbustype buses, void *data); +struct registered_master { + enum chipbustype buses_supported; + struct { + struct par_master par; + struct spi_master spi; + struct opaque_master opaque; + }; +}; +extern struct registered_master registered_masters[]; +extern int registered_master_count; +int register_master(const struct registered_master *mst); + + + +/* serial.c */ +#if IS_WINDOWS +typedef HANDLE fdtype; +#define SER_INV_FD INVALID_HANDLE_VALUE +#else +typedef int fdtype; +#define SER_INV_FD -1 +#endif + +void sp_flush_incoming(void); +fdtype sp_openserport(char *dev, int baud); +extern fdtype sp_fd; +int serialport_config(fdtype fd, int baud); +int serialport_shutdown(void *data); +int serialport_write(const unsigned char *buf, unsigned int writecnt); +int serialport_write_nonblock(const unsigned char *buf, unsigned int writecnt, unsigned int timeout, unsigned int *really_wrote); +int serialport_read(unsigned char *buf, unsigned int readcnt); +int serialport_read_nonblock(unsigned char *c, unsigned int readcnt, unsigned int timeout, unsigned int *really_read); + +/* Serial port/pin mapping: + + 1 CD <- + 2 RXD <- + 3 TXD -> + 4 DTR -> + 5 GND -- + 6 DSR <- + 7 RTS -> + 8 CTS <- + 9 RI <- +*/ +enum SP_PIN { + PIN_CD = 1, + PIN_RXD, + PIN_TXD, + PIN_DTR, + PIN_GND, + PIN_DSR, + PIN_RTS, + PIN_CTS, + PIN_RI, +}; + +void sp_set_pin(enum SP_PIN pin, int val); +int sp_get_pin(enum SP_PIN pin); + +/* spi_master feature checks */ +static inline bool spi_master_4ba(const struct flashctx *const flash) +{ + return flash->mst->buses_supported & BUS_SPI && + flash->mst->spi.features & SPI_MASTER_4BA; +} +static inline bool spi_master_no_4ba_modes(const struct flashctx *const flash) +{ + return flash->mst->buses_supported & BUS_SPI && + flash->mst->spi.features & SPI_MASTER_NO_4BA_MODES; +} + +/* usbdev.c */ +struct libusb_device_handle; +struct libusb_context; +struct libusb_device_handle *usb_dev_get_by_vid_pid_serial( + struct libusb_context *usb_ctx, uint16_t vid, uint16_t pid, const char *serialno); +struct libusb_device_handle *usb_dev_get_by_vid_pid_number( + struct libusb_context *usb_ctx, uint16_t vid, uint16_t pid, unsigned int num); + + +#endif /* !__PROGRAMMER_H__ */ diff --git a/include/spi.h b/include/spi.h new file mode 100644 index 00000000..14f71aa0 --- /dev/null +++ b/include/spi.h @@ -0,0 +1,224 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2007, 2008 Carl-Daniel Hailfinger + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef __SPI_H__ +#define __SPI_H__ 1 + +/* + * Contains the generic SPI headers + */ + +#define JEDEC_MAX_ADDR_LEN 0x04 + +/* Read Electronic ID */ +#define JEDEC_RDID 0x9f +#define JEDEC_RDID_OUTSIZE 0x01 +/* INSIZE may be 0x04 for some chips*/ +#define JEDEC_RDID_INSIZE 0x03 + +/* Some ST M95X model */ +#define ST_M95_RDID 0x83 +#define ST_M95_RDID_3BA_OUTSIZE 0x04 /* 8b op, 24bit addr where size >64KiB */ +#define ST_M95_RDID_2BA_OUTSIZE 0x03 /* 8b op, 16bit addr where size <=64KiB */ +#define ST_M95_RDID_OUTSIZE_MAX 0x04 /* ST_M95_RDID_3BA_OUTSIZE */ +#define ST_M95_RDID_INSIZE 0x03 + +/* Some Atmel AT25F* models have bit 3 as don't care bit in commands */ +#define AT25F_RDID 0x15 /* 0x15 or 0x1d */ +#define AT25F_RDID_OUTSIZE 0x01 +#define AT25F_RDID_INSIZE 0x02 + +/* Read Electronic Manufacturer Signature */ +#define JEDEC_REMS 0x90 +#define JEDEC_REMS_OUTSIZE 0x04 +#define JEDEC_REMS_INSIZE 0x02 + +/* Read Serial Flash Discoverable Parameters (SFDP) */ +#define JEDEC_SFDP 0x5a +#define JEDEC_SFDP_OUTSIZE 0x05 /* 8b op, 24b addr, 8b dummy */ +/* JEDEC_SFDP_INSIZE : any length */ + +/* Read Electronic Signature */ +#define JEDEC_RES 0xab +#define JEDEC_RES_OUTSIZE 0x04 +/* INSIZE may be 0x02 for some chips*/ +#define JEDEC_RES_INSIZE 0x01 + +/* Write Enable */ +#define JEDEC_WREN 0x06 +#define JEDEC_WREN_OUTSIZE 0x01 +#define JEDEC_WREN_INSIZE 0x00 + +/* Write Disable */ +#define JEDEC_WRDI 0x04 +#define JEDEC_WRDI_OUTSIZE 0x01 +#define JEDEC_WRDI_INSIZE 0x00 + +/* Chip Erase 0x60 is supported by Macronix/SST chips. */ +#define JEDEC_CE_60 0x60 +#define JEDEC_CE_60_OUTSIZE 0x01 +#define JEDEC_CE_60_INSIZE 0x00 + +/* Chip Erase 0x62 is supported by Atmel AT25F chips. */ +#define JEDEC_CE_62 0x62 +#define JEDEC_CE_62_OUTSIZE 0x01 +#define JEDEC_CE_62_INSIZE 0x00 + +/* Chip Erase 0xc7 is supported by SST/ST/EON/Macronix chips. */ +#define JEDEC_CE_C7 0xc7 +#define JEDEC_CE_C7_OUTSIZE 0x01 +#define JEDEC_CE_C7_INSIZE 0x00 + +/* Block Erase 0x50 is supported by Atmel AT26DF chips. */ +#define JEDEC_BE_50 0x50 +#define JEDEC_BE_50_OUTSIZE 0x04 +#define JEDEC_BE_50_INSIZE 0x00 + +/* Block Erase 0x52 is supported by SST and old Atmel chips. */ +#define JEDEC_BE_52 0x52 +#define JEDEC_BE_52_OUTSIZE 0x04 +#define JEDEC_BE_52_INSIZE 0x00 + +/* Block Erase 0x81 is supported by Atmel AT26DF chips. */ +#define JEDEC_BE_81 0x81 +#define JEDEC_BE_81_OUTSIZE 0x04 +#define JEDEC_BE_81_INSIZE 0x00 + +/* Block Erase 0xc4 is supported by Micron chips. */ +#define JEDEC_BE_C4 0xc4 +#define JEDEC_BE_C4_OUTSIZE 0x04 +#define JEDEC_BE_C4_INSIZE 0x00 + +/* Block Erase 0xd8 is supported by EON/Macronix chips. */ +#define JEDEC_BE_D8 0xd8 +#define JEDEC_BE_D8_OUTSIZE 0x04 +#define JEDEC_BE_D8_INSIZE 0x00 + +/* Block Erase 0xd7 is supported by PMC chips. */ +#define JEDEC_BE_D7 0xd7 +#define JEDEC_BE_D7_OUTSIZE 0x04 +#define JEDEC_BE_D7_INSIZE 0x00 + +/* Block Erase 0xdc is supported by Spansion chips, takes 4 byte address */ +#define JEDEC_BE_DC 0xdc +#define JEDEC_BE_DC_OUTSIZE 0x05 +#define JEDEC_BE_DC_INSIZE 0x00 + +/* Sector Erase 0x20 is supported by Macronix/SST chips. */ +#define JEDEC_SE 0x20 +#define JEDEC_SE_OUTSIZE 0x04 +#define JEDEC_SE_INSIZE 0x00 + +/* Page Erase 0xDB */ +#define JEDEC_PE 0xDB +#define JEDEC_PE_OUTSIZE 0x04 +#define JEDEC_PE_INSIZE 0x00 + +/* Read Status Register */ +#define JEDEC_RDSR 0x05 +#define JEDEC_RDSR_OUTSIZE 0x01 +#define JEDEC_RDSR_INSIZE 0x01 + +/* Read Status Register 2 */ +#define JEDEC_RDSR2 0x35 +#define JEDEC_RDSR2_OUTSIZE 0x01 +#define JEDEC_RDSR2_INSIZE 0x01 + +/* Read Status Register 3 */ +#define JEDEC_RDSR3 0x15 +#define JEDEC_RDSR3_OUTSIZE 0x01 +#define JEDEC_RDSR3_INSIZE 0x01 + +/* Status Register Bits */ +#define SPI_SR_WIP (0x01 << 0) +#define SPI_SR_WEL (0x01 << 1) +#define SPI_SR_ERA_ERR (0x01 << 5) +#define SPI_SR_AAI (0x01 << 6) + +/* Write Status Enable */ +#define JEDEC_EWSR 0x50 +#define JEDEC_EWSR_OUTSIZE 0x01 +#define JEDEC_EWSR_INSIZE 0x00 + +/* Write Status Register */ +#define JEDEC_WRSR 0x01 +#define JEDEC_WRSR_OUTSIZE 0x02 +#define JEDEC_WRSR_INSIZE 0x00 +#define JEDEC_WRSR_EXT_OUTSIZE 0x03 + +/* Write Status Register 2 */ +#define JEDEC_WRSR2 0x31 +#define JEDEC_WRSR2_OUTSIZE 0x02 +#define JEDEC_WRSR2_INSIZE 0x00 + +/* Write Status Register 3 */ +#define JEDEC_WRSR3 0x11 +#define JEDEC_WRSR3_OUTSIZE 0x02 +#define JEDEC_WRSR3_INSIZE 0x00 + +/* Enter 4-byte Address Mode */ +#define JEDEC_ENTER_4_BYTE_ADDR_MODE 0xB7 + +/* Exit 4-byte Address Mode */ +#define JEDEC_EXIT_4_BYTE_ADDR_MODE 0xE9 + +/* Write Extended Address Register */ +#define JEDEC_WRITE_EXT_ADDR_REG 0xC5 + +/* Read Extended Address Register */ +#define JEDEC_READ_EXT_ADDR_REG 0xC8 + +/* Read the memory */ +#define JEDEC_READ 0x03 +#define JEDEC_READ_OUTSIZE 0x04 +/* JEDEC_READ_INSIZE : any length */ + +/* Read the memory (with delay after sending address) */ +#define JEDEC_READ_FAST 0x0b + +/* Write memory byte */ +#define JEDEC_BYTE_PROGRAM 0x02 +#define JEDEC_BYTE_PROGRAM_OUTSIZE 0x05 +#define JEDEC_BYTE_PROGRAM_INSIZE 0x00 + +/* Write AAI word (SST25VF080B) */ +#define JEDEC_AAI_WORD_PROGRAM 0xad +#define JEDEC_AAI_WORD_PROGRAM_OUTSIZE 0x06 +#define JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE 0x03 +#define JEDEC_AAI_WORD_PROGRAM_INSIZE 0x00 + +/* Read the memory with 4-byte address + From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ +#define JEDEC_READ_4BA 0x13 + +/* Read the memory with 4-byte address (and delay after sending address) + From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ +#define JEDEC_READ_4BA_FAST 0x0c + +/* Write memory byte with 4-byte address + From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ +#define JEDEC_BYTE_PROGRAM_4BA 0x12 + +/* Error codes */ +#define SPI_GENERIC_ERROR -1 +#define SPI_INVALID_OPCODE -2 +#define SPI_INVALID_ADDRESS -3 +#define SPI_INVALID_LENGTH -4 +#define SPI_FLASHROM_BUG -5 +#define SPI_PROGRAMMER_ERROR -6 + +void clear_spi_id_cache(void); + +#endif /* !__SPI_H__ */ diff --git a/include/usb_device.h b/include/usb_device.h new file mode 100644 index 00000000..8b7a8010 --- /dev/null +++ b/include/usb_device.h @@ -0,0 +1,181 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2020, Google Inc. All rights reserved. + * + * 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. + */ + +#ifndef USB_DEVICE_H +#define USB_DEVICE_H + +/* + * USB device matching framework + * + * This can be used to match a USB device by a number of different parameters. + * The parameters can be passed on the command line and defaults can be set + * by the programmer. + */ + +#include +#include +#include + +/* + * The LIBUSB_ERROR macro converts a libusb failure code into an error code that + * flashrom recognizes. It does so without displaying an error code allowing us + * to compare error codes against the library enumeration values. + */ +#define LIBUSB_ERROR(error_code) (0x20000 | -(error_code)) + +/* + * The LIBUSB macro converts a libusb failure code into an error code that + * flashrom recognizes. It also displays additional libusb specific + * information about the failure. + */ +#define LIBUSB(expression) \ + ({ \ + int libusb_error__ = (expression); \ + \ + if (libusb_error__ < 0) { \ + msg_perr("libusb error: %s:%d %s\n", \ + __FILE__, \ + __LINE__, \ + libusb_error_name(libusb_error__)); \ + libusb_error__ = LIBUSB_ERROR(libusb_error__); \ + } else { \ + libusb_error__ = 0; \ + } \ + \ + libusb_error__; \ + }) + +/* + * Returns true if the error code falls within the range of valid libusb + * error codes. + */ +static inline bool usb_device_is_libusb_error(int error_code) +{ + return (0x20000 <= error_code && error_code < 0x20064); +} + +/* + * A USB match and associated value struct are used to encode the information + * about a device against which we wish to match. If the value of a + * usb_match_value has been set then a device must match that value. The name + * of the usb_match_value is used to fetch the programmer parameter from the + * flashrom command line and is the same as the name of the corresponding + * field in usb_match. + */ +struct usb_match_value { + char const *name; + int value; + int set; +}; + +struct usb_match { + struct usb_match_value bus; + struct usb_match_value address; + struct usb_match_value vid; + struct usb_match_value pid; + struct usb_match_value serial; + struct usb_match_value config; + struct usb_match_value interface; + struct usb_match_value altsetting; + struct usb_match_value class; + struct usb_match_value subclass; + struct usb_match_value protocol; +}; + +/* + * Initialize a usb_match structure so that each value's name matches the + * values name in the usb_match structure (so bus.name == "bus"...), and + * look for each value in the flashrom command line via + * extract_programmer_param. If the value is found convert it to an integer + * using strtol, accepting hex, decimal and octal encoding. + */ +void usb_match_init(struct usb_match *match); + +/* + * Add a default value to a usb_match_value. This must be done after calling + * usb_match_init. If usb_match_init already set the value of a usb_match_value + * we do nothing, otherwise set the value to default_value. This ensures that + * parameters passed on the command line override defaults. + */ +void usb_match_value_default(struct usb_match_value *match, + long int default_value); + +/* + * The usb_device structure is an entry in a linked list of devices that were + * matched by usb_device_find. + */ +struct usb_device { + struct libusb_device *device; + struct libusb_config_descriptor *config_descriptor; + struct libusb_interface_descriptor const *interface_descriptor; + + /* + * Initially NULL, the libusb_device_handle is only valid once the + * usb_device has been successfully passed to usb_device_show or + * usb_device_claim. + */ + struct libusb_device_handle *handle; + + /* + * Link to next device, or NULL + */ + struct usb_device *next; +}; + +/* + * Find and return a list of all compatible devices. Each device is added to + * the list with its first valid configuration and interface. If an alternate + * configuration (config, interface, altsetting...) is desired the specifics + * can be supplied as programmer parameters. + * + * Return: + * 0: At least one matching device was found. + * 1: No matching devices were found. + */ +int usb_device_find(struct usb_match const *match, struct usb_device **devices); + +/* + * Display the devices bus and address as well as its product string. The + * underlying libusb device is opened if it is not already open. + * + * Return: + * 0: The device information was displayed. + * non-zero: There was a failure while displaying the device information. + */ +int usb_device_show(char const *prefix, struct usb_device *device); + +/* + * Open the underlying libusb device, set its config, claim the interface and + * select the correct alternate interface. + * + * Return: + * 0: The device was successfully claimed. + * non-zero: There was a failure while trying to claim the device. + */ +int usb_device_claim(struct usb_device *device); + +/* + * Free a usb_device structure. + * + * This ensures that the libusb device is closed and that all allocated + * handles and descriptors are freed. + * + * Return: + * The next device in the device list. + */ +struct usb_device *usb_device_free(struct usb_device *device); + +#endif /* USB_DEVICE_H */ diff --git a/include/writeprotect.h b/include/writeprotect.h new file mode 100644 index 00000000..e27403dc --- /dev/null +++ b/include/writeprotect.h @@ -0,0 +1,89 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 Google Inc. + * + * 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. + * + */ + +#ifndef __WRITEPROTECT_H__ +#define __WRITEPROTECT_H__ 1 + +#include +#include +#include + +#include "libflashrom.h" + +#define MAX_BP_BITS 4 + +/* Chip protection range: start address and length. */ +struct wp_range { + size_t start, len; +}; + +/* Generic description of a chip's write protection configuration. */ +struct flashrom_wp_cfg { + enum flashrom_wp_mode mode; + struct wp_range range; +}; + +/* Collection of multiple write protection ranges. */ +struct flashrom_wp_ranges { + struct wp_range *ranges; + size_t count; +}; + +/* + * Description of a chip's write protection configuration. + * + * It allows most WP code to store and manipulate a chip's configuration + * without knowing the exact layout of bits in the chip's status registers. + */ +struct wp_bits { + /* Status register protection bit (SRP) */ + bool srp_bit_present; + uint8_t srp; + + /* Status register lock bit (SRL) */ + bool srl_bit_present; + uint8_t srl; + + /* Complement bit (CMP) */ + bool cmp_bit_present; + uint8_t cmp; + + /* Sector/block protection bit (SEC) */ + bool sec_bit_present; + uint8_t sec; + + /* Top/bottom protection bit (TB) */ + bool tb_bit_present; + uint8_t tb; + + /* Block protection bits (BP) */ + size_t bp_bit_count; + uint8_t bp[MAX_BP_BITS]; +}; + +struct flashrom_flashctx; + +/* Write WP configuration to the chip */ +enum flashrom_wp_result wp_write_cfg(struct flashrom_flashctx *, const struct flashrom_wp_cfg *); + +/* Read WP configuration from the chip */ +enum flashrom_wp_result wp_read_cfg(struct flashrom_wp_cfg *, struct flashrom_flashctx *); + +/* Get a list of protection ranges supported by the chip */ +enum flashrom_wp_result wp_get_available_ranges(struct flashrom_wp_ranges **, struct flashrom_flashctx *); + +#endif /* !__WRITEPROTECT_H__ */ -- cgit v1.2.3