[PATCH] powerpc: Take 3, merge page.h - BORKEN
Michael Ellerman
michael at ellerman.id.au
Fri Nov 11 13:09:17 EST 2005
That's missing a quilt ref, new version coming.
On Fri, 11 Nov 2005 12:03, Michael Ellerman wrote:
> Merge asm-ppc/page.h and asm-ppc64/page.h, into asm-powerpc/page.h,
> asm-powerpc/page_32.h and asm-powerpc/page_64.h
>
> There's a bit of weirdness in page_32.h, with APUS undef'ing things. I
> think this is cleaner though than polluting the rest of the code with
> PPC_MEMOFFSET etc.
>
> Built for PPC (common_defconfig), with ARCH=powerpc, mostly built with
> ARCH=ppc (other things break the build). Built and booted on P5 LPAR for
> PPC64 with ARCH=ppc/powerpc (pseries_defconfig). Mostly built and for
> iSeries powerpc.
>
> Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
> ---
>
> include/asm-powerpc/page.h | 173 +++++++++++++++++++++
> include/asm-powerpc/page_32.h | 97 ++++++++++++
> include/asm-powerpc/page_64.h | 177 ++++++++++++++++++++++
> include/asm-ppc/page.h | 173 ---------------------
> include/asm-ppc64/page.h | 333
> ------------------------------------------ 5 files changed, 447
> insertions(+), 506 deletions(-)
>
> Index: kexec/include/asm-powerpc/page.h
> ===================================================================
> --- /dev/null
> +++ kexec/include/asm-powerpc/page.h
> @@ -0,0 +1,173 @@
> +#ifndef _ASM_POWERPC_PAGE_H
> +#define _ASM_POWERPC_PAGE_H
> +
> +/*
> + * Copyright (C) 2001,2005 IBM Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#ifdef __KERNEL__
> +#include <linux/config.h>
> +#include <asm/ppc_asm.h> /* for ASM_CONST */
> +
> +/*
> + * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K
> software + * page size. When using 64K pages however, whether we are really
> supporting + * 64K pages in HW or not is irrelevant to those definitions.
> + */
> +#ifdef CONFIG_PPC_64K_PAGES
> +#define PAGE_SHIFT 16
> +#else
> +#define PAGE_SHIFT 12
> +#endif
> +
> +#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
> +
> +/*
> + * Subtle: (1 << PAGE_SHIFT) is an int, not an unsigned long. So on PPC32
> + * if we assign PAGE_MASK to a long long it gets extended the way want
> + * (i.e. with 1s in the high bits)
> + */
> +#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
> +
> +#define PAGE_OFFSET ASM_CONST(CONFIG_KERNEL_START)
> +#define KERNELBASE PAGE_OFFSET
> +
> +#ifdef CONFIG_DISCONTIGMEM
> +#define page_to_pfn(page) discontigmem_page_to_pfn(page)
> +#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
> +#define pfn_valid(pfn) discontigmem_pfn_valid(pfn)
> +#endif
> +
> +#ifdef CONFIG_FLATMEM
> +#define pfn_to_page(pfn) (mem_map + (pfn))
> +#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
> +#define pfn_valid(pfn) ((pfn) < max_mapnr)
> +#endif
> +
> +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
> +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
> +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> +
> +#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
> +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
> +
> +/*
> + * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
> + * and needs to be executable. This means the whole heap ends
> + * up being executable.
> + */
> +#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
> + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> +
> +#define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
> + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> +
> +#ifdef __powerpc64__
> +#include <asm/page_64.h>
> +#else
> +#include <asm/page_32.h>
> +#endif
> +
> +#undef STRICT_MM_TYPECHECKS
> +
> +#ifdef STRICT_MM_TYPECHECKS
> +/* These are used to make use of C type-checking. */
> +
> +/* PTE level */
> +typedef struct { pte_basic_t pte; } pte_t;
> +#define pte_val(x) ((x).pte)
> +#define __pte(x) ((pte_t) { (x) })
> +
> +/* 64k pages additionally define a bigger "real PTE" type that gathers
> + * the "second half" part of the PTE for pseudo 64k pages
> + */
> +#ifdef CONFIG_PPC_64K_PAGES
> +typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
> +#else
> +typedef struct { pte_t pte; } real_pte_t;
> +#endif
> +
> +/* PMD level */
> +typedef struct { unsigned long pmd; } pmd_t;
> +#define pmd_val(x) ((x).pmd)
> +#define __pmd(x) ((pmd_t) { (x) })
> +
> +/* PUD level exusts only on 4k pages */
> +#ifndef CONFIG_PPC_64K_PAGES
> +typedef struct { unsigned long pud; } pud_t;
> +#define pud_val(x) ((x).pud)
> +#define __pud(x) ((pud_t) { (x) })
> +#endif
> +
> +/* PGD level */
> +typedef struct { unsigned long pgd; } pgd_t;
> +#define pgd_val(x) ((x).pgd)
> +#define __pgd(x) ((pgd_t) { (x) })
> +
> +/* Page protection bits */
> +typedef struct { unsigned long pgprot; } pgprot_t;
> +#define pgprot_val(x) ((x).pgprot)
> +#define __pgprot(x) ((pgprot_t) { (x) })
> +
> +#else
> +
> +/*
> + * .. while these make it easier on the compiler
> + */
> +
> +typedef pte_basic_t pte_t;
> +#define pte_val(x) (x)
> +#define __pte(x) (x)
> +
> +#ifdef CONFIG_PPC_64K_PAGES
> +typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
> +#else
> +typedef unsigned long real_pte_t;
> +#endif
> +
> +
> +typedef unsigned long pmd_t;
> +#define pmd_val(x) (x)
> +#define __pmd(x) (x)
> +
> +#ifndef CONFIG_PPC_64K_PAGES
> +typedef unsigned long pud_t;
> +#define pud_val(x) (x)
> +#define __pud(x) (x)
> +#endif
> +
> +typedef unsigned long pgd_t;
> +#define pgd_val(x) (x)
> +#define pgprot_val(x) (x)
> +
> +typedef unsigned long pgprot_t;
> +#define __pgd(x) (x)
> +#define __pgprot(x) (x)
> +
> +#endif
> +
> +
> +/* align addr on a size boundary - adjust address up/down if needed */
> +#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
> +#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
> +
> +/* align addr on a size boundary - adjust address up if needed */
> +#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
> +
> +/* to align the pointer to the (next) page boundary */
> +#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
> +
> +struct page;
> +extern void clear_user_page(void *page, unsigned long vaddr, struct page
> *pg); +extern void copy_user_page(void *to, void *from, unsigned long
> vaddr, + struct page *p);
> +extern int page_is_ram(unsigned long pfn);
> +
> +#endif /* __KERNEL__ */
> +
> +#endif /* _ASM_POWERPC_PAGE_H */
> Index: kexec/include/asm-powerpc/page_32.h
> ===================================================================
> --- /dev/null
> +++ kexec/include/asm-powerpc/page_32.h
> @@ -0,0 +1,97 @@
> +#ifndef _ASM_POWERPC_PAGE_32_H
> +#define _ASM_POWERPC_PAGE_32_H
> +
> +#define VM_DATA_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS_32
> +
> +#ifndef __ASSEMBLY__
> +/*
> + * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
> + * physical addressing. For now this just the IBM PPC440.
> + */
> +#ifdef CONFIG_PTE_64BIT
> +typedef unsigned long long pte_basic_t;
> +#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */
> +#define PTE_FMT "%16Lx"
> +#else
> +typedef unsigned long pte_basic_t;
> +#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
> +#define PTE_FMT "%.8lx"
> +#endif
> +
> +struct page;
> +extern void clear_pages(void *page, int order);
> +static inline void clear_page(void *page) { clear_pages(page, 0); }
> +extern void copy_page(void *to, void *from);
> +
> +/* Pure 2^n version of get_order */
> +extern __inline__ int get_order(unsigned long size)
> +{
> + int lz;
> +
> + size = (size-1) >> PAGE_SHIFT;
> + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
> + return 32 - lz;
> +}
> +
> +#ifndef CONFIG_APUS
> +#define PPC_MEMSTART 0
> +#else /* CONFIG_APUS */
> +extern unsigned long ppc_memstart;
> +extern unsigned long ppc_pgstart;
> +extern unsigned long ppc_memoffset;
> +#define PPC_MEMSTART ppc_memstart
> +
> +#ifdef MODULE
> +#define ___pa(vaddr) ((vaddr) - ppc_memoffset)
> +#define ___va(paddr) ((paddr) + ppc_memoffset)
> +#else /* !MODULE */
> +/* map phys->virtual and virtual->phys for RAM pages */
> +static inline unsigned long ___pa(unsigned long v)
> +{
> + unsigned long p;
> + asm volatile ("1: addis %0, %1, %2;"
> + ".section \".vtop_fixup\",\"aw\";"
> + ".align 1;"
> + ".long 1b;"
> + ".previous;"
> + : "=r" (p)
> + : "b" (v), "K" (((-PAGE_OFFSET) >> 16) & 0xffff));
> +
> + return p;
> +}
> +static inline void* ___va(unsigned long p)
> +{
> + unsigned long v;
> + asm volatile ("1: addis %0, %1, %2;"
> + ".section \".ptov_fixup\",\"aw\";"
> + ".align 1;"
> + ".long 1b;"
> + ".previous;"
> + : "=r" (v)
> + : "b" (p), "K" (((PAGE_OFFSET) >> 16) & 0xffff));
> +
> + return (void*) v;
> +}
> +#endif
> +
> +/* APUS needs more complicated versions of these macros */
> +#undef __pa
> +#define __pa(x) ___pa((unsigned long)(x))
> +
> +#undef __va
> +#define __va(x) ((void *)(___va((unsigned long)(x))))
> +
> +#undef pfn_to_page
> +#define pfn_to_page(pfn) (mem_map + ((pfn) - ppc_pgstart))
> +
> +#undef page_to_pfn
> +#define page_to_pfn(page) ((unsigned long)((page) - mem_map) +
> ppc_pgstart) +
> +#undef pfn_valid
> +#define pfn_valid(pfn) (((pfn) - ppc_pgstart) < max_mapnr)
> +
> +#endif /* CONFIG_APUS */
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _ASM_POWERPC_PAGE_32_H */
> Index: kexec/include/asm-powerpc/page_64.h
> ===================================================================
> --- /dev/null
> +++ kexec/include/asm-powerpc/page_64.h
> @@ -0,0 +1,177 @@
> +#ifndef _ASM_POWERPC_PAGE_64_H
> +#define _ASM_POWERPC_PAGE_64_H
> +
> +/*
> + * Copyright (C) 2001 PPC64 Team, IBM Corp
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +/*
> + * We always define HW_PAGE_SHIFT to 12 as use of 64K pages remains Linux
> + * specific, every notion of page number shared with the firmware, TCEs,
> + * iommu, etc... still uses a page size of 4K.
> + */
> +#define HW_PAGE_SHIFT 12
> +#define HW_PAGE_SIZE (ASM_CONST(1) << HW_PAGE_SHIFT)
> +#define HW_PAGE_MASK (~(HW_PAGE_SIZE-1))
> +
> +/*
> + * PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and
> + * HW_PAGE_SHIFT, that is 4K pages.
> + */
> +#define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT)
> +
> +#define REGION_SIZE 4UL
> +#define REGION_SHIFT 60UL
> +#define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
> +
> +#define VMALLOCBASE ASM_CONST(0xD000000000000000)
> +#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT)
> +#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT)
> +#define USER_REGION_ID (0UL)
> +#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
> +
> +/* Segment size */
> +#define SID_SHIFT 28
> +#define SID_MASK 0xfffffffffUL
> +#define ESID_MASK 0xfffffffff0000000UL
> +#define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK)
> +
> +#ifndef __ASSEMBLY__
> +#include <asm/cache.h>
> +
> +typedef unsigned long pte_basic_t;
> +
> +static __inline__ void clear_page(void *addr)
> +{
> + unsigned long lines, line_size;
> +
> + line_size = ppc64_caches.dline_size;
> + lines = ppc64_caches.dlines_per_page;
> +
> + __asm__ __volatile__(
> + "mtctr %1 # clear_page\n\
> +1: dcbz 0,%0\n\
> + add %0,%0,%3\n\
> + bdnz+ 1b"
> + : "=r" (addr)
> + : "r" (lines), "0" (addr), "r" (line_size)
> + : "ctr", "memory");
> +}
> +
> +extern void copy_4K_page(void *to, void *from);
> +
> +#ifdef CONFIG_PPC_64K_PAGES
> +static inline void copy_page(void *to, void *from)
> +{
> + unsigned int i;
> + for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) {
> + copy_4K_page(to, from);
> + to += 4096;
> + from += 4096;
> + }
> +}
> +#else /* CONFIG_PPC_64K_PAGES */
> +static inline void copy_page(void *to, void *from)
> +{
> + copy_4K_page(to, from);
> +}
> +#endif /* CONFIG_PPC_64K_PAGES */
> +
> +/* Log 2 of page table size */
> +extern u64 ppc64_pft_size;
> +
> +/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
> +#define __HAVE_ARCH_GATE_AREA 1
> +
> +/* Large pages size */
> +extern unsigned int HPAGE_SHIFT;
> +#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
> +#define HPAGE_MASK (~(HPAGE_SIZE - 1))
> +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#ifdef CONFIG_HUGETLB_PAGE
> +
> +#define HTLB_AREA_SHIFT 40
> +#define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT)
> +#define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT)
> +
> +#define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \
> + - (1U << GET_ESID(addr))) & 0xffff)
> +#define HTLB_AREA_MASK(addr, len) (((1U <<
> (GET_HTLB_AREA(addr+len-1)+1)) \ + - (1U <<
> GET_HTLB_AREA(addr))) & 0xffff)
> +
> +#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
> +#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
> +#define ARCH_HAS_SETCLEAR_HUGE_PTE
> +
> +#define touches_hugepage_low_range(mm, addr, len) \
> + (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas)
> +#define touches_hugepage_high_range(mm, addr, len) \
> + (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas)
> +
> +#define __within_hugepage_low_range(addr, len, segmask) \
> + ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask))
> +#define within_hugepage_low_range(addr, len) \
> + __within_hugepage_low_range((addr), (len), \
> + current->mm->context.low_htlb_areas)
> +#define __within_hugepage_high_range(addr, len, zonemask) \
> + ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask))
> +#define within_hugepage_high_range(addr, len) \
> + __within_hugepage_high_range((addr), (len), \
> + current->mm->context.high_htlb_areas)
> +
> +#define is_hugepage_only_range(mm, addr, len) \
> + (touches_hugepage_high_range((mm), (addr), (len)) || \
> + touches_hugepage_low_range((mm), (addr), (len)))
> +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
> +
> +#define in_hugepage_area(context, addr) \
> + (cpu_has_feature(CPU_FTR_16M_PAGE) && \
> + ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \
> + ( ((addr) < 0x100000000L) && \
> + ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) )
> +
> +#else /* !CONFIG_HUGETLB_PAGE */
> +
> +#define in_hugepage_area(mm, addr) 0
> +
> +#endif /* !CONFIG_HUGETLB_PAGE */
> +
> +#ifdef MODULE
> +#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
> +#else
> +#define __page_aligned \
> + __attribute__((__aligned__(PAGE_SIZE), \
> + __section__(".data.page_aligned")))
> +#endif
> +
> +#define VM_DATA_DEFAULT_FLAGS \
> + (test_thread_flag(TIF_32BIT) ? \
> + VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
> +
> +/*
> + * This is the default if a program doesn't have a PT_GNU_STACK
> + * program header entry. The PPC64 ELF ABI has a non executable stack
> + * stack by default, so in the absense of a PT_GNU_STACK program header
> + * we turn execute permission off.
> + */
> +#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
> + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> +
> +#define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
> + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> +
> +#define VM_STACK_DEFAULT_FLAGS \
> + (test_thread_flag(TIF_32BIT) ? \
> + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
> +
> +#include <asm-generic/page.h>
> +
> +#endif /* _ASM_POWERPC_PAGE_64_H */
> Index: kexec/include/asm-ppc/page.h
> ===================================================================
> --- kexec.orig/include/asm-ppc/page.h
> +++ /dev/null
> @@ -1,173 +0,0 @@
> -#ifndef _PPC_PAGE_H
> -#define _PPC_PAGE_H
> -
> -/* PAGE_SHIFT determines the page size */
> -#define PAGE_SHIFT 12
> -#define PAGE_SIZE (1UL << PAGE_SHIFT)
> -
> -/*
> - * Subtle: this is an int (not an unsigned long) and so it
> - * gets extended to 64 bits the way want (i.e. with 1s). -- paulus
> - */
> -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
> -
> -#ifdef __KERNEL__
> -#include <linux/config.h>
> -
> -/* This must match what is in arch/ppc/Makefile */
> -#define PAGE_OFFSET CONFIG_KERNEL_START
> -#define KERNELBASE PAGE_OFFSET
> -
> -#ifndef __ASSEMBLY__
> -
> -/*
> - * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
> - * physical addressing. For now this just the IBM PPC440.
> - */
> -#ifdef CONFIG_PTE_64BIT
> -typedef unsigned long long pte_basic_t;
> -#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */
> -#define PTE_FMT "%16Lx"
> -#else
> -typedef unsigned long pte_basic_t;
> -#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
> -#define PTE_FMT "%.8lx"
> -#endif
> -
> -/* align addr on a size boundary - adjust address up/down if needed */
> -#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
> -#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
> -
> -/* align addr on a size boundary - adjust address up if needed */
> -#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
> -
> -/* to align the pointer to the (next) page boundary */
> -#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
> -
> -
> -#undef STRICT_MM_TYPECHECKS
> -
> -#ifdef STRICT_MM_TYPECHECKS
> -/*
> - * These are used to make use of C type-checking..
> - */
> -typedef struct { pte_basic_t pte; } pte_t;
> -typedef struct { unsigned long pmd; } pmd_t;
> -typedef struct { unsigned long pgd; } pgd_t;
> -typedef struct { unsigned long pgprot; } pgprot_t;
> -
> -#define pte_val(x) ((x).pte)
> -#define pmd_val(x) ((x).pmd)
> -#define pgd_val(x) ((x).pgd)
> -#define pgprot_val(x) ((x).pgprot)
> -
> -#define __pte(x) ((pte_t) { (x) } )
> -#define __pmd(x) ((pmd_t) { (x) } )
> -#define __pgd(x) ((pgd_t) { (x) } )
> -#define __pgprot(x) ((pgprot_t) { (x) } )
> -
> -#else
> -/*
> - * .. while these make it easier on the compiler
> - */
> -typedef pte_basic_t pte_t;
> -typedef unsigned long pmd_t;
> -typedef unsigned long pgd_t;
> -typedef unsigned long pgprot_t;
> -
> -#define pte_val(x) (x)
> -#define pmd_val(x) (x)
> -#define pgd_val(x) (x)
> -#define pgprot_val(x) (x)
> -
> -#define __pte(x) (x)
> -#define __pmd(x) (x)
> -#define __pgd(x) (x)
> -#define __pgprot(x) (x)
> -
> -#endif
> -
> -struct page;
> -extern void clear_pages(void *page, int order);
> -static inline void clear_page(void *page) { clear_pages(page, 0); }
> -extern void copy_page(void *to, void *from);
> -extern void clear_user_page(void *page, unsigned long vaddr, struct page
> *pg); -extern void copy_user_page(void *to, void *from, unsigned long
> vaddr, - struct page *pg);
> -
> -#ifndef CONFIG_APUS
> -#define PPC_MEMSTART 0
> -#define PPC_PGSTART 0
> -#define PPC_MEMOFFSET PAGE_OFFSET
> -#else
> -extern unsigned long ppc_memstart;
> -extern unsigned long ppc_pgstart;
> -extern unsigned long ppc_memoffset;
> -#define PPC_MEMSTART ppc_memstart
> -#define PPC_PGSTART ppc_pgstart
> -#define PPC_MEMOFFSET ppc_memoffset
> -#endif
> -
> -#if defined(CONFIG_APUS) && !defined(MODULE)
> -/* map phys->virtual and virtual->phys for RAM pages */
> -static inline unsigned long ___pa(unsigned long v)
> -{
> - unsigned long p;
> - asm volatile ("1: addis %0, %1, %2;"
> - ".section \".vtop_fixup\",\"aw\";"
> - ".align 1;"
> - ".long 1b;"
> - ".previous;"
> - : "=r" (p)
> - : "b" (v), "K" (((-PAGE_OFFSET) >> 16) & 0xffff));
> -
> - return p;
> -}
> -static inline void* ___va(unsigned long p)
> -{
> - unsigned long v;
> - asm volatile ("1: addis %0, %1, %2;"
> - ".section \".ptov_fixup\",\"aw\";"
> - ".align 1;"
> - ".long 1b;"
> - ".previous;"
> - : "=r" (v)
> - : "b" (p), "K" (((PAGE_OFFSET) >> 16) & 0xffff));
> -
> - return (void*) v;
> -}
> -#else
> -#define ___pa(vaddr) ((vaddr)-PPC_MEMOFFSET)
> -#define ___va(paddr) ((paddr)+PPC_MEMOFFSET)
> -#endif
> -
> -extern int page_is_ram(unsigned long pfn);
> -
> -#define __pa(x) ___pa((unsigned long)(x))
> -#define __va(x) ((void *)(___va((unsigned long)(x))))
> -
> -#define pfn_to_page(pfn) (mem_map + ((pfn) - PPC_PGSTART))
> -#define page_to_pfn(page) ((unsigned long)((page) - mem_map) +
> PPC_PGSTART) -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >>
> PAGE_SHIFT) -#define page_to_virt(page) __va(page_to_pfn(page) <<
> PAGE_SHIFT)
> -
> -#define pfn_valid(pfn) (((pfn) - PPC_PGSTART) < max_mapnr)
> -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> -
> -/* Pure 2^n version of get_order */
> -extern __inline__ int get_order(unsigned long size)
> -{
> - int lz;
> -
> - size = (size-1) >> PAGE_SHIFT;
> - asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
> - return 32 - lz;
> -}
> -
> -#endif /* __ASSEMBLY__ */
> -
> -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
> - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> -
> -#endif /* __KERNEL__ */
> -#endif /* _PPC_PAGE_H */
> Index: kexec/include/asm-ppc64/page.h
> ===================================================================
> --- kexec.orig/include/asm-ppc64/page.h
> +++ /dev/null
> @@ -1,333 +0,0 @@
> -#ifndef _PPC64_PAGE_H
> -#define _PPC64_PAGE_H
> -
> -/*
> - * Copyright (C) 2001 PPC64 Team, IBM Corp
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version
> - * 2 of the License, or (at your option) any later version.
> - */
> -
> -#include <linux/config.h>
> -#include <asm/ppc_asm.h> /* for ASM_CONST */
> -
> -/*
> - * We support either 4k or 64k software page size. When using 64k pages
> - * however, wether we are really supporting 64k pages in HW or not is
> - * irrelevant to those definitions. We always define HW_PAGE_SHIFT to 12
> - * as use of 64k pages remains a linux kernel specific, every notion of
> - * page number shared with the firmware, TCEs, iommu, etc... still assumes
> - * a page size of 4096.
> - */
> -#ifdef CONFIG_PPC_64K_PAGES
> -#define PAGE_SHIFT 16
> -#else
> -#define PAGE_SHIFT 12
> -#endif
> -
> -#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
> -#define PAGE_MASK (~(PAGE_SIZE-1))
> -
> -/* HW_PAGE_SHIFT is always 4k pages */
> -#define HW_PAGE_SHIFT 12
> -#define HW_PAGE_SIZE (ASM_CONST(1) << HW_PAGE_SHIFT)
> -#define HW_PAGE_MASK (~(HW_PAGE_SIZE-1))
> -
> -/* PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and
> - * HW_PAGE_SHIFT, that is 4k pages
> - */
> -#define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT)
> -
> -/* Segment size */
> -#define SID_SHIFT 28
> -#define SID_MASK 0xfffffffffUL
> -#define ESID_MASK 0xfffffffff0000000UL
> -#define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK)
> -
> -/* Large pages size */
> -
> -#ifndef __ASSEMBLY__
> -extern unsigned int HPAGE_SHIFT;
> -#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
> -#define HPAGE_MASK (~(HPAGE_SIZE - 1))
> -#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
> -#endif /* __ASSEMBLY__ */
> -
> -#ifdef CONFIG_HUGETLB_PAGE
> -
> -
> -#define HTLB_AREA_SHIFT 40
> -#define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT)
> -#define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT)
> -
> -#define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \
> - - (1U << GET_ESID(addr))) & 0xffff)
> -#define HTLB_AREA_MASK(addr, len) (((1U <<
> (GET_HTLB_AREA(addr+len-1)+1)) \ - - (1U <<
> GET_HTLB_AREA(addr))) & 0xffff) -
> -#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
> -#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
> -#define ARCH_HAS_SETCLEAR_HUGE_PTE
> -
> -#define touches_hugepage_low_range(mm, addr, len) \
> - (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas)
> -#define touches_hugepage_high_range(mm, addr, len) \
> - (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas)
> -
> -#define __within_hugepage_low_range(addr, len, segmask) \
> - ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask))
> -#define within_hugepage_low_range(addr, len) \
> - __within_hugepage_low_range((addr), (len), \
> - current->mm->context.low_htlb_areas)
> -#define __within_hugepage_high_range(addr, len, zonemask) \
> - ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask))
> -#define within_hugepage_high_range(addr, len) \
> - __within_hugepage_high_range((addr), (len), \
> - current->mm->context.high_htlb_areas)
> -
> -#define is_hugepage_only_range(mm, addr, len) \
> - (touches_hugepage_high_range((mm), (addr), (len)) || \
> - touches_hugepage_low_range((mm), (addr), (len)))
> -#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
> -
> -#define in_hugepage_area(context, addr) \
> - (cpu_has_feature(CPU_FTR_16M_PAGE) && \
> - ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \
> - ( ((addr) < 0x100000000L) && \
> - ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) )
> -
> -#else /* !CONFIG_HUGETLB_PAGE */
> -
> -#define in_hugepage_area(mm, addr) 0
> -
> -#endif /* !CONFIG_HUGETLB_PAGE */
> -
> -/* align addr on a size boundary - adjust address up/down if needed */
> -#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
> -#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
> -
> -/* align addr on a size boundary - adjust address up if needed */
> -#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
> -
> -/* to align the pointer to the (next) page boundary */
> -#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
> -
> -#ifdef __KERNEL__
> -#ifndef __ASSEMBLY__
> -#include <asm/cache.h>
> -
> -#undef STRICT_MM_TYPECHECKS
> -
> -#define REGION_SIZE 4UL
> -#define REGION_SHIFT 60UL
> -#define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
> -
> -static __inline__ void clear_page(void *addr)
> -{
> - unsigned long lines, line_size;
> -
> - line_size = ppc64_caches.dline_size;
> - lines = ppc64_caches.dlines_per_page;
> -
> - __asm__ __volatile__(
> - "mtctr %1 # clear_page\n\
> -1: dcbz 0,%0\n\
> - add %0,%0,%3\n\
> - bdnz+ 1b"
> - : "=r" (addr)
> - : "r" (lines), "0" (addr), "r" (line_size)
> - : "ctr", "memory");
> -}
> -
> -extern void copy_4K_page(void *to, void *from);
> -
> -#ifdef CONFIG_PPC_64K_PAGES
> -static inline void copy_page(void *to, void *from)
> -{
> - unsigned int i;
> - for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) {
> - copy_4K_page(to, from);
> - to += 4096;
> - from += 4096;
> - }
> -}
> -#else /* CONFIG_PPC_64K_PAGES */
> -static inline void copy_page(void *to, void *from)
> -{
> - copy_4K_page(to, from);
> -}
> -#endif /* CONFIG_PPC_64K_PAGES */
> -
> -struct page;
> -extern void clear_user_page(void *page, unsigned long vaddr, struct page
> *pg); -extern void copy_user_page(void *to, void *from, unsigned long
> vaddr, struct page *p); -
> -#ifdef STRICT_MM_TYPECHECKS
> -/*
> - * These are used to make use of C type-checking.
> - * Entries in the pte table are 64b, while entries in the pgd & pmd are
> 32b. - */
> -
> -/* PTE level */
> -typedef struct { unsigned long pte; } pte_t;
> -#define pte_val(x) ((x).pte)
> -#define __pte(x) ((pte_t) { (x) })
> -
> -/* 64k pages additionally define a bigger "real PTE" type that gathers
> - * the "second half" part of the PTE for pseudo 64k pages
> - */
> -#ifdef CONFIG_PPC_64K_PAGES
> -typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
> -#else
> -typedef struct { pte_t pte; } real_pte_t;
> -#endif
> -
> -/* PMD level */
> -typedef struct { unsigned long pmd; } pmd_t;
> -#define pmd_val(x) ((x).pmd)
> -#define __pmd(x) ((pmd_t) { (x) })
> -
> -/* PUD level exusts only on 4k pages */
> -#ifndef CONFIG_PPC_64K_PAGES
> -typedef struct { unsigned long pud; } pud_t;
> -#define pud_val(x) ((x).pud)
> -#define __pud(x) ((pud_t) { (x) })
> -#endif
> -
> -/* PGD level */
> -typedef struct { unsigned long pgd; } pgd_t;
> -#define pgd_val(x) ((x).pgd)
> -#define __pgd(x) ((pgd_t) { (x) })
> -
> -/* Page protection bits */
> -typedef struct { unsigned long pgprot; } pgprot_t;
> -#define pgprot_val(x) ((x).pgprot)
> -#define __pgprot(x) ((pgprot_t) { (x) })
> -
> -#else
> -
> -/*
> - * .. while these make it easier on the compiler
> - */
> -
> -typedef unsigned long pte_t;
> -#define pte_val(x) (x)
> -#define __pte(x) (x)
> -
> -#ifdef CONFIG_PPC_64K_PAGES
> -typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
> -#else
> -typedef unsigned long real_pte_t;
> -#endif
> -
> -
> -typedef unsigned long pmd_t;
> -#define pmd_val(x) (x)
> -#define __pmd(x) (x)
> -
> -#ifndef CONFIG_PPC_64K_PAGES
> -typedef unsigned long pud_t;
> -#define pud_val(x) (x)
> -#define __pud(x) (x)
> -#endif
> -
> -typedef unsigned long pgd_t;
> -#define pgd_val(x) (x)
> -#define pgprot_val(x) (x)
> -
> -typedef unsigned long pgprot_t;
> -#define __pgd(x) (x)
> -#define __pgprot(x) (x)
> -
> -#endif
> -
> -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
> -
> -extern int page_is_ram(unsigned long pfn);
> -
> -extern u64 ppc64_pft_size; /* Log 2 of page table size */
> -
> -/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
> -#define __HAVE_ARCH_GATE_AREA 1
> -
> -#endif /* __ASSEMBLY__ */
> -
> -#ifdef MODULE
> -#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
> -#else
> -#define __page_aligned \
> - __attribute__((__aligned__(PAGE_SIZE), \
> - __section__(".data.page_aligned")))
> -#endif
> -
> -
> -/* This must match the -Ttext linker address */
> -/* Note: tophys & tovirt make assumptions about how */
> -/* KERNELBASE is defined for performance reasons. */
> -/* When KERNELBASE moves, those macros may have */
> -/* to change! */
> -#define PAGE_OFFSET ASM_CONST(0xC000000000000000)
> -#define KERNELBASE PAGE_OFFSET
> -#define VMALLOCBASE ASM_CONST(0xD000000000000000)
> -
> -#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT)
> -#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT)
> -#define USER_REGION_ID (0UL)
> -#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
> -
> -#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
> -
> -#ifdef CONFIG_DISCONTIGMEM
> -#define page_to_pfn(page) discontigmem_page_to_pfn(page)
> -#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
> -#define pfn_valid(pfn) discontigmem_pfn_valid(pfn)
> -#endif
> -#ifdef CONFIG_FLATMEM
> -#define pfn_to_page(pfn) (mem_map + (pfn))
> -#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
> -#define pfn_valid(pfn) ((pfn) < max_mapnr)
> -#endif
> -
> -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
> -#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
> -
> -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> -
> -/*
> - * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
> - * and needs to be executable. This means the whole heap ends
> - * up being executable.
> - */
> -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
> - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> -
> -#define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
> - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> -
> -#define VM_DATA_DEFAULT_FLAGS \
> - (test_thread_flag(TIF_32BIT) ? \
> - VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
> -
> -/*
> - * This is the default if a program doesn't have a PT_GNU_STACK
> - * program header entry. The PPC64 ELF ABI has a non executable stack
> - * stack by default, so in the absense of a PT_GNU_STACK program header
> - * we turn execute permission off.
> - */
> -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
> - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> -
> -#define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
> - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> -
> -#define VM_STACK_DEFAULT_FLAGS \
> - (test_thread_flag(TIF_32BIT) ? \
> - VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
> -
> -#endif /* __KERNEL__ */
> -
> -#include <asm-generic/page.h>
> -
> -#endif /* _PPC64_PAGE_H */
> _______________________________________________
> Linuxppc64-dev mailing list
> Linuxppc64-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc64-dev
--
Michael Ellerman
IBM OzLabs
email: michael:ellerman.id.au
inmsg: mpe:jabber.org
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20051111/edbba2b9/attachment.pgp
More information about the Linuxppc64-dev
mailing list