1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
28 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
32 /* defined in linker script */
33 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
34 #if defined(IPOD_VIDEO)
35 extern unsigned char *audiobufend_lds
[];
36 unsigned char *audiobufend
;
37 #else /* !IPOD_VIDEO */
38 extern unsigned char audiobufend
[];
40 /* defined in linker script */
41 extern unsigned char audiobuffer
[];
42 #else /* PLATFORM_HOSTED */
43 unsigned char audiobuffer
[(MEMORYSIZE
*1024-256)*1024];
44 unsigned char *audiobufend
= audiobuffer
+ sizeof(audiobuffer
);
45 extern unsigned char *audiobufend
;
48 static unsigned char *audiobuf
;
50 #ifdef BUFFER_ALLOC_DEBUG
51 static unsigned char *audiobuf_orig_start
;
53 struct buffer_start_marker
58 #define BUF_MAGIC 0xDEADD0D0
60 struct buffer_end_marker
65 #endif /* BUFFER_ALLOC_DEBUG */
67 void buffer_init(void)
70 audiobuf
= (void *)(((unsigned long)audiobuffer
+ 3) & ~3);
72 #if defined(IPOD_VIDEO)
73 audiobufend
=(unsigned char *)audiobufend_lds
;
74 if(MEMORYSIZE
==64 && probed_ramsize
!=64)
76 audiobufend
-= (32<<20);
80 #ifdef BUFFER_ALLOC_DEBUG
81 audiobuf_orig_start
= audiobuf
;
82 #endif /* BUFFER_ALLOC_DEBUG */
85 /* protect concurrent access */
86 static volatile int lock
;
89 * Give the entire buffer, return the size in size.
90 * The caller needs to make sure audiobuf is not otherwise used
92 * Note that this does not modify the buffer position (buffer_release_buffer()
93 * does), so call this if you want to aquire temporary memory
95 #define _ALIGN (sizeof(char*))
96 void *buffer_get_buffer(size_t *size
)
99 panicf("concurrent audiobuf access");
101 audiobuf
= ALIGN_UP(audiobuf
, sizeof(intptr_t));
102 *size
= (audiobufend
- audiobuf
);
107 * Release the buffer gotten with buffer_get_buffer
109 * size should have the amount of bytes (from the front) that caller keeps for
110 * its own, 0 if the entire buffer is to be released
112 * safe to be called with size=0 even if the buffer wasn't claimed before
114 void buffer_release_buffer(size_t size
)
117 /* ensure alignment */
118 audiobuf
= ALIGN_UP(audiobuf
, sizeof(intptr_t));
123 * Query how much free space the buffer has */
124 size_t buffer_available(void)
126 return audiobufend
- audiobuf
;
129 void *buffer_alloc(size_t size
)
131 if (lock
) /* it's not save to call this here */
132 panicf("buffer_alloc(): exclusive buffer owner");
134 #ifdef BUFFER_ALLOC_DEBUG
135 struct buffer_start_marker
*start
;
136 struct buffer_end_marker
*end
;
137 #endif /* BUFFER_ALLOC_DEBUG */
140 size
= (size
+ 3) & ~3;
142 /* Other code touches audiobuf. Make sure it stays aligned */
143 audiobuf
= (void *)(((unsigned long)audiobuf
+ 3) & ~3);
147 #ifdef BUFFER_ALLOC_DEBUG
148 retval
+=sizeof(struct buffer_start_marker
);
151 end
=(struct buffer_end_marker
*)(audiobuf
- sizeof(struct buffer_end_marker
));
152 if(end
->magic
== BUF_MAGIC
)
156 start
=(struct buffer_start_marker
*)audiobuf
;
157 start
->magic
= BUF_MAGIC
;
158 start
->buffer_size
= size
;
159 end
=(struct buffer_end_marker
*)(audiobuf
+sizeof(struct buffer_start_marker
)+size
);
160 end
->magic
= BUF_MAGIC
;
163 audiobuf
= ((unsigned char *)end
) + sizeof(struct buffer_end_marker
);
166 logf("Alloc %x %d",(unsigned int)retval
,size
);
167 #else /* !BUFFER_ALLOC_DEBUG */
169 #endif /* BUFFER_ALLOC_DEBUG */
171 if (audiobuf
> audiobufend
) {
172 panicf("OOM: %d bytes", (int) size
);
178 #ifdef BUFFER_ALLOC_DEBUG
179 void buffer_alloc_check(char *name
)
181 unsigned char *buf_ptr
= audiobuf_orig_start
;
182 struct buffer_start_marker
*start
;
183 struct buffer_end_marker
*end
;
186 while(buf_ptr
< audiobuf
)
188 start
=(struct buffer_start_marker
*)buf_ptr
;
189 if(start
->magic
!= BUF_MAGIC
)
191 panicf("%s corrupted buffer %x start", name
,(unsigned int)buf_ptr
+sizeof(struct buffer_start_marker
));
193 end
=(struct buffer_end_marker
*)(buf_ptr
+sizeof(struct buffer_start_marker
)+start
->buffer_size
);
194 if(end
->magic
!= BUF_MAGIC
)
196 panicf("%s corrupted %x end", name
,(unsigned int)buf_ptr
+sizeof(struct buffer_start_marker
));
200 buf_ptr
=((unsigned char *)end
)+sizeof(struct buffer_end_marker
);
203 #endif /* BUFFER_ALLOC_DEBUG */