Root/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch

1From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001
2From: Xiangfu <xiangfu@openmobilefree.net>
3Date: Fri, 12 Oct 2012 09:47:39 +0800
4Subject: [PATCH 2/6] qi_lb60: add software usbboot support
5
6  JZ4740 CPU have a internal ROM have such kind of code, that make
7  JZ4740 can boot from USB
8
9  usbboot.S can downloads user program from the USB port to internal
10  SRAM and branches to the internal SRAM to execute the program
11
12Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
13---
14 board/qi/qi_lb60/Makefile | 1 +
15 board/qi/qi_lb60/qi_lb60-spl.c | 20 +
16 board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++
17 3 files changed, 859 insertions(+)
18 create mode 100644 board/qi/qi_lb60/usbboot.S
19
20diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
21index e399246..6dd8c6f 100644
22--- a/board/qi/qi_lb60/Makefile
23+++ b/board/qi/qi_lb60/Makefile
24@@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk
25 LIB = $(obj)lib$(BOARD).o
26 
27 ifeq ($(CONFIG_SPL_BUILD),y)
28+SOBJS := usbboot.o
29 COBJS := $(BOARD)-spl.o
30 else
31 COBJS := $(BOARD).o
32diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
33index 3fe3fa3..aea459c 100644
34--- a/board/qi/qi_lb60/qi_lb60-spl.c
35+++ b/board/qi/qi_lb60/qi_lb60-spl.c
36@@ -12,6 +12,24 @@
37 #include <asm/io.h>
38 #include <asm/jz4740.h>
39 
40+#define KEY_U_OUT (32 * 2 + 16)
41+#define KEY_U_IN (32 * 3 + 19)
42+
43+extern void usb_boot(void);
44+
45+static void check_usb_boot(void)
46+{
47+ __gpio_as_input(KEY_U_IN);
48+ __gpio_enable_pull(KEY_U_IN);
49+ __gpio_as_output(KEY_U_OUT);
50+ __gpio_clear_pin(KEY_U_OUT);
51+
52+ if (!__gpio_get_pin(KEY_U_IN)) {
53+ puts("[U] pressed, goto USBBOOT mode\n");
54+ usb_boot();
55+ }
56+}
57+
58 void nand_spl_boot(void)
59 {
60     __gpio_as_sdram_16bit_4720();
61@@ -23,6 +41,8 @@ void nand_spl_boot(void)
62     pll_init();
63     sdram_init();
64 
65+ check_usb_boot();
66+
67     nand_init();
68 
69     puts("\nQi LB60 SPL: Starting U-Boot ...\n");
70diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S
71new file mode 100644
72index 0000000..c872266
73--- /dev/null
74+++ b/board/qi/qi_lb60/usbboot.S
75@@ -0,0 +1,838 @@
76+/*
77+ * for jz4740 usb boot
78+ *
79+ * Copyright (c) 2009 Author: <jlwei@ingenic.cn>
80+ *
81+ * See file CREDITS for list of people who contributed to this
82+ * project.
83+ *
84+ * This program is free software; you can redistribute it and/or
85+ * modify it under the terms of the GNU General Public License as
86+ * published by the Free Software Foundation; either version 2 of
87+ * the License, or (at your option) any later version.
88+ *
89+ * This program is distributed in the hope that it will be useful,
90+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
91+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
92+ * GNU General Public License for more details.
93+ *
94+ * You should have received a copy of the GNU General Public License
95+ * along with this program; if not, write to the Free Software
96+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
97+ * MA 02111-1307 USA
98+ */
99+ .set noreorder
100+ .globl usb_boot
101+ .text
102+
103+/*
104+ * Both NAND and USB boot load data to D-Cache first, then transfer
105+ * data from D-Cache to I-Cache, and jump to execute the code in I-Cache.
106+ * So init caches first and then dispatch to a proper boot routine.
107+ */
108+
109+.macro load_addr reg addr
110+ li \reg, 0x80000000
111+ addiu \reg, \reg, \addr
112+ la $2, usbboot_begin
113+ subu \reg, \reg, $2
114+.endm
115+
116+usb_boot:
117+ /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */
118+ la $9, 0xB0000000 /* CPCCR: Clock Control Register */
119+ la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */
120+ sw $8, 0($9)
121+
122+ la $9, 0xB0000010 /* CPPCR: PLL Control Register */
123+ la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */
124+ sw $8, 0($9)
125+
126+ mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */
127+ nop
128+
129+ mtc0 $0, $16 /* CP0_CONFIG */
130+ nop
131+
132+ /* Relocate code to beginning of the ram */
133+
134+ la $2, usbboot_begin
135+ la $3, usbboot_end
136+ li $4, 0x80000000
137+
138+1:
139+ lw $5, 0($2)
140+ sw $5, 0($4)
141+ addiu $2, $2, 4
142+ bne $2, $3, 1b
143+ addiu $4, $4, 4
144+
145+ li $2, 0x80000000
146+ ori $3, $2, 0
147+ addiu $3, $3, usbboot_end
148+ la $4, usbboot_begin
149+ subu $3, $3, $4
150+
151+
152+2:
153+ cache 0x0, 0($2) /* Index_Invalidate_I */
154+ cache 0x1, 0($2) /* Index_Writeback_Inv_D */
155+ addiu $2, $2, 32
156+ subu $4, $3, $2
157+ bgtz $4, 2b
158+ nop
159+
160+ load_addr $3, usb_boot_return
161+
162+ jr $3
163+
164+usbboot_begin:
165+
166+init_caches:
167+ li $2, 3 /* cacheable for kseg0 access */
168+ mtc0 $2, $16 /* CP0_CONFIG */
169+ nop
170+
171+ li $2, 0x20000000 /* enable idx-store-data cache insn */
172+ mtc0 $2, $26 /* CP0_ERRCTL */
173+
174+ ori $2, $28, 0 /* start address */
175+ ori $3, $2, 0x3fe0 /* end address, total 16KB */
176+ mtc0 $0, $28, 0 /* CP0_TAGLO */
177+ mtc0 $0, $28, 1 /* CP0_DATALO */
178+cache_clear_a_line:
179+ cache 0x8, 0($2) /* Index_Store_Tag_I */
180+ cache 0x9, 0($2) /* Index_Store_Tag_D */
181+ bne $2, $3, cache_clear_a_line
182+ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
183+
184+ ori $2, $28, 0 /* start address */
185+ ori $3, $2, 0x3fe0 /* end address, total 16KB */
186+ la $4, 0x1ffff000 /* physical address and 4KB page mask */
187+cache_alloc_a_line:
188+ and $5, $2, $4
189+ ori $5, $5, 1 /* V bit of the physical tag */
190+ mtc0 $5, $28, 0 /* CP0_TAGLO */
191+ cache 0x8, 0($2) /* Index_Store_Tag_I */
192+ cache 0x9, 0($2) /* Index_Store_Tag_D */
193+ bne $2, $3, cache_alloc_a_line
194+ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
195+
196+ nop
197+ nop
198+ nop
199+ /*
200+ * Transfer data from dcache to icache, then jump to icache.
201+ * Input parameters:
202+ * $19: data length in bytes
203+ * $20: jump target address
204+ */
205+xfer_d2i:
206+
207+ ori $8, $20, 0
208+ addu $9, $8, $19 /* total 16KB */
209+
210+1:
211+ cache 0x0, 0($8) /* Index_Invalidate_I */
212+ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
213+ bne $8, $9, 1b
214+ addiu $8, $8, 32
215+
216+ /* flush write-buffer */
217+ sync
218+
219+ /* Invalidate BTB */
220+ mfc0 $8, $16, 7 /* CP0_CONFIG */
221+ nop
222+ ori $8, 2
223+ mtc0 $8, $16, 7
224+ nop
225+
226+ /* Overwrite config to disable ram initalisation */
227+ li $2, 0xff
228+ sb $2, 20($20)
229+
230+ jalr $20
231+ nop
232+
233+icache_return:
234+ /* User code can return to here after executing itself in
235+ icache, by jumping to $31. */
236+ b usb_boot_return
237+ nop
238+
239+
240+usb_boot_return:
241+ /* Enable the USB PHY */
242+ la $9, 0xB0000024 /* CPM_SCR */
243+ lw $8, 0($9)
244+ ori $8, 0x40 /* USBPHY_ENABLE */
245+ sw $8, 0($9)
246+
247+ /* Initialize USB registers */
248+ la $27, 0xb3040000 /* USB registers base address */
249+
250+ sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */
251+ sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */
252+ sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */
253+
254+ li $9, 0x61
255+ sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */
256+
257+ /* Initialize USB states */
258+ li $22, 0 /* set EP0 to IDLE state */
259+ li $23, 1 /* no data stage */
260+
261+ /* Main loop of polling the usb commands */
262+usb_command_loop:
263+ lbu $9, 0x0a($27) /* read INTRUSB */
264+ andi $9, 0x04 /* check USB_INTR_RESET */
265+ beqz $9, check_intr_ep0in
266+ nop
267+
268+ /* 1. Handle USB reset interrupt */
269+handle_reset_intr:
270+ lbu $9, 0x01($27) /* read POWER */
271+ andi $9, 0x10 /* test HS_MODE */
272+ bnez $9, _usb_set_maxpktsize
273+ li $9, 512 /* max packet size of HS mode */
274+ li $9, 64 /* max packet size of FS mode */
275+
276+_usb_set_maxpktsize:
277+ li $8, 1
278+ sb $8, 0x0e($27) /* set INDEX 1 */
279+
280+ sh $9, 0x10($27) /* INMAXP */
281+ sb $0, 0x13($27) /* INCSRH */
282+ sh $9, 0x14($27) /* OUTMAXP */
283+ sb $0, 0x17($27) /* OUTCSRH */
284+
285+_usb_flush_fifo:
286+ li $8, 0x48 /* INCSR_CDT && INCSR_FF */
287+ sb $8, 0x12($27) /* INCSR */
288+ li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */
289+ sb $8, 0x16($27) /* OUTCSR */
290+
291+ li $22, 0 /* set EP0 to IDLE state */
292+ li $23, 1 /* no data stage */
293+
294+ /* 2. Check and handle EP0 interrupt */
295+check_intr_ep0in:
296+ lhu $10, 0x02($27) /* read INTRIN */
297+ andi $9, $10, 0x1 /* check EP0 interrupt */
298+ beqz $9, check_intr_ep1in
299+ nop
300+
301+handle_ep0_intr:
302+ sb $0, 0x0e($27) /* set INDEX 0 */
303+ lbu $11, 0x12($27) /* read CSR0 */
304+
305+ andi $9, $11, 0x04 /* check SENTSTALL */
306+ beqz $9, _ep0_setupend
307+ nop
308+
309+_ep0_sentstall:
310+ andi $9, $11, 0xdb
311+ sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */
312+ li $22, 0 /* set EP0 to IDLE state */
313+
314+_ep0_setupend:
315+ andi $9, $11, 0x10 /* check SETUPEND */
316+ beqz $9, ep0_idle_state
317+ nop
318+
319+ ori $9, $11, 0x80
320+ sb $9, 0x12($27) /* set SVDSETUPEND */
321+ li $22, 0 /* set EP0 to IDLE state */
322+
323+ep0_idle_state:
324+ bnez $22, ep0_tx_state
325+ nop
326+
327+ /* 2.1 Handle EP0 IDLE state interrupt */
328+ andi $9, $11, 0x01 /* check OUTPKTRDY */
329+ beqz $9, check_intr_ep1in
330+ nop
331+
332+ /* Read 8-bytes setup packet from the FIFO */
333+ lw $25, 0x20($27) /* first word of setup packet */
334+ lw $26, 0x20($27) /* second word of setup packet */
335+
336+ andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */
337+ beqz $9, _ep0_std_req
338+ nop
339+
340+ /* 2.1.1 Vendor-specific setup request */
341+_ep0_vend_req:
342+ li $22, 0 /* set EP0 to IDLE state */
343+ li $23, 1 /* NoData = 1 */
344+
345+ andi $9, $25, 0xff00 /* check bRequest */
346+ srl $9, $9, 8
347+ beqz $9, __ep0_get_cpu_info
348+ sub $8, $9, 0x1
349+ beqz $8, __ep0_set_data_address
350+ sub $8, $9, 0x2
351+ beqz $8, __ep0_set_data_length
352+ sub $8, $9, 0x3
353+ beqz $8, __ep0_flush_caches
354+ sub $8, $9, 0x4
355+ beqz $8, __ep0_prog_start1
356+ sub $8, $9, 0x5
357+ beqz $8, __ep0_prog_start2
358+ nop
359+ b _ep0_idle_state_fini /* invalid request */
360+ nop
361+
362+__ep0_get_cpu_info:
363+ load_addr $20, cpu_info_data /* data pointer to transfer */
364+ li $21, 8 /* bytes left to transfer */
365+ li $22, 1 /* set EP0 to TX state */
366+ li $23, 0 /* NoData = 0 */
367+
368+ b _ep0_idle_state_fini
369+ nop
370+
371+__ep0_set_data_address:
372+ li $9, 0xffff0000
373+ and $9, $25, $9
374+ andi $8, $26, 0xffff
375+ or $20, $9, $8 /* data address of next transfer */
376+
377+ b _ep0_idle_state_fini
378+ nop
379+
380+__ep0_set_data_length:
381+ li $9, 0xffff0000
382+ and $9, $25, $9
383+ andi $8, $26, 0xffff
384+ or $21, $9, $8 /* data length of next transfer */
385+
386+ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
387+ sb $9, 0x12($27) /* CSR0 */
388+
389+ /* We must write packet to FIFO before EP1-IN interrupt here. */
390+ b handle_epin1_intr
391+ nop
392+
393+__ep0_flush_caches:
394+ /* Flush dcache and invalidate icache. */
395+ li $8, 0x80000000
396+ addi $9, $8, 0x3fe0 /* total 16KB */
397+
398+1:
399+ cache 0x0, 0($8) /* Index_Invalidate_I */
400+ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
401+ bne $8, $9, 1b
402+ addiu $8, $8, 32
403+
404+ /* flush write-buffer */
405+ sync
406+
407+ /* Invalidate BTB */
408+ mfc0 $8, $16, 7 /* CP0_CONFIG */
409+ nop
410+ ori $8, 2
411+ mtc0 $8, $16, 7
412+ nop
413+
414+ b _ep0_idle_state_fini
415+ nop
416+
417+__ep0_prog_start1:
418+ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
419+ sb $9, 0x12($27) /* CSR0 */
420+
421+ li $9, 0xffff0000
422+ and $9, $25, $9
423+ andi $8, $26, 0xffff
424+ or $20, $9, $8 /* target address */
425+
426+ b xfer_d2i
427+ li $19, 0x2000 /* 16KB data length */
428+
429+__ep0_prog_start2:
430+ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
431+ sb $9, 0x12($27) /* CSR0 */
432+
433+ li $9, 0xffff0000
434+ and $9, $25, $9
435+ andi $8, $26, 0xffff
436+ or $20, $9, $8 /* target address */
437+
438+ jalr $20 /* jump, and place the return address in $31 */
439+ nop
440+
441+__ep0_prog_start2_return:
442+/* User code can return to here after executing itself, by jumping to $31 */
443+ b usb_boot_return
444+ nop
445+
446+ /* 2.1.2 Standard setup request */
447+_ep0_std_req:
448+ andi $12, $25, 0xff00 /* check bRequest */
449+ srl $12, $12, 8
450+ sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */
451+ bnez $9, __ep0_req_set_config
452+ nop
453+
454+ /* Handle USB_REQ_SET_ADDRESS */
455+__ep0_req_set_addr:
456+ srl $9, $25, 16 /* get wValue */
457+ sb $9, 0x0($27) /* set FADDR */
458+ li $23, 1 /* NoData = 1 */
459+ b _ep0_idle_state_fini
460+ nop
461+
462+__ep0_req_set_config:
463+ sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */
464+ bnez $9, __ep0_req_get_desc
465+ nop
466+
467+ /* Handle USB_REQ_SET_CONFIGURATION */
468+ li $23, 1 /* NoData = 1 */
469+ b _ep0_idle_state_fini
470+ nop
471+
472+__ep0_req_get_desc:
473+ sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */
474+ bnez $9, _ep0_idle_state_fini
475+ li $23, 1 /* NoData = 1 */
476+
477+ /* Handle USB_REQ_GET_DESCRIPTOR */
478+ li $23, 0 /* NoData = 0 */
479+
480+ srl $9, $25, 24 /* wValue >> 8 */
481+ sub $8, $9, 0x01 /* check USB_DT_DEVICE */
482+ beqz $8, ___ep0_get_dev_desc
483+ srl $21, $26, 16 /* get wLength */
484+ sub $8, $9, 0x02 /* check USB_DT_CONFIG */
485+ beqz $8, ___ep0_get_conf_desc
486+ sub $8, $9, 0x03 /* check USB_DT_STRING */
487+ beqz $8, ___ep0_get_string_desc
488+ sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */
489+ beqz $8, ___ep0_get_dev_qualifier
490+ nop
491+ b _ep0_idle_state_fini
492+ nop
493+
494+___ep0_get_dev_desc:
495+ load_addr $20, device_desc /* data pointer */
496+ li $22, 1 /* set EP0 to TX state */
497+ sub $8, $21, 18
498+ blez $8, _ep0_idle_state_fini /* wLength <= 18 */
499+ nop
500+ li $21, 18 /* max length of device_desc */
501+ b _ep0_idle_state_fini
502+ nop
503+
504+___ep0_get_dev_qualifier:
505+ load_addr $20, dev_qualifier /* data pointer */
506+ li $22, 1 /* set EP0 to TX state */
507+ sub $8, $21, 10
508+ blez $8, _ep0_idle_state_fini /* wLength <= 10 */
509+ nop
510+ li $21, 10 /* max length of dev_qualifier */
511+ b _ep0_idle_state_fini
512+ nop
513+
514+___ep0_get_conf_desc:
515+ load_addr $20, config_desc_fs /* data pointer of FS mode */
516+ lbu $8, 0x01($27) /* read POWER */
517+ andi $8, 0x10 /* test HS_MODE */
518+ beqz $8, ___ep0_get_conf_desc2
519+ nop
520+ load_addr $20, config_desc_hs /* data pointer of HS mode */
521+
522+___ep0_get_conf_desc2:
523+ li $22, 1 /* set EP0 to TX state */
524+ sub $8, $21, 32
525+ blez $8, _ep0_idle_state_fini /* wLength <= 32 */
526+ nop
527+ li $21, 32 /* max length of config_desc */
528+ b _ep0_idle_state_fini
529+ nop
530+
531+___ep0_get_string_desc:
532+ li $22, 1 /* set EP0 to TX state */
533+
534+ srl $9, $25, 16 /* wValue & 0xff */
535+ andi $9, 0xff
536+
537+ sub $8, $9, 1
538+ beqz $8, ___ep0_get_string_manufacture
539+ sub $8, $9, 2
540+ beqz $8, ___ep0_get_string_product
541+ nop
542+
543+___ep0_get_string_lang_ids:
544+ load_addr $20, string_lang_ids /* data pointer */
545+ b _ep0_idle_state_fini
546+ li $21, 4 /* data length */
547+
548+___ep0_get_string_manufacture:
549+ load_addr $20, string_manufacture /* data pointer */
550+ b _ep0_idle_state_fini
551+ li $21, 16 /* data length */
552+
553+___ep0_get_string_product:
554+ load_addr $20, string_product /* data pointer */
555+ b _ep0_idle_state_fini
556+ li $21, 46 /* data length */
557+
558+_ep0_idle_state_fini:
559+ li $9, 0x40 /* SVDOUTPKTRDY */
560+ beqz $23, _ep0_idle_state_fini2
561+ nop
562+ ori $9, $9, 0x08 /* DATAEND */
563+_ep0_idle_state_fini2:
564+ sb $9, 0x12($27) /* CSR0 */
565+ beqz $22, check_intr_ep1in
566+ nop
567+
568+ /* 2.2 Handle EP0 TX state interrupt */
569+ep0_tx_state:
570+ sub $9, $22, 1
571+ bnez $9, check_intr_ep1in
572+ nop
573+
574+ sub $9, $21, 64 /* max packetsize */
575+ blez $9, _ep0_tx_state2 /* data count <= 64 */
576+ ori $19, $21, 0
577+ li $19, 64
578+
579+_ep0_tx_state2:
580+ beqz $19, _ep0_tx_state3 /* send ZLP */
581+ ori $18, $19, 0 /* record bytes to be transferred */
582+ sub $21, $21, $19 /* decrement data count */
583+
584+_ep0_fifo_write_loop:
585+ lbu $9, 0($20) /* read data */
586+ sb $9, 0x20($27) /* load FIFO */
587+ sub $19, $19, 1 /* decrement counter */
588+ bnez $19, _ep0_fifo_write_loop
589+ addi $20, $20, 1 /* increment data pointer */
590+
591+ sub $9, $18, 64 /* max packetsize */
592+ beqz $9, _ep0_tx_state4
593+ nop
594+
595+_ep0_tx_state3:
596+ /* transferred bytes < max packetsize */
597+ li $9, 0x0a /* set INPKTRDY and DATAEND */
598+ sb $9, 0x12($27) /* CSR0 */
599+ li $22, 0 /* set EP0 to IDLE state */
600+ b check_intr_ep1in
601+ nop
602+
603+_ep0_tx_state4:
604+ /* transferred bytes == max packetsize */
605+ li $9, 0x02 /* set INPKTRDY */
606+ sb $9, 0x12($27) /* CSR0 */
607+ b check_intr_ep1in
608+ nop
609+
610+ /* 3. Check and handle EP1 BULK-IN interrupt */
611+check_intr_ep1in:
612+ andi $9, $10, 0x2 /* check EP1 IN interrupt */
613+ beqz $9, check_intr_ep1out
614+ nop
615+
616+handle_epin1_intr:
617+ li $9, 1
618+ sb $9, 0x0e($27) /* set INDEX 1 */
619+ lbu $9, 0x12($27) /* read INCSR */
620+
621+ andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */
622+ bnez $8, _epin1_tx_state4
623+ nop
624+
625+_epin1_write_fifo:
626+ lhu $9, 0x10($27) /* get INMAXP */
627+ sub $8, $21, $9
628+ blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */
629+ ori $19, $21, 0
630+ ori $19, $9, 0
631+
632+_epin1_tx_state1:
633+ beqz $19, _epin1_tx_state4 /* No data */
634+ nop
635+
636+ sub $21, $21, $19 /* decrement data count */
637+
638+ srl $5, $19, 2 /* # of word */
639+ andi $6, $19, 0x3 /* # of byte */
640+ beqz $5, _epin1_tx_state2
641+ nop
642+
643+_epin1_fifo_write_word:
644+ lw $9, 0($20) /* read data from source address */
645+ sw $9, 0x24($27) /* write FIFO */
646+ sub $5, $5, 1 /* decrement counter */
647+ bnez $5, _epin1_fifo_write_word
648+ addiu $20, $20, 4 /* increment dest address */
649+
650+_epin1_tx_state2:
651+ beqz $6, _epin1_tx_state3
652+ nop
653+
654+_epin1_fifo_write_byte:
655+ lbu $9, 0($20) /* read data from source address */
656+ sb $9, 0x24($27) /* write FIFO */
657+ sub $6, $6, 1 /* decrement counter */
658+ bnez $6, _epin1_fifo_write_byte
659+ addiu $20, $20, 1 /* increment dest address */
660+
661+_epin1_tx_state3:
662+ li $9, 0x1
663+ sb $9, 0x12($27) /* INCSR, set INPKTRDY */
664+
665+_epin1_tx_state4:
666+ /* 4. Check and handle EP1 BULK-OUT interrupt */
667+check_intr_ep1out:
668+ lhu $9, 0x04($27) /* read INTROUT */
669+ andi $9, 0x2
670+ beqz $9, check_status_next
671+ nop
672+
673+handle_epout1_intr:
674+ li $9, 1
675+ sb $9, 0x0e($27) /* set INDEX 1 */
676+
677+ lbu $9, 0x16($27) /* read OUTCSR */
678+ andi $9, 0x1 /* check OUTPKTRDY */
679+ beqz $9, check_status_next
680+ nop
681+
682+_epout1_read_fifo:
683+ lhu $19, 0x18($27) /* read OUTCOUNT */
684+ srl $5, $19, 2 /* # of word */
685+ andi $6, $19, 0x3 /* # of byte */
686+ beqz $5, _epout1_rx_state1
687+ nop
688+
689+_epout1_fifo_read_word:
690+ lw $9, 0x24($27) /* read FIFO */
691+ sw $9, 0($20) /* store to dest address */
692+ sub $5, $5, 1 /* decrement counter */
693+ bnez $5, _epout1_fifo_read_word
694+ addiu $20, $20, 4 /* increment dest address */
695+
696+_epout1_rx_state1:
697+ beqz $6, _epout1_rx_state2
698+ nop
699+
700+_epout1_fifo_read_byte:
701+ lbu $9, 0x24($27) /* read FIFO */
702+ sb $9, 0($20) /* store to dest address */
703+ sub $6, $6, 1 /* decrement counter */
704+ bnez $6, _epout1_fifo_read_byte
705+ addiu $20, $20, 1 /* increment dest address */
706+
707+_epout1_rx_state2:
708+ sb $0, 0x16($27) /* clear OUTPKTRDY */
709+
710+check_status_next:
711+ b usb_command_loop
712+ nop
713+
714+/* Device/Configuration/Interface/Endpoint/String Descriptors */
715+
716+ .align 2
717+device_desc:
718+ .byte 0x12 /* bLength */
719+ .byte 0x01 /* bDescriptorType */
720+ .byte 0x00 /* bcdUSB */
721+ .byte 0x02 /* bcdUSB */
722+ .byte 0x00 /* bDeviceClass */
723+ .byte 0x00 /* bDeviceSubClass */
724+ .byte 0x00 /* bDeviceProtocol */
725+ .byte 0x40 /* bMaxPacketSize0 */
726+ .byte 0x1a /* idVendor */
727+ .byte 0x60 /* idVendor */
728+ .byte 0x40 /* idProduct */
729+ .byte 0x47 /* idProduct */
730+ .byte 0x00 /* bcdDevice */
731+ .byte 0x01 /* bcdDevice */
732+ .byte 0x01 /* iManufacturer */
733+ .byte 0x02 /* iProduct */
734+ .byte 0x00 /* iSerialNumber */
735+ .byte 0x01 /* bNumConfigurations */
736+
737+ .align 2
738+dev_qualifier:
739+ .byte 0x0a /* bLength */
740+ .byte 0x06 /* bDescriptorType */
741+ .byte 0x00 /* bcdUSB */
742+ .byte 0x02 /* bcdUSB */
743+ .byte 0x00 /* bDeviceClass */
744+ .byte 0x00 /* bDeviceSubClass */
745+ .byte 0x00 /* bDeviceProtocol */
746+ .byte 0x40 /* bMaxPacketSize0 */
747+ .byte 0x01 /* bNumConfigurations */
748+ .byte 0x00 /* bRESERVED */
749+
750+ .align 2
751+config_desc_hs:
752+ .byte 0x09 /* bLength */
753+ .byte 0x02 /* bDescriptorType */
754+ .byte 0x20 /* wTotalLength */
755+ .byte 0x00 /* wTotalLength */
756+ .byte 0x01 /* bNumInterfaces */
757+ .byte 0x01 /* bConfigurationValue */
758+ .byte 0x00 /* iConfiguration */
759+ .byte 0xc0 /* bmAttributes */
760+ .byte 0x01 /* MaxPower */
761+intf_desc_hs:
762+ .byte 0x09 /* bLength */
763+ .byte 0x04 /* bDescriptorType */
764+ .byte 0x00 /* bInterfaceNumber */
765+ .byte 0x00 /* bAlternateSetting */
766+ .byte 0x02 /* bNumEndpoints */
767+ .byte 0xff /* bInterfaceClass */
768+ .byte 0x00 /* bInterfaceSubClass */
769+ .byte 0x50 /* bInterfaceProtocol */
770+ .byte 0x00 /* iInterface */
771+ep1_desc_hs:
772+ .byte 0x07 /* bLength */
773+ .byte 0x05 /* bDescriptorType */
774+ .byte 0x01 /* bEndpointAddress */
775+ .byte 0x02 /* bmAttributes */
776+ .byte 0x00 /* wMaxPacketSize */
777+ .byte 0x02 /* wMaxPacketSize */
778+ .byte 0x00 /* bInterval */
779+ep2_desc_hs:
780+ .byte 0x07 /* bLength */
781+ .byte 0x05 /* bDescriptorType */
782+ .byte 0x81 /* bEndpointAddress */
783+ .byte 0x02 /* bmAttributes */
784+ .byte 0x00 /* wMaxPacketSize */
785+ .byte 0x02 /* wMaxPacketSize */
786+ .byte 0x00 /* bInterval */
787+
788+ .align 2
789+config_desc_fs:
790+ .byte 0x09 /* bLength */
791+ .byte 0x02 /* bDescriptorType */
792+ .byte 0x20 /* wTotalLength */
793+ .byte 0x00 /* wTotalLength */
794+ .byte 0x01 /* bNumInterfaces */
795+ .byte 0x01 /* bConfigurationValue */
796+ .byte 0x00 /* iConfiguration */
797+ .byte 0xc0 /* bmAttributes */
798+ .byte 0x01 /* MaxPower */
799+intf_desc_fs:
800+ .byte 0x09 /* bLength */
801+ .byte 0x04 /* bDescriptorType */
802+ .byte 0x00 /* bInterfaceNumber */
803+ .byte 0x00 /* bAlternateSetting */
804+ .byte 0x02 /* bNumEndpoints */
805+ .byte 0xff /* bInterfaceClass */
806+ .byte 0x00 /* bInterfaceSubClass */
807+ .byte 0x50 /* bInterfaceProtocol */
808+ .byte 0x00 /* iInterface */
809+ep1_desc_fs:
810+ .byte 0x07 /* bLength */
811+ .byte 0x05 /* bDescriptorType */
812+ .byte 0x01 /* bEndpointAddress */
813+ .byte 0x02 /* bmAttributes */
814+ .byte 0x40 /* wMaxPacketSize */
815+ .byte 0x00 /* wMaxPacketSize */
816+ .byte 0x00 /* bInterval */
817+ep2_desc_fs:
818+ .byte 0x07 /* bLength */
819+ .byte 0x05 /* bDescriptorType */
820+ .byte 0x81 /* bEndpointAddress */
821+ .byte 0x02 /* bmAttributes */
822+ .byte 0x40 /* wMaxPacketSize */
823+ .byte 0x00 /* wMaxPacketSize */
824+ .byte 0x00 /* bInterval */
825+
826+ .align 2
827+string_lang_ids:
828+ .byte 0x04
829+ .byte 0x03
830+ .byte 0x09
831+ .byte 0x04
832+
833+ .align 2
834+string_manufacture:
835+ .byte 0x10
836+ .byte 0x03
837+ .byte 0x49
838+ .byte 0x00
839+ .byte 0x6e
840+ .byte 0x00
841+ .byte 0x67
842+ .byte 0x00
843+ .byte 0x65
844+ .byte 0x00
845+ .byte 0x6e
846+ .byte 0x00
847+ .byte 0x69
848+ .byte 0x00
849+ .byte 0x63
850+ .byte 0x00
851+
852+ .align 2
853+string_product:
854+ .byte 0x2e
855+ .byte 0x03
856+ .byte 0x4a
857+ .byte 0x00
858+ .byte 0x5a
859+ .byte 0x00
860+ .byte 0x34
861+ .byte 0x00
862+ .byte 0x37
863+ .byte 0x00
864+ .byte 0x34
865+ .byte 0x00
866+ .byte 0x30
867+ .byte 0x00
868+ .byte 0x20
869+ .byte 0x00
870+ .byte 0x55
871+ .byte 0x00
872+ .byte 0x53
873+ .byte 0x00
874+ .byte 0x42
875+ .byte 0x00
876+ .byte 0x20
877+ .byte 0x00
878+ .byte 0x42
879+ .byte 0x00
880+ .byte 0x6f
881+ .byte 0x00
882+ .byte 0x6f
883+ .byte 0x00
884+ .byte 0x74
885+ .byte 0x00
886+ .byte 0x20
887+ .byte 0x00
888+ .byte 0x44
889+ .byte 0x00
890+ .byte 0x65
891+ .byte 0x00
892+ .byte 0x76
893+ .byte 0x00
894+ .byte 0x69
895+ .byte 0x00
896+ .byte 0x63
897+ .byte 0x00
898+ .byte 0x65
899+ .byte 0x00
900+
901+ .align 2
902+cpu_info_data:
903+ .byte 0x4a
904+ .byte 0x5a
905+ .byte 0x34
906+ .byte 0x37
907+ .byte 0x34
908+ .byte 0x30
909+ .byte 0x56
910+ .byte 0x31
911+usbboot_end:
912+
913+ .set reorder
914--
9151.7.9.5
916
917

Archive Download this file



interactive