// SPDX-License-Identifier: GPL-2.0-or-later /* * Modifications by Kumar Gala (galak@kernel.crashing.org) to support * E500 Book E processors. * * Copyright 2004,2010 Freescale Semiconductor, Inc. * * This file contains the routines for initializing the MMU * on the 4xx series of chips. * -- paulus * * Derived from arch/ppc/mm/init.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) * and Cort Dougan (PReP) (cort@cs.nmt.edu) * Copyright (C) 1996 Paul Mackerras * * Derived from "arch/i386/mm/init.c" * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
*/
#ifdef CONFIG_PPC_85xx /* * Return PA for this VA if it is mapped by a CAM, or 0
*/
phys_addr_t v_block_mapped(unsignedlong va)
{ int b; for (b = 0; b < tlbcam_index; ++b) if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit) return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start); return 0;
}
/* * Return VA for a given PA or 0 if not mapped
*/ unsignedlong p_block_mapped(phys_addr_t pa)
{ int b; for (b = 0; b < tlbcam_index; ++b) if (pa >= tlbcam_addrs[b].phys
&& pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
+tlbcam_addrs[b].phys) return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); return 0;
} #endif
/* * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; * in particular size must be a power of 4 between 4k and the max supported by * an implementation; max may further be limited by what can be represented in * an unsigned long (for example, 32-bit implementations cannot support a 4GB * size).
*/ staticvoid settlbcam(int index, unsignedlong virt, phys_addr_t phys, unsignedlong size, unsignedlong flags, unsignedint pid)
{ unsignedint tsize;
/* * Relocatable kernel support based on processing of dynamic * relocation entries. Before we get the real memstart_addr, * We will compute the virt_phys_offset like this: * virt_phys_offset = stext.run - kernstart_addr * * stext.run = (KERNELBASE & ~0x3ffffff) + * (kernstart_addr & 0x3ffffff) * When we relocate, we have : * * (kernstart_addr & 0x3ffffff) = (stext.run & 0x3ffffff) * * hence: * virt_phys_offset = (KERNELBASE & ~0x3ffffff) - * (kernstart_addr & ~0x3ffffff) *
*/
start &= ~0x3ffffff;
base &= ~0x3ffffff;
virt_phys_offset = base - start;
early_get_first_memblock_info(__va(dt_ptr), &size); /* * We now get the memstart_addr, then we should check if this * address is the same as what the PAGE_OFFSET map to now. If * not we have to change the map of PAGE_OFFSET to memstart_addr * and do a second relocation.
*/ if (start != memstart_addr) { int n; long offset = start - memstart_addr;
is_second_reloc = 1;
n = switch_to_as1(); /* map a 64M area for the second relocation */ if (memstart_addr > start)
map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM, false, true); else
map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
0x4000000, CONFIG_LOWMEM_CAM_NUM, false, true);
restore_to_as0(n, offset, __va(dt_ptr), 1); /* We should never reach here */
panic("Relocation error");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.