123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916 |
- From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001
- From: Xiangfu <xiangfu@openmobilefree.net>
- Date: Fri, 12 Oct 2012 09:47:39 +0800
- Subject: [PATCH 2/6] qi_lb60: add software usbboot support
- JZ4740 CPU have a internal ROM have such kind of code, that make
- JZ4740 can boot from USB
- usbboot.S can downloads user program from the USB port to internal
- SRAM and branches to the internal SRAM to execute the program
- Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
- ---
- board/qi/qi_lb60/Makefile | 1 +
- board/qi/qi_lb60/qi_lb60-spl.c | 20 +
- board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 859 insertions(+)
- create mode 100644 board/qi/qi_lb60/usbboot.S
- diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
- index e399246..6dd8c6f 100644
- --- a/board/qi/qi_lb60/Makefile
- +++ b/board/qi/qi_lb60/Makefile
- @@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk
- LIB = $(obj)lib$(BOARD).o
-
- ifeq ($(CONFIG_SPL_BUILD),y)
- +SOBJS := usbboot.o
- COBJS := $(BOARD)-spl.o
- else
- COBJS := $(BOARD).o
- diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
- index 3fe3fa3..aea459c 100644
- --- a/board/qi/qi_lb60/qi_lb60-spl.c
- +++ b/board/qi/qi_lb60/qi_lb60-spl.c
- @@ -12,6 +12,24 @@
- #include <asm/io.h>
- #include <asm/jz4740.h>
-
- +#define KEY_U_OUT (32 * 2 + 16)
- +#define KEY_U_IN (32 * 3 + 19)
- +
- +extern void usb_boot(void);
- +
- +static void check_usb_boot(void)
- +{
- + __gpio_as_input(KEY_U_IN);
- + __gpio_enable_pull(KEY_U_IN);
- + __gpio_as_output(KEY_U_OUT);
- + __gpio_clear_pin(KEY_U_OUT);
- +
- + if (!__gpio_get_pin(KEY_U_IN)) {
- + puts("[U] pressed, goto USBBOOT mode\n");
- + usb_boot();
- + }
- +}
- +
- void nand_spl_boot(void)
- {
- __gpio_as_sdram_16bit_4720();
- @@ -23,6 +41,8 @@ void nand_spl_boot(void)
- pll_init();
- sdram_init();
-
- + check_usb_boot();
- +
- nand_init();
-
- puts("\nQi LB60 SPL: Starting U-Boot ...\n");
- diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S
- new file mode 100644
- index 0000000..c872266
- --- /dev/null
- +++ b/board/qi/qi_lb60/usbboot.S
- @@ -0,0 +1,838 @@
- +/*
- + * for jz4740 usb boot
- + *
- + * Copyright (c) 2009 Author: <jlwei@ingenic.cn>
- + *
- + * See file CREDITS for list of people who contributed to this
- + * project.
- + *
- + * 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
- + */
- + .set noreorder
- + .globl usb_boot
- + .text
- +
- +/*
- + * Both NAND and USB boot load data to D-Cache first, then transfer
- + * data from D-Cache to I-Cache, and jump to execute the code in I-Cache.
- + * So init caches first and then dispatch to a proper boot routine.
- + */
- +
- +.macro load_addr reg addr
- + li \reg, 0x80000000
- + addiu \reg, \reg, \addr
- + la $2, usbboot_begin
- + subu \reg, \reg, $2
- +.endm
- +
- +usb_boot:
- + /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */
- + la $9, 0xB0000000 /* CPCCR: Clock Control Register */
- + la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */
- + sw $8, 0($9)
- +
- + la $9, 0xB0000010 /* CPPCR: PLL Control Register */
- + la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */
- + sw $8, 0($9)
- +
- + mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */
- + nop
- +
- + mtc0 $0, $16 /* CP0_CONFIG */
- + nop
- +
- + /* Relocate code to beginning of the ram */
- +
- + la $2, usbboot_begin
- + la $3, usbboot_end
- + li $4, 0x80000000
- +
- +1:
- + lw $5, 0($2)
- + sw $5, 0($4)
- + addiu $2, $2, 4
- + bne $2, $3, 1b
- + addiu $4, $4, 4
- +
- + li $2, 0x80000000
- + ori $3, $2, 0
- + addiu $3, $3, usbboot_end
- + la $4, usbboot_begin
- + subu $3, $3, $4
- +
- +
- +2:
- + cache 0x0, 0($2) /* Index_Invalidate_I */
- + cache 0x1, 0($2) /* Index_Writeback_Inv_D */
- + addiu $2, $2, 32
- + subu $4, $3, $2
- + bgtz $4, 2b
- + nop
- +
- + load_addr $3, usb_boot_return
- +
- + jr $3
- +
- +usbboot_begin:
- +
- +init_caches:
- + li $2, 3 /* cacheable for kseg0 access */
- + mtc0 $2, $16 /* CP0_CONFIG */
- + nop
- +
- + li $2, 0x20000000 /* enable idx-store-data cache insn */
- + mtc0 $2, $26 /* CP0_ERRCTL */
- +
- + ori $2, $28, 0 /* start address */
- + ori $3, $2, 0x3fe0 /* end address, total 16KB */
- + mtc0 $0, $28, 0 /* CP0_TAGLO */
- + mtc0 $0, $28, 1 /* CP0_DATALO */
- +cache_clear_a_line:
- + cache 0x8, 0($2) /* Index_Store_Tag_I */
- + cache 0x9, 0($2) /* Index_Store_Tag_D */
- + bne $2, $3, cache_clear_a_line
- + addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
- +
- + ori $2, $28, 0 /* start address */
- + ori $3, $2, 0x3fe0 /* end address, total 16KB */
- + la $4, 0x1ffff000 /* physical address and 4KB page mask */
- +cache_alloc_a_line:
- + and $5, $2, $4
- + ori $5, $5, 1 /* V bit of the physical tag */
- + mtc0 $5, $28, 0 /* CP0_TAGLO */
- + cache 0x8, 0($2) /* Index_Store_Tag_I */
- + cache 0x9, 0($2) /* Index_Store_Tag_D */
- + bne $2, $3, cache_alloc_a_line
- + addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
- +
- + nop
- + nop
- + nop
- + /*
- + * Transfer data from dcache to icache, then jump to icache.
- + * Input parameters:
- + * $19: data length in bytes
- + * $20: jump target address
- + */
- +xfer_d2i:
- +
- + ori $8, $20, 0
- + addu $9, $8, $19 /* total 16KB */
- +
- +1:
- + cache 0x0, 0($8) /* Index_Invalidate_I */
- + cache 0x1, 0($8) /* Index_Writeback_Inv_D */
- + bne $8, $9, 1b
- + addiu $8, $8, 32
- +
- + /* flush write-buffer */
- + sync
- +
- + /* Invalidate BTB */
- + mfc0 $8, $16, 7 /* CP0_CONFIG */
- + nop
- + ori $8, 2
- + mtc0 $8, $16, 7
- + nop
- +
- + /* Overwrite config to disable ram initalisation */
- + li $2, 0xff
- + sb $2, 20($20)
- +
- + jalr $20
- + nop
- +
- +icache_return:
- + /* User code can return to here after executing itself in
- + icache, by jumping to $31. */
- + b usb_boot_return
- + nop
- +
- +
- +usb_boot_return:
- + /* Enable the USB PHY */
- + la $9, 0xB0000024 /* CPM_SCR */
- + lw $8, 0($9)
- + ori $8, 0x40 /* USBPHY_ENABLE */
- + sw $8, 0($9)
- +
- + /* Initialize USB registers */
- + la $27, 0xb3040000 /* USB registers base address */
- +
- + sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */
- + sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */
- + sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */
- +
- + li $9, 0x61
- + sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */
- +
- + /* Initialize USB states */
- + li $22, 0 /* set EP0 to IDLE state */
- + li $23, 1 /* no data stage */
- +
- + /* Main loop of polling the usb commands */
- +usb_command_loop:
- + lbu $9, 0x0a($27) /* read INTRUSB */
- + andi $9, 0x04 /* check USB_INTR_RESET */
- + beqz $9, check_intr_ep0in
- + nop
- +
- + /* 1. Handle USB reset interrupt */
- +handle_reset_intr:
- + lbu $9, 0x01($27) /* read POWER */
- + andi $9, 0x10 /* test HS_MODE */
- + bnez $9, _usb_set_maxpktsize
- + li $9, 512 /* max packet size of HS mode */
- + li $9, 64 /* max packet size of FS mode */
- +
- +_usb_set_maxpktsize:
- + li $8, 1
- + sb $8, 0x0e($27) /* set INDEX 1 */
- +
- + sh $9, 0x10($27) /* INMAXP */
- + sb $0, 0x13($27) /* INCSRH */
- + sh $9, 0x14($27) /* OUTMAXP */
- + sb $0, 0x17($27) /* OUTCSRH */
- +
- +_usb_flush_fifo:
- + li $8, 0x48 /* INCSR_CDT && INCSR_FF */
- + sb $8, 0x12($27) /* INCSR */
- + li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */
- + sb $8, 0x16($27) /* OUTCSR */
- +
- + li $22, 0 /* set EP0 to IDLE state */
- + li $23, 1 /* no data stage */
- +
- + /* 2. Check and handle EP0 interrupt */
- +check_intr_ep0in:
- + lhu $10, 0x02($27) /* read INTRIN */
- + andi $9, $10, 0x1 /* check EP0 interrupt */
- + beqz $9, check_intr_ep1in
- + nop
- +
- +handle_ep0_intr:
- + sb $0, 0x0e($27) /* set INDEX 0 */
- + lbu $11, 0x12($27) /* read CSR0 */
- +
- + andi $9, $11, 0x04 /* check SENTSTALL */
- + beqz $9, _ep0_setupend
- + nop
- +
- +_ep0_sentstall:
- + andi $9, $11, 0xdb
- + sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */
- + li $22, 0 /* set EP0 to IDLE state */
- +
- +_ep0_setupend:
- + andi $9, $11, 0x10 /* check SETUPEND */
- + beqz $9, ep0_idle_state
- + nop
- +
- + ori $9, $11, 0x80
- + sb $9, 0x12($27) /* set SVDSETUPEND */
- + li $22, 0 /* set EP0 to IDLE state */
- +
- +ep0_idle_state:
- + bnez $22, ep0_tx_state
- + nop
- +
- + /* 2.1 Handle EP0 IDLE state interrupt */
- + andi $9, $11, 0x01 /* check OUTPKTRDY */
- + beqz $9, check_intr_ep1in
- + nop
- +
- + /* Read 8-bytes setup packet from the FIFO */
- + lw $25, 0x20($27) /* first word of setup packet */
- + lw $26, 0x20($27) /* second word of setup packet */
- +
- + andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */
- + beqz $9, _ep0_std_req
- + nop
- +
- + /* 2.1.1 Vendor-specific setup request */
- +_ep0_vend_req:
- + li $22, 0 /* set EP0 to IDLE state */
- + li $23, 1 /* NoData = 1 */
- +
- + andi $9, $25, 0xff00 /* check bRequest */
- + srl $9, $9, 8
- + beqz $9, __ep0_get_cpu_info
- + sub $8, $9, 0x1
- + beqz $8, __ep0_set_data_address
- + sub $8, $9, 0x2
- + beqz $8, __ep0_set_data_length
- + sub $8, $9, 0x3
- + beqz $8, __ep0_flush_caches
- + sub $8, $9, 0x4
- + beqz $8, __ep0_prog_start1
- + sub $8, $9, 0x5
- + beqz $8, __ep0_prog_start2
- + nop
- + b _ep0_idle_state_fini /* invalid request */
- + nop
- +
- +__ep0_get_cpu_info:
- + load_addr $20, cpu_info_data /* data pointer to transfer */
- + li $21, 8 /* bytes left to transfer */
- + li $22, 1 /* set EP0 to TX state */
- + li $23, 0 /* NoData = 0 */
- +
- + b _ep0_idle_state_fini
- + nop
- +
- +__ep0_set_data_address:
- + li $9, 0xffff0000
- + and $9, $25, $9
- + andi $8, $26, 0xffff
- + or $20, $9, $8 /* data address of next transfer */
- +
- + b _ep0_idle_state_fini
- + nop
- +
- +__ep0_set_data_length:
- + li $9, 0xffff0000
- + and $9, $25, $9
- + andi $8, $26, 0xffff
- + or $21, $9, $8 /* data length of next transfer */
- +
- + li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
- + sb $9, 0x12($27) /* CSR0 */
- +
- + /* We must write packet to FIFO before EP1-IN interrupt here. */
- + b handle_epin1_intr
- + nop
- +
- +__ep0_flush_caches:
- + /* Flush dcache and invalidate icache. */
- + li $8, 0x80000000
- + addi $9, $8, 0x3fe0 /* total 16KB */
- +
- +1:
- + cache 0x0, 0($8) /* Index_Invalidate_I */
- + cache 0x1, 0($8) /* Index_Writeback_Inv_D */
- + bne $8, $9, 1b
- + addiu $8, $8, 32
- +
- + /* flush write-buffer */
- + sync
- +
- + /* Invalidate BTB */
- + mfc0 $8, $16, 7 /* CP0_CONFIG */
- + nop
- + ori $8, 2
- + mtc0 $8, $16, 7
- + nop
- +
- + b _ep0_idle_state_fini
- + nop
- +
- +__ep0_prog_start1:
- + li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
- + sb $9, 0x12($27) /* CSR0 */
- +
- + li $9, 0xffff0000
- + and $9, $25, $9
- + andi $8, $26, 0xffff
- + or $20, $9, $8 /* target address */
- +
- + b xfer_d2i
- + li $19, 0x2000 /* 16KB data length */
- +
- +__ep0_prog_start2:
- + li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
- + sb $9, 0x12($27) /* CSR0 */
- +
- + li $9, 0xffff0000
- + and $9, $25, $9
- + andi $8, $26, 0xffff
- + or $20, $9, $8 /* target address */
- +
- + jalr $20 /* jump, and place the return address in $31 */
- + nop
- +
- +__ep0_prog_start2_return:
- +/* User code can return to here after executing itself, by jumping to $31 */
- + b usb_boot_return
- + nop
- +
- + /* 2.1.2 Standard setup request */
- +_ep0_std_req:
- + andi $12, $25, 0xff00 /* check bRequest */
- + srl $12, $12, 8
- + sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */
- + bnez $9, __ep0_req_set_config
- + nop
- +
- + /* Handle USB_REQ_SET_ADDRESS */
- +__ep0_req_set_addr:
- + srl $9, $25, 16 /* get wValue */
- + sb $9, 0x0($27) /* set FADDR */
- + li $23, 1 /* NoData = 1 */
- + b _ep0_idle_state_fini
- + nop
- +
- +__ep0_req_set_config:
- + sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */
- + bnez $9, __ep0_req_get_desc
- + nop
- +
- + /* Handle USB_REQ_SET_CONFIGURATION */
- + li $23, 1 /* NoData = 1 */
- + b _ep0_idle_state_fini
- + nop
- +
- +__ep0_req_get_desc:
- + sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */
- + bnez $9, _ep0_idle_state_fini
- + li $23, 1 /* NoData = 1 */
- +
- + /* Handle USB_REQ_GET_DESCRIPTOR */
- + li $23, 0 /* NoData = 0 */
- +
- + srl $9, $25, 24 /* wValue >> 8 */
- + sub $8, $9, 0x01 /* check USB_DT_DEVICE */
- + beqz $8, ___ep0_get_dev_desc
- + srl $21, $26, 16 /* get wLength */
- + sub $8, $9, 0x02 /* check USB_DT_CONFIG */
- + beqz $8, ___ep0_get_conf_desc
- + sub $8, $9, 0x03 /* check USB_DT_STRING */
- + beqz $8, ___ep0_get_string_desc
- + sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */
- + beqz $8, ___ep0_get_dev_qualifier
- + nop
- + b _ep0_idle_state_fini
- + nop
- +
- +___ep0_get_dev_desc:
- + load_addr $20, device_desc /* data pointer */
- + li $22, 1 /* set EP0 to TX state */
- + sub $8, $21, 18
- + blez $8, _ep0_idle_state_fini /* wLength <= 18 */
- + nop
- + li $21, 18 /* max length of device_desc */
- + b _ep0_idle_state_fini
- + nop
- +
- +___ep0_get_dev_qualifier:
- + load_addr $20, dev_qualifier /* data pointer */
- + li $22, 1 /* set EP0 to TX state */
- + sub $8, $21, 10
- + blez $8, _ep0_idle_state_fini /* wLength <= 10 */
- + nop
- + li $21, 10 /* max length of dev_qualifier */
- + b _ep0_idle_state_fini
- + nop
- +
- +___ep0_get_conf_desc:
- + load_addr $20, config_desc_fs /* data pointer of FS mode */
- + lbu $8, 0x01($27) /* read POWER */
- + andi $8, 0x10 /* test HS_MODE */
- + beqz $8, ___ep0_get_conf_desc2
- + nop
- + load_addr $20, config_desc_hs /* data pointer of HS mode */
- +
- +___ep0_get_conf_desc2:
- + li $22, 1 /* set EP0 to TX state */
- + sub $8, $21, 32
- + blez $8, _ep0_idle_state_fini /* wLength <= 32 */
- + nop
- + li $21, 32 /* max length of config_desc */
- + b _ep0_idle_state_fini
- + nop
- +
- +___ep0_get_string_desc:
- + li $22, 1 /* set EP0 to TX state */
- +
- + srl $9, $25, 16 /* wValue & 0xff */
- + andi $9, 0xff
- +
- + sub $8, $9, 1
- + beqz $8, ___ep0_get_string_manufacture
- + sub $8, $9, 2
- + beqz $8, ___ep0_get_string_product
- + nop
- +
- +___ep0_get_string_lang_ids:
- + load_addr $20, string_lang_ids /* data pointer */
- + b _ep0_idle_state_fini
- + li $21, 4 /* data length */
- +
- +___ep0_get_string_manufacture:
- + load_addr $20, string_manufacture /* data pointer */
- + b _ep0_idle_state_fini
- + li $21, 16 /* data length */
- +
- +___ep0_get_string_product:
- + load_addr $20, string_product /* data pointer */
- + b _ep0_idle_state_fini
- + li $21, 46 /* data length */
- +
- +_ep0_idle_state_fini:
- + li $9, 0x40 /* SVDOUTPKTRDY */
- + beqz $23, _ep0_idle_state_fini2
- + nop
- + ori $9, $9, 0x08 /* DATAEND */
- +_ep0_idle_state_fini2:
- + sb $9, 0x12($27) /* CSR0 */
- + beqz $22, check_intr_ep1in
- + nop
- +
- + /* 2.2 Handle EP0 TX state interrupt */
- +ep0_tx_state:
- + sub $9, $22, 1
- + bnez $9, check_intr_ep1in
- + nop
- +
- + sub $9, $21, 64 /* max packetsize */
- + blez $9, _ep0_tx_state2 /* data count <= 64 */
- + ori $19, $21, 0
- + li $19, 64
- +
- +_ep0_tx_state2:
- + beqz $19, _ep0_tx_state3 /* send ZLP */
- + ori $18, $19, 0 /* record bytes to be transferred */
- + sub $21, $21, $19 /* decrement data count */
- +
- +_ep0_fifo_write_loop:
- + lbu $9, 0($20) /* read data */
- + sb $9, 0x20($27) /* load FIFO */
- + sub $19, $19, 1 /* decrement counter */
- + bnez $19, _ep0_fifo_write_loop
- + addi $20, $20, 1 /* increment data pointer */
- +
- + sub $9, $18, 64 /* max packetsize */
- + beqz $9, _ep0_tx_state4
- + nop
- +
- +_ep0_tx_state3:
- + /* transferred bytes < max packetsize */
- + li $9, 0x0a /* set INPKTRDY and DATAEND */
- + sb $9, 0x12($27) /* CSR0 */
- + li $22, 0 /* set EP0 to IDLE state */
- + b check_intr_ep1in
- + nop
- +
- +_ep0_tx_state4:
- + /* transferred bytes == max packetsize */
- + li $9, 0x02 /* set INPKTRDY */
- + sb $9, 0x12($27) /* CSR0 */
- + b check_intr_ep1in
- + nop
- +
- + /* 3. Check and handle EP1 BULK-IN interrupt */
- +check_intr_ep1in:
- + andi $9, $10, 0x2 /* check EP1 IN interrupt */
- + beqz $9, check_intr_ep1out
- + nop
- +
- +handle_epin1_intr:
- + li $9, 1
- + sb $9, 0x0e($27) /* set INDEX 1 */
- + lbu $9, 0x12($27) /* read INCSR */
- +
- + andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */
- + bnez $8, _epin1_tx_state4
- + nop
- +
- +_epin1_write_fifo:
- + lhu $9, 0x10($27) /* get INMAXP */
- + sub $8, $21, $9
- + blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */
- + ori $19, $21, 0
- + ori $19, $9, 0
- +
- +_epin1_tx_state1:
- + beqz $19, _epin1_tx_state4 /* No data */
- + nop
- +
- + sub $21, $21, $19 /* decrement data count */
- +
- + srl $5, $19, 2 /* # of word */
- + andi $6, $19, 0x3 /* # of byte */
- + beqz $5, _epin1_tx_state2
- + nop
- +
- +_epin1_fifo_write_word:
- + lw $9, 0($20) /* read data from source address */
- + sw $9, 0x24($27) /* write FIFO */
- + sub $5, $5, 1 /* decrement counter */
- + bnez $5, _epin1_fifo_write_word
- + addiu $20, $20, 4 /* increment dest address */
- +
- +_epin1_tx_state2:
- + beqz $6, _epin1_tx_state3
- + nop
- +
- +_epin1_fifo_write_byte:
- + lbu $9, 0($20) /* read data from source address */
- + sb $9, 0x24($27) /* write FIFO */
- + sub $6, $6, 1 /* decrement counter */
- + bnez $6, _epin1_fifo_write_byte
- + addiu $20, $20, 1 /* increment dest address */
- +
- +_epin1_tx_state3:
- + li $9, 0x1
- + sb $9, 0x12($27) /* INCSR, set INPKTRDY */
- +
- +_epin1_tx_state4:
- + /* 4. Check and handle EP1 BULK-OUT interrupt */
- +check_intr_ep1out:
- + lhu $9, 0x04($27) /* read INTROUT */
- + andi $9, 0x2
- + beqz $9, check_status_next
- + nop
- +
- +handle_epout1_intr:
- + li $9, 1
- + sb $9, 0x0e($27) /* set INDEX 1 */
- +
- + lbu $9, 0x16($27) /* read OUTCSR */
- + andi $9, 0x1 /* check OUTPKTRDY */
- + beqz $9, check_status_next
- + nop
- +
- +_epout1_read_fifo:
- + lhu $19, 0x18($27) /* read OUTCOUNT */
- + srl $5, $19, 2 /* # of word */
- + andi $6, $19, 0x3 /* # of byte */
- + beqz $5, _epout1_rx_state1
- + nop
- +
- +_epout1_fifo_read_word:
- + lw $9, 0x24($27) /* read FIFO */
- + sw $9, 0($20) /* store to dest address */
- + sub $5, $5, 1 /* decrement counter */
- + bnez $5, _epout1_fifo_read_word
- + addiu $20, $20, 4 /* increment dest address */
- +
- +_epout1_rx_state1:
- + beqz $6, _epout1_rx_state2
- + nop
- +
- +_epout1_fifo_read_byte:
- + lbu $9, 0x24($27) /* read FIFO */
- + sb $9, 0($20) /* store to dest address */
- + sub $6, $6, 1 /* decrement counter */
- + bnez $6, _epout1_fifo_read_byte
- + addiu $20, $20, 1 /* increment dest address */
- +
- +_epout1_rx_state2:
- + sb $0, 0x16($27) /* clear OUTPKTRDY */
- +
- +check_status_next:
- + b usb_command_loop
- + nop
- +
- +/* Device/Configuration/Interface/Endpoint/String Descriptors */
- +
- + .align 2
- +device_desc:
- + .byte 0x12 /* bLength */
- + .byte 0x01 /* bDescriptorType */
- + .byte 0x00 /* bcdUSB */
- + .byte 0x02 /* bcdUSB */
- + .byte 0x00 /* bDeviceClass */
- + .byte 0x00 /* bDeviceSubClass */
- + .byte 0x00 /* bDeviceProtocol */
- + .byte 0x40 /* bMaxPacketSize0 */
- + .byte 0x1a /* idVendor */
- + .byte 0x60 /* idVendor */
- + .byte 0x40 /* idProduct */
- + .byte 0x47 /* idProduct */
- + .byte 0x00 /* bcdDevice */
- + .byte 0x01 /* bcdDevice */
- + .byte 0x01 /* iManufacturer */
- + .byte 0x02 /* iProduct */
- + .byte 0x00 /* iSerialNumber */
- + .byte 0x01 /* bNumConfigurations */
- +
- + .align 2
- +dev_qualifier:
- + .byte 0x0a /* bLength */
- + .byte 0x06 /* bDescriptorType */
- + .byte 0x00 /* bcdUSB */
- + .byte 0x02 /* bcdUSB */
- + .byte 0x00 /* bDeviceClass */
- + .byte 0x00 /* bDeviceSubClass */
- + .byte 0x00 /* bDeviceProtocol */
- + .byte 0x40 /* bMaxPacketSize0 */
- + .byte 0x01 /* bNumConfigurations */
- + .byte 0x00 /* bRESERVED */
- +
- + .align 2
- +config_desc_hs:
- + .byte 0x09 /* bLength */
- + .byte 0x02 /* bDescriptorType */
- + .byte 0x20 /* wTotalLength */
- + .byte 0x00 /* wTotalLength */
- + .byte 0x01 /* bNumInterfaces */
- + .byte 0x01 /* bConfigurationValue */
- + .byte 0x00 /* iConfiguration */
- + .byte 0xc0 /* bmAttributes */
- + .byte 0x01 /* MaxPower */
- +intf_desc_hs:
- + .byte 0x09 /* bLength */
- + .byte 0x04 /* bDescriptorType */
- + .byte 0x00 /* bInterfaceNumber */
- + .byte 0x00 /* bAlternateSetting */
- + .byte 0x02 /* bNumEndpoints */
- + .byte 0xff /* bInterfaceClass */
- + .byte 0x00 /* bInterfaceSubClass */
- + .byte 0x50 /* bInterfaceProtocol */
- + .byte 0x00 /* iInterface */
- +ep1_desc_hs:
- + .byte 0x07 /* bLength */
- + .byte 0x05 /* bDescriptorType */
- + .byte 0x01 /* bEndpointAddress */
- + .byte 0x02 /* bmAttributes */
- + .byte 0x00 /* wMaxPacketSize */
- + .byte 0x02 /* wMaxPacketSize */
- + .byte 0x00 /* bInterval */
- +ep2_desc_hs:
- + .byte 0x07 /* bLength */
- + .byte 0x05 /* bDescriptorType */
- + .byte 0x81 /* bEndpointAddress */
- + .byte 0x02 /* bmAttributes */
- + .byte 0x00 /* wMaxPacketSize */
- + .byte 0x02 /* wMaxPacketSize */
- + .byte 0x00 /* bInterval */
- +
- + .align 2
- +config_desc_fs:
- + .byte 0x09 /* bLength */
- + .byte 0x02 /* bDescriptorType */
- + .byte 0x20 /* wTotalLength */
- + .byte 0x00 /* wTotalLength */
- + .byte 0x01 /* bNumInterfaces */
- + .byte 0x01 /* bConfigurationValue */
- + .byte 0x00 /* iConfiguration */
- + .byte 0xc0 /* bmAttributes */
- + .byte 0x01 /* MaxPower */
- +intf_desc_fs:
- + .byte 0x09 /* bLength */
- + .byte 0x04 /* bDescriptorType */
- + .byte 0x00 /* bInterfaceNumber */
- + .byte 0x00 /* bAlternateSetting */
- + .byte 0x02 /* bNumEndpoints */
- + .byte 0xff /* bInterfaceClass */
- + .byte 0x00 /* bInterfaceSubClass */
- + .byte 0x50 /* bInterfaceProtocol */
- + .byte 0x00 /* iInterface */
- +ep1_desc_fs:
- + .byte 0x07 /* bLength */
- + .byte 0x05 /* bDescriptorType */
- + .byte 0x01 /* bEndpointAddress */
- + .byte 0x02 /* bmAttributes */
- + .byte 0x40 /* wMaxPacketSize */
- + .byte 0x00 /* wMaxPacketSize */
- + .byte 0x00 /* bInterval */
- +ep2_desc_fs:
- + .byte 0x07 /* bLength */
- + .byte 0x05 /* bDescriptorType */
- + .byte 0x81 /* bEndpointAddress */
- + .byte 0x02 /* bmAttributes */
- + .byte 0x40 /* wMaxPacketSize */
- + .byte 0x00 /* wMaxPacketSize */
- + .byte 0x00 /* bInterval */
- +
- + .align 2
- +string_lang_ids:
- + .byte 0x04
- + .byte 0x03
- + .byte 0x09
- + .byte 0x04
- +
- + .align 2
- +string_manufacture:
- + .byte 0x10
- + .byte 0x03
- + .byte 0x49
- + .byte 0x00
- + .byte 0x6e
- + .byte 0x00
- + .byte 0x67
- + .byte 0x00
- + .byte 0x65
- + .byte 0x00
- + .byte 0x6e
- + .byte 0x00
- + .byte 0x69
- + .byte 0x00
- + .byte 0x63
- + .byte 0x00
- +
- + .align 2
- +string_product:
- + .byte 0x2e
- + .byte 0x03
- + .byte 0x4a
- + .byte 0x00
- + .byte 0x5a
- + .byte 0x00
- + .byte 0x34
- + .byte 0x00
- + .byte 0x37
- + .byte 0x00
- + .byte 0x34
- + .byte 0x00
- + .byte 0x30
- + .byte 0x00
- + .byte 0x20
- + .byte 0x00
- + .byte 0x55
- + .byte 0x00
- + .byte 0x53
- + .byte 0x00
- + .byte 0x42
- + .byte 0x00
- + .byte 0x20
- + .byte 0x00
- + .byte 0x42
- + .byte 0x00
- + .byte 0x6f
- + .byte 0x00
- + .byte 0x6f
- + .byte 0x00
- + .byte 0x74
- + .byte 0x00
- + .byte 0x20
- + .byte 0x00
- + .byte 0x44
- + .byte 0x00
- + .byte 0x65
- + .byte 0x00
- + .byte 0x76
- + .byte 0x00
- + .byte 0x69
- + .byte 0x00
- + .byte 0x63
- + .byte 0x00
- + .byte 0x65
- + .byte 0x00
- +
- + .align 2
- +cpu_info_data:
- + .byte 0x4a
- + .byte 0x5a
- + .byte 0x34
- + .byte 0x37
- + .byte 0x34
- + .byte 0x30
- + .byte 0x56
- + .byte 0x31
- +usbboot_end:
- +
- + .set reorder
- --
- 1.7.9.5
|