#include <xen/nodemask.h>
#include <xen/numa.h>
#include <asm/acpi.h>
+#include <asm/e820.h>
#ifndef Dprintk
#define Dprintk(x...)
flsl(node_start_pfn(node) + node_spanned_pages(node) / 4 - 1)
+ PAGE_SHIFT, 32);
}
+
+int __init arch_get_ram_range(unsigned int idx, paddr_t *start, paddr_t *end)
+{
+ if ( idx >= e820.nr_map )
+ return -ENOENT;
+
+ if ( e820.map[idx].type != E820_RAM )
+ return -ENODATA;
+
+ *start = e820.map[idx].addr;
+ *end = *start + e820.map[idx].size;
+
+ return 0;
+}
Make sure the PXMs cover all memory. */
static int __init nodes_cover_memory(void)
{
- int i;
+ unsigned int i;
- for (i = 0; i < e820.nr_map; i++) {
- int j, found;
+ for (i = 0; ; i++) {
+ int err;
+ unsigned int j;
+ bool found;
paddr_t start, end;
- if (e820.map[i].type != E820_RAM) {
- continue;
- }
+ /* Try to loop memory map from index 0 to end to get RAM ranges. */
+ err = arch_get_ram_range(i, &start, &end);
- start = e820.map[i].addr;
- end = e820.map[i].addr + e820.map[i].size;
+ /* Reached the end of the memory map? */
+ if (err == -ENOENT)
+ break;
+
+ /* Skip non-RAM entries. */
+ if (err)
+ continue;
do {
- found = 0;
+ found = false;
for_each_node_mask(j, memory_nodes_parsed)
if (start < nodes[j].end
&& end > nodes[j].start) {
if (start >= nodes[j].start) {
start = nodes[j].end;
- found = 1;
+ found = true;
}
if (end <= nodes[j].end) {
end = nodes[j].start;
- found = 1;
+ found = true;
}
}
} while (found && start < end);
if (start < end) {
- printk(KERN_ERR "SRAT: No PXM for e820 range: "
+ printk(KERN_ERR "NUMA: No NODE for RAM range: "
"[%"PRIpaddr", %"PRIpaddr"]\n", start, end - 1);
return 0;
}
#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
NODE_DATA(nid)->node_spanned_pages)
+/*
+ * This function provides the ability for caller to get one RAM entry
+ * from architectural memory map by index.
+ *
+ * This function will return zero if it can return a proper RAM entry.
+ * Otherwise it will return -ENOENT for out of scope index, or other
+ * error codes, e.g. return -ENODATA for non-RAM type memory entry.
+ *
+ * Note: the range is exclusive at the end, e.g. [*start, *end).
+ */
+extern int arch_get_ram_range(unsigned int idx,
+ paddr_t *start, paddr_t *end);
+
#endif
#endif /* _XEN_NUMA_H */