summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/memdisk/e820func.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/memdisk/e820func.c')
-rw-r--r--contrib/syslinux-4.02/memdisk/e820func.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/memdisk/e820func.c b/contrib/syslinux-4.02/memdisk/e820func.c
new file mode 100644
index 0000000..13c0a6f
--- /dev/null
+++ b/contrib/syslinux-4.02/memdisk/e820func.c
@@ -0,0 +1,107 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * e820func.c
+ *
+ * E820 range database manager
+ */
+
+#include <stdint.h>
+#ifdef TEST
+#include <string.h>
+#else
+#include "memdisk.h" /* For memset() */
+#endif
+#include "e820.h"
+
+#define MAXRANGES 1024
+/* All of memory starts out as one range of "indeterminate" type */
+struct e820range ranges[MAXRANGES];
+int nranges;
+
+void e820map_init(void)
+{
+ memset(ranges, 0, sizeof(ranges));
+ nranges = 1;
+ ranges[1].type = -1U;
+}
+
+static void insertrange_at(int where, uint64_t start, uint32_t type)
+{
+ int i;
+
+ for (i = nranges; i > where; i--)
+ ranges[i] = ranges[i - 1];
+
+ ranges[where].start = start;
+ ranges[where].type = type;
+
+ nranges++;
+ ranges[nranges].start = 0ULL;
+ ranges[nranges].type = -1U;
+}
+
+void insertrange(uint64_t start, uint64_t len, uint32_t type)
+{
+ uint64_t last;
+ uint32_t oldtype;
+ int i, j;
+
+ /* Remove this to make len == 0 mean all of memory */
+ if (len == 0)
+ return; /* Nothing to insert */
+
+ last = start + len - 1; /* May roll over */
+
+ i = 0;
+ oldtype = -2U;
+ while (start > ranges[i].start && ranges[i].type != -1U) {
+ oldtype = ranges[i].type;
+ i++;
+ }
+
+ /* Consider the replacement policy. This current one is "overwrite." */
+
+ if (start < ranges[i].start || ranges[i].type == -1U)
+ insertrange_at(i++, start, type);
+
+ while (i == 0 || last > ranges[i].start - 1) {
+ oldtype = ranges[i].type;
+ ranges[i].type = type;
+ i++;
+ }
+
+ if (last < ranges[i].start - 1)
+ insertrange_at(i, last + 1, oldtype);
+
+ /* Now the map is correct, but quite possibly not optimal. Scan the
+ map for ranges which are redundant and remove them. */
+ i = j = 1;
+ oldtype = ranges[0].type;
+ while (i < nranges) {
+ if (ranges[i].type == oldtype) {
+ i++;
+ } else {
+ oldtype = ranges[i].type;
+ if (i != j)
+ ranges[j] = ranges[i];
+ i++;
+ j++;
+ }
+ }
+
+ if (i != j) {
+ ranges[j] = ranges[i]; /* Termination sentinel copy */
+ nranges -= (i - j);
+ }
+}