Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver
Hi Stefan, On 15/08/2017 23:54, Stefan Agner wrote: >> >> It looks like that I am again out of sync with documentation. Where is >> defined SDP_SKIP_DCD_HEADER ? It is undefined for MX6Q/D, Solo and DL. >> > > This is only available in newer SoC's e.g. i.MX 7. ok > > It allows to skip the DCD header in a downloaded image. Since the DCD > header is anyway ignored by this SDP implementation, the command is kind > of useless. I still think it is a good idea to have the command type > define for completeness... I agree with you - I just wanted to understand. >And I think also some SDP host side > implementation might issue the command... That's ok, thanks for clarification. >> >> It is fine, but I am just missing if this is a use case. DCD is >> interpreted by boot ROM, and we are here already over in SPL. >> > > I also don't have a use case currently, but it is rather cheap so why > don't? Yes, that's fine. > > Note that the SDP_READ_REGISTER command is actually used by the > sb_loader to do some verification whether the image got correctly > downloaded... But I don't think it required DCD_WRITE for something, but > I would have to retest. > >>> + case SDP_JUMP_ADDRESS: >>> + sdp->always_send_status = false; >>> + sdp->error_status = 0; >>> + >>> + sdp->jmp_address = be32_to_cpu(cmd->addr); >>> + sdp->state = SDP_STATE_TX_SEC_CONF; >>> + sdp->next_state = SDP_STATE_JUMP; >>> + break; >>> + case SDP_SKIP_DCD_HEADER: >>> + sdp->always_send_status = true; >>> + sdp->error_status = SDP_SKIP_DCD_HEADER_COMPLETE; >>> + >>> + /* Ignore command, DCD not supported anyway */ >> >> Right - we load a file, we do not need a DCD. >> >>> + sdp->state = SDP_STATE_TX_SEC_CONF; >>> + sdp->next_state = SDP_STATE_IDLE; >>> + break; >>> + default: >>> + error("Unknown command: %08x\n", be16_to_cpu(cmd->cmd)); >>> + } >>> +} >>> + >>> +static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request >>> *req) >>> +{ >>> + struct f_sdp *sdp = req->context; >>> + int status = req->status; >>> + u8 *data = req->buf; >>> + u8 report = data[0]; >>> + int datalen = req->length - 1; >>> + >>> + if (status != 0) { >>> + error("Status: %d", status); >>> + return; >>> + } >>> + >>> + if (report != 2) { >>> + error("Unexpected report %d", report); >>> + return; >>> + } >>> + >>> + if (sdp->dnl_bytes_remaining < datalen) { >>> + /* >>> +* Some USB stacks require to send a complete buffer as >>> +* specified in the HID descriptor. This leads to longer >>> +* transfers than the file length, no problem for us. >>> +*/ >>> + sdp->dnl_bytes_remaining = 0; >>> + } else { >>> + sdp->dnl_bytes_remaining -= datalen; >>> + } >>> + >>> + if (sdp->state == SDP_STATE_RX_FILE_DATA) { >>> + memcpy((void *)sdp->dnl_address, req->buf + 1, datalen); >>> + sdp->dnl_address += datalen; >>> + } >>> + >>> + if (sdp->dnl_bytes_remaining) >>> + return; >>> + >>> + printf("done\n"); >>> + >>> + switch (sdp->state) { >>> + case SDP_STATE_RX_FILE_DATA: >>> + sdp->state = SDP_STATE_TX_SEC_CONF; >>> + break; >>> + case SDP_STATE_RX_DCD_DATA: >>> + sdp->state = SDP_STATE_TX_SEC_CONF; >>> + break; >>> + default: >>> + error("Invalid state: %d", sdp->state); >>> + } >>> +} >>> + >>> + >>> + >>> +static void sdp_tx_complete(struct usb_ep *ep, struct usb_request *req) >>> +{ >>> + struct f_sdp *sdp = req->context; >>> + int status = req->status; >>> + >>> + if (status != 0) { >>> + error("Status: %d", status); >>> + return; >>> + } >>> + >>> + switch (sdp->state) { >>> + case SDP_STATE_TX_SEC_CONF_BUSY: >>> + /* Not all commands require status report */ >>> + if (sdp->always_send_status || sdp->error_status) >>> + sdp->state = SDP_STATE_TX_STATUS; >>> + else >>> + sdp->state = sdp->next_state; >>> + >>> + break; >>> + case SDP_STATE_TX_STATUS_BUSY: >>> + sdp->state = sdp->next_state; >>> + break; >>> + case SDP_STATE_TX_REGISTER_BUSY: >>> + if (sdp->dnl_bytes_remaining) >>> + sdp->state = SDP_STATE_TX_REGISTER; >>> + else >>> + sdp->state = SDP_STATE_IDLE; >>> + break; >>> + default: >>> + error("Wrong State: %d", sdp->state); >>> + sdp->state = SDP_STATE_IDLE; >>> + break; >>> + } >>> + debug("%s complete --> %d, %d/%d\n", ep->name, >>> + status, req->actual, req->length); >>> +} >>> + >>> +static int sdp_setup(struct usb_function *f, const struct usb_ctrlrequest >>> *ctrl) >>> +{ >>> + struct usb_gadget *gadget = f->config->cdev->gadget; >>>
Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver
On 2017-08-10 01:14, Stefano Babic wrote: > Hi Stefan, > > On 05/08/2017 01:38, Stefan Agner wrote: >> From: Stefan Agner >> >> Add SDP (Serial Downloader Protocol) implementation for U-Boot. The >> protocol is used in NXP SoC's boot ROM and allows to download program >> images. Beside that, it can also be used to read/write registers and >> download complete Device Configuration Data (DCD) sets. This basic >> implementation supports downloading images with the imx header format >> and reading registers. >> >> Signed-off-by: Stefan Agner >> --- >> >> drivers/usb/gadget/Kconfig | 7 + >> drivers/usb/gadget/Makefile | 1 + >> drivers/usb/gadget/f_sdp.c | 723 >> >> include/sdp.h | 16 + >> 4 files changed, 747 insertions(+) >> create mode 100644 drivers/usb/gadget/f_sdp.c >> create mode 100644 include/sdp.h >> >> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig >> index 261ed128ac..225b66bc95 100644 >> --- a/drivers/usb/gadget/Kconfig >> +++ b/drivers/usb/gadget/Kconfig >> @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD >> >> if USB_GADGET_DOWNLOAD >> >> +config USB_FUNCTION_SDP >> +bool "Enable USB SDP (Serial Download Protocol)" >> +help >> + Enable Serial Download Protocol (SDP) device support in U-Boot. This >> + allows to download images into memory and execute (jump to) them >> + using the same protocol as implemented by the i.MX family's boot ROM. >> + >> config G_DNL_MANUFACTURER >> string "Vendor name of USB device" >> >> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile >> index 5e316a7cff..6a007d1bcb 100644 >> --- a/drivers/usb/gadget/Makefile >> +++ b/drivers/usb/gadget/Makefile >> @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o >> obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o >> obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o >> obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o >> +obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o >> endif >> endif >> ifdef CONFIG_USB_ETHER >> diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c >> new file mode 100644 >> index 00..eb89695aaf >> --- /dev/null >> +++ b/drivers/usb/gadget/f_sdp.c >> @@ -0,0 +1,723 @@ >> +/* >> + * f_sdp.c -- USB HID Serial Download Protocol >> + * >> + * Copyright (C) 2016 Toradex >> + * Author: Stefan Agner >> + * >> + * This file implements the Serial Download Protocol (SDP) as specified in >> + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and >> + * allows to download images directly to memory. The implementation >> + * works with the imx_loader (imx_usb) USB client software on host side. >> + * >> + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and >> + * SKIP_DCD_HEADER are only stubs. >> + * >> + * Parts of the implementation are based on f_dfu and f_thor. >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#define HID_REPORT_ID_MASK 0x00ff >> + >> +/* >> + * HID class requests >> + */ >> +#define HID_REQ_GET_REPORT 0x01 >> +#define HID_REQ_GET_IDLE0x02 >> +#define HID_REQ_GET_PROTOCOL0x03 >> +#define HID_REQ_SET_REPORT 0x09 >> +#define HID_REQ_SET_IDLE0x0A >> +#define HID_REQ_SET_PROTOCOL0x0B >> + >> +#define HID_USAGE_PAGE_LEN 76 >> + >> +struct hid_report { >> +u8 usage_page[HID_USAGE_PAGE_LEN]; >> +} __packed; >> + >> +#define SDP_READ_REGISTER 0x0101 >> +#define SDP_WRITE_REGISTER 0x0202 >> +#define SDP_WRITE_FILE 0x0404 >> +#define SDP_ERROR_STATUS0x0505 >> +#define SDP_DCD_WRITE 0x0a0a >> +#define SDP_JUMP_ADDRESS0x0b0b >> +#define SDP_SKIP_DCD_HEADER 0x0c0c > > It looks like that I am again out of sync with documentation. Where is > defined SDP_SKIP_DCD_HEADER ? It is undefined for MX6Q/D, Solo and DL. > This is only available in newer SoC's e.g. i.MX 7. It allows to skip the DCD header in a downloaded image. Since the DCD header is anyway ignored by this SDP implementation, the command is kind of useless. I still think it is a good idea to have the command type define for completeness... And I think also some SDP host side implementation might issue the command... >> + >> +#define SDP_WRITE_FILE_COMPLETE 0x >> +#define SDP_WRITE_REGISTER_COMPLETE 0x128A8A12 >> +#define SDP_SKIP_DCD_HEADER_COMPLETE0x900DD009 >> +#define SDP_ERROR_IMXHEADER 0x000a0533 >> + >> +#define SDP_COMMAND_LEN 16 >> + >> +struct sdp_command { >> +u16 cmd; >> +u32 addr; >> +u8 format; >> +u32 cnt; >> +u32 data; >> +u8 rsvd; >> +} __packed; >> + >> +enum sdp_state { >> +SDP_STATE_IDLE, >> +SDP_STATE_RX_DCD_DATA, >> +SDP_STA
Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver
Hi Stefan, On 05/08/2017 01:38, Stefan Agner wrote: > From: Stefan Agner > > Add SDP (Serial Downloader Protocol) implementation for U-Boot. The > protocol is used in NXP SoC's boot ROM and allows to download program > images. Beside that, it can also be used to read/write registers and > download complete Device Configuration Data (DCD) sets. This basic > implementation supports downloading images with the imx header format > and reading registers. > > Signed-off-by: Stefan Agner > --- > > drivers/usb/gadget/Kconfig | 7 + > drivers/usb/gadget/Makefile | 1 + > drivers/usb/gadget/f_sdp.c | 723 > > include/sdp.h | 16 + > 4 files changed, 747 insertions(+) > create mode 100644 drivers/usb/gadget/f_sdp.c > create mode 100644 include/sdp.h > > diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig > index 261ed128ac..225b66bc95 100644 > --- a/drivers/usb/gadget/Kconfig > +++ b/drivers/usb/gadget/Kconfig > @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD > > if USB_GADGET_DOWNLOAD > > +config USB_FUNCTION_SDP > + bool "Enable USB SDP (Serial Download Protocol)" > + help > + Enable Serial Download Protocol (SDP) device support in U-Boot. This > + allows to download images into memory and execute (jump to) them > + using the same protocol as implemented by the i.MX family's boot ROM. > + > config G_DNL_MANUFACTURER > string "Vendor name of USB device" > > diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile > index 5e316a7cff..6a007d1bcb 100644 > --- a/drivers/usb/gadget/Makefile > +++ b/drivers/usb/gadget/Makefile > @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o > obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o > obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o > obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o > +obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o > endif > endif > ifdef CONFIG_USB_ETHER > diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c > new file mode 100644 > index 00..eb89695aaf > --- /dev/null > +++ b/drivers/usb/gadget/f_sdp.c > @@ -0,0 +1,723 @@ > +/* > + * f_sdp.c -- USB HID Serial Download Protocol > + * > + * Copyright (C) 2016 Toradex > + * Author: Stefan Agner > + * > + * This file implements the Serial Download Protocol (SDP) as specified in > + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and > + * allows to download images directly to memory. The implementation > + * works with the imx_loader (imx_usb) USB client software on host side. > + * > + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and > + * SKIP_DCD_HEADER are only stubs. > + * > + * Parts of the implementation are based on f_dfu and f_thor. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#define HID_REPORT_ID_MASK 0x00ff > + > +/* > + * HID class requests > + */ > +#define HID_REQ_GET_REPORT 0x01 > +#define HID_REQ_GET_IDLE 0x02 > +#define HID_REQ_GET_PROTOCOL 0x03 > +#define HID_REQ_SET_REPORT 0x09 > +#define HID_REQ_SET_IDLE 0x0A > +#define HID_REQ_SET_PROTOCOL 0x0B > + > +#define HID_USAGE_PAGE_LEN 76 > + > +struct hid_report { > + u8 usage_page[HID_USAGE_PAGE_LEN]; > +} __packed; > + > +#define SDP_READ_REGISTER0x0101 > +#define SDP_WRITE_REGISTER 0x0202 > +#define SDP_WRITE_FILE 0x0404 > +#define SDP_ERROR_STATUS 0x0505 > +#define SDP_DCD_WRITE0x0a0a > +#define SDP_JUMP_ADDRESS 0x0b0b > +#define SDP_SKIP_DCD_HEADER 0x0c0c It looks like that I am again out of sync with documentation. Where is defined SDP_SKIP_DCD_HEADER ? It is undefined for MX6Q/D, Solo and DL. > + > +#define SDP_WRITE_FILE_COMPLETE 0x > +#define SDP_WRITE_REGISTER_COMPLETE 0x128A8A12 > +#define SDP_SKIP_DCD_HEADER_COMPLETE 0x900DD009 > +#define SDP_ERROR_IMXHEADER 0x000a0533 > + > +#define SDP_COMMAND_LEN 16 > + > +struct sdp_command { > + u16 cmd; > + u32 addr; > + u8 format; > + u32 cnt; > + u32 data; > + u8 rsvd; > +} __packed; > + > +enum sdp_state { > + SDP_STATE_IDLE, > + SDP_STATE_RX_DCD_DATA, > + SDP_STATE_RX_FILE_DATA, > + SDP_STATE_TX_SEC_CONF, > + SDP_STATE_TX_SEC_CONF_BUSY, > + SDP_STATE_TX_REGISTER, > + SDP_STATE_TX_REGISTER_BUSY, > + SDP_STATE_TX_STATUS, > + SDP_STATE_TX_STATUS_BUSY, > + SDP_STATE_JUMP, > +}; > + > +struct f_sdp { > + struct usb_function usb_function; > + > + struct usb_descriptor_header**function; > + > + u8 altsetting; > + enum sdp_state state; > + enum sdp_state next_state; > + u
Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver
Hi Stefan, From: Stefan Agner Add SDP (Serial Downloader Protocol) implementation for U-Boot. The protocol is used in NXP SoC's boot ROM and allows to download program images. Beside that, it can also be used to read/write registers and download complete Device Configuration Data (DCD) sets. This basic implementation supports downloading images with the imx header format and reading registers. Signed-off-by: Stefan Agner Just some minor comments (despite comments from Lothar). --- drivers/usb/gadget/Kconfig | 7 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_sdp.c | 723 include/sdp.h | 16 + 4 files changed, 747 insertions(+) create mode 100644 drivers/usb/gadget/f_sdp.c create mode 100644 include/sdp.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 261ed128ac..225b66bc95 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD if USB_GADGET_DOWNLOAD +config USB_FUNCTION_SDP + bool "Enable USB SDP (Serial Download Protocol)" + help + Enable Serial Download Protocol (SDP) device support in U-Boot. This + allows to download images into memory and execute (jump to) them + using the same protocol as implemented by the i.MX family's boot ROM. + config G_DNL_MANUFACTURER string "Vendor name of USB device" diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 5e316a7cff..6a007d1bcb 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o endif endif ifdef CONFIG_USB_ETHER diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c new file mode 100644 index 00..eb89695aaf --- /dev/null +++ b/drivers/usb/gadget/f_sdp.c @@ -0,0 +1,723 @@ +/* + * f_sdp.c -- USB HID Serial Download Protocol + * + * Copyright (C) 2016 Toradex - minor -> If you are going to prepare v2, please update the date. + * Author: Stefan Agner + * + * This file implements the Serial Download Protocol (SDP) as specified in + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and + * allows to download images directly to memory. The implementation + * works with the imx_loader (imx_usb) USB client software on host side. + * + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and + * SKIP_DCD_HEADER are only stubs. + * + * Parts of the implementation are based on f_dfu and f_thor. + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define HID_REPORT_ID_MASK 0x00ff + +/* + * HID class requests + */ +#define HID_REQ_GET_REPORT 0x01 +#define HID_REQ_GET_IDLE 0x02 +#define HID_REQ_GET_PROTOCOL 0x03 +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_SET_PROTOCOL 0x0B + +#define HID_USAGE_PAGE_LEN 76 + +struct hid_report { + u8 usage_page[HID_USAGE_PAGE_LEN]; +} __packed; + +#define SDP_READ_REGISTER 0x0101 +#define SDP_WRITE_REGISTER 0x0202 +#define SDP_WRITE_FILE 0x0404 +#define SDP_ERROR_STATUS 0x0505 +#define SDP_DCD_WRITE 0x0a0a +#define SDP_JUMP_ADDRESS 0x0b0b +#define SDP_SKIP_DCD_HEADER0x0c0c + +#define SDP_WRITE_FILE_COMPLETE0x +#define SDP_WRITE_REGISTER_COMPLETE0x128A8A12 +#define SDP_SKIP_DCD_HEADER_COMPLETE 0x900DD009 +#define SDP_ERROR_IMXHEADER0x000a0533 + +#define SDP_COMMAND_LEN16 + +struct sdp_command { + u16 cmd; + u32 addr; + u8 format; + u32 cnt; + u32 data; + u8 rsvd; +} __packed; + +enum sdp_state { + SDP_STATE_IDLE, + SDP_STATE_RX_DCD_DATA, + SDP_STATE_RX_FILE_DATA, + SDP_STATE_TX_SEC_CONF, + SDP_STATE_TX_SEC_CONF_BUSY, + SDP_STATE_TX_REGISTER, + SDP_STATE_TX_REGISTER_BUSY, + SDP_STATE_TX_STATUS, + SDP_STATE_TX_STATUS_BUSY, + SDP_STATE_JUMP, +}; + +struct f_sdp { + struct usb_function usb_function; + + struct usb_descriptor_header**function; + + u8 altsetting; + enum sdp_state state; + enum sdp_state next_state; + u32 dnl_address; + u32 dnl_bytes_remaining; + u32 jmp_address; + boolalways_send_status; + u32 error_stat
Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver
Hi, On Fri, 4 Aug 2017 16:38:08 -0700 Stefan Agner wrote: > From: Stefan Agner > > Add SDP (Serial Downloader Protocol) implementation for U-Boot. The > protocol is used in NXP SoC's boot ROM and allows to download program > images. Beside that, it can also be used to read/write registers and > download complete Device Configuration Data (DCD) sets. This basic > implementation supports downloading images with the imx header format > and reading registers. > > Signed-off-by: Stefan Agner > --- > > drivers/usb/gadget/Kconfig | 7 + > drivers/usb/gadget/Makefile | 1 + > drivers/usb/gadget/f_sdp.c | 723 > > include/sdp.h | 16 + > 4 files changed, 747 insertions(+) > create mode 100644 drivers/usb/gadget/f_sdp.c > create mode 100644 include/sdp.h > > diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig > index 261ed128ac..225b66bc95 100644 > --- a/drivers/usb/gadget/Kconfig > +++ b/drivers/usb/gadget/Kconfig > @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD > > if USB_GADGET_DOWNLOAD > > +config USB_FUNCTION_SDP > + bool "Enable USB SDP (Serial Download Protocol)" > + help > + Enable Serial Download Protocol (SDP) device support in U-Boot. This > + allows to download images into memory and execute (jump to) them > + using the same protocol as implemented by the i.MX family's boot ROM. > + > config G_DNL_MANUFACTURER > string "Vendor name of USB device" > > diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile > index 5e316a7cff..6a007d1bcb 100644 > --- a/drivers/usb/gadget/Makefile > +++ b/drivers/usb/gadget/Makefile > @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o > obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o > obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o > obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o > +obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o > endif > endif > ifdef CONFIG_USB_ETHER > diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c > new file mode 100644 > index 00..eb89695aaf > --- /dev/null > +++ b/drivers/usb/gadget/f_sdp.c > @@ -0,0 +1,723 @@ > +/* > + * f_sdp.c -- USB HID Serial Download Protocol > + * > + * Copyright (C) 2016 Toradex > + * Author: Stefan Agner > + * > + * This file implements the Serial Download Protocol (SDP) as specified in > + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and > + * allows to download images directly to memory. The implementation > + * works with the imx_loader (imx_usb) USB client software on host side. > + * > + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and > + * SKIP_DCD_HEADER are only stubs. > + * > + * Parts of the implementation are based on f_dfu and f_thor. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#define HID_REPORT_ID_MASK 0x00ff > + > +/* > + * HID class requests > + */ > +#define HID_REQ_GET_REPORT 0x01 > +#define HID_REQ_GET_IDLE 0x02 > +#define HID_REQ_GET_PROTOCOL 0x03 > +#define HID_REQ_SET_REPORT 0x09 > +#define HID_REQ_SET_IDLE 0x0A > +#define HID_REQ_SET_PROTOCOL 0x0B > + > +#define HID_USAGE_PAGE_LEN 76 > + > +struct hid_report { > + u8 usage_page[HID_USAGE_PAGE_LEN]; > +} __packed; > + > +#define SDP_READ_REGISTER0x0101 > +#define SDP_WRITE_REGISTER 0x0202 > +#define SDP_WRITE_FILE 0x0404 > +#define SDP_ERROR_STATUS 0x0505 > +#define SDP_DCD_WRITE0x0a0a > +#define SDP_JUMP_ADDRESS 0x0b0b > +#define SDP_SKIP_DCD_HEADER 0x0c0c > + > +#define SDP_WRITE_FILE_COMPLETE 0x > +#define SDP_WRITE_REGISTER_COMPLETE 0x128A8A12 > +#define SDP_SKIP_DCD_HEADER_COMPLETE 0x900DD009 > +#define SDP_ERROR_IMXHEADER 0x000a0533 > + > +#define SDP_COMMAND_LEN 16 > + > +struct sdp_command { > + u16 cmd; > + u32 addr; > + u8 format; > + u32 cnt; > + u32 data; > + u8 rsvd; > +} __packed; > + > +enum sdp_state { > + SDP_STATE_IDLE, > + SDP_STATE_RX_DCD_DATA, > + SDP_STATE_RX_FILE_DATA, > + SDP_STATE_TX_SEC_CONF, > + SDP_STATE_TX_SEC_CONF_BUSY, > + SDP_STATE_TX_REGISTER, > + SDP_STATE_TX_REGISTER_BUSY, > + SDP_STATE_TX_STATUS, > + SDP_STATE_TX_STATUS_BUSY, > + SDP_STATE_JUMP, > +}; > + > +struct f_sdp { > + struct usb_function usb_function; > + > + struct usb_descriptor_header**function; > + > + u8 altsetting; > + enum sdp_state state; > + enum sdp_state next_state; > + u32 dnl_address; > + u32 dnl_bytes_remaining; > + u32
[U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver
From: Stefan Agner Add SDP (Serial Downloader Protocol) implementation for U-Boot. The protocol is used in NXP SoC's boot ROM and allows to download program images. Beside that, it can also be used to read/write registers and download complete Device Configuration Data (DCD) sets. This basic implementation supports downloading images with the imx header format and reading registers. Signed-off-by: Stefan Agner --- drivers/usb/gadget/Kconfig | 7 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_sdp.c | 723 include/sdp.h | 16 + 4 files changed, 747 insertions(+) create mode 100644 drivers/usb/gadget/f_sdp.c create mode 100644 include/sdp.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 261ed128ac..225b66bc95 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD if USB_GADGET_DOWNLOAD +config USB_FUNCTION_SDP + bool "Enable USB SDP (Serial Download Protocol)" + help + Enable Serial Download Protocol (SDP) device support in U-Boot. This + allows to download images into memory and execute (jump to) them + using the same protocol as implemented by the i.MX family's boot ROM. + config G_DNL_MANUFACTURER string "Vendor name of USB device" diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 5e316a7cff..6a007d1bcb 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o endif endif ifdef CONFIG_USB_ETHER diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c new file mode 100644 index 00..eb89695aaf --- /dev/null +++ b/drivers/usb/gadget/f_sdp.c @@ -0,0 +1,723 @@ +/* + * f_sdp.c -- USB HID Serial Download Protocol + * + * Copyright (C) 2016 Toradex + * Author: Stefan Agner + * + * This file implements the Serial Download Protocol (SDP) as specified in + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and + * allows to download images directly to memory. The implementation + * works with the imx_loader (imx_usb) USB client software on host side. + * + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and + * SKIP_DCD_HEADER are only stubs. + * + * Parts of the implementation are based on f_dfu and f_thor. + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define HID_REPORT_ID_MASK 0x00ff + +/* + * HID class requests + */ +#define HID_REQ_GET_REPORT 0x01 +#define HID_REQ_GET_IDLE 0x02 +#define HID_REQ_GET_PROTOCOL 0x03 +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_SET_PROTOCOL 0x0B + +#define HID_USAGE_PAGE_LEN 76 + +struct hid_report { + u8 usage_page[HID_USAGE_PAGE_LEN]; +} __packed; + +#define SDP_READ_REGISTER 0x0101 +#define SDP_WRITE_REGISTER 0x0202 +#define SDP_WRITE_FILE 0x0404 +#define SDP_ERROR_STATUS 0x0505 +#define SDP_DCD_WRITE 0x0a0a +#define SDP_JUMP_ADDRESS 0x0b0b +#define SDP_SKIP_DCD_HEADER0x0c0c + +#define SDP_WRITE_FILE_COMPLETE0x +#define SDP_WRITE_REGISTER_COMPLETE0x128A8A12 +#define SDP_SKIP_DCD_HEADER_COMPLETE 0x900DD009 +#define SDP_ERROR_IMXHEADER0x000a0533 + +#define SDP_COMMAND_LEN16 + +struct sdp_command { + u16 cmd; + u32 addr; + u8 format; + u32 cnt; + u32 data; + u8 rsvd; +} __packed; + +enum sdp_state { + SDP_STATE_IDLE, + SDP_STATE_RX_DCD_DATA, + SDP_STATE_RX_FILE_DATA, + SDP_STATE_TX_SEC_CONF, + SDP_STATE_TX_SEC_CONF_BUSY, + SDP_STATE_TX_REGISTER, + SDP_STATE_TX_REGISTER_BUSY, + SDP_STATE_TX_STATUS, + SDP_STATE_TX_STATUS_BUSY, + SDP_STATE_JUMP, +}; + +struct f_sdp { + struct usb_function usb_function; + + struct usb_descriptor_header**function; + + u8 altsetting; + enum sdp_state state; + enum sdp_state next_state; + u32 dnl_address; + u32 dnl_bytes_remaining; + u32 jmp_address; + boolalways_send_status; + u32 error_status; + + /* EP0 request */ + struct usb_request *req; + + /* EP1 IN */ + struct usb_ep *in_ep; +