summaryrefslogtreecommitdiffstats
path: root/lib/libstand
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-02-05 22:53:58 +0000
committerian <ian@FreeBSD.org>2014-02-05 22:53:58 +0000
commit06622912a6d1b3e7836b9bf0bf0127bf814e6c89 (patch)
tree1468352483b9188a31f8a142442ed1984150ea6d /lib/libstand
parent7de248459b4d943ad4a313358f2051ad69f0d1dc (diff)
downloadFreeBSD-src-06622912a6d1b3e7836b9bf0bf0127bf814e6c89.zip
FreeBSD-src-06622912a6d1b3e7836b9bf0bf0127bf814e6c89.tar.gz
Set the malloc alignment to 64 bytes on platforms that use the U-Boot API
device drivers. Recent versions of u-boot run with the MMU enabled, and require DMA-based I/O to be aligned to cache line boundaries. These changes are based on a patch originally submitted by Juergen Weiss, but I reworked them and thus any problems are purely my fault. Submitted by: "Juergen Weiss" <weiss@uni-mainz.de> Reviewed by: imp, nwhitehorn, jhb
Diffstat (limited to 'lib/libstand')
-rw-r--r--lib/libstand/sbrk.c6
-rw-r--r--lib/libstand/zalloc.c9
-rw-r--r--lib/libstand/zalloc_defs.h16
-rw-r--r--lib/libstand/zalloc_mem.h2
4 files changed, 25 insertions, 8 deletions
diff --git a/lib/libstand/sbrk.c b/lib/libstand/sbrk.c
index 93d94e4..471e78e 100644
--- a/lib/libstand/sbrk.c
+++ b/lib/libstand/sbrk.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include "stand.h"
+#include "zalloc_defs.h"
static size_t maxheap, heapsize = 0;
static void *heapbase;
@@ -40,8 +41,9 @@ static void *heapbase;
void
setheap(void *base, void *top)
{
- /* Align start address to 16 bytes for the malloc code. Sigh. */
- heapbase = (void *)(((uintptr_t)base + 15) & ~15);
+ /* Align start address for the malloc code. Sigh. */
+ heapbase = (void *)(((uintptr_t)base + MALLOCALIGN_MASK) &
+ ~MALLOCALIGN_MASK);
maxheap = (char *)top - (char *)heapbase;
}
diff --git a/lib/libstand/zalloc.c b/lib/libstand/zalloc.c
index 41aef0d..4d1ec62 100644
--- a/lib/libstand/zalloc.c
+++ b/lib/libstand/zalloc.c
@@ -71,6 +71,15 @@ __FBSDID("$FreeBSD$");
#include "zalloc_defs.h"
/*
+ * Objects in the pool must be aligned to at least the size of struct MemNode.
+ * They must also be aligned to MALLOCALIGN, which should normally be larger
+ * than the struct, so assert that to be so at compile time.
+ */
+typedef char assert_align[(sizeof(struct MemNode) <= MALLOCALIGN) ? 1 : -1];
+
+#define MEMNODE_SIZE_MASK MALLOCALIGN_MASK
+
+/*
* znalloc() - allocate memory (without zeroing) from pool. Call reclaim
* and retry if appropriate, return NULL if unable to allocate
* memory.
diff --git a/lib/libstand/zalloc_defs.h b/lib/libstand/zalloc_defs.h
index 5331ee0..7f2cc12 100644
--- a/lib/libstand/zalloc_defs.h
+++ b/lib/libstand/zalloc_defs.h
@@ -52,18 +52,26 @@
#define BLKEXTENDMASK (BLKEXTEND - 1)
/*
- * required malloc alignment. Just hardwire to 16.
+ * Required malloc alignment.
*
- * Note: if we implement a more sophisticated realloc, we should ensure that
- * MALLOCALIGN is at least as large as MemNode.
+ * Embedded platforms using the u-boot API drivers require that all I/O buffers
+ * be on a cache line sized boundary. The worst case size for that is 64 bytes.
+ * For other platforms, 16 bytes works fine. The alignment also must be at
+ * least sizeof(struct MemNode); this is asserted in zalloc.c.
*/
+#if defined(__arm__) || defined(__mips__) || defined(__powerpc__)
+#define MALLOCALIGN 64
+#else
+#define MALLOCALIGN 16
+#endif
+#define MALLOCALIGN_MASK (MALLOCALIGN - 1)
+
typedef struct Guard {
size_t ga_Bytes;
size_t ga_Magic; /* must be at least 32 bits */
} Guard;
-#define MALLOCALIGN 16
#define GAMAGIC 0x55FF44FD
#define GAFREE 0x5F54F4DF
diff --git a/lib/libstand/zalloc_mem.h b/lib/libstand/zalloc_mem.h
index f29c0d7..26d388d 100644
--- a/lib/libstand/zalloc_mem.h
+++ b/lib/libstand/zalloc_mem.h
@@ -48,8 +48,6 @@ typedef struct MemPool {
uintptr_t mp_Used;
} MemPool;
-#define MEMNODE_SIZE_MASK ((sizeof(MemNode) <= 8) ? 7 : 15)
-
#define ZNOTE_FREE 0
#define ZNOTE_REUSE 1
OpenPOWER on IntegriCloud