summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-07-13 17:35:53 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-07-13 17:47:01 +0200
commit140783ef66eef379feedcfef5403c5729d38936a (patch)
tree0185a6a6ef80ab134150454674a1d7e1333b8757 /utils/hwstub/stub
parent3dd5e983db8d83113cc76ee0f5c02e158380606a (diff)
downloadrockbox-140783ef66eef379feedcfef5403c5729d38936a.tar.gz
rockbox-140783ef66eef379feedcfef5403c5729d38936a.zip
hwstub: split target specific code from the common part
Completely rewrite the Mafile, properly put the usb driver in its own file and the target specific files in a subdirectory. Change-Id: Iaeee0128e021d5dad76b4d6035a63e33e2d946c1
Diffstat (limited to 'utils/hwstub/stub')
-rw-r--r--utils/hwstub/stub/SOURCES12
-rw-r--r--utils/hwstub/stub/config.h49
-rw-r--r--utils/hwstub/stub/crt0.S17
-rw-r--r--utils/hwstub/stub/format.c223
-rw-r--r--utils/hwstub/stub/format.h29
-rw-r--r--utils/hwstub/stub/hwstub.lds71
-rw-r--r--utils/hwstub/stub/hwstub.make49
-rw-r--r--utils/hwstub/stub/logf.c69
-rw-r--r--utils/hwstub/stub/logf.h31
-rw-r--r--utils/hwstub/stub/memcpy.S176
-rw-r--r--utils/hwstub/stub/memmove.S190
-rw-r--r--utils/hwstub/stub/memory.h30
-rw-r--r--utils/hwstub/stub/memset.S98
-rw-r--r--utils/hwstub/stub/protocol.h1
-rw-r--r--utils/hwstub/stub/stddef.h32
-rw-r--r--utils/hwstub/stub/stdint.h40
-rw-r--r--utils/hwstub/stub/stmp/Makefile14
-rw-r--r--utils/hwstub/stub/stmp/target-config.h9
-rw-r--r--utils/hwstub/stub/stmp/target.c205
-rw-r--r--utils/hwstub/stub/string.c29
-rw-r--r--utils/hwstub/stub/string.h28
-rw-r--r--utils/hwstub/stub/system.h118
-rw-r--r--utils/hwstub/stub/target.h31
-rw-r--r--utils/hwstub/stub/usb_ch9.h454
-rw-r--r--utils/hwstub/stub/usb_drv.h47
-rw-r--r--utils/hwstub/stub/usb_drv_arc.c364
26 files changed, 2416 insertions, 0 deletions
diff --git a/utils/hwstub/stub/SOURCES b/utils/hwstub/stub/SOURCES
new file mode 100644
index 0000000000..bfb847c21b
--- /dev/null
+++ b/utils/hwstub/stub/SOURCES
@@ -0,0 +1,12 @@
1main.c
2crt0.S
3logf.c
4memcpy.S
5memmove.S
6memset.S
7string.c
8format.c
9#ifdef CONFIG_STMP
10usb_drv_arc.c
11stmp/target.c
12#endif
diff --git a/utils/hwstub/stub/config.h b/utils/hwstub/stub/config.h
new file mode 100644
index 0000000000..3cd2deeeb3
--- /dev/null
+++ b/utils/hwstub/stub/config.h
@@ -0,0 +1,49 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_CONFIG__
22#define __HWSTUB_CONFIG__
23
24#include "target-config.h"
25
26#define STACK_SIZE 0x1000
27#define MAX_LOGF_SIZE 128
28
29#if defined(CPU_ARM) && defined(__ASSEMBLER__)
30/* ARMv4T doesn't switch the T bit when popping pc directly, we must use BX */
31.macro ldmpc cond="", order="ia", regs
32#if ARM_ARCH == 4 && defined(USE_THUMB)
33 ldm\cond\order sp!, { \regs, lr }
34 bx\cond lr
35#else
36 ldm\cond\order sp!, { \regs, pc }
37#endif
38.endm
39.macro ldrpc cond=""
40#if ARM_ARCH == 4 && defined(USE_THUMB)
41 ldr\cond lr, [sp], #4
42 bx\cond lr
43#else
44 ldr\cond pc, [sp], #4
45#endif
46.endm
47#endif
48
49#endif /* __HWSTUB_CONFIG__ */
diff --git a/utils/hwstub/stub/crt0.S b/utils/hwstub/stub/crt0.S
new file mode 100644
index 0000000000..e2d4742d36
--- /dev/null
+++ b/utils/hwstub/stub/crt0.S
@@ -0,0 +1,17 @@
1.section .text,"ax",%progbits
2.code 32
3.align 0x04
4.global start
5start:
6 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
7 ldr sp, =oc_stackend
8 /* clear bss */
9 ldr r2, =bss_start
10 ldr r3, =bss_end
11 mov r4, #0
121:
13 cmp r3, r2
14 strhi r4, [r2], #4
15 bhi 1b
16 /* jump to C code */
17 b main
diff --git a/utils/hwstub/stub/format.c b/utils/hwstub/stub/format.c
new file mode 100644
index 0000000000..f5783159c0
--- /dev/null
+++ b/utils/hwstub/stub/format.c
@@ -0,0 +1,223 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Gary Czvitkovicz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#include <stdarg.h>
24#include <limits.h>
25#include "stddef.h"
26#include "string.h"
27#include "format.h"
28
29static const char hexdigit[] = "0123456789ABCDEF";
30
31void vuprintf(
32 /* call 'push()' for each output letter */
33 int (*push)(void *userp, unsigned char data),
34 void *userp,
35 const char *fmt,
36 va_list ap)
37{
38 char *str;
39 char tmpbuf[12], pad;
40 int ch, width, val, sign, precision;
41 long lval, lsign;
42 unsigned int uval;
43 unsigned long ulval;
44 size_t uszval;
45 ssize_t szval, szsign;
46 bool ok = true;
47
48 tmpbuf[sizeof tmpbuf - 1] = '\0';
49
50 while ((ch = *fmt++) != '\0' && ok)
51 {
52 if (ch == '%')
53 {
54 ch = *fmt++;
55 pad = ' ';
56 if (ch == '0')
57 pad = '0';
58
59 width = 0;
60 while (ch >= '0' && ch <= '9')
61 {
62 width = 10*width + ch - '0';
63 ch = *fmt++;
64 }
65
66 precision = 0;
67 if(ch == '.')
68 {
69 ch = *fmt++;
70 while (ch >= '0' && ch <= '9')
71 {
72 precision = 10*precision + ch - '0';
73 ch = *fmt++;
74 }
75 } else {
76 precision = INT_MAX;
77 }
78
79 str = tmpbuf + sizeof tmpbuf - 1;
80 switch (ch)
81 {
82 case 'c':
83 *--str = va_arg (ap, int);
84 break;
85
86 case 's':
87 str = va_arg (ap, char*);
88 break;
89
90 case 'd':
91 val = sign = va_arg (ap, int);
92 if (val < 0)
93 val = -val;
94 do
95 {
96 *--str = (val % 10) + '0';
97 val /= 10;
98 }
99 while (val > 0);
100 if (sign < 0)
101 *--str = '-';
102 break;
103
104 case 'u':
105 uval = va_arg(ap, unsigned int);
106 do
107 {
108 *--str = (uval % 10) + '0';
109 uval /= 10;
110 }
111 while (uval > 0);
112 break;
113
114 case 'x':
115 case 'X':
116 pad='0';
117 uval = va_arg (ap, int);
118 do
119 {
120 *--str = hexdigit[uval & 0xf];
121 uval >>= 4;
122 }
123 while (uval);
124 break;
125
126 case 'l':
127 ch = *fmt++;
128 switch(ch) {
129 case 'x':
130 case 'X':
131 pad='0';
132 ulval = va_arg (ap, long);
133 do
134 {
135 *--str = hexdigit[ulval & 0xf];
136 ulval >>= 4;
137 }
138 while (ulval);
139 break;
140 case 'd':
141 lval = lsign = va_arg (ap, long);
142 if (lval < 0)
143 lval = -lval;
144 do
145 {
146 *--str = (lval % 10) + '0';
147 lval /= 10;
148 }
149 while (lval > 0);
150 if (lsign < 0)
151 *--str = '-';
152 break;
153
154 case 'u':
155 ulval = va_arg(ap, unsigned long);
156 do
157 {
158 *--str = (ulval % 10) + '0';
159 ulval /= 10;
160 }
161 while (ulval > 0);
162 break;
163
164 default:
165 *--str = 'l';
166 *--str = ch;
167 }
168
169 break;
170
171 case 'z':
172 ch = *fmt++;
173 switch(ch) {
174 case 'd':
175 szval = szsign = va_arg (ap, ssize_t);
176 if (szval < 0)
177 szval = -szval;
178 do
179 {
180 *--str = (szval % 10) + '0';
181 szval /= 10;
182 }
183 while (szval > 0);
184 if (szsign < 0)
185 *--str = '-';
186 break;
187
188 case 'u':
189 uszval = va_arg(ap, size_t);
190 do
191 {
192 *--str = (uszval % 10) + '0';
193 uszval /= 10;
194 }
195 while (uszval > 0);
196 break;
197
198 default:
199 *--str = 'z';
200 *--str = ch;
201 }
202
203 break;
204
205 default:
206 *--str = ch;
207 break;
208 }
209
210 if (width > 0)
211 {
212 width -= strlen (str);
213 while (width-- > 0 && ok)
214 ok=push(userp, pad);
215 }
216 while (*str != '\0' && ok && precision--)
217 ok=push(userp, *str++);
218 }
219 else
220 ok=push(userp, ch);
221 }
222}
223
diff --git a/utils/hwstub/stub/format.h b/utils/hwstub/stub/format.h
new file mode 100644
index 0000000000..2ad4229f1e
--- /dev/null
+++ b/utils/hwstub/stub/format.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_FORMAT__
22#define __HWSTUB_FORMAT__
23
24#include <stdarg.h>
25
26void vuprintf(int (*push)(void *userp, unsigned char data),
27 void *userp, const char *fmt, va_list ap);
28
29#endif /* __HWSTUB_FORMAT__ */
diff --git a/utils/hwstub/stub/hwstub.lds b/utils/hwstub/stub/hwstub.lds
new file mode 100644
index 0000000000..61504a3e75
--- /dev/null
+++ b/utils/hwstub/stub/hwstub.lds
@@ -0,0 +1,71 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22
23ENTRY(start)
24OUTPUT_FORMAT(elf32-littlearm)
25OUTPUT_ARCH(arm)
26STARTUP(crt0.o)
27
28#define IRAM_END_ADDR (IRAM_ORIG + IRAM_SIZE)
29
30MEMORY
31{
32 OCRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE
33}
34
35SECTIONS
36{
37 .octext :
38 {
39 oc_codestart = .;
40 *(.text*)
41 *(.icode*)
42 *(.data*)
43 *(.rodata*)
44 } > OCRAM
45
46 .bss (NOLOAD) :
47 {
48 bss_start = .;
49 *(.bss)
50 bss_end = .;
51 } > OCRAM
52
53 .stack (NOLOAD) :
54 {
55 oc_codeend = .;
56 oc_stackstart = .;
57 . += STACK_SIZE;
58 oc_stackend = .;
59 oc_bufferstart = .;
60 } > OCRAM
61
62 .ocend IRAM_END_ADDR (NOLOAD) :
63 {
64 oc_bufferend = .;
65 } > OCRAM
66
67 /DISCARD/ :
68 {
69 *(.eh_frame)
70 }
71}
diff --git a/utils/hwstub/stub/hwstub.make b/utils/hwstub/stub/hwstub.make
new file mode 100644
index 0000000000..b46a2736ef
--- /dev/null
+++ b/utils/hwstub/stub/hwstub.make
@@ -0,0 +1,49 @@
1INCLUDES+=-I$(ROOT_DIR)
2LINKER_FILE=$(ROOT_DIR)/hwstub.lds
3TMP_LDS=$(BUILD_DIR)/link.lds
4TMP_MAP=$(BUILD_DIR)/hwstub.map
5CFLAGS=$(GCCOPTS) $(DEFINES) -W -Wall -Wundef -O -nostdlib -ffreestanding -Wstrict-prototypes -pipe -std=gnu99 -fomit-frame-pointer -Wno-pointer-sign -Wno-override-init $(INCLUDES)
6ASFLAGS=$(CFLAGS) -D__ASSEMBLER__
7LDFLAGS=-lgcc -Os -nostdlib -T$(TMP_LDS) -Wl,-Map,$(TMP_MAP) $(INCLUDES) -L$(BUILD_DIR)
8
9SRC:=$(shell cat $(ROOT_DIR)/SOURCES | $(CC) $(INCLUDES) \
10 $(DEFINES) -E -P -include "config.h" - 2>/dev/null \
11 | grep -v "^\#")
12SRC:=$(foreach src,$(SRC),$(BUILD_DIR)/$(src))
13OBJ=$(SRC:.c=.o)
14OBJ:=$(OBJ:.S=.o)
15OBJ_EXCEPT_CRT0=$(filter-out $(BUILD_DIR)/crt0.o,$(OBJ))
16EXEC_ELF=$(BUILD_DIR)/hwstub.elf
17DEPS=$(foreach obj,$(OBJ),$(obj).d)
18
19EXEC=$(EXEC_ELF)
20
21SILENT?=@
22PRINTS=$(SILENT)$(call info,$(1))
23
24all: $(EXEC)
25
26# pull in dependency info for *existing* .o files
27-include $(DEPS)
28
29$(BUILD_DIR)/%.o: $(ROOT_DIR)/%.c
30 $(SILENT)mkdir -p $(dir $@)
31 $(call PRINTS,CC $(<F))
32 $(SILENT)$(CC) $(CFLAGS) -c -o $@ $<
33 $(SILENT)$(CC) -MM $(CFLAGS) $< -MT $@ > $@.d
34
35$(BUILD_DIR)/%.o: $(ROOT_DIR)/%.S
36 $(call PRINTS,AS $(<F))
37 $(SILENT)mkdir -p $(dir $@)
38 $(SILENT)$(AS) $(ASFLAGS) -c -o $@ $<
39
40$(TMP_LDS): $(LINKER_FILE)
41 $(call PRINTS,PP $(<F))
42 $(SILENT)$(CC) $(CFLAGS) -E -x c - < $< | sed '/#/d' > $@
43
44$(EXEC_ELF): $(OBJ) $(TMP_LDS)
45 $(call PRINTS,LD $(@F))
46 $(SILENT)$(LD) $(LDFLAGS) -o $@ $(OBJ_EXCEPT_CRT0)
47
48clean:
49 $(SILENT)rm -rf $(OBJ) $(DEPS) $(EXEC) $(TMP_LDS) $(TMP_MAP)
diff --git a/utils/hwstub/stub/logf.c b/utils/hwstub/stub/logf.c
new file mode 100644
index 0000000000..623ddb1c6c
--- /dev/null
+++ b/utils/hwstub/stub/logf.c
@@ -0,0 +1,69 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "logf.h"
23#include "format.h"
24#include "string.h"
25#include "memory.h"
26
27static unsigned char logfbuffer[MAX_LOGF_SIZE];
28static int logfread = 0;
29static int logfwrite = 0;
30static int logfen = true;
31
32void enable_logf(bool en)
33{
34 logfen = en;
35}
36
37static int logf_push(void *userp, unsigned char c)
38{
39 (void)userp;
40
41 logfbuffer[logfwrite++] = c;
42 if(logfwrite == MAX_LOGF_SIZE)
43 logfwrite = 0;
44 return true;
45}
46
47void logf(const char *fmt, ...)
48{
49 if(!logfen) return;
50 va_list ap;
51 va_start(ap, fmt);
52 vuprintf(logf_push, NULL, fmt, ap);
53 va_end(ap);
54}
55
56size_t logf_readback(char *buf, size_t max_size)
57{
58 if(logfread == logfwrite)
59 return 0;
60 if(logfread < logfwrite)
61 max_size = MIN(max_size, (size_t)(logfwrite - logfread));
62 else
63 max_size = MIN(max_size, (size_t)(MAX_LOGF_SIZE - logfread));
64 memcpy(buf, &logfbuffer[logfread], max_size);
65 logfread += max_size;
66 if(logfread == MAX_LOGF_SIZE)
67 logfread = 0;
68 return max_size;
69}
diff --git a/utils/hwstub/stub/logf.h b/utils/hwstub/stub/logf.h
new file mode 100644
index 0000000000..48c8c2c9b9
--- /dev/null
+++ b/utils/hwstub/stub/logf.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_LOGF__
22#define __HWSTUB_LOGF__
23
24#include "stddef.h"
25#include <stdarg.h>
26
27void enable_logf(bool en);
28void logf(const char *fmt, ...);
29size_t logf_readback(char *buf, size_t max_size);
30
31#endif /* __HWSTUB_LOGF__ */
diff --git a/utils/hwstub/stub/memcpy.S b/utils/hwstub/stub/memcpy.S
new file mode 100644
index 0000000000..2a55fb5656
--- /dev/null
+++ b/utils/hwstub/stub/memcpy.S
@@ -0,0 +1,176 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Free Software Foundation, Inc.
11 * This file was originally part of the GNU C Library
12 * Contributed to glibc by MontaVista Software, Inc. (written by Nicolas Pitre)
13 * Adapted for Rockbox by Daniel Ankers
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26
27/*
28 * Endian independent macros for shifting bytes within registers.
29 */
30#ifndef __ARMEB__
31#define pull lsr
32#define push lsl
33#else
34#define pull lsl
35#define push lsr
36#endif
37
38/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
39
40 .section .icode,"ax",%progbits
41
42 .align 2
43 .global memcpy
44 .type memcpy,%function
45
46memcpy:
47 stmfd sp!, {r0, r4, lr}
48
49 subs r2, r2, #4
50 blt 8f
51 ands ip, r0, #3
52 bne 9f
53 ands ip, r1, #3
54 bne 10f
55
561: subs r2, r2, #(28)
57 stmfd sp!, {r5 - r8}
58 blt 5f
59
602:
613:
624: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
63 subs r2, r2, #32
64 stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
65 bge 3b
66
675: ands ip, r2, #28
68 rsb ip, ip, #32
69 addne pc, pc, ip @ C is always clear here
70 b 7f
716: nop
72 ldr r3, [r1], #4
73 ldr r4, [r1], #4
74 ldr r5, [r1], #4
75 ldr r6, [r1], #4
76 ldr r7, [r1], #4
77 ldr r8, [r1], #4
78 ldr lr, [r1], #4
79
80 add pc, pc, ip
81 nop
82 nop
83 str r3, [r0], #4
84 str r4, [r0], #4
85 str r5, [r0], #4
86 str r6, [r0], #4
87 str r7, [r0], #4
88 str r8, [r0], #4
89 str lr, [r0], #4
90
917: ldmfd sp!, {r5 - r8}
92
938: movs r2, r2, lsl #31
94 ldrneb r3, [r1], #1
95 ldrcsb r4, [r1], #1
96 ldrcsb ip, [r1]
97 strneb r3, [r0], #1
98 strcsb r4, [r0], #1
99 strcsb ip, [r0]
100
101 ldmpc regs="r0, r4"
102
1039: rsb ip, ip, #4
104 cmp ip, #2
105 ldrgtb r3, [r1], #1
106 ldrgeb r4, [r1], #1
107 ldrb lr, [r1], #1
108 strgtb r3, [r0], #1
109 strgeb r4, [r0], #1
110 subs r2, r2, ip
111 strb lr, [r0], #1
112 blt 8b
113 ands ip, r1, #3
114 beq 1b
115
11610: bic r1, r1, #3
117 cmp ip, #2
118 ldr lr, [r1], #4
119 beq 17f
120 bgt 18f
121
122
123 .macro forward_copy_shift pull push
124
125 subs r2, r2, #28
126 blt 14f
127
12811: stmfd sp!, {r5 - r9}
129
13012:
13113: ldmia r1!, {r4, r5, r6, r7}
132 mov r3, lr, pull #\pull
133 subs r2, r2, #32
134 ldmia r1!, {r8, r9, ip, lr}
135 orr r3, r3, r4, push #\push
136 mov r4, r4, pull #\pull
137 orr r4, r4, r5, push #\push
138 mov r5, r5, pull #\pull
139 orr r5, r5, r6, push #\push
140 mov r6, r6, pull #\pull
141 orr r6, r6, r7, push #\push
142 mov r7, r7, pull #\pull
143 orr r7, r7, r8, push #\push
144 mov r8, r8, pull #\pull
145 orr r8, r8, r9, push #\push
146 mov r9, r9, pull #\pull
147 orr r9, r9, ip, push #\push
148 mov ip, ip, pull #\pull
149 orr ip, ip, lr, push #\push
150 stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
151 bge 12b
152
153 ldmfd sp!, {r5 - r9}
154
15514: ands ip, r2, #28
156 beq 16f
157
15815: mov r3, lr, pull #\pull
159 ldr lr, [r1], #4
160 subs ip, ip, #4
161 orr r3, r3, lr, push #\push
162 str r3, [r0], #4
163 bgt 15b
164
16516: sub r1, r1, #(\push / 8)
166 b 8b
167
168 .endm
169
170
171 forward_copy_shift pull=8 push=24
172
17317: forward_copy_shift pull=16 push=16
174
17518: forward_copy_shift pull=24 push=8
176
diff --git a/utils/hwstub/stub/memmove.S b/utils/hwstub/stub/memmove.S
new file mode 100644
index 0000000000..d8cab048be
--- /dev/null
+++ b/utils/hwstub/stub/memmove.S
@@ -0,0 +1,190 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Free Software Foundation, Inc.
11 * This file was originally part of the GNU C Library
12 * Contributed to glibc by MontaVista Software, Inc. (written by Nicolas Pitre)
13 * Adapted for Rockbox by Daniel Ankers
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26
27/*
28 * Endian independent macros for shifting bytes within registers.
29 */
30#ifndef __ARMEB__
31#define pull lsr
32#define push lsl
33#else
34#define pull lsl
35#define push lsr
36#endif
37
38 .text
39
40/*
41 * Prototype: void *memmove(void *dest, const void *src, size_t n);
42 *
43 * Note:
44 *
45 * If the memory regions don't overlap, we simply branch to memcpy which is
46 * normally a bit faster. Otherwise the copy is done going downwards.
47 */
48
49 .section .icode,"ax",%progbits
50
51 .align 2
52 .global memmove
53 .type memmove,%function
54
55memmove:
56
57 subs ip, r0, r1
58 cmphi r2, ip
59 bls memcpy
60
61 stmfd sp!, {r0, r4, lr}
62 add r1, r1, r2
63 add r0, r0, r2
64 subs r2, r2, #4
65 blt 8f
66 ands ip, r0, #3
67 bne 9f
68 ands ip, r1, #3
69 bne 10f
70
711: subs r2, r2, #(28)
72 stmfd sp!, {r5 - r8}
73 blt 5f
74
752:
763:
774: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
78 subs r2, r2, #32
79 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
80 bge 3b
81
825: ands ip, r2, #28
83 rsb ip, ip, #32
84 addne pc, pc, ip @ C is always clear here
85 b 7f
866: nop
87 ldr r3, [r1, #-4]!
88 ldr r4, [r1, #-4]!
89 ldr r5, [r1, #-4]!
90 ldr r6, [r1, #-4]!
91 ldr r7, [r1, #-4]!
92 ldr r8, [r1, #-4]!
93 ldr lr, [r1, #-4]!
94
95 add pc, pc, ip
96 nop
97 nop
98 str r3, [r0, #-4]!
99 str r4, [r0, #-4]!
100 str r5, [r0, #-4]!
101 str r6, [r0, #-4]!
102 str r7, [r0, #-4]!
103 str r8, [r0, #-4]!
104 str lr, [r0, #-4]!
105
1067: ldmfd sp!, {r5 - r8}
107
1088: movs r2, r2, lsl #31
109 ldrneb r3, [r1, #-1]!
110 ldrcsb r4, [r1, #-1]!
111 ldrcsb ip, [r1, #-1]
112 strneb r3, [r0, #-1]!
113 strcsb r4, [r0, #-1]!
114 strcsb ip, [r0, #-1]
115 ldmpc regs="r0, r4"
116
1179: cmp ip, #2
118 ldrgtb r3, [r1, #-1]!
119 ldrgeb r4, [r1, #-1]!
120 ldrb lr, [r1, #-1]!
121 strgtb r3, [r0, #-1]!
122 strgeb r4, [r0, #-1]!
123 subs r2, r2, ip
124 strb lr, [r0, #-1]!
125 blt 8b
126 ands ip, r1, #3
127 beq 1b
128
12910: bic r1, r1, #3
130 cmp ip, #2
131 ldr r3, [r1, #0]
132 beq 17f
133 blt 18f
134
135
136 .macro backward_copy_shift push pull
137
138 subs r2, r2, #28
139 blt 14f
140
14111: stmfd sp!, {r5 - r9}
142
14312:
14413: ldmdb r1!, {r7, r8, r9, ip}
145 mov lr, r3, push #\push
146 subs r2, r2, #32
147 ldmdb r1!, {r3, r4, r5, r6}
148 orr lr, lr, ip, pull #\pull
149 mov ip, ip, push #\push
150 orr ip, ip, r9, pull #\pull
151 mov r9, r9, push #\push
152 orr r9, r9, r8, pull #\pull
153 mov r8, r8, push #\push
154 orr r8, r8, r7, pull #\pull
155 mov r7, r7, push #\push
156 orr r7, r7, r6, pull #\pull
157 mov r6, r6, push #\push
158 orr r6, r6, r5, pull #\pull
159 mov r5, r5, push #\push
160 orr r5, r5, r4, pull #\pull
161 mov r4, r4, push #\push
162 orr r4, r4, r3, pull #\pull
163 stmdb r0!, {r4 - r9, ip, lr}
164 bge 12b
165
166 ldmfd sp!, {r5 - r9}
167
16814: ands ip, r2, #28
169 beq 16f
170
17115: mov lr, r3, push #\push
172 ldr r3, [r1, #-4]!
173 subs ip, ip, #4
174 orr lr, lr, r3, pull #\pull
175 str lr, [r0, #-4]!
176 bgt 15b
177
17816: add r1, r1, #(\pull / 8)
179 b 8b
180
181 .endm
182
183
184 backward_copy_shift push=8 pull=24
185
18617: backward_copy_shift push=16 pull=16
187
18818: backward_copy_shift push=24 pull=8
189
190
diff --git a/utils/hwstub/stub/memory.h b/utils/hwstub/stub/memory.h
new file mode 100644
index 0000000000..206ed8604a
--- /dev/null
+++ b/utils/hwstub/stub/memory.h
@@ -0,0 +1,30 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_MEMORY__
22#define __HWSTUB_MEMORY__
23
24#include "stddef.h"
25
26void memset(void *dst, int c, size_t n);
27void memcpy(void *dst, const void *src, size_t n);
28void memmove(void *dst, const void *src, size_t n);
29
30#endif /* __HWSTUB_MEMORY__ */ \ No newline at end of file
diff --git a/utils/hwstub/stub/memset.S b/utils/hwstub/stub/memset.S
new file mode 100644
index 0000000000..682da874ce
--- /dev/null
+++ b/utils/hwstub/stub/memset.S
@@ -0,0 +1,98 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Thom Johansen
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22
23 .section .icode,"ax",%progbits
24
25 .align 2
26
27/* The following code is based on code found in Linux kernel version 2.6.15.3
28 * linux/arch/arm/lib/memset.S
29 *
30 * Copyright (C) 1995-2000 Russell King
31 */
32
33/* This code will align a pointer for memset, if needed */
341: cmp r2, #4 @ 1 do we have enough
35 blt 5f @ 1 bytes to align with?
36 cmp r3, #2 @ 1
37 strgtb r1, [r0, #-1]! @ 1
38 strgeb r1, [r0, #-1]! @ 1
39 strb r1, [r0, #-1]! @ 1
40 sub r2, r2, r3 @ 1 r2 = r2 - r3
41 b 2f
42
43 .global memset
44 .type memset,%function
45memset:
46 add r0, r0, r2 @ we'll write backwards in memory
47 ands r3, r0, #3 @ 1 unaligned?
48 bne 1b @ 1
492:
50/*
51 * we know that the pointer in r0 is aligned to a word boundary.
52 */
53 orr r1, r1, r1, lsl #8
54 orr r1, r1, r1, lsl #16
55 mov r3, r1
56 cmp r2, #16
57 blt 5f
58/*
59 * We need an extra register for this loop - save the return address and
60 * use the LR
61 */
62 str lr, [sp, #-4]!
63 mov ip, r1
64 mov lr, r1
65
663: subs r2, r2, #64
67 stmgedb r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
68 stmgedb r0!, {r1, r3, ip, lr}
69 stmgedb r0!, {r1, r3, ip, lr}
70 stmgedb r0!, {r1, r3, ip, lr}
71 bgt 3b
72 ldrpc cond=eq @ Now <64 bytes to go.
73/*
74 * No need to correct the count; we're only testing bits from now on
75 */
76 tst r2, #32
77 stmnedb r0!, {r1, r3, ip, lr}
78 stmnedb r0!, {r1, r3, ip, lr}
79 tst r2, #16
80 stmnedb r0!, {r1, r3, ip, lr}
81 ldr lr, [sp], #4
82
835: tst r2, #8
84 stmnedb r0!, {r1, r3}
85 tst r2, #4
86 strne r1, [r0, #-4]!
87/*
88 * When we get here, we've got less than 4 bytes to zero. We
89 * may have an unaligned pointer as well.
90 */
916: tst r2, #2
92 strneb r1, [r0, #-1]!
93 strneb r1, [r0, #-1]!
94 tst r2, #1
95 strneb r1, [r0, #-1]!
96 bx lr
97.end:
98 .size memset,.end-memset
diff --git a/utils/hwstub/stub/protocol.h b/utils/hwstub/stub/protocol.h
new file mode 100644
index 0000000000..35510fa9b2
--- /dev/null
+++ b/utils/hwstub/stub/protocol.h
@@ -0,0 +1 @@
#include "../hwstub_protocol.h"
diff --git a/utils/hwstub/stub/stddef.h b/utils/hwstub/stub/stddef.h
new file mode 100644
index 0000000000..9bfd767750
--- /dev/null
+++ b/utils/hwstub/stub/stddef.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_STDDEF__
22#define __HWSTUB_STDDEF__
23
24#include "stdint.h"
25
26typedef uint32_t size_t;
27typedef int32_t ssize_t;
28
29#define MIN(a, b) ((a) < (b) ? (a) : (b))
30#define MAX(a, b) ((a) > (b) ? (a) : (b))
31
32#endif /* __HWSTUB_STDDEF__ */
diff --git a/utils/hwstub/stub/stdint.h b/utils/hwstub/stub/stdint.h
new file mode 100644
index 0000000000..393ff3fffd
--- /dev/null
+++ b/utils/hwstub/stub/stdint.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __STDINT_H__
23#define __STDINT_H__
24
25typedef signed char int8_t;
26typedef unsigned char uint8_t;
27typedef short int16_t;
28typedef unsigned short uint16_t;
29typedef long int32_t;
30typedef unsigned long uint32_t;
31typedef unsigned long long uint64_t;
32typedef uint32_t intptr_t;
33typedef char bool;
34
35#define true 1
36#define false 0
37
38#define NULL (void *)0
39
40#endif /* __STDINT_H__ */
diff --git a/utils/hwstub/stub/stmp/Makefile b/utils/hwstub/stub/stmp/Makefile
new file mode 100644
index 0000000000..14e6d0fbba
--- /dev/null
+++ b/utils/hwstub/stub/stmp/Makefile
@@ -0,0 +1,14 @@
1#
2# common
3#
4CC=arm-elf-eabi-gcc
5LD=arm-elf-eabi-gcc
6AS=arm-elf-eabi-gcc
7OC=arm-elf-eabi-objcopy
8DEFINES=
9INCLUDES=-I$(CURDIR)
10GCCOPTS=-mcpu=arm926ej-s
11BUILD_DIR=$(CURDIR)/build/
12ROOT_DIR=$(CURDIR)/..
13
14include ../hwstub.make \ No newline at end of file
diff --git a/utils/hwstub/stub/stmp/target-config.h b/utils/hwstub/stub/stmp/target-config.h
new file mode 100644
index 0000000000..aba2cf564b
--- /dev/null
+++ b/utils/hwstub/stub/stmp/target-config.h
@@ -0,0 +1,9 @@
1#define CONFIG_STMP
2#define IRAM_ORIG 0
3#define IRAM_SIZE 0x8000
4#define DRAM_ORIG 0x40000000
5#define DRAM_SIZE (MEMORYSIZE * 0x100000)
6#define CPU_ARM
7#define ARM_ARCH 5
8#define USB_BASE 0x80080000
9#define USB_NUM_ENDPOINTS 2 \ No newline at end of file
diff --git a/utils/hwstub/stub/stmp/target.c b/utils/hwstub/stub/stmp/target.c
new file mode 100644
index 0000000000..60411f908e
--- /dev/null
+++ b/utils/hwstub/stub/stmp/target.c
@@ -0,0 +1,205 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "stddef.h"
22#include "target.h"
23#include "system.h"
24#include "logf.h"
25
26#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1)))
27#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2)))
28#define __REG_TOG(reg) (*((volatile uint32_t *)(&reg + 3)))
29
30#define __BLOCK_SFTRST (1 << 31)
31#define __BLOCK_CLKGATE (1 << 30)
32
33#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP)
34#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP)
35#define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP)
36
37/**
38 *
39 * Global
40 *
41 */
42
43enum stmp_family_t
44{
45 UNKNOWN,
46 STMP3600,
47 STMP3700,
48 STMP3770,
49 STMP3780
50};
51
52enum stmp_family_t g_stmp_family = UNKNOWN;
53
54/**
55 *
56 * Clkctrl
57 *
58 */
59
60#define HW_CLKCTRL_BASE 0x80040000
61
62#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
63#define HW_CLKCTRL_PLLCTRL0__BYPASS (1 << 17) /* STMP3600 only */
64#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
65#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
66
67#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
68#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
69
70/* STMP3600 only */
71#define HW_CLKCTRL_CPUCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
72#define HW_CLKCTRL_CPUCLKCTRL__DIV_BP 0
73#define HW_CLKCTRL_CPUCLKCTRL__DIV_BM 0x3ff
74#define HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK (1 << 30)
75
76/* STMP3600 */
77#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
78
79/* STMP3600 only */
80#define HW_CLKCTRL_XBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
81#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BP 0
82#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BM 0x3ff
83
84/* STMP3600 only */
85#define HW_CLKCTRL_UTMICLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
86#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
87#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
88
89/**
90 *
91 * Digctl
92 *
93 */
94
95/* Digital control */
96#define HW_DIGCTL_BASE 0x8001C000
97#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
98#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
99
100#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
101
102#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
103#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16
104#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BM 0xffff0000
105#define HW_DIGCTL_CHIPID__REVISION_BP 0
106#define HW_DIGCTL_CHIPID__REVISION_BM 0xff
107
108#define HZ 1000000
109
110/**
111 *
112 * USB PHY
113 *
114 */
115/* USB Phy */
116#define HW_USBPHY_BASE 0x8007C000
117#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
118
119#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
120
121void target_init(void)
122{
123 /* detect family */
124 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
125 if(product_code >= 0x3600 && product_code < 0x3700)
126 {
127 logf("identified STMP3600 family\n");
128 g_stmp_family = STMP3600;
129 }
130 else if(product_code == 0x3700)
131 {
132 logf("identified STMP3700 family\n");
133 g_stmp_family = STMP3700;
134 }
135 else if(product_code == 0x37b0)
136 {
137 logf("identified STMP3770 family\n");
138 g_stmp_family = STMP3770;
139 }
140 else if(product_code == 0x3780)
141 {
142 logf("identified STMP3780 family\n");
143 g_stmp_family = STMP3780;
144 }
145 else
146 logf("cannot identify family: 0x%x\n", product_code);
147
148 if(g_stmp_family == STMP3600)
149 {
150 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
151 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
152 * (1.2MHz) for a safe transition */
153 HW_CLKCTRL_CPUCLKCTRL = HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK | 400;
154 /* We need to ensure that XBUS < HBUS but HBUS will be 1.2 MHz after the
155 * switch so lower XBUS too */
156 HW_CLKCTRL_XBUSCLKCTRL = 20;
157 /* Power PLL */
158 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
159 HW_CLKCTRL_PLLCTRL0 = (HW_CLKCTRL_PLLCTRL0 & ~0x3ff) | 480;
160 /* Wait lock */
161 while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
162 /* Switch to PLL source */
163 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__BYPASS;
164 /* Get back XBUS = 24 MHz and CPU = HBUS = 64MHz */
165 HW_CLKCTRL_CPUCLKCTRL = 7;
166 HW_CLKCTRL_HBUSCLKCTRL = 7;
167 HW_CLKCTRL_XBUSCLKCTRL = 1;
168 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE;
169 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
170 }
171 else
172 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
173 /* enable USB PHY PLL */
174 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
175 /* power up USB PHY */
176 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
177 HW_USBPHY_PWD = 0;
178 /* enable USB controller */
179 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
180}
181
182static struct usb_resp_info_stmp_t g_stmp;
183static struct usb_resp_info_target_t g_target =
184{
185 .id = HWSTUB_TARGET_STMP,
186 .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)"
187};
188
189int target_get_info(int info, void **buffer)
190{
191 if(info == HWSTUB_INFO_STMP)
192 {
193 g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
194 g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
195 g_stmp.is_supported = g_stmp_family != 0;
196 *buffer = &g_stmp;
197 return sizeof(g_stmp);
198 }
199 else
200 return -1;
201}
202
203void target_exit(void)
204{
205}
diff --git a/utils/hwstub/stub/string.c b/utils/hwstub/stub/string.c
new file mode 100644
index 0000000000..1f8c415a99
--- /dev/null
+++ b/utils/hwstub/stub/string.c
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "string.h"
22
23size_t strlen(const char *s)
24{
25 size_t len = 0;
26 while(*s++)
27 len++;
28 return len;
29}
diff --git a/utils/hwstub/stub/string.h b/utils/hwstub/stub/string.h
new file mode 100644
index 0000000000..ae352fe50e
--- /dev/null
+++ b/utils/hwstub/stub/string.h
@@ -0,0 +1,28 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_STRING__
22#define __HWSTUB_STRING__
23
24#include "stddef.h"
25
26size_t strlen(const char *s);
27
28#endif /* __HWSTUB_STRING__ */
diff --git a/utils/hwstub/stub/system.h b/utils/hwstub/stub/system.h
new file mode 100644
index 0000000000..e5aea12051
--- /dev/null
+++ b/utils/hwstub/stub/system.h
@@ -0,0 +1,118 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __HWSTUB_SYSTEM__
22#define __HWSTUB_SYSTEM__
23
24#define IRQ_ENABLED 0x00
25#define IRQ_DISABLED 0x80
26#define IRQ_STATUS 0x80
27#define FIQ_ENABLED 0x00
28#define FIQ_DISABLED 0x40
29#define FIQ_STATUS 0x40
30#define IRQ_FIQ_ENABLED 0x00
31#define IRQ_FIQ_DISABLED 0xc0
32#define IRQ_FIQ_STATUS 0xc0
33#define HIGHEST_IRQ_LEVEL IRQ_DISABLED
34
35#define set_irq_level(status) \
36 set_interrupt_status((status), IRQ_STATUS)
37#define set_fiq_status(status) \
38 set_interrupt_status((status), FIQ_STATUS)
39
40#define disable_irq_save() \
41 disable_interrupt_save(IRQ_STATUS)
42#define disable_fiq_save() \
43 disable_interrupt_save(FIQ_STATUS)
44
45#define restore_irq(cpsr) \
46 restore_interrupt(cpsr)
47#define restore_fiq(cpsr) \
48 restore_interrupt(cpsr)
49
50#define disable_irq() \
51 disable_interrupt(IRQ_STATUS)
52#define enable_irq() \
53 enable_interrupt(IRQ_STATUS)
54#define disable_fiq() \
55 disable_interrupt(FIQ_STATUS)
56#define enable_fiq() \
57 enable_interrupt(FIQ_STATUS)
58
59static inline int set_interrupt_status(int status, int mask)
60{
61 unsigned long cpsr;
62 int oldstatus;
63 /* Read the old levels and set the new ones */
64 asm volatile (
65 "mrs %1, cpsr \n"
66 "bic %0, %1, %[mask] \n"
67 "orr %0, %0, %2 \n"
68 "msr cpsr_c, %0 \n"
69 : "=&r,r"(cpsr), "=&r,r"(oldstatus)
70 : "r,i"(status & mask), [mask]"i,i"(mask));
71
72 return oldstatus;
73}
74
75static inline void restore_interrupt(int cpsr)
76{
77 /* Set cpsr_c from value returned by disable_interrupt_save
78 * or set_interrupt_status */
79 asm volatile ("msr cpsr_c, %0" : : "r"(cpsr));
80}
81
82static inline void enable_interrupt(int mask)
83{
84 /* Clear I and/or F disable bit */
85 int tmp;
86 asm volatile (
87 "mrs %0, cpsr \n"
88 "bic %0, %0, %1 \n"
89 "msr cpsr_c, %0 \n"
90 : "=&r"(tmp) : "i"(mask));
91}
92
93static inline void disable_interrupt(int mask)
94{
95 /* Set I and/or F disable bit */
96 int tmp;
97 asm volatile (
98 "mrs %0, cpsr \n"
99 "orr %0, %0, %1 \n"
100 "msr cpsr_c, %0 \n"
101 : "=&r"(tmp) : "i"(mask));
102}
103
104static inline int disable_interrupt_save(int mask)
105{
106 /* Set I and/or F disable bit and return old cpsr value */
107 int cpsr, tmp;
108 asm volatile (
109 "mrs %1, cpsr \n"
110 "orr %0, %1, %2 \n"
111 "msr cpsr_c, %0 \n"
112 : "=&r"(tmp), "=&r"(cpsr)
113 : "i"(mask));
114 return cpsr;
115}
116
117#endif /* __HWSTUB_SYSTEM__ */
118
diff --git a/utils/hwstub/stub/target.h b/utils/hwstub/stub/target.h
new file mode 100644
index 0000000000..3f1551c72d
--- /dev/null
+++ b/utils/hwstub/stub/target.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __TARGET_H__
22#define __TARGET_H__
23
24#include "protocol.h"
25
26void target_init(void);
27void target_exit(void);
28/* return actual size or -1 if error */
29int target_get_info(int info, void **buffer);
30
31#endif /* __TARGET_H__ */
diff --git a/utils/hwstub/stub/usb_ch9.h b/utils/hwstub/stub/usb_ch9.h
new file mode 100644
index 0000000000..09141b93bd
--- /dev/null
+++ b/utils/hwstub/stub/usb_ch9.h
@@ -0,0 +1,454 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) by Linux Kernel Developers
11 *
12 * Based on code from the Linux Kernel
13 * available at http://www.kernel.org
14 * Original file: <kernel>/include/linux/usb/ch9.h
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26/*
27 * This file holds USB constants and structures that are needed for
28 * USB device APIs. These are used by the USB device model, which is
29 * defined in chapter 9 of the USB 2.0 specification and in the
30 * Wireless USB 1.0 (spread around). Linux has several APIs in C that
31 * need these:
32 *
33 * - the master/host side Linux-USB kernel driver API;
34 * - the "usbfs" user space API; and
35 * - the Linux "gadget" slave/device/peripheral side driver API.
36 *
37 * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
38 * act either as a USB master/host or as a USB slave/device. That means
39 * the master and slave side APIs benefit from working well together.
40 *
41 * There's also "Wireless USB", using low power short range radios for
42 * peripheral interconnection but otherwise building on the USB framework.
43 *
44 * Note all descriptors are declared '__attribute__((packed))' so that:
45 *
46 * [a] they never get padded, either internally (USB spec writers
47 * probably handled that) or externally;
48 *
49 * [b] so that accessing bigger-than-a-bytes fields will never
50 * generate bus errors on any platform, even when the location of
51 * its descriptor inside a bundle isn't "naturally aligned", and
52 *
53 * [c] for consistency, removing all doubt even when it appears to
54 * someone that the two other points are non-issues for that
55 * particular descriptor type.
56 */
57
58#ifndef _CH9_H_
59#define _CH9_H_
60
61#include "stdint.h"
62
63/*-------------------------------------------------------------------------*/
64
65/* CONTROL REQUEST SUPPORT */
66
67/*
68 * USB directions
69 *
70 * This bit flag is used in endpoint descriptors' bEndpointAddress field.
71 * It's also one of three fields in control requests bRequestType.
72 */
73#define USB_DIR_OUT 0 /* to device */
74#define USB_DIR_IN 0x80 /* to host */
75
76/*
77 * USB types, the second of three bRequestType fields
78 */
79#define USB_TYPE_MASK (0x03 << 5)
80#define USB_TYPE_STANDARD (0x00 << 5)
81#define USB_TYPE_CLASS (0x01 << 5)
82#define USB_TYPE_VENDOR (0x02 << 5)
83#define USB_TYPE_RESERVED (0x03 << 5)
84
85/*
86 * USB recipients, the third of three bRequestType fields
87 */
88#define USB_RECIP_MASK 0x1f
89#define USB_RECIP_DEVICE 0x00
90#define USB_RECIP_INTERFACE 0x01
91#define USB_RECIP_ENDPOINT 0x02
92#define USB_RECIP_OTHER 0x03
93
94/*
95 * Standard requests, for the bRequest field of a SETUP packet.
96 *
97 * These are qualified by the bRequestType field, so that for example
98 * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
99 * by a GET_STATUS request.
100 */
101#define USB_REQ_GET_STATUS 0x00
102#define USB_REQ_CLEAR_FEATURE 0x01
103#define USB_REQ_SET_FEATURE 0x03
104#define USB_REQ_SET_ADDRESS 0x05
105#define USB_REQ_GET_DESCRIPTOR 0x06
106#define USB_REQ_SET_DESCRIPTOR 0x07
107#define USB_REQ_GET_CONFIGURATION 0x08
108#define USB_REQ_SET_CONFIGURATION 0x09
109#define USB_REQ_GET_INTERFACE 0x0A
110#define USB_REQ_SET_INTERFACE 0x0B
111#define USB_REQ_SYNCH_FRAME 0x0C
112/*
113 * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
114 * are read as a bit array returned by USB_REQ_GET_STATUS. (So there
115 * are at most sixteen features of each type.) Hubs may also support a
116 * new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend.
117 */
118#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
119#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
120#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
121#define USB_DEVICE_BATTERY 2 /* (wireless) */
122#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
123#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
124#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
125#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
126#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
127
128#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
129
130
131/**
132 * struct usb_ctrlrequest - SETUP data for a USB device control request
133 * @bRequestType: matches the USB bmRequestType field
134 * @bRequest: matches the USB bRequest field
135 * @wValue: matches the USB wValue field (le16 byte order)
136 * @wIndex: matches the USB wIndex field (le16 byte order)
137 * @wLength: matches the USB wLength field (le16 byte order)
138 *
139 * This structure is used to send control requests to a USB device. It matches
140 * the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
141 * USB spec for a fuller description of the different fields, and what they are
142 * used for.
143 *
144 * Note that the driver for any interface can issue control requests.
145 * For most devices, interfaces don't coordinate with each other, so
146 * such requests may be made at any time.
147 */
148struct usb_ctrlrequest {
149 uint8_t bRequestType;
150 uint8_t bRequest;
151 uint16_t wValue;
152 uint16_t wIndex;
153 uint16_t wLength;
154} __attribute__ ((packed));
155
156/*-------------------------------------------------------------------------*/
157
158/*
159 * STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
160 * (rarely) accepted by SET_DESCRIPTOR.
161 *
162 * Note that all multi-byte values here are encoded in little endian
163 * byte order "on the wire". But when exposed through Linux-USB APIs,
164 * they've been converted to cpu byte order.
165 */
166
167/*
168 * Descriptor types ... USB 2.0 spec table 9.5
169 */
170#define USB_DT_DEVICE 0x01
171#define USB_DT_CONFIG 0x02
172#define USB_DT_STRING 0x03
173#define USB_DT_INTERFACE 0x04
174#define USB_DT_ENDPOINT 0x05
175#define USB_DT_DEVICE_QUALIFIER 0x06
176#define USB_DT_OTHER_SPEED_CONFIG 0x07
177#define USB_DT_INTERFACE_POWER 0x08
178/* these are from a minor usb 2.0 revision (ECN) */
179#define USB_DT_OTG 0x09
180#define USB_DT_DEBUG 0x0a
181#define USB_DT_INTERFACE_ASSOCIATION 0x0b
182/* these are from the Wireless USB spec */
183#define USB_DT_SECURITY 0x0c
184#define USB_DT_KEY 0x0d
185#define USB_DT_ENCRYPTION_TYPE 0x0e
186#define USB_DT_BOS 0x0f
187#define USB_DT_DEVICE_CAPABILITY 0x10
188#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
189#define USB_DT_WIRE_ADAPTER 0x21
190#define USB_DT_RPIPE 0x22
191#define USB_DT_CS_RADIO_CONTROL 0x23
192
193/* Conventional codes for class-specific descriptors. The convention is
194 * defined in the USB "Common Class" Spec (3.11). Individual class specs
195 * are authoritative for their usage, not the "common class" writeup.
196 */
197#define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE)
198#define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG)
199#define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING)
200#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE)
201#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT)
202
203/* All standard descriptors have these 2 fields at the beginning */
204struct usb_descriptor_header {
205 uint8_t bLength;
206 uint8_t bDescriptorType;
207} __attribute__ ((packed));
208
209
210/*-------------------------------------------------------------------------*/
211
212/* USB_DT_DEVICE: Device descriptor */
213struct usb_device_descriptor {
214 uint8_t bLength;
215 uint8_t bDescriptorType;
216
217 uint16_t bcdUSB;
218 uint8_t bDeviceClass;
219 uint8_t bDeviceSubClass;
220 uint8_t bDeviceProtocol;
221 uint8_t bMaxPacketSize0;
222 uint16_t idVendor;
223 uint16_t idProduct;
224 uint16_t bcdDevice;
225 uint8_t iManufacturer;
226 uint8_t iProduct;
227 uint8_t iSerialNumber;
228 uint8_t bNumConfigurations;
229} __attribute__ ((packed));
230
231#define USB_DT_DEVICE_SIZE 18
232
233
234/*
235 * Device and/or Interface Class codes
236 * as found in bDeviceClass or bInterfaceClass
237 * and defined by www.usb.org documents
238 */
239#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
240#define USB_CLASS_AUDIO 1
241#define USB_CLASS_COMM 2
242#define USB_CLASS_HID 3
243#define USB_CLASS_PHYSICAL 5
244#define USB_CLASS_STILL_IMAGE 6
245#define USB_CLASS_PRINTER 7
246#define USB_CLASS_MASS_STORAGE 8
247#define USB_CLASS_HUB 9
248#define USB_CLASS_CDC_DATA 0x0a
249#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
250#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
251#define USB_CLASS_VIDEO 0x0e
252#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
253#define USB_CLASS_MISC 0xef
254#define USB_CLASS_APP_SPEC 0xfe
255#define USB_CLASS_VENDOR_SPEC 0xff
256
257/*-------------------------------------------------------------------------*/
258
259/* USB_DT_CONFIG: Configuration descriptor information.
260 *
261 * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
262 * descriptor type is different. Highspeed-capable devices can look
263 * different depending on what speed they're currently running. Only
264 * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
265 * descriptors.
266 */
267struct usb_config_descriptor {
268 uint8_t bLength;
269 uint8_t bDescriptorType;
270
271 uint16_t wTotalLength;
272 uint8_t bNumInterfaces;
273 uint8_t bConfigurationValue;
274 uint8_t iConfiguration;
275 uint8_t bmAttributes;
276 uint8_t bMaxPower;
277} __attribute__ ((packed));
278
279#define USB_DT_CONFIG_SIZE 9
280
281/* from config descriptor bmAttributes */
282#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
283#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
284#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
285#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */
286
287/*-------------------------------------------------------------------------*/
288
289/* USB_DT_STRING: String descriptor */
290struct usb_string_descriptor {
291 uint8_t bLength;
292 uint8_t bDescriptorType;
293
294 uint16_t wString[]; /* UTF-16LE encoded */
295} __attribute__ ((packed));
296
297/* note that "string" zero is special, it holds language codes that
298 * the device supports, not Unicode characters.
299 */
300
301/*-------------------------------------------------------------------------*/
302
303/* USB_DT_INTERFACE: Interface descriptor */
304struct usb_interface_descriptor {
305 uint8_t bLength;
306 uint8_t bDescriptorType;
307
308 uint8_t bInterfaceNumber;
309 uint8_t bAlternateSetting;
310 uint8_t bNumEndpoints;
311 uint8_t bInterfaceClass;
312 uint8_t bInterfaceSubClass;
313 uint8_t bInterfaceProtocol;
314 uint8_t iInterface;
315} __attribute__ ((packed));
316
317#define USB_DT_INTERFACE_SIZE 9
318
319/*-------------------------------------------------------------------------*/
320
321/* USB_DT_ENDPOINT: Endpoint descriptor */
322struct usb_endpoint_descriptor {
323 uint8_t bLength;
324 uint8_t bDescriptorType;
325
326 uint8_t bEndpointAddress;
327 uint8_t bmAttributes;
328 uint16_t wMaxPacketSize;
329 uint8_t bInterval;
330} __attribute__ ((packed));
331
332#define USB_DT_ENDPOINT_SIZE 7
333#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
334
335
336/*
337 * Endpoints
338 */
339#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
340#define USB_ENDPOINT_DIR_MASK 0x80
341
342#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
343#define USB_ENDPOINT_XFER_CONTROL 0
344#define USB_ENDPOINT_XFER_ISOC 1
345#define USB_ENDPOINT_XFER_BULK 2
346#define USB_ENDPOINT_XFER_INT 3
347#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
348
349
350/*-------------------------------------------------------------------------*/
351
352/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
353struct usb_qualifier_descriptor {
354 uint8_t bLength;
355 uint8_t bDescriptorType;
356
357 uint16_t bcdUSB;
358 uint8_t bDeviceClass;
359 uint8_t bDeviceSubClass;
360 uint8_t bDeviceProtocol;
361 uint8_t bMaxPacketSize0;
362 uint8_t bNumConfigurations;
363 uint8_t bRESERVED;
364} __attribute__ ((packed));
365
366
367/*-------------------------------------------------------------------------*/
368
369/* USB_DT_OTG (from OTG 1.0a supplement) */
370struct usb_otg_descriptor {
371 uint8_t bLength;
372 uint8_t bDescriptorType;
373
374 uint8_t bmAttributes; /* support for HNP, SRP, etc */
375} __attribute__ ((packed));
376
377/* from usb_otg_descriptor.bmAttributes */
378#define USB_OTG_SRP (1 << 0)
379#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
380
381/*-------------------------------------------------------------------------*/
382
383/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
384struct usb_debug_descriptor {
385 uint8_t bLength;
386 uint8_t bDescriptorType;
387
388 /* bulk endpoints with 8 byte maxpacket */
389 uint8_t bDebugInEndpoint;
390 uint8_t bDebugOutEndpoint;
391} __attribute__((packed));
392
393/*-------------------------------------------------------------------------*/
394/* USB 2.0 defines three speeds, here's how Linux identifies them */
395
396enum usb_device_speed {
397 USB_SPEED_UNKNOWN = 0, /* enumerating */
398 USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
399 USB_SPEED_HIGH, /* usb 2.0 */
400 USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
401};
402
403enum usb_device_state {
404 /* NOTATTACHED isn't in the USB spec, and this state acts
405 * the same as ATTACHED ... but it's clearer this way.
406 */
407 USB_STATE_NOTATTACHED = 0,
408
409 /* chapter 9 and authentication (wireless) device states */
410 USB_STATE_ATTACHED,
411 USB_STATE_POWERED, /* wired */
412 USB_STATE_UNAUTHENTICATED, /* auth */
413 USB_STATE_RECONNECTING, /* auth */
414 USB_STATE_DEFAULT, /* limited function */
415 USB_STATE_ADDRESS,
416 USB_STATE_CONFIGURED, /* most functions */
417
418 USB_STATE_SUSPENDED
419
420 /* NOTE: there are actually four different SUSPENDED
421 * states, returning to POWERED, DEFAULT, ADDRESS, or
422 * CONFIGURED respectively when SOF tokens flow again.
423 * At this level there's no difference between L1 and L2
424 * suspend states. (L2 being original USB 1.1 suspend.)
425 */
426};
427
428/**
429 * struct usb_string - wraps a C string and its USB id
430 * @id:the (nonzero) ID for this string
431 * @s:the string, in UTF-8 encoding
432 *
433 * If you're using usb_gadget_get_string(), use this to wrap a string
434 * together with its ID.
435 */
436struct usb_string {
437 uint8_t id;
438 const char* s;
439};
440
441/**
442 * struct usb_gadget_strings - a set of USB strings in a given language
443 * @language:identifies the strings' language (0x0409 for en-us)
444 * @strings:array of strings with their ids
445 *
446 * If you're using usb_gadget_get_string(), use this to wrap all the
447 * strings for a given language.
448 */
449struct usb_gadget_strings {
450 uint16_t language; /* 0x0409 for en-us */
451 struct usb_string* strings;
452};
453
454#endif /*_CH9_H_*/
diff --git a/utils/hwstub/stub/usb_drv.h b/utils/hwstub/stub/usb_drv.h
new file mode 100644
index 0000000000..00f22d8e1a
--- /dev/null
+++ b/utils/hwstub/stub/usb_drv.h
@@ -0,0 +1,47 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Björn Stenberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _USB_DRV_H
22#define _USB_DRV_H
23
24#include "usb_ch9.h"
25
26#define EP_CONTROL 0
27
28#define DIR_OUT 0
29#define DIR_IN 1
30
31#define EP_DIR(ep) (((ep) & USB_ENDPOINT_DIR_MASK) ? DIR_IN : DIR_OUT)
32#define EP_NUM(ep) ((ep) & USB_ENDPOINT_NUMBER_MASK)
33
34void usb_drv_init(void);
35void usb_drv_exit(void);
36void usb_drv_stall(int endpoint, bool stall,bool in);
37int usb_drv_send(int endpoint, void* ptr, int length);
38int usb_drv_send_nonblocking(int endpoint, void* ptr, int length);
39int usb_drv_recv(int endpoint, void* ptr, int length);// blocking !
40int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length);
41int usb_drv_recv_setup(struct usb_ctrlrequest *req);
42void usb_drv_set_address(int address);
43int usb_drv_port_speed(void);
44void usb_drv_configure_endpoint(int ep_num, int type);
45
46#endif /* _USB_DRV_H */
47
diff --git a/utils/hwstub/stub/usb_drv_arc.c b/utils/hwstub/stub/usb_drv_arc.c
new file mode 100644
index 0000000000..32275b6adb
--- /dev/null
+++ b/utils/hwstub/stub/usb_drv_arc.c
@@ -0,0 +1,364 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Driver for ARC USBOTG Device Controller
11 *
12 * Copyright (C) 2007 by Björn Stenberg
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "usb_drv.h"
24#include "config.h"
25#include "memory.h"
26
27#define MAX_PKT_SIZE 1024
28#define MAX_PKT_SIZE_EP0 64
29
30/* USB device mode registers (Little Endian) */
31#define REG_USBCMD (*(volatile unsigned int *)(USB_BASE+0x140))
32#define REG_DEVICEADDR (*(volatile unsigned int *)(USB_BASE+0x154))
33#define REG_ENDPOINTLISTADDR (*(volatile unsigned int *)(USB_BASE+0x158))
34#define REG_PORTSC1 (*(volatile unsigned int *)(USB_BASE+0x184))
35#define REG_USBMODE (*(volatile unsigned int *)(USB_BASE+0x1a8))
36#define REG_ENDPTSETUPSTAT (*(volatile unsigned int *)(USB_BASE+0x1ac))
37#define REG_ENDPTPRIME (*(volatile unsigned int *)(USB_BASE+0x1b0))
38#define REG_ENDPTSTATUS (*(volatile unsigned int *)(USB_BASE+0x1b8))
39#define REG_ENDPTCOMPLETE (*(volatile unsigned int *)(USB_BASE+0x1bc))
40#define REG_ENDPTCTRL0 (*(volatile unsigned int *)(USB_BASE+0x1c0))
41#define REG_ENDPTCTRL1 (*(volatile unsigned int *)(USB_BASE+0x1c4))
42#define REG_ENDPTCTRL2 (*(volatile unsigned int *)(USB_BASE+0x1c8))
43#define REG_ENDPTCTRL(_x_) (*(volatile unsigned int *)(USB_BASE+0x1c0+4*(_x_)))
44
45/* USB CMD Register Bit Masks */
46#define USBCMD_RUN (0x00000001)
47#define USBCMD_CTRL_RESET (0x00000002)
48#define USBCMD_PERIODIC_SCHEDULE_EN (0x00000010)
49#define USBCMD_ASYNC_SCHEDULE_EN (0x00000020)
50#define USBCMD_INT_AA_DOORBELL (0x00000040)
51#define USBCMD_ASP (0x00000300)
52#define USBCMD_ASYNC_SCH_PARK_EN (0x00000800)
53#define USBCMD_SUTW (0x00002000)
54#define USBCMD_ATDTW (0x00004000)
55#define USBCMD_ITC (0x00FF0000)
56
57/* Device Address bit masks */
58#define USBDEVICEADDRESS_MASK (0xFE000000)
59#define USBDEVICEADDRESS_BIT_POS (25)
60
61/* Endpoint Setup Status bit masks */
62#define EPSETUP_STATUS_EP0 (0x00000001)
63
64/* PORTSCX Register Bit Masks */
65#define PORTSCX_CURRENT_CONNECT_STATUS (0x00000001)
66#define PORTSCX_CONNECT_STATUS_CHANGE (0x00000002)
67#define PORTSCX_PORT_ENABLE (0x00000004)
68#define PORTSCX_PORT_EN_DIS_CHANGE (0x00000008)
69#define PORTSCX_OVER_CURRENT_ACT (0x00000010)
70#define PORTSCX_OVER_CURRENT_CHG (0x00000020)
71#define PORTSCX_PORT_FORCE_RESUME (0x00000040)
72#define PORTSCX_PORT_SUSPEND (0x00000080)
73#define PORTSCX_PORT_RESET (0x00000100)
74#define PORTSCX_LINE_STATUS_BITS (0x00000C00)
75#define PORTSCX_PORT_POWER (0x00001000)
76#define PORTSCX_PORT_INDICTOR_CTRL (0x0000C000)
77#define PORTSCX_PORT_TEST_CTRL (0x000F0000)
78#define PORTSCX_WAKE_ON_CONNECT_EN (0x00100000)
79#define PORTSCX_WAKE_ON_CONNECT_DIS (0x00200000)
80#define PORTSCX_WAKE_ON_OVER_CURRENT (0x00400000)
81#define PORTSCX_PHY_LOW_POWER_SPD (0x00800000)
82#define PORTSCX_PORT_FORCE_FULL_SPEED (0x01000000)
83#define PORTSCX_PORT_SPEED_MASK (0x0C000000)
84#define PORTSCX_PORT_WIDTH (0x10000000)
85#define PORTSCX_PHY_TYPE_SEL (0xC0000000)
86
87/* bit 11-10 are line status */
88#define PORTSCX_LINE_STATUS_SE0 (0x00000000)
89#define PORTSCX_LINE_STATUS_JSTATE (0x00000400)
90#define PORTSCX_LINE_STATUS_KSTATE (0x00000800)
91#define PORTSCX_LINE_STATUS_UNDEF (0x00000C00)
92#define PORTSCX_LINE_STATUS_BIT_POS (10)
93
94/* bit 15-14 are port indicator control */
95#define PORTSCX_PIC_OFF (0x00000000)
96#define PORTSCX_PIC_AMBER (0x00004000)
97#define PORTSCX_PIC_GREEN (0x00008000)
98#define PORTSCX_PIC_UNDEF (0x0000C000)
99#define PORTSCX_PIC_BIT_POS (14)
100
101/* bit 19-16 are port test control */
102#define PORTSCX_PTC_DISABLE (0x00000000)
103#define PORTSCX_PTC_JSTATE (0x00010000)
104#define PORTSCX_PTC_KSTATE (0x00020000)
105#define PORTSCX_PTC_SE0NAK (0x00030000)
106#define PORTSCX_PTC_PACKET (0x00040000)
107#define PORTSCX_PTC_FORCE_EN (0x00050000)
108#define PORTSCX_PTC_BIT_POS (16)
109
110/* bit 27-26 are port speed */
111#define PORTSCX_PORT_SPEED_FULL (0x00000000)
112#define PORTSCX_PORT_SPEED_LOW (0x04000000)
113#define PORTSCX_PORT_SPEED_HIGH (0x08000000)
114#define PORTSCX_PORT_SPEED_UNDEF (0x0C000000)
115#define PORTSCX_SPEED_BIT_POS (26)
116
117/* bit 28 is parallel transceiver width for UTMI interface */
118#define PORTSCX_PTW (0x10000000)
119#define PORTSCX_PTW_8BIT (0x00000000)
120#define PORTSCX_PTW_16BIT (0x10000000)
121
122/* bit 31-30 are port transceiver select */
123#define PORTSCX_PTS_UTMI (0x00000000)
124#define PORTSCX_PTS_CLASSIC (0x40000000)
125#define PORTSCX_PTS_ULPI (0x80000000)
126#define PORTSCX_PTS_FSLS (0xC0000000)
127#define PORTSCX_PTS_BIT_POS (30)
128
129/* USB MODE Register Bit Masks */
130#define USBMODE_CTRL_MODE_IDLE (0x00000000)
131#define USBMODE_CTRL_MODE_DEVICE (0x00000002)
132#define USBMODE_CTRL_MODE_HOST (0x00000003)
133#define USBMODE_CTRL_MODE_RSV (0x00000001)
134#define USBMODE_SETUP_LOCK_OFF (0x00000008)
135#define USBMODE_STREAM_DISABLE (0x00000010)
136
137/* ENDPOINTCTRLx Register Bit Masks */
138#define EPCTRL_TX_ENABLE (0x00800000)
139#define EPCTRL_TX_DATA_TOGGLE_RST (0x00400000) /* Not EP0 */
140#define EPCTRL_TX_DATA_TOGGLE_INH (0x00200000) /* Not EP0 */
141#define EPCTRL_TX_TYPE (0x000C0000)
142#define EPCTRL_TX_DATA_SOURCE (0x00020000) /* Not EP0 */
143#define EPCTRL_TX_EP_STALL (0x00010000)
144#define EPCTRL_RX_ENABLE (0x00000080)
145#define EPCTRL_RX_DATA_TOGGLE_RST (0x00000040) /* Not EP0 */
146#define EPCTRL_RX_DATA_TOGGLE_INH (0x00000020) /* Not EP0 */
147#define EPCTRL_RX_TYPE (0x0000000C)
148#define EPCTRL_RX_DATA_SINK (0x00000002) /* Not EP0 */
149#define EPCTRL_RX_EP_STALL (0x00000001)
150
151/* bit 19-18 and 3-2 are endpoint type */
152#define EPCTRL_TX_EP_TYPE_SHIFT (18)
153#define EPCTRL_RX_EP_TYPE_SHIFT (2)
154
155#define QH_MULT_POS (30)
156#define QH_ZLT_SEL (0x20000000)
157#define QH_MAX_PKT_LEN_POS (16)
158#define QH_IOS (0x00008000)
159#define QH_NEXT_TERMINATE (0x00000001)
160#define QH_IOC (0x00008000)
161#define QH_MULTO (0x00000C00)
162#define QH_STATUS_HALT (0x00000040)
163#define QH_STATUS_ACTIVE (0x00000080)
164#define EP_QUEUE_CURRENT_OFFSET_MASK (0x00000FFF)
165#define EP_QUEUE_HEAD_NEXT_POINTER_MASK (0xFFFFFFE0)
166#define EP_QUEUE_FRINDEX_MASK (0x000007FF)
167#define EP_MAX_LENGTH_TRANSFER (0x4000)
168
169#define DTD_NEXT_TERMINATE (0x00000001)
170#define DTD_IOC (0x00008000)
171#define DTD_STATUS_ACTIVE (0x00000080)
172#define DTD_STATUS_HALTED (0x00000040)
173#define DTD_STATUS_DATA_BUFF_ERR (0x00000020)
174#define DTD_STATUS_TRANSACTION_ERR (0x00000008)
175#define DTD_RESERVED_FIELDS (0x80007300)
176#define DTD_ADDR_MASK (0xFFFFFFE0)
177#define DTD_PACKET_SIZE (0x7FFF0000)
178#define DTD_LENGTH_BIT_POS (16)
179#define DTD_ERROR_MASK (DTD_STATUS_HALTED | \
180 DTD_STATUS_DATA_BUFF_ERR | \
181 DTD_STATUS_TRANSACTION_ERR)
182/*-------------------------------------------------------------------------*/
183/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */
184struct transfer_descriptor {
185 unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set
186 indicate invalid */
187 unsigned int size_ioc_sts; /* Total bytes (30-16), IOC (15),
188 MultO(11-10), STS (7-0) */
189 unsigned int buff_ptr0; /* Buffer pointer Page 0 */
190 unsigned int buff_ptr1; /* Buffer pointer Page 1 */
191 unsigned int buff_ptr2; /* Buffer pointer Page 2 */
192 unsigned int buff_ptr3; /* Buffer pointer Page 3 */
193 unsigned int buff_ptr4; /* Buffer pointer Page 4 */
194 unsigned int reserved;
195} __attribute__ ((packed));
196
197static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2]
198 __attribute__((aligned(32)));
199
200/* manual: 32.13.1 Endpoint Queue Head (dQH) */
201struct queue_head {
202 unsigned int max_pkt_length; /* Mult(31-30) , Zlt(29) , Max Pkt len
203 and IOS(15) */
204 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */
205 struct transfer_descriptor dtd; /* dTD overlay */
206 unsigned int setup_buffer[2]; /* Setup data 8 bytes */
207 unsigned int reserved; /* for software use, pointer to the first TD */
208 unsigned int status; /* for software use, status of chain in progress */
209 unsigned int length; /* for software use, transfered bytes of chain in progress */
210 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
211} __attribute__((packed));
212
213static struct queue_head qh_array[USB_NUM_ENDPOINTS*2] __attribute__((aligned(2048)));
214
215static const unsigned int pipe2mask[] = {
216 0x01, 0x010000,
217 0x02, 0x020000,
218 0x04, 0x040000,
219 0x08, 0x080000,
220 0x10, 0x100000,
221};
222
223/* return transfered size if wait=true */
224static int prime_transfer(int ep_num, void *ptr, int len, bool send, bool wait)
225{
226 int pipe = ep_num * 2 + (send ? 1 : 0);
227 unsigned mask = pipe2mask[pipe];
228 struct transfer_descriptor *td = &td_array[pipe];
229 struct queue_head* qh = &qh_array[pipe];
230
231 /* prepare TD */
232 td->next_td_ptr = DTD_NEXT_TERMINATE;
233 td->size_ioc_sts = (len<< DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE;
234 td->buff_ptr0 = (unsigned int)ptr;
235 td->buff_ptr1 = ((unsigned int)ptr & 0xfffff000) + 0x1000;
236 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000;
237 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000;
238 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000;
239 td->reserved = 0;
240 /* prime */
241 qh->dtd.next_td_ptr = (unsigned int)td;
242 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE);
243 REG_ENDPTPRIME |= mask;
244 /* wait for priming to be taken into account */
245 while(!(REG_ENDPTSTATUS & mask));
246 /* wait for completion */
247 if(wait)
248 {
249 while(!(REG_ENDPTCOMPLETE & mask));
250 REG_ENDPTCOMPLETE = mask;
251 /* memory barrier */
252 asm volatile("":::"memory");
253 /* return transfered size */
254 return len - (td->size_ioc_sts >> DTD_LENGTH_BIT_POS);
255 }
256 else
257 return 0;
258}
259
260void usb_drv_set_address(int address)
261{
262 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS;
263}
264
265/* endpoints */
266
267int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
268{
269 return prime_transfer(EP_NUM(endpoint), ptr, length, true, false);
270}
271
272int usb_drv_send(int endpoint, void* ptr, int length)
273{
274 return prime_transfer(EP_NUM(endpoint), ptr, length, true, true);
275}
276
277int usb_drv_recv(int endpoint, void* ptr, int length)
278{
279 return prime_transfer(EP_NUM(endpoint), ptr, length, false, true);
280}
281
282int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length)
283{
284 return prime_transfer(EP_NUM(endpoint), ptr, length, false, false);
285}
286
287int usb_drv_port_speed(void)
288{
289 return (REG_PORTSC1 & 0x08000000) ? 1 : 0;
290}
291
292void usb_drv_stall(int endpoint, bool stall, bool in)
293{
294 int ep_num = EP_NUM(endpoint);
295
296 if(in)
297 {
298 if(stall)
299 REG_ENDPTCTRL(ep_num) |= EPCTRL_TX_EP_STALL;
300 else
301 REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_EP_STALL;
302 }
303 else
304 {
305 if (stall)
306 REG_ENDPTCTRL(ep_num) |= EPCTRL_RX_EP_STALL;
307 else
308 REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_EP_STALL;
309 }
310}
311
312void usb_drv_configure_endpoint(int ep_num, int type)
313{
314 REG_ENDPTCTRL(ep_num) =
315 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
316 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
317 (type << EPCTRL_RX_EP_TYPE_SHIFT) |
318 (type << EPCTRL_TX_EP_TYPE_SHIFT);
319}
320
321void usb_drv_init(void)
322{
323 /* we don't know if USB was connected or not. In USB recovery mode it will
324 * but in other cases it might not be. In doubt, disconnect */
325 REG_USBCMD &= ~USBCMD_RUN;
326 /* reset the controller */
327 REG_USBCMD |= USBCMD_CTRL_RESET;
328 while (REG_USBCMD & USBCMD_CTRL_RESET);
329 /* put it in device mode */
330 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
331 /* reset address */
332 REG_DEVICEADDR = 0;
333 /* prepare qh array */
334 qh_array[0].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
335 qh_array[1].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
336 qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
337 qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
338 /* setup qh */
339 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
340 /* clear setup status */
341 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
342 /* run! */
343 REG_USBCMD |= USBCMD_RUN;
344}
345
346void usb_drv_exit(void)
347{
348 REG_USBCMD &= ~USBCMD_RUN;
349 REG_USBCMD |= USBCMD_CTRL_RESET;
350}
351
352int usb_drv_recv_setup(struct usb_ctrlrequest *req)
353{
354 /* wait for setup */
355 while(!(REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0))
356 ;
357 /* clear setup status */
358 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
359 /* check request */
360 asm volatile("":::"memory");
361 /* copy */
362 memcpy(req, (void *)&qh_array[0].setup_buffer[0], sizeof(struct usb_ctrlrequest));
363 return 0;
364}