Commit 2bf8ec2d authored by Thomas Bogendoerfer's avatar Thomas Bogendoerfer Committed by Ralf Baechle

[MIPS] IP27: Fix bootmem memory setup

Changes in the generic bootmem code broke memory setup for IP27. This
patch fixes this by replacing lots of special IP27 code with generic
bootmon code. This has been tested only on a single node.
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent c2719d93
...@@ -33,10 +33,6 @@ ...@@ -33,10 +33,6 @@
#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT) #define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT) #define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
#define SLOT_IGNORED 0xffff
static short __initdata slot_lastfilled_cache[MAX_COMPACT_NODES];
static unsigned short __initdata slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES]; static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES];
struct node_data *__node_data[MAX_COMPACT_NODES]; struct node_data *__node_data[MAX_COMPACT_NODES];
...@@ -267,51 +263,6 @@ static pfn_t __init slot_getbasepfn(cnodeid_t cnode, int slot) ...@@ -267,51 +263,6 @@ static pfn_t __init slot_getbasepfn(cnodeid_t cnode, int slot)
return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT); return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT);
} }
/*
* Return the number of pages of memory provided by the given slot
* on the specified node.
*/
static pfn_t __init slot_getsize(cnodeid_t node, int slot)
{
return (pfn_t) slot_psize_cache[node][slot];
}
/*
* Return highest slot filled
*/
static int __init node_getlastslot(cnodeid_t node)
{
return (int) slot_lastfilled_cache[node];
}
/*
* Return the pfn of the last free page of memory on a node.
*/
static pfn_t __init node_getmaxclick(cnodeid_t node)
{
pfn_t slot_psize;
int slot;
/*
* Start at the top slot. When we find a slot with memory in it,
* that's the winner.
*/
for (slot = (MAX_MEM_SLOTS - 1); slot >= 0; slot--) {
if ((slot_psize = slot_getsize(node, slot))) {
if (slot_psize == SLOT_IGNORED)
continue;
/* Return the basepfn + the slot size, minus 1. */
return slot_getbasepfn(node, slot) + slot_psize - 1;
}
}
/*
* If there's no memory on the node, return 0. This is likely
* to cause problems.
*/
return 0;
}
static pfn_t __init slot_psize_compute(cnodeid_t node, int slot) static pfn_t __init slot_psize_compute(cnodeid_t node, int slot)
{ {
nasid_t nasid; nasid_t nasid;
...@@ -404,13 +355,13 @@ static void __init mlreset(void) ...@@ -404,13 +355,13 @@ static void __init mlreset(void)
static void __init szmem(void) static void __init szmem(void)
{ {
pfn_t slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */ pfn_t slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */
int slot, ignore; int slot;
cnodeid_t node; cnodeid_t node;
num_physpages = 0; num_physpages = 0;
for_each_online_node(node) { for_each_online_node(node) {
ignore = nodebytes = 0; nodebytes = 0;
for (slot = 0; slot < MAX_MEM_SLOTS; slot++) { for (slot = 0; slot < MAX_MEM_SLOTS; slot++) {
slot_psize = slot_psize_compute(node, slot); slot_psize = slot_psize_compute(node, slot);
if (slot == 0) if (slot == 0)
...@@ -420,21 +371,20 @@ static void __init szmem(void) ...@@ -420,21 +371,20 @@ static void __init szmem(void)
* kernel text. * kernel text.
*/ */
nodebytes += (1LL << SLOT_SHIFT); nodebytes += (1LL << SLOT_SHIFT);
if (!slot_psize)
continue;
if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
(slot0sz << PAGE_SHIFT)) (slot0sz << PAGE_SHIFT)) {
ignore = 1;
if (ignore && slot_psize) {
printk("Ignoring slot %d onwards on node %d\n", printk("Ignoring slot %d onwards on node %d\n",
slot, node); slot, node);
slot_psize_cache[node][slot] = SLOT_IGNORED;
slot = MAX_MEM_SLOTS; slot = MAX_MEM_SLOTS;
continue; continue;
} }
num_physpages += slot_psize; num_physpages += slot_psize;
slot_psize_cache[node][slot] = add_active_range(node, slot_getbasepfn(node, slot),
(unsigned short) slot_psize; slot_getbasepfn(node, slot) + slot_psize);
if (slot_psize)
slot_lastfilled_cache[node] = slot;
} }
} }
} }
...@@ -442,18 +392,20 @@ static void __init szmem(void) ...@@ -442,18 +392,20 @@ static void __init szmem(void)
static void __init node_mem_init(cnodeid_t node) static void __init node_mem_init(cnodeid_t node)
{ {
pfn_t slot_firstpfn = slot_getbasepfn(node, 0); pfn_t slot_firstpfn = slot_getbasepfn(node, 0);
pfn_t slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
pfn_t slot_freepfn = node_getfirstfree(node); pfn_t slot_freepfn = node_getfirstfree(node);
struct pglist_data *pd;
unsigned long bootmap_size; unsigned long bootmap_size;
pfn_t start_pfn, end_pfn;
get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
/* /*
* Allocate the node data structures on the node first. * Allocate the node data structures on the node first.
*/ */
__node_data[node] = __va(slot_freepfn << PAGE_SHIFT); __node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
pd = NODE_DATA(node); NODE_DATA(node)->bdata = &plat_node_bdata[node];
pd->bdata = &plat_node_bdata[node]; NODE_DATA(node)->node_start_pfn = start_pfn;
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
cpus_clear(hub_data(node)->h_cpus); cpus_clear(hub_data(node)->h_cpus);
...@@ -461,12 +413,12 @@ static void __init node_mem_init(cnodeid_t node) ...@@ -461,12 +413,12 @@ static void __init node_mem_init(cnodeid_t node)
sizeof(struct hub_data)); sizeof(struct hub_data));
bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
slot_firstpfn, slot_lastpfn); start_pfn, end_pfn);
free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, free_bootmem_with_active_regions(node, end_pfn);
(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size, ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size,
BOOTMEM_DEFAULT); BOOTMEM_DEFAULT);
sparse_memory_present_with_active_regions(node);
} }
/* /*
...@@ -515,16 +467,15 @@ void __init paging_init(void) ...@@ -515,16 +467,15 @@ void __init paging_init(void)
pagetable_init(); pagetable_init();
for_each_online_node(node) { for_each_online_node(node) {
pfn_t start_pfn = slot_getbasepfn(node, 0); pfn_t start_pfn, end_pfn;
pfn_t end_pfn = node_getmaxclick(node) + 1;
zones_size[ZONE_NORMAL] = end_pfn - start_pfn; get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
free_area_init_node(node, NODE_DATA(node),
zones_size, start_pfn, NULL);
if (end_pfn > max_low_pfn) if (end_pfn > max_low_pfn)
max_low_pfn = end_pfn; max_low_pfn = end_pfn;
} }
zones_size[ZONE_NORMAL] = max_low_pfn;
free_area_init_nodes(zones_size);
} }
void __init mem_init(void) void __init mem_init(void)
...@@ -535,34 +486,10 @@ void __init mem_init(void) ...@@ -535,34 +486,10 @@ void __init mem_init(void)
high_memory = (void *) __va(num_physpages << PAGE_SHIFT); high_memory = (void *) __va(num_physpages << PAGE_SHIFT);
for_each_online_node(node) { for_each_online_node(node) {
unsigned slot, numslots;
struct page *end, *p;
/* /*
* This will free up the bootmem, ie, slot 0 memory. * This will free up the bootmem, ie, slot 0 memory.
*/ */
totalram_pages += free_all_bootmem_node(NODE_DATA(node)); totalram_pages += free_all_bootmem_node(NODE_DATA(node));
/*
* We need to manually do the other slots.
*/
numslots = node_getlastslot(node);
for (slot = 1; slot <= numslots; slot++) {
p = nid_page_nr(node, slot_getbasepfn(node, slot) -
slot_getbasepfn(node, 0));
/*
* Free valid memory in current slot.
*/
for (end = p + slot_getsize(node, slot); p < end; p++) {
/* if (!page_is_ram(pgnr)) continue; */
/* commented out until page_is_ram works */
ClearPageReserved(p);
init_page_count(p);
__free_page(p);
totalram_pages++;
}
}
} }
totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ totalram_pages -= setup_zero_pages(); /* This comes from node 0 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment