diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-06-12 19:46:04 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-06-12 19:46:04 +0200 |
commit | 11da9d23fe323ce452fcd04a10a0ddf78eaa63ea (patch) | |
tree | 7ab4d162b2a944214bb01d498d5a0400dec031a0 /utils/imxtools/hwemul | |
parent | 3f4eeb850e91fd026a99f2b17bd7e0837f112bb5 (diff) | |
download | rockbox-11da9d23fe323ce452fcd04a10a0ddf78eaa63ea.tar.gz rockbox-11da9d23fe323ce452fcd04a10a0ddf78eaa63ea.zip |
imxtools: move hwemul to its own directory
The hwemul is only partly imx specific: the stub is stmp specific
but could be ported to other targets, the computer side and the
protocol are mostly stmp independent (or should be).
Change-Id: If88febffe591b0de86ea11cb740455ba20ddc401
Diffstat (limited to 'utils/imxtools/hwemul')
25 files changed, 0 insertions, 3727 deletions
diff --git a/utils/imxtools/hwemul/dev/Makefile b/utils/imxtools/hwemul/dev/Makefile deleted file mode 100644 index ca61fe392d..0000000000 --- a/utils/imxtools/hwemul/dev/Makefile +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | PREFIX?=arm-elf-eabi- | ||
2 | CC=$(PREFIX)gcc | ||
3 | LD=$(PREFIX)gcc | ||
4 | AS=$(PREFIX)gcc | ||
5 | OC=$(PREFIX)objcopy | ||
6 | SBTOOLS=../../sbtools/ | ||
7 | CFLAGS=-W -Wall -Wundef -O -nostdlib -ffreestanding -Wstrict-prototypes -pipe -std=gnu99 -mcpu=arm926ej-s -fomit-frame-pointer -Wno-pointer-sign -Wno-override-init -ffunction-sections | ||
8 | CFLAGS_3700=$(CFLAGS) -DHAVE_STMP3700 | ||
9 | ASFLAGS=$(CFLAGS) -D__ASSEMBLER__ | ||
10 | ASFLAGS_3700=$(CFLAGS_3700) -D__ASSEMBLER__ | ||
11 | OCFLAGS= | ||
12 | LINKER_FILE=hwemul.lds | ||
13 | LDFLAGS=-lgcc -Os -nostdlib -Tlink.lds -Wl,-Map,hwemul.map | ||
14 | LDFLAGS_3700=-lgcc -Os -nostdlib -Tlink.lds -Wl,-Map,hwemul3700.map | ||
15 | SRC_C=$(wildcard *.c) | ||
16 | SRC_S=$(wildcard *.S) | ||
17 | OBJ_C=$(SRC_C:.c=.o) | ||
18 | OBJ_S=$(SRC_S:.S=.o) | ||
19 | OBJ_C_3700=$(SRC_C:.c=.3700.o) | ||
20 | OBJ_S_3700=$(SRC_S:.S=.3700.o) | ||
21 | OBJ=$(OBJ_C) $(OBJ_S) | ||
22 | OBJ_3700=$(OBJ_C_3700) $(OBJ_S_3700) | ||
23 | OBJ_EXCEPT_CRT0=$(filter-out crt0.o,$(OBJ)) | ||
24 | OBJ_EXCEPT_CRT0_3700=$(filter-out crt0.3700.o,$(OBJ_3700)) | ||
25 | DEPS=$(OBJ:.o=.d) | ||
26 | EXEC_ELF=hwemul.elf | ||
27 | EXEC_SB=hwemul.sb | ||
28 | EXEC_ELF_3700=hwemul3700.elf | ||
29 | EXEC_SB_3700=hwemul3700.sb | ||
30 | |||
31 | ELF2SB=$(SBTOOLS)/elftosb -d | ||
32 | ELF2SB_CMD=-c hwemul.db | ||
33 | ELF2SB_KEY=-z | ||
34 | SBLOADER=$(SBTOOLS)/sbloader | ||
35 | SBLOADER_CMD=0 $(EXEC_SB) | ||
36 | SBLOADER_CMD_3700=0 $(EXEC_SB_3700) | ||
37 | |||
38 | TOOLS=../../../../tools/ | ||
39 | SCRAMBLE=$(TOOLS)/scramble | ||
40 | |||
41 | EXEC=$(EXEC_SB) $(EXEC_SB_3700) $(EXEC_ELF) $(EXEC_ELF_3700) | ||
42 | |||
43 | all: $(EXEC) | ||
44 | |||
45 | # pull in dependency info for *existing* .o files | ||
46 | -include $(DEPS) | ||
47 | |||
48 | %.3700.o: %.c | ||
49 | $(CC) $(CFLAGS_3700) -c -o $@ $< | ||
50 | $(CC) -MM $(CFLAGS_3700) $*.c > $*.d | ||
51 | @cp -f $*.d $*.d.tmp | ||
52 | @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \ | ||
53 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d | ||
54 | @rm -f $*.d.tmp | ||
55 | |||
56 | %.o: %.c | ||
57 | $(CC) $(CFLAGS) -c -o $@ $< | ||
58 | $(CC) -MM $(CFLAGS) $*.c > $*.d | ||
59 | @cp -f $*.d $*.d.tmp | ||
60 | @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \ | ||
61 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d | ||
62 | @rm -f $*.d.tmp | ||
63 | |||
64 | %.3700.o: %.S | ||
65 | $(AS) $(ASFLAGS_3700) -c -o $@ $< | ||
66 | |||
67 | %.o: %.S | ||
68 | $(AS) $(ASFLAGS) -c -o $@ $< | ||
69 | |||
70 | link.lds: $(LINKER_FILE) | ||
71 | $(CC) -E -x c - < $< | sed '/#/d' > $@ | ||
72 | |||
73 | $(EXEC_ELF): $(OBJ) link.lds | ||
74 | $(LD) $(LDFLAGS) -o $@ $(OBJ_EXCEPT_CRT0) | ||
75 | |||
76 | $(EXEC_SB): $(EXEC_ELF) | ||
77 | $(ELF2SB) $(ELF2SB_CMD) $(ELF2SB_KEY) -o $@ | ||
78 | |||
79 | $(EXEC_ELF_3700): $(OBJ_3700) link.lds | ||
80 | $(LD) $(LDFLAGS_3700) -o $@ $(OBJ_EXCEPT_CRT0_3700) | ||
81 | |||
82 | $(EXEC_SB_3700): $(EXEC_ELF_3700) | ||
83 | $(ELF2SB) $(ELF2SB_CMD) $(ELF2SB_KEY) -o $@ | ||
84 | |||
85 | sbload: $(EXEC_SB) | ||
86 | $(SBLOADER) $(SBLOADER_CMD) | ||
87 | |||
88 | sbload3700: $(EXEC_SB_3700) | ||
89 | $(SBLOADER) $(SBLOADER_CMD_3700) | ||
90 | |||
91 | clean: | ||
92 | rm -rf $(OBJ) $(OBJ_3700) $(DEPS) $(EXEC) *.map | ||
diff --git a/utils/imxtools/hwemul/dev/config.h b/utils/imxtools/hwemul/dev/config.h deleted file mode 100644 index 6bd995e147..0000000000 --- a/utils/imxtools/hwemul/dev/config.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
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 __HWEMUL_CONFIG__ | ||
22 | #define __HWEMUL_CONFIG__ | ||
23 | |||
24 | #define MEMORYSIZE 0 | ||
25 | #define STACK_SIZE 0x1000 | ||
26 | #define MAX_LOGF_SIZE 128 | ||
27 | |||
28 | #define IRAM_ORIG 0 | ||
29 | #define IRAM_SIZE 0x8000 | ||
30 | #define DRAM_ORIG 0x40000000 | ||
31 | #define DRAM_SIZE (MEMORYSIZE * 0x100000) | ||
32 | |||
33 | #endif /* __HWEMUL_CONFIG__ */ | ||
diff --git a/utils/imxtools/hwemul/dev/crt0.S b/utils/imxtools/hwemul/dev/crt0.S deleted file mode 100644 index e2d4742d36..0000000000 --- a/utils/imxtools/hwemul/dev/crt0.S +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | .section .text,"ax",%progbits | ||
2 | .code 32 | ||
3 | .align 0x04 | ||
4 | .global start | ||
5 | start: | ||
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 | ||
12 | 1: | ||
13 | cmp r3, r2 | ||
14 | strhi r4, [r2], #4 | ||
15 | bhi 1b | ||
16 | /* jump to C code */ | ||
17 | b main | ||
diff --git a/utils/imxtools/hwemul/dev/format.c b/utils/imxtools/hwemul/dev/format.c deleted file mode 100644 index f5783159c0..0000000000 --- a/utils/imxtools/hwemul/dev/format.c +++ /dev/null | |||
@@ -1,223 +0,0 @@ | |||
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 | |||
29 | static const char hexdigit[] = "0123456789ABCDEF"; | ||
30 | |||
31 | void 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/imxtools/hwemul/dev/format.h b/utils/imxtools/hwemul/dev/format.h deleted file mode 100644 index a514c882ba..0000000000 --- a/utils/imxtools/hwemul/dev/format.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
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 __HWEMUL_FORMAT__ | ||
22 | #define __HWEMUL_FORMAT__ | ||
23 | |||
24 | #include <stdarg.h> | ||
25 | |||
26 | void vuprintf(int (*push)(void *userp, unsigned char data), | ||
27 | void *userp, const char *fmt, va_list ap); | ||
28 | |||
29 | #endif /* __HWEMUL_FORMAT__ */ | ||
diff --git a/utils/imxtools/hwemul/dev/hwemul.db b/utils/imxtools/hwemul/dev/hwemul.db deleted file mode 100644 index 7a6f930f57..0000000000 --- a/utils/imxtools/hwemul/dev/hwemul.db +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
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 | sources | ||
22 | { | ||
23 | hwemul = "hwemul.elf"; | ||
24 | } | ||
25 | |||
26 | section(0) | ||
27 | { | ||
28 | load hwemul; | ||
29 | jump hwemul(1); | ||
30 | } | ||
31 | |||
diff --git a/utils/imxtools/hwemul/dev/hwemul.lds b/utils/imxtools/hwemul/dev/hwemul.lds deleted file mode 100644 index 7e3ac747a2..0000000000 --- a/utils/imxtools/hwemul/dev/hwemul.lds +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
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 | |||
23 | ENTRY(start) | ||
24 | OUTPUT_FORMAT(elf32-littlearm) | ||
25 | OUTPUT_ARCH(arm) | ||
26 | STARTUP(crt0.o) | ||
27 | |||
28 | #define IRAM_END_ADDR (IRAM_ORIG + IRAM_SIZE) | ||
29 | |||
30 | MEMORY | ||
31 | { | ||
32 | OCRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE | ||
33 | } | ||
34 | |||
35 | SECTIONS | ||
36 | { | ||
37 | .octext : | ||
38 | { | ||
39 | oc_codestart = .; | ||
40 | *(.text*) | ||
41 | *(.data*) | ||
42 | *(.rodata*) | ||
43 | } > OCRAM | ||
44 | |||
45 | .bss (NOLOAD) : | ||
46 | { | ||
47 | bss_start = .; | ||
48 | *(.bss) | ||
49 | bss_end = .; | ||
50 | } > OCRAM | ||
51 | |||
52 | .stack (NOLOAD) : | ||
53 | { | ||
54 | oc_codeend = .; | ||
55 | oc_stackstart = .; | ||
56 | . += STACK_SIZE; | ||
57 | oc_stackend = .; | ||
58 | oc_bufferstart = .; | ||
59 | } > OCRAM | ||
60 | |||
61 | .ocend IRAM_END_ADDR (NOLOAD) : | ||
62 | { | ||
63 | oc_bufferend = .; | ||
64 | } > OCRAM | ||
65 | |||
66 | /DISCARD/ : | ||
67 | { | ||
68 | *(.eh_frame) | ||
69 | } | ||
70 | } | ||
diff --git a/utils/imxtools/hwemul/dev/link.lds b/utils/imxtools/hwemul/dev/link.lds deleted file mode 100644 index 97b259955f..0000000000 --- a/utils/imxtools/hwemul/dev/link.lds +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | |||
2 | ENTRY(start) | ||
3 | OUTPUT_FORMAT(elf32-littlearm) | ||
4 | OUTPUT_ARCH(arm) | ||
5 | STARTUP(crt0.o) | ||
6 | |||
7 | |||
8 | |||
9 | MEMORY | ||
10 | { | ||
11 | OCRAM : ORIGIN = 0, LENGTH = 0x8000 | ||
12 | } | ||
13 | |||
14 | SECTIONS | ||
15 | { | ||
16 | .octext : | ||
17 | { | ||
18 | oc_codestart = .; | ||
19 | *(.text*) | ||
20 | *(.data*) | ||
21 | *(.rodata*) | ||
22 | } > OCRAM | ||
23 | |||
24 | .bss (NOLOAD) : | ||
25 | { | ||
26 | bss_start = .; | ||
27 | *(.bss) | ||
28 | bss_end = .; | ||
29 | } > OCRAM | ||
30 | |||
31 | .stack (NOLOAD) : | ||
32 | { | ||
33 | oc_codeend = .; | ||
34 | oc_stackstart = .; | ||
35 | . += 0x1000; | ||
36 | oc_stackend = .; | ||
37 | oc_bufferstart = .; | ||
38 | } > OCRAM | ||
39 | |||
40 | .ocend (0 + 0x8000) (NOLOAD) : | ||
41 | { | ||
42 | oc_bufferend = .; | ||
43 | } > OCRAM | ||
44 | |||
45 | /DISCARD/ : | ||
46 | { | ||
47 | *(.eh_frame) | ||
48 | } | ||
49 | } | ||
diff --git a/utils/imxtools/hwemul/dev/logf.c b/utils/imxtools/hwemul/dev/logf.c deleted file mode 100644 index 3ccc5c5e9f..0000000000 --- a/utils/imxtools/hwemul/dev/logf.c +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
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 | |||
26 | static unsigned char logfbuffer[MAX_LOGF_SIZE]; | ||
27 | static int logfread = 0; | ||
28 | static int logfwrite = 0; | ||
29 | static int logfen = true; | ||
30 | |||
31 | void enable_logf(bool en) | ||
32 | { | ||
33 | logfen = en; | ||
34 | } | ||
35 | |||
36 | static int logf_push(void *userp, unsigned char c) | ||
37 | { | ||
38 | (void)userp; | ||
39 | |||
40 | logfbuffer[logfwrite++] = c; | ||
41 | if(logfwrite == MAX_LOGF_SIZE) | ||
42 | logfwrite = 0; | ||
43 | return true; | ||
44 | } | ||
45 | |||
46 | void logf(const char *fmt, ...) | ||
47 | { | ||
48 | if(!logfen) return; | ||
49 | va_list ap; | ||
50 | va_start(ap, fmt); | ||
51 | vuprintf(logf_push, NULL, fmt, ap); | ||
52 | va_end(ap); | ||
53 | } | ||
54 | |||
55 | size_t logf_readback(char *buf, size_t max_size) | ||
56 | { | ||
57 | if(logfread == logfwrite) | ||
58 | return 0; | ||
59 | if(logfread < logfwrite) | ||
60 | max_size = MIN(max_size, (size_t)(logfwrite - logfread)); | ||
61 | else | ||
62 | max_size = MIN(max_size, (size_t)(MAX_LOGF_SIZE - logfread)); | ||
63 | memcpy(buf, &logfbuffer[logfread], max_size); | ||
64 | logfread += max_size; | ||
65 | if(logfread == MAX_LOGF_SIZE) | ||
66 | logfread = 0; | ||
67 | return max_size; | ||
68 | } | ||
diff --git a/utils/imxtools/hwemul/dev/logf.h b/utils/imxtools/hwemul/dev/logf.h deleted file mode 100644 index 5aa882a630..0000000000 --- a/utils/imxtools/hwemul/dev/logf.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
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 __HWEMUL_LOGF__ | ||
22 | #define __HWEMUL_LOGF__ | ||
23 | |||
24 | #include "stddef.h" | ||
25 | #include <stdarg.h> | ||
26 | |||
27 | void enable_logf(bool en); | ||
28 | void logf(const char *fmt, ...); | ||
29 | size_t logf_readback(char *buf, size_t max_size); | ||
30 | |||
31 | #endif /* __HWEMUL_LOGF__ */ | ||
diff --git a/utils/imxtools/hwemul/dev/main.c b/utils/imxtools/hwemul/dev/main.c deleted file mode 100644 index 09bb6c7714..0000000000 --- a/utils/imxtools/hwemul/dev/main.c +++ /dev/null | |||
@@ -1,1409 +0,0 @@ | |||
1 | #include "stddef.h" | ||
2 | #include "protocol.h" | ||
3 | #include "logf.h" | ||
4 | #include "usb_ch9.h" | ||
5 | |||
6 | extern unsigned char oc_codestart[]; | ||
7 | extern unsigned char oc_codeend[]; | ||
8 | extern unsigned char oc_stackstart[]; | ||
9 | extern unsigned char oc_stackend[]; | ||
10 | extern unsigned char oc_bufferstart[]; | ||
11 | extern unsigned char oc_bufferend[]; | ||
12 | |||
13 | #define oc_codesize ((size_t)(oc_codeend - oc_codestart)) | ||
14 | #define oc_stacksize ((size_t)(oc_stackend - oc_stackstart)) | ||
15 | #define oc_buffersize ((size_t)(oc_bufferend - oc_bufferstart)) | ||
16 | |||
17 | /** | ||
18 | * | ||
19 | * Common | ||
20 | * | ||
21 | */ | ||
22 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | ||
23 | |||
24 | #define __REG_SET(reg) (*((volatile uint32_t *)(® + 1))) | ||
25 | #define __REG_CLR(reg) (*((volatile uint32_t *)(® + 2))) | ||
26 | #define __REG_TOG(reg) (*((volatile uint32_t *)(® + 3))) | ||
27 | |||
28 | #define __BLOCK_SFTRST (1 << 31) | ||
29 | #define __BLOCK_CLKGATE (1 << 30) | ||
30 | |||
31 | #define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP) | ||
32 | #define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP) | ||
33 | #define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP) | ||
34 | |||
35 | /** | ||
36 | * | ||
37 | * Pin control | ||
38 | * | ||
39 | */ | ||
40 | |||
41 | #define HW_PINCTRL_BASE 0x80018000 | ||
42 | |||
43 | #define HW_PINCTRL_CTRL (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x0)) | ||
44 | #define HW_PINCTRL_MUXSEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x100 + (i) * 0x10)) | ||
45 | #define HW_PINCTRL_DRIVE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x200 + (i) * 0x10)) | ||
46 | #ifdef HAVE_STMP3700 | ||
47 | #define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x300 + (i) * 0x10)) | ||
48 | #define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10)) | ||
49 | #define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10)) | ||
50 | #define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10)) | ||
51 | #define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10)) | ||
52 | #define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10)) | ||
53 | #define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10)) | ||
54 | #define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10)) | ||
55 | #define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10)) | ||
56 | #else | ||
57 | #define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10)) | ||
58 | #define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10)) | ||
59 | #define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10)) | ||
60 | #define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10)) | ||
61 | #define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10)) | ||
62 | #define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10)) | ||
63 | #define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10)) | ||
64 | #define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10)) | ||
65 | #define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xc00 + (i) * 0x10)) | ||
66 | #endif | ||
67 | |||
68 | #define PINCTRL_FUNCTION_MAIN 0 | ||
69 | #define PINCTRL_FUNCTION_ALT1 1 | ||
70 | #define PINCTRL_FUNCTION_ALT2 2 | ||
71 | #define PINCTRL_FUNCTION_GPIO 3 | ||
72 | |||
73 | #define PINCTRL_DRIVE_4mA 0 | ||
74 | #define PINCTRL_DRIVE_8mA 1 | ||
75 | #define PINCTRL_DRIVE_12mA 2 | ||
76 | #define PINCTRL_DRIVE_16mA 3 /* not available on all pins */ | ||
77 | |||
78 | typedef void (*pin_irq_cb_t)(int bank, int pin); | ||
79 | |||
80 | static inline void imx233_pinctrl_init(void) | ||
81 | { | ||
82 | __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST; | ||
83 | } | ||
84 | |||
85 | static inline void imx233_set_pin_drive_strength(unsigned bank, unsigned pin, unsigned strength) | ||
86 | { | ||
87 | __REG_CLR(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = 3 << (4 * (pin % 8)); | ||
88 | __REG_SET(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = strength << (4 * (pin % 8)); | ||
89 | } | ||
90 | |||
91 | static inline void imx233_enable_gpio_output(unsigned bank, unsigned pin, bool enable) | ||
92 | { | ||
93 | if(enable) | ||
94 | __REG_SET(HW_PINCTRL_DOE(bank)) = 1 << pin; | ||
95 | else | ||
96 | __REG_CLR(HW_PINCTRL_DOE(bank)) = 1 << pin; | ||
97 | } | ||
98 | |||
99 | static inline void imx233_enable_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool enable) | ||
100 | { | ||
101 | if(enable) | ||
102 | __REG_SET(HW_PINCTRL_DOE(bank)) = pin_mask; | ||
103 | else | ||
104 | __REG_CLR(HW_PINCTRL_DOE(bank)) = pin_mask; | ||
105 | } | ||
106 | |||
107 | static inline void imx233_set_gpio_output(unsigned bank, unsigned pin, bool value) | ||
108 | { | ||
109 | if(value) | ||
110 | __REG_SET(HW_PINCTRL_DOUT(bank)) = 1 << pin; | ||
111 | else | ||
112 | __REG_CLR(HW_PINCTRL_DOUT(bank)) = 1 << pin; | ||
113 | } | ||
114 | |||
115 | static inline void imx233_set_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool value) | ||
116 | { | ||
117 | if(value) | ||
118 | __REG_SET(HW_PINCTRL_DOUT(bank)) = pin_mask; | ||
119 | else | ||
120 | __REG_CLR(HW_PINCTRL_DOUT(bank)) = pin_mask; | ||
121 | } | ||
122 | |||
123 | static inline uint32_t imx233_get_gpio_input_mask(unsigned bank, uint32_t pin_mask) | ||
124 | { | ||
125 | return HW_PINCTRL_DIN(bank) & pin_mask; | ||
126 | } | ||
127 | |||
128 | static inline void imx233_set_pin_function(unsigned bank, unsigned pin, unsigned function) | ||
129 | { | ||
130 | __REG_CLR(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = 3 << (2 * (pin % 16)); | ||
131 | __REG_SET(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = function << (2 * (pin % 16)); | ||
132 | } | ||
133 | |||
134 | static inline void imx233_enable_pin_pullup(unsigned bank, unsigned pin, bool enable) | ||
135 | { | ||
136 | if(enable) | ||
137 | __REG_SET(HW_PINCTRL_PULL(bank)) = 1 << pin; | ||
138 | else | ||
139 | __REG_CLR(HW_PINCTRL_PULL(bank)) = 1 << pin; | ||
140 | } | ||
141 | |||
142 | static inline void imx233_enable_pin_pullup_mask(unsigned bank, uint32_t pin_msk, bool enable) | ||
143 | { | ||
144 | if(enable) | ||
145 | __REG_SET(HW_PINCTRL_PULL(bank)) = pin_msk; | ||
146 | else | ||
147 | __REG_CLR(HW_PINCTRL_PULL(bank)) = pin_msk; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * | ||
152 | * USB subsystem | ||
153 | * | ||
154 | */ | ||
155 | |||
156 | #define USB_BASE 0x80080000 | ||
157 | #define USB_NUM_ENDPOINTS 2 | ||
158 | #define MAX_PKT_SIZE 1024 | ||
159 | #define MAX_PKT_SIZE_EP0 64 | ||
160 | |||
161 | /* USB device mode registers (Little Endian) */ | ||
162 | #define REG_USBCMD (*(volatile unsigned int *)(USB_BASE+0x140)) | ||
163 | #define REG_DEVICEADDR (*(volatile unsigned int *)(USB_BASE+0x154)) | ||
164 | #define REG_ENDPOINTLISTADDR (*(volatile unsigned int *)(USB_BASE+0x158)) | ||
165 | #define REG_PORTSC1 (*(volatile unsigned int *)(USB_BASE+0x184)) | ||
166 | #define REG_USBMODE (*(volatile unsigned int *)(USB_BASE+0x1a8)) | ||
167 | #define REG_ENDPTSETUPSTAT (*(volatile unsigned int *)(USB_BASE+0x1ac)) | ||
168 | #define REG_ENDPTPRIME (*(volatile unsigned int *)(USB_BASE+0x1b0)) | ||
169 | #define REG_ENDPTSTATUS (*(volatile unsigned int *)(USB_BASE+0x1b8)) | ||
170 | #define REG_ENDPTCOMPLETE (*(volatile unsigned int *)(USB_BASE+0x1bc)) | ||
171 | #define REG_ENDPTCTRL0 (*(volatile unsigned int *)(USB_BASE+0x1c0)) | ||
172 | #define REG_ENDPTCTRL1 (*(volatile unsigned int *)(USB_BASE+0x1c4)) | ||
173 | #define REG_ENDPTCTRL2 (*(volatile unsigned int *)(USB_BASE+0x1c8)) | ||
174 | #define REG_ENDPTCTRL(_x_) (*(volatile unsigned int *)(USB_BASE+0x1c0+4*(_x_))) | ||
175 | |||
176 | /* USB CMD Register Bit Masks */ | ||
177 | #define USBCMD_RUN (0x00000001) | ||
178 | #define USBCMD_CTRL_RESET (0x00000002) | ||
179 | #define USBCMD_PERIODIC_SCHEDULE_EN (0x00000010) | ||
180 | #define USBCMD_ASYNC_SCHEDULE_EN (0x00000020) | ||
181 | #define USBCMD_INT_AA_DOORBELL (0x00000040) | ||
182 | #define USBCMD_ASP (0x00000300) | ||
183 | #define USBCMD_ASYNC_SCH_PARK_EN (0x00000800) | ||
184 | #define USBCMD_SUTW (0x00002000) | ||
185 | #define USBCMD_ATDTW (0x00004000) | ||
186 | #define USBCMD_ITC (0x00FF0000) | ||
187 | |||
188 | /* Device Address bit masks */ | ||
189 | #define USBDEVICEADDRESS_MASK (0xFE000000) | ||
190 | #define USBDEVICEADDRESS_BIT_POS (25) | ||
191 | |||
192 | /* Endpoint Setup Status bit masks */ | ||
193 | #define EPSETUP_STATUS_EP0 (0x00000001) | ||
194 | |||
195 | /* PORTSCX Register Bit Masks */ | ||
196 | #define PORTSCX_CURRENT_CONNECT_STATUS (0x00000001) | ||
197 | #define PORTSCX_CONNECT_STATUS_CHANGE (0x00000002) | ||
198 | #define PORTSCX_PORT_ENABLE (0x00000004) | ||
199 | #define PORTSCX_PORT_EN_DIS_CHANGE (0x00000008) | ||
200 | #define PORTSCX_OVER_CURRENT_ACT (0x00000010) | ||
201 | #define PORTSCX_OVER_CURRENT_CHG (0x00000020) | ||
202 | #define PORTSCX_PORT_FORCE_RESUME (0x00000040) | ||
203 | #define PORTSCX_PORT_SUSPEND (0x00000080) | ||
204 | #define PORTSCX_PORT_RESET (0x00000100) | ||
205 | #define PORTSCX_LINE_STATUS_BITS (0x00000C00) | ||
206 | #define PORTSCX_PORT_POWER (0x00001000) | ||
207 | #define PORTSCX_PORT_INDICTOR_CTRL (0x0000C000) | ||
208 | #define PORTSCX_PORT_TEST_CTRL (0x000F0000) | ||
209 | #define PORTSCX_WAKE_ON_CONNECT_EN (0x00100000) | ||
210 | #define PORTSCX_WAKE_ON_CONNECT_DIS (0x00200000) | ||
211 | #define PORTSCX_WAKE_ON_OVER_CURRENT (0x00400000) | ||
212 | #define PORTSCX_PHY_LOW_POWER_SPD (0x00800000) | ||
213 | #define PORTSCX_PORT_FORCE_FULL_SPEED (0x01000000) | ||
214 | #define PORTSCX_PORT_SPEED_MASK (0x0C000000) | ||
215 | #define PORTSCX_PORT_WIDTH (0x10000000) | ||
216 | #define PORTSCX_PHY_TYPE_SEL (0xC0000000) | ||
217 | |||
218 | /* bit 11-10 are line status */ | ||
219 | #define PORTSCX_LINE_STATUS_SE0 (0x00000000) | ||
220 | #define PORTSCX_LINE_STATUS_JSTATE (0x00000400) | ||
221 | #define PORTSCX_LINE_STATUS_KSTATE (0x00000800) | ||
222 | #define PORTSCX_LINE_STATUS_UNDEF (0x00000C00) | ||
223 | #define PORTSCX_LINE_STATUS_BIT_POS (10) | ||
224 | |||
225 | /* bit 15-14 are port indicator control */ | ||
226 | #define PORTSCX_PIC_OFF (0x00000000) | ||
227 | #define PORTSCX_PIC_AMBER (0x00004000) | ||
228 | #define PORTSCX_PIC_GREEN (0x00008000) | ||
229 | #define PORTSCX_PIC_UNDEF (0x0000C000) | ||
230 | #define PORTSCX_PIC_BIT_POS (14) | ||
231 | |||
232 | /* bit 19-16 are port test control */ | ||
233 | #define PORTSCX_PTC_DISABLE (0x00000000) | ||
234 | #define PORTSCX_PTC_JSTATE (0x00010000) | ||
235 | #define PORTSCX_PTC_KSTATE (0x00020000) | ||
236 | #define PORTSCX_PTC_SE0NAK (0x00030000) | ||
237 | #define PORTSCX_PTC_PACKET (0x00040000) | ||
238 | #define PORTSCX_PTC_FORCE_EN (0x00050000) | ||
239 | #define PORTSCX_PTC_BIT_POS (16) | ||
240 | |||
241 | /* bit 27-26 are port speed */ | ||
242 | #define PORTSCX_PORT_SPEED_FULL (0x00000000) | ||
243 | #define PORTSCX_PORT_SPEED_LOW (0x04000000) | ||
244 | #define PORTSCX_PORT_SPEED_HIGH (0x08000000) | ||
245 | #define PORTSCX_PORT_SPEED_UNDEF (0x0C000000) | ||
246 | #define PORTSCX_SPEED_BIT_POS (26) | ||
247 | |||
248 | /* bit 28 is parallel transceiver width for UTMI interface */ | ||
249 | #define PORTSCX_PTW (0x10000000) | ||
250 | #define PORTSCX_PTW_8BIT (0x00000000) | ||
251 | #define PORTSCX_PTW_16BIT (0x10000000) | ||
252 | |||
253 | /* bit 31-30 are port transceiver select */ | ||
254 | #define PORTSCX_PTS_UTMI (0x00000000) | ||
255 | #define PORTSCX_PTS_CLASSIC (0x40000000) | ||
256 | #define PORTSCX_PTS_ULPI (0x80000000) | ||
257 | #define PORTSCX_PTS_FSLS (0xC0000000) | ||
258 | #define PORTSCX_PTS_BIT_POS (30) | ||
259 | |||
260 | /* USB MODE Register Bit Masks */ | ||
261 | #define USBMODE_CTRL_MODE_IDLE (0x00000000) | ||
262 | #define USBMODE_CTRL_MODE_DEVICE (0x00000002) | ||
263 | #define USBMODE_CTRL_MODE_HOST (0x00000003) | ||
264 | #define USBMODE_CTRL_MODE_RSV (0x00000001) | ||
265 | #define USBMODE_SETUP_LOCK_OFF (0x00000008) | ||
266 | #define USBMODE_STREAM_DISABLE (0x00000010) | ||
267 | |||
268 | /* ENDPOINTCTRLx Register Bit Masks */ | ||
269 | #define EPCTRL_TX_ENABLE (0x00800000) | ||
270 | #define EPCTRL_TX_DATA_TOGGLE_RST (0x00400000) /* Not EP0 */ | ||
271 | #define EPCTRL_TX_DATA_TOGGLE_INH (0x00200000) /* Not EP0 */ | ||
272 | #define EPCTRL_TX_TYPE (0x000C0000) | ||
273 | #define EPCTRL_TX_DATA_SOURCE (0x00020000) /* Not EP0 */ | ||
274 | #define EPCTRL_TX_EP_STALL (0x00010000) | ||
275 | #define EPCTRL_RX_ENABLE (0x00000080) | ||
276 | #define EPCTRL_RX_DATA_TOGGLE_RST (0x00000040) /* Not EP0 */ | ||
277 | #define EPCTRL_RX_DATA_TOGGLE_INH (0x00000020) /* Not EP0 */ | ||
278 | #define EPCTRL_RX_TYPE (0x0000000C) | ||
279 | #define EPCTRL_RX_DATA_SINK (0x00000002) /* Not EP0 */ | ||
280 | #define EPCTRL_RX_EP_STALL (0x00000001) | ||
281 | |||
282 | /* bit 19-18 and 3-2 are endpoint type */ | ||
283 | #define EPCTRL_TX_EP_TYPE_SHIFT (18) | ||
284 | #define EPCTRL_RX_EP_TYPE_SHIFT (2) | ||
285 | |||
286 | #define QH_MULT_POS (30) | ||
287 | #define QH_ZLT_SEL (0x20000000) | ||
288 | #define QH_MAX_PKT_LEN_POS (16) | ||
289 | #define QH_IOS (0x00008000) | ||
290 | #define QH_NEXT_TERMINATE (0x00000001) | ||
291 | #define QH_IOC (0x00008000) | ||
292 | #define QH_MULTO (0x00000C00) | ||
293 | #define QH_STATUS_HALT (0x00000040) | ||
294 | #define QH_STATUS_ACTIVE (0x00000080) | ||
295 | #define EP_QUEUE_CURRENT_OFFSET_MASK (0x00000FFF) | ||
296 | #define EP_QUEUE_HEAD_NEXT_POINTER_MASK (0xFFFFFFE0) | ||
297 | #define EP_QUEUE_FRINDEX_MASK (0x000007FF) | ||
298 | #define EP_MAX_LENGTH_TRANSFER (0x4000) | ||
299 | |||
300 | #define DTD_NEXT_TERMINATE (0x00000001) | ||
301 | #define DTD_IOC (0x00008000) | ||
302 | #define DTD_STATUS_ACTIVE (0x00000080) | ||
303 | #define DTD_STATUS_HALTED (0x00000040) | ||
304 | #define DTD_STATUS_DATA_BUFF_ERR (0x00000020) | ||
305 | #define DTD_STATUS_TRANSACTION_ERR (0x00000008) | ||
306 | #define DTD_RESERVED_FIELDS (0x80007300) | ||
307 | #define DTD_ADDR_MASK (0xFFFFFFE0) | ||
308 | #define DTD_PACKET_SIZE (0x7FFF0000) | ||
309 | #define DTD_LENGTH_BIT_POS (16) | ||
310 | #define DTD_ERROR_MASK (DTD_STATUS_HALTED | \ | ||
311 | DTD_STATUS_DATA_BUFF_ERR | \ | ||
312 | DTD_STATUS_TRANSACTION_ERR) | ||
313 | /*-------------------------------------------------------------------------*/ | ||
314 | /* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ | ||
315 | struct transfer_descriptor { | ||
316 | unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set | ||
317 | indicate invalid */ | ||
318 | unsigned int size_ioc_sts; /* Total bytes (30-16), IOC (15), | ||
319 | MultO(11-10), STS (7-0) */ | ||
320 | unsigned int buff_ptr0; /* Buffer pointer Page 0 */ | ||
321 | unsigned int buff_ptr1; /* Buffer pointer Page 1 */ | ||
322 | unsigned int buff_ptr2; /* Buffer pointer Page 2 */ | ||
323 | unsigned int buff_ptr3; /* Buffer pointer Page 3 */ | ||
324 | unsigned int buff_ptr4; /* Buffer pointer Page 4 */ | ||
325 | unsigned int reserved; | ||
326 | } __attribute__ ((packed)); | ||
327 | |||
328 | static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2] | ||
329 | __attribute__((aligned(32))); | ||
330 | |||
331 | /* manual: 32.13.1 Endpoint Queue Head (dQH) */ | ||
332 | struct queue_head { | ||
333 | unsigned int max_pkt_length; /* Mult(31-30) , Zlt(29) , Max Pkt len | ||
334 | and IOS(15) */ | ||
335 | unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */ | ||
336 | struct transfer_descriptor dtd; /* dTD overlay */ | ||
337 | unsigned int setup_buffer[2]; /* Setup data 8 bytes */ | ||
338 | unsigned int reserved; /* for software use, pointer to the first TD */ | ||
339 | unsigned int status; /* for software use, status of chain in progress */ | ||
340 | unsigned int length; /* for software use, transfered bytes of chain in progress */ | ||
341 | unsigned int wait; /* for softwate use, indicates if the transfer is blocking */ | ||
342 | } __attribute__((packed)); | ||
343 | |||
344 | static struct queue_head qh_array[USB_NUM_ENDPOINTS*2] __attribute__((aligned(2048))); | ||
345 | |||
346 | static const unsigned int pipe2mask[] = { | ||
347 | 0x01, 0x010000, | ||
348 | 0x02, 0x020000, | ||
349 | 0x04, 0x040000, | ||
350 | 0x08, 0x080000, | ||
351 | 0x10, 0x100000, | ||
352 | }; | ||
353 | |||
354 | /* return transfered size if wait=true */ | ||
355 | static int prime_transfer(int ep_num, void *ptr, int len, bool send, bool wait) | ||
356 | { | ||
357 | int pipe = ep_num * 2 + (send ? 1 : 0); | ||
358 | unsigned mask = pipe2mask[pipe]; | ||
359 | struct transfer_descriptor *td = &td_array[pipe]; | ||
360 | struct queue_head* qh = &qh_array[pipe]; | ||
361 | |||
362 | /* prepare TD */ | ||
363 | td->next_td_ptr = DTD_NEXT_TERMINATE; | ||
364 | td->size_ioc_sts = (len<< DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE; | ||
365 | td->buff_ptr0 = (unsigned int)ptr; | ||
366 | td->buff_ptr1 = ((unsigned int)ptr & 0xfffff000) + 0x1000; | ||
367 | td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000; | ||
368 | td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000; | ||
369 | td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000; | ||
370 | td->reserved = 0; | ||
371 | /* prime */ | ||
372 | qh->dtd.next_td_ptr = (unsigned int)td; | ||
373 | qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); | ||
374 | REG_ENDPTPRIME |= mask; | ||
375 | /* wait for priming to be taken into account */ | ||
376 | while(!(REG_ENDPTSTATUS & mask)); | ||
377 | /* wait for completion */ | ||
378 | if(wait) | ||
379 | { | ||
380 | while(!(REG_ENDPTCOMPLETE & mask)); | ||
381 | REG_ENDPTCOMPLETE = mask; | ||
382 | /* memory barrier */ | ||
383 | asm volatile("":::"memory"); | ||
384 | /* return transfered size */ | ||
385 | return len - (td->size_ioc_sts >> DTD_LENGTH_BIT_POS); | ||
386 | } | ||
387 | else | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | void usb_drv_set_address(int address) | ||
392 | { | ||
393 | REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS; | ||
394 | } | ||
395 | |||
396 | /* endpoints */ | ||
397 | #define EP_CONTROL 0 | ||
398 | |||
399 | #define DIR_OUT 0 | ||
400 | #define DIR_IN 1 | ||
401 | |||
402 | #define EP_DIR(ep) (((ep) & USB_ENDPOINT_DIR_MASK) ? DIR_IN : DIR_OUT) | ||
403 | #define EP_NUM(ep) ((ep) & USB_ENDPOINT_NUMBER_MASK) | ||
404 | |||
405 | static int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | ||
406 | { | ||
407 | return prime_transfer(EP_NUM(endpoint), ptr, length, true, false); | ||
408 | } | ||
409 | |||
410 | static int usb_drv_send(int endpoint, void* ptr, int length) | ||
411 | { | ||
412 | return prime_transfer(EP_NUM(endpoint), ptr, length, true, true); | ||
413 | } | ||
414 | |||
415 | static int usb_drv_recv(int endpoint, void* ptr, int length) | ||
416 | { | ||
417 | return prime_transfer(EP_NUM(endpoint), ptr, length, false, true); | ||
418 | } | ||
419 | |||
420 | static int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length) | ||
421 | { | ||
422 | return prime_transfer(EP_NUM(endpoint), ptr, length, false, false); | ||
423 | } | ||
424 | |||
425 | static int usb_drv_port_speed(void) | ||
426 | { | ||
427 | return (REG_PORTSC1 & 0x08000000) ? 1 : 0; | ||
428 | } | ||
429 | |||
430 | static void usb_drv_stall(int endpoint, bool stall, bool in) | ||
431 | { | ||
432 | int ep_num = EP_NUM(endpoint); | ||
433 | |||
434 | if(in) | ||
435 | { | ||
436 | if(stall) | ||
437 | REG_ENDPTCTRL(ep_num) |= EPCTRL_TX_EP_STALL; | ||
438 | else | ||
439 | REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_EP_STALL; | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | if (stall) | ||
444 | REG_ENDPTCTRL(ep_num) |= EPCTRL_RX_EP_STALL; | ||
445 | else | ||
446 | REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_EP_STALL; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | static void usb_drv_configure_endpoint(int ep_num, int type) | ||
451 | { | ||
452 | REG_ENDPTCTRL(ep_num) = | ||
453 | EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | | ||
454 | EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | | ||
455 | (type << EPCTRL_RX_EP_TYPE_SHIFT) | | ||
456 | (type << EPCTRL_TX_EP_TYPE_SHIFT); | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * | ||
461 | * Clock control | ||
462 | * | ||
463 | **/ | ||
464 | #define __CLK_CLKGATE (1 << 31) | ||
465 | #define __CLK_BUSY (1 << 29) | ||
466 | |||
467 | #define HW_CLKCTRL_BASE 0x80040000 | ||
468 | |||
469 | #define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0)) | ||
470 | #define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16) | ||
471 | #define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18) | ||
472 | #define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20 | ||
473 | #define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20) | ||
474 | |||
475 | #define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10)) | ||
476 | |||
477 | #define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20)) | ||
478 | #define HW_CLKCTRL_CPU__DIV_CPU_BP 0 | ||
479 | #define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f | ||
480 | #define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12) | ||
481 | #define HW_CLKCTRL_CPU__DIV_XTAL_BP 16 | ||
482 | #define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16) | ||
483 | #define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26) | ||
484 | #define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28) | ||
485 | |||
486 | #define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30)) | ||
487 | #define HW_CLKCTRL_HBUS__DIV_BP 0 | ||
488 | #define HW_CLKCTRL_HBUS__DIV_BM 0x1f | ||
489 | #define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5) | ||
490 | #define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16 | ||
491 | #define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16) | ||
492 | #define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20) | ||
493 | |||
494 | #define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40)) | ||
495 | #define HW_CLKCTRL_XBUS__DIV_BP 0 | ||
496 | #define HW_CLKCTRL_XBUS__DIV_BM 0x3ff | ||
497 | #define HW_CLKCTRL_XBUS__BUSY (1 << 31) | ||
498 | |||
499 | #define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50)) | ||
500 | #define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26) | ||
501 | #define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28) | ||
502 | #define HW_CLKCTRL_XTAL__PWM_CLK24M_GATE (1 << 29) | ||
503 | #define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30) | ||
504 | |||
505 | #define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60)) | ||
506 | #define HW_CLKCTRL_PIX__DIV_BP 0 | ||
507 | #define HW_CLKCTRL_PIX__DIV_BM 0xfff | ||
508 | |||
509 | #define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70)) | ||
510 | #define HW_CLKCTRL_SSP__DIV_BP 0 | ||
511 | #define HW_CLKCTRL_SSP__DIV_BM 0x1ff | ||
512 | |||
513 | #define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0)) | ||
514 | #define HW_CLKCTRL_EMI__DIV_EMI_BP 0 | ||
515 | #define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f | ||
516 | #define HW_CLKCTRL_EMI__DIV_XTAL_BP 8 | ||
517 | #define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8) | ||
518 | #define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28) | ||
519 | #define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30) | ||
520 | #define HW_CLKCTRL_EMI__CLKGATE (1 << 31) | ||
521 | |||
522 | #ifdef HAVE_STMP3770 | ||
523 | #define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xe0)) | ||
524 | #else | ||
525 | #define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110)) | ||
526 | #endif | ||
527 | #define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1) | ||
528 | #define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5) | ||
529 | #define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6) | ||
530 | #define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7) | ||
531 | |||
532 | #ifdef HAVE_STMP3770 | ||
533 | #define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xd0)) | ||
534 | #else | ||
535 | #define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0)) | ||
536 | #endif | ||
537 | #define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0)) | ||
538 | #define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1)) | ||
539 | #define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2)) | ||
540 | #define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3)) | ||
541 | #define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f | ||
542 | #define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6) | ||
543 | #define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7) | ||
544 | |||
545 | #define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120)) | ||
546 | #define HW_CLKCTRL_RESET_CHIP 0x2 | ||
547 | #define HW_CLKCTRL_RESET_DIG 0x1 | ||
548 | |||
549 | /** | ||
550 | * | ||
551 | * DMA | ||
552 | * | ||
553 | */ | ||
554 | |||
555 | /******** | ||
556 | * APHB * | ||
557 | ********/ | ||
558 | |||
559 | #define HW_APBH_BASE 0x80004000 | ||
560 | |||
561 | /* APHB channels */ | ||
562 | #define HW_APBH_SSP(ssp) ssp | ||
563 | |||
564 | #define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0)) | ||
565 | #define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i)) | ||
566 | #define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8)) | ||
567 | #define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16)) | ||
568 | #define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28) | ||
569 | #define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29) | ||
570 | |||
571 | #define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10)) | ||
572 | #define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i)) | ||
573 | #define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16)) | ||
574 | |||
575 | #define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20)) | ||
576 | #define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i)) | ||
577 | #define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16)) | ||
578 | |||
579 | #define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i))) | ||
580 | |||
581 | #define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i))) | ||
582 | |||
583 | #define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i))) | ||
584 | |||
585 | #define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i))) | ||
586 | |||
587 | #define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i))) | ||
588 | |||
589 | #define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i))) | ||
590 | |||
591 | #define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i))) | ||
592 | #define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0 | ||
593 | #define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff | ||
594 | #define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16 | ||
595 | #define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000 | ||
596 | |||
597 | /******** | ||
598 | * APHX * | ||
599 | ********/ | ||
600 | |||
601 | /* APHX channels */ | ||
602 | #define HW_APBX_AUDIO_ADC 0 | ||
603 | #define HW_APBX_AUDIO_DAC 1 | ||
604 | #define HW_APBX_I2C 3 | ||
605 | |||
606 | #define HW_APBX_BASE 0x80024000 | ||
607 | |||
608 | #define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0)) | ||
609 | |||
610 | #define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10)) | ||
611 | #define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i)) | ||
612 | #define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16)) | ||
613 | |||
614 | #define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20)) | ||
615 | #define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i)) | ||
616 | #define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16)) | ||
617 | |||
618 | #define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30)) | ||
619 | #define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i)) | ||
620 | #define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16)) | ||
621 | |||
622 | #define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70)) | ||
623 | |||
624 | #define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70)) | ||
625 | |||
626 | #define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70)) | ||
627 | |||
628 | #define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70)) | ||
629 | |||
630 | #define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70)) | ||
631 | |||
632 | #define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70)) | ||
633 | |||
634 | #define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70)) | ||
635 | #define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0 | ||
636 | #define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff | ||
637 | #define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16 | ||
638 | #define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000 | ||
639 | |||
640 | /********** | ||
641 | * COMMON * | ||
642 | **********/ | ||
643 | |||
644 | struct apb_dma_command_t | ||
645 | { | ||
646 | struct apb_dma_command_t *next; | ||
647 | uint32_t cmd; | ||
648 | void *buffer; | ||
649 | /* PIO words follow */ | ||
650 | }; | ||
651 | |||
652 | #define APBH_DMA_CHANNEL(i) i | ||
653 | #define APBX_DMA_CHANNEL(i) ((i) | 0x10) | ||
654 | #define APB_IS_APBX_CHANNEL(x) ((x) & 0x10) | ||
655 | #define APB_GET_DMA_CHANNEL(x) ((x) & 0xf) | ||
656 | |||
657 | #define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp)) | ||
658 | #define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC) | ||
659 | #define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC) | ||
660 | #define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C) | ||
661 | |||
662 | #define HW_APB_CHx_CMD__COMMAND_BM 0x3 | ||
663 | #define HW_APB_CHx_CMD__COMMAND__NO_XFER 0 | ||
664 | #define HW_APB_CHx_CMD__COMMAND__WRITE 1 | ||
665 | #define HW_APB_CHx_CMD__COMMAND__READ 2 | ||
666 | #define HW_APB_CHx_CMD__COMMAND__SENSE 3 | ||
667 | #define HW_APB_CHx_CMD__CHAIN (1 << 2) | ||
668 | #define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3) | ||
669 | /* those two are only available on APHB */ | ||
670 | #define HW_APBH_CHx_CMD__NANDLOCK (1 << 4) | ||
671 | #define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5) | ||
672 | #define HW_APB_CHx_CMD__SEMAPHORE (1 << 6) | ||
673 | #define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7) | ||
674 | /* An errata advise not to use it */ | ||
675 | //#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8) | ||
676 | #define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000 | ||
677 | #define HW_APB_CHx_CMD__CMDWORDS_BP 12 | ||
678 | #define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000 | ||
679 | #define HW_APB_CHx_CMD__XFER_COUNT_BP 16 | ||
680 | /* For software use */ | ||
681 | #define HW_APB_CHx_CMD__UNUSED_BP 8 | ||
682 | #define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8) | ||
683 | #define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8) | ||
684 | |||
685 | #define HW_APB_CHx_SEMA__PHORE_BM 0xff0000 | ||
686 | #define HW_APB_CHx_SEMA__PHORE_BP 16 | ||
687 | |||
688 | /* A single descriptor cannot transfer more than 2^16 bytes */ | ||
689 | #define IMX233_MAX_SINGLE_DMA_XFER_SIZE (1 << 16) | ||
690 | |||
691 | static void imx233_dma_init(void) | ||
692 | { | ||
693 | __REG_CLR(HW_APBH_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST; | ||
694 | __REG_CLR(HW_APBX_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST; | ||
695 | } | ||
696 | |||
697 | static void imx233_dma_reset_channel(unsigned chan) | ||
698 | { | ||
699 | volatile uint32_t *ptr; | ||
700 | uint32_t bm; | ||
701 | if(APB_IS_APBX_CHANNEL(chan)) | ||
702 | { | ||
703 | ptr = &HW_APBX_CHANNEL_CTRL; | ||
704 | bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan)); | ||
705 | } | ||
706 | else | ||
707 | { | ||
708 | ptr = &HW_APBH_CTRL0; | ||
709 | bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan)); | ||
710 | } | ||
711 | __REG_SET(*ptr) = bm; | ||
712 | /* wait for end of reset */ | ||
713 | while(*ptr & bm) | ||
714 | ; | ||
715 | } | ||
716 | |||
717 | static void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd) | ||
718 | { | ||
719 | if(APB_IS_APBX_CHANNEL(chan)) | ||
720 | { | ||
721 | HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd; | ||
722 | HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1; | ||
723 | } | ||
724 | else | ||
725 | { | ||
726 | HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd; | ||
727 | HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | static void imx233_dma_wait_completion(unsigned chan) | ||
732 | { | ||
733 | volatile uint32_t *sema; | ||
734 | if(APB_IS_APBX_CHANNEL(chan)) | ||
735 | sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); | ||
736 | else | ||
737 | sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)); | ||
738 | |||
739 | while(*sema & HW_APB_CHx_SEMA__PHORE_BM) | ||
740 | ; | ||
741 | } | ||
742 | |||
743 | /** | ||
744 | * | ||
745 | * Digctl | ||
746 | * | ||
747 | */ | ||
748 | |||
749 | /* Digital control */ | ||
750 | #define HW_DIGCTL_BASE 0x8001C000 | ||
751 | #define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) | ||
752 | #define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) | ||
753 | |||
754 | #define HW_DIGCTL_HCLKCOUNT (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x20)) | ||
755 | |||
756 | #define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) | ||
757 | |||
758 | #define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) | ||
759 | #define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 | ||
760 | #define HW_DIGCTL_CHIPID__PRODUCT_CODE_BM 0xffff0000 | ||
761 | #define HW_DIGCTL_CHIPID__REVISION_BP 0 | ||
762 | #define HW_DIGCTL_CHIPID__REVISION_BM 0xff | ||
763 | |||
764 | static bool imx233_us_elapsed(uint32_t ref, unsigned us_delay) | ||
765 | { | ||
766 | uint32_t cur = HW_DIGCTL_MICROSECONDS; | ||
767 | if(ref + us_delay <= ref) | ||
768 | return !(cur > ref) && !(cur < (ref + us_delay)); | ||
769 | else | ||
770 | return (cur < ref) || cur >= (ref + us_delay); | ||
771 | } | ||
772 | |||
773 | static void udelay(unsigned us) | ||
774 | { | ||
775 | uint32_t ref = HW_DIGCTL_MICROSECONDS; | ||
776 | while(!imx233_us_elapsed(ref, us)); | ||
777 | } | ||
778 | |||
779 | #define HZ 1000000 | ||
780 | |||
781 | /** | ||
782 | * | ||
783 | * USB PHY | ||
784 | * | ||
785 | */ | ||
786 | /* USB Phy */ | ||
787 | #define HW_USBPHY_BASE 0x8007C000 | ||
788 | #define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0)) | ||
789 | #define HW_USBPHY_PWD__ALL (7 << 10 | 0xf << 17) | ||
790 | |||
791 | #define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30)) | ||
792 | |||
793 | /** | ||
794 | * | ||
795 | * DCP | ||
796 | * | ||
797 | */ | ||
798 | #define HW_DCP_BASE 0x80028000 | ||
799 | |||
800 | #define HW_DCP_CTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x0)) | ||
801 | |||
802 | #define HW_DCP_STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x10)) | ||
803 | #define HW_DCP_STAT__IRQ(x) (1 << (x)) | ||
804 | |||
805 | #define HW_DCP_CHANNELCTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x20)) | ||
806 | #define HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(x) (1 << (x)) | ||
807 | |||
808 | #define HW_DCP_CH0CMDPTR (*(volatile unsigned long *)(HW_DCP_BASE + 0x100)) | ||
809 | |||
810 | #define HW_DCP_CH0SEMA (*(volatile unsigned long *)(HW_DCP_BASE + 0x110)) | ||
811 | #define HW_DCP_CH0SEMA__INCREMENT(x) (x) | ||
812 | #define HW_DCP_CH0SEMA__VALUE_BP 16 | ||
813 | #define HW_DCP_CH0SEMA__VALUE_BM (0xff << 16) | ||
814 | #define HW_DCP_CH0STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x120)) | ||
815 | |||
816 | #define HW_DCP_CTRL0__INTERRUPT_ENABLE (1 << 0) | ||
817 | #define HW_DCP_CTRL0__DECR_SEMAPHORE (1 << 1) | ||
818 | #define HW_DCP_CTRL0__ENABLE_MEMCOPY (1 << 4) | ||
819 | #define HW_DCP_CTRL0__ENABLE_CIPHER (1 << 5) | ||
820 | #define HW_DCP_CTRL0__ENABLE_HASH (1 << 6) | ||
821 | #define HW_DCP_CTRL0__CIPHER_ENCRYPT (1 << 8) | ||
822 | #define HW_DCP_CTRL0__CIPHER_INIT (1 << 9) | ||
823 | #define HW_DCP_CTRL0__OTP_KEY (1 << 10) | ||
824 | #define HW_DCP_CTRL0__HASH_INIT (1 << 12) | ||
825 | #define HW_DCP_CTRL0__HASH_TERM (1 << 13) | ||
826 | #define HW_DCP_CTRL0__HASH_OUTPUT (1 << 15) | ||
827 | |||
828 | #define HW_DCP_CTRL1__CIPHER_SELECT_BP 0 | ||
829 | #define HW_DCP_CTRL1__CIPHER_SELECT_BM 0xf | ||
830 | #define HW_DCP_CTRL1__CIPHER_SELECT__AES128 0 | ||
831 | #define HW_DCP_CTRL1__CIPHER_MODE_BP 4 | ||
832 | #define HW_DCP_CTRL1__CIPHER_MODE_BM 0xf0 | ||
833 | #define HW_DCP_CTRL1__CIPHER_MODE__CBC (1 << 4) | ||
834 | #define HW_DCP_CTRL1__HASH_SELECT_BP 4 | ||
835 | #define HW_DCP_CTRL1__HASH_SELECT_BM 0xf00 | ||
836 | |||
837 | struct dcp_packet_t | ||
838 | { | ||
839 | unsigned long next; | ||
840 | unsigned long ctrl0; | ||
841 | unsigned long ctrl1; | ||
842 | unsigned long src_buf; | ||
843 | unsigned long dst_buf; | ||
844 | unsigned long buf_sz; | ||
845 | unsigned long payload_ptr; | ||
846 | unsigned long status; | ||
847 | } __attribute__((packed)); | ||
848 | |||
849 | /** | ||
850 | * | ||
851 | * Misc | ||
852 | * | ||
853 | */ | ||
854 | |||
855 | void memcpy(uint8_t *dst, const uint8_t *src, uint32_t length) | ||
856 | { | ||
857 | for(uint32_t i = 0; i < length; i++) | ||
858 | dst[i] = src[i]; | ||
859 | } | ||
860 | |||
861 | void memset(uint8_t *dst, uint8_t fill, uint32_t length) | ||
862 | { | ||
863 | for(uint32_t i = 0; i < length; i++) | ||
864 | dst[i] = fill; | ||
865 | } | ||
866 | |||
867 | /** | ||
868 | * | ||
869 | * USB stack | ||
870 | * | ||
871 | */ | ||
872 | |||
873 | static struct usb_device_descriptor __attribute__((aligned(2))) | ||
874 | device_descriptor= | ||
875 | { | ||
876 | .bLength = sizeof(struct usb_device_descriptor), | ||
877 | .bDescriptorType = USB_DT_DEVICE, | ||
878 | .bcdUSB = 0x0200, | ||
879 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | ||
880 | .bDeviceSubClass = 0, | ||
881 | .bDeviceProtocol = 0, | ||
882 | .bMaxPacketSize0 = 64, | ||
883 | .idVendor = HWEMUL_USB_VID, | ||
884 | .idProduct = HWEMUL_USB_PID, | ||
885 | .bcdDevice = HWEMUL_VERSION_MAJOR << 8 | HWEMUL_VERSION_MINOR, | ||
886 | .iManufacturer = 1, | ||
887 | .iProduct = 2, | ||
888 | .iSerialNumber = 3, | ||
889 | .bNumConfigurations = 1 | ||
890 | }; | ||
891 | |||
892 | #define USB_MAX_CURRENT 200 | ||
893 | |||
894 | static struct usb_config_descriptor __attribute__((aligned(2))) | ||
895 | config_descriptor = | ||
896 | { | ||
897 | .bLength = sizeof(struct usb_config_descriptor), | ||
898 | .bDescriptorType = USB_DT_CONFIG, | ||
899 | .wTotalLength = 0, /* will be filled in later */ | ||
900 | .bNumInterfaces = 1, | ||
901 | .bConfigurationValue = 1, | ||
902 | .iConfiguration = 0, | ||
903 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
904 | .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */ | ||
905 | }; | ||
906 | |||
907 | /* main interface */ | ||
908 | static struct usb_interface_descriptor __attribute__((aligned(2))) | ||
909 | interface_descriptor = | ||
910 | { | ||
911 | .bLength = sizeof(struct usb_interface_descriptor), | ||
912 | .bDescriptorType = USB_DT_INTERFACE, | ||
913 | .bInterfaceNumber = 0, | ||
914 | .bAlternateSetting = 0, | ||
915 | .bNumEndpoints = 3, | ||
916 | .bInterfaceClass = HWEMUL_CLASS, | ||
917 | .bInterfaceSubClass = HWEMUL_SUBCLASS, | ||
918 | .bInterfaceProtocol = HWEMUL_PROTOCOL, | ||
919 | .iInterface = 4 | ||
920 | }; | ||
921 | |||
922 | |||
923 | static struct usb_endpoint_descriptor __attribute__((aligned(2))) | ||
924 | endpoint_descriptor = | ||
925 | { | ||
926 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
927 | .bDescriptorType = USB_DT_ENDPOINT, | ||
928 | .bEndpointAddress = 0, | ||
929 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
930 | .wMaxPacketSize = 0, | ||
931 | .bInterval = 0 | ||
932 | }; | ||
933 | |||
934 | static const struct usb_string_descriptor __attribute__((aligned(2))) | ||
935 | usb_string_iManufacturer = | ||
936 | { | ||
937 | 24, | ||
938 | USB_DT_STRING, | ||
939 | {'R', 'o', 'c', 'k', 'b', 'o', 'x', '.', 'o', 'r', 'g'} | ||
940 | }; | ||
941 | |||
942 | static const struct usb_string_descriptor __attribute__((aligned(2))) | ||
943 | usb_string_iProduct = | ||
944 | { | ||
945 | 52, | ||
946 | USB_DT_STRING, | ||
947 | {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ', | ||
948 | 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ', | ||
949 | 'e', 'm', 'u', 'l', 'a', 't', 'e', 'r'} | ||
950 | }; | ||
951 | |||
952 | static struct usb_string_descriptor __attribute__((aligned(2))) | ||
953 | usb_string_iSerial = | ||
954 | { | ||
955 | 84, | ||
956 | USB_DT_STRING, | ||
957 | {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
958 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
959 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
960 | '0', '0', '0', '0', '0', '0', '0', '0'} | ||
961 | }; | ||
962 | |||
963 | static struct usb_string_descriptor __attribute__((aligned(2))) | ||
964 | usb_string_iInterface = | ||
965 | { | ||
966 | 28, | ||
967 | USB_DT_STRING, | ||
968 | {'A', 'c', 'i', 'd', ' ', | ||
969 | '0' + (HWEMUL_VERSION_MAJOR >> 4), '0' + (HWEMUL_VERSION_MAJOR & 0xf), '.', | ||
970 | '0' + (HWEMUL_VERSION_MINOR >> 4), '0' + (HWEMUL_VERSION_MINOR & 0xf), '.', | ||
971 | '0' + (HWEMUL_VERSION_REV >> 4), '0' + (HWEMUL_VERSION_REV & 0xf) } | ||
972 | }; | ||
973 | |||
974 | /* this is stringid #0: languages supported */ | ||
975 | static const struct usb_string_descriptor __attribute__((aligned(2))) | ||
976 | lang_descriptor = | ||
977 | { | ||
978 | 4, | ||
979 | USB_DT_STRING, | ||
980 | {0x0409} /* LANGID US English */ | ||
981 | }; | ||
982 | |||
983 | #define USB_NUM_STRINGS 5 | ||
984 | |||
985 | static const struct usb_string_descriptor* const usb_strings[USB_NUM_STRINGS] = | ||
986 | { | ||
987 | &lang_descriptor, | ||
988 | &usb_string_iManufacturer, | ||
989 | &usb_string_iProduct, | ||
990 | &usb_string_iSerial, | ||
991 | &usb_string_iInterface | ||
992 | }; | ||
993 | |||
994 | uint8_t *usb_buffer = oc_bufferstart; | ||
995 | uint32_t usb_buffer_size = 0; | ||
996 | |||
997 | #define EP_BULK 1 | ||
998 | #define EP_INT 2 | ||
999 | |||
1000 | static void set_config(void) | ||
1001 | { | ||
1002 | usb_drv_configure_endpoint(EP_BULK, USB_ENDPOINT_XFER_BULK); | ||
1003 | usb_drv_configure_endpoint(EP_INT, USB_ENDPOINT_XFER_INT); | ||
1004 | } | ||
1005 | |||
1006 | static void handle_std_dev_desc(struct usb_ctrlrequest *req) | ||
1007 | { | ||
1008 | int size; | ||
1009 | const void* ptr = NULL; | ||
1010 | unsigned index = req->wValue & 0xff; | ||
1011 | |||
1012 | switch(req->wValue >> 8) | ||
1013 | { | ||
1014 | case USB_DT_DEVICE: | ||
1015 | ptr = &device_descriptor; | ||
1016 | size = sizeof(struct usb_device_descriptor); | ||
1017 | break; | ||
1018 | case USB_DT_OTHER_SPEED_CONFIG: | ||
1019 | case USB_DT_CONFIG: | ||
1020 | { | ||
1021 | int max_packet_size; | ||
1022 | |||
1023 | /* config desc */ | ||
1024 | if((req->wValue >> 8) ==USB_DT_CONFIG) | ||
1025 | { | ||
1026 | max_packet_size = (usb_drv_port_speed() ? 512 : 64); | ||
1027 | config_descriptor.bDescriptorType = USB_DT_CONFIG; | ||
1028 | } | ||
1029 | else | ||
1030 | { | ||
1031 | max_packet_size=(usb_drv_port_speed() ? 64 : 512); | ||
1032 | config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; | ||
1033 | } | ||
1034 | size = sizeof(struct usb_config_descriptor); | ||
1035 | |||
1036 | /* interface */ | ||
1037 | memcpy(usb_buffer + size, (void *)&interface_descriptor, | ||
1038 | sizeof(interface_descriptor)); | ||
1039 | size += sizeof(interface_descriptor); | ||
1040 | /* endpoint 1: bulk out */ | ||
1041 | endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT; | ||
1042 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; | ||
1043 | endpoint_descriptor.wMaxPacketSize = 512; | ||
1044 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | ||
1045 | sizeof(endpoint_descriptor)); | ||
1046 | size += sizeof(endpoint_descriptor); | ||
1047 | /* endpoint 2: bulk in */ | ||
1048 | endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN; | ||
1049 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; | ||
1050 | endpoint_descriptor.wMaxPacketSize = 512; | ||
1051 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | ||
1052 | sizeof(endpoint_descriptor)); | ||
1053 | size += sizeof(endpoint_descriptor); | ||
1054 | /* endpoint 3: int in */ | ||
1055 | endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN; | ||
1056 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT; | ||
1057 | endpoint_descriptor.wMaxPacketSize = 1024; | ||
1058 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | ||
1059 | sizeof(endpoint_descriptor)); | ||
1060 | size += sizeof(endpoint_descriptor); | ||
1061 | |||
1062 | /* fix config descriptor */ | ||
1063 | config_descriptor.bNumInterfaces = 1; | ||
1064 | config_descriptor.wTotalLength = size; | ||
1065 | memcpy(usb_buffer, (void *)&config_descriptor, sizeof(config_descriptor)); | ||
1066 | |||
1067 | ptr = usb_buffer; | ||
1068 | break; | ||
1069 | } | ||
1070 | case USB_DT_STRING: | ||
1071 | if(index < USB_NUM_STRINGS) | ||
1072 | { | ||
1073 | size = usb_strings[index]->bLength; | ||
1074 | ptr = usb_strings[index]; | ||
1075 | } | ||
1076 | else | ||
1077 | usb_drv_stall(EP_CONTROL, true, true); | ||
1078 | break; | ||
1079 | default: | ||
1080 | break; | ||
1081 | } | ||
1082 | |||
1083 | if(ptr) | ||
1084 | { | ||
1085 | int length = MIN(size, req->wLength); | ||
1086 | |||
1087 | if(ptr != usb_buffer) | ||
1088 | memcpy(usb_buffer, ptr, length); | ||
1089 | |||
1090 | usb_drv_send(EP_CONTROL, usb_buffer, length); | ||
1091 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
1092 | } | ||
1093 | else | ||
1094 | usb_drv_stall(EP_CONTROL, true, true); | ||
1095 | } | ||
1096 | |||
1097 | static void handle_std_dev_req(struct usb_ctrlrequest *req) | ||
1098 | { | ||
1099 | switch(req->bRequest) | ||
1100 | { | ||
1101 | case USB_REQ_GET_CONFIGURATION: | ||
1102 | usb_buffer[0] = 1; | ||
1103 | usb_drv_send(EP_CONTROL, usb_buffer, 1); | ||
1104 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
1105 | break; | ||
1106 | case USB_REQ_SET_CONFIGURATION: | ||
1107 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
1108 | set_config(); | ||
1109 | break; | ||
1110 | case USB_REQ_GET_DESCRIPTOR: | ||
1111 | handle_std_dev_desc(req); | ||
1112 | break; | ||
1113 | case USB_REQ_SET_ADDRESS: | ||
1114 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
1115 | usb_drv_set_address(req->wValue); | ||
1116 | break; | ||
1117 | case USB_REQ_GET_STATUS: | ||
1118 | usb_buffer[0] = 0; | ||
1119 | usb_buffer[1] = 0; | ||
1120 | usb_drv_send(EP_CONTROL, usb_buffer, 2); | ||
1121 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
1122 | break; | ||
1123 | default: | ||
1124 | usb_drv_stall(EP_CONTROL, true, true); | ||
1125 | } | ||
1126 | } | ||
1127 | |||
1128 | static void handle_std_req(struct usb_ctrlrequest *req) | ||
1129 | { | ||
1130 | switch(req->bRequestType & USB_RECIP_MASK) | ||
1131 | { | ||
1132 | case USB_RECIP_DEVICE: | ||
1133 | return handle_std_dev_req(req); | ||
1134 | default: | ||
1135 | usb_drv_stall(EP_CONTROL, true, true); | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | struct usb_resp_info_version_t g_version = | ||
1140 | { | ||
1141 | .major = HWEMUL_VERSION_MAJOR, | ||
1142 | .minor = HWEMUL_VERSION_MINOR, | ||
1143 | .revision = HWEMUL_VERSION_REV | ||
1144 | }; | ||
1145 | |||
1146 | struct usb_resp_info_layout_t g_layout; | ||
1147 | |||
1148 | struct usb_resp_info_stmp_t g_stmp; | ||
1149 | |||
1150 | struct usb_resp_info_features_t g_features = | ||
1151 | { | ||
1152 | .feature_mask = HWEMUL_FEATURE_LOG | HWEMUL_FEATURE_MEM | | ||
1153 | HWEMUL_FEATURE_CALL | HWEMUL_FEATURE_JUMP | HWEMUL_FEATURE_AES_OTP | ||
1154 | }; | ||
1155 | |||
1156 | static void fill_layout_info(void) | ||
1157 | { | ||
1158 | g_layout.oc_code_start = (uint32_t)oc_codestart; | ||
1159 | g_layout.oc_code_size = oc_codesize; | ||
1160 | g_layout.oc_stack_start = (uint32_t)oc_stackstart; | ||
1161 | g_layout.oc_stack_size = oc_stacksize; | ||
1162 | g_layout.oc_buffer_start = (uint32_t)oc_bufferstart; | ||
1163 | g_layout.oc_buffer_size = oc_buffersize; | ||
1164 | } | ||
1165 | |||
1166 | static void fill_stmp_info(void) | ||
1167 | { | ||
1168 | g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | ||
1169 | g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION); | ||
1170 | g_stmp.is_supported = g_stmp.chipid == 0x3780 || g_stmp.chipid == 0x3700 || | ||
1171 | g_stmp.chipid == 0x3b00; | ||
1172 | } | ||
1173 | |||
1174 | static void handle_get_info(struct usb_ctrlrequest *req) | ||
1175 | { | ||
1176 | void *ptr = NULL; | ||
1177 | int size = 0; | ||
1178 | switch(req->wIndex) | ||
1179 | { | ||
1180 | case HWEMUL_INFO_VERSION: | ||
1181 | ptr = &g_version; | ||
1182 | size = sizeof(g_version); | ||
1183 | break; | ||
1184 | case HWEMUL_INFO_LAYOUT: | ||
1185 | fill_layout_info(); | ||
1186 | ptr = &g_layout; | ||
1187 | size = sizeof(g_layout); | ||
1188 | break; | ||
1189 | case HWEMUL_INFO_STMP: | ||
1190 | fill_stmp_info(); | ||
1191 | ptr = &g_stmp; | ||
1192 | size = sizeof(g_stmp); | ||
1193 | break; | ||
1194 | case HWEMUL_INFO_FEATURES: | ||
1195 | ptr = &g_features; | ||
1196 | size = sizeof(g_features); | ||
1197 | break; | ||
1198 | default: | ||
1199 | usb_drv_stall(EP_CONTROL, true, true); | ||
1200 | } | ||
1201 | |||
1202 | if(ptr) | ||
1203 | { | ||
1204 | int length = MIN(size, req->wLength); | ||
1205 | |||
1206 | if(ptr != usb_buffer) | ||
1207 | memcpy(usb_buffer, ptr, length); | ||
1208 | usb_drv_send(EP_CONTROL, usb_buffer, length); | ||
1209 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | static void handle_get_log(struct usb_ctrlrequest *req) | ||
1214 | { | ||
1215 | enable_logf(false); | ||
1216 | int length = logf_readback(usb_buffer, MIN(req->wLength, usb_buffer_size)); | ||
1217 | usb_drv_send(EP_CONTROL, usb_buffer, length); | ||
1218 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
1219 | enable_logf(true); | ||
1220 | } | ||
1221 | |||
1222 | static void handle_rw_mem(struct usb_ctrlrequest *req) | ||
1223 | { | ||
1224 | uint32_t addr = req->wValue | req->wIndex << 16; | ||
1225 | uint16_t length = req->wLength; | ||
1226 | |||
1227 | if(req->bRequestType & USB_DIR_IN) | ||
1228 | { | ||
1229 | memcpy(usb_buffer, (void *)addr, length); | ||
1230 | asm volatile("nop" : : : "memory"); | ||
1231 | usb_drv_send(EP_CONTROL, usb_buffer, length); | ||
1232 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
1233 | } | ||
1234 | else | ||
1235 | { | ||
1236 | int size = usb_drv_recv(EP_CONTROL, usb_buffer, length); | ||
1237 | asm volatile("nop" : : : "memory"); | ||
1238 | if(size != length) | ||
1239 | usb_drv_stall(EP_CONTROL, true, true); | ||
1240 | else | ||
1241 | { | ||
1242 | memcpy((void *)addr, usb_buffer, length); | ||
1243 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
1244 | } | ||
1245 | } | ||
1246 | } | ||
1247 | |||
1248 | static void handle_call_jump(struct usb_ctrlrequest *req) | ||
1249 | { | ||
1250 | uint32_t addr = req->wValue | req->wIndex << 16; | ||
1251 | |||
1252 | if(req->bRequest == HWEMUL_CALL) | ||
1253 | ((void (*)(void))addr)(); | ||
1254 | else | ||
1255 | asm volatile("bx %0\n" : : "r" (addr) : "memory"); | ||
1256 | } | ||
1257 | |||
1258 | static void do_aes_otp(void *buffer, unsigned length, unsigned params) | ||
1259 | { | ||
1260 | static struct dcp_packet_t dcp_packet; | ||
1261 | |||
1262 | bool encrypt = !!(params & HWEMUL_AES_OTP_ENCRYPT); | ||
1263 | /* reset DCP */ | ||
1264 | __REG_SET(HW_DCP_CTRL) = 0x80000000; | ||
1265 | /* clear clock gate */ | ||
1266 | __REG_CLR(HW_DCP_CTRL) = 0xc0000000; | ||
1267 | /* enable dma for channel 0 */ | ||
1268 | __REG_SET(HW_DCP_CHANNELCTRL) = HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(0); | ||
1269 | /* prepare packet */ | ||
1270 | dcp_packet.next = 0; | ||
1271 | |||
1272 | dcp_packet.ctrl0 = HW_DCP_CTRL0__INTERRUPT_ENABLE | | ||
1273 | HW_DCP_CTRL0__DECR_SEMAPHORE | HW_DCP_CTRL0__CIPHER_INIT | | ||
1274 | HW_DCP_CTRL0__ENABLE_CIPHER | HW_DCP_CTRL0__OTP_KEY | | ||
1275 | (encrypt ? HW_DCP_CTRL0__CIPHER_ENCRYPT : 0); | ||
1276 | dcp_packet.ctrl1 = HW_DCP_CTRL1__CIPHER_SELECT__AES128 | | ||
1277 | HW_DCP_CTRL1__CIPHER_MODE__CBC; | ||
1278 | dcp_packet.src_buf = (unsigned long)buffer + 16; | ||
1279 | dcp_packet.dst_buf = (unsigned long)buffer + 16; | ||
1280 | dcp_packet.buf_sz = length - 16; | ||
1281 | dcp_packet.payload_ptr = (unsigned long)buffer; | ||
1282 | dcp_packet.status = 0; | ||
1283 | |||
1284 | asm volatile("":::"memory"); | ||
1285 | /* kick */ | ||
1286 | HW_DCP_CH0CMDPTR = (unsigned long)&dcp_packet; | ||
1287 | HW_DCP_CH0SEMA = HW_DCP_CH0SEMA__INCREMENT(1); | ||
1288 | /* wait */ | ||
1289 | while(!(HW_DCP_STAT & HW_DCP_STAT__IRQ(0))); | ||
1290 | |||
1291 | usb_drv_send_nonblocking(EP_INT, buffer, length); | ||
1292 | } | ||
1293 | |||
1294 | static void handle_aes_otp(struct usb_ctrlrequest *req) | ||
1295 | { | ||
1296 | uint16_t length = req->wLength; | ||
1297 | |||
1298 | int size = usb_drv_recv(EP_CONTROL, usb_buffer, length); | ||
1299 | if(size != length) | ||
1300 | usb_drv_stall(EP_CONTROL, true, true); | ||
1301 | else | ||
1302 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
1303 | do_aes_otp(usb_buffer, length, req->wValue); | ||
1304 | } | ||
1305 | |||
1306 | static void handle_class_dev_req(struct usb_ctrlrequest *req) | ||
1307 | { | ||
1308 | switch(req->bRequest) | ||
1309 | { | ||
1310 | case HWEMUL_GET_INFO: | ||
1311 | handle_get_info(req); | ||
1312 | break; | ||
1313 | case HWEMUL_GET_LOG: | ||
1314 | handle_get_log(req); | ||
1315 | break; | ||
1316 | case HWEMUL_RW_MEM: | ||
1317 | handle_rw_mem(req); | ||
1318 | break; | ||
1319 | case HWEMUL_CALL: | ||
1320 | case HWEMUL_JUMP: | ||
1321 | handle_call_jump(req); | ||
1322 | break; | ||
1323 | case HWEMUL_AES_OTP: | ||
1324 | handle_aes_otp(req); | ||
1325 | break; | ||
1326 | default: | ||
1327 | usb_drv_stall(EP_CONTROL, true, true); | ||
1328 | } | ||
1329 | } | ||
1330 | |||
1331 | static void handle_class_req(struct usb_ctrlrequest *req) | ||
1332 | { | ||
1333 | switch(req->bRequestType & USB_RECIP_MASK) | ||
1334 | { | ||
1335 | case USB_RECIP_DEVICE: | ||
1336 | return handle_class_dev_req(req); | ||
1337 | default: | ||
1338 | usb_drv_stall(EP_CONTROL, true, true); | ||
1339 | } | ||
1340 | } | ||
1341 | |||
1342 | /** | ||
1343 | * | ||
1344 | * Main | ||
1345 | * | ||
1346 | */ | ||
1347 | |||
1348 | void main(uint32_t arg) | ||
1349 | { | ||
1350 | usb_buffer_size = oc_buffersize; | ||
1351 | |||
1352 | logf("hwemul %d.%d.%d\n", HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR, | ||
1353 | HWEMUL_VERSION_REV); | ||
1354 | logf("argument: 0x%08x\n", arg); | ||
1355 | |||
1356 | /* we don't know if USB was connected or not. In USB recovery mode it will | ||
1357 | * but in other cases it might not be. In doubt, disconnect */ | ||
1358 | REG_USBCMD &= ~USBCMD_RUN; | ||
1359 | /* enable USB PHY PLL */ | ||
1360 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; | ||
1361 | /* power up USB PHY */ | ||
1362 | __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST; | ||
1363 | //__REG_CLR(HW_USBPHY_PWD) = HW_USBPHY_PWD__ALL; | ||
1364 | HW_USBPHY_PWD = 0; | ||
1365 | /* enable USB controller */ | ||
1366 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; | ||
1367 | /* reset the controller */ | ||
1368 | REG_USBCMD |= USBCMD_CTRL_RESET; | ||
1369 | while (REG_USBCMD & USBCMD_CTRL_RESET); | ||
1370 | /* put it in device mode */ | ||
1371 | REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; | ||
1372 | /* reset address */ | ||
1373 | REG_DEVICEADDR = 0; | ||
1374 | /* prepare qh array */ | ||
1375 | qh_array[0].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16; | ||
1376 | qh_array[1].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16; | ||
1377 | qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16; | ||
1378 | qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16; | ||
1379 | /* setup qh */ | ||
1380 | REG_ENDPOINTLISTADDR = (unsigned int)qh_array; | ||
1381 | /* clear setup status */ | ||
1382 | REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0; | ||
1383 | /* run! */ | ||
1384 | REG_USBCMD |= USBCMD_RUN; | ||
1385 | |||
1386 | while(1) | ||
1387 | { | ||
1388 | /* wait for setup */ | ||
1389 | while(!(REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) | ||
1390 | ; | ||
1391 | /* clear setup status */ | ||
1392 | REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0; | ||
1393 | /* check request */ | ||
1394 | asm volatile("":::"memory"); | ||
1395 | struct usb_ctrlrequest *req = (void *)&qh_array[0].setup_buffer[0]; | ||
1396 | |||
1397 | switch(req->bRequestType & USB_TYPE_MASK) | ||
1398 | { | ||
1399 | case USB_TYPE_STANDARD: | ||
1400 | handle_std_req(req); | ||
1401 | break; | ||
1402 | case USB_TYPE_CLASS: | ||
1403 | handle_class_req(req); | ||
1404 | break; | ||
1405 | default: | ||
1406 | usb_drv_stall(EP_CONTROL, true, true); | ||
1407 | } | ||
1408 | } | ||
1409 | } | ||
diff --git a/utils/imxtools/hwemul/dev/protocol.h b/utils/imxtools/hwemul/dev/protocol.h deleted file mode 100644 index d3ffb6ce00..0000000000 --- a/utils/imxtools/hwemul/dev/protocol.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include "../hwemul_protocol.h" | ||
diff --git a/utils/imxtools/hwemul/dev/stddef.h b/utils/imxtools/hwemul/dev/stddef.h deleted file mode 100644 index 9d59d2913c..0000000000 --- a/utils/imxtools/hwemul/dev/stddef.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
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 __HWEMUL_STDDEF__ | ||
22 | #define __HWEMUL_STDDEF__ | ||
23 | |||
24 | #include "stdint.h" | ||
25 | |||
26 | typedef uint32_t size_t; | ||
27 | typedef 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 /* __HWEMUL_STDDEF__ */ | ||
diff --git a/utils/imxtools/hwemul/dev/stdint.h b/utils/imxtools/hwemul/dev/stdint.h deleted file mode 100644 index 4fe3702c86..0000000000 --- a/utils/imxtools/hwemul/dev/stdint.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
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 | |||
25 | typedef signed char int8_t; | ||
26 | typedef unsigned char uint8_t; | ||
27 | typedef short int16_t; | ||
28 | typedef unsigned short uint16_t; | ||
29 | typedef long int32_t; | ||
30 | typedef unsigned long uint32_t; | ||
31 | typedef char bool; | ||
32 | |||
33 | #define true 1 | ||
34 | #define false 0 | ||
35 | |||
36 | #define NULL (void *)0 | ||
37 | |||
38 | #endif /* __STDINT_H__ */ | ||
diff --git a/utils/imxtools/hwemul/dev/string.c b/utils/imxtools/hwemul/dev/string.c deleted file mode 100644 index 1f8c415a99..0000000000 --- a/utils/imxtools/hwemul/dev/string.c +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
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 | |||
23 | size_t strlen(const char *s) | ||
24 | { | ||
25 | size_t len = 0; | ||
26 | while(*s++) | ||
27 | len++; | ||
28 | return len; | ||
29 | } | ||
diff --git a/utils/imxtools/hwemul/dev/string.h b/utils/imxtools/hwemul/dev/string.h deleted file mode 100644 index 7ef460ea6e..0000000000 --- a/utils/imxtools/hwemul/dev/string.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
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 __HWEMUL_STRING__ | ||
22 | #define __HWEMUL_STRING__ | ||
23 | |||
24 | #include "stddef.h" | ||
25 | |||
26 | void memset(void *dst, int c, size_t n); | ||
27 | void memcpy(void *dst, const void *src, size_t n); | ||
28 | size_t strlen(const char *s); | ||
29 | |||
30 | #endif /* __HWEMUL_STRING__ */ | ||
diff --git a/utils/imxtools/hwemul/dev/system.h b/utils/imxtools/hwemul/dev/system.h deleted file mode 100644 index c1babe7d87..0000000000 --- a/utils/imxtools/hwemul/dev/system.h +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
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 __HWEMUL_SYSTEM__ | ||
22 | #define __HWEMUL_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 | |||
59 | static 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 | |||
75 | static 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 | |||
82 | static 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 | |||
93 | static 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 | |||
104 | static 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 /* __HWEMUL_SYSTEM__ */ | ||
118 | |||
diff --git a/utils/imxtools/hwemul/dev/usb_ch9.h b/utils/imxtools/hwemul/dev/usb_ch9.h deleted file mode 100644 index 09141b93bd..0000000000 --- a/utils/imxtools/hwemul/dev/usb_ch9.h +++ /dev/null | |||
@@ -1,454 +0,0 @@ | |||
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 | */ | ||
148 | struct 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 */ | ||
204 | struct usb_descriptor_header { | ||
205 | uint8_t bLength; | ||
206 | uint8_t bDescriptorType; | ||
207 | } __attribute__ ((packed)); | ||
208 | |||
209 | |||
210 | /*-------------------------------------------------------------------------*/ | ||
211 | |||
212 | /* USB_DT_DEVICE: Device descriptor */ | ||
213 | struct 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 | */ | ||
267 | struct 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 */ | ||
290 | struct 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 */ | ||
304 | struct 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 */ | ||
322 | struct 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 */ | ||
353 | struct 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) */ | ||
370 | struct 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 */ | ||
384 | struct 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 | |||
396 | enum 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 | |||
403 | enum 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 | */ | ||
436 | struct 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 | */ | ||
449 | struct 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/imxtools/hwemul/hwemul_protocol.h b/utils/imxtools/hwemul/hwemul_protocol.h deleted file mode 100644 index f11fd91352..0000000000 --- a/utils/imxtools/hwemul/hwemul_protocol.h +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
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 __HWEMUL_PROTOCOL__ | ||
22 | #define __HWEMUL_PROTOCOL__ | ||
23 | |||
24 | #define HWEMUL_CLASS 0xfe | ||
25 | #define HWEMUL_SUBCLASS 0xac | ||
26 | #define HWEMUL_PROTOCOL 0x1d | ||
27 | |||
28 | #define HWEMUL_VERSION_MAJOR 2 | ||
29 | #define HWEMUL_VERSION_MINOR 8 | ||
30 | #define HWEMUL_VERSION_REV 2 | ||
31 | |||
32 | #define HWEMUL_USB_VID 0xfee1 | ||
33 | #define HWEMUL_USB_PID 0xdead | ||
34 | |||
35 | /** | ||
36 | * Control commands | ||
37 | * | ||
38 | * These commands are sent to the device, using the standard bRequest field | ||
39 | * of the SETUP packet. This is to take advantage of both wIndex and wValue | ||
40 | * although it would have been more correct to send them to the interface. | ||
41 | */ | ||
42 | |||
43 | /* list of commands */ | ||
44 | #define HWEMUL_GET_INFO 0 /* mandatory */ | ||
45 | #define HWEMUL_GET_LOG 1 /* optional */ | ||
46 | #define HWEMUL_RW_MEM 2 /* optional */ | ||
47 | #define HWEMUL_CALL 3 /* optional */ | ||
48 | #define HWEMUL_JUMP 4 /* optional */ | ||
49 | #define HWEMUL_AES_OTP 5 /* optional */ | ||
50 | |||
51 | /** | ||
52 | * HWEMUL_GET_INFO: get some information about an aspect of the device. | ||
53 | * The wIndex field of the SETUP specifies which information to get. */ | ||
54 | |||
55 | /* list of possible information */ | ||
56 | #define HWEMUL_INFO_VERSION 0 | ||
57 | #define HWEMUL_INFO_LAYOUT 1 | ||
58 | #define HWEMUL_INFO_STMP 2 | ||
59 | #define HWEMUL_INFO_FEATURES 3 | ||
60 | |||
61 | struct usb_resp_info_version_t | ||
62 | { | ||
63 | uint8_t major; | ||
64 | uint8_t minor; | ||
65 | uint8_t revision; | ||
66 | } __attribute__((packed)); | ||
67 | |||
68 | struct usb_resp_info_layout_t | ||
69 | { | ||
70 | /* describe the range of memory used by the running code */ | ||
71 | uint32_t oc_code_start; | ||
72 | uint32_t oc_code_size; | ||
73 | /* describe the range of memory used by the stack */ | ||
74 | uint32_t oc_stack_start; | ||
75 | uint32_t oc_stack_size; | ||
76 | /* describe the range of memory available as a buffer */ | ||
77 | uint32_t oc_buffer_start; | ||
78 | uint32_t oc_buffer_size; | ||
79 | } __attribute__((packed)); | ||
80 | |||
81 | struct usb_resp_info_stmp_t | ||
82 | { | ||
83 | uint16_t chipid; /* 0x3780 for STMP3780 for example */ | ||
84 | uint8_t rev; /* 0=TA1 on STMP3780 for example */ | ||
85 | uint8_t is_supported; /* 1 if the chip is supported */ | ||
86 | } __attribute__((packed)); | ||
87 | |||
88 | /* list of possible features */ | ||
89 | #define HWEMUL_FEATURE_LOG (1 << 0) | ||
90 | #define HWEMUL_FEATURE_MEM (1 << 1) | ||
91 | #define HWEMUL_FEATURE_CALL (1 << 2) | ||
92 | #define HWEMUL_FEATURE_JUMP (1 << 2) | ||
93 | #define HWEMUL_FEATURE_AES_OTP (1 << 3) | ||
94 | |||
95 | struct usb_resp_info_features_t | ||
96 | { | ||
97 | uint32_t feature_mask; | ||
98 | }; | ||
99 | |||
100 | /** | ||
101 | * HWEMUL_GET_LOG: only if has HWEMUL_FEATURE_LOG. | ||
102 | * The log is returned as part of the control transfer. | ||
103 | */ | ||
104 | |||
105 | /** | ||
106 | * HWEMUL_RW_MEM: only if has HWEMUL_FEATURE_MEM. | ||
107 | * The 32-bit address is split into two parts. | ||
108 | * The low 16-bit are stored in wValue and the upper | ||
109 | * 16-bit are stored in wIndex. Depending on the transfer direction, | ||
110 | * the transfer is either a read or a write. */ | ||
111 | |||
112 | /** | ||
113 | * HWEMUL_x: only if has HWEMUL_FEATURE_x where x=CALL or JUMP. | ||
114 | * The 32-bit address is split into two parts. | ||
115 | * The low 16-bit are stored in wValue and the upper | ||
116 | * 16-bit are stored in wIndex. Depending on the transfer direction, | ||
117 | * the transfer is either a read or a write. */ | ||
118 | |||
119 | /** | ||
120 | * HWEMUL_AES_OTP: only if has HWEMUL_FEATURE_AES_OTP. | ||
121 | * The control transfer contains the data to be en/decrypted and the data | ||
122 | * is sent back on the interrupt endpoint. The first 16-bytes of the data | ||
123 | * are interpreted as the IV. The output format is the same. | ||
124 | * The wValue field contains the parameters of the process. */ | ||
125 | #define HWEMUL_AES_OTP_ENCRYPT (1 << 0) | ||
126 | |||
127 | #endif /* __HWEMUL_PROTOCOL__ */ | ||
diff --git a/utils/imxtools/hwemul/lib/Makefile b/utils/imxtools/hwemul/lib/Makefile deleted file mode 100644 index 7280fe8e38..0000000000 --- a/utils/imxtools/hwemul/lib/Makefile +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | CC=gcc | ||
2 | AR=ar | ||
3 | CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -fPIC | ||
4 | LDFLAGS=`pkg-config --libs libusb-1.0` -fPIC | ||
5 | LIB=libhwemul.a | ||
6 | REGTOOLS=../../regtools | ||
7 | DESC=$(REGTOOLS)/desc | ||
8 | HWEMULGEN=$(REGTOOLS)/hwemulgen | ||
9 | HWEMULSOC_PREFIX=hwemul_soc | ||
10 | SRC=$(wildcard *.c) $(HWEMULSOC_PREFIX).c | ||
11 | OBJ=$(SRC:.c=.o) | ||
12 | |||
13 | all: $(LIB) $(EXEC) | ||
14 | |||
15 | $(HWEMULSOC_PREFIX).c $(HWEMULSOC_PREFIX).h: | ||
16 | $(HWEMULGEN) $(DESC)/*.xml $(HWEMULSOC_PREFIX) | ||
17 | |||
18 | %.o: %.c $(HWEMULSOC_PREFIX).h | ||
19 | $(CC) $(CFLAGS) -c -o $@ $< | ||
20 | |||
21 | $(LIB): $(OBJ) | ||
22 | $(AR) rcs $@ $^ | ||
23 | |||
24 | clean: | ||
25 | rm -rf $(OBJ) $(LIB) $(HWEMULSOC_PREFIX).c $(HWEMULSOC_PREFIX).h | ||
26 | |||
27 | |||
diff --git a/utils/imxtools/hwemul/lib/hwemul.c b/utils/imxtools/hwemul/lib/hwemul.c deleted file mode 100644 index 3e2e6de38a..0000000000 --- a/utils/imxtools/hwemul/lib/hwemul.c +++ /dev/null | |||
@@ -1,175 +0,0 @@ | |||
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 "hwemul.h" | ||
22 | #include "hwemul_soc.h" | ||
23 | |||
24 | #ifndef MIN | ||
25 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | ||
26 | #endif | ||
27 | |||
28 | /* requires then ->handle field only */ | ||
29 | int hwemul_probe(struct hwemul_device_t *dev) | ||
30 | { | ||
31 | libusb_device *mydev = libusb_get_device(dev->handle); | ||
32 | |||
33 | int config_id; | ||
34 | libusb_get_configuration(dev->handle, &config_id); | ||
35 | struct libusb_config_descriptor *config; | ||
36 | libusb_get_active_config_descriptor(mydev, &config); | ||
37 | |||
38 | const struct libusb_endpoint_descriptor *endp = NULL; | ||
39 | int intf; | ||
40 | for(intf = 0; intf < config->bNumInterfaces; intf++) | ||
41 | { | ||
42 | if(config->interface[intf].num_altsetting != 1) | ||
43 | continue; | ||
44 | const struct libusb_interface_descriptor *interface = | ||
45 | &config->interface[intf].altsetting[0]; | ||
46 | if(interface->bNumEndpoints != 3 || | ||
47 | interface->bInterfaceClass != HWEMUL_CLASS || | ||
48 | interface->bInterfaceSubClass != HWEMUL_SUBCLASS || | ||
49 | interface->bInterfaceProtocol != HWEMUL_PROTOCOL) | ||
50 | continue; | ||
51 | dev->intf = intf; | ||
52 | dev->bulk_in = dev->bulk_out = dev->int_in = -1; | ||
53 | for(int ep = 0; ep < interface->bNumEndpoints; ep++) | ||
54 | { | ||
55 | endp = &interface->endpoint[ep]; | ||
56 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_INTERRUPT && | ||
57 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) | ||
58 | dev->int_in = endp->bEndpointAddress; | ||
59 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && | ||
60 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) | ||
61 | dev->bulk_in = endp->bEndpointAddress; | ||
62 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && | ||
63 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) | ||
64 | dev->bulk_out = endp->bEndpointAddress; | ||
65 | } | ||
66 | if(dev->bulk_in == -1 || dev->bulk_out == -1 || dev->int_in == -1) | ||
67 | continue; | ||
68 | break; | ||
69 | } | ||
70 | if(intf == config->bNumInterfaces) | ||
71 | return 1; | ||
72 | |||
73 | return libusb_claim_interface(dev->handle, intf); | ||
74 | } | ||
75 | |||
76 | int hwemul_release(struct hwemul_device_t *dev) | ||
77 | { | ||
78 | return libusb_release_interface(dev->handle, dev->intf); | ||
79 | } | ||
80 | |||
81 | int hwemul_get_info(struct hwemul_device_t *dev, uint16_t idx, void *info, size_t sz) | ||
82 | { | ||
83 | return libusb_control_transfer(dev->handle, | ||
84 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, | ||
85 | HWEMUL_GET_INFO, 0, idx, info, sz, 1000); | ||
86 | } | ||
87 | |||
88 | int hwemul_get_log(struct hwemul_device_t *dev, void *buf, size_t sz) | ||
89 | { | ||
90 | return libusb_control_transfer(dev->handle, | ||
91 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, | ||
92 | HWEMUL_GET_LOG, 0, 0, buf, sz, 1000); | ||
93 | } | ||
94 | |||
95 | int hwemul_rw_mem(struct hwemul_device_t *dev, int read, uint32_t addr, void *buf, size_t sz) | ||
96 | { | ||
97 | size_t tot_sz = 0; | ||
98 | while(sz) | ||
99 | { | ||
100 | uint16_t xfer = MIN(1 * 1024, sz); | ||
101 | int ret = libusb_control_transfer(dev->handle, | ||
102 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
103 | (read ? LIBUSB_ENDPOINT_IN : LIBUSB_ENDPOINT_OUT), | ||
104 | HWEMUL_RW_MEM, addr & 0xffff, addr >> 16, buf, xfer, 1000); | ||
105 | if(ret != xfer) | ||
106 | return ret; | ||
107 | sz -= xfer; | ||
108 | addr += xfer; | ||
109 | buf += xfer; | ||
110 | tot_sz += xfer; | ||
111 | } | ||
112 | return tot_sz; | ||
113 | } | ||
114 | |||
115 | int hwemul_call(struct hwemul_device_t *dev, uint32_t addr) | ||
116 | { | ||
117 | return libusb_control_transfer(dev->handle, | ||
118 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
119 | LIBUSB_ENDPOINT_OUT, HWEMUL_CALL, addr & 0xffff, addr >> 16, NULL, 0, | ||
120 | 1000); | ||
121 | } | ||
122 | |||
123 | int hwemul_jump(struct hwemul_device_t *dev, uint32_t addr) | ||
124 | { | ||
125 | return libusb_control_transfer(dev->handle, | ||
126 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
127 | LIBUSB_ENDPOINT_OUT, HWEMUL_JUMP, addr & 0xffff, addr >> 16, NULL, 0, | ||
128 | 1000); | ||
129 | } | ||
130 | |||
131 | const char *hwemul_get_product_string(struct usb_resp_info_stmp_t *stmp) | ||
132 | { | ||
133 | switch(stmp->chipid) | ||
134 | { | ||
135 | case 0x3700: return "STMP 3700"; | ||
136 | case 0x37b0: return "STMP 3770"; | ||
137 | case 0x3780: return "STMP 3780 / i.MX233"; | ||
138 | default: return "unknown"; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | const char *hwemul_get_rev_string(struct usb_resp_info_stmp_t *stmp) | ||
143 | { | ||
144 | switch(stmp->chipid) | ||
145 | { | ||
146 | case 0x37b0: | ||
147 | case 0x3780: | ||
148 | switch(stmp->rev) | ||
149 | { | ||
150 | case 0: return "TA1"; | ||
151 | case 1: return "TA2"; | ||
152 | case 2: return "TA3"; | ||
153 | case 3: return "TA4"; | ||
154 | default: return "unknown"; | ||
155 | } | ||
156 | break; | ||
157 | default: | ||
158 | return "unknown"; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | int hwemul_aes_otp(struct hwemul_device_t *dev, void *buf, size_t sz, uint16_t param) | ||
163 | { | ||
164 | int ret = libusb_control_transfer(dev->handle, | ||
165 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
166 | LIBUSB_ENDPOINT_OUT, HWEMUL_AES_OTP, param, 0, buf, sz, | ||
167 | 1000); | ||
168 | if(ret <0 || (unsigned)ret != sz) | ||
169 | return -1; | ||
170 | int xfer; | ||
171 | ret = libusb_interrupt_transfer(dev->handle, dev->int_in, buf, sz, &xfer, 1000); | ||
172 | if(ret < 0 || (unsigned)xfer != sz) | ||
173 | return -1; | ||
174 | return ret; | ||
175 | } | ||
diff --git a/utils/imxtools/hwemul/lib/hwemul.h b/utils/imxtools/hwemul/lib/hwemul.h deleted file mode 100644 index 376ba65381..0000000000 --- a/utils/imxtools/hwemul/lib/hwemul.h +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
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 __HWEMUL__ | ||
22 | #define __HWEMUL__ | ||
23 | |||
24 | #include <libusb.h> | ||
25 | #include "hwemul_protocol.h" | ||
26 | #include "hwemul_soc.h" | ||
27 | |||
28 | /** | ||
29 | * | ||
30 | * Low-Level interface | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | struct hwemul_device_t | ||
35 | { | ||
36 | libusb_device_handle *handle; | ||
37 | int intf; | ||
38 | int bulk_in; | ||
39 | int bulk_out; | ||
40 | int int_in; | ||
41 | }; | ||
42 | |||
43 | /* Requires then ->handle field only. Returns 0 on success */ | ||
44 | int hwemul_probe(struct hwemul_device_t *dev); | ||
45 | /* Returns 0 on success */ | ||
46 | int hwemul_release(struct hwemul_device_t *dev); | ||
47 | |||
48 | /* Returns number of bytes filled */ | ||
49 | int hwemul_get_info(struct hwemul_device_t *dev, uint16_t idx, void *info, size_t sz); | ||
50 | /* Returns number of bytes filled */ | ||
51 | int hwemul_get_log(struct hwemul_device_t *dev, void *buf, size_t sz); | ||
52 | /* Returns number of bytes written/read or <0 on error */ | ||
53 | int hwemul_rw_mem(struct hwemul_device_t *dev, int read, uint32_t addr, void *buf, size_t sz); | ||
54 | /* Returns <0 on error */ | ||
55 | int hwemul_call(struct hwemul_device_t *dev, uint32_t addr); | ||
56 | int hwemul_jump(struct hwemul_device_t *dev, uint32_t addr); | ||
57 | /* Returns <0 on error. The size must be a multiple of 16. */ | ||
58 | int hwemul_aes_otp(struct hwemul_device_t *dev, void *buf, size_t sz, uint16_t param); | ||
59 | |||
60 | const char *hwemul_get_product_string(struct usb_resp_info_stmp_t *stmp); | ||
61 | const char *hwemul_get_rev_string(struct usb_resp_info_stmp_t *stmp); | ||
62 | |||
63 | #endif /* __HWEMUL__ */ \ No newline at end of file | ||
diff --git a/utils/imxtools/hwemul/lib/hwemul_protocol.h b/utils/imxtools/hwemul/lib/hwemul_protocol.h deleted file mode 100644 index d3ffb6ce00..0000000000 --- a/utils/imxtools/hwemul/lib/hwemul_protocol.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include "../hwemul_protocol.h" | ||
diff --git a/utils/imxtools/hwemul/tools/Makefile b/utils/imxtools/hwemul/tools/Makefile deleted file mode 100644 index 3466a4e776..0000000000 --- a/utils/imxtools/hwemul/tools/Makefile +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | CC=gcc | ||
2 | AR=ar | ||
3 | HWEMUL_LIB_DIR=../lib | ||
4 | CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -I$(HWEMUL_LIB_DIR) | ||
5 | LDFLAGS=`pkg-config --libs libusb-1.0` -lreadline | ||
6 | EXEC=hwemul_tool | ||
7 | HWEMUL_LIB=$(HWEMUL_LIB_DIR)/libhwemul.a | ||
8 | SRC=$(wildcard *.c) | ||
9 | OBJ=$(SRC:.c=.o) | ||
10 | |||
11 | all: $(EXEC) | ||
12 | |||
13 | %.o: %.c | ||
14 | $(CC) $(CFLAGS) -c -o $@ $< | ||
15 | |||
16 | hwemul_tool: hwemul_tool.o $(HWEMUL_LIB) | ||
17 | $(CC) -o $@ $^ $(LDFLAGS) | ||
18 | |||
19 | clean: | ||
20 | rm -rf $(OBJ) $(LIB) | ||
21 | |||
22 | |||
diff --git a/utils/imxtools/hwemul/tools/hwemul_tool.c b/utils/imxtools/hwemul/tools/hwemul_tool.c deleted file mode 100644 index d75cd7a957..0000000000 --- a/utils/imxtools/hwemul/tools/hwemul_tool.c +++ /dev/null | |||
@@ -1,558 +0,0 @@ | |||
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 "hwemul.h" | ||
22 | #include <stdio.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | #include <getopt.h> | ||
26 | #include <stdbool.h> | ||
27 | #include <readline/readline.h> | ||
28 | #include <readline/history.h> | ||
29 | |||
30 | bool g_quiet = false; | ||
31 | struct hwemul_device_t hwdev; | ||
32 | struct hwemul_soc_t *cur_soc = NULL; | ||
33 | |||
34 | void print_log(struct hwemul_device_t *hwdev) | ||
35 | { | ||
36 | do | ||
37 | { | ||
38 | char buffer[128]; | ||
39 | int length = hwemul_get_log(hwdev, buffer, sizeof(buffer) - 1); | ||
40 | if(length <= 0) | ||
41 | break; | ||
42 | buffer[length] = 0; | ||
43 | printf("%s", buffer); | ||
44 | }while(1); | ||
45 | } | ||
46 | |||
47 | int print_help() | ||
48 | { | ||
49 | printf("Commands:\n"); | ||
50 | printf(" help\t\tDisplay this help\n"); | ||
51 | printf(" call <addr>\tCall address <addr>\n"); | ||
52 | printf(" quit\t\tQuit this session\n"); | ||
53 | printf(" read32 <addr>\tRead a 32-bit word at <addr>\n"); | ||
54 | printf(" write32 <value> <addr>\tRead the 32-bit word <value> at <addr>\n"); | ||
55 | printf(" read <regname>\tRead a register by name\n"); | ||
56 | printf(" read <regname>.<field>\tRead a register field by name\n"); | ||
57 | printf(" soc <socname>\tSelect the soc description to use\n"); | ||
58 | printf(" write <value> <regname>\tWrite a register by name\n"); | ||
59 | printf(" write <value <regname>.<field>\tWrite a register field by name\n"); | ||
60 | printf(" NOTE: if the register is SCT variant, no read is performed.\n"); | ||
61 | return 1; | ||
62 | } | ||
63 | |||
64 | int syntax_error(char *str) | ||
65 | { | ||
66 | printf("Syntax error at '%s'. Type 'help' to get some help.\n", str); | ||
67 | return 1; | ||
68 | } | ||
69 | |||
70 | int parse_uint32(char *str, uint32_t *u) | ||
71 | { | ||
72 | char *end; | ||
73 | *u = strtoul(str, &end, 0); | ||
74 | return *end == 0; | ||
75 | } | ||
76 | |||
77 | int do_call(uint32_t a) | ||
78 | { | ||
79 | hwemul_call(&hwdev, a); | ||
80 | return 1; | ||
81 | } | ||
82 | |||
83 | int parse_call() | ||
84 | { | ||
85 | char *arg = strtok(NULL, " "); | ||
86 | uint32_t addr; | ||
87 | if(arg && parse_uint32(arg, &addr)) | ||
88 | return do_call(addr); | ||
89 | else | ||
90 | return syntax_error(arg); | ||
91 | } | ||
92 | |||
93 | int do_read32(uint32_t a) | ||
94 | { | ||
95 | uint32_t val; | ||
96 | if(hwemul_rw_mem(&hwdev, 1, a, &val, sizeof(val)) == sizeof(val)) | ||
97 | printf("%#x = %#x\n", a, val); | ||
98 | else | ||
99 | printf("read error at %#x\n", a); | ||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | int parse_read32() | ||
104 | { | ||
105 | char *arg = strtok(NULL, " "); | ||
106 | uint32_t addr; | ||
107 | if(arg && parse_uint32(arg, &addr)) | ||
108 | return do_read32(addr); | ||
109 | else | ||
110 | return syntax_error(arg); | ||
111 | } | ||
112 | |||
113 | int do_write32(uint32_t val, uint32_t a) | ||
114 | { | ||
115 | if(hwemul_rw_mem(&hwdev, 0, a, &val, sizeof(val)) == sizeof(val)) | ||
116 | printf("data written\n"); | ||
117 | else | ||
118 | printf("write error at %#x\n", a); | ||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | int parse_write32() | ||
123 | { | ||
124 | char *arg = strtok(NULL, " "); | ||
125 | uint32_t val; | ||
126 | if(!arg || !parse_uint32(arg, &val)) | ||
127 | return syntax_error(arg); | ||
128 | uint32_t addr; | ||
129 | arg = strtok(NULL, " "); | ||
130 | if(arg && parse_uint32(arg, &addr)) | ||
131 | return do_write32(val, addr); | ||
132 | else | ||
133 | return syntax_error(arg); | ||
134 | } | ||
135 | |||
136 | struct hwemul_soc_t *find_soc_by_name(const char *soc) | ||
137 | { | ||
138 | struct hwemul_soc_list_t *list = hwemul_get_soc_list(); | ||
139 | for(size_t i = 0; i < list->nr_socs; i++) | ||
140 | if(strcmp(soc, list->socs[i]->name) == 0) | ||
141 | return list->socs[i]; | ||
142 | return NULL; | ||
143 | } | ||
144 | |||
145 | struct hwemul_soc_reg_t *find_reg_by_name(struct hwemul_soc_t *soc, const char *reg) | ||
146 | { | ||
147 | for(size_t i = 0; i < soc->nr_regs; i++) | ||
148 | if(strcmp(reg, soc->regs_by_name[i]->name) == 0) | ||
149 | return soc->regs_by_name[i]; | ||
150 | return NULL; | ||
151 | } | ||
152 | |||
153 | struct hwemul_soc_reg_field_t *find_field_by_name(struct hwemul_soc_reg_t *reg, const char *field) | ||
154 | { | ||
155 | for(size_t i = 0; i < reg->nr_fields; i++) | ||
156 | if(strcmp(field, reg->fields_by_name[i]->name) == 0) | ||
157 | return reg->fields_by_name[i]; | ||
158 | return NULL; | ||
159 | } | ||
160 | |||
161 | |||
162 | int do_read(char *regname) | ||
163 | { | ||
164 | char *dot = strchr(regname, '.'); | ||
165 | if(dot != NULL) | ||
166 | *dot++ = 0; | ||
167 | if(cur_soc == NULL) | ||
168 | { | ||
169 | printf("No soc selected!\n"); | ||
170 | return 1; | ||
171 | } | ||
172 | struct hwemul_soc_reg_t *reg = find_reg_by_name(cur_soc, regname); | ||
173 | if(reg == NULL) | ||
174 | { | ||
175 | printf("no reg '%s' found\n", regname); | ||
176 | return 1; | ||
177 | } | ||
178 | uint32_t val; | ||
179 | if(hwemul_rw_mem(&hwdev, 1, reg->addr, &val, sizeof(val)) != sizeof(val)) | ||
180 | { | ||
181 | printf("read error at %#x\n", reg->addr); | ||
182 | return 1; | ||
183 | } | ||
184 | if(dot) | ||
185 | { | ||
186 | struct hwemul_soc_reg_field_t *field = find_field_by_name(reg, dot); | ||
187 | if(field == NULL) | ||
188 | { | ||
189 | printf("no field '%s' found\n", dot); | ||
190 | return 1; | ||
191 | } | ||
192 | val >>= field->first_bit; | ||
193 | val &= (1 << (field->last_bit - field->first_bit + 1)) - 1; | ||
194 | printf("%s.%s = %#x\n", regname, dot, val); | ||
195 | } | ||
196 | else | ||
197 | printf("%s = %#x\n", regname, val); | ||
198 | return 1; | ||
199 | } | ||
200 | |||
201 | int parse_read() | ||
202 | { | ||
203 | char *arg = strtok(NULL, " "); | ||
204 | if(arg) | ||
205 | return do_read(arg); | ||
206 | else | ||
207 | return syntax_error(arg); | ||
208 | } | ||
209 | |||
210 | int do_soc(char *soc) | ||
211 | { | ||
212 | struct hwemul_soc_t *s = find_soc_by_name(soc); | ||
213 | if(s == NULL) | ||
214 | printf("no soc '%s' found\n", soc); | ||
215 | else | ||
216 | cur_soc = s; | ||
217 | return 1; | ||
218 | } | ||
219 | |||
220 | int parse_soc() | ||
221 | { | ||
222 | char *arg = strtok(NULL, " "); | ||
223 | if(arg) | ||
224 | return do_soc(arg); | ||
225 | else | ||
226 | return syntax_error(arg); | ||
227 | } | ||
228 | |||
229 | int do_write(uint32_t val, char *regname) | ||
230 | { | ||
231 | char *dot = strchr(regname, '.'); | ||
232 | if(dot != NULL) | ||
233 | *dot++ = 0; | ||
234 | if(cur_soc == NULL) | ||
235 | { | ||
236 | printf("No soc selected!\n"); | ||
237 | return 1; | ||
238 | } | ||
239 | struct hwemul_soc_reg_t *reg = find_reg_by_name(cur_soc, regname); | ||
240 | int is_sct = 0; | ||
241 | uint32_t addr_off = 0; | ||
242 | if(reg == NULL) | ||
243 | { | ||
244 | size_t len = strlen(regname); | ||
245 | /* try SCT variant */ | ||
246 | if(strcmp(regname + len - 4, "_SET") == 0) | ||
247 | addr_off = 4; | ||
248 | else if(strcmp(regname + len - 4, "_CLR") == 0) | ||
249 | addr_off = 8; | ||
250 | else if(strcmp(regname + len - 4, "_TOG") == 0) | ||
251 | addr_off = 12; | ||
252 | else | ||
253 | { | ||
254 | printf("no reg '%s' found\n", regname); | ||
255 | return 1; | ||
256 | } | ||
257 | is_sct = 1; | ||
258 | regname[len - 4] = 0; | ||
259 | reg = find_reg_by_name(cur_soc, regname); | ||
260 | if(reg == NULL) | ||
261 | { | ||
262 | printf("no reg '%s' found\n", regname); | ||
263 | return 1; | ||
264 | } | ||
265 | } | ||
266 | if(dot) | ||
267 | { | ||
268 | struct hwemul_soc_reg_field_t *field = find_field_by_name(reg, dot); | ||
269 | if(field == NULL) | ||
270 | { | ||
271 | printf("no field '%s' found\n", dot); | ||
272 | return 1; | ||
273 | } | ||
274 | uint32_t actual_val = 0; | ||
275 | if(!is_sct) | ||
276 | { | ||
277 | if(hwemul_rw_mem(&hwdev, 1, reg->addr, &actual_val, sizeof(actual_val)) != sizeof(actual_val)) | ||
278 | { | ||
279 | printf("read error at %#x\n", reg->addr); | ||
280 | return 1; | ||
281 | } | ||
282 | printf("read %#x at %#x\n", actual_val, reg->addr); | ||
283 | } | ||
284 | uint32_t mask = ((1 << (field->last_bit - field->first_bit + 1)) - 1) << field->first_bit; | ||
285 | printf("mask=%#x\n", mask); | ||
286 | val = (actual_val & ~mask) | ((val << field->first_bit) & mask); | ||
287 | } | ||
288 | printf("write %#x to %#x\n", val, reg->addr + addr_off); | ||
289 | if(hwemul_rw_mem(&hwdev, 0, reg->addr + addr_off, &val, sizeof(val)) != sizeof(val)) | ||
290 | { | ||
291 | printf("write error at %#x\n", reg->addr); | ||
292 | return 1; | ||
293 | } | ||
294 | return 1; | ||
295 | } | ||
296 | |||
297 | int parse_write() | ||
298 | { | ||
299 | char *arg = strtok(NULL, " "); | ||
300 | uint32_t val; | ||
301 | if(!arg || !parse_uint32(arg, &val)) | ||
302 | return syntax_error(arg); | ||
303 | arg = strtok(NULL, " "); | ||
304 | if(arg) | ||
305 | return do_write(val, arg); | ||
306 | else | ||
307 | return syntax_error(arg); | ||
308 | } | ||
309 | |||
310 | int parse_command(char *cmd) | ||
311 | { | ||
312 | if(strcmp(cmd, "help") == 0) | ||
313 | return print_help(); | ||
314 | if(strcmp(cmd, "quit") == 0) | ||
315 | return 0; | ||
316 | if(strcmp(cmd, "call") == 0) | ||
317 | return parse_call(); | ||
318 | if(strcmp(cmd, "read32") == 0) | ||
319 | return parse_read32(); | ||
320 | if(strcmp(cmd, "write32") == 0) | ||
321 | return parse_write32(); | ||
322 | if(strcmp(cmd, "read") == 0) | ||
323 | return parse_read(); | ||
324 | if(strcmp(cmd, "soc") == 0) | ||
325 | return parse_soc(); | ||
326 | if(strcmp(cmd, "write") == 0) | ||
327 | return parse_write(); | ||
328 | return syntax_error(cmd); | ||
329 | } | ||
330 | |||
331 | void interactive_mode(void) | ||
332 | { | ||
333 | rl_bind_key('\t', rl_complete); | ||
334 | while(1) | ||
335 | { | ||
336 | char *input = readline("> "); | ||
337 | if(!input) | ||
338 | break; | ||
339 | add_history(input); | ||
340 | int ret = parse_command(input); | ||
341 | free(input); | ||
342 | if(ret == 0) | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | void usage(void) | ||
348 | { | ||
349 | printf("hwemul_tool, compiled with hwemul %d.%d.%d\n", | ||
350 | HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR, HWEMUL_VERSION_REV); | ||
351 | printf("available soc descriptions:"); | ||
352 | for(unsigned i = 0; i < hwemul_get_soc_list()->nr_socs; i++) | ||
353 | printf(" %s", hwemul_get_soc_list()->socs[i]->name); | ||
354 | printf("\n"); | ||
355 | printf("usage: hwemul_tool [options]\n"); | ||
356 | printf("options:\n"); | ||
357 | printf(" --help/-?\tDisplay this help\n"); | ||
358 | printf(" --quiet/-q\tQuiet non-command messages\n"); | ||
359 | exit(1); | ||
360 | } | ||
361 | |||
362 | int main(int argc, char **argv) | ||
363 | { | ||
364 | while(1) | ||
365 | { | ||
366 | static struct option long_options[] = | ||
367 | { | ||
368 | {"help", no_argument, 0, '?'}, | ||
369 | {"quiet", no_argument, 0, 'q'}, | ||
370 | {0, 0, 0, 0} | ||
371 | }; | ||
372 | |||
373 | int c = getopt_long(argc, argv, "?q", long_options, NULL); | ||
374 | if(c == -1) | ||
375 | break; | ||
376 | switch(c) | ||
377 | { | ||
378 | case -1: | ||
379 | break; | ||
380 | case 'q': | ||
381 | g_quiet = true; | ||
382 | break; | ||
383 | case '?': | ||
384 | usage(); | ||
385 | break; | ||
386 | default: | ||
387 | abort(); | ||
388 | } | ||
389 | } | ||
390 | |||
391 | if(argc - optind != 0) | ||
392 | { | ||
393 | usage(); | ||
394 | return 1; | ||
395 | } | ||
396 | |||
397 | libusb_context *ctx; | ||
398 | libusb_init(&ctx); | ||
399 | libusb_set_debug(ctx, 3); | ||
400 | |||
401 | if(!g_quiet) | ||
402 | printf("Looking for device %#04x:%#04x...\n", HWEMUL_USB_VID, HWEMUL_USB_PID); | ||
403 | |||
404 | libusb_device_handle *handle = libusb_open_device_with_vid_pid(ctx, | ||
405 | HWEMUL_USB_VID, HWEMUL_USB_PID); | ||
406 | if(handle == NULL) | ||
407 | { | ||
408 | printf("No device found\n"); | ||
409 | return 1; | ||
410 | } | ||
411 | |||
412 | libusb_device *mydev = libusb_get_device(handle); | ||
413 | if(!g_quiet) | ||
414 | { | ||
415 | printf("device found at %d:%d\n", | ||
416 | libusb_get_bus_number(mydev), | ||
417 | libusb_get_device_address(mydev)); | ||
418 | } | ||
419 | hwdev.handle = handle; | ||
420 | if(hwemul_probe(&hwdev)) | ||
421 | { | ||
422 | printf("Cannot probe device!\n"); | ||
423 | return 1; | ||
424 | } | ||
425 | |||
426 | struct usb_resp_info_version_t ver; | ||
427 | int ret = hwemul_get_info(&hwdev, HWEMUL_INFO_VERSION, &ver, sizeof(ver)); | ||
428 | if(ret != sizeof(ver)) | ||
429 | { | ||
430 | printf("Cannot get version!\n"); | ||
431 | goto Lerr; | ||
432 | } | ||
433 | if(!g_quiet) | ||
434 | printf("Device version: %d.%d.%d\n", ver.major, ver.minor, ver.revision); | ||
435 | |||
436 | struct usb_resp_info_layout_t layout; | ||
437 | ret = hwemul_get_info(&hwdev, HWEMUL_INFO_LAYOUT, &layout, sizeof(layout)); | ||
438 | if(ret != sizeof(layout)) | ||
439 | { | ||
440 | printf("Cannot get layout: %d\n", ret); | ||
441 | goto Lerr; | ||
442 | } | ||
443 | if(!g_quiet) | ||
444 | { | ||
445 | printf("Device layout:\n"); | ||
446 | printf(" Code: 0x%x (0x%x)\n", layout.oc_code_start, layout.oc_code_size); | ||
447 | printf(" Stack: 0x%x (0x%x)\n", layout.oc_stack_start, layout.oc_stack_size); | ||
448 | printf(" Buffer: 0x%x (0x%x)\n", layout.oc_buffer_start, layout.oc_buffer_size); | ||
449 | } | ||
450 | |||
451 | struct usb_resp_info_features_t features; | ||
452 | ret = hwemul_get_info(&hwdev, HWEMUL_INFO_FEATURES, &features, sizeof(features)); | ||
453 | if(ret != sizeof(features)) | ||
454 | { | ||
455 | printf("Cannot get features: %d\n", ret); | ||
456 | goto Lerr; | ||
457 | } | ||
458 | if(!g_quiet) | ||
459 | { | ||
460 | printf("Device features:"); | ||
461 | if(features.feature_mask & HWEMUL_FEATURE_LOG) | ||
462 | printf(" log"); | ||
463 | if(features.feature_mask & HWEMUL_FEATURE_MEM) | ||
464 | printf(" mem"); | ||
465 | if(features.feature_mask & HWEMUL_FEATURE_CALL) | ||
466 | printf(" call"); | ||
467 | if(features.feature_mask & HWEMUL_FEATURE_JUMP) | ||
468 | printf(" jump"); | ||
469 | if(features.feature_mask & HWEMUL_FEATURE_AES_OTP) | ||
470 | printf(" aes_otp"); | ||
471 | printf("\n"); | ||
472 | } | ||
473 | |||
474 | struct usb_resp_info_stmp_t stmp; | ||
475 | ret = hwemul_get_info(&hwdev, HWEMUL_INFO_STMP, &stmp, sizeof(stmp)); | ||
476 | if(ret != sizeof(stmp)) | ||
477 | { | ||
478 | printf("Cannot get stmp: %d\n", ret); | ||
479 | goto Lerr; | ||
480 | } | ||
481 | if(!g_quiet) | ||
482 | { | ||
483 | printf("Device stmp:\n"); | ||
484 | printf(" chip ID: %x (%s)\n", stmp.chipid,hwemul_get_product_string(&stmp)); | ||
485 | printf(" revision: %d (%s)\n", stmp.rev, hwemul_get_rev_string(&stmp)); | ||
486 | printf(" supported: %d\n", stmp.is_supported); | ||
487 | } | ||
488 | |||
489 | if(!g_quiet) | ||
490 | { | ||
491 | void *rom = malloc(64 * 1024); | ||
492 | ret = hwemul_rw_mem(&hwdev, 1, 0xc0000000, rom, 64 * 1024); | ||
493 | if(ret != 64 * 1024) | ||
494 | { | ||
495 | printf("Cannot read ROM: %d\n", ret); | ||
496 | goto Lerr; | ||
497 | } | ||
498 | |||
499 | printf("ROM successfully read!\n"); | ||
500 | FILE *f = fopen("rom.bin", "wb"); | ||
501 | fwrite(rom, 64 * 1024, 1, f); | ||
502 | fclose(f); | ||
503 | } | ||
504 | |||
505 | if(!g_quiet) | ||
506 | { | ||
507 | struct | ||
508 | { | ||
509 | uint8_t iv[16]; | ||
510 | uint8_t data[16]; | ||
511 | } __attribute__((packed)) dcp_test; | ||
512 | |||
513 | for(int i = 0; i < 16; i++) | ||
514 | dcp_test.iv[i] = rand(); | ||
515 | for(int i = 0; i < 16; i++) | ||
516 | dcp_test.data[i] = rand(); | ||
517 | printf("DCP\n"); | ||
518 | printf(" IN\n"); | ||
519 | printf(" IV:"); | ||
520 | for(int i = 0; i < 16; i++) | ||
521 | printf(" %02x", dcp_test.iv[i]); | ||
522 | printf("\n"); | ||
523 | printf(" IV:"); | ||
524 | for(int i = 0; i < 16; i++) | ||
525 | printf(" %02x", dcp_test.data[i]); | ||
526 | printf("\n"); | ||
527 | |||
528 | if(!hwemul_aes_otp(&hwdev, &dcp_test, sizeof(dcp_test), HWEMUL_AES_OTP_ENCRYPT)) | ||
529 | { | ||
530 | printf(" OUT\n"); | ||
531 | printf(" IV:"); | ||
532 | for(int i = 0; i < 16; i++) | ||
533 | printf(" %02x", dcp_test.iv[i]); | ||
534 | printf("\n"); | ||
535 | printf(" IV:"); | ||
536 | for(int i = 0; i < 16; i++) | ||
537 | printf(" %02x", dcp_test.data[i]); | ||
538 | printf("\n"); | ||
539 | } | ||
540 | else | ||
541 | printf("DCP error!\n"); | ||
542 | } | ||
543 | |||
544 | if(!g_quiet) | ||
545 | printf("Starting interactive session. Type 'help' to get help.\n"); | ||
546 | |||
547 | interactive_mode(); | ||
548 | |||
549 | Lerr: | ||
550 | if(features.feature_mask & HWEMUL_FEATURE_LOG) | ||
551 | { | ||
552 | if(!g_quiet) | ||
553 | printf("Device log:\n"); | ||
554 | print_log(&hwdev); | ||
555 | } | ||
556 | hwemul_release(&hwdev); | ||
557 | return 1; | ||
558 | } | ||