summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/lib/SOURCES5
-rw-r--r--apps/codecs/lib/setjmp.h59
-rw-r--r--apps/codecs/lib/setjmp_arm.S172
-rw-r--r--apps/codecs/lib/setjmp_cf.S79
-rw-r--r--apps/codecs/libtremor/oggmalloc.c9
-rw-r--r--apps/codecs/vorbis.c18
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
5mdct2.c 5mdct2.c
6#ifdef CPU_ARM 6#ifdef CPU_ARM
7mdct_arm.S 7mdct_arm.S
8setjmp_arm.S
8#if ARM_ARCH == 4 9#if ARM_ARCH == 4
9udiv32_armv4.S 10udiv32_armv4.S
10#endif 11#endif
11#endif 12#endif
12 13
14#ifdef CPU_COLDFIRE
15setjmp_cf.S
16#endif
17
13#elif defined(SIMULATOR) && defined(__APPLE__) 18#elif defined(SIMULATOR) && defined(__APPLE__)
14osx.dummy.c 19osx.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
49typedef _JBTYPE jmp_buf[_JBLEN];
50#else
51typedef int jmp_buf[_JBLEN];
52#endif
53#endif
54
55
56extern void longjmp(jmp_buf __jmpb, int __retval);
57extern 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
93SYM (.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)
107SYM (\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
36SYM (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
44SYM (longjmp):
45 moveal sp@(4),a0
46 movel sp@(8),d0
47 bne 1f
48 movel &1,d0
491:
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
59SYM (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
68SYM (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
741:
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>
5extern jmp_buf rb_jump_buf;
6#endif
7
3static size_t tmp_ptr; 8static size_t tmp_ptr;
4 9
5void ogg_malloc_init(void) 10void 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
26CODEC_HEADER 26CODEC_HEADER
27 27
28#if defined(CPU_ARM) || defined(CPU_COLDFIRE)
29#include <setjmp.h>
30jmp_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
30static size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) 35static 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. */
123next_track: 137next_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