First version
[people/xl0/gpxe.git] / src / arch / i386 / core / load_buffer.c
1 #include "limits.h"
2 #include "io.h"
3 #include "memsizes.h"
4 #include "init.h"
5 #include "buffer.h"
6
7 /*
8  * Initialise a buffer in an unused portion of memory, to be used for
9  * loading an image
10  *
11  */
12
13 /* Under KEEP_IT_REAL, always use 07c0:0000 as the buffer.  Otherwise,
14  * use a reset_fn that finds the largest available block of RAM.
15  */
16 struct buffer load_buffer = {
17         .start = 0x7c00,
18         .end = 0xa0000,
19 };
20
21 #ifndef KEEP_IT_REAL
22
23 extern char _text[];
24
25 static void init_load_buffer ( void ) {
26         unsigned int i;
27         unsigned long size = 0;
28
29         load_buffer.start = 0;
30         load_buffer.end = 0;
31
32         /* Find the largest usable segment in memory */
33         for ( i = 0 ; i < meminfo.map_count ; i++ ) {
34                 unsigned long r_start, r_end;
35
36                 if ( meminfo.map[i].type != E820_RAM )
37                         continue;
38
39                 if ( meminfo.map[i].addr + meminfo.map[i].size > ULONG_MAX )
40                         continue;
41
42                 r_start = meminfo.map[i].addr;
43                 r_end = meminfo.map[i].size;
44
45                 /* Avoid overlap with Etherboot.  Etherboot will be
46                  * located towards the top of a segment, so we need
47                  * only consider one-sided truncation.
48                  */
49                 if ( ( r_start <= virt_to_phys ( _text ) ) &&
50                      ( virt_to_phys ( _text ) < r_end ) ) {
51                         r_end = virt_to_phys ( _text );
52                 }
53
54                 if ( r_end - r_start > size ) {
55                         size = r_end - r_start;
56                         load_buffer.start = r_start;
57                         load_buffer.end = r_end;
58                 }
59         }
60 }
61
62 INIT_FN ( INIT_HEAP, init_load_buffer, init_load_buffer, NULL );
63                  
64 #endif