diff options
author | Torne Wuff <torne@wolfpuppy.org.uk> | 2010-02-01 17:16:39 +0000 |
---|---|---|
committer | Torne Wuff <torne@wolfpuppy.org.uk> | 2010-02-01 17:16:39 +0000 |
commit | c4e051bed7318b413bb9ba881678041acbec5991 (patch) | |
tree | 73172a91e509788d41ffc8f75d5d6ba3af7b21fb /apps/buffering.c | |
parent | a09606123f4e8501dd527c48d493853435df2a0d (diff) |
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
Diffstat (limited to 'apps/buffering.c')
-rw-r--r-- | apps/buffering.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 9deced433f..f261b5a711 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -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; |