Index: sata_sil.c
===================================================================
--- sata_sil.c	(revision 0)
+++ sata_sil.c	(revision 0)
@@ -0,0 +1,146 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "flash.h"
+
+#define PCI_IO_BASE_ADDRESS 0x10
+#define PCI_VENDOR_ID_SIL	0x1095
+
+uint8_t volatile *sil_bar;
+uint16_t id;
+
+struct pcidev_status satas_sil[] = {
+	{0x1095, 0x3114, PCI_NT, "SiI 3114 [SATALink/SATARaid] Serial ATA Controller"},
+	{0x1095, 0x3132, PCI_NT, "SiI 3132 Serial ATA Raid II Controller (rev 01)"},
+	{},
+};
+
+int sata_sil_init(void)
+{
+	uint32_t addr;
+	unit16_t reg_offset;
+
+	get_io_perms();
+
+	pcidev_init(PCI_VENDOR_ID_SIL, satas_sil);
+
+	id = pcidev_dev->device_id;
+
+	if (id == 0x3114)
+		/* BAR 5 */
+		addr = pci_read_long(pcidev_dev, PCI_IO_BASE_ADDRESS + (5 * 4)) & ~0x07;
+		reg_offset = 0x50;
+	else {
+		/* BAR 0 */
+		addr = pci_read_long(pcidev_dev, PCI_IO_BASE_ADDRESS) & ~0x07;
+		reg_offset = 0x70;
+
+	}
+
+	sil_bar = physmap("SATA SIL registers", addr, 0x100);
+	printf("virt %llx\n", sil_bar);
+	sil_bar += reg_offset;
+
+	/* check if rom cycle are OK */
+
+	return 0;
+}
+
+int sata_sil_shutdown(void)
+{
+
+	free(pcidev_bdf);
+	pci_cleanup(pacc);
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+	close(io_fd);
+#endif
+	return 0;
+}
+
+void *sata_sil_map(const char *descr, unsigned long phys_addr, size_t len)
+{
+	return 0;
+}
+
+void sata_sil_unmap(void *virt_addr, size_t len)
+{
+}
+
+
+/*
+? Bit [31:28]: Reserved (R). This bit field is reserved and returns zeros on a read.
+? Bit [27]: Memory Init Done (R) ­ This bit set indicates that the memory initialization sequence is done. The
+  memory sequence is activated upon the release of reset.
+? Bit [26]: Mem Init (R) ­ Memory Initialized. This bit set indicates that the memory was initialized properly (a
+  correct data sequence was read from the Flash.)
+? Bit [25]: Mem Access Start (R/W) ­ Memory Access Start. This bit is set to initiate an operation to Flash
+  memory. This bit is cleared when the operation is complete.
+? Bit [24]: Mem Access Type (R/W) ­ Memory Access Type. This bit is set to define a read operation from
+  Flash memory. This bit is cleared to define a write operation to Flash memory.
+? Bit [23:19]: Reserved (R). This bit field is reserved and returns zeros on a read.
+? Bit [18:00]: Memory Address (R/W). This bit field is programmed with the address for a flash memory read
+*/
+
+
+void sata_sil_chip_writeb(uint8_t val, chipaddr addr)
+{
+
+	uint32_t tmp, tmp2;
+
+	while ((tmp = readl(sil_bar)) & (1 << 25)) ;
+
+	tmp &= 0xfcf80000;
+	tmp |= (1 << 25) | (0 << 24) | ((uint32_t) addr & 0xffffff);
+
+	tmp2 = readl((sil_bar + 4));
+	tmp2 &= ~0xff;
+	tmp2 |= val;
+	writel((sil_bar + 4), val);
+	writel(sil_bar, tmp);
+
+	while (readl(sil_bar) & (1 << 25)) ;
+
+}
+
+uint8_t sata_sil_chip_readb(const chipaddr addr)
+{
+	uint32_t tmp, tmp2;
+	uint32_t val;
+
+	while ((tmp = readl(sil_bar)) & (1 << 25)) ;
+
+//	printf("reg is %x\n",tmp);
+	tmp &= 0xfcf80000;
+	tmp |= (1 << 25) | (1 << 24) | ((uint32_t) addr & 0xffffff);
+
+	writel(sil_bar, tmp);
+
+	while ((tmp = readl(sil_bar)) & (1 << 25)) ;
+
+	val = (readl(sil_bar + 4)) & 0xff;
+	printf("REad %x from %x\n", (unsigned int) val, (uint32_t) addr & 0xffffff);
+	return val & 0xff;
+}
Index: flash.h
===================================================================
--- flash.h	(revision 523)
+++ flash.h	(working copy)
@@ -83,6 +83,7 @@
 #define PROGRAMMER_INTERNAL	0x00
 #define PROGRAMMER_DUMMY	0x01
 #define PROGRAMMER_NIC3COM	0x02
+#define PROGRAMMER_SATA_SIL	0x03
 
 struct programmer_entry {
 	const char *vendor;
@@ -407,6 +408,7 @@
 #define PMC_25LV040		0x7E
 #define PMC_25LV080B		0x13
 #define PMC_25LV016B		0x14
+#define PMC_39LV010		0x1C
 #define PMC_39LV512		0x1B
 #define PMC_39F010		0x1C	/* also Pm39LV010 */
 #define PMC_39LV020		0x3D
@@ -652,6 +654,16 @@
 uint8_t nic3com_chip_readb(const chipaddr addr);
 extern struct pcidev_status nics_3com[];
 
+/* sata_sil.c */
+int sata_sil_init(void);
+int sata_sil_shutdown(void);
+void *sata_sil_map(const char *descr, unsigned long phys_addr, size_t len);
+void sata_sil_unmap(void *virt_addr, size_t len);
+void sata_sil_chip_writeb(uint8_t val, chipaddr addr);
+uint8_t sata_sil_chip_readb(const chipaddr addr);
+extern struct pcidev_status satas_sil[];
+
+
 /* flashrom.c */
 extern int verbose;
 #define printf_debug(x...) { if (verbose) printf(x); }
Index: flashchips.c
===================================================================
--- flashchips.c	(revision 523)
+++ flashchips.c	(working copy)
@@ -1132,6 +1132,20 @@
 
 	{
 		.vendor		= "PMC",
+		.name		= "Pm39LV010",
+		.manufacture_id	= PMC_ID_NOPREFIX,
+		.model_id	= PMC_39LV010,
+		.total_size	= 128,
+		.page_size	= 4096,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_jedec,
+		.erase		= erase_chip_jedec,
+		.write		= write_49f002,
+		.read		= read_memmapped,
+	},
+
+	{
+		.vendor		= "PMC",
 		.name		= "Pm49FL002",
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_49FL002,
Index: Makefile
===================================================================
--- Makefile	(revision 523)
+++ Makefile	(working copy)
@@ -33,7 +33,7 @@
 	sst49lfxxxc.o sst_fwhub.o layout.o cbtable.o flashchips.o physmap.o \
 	flashrom.o w39v080fa.o sharplhf00l04.o w29ee011.o spi.o it87spi.o \
 	ichspi.o w39v040c.o sb600spi.o wbsio_spi.o m29f002.o internal.o \
-	dummyflasher.o pcidev.o nic3com.o
+	dummyflasher.o pcidev.o nic3com.o sata_sil.o
 
 all: pciutils dep $(PROGRAM)
 
Index: flashrom.c
===================================================================
--- flashrom.c	(revision 523)
+++ flashrom.c	(working copy)
@@ -74,6 +74,19 @@
 		.chip_writel		= fallback_chip_writel,
 	},
 
+	{
+		.init			= sata_sil_init,
+		.shutdown		= sata_sil_shutdown,
+		.map_flash_region	= sata_sil_map,
+		.unmap_flash_region	= sata_sil_unmap,
+		.chip_readb		= sata_sil_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_writeb		= sata_sil_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+	},
+
 	{},
 };
 
@@ -503,6 +516,10 @@
 				programmer = PROGRAMMER_NIC3COM;
 				if (optarg[7] == '=')
 					pcidev_bdf = strdup(optarg + 8);
+			} else if (strncmp(optarg, "sata_sil", 7) == 0) {
+				programmer = PROGRAMMER_SATA_SIL;
+				if (optarg[7] == '=')
+					pcidev_bdf = strdup(optarg + 8);
 			} else {
 				printf("Error: Unknown programmer.\n");
 				exit(1);

