aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-27 08:30:07 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-27 08:30:07 -0400
commitefda9452046bdd707b23a85b7846ec33548f84f1 (patch)
treef08c915049ea1829ba115cd41a0ba28ddf184e07 /arch/sparc64/kernel
parentb01f2cc1c37ac3d5ca313c90370a586dffe5aca9 (diff)
parent36676bcbf9f6bcbea9d06e67ee8d04eacde54952 (diff)
Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/pci.c1
-rw-r--r--arch/sparc64/kernel/traps.c3
-rw-r--r--arch/sparc64/kernel/una_asm.S153
-rw-r--r--arch/sparc64/kernel/unaligned.c261
-rw-r--r--arch/sparc64/kernel/us2e_cpufreq.c36
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c29
7 files changed, 269 insertions, 216 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 093281bdf85f..6f00ab8b9d23 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror
8extra-y := head.o init_task.o vmlinux.lds 8extra-y := head.o init_task.o vmlinux.lds
9 9
10obj-y := process.o setup.o cpu.o idprom.o \ 10obj-y := process.o setup.o cpu.o idprom.o \
11 traps.o devices.o auxio.o \ 11 traps.o devices.o auxio.o una_asm.o \
12 irq.o ptrace.o time.o sys_sparc.o signal.o \ 12 irq.o ptrace.o time.o sys_sparc.o signal.o \
13 unaligned.o central.o pci.o starfire.o semaphore.o \ 13 unaligned.o central.o pci.o starfire.o semaphore.o \
14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o 14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index bba140d98b1b..f21c993f8856 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -540,6 +540,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
540 540
541 pbm->parent->resource_adjust(pdev, res, root); 541 pbm->parent->resource_adjust(pdev, res, root);
542} 542}
543EXPORT_SYMBOL(pcibios_bus_to_resource);
543 544
544char * __init pcibios_setup(char *str) 545char * __init pcibios_setup(char *str)
545{ 546{
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 100b0107c4be..0c9e54b2f0c8 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -2127,6 +2127,9 @@ void __init trap_init(void)
2127 TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || 2127 TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
2128 TI_NEW_CHILD != offsetof(struct thread_info, new_child) || 2128 TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
2129 TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || 2129 TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||
2130 TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) ||
2131 TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) ||
2132 TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) ||
2130 TI_FPREGS != offsetof(struct thread_info, fpregs) || 2133 TI_FPREGS != offsetof(struct thread_info, fpregs) ||
2131 (TI_FPREGS & (64 - 1))) 2134 (TI_FPREGS & (64 - 1)))
2132 thread_info_offsets_are_bolixed_dave(); 2135 thread_info_offsets_are_bolixed_dave();
diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S
new file mode 100644
index 000000000000..cbb40585253c
--- /dev/null
+++ b/arch/sparc64/kernel/una_asm.S
@@ -0,0 +1,153 @@
1/* una_asm.S: Kernel unaligned trap assembler helpers.
2 *
3 * Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7 .text
8
9kernel_unaligned_trap_fault:
10 call kernel_mna_trap_fault
11 nop
12 retl
13 nop
14 .size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
15
16 .globl __do_int_store
17__do_int_store:
18 rd %asi, %o4
19 wr %o3, 0, %asi
20 ldx [%o2], %g3
21 cmp %o1, 2
22 be,pn %icc, 2f
23 cmp %o1, 4
24 be,pt %icc, 1f
25 srlx %g3, 24, %g2
26 srlx %g3, 56, %g1
27 srlx %g3, 48, %g7
284: stba %g1, [%o0] %asi
29 srlx %g3, 40, %g1
305: stba %g7, [%o0 + 1] %asi
31 srlx %g3, 32, %g7
326: stba %g1, [%o0 + 2] %asi
337: stba %g7, [%o0 + 3] %asi
34 srlx %g3, 16, %g1
358: stba %g2, [%o0 + 4] %asi
36 srlx %g3, 8, %g7
379: stba %g1, [%o0 + 5] %asi
3810: stba %g7, [%o0 + 6] %asi
39 ba,pt %xcc, 0f
4011: stba %g3, [%o0 + 7] %asi
411: srl %g3, 16, %g7
4212: stba %g2, [%o0] %asi
43 srl %g3, 8, %g2
4413: stba %g7, [%o0 + 1] %asi
4514: stba %g2, [%o0 + 2] %asi
46 ba,pt %xcc, 0f
4715: stba %g3, [%o0 + 3] %asi
482: srl %g3, 8, %g2
4916: stba %g2, [%o0] %asi
5017: stba %g3, [%o0 + 1] %asi
510:
52 wr %o4, 0x0, %asi
53 retl
54 nop
55 .size __do_int_store, .-__do_int_store
56
57 .section __ex_table
58 .word 4b, kernel_unaligned_trap_fault
59 .word 5b, kernel_unaligned_trap_fault
60 .word 6b, kernel_unaligned_trap_fault
61 .word 7b, kernel_unaligned_trap_fault
62 .word 8b, kernel_unaligned_trap_fault
63 .word 9b, kernel_unaligned_trap_fault
64 .word 10b, kernel_unaligned_trap_fault
65 .word 11b, kernel_unaligned_trap_fault
66 .word 12b, kernel_unaligned_trap_fault
67 .word 13b, kernel_unaligned_trap_fault
68 .word 14b, kernel_unaligned_trap_fault
69 .word 15b, kernel_unaligned_trap_fault
70 .word 16b, kernel_unaligned_trap_fault
71 .word 17b, kernel_unaligned_trap_fault
72 .previous
73
74 .globl do_int_load
75do_int_load:
76 rd %asi, %o5
77 wr %o4, 0, %asi
78 cmp %o1, 8
79 bge,pn %icc, 9f
80 cmp %o1, 4
81 be,pt %icc, 6f
824: lduba [%o2] %asi, %g2
835: lduba [%o2 + 1] %asi, %g3
84 sll %g2, 8, %g2
85 brz,pt %o3, 3f
86 add %g2, %g3, %g2
87 sllx %g2, 48, %g2
88 srax %g2, 48, %g2
893: ba,pt %xcc, 0f
90 stx %g2, [%o0]
916: lduba [%o2 + 1] %asi, %g3
92 sll %g2, 24, %g2
937: lduba [%o2 + 2] %asi, %g7
94 sll %g3, 16, %g3
958: lduba [%o2 + 3] %asi, %g1
96 sll %g7, 8, %g7
97 or %g2, %g3, %g2
98 or %g7, %g1, %g7
99 or %g2, %g7, %g2
100 brnz,a,pt %o3, 3f
101 sra %g2, 0, %g2
1023: ba,pt %xcc, 0f
103 stx %g2, [%o0]
1049: lduba [%o2] %asi, %g2
10510: lduba [%o2 + 1] %asi, %g3
106 sllx %g2, 56, %g2
10711: lduba [%o2 + 2] %asi, %g7
108 sllx %g3, 48, %g3
10912: lduba [%o2 + 3] %asi, %g1
110 sllx %g7, 40, %g7
111 sllx %g1, 32, %g1
112 or %g2, %g3, %g2
113 or %g7, %g1, %g7
11413: lduba [%o2 + 4] %asi, %g3
115 or %g2, %g7, %g7
11614: lduba [%o2 + 5] %asi, %g1
117 sllx %g3, 24, %g3
11815: lduba [%o2 + 6] %asi, %g2
119 sllx %g1, 16, %g1
120 or %g7, %g3, %g7
12116: lduba [%o2 + 7] %asi, %g3
122 sllx %g2, 8, %g2
123 or %g7, %g1, %g7
124 or %g2, %g3, %g2
125 or %g7, %g2, %g7
126 cmp %o1, 8
127 be,a,pt %icc, 0f
128 stx %g7, [%o0]
129 srlx %g7, 32, %g2
130 sra %g7, 0, %g7
131 stx %g2, [%o0]
132 stx %g7, [%o0 + 8]
1330:
134 wr %o5, 0x0, %asi
135 retl
136 nop
137 .size __do_int_load, .-__do_int_load
138
139 .section __ex_table
140 .word 4b, kernel_unaligned_trap_fault
141 .word 5b, kernel_unaligned_trap_fault
142 .word 6b, kernel_unaligned_trap_fault
143 .word 7b, kernel_unaligned_trap_fault
144 .word 8b, kernel_unaligned_trap_fault
145 .word 9b, kernel_unaligned_trap_fault
146 .word 10b, kernel_unaligned_trap_fault
147 .word 11b, kernel_unaligned_trap_fault
148 .word 12b, kernel_unaligned_trap_fault
149 .word 13b, kernel_unaligned_trap_fault
150 .word 14b, kernel_unaligned_trap_fault
151 .word 15b, kernel_unaligned_trap_fault
152 .word 16b, kernel_unaligned_trap_fault
153 .previous
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 4372bf32ecf6..11c3e88732e4 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -180,169 +180,28 @@ static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs)
180 die_if_kernel(str, regs); 180 die_if_kernel(str, regs);
181} 181}
182 182
183#define do_integer_load(dest_reg, size, saddr, is_signed, asi, errh) ({ \ 183extern void do_int_load(unsigned long *dest_reg, int size,
184__asm__ __volatile__ ( \ 184 unsigned long *saddr, int is_signed, int asi);
185 "wr %4, 0, %%asi\n\t" \
186 "cmp %1, 8\n\t" \
187 "bge,pn %%icc, 9f\n\t" \
188 " cmp %1, 4\n\t" \
189 "be,pt %%icc, 6f\n" \
190"4:\t" " lduba [%2] %%asi, %%l1\n" \
191"5:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
192 "sll %%l1, 8, %%l1\n\t" \
193 "brz,pt %3, 3f\n\t" \
194 " add %%l1, %%l2, %%l1\n\t" \
195 "sllx %%l1, 48, %%l1\n\t" \
196 "srax %%l1, 48, %%l1\n" \
197"3:\t" "ba,pt %%xcc, 0f\n\t" \
198 " stx %%l1, [%0]\n" \
199"6:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
200 "sll %%l1, 24, %%l1\n" \
201"7:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \
202 "sll %%l2, 16, %%l2\n" \
203"8:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \
204 "sll %%g7, 8, %%g7\n\t" \
205 "or %%l1, %%l2, %%l1\n\t" \
206 "or %%g7, %%g1, %%g7\n\t" \
207 "or %%l1, %%g7, %%l1\n\t" \
208 "brnz,a,pt %3, 3f\n\t" \
209 " sra %%l1, 0, %%l1\n" \
210"3:\t" "ba,pt %%xcc, 0f\n\t" \
211 " stx %%l1, [%0]\n" \
212"9:\t" "lduba [%2] %%asi, %%l1\n" \
213"10:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
214 "sllx %%l1, 56, %%l1\n" \
215"11:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \
216 "sllx %%l2, 48, %%l2\n" \
217"12:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \
218 "sllx %%g7, 40, %%g7\n\t" \
219 "sllx %%g1, 32, %%g1\n\t" \
220 "or %%l1, %%l2, %%l1\n\t" \
221 "or %%g7, %%g1, %%g7\n" \
222"13:\t" "lduba [%2 + 4] %%asi, %%l2\n\t" \
223 "or %%l1, %%g7, %%g7\n" \
224"14:\t" "lduba [%2 + 5] %%asi, %%g1\n\t" \
225 "sllx %%l2, 24, %%l2\n" \
226"15:\t" "lduba [%2 + 6] %%asi, %%l1\n\t" \
227 "sllx %%g1, 16, %%g1\n\t" \
228 "or %%g7, %%l2, %%g7\n" \
229"16:\t" "lduba [%2 + 7] %%asi, %%l2\n\t" \
230 "sllx %%l1, 8, %%l1\n\t" \
231 "or %%g7, %%g1, %%g7\n\t" \
232 "or %%l1, %%l2, %%l1\n\t" \
233 "or %%g7, %%l1, %%g7\n\t" \
234 "cmp %1, 8\n\t" \
235 "be,a,pt %%icc, 0f\n\t" \
236 " stx %%g7, [%0]\n\t" \
237 "srlx %%g7, 32, %%l1\n\t" \
238 "sra %%g7, 0, %%g7\n\t" \
239 "stx %%l1, [%0]\n\t" \
240 "stx %%g7, [%0 + 8]\n" \
241"0:\n\t" \
242 "wr %%g0, %5, %%asi\n\n\t" \
243 ".section __ex_table\n\t" \
244 ".word 4b, " #errh "\n\t" \
245 ".word 5b, " #errh "\n\t" \
246 ".word 6b, " #errh "\n\t" \
247 ".word 7b, " #errh "\n\t" \
248 ".word 8b, " #errh "\n\t" \
249 ".word 9b, " #errh "\n\t" \
250 ".word 10b, " #errh "\n\t" \
251 ".word 11b, " #errh "\n\t" \
252 ".word 12b, " #errh "\n\t" \
253 ".word 13b, " #errh "\n\t" \
254 ".word 14b, " #errh "\n\t" \
255 ".word 15b, " #errh "\n\t" \
256 ".word 16b, " #errh "\n\n\t" \
257 ".previous\n\t" \
258 : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed), \
259 "r" (asi), "i" (ASI_AIUS) \
260 : "l1", "l2", "g7", "g1", "cc"); \
261})
262 185
263#define store_common(dst_addr, size, src_val, asi, errh) ({ \ 186extern void __do_int_store(unsigned long *dst_addr, int size,
264__asm__ __volatile__ ( \ 187 unsigned long *src_val, int asi);
265 "wr %3, 0, %%asi\n\t" \ 188
266 "ldx [%2], %%l1\n" \ 189static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
267 "cmp %1, 2\n\t" \ 190 struct pt_regs *regs, int asi)
268 "be,pn %%icc, 2f\n\t" \ 191{
269 " cmp %1, 4\n\t" \ 192 unsigned long zero = 0;
270 "be,pt %%icc, 1f\n\t" \ 193 unsigned long *src_val = &zero;
271 " srlx %%l1, 24, %%l2\n\t" \ 194
272 "srlx %%l1, 56, %%g1\n\t" \ 195 if (size == 16) {
273 "srlx %%l1, 48, %%g7\n" \ 196 size = 8;
274"4:\t" "stba %%g1, [%0] %%asi\n\t" \ 197 zero = (((long)(reg_num ?
275 "srlx %%l1, 40, %%g1\n" \ 198 (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
276"5:\t" "stba %%g7, [%0 + 1] %%asi\n\t" \ 199 (unsigned)fetch_reg(reg_num + 1, regs);
277 "srlx %%l1, 32, %%g7\n" \ 200 } else if (reg_num) {
278"6:\t" "stba %%g1, [%0 + 2] %%asi\n" \ 201 src_val = fetch_reg_addr(reg_num, regs);
279"7:\t" "stba %%g7, [%0 + 3] %%asi\n\t" \ 202 }
280 "srlx %%l1, 16, %%g1\n" \ 203 __do_int_store(dst_addr, size, src_val, asi);
281"8:\t" "stba %%l2, [%0 + 4] %%asi\n\t" \ 204}
282 "srlx %%l1, 8, %%g7\n" \
283"9:\t" "stba %%g1, [%0 + 5] %%asi\n" \
284"10:\t" "stba %%g7, [%0 + 6] %%asi\n\t" \
285 "ba,pt %%xcc, 0f\n" \
286"11:\t" " stba %%l1, [%0 + 7] %%asi\n" \
287"1:\t" "srl %%l1, 16, %%g7\n" \
288"12:\t" "stba %%l2, [%0] %%asi\n\t" \
289 "srl %%l1, 8, %%l2\n" \
290"13:\t" "stba %%g7, [%0 + 1] %%asi\n" \
291"14:\t" "stba %%l2, [%0 + 2] %%asi\n\t" \
292 "ba,pt %%xcc, 0f\n" \
293"15:\t" " stba %%l1, [%0 + 3] %%asi\n" \
294"2:\t" "srl %%l1, 8, %%l2\n" \
295"16:\t" "stba %%l2, [%0] %%asi\n" \
296"17:\t" "stba %%l1, [%0 + 1] %%asi\n" \
297"0:\n\t" \
298 "wr %%g0, %4, %%asi\n\n\t" \
299 ".section __ex_table\n\t" \
300 ".word 4b, " #errh "\n\t" \
301 ".word 5b, " #errh "\n\t" \
302 ".word 6b, " #errh "\n\t" \
303 ".word 7b, " #errh "\n\t" \
304 ".word 8b, " #errh "\n\t" \
305 ".word 9b, " #errh "\n\t" \
306 ".word 10b, " #errh "\n\t" \
307 ".word 11b, " #errh "\n\t" \
308 ".word 12b, " #errh "\n\t" \
309 ".word 13b, " #errh "\n\t" \
310 ".word 14b, " #errh "\n\t" \
311 ".word 15b, " #errh "\n\t" \
312 ".word 16b, " #errh "\n\t" \
313 ".word 17b, " #errh "\n\n\t" \
314 ".previous\n\t" \
315 : : "r" (dst_addr), "r" (size), "r" (src_val), "r" (asi), "i" (ASI_AIUS)\
316 : "l1", "l2", "g7", "g1", "cc"); \
317})
318
319#define do_integer_store(reg_num, size, dst_addr, regs, asi, errh) ({ \
320 unsigned long zero = 0; \
321 unsigned long *src_val = &zero; \
322 \
323 if (size == 16) { \
324 size = 8; \
325 zero = (((long)(reg_num ? \
326 (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | \
327 (unsigned)fetch_reg(reg_num + 1, regs); \
328 } else if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
329 store_common(dst_addr, size, src_val, asi, errh); \
330})
331
332extern void smp_capture(void);
333extern void smp_release(void);
334
335#define do_atomic(srcdest_reg, mem, errh) ({ \
336 unsigned long flags, tmp; \
337 \
338 smp_capture(); \
339 local_irq_save(flags); \
340 tmp = *srcdest_reg; \
341 do_integer_load(srcdest_reg, 4, mem, 0, errh); \
342 store_common(mem, 4, &tmp, errh); \
343 local_irq_restore(flags); \
344 smp_release(); \
345})
346 205
347static inline void advance(struct pt_regs *regs) 206static inline void advance(struct pt_regs *regs)
348{ 207{
@@ -364,24 +223,29 @@ static inline int ok_for_kernel(unsigned int insn)
364 return !floating_point_load_or_store_p(insn); 223 return !floating_point_load_or_store_p(insn);
365} 224}
366 225
367void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault"); 226void kernel_mna_trap_fault(void)
368
369void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
370{ 227{
371 unsigned long g2 = regs->u_regs [UREG_G2]; 228 struct pt_regs *regs = current_thread_info()->kern_una_regs;
229 unsigned int insn = current_thread_info()->kern_una_insn;
230 unsigned long g2 = regs->u_regs[UREG_G2];
372 unsigned long fixup = search_extables_range(regs->tpc, &g2); 231 unsigned long fixup = search_extables_range(regs->tpc, &g2);
373 232
374 if (!fixup) { 233 if (!fixup) {
375 unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); 234 unsigned long address;
235
236 address = compute_effective_address(regs, insn,
237 ((insn >> 25) & 0x1f));
376 if (address < PAGE_SIZE) { 238 if (address < PAGE_SIZE) {
377 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler"); 239 printk(KERN_ALERT "Unable to handle kernel NULL "
240 "pointer dereference in mna handler");
378 } else 241 } else
379 printk(KERN_ALERT "Unable to handle kernel paging request in mna handler"); 242 printk(KERN_ALERT "Unable to handle kernel paging "
243 "request in mna handler");
380 printk(KERN_ALERT " at virtual address %016lx\n",address); 244 printk(KERN_ALERT " at virtual address %016lx\n",address);
381 printk(KERN_ALERT "current->{mm,active_mm}->context = %016lx\n", 245 printk(KERN_ALERT "current->{active_,}mm->context = %016lx\n",
382 (current->mm ? CTX_HWBITS(current->mm->context) : 246 (current->mm ? CTX_HWBITS(current->mm->context) :
383 CTX_HWBITS(current->active_mm->context))); 247 CTX_HWBITS(current->active_mm->context)));
384 printk(KERN_ALERT "current->{mm,active_mm}->pgd = %016lx\n", 248 printk(KERN_ALERT "current->{active_,}mm->pgd = %016lx\n",
385 (current->mm ? (unsigned long) current->mm->pgd : 249 (current->mm ? (unsigned long) current->mm->pgd :
386 (unsigned long) current->active_mm->pgd)); 250 (unsigned long) current->active_mm->pgd));
387 die_if_kernel("Oops", regs); 251 die_if_kernel("Oops", regs);
@@ -400,48 +264,41 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
400 enum direction dir = decode_direction(insn); 264 enum direction dir = decode_direction(insn);
401 int size = decode_access_size(insn); 265 int size = decode_access_size(insn);
402 266
267 current_thread_info()->kern_una_regs = regs;
268 current_thread_info()->kern_una_insn = insn;
269
403 if (!ok_for_kernel(insn) || dir == both) { 270 if (!ok_for_kernel(insn) || dir == both) {
404 printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n", 271 printk("Unsupported unaligned load/store trap for kernel "
405 regs->tpc); 272 "at <%016lx>.\n", regs->tpc);
406 unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs); 273 unaligned_panic("Kernel does fpu/atomic "
407 274 "unaligned load/store.", regs);
408 __asm__ __volatile__ ("\n" 275
409"kernel_unaligned_trap_fault:\n\t" 276 kernel_mna_trap_fault();
410 "mov %0, %%o0\n\t"
411 "call kernel_mna_trap_fault\n\t"
412 " mov %1, %%o1\n\t"
413 :
414 : "r" (regs), "r" (insn)
415 : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
416 "g1", "g2", "g3", "g4", "g7", "cc");
417 } else { 277 } else {
418 unsigned long addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); 278 unsigned long addr;
419 279
280 addr = compute_effective_address(regs, insn,
281 ((insn >> 25) & 0x1f));
420#ifdef DEBUG_MNA 282#ifdef DEBUG_MNA
421 printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n", 283 printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] "
422 regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); 284 "retpc[%016lx]\n",
285 regs->tpc, dirstrings[dir], addr, size,
286 regs->u_regs[UREG_RETPC]);
423#endif 287#endif
424 switch (dir) { 288 switch (dir) {
425 case load: 289 case load:
426 do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), 290 do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
427 size, (unsigned long *) addr, 291 size, (unsigned long *) addr,
428 decode_signedness(insn), decode_asi(insn, regs), 292 decode_signedness(insn),
429 kernel_unaligned_trap_fault); 293 decode_asi(insn, regs));
430 break; 294 break;
431 295
432 case store: 296 case store:
433 do_integer_store(((insn>>25)&0x1f), size, 297 do_int_store(((insn>>25)&0x1f), size,
434 (unsigned long *) addr, regs, 298 (unsigned long *) addr, regs,
435 decode_asi(insn, regs), 299 decode_asi(insn, regs));
436 kernel_unaligned_trap_fault);
437 break;
438#if 0 /* unsupported */
439 case both:
440 do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
441 (unsigned long *) addr,
442 kernel_unaligned_trap_fault);
443 break; 300 break;
444#endif 301
445 default: 302 default:
446 panic("Impossible kernel unaligned trap."); 303 panic("Impossible kernel unaligned trap.");
447 /* Not reached... */ 304 /* Not reached... */
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index 7aae0a18aabe..686e526bec04 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -88,7 +88,6 @@ static void frob_mem_refresh(int cpu_slowing_down,
88{ 88{
89 unsigned long old_refr_count, refr_count, mctrl; 89 unsigned long old_refr_count, refr_count, mctrl;
90 90
91
92 refr_count = (clock_tick * MCTRL0_REFR_INTERVAL); 91 refr_count = (clock_tick * MCTRL0_REFR_INTERVAL);
93 refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL); 92 refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL);
94 93
@@ -230,6 +229,25 @@ static unsigned long estar_to_divisor(unsigned long estar)
230 return ret; 229 return ret;
231} 230}
232 231
232static unsigned int us2e_freq_get(unsigned int cpu)
233{
234 cpumask_t cpus_allowed;
235 unsigned long clock_tick, estar;
236
237 if (!cpu_online(cpu))
238 return 0;
239
240 cpus_allowed = current->cpus_allowed;
241 set_cpus_allowed(current, cpumask_of_cpu(cpu));
242
243 clock_tick = sparc64_get_clock_tick(cpu) / 1000;
244 estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
245
246 set_cpus_allowed(current, cpus_allowed);
247
248 return clock_tick / estar_to_divisor(estar);
249}
250
233static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) 251static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
234{ 252{
235 unsigned long new_bits, new_freq; 253 unsigned long new_bits, new_freq;
@@ -243,7 +261,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
243 cpus_allowed = current->cpus_allowed; 261 cpus_allowed = current->cpus_allowed;
244 set_cpus_allowed(current, cpumask_of_cpu(cpu)); 262 set_cpus_allowed(current, cpumask_of_cpu(cpu));
245 263
246 new_freq = clock_tick = sparc64_get_clock_tick(cpu); 264 new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
247 new_bits = index_to_estar_mode(index); 265 new_bits = index_to_estar_mode(index);
248 divisor = index_to_divisor(index); 266 divisor = index_to_divisor(index);
249 new_freq /= divisor; 267 new_freq /= divisor;
@@ -258,7 +276,8 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
258 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 276 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
259 277
260 if (old_divisor != divisor) 278 if (old_divisor != divisor)
261 us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor); 279 us2e_transition(estar, new_bits, clock_tick * 1000,
280 old_divisor, divisor);
262 281
263 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 282 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
264 283
@@ -272,10 +291,8 @@ static int us2e_freq_target(struct cpufreq_policy *policy,
272 unsigned int new_index = 0; 291 unsigned int new_index = 0;
273 292
274 if (cpufreq_frequency_table_target(policy, 293 if (cpufreq_frequency_table_target(policy,
275 &us2e_freq_table[policy->cpu].table[0], 294 &us2e_freq_table[policy->cpu].table[0],
276 target_freq, 295 target_freq, relation, &new_index))
277 relation,
278 &new_index))
279 return -EINVAL; 296 return -EINVAL;
280 297
281 us2e_set_cpu_divider_index(policy->cpu, new_index); 298 us2e_set_cpu_divider_index(policy->cpu, new_index);
@@ -292,7 +309,7 @@ static int us2e_freq_verify(struct cpufreq_policy *policy)
292static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) 309static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
293{ 310{
294 unsigned int cpu = policy->cpu; 311 unsigned int cpu = policy->cpu;
295 unsigned long clock_tick = sparc64_get_clock_tick(cpu); 312 unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
296 struct cpufreq_frequency_table *table = 313 struct cpufreq_frequency_table *table =
297 &us2e_freq_table[cpu].table[0]; 314 &us2e_freq_table[cpu].table[0];
298 315
@@ -351,9 +368,10 @@ static int __init us2e_freq_init(void)
351 memset(us2e_freq_table, 0, 368 memset(us2e_freq_table, 0,
352 (NR_CPUS * sizeof(struct us2e_freq_percpu_info))); 369 (NR_CPUS * sizeof(struct us2e_freq_percpu_info)));
353 370
371 driver->init = us2e_freq_cpu_init;
354 driver->verify = us2e_freq_verify; 372 driver->verify = us2e_freq_verify;
355 driver->target = us2e_freq_target; 373 driver->target = us2e_freq_target;
356 driver->init = us2e_freq_cpu_init; 374 driver->get = us2e_freq_get;
357 driver->exit = us2e_freq_cpu_exit; 375 driver->exit = us2e_freq_cpu_exit;
358 driver->owner = THIS_MODULE, 376 driver->owner = THIS_MODULE,
359 strcpy(driver->name, "UltraSPARC-IIe"); 377 strcpy(driver->name, "UltraSPARC-IIe");
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 18fe54b8aa55..9080e7cd4bb0 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -56,7 +56,7 @@ static void write_safari_cfg(unsigned long val)
56 56
57static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg) 57static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg)
58{ 58{
59 unsigned long clock_tick = sparc64_get_clock_tick(cpu); 59 unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
60 unsigned long ret; 60 unsigned long ret;
61 61
62 switch (safari_cfg & SAFARI_CFG_DIV_MASK) { 62 switch (safari_cfg & SAFARI_CFG_DIV_MASK) {
@@ -76,6 +76,26 @@ static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg
76 return ret; 76 return ret;
77} 77}
78 78
79static unsigned int us3_freq_get(unsigned int cpu)
80{
81 cpumask_t cpus_allowed;
82 unsigned long reg;
83 unsigned int ret;
84
85 if (!cpu_online(cpu))
86 return 0;
87
88 cpus_allowed = current->cpus_allowed;
89 set_cpus_allowed(current, cpumask_of_cpu(cpu));
90
91 reg = read_safari_cfg();
92 ret = get_current_freq(cpu, reg);
93
94 set_cpus_allowed(current, cpus_allowed);
95
96 return ret;
97}
98
79static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) 99static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
80{ 100{
81 unsigned long new_bits, new_freq, reg; 101 unsigned long new_bits, new_freq, reg;
@@ -88,7 +108,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
88 cpus_allowed = current->cpus_allowed; 108 cpus_allowed = current->cpus_allowed;
89 set_cpus_allowed(current, cpumask_of_cpu(cpu)); 109 set_cpus_allowed(current, cpumask_of_cpu(cpu));
90 110
91 new_freq = sparc64_get_clock_tick(cpu); 111 new_freq = sparc64_get_clock_tick(cpu) / 1000;
92 switch (index) { 112 switch (index) {
93 case 0: 113 case 0:
94 new_bits = SAFARI_CFG_DIV_1; 114 new_bits = SAFARI_CFG_DIV_1;
@@ -150,7 +170,7 @@ static int us3_freq_verify(struct cpufreq_policy *policy)
150static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) 170static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
151{ 171{
152 unsigned int cpu = policy->cpu; 172 unsigned int cpu = policy->cpu;
153 unsigned long clock_tick = sparc64_get_clock_tick(cpu); 173 unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
154 struct cpufreq_frequency_table *table = 174 struct cpufreq_frequency_table *table =
155 &us3_freq_table[cpu].table[0]; 175 &us3_freq_table[cpu].table[0];
156 176
@@ -206,9 +226,10 @@ static int __init us3_freq_init(void)
206 memset(us3_freq_table, 0, 226 memset(us3_freq_table, 0,
207 (NR_CPUS * sizeof(struct us3_freq_percpu_info))); 227 (NR_CPUS * sizeof(struct us3_freq_percpu_info)));
208 228
229 driver->init = us3_freq_cpu_init;
209 driver->verify = us3_freq_verify; 230 driver->verify = us3_freq_verify;
210 driver->target = us3_freq_target; 231 driver->target = us3_freq_target;
211 driver->init = us3_freq_cpu_init; 232 driver->get = us3_freq_get;
212 driver->exit = us3_freq_cpu_exit; 233 driver->exit = us3_freq_cpu_exit;
213 driver->owner = THIS_MODULE, 234 driver->owner = THIS_MODULE,
214 strcpy(driver->name, "UltraSPARC-III"); 235 strcpy(driver->name, "UltraSPARC-III");