Browse Source

Tear out old heap code, replace with code that simply allocates memory

for use by malloc().

This breaks the image-loading code (which previously used the heap to
allocate the buffer for downloading the image), but that's not a major
concern since I'm going to tear out all the image formats within the next
couple of days anyway.  Byebye, NBI!  :)
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
0afa9db2de
5 changed files with 34 additions and 301 deletions
  1. 15
    196
      src/core/heap.c
  2. 4
    0
      src/core/image.c
  3. 0
    13
      src/core/osloader.c
  4. 15
    0
      src/include/gpxe/heap.h
  5. 0
    92
      src/include/heap.h

+ 15
- 196
src/core/heap.c View File

@@ -1,208 +1,27 @@
1
-#include "etherboot.h"
2
-#include <gpxe/init.h>
3
-#include "memsizes.h"
4
-#include <assert.h>
5
-#include "heap.h"
1
+#include <malloc.h>
2
+#include <gpxe/heap.h>
6 3
 
7
-struct heap_block {
8
-	size_t size;
9
-	unsigned int align;
10
-	char data[0];
11
-};
12
-
13
-/* Linker symbols */
14
-extern char _text[];
15
-extern char _end[];
16
-
17
-static physaddr_t heap_start;
18
-
19
-/*
20
- * Find the largest contiguous area of memory that I can use for the
21
- * heap.
22
- *
23
- */
24
-static void init_heap ( void ) {
25
-	unsigned int i;
26
-	physaddr_t eb_start, eb_end;
27
-	physaddr_t size;
28
-
29
-	size = 0;
30
-	
31
-	/* Region occupied by Etherboot */
32
-	eb_start = virt_to_phys ( _text );
33
-	eb_end = virt_to_phys ( _end );
34
-
35
-	for ( i = 0 ; i < meminfo.map_count ; i++ ) {
36
-		physaddr_t r_start, r_end, r_size;
37
-		physaddr_t pre_eb, post_eb;
38
-
39
-		/* Get start and end addresses of the region */
40
-		if ( meminfo.map[i].type != E820_RAM )
41
-			continue;
42
-		if ( meminfo.map[i].addr > ULONG_MAX )
43
-			continue;
44
-		r_start = meminfo.map[i].addr;
45
-		if ( r_start + meminfo.map[i].size > ULONG_MAX ) {
46
-			r_end = ULONG_MAX;
47
-		} else {
48
-			r_end = r_start + meminfo.map[i].size;
49
-		}
50
-		
51
-		/* Avoid overlap with Etherboot.  When Etherboot is
52
-		 * completely contained within the region, choose the
53
-		 * larger of the two remaining portions.
54
-		 */
55
-		if ( ( eb_start < r_end ) && ( eb_end > r_start ) ) {
56
-			pre_eb = ( eb_start > r_start ) ?
57
-				( eb_start - r_start ) : 0;
58
-			post_eb = ( r_end > eb_end ) ?
59
-				( r_end - eb_end ) : 0;
60
-			if ( pre_eb > post_eb ) {
61
-				r_end = eb_start;
62
-			} else {
63
-				r_start = eb_end;
64
-			}
65
-		}
66
-
67
-		/* Use the biggest region.  Where two regions are the
68
-		 * same size, use the later region.  (Provided that
69
-		 * the memory map is laid out in a sensible order,
70
-		 * this should give us the higher region.)
71
-		 */
72
-		r_size = r_end - r_start;
73
-		if ( r_size >= size ) {
74
-			heap_start = r_start;
75
-			heap_end = r_end;
76
-			size = r_size;
77
-		}
78
-	}
79
-
80
-	assert ( size != 0 );
81
-	DBG ( "HEAP using region [%x,%x)\n", heap_start, heap_end );
82
-	heap_ptr = heap_end;
83
-}
84
-
85
-/*
86
- * Allocate a block from the heap.
87
- *
88
- */
89
-static inline physaddr_t block_alloc_addr ( physaddr_t heap_ptr,
90
-					    size_t size, unsigned int align ) {
91
-	return ( ( ( heap_ptr - size ) & ~( align - 1 ) )
92
-		 - sizeof ( struct heap_block ) );
93
-}
94
-
95
-void * emalloc ( size_t size, unsigned int align ) {
96
-	struct heap_block *block;
97
-	physaddr_t addr;
98
-	
99
-	assert ( ( align & ( align - 1 ) ) == 0 );
100
-
101
-	addr = block_alloc_addr ( heap_ptr, size, align );
102
-	if ( addr < heap_start ) {
103
-		DBG ( "HEAP no space for %x bytes (alignment %d) in [%x,%x)\n",
104
-		      size, align, heap_start, heap_ptr );
105
-		return NULL;
106
-	}
107
-
108
-	block = phys_to_virt ( addr );
109
-	block->size = ( heap_ptr - addr );
110
-	block->align = align;
111
-	DBG ( "HEAP allocated %x bytes (alignment %d) at %x [%x,%x)\n",
112
-	      size, align, virt_to_phys ( block->data ), addr, heap_ptr );
113
-	heap_ptr = addr;
114
-	return block->data;
115
-}
116
-
117
-/*
118
- * Allocate all remaining space on the heap
4
+/**
5
+ * @file
119 6
  *
120
- */
121
-void * emalloc_all ( size_t *size ) {
122
-	*size = heap_ptr - heap_start - sizeof ( struct heap_block );
123
-	return emalloc ( *size, sizeof ( void * ) );
124
-}
125
-
126
-/*
127
- * Free a heap block
7
+ * Heap
128 8
  *
129 9
  */
130
-static inline physaddr_t block_free_addr ( size_t size ) {
131
-	return heap_ptr + size;
132
-}
133
-
134
-void efree ( void *ptr ) {
135
-	struct heap_block *block;
136
-
137
-	assert ( ptr == phys_to_virt ( heap_ptr + sizeof ( size_t ) ) );
138
-	
139
-	block = ( struct heap_block * )
140
-		( ptr - offsetof ( struct heap_block, data ) );
141
-	heap_ptr = block_free_addr ( block->size );
142
-
143
-	DBG ( "HEAP freed %x [%x,%x)\n", virt_to_phys ( ptr ),
144
-	      virt_to_phys ( block ), heap_ptr );
145 10
 
146
-	assert ( heap_ptr <= heap_end );
147
-}
148
-
149
-/*
150
- * Free all allocated heap blocks
11
+/**
12
+ * Heap size
151 13
  *
14
+ * Currently fixed at 48kB.
152 15
  */
153
-void efree_all ( void ) {
154
-	DBG ( "HEAP discarding allocated blocks in [%x,%x)\n",
155
-	      heap_ptr, heap_end );
16
+#define HEAP_SIZE ( 48 * 1024 )
156 17
 
157
-	heap_ptr = heap_end;
158
-}
18
+/** The heap itself */
19
+char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) )));
159 20
 
160
-/*
161
- * Resize a heap block
21
+/**
22
+ * Initialise the heap
162 23
  *
163 24
  */
164
-void * erealloc ( void *ptr, size_t size ) {
165
-	struct heap_block *old_block;
166
-	size_t old_size;
167
-	unsigned int old_align;
168
-	physaddr_t new_addr;
169
-	size_t move_size;
170
-	
171
-	/* Get descriptor of the old block */
172
-	old_block = ( struct heap_block * )
173
-		( ptr - offsetof ( struct heap_block, data ) );
174
-	old_size = old_block->size;
175
-	old_align = old_block->align;
176
-
177
-	/* Check that allocation is going to succeed */
178
-	new_addr = block_alloc_addr ( block_free_addr ( old_size ),
179
-				      size, old_align );
180
-	if ( new_addr < heap_start ) {
181
-		DBG ( "HEAP no space for %x bytes (alignment %d) in [%x,%x)\n",
182
-		      size, align, heap_start, block_free_addr ( old_size ) );
183
-		return NULL;
184
-	}
185
-
186
-	/* Free the old block */
187
-	efree ( ptr );
188
-
189
-	/* Move the data.  Do this *before* allocating the new block,
190
-	 * because the new block's descriptor may overwrite the old
191
-	 * block's data, if the new block is smaller than the old
192
-	 * block.
193
-	 */
194
-	move_size = size + sizeof ( struct heap_block );
195
-	if ( old_size < move_size )
196
-		move_size = old_size;
197
-	memmove ( phys_to_virt ( new_addr ), old_block, move_size );
198
-
199
-	/* Allocate the new block.  This must succeed, because we
200
-	 * already checked that there was sufficient space.
201
-	 */
202
-	ptr = emalloc ( size, old_align );
203
-	assert ( ptr != NULL );
204
-
205
-	return ptr;
25
+void init_heap ( void ) {
26
+	mpopulate ( heap, sizeof ( heap ) );
206 27
 }
207
-
208
-INIT_FN ( INIT_HEAP, init_heap, efree_all, NULL );

+ 4
- 0
src/core/image.c View File

@@ -18,6 +18,8 @@ void print_images ( void ) {
18 18
 	}
19 19
 }
20 20
 
21
+#if 0
22
+
21 23
 /*
22 24
  * Identify the image format
23 25
  *
@@ -80,3 +82,5 @@ int autoload ( struct dev *dev, struct image **image, void **context ) {
80 82
  out:
81 83
 	return rc;
82 84
 }
85
+
86
+#endif

+ 0
- 13
src/core/osloader.c View File

@@ -30,7 +30,6 @@ Modifications: Ken Yap (for Etherboot/16)
30 30
  */
31 31
 
32 32
 #include "io.h"
33
-#include "heap.h"
34 33
 #include "memsizes.h"
35 34
 
36 35
 /* Linker symbols */
@@ -57,18 +56,6 @@ int prep_segment ( physaddr_t start, physaddr_t mid, physaddr_t end ) {
57 56
 		return 0;
58 57
 	}
59 58
 
60
-	/* Check for overlap with used portion of heap.  Since the
61
-	 * heap code just finds the biggest available memory area, we
62
-	 * check only against the used heap area, rather than the
63
-	 * whole heap area.
64
-	 */
65
-	if ( ( end > heap_ptr ) && ( start < heap_end ) ) {
66
-		DBG ( "OSLOADER got segment [%lX, %lX) "
67
-		      "overlapping used heap [%lX, %lX)\n",
68
-		      start, end, heap_ptr, heap_end );
69
-		return 0;
70
-	}
71
-
72 59
 	/* Check that block fits entirely inside a single memory region */
73 60
 	fit = 0;
74 61
 	for ( i = 0 ; i < meminfo.map_count ; i++ ) {

+ 15
- 0
src/include/gpxe/heap.h View File

@@ -0,0 +1,15 @@
1
+#ifndef _GPXE_HEAP_H
2
+#define _GPXE_HEAP_H
3
+
4
+/**
5
+ * @file
6
+ *
7
+ * Heap
8
+ *
9
+ */
10
+
11
+extern char heap[];
12
+
13
+extern void init_heap ( void );
14
+
15
+#endif /* _GPXE_HEAP_H */

+ 0
- 92
src/include/heap.h View File

@@ -1,92 +0,0 @@
1
-#ifndef HEAP_H
2
-#define HEAP_H
3
-
4
-/*
5
- * Allocate a block with specified (physical) alignment
6
- *
7
- * "align" must be a power of 2.
8
- *
9
- * Note that "align" affects the alignment of the physical address,
10
- * not the virtual address.  This is almost certainly what you want.
11
- *
12
- */
13
-extern void * emalloc ( size_t size, unsigned int align );
14
-
15
-/*
16
- * Allocate all remaining space on the heap
17
- *
18
- */
19
-extern void * emalloc_all ( size_t *size );
20
-
21
-/*
22
- * Free a block.
23
- *
24
- * The caller must ensure that the block being freed is the last (most
25
- * recent) block allocated on the heap, otherwise heap corruption will
26
- * occur.
27
- *
28
- */
29
-extern void efree ( void *ptr );
30
-
31
-/*
32
- * Free all allocated blocks on the heap
33
- *
34
- */
35
-extern void efree_all ( void );
36
-
37
-/*
38
- * Resize a block.
39
- *
40
- * The caller must ensure that the block being resized is the last
41
- * (most recent) block allocated on the heap, otherwise heap
42
- * corruption will occur.
43
- *
44
- */
45
-extern void * erealloc ( void *ptr, size_t size );
46
-
47
-/*
48
- * Allocate, free, and resize blocks without caring about alignment
49
- *
50
- */
51
-static inline void * malloc ( size_t size ) {
52
-	return emalloc ( size, sizeof ( void * ) );
53
-}
54
-
55
-static inline void free ( void *ptr ) {
56
-	efree ( ptr );
57
-}
58
-
59
-static inline void * realloc ( void *ptr, size_t size ) {
60
-	return erealloc ( ptr, size );
61
-}
62
-
63
-/*
64
- * Legacy API calls
65
- *
66
- */
67
-static inline void * allot ( size_t size ) {
68
-	return emalloc ( size, sizeof ( void * ) );
69
-}
70
-
71
-static inline void forget ( void *ptr ) {
72
-	efree ( ptr );
73
-}
74
-
75
-static inline void * allot2 ( size_t size, uint32_t mask ) {
76
-	return emalloc ( size, mask + 1 );
77
-}
78
-
79
-static inline void forget2 ( void *ptr ) {
80
-	efree ( ptr );
81
-}
82
-
83
-/*
84
- * Heap markers.  osloader.c and other code may wish to know the heap
85
- * location, without necessarily wanting to drag in heap.o.  We
86
- * therefore declare these as shared (i.e. common) symbols.
87
- *
88
- */
89
-physaddr_t heap_ptr __asm__ ( "_shared_heap_ptr" );
90
-physaddr_t heap_end __asm__ ( "_shared_heap_end" );
91
-
92
-#endif /* HEAP_H */

Loading…
Cancel
Save