fomu-flash: convert tabs to spaces
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
f2ae56a13e
commit
4156a37d72
892
fomu-flash.c
892
fomu-flash.c
@ -28,543 +28,543 @@ static unsigned int F_RESET = 27;
|
|||||||
#define DEBUG_ICE40_PATCH
|
#define DEBUG_ICE40_PATCH
|
||||||
|
|
||||||
static int spi_irw_readb(void *data) {
|
static int spi_irw_readb(void *data) {
|
||||||
return spiRx(data);
|
return spiRx(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_irw_writeb(void *data, uint8_t b) {
|
static int spi_irw_writeb(void *data, uint8_t b) {
|
||||||
spiTx(data, b);
|
spiTx(data, b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int isprint(int c)
|
static inline int isprint(int c)
|
||||||
{
|
{
|
||||||
return c > 32 && c < 127;
|
return c > 32 && c < 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
int print_hex_offset(FILE *stream,
|
int print_hex_offset(FILE *stream,
|
||||||
const void *block, int count, int offset, uint32_t start)
|
const void *block, int count, int offset, uint32_t start)
|
||||||
{
|
{
|
||||||
|
|
||||||
int byte;
|
int byte;
|
||||||
const uint8_t *b = block;
|
const uint8_t *b = block;
|
||||||
|
|
||||||
count += offset;
|
count += offset;
|
||||||
b -= offset;
|
b -= offset;
|
||||||
for ( ; offset < count; offset += 16) {
|
for ( ; offset < count; offset += 16) {
|
||||||
fprintf(stream, "%08x", start + offset);
|
fprintf(stream, "%08x", start + offset);
|
||||||
|
|
||||||
for (byte = 0; byte < 16; byte++) {
|
for (byte = 0; byte < 16; byte++) {
|
||||||
if (byte == 8)
|
if (byte == 8)
|
||||||
fprintf(stream, " ");
|
fprintf(stream, " ");
|
||||||
fprintf(stream, " ");
|
fprintf(stream, " ");
|
||||||
if (offset + byte < count)
|
if (offset + byte < count)
|
||||||
fprintf(stream, "%02x", b[offset + byte] & 0xff);
|
fprintf(stream, "%02x", b[offset + byte] & 0xff);
|
||||||
else
|
else
|
||||||
fprintf(stream, " ");
|
fprintf(stream, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stream, " |");
|
fprintf(stream, " |");
|
||||||
for (byte = 0; byte < 16 && byte + offset < count; byte++)
|
for (byte = 0; byte < 16 && byte + offset < count; byte++)
|
||||||
fprintf(stream, "%c", isprint(b[offset + byte]) ? b[offset + byte] : '.');
|
fprintf(stream, "%c", isprint(b[offset + byte]) ? b[offset + byte] : '.');
|
||||||
fprintf(stream, "|\r\n");
|
fprintf(stream, "|\r\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int print_hex(const void *block, int count, uint32_t start)
|
int print_hex(const void *block, int count, uint32_t start)
|
||||||
{
|
{
|
||||||
FILE *stream = stdout;
|
FILE *stream = stdout;
|
||||||
return print_hex_offset(stream, block, count, 0, start);
|
return print_hex_offset(stream, block, count, 0, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum op {
|
enum op {
|
||||||
OP_SPI_READ,
|
OP_SPI_READ,
|
||||||
OP_SPI_WRITE,
|
OP_SPI_WRITE,
|
||||||
OP_SPI_VERIFY,
|
OP_SPI_VERIFY,
|
||||||
OP_SPI_PEEK,
|
OP_SPI_PEEK,
|
||||||
OP_SPI_ID,
|
OP_SPI_ID,
|
||||||
OP_SPI_SECURITY_READ,
|
OP_SPI_SECURITY_READ,
|
||||||
OP_SPI_SECURITY_WRITE,
|
OP_SPI_SECURITY_WRITE,
|
||||||
OP_FPGA_BOOT,
|
OP_FPGA_BOOT,
|
||||||
OP_FPGA_RESET,
|
OP_FPGA_RESET,
|
||||||
OP_UNKNOWN,
|
OP_UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pinspec_to_pinname(char code) {
|
static int pinspec_to_pinname(char code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case '0': return SP_D0;
|
case '0': return SP_D0;
|
||||||
case '1': return SP_D1;
|
case '1': return SP_D1;
|
||||||
case '2': return SP_D2;
|
case '2': return SP_D2;
|
||||||
case '3': return SP_D3;
|
case '3': return SP_D3;
|
||||||
case 'o': return SP_MOSI;
|
case 'o': return SP_MOSI;
|
||||||
case 'i': return SP_MISO;
|
case 'i': return SP_MISO;
|
||||||
case 'w': return SP_WP;
|
case 'w': return SP_WP;
|
||||||
case 'h': return SP_HOLD;
|
case 'h': return SP_HOLD;
|
||||||
case 'c': return SP_CLK;
|
case 'c': return SP_CLK;
|
||||||
case 's': return SP_CS;
|
case 's': return SP_CS;
|
||||||
case 'r': return FP_RESET;
|
case 'r': return FP_RESET;
|
||||||
case 'd': return FP_DONE;
|
case 'd': return FP_DONE;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_pinspec(FILE *stream) {
|
static int print_pinspec(FILE *stream) {
|
||||||
fprintf(stream, "Pinspec:\n");
|
fprintf(stream, "Pinspec:\n");
|
||||||
fprintf(stream, " Name Description Default (BCM pin number)\n");
|
fprintf(stream, " Name Description Default (BCM pin number)\n");
|
||||||
fprintf(stream, " 0 SPI D0 %d\n", S_D0);
|
fprintf(stream, " 0 SPI D0 %d\n", S_D0);
|
||||||
fprintf(stream, " 1 SPI D1 %d\n", S_D1);
|
fprintf(stream, " 1 SPI D1 %d\n", S_D1);
|
||||||
fprintf(stream, " 2 SPI D2 %d\n", S_D2);
|
fprintf(stream, " 2 SPI D2 %d\n", S_D2);
|
||||||
fprintf(stream, " 3 SPI D3 %d\n", S_D3);
|
fprintf(stream, " 3 SPI D3 %d\n", S_D3);
|
||||||
fprintf(stream, " o SPI MOSI %d\n", S_MOSI);
|
fprintf(stream, " o SPI MOSI %d\n", S_MOSI);
|
||||||
fprintf(stream, " i SPI MISO %d\n", S_MISO);
|
fprintf(stream, " i SPI MISO %d\n", S_MISO);
|
||||||
fprintf(stream, " w SPI WP %d\n", S_WP);
|
fprintf(stream, " w SPI WP %d\n", S_WP);
|
||||||
fprintf(stream, " h SPI HOLD %d\n", S_HOLD);
|
fprintf(stream, " h SPI HOLD %d\n", S_HOLD);
|
||||||
fprintf(stream, " c SPI CLK %d\n", S_CLK);
|
fprintf(stream, " c SPI CLK %d\n", S_CLK);
|
||||||
fprintf(stream, " s SPI CS %d\n", S_CE0);
|
fprintf(stream, " s SPI CS %d\n", S_CE0);
|
||||||
fprintf(stream, " r FPGA Reset %d\n", F_RESET);
|
fprintf(stream, " r FPGA Reset %d\n", F_RESET);
|
||||||
fprintf(stream, " d FPGA Done %d\n", F_DONE);
|
fprintf(stream, " d FPGA Done %d\n", F_DONE);
|
||||||
fprintf(stream, "For example: -g i:23 or -g d:27\n");
|
fprintf(stream, "For example: -g i:23 or -g d:27\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_program_modes(FILE *stream) {
|
static int print_program_modes(FILE *stream) {
|
||||||
fprintf(stream, " -h This help page\n");
|
fprintf(stream, " -h This help page\n");
|
||||||
fprintf(stream, " -r Reset the FPGA and have it boot from SPI\n");
|
fprintf(stream, " -r Reset the FPGA and have it boot from SPI\n");
|
||||||
fprintf(stream, " -i Print out the SPI ID code\n");
|
fprintf(stream, " -i Print out the SPI ID code\n");
|
||||||
fprintf(stream, " -p offset Peek at 256 bytes of SPI flash at the specified offset\n");
|
fprintf(stream, " -p offset Peek at 256 bytes of SPI flash at the specified offset\n");
|
||||||
fprintf(stream, " -f bin Load this bitstream directly into the FPGA\n");
|
fprintf(stream, " -f bin Load this bitstream directly into the FPGA\n");
|
||||||
fprintf(stream, " -l rom Replace the ROM in the bitstream with this file\n");
|
fprintf(stream, " -l rom Replace the ROM in the bitstream with this file\n");
|
||||||
fprintf(stream, " -w bin Write this binary into the SPI flash chip\n");
|
fprintf(stream, " -w bin Write this binary into the SPI flash chip\n");
|
||||||
fprintf(stream, " -v bin Verify the SPI flash contains this data\n");
|
fprintf(stream, " -v bin Verify the SPI flash contains this data\n");
|
||||||
fprintf(stream, " -s out Save the SPI flash contents to this file\n");
|
fprintf(stream, " -s out Save the SPI flash contents to this file\n");
|
||||||
fprintf(stream, " -k n[:f] Read security register [n], or update it with the contents of file [f]\n");
|
fprintf(stream, " -k n[:f] Read security register [n], or update it with the contents of file [f]\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_help(FILE *stream, const char *progname) {
|
static int print_help(FILE *stream, const char *progname) {
|
||||||
fprintf(stream, "Fomu Raspberry Pi Flash Utilities\n");
|
fprintf(stream, "Fomu Raspberry Pi Flash Utilities\n");
|
||||||
fprintf(stream, "Usage:\n");
|
fprintf(stream, "Usage:\n");
|
||||||
fprintf(stream, "%15s (-[hri] | [-p offset] | [-f bitstream] | \n", progname);
|
fprintf(stream, "%15s (-[hri] | [-p offset] | [-f bitstream] | \n", progname);
|
||||||
fprintf(stream, "%15s [-w bin] | [-v bin] | [-s out] | [-k n[:f]])\n", "");
|
fprintf(stream, "%15s [-w bin] | [-v bin] | [-s out] | [-k n[:f]])\n", "");
|
||||||
fprintf(stream, " [-g pinspec] [-t spitype] [-b bytes]\n");
|
fprintf(stream, " [-g pinspec] [-t spitype] [-b bytes]\n");
|
||||||
fprintf(stream, "\n");
|
fprintf(stream, "\n");
|
||||||
fprintf(stream, "Program mode (pick one):\n");
|
fprintf(stream, "Program mode (pick one):\n");
|
||||||
print_program_modes(stream);
|
print_program_modes(stream);
|
||||||
fprintf(stream, "\n");
|
fprintf(stream, "\n");
|
||||||
fprintf(stream, "Configuration options:\n");
|
fprintf(stream, "Configuration options:\n");
|
||||||
fprintf(stream, " -g ps Set the pin assignment with the given pinspec\n");
|
fprintf(stream, " -g ps Set the pin assignment with the given pinspec\n");
|
||||||
fprintf(stream, " -t type Set the number of bits to use for SPI (1, 2, 4, or Q)\n");
|
fprintf(stream, " -t type Set the number of bits to use for SPI (1, 2, 4, or Q)\n");
|
||||||
fprintf(stream, " -b bytes Override the size of the SPI flash, in bytes\n");
|
fprintf(stream, " -b bytes Override the size of the SPI flash, in bytes\n");
|
||||||
fprintf(stream, "You can remap various pins with -g. The format is [name]:[number].\n");
|
fprintf(stream, "You can remap various pins with -g. The format is [name]:[number].\n");
|
||||||
fprintf(stream, "\n");
|
fprintf(stream, "\n");
|
||||||
fprintf(stream, "The width of SPI can be set with 't [width]'. Valid widths are:\n");
|
fprintf(stream, "The width of SPI can be set with 't [width]'. Valid widths are:\n");
|
||||||
fprintf(stream, " 1 - standard 1-bit spi\n");
|
fprintf(stream, " 1 - standard 1-bit spi\n");
|
||||||
fprintf(stream, " 2 - standard 2-bit spi\n");
|
fprintf(stream, " 2 - standard 2-bit spi\n");
|
||||||
fprintf(stream, " 4 - standard 4-bit spi (with 1-bit commands)\n");
|
fprintf(stream, " 4 - standard 4-bit spi (with 1-bit commands)\n");
|
||||||
fprintf(stream, " q - 4-bit qspi (with 4-bit commands)\n");
|
fprintf(stream, " q - 4-bit qspi (with 4-bit commands)\n");
|
||||||
fprintf(stream, "\n");
|
fprintf(stream, "\n");
|
||||||
print_pinspec(stream);
|
print_pinspec(stream);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_usage_error(FILE *stream) {
|
static int print_usage_error(FILE *stream) {
|
||||||
fprintf(stream, "Error: You must only specify one program mode:\n");
|
fprintf(stream, "Error: You must only specify one program mode:\n");
|
||||||
print_program_modes(stream);
|
print_program_modes(stream);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int opt;
|
int opt;
|
||||||
int fd;
|
int fd;
|
||||||
char *op_filename = NULL;
|
char *op_filename = NULL;
|
||||||
struct ff_spi *spi;
|
struct ff_spi *spi;
|
||||||
struct ff_fpga *fpga;
|
struct ff_fpga *fpga;
|
||||||
int peek_offset = 0;
|
int peek_offset = 0;
|
||||||
int spi_flash_bytes = -1;
|
int spi_flash_bytes = -1;
|
||||||
uint8_t security_reg;
|
uint8_t security_reg;
|
||||||
uint8_t security_val[256];
|
uint8_t security_val[256];
|
||||||
enum op op = OP_UNKNOWN;
|
enum op op = OP_UNKNOWN;
|
||||||
enum spi_type spi_type = ST_SINGLE;
|
enum spi_type spi_type = ST_SINGLE;
|
||||||
struct irw_file *replacement_rom = NULL;
|
struct irw_file *replacement_rom = NULL;
|
||||||
|
|
||||||
if (gpioInitialise() < 0) {
|
if (gpioInitialise() < 0) {
|
||||||
fprintf(stderr, "Unable to initialize GPIO\n");
|
fprintf(stderr, "Unable to initialize GPIO\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The original Raspberry Pi boards had a different assignment
|
// The original Raspberry Pi boards had a different assignment
|
||||||
// of pin 13. All other boards assign it to BCM 27, but the
|
// of pin 13. All other boards assign it to BCM 27, but the
|
||||||
// original had it as BCM 21.
|
// original had it as BCM 21.
|
||||||
if ((gpioHardwareRevision() == 2) || (gpioHardwareRevision() == 3))
|
if ((gpioHardwareRevision() == 2) || (gpioHardwareRevision() == 3))
|
||||||
F_RESET = 21;
|
F_RESET = 21;
|
||||||
|
|
||||||
spi = spiAlloc();
|
spi = spiAlloc();
|
||||||
fpga = fpgaAlloc();
|
fpga = fpgaAlloc();
|
||||||
|
|
||||||
spiSetPin(spi, SP_CLK, S_CLK);
|
spiSetPin(spi, SP_CLK, S_CLK);
|
||||||
spiSetPin(spi, SP_D0, S_D0);
|
spiSetPin(spi, SP_D0, S_D0);
|
||||||
spiSetPin(spi, SP_D1, S_D1);
|
spiSetPin(spi, SP_D1, S_D1);
|
||||||
spiSetPin(spi, SP_D2, S_D2);
|
spiSetPin(spi, SP_D2, S_D2);
|
||||||
spiSetPin(spi, SP_D3, S_D3);
|
spiSetPin(spi, SP_D3, S_D3);
|
||||||
spiSetPin(spi, SP_MISO, S_MISO);
|
spiSetPin(spi, SP_MISO, S_MISO);
|
||||||
spiSetPin(spi, SP_MOSI, S_MOSI);
|
spiSetPin(spi, SP_MOSI, S_MOSI);
|
||||||
spiSetPin(spi, SP_HOLD, S_HOLD);
|
spiSetPin(spi, SP_HOLD, S_HOLD);
|
||||||
spiSetPin(spi, SP_WP, S_WP);
|
spiSetPin(spi, SP_WP, S_WP);
|
||||||
spiSetPin(spi, SP_CS, S_CE0);
|
spiSetPin(spi, SP_CS, S_CE0);
|
||||||
|
|
||||||
fpgaSetPin(fpga, FP_RESET, F_RESET);
|
fpgaSetPin(fpga, FP_RESET, F_RESET);
|
||||||
fpgaSetPin(fpga, FP_DONE, F_DONE);
|
fpgaSetPin(fpga, FP_DONE, F_DONE);
|
||||||
fpgaSetPin(fpga, FP_CS, S_CE0);
|
fpgaSetPin(fpga, FP_CS, S_CE0);
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "hip:rf:b:w:s:2:3:v:g:t:k:l:")) != -1) {
|
while ((opt = getopt(argc, argv, "hip:rf:b:w:s:2:3:v:g:t:k:l:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_FPGA_RESET;
|
op = OP_FPGA_RESET;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
spi_flash_bytes = strtoul(optarg, NULL, 0);
|
spi_flash_bytes = strtoul(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
replacement_rom = irw_open(optarg, "r");
|
replacement_rom = irw_open(optarg, "r");
|
||||||
if (!replacement_rom) {
|
if (!replacement_rom) {
|
||||||
perror("couldn't open replacement rom file");
|
perror("couldn't open replacement rom file");
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'k': {
|
case 'k': {
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
char *security_filename = strchr(optarg, ':');
|
char *security_filename = strchr(optarg, ':');
|
||||||
|
|
||||||
security_reg = strtoul(optarg, NULL, 0);
|
security_reg = strtoul(optarg, NULL, 0);
|
||||||
if (security_filename) {
|
if (security_filename) {
|
||||||
security_filename++;
|
security_filename++;
|
||||||
op = OP_SPI_SECURITY_WRITE;
|
op = OP_SPI_SECURITY_WRITE;
|
||||||
int fd;
|
int fd;
|
||||||
fd = open(security_filename, O_RDONLY);
|
fd = open(security_filename, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("couldn't open security file");
|
perror("couldn't open security file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memset(security_val, 0, sizeof(security_val));
|
memset(security_val, 0, sizeof(security_val));
|
||||||
if (-1 == read(fd, security_val, sizeof(security_val))) {
|
if (-1 == read(fd, security_val, sizeof(security_val))) {
|
||||||
perror("couldn't read from security file");
|
perror("couldn't read from security file");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
op = OP_SPI_SECURITY_READ;
|
op = OP_SPI_SECURITY_READ;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_SPI_ID;
|
op = OP_SPI_ID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_SPI_PEEK;
|
op = OP_SPI_PEEK;
|
||||||
peek_offset = strtoul(optarg, NULL, 0);
|
peek_offset = strtoul(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
switch (*optarg) {
|
switch (*optarg) {
|
||||||
case '1':
|
case '1':
|
||||||
spi_type = ST_SINGLE;
|
spi_type = ST_SINGLE;
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
spi_type = ST_DUAL;
|
spi_type = ST_DUAL;
|
||||||
break;
|
break;
|
||||||
case '4':
|
case '4':
|
||||||
spi_type = ST_QUAD;
|
spi_type = ST_QUAD;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
spi_type = ST_QPI;
|
spi_type = ST_QPI;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unrecognized SPI speed '%c'. Valid types are: 1, 2, 4, or q\n", *optarg);
|
fprintf(stderr, "Unrecognized SPI speed '%c'. Valid types are: 1, 2, 4, or q\n", *optarg);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
if ((optarg[0] == '\0') || (optarg[1] != ':')) {
|
if ((optarg[0] == '\0') || (optarg[1] != ':')) {
|
||||||
fprintf(stderr, "-g requires a pinspec. Usage:\n");
|
fprintf(stderr, "-g requires a pinspec. Usage:\n");
|
||||||
print_pinspec(stderr);
|
print_pinspec(stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
spiSetPin(spi, pinspec_to_pinname(optarg[0]), strtoul(optarg+2, NULL, 0));
|
spiSetPin(spi, pinspec_to_pinname(optarg[0]), strtoul(optarg+2, NULL, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '2':
|
case '2':
|
||||||
spiSetPin(spi, SP_D2, strtoul(optarg, NULL, 0));
|
spiSetPin(spi, SP_D2, strtoul(optarg, NULL, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '3':
|
case '3':
|
||||||
spiSetPin(spi, SP_D3, strtoul(optarg, NULL, 0));
|
spiSetPin(spi, SP_D3, strtoul(optarg, NULL, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_FPGA_BOOT;
|
op = OP_FPGA_BOOT;
|
||||||
if (op_filename)
|
if (op_filename)
|
||||||
free(op_filename);
|
free(op_filename);
|
||||||
op_filename = strdup(optarg);
|
op_filename = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w':
|
case 'w':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_SPI_WRITE;
|
op = OP_SPI_WRITE;
|
||||||
if (op_filename)
|
if (op_filename)
|
||||||
free(op_filename);
|
free(op_filename);
|
||||||
op_filename = strdup(optarg);
|
op_filename = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_SPI_VERIFY;
|
op = OP_SPI_VERIFY;
|
||||||
if (op_filename)
|
if (op_filename)
|
||||||
free(op_filename);
|
free(op_filename);
|
||||||
op_filename = strdup(optarg);
|
op_filename = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
if (op != OP_UNKNOWN)
|
if (op != OP_UNKNOWN)
|
||||||
return print_usage_error(stdout);
|
return print_usage_error(stdout);
|
||||||
op = OP_SPI_READ;
|
op = OP_SPI_READ;
|
||||||
if (op_filename)
|
if (op_filename)
|
||||||
free(op_filename);
|
free(op_filename);
|
||||||
op_filename = strdup(optarg);
|
op_filename = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print_help(stdout, argv[0]);
|
print_help(stdout, argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == OP_UNKNOWN) {
|
if (op == OP_UNKNOWN) {
|
||||||
print_help(stdout, argv[0]);
|
print_help(stdout, argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
spiInit(spi);
|
spiInit(spi);
|
||||||
fpgaInit(fpga);
|
fpgaInit(fpga);
|
||||||
|
|
||||||
spiSetType(spi, spi_type);
|
spiSetType(spi, spi_type);
|
||||||
fpgaReset(fpga);
|
fpgaReset(fpga);
|
||||||
|
|
||||||
if (spi_flash_bytes != -1)
|
if (spi_flash_bytes != -1)
|
||||||
spiOverrideSize(spi, spi_flash_bytes);
|
spiOverrideSize(spi, spi_flash_bytes);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_SPI_ID: {
|
case OP_SPI_ID: {
|
||||||
struct spi_id id = spiId(spi);
|
struct spi_id id = spiId(spi);
|
||||||
printf("Manufacturer ID: %s (%02x)\n", id.manufacturer, id.manufacturer_id);
|
printf("Manufacturer ID: %s (%02x)\n", id.manufacturer, id.manufacturer_id);
|
||||||
if (id.manufacturer_id != id._manufacturer_id)
|
if (id.manufacturer_id != id._manufacturer_id)
|
||||||
printf("!! JEDEC Manufacturer ID: %02x\n",
|
printf("!! JEDEC Manufacturer ID: %02x\n",
|
||||||
id._manufacturer_id);
|
id._manufacturer_id);
|
||||||
printf("Memory model: %s (%02x)\n", id.model, id.memory_type);
|
printf("Memory model: %s (%02x)\n", id.model, id.memory_type);
|
||||||
printf("Memory size: %s (%02x)\n", id.capacity, id.memory_size);
|
printf("Memory size: %s (%02x)\n", id.capacity, id.memory_size);
|
||||||
printf("Device ID: %02x\n", id.device_id);
|
printf("Device ID: %02x\n", id.device_id);
|
||||||
if (id.device_id != id.signature)
|
if (id.device_id != id.signature)
|
||||||
printf("!! Electronic Signature: %02x\n", id.signature);
|
printf("!! Electronic Signature: %02x\n", id.signature);
|
||||||
printf("Serial number: %02x %02x %02x %02x\n", id.serial[0], id.serial[1], id.serial[2], id.serial[3]);
|
printf("Serial number: %02x %02x %02x %02x\n", id.serial[0], id.serial[1], id.serial[2], id.serial[3]);
|
||||||
printf("Status 1: %02x\n", spiReadStatus(spi, 1));
|
printf("Status 1: %02x\n", spiReadStatus(spi, 1));
|
||||||
printf("Status 2: %02x\n", spiReadStatus(spi, 2));
|
printf("Status 2: %02x\n", spiReadStatus(spi, 2));
|
||||||
printf("Status 3: %02x\n", spiReadStatus(spi, 3));
|
printf("Status 3: %02x\n", spiReadStatus(spi, 3));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_SECURITY_WRITE: {
|
case OP_SPI_SECURITY_WRITE: {
|
||||||
printf("Updating security register %d.\n", security_reg);
|
printf("Updating security register %d.\n", security_reg);
|
||||||
spiWriteSecurity(spi, security_reg, security_val);
|
spiWriteSecurity(spi, security_reg, security_val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_SECURITY_READ: {
|
case OP_SPI_SECURITY_READ: {
|
||||||
uint8_t security[256];
|
uint8_t security[256];
|
||||||
printf("Security register %d contents:\n", security_reg);
|
printf("Security register %d contents:\n", security_reg);
|
||||||
spiReadSecurity(spi, security_reg, security);
|
spiReadSecurity(spi, security_reg, security);
|
||||||
print_hex(security, sizeof(security), 0);
|
print_hex(security, sizeof(security), 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_READ: {
|
case OP_SPI_READ: {
|
||||||
struct spi_id id = spiId(spi);
|
struct spi_id id = spiId(spi);
|
||||||
if (id.bytes == -1) {
|
if (id.bytes == -1) {
|
||||||
fprintf(stderr, "unknown spi flash size -- specify with -b\n");
|
fprintf(stderr, "unknown spi flash size -- specify with -b\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(op_filename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
fd = open(op_filename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("unable to open output file");
|
perror("unable to open output file");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint8_t *bfr = malloc(id.bytes);
|
uint8_t *bfr = malloc(id.bytes);
|
||||||
if (!bfr) {
|
if (!bfr) {
|
||||||
perror("unable to allocate memory for spi");
|
perror("unable to allocate memory for spi");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
spiRead(spi, 0, bfr, id.bytes);
|
spiRead(spi, 0, bfr, id.bytes);
|
||||||
if (write(fd, bfr, id.bytes) != id.bytes) {
|
if (write(fd, bfr, id.bytes) != id.bytes) {
|
||||||
perror("unable to write SPI flash image to disk");
|
perror("unable to write SPI flash image to disk");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
free(bfr);
|
free(bfr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_WRITE: {
|
case OP_SPI_WRITE: {
|
||||||
fd = open(op_filename, O_RDONLY);
|
fd = open(op_filename, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("unable to open input file");
|
perror("unable to open input file");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
if (fstat(fd, &stat) == -1) {
|
if (fstat(fd, &stat) == -1) {
|
||||||
perror("unable to get bitstream file size");
|
perror("unable to get bitstream file size");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *bfr = malloc(stat.st_size);
|
uint8_t *bfr = malloc(stat.st_size);
|
||||||
if (!bfr) {
|
if (!bfr) {
|
||||||
perror("unable to alloc memory for buffer");
|
perror("unable to alloc memory for buffer");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (read(fd, bfr, stat.st_size) != stat.st_size) {
|
if (read(fd, bfr, stat.st_size) != stat.st_size) {
|
||||||
perror("unable to read from file");
|
perror("unable to read from file");
|
||||||
free(bfr);
|
free(bfr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
spiWrite(spi, 0, bfr, stat.st_size);
|
spiWrite(spi, 0, bfr, stat.st_size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_VERIFY: {
|
case OP_SPI_VERIFY: {
|
||||||
fd = open(op_filename, O_RDONLY);
|
fd = open(op_filename, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("unable to open input file");
|
perror("unable to open input file");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
if (fstat(fd, &stat) == -1) {
|
if (fstat(fd, &stat) == -1) {
|
||||||
perror("unable to get bitstream file size");
|
perror("unable to get bitstream file size");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *file_src = malloc(stat.st_size);
|
uint8_t *file_src = malloc(stat.st_size);
|
||||||
uint8_t *spi_src = malloc(stat.st_size);
|
uint8_t *spi_src = malloc(stat.st_size);
|
||||||
if (!file_src) {
|
if (!file_src) {
|
||||||
perror("unable to alloc memory for buffer");
|
perror("unable to alloc memory for buffer");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (read(fd, file_src, stat.st_size) != stat.st_size) {
|
if (read(fd, file_src, stat.st_size) != stat.st_size) {
|
||||||
perror("unable to read from file");
|
perror("unable to read from file");
|
||||||
free(file_src);
|
free(file_src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
spiRead(spi, 0, spi_src, stat.st_size);
|
spiRead(spi, 0, spi_src, stat.st_size);
|
||||||
|
|
||||||
int offset;
|
int offset;
|
||||||
for (offset = 0; offset < stat.st_size; offset++) {
|
for (offset = 0; offset < stat.st_size; offset++) {
|
||||||
if (file_src[offset] != spi_src[offset])
|
if (file_src[offset] != spi_src[offset])
|
||||||
printf("%9d: file: %02x spi: %02x\n",
|
printf("%9d: file: %02x spi: %02x\n",
|
||||||
offset, file_src[offset], spi_src[offset]);
|
offset, file_src[offset], spi_src[offset]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SPI_PEEK: {
|
case OP_SPI_PEEK: {
|
||||||
uint8_t page[256];
|
uint8_t page[256];
|
||||||
spiRead(spi, peek_offset, page, sizeof(page));
|
spiRead(spi, peek_offset, page, sizeof(page));
|
||||||
print_hex_offset(stdout, page, sizeof(page), 0, 0);
|
print_hex_offset(stdout, page, sizeof(page), 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_FPGA_BOOT: {
|
case OP_FPGA_BOOT: {
|
||||||
int count;
|
int count;
|
||||||
spiHold(spi);
|
spiHold(spi);
|
||||||
spiSwapTxRx(spi);
|
spiSwapTxRx(spi);
|
||||||
fpgaResetSlave(fpga);
|
fpgaResetSlave(fpga);
|
||||||
|
|
||||||
fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
|
fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
|
||||||
|
|
||||||
spiBegin(spi);
|
spiBegin(spi);
|
||||||
|
|
||||||
if (replacement_rom) {
|
if (replacement_rom) {
|
||||||
IRW_FILE *bitstream = irw_open(op_filename, "r");
|
IRW_FILE *bitstream = irw_open(op_filename, "r");
|
||||||
if (!bitstream) {
|
if (!bitstream) {
|
||||||
perror("unable to open fpga bitstream");
|
perror("unable to open fpga bitstream");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_ICE40_PATCH
|
#ifdef DEBUG_ICE40_PATCH
|
||||||
IRW_FILE *spidev = irw_open("foboot-patched-broken.bin", "w");
|
IRW_FILE *spidev = irw_open("foboot-patched-broken.bin", "w");
|
||||||
#else
|
#else
|
||||||
IRW_FILE *spidev = irw_open_fake(spi, spi_irw_readb, spi_irw_writeb);
|
IRW_FILE *spidev = irw_open_fake(spi, spi_irw_readb, spi_irw_writeb);
|
||||||
#endif
|
#endif
|
||||||
ice40_patch(bitstream, replacement_rom, spidev, 8192);
|
ice40_patch(bitstream, replacement_rom, spidev, 8192);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8_t bfr[32768];
|
uint8_t bfr[32768];
|
||||||
int fd = open(op_filename, O_RDONLY);
|
int fd = open(op_filename, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("unable to open fpga bitstream");
|
perror("unable to open fpga bitstream");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while ((count = read(fd, bfr, sizeof(bfr))) > 0) {
|
while ((count = read(fd, bfr, sizeof(bfr))) > 0) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
spiTx(spi, bfr[i]);
|
spiTx(spi, bfr[i]);
|
||||||
}
|
}
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
perror("unable to read from fpga bitstream file");
|
perror("unable to read from fpga bitstream file");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
for (count = 0; count < 500; count++)
|
for (count = 0; count < 500; count++)
|
||||||
spiTx(spi, 0xff);
|
spiTx(spi, 0xff);
|
||||||
fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
|
fprintf(stderr, "FPGA Done? %d\n", fpgaDone(fpga));
|
||||||
spiEnd(spi);
|
spiEnd(spi);
|
||||||
|
|
||||||
spiSwapTxRx(spi);
|
spiSwapTxRx(spi);
|
||||||
spiUnhold(spi);
|
spiUnhold(spi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_FPGA_RESET:
|
case OP_FPGA_RESET:
|
||||||
printf("resetting fpga\n");
|
printf("resetting fpga\n");
|
||||||
fpgaResetMaster(fpga);
|
fpgaResetMaster(fpga);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "error: unknown operation\n");
|
fprintf(stderr, "error: unknown operation\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpgaFree(&fpga);
|
fpgaFree(&fpga);
|
||||||
spiFree(&spi);
|
spiFree(&spi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user