Commit 6f86dc11 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

[PATCH] convert i386 to generic nopmd header

Adapt the i386 architecture to use the generic 2-level folding header.
Just to show how it is done.
Signed-off-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1792057c
...@@ -116,7 +116,6 @@ static inline struct pglist_data *pfn_to_pgdat(unsigned long pfn) ...@@ -116,7 +116,6 @@ static inline struct pglist_data *pfn_to_pgdat(unsigned long pfn)
(unsigned long)(__page - __zone->zone_mem_map) \ (unsigned long)(__page - __zone->zone_mem_map) \
+ __zone->zone_start_pfn; \ + __zone->zone_start_pfn; \
}) })
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
#ifdef CONFIG_X86_NUMAQ /* we have contiguous memory on NUMA-Q */ #ifdef CONFIG_X86_NUMAQ /* we have contiguous memory on NUMA-Q */
#define pfn_valid(pfn) ((pfn) < num_physpages) #define pfn_valid(pfn) ((pfn) < num_physpages)
......
...@@ -46,11 +46,12 @@ typedef struct { unsigned long pte_low, pte_high; } pte_t; ...@@ -46,11 +46,12 @@ typedef struct { unsigned long pte_low, pte_high; } pte_t;
typedef struct { unsigned long long pmd; } pmd_t; typedef struct { unsigned long long pmd; } pmd_t;
typedef struct { unsigned long long pgd; } pgd_t; typedef struct { unsigned long long pgd; } pgd_t;
typedef struct { unsigned long long pgprot; } pgprot_t; typedef struct { unsigned long long pgprot; } pgprot_t;
#define pmd_val(x) ((x).pmd)
#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
#define __pmd(x) ((pmd_t) { (x) } )
#define HPAGE_SHIFT 21 #define HPAGE_SHIFT 21
#else #else
typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t; typedef struct { unsigned long pgprot; } pgprot_t;
#define boot_pte_t pte_t /* or would you rather have a typedef */ #define boot_pte_t pte_t /* or would you rather have a typedef */
...@@ -66,13 +67,10 @@ typedef struct { unsigned long pgprot; } pgprot_t; ...@@ -66,13 +67,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#endif #endif
#define pmd_val(x) ((x).pmd)
#define pgd_val(x) ((x).pgd) #define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot) #define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } ) #define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } )
......
...@@ -10,12 +10,10 @@ ...@@ -10,12 +10,10 @@
#define pmd_populate_kernel(mm, pmd, pte) \ #define pmd_populate_kernel(mm, pmd, pte) \
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) #define pmd_populate(mm, pmd, pte) \
{ set_pmd(pmd, __pmd(_PAGE_TABLE + \
set_pmd(pmd, __pmd(_PAGE_TABLE + ((unsigned long long)page_to_pfn(pte) << \
((unsigned long long)page_to_pfn(pte) << (unsigned long long) PAGE_SHIFT)))
(unsigned long long) PAGE_SHIFT)));
}
/* /*
* Allocate and free page tables. * Allocate and free page tables.
*/ */
...@@ -39,16 +37,15 @@ static inline void pte_free(struct page *pte) ...@@ -39,16 +37,15 @@ static inline void pte_free(struct page *pte)
#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
#ifdef CONFIG_X86_PAE
/* /*
* allocating and freeing a pmd is trivial: the 1-entry pmd is * In the PAE case we free the pmds as part of the pgd.
* inside the pgd, so has no extra memory associated with it.
* (In the PAE case we free the pmds as part of the pgd.)
*/ */
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free(x) do { } while (0) #define pmd_free(x) do { } while (0)
#define __pmd_free_tlb(tlb,x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0)
#define pgd_populate(mm, pmd, pte) BUG() #define pgd_populate(mm, pmd, pte) BUG()
#endif
#define check_pgt_cache() do { } while (0) #define check_pgt_cache() do { } while (0)
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
* the i386 is two-level, so we don't really have any * the i386 is two-level, so we don't really have any
* PMD directory physically. * PMD directory physically.
*/ */
#define PMD_SHIFT 22
#define PTRS_PER_PMD 1
#define PTRS_PER_PTE 1024 #define PTRS_PER_PTE 1024
......
#ifndef _I386_PGTABLE_2LEVEL_H #ifndef _I386_PGTABLE_2LEVEL_H
#define _I386_PGTABLE_2LEVEL_H #define _I386_PGTABLE_2LEVEL_H
#include <asm-generic/pgtable-nopmd.h>
#define pte_ERROR(e) \ #define pte_ERROR(e) \
printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
#define pgd_ERROR(e) \ #define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
/*
* The "pgd_xxx()" functions here are trivial for a folded two-level
* setup: the pgd is never bad, and a pmd always exists (as it's folded
* into the pgd entry)
*/
static inline int pgd_none(pgd_t pgd) { return 0; }
static inline int pgd_bad(pgd_t pgd) { return 0; }
static inline int pgd_present(pgd_t pgd) { return 1; }
#define pgd_clear(xp) do { } while (0)
/* /*
* Certain architectures need to do special things when PTEs * Certain architectures need to do special things when PTEs
* within a page table are directly modified. Thus, the following * within a page table are directly modified. Thus, the following
...@@ -25,20 +15,8 @@ static inline int pgd_present(pgd_t pgd) { return 1; } ...@@ -25,20 +15,8 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
*/ */
#define set_pte(pteptr, pteval) (*(pteptr) = pteval) #define set_pte(pteptr, pteval) (*(pteptr) = pteval)
#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
/* #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
* (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)
#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
#define pgd_page(pgd) \
((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) dir;
}
#define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0)) #define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0))
#define pte_same(a, b) ((a).pte_low == (b).pte_low) #define pte_same(a, b) ((a).pte_low == (b).pte_low)
#define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_page(x) pfn_to_page(pte_pfn(x))
...@@ -47,6 +25,11 @@ static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) ...@@ -47,6 +25,11 @@ static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
#define pmd_page_kernel(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
/* /*
* All present user pages are user-executable: * All present user pages are user-executable:
*/ */
......
...@@ -70,9 +70,18 @@ static inline void set_pte(pte_t *ptep, pte_t pte) ...@@ -70,9 +70,18 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
*/ */
static inline void pgd_clear (pgd_t * pgd) { } static inline void pgd_clear (pgd_t * pgd) { }
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
#define pmd_page_kernel(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
#define pgd_page(pgd) \ #define pgd_page(pgd) \
((struct page *) __va(pgd_val(pgd) & PAGE_MASK))
#define pgd_page_kernel(pgd) \
((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
/* Find an entry in the second-level page table.. */ /* Find an entry in the second-level page table.. */
#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \ #define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
pmd_index(address)) pmd_index(address))
...@@ -142,4 +151,6 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) ...@@ -142,4 +151,6 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
#define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) #define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high })
#define __swp_entry_to_pte(x) ((pte_t){ 0, (x).val }) #define __swp_entry_to_pte(x) ((pte_t){ 0, (x).val })
#define __pmd_free_tlb(tlb, x) do { } while (0)
#endif /* _I386_PGTABLE_3LEVEL_H */ #endif /* _I386_PGTABLE_3LEVEL_H */
...@@ -50,12 +50,12 @@ void paging_init(void); ...@@ -50,12 +50,12 @@ void paging_init(void);
*/ */
#ifdef CONFIG_X86_PAE #ifdef CONFIG_X86_PAE
# include <asm/pgtable-3level-defs.h> # include <asm/pgtable-3level-defs.h>
# define PMD_SIZE (1UL << PMD_SHIFT)
# define PMD_MASK (~(PMD_SIZE-1))
#else #else
# include <asm/pgtable-2level-defs.h> # include <asm/pgtable-2level-defs.h>
#endif #endif
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1)) #define PGDIR_MASK (~(PGDIR_SIZE-1))
...@@ -293,15 +293,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ...@@ -293,15 +293,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define page_pte(page) page_pte_prot(page, __pgprot(0)) #define page_pte(page) page_pte_prot(page, __pgprot(0))
#define pmd_page_kernel(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
#ifndef CONFIG_DISCONTIGMEM
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
#endif /* !CONFIG_DISCONTIGMEM */
#define pmd_large(pmd) \ #define pmd_large(pmd) \
((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
/* /*
* the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment