summaryrefslogtreecommitdiffstats
path: root/libdpf/bootload.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdpf/bootload.c')
-rw-r--r--libdpf/bootload.c634
1 files changed, 348 insertions, 286 deletions
diff --git a/libdpf/bootload.c b/libdpf/bootload.c
index 2d882cf..342ec2b 100644
--- a/libdpf/bootload.c
+++ b/libdpf/bootload.c
@@ -5,7 +5,7 @@
//
#include "dpf.h"
-#include "usbuser.h" // our user defined flash commands
+#include "usbuser.h" // our user defined flash commands
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -20,360 +20,422 @@
#define BUFSIZE (64 - 6)
#define PKTSIZE (64 - 7)
-typedef struct {
- unsigned char len;
- unsigned char chk;
- unsigned char jmp[2];
- union {
- // Structures for various backends
- // The default memory loader:
- struct {
- unsigned char offset[2]; // XDATA memory dest address
- unsigned char buf[BUFSIZE]; // Binary data to write
- } loader;
- struct {
- unsigned char opcode; // SPI operation opcode
- unsigned char wnum; // Number of bytes to send (Host -> DPF)
- unsigned char rnum; // Number of bytes to recv (DPF -> Host)
- unsigned char seq[PKTSIZE]; // SPI cmd sequence
- } spi;
- } u;
+typedef struct
+{
+ unsigned char len;
+ unsigned char chk;
+ unsigned char jmp[2];
+ union
+ {
+ // Structures for various backends
+ // The default memory loader:
+ struct
+ {
+ unsigned char offset[2]; // XDATA memory dest address
+ unsigned char buf[BUFSIZE]; // Binary data to write
+ } loader;
+ struct
+ {
+ unsigned char opcode; // SPI operation opcode
+ unsigned char wnum; // Number of bytes to send (Host -> DPF)
+ unsigned char rnum; // Number of bytes to recv (DPF -> Host)
+ unsigned char seq[PKTSIZE]; // SPI cmd sequence
+ } spi;
+ } u;
} UsbMsg;
-#define OPCODE_SPISEL 0x01 // assert SELECT
+#define OPCODE_SPISEL 0x01 // assert SELECT
#define OPCODE_CRYPT0 0x02
#define OPCODE_CRYPT1 0x04
-#define OPCODE_SPIDES 0x10 // assert DESELECT
+#define OPCODE_SPIDES 0x10 // assert DESELECT
-int validate(UsbMsg *msg)
+int
+validate (UsbMsg * msg)
{
- unsigned short c = 0;
- unsigned char *b = (unsigned char *) msg;
- unsigned short l = msg->len;
+ unsigned short c = 0;
+ unsigned char *b = (unsigned char *) msg;
+ unsigned short l = msg->len;
- if (l < 6 || l > 64) return -1;
+ if (l < 6 || l > 64)
+ return -1;
- while (l--) {
- c += *b++;
- }
+ while (l--)
+ {
+ c += *b++;
+ }
- msg->chk -= c;
+ msg->chk -= c;
- return 0;
+ return 0;
}
-void hexdump(unsigned char *buf, unsigned long n)
+void
+hexdump (unsigned char *buf, unsigned long n)
{
- int i = 0;
- int c = 0;
-
- while (i < n) {
- printf("%02x ", buf[i]);
- c++;
- if (c == 16) { c = 0; printf("\n"); }
- i++;
- }
- if (c)
- printf("\n");
+ int i = 0;
+ int c = 0;
+
+ while (i < n)
+ {
+ printf ("%02x ", buf[i]);
+ c++;
+ if (c == 16)
+ {
+ c = 0;
+ printf ("\n");
+ }
+ i++;
+ }
+ if (c)
+ printf ("\n");
}
-int transmit(DPFContext *dpf, UsbMsg *m)
+int
+transmit (DPFContext * dpf, UsbMsg * m)
{
- int error;
- unsigned char *s = (unsigned char *) m;
- // hexdump(s, m->len);
- error = usb_rawwrite(dpf->dev.udev, s, m->len);
- if (error < 0) {
- perror("Writing to USB");
- }
- return error;
+ int error;
+ unsigned char *s = (unsigned char *) m;
+ // hexdump(s, m->len);
+ error = usb_rawwrite (dpf->dev.udev, s, m->len);
+ if (error < 0)
+ {
+ perror ("Writing to USB");
+ }
+ return error;
}
-int spilib_process(DPFContext *h, UsbMsg *umsg, unsigned char *out)
+int
+spilib_process (DPFContext * h, UsbMsg * umsg, unsigned char *out)
{
- int error;
- umsg->jmp[0] = JMP_SPILIB & 0xff; umsg->jmp[1] = JMP_SPILIB >> 8;
- umsg->len = 7 + umsg->u.spi.wnum;
-
- validate(umsg);
- error = transmit(h, umsg);
- if (umsg->u.spi.rnum > 0 && error >= 0) {
- error = usb_rawread(h->dev.udev, out, 64);
- }
- if (error < 0) perror("Reading USB");
- else error = 0;
- return error;
+ int error;
+ umsg->jmp[0] = JMP_SPILIB & 0xff;
+ umsg->jmp[1] = JMP_SPILIB >> 8;
+ umsg->len = 7 + umsg->u.spi.wnum;
+
+ validate (umsg);
+ error = transmit (h, umsg);
+ if (umsg->u.spi.rnum > 0 && error >= 0)
+ {
+ error = usb_rawread (h->dev.udev, out, 64);
+ }
+ if (error < 0)
+ perror ("Reading USB");
+ else
+ error = 0;
+ return error;
}
-int go_hid(DPFContext *dpf, ADDR jmpoffset)
+int
+go_hid (DPFContext * dpf, ADDR jmpoffset)
{
- UsbMsg umsg;
- umsg.jmp[0] = jmpoffset; umsg.jmp[1] = jmpoffset >> 8;
- umsg.len = 8;
- validate(&umsg);
- return transmit(dpf, &umsg);
+ UsbMsg umsg;
+ umsg.jmp[0] = jmpoffset;
+ umsg.jmp[1] = jmpoffset >> 8;
+ umsg.len = 8;
+ validate (&umsg);
+ return transmit (dpf, &umsg);
}
-int load(DPFContext *dpf, FILE *f, uint16_t jmpoffset)
+int
+load (DPFContext * dpf, FILE * f, uint16_t jmpoffset)
{
- int size;
- UsbMsg umsg;
-
- unsigned short offset = jmpoffset - 0x800;
-
- umsg.jmp[0] = JMP_LOAD & 0xff; umsg.jmp[1] = JMP_LOAD >> 8;
- umsg.chk = 0xce;
- size = fread(umsg.u.loader.buf, 1, BUFSIZE, f);
- if (size < 0) return size;
-
- while (size > 0) {
- umsg.u.loader.offset[0] = offset;
- umsg.u.loader.offset[1] = offset >> 8;
- umsg.len = sizeof(UsbMsg) - BUFSIZE + size;
- offset += size;
- validate(&umsg);
- transmit(dpf, &umsg);
- size = fread(umsg.u.loader.buf, 1, BUFSIZE, f);
- }
-
- // And jump into the code:
- if (jmpoffset != 0x0000) {
- go_hid(dpf, jmpoffset);
- }
- return size;
+ int size;
+ UsbMsg umsg;
+
+ unsigned short offset = jmpoffset - 0x800;
+
+ umsg.jmp[0] = JMP_LOAD & 0xff;
+ umsg.jmp[1] = JMP_LOAD >> 8;
+ umsg.chk = 0xce;
+ size = fread (umsg.u.loader.buf, 1, BUFSIZE, f);
+ if (size < 0)
+ return size;
+
+ while (size > 0)
+ {
+ umsg.u.loader.offset[0] = offset;
+ umsg.u.loader.offset[1] = offset >> 8;
+ umsg.len = sizeof (UsbMsg) - BUFSIZE + size;
+ offset += size;
+ validate (&umsg);
+ transmit (dpf, &umsg);
+ size = fread (umsg.u.loader.buf, 1, BUFSIZE, f);
+ }
+
+ // And jump into the code:
+ if (jmpoffset != 0x0000)
+ {
+ go_hid (dpf, jmpoffset);
+ }
+ return size;
}
+
/* Flash stuff, HID wrapped */
static unsigned char s_rbuf[64];
-static
-int flash_probe_hid(DPFContext *h, unsigned char *id)
+static int
+flash_probe_hid (DPFContext * h, unsigned char *id)
{
- int error;
- UsbMsg umsg;
- FILE *f;
-
- // First, load spilib.bin
- f = fopen("spilib.bin", "rb");
-
- if (!f) {
- printf("failed to open flash driver\n");
- return -1;
- }
- umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
-
- error = load(h, f, 0x0000); // Load, but do not execute
- fclose(f);
- usleep(500000);
- if (error == 0) {
- umsg.u.spi.wnum = 1;
- umsg.u.spi.rnum = 4;
- umsg.u.spi.seq[0] = SPM_RDID;
- error = spilib_process(h, &umsg, s_rbuf);
- id[0] = s_rbuf[0]; id[1] = s_rbuf[1]; id[2] = s_rbuf[2];
- }
- return error;
+ int error;
+ UsbMsg umsg;
+ FILE *f;
+
+ // First, load spilib.bin
+ f = fopen ("spilib.bin", "rb");
+
+ if (!f)
+ {
+ printf ("failed to open flash driver\n");
+ return -1;
+ }
+ umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
+
+ error = load (h, f, 0x0000); // Load, but do not execute
+ fclose (f);
+ usleep (500000);
+ if (error == 0)
+ {
+ umsg.u.spi.wnum = 1;
+ umsg.u.spi.rnum = 4;
+ umsg.u.spi.seq[0] = SPM_RDID;
+ error = spilib_process (h, &umsg, s_rbuf);
+ id[0] = s_rbuf[0];
+ id[1] = s_rbuf[1];
+ id[2] = s_rbuf[2];
+ }
+ return error;
}
-static
-int flash_cmd_hid(DPFContext *h, int command, int cmdlen, ADDR addr)
+static int
+flash_cmd_hid (DPFContext * h, int command, int cmdlen, ADDR addr)
{
- UsbMsg umsg;
- umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
- umsg.u.spi.wnum = cmdlen;
- umsg.u.spi.rnum = 0;
- umsg.u.spi.seq[0] = command;
- umsg.u.spi.seq[1] = addr >> 16;
- umsg.u.spi.seq[2] = addr >> 8;
- umsg.u.spi.seq[3] = addr;
-
- return spilib_process(h, &umsg, 0);
+ UsbMsg umsg;
+ umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
+ umsg.u.spi.wnum = cmdlen;
+ umsg.u.spi.rnum = 0;
+ umsg.u.spi.seq[0] = command;
+ umsg.u.spi.seq[1] = addr >> 16;
+ umsg.u.spi.seq[2] = addr >> 8;
+ umsg.u.spi.seq[3] = addr;
+
+ return spilib_process (h, &umsg, 0);
}
-int flash_status_hid(DPFHANDLE h, uint8_t *status)
+int
+flash_status_hid (DPFHANDLE h, uint8_t * status)
{
- int error;
- UsbMsg umsg;
- umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
- umsg.u.spi.wnum = 1;
- umsg.u.spi.rnum = 1;
- umsg.u.spi.seq[0] = SPM_RDSR;
-
- error = spilib_process(h, &umsg, s_rbuf);
- *status = s_rbuf[0];
- return error;
+ int error;
+ UsbMsg umsg;
+ umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
+ umsg.u.spi.wnum = 1;
+ umsg.u.spi.rnum = 1;
+ umsg.u.spi.seq[0] = SPM_RDSR;
+
+ error = spilib_process (h, &umsg, s_rbuf);
+ *status = s_rbuf[0];
+ return error;
}
-static
-int chunk_read(DPFContext *h, unsigned char *buf, ADDR offset, int len)
+static int
+chunk_read (DPFContext * h, unsigned char *buf, ADDR offset, int len)
{
- int error;
- UsbMsg umsg;
+ int error;
+ UsbMsg umsg;
- if (len > PKTSIZE) len = PKTSIZE;
+ if (len > PKTSIZE)
+ len = PKTSIZE;
- umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
- umsg.u.spi.wnum = 4;
- umsg.u.spi.rnum = PKTSIZE;
- umsg.u.spi.seq[0] = SPM_READ;
- umsg.u.spi.seq[1] = offset >> 16;
- umsg.u.spi.seq[2] = offset >> 8;
- umsg.u.spi.seq[3] = offset;
+ umsg.u.spi.opcode = OPCODE_SPISEL | OPCODE_SPIDES;
+ umsg.u.spi.wnum = 4;
+ umsg.u.spi.rnum = PKTSIZE;
+ umsg.u.spi.seq[0] = SPM_READ;
+ umsg.u.spi.seq[1] = offset >> 16;
+ umsg.u.spi.seq[2] = offset >> 8;
+ umsg.u.spi.seq[3] = offset;
- error = spilib_process(h, &umsg, buf);
- if (error < 0) return error;
+ error = spilib_process (h, &umsg, buf);
+ if (error < 0)
+ return error;
- return len;
+ return len;
}
-static
-int flash_read_hid(DPFContext *h, unsigned char *buf, ADDR offset, int len)
+static int
+flash_read_hid (DPFContext * h, unsigned char *buf, ADDR offset, int len)
{
- int n;
-
- while (len > 0) {
- n = chunk_read(h, buf, offset, len);
- if (n < 0) return n;
- len -= n; offset += n; buf += n;
- }
- return 0;
+ int n;
+
+ while (len > 0)
+ {
+ n = chunk_read (h, buf, offset, len);
+ if (n < 0)
+ return n;
+ len -= n;
+ offset += n;
+ buf += n;
+ }
+ return 0;
}
-int fill_spimsg(UsbMsg *umsg, const unsigned char *buf,
- unsigned short offset, int len)
+int
+fill_spimsg (UsbMsg * umsg, const unsigned char *buf,
+ unsigned short offset, int len)
{
- int n = PKTSIZE - offset;
- if (len > n) len = n;
- memcpy(&umsg->u.spi.seq[offset], buf, len);
- umsg->u.spi.wnum = offset + len;
- return len;
+ int n = PKTSIZE - offset;
+ if (len > n)
+ len = n;
+ memcpy (&umsg->u.spi.seq[offset], buf, len);
+ umsg->u.spi.wnum = offset + len;
+ return len;
}
-static
-int flash_writechunk_hid(DPFContext *h,
- const unsigned char *buf, ADDR offset, int len)
+static int
+flash_writechunk_hid (DPFContext * h,
+ const unsigned char *buf, ADDR offset, int len)
{
- UsbMsg umsg;
- int error;
- int n;
-
- if (len > PAGESIZE) len = PAGESIZE;
-
- umsg.u.spi.rnum = 0;
- umsg.u.spi.seq[0] = SPM_PP;
- umsg.u.spi.seq[1] = offset >> 16;
- umsg.u.spi.seq[2] = offset >> 8;
- umsg.u.spi.seq[3] = offset;
-
- n = fill_spimsg(&umsg, buf, 4, len);
- len -= n; buf += n; offset += n;
-
- umsg.u.spi.opcode = OPCODE_SPISEL;
- error = spilib_process(h, &umsg, 0);
- if (error < 0) return error;
-
- umsg.u.spi.opcode = 0;
- while (len > PKTSIZE) {
- n = fill_spimsg(&umsg, buf, 0, PKTSIZE);
- error = spilib_process(h, &umsg, 0);
- if (error < 0) return error;
- len -= n; buf += n; offset += n;
- }
-
- umsg.u.spi.opcode = OPCODE_SPIDES;
- fill_spimsg(&umsg, buf, 0, len);
- error = spilib_process(h, &umsg, 0);
- if (error < 0) return error;
-
- return PAGESIZE;
+ UsbMsg umsg;
+ int error;
+ int n;
+
+ if (len > PAGESIZE)
+ len = PAGESIZE;
+
+ umsg.u.spi.rnum = 0;
+ umsg.u.spi.seq[0] = SPM_PP;
+ umsg.u.spi.seq[1] = offset >> 16;
+ umsg.u.spi.seq[2] = offset >> 8;
+ umsg.u.spi.seq[3] = offset;
+
+ n = fill_spimsg (&umsg, buf, 4, len);
+ len -= n;
+ buf += n;
+ offset += n;
+
+ umsg.u.spi.opcode = OPCODE_SPISEL;
+ error = spilib_process (h, &umsg, 0);
+ if (error < 0)
+ return error;
+
+ umsg.u.spi.opcode = 0;
+ while (len > PKTSIZE)
+ {
+ n = fill_spimsg (&umsg, buf, 0, PKTSIZE);
+ error = spilib_process (h, &umsg, 0);
+ if (error < 0)
+ return error;
+ len -= n;
+ buf += n;
+ offset += n;
+ }
+
+ umsg.u.spi.opcode = OPCODE_SPIDES;
+ fill_spimsg (&umsg, buf, 0, len);
+ error = spilib_process (h, &umsg, 0);
+ if (error < 0)
+ return error;
+
+ return PAGESIZE;
}
-int blk_write(DPFContext *h, ADDR dst, const unsigned char *src,
- unsigned short len)
+int
+blk_write (DPFContext * h, ADDR dst, const unsigned char *src,
+ unsigned short len)
{
- static UsbMsg umsg;
+ static UsbMsg umsg;
- if (len > BUFSIZE) len = BUFSIZE;
+ if (len > BUFSIZE)
+ len = BUFSIZE;
- umsg.jmp[0] = JMP_LOAD & 0xff; umsg.jmp[1] = JMP_LOAD >> 8;
- memcpy(umsg.u.loader.buf, src, len);
- umsg.u.loader.offset[0] = dst;
- umsg.u.loader.offset[1] = dst >> 8;
- umsg.len = sizeof(UsbMsg) - BUFSIZE + len;
+ umsg.jmp[0] = JMP_LOAD & 0xff;
+ umsg.jmp[1] = JMP_LOAD >> 8;
+ memcpy (umsg.u.loader.buf, src, len);
+ umsg.u.loader.offset[0] = dst;
+ umsg.u.loader.offset[1] = dst >> 8;
+ umsg.len = sizeof (UsbMsg) - BUFSIZE + len;
- validate(&umsg);
- transmit(h, &umsg);
- return len;
+ validate (&umsg);
+ transmit (h, &umsg);
+ return len;
}
-int mem_write_hid(DPFContext *h,
- ADDR dst, const unsigned char *src, unsigned short n)
+int
+mem_write_hid (DPFContext * h,
+ ADDR dst, const unsigned char *src, unsigned short n)
{
- int len;
-
- while (n > 0) {
- len = blk_write(h, dst, src, n);
- n -= len; src += len; dst += len;
- }
- return n;
+ int len;
+
+ while (n > 0)
+ {
+ len = blk_write (h, dst, src, n);
+ n -= len;
+ src += len;
+ dst += len;
+ }
+ return n;
}
-AccessMethods
-hid_methods = {
- .mem_read = NULL,
- .mem_write = mem_write_hid,
- .go = go_hid,
- .bootstrap = NULL,
- .flash_probe = flash_probe_hid,
- .flash_cmd = flash_cmd_hid,
- .flash_status = flash_status_hid,
- .flash_read = flash_read_hid,
- .flash_writechunk = flash_writechunk_hid,
- .flash_lock = NULL,
-};
+AccessMethods hid_methods =
+{
+.mem_read = NULL,.mem_write = mem_write_hid,.go = go_hid,.bootstrap =
+ NULL,.flash_probe = flash_probe_hid,.flash_cmd =
+ flash_cmd_hid,.flash_status = flash_status_hid,.flash_read =
+ flash_read_hid,.flash_writechunk = flash_writechunk_hid,.flash_lock =
+ NULL,};
#ifdef TEST
-int main(int argc, char **argv)
+int
+main (int argc, char **argv)
{
- FILE *f;
- int error;
- DPFHANDLE dpf;
- uint16_t startaddr = 0x1000;
-
- if (argc >= 2) {
-
- f = fopen(argv[1], "rb");
-
- if (!f) {
- printf("failed to open file\n");
- return -1;
- }
- if (argc == 3) {
- startaddr = strtol(argv[2], NULL, 16);
- printf("Starting at %04x\n", startaddr);
- }
-
- error = dpf_open("usb0", &dpf);
- if (error < 0) {
- printf("Failed to open DPF\n");
- return error;
- }
- if (dpf->mode == MODE_USBHID) {
- error = load(dpf, f, startaddr);
- } else {
- printf("Not in BOOTLOAD mode! Press Reset and hold MENU\n");
- }
- dpf_close(dpf);
- } else {
- printf("Needs boot image argument\n");
- }
-
- if (error < 0) {
- printf("Error\n");
- }
- return error;
+ FILE *f;
+ int error;
+ DPFHANDLE dpf;
+ uint16_t startaddr = 0x1000;
+
+ if (argc >= 2)
+ {
+
+ f = fopen (argv[1], "rb");
+
+ if (!f)
+ {
+ printf ("failed to open file\n");
+ return -1;
+ }
+ if (argc == 3)
+ {
+ startaddr = strtol (argv[2], NULL, 16);
+ printf ("Starting at %04x\n", startaddr);
+ }
+
+ error = dpf_open ("usb0", &dpf);
+ if (error < 0)
+ {
+ printf ("Failed to open DPF\n");
+ return error;
+ }
+ if (dpf->mode == MODE_USBHID)
+ {
+ error = load (dpf, f, startaddr);
+ }
+ else
+ {
+ printf ("Not in BOOTLOAD mode! Press Reset and hold MENU\n");
+ }
+ dpf_close (dpf);
+ }
+ else
+ {
+ printf ("Needs boot image argument\n");
+ }
+
+ if (error < 0)
+ {
+ printf ("Error\n");
+ }
+ return error;
}
#endif