forked from Minki/linux
sh: Acquire some more page flags for SH-5.
We need some more page flags to hook up _PAGE_WIRED (and eventually other things). So use the unused PTE bits above the PPN field as no implementations use these for anything currently. Now that we have _PAGE_WIRED let's provide the SH-5 functions for wiring up TLB entries. Signed-off-by: Matt Fleming <matt@console-pimps.org>
This commit is contained in:
parent
8eda551420
commit
24ef7fc4dc
@ -88,7 +88,7 @@ typedef struct { unsigned long pgd; } pgd_t;
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#else
|
||||
typedef struct { unsigned long long pte_low; } pte_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
typedef struct { unsigned long long pgprot; } pgprot_t;
|
||||
typedef struct { unsigned long pgd; } pgd_t;
|
||||
#define pte_val(x) ((x).pte_low)
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
|
@ -123,8 +123,21 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
|
||||
#define _PAGE_DIRTY 0x400 /* software: page accessed in write */
|
||||
#define _PAGE_ACCESSED 0x800 /* software: page referenced */
|
||||
|
||||
/* Wrapper for extended mode pgprot twiddling */
|
||||
#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
|
||||
|
||||
/*
|
||||
* We can use the sign-extended bits in the PTEL to get 32 bits of
|
||||
* software flags. This works for now because no implementations uses
|
||||
* anything above the PPN field.
|
||||
*/
|
||||
#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */
|
||||
|
||||
#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
|
||||
_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
|
||||
|
||||
/* Mask which drops software flags */
|
||||
#define _PAGE_FLAGS_HARDWARE_MASK 0xfffffffffffff3dbLL
|
||||
#define _PAGE_FLAGS_HARDWARE_MASK (NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))
|
||||
|
||||
/*
|
||||
* HugeTLB support
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifdef CONFIG_MMU
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
/*
|
||||
* TLB handling. This allows us to remove pages from the page
|
||||
@ -100,6 +101,46 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
|
||||
#ifdef CONFIG_CPU_SH4
|
||||
extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
|
||||
extern void tlb_unwire_entry(void);
|
||||
#elif defined(CONFIG_SUPERH64)
|
||||
static int dtlb_entry;
|
||||
static unsigned long long dtlb_entries[64];
|
||||
|
||||
static inline void tlb_wire_entry(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t pte)
|
||||
{
|
||||
unsigned long long entry;
|
||||
unsigned long paddr, flags;
|
||||
|
||||
BUG_ON(dtlb_entry == 64);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
entry = sh64_get_wired_dtlb_entry();
|
||||
dtlb_entries[dtlb_entry++] = entry;
|
||||
|
||||
paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK;
|
||||
paddr &= ~PAGE_MASK;
|
||||
|
||||
sh64_setup_tlb_slot(entry, addr, get_asid(), paddr);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static inline void tlb_unwire_entry(void)
|
||||
{
|
||||
unsigned long long entry;
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!dtlb_entry);
|
||||
|
||||
local_irq_save(flags);
|
||||
entry = dtlb_entries[dtlb_entry--];
|
||||
|
||||
sh64_teardown_tlb_slot(entry);
|
||||
sh64_put_wired_dtlb_entry(entry);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#else
|
||||
static inline void tlb_wire_entry(struct vm_area_struct *vma ,
|
||||
unsigned long addr, pte_t pte)
|
||||
|
@ -36,7 +36,7 @@ extern void die(const char *,struct pt_regs *,long);
|
||||
|
||||
static inline void print_prots(pgprot_t prot)
|
||||
{
|
||||
printk("prot is 0x%08lx\n",pgprot_val(prot));
|
||||
printk("prot is 0x%016llx\n",pgprot_val(prot));
|
||||
|
||||
printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ),
|
||||
PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER));
|
||||
|
Loading…
Reference in New Issue
Block a user