mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-10-31 05:10:41 +01: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:
		| @@ -131,34 +131,37 @@ int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, unsigned int r | ||||
| 	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) | ||||
| { | ||||
| 	unsigned char buf[512]; | ||||
| 	int ret = 0; | ||||
| 	int i; | ||||
| 	char *devpos = NULL; | ||||
| 	char *dev = NULL; | ||||
| 	int devlen; | ||||
| 	char *speed = NULL; | ||||
| 	int spispeed = 0x7; | ||||
|  | ||||
| 	if (programmer_param && !strlen(programmer_param)) { | ||||
| 		free(programmer_param); | ||||
| 		programmer_param = NULL; | ||||
| 	} | ||||
| 	if (programmer_param) { | ||||
| 		devpos = strstr(programmer_param, "dev="); | ||||
| 		if (devpos) { | ||||
| 			devpos += 4; | ||||
| 			devlen = strcspn(devpos, ",:"); | ||||
| 			if (devlen) { | ||||
| 				dev = malloc(devlen + 1); | ||||
| 				if (!dev) { | ||||
| 					fprintf(stderr, "Out of memory!\n"); | ||||
| 					exit(1); | ||||
| 				} | ||||
| 				strncpy(dev, devpos, devlen); | ||||
| 				dev[devlen] = '\0'; | ||||
| 			} | ||||
| 		} | ||||
| 		dev = extract_param(&programmer_param, "dev=", ",:"); | ||||
| 		speed = extract_param(&programmer_param, "spispeed=", ",:"); | ||||
| 		if (strlen(programmer_param)) | ||||
| 			fprintf(stderr, "Unhandled programmer parameters: %s\n", | ||||
| 				programmer_param); | ||||
| 		free(programmer_param); | ||||
| 		programmer_param = NULL; | ||||
| 	} | ||||
| @@ -167,6 +170,18 @@ int buspirate_spi_init(void) | ||||
| 			"buspiratespi:dev=/dev/ttyUSB0\n"); | ||||
| 		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); | ||||
| 	if (ret) | ||||
| @@ -224,8 +239,8 @@ int buspirate_spi_init(void) | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	/* Set speed to 8 MHz */ | ||||
| 	buf[0] = 0x60 | 0x7; | ||||
| 	/* Set SPI speed */ | ||||
| 	buf[0] = 0x60 | spispeed; | ||||
| 	ret = buspirate_sendrecv(buf, 1, 1); | ||||
| 	if (ret) | ||||
| 		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) | ||||
| { | ||||
| 	/* Maximum read length is 12 bytes, use 8 for now. */ | ||||
| 	return spi_read_chunked(flash, buf, start, len, 8); | ||||
| 	return spi_read_chunked(flash, buf, start, len, 12); | ||||
| } | ||||
|  | ||||
| /* 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); | ||||
|  | ||||
| /* buspirate_spi.c */ | ||||
| struct buspirate_spispeeds { | ||||
| 	const char *name; | ||||
| 	const int speed; | ||||
| }; | ||||
| int buspirate_spi_init(void); | ||||
| int buspirate_spi_shutdown(void); | ||||
| 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 min(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 verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message); | ||||
| 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 | ||||
| .BR "* serprog" " (for flash ROMs attached to Urja's AVR programmer)" | ||||
| .sp | ||||
| .BR "* buspiratespi" " (for flash ROMs attached to a Bus Pirate)" | ||||
| .sp | ||||
| The dummy programmer has an optional parameter specifying the bus types it | ||||
| should support. For that you have to use the | ||||
| .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 | ||||
| the source distribution. | ||||
| .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. | ||||
| .B "flashrom -h" | ||||
| lists all supported programmers. | ||||
|   | ||||
							
								
								
									
										54
									
								
								flashrom.c
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								flashrom.c
									
									
									
									
									
								
							| @@ -336,6 +336,60 @@ char *strcat_realloc(char *dest, const char *src) | ||||
| 	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 */ | ||||
| int check_erased_range(struct flashchip *flash, int start, int len) | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Carl-Daniel Hailfinger
					Carl-Daniel Hailfinger