===================================================================
@@ -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.
===================================================================
@@ -0,0 +1,142 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2011 Jonathan Kollasch <jakllsch@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;
+}
===================================================================
@@ -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",
===================================================================
@@ -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 {
===================================================================
@@ -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);
Add VIA VT6421A LPC programmer driver. Signed-off-by: Jonathan Kollasch <jakllsch@kollasch.net>