mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-28 07:23:43 +02:00
Add the ability to set Bus Pirate SPI speed via the command line
Example usage: flashrom -p buspiratespi:spispeed=2.6MHz,dev=/dev/foo flashrom -p buspiratespi:dev=/dev/foo,spispeed=2.6M Refactor programmer option parsing (this allows cleanups in other programmers as well). Increase SPI read size from 8 to 12 bytes (current single-transaction limit of the Bus Pirate raw SPI protocol). Add Bus Pirate to the list of programmers supporting 4 byte RDID. Add Bus Pirate syntax to the man page. Tested-by: Sean Nelson <audiohacked@gmail.com> Corresponding to flashrom svn r776. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Sean Nelson <audiohacked@gmail.com>
This commit is contained in:
parent
d70b09ca13
commit
d5b28fae1d
@ -131,34 +131,37 @@ int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, unsigned int r
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct buspirate_spispeeds spispeeds[] = {
|
||||||
|
{"30k", 0x0},
|
||||||
|
{"125k", 0x1},
|
||||||
|
{"250k", 0x2},
|
||||||
|
{"1M", 0x3},
|
||||||
|
{"2M", 0x4},
|
||||||
|
{"2.6M", 0x5},
|
||||||
|
{"4M", 0x6},
|
||||||
|
{"8M", 0x7},
|
||||||
|
{NULL, 0x0}
|
||||||
|
};
|
||||||
|
|
||||||
int buspirate_spi_init(void)
|
int buspirate_spi_init(void)
|
||||||
{
|
{
|
||||||
unsigned char buf[512];
|
unsigned char buf[512];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
char *devpos = NULL;
|
|
||||||
char *dev = NULL;
|
char *dev = NULL;
|
||||||
int devlen;
|
char *speed = NULL;
|
||||||
|
int spispeed = 0x7;
|
||||||
|
|
||||||
if (programmer_param && !strlen(programmer_param)) {
|
if (programmer_param && !strlen(programmer_param)) {
|
||||||
free(programmer_param);
|
free(programmer_param);
|
||||||
programmer_param = NULL;
|
programmer_param = NULL;
|
||||||
}
|
}
|
||||||
if (programmer_param) {
|
if (programmer_param) {
|
||||||
devpos = strstr(programmer_param, "dev=");
|
dev = extract_param(&programmer_param, "dev=", ",:");
|
||||||
if (devpos) {
|
speed = extract_param(&programmer_param, "spispeed=", ",:");
|
||||||
devpos += 4;
|
if (strlen(programmer_param))
|
||||||
devlen = strcspn(devpos, ",:");
|
fprintf(stderr, "Unhandled programmer parameters: %s\n",
|
||||||
if (devlen) {
|
programmer_param);
|
||||||
dev = malloc(devlen + 1);
|
|
||||||
if (!dev) {
|
|
||||||
fprintf(stderr, "Out of memory!\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
strncpy(dev, devpos, devlen);
|
|
||||||
dev[devlen] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(programmer_param);
|
free(programmer_param);
|
||||||
programmer_param = NULL;
|
programmer_param = NULL;
|
||||||
}
|
}
|
||||||
@ -167,6 +170,18 @@ int buspirate_spi_init(void)
|
|||||||
"buspiratespi:dev=/dev/ttyUSB0\n");
|
"buspiratespi:dev=/dev/ttyUSB0\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (speed) {
|
||||||
|
for (i = 0; spispeeds[i].name; i++)
|
||||||
|
if (!strncasecmp(spispeeds[i].name, speed,
|
||||||
|
strlen(spispeeds[i].name))) {
|
||||||
|
spispeed = spispeeds[i].speed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!spispeeds[i].name)
|
||||||
|
fprintf(stderr, "Invalid SPI speed, using default.\n");
|
||||||
|
}
|
||||||
|
/* This works because speeds numbering starts at 0 and is contiguous. */
|
||||||
|
printf_debug("SPI speed is %sHz\n", spispeeds[spispeed].name);
|
||||||
|
|
||||||
ret = buspirate_serialport_setup(dev);
|
ret = buspirate_serialport_setup(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -224,8 +239,8 @@ int buspirate_spi_init(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set speed to 8 MHz */
|
/* Set SPI speed */
|
||||||
buf[0] = 0x60 | 0x7;
|
buf[0] = 0x60 | spispeed;
|
||||||
ret = buspirate_sendrecv(buf, 1, 1);
|
ret = buspirate_sendrecv(buf, 1, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 1;
|
return 1;
|
||||||
@ -351,8 +366,7 @@ int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
|||||||
|
|
||||||
int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
/* Maximum read length is 12 bytes, use 8 for now. */
|
return spi_read_chunked(flash, buf, start, len, 12);
|
||||||
return spi_read_chunked(flash, buf, start, len, 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We could do 12-byte writes, but for now we use the generic 1-byte code. */
|
/* We could do 12-byte writes, but for now we use the generic 1-byte code. */
|
||||||
|
5
flash.h
5
flash.h
@ -488,6 +488,10 @@ int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
|||||||
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
|
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
/* buspirate_spi.c */
|
/* buspirate_spi.c */
|
||||||
|
struct buspirate_spispeeds {
|
||||||
|
const char *name;
|
||||||
|
const int speed;
|
||||||
|
};
|
||||||
int buspirate_spi_init(void);
|
int buspirate_spi_init(void);
|
||||||
int buspirate_spi_shutdown(void);
|
int buspirate_spi_shutdown(void);
|
||||||
int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
||||||
@ -503,6 +507,7 @@ int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len);
|
|||||||
int erase_flash(struct flashchip *flash);
|
int erase_flash(struct flashchip *flash);
|
||||||
int min(int a, int b);
|
int min(int a, int b);
|
||||||
int max(int a, int b);
|
int max(int a, int b);
|
||||||
|
char *extract_param(char **haystack, char *needle, char *delim);
|
||||||
int check_erased_range(struct flashchip *flash, int start, int len);
|
int check_erased_range(struct flashchip *flash, int start, int len);
|
||||||
int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
|
int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
|
||||||
char *strcat_realloc(char *dest, const char *src);
|
char *strcat_realloc(char *dest, const char *src);
|
||||||
|
12
flashrom.8
12
flashrom.8
@ -152,6 +152,8 @@ Specify the programmer device. Currently supported are:
|
|||||||
.sp
|
.sp
|
||||||
.BR "* serprog" " (for flash ROMs attached to Urja's AVR programmer)"
|
.BR "* serprog" " (for flash ROMs attached to Urja's AVR programmer)"
|
||||||
.sp
|
.sp
|
||||||
|
.BR "* buspiratespi" " (for flash ROMs attached to a Bus Pirate)"
|
||||||
|
.sp
|
||||||
The dummy programmer has an optional parameter specifying the bus types it
|
The dummy programmer has an optional parameter specifying the bus types it
|
||||||
should support. For that you have to use the
|
should support. For that you have to use the
|
||||||
.B "flashrom -p dummy:type"
|
.B "flashrom -p dummy:type"
|
||||||
@ -219,6 +221,16 @@ syntax and for IP, you have to use
|
|||||||
instead. More information about serprog is available in serprog-protocol.txt in
|
instead. More information about serprog is available in serprog-protocol.txt in
|
||||||
the source distribution.
|
the source distribution.
|
||||||
.sp
|
.sp
|
||||||
|
The buspiratespi programmer has a required dev parameter specifying the Bus
|
||||||
|
Pirate device node and an optional spispeed parameter specifying the frequency
|
||||||
|
of the SPI bus. The parameter delimiter is a comma. Syntax is
|
||||||
|
.B "flashrom -p buspiratespi:dev=/dev/device,spispeed=frequency"
|
||||||
|
where
|
||||||
|
.B frequency
|
||||||
|
can be any of
|
||||||
|
.B 30k 125k 250k 1M 2M 2.6M 4M 8M
|
||||||
|
(in Hz).
|
||||||
|
.sp
|
||||||
Support for some programmers can be disabled at compile time.
|
Support for some programmers can be disabled at compile time.
|
||||||
.B "flashrom -h"
|
.B "flashrom -h"
|
||||||
lists all supported programmers.
|
lists all supported programmers.
|
||||||
|
54
flashrom.c
54
flashrom.c
@ -336,6 +336,60 @@ char *strcat_realloc(char *dest, const char *src)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is a somewhat hacked function similar in some ways to strtok().
|
||||||
|
* It will look for needle in haystack, return a copy of needle and remove
|
||||||
|
* everything from the first occurrence of needle to the next delimiter
|
||||||
|
* from haystack.
|
||||||
|
*/
|
||||||
|
char *extract_param(char **haystack, char *needle, char *delim)
|
||||||
|
{
|
||||||
|
char *param_pos, *rest, *tmp;
|
||||||
|
char *dev = NULL;
|
||||||
|
int devlen;
|
||||||
|
|
||||||
|
param_pos = strstr(*haystack, needle);
|
||||||
|
do {
|
||||||
|
if (!param_pos)
|
||||||
|
return NULL;
|
||||||
|
/* Beginning of the string? */
|
||||||
|
if (param_pos == *haystack)
|
||||||
|
break;
|
||||||
|
/* After a delimiter? */
|
||||||
|
if (strchr(delim, *(param_pos - 1)))
|
||||||
|
break;
|
||||||
|
/* Continue searching. */
|
||||||
|
param_pos++;
|
||||||
|
param_pos = strstr(param_pos, needle);
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
if (param_pos) {
|
||||||
|
param_pos += strlen(needle);
|
||||||
|
devlen = strcspn(param_pos, delim);
|
||||||
|
if (devlen) {
|
||||||
|
dev = malloc(devlen + 1);
|
||||||
|
if (!dev) {
|
||||||
|
fprintf(stderr, "Out of memory!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
strncpy(dev, param_pos, devlen);
|
||||||
|
dev[devlen] = '\0';
|
||||||
|
}
|
||||||
|
rest = param_pos + devlen;
|
||||||
|
rest += strspn(rest, delim);
|
||||||
|
param_pos -= strlen(needle);
|
||||||
|
memmove(param_pos, rest, strlen(rest) + 1);
|
||||||
|
tmp = realloc(*haystack, strlen(*haystack) + 1);
|
||||||
|
if (!tmp) {
|
||||||
|
fprintf(stderr, "Out of memory!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*haystack = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
/* start is an offset to the base address of the flash chip */
|
/* start is an offset to the base address of the flash chip */
|
||||||
int check_erased_range(struct flashchip *flash, int start, int len)
|
int check_erased_range(struct flashchip *flash, int start, int len)
|
||||||
{
|
{
|
||||||
|
3
spi.c
3
spi.c
@ -318,6 +318,9 @@ int probe_spi_rdid4(struct flashchip *flash)
|
|||||||
#endif
|
#endif
|
||||||
#if DUMMY_SUPPORT == 1
|
#if DUMMY_SUPPORT == 1
|
||||||
case SPI_CONTROLLER_DUMMY:
|
case SPI_CONTROLLER_DUMMY:
|
||||||
|
#endif
|
||||||
|
#if BUSPIRATE_SPI_SUPPORT == 1
|
||||||
|
case SPI_CONTROLLER_BUSPIRATE:
|
||||||
#endif
|
#endif
|
||||||
return probe_spi_rdid_generic(flash, 4);
|
return probe_spi_rdid_generic(flash, 4);
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user