aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/init.c')
-rw-r--r--arch/mips/mm/init.c98
1 files changed, 43 insertions, 55 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8a038b30d3c4..090fa653dfa9 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -269,37 +269,46 @@ void __init fixrange_init(unsigned long start, unsigned long end,
#endif
}
-unsigned __weak platform_maar_init(unsigned num_pairs)
+struct maar_walk_info {
+ struct maar_config cfg[16];
+ unsigned int num_cfg;
+};
+
+static int maar_res_walk(unsigned long start_pfn, unsigned long nr_pages,
+ void *data)
{
- struct maar_config cfg[BOOT_MEM_MAP_MAX];
- unsigned i, num_configured, num_cfg = 0;
-
- for (i = 0; i < boot_mem_map.nr_map; i++) {
- switch (boot_mem_map.map[i].type) {
- case BOOT_MEM_RAM:
- case BOOT_MEM_INIT_RAM:
- break;
- default:
- continue;
- }
+ struct maar_walk_info *wi = data;
+ struct maar_config *cfg = &wi->cfg[wi->num_cfg];
+ unsigned int maar_align;
- /* Round lower up */
- cfg[num_cfg].lower = boot_mem_map.map[i].addr;
- cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
+ /* MAAR registers hold physical addresses right shifted by 4 bits */
+ maar_align = BIT(MIPS_MAAR_ADDR_SHIFT + 4);
- /* Round upper down */
- cfg[num_cfg].upper = boot_mem_map.map[i].addr +
- boot_mem_map.map[i].size;
- cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
+ /* Fill in the MAAR config entry */
+ cfg->lower = ALIGN(PFN_PHYS(start_pfn), maar_align);
+ cfg->upper = ALIGN_DOWN(PFN_PHYS(start_pfn + nr_pages), maar_align) - 1;
+ cfg->attrs = MIPS_MAAR_S;
+
+ /* Ensure we don't overflow the cfg array */
+ if (!WARN_ON(wi->num_cfg >= ARRAY_SIZE(wi->cfg)))
+ wi->num_cfg++;
+
+ return 0;
+}
- cfg[num_cfg].attrs = MIPS_MAAR_S;
- num_cfg++;
- }
- num_configured = maar_config(cfg, num_cfg, num_pairs);
- if (num_configured < num_cfg)
- pr_warn("Not enough MAAR pairs (%u) for all bootmem regions (%u)\n",
- num_pairs, num_cfg);
+unsigned __weak platform_maar_init(unsigned num_pairs)
+{
+ unsigned int num_configured;
+ struct maar_walk_info wi;
+
+ wi.num_cfg = 0;
+ walk_system_ram_range(0, max_pfn, &wi, maar_res_walk);
+
+ num_configured = maar_config(wi.cfg, wi.num_cfg, num_pairs);
+ if (num_configured < wi.num_cfg)
+ pr_warn("Not enough MAAR pairs (%u) for all memory regions (%u)\n",
+ num_pairs, wi.num_cfg);
return num_configured;
}
@@ -382,33 +391,6 @@ void maar_init(void)
}
#ifndef CONFIG_NEED_MULTIPLE_NODES
-int page_is_ram(unsigned long pagenr)
-{
- int i;
-
- for (i = 0; i < boot_mem_map.nr_map; i++) {
- unsigned long addr, end;
-
- switch (boot_mem_map.map[i].type) {
- case BOOT_MEM_RAM:
- case BOOT_MEM_INIT_RAM:
- break;
- default:
- /* not usable memory */
- continue;
- }
-
- addr = PFN_UP(boot_mem_map.map[i].addr);
- end = PFN_DOWN(boot_mem_map.map[i].addr +
- boot_mem_map.map[i].size);
-
- if (pagenr >= addr && pagenr < end)
- return 1;
- }
-
- return 0;
-}
-
void __init paging_init(void)
{
unsigned long max_zone_pfns[MAX_NR_ZONES];
@@ -443,7 +425,7 @@ void __init paging_init(void)
static struct kcore_list kcore_kseg0;
#endif
-static inline void mem_init_free_highmem(void)
+static inline void __init mem_init_free_highmem(void)
{
#ifdef CONFIG_HIGHMEM
unsigned long tmp;
@@ -454,7 +436,7 @@ static inline void mem_init_free_highmem(void)
for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
struct page *page = pfn_to_page(tmp);
- if (!page_is_ram(tmp))
+ if (!memblock_is_memory(PFN_PHYS(tmp)))
SetPageReserved(page);
else
free_highmem_page(page);
@@ -464,6 +446,12 @@ static inline void mem_init_free_highmem(void)
void __init mem_init(void)
{
+ /*
+ * When _PFN_SHIFT is greater than PAGE_SHIFT we won't have enough PTE
+ * bits to hold a full 32b physical address on MIPS32 systems.
+ */
+ BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (_PFN_SHIFT > PAGE_SHIFT));
+
#ifdef CONFIG_HIGHMEM
#ifdef CONFIG_DISCONTIGMEM
#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"