diff options
-rw-r--r-- | apps/buffering.c | 37 | ||||
-rw-r--r-- | firmware/export/config.h | 16 |
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. */ |
714 | static void reset_handle(int handle_id) | 716 | static 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__ */ |