forked from len0rd/rockbox
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:
parent
194a66ef83
commit
57d71e4267
8 changed files with 87 additions and 5 deletions
|
@ -518,6 +518,10 @@ static const struct plugin_api rockbox_api = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread_wait,
|
thread_wait,
|
||||||
|
|
||||||
|
#ifdef PROC_NEEDS_CACHEALIGN
|
||||||
|
align_buffer,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int plugin_load(const char* plugin, void* parameter)
|
int plugin_load(const char* plugin, void* parameter)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
|
#include "general.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
|
@ -112,7 +113,7 @@
|
||||||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||||
|
|
||||||
/* increase this every time the api struct changes */
|
/* 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
|
/* update this to latest version if a change to the api struct breaks
|
||||||
backwards compatibility (and please take the opportunity to sort in any
|
backwards compatibility (and please take the opportunity to sort in any
|
||||||
|
@ -640,6 +641,10 @@ struct plugin_api {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void (*thread_wait)(struct thread_entry *thread);
|
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 */
|
/* plugin header */
|
||||||
|
@ -742,4 +747,12 @@ enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter)
|
||||||
|
|
||||||
#endif /* CACHE_FUNCTION_WRAPPERS */
|
#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
|
#endif
|
||||||
|
|
|
@ -42,7 +42,8 @@ enum fill_opt {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*** globals ***/
|
/*** 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;
|
static fb_data* lcd_backdrop = NULL;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define GENERAL_H
|
#define GENERAL_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* round a signed/unsigned 32bit value to the closest of a list of values */
|
/* round a signed/unsigned 32bit value to the closest of a list of values */
|
||||||
/* returns the index of the closest value */
|
/* 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_mask,
|
||||||
unsigned long *caps_list);
|
unsigned long *caps_list);
|
||||||
|
|
||||||
|
size_t align_buffer(void **start, size_t size, size_t align);
|
||||||
|
|
||||||
#endif /* GENERAL_H */
|
#endif /* GENERAL_H */
|
||||||
|
|
|
@ -229,4 +229,36 @@ static inline uint32_t swap_odd_even32(uint32_t value)
|
||||||
#define flush_icache()
|
#define flush_icache()
|
||||||
#endif
|
#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__ */
|
#endif /* __SYSTEM_H__ */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include "system.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
|
|
||||||
|
@ -75,3 +76,26 @@ int make_list_from_caps32(unsigned long src_mask,
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
} /* make_list_from_caps32 */
|
} /* 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 */
|
||||||
|
|
|
@ -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
|
/* 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
|
* To avoid problems with flickering, we double-buffer the framebuffer and turn
|
||||||
* off DMA while updates are taking place
|
* 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]
|
static fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
|
||||||
__attribute__((aligned(16)));
|
CACHEALIGN_AT_LEAST_ATTR(16);
|
||||||
|
|
||||||
#ifdef BOOTLOADER
|
#ifdef BOOTLOADER
|
||||||
static void lcd_init_gpio(void)
|
static void lcd_init_gpio(void)
|
||||||
|
|
|
@ -94,11 +94,17 @@ static inline unsigned int processor_id(void)
|
||||||
#define UNCACHED_ADDR(a) (a)
|
#define UNCACHED_ADDR(a) (a)
|
||||||
#else
|
#else
|
||||||
#define UNCACHED_ADDR(a) \
|
#define UNCACHED_ADDR(a) \
|
||||||
((typeof (a))((uintptr_t)(a) + 0x10000000))
|
((typeof (a))((uintptr_t)(a) | 0x10000000))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CPU_PP502x
|
#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
|
#ifndef BOOTLOADER
|
||||||
#define CACHE_FUNCTIONS_AS_CALL
|
#define CACHE_FUNCTIONS_AS_CALL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue