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
This commit is contained in:
Michael Sevakis 2007-11-08 05:17:20 +00:00
parent 194a66ef83
commit 57d71e4267
8 changed files with 87 additions and 5 deletions

View file

@ -518,6 +518,10 @@ static const struct plugin_api rockbox_api = {
#endif
thread_wait,
#ifdef PROC_NEEDS_CACHEALIGN
align_buffer,
#endif
};
int plugin_load(const char* plugin, void* parameter)

View file

@ -37,6 +37,7 @@
#include "config.h"
#include "system.h"
#include "dir.h"
#include "general.h"
#include "kernel.h"
#include "thread.h"
#include "button.h"
@ -112,7 +113,7 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 88
#define PLUGIN_API_VERSION 89
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
@ -640,6 +641,10 @@ struct plugin_api {
#endif
void (*thread_wait)(struct thread_entry *thread);
#ifdef PROC_NEEDS_CACHEALIGN
size_t (*align_buffer)(void **start, size_t size, size_t align);
#endif
};
/* plugin header */
@ -742,4 +747,12 @@ enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter)
#endif /* CACHE_FUNCTION_WRAPPERS */
#ifndef ALIGN_BUFFER_WRAPPER
#define ALIGN_BUFFER_WRAPPER(api) \
size_t align_buffer(void **start, size_t size, size_t align) \
{ \
return (api)->align_buffer(start, size, align); \
}
#endif /* ALIGN_BUFFER_WRAPPER */
#endif

View file

@ -42,7 +42,8 @@ enum fill_opt {
};
/*** globals ***/
fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16)));
fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
static fb_data* lcd_backdrop = NULL;

View file

@ -21,6 +21,7 @@
#define GENERAL_H
#include <stdbool.h>
#include <stddef.h>
/* round a signed/unsigned 32bit value to the closest of a list of values */
/* returns the index of the closest value */
@ -34,5 +35,6 @@ int make_list_from_caps32(unsigned long src_mask,
unsigned long caps_mask,
unsigned long *caps_list);
size_t align_buffer(void **start, size_t size, size_t align);
#endif /* GENERAL_H */

View file

@ -229,4 +229,36 @@ static inline uint32_t swap_odd_even32(uint32_t value)
#define flush_icache()
#endif
#ifdef PROC_NEEDS_CACHEALIGN
/* Cache alignment attributes and sizes are enabled */
/* 2^CACHEALIGN_BITS = the byte size */
#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS)
#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE)))
/* Aligns x up to a CACHEALIGN_SIZE boundary */
#define CACHEALIGN_UP(x) \
((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS))
/* Aligns x down to a CACHEALIGN_SIZE boundary */
#define CACHEALIGN_DOWN(x) \
((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS))
/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */
#define CACHEALIGN_AT_LEAST_ATTR(x) __attribute__((aligned(CACHEALIGN_UP(x))))
/* Aligns a buffer pointer and size to proper boundaries */
#define CACHEALIGN_BUFFER(start, size) \
({ align_buffer((start), (size), CACHEALIGN_SIZE); })
#else /* ndef PROC_NEEDS_CACHEALIGN */
/* Cache alignment attributes and sizes are not enabled */
#define CACHEALIGN_ATTR
#define CACHEALIGN_AT_LEAST_ATTR(x) __attribute__((aligned(x)))
#define CACHEALIGN_UP(x) (x)
#define CACHEALIGN_DOWN(x) (x)
/* Make no adjustments */
#define CACHEALIGN_BUFFER(start, size) \
({ (void)(start); (size); })
#endif /* PROC_NEEDS_CACHEALIGN */
#endif /* __SYSTEM_H__ */

View file

@ -17,6 +17,7 @@
*
****************************************************************************/
#include <limits.h>
#include "system.h"
#include "config.h"
#include "general.h"
@ -75,3 +76,26 @@ int make_list_from_caps32(unsigned long src_mask,
return count;
} /* make_list_from_caps32 */
/* Only needed for cache aligning atm */
#ifdef PROC_NEEDS_CACHEALIGN
/* Align a buffer and size to a size boundary while remaining within
* the original boundaries */
size_t align_buffer(void **start, size_t size, size_t align)
{
void *newstart = *start;
void *newend = newstart + size;
/* Align the end down and the start up */
newend = (void *)ALIGN_DOWN((intptr_t)newend, align);
newstart = (void *)ALIGN_UP((intptr_t)newstart, align);
/* Hmmm - too small for this */
if (newend <= newstart)
return 0;
/* Return adjusted pointer and size */
*start = newstart;
return newend - newstart;
}
#endif /* PROC_NEEDS_CACHEALIGN */

View file

@ -109,9 +109,9 @@ static unsigned short r_drv_output_control = R_DRV_OUTPUT_CONTROL_NORMAL;
/* We don't know how to receive a DMA finished signal from the LCD controller
* To avoid problems with flickering, we double-buffer the framebuffer and turn
* off DMA while updates are taking place
* Same alignment as in lcd-16bit.c and cache interference free */
* At least the alignment as in lcd-16bit.c and cache interference free */
static fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
__attribute__((aligned(16)));
CACHEALIGN_AT_LEAST_ATTR(16);
#ifdef BOOTLOADER
static void lcd_init_gpio(void)

View file

@ -94,11 +94,17 @@ static inline unsigned int processor_id(void)
#define UNCACHED_ADDR(a) (a)
#else
#define UNCACHED_ADDR(a) \
((typeof (a))((uintptr_t)(a) + 0x10000000))
((typeof (a))((uintptr_t)(a) | 0x10000000))
#endif
#ifdef CPU_PP502x
/* Certain data needs to be out of the way of cache line interference
* such as data for COP use or for use with UNCACHED_ADDR */
#define PROC_NEEDS_CACHEALIGN
#define CACHEALIGN_BITS (5) /* 2^5 = 32 bytes */
/** cache functions **/
#ifndef BOOTLOADER
#define CACHE_FUNCTIONS_AS_CALL