[OpenBIOS] r153 - openbios-devel/arch/sparc32
svn at openbios.org
svn at openbios.org
Wed Jun 27 22:09:08 CEST 2007
Author: blueswirl
Date: 2007-06-27 22:09:08 +0200 (Wed, 27 Jun 2007)
New Revision: 153
Modified:
openbios-devel/arch/sparc32/lib.c
Log:
Get a real memory allocator for Sparc, based on PPC ofmem
Modified: openbios-devel/arch/sparc32/lib.c
===================================================================
--- openbios-devel/arch/sparc32/lib.c 2007-06-27 20:07:37 UTC (rev 152)
+++ openbios-devel/arch/sparc32/lib.c 2007-06-27 20:09:08 UTC (rev 153)
@@ -32,16 +32,127 @@
return i;
}
+typedef struct alloc_desc {
+ struct alloc_desc *next;
+ int size; /* size (including) this struct */
+} alloc_desc_t;
+
+typedef struct mem_range {
+ struct mem_range *next;
+ ulong start;
+ ulong size;
+} range_t;
+
+typedef struct trans {
+ struct trans *next;
+ ulong virt; /* chain is sorted by virt */
+ ulong size;
+ ulong phys;
+ int mode;
+} translation_t;
+
+static struct {
+ char *next_malloc;
+ int left;
+ alloc_desc_t *mfree; /* list of free malloc blocks */
+
+ range_t *phys_range;
+ range_t *virt_range;
+
+ translation_t *trans; /* this is really a translation_t */
+} ofmem;
+#define ALLOC_BLOCK (64 * 1024)
+
void *malloc(int size)
{
- extern struct mem cmem;
+ alloc_desc_t *d, **pp;
+ char *ret;
+ extern struct mem cmem;
- return mem_alloc(&cmem, size, 4);
+ if( !size )
+ return NULL;
+
+ if( size & 3 )
+ size += 4 - (size & 3);
+ size += sizeof(alloc_desc_t);
+
+ /* look in the freelist */
+ for( pp=&ofmem.mfree; *pp && (**pp).size < size; pp = &(**pp).next )
+ ;
+
+ /* waste at most 4K by taking an entry from the freelist */
+ if( *pp && (**pp).size < size + 0x1000 ) {
+ ret = (char*)*pp + sizeof(alloc_desc_t);
+ memset( ret, 0, (**pp).size - sizeof(alloc_desc_t) );
+ *pp = (**pp).next;
+ return ret;
+ }
+
+ if( !ofmem.next_malloc || ofmem.left < size) {
+ unsigned long alloc_size = ALLOC_BLOCK;
+ if (size > ALLOC_BLOCK)
+ alloc_size = size;
+ // Recover possible leftover
+ if (ofmem.left > sizeof(alloc_desc_t) + 4) {
+ alloc_desc_t *d;
+
+ d = (alloc_desc_t*)ofmem.next_malloc;
+ d->size = ofmem.left - sizeof(alloc_desc_t);
+ free((unsigned long)d + sizeof(alloc_desc_t));
+ }
+
+ ofmem.next_malloc = mem_alloc(&cmem, alloc_size, 4);
+ ofmem.left = alloc_size;
+ }
+
+ if( ofmem.left < size) {
+ printk("out of malloc memory (%x)!\n", size );
+ return NULL;
+ }
+ d = (alloc_desc_t*) ofmem.next_malloc;
+ ofmem.next_malloc += size;
+ ofmem.left -= size;
+
+ d->next = NULL;
+ d->size = size;
+
+ ret = (char*)d + sizeof(alloc_desc_t);
+ memset( ret, 0, size - sizeof(alloc_desc_t) );
+ return ret;
}
void free(void *ptr)
{
- /* Nothing yet */
+ alloc_desc_t **pp, *d;
+
+ /* it is legal to free NULL pointers (size zero allocations) */
+ if( !ptr )
+ return;
+
+ d = (alloc_desc_t*)((unsigned long)ptr - sizeof(alloc_desc_t));
+ d->next = ofmem.mfree;
+
+ /* insert in the (sorted) freelist */
+ for( pp=&ofmem.mfree; *pp && (**pp).size < d->size ; pp = &(**pp).next )
+ ;
+ d->next = *pp;
+ *pp = d;
}
+void *
+realloc( void *ptr, size_t size )
+{
+ alloc_desc_t *d = (alloc_desc_t*)((unsigned long)ptr - sizeof(alloc_desc_t));
+ char *p;
+ if( !ptr )
+ return malloc( size );
+ if( !size ) {
+ free( ptr );
+ return NULL;
+ }
+ p = malloc( size );
+ memcpy( p, ptr, MIN(d->size - sizeof(alloc_desc_t),size) );
+ free( ptr );
+ return p;
+}
More information about the OpenBIOS
mailing list