summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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__ */