aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
authorMikael Starvik <mikael.starvik@axis.com>2005-07-27 14:44:42 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-27 19:26:01 -0400
commit8d20a541b089ecb67a88a673548161b686ed7b85 (patch)
tree53bac804d538068c80684becb76cd76937956502 /arch/cris
parent21783c9746619a782c21be606f6498bbd4d4615e (diff)
[PATCH] CRIS update: SMP
Patches to support SMP. * Each CPU has its own current_pgd. * flush_tlb_range is implemented as flush_tlb_mm. * Atomic operations implemented with spinlocks. * Semaphores implemented with spinlocks. Signed-off-by: Mikael Starvik <starvik@axis.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v10/mm/fault.c26
-rw-r--r--arch/cris/arch-v10/mm/init.c2
-rw-r--r--arch/cris/arch-v10/mm/tlb.c49
3 files changed, 4 insertions, 73 deletions
diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c
index 6805cdb25a53..fe2615022b97 100644
--- a/arch/cris/arch-v10/mm/fault.c
+++ b/arch/cris/arch-v10/mm/fault.c
@@ -14,6 +14,7 @@
14#include <asm/uaccess.h> 14#include <asm/uaccess.h>
15#include <asm/pgtable.h> 15#include <asm/pgtable.h>
16#include <asm/arch/svinto.h> 16#include <asm/arch/svinto.h>
17#include <asm/mmu_context.h>
17 18
18/* debug of low-level TLB reload */ 19/* debug of low-level TLB reload */
19#undef DEBUG 20#undef DEBUG
@@ -24,8 +25,6 @@
24#define D(x) 25#define D(x)
25#endif 26#endif
26 27
27extern volatile pgd_t *current_pgd;
28
29extern const struct exception_table_entry 28extern const struct exception_table_entry
30 *search_exception_tables(unsigned long addr); 29 *search_exception_tables(unsigned long addr);
31 30
@@ -46,7 +45,7 @@ handle_mmu_bus_fault(struct pt_regs *regs)
46 int page_id; 45 int page_id;
47 int acc, inv; 46 int acc, inv;
48#endif 47#endif
49 pgd_t* pgd = (pgd_t*)current_pgd; 48 pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id());
50 pmd_t *pmd; 49 pmd_t *pmd;
51 pte_t pte; 50 pte_t pte;
52 int miss, we, writeac; 51 int miss, we, writeac;
@@ -94,24 +93,3 @@ handle_mmu_bus_fault(struct pt_regs *regs)
94 *R_TLB_LO = pte_val(pte); 93 *R_TLB_LO = pte_val(pte);
95 local_irq_restore(flags); 94 local_irq_restore(flags);
96} 95}
97
98/* Called from arch/cris/mm/fault.c to find fixup code. */
99int
100find_fixup_code(struct pt_regs *regs)
101{
102 const struct exception_table_entry *fixup;
103
104 if ((fixup = search_exception_tables(regs->irp)) != 0) {
105 /* Adjust the instruction pointer in the stackframe. */
106 regs->irp = fixup->fixup;
107
108 /*
109 * Don't return by restoring the CPU state, so switch
110 * frame-type.
111 */
112 regs->frametype = CRIS_FRAME_NORMAL;
113 return 1;
114 }
115
116 return 0;
117}
diff --git a/arch/cris/arch-v10/mm/init.c b/arch/cris/arch-v10/mm/init.c
index a9f975a9cfb5..ff3481e76dd4 100644
--- a/arch/cris/arch-v10/mm/init.c
+++ b/arch/cris/arch-v10/mm/init.c
@@ -42,7 +42,7 @@ paging_init(void)
42 * switch_mm) 42 * switch_mm)
43 */ 43 */
44 44
45 current_pgd = init_mm.pgd; 45 per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
46 46
47 /* initialise the TLB (tlb.c) */ 47 /* initialise the TLB (tlb.c) */
48 48
diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c
index 9d06125ff5a2..70a5523eff78 100644
--- a/arch/cris/arch-v10/mm/tlb.c
+++ b/arch/cris/arch-v10/mm/tlb.c
@@ -139,53 +139,6 @@ flush_tlb_page(struct vm_area_struct *vma,
139 local_irq_restore(flags); 139 local_irq_restore(flags);
140} 140}
141 141
142/* invalidate a page range */
143
144void
145flush_tlb_range(struct vm_area_struct *vma,
146 unsigned long start,
147 unsigned long end)
148{
149 struct mm_struct *mm = vma->vm_mm;
150 int page_id = mm->context.page_id;
151 int i;
152 unsigned long flags;
153
154 D(printk("tlb: flush range %p<->%p in context %d (%p)\n",
155 start, end, page_id, mm));
156
157 if(page_id == NO_CONTEXT)
158 return;
159
160 start &= PAGE_MASK; /* probably not necessary */
161 end &= PAGE_MASK; /* dito */
162
163 /* invalidate those TLB entries that match both the mm context
164 * and the virtual address range
165 */
166
167 local_save_flags(flags);
168 local_irq_disable();
169 for(i = 0; i < NUM_TLB_ENTRIES; i++) {
170 unsigned long tlb_hi, vpn;
171 *R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
172 tlb_hi = *R_TLB_HI;
173 vpn = tlb_hi & PAGE_MASK;
174 if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
175 vpn >= start && vpn < end) {
176 *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
177 IO_FIELD(R_TLB_HI, vpn, i & 0xf ) );
178
179 *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) |
180 IO_STATE(R_TLB_LO, valid, no ) |
181 IO_STATE(R_TLB_LO, kernel,no ) |
182 IO_STATE(R_TLB_LO, we, no ) |
183 IO_FIELD(R_TLB_LO, pfn, 0 ) );
184 }
185 }
186 local_irq_restore(flags);
187}
188
189/* dump the entire TLB for debug purposes */ 142/* dump the entire TLB for debug purposes */
190 143
191#if 0 144#if 0
@@ -237,7 +190,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
237 * the pgd. 190 * the pgd.
238 */ 191 */
239 192
240 current_pgd = next->pgd; 193 per_cpu(current_pgd, smp_processor_id()) = next->pgd;
241 194
242 /* switch context in the MMU */ 195 /* switch context in the MMU */
243 196