diff options
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/lib/SOURCES | 5 | ||||
-rw-r--r-- | apps/codecs/lib/setjmp.h | 59 | ||||
-rw-r--r-- | apps/codecs/lib/setjmp_arm.S | 172 | ||||
-rw-r--r-- | apps/codecs/lib/setjmp_cf.S | 79 | ||||
-rw-r--r-- | apps/codecs/libtremor/oggmalloc.c | 9 | ||||
-rw-r--r-- | apps/codecs/vorbis.c | 18 |
6 files changed, 340 insertions, 2 deletions
diff --git a/apps/codecs/lib/SOURCES b/apps/codecs/lib/SOURCES index 8099620098..b0ebbc5441 100644 --- a/apps/codecs/lib/SOURCES +++ b/apps/codecs/lib/SOURCES | |||
@@ -5,11 +5,16 @@ codeclib.c | |||
5 | mdct2.c | 5 | mdct2.c |
6 | #ifdef CPU_ARM | 6 | #ifdef CPU_ARM |
7 | mdct_arm.S | 7 | mdct_arm.S |
8 | setjmp_arm.S | ||
8 | #if ARM_ARCH == 4 | 9 | #if ARM_ARCH == 4 |
9 | udiv32_armv4.S | 10 | udiv32_armv4.S |
10 | #endif | 11 | #endif |
11 | #endif | 12 | #endif |
12 | 13 | ||
14 | #ifdef CPU_COLDFIRE | ||
15 | setjmp_cf.S | ||
16 | #endif | ||
17 | |||
13 | #elif defined(SIMULATOR) && defined(__APPLE__) | 18 | #elif defined(SIMULATOR) && defined(__APPLE__) |
14 | osx.dummy.c | 19 | osx.dummy.c |
15 | #endif | 20 | #endif |
diff --git a/apps/codecs/lib/setjmp.h b/apps/codecs/lib/setjmp.h new file mode 100644 index 0000000000..4bcf6af623 --- /dev/null +++ b/apps/codecs/lib/setjmp.h | |||
@@ -0,0 +1,59 @@ | |||
1 | #ifndef _SETJMP_H_ | ||
2 | #define _SETJMP_H_ | ||
3 | |||
4 | /* Combined parts of include/setjmp.h and include/machine/setjmp.h in | ||
5 | * newlib 1.17.0, with minor changes for Rockbox. | ||
6 | */ | ||
7 | |||
8 | #ifdef CPU_ARM | ||
9 | /* | ||
10 | * All callee preserved registers: | ||
11 | * v1 - v7, fp, ip, sp, lr, f4, f5, f6, f7 | ||
12 | */ | ||
13 | #define _JBLEN 23 | ||
14 | #endif | ||
15 | |||
16 | /* necv70 was 9 as well. */ | ||
17 | |||
18 | #ifdef CPU_COLDFIRE | ||
19 | /* | ||
20 | * onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6, | ||
21 | * fp2-fp7 for 68881. | ||
22 | * All else recovered by under/over(flow) handling. | ||
23 | */ | ||
24 | #define _JBLEN 34 | ||
25 | #endif | ||
26 | |||
27 | #ifdef __mips__ | ||
28 | #ifdef __mips64 | ||
29 | #define _JBTYPE long long | ||
30 | #endif | ||
31 | #ifdef __mips_soft_float | ||
32 | #define _JBLEN 11 | ||
33 | #else | ||
34 | #define _JBLEN 23 | ||
35 | #endif | ||
36 | #endif | ||
37 | |||
38 | #ifdef __sh__ | ||
39 | #if __SH5__ | ||
40 | #define _JBLEN 50 | ||
41 | #define _JBTYPE long long | ||
42 | #else | ||
43 | #define _JBLEN 20 | ||
44 | #endif /* __SH5__ */ | ||
45 | #endif | ||
46 | |||
47 | #ifdef _JBLEN | ||
48 | #ifdef _JBTYPE | ||
49 | typedef _JBTYPE jmp_buf[_JBLEN]; | ||
50 | #else | ||
51 | typedef int jmp_buf[_JBLEN]; | ||
52 | #endif | ||
53 | #endif | ||
54 | |||
55 | |||
56 | extern void longjmp(jmp_buf __jmpb, int __retval); | ||
57 | extern int setjmp(jmp_buf __jmpb); | ||
58 | |||
59 | #endif // _SETJMP_H_ | ||
diff --git a/apps/codecs/lib/setjmp_arm.S b/apps/codecs/lib/setjmp_arm.S new file mode 100644 index 0000000000..4bb2a46a7a --- /dev/null +++ b/apps/codecs/lib/setjmp_arm.S | |||
@@ -0,0 +1,172 @@ | |||
1 | /* This is a simple version of setjmp and longjmp. | ||
2 | |||
3 | Nick Clifton, Cygnus Solutions, 13 June 1997. */ | ||
4 | |||
5 | /* ANSI concatenation macros. */ | ||
6 | #define CONCAT(a, b) CONCAT2(a, b) | ||
7 | #define CONCAT2(a, b) a##b | ||
8 | |||
9 | #ifndef __USER_LABEL_PREFIX__ | ||
10 | #error __USER_LABEL_PREFIX__ not defined | ||
11 | #endif | ||
12 | |||
13 | #define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x) | ||
14 | |||
15 | #ifdef __ELF__ | ||
16 | #define TYPE(x) .type SYM(x),function | ||
17 | #define SIZE(x) .size SYM(x), . - SYM(x) | ||
18 | #else | ||
19 | #define TYPE(x) | ||
20 | #define SIZE(x) | ||
21 | #endif | ||
22 | |||
23 | /* Arm/Thumb interworking support: | ||
24 | |||
25 | The interworking scheme expects functions to use a BX instruction | ||
26 | to return control to their parent. Since we need this code to work | ||
27 | in both interworked and non-interworked environments as well as with | ||
28 | older processors which do not have the BX instruction we do the | ||
29 | following: | ||
30 | Test the return address. | ||
31 | If the bottom bit is clear perform an "old style" function exit. | ||
32 | (We know that we are in ARM mode and returning to an ARM mode caller). | ||
33 | Otherwise use the BX instruction to perform the function exit. | ||
34 | |||
35 | We know that we will never attempt to perform the BX instruction on | ||
36 | an older processor, because that kind of processor will never be | ||
37 | interworked, and a return address with the bottom bit set will never | ||
38 | be generated. | ||
39 | |||
40 | In addition, we do not actually assemble the BX instruction as this would | ||
41 | require us to tell the assembler that the processor is an ARM7TDMI and | ||
42 | it would store this information in the binary. We want this binary to be | ||
43 | able to be linked with binaries compiled for older processors however, so | ||
44 | we do not want such information stored there. | ||
45 | |||
46 | If we are running using the APCS-26 convention however, then we never | ||
47 | test the bottom bit, because this is part of the processor status. | ||
48 | Instead we just do a normal return, since we know that we cannot be | ||
49 | returning to a Thumb caller - the Thumb does not support APCS-26. | ||
50 | |||
51 | Function entry is much simpler. If we are compiling for the Thumb we | ||
52 | just switch into ARM mode and then drop through into the rest of the | ||
53 | function. The function exit code will take care of the restore to | ||
54 | Thumb mode. | ||
55 | |||
56 | For Thumb-2 do everything in Thumb mode. */ | ||
57 | |||
58 | #ifdef __APCS_26__ | ||
59 | #define RET movs pc, lr | ||
60 | #elif defined(__thumb2__) | ||
61 | #define RET bx lr | ||
62 | #else | ||
63 | #define RET tst lr, #1; \ | ||
64 | moveq pc, lr ; \ | ||
65 | .word 0xe12fff1e /* bx lr */ | ||
66 | #endif | ||
67 | |||
68 | #ifdef __thumb2__ | ||
69 | .macro COND where when | ||
70 | i\where \when | ||
71 | .endm | ||
72 | #else | ||
73 | .macro COND where when | ||
74 | .endm | ||
75 | #endif | ||
76 | |||
77 | #if defined(__thumb2__) | ||
78 | .syntax unified | ||
79 | .macro MODE | ||
80 | .thumb | ||
81 | .thumb_func | ||
82 | .endm | ||
83 | .macro PROLOGUE name | ||
84 | .endm | ||
85 | |||
86 | #elif defined(__thumb__) | ||
87 | #define MODE .thumb_func | ||
88 | .macro PROLOGUE name | ||
89 | .code 16 | ||
90 | bx pc | ||
91 | nop | ||
92 | .code 32 | ||
93 | SYM (.arm_start_of.\name): | ||
94 | .endm | ||
95 | #else /* Arm */ | ||
96 | #define MODE .code 32 | ||
97 | .macro PROLOGUE name | ||
98 | .endm | ||
99 | #endif | ||
100 | |||
101 | .macro FUNC_START name | ||
102 | .text | ||
103 | .align 2 | ||
104 | MODE | ||
105 | .globl SYM (\name) | ||
106 | TYPE (\name) | ||
107 | SYM (\name): | ||
108 | PROLOGUE \name | ||
109 | .endm | ||
110 | |||
111 | .macro FUNC_END name | ||
112 | RET | ||
113 | SIZE (\name) | ||
114 | .endm | ||
115 | |||
116 | /* -------------------------------------------------------------------- | ||
117 | int setjmp (jmp_buf); | ||
118 | -------------------------------------------------------------------- */ | ||
119 | |||
120 | FUNC_START setjmp | ||
121 | |||
122 | /* Save all the callee-preserved registers into the jump buffer. */ | ||
123 | #ifdef __thumb2__ | ||
124 | stmea a1!, { v1-v7, fp, ip, lr } | ||
125 | str sp, [a1],#+4 | ||
126 | #else | ||
127 | stmea a1!, { v1-v7, fp, ip, sp, lr } | ||
128 | #endif | ||
129 | |||
130 | #if 0 /* Simulator does not cope with FP instructions yet. */ | ||
131 | #ifndef __SOFTFP__ | ||
132 | /* Save the floating point registers. */ | ||
133 | sfmea f4, 4, [a1] | ||
134 | #endif | ||
135 | #endif | ||
136 | /* When setting up the jump buffer return 0. */ | ||
137 | mov a1, #0 | ||
138 | |||
139 | FUNC_END setjmp | ||
140 | |||
141 | /* -------------------------------------------------------------------- | ||
142 | volatile void longjmp (jmp_buf, int); | ||
143 | -------------------------------------------------------------------- */ | ||
144 | |||
145 | FUNC_START longjmp | ||
146 | |||
147 | /* If we have stack extension code it ought to be handled here. */ | ||
148 | |||
149 | /* Restore the registers, retrieving the state when setjmp() was called. */ | ||
150 | #ifdef __thumb2__ | ||
151 | ldmfd a1!, { v1-v7, fp, ip, lr } | ||
152 | ldr sp, [a1],#+4 | ||
153 | #else | ||
154 | ldmfd a1!, { v1-v7, fp, ip, sp, lr } | ||
155 | #endif | ||
156 | |||
157 | #if 0 /* Simulator does not cope with FP instructions yet. */ | ||
158 | #ifndef __SOFTFP__ | ||
159 | /* Restore floating point registers as well. */ | ||
160 | lfmfd f4, 4, [a1] | ||
161 | #endif | ||
162 | #endif | ||
163 | /* Put the return value into the integer result register. | ||
164 | But if it is zero then return 1 instead. */ | ||
165 | movs a1, a2 | ||
166 | #ifdef __thumb2__ | ||
167 | it eq | ||
168 | #endif | ||
169 | moveq a1, #1 | ||
170 | |||
171 | FUNC_END longjmp | ||
172 | |||
diff --git a/apps/codecs/lib/setjmp_cf.S b/apps/codecs/lib/setjmp_cf.S new file mode 100644 index 0000000000..acc98c3f59 --- /dev/null +++ b/apps/codecs/lib/setjmp_cf.S | |||
@@ -0,0 +1,79 @@ | |||
1 | /* ANSI concatenation macros. */ | ||
2 | |||
3 | #define CONCAT1(a, b) CONCAT2(a, b) | ||
4 | #define CONCAT2(a, b) a ## b | ||
5 | |||
6 | /* Use the right prefix for global labels. */ | ||
7 | |||
8 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) | ||
9 | |||
10 | /* Use the right prefix for registers. */ | ||
11 | |||
12 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) | ||
13 | |||
14 | #define d0 REG (d0) | ||
15 | #define d1 REG (d1) | ||
16 | #define d2 REG (d2) | ||
17 | #define d3 REG (d3) | ||
18 | #define d4 REG (d4) | ||
19 | #define d5 REG (d5) | ||
20 | #define d6 REG (d6) | ||
21 | #define d7 REG (d7) | ||
22 | #define a0 REG (a0) | ||
23 | #define a1 REG (a1) | ||
24 | #define a2 REG (a2) | ||
25 | #define a3 REG (a3) | ||
26 | #define a4 REG (a4) | ||
27 | #define a5 REG (a5) | ||
28 | #define a6 REG (a6) | ||
29 | #define fp REG (fp) | ||
30 | #define sp REG (sp) | ||
31 | |||
32 | |||
33 | .global SYM (setjmp) | ||
34 | .global SYM (longjmp) | ||
35 | |||
36 | SYM (setjmp): | ||
37 | moveal sp@(4),a0 | ||
38 | movel sp@(0),a0@(12) | ||
39 | movel sp,a0@(8) | ||
40 | moveml d2-d7/a2-a6,a0@(20) | ||
41 | clrl d0 | ||
42 | rts | ||
43 | |||
44 | SYM (longjmp): | ||
45 | moveal sp@(4),a0 | ||
46 | movel sp@(8),d0 | ||
47 | bne 1f | ||
48 | movel &1,d0 | ||
49 | 1: | ||
50 | moveml a0@(20),d2-d7/a2-a6 | ||
51 | moveal a0@(8),sp | ||
52 | movel a0@(12),sp@ | ||
53 | rts | ||
54 | |||
55 | #ifdef M68881 | ||
56 | .global SYM (setjmp_68881) | ||
57 | .global SYM (longjmp_68881) | ||
58 | |||
59 | SYM (setjmp_68881): | ||
60 | moveal sp@(4),a0 | ||
61 | movel sp@(0),a0@(12) | ||
62 | movel sp,a0@(8) | ||
63 | moveml d2-d7/a2-a6,a0@(20) | ||
64 | fmovemx fp2-fp7,a0@(64) | ||
65 | clrl d0 | ||
66 | rts | ||
67 | |||
68 | SYM (longjmp_68881): | ||
69 | moveal sp@(4),a0 | ||
70 | fmovemx a0@(64),fp2-fp7 | ||
71 | movel sp@(8),d0 | ||
72 | bne 1f | ||
73 | movel &1,d0 | ||
74 | 1: | ||
75 | moveml a0@(20),d2-d7/a2-a6 | ||
76 | moveal a0@(8),sp | ||
77 | movel a0@(12),sp@ | ||
78 | rts | ||
79 | #endif | ||
diff --git a/apps/codecs/libtremor/oggmalloc.c b/apps/codecs/libtremor/oggmalloc.c index ca917ff397..4aa2760629 100644 --- a/apps/codecs/libtremor/oggmalloc.c +++ b/apps/codecs/libtremor/oggmalloc.c | |||
@@ -1,5 +1,10 @@ | |||
1 | #include "os_types.h" | 1 | #include "os_types.h" |
2 | 2 | ||
3 | #if defined(CPU_ARM) || defined(CPU_COLDFIRE) | ||
4 | #include <setjmp.h> | ||
5 | extern jmp_buf rb_jump_buf; | ||
6 | #endif | ||
7 | |||
3 | static size_t tmp_ptr; | 8 | static size_t tmp_ptr; |
4 | 9 | ||
5 | void ogg_malloc_init(void) | 10 | void ogg_malloc_init(void) |
@@ -16,7 +21,11 @@ void *ogg_malloc(size_t size) | |||
16 | size = (size + 3) & ~3; | 21 | size = (size + 3) & ~3; |
17 | 22 | ||
18 | if (mem_ptr + size > tmp_ptr) | 23 | if (mem_ptr + size > tmp_ptr) |
24 | #if defined(CPU_ARM) || defined(CPU_COLDFIRE) | ||
25 | longjmp(rb_jump_buf, 1); | ||
26 | #else | ||
19 | return NULL; | 27 | return NULL; |
28 | #endif | ||
20 | 29 | ||
21 | x = &mallocbuf[mem_ptr]; | 30 | x = &mallocbuf[mem_ptr]; |
22 | mem_ptr += size; /* Keep memory 32-bit aligned */ | 31 | mem_ptr += size; /* Keep memory 32-bit aligned */ |
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c index 74d582ebb3..f14aeead84 100644 --- a/apps/codecs/vorbis.c +++ b/apps/codecs/vorbis.c | |||
@@ -25,6 +25,11 @@ | |||
25 | 25 | ||
26 | CODEC_HEADER | 26 | CODEC_HEADER |
27 | 27 | ||
28 | #if defined(CPU_ARM) || defined(CPU_COLDFIRE) | ||
29 | #include <setjmp.h> | ||
30 | jmp_buf rb_jump_buf; | ||
31 | #endif | ||
32 | |||
28 | /* Some standard functions and variables needed by Tremor */ | 33 | /* Some standard functions and variables needed by Tremor */ |
29 | 34 | ||
30 | static size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) | 35 | static size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) |
@@ -107,7 +112,7 @@ enum codec_status codec_main(void) | |||
107 | int error; | 112 | int error; |
108 | long n; | 113 | long n; |
109 | int current_section; | 114 | int current_section; |
110 | int previous_section = -1; | 115 | int previous_section; |
111 | int eof; | 116 | int eof; |
112 | ogg_int64_t vf_offsets[2]; | 117 | ogg_int64_t vf_offsets[2]; |
113 | ogg_int64_t vf_dataoffsets; | 118 | ogg_int64_t vf_dataoffsets; |
@@ -119,6 +124,15 @@ enum codec_status codec_main(void) | |||
119 | * they should be set differently based on quality setting | 124 | * they should be set differently based on quality setting |
120 | */ | 125 | */ |
121 | 126 | ||
127 | #if defined(CPU_ARM) || defined(CPU_COLDFIRE) | ||
128 | if (setjmp(rb_jump_buf) != 0) | ||
129 | { | ||
130 | /* malloc failed; skip to next track */ | ||
131 | error = CODEC_ERROR; | ||
132 | goto done; | ||
133 | } | ||
134 | #endif | ||
135 | |||
122 | /* We need to flush reserver memory every track load. */ | 136 | /* We need to flush reserver memory every track load. */ |
123 | next_track: | 137 | next_track: |
124 | if (codec_init()) { | 138 | if (codec_init()) { |
@@ -181,6 +195,7 @@ next_track: | |||
181 | ci->set_offset(ov_raw_tell(&vf)); | 195 | ci->set_offset(ov_raw_tell(&vf)); |
182 | } | 196 | } |
183 | 197 | ||
198 | previous_section = -1; | ||
184 | eof = 0; | 199 | eof = 0; |
185 | while (!eof) { | 200 | while (!eof) { |
186 | ci->yield(); | 201 | ci->yield(); |
@@ -227,7 +242,6 @@ done: | |||
227 | vf.serialnos = NULL; | 242 | vf.serialnos = NULL; |
228 | vf.pcmlengths = NULL; | 243 | vf.pcmlengths = NULL; |
229 | ov_clear(&vf); | 244 | ov_clear(&vf); |
230 | previous_section = -1; | ||
231 | goto next_track; | 245 | goto next_track; |
232 | } | 246 | } |
233 | 247 | ||