Steps:
1. You will need libusb-dev on your host box:
sudo apt-get install libusb-dev
2. Modify u-boot to boot directly if it can't find mmc:
change "run nandboot;" to "run ramboot;"
and add:
"ramboot=setenv bootargs console=ttyO2,115200n8 mem=256M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm\0"
in this file u-boot/include/configs/omap3_beagle.h
3. Run minicom to the serial port, unplug USB OTG and brick power to
the BeagleBoard, remove the SD Card and then run this program like this:
cd scripts
sudo omap3_usbload/omap3_usbload -f ../tftpboot/x-load.bin \
-a 0x80008000 -f ../tftpboot/u-boot.bin \
-a 0x82000000 -f ../tftpboot/uMulti -j 0x80008000 -v
Then plug in the USB OTG cable to your host to power the board.
Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]
NOTE: first file (file1) has no addr
Load address MUST come before each file2-N
uMulti is a combined kernel/filesystem. You can substitute
uImage for uMulti and it will at least boot into the kernel,
but you won't have a filesystem.
Tested on BeagleBoardXM Rev C and Beagleboard Rev B4
The Rev B4 Beagleboard saves u-boot environment var's in NAND so you will have to interrupt u-boot
and correct them. Also on Rev B4 you will have to use an older kernel, this one won't work, then
interrupt u-boot and do:
setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm 0x82000000
You could load uImage at one address, then the ramdisk file at yet another address (at say 0x830000000) and do:
setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0 initrd=0x830000000,8M; bootm 0x82000000
http://members.efn.org/~rick/pub/0001-Add-USB-download-capability.patch
From 719f9d4d4bb09fee612abae97b28d630b6d7cfdc Mon Sep 17 00:00:00 2001
From: Rick Bronson <ri...@efn.org>
Date: Sun, 20 Nov 2011 22:22:56 -0800
Subject: [PATCH 1/1] Add USB download capability.
Signed-off-by: Rick Bronson <ri...@efn.org>
---
board/igep00x0/config.mk | 4 +-
board/omap3530beagle/config.mk | 6 +-
board/omap3evm/config.mk | 4 +-
board/overo/config.mk | 4 +-
cpu/omap3/start.S | 17 ++-
drivers/Makefile | 2 +-
drivers/usb.c | 141 ++++++++++++
drivers/usb.h | 63 ++++++
include/common.h | 1 +
include/configs/omap3530beagle.h | 2 +
lib/board.c | 5 +
scripts/Makefile | 18 ++
scripts/omap3_usbload.c | 442 ++++++++++++++++++++++++++++++++++++++
scripts/signGP.c | 2 +-
14 files changed, 696 insertions(+), 15 deletions(-)
create mode 100644 drivers/usb.c
create mode 100644 drivers/usb.h
create mode 100644 scripts/Makefile
create mode 100644 scripts/omap3_usbload.c
diff --git a/board/igep00x0/config.mk b/board/igep00x0/config.mk
index 864b7d0..48f1f4b 100644
--- a/board/igep00x0/config.mk
+++ b/board/igep00x0/config.mk
@@ -14,6 +14,6 @@
# For XIP in 64K of SRAM or debug (GP device has it all availabe)
# SRAM 40200000-4020FFFF base
# initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
# If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/board/omap3530beagle/config.mk b/board/omap3530beagle/config.mk
index f271b14..c7100cb 100644
--- a/board/omap3530beagle/config.mk
+++ b/board/omap3530beagle/config.mk
@@ -10,11 +10,11 @@
# 8000'0000 (bank0)
# For use if you want X-Loader to relocate from SRAM to DDR
-#TEXT_BASE = 0x80e80000
+#TEXT_BASE = 0x40200000
# For XIP in 64K of SRAM or debug (GP device has it all availabe)
# SRAM 40200000-4020FFFF base
# initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
# If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/board/omap3evm/config.mk b/board/omap3evm/config.mk
index a45ec22..7b4d870 100644
--- a/board/omap3evm/config.mk
+++ b/board/omap3evm/config.mk
@@ -14,6 +14,6 @@
# For XIP in 64K of SRAM or debug (GP device has it all availabe)
# SRAM 40200000-4020FFFF base
# initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
# If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/board/overo/config.mk b/board/overo/config.mk
index 7ee3014..3ce87c3 100644
--- a/board/overo/config.mk
+++ b/board/overo/config.mk
@@ -15,6 +15,6 @@
# For XIP in 64K of SRAM or debug (GP device has it all availabe)
# SRAM 40200000-4020FFFF base
# initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
# If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/cpu/omap3/start.S b/cpu/omap3/start.S
index 4cbf437..983b065 100644
--- a/cpu/omap3/start.S
+++ b/cpu/omap3/start.S
@@ -142,9 +142,7 @@ copy_loop:
/* Set up the stack */
stack_setup:
- ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
- sub sp, r0, #128 /* leave 32 words for abort-stack */
- and sp, sp, #~7 /* 8 byte alinged for (ldr/str)d */
+ ldr sp, _abort_stack
/* Clear BSS (if any). Is below tx (watch load addr - need space) */
clear_bss:
@@ -161,7 +159,18 @@ clbss_l:
_start_armboot: .word start_armboot
-
+/* we can't have the stack at the beginning of SRAM, reset needs to be there */
+ .align 3
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+ .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */
+abort_stack:
+_abort_stack: .word abort_stack
/*
*************************************************************************
*
diff --git a/drivers/Makefile b/drivers/Makefile
index bd620c2..807beb5 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -37,7 +37,7 @@ COBJS += k9f1g08r0a.o
endif
ifeq ($(BOARD), omap3530beagle)
-COBJS += k9f1g08r0a.o
+COBJS += k9f1g08r0a.o usb.o
endif
ifeq ($(BOARD), omap3evm)
diff --git a/drivers/usb.c b/drivers/usb.c
new file mode 100644
index 0000000..cd77f17
--- /dev/null
+++ b/drivers/usb.c
@@ -0,0 +1,141 @@
+/*
+ * USB bootloader
+ *
+ * Copyright (C) 2011 Rick Bronson
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/arch/cpu.h> /* get chip and board defs */
+#include "usb.h"
+
+extern void udelay (unsigned long usecs);
+
+typedef int boot_os_fn (void);
+
+/* send a buffer via USB */
+int usb_send(unsigned char *buffer, unsigned int buffer_size)
+ {
+ int ret = 0;
+
+ if (!(*peri_txcsr & MUSB_TXCSR_TXPKTRDY))
+ {
+ unsigned int cntr;
+
+ for (cntr = 0; cntr < buffer_size; cntr++)
+ *bulk_fifo = buffer[cntr];
+
+ *peri_txcsr |= MUSB_TXCSR_TXPKTRDY;
+
+ ret = buffer_size;
+ }
+ return ret;
+ }
+
+////////////////////
+
+static int usb_recv (u8 *buffer, int size)
+{
+ int cntr;
+ u16 count = 0;
+
+ if (*peri_rxcsr & MUSB_RXCSR_RXPKTRDY)
+ {
+ count = *rxcount;
+ for (cntr = 0; cntr < count; cntr++)
+ {
+ *buffer++ = *bulk_fifo;
+ }
+ /* Clear the RXPKTRDY bit */
+ *peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY;
+ }
+ return count; /* FIXME */
+}
+
+static unsigned char usb_outbuffer[64];
+
+static void usb_msg (unsigned int cmd, const char *msg)
+ {
+ unsigned char *p_char = usb_outbuffer;
+
+ * (int *) p_char = cmd;
+ p_char += sizeof (cmd);
+ if (msg)
+ {
+ while (*msg)
+ *p_char++= *msg++;
+ *p_char++= 0;
+ }
+ usb_send (usb_outbuffer, p_char - usb_outbuffer);
+ }
+
+static void usb_code (unsigned int cmd, u32 code)
+ {
+ unsigned int *p_int = (unsigned int *) usb_outbuffer;
+
+ *p_int++ = cmd;
+ *p_int++ = code;
+ usb_send (usb_outbuffer, ((unsigned char *) p_int) - usb_outbuffer);
+ }
+
+void do_usb (void)
+ {
+ boot_os_fn *boot_fn;
+ int res;
+ u32 usb_inbuffer[16];
+ u32 total;
+ u8 *addr;
+ u32 bytes;
+ int size;
+ int cntr;
+
+ usb_msg (USBLOAD_CMD_FILE_REQ, "file req");
+ for (cntr = 0; cntr < 100000; cntr++) /* try for 1 second then bail out */
+ {
+ res = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer));
+ switch (usb_inbuffer[0])
+ {
+ case USBLOAD_CMD_FILE:
+ printf ("USBLOAD_CMD_FILE total = %d addr = 0x%x val = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1], usb_inbuffer[2]);
+ total = usb_inbuffer[1]; /* get size and address */
+ addr = (u8 *) usb_inbuffer[2];
+ usb_code (USBLOAD_CMD_ECHO_SZ, total);
+
+ bytes = 0;
+ while (bytes < total)
+ {
+ size = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer));
+ memcpy(addr, usb_inbuffer, size);
+ addr += size;
+ bytes += size;
+ }
+ usb_code (USBLOAD_CMD_REPORT_SZ, total); /* tell him we got this many bytes */
+ printf ("got file addr = 0x%x\n", addr);
+ usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); /* see if they have another file for us */
+ break;
+ case USBLOAD_CMD_JUMP:
+ printf ("USBLOAD_CMD_JUMP total = %d addr = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1]);
+ boot_fn = (boot_os_fn *) usb_inbuffer[1];
+ boot_fn(); /* go to u-boot and maybe kernel */
+ break;
+ default:
+ break;
+ }
+ udelay(10); /* delay 10 us */
+ }
+ }
diff --git a/drivers/usb.h b/drivers/usb.h
new file mode 100644
index 0000000..ba8f495
--- /dev/null
+++ b/drivers/usb.h
@@ -0,0 +1,63 @@
+/*
+ * USB bootloader
+ *
+ * Copyright (C) 2011 Rick Bronson
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#define OMAP34XX_USB_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
+
+#define OMAP34XX_USB_EP(n) (OMAP34XX_USB_BASE + 0x100 + 0x10*(n))
+
+#define MUSB_RXCSR 0x06
+#define MUSB_RXCOUNT 0x08
+#define MUSB_TXCSR 0x02
+#define MUSB_FIFOSIZE 0x0F
+#define OMAP34XX_USB_RXCSR(n) (OMAP34XX_USB_EP(n) + MUSB_RXCSR)
+#define OMAP34XX_USB_RXCOUNT(n) (OMAP34XX_USB_EP(n) + MUSB_RXCOUNT)
+#define OMAP34XX_USB_TXCSR(n) (OMAP34XX_USB_EP(n) + MUSB_TXCSR)
+#define OMAP34XX_USB_FIFOSIZE(n) (OMAP34XX_USB_EP(n) + MUSB_FIFOSIZE)
+#define OMAP34XX_USB_FIFO(n) (OMAP34XX_USB_BASE + 0x20 + ((n) * 4))
+
+/* memory mapped registers */
+#define BULK_ENDPOINT 1
+static volatile u16 *peri_rxcsr = (volatile u16 *) OMAP34XX_USB_RXCSR(BULK_ENDPOINT);
+#define MUSB_RXCSR_RXPKTRDY 0x0001
+static volatile u16 *rxcount = (volatile u16 *) OMAP34XX_USB_RXCOUNT(BULK_ENDPOINT);
+static volatile u16 *peri_txcsr = (volatile u16 *) OMAP34XX_USB_TXCSR(BULK_ENDPOINT);
+#define MUSB_TXCSR_TXPKTRDY 0x0001
+static volatile u8 *bulk_fifo = (volatile u8 *) OMAP34XX_USB_FIFO(BULK_ENDPOINT);
+
+/* In high speed mode packets are 512
+ In full speed mode packets are 64 */
+#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200)
+#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040)
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b))
+
+#define PACK4(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))
+#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's') /* send file size */
+#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j') /* go where I tell you */
+#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f') /* file request */
+#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n') /* echo file size */
+#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o') /* report file size */
+#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm') /* message for debug */
+
+#endif
diff --git a/include/common.h b/include/common.h
index a3c5092..e21cc23 100644
--- a/include/common.h
+++ b/include/common.h
@@ -111,6 +111,7 @@ void hang (void) __attribute__ ((noreturn));
extern int do_load_serial_bin (ulong offset, int baudrate);
extern u32 get_mem_type(void);
extern int mmc_init(int verbose);
+extern void do_usb(void);
extern int misc_init_r(void);
extern int sprintf (char *__s, const char *__format, ...);
diff --git a/include/configs/omap3530beagle.h b/include/configs/omap3530beagle.h
index 5625417..76e3261 100644
--- a/include/configs/omap3530beagle.h
+++ b/include/configs/omap3530beagle.h
@@ -42,6 +42,8 @@
#define CONFIG_BEAGLE_REV2 1
+/* Enable the below macro if you want to use omap3_usbload to download u-boot and linux via USB */
+#define CONFIG_USB 1
/* Enable the below macro if MMC boot support is required */
#define CONFIG_MMC 1
#if defined(CONFIG_MMC)
diff --git a/lib/board.c b/lib/board.c
index 0f6b960..2f1d288 100644
--- a/lib/board.c
+++ b/lib/board.c
@@ -93,6 +93,11 @@ void start_armboot (void)
misc_init_r();
+#ifdef CONFIG_USB
+ printf("Trying load from USB\n");
+ do_usb(); /* check for usb download */
+#endif
+
buf = (uchar*) CFG_LOADADDR;
*(int *)buf = 0xffffffff;
diff --git a/scripts/Makefile b/scripts/Makefile
new file mode 100644
index 0000000..04c1e55
--- /dev/null
+++ b/scripts/Makefile
@@ -0,0 +1,18 @@
+CC = gcc
+INCLUDES =
+CFLAGS = -Wall -O2 -g $(INCLUDES)
+LIBS = -lusb
+LDFLAGS = -g $(LIBS)
+APP_NAME = omap3_usbload
+
+OBJS = omap3_usbload.o
+
+all: $(APP_NAME)
+
+$(APP_NAME): $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $^
+
+clean:
+ rm -r $(APP_NAME) *.o
+
+.PHONY: all clean
diff --git a/scripts/omap3_usbload.c b/scripts/omap3_usbload.c
new file mode 100644
index 0000000..4666111
--- /dev/null
+++ b/scripts/omap3_usbload.c
@@ -0,0 +1,442 @@
+/* $Id: Exp $
+ *
+ * omap3_usbload, an USB download application for OMAP3 processors
+ * Copyright (C) 2008 Martin Mueller <mart...@pfump.org>
+ * Modified by Rick Bronson 2011
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/*
+
+ OMAP USB loader. Using the version of x-loader with CONFIG_USB, you can
+now boot up the BeagleBoard completely into Linux with a ramdisk via USB.
+
+ Steps:
+
+1. You will need libusb-dev on your host box:
+
+sudo apt-get install libusb-dev
+
+2. Modify u-boot to boot directly if it can't find mmc:
+
+change "run nandboot;" to "run ramboot;"
+
+and add:
+
+"ramboot=setenv bootargs console=ttyO2,115200n8 mem=256M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm\0"
+
+ in this file u-boot/include/configs/omap3_beagle.h
+
+3. Run minicom to the serial port, unplug USB OTG and brick power to
+ the BeagleBoard, remove the SD Card and then run this program like this:
+
+cd scripts
+sudo omap3_usbload/omap3_usbload -f ../tftpboot/x-load.bin \
+ -a 0x80008000 -f ../tftpboot/u-boot.bin \
+ -a 0x82000000 -f ../tftpboot/uMulti -j 0x80008000 -v
+
+ Then plug in the USB OTG cable to your host to power the board.
+
+Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]
+
+ NOTE: first file (file1) has no addr
+ Load address MUST come before each file2-N
+
+ uMulti is a combined kernel/filesystem. You can substitute
+uImage for uMulti and it will at least boot into the kernel,
+but you won't have a filesystem.
+
+ Tested on BeagleBoardXM Rev C and Beagleboard Rev B4
+
+ The Rev B4 Beagleboard saves u-boot environment var's in NAND so you will have to interrupt u-boot
+and correct them. Also on Rev B4 you will have to use an older kernel, this one won't work, then
+interrupt u-boot and do:
+
+setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm 0x82000000
+
+ You could load uImage at one address, then the ramdisk file at yet another address (at say 0x830000000) and do:
+
+setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0 initrd=0x830000000,8M; bootm 0x82000000
+
+*/
+
+#include <getopt.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <usb.h>
+
+#define VERSION "1.1"
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define cpu_to_le32(x) (x)
+# define le32_to_cpu(x) (x)
+#else
+# define cpu_to_le32(x) bswap_32 (x)
+# define le32_to_cpu(x) bswap_32 (x)
+#endif
+
+#define VENDOR_ID_TI 0x0451
+#define DEVICE_ID 0xD000
+#define DEVICE_ID_MASK 0xff00
+
+#define OMAP3_BOOT_CMD 0xF0030002 /* see page 3515 sprugn4c.pdf */
+
+#define PACK4(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))
+#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's') /* send file size */
+#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j') /* go where I tell you */
+#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f') /* file request */
+#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n') /* echo file size */
+#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o') /* report file size */
+#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm') /* message for debug */
+
+#define EP_BULK_IN 0x81
+#define EP_BULK_OUT 0x01
+#define BUF_LEN 128
+#define BUF_LEN_SM 256 /* we seem to need this exact size ?? */
+
+#define USB_TIMEOUT 1000 /* time in ms */
+
+#define MAX_FILES 10 /* the max addr/file pairs */
+struct UPLOAD_DATA
+ {
+ int file_cntr;
+ unsigned long addrs[MAX_FILES];
+ int fd[MAX_FILES];
+ int filesize[MAX_FILES];
+ const char *filename[MAX_FILES]; /* file names */
+ unsigned long jump_addr;
+ usb_dev_handle *udev;
+ int verbose; /* be verbose? */
+ char *p_file;
+ };
+
+struct UPLOAD_DATA upload_data =
+ {
+ .verbose = 0, /* be verbose? */
+ .filename[0] = NULL,
+ .jump_addr = 0x80008000,
+ .p_file = NULL,
+ };
+
+
+ /* A string listing valid short options letters. */
+const char* const short_options = "a:f:j:v";
+ /* An array describing valid long options. */
+const struct option long_options[] = {
+ { "load_addr", 1, NULL, 'a' },
+ { "file", 1, NULL, 'f' },
+ { "jump", 1, NULL, 'j' },
+ { "verbose", 0, NULL, 'v' },
+ { NULL, 0, NULL, 0 } /* Required at end of array. */
+ };
+
+/* send a value to x-loader */
+static int send_val (struct UPLOAD_DATA *p_data, unsigned int code, unsigned int val1, unsigned int val2)
+{
+ int res;
+ int buffer[3];
+
+ buffer[0]= code;
+ buffer[1] = cpu_to_le32 (val1);
+ buffer[2] = cpu_to_le32 (val2);
+
+ if (p_data->verbose)
+ printf ("send_val code = 0x%x, val1 = 0x%x, val2 = 0x%x\n",(int) buffer[0], (int) buffer[1], (int) buffer[2]);
+ res= usb_bulk_write (p_data->udev, EP_BULK_OUT, (const char *) buffer, sizeof (buffer), USB_TIMEOUT);
+ if (res < sizeof (buffer))
+ {
+ printf ("Error in usb_bulk_write1: %d/8\n", res);
+ return 1;
+ }
+
+ return 0;
+}
+
+void print_usage (FILE* stream, int exit_code)
+ {
+ fprintf (stream, "Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]\n");
+ fprintf (stream,
+ " -f --file file File to load, first file (file1) has no addr\n"
+ " -a --load_addr addr Load address, MUST come before each file2-N\n"
+ " -j --jump addr Jump address[0x80008000]\n");
+ exit (exit_code);
+}
+
+enum { /* subroutine return codes */
+ RET_OK,
+ RET_ERR,
+ RET_IN_LOOP
+};
+
+int do_files(struct UPLOAD_DATA *p_data)
+ {
+ int res, sz, file_cnt, file_len, size, usb_cnt;
+ int dat_buf[BUF_LEN];
+ unsigned int command;
+ int this_file = 1; /* start with the 2nd file */
+ char *p_file;
+
+ file_cnt = usb_bulk_read(p_data->udev, EP_BULK_IN, (char *) dat_buf, sizeof (dat_buf), USB_TIMEOUT);
+ if (file_cnt <= 0)
+ {
+ printf("could not get ASIC ID\n");
+ return(-1);
+ }
+
+ command = OMAP3_BOOT_CMD;
+ if (sizeof(command) != usb_bulk_write(p_data->udev, EP_BULK_OUT, (char*) &command, sizeof(command), USB_TIMEOUT))
+ {
+ printf("could not send peripheral boot command\n");
+ return(-1);
+ }
+
+ file_len = p_data->filesize[0];
+ if (sizeof(file_len) != usb_bulk_write(p_data->udev, EP_BULK_OUT, (char*) &file_len, sizeof(file_len), USB_TIMEOUT))
+ {
+ printf("could not send length\n");
+ return(-1);
+ }
+
+ do
+ {
+ file_cnt = read(p_data->fd[0], dat_buf, sizeof (dat_buf));
+ if (file_cnt > 0)
+ {
+ usb_cnt = usb_bulk_write(p_data->udev, EP_BULK_OUT, (char *) dat_buf, file_cnt, USB_TIMEOUT);
+
+ if (usb_cnt != file_cnt)
+ {
+ printf("could not write to usb usb_cnt = %d file_cnt = %d\n", usb_cnt, file_cnt );
+ return(-1);
+ }
+ }
+ } while (file_cnt > 0);
+
+ if (p_data->verbose)
+ printf("download ok\n");
+ close(p_data->fd[0]);
+ p_data->fd[0] = 0; /* mark as closed */
+
+ /* now wait for x-loader */
+ while ((size = p_data->filesize[this_file]) > 0)
+ {
+ if (p_data->verbose)
+ printf ("while loop size = %d\n", size);
+ p_file = p_data->p_file = malloc (p_data->filesize[this_file]);
+ if (p_file == NULL)
+ {
+ printf ("Out of memory requesting %d bytes\n", p_data->filesize[this_file]);
+ return 1;
+ }
+ /* read whole file in */
+ if ((p_data->filesize[this_file] = read (p_data->fd[this_file], p_file, p_data->filesize[this_file])) < 0)
+ {
+ perror ("read file");
+ return 1;
+ }
+ if (p_data->verbose)
+ printf ("filesize = %d\n", p_data->filesize[this_file]);
+ close (p_data->fd[this_file]);
+
+ while (size > 0)
+ {
+ res= usb_bulk_read (p_data->udev, EP_BULK_IN, (char *) dat_buf, sizeof (dat_buf), USB_TIMEOUT);
+ if (res < 0)
+ {
+ printf("Error in usb_bulk_read: %d\n", res);
+ return 1;
+ }
+ if (res < 8)
+ continue;
+
+ switch (dat_buf[0])
+ {
+ case USBLOAD_CMD_FILE_REQ:
+ if (p_data->verbose)
+ printf("f: size = %d, addr = 0x%x\n", size, (int) p_data->addrs[this_file]);
+ if (send_val (p_data, USBLOAD_CMD_FILE, size, p_data->addrs[this_file]))
+ size= -1;
+ break;
+
+ case USBLOAD_CMD_REPORT_SZ: /* he tells us how many btyes are left */
+ size -= le32_to_cpu (dat_buf[1]);
+ if (size > 0)
+ size= -1;
+ break;
+
+ case USBLOAD_CMD_ECHO_SZ: /* he echo's the file size */
+ sz = le32_to_cpu (dat_buf[1]);
+ if (p_data->verbose)
+ printf("sending file, size %d %d\n", sz, res);
+ while (sz > 0)
+ {
+ res = usb_bulk_write(p_data->udev, EP_BULK_OUT, p_file, BUF_LEN_SM, USB_TIMEOUT);
+ if (res != BUF_LEN_SM) {
+ printf("Error in usb_bulk_write3: %d/%d\n", res, sz);
+ size = -1;
+ break;
+ }
+ p_file += res;
+ sz -= res;
+ }
+ break;
+
+ case USBLOAD_CMD_MESSAGE:
+ printf("Message: %s\n", (char *) &dat_buf[1]);
+ break;
+
+ default:
+ printf("Unknown packet type '%s'\n", (char *) dat_buf[1]);
+ break;
+ }
+ }
+ if (size == 0 && p_data->verbose)
+ printf("Program stored in memory: %d bytes\n", p_data->filesize[this_file]);
+ this_file++; /* next */
+ free (p_data->p_file);
+ p_data->p_file = NULL; /* mark as freed */
+ }
+ if (p_data->jump_addr)
+ {
+ send_val (p_data, USBLOAD_CMD_JUMP, p_data->jump_addr, 0); /* go to address */
+ if (p_data->verbose)
+ printf("Sending jump 0x%x\n", (int) p_data->jump_addr);
+ }
+ return 0;
+ }
+
+enum { /* need to have at least one file to load */
+ ARG_PROGNAME,
+ ARG_BINFILE,
+ NUM_ARGS
+};
+
+int main(int argc, char **argv)
+ {
+ struct UPLOAD_DATA *p_data;
+ int next_option;
+ struct usb_bus *bus;
+ int file_cntr = 0, res = RET_IN_LOOP;
+
+ p_data = &upload_data;
+ do
+ {
+ next_option = getopt_long (argc, argv, short_options,
+ long_options, NULL);
+ switch (next_option)
+ {
+ case 'a': /* -a or --load_addr */
+ /* This option takes an argument, the address to load the file into. */
+ p_data->addrs[file_cntr] = strtoul (optarg, NULL, 0);
+ break;
+ case 'f': /* -f or --file */
+ /* This option takes an argument, the name of the file. */
+ p_data->filename[file_cntr] = optarg;
+ p_data->fd[file_cntr] = open(p_data->filename[file_cntr], O_RDONLY);
+ if (p_data->fd[file_cntr] < 0)
+ {
+ perror("Can't open file");
+ return 1;
+ }
+ p_data->filesize[file_cntr] = lseek (p_data->fd[file_cntr], 0, SEEK_END);
+ if (p_data->filesize[file_cntr] < 0 || lseek (p_data->fd[file_cntr], 0, SEEK_SET) < 0)
+ {
+ perror ("lseek binfile");
+ close (p_data->fd[file_cntr]);
+ return 1;
+ }
+ if (p_data->verbose)
+ printf("Opening %s fd = %d, size = %d\n", p_data->filename[file_cntr], p_data->fd[file_cntr], p_data->filesize[file_cntr]);
+ file_cntr++; /* go to next file */
+ break;
+ case 'j': /* -j or --jump */
+ /* This option takes an argument, the jump address. */
+ p_data->jump_addr = strtoul (optarg, NULL, 0);
+ break;
+ case 'v': /* -v or --verbose */
+ p_data->verbose = 1;
+ break;
+ case '?': /* The user specified an invalid option. */
+ /* Print usage information to standard error, and exit with exit
+ code one (indicating abonormal termination). */
+ print_usage (stderr, 1);
+ break;
+ case -1: /* Done with options. */
+ break;
+ default: /* Something else: unexpected. */
+ print_usage (stderr, 1);
+ }
+ }
+ while (next_option != -1);
+
+ if (argc < NUM_ARGS) {
+ print_usage (stderr, 1);
+ return(-1);
+ }
+
+ usb_init();
+ usb_find_busses();
+
+ while (res == RET_IN_LOOP)
+ {
+ printf(".");
+ fflush(stdout);
+
+ if (usb_find_devices())
+ {
+ for (bus = usb_get_busses(); bus; bus = bus->next)
+ {
+ struct usb_device *dev;
+
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ if (dev->descriptor.idVendor == VENDOR_ID_TI &&
+ (dev->descriptor.idProduct & DEVICE_ID_MASK) == DEVICE_ID)
+ {
+ p_data->udev = usb_open(dev);
+
+ if (p_data->udev)
+ {
+ if (p_data->verbose)
+ printf("\n\nfound device 0x%04x:0x%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
+
+ if (usb_set_configuration(p_data->udev, 1) < 0)
+ {
+ printf("could not set configuration\n");
+ res = RET_ERR;
+ }
+ if (do_files(p_data)) /* if an error occurred */
+ res = RET_ERR;
+ else
+ res = RET_OK;
+ }
+ }
+ }
+ }
+ }
+ usleep(500 * 1000); /* wait until we put another dot */
+ }
+ for (file_cntr = 0; file_cntr < MAX_FILES; file_cntr++) /* close all files */
+ if (p_data->fd[file_cntr])
+ close(p_data->fd[file_cntr]);
+ if (p_data->p_file)
+ free (p_data->p_file);
+ usb_close(p_data->udev);
+ return(res);
+ }
diff --git a/scripts/signGP.c b/scripts/signGP.c
index ab4715c..a11b533 100644
--- a/scripts/signGP.c
+++ b/scripts/signGP.c
@@ -255,7 +255,7 @@ int main(int argc, char *argv[])
/* Default to x-load.bin and 0x40200800. */
strcpy(ifname, "x-load.bin");
- loadaddr = 0x40200800;
+ loadaddr = 0x40200000;
if ((argc == 2) || (argc == 3) || (argc == 4))
strcpy(ifname, argv[1]);
--
1.7.7.3