0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <stddef.h>
0013 #include "types.h"
0014 #include "page.h"
0015 #include "string.h"
0016 #include "ops.h"
0017
0018 #define ENTRY_BEEN_USED 0x01
0019 #define ENTRY_IN_USE 0x02
0020
0021 static struct alloc_info {
0022 unsigned long flags;
0023 unsigned long base;
0024 unsigned long size;
0025 } *alloc_tbl;
0026
0027 static unsigned long tbl_entries;
0028 static unsigned long alloc_min;
0029 static unsigned long next_base;
0030 static unsigned long space_left;
0031
0032
0033
0034
0035
0036
0037 static void *simple_malloc(unsigned long size)
0038 {
0039 unsigned long i;
0040 struct alloc_info *p = alloc_tbl;
0041
0042 if (size == 0)
0043 goto err_out;
0044
0045 size = _ALIGN_UP(size, alloc_min);
0046
0047 for (i=0; i<tbl_entries; i++, p++)
0048 if (!(p->flags & ENTRY_BEEN_USED)) {
0049 if (size <= space_left) {
0050 p->base = next_base;
0051 p->size = size;
0052 p->flags = ENTRY_BEEN_USED | ENTRY_IN_USE;
0053 next_base += size;
0054 space_left -= size;
0055 return (void *)p->base;
0056 }
0057 goto err_out;
0058 }
0059
0060 else if (!(p->flags & ENTRY_IN_USE) && (size <= p->size)) {
0061 p->flags |= ENTRY_IN_USE;
0062 return (void *)p->base;
0063 }
0064 err_out:
0065 return NULL;
0066 }
0067
0068 static struct alloc_info *simple_find_entry(void *ptr)
0069 {
0070 unsigned long i;
0071 struct alloc_info *p = alloc_tbl;
0072
0073 for (i=0; i<tbl_entries; i++,p++) {
0074 if (!(p->flags & ENTRY_BEEN_USED))
0075 break;
0076 if ((p->flags & ENTRY_IN_USE) &&
0077 (p->base == (unsigned long)ptr))
0078 return p;
0079 }
0080 return NULL;
0081 }
0082
0083 static void simple_free(void *ptr)
0084 {
0085 struct alloc_info *p = simple_find_entry(ptr);
0086
0087 if (p != NULL)
0088 p->flags &= ~ENTRY_IN_USE;
0089 }
0090
0091
0092
0093
0094
0095
0096
0097 static void *simple_realloc(void *ptr, unsigned long size)
0098 {
0099 struct alloc_info *p;
0100 void *new;
0101
0102 if (size == 0) {
0103 simple_free(ptr);
0104 return NULL;
0105 }
0106
0107 if (ptr == NULL)
0108 return simple_malloc(size);
0109
0110 p = simple_find_entry(ptr);
0111 if (p == NULL)
0112 return NULL;
0113 if (size <= p->size)
0114 return ptr;
0115
0116 new = simple_malloc(size);
0117 memcpy(new, ptr, p->size);
0118 simple_free(ptr);
0119 return new;
0120 }
0121
0122
0123
0124
0125
0126 void *simple_alloc_init(char *base, unsigned long heap_size,
0127 unsigned long granularity, unsigned long max_allocs)
0128 {
0129 unsigned long heap_base, tbl_size;
0130
0131 heap_size = _ALIGN_UP(heap_size, granularity);
0132 alloc_min = granularity;
0133 tbl_entries = max_allocs;
0134
0135 tbl_size = tbl_entries * sizeof(struct alloc_info);
0136
0137 alloc_tbl = (struct alloc_info *)_ALIGN_UP((unsigned long)base, 8);
0138 memset(alloc_tbl, 0, tbl_size);
0139
0140 heap_base = _ALIGN_UP((unsigned long)alloc_tbl + tbl_size, alloc_min);
0141
0142 next_base = heap_base;
0143 space_left = heap_size;
0144
0145 platform_ops.malloc = simple_malloc;
0146 platform_ops.free = simple_free;
0147 platform_ops.realloc = simple_realloc;
0148
0149 return (void *)(heap_base + heap_size);
0150 }