1 /* $Id: r6000.c,v 1.6 1999/01/04 16:03:54 ralf Exp $
3 * r6000.c: MMU and cache routines for the R6000 processors.
5 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
7 #include <linux/init.h>
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
12 #include <asm/cacheops.h>
14 #include <asm/pgtable.h>
15 #include <asm/system.h>
16 #include <asm/sgialib.h>
17 #include <asm/mmu_context.h>
19 __asm__(".set mips3"); /* because we know... */
21 /* Cache operations. XXX Write these dave... */
22 static inline void r6000_flush_cache_all(void)
27 static void r6000_flush_cache_mm(struct mm_struct
*mm
)
32 static void r6000_flush_cache_range(struct mm_struct
*mm
,
39 static void r6000_flush_cache_page(struct vm_area_struct
*vma
,
45 static void r6000_flush_page_to_ram(unsigned long page
)
50 static void r6000_flush_cache_sigtramp(unsigned long page
)
55 /* TLB operations. XXX Write these dave... */
56 static inline void r6000_flush_tlb_all(void)
61 static void r6000_flush_tlb_mm(struct mm_struct
*mm
)
66 static void r6000_flush_tlb_range(struct mm_struct
*mm
, unsigned long start
,
72 static void r6000_flush_tlb_page(struct vm_area_struct
*vma
, unsigned long page
)
77 static void r6000_load_pgd(unsigned long pg_dir
)
81 static void r6000_pgd_init(unsigned long page
)
83 unsigned long dummy1
, dummy2
;
86 * This version is optimized for the R6000. We generate dirty lines
87 * in the datacache, overwrite these lines with zeros and then flush
88 * the cache. Sounds horribly complicated but is just a trick to
89 * avoid unnecessary loads of from memory and uncached stores which
90 * are very expensive. Not tested yet as the R6000 is a rare CPU only
91 * available in SGI machines and I don't have one.
101 "cache\t%5,16(%0)\n\t"
112 :"r" ((unsigned long) invalid_pte_table
),
114 "1" (USER_PTRS_PER_PGD
/8),
115 "i" (Create_Dirty_Excl_D
));
118 static void r6000_update_mmu_cache(struct vm_area_struct
* vma
,
119 unsigned long address
, pte_t pte
)
121 r6000_flush_tlb_page(vma
, address
);
123 * FIXME: We should also reload a new entry into the TLB to
124 * avoid unnecessary exceptions.
128 static void r6000_show_regs(struct pt_regs
* regs
)
131 * Saved main processor registers
133 printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
134 0, (unsigned long) regs
->regs
[1], (unsigned long) regs
->regs
[2],
135 (unsigned long) regs
->regs
[3], (unsigned long) regs
->regs
[4],
136 (unsigned long) regs
->regs
[5], (unsigned long) regs
->regs
[6],
137 (unsigned long) regs
->regs
[7]);
138 printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
139 (unsigned long) regs
->regs
[8], (unsigned long) regs
->regs
[9],
140 (unsigned long) regs
->regs
[10], (unsigned long) regs
->regs
[11],
141 (unsigned long) regs
->regs
[12], (unsigned long) regs
->regs
[13],
142 (unsigned long) regs
->regs
[14], (unsigned long) regs
->regs
[15]);
143 printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
144 (unsigned long) regs
->regs
[16], (unsigned long) regs
->regs
[17],
145 (unsigned long) regs
->regs
[18], (unsigned long) regs
->regs
[19],
146 (unsigned long) regs
->regs
[20], (unsigned long) regs
->regs
[21],
147 (unsigned long) regs
->regs
[22], (unsigned long) regs
->regs
[23]);
148 printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n",
149 (unsigned long) regs
->regs
[24], (unsigned long) regs
->regs
[25],
150 (unsigned long) regs
->regs
[28], (unsigned long) regs
->regs
[29],
151 (unsigned long) regs
->regs
[30], (unsigned long) regs
->regs
[31]);
154 * Saved cp0 registers
156 printk("epc : %08lx\nStatus: %08x\nCause : %08x\n",
157 (unsigned long) regs
->cp0_epc
, (unsigned int) regs
->cp0_status
,
158 (unsigned int) regs
->cp0_cause
);
161 static void r6000_add_wired_entry(unsigned long entrylo0
, unsigned long entrylo1
,
162 unsigned long entryhi
, unsigned long pagemask
)
167 static int r6000_user_mode(struct pt_regs
*regs
)
169 return !(regs
->cp0_status
& 0x4);
172 __initfunc(void ld_mmu_r6000(void))
174 flush_cache_all
= r6000_flush_cache_all
;
175 flush_cache_mm
= r6000_flush_cache_mm
;
176 flush_cache_range
= r6000_flush_cache_range
;
177 flush_cache_page
= r6000_flush_cache_page
;
178 flush_cache_sigtramp
= r6000_flush_cache_sigtramp
;
179 flush_page_to_ram
= r6000_flush_page_to_ram
;
181 flush_tlb_all
= r6000_flush_tlb_all
;
182 flush_tlb_mm
= r6000_flush_tlb_mm
;
183 flush_tlb_range
= r6000_flush_tlb_range
;
184 flush_tlb_page
= r6000_flush_tlb_page
;
187 load_pgd
= r6000_load_pgd
;
188 pgd_init
= r6000_pgd_init
;
189 update_mmu_cache
= r6000_update_mmu_cache
;
191 show_regs
= r6000_show_regs
;
193 add_wired_entry
= r6000_add_wired_entry
;
195 user_mode
= r6000_user_mode
;