extern int memory_end_set;
extern unsigned long memory_end;
-void detect_memory_layout(struct mem_chunk chunk[]);
+void detect_memory_layout(struct mem_chunk chunk[], unsigned long maxsize);
void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
unsigned long size, int type);
struct mem_chunk *chunk_array;
chunk_array = kzalloc_panic(MEMORY_CHUNKS * sizeof(struct mem_chunk));
- detect_memory_layout(chunk_array);
+ detect_memory_layout(chunk_array, 0);
create_mem_hole(chunk_array, OLDMEM_BASE, OLDMEM_SIZE, CHUNK_CRASHK);
return chunk_array;
}
#define ADDR2G (1ULL << 31)
-static void find_memory_chunks(struct mem_chunk chunk[])
+static void find_memory_chunks(struct mem_chunk chunk[], unsigned long maxsize)
{
unsigned long long memsize, rnmax, rzm;
unsigned long addr = 0, size;
rzm = min(ADDR2G, rzm);
memsize = memsize ? min(ADDR2G, memsize) : ADDR2G;
}
+ if (maxsize)
+ memsize = memsize ? min((unsigned long)memsize, maxsize) : maxsize;
do {
size = 0;
type = tprot(addr);
break;
} while (type == tprot(addr + size));
if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) {
+ if (memsize && (addr + size > memsize))
+ size = memsize - addr;
chunk[i].addr = addr;
chunk[i].size = size;
chunk[i].type = type;
} while (addr < memsize && i < MEMORY_CHUNKS);
}
-void detect_memory_layout(struct mem_chunk chunk[])
+/**
+ * detect_memory_layout - fill mem_chunk array with memory layout data
+ * @chunk: mem_chunk array to be filled
+ * @maxsize: maximum address where memory detection should stop
+ *
+ * Fills the passed in memory chunk array with the memory layout of the
+ * machine. The array must have a size of at least MEMORY_CHUNKS and will
+ * be fully initialized afterwards.
+ * If the maxsize paramater has a value > 0 memory detection will stop at
+ * that address. It is guaranteed that all chunks have an ending address
+ * that is smaller than maxsize.
+ * If maxsize is 0 all memory will be detected.
+ */
+void detect_memory_layout(struct mem_chunk chunk[], unsigned long maxsize)
{
unsigned long flags, flags_dat, cr0;
}
__ctl_store(cr0, 0, 0);
__ctl_clear_bit(0, 28);
- find_memory_chunks(chunk);
+ find_memory_chunks(chunk, maxsize);
__ctl_load(cr0, 0, 0);
out:
__arch_local_irq_ssm(flags_dat);
GFP_KERNEL);
if (!chunk_array)
return -ENOMEM;
- detect_memory_layout(chunk_array);
+ detect_memory_layout(chunk_array, 0);
buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL);
if (!buf) {
kfree(chunk_array);
GFP_KERNEL);
if (!chunk_array)
return -ENOMEM;
- detect_memory_layout(chunk_array);
+ detect_memory_layout(chunk_array, 0);
for (i = 0; i < MEMORY_CHUNKS; i++) {
if (chunk_array[i].size == 0)
break;