summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-11-08 05:17:20 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-11-08 05:17:20 +0000
commit57d71e4267ecf66c84173f8ff3606091187b93b1 (patch)
tree7992814f1dfbcf7c5251cad0fdc6da9a5ebb70a3
parent194a66ef83664b0ebd23b9bea031c67c3b80f6ac (diff)
downloadrockbox-57d71e4267ecf66c84173f8ff3606091187b93b1.tar.gz
rockbox-57d71e4267ecf66c84173f8ff3606091187b93b1.zip
Add some CACHEALIGN_* macros and a helper function to assist in aligning data and buffers on PortalPlayer processors to cache line boundaries. They're noops when PROC_NEED_CACHEALIGN isn't defined. Go safe and increase the value to 32 since I'm not sure yet if 16 is sufficient - changing that is a one-liner. Add helper to plugin API which will be needed shortly.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15523 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c4
-rw-r--r--apps/plugin.h15
-rw-r--r--firmware/drivers/lcd-16bit.c3
-rw-r--r--firmware/export/general.h2
-rw-r--r--firmware/export/system.h32
-rw-r--r--firmware/general.c24
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/lcd-e200.c4
-rw-r--r--firmware/target/arm/system-target.h8
8 files changed, 87 insertions, 5 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index ff23a55537..a80e9dd86d 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -518,6 +518,10 @@ static const struct plugin_api rockbox_api = {
518#endif 518#endif
519 519
520 thread_wait, 520 thread_wait,
521
522#ifdef PROC_NEEDS_CACHEALIGN
523 align_buffer,
524#endif
521}; 525};
522 526
523int plugin_load(const char* plugin, void* parameter) 527int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 300cad0781..f56590c29e 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -37,6 +37,7 @@
37#include "config.h" 37#include "config.h"
38#include "system.h" 38#include "system.h"
39#include "dir.h" 39#include "dir.h"
40#include "general.h"
40#include "kernel.h" 41#include "kernel.h"
41#include "thread.h" 42#include "thread.h"
42#include "button.h" 43#include "button.h"
@@ -112,7 +113,7 @@
112#define PLUGIN_MAGIC 0x526F634B /* RocK */ 113#define PLUGIN_MAGIC 0x526F634B /* RocK */
113 114
114/* increase this every time the api struct changes */ 115/* increase this every time the api struct changes */
115#define PLUGIN_API_VERSION 88 116#define PLUGIN_API_VERSION 89
116 117
117/* update this to latest version if a change to the api struct breaks 118/* update this to latest version if a change to the api struct breaks
118 backwards compatibility (and please take the opportunity to sort in any 119 backwards compatibility (and please take the opportunity to sort in any
@@ -640,6 +641,10 @@ struct plugin_api {
640#endif 641#endif
641 642
642 void (*thread_wait)(struct thread_entry *thread); 643 void (*thread_wait)(struct thread_entry *thread);
644
645#ifdef PROC_NEEDS_CACHEALIGN
646 size_t (*align_buffer)(void **start, size_t size, size_t align);
647#endif
643}; 648};
644 649
645/* plugin header */ 650/* plugin header */
@@ -742,4 +747,12 @@ enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter)
742 747
743#endif /* CACHE_FUNCTION_WRAPPERS */ 748#endif /* CACHE_FUNCTION_WRAPPERS */
744 749
750#ifndef ALIGN_BUFFER_WRAPPER
751#define ALIGN_BUFFER_WRAPPER(api) \
752 size_t align_buffer(void **start, size_t size, size_t align) \
753 { \
754 return (api)->align_buffer(start, size, align); \
755 }
756#endif /* ALIGN_BUFFER_WRAPPER */
757
745#endif 758#endif
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 2c36ab993a..f16503e0c6 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -42,7 +42,8 @@ enum fill_opt {
42}; 42};
43 43
44/*** globals ***/ 44/*** globals ***/
45fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16))); 45fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
46 IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
46 47
47 48
48static fb_data* lcd_backdrop = NULL; 49static fb_data* lcd_backdrop = NULL;
diff --git a/firmware/export/general.h b/firmware/export/general.h
index 427e2773b8..f4ea9e206a 100644
--- a/firmware/export/general.h
+++ b/firmware/export/general.h
@@ -21,6 +21,7 @@
21#define GENERAL_H 21#define GENERAL_H
22 22
23#include <stdbool.h> 23#include <stdbool.h>
24#include <stddef.h>
24 25
25/* round a signed/unsigned 32bit value to the closest of a list of values */ 26/* round a signed/unsigned 32bit value to the closest of a list of values */
26/* returns the index of the closest value */ 27/* returns the index of the closest value */
@@ -34,5 +35,6 @@ int make_list_from_caps32(unsigned long src_mask,
34 unsigned long caps_mask, 35 unsigned long caps_mask,
35 unsigned long *caps_list); 36 unsigned long *caps_list);
36 37
38size_t align_buffer(void **start, size_t size, size_t align);
37 39
38#endif /* GENERAL_H */ 40#endif /* GENERAL_H */
diff --git a/firmware/export/system.h b/firmware/export/system.h
index dc10c4545f..cba4b81631 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -229,4 +229,36 @@ static inline uint32_t swap_odd_even32(uint32_t value)
229#define flush_icache() 229#define flush_icache()
230#endif 230#endif
231 231
232#ifdef PROC_NEEDS_CACHEALIGN
233/* Cache alignment attributes and sizes are enabled */
234
235/* 2^CACHEALIGN_BITS = the byte size */
236#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS)
237
238#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE)))
239/* Aligns x up to a CACHEALIGN_SIZE boundary */
240#define CACHEALIGN_UP(x) \
241 ((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS))
242/* Aligns x down to a CACHEALIGN_SIZE boundary */
243#define CACHEALIGN_DOWN(x) \
244 ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS))
245/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */
246#define CACHEALIGN_AT_LEAST_ATTR(x) __attribute__((aligned(CACHEALIGN_UP(x))))
247/* Aligns a buffer pointer and size to proper boundaries */
248#define CACHEALIGN_BUFFER(start, size) \
249 ({ align_buffer((start), (size), CACHEALIGN_SIZE); })
250
251#else /* ndef PROC_NEEDS_CACHEALIGN */
252
253/* Cache alignment attributes and sizes are not enabled */
254#define CACHEALIGN_ATTR
255#define CACHEALIGN_AT_LEAST_ATTR(x) __attribute__((aligned(x)))
256#define CACHEALIGN_UP(x) (x)
257#define CACHEALIGN_DOWN(x) (x)
258/* Make no adjustments */
259#define CACHEALIGN_BUFFER(start, size) \
260 ({ (void)(start); (size); })
261
262#endif /* PROC_NEEDS_CACHEALIGN */
263
232#endif /* __SYSTEM_H__ */ 264#endif /* __SYSTEM_H__ */
diff --git a/firmware/general.c b/firmware/general.c
index 7f4348046c..cc3710c8f3 100644
--- a/firmware/general.c
+++ b/firmware/general.c
@@ -17,6 +17,7 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#include <limits.h> 19#include <limits.h>
20#include "system.h"
20#include "config.h" 21#include "config.h"
21#include "general.h" 22#include "general.h"
22 23
@@ -75,3 +76,26 @@ int make_list_from_caps32(unsigned long src_mask,
75 76
76 return count; 77 return count;
77} /* make_list_from_caps32 */ 78} /* make_list_from_caps32 */
79
80/* Only needed for cache aligning atm */
81#ifdef PROC_NEEDS_CACHEALIGN
82/* Align a buffer and size to a size boundary while remaining within
83 * the original boundaries */
84size_t align_buffer(void **start, size_t size, size_t align)
85{
86 void *newstart = *start;
87 void *newend = newstart + size;
88
89 /* Align the end down and the start up */
90 newend = (void *)ALIGN_DOWN((intptr_t)newend, align);
91 newstart = (void *)ALIGN_UP((intptr_t)newstart, align);
92
93 /* Hmmm - too small for this */
94 if (newend <= newstart)
95 return 0;
96
97 /* Return adjusted pointer and size */
98 *start = newstart;
99 return newend - newstart;
100}
101#endif /* PROC_NEEDS_CACHEALIGN */
diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
index aa969d2bff..e1212c9512 100644
--- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
+++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
@@ -109,9 +109,9 @@ static unsigned short r_drv_output_control = R_DRV_OUTPUT_CONTROL_NORMAL;
109/* We don't know how to receive a DMA finished signal from the LCD controller 109/* We don't know how to receive a DMA finished signal from the LCD controller
110 * To avoid problems with flickering, we double-buffer the framebuffer and turn 110 * To avoid problems with flickering, we double-buffer the framebuffer and turn
111 * off DMA while updates are taking place 111 * off DMA while updates are taking place
112 * Same alignment as in lcd-16bit.c and cache interference free */ 112 * At least the alignment as in lcd-16bit.c and cache interference free */
113static fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] 113static fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
114 __attribute__((aligned(16))); 114 CACHEALIGN_AT_LEAST_ATTR(16);
115 115
116#ifdef BOOTLOADER 116#ifdef BOOTLOADER
117static void lcd_init_gpio(void) 117static void lcd_init_gpio(void)
diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h
index 6e433be9d5..e9419b3f86 100644
--- a/firmware/target/arm/system-target.h
+++ b/firmware/target/arm/system-target.h
@@ -94,11 +94,17 @@ static inline unsigned int processor_id(void)
94#define UNCACHED_ADDR(a) (a) 94#define UNCACHED_ADDR(a) (a)
95#else 95#else
96#define UNCACHED_ADDR(a) \ 96#define UNCACHED_ADDR(a) \
97 ((typeof (a))((uintptr_t)(a) + 0x10000000)) 97 ((typeof (a))((uintptr_t)(a) | 0x10000000))
98#endif 98#endif
99 99
100#ifdef CPU_PP502x 100#ifdef CPU_PP502x
101 101
102/* Certain data needs to be out of the way of cache line interference
103 * such as data for COP use or for use with UNCACHED_ADDR */
104#define PROC_NEEDS_CACHEALIGN
105#define CACHEALIGN_BITS (5) /* 2^5 = 32 bytes */
106
107/** cache functions **/
102#ifndef BOOTLOADER 108#ifndef BOOTLOADER
103#define CACHE_FUNCTIONS_AS_CALL 109#define CACHE_FUNCTIONS_AS_CALL
104 110