Align addresses in the buffering code to STORAGE_ALIGN_MASK if the target has one.

The PP502x DMA controller can only deal with doing DMA to 16-byte-aligned
addresses because we have inadequate control over the cache to prevent
interference. Other targets may also *prefer* cacheline aligned DMAs to
reduce the number of cache operations required. Almost all disk reads in
buffering.c will now be suitably aligned, allowing DMA to be used on PP502x.

Original change from FS#9708 by Boris Gjenero (dreamlayers).


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24440 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Torne Wuff 2010-02-01 17:16:39 +00:00
parent a09606123f
commit c4e051bed7
2 changed files with 49 additions and 4 deletions

View file

@ -108,7 +108,9 @@ struct memory_handle {
enum data_type type; /* Type of data buffered with this handle */
char path[MAX_PATH]; /* Path if data originated in a file */
int fd; /* File descriptor to path (-1 if closed) */
size_t data; /* Start index of the handle's data buffer */
size_t start; /* Start index of the handle's data buffer,
for use by reset_handle. */
size_t data; /* Start index of the handle's data */
volatile size_t ridx; /* Read pointer, relative to the main buffer */
size_t widx; /* Write pointer */
size_t filesize; /* File total length */
@ -713,13 +715,19 @@ static bool buffer_handle(int handle_id)
Use this after having set the new offset to use. */
static void reset_handle(int handle_id)
{
size_t alignment_pad;
logf("reset_handle(%d)", handle_id);
struct memory_handle *h = find_handle(handle_id);
if (!h)
return;
h->ridx = h->widx = h->data;
/* Align to desired storage alignment */
alignment_pad = (h->offset - (size_t)(&buffer[h->start]))
& STORAGE_ALIGN_MASK;
h->ridx = h->widx = h->data = RINGBUF_ADD(h->start, alignment_pad);
if (h == cur_handle)
buf_widx = h->widx;
h->available = 0;
@ -831,6 +839,7 @@ static void shrink_handle(struct memory_handle *h)
return;
h->data = RINGBUF_ADD(h->data, delta);
h->start = RINGBUF_ADD(h->start, delta);
h->available -= delta;
h->offset += delta;
}
@ -981,7 +990,9 @@ int bufopen(const char *file, size_t offset, enum data_type type,
if (adjusted_offset > size)
adjusted_offset = 0;
struct memory_handle *h = add_handle(size-adjusted_offset, can_wrap, false);
/* Reserve extra space because alignment can move data forward */
struct memory_handle *h = add_handle(size-adjusted_offset+STORAGE_ALIGN_MASK,
can_wrap, false);
if (!h)
{
DEBUGF("bufopen: failed to add handle\n");
@ -991,6 +1002,23 @@ int bufopen(const char *file, size_t offset, enum data_type type,
strlcpy(h->path, file, MAX_PATH);
h->offset = adjusted_offset;
/* Don't bother to storage align bitmaps because they are not
* loaded directly into the buffer.
*/
if (type != TYPE_BITMAP)
{
size_t alignment_pad;
/* Remember where data area starts, for use by reset_handle */
h->start = buf_widx;
/* Align to desired storage alignment */
alignment_pad = (adjusted_offset - (size_t)(&buffer[buf_widx]))
& STORAGE_ALIGN_MASK;
buf_widx = RINGBUF_ADD(buf_widx, alignment_pad);
}
h->ridx = buf_widx;
h->widx = buf_widx;
h->data = buf_widx;
@ -1522,7 +1550,8 @@ bool buffering_reset(char *buf, size_t buflen)
return false;
buffer = buf;
buffer_len = buflen;
/* Preserve alignment when wrapping around */
buffer_len = buflen & ~STORAGE_ALIGN_MASK;
guard_buffer = buf + buflen;
buf_widx = 0;

View file

@ -889,6 +889,22 @@ Lyre prototype 1 */
#endif /* HAVE_USBSTACK */
/* Storage alignment: the mask specifies a mask of bits which should be
* clear in addresses used for storage_{read,write}_sectors(). This is
* only relevant for buffers that will contain one or more whole sectors.
*/
/* PP502x DMA requires an alignment of at least 16 bytes */
#ifdef HAVE_ATA_DMA
#ifdef CPU_PP502x
#define STORAGE_ALIGN_MASK 15
#endif
#endif /* HAVE_ATA_DMA */
/* by default no alignment is required */
#ifndef STORAGE_ALIGN_MASK
#define STORAGE_ALIGN_MASK 0
#endif
#endif /* __CONFIG_H__ */