aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>2010-12-30 13:56:12 +0000
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2010-12-30 13:56:12 +0000
commit6762c5050818441e4f7eb5b3d9395702dce2e7e5 (patch)
treea70de4909fa64d22abc5e2960676982b262337be
parent402ccb7e01276fcde6ea39d3553d4bf1082e6a98 (diff)
downloadopenbios-6762c5050818441e4f7eb5b3d9395702dce2e7e5.zip
openbios-6762c5050818441e4f7eb5b3d9395702dce2e7e5.tar.gz
openbios-6762c5050818441e4f7eb5b3d9395702dce2e7e5.tar.bz2
Fix alignment of memory allocated by OFMEM's ofmem_malloc().
A casual glance at the source code suggests that pointers returned by ofmem_malloc() are aligned, but in fact they are not because sizeof(alloc_desc_t) is added to the final pointer return value. Create some additional padding after the previous value of ofmem->next_malloc so we can store the alloc_desc_t underneath the final return pointer in memory, thus ensuring that the final pointer is aligned correctly. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@991 f158a5a8-5612-0410-a976-696ce0be7e32
-rw-r--r--libopenbios/ofmem_common.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/libopenbios/ofmem_common.c b/libopenbios/ofmem_common.c
index 20a4cba..bd0833f 100644
--- a/libopenbios/ofmem_common.c
+++ b/libopenbios/ofmem_common.c
@@ -28,9 +28,14 @@
//#define OFMEM_FILL_RANGE
-static inline size_t ALIGN_SIZE(size_t x, size_t a)
+static inline size_t align_size(size_t x, size_t a)
{
- return (x + a - 1) & ~(a-1);
+ return (x + a - 1) & ~(a - 1);
+}
+
+static inline void * align_ptr(uintptr_t x, size_t a)
+{
+ return (void *)((x + a - 1) & ~(a - 1));
}
static ucell get_ram_size( void )
@@ -85,7 +90,7 @@ void* ofmem_malloc( size_t size )
{
ofmem_t *ofmem = ofmem_arch_get_private();
alloc_desc_t *d, **pp;
- char *ret;
+ void *ret;
ucell top;
if( !size )
@@ -94,7 +99,7 @@ void* ofmem_malloc( size_t size )
if( !ofmem->next_malloc )
ofmem->next_malloc = (char*)ofmem_arch_get_malloc_base();
- size = ALIGN_SIZE(size + sizeof(alloc_desc_t), CONFIG_OFMEM_MALLOC_ALIGN);
+ size = align_size(size + sizeof(alloc_desc_t), CONFIG_OFMEM_MALLOC_ALIGN);
/* look in the freelist */
for( pp=&ofmem->mfree; *pp && (**pp).size < size; pp = &(**pp).next ) {
@@ -102,7 +107,7 @@ void* ofmem_malloc( size_t size )
/* waste at most 4K by taking an entry from the freelist */
if( *pp && (**pp).size < size + 0x1000 ) {
- ret = (char*)*pp + sizeof(alloc_desc_t);
+ ret = (void *)((uintptr_t)*pp + sizeof(alloc_desc_t));
memset( ret, 0, (**pp).size - sizeof(alloc_desc_t) );
*pp = (**pp).next;
return ret;
@@ -110,18 +115,18 @@ void* ofmem_malloc( size_t size )
top = ofmem_arch_get_heap_top();
- if( pointer2cell(ofmem->next_malloc) + size > top ) {
+ ret = align_ptr((uintptr_t)ofmem->next_malloc + sizeof(alloc_desc_t), CONFIG_OFMEM_MALLOC_ALIGN);
+ if( pointer2cell(ret) + size > top ) {
printk("out of malloc memory (%x)!\n", size );
return NULL;
}
- d = (alloc_desc_t*) ofmem->next_malloc;
+ d = (alloc_desc_t*)((uintptr_t)ret - sizeof(alloc_desc_t));
ofmem->next_malloc += size;
d->next = NULL;
d->size = size;
- ret = (char*)d + sizeof(alloc_desc_t);
memset( ret, 0, size - sizeof(alloc_desc_t) );
return ret;