[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