Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support.
This code is totally untested and may fry your flash chip, explode mysteriously and abduct your dog. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Logs from "flashrom -V" on all newer Nvidia nForce chipsets appreciated.
This patch depends on my RayeR SPIPGM patch I sent a few minutes ago, Message-ID: 4BFDBD86.1020100@gmx.net and available at http://patchwork.coreboot.org/patch/1401/ The code will be compiled in automatically if the internal programmer is enabled (which is the default).
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
diff generated by interdiff diff -u flashrom-bitbang_spi_rayer/flash.h flashrom-bitbang_spi_nvidia_mcp/flash.h --- flashrom-bitbang_spi_rayer/flash.h (Arbeitskopie) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -132,6 +132,11 @@ #if RAYER_BITBANG_SPI_SUPPORT == 1 BITBANG_SPI_MASTER_RAYER, #endif +#if INTERNAL_SUPPORT == 1 +#if defined(__i386__) || defined(__x86_64__) + BITBANG_SPI_MASTER_MCP, +#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
@@ -527,6 +532,18 @@ int rayer_bitbang_get_miso(void); #endif
+/* mcp6x_spi.c */ +#if INTERNAL_SUPPORT == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif + /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; @@ -633,6 +650,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO, + SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if FT2232_SPI_SUPPORT == 1 diff -u flashrom-bitbang_spi_rayer/spi25.c flashrom-bitbang_spi_nvidia_mcp/spi25.c --- flashrom-bitbang_spi_rayer/spi25.c (Arbeitskopie) +++ flashrom-bitbang_spi_nvidia_mcp/spi25.c (Arbeitskopie) @@ -178,6 +178,7 @@ case SPI_CONTROLLER_VIA: case SPI_CONTROLLER_SB600: case SPI_CONTROLLER_WBSIO: + case SPI_CONTROLLER_MCP6X_BITBANG: #endif #endif #if FT2232_SPI_SUPPORT == 1 diff -u flashrom-bitbang_spi_rayer/bitbang_spi.c flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c --- flashrom-bitbang_spi_rayer/bitbang_spi.c (Arbeitskopie) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -40,6 +40,18 @@ .get_miso = rayer_bitbang_get_miso, }, #endif + +#if INTERNAL_SUPPORT == 1 +#if defined(__i386__) || defined(__x86_64__) + { + .set_cs = mcp6x_bitbang_set_cs, + .set_sck = mcp6x_bitbang_set_sck, + .set_mosi = mcp6x_bitbang_set_mosi, + .get_miso = mcp6x_bitbang_get_miso, + }, +#endif +#endif + {}, /* This entry corresponds to SPI_BITBANG_INVALID. */ };
diff -u flashrom-bitbang_spi_rayer/spi.c flashrom-bitbang_spi_nvidia_mcp/spi.c --- flashrom-bitbang_spi_rayer/spi.c (Arbeitskopie) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -84,6 +84,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, }, + + { /* SPI_CONTROLLER_MCP6X_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, #endif #endif
diff -u flashrom-bitbang_spi_rayer/Makefile flashrom-bitbang_spi_nvidia_mcp/Makefile --- flashrom-bitbang_spi_rayer/Makefile (Arbeitskopie) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -92,8 +92,12 @@ ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) CONFIG_BITBANG_SPI = yes else +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no endif +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -133,7 +137,7 @@ FEATURE_CFLAGS += -D'INTERNAL_SUPPORT=1' PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
only in patch2: unchanged: --- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1013) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1063,10 +1063,8 @@ { int ret = 0; uint8_t val; - uint16_t status; char *busname; - uint32_t mcp_spibaraddr; - void *mcp_spibar; + uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n"); @@ -1115,40 +1113,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */ - mcp_spibaraddr = pci_read_long(smbusdev, 0x74); - msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr); + mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74); + msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface (well, * a set of GPIOs that is connected to SPI flash) is at offset 0x530, * so we expect a size of at least 0x800. Clear the lower bits. * It is entirely possible that the BAR is 64k big and the low bits are * reserved for an entirely different purpose. */ - mcp_spibaraddr &= ~0x7ff; - msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr); + mcp6x_spibaraddr &= ~0x7ff; + msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */ - if (mcp_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { + if (mcp6x_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ - mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544); + mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1 << 1) -#define MCP67_SPI_SCK (1 << 2) -#define MCP67_SPI_MOSI (1 << 3) -#define MCP67_SPI_MISO (1 << 4) -#define MCP67_SPI_ENABLE (1 << 0) -#define MCP67_SPI_IDLE (1 << 8) - - status = mmio_readw(mcp_spibar + 0x530); - msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", - status, status & 0x1, (status >> 8) & 0x1); + if (mcp6x_spi_init()) + ret = 1; +#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */ - physunmap(mcp_spibar, 0x544); - } else if (!mcp_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { + physunmap(mcp6x_spibar, 0x544); +#endif + } else if (!mcp6x_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported &= ~CHIP_BUSTYPE_SPI; ret = 1; - } else if (mcp_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { + } else if (mcp6x_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else { @@ -1186,8 +1177,7 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type detection.\n"); @@ -1212,8 +1202,7 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type detection.\n"); only in patch2: unchanged: --- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller. + * Based on clean room reverse engineered docs from + * http://www.flashrom.org/pipermail/flashrom/2009-December/001180.html + * created by Michael Karcher. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h" + +/* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + */ + +/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8 + +void *mcp6x_spibar = NULL; + +void mcp6x_request_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte |= 1 << MCP6X_SPI_ENABLE; + mmio_writeb(byte, mcp6x_spibar + 0x530); + + /* Wait until we are allowed to use the SPI bus. */ + while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_IDLE))) ; +} + +void mcp6x_release_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_ENABLE); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_cs(int val) +{ + uint8_t byte; + + /* Requesting and releasing the SPI bus is handled in here to allow the + * chipset to use its own SPI engine for native reads. + */ + if (val == 1) + mcp6x_request_spibus(); + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_CS); + byte |= (val << MCP6X_SPI_CS); + mmio_writeb(byte, mcp6x_spibar + 0x530); + + if (val == 0) + mcp6x_release_spibus(); +} + +void mcp6x_bitbang_set_sck(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_SCK); + byte |= (val << MCP6X_SPI_SCK); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_mosi(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_MOSI); + byte |= (val << MCP6X_SPI_MOSI); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +int mcp6x_bitbang_get_miso(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte = (byte >> MCP6X_SPI_MISO) & 0x1; + return byte; +} + +int mcp6x_spi_init(void) +{ + uint16_t status; + + status = mmio_readw(mcp6x_spibar + 0x530); + msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", + status, (status >> MCP6X_SPI_ENABLE) & 0x1, + (status >> MCP6X_SPI_IDLE) & 0x1); + + if (bitbang_spi_init()) + return 1; + spi_controller = SPI_CONTROLLER_MCP6X_BITBANG; + + return 0; +} + +#endif
On 27.05.2010 02:43, Carl-Daniel Hailfinger wrote:
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support.
This code is totally untested and may fry your flash chip, explode mysteriously and abduct your dog. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Logs from "flashrom -V" on all newer Nvidia nForce chipsets appreciated.
This patch includes the RayeR SPIPGM code as well because they depend on each other.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-bitbang_spi_nvidia_mcp/flash.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/flash.h (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -81,6 +81,9 @@ #if CONFIG_DEDIPROG == 1 PROGRAMMER_DEDIPROG, #endif +#if CONFIG_RAYER_BITBANG_SPI == 1 + PROGRAMMER_RAYER_BITBANG_SPI, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -128,13 +131,19 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if CONFIG_RAYER_BITBANG_SPI == 1 + BITBANG_SPI_MASTER_RAYER, +#endif +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + BITBANG_SPI_MASTER_MCP, +#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
extern const int bitbang_spi_master_count;
-extern enum bitbang_spi_master bitbang_spi_master; - struct bitbang_spi_master_entry { void (*set_cs) (int val); void (*set_sck) (int val); @@ -529,10 +538,31 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* rayer_bitbang_spi.c */ +#if CONFIG_RAYER_BITBANG_SPI == 1 +int rayer_bitbang_spi_init(void); +void rayer_bitbang_set_cs(int val); +void rayer_bitbang_set_sck(int val); +void rayer_bitbang_set_mosi(int val); +int rayer_bitbang_get_miso(void); +#endif + +/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif + /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; -int bitbang_spi_init(void); +int bitbang_spi_init(enum bitbang_spi_master master); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -635,6 +665,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO, + SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if CONFIG_FT2232_SPI == 1 @@ -649,6 +680,9 @@ #if CONFIG_DEDIPROG == 1 SPI_CONTROLLER_DEDIPROG, #endif +#if CONFIG_RAYER_BITBANG_SPI == 1 + SPI_CONTROLLER_RAYER_BITBANG, +#endif SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; Index: flashrom-bitbang_spi_nvidia_mcp/hwaccess.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Arbeitskopie) @@ -169,6 +169,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order: + * OUT[BWL](val, port) + */ + #if defined(__FreeBSD__) || defined(__DragonFly__) #include <machine/cpufunc.h> #define off64_t off_t Index: flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -32,11 +32,32 @@ enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { - {}, /* This entry corresponds to BITBANG_SPI_INVALID. */ +#if CONFIG_RAYER_BITBANG_SPI == 1 + { + .set_cs = rayer_bitbang_set_cs, + .set_sck = rayer_bitbang_set_sck, + .set_mosi = rayer_bitbang_set_mosi, + .get_miso = rayer_bitbang_get_miso, + }, +#endif + +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + { + .set_cs = mcp6x_bitbang_set_cs, + .set_sck = mcp6x_bitbang_set_sck, + .set_mosi = mcp6x_bitbang_set_mosi, + .get_miso = mcp6x_bitbang_get_miso, + }, +#endif +#endif + + {}, /* This entry corresponds to SPI_BITBANG_INVALID. */ };
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -57,10 +78,18 @@ return bitbang_spi_master_table[bitbang_spi_master].get_miso(); }
-int bitbang_spi_init(void) +int bitbang_spi_init(enum bitbang_spi_master master) { + bitbang_spi_master = master; + + if (bitbang_spi_master == BITBANG_SPI_INVALID) { + msg_perr("Invalid bitbang SPI master. \n" + "Please report a bug at flashrom@flashrom.org\n"); + return 1; + } bitbang_spi_set_cs(1); bitbang_spi_set_sck(0); + bitbang_spi_set_mosi(0); buses_supported = CHIP_BUSTYPE_SPI; return 0; } @@ -87,6 +116,7 @@ { static unsigned char *bufout = NULL; static unsigned char *bufin = NULL; + unsigned char *tmp; static int oldbufsize = 0; int bufsize; int i; @@ -98,20 +128,34 @@ bufsize = max(writecnt + readcnt, 260); /* Never shrink. realloc() calls are expensive. */ if (bufsize > oldbufsize) { - bufout = realloc(bufout, bufsize); - if (!bufout) { + tmp = realloc(bufout, bufsize); + if (!tmp) { msg_perr("Out of memory!\n"); + if (bufout) + free(bufout); + bufout = NULL; if (bufin) free(bufin); + bufin = NULL; + oldbufsize = 0; exit(1); - } - bufin = realloc(bufout, bufsize); - if (!bufin) { + } else + bufout = tmp; + + tmp = realloc(bufin, bufsize); + if (!tmp) { msg_perr("Out of memory!\n"); + if (bufin) + free(bufin); + bufin = NULL; if (bufout) free(bufout); + bufout = NULL; + oldbufsize = 0; exit(1); - } + } else + bufin = tmp; + oldbufsize = bufsize; } @@ -135,8 +179,13 @@
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { - /* Maximum read length is unlimited, use 64k bytes. */ - return spi_read_chunked(flash, buf, start, len, 64 * 1024); + /* Maximum read length is unlimited in theory. + * The current implementation can handle reads of up to 65536 bytes. + * Please note that you need two buffers of 2n+4 bytes each for a read + * of n bytes, resulting in a total memory requirement of 4n+8 bytes. + * To conserve memory, read in chunks of 256 bytes. + */ + return spi_read_chunked(flash, buf, start, len, 256); }
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf) Index: flashrom-bitbang_spi_nvidia_mcp/Makefile =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -107,8 +107,19 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# RayeR SPIPGM hardware support +CONFIG_RAYER_BITBANG_SPI ?= yes + +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) +CONFIG_BITBANG_SPI = yes +else +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -151,7 +162,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
@@ -162,6 +173,13 @@ NEED_NET := yes endif
+ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) +FEATURE_CFLAGS += -D'CONFIG_RAYER_BITBANG_SPI=1' +PROGRAMMER_OBJS += rayer_bitbang_spi.o +# Actually, NEED_PCI is wrong. NEED_IOPORT_ACCESS would be more correct. +NEED_PCI := yes +endif + ifeq ($(CONFIG_BITBANG_SPI), yes) FEATURE_CFLAGS += -D'CONFIG_BITBANG_SPI=1' PROGRAMMER_OBJS += bitbang_spi.o Index: flashrom-bitbang_spi_nvidia_mcp/spi25.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi25.c (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/spi25.c (Arbeitskopie) @@ -178,6 +178,7 @@ case SPI_CONTROLLER_VIA: case SPI_CONTROLLER_SB600: case SPI_CONTROLLER_WBSIO: + case SPI_CONTROLLER_MCP6X_BITBANG: #endif #endif #if CONFIG_FT2232_SPI == 1 @@ -192,6 +193,9 @@ #if CONFIG_DEDIPROG == 1 case SPI_CONTROLLER_DEDIPROG: #endif +#if CONFIG_RAYER_BITBANG_SPI == 1 + case SPI_CONTROLLER_RAYER_BITBANG: +#endif return probe_spi_rdid_generic(flash, 4); default: msg_cinfo("4b ID not supported on this SPI controller\n"); Index: flashrom-bitbang_spi_nvidia_mcp/spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -83,6 +83,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, }, + + { /* SPI_CONTROLLER_MCP6X_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, #endif #endif
@@ -122,6 +129,15 @@ }, #endif
+#if CONFIG_RAYER_BITBANG_SPI == 1 + { /* SPI_CONTROLLER_RAYER_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, +#endif + {}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ };
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1092,10 +1092,8 @@ { int ret = 0; uint8_t val; - uint16_t status; char *busname; - uint32_t mcp_spibaraddr; - void *mcp_spibar; + uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n"); @@ -1144,40 +1142,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */ - mcp_spibaraddr = pci_read_long(smbusdev, 0x74); - msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr); + mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74); + msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface (well, * a set of GPIOs that is connected to SPI flash) is at offset 0x530, * so we expect a size of at least 0x800. Clear the lower bits. * It is entirely possible that the BAR is 64k big and the low bits are * reserved for an entirely different purpose. */ - mcp_spibaraddr &= ~0x7ff; - msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr); + mcp6x_spibaraddr &= ~0x7ff; + msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */ - if (mcp_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { + if (mcp6x_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ - mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544); + mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1 << 1) -#define MCP67_SPI_SCK (1 << 2) -#define MCP67_SPI_MOSI (1 << 3) -#define MCP67_SPI_MISO (1 << 4) -#define MCP67_SPI_ENABLE (1 << 0) -#define MCP67_SPI_IDLE (1 << 8) - - status = mmio_readw(mcp_spibar + 0x530); - msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", - status, status & 0x1, (status >> 8) & 0x1); + if (mcp6x_spi_init()) + ret = 1; +#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */ - physunmap(mcp_spibar, 0x544); - } else if (!mcp_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { + physunmap(mcp6x_spibar, 0x544); +#endif + } else if (!mcp6x_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported &= ~CHIP_BUSTYPE_SPI; ret = 1; - } else if (mcp_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { + } else if (mcp6x_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else { @@ -1215,8 +1206,7 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type detection.\n"); @@ -1241,8 +1231,7 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type detection.\n"); Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller. + * Based on clean room reverse engineered docs from + * http://www.flashrom.org/pipermail/flashrom/2009-December/001180.html + * created by Michael Karcher. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h" + +/* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + */ + +/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8 + +void *mcp6x_spibar = NULL; + +void mcp6x_request_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte |= 1 << MCP6X_SPI_ENABLE; + mmio_writeb(byte, mcp6x_spibar + 0x530); + + /* Wait until we are allowed to use the SPI bus. */ + while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_IDLE))) ; +} + +void mcp6x_release_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_ENABLE); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_cs(int val) +{ + uint8_t byte; + + /* Requesting and releasing the SPI bus is handled in here to allow the + * chipset to use its own SPI engine for native reads. + */ + if (val == 1) + mcp6x_request_spibus(); + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_CS); + byte |= (val << MCP6X_SPI_CS); + mmio_writeb(byte, mcp6x_spibar + 0x530); + + if (val == 0) + mcp6x_release_spibus(); +} + +void mcp6x_bitbang_set_sck(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_SCK); + byte |= (val << MCP6X_SPI_SCK); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_mosi(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_MOSI); + byte |= (val << MCP6X_SPI_MOSI); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +int mcp6x_bitbang_get_miso(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte = (byte >> MCP6X_SPI_MISO) & 0x1; + return byte; +} + +int mcp6x_spi_init(void) +{ + uint16_t status; + + status = mmio_readw(mcp6x_spibar + 0x530); + msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", + status, (status >> MCP6X_SPI_ENABLE) & 0x1, + (status >> MCP6X_SPI_IDLE) & 0x1); + + if (bitbang_spi_init(BITBANG_SPI_MASTER_MCP)) + return 1; + spi_controller = SPI_CONTROLLER_MCP6X_BITBANG; + + return 0; +} + +#endif Index: flashrom-bitbang_spi_nvidia_mcp/flashrom.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/flashrom.c (Revision 1048) +++ flashrom-bitbang_spi_nvidia_mcp/flashrom.c (Arbeitskopie) @@ -48,7 +48,7 @@ * if more than one of them is selected. If only one is selected, it is clear * that the user wants that one to become the default. */ -#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG > 1 +#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG+CONFIG_RAYER_BITBANG_SPI > 1 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all programmers except one. #endif enum programmer programmer = @@ -86,6 +86,9 @@ #if CONFIG_DEDIPROG == 1 PROGRAMMER_DEDIPROG #endif +#if CONFIG_RAYER_BITBANG_SPI == 1 + PROGRAMMER_RAYER_BITBANG_SPI +#endif ; #endif
@@ -394,6 +397,25 @@ }, #endif
+#if CONFIG_RAYER_BITBANG_SPI == 1 + { + .name = "rayer_bitbang_spi", + .init = rayer_bitbang_spi_init, + .shutdown = noop_shutdown, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, + .chip_readb = noop_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = noop_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .delay = internal_delay, + }, +#endif + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
Index: flashrom-bitbang_spi_nvidia_mcp/rayer_bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/rayer_bitbang_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/rayer_bitbang_spi.c (Revision 0) @@ -0,0 +1,112 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009,2010 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the SPIPGM hardware by "RayeR" Martin Rehak. + * See http://rayer.ic.cz/elektro/spipgm.htm for schematics and instructions. + */ + +/* This driver uses non-portable direct I/O port accesses which won't work on + * any non-x86 platform, and even on x86 there is a high chance there will be + * collisions with any loaded parallel port drivers. + * The big advantage of direct port I/O is OS independence and speed because + * most OS parport drivers will perform many unnecessary accesses although + * this driver just treats the parallel port as a GPIO set. + */ +#if defined(__i386__) || defined(__x86_64__) + +#include "flash.h" + +/* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + */ +/* Pins for master->slave direction */ +#define SPI_CS_PIN 5 +#define SPI_SCK_PIN 6 +#define SPI_MOSI_PIN 7 +/* Pins for slave->master direction */ +#define SPI_MISO_PIN 6 + +static int lpt_iobase; + +/* FIXME: All rayer_bitbang_set_* functions could use caching of the value + * stored at port lpt_iobase to avoid unnecessary INB. In theory, only one + * INB(lpt_iobase) would be needed on programmer init to get the initial + * value. + */ + +void rayer_bitbang_set_cs(int val) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase); + tmp &= ~(1 << SPI_CS_PIN); + tmp |= (val << SPI_CS_PIN); + OUTB(tmp, lpt_iobase); +} + +void rayer_bitbang_set_sck(int val) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase); + tmp &= ~(1 << SPI_SCK_PIN); + tmp |= (val << SPI_SCK_PIN); + OUTB(tmp, lpt_iobase); +} + +void rayer_bitbang_set_mosi(int val) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase); + tmp &= ~(1 << SPI_MOSI_PIN); + tmp |= (val << SPI_MOSI_PIN); + OUTB(tmp, lpt_iobase); +} + +int rayer_bitbang_get_miso(void) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase + 1); + tmp = (tmp >> SPI_MISO_PIN) & 0x1; + return tmp; +} + +int rayer_bitbang_spi_init(void) +{ + /* Pick a default value for now. */ + lpt_iobase = 0x378; + + msg_pdbg("Using port 0x%x as I/O base for parallel port access.\n", + lpt_iobase); + + get_io_perms(); + + if (bitbang_spi_init(BITBANG_SPI_MASTER_RAYER)) + return 1; + + spi_controller = SPI_CONTROLLER_RAYER_BITBANG; + + return 0; +} + +#else +#error PCI port I/O access is not supported on this architecture yet. +#endif
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support. Fix a few problems in the previously unused SPI bitbanging core.
This code is untested and may fry your flash chip, explode mysteriously and abduct your dog. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Logs from "flashrom -V" on all newer Nvidia nForce chipsets appreciated.
Huge thanks go to Michael Karcher for reverse engineering the interface and to Johannes Sjolund for testing multiple iterations of my patch on his hardware until it worked.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Johannes, you can also find this patch near the top at http://patchwork.coreboot.org/project/flashrom/list/ in case your mailer corrupts the patch. It applies against latest clean svn.
Index: flashrom-bitbang_spi_nvidia_mcp/flash.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/flash.h (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -128,13 +128,16 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + BITBANG_SPI_MASTER_MCP, +#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
extern const int bitbang_spi_master_count;
-extern enum bitbang_spi_master bitbang_spi_master; - struct bitbang_spi_master_entry { void (*set_cs) (int val); void (*set_sck) (int val); @@ -529,10 +532,22 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif + /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; -int bitbang_spi_init(void); +int bitbang_spi_init(enum bitbang_spi_master master); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -635,6 +650,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO, + SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if CONFIG_FT2232_SPI == 1 Index: flashrom-bitbang_spi_nvidia_mcp/spi25.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi25.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/spi25.c (Arbeitskopie) @@ -178,6 +178,7 @@ case SPI_CONTROLLER_VIA: case SPI_CONTROLLER_SB600: case SPI_CONTROLLER_WBSIO: + case SPI_CONTROLLER_MCP6X_BITBANG: #endif #endif #if CONFIG_FT2232_SPI == 1 Index: flashrom-bitbang_spi_nvidia_mcp/hwaccess.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Arbeitskopie) @@ -169,6 +169,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order: + * OUT[BWL](val, port) + */ + #if defined(__FreeBSD__) || defined(__DragonFly__) #include <machine/cpufunc.h> #define off64_t off_t Index: flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -26,17 +26,29 @@ #include "chipdrivers.h" #include "spi.h"
-/* Length of half a clock period in usecs */ -int bitbang_spi_half_period = 0; +/* Length of half a clock period in usecs. Default to 1 (500 kHz). */ +int bitbang_spi_half_period = 1;
enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + { + .set_cs = mcp6x_bitbang_set_cs, + .set_sck = mcp6x_bitbang_set_sck, + .set_mosi = mcp6x_bitbang_set_mosi, + .get_miso = mcp6x_bitbang_get_miso, + }, +#endif +#endif + {}, /* This entry corresponds to BITBANG_SPI_INVALID. */ };
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -57,10 +69,18 @@ return bitbang_spi_master_table[bitbang_spi_master].get_miso(); }
-int bitbang_spi_init(void) +int bitbang_spi_init(enum bitbang_spi_master master) { + bitbang_spi_master = master; + + if (bitbang_spi_master == BITBANG_SPI_INVALID) { + msg_perr("Invalid bitbang SPI master. \n" + "Please report a bug at flashrom@flashrom.org\n"); + return 1; + } bitbang_spi_set_cs(1); bitbang_spi_set_sck(0); + bitbang_spi_set_mosi(0); buses_supported = CHIP_BUSTYPE_SPI; return 0; } @@ -87,6 +107,7 @@ { static unsigned char *bufout = NULL; static unsigned char *bufin = NULL; + unsigned char *tmp; static int oldbufsize = 0; int bufsize; int i; @@ -98,20 +119,34 @@ bufsize = max(writecnt + readcnt, 260); /* Never shrink. realloc() calls are expensive. */ if (bufsize > oldbufsize) { - bufout = realloc(bufout, bufsize); - if (!bufout) { + tmp = realloc(bufout, bufsize); + if (!tmp) { msg_perr("Out of memory!\n"); + if (bufout) + free(bufout); + bufout = NULL; if (bufin) free(bufin); + bufin = NULL; + oldbufsize = 0; exit(1); - } - bufin = realloc(bufout, bufsize); - if (!bufin) { + } else + bufout = tmp; + + tmp = realloc(bufin, bufsize); + if (!tmp) { msg_perr("Out of memory!\n"); + if (bufin) + free(bufin); + bufin = NULL; if (bufout) free(bufout); + bufout = NULL; + oldbufsize = 0; exit(1); - } + } else + bufin = tmp; + oldbufsize = bufsize; } @@ -135,8 +170,13 @@
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { - /* Maximum read length is unlimited, use 64k bytes. */ - return spi_read_chunked(flash, buf, start, len, 64 * 1024); + /* Maximum read length is unlimited in theory. + * The current implementation can handle reads of up to 65536 bytes. + * Please note that you need two buffers of 2n+4 bytes each for a read + * of n bytes, resulting in a total memory requirement of 4n+8 bytes. + * To conserve memory, read in chunks of 256 bytes. + */ + return spi_read_chunked(flash, buf, start, len, 256); }
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf) Index: flashrom-bitbang_spi_nvidia_mcp/spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -83,6 +83,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, }, + + { /* SPI_CONTROLLER_MCP6X_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, #endif #endif
Index: flashrom-bitbang_spi_nvidia_mcp/Makefile =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -107,8 +107,12 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -151,7 +155,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1092,10 +1092,8 @@ { int ret = 0; uint8_t val; - uint16_t status; char *busname; - uint32_t mcp_spibaraddr; - void *mcp_spibar; + uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n"); @@ -1144,40 +1142,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */ - mcp_spibaraddr = pci_read_long(smbusdev, 0x74); - msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr); + mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74); + msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface (well, * a set of GPIOs that is connected to SPI flash) is at offset 0x530, * so we expect a size of at least 0x800. Clear the lower bits. * It is entirely possible that the BAR is 64k big and the low bits are * reserved for an entirely different purpose. */ - mcp_spibaraddr &= ~0x7ff; - msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr); + mcp6x_spibaraddr &= ~0x7ff; + msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */ - if (mcp_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { + if (mcp6x_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ - mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544); + mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1 << 1) -#define MCP67_SPI_SCK (1 << 2) -#define MCP67_SPI_MOSI (1 << 3) -#define MCP67_SPI_MISO (1 << 4) -#define MCP67_SPI_ENABLE (1 << 0) -#define MCP67_SPI_IDLE (1 << 8) - - status = mmio_readw(mcp_spibar + 0x530); - msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", - status, status & 0x1, (status >> 8) & 0x1); + if (mcp6x_spi_init()) + ret = 1; +#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */ - physunmap(mcp_spibar, 0x544); - } else if (!mcp_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { + physunmap(mcp6x_spibar, 0x544); +#endif + } else if (!mcp6x_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported &= ~CHIP_BUSTYPE_SPI; ret = 1; - } else if (mcp_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { + } else if (mcp6x_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else { @@ -1215,8 +1206,7 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type detection.\n"); @@ -1241,8 +1231,7 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type detection.\n"); Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller. + * Based on clean room reverse engineered docs from + * http://www.flashrom.org/pipermail/flashrom/2009-December/001180.html + * created by Michael Karcher. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h" + +/* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + */ + +/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8 + +void *mcp6x_spibar = NULL; + +void mcp6x_request_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte |= 1 << MCP6X_SPI_ENABLE; + mmio_writeb(byte, mcp6x_spibar + 0x530); + + /* Wait until we are allowed to use the SPI bus. */ + while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_IDLE))) ; +} + +void mcp6x_release_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_ENABLE); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_cs(int val) +{ + uint8_t byte; + + /* Requesting and releasing the SPI bus is handled in here to allow the + * chipset to use its own SPI engine for native reads. + */ + if (val == 0) + mcp6x_request_spibus(); + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_CS); + byte |= (val << MCP6X_SPI_CS); + mmio_writeb(byte, mcp6x_spibar + 0x530); + + if (val == 1) + mcp6x_release_spibus(); +} + +void mcp6x_bitbang_set_sck(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_SCK); + byte |= (val << MCP6X_SPI_SCK); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_mosi(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_MOSI); + byte |= (val << MCP6X_SPI_MOSI); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +int mcp6x_bitbang_get_miso(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte = (byte >> MCP6X_SPI_MISO) & 0x1; + return byte; +} + +int mcp6x_spi_init(void) +{ + uint16_t status; + + status = mmio_readw(mcp6x_spibar + 0x530); + msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", + status, (status >> MCP6X_SPI_ENABLE) & 0x1, + (status >> MCP6X_SPI_IDLE) & 0x1); + + if (bitbang_spi_init(BITBANG_SPI_MASTER_MCP)) + return 1; + spi_controller = SPI_CONTROLLER_MCP6X_BITBANG; + + return 0; +} + +#endif
Applied patch, log attached. Is it me or does that look like it found the chip?! :)
Tested reading too. The resulting 1MB file is very similar to the downloaded BIOS. (Not the same due to MAC address, serial number/s and other similar settings.)
I also applied the patch and tested. See the attached log.
On Thu, Jun 17, 2010 at 4:37 AM, Carl-Daniel Hailfinger < c-d.hailfinger.devel.2006@gmx.net> wrote:
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support. Fix a few problems in the previously unused SPI bitbanging core.
This code is untested and may fry your flash chip, explode mysteriously and abduct your dog. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Logs from "flashrom -V" on all newer Nvidia nForce chipsets appreciated.
Huge thanks go to Michael Karcher for reverse engineering the interface and to Johannes Sjolund for testing multiple iterations of my patch on his hardware until it worked.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Johannes, you can also find this patch near the top at http://patchwork.coreboot.org/project/flashrom/list/ in case your mailer corrupts the patch. It applies against latest clean svn.
Index: flashrom-bitbang_spi_nvidia_mcp/flash.h
--- flashrom-bitbang_spi_nvidia_mcp/flash.h (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -128,13 +128,16 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__)
BITBANG_SPI_MASTER_MCP,
+#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
extern const int bitbang_spi_master_count;
-extern enum bitbang_spi_master bitbang_spi_master;
struct bitbang_spi_master_entry { void (*set_cs) (int val); void (*set_sck) (int val); @@ -529,10 +532,22 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif
/* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; -int bitbang_spi_init(void); +int bitbang_spi_init(enum bitbang_spi_master master); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -635,6 +650,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO,
SPI_CONTROLLER_MCP6X_BITBANG,
#endif #endif #if CONFIG_FT2232_SPI == 1 Index: flashrom-bitbang_spi_nvidia_mcp/spi25.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi25.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/spi25.c (Arbeitskopie) @@ -178,6 +178,7 @@ case SPI_CONTROLLER_VIA: case SPI_CONTROLLER_SB600: case SPI_CONTROLLER_WBSIO:
case SPI_CONTROLLER_MCP6X_BITBANG:
#endif #endif #if CONFIG_FT2232_SPI == 1 Index: flashrom-bitbang_spi_nvidia_mcp/hwaccess.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Arbeitskopie) @@ -169,6 +169,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order:
- OUT[BWL](val, port)
- */
#if defined(__FreeBSD__) || defined(__DragonFly__) #include <machine/cpufunc.h> #define off64_t off_t Index: flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -26,17 +26,29 @@ #include "chipdrivers.h" #include "spi.h"
-/* Length of half a clock period in usecs */ -int bitbang_spi_half_period = 0; +/* Length of half a clock period in usecs. Default to 1 (500 kHz). */ +int bitbang_spi_half_period = 1;
enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__)
{
.set_cs = mcp6x_bitbang_set_cs,
.set_sck = mcp6x_bitbang_set_sck,
.set_mosi = mcp6x_bitbang_set_mosi,
.get_miso = mcp6x_bitbang_get_miso,
},
+#endif +#endif
{}, /* This entry corresponds to BITBANG_SPI_INVALID. */
};
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -57,10 +69,18 @@ return bitbang_spi_master_table[bitbang_spi_master].get_miso(); }
-int bitbang_spi_init(void) +int bitbang_spi_init(enum bitbang_spi_master master) {
bitbang_spi_master = master;
if (bitbang_spi_master == BITBANG_SPI_INVALID) {
msg_perr("Invalid bitbang SPI master. \n"
"Please report a bug at flashrom@flashrom.org
\n");
return 1;
} bitbang_spi_set_cs(1); bitbang_spi_set_sck(0);
bitbang_spi_set_mosi(0); buses_supported = CHIP_BUSTYPE_SPI; return 0;
} @@ -87,6 +107,7 @@ { static unsigned char *bufout = NULL; static unsigned char *bufin = NULL;
unsigned char *tmp; static int oldbufsize = 0; int bufsize; int i;
@@ -98,20 +119,34 @@ bufsize = max(writecnt + readcnt, 260); /* Never shrink. realloc() calls are expensive. */ if (bufsize > oldbufsize) {
bufout = realloc(bufout, bufsize);
if (!bufout) {
tmp = realloc(bufout, bufsize);
if (!tmp) { msg_perr("Out of memory!\n");
if (bufout)
free(bufout);
bufout = NULL; if (bufin) free(bufin);
bufin = NULL;
oldbufsize = 0; exit(1);
}
bufin = realloc(bufout, bufsize);
if (!bufin) {
} else
bufout = tmp;
tmp = realloc(bufin, bufsize);
if (!tmp) { msg_perr("Out of memory!\n");
if (bufin)
free(bufin);
bufin = NULL; if (bufout) free(bufout);
bufout = NULL;
oldbufsize = 0; exit(1);
}
} else
bufin = tmp;
oldbufsize = bufsize; }
@@ -135,8 +170,13 @@
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) {
/* Maximum read length is unlimited, use 64k bytes. */
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
/* Maximum read length is unlimited in theory.
* The current implementation can handle reads of up to 65536
bytes.
* Please note that you need two buffers of 2n+4 bytes each for a
read
* of n bytes, resulting in a total memory requirement of 4n+8
bytes.
* To conserve memory, read in chunks of 256 bytes.
*/
return spi_read_chunked(flash, buf, start, len, 256);
}
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf) Index: flashrom-bitbang_spi_nvidia_mcp/spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -83,6 +83,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, },
{ /* SPI_CONTROLLER_MCP6X_BITBANG */
.command = bitbang_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = bitbang_spi_read,
.write_256 = bitbang_spi_write_256,
},
#endif #endif
Index: flashrom-bitbang_spi_nvidia_mcp/Makefile
--- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -107,8 +107,12 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -151,7 +155,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c
--- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1049) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1092,10 +1092,8 @@ { int ret = 0; uint8_t val;
uint16_t status; char *busname;
uint32_t mcp_spibaraddr;
void *mcp_spibar;
uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev; msg_pinfo("This chipset is not really supported yet.
Guesswork...\n"); @@ -1144,40 +1142,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */
mcp_spibaraddr = pci_read_long(smbusdev, 0x74);
msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr);
mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74);
msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface
(well, * a set of GPIOs that is connected to SPI flash) is at offset 0x530, * so we expect a size of at least 0x800. Clear the lower bits. * It is entirely possible that the BAR is 64k big and the low bits are * reserved for an entirely different purpose. */
mcp_spibaraddr &= ~0x7ff;
msg_pdbg("after clearing low bits BAR is at 0x%08x\n",
mcp_spibaraddr);
mcp6x_spibaraddr &= ~0x7ff;
msg_pdbg("after clearing low bits BAR is at 0x%08x\n",
mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */
if (mcp_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) {
if (mcp6x_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540.
*/
mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544);
mcp6x_spibar = physmap("Nvidia MCP6x SPI",
mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1 << 1) -#define MCP67_SPI_SCK (1 << 2) -#define MCP67_SPI_MOSI (1 << 3) -#define MCP67_SPI_MISO (1 << 4) -#define MCP67_SPI_ENABLE (1 << 0) -#define MCP67_SPI_IDLE (1 << 8)
status = mmio_readw(mcp_spibar + 0x530);
msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n",
status, status & 0x1, (status >> 8) & 0x1);
if (mcp6x_spi_init())
ret = 1;
+#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */
physunmap(mcp_spibar, 0x544);
} else if (!mcp_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI))
{
physunmap(mcp6x_spibar, 0x544);
+#endif
} else if (!mcp6x_spibaraddr && (buses_supported &
CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported &= ~CHIP_BUSTYPE_SPI; ret = 1;
} else if (mcp_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI))
{
} else if (mcp6x_spibaraddr && !(buses_supported &
CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else { @@ -1215,8 +1206,7 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI:
msg_pinfo("SPI on this chipset is not supported yet.\n");
buses_supported = CHIP_BUSTYPE_NONE;
msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type
detection.\n"); @@ -1241,8 +1231,7 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI:
msg_pinfo("SPI on this chipset is not supported yet.\n");
buses_supported = CHIP_BUSTYPE_NONE;
msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); break; default: msg_pinfo("Something went wrong with bus type
detection.\n"); Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/*
- This file is part of the flashrom project.
- Copyright (C) 2010 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.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
- */
+/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller.
- Based on clean room reverse engineered docs from
- created by Michael Karcher.
- */
+#if defined(__i386__) || defined(__x86_64__)
+#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h"
+/* We have two sets of pins, out and in. The numbers for both sets are
- independent and are bitshift values, not real pin numbers.
- */
+/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8
+void *mcp6x_spibar = NULL;
+void mcp6x_request_spibus(void) +{
uint8_t byte;
byte = mmio_readb(mcp6x_spibar + 0x530);
byte |= 1 << MCP6X_SPI_ENABLE;
mmio_writeb(byte, mcp6x_spibar + 0x530);
/* Wait until we are allowed to use the SPI bus. */
while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_IDLE)))
; +}
+void mcp6x_release_spibus(void) +{
uint8_t byte;
byte = mmio_readb(mcp6x_spibar + 0x530);
byte &= ~(1 << MCP6X_SPI_ENABLE);
mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+void mcp6x_bitbang_set_cs(int val) +{
uint8_t byte;
/* Requesting and releasing the SPI bus is handled in here to allow
the
* chipset to use its own SPI engine for native reads.
*/
if (val == 0)
mcp6x_request_spibus();
byte = mmio_readb(mcp6x_spibar + 0x530);
byte &= ~(1 << MCP6X_SPI_CS);
byte |= (val << MCP6X_SPI_CS);
mmio_writeb(byte, mcp6x_spibar + 0x530);
if (val == 1)
mcp6x_release_spibus();
+}
+void mcp6x_bitbang_set_sck(int val) +{
uint8_t byte;
byte = mmio_readb(mcp6x_spibar + 0x530);
byte &= ~(1 << MCP6X_SPI_SCK);
byte |= (val << MCP6X_SPI_SCK);
mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+void mcp6x_bitbang_set_mosi(int val) +{
uint8_t byte;
byte = mmio_readb(mcp6x_spibar + 0x530);
byte &= ~(1 << MCP6X_SPI_MOSI);
byte |= (val << MCP6X_SPI_MOSI);
mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+int mcp6x_bitbang_get_miso(void) +{
uint8_t byte;
byte = mmio_readb(mcp6x_spibar + 0x530);
byte = (byte >> MCP6X_SPI_MISO) & 0x1;
return byte;
+}
+int mcp6x_spi_init(void) +{
uint16_t status;
status = mmio_readw(mcp6x_spibar + 0x530);
msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n",
status, (status >> MCP6X_SPI_ENABLE) & 0x1,
(status >> MCP6X_SPI_IDLE) & 0x1);
if (bitbang_spi_init(BITBANG_SPI_MASTER_MCP))
return 1;
spi_controller = SPI_CONTROLLER_MCP6X_BITBANG;
return 0;
+}
+#endif
On 17.06.2010 17:39, Johannes Sjölund wrote:
I also applied the patch and tested. See the attached log.
flashrom v0.9.2-r1049 on Linux 2.6.33-ARCH (x86_64), built with libpci 3.1.7, GCC 4.5.0 20100520 (prerelease), little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 1 usecs, 927M loops per second, 10 myus = 11 us, 100 myus = 101 us, 1000 myus = 1000 us, 10000 myus = 10003 us, 4 myus = 5 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "MSI" DMI string system-product-name: "MS-7369" DMI string system-version: "1.0" DMI string baseboard-manufacturer: "MSI" DMI string baseboard-product-name: "MS-7369" DMI string baseboard-version: "1.0" DMI string chassis-type: "Desktop" Found chipset "NVIDIA MCP65", enabling flash write... chipset PCI ID is 10de:0441, This chipset is not really supported yet. Guesswork... ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Guessed flash bus type is SPI Found SMBus device 10de:0446 at 00:01:1 SPI BAR is at 0xfec80000, after clearing low bits BAR is at 0xfec80000 SPI control is 0x0002, enable=0, idle=0 Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks. OK. This chipset supports the following protocols: SPI. [...] Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "Macronix MX25L8005" (1024 KB, SPI) at physical address 0xfff00000. [...] No operations were specified.
Thanks for the log and the testing.
Regards, Carl-Daniel
Hi,
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP61: Andrew Cleveland, Free Wind, Andre Robatino, Антон Кочков, Benjamin Henrion, Chris Yagami, Jim Lunsford MCP65: Kjell Braden, Mark Morschhäuser, Melchior FRANZ, Wolfgang Schnitker MCP67: Alessandro Polverini, NotLim MCP73: Noe, Maik Masling MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers MCP79: Alex Neblett, J.P. Krauss, Ivo Anjo, Halim Sahin, Joakim Gissberg, Benjamin Eugler
This code has been tested for probe/read for the following chipsets: MCP65: Johannes Sjölund MCP79: Andrew Morgan
Testing instructions ====================
This patch may fry your flash chip, explode mysteriously and abduct your dog, but so far it looks good. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Please apply this patch to the latest flashrom svn (subversion) tree, recompile and then run flashrom -V This command should be reasonably safe (it only tries to identify your flash chip), but if you don't have a way to recover from a bad flash, please don't try it. Then please mail the output from the command above to the flashrom mailing list (preferably as reply to this mail). Doing this on your boards with newer (last 5 years) Nvidia nForce chipsets would be highly appreciated.
You can also find this patch near the top at http://patchwork.coreboot.org/project/flashrom/list/ in case your mailer corrupts the patch. It applies against latest clean svn tree.
Patch description ================= Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support. Fix a few problems in the previously unused SPI bitbanging core.
Huge thanks go to Michael Karcher for reverse engineering the interface and to Johannes Sjölund for testing multiple iterations of my patch on his hardware until it worked.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-bitbang_spi_nvidia_mcp/flash.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/flash.h (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -128,13 +128,16 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + BITBANG_SPI_MASTER_MCP, +#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
extern const int bitbang_spi_master_count;
-extern enum bitbang_spi_master bitbang_spi_master; - struct bitbang_spi_master_entry { void (*set_cs) (int val); void (*set_sck) (int val); @@ -530,10 +533,22 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif + /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; -int bitbang_spi_init(void); +int bitbang_spi_init(enum bitbang_spi_master master); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -637,6 +652,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO, + SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if CONFIG_FT2232_SPI == 1 Index: flashrom-bitbang_spi_nvidia_mcp/hwaccess.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Arbeitskopie) @@ -176,6 +176,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order: + * OUT[BWL](val, port) + */ + #if defined(__FreeBSD__) || defined(__DragonFly__) #include <machine/cpufunc.h> #define off64_t off_t Index: flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -26,17 +26,29 @@ #include "chipdrivers.h" #include "spi.h"
-/* Length of half a clock period in usecs */ -int bitbang_spi_half_period = 0; +/* Length of half a clock period in usecs. Default to 1 (500 kHz). */ +int bitbang_spi_half_period = 1;
enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + { + .set_cs = mcp6x_bitbang_set_cs, + .set_sck = mcp6x_bitbang_set_sck, + .set_mosi = mcp6x_bitbang_set_mosi, + .get_miso = mcp6x_bitbang_get_miso, + }, +#endif +#endif + {}, /* This entry corresponds to BITBANG_SPI_INVALID. */ };
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -57,10 +69,18 @@ return bitbang_spi_master_table[bitbang_spi_master].get_miso(); }
-int bitbang_spi_init(void) +int bitbang_spi_init(enum bitbang_spi_master master) { + bitbang_spi_master = master; + + if (bitbang_spi_master == BITBANG_SPI_INVALID) { + msg_perr("Invalid bitbang SPI master. \n" + "Please report a bug at flashrom@flashrom.org\n"); + return 1; + } bitbang_spi_set_cs(1); bitbang_spi_set_sck(0); + bitbang_spi_set_mosi(0); buses_supported = CHIP_BUSTYPE_SPI; return 0; } @@ -87,6 +107,7 @@ { static unsigned char *bufout = NULL; static unsigned char *bufin = NULL; + unsigned char *tmp; static int oldbufsize = 0; int bufsize; int i; @@ -98,20 +119,34 @@ bufsize = max(writecnt + readcnt, 260); /* Never shrink. realloc() calls are expensive. */ if (bufsize > oldbufsize) { - bufout = realloc(bufout, bufsize); - if (!bufout) { + tmp = realloc(bufout, bufsize); + if (!tmp) { msg_perr("Out of memory!\n"); + if (bufout) + free(bufout); + bufout = NULL; if (bufin) free(bufin); + bufin = NULL; + oldbufsize = 0; exit(1); - } - bufin = realloc(bufout, bufsize); - if (!bufin) { + } else + bufout = tmp; + + tmp = realloc(bufin, bufsize); + if (!tmp) { msg_perr("Out of memory!\n"); + if (bufin) + free(bufin); + bufin = NULL; if (bufout) free(bufout); + bufout = NULL; + oldbufsize = 0; exit(1); - } + } else + bufin = tmp; + oldbufsize = bufsize; } @@ -135,8 +170,13 @@
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { - /* Maximum read length is unlimited, use 64k bytes. */ - return spi_read_chunked(flash, buf, start, len, 64 * 1024); + /* Maximum read length is unlimited in theory. + * The current implementation can handle reads of up to 65536 bytes. + * Please note that you need two buffers of 2n+4 bytes each for a read + * of n bytes, resulting in a total memory requirement of 4n+8 bytes. + * To conserve memory, read in chunks of 256 bytes. + */ + return spi_read_chunked(flash, buf, start, len, 256); }
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf) Index: flashrom-bitbang_spi_nvidia_mcp/spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -82,6 +82,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, }, + + { /* SPI_CONTROLLER_MCP6X_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, #endif #endif
Index: flashrom-bitbang_spi_nvidia_mcp/Makefile =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -111,8 +111,12 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -155,7 +159,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1124,10 +1124,8 @@ { int ret = 0; uint8_t val; - uint16_t status; char *busname; - uint32_t mcp_spibaraddr; - void *mcp_spibar; + uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n"); @@ -1176,40 +1174,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */ - mcp_spibaraddr = pci_read_long(smbusdev, 0x74); - msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr); + mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74); + msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface (well, * a set of GPIOs that is connected to SPI flash) is at offset 0x530, * so we expect a size of at least 0x800. Clear the lower bits. * It is entirely possible that the BAR is 64k big and the low bits are * reserved for an entirely different purpose. */ - mcp_spibaraddr &= ~0x7ff; - msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr); + mcp6x_spibaraddr &= ~0x7ff; + msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */ - if (mcp_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { + if (mcp6x_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ - mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544); + mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1 << 1) -#define MCP67_SPI_SCK (1 << 2) -#define MCP67_SPI_MOSI (1 << 3) -#define MCP67_SPI_MISO (1 << 4) -#define MCP67_SPI_ENABLE (1 << 0) -#define MCP67_SPI_IDLE (1 << 8) - - status = mmio_readw(mcp_spibar + 0x530); - msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", - status, status & 0x1, (status >> 8) & 0x1); + if (mcp6x_spi_init()) + ret = 1; +#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */ - physunmap(mcp_spibar, 0x544); - } else if (!mcp_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { + physunmap(mcp6x_spibar, 0x544); +#endif + } else if (!mcp6x_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported &= ~CHIP_BUSTYPE_SPI; ret = 1; - } else if (mcp_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { + } else if (mcp6x_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else { @@ -1247,8 +1238,8 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); + programmer_may_write = 0; break; default: msg_pinfo("Something went wrong with bus type detection.\n"); @@ -1273,8 +1264,8 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; + msg_perr("SPI on this chipset is WIP. DO NOT USE!\n"); + programmer_may_write = 0; break; default: msg_pinfo("Something went wrong with bus type detection.\n"); Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller. + * Based on clean room reverse engineered docs from + * http://www.flashrom.org/pipermail/flashrom/2009-December/001180.html + * created by Michael Karcher. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h" + +/* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + */ + +/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8 + +void *mcp6x_spibar = NULL; + +void mcp6x_request_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte |= 1 << MCP6X_SPI_ENABLE; + mmio_writeb(byte, mcp6x_spibar + 0x530); + + /* Wait until we are allowed to use the SPI bus. */ + while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_IDLE))) ; +} + +void mcp6x_release_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_ENABLE); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_cs(int val) +{ + uint8_t byte; + + /* Requesting and releasing the SPI bus is handled in here to allow the + * chipset to use its own SPI engine for native reads. + */ + if (val == 0) + mcp6x_request_spibus(); + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_CS); + byte |= (val << MCP6X_SPI_CS); + mmio_writeb(byte, mcp6x_spibar + 0x530); + + if (val == 1) + mcp6x_release_spibus(); +} + +void mcp6x_bitbang_set_sck(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_SCK); + byte |= (val << MCP6X_SPI_SCK); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +void mcp6x_bitbang_set_mosi(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_MOSI); + byte |= (val << MCP6X_SPI_MOSI); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +int mcp6x_bitbang_get_miso(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte = (byte >> MCP6X_SPI_MISO) & 0x1; + return byte; +} + +int mcp6x_spi_init(void) +{ + uint16_t status; + + status = mmio_readw(mcp6x_spibar + 0x530); + msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", + status, (status >> MCP6X_SPI_ENABLE) & 0x1, + (status >> MCP6X_SPI_IDLE) & 0x1); + + if (bitbang_spi_init(BITBANG_SPI_MASTER_MCP)) + return 1; + spi_controller = SPI_CONTROLLER_MCP6X_BITBANG; + + return 0; +} + +#endif
On 03.07.2010 15:29, Carl-Daniel Hailfinger wrote:
Please apply this patch to the latest flashrom svn (subversion) tree, recompile and then run flashrom -V This command should be reasonably safe (it only tries to identify your flash chip), but if you don't have a way to recover from a bad flash, please don't try it. Then please mail the output from the command above to the flashrom mailing list (preferably as reply to this mail). Doing this on your boards with newer (last 5 years) Nvidia nForce chipsets would be highly appreciated.
Hi,
my first mail was this: [1]
Find attached the output of "flashrom -V" after applying the patch.
HTH -Kjell
[1] http://www.flashrom.org/pipermail/flashrom/2010-May/003113.html
Hi,
Here is the output of flashrom -V with the new patch (1580), on an ECS Geforce6100SM-M. Thanks.
flashrom v0.9.2-r1069 on Linux 2.6.32-23-generic (x86_64), built with libpci 3.0.0, GCC 4.4.3, little endian
flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 2 usecs, 774M loops per second, 10 myus = 11 us, 100 myus = 98 us, 1000 myus = 964 us, 10000 myus = 10250 us, 8 myus = 9 us, OK.
Initializing internal programmer
No coreboot table found.
DMI string system-manufacturer: " "
DMI string system-product-name: " "
DMI string system-version: " "
DMI string baseboard-manufacturer: " "
DMI string baseboard-product-name: "NF-MCP61"
DMI string baseboard-version: " "
DMI string chassis-type: "Desktop"
Found ITE Super I/O, id 8726
Found chipset "NVIDIA MCP61", enabling flash write... chipset PCI ID is 10de:03e0, This chipset is not really supported yet. Guesswork...
ISA/LPC bridge reg 0x8a contents: 0x00, bit 6 is 0, bit 5 is 0
Guessed flash bus type is LPC
Found SMBus device 10de:03eb at 00:01:1
SPI BAR is at 0xfec80000, after clearing low bits BAR is at 0xfec80000
Strange. MCP SPI BAR is valid, but chipset apparently doesn't have SPI enabled.
Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks.
OK.
This chipset supports the following protocols: LPC.
SuperI/O ID 8726 is not on the controller list.
Probing for AMD Am29F010A/B, 128 KB: skipped.
Probing for AMD Am29F002(N)BB, 256 KB: skipped.
Probing for AMD Am29F002(N)BT, 256 KB: skipped.
Probing for AMD Am29F016D, 2048 KB: skipped.
Probing for AMD Am29F040B, 512 KB: skipped.
Probing for AMD Am29F080B, 1024 KB: skipped.
Probing for AMD Am29LV040B, 512 KB: skipped.
Probing for AMD Am29LV081B, 1024 KB: skipped.
Probing for ASD AE49F2008, 256 KB: skipped.
Probing for Atmel AT25DF021, 256 KB: skipped.
Probing for Atmel AT25DF041A, 512 KB: skipped.
Probing for Atmel AT25DF081, 1024 KB: skipped.
Probing for Atmel AT25DF161, 2048 KB: skipped.
Probing for Atmel AT25DF321, 4096 KB: skipped.
Probing for Atmel AT25DF321A, 4096 KB: skipped.
Probing for Atmel AT25DF641, 8192 KB: skipped.
Probing for Atmel AT25F512B, 64 KB: skipped.
Probing for Atmel AT25FS010, 128 KB: skipped.
Probing for Atmel AT25FS040, 512 KB: skipped.
Probing for Atmel AT26DF041, 512 KB: skipped.
Probing for Atmel AT26DF081A, 1024 KB: skipped.
Probing for Atmel AT26DF161, 2048 KB: skipped.
Probing for Atmel AT26DF161A, 2048 KB: skipped.
Probing for Atmel AT26F004, 512 KB: skipped.
Probing for Atmel AT29C512, 64 KB: skipped.
Probing for Atmel AT29C010A, 128 KB: skipped.
Probing for Atmel AT29C020, 256 KB: skipped.
Probing for Atmel AT29C040A, 512 KB: skipped.
Probing for Atmel AT45CS1282, 16896 KB: skipped.
Probing for Atmel AT45DB011D, 128 KB: skipped.
Probing for Atmel AT45DB021D, 256 KB: skipped.
Probing for Atmel AT45DB041D, 512 KB: skipped.
Probing for Atmel AT45DB081D, 1024 KB: skipped.
Probing for Atmel AT45DB161D, 2048 KB: skipped.
Probing for Atmel AT45DB321C, 4224 KB: skipped.
Probing for Atmel AT45DB321D, 4096 KB: skipped.
Probing for Atmel AT45DB642D, 8192 KB: skipped.
Probing for Atmel AT49BV512, 64 KB: skipped.
Probing for Atmel AT49F020, 256 KB: skipped.
Probing for Atmel AT49F002(N), 256 KB: skipped.
Probing for Atmel AT49F002(N)T, 256 KB: skipped.
Probing for AMIC A25L40PT, 512 KB: skipped.
Probing for AMIC A25L40PU, 512 KB: skipped.
Probing for AMIC A29002B, 256 KB: skipped.
Probing for AMIC A29002T, 256 KB: skipped.
Probing for AMIC A29040B, 512 KB: skipped.
Probing for AMIC A49LF040A, 512 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for EMST F49B002UA, 256 KB: skipped.
Probing for EMST F25L008A, 1024 KB: skipped.
Probing for Eon EN25B05, 64 KB: skipped.
Probing for Eon EN25B05T, 64 KB: skipped.
Probing for Eon EN25B10, 128 KB: skipped.
Probing for Eon EN25B10T, 128 KB: skipped.
Probing for Eon EN25B20, 256 KB: skipped.
Probing for Eon EN25B20T, 256 KB: skipped.
Probing for Eon EN25B40, 512 KB: skipped.
Probing for Eon EN25B40T, 512 KB: skipped.
Probing for Eon EN25B80, 1024 KB: skipped.
Probing for Eon EN25B80T, 1024 KB: skipped.
Probing for Eon EN25B16, 2048 KB: skipped.
Probing for Eon EN25B16T, 2048 KB: skipped.
Probing for Eon EN25B32, 4096 KB: skipped.
Probing for Eon EN25B32T, 4096 KB: skipped.
Probing for Eon EN25B64, 8192 KB: skipped.
Probing for Eon EN25B64T, 8192 KB: skipped.
Probing for Eon EN25D16, 2048 KB: skipped.
Probing for Eon EN25F05, 64 KB: skipped.
Probing for Eon EN25F10, 128 KB: skipped.
Probing for Eon EN25F20, 256 KB: skipped.
Probing for Eon EN25F40, 512 KB: skipped.
Probing for Eon EN25F80, 1024 KB: skipped.
Probing for Eon EN25F16, 2048 KB: skipped.
Probing for Eon EN25F32, 4096 KB: skipped.
Probing for Eon EN29F010, 128 KB: skipped.
Probing for EON EN29F002(A)(N)B, 256 KB: skipped.
Probing for EON EN29F002(A)(N)T, 256 KB: skipped.
Probing for Fujitsu MBM29F004BC, 512 KB: skipped.
Probing for Fujitsu MBM29F004TC, 512 KB: skipped.
Probing for Fujitsu MBM29F400BC, 512 KB: skipped.
Probing for Fujitsu MBM29F400TC, 512 KB: skipped.
Probing for Hyundai HY29F002T, 256 KB: skipped.
Probing for Hyundai HY29F002B, 256 KB: skipped.
Probing for Intel 28F001BX-B, 128 KB: skipped.
Probing for Intel 28F001BX-T, 128 KB: skipped.
Probing for Intel 28F004S5, 512 KB: skipped.
Probing for Intel 28F004BV/BE-B, 512 KB: skipped.
Probing for Intel 28F004BV/BE-T, 512 KB: skipped.
Probing for Intel 28F400BV/CV/CE-B, 512 KB: skipped.
Probing for Intel 28F400BV/CV/CE-T, 512 KB: skipped.
Probing for Intel 82802AB, 512 KB: skipped.
Probing for Intel 82802AC, 1024 KB: skipped.
Probing for Macronix MX25L512, 64 KB: skipped.
Probing for Macronix MX25L1005, 128 KB: skipped.
Probing for Macronix MX25L2005, 256 KB: skipped.
Probing for Macronix MX25L4005, 512 KB: skipped.
Probing for Macronix MX25L8005, 1024 KB: skipped.
Probing for Macronix MX25L1605, 2048 KB: skipped.
Probing for Macronix MX25L1635D, 2048 KB: skipped.
Probing for Macronix MX25L3205, 4096 KB: skipped.
Probing for Macronix MX25L3235D, 4096 KB: skipped.
Probing for Macronix MX25L6405, 8192 KB: skipped.
Probing for Macronix MX25L12805, 16384 KB: skipped.
Probing for Macronix MX29F001B, 128 KB: skipped.
Probing for Macronix MX29F001T, 128 KB: skipped.
Probing for Macronix MX29F002B, 256 KB: skipped.
Probing for Macronix MX29F002T, 256 KB: skipped.
Probing for Macronix MX29LV040, 512 KB: skipped.
Probing for Numonyx M25PE10, 128 KB: skipped.
Probing for Numonyx M25PE20, 256 KB: skipped.
Probing for Numonyx M25PE40, 512 KB: skipped.
Probing for Numonyx M25PE80, 1024 KB: skipped.
Probing for Numonyx M25PE16, 2048 KB: skipped.
Probing for PMC Pm25LV010, 128 KB: skipped.
Probing for PMC Pm25LV016B, 2048 KB: skipped.
Probing for PMC Pm25LV020, 256 KB: skipped.
Probing for PMC Pm25LV040, 512 KB: skipped.
Probing for PMC Pm25LV080B, 1024 KB: skipped.
Probing for PMC Pm25LV512, 64 KB: skipped.
Probing for PMC Pm29F002T, 256 KB: skipped.
Probing for PMC Pm29F002B, 256 KB: skipped.
Probing for PMC Pm39LV010, 128 KB: skipped.
Probing for PMC Pm39LV020, 256 KB: skipped.
Probing for PMC Pm39LV040, 512 KB: skipped.
Probing for PMC Pm49FL002, 256 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for PMC Pm49FL004, 512 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Found chip "PMC Pm49FL004" (512 KB, LPC,FWH) at physical address 0xfff80000.
Probing for Sanyo LF25FW203A, 2048 KB: skipped.
Probing for Sharp LHF00L04, 1024 KB: skipped.
Probing for Spansion S25FL008A, 1024 KB: skipped.
Probing for Spansion S25FL016A, 2048 KB: skipped.
Probing for SST SST25VF016B, 2048 KB: skipped.
Probing for SST SST25VF032B, 4096 KB: skipped.
Probing for SST SST25VF040.REMS, 512 KB: skipped.
Probing for SST SST25VF040B, 512 KB: skipped.
Probing for SST SST25LF040A.RES, 512 KB: skipped.
Probing for SST SST25VF040B.REMS, 512 KB: skipped.
Probing for SST SST25VF080B, 1024 KB: skipped.
Probing for SST SST28SF040A, 512 KB: skipped.
Probing for SST SST29EE010, 128 KB: skipped.
Probing for SST SST29LE010, 128 KB: skipped.
Probing for SST SST29EE020A, 256 KB: skipped.
Probing for SST SST29LE020, 256 KB: skipped.
Probing for SST SST39SF512, 64 KB: skipped.
Probing for SST SST39SF010A, 128 KB: skipped.
Probing for SST SST39SF020A, 256 KB: skipped.
Probing for SST SST39SF040, 512 KB: skipped.
Probing for SST SST39VF512, 64 KB: skipped.
Probing for SST SST39VF010, 128 KB: skipped.
Probing for SST SST39VF020, 256 KB: skipped.
Probing for SST SST39VF040, 512 KB: skipped.
Probing for SST SST39VF080, 1024 KB: skipped.
Probing for SST SST49LF002A/B, 256 KB: skipped.
Probing for SST SST49LF003A/B, 384 KB: skipped.
Probing for SST SST49LF004A/B, 512 KB: skipped.
Probing for SST SST49LF004C, 512 KB: skipped.
Probing for SST SST49LF008A, 1024 KB: skipped.
Probing for SST SST49LF008C, 1024 KB: skipped.
Probing for SST SST49LF016C, 2048 KB: skipped.
Probing for SST SST49LF020, 256 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for SST SST49LF020A, 256 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for SST SST49LF040, 512 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for SST SST49LF040B, 512 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for SST SST49LF080A, 1024 KB: Chip lacks correct probe timing information, using default 10mS/40uS. probe_jedec_common: id1 0xff, id2 0xff, id1 parity violation, id1 is normal flash content, id2 is normal flash content
Probing for SST SST49LF160C, 2048 KB: probe_82802ab: id1 0xff, id2 0xff, id1 parity violation, id1 is normal flash content, id2 is normal flash content
Probing for ST M25P05-A, 64 KB: skipped.
Probing for ST M25P05.RES, 64 KB: skipped.
Probing for ST M25P10-A, 128 KB: skipped.
Probing for ST M25P10.RES, 128 KB: skipped.
Probing for ST M25P20, 256 KB: skipped.
Probing for ST M25P40, 512 KB: skipped.
Probing for ST M25P40-old, 512 KB: skipped.
Probing for ST M25P80, 1024 KB: skipped.
Probing for ST M25P16, 2048 KB: skipped.
Probing for ST M25P32, 4096 KB: skipped.
Probing for ST M25P64, 8192 KB: skipped.
Probing for ST M25P128, 16384 KB: skipped.
Probing for ST M29F002B, 256 KB: skipped.
Probing for ST M29F002T/NT, 256 KB: skipped.
Probing for ST M29F040B, 512 KB: skipped.
Probing for ST M29F400BT, 512 KB: skipped.
Probing for ST M29W010B, 128 KB: skipped.
Probing for ST M29W040B, 512 KB: skipped.
Probing for ST M29W512B, 64 KB: skipped.
Probing for ST M50FLW040A, 512 KB: probe_82802ab: id1 0x49, id2 0x4d, id1 is normal flash content, id2 is normal flash content
Probing for ST M50FLW040B, 512 KB: probe_82802ab: id1 0x49, id2 0x4d, id1 is normal flash content, id2 is normal flash content
Probing for ST M50FLW080A, 1024 KB: probe_82802ab: id1 0xff, id2 0xff, id1 parity violation, id1 is normal flash content, id2 is normal flash content
Probing for ST M50FLW080B, 1024 KB: probe_82802ab: id1 0xff, id2 0xff, id1 parity violation, id1 is normal flash content, id2 is normal flash content
Probing for ST M50FW002, 256 KB: skipped.
Probing for ST M50FW016, 2048 KB: skipped.
Probing for ST M50FW040, 512 KB: skipped.
Probing for ST M50FW080, 1024 KB: skipped.
Probing for ST M50LPW116, 2048 KB: probe_82802ab: id1 0xff, id2 0xff, id1 parity violation, id1 is normal flash content, id2 is normal flash content
Probing for SyncMOS S29C31004T, 512 KB: skipped.
Probing for SyncMOS S29C51001T, 128 KB: skipped.
Probing for SyncMOS S29C51002T, 256 KB: skipped.
Probing for SyncMOS S29C51004T, 512 KB: skipped.
Probing for TI TMS29F002RB, 256 KB: skipped.
Probing for TI TMS29F002RT, 256 KB: skipped.
Probing for Winbond W25Q80, 1024 KB: skipped.
Probing for Winbond W25Q16, 2048 KB: skipped.
Probing for Winbond W25Q32, 4096 KB: skipped.
Probing for Winbond W25Q64, 8192 KB: skipped.
Probing for Winbond W25x10, 128 KB: skipped.
Probing for Winbond W25x20, 256 KB: skipped.
Probing for Winbond W25x40, 512 KB: skipped.
Probing for Winbond W25x80, 1024 KB: skipped.
Probing for Winbond W25x16, 2048 KB: skipped.
Probing for Winbond W25x32, 4096 KB: skipped.
Probing for Winbond W25x64, 8192 KB: skipped.
Probing for Winbond W29C011, 128 KB: skipped.
Probing for Winbond W29C020C, 256 KB: skipped.
Probing for Winbond W29C040P, 512 KB: skipped.
Probing for Winbond W29EE011, 128 KB: skipped.
Probing for Winbond W39V040A, 512 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for Winbond W39V040B, 512 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for Winbond W39V040C, 512 KB: Chip lacks correct probe timing information, using default 10mS/40uS. probe_jedec_common: id1 0x9d, id2 0x6e
Probing for Winbond W39V040FA, 512 KB: skipped.
Probing for Winbond W39V080A, 1024 KB: probe_jedec_common: id1 0xff, id2 0xff, id1 parity violation, id1 is normal flash content, id2 is normal flash content
Probing for Winbond W49F002U, 256 KB: skipped.
Probing for Winbond W49V002A, 256 KB: probe_jedec_common: id1 0x9d, id2 0x6e
Probing for Winbond W49V002FA, 256 KB: skipped.
Probing for Winbond W39V080FA, 1024 KB: skipped.
Probing for Winbond W39V080FA (dual mode), 512 KB: skipped.
Probing for Atmel unknown Atmel SPI chip, 0 KB: skipped.
Probing for EON unknown EON SPI chip, 0 KB: skipped.
Probing for Macronix unknown Macronix SPI chip, 0 KB: skipped.
Probing for PMC unknown PMC SPI chip, 0 KB: skipped.
Probing for SST unknown SST SPI chip, 0 KB: skipped.
Probing for ST unknown ST SPI chip, 0 KB: skipped.
Probing for Sanyo unknown Sanyo SPI chip, 0 KB: skipped.
Probing for Generic unknown SPI chip (RDID), 0 KB: skipped.
Probing for Generic unknown SPI chip (REMS), 0 KB: skipped.
No operations were specified.
On Sat, Jul 3, 2010 at 6:29 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Hi,
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP61: Andrew Cleveland, Free Wind, Andre Robatino, Антон Кочков, Benjamin Henrion, Chris Yagami, Jim Lunsford MCP65: Kjell Braden, Mark Morschhäuser, Melchior FRANZ, Wolfgang Schnitker MCP67: Alessandro Polverini, NotLim MCP73: Noe, Maik Masling MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers MCP79: Alex Neblett, J.P. Krauss, Ivo Anjo, Halim Sahin, Joakim Gissberg, Benjamin Eugler
This code has been tested for probe/read for the following chipsets: MCP65: Johannes Sjölund MCP79: Andrew Morgan
flashrom -V flashrom v0.9.2-runknown on Linux 2.6.32-gentoo-r8 (i686), built with libpci 3.1.4, GCC 4.4.3, little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 3 usecs, 390M loops per second, 10 myus = 12 us, 100 myus = 99 us, 1000 myus = 1227 us, 10000 myus = 10214 us, 12 myus = 22 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "LENOVO" DMI string system-product-name: "20021,2959" DMI string system-version: "Lenovo Ideapad S12" DMI string baseboard-manufacturer: "LENOVO" DMI string baseboard-product-name: "MoutCook" DMI string baseboard-version: "Not Applicable" DMI string chassis-type: "Notebook" Laptop detected via DMI ======================================================================== WARNING! You seem to be running flashrom on a laptop. Laptops, notebooks and netbooks are difficult to support and we recommend to use the vendor flashing utility. The embedded controller (EC) in these machines often interacts badly with flashing. See http://www.flashrom.org/Laptops for details.
If flash is shared with the EC, erase is guaranteed to brick your laptop and write may brick your laptop. Read and probe may irritate your EC and cause fan failure, backlight failure and sudden poweroff. You have been warned. ======================================================================== Aborting.
<> sudo flashrom -V flashrom v0.9.2-r1069 on Linux 2.6.35-rc3 (x86_64), built with libpci 3.0.0, GCC 4.4.3, little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 1 usecs, 1299M loops per second, 10 myus = 10 us, 100 myus = 100 us, 1000 myus = 999 us, 10000 myus = 10007 us, 4 myus = 5 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "System manufacturer" DMI string system-product-name: "System Product Name" DMI string system-version: "System Version" DMI string baseboard-manufacturer: "ASUSTeK Computer INC." DMI string baseboard-product-name: "M4N78 PRO" DMI string baseboard-version: "Rev 1.xx" DMI string chassis-type: "Desktop" Found ITE Super I/O, id 8720 Found chipset "NVIDIA MCP78S", enabling flash write... chipset PCI ID is 10de:075c, This chipset is not really supported yet. Guesswork... ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Guessed flash bus type is SPI Found SMBus device 10de:0752 at 00:01:1 SPI BAR is at 0xfbd80000, after clearing low bits BAR is at 0xfbd80000 Mapping Nvidia MCP6x SPI at 0xfbd80000, unaligned size 0x544. SPI control is 0xc01a, enable=0, idle=0 Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks. SPI on this chipset is WIP. DO NOT USE! OK. This chipset supports the following protocols: SPI. No IT87* serial flash segment enabled. Probing for AMD Am29F010A/B, 128 KB: skipped. Probing for AMD Am29F002(N)BB, 256 KB: skipped. Probing for AMD Am29F002(N)BT, 256 KB: skipped. Probing for AMD Am29F016D, 2048 KB: skipped. Probing for AMD Am29F040B, 512 KB: skipped. Probing for AMD Am29F080B, 1024 KB: skipped. Probing for AMD Am29LV040B, 512 KB: skipped. Probing for AMD Am29LV081B, 1024 KB: skipped. Probing for ASD AE49F2008, 256 KB: skipped. Probing for Atmel AT25DF021, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF041A, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF081, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF161, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF321, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF321A, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF641, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25F512B, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25FS010, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25FS040, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF041, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF081A, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF161, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF161A, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26F004, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT29C512, 64 KB: skipped. Probing for Atmel AT29C010A, 128 KB: skipped. Probing for Atmel AT29C020, 256 KB: skipped. Probing for Atmel AT29C040A, 512 KB: skipped. Probing for Atmel AT45CS1282, 16896 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB011D, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB021D, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB041D, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB081D, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB161D, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB321C, 4224 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB321D, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB642D, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT49BV512, 64 KB: skipped. Probing for Atmel AT49F020, 256 KB: skipped. Probing for Atmel AT49F002(N), 256 KB: skipped. Probing for Atmel AT49F002(N)T, 256 KB: skipped. Probing for AMIC A25L40PT, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for AMIC A25L40PU, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for AMIC A29002B, 256 KB: skipped. Probing for AMIC A29002T, 256 KB: skipped. Probing for AMIC A29040B, 512 KB: skipped. Probing for AMIC A49LF040A, 512 KB: skipped. Probing for EMST F49B002UA, 256 KB: skipped. Probing for EMST F25L008A, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B05, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B05T, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B10T, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B20T, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B40T, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B80T, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B16T, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B32T, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B64T, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25D16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F05, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN29F010, 128 KB: skipped. Probing for EON EN29F002(A)(N)B, 256 KB: skipped. Probing for EON EN29F002(A)(N)T, 256 KB: skipped. Probing for Fujitsu MBM29F004BC, 512 KB: skipped. Probing for Fujitsu MBM29F004TC, 512 KB: skipped. Probing for Fujitsu MBM29F400BC, 512 KB: skipped. Probing for Fujitsu MBM29F400TC, 512 KB: skipped. Probing for Hyundai HY29F002T, 256 KB: skipped. Probing for Hyundai HY29F002B, 256 KB: skipped. Probing for Intel 28F001BX-B, 128 KB: skipped. Probing for Intel 28F001BX-T, 128 KB: skipped. Probing for Intel 28F004S5, 512 KB: skipped. Probing for Intel 28F004BV/BE-B, 512 KB: skipped. Probing for Intel 28F004BV/BE-T, 512 KB: skipped. Probing for Intel 28F400BV/CV/CE-B, 512 KB: skipped. Probing for Intel 28F400BV/CV/CE-T, 512 KB: skipped. Probing for Intel 82802AB, 512 KB: skipped. Probing for Intel 82802AC, 1024 KB: skipped. Probing for Macronix MX25L512, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L1005, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L2005, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L4005, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L1605, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L1635D, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L3205, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L3235D, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L6405, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L12805, 16384 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX29F001B, 128 KB: skipped. Probing for Macronix MX29F001T, 128 KB: skipped. Probing for Macronix MX29F002B, 256 KB: skipped. Probing for Macronix MX29F002T, 256 KB: skipped. Probing for Macronix MX29LV040, 512 KB: skipped. Probing for Numonyx M25PE10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV010, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV016B, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV020, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV040, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV080B, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV512, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm29F002T, 256 KB: skipped. Probing for PMC Pm29F002B, 256 KB: skipped. Probing for PMC Pm39LV010, 128 KB: skipped. Probing for PMC Pm39LV020, 256 KB: skipped. Probing for PMC Pm39LV040, 512 KB: skipped. Probing for PMC Pm49FL002, 256 KB: skipped. Probing for PMC Pm49FL004, 512 KB: skipped. Probing for Sanyo LF25FW203A, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Sharp LHF00L04, 1024 KB: skipped. Probing for Spansion S25FL008A, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Spansion S25FL016A, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25VF016B, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25VF032B, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25VF040.REMS, 512 KB: probe_spi_rems: id1 0xef, id2 0x13 Probing for SST SST25VF040B, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25LF040A.RES, 512 KB: probe_spi_res2: id1 0x13, id2 0x13 Probing for SST SST25VF040B.REMS, 512 KB: probe_spi_rems: id1 0xef, id2 0x13 Probing for SST SST25VF080B, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST28SF040A, 512 KB: skipped. Probing for SST SST29EE010, 128 KB: skipped. Probing for SST SST29LE010, 128 KB: skipped. Probing for SST SST29EE020A, 256 KB: skipped. Probing for SST SST29LE020, 256 KB: skipped. Probing for SST SST39SF512, 64 KB: skipped. Probing for SST SST39SF010A, 128 KB: skipped. Probing for SST SST39SF020A, 256 KB: skipped. Probing for SST SST39SF040, 512 KB: skipped. Probing for SST SST39VF512, 64 KB: skipped. Probing for SST SST39VF010, 128 KB: skipped. Probing for SST SST39VF020, 256 KB: skipped. Probing for SST SST39VF040, 512 KB: skipped. Probing for SST SST39VF080, 1024 KB: skipped. Probing for SST SST49LF002A/B, 256 KB: skipped. Probing for SST SST49LF003A/B, 384 KB: skipped. Probing for SST SST49LF004A/B, 512 KB: skipped. Probing for SST SST49LF004C, 512 KB: skipped. Probing for SST SST49LF008A, 1024 KB: skipped. Probing for SST SST49LF008C, 1024 KB: skipped. Probing for SST SST49LF016C, 2048 KB: skipped. Probing for SST SST49LF020, 256 KB: skipped. Probing for SST SST49LF020A, 256 KB: skipped. Probing for SST SST49LF040, 512 KB: skipped. Probing for SST SST49LF040B, 512 KB: skipped. Probing for SST SST49LF080A, 1024 KB: skipped. Probing for SST SST49LF160C, 2048 KB: skipped. Probing for ST M25P05-A, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P05.RES, 64 KB: Ignoring RES in favour of RDID. Probing for ST M25P10-A, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P10.RES, 128 KB: Ignoring RES in favour of RDID. Probing for ST M25P20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P40-old, 512 KB: Ignoring RES in favour of RDID. Probing for ST M25P80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P128, 16384 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M29F002B, 256 KB: skipped. Probing for ST M29F002T/NT, 256 KB: skipped. Probing for ST M29F040B, 512 KB: skipped. Probing for ST M29F400BT, 512 KB: skipped. Probing for ST M29W010B, 128 KB: skipped. Probing for ST M29W040B, 512 KB: skipped. Probing for ST M29W512B, 64 KB: skipped. Probing for ST M50FLW040A, 512 KB: skipped. Probing for ST M50FLW040B, 512 KB: skipped. Probing for ST M50FLW080A, 1024 KB: skipped. Probing for ST M50FLW080B, 1024 KB: skipped. Probing for ST M50FW002, 256 KB: skipped. Probing for ST M50FW016, 2048 KB: skipped. Probing for ST M50FW040, 512 KB: skipped. Probing for ST M50FW080, 1024 KB: skipped. Probing for ST M50LPW116, 2048 KB: skipped. Probing for SyncMOS S29C31004T, 512 KB: skipped. Probing for SyncMOS S29C51001T, 128 KB: skipped. Probing for SyncMOS S29C51002T, 256 KB: skipped. Probing for SyncMOS S29C51004T, 512 KB: skipped. Probing for TI TMS29F002RB, 256 KB: skipped. Probing for TI TMS29F002RT, 256 KB: skipped. Probing for Winbond W25Q80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25Q16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25Q32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25Q64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Chip status register is 00 Found chip "Winbond W25x80" (1024 KB, SPI) at physical address 0xfff00000. Probing for Winbond W25x16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W29C011, 128 KB: skipped. Probing for Winbond W29C020C, 256 KB: skipped. Probing for Winbond W29C040P, 512 KB: skipped. Probing for Winbond W29EE011, 128 KB: skipped. Probing for Winbond W39V040A, 512 KB: skipped. Probing for Winbond W39V040B, 512 KB: skipped. Probing for Winbond W39V040C, 512 KB: skipped. Probing for Winbond W39V040FA, 512 KB: skipped. Probing for Winbond W39V080A, 1024 KB: skipped. Probing for Winbond W49F002U, 256 KB: skipped. Probing for Winbond W49V002A, 256 KB: skipped. Probing for Winbond W49V002FA, 256 KB: skipped. Probing for Winbond W39V080FA, 1024 KB: skipped. Probing for Winbond W39V080FA (dual mode), 512 KB: skipped. Probing for Atmel unknown Atmel SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for EON unknown EON SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix unknown Macronix SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC unknown PMC SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST unknown SST SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST unknown ST SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Sanyo unknown Sanyo SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Generic unknown SPI chip (RDID), 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Generic unknown SPI chip (REMS), 0 KB: probe_spi_rems: id1 0xef, id2 0x13 === This flash part has status UNTESTED for operations: ERASE The test status of this chip may have been updated in the latest development version of flashrom. If you are running the latest development version, please email a report to flashrom@flashrom.org if any of the above operations work correctly for you with this flash part. Please include the flashrom output with the additional -V option for all operations you tested (-V, -Vr, -Vw, -VE), and mention which mainboard or programmer you tested. Thanks for your help! === No operations were specified.
On 07/03/2010 09:29 AM, Carl-Daniel Hailfinger wrote:
Hi,
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP61: Andrew Cleveland, Free Wind, Andre Robatino, Антон Кочков, Benjamin Henrion, Chris Yagami, Jim Lunsford MCP65: Kjell Braden, Mark Morschhäuser, Melchior FRANZ, Wolfgang Schnitker MCP67: Alessandro Polverini, NotLim MCP73: Noe, Maik Masling MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers MCP79: Alex Neblett, J.P. Krauss, Ivo Anjo, Halim Sahin, Joakim Gissberg, Benjamin Eugler
This code has been tested for probe/read for the following chipsets: MCP65: Johannes Sjölund MCP79: Andrew Morgan
Testing instructions
This patch may fry your flash chip, explode mysteriously and abduct your dog, but so far it looks good. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Please apply this patch to the latest flashrom svn (subversion) tree, recompile and then run flashrom -V This command should be reasonably safe (it only tries to identify your flash chip), but if you don't have a way to recover from a bad flash, please don't try it. Then please mail the output from the command above to the flashrom mailing list (preferably as reply to this mail). Doing this on your boards with newer (last 5 years) Nvidia nForce chipsets would be highly appreciated.
You can also find this patch near the top at http://patchwork.coreboot.org/project/flashrom/list/ in case your mailer corrupts the patch. It applies against latest clean svn tree.
Patch description
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support. Fix a few problems in the previously unused SPI bitbanging core.
Huge thanks go to Michael Karcher for reverse engineering the interface and to Johannes Sjölund for testing multiple iterations of my patch on his hardware until it worked.
Signed-off-by: Carl-Daniel Hailfingerc-d.hailfinger.devel.2006@gmx.net
Index: flashrom-bitbang_spi_nvidia_mcp/flash.h
--- flashrom-bitbang_spi_nvidia_mcp/flash.h (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -128,13 +128,16 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__)
- BITBANG_SPI_MASTER_MCP,
+#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
extern const int bitbang_spi_master_count;
-extern enum bitbang_spi_master bitbang_spi_master;
- struct bitbang_spi_master_entry { void (*set_cs) (int val); void (*set_sck) (int val);
@@ -530,10 +533,22 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif
- /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[];
-int bitbang_spi_init(void); +int bitbang_spi_init(enum bitbang_spi_master master); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -637,6 +652,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO,
- SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if CONFIG_FT2232_SPI == 1
Index: flashrom-bitbang_spi_nvidia_mcp/hwaccess.h
--- flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Arbeitskopie) @@ -176,6 +176,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order:
- OUT[BWL](val, port)
- */
- #if defined(__FreeBSD__) || defined(__DragonFly__) #include<machine/cpufunc.h> #define off64_t off_t
Index: flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c
--- flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -26,17 +26,29 @@ #include "chipdrivers.h" #include "spi.h"
-/* Length of half a clock period in usecs */ -int bitbang_spi_half_period = 0; +/* Length of half a clock period in usecs. Default to 1 (500 kHz). */ +int bitbang_spi_half_period = 1;
enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__)
- {
.set_cs = mcp6x_bitbang_set_cs,
.set_sck = mcp6x_bitbang_set_sck,
.set_mosi = mcp6x_bitbang_set_mosi,
.get_miso = mcp6x_bitbang_get_miso,
- },
+#endif +#endif
{}, /* This entry corresponds to BITBANG_SPI_INVALID. */ };
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -57,10 +69,18 @@ return bitbang_spi_master_table[bitbang_spi_master].get_miso(); }
-int bitbang_spi_init(void) +int bitbang_spi_init(enum bitbang_spi_master master) {
- bitbang_spi_master = master;
- if (bitbang_spi_master == BITBANG_SPI_INVALID) {
msg_perr("Invalid bitbang SPI master. \n"
"Please report a bug at flashrom@flashrom.org\n");
return 1;
- } bitbang_spi_set_cs(1); bitbang_spi_set_sck(0);
- bitbang_spi_set_mosi(0); buses_supported = CHIP_BUSTYPE_SPI; return 0; }
@@ -87,6 +107,7 @@ { static unsigned char *bufout = NULL; static unsigned char *bufin = NULL;
- unsigned char *tmp; static int oldbufsize = 0; int bufsize; int i;
@@ -98,20 +119,34 @@ bufsize = max(writecnt + readcnt, 260); /* Never shrink. realloc() calls are expensive. */ if (bufsize> oldbufsize) {
bufout = realloc(bufout, bufsize);
if (!bufout) {
tmp = realloc(bufout, bufsize);
if (!tmp) { msg_perr("Out of memory!\n");
if (bufout)
free(bufout);
bufout = NULL; if (bufin) free(bufin);
bufin = NULL;
oldbufsize = 0; exit(1);
}
bufin = realloc(bufout, bufsize);
if (!bufin) {
} else
bufout = tmp;
tmp = realloc(bufin, bufsize);
if (!tmp) { msg_perr("Out of memory!\n");
if (bufin)
free(bufin);
bufin = NULL; if (bufout) free(bufout);
bufout = NULL;
oldbufsize = 0; exit(1);
}
} else
bufin = tmp;
- oldbufsize = bufsize; }
@@ -135,8 +170,13 @@
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) {
- /* Maximum read length is unlimited, use 64k bytes. */
- return spi_read_chunked(flash, buf, start, len, 64 * 1024);
/* Maximum read length is unlimited in theory.
* The current implementation can handle reads of up to 65536 bytes.
* Please note that you need two buffers of 2n+4 bytes each for a read
* of n bytes, resulting in a total memory requirement of 4n+8 bytes.
* To conserve memory, read in chunks of 256 bytes.
*/
return spi_read_chunked(flash, buf, start, len, 256); }
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf)
Index: flashrom-bitbang_spi_nvidia_mcp/spi.c
--- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -82,6 +82,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, },
- { /* SPI_CONTROLLER_MCP6X_BITBANG */
.command = bitbang_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = bitbang_spi_read,
.write_256 = bitbang_spi_write_256,
- }, #endif #endif
Index: flashrom-bitbang_spi_nvidia_mcp/Makefile
--- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -111,8 +111,12 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -155,7 +159,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c
--- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1124,10 +1124,8 @@ { int ret = 0; uint8_t val;
- uint16_t status; char *busname;
- uint32_t mcp_spibaraddr;
- void *mcp_spibar;
uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n");
@@ -1176,40 +1174,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */
- mcp_spibaraddr = pci_read_long(smbusdev, 0x74);
- msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr);
- mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74);
- msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface (well,
*/
- a set of GPIOs that is connected to SPI flash) is at offset 0x530,
- so we expect a size of at least 0x800. Clear the lower bits.
- It is entirely possible that the BAR is 64k big and the low bits are
- reserved for an entirely different purpose.
- mcp_spibaraddr&= ~0x7ff;
- msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr);
mcp6x_spibaraddr&= ~0x7ff;
msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */
- if (mcp_spibaraddr&& (buses_supported == CHIP_BUSTYPE_SPI)) {
- if (mcp6x_spibaraddr&& (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */
mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544);
mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1<< 1) -#define MCP67_SPI_SCK (1<< 2) -#define MCP67_SPI_MOSI (1<< 3) -#define MCP67_SPI_MISO (1<< 4) -#define MCP67_SPI_ENABLE (1<< 0) -#define MCP67_SPI_IDLE (1<< 8)
status = mmio_readw(mcp_spibar + 0x530);
msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n",
status, status& 0x1, (status>> 8)& 0x1);
if (mcp6x_spi_init())
ret = 1;
+#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */
physunmap(mcp_spibar, 0x544);
- } else if (!mcp_spibaraddr&& (buses_supported& CHIP_BUSTYPE_SPI)) {
physunmap(mcp6x_spibar, 0x544);
+#endif
- } else if (!mcp6x_spibaraddr&& (buses_supported& CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported&= ~CHIP_BUSTYPE_SPI; ret = 1;
- } else if (mcp_spibaraddr&& !(buses_supported& CHIP_BUSTYPE_SPI)) {
- } else if (mcp6x_spibaraddr&& !(buses_supported& CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else {
@@ -1247,8 +1238,8 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI:
msg_pinfo("SPI on this chipset is not supported yet.\n");
buses_supported = CHIP_BUSTYPE_NONE;
msg_perr("SPI on this chipset is WIP. DO NOT USE!\n");
break; default: msg_pinfo("Something went wrong with bus type detection.\n");programmer_may_write = 0;
@@ -1273,8 +1264,8 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI:
msg_pinfo("SPI on this chipset is not supported yet.\n");
buses_supported = CHIP_BUSTYPE_NONE;
msg_perr("SPI on this chipset is WIP. DO NOT USE!\n");
break; default: msg_pinfo("Something went wrong with bus type detection.\n");programmer_may_write = 0;
Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c
--- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/*
- This file is part of the flashrom project.
- Copyright (C) 2010 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.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
+/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller.
- Based on clean room reverse engineered docs from
- created by Michael Karcher.
- */
+#if defined(__i386__) || defined(__x86_64__)
+#include<stdint.h> +#include<stdlib.h> +#include<ctype.h> +#include "flash.h"
+/* We have two sets of pins, out and in. The numbers for both sets are
- independent and are bitshift values, not real pin numbers.
- */
+/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8
+void *mcp6x_spibar = NULL;
+void mcp6x_request_spibus(void) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte |= 1<< MCP6X_SPI_ENABLE;
- mmio_writeb(byte, mcp6x_spibar + 0x530);
- /* Wait until we are allowed to use the SPI bus. */
- while (!(mmio_readw(mcp6x_spibar + 0x530)& (1<< MCP6X_SPI_IDLE))) ;
+}
+void mcp6x_release_spibus(void) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_ENABLE);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+void mcp6x_bitbang_set_cs(int val) +{
- uint8_t byte;
- /* Requesting and releasing the SPI bus is handled in here to allow the
* chipset to use its own SPI engine for native reads.
*/
- if (val == 0)
mcp6x_request_spibus();
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_CS);
- byte |= (val<< MCP6X_SPI_CS);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
- if (val == 1)
mcp6x_release_spibus();
+}
+void mcp6x_bitbang_set_sck(int val) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_SCK);
- byte |= (val<< MCP6X_SPI_SCK);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+void mcp6x_bitbang_set_mosi(int val) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_MOSI);
- byte |= (val<< MCP6X_SPI_MOSI);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+int mcp6x_bitbang_get_miso(void) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte = (byte>> MCP6X_SPI_MISO)& 0x1;
- return byte;
+}
+int mcp6x_spi_init(void) +{
- uint16_t status;
- status = mmio_readw(mcp6x_spibar + 0x530);
- msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n",
status, (status>> MCP6X_SPI_ENABLE)& 0x1,
(status>> MCP6X_SPI_IDLE)& 0x1);
- if (bitbang_spi_init(BITBANG_SPI_MASTER_MCP))
return 1;
- spi_controller = SPI_CONTROLLER_MCP6X_BITBANG;
- return 0;
+}
+#endif
flashrom -p internal:laptop=force_I_want_a_brick -V -c "unknown SPI chip (RDID)" flashrom v0.9.2-runknown on Linux 2.6.32-gentoo-r8 (i686), built with libpci 3.1.4, GCC 4.4.3, little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 2 usecs, 373M loops per second, 10 myus = 11 us, 100 myus = 95 us, 1000 myus = 935 us, 10000 myus = 9868 us, 8 myus = 9 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "LENOVO" DMI string system-product-name: "20021,2959" DMI string system-version: "Lenovo Ideapad S12" DMI string baseboard-manufacturer: "LENOVO" DMI string baseboard-product-name: "MoutCook" DMI string baseboard-version: "Not Applicable" DMI string chassis-type: "Notebook" Laptop detected via DMI ======================================================================== WARNING! You seem to be running flashrom on a laptop. Laptops, notebooks and netbooks are difficult to support and we recommend to use the vendor flashing utility. The embedded controller (EC) in these machines often interacts badly with flashing. See http://www.flashrom.org/Laptops for details.
If flash is shared with the EC, erase is guaranteed to brick your laptop and write may brick your laptop. Read and probe may irritate your EC and cause fan failure, backlight failure and sudden poweroff. You have been warned. ======================================================================== Proceeding anyway because user specified laptop=force_I_want_a_brick Found chipset "NVIDIA MCP79", enabling flash write... chipset PCI ID is 10de:0aae, This chipset is not really supported yet. Guesswork... ISA/LPC bridge reg 0x8a contents: 0x00, bit 6 is 0, bit 5 is 0 Guessed flash bus type is LPC Found SMBus device 10de:0aa2 at 00:03:2 SPI BAR is at 0xc0080000, after clearing low bits BAR is at 0xc0080000 Strange. MCP SPI BAR is valid, but chipset apparently doesn't have SPI enabled. Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks. LPC on this chipset is not supported yet. OK. This chipset supports the following protocols: LPC. Probing for Generic unknown SPI chip (RDID), 0 KB: skipped. No EEPROM/flash device found. Note: flashrom can never write if the flash chip isn't found automatically.
flashrom v0.9.2-r1069 on Linux 2.6.32.12-115.fc12.x86_64 (x86_64), built with libpci 3.1.6, GCC 4.4.3 20100127 (Red Hat 4.4.3-4), little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 1 usecs, 992M loops per second, 10 myus = 11 us, 100 myus = 101 us, 1000 myus = 1004 us, 10000 myus = 9986 us, 4 myus = 4 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "System manufacturer" DMI string system-product-name: "System Product Name" DMI string system-version: "System Version" DMI string baseboard-manufacturer: "ASUSTeK Computer INC." DMI string baseboard-product-name: "M4N78 PRO" DMI string baseboard-version: "Rev 1.xx" DMI string chassis-type: "Desktop" Found ITE Super I/O, id 8720 Found chipset "NVIDIA MCP78S", enabling flash write... chipset PCI ID is 10de:075c, This chipset is not really supported yet. Guesswork... ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Guessed flash bus type is SPI Found SMBus device 10de:0752 at 00:01:1 SPI BAR is at 0xf7f80000, after clearing low bits BAR is at 0xf7f80000 Mapping Nvidia MCP6x SPI at 0xf7f80000, unaligned size 0x544. SPI control is 0xc01a, enable=0, idle=0 Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks. SPI on this chipset is WIP. DO NOT USE! OK. This chipset supports the following protocols: SPI. No IT87* serial flash segment enabled. Probing for AMD Am29F010A/B, 128 KB: skipped. Probing for AMD Am29F002(N)BB, 256 KB: skipped. Probing for AMD Am29F002(N)BT, 256 KB: skipped. Probing for AMD Am29F016D, 2048 KB: skipped. Probing for AMD Am29F040B, 512 KB: skipped. Probing for AMD Am29F080B, 1024 KB: skipped. Probing for AMD Am29LV040B, 512 KB: skipped. Probing for AMD Am29LV081B, 1024 KB: skipped. Probing for ASD AE49F2008, 256 KB: skipped. Probing for Atmel AT25DF021, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF041A, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF081, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF161, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF321, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF321A, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25DF641, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25F512B, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25FS010, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT25FS040, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF041, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF081A, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF161, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26DF161A, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT26F004, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT29C512, 64 KB: skipped. Probing for Atmel AT29C010A, 128 KB: skipped. Probing for Atmel AT29C020, 256 KB: skipped. Probing for Atmel AT29C040A, 512 KB: skipped. Probing for Atmel AT45CS1282, 16896 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB011D, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB021D, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB041D, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB081D, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB161D, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB321C, 4224 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB321D, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT45DB642D, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Atmel AT49BV512, 64 KB: skipped. Probing for Atmel AT49F020, 256 KB: skipped. Probing for Atmel AT49F002(N), 256 KB: skipped. Probing for Atmel AT49F002(N)T, 256 KB: skipped. Probing for AMIC A25L40PT, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for AMIC A25L40PU, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for AMIC A29002B, 256 KB: skipped. Probing for AMIC A29002T, 256 KB: skipped. Probing for AMIC A29040B, 512 KB: skipped. Probing for AMIC A49LF040A, 512 KB: skipped. Probing for EMST F49B002UA, 256 KB: skipped. Probing for EMST F25L008A, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B05, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B05T, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B10T, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B20T, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B40T, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B80T, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B16T, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B32T, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25B64T, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25D16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F05, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN25F32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Eon EN29F010, 128 KB: skipped. Probing for EON EN29F002(A)(N)B, 256 KB: skipped. Probing for EON EN29F002(A)(N)T, 256 KB: skipped. Probing for Fujitsu MBM29F004BC, 512 KB: skipped. Probing for Fujitsu MBM29F004TC, 512 KB: skipped. Probing for Fujitsu MBM29F400BC, 512 KB: skipped. Probing for Fujitsu MBM29F400TC, 512 KB: skipped. Probing for Hyundai HY29F002T, 256 KB: skipped. Probing for Hyundai HY29F002B, 256 KB: skipped. Probing for Intel 28F001BX-B, 128 KB: skipped. Probing for Intel 28F001BX-T, 128 KB: skipped. Probing for Intel 28F004S5, 512 KB: skipped. Probing for Intel 28F004BV/BE-B, 512 KB: skipped. Probing for Intel 28F004BV/BE-T, 512 KB: skipped. Probing for Intel 28F400BV/CV/CE-B, 512 KB: skipped. Probing for Intel 28F400BV/CV/CE-T, 512 KB: skipped. Probing for Intel 82802AB, 512 KB: skipped. Probing for Intel 82802AC, 1024 KB: skipped. Probing for Macronix MX25L512, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L1005, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L2005, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L4005, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L1605, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L1635D, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L3205, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L3235D, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L6405, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX25L12805, 16384 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix MX29F001B, 128 KB: skipped. Probing for Macronix MX29F001T, 128 KB: skipped. Probing for Macronix MX29F002B, 256 KB: skipped. Probing for Macronix MX29F002T, 256 KB: skipped. Probing for Macronix MX29LV040, 512 KB: skipped. Probing for Numonyx M25PE10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Numonyx M25PE16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV010, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV016B, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV020, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV040, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV080B, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm25LV512, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC Pm29F002T, 256 KB: skipped. Probing for PMC Pm29F002B, 256 KB: skipped. Probing for PMC Pm39LV010, 128 KB: skipped. Probing for PMC Pm39LV020, 256 KB: skipped. Probing for PMC Pm39LV040, 512 KB: skipped. Probing for PMC Pm49FL002, 256 KB: skipped. Probing for PMC Pm49FL004, 512 KB: skipped. Probing for Sanyo LF25FW203A, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Sharp LHF00L04, 1024 KB: skipped. Probing for Spansion S25FL008A, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Spansion S25FL016A, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25VF016B, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25VF032B, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25VF040.REMS, 512 KB: probe_spi_rems: id1 0xef, id2 0x13 Probing for SST SST25VF040B, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST25LF040A.RES, 512 KB: probe_spi_res2: id1 0x13, id2 0x13 Probing for SST SST25VF040B.REMS, 512 KB: probe_spi_rems: id1 0xef, id2 0x13 Probing for SST SST25VF080B, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST SST28SF040A, 512 KB: skipped. Probing for SST SST29EE010, 128 KB: skipped. Probing for SST SST29LE010, 128 KB: skipped. Probing for SST SST29EE020A, 256 KB: skipped. Probing for SST SST29LE020, 256 KB: skipped. Probing for SST SST39SF512, 64 KB: skipped. Probing for SST SST39SF010A, 128 KB: skipped. Probing for SST SST39SF020A, 256 KB: skipped. Probing for SST SST39SF040, 512 KB: skipped. Probing for SST SST39VF512, 64 KB: skipped. Probing for SST SST39VF010, 128 KB: skipped. Probing for SST SST39VF020, 256 KB: skipped. Probing for SST SST39VF040, 512 KB: skipped. Probing for SST SST39VF080, 1024 KB: skipped. Probing for SST SST49LF002A/B, 256 KB: skipped. Probing for SST SST49LF003A/B, 384 KB: skipped. Probing for SST SST49LF004A/B, 512 KB: skipped. Probing for SST SST49LF004C, 512 KB: skipped. Probing for SST SST49LF008A, 1024 KB: skipped. Probing for SST SST49LF008C, 1024 KB: skipped. Probing for SST SST49LF016C, 2048 KB: skipped. Probing for SST SST49LF020, 256 KB: skipped. Probing for SST SST49LF020A, 256 KB: skipped. Probing for SST SST49LF040, 512 KB: skipped. Probing for SST SST49LF040B, 512 KB: skipped. Probing for SST SST49LF080A, 1024 KB: skipped. Probing for SST SST49LF160C, 2048 KB: skipped. Probing for ST M25P05-A, 64 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P05.RES, 64 KB: Ignoring RES in favour of RDID. Probing for ST M25P10-A, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P10.RES, 128 KB: Ignoring RES in favour of RDID. Probing for ST M25P20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P40-old, 512 KB: Ignoring RES in favour of RDID. Probing for ST M25P80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M25P128, 16384 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST M29F002B, 256 KB: skipped. Probing for ST M29F002T/NT, 256 KB: skipped. Probing for ST M29F040B, 512 KB: skipped. Probing for ST M29F400BT, 512 KB: skipped. Probing for ST M29W010B, 128 KB: skipped. Probing for ST M29W040B, 512 KB: skipped. Probing for ST M29W512B, 64 KB: skipped. Probing for ST M50FLW040A, 512 KB: skipped. Probing for ST M50FLW040B, 512 KB: skipped. Probing for ST M50FLW080A, 1024 KB: skipped. Probing for ST M50FLW080B, 1024 KB: skipped. Probing for ST M50FW002, 256 KB: skipped. Probing for ST M50FW016, 2048 KB: skipped. Probing for ST M50FW040, 512 KB: skipped. Probing for ST M50FW080, 1024 KB: skipped. Probing for ST M50LPW116, 2048 KB: skipped. Probing for SyncMOS S29C31004T, 512 KB: skipped. Probing for SyncMOS S29C51001T, 128 KB: skipped. Probing for SyncMOS S29C51002T, 256 KB: skipped. Probing for SyncMOS S29C51004T, 512 KB: skipped. Probing for TI TMS29F002RB, 256 KB: skipped. Probing for TI TMS29F002RT, 256 KB: skipped. Probing for Winbond W25Q80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25Q16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25Q32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25Q64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x10, 128 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x20, 256 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x40, 512 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Chip status register is 00 Found chip "Winbond W25x80" (1024 KB, SPI) at physical address 0xfff00000. Probing for Winbond W25x16, 2048 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x32, 4096 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W25x64, 8192 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Winbond W29C011, 128 KB: skipped. Probing for Winbond W29C020C, 256 KB: skipped. Probing for Winbond W29C040P, 512 KB: skipped. Probing for Winbond W29EE011, 128 KB: skipped. Probing for Winbond W39V040A, 512 KB: skipped. Probing for Winbond W39V040B, 512 KB: skipped. Probing for Winbond W39V040C, 512 KB: skipped. Probing for Winbond W39V040FA, 512 KB: skipped. Probing for Winbond W39V080A, 1024 KB: skipped. Probing for Winbond W49F002U, 256 KB: skipped. Probing for Winbond W49V002A, 256 KB: skipped. Probing for Winbond W49V002FA, 256 KB: skipped. Probing for Winbond W39V080FA, 1024 KB: skipped. Probing for Winbond W39V080FA (dual mode), 512 KB: skipped. Probing for Atmel unknown Atmel SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for EON unknown EON SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Macronix unknown Macronix SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for PMC unknown PMC SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for SST unknown SST SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for ST unknown ST SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Sanyo unknown Sanyo SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Generic unknown SPI chip (RDID), 0 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Probing for Generic unknown SPI chip (REMS), 0 KB: probe_spi_rems: id1 0xef, id2 0x13 === This flash part has status UNTESTED for operations: ERASE The test status of this chip may have been updated in the latest development version of flashrom. If you are running the latest development version, please email a report to flashrom@flashrom.org if any of the above operations work correctly for you with this flash part. Please include the flashrom output with the additional -V option for all operations you tested (-V, -Vr, -Vw, -VE), and mention which mainboard or programmer you tested. Thanks for your help! === No operations were specified.
On Sat, 03 Jul 2010 15:29:19 +0200 Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Hello Carl-Daniel,
MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers
O/P as follows for (with patches applied to SVN source) ASUS M3N78 PRO;
flashrom v0.9.2-r1069 on Linux 2.6.32-5-amd64 (x86_64), built with libpci 3.1.7, GCC 4.4.4, little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 1 usecs, 1546M loops per second, 10 myus = 11 us, 100 myus = 101 us, 1000 myus = 1004 us, 10000 myus = 10011 us, 4 myus = 5 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "System manufacturer" DMI string system-product-name: "System Product Name" DMI string system-version: "System Version" DMI string baseboard-manufacturer: "ASUSTeK Computer INC." DMI string baseboard-product-name: "M3N78 PRO" DMI string baseboard-version: "1.XX" DMI string chassis-type: "Desktop" Found ITE Super I/O, id 8716 Found chipset "NVIDIA MCP78S", enabling flash write... chipset PCI ID is 10de:075c, This chipset is not really supported yet. Guesswork... ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Guessed flash bus type is SPI Found SMBus device 10de:0752 at 00:01:1 SPI BAR is at 0xfdf80000, after clearing low bits BAR is at 0xfdf80000 SPI control is 0xc01a, enable=0, idle=0 Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks. OK. This chipset supports the following protocols: SPI. No IT87* serial flash segment enabled. Probing for AMD Am29F010A/B, 128 KB: skipped. Probing for AMD Am29F002(N)BB, 256 KB: skipped. Probing for AMD Am29F002(N)BT, 256 KB: skipped. Probing for AMD Am29F016D, 2048 KB: skipped. Probing for AMD Am29F040B, 512 KB: skipped. Probing for AMD Am29F080B, 1024 KB: skipped. Probing for AMD Am29LV040B, 512 KB: skipped. Probing for AMD Am29LV081B, 1024 KB: skipped. Probing for ASD AE49F2008, 256 KB: skipped. Probing for Atmel AT25DF021, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25DF041A, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25DF081, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25DF161, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25DF321, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25DF321A, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25DF641, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25F512B, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25FS010, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT25FS040, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT26DF041, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT26DF081A, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT26DF161, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT26DF161A, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT26F004, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT29C512, 64 KB: skipped. Probing for Atmel AT29C010A, 128 KB: skipped. Probing for Atmel AT29C020, 256 KB: skipped. Probing for Atmel AT29C040A, 512 KB: skipped. Probing for Atmel AT45CS1282, 16896 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB011D, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB021D, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB041D, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB081D, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB161D, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB321C, 4224 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB321D, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT45DB642D, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Atmel AT49BV512, 64 KB: skipped. Probing for Atmel AT49F020, 256 KB: skipped. Probing for Atmel AT49F002(N), 256 KB: skipped. Probing for Atmel AT49F002(N)T, 256 KB: skipped. Probing for AMIC A25L40PT, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for AMIC A25L40PU, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for AMIC A29002B, 256 KB: skipped. Probing for AMIC A29002T, 256 KB: skipped. Probing for AMIC A29040B, 512 KB: skipped. Probing for AMIC A49LF040A, 512 KB: skipped. Probing for EMST F49B002UA, 256 KB: skipped. Probing for EMST F25L008A, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B05, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B05T, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B10, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B10T, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B20, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B20T, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B40, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B40T, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B80, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B80T, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B16T, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B32, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B32T, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B64, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25B64T, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25D16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F05, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F10, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F20, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F40, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F80, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN25F32, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Eon EN29F010, 128 KB: skipped. Probing for EON EN29F002(A)(N)B, 256 KB: skipped. Probing for EON EN29F002(A)(N)T, 256 KB: skipped. Probing for Fujitsu MBM29F004BC, 512 KB: skipped. Probing for Fujitsu MBM29F004TC, 512 KB: skipped. Probing for Fujitsu MBM29F400BC, 512 KB: skipped. Probing for Fujitsu MBM29F400TC, 512 KB: skipped. Probing for Hyundai HY29F002T, 256 KB: skipped. Probing for Hyundai HY29F002B, 256 KB: skipped. Probing for Intel 28F001BX-B, 128 KB: skipped. Probing for Intel 28F001BX-T, 128 KB: skipped. Probing for Intel 28F004S5, 512 KB: skipped. Probing for Intel 28F004BV/BE-B, 512 KB: skipped. Probing for Intel 28F004BV/BE-T, 512 KB: skipped. Probing for Intel 28F400BV/CV/CE-B, 512 KB: skipped. Probing for Intel 28F400BV/CV/CE-T, 512 KB: skipped. Probing for Intel 82802AB, 512 KB: skipped. Probing for Intel 82802AC, 1024 KB: skipped. Probing for Macronix MX25L512, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L1005, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L2005, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L4005, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "Macronix MX25L8005" (1024 KB, SPI) at physical address 0xfff00000. Probing for Macronix MX25L1605, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L1635D, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L3205, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L3235D, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L6405, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX25L12805, 16384 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix MX29F001B, 128 KB: skipped. Probing for Macronix MX29F001T, 128 KB: skipped. Probing for Macronix MX29F002B, 256 KB: skipped. Probing for Macronix MX29F002T, 256 KB: skipped. Probing for Macronix MX29LV040, 512 KB: skipped. Probing for Numonyx M25PE10, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Numonyx M25PE20, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Numonyx M25PE40, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Numonyx M25PE80, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Numonyx M25PE16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm25LV010, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm25LV016B, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm25LV020, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm25LV040, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm25LV080B, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm25LV512, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC Pm29F002T, 256 KB: skipped. Probing for PMC Pm29F002B, 256 KB: skipped. Probing for PMC Pm39LV010, 128 KB: skipped. Probing for PMC Pm39LV020, 256 KB: skipped. Probing for PMC Pm39LV040, 512 KB: skipped. Probing for PMC Pm49FL002, 256 KB: skipped. Probing for PMC Pm49FL004, 512 KB: skipped. Probing for Sanyo LF25FW203A, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Sharp LHF00L04, 1024 KB: skipped. Probing for Spansion S25FL008A, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Spansion S25FL016A, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for SST SST25VF016B, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for SST SST25VF032B, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for SST SST25VF040.REMS, 512 KB: probe_spi_rems: id1 0xc2, id2 0x13 Probing for SST SST25VF040B, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for SST SST25LF040A.RES, 512 KB: probe_spi_res2: id1 0x13, id2 0x13 Probing for SST SST25VF040B.REMS, 512 KB: probe_spi_rems: id1 0xc2, id2 0x13 Probing for SST SST25VF080B, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for SST SST28SF040A, 512 KB: skipped. Probing for SST SST29EE010, 128 KB: skipped. Probing for SST SST29LE010, 128 KB: skipped. Probing for SST SST29EE020A, 256 KB: skipped. Probing for SST SST29LE020, 256 KB: skipped. Probing for SST SST39SF512, 64 KB: skipped. Probing for SST SST39SF010A, 128 KB: skipped. Probing for SST SST39SF020A, 256 KB: skipped. Probing for SST SST39SF040, 512 KB: skipped. Probing for SST SST39VF512, 64 KB: skipped. Probing for SST SST39VF010, 128 KB: skipped. Probing for SST SST39VF020, 256 KB: skipped. Probing for SST SST39VF040, 512 KB: skipped. Probing for SST SST39VF080, 1024 KB: skipped. Probing for SST SST49LF002A/B, 256 KB: skipped. Probing for SST SST49LF003A/B, 384 KB: skipped. Probing for SST SST49LF004A/B, 512 KB: skipped. Probing for SST SST49LF004C, 512 KB: skipped. Probing for SST SST49LF008A, 1024 KB: skipped. Probing for SST SST49LF008C, 1024 KB: skipped. Probing for SST SST49LF016C, 2048 KB: skipped. Probing for SST SST49LF020, 256 KB: skipped. Probing for SST SST49LF020A, 256 KB: skipped. Probing for SST SST49LF040, 512 KB: skipped. Probing for SST SST49LF040B, 512 KB: skipped. Probing for SST SST49LF080A, 1024 KB: skipped. Probing for SST SST49LF160C, 2048 KB: skipped. Probing for ST M25P05-A, 64 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P05.RES, 64 KB: Ignoring RES in favour of RDID. Probing for ST M25P10-A, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P10.RES, 128 KB: Ignoring RES in favour of RDID. Probing for ST M25P20, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P40, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P40-old, 512 KB: Ignoring RES in favour of RDID. Probing for ST M25P80, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P32, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P64, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M25P128, 16384 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST M29F002B, 256 KB: skipped. Probing for ST M29F002T/NT, 256 KB: skipped. Probing for ST M29F040B, 512 KB: skipped. Probing for ST M29F400BT, 512 KB: skipped. Probing for ST M29W010B, 128 KB: skipped. Probing for ST M29W040B, 512 KB: skipped. Probing for ST M29W512B, 64 KB: skipped. Probing for ST M50FLW040A, 512 KB: skipped. Probing for ST M50FLW040B, 512 KB: skipped. Probing for ST M50FLW080A, 1024 KB: skipped. Probing for ST M50FLW080B, 1024 KB: skipped. Probing for ST M50FW002, 256 KB: skipped. Probing for ST M50FW016, 2048 KB: skipped. Probing for ST M50FW040, 512 KB: skipped. Probing for ST M50FW080, 1024 KB: skipped. Probing for ST M50LPW116, 2048 KB: skipped. Probing for SyncMOS S29C31004T, 512 KB: skipped. Probing for SyncMOS S29C51001T, 128 KB: skipped. Probing for SyncMOS S29C51002T, 256 KB: skipped. Probing for SyncMOS S29C51004T, 512 KB: skipped. Probing for TI TMS29F002RB, 256 KB: skipped. Probing for TI TMS29F002RT, 256 KB: skipped. Probing for Winbond W25Q80, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25Q16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25Q32, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25Q64, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x10, 128 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x20, 256 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x40, 512 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x16, 2048 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x32, 4096 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W25x64, 8192 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Winbond W29C011, 128 KB: skipped. Probing for Winbond W29C020C, 256 KB: skipped. Probing for Winbond W29C040P, 512 KB: skipped. Probing for Winbond W29EE011, 128 KB: skipped. Probing for Winbond W39V040A, 512 KB: skipped. Probing for Winbond W39V040B, 512 KB: skipped. Probing for Winbond W39V040C, 512 KB: skipped. Probing for Winbond W39V040FA, 512 KB: skipped. Probing for Winbond W39V080A, 1024 KB: skipped. Probing for Winbond W49F002U, 256 KB: skipped. Probing for Winbond W49V002A, 256 KB: skipped. Probing for Winbond W49V002FA, 256 KB: skipped. Probing for Winbond W39V080FA, 1024 KB: skipped. Probing for Winbond W39V080FA (dual mode), 512 KB: skipped. Probing for Atmel unknown Atmel SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for EON unknown EON SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Macronix unknown Macronix SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for PMC unknown PMC SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for SST unknown SST SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for ST unknown ST SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Sanyo unknown Sanyo SPI chip, 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Generic unknown SPI chip (RDID), 0 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Probing for Generic unknown SPI chip (REMS), 0 KB: probe_spi_rems: id1 0xc2, id2 0x13 === This flash part has status UNTESTED for operations: ERASE The test status of this chip may have been updated in the latest development version of flashrom. If you are running the latest development version, please email a report to flashrom@flashrom.org if any of the above operations work correctly for you with this flash part. Please include the flashrom output with the additional -V option for all operations you tested (-V, -Vr, -Vw, -VE), and mention which mainboard or programmer you tested. Thanks for your help! === No operations were specified.
On 07/03/2010 04:29 PM, Carl-Daniel Hailfinger wrote:
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers
I also did a read test but result differs from bios image downloaded from mainboard manufacturer. Should this match only when default bios settings are used?
On 04.07.2010 10:11, Kimmo Vuorinen wrote:
On 07/03/2010 04:29 PM, Carl-Daniel Hailfinger wrote:
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers
I also did a read test but result differs from bios image downloaded from mainboard manufacturer. Should this match only when default bios settings are used?
If you downloaded exactly the same BIOS version as is installed on your mainboard, only a few places (total maybe 4 kBytes) should differ. Newer BIOSes often store DMI information and boot time and network card MAC addresses in the flash chip, and those regions are thus expected to differ from the download.
Regards, Carl-Daniel
On 04/07/10 09:11, Kimmo Vuorinen wrote:
On 07/03/2010 04:29 PM, Carl-Daniel Hailfinger wrote:
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers
I also did a read test but result differs from bios image downloaded from mainboard manufacturer. Should this match only when default bios settings are used?
I found they didn't match on mine either, because of network card MAC address and other settings. I compared them by first running hexdump on each image, then running diff on the two resulting files. Large chunks were the same, and then some chunks were different, but the different chunks were all 0xFF or 0x00 in the downloaded file. They were similar enough for me. :)
Hi,
I am not very experienced with patching in SVN....
Please find attached file output.txt
and left on terminal:
sudo ./flashrom -V > output.txt Mapping Nvidia MCP6x SPI at 0xfec80000, unaligned size 0x544. SPI on this chipset is WIP. DO NOT USE!
Am 03.07.2010 15:29, schrieb Carl-Daniel Hailfinger:
Hi,
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP61: Andrew Cleveland, Free Wind, Andre Robatino, Антон Кочков, Benjamin Henrion, Chris Yagami, Jim Lunsford MCP65: Kjell Braden, Mark Morschhäuser, Melchior FRANZ, Wolfgang Schnitker MCP67: Alessandro Polverini, NotLim MCP73: Noe, Maik Masling MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers MCP79: Alex Neblett, J.P. Krauss, Ivo Anjo, Halim Sahin, Joakim Gissberg, Benjamin Eugler
This code has been tested for probe/read for the following chipsets: MCP65: Johannes Sjölund MCP79: Andrew Morgan
coreboot.org/project/flashrom/list/ in case your mailer corrupts the patch. It applies against latest clean svn tree.
Here's my report for:
NVIDIA MCP65 MSI MS-7369 "K9N Neo V2" v1.0 (2007)
After the -V run the machine still booted and behaves normally. :-) Here the relevant lines from the output:
Found chipset "NVIDIA MCP65", enabling flash write... chipset PCI ID is 10de:0441 ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Guessed flash bus type is SPI Found SMBus device 10de:0446 at 00:01:1 SPI BAR is at 0xfec80000, after clearing low bits BAR is at 0xfec80000 SPI control is 0x0002, enable=0, idle=0
Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Chip status register is 00 Found chip "Winbond W25x80" (1024 KB, SPI) at physical address 0xfff00000.
m.
On 04.07.2010 14:56, Melchior FRANZ wrote:
Here's my report for:
NVIDIA MCP65 MSI MS-7369 "K9N Neo V2" v1.0 (2007)
After the -V run the machine still booted and behaves normally. :-) Here the relevant lines from the output:
Found chipset "NVIDIA MCP65", enabling flash write... chipset PCI ID is 10de:0441 ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Guessed flash bus type is SPI Found SMBus device 10de:0446 at 00:01:1 SPI BAR is at 0xfec80000, after clearing low bits BAR is at 0xfec80000 SPI control is 0x0002, enable=0, idle=0
Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Chip status register is 00 Found chip "Winbond W25x80" (1024 KB, SPI) at physical address 0xfff00000.
m.
Not sure if that's relevant, but I seem have the same board and my results differ:
--- Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "Macronix MX25L8005" (1024 KB, SPI) at physical address 0xfff00000. ---
See my other reply from July 3 for the full output.
HTH -Kjell
On 07.07.2010 18:17, Kjell Braden wrote:
On 04.07.2010 14:56, Melchior FRANZ wrote:
NVIDIA MCP65 MSI MS-7369 "K9N Neo V2" v1.0 (2007)
After the -V run the machine still booted and behaves normally. :-) Here the relevant lines from the output:
Found chipset "NVIDIA MCP65", enabling flash write... chipset PCI ID is 10de:0441 Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Found chip "Winbond W25x80" (1024 KB, SPI) at physical address 0xfff00000.
Not sure if that's relevant, but I seem have the same board and my results differ:
Probing for Macronix MX25L8005, 1024 KB: probe_spi_rdid_generic: id1 0xc2, id2 0x2014 Found chip "Macronix MX25L8005" (1024 KB, SPI) at physical address 0xfff00000.
It's not unusual for mainboard vendors to use multiple sources for flash chips. The two flash chips in question speak the same protocol and have the same size, and are compatible. Due to that, the only deciding factors are price and availability. Programming speed may or may not be a factor, but it usually improves each time the production process is upgraded, so it might make sense to switch vendors multiple times.
Regards, Carl-Daniel
Dear flashrom devs, thx for notifying, here's a log of flashrom -V @svn rev 1075 (plus this patch) on an Asus M3N78-VM (the ECS GF8100VM-M3 i had reported back with earlier unfortunately died a smoking death...). Hope it is of some use... Best Regards, Marcel.
On 03/07/10 15:29, Carl-Daniel Hailfinger wrote:
Hi,
you have sent a report for a mainboard with Nvidia nForce chipset, and we now have a patch to support your chipset and would appreciate if you could test (unless you can't recover in case something goes wrong).
The following chipsets would be nice to get reports for: MCP61: Andrew Cleveland, Free Wind, Andre Robatino, Антон Кочков, Benjamin Henrion, Chris Yagami, Jim Lunsford MCP65: Kjell Braden, Mark Morschhäuser, Melchior FRANZ, Wolfgang Schnitker MCP67: Alessandro Polverini, NotLim MCP73: Noe, Maik Masling MCP78S: Ivo Anjo, Julian Hughes, Dietmar Gaffron, Kimmo Vuorinen, Urja Rannikko, ataya65, Vikram Noel Ambrose, Marcel Partap, antioxid, Rainer Stumbaum, Brad Rogers MCP79: Alex Neblett, J.P. Krauss, Ivo Anjo, Halim Sahin, Joakim Gissberg, Benjamin Eugler
This code has been tested for probe/read for the following chipsets: MCP65: Johannes Sjölund MCP79: Andrew Morgan
Testing instructions
This patch may fry your flash chip, explode mysteriously and abduct your dog, but so far it looks good. Do NOT try to read/write/erase with this code until we know that it behaves correctly.
Please apply this patch to the latest flashrom svn (subversion) tree, recompile and then run flashrom -V This command should be reasonably safe (it only tries to identify your flash chip), but if you don't have a way to recover from a bad flash, please don't try it. Then please mail the output from the command above to the flashrom mailing list (preferably as reply to this mail). Doing this on your boards with newer (last 5 years) Nvidia nForce chipsets would be highly appreciated.
You can also find this patch near the top at http://patchwork.coreboot.org/project/flashrom/list/ in case your mailer corrupts the patch. It applies against latest clean svn tree.
Patch description
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support. Fix a few problems in the previously unused SPI bitbanging core.
Huge thanks go to Michael Karcher for reverse engineering the interface and to Johannes Sjölund for testing multiple iterations of my patch on his hardware until it worked.
Signed-off-by: Carl-Daniel Hailfingerc-d.hailfinger.devel.2006@gmx.net
Index: flashrom-bitbang_spi_nvidia_mcp/flash.h
--- flashrom-bitbang_spi_nvidia_mcp/flash.h (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/flash.h (Arbeitskopie) @@ -128,13 +128,16 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__)
- BITBANG_SPI_MASTER_MCP,
+#endif +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
extern const int bitbang_spi_master_count;
-extern enum bitbang_spi_master bitbang_spi_master;
- struct bitbang_spi_master_entry { void (*set_cs) (int val); void (*set_sck) (int val);
@@ -530,10 +533,22 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +extern void *mcp6x_spibar; +int mcp6x_spi_init(void); +void mcp6x_bitbang_set_cs(int val); +void mcp6x_bitbang_set_sck(int val); +void mcp6x_bitbang_set_mosi(int val); +int mcp6x_bitbang_get_miso(void); +#endif +#endif
- /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[];
-int bitbang_spi_init(void); +int bitbang_spi_init(enum bitbang_spi_master master); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); @@ -637,6 +652,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO,
- SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if CONFIG_FT2232_SPI == 1
Index: flashrom-bitbang_spi_nvidia_mcp/hwaccess.h
--- flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/hwaccess.h (Arbeitskopie) @@ -176,6 +176,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order:
- OUT[BWL](val, port)
- */
- #if defined(__FreeBSD__) || defined(__DragonFly__) #include<machine/cpufunc.h> #define off64_t off_t
Index: flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c
--- flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/bitbang_spi.c (Arbeitskopie) @@ -26,17 +26,29 @@ #include "chipdrivers.h" #include "spi.h"
-/* Length of half a clock period in usecs */ -int bitbang_spi_half_period = 0; +/* Length of half a clock period in usecs. Default to 1 (500 kHz). */ +int bitbang_spi_half_period = 1;
enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__)
- {
.set_cs = mcp6x_bitbang_set_cs,
.set_sck = mcp6x_bitbang_set_sck,
.set_mosi = mcp6x_bitbang_set_mosi,
.get_miso = mcp6x_bitbang_get_miso,
- },
+#endif +#endif
{}, /* This entry corresponds to BITBANG_SPI_INVALID. */ };
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -57,10 +69,18 @@ return bitbang_spi_master_table[bitbang_spi_master].get_miso(); }
-int bitbang_spi_init(void) +int bitbang_spi_init(enum bitbang_spi_master master) {
- bitbang_spi_master = master;
- if (bitbang_spi_master == BITBANG_SPI_INVALID) {
msg_perr("Invalid bitbang SPI master. \n"
"Please report a bug at flashrom@flashrom.org\n");
return 1;
- } bitbang_spi_set_cs(1); bitbang_spi_set_sck(0);
- bitbang_spi_set_mosi(0); buses_supported = CHIP_BUSTYPE_SPI; return 0; }
@@ -87,6 +107,7 @@ { static unsigned char *bufout = NULL; static unsigned char *bufin = NULL;
- unsigned char *tmp; static int oldbufsize = 0; int bufsize; int i;
@@ -98,20 +119,34 @@ bufsize = max(writecnt + readcnt, 260); /* Never shrink. realloc() calls are expensive. */ if (bufsize> oldbufsize) {
bufout = realloc(bufout, bufsize);
if (!bufout) {
tmp = realloc(bufout, bufsize);
if (!tmp) { msg_perr("Out of memory!\n");
if (bufout)
free(bufout);
bufout = NULL; if (bufin) free(bufin);
bufin = NULL;
oldbufsize = 0; exit(1);
}
bufin = realloc(bufout, bufsize);
if (!bufin) {
} else
bufout = tmp;
tmp = realloc(bufin, bufsize);
if (!tmp) { msg_perr("Out of memory!\n");
if (bufin)
free(bufin);
bufin = NULL; if (bufout) free(bufout);
bufout = NULL;
oldbufsize = 0; exit(1);
}
} else
bufin = tmp;
- oldbufsize = bufsize; }
@@ -135,8 +170,13 @@
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) {
- /* Maximum read length is unlimited, use 64k bytes. */
- return spi_read_chunked(flash, buf, start, len, 64 * 1024);
/* Maximum read length is unlimited in theory.
* The current implementation can handle reads of up to 65536 bytes.
* Please note that you need two buffers of 2n+4 bytes each for a read
* of n bytes, resulting in a total memory requirement of 4n+8 bytes.
* To conserve memory, read in chunks of 256 bytes.
*/
return spi_read_chunked(flash, buf, start, len, 256); }
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf)
Index: flashrom-bitbang_spi_nvidia_mcp/spi.c
--- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -82,6 +82,13 @@ .read = wbsio_spi_read, .write_256 = wbsio_spi_write_1, },
- { /* SPI_CONTROLLER_MCP6X_BITBANG */
.command = bitbang_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = bitbang_spi_read,
.write_256 = bitbang_spi_write_256,
- }, #endif #endif
Index: flashrom-bitbang_spi_nvidia_mcp/Makefile
--- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -111,8 +111,12 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_INTERNAL), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -155,7 +159,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c
--- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1069) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -1124,10 +1124,8 @@ { int ret = 0; uint8_t val;
- uint16_t status; char *busname;
- uint32_t mcp_spibaraddr;
- void *mcp_spibar;
uint32_t mcp6x_spibaraddr; struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n");
@@ -1176,40 +1174,33 @@ smbusdev->bus, smbusdev->dev, smbusdev->func);
/* Locate the BAR where the SPI interface lives. */
- mcp_spibaraddr = pci_read_long(smbusdev, 0x74);
- msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr);
- mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74);
- msg_pdbg("SPI BAR is at 0x%08x, ", mcp6x_spibaraddr); /* We hope this has native alignment. We know the SPI interface (well,
*/
- a set of GPIOs that is connected to SPI flash) is at offset 0x530,
- so we expect a size of at least 0x800. Clear the lower bits.
- It is entirely possible that the BAR is 64k big and the low bits are
- reserved for an entirely different purpose.
- mcp_spibaraddr&= ~0x7ff;
- msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr);
mcp6x_spibaraddr&= ~0x7ff;
msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp6x_spibaraddr);
/* Accessing a NULL pointer BAR is evil. Don't do it. */
- if (mcp_spibaraddr&& (buses_supported == CHIP_BUSTYPE_SPI)) {
- if (mcp6x_spibaraddr&& (buses_supported == CHIP_BUSTYPE_SPI)) { /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */
mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544);
mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544);
-/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1<< 1) -#define MCP67_SPI_SCK (1<< 2) -#define MCP67_SPI_MOSI (1<< 3) -#define MCP67_SPI_MISO (1<< 4) -#define MCP67_SPI_ENABLE (1<< 0) -#define MCP67_SPI_IDLE (1<< 8)
status = mmio_readw(mcp_spibar + 0x530);
msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n",
status, status& 0x1, (status>> 8)& 0x1);
if (mcp6x_spi_init())
ret = 1;
+#if 0 /* FIXME: Remove the physunmap once the SPI driver exists. */
physunmap(mcp_spibar, 0x544);
- } else if (!mcp_spibaraddr&& (buses_supported& CHIP_BUSTYPE_SPI)) {
physunmap(mcp6x_spibar, 0x544);
+#endif
- } else if (!mcp6x_spibaraddr&& (buses_supported& CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); buses_supported&= ~CHIP_BUSTYPE_SPI; ret = 1;
- } else if (mcp_spibaraddr&& !(buses_supported& CHIP_BUSTYPE_SPI)) {
- } else if (mcp6x_spibaraddr&& !(buses_supported& CHIP_BUSTYPE_SPI)) { msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" " doesn't have SPI enabled.\n"); } else {
@@ -1247,8 +1238,8 @@ result = enable_flash_mcp55(dev, name); break; case CHIP_BUSTYPE_SPI:
msg_pinfo("SPI on this chipset is not supported yet.\n");
buses_supported = CHIP_BUSTYPE_NONE;
msg_perr("SPI on this chipset is WIP. DO NOT USE!\n");
break; default: msg_pinfo("Something went wrong with bus type detection.\n");programmer_may_write = 0;
@@ -1273,8 +1264,8 @@ msg_pinfo("LPC on this chipset is not supported yet.\n"); break; case CHIP_BUSTYPE_SPI:
msg_pinfo("SPI on this chipset is not supported yet.\n");
buses_supported = CHIP_BUSTYPE_NONE;
msg_perr("SPI on this chipset is WIP. DO NOT USE!\n");
break; default: msg_pinfo("Something went wrong with bus type detection.\n");programmer_may_write = 0;
Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c
--- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,132 @@ +/*
- This file is part of the flashrom project.
- Copyright (C) 2010 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.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
+/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller.
- Based on clean room reverse engineered docs from
- created by Michael Karcher.
- */
+#if defined(__i386__) || defined(__x86_64__)
+#include<stdint.h> +#include<stdlib.h> +#include<ctype.h> +#include "flash.h"
+/* We have two sets of pins, out and in. The numbers for both sets are
- independent and are bitshift values, not real pin numbers.
- */
+/* Guessed. */ +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_ENABLE 0 +#define MCP6X_SPI_IDLE 8
+void *mcp6x_spibar = NULL;
+void mcp6x_request_spibus(void) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte |= 1<< MCP6X_SPI_ENABLE;
- mmio_writeb(byte, mcp6x_spibar + 0x530);
- /* Wait until we are allowed to use the SPI bus. */
- while (!(mmio_readw(mcp6x_spibar + 0x530)& (1<< MCP6X_SPI_IDLE))) ;
+}
+void mcp6x_release_spibus(void) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_ENABLE);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+void mcp6x_bitbang_set_cs(int val) +{
- uint8_t byte;
- /* Requesting and releasing the SPI bus is handled in here to allow the
* chipset to use its own SPI engine for native reads.
*/
- if (val == 0)
mcp6x_request_spibus();
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_CS);
- byte |= (val<< MCP6X_SPI_CS);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
- if (val == 1)
mcp6x_release_spibus();
+}
+void mcp6x_bitbang_set_sck(int val) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_SCK);
- byte |= (val<< MCP6X_SPI_SCK);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+void mcp6x_bitbang_set_mosi(int val) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte&= ~(1<< MCP6X_SPI_MOSI);
- byte |= (val<< MCP6X_SPI_MOSI);
- mmio_writeb(byte, mcp6x_spibar + 0x530);
+}
+int mcp6x_bitbang_get_miso(void) +{
- uint8_t byte;
- byte = mmio_readb(mcp6x_spibar + 0x530);
- byte = (byte>> MCP6X_SPI_MISO)& 0x1;
- return byte;
+}
+int mcp6x_spi_init(void) +{
- uint16_t status;
- status = mmio_readw(mcp6x_spibar + 0x530);
- msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n",
status, (status>> MCP6X_SPI_ENABLE)& 0x1,
(status>> MCP6X_SPI_IDLE)& 0x1);
- if (bitbang_spi_init(BITBANG_SPI_MASTER_MCP))
return 1;
- spi_controller = SPI_CONTROLLER_MCP6X_BITBANG;
- return 0;
+}
+#endif
Latest version.
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support.
Huge thanks go to Michael Karcher for reverse engineering the interface and to Johannes Sjölund for testing the first iterations of my patch on his hardware until it worked.
Thanks to the following testers of the patch: * MCP61, 10de:03e0, LPC OK (valid SPIBAR), ECS Geforce6100SM-M, Andrew Cleveland * MCP61, 10de:03e0, LPC OK (valid SPIBAR), Biostar NF520-A2 NF61D-A2, Vitaliy Buchynskyy * MCP65, 10de:0441, SPI OK, MSI MS-7369 K9N Neo-F v2, Kjell Braden * MCP65, 10de:0441, SPI OK, MSI MS-7369, Wolfgang Schnitker * MCP65, 10de:0441, SPI OK, MSI MS-7369, Johannes Sjölund * MCP65, 10de:0441, SPI OK, MSI MS-7369, Melchior Franz * MCP78S, 10de:075c, SPI OK, Asus M3N78 PRO, Brad Rogers * MCP78S, 10de:075c, SPI OK, Asus M3N78-VM, Marcel Partap * MCP78S, 10de:075c, SPI OK, Asus M4N78 PRO, Kimmo Vuorinen * MCP78S, 10de:075c, SPI OK, Asus M4N78 PRO, Vikram Ambrose * MCP79, 10de:0aad, SPI OK, Acer Aspire R3600, Andrew Morgan * MCP79, 10de:0aae, LPC ??, Lenovo Ideapad S12 laptop, Christian Schmitt * MCP79, 10de:0aae, SPI OK, Apple iMac9,1 Mac-F2218EA9, David "dledson"
flashrom will refuse to write/erase for safety reasons if MCP6x/MCP7x SPI is detected.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-bitbang_spi_nvidia_mcp/Makefile =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/Makefile (Revision 1112) +++ flashrom-bitbang_spi_nvidia_mcp/Makefile (Arbeitskopie) @@ -118,8 +118,12 @@ ifeq ($(CONFIG_RAYER_SPI), yes) override CONFIG_BITBANG_SPI = yes else +ifeq ($(CONFIG_INTERNAL), yes) +override CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no endif +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -162,7 +166,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o # FIXME: The PROGRAMMER_OBJS below should only be included on x86. -PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o +PROGRAMMER_OBJS += it87spi.o ichspi.o sb600spi.o wbsio_spi.o mcp6x_spi.o NEED_PCI := yes endif
Index: flashrom-bitbang_spi_nvidia_mcp/spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/spi.c (Revision 1112) +++ flashrom-bitbang_spi_nvidia_mcp/spi.c (Arbeitskopie) @@ -83,6 +83,13 @@ .read = wbsio_spi_read, .write_256 = spi_chip_write_1_new, }, + + { /* SPI_CONTROLLER_MCP6X_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, #endif #endif
Index: flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Revision 1112) +++ flashrom-bitbang_spi_nvidia_mcp/chipset_enable.c (Arbeitskopie) @@ -868,18 +868,16 @@ return 0; }
-/* This is a shot in the dark. Even if the code is totally bogus for some - * chipsets, users will at least start to send in reports. +/** + * The MCP6x/MCP7x code is based on cleanroom reverse engineering. + * It is assumed that LPC chips need the MCP55 code and SPI chips need the + * code provided in enable_flash_mcp6x_7x_common. */ -static int enable_flash_mcp6x_7x_common(struct pci_dev *dev, const char *name) +static int enable_flash_mcp6x_7x(struct pci_dev *dev, const char *name) { int ret = 0; + int want_spi = 0; uint8_t val; - uint16_t status; - char *busname; - uint32_t mcp_spibaraddr; - void *mcp_spibar; - struct pci_dev *smbusdev;
msg_pinfo("This chipset is not really supported yet. Guesswork...\n");
@@ -887,20 +885,31 @@ val = pci_read_byte(dev, 0x8a); msg_pdbg("ISA/LPC bridge reg 0x8a contents: 0x%02x, bit 6 is %i, bit 5 " "is %i\n", val, (val >> 6) & 0x1, (val >> 5) & 0x1); + switch ((val >> 5) & 0x3) { case 0x0: + ret = enable_flash_mcp55(dev, name); buses_supported = CHIP_BUSTYPE_LPC; + msg_pdbg("Flash bus type is LPC\n"); break; case 0x2: - buses_supported = CHIP_BUSTYPE_SPI; + want_spi = 1; + /* SPI is added in mcp6x_spi_init if it works. + * Do we really want to disable LPC in this case? + */ + buses_supported = CHIP_BUSTYPE_NONE; + msg_pdbg("Flash bus type is SPI\n"); + msg_perr("SPI on this chipset is WIP. Write is unsupported!\n"); + programmer_may_write = 0; break; default: - buses_supported = CHIP_BUSTYPE_UNKNOWN; + /* Should not happen. */ + buses_supported = CHIP_BUSTYPE_NONE; + msg_pdbg("Flash bus type is unknown (none)\n"); + msg_pinfo("Something went wrong with bus type detection.\n"); + goto out_msg; break; } - busname = flashbuses_to_text(buses_supported); - msg_pdbg("Guessed flash bus type is %s\n", busname); - free(busname);
/* Force enable SPI and disable LPC? Not a good idea. */ #if 0 @@ -909,62 +918,8 @@ pci_write_byte(dev, 0x8a, val); #endif
- /* Look for the SMBus device (SMBus PCI class) */ - smbusdev = pci_dev_find_vendorclass(0x10de, 0x0c05); - if (!smbusdev) { - if (buses_supported & CHIP_BUSTYPE_SPI) { - msg_perr("ERROR: SMBus device not found. Not enabling " - "SPI.\n"); - buses_supported &= ~CHIP_BUSTYPE_SPI; - ret = 1; - } else { - msg_pinfo("Odd. SMBus device not found.\n"); - } - goto out_msg; - } - msg_pdbg("Found SMBus device %04x:%04x at %02x:%02x:%01x\n", - smbusdev->vendor_id, smbusdev->device_id, - smbusdev->bus, smbusdev->dev, smbusdev->func); - - /* Locate the BAR where the SPI interface lives. */ - mcp_spibaraddr = pci_read_long(smbusdev, 0x74); - msg_pdbg("SPI BAR is at 0x%08x, ", mcp_spibaraddr); - /* We hope this has native alignment. We know the SPI interface (well, - * a set of GPIOs that is connected to SPI flash) is at offset 0x530, - * so we expect a size of at least 0x800. Clear the lower bits. - * It is entirely possible that the BAR is 64k big and the low bits are - * reserved for an entirely different purpose. - */ - mcp_spibaraddr &= ~0x7ff; - msg_pdbg("after clearing low bits BAR is at 0x%08x\n", mcp_spibaraddr); - - /* Accessing a NULL pointer BAR is evil. Don't do it. */ - if (mcp_spibaraddr && (buses_supported == CHIP_BUSTYPE_SPI)) { - /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ - mcp_spibar = physmap("MCP67 SPI", mcp_spibaraddr, 0x544); - -/* Guessed. If this is correct, migrate to a separate MCP67 SPI driver. */ -#define MCP67_SPI_CS (1 << 1) -#define MCP67_SPI_SCK (1 << 2) -#define MCP67_SPI_MOSI (1 << 3) -#define MCP67_SPI_MISO (1 << 4) -#define MCP67_SPI_ENABLE (1 << 0) -#define MCP67_SPI_IDLE (1 << 8) - - status = mmio_readw(mcp_spibar + 0x530); - msg_pdbg("SPI control is 0x%04x, enable=%i, idle=%i\n", - status, status & 0x1, (status >> 8) & 0x1); - /* FIXME: Remove the physunmap once the SPI driver exists. */ - physunmap(mcp_spibar, 0x544); - } else if (!mcp_spibaraddr && (buses_supported & CHIP_BUSTYPE_SPI)) { - msg_pdbg("Strange. MCP SPI BAR is invalid.\n"); - buses_supported &= ~CHIP_BUSTYPE_SPI; + if (mcp6x_spi_init(want_spi)) { ret = 1; - } else if (mcp_spibaraddr && !(buses_supported & CHIP_BUSTYPE_SPI)) { - msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" - " doesn't have SPI enabled.\n"); - } else { - msg_pdbg("MCP SPI is not used.\n"); } out_msg: msg_pinfo("Please send the output of "flashrom -V" to " @@ -974,68 +929,6 @@ return ret; }
-/** - * The MCP61/MCP67 code is guesswork based on cleanroom reverse engineering. - * Due to that, it only reads info and doesn't change any settings. - * It is assumed that LPC chips need the MCP55 code and SPI chips need the - * code provided in enable_flash_mcp6x_7x_common. Until we know for sure, call - * enable_flash_mcp55 from this function only if enable_flash_mcp6x_7x_common - * indicates the flash chip is LPC. Warning: enable_flash_mcp55 - * might make SPI flash inaccessible. The same caveat applies to SPI init - * for LPC flash. - */ -static int enable_flash_mcp67(struct pci_dev *dev, const char *name) -{ - int result = 0; - - result = enable_flash_mcp6x_7x_common(dev, name); - if (result) - return result; - - /* Not sure if this is correct. No docs as usual. */ - switch (buses_supported) { - case CHIP_BUSTYPE_LPC: - result = enable_flash_mcp55(dev, name); - break; - case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; - break; - default: - msg_pinfo("Something went wrong with bus type detection.\n"); - buses_supported = CHIP_BUSTYPE_NONE; - break; - } - - return result; -} - -static int enable_flash_mcp7x(struct pci_dev *dev, const char *name) -{ - int result = 0; - - result = enable_flash_mcp6x_7x_common(dev, name); - if (result) - return result; - - /* Not sure if this is correct. No docs as usual. */ - switch (buses_supported) { - case CHIP_BUSTYPE_LPC: - msg_pinfo("LPC on this chipset is not supported yet.\n"); - break; - case CHIP_BUSTYPE_SPI: - msg_pinfo("SPI on this chipset is not supported yet.\n"); - buses_supported = CHIP_BUSTYPE_NONE; - break; - default: - msg_pinfo("Something went wrong with bus type detection.\n"); - buses_supported = CHIP_BUSTYPE_NONE; - break; - } - - return result; -} - static int enable_flash_ht1000(struct pci_dev *dev, const char *name) { uint8_t val; @@ -1187,22 +1080,22 @@ {0x10de, 0x0365, OK, "NVIDIA", "MCP55", enable_flash_mcp55}, /* LPC */ {0x10de, 0x0366, OK, "NVIDIA", "MCP55", enable_flash_mcp55}, /* LPC */ {0x10de, 0x0367, OK, "NVIDIA", "MCP55", enable_flash_mcp55}, /* Pro */ - {0x10de, 0x03e0, NT, "NVIDIA", "MCP61", enable_flash_mcp67}, - {0x10de, 0x03e1, NT, "NVIDIA", "MCP61", enable_flash_mcp67}, - {0x10de, 0x03e2, NT, "NVIDIA", "MCP61", enable_flash_mcp67}, - {0x10de, 0x03e3, NT, "NVIDIA", "MCP61", enable_flash_mcp67}, - {0x10de, 0x0440, NT, "NVIDIA", "MCP65", enable_flash_mcp7x}, - {0x10de, 0x0441, NT, "NVIDIA", "MCP65", enable_flash_mcp7x}, - {0x10de, 0x0442, NT, "NVIDIA", "MCP65", enable_flash_mcp7x}, - {0x10de, 0x0443, NT, "NVIDIA", "MCP65", enable_flash_mcp7x}, - {0x10de, 0x0548, OK, "NVIDIA", "MCP67", enable_flash_mcp67}, - {0x10de, 0x075c, NT, "NVIDIA", "MCP78S", enable_flash_mcp7x}, - {0x10de, 0x075d, NT, "NVIDIA", "MCP78S", enable_flash_mcp7x}, - {0x10de, 0x07d7, NT, "NVIDIA", "MCP73", enable_flash_mcp7x}, - {0x10de, 0x0aac, NT, "NVIDIA", "MCP79", enable_flash_mcp7x}, - {0x10de, 0x0aad, NT, "NVIDIA", "MCP79", enable_flash_mcp7x}, - {0x10de, 0x0aae, NT, "NVIDIA", "MCP79", enable_flash_mcp7x}, - {0x10de, 0x0aaf, NT, "NVIDIA", "MCP79", enable_flash_mcp7x}, + {0x10de, 0x03e0, NT, "NVIDIA", "MCP61", enable_flash_mcp6x_7x}, + {0x10de, 0x03e1, NT, "NVIDIA", "MCP61", enable_flash_mcp6x_7x}, + {0x10de, 0x03e2, NT, "NVIDIA", "MCP61", enable_flash_mcp6x_7x}, + {0x10de, 0x03e3, NT, "NVIDIA", "MCP61", enable_flash_mcp6x_7x}, + {0x10de, 0x0440, NT, "NVIDIA", "MCP65", enable_flash_mcp6x_7x}, + {0x10de, 0x0441, NT, "NVIDIA", "MCP65", enable_flash_mcp6x_7x}, + {0x10de, 0x0442, NT, "NVIDIA", "MCP65", enable_flash_mcp6x_7x}, + {0x10de, 0x0443, NT, "NVIDIA", "MCP65", enable_flash_mcp6x_7x}, + {0x10de, 0x0548, OK, "NVIDIA", "MCP67", enable_flash_mcp6x_7x}, + {0x10de, 0x075c, NT, "NVIDIA", "MCP78S", enable_flash_mcp6x_7x}, + {0x10de, 0x075d, NT, "NVIDIA", "MCP78S", enable_flash_mcp6x_7x}, + {0x10de, 0x07d7, NT, "NVIDIA", "MCP73", enable_flash_mcp6x_7x}, + {0x10de, 0x0aac, NT, "NVIDIA", "MCP79", enable_flash_mcp6x_7x}, + {0x10de, 0x0aad, NT, "NVIDIA", "MCP79", enable_flash_mcp6x_7x}, + {0x10de, 0x0aae, NT, "NVIDIA", "MCP79", enable_flash_mcp6x_7x}, + {0x10de, 0x0aaf, NT, "NVIDIA", "MCP79", enable_flash_mcp6x_7x}, {0x1039, 0x0496, NT, "SiS", "85C496+497", enable_flash_sis85c496}, {0x1039, 0x0406, NT, "SiS", "501/5101/5501", enable_flash_sis501}, {0x1039, 0x5511, NT, "SiS", "5511", enable_flash_sis5511}, Index: flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) +++ flashrom-bitbang_spi_nvidia_mcp/mcp6x_spi.c (Revision 0) @@ -0,0 +1,193 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the Nvidia MCP6x/MCP7x MCP6X_SPI controller. + * Based on clean room reverse engineered docs from + * http://www.flashrom.org/pipermail/flashrom/2009-December/001180.html + * created by Michael Karcher. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h" +#include "programmer.h" + +/* Bit positions for each pin. */ + +#define MCP6X_SPI_CS 1 +#define MCP6X_SPI_SCK 2 +#define MCP6X_SPI_MOSI 3 +#define MCP6X_SPI_MISO 4 +#define MCP6X_SPI_REQUEST 0 +#define MCP6X_SPI_GRANT 8 + +void *mcp6x_spibar = NULL; + +static void mcp6x_request_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte |= 1 << MCP6X_SPI_REQUEST; + mmio_writeb(byte, mcp6x_spibar + 0x530); + + /* Wait until we are allowed to use the SPI bus. */ + while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_GRANT))) ; +} + +static void mcp6x_release_spibus(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_REQUEST); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +static void mcp6x_bitbang_set_cs(int val) +{ + uint8_t byte; + + /* Requesting and releasing the SPI bus is handled in here to allow the + * chipset to use its own SPI engine for native reads. + */ + if (val == 0) + mcp6x_request_spibus(); + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_CS); + byte |= (val << MCP6X_SPI_CS); + mmio_writeb(byte, mcp6x_spibar + 0x530); + + if (val == 1) + mcp6x_release_spibus(); +} + +static void mcp6x_bitbang_set_sck(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_SCK); + byte |= (val << MCP6X_SPI_SCK); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +static void mcp6x_bitbang_set_mosi(int val) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte &= ~(1 << MCP6X_SPI_MOSI); + byte |= (val << MCP6X_SPI_MOSI); + mmio_writeb(byte, mcp6x_spibar + 0x530); +} + +static int mcp6x_bitbang_get_miso(void) +{ + uint8_t byte; + + byte = mmio_readb(mcp6x_spibar + 0x530); + byte = (byte >> MCP6X_SPI_MISO) & 0x1; + return byte; +} + +static const struct bitbang_spi_master bitbang_spi_master_mcp6x = { + .type = BITBANG_SPI_MASTER_MCP, + .set_cs = mcp6x_bitbang_set_cs, + .set_sck = mcp6x_bitbang_set_sck, + .set_mosi = mcp6x_bitbang_set_mosi, + .get_miso = mcp6x_bitbang_get_miso, +}; + +int mcp6x_spi_init(int want_spi) +{ + uint16_t status; + uint32_t mcp6x_spibaraddr; + struct pci_dev *smbusdev; + + /* Look for the SMBus device (SMBus PCI class) */ + smbusdev = pci_dev_find_vendorclass(0x10de, 0x0c05); + if (!smbusdev) { + if (want_spi) { + msg_perr("ERROR: SMBus device not found. Not enabling " + "SPI.\n"); + return 1; + } else { + msg_pinfo("Odd. SMBus device not found.\n"); + return 0; + } + } + msg_pdbg("Found SMBus device %04x:%04x at %02x:%02x:%01x\n", + smbusdev->vendor_id, smbusdev->device_id, + smbusdev->bus, smbusdev->dev, smbusdev->func); + + + /* Locate the BAR where the SPI interface lives. */ + mcp6x_spibaraddr = pci_read_long(smbusdev, 0x74); + /* BAR size is 64k, bits 15..4 are zero, bit 3..0 declare a + * 32-bit non-prefetchable memory BAR. + */ + mcp6x_spibaraddr &= ~0xffff; + msg_pdbg("MCP SPI BAR is at 0x%08x\n", mcp6x_spibaraddr); + + /* Accessing a NULL pointer BAR is evil. Don't do it. */ + if (!mcp6x_spibaraddr && want_spi) { + msg_perr("Error: Chipset is strapped for SPI, but MCP SPI BAR " + "is invalid.\n"); + return 1; + } else if (!mcp6x_spibaraddr && !want_spi) { + msg_pdbg("MCP SPI is not used.\n"); + return 0; + } else if (mcp6x_spibaraddr && !want_spi) { + msg_pdbg("Strange. MCP SPI BAR is valid, but chipset apparently" + " doesn't have SPI enabled.\n"); + /* FIXME: Should we enable SPI anyway? */ + return 0; + } + /* Map the BAR. Bytewise/wordwise access at 0x530 and 0x540. */ + mcp6x_spibar = physmap("Nvidia MCP6x SPI", mcp6x_spibaraddr, 0x544); + +#if 0 + /* FIXME: Run the physunmap in a shutdown function. */ + physunmap(mcp6x_spibar, 0x544); +#endif + + status = mmio_readw(mcp6x_spibar + 0x530); + msg_pdbg("SPI control is 0x%04x, req=%i, gnt=%i\n", + status, (status >> MCP6X_SPI_REQUEST) & 0x1, + (status >> MCP6X_SPI_GRANT) & 0x1); + + /* 1 usec halfperiod delay for now. */ + if (bitbang_spi_init(&bitbang_spi_master_mcp6x, 1)) { + /* This should never happen. */ + msg_perr("MCP6X bitbang SPI master init failed!\n"); + return 1; + } + + buses_supported |= CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_MCP6X_BITBANG; + + return 0; +} + +#endif Index: flashrom-bitbang_spi_nvidia_mcp/programmer.h =================================================================== --- flashrom-bitbang_spi_nvidia_mcp/programmer.h (Revision 1112) +++ flashrom-bitbang_spi_nvidia_mcp/programmer.h (Arbeitskopie) @@ -110,6 +110,11 @@ #if CONFIG_RAYER_SPI == 1 BITBANG_SPI_MASTER_RAYER, #endif +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) + BITBANG_SPI_MASTER_MCP, +#endif +#endif };
struct bitbang_spi_master { @@ -404,6 +409,13 @@ int rayer_spi_init(void); #endif
+/* mcp6x_spi.c */ +#if CONFIG_INTERNAL == 1 +#if defined(__i386__) || defined(__x86_64__) +int mcp6x_spi_init(int want_spi); +#endif +#endif + /* bitbang_spi.c */ int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); @@ -455,6 +467,7 @@ SPI_CONTROLLER_SB600, SPI_CONTROLLER_VIA, SPI_CONTROLLER_WBSIO, + SPI_CONTROLLER_MCP6X_BITBANG, #endif #endif #if CONFIG_FT2232_SPI == 1
On Wed, Jul 28, 2010 at 03:13:42AM +0200, Carl-Daniel Hailfinger wrote:
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Uwe Hermann uwe@hermann-uwe.de
Looks good, compile-tested and reviewed, also tested on hardware by various people.
+static void mcp6x_request_spibus(void) +{
- uint8_t byte;
You use "byte" in most functions as variable name, but IIRC there were issues on some systems/compilers with this name. I recommend renaming to reg8 or tmp8 or the like.
Uwe.
On 28.07.2010 12:36, Uwe Hermann wrote:
On Wed, Jul 28, 2010 at 03:13:42AM +0200, Carl-Daniel Hailfinger wrote:
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Uwe Hermann uwe@hermann-uwe.de
Looks good, compile-tested and reviewed, also tested on hardware by various people.
+static void mcp6x_request_spibus(void) +{
- uint8_t byte;
You use "byte" in most functions as variable name, but IIRC there were issues on some systems/compilers with this name. I recommend renaming to reg8 or tmp8 or the like.
Thanks for the review. Renamed the identifier and committed in r1113.
Regards, Carl-Daniel
* Carl-Daniel Hailfinger -- Wednesday 28 July 2010:
Add Nvidia nForce MCP61/MCP65/MCP67/MCP78S/MCP73/MCP79 SPI flashing support.
JFTR: On the motherboard which I originally reported ("NVIDIA MCP65, MSI MS-7369 "K9N Neo V2" v1.0 (2007)"), reading and verifying the BIOS was successful using r1182, which is HEAD as of today.
m.
# flashrom -Vr /tmp/bios flashrom v0.9.2-r1182 on Linux 2.6.35.5 (x86_64), built with libpci 3.1.7, GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292], little endian flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop... OS timer resolution is 1 usecs, 1378M loops per second, 10 myus = 11 us, 100 myus = 100 us, 1000 myus = 996 us, 10000 myus = 10214 us, 4 myus = 4 us, OK. Initializing internal programmer No coreboot table found. DMI string system-manufacturer: "MSI" DMI string system-product-name: "MS-7369" DMI string system-version: "1.0" DMI string baseboard-manufacturer: "MSI" DMI string baseboard-product-name: "MS-7369" DMI string baseboard-version: "1.0" DMI string chassis-type: "Desktop" Found chipset "NVIDIA MCP65", enabling flash write... chipset PCI ID is 10de:0441, This chipset is not really supported yet. Guesswork... ISA/LPC bridge reg 0x8a contents: 0x40, bit 6 is 1, bit 5 is 0 Flash bus type is SPI SPI on this chipset is WIP. Write is unsupported! Found SMBus device 10de:0446 at 00:01:1 MCP SPI BAR is at 0xfec80000 Mapping NVIDIA MCP6x SPI at 0xfec80000, unaligned size 0x544. SPI control is 0x0002, req=0, gnt=0 Please send the output of "flashrom -V" to flashrom@flashrom.org to help us finish support for your chipset. Thanks. OK. This chipset supports the following protocols: SPI. [...] Probing for Winbond W25x80, 1024 KB: probe_spi_rdid_generic: id1 0xef, id2 0x3014 Chip status register is 00 Found chip "Winbond W25x80" (1024 KB, SPI) at physical address 0xfff00000. [...]
# flashrom -Vv /tmp/bios [...] Flash image seems to be a legacy BIOS. Disabling checks. Verifying flash... VERIFIED.