|
@@ -1,6 +1,14 @@
|
1
|
1
|
#include "etherboot.h"
|
2
|
2
|
#include "init.h"
|
3
|
3
|
#include "memsizes.h"
|
|
4
|
+#include "heap.h"
|
|
5
|
+
|
|
6
|
+#define ASSERT(...)
|
|
7
|
+
|
|
8
|
+struct heap_block {
|
|
9
|
+ size_t size;
|
|
10
|
+ char data[0];
|
|
11
|
+};
|
4
|
12
|
|
5
|
13
|
size_t heap_ptr, heap_top, heap_bot;
|
6
|
14
|
|
|
@@ -86,94 +94,59 @@ static void init_heap(void)
|
86
|
94
|
heap_ptr = heap_bot;
|
87
|
95
|
}
|
88
|
96
|
|
89
|
|
-static void reset_heap(void)
|
90
|
|
-{
|
91
|
|
- heap_ptr = heap_bot;
|
92
|
|
-}
|
93
|
|
-
|
94
|
|
-void *allot(size_t size)
|
95
|
|
-{
|
96
|
|
- void *ptr;
|
97
|
|
- size_t *mark, addr;
|
98
|
|
- /* Get an 16 byte aligned chunk of memory off of the heap
|
99
|
|
- * An extra sizeof(size_t) bytes is allocated to track
|
100
|
|
- * the size of the object allocated on the heap.
|
101
|
|
- */
|
102
|
|
- addr = (heap_ptr - (size + sizeof(size_t))) & ~15;
|
103
|
|
- if (addr < heap_top) {
|
104
|
|
- ptr = 0;
|
105
|
|
- } else {
|
106
|
|
- mark = phys_to_virt(addr);
|
107
|
|
- *mark = size;
|
108
|
|
- heap_ptr = addr;
|
109
|
|
- ptr = phys_to_virt(addr + sizeof(size_t));
|
|
97
|
+/*
|
|
98
|
+ * Allocate a block from the heap.
|
|
99
|
+ *
|
|
100
|
+ */
|
|
101
|
+void * emalloc ( size_t size, unsigned int align ) {
|
|
102
|
+ physaddr_t addr;
|
|
103
|
+ struct heap_block *block;
|
|
104
|
+
|
|
105
|
+ ASSERT ( ! ( align & ( align - 1 ) ) );
|
|
106
|
+
|
|
107
|
+ addr = ( ( ( heap_ptr - size ) & ~( align - 1 ) )
|
|
108
|
+ - sizeof ( struct heap_block ) );
|
|
109
|
+ if ( addr < heap_top ) {
|
|
110
|
+ return NULL;
|
110
|
111
|
}
|
111
|
|
- return ptr;
|
|
112
|
+
|
|
113
|
+ block = phys_to_virt ( addr );
|
|
114
|
+ block->size = ( heap_ptr - addr );
|
|
115
|
+ heap_ptr = addr;
|
|
116
|
+ return block->data;
|
112
|
117
|
}
|
113
|
118
|
|
114
|
|
-//if mask = 0xf, it will be 16 byte aligned
|
115
|
|
-//if mask = 0xff, it will be 256 byte aligned
|
116
|
|
-//For DMA memory allocation, because it has more reqiurement on alignment
|
117
|
|
-void *allot2(size_t size, uint32_t mask)
|
118
|
|
-{
|
119
|
|
- void *ptr;
|
120
|
|
- size_t *mark, addr;
|
121
|
|
- uint32_t *mark1;
|
122
|
|
-
|
123
|
|
- addr = ((heap_ptr - size ) & ~mask) - sizeof(size_t) - sizeof(uint32_t);
|
124
|
|
- if (addr < heap_top) {
|
125
|
|
- ptr = 0;
|
126
|
|
- } else {
|
127
|
|
- mark = phys_to_virt(addr);
|
128
|
|
- *mark = size;
|
129
|
|
- mark1 = phys_to_virt(addr+sizeof(size_t));
|
130
|
|
- *mark1 = mask;
|
131
|
|
- heap_ptr = addr;
|
132
|
|
- ptr = phys_to_virt(addr + sizeof(size_t) + sizeof(uint32_t));
|
133
|
|
- }
|
134
|
|
- return ptr;
|
135
|
|
-}
|
|
119
|
+/*
|
|
120
|
+ * Allocate all remaining space on the heap
|
|
121
|
+ *
|
|
122
|
+ */
|
|
123
|
+void * emalloc_all ( size_t *size ) {
|
|
124
|
+ *size = heap_ptr - heap_top - sizeof ( struct heap_block );
|
|
125
|
+ return emalloc ( *size, sizeof ( void * ) );
|
|
126
|
+}
|
136
|
127
|
|
137
|
|
-void forget(void *ptr)
|
138
|
|
-{
|
139
|
|
- size_t *mark, addr;
|
140
|
|
- size_t size;
|
|
128
|
+/*
|
|
129
|
+ * Free a heap block
|
|
130
|
+ *
|
|
131
|
+ */
|
|
132
|
+void efree ( void *ptr ) {
|
|
133
|
+ struct heap_block *block;
|
141
|
134
|
|
142
|
|
- if (!ptr) {
|
143
|
|
- return;
|
144
|
|
- }
|
145
|
|
- addr = virt_to_phys(ptr);
|
146
|
|
- mark = phys_to_virt(addr - sizeof(size_t));
|
147
|
|
- size = *mark;
|
148
|
|
- addr += (size + 15) & ~15;
|
|
135
|
+ ASSERT ( ptr == ( heap_ptr + sizeof ( size_t ) ) );
|
149
|
136
|
|
150
|
|
- if (addr > heap_bot) {
|
151
|
|
- addr = heap_bot;
|
152
|
|
- }
|
153
|
|
- heap_ptr = addr;
|
154
|
|
-}
|
155
|
|
-
|
156
|
|
-void forget2(void *ptr)
|
157
|
|
-{
|
158
|
|
- size_t *mark, addr;
|
159
|
|
- size_t size;
|
160
|
|
- uint32_t mask;
|
161
|
|
- uint32_t *mark1;
|
|
137
|
+ block = ( struct heap_block * )
|
|
138
|
+ ( ptr - offsetof ( struct heap_block, data ) );
|
|
139
|
+ heap_ptr += block->size;
|
162
|
140
|
|
163
|
|
- if (!ptr) {
|
164
|
|
- return;
|
165
|
|
- }
|
166
|
|
- addr = virt_to_phys(ptr);
|
167
|
|
- mark = phys_to_virt(addr - sizeof(size_t) - sizeof(uint32_t));
|
168
|
|
- size = *mark;
|
169
|
|
- mark1 = phys_to_virt(addr - sizeof(uint32_t));
|
170
|
|
- mask = *mark1;
|
171
|
|
- addr += (size + mask) & ~mask;
|
|
141
|
+ ASSERT ( heap_ptr <= heap_bot );
|
|
142
|
+}
|
172
|
143
|
|
173
|
|
- if (addr > heap_bot) {
|
174
|
|
- addr = heap_bot;
|
175
|
|
- }
|
176
|
|
- heap_ptr = addr;
|
|
144
|
+/*
|
|
145
|
+ * Free all allocated heap blocks
|
|
146
|
+ *
|
|
147
|
+ */
|
|
148
|
+void efree_all ( void ) {
|
|
149
|
+ heap_ptr = heap_bot;
|
177
|
150
|
}
|
178
|
151
|
|
179
|
|
-INIT_FN ( INIT_HEAP, init_heap, reset_heap, NULL );
|
|
152
|
+INIT_FN ( INIT_HEAP, init_heap, efree_all, NULL );
|