diff options
-rw-r--r-- | apps/plugin.c | 4 | ||||
-rw-r--r-- | apps/plugin.h | 15 | ||||
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 3 | ||||
-rw-r--r-- | firmware/export/general.h | 2 | ||||
-rw-r--r-- | firmware/export/system.h | 32 | ||||
-rw-r--r-- | firmware/general.c | 24 | ||||
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/system-target.h | 8 |
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 | ||
523 | int plugin_load(const char* plugin, void* parameter) | 527 | int 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 ***/ |
45 | fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16))); | 45 | fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] |
46 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); | ||
46 | 47 | ||
47 | 48 | ||
48 | static fb_data* lcd_backdrop = NULL; | 49 | static 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 | ||
38 | size_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 */ | ||
84 | size_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 */ |
113 | static fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] | 113 | static 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 |
117 | static void lcd_init_gpio(void) | 117 | static 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 | ||