1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 23:22:37 +02:00

Add support for RayeR SPIPGM hardware as described in http://rayer.ic.cz/elektro/spipgm.htm

To use the RayeR driver, run
flashrom -p rayer_spi -V

Known bugs/limitations:
- Won't compile/work on non-x86 architectures.
- Will always use direct port I/O access.

Log follows:

flashrom v0.9.2-r1039 on MS-DOS 7 (i686), built with libpci 3.1.5, GCC 
4.3.2, little endian
Calibrating delay loop... OK.
Initializing rayer_bitbang_spi programmer
Using port 0x378 as I/O base for parallel port access.
...
Probing for Macronix MX25L1605, 2048 KB: probe_spi_rdid_generic: id1 
0xc2, id2 0x2015
...
Found chip "Macronix MX25L1605" (2048 KB, SPI) at physical address 
0xffe00000.
...
No operations were specified.

Corresponding to flashrom svn r1093.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Martin Rehak <rayer@seznam.cz>
Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
This commit is contained in:
Carl-Daniel Hailfinger 2010-07-21 10:26:01 +00:00
parent 17e23ac979
commit e7fdd6e9a1
6 changed files with 193 additions and 2 deletions

View File

@ -111,8 +111,15 @@ CONFIG_INTERNAL ?= yes
# Always enable serprog for now. Needs to be disabled on Windows. # Always enable serprog for now. Needs to be disabled on Windows.
CONFIG_SERPROG ?= yes CONFIG_SERPROG ?= yes
# Bitbanging SPI infrastructure is not used yet. # RayeR SPIPGM hardware support
CONFIG_RAYER_SPI ?= yes
# Bitbanging SPI infrastructure, default off unless needed.
ifeq ($(CONFIG_RAYER_SPI), yes)
override CONFIG_BITBANG_SPI = yes
else
CONFIG_BITBANG_SPI ?= no CONFIG_BITBANG_SPI ?= no
endif
# Always enable 3Com NICs for now. # Always enable 3Com NICs for now.
CONFIG_NIC3COM ?= yes CONFIG_NIC3COM ?= yes
@ -166,6 +173,13 @@ NEED_SERIAL := yes
NEED_NET := yes NEED_NET := yes
endif endif
ifeq ($(CONFIG_RAYER_SPI), yes)
FEATURE_CFLAGS += -D'CONFIG_RAYER_SPI=1'
PROGRAMMER_OBJS += rayer_spi.o
# Actually, NEED_PCI is wrong. NEED_IOPORT_ACCESS would be more correct.
NEED_PCI := yes
endif
ifeq ($(CONFIG_BITBANG_SPI), yes) ifeq ($(CONFIG_BITBANG_SPI), yes)
FEATURE_CFLAGS += -D'CONFIG_BITBANG_SPI=1' FEATURE_CFLAGS += -D'CONFIG_BITBANG_SPI=1'
PROGRAMMER_OBJS += bitbang_spi.o PROGRAMMER_OBJS += bitbang_spi.o

14
flash.h
View File

@ -80,6 +80,9 @@ enum programmer {
#endif #endif
#if CONFIG_DEDIPROG == 1 #if CONFIG_DEDIPROG == 1
PROGRAMMER_DEDIPROG, PROGRAMMER_DEDIPROG,
#endif
#if CONFIG_RAYER_SPI == 1
PROGRAMMER_RAYER_SPI,
#endif #endif
PROGRAMMER_INVALID /* This must always be the last entry. */ PROGRAMMER_INVALID /* This must always be the last entry. */
}; };
@ -129,6 +132,9 @@ void programmer_delay(int usecs);
enum bitbang_spi_master_type { enum bitbang_spi_master_type {
BITBANG_SPI_INVALID = 0, /* This must always be the first entry. */ BITBANG_SPI_INVALID = 0, /* This must always be the first entry. */
#if CONFIG_RAYER_SPI == 1
BITBANG_SPI_MASTER_RAYER,
#endif
}; };
struct bitbang_spi_master { struct bitbang_spi_master {
@ -531,6 +537,11 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const u
int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
/* rayer_spi.c */
#if CONFIG_RAYER_SPI == 1
int rayer_spi_init(void);
#endif
/* bitbang_spi.c */ /* bitbang_spi.c */
int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod); int bitbang_spi_init(const struct bitbang_spi_master *master, int halfperiod);
int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
@ -649,6 +660,9 @@ enum spi_controller {
#endif #endif
#if CONFIG_DEDIPROG == 1 #if CONFIG_DEDIPROG == 1
SPI_CONTROLLER_DEDIPROG, SPI_CONTROLLER_DEDIPROG,
#endif
#if CONFIG_RAYER_SPI == 1
SPI_CONTROLLER_RAYER,
#endif #endif
SPI_CONTROLLER_INVALID /* This must always be the last entry. */ SPI_CONTROLLER_INVALID /* This must always be the last entry. */
}; };

View File

@ -187,6 +187,9 @@ USB SPI programmer)"
.sp .sp
.BR "* buspirate_spi" " (for SPI flash ROMs attached to a Bus Pirate)" .BR "* buspirate_spi" " (for SPI flash ROMs attached to a Bus Pirate)"
.sp .sp
.BR "* rayer_spi" " (for SPI flash ROMs attached to a RayeR parport \
based programmer)"
.sp
Some programmers have optional or mandatory parameters which are described Some programmers have optional or mandatory parameters which are described
in detail in the in detail in the
.B PROGRAMMER SPECIFIC INFO .B PROGRAMMER SPECIFIC INFO
@ -389,6 +392,10 @@ where
can be any of can be any of
.BR 30k ", " 125k ", " 250k ", " 1M ", " 2M ", " 2.6M ", " 4M ", " 8M .BR 30k ", " 125k ", " 250k ", " 1M ", " 2M ", " 2.6M ", " 4M ", " 8M
(in Hz). The default is the maximum frequency of 8 MHz. (in Hz). The default is the maximum frequency of 8 MHz.
.TP
.BR "rayer_spi " programmer
No parameters defined yet. More information about the hardware is available at
http://rayer.ic.cz/elektro/spipgm.htm
.SH EXIT STATUS .SH EXIT STATUS
flashrom exits with 0 on success, 1 on most failures but with 2 if /dev/mem flashrom exits with 0 on success, 1 on most failures but with 2 if /dev/mem
(/dev/xsvc on Solaris) can not be opened and with 3 if a call to mmap() fails. (/dev/xsvc on Solaris) can not be opened and with 3 if a call to mmap() fails.
@ -411,6 +418,9 @@ needs PCI configuration space access and raw I/O port access.
.BR gfxnvidia " and " drkaiser .BR gfxnvidia " and " drkaiser
need PCI configuration space access and raw memory access. need PCI configuration space access and raw memory access.
.sp .sp
.B rayer_spi
needs raw I/O port access.
.sp
.B satasii .B satasii
needs PCI configuration space read access and raw memory access. needs PCI configuration space read access and raw memory access.
.sp .sp

View File

@ -48,7 +48,7 @@ enum programmer programmer = PROGRAMMER_DUMMY;
* if more than one of them is selected. If only one is selected, it is clear * 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. * 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 > 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 > 1
#error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all programmers except one. #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all programmers except one.
#endif #endif
enum programmer programmer = enum programmer programmer =
@ -86,6 +86,9 @@ enum programmer programmer =
#if CONFIG_DEDIPROG == 1 #if CONFIG_DEDIPROG == 1
PROGRAMMER_DEDIPROG PROGRAMMER_DEDIPROG
#endif #endif
#if CONFIG_RAYER_SPI == 1
PROGRAMMER_RAYER_SPI
#endif
; ;
#endif #endif
@ -391,6 +394,25 @@ const struct programmer_entry programmer_table[] = {
}, },
#endif #endif
#if CONFIG_RAYER_SPI == 1
{
.name = "rayer_spi",
.init = rayer_spi_init,
.shutdown = noop_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. */ {}, /* This entry corresponds to PROGRAMMER_INVALID. */
}; };

122
rayer_spi.c Normal file
View File

@ -0,0 +1,122 @@
/*
* This file is part of the flashrom project.
*
* Copyright (C) 2009,2010 Carl-Daniel Hailfinger
*
* 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
*/
/* Driver for the SPIPGM hardware by "RayeR" Martin Rehak.
* See http://rayer.ic.cz/elektro/spipgm.htm for schematics and instructions.
*/
/* This driver uses non-portable direct I/O port accesses which won't work on
* any non-x86 platform, and even on x86 there is a high chance there will be
* collisions with any loaded parallel port drivers.
* The big advantage of direct port I/O is OS independence and speed because
* most OS parport drivers will perform many unnecessary accesses although
* this driver just treats the parallel port as a GPIO set.
*/
#if defined(__i386__) || defined(__x86_64__)
#include "flash.h"
/* We have two sets of pins, out and in. The numbers for both sets are
* independent and are bitshift values, not real pin numbers.
*/
/* Pins for master->slave direction */
#define SPI_CS_PIN 5
#define SPI_SCK_PIN 6
#define SPI_MOSI_PIN 7
/* Pins for slave->master direction */
#define SPI_MISO_PIN 6
static int lpt_iobase;
/* FIXME: All rayer_bitbang_set_* functions could use caching of the value
* stored at port lpt_iobase to avoid unnecessary INB. In theory, only one
* INB(lpt_iobase) would be needed on programmer init to get the initial
* value.
*/
void rayer_bitbang_set_cs(int val)
{
uint8_t tmp;
tmp = INB(lpt_iobase);
tmp &= ~(1 << SPI_CS_PIN);
tmp |= (val << SPI_CS_PIN);
OUTB(tmp, lpt_iobase);
}
void rayer_bitbang_set_sck(int val)
{
uint8_t tmp;
tmp = INB(lpt_iobase);
tmp &= ~(1 << SPI_SCK_PIN);
tmp |= (val << SPI_SCK_PIN);
OUTB(tmp, lpt_iobase);
}
void rayer_bitbang_set_mosi(int val)
{
uint8_t tmp;
tmp = INB(lpt_iobase);
tmp &= ~(1 << SPI_MOSI_PIN);
tmp |= (val << SPI_MOSI_PIN);
OUTB(tmp, lpt_iobase);
}
int rayer_bitbang_get_miso(void)
{
uint8_t tmp;
tmp = INB(lpt_iobase + 1);
tmp = (tmp >> SPI_MISO_PIN) & 0x1;
return tmp;
}
static const struct bitbang_spi_master bitbang_spi_master_rayer = {
.type = BITBANG_SPI_MASTER_RAYER,
.set_cs = rayer_bitbang_set_cs,
.set_sck = rayer_bitbang_set_sck,
.set_mosi = rayer_bitbang_set_mosi,
.get_miso = rayer_bitbang_get_miso,
};
int rayer_spi_init(void)
{
/* Pick a default value for now. */
lpt_iobase = 0x378;
msg_pdbg("Using port 0x%x as I/O base for parallel port access.\n",
lpt_iobase);
get_io_perms();
/* 1 usec halfperiod delay for now. */
if (bitbang_spi_init(&bitbang_spi_master_rayer, 1))
return 1;
buses_supported = CHIP_BUSTYPE_SPI;
spi_controller = SPI_CONTROLLER_RAYER;
return 0;
}
#else
#error PCI port I/O access is not supported on this architecture yet.
#endif

9
spi.c
View File

@ -121,6 +121,15 @@ const struct spi_programmer spi_programmer[] = {
}, },
#endif #endif
#if CONFIG_RAYER_SPI == 1
{ /* SPI_CONTROLLER_RAYER */
.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. */ {}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */
}; };