[flashrom] [commit] r1151 - trunk

repository service svn at flashrom.org
Fri Sep 3 20:21:21 CEST 2010


Author: uwe
Date: Fri Sep  3 20:21:21 2010
New Revision: 1151
URL: http://flashrom.org/trac/flashrom/changeset/1151

Log:
Add Intel Gigabit NIC SPI flashing support.
Tested on a 82541PI (0x8086, 0x107c) using 32-bit hardware.

The last line in nicintel_request_spibus() could be changed so that FL_BUSY
is used instead.

Shortened sample log:
[...]
Found "Intel 82541PI Gigabit Ethernet Controller" (8086:107c, BDF 01:03.0).
Found chip "ST M25P10.RES" (128 KB, SPI) at physical address 0xfffe0000.
Multiple flash chips were detected: M25P05.RES M25P10.RES
Please specify which chip to use with the -c <chipname> option.
[...]

Signed-off-by: Idwer Vollering <vidwer at gmail.com>
Acked-by: Uwe Hermann <uwe at hermann-uwe.de>

Added:
   trunk/nicintel_spi.c
Modified:
   trunk/Makefile
   trunk/flashrom.8
   trunk/flashrom.c
   trunk/print.c
   trunk/print_wiki.c
   trunk/programmer.h
   trunk/spi.c

Modified: trunk/Makefile
==============================================================================
--- trunk/Makefile	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/Makefile	Fri Sep  3 20:21:21 2010	(r1151)
@@ -121,9 +121,13 @@
 ifeq ($(CONFIG_INTERNAL), yes)
 override CONFIG_BITBANG_SPI = yes
 else
+ifeq ($(CONFIG_NICINTEL_SPI), yes)
+override CONFIG_BITBANG_SPI = yes
+else
 CONFIG_BITBANG_SPI ?= no
 endif
 endif
+endif
 
 # Always enable 3Com NICs for now.
 CONFIG_NIC3COM ?= yes
@@ -153,6 +157,9 @@
 # Disable National Semiconductor NICs until support is complete and tested.
 CONFIG_NICNATSEMI ?= no
 
+# Always enable SPI on Intel NICs for now.
+CONFIG_NICINTEL_SPI ?= yes
+
 # Always enable Bus Pirate SPI for now.
 CONFIG_BUSPIRATE_SPI ?= yes
 
@@ -244,6 +251,12 @@
 NEED_PCI := yes
 endif
 
+ifeq ($(CONFIG_NICINTEL_SPI), yes)
+FEATURE_CFLAGS += -D'CONFIG_NICINTEL_SPI=1'
+PROGRAMMER_OBJS += nicintel_spi.o
+NEED_PCI := yes
+endif
+
 ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_BUSPIRATE_SPI=1'
 PROGRAMMER_OBJS += buspirate_spi.o

Modified: trunk/flashrom.8
==============================================================================
--- trunk/flashrom.8	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/flashrom.8	Fri Sep  3 20:21:21 2010	(r1151)
@@ -190,6 +190,9 @@
 .BR "* rayer_spi" " (for SPI flash ROMs attached to a RayeR parport \
 based programmer)"
 .sp
+.BR "* nicintel_spi" " (for SPI flash ROMs attached to an Intel Gigabit \
+network cards)"
+.sp
 Some programmers have optional or mandatory parameters which are described
 in detail in the
 .B PROGRAMMER SPECIFIC INFO

Modified: trunk/flashrom.c
==============================================================================
--- trunk/flashrom.c	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/flashrom.c	Fri Sep  3 20:21:21 2010	(r1151)
@@ -49,7 +49,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+CONFIG_RAYER_SPI > 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_SPI+CONFIG_NICINTEL_SPI > 1
 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all programmers except one.
 #endif
 enum programmer programmer =
@@ -90,6 +90,9 @@
 #if CONFIG_RAYER_SPI == 1
 	PROGRAMMER_RAYER_SPI
 #endif
+#if CONFIG_NICINTEL_SPI == 1
+	PROGRAMMER_NICINTEL_SPI
+#endif
 ;
 #endif
 
@@ -414,6 +417,25 @@
 	},
 #endif
 
+#if CONFIG_NICINTEL_SPI == 1
+	{
+		.name = "nicintel_spi",
+		.init = nicintel_spi_init,
+		.shutdown = nicintel_spi_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. */
 };
 

Added: trunk/nicintel_spi.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/nicintel_spi.c	Fri Sep  3 20:21:21 2010	(r1151)
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Carl-Daniel Hailfinger
+ * Copyright (C) 2010 Idwer Vollering
+ *
+ * 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
+ */
+
+/*
+ * Datasheet:
+ * PCI/PCI-X Family of Gigabit Ethernet Controllers Software Developer's Manual
+ * 82540EP/EM, 82541xx, 82544GC/EI, 82545GM/EM, 82546GB/EB, and 82547xx
+ * http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf
+ */
+
+#include <stdlib.h>
+#include "flash.h"
+#include "programmer.h"
+
+#define PCI_VENDOR_ID_INTEL 0x8086
+
+#define EECD	0x10
+#define FLA	0x1c
+
+/*
+ * Register bits of EECD.
+ * 
+ * Bit 04, 05: FWE (Flash Write Enable Control)
+ * 00b = not allowed
+ * 01b = flash writes disabled
+ * 10b = flash writes enabled
+ * 11b = not allowed
+ */
+#define FLASH_WRITES_DISABLED	0x10 /* FWE: 10000b */
+#define FLASH_WRITES_ENABLED	0x20 /* FWE: 100000b */
+
+/* Flash Access register bits */
+/* Table 13-9 */
+#define FL_SCK	0
+#define FL_CS	1
+#define FL_SI	2
+#define FL_SO	3
+#define FL_REQ	4
+#define FL_GNT	5
+/* Currently unused */
+// #define FL_BUSY	30
+// #define FL_ER	31
+
+uint8_t *nicintel_spibar;
+
+const struct pcidev_status nics_intel_spi[] = {
+	{PCI_VENDOR_ID_INTEL, 0x107c, OK, "Intel", "82541PI Gigabit Ethernet Controller"},
+
+	{},
+};
+
+static void nicintel_request_spibus(void)
+{
+	uint32_t tmp;
+
+	tmp = pci_mmio_readl(nicintel_spibar + FLA);
+	tmp |= 1 << FL_REQ;
+	pci_mmio_writel(tmp, nicintel_spibar + FLA);
+
+	/* Wait until we are allowed to use the SPI bus. */
+	while (!(pci_mmio_readl(nicintel_spibar + FLA) & (1 << FL_GNT))) ;
+}
+
+static void nicintel_release_spibus(void)
+{
+	uint32_t tmp;
+
+	tmp = pci_mmio_readl(nicintel_spibar + FLA);
+	tmp &= ~(1 << FL_REQ);
+	pci_mmio_writel(tmp, nicintel_spibar + FLA);
+}
+
+static void nicintel_bitbang_set_cs(int val)
+{
+	uint32_t tmp;
+
+	/*
+	 * 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)
+		nicintel_request_spibus();
+
+	tmp = pci_mmio_readl(nicintel_spibar + FLA);
+	tmp &= ~(1 << FL_CS);
+	tmp |= (val << FL_CS);
+	pci_mmio_writel(tmp,  nicintel_spibar + FLA);
+
+	if (val == 1)
+		nicintel_release_spibus();
+}
+
+static void nicintel_bitbang_set_sck(int val)
+{
+	uint32_t tmp;
+
+	tmp = pci_mmio_readl(nicintel_spibar + FLA);
+	tmp &= ~(1 << FL_SCK);
+	tmp |= (val << FL_SCK);
+	pci_mmio_writel(tmp, nicintel_spibar + FLA);
+}
+
+static void nicintel_bitbang_set_mosi(int val)
+{
+	uint32_t tmp;
+
+	tmp = pci_mmio_readl(nicintel_spibar + FLA);
+	tmp &= ~(1 << FL_SI);
+	tmp |= (val << FL_SI);
+	pci_mmio_writel(tmp, nicintel_spibar + FLA);
+}
+
+static int nicintel_bitbang_get_miso(void)
+{
+	uint32_t tmp;
+
+	tmp = pci_mmio_readl(nicintel_spibar + FLA);
+	tmp = (tmp >> FL_SO) & 0x1;
+	return tmp;
+}
+
+static const struct bitbang_spi_master bitbang_spi_master_nicintel = {
+	.type = BITBANG_SPI_MASTER_NICINTEL,
+	.set_cs = nicintel_bitbang_set_cs,
+	.set_sck = nicintel_bitbang_set_sck,
+	.set_mosi = nicintel_bitbang_set_mosi,
+	.get_miso = nicintel_bitbang_get_miso,
+};
+
+int nicintel_spi_init(void)
+{
+	uint32_t tmp;
+
+	get_io_perms();
+
+	io_base_addr = pcidev_init(PCI_VENDOR_ID_INTEL, PCI_BASE_ADDRESS_0,
+				   nics_intel_spi);
+
+	nicintel_spibar = physmap("Intel Gigabit NIC w/ SPI flash",
+				  io_base_addr, 4096);
+	tmp = pci_mmio_readl(nicintel_spibar + EECD);
+	tmp &= ~FLASH_WRITES_DISABLED;
+	tmp |= FLASH_WRITES_ENABLED;
+	pci_mmio_writel(tmp, nicintel_spibar + EECD);
+
+	/* 1 usec halfperiod delay for now. */
+	if (bitbang_spi_init(&bitbang_spi_master_nicintel, 1))
+		return 1;
+
+	buses_supported = CHIP_BUSTYPE_SPI;
+	spi_controller = SPI_CONTROLLER_NICINTEL;
+
+	return 0;
+}
+
+int nicintel_spi_shutdown(void)
+{
+	uint32_t tmp;
+
+	tmp = pci_mmio_readl(nicintel_spibar + EECD);
+	tmp &= ~FLASH_WRITES_ENABLED;
+	tmp |= FLASH_WRITES_DISABLED;
+	pci_mmio_writel(tmp, nicintel_spibar + EECD);
+
+	physunmap(nicintel_spibar, 4096);
+	pci_cleanup(pacc);
+	release_io_perms();
+
+	return 0;
+}

Modified: trunk/print.c
==============================================================================
--- trunk/print.c	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/print.c	Fri Sep  3 20:21:21 2010	(r1151)
@@ -255,6 +255,9 @@
 #if CONFIG_ATAHPT == 1
 		print_supported_pcidevs(ata_hpt);
 #endif
+#if CONFIG_NICINTEL_SPI == 1
+		print_supported_pcidevs(nics_intel_spi);
+#endif
 
 #if CONFIG_FT2232_SPI+CONFIG_DEDIPROG >= 1
 		printf("\nSupported USB devices flashrom can use "

Modified: trunk/print_wiki.c
==============================================================================
--- trunk/print_wiki.c	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/print_wiki.c	Fri Sep  3 20:21:21 2010	(r1151)
@@ -296,6 +296,9 @@
 #if CONFIG_ATAHPT == 1
 	print_supported_pcidevs_wiki(ata_hpt);
 #endif
+#if CONFIG_NICINTEL_SPI == 1
+	print_supported_pcidevs_wiki(nics_intel_spi);
+#endif
 	printf("\n|}\n");
 }
 

Modified: trunk/programmer.h
==============================================================================
--- trunk/programmer.h	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/programmer.h	Fri Sep  3 20:21:21 2010	(r1151)
@@ -37,10 +37,10 @@
 #if CONFIG_NICREALTEK == 1
 	PROGRAMMER_NICREALTEK,
 	PROGRAMMER_NICREALTEK2,
-#endif	
+#endif
 #if CONFIG_NICNATSEMI == 1
 	PROGRAMMER_NICNATSEMI,
-#endif	
+#endif
 #if CONFIG_GFXNVIDIA == 1
 	PROGRAMMER_GFXNVIDIA,
 #endif
@@ -73,6 +73,9 @@
 #if CONFIG_RAYER_SPI == 1
 	PROGRAMMER_RAYER_SPI,
 #endif
+#if CONFIG_NICINTEL_SPI == 1
+	PROGRAMMER_NICINTEL_SPI,
+#endif
 	PROGRAMMER_INVALID /* This must always be the last entry. */
 };
 
@@ -110,6 +113,9 @@
 #if CONFIG_RAYER_SPI == 1
 	BITBANG_SPI_MASTER_RAYER,
 #endif
+#if CONFIG_NICINTEL_SPI == 1
+	BITBANG_SPI_MASTER_NICINTEL,
+#endif
 #if CONFIG_INTERNAL == 1
 #if defined(__i386__) || defined(__x86_64__)
 	BITBANG_SPI_MASTER_MCP,
@@ -207,7 +213,7 @@
 #endif
 
 /* print.c */
-#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT >= 1
+#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_NICINTEL_SPI >= 1
 void print_supported_pcidevs(const struct pcidev_status *devs);
 #endif
 
@@ -378,6 +384,16 @@
 extern const struct pcidev_status nics_natsemi[];
 #endif
 
+/* nicintel_spi.c */
+#if CONFIG_NICINTEL_SPI == 1
+int nicintel_spi_init(void);
+int nicintel_spi_shutdown(void);
+int nicintel_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+	const unsigned char *writearr, unsigned char *readarr);
+void nicintel_spi_chip_writeb(uint8_t val, chipaddr addr);
+extern const struct pcidev_status nics_intel_spi[];
+#endif
+
 /* satasii.c */
 #if CONFIG_SATASII == 1
 int satasii_init(void);
@@ -494,6 +510,9 @@
 #if CONFIG_RAYER_SPI == 1
 	SPI_CONTROLLER_RAYER,
 #endif
+#if CONFIG_NICINTEL_SPI == 1
+	SPI_CONTROLLER_NICINTEL,
+#endif
 	SPI_CONTROLLER_INVALID /* This must always be the last entry. */
 };
 extern const int spi_programmer_count;

Modified: trunk/spi.c
==============================================================================
--- trunk/spi.c	Fri Sep  3 05:35:48 2010	(r1150)
+++ trunk/spi.c	Fri Sep  3 20:21:21 2010	(r1151)
@@ -136,6 +136,15 @@
 	},
 #endif
 
+#if CONFIG_NICINTEL_SPI == 1
+	{ /* SPI_CONTROLLER_NICINTEL */
+		.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. */
 };
 




More information about the flashrom mailing list