aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-11-19 16:11:05 -0500
committerMatt Fleming <matt@console-pimps.org>2010-01-16 09:29:06 -0500
commit24ef7fc4dcc57afa0c33166c25bfe7676ffd4296 (patch)
treed6fc5129f2dbb0534521f5a5111e2bed3cd0f0a7 /arch/sh
parent8eda55142080f0373b1f0268fe6d6807f193e713 (diff)
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>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/page.h2
-rw-r--r--arch/sh/include/asm/pgtable_64.h15
-rw-r--r--arch/sh/include/asm/tlb.h41
-rw-r--r--arch/sh/mm/tlbflush_64.c2
4 files changed, 57 insertions, 3 deletions
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index a86c0f1d05d4..61e58105adc3 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -88,7 +88,7 @@ typedef struct { unsigned long pgd; } pgd_t;
88#define __pte(x) ((pte_t) { (x) } ) 88#define __pte(x) ((pte_t) { (x) } )
89#else 89#else
90typedef struct { unsigned long long pte_low; } pte_t; 90typedef struct { unsigned long long pte_low; } pte_t;
91typedef struct { unsigned long pgprot; } pgprot_t; 91typedef struct { unsigned long long pgprot; } pgprot_t;
92typedef struct { unsigned long pgd; } pgd_t; 92typedef struct { unsigned long pgd; } pgd_t;
93#define pte_val(x) ((x).pte_low) 93#define pte_val(x) ((x).pte_low)
94#define __pte(x) ((pte_t) { (x) } ) 94#define __pte(x) ((pte_t) { (x) } )
diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h
index dd381588c695..0ee46776dad6 100644
--- a/arch/sh/include/asm/pgtable_64.h
+++ b/arch/sh/include/asm/pgtable_64.h
@@ -123,8 +123,21 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
123#define _PAGE_DIRTY 0x400 /* software: page accessed in write */ 123#define _PAGE_DIRTY 0x400 /* software: page accessed in write */
124#define _PAGE_ACCESSED 0x800 /* software: page referenced */ 124#define _PAGE_ACCESSED 0x800 /* software: page referenced */
125 125
126/* Wrapper for extended mode pgprot twiddling */
127#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
128
129/*
130 * We can use the sign-extended bits in the PTEL to get 32 bits of
131 * software flags. This works for now because no implementations uses
132 * anything above the PPN field.
133 */
134#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */
135
136#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
137 _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
138
126/* Mask which drops software flags */ 139/* Mask which drops software flags */
127#define _PAGE_FLAGS_HARDWARE_MASK 0xfffffffffffff3dbLL 140#define _PAGE_FLAGS_HARDWARE_MASK (NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))
128 141
129/* 142/*
130 * HugeTLB support 143 * HugeTLB support
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index 3ed2f7a05416..dfc8fcd8ee50 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -11,6 +11,7 @@
11#ifdef CONFIG_MMU 11#ifdef CONFIG_MMU
12#include <asm/pgalloc.h> 12#include <asm/pgalloc.h>
13#include <asm/tlbflush.h> 13#include <asm/tlbflush.h>
14#include <asm/mmu_context.h>
14 15
15/* 16/*
16 * TLB handling. This allows us to remove pages from the page 17 * 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)
100#ifdef CONFIG_CPU_SH4 101#ifdef CONFIG_CPU_SH4
101extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t); 102extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
102extern void tlb_unwire_entry(void); 103extern void tlb_unwire_entry(void);
104#elif defined(CONFIG_SUPERH64)
105static int dtlb_entry;
106static unsigned long long dtlb_entries[64];
107
108static inline void tlb_wire_entry(struct vm_area_struct *vma,
109 unsigned long addr, pte_t pte)
110{
111 unsigned long long entry;
112 unsigned long paddr, flags;
113
114 BUG_ON(dtlb_entry == 64);
115
116 local_irq_save(flags);
117
118 entry = sh64_get_wired_dtlb_entry();
119 dtlb_entries[dtlb_entry++] = entry;
120
121 paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK;
122 paddr &= ~PAGE_MASK;
123
124 sh64_setup_tlb_slot(entry, addr, get_asid(), paddr);
125
126 local_irq_restore(flags);
127}
128
129static inline void tlb_unwire_entry(void)
130{
131 unsigned long long entry;
132 unsigned long flags;
133
134 BUG_ON(!dtlb_entry);
135
136 local_irq_save(flags);
137 entry = dtlb_entries[dtlb_entry--];
138
139 sh64_teardown_tlb_slot(entry);
140 sh64_put_wired_dtlb_entry(entry);
141
142 local_irq_restore(flags);
143}
103#else 144#else
104static inline void tlb_wire_entry(struct vm_area_struct *vma , 145static inline void tlb_wire_entry(struct vm_area_struct *vma ,
105 unsigned long addr, pte_t pte) 146 unsigned long addr, pte_t pte)
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index de0b0e881823..706da1d3a67a 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -36,7 +36,7 @@ extern void die(const char *,struct pt_regs *,long);
36 36
37static inline void print_prots(pgprot_t prot) 37static inline void print_prots(pgprot_t prot)
38{ 38{
39 printk("prot is 0x%08lx\n",pgprot_val(prot)); 39 printk("prot is 0x%016llx\n",pgprot_val(prot));
40 40
41 printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ), 41 printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ),
42 PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER)); 42 PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER));