diff options
Diffstat (limited to 'package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch')
-rw-r--r-- | package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch | 916 |
1 files changed, 916 insertions, 0 deletions
diff --git a/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch new file mode 100644 index 000000000..feaf297b7 --- /dev/null +++ b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch @@ -0,0 +1,916 @@ +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 + |