linux/arch/powerpc/mm/init_32.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  PowerPC version
   4 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
   5 *
   6 *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
   7 *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
   8 *    Copyright (C) 1996 Paul Mackerras
   9 *  PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
  10 *
  11 *  Derived from "arch/i386/mm/init.c"
  12 *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/sched.h>
  17#include <linux/kernel.h>
  18#include <linux/errno.h>
  19#include <linux/string.h>
  20#include <linux/types.h>
  21#include <linux/mm.h>
  22#include <linux/stddef.h>
  23#include <linux/init.h>
  24#include <linux/highmem.h>
  25#include <linux/initrd.h>
  26#include <linux/pagemap.h>
  27#include <linux/memblock.h>
  28#include <linux/gfp.h>
  29#include <linux/slab.h>
  30#include <linux/hugetlb.h>
  31
  32#include <asm/prom.h>
  33#include <asm/io.h>
  34#include <asm/mmu.h>
  35#include <asm/smp.h>
  36#include <asm/machdep.h>
  37#include <asm/btext.h>
  38#include <asm/tlb.h>
  39#include <asm/sections.h>
  40#include <asm/hugetlb.h>
  41#include <asm/kup.h>
  42#include <asm/kasan.h>
  43
  44#include <mm/mmu_decl.h>
  45
  46#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
  47/* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */
  48#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET))
  49#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_KERNEL_START"
  50#endif
  51#endif
  52#define MAX_LOW_MEM     CONFIG_LOWMEM_SIZE
  53
  54phys_addr_t total_memory;
  55phys_addr_t total_lowmem;
  56
  57#ifdef CONFIG_RELOCATABLE
  58/* Used in __va()/__pa() */
  59long long virt_phys_offset;
  60EXPORT_SYMBOL(virt_phys_offset);
  61#endif
  62
  63phys_addr_t lowmem_end_addr;
  64
  65int boot_mapsize;
  66#ifdef CONFIG_PPC_PMAC
  67unsigned long agp_special_page;
  68EXPORT_SYMBOL(agp_special_page);
  69#endif
  70
  71void MMU_init(void);
  72
  73/*
  74 * this tells the system to map all of ram with the segregs
  75 * (i.e. page tables) instead of the bats.
  76 * -- Cort
  77 */
  78int __map_without_bats;
  79int __map_without_ltlbs;
  80
  81/* max amount of low RAM to map in */
  82unsigned long __max_low_memory = MAX_LOW_MEM;
  83
  84/*
  85 * Check for command-line options that affect what MMU_init will do.
  86 */
  87static void __init MMU_setup(void)
  88{
  89        /* Check for nobats option (used in mapin_ram). */
  90        if (strstr(boot_command_line, "nobats")) {
  91                __map_without_bats = 1;
  92        }
  93
  94        if (strstr(boot_command_line, "noltlbs")) {
  95                __map_without_ltlbs = 1;
  96        }
  97        if (IS_ENABLED(CONFIG_PPC_8xx))
  98                return;
  99
 100        if (IS_ENABLED(CONFIG_KFENCE))
 101                __map_without_ltlbs = 1;
 102
 103        if (debug_pagealloc_enabled())
 104                __map_without_ltlbs = 1;
 105
 106        if (strict_kernel_rwx_enabled())
 107                __map_without_ltlbs = 1;
 108}
 109
 110/*
 111 * MMU_init sets up the basic memory mappings for the kernel,
 112 * including both RAM and possibly some I/O regions,
 113 * and sets up the page tables and the MMU hardware ready to go.
 114 */
 115void __init MMU_init(void)
 116{
 117        if (ppc_md.progress)
 118                ppc_md.progress("MMU:enter", 0x111);
 119
 120        /* parse args from command line */
 121        MMU_setup();
 122
 123        /*
 124         * Reserve gigantic pages for hugetlb.  This MUST occur before
 125         * lowmem_end_addr is initialized below.
 126         */
 127        if (memblock.memory.cnt > 1) {
 128#ifndef CONFIG_WII
 129                memblock_enforce_memory_limit(memblock.memory.regions[0].size);
 130                pr_warn("Only using first contiguous memory region\n");
 131#else
 132                wii_memory_fixups();
 133#endif
 134        }
 135
 136        total_lowmem = total_memory = memblock_end_of_DRAM() - memstart_addr;
 137        lowmem_end_addr = memstart_addr + total_lowmem;
 138
 139#ifdef CONFIG_FSL_BOOKE
 140        /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
 141         * entries, so we need to adjust lowmem to match the amount we can map
 142         * in the fixed entries */
 143        adjust_total_lowmem();
 144#endif /* CONFIG_FSL_BOOKE */
 145
 146        if (total_lowmem > __max_low_memory) {
 147                total_lowmem = __max_low_memory;
 148                lowmem_end_addr = memstart_addr + total_lowmem;
 149#ifndef CONFIG_HIGHMEM
 150                total_memory = total_lowmem;
 151                memblock_enforce_memory_limit(total_lowmem);
 152#endif /* CONFIG_HIGHMEM */
 153        }
 154
 155        /* Initialize the MMU hardware */
 156        if (ppc_md.progress)
 157                ppc_md.progress("MMU:hw init", 0x300);
 158        MMU_init_hw();
 159
 160        /* Map in all of RAM starting at KERNELBASE */
 161        if (ppc_md.progress)
 162                ppc_md.progress("MMU:mapin", 0x301);
 163        mapin_ram();
 164
 165        /* Initialize early top-down ioremap allocator */
 166        ioremap_bot = IOREMAP_TOP;
 167
 168        if (ppc_md.progress)
 169                ppc_md.progress("MMU:exit", 0x211);
 170
 171        /* From now on, btext is no longer BAT mapped if it was at all */
 172#ifdef CONFIG_BOOTX_TEXT
 173        btext_unmap();
 174#endif
 175
 176        kasan_mmu_init();
 177
 178        setup_kup();
 179
 180        /* Shortly after that, the entire linear mapping will be available */
 181        memblock_set_current_limit(lowmem_end_addr);
 182}
 183