aboutsummaryrefslogtreecommitdiffstats
path: root/memdisk/e820func.c
diff options
context:
space:
mode:
authorhpa <hpa>2001-12-09 05:57:00 +0000
committerhpa <hpa>2001-12-09 05:57:00 +0000
commit60db26b4fe464241b882791ca34d6233aa96ef24 (patch)
tree77307fe904dce932d3265d08b9ac69ebd03dca2d /memdisk/e820func.c
parent03a8cc27ff84852d1f56206a5ea492fd8b5e7e88 (diff)
downloadsyslinux.git-60db26b4fe464241b882791ca34d6233aa96ef24.tar.gz
syslinux.git-60db26b4fe464241b882791ca34d6233aa96ef24.tar.xz
syslinux.git-60db26b4fe464241b882791ca34d6233aa96ef24.zip
Initial work for the in-memory disk emulator
Diffstat (limited to 'memdisk/e820func.c')
-rw-r--r--memdisk/e820func.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/memdisk/e820func.c b/memdisk/e820func.c
new file mode 100644
index 00000000..72e1bf80
--- /dev/null
+++ b/memdisk/e820func.c
@@ -0,0 +1,96 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2001 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,
+ * Bostom 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>
+#include "e820.h"
+
+#define MAXRANGES 64
+/* All of memory starts out as one range of "indeterminate" type */
+struct e820range ranges[MAXRANGES] = { { 0ULL, 0 }, { 0ULL, (uint32_t)-1 } };
+int nranges = 1;
+
+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 = (uint32_t)-1;
+}
+
+void insertrange(uint64_t start, uint64_t len, uint32_t type)
+{
+ uint64_t newstart, 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 = -2;
+ while ( start > ranges[i].start && ranges[i].type != -1 ) {
+ oldtype = ranges[i].type;
+ i++;
+ }
+
+ /* Consider the replacement policy. This current one is "overwrite." */
+
+ if ( start < ranges[i].start || ranges[i].type == -1 )
+ 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);
+ }
+}
+