chain.c: change file/sect/hand area handling logic, add 'hptr' option
[syslinux/sherbszt.git] / memdisk / e820func.c
blob13c0a6fed6a0c1f7e16433aac277acbe374c09ed
1 /* ----------------------------------------------------------------------- *
3 * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
14 * e820func.c
16 * E820 range database manager
19 #include <stdint.h>
20 #ifdef TEST
21 #include <string.h>
22 #else
23 #include "memdisk.h" /* For memset() */
24 #endif
25 #include "e820.h"
27 #define MAXRANGES 1024
28 /* All of memory starts out as one range of "indeterminate" type */
29 struct e820range ranges[MAXRANGES];
30 int nranges;
32 void e820map_init(void)
34 memset(ranges, 0, sizeof(ranges));
35 nranges = 1;
36 ranges[1].type = -1U;
39 static void insertrange_at(int where, uint64_t start, uint32_t type)
41 int i;
43 for (i = nranges; i > where; i--)
44 ranges[i] = ranges[i - 1];
46 ranges[where].start = start;
47 ranges[where].type = type;
49 nranges++;
50 ranges[nranges].start = 0ULL;
51 ranges[nranges].type = -1U;
54 void insertrange(uint64_t start, uint64_t len, uint32_t type)
56 uint64_t last;
57 uint32_t oldtype;
58 int i, j;
60 /* Remove this to make len == 0 mean all of memory */
61 if (len == 0)
62 return; /* Nothing to insert */
64 last = start + len - 1; /* May roll over */
66 i = 0;
67 oldtype = -2U;
68 while (start > ranges[i].start && ranges[i].type != -1U) {
69 oldtype = ranges[i].type;
70 i++;
73 /* Consider the replacement policy. This current one is "overwrite." */
75 if (start < ranges[i].start || ranges[i].type == -1U)
76 insertrange_at(i++, start, type);
78 while (i == 0 || last > ranges[i].start - 1) {
79 oldtype = ranges[i].type;
80 ranges[i].type = type;
81 i++;
84 if (last < ranges[i].start - 1)
85 insertrange_at(i, last + 1, oldtype);
87 /* Now the map is correct, but quite possibly not optimal. Scan the
88 map for ranges which are redundant and remove them. */
89 i = j = 1;
90 oldtype = ranges[0].type;
91 while (i < nranges) {
92 if (ranges[i].type == oldtype) {
93 i++;
94 } else {
95 oldtype = ranges[i].type;
96 if (i != j)
97 ranges[j] = ranges[i];
98 i++;
99 j++;
103 if (i != j) {
104 ranges[j] = ranges[i]; /* Termination sentinel copy */
105 nranges -= (i - j);