[flashrom] [patch] atavia

Jonathan A. Kollasch jakllsch at kollasch.net
Mon Jun 27 01:33:33 CEST 2011


Add VIA VT6421A LPC programmer driver.

Signed-off-by: Jonathan Kollasch <jakllsch at kollasch.net>
-------------- next part --------------
Index: Makefile
===================================================================
--- Makefile	(revision 1357)
+++ Makefile	(working copy)
@@ -164,6 +164,9 @@
 # IMPORTANT: This code is not yet working!
 CONFIG_ATAHPT ?= no
 
+# VIA VT6421A LPC memory support
+CONFIG_ATAVIA ?= yes
+
 # Always enable FT2232 SPI dongles for now.
 CONFIG_FT2232_SPI ?= yes
 
@@ -270,6 +273,12 @@
 NEED_PCI := yes
 endif
 
+ifeq ($(CONFIG_ATAVIA), yes)
+FEATURE_CFLAGS += -D'CONFIG_ATAVIA=1'
+PROGRAMMER_OBJS += atavia.o
+NEED_PCI := yes
+endif
+
 ifeq ($(CONFIG_FT2232_SPI), yes)
 FTDILIBS := $(shell pkg-config --libs libftdi 2>/dev/null || printf "%s" "-lftdi -lusb")
 # This is a totally ugly hack.
Index: atavia.c
===================================================================
--- atavia.c	(revision 0)
+++ atavia.c	(revision 0)
@@ -0,0 +1,142 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe at hermann-uwe.de>
+ * Copyright (C) 2011 Jonathan Kollasch <jakllsch at kollasch.net>
+ *
+ * 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 <stdbool.h>
+#include <string.h>
+#include "flash.h"
+#include "programmer.h"
+#include <stdio.h>
+
+#define PCI_VENDOR_ID_VIA 0x1106
+
+#define BROM_ADDR	0x60
+#define BROM_DATA	0x64
+
+#define BROM_ACCESS	0x68
+#define BROM_TRIGGER		0x80
+#define BROM_WRITE		0x40
+#define BROM_SIZE_MASK		0x30
+#define BROM_SIZE_64K		0x00
+#define BROM_SIZE_32K		0x10
+#define BROM_SIZE_16K		0x20
+#define BROM_SIZE_0K		0x30
+#define BROM_BYTE_ENABLE_MASK	0x0f
+
+/*
+ * Select the byte we want to access.  This is done by clearing the bit
+ * corresponding to the byte we want to access, leaving the others set.
+ * (Yes, really.)
+ */
+#define ENABLE(address) ((~(1 << ((address) & 3))) & BROM_BYTE_ENABLE_MASK)
+
+#define BROM_STATUS	0x69
+#define BROM_ERROR_STATUS	0x80
+
+static bool atavia_ready(void);
+
+const struct pcidev_status ata_via[] = {
+	{PCI_VENDOR_ID_VIA, 0x3249, NT, "VIA", "VT6421A"},
+
+	{},
+};
+
+static int atavia_shutdown(void *data)
+{
+	pci_cleanup(pacc);
+	release_io_perms();
+
+	return 0;
+}
+
+
+static bool atavia_ready(void)
+{
+	int try;
+	uint8_t access;
+	bool status;
+
+	for (status = false, try = 0; try < 300; try++) {
+		access = pci_read_byte(pcidev_dev, BROM_ACCESS);
+		if ((access & BROM_TRIGGER) == 0) {
+			status = true;
+			break;
+		} else {
+			programmer_delay(1);
+			continue;
+		}
+	}
+
+	msg_pdbg("%s() %s after %d tries\n", __FUNCTION__,
+		 status ? "suceeded" : "failed", try);
+
+	return status;
+}
+
+int atavia_init(void)
+{
+	buses_supported = CHIP_BUSTYPE_LPC;
+
+	pcidev_init(4, ata_via);
+
+	/* must be done before rpci calls */
+	if (register_shutdown(atavia_shutdown, NULL))
+		return 1;
+
+	rpci_write_long(pcidev_dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
+	programmer_delay(90);
+	pci_write_long(pcidev_dev, PCI_ROM_ADDRESS, 0);
+	programmer_delay(10);
+
+	return ((atavia_ready() == true) ? 0 : 1);
+}
+
+void *atavia_map(const char *descr, unsigned long phys_addr, size_t len)
+{
+	return (void *)phys_addr;
+}
+
+void atavia_chip_writeb(uint8_t val, chipaddr addr)
+{
+	pci_write_long(pcidev_dev, BROM_ADDR, (addr & ~3));
+	pci_write_long(pcidev_dev, BROM_DATA, val << (8 * (addr & 3)));
+	pci_write_byte(pcidev_dev, BROM_ACCESS, BROM_TRIGGER | BROM_WRITE | ENABLE(addr));
+
+	if (atavia_ready() == false) {
+		msg_perr("not ready after write\n");
+	}
+}
+
+uint8_t atavia_chip_readb(const chipaddr addr)
+{
+	uint8_t val;
+
+	pci_write_long(pcidev_dev, BROM_ADDR, (addr & ~3));
+	pci_write_byte(pcidev_dev, BROM_ACCESS, BROM_TRIGGER | ENABLE(addr));
+
+	if (atavia_ready() == false) {
+		msg_perr("not ready after read\n");
+	}
+
+	val = (pci_read_long(pcidev_dev, BROM_DATA) >> ((addr & 3)*8)) & 0xff;
+
+	return val;
+}
Index: flashrom.c
===================================================================
--- flashrom.c	(revision 1357)
+++ flashrom.c	(working copy)
@@ -52,7 +52,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+CONFIG_NICINTEL+CONFIG_NICINTEL_SPI+CONFIG_OGP_SPI+CONFIG_SATAMV > 1
+#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_ATAVIA+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG+CONFIG_RAYER_SPI+CONFIG_NICINTEL+CONFIG_NICINTEL_SPI+CONFIG_OGP_SPI+CONFIG_SATAMV > 1
 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all programmers except one.
 #endif
 enum programmer programmer =
@@ -77,6 +77,9 @@
 #if CONFIG_ATAHPT == 1
 	PROGRAMMER_ATAHPT
 #endif
+#if CONFIG_ATAVIA == 1
+	PROGRAMMER_ATAVIA
+#endif
 #if CONFIG_FT2232_SPI == 1
 	PROGRAMMER_FT2232_SPI
 #endif
@@ -289,6 +292,24 @@
 	},
 #endif
 
+#if CONFIG_ATAVIA == 1
+	{
+		.name			= "atavia",
+		.init			= atavia_init,
+		.map_flash_region	= atavia_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= atavia_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= atavia_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
 #if CONFIG_FT2232_SPI == 1
 	{
 		.name			= "ft2232_spi",
Index: programmer.h
===================================================================
--- programmer.h	(revision 1357)
+++ programmer.h	(working copy)
@@ -52,6 +52,9 @@
 #if CONFIG_ATAHPT == 1
 	PROGRAMMER_ATAHPT,
 #endif
+#if CONFIG_ATAVIA == 1
+	PROGRAMMER_ATAVIA,
+#endif
 #if CONFIG_FT2232_SPI == 1
 	PROGRAMMER_FT2232_SPI,
 #endif
@@ -460,6 +463,15 @@
 extern const struct pcidev_status ata_hpt[];
 #endif
 
+/* atavia.c */
+#if CONFIG_ATAVIA == 1
+int atavia_init(void);
+void *atavia_map(const char *descr, unsigned long phys_addr, size_t len);
+void atavia_chip_writeb(uint8_t val, chipaddr addr);
+uint8_t atavia_chip_readb(const chipaddr addr);
+extern const struct pcidev_status ata_via[];
+#endif
+
 /* ft2232_spi.c */
 #if CONFIG_FT2232_SPI == 1
 struct usbdev_status {
Index: print.c
===================================================================
--- print.c	(revision 1357)
+++ print.c	(working copy)
@@ -313,6 +313,11 @@
 	       programmer_table[PROGRAMMER_ATAHPT].name);
 	print_supported_pcidevs(ata_hpt);
 #endif
+#if CONFIG_ATAVIA == 1
+	printf("\nSupported devices for the %s programmer:\n",
+	       programmer_table[PROGRAMMER_ATAVIA].name);
+	print_supported_pcidevs(ata_via);
+#endif
 #if CONFIG_FT2232_SPI == 1
 	msg_ginfo("\nSupported devices for the %s programmer:\n",
 	       programmer_table[PROGRAMMER_FT2232_SPI].name);


More information about the flashrom mailing list