Some uses of ofmem_malloc_align() need to ensure that the alignment requirement is for physical as well as virtual addresses, e.g. for MMU page tables.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk --- openbios-devel/include/arch/ppc/io.h | 20 ++++++++++++++++++++ openbios-devel/libopenbios/ofmem_common.c | 11 ++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/openbios-devel/include/arch/ppc/io.h b/openbios-devel/include/arch/ppc/io.h index 3449c5b..20586e4 100644 --- a/openbios-devel/include/arch/ppc/io.h +++ b/openbios-devel/include/arch/ppc/io.h @@ -9,6 +9,26 @@ extern char _start, _end; extern unsigned long virt_offset;
+static inline unsigned long +va2pa(unsigned long va) +{ + if ((va >= (unsigned long)&_start) && + (va < (unsigned long)&_end)) + return va - virt_offset; + else + return va; +} + +static inline unsigned long +pa2va(unsigned long pa) +{ + if ((pa + virt_offset >= (unsigned long)&_start) && + (pa + virt_offset < (unsigned long)&_end)) + return pa + virt_offset; + else + return pa; +} + #define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virt_offset)) #define virt_to_phys(virt) ((unsigned long) (virt) + virt_offset)
diff --git a/openbios-devel/libopenbios/ofmem_common.c b/openbios-devel/libopenbios/ofmem_common.c index e892260..50cd7d8 100644 --- a/openbios-devel/libopenbios/ofmem_common.c +++ b/openbios-devel/libopenbios/ofmem_common.c @@ -33,9 +33,9 @@ static inline size_t ALIGN_SIZE(size_t x, size_t a) return (x + a - 1) & ~(a-1); }
-static inline void * ALIGN_PTR(uintptr_t x, size_t a) +static inline phys_addr_t ALIGN_PTR(phys_addr_t x, size_t a) { - return (void *)((x + a - 1) & ~(a-1)); + return (x + a - 1) & ~(a-1); }
static ucell get_ram_size( void ) @@ -92,6 +92,7 @@ void* ofmem_malloc_align( size_t size, int alignment ) alloc_desc_t *d, **pp; char *ret; ucell top; + phys_addr_t pa;
if( !size ) return NULL; @@ -115,7 +116,11 @@ void* ofmem_malloc_align( size_t size, int alignment )
top = ofmem_arch_get_heap_top();
- ret = (char *)ALIGN_PTR((uintptr_t)ofmem->next_malloc + sizeof(alloc_desc_t), alignment); + /* Alignment should be on physical not virtual address */ + pa = va2pa((uintptr_t)ofmem->next_malloc + sizeof(alloc_desc_t)); + pa = ALIGN_PTR(pa, alignment); + ret = (char *)pa2va(pa); + if( pointer2cell((void *)ret) + size > top ) { printk("out of malloc memory (%x)!\n", size ); return NULL;