Patchwork HPT360/HPT370 ATA controller flash interface

login
register
about
Submitter Uwe Hermann
Date 2010-01-17 00:55:47
Message ID <20100117005547.GB17150@greenwood>
Download mbox | patch
Permalink /patch/797/
State Accepted
Commit r908
Headers show

Comments

Uwe Hermann - 2010-01-17 00:55:47
On Thu, Jan 14, 2010 at 02:09:51AM +0100, Uwe Hermann wrote:
> I'll post a patch tomorrow or so and test on my HPT370A.

Here's the first draft. It does not yet work, the chip cannot be
detected, all reads return 0x00 so far.

Attached is the patch, an lspci -xxxnnnvvv after a fresh boot and before
any flashrom runs, and the output of 'flashrom -p atahpt -V'.

I desoldered the SST39SF512 chip and soldered on a PLCC socket onto the
HPT card for easier testing. I already posted a patch for the
SST39SF512, which I tested in a supported mainboard and it works fine.

Note that the WE# pin is at 3.3V while the HPT card is powered, thus
writes are _dis_abled, unless I'm mistaken. The WE# pin is connected to
some pin of the HPT370A chip (probably a GPIO), so it can in theory
toggle the WE# pin.

The PCI registers suggest that the flash access is enabled per default,
and the IO-vs-MMIO bit is set to I/O per default.


HTH, Uwe.
Carl-Daniel Hailfinger - 2010-02-04 00:49:48
On 17.01.2010 01:55, Uwe Hermann wrote:
> Here's the first draft. It does not yet work, the chip cannot be
> detected, all reads return 0x00 so far.
>
> Note that the WE# pin is at 3.3V while the HPT card is powered, thus
> writes are _dis_abled, unless I'm mistaken. The WE# pin is connected to
> some pin of the HPT370A chip (probably a GPIO), so it can in theory
> toggle the WE# pin.
>   

That would explain why you don't get any probe response. An interesting
experiment would be to write some random image to the chip with a known
good programmer (your mainboard?), then force read the chip in the
HPT360. If that works, you only have to handle WE#. If it doesn't, there
are deeper issues that need to be fixed.


> Index: Makefile
> ===================================================================
> --- Makefile	(revision 862)
> +++ Makefile	(working copy)
> @@ -84,6 +84,9 @@
>  # Always enable SiI SATA controllers for now.
>  CONFIG_SATASII ?= yes
>  
> +# Always enable Highpoint (HPT) ATA/RAID controllers for now.
> +CONFIG_ATAHPT ?= yes
> +
>  # Always enable FT2232 SPI dongles for now.
>  CONFIG_FT2232SPI ?= yes
>  
>   

Following the policy of merging code early as long as users won't trip
over it, change CONFIG_ATAHPT to default to no, and the patch is
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>

If you merge the current tree with your patch, a conflict will arise in
flashrom.c. Suggested resolution:

#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+ATAHPT_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT+DEDIPROG_SUPPORT > 1


Regards,
Carl-Daniel
Uwe Hermann - 2010-02-21 21:18:20
On Thu, Feb 04, 2010 at 01:49:48AM +0100, Carl-Daniel Hailfinger wrote:
> On 17.01.2010 01:55, Uwe Hermann wrote:
> > Here's the first draft. It does not yet work, the chip cannot be
> > detected, all reads return 0x00 so far.
> >
> > Note that the WE# pin is at 3.3V while the HPT card is powered, thus
> > writes are _dis_abled, unless I'm mistaken. The WE# pin is connected to
> > some pin of the HPT370A chip (probably a GPIO), so it can in theory
> > toggle the WE# pin.
> >   
> 
> That would explain why you don't get any probe response. An interesting
> experiment would be to write some random image to the chip with a known
> good programmer (your mainboard?), then force read the chip in the
> HPT360. If that works, you only have to handle WE#. If it doesn't, there
> are deeper issues that need to be fixed.

Will check as soon as I find some spare time.

 
> Following the policy of merging code early as long as users won't trip
> over it, change CONFIG_ATAHPT to default to no, and the patch is
> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>

Thanks, r908. The code is disabled by default in the Makefile.

 
Uwe.

Patch

Index: flashrom.8
===================================================================
--- flashrom.8	(revision 862)
+++ flashrom.8	(working copy)
@@ -146,6 +146,8 @@ 
 .sp
 .BR "* satasii" " (for flash ROMs on Silicon Image SATA/IDE controllers)"
 .sp
+.BR "* atahpt" " (for flash ROMs on Highpoint ATA/RAID controllers)"
+.sp
 .BR "* it87spi" " (for flash ROMs behind an ITE IT87xx Super I/O LPC/SPI translation unit)"
 .sp
 .BR "* ft2232spi" " (for flash ROMs attached to a FT2232H/FT4232H based USB SPI programmer)"
@@ -185,7 +187,8 @@ 
 Currently the following programmers support this mechanism:
 .BR nic3com ,
 .BR gfxnvidia ,
-.BR satasii .
+.BR satasii ,
+.BR atahpt .
 .sp
 The it87spi programmer has an optional parameter which will set the I/O base
 port of the IT87* SPI controller interface to the port specified in the
Index: flash.h
===================================================================
--- flash.h	(revision 862)
+++ flash.h	(working copy)
@@ -55,6 +55,9 @@ 
 #if SATASII_SUPPORT == 1
 	PROGRAMMER_SATASII,
 #endif
+#if ATAHPT_SUPPORT == 1
+	PROGRAMMER_ATAHPT,
+#endif
 #if INTERNAL_SUPPORT == 1
 	PROGRAMMER_IT87SPI,
 #endif
@@ -312,7 +315,7 @@ 
 /* print.c */
 char *flashbuses_to_text(enum chipbustype bustype);
 void print_supported(void);
-#if (NIC3COM_SUPPORT == 1) || (GFXNVIDIA_SUPPORT == 1) || (DRKAISER_SUPPORT == 1) || (SATASII_SUPPORT == 1)
+#if (NIC3COM_SUPPORT == 1) || (GFXNVIDIA_SUPPORT == 1) || (DRKAISER_SUPPORT == 1) || (SATASII_SUPPORT == 1) || (ATAHPT_SUPPORT == 1)
 void print_supported_pcidevs(struct pcidev_status *devs);
 #endif
 void print_supported_wiki(void);
@@ -444,6 +447,15 @@ 
 extern struct pcidev_status satas_sii[];
 #endif
 
+/* atahpt.c */
+#if ATAHPT_SUPPORT == 1
+int atahpt_init(void);
+int atahpt_shutdown(void);
+void atahpt_chip_writeb(uint8_t val, chipaddr addr);
+uint8_t atahpt_chip_readb(const chipaddr addr);
+extern struct pcidev_status ata_hpt[];
+#endif
+
 /* ft2232_spi.c */
 #define FTDI_FT2232H 0x6010
 #define FTDI_FT4232H 0x6011
Index: atahpt.c
===================================================================
--- atahpt.c	(revision 0)
+++ atahpt.c	(revision 0)
@@ -0,0 +1,85 @@ 
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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 <sys/types.h>
+#include "flash.h"
+
+#define BIOS_ROM_ADDR		0x90
+#define BIOS_ROM_DATA		0x94
+
+#define REG_FLASH_ACCESS	0x58
+
+#define PCI_VENDOR_ID_HPT	0x1103
+
+struct pcidev_status ata_hpt[] = {
+	{0x1103, 0x0004, PCI_NT, "Highpoint", "HPT366/368/370/370A/372/372N"},
+	{0x1103, 0x0005, PCI_NT, "Highpoint", "HPT372A/372N"},
+	{0x1103, 0x0006, PCI_NT, "Highpoint", "HPT302/302N"},
+
+	{},
+};
+
+int atahpt_init(void)
+{
+	uint32_t reg32;
+
+	get_io_perms();
+
+	io_base_addr = pcidev_init(PCI_VENDOR_ID_HPT, PCI_BASE_ADDRESS_4,
+				   ata_hpt, programmer_param);
+
+	/* Enable flash access. */
+	reg32 = pci_read_long(pcidev_dev, REG_FLASH_ACCESS);
+	reg32 |= (1 << 24);
+	pci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
+
+	buses_supported = CHIP_BUSTYPE_PARALLEL;
+
+	return 0;
+}
+
+int atahpt_shutdown(void)
+{
+	uint32_t reg32;
+
+	/* Disable flash access again. */
+	reg32 = pci_read_long(pcidev_dev, REG_FLASH_ACCESS);
+	reg32 &= ~(1 << 24);
+	pci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
+
+	free(programmer_param);
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
+void atahpt_chip_writeb(uint8_t val, chipaddr addr)
+{
+	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
+	OUTB(val, io_base_addr + BIOS_ROM_DATA);
+}
+
+uint8_t atahpt_chip_readb(const chipaddr addr)
+{
+	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
+	return INB(io_base_addr + BIOS_ROM_DATA);
+}
Index: Makefile
===================================================================
--- Makefile	(revision 862)
+++ Makefile	(working copy)
@@ -84,6 +84,9 @@ 
 # Always enable SiI SATA controllers for now.
 CONFIG_SATASII ?= yes
 
+# Always enable Highpoint (HPT) ATA/RAID controllers for now.
+CONFIG_ATAHPT ?= yes
+
 # Always enable FT2232 SPI dongles for now.
 CONFIG_FT2232SPI ?= yes
 
@@ -136,6 +139,12 @@ 
 NEED_PCI := yes
 endif
 
+ifeq ($(CONFIG_ATAHPT), yes)
+FEATURE_CFLAGS += -D'ATAHPT_SUPPORT=1'
+PROGRAMMER_OBJS += atahpt.o
+NEED_PCI := yes
+endif
+
 ifeq ($(CONFIG_FT2232SPI), yes)
 FTDILIBS := $(shell pkg-config --libs libftdi 2>/dev/null || printf "%s" "-lftdi -lusb")
 # This is a totally ugly hack.
Index: flashrom.c
===================================================================
--- flashrom.c	(revision 862)
+++ flashrom.c	(working copy)
@@ -44,7 +44,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 NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT > 1
+#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+ATAHPT_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT > 1
 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all external programmers except one.
 #endif
 enum programmer programmer =
@@ -60,6 +60,9 @@ 
 #if SATASII_SUPPORT == 1
 	PROGRAMMER_SATASII
 #endif
+#if ATAHPT_SUPPORT == 1
+	PROGRAMMER_ATAHPT
+#endif
 #if FT2232_SPI_SUPPORT == 1
 	PROGRAMMER_FT2232SPI
 #endif
@@ -207,6 +210,25 @@ 
 	},
 #endif
 
+#if ATAHPT_SUPPORT == 1
+	{
+		.name			= "atahpt",
+		.init			= atahpt_init,
+		.shutdown		= atahpt_shutdown,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= atahpt_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= atahpt_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
 #if INTERNAL_SUPPORT == 1
 	{
 		.name			= "it87spi",
Index: print_wiki.c
===================================================================
--- print_wiki.c	(revision 862)
+++ print_wiki.c	(working copy)
@@ -565,6 +565,9 @@ 
 #if SATASII_SUPPORT == 1
 	print_supported_pcidevs_wiki(satas_sii);
 #endif
+#if ATAHPT_SUPPORT == 1
+	print_supported_pcidevs_wiki(ata_hpt);
+#endif
 	printf("\n|}\n");
 }