/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * OpenRISC Linux * * Linux architectural port borrowing liberally from similar works of * others. All original copyrights apply as per the original source * declaration. * * OpenRISC implementation: * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> * et al.
*/
/* or1k pgtable.h - macros and functions to manipulate page tables * * Based on: * include/asm-cris/pgtable.h
*/
/* * The Linux memory management assumes a three-level page table setup. On * or1k, we use that, but "fold" the mid level into the top-level page * table. Since the MMU TLB is software loaded through an interrupt, it * supports any page table structure, so we could have used a three-level * setup, but for the amounts of memory we normally use, a two-level is * probably more efficient. * * This file contains the functions and defines necessary to modify and use * the or1k page table tree.
*/
externvoid paging_init(void);
/* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available.
*/ #define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
/* * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.)
*/ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
/* * entries per page directory level: we use a two-level, so * we don't really have any PMD directory physically. * pointers are 4 bytes so we can use the page size and * divide it by 4 (shift by 2).
*/ #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-2))
#define PTRS_PER_PGD (1UL << (32-PGDIR_SHIFT))
/* calculate how many PGD entries a user-level program can use * the first mappable virtual address is 0 * (TASK_SIZE is the maximum virtual address space)
*/
#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
/* * Kernels own virtual memory area.
*/
/* * The size and location of the vmalloc area are chosen so that modules * placed in this area aren't more than a 28-bit signed offset from any * kernel functions that they may need. This greatly simplifies handling * of the relocations for l.j and l.jal instructions as we don't need to * introduce any trampolines for reaching "distant" code. * * 64 MB of vmalloc area is comparable to what's available on other arches.
*/
/* Define some higher level generic page attributes. * * If you change _PAGE_CI definition be sure to change it in * io.h for ioremap() too.
*/
/* * An OR32 PTE looks like this: * * | 31 ... 10 | 9 | 8 ... 6 | 5 | 4 | 3 | 2 | 1 | 0 | * Phys pg.num L PP Index D A WOM WBC CI CC * * L : link * PPI: Page protection index * D : Dirty * A : Accessed * WOM: Weakly ordered memory * WBC: Write-back cache * CI : Cache inhibit * CC : Cache coherent * * The protection bits below should correspond to the layout of the actual * PTE as per above
*/
#define _PAGE_SRE 0x100 /* superuser read enable */ #define _PAGE_SWE 0x200 /* superuser write enable */ #define _PAGE_EXEC 0x400 /* software: page is executable */ #define _PAGE_U_SHARED 0x800 /* software: page is shared in user space */
/* 0x001 is cache coherency bit, which should always be set to * 1 - for SMP (when we support it) * 0 - otherwise * * we just reuse this bit in software for _PAGE_PRESENT and * force it to 0 when loading it into TLB.
*/ #define _PAGE_PRESENT _PAGE_CC #define _PAGE_USER _PAGE_URE #define _PAGE_WRITE (_PAGE_UWE | _PAGE_SWE) #define _PAGE_DIRTY _PAGE_D #define _PAGE_ACCESSED _PAGE_A #define _PAGE_NO_CACHE _PAGE_CI #define _PAGE_SHARED _PAGE_U_SHARED #define _PAGE_READ (_PAGE_URE | _PAGE_SRE)
/* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to.
*/
/* What actually goes as arguments to the various functions is less than * obvious, but a rule of thumb is that struct page's goes as struct page *, * really physical DRAM addresses are unsigned long's, and DRAM "virtual" * addresses (the 0xc0xxxxxx's) goes as void *'s.
*/
/* * pte_val refers to a page in the 0x0xxxxxxx physical DRAM interval * __pte_page(pte_val) refers to the "virtual" DRAM interval * pte_pagenr refers to the page-number counted starting from the virtual * DRAM start
*/
staticinlineunsignedlong __pte_page(pte_t pte)
{ /* the PTE contains a physical address */ return (unsignedlong)__va(pte_val(pte) & PAGE_MASK);
}
/* * only the pte's themselves need to point to physical DRAM (see above) * the pagetable links are purely handled within the kernel SW and thus * don't need the __pa and __va transformations.
*/ staticinlinevoid pmd_set(pmd_t *pmdp, pte_t *ptep)
{
pmd_val(*pmdp) = _KERNPG_TABLE | (unsignedlong) ptep;
}
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.