aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 13:39:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 13:39:06 -0400
commitf737c7705ff0df2f1d66e14ec30a1a5f285ddb39 (patch)
treedc955f0d51f6c9d3b4aa8595074bec03ee4f8da5
parent13199a0845729492fc51d1ba87938cdfe341b141 (diff)
parente49e6ff553ffee2e747a8e331a9dcf3a80555944 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull Sparc updates from David S. Miller: 1) Remove the idiotic situation wherein Leon was a special case in all of the TLB/cache handling code. The worst side effect of this bogosity is that you couldn't build a kernel with Leon support enabled (to get better build coverage), and test boot it on a non-LEON cpu. Leon is, in all core respects, programatically identical to the 32-bit SRMMU. Except that they put the TLB registers in a different alternate address space location. Through code patching (for fast paths) and run time checks, this issue is now a thing of the past. From Sam Ravnborg. 2) There was a mis-merge of arch/sparc/Kconfig for one of the clockevents changes that went in, causing 32-bit sparc to start failing to build. I merged in your tree to get those clockevents changes (and added a note to the merge commit) then added Stephen Rothwell's fix for the merge error. 3) Software quad floating point emulation was not working properly on more recent Niagara chips, because the way the situation is reported by the cpu has changed. Nobody noticed because gcc emits calls to software emulation routines in glibc. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: (25 commits) sparc: fix sparc64 build due to leon.h inclusion sparc32: remove unused variable in head_32.S sparc32,leon: fix leon bootup sparc32: Export leon_dma_ops to modules. sparc32: support leon + sun in dma_make_coherent() sparc32,leon: always support leon in ioport sparc32,leon: always include leon_pmc in build sparc32: refactor cpu_idle() sparc32: srmmu_probe now knows about leon too sparc32: drop LEON hack for ASI_M_MMUREGS sparc32: introduce run-time patching of srmmu access functions sparc32: introduce support for run-time patching for all shared assembler code sparc32,leon: fix section mismatch warning sparc32,leon: always include leon_smp + leon_mm in build sparc32,leon: always include leon_kernel in build sparc32,leon: clean up leon.h sparc32: handle leon in cpu.c sparc32: handle leon in irq_32.c sparc32: add support for run-time patching of leon/sun single instructions sparc32: introduce sparc32_start_kernel called from head_32.S ...
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/include/asm/asi.h4
-rw-r--r--arch/sparc/include/asm/asmmacro.h22
-rw-r--r--arch/sparc/include/asm/dma-mapping.h9
-rw-r--r--arch/sparc/include/asm/leon.h82
-rw-r--r--arch/sparc/include/asm/leon_amba.h4
-rw-r--r--arch/sparc/include/asm/pgtsrmmu.h86
-rw-r--r--arch/sparc/include/asm/psr.h8
-rw-r--r--arch/sparc/include/asm/sections.h3
-rw-r--r--arch/sparc/kernel/Makefile4
-rw-r--r--arch/sparc/kernel/cpu.c18
-rw-r--r--arch/sparc/kernel/entry.S10
-rw-r--r--arch/sparc/kernel/etrap_32.S18
-rw-r--r--arch/sparc/kernel/head_32.S168
-rw-r--r--arch/sparc/kernel/ioport.c24
-rw-r--r--arch/sparc/kernel/irq_32.c22
-rw-r--r--arch/sparc/kernel/kernel.h3
-rw-r--r--arch/sparc/kernel/leon_kernel.c1
-rw-r--r--arch/sparc/kernel/leon_pmc.c15
-rw-r--r--arch/sparc/kernel/leon_smp.c8
-rw-r--r--arch/sparc/kernel/process_32.c35
-rw-r--r--arch/sparc/kernel/prom_common.c1
-rw-r--r--arch/sparc/kernel/rtrap_32.S18
-rw-r--r--arch/sparc/kernel/setup_32.c62
-rw-r--r--arch/sparc/kernel/trampoline_32.S6
-rw-r--r--arch/sparc/kernel/traps_64.c12
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S5
-rw-r--r--arch/sparc/kernel/wof.S18
-rw-r--r--arch/sparc/kernel/wuf.S27
-rw-r--r--arch/sparc/math-emu/math_64.c20
-rw-r--r--arch/sparc/mm/Makefile3
-rw-r--r--arch/sparc/mm/leon_mm.c2
-rw-r--r--arch/sparc/mm/srmmu.c25
-rw-r--r--arch/sparc/mm/srmmu_access.S82
34 files changed, 444 insertions, 382 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 83bd051754e1..e74ff1377626 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -41,7 +41,6 @@ config SPARC32
41 def_bool !64BIT 41 def_bool !64BIT
42 select GENERIC_ATOMIC64 42 select GENERIC_ATOMIC64
43 select CLZ_TAB 43 select CLZ_TAB
44 select ARCH_USES_GETTIMEOFFSET
45 44
46config SPARC64 45config SPARC64
47 def_bool 64BIT 46 def_bool 64BIT
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h
index cbb93e5141de..61ebe7411ceb 100644
--- a/arch/sparc/include/asm/asi.h
+++ b/arch/sparc/include/asm/asi.h
@@ -40,11 +40,7 @@
40#define ASI_M_UNA01 0x01 /* Same here... */ 40#define ASI_M_UNA01 0x01 /* Same here... */
41#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ 41#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */
42#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ 42#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */
43#ifndef CONFIG_SPARC_LEON
44#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ 43#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */
45#else
46#define ASI_M_MMUREGS 0x19
47#endif /* CONFIG_SPARC_LEON */
48#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ 44#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */
49#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ 45#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */
50#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ 46#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */
diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h
index 02a172fb193a..a0e28ef02558 100644
--- a/arch/sparc/include/asm/asmmacro.h
+++ b/arch/sparc/include/asm/asmmacro.h
@@ -20,4 +20,26 @@
20/* All traps low-level code here must end with this macro. */ 20/* All traps low-level code here must end with this macro. */
21#define RESTORE_ALL b ret_trap_entry; clr %l6; 21#define RESTORE_ALL b ret_trap_entry; clr %l6;
22 22
23/* Support for run-time patching of single instructions.
24 * This is used to handle the differences in the ASI for
25 * MMUREGS for LEON and SUN.
26 *
27 * Sample:
28 * LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0
29 * SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0
30 * PI == Patch Instruction
31 *
32 * For LEON we will use the first variant,
33 * and for all other we will use the SUN variant.
34 * The order is important.
35 */
36#define LEON_PI(...) \
37662: __VA_ARGS__
38
39#define SUN_PI_(...) \
40 .section .leon_1insn_patch, "ax"; \
41 .word 662b; \
42 __VA_ARGS__; \
43 .previous
44
23#endif /* !(_SPARC_ASMMACRO_H) */ 45#endif /* !(_SPARC_ASMMACRO_H) */
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 48a7c65731d2..8493fd3c7ba5 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -12,13 +12,18 @@ extern int dma_supported(struct device *dev, u64 mask);
12#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) 12#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
13#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 13#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
14 14
15extern struct dma_map_ops *dma_ops, pci32_dma_ops; 15extern struct dma_map_ops *dma_ops;
16extern struct dma_map_ops *leon_dma_ops;
17extern struct dma_map_ops pci32_dma_ops;
18
16extern struct bus_type pci_bus_type; 19extern struct bus_type pci_bus_type;
17 20
18static inline struct dma_map_ops *get_dma_ops(struct device *dev) 21static inline struct dma_map_ops *get_dma_ops(struct device *dev)
19{ 22{
20#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI) 23#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
21 if (dev->bus == &pci_bus_type) 24 if (sparc_cpu_model == sparc_leon)
25 return leon_dma_ops;
26 else if (dev->bus == &pci_bus_type)
22 return &pci32_dma_ops; 27 return &pci32_dma_ops;
23#endif 28#endif
24 return dma_ops; 29 return dma_ops;
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index 07659124c140..3375c6293893 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -8,8 +8,6 @@
8#ifndef LEON_H_INCLUDE 8#ifndef LEON_H_INCLUDE
9#define LEON_H_INCLUDE 9#define LEON_H_INCLUDE
10 10
11#ifdef CONFIG_SPARC_LEON
12
13/* mmu register access, ASI_LEON_MMUREGS */ 11/* mmu register access, ASI_LEON_MMUREGS */
14#define LEON_CNR_CTRL 0x000 12#define LEON_CNR_CTRL 0x000
15#define LEON_CNR_CTXP 0x100 13#define LEON_CNR_CTXP 0x100
@@ -62,15 +60,6 @@
62 60
63#ifndef __ASSEMBLY__ 61#ifndef __ASSEMBLY__
64 62
65/* do a virtual address read without cache */
66static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
67{
68 unsigned long retval;
69 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
70 "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
71 return retval;
72}
73
74/* do a physical address bypass write, i.e. for 0x80000000 */ 63/* do a physical address bypass write, i.e. for 0x80000000 */
75static inline void leon_store_reg(unsigned long paddr, unsigned long value) 64static inline void leon_store_reg(unsigned long paddr, unsigned long value)
76{ 65{
@@ -87,47 +76,16 @@ static inline unsigned long leon_load_reg(unsigned long paddr)
87 return retval; 76 return retval;
88} 77}
89 78
90static inline void leon_srmmu_disabletlb(void)
91{
92 unsigned int retval;
93 __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
94 "i"(ASI_LEON_MMUREGS));
95 retval |= LEON_CNR_CTRL_TLBDIS;
96 __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
97 "i"(ASI_LEON_MMUREGS) : "memory");
98}
99
100static inline void leon_srmmu_enabletlb(void)
101{
102 unsigned int retval;
103 __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
104 "i"(ASI_LEON_MMUREGS));
105 retval = retval & ~LEON_CNR_CTRL_TLBDIS;
106 __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
107 "i"(ASI_LEON_MMUREGS) : "memory");
108}
109
110/* macro access for leon_load_reg() and leon_store_reg() */ 79/* macro access for leon_load_reg() and leon_store_reg() */
111#define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x))) 80#define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x)))
112#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v))) 81#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
113#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
114#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
115#define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x)) 82#define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x))
116#define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v)) 83#define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v))
117#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS)
118#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
119#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
120#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))
121
122/* macro access for leon_readnobuffer_reg() */
123#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
124 84
125extern void leon_init(void); 85extern void leon_init(void);
126extern void leon_switch_mm(void); 86extern void leon_switch_mm(void);
127extern void leon_init_IRQ(void); 87extern void leon_init_IRQ(void);
128 88
129extern unsigned long last_valid_pfn;
130
131static inline unsigned long sparc_leon3_get_dcachecfg(void) 89static inline unsigned long sparc_leon3_get_dcachecfg(void)
132{ 90{
133 unsigned int retval; 91 unsigned int retval;
@@ -230,9 +188,6 @@ static inline int sparc_leon3_cpuid(void)
230#error cannot determine LEON_PAGE_SIZE_LEON 188#error cannot determine LEON_PAGE_SIZE_LEON
231#endif 189#endif
232 190
233#define PAGE_MIN_SHIFT (12)
234#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT)
235
236#define LEON3_XCCR_SETS_MASK 0x07000000UL 191#define LEON3_XCCR_SETS_MASK 0x07000000UL
237#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL 192#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL
238 193
@@ -242,7 +197,7 @@ static inline int sparc_leon3_cpuid(void)
242#ifndef __ASSEMBLY__ 197#ifndef __ASSEMBLY__
243struct vm_area_struct; 198struct vm_area_struct;
244 199
245extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); 200extern unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr);
246extern void leon_flush_icache_all(void); 201extern void leon_flush_icache_all(void);
247extern void leon_flush_dcache_all(void); 202extern void leon_flush_dcache_all(void);
248extern void leon_flush_cache_all(void); 203extern void leon_flush_cache_all(void);
@@ -258,15 +213,7 @@ struct leon3_cacheregs {
258 unsigned long dccr; /* 0x0c - Data Cache Configuration Register */ 213 unsigned long dccr; /* 0x0c - Data Cache Configuration Register */
259}; 214};
260 215
261/* struct that hold LEON2 cache configuration register 216#include <linux/irq.h>
262 * & configuration register
263 */
264struct leon2_cacheregs {
265 unsigned long ccr, cfg;
266};
267
268#ifdef __KERNEL__
269
270#include <linux/interrupt.h> 217#include <linux/interrupt.h>
271 218
272struct device_node; 219struct device_node;
@@ -292,24 +239,15 @@ extern void leon_smp_done(void);
292extern void leon_boot_cpus(void); 239extern void leon_boot_cpus(void);
293extern int leon_boot_one_cpu(int i, struct task_struct *); 240extern int leon_boot_one_cpu(int i, struct task_struct *);
294void leon_init_smp(void); 241void leon_init_smp(void);
295extern void cpu_idle(void);
296extern void init_IRQ(void);
297extern void cpu_panic(void);
298extern int __leon_processor_id(void);
299void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu); 242void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
300extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused); 243extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
301 244
302extern unsigned int real_irq_entry[];
303extern unsigned int smpleon_ipi[]; 245extern unsigned int smpleon_ipi[];
304extern unsigned int patchme_maybe_smp_msg[]; 246extern unsigned int linux_trap_ipi15_leon[];
305extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
306extern unsigned int linux_trap_ipi15_sun4m[];
307extern int leon_ipi_irq; 247extern int leon_ipi_irq;
308 248
309#endif /* CONFIG_SMP */ 249#endif /* CONFIG_SMP */
310 250
311#endif /* __KERNEL__ */
312
313#endif /* __ASSEMBLY__ */ 251#endif /* __ASSEMBLY__ */
314 252
315/* macros used in leon_mm.c */ 253/* macros used in leon_mm.c */
@@ -317,18 +255,4 @@ extern int leon_ipi_irq;
317#define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base))) 255#define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
318#define _SRMMU_PTE_PMASK_LEON 0xffffffff 256#define _SRMMU_PTE_PMASK_LEON 0xffffffff
319 257
320#else /* defined(CONFIG_SPARC_LEON) */
321
322/* nop definitions for !LEON case */
323#define leon_init() do {} while (0)
324#define leon_switch_mm() do {} while (0)
325#define leon_init_IRQ() do {} while (0)
326#define init_leon() do {} while (0)
327#define leon_smp_done() do {} while (0)
328#define leon_boot_cpus() do {} while (0)
329#define leon_boot_one_cpu(i, t) 1
330#define leon_init_smp() do {} while (0)
331
332#endif /* !defined(CONFIG_SPARC_LEON) */
333
334#endif 258#endif
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h
index e50f326e71bd..f3034eddf468 100644
--- a/arch/sparc/include/asm/leon_amba.h
+++ b/arch/sparc/include/asm/leon_amba.h
@@ -87,8 +87,6 @@ struct amba_prom_registers {
87#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7) 87#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7)
88#define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0) 88#define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0)
89 89
90#ifdef CONFIG_SPARC_LEON
91
92#ifndef __ASSEMBLY__ 90#ifndef __ASSEMBLY__
93 91
94struct leon3_irqctrl_regs_map { 92struct leon3_irqctrl_regs_map {
@@ -264,6 +262,4 @@ extern unsigned int sparc_leon_eirq;
264 262
265#define amba_device(x) (((x) >> 12) & 0xfff) 263#define amba_device(x) (((x) >> 12) & 0xfff)
266 264
267#endif /* !defined(CONFIG_SPARC_LEON) */
268
269#endif 265#endif
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h
index cb828703a63a..79da17866fa8 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -139,6 +139,7 @@
139 restore %g0, %g0, %g0; 139 restore %g0, %g0, %g0;
140 140
141#ifndef __ASSEMBLY__ 141#ifndef __ASSEMBLY__
142extern unsigned long last_valid_pfn;
142 143
143/* This makes sense. Honest it does - Anton */ 144/* This makes sense. Honest it does - Anton */
144/* XXX Yes but it's ugly as sin. FIXME. -KMW */ 145/* XXX Yes but it's ugly as sin. FIXME. -KMW */
@@ -148,67 +149,13 @@ extern void *srmmu_nocache_pool;
148#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR)) 149#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
149 150
150/* Accessing the MMU control register. */ 151/* Accessing the MMU control register. */
151static inline unsigned int srmmu_get_mmureg(void) 152unsigned int srmmu_get_mmureg(void);
152{ 153void srmmu_set_mmureg(unsigned long regval);
153 unsigned int retval; 154void srmmu_set_ctable_ptr(unsigned long paddr);
154 __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : 155void srmmu_set_context(int context);
155 "=r" (retval) : 156int srmmu_get_context(void);
156 "i" (ASI_M_MMUREGS)); 157unsigned int srmmu_get_fstatus(void);
157 return retval; 158unsigned int srmmu_get_faddr(void);
158}
159
160static inline void srmmu_set_mmureg(unsigned long regval)
161{
162 __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
163 "r" (regval), "i" (ASI_M_MMUREGS) : "memory");
164
165}
166
167static inline void srmmu_set_ctable_ptr(unsigned long paddr)
168{
169 paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
170 __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
171 "r" (paddr), "r" (SRMMU_CTXTBL_PTR),
172 "i" (ASI_M_MMUREGS) :
173 "memory");
174}
175
176static inline void srmmu_set_context(int context)
177{
178 __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
179 "r" (context), "r" (SRMMU_CTX_REG),
180 "i" (ASI_M_MMUREGS) : "memory");
181}
182
183static inline int srmmu_get_context(void)
184{
185 register int retval;
186 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
187 "=r" (retval) :
188 "r" (SRMMU_CTX_REG),
189 "i" (ASI_M_MMUREGS));
190 return retval;
191}
192
193static inline unsigned int srmmu_get_fstatus(void)
194{
195 unsigned int retval;
196
197 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
198 "=r" (retval) :
199 "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS));
200 return retval;
201}
202
203static inline unsigned int srmmu_get_faddr(void)
204{
205 unsigned int retval;
206
207 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
208 "=r" (retval) :
209 "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS));
210 return retval;
211}
212 159
213/* This is guaranteed on all SRMMU's. */ 160/* This is guaranteed on all SRMMU's. */
214static inline void srmmu_flush_whole_tlb(void) 161static inline void srmmu_flush_whole_tlb(void)
@@ -219,23 +166,6 @@ static inline void srmmu_flush_whole_tlb(void)
219 166
220} 167}
221 168
222/* These flush types are not available on all chips... */
223#ifndef CONFIG_SPARC_LEON
224static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
225{
226 unsigned long retval;
227
228 vaddr &= PAGE_MASK;
229 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
230 "=r" (retval) :
231 "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
232
233 return retval;
234}
235#else
236#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0)
237#endif
238
239static inline int 169static inline int
240srmmu_get_pte (unsigned long addr) 170srmmu_get_pte (unsigned long addr)
241{ 171{
diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h
index b8c0e5f0a66b..cee7ed9c927d 100644
--- a/arch/sparc/include/asm/psr.h
+++ b/arch/sparc/include/asm/psr.h
@@ -35,6 +35,14 @@
35#define PSR_VERS 0x0f000000 /* cpu-version field */ 35#define PSR_VERS 0x0f000000 /* cpu-version field */
36#define PSR_IMPL 0xf0000000 /* cpu-implementation field */ 36#define PSR_IMPL 0xf0000000 /* cpu-implementation field */
37 37
38#define PSR_VERS_SHIFT 24
39#define PSR_IMPL_SHIFT 28
40#define PSR_VERS_SHIFTED_MASK 0xf
41#define PSR_IMPL_SHIFTED_MASK 0xf
42
43#define PSR_IMPL_TI 0x4
44#define PSR_IMPL_LEON 0xf
45
38#ifdef __KERNEL__ 46#ifdef __KERNEL__
39 47
40#ifndef __ASSEMBLY__ 48#ifndef __ASSEMBLY__
diff --git a/arch/sparc/include/asm/sections.h b/arch/sparc/include/asm/sections.h
index 0b0553bbd8a0..f300d1a9b2b6 100644
--- a/arch/sparc/include/asm/sections.h
+++ b/arch/sparc/include/asm/sections.h
@@ -7,4 +7,7 @@
7/* sparc entry point */ 7/* sparc entry point */
8extern char _start[]; 8extern char _start[];
9 9
10extern char __leon_1insn_patch[];
11extern char __leon_1insn_patch_end[];
12
10#endif 13#endif
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 72308f9b0096..6cf591b7e1c6 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -51,8 +51,8 @@ obj-y += of_device_common.o
51obj-y += of_device_$(BITS).o 51obj-y += of_device_$(BITS).o
52obj-$(CONFIG_SPARC64) += prom_irqtrans.o 52obj-$(CONFIG_SPARC64) += prom_irqtrans.o
53 53
54obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o 54obj-$(CONFIG_SPARC32) += leon_kernel.o
55obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o 55obj-$(CONFIG_SPARC32) += leon_pmc.o
56 56
57obj-$(CONFIG_SPARC64) += reboot.o 57obj-$(CONFIG_SPARC64) += reboot.o
58obj-$(CONFIG_SPARC64) += sysfs.o 58obj-$(CONFIG_SPARC64) += sysfs.o
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 2d1819641769..a6c94a2bf9d4 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -121,7 +121,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
121 FPU(-1, NULL) 121 FPU(-1, NULL)
122 } 122 }
123},{ 123},{
124 4, 124 PSR_IMPL_TI,
125 .cpu_info = { 125 .cpu_info = {
126 CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"), 126 CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"),
127 /* SparcClassic -- borned STP1010TAB-50*/ 127 /* SparcClassic -- borned STP1010TAB-50*/
@@ -191,7 +191,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
191 FPU(-1, NULL) 191 FPU(-1, NULL)
192 } 192 }
193},{ 193},{
194 0xF, /* Aeroflex Gaisler */ 194 PSR_IMPL_LEON, /* Aeroflex Gaisler */
195 .cpu_info = { 195 .cpu_info = {
196 CPU(3, "LEON"), 196 CPU(3, "LEON"),
197 CPU(-1, NULL) 197 CPU(-1, NULL)
@@ -440,16 +440,16 @@ static int __init cpu_type_probe(void)
440 int psr_impl, psr_vers, fpu_vers; 440 int psr_impl, psr_vers, fpu_vers;
441 int psr; 441 int psr;
442 442
443 psr_impl = ((get_psr() >> 28) & 0xf); 443 psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK);
444 psr_vers = ((get_psr() >> 24) & 0xf); 444 psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK);
445 445
446 psr = get_psr(); 446 psr = get_psr();
447 put_psr(psr | PSR_EF); 447 put_psr(psr | PSR_EF);
448#ifdef CONFIG_SPARC_LEON 448
449 fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; 449 if (psr_impl == PSR_IMPL_LEON)
450#else 450 fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
451 fpu_vers = ((get_fsr() >> 17) & 0x7); 451 else
452#endif 452 fpu_vers = ((get_fsr() >> 17) & 0x7);
453 453
454 put_psr(psr); 454 put_psr(psr);
455 455
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 2dbe1806e530..dcaa1cf0de40 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -393,7 +393,6 @@ linux_trap_ipi15_sun4d:
393 /* FIXME */ 393 /* FIXME */
3941: b,a 1b 3941: b,a 1b
395 395
396#ifdef CONFIG_SPARC_LEON
397 .globl smpleon_ipi 396 .globl smpleon_ipi
398 .extern leon_ipi_interrupt 397 .extern leon_ipi_interrupt
399 /* SMP per-cpu IPI interrupts are handled specially. */ 398 /* SMP per-cpu IPI interrupts are handled specially. */
@@ -424,8 +423,6 @@ linux_trap_ipi15_leon:
424 b ret_trap_lockless_ipi 423 b ret_trap_lockless_ipi
425 clr %l6 424 clr %l6
426 425
427#endif /* CONFIG_SPARC_LEON */
428
429#endif /* CONFIG_SMP */ 426#endif /* CONFIG_SMP */
430 427
431 /* This routine handles illegal instructions and privileged 428 /* This routine handles illegal instructions and privileged
@@ -770,8 +767,11 @@ srmmu_fault:
770 mov 0x400, %l5 767 mov 0x400, %l5
771 mov 0x300, %l4 768 mov 0x300, %l4
772 769
773 lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first 770LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) ! read sfar first
774 lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last 771SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) ! read sfar first
772
773LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) ! read sfsr last
774SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last
775 775
776 andn %l6, 0xfff, %l6 776 andn %l6, 0xfff, %l6
777 srl %l5, 6, %l5 ! and encode all info into l7 777 srl %l5, 6, %l5 ! and encode all info into l7
diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S
index 84b5f0d2afde..e3e80d65e39a 100644
--- a/arch/sparc/kernel/etrap_32.S
+++ b/arch/sparc/kernel/etrap_32.S
@@ -234,7 +234,8 @@ tsetup_srmmu_stackchk:
234 234
235 cmp %glob_tmp, %sp 235 cmp %glob_tmp, %sp
236 bleu,a 1f 236 bleu,a 1f
237 lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control 237LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
238SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
238 239
239trap_setup_user_stack_is_bolixed: 240trap_setup_user_stack_is_bolixed:
240 /* From user/kernel into invalid window w/bad user 241 /* From user/kernel into invalid window w/bad user
@@ -249,18 +250,25 @@ trap_setup_user_stack_is_bolixed:
2491: 2501:
250 /* Clear the fault status and turn on the no_fault bit. */ 251 /* Clear the fault status and turn on the no_fault bit. */
251 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit 252 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
252 sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it 253LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
254SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
253 255
254 /* Dump the registers and cross fingers. */ 256 /* Dump the registers and cross fingers. */
255 STORE_WINDOW(sp) 257 STORE_WINDOW(sp)
256 258
257 /* Clear the no_fault bit and check the status. */ 259 /* Clear the no_fault bit and check the status. */
258 andn %glob_tmp, 0x2, %glob_tmp 260 andn %glob_tmp, 0x2, %glob_tmp
259 sta %glob_tmp, [%g0] ASI_M_MMUREGS 261LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
262SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
263
260 mov AC_M_SFAR, %glob_tmp 264 mov AC_M_SFAR, %glob_tmp
261 lda [%glob_tmp] ASI_M_MMUREGS, %g0 265LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
266SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
267
262 mov AC_M_SFSR, %glob_tmp 268 mov AC_M_SFSR, %glob_tmp
263 lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore 269LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore
270SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore
271
264 andcc %glob_tmp, 0x2, %g0 ! did we fault? 272 andcc %glob_tmp, 0x2, %g0 ! did we fault?
265 bne trap_setup_user_stack_is_bolixed ! failure 273 bne trap_setup_user_stack_is_bolixed ! failure
266 nop 274 nop
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index a0f5c20e4b9c..afeb1d770303 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -30,10 +30,6 @@
30 * the cpu-type 30 * the cpu-type
31 */ 31 */
32 .align 4 32 .align 4
33cputyp:
34 .word 1
35
36 .align 4
37 .globl cputypval 33 .globl cputypval
38cputypval: 34cputypval:
39 .asciz "sun4m" 35 .asciz "sun4m"
@@ -46,8 +42,8 @@ cputypvar:
46 42
47 .align 4 43 .align 4
48 44
49sun4c_notsup: 45notsup:
50 .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" 46 .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
51 .align 4 47 .align 4
52 48
53sun4e_notsup: 49sun4e_notsup:
@@ -123,7 +119,7 @@ current_pc:
123 tst %o0 119 tst %o0
124 be no_sun4u_here 120 be no_sun4u_here
125 mov %g4, %o7 /* Previous %o7. */ 121 mov %g4, %o7 /* Previous %o7. */
126 122
127 mov %o0, %l0 ! stash away romvec 123 mov %o0, %l0 ! stash away romvec
128 mov %o0, %g7 ! put it here too 124 mov %o0, %g7 ! put it here too
129 mov %o1, %l1 ! stash away debug_vec too 125 mov %o1, %l1 ! stash away debug_vec too
@@ -132,7 +128,7 @@ current_pc:
132 set current_pc, %g5 128 set current_pc, %g5
133 cmp %g3, %g5 129 cmp %g3, %g5
134 be already_mapped 130 be already_mapped
135 nop 131 nop
136 132
137 /* %l6 will hold the offset we have to subtract 133 /* %l6 will hold the offset we have to subtract
138 * from absolute symbols in order to access areas 134 * from absolute symbols in order to access areas
@@ -192,9 +188,9 @@ copy_prom_done:
192 bne not_a_sun4 188 bne not_a_sun4
193 nop 189 nop
194 190
195halt_sun4_or_sun4c: 191halt_notsup:
196 ld [%g7 + 0x68], %o1 192 ld [%g7 + 0x68], %o1
197 set sun4c_notsup, %o0 193 set notsup, %o0
198 sub %o0, %l6, %o0 194 sub %o0, %l6, %o0
199 call %o1 195 call %o1
200 nop 196 nop
@@ -202,18 +198,31 @@ halt_sun4_or_sun4c:
202 nop 198 nop
203 199
204not_a_sun4: 200not_a_sun4:
201 /* It looks like this is a machine we support.
202 * Now find out what MMU we are dealing with
203 * LEON - identified by the psr.impl field
204 * Viking - identified by the psr.impl field
205 * In all other cases a sun4m srmmu.
206 * We check that the MMU is enabled in all cases.
207 */
208
209 /* Check if this is a LEON CPU */
210 rd %psr, %g3
211 srl %g3, PSR_IMPL_SHIFT, %g3
212 and %g3, PSR_IMPL_SHIFTED_MASK, %g3
213 cmp %g3, PSR_IMPL_LEON
214 be leon_remap /* It is a LEON - jump */
215 nop
216
217 /* Sanity-check, is MMU enabled */
205 lda [%g0] ASI_M_MMUREGS, %g1 218 lda [%g0] ASI_M_MMUREGS, %g1
206 andcc %g1, 1, %g0 219 andcc %g1, 1, %g0
207 be halt_sun4_or_sun4c 220 be halt_notsup
208 nop 221 nop
209 222
210srmmu_remap: 223 /* Check for a viking (TI) module. */
211 /* First, check for a viking (TI) module. */ 224 cmp %g3, PSR_IMPL_TI
212 set 0x40000000, %g2 225 bne srmmu_not_viking
213 rd %psr, %g3
214 and %g2, %g3, %g3
215 subcc %g3, 0x0, %g0
216 bz srmmu_nviking
217 nop 226 nop
218 227
219 /* Figure out what kind of viking we are on. 228 /* Figure out what kind of viking we are on.
@@ -228,14 +237,14 @@ srmmu_remap:
228 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg 237 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg
229 and %g2, %g3, %g3 238 and %g2, %g3, %g3
230 subcc %g3, 0x0, %g0 239 subcc %g3, 0x0, %g0
231 bnz srmmu_nviking ! is in mbus mode 240 bnz srmmu_not_viking ! is in mbus mode
232 nop 241 nop
233 242
234 rd %psr, %g3 ! DO NOT TOUCH %g3 243 rd %psr, %g3 ! DO NOT TOUCH %g3
235 andn %g3, PSR_ET, %g2 244 andn %g3, PSR_ET, %g2
236 wr %g2, 0x0, %psr 245 wr %g2, 0x0, %psr
237 WRITE_PAUSE 246 WRITE_PAUSE
238 247
239 /* Get context table pointer, then convert to 248 /* Get context table pointer, then convert to
240 * a physical address, which is 36 bits. 249 * a physical address, which is 36 bits.
241 */ 250 */
@@ -258,12 +267,12 @@ srmmu_remap:
258 lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr 267 lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr
259 srl %o1, 0x4, %o1 ! Clear low 4 bits 268 srl %o1, 0x4, %o1 ! Clear low 4 bits
260 sll %o1, 0x8, %o1 ! Make physical 269 sll %o1, 0x8, %o1 ! Make physical
261 270
262 /* Ok, pull in the PTD. */ 271 /* Ok, pull in the PTD. */
263 lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd 272 lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd
264 273
265 /* Calculate to KERNBASE entry. */ 274 /* Calculate to KERNBASE entry. */
266 add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 275 add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3
267 276
268 /* Poke the entry into the calculated address. */ 277 /* Poke the entry into the calculated address. */
269 sta %o2, [%o3] ASI_M_BYPASS 278 sta %o2, [%o3] ASI_M_BYPASS
@@ -293,12 +302,12 @@ srmmu_remap:
293 b go_to_highmem 302 b go_to_highmem
294 nop 303 nop
295 304
305srmmu_not_viking:
296 /* This works on viking's in Mbus mode and all 306 /* This works on viking's in Mbus mode and all
297 * other MBUS modules. It is virtually the same as 307 * other MBUS modules. It is virtually the same as
298 * the above madness sans turning traps off and flipping 308 * the above madness sans turning traps off and flipping
299 * the AC bit. 309 * the AC bit.
300 */ 310 */
301srmmu_nviking:
302 set AC_M_CTPR, %g1 311 set AC_M_CTPR, %g1
303 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr 312 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr
304 sll %g1, 0x4, %g1 ! make physical addr 313 sll %g1, 0x4, %g1 ! make physical addr
@@ -313,6 +322,29 @@ srmmu_nviking:
313 nop ! wheee.... 322 nop ! wheee....
314 323
315 324
325leon_remap:
326 /* Sanity-check, is MMU enabled */
327 lda [%g0] ASI_LEON_MMUREGS, %g1
328 andcc %g1, 1, %g0
329 be halt_notsup
330 nop
331
332 /* Same code as in the srmmu_not_viking case,
333 * with the LEON ASI for mmuregs
334 */
335 set AC_M_CTPR, %g1
336 lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr
337 sll %g1, 0x4, %g1 ! make physical addr
338 lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table
339 srl %g1, 0x4, %g1
340 sll %g1, 0x8, %g1 ! make phys addr for l1 tbl
341
342 lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0
343 add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3
344 sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry
345 b go_to_highmem
346 nop ! wheee....
347
316/* Now do a non-relative jump so that PC is in high-memory */ 348/* Now do a non-relative jump so that PC is in high-memory */
317go_to_highmem: 349go_to_highmem:
318 set execute_in_high_mem, %g1 350 set execute_in_high_mem, %g1
@@ -336,8 +368,9 @@ execute_in_high_mem:
336 sethi %hi(linux_dbvec), %g1 368 sethi %hi(linux_dbvec), %g1
337 st %o1, [%g1 + %lo(linux_dbvec)] 369 st %o1, [%g1 + %lo(linux_dbvec)]
338 370
339/* Get the machine type via the mysterious romvec node operations. */ 371 /* Get the machine type via the romvec
340 372 * getprops node operation
373 */
341 add %g7, 0x1c, %l1 374 add %g7, 0x1c, %l1
342 ld [%l1], %l0 375 ld [%l1], %l0
343 ld [%l0], %l0 376 ld [%l0], %l0
@@ -356,9 +389,42 @@ execute_in_high_mem:
356 ! to a buf where above string 389 ! to a buf where above string
357 ! will get stored by the prom. 390 ! will get stored by the prom.
358 391
359#ifdef CONFIG_SPARC_LEON
360 /* no cpu-type check is needed, it is a SPARC-LEON */
361 392
393 /* Check value of "compatible" property.
394 * "value" => "model"
395 * leon => sparc_leon
396 * sun4m => sun4m
397 * sun4s => sun4m
398 * sun4d => sun4d
399 * sun4e => "no_sun4e_here"
400 * '*' => "no_sun4u_here"
401 * Check single letters only
402 */
403
404 set cputypval, %o2
405 /* If cputypval[0] == 'l' (lower case letter L) this is leon */
406 ldub [%o2], %l1
407 cmp %l1, 'l'
408 be leon_init
409 nop
410
411 /* Check cputypval[4] to find the sun model */
412 ldub [%o2 + 0x4], %l1
413
414 cmp %l1, 'm'
415 be sun4m_init
416 cmp %l1, 's'
417 be sun4m_init
418 cmp %l1, 'd'
419 be sun4d_init
420 cmp %l1, 'e'
421 be no_sun4e_here ! Could be a sun4e.
422 nop
423 b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
424 nop
425
426leon_init:
427 /* LEON CPU - set boot_cpu_id */
362 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index 428 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index
363 429
364#ifdef CONFIG_SMP 430#ifdef CONFIG_SMP
@@ -376,26 +442,6 @@ execute_in_high_mem:
376 442
377 ba continue_boot 443 ba continue_boot
378 nop 444 nop
379#endif
380
381/* Check to cputype. We may be booted on a sun4u (64 bit box),
382 * and sun4d needs special treatment.
383 */
384
385 set cputypval, %o2
386 ldub [%o2 + 0x4], %l1
387
388 cmp %l1, 'm'
389 be sun4m_init
390 cmp %l1, 's'
391 be sun4m_init
392 cmp %l1, 'd'
393 be sun4d_init
394 cmp %l1, 'e'
395 be no_sun4e_here ! Could be a sun4e.
396 nop
397 b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
398 nop
399 445
400/* CPUID in bootbus can be found at PA 0xff0140000 */ 446/* CPUID in bootbus can be found at PA 0xff0140000 */
401#define SUN4D_BOOTBUS_CPUID 0xf0140000 447#define SUN4D_BOOTBUS_CPUID 0xf0140000
@@ -431,9 +477,9 @@ sun4m_init:
431/* This sucks, apparently this makes Vikings call prom panic, will fix later */ 477/* This sucks, apparently this makes Vikings call prom panic, will fix later */
4322: 4782:
433 rd %psr, %o1 479 rd %psr, %o1
434 srl %o1, 28, %o1 ! Get a type of the CPU 480 srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU
435 481
436 subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC 482 subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC
437 be continue_boot 483 be continue_boot
438 nop 484 nop
439 485
@@ -459,10 +505,6 @@ continue_boot:
459/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's 505/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
460 * show-time! 506 * show-time!
461 */ 507 */
462
463 sethi %hi(cputyp), %o0
464 st %g4, [%o0 + %lo(cputyp)]
465
466 /* Turn on Supervisor, EnableFloating, and all the PIL bits. 508 /* Turn on Supervisor, EnableFloating, and all the PIL bits.
467 * Also puts us in register window zero with traps off. 509 * Also puts us in register window zero with traps off.
468 */ 510 */
@@ -480,7 +522,7 @@ continue_boot:
480 set __bss_start , %o0 ! First address of BSS 522 set __bss_start , %o0 ! First address of BSS
481 set _end , %o1 ! Last address of BSS 523 set _end , %o1 ! Last address of BSS
482 add %o0, 0x1, %o0 524 add %o0, 0x1, %o0
4831: 5251:
484 stb %g0, [%o0] 526 stb %g0, [%o0]
485 subcc %o0, %o1, %g0 527 subcc %o0, %o1, %g0
486 bl 1b 528 bl 1b
@@ -546,7 +588,7 @@ continue_boot:
546 set dest, %g2; \ 588 set dest, %g2; \
547 ld [%g5], %g4; \ 589 ld [%g5], %g4; \
548 st %g4, [%g2]; 590 st %g4, [%g2];
549 591
550 /* Patch for window spills... */ 592 /* Patch for window spills... */
551 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) 593 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
552 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) 594 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
@@ -597,7 +639,7 @@ continue_boot:
597 st %g4, [%g5 + 0x18] 639 st %g4, [%g5 + 0x18]
598 st %g4, [%g5 + 0x1c] 640 st %g4, [%g5 + 0x1c]
599 641
6002: 6422:
601 sethi %hi(nwindows), %g4 643 sethi %hi(nwindows), %g4
602 st %g3, [%g4 + %lo(nwindows)] ! store final value 644 st %g3, [%g4 + %lo(nwindows)] ! store final value
603 sub %g3, 0x1, %g3 645 sub %g3, 0x1, %g3
@@ -617,18 +659,12 @@ continue_boot:
617 wr %g3, PSR_ET, %psr 659 wr %g3, PSR_ET, %psr
618 WRITE_PAUSE 660 WRITE_PAUSE
619 661
620 /* First we call prom_init() to set up PROMLIB, then 662 /* Call sparc32_start_kernel(struct linux_romvec *rp) */
621 * off to start_kernel().
622 */
623
624 sethi %hi(prom_vector_p), %g5 663 sethi %hi(prom_vector_p), %g5
625 ld [%g5 + %lo(prom_vector_p)], %o0 664 ld [%g5 + %lo(prom_vector_p)], %o0
626 call prom_init 665 call sparc32_start_kernel
627 nop 666 nop
628 667
629 call start_kernel
630 nop
631
632 /* We should not get here. */ 668 /* We should not get here. */
633 call halt_me 669 call halt_me
634 nop 670 nop
@@ -659,7 +695,7 @@ sun4u_5:
659 .asciz "write" 695 .asciz "write"
660 .align 4 696 .align 4
661sun4u_6: 697sun4u_6:
662 .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r" 698 .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r"
663sun4u_6e: 699sun4u_6e:
664 .align 4 700 .align 4
665sun4u_7: 701sun4u_7:
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index a2846f5e32d8..0f094db918c7 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -55,17 +55,13 @@ const struct sparc32_dma_ops *sparc32_dma_ops;
55/* This function must make sure that caches and memory are coherent after DMA 55/* This function must make sure that caches and memory are coherent after DMA
56 * On LEON systems without cache snooping it flushes the entire D-CACHE. 56 * On LEON systems without cache snooping it flushes the entire D-CACHE.
57 */ 57 */
58#ifndef CONFIG_SPARC_LEON
59static inline void dma_make_coherent(unsigned long pa, unsigned long len) 58static inline void dma_make_coherent(unsigned long pa, unsigned long len)
60{ 59{
60 if (sparc_cpu_model == sparc_leon) {
61 if (!sparc_leon3_snooping_enabled())
62 leon_flush_dcache_all();
63 }
61} 64}
62#else
63static inline void dma_make_coherent(unsigned long pa, unsigned long len)
64{
65 if (!sparc_leon3_snooping_enabled())
66 leon_flush_dcache_all();
67}
68#endif
69 65
70static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz); 66static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz);
71static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, 67static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
@@ -427,9 +423,6 @@ arch_initcall(sparc_register_ioport);
427#endif /* CONFIG_SBUS */ 423#endif /* CONFIG_SBUS */
428 424
429 425
430/* LEON reuses PCI DMA ops */
431#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON)
432
433/* Allocate and map kernel buffer using consistent mode DMA for a device. 426/* Allocate and map kernel buffer using consistent mode DMA for a device.
434 * hwdev should be valid struct pci_dev pointer for PCI devices. 427 * hwdev should be valid struct pci_dev pointer for PCI devices.
435 */ 428 */
@@ -657,14 +650,11 @@ struct dma_map_ops pci32_dma_ops = {
657}; 650};
658EXPORT_SYMBOL(pci32_dma_ops); 651EXPORT_SYMBOL(pci32_dma_ops);
659 652
660#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ 653/* leon re-uses pci32_dma_ops */
654struct dma_map_ops *leon_dma_ops = &pci32_dma_ops;
655EXPORT_SYMBOL(leon_dma_ops);
661 656
662#ifdef CONFIG_SPARC_LEON
663struct dma_map_ops *dma_ops = &pci32_dma_ops;
664#elif defined(CONFIG_SBUS)
665struct dma_map_ops *dma_ops = &sbus_dma_ops; 657struct dma_map_ops *dma_ops = &sbus_dma_ops;
666#endif
667
668EXPORT_SYMBOL(dma_ops); 658EXPORT_SYMBOL(dma_ops);
669 659
670 660
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index ae04914f7774..c145f6fd123b 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -241,9 +241,6 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
241 unsigned int cpu_irq; 241 unsigned int cpu_irq;
242 int err; 242 int err;
243 243
244#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
245 struct tt_entry *trap_table;
246#endif
247 244
248 err = request_irq(irq, irq_handler, 0, "floppy", NULL); 245 err = request_irq(irq, irq_handler, 0, "floppy", NULL);
249 if (err) 246 if (err)
@@ -264,13 +261,18 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
264 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; 261 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
265 262
266 INSTANTIATE(sparc_ttable) 263 INSTANTIATE(sparc_ttable)
267#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON 264
268 trap_table = &trapbase_cpu1; 265#if defined CONFIG_SMP
269 INSTANTIATE(trap_table) 266 if (sparc_cpu_model != sparc_leon) {
270 trap_table = &trapbase_cpu2; 267 struct tt_entry *trap_table;
271 INSTANTIATE(trap_table) 268
272 trap_table = &trapbase_cpu3; 269 trap_table = &trapbase_cpu1;
273 INSTANTIATE(trap_table) 270 INSTANTIATE(trap_table)
271 trap_table = &trapbase_cpu2;
272 INSTANTIATE(trap_table)
273 trap_table = &trapbase_cpu3;
274 INSTANTIATE(trap_table)
275 }
274#endif 276#endif
275#undef INSTANTIATE 277#undef INSTANTIATE
276 /* 278 /*
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index a86372d34587..291bb5de9ce0 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -26,6 +26,9 @@ static inline unsigned long kimage_addr_to_ra(const char *p)
26#endif 26#endif
27 27
28#ifdef CONFIG_SPARC32 28#ifdef CONFIG_SPARC32
29/* setup_32.c */
30void sparc32_start_kernel(struct linux_romvec *rp);
31
29/* cpu.c */ 32/* cpu.c */
30extern void cpu_probe(void); 33extern void cpu_probe(void);
31 34
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 77c1b916e4dd..e34e2c40c060 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -23,6 +23,7 @@
23#include <asm/smp.h> 23#include <asm/smp.h>
24#include <asm/setup.h> 24#include <asm/setup.h>
25 25
26#include "kernel.h"
26#include "prom.h" 27#include "prom.h"
27#include "irq.h" 28#include "irq.h"
28 29
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c
index 519ca923f59f..4e174321097d 100644
--- a/arch/sparc/kernel/leon_pmc.c
+++ b/arch/sparc/kernel/leon_pmc.c
@@ -7,6 +7,7 @@
7#include <linux/pm.h> 7#include <linux/pm.h>
8 8
9#include <asm/leon_amba.h> 9#include <asm/leon_amba.h>
10#include <asm/cpu_type.h>
10#include <asm/leon.h> 11#include <asm/leon.h>
11 12
12/* List of Systems that need fixup instructions around power-down instruction */ 13/* List of Systems that need fixup instructions around power-down instruction */
@@ -65,13 +66,15 @@ void pmc_leon_idle(void)
65/* Install LEON Power Down function */ 66/* Install LEON Power Down function */
66static int __init leon_pmc_install(void) 67static int __init leon_pmc_install(void)
67{ 68{
68 /* Assign power management IDLE handler */ 69 if (sparc_cpu_model == sparc_leon) {
69 if (pmc_leon_need_fixup()) 70 /* Assign power management IDLE handler */
70 pm_idle = pmc_leon_idle_fixup; 71 if (pmc_leon_need_fixup())
71 else 72 pm_idle = pmc_leon_idle_fixup;
72 pm_idle = pmc_leon_idle; 73 else
74 pm_idle = pmc_leon_idle;
73 75
74 printk(KERN_INFO "leon: power management initialized\n"); 76 printk(KERN_INFO "leon: power management initialized\n");
77 }
75 78
76 return 0; 79 return 0;
77} 80}
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index a469090faf9f..0f3fb6d9c8ef 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -48,15 +48,13 @@
48 48
49#include "kernel.h" 49#include "kernel.h"
50 50
51#ifdef CONFIG_SPARC_LEON
52
53#include "irq.h" 51#include "irq.h"
54 52
55extern ctxd_t *srmmu_ctx_table_phys; 53extern ctxd_t *srmmu_ctx_table_phys;
56static int smp_processors_ready; 54static int smp_processors_ready;
57extern volatile unsigned long cpu_callin_map[NR_CPUS]; 55extern volatile unsigned long cpu_callin_map[NR_CPUS];
58extern cpumask_t smp_commenced_mask; 56extern cpumask_t smp_commenced_mask;
59void __init leon_configure_cache_smp(void); 57void __cpuinit leon_configure_cache_smp(void);
60static void leon_ipi_init(void); 58static void leon_ipi_init(void);
61 59
62/* IRQ number of LEON IPIs */ 60/* IRQ number of LEON IPIs */
@@ -123,7 +121,7 @@ void __cpuinit leon_callin(void)
123 121
124extern struct linux_prom_registers smp_penguin_ctable; 122extern struct linux_prom_registers smp_penguin_ctable;
125 123
126void __init leon_configure_cache_smp(void) 124void __cpuinit leon_configure_cache_smp(void)
127{ 125{
128 unsigned long cfg = sparc_leon3_get_dcachecfg(); 126 unsigned long cfg = sparc_leon3_get_dcachecfg();
129 int me = smp_processor_id(); 127 int me = smp_processor_id();
@@ -507,5 +505,3 @@ void __init leon_init_smp(void)
507 505
508 sparc32_ipi_ops = &leon_ipi_ops; 506 sparc32_ipi_ops = &leon_ipi_ops;
509} 507}
510
511#endif /* CONFIG_SPARC_LEON */
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index fe6787cc62fc..cb36e82dcd5d 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -65,50 +65,25 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
65struct task_struct *last_task_used_math = NULL; 65struct task_struct *last_task_used_math = NULL;
66struct thread_info *current_set[NR_CPUS]; 66struct thread_info *current_set[NR_CPUS];
67 67
68#ifndef CONFIG_SMP
69
70/* 68/*
71 * the idle loop on a Sparc... ;) 69 * the idle loop on a Sparc... ;)
72 */ 70 */
73void cpu_idle(void) 71void cpu_idle(void)
74{ 72{
75 /* endless idle loop with no priority at all */ 73 set_thread_flag(TIF_POLLING_NRFLAG);
76 for (;;) {
77 if (pm_idle) {
78 while (!need_resched())
79 (*pm_idle)();
80 } else {
81 while (!need_resched())
82 cpu_relax();
83 }
84 schedule_preempt_disabled();
85 }
86}
87
88#else
89 74
90/* This is being executed in task 0 'user space'. */
91void cpu_idle(void)
92{
93 set_thread_flag(TIF_POLLING_NRFLAG);
94 /* endless idle loop with no priority at all */ 75 /* endless idle loop with no priority at all */
95 while(1) { 76 for (;;) {
96#ifdef CONFIG_SPARC_LEON 77 while (!need_resched()) {
97 if (pm_idle) { 78 if (pm_idle)
98 while (!need_resched())
99 (*pm_idle)(); 79 (*pm_idle)();
100 } else 80 else
101#endif
102 {
103 while (!need_resched())
104 cpu_relax(); 81 cpu_relax();
105 } 82 }
106 schedule_preempt_disabled(); 83 schedule_preempt_disabled();
107 } 84 }
108} 85}
109 86
110#endif
111
112/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ 87/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
113void machine_halt(void) 88void machine_halt(void)
114{ 89{
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 741df916c124..1303021748c8 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -23,7 +23,6 @@
23#include <linux/of_pdt.h> 23#include <linux/of_pdt.h>
24#include <asm/prom.h> 24#include <asm/prom.h>
25#include <asm/oplib.h> 25#include <asm/oplib.h>
26#include <asm/leon.h>
27 26
28#include "prom.h" 27#include "prom.h"
29 28
diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S
index 7abc24e2bf1a..6c34de0c2abd 100644
--- a/arch/sparc/kernel/rtrap_32.S
+++ b/arch/sparc/kernel/rtrap_32.S
@@ -231,11 +231,14 @@ srmmu_rett_stackchk:
231 cmp %g1, %fp 231 cmp %g1, %fp
232 bleu ret_trap_user_stack_is_bolixed 232 bleu ret_trap_user_stack_is_bolixed
233 mov AC_M_SFSR, %g1 233 mov AC_M_SFSR, %g1
234 lda [%g1] ASI_M_MMUREGS, %g0 234LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0)
235SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0)
235 236
236 lda [%g0] ASI_M_MMUREGS, %g1 237LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1)
238SUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1)
237 or %g1, 0x2, %g1 239 or %g1, 0x2, %g1
238 sta %g1, [%g0] ASI_M_MMUREGS 240LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS)
241SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS)
239 242
240 restore %g0, %g0, %g0 243 restore %g0, %g0, %g0
241 244
@@ -244,13 +247,16 @@ srmmu_rett_stackchk:
244 save %g0, %g0, %g0 247 save %g0, %g0, %g0
245 248
246 andn %g1, 0x2, %g1 249 andn %g1, 0x2, %g1
247 sta %g1, [%g0] ASI_M_MMUREGS 250LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS)
251SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS)
248 252
249 mov AC_M_SFAR, %g2 253 mov AC_M_SFAR, %g2
250 lda [%g2] ASI_M_MMUREGS, %g2 254LEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2)
255SUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2)
251 256
252 mov AC_M_SFSR, %g1 257 mov AC_M_SFSR, %g1
253 lda [%g1] ASI_M_MMUREGS, %g1 258LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1)
259SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1)
254 andcc %g1, 0x2, %g0 260 andcc %g1, 0x2, %g0
255 be ret_trap_userwins_ok 261 be ret_trap_userwins_ok
256 nop 262 nop
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index c052313f4dc5..efe3e64bba38 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -32,6 +32,7 @@
32#include <linux/cpu.h> 32#include <linux/cpu.h>
33#include <linux/kdebug.h> 33#include <linux/kdebug.h>
34#include <linux/export.h> 34#include <linux/export.h>
35#include <linux/start_kernel.h>
35 36
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/processor.h> 38#include <asm/processor.h>
@@ -45,6 +46,7 @@
45#include <asm/cpudata.h> 46#include <asm/cpudata.h>
46#include <asm/setup.h> 47#include <asm/setup.h>
47#include <asm/cacheflush.h> 48#include <asm/cacheflush.h>
49#include <asm/sections.h>
48 50
49#include "kernel.h" 51#include "kernel.h"
50 52
@@ -237,28 +239,42 @@ static void __init per_cpu_patch(void)
237 } 239 }
238} 240}
239 241
242struct leon_1insn_patch_entry {
243 unsigned int addr;
244 unsigned int insn;
245};
246
240enum sparc_cpu sparc_cpu_model; 247enum sparc_cpu sparc_cpu_model;
241EXPORT_SYMBOL(sparc_cpu_model); 248EXPORT_SYMBOL(sparc_cpu_model);
242 249
243struct tt_entry *sparc_ttable; 250static __init void leon_patch(void)
251{
252 struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch;
253 struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end;
244 254
245struct pt_regs fake_swapper_regs; 255 /* Default instruction is leon - no patching */
256 if (sparc_cpu_model == sparc_leon)
257 return;
246 258
247void __init setup_arch(char **cmdline_p) 259 while (start < end) {
248{ 260 unsigned long addr = start->addr;
249 int i;
250 unsigned long highest_paddr;
251 261
252 sparc_ttable = (struct tt_entry *) &trapbase; 262 *(unsigned int *)(addr) = start->insn;
263 flushi(addr);
253 264
254 /* Initialize PROM console and command line. */ 265 start++;
255 *cmdline_p = prom_getbootargs(); 266 }
256 strcpy(boot_command_line, *cmdline_p); 267}
257 parse_early_param();
258 268
259 boot_flags_init(*cmdline_p); 269struct tt_entry *sparc_ttable;
270struct pt_regs fake_swapper_regs;
260 271
261 register_console(&prom_early_console); 272/* Called from head_32.S - before we have setup anything
273 * in the kernel. Be very careful with what you do here.
274 */
275void __init sparc32_start_kernel(struct linux_romvec *rp)
276{
277 prom_init(rp);
262 278
263 /* Set sparc_cpu_model */ 279 /* Set sparc_cpu_model */
264 sparc_cpu_model = sun_unknown; 280 sparc_cpu_model = sun_unknown;
@@ -275,6 +291,26 @@ void __init setup_arch(char **cmdline_p)
275 if (!strncmp(&cputypval[0], "leon" , 4)) 291 if (!strncmp(&cputypval[0], "leon" , 4))
276 sparc_cpu_model = sparc_leon; 292 sparc_cpu_model = sparc_leon;
277 293
294 leon_patch();
295 start_kernel();
296}
297
298void __init setup_arch(char **cmdline_p)
299{
300 int i;
301 unsigned long highest_paddr;
302
303 sparc_ttable = (struct tt_entry *) &trapbase;
304
305 /* Initialize PROM console and command line. */
306 *cmdline_p = prom_getbootargs();
307 strcpy(boot_command_line, *cmdline_p);
308 parse_early_param();
309
310 boot_flags_init(*cmdline_p);
311
312 register_console(&prom_early_console);
313
278 printk("ARCH: "); 314 printk("ARCH: ");
279 switch(sparc_cpu_model) { 315 switch(sparc_cpu_model) {
280 case sun4m: 316 case sun4m:
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S
index 7364ddc9e5aa..af27acab4486 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -149,8 +149,6 @@ sun4d_cpu_startup:
149 149
150 b,a smp_do_cpu_idle 150 b,a smp_do_cpu_idle
151 151
152#ifdef CONFIG_SPARC_LEON
153
154 __CPUINIT 152 __CPUINIT
155 .align 4 153 .align 4
156 .global leon_smp_cpu_startup, smp_penguin_ctable 154 .global leon_smp_cpu_startup, smp_penguin_ctable
@@ -161,7 +159,7 @@ leon_smp_cpu_startup:
161 ld [%g1+4],%g1 159 ld [%g1+4],%g1
162 srl %g1,4,%g1 160 srl %g1,4,%g1
163 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ 161 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */
164 sta %g1, [%g5] ASI_M_MMUREGS 162 sta %g1, [%g5] ASI_LEON_MMUREGS
165 163
166 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ 164 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
167 set (PSR_PIL | PSR_S | PSR_PS), %g1 165 set (PSR_PIL | PSR_S | PSR_PS), %g1
@@ -207,5 +205,3 @@ leon_smp_cpu_startup:
207 nop 205 nop
208 206
209 b,a smp_do_cpu_idle 207 b,a smp_do_cpu_idle
210
211#endif
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index c72fdf55e1c1..3b05e6697710 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2054,7 +2054,7 @@ void do_fpieee(struct pt_regs *regs)
2054 do_fpe_common(regs); 2054 do_fpe_common(regs);
2055} 2055}
2056 2056
2057extern int do_mathemu(struct pt_regs *, struct fpustate *); 2057extern int do_mathemu(struct pt_regs *, struct fpustate *, bool);
2058 2058
2059void do_fpother(struct pt_regs *regs) 2059void do_fpother(struct pt_regs *regs)
2060{ 2060{
@@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs)
2068 switch ((current_thread_info()->xfsr[0] & 0x1c000)) { 2068 switch ((current_thread_info()->xfsr[0] & 0x1c000)) {
2069 case (2 << 14): /* unfinished_FPop */ 2069 case (2 << 14): /* unfinished_FPop */
2070 case (3 << 14): /* unimplemented_FPop */ 2070 case (3 << 14): /* unimplemented_FPop */
2071 ret = do_mathemu(regs, f); 2071 ret = do_mathemu(regs, f, false);
2072 break; 2072 break;
2073 } 2073 }
2074 if (ret) 2074 if (ret)
@@ -2308,10 +2308,12 @@ void do_illegal_instruction(struct pt_regs *regs)
2308 } else { 2308 } else {
2309 struct fpustate *f = FPUSTATE; 2309 struct fpustate *f = FPUSTATE;
2310 2310
2311 /* XXX maybe verify XFSR bits like 2311 /* On UltraSPARC T2 and later, FPU insns which
2312 * XXX do_fpother() does? 2312 * are not implemented in HW signal an illegal
2313 * instruction trap and do not set the FP Trap
2314 * Trap in the %fsr to unimplemented_FPop.
2313 */ 2315 */
2314 if (do_mathemu(regs, f)) 2316 if (do_mathemu(regs, f, true))
2315 return; 2317 return;
2316 } 2318 }
2317 } 2319 }
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 0e1605697b49..89c2c29f154b 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -107,6 +107,11 @@ SECTIONS
107 *(.sun4v_2insn_patch) 107 *(.sun4v_2insn_patch)
108 __sun4v_2insn_patch_end = .; 108 __sun4v_2insn_patch_end = .;
109 } 109 }
110 .leon_1insn_patch : {
111 __leon_1insn_patch = .;
112 *(.leon_1insn_patch)
113 __leon_1insn_patch_end = .;
114 }
110 .swapper_tsb_phys_patch : { 115 .swapper_tsb_phys_patch : {
111 __swapper_tsb_phys_patch = .; 116 __swapper_tsb_phys_patch = .;
112 *(.swapper_tsb_phys_patch) 117 *(.swapper_tsb_phys_patch)
diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S
index 4c2de3cf309b..28a7bc69f82b 100644
--- a/arch/sparc/kernel/wof.S
+++ b/arch/sparc/kernel/wof.S
@@ -332,24 +332,30 @@ spwin_srmmu_stackchk:
332 mov AC_M_SFSR, %glob_tmp 332 mov AC_M_SFSR, %glob_tmp
333 333
334 /* Clear the fault status and turn on the no_fault bit. */ 334 /* Clear the fault status and turn on the no_fault bit. */
335 lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR 335LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) ! eat SFSR
336SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) ! eat SFSR
336 337
337 lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control 338LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
339SUN_PI_(lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
338 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit 340 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
339 sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it 341LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
342SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
340 343
341 /* Dump the registers and cross fingers. */ 344 /* Dump the registers and cross fingers. */
342 STORE_WINDOW(sp) 345 STORE_WINDOW(sp)
343 346
344 /* Clear the no_fault bit and check the status. */ 347 /* Clear the no_fault bit and check the status. */
345 andn %glob_tmp, 0x2, %glob_tmp 348 andn %glob_tmp, 0x2, %glob_tmp
346 sta %glob_tmp, [%g0] ASI_M_MMUREGS 349LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
350SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
347 351
348 mov AC_M_SFAR, %glob_tmp 352 mov AC_M_SFAR, %glob_tmp
349 lda [%glob_tmp] ASI_M_MMUREGS, %g0 353LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
354SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
350 355
351 mov AC_M_SFSR, %glob_tmp 356 mov AC_M_SFSR, %glob_tmp
352 lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp 357LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)
358SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp)
353 andcc %glob_tmp, 0x2, %g0 ! did we fault? 359 andcc %glob_tmp, 0x2, %g0 ! did we fault?
354 be,a spwin_finish_up + 0x4 ! cool beans, success 360 be,a spwin_finish_up + 0x4 ! cool beans, success
355 restore %g0, %g0, %g0 361 restore %g0, %g0, %g0
diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S
index 9fde91a249e0..2c21cc59683e 100644
--- a/arch/sparc/kernel/wuf.S
+++ b/arch/sparc/kernel/wuf.S
@@ -254,16 +254,19 @@ srmmu_fwin_stackchk:
254 mov AC_M_SFSR, %l4 254 mov AC_M_SFSR, %l4
255 cmp %l5, %sp 255 cmp %l5, %sp
256 bleu fwin_user_stack_is_bolixed 256 bleu fwin_user_stack_is_bolixed
257 lda [%l4] ASI_M_MMUREGS, %g0 ! clear fault status 257LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status
258SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status
258 259
259 /* The technique is, turn off faults on this processor, 260 /* The technique is, turn off faults on this processor,
260 * just let the load rip, then check the sfsr to see if 261 * just let the load rip, then check the sfsr to see if
261 * a fault did occur. Then we turn on fault traps again 262 * a fault did occur. Then we turn on fault traps again
262 * and branch conditionally based upon what happened. 263 * and branch conditionally based upon what happened.
263 */ 264 */
264 lda [%g0] ASI_M_MMUREGS, %l5 ! read mmu-ctrl reg 265LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg
266SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg
265 or %l5, 0x2, %l5 ! turn on no-fault bit 267 or %l5, 0x2, %l5 ! turn on no-fault bit
266 sta %l5, [%g0] ASI_M_MMUREGS ! store it 268LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it
269SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it
267 270
268 /* Cross fingers and go for it. */ 271 /* Cross fingers and go for it. */
269 LOAD_WINDOW(sp) 272 LOAD_WINDOW(sp)
@@ -275,18 +278,22 @@ srmmu_fwin_stackchk:
275 278
276 /* LOCATION: Window 'T' */ 279 /* LOCATION: Window 'T' */
277 280
278 lda [%g0] ASI_M_MMUREGS, %twin_tmp1 ! load mmu-ctrl again 281LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
279 andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit 282SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
280 sta %twin_tmp1, [%g0] ASI_M_MMUREGS ! store it 283 andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit
284LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it
285SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it
281 286
282 mov AC_M_SFAR, %twin_tmp2 287 mov AC_M_SFAR, %twin_tmp2
283 lda [%twin_tmp2] ASI_M_MMUREGS, %g0 ! read fault address 288LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address
289SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address
284 290
285 mov AC_M_SFSR, %twin_tmp2 291 mov AC_M_SFSR, %twin_tmp2
286 lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2 ! read fault status 292LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status
287 andcc %twin_tmp2, 0x2, %g0 ! did fault occur? 293SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status
294 andcc %twin_tmp2, 0x2, %g0 ! did fault occur?
288 295
289 bne 1f ! yep, cleanup 296 bne 1f ! yep, cleanup
290 nop 297 nop
291 298
292 wr %t_psr, 0x0, %psr 299 wr %t_psr, 0x0, %psr
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c
index 2bbe2f28ad23..1704068da928 100644
--- a/arch/sparc/math-emu/math_64.c
+++ b/arch/sparc/math-emu/math_64.c
@@ -163,7 +163,7 @@ typedef union {
163 u64 q[2]; 163 u64 q[2];
164} *argp; 164} *argp;
165 165
166int do_mathemu(struct pt_regs *regs, struct fpustate *f) 166int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap)
167{ 167{
168 unsigned long pc = regs->tpc; 168 unsigned long pc = regs->tpc;
169 unsigned long tstate = regs->tstate; 169 unsigned long tstate = regs->tstate;
@@ -218,7 +218,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
218 case FSQRTS: { 218 case FSQRTS: {
219 unsigned long x = current_thread_info()->xfsr[0]; 219 unsigned long x = current_thread_info()->xfsr[0];
220 220
221 x = (x >> 14) & 0xf; 221 x = (x >> 14) & 0x7;
222 TYPE(x,1,1,1,1,0,0); 222 TYPE(x,1,1,1,1,0,0);
223 break; 223 break;
224 } 224 }
@@ -226,7 +226,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
226 case FSQRTD: { 226 case FSQRTD: {
227 unsigned long x = current_thread_info()->xfsr[0]; 227 unsigned long x = current_thread_info()->xfsr[0];
228 228
229 x = (x >> 14) & 0xf; 229 x = (x >> 14) & 0x7;
230 TYPE(x,2,1,2,1,0,0); 230 TYPE(x,2,1,2,1,0,0);
231 break; 231 break;
232 } 232 }
@@ -357,9 +357,17 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
357 if (type) { 357 if (type) {
358 argp rs1 = NULL, rs2 = NULL, rd = NULL; 358 argp rs1 = NULL, rs2 = NULL, rd = NULL;
359 359
360 freg = (current_thread_info()->xfsr[0] >> 14) & 0xf; 360 /* Starting with UltraSPARC-T2, the cpu does not set the FP Trap
361 if (freg != (type >> 9)) 361 * Type field in the %fsr to unimplemented_FPop. Nor does it
362 goto err; 362 * use the fp_exception_other trap. Instead it signals an
363 * illegal instruction and leaves the FP trap type field of
364 * the %fsr unchanged.
365 */
366 if (!illegal_insn_trap) {
367 int ftt = (current_thread_info()->xfsr[0] >> 14) & 0x7;
368 if (ftt != (type >> 9))
369 goto err;
370 }
363 current_thread_info()->xfsr[0] &= ~0x1c000; 371 current_thread_info()->xfsr[0] &= ~0x1c000;
364 freg = ((insn >> 14) & 0x1f); 372 freg = ((insn >> 14) & 0x1f);
365 switch (type & 0x3) { 373 switch (type & 0x3) {
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 69ffd3112fed..30c3eccfdf5a 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -8,8 +8,9 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o
8obj-y += fault_$(BITS).o 8obj-y += fault_$(BITS).o
9obj-y += init_$(BITS).o 9obj-y += init_$(BITS).o
10obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o 10obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o
11obj-$(CONFIG_SPARC32) += srmmu_access.o
11obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o 12obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o
12obj-$(CONFIG_SPARC_LEON)+= leon_mm.o 13obj-$(CONFIG_SPARC32) += leon_mm.o
13 14
14# Only used by sparc64 15# Only used by sparc64
15obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 16obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c
index 4c67ae6e5023..5bed085a2c17 100644
--- a/arch/sparc/mm/leon_mm.c
+++ b/arch/sparc/mm/leon_mm.c
@@ -32,7 +32,7 @@ static inline unsigned long leon_get_ctable_ptr(void)
32} 32}
33 33
34 34
35unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) 35unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr)
36{ 36{
37 37
38 unsigned int ctxtbl; 38 unsigned int ctxtbl;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 256db6b22c54..62e3f5773303 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -646,6 +646,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
646 } 646 }
647} 647}
648 648
649/* These flush types are not available on all chips... */
650static inline unsigned long srmmu_probe(unsigned long vaddr)
651{
652 unsigned long retval;
653
654 if (sparc_cpu_model != sparc_leon) {
655
656 vaddr &= PAGE_MASK;
657 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
658 "=r" (retval) :
659 "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
660 } else {
661 retval = leon_swprobe(vaddr, 0);
662 }
663 return retval;
664}
665
649/* 666/*
650 * This is much cleaner than poking around physical address space 667 * This is much cleaner than poking around physical address space
651 * looking at the prom's page table directly which is what most 668 * looking at the prom's page table directly which is what most
@@ -665,7 +682,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
665 break; /* probably wrap around */ 682 break; /* probably wrap around */
666 if(start == 0xfef00000) 683 if(start == 0xfef00000)
667 start = KADB_DEBUGGER_BEGVM; 684 start = KADB_DEBUGGER_BEGVM;
668 if(!(prompte = srmmu_hwprobe(start))) { 685 if(!(prompte = srmmu_probe(start))) {
669 start += PAGE_SIZE; 686 start += PAGE_SIZE;
670 continue; 687 continue;
671 } 688 }
@@ -674,12 +691,12 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
674 what = 0; 691 what = 0;
675 692
676 if(!(start & ~(SRMMU_REAL_PMD_MASK))) { 693 if(!(start & ~(SRMMU_REAL_PMD_MASK))) {
677 if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) 694 if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte)
678 what = 1; 695 what = 1;
679 } 696 }
680 697
681 if(!(start & ~(SRMMU_PGDIR_MASK))) { 698 if(!(start & ~(SRMMU_PGDIR_MASK))) {
682 if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == 699 if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) ==
683 prompte) 700 prompte)
684 what = 2; 701 what = 2;
685 } 702 }
@@ -1156,7 +1173,7 @@ static void turbosparc_flush_page_to_ram(unsigned long page)
1156#ifdef TURBOSPARC_WRITEBACK 1173#ifdef TURBOSPARC_WRITEBACK
1157 volatile unsigned long clear; 1174 volatile unsigned long clear;
1158 1175
1159 if (srmmu_hwprobe(page)) 1176 if (srmmu_probe(page))
1160 turbosparc_flush_page_cache(page); 1177 turbosparc_flush_page_cache(page);
1161 clear = srmmu_get_fstatus(); 1178 clear = srmmu_get_fstatus();
1162#endif 1179#endif
diff --git a/arch/sparc/mm/srmmu_access.S b/arch/sparc/mm/srmmu_access.S
new file mode 100644
index 000000000000..d0a67b2c2383
--- /dev/null
+++ b/arch/sparc/mm/srmmu_access.S
@@ -0,0 +1,82 @@
1/* Assembler variants of srmmu access functions.
2 * Implemented in assembler to allow run-time patching.
3 * LEON uses a different ASI for MMUREGS than SUN.
4 *
5 * The leon_1insn_patch infrastructure is used
6 * for the run-time patching.
7 */
8
9#include <linux/linkage.h>
10
11#include <asm/asmmacro.h>
12#include <asm/pgtsrmmu.h>
13#include <asm/asi.h>
14
15/* unsigned int srmmu_get_mmureg(void) */
16ENTRY(srmmu_get_mmureg)
17LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0)
18SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0)
19 retl
20 nop
21ENDPROC(srmmu_get_mmureg)
22
23/* void srmmu_set_mmureg(unsigned long regval) */
24ENTRY(srmmu_set_mmureg)
25LEON_PI(sta %o0, [%g0] ASI_LEON_MMUREGS)
26SUN_PI_(sta %o0, [%g0] ASI_M_MMUREGS)
27 retl
28 nop
29ENDPROC(srmmu_set_mmureg)
30
31/* void srmmu_set_ctable_ptr(unsigned long paddr) */
32ENTRY(srmmu_set_ctable_ptr)
33 /* paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); */
34 srl %o0, 4, %g1
35 and %g1, SRMMU_CTX_PMASK, %g1
36
37 mov SRMMU_CTXTBL_PTR, %g2
38LEON_PI(sta %g1, [%g2] ASI_LEON_MMUREGS)
39SUN_PI_(sta %g1, [%g2] ASI_M_MMUREGS)
40 retl
41 nop
42ENDPROC(srmmu_set_ctable_ptr)
43
44
45/* void srmmu_set_context(int context) */
46ENTRY(srmmu_set_context)
47 mov SRMMU_CTX_REG, %g1
48LEON_PI(sta %o0, [%g1] ASI_LEON_MMUREGS)
49SUN_PI_(sta %o0, [%g1] ASI_M_MMUREGS)
50 retl
51 nop
52ENDPROC(srmmu_set_context)
53
54
55/* int srmmu_get_context(void) */
56ENTRY(srmmu_get_context)
57 mov SRMMU_CTX_REG, %o0
58LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0)
59SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0)
60 retl
61 nop
62ENDPROC(srmmu_get_context)
63
64
65/* unsigned int srmmu_get_fstatus(void) */
66ENTRY(srmmu_get_fstatus)
67 mov SRMMU_FAULT_STATUS, %o0
68LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0)
69SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0)
70 retl
71 nop
72ENDPROC(srmmu_get_fstatus)
73
74
75/* unsigned int srmmu_get_faddr(void) */
76ENTRY(srmmu_get_faddr)
77 mov SRMMU_FAULT_ADDR, %o0
78LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0)
79SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0)
80 retl
81 nop
82ENDPROC(srmmu_get_faddr)