summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorne Wuff <torne@wolfpuppy.org.uk>2010-02-01 17:16:39 +0000
committerTorne Wuff <torne@wolfpuppy.org.uk>2010-02-01 17:16:39 +0000
commitc4e051bed7318b413bb9ba881678041acbec5991 (patch)
tree73172a91e509788d41ffc8f75d5d6ba3af7b21fb
parenta09606123f4e8501dd527c48d493853435df2a0d (diff)
downloadrockbox-c4e051bed7318b413bb9ba881678041acbec5991.tar.gz
rockbox-c4e051bed7318b413bb9ba881678041acbec5991.zip
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
-rw-r--r--apps/buffering.c37
-rw-r--r--firmware/export/config.h16
2 files changed, 49 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 {
108 enum data_type type; /* Type of data buffered with this handle */ 108 enum data_type type; /* Type of data buffered with this handle */
109 char path[MAX_PATH]; /* Path if data originated in a file */ 109 char path[MAX_PATH]; /* Path if data originated in a file */
110 int fd; /* File descriptor to path (-1 if closed) */ 110 int fd; /* File descriptor to path (-1 if closed) */
111 size_t data; /* Start index of the handle's data buffer */ 111 size_t start; /* Start index of the handle's data buffer,
112 for use by reset_handle. */
113 size_t data; /* Start index of the handle's data */
112 volatile size_t ridx; /* Read pointer, relative to the main buffer */ 114 volatile size_t ridx; /* Read pointer, relative to the main buffer */
113 size_t widx; /* Write pointer */ 115 size_t widx; /* Write pointer */
114 size_t filesize; /* File total length */ 116 size_t filesize; /* File total length */
@@ -713,13 +715,19 @@ static bool buffer_handle(int handle_id)
713 Use this after having set the new offset to use. */ 715 Use this after having set the new offset to use. */
714static void reset_handle(int handle_id) 716static void reset_handle(int handle_id)
715{ 717{
718 size_t alignment_pad;
719
716 logf("reset_handle(%d)", handle_id); 720 logf("reset_handle(%d)", handle_id);
717 721
718 struct memory_handle *h = find_handle(handle_id); 722 struct memory_handle *h = find_handle(handle_id);
719 if (!h) 723 if (!h)
720 return; 724 return;
721 725
722 h->ridx = h->widx = h->data; 726 /* Align to desired storage alignment */
727 alignment_pad = (h->offset - (size_t)(&buffer[h->start]))
728 & STORAGE_ALIGN_MASK;
729 h->ridx = h->widx = h->data = RINGBUF_ADD(h->start, alignment_pad);
730
723 if (h == cur_handle) 731 if (h == cur_handle)
724 buf_widx = h->widx; 732 buf_widx = h->widx;
725 h->available = 0; 733 h->available = 0;
@@ -831,6 +839,7 @@ static void shrink_handle(struct memory_handle *h)
831 return; 839 return;
832 840
833 h->data = RINGBUF_ADD(h->data, delta); 841 h->data = RINGBUF_ADD(h->data, delta);
842 h->start = RINGBUF_ADD(h->start, delta);
834 h->available -= delta; 843 h->available -= delta;
835 h->offset += delta; 844 h->offset += delta;
836 } 845 }
@@ -981,7 +990,9 @@ int bufopen(const char *file, size_t offset, enum data_type type,
981 if (adjusted_offset > size) 990 if (adjusted_offset > size)
982 adjusted_offset = 0; 991 adjusted_offset = 0;
983 992
984 struct memory_handle *h = add_handle(size-adjusted_offset, can_wrap, false); 993 /* Reserve extra space because alignment can move data forward */
994 struct memory_handle *h = add_handle(size-adjusted_offset+STORAGE_ALIGN_MASK,
995 can_wrap, false);
985 if (!h) 996 if (!h)
986 { 997 {
987 DEBUGF("bufopen: failed to add handle\n"); 998 DEBUGF("bufopen: failed to add handle\n");
@@ -991,6 +1002,23 @@ int bufopen(const char *file, size_t offset, enum data_type type,
991 1002
992 strlcpy(h->path, file, MAX_PATH); 1003 strlcpy(h->path, file, MAX_PATH);
993 h->offset = adjusted_offset; 1004 h->offset = adjusted_offset;
1005
1006 /* Don't bother to storage align bitmaps because they are not
1007 * loaded directly into the buffer.
1008 */
1009 if (type != TYPE_BITMAP)
1010 {
1011 size_t alignment_pad;
1012
1013 /* Remember where data area starts, for use by reset_handle */
1014 h->start = buf_widx;
1015
1016 /* Align to desired storage alignment */
1017 alignment_pad = (adjusted_offset - (size_t)(&buffer[buf_widx]))
1018 & STORAGE_ALIGN_MASK;
1019 buf_widx = RINGBUF_ADD(buf_widx, alignment_pad);
1020 }
1021
994 h->ridx = buf_widx; 1022 h->ridx = buf_widx;
995 h->widx = buf_widx; 1023 h->widx = buf_widx;
996 h->data = buf_widx; 1024 h->data = buf_widx;
@@ -1522,7 +1550,8 @@ bool buffering_reset(char *buf, size_t buflen)
1522 return false; 1550 return false;
1523 1551
1524 buffer = buf; 1552 buffer = buf;
1525 buffer_len = buflen; 1553 /* Preserve alignment when wrapping around */
1554 buffer_len = buflen & ~STORAGE_ALIGN_MASK;
1526 guard_buffer = buf + buflen; 1555 guard_buffer = buf + buflen;
1527 1556
1528 buf_widx = 0; 1557 buf_widx = 0;
diff --git a/firmware/export/config.h b/firmware/export/config.h
index f731fb5513..96fec57d7b 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -889,6 +889,22 @@ Lyre prototype 1 */
889 889
890#endif /* HAVE_USBSTACK */ 890#endif /* HAVE_USBSTACK */
891 891
892/* Storage alignment: the mask specifies a mask of bits which should be
893 * clear in addresses used for storage_{read,write}_sectors(). This is
894 * only relevant for buffers that will contain one or more whole sectors.
895 */
896
897/* PP502x DMA requires an alignment of at least 16 bytes */
898#ifdef HAVE_ATA_DMA
899#ifdef CPU_PP502x
900#define STORAGE_ALIGN_MASK 15
901#endif
902#endif /* HAVE_ATA_DMA */
903
904/* by default no alignment is required */
905#ifndef STORAGE_ALIGN_MASK
906#define STORAGE_ALIGN_MASK 0
907#endif
892 908
893 909
894#endif /* __CONFIG_H__ */ 910#endif /* __CONFIG_H__ */