8 #define STACK_SIZE 4096
10 #define MEMTYPE_MASK 7
11 #define MEM_USED 0x8000
17 struct memrange *next;
18 unsigned char start[];
28 static struct memrange *pool[NUM_POOLS];
29 static uint32_t stack_base, stack_top;
31 extern int _mem_start;
33 void move_init_stack(uint32_t newtop); /* in startup.s */
35 static void add_range(int pidx, struct memrange *mr);
41 struct memrange *mr, *smr;
42 struct alib_memnode *mem;
43 uint32_t mem_start = (uint32_t)&_mem_start;
45 printf("mem_start: %06lx\n", mem_start);
47 printf("Memory ranges:\n");
48 mem = execbase->memlist.head;
50 unsigned long start, end, size;
54 /* assume we're dealing with at least 64k blocks */
55 start = (unsigned long)mem->start & 0xff0000;
56 end = ((unsigned long)mem->end + 0xffff) & 0xff0000;
59 if(mem->attrib & ALIB_MEMF_CHIP) {
63 } else if(mem->attrib & ALIB_MEMF_FAST) {
64 if(start >= 0xc00000 && end <= 0xd80000) {
74 printf("ignoring memory range %06lx - %06lx of unknown type: %u\n",
75 start, end, mem->attrib);
80 printf(" %06lx - %06lx: %s (%ldk)\n", start, end, stype, size >> 10);
83 if(mem_start >= start && mem_start < end) {
84 size -= mem_start - start;
88 mr = (struct memrange*)start;
91 mr->size = size - sizeof *mr;
95 /* allocate stack space at the top of a memory range, order of preference:
99 for(i=0; i<NUM_POOLS; i++) {
102 /* ranges in the list are sorted, so keep updating the potential stack
103 * allocation until we reach the end of the list, and use the last one
104 * we found that fits. Note: at this point it's not expected that any
105 * one of the lists will have more than a single range, but this should
109 if(mr->size >= STACK_SIZE) {
110 stack_top = (uint32_t)mr->start + mr->size;
111 stack_base = stack_top - STACK_SIZE;
118 smr->size -= STACK_SIZE;
124 panic("Failed to allocate stack, no suitable memory ranges found!\n");
127 printf("Allocated %dk stack space: %06lx - %06lx\n", STACK_SIZE >> 10, stack_base, stack_top);
128 move_init_stack(stack_top);
133 #define MIN_MEMRANGE 8
135 void *mem_alloc(unsigned int sz, unsigned int attr)
138 struct memrange *mr, *prev, dummy;
139 struct memrange *mem = 0;
141 if(!(attr & MEM_ANY)) {
145 for(i=0; i<NUM_POOLS; i++) {
146 if(!(attr & (1 << i))) continue;
148 dummy.next = pool[i];
153 if(mr->size >= sz + sizeof *mr + MIN_MEMRANGE) {
154 /* we have enough space for a leftover piece */
157 mr = (struct memrange*)(mem->start + sz);
159 mr->size -= sz + sizeof *mr;
163 mem->attr |= MEM_USED;
166 /* not enough leftover space, just allocate the whole range */
168 mr->attr |= MEM_USED;
169 prev->next = mr->next;
177 pool[i] = dummy.next;
187 void mem_free(void *ptr)
189 struct memrange *mr = (struct memrange*)ptr - 1;
192 if(mr->magic != MAGIC || !(mr->attr & MEM_ANY)) {
196 if(mr->attr & MEM_FAST) {
198 } else if(mr->attr & MEM_SLOW) {
200 } else if(mr->attr & MEM_CHIP) {
210 printf("mem_free(%p): invalid pointer or magic corrupted\n", ptr);
211 memdump(mr, sizeof *mr);
215 static void add_range(int pidx, struct memrange *mr)
217 struct memrange *prev, *next, dummy;
219 printf("DBG adding free range: %06lx - %06lx to pool %d\n", (unsigned long)mr,
220 (unsigned long)(mr->start + mr->size), pidx);
222 dummy.next = pool[pidx];
225 while(prev->next && prev->next < mr) {
229 mr->next = prev->next;
233 if((next = mr->next) && mr->start + mr->size >= (unsigned char*)mr->next) {
234 mr->size = next->start + next->size - mr->start;
235 mr->next = next->next;
237 printf(" DBG coalescing up\n");
239 if(prev != &dummy && prev->start + prev->size >= (unsigned char*)mr) {
240 prev->size = mr->start + mr->size - prev->start;
241 prev->next = mr->next;
243 printf(" DBG coalescing down\n");
246 pool[pidx] = dummy.next;
249 void dbg_memprint(void)
251 struct memrange *mr = pool[POOL_SLOW];
255 printf(" [%lx - %lx]", (unsigned long)mr, (unsigned long)(mr->start + mr->size));