aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/parisc/kernel
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/Makefile24
-rw-r--r--arch/parisc/kernel/asm-offsets.c299
-rw-r--r--arch/parisc/kernel/binfmt_elf32.c126
-rw-r--r--arch/parisc/kernel/cache.c366
-rw-r--r--arch/parisc/kernel/drivers.c765
-rw-r--r--arch/parisc/kernel/entry.S2426
-rw-r--r--arch/parisc/kernel/firmware.c1405
-rw-r--r--arch/parisc/kernel/hardware.c1366
-rw-r--r--arch/parisc/kernel/head.S386
-rw-r--r--arch/parisc/kernel/hpmc.S304
-rw-r--r--arch/parisc/kernel/init_task.c76
-rw-r--r--arch/parisc/kernel/inventory.c612
-rw-r--r--arch/parisc/kernel/ioctl32.c625
-rw-r--r--arch/parisc/kernel/irq.c343
-rw-r--r--arch/parisc/kernel/module.c822
-rw-r--r--arch/parisc/kernel/pa7300lc.c49
-rw-r--r--arch/parisc/kernel/pacache.S1086
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c187
-rw-r--r--arch/parisc/kernel/pci-dma.c578
-rw-r--r--arch/parisc/kernel/pci.c346
-rw-r--r--arch/parisc/kernel/pdc_chassis.c245
-rw-r--r--arch/parisc/kernel/pdc_cons.c189
-rw-r--r--arch/parisc/kernel/perf.c841
-rw-r--r--arch/parisc/kernel/perf_asm.S1691
-rw-r--r--arch/parisc/kernel/perf_images.h3138
-rw-r--r--arch/parisc/kernel/process.c396
-rw-r--r--arch/parisc/kernel/processor.c400
-rw-r--r--arch/parisc/kernel/ptrace.c423
-rw-r--r--arch/parisc/kernel/real2.S304
-rw-r--r--arch/parisc/kernel/semaphore.c102
-rw-r--r--arch/parisc/kernel/setup.c368
-rw-r--r--arch/parisc/kernel/signal.c664
-rw-r--r--arch/parisc/kernel/signal32.c400
-rw-r--r--arch/parisc/kernel/signal32.h43
-rw-r--r--arch/parisc/kernel/smp.c723
-rw-r--r--arch/parisc/kernel/sys32.h48
-rw-r--r--arch/parisc/kernel/sys_parisc.c253
-rw-r--r--arch/parisc/kernel/sys_parisc32.c720
-rw-r--r--arch/parisc/kernel/syscall.S703
-rw-r--r--arch/parisc/kernel/syscall_table.S372
-rw-r--r--arch/parisc/kernel/time.c243
-rw-r--r--arch/parisc/kernel/topology.c37
-rw-r--r--arch/parisc/kernel/traps.c834
-rw-r--r--arch/parisc/kernel/unaligned.c816
-rw-r--r--arch/parisc/kernel/unwind.c393
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S207
46 files changed, 26744 insertions, 0 deletions
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
new file mode 100644
index 000000000000..171f9c239f60
--- /dev/null
+++ b/arch/parisc/kernel/Makefile
@@ -0,0 +1,24 @@
1#
2# Makefile for arch/parisc/kernel
3#
4
5extra-y := init_task.o head.o vmlinux.lds
6
7AFLAGS_entry.o := -traditional
8AFLAGS_pacache.o := -traditional
9CFLAGS_ioctl32.o := -Ifs/
10
11obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \
12 pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
13 ptrace.o hardware.o inventory.o drivers.o semaphore.o \
14 signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
15 process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
16 topology.o
17
18obj-$(CONFIG_SMP) += smp.o
19obj-$(CONFIG_PA11) += pci-dma.o
20obj-$(CONFIG_PCI) += pci.o
21obj-$(CONFIG_MODULES) += module.o
22obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o ioctl32.o signal32.o
23# only supported for PCX-W/U in 64-bit mode at the moment
24obj-$(CONFIG_64BIT) += perf.o perf_asm.o
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
new file mode 100644
index 000000000000..1ad44f92d6e4
--- /dev/null
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -0,0 +1,299 @@
1/*
2 * Generate definitions needed by assembly language modules.
3 * This code generates raw asm output which is post-processed to extract
4 * and format the required data.
5 *
6 * Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
7 * Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
8 * Copyright (C) 2000 Sam Creasey <sammy@sammy.net>
9 * Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
10 * Copyright (C) 2001 Paul Bame <bame at parisc-linux.org>
11 * Copyright (C) 2001 Richard Hirst <rhirst at parisc-linux.org>
12 * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
13 * Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/types.h>
31#include <linux/sched.h>
32#include <linux/thread_info.h>
33#include <linux/version.h>
34#include <linux/ptrace.h>
35#include <linux/hardirq.h>
36
37#include <asm/pgtable.h>
38#include <asm/ptrace.h>
39#include <asm/processor.h>
40#include <asm/pdc.h>
41#include <asm/uaccess.h>
42
43#define DEFINE(sym, val) \
44 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
45
46#define BLANK() asm volatile("\n->" : : )
47
48#ifdef __LP64__
49#define FRAME_SIZE 128
50#else
51#define FRAME_SIZE 64
52#endif
53
54#define align(x,y) (((x)+FRAME_SIZE+(y)-1) - (((x)+(y)-1)%(y)))
55
56int main(void)
57{
58 DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
59 DEFINE(TASK_STATE, offsetof(struct task_struct, state));
60 DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
61 DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
62 DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
63 DEFINE(TASK_MM, offsetof(struct task_struct, mm));
64 DEFINE(TASK_PERSONALITY, offsetof(struct task_struct, personality));
65 DEFINE(TASK_PID, offsetof(struct task_struct, pid));
66 BLANK();
67 DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
68 DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
69 DEFINE(TASK_PT_GR1, offsetof(struct task_struct, thread.regs.gr[ 1]));
70 DEFINE(TASK_PT_GR2, offsetof(struct task_struct, thread.regs.gr[ 2]));
71 DEFINE(TASK_PT_GR3, offsetof(struct task_struct, thread.regs.gr[ 3]));
72 DEFINE(TASK_PT_GR4, offsetof(struct task_struct, thread.regs.gr[ 4]));
73 DEFINE(TASK_PT_GR5, offsetof(struct task_struct, thread.regs.gr[ 5]));
74 DEFINE(TASK_PT_GR6, offsetof(struct task_struct, thread.regs.gr[ 6]));
75 DEFINE(TASK_PT_GR7, offsetof(struct task_struct, thread.regs.gr[ 7]));
76 DEFINE(TASK_PT_GR8, offsetof(struct task_struct, thread.regs.gr[ 8]));
77 DEFINE(TASK_PT_GR9, offsetof(struct task_struct, thread.regs.gr[ 9]));
78 DEFINE(TASK_PT_GR10, offsetof(struct task_struct, thread.regs.gr[10]));
79 DEFINE(TASK_PT_GR11, offsetof(struct task_struct, thread.regs.gr[11]));
80 DEFINE(TASK_PT_GR12, offsetof(struct task_struct, thread.regs.gr[12]));
81 DEFINE(TASK_PT_GR13, offsetof(struct task_struct, thread.regs.gr[13]));
82 DEFINE(TASK_PT_GR14, offsetof(struct task_struct, thread.regs.gr[14]));
83 DEFINE(TASK_PT_GR15, offsetof(struct task_struct, thread.regs.gr[15]));
84 DEFINE(TASK_PT_GR16, offsetof(struct task_struct, thread.regs.gr[16]));
85 DEFINE(TASK_PT_GR17, offsetof(struct task_struct, thread.regs.gr[17]));
86 DEFINE(TASK_PT_GR18, offsetof(struct task_struct, thread.regs.gr[18]));
87 DEFINE(TASK_PT_GR19, offsetof(struct task_struct, thread.regs.gr[19]));
88 DEFINE(TASK_PT_GR20, offsetof(struct task_struct, thread.regs.gr[20]));
89 DEFINE(TASK_PT_GR21, offsetof(struct task_struct, thread.regs.gr[21]));
90 DEFINE(TASK_PT_GR22, offsetof(struct task_struct, thread.regs.gr[22]));
91 DEFINE(TASK_PT_GR23, offsetof(struct task_struct, thread.regs.gr[23]));
92 DEFINE(TASK_PT_GR24, offsetof(struct task_struct, thread.regs.gr[24]));
93 DEFINE(TASK_PT_GR25, offsetof(struct task_struct, thread.regs.gr[25]));
94 DEFINE(TASK_PT_GR26, offsetof(struct task_struct, thread.regs.gr[26]));
95 DEFINE(TASK_PT_GR27, offsetof(struct task_struct, thread.regs.gr[27]));
96 DEFINE(TASK_PT_GR28, offsetof(struct task_struct, thread.regs.gr[28]));
97 DEFINE(TASK_PT_GR29, offsetof(struct task_struct, thread.regs.gr[29]));
98 DEFINE(TASK_PT_GR30, offsetof(struct task_struct, thread.regs.gr[30]));
99 DEFINE(TASK_PT_GR31, offsetof(struct task_struct, thread.regs.gr[31]));
100 DEFINE(TASK_PT_FR0, offsetof(struct task_struct, thread.regs.fr[ 0]));
101 DEFINE(TASK_PT_FR1, offsetof(struct task_struct, thread.regs.fr[ 1]));
102 DEFINE(TASK_PT_FR2, offsetof(struct task_struct, thread.regs.fr[ 2]));
103 DEFINE(TASK_PT_FR3, offsetof(struct task_struct, thread.regs.fr[ 3]));
104 DEFINE(TASK_PT_FR4, offsetof(struct task_struct, thread.regs.fr[ 4]));
105 DEFINE(TASK_PT_FR5, offsetof(struct task_struct, thread.regs.fr[ 5]));
106 DEFINE(TASK_PT_FR6, offsetof(struct task_struct, thread.regs.fr[ 6]));
107 DEFINE(TASK_PT_FR7, offsetof(struct task_struct, thread.regs.fr[ 7]));
108 DEFINE(TASK_PT_FR8, offsetof(struct task_struct, thread.regs.fr[ 8]));
109 DEFINE(TASK_PT_FR9, offsetof(struct task_struct, thread.regs.fr[ 9]));
110 DEFINE(TASK_PT_FR10, offsetof(struct task_struct, thread.regs.fr[10]));
111 DEFINE(TASK_PT_FR11, offsetof(struct task_struct, thread.regs.fr[11]));
112 DEFINE(TASK_PT_FR12, offsetof(struct task_struct, thread.regs.fr[12]));
113 DEFINE(TASK_PT_FR13, offsetof(struct task_struct, thread.regs.fr[13]));
114 DEFINE(TASK_PT_FR14, offsetof(struct task_struct, thread.regs.fr[14]));
115 DEFINE(TASK_PT_FR15, offsetof(struct task_struct, thread.regs.fr[15]));
116 DEFINE(TASK_PT_FR16, offsetof(struct task_struct, thread.regs.fr[16]));
117 DEFINE(TASK_PT_FR17, offsetof(struct task_struct, thread.regs.fr[17]));
118 DEFINE(TASK_PT_FR18, offsetof(struct task_struct, thread.regs.fr[18]));
119 DEFINE(TASK_PT_FR19, offsetof(struct task_struct, thread.regs.fr[19]));
120 DEFINE(TASK_PT_FR20, offsetof(struct task_struct, thread.regs.fr[20]));
121 DEFINE(TASK_PT_FR21, offsetof(struct task_struct, thread.regs.fr[21]));
122 DEFINE(TASK_PT_FR22, offsetof(struct task_struct, thread.regs.fr[22]));
123 DEFINE(TASK_PT_FR23, offsetof(struct task_struct, thread.regs.fr[23]));
124 DEFINE(TASK_PT_FR24, offsetof(struct task_struct, thread.regs.fr[24]));
125 DEFINE(TASK_PT_FR25, offsetof(struct task_struct, thread.regs.fr[25]));
126 DEFINE(TASK_PT_FR26, offsetof(struct task_struct, thread.regs.fr[26]));
127 DEFINE(TASK_PT_FR27, offsetof(struct task_struct, thread.regs.fr[27]));
128 DEFINE(TASK_PT_FR28, offsetof(struct task_struct, thread.regs.fr[28]));
129 DEFINE(TASK_PT_FR29, offsetof(struct task_struct, thread.regs.fr[29]));
130 DEFINE(TASK_PT_FR30, offsetof(struct task_struct, thread.regs.fr[30]));
131 DEFINE(TASK_PT_FR31, offsetof(struct task_struct, thread.regs.fr[31]));
132 DEFINE(TASK_PT_SR0, offsetof(struct task_struct, thread.regs.sr[ 0]));
133 DEFINE(TASK_PT_SR1, offsetof(struct task_struct, thread.regs.sr[ 1]));
134 DEFINE(TASK_PT_SR2, offsetof(struct task_struct, thread.regs.sr[ 2]));
135 DEFINE(TASK_PT_SR3, offsetof(struct task_struct, thread.regs.sr[ 3]));
136 DEFINE(TASK_PT_SR4, offsetof(struct task_struct, thread.regs.sr[ 4]));
137 DEFINE(TASK_PT_SR5, offsetof(struct task_struct, thread.regs.sr[ 5]));
138 DEFINE(TASK_PT_SR6, offsetof(struct task_struct, thread.regs.sr[ 6]));
139 DEFINE(TASK_PT_SR7, offsetof(struct task_struct, thread.regs.sr[ 7]));
140 DEFINE(TASK_PT_IASQ0, offsetof(struct task_struct, thread.regs.iasq[0]));
141 DEFINE(TASK_PT_IASQ1, offsetof(struct task_struct, thread.regs.iasq[1]));
142 DEFINE(TASK_PT_IAOQ0, offsetof(struct task_struct, thread.regs.iaoq[0]));
143 DEFINE(TASK_PT_IAOQ1, offsetof(struct task_struct, thread.regs.iaoq[1]));
144 DEFINE(TASK_PT_CR27, offsetof(struct task_struct, thread.regs.cr27));
145 DEFINE(TASK_PT_ORIG_R28, offsetof(struct task_struct, thread.regs.orig_r28));
146 DEFINE(TASK_PT_KSP, offsetof(struct task_struct, thread.regs.ksp));
147 DEFINE(TASK_PT_KPC, offsetof(struct task_struct, thread.regs.kpc));
148 DEFINE(TASK_PT_SAR, offsetof(struct task_struct, thread.regs.sar));
149 DEFINE(TASK_PT_IIR, offsetof(struct task_struct, thread.regs.iir));
150 DEFINE(TASK_PT_ISR, offsetof(struct task_struct, thread.regs.isr));
151 DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior));
152 BLANK();
153 DEFINE(TASK_SZ, sizeof(struct task_struct));
154 DEFINE(TASK_SZ_ALGN, align(sizeof(struct task_struct), 64));
155 BLANK();
156 DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0]));
157 DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1]));
158 DEFINE(PT_GR2, offsetof(struct pt_regs, gr[ 2]));
159 DEFINE(PT_GR3, offsetof(struct pt_regs, gr[ 3]));
160 DEFINE(PT_GR4, offsetof(struct pt_regs, gr[ 4]));
161 DEFINE(PT_GR5, offsetof(struct pt_regs, gr[ 5]));
162 DEFINE(PT_GR6, offsetof(struct pt_regs, gr[ 6]));
163 DEFINE(PT_GR7, offsetof(struct pt_regs, gr[ 7]));
164 DEFINE(PT_GR8, offsetof(struct pt_regs, gr[ 8]));
165 DEFINE(PT_GR9, offsetof(struct pt_regs, gr[ 9]));
166 DEFINE(PT_GR10, offsetof(struct pt_regs, gr[10]));
167 DEFINE(PT_GR11, offsetof(struct pt_regs, gr[11]));
168 DEFINE(PT_GR12, offsetof(struct pt_regs, gr[12]));
169 DEFINE(PT_GR13, offsetof(struct pt_regs, gr[13]));
170 DEFINE(PT_GR14, offsetof(struct pt_regs, gr[14]));
171 DEFINE(PT_GR15, offsetof(struct pt_regs, gr[15]));
172 DEFINE(PT_GR16, offsetof(struct pt_regs, gr[16]));
173 DEFINE(PT_GR17, offsetof(struct pt_regs, gr[17]));
174 DEFINE(PT_GR18, offsetof(struct pt_regs, gr[18]));
175 DEFINE(PT_GR19, offsetof(struct pt_regs, gr[19]));
176 DEFINE(PT_GR20, offsetof(struct pt_regs, gr[20]));
177 DEFINE(PT_GR21, offsetof(struct pt_regs, gr[21]));
178 DEFINE(PT_GR22, offsetof(struct pt_regs, gr[22]));
179 DEFINE(PT_GR23, offsetof(struct pt_regs, gr[23]));
180 DEFINE(PT_GR24, offsetof(struct pt_regs, gr[24]));
181 DEFINE(PT_GR25, offsetof(struct pt_regs, gr[25]));
182 DEFINE(PT_GR26, offsetof(struct pt_regs, gr[26]));
183 DEFINE(PT_GR27, offsetof(struct pt_regs, gr[27]));
184 DEFINE(PT_GR28, offsetof(struct pt_regs, gr[28]));
185 DEFINE(PT_GR29, offsetof(struct pt_regs, gr[29]));
186 DEFINE(PT_GR30, offsetof(struct pt_regs, gr[30]));
187 DEFINE(PT_GR31, offsetof(struct pt_regs, gr[31]));
188 DEFINE(PT_FR0, offsetof(struct pt_regs, fr[ 0]));
189 DEFINE(PT_FR1, offsetof(struct pt_regs, fr[ 1]));
190 DEFINE(PT_FR2, offsetof(struct pt_regs, fr[ 2]));
191 DEFINE(PT_FR3, offsetof(struct pt_regs, fr[ 3]));
192 DEFINE(PT_FR4, offsetof(struct pt_regs, fr[ 4]));
193 DEFINE(PT_FR5, offsetof(struct pt_regs, fr[ 5]));
194 DEFINE(PT_FR6, offsetof(struct pt_regs, fr[ 6]));
195 DEFINE(PT_FR7, offsetof(struct pt_regs, fr[ 7]));
196 DEFINE(PT_FR8, offsetof(struct pt_regs, fr[ 8]));
197 DEFINE(PT_FR9, offsetof(struct pt_regs, fr[ 9]));
198 DEFINE(PT_FR10, offsetof(struct pt_regs, fr[10]));
199 DEFINE(PT_FR11, offsetof(struct pt_regs, fr[11]));
200 DEFINE(PT_FR12, offsetof(struct pt_regs, fr[12]));
201 DEFINE(PT_FR13, offsetof(struct pt_regs, fr[13]));
202 DEFINE(PT_FR14, offsetof(struct pt_regs, fr[14]));
203 DEFINE(PT_FR15, offsetof(struct pt_regs, fr[15]));
204 DEFINE(PT_FR16, offsetof(struct pt_regs, fr[16]));
205 DEFINE(PT_FR17, offsetof(struct pt_regs, fr[17]));
206 DEFINE(PT_FR18, offsetof(struct pt_regs, fr[18]));
207 DEFINE(PT_FR19, offsetof(struct pt_regs, fr[19]));
208 DEFINE(PT_FR20, offsetof(struct pt_regs, fr[20]));
209 DEFINE(PT_FR21, offsetof(struct pt_regs, fr[21]));
210 DEFINE(PT_FR22, offsetof(struct pt_regs, fr[22]));
211 DEFINE(PT_FR23, offsetof(struct pt_regs, fr[23]));
212 DEFINE(PT_FR24, offsetof(struct pt_regs, fr[24]));
213 DEFINE(PT_FR25, offsetof(struct pt_regs, fr[25]));
214 DEFINE(PT_FR26, offsetof(struct pt_regs, fr[26]));
215 DEFINE(PT_FR27, offsetof(struct pt_regs, fr[27]));
216 DEFINE(PT_FR28, offsetof(struct pt_regs, fr[28]));
217 DEFINE(PT_FR29, offsetof(struct pt_regs, fr[29]));
218 DEFINE(PT_FR30, offsetof(struct pt_regs, fr[30]));
219 DEFINE(PT_FR31, offsetof(struct pt_regs, fr[31]));
220 DEFINE(PT_SR0, offsetof(struct pt_regs, sr[ 0]));
221 DEFINE(PT_SR1, offsetof(struct pt_regs, sr[ 1]));
222 DEFINE(PT_SR2, offsetof(struct pt_regs, sr[ 2]));
223 DEFINE(PT_SR3, offsetof(struct pt_regs, sr[ 3]));
224 DEFINE(PT_SR4, offsetof(struct pt_regs, sr[ 4]));
225 DEFINE(PT_SR5, offsetof(struct pt_regs, sr[ 5]));
226 DEFINE(PT_SR6, offsetof(struct pt_regs, sr[ 6]));
227 DEFINE(PT_SR7, offsetof(struct pt_regs, sr[ 7]));
228 DEFINE(PT_IASQ0, offsetof(struct pt_regs, iasq[0]));
229 DEFINE(PT_IASQ1, offsetof(struct pt_regs, iasq[1]));
230 DEFINE(PT_IAOQ0, offsetof(struct pt_regs, iaoq[0]));
231 DEFINE(PT_IAOQ1, offsetof(struct pt_regs, iaoq[1]));
232 DEFINE(PT_CR27, offsetof(struct pt_regs, cr27));
233 DEFINE(PT_ORIG_R28, offsetof(struct pt_regs, orig_r28));
234 DEFINE(PT_KSP, offsetof(struct pt_regs, ksp));
235 DEFINE(PT_KPC, offsetof(struct pt_regs, kpc));
236 DEFINE(PT_SAR, offsetof(struct pt_regs, sar));
237 DEFINE(PT_IIR, offsetof(struct pt_regs, iir));
238 DEFINE(PT_ISR, offsetof(struct pt_regs, isr));
239 DEFINE(PT_IOR, offsetof(struct pt_regs, ior));
240 DEFINE(PT_SIZE, sizeof(struct pt_regs));
241 DEFINE(PT_SZ_ALGN, align(sizeof(struct pt_regs), 64));
242 BLANK();
243 DEFINE(TI_TASK, offsetof(struct thread_info, task));
244 DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
245 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
246 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
247 DEFINE(TI_SEGMENT, offsetof(struct thread_info, addr_limit));
248 DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
249 DEFINE(THREAD_SZ, sizeof(struct thread_info));
250 DEFINE(THREAD_SZ_ALGN, align(sizeof(struct thread_info), 64));
251 BLANK();
252 DEFINE(IRQSTAT_SIRQ_PEND, offsetof(irq_cpustat_t, __softirq_pending));
253 DEFINE(IRQSTAT_SZ, sizeof(irq_cpustat_t));
254 BLANK();
255 DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
256 DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));
257 DEFINE(ICACHE_COUNT, offsetof(struct pdc_cache_info, ic_count));
258 DEFINE(ICACHE_LOOP, offsetof(struct pdc_cache_info, ic_loop));
259 DEFINE(DCACHE_BASE, offsetof(struct pdc_cache_info, dc_base));
260 DEFINE(DCACHE_STRIDE, offsetof(struct pdc_cache_info, dc_stride));
261 DEFINE(DCACHE_COUNT, offsetof(struct pdc_cache_info, dc_count));
262 DEFINE(DCACHE_LOOP, offsetof(struct pdc_cache_info, dc_loop));
263 DEFINE(ITLB_SID_BASE, offsetof(struct pdc_cache_info, it_sp_base));
264 DEFINE(ITLB_SID_STRIDE, offsetof(struct pdc_cache_info, it_sp_stride));
265 DEFINE(ITLB_SID_COUNT, offsetof(struct pdc_cache_info, it_sp_count));
266 DEFINE(ITLB_OFF_BASE, offsetof(struct pdc_cache_info, it_off_base));
267 DEFINE(ITLB_OFF_STRIDE, offsetof(struct pdc_cache_info, it_off_stride));
268 DEFINE(ITLB_OFF_COUNT, offsetof(struct pdc_cache_info, it_off_count));
269 DEFINE(ITLB_LOOP, offsetof(struct pdc_cache_info, it_loop));
270 DEFINE(DTLB_SID_BASE, offsetof(struct pdc_cache_info, dt_sp_base));
271 DEFINE(DTLB_SID_STRIDE, offsetof(struct pdc_cache_info, dt_sp_stride));
272 DEFINE(DTLB_SID_COUNT, offsetof(struct pdc_cache_info, dt_sp_count));
273 DEFINE(DTLB_OFF_BASE, offsetof(struct pdc_cache_info, dt_off_base));
274 DEFINE(DTLB_OFF_STRIDE, offsetof(struct pdc_cache_info, dt_off_stride));
275 DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
276 DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
277 BLANK();
278 DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT);
279 DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT);
280 BLANK();
281 DEFINE(ASM_PMD_SHIFT, PMD_SHIFT);
282 DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT);
283 DEFINE(ASM_BITS_PER_PGD, BITS_PER_PGD);
284 DEFINE(ASM_BITS_PER_PMD, BITS_PER_PMD);
285 DEFINE(ASM_BITS_PER_PTE, BITS_PER_PTE);
286 DEFINE(ASM_PGD_PMD_OFFSET, -(PAGE_SIZE << PGD_ORDER));
287 DEFINE(ASM_PMD_ENTRY, ((PAGE_OFFSET & PMD_MASK) >> PMD_SHIFT));
288 DEFINE(ASM_PGD_ENTRY, PAGE_OFFSET >> PGDIR_SHIFT);
289 DEFINE(ASM_PGD_ENTRY_SIZE, PGD_ENTRY_SIZE);
290 DEFINE(ASM_PMD_ENTRY_SIZE, PMD_ENTRY_SIZE);
291 DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE);
292 DEFINE(ASM_PT_INITIAL, PT_INITIAL);
293 DEFINE(ASM_PAGE_SIZE, PAGE_SIZE);
294 BLANK();
295 DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
296 DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
297 DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
298 return 0;
299}
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
new file mode 100644
index 000000000000..d1833f164bbe
--- /dev/null
+++ b/arch/parisc/kernel/binfmt_elf32.c
@@ -0,0 +1,126 @@
1/*
2 * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels
3 *
4 * Copyright (C) 2000 John Marvin
5 * Copyright (C) 2000 Hewlett Packard Co.
6 *
7 * Heavily inspired from various other efforts to do the same thing
8 * (ia64,sparc64/mips64)
9 */
10
11/* Make sure include/asm-parisc/elf.h does the right thing */
12
13#define ELF_CLASS ELFCLASS32
14
15#define ELF_CORE_COPY_REGS(dst, pt) \
16 memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \
17 { int i; \
18 for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
19 for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
20 } \
21 dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
22 dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
23 dst[44] = (elf_greg_t) pt->sar; dst[45] = (elf_greg_t) pt->iir; \
24 dst[46] = (elf_greg_t) pt->isr; dst[47] = (elf_greg_t) pt->ior; \
25 dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
26 dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
27 dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
28 dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
29 dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
30 dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
31 dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
32 dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
33
34
35typedef unsigned int elf_greg_t;
36
37#include <linux/spinlock.h>
38#include <asm/processor.h>
39#include <linux/module.h>
40#include <linux/elfcore.h>
41#include <linux/compat.h> /* struct compat_timeval */
42
43#define elf_prstatus elf_prstatus32
44struct elf_prstatus32
45{
46 struct elf_siginfo pr_info; /* Info associated with signal */
47 short pr_cursig; /* Current signal */
48 unsigned int pr_sigpend; /* Set of pending signals */
49 unsigned int pr_sighold; /* Set of held signals */
50 pid_t pr_pid;
51 pid_t pr_ppid;
52 pid_t pr_pgrp;
53 pid_t pr_sid;
54 struct compat_timeval pr_utime; /* User time */
55 struct compat_timeval pr_stime; /* System time */
56 struct compat_timeval pr_cutime; /* Cumulative user time */
57 struct compat_timeval pr_cstime; /* Cumulative system time */
58 elf_gregset_t pr_reg; /* GP registers */
59 int pr_fpvalid; /* True if math co-processor being used. */
60};
61
62#define elf_prpsinfo elf_prpsinfo32
63struct elf_prpsinfo32
64{
65 char pr_state; /* numeric process state */
66 char pr_sname; /* char for pr_state */
67 char pr_zomb; /* zombie */
68 char pr_nice; /* nice val */
69 unsigned int pr_flag; /* flags */
70 u16 pr_uid;
71 u16 pr_gid;
72 pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
73 /* Lots missing */
74 char pr_fname[16]; /* filename of executable */
75 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
76};
77
78#define elf_addr_t unsigned int
79#define init_elf_binfmt init_elf32_binfmt
80
81#define ELF_PLATFORM ("PARISC32\0")
82
83/*
84 * We should probably use this macro to set a flag somewhere to indicate
85 * this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we
86 * could set a processor dependent flag in the thread_struct.
87 */
88
89#define SET_PERSONALITY(ex, ibcs2) \
90 current->personality = PER_LINUX32; \
91 current->thread.map_base = DEFAULT_MAP_BASE32; \
92 current->thread.task_size = DEFAULT_TASK_SIZE32 \
93
94#undef cputime_to_timeval
95#define cputime_to_timeval cputime_to_compat_timeval
96static __inline__ void
97cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
98{
99 unsigned long jiffies = cputime_to_jiffies(cputime);
100 value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
101 value->tv_sec = jiffies / HZ;
102}
103
104#include "../../../fs/binfmt_elf.c"
105
106/* Set up a separate execution domain for ELF32 binaries running
107 * on an ELF64 kernel */
108
109static struct exec_domain parisc32_exec_domain = {
110 .name = "Linux/ELF32",
111 .pers_low = PER_LINUX32,
112 .pers_high = PER_LINUX32,
113};
114
115static int __init parisc32_exec_init(void)
116{
117 /* steal the identity signal mappings from the default domain */
118 parisc32_exec_domain.signal_map = default_exec_domain.signal_map;
119 parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
120
121 register_exec_domain(&parisc32_exec_domain);
122
123 return 0;
124}
125
126__initcall(parisc32_exec_init);
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
new file mode 100644
index 000000000000..f46a07a79218
--- /dev/null
+++ b/arch/parisc/kernel/cache.c
@@ -0,0 +1,366 @@
1/* $Id: cache.c,v 1.4 2000/01/25 00:11:38 prumpf Exp $
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1999 Helge Deller (07-13-1999)
8 * Copyright (C) 1999 SuSE GmbH Nuernberg
9 * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org)
10 *
11 * Cache and TLB management
12 *
13 */
14
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/mm.h>
18#include <linux/module.h>
19#include <linux/seq_file.h>
20#include <linux/pagemap.h>
21
22#include <asm/pdc.h>
23#include <asm/cache.h>
24#include <asm/cacheflush.h>
25#include <asm/tlbflush.h>
26#include <asm/system.h>
27#include <asm/page.h>
28#include <asm/pgalloc.h>
29#include <asm/processor.h>
30
31int split_tlb;
32int dcache_stride;
33int icache_stride;
34EXPORT_SYMBOL(dcache_stride);
35
36
37#if defined(CONFIG_SMP)
38/* On some machines (e.g. ones with the Merced bus), there can be
39 * only a single PxTLB broadcast at a time; this must be guaranteed
40 * by software. We put a spinlock around all TLB flushes to
41 * ensure this.
42 */
43DEFINE_SPINLOCK(pa_tlb_lock);
44EXPORT_SYMBOL(pa_tlb_lock);
45#endif
46
47struct pdc_cache_info cache_info;
48#ifndef CONFIG_PA20
49static struct pdc_btlb_info btlb_info;
50#endif
51
52#ifdef CONFIG_SMP
53void
54flush_data_cache(void)
55{
56 on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
57}
58void
59flush_instruction_cache(void)
60{
61 on_each_cpu((void (*)(void *))flush_instruction_cache_local, NULL, 1, 1);
62}
63#endif
64
65void
66flush_cache_all_local(void)
67{
68 flush_instruction_cache_local();
69 flush_data_cache_local();
70}
71EXPORT_SYMBOL(flush_cache_all_local);
72
73/* flushes EVERYTHING (tlb & cache) */
74
75void
76flush_all_caches(void)
77{
78 flush_cache_all();
79 flush_tlb_all();
80}
81EXPORT_SYMBOL(flush_all_caches);
82
83void
84update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
85{
86 struct page *page = pte_page(pte);
87
88 if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
89 test_bit(PG_dcache_dirty, &page->flags)) {
90
91 flush_kernel_dcache_page(page_address(page));
92 clear_bit(PG_dcache_dirty, &page->flags);
93 }
94}
95
96void
97show_cache_info(struct seq_file *m)
98{
99 seq_printf(m, "I-cache\t\t: %ld KB\n",
100 cache_info.ic_size/1024 );
101 seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n",
102 cache_info.dc_size/1024,
103 (cache_info.dc_conf.cc_wt ? "WT":"WB"),
104 (cache_info.dc_conf.cc_sh ? ", shared I/D":""),
105 (cache_info.dc_conf.cc_assoc)
106 );
107
108 seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
109 cache_info.it_size,
110 cache_info.dt_size,
111 cache_info.dt_conf.tc_sh ? " - shared with ITLB":""
112 );
113
114#ifndef CONFIG_PA20
115 /* BTLB - Block TLB */
116 if (btlb_info.max_size==0) {
117 seq_printf(m, "BTLB\t\t: not supported\n" );
118 } else {
119 seq_printf(m,
120 "BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"
121 "BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"
122 "BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",
123 btlb_info.max_size, (int)4096,
124 btlb_info.max_size>>8,
125 btlb_info.fixed_range_info.num_i,
126 btlb_info.fixed_range_info.num_d,
127 btlb_info.fixed_range_info.num_comb,
128 btlb_info.variable_range_info.num_i,
129 btlb_info.variable_range_info.num_d,
130 btlb_info.variable_range_info.num_comb
131 );
132 }
133#endif
134}
135
136void __init
137parisc_cache_init(void)
138{
139 if (pdc_cache_info(&cache_info) < 0)
140 panic("parisc_cache_init: pdc_cache_info failed");
141
142#if 0
143 printk("ic_size %lx dc_size %lx it_size %lx\n",
144 cache_info.ic_size,
145 cache_info.dc_size,
146 cache_info.it_size);
147
148 printk("DC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
149 cache_info.dc_base,
150 cache_info.dc_stride,
151 cache_info.dc_count,
152 cache_info.dc_loop);
153
154 printk("dc_conf = 0x%lx alias %d blk %d line %d shift %d\n",
155 *(unsigned long *) (&cache_info.dc_conf),
156 cache_info.dc_conf.cc_alias,
157 cache_info.dc_conf.cc_block,
158 cache_info.dc_conf.cc_line,
159 cache_info.dc_conf.cc_shift);
160 printk(" wt %d sh %d cst %d assoc %d\n",
161 cache_info.dc_conf.cc_wt,
162 cache_info.dc_conf.cc_sh,
163 cache_info.dc_conf.cc_cst,
164 cache_info.dc_conf.cc_assoc);
165
166 printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
167 cache_info.ic_base,
168 cache_info.ic_stride,
169 cache_info.ic_count,
170 cache_info.ic_loop);
171
172 printk("ic_conf = 0x%lx alias %d blk %d line %d shift %d\n",
173 *(unsigned long *) (&cache_info.ic_conf),
174 cache_info.ic_conf.cc_alias,
175 cache_info.ic_conf.cc_block,
176 cache_info.ic_conf.cc_line,
177 cache_info.ic_conf.cc_shift);
178 printk(" wt %d sh %d cst %d assoc %d\n",
179 cache_info.ic_conf.cc_wt,
180 cache_info.ic_conf.cc_sh,
181 cache_info.ic_conf.cc_cst,
182 cache_info.ic_conf.cc_assoc);
183
184 printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
185 cache_info.dt_conf.tc_sh,
186 cache_info.dt_conf.tc_page,
187 cache_info.dt_conf.tc_cst,
188 cache_info.dt_conf.tc_aid,
189 cache_info.dt_conf.tc_pad1);
190
191 printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
192 cache_info.it_conf.tc_sh,
193 cache_info.it_conf.tc_page,
194 cache_info.it_conf.tc_cst,
195 cache_info.it_conf.tc_aid,
196 cache_info.it_conf.tc_pad1);
197#endif
198
199 split_tlb = 0;
200 if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) {
201 if (cache_info.dt_conf.tc_sh == 2)
202 printk(KERN_WARNING "Unexpected TLB configuration. "
203 "Will flush I/D separately (could be optimized).\n");
204
205 split_tlb = 1;
206 }
207
208 /* "New and Improved" version from Jim Hull
209 * (1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift))
210 */
211#define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift))
212 dcache_stride = CAFL_STRIDE(cache_info.dc_conf);
213 icache_stride = CAFL_STRIDE(cache_info.ic_conf);
214#undef CAFL_STRIDE
215
216#ifndef CONFIG_PA20
217 if (pdc_btlb_info(&btlb_info) < 0) {
218 memset(&btlb_info, 0, sizeof btlb_info);
219 }
220#endif
221
222 if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) ==
223 PDC_MODEL_NVA_UNSUPPORTED) {
224 printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n");
225#if 0
226 panic("SMP kernel required to avoid non-equivalent aliasing");
227#endif
228 }
229}
230
231void disable_sr_hashing(void)
232{
233 int srhash_type;
234
235 switch (boot_cpu_data.cpu_type) {
236 case pcx: /* We shouldn't get this far. setup.c should prevent it. */
237 BUG();
238 return;
239
240 case pcxs:
241 case pcxt:
242 case pcxt_:
243 srhash_type = SRHASH_PCXST;
244 break;
245
246 case pcxl:
247 srhash_type = SRHASH_PCXL;
248 break;
249
250 case pcxl2: /* pcxl2 doesn't support space register hashing */
251 return;
252
253 default: /* Currently all PA2.0 machines use the same ins. sequence */
254 srhash_type = SRHASH_PA20;
255 break;
256 }
257
258 disable_sr_hashing_asm(srhash_type);
259}
260
261void flush_dcache_page(struct page *page)
262{
263 struct address_space *mapping = page_mapping(page);
264 struct vm_area_struct *mpnt;
265 struct prio_tree_iter iter;
266 unsigned long offset;
267 unsigned long addr;
268 pgoff_t pgoff;
269 pte_t *pte;
270 unsigned long pfn = page_to_pfn(page);
271
272
273 if (mapping && !mapping_mapped(mapping)) {
274 set_bit(PG_dcache_dirty, &page->flags);
275 return;
276 }
277
278 flush_kernel_dcache_page(page_address(page));
279
280 if (!mapping)
281 return;
282
283 pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
284
285 /* We have carefully arranged in arch_get_unmapped_area() that
286 * *any* mappings of a file are always congruently mapped (whether
287 * declared as MAP_PRIVATE or MAP_SHARED), so we only need
288 * to flush one address here for them all to become coherent */
289
290 flush_dcache_mmap_lock(mapping);
291 vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
292 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
293 addr = mpnt->vm_start + offset;
294
295 /* Flush instructions produce non access tlb misses.
296 * On PA, we nullify these instructions rather than
297 * taking a page fault if the pte doesn't exist.
298 * This is just for speed. If the page translation
299 * isn't there, there's no point exciting the
300 * nadtlb handler into a nullification frenzy */
301
302
303 if(!(pte = translation_exists(mpnt, addr)))
304 continue;
305
306 /* make sure we really have this page: the private
307 * mappings may cover this area but have COW'd this
308 * particular page */
309 if(pte_pfn(*pte) != pfn)
310 continue;
311
312 __flush_cache_page(mpnt, addr);
313
314 break;
315 }
316 flush_dcache_mmap_unlock(mapping);
317}
318EXPORT_SYMBOL(flush_dcache_page);
319
320/* Defined in arch/parisc/kernel/pacache.S */
321EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
322EXPORT_SYMBOL(flush_kernel_dcache_page);
323EXPORT_SYMBOL(flush_data_cache_local);
324EXPORT_SYMBOL(flush_kernel_icache_range_asm);
325
326void clear_user_page_asm(void *page, unsigned long vaddr)
327{
328 /* This function is implemented in assembly in pacache.S */
329 extern void __clear_user_page_asm(void *page, unsigned long vaddr);
330
331 purge_tlb_start();
332 __clear_user_page_asm(page, vaddr);
333 purge_tlb_end();
334}
335
336#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
337int parisc_cache_flush_threshold = FLUSH_THRESHOLD;
338
339void parisc_setup_cache_timing(void)
340{
341 unsigned long rangetime, alltime;
342 extern char _text; /* start of kernel code, defined by linker */
343 extern char _end; /* end of BSS, defined by linker */
344 unsigned long size;
345
346 alltime = mfctl(16);
347 flush_data_cache();
348 alltime = mfctl(16) - alltime;
349
350 size = (unsigned long)(&_end - _text);
351 rangetime = mfctl(16);
352 flush_kernel_dcache_range((unsigned long)&_text, size);
353 rangetime = mfctl(16) - rangetime;
354
355 printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
356 alltime, size, rangetime);
357
358 /* Racy, but if we see an intermediate value, it's ok too... */
359 parisc_cache_flush_threshold = size * alltime / rangetime;
360
361 parisc_cache_flush_threshold = (parisc_cache_flush_threshold + L1_CACHE_BYTES - 1) &~ (L1_CACHE_BYTES - 1);
362 if (!parisc_cache_flush_threshold)
363 parisc_cache_flush_threshold = FLUSH_THRESHOLD;
364
365 printk("Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
366}
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
new file mode 100644
index 000000000000..ebf186656afb
--- /dev/null
+++ b/arch/parisc/kernel/drivers.c
@@ -0,0 +1,765 @@
1/*
2 * drivers.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Copyright (c) 1999 The Puffin Group
10 * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
11 * Copyright (c) 2001 Helge Deller <deller@gmx.de>
12 * Copyright (c) 2001,2002 Ryan Bradetich
13 * Copyright (c) 2004-2005 Thibaut VARENE <varenet@parisc-linux.org>
14 *
15 * The file handles registering devices and drivers, then matching them.
16 * It's the closest we get to a dating agency.
17 *
18 * If you're thinking about modifying this file, here are some gotchas to
19 * bear in mind:
20 * - 715/Mirage device paths have a dummy device between Lasi and its children
21 * - The EISA adapter may show up as a sibling or child of Wax
22 * - Dino has an optionally functional serial port. If firmware enables it,
23 * it shows up as a child of Dino. If firmware disables it, the buswalk
24 * finds it and it shows up as a child of Cujo
25 * - Dino has both parisc and pci devices as children
26 * - parisc devices are discovered in a random order, including children
27 * before parents in some cases.
28 */
29
30#include <linux/slab.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/pci.h>
34#include <linux/spinlock.h>
35#include <linux/string.h>
36#include <asm/hardware.h>
37#include <asm/io.h>
38#include <asm/pdc.h>
39#include <asm/parisc-device.h>
40
41/* See comments in include/asm-parisc/pci.h */
42struct hppa_dma_ops *hppa_dma_ops;
43EXPORT_SYMBOL(hppa_dma_ops);
44
45static struct device root = {
46 .bus_id = "parisc",
47};
48
49#define for_each_padev(padev) \
50 for (padev = next_dev(&root); padev != NULL; \
51 padev = next_dev(&padev->dev))
52
53#define check_dev(padev) \
54 (padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev)
55
56/**
57 * next_dev - enumerates registered devices
58 * @dev: the previous device returned from next_dev
59 *
60 * next_dev does a depth-first search of the tree, returning parents
61 * before children. Returns NULL when there are no more devices.
62 */
63static struct parisc_device *next_dev(struct device *dev)
64{
65 if (!list_empty(&dev->children)) {
66 dev = list_to_dev(dev->children.next);
67 return check_dev(to_parisc_device(dev));
68 }
69
70 while (dev != &root) {
71 if (dev->node.next != &dev->parent->children) {
72 dev = list_to_dev(dev->node.next);
73 return to_parisc_device(dev);
74 }
75 dev = dev->parent;
76 }
77
78 return NULL;
79}
80
81/**
82 * match_device - Report whether this driver can handle this device
83 * @driver: the PA-RISC driver to try
84 * @dev: the PA-RISC device to try
85 */
86static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
87{
88 const struct parisc_device_id *ids;
89
90 for (ids = driver->id_table; ids->sversion; ids++) {
91 if ((ids->sversion != SVERSION_ANY_ID) &&
92 (ids->sversion != dev->id.sversion))
93 continue;
94
95 if ((ids->hw_type != HWTYPE_ANY_ID) &&
96 (ids->hw_type != dev->id.hw_type))
97 continue;
98
99 if ((ids->hversion != HVERSION_ANY_ID) &&
100 (ids->hversion != dev->id.hversion))
101 continue;
102
103 return 1;
104 }
105 return 0;
106}
107
108static void claim_device(struct parisc_driver *driver, struct parisc_device *dev)
109{
110 dev->driver = driver;
111 request_mem_region(dev->hpa, 0x1000, driver->name);
112}
113
114static int parisc_driver_probe(struct device *dev)
115{
116 int rc;
117 struct parisc_device *pa_dev = to_parisc_device(dev);
118 struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
119
120 rc = pa_drv->probe(pa_dev);
121
122 if(!rc)
123 claim_device(pa_drv, pa_dev);
124
125 return rc;
126}
127
128static int parisc_driver_remove(struct device *dev)
129{
130 struct parisc_device *pa_dev = to_parisc_device(dev);
131 struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
132 if (pa_drv->remove)
133 pa_drv->remove(pa_dev);
134 release_mem_region(pa_dev->hpa, 0x1000);
135
136 return 0;
137}
138
139
140/**
141 * register_parisc_driver - Register this driver if it can handle a device
142 * @driver: the PA-RISC driver to try
143 */
144int register_parisc_driver(struct parisc_driver *driver)
145{
146 /* FIXME: we need this because apparently the sti
147 * driver can be registered twice */
148 if(driver->drv.name) {
149 printk(KERN_WARNING
150 "BUG: skipping previously registered driver %s\n",
151 driver->name);
152 return 1;
153 }
154
155 if (!driver->probe) {
156 printk(KERN_WARNING
157 "BUG: driver %s has no probe routine\n",
158 driver->name);
159 return 1;
160 }
161
162 driver->drv.bus = &parisc_bus_type;
163
164 /* We install our own probe and remove routines */
165 WARN_ON(driver->drv.probe != NULL);
166 WARN_ON(driver->drv.remove != NULL);
167
168 driver->drv.probe = parisc_driver_probe;
169 driver->drv.remove = parisc_driver_remove;
170 driver->drv.name = driver->name;
171
172 return driver_register(&driver->drv);
173}
174EXPORT_SYMBOL(register_parisc_driver);
175
176/**
177 * count_parisc_driver - count # of devices this driver would match
178 * @driver: the PA-RISC driver to try
179 *
180 * Use by IOMMU support to "guess" the right size IOPdir.
181 * Formula is something like memsize/(num_iommu * entry_size).
182 */
183int count_parisc_driver(struct parisc_driver *driver)
184{
185 struct parisc_device *device;
186 int cnt = 0;
187
188 for_each_padev(device) {
189 if (match_device(driver, device))
190 cnt++;
191 }
192
193 return cnt;
194}
195
196
197
198/**
199 * unregister_parisc_driver - Unregister this driver from the list of drivers
200 * @driver: the PA-RISC driver to unregister
201 */
202int unregister_parisc_driver(struct parisc_driver *driver)
203{
204 driver_unregister(&driver->drv);
205 return 0;
206}
207EXPORT_SYMBOL(unregister_parisc_driver);
208
209static struct parisc_device *find_device_by_addr(unsigned long hpa)
210{
211 struct parisc_device *dev;
212 for_each_padev(dev) {
213 if (dev->hpa == hpa)
214 return dev;
215 }
216 return NULL;
217}
218
219/**
220 * find_pa_parent_type - Find a parent of a specific type
221 * @dev: The device to start searching from
222 * @type: The device type to search for.
223 *
224 * Walks up the device tree looking for a device of the specified type.
225 * If it finds it, it returns it. If not, it returns NULL.
226 */
227const struct parisc_device *
228find_pa_parent_type(const struct parisc_device *padev, int type)
229{
230 const struct device *dev = &padev->dev;
231 while (dev != &root) {
232 struct parisc_device *candidate = to_parisc_device(dev);
233 if (candidate->id.hw_type == type)
234 return candidate;
235 dev = dev->parent;
236 }
237
238 return NULL;
239}
240
241#ifdef CONFIG_PCI
242static inline int is_pci_dev(struct device *dev)
243{
244 return dev->bus == &pci_bus_type;
245}
246#else
247static inline int is_pci_dev(struct device *dev)
248{
249 return 0;
250}
251#endif
252
253/*
254 * get_node_path fills in @path with the firmware path to the device.
255 * Note that if @node is a parisc device, we don't fill in the 'mod' field.
256 * This is because both callers pass the parent and fill in the mod
257 * themselves. If @node is a PCI device, we do fill it in, even though this
258 * is inconsistent.
259 */
260static void get_node_path(struct device *dev, struct hardware_path *path)
261{
262 int i = 5;
263 memset(&path->bc, -1, 6);
264
265 if (is_pci_dev(dev)) {
266 unsigned int devfn = to_pci_dev(dev)->devfn;
267 path->mod = PCI_FUNC(devfn);
268 path->bc[i--] = PCI_SLOT(devfn);
269 dev = dev->parent;
270 }
271
272 while (dev != &root) {
273 if (is_pci_dev(dev)) {
274 unsigned int devfn = to_pci_dev(dev)->devfn;
275 path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
276 } else if (dev->bus == &parisc_bus_type) {
277 path->bc[i--] = to_parisc_device(dev)->hw_path;
278 }
279 dev = dev->parent;
280 }
281}
282
283static char *print_hwpath(struct hardware_path *path, char *output)
284{
285 int i;
286 for (i = 0; i < 6; i++) {
287 if (path->bc[i] == -1)
288 continue;
289 output += sprintf(output, "%u/", (unsigned char) path->bc[i]);
290 }
291 output += sprintf(output, "%u", (unsigned char) path->mod);
292 return output;
293}
294
295/**
296 * print_pa_hwpath - Returns hardware path for PA devices
297 * dev: The device to return the path for
298 * output: Pointer to a previously-allocated array to place the path in.
299 *
300 * This function fills in the output array with a human-readable path
301 * to a PA device. This string is compatible with that used by PDC, and
302 * may be printed on the outside of the box.
303 */
304char *print_pa_hwpath(struct parisc_device *dev, char *output)
305{
306 struct hardware_path path;
307
308 get_node_path(dev->dev.parent, &path);
309 path.mod = dev->hw_path;
310 return print_hwpath(&path, output);
311}
312EXPORT_SYMBOL(print_pa_hwpath);
313
314#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
315/**
316 * get_pci_node_path - Determines the hardware path for a PCI device
317 * @pdev: The device to return the path for
318 * @path: Pointer to a previously-allocated array to place the path in.
319 *
320 * This function fills in the hardware_path structure with the route to
321 * the specified PCI device. This structure is suitable for passing to
322 * PDC calls.
323 */
324void get_pci_node_path(struct pci_dev *pdev, struct hardware_path *path)
325{
326 get_node_path(&pdev->dev, path);
327}
328EXPORT_SYMBOL(get_pci_node_path);
329
330/**
331 * print_pci_hwpath - Returns hardware path for PCI devices
332 * dev: The device to return the path for
333 * output: Pointer to a previously-allocated array to place the path in.
334 *
335 * This function fills in the output array with a human-readable path
336 * to a PCI device. This string is compatible with that used by PDC, and
337 * may be printed on the outside of the box.
338 */
339char *print_pci_hwpath(struct pci_dev *dev, char *output)
340{
341 struct hardware_path path;
342
343 get_pci_node_path(dev, &path);
344 return print_hwpath(&path, output);
345}
346EXPORT_SYMBOL(print_pci_hwpath);
347
348#endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
349
350static void setup_bus_id(struct parisc_device *padev)
351{
352 struct hardware_path path;
353 char *output = padev->dev.bus_id;
354 int i;
355
356 get_node_path(padev->dev.parent, &path);
357
358 for (i = 0; i < 6; i++) {
359 if (path.bc[i] == -1)
360 continue;
361 output += sprintf(output, "%u:", (unsigned char) path.bc[i]);
362 }
363 sprintf(output, "%u", (unsigned char) padev->hw_path);
364}
365
366struct parisc_device * create_tree_node(char id, struct device *parent)
367{
368 struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
369 if (!dev)
370 return NULL;
371
372 memset(dev, 0, sizeof(*dev));
373 dev->hw_path = id;
374 dev->id.hw_type = HPHW_FAULTY;
375
376 dev->dev.parent = parent;
377 setup_bus_id(dev);
378
379 dev->dev.bus = &parisc_bus_type;
380 dev->dma_mask = 0xffffffffUL; /* PARISC devices are 32-bit */
381
382 /* make the generic dma mask a pointer to the parisc one */
383 dev->dev.dma_mask = &dev->dma_mask;
384 dev->dev.coherent_dma_mask = dev->dma_mask;
385 device_register(&dev->dev);
386
387 return dev;
388}
389
390/**
391 * alloc_tree_node - returns a device entry in the iotree
392 * @parent: the parent node in the tree
393 * @id: the element of the module path for this entry
394 *
395 * Checks all the children of @parent for a matching @id. If none
396 * found, it allocates a new device and returns it.
397 */
398static struct parisc_device * alloc_tree_node(struct device *parent, char id)
399{
400 struct device *dev;
401
402 list_for_each_entry(dev, &parent->children, node) {
403 struct parisc_device *padev = to_parisc_device(dev);
404 if (padev->hw_path == id)
405 return padev;
406 }
407
408 return create_tree_node(id, parent);
409}
410
411static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
412{
413 int i;
414 struct device *parent = &root;
415 for (i = 0; i < 6; i++) {
416 if (modpath->bc[i] == -1)
417 continue;
418 parent = &alloc_tree_node(parent, modpath->bc[i])->dev;
419 }
420 return alloc_tree_node(parent, modpath->mod);
421}
422
423struct parisc_device *
424alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
425{
426 int status;
427 unsigned long bytecnt;
428 u8 iodc_data[32];
429 struct parisc_device *dev;
430 const char *name;
431
432 /* Check to make sure this device has not already been added - Ryan */
433 if (find_device_by_addr(hpa) != NULL)
434 return NULL;
435
436 status = pdc_iodc_read(&bytecnt, hpa, 0, &iodc_data, 32);
437 if (status != PDC_OK)
438 return NULL;
439
440 dev = create_parisc_device(mod_path);
441 if (dev->id.hw_type != HPHW_FAULTY) {
442 char p[64];
443 print_pa_hwpath(dev, p);
444 printk("Two devices have hardware path %s. Please file a bug with HP.\n"
445 "In the meantime, you could try rearranging your cards.\n", p);
446 return NULL;
447 }
448
449 dev->id.hw_type = iodc_data[3] & 0x1f;
450 dev->id.hversion = (iodc_data[0] << 4) | ((iodc_data[1] & 0xf0) >> 4);
451 dev->id.hversion_rev = iodc_data[1] & 0x0f;
452 dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
453 (iodc_data[5] << 8) | iodc_data[6];
454 dev->hpa = hpa;
455 name = parisc_hardware_description(&dev->id);
456 if (name) {
457 strlcpy(dev->name, name, sizeof(dev->name));
458 }
459
460 return dev;
461}
462
463static int parisc_generic_match(struct device *dev, struct device_driver *drv)
464{
465 return match_device(to_parisc_driver(drv), to_parisc_device(dev));
466}
467
468#define pa_dev_attr(name, field, format_string) \
469static ssize_t name##_show(struct device *dev, char *buf) \
470{ \
471 struct parisc_device *padev = to_parisc_device(dev); \
472 return sprintf(buf, format_string, padev->field); \
473}
474
475#define pa_dev_attr_id(field, format) pa_dev_attr(field, id.field, format)
476
477pa_dev_attr(irq, irq, "%u\n");
478pa_dev_attr_id(hw_type, "0x%02x\n");
479pa_dev_attr(rev, id.hversion_rev, "0x%x\n");
480pa_dev_attr_id(hversion, "0x%03x\n");
481pa_dev_attr_id(sversion, "0x%05x\n");
482
483static struct device_attribute parisc_device_attrs[] = {
484 __ATTR_RO(irq),
485 __ATTR_RO(hw_type),
486 __ATTR_RO(rev),
487 __ATTR_RO(hversion),
488 __ATTR_RO(sversion),
489 __ATTR_NULL,
490};
491
492struct bus_type parisc_bus_type = {
493 .name = "parisc",
494 .match = parisc_generic_match,
495 .dev_attrs = parisc_device_attrs,
496};
497
498/**
499 * register_parisc_device - Locate a driver to manage this device.
500 * @dev: The parisc device.
501 *
502 * Search the driver list for a driver that is willing to manage
503 * this device.
504 */
505int register_parisc_device(struct parisc_device *dev)
506{
507 if (!dev)
508 return 0;
509
510 if (dev->driver)
511 return 1;
512
513 return 0;
514}
515
516/**
517 * match_pci_device - Matches a pci device against a given hardware path
518 * entry.
519 * @dev: the generic device (known to be contained by a pci_dev).
520 * @index: the current BC index
521 * @modpath: the hardware path.
522 * @return: true if the device matches the hardware path.
523 */
524static int match_pci_device(struct device *dev, int index,
525 struct hardware_path *modpath)
526{
527 struct pci_dev *pdev = to_pci_dev(dev);
528 int id;
529
530 if (index == 5) {
531 /* we are at the end of the path, and on the actual device */
532 unsigned int devfn = pdev->devfn;
533 return ((modpath->bc[5] == PCI_SLOT(devfn)) &&
534 (modpath->mod == PCI_FUNC(devfn)));
535 }
536
537 id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5);
538 return (modpath->bc[index] == id);
539}
540
541/**
542 * match_parisc_device - Matches a parisc device against a given hardware
543 * path entry.
544 * @dev: the generic device (known to be contained by a parisc_device).
545 * @index: the current BC index
546 * @modpath: the hardware path.
547 * @return: true if the device matches the hardware path.
548 */
549static int match_parisc_device(struct device *dev, int index,
550 struct hardware_path *modpath)
551{
552 struct parisc_device *curr = to_parisc_device(dev);
553 char id = (index == 6) ? modpath->mod : modpath->bc[index];
554
555 return (curr->hw_path == id);
556}
557
558/**
559 * parse_tree_node - returns a device entry in the iotree
560 * @parent: the parent node in the tree
561 * @index: the current BC index
562 * @modpath: the hardware_path struct to match a device against
563 * @return: The corresponding device if found, NULL otherwise.
564 *
565 * Checks all the children of @parent for a matching @id. If none
566 * found, it returns NULL.
567 */
568static struct device *
569parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
570{
571 struct device *device;
572
573 list_for_each_entry(device, &parent->children, node) {
574 if (device->bus == &parisc_bus_type) {
575 if (match_parisc_device(device, index, modpath))
576 return device;
577 } else if (is_pci_dev(device)) {
578 if (match_pci_device(device, index, modpath))
579 return device;
580 } else if (device->bus == NULL) {
581 /* we are on a bus bridge */
582 struct device *new = parse_tree_node(device, index, modpath);
583 if (new)
584 return new;
585 }
586 }
587
588 return NULL;
589}
590
591/**
592 * hwpath_to_device - Finds the generic device corresponding to a given hardware path.
593 * @modpath: the hardware path.
594 * @return: The target device, NULL if not found.
595 */
596struct device *hwpath_to_device(struct hardware_path *modpath)
597{
598 int i;
599 struct device *parent = &root;
600 for (i = 0; i < 6; i++) {
601 if (modpath->bc[i] == -1)
602 continue;
603 parent = parse_tree_node(parent, i, modpath);
604 if (!parent)
605 return NULL;
606 }
607 if (is_pci_dev(parent)) /* pci devices already parse MOD */
608 return parent;
609 else
610 return parse_tree_node(parent, 6, modpath);
611}
612EXPORT_SYMBOL(hwpath_to_device);
613
614/**
615 * device_to_hwpath - Populates the hwpath corresponding to the given device.
616 * @param dev the target device
617 * @param path pointer to a previously allocated hwpath struct to be filled in
618 */
619void device_to_hwpath(struct device *dev, struct hardware_path *path)
620{
621 struct parisc_device *padev;
622 if (dev->bus == &parisc_bus_type) {
623 padev = to_parisc_device(dev);
624 get_node_path(dev->parent, path);
625 path->mod = padev->hw_path;
626 } else if (is_pci_dev(dev)) {
627 get_node_path(dev, path);
628 }
629}
630EXPORT_SYMBOL(device_to_hwpath);
631
632#define BC_PORT_MASK 0x8
633#define BC_LOWER_PORT 0x8
634
635#define BUS_CONVERTER(dev) \
636 ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
637
638#define IS_LOWER_PORT(dev) \
639 ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \
640 & BC_PORT_MASK) == BC_LOWER_PORT)
641
642#define MAX_NATIVE_DEVICES 64
643#define NATIVE_DEVICE_OFFSET 0x1000
644
645#define FLEX_MASK F_EXTEND(0xfffc0000)
646#define IO_IO_LOW offsetof(struct bc_module, io_io_low)
647#define IO_IO_HIGH offsetof(struct bc_module, io_io_high)
648#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW)
649#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH)
650
651static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
652 struct device *parent);
653
654void walk_lower_bus(struct parisc_device *dev)
655{
656 unsigned long io_io_low, io_io_high;
657
658 if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
659 return;
660
661 if(dev->id.hw_type == HPHW_IOA) {
662 io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
663 io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
664 } else {
665 io_io_low = (READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK;
666 io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK;
667 }
668
669 walk_native_bus(io_io_low, io_io_high, &dev->dev);
670}
671
672/**
673 * walk_native_bus -- Probe a bus for devices
674 * @io_io_low: Base address of this bus.
675 * @io_io_high: Last address of this bus.
676 * @parent: The parent bus device.
677 *
678 * A native bus (eg Runway or GSC) may have up to 64 devices on it,
679 * spaced at intervals of 0x1000 bytes. PDC may not inform us of these
680 * devices, so we have to probe for them. Unfortunately, we may find
681 * devices which are not physically connected (such as extra serial &
682 * keyboard ports). This problem is not yet solved.
683 */
684static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
685 struct device *parent)
686{
687 int i, devices_found = 0;
688 unsigned long hpa = io_io_low;
689 struct hardware_path path;
690
691 get_node_path(parent, &path);
692 do {
693 for(i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) {
694 struct parisc_device *dev;
695
696 /* Was the device already added by Firmware? */
697 dev = find_device_by_addr(hpa);
698 if (!dev) {
699 path.mod = i;
700 dev = alloc_pa_dev(hpa, &path);
701 if (!dev)
702 continue;
703
704 register_parisc_device(dev);
705 devices_found++;
706 }
707 walk_lower_bus(dev);
708 }
709 } while(!devices_found && hpa < io_io_high);
710}
711
712#define CENTRAL_BUS_ADDR F_EXTEND(0xfff80000)
713
714/**
715 * walk_central_bus - Find devices attached to the central bus
716 *
717 * PDC doesn't tell us about all devices in the system. This routine
718 * finds devices connected to the central bus.
719 */
720void walk_central_bus(void)
721{
722 walk_native_bus(CENTRAL_BUS_ADDR,
723 CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET),
724 &root);
725}
726
727static void print_parisc_device(struct parisc_device *dev)
728{
729 char hw_path[64];
730 static int count;
731
732 print_pa_hwpath(dev, hw_path);
733 printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
734 ++count, dev->name, dev->hpa, hw_path, dev->id.hw_type,
735 dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
736
737 if (dev->num_addrs) {
738 int k;
739 printk(", additional addresses: ");
740 for (k = 0; k < dev->num_addrs; k++)
741 printk("0x%lx ", dev->addr[k]);
742 }
743 printk("\n");
744}
745
746/**
747 * init_parisc_bus - Some preparation to be done before inventory
748 */
749void init_parisc_bus(void)
750{
751 bus_register(&parisc_bus_type);
752 device_register(&root);
753 get_device(&root);
754}
755
756/**
757 * print_parisc_devices - Print out a list of devices found in this system
758 */
759void print_parisc_devices(void)
760{
761 struct parisc_device *dev;
762 for_each_padev(dev) {
763 print_parisc_device(dev);
764 }
765}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
new file mode 100644
index 000000000000..ee58d37dbb27
--- /dev/null
+++ b/arch/parisc/kernel/entry.S
@@ -0,0 +1,2426 @@
1/*
2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
3 *
4 * kernel entry points (interruptions, system call wrappers)
5 * Copyright (C) 1999,2000 Philipp Rumpf
6 * Copyright (C) 1999 SuSE GmbH Nuernberg
7 * Copyright (C) 2000 Hewlett-Packard (John Marvin)
8 * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/config.h>
26#include <asm/offsets.h>
27
28/* we have the following possibilities to act on an interruption:
29 * - handle in assembly and use shadowed registers only
30 * - save registers to kernel stack and handle in assembly or C */
31
32
33#include <asm/assembly.h> /* for LDREG/STREG defines */
34#include <asm/pgtable.h>
35#include <asm/psw.h>
36#include <asm/signal.h>
37#include <asm/unistd.h>
38#include <asm/thread_info.h>
39
40#ifdef __LP64__
41#define CMPIB cmpib,*
42#define CMPB cmpb,*
43#define COND(x) *x
44
45 .level 2.0w
46#else
47#define CMPIB cmpib,
48#define CMPB cmpb,
49#define COND(x) x
50
51 .level 2.0
52#endif
53
54 .import pa_dbit_lock,data
55
56 /* space_to_prot macro creates a prot id from a space id */
57
58#if (SPACEID_SHIFT) == 0
59 .macro space_to_prot spc prot
60 depd,z \spc,62,31,\prot
61 .endm
62#else
63 .macro space_to_prot spc prot
64 extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
65 .endm
66#endif
67
68 /* Switch to virtual mapping, trashing only %r1 */
69 .macro virt_map
70 rsm PSW_SM_Q,%r0
71 tovirt_r1 %r29
72 mfsp %sr7, %r1
73 or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
74 mtsp %r1, %sr3
75 mtsp %r0, %sr4
76 mtsp %r0, %sr5
77 mtsp %r0, %sr6
78 mtsp %r0, %sr7
79 load32 KERNEL_PSW, %r1
80 mtctl %r1, %cr22
81 mtctl %r0, %cr17 /* Clear IIASQ tail */
82 mtctl %r0, %cr17 /* Clear IIASQ head */
83 load32 4f, %r1
84 mtctl %r1, %cr18 /* Set IIAOQ tail */
85 ldo 4(%r1), %r1
86 mtctl %r1, %cr18 /* Set IIAOQ head */
87 rfir
88 nop
894:
90 .endm
91
92 /*
93 * The "get_stack" macros are responsible for determining the
94 * kernel stack value.
95 *
96 * For Faults:
97 * If sr7 == 0
98 * Already using a kernel stack, so call the
99 * get_stack_use_r30 macro to push a pt_regs structure
100 * on the stack, and store registers there.
101 * else
102 * Need to set up a kernel stack, so call the
103 * get_stack_use_cr30 macro to set up a pointer
104 * to the pt_regs structure contained within the
105 * task pointer pointed to by cr30. Set the stack
106 * pointer to point to the end of the task structure.
107 *
108 * For Interrupts:
109 * If sr7 == 0
110 * Already using a kernel stack, check to see if r30
111 * is already pointing to the per processor interrupt
112 * stack. If it is, call the get_stack_use_r30 macro
113 * to push a pt_regs structure on the stack, and store
114 * registers there. Otherwise, call get_stack_use_cr31
115 * to get a pointer to the base of the interrupt stack
116 * and push a pt_regs structure on that stack.
117 * else
118 * Need to set up a kernel stack, so call the
119 * get_stack_use_cr30 macro to set up a pointer
120 * to the pt_regs structure contained within the
121 * task pointer pointed to by cr30. Set the stack
122 * pointer to point to the end of the task structure.
123 * N.B: We don't use the interrupt stack for the
124 * first interrupt from userland, because signals/
125 * resched's are processed when returning to userland,
126 * and we can sleep in those cases.
127 *
128 * Note that we use shadowed registers for temps until
129 * we can save %r26 and %r29. %r26 is used to preserve
130 * %r8 (a shadowed register) which temporarily contained
131 * either the fault type ("code") or the eirr. We need
132 * to use a non-shadowed register to carry the value over
133 * the rfir in virt_map. We use %r26 since this value winds
134 * up being passed as the argument to either do_cpu_irq_mask
135 * or handle_interruption. %r29 is used to hold a pointer
136 * the register save area, and once again, it needs to
137 * be a non-shadowed register so that it survives the rfir.
138 *
139 * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
140 */
141
142 .macro get_stack_use_cr30
143
144 /* we save the registers in the task struct */
145
146 mfctl %cr30, %r1
147 tophys %r1,%r9
148 LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */
149 tophys %r1,%r9
150 ldo TASK_REGS(%r9),%r9
151 STREG %r30, PT_GR30(%r9)
152 STREG %r29,PT_GR29(%r9)
153 STREG %r26,PT_GR26(%r9)
154 copy %r9,%r29
155 mfctl %cr30, %r1
156 ldo THREAD_SZ_ALGN(%r1), %r30
157 .endm
158
159 .macro get_stack_use_r30
160
161 /* we put a struct pt_regs on the stack and save the registers there */
162
163 tophys %r30,%r9
164 STREG %r30,PT_GR30(%r9)
165 ldo PT_SZ_ALGN(%r30),%r30
166 STREG %r29,PT_GR29(%r9)
167 STREG %r26,PT_GR26(%r9)
168 copy %r9,%r29
169 .endm
170
171 .macro rest_stack
172 LDREG PT_GR1(%r29), %r1
173 LDREG PT_GR30(%r29),%r30
174 LDREG PT_GR29(%r29),%r29
175 .endm
176
177 /* default interruption handler
178 * (calls traps.c:handle_interruption) */
179 .macro def code
180 b intr_save
181 ldi \code, %r8
182 .align 32
183 .endm
184
185 /* Interrupt interruption handler
186 * (calls irq.c:do_cpu_irq_mask) */
187 .macro extint code
188 b intr_extint
189 mfsp %sr7,%r16
190 .align 32
191 .endm
192
193 .import os_hpmc, code
194
195 /* HPMC handler */
196 .macro hpmc code
197 nop /* must be a NOP, will be patched later */
198 load32 PA(os_hpmc), %r3
199 bv,n 0(%r3)
200 nop
201 .word 0 /* checksum (will be patched) */
202 .word PA(os_hpmc) /* address of handler */
203 .word 0 /* length of handler */
204 .endm
205
206 /*
207 * Performance Note: Instructions will be moved up into
208 * this part of the code later on, once we are sure
209 * that the tlb miss handlers are close to final form.
210 */
211
212 /* Register definitions for tlb miss handler macros */
213
214 va = r8 /* virtual address for which the trap occured */
215 spc = r24 /* space for which the trap occured */
216
217#ifndef __LP64__
218
219 /*
220 * itlb miss interruption handler (parisc 1.1 - 32 bit)
221 */
222
223 .macro itlb_11 code
224
225 mfctl %pcsq, spc
226 b itlb_miss_11
227 mfctl %pcoq, va
228
229 .align 32
230 .endm
231#endif
232
233 /*
234 * itlb miss interruption handler (parisc 2.0)
235 */
236
237 .macro itlb_20 code
238 mfctl %pcsq, spc
239#ifdef __LP64__
240 b itlb_miss_20w
241#else
242 b itlb_miss_20
243#endif
244 mfctl %pcoq, va
245
246 .align 32
247 .endm
248
249#ifndef __LP64__
250 /*
251 * naitlb miss interruption handler (parisc 1.1 - 32 bit)
252 *
253 * Note: naitlb misses will be treated
254 * as an ordinary itlb miss for now.
255 * However, note that naitlb misses
256 * have the faulting address in the
257 * IOR/ISR.
258 */
259
260 .macro naitlb_11 code
261
262 mfctl %isr,spc
263 b itlb_miss_11
264 mfctl %ior,va
265 /* FIXME: If user causes a naitlb miss, the priv level may not be in
266 * lower bits of va, where the itlb miss handler is expecting them
267 */
268
269 .align 32
270 .endm
271#endif
272
273 /*
274 * naitlb miss interruption handler (parisc 2.0)
275 *
276 * Note: naitlb misses will be treated
277 * as an ordinary itlb miss for now.
278 * However, note that naitlb misses
279 * have the faulting address in the
280 * IOR/ISR.
281 */
282
283 .macro naitlb_20 code
284
285 mfctl %isr,spc
286#ifdef __LP64__
287 b itlb_miss_20w
288#else
289 b itlb_miss_20
290#endif
291 mfctl %ior,va
292 /* FIXME: If user causes a naitlb miss, the priv level may not be in
293 * lower bits of va, where the itlb miss handler is expecting them
294 */
295
296 .align 32
297 .endm
298
299#ifndef __LP64__
300 /*
301 * dtlb miss interruption handler (parisc 1.1 - 32 bit)
302 */
303
304 .macro dtlb_11 code
305
306 mfctl %isr, spc
307 b dtlb_miss_11
308 mfctl %ior, va
309
310 .align 32
311 .endm
312#endif
313
314 /*
315 * dtlb miss interruption handler (parisc 2.0)
316 */
317
318 .macro dtlb_20 code
319
320 mfctl %isr, spc
321#ifdef __LP64__
322 b dtlb_miss_20w
323#else
324 b dtlb_miss_20
325#endif
326 mfctl %ior, va
327
328 .align 32
329 .endm
330
331#ifndef __LP64__
332 /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
333
334 .macro nadtlb_11 code
335
336 mfctl %isr,spc
337 b nadtlb_miss_11
338 mfctl %ior,va
339
340 .align 32
341 .endm
342#endif
343
344 /* nadtlb miss interruption handler (parisc 2.0) */
345
346 .macro nadtlb_20 code
347
348 mfctl %isr,spc
349#ifdef __LP64__
350 b nadtlb_miss_20w
351#else
352 b nadtlb_miss_20
353#endif
354 mfctl %ior,va
355
356 .align 32
357 .endm
358
359#ifndef __LP64__
360 /*
361 * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
362 */
363
364 .macro dbit_11 code
365
366 mfctl %isr,spc
367 b dbit_trap_11
368 mfctl %ior,va
369
370 .align 32
371 .endm
372#endif
373
374 /*
375 * dirty bit trap interruption handler (parisc 2.0)
376 */
377
378 .macro dbit_20 code
379
380 mfctl %isr,spc
381#ifdef __LP64__
382 b dbit_trap_20w
383#else
384 b dbit_trap_20
385#endif
386 mfctl %ior,va
387
388 .align 32
389 .endm
390
391 /* The following are simple 32 vs 64 bit instruction
392 * abstractions for the macros */
393 .macro EXTR reg1,start,length,reg2
394#ifdef __LP64__
395 extrd,u \reg1,32+\start,\length,\reg2
396#else
397 extrw,u \reg1,\start,\length,\reg2
398#endif
399 .endm
400
401 .macro DEP reg1,start,length,reg2
402#ifdef __LP64__
403 depd \reg1,32+\start,\length,\reg2
404#else
405 depw \reg1,\start,\length,\reg2
406#endif
407 .endm
408
409 .macro DEPI val,start,length,reg
410#ifdef __LP64__
411 depdi \val,32+\start,\length,\reg
412#else
413 depwi \val,\start,\length,\reg
414#endif
415 .endm
416
417 /* In LP64, the space contains part of the upper 32 bits of the
418 * fault. We have to extract this and place it in the va,
419 * zeroing the corresponding bits in the space register */
420 .macro space_adjust spc,va,tmp
421#ifdef __LP64__
422 extrd,u \spc,63,SPACEID_SHIFT,\tmp
423 depd %r0,63,SPACEID_SHIFT,\spc
424 depd \tmp,31,SPACEID_SHIFT,\va
425#endif
426 .endm
427
428 .import swapper_pg_dir,code
429
430 /* Get the pgd. For faults on space zero (kernel space), this
431 * is simply swapper_pg_dir. For user space faults, the
432 * pgd is stored in %cr25 */
433 .macro get_pgd spc,reg
434 ldil L%PA(swapper_pg_dir),\reg
435 ldo R%PA(swapper_pg_dir)(\reg),\reg
436 or,COND(=) %r0,\spc,%r0
437 mfctl %cr25,\reg
438 .endm
439
440 /*
441 space_check(spc,tmp,fault)
442
443 spc - The space we saw the fault with.
444 tmp - The place to store the current space.
445 fault - Function to call on failure.
446
447 Only allow faults on different spaces from the
448 currently active one if we're the kernel
449
450 */
451 .macro space_check spc,tmp,fault
452 mfsp %sr7,\tmp
453 or,COND(<>) %r0,\spc,%r0 /* user may execute gateway page
454 * as kernel, so defeat the space
455 * check if it is */
456 copy \spc,\tmp
457 or,COND(=) %r0,\tmp,%r0 /* nullify if executing as kernel */
458 cmpb,COND(<>),n \tmp,\spc,\fault
459 .endm
460
461 /* Look up a PTE in a 2-Level scheme (faulting at each
462 * level if the entry isn't present
463 *
464 * NOTE: we use ldw even for LP64, since the short pointers
465 * can address up to 1TB
466 */
467 .macro L2_ptep pmd,pte,index,va,fault
468#if PT_NLEVELS == 3
469 EXTR \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
470#else
471 EXTR \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
472#endif
473 DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
474 copy %r0,\pte
475 ldw,s \index(\pmd),\pmd
476 bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
477 DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
478 copy \pmd,%r9
479#ifdef __LP64__
480 shld %r9,PxD_VALUE_SHIFT,\pmd
481#else
482 shlw %r9,PxD_VALUE_SHIFT,\pmd
483#endif
484 EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
485 DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
486 shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
487 LDREG %r0(\pmd),\pte /* pmd is now pte */
488 bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
489 .endm
490
491 /* Look up PTE in a 3-Level scheme.
492 *
493 * Here we implement a Hybrid L2/L3 scheme: we allocate the
494 * first pmd adjacent to the pgd. This means that we can
495 * subtract a constant offset to get to it. The pmd and pgd
496 * sizes are arranged so that a single pmd covers 4GB (giving
497 * a full LP64 process access to 8TB) so our lookups are
498 * effectively L2 for the first 4GB of the kernel (i.e. for
499 * all ILP32 processes and all the kernel for machines with
500 * under 4GB of memory) */
501 .macro L3_ptep pgd,pte,index,va,fault
502 extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
503 copy %r0,\pte
504 extrd,u,*= \va,31,32,%r0
505 ldw,s \index(\pgd),\pgd
506 extrd,u,*= \va,31,32,%r0
507 bb,>=,n \pgd,_PxD_PRESENT_BIT,\fault
508 extrd,u,*= \va,31,32,%r0
509 shld \pgd,PxD_VALUE_SHIFT,\index
510 extrd,u,*= \va,31,32,%r0
511 copy \index,\pgd
512 extrd,u,*<> \va,31,32,%r0
513 ldo ASM_PGD_PMD_OFFSET(\pgd),\pgd
514 L2_ptep \pgd,\pte,\index,\va,\fault
515 .endm
516
517 /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and
518 * don't needlessly dirty the cache line if it was already set */
519 .macro update_ptep ptep,pte,tmp,tmp1
520 ldi _PAGE_ACCESSED,\tmp1
521 or \tmp1,\pte,\tmp
522 and,COND(<>) \tmp1,\pte,%r0
523 STREG \tmp,0(\ptep)
524 .endm
525
526 /* Set the dirty bit (and accessed bit). No need to be
527 * clever, this is only used from the dirty fault */
528 .macro update_dirty ptep,pte,tmp
529 ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
530 or \tmp,\pte,\pte
531 STREG \pte,0(\ptep)
532 .endm
533
534 /* Convert the pte and prot to tlb insertion values. How
535 * this happens is quite subtle, read below */
536 .macro make_insert_tlb spc,pte,prot
537 space_to_prot \spc \prot /* create prot id from space */
538 /* The following is the real subtlety. This is depositing
539 * T <-> _PAGE_REFTRAP
540 * D <-> _PAGE_DIRTY
541 * B <-> _PAGE_DMB (memory break)
542 *
543 * Then incredible subtlety: The access rights are
544 * _PAGE_GATEWAY _PAGE_EXEC _PAGE_READ
545 * See 3-14 of the parisc 2.0 manual
546 *
547 * Finally, _PAGE_READ goes in the top bit of PL1 (so we
548 * trigger an access rights trap in user space if the user
549 * tries to read an unreadable page */
550 depd \pte,8,7,\prot
551
552 /* PAGE_USER indicates the page can be read with user privileges,
553 * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
554 * contains _PAGE_READ */
555 extrd,u,*= \pte,_PAGE_USER_BIT+32,1,%r0
556 depdi 7,11,3,\prot
557 /* If we're a gateway page, drop PL2 back to zero for promotion
558 * to kernel privilege (so we can execute the page as kernel).
559 * Any privilege promotion page always denys read and write */
560 extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0
561 depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */
562
563 /* Get rid of prot bits and convert to page addr for iitlbt */
564
565 depd %r0,63,PAGE_SHIFT,\pte
566 extrd,u \pte,56,32,\pte
567 .endm
568
569 /* Identical macro to make_insert_tlb above, except it
570 * makes the tlb entry for the differently formatted pa11
571 * insertion instructions */
572 .macro make_insert_tlb_11 spc,pte,prot
573 zdep \spc,30,15,\prot
574 dep \pte,8,7,\prot
575 extru,= \pte,_PAGE_NO_CACHE_BIT,1,%r0
576 depi 1,12,1,\prot
577 extru,= \pte,_PAGE_USER_BIT,1,%r0
578 depi 7,11,3,\prot /* Set for user space (1 rsvd for read) */
579 extru,= \pte,_PAGE_GATEWAY_BIT,1,%r0
580 depi 0,11,2,\prot /* If Gateway, Set PL2 to 0 */
581
582 /* Get rid of prot bits and convert to page addr for iitlba */
583
584 depi 0,31,12,\pte
585 extru \pte,24,25,\pte
586
587 .endm
588
589 /* This is for ILP32 PA2.0 only. The TLB insertion needs
590 * to extend into I/O space if the address is 0xfXXXXXXX
591 * so we extend the f's into the top word of the pte in
592 * this case */
593 .macro f_extend pte,tmp
594 extrd,s \pte,42,4,\tmp
595 addi,<> 1,\tmp,%r0
596 extrd,s \pte,63,25,\pte
597 .endm
598
599 /* The alias region is an 8MB aligned 16MB to do clear and
600 * copy user pages at addresses congruent with the user
601 * virtual address.
602 *
603 * To use the alias page, you set %r26 up with the to TLB
604 * entry (identifying the physical page) and %r23 up with
605 * the from tlb entry (or nothing if only a to entry---for
606 * clear_user_page_asm) */
607 .macro do_alias spc,tmp,tmp1,va,pte,prot,fault
608 cmpib,COND(<>),n 0,\spc,\fault
609 ldil L%(TMPALIAS_MAP_START),\tmp
610#if defined(__LP64__) && (TMPALIAS_MAP_START >= 0x80000000)
611 /* on LP64, ldi will sign extend into the upper 32 bits,
612 * which is behaviour we don't want */
613 depdi 0,31,32,\tmp
614#endif
615 copy \va,\tmp1
616 DEPI 0,31,23,\tmp1
617 cmpb,COND(<>),n \tmp,\tmp1,\fault
618 ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot
619 depd,z \prot,8,7,\prot
620 /*
621 * OK, it is in the temp alias region, check whether "from" or "to".
622 * Check "subtle" note in pacache.S re: r23/r26.
623 */
624#ifdef __LP64__
625 extrd,u,*= \va,41,1,%r0
626#else
627 extrw,u,= \va,9,1,%r0
628#endif
629 or,COND(tr) %r23,%r0,\pte
630 or %r26,%r0,\pte
631 .endm
632
633
634 /*
635 * Align fault_vector_20 on 4K boundary so that both
636 * fault_vector_11 and fault_vector_20 are on the
637 * same page. This is only necessary as long as we
638 * write protect the kernel text, which we may stop
639 * doing once we use large page translations to cover
640 * the static part of the kernel address space.
641 */
642
643 .export fault_vector_20
644
645 .text
646
647 .align 4096
648
649fault_vector_20:
650 /* First vector is invalid (0) */
651 .ascii "cows can fly"
652 .byte 0
653 .align 32
654
655 hpmc 1
656 def 2
657 def 3
658 extint 4
659 def 5
660 itlb_20 6
661 def 7
662 def 8
663 def 9
664 def 10
665 def 11
666 def 12
667 def 13
668 def 14
669 dtlb_20 15
670#if 0
671 naitlb_20 16
672#else
673 def 16
674#endif
675 nadtlb_20 17
676 def 18
677 def 19
678 dbit_20 20
679 def 21
680 def 22
681 def 23
682 def 24
683 def 25
684 def 26
685 def 27
686 def 28
687 def 29
688 def 30
689 def 31
690
691#ifndef __LP64__
692
693 .export fault_vector_11
694
695 .align 2048
696
697fault_vector_11:
698 /* First vector is invalid (0) */
699 .ascii "cows can fly"
700 .byte 0
701 .align 32
702
703 hpmc 1
704 def 2
705 def 3
706 extint 4
707 def 5
708 itlb_11 6
709 def 7
710 def 8
711 def 9
712 def 10
713 def 11
714 def 12
715 def 13
716 def 14
717 dtlb_11 15
718#if 0
719 naitlb_11 16
720#else
721 def 16
722#endif
723 nadtlb_11 17
724 def 18
725 def 19
726 dbit_11 20
727 def 21
728 def 22
729 def 23
730 def 24
731 def 25
732 def 26
733 def 27
734 def 28
735 def 29
736 def 30
737 def 31
738
739#endif
740
741 .import handle_interruption,code
742 .import do_cpu_irq_mask,code
743
744 /*
745 * r26 = function to be called
746 * r25 = argument to pass in
747 * r24 = flags for do_fork()
748 *
749 * Kernel threads don't ever return, so they don't need
750 * a true register context. We just save away the arguments
751 * for copy_thread/ret_ to properly set up the child.
752 */
753
754#define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
755#define CLONE_UNTRACED 0x00800000
756
757 .export __kernel_thread, code
758 .import do_fork
759__kernel_thread:
760 STREG %r2, -RP_OFFSET(%r30)
761
762 copy %r30, %r1
763 ldo PT_SZ_ALGN(%r30),%r30
764#ifdef __LP64__
765 /* Yo, function pointers in wide mode are little structs... -PB */
766 ldd 24(%r26), %r2
767 STREG %r2, PT_GR27(%r1) /* Store childs %dp */
768 ldd 16(%r26), %r26
769
770 STREG %r22, PT_GR22(%r1) /* save r22 (arg5) */
771 copy %r0, %r22 /* user_tid */
772#endif
773 STREG %r26, PT_GR26(%r1) /* Store function & argument for child */
774 STREG %r25, PT_GR25(%r1)
775 ldil L%CLONE_UNTRACED, %r26
776 ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */
777 or %r26, %r24, %r26 /* will have kernel mappings. */
778 ldi 1, %r25 /* stack_start, signals kernel thread */
779 stw %r0, -52(%r30) /* user_tid */
780#ifdef __LP64__
781 ldo -16(%r30),%r29 /* Reference param save area */
782#endif
783 BL do_fork, %r2
784 copy %r1, %r24 /* pt_regs */
785
786 /* Parent Returns here */
787
788 LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2
789 ldo -PT_SZ_ALGN(%r30), %r30
790 bv %r0(%r2)
791 nop
792
793 /*
794 * Child Returns here
795 *
796 * copy_thread moved args from temp save area set up above
797 * into task save area.
798 */
799
800 .export ret_from_kernel_thread
801ret_from_kernel_thread:
802
803 /* Call schedule_tail first though */
804 BL schedule_tail, %r2
805 nop
806
807 LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1
808 LDREG TASK_PT_GR25(%r1), %r26
809#ifdef __LP64__
810 LDREG TASK_PT_GR27(%r1), %r27
811 LDREG TASK_PT_GR22(%r1), %r22
812#endif
813 LDREG TASK_PT_GR26(%r1), %r1
814 ble 0(%sr7, %r1)
815 copy %r31, %r2
816
817#ifdef __LP64__
818 ldo -16(%r30),%r29 /* Reference param save area */
819 loadgp /* Thread could have been in a module */
820#endif
821 b sys_exit
822 ldi 0, %r26
823
824 .import sys_execve, code
825 .export __execve, code
826__execve:
827 copy %r2, %r15
828 copy %r30, %r16
829 ldo PT_SZ_ALGN(%r30), %r30
830 STREG %r26, PT_GR26(%r16)
831 STREG %r25, PT_GR25(%r16)
832 STREG %r24, PT_GR24(%r16)
833#ifdef __LP64__
834 ldo -16(%r30),%r29 /* Reference param save area */
835#endif
836 BL sys_execve, %r2
837 copy %r16, %r26
838
839 cmpib,=,n 0,%r28,intr_return /* forward */
840
841 /* yes, this will trap and die. */
842 copy %r15, %r2
843 copy %r16, %r30
844 bv %r0(%r2)
845 nop
846
847 .align 4
848
849 /*
850 * struct task_struct *_switch_to(struct task_struct *prev,
851 * struct task_struct *next)
852 *
853 * switch kernel stacks and return prev */
854 .export _switch_to, code
855_switch_to:
856 STREG %r2, -RP_OFFSET(%r30)
857
858 callee_save
859
860 load32 _switch_to_ret, %r2
861
862 STREG %r2, TASK_PT_KPC(%r26)
863 LDREG TASK_PT_KPC(%r25), %r2
864
865 STREG %r30, TASK_PT_KSP(%r26)
866 LDREG TASK_PT_KSP(%r25), %r30
867 LDREG TASK_THREAD_INFO(%r25), %r25
868 bv %r0(%r2)
869 mtctl %r25,%cr30
870
871_switch_to_ret:
872 mtctl %r0, %cr0 /* Needed for single stepping */
873 callee_rest
874
875 LDREG -RP_OFFSET(%r30), %r2
876 bv %r0(%r2)
877 copy %r26, %r28
878
879 /*
880 * Common rfi return path for interruptions, kernel execve, and
881 * sys_rt_sigreturn (sometimes). The sys_rt_sigreturn syscall will
882 * return via this path if the signal was received when the process
883 * was running; if the process was blocked on a syscall then the
884 * normal syscall_exit path is used. All syscalls for traced
885 * proceses exit via intr_restore.
886 *
887 * XXX If any syscalls that change a processes space id ever exit
888 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
889 * adjust IASQ[0..1].
890 *
891 * Note that the following code uses a "relied upon translation".
892 * See the parisc ACD for details. The ssm is necessary due to a
893 * PCXT bug.
894 */
895
896 .align 4096
897
898 .export syscall_exit_rfi
899syscall_exit_rfi:
900 mfctl %cr30,%r16
901 LDREG TI_TASK(%r16), %r16 /* thread_info -> task_struct */
902 ldo TASK_REGS(%r16),%r16
903 /* Force iaoq to userspace, as the user has had access to our current
904 * context via sigcontext. Also Filter the PSW for the same reason.
905 */
906 LDREG PT_IAOQ0(%r16),%r19
907 depi 3,31,2,%r19
908 STREG %r19,PT_IAOQ0(%r16)
909 LDREG PT_IAOQ1(%r16),%r19
910 depi 3,31,2,%r19
911 STREG %r19,PT_IAOQ1(%r16)
912 LDREG PT_PSW(%r16),%r19
913 load32 USER_PSW_MASK,%r1
914#ifdef __LP64__
915 load32 USER_PSW_HI_MASK,%r20
916 depd %r20,31,32,%r1
917#endif
918 and %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
919 load32 USER_PSW,%r1
920 or %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
921 STREG %r19,PT_PSW(%r16)
922
923 /*
924 * If we aren't being traced, we never saved space registers
925 * (we don't store them in the sigcontext), so set them
926 * to "proper" values now (otherwise we'll wind up restoring
927 * whatever was last stored in the task structure, which might
928 * be inconsistent if an interrupt occured while on the gateway
929 * page) Note that we may be "trashing" values the user put in
930 * them, but we don't support the the user changing them.
931 */
932
933 STREG %r0,PT_SR2(%r16)
934 mfsp %sr3,%r19
935 STREG %r19,PT_SR0(%r16)
936 STREG %r19,PT_SR1(%r16)
937 STREG %r19,PT_SR3(%r16)
938 STREG %r19,PT_SR4(%r16)
939 STREG %r19,PT_SR5(%r16)
940 STREG %r19,PT_SR6(%r16)
941 STREG %r19,PT_SR7(%r16)
942
943intr_return:
944 /* NOTE: Need to enable interrupts incase we schedule. */
945 ssm PSW_SM_I, %r0
946
947 /* Check for software interrupts */
948
949 .import irq_stat,data
950
951 load32 irq_stat,%r19
952#ifdef CONFIG_SMP
953 mfctl %cr30,%r1
954 ldw TI_CPU(%r1),%r1 /* get cpu # - int */
955 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
956 ** irq_stat[] is defined using ____cacheline_aligned.
957 */
958#ifdef __LP64__
959 shld %r1, 6, %r20
960#else
961 shlw %r1, 5, %r20
962#endif
963 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
964#endif /* CONFIG_SMP */
965
966 LDREG IRQSTAT_SIRQ_PEND(%r19),%r20 /* hardirq.h: unsigned long */
967 cmpib,<>,n 0,%r20,intr_do_softirq /* forward */
968
969intr_check_resched:
970
971 /* check for reschedule */
972 mfctl %cr30,%r1
973 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
974 bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
975
976intr_check_sig:
977 /* As above */
978 mfctl %cr30,%r1
979 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_SIGPENDING */
980 bb,<,n %r19, 31-TIF_SIGPENDING, intr_do_signal /* forward */
981
982intr_restore:
983 copy %r16,%r29
984 ldo PT_FR31(%r29),%r1
985 rest_fp %r1
986 rest_general %r29
987
988 /* Create a "relied upon translation" PA 2.0 Arch. F-5 */
989 ssm 0,%r0
990 nop
991 nop
992 nop
993 nop
994 nop
995 nop
996 nop
997 tophys_r1 %r29
998 rsm (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0
999
1000 /* Restore space id's and special cr's from PT_REGS
1001 * structure pointed to by r29 */
1002 rest_specials %r29
1003
1004 /* Important: Note that rest_stack restores r29
1005 * last (we are using it)! It also restores r1 and r30. */
1006 rest_stack
1007
1008 rfi
1009 nop
1010 nop
1011 nop
1012 nop
1013 nop
1014 nop
1015 nop
1016 nop
1017
1018 .import do_softirq,code
1019intr_do_softirq:
1020 bl do_softirq,%r2
1021#ifdef __LP64__
1022 ldo -16(%r30),%r29 /* Reference param save area */
1023#else
1024 nop
1025#endif
1026 b intr_check_resched
1027 nop
1028
1029 .import schedule,code
1030intr_do_resched:
1031 /* Only do reschedule if we are returning to user space */
1032 LDREG PT_IASQ0(%r16), %r20
1033 CMPIB= 0,%r20,intr_restore /* backward */
1034 nop
1035 LDREG PT_IASQ1(%r16), %r20
1036 CMPIB= 0,%r20,intr_restore /* backward */
1037 nop
1038
1039#ifdef __LP64__
1040 ldo -16(%r30),%r29 /* Reference param save area */
1041#endif
1042
1043 ldil L%intr_check_sig, %r2
1044 b schedule
1045 ldo R%intr_check_sig(%r2), %r2
1046
1047
1048 .import do_signal,code
1049intr_do_signal:
1050 /*
1051 This check is critical to having LWS
1052 working. The IASQ is zero on the gateway
1053 page and we cannot deliver any signals until
1054 we get off the gateway page.
1055
1056 Only do signals if we are returning to user space
1057 */
1058 LDREG PT_IASQ0(%r16), %r20
1059 CMPIB= 0,%r20,intr_restore /* backward */
1060 nop
1061 LDREG PT_IASQ1(%r16), %r20
1062 CMPIB= 0,%r20,intr_restore /* backward */
1063 nop
1064
1065 copy %r0, %r24 /* unsigned long in_syscall */
1066 copy %r16, %r25 /* struct pt_regs *regs */
1067#ifdef __LP64__
1068 ldo -16(%r30),%r29 /* Reference param save area */
1069#endif
1070
1071 BL do_signal,%r2
1072 copy %r0, %r26 /* sigset_t *oldset = NULL */
1073
1074 b intr_check_sig
1075 nop
1076
1077 /*
1078 * External interrupts.
1079 */
1080
1081intr_extint:
1082 CMPIB=,n 0,%r16,1f
1083 get_stack_use_cr30
1084 b,n 3f
1085
10861:
1087#if 0 /* Interrupt Stack support not working yet! */
1088 mfctl %cr31,%r1
1089 copy %r30,%r17
1090 /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
1091#ifdef __LP64__
1092 depdi 0,63,15,%r17
1093#else
1094 depi 0,31,15,%r17
1095#endif
1096 CMPB=,n %r1,%r17,2f
1097 get_stack_use_cr31
1098 b,n 3f
1099#endif
11002:
1101 get_stack_use_r30
1102
11033:
1104 save_specials %r29
1105 virt_map
1106 save_general %r29
1107
1108 ldo PT_FR0(%r29), %r24
1109 save_fp %r24
1110
1111 loadgp
1112
1113 copy %r29, %r26 /* arg0 is pt_regs */
1114 copy %r29, %r16 /* save pt_regs */
1115
1116 ldil L%intr_return, %r2
1117
1118#ifdef __LP64__
1119 ldo -16(%r30),%r29 /* Reference param save area */
1120#endif
1121
1122 b do_cpu_irq_mask
1123 ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */
1124
1125
1126 /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1127
1128 .export intr_save, code /* for os_hpmc */
1129
1130intr_save:
1131 mfsp %sr7,%r16
1132 CMPIB=,n 0,%r16,1f
1133 get_stack_use_cr30
1134 b 2f
1135 copy %r8,%r26
1136
11371:
1138 get_stack_use_r30
1139 copy %r8,%r26
1140
11412:
1142 save_specials %r29
1143
1144 /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1145
1146 /*
1147 * FIXME: 1) Use a #define for the hardwired "6" below (and in
1148 * traps.c.
1149 * 2) Once we start executing code above 4 Gb, we need
1150 * to adjust iasq/iaoq here in the same way we
1151 * adjust isr/ior below.
1152 */
1153
1154 CMPIB=,n 6,%r26,skip_save_ior
1155
1156 /* save_specials left ipsw value in r8 for us to test */
1157
1158 mfctl %cr20, %r16 /* isr */
1159 mfctl %cr21, %r17 /* ior */
1160
1161#ifdef __LP64__
1162 /*
1163 * If the interrupted code was running with W bit off (32 bit),
1164 * clear the b bits (bits 0 & 1) in the ior.
1165 */
1166 extrd,u,*<> %r8,PSW_W_BIT,1,%r0
1167 depdi 0,1,2,%r17
1168
1169 /*
1170 * FIXME: This code has hardwired assumptions about the split
1171 * between space bits and offset bits. This will change
1172 * when we allow alternate page sizes.
1173 */
1174
1175 /* adjust isr/ior. */
1176
1177 extrd,u %r16,63,7,%r1 /* get high bits from isr for ior */
1178 depd %r1,31,7,%r17 /* deposit them into ior */
1179 depdi 0,63,7,%r16 /* clear them from isr */
1180#endif
1181 STREG %r16, PT_ISR(%r29)
1182 STREG %r17, PT_IOR(%r29)
1183
1184
1185skip_save_ior:
1186 virt_map
1187 save_general %r29
1188
1189 ldo PT_FR0(%r29), %r25
1190 save_fp %r25
1191
1192 loadgp
1193
1194 copy %r29, %r25 /* arg1 is pt_regs */
1195#ifdef __LP64__
1196 ldo -16(%r30),%r29 /* Reference param save area */
1197#endif
1198
1199 ldil L%intr_check_sig, %r2
1200 copy %r25, %r16 /* save pt_regs */
1201
1202 b handle_interruption
1203 ldo R%intr_check_sig(%r2), %r2
1204
1205
1206 /*
1207 * Note for all tlb miss handlers:
1208 *
1209 * cr24 contains a pointer to the kernel address space
1210 * page directory.
1211 *
1212 * cr25 contains a pointer to the current user address
1213 * space page directory.
1214 *
1215 * sr3 will contain the space id of the user address space
1216 * of the current running thread while that thread is
1217 * running in the kernel.
1218 */
1219
1220 /*
1221 * register number allocations. Note that these are all
1222 * in the shadowed registers
1223 */
1224
1225 t0 = r1 /* temporary register 0 */
1226 va = r8 /* virtual address for which the trap occured */
1227 t1 = r9 /* temporary register 1 */
1228 pte = r16 /* pte/phys page # */
1229 prot = r17 /* prot bits */
1230 spc = r24 /* space for which the trap occured */
1231 ptp = r25 /* page directory/page table pointer */
1232
1233#ifdef __LP64__
1234
1235dtlb_miss_20w:
1236 space_adjust spc,va,t0
1237 get_pgd spc,ptp
1238 space_check spc,t0,dtlb_fault
1239
1240 L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w
1241
1242 update_ptep ptp,pte,t0,t1
1243
1244 make_insert_tlb spc,pte,prot
1245
1246 idtlbt pte,prot
1247
1248 rfir
1249 nop
1250
1251dtlb_check_alias_20w:
1252 do_alias spc,t0,t1,va,pte,prot,dtlb_fault
1253
1254 idtlbt pte,prot
1255
1256 rfir
1257 nop
1258
1259nadtlb_miss_20w:
1260 space_adjust spc,va,t0
1261 get_pgd spc,ptp
1262 space_check spc,t0,nadtlb_fault
1263
1264 L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w
1265
1266 update_ptep ptp,pte,t0,t1
1267
1268 make_insert_tlb spc,pte,prot
1269
1270 idtlbt pte,prot
1271
1272 rfir
1273 nop
1274
1275nadtlb_check_flush_20w:
1276 bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1277
1278 /* Insert a "flush only" translation */
1279
1280 depdi,z 7,7,3,prot
1281 depdi 1,10,1,prot
1282
1283 /* Get rid of prot bits and convert to page addr for idtlbt */
1284
1285 depdi 0,63,12,pte
1286 extrd,u pte,56,52,pte
1287 idtlbt pte,prot
1288
1289 rfir
1290 nop
1291
1292#else
1293
1294dtlb_miss_11:
1295 get_pgd spc,ptp
1296
1297 space_check spc,t0,dtlb_fault
1298
1299 L2_ptep ptp,pte,t0,va,dtlb_check_alias_11
1300
1301 update_ptep ptp,pte,t0,t1
1302
1303 make_insert_tlb_11 spc,pte,prot
1304
1305 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
1306 mtsp spc,%sr1
1307
1308 idtlba pte,(%sr1,va)
1309 idtlbp prot,(%sr1,va)
1310
1311 mtsp t0, %sr1 /* Restore sr1 */
1312
1313 rfir
1314 nop
1315
1316dtlb_check_alias_11:
1317
1318 /* Check to see if fault is in the temporary alias region */
1319
1320 cmpib,<>,n 0,spc,dtlb_fault /* forward */
1321 ldil L%(TMPALIAS_MAP_START),t0
1322 copy va,t1
1323 depwi 0,31,23,t1
1324 cmpb,<>,n t0,t1,dtlb_fault /* forward */
1325 ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
1326 depw,z prot,8,7,prot
1327
1328 /*
1329 * OK, it is in the temp alias region, check whether "from" or "to".
1330 * Check "subtle" note in pacache.S re: r23/r26.
1331 */
1332
1333 extrw,u,= va,9,1,r0
1334 or,tr %r23,%r0,pte /* If "from" use "from" page */
1335 or %r26,%r0,pte /* else "to", use "to" page */
1336
1337 idtlba pte,(va)
1338 idtlbp prot,(va)
1339
1340 rfir
1341 nop
1342
1343nadtlb_miss_11:
1344 get_pgd spc,ptp
1345
1346 space_check spc,t0,nadtlb_fault
1347
1348 L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11
1349
1350 update_ptep ptp,pte,t0,t1
1351
1352 make_insert_tlb_11 spc,pte,prot
1353
1354
1355 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
1356 mtsp spc,%sr1
1357
1358 idtlba pte,(%sr1,va)
1359 idtlbp prot,(%sr1,va)
1360
1361 mtsp t0, %sr1 /* Restore sr1 */
1362
1363 rfir
1364 nop
1365
1366nadtlb_check_flush_11:
1367 bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1368
1369 /* Insert a "flush only" translation */
1370
1371 zdepi 7,7,3,prot
1372 depi 1,10,1,prot
1373
1374 /* Get rid of prot bits and convert to page addr for idtlba */
1375
1376 depi 0,31,12,pte
1377 extru pte,24,25,pte
1378
1379 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
1380 mtsp spc,%sr1
1381
1382 idtlba pte,(%sr1,va)
1383 idtlbp prot,(%sr1,va)
1384
1385 mtsp t0, %sr1 /* Restore sr1 */
1386
1387 rfir
1388 nop
1389
1390dtlb_miss_20:
1391 space_adjust spc,va,t0
1392 get_pgd spc,ptp
1393 space_check spc,t0,dtlb_fault
1394
1395 L2_ptep ptp,pte,t0,va,dtlb_check_alias_20
1396
1397 update_ptep ptp,pte,t0,t1
1398
1399 make_insert_tlb spc,pte,prot
1400
1401 f_extend pte,t0
1402
1403 idtlbt pte,prot
1404
1405 rfir
1406 nop
1407
1408dtlb_check_alias_20:
1409 do_alias spc,t0,t1,va,pte,prot,dtlb_fault
1410
1411 idtlbt pte,prot
1412
1413 rfir
1414 nop
1415
1416nadtlb_miss_20:
1417 get_pgd spc,ptp
1418
1419 space_check spc,t0,nadtlb_fault
1420
1421 L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20
1422
1423 update_ptep ptp,pte,t0,t1
1424
1425 make_insert_tlb spc,pte,prot
1426
1427 f_extend pte,t0
1428
1429 idtlbt pte,prot
1430
1431 rfir
1432 nop
1433
1434nadtlb_check_flush_20:
1435 bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1436
1437 /* Insert a "flush only" translation */
1438
1439 depdi,z 7,7,3,prot
1440 depdi 1,10,1,prot
1441
1442 /* Get rid of prot bits and convert to page addr for idtlbt */
1443
1444 depdi 0,63,12,pte
1445 extrd,u pte,56,32,pte
1446 idtlbt pte,prot
1447
1448 rfir
1449 nop
1450#endif
1451
1452nadtlb_emulate:
1453
1454 /*
1455 * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1456 * probei instructions. We don't want to fault for these
1457 * instructions (not only does it not make sense, it can cause
1458 * deadlocks, since some flushes are done with the mmap
1459 * semaphore held). If the translation doesn't exist, we can't
1460 * insert a translation, so have to emulate the side effects
1461 * of the instruction. Since we don't insert a translation
1462 * we can get a lot of faults during a flush loop, so it makes
1463 * sense to try to do it here with minimum overhead. We only
1464 * emulate fdc,fic,pdc,probew,prober instructions whose base
1465 * and index registers are not shadowed. We defer everything
1466 * else to the "slow" path.
1467 */
1468
1469 mfctl %cr19,%r9 /* Get iir */
1470
1471 /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1472 Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1473
1474 /* Checks for fdc,fdce,pdc,"fic,4f" only */
1475 ldi 0x280,%r16
1476 and %r9,%r16,%r17
1477 cmpb,<>,n %r16,%r17,nadtlb_probe_check
1478 bb,>=,n %r9,26,nadtlb_nullify /* m bit not set, just nullify */
1479 BL get_register,%r25
1480 extrw,u %r9,15,5,%r8 /* Get index register # */
1481 CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */
1482 copy %r1,%r24
1483 BL get_register,%r25
1484 extrw,u %r9,10,5,%r8 /* Get base register # */
1485 CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */
1486 BL set_register,%r25
1487 add,l %r1,%r24,%r1 /* doesn't affect c/b bits */
1488
1489nadtlb_nullify:
1490 mfctl %cr22,%r8 /* Get ipsw */
1491 ldil L%PSW_N,%r9
1492 or %r8,%r9,%r8 /* Set PSW_N */
1493 mtctl %r8,%cr22
1494
1495 rfir
1496 nop
1497
1498 /*
1499 When there is no translation for the probe address then we
1500 must nullify the insn and return zero in the target regsiter.
1501 This will indicate to the calling code that it does not have
1502 write/read privileges to this address.
1503
1504 This should technically work for prober and probew in PA 1.1,
1505 and also probe,r and probe,w in PA 2.0
1506
1507 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1508 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1509
1510 */
1511nadtlb_probe_check:
1512 ldi 0x80,%r16
1513 and %r9,%r16,%r17
1514 cmpb,<>,n %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1515 BL get_register,%r25 /* Find the target register */
1516 extrw,u %r9,31,5,%r8 /* Get target register */
1517 CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */
1518 BL set_register,%r25
1519 copy %r0,%r1 /* Write zero to target register */
1520 b nadtlb_nullify /* Nullify return insn */
1521 nop
1522
1523
1524#ifdef __LP64__
1525itlb_miss_20w:
1526
1527 /*
1528 * I miss is a little different, since we allow users to fault
1529 * on the gateway page which is in the kernel address space.
1530 */
1531
1532 space_adjust spc,va,t0
1533 get_pgd spc,ptp
1534 space_check spc,t0,itlb_fault
1535
1536 L3_ptep ptp,pte,t0,va,itlb_fault
1537
1538 update_ptep ptp,pte,t0,t1
1539
1540 make_insert_tlb spc,pte,prot
1541
1542 iitlbt pte,prot
1543
1544 rfir
1545 nop
1546
1547#else
1548
1549itlb_miss_11:
1550 get_pgd spc,ptp
1551
1552 space_check spc,t0,itlb_fault
1553
1554 L2_ptep ptp,pte,t0,va,itlb_fault
1555
1556 update_ptep ptp,pte,t0,t1
1557
1558 make_insert_tlb_11 spc,pte,prot
1559
1560 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
1561 mtsp spc,%sr1
1562
1563 iitlba pte,(%sr1,va)
1564 iitlbp prot,(%sr1,va)
1565
1566 mtsp t0, %sr1 /* Restore sr1 */
1567
1568 rfir
1569 nop
1570
1571itlb_miss_20:
1572 get_pgd spc,ptp
1573
1574 space_check spc,t0,itlb_fault
1575
1576 L2_ptep ptp,pte,t0,va,itlb_fault
1577
1578 update_ptep ptp,pte,t0,t1
1579
1580 make_insert_tlb spc,pte,prot
1581
1582 f_extend pte,t0
1583
1584 iitlbt pte,prot
1585
1586 rfir
1587 nop
1588
1589#endif
1590
1591#ifdef __LP64__
1592
1593dbit_trap_20w:
1594 space_adjust spc,va,t0
1595 get_pgd spc,ptp
1596 space_check spc,t0,dbit_fault
1597
1598 L3_ptep ptp,pte,t0,va,dbit_fault
1599
1600#ifdef CONFIG_SMP
1601 CMPIB=,n 0,spc,dbit_nolock_20w
1602 load32 PA(pa_dbit_lock),t0
1603
1604dbit_spin_20w:
1605 ldcw 0(t0),t1
1606 cmpib,= 0,t1,dbit_spin_20w
1607 nop
1608
1609dbit_nolock_20w:
1610#endif
1611 update_dirty ptp,pte,t1
1612
1613 make_insert_tlb spc,pte,prot
1614
1615 idtlbt pte,prot
1616#ifdef CONFIG_SMP
1617 CMPIB=,n 0,spc,dbit_nounlock_20w
1618 ldi 1,t1
1619 stw t1,0(t0)
1620
1621dbit_nounlock_20w:
1622#endif
1623
1624 rfir
1625 nop
1626#else
1627
1628dbit_trap_11:
1629
1630 get_pgd spc,ptp
1631
1632 space_check spc,t0,dbit_fault
1633
1634 L2_ptep ptp,pte,t0,va,dbit_fault
1635
1636#ifdef CONFIG_SMP
1637 CMPIB=,n 0,spc,dbit_nolock_11
1638 load32 PA(pa_dbit_lock),t0
1639
1640dbit_spin_11:
1641 ldcw 0(t0),t1
1642 cmpib,= 0,t1,dbit_spin_11
1643 nop
1644
1645dbit_nolock_11:
1646#endif
1647 update_dirty ptp,pte,t1
1648
1649 make_insert_tlb_11 spc,pte,prot
1650
1651 mfsp %sr1,t1 /* Save sr1 so we can use it in tlb inserts */
1652 mtsp spc,%sr1
1653
1654 idtlba pte,(%sr1,va)
1655 idtlbp prot,(%sr1,va)
1656
1657 mtsp t1, %sr1 /* Restore sr1 */
1658#ifdef CONFIG_SMP
1659 CMPIB=,n 0,spc,dbit_nounlock_11
1660 ldi 1,t1
1661 stw t1,0(t0)
1662
1663dbit_nounlock_11:
1664#endif
1665
1666 rfir
1667 nop
1668
1669dbit_trap_20:
1670 get_pgd spc,ptp
1671
1672 space_check spc,t0,dbit_fault
1673
1674 L2_ptep ptp,pte,t0,va,dbit_fault
1675
1676#ifdef CONFIG_SMP
1677 CMPIB=,n 0,spc,dbit_nolock_20
1678 load32 PA(pa_dbit_lock),t0
1679
1680dbit_spin_20:
1681 ldcw 0(t0),t1
1682 cmpib,= 0,t1,dbit_spin_20
1683 nop
1684
1685dbit_nolock_20:
1686#endif
1687 update_dirty ptp,pte,t1
1688
1689 make_insert_tlb spc,pte,prot
1690
1691 f_extend pte,t1
1692
1693 idtlbt pte,prot
1694
1695#ifdef CONFIG_SMP
1696 CMPIB=,n 0,spc,dbit_nounlock_20
1697 ldi 1,t1
1698 stw t1,0(t0)
1699
1700dbit_nounlock_20:
1701#endif
1702
1703 rfir
1704 nop
1705#endif
1706
1707 .import handle_interruption,code
1708
1709kernel_bad_space:
1710 b intr_save
1711 ldi 31,%r8 /* Use an unused code */
1712
1713dbit_fault:
1714 b intr_save
1715 ldi 20,%r8
1716
1717itlb_fault:
1718 b intr_save
1719 ldi 6,%r8
1720
1721nadtlb_fault:
1722 b intr_save
1723 ldi 17,%r8
1724
1725dtlb_fault:
1726 b intr_save
1727 ldi 15,%r8
1728
1729 /* Register saving semantics for system calls:
1730
1731 %r1 clobbered by system call macro in userspace
1732 %r2 saved in PT_REGS by gateway page
1733 %r3 - %r18 preserved by C code (saved by signal code)
1734 %r19 - %r20 saved in PT_REGS by gateway page
1735 %r21 - %r22 non-standard syscall args
1736 stored in kernel stack by gateway page
1737 %r23 - %r26 arg3-arg0, saved in PT_REGS by gateway page
1738 %r27 - %r30 saved in PT_REGS by gateway page
1739 %r31 syscall return pointer
1740 */
1741
1742 /* Floating point registers (FIXME: what do we do with these?)
1743
1744 %fr0 - %fr3 status/exception, not preserved
1745 %fr4 - %fr7 arguments
1746 %fr8 - %fr11 not preserved by C code
1747 %fr12 - %fr21 preserved by C code
1748 %fr22 - %fr31 not preserved by C code
1749 */
1750
1751 .macro reg_save regs
1752 STREG %r3, PT_GR3(\regs)
1753 STREG %r4, PT_GR4(\regs)
1754 STREG %r5, PT_GR5(\regs)
1755 STREG %r6, PT_GR6(\regs)
1756 STREG %r7, PT_GR7(\regs)
1757 STREG %r8, PT_GR8(\regs)
1758 STREG %r9, PT_GR9(\regs)
1759 STREG %r10,PT_GR10(\regs)
1760 STREG %r11,PT_GR11(\regs)
1761 STREG %r12,PT_GR12(\regs)
1762 STREG %r13,PT_GR13(\regs)
1763 STREG %r14,PT_GR14(\regs)
1764 STREG %r15,PT_GR15(\regs)
1765 STREG %r16,PT_GR16(\regs)
1766 STREG %r17,PT_GR17(\regs)
1767 STREG %r18,PT_GR18(\regs)
1768 .endm
1769
1770 .macro reg_restore regs
1771 LDREG PT_GR3(\regs), %r3
1772 LDREG PT_GR4(\regs), %r4
1773 LDREG PT_GR5(\regs), %r5
1774 LDREG PT_GR6(\regs), %r6
1775 LDREG PT_GR7(\regs), %r7
1776 LDREG PT_GR8(\regs), %r8
1777 LDREG PT_GR9(\regs), %r9
1778 LDREG PT_GR10(\regs),%r10
1779 LDREG PT_GR11(\regs),%r11
1780 LDREG PT_GR12(\regs),%r12
1781 LDREG PT_GR13(\regs),%r13
1782 LDREG PT_GR14(\regs),%r14
1783 LDREG PT_GR15(\regs),%r15
1784 LDREG PT_GR16(\regs),%r16
1785 LDREG PT_GR17(\regs),%r17
1786 LDREG PT_GR18(\regs),%r18
1787 .endm
1788
1789 .export sys_fork_wrapper
1790 .export child_return
1791sys_fork_wrapper:
1792 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1793 ldo TASK_REGS(%r1),%r1
1794 reg_save %r1
1795 mfctl %cr27, %r3
1796 STREG %r3, PT_CR27(%r1)
1797
1798 STREG %r2,-RP_OFFSET(%r30)
1799 ldo FRAME_SIZE(%r30),%r30
1800#ifdef __LP64__
1801 ldo -16(%r30),%r29 /* Reference param save area */
1802#endif
1803
1804 /* These are call-clobbered registers and therefore
1805 also syscall-clobbered (we hope). */
1806 STREG %r2,PT_GR19(%r1) /* save for child */
1807 STREG %r30,PT_GR21(%r1)
1808
1809 LDREG PT_GR30(%r1),%r25
1810 copy %r1,%r24
1811 BL sys_clone,%r2
1812 ldi SIGCHLD,%r26
1813
1814 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
1815wrapper_exit:
1816 ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */
1817 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1818 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1819
1820 LDREG PT_CR27(%r1), %r3
1821 mtctl %r3, %cr27
1822 reg_restore %r1
1823
1824 /* strace expects syscall # to be preserved in r20 */
1825 ldi __NR_fork,%r20
1826 bv %r0(%r2)
1827 STREG %r20,PT_GR20(%r1)
1828
1829 /* Set the return value for the child */
1830child_return:
1831 BL schedule_tail, %r2
1832 nop
1833
1834 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
1835 LDREG TASK_PT_GR19(%r1),%r2
1836 b wrapper_exit
1837 copy %r0,%r28
1838
1839
1840 .export sys_clone_wrapper
1841sys_clone_wrapper:
1842 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1843 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1844 reg_save %r1
1845 mfctl %cr27, %r3
1846 STREG %r3, PT_CR27(%r1)
1847
1848 STREG %r2,-RP_OFFSET(%r30)
1849 ldo FRAME_SIZE(%r30),%r30
1850#ifdef __LP64__
1851 ldo -16(%r30),%r29 /* Reference param save area */
1852#endif
1853
1854 STREG %r2,PT_GR19(%r1) /* save for child */
1855 STREG %r30,PT_GR21(%r1)
1856 BL sys_clone,%r2
1857 copy %r1,%r24
1858
1859 b wrapper_exit
1860 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
1861
1862 .export sys_vfork_wrapper
1863sys_vfork_wrapper:
1864 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1865 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1866 reg_save %r1
1867 mfctl %cr27, %r3
1868 STREG %r3, PT_CR27(%r1)
1869
1870 STREG %r2,-RP_OFFSET(%r30)
1871 ldo FRAME_SIZE(%r30),%r30
1872#ifdef __LP64__
1873 ldo -16(%r30),%r29 /* Reference param save area */
1874#endif
1875
1876 STREG %r2,PT_GR19(%r1) /* save for child */
1877 STREG %r30,PT_GR21(%r1)
1878
1879 BL sys_vfork,%r2
1880 copy %r1,%r26
1881
1882 b wrapper_exit
1883 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
1884
1885
1886 .macro execve_wrapper execve
1887 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1888 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1889
1890 /*
1891 * Do we need to save/restore r3-r18 here?
1892 * I don't think so. why would new thread need old
1893 * threads registers?
1894 */
1895
1896 /* %arg0 - %arg3 are already saved for us. */
1897
1898 STREG %r2,-RP_OFFSET(%r30)
1899 ldo FRAME_SIZE(%r30),%r30
1900#ifdef __LP64__
1901 ldo -16(%r30),%r29 /* Reference param save area */
1902#endif
1903 bl \execve,%r2
1904 copy %r1,%arg0
1905
1906 ldo -FRAME_SIZE(%r30),%r30
1907 LDREG -RP_OFFSET(%r30),%r2
1908
1909 /* If exec succeeded we need to load the args */
1910
1911 ldo -1024(%r0),%r1
1912 cmpb,>>= %r28,%r1,error_\execve
1913 copy %r2,%r19
1914
1915error_\execve:
1916 bv %r0(%r19)
1917 nop
1918 .endm
1919
1920 .export sys_execve_wrapper
1921 .import sys_execve
1922
1923sys_execve_wrapper:
1924 execve_wrapper sys_execve
1925
1926#ifdef __LP64__
1927 .export sys32_execve_wrapper
1928 .import sys32_execve
1929
1930sys32_execve_wrapper:
1931 execve_wrapper sys32_execve
1932#endif
1933
1934 .export sys_rt_sigreturn_wrapper
1935sys_rt_sigreturn_wrapper:
1936 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1937 ldo TASK_REGS(%r26),%r26 /* get pt regs */
1938 /* Don't save regs, we are going to restore them from sigcontext. */
1939 STREG %r2, -RP_OFFSET(%r30)
1940#ifdef __LP64__
1941 ldo FRAME_SIZE(%r30), %r30
1942 BL sys_rt_sigreturn,%r2
1943 ldo -16(%r30),%r29 /* Reference param save area */
1944#else
1945 BL sys_rt_sigreturn,%r2
1946 ldo FRAME_SIZE(%r30), %r30
1947#endif
1948
1949 ldo -FRAME_SIZE(%r30), %r30
1950 LDREG -RP_OFFSET(%r30), %r2
1951
1952 /* FIXME: I think we need to restore a few more things here. */
1953 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1954 ldo TASK_REGS(%r1),%r1 /* get pt regs */
1955 reg_restore %r1
1956
1957 /* If the signal was received while the process was blocked on a
1958 * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1959 * take us to syscall_exit_rfi and on to intr_return.
1960 */
1961 bv %r0(%r2)
1962 LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */
1963
1964 .export sys_sigaltstack_wrapper
1965sys_sigaltstack_wrapper:
1966 /* Get the user stack pointer */
1967 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1968 ldo TASK_REGS(%r1),%r24 /* get pt regs */
1969 LDREG TASK_PT_GR30(%r24),%r24
1970 STREG %r2, -RP_OFFSET(%r30)
1971#ifdef __LP64__
1972 ldo FRAME_SIZE(%r30), %r30
1973 b,l do_sigaltstack,%r2
1974 ldo -16(%r30),%r29 /* Reference param save area */
1975#else
1976 bl do_sigaltstack,%r2
1977 ldo FRAME_SIZE(%r30), %r30
1978#endif
1979
1980 ldo -FRAME_SIZE(%r30), %r30
1981 LDREG -RP_OFFSET(%r30), %r2
1982 bv %r0(%r2)
1983 nop
1984
1985#ifdef __LP64__
1986 .export sys32_sigaltstack_wrapper
1987sys32_sigaltstack_wrapper:
1988 /* Get the user stack pointer */
1989 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
1990 LDREG TASK_PT_GR30(%r24),%r24
1991 STREG %r2, -RP_OFFSET(%r30)
1992 ldo FRAME_SIZE(%r30), %r30
1993 b,l do_sigaltstack32,%r2
1994 ldo -16(%r30),%r29 /* Reference param save area */
1995
1996 ldo -FRAME_SIZE(%r30), %r30
1997 LDREG -RP_OFFSET(%r30), %r2
1998 bv %r0(%r2)
1999 nop
2000#endif
2001
2002 .export sys_rt_sigsuspend_wrapper
2003sys_rt_sigsuspend_wrapper:
2004 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
2005 ldo TASK_REGS(%r1),%r24
2006 reg_save %r24
2007
2008 STREG %r2, -RP_OFFSET(%r30)
2009#ifdef __LP64__
2010 ldo FRAME_SIZE(%r30), %r30
2011 b,l sys_rt_sigsuspend,%r2
2012 ldo -16(%r30),%r29 /* Reference param save area */
2013#else
2014 bl sys_rt_sigsuspend,%r2
2015 ldo FRAME_SIZE(%r30), %r30
2016#endif
2017
2018 ldo -FRAME_SIZE(%r30), %r30
2019 LDREG -RP_OFFSET(%r30), %r2
2020
2021 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
2022 ldo TASK_REGS(%r1),%r1
2023 reg_restore %r1
2024
2025 bv %r0(%r2)
2026 nop
2027
2028 .export syscall_exit
2029syscall_exit:
2030
2031 /* NOTE: HP-UX syscalls also come through here
2032 * after hpux_syscall_exit fixes up return
2033 * values. */
2034
2035 /* NOTE: Not all syscalls exit this way. rt_sigreturn will exit
2036 * via syscall_exit_rfi if the signal was received while the process
2037 * was running.
2038 */
2039
2040 /* save return value now */
2041
2042 mfctl %cr30, %r1
2043 LDREG TI_TASK(%r1),%r1
2044 STREG %r28,TASK_PT_GR28(%r1)
2045
2046#ifdef CONFIG_HPUX
2047
2048/* <linux/personality.h> cannot be easily included */
2049#define PER_HPUX 0x10
2050 LDREG TASK_PERSONALITY(%r1),%r19
2051
2052 /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
2053 ldo -PER_HPUX(%r19), %r19
2054 CMPIB<>,n 0,%r19,1f
2055
2056 /* Save other hpux returns if personality is PER_HPUX */
2057 STREG %r22,TASK_PT_GR22(%r1)
2058 STREG %r29,TASK_PT_GR29(%r1)
20591:
2060
2061#endif /* CONFIG_HPUX */
2062
2063 /* Seems to me that dp could be wrong here, if the syscall involved
2064 * calling a module, and nothing got round to restoring dp on return.
2065 */
2066 loadgp
2067
2068syscall_check_bh:
2069
2070 /* Check for software interrupts */
2071
2072 .import irq_stat,data
2073
2074 load32 irq_stat,%r19
2075
2076#ifdef CONFIG_SMP
2077 /* sched.h: int processor */
2078 /* %r26 is used as scratch register to index into irq_stat[] */
2079 ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
2080
2081 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
2082#ifdef __LP64__
2083 shld %r26, 6, %r20
2084#else
2085 shlw %r26, 5, %r20
2086#endif
2087 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
2088#endif /* CONFIG_SMP */
2089
2090 LDREG IRQSTAT_SIRQ_PEND(%r19),%r20 /* hardirq.h: unsigned long */
2091 cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */
2092
2093syscall_check_resched:
2094
2095 /* check for reschedule */
2096
2097 LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */
2098 bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
2099
2100syscall_check_sig:
2101 LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* get ti flags */
2102 bb,<,n %r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */
2103
2104syscall_restore:
2105 /* Are we being ptraced? */
2106 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2107
2108 LDREG TASK_PTRACE(%r1), %r19
2109 bb,< %r19,31,syscall_restore_rfi
2110 nop
2111
2112 ldo TASK_PT_FR31(%r1),%r19 /* reload fpregs */
2113 rest_fp %r19
2114
2115 LDREG TASK_PT_SAR(%r1),%r19 /* restore SAR */
2116 mtsar %r19
2117
2118 LDREG TASK_PT_GR2(%r1),%r2 /* restore user rp */
2119 LDREG TASK_PT_GR19(%r1),%r19
2120 LDREG TASK_PT_GR20(%r1),%r20
2121 LDREG TASK_PT_GR21(%r1),%r21
2122 LDREG TASK_PT_GR22(%r1),%r22
2123 LDREG TASK_PT_GR23(%r1),%r23
2124 LDREG TASK_PT_GR24(%r1),%r24
2125 LDREG TASK_PT_GR25(%r1),%r25
2126 LDREG TASK_PT_GR26(%r1),%r26
2127 LDREG TASK_PT_GR27(%r1),%r27 /* restore user dp */
2128 LDREG TASK_PT_GR28(%r1),%r28 /* syscall return value */
2129 LDREG TASK_PT_GR29(%r1),%r29
2130 LDREG TASK_PT_GR31(%r1),%r31 /* restore syscall rp */
2131
2132 /* NOTE: We use rsm/ssm pair to make this operation atomic */
2133 rsm PSW_SM_I, %r0
2134 LDREG TASK_PT_GR30(%r1),%r30 /* restore user sp */
2135 mfsp %sr3,%r1 /* Get users space id */
2136 mtsp %r1,%sr7 /* Restore sr7 */
2137 ssm PSW_SM_I, %r0
2138
2139 /* Set sr2 to zero for userspace syscalls to work. */
2140 mtsp %r0,%sr2
2141 mtsp %r1,%sr4 /* Restore sr4 */
2142 mtsp %r1,%sr5 /* Restore sr5 */
2143 mtsp %r1,%sr6 /* Restore sr6 */
2144
2145 depi 3,31,2,%r31 /* ensure return to user mode. */
2146
2147#ifdef __LP64__
2148 /* decide whether to reset the wide mode bit
2149 *
2150 * For a syscall, the W bit is stored in the lowest bit
2151 * of sp. Extract it and reset W if it is zero */
2152 extrd,u,*<> %r30,63,1,%r1
2153 rsm PSW_SM_W, %r0
2154 /* now reset the lowest bit of sp if it was set */
2155 xor %r30,%r1,%r30
2156#endif
2157 be,n 0(%sr3,%r31) /* return to user space */
2158
2159 /* We have to return via an RFI, so that PSW T and R bits can be set
2160 * appropriately.
2161 * This sets up pt_regs so we can return via intr_restore, which is not
2162 * the most efficient way of doing things, but it works.
2163 */
2164syscall_restore_rfi:
2165 ldo -1(%r0),%r2 /* Set recovery cntr to -1 */
2166 mtctl %r2,%cr0 /* for immediate trap */
2167 LDREG TASK_PT_PSW(%r1),%r2 /* Get old PSW */
2168 ldi 0x0b,%r20 /* Create new PSW */
2169 depi -1,13,1,%r20 /* C, Q, D, and I bits */
2170
2171 /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
2172 * set in include/linux/ptrace.h and converted to PA bitmap
2173 * numbers in asm-offsets.c */
2174
2175 /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
2176 extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
2177 depi -1,27,1,%r20 /* R bit */
2178
2179 /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
2180 extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
2181 depi -1,7,1,%r20 /* T bit */
2182
2183 STREG %r20,TASK_PT_PSW(%r1)
2184
2185 /* Always store space registers, since sr3 can be changed (e.g. fork) */
2186
2187 mfsp %sr3,%r25
2188 STREG %r25,TASK_PT_SR3(%r1)
2189 STREG %r25,TASK_PT_SR4(%r1)
2190 STREG %r25,TASK_PT_SR5(%r1)
2191 STREG %r25,TASK_PT_SR6(%r1)
2192 STREG %r25,TASK_PT_SR7(%r1)
2193 STREG %r25,TASK_PT_IASQ0(%r1)
2194 STREG %r25,TASK_PT_IASQ1(%r1)
2195
2196 /* XXX W bit??? */
2197 /* Now if old D bit is clear, it means we didn't save all registers
2198 * on syscall entry, so do that now. This only happens on TRACEME
2199 * calls, or if someone attached to us while we were on a syscall.
2200 * We could make this more efficient by not saving r3-r18, but
2201 * then we wouldn't be able to use the common intr_restore path.
2202 * It is only for traced processes anyway, so performance is not
2203 * an issue.
2204 */
2205 bb,< %r2,30,pt_regs_ok /* Branch if D set */
2206 ldo TASK_REGS(%r1),%r25
2207 reg_save %r25 /* Save r3 to r18 */
2208
2209 /* Save the current sr */
2210 mfsp %sr0,%r2
2211 STREG %r2,TASK_PT_SR0(%r1)
2212
2213 /* Save the scratch sr */
2214 mfsp %sr1,%r2
2215 STREG %r2,TASK_PT_SR1(%r1)
2216
2217 /* sr2 should be set to zero for userspace syscalls */
2218 STREG %r0,TASK_PT_SR2(%r1)
2219
2220pt_regs_ok:
2221 LDREG TASK_PT_GR31(%r1),%r2
2222 depi 3,31,2,%r2 /* ensure return to user mode. */
2223 STREG %r2,TASK_PT_IAOQ0(%r1)
2224 ldo 4(%r2),%r2
2225 STREG %r2,TASK_PT_IAOQ1(%r1)
2226 copy %r25,%r16
2227 b intr_restore
2228 nop
2229
2230 .import do_softirq,code
2231syscall_do_softirq:
2232 bl do_softirq,%r2
2233 nop
2234 /* NOTE: We enable I-bit incase we schedule later,
2235 * and we might be going back to userspace if we were
2236 * traced. */
2237 b syscall_check_resched
2238 ssm PSW_SM_I, %r0 /* do_softirq returns with I bit off */
2239
2240 .import schedule,code
2241syscall_do_resched:
2242 BL schedule,%r2
2243#ifdef __LP64__
2244 ldo -16(%r30),%r29 /* Reference param save area */
2245#else
2246 nop
2247#endif
2248 b syscall_check_bh /* if resched, we start over again */
2249 nop
2250
2251 .import do_signal,code
2252syscall_do_signal:
2253 /* Save callee-save registers (for sigcontext).
2254 FIXME: After this point the process structure should be
2255 consistent with all the relevant state of the process
2256 before the syscall. We need to verify this. */
2257 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2258 ldo TASK_REGS(%r1), %r25 /* struct pt_regs *regs */
2259 reg_save %r25
2260
2261 ldi 1, %r24 /* unsigned long in_syscall */
2262
2263#ifdef __LP64__
2264 ldo -16(%r30),%r29 /* Reference param save area */
2265#endif
2266 BL do_signal,%r2
2267 copy %r0, %r26 /* sigset_t *oldset = NULL */
2268
2269 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2270 ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
2271 reg_restore %r20
2272
2273 b,n syscall_check_sig
2274
2275 /*
2276 * get_register is used by the non access tlb miss handlers to
2277 * copy the value of the general register specified in r8 into
2278 * r1. This routine can't be used for shadowed registers, since
2279 * the rfir will restore the original value. So, for the shadowed
2280 * registers we put a -1 into r1 to indicate that the register
2281 * should not be used (the register being copied could also have
2282 * a -1 in it, but that is OK, it just means that we will have
2283 * to use the slow path instead).
2284 */
2285
2286get_register:
2287 blr %r8,%r0
2288 nop
2289 bv %r0(%r25) /* r0 */
2290 copy %r0,%r1
2291 bv %r0(%r25) /* r1 - shadowed */
2292 ldi -1,%r1
2293 bv %r0(%r25) /* r2 */
2294 copy %r2,%r1
2295 bv %r0(%r25) /* r3 */
2296 copy %r3,%r1
2297 bv %r0(%r25) /* r4 */
2298 copy %r4,%r1
2299 bv %r0(%r25) /* r5 */
2300 copy %r5,%r1
2301 bv %r0(%r25) /* r6 */
2302 copy %r6,%r1
2303 bv %r0(%r25) /* r7 */
2304 copy %r7,%r1
2305 bv %r0(%r25) /* r8 - shadowed */
2306 ldi -1,%r1
2307 bv %r0(%r25) /* r9 - shadowed */
2308 ldi -1,%r1
2309 bv %r0(%r25) /* r10 */
2310 copy %r10,%r1
2311 bv %r0(%r25) /* r11 */
2312 copy %r11,%r1
2313 bv %r0(%r25) /* r12 */
2314 copy %r12,%r1
2315 bv %r0(%r25) /* r13 */
2316 copy %r13,%r1
2317 bv %r0(%r25) /* r14 */
2318 copy %r14,%r1
2319 bv %r0(%r25) /* r15 */
2320 copy %r15,%r1
2321 bv %r0(%r25) /* r16 - shadowed */
2322 ldi -1,%r1
2323 bv %r0(%r25) /* r17 - shadowed */
2324 ldi -1,%r1
2325 bv %r0(%r25) /* r18 */
2326 copy %r18,%r1
2327 bv %r0(%r25) /* r19 */
2328 copy %r19,%r1
2329 bv %r0(%r25) /* r20 */
2330 copy %r20,%r1
2331 bv %r0(%r25) /* r21 */
2332 copy %r21,%r1
2333 bv %r0(%r25) /* r22 */
2334 copy %r22,%r1
2335 bv %r0(%r25) /* r23 */
2336 copy %r23,%r1
2337 bv %r0(%r25) /* r24 - shadowed */
2338 ldi -1,%r1
2339 bv %r0(%r25) /* r25 - shadowed */
2340 ldi -1,%r1
2341 bv %r0(%r25) /* r26 */
2342 copy %r26,%r1
2343 bv %r0(%r25) /* r27 */
2344 copy %r27,%r1
2345 bv %r0(%r25) /* r28 */
2346 copy %r28,%r1
2347 bv %r0(%r25) /* r29 */
2348 copy %r29,%r1
2349 bv %r0(%r25) /* r30 */
2350 copy %r30,%r1
2351 bv %r0(%r25) /* r31 */
2352 copy %r31,%r1
2353
2354 /*
2355 * set_register is used by the non access tlb miss handlers to
2356 * copy the value of r1 into the general register specified in
2357 * r8.
2358 */
2359
2360set_register:
2361 blr %r8,%r0
2362 nop
2363 bv %r0(%r25) /* r0 (silly, but it is a place holder) */
2364 copy %r1,%r0
2365 bv %r0(%r25) /* r1 */
2366 copy %r1,%r1
2367 bv %r0(%r25) /* r2 */
2368 copy %r1,%r2
2369 bv %r0(%r25) /* r3 */
2370 copy %r1,%r3
2371 bv %r0(%r25) /* r4 */
2372 copy %r1,%r4
2373 bv %r0(%r25) /* r5 */
2374 copy %r1,%r5
2375 bv %r0(%r25) /* r6 */
2376 copy %r1,%r6
2377 bv %r0(%r25) /* r7 */
2378 copy %r1,%r7
2379 bv %r0(%r25) /* r8 */
2380 copy %r1,%r8
2381 bv %r0(%r25) /* r9 */
2382 copy %r1,%r9
2383 bv %r0(%r25) /* r10 */
2384 copy %r1,%r10
2385 bv %r0(%r25) /* r11 */
2386 copy %r1,%r11
2387 bv %r0(%r25) /* r12 */
2388 copy %r1,%r12
2389 bv %r0(%r25) /* r13 */
2390 copy %r1,%r13
2391 bv %r0(%r25) /* r14 */
2392 copy %r1,%r14
2393 bv %r0(%r25) /* r15 */
2394 copy %r1,%r15
2395 bv %r0(%r25) /* r16 */
2396 copy %r1,%r16
2397 bv %r0(%r25) /* r17 */
2398 copy %r1,%r17
2399 bv %r0(%r25) /* r18 */
2400 copy %r1,%r18
2401 bv %r0(%r25) /* r19 */
2402 copy %r1,%r19
2403 bv %r0(%r25) /* r20 */
2404 copy %r1,%r20
2405 bv %r0(%r25) /* r21 */
2406 copy %r1,%r21
2407 bv %r0(%r25) /* r22 */
2408 copy %r1,%r22
2409 bv %r0(%r25) /* r23 */
2410 copy %r1,%r23
2411 bv %r0(%r25) /* r24 */
2412 copy %r1,%r24
2413 bv %r0(%r25) /* r25 */
2414 copy %r1,%r25
2415 bv %r0(%r25) /* r26 */
2416 copy %r1,%r26
2417 bv %r0(%r25) /* r27 */
2418 copy %r1,%r27
2419 bv %r0(%r25) /* r28 */
2420 copy %r1,%r28
2421 bv %r0(%r25) /* r29 */
2422 copy %r1,%r29
2423 bv %r0(%r25) /* r30 */
2424 copy %r1,%r30
2425 bv %r0(%r25) /* r31 */
2426 copy %r1,%r31
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
new file mode 100644
index 000000000000..f244fb200db1
--- /dev/null
+++ b/arch/parisc/kernel/firmware.c
@@ -0,0 +1,1405 @@
1/*
2 * arch/parisc/kernel/firmware.c - safe PDC access routines
3 *
4 * PDC == Processor Dependent Code
5 *
6 * See http://www.parisc-linux.org/documentation/index.html
7 * for documentation describing the entry points and calling
8 * conventions defined below.
9 *
10 * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
11 * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
12 * Copyright 2003 Grant Grundler <grundler parisc-linux org>
13 * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
14 * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 */
22
23/* I think it would be in everyone's best interest to follow this
24 * guidelines when writing PDC wrappers:
25 *
26 * - the name of the pdc wrapper should match one of the macros
27 * used for the first two arguments
28 * - don't use caps for random parts of the name
29 * - use the static PDC result buffers and "copyout" to structs
30 * supplied by the caller to encapsulate alignment restrictions
31 * - hold pdc_lock while in PDC or using static result buffers
32 * - use __pa() to convert virtual (kernel) pointers to physical
33 * ones.
34 * - the name of the struct used for pdc return values should equal
35 * one of the macros used for the first two arguments to the
36 * corresponding PDC call
37 * - keep the order of arguments
38 * - don't be smart (setting trailing NUL bytes for strings, return
39 * something useful even if the call failed) unless you are sure
40 * it's not going to affect functionality or performance
41 *
42 * Example:
43 * int pdc_cache_info(struct pdc_cache_info *cache_info )
44 * {
45 * int retval;
46 *
47 * spin_lock_irq(&pdc_lock);
48 * retval = mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
49 * convert_to_wide(pdc_result);
50 * memcpy(cache_info, pdc_result, sizeof(*cache_info));
51 * spin_unlock_irq(&pdc_lock);
52 *
53 * return retval;
54 * }
55 * prumpf 991016
56 */
57
58#include <stdarg.h>
59
60#include <linux/delay.h>
61#include <linux/init.h>
62#include <linux/kernel.h>
63#include <linux/module.h>
64#include <linux/string.h>
65#include <linux/spinlock.h>
66
67#include <asm/page.h>
68#include <asm/pdc.h>
69#include <asm/pdcpat.h>
70#include <asm/system.h>
71#include <asm/processor.h> /* for boot_cpu_data */
72
73static DEFINE_SPINLOCK(pdc_lock);
74static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
75static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
76
77#ifdef __LP64__
78#define WIDE_FIRMWARE 0x1
79#define NARROW_FIRMWARE 0x2
80
81/* Firmware needs to be initially set to narrow to determine the
82 * actual firmware width. */
83int parisc_narrow_firmware = 1;
84#endif
85
86/* on all currently-supported platforms, IODC I/O calls are always
87 * 32-bit calls, and MEM_PDC calls are always the same width as the OS.
88 * This means Cxxx boxes can't run wide kernels right now. -PB
89 *
90 * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on
91 * systems with 32-bit MEM_PDC calls. This will allow wide kernels to
92 * run on Cxxx boxes now. -RB
93 *
94 * Note that some PAT boxes may have 64-bit IODC I/O...
95 */
96
97#ifdef __LP64__
98long real64_call(unsigned long function, ...);
99#endif
100long real32_call(unsigned long function, ...);
101
102#ifdef __LP64__
103# define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
104# define mem_pdc_call(args...) unlikely(parisc_narrow_firmware) ? real32_call(MEM_PDC, args) : real64_call(MEM_PDC, args)
105#else
106# define MEM_PDC (unsigned long)PAGE0->mem_pdc
107# define mem_pdc_call(args...) real32_call(MEM_PDC, args)
108#endif
109
110
111/**
112 * f_extend - Convert PDC addresses to kernel addresses.
113 * @address: Address returned from PDC.
114 *
115 * This function is used to convert PDC addresses into kernel addresses
116 * when the PDC address size and kernel address size are different.
117 */
118static unsigned long f_extend(unsigned long address)
119{
120#ifdef __LP64__
121 if(unlikely(parisc_narrow_firmware)) {
122 if((address & 0xff000000) == 0xf0000000)
123 return 0xf0f0f0f000000000UL | (u32)address;
124
125 if((address & 0xf0000000) == 0xf0000000)
126 return 0xffffffff00000000UL | (u32)address;
127 }
128#endif
129 return address;
130}
131
132/**
133 * convert_to_wide - Convert the return buffer addresses into kernel addresses.
134 * @address: The return buffer from PDC.
135 *
136 * This function is used to convert the return buffer addresses retrieved from PDC
137 * into kernel addresses when the PDC address size and kernel address size are
138 * different.
139 */
140static void convert_to_wide(unsigned long *addr)
141{
142#ifdef __LP64__
143 int i;
144 unsigned int *p = (unsigned int *)addr;
145
146 if(unlikely(parisc_narrow_firmware)) {
147 for(i = 31; i >= 0; --i)
148 addr[i] = p[i];
149 }
150#endif
151}
152
153/**
154 * set_firmware_width - Determine if the firmware is wide or narrow.
155 *
156 * This function must be called before any pdc_* function that uses the convert_to_wide
157 * function.
158 */
159void __init set_firmware_width(void)
160{
161#ifdef __LP64__
162 int retval;
163
164 spin_lock_irq(&pdc_lock);
165 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
166 convert_to_wide(pdc_result);
167 if(pdc_result[0] != NARROW_FIRMWARE)
168 parisc_narrow_firmware = 0;
169 spin_unlock_irq(&pdc_lock);
170#endif
171}
172
173/**
174 * pdc_emergency_unlock - Unlock the linux pdc lock
175 *
176 * This call unlocks the linux pdc lock in case we need some PDC functions
177 * (like pdc_add_valid) during kernel stack dump.
178 */
179void pdc_emergency_unlock(void)
180{
181 /* Spinlock DEBUG code freaks out if we unconditionally unlock */
182 if (spin_is_locked(&pdc_lock))
183 spin_unlock(&pdc_lock);
184}
185
186
187/**
188 * pdc_add_valid - Verify address can be accessed without causing a HPMC.
189 * @address: Address to be verified.
190 *
191 * This PDC call attempts to read from the specified address and verifies
192 * if the address is valid.
193 *
194 * The return value is PDC_OK (0) in case accessing this address is valid.
195 */
196int pdc_add_valid(unsigned long address)
197{
198 int retval;
199
200 spin_lock_irq(&pdc_lock);
201 retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
202 spin_unlock_irq(&pdc_lock);
203
204 return retval;
205}
206EXPORT_SYMBOL(pdc_add_valid);
207
208/**
209 * pdc_chassis_info - Return chassis information.
210 * @result: The return buffer.
211 * @chassis_info: The memory buffer address.
212 * @len: The size of the memory buffer address.
213 *
214 * An HVERSION dependent call for returning the chassis information.
215 */
216int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
217{
218 int retval;
219
220 spin_lock_irq(&pdc_lock);
221 memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
222 memcpy(&pdc_result2, led_info, len);
223 retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
224 __pa(pdc_result), __pa(pdc_result2), len);
225 memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
226 memcpy(led_info, pdc_result2, len);
227 spin_unlock_irq(&pdc_lock);
228
229 return retval;
230}
231
232/**
233 * pdc_pat_chassis_send_log - Sends a PDC PAT CHASSIS log message.
234 * @retval: -1 on error, 0 on success. Other value are PDC errors
235 *
236 * Must be correctly formatted or expect system crash
237 */
238#ifdef __LP64__
239int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
240{
241 int retval = 0;
242
243 if (!is_pdc_pat())
244 return -1;
245
246 spin_lock_irq(&pdc_lock);
247 retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
248 spin_unlock_irq(&pdc_lock);
249
250 return retval;
251}
252#endif
253
254/**
255 * pdc_chassis_disp - Updates display
256 * @retval: -1 on error, 0 on success
257 *
258 * Works on old PDC only (E class, others?)
259 */
260int pdc_chassis_disp(unsigned long disp)
261{
262 int retval = 0;
263
264 spin_lock_irq(&pdc_lock);
265 retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
266 spin_unlock_irq(&pdc_lock);
267
268 return retval;
269}
270
271/**
272 * pdc_coproc_cfg - To identify coprocessors attached to the processor.
273 * @pdc_coproc_info: Return buffer address.
274 *
275 * This PDC call returns the presence and status of all the coprocessors
276 * attached to the processor.
277 */
278int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
279{
280 int retval;
281
282 spin_lock_irq(&pdc_lock);
283 retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
284 convert_to_wide(pdc_result);
285 pdc_coproc_info->ccr_functional = pdc_result[0];
286 pdc_coproc_info->ccr_present = pdc_result[1];
287 pdc_coproc_info->revision = pdc_result[17];
288 pdc_coproc_info->model = pdc_result[18];
289 spin_unlock_irq(&pdc_lock);
290
291 return retval;
292}
293
294/**
295 * pdc_iodc_read - Read data from the modules IODC.
296 * @actcnt: The actual number of bytes.
297 * @hpa: The HPA of the module for the iodc read.
298 * @index: The iodc entry point.
299 * @iodc_data: A buffer memory for the iodc options.
300 * @iodc_data_size: Size of the memory buffer.
301 *
302 * This PDC call reads from the IODC of the module specified by the hpa
303 * argument.
304 */
305int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
306 void *iodc_data, unsigned int iodc_data_size)
307{
308 int retval;
309
310 spin_lock_irq(&pdc_lock);
311 retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa,
312 index, __pa(pdc_result2), iodc_data_size);
313 convert_to_wide(pdc_result);
314 *actcnt = pdc_result[0];
315 memcpy(iodc_data, pdc_result2, iodc_data_size);
316 spin_unlock_irq(&pdc_lock);
317
318 return retval;
319}
320EXPORT_SYMBOL(pdc_iodc_read);
321
322/**
323 * pdc_system_map_find_mods - Locate unarchitected modules.
324 * @pdc_mod_info: Return buffer address.
325 * @mod_path: pointer to dev path structure.
326 * @mod_index: fixed address module index.
327 *
328 * To locate and identify modules which reside at fixed I/O addresses, which
329 * do not self-identify via architected bus walks.
330 */
331int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
332 struct pdc_module_path *mod_path, long mod_index)
333{
334 int retval;
335
336 spin_lock_irq(&pdc_lock);
337 retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result),
338 __pa(pdc_result2), mod_index);
339 convert_to_wide(pdc_result);
340 memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
341 memcpy(mod_path, pdc_result2, sizeof(*mod_path));
342 spin_unlock_irq(&pdc_lock);
343
344 pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
345 return retval;
346}
347
348/**
349 * pdc_system_map_find_addrs - Retrieve additional address ranges.
350 * @pdc_addr_info: Return buffer address.
351 * @mod_index: Fixed address module index.
352 * @addr_index: Address range index.
353 *
354 * Retrieve additional information about subsequent address ranges for modules
355 * with multiple address ranges.
356 */
357int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
358 long mod_index, long addr_index)
359{
360 int retval;
361
362 spin_lock_irq(&pdc_lock);
363 retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
364 mod_index, addr_index);
365 convert_to_wide(pdc_result);
366 memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
367 spin_unlock_irq(&pdc_lock);
368
369 pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
370 return retval;
371}
372
373/**
374 * pdc_model_info - Return model information about the processor.
375 * @model: The return buffer.
376 *
377 * Returns the version numbers, identifiers, and capabilities from the processor module.
378 */
379int pdc_model_info(struct pdc_model *model)
380{
381 int retval;
382
383 spin_lock_irq(&pdc_lock);
384 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
385 convert_to_wide(pdc_result);
386 memcpy(model, pdc_result, sizeof(*model));
387 spin_unlock_irq(&pdc_lock);
388
389 return retval;
390}
391
392/**
393 * pdc_model_sysmodel - Get the system model name.
394 * @name: A char array of at least 81 characters.
395 *
396 * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L)
397 */
398int pdc_model_sysmodel(char *name)
399{
400 int retval;
401
402 spin_lock_irq(&pdc_lock);
403 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
404 OS_ID_HPUX, __pa(name));
405 convert_to_wide(pdc_result);
406
407 if (retval == PDC_OK) {
408 name[pdc_result[0]] = '\0'; /* add trailing '\0' */
409 } else {
410 name[0] = 0;
411 }
412 spin_unlock_irq(&pdc_lock);
413
414 return retval;
415}
416
417/**
418 * pdc_model_versions - Identify the version number of each processor.
419 * @cpu_id: The return buffer.
420 * @id: The id of the processor to check.
421 *
422 * Returns the version number for each processor component.
423 *
424 * This comment was here before, but I do not know what it means :( -RB
425 * id: 0 = cpu revision, 1 = boot-rom-version
426 */
427int pdc_model_versions(unsigned long *versions, int id)
428{
429 int retval;
430
431 spin_lock_irq(&pdc_lock);
432 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
433 convert_to_wide(pdc_result);
434 *versions = pdc_result[0];
435 spin_unlock_irq(&pdc_lock);
436
437 return retval;
438}
439
440/**
441 * pdc_model_cpuid - Returns the CPU_ID.
442 * @cpu_id: The return buffer.
443 *
444 * Returns the CPU_ID value which uniquely identifies the cpu portion of
445 * the processor module.
446 */
447int pdc_model_cpuid(unsigned long *cpu_id)
448{
449 int retval;
450
451 spin_lock_irq(&pdc_lock);
452 pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
453 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
454 convert_to_wide(pdc_result);
455 *cpu_id = pdc_result[0];
456 spin_unlock_irq(&pdc_lock);
457
458 return retval;
459}
460
461/**
462 * pdc_model_capabilities - Returns the platform capabilities.
463 * @capabilities: The return buffer.
464 *
465 * Returns information about platform support for 32- and/or 64-bit
466 * OSes, IO-PDIR coherency, and virtual aliasing.
467 */
468int pdc_model_capabilities(unsigned long *capabilities)
469{
470 int retval;
471
472 spin_lock_irq(&pdc_lock);
473 pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
474 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
475 convert_to_wide(pdc_result);
476 *capabilities = pdc_result[0];
477 spin_unlock_irq(&pdc_lock);
478
479 return retval;
480}
481
482/**
483 * pdc_cache_info - Return cache and TLB information.
484 * @cache_info: The return buffer.
485 *
486 * Returns information about the processor's cache and TLB.
487 */
488int pdc_cache_info(struct pdc_cache_info *cache_info)
489{
490 int retval;
491
492 spin_lock_irq(&pdc_lock);
493 retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
494 convert_to_wide(pdc_result);
495 memcpy(cache_info, pdc_result, sizeof(*cache_info));
496 spin_unlock_irq(&pdc_lock);
497
498 return retval;
499}
500
501#ifndef CONFIG_PA20
502/**
503 * pdc_btlb_info - Return block TLB information.
504 * @btlb: The return buffer.
505 *
506 * Returns information about the hardware Block TLB.
507 */
508int pdc_btlb_info(struct pdc_btlb_info *btlb)
509{
510 int retval;
511
512 spin_lock_irq(&pdc_lock);
513 retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
514 memcpy(btlb, pdc_result, sizeof(*btlb));
515 spin_unlock_irq(&pdc_lock);
516
517 if(retval < 0) {
518 btlb->max_size = 0;
519 }
520 return retval;
521}
522
523/**
524 * pdc_mem_map_hpa - Find fixed module information.
525 * @address: The return buffer
526 * @mod_path: pointer to dev path structure.
527 *
528 * This call was developed for S700 workstations to allow the kernel to find
529 * the I/O devices (Core I/O). In the future (Kittyhawk and beyond) this
530 * call will be replaced (on workstations) by the architected PDC_SYSTEM_MAP
531 * call.
532 *
533 * This call is supported by all existing S700 workstations (up to Gecko).
534 */
535int pdc_mem_map_hpa(struct pdc_memory_map *address,
536 struct pdc_module_path *mod_path)
537{
538 int retval;
539
540 spin_lock_irq(&pdc_lock);
541 memcpy(pdc_result2, mod_path, sizeof(*mod_path));
542 retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
543 __pa(pdc_result2));
544 memcpy(address, pdc_result, sizeof(*address));
545 spin_unlock_irq(&pdc_lock);
546
547 return retval;
548}
549#endif /* !CONFIG_PA20 */
550
551/**
552 * pdc_lan_station_id - Get the LAN address.
553 * @lan_addr: The return buffer.
554 * @hpa: The network device HPA.
555 *
556 * Get the LAN station address when it is not directly available from the LAN hardware.
557 */
558int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
559{
560 int retval;
561
562 spin_lock_irq(&pdc_lock);
563 retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
564 __pa(pdc_result), hpa);
565 if (retval < 0) {
566 /* FIXME: else read MAC from NVRAM */
567 memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
568 } else {
569 memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
570 }
571 spin_unlock_irq(&pdc_lock);
572
573 return retval;
574}
575EXPORT_SYMBOL(pdc_lan_station_id);
576
577/**
578 * pdc_stable_read - Read data from Stable Storage.
579 * @staddr: Stable Storage address to access.
580 * @memaddr: The memory address where Stable Storage data shall be copied.
581 * @count: number of bytes to transfert. count is multiple of 4.
582 *
583 * This PDC call reads from the Stable Storage address supplied in staddr
584 * and copies count bytes to the memory address memaddr.
585 * The call will fail if staddr+count > PDC_STABLE size.
586 */
587int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
588{
589 int retval;
590
591 spin_lock_irq(&pdc_lock);
592 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
593 __pa(pdc_result), count);
594 convert_to_wide(pdc_result);
595 memcpy(memaddr, pdc_result, count);
596 spin_unlock_irq(&pdc_lock);
597
598 return retval;
599}
600EXPORT_SYMBOL(pdc_stable_read);
601
602/**
603 * pdc_stable_write - Write data to Stable Storage.
604 * @staddr: Stable Storage address to access.
605 * @memaddr: The memory address where Stable Storage data shall be read from.
606 * @count: number of bytes to transfert. count is multiple of 4.
607 *
608 * This PDC call reads count bytes from the supplied memaddr address,
609 * and copies count bytes to the Stable Storage address staddr.
610 * The call will fail if staddr+count > PDC_STABLE size.
611 */
612int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
613{
614 int retval;
615
616 spin_lock_irq(&pdc_lock);
617 memcpy(pdc_result, memaddr, count);
618 convert_to_wide(pdc_result);
619 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
620 __pa(pdc_result), count);
621 spin_unlock_irq(&pdc_lock);
622
623 return retval;
624}
625EXPORT_SYMBOL(pdc_stable_write);
626
627/**
628 * pdc_stable_get_size - Get Stable Storage size in bytes.
629 * @size: pointer where the size will be stored.
630 *
631 * This PDC call returns the number of bytes in the processor's Stable
632 * Storage, which is the number of contiguous bytes implemented in Stable
633 * Storage starting from staddr=0. size in an unsigned 64-bit integer
634 * which is a multiple of four.
635 */
636int pdc_stable_get_size(unsigned long *size)
637{
638 int retval;
639
640 spin_lock_irq(&pdc_lock);
641 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
642 *size = pdc_result[0];
643 spin_unlock_irq(&pdc_lock);
644
645 return retval;
646}
647EXPORT_SYMBOL(pdc_stable_get_size);
648
649/**
650 * pdc_stable_verify_contents - Checks that Stable Storage contents are valid.
651 *
652 * This PDC call is meant to be used to check the integrity of the current
653 * contents of Stable Storage.
654 */
655int pdc_stable_verify_contents(void)
656{
657 int retval;
658
659 spin_lock_irq(&pdc_lock);
660 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
661 spin_unlock_irq(&pdc_lock);
662
663 return retval;
664}
665EXPORT_SYMBOL(pdc_stable_verify_contents);
666
667/**
668 * pdc_stable_initialize - Sets Stable Storage contents to zero and initialize
669 * the validity indicator.
670 *
671 * This PDC call will erase all contents of Stable Storage. Use with care!
672 */
673int pdc_stable_initialize(void)
674{
675 int retval;
676
677 spin_lock_irq(&pdc_lock);
678 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
679 spin_unlock_irq(&pdc_lock);
680
681 return retval;
682}
683EXPORT_SYMBOL(pdc_stable_initialize);
684
685/**
686 * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
687 * @hwpath: fully bc.mod style path to the device.
688 * @initiator: the array to return the result into
689 *
690 * Get the SCSI operational parameters from PDC.
691 * Needed since HPUX never used BIOS or symbios card NVRAM.
692 * Most ncr/sym cards won't have an entry and just use whatever
693 * capabilities of the card are (eg Ultra, LVD). But there are
694 * several cases where it's useful:
695 * o set SCSI id for Multi-initiator clusters,
696 * o cable too long (ie SE scsi 10Mhz won't support 6m length),
697 * o bus width exported is less than what the interface chip supports.
698 */
699int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
700{
701 int retval;
702
703 spin_lock_irq(&pdc_lock);
704
705/* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */
706#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
707 strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0)
708
709 retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR,
710 __pa(pdc_result), __pa(hwpath));
711 if (retval < PDC_OK)
712 goto out;
713
714 if (pdc_result[0] < 16) {
715 initiator->host_id = pdc_result[0];
716 } else {
717 initiator->host_id = -1;
718 }
719
720 /*
721 * Sprockets and Piranha return 20 or 40 (MT/s). Prelude returns
722 * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively
723 */
724 switch (pdc_result[1]) {
725 case 1: initiator->factor = 50; break;
726 case 2: initiator->factor = 25; break;
727 case 5: initiator->factor = 12; break;
728 case 25: initiator->factor = 10; break;
729 case 20: initiator->factor = 12; break;
730 case 40: initiator->factor = 10; break;
731 default: initiator->factor = -1; break;
732 }
733
734 if (IS_SPROCKETS()) {
735 initiator->width = pdc_result[4];
736 initiator->mode = pdc_result[5];
737 } else {
738 initiator->width = -1;
739 initiator->mode = -1;
740 }
741
742 out:
743 spin_unlock_irq(&pdc_lock);
744 return (retval >= PDC_OK);
745}
746EXPORT_SYMBOL(pdc_get_initiator);
747
748
749/**
750 * pdc_pci_irt_size - Get the number of entries in the interrupt routing table.
751 * @num_entries: The return value.
752 * @hpa: The HPA for the device.
753 *
754 * This PDC function returns the number of entries in the specified cell's
755 * interrupt table.
756 * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
757 */
758int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
759{
760 int retval;
761
762 spin_lock_irq(&pdc_lock);
763 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
764 __pa(pdc_result), hpa);
765 convert_to_wide(pdc_result);
766 *num_entries = pdc_result[0];
767 spin_unlock_irq(&pdc_lock);
768
769 return retval;
770}
771
772/**
773 * pdc_pci_irt - Get the PCI interrupt routing table.
774 * @num_entries: The number of entries in the table.
775 * @hpa: The Hard Physical Address of the device.
776 * @tbl:
777 *
778 * Get the PCI interrupt routing table for the device at the given HPA.
779 * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
780 */
781int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
782{
783 int retval;
784
785 BUG_ON((unsigned long)tbl & 0x7);
786
787 spin_lock_irq(&pdc_lock);
788 pdc_result[0] = num_entries;
789 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
790 __pa(pdc_result), hpa, __pa(tbl));
791 spin_unlock_irq(&pdc_lock);
792
793 return retval;
794}
795
796
797#if 0 /* UNTEST CODE - left here in case someone needs it */
798
799/**
800 * pdc_pci_config_read - read PCI config space.
801 * @hpa token from PDC to indicate which PCI device
802 * @pci_addr configuration space address to read from
803 *
804 * Read PCI Configuration space *before* linux PCI subsystem is running.
805 */
806unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
807{
808 int retval;
809 spin_lock_irq(&pdc_lock);
810 pdc_result[0] = 0;
811 pdc_result[1] = 0;
812 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG,
813 __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
814 spin_unlock_irq(&pdc_lock);
815 return retval ? ~0 : (unsigned int) pdc_result[0];
816}
817
818
819/**
820 * pdc_pci_config_write - read PCI config space.
821 * @hpa token from PDC to indicate which PCI device
822 * @pci_addr configuration space address to write
823 * @val value we want in the 32-bit register
824 *
825 * Write PCI Configuration space *before* linux PCI subsystem is running.
826 */
827void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
828{
829 int retval;
830 spin_lock_irq(&pdc_lock);
831 pdc_result[0] = 0;
832 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG,
833 __pa(pdc_result), hpa,
834 cfg_addr&~3UL, 4UL, (unsigned long) val);
835 spin_unlock_irq(&pdc_lock);
836 return retval;
837}
838#endif /* UNTESTED CODE */
839
840/**
841 * pdc_tod_read - Read the Time-Of-Day clock.
842 * @tod: The return buffer:
843 *
844 * Read the Time-Of-Day clock
845 */
846int pdc_tod_read(struct pdc_tod *tod)
847{
848 int retval;
849
850 spin_lock_irq(&pdc_lock);
851 retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
852 convert_to_wide(pdc_result);
853 memcpy(tod, pdc_result, sizeof(*tod));
854 spin_unlock_irq(&pdc_lock);
855
856 return retval;
857}
858EXPORT_SYMBOL(pdc_tod_read);
859
860/**
861 * pdc_tod_set - Set the Time-Of-Day clock.
862 * @sec: The number of seconds since epoch.
863 * @usec: The number of micro seconds.
864 *
865 * Set the Time-Of-Day clock.
866 */
867int pdc_tod_set(unsigned long sec, unsigned long usec)
868{
869 int retval;
870
871 spin_lock_irq(&pdc_lock);
872 retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
873 spin_unlock_irq(&pdc_lock);
874
875 return retval;
876}
877EXPORT_SYMBOL(pdc_tod_set);
878
879#ifdef __LP64__
880int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
881 struct pdc_memory_table *tbl, unsigned long entries)
882{
883 int retval;
884
885 spin_lock_irq(&pdc_lock);
886 retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
887 convert_to_wide(pdc_result);
888 memcpy(r_addr, pdc_result, sizeof(*r_addr));
889 memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
890 spin_unlock_irq(&pdc_lock);
891
892 return retval;
893}
894#endif /* __LP64__ */
895
896/* FIXME: Is this pdc used? I could not find type reference to ftc_bitmap
897 * so I guessed at unsigned long. Someone who knows what this does, can fix
898 * it later. :)
899 */
900int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
901{
902 int retval;
903
904 spin_lock_irq(&pdc_lock);
905 retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
906 PDC_FIRM_TEST_MAGIC, ftc_bitmap);
907 spin_unlock_irq(&pdc_lock);
908
909 return retval;
910}
911
912/*
913 * pdc_do_reset - Reset the system.
914 *
915 * Reset the system.
916 */
917int pdc_do_reset(void)
918{
919 int retval;
920
921 spin_lock_irq(&pdc_lock);
922 retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
923 spin_unlock_irq(&pdc_lock);
924
925 return retval;
926}
927
928/*
929 * pdc_soft_power_info - Enable soft power switch.
930 * @power_reg: address of soft power register
931 *
932 * Return the absolute address of the soft power switch register
933 */
934int __init pdc_soft_power_info(unsigned long *power_reg)
935{
936 int retval;
937
938 *power_reg = (unsigned long) (-1);
939
940 spin_lock_irq(&pdc_lock);
941 retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
942 if (retval == PDC_OK) {
943 convert_to_wide(pdc_result);
944 *power_reg = f_extend(pdc_result[0]);
945 }
946 spin_unlock_irq(&pdc_lock);
947
948 return retval;
949}
950
951/*
952 * pdc_soft_power_button - Control the soft power button behaviour
953 * @sw_control: 0 for hardware control, 1 for software control
954 *
955 *
956 * This PDC function places the soft power button under software or
957 * hardware control.
958 * Under software control the OS may control to when to allow to shut
959 * down the system. Under hardware control pressing the power button
960 * powers off the system immediately.
961 */
962int pdc_soft_power_button(int sw_control)
963{
964 int retval;
965 spin_lock_irq(&pdc_lock);
966 retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
967 spin_unlock_irq(&pdc_lock);
968 return retval;
969}
970
971/*
972 * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
973 * Primarily a problem on T600 (which parisc-linux doesn't support) but
974 * who knows what other platform firmware might do with this OS "hook".
975 */
976void pdc_io_reset(void)
977{
978 spin_lock_irq(&pdc_lock);
979 mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
980 spin_unlock_irq(&pdc_lock);
981}
982
983/*
984 * pdc_io_reset_devices - Hack to Stop USB controller
985 *
986 * If PDC used the usb controller, the usb controller
987 * is still running and will crash the machines during iommu
988 * setup, because of still running DMA. This PDC call
989 * stops the USB controller.
990 * Normally called after calling pdc_io_reset().
991 */
992void pdc_io_reset_devices(void)
993{
994 spin_lock_irq(&pdc_lock);
995 mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
996 spin_unlock_irq(&pdc_lock);
997}
998
999
1000/**
1001 * pdc_iodc_putc - Console character print using IODC.
1002 * @c: the character to output.
1003 *
1004 * Note that only these special chars are architected for console IODC io:
1005 * BEL, BS, CR, and LF. Others are passed through.
1006 * Since the HP console requires CR+LF to perform a 'newline', we translate
1007 * "\n" to "\r\n".
1008 */
1009void pdc_iodc_putc(unsigned char c)
1010{
1011 /* XXX Should we spinlock posx usage */
1012 static int posx; /* for simple TAB-Simulation... */
1013 static int __attribute__((aligned(8))) iodc_retbuf[32];
1014 static char __attribute__((aligned(64))) iodc_dbuf[4096];
1015 unsigned int n;
1016 unsigned int flags;
1017
1018 switch (c) {
1019 case '\n':
1020 iodc_dbuf[0] = '\r';
1021 iodc_dbuf[1] = '\n';
1022 n = 2;
1023 posx = 0;
1024 break;
1025 case '\t':
1026 pdc_iodc_putc(' ');
1027 while (posx & 7) /* expand TAB */
1028 pdc_iodc_putc(' ');
1029 return; /* return since IODC can't handle this */
1030 case '\b':
1031 posx-=2; /* BS */
1032 default:
1033 iodc_dbuf[0] = c;
1034 n = 1;
1035 posx++;
1036 break;
1037 }
1038
1039 spin_lock_irqsave(&pdc_lock, flags);
1040 real32_call(PAGE0->mem_cons.iodc_io,
1041 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
1042 PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
1043 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
1044 spin_unlock_irqrestore(&pdc_lock, flags);
1045}
1046
1047/**
1048 * pdc_iodc_outc - Console character print using IODC (without conversions).
1049 * @c: the character to output.
1050 *
1051 * Write the character directly to the IODC console.
1052 */
1053void pdc_iodc_outc(unsigned char c)
1054{
1055 unsigned int n, flags;
1056
1057 /* fill buffer with one caracter and print it */
1058 static int __attribute__((aligned(8))) iodc_retbuf[32];
1059 static char __attribute__((aligned(64))) iodc_dbuf[4096];
1060
1061 n = 1;
1062 iodc_dbuf[0] = c;
1063
1064 spin_lock_irqsave(&pdc_lock, flags);
1065 real32_call(PAGE0->mem_cons.iodc_io,
1066 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
1067 PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
1068 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
1069 spin_unlock_irqrestore(&pdc_lock, flags);
1070}
1071
1072/**
1073 * pdc_iodc_getc - Read a character (non-blocking) from the PDC console.
1074 *
1075 * Read a character (non-blocking) from the PDC console, returns -1 if
1076 * key is not present.
1077 */
1078int pdc_iodc_getc(void)
1079{
1080 unsigned int flags;
1081 static int __attribute__((aligned(8))) iodc_retbuf[32];
1082 static char __attribute__((aligned(64))) iodc_dbuf[4096];
1083 int ch;
1084 int status;
1085
1086 /* Bail if no console input device. */
1087 if (!PAGE0->mem_kbd.iodc_io)
1088 return 0;
1089
1090 /* wait for a keyboard (rs232)-input */
1091 spin_lock_irqsave(&pdc_lock, flags);
1092 real32_call(PAGE0->mem_kbd.iodc_io,
1093 (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
1094 PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
1095 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
1096
1097 ch = *iodc_dbuf;
1098 status = *iodc_retbuf;
1099 spin_unlock_irqrestore(&pdc_lock, flags);
1100
1101 if (status == 0)
1102 return -1;
1103
1104 return ch;
1105}
1106
1107int pdc_sti_call(unsigned long func, unsigned long flags,
1108 unsigned long inptr, unsigned long outputr,
1109 unsigned long glob_cfg)
1110{
1111 int retval;
1112
1113 spin_lock_irq(&pdc_lock);
1114 retval = real32_call(func, flags, inptr, outputr, glob_cfg);
1115 spin_unlock_irq(&pdc_lock);
1116
1117 return retval;
1118}
1119EXPORT_SYMBOL(pdc_sti_call);
1120
1121#ifdef __LP64__
1122/**
1123 * pdc_pat_cell_get_number - Returns the cell number.
1124 * @cell_info: The return buffer.
1125 *
1126 * This PDC call returns the cell number of the cell from which the call
1127 * is made.
1128 */
1129int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
1130{
1131 int retval;
1132
1133 spin_lock_irq(&pdc_lock);
1134 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
1135 memcpy(cell_info, pdc_result, sizeof(*cell_info));
1136 spin_unlock_irq(&pdc_lock);
1137
1138 return retval;
1139}
1140
1141/**
1142 * pdc_pat_cell_module - Retrieve the cell's module information.
1143 * @actcnt: The number of bytes written to mem_addr.
1144 * @ploc: The physical location.
1145 * @mod: The module index.
1146 * @view_type: The view of the address type.
1147 * @mem_addr: The return buffer.
1148 *
1149 * This PDC call returns information about each module attached to the cell
1150 * at the specified location.
1151 */
1152int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
1153 unsigned long view_type, void *mem_addr)
1154{
1155 int retval;
1156 static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
1157
1158 spin_lock_irq(&pdc_lock);
1159 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result),
1160 ploc, mod, view_type, __pa(&result));
1161 if(!retval) {
1162 *actcnt = pdc_result[0];
1163 memcpy(mem_addr, &result, *actcnt);
1164 }
1165 spin_unlock_irq(&pdc_lock);
1166
1167 return retval;
1168}
1169
1170/**
1171 * pdc_pat_cpu_get_number - Retrieve the cpu number.
1172 * @cpu_info: The return buffer.
1173 * @hpa: The Hard Physical Address of the CPU.
1174 *
1175 * Retrieve the cpu number for the cpu at the specified HPA.
1176 */
1177int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
1178{
1179 int retval;
1180
1181 spin_lock_irq(&pdc_lock);
1182 retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
1183 __pa(&pdc_result), hpa);
1184 memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
1185 spin_unlock_irq(&pdc_lock);
1186
1187 return retval;
1188}
1189
1190/**
1191 * pdc_pat_get_irt_size - Retrieve the number of entries in the cell's interrupt table.
1192 * @num_entries: The return value.
1193 * @cell_num: The target cell.
1194 *
1195 * This PDC function returns the number of entries in the specified cell's
1196 * interrupt table.
1197 */
1198int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
1199{
1200 int retval;
1201
1202 spin_lock_irq(&pdc_lock);
1203 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
1204 __pa(pdc_result), cell_num);
1205 *num_entries = pdc_result[0];
1206 spin_unlock_irq(&pdc_lock);
1207
1208 return retval;
1209}
1210
1211/**
1212 * pdc_pat_get_irt - Retrieve the cell's interrupt table.
1213 * @r_addr: The return buffer.
1214 * @cell_num: The target cell.
1215 *
1216 * This PDC function returns the actual interrupt table for the specified cell.
1217 */
1218int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
1219{
1220 int retval;
1221
1222 spin_lock_irq(&pdc_lock);
1223 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
1224 __pa(r_addr), cell_num);
1225 spin_unlock_irq(&pdc_lock);
1226
1227 return retval;
1228}
1229
1230/**
1231 * pdc_pat_pd_get_addr_map - Retrieve information about memory address ranges.
1232 * @actlen: The return buffer.
1233 * @mem_addr: Pointer to the memory buffer.
1234 * @count: The number of bytes to read from the buffer.
1235 * @offset: The offset with respect to the beginning of the buffer.
1236 *
1237 */
1238int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
1239 unsigned long count, unsigned long offset)
1240{
1241 int retval;
1242
1243 spin_lock_irq(&pdc_lock);
1244 retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result),
1245 __pa(pdc_result2), count, offset);
1246 *actual_len = pdc_result[0];
1247 memcpy(mem_addr, pdc_result2, *actual_len);
1248 spin_unlock_irq(&pdc_lock);
1249
1250 return retval;
1251}
1252
1253/**
1254 * pdc_pat_io_pci_cfg_read - Read PCI configuration space.
1255 * @pci_addr: PCI configuration space address for which the read request is being made.
1256 * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4.
1257 * @mem_addr: Pointer to return memory buffer.
1258 *
1259 */
1260int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
1261{
1262 int retval;
1263 spin_lock_irq(&pdc_lock);
1264 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ,
1265 __pa(pdc_result), pci_addr, pci_size);
1266 switch(pci_size) {
1267 case 1: *(u8 *) mem_addr = (u8) pdc_result[0];
1268 case 2: *(u16 *)mem_addr = (u16) pdc_result[0];
1269 case 4: *(u32 *)mem_addr = (u32) pdc_result[0];
1270 }
1271 spin_unlock_irq(&pdc_lock);
1272
1273 return retval;
1274}
1275
1276/**
1277 * pdc_pat_io_pci_cfg_write - Retrieve information about memory address ranges.
1278 * @pci_addr: PCI configuration space address for which the write request is being made.
1279 * @pci_size: Size of write in bytes. Valid values are 1, 2, and 4.
1280 * @value: Pointer to 1, 2, or 4 byte value in low order end of argument to be
1281 * written to PCI Config space.
1282 *
1283 */
1284int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
1285{
1286 int retval;
1287
1288 spin_lock_irq(&pdc_lock);
1289 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE,
1290 pci_addr, pci_size, val);
1291 spin_unlock_irq(&pdc_lock);
1292
1293 return retval;
1294}
1295#endif /* __LP64__ */
1296
1297
1298/***************** 32-bit real-mode calls ***********/
1299/* The struct below is used
1300 * to overlay real_stack (real2.S), preparing a 32-bit call frame.
1301 * real32_call_asm() then uses this stack in narrow real mode
1302 */
1303
1304struct narrow_stack {
1305 /* use int, not long which is 64 bits */
1306 unsigned int arg13;
1307 unsigned int arg12;
1308 unsigned int arg11;
1309 unsigned int arg10;
1310 unsigned int arg9;
1311 unsigned int arg8;
1312 unsigned int arg7;
1313 unsigned int arg6;
1314 unsigned int arg5;
1315 unsigned int arg4;
1316 unsigned int arg3;
1317 unsigned int arg2;
1318 unsigned int arg1;
1319 unsigned int arg0;
1320 unsigned int frame_marker[8];
1321 unsigned int sp;
1322 /* in reality, there's nearly 8k of stack after this */
1323};
1324
1325long real32_call(unsigned long fn, ...)
1326{
1327 va_list args;
1328 extern struct narrow_stack real_stack;
1329 extern unsigned long real32_call_asm(unsigned int *,
1330 unsigned int *,
1331 unsigned int);
1332
1333 va_start(args, fn);
1334 real_stack.arg0 = va_arg(args, unsigned int);
1335 real_stack.arg1 = va_arg(args, unsigned int);
1336 real_stack.arg2 = va_arg(args, unsigned int);
1337 real_stack.arg3 = va_arg(args, unsigned int);
1338 real_stack.arg4 = va_arg(args, unsigned int);
1339 real_stack.arg5 = va_arg(args, unsigned int);
1340 real_stack.arg6 = va_arg(args, unsigned int);
1341 real_stack.arg7 = va_arg(args, unsigned int);
1342 real_stack.arg8 = va_arg(args, unsigned int);
1343 real_stack.arg9 = va_arg(args, unsigned int);
1344 real_stack.arg10 = va_arg(args, unsigned int);
1345 real_stack.arg11 = va_arg(args, unsigned int);
1346 real_stack.arg12 = va_arg(args, unsigned int);
1347 real_stack.arg13 = va_arg(args, unsigned int);
1348 va_end(args);
1349
1350 return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
1351}
1352
1353#ifdef __LP64__
1354/***************** 64-bit real-mode calls ***********/
1355
1356struct wide_stack {
1357 unsigned long arg0;
1358 unsigned long arg1;
1359 unsigned long arg2;
1360 unsigned long arg3;
1361 unsigned long arg4;
1362 unsigned long arg5;
1363 unsigned long arg6;
1364 unsigned long arg7;
1365 unsigned long arg8;
1366 unsigned long arg9;
1367 unsigned long arg10;
1368 unsigned long arg11;
1369 unsigned long arg12;
1370 unsigned long arg13;
1371 unsigned long frame_marker[2]; /* rp, previous sp */
1372 unsigned long sp;
1373 /* in reality, there's nearly 8k of stack after this */
1374};
1375
1376long real64_call(unsigned long fn, ...)
1377{
1378 va_list args;
1379 extern struct wide_stack real64_stack;
1380 extern unsigned long real64_call_asm(unsigned long *,
1381 unsigned long *,
1382 unsigned long);
1383
1384 va_start(args, fn);
1385 real64_stack.arg0 = va_arg(args, unsigned long);
1386 real64_stack.arg1 = va_arg(args, unsigned long);
1387 real64_stack.arg2 = va_arg(args, unsigned long);
1388 real64_stack.arg3 = va_arg(args, unsigned long);
1389 real64_stack.arg4 = va_arg(args, unsigned long);
1390 real64_stack.arg5 = va_arg(args, unsigned long);
1391 real64_stack.arg6 = va_arg(args, unsigned long);
1392 real64_stack.arg7 = va_arg(args, unsigned long);
1393 real64_stack.arg8 = va_arg(args, unsigned long);
1394 real64_stack.arg9 = va_arg(args, unsigned long);
1395 real64_stack.arg10 = va_arg(args, unsigned long);
1396 real64_stack.arg11 = va_arg(args, unsigned long);
1397 real64_stack.arg12 = va_arg(args, unsigned long);
1398 real64_stack.arg13 = va_arg(args, unsigned long);
1399 va_end(args);
1400
1401 return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn);
1402}
1403
1404#endif /* __LP64__ */
1405
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
new file mode 100644
index 000000000000..2071b5bba15c
--- /dev/null
+++ b/arch/parisc/kernel/hardware.c
@@ -0,0 +1,1366 @@
1/*
2 * Hardware descriptions for HP 9000 based hardware, including
3 * system types, SCSI controllers, DMA controllers, HPPB controllers
4 * and lots more.
5 *
6 * Based on the document "PA-RISC 1.1 I/O Firmware Architecture
7 * Reference Specification", March 7, 1999, version 0.96. This
8 * is available at http://parisc-linux.org/documentation/
9 *
10 * Copyright 1999 by Alex deVries <alex@onefishtwo.ca>
11 * and copyright 1999 The Puffin Group Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 */
28
29
30#include <asm/hardware.h>
31#include <linux/stddef.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34
35/*
36 * HP PARISC Hardware Database
37 * Access to this database is only possible during bootup
38 * so don't reference this table after starting the init process
39 */
40
41static struct hp_hardware hp_hardware_list[] __initdata = {
42 {HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"},
43 {HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"},
44 {HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"},
45 {HPHW_NPROC,0xB,0x4,0x01,"Technical Shogun (845, 645)"},
46 {HPHW_NPROC,0xF,0x4,0x01,"Commercial Shogun (949)"},
47 {HPHW_NPROC,0xC,0x4,0x01,"Cheetah (850, 950)"},
48 {HPHW_NPROC,0x80,0x4,0x01,"Cheetah (950S)"},
49 {HPHW_NPROC,0x81,0x4,0x01,"Jaguar (855, 955)"},
50 {HPHW_NPROC,0x82,0x4,0x01,"Cougar (860, 960)"},
51 {HPHW_NPROC,0x83,0x4,0x13,"Panther (865, 870, 980)"},
52 {HPHW_NPROC,0x100,0x4,0x01,"Burgundy (810)"},
53 {HPHW_NPROC,0x101,0x4,0x01,"SilverFox Low (822, 922)"},
54 {HPHW_NPROC,0x102,0x4,0x01,"SilverFox High (832, 932)"},
55 {HPHW_NPROC,0x103,0x4,0x01,"Lego, SilverLite (815, 808, 920)"},
56 {HPHW_NPROC,0x104,0x4,0x03,"SilverBullet Low (842, 948)"},
57 {HPHW_NPROC,0x105,0x4,0x03,"SilverBullet High (852, 958)"},
58 {HPHW_NPROC,0x106,0x4,0x81,"Oboe"},
59 {HPHW_NPROC,0x180,0x4,0x12,"Dragon"},
60 {HPHW_NPROC,0x181,0x4,0x13,"Chimera (890, 990, 992)"},
61 {HPHW_NPROC,0x182,0x4,0x91,"TNT 100 (891,T500)"},
62 {HPHW_NPROC,0x183,0x4,0x91,"TNT 120 (892,T520)"},
63 {HPHW_NPROC,0x184,0x4,0x91,"Jade 180 U (893,T540)"},
64 {HPHW_NPROC,0x1FF,0x4,0x91,"Hitachi X Processor"},
65 {HPHW_NPROC,0x200,0x4,0x81,"Cobra (720)"},
66 {HPHW_NPROC,0x201,0x4,0x81,"Coral (750)"},
67 {HPHW_NPROC,0x202,0x4,0x81,"King Cobra (730)"},
68 {HPHW_NPROC,0x203,0x4,0x81,"Hardball (735/99)"},
69 {HPHW_NPROC,0x204,0x4,0x81,"Coral II (755/99)"},
70 {HPHW_NPROC,0x205,0x4,0x81,"Coral II (755/125)"},
71 {HPHW_NPROC,0x205,0x4,0x91,"Snake Eagle "},
72 {HPHW_NPROC,0x206,0x4,0x81,"Snake Cheetah (735/130)"},
73 {HPHW_NPROC,0x280,0x4,0x81,"Nova Low (817, 827, 957, 957LX)"},
74 {HPHW_NPROC,0x281,0x4,0x81,"Nova High (837, 847, 857, 967, 967LX)"},
75 {HPHW_NPROC,0x282,0x4,0x81,"Nova8 (807, 917, 917LX, 927,927LX, 937, 937LX, 947,947LX)"},
76 {HPHW_NPROC,0x283,0x4,0x81,"Nova64 (867, 877, 977)"},
77 {HPHW_NPROC,0x284,0x4,0x81,"TNova (887, 897, 987)"},
78 {HPHW_NPROC,0x285,0x4,0x81,"TNova64"},
79 {HPHW_NPROC,0x286,0x4,0x91,"Hydra64 (Nova)"},
80 {HPHW_NPROC,0x287,0x4,0x91,"Hydra96 (Nova)"},
81 {HPHW_NPROC,0x288,0x4,0x81,"TNova96"},
82 {HPHW_NPROC,0x300,0x4,0x81,"Bushmaster (710)"},
83 {HPHW_NPROC,0x302,0x4,0x81,"Flounder (705)"},
84 {HPHW_NPROC,0x310,0x4,0x81,"Scorpio (715/50)"},
85 {HPHW_NPROC,0x311,0x4,0x81,"Scorpio Jr.(715/33)"},
86 {HPHW_NPROC,0x312,0x4,0x81,"Strider-50 (715S/50)"},
87 {HPHW_NPROC,0x313,0x4,0x81,"Strider-33 (715S/33)"},
88 {HPHW_NPROC,0x314,0x4,0x81,"Trailways-50 (715T/50)"},
89 {HPHW_NPROC,0x315,0x4,0x81,"Trailways-33 (715T/33)"},
90 {HPHW_NPROC,0x316,0x4,0x81,"Scorpio Sr.(715/75)"},
91 {HPHW_NPROC,0x317,0x4,0x81,"Scorpio 100 (715/100)"},
92 {HPHW_NPROC,0x318,0x4,0x81,"Spectra (725/50)"},
93 {HPHW_NPROC,0x319,0x4,0x81,"Spectra (725/75)"},
94 {HPHW_NPROC,0x320,0x4,0x81,"Spectra (725/100)"},
95 {HPHW_NPROC,0x401,0x4,0x81,"Pace (745i, 747i)"},
96 {HPHW_NPROC,0x402,0x4,0x81,"Sidewinder (742i)"},
97 {HPHW_NPROC,0x403,0x4,0x81,"Fast Pace"},
98 {HPHW_NPROC,0x480,0x4,0x81,"Orville (E23)"},
99 {HPHW_NPROC,0x481,0x4,0x81,"Wilbur (E25)"},
100 {HPHW_NPROC,0x482,0x4,0x81,"WB-80 (E35)"},
101 {HPHW_NPROC,0x483,0x4,0x81,"WB-96 (E45)"},
102 {HPHW_NPROC,0x484,0x4,0x81,"UL Proc L-100 (811/D210,D310)"},
103 {HPHW_NPROC,0x485,0x4,0x81,"UL Proc L-75 (801/D200)"},
104 {HPHW_NPROC,0x501,0x4,0x81,"Merlin L2 132 (9000/778/B132L)"},
105 {HPHW_NPROC,0x502,0x4,0x81,"Merlin L2 160 (9000/778/B160L)"},
106 {HPHW_NPROC,0x503,0x4,0x81,"Merlin L2+ 132 (9000/778/B132L)"},
107 {HPHW_NPROC,0x504,0x4,0x81,"Merlin L2+ 180 (9000/778/B180L)"},
108 {HPHW_NPROC,0x505,0x4,0x81,"Raven L2 132 (9000/778/C132L)"},
109 {HPHW_NPROC,0x506,0x4,0x81,"Raven L2 160 (9000/779/C160L)"},
110 {HPHW_NPROC,0x507,0x4,0x81,"Raven L2 180 (9000/779/C180L)"},
111 {HPHW_NPROC,0x508,0x4,0x81,"Raven L2 160 (9000/779/C160L)"},
112 {HPHW_NPROC,0x509,0x4,0x81,"712/132 L2 Upgrade"},
113 {HPHW_NPROC,0x50A,0x4,0x81,"712/160 L2 Upgrade"},
114 {HPHW_NPROC,0x50B,0x4,0x81,"715/132 L2 Upgrade"},
115 {HPHW_NPROC,0x50C,0x4,0x81,"715/160 L2 Upgrade"},
116 {HPHW_NPROC,0x50D,0x4,0x81,"Rocky2 L2 120"},
117 {HPHW_NPROC,0x50E,0x4,0x81,"Rocky2 L2 150"},
118 {HPHW_NPROC,0x50F,0x4,0x81,"Anole L2 132 (744)"},
119 {HPHW_NPROC,0x510,0x4,0x81,"Anole L2 165 (744)"},
120 {HPHW_NPROC,0x511,0x4,0x81,"Kiji L2 132"},
121 {HPHW_NPROC,0x512,0x4,0x81,"UL L2 132 (803/D220,D320)"},
122 {HPHW_NPROC,0x513,0x4,0x81,"UL L2 160 (813/D220,D320)"},
123 {HPHW_NPROC,0x514,0x4,0x81,"Merlin Jr L2 132"},
124 {HPHW_NPROC,0x515,0x4,0x81,"Staccato L2 132"},
125 {HPHW_NPROC,0x516,0x4,0x81,"Staccato L2 180 (A Class 180)"},
126 {HPHW_NPROC,0x580,0x4,0x81,"KittyHawk DC2-100 (K100)"},
127 {HPHW_NPROC,0x581,0x4,0x91,"KittyHawk DC3-120 (K210)"},
128 {HPHW_NPROC,0x582,0x4,0x91,"KittyHawk DC3 100 (K400)"},
129 {HPHW_NPROC,0x583,0x4,0x91,"KittyHawk DC3 120 (K410)"},
130 {HPHW_NPROC,0x584,0x4,0x91,"LighteningHawk T120"},
131 {HPHW_NPROC,0x585,0x4,0x91,"SkyHawk 100"},
132 {HPHW_NPROC,0x586,0x4,0x91,"SkyHawk 120"},
133 {HPHW_NPROC,0x587,0x4,0x81,"UL Proc 1-way T'120"},
134 {HPHW_NPROC,0x588,0x4,0x91,"UL Proc 2-way T'120"},
135 {HPHW_NPROC,0x589,0x4,0x81,"UL Proc 1-way T'100 (821/D250,D350)"},
136 {HPHW_NPROC,0x58A,0x4,0x91,"UL Proc 2-way T'100 (831/D250,D350)"},
137 {HPHW_NPROC,0x58B,0x4,0x91,"KittyHawk DC2 100 (K200)"},
138 {HPHW_NPROC,0x58C,0x4,0x91,"ThunderHawk DC3- 120 1M (K220)"},
139 {HPHW_NPROC,0x58D,0x4,0x91,"ThunderHawk DC3 120 1M (K420)"},
140 {HPHW_NPROC,0x58E,0x4,0x81,"Raven 120 T'"},
141 {HPHW_NPROC,0x58F,0x4,0x91,"Mohawk 160 U 1M DC3 (K450)"},
142 {HPHW_NPROC,0x590,0x4,0x91,"Mohawk 180 U 1M DC3 (K460)"},
143 {HPHW_NPROC,0x591,0x4,0x91,"Mohawk 200 U 1M DC3"},
144 {HPHW_NPROC,0x592,0x4,0x81,"Raven 100 T'"},
145 {HPHW_NPROC,0x593,0x4,0x91,"FireHawk 160 U"},
146 {HPHW_NPROC,0x594,0x4,0x91,"FireHawk 180 U"},
147 {HPHW_NPROC,0x595,0x4,0x91,"FireHawk 220 U"},
148 {HPHW_NPROC,0x596,0x4,0x91,"FireHawk 240 U"},
149 {HPHW_NPROC,0x597,0x4,0x91,"SPP2000 processor"},
150 {HPHW_NPROC,0x598,0x4,0x81,"Raven U 230 (9000/780/C230)"},
151 {HPHW_NPROC,0x599,0x4,0x81,"Raven U 240 (9000/780/C240)"},
152 {HPHW_NPROC,0x59A,0x4,0x91,"Unlisted but reserved"},
153 {HPHW_NPROC,0x59A,0x4,0x81,"Unlisted but reserved"},
154 {HPHW_NPROC,0x59B,0x4,0x81,"Raven U 160 (9000/780/C160)"},
155 {HPHW_NPROC,0x59C,0x4,0x81,"Raven U 180 (9000/780/C180)"},
156 {HPHW_NPROC,0x59D,0x4,0x81,"Raven U 200 (9000/780/C200)"},
157 {HPHW_NPROC,0x59E,0x4,0x91,"ThunderHawk T' 120"},
158 {HPHW_NPROC,0x59F,0x4,0x91,"Raven U 180+ (9000/780)"},
159 {HPHW_NPROC,0x5A0,0x4,0x81,"UL 1w T120 1MB/1MB (841/D260,D360)"},
160 {HPHW_NPROC,0x5A1,0x4,0x91,"UL 2w T120 1MB/1MB (851/D260,D360)"},
161 {HPHW_NPROC,0x5A2,0x4,0x81,"UL 1w U160 512K/512K (861/D270,D370)"},
162 {HPHW_NPROC,0x5A3,0x4,0x91,"UL 2w U160 512K/512K (871/D270,D370)"},
163 {HPHW_NPROC,0x5A4,0x4,0x91,"Mohawk 160 U 1M DC3- (K250)"},
164 {HPHW_NPROC,0x5A5,0x4,0x91,"Mohawk 180 U 1M DC3- (K260)"},
165 {HPHW_NPROC,0x5A6,0x4,0x91,"Mohawk 200 U 1M DC3-"},
166 {HPHW_NPROC,0x5A7,0x4,0x81,"UL proc 1-way U160 1M/1M"},
167 {HPHW_NPROC,0x5A8,0x4,0x91,"UL proc 2-way U160 1M/1M"},
168 {HPHW_NPROC,0x5A9,0x4,0x81,"UL proc 1-way U180 1M/1M"},
169 {HPHW_NPROC,0x5AA,0x4,0x91,"UL proc 2-way U180 1M/1M"},
170 {HPHW_NPROC,0x5AB,0x4,0x91,"Obsolete"},
171 {HPHW_NPROC,0x5AB,0x4,0x81,"Obsolete"},
172 {HPHW_NPROC,0x5AC,0x4,0x91,"Obsolete"},
173 {HPHW_NPROC,0x5AC,0x4,0x81,"Obsolete"},
174 {HPHW_NPROC,0x5AD,0x4,0x91,"BraveHawk 180MHz DC3-"},
175 {HPHW_NPROC,0x5AE,0x4,0x91,"BraveHawk 200MHz DC3- (898/K370)"},
176 {HPHW_NPROC,0x5AF,0x4,0x91,"BraveHawk 220MHz DC3-"},
177 {HPHW_NPROC,0x5B0,0x4,0x91,"BraveHawk 180MHz DC3"},
178 {HPHW_NPROC,0x5B1,0x4,0x91,"BraveHawk 200MHz DC3 (899/K570)"},
179 {HPHW_NPROC,0x5B2,0x4,0x91,"BraveHawk 220MHz DC3"},
180 {HPHW_NPROC,0x5B3,0x4,0x91,"FireHawk 200"},
181 {HPHW_NPROC,0x5B4,0x4,0x91,"SPP2500"},
182 {HPHW_NPROC,0x5B5,0x4,0x91,"SummitHawk U+"},
183 {HPHW_NPROC,0x5B6,0x4,0x91,"DragonHawk U+ 240 DC3"},
184 {HPHW_NPROC,0x5B7,0x4,0x91,"DragonHawk U+ 240 DC3-"},
185 {HPHW_NPROC,0x5B8,0x4,0x91,"SPP2250 240 MHz"},
186 {HPHW_NPROC,0x5B9,0x4,0x81,"UL 1w U+/240 (350/550)"},
187 {HPHW_NPROC,0x5BA,0x4,0x91,"UL 2w U+/240 (350/550)"},
188 {HPHW_NPROC,0x5BB,0x4,0x81,"AllegroHigh W"},
189 {HPHW_NPROC,0x5BC,0x4,0x91,"AllegroLow W"},
190 {HPHW_NPROC,0x5BD,0x4,0x91,"Forte W 2-way"},
191 {HPHW_NPROC,0x5BE,0x4,0x91,"Prelude W"},
192 {HPHW_NPROC,0x5BF,0x4,0x91,"Forte W 4-way"},
193 {HPHW_NPROC,0x5C0,0x4,0x91,"M2250"},
194 {HPHW_NPROC,0x5C1,0x4,0x91,"M2500"},
195 {HPHW_NPROC,0x5C2,0x4,0x91,"Sonata 440"},
196 {HPHW_NPROC,0x5C3,0x4,0x91,"Sonata 360"},
197 {HPHW_NPROC,0x5C4,0x4,0x91,"Rhapsody 440"},
198 {HPHW_NPROC,0x5C5,0x4,0x91,"Rhapsody 360"},
199 {HPHW_NPROC,0x5C6,0x4,0x91,"Raven W 360 (9000/780)"},
200 {HPHW_NPROC,0x5C7,0x4,0x91,"Halfdome W 440"},
201 {HPHW_NPROC,0x5C8,0x4,0x81,"Lego 360 processor"},
202 {HPHW_NPROC,0x5C9,0x4,0x91,"Rhapsody DC- 440"},
203 {HPHW_NPROC,0x5CA,0x4,0x91,"Rhapsody DC- 360"},
204 {HPHW_NPROC,0x5CB,0x4,0x91,"Crescendo 440"},
205 {HPHW_NPROC,0x5CC,0x4,0x91,"Prelude W 440"},
206 {HPHW_NPROC,0x5CD,0x4,0x91,"SPP2600"},
207 {HPHW_NPROC,0x5CE,0x4,0x91,"M2600"},
208 {HPHW_NPROC,0x5CF,0x4,0x81,"Allegro W+"},
209 {HPHW_NPROC,0x5D0,0x4,0x81,"Kazoo W+"},
210 {HPHW_NPROC,0x5D1,0x4,0x91,"Forte W+ 2w"},
211 {HPHW_NPROC,0x5D2,0x4,0x91,"Forte W+ 4w"},
212 {HPHW_NPROC,0x5D3,0x4,0x91,"Prelude W+ 540"},
213 {HPHW_NPROC,0x5D4,0x4,0x91,"Duet W+"},
214 {HPHW_NPROC,0x5D5,0x4,0x91,"Crescendo 550"},
215 {HPHW_NPROC,0x5D6,0x4,0x81,"Crescendo DC- 440"},
216 {HPHW_NPROC,0x5D7,0x4,0x91,"Keystone W+"},
217 {HPHW_NPROC,0x5D8,0x4,0x91,"Rhapsody wave 2 W+ DC-"},
218 {HPHW_NPROC,0x5D9,0x4,0x91,"Rhapsody wave 2 W+"},
219 {HPHW_NPROC,0x5DA,0x4,0x91,"Marcato W+ DC-"},
220 {HPHW_NPROC,0x5DB,0x4,0x91,"Marcato W+"},
221 {HPHW_NPROC,0x5DC,0x4,0x91,"Allegro W2"},
222 {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
223 {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
224 {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
225 {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
226 {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
227 {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
228 {HPHW_NPROC,0x5E3,0x4,0x91,"Crescendo 750 W2"},
229 {HPHW_NPROC,0x5E4,0x4,0x91,"Keystone/Matterhorn W2 750"},
230 {HPHW_NPROC,0x5E5,0x4,0x91,"PowerBar W+"},
231 {HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
232 {HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
233 {HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
234 {HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
235 {HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
236 {HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
237 {HPHW_NPROC,0x602,0x4,0x81,"Gecko 100 (712/100)"},
238 {HPHW_NPROC,0x603,0x4,0x81,"Anole 64 (743/64)"},
239 {HPHW_NPROC,0x604,0x4,0x81,"Anole 100 (743/100)"},
240 {HPHW_NPROC,0x605,0x4,0x81,"Gecko 120 (712/120)"},
241 {HPHW_NPROC,0x606,0x4,0x81,"Gila 80"},
242 {HPHW_NPROC,0x607,0x4,0x81,"Gila 100"},
243 {HPHW_NPROC,0x608,0x4,0x81,"Gila 120"},
244 {HPHW_NPROC,0x609,0x4,0x81,"Scorpio-L 80"},
245 {HPHW_NPROC,0x60A,0x4,0x81,"Mirage Jr (715/64)"},
246 {HPHW_NPROC,0x60B,0x4,0x81,"Mirage 100"},
247 {HPHW_NPROC,0x60C,0x4,0x81,"Mirage 100+"},
248 {HPHW_NPROC,0x60D,0x4,0x81,"Electra 100"},
249 {HPHW_NPROC,0x60E,0x4,0x81,"Electra 120"},
250 {HPHW_NPROC,0x610,0x4,0x81,"Scorpio-L 100"},
251 {HPHW_NPROC,0x611,0x4,0x81,"Scorpio-L 120"},
252 {HPHW_NPROC,0x612,0x4,0x81,"Spectra-L 80"},
253 {HPHW_NPROC,0x613,0x4,0x81,"Spectra-L 100"},
254 {HPHW_NPROC,0x614,0x4,0x81,"Spectra-L 120"},
255 {HPHW_NPROC,0x615,0x4,0x81,"Piranha 100"},
256 {HPHW_NPROC,0x616,0x4,0x81,"Piranha 120"},
257 {HPHW_NPROC,0x617,0x4,0x81,"Jason 50"},
258 {HPHW_NPROC,0x618,0x4,0x81,"Jason 100"},
259 {HPHW_NPROC,0x619,0x4,0x81,"Mirage 80"},
260 {HPHW_NPROC,0x61A,0x4,0x81,"SAIC L-80"},
261 {HPHW_NPROC,0x61B,0x4,0x81,"Rocky1 L-60"},
262 {HPHW_NPROC,0x61C,0x4,0x81,"Anole T (743/T)"},
263 {HPHW_NPROC,0x67E,0x4,0x81,"Hitachi Tiny 80"},
264 {HPHW_NPROC,0x67F,0x4,0x81,"Hitachi Tiny 64"},
265 {HPHW_NPROC,0x700,0x4,0x91,"NEC Aska Processor"},
266 {HPHW_NPROC,0x880,0x4,0x91,"Orca Mako"},
267 {HPHW_NPROC,0x881,0x4,0x91,"Everest Mako"},
268 {HPHW_NPROC,0x882,0x4,0x91,"Rainier/Medel Mako Slow"},
269 {HPHW_NPROC,0x883,0x4,0x91,"Rainier/Medel Mako Fast"},
270 {HPHW_NPROC,0x884,0x4,0x91,"Mt. Hamilton"},
271 {HPHW_NPROC,0x885,0x4,0x91,"Mt. Hamilton DC-"},
272 {HPHW_NPROC,0x886,0x4,0x91,"Storm Peak Slow DC-"},
273 {HPHW_NPROC,0x887,0x4,0x91,"Storm Peak Slow"},
274 {HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"},
275 {HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"},
276 {HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak"},
277 {HPHW_A_DIRECT, 0x004, 0x0000D, 0x00, "Arrakis MUX"},
278 {HPHW_A_DIRECT, 0x005, 0x0000D, 0x00, "Dyun Kiuh MUX"},
279 {HPHW_A_DIRECT, 0x006, 0x0000D, 0x00, "Baat Kiuh AP/MUX (40299B)"},
280 {HPHW_A_DIRECT, 0x007, 0x0000D, 0x00, "Dino AP"},
281 {HPHW_A_DIRECT, 0x009, 0x0000D, 0x00, "Solaris Direct Connect MUX (J2092A)"},
282 {HPHW_A_DIRECT, 0x00A, 0x0000D, 0x00, "Solaris RS-422/423 MUX (J2093A)"},
283 {HPHW_A_DIRECT, 0x00B, 0x0000D, 0x00, "Solaris RS-422/423 Quadriloops MUX"},
284 {HPHW_A_DIRECT, 0x00C, 0x0000D, 0x00, "Solaris Modem MUX (J2094A)"},
285 {HPHW_A_DIRECT, 0x00D, 0x0000D, 0x00, "Twins Direct Connect MUX"},
286 {HPHW_A_DIRECT, 0x00E, 0x0000D, 0x00, "Twins Modem MUX"},
287 {HPHW_A_DIRECT, 0x00F, 0x0000D, 0x00, "Nautilus RS-485"},
288 {HPHW_A_DIRECT, 0x010, 0x0000D, 0x00, "UltraLight CAP/MUX"},
289 {HPHW_A_DIRECT, 0x015, 0x0000D, 0x00, "Eole CAP/MUX"},
290 {HPHW_A_DIRECT, 0x024, 0x0000D, 0x00, "Sahp Kiuh AP/MUX"},
291 {HPHW_A_DIRECT, 0x034, 0x0000D, 0x00, "Sahp Kiuh Low AP/MUX"},
292 {HPHW_A_DIRECT, 0x044, 0x0000D, 0x00, "Sahp Baat Kiuh AP/MUX"},
293 {HPHW_A_DIRECT, 0x004, 0x0000E, 0x80, "Burgundy RS-232"},
294 {HPHW_A_DIRECT, 0x005, 0x0000E, 0x80, "Silverfox RS-232"},
295 {HPHW_A_DIRECT, 0x006, 0x0000E, 0x80, "Lego RS-232"},
296 {HPHW_A_DIRECT, 0x004, 0x0000F, 0x00, "Peacock Graphics"},
297 {HPHW_A_DIRECT, 0x004, 0x00014, 0x80, "Burgundy HIL"},
298 {HPHW_A_DIRECT, 0x005, 0x00014, 0x80, "Peacock HIL"},
299 {HPHW_A_DIRECT, 0x004, 0x00015, 0x80, "Leonardo"},
300 {HPHW_A_DIRECT, 0x004, 0x00016, 0x80, "HP-PB HRM"},
301 {HPHW_A_DIRECT, 0x004, 0x00017, 0x80, "HP-PB HRC"},
302 {HPHW_A_DIRECT, 0x004, 0x0003A, 0x80, "Skunk Centronics (28655A)"},
303 {HPHW_A_DIRECT, 0x024, 0x0003A, 0x80, "Sahp Kiuh Centronics"},
304 {HPHW_A_DIRECT, 0x044, 0x0003A, 0x80, "Sahp Baat Kiuh Centronics"},
305 {HPHW_A_DIRECT, 0x004, 0x0004E, 0x80, "AT&T DataKit (AMSO)"},
306 {HPHW_A_DIRECT, 0x004, 0x0009B, 0x80, "Test&Meas GSC HPIB"},
307 {HPHW_A_DIRECT, 0x004, 0x000A8, 0x00, "Rocky2-120 Front Keyboard"},
308 {HPHW_A_DIRECT, 0x005, 0x000A8, 0x00, "Rocky2-150 Front Keyboard"},
309 {HPHW_A_DIRECT, 0x004, 0x00101, 0x80, "Hitachi Console Module"},
310 {HPHW_A_DIRECT, 0x004, 0x00102, 0x80, "Hitachi Boot Module"},
311 {HPHW_A_DIRECT, 0x004, 0x00203, 0x80, "MELCO HBMLA MLAIT"},
312 {HPHW_A_DIRECT, 0x004, 0x00208, 0x80, "MELCO HBDPC"},
313 {HPHW_A_DIRECT, 0x004, 0x00300, 0x00, "DCI TWINAX TERM IO MUX"},
314 {HPHW_A_DMA, 0x004, 0x00039, 0x80, "Skunk SCSI (28655A)"},
315 {HPHW_A_DMA, 0x005, 0x00039, 0x80, "KittyHawk CSY Core SCSI"},
316 {HPHW_A_DMA, 0x014, 0x00039, 0x80, "Diablo SCSI"},
317 {HPHW_A_DMA, 0x024, 0x00039, 0x80, "Sahp Kiuh SCSI"},
318 {HPHW_A_DMA, 0x034, 0x00039, 0x80, "Sahp Kiuh Low SCSI"},
319 {HPHW_A_DMA, 0x044, 0x00039, 0x80, "Sahp Baat Kiuh SCSI"},
320 {HPHW_A_DMA, 0x004, 0x0003B, 0x80, "Wizard SCSI"},
321 {HPHW_A_DMA, 0x005, 0x0003B, 0x80, "KittyHawk CSY Core FW-SCSI"},
322 {HPHW_A_DMA, 0x006, 0x0003B, 0x80, "Symbios EPIC FW-SCSI"},
323 {HPHW_A_DMA, 0x004, 0x00040, 0x80, "HP-PB Shazam HPIB (28650A)"},
324 {HPHW_A_DMA, 0x005, 0x00040, 0x80, "Burgundy HPIB"},
325 {HPHW_A_DMA, 0x004, 0x00041, 0x80, "HP-PB HP-FL"},
326 {HPHW_A_DMA, 0x004, 0x00042, 0x80, "HP-PB LoQuix HPIB (28650B)"},
327 {HPHW_A_DMA, 0x004, 0x00043, 0x80, "HP-PB Crypt LoQuix"},
328 {HPHW_A_DMA, 0x004, 0x00044, 0x80, "HP-PB Shazam GPIO (28651A)"},
329 {HPHW_A_DMA, 0x004, 0x00045, 0x80, "HP-PB LoQuix GPIO"},
330 {HPHW_A_DMA, 0x004, 0x00046, 0x80, "2-Port X.25 NIO_ACC (AMSO)"},
331 {HPHW_A_DMA, 0x004, 0x00047, 0x80, "4-Port X.25 NIO_ACC (AMSO)"},
332 {HPHW_A_DMA, 0x004, 0x0004B, 0x80, "LGB Control"},
333 {HPHW_A_DMA, 0x004, 0x0004C, 0x80, "Martian RTI (AMSO)"},
334 {HPHW_A_DMA, 0x004, 0x0004D, 0x80, "ACC Mux (AMSO)"},
335 {HPHW_A_DMA, 0x004, 0x00050, 0x80, "Lanbrusca 802.3 (36967A)"},
336 {HPHW_A_DMA, 0x004, 0x00056, 0x80, "HP-PB LoQuix FDDI"},
337 {HPHW_A_DMA, 0x004, 0x00057, 0x80, "HP-PB LoQuix FDDI (28670A)"},
338 {HPHW_A_DMA, 0x004, 0x0005E, 0x00, "Gecko Add-on Token Ring"},
339 {HPHW_A_DMA, 0x012, 0x00089, 0x80, "Barracuda Add-on FW-SCSI"},
340 {HPHW_A_DMA, 0x013, 0x00089, 0x80, "Bluefish Add-on FW-SCSI"},
341 {HPHW_A_DMA, 0x014, 0x00089, 0x80, "Shrike Add-on FW-SCSI"},
342 {HPHW_A_DMA, 0x015, 0x00089, 0x80, "KittyHawk GSY Core FW-SCSI"},
343 {HPHW_A_DMA, 0x017, 0x00089, 0x80, "Shrike Jade Add-on FW-SCSI (A3644A)"},
344 {HPHW_A_DMA, 0x01F, 0x00089, 0x80, "SkyHawk 100/120 FW-SCSI"},
345 {HPHW_A_DMA, 0x027, 0x00089, 0x80, "Piranha 100 FW-SCSI"},
346 {HPHW_A_DMA, 0x032, 0x00089, 0x80, "Raven T' Core FW-SCSI"},
347 {HPHW_A_DMA, 0x03B, 0x00089, 0x80, "Raven U/L2 Core FW-SCSI"},
348 {HPHW_A_DMA, 0x03C, 0x00089, 0x80, "Merlin 132 Core FW-SCSI"},
349 {HPHW_A_DMA, 0x03D, 0x00089, 0x80, "Merlin 160 Core FW-SCSI"},
350 {HPHW_A_DMA, 0x044, 0x00089, 0x80, "Mohawk Core FW-SCSI"},
351 {HPHW_A_DMA, 0x051, 0x00089, 0x80, "Firehawk FW-SCSI"},
352 {HPHW_A_DMA, 0x058, 0x00089, 0x80, "FireHawk 200 FW-SCSI"},
353 {HPHW_A_DMA, 0x05C, 0x00089, 0x80, "SummitHawk 230 Ultra-SCSI"},
354 {HPHW_A_DMA, 0x014, 0x00091, 0x80, "Baby Hugo Add-on Net FC (A3406A)"},
355 {HPHW_A_DMA, 0x020, 0x00091, 0x80, "Baby Jade Add-on Net FC (A3638A)"},
356 {HPHW_A_DMA, 0x004, 0x00092, 0x80, "GSC+ YLIASTER ATM"},
357 {HPHW_A_DMA, 0x004, 0x00095, 0x80, "Hamlyn GSC+ Network Card"},
358 {HPHW_A_DMA, 0x004, 0x00098, 0x80, "Lo-fat Emulator"},
359 {HPHW_A_DMA, 0x004, 0x0009A, 0x80, "GSC+ Venus ATM"},
360 {HPHW_A_DMA, 0x005, 0x0009A, 0x80, "GSC+ Samorobrive ATM"},
361 {HPHW_A_DMA, 0x004, 0x0009D, 0x80, "HP HSC-PCI Cards"},
362 {HPHW_A_DMA, 0x004, 0x0009E, 0x80, "Alaxis GSC+ 155Mb ATM"},
363 {HPHW_A_DMA, 0x005, 0x0009E, 0x80, "Alaxis GSC+ 622Mb ATM"},
364 {HPHW_A_DMA, 0x05C, 0x0009F, 0x80, "SummitHawk 230 USB"},
365 {HPHW_A_DMA, 0x05C, 0x000A0, 0x80, "SummitHawk 230 100BaseT"},
366 {HPHW_A_DMA, 0x015, 0x000A7, 0x80, "Baby Hugo Add-on mass FC (A3404A)"},
367 {HPHW_A_DMA, 0x018, 0x000A7, 0x80, "Mombasa GS Add-on mass FC (A3591)"},
368 {HPHW_A_DMA, 0x021, 0x000A7, 0x80, "Baby Jade Add-on mass FC (A3636A)"},
369 {HPHW_A_DMA, 0x004, 0x00201, 0x80, "MELCO HCMAP"},
370 {HPHW_A_DMA, 0x004, 0x00202, 0x80, "MELCO HBMLA MLAMA"},
371 {HPHW_A_DMA, 0x004, 0x00205, 0x80, "MELCO HBRFU"},
372 {HPHW_A_DMA, 0x004, 0x00380, 0x80, "Interphase NIO-FC"},
373 {HPHW_A_DMA, 0x004, 0x00381, 0x80, "Interphase NIO-ATM"},
374 {HPHW_A_DMA, 0x004, 0x00382, 0x80, "Interphase NIO-100BaseTX"},
375 {HPHW_BA, 0x004, 0x00070, 0x0, "Cobra Core BA"},
376 {HPHW_BA, 0x005, 0x00070, 0x0, "Coral Core BA"},
377 {HPHW_BA, 0x006, 0x00070, 0x0, "Bushmaster Core BA"},
378 {HPHW_BA, 0x007, 0x00070, 0x0, "Scorpio Core BA"},
379 {HPHW_BA, 0x008, 0x00070, 0x0, "Flounder Core BA"},
380 {HPHW_BA, 0x009, 0x00070, 0x0, "Outfield Core BA"},
381 {HPHW_BA, 0x00A, 0x00070, 0x0, "CoralII Core BA"},
382 {HPHW_BA, 0x00B, 0x00070, 0x0, "Scorpio Jr. Core BA"},
383 {HPHW_BA, 0x00C, 0x00070, 0x0, "Strider-50 Core BA"},
384 {HPHW_BA, 0x00D, 0x00070, 0x0, "Strider-33 Core BA"},
385 {HPHW_BA, 0x00E, 0x00070, 0x0, "Trailways-50 Core BA"},
386 {HPHW_BA, 0x00F, 0x00070, 0x0, "Trailways-33 Core BA"},
387 {HPHW_BA, 0x010, 0x00070, 0x0, "Pace Core BA"},
388 {HPHW_BA, 0x011, 0x00070, 0x0, "Sidewinder Core BA"},
389 {HPHW_BA, 0x019, 0x00070, 0x0, "Scorpio Sr. Core BA"},
390 {HPHW_BA, 0x020, 0x00070, 0x0, "Scorpio 100 Core BA"},
391 {HPHW_BA, 0x021, 0x00070, 0x0, "Spectra 50 Core BA"},
392 {HPHW_BA, 0x022, 0x00070, 0x0, "Spectra 75 Core BA"},
393 {HPHW_BA, 0x023, 0x00070, 0x0, "Spectra 100 Core BA"},
394 {HPHW_BA, 0x024, 0x00070, 0x0, "Fast Pace Core BA"},
395 {HPHW_BA, 0x026, 0x00070, 0x0, "CoralII Jaguar Core BA"},
396 {HPHW_BA, 0x004, 0x00076, 0x0, "Cobra EISA BA"},
397 {HPHW_BA, 0x005, 0x00076, 0x0, "Coral EISA BA"},
398 {HPHW_BA, 0x007, 0x00076, 0x0, "Scorpio EISA BA"},
399 {HPHW_BA, 0x00A, 0x00076, 0x0, "CoralII EISA BA"},
400 {HPHW_BA, 0x00B, 0x00076, 0x0, "Scorpio Jr. EISA BA"},
401 {HPHW_BA, 0x00C, 0x00076, 0x0, "Strider-50 Core EISA"},
402 {HPHW_BA, 0x00D, 0x00076, 0x0, "Strider-33 Core EISA"},
403 {HPHW_BA, 0x00E, 0x00076, 0x0, "Trailways-50 Core EISA"},
404 {HPHW_BA, 0x00F, 0x00076, 0x0, "Trailways-33 Core EISA"},
405 {HPHW_BA, 0x010, 0x00076, 0x0, "Pace Core EISA"},
406 {HPHW_BA, 0x019, 0x00076, 0x0, "Scorpio Sr. EISA BA"},
407 {HPHW_BA, 0x020, 0x00076, 0x0, "Scorpio 100 EISA BA"},
408 {HPHW_BA, 0x021, 0x00076, 0x0, "Spectra 50 EISA BA"},
409 {HPHW_BA, 0x022, 0x00076, 0x0, "Spectra 75 EISA BA"},
410 {HPHW_BA, 0x023, 0x00076, 0x0, "Spectra 100 EISA BA"},
411 {HPHW_BA, 0x026, 0x00076, 0x0, "CoralII Jaguar EISA BA"},
412 {HPHW_BA, 0x010, 0x00078, 0x0, "Pace VME BA"},
413 {HPHW_BA, 0x011, 0x00078, 0x0, "Sidewinder VME BA"},
414 {HPHW_BA, 0x01A, 0x00078, 0x0, "Anole 64 VME BA"},
415 {HPHW_BA, 0x01B, 0x00078, 0x0, "Anole 100 VME BA"},
416 {HPHW_BA, 0x024, 0x00078, 0x0, "Fast Pace VME BA"},
417 {HPHW_BA, 0x034, 0x00078, 0x0, "Anole T VME BA"},
418 {HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 VME BA"},
419 {HPHW_BA, 0x04C, 0x00078, 0x0, "Anole L2 165 VME BA"},
420 {HPHW_BA, 0x011, 0x00081, 0x0, "WB-96 Core BA"},
421 {HPHW_BA, 0x012, 0x00081, 0x0, "Orville UX Core BA"},
422 {HPHW_BA, 0x013, 0x00081, 0x0, "Wilbur UX Core BA"},
423 {HPHW_BA, 0x014, 0x00081, 0x0, "WB-80 Core BA"},
424 {HPHW_BA, 0x015, 0x00081, 0x0, "KittyHawk GSY Core BA"},
425 {HPHW_BA, 0x016, 0x00081, 0x0, "Gecko Core BA"},
426 {HPHW_BA, 0x018, 0x00081, 0x0, "Gecko Optional BA"},
427 {HPHW_BA, 0x01A, 0x00081, 0x0, "Anole 64 Core BA"},
428 {HPHW_BA, 0x01B, 0x00081, 0x0, "Anole 100 Core BA"},
429 {HPHW_BA, 0x01C, 0x00081, 0x0, "Gecko 80 Core BA"},
430 {HPHW_BA, 0x01D, 0x00081, 0x0, "Gecko 100 Core BA"},
431 {HPHW_BA, 0x01F, 0x00081, 0x0, "SkyHawk 100/120 Core BA"},
432 {HPHW_BA, 0x027, 0x00081, 0x0, "Piranha 100 Core BA"},
433 {HPHW_BA, 0x028, 0x00081, 0x0, "Mirage Jr Core BA"},
434 {HPHW_BA, 0x029, 0x00081, 0x0, "Mirage Core BA"},
435 {HPHW_BA, 0x02A, 0x00081, 0x0, "Electra Core BA"},
436 {HPHW_BA, 0x02B, 0x00081, 0x0, "Mirage 80 Core BA"},
437 {HPHW_BA, 0x02C, 0x00081, 0x0, "Mirage 100+ Core BA"},
438 {HPHW_BA, 0x02E, 0x00081, 0x0, "UL 350 Lasi Core BA"},
439 {HPHW_BA, 0x02F, 0x00081, 0x0, "UL 550 Lasi Core BA"},
440 {HPHW_BA, 0x032, 0x00081, 0x0, "Raven T' Core BA"},
441 {HPHW_BA, 0x033, 0x00081, 0x0, "Anole T Core BA"},
442 {HPHW_BA, 0x034, 0x00081, 0x0, "SAIC L-80 Core BA"},
443 {HPHW_BA, 0x035, 0x00081, 0x0, "PCX-L2 712/132 Core BA"},
444 {HPHW_BA, 0x036, 0x00081, 0x0, "PCX-L2 712/160 Core BA"},
445 {HPHW_BA, 0x03B, 0x00081, 0x0, "Raven U/L2 Core BA"},
446 {HPHW_BA, 0x03C, 0x00081, 0x0, "Merlin 132 Core BA"},
447 {HPHW_BA, 0x03D, 0x00081, 0x0, "Merlin 160 Core BA"},
448 {HPHW_BA, 0x03E, 0x00081, 0x0, "Merlin+ 132 Core BA"},
449 {HPHW_BA, 0x03F, 0x00081, 0x0, "Merlin+ 180 Core BA"},
450 {HPHW_BA, 0x044, 0x00081, 0x0, "Mohawk Core BA"},
451 {HPHW_BA, 0x045, 0x00081, 0x0, "Rocky1 Core BA"},
452 {HPHW_BA, 0x046, 0x00081, 0x0, "Rocky2 120 Core BA"},
453 {HPHW_BA, 0x047, 0x00081, 0x0, "Rocky2 150 Core BA"},
454 {HPHW_BA, 0x04B, 0x00081, 0x0, "Anole L2 132 Core BA"},
455 {HPHW_BA, 0x04D, 0x00081, 0x0, "Anole L2 165 Core BA"},
456 {HPHW_BA, 0x04E, 0x00081, 0x0, "Kiji L2 132 Core BA"},
457 {HPHW_BA, 0x050, 0x00081, 0x0, "Merlin Jr 132 Core BA"},
458 {HPHW_BA, 0x051, 0x00081, 0x0, "Firehawk Core BA"},
459 {HPHW_BA, 0x056, 0x00081, 0x0, "Raven+ w SE FWSCSI Core BA"},
460 {HPHW_BA, 0x057, 0x00081, 0x0, "Raven+ w Diff FWSCSI Core BA"},
461 {HPHW_BA, 0x058, 0x00081, 0x0, "FireHawk 200 Core BA"},
462 {HPHW_BA, 0x05C, 0x00081, 0x0, "SummitHawk 230 Core BA"},
463 {HPHW_BA, 0x05E, 0x00081, 0x0, "Staccato 132 Core BA"},
464 {HPHW_BA, 0x05E, 0x00081, 0x0, "Staccato 180 Core BA"},
465 {HPHW_BA, 0x05F, 0x00081, 0x0, "Staccato 180 Lasi"},
466 {HPHW_BA, 0x800, 0x00081, 0x0, "Hitachi Tiny 64 Core BA"},
467 {HPHW_BA, 0x801, 0x00081, 0x0, "Hitachi Tiny 80 Core BA"},
468 {HPHW_BA, 0x004, 0x0008B, 0x0, "Anole Optional PCMCIA BA"},
469 {HPHW_BA, 0x004, 0x0008E, 0x0, "GSC ITR Wax BA"},
470 {HPHW_BA, 0x00C, 0x0008E, 0x0, "Gecko Optional Wax BA"},
471 {HPHW_BA, 0x010, 0x0008E, 0x0, "Pace Wax BA"},
472 {HPHW_BA, 0x011, 0x0008E, 0x0, "SuperPace Wax BA"},
473 {HPHW_BA, 0x012, 0x0008E, 0x0, "Mirage Jr Wax BA"},
474 {HPHW_BA, 0x013, 0x0008E, 0x0, "Mirage Wax BA"},
475 {HPHW_BA, 0x014, 0x0008E, 0x0, "Electra Wax BA"},
476 {HPHW_BA, 0x017, 0x0008E, 0x0, "Raven Backplane Wax BA"},
477 {HPHW_BA, 0x01E, 0x0008E, 0x0, "Raven T' Wax BA"},
478 {HPHW_BA, 0x01F, 0x0008E, 0x0, "SkyHawk Wax BA"},
479 {HPHW_BA, 0x023, 0x0008E, 0x0, "Rocky1 Wax BA"},
480 {HPHW_BA, 0x02B, 0x0008E, 0x0, "Mirage 80 Wax BA"},
481 {HPHW_BA, 0x02C, 0x0008E, 0x0, "Mirage 100+ Wax BA"},
482 {HPHW_BA, 0x030, 0x0008E, 0x0, "UL 350 Core Wax BA"},
483 {HPHW_BA, 0x031, 0x0008E, 0x0, "UL 550 Core Wax BA"},
484 {HPHW_BA, 0x034, 0x0008E, 0x0, "SAIC L-80 Wax BA"},
485 {HPHW_BA, 0x03A, 0x0008E, 0x0, "Merlin+ Wax BA"},
486 {HPHW_BA, 0x040, 0x0008E, 0x0, "Merlin 132 Wax BA"},
487 {HPHW_BA, 0x041, 0x0008E, 0x0, "Merlin 160 Wax BA"},
488 {HPHW_BA, 0x043, 0x0008E, 0x0, "Merlin 132/160 Wax BA"},
489 {HPHW_BA, 0x052, 0x0008E, 0x0, "Raven+ Hi Power Backplane w/EISA Wax BA"},
490 {HPHW_BA, 0x054, 0x0008E, 0x0, "Raven+ Lo Power Backplane w/EISA Wax BA"},
491 {HPHW_BA, 0x059, 0x0008E, 0x0, "FireHawk 200 Wax BA"},
492 {HPHW_BA, 0x05A, 0x0008E, 0x0, "Raven+ L2 Backplane w/EISA Wax BA"},
493 {HPHW_BA, 0x05D, 0x0008E, 0x0, "SummitHawk Wax BA"},
494 {HPHW_BA, 0x800, 0x0008E, 0x0, "Hitachi Tiny 64 Wax BA"},
495 {HPHW_BA, 0x801, 0x0008E, 0x0, "Hitachi Tiny 80 Wax BA"},
496 {HPHW_BA, 0x011, 0x00090, 0x0, "SuperPace Wax EISA BA"},
497 {HPHW_BA, 0x017, 0x00090, 0x0, "Raven Backplane Wax EISA BA"},
498 {HPHW_BA, 0x01E, 0x00090, 0x0, "Raven T' Wax EISA BA"},
499 {HPHW_BA, 0x01F, 0x00090, 0x0, "SkyHawk 100/120 Wax EISA BA"},
500 {HPHW_BA, 0x027, 0x00090, 0x0, "Piranha 100 Wax EISA BA"},
501 {HPHW_BA, 0x028, 0x00090, 0x0, "Mirage Jr Wax EISA BA"},
502 {HPHW_BA, 0x029, 0x00090, 0x0, "Mirage Wax EISA BA"},
503 {HPHW_BA, 0x02A, 0x00090, 0x0, "Electra Wax EISA BA"},
504 {HPHW_BA, 0x02B, 0x00090, 0x0, "Mirage 80 Wax EISA BA"},
505 {HPHW_BA, 0x02C, 0x00090, 0x0, "Mirage 100+ Wax EISA BA"},
506 {HPHW_BA, 0x030, 0x00090, 0x0, "UL 350 Wax EISA BA"},
507 {HPHW_BA, 0x031, 0x00090, 0x0, "UL 550 Wax EISA BA"},
508 {HPHW_BA, 0x034, 0x00090, 0x0, "SAIC L-80 Wax EISA BA"},
509 {HPHW_BA, 0x03A, 0x00090, 0x0, "Merlin+ Wax EISA BA"},
510 {HPHW_BA, 0x040, 0x00090, 0x0, "Merlin 132 Wax EISA BA"},
511 {HPHW_BA, 0x041, 0x00090, 0x0, "Merlin 160 Wax EISA BA"},
512 {HPHW_BA, 0x043, 0x00090, 0x0, "Merlin 132/160 Wax EISA BA"},
513 {HPHW_BA, 0x052, 0x00090, 0x0, "Raven Hi Power Backplane Wax EISA BA"},
514 {HPHW_BA, 0x054, 0x00090, 0x0, "Raven Lo Power Backplane Wax EISA BA"},
515 {HPHW_BA, 0x059, 0x00090, 0x0, "FireHawk 200 Wax EISA BA"},
516 {HPHW_BA, 0x05A, 0x00090, 0x0, "Raven L2 Backplane Wax EISA BA"},
517 {HPHW_BA, 0x05D, 0x00090, 0x0, "SummitHawk Wax EISA BA"},
518 {HPHW_BA, 0x800, 0x00090, 0x0, "Hitachi Tiny 64 Wax EISA BA"},
519 {HPHW_BA, 0x801, 0x00090, 0x0, "Hitachi Tiny 80 Wax EISA BA"},
520 {HPHW_BA, 0x01A, 0x00093, 0x0, "Anole 64 TIMI BA"},
521 {HPHW_BA, 0x01B, 0x00093, 0x0, "Anole 100 TIMI BA"},
522 {HPHW_BA, 0x034, 0x00093, 0x0, "Anole T TIMI BA"},
523 {HPHW_BA, 0x04A, 0x00093, 0x0, "Anole L2 132 TIMI BA"},
524 {HPHW_BA, 0x04C, 0x00093, 0x0, "Anole L2 165 TIMI BA"},
525 {HPHW_BA, 0x582, 0x000A5, 0x00, "Epic PCI Bridge"},
526 {HPHW_BCPORT, 0x504, 0x00000, 0x00, "Phantom PseudoBC GSC+ Port"},
527 {HPHW_BCPORT, 0x505, 0x00000, 0x00, "Phantom PseudoBC GSC+ Port"},
528 {HPHW_BCPORT, 0x503, 0x0000C, 0x00, "Java BC GSC+ Port"},
529 {HPHW_BCPORT, 0x57F, 0x0000C, 0x00, "Hitachi Ghostview GSC+ Port"},
530 {HPHW_BCPORT, 0x501, 0x0000C, 0x00, "U2-IOA BC GSC+ Port"},
531 {HPHW_BCPORT, 0x502, 0x0000C, 0x00, "Uturn-IOA BC GSC+ Port"},
532 {HPHW_BCPORT, 0x780, 0x0000C, 0x00, "Astro BC Ropes Port"},
533 {HPHW_BCPORT, 0x506, 0x0000C, 0x00, "NEC-IOS BC HSC Port"},
534 {HPHW_BCPORT, 0x004, 0x0000C, 0x00, "Cheetah BC SMB Port"},
535 {HPHW_BCPORT, 0x006, 0x0000C, 0x00, "Cheetah BC MID_BUS Port"},
536 {HPHW_BCPORT, 0x005, 0x0000C, 0x00, "Condor BC MID_BUS Port"},
537 {HPHW_BCPORT, 0x100, 0x0000C, 0x00, "Condor BC HP-PB Port"},
538 {HPHW_BCPORT, 0x184, 0x0000C, 0x00, "Summit BC Port"},
539 {HPHW_BCPORT, 0x101, 0x0000C, 0x00, "Summit BC HP-PB Port"},
540 {HPHW_BCPORT, 0x102, 0x0000C, 0x00, "HP-PB Port (prefetch)"},
541 {HPHW_BCPORT, 0x500, 0x0000C, 0x00, "Gecko BOA BC GSC+ Port"},
542 {HPHW_BCPORT, 0x103, 0x0000C, 0x00, "Gecko BOA BC HP-PB Port"},
543 {HPHW_BCPORT, 0x507, 0x0000C, 0x00, "Keyaki BC GSC+ Port"},
544 {HPHW_BCPORT, 0x508, 0x0000C, 0x00, "Keyaki-DX BC GSC+ Port"},
545 {HPHW_BCPORT, 0x584, 0x0000C, 0x10, "DEW BC Runway Port"},
546 {HPHW_BCPORT, 0x800, 0x0000C, 0x10, "DEW BC Merced Port"},
547 {HPHW_BCPORT, 0x801, 0x0000C, 0x10, "SMC Bus Interface Merced Bus0"},
548 {HPHW_BCPORT, 0x802, 0x0000C, 0x10, "SMC Bus INterface Merced Bus1"},
549 {HPHW_BCPORT, 0x803, 0x0000C, 0x10, "IKE I/O BC Merced Port"},
550 {HPHW_BCPORT, 0x781, 0x0000C, 0x00, "IKE I/O BC Ropes Port"},
551 {HPHW_BCPORT, 0x804, 0x0000C, 0x10, "REO I/O BC Merced Port"},
552 {HPHW_BCPORT, 0x782, 0x0000C, 0x00, "REO I/O BC Ropes Port"},
553 {HPHW_BCPORT, 0x784, 0x0000C, 0x00, "Pluto I/O BC Ropes Port"},
554 {HPHW_BRIDGE, 0x680, 0x0000A, 0x00, "Dino PCI Bridge"},
555 {HPHW_BRIDGE, 0x682, 0x0000A, 0x00, "Cujo PCI Bridge"},
556 {HPHW_BRIDGE, 0x782, 0x0000A, 0x00, "Elroy PCI Bridge"},
557 {HPHW_BRIDGE, 0x583, 0x000A5, 0x00, "Saga PCI Bridge"},
558 {HPHW_BRIDGE, 0x783, 0x0000A, 0x00, "Mercury PCI Bridge"},
559 {HPHW_BRIDGE, 0x784, 0x0000A, 0x00, "Quicksilver AGP Bridge"},
560 {HPHW_B_DMA, 0x004, 0x00018, 0x00, "Parallel I/O"},
561 {HPHW_B_DMA, 0x004, 0x00019, 0x00, "Parallel RDB"},
562 {HPHW_B_DMA, 0x004, 0x00020, 0x80, "MID_BUS PSI"},
563 {HPHW_B_DMA, 0x004, 0x0002F, 0x80, "HP-PB Transit PSI (36960A)"},
564 {HPHW_B_DMA, 0x008, 0x00051, 0x80, "HP-PB Transit 802.3"},
565 {HPHW_B_DMA, 0x004, 0x00052, 0x80, "Miura LAN/Console (J2146A)"},
566 {HPHW_B_DMA, 0x008, 0x00058, 0x80, "HP-PB Transit 802.4"},
567 {HPHW_B_DMA, 0x005, 0x00060, 0x80, "KittyHawk CSY Core LAN/Console"},
568 {HPHW_B_DMA, 0x014, 0x00060, 0x80, "Diablo LAN/Console"},
569 {HPHW_B_DMA, 0x054, 0x00060, 0x80, "Countach LAN/Console"},
570 {HPHW_B_DMA, 0x004, 0x00094, 0x80, "KittyHawk GSC+ Exerciser"},
571 {HPHW_B_DMA, 0x004, 0x00100, 0x80, "HP-PB HF Interface"},
572 {HPHW_B_DMA, 0x000, 0x00206, 0x80, "MELCO HMPHA"},
573 {HPHW_B_DMA, 0x005, 0x00206, 0x80, "MELCO HMPHA_10"},
574 {HPHW_B_DMA, 0x006, 0x00206, 0x80, "MELCO HMQHA"},
575 {HPHW_B_DMA, 0x007, 0x00206, 0x80, "MELCO HMQHA_10"},
576 {HPHW_B_DMA, 0x004, 0x207, 0x80, "MELCO HNDWA MDWS-70"},
577 {HPHW_CIO, 0x004, 0x00010, 0x00, "VLSI CIO"},
578 {HPHW_CIO, 0x005, 0x00010, 0x00, "Silverfox CIO"},
579 {HPHW_CIO, 0x006, 0x00010, 0x00, "Emerald CIO"},
580 {HPHW_CIO, 0x008, 0x00010, 0x00, "Discrete CIO"},
581 {HPHW_CONSOLE, 0x004, 0x0001C, 0x00, "Cheetah console"},
582 {HPHW_CONSOLE, 0x005, 0x0001C, 0x00, "Emerald console"},
583 {HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"},
584 {HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"},
585 {HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"},
586 {HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"},
587 {HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"},
588 {HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"},
589 {HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"},
590 {HPHW_FIO, 0x004, 0x0004F, 0x0, "8-Port X.25 EISA-ACC (AMSO)"},
591 {HPHW_FIO, 0x004, 0x00071, 0x0, "Cobra Core SCSI"},
592 {HPHW_FIO, 0x005, 0x00071, 0x0, "Coral Core SCSI"},
593 {HPHW_FIO, 0x006, 0x00071, 0x0, "Bushmaster Core SCSI"},
594 {HPHW_FIO, 0x007, 0x00071, 0x0, "Scorpio Core SCSI"},
595 {HPHW_FIO, 0x008, 0x00071, 0x0, "Flounder Core SCSI"},
596 {HPHW_FIO, 0x009, 0x00071, 0x0, "Outfield Core SCSI"},
597 {HPHW_FIO, 0x00A, 0x00071, 0x0, "CoralII Core SCSI"},
598 {HPHW_FIO, 0x00B, 0x00071, 0x0, "Scorpio Jr. Core SCSI"},
599 {HPHW_FIO, 0x00C, 0x00071, 0x0, "Strider-50 Core SCSI"},
600 {HPHW_FIO, 0x00D, 0x00071, 0x0, "Strider-33 Core SCSI"},
601 {HPHW_FIO, 0x00E, 0x00071, 0x0, "Trailways-50 Core SCSI"},
602 {HPHW_FIO, 0x00F, 0x00071, 0x0, "Trailways-33 Core SCSI"},
603 {HPHW_FIO, 0x010, 0x00071, 0x0, "Pace Core SCSI"},
604 {HPHW_FIO, 0x011, 0x00071, 0x0, "Sidewinder Core SCSI"},
605 {HPHW_FIO, 0x019, 0x00071, 0x0, "Scorpio Sr. Core SCSI"},
606 {HPHW_FIO, 0x020, 0x00071, 0x0, "Scorpio 100 Core SCSI"},
607 {HPHW_FIO, 0x021, 0x00071, 0x0, "Spectra 50 Core SCSI"},
608 {HPHW_FIO, 0x022, 0x00071, 0x0, "Spectra 75 Core SCSI"},
609 {HPHW_FIO, 0x023, 0x00071, 0x0, "Spectra 100 Core SCSI"},
610 {HPHW_FIO, 0x024, 0x00071, 0x0, "Fast Pace Core SCSI"},
611 {HPHW_FIO, 0x026, 0x00071, 0x0, "CoralII Jaguar Core SCSI"},
612 {HPHW_FIO, 0x004, 0x00072, 0x0, "Cobra Core LAN (802.3)"},
613 {HPHW_FIO, 0x005, 0x00072, 0x0, "Coral Core LAN (802.3)"},
614 {HPHW_FIO, 0x006, 0x00072, 0x0, "Bushmaster Core LAN (802.3)"},
615 {HPHW_FIO, 0x007, 0x00072, 0x0, "Scorpio Core LAN (802.3)"},
616 {HPHW_FIO, 0x008, 0x00072, 0x0, "Flounder Core LAN (802.3)"},
617 {HPHW_FIO, 0x009, 0x00072, 0x0, "Outfield Core LAN (802.3)"},
618 {HPHW_FIO, 0x00A, 0x00072, 0x0, "CoralII Core LAN (802.3)"},
619 {HPHW_FIO, 0x00B, 0x00072, 0x0, "Scorpio Jr. Core LAN (802.3)"},
620 {HPHW_FIO, 0x00C, 0x00072, 0x0, "Strider-50 Core LAN (802.3)"},
621 {HPHW_FIO, 0x00D, 0x00072, 0x0, "Strider-33 Core LAN (802.3)"},
622 {HPHW_FIO, 0x00E, 0x00072, 0x0, "Trailways-50 Core LAN (802.3)"},
623 {HPHW_FIO, 0x00F, 0x00072, 0x0, "Trailways-33 Core LAN (802.3)"},
624 {HPHW_FIO, 0x010, 0x00072, 0x0, "Pace Core LAN (802.3)"},
625 {HPHW_FIO, 0x011, 0x00072, 0x0, "Sidewinder Core LAN (802.3)"},
626 {HPHW_FIO, 0x019, 0x00072, 0x0, "Scorpio Sr. Core LAN (802.3)"},
627 {HPHW_FIO, 0x020, 0x00072, 0x0, "Scorpio 100 Core LAN (802.3)"},
628 {HPHW_FIO, 0x021, 0x00072, 0x0, "Spectra 50 Core LAN (802.3)"},
629 {HPHW_FIO, 0x022, 0x00072, 0x0, "Spectra 75 Core LAN (802.3)"},
630 {HPHW_FIO, 0x023, 0x00072, 0x0, "Spectra 100 Core LAN (802.3)"},
631 {HPHW_FIO, 0x024, 0x00072, 0x0, "Fast Pace Core LAN (802.3)"},
632 {HPHW_FIO, 0x026, 0x00072, 0x0, "CoralII Jaguar Core LAN (802.3)"},
633 {HPHW_FIO, 0x004, 0x00073, 0x0, "Cobra Core HIL"},
634 {HPHW_FIO, 0x005, 0x00073, 0x0, "Coral Core HIL"},
635 {HPHW_FIO, 0x006, 0x00073, 0x0, "Bushmaster Core HIL"},
636 {HPHW_FIO, 0x007, 0x00073, 0x0, "Scorpio Core HIL"},
637 {HPHW_FIO, 0x008, 0x00073, 0x0, "Flounder Core HIL"},
638 {HPHW_FIO, 0x009, 0x00073, 0x0, "Outfield Core HIL"},
639 {HPHW_FIO, 0x00A, 0x00073, 0x0, "CoralII Core HIL"},
640 {HPHW_FIO, 0x00B, 0x00073, 0x0, "Scorpio Jr. Core HIL"},
641 {HPHW_FIO, 0x00C, 0x00073, 0x0, "Strider-50 Core HIL"},
642 {HPHW_FIO, 0x00D, 0x00073, 0x0, "Strider-33 Core HIL"},
643 {HPHW_FIO, 0x00E, 0x00073, 0x0, "Trailways-50 Core HIL"},
644 {HPHW_FIO, 0x00F, 0x00073, 0x0, "Trailways-33 Core HIL"},
645 {HPHW_FIO, 0x010, 0x00073, 0x0, "Pace Core HIL"},
646 {HPHW_FIO, 0x011, 0x00073, 0xcc, "SuperPace Wax HIL"},
647 {HPHW_FIO, 0x012, 0x00073, 0x0, "Mirage Jr Wax HIL"},
648 {HPHW_FIO, 0x013, 0x00073, 0x0, "Mirage 100 Wax HIL"},
649 {HPHW_FIO, 0x014, 0x00073, 0x0, "Electra Wax HIL"},
650 {HPHW_FIO, 0x017, 0x00073, 0x0, "Raven Backplane Wax HIL"},
651 {HPHW_FIO, 0x019, 0x00073, 0x0, "Scorpio Sr. Core HIL"},
652 {HPHW_FIO, 0x01E, 0x00073, 0x0, "Raven T' Wax HIL"},
653 {HPHW_FIO, 0x01F, 0x00073, 0x0, "SkyHawk 100/120 Wax HIL"},
654 {HPHW_FIO, 0x020, 0x00073, 0x0, "Scorpio 100 Core HIL"},
655 {HPHW_FIO, 0x021, 0x00073, 0x0, "Spectra 50 Core HIL"},
656 {HPHW_FIO, 0x022, 0x00073, 0x0, "Spectra 75 Core HIL"},
657 {HPHW_FIO, 0x023, 0x00073, 0x0, "Spectra 100 Core HIL"},
658 {HPHW_FIO, 0x024, 0x00073, 0x0, "Fast Pace Core HIL"},
659 {HPHW_FIO, 0x026, 0x00073, 0x0, "CoralII Jaguar Core HIL"},
660 {HPHW_FIO, 0x02B, 0x00073, 0x0, "Mirage 80 Wax HIL"},
661 {HPHW_FIO, 0x02C, 0x00073, 0x0, "Mirage 100+ Wax HIL"},
662 {HPHW_FIO, 0x03A, 0x00073, 0x0, "Merlin+ Wax HIL"},
663 {HPHW_FIO, 0x040, 0x00073, 0x0, "Merlin 132 Wax HIL"},
664 {HPHW_FIO, 0x041, 0x00073, 0x0, "Merlin 160 Wax HIL"},
665 {HPHW_FIO, 0x043, 0x00073, 0x0, "Merlin 132/160 Wax HIL"},
666 {HPHW_FIO, 0x052, 0x00073, 0x0, "Raven+ Hi Power Backplane w/EISA Wax HIL"},
667 {HPHW_FIO, 0x053, 0x00073, 0x0, "Raven+ Hi Power Backplane wo/EISA Wax HIL"},
668 {HPHW_FIO, 0x054, 0x00073, 0x0, "Raven+ Lo Power Backplane w/EISA Wax HIL"},
669 {HPHW_FIO, 0x055, 0x00073, 0x0, "Raven+ Lo Power Backplane wo/EISA Wax HIL"},
670 {HPHW_FIO, 0x059, 0x00073, 0x0, "FireHawk 200 Wax HIL"},
671 {HPHW_FIO, 0x05A, 0x00073, 0x0, "Raven+ L2 Backplane w/EISA Wax HIL"},
672 {HPHW_FIO, 0x05B, 0x00073, 0x0, "Raven+ L2 Backplane wo/EISA Wax HIL"},
673 {HPHW_FIO, 0x05D, 0x00073, 0x0, "SummitHawk Wax HIL"},
674 {HPHW_FIO, 0x800, 0x00073, 0x0, "Hitachi Tiny 64 Wax HIL"},
675 {HPHW_FIO, 0x801, 0x00073, 0x0, "Hitachi Tiny 80 Wax HIL"},
676 {HPHW_FIO, 0x004, 0x00074, 0x0, "Cobra Core Centronics"},
677 {HPHW_FIO, 0x005, 0x00074, 0x0, "Coral Core Centronics"},
678 {HPHW_FIO, 0x006, 0x00074, 0x0, "Bushmaster Core Centronics"},
679 {HPHW_FIO, 0x007, 0x00074, 0x0, "Scorpio Core Centronics"},
680 {HPHW_FIO, 0x008, 0x00074, 0x0, "Flounder Core Centronics"},
681 {HPHW_FIO, 0x009, 0x00074, 0x0, "Outfield Core Centronics"},
682 {HPHW_FIO, 0x00A, 0x00074, 0x0, "CoralII Core Centronics"},
683 {HPHW_FIO, 0x00B, 0x00074, 0x0, "Scorpio Jr. Core Centronics"},
684 {HPHW_FIO, 0x00C, 0x00074, 0x0, "Strider-50 Core Centronics"},
685 {HPHW_FIO, 0x00D, 0x00074, 0x0, "Strider-33 Core Centronics"},
686 {HPHW_FIO, 0x00E, 0x00074, 0x0, "Trailways-50 Core Centronics"},
687 {HPHW_FIO, 0x00F, 0x00074, 0x0, "Trailways-33 Core Centronics"},
688 {HPHW_FIO, 0x010, 0x00074, 0x0, "Pace Core Centronics"},
689 {HPHW_FIO, 0x011, 0x00074, 0x0, "Sidewinder Core Centronics"},
690 {HPHW_FIO, 0x015, 0x00074, 0x0, "KittyHawk GSY Core Centronics"},
691 {HPHW_FIO, 0x016, 0x00074, 0x0, "Gecko Core Centronics"},
692 {HPHW_FIO, 0x019, 0x00074, 0x0, "Scorpio Sr. Core Centronics"},
693 {HPHW_FIO, 0x01A, 0x00074, 0x0, "Anole 64 Core Centronics"},
694 {HPHW_FIO, 0x01B, 0x00074, 0x0, "Anole 100 Core Centronics"},
695 {HPHW_FIO, 0x01C, 0x00074, 0x0, "Gecko 80 Core Centronics"},
696 {HPHW_FIO, 0x01D, 0x00074, 0x0, "Gecko 100 Core Centronics"},
697 {HPHW_FIO, 0x01F, 0x00074, 0x0, "SkyHawk 100/120 Core Centronics"},
698 {HPHW_FIO, 0x020, 0x00074, 0x0, "Scorpio 100 Core Centronics"},
699 {HPHW_FIO, 0x021, 0x00074, 0x0, "Spectra 50 Core Centronics"},
700 {HPHW_FIO, 0x022, 0x00074, 0x0, "Spectra 75 Core Centronics"},
701 {HPHW_FIO, 0x023, 0x00074, 0x0, "Spectra 100 Core Centronics"},
702 {HPHW_FIO, 0x024, 0x00074, 0x0, "Fast Pace Core Centronics"},
703 {HPHW_FIO, 0x026, 0x00074, 0x0, "CoralII Jaguar Core Centronics"},
704 {HPHW_FIO, 0x027, 0x00074, 0x0, "Piranha 100 Core Centronics"},
705 {HPHW_FIO, 0x028, 0x00074, 0x0, "Mirage Jr Core Centronics"},
706 {HPHW_FIO, 0x029, 0x00074, 0x0, "Mirage Core Centronics"},
707 {HPHW_FIO, 0x02A, 0x00074, 0x0, "Electra Core Centronics"},
708 {HPHW_FIO, 0x02B, 0x00074, 0x0, "Mirage 80 Core Centronics"},
709 {HPHW_FIO, 0x02C, 0x00074, 0x0, "Mirage 100+ Core Centronics"},
710 {HPHW_FIO, 0x02E, 0x00074, 0x0, "UL 350 Core Centronics"},
711 {HPHW_FIO, 0x02F, 0x00074, 0x0, "UL 550 Core Centronics"},
712 {HPHW_FIO, 0x032, 0x00074, 0x0, "Raven T' Core Centronics"},
713 {HPHW_FIO, 0x033, 0x00074, 0x0, "Anole T Core Centronics"},
714 {HPHW_FIO, 0x034, 0x00074, 0x0, "SAIC L-80 Core Centronics"},
715 {HPHW_FIO, 0x035, 0x00074, 0x0, "PCX-L2 712/132 Core Centronics"},
716 {HPHW_FIO, 0x036, 0x00074, 0x0, "PCX-L2 712/160 Core Centronics"},
717 {HPHW_FIO, 0x03B, 0x00074, 0x0, "Raven U/L2 Core Centronics"},
718 {HPHW_FIO, 0x03C, 0x00074, 0x0, "Merlin 132 Core Centronics"},
719 {HPHW_FIO, 0x03D, 0x00074, 0x0, "Merlin 160 Core Centronics"},
720 {HPHW_FIO, 0x03E, 0x00074, 0x0, "Merlin+ 132 Core Centronics"},
721 {HPHW_FIO, 0x03F, 0x00074, 0x0, "Merlin+ 180 Core Centronics"},
722 {HPHW_FIO, 0x044, 0x00074, 0x0, "Mohawk Core Centronics"},
723 {HPHW_FIO, 0x045, 0x00074, 0x0, "Rocky1 Core Centronics"},
724 {HPHW_FIO, 0x046, 0x00074, 0x0, "Rocky2 120 Core Centronics"},
725 {HPHW_FIO, 0x047, 0x00074, 0x0, "Rocky2 150 Core Centronics"},
726 {HPHW_FIO, 0x04B, 0x00074, 0x0, "Anole L2 132 Core Centronics"},
727 {HPHW_FIO, 0x04D, 0x00074, 0x0, "Anole L2 165 Core Centronics"},
728 {HPHW_FIO, 0x050, 0x00074, 0x0, "Merlin Jr 132 Core Centronics"},
729 {HPHW_FIO, 0x051, 0x00074, 0x0, "Firehawk Core Centronics"},
730 {HPHW_FIO, 0x056, 0x00074, 0x0, "Raven+ w SE FWSCSI Core Centronics"},
731 {HPHW_FIO, 0x057, 0x00074, 0x0, "Raven+ w Diff FWSCSI Core Centronics"},
732 {HPHW_FIO, 0x058, 0x00074, 0x0, "FireHawk 200 Core Centronics"},
733 {HPHW_FIO, 0x05C, 0x00074, 0x0, "SummitHawk 230 Core Centronics"},
734 {HPHW_FIO, 0x800, 0x00074, 0x0, "Hitachi Tiny 64 Core Centronics"},
735 {HPHW_FIO, 0x801, 0x00074, 0x0, "Hitachi Tiny 80 Core Centronics"},
736 {HPHW_FIO, 0x004, 0x00075, 0x0, "Cobra Core RS-232"},
737 {HPHW_FIO, 0x005, 0x00075, 0x0, "Coral Core RS-232"},
738 {HPHW_FIO, 0x006, 0x00075, 0x0, "Bushmaster Core RS-232"},
739 {HPHW_FIO, 0x007, 0x00075, 0x0, "Scorpio Core RS-232"},
740 {HPHW_FIO, 0x008, 0x00075, 0x0, "Flounder Core RS-232"},
741 {HPHW_FIO, 0x009, 0x00075, 0x0, "Outfield Core RS-232"},
742 {HPHW_FIO, 0x00A, 0x00075, 0x0, "CoralII Core RS-232"},
743 {HPHW_FIO, 0x00B, 0x00075, 0x0, "Scorpio Jr. Core RS-232"},
744 {HPHW_FIO, 0x00C, 0x00075, 0x0, "Strider-50 Core RS-232"},
745 {HPHW_FIO, 0x00D, 0x00075, 0x0, "Strider-33 Core RS-232"},
746 {HPHW_FIO, 0x00E, 0x00075, 0x0, "Trailways-50 Core RS-232"},
747 {HPHW_FIO, 0x00F, 0x00075, 0x0, "Trailways-33 Core RS-232"},
748 {HPHW_FIO, 0x010, 0x00075, 0x0, "Pace Core RS-232"},
749 {HPHW_FIO, 0x011, 0x00075, 0x0, "Sidewinder Core RS-232"},
750 {HPHW_FIO, 0x019, 0x00075, 0x0, "Scorpio Sr. Core RS-232"},
751 {HPHW_FIO, 0x020, 0x00075, 0x0, "Scorpio 100 Core RS-232"},
752 {HPHW_FIO, 0x021, 0x00075, 0x0, "Spectra 50 Core RS-232"},
753 {HPHW_FIO, 0x022, 0x00075, 0x0, "Spectra 75 Core RS-232"},
754 {HPHW_FIO, 0x023, 0x00075, 0x0, "Spectra 100 Core RS-232"},
755 {HPHW_FIO, 0x024, 0x00075, 0x0, "Fast Pace Core RS-232"},
756 {HPHW_FIO, 0x026, 0x00075, 0x0, "CoralII Jaguar Core RS-232"},
757 {HPHW_FIO, 0x004, 0x00077, 0x0, "Coral SGC Graphics"},
758 {HPHW_FIO, 0x005, 0x00077, 0x0, "Hyperdrive Optional Graphics"},
759 {HPHW_FIO, 0x006, 0x00077, 0x0, "Stinger Optional Graphics"},
760 {HPHW_FIO, 0x007, 0x00077, 0x0, "Scorpio Builtin Graphics"},
761 {HPHW_FIO, 0x008, 0x00077, 0x0, "Anole Hyperdrive Optional Graphics"},
762 {HPHW_FIO, 0x009, 0x00077, 0x0, "Thunder II graphics EISA form"},
763 {HPHW_FIO, 0x00A, 0x00077, 0x0, "Thunder II graphics GSA form"},
764 {HPHW_FIO, 0x00B, 0x00077, 0x0, "Scorpio Jr Builtin Graphics"},
765 {HPHW_FIO, 0x00C, 0x00077, 0x0, "Strider-50 SSC Graphics"},
766 {HPHW_FIO, 0x00D, 0x00077, 0x0, "Strider-33 SSC Graphics"},
767 {HPHW_FIO, 0x00E, 0x00077, 0x0, "Trailways-50 SSC Graphics"},
768 {HPHW_FIO, 0x00F, 0x00077, 0x0, "Trailways-33 SSC Graphics"},
769 {HPHW_FIO, 0x010, 0x00077, 0x0, "Pace SGC Graphics"},
770 {HPHW_FIO, 0x011, 0x00077, 0x0, "Mohawk Opt. 2D Graphics (Kid)"},
771 {HPHW_FIO, 0x012, 0x00077, 0x0, "Raven Opt. 2D Graphics (Goat)"},
772 {HPHW_FIO, 0x016, 0x00077, 0x0, "Lego 24 SCG Graphics"},
773 {HPHW_FIO, 0x017, 0x00077, 0x0, "Lego 24Z SCG Graphics"},
774 {HPHW_FIO, 0x018, 0x00077, 0x0, "Lego 48Z SCG Graphics"},
775 {HPHW_FIO, 0x019, 0x00077, 0x0, "Scorpio Sr Builtin Graphics"},
776 {HPHW_FIO, 0x020, 0x00077, 0x0, "Scorpio 100 Builtin Graphics"},
777 {HPHW_FIO, 0x021, 0x00077, 0x0, "Spectra 50 Builtin Graphics"},
778 {HPHW_FIO, 0x022, 0x00077, 0x0, "Spectra 75 Builtin Graphics"},
779 {HPHW_FIO, 0x023, 0x00077, 0x0, "Spectra 100 Builtin Graphics"},
780 {HPHW_FIO, 0x024, 0x00077, 0x0, "Fast Pace SGC Graphics"},
781 {HPHW_FIO, 0x006, 0x0007A, 0x0, "Bushmaster Audio"},
782 {HPHW_FIO, 0x008, 0x0007A, 0x0, "Flounder Audio"},
783 {HPHW_FIO, 0x004, 0x0007B, 0x0, "UL Optional Audio"},
784 {HPHW_FIO, 0x007, 0x0007B, 0x0, "Scorpio Audio"},
785 {HPHW_FIO, 0x00B, 0x0007B, 0x0, "Scorpio Jr. Audio"},
786 {HPHW_FIO, 0x00C, 0x0007B, 0x0, "Strider-50 Audio"},
787 {HPHW_FIO, 0x00D, 0x0007B, 0x0, "Strider-33 Audio"},
788 {HPHW_FIO, 0x00E, 0x0007B, 0x0, "Trailways-50 Audio"},
789 {HPHW_FIO, 0x00F, 0x0007B, 0x0, "Trailways-33 Audio"},
790 {HPHW_FIO, 0x015, 0x0007B, 0x0, "KittyHawk GSY Core Audio"},
791 {HPHW_FIO, 0x016, 0x0007B, 0x0, "Gecko Audio"},
792 {HPHW_FIO, 0x019, 0x0007B, 0x0, "Scorpio Sr. Audio"},
793 {HPHW_FIO, 0x01A, 0x0007B, 0x0, "Anole 64 Audio"},
794 {HPHW_FIO, 0x01B, 0x0007B, 0x0, "Anole 100 Audio"},
795 {HPHW_FIO, 0x01C, 0x0007B, 0x0, "Gecko 80 Audio"},
796 {HPHW_FIO, 0x01D, 0x0007B, 0x0, "Gecko 100 Audio"},
797 {HPHW_FIO, 0x01F, 0x0007B, 0x0, "SkyHawk 100/120 Audio"},
798 {HPHW_FIO, 0x020, 0x0007B, 0x0, "Scorpio 100 Audio"},
799 {HPHW_FIO, 0x021, 0x0007B, 0x0, "Spectra 50 Audio"},
800 {HPHW_FIO, 0x022, 0x0007B, 0x0, "Spectra 75 Audio"},
801 {HPHW_FIO, 0x023, 0x0007B, 0x0, "Spectra 100 Audio"},
802 {HPHW_FIO, 0x028, 0x0007B, 0x0, "Mirage Jr Audio"},
803 {HPHW_FIO, 0x029, 0x0007B, 0x0, "Mirage Audio"},
804 {HPHW_FIO, 0x02A, 0x0007B, 0x0, "Electra Audio"},
805 {HPHW_FIO, 0x02B, 0x0007B, 0x0, "Mirage 80 Audio"},
806 {HPHW_FIO, 0x02C, 0x0007B, 0x0, "Mirage 100+ Audio"},
807 {HPHW_FIO, 0x032, 0x0007B, 0x0, "Raven T' Audio"},
808 {HPHW_FIO, 0x034, 0x0007B, 0x0, "SAIC L-80 Audio"},
809 {HPHW_FIO, 0x035, 0x0007B, 0x0, "PCX-L2 712/132 Core Audio"},
810 {HPHW_FIO, 0x036, 0x0007B, 0x0, "PCX-L2 712/160 Core Audio"},
811 {HPHW_FIO, 0x03B, 0x0007B, 0x0, "Raven U/L2 Core Audio"},
812 {HPHW_FIO, 0x03C, 0x0007B, 0x0, "Merlin 132 Core Audio"},
813 {HPHW_FIO, 0x03D, 0x0007B, 0x0, "Merlin 160 Core Audio"},
814 {HPHW_FIO, 0x03E, 0x0007B, 0x0, "Merlin+ 132 Core Audio"},
815 {HPHW_FIO, 0x03F, 0x0007B, 0x0, "Merlin+ 180 Core Audio"},
816 {HPHW_FIO, 0x044, 0x0007B, 0x0, "Mohawk Core Audio"},
817 {HPHW_FIO, 0x046, 0x0007B, 0x0, "Rocky2 120 Core Audio"},
818 {HPHW_FIO, 0x047, 0x0007B, 0x0, "Rocky2 150 Core Audio"},
819 {HPHW_FIO, 0x04B, 0x0007B, 0x0, "Anole L2 132 Core Audio"},
820 {HPHW_FIO, 0x04D, 0x0007B, 0x0, "Anole L2 165 Core Audio"},
821 {HPHW_FIO, 0x04E, 0x0007B, 0x0, "Kiji L2 132 Core Audio"},
822 {HPHW_FIO, 0x050, 0x0007B, 0x0, "Merlin Jr 132 Core Audio"},
823 {HPHW_FIO, 0x051, 0x0007B, 0x0, "Firehawk Audio"},
824 {HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSI Core Audio"},
825 {HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSI Core Audio"},
826 {HPHW_FIO, 0x058, 0x0007B, 0x0, "FireHawk 200 Audio"},
827 {HPHW_FIO, 0x05C, 0x0007B, 0x0, "SummitHawk 230 Core Audio"},
828 {HPHW_FIO, 0x800, 0x0007B, 0x0, "Hitachi Tiny 64 Audio"},
829 {HPHW_FIO, 0x801, 0x0007B, 0x0, "Hitachi Tiny 80 Audio"},
830 {HPHW_FIO, 0x009, 0x0007C, 0x0, "Outfield FW SCSI"},
831 {HPHW_FIO, 0x00A, 0x0007C, 0x0, "CoralII FW SCSI"},
832 {HPHW_FIO, 0x026, 0x0007C, 0x0, "CoralII Jaguar FW SCSI"},
833 {HPHW_FIO, 0x009, 0x0007D, 0x0, "Outfield FDDI"},
834 {HPHW_FIO, 0x00A, 0x0007D, 0x0, "CoralII FDDI"},
835 {HPHW_FIO, 0x026, 0x0007D, 0x0, "CoralII Jaguar FDDI"},
836 {HPHW_FIO, 0x010, 0x0007E, 0x0, "Pace Audio"},
837 {HPHW_FIO, 0x024, 0x0007E, 0x0, "Fast Pace Audio"},
838 {HPHW_FIO, 0x009, 0x0007F, 0x0, "Outfield Audio"},
839 {HPHW_FIO, 0x00A, 0x0007F, 0x0, "CoralII Audio"},
840 {HPHW_FIO, 0x026, 0x0007F, 0x0, "CoralII Jaguar Audio"},
841 {HPHW_FIO, 0x010, 0x00080, 0x0, "Pace Core HPIB"},
842 {HPHW_FIO, 0x024, 0x00080, 0x0, "Fast Pace Core HPIB"},
843 {HPHW_FIO, 0x015, 0x00082, 0x0, "KittyHawk GSY Core SCSI"},
844 {HPHW_FIO, 0x016, 0x00082, 0x0, "Gecko Core SCSI"},
845 {HPHW_FIO, 0x01A, 0x00082, 0x0, "Anole 64 Core SCSI"},
846 {HPHW_FIO, 0x01B, 0x00082, 0x0, "Anole 100 Core SCSI"},
847 {HPHW_FIO, 0x01C, 0x00082, 0x0, "Gecko 80 Core SCSI"},
848 {HPHW_FIO, 0x01D, 0x00082, 0x0, "Gecko 100 Core SCSI"},
849 {HPHW_FIO, 0x01F, 0x00082, 0x0, "SkyHawk 100/120 Core SCSI"},
850 {HPHW_FIO, 0x027, 0x00082, 0x0, "Piranha 100 Core SCSI"},
851 {HPHW_FIO, 0x028, 0x00082, 0x0, "Mirage Jr Core SCSI"},
852 {HPHW_FIO, 0x029, 0x00082, 0x0, "Mirage Core SCSI"},
853 {HPHW_FIO, 0x02A, 0x00082, 0x0, "Electra Core SCSI"},
854 {HPHW_FIO, 0x02B, 0x00082, 0x0, "Mirage 80 Core SCSI"},
855 {HPHW_FIO, 0x02C, 0x00082, 0x0, "Mirage 100+ Core SCSI"},
856 {HPHW_FIO, 0x02E, 0x00082, 0x0, "UL 350 Core SCSI"},
857 {HPHW_FIO, 0x02F, 0x00082, 0x0, "UL 550 Core SCSI"},
858 {HPHW_FIO, 0x032, 0x00082, 0x0, "Raven T' Core SCSI"},
859 {HPHW_FIO, 0x033, 0x00082, 0x0, "Anole T Core SCSI"},
860 {HPHW_FIO, 0x034, 0x00082, 0x0, "SAIC L-80 Core SCSI"},
861 {HPHW_FIO, 0x035, 0x00082, 0x0, "PCX-L2 712/132 Core SCSI"},
862 {HPHW_FIO, 0x036, 0x00082, 0x0, "PCX-L2 712/160 Core SCSI"},
863 {HPHW_FIO, 0x03B, 0x00082, 0x0, "Raven U/L2 Core SCSI"},
864 {HPHW_FIO, 0x03C, 0x00082, 0x0, "Merlin 132 Core SCSI"},
865 {HPHW_FIO, 0x03D, 0x00082, 0x0, "Merlin 160 Core SCSI"},
866 {HPHW_FIO, 0x03E, 0x00082, 0x0, "Merlin+ 132 Core SCSI"},
867 {HPHW_FIO, 0x03F, 0x00082, 0x0, "Merlin+ 180 Core SCSI"},
868 {HPHW_FIO, 0x044, 0x00082, 0x0, "Mohawk Core SCSI"},
869 {HPHW_FIO, 0x045, 0x00082, 0x0, "Rocky1 Core SCSI"},
870 {HPHW_FIO, 0x046, 0x00082, 0x0, "Rocky2 120 Core SCSI"},
871 {HPHW_FIO, 0x047, 0x00082, 0x0, "Rocky2 150 Core SCSI"},
872 {HPHW_FIO, 0x04B, 0x00082, 0x0, "Anole L2 132 Core SCSI"},
873 {HPHW_FIO, 0x04D, 0x00082, 0x0, "Anole L2 165 Core SCSI"},
874 {HPHW_FIO, 0x04E, 0x00082, 0x0, "Kiji L2 132 Core SCSI"},
875 {HPHW_FIO, 0x050, 0x00082, 0x0, "Merlin Jr 132 Core SCSI"},
876 {HPHW_FIO, 0x051, 0x00082, 0x0, "Firehawk Core SCSI"},
877 {HPHW_FIO, 0x056, 0x00082, 0x0, "Raven+ w SE FWSCSI Core SCSI"},
878 {HPHW_FIO, 0x057, 0x00082, 0x0, "Raven+ w Diff FWSCSI Core SCSI"},
879 {HPHW_FIO, 0x058, 0x00082, 0x0, "FireHawk 200 Core SCSI"},
880 {HPHW_FIO, 0x05C, 0x00082, 0x0, "SummitHawk 230 Core SCSI"},
881 {HPHW_FIO, 0x05E, 0x00082, 0x0, "Staccato 132 Core SCSI"},
882 {HPHW_FIO, 0x05F, 0x00082, 0x0, "Staccato 180 Core SCSI"},
883 {HPHW_FIO, 0x800, 0x00082, 0x0, "Hitachi Tiny 64 Core SCSI"},
884 {HPHW_FIO, 0x801, 0x00082, 0x0, "Hitachi Tiny 80 Core SCSI"},
885 {HPHW_FIO, 0x016, 0x00083, 0x0, "Gecko Core PC Floppy"},
886 {HPHW_FIO, 0x01C, 0x00083, 0x0, "Gecko 80 Core PC Floppy"},
887 {HPHW_FIO, 0x01D, 0x00083, 0x0, "Gecko 100 Core PC Floppy"},
888 {HPHW_FIO, 0x051, 0x00083, 0x0, "Firehawk Core PC Floppy"},
889 {HPHW_FIO, 0x058, 0x00083, 0x0, "FireHawk 200 Core PC Floppy"},
890 {HPHW_FIO, 0x027, 0x00083, 0x0, "Piranha 100 Core PC Floppy"},
891 {HPHW_FIO, 0x028, 0x00083, 0x0, "Mirage Jr Core PC Floppy"},
892 {HPHW_FIO, 0x029, 0x00083, 0x0, "Mirage Core PC Floppy"},
893 {HPHW_FIO, 0x02A, 0x00083, 0x0, "Electra Core PC Floppy"},
894 {HPHW_FIO, 0x02B, 0x00083, 0x0, "Mirage 80 Core PC Floppy"},
895 {HPHW_FIO, 0x02C, 0x00083, 0x0, "Mirage 100+ Core PC Floppy"},
896 {HPHW_FIO, 0x02E, 0x00083, 0x0, "UL 350 Core PC Floppy"},
897 {HPHW_FIO, 0x02F, 0x00083, 0x0, "UL 550 Core PC Floppy"},
898 {HPHW_FIO, 0x032, 0x00083, 0x0, "Raven T' Core PC Floppy"},
899 {HPHW_FIO, 0x034, 0x00083, 0x0, "SAIC L-80 Core PC Floppy"},
900 {HPHW_FIO, 0x035, 0x00083, 0x0, "PCX-L2 712/132 Core Floppy"},
901 {HPHW_FIO, 0x036, 0x00083, 0x0, "PCX-L2 712/160 Core Floppy"},
902 {HPHW_FIO, 0x03B, 0x00083, 0x0, "Raven U/L2 Core PC Floppy"},
903 {HPHW_FIO, 0x03C, 0x00083, 0x0, "Merlin 132 Core PC Floppy"},
904 {HPHW_FIO, 0x03D, 0x00083, 0x0, "Merlin 160 Core PC Floppy"},
905 {HPHW_FIO, 0x03E, 0x00083, 0x0, "Merlin+ 132 Core PC Floppy"},
906 {HPHW_FIO, 0x03F, 0x00083, 0x0, "Merlin+ 180 Core PC Floppy"},
907 {HPHW_FIO, 0x045, 0x00083, 0x0, "Rocky1 Core PC Floppy"},
908 {HPHW_FIO, 0x046, 0x00083, 0x0, "Rocky2 120 Core PC Floppy"},
909 {HPHW_FIO, 0x047, 0x00083, 0x0, "Rocky2 150 Core PC Floppy"},
910 {HPHW_FIO, 0x04E, 0x00083, 0x0, "Kiji L2 132 Core PC Floppy"},
911 {HPHW_FIO, 0x050, 0x00083, 0x0, "Merlin Jr 132 Core PC Floppy"},
912 {HPHW_FIO, 0x056, 0x00083, 0x0, "Raven+ w SE FWSCSI Core PC Floppy"},
913 {HPHW_FIO, 0x057, 0x00083, 0x0, "Raven+ w Diff FWSCSI Core PC Floppy"},
914 {HPHW_FIO, 0x800, 0x00083, 0x0, "Hitachi Tiny 64 Core PC Floppy"},
915 {HPHW_FIO, 0x801, 0x00083, 0x0, "Hitachi Tiny 80 Core PC Floppy"},
916 {HPHW_FIO, 0x015, 0x00084, 0x0, "KittyHawk GSY Core PS/2 Port"},
917 {HPHW_FIO, 0x016, 0x00084, 0x0, "Gecko Core PS/2 Port"},
918 {HPHW_FIO, 0x018, 0x00084, 0x0, "Gecko Optional PS/2 Port"},
919 {HPHW_FIO, 0x01A, 0x00084, 0x0, "Anole 64 Core PS/2 Port"},
920 {HPHW_FIO, 0x01B, 0x00084, 0x0, "Anole 100 Core PS/2 Port"},
921 {HPHW_FIO, 0x01C, 0x00084, 0x0, "Gecko 80 Core PS/2 Port"},
922 {HPHW_FIO, 0x01D, 0x00084, 0x0, "Gecko 100 Core PS/2 Port"},
923 {HPHW_FIO, 0x01F, 0x00084, 0x0, "SkyHawk 100/120 Core PS/2 Port"},
924 {HPHW_FIO, 0x027, 0x00084, 0x0, "Piranha 100 Core PS/2 Port"},
925 {HPHW_FIO, 0x028, 0x00084, 0x0, "Mirage Jr Core PS/2 Port"},
926 {HPHW_FIO, 0x029, 0x00084, 0x0, "Mirage Core PS/2 Port"},
927 {HPHW_FIO, 0x02A, 0x00084, 0x0, "Electra Core PS/2 Port"},
928 {HPHW_FIO, 0x02B, 0x00084, 0x0, "Mirage 80 Core PS/2 Port"},
929 {HPHW_FIO, 0x02C, 0x00084, 0x0, "Mirage 100+ Core PS/2 Port"},
930 {HPHW_FIO, 0x02E, 0x00084, 0x0, "UL 350 Core PS/2 Port"},
931 {HPHW_FIO, 0x02F, 0x00084, 0x0, "UL 550 Core PS/2 Port"},
932 {HPHW_FIO, 0x032, 0x00084, 0x0, "Raven T' Core PS/2 Port"},
933 {HPHW_FIO, 0x033, 0x00084, 0x0, "Anole T Core PS/2 Port"},
934 {HPHW_FIO, 0x034, 0x00084, 0x0, "SAIC L-80 Core PS/2 Port"},
935 {HPHW_FIO, 0x035, 0x00084, 0x0, "PCX-L2 712/132 Core PS/2 Port"},
936 {HPHW_FIO, 0x036, 0x00084, 0x0, "PCX-L2 712/160 Core PS/2 Port"},
937 {HPHW_FIO, 0x03B, 0x00084, 0x0, "Raven U/L2 Core PS/2 Port"},
938 {HPHW_FIO, 0x03C, 0x00084, 0x0, "Merlin 132 Core PS/2 Port"},
939 {HPHW_FIO, 0x03D, 0x00084, 0x0, "Merlin 160 Core PS/2 Port"},
940 {HPHW_FIO, 0x03E, 0x00084, 0x0, "Merlin+ 132 Core PS/2 Port"},
941 {HPHW_FIO, 0x03F, 0x00084, 0x0, "Merlin+ 180 Core PS/2 Port"},
942 {HPHW_FIO, 0x044, 0x00084, 0x0, "Mohawk Core PS/2 Port"},
943 {HPHW_FIO, 0x045, 0x00084, 0x0, "Rocky1 Core PS/2 Port"},
944 {HPHW_FIO, 0x046, 0x00084, 0x0, "Rocky2 120 Core PS/2 Port"},
945 {HPHW_FIO, 0x047, 0x00084, 0x0, "Rocky2 150 Core PS/2 Port"},
946 {HPHW_FIO, 0x048, 0x00084, 0x0, "Rocky2 120 Dino PS/2 Port"},
947 {HPHW_FIO, 0x049, 0x00084, 0x0, "Rocky2 150 Dino PS/2 Port"},
948 {HPHW_FIO, 0x04B, 0x00084, 0x0, "Anole L2 132 Core PS/2 Port"},
949 {HPHW_FIO, 0x04D, 0x00084, 0x0, "Anole L2 165 Core PS/2 Port"},
950 {HPHW_FIO, 0x04E, 0x00084, 0x0, "Kiji L2 132 Core PS/2 Port"},
951 {HPHW_FIO, 0x050, 0x00084, 0x0, "Merlin Jr 132 Core PS/2 Port"},
952 {HPHW_FIO, 0x051, 0x00084, 0x0, "Firehawk Core PS/2 Port"},
953 {HPHW_FIO, 0x056, 0x00084, 0x0, "Raven+ w SE FWSCSI Core PS/2 Port"},
954 {HPHW_FIO, 0x057, 0x00084, 0x0, "Raven+ w Diff FWSCSI Core PS/2 Port"},
955 {HPHW_FIO, 0x058, 0x00084, 0x0, "FireHawk 200 Core PS/2 Port"},
956 {HPHW_FIO, 0x05C, 0x00084, 0x0, "SummitHawk 230 Core PS/2 Port"},
957 {HPHW_FIO, 0x800, 0x00084, 0x0, "Hitachi Tiny 64 Core PS/2 Port"},
958 {HPHW_FIO, 0x801, 0x00084, 0x0, "Hitachi Tiny 80 Core PS/2 Port"},
959 {HPHW_FIO, 0x004, 0x00085, 0x0, "Solo GSC Optional Graphics"},
960 {HPHW_FIO, 0x005, 0x00085, 0x0, "Duet GSC Optional Graphics"},
961 {HPHW_FIO, 0x008, 0x00085, 0x0, "Anole Artist Optional Graphics"},
962 {HPHW_FIO, 0x010, 0x00085, 0x0, "Mirage 80 GSC Builtin Graphics"},
963 {HPHW_FIO, 0x011, 0x00085, 0x0, "Mirage 100+ GSC Builtin Graphics"},
964 {HPHW_FIO, 0x012, 0x00085, 0x0, "Mirage Jr GSC Builtin Graphics"},
965 {HPHW_FIO, 0x013, 0x00085, 0x0, "Mirage GSC Builtin Graphics"},
966 {HPHW_FIO, 0x014, 0x00085, 0x0, "Electra GSC Builtin Graphics"},
967 {HPHW_FIO, 0x016, 0x00085, 0x0, "Gecko GSC Core Graphics"},
968 {HPHW_FIO, 0x017, 0x00085, 0x0, "Gecko GSC Optional Graphics"},
969 {HPHW_FIO, 0x01A, 0x00085, 0x0, "Anole 64 Artist Builtin Graphics"},
970 {HPHW_FIO, 0x01B, 0x00085, 0x0, "Anole 100 Artist Builtin Graphics"},
971 {HPHW_FIO, 0x01C, 0x00085, 0x0, "Gecko 80 GSC Core Graphics"},
972 {HPHW_FIO, 0x01D, 0x00085, 0x0, "Gecko 100 GSC Core Graphics"},
973 {HPHW_FIO, 0x032, 0x00085, 0x0, "Raven T' GSC Core Graphics"},
974 {HPHW_FIO, 0x033, 0x00085, 0x0, "Anole T Artist Builtin Graphics"},
975 {HPHW_FIO, 0x034, 0x00085, 0x0, "SAIC L-80 GSC Core Graphics"},
976 {HPHW_FIO, 0x035, 0x00085, 0x0, "PCX-L2 712/132 Core Graphics"},
977 {HPHW_FIO, 0x036, 0x00085, 0x0, "PCX-L2 712/160 Core Graphics"},
978 {HPHW_FIO, 0x03B, 0x00085, 0x0, "Raven U/L2 Core Graphics"},
979 {HPHW_FIO, 0x03C, 0x00085, 0x0, "Merlin 132 Core Graphics"},
980 {HPHW_FIO, 0x03D, 0x00085, 0x0, "Merlin 160 Core Graphics"},
981 {HPHW_FIO, 0x03E, 0x00085, 0x0, "Merlin+ 132 Core Graphics"},
982 {HPHW_FIO, 0x03F, 0x00085, 0x0, "Merlin+ 180 Core Graphics"},
983 {HPHW_FIO, 0x045, 0x00085, 0x0, "Rocky1 Core Graphics"},
984 {HPHW_FIO, 0x046, 0x00085, 0x0, "Rocky2 120 Core Graphics"},
985 {HPHW_FIO, 0x047, 0x00085, 0x0, "Rocky2 150 Core Graphics"},
986 {HPHW_FIO, 0x04B, 0x00085, 0x0, "Anole L2 132 Core Graphics"},
987 {HPHW_FIO, 0x04D, 0x00085, 0x0, "Anole L2 165 Core Graphics"},
988 {HPHW_FIO, 0x04E, 0x00085, 0x0, "Kiji L2 132 Core Graphics"},
989 {HPHW_FIO, 0x050, 0x00085, 0x0, "Merlin Jr 132 Core Graphics"},
990 {HPHW_FIO, 0x056, 0x00085, 0x0, "Raven+ w SE FWSCSI Core Graphics"},
991 {HPHW_FIO, 0x057, 0x00085, 0x0, "Raven+ w Diff FWSCSI Core Graphics"},
992 {HPHW_FIO, 0x800, 0x00085, 0x0, "Hitachi Tiny 64 Core Graphics"},
993 {HPHW_FIO, 0x801, 0x00085, 0x0, "Hitachi Tiny 80 Core Graphics"},
994 {HPHW_FIO, 0x004, 0x00086, 0x0, "GSC IBM Token Ring"},
995 {HPHW_FIO, 0x015, 0x00087, 0x0, "Gecko Optional ISDN"},
996 {HPHW_FIO, 0x016, 0x00087, 0x0, "Gecko Core ISDN"},
997 {HPHW_FIO, 0x01C, 0x00087, 0x0, "Gecko 80 Core ISDN"},
998 {HPHW_FIO, 0x01D, 0x00087, 0x0, "Gecko 100 Core ISDN"},
999 {HPHW_FIO, 0x010, 0x00088, 0x0, "Pace VME Networking"},
1000 {HPHW_FIO, 0x011, 0x00088, 0x0, "Sidewinder VME Networking"},
1001 {HPHW_FIO, 0x01A, 0x00088, 0x0, "Anole 64 VME Networking"},
1002 {HPHW_FIO, 0x01B, 0x00088, 0x0, "Anole 100 VME Networking"},
1003 {HPHW_FIO, 0x024, 0x00088, 0x0, "Fast Pace VME Networking"},
1004 {HPHW_FIO, 0x034, 0x00088, 0x0, "Anole T VME Networking"},
1005 {HPHW_FIO, 0x04A, 0x00088, 0x0, "Anole L2 132 VME Networking"},
1006 {HPHW_FIO, 0x04C, 0x00088, 0x0, "Anole L2 165 VME Networking"},
1007 {HPHW_FIO, 0x011, 0x0008A, 0x0, "WB-96 Core LAN (802.3)"},
1008 {HPHW_FIO, 0x012, 0x0008A, 0x0, "Orville Core LAN (802.3)"},
1009 {HPHW_FIO, 0x013, 0x0008A, 0x0, "Wilbur Core LAN (802.3)"},
1010 {HPHW_FIO, 0x014, 0x0008A, 0x0, "WB-80 Core LAN (802.3)"},
1011 {HPHW_FIO, 0x015, 0x0008A, 0x0, "KittyHawk GSY Core LAN (802.3)"},
1012 {HPHW_FIO, 0x016, 0x0008A, 0x0, "Gecko Core LAN (802.3)"},
1013 {HPHW_FIO, 0x018, 0x0008A, 0x0, "Gecko Optional LAN (802.3)"},
1014 {HPHW_FIO, 0x01A, 0x0008A, 0x0, "Anole 64 Core LAN (802.3)"},
1015 {HPHW_FIO, 0x01B, 0x0008A, 0x0, "Anole 100 Core LAN (802.3)"},
1016 {HPHW_FIO, 0x01C, 0x0008A, 0x0, "Gecko 80 Core LAN (802.3)"},
1017 {HPHW_FIO, 0x01D, 0x0008A, 0x0, "Gecko 100 Core LAN (802.3)"},
1018 {HPHW_FIO, 0x01F, 0x0008A, 0x0, "SkyHawk 100/120 Core LAN (802.3)"},
1019 {HPHW_FIO, 0x027, 0x0008A, 0x0, "Piranha 100 Core LAN (802.3)"},
1020 {HPHW_FIO, 0x028, 0x0008A, 0x0, "Mirage Jr Core LAN (802.3)"},
1021 {HPHW_FIO, 0x029, 0x0008A, 0x0, "Mirage Core LAN (802.3)"},
1022 {HPHW_FIO, 0x02A, 0x0008A, 0x0, "Electra Core LAN (802.3)"},
1023 {HPHW_FIO, 0x02B, 0x0008A, 0x0, "Mirage 80 Core LAN (802.3)"},
1024 {HPHW_FIO, 0x02C, 0x0008A, 0x0, "Mirage 100+ Core LAN (802.3)"},
1025 {HPHW_FIO, 0x02E, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"},
1026 {HPHW_FIO, 0x02F, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"},
1027 {HPHW_FIO, 0x032, 0x0008A, 0x0, "Raven T' Core LAN (802.3)"},
1028 {HPHW_FIO, 0x033, 0x0008A, 0x0, "Anole T Core LAN (802.3)"},
1029 {HPHW_FIO, 0x034, 0x0008A, 0x0, "SAIC L-80 Core LAN (802.3)"},
1030 {HPHW_FIO, 0x035, 0x0008A, 0x0, "PCX-L2 712/132 Core LAN (802.3)"},
1031 {HPHW_FIO, 0x036, 0x0008A, 0x0, "PCX-L2 712/160 Core LAN (802.3)"},
1032 {HPHW_FIO, 0x03B, 0x0008A, 0x0, "Raven U/L2 Core LAN (802.3)"},
1033 {HPHW_FIO, 0x03C, 0x0008A, 0x0, "Merlin 132 Core LAN (802.3)"},
1034 {HPHW_FIO, 0x03D, 0x0008A, 0x0, "Merlin 160 Core LAN (802.3)"},
1035 {HPHW_FIO, 0x044, 0x0008A, 0x0, "Mohawk Core LAN (802.3)"},
1036 {HPHW_FIO, 0x045, 0x0008A, 0x0, "Rocky1 Core LAN (802.3)"},
1037 {HPHW_FIO, 0x046, 0x0008A, 0x0, "Rocky2 120 Core LAN (802.3)"},
1038 {HPHW_FIO, 0x047, 0x0008A, 0x0, "Rocky2 150 Core LAN (802.3)"},
1039 {HPHW_FIO, 0x04B, 0x0008A, 0x0, "Anole L2 132 Core LAN (802.3)"},
1040 {HPHW_FIO, 0x04D, 0x0008A, 0x0, "Anole L2 165 Core LAN (802.3)"},
1041 {HPHW_FIO, 0x04E, 0x0008A, 0x0, "Kiji L2 132 Core LAN (802.3)"},
1042 {HPHW_FIO, 0x050, 0x0008A, 0x0, "Merlin Jr 132 Core LAN (802.3)"},
1043 {HPHW_FIO, 0x058, 0x0008A, 0x0, "FireHawk 200 Core LAN (802.3)"},
1044 {HPHW_FIO, 0x800, 0x0008A, 0x0, "Hitachi Tiny 64 Core LAN (802.3)"},
1045 {HPHW_FIO, 0x801, 0x0008A, 0x0, "Hitachi Tiny 80 Core LAN (802.3)"},
1046 {HPHW_FIO, 0x004, 0x0008C, 0x0, "SkyHawk 100/120 Wax RS-232"},
1047 {HPHW_FIO, 0x005, 0x0008C, 0x0, "SAIC L-80 Wax RS-232"},
1048 {HPHW_FIO, 0x006, 0x0008C, 0x0, "Raven U/L2 Dino RS-232"},
1049 {HPHW_FIO, 0x007, 0x0008C, 0x0, "Dino RS-232"},
1050 {HPHW_FIO, 0x008, 0x0008C, 0x0, "Merlin 132 Dino RS-232"},
1051 {HPHW_FIO, 0x009, 0x0008C, 0x0, "Merlin 160 Dino RS-232"},
1052 {HPHW_FIO, 0x00A, 0x0008C, 0x0, "Merlin Jr 132 Dino RS-232"},
1053 {HPHW_FIO, 0x010, 0x0008C, 0x0, "Mirage 80 Wax RS-232"},
1054 {HPHW_FIO, 0x011, 0x0008C, 0x0, "Mirage 100+ Wax RS-232"},
1055 {HPHW_FIO, 0x012, 0x0008C, 0x0, "Mirage Jr Wax RS-232"},
1056 {HPHW_FIO, 0x013, 0x0008C, 0x0, "Mirage Wax RS-232"},
1057 {HPHW_FIO, 0x014, 0x0008C, 0x0, "Electra Wax RS-232"},
1058 {HPHW_FIO, 0x015, 0x0008C, 0x0, "KittyHawk GSY Core RS-232"},
1059 {HPHW_FIO, 0x016, 0x0008C, 0x0, "Gecko Core RS-232"},
1060 {HPHW_FIO, 0x017, 0x0008C, 0x0, "Raven Backplane RS-232"},
1061 {HPHW_FIO, 0x018, 0x0008C, 0x0, "Gecko Optional RS-232"},
1062 {HPHW_FIO, 0x019, 0x0008C, 0x0, "Merlin+ 180 Dino RS-232"},
1063 {HPHW_FIO, 0x01A, 0x0008C, 0x0, "Anole 64 Core RS-232"},
1064 {HPHW_FIO, 0x01B, 0x0008C, 0x0, "Anole 100 Core RS-232"},
1065 {HPHW_FIO, 0x01C, 0x0008C, 0x0, "Gecko 80 Core RS-232"},
1066 {HPHW_FIO, 0x01D, 0x0008C, 0x0, "Gecko 100 Core RS-232"},
1067 {HPHW_FIO, 0x01E, 0x0008C, 0x0, "Raven T' Wax RS-232"},
1068 {HPHW_FIO, 0x01F, 0x0008C, 0x0, "SkyHawk 100/120 Core RS-232"},
1069 {HPHW_FIO, 0x020, 0x0008C, 0x0, "Anole 64 Timi RS-232"},
1070 {HPHW_FIO, 0x021, 0x0008C, 0x0, "Anole 100 Timi RS-232"},
1071 {HPHW_FIO, 0x022, 0x0008C, 0x0, "Merlin+ 132 Dino RS-232"},
1072 {HPHW_FIO, 0x023, 0x0008C, 0x0, "Rocky1 Wax RS-232"},
1073 {HPHW_FIO, 0x025, 0x0008C, 0x0, "Armyknife Optional RS-232"},
1074 {HPHW_FIO, 0x026, 0x0008C, 0x0, "Piranha 100 Wax RS-232"},
1075 {HPHW_FIO, 0x027, 0x0008C, 0x0, "Piranha 100 Core RS-232"},
1076 {HPHW_FIO, 0x028, 0x0008C, 0x0, "Mirage Jr Core RS-232"},
1077 {HPHW_FIO, 0x029, 0x0008C, 0x0, "Mirage Core RS-232"},
1078 {HPHW_FIO, 0x02A, 0x0008C, 0x0, "Electra Core RS-232"},
1079 {HPHW_FIO, 0x02B, 0x0008C, 0x0, "Mirage 80 Core RS-232"},
1080 {HPHW_FIO, 0x02C, 0x0008C, 0x0, "Mirage 100+ Core RS-232"},
1081 {HPHW_FIO, 0x02E, 0x0008C, 0x0, "UL 350 Lasi Core RS-232"},
1082 {HPHW_FIO, 0x02F, 0x0008C, 0x0, "UL 550 Lasi Core RS-232"},
1083 {HPHW_FIO, 0x030, 0x0008C, 0x0, "UL 350 Wax Core RS-232"},
1084 {HPHW_FIO, 0x031, 0x0008C, 0x0, "UL 550 Wax Core RS-232"},
1085 {HPHW_FIO, 0x032, 0x0008C, 0x0, "Raven T' Lasi Core RS-232"},
1086 {HPHW_FIO, 0x033, 0x0008C, 0x0, "Anole T Core RS-232"},
1087 {HPHW_FIO, 0x034, 0x0008C, 0x0, "SAIC L-80 Core RS-232"},
1088 {HPHW_FIO, 0x035, 0x0008C, 0x0, "PCX-L2 712/132 Core RS-232"},
1089 {HPHW_FIO, 0x036, 0x0008C, 0x0, "PCX-L2 712/160 Core RS-232"},
1090 {HPHW_FIO, 0x03A, 0x0008C, 0x0, "Merlin+ Wax RS-232"},
1091 {HPHW_FIO, 0x03B, 0x0008C, 0x0, "Raven U/L2 Core RS-232"},
1092 {HPHW_FIO, 0x03C, 0x0008C, 0x0, "Merlin 132 Core RS-232"},
1093 {HPHW_FIO, 0x03D, 0x0008C, 0x0, "Merlin 160 Core RS-232"},
1094 {HPHW_FIO, 0x03E, 0x0008C, 0x0, "Merlin+ 132 Core RS-232"},
1095 {HPHW_FIO, 0x03F, 0x0008C, 0x0, "Merlin+ 180 Core RS-232"},
1096 {HPHW_FIO, 0x040, 0x0008C, 0x0, "Merlin 132 Wax RS-232"},
1097 {HPHW_FIO, 0x041, 0x0008C, 0x0, "Merlin 160 Wax RS-232"},
1098 {HPHW_FIO, 0x043, 0x0008C, 0x0, "Merlin 132/160 Wax RS-232"},
1099 {HPHW_FIO, 0x044, 0x0008C, 0x0, "Mohawk Core RS-232"},
1100 {HPHW_FIO, 0x045, 0x0008C, 0x0, "Rocky1 Core RS-232"},
1101 {HPHW_FIO, 0x046, 0x0008C, 0x0, "Rocky2 120 Core RS-232"},
1102 {HPHW_FIO, 0x047, 0x0008C, 0x0, "Rocky2 150 Core RS-232"},
1103 {HPHW_FIO, 0x048, 0x0008C, 0x0, "Rocky2 120 Dino RS-232"},
1104 {HPHW_FIO, 0x049, 0x0008C, 0x0, "Rocky2 150 Dino RS-232"},
1105 {HPHW_FIO, 0x04A, 0x0008C, 0x0, "Anole L2 132 TIMI RS-232"},
1106 {HPHW_FIO, 0x04B, 0x0008C, 0x0, "Anole L2 l32 Core RS-232"},
1107 {HPHW_FIO, 0x04C, 0x0008D, 0x0, "Anole L2 165 TIMI RS-232"},
1108 {HPHW_FIO, 0x04D, 0x0008C, 0x0, "Anole L2 165 Core RS-232"},
1109 {HPHW_FIO, 0x04E, 0x0008C, 0x0, "Kiji L2 132 Core RS-232"},
1110 {HPHW_FIO, 0x04F, 0x0008C, 0x0, "Kiji L2 132 Dino RS-232"},
1111 {HPHW_FIO, 0x050, 0x0008C, 0x0, "Merlin Jr 132 Core RS-232"},
1112 {HPHW_FIO, 0x051, 0x0008C, 0x0, "Firehawk Core RS-232"},
1113 {HPHW_FIO, 0x052, 0x0008C, 0x0, "Raven+ Hi Power Backplane w EISA RS-232"},
1114 {HPHW_FIO, 0x053, 0x0008C, 0x0, "Raven+ Hi Power Backplane w/o EISA RS-232"},
1115 {HPHW_FIO, 0x054, 0x0008C, 0x0, "Raven+ Lo Power Backplane w EISA RS-232"},
1116 {HPHW_FIO, 0x055, 0x0008C, 0x0, "Raven+ Lo Power Backplane w/o EISA RS-232"},
1117 {HPHW_FIO, 0x056, 0x0008C, 0x0, "Raven+ w SE FWSCSI Core RS-232"},
1118 {HPHW_FIO, 0x057, 0x0008C, 0x0, "Raven+ w Diff FWSCSI Core RS-232"},
1119 {HPHW_FIO, 0x058, 0x0008C, 0x0, "FireHawk 200 Core RS-232"},
1120 {HPHW_FIO, 0x059, 0x0008C, 0x0, "FireHawk 200 Wax RS-232"},
1121 {HPHW_FIO, 0x05A, 0x0008C, 0x0, "Raven+ L2 Backplane w EISA RS-232"},
1122 {HPHW_FIO, 0x05B, 0x0008C, 0x0, "Raven+ L2 Backplane w/o EISA RS-232"},
1123 {HPHW_FIO, 0x05D, 0x0008C, 0x0, "SummitHawk Dino RS-232"},
1124 {HPHW_FIO, 0x05E, 0x0008C, 0x0, "Staccato 132 Core LAN RS-232"},
1125 {HPHW_FIO, 0x05F, 0x0008C, 0x0, "Staccato 180 Core LAN RS-232"},
1126 {HPHW_FIO, 0x800, 0x0008C, 0x0, "Hitachi Tiny 64 Core RS-232"},
1127 {HPHW_FIO, 0x801, 0x0008C, 0x0, "Hitachi Tiny 80 Core RS-232"},
1128 {HPHW_FIO, 0x015, 0x0008D, 0x0, "Gecko Optional RJ-16"},
1129 {HPHW_FIO, 0x016, 0x0008D, 0x0, "Gecko Core RJ-16"},
1130 {HPHW_FIO, 0x01C, 0x0008D, 0x0, "Gecko 80 Core RJ-16"},
1131 {HPHW_FIO, 0x01D, 0x0008D, 0x0, "Gecko 100 Core RJ-16"},
1132 {HPHW_FIO, 0x004, 0x0008F, 0x0, "Anole Boot Rom"},
1133 {HPHW_FIO, 0x005, 0x0008F, 0x0, "Rocky1 Boot Rom"},
1134 {HPHW_FIO, 0x006, 0x0008F, 0x0, "Rocky2 120 Boot Rom"},
1135 {HPHW_FIO, 0x007, 0x0008F, 0x0, "Rocky2 150 Boot Rom"},
1136 {HPHW_FIO, 0x01B, 0x0008F, 0x0, "Anole 100 Boot Rom"},
1137 {HPHW_FIO, 0x006, 0x00096, 0x0, "Raven U/L2 Dino PS/2 Port"},
1138 {HPHW_FIO, 0x007, 0x00096, 0x0, "Dino PS/2 Port"},
1139 {HPHW_FIO, 0x008, 0x00096, 0x0, "Merlin 132 Dino PS/2 Port"},
1140 {HPHW_FIO, 0x009, 0x00096, 0x0, "Merlin 160 Dino PS/2 Port"},
1141 {HPHW_FIO, 0x00A, 0x00096, 0x0, "Merlin Jr 132 Dino PS/2 Port"},
1142 {HPHW_FIO, 0x019, 0x00096, 0x0, "Merlin+ 180 Dino PS/2 Port"},
1143 {HPHW_FIO, 0x022, 0x00096, 0x0, "Merlin+ 132 Dino PS/2 Port"},
1144 {HPHW_FIO, 0x004, 0x00097, 0x0, "Cascade EISA 100VG LAN"},
1145 {HPHW_FIO, 0x023, 0x00099, 0x0, "Rocky1 Wax HPIB"},
1146 {HPHW_FIO, 0x048, 0x00099, 0x0, "Rocky2 120 Clark/Dino HPIB"},
1147 {HPHW_FIO, 0x049, 0x00099, 0x0, "Rocky2 150 Clark/Dino HPIB"},
1148 {HPHW_FIO, 0x004, 0x000A1, 0x0, "SPP2000 Console TTY"},
1149 {HPHW_FIO, 0x004, 0x000A2, 0x0, "Forte Core PCI 10/100BT LAN"},
1150 {HPHW_FIO, 0x005, 0x000A2, 0x0, "AllegroLow PCI 10/100BT LAN"},
1151 {HPHW_FIO, 0x006, 0x000A2, 0x0, "AllegroHIgh Core PCI 10/100BT LAN"},
1152 {HPHW_FIO, 0x007, 0x000A2, 0x0, "PCI Plug-in LAN"},
1153 {HPHW_FIO, 0x00A, 0x000A2, 0x0, "Lego 360 Core PCI 10/100BT LAN"},
1154 {HPHW_FIO, 0x03E, 0x000A2, 0x0, "Merlin+ 132 Core PCI LAN"},
1155 {HPHW_FIO, 0x03F, 0x000A2, 0x0, "Merlin+ 180 Core PCI LAN"},
1156 {HPHW_FIO, 0x056, 0x000A2, 0x0, "Raven+ w SE FWSCSI Core PCI LAN"},
1157 {HPHW_FIO, 0x057, 0x000A2, 0x0, "Raven+ w Diff FWSCSI Core PCI LAN"},
1158 {HPHW_FIO, 0x05E, 0x000A2, 0x0, "Staccato 132 PCI LAN"},
1159 {HPHW_FIO, 0x05F, 0x000A2, 0x0, "Staccato 180 PCI LAN"},
1160 {HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI LVD Ultra2 SCSI"},
1161 {HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI SE UltraSCSI"},
1162 {HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI IDE/ATAPI CD-ROM"},
1163 {HPHW_FIO, 0x005, 0x000A3, 0x0, "AllegroLow Core PCI LVD Ultra2 SCSI"},
1164 {HPHW_FIO, 0x005, 0x000A3, 0x0, "AllegroLow Core PCI IDE/ATAPI CD-ROM"},
1165 {HPHW_FIO, 0x006, 0x000A3, 0x0, "AllegroHigh Core PCI LVD Ultra2 SCSI"},
1166 {HPHW_FIO, 0x006, 0x000A3, 0x0, "AllegroHigh Core PCI IDE/ATAPI CD-ROM"},
1167 {HPHW_FIO, 0x007, 0x000A3, 0x0, "PCI Plug-in Disk"},
1168 {HPHW_FIO, 0x008, 0x000A3, 0x0, "A5158A S FC Tachlite HBA"},
1169 {HPHW_FIO, 0x009, 0x000A3, 0x0, "A5157A D FC HBA"},
1170 {HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI LVD Ultra2 SCSI"},
1171 {HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI NSE UltraSCSI"},
1172 {HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI WSE UltraSCSI"},
1173 {HPHW_FIO, 0x00A, 0x000A3, 0x0, "Lego 360 Core PCI IDE/ATAPI CD-ROM"},
1174 {HPHW_FIO, 0x03E, 0x000A3, 0x0, "Merlin+ 132 Core SE FWSCSI PCI Disk"},
1175 {HPHW_FIO, 0x03F, 0x000A3, 0x0, "Merlin+ 180 Core SE FWSCSI PCI Disk"},
1176 {HPHW_FIO, 0x056, 0x000A3, 0x0, "Raven+ w SE FWSCSI Core PCI Disk"},
1177 {HPHW_FIO, 0x057, 0x000A3, 0x0, "Raven+ w Diff FWSCSI Core PCI Disk"},
1178 {HPHW_FIO, 0x004, 0x000A4, 0x0, "SPP2000 Core BA"},
1179 {HPHW_FIO, 0x004, 0x000A6, 0x0, "Sonic Ethernet 802.3 Card"},
1180 {HPHW_FIO, 0x004, 0x000A9, 0x00, "Forte Core PCI SuperIO RS-232"},
1181 {HPHW_FIO, 0x004, 0x000A9, 0x00, "Forte Core PCI USB KB"},
1182 {HPHW_FIO, 0x005, 0x000A9, 0x00, "AllegroLow Core PCI SuperIO RS-232"},
1183 {HPHW_FIO, 0x005, 0x000A9, 0x00, "AllegroLow Core PCI USB KB"},
1184 {HPHW_FIO, 0x006, 0x000A9, 0x00, "AllegroHigh Core PCI SuperIO RS-232"},
1185 {HPHW_FIO, 0x006, 0x000A9, 0x00, "AllegroHigh Core PCI USB KB"},
1186 {HPHW_FIO, 0x007, 0x000A9, 0x0, "Miscelaneous PCI Plug-in"},
1187 {HPHW_FIO, 0x00A, 0x000A9, 0x0, "Lego 360 Core PCI SuperIO RS-232"},
1188 {HPHW_FIO, 0x00A, 0x000A9, 0x0, "Lego 360 Core PCI USB KB"},
1189 {HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"},
1190 {HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"},
1191 {HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"},
1192 {HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"},
1193 {HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"},
1194 {HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"},
1195 {HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"},
1196 {HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"},
1197 {HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"},
1198 {HPHW_IOA, 0x880, 0x0000C, 0x10, "Pluto BC McKinley Port"},
1199 {HPHW_MEMORY, 0x002, 0x00008, 0x00, "MID_BUS"},
1200 {HPHW_MEMORY, 0x063, 0x00009, 0x00, "712/132 L2 Upgrade"},
1201 {HPHW_MEMORY, 0x064, 0x00009, 0x00, "712/160 L2 Upgrade"},
1202 {HPHW_MEMORY, 0x065, 0x00009, 0x00, "715/132 L2 Upgrade"},
1203 {HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"},
1204 {HPHW_MEMORY, 0x0AF, 0x00009, 0x00, "Everest Mako Memory"},
1205 {HPHW_OTHER, 0x004, 0x00030, 0x00, "Master"},
1206 {HPHW_OTHER, 0x004, 0x00034, 0x00, "Slave"},
1207 {HPHW_OTHER, 0x004, 0x00038, 0x00, "EDU"},
1208 {HPHW_OTHER, 0x004, 0x00049, 0x00, "LGB Control"},
1209 {HPHW_MC, 0x004, 0x000C0, 0x00, "BMC IPMI Mgmt Ctlr"},
1210 {HPHW_FAULTY, 0, } /* Special Marker for last entry */
1211};
1212
1213
1214static struct hp_cpu_type_mask {
1215 unsigned short model;
1216 unsigned short mask;
1217 enum cpu_type cpu;
1218} hp_cpu_type_mask_list[] __initdata = {
1219
1220 { 0x0000, 0x0ff0, pcx }, /* 0x0000 - 0x000f */
1221 { 0x0048, 0x0ff0, pcxl }, /* 0x0040 - 0x004f */
1222 { 0x0080, 0x0ff0, pcx }, /* 0x0080 - 0x008f */
1223 { 0x0100, 0x0ff0, pcx }, /* 0x0100 - 0x010f */
1224 { 0x0182, 0x0ffe, pcx }, /* 0x0182 - 0x0183 */
1225 { 0x0182, 0x0ffe, pcxt }, /* 0x0182 - 0x0183 */
1226 { 0x0184, 0x0fff, pcxu }, /* 0x0184 - 0x0184 */
1227 { 0x0200, 0x0ffe, pcxs }, /* 0x0200 - 0x0201 */
1228 { 0x0202, 0x0fff, pcxs }, /* 0x0202 - 0x0202 */
1229 { 0x0203, 0x0fff, pcxt }, /* 0x0203 - 0x0203 */
1230 { 0x0204, 0x0ffc, pcxt }, /* 0x0204 - 0x0207 */
1231 { 0x0280, 0x0ffc, pcxs }, /* 0x0280 - 0x0283 */
1232 { 0x0284, 0x0ffc, pcxt }, /* 0x0284 - 0x0287 */
1233 { 0x0288, 0x0fff, pcxt }, /* 0x0288 - 0x0288 */
1234 { 0x0300, 0x0ffc, pcxs }, /* 0x0300 - 0x0303 */
1235 { 0x0310, 0x0ff0, pcxt }, /* 0x0310 - 0x031f */
1236 { 0x0320, 0x0ff0, pcxt }, /* 0x0320 - 0x032f */
1237 { 0x0400, 0x0ff0, pcxt }, /* 0x0400 - 0x040f */
1238 { 0x0480, 0x0ff0, pcxl }, /* 0x0480 - 0x048f */
1239 { 0x0500, 0x0ff0, pcxl2 }, /* 0x0500 - 0x050f */
1240 { 0x0510, 0x0ff0, pcxl2 }, /* 0x0510 - 0x051f */
1241 { 0x0580, 0x0ff8, pcxt_ }, /* 0x0580 - 0x0587 */
1242 { 0x0588, 0x0ffc, pcxt_ }, /* 0x0588 - 0x058b */
1243 { 0x058c, 0x0ffe, pcxt_ }, /* 0x058c - 0x058d */
1244 { 0x058e, 0x0fff, pcxt_ }, /* 0x058e - 0x058e */
1245 { 0x058f, 0x0fff, pcxu }, /* 0x058f - 0x058f */
1246 { 0x0590, 0x0ffe, pcxu }, /* 0x0590 - 0x0591 */
1247 { 0x0592, 0x0fff, pcxt_ }, /* 0x0592 - 0x0592 */
1248 { 0x0593, 0x0fff, pcxu }, /* 0x0593 - 0x0593 */
1249 { 0x0594, 0x0ffc, pcxu }, /* 0x0594 - 0x0597 */
1250 { 0x0598, 0x0ffe, pcxu_ }, /* 0x0598 - 0x0599 */
1251 { 0x059a, 0x0ffe, pcxu }, /* 0x059a - 0x059b */
1252 { 0x059c, 0x0fff, pcxu }, /* 0x059c - 0x059c */
1253 { 0x059d, 0x0fff, pcxu_ }, /* 0x059d - 0x059d */
1254 { 0x059e, 0x0fff, pcxt_ }, /* 0x059e - 0x059e */
1255 { 0x059f, 0x0fff, pcxu }, /* 0x059f - 0x059f */
1256 { 0x05a0, 0x0ffe, pcxt_ }, /* 0x05a0 - 0x05a1 */
1257 { 0x05a2, 0x0ffe, pcxu }, /* 0x05a2 - 0x05a3 */
1258 { 0x05a4, 0x0ffc, pcxu }, /* 0x05a4 - 0x05a7 */
1259 { 0x05a8, 0x0ffc, pcxu }, /* 0x05a8 - 0x05ab */
1260 { 0x05ad, 0x0fff, pcxu_ }, /* 0x05ad - 0x05ad */
1261 { 0x05ae, 0x0ffe, pcxu_ }, /* 0x05ae - 0x05af */
1262 { 0x05b0, 0x0ffe, pcxu_ }, /* 0x05b0 - 0x05b1 */
1263 { 0x05b2, 0x0fff, pcxu_ }, /* 0x05b2 - 0x05b2 */
1264 { 0x05b3, 0x0fff, pcxu }, /* 0x05b3 - 0x05b3 */
1265 { 0x05b4, 0x0fff, pcxw }, /* 0x05b4 - 0x05b4 */
1266 { 0x05b5, 0x0fff, pcxu_ }, /* 0x05b5 - 0x05b5 */
1267 { 0x05b6, 0x0ffe, pcxu_ }, /* 0x05b6 - 0x05b7 */
1268 { 0x05b8, 0x0ffe, pcxu_ }, /* 0x05b8 - 0x05b9 */
1269 { 0x05ba, 0x0fff, pcxu_ }, /* 0x05ba - 0x05ba */
1270 { 0x05bb, 0x0fff, pcxw }, /* 0x05bb - 0x05bb */
1271 { 0x05bc, 0x0ffc, pcxw }, /* 0x05bc - 0x05bf */
1272 { 0x05c0, 0x0ffc, pcxw }, /* 0x05c0 - 0x05c3 */
1273 { 0x05c4, 0x0ffe, pcxw }, /* 0x05c4 - 0x05c5 */
1274 { 0x05c6, 0x0fff, pcxw }, /* 0x05c6 - 0x05c6 */
1275 { 0x05c7, 0x0fff, pcxw_ }, /* 0x05c7 - 0x05c7 */
1276 { 0x05c8, 0x0ffc, pcxw }, /* 0x05c8 - 0x05cb */
1277 { 0x05cc, 0x0ffe, pcxw }, /* 0x05cc - 0x05cd */
1278 { 0x05ce, 0x0ffe, pcxw_ }, /* 0x05ce - 0x05cf */
1279 { 0x05d0, 0x0ffc, pcxw_ }, /* 0x05d0 - 0x05d3 */
1280 { 0x05d4, 0x0ffe, pcxw_ }, /* 0x05d4 - 0x05d5 */
1281 { 0x05d6, 0x0fff, pcxw }, /* 0x05d6 - 0x05d6 */
1282 { 0x05d7, 0x0fff, pcxw_ }, /* 0x05d7 - 0x05d7 */
1283 { 0x05d8, 0x0ffc, pcxw_ }, /* 0x05d8 - 0x05db */
1284 { 0x05dc, 0x0ffe, pcxw2 }, /* 0x05dc - 0x05dd */
1285 { 0x05de, 0x0fff, pcxw_ }, /* 0x05de - 0x05de */
1286 { 0x05df, 0x0fff, pcxw2 }, /* 0x05df - 0x05df */
1287 { 0x05e0, 0x0ffc, pcxw2 }, /* 0x05e0 - 0x05e3 */
1288 { 0x05e4, 0x0fff, pcxw2 }, /* 0x05e4 - 0x05e4 */
1289 { 0x05e5, 0x0fff, pcxw_ }, /* 0x05e5 - 0x05e5 */
1290 { 0x05e6, 0x0ffe, pcxw2 }, /* 0x05e6 - 0x05e7 */
1291 { 0x05e8, 0x0ff8, pcxw2 }, /* 0x05e8 - 0x05ef */
1292 { 0x05f0, 0x0ff0, pcxw2 }, /* 0x05f0 - 0x05ff */
1293 { 0x0600, 0x0fe0, pcxl }, /* 0x0600 - 0x061f */
1294 { 0x0880, 0x0ff0, mako }, /* 0x0880 - 0x088f */
1295 { 0x0000, 0x0000, pcx } /* terminate table */
1296};
1297
1298char *cpu_name_version[][2] = {
1299 [pcx] = { "PA7000 (PCX)", "1.0" },
1300 [pcxs] = { "PA7000 (PCX-S)", "1.1a" },
1301 [pcxt] = { "PA7100 (PCX-T)", "1.1b" },
1302 [pcxt_] = { "PA7200 (PCX-T')", "1.1c" },
1303 [pcxl] = { "PA7100LC (PCX-L)", "1.1d" },
1304 [pcxl2] = { "PA7300LC (PCX-L2)", "1.1e" },
1305 [pcxu] = { "PA8000 (PCX-U)", "2.0" },
1306 [pcxu_] = { "PA8200 (PCX-U+)", "2.0" },
1307 [pcxw] = { "PA8500 (PCX-W)", "2.0" },
1308 [pcxw_] = { "PA8600 (PCX-W+)", "2.0" },
1309 [pcxw2] = { "PA8700 (PCX-W2)", "2.0" },
1310 [mako] = { "PA8800 (Mako)", "2.0" }
1311};
1312
1313const char * __init
1314parisc_hardware_description(struct parisc_device_id *id)
1315{
1316 struct hp_hardware *listptr;
1317
1318 for (listptr = hp_hardware_list; listptr->hw_type != HPHW_FAULTY; listptr++) {
1319 if ((listptr->hw_type == id->hw_type) &&
1320 (listptr->hversion == id->hversion) &&
1321 (listptr->sversion == id->sversion)){
1322 return listptr->name;
1323 }
1324 }
1325
1326 /*
1327 * ok, the above hardware table isn't complete, and we haven't found
1328 * our device in this table. So let's now try to find a generic name
1329 * to describe the given hardware...
1330 */
1331 switch (id->hw_type) {
1332 case HPHW_NPROC:
1333 return "Unknown machine";
1334
1335 case HPHW_A_DIRECT:
1336 switch (id->sversion) {
1337 case 0x0D: return "MUX port";
1338 case 0x0E: return "RS-232 port";
1339 }
1340 break;
1341
1342 case HPHW_MEMORY:
1343 return "Memory";
1344
1345 }
1346
1347 return "unknown device";
1348}
1349
1350
1351/* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */
1352enum cpu_type __init
1353parisc_get_cpu_type(unsigned long hversion)
1354{
1355 struct hp_cpu_type_mask *ptr;
1356 unsigned short model = ((unsigned short) (hversion)) >> 4;
1357
1358 for (ptr = hp_cpu_type_mask_list; 0 != ptr->mask; ptr++) {
1359 if (ptr->model == (model & ptr->mask))
1360 return ptr->cpu;
1361 }
1362 panic("could not identify CPU type\n");
1363
1364 return pcx; /* not reached: */
1365}
1366
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
new file mode 100644
index 000000000000..ddf7e914f15e
--- /dev/null
+++ b/arch/parisc/kernel/head.S
@@ -0,0 +1,386 @@
1/* This file is subject to the terms and conditions of the GNU General Public
2 * License. See the file "COPYING" in the main directory of this archive
3 * for more details.
4 *
5 * Copyright (C) 1999 by Helge Deller
6 * Copyright 1999 SuSE GmbH (Philipp Rumpf)
7 * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
8 * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
9 * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
10 * Copyright (C) 2004 Kyle McMartin <kyle@debian.org>
11 *
12 * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
13 */
14
15#include <linux/autoconf.h> /* for CONFIG_SMP */
16
17#include <asm/offsets.h>
18#include <asm/psw.h>
19#include <asm/pdc.h>
20
21#include <asm/assembly.h>
22#include <asm/pgtable.h>
23
24 .level LEVEL
25
26 .data
27
28 .export boot_args
29boot_args:
30 .word 0 /* arg0 */
31 .word 0 /* arg1 */
32 .word 0 /* arg2 */
33 .word 0 /* arg3 */
34
35 .text
36 .align 4
37 .import init_thread_union,data
38 .import fault_vector_20,code /* IVA parisc 2.0 32 bit */
39#ifndef __LP64__
40 .import fault_vector_11,code /* IVA parisc 1.1 32 bit */
41 .import $global$ /* forward declaration */
42#endif /*!LP64*/
43 .export stext
44 .export _stext,data /* Kernel want it this way! */
45_stext:
46stext:
47 .proc
48 .callinfo
49
50 /* Make sure sr4-sr7 are set to zero for the kernel address space */
51 mtsp %r0,%sr4
52 mtsp %r0,%sr5
53 mtsp %r0,%sr6
54 mtsp %r0,%sr7
55
56 /* Clear BSS (shouldn't the boot loader do this?) */
57
58 .import __bss_start,data
59 .import __bss_stop,data
60
61 load32 PA(__bss_start),%r3
62 load32 PA(__bss_stop),%r4
63$bss_loop:
64 cmpb,<<,n %r3,%r4,$bss_loop
65 stw,ma %r0,4(%r3)
66
67 /* Save away the arguments the boot loader passed in (32 bit args) */
68 load32 PA(boot_args),%r1
69 stw,ma %arg0,4(%r1)
70 stw,ma %arg1,4(%r1)
71 stw,ma %arg2,4(%r1)
72 stw,ma %arg3,4(%r1)
73
74 /* Initialize startup VM. Just map first 8/16 MB of memory */
75 load32 PA(swapper_pg_dir),%r4
76 mtctl %r4,%cr24 /* Initialize kernel root pointer */
77 mtctl %r4,%cr25 /* Initialize user root pointer */
78
79#ifdef __LP64__
80 /* Set pmd in pgd */
81 load32 PA(pmd0),%r5
82 shrd %r5,PxD_VALUE_SHIFT,%r3
83 ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
84 stw %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
85 ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4
86#else
87 /* 2-level page table, so pmd == pgd */
88 ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
89#endif
90
91 /* Fill in pmd with enough pte directories */
92 load32 PA(pg0),%r1
93 SHRREG %r1,PxD_VALUE_SHIFT,%r3
94 ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
95
96 ldi ASM_PT_INITIAL,%r1
97
981:
99 stw %r3,0(%r4)
100 ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
101 addib,> -1,%r1,1b
102#ifdef __LP64__
103 ldo ASM_PMD_ENTRY_SIZE(%r4),%r4
104#else
105 ldo ASM_PGD_ENTRY_SIZE(%r4),%r4
106#endif
107
108
109 /* Now initialize the PTEs themselves */
110 ldo _PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
111 load32 PA(pg0),%r1
112
113$pgt_fill_loop:
114 STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1)
115 ldo ASM_PAGE_SIZE(%r3),%r3
116 bb,>= %r3,31-KERNEL_INITIAL_ORDER,$pgt_fill_loop
117 nop
118
119 /* Load the return address...er...crash 'n burn */
120 copy %r0,%r2
121
122 /* And the RFI Target address too */
123 load32 start_kernel,%r11
124
125 /* And the initial task pointer */
126 load32 init_thread_union,%r6
127 mtctl %r6,%cr30
128
129 /* And the stack pointer too */
130 ldo THREAD_SZ_ALGN(%r6),%sp
131
132 /* And the interrupt stack */
133 load32 interrupt_stack,%r6
134 mtctl %r6,%cr31
135
136#ifdef CONFIG_SMP
137 /* Set the smp rendevous address into page zero.
138 ** It would be safer to do this in init_smp_config() but
139 ** it's just way easier to deal with here because
140 ** of 64-bit function ptrs and the address is local to this file.
141 */
142 load32 PA(smp_slave_stext),%r10
143 stw %r10,0x10(%r0) /* MEM_RENDEZ */
144 stw %r0,0x28(%r0) /* MEM_RENDEZ_HI - assume addr < 4GB */
145
146 /* FALLTHROUGH */
147 .procend
148
149 /*
150 ** Code Common to both Monarch and Slave processors.
151 ** Entry:
152 **
153 ** 1.1:
154 ** %r11 must contain RFI target address.
155 ** %r25/%r26 args to pass to target function
156 ** %r2 in case rfi target decides it didn't like something
157 **
158 ** 2.0w:
159 ** %r3 PDCE_PROC address
160 ** %r11 RFI target address
161 **
162 ** Caller must init: SR4-7, %sp, %r10, %cr24/25,
163 */
164common_stext:
165 .proc
166 .callinfo
167#else
168 /* Clear PDC entry point - we won't use it */
169 stw %r0,0x10(%r0) /* MEM_RENDEZ */
170 stw %r0,0x28(%r0) /* MEM_RENDEZ_HI */
171#endif /*CONFIG_SMP*/
172
173#ifdef __LP64__
174 tophys_r1 %sp
175
176 /* Save the rfi target address */
177 ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10
178 tophys_r1 %r10
179 std %r11, TASK_PT_GR11(%r10)
180 /* Switch to wide mode Superdome doesn't support narrow PDC
181 ** calls.
182 */
1831: mfia %rp /* clear upper part of pcoq */
184 ldo 2f-1b(%rp),%rp
185 depdi 0,31,32,%rp
186 bv (%rp)
187 ssm PSW_SM_W,%r0
188
189 /* Set Wide mode as the "Default" (eg for traps)
190 ** First trap occurs *right* after (or part of) rfi for slave CPUs.
191 ** Someday, palo might not do this for the Monarch either.
192 */
1932:
194#define MEM_PDC_LO 0x388
195#define MEM_PDC_HI 0x35C
196 ldw MEM_PDC_LO(%r0),%r3
197 ldw MEM_PDC_HI(%r0),%r6
198 depd %r6, 31, 32, %r3 /* move to upper word */
199
200 ldo PDC_PSW(%r0),%arg0 /* 21 */
201 ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
202 ldo PDC_PSW_WIDE_BIT(%r0),%arg2 /* 2 */
203 load32 PA(stext_pdc_ret), %rp
204 bv (%r3)
205 copy %r0,%arg3
206
207stext_pdc_ret:
208 /* restore rfi target address*/
209 ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10
210 tophys_r1 %r10
211 ldd TASK_PT_GR11(%r10), %r11
212 tovirt_r1 %sp
213#endif
214
215 /* PARANOID: clear user scratch/user space SR's */
216 mtsp %r0,%sr0
217 mtsp %r0,%sr1
218 mtsp %r0,%sr2
219 mtsp %r0,%sr3
220
221 /* Initialize Protection Registers */
222 mtctl %r0,%cr8
223 mtctl %r0,%cr9
224 mtctl %r0,%cr12
225 mtctl %r0,%cr13
226
227 /* Prepare to RFI! Man all the cannons! */
228
229 /* Initialize the global data pointer */
230 loadgp
231
232 /* Set up our interrupt table. HPMCs might not work after this!
233 *
234 * We need to install the correct iva for PA1.1 or PA2.0. The
235 * following short sequence of instructions can determine this
236 * (without being illegal on a PA1.1 machine).
237 */
238#ifndef __LP64__
239 ldi 32,%r10
240 mtctl %r10,%cr11
241 .level 2.0
242 mfctl,w %cr11,%r10
243 .level 1.1
244 comib,<>,n 0,%r10,$is_pa20
245 ldil L%PA(fault_vector_11),%r10
246 b $install_iva
247 ldo R%PA(fault_vector_11)(%r10),%r10
248
249$is_pa20:
250 .level LEVEL /* restore 1.1 || 2.0w */
251#endif /*!LP64*/
252 load32 PA(fault_vector_20),%r10
253
254$install_iva:
255 mtctl %r10,%cr14
256
257#ifdef __LP64__
258 b aligned_rfi
259 nop
260
261 .align 256
262aligned_rfi:
263 ssm 0,0
264 nop /* 1 */
265 nop /* 2 */
266 nop /* 3 */
267 nop /* 4 */
268 nop /* 5 */
269 nop /* 6 */
270 nop /* 7 */
271 nop /* 8 */
272#endif
273
274#ifdef __LP64__ /* move to psw.h? */
275#define PSW_BITS PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R
276#else
277#define PSW_BITS PSW_SM_Q
278#endif
279
280$rfi:
281 /* turn off troublesome PSW bits */
282 rsm PSW_BITS,%r0
283
284 /* kernel PSW:
285 * - no interruptions except HPMC and TOC (which are handled by PDC)
286 * - Q bit set (IODC / PDC interruptions)
287 * - big-endian
288 * - virtually mapped
289 */
290 load32 KERNEL_PSW,%r10
291 mtctl %r10,%ipsw
292
293 /* Set the space pointers for the post-RFI world
294 ** Clear the two-level IIA Space Queue, effectively setting
295 ** Kernel space.
296 */
297 mtctl %r0,%cr17 /* Clear IIASQ tail */
298 mtctl %r0,%cr17 /* Clear IIASQ head */
299
300 /* Load RFI target into PC queue */
301 mtctl %r11,%cr18 /* IIAOQ head */
302 ldo 4(%r11),%r11
303 mtctl %r11,%cr18 /* IIAOQ tail */
304
305 /* Jump to hyperspace */
306 rfi
307 nop
308
309 .procend
310
311#ifdef CONFIG_SMP
312
313 .import smp_init_current_idle_task,data
314 .import smp_callin,code
315
316#ifndef __LP64__
317smp_callin_rtn:
318 .proc
319 .callinfo
320 break 1,1 /* Break if returned from start_secondary */
321 nop
322 nop
323 .procend
324#endif /*!LP64*/
325
326/***************************************************************************
327* smp_slave_stext is executed by all non-monarch Processors when the Monarch
328* pokes the slave CPUs in smp.c:smp_boot_cpus().
329*
330* Once here, registers values are initialized in order to branch to virtual
331* mode. Once all available/eligible CPUs are in virtual mode, all are
332* released and start out by executing their own idle task.
333*****************************************************************************/
334smp_slave_stext:
335 .proc
336 .callinfo
337
338 /*
339 ** Initialize Space registers
340 */
341 mtsp %r0,%sr4
342 mtsp %r0,%sr5
343 mtsp %r0,%sr6
344 mtsp %r0,%sr7
345
346 /* Initialize the SP - monarch sets up smp_init_current_idle_task */
347 load32 PA(smp_init_current_idle_task),%sp
348 LDREG 0(%sp),%sp /* load task address */
349 tophys_r1 %sp
350 LDREG TASK_THREAD_INFO(%sp),%sp
351 mtctl %sp,%cr30 /* store in cr30 */
352 ldo THREAD_SZ_ALGN(%sp),%sp
353
354 /* point CPU to kernel page tables */
355 load32 PA(swapper_pg_dir),%r4
356 mtctl %r4,%cr24 /* Initialize kernel root pointer */
357 mtctl %r4,%cr25 /* Initialize user root pointer */
358
359#ifdef __LP64__
360 /* Setup PDCE_PROC entry */
361 copy %arg0,%r3
362#else
363 /* Load RFI *return* address in case smp_callin bails */
364 load32 smp_callin_rtn,%r2
365#endif
366
367 /* Load RFI target address. */
368 load32 smp_callin,%r11
369
370 /* ok...common code can handle the rest */
371 b common_stext
372 nop
373
374 .procend
375#endif /* CONFIG_SMP */
376#ifndef __LP64__
377 .data
378
379 .align 4
380 .export $global$,data
381
382 .type $global$,@object
383 .size $global$,4
384$global$:
385 .word 0
386#endif /*!LP64*/
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
new file mode 100644
index 000000000000..c412c0adc4a9
--- /dev/null
+++ b/arch/parisc/kernel/hpmc.S
@@ -0,0 +1,304 @@
1/*
2 * HPMC (High Priority Machine Check) handler.
3 *
4 * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org>
5 * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
6 * Copyright (C) 2000 Hewlett-Packard (John Marvin)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24/*
25 * This HPMC handler retrieves the HPMC pim data, resets IO and
26 * returns to the default trap handler with code set to 1 (HPMC).
27 * The default trap handler calls handle interruption, which
28 * does a stack and register dump. This at least allows kernel
29 * developers to get back to C code in virtual mode, where they
30 * have the option to examine and print values from memory that
31 * would help in debugging an HPMC caused by a software bug.
32 *
33 * There is more to do here:
34 *
35 * 1) On MP systems we need to synchronize processors
36 * before calling pdc/iodc.
37 * 2) We should be checking the system state and not
38 * returning to the fault handler if things are really
39 * bad.
40 *
41 */
42
43 .level 1.1
44 .data
45
46#include <asm/assembly.h>
47#include <asm/pdc.h>
48
49 /*
50 * stack for os_hpmc, the HPMC handler.
51 * buffer for IODC procedures (for the HPMC handler).
52 *
53 * IODC requires 7K byte stack. That leaves 1K byte for os_hpmc.
54 */
55
56 .align 4096
57hpmc_stack:
58 .block 16384
59
60#define HPMC_IODC_BUF_SIZE 0x8000
61
62 .align 4096
63hpmc_iodc_buf:
64 .block HPMC_IODC_BUF_SIZE
65
66 .align 8
67hpmc_raddr:
68 .block 128
69
70#define HPMC_PIM_DATA_SIZE 896 /* Enough to hold all architected 2.0 state */
71
72 .export hpmc_pim_data, data
73 .align 8
74hpmc_pim_data:
75 .block HPMC_PIM_DATA_SIZE
76
77 .text
78
79 .export os_hpmc, code
80 .import intr_save, code
81
82os_hpmc:
83
84 /*
85 * registers modified:
86 *
87 * Using callee saves registers without saving them. The
88 * original values are in the pim dump if we need them.
89 *
90 * r2 (rp) return pointer
91 * r3 address of PDCE_PROC
92 * r4 scratch
93 * r5 scratch
94 * r23 (arg3) procedure arg
95 * r24 (arg2) procedure arg
96 * r25 (arg1) procedure arg
97 * r26 (arg0) procedure arg
98 * r30 (sp) stack pointer
99 *
100 * registers read:
101 *
102 * r26 contains address of PDCE_PROC on entry
103 * r28 (ret0) return value from procedure
104 */
105
106 copy arg0, %r3 /* save address of PDCE_PROC */
107
108 /*
109 * disable nested HPMCs
110 *
111 * Increment os_hpmc checksum to invalidate it.
112 * Do this before turning the PSW M bit off.
113 */
114
115 mfctl %cr14, %r4
116 ldw 52(%r4),%r5
117 addi 1,%r5,%r5
118 stw %r5,52(%r4)
119
120 /* MP_FIXME: synchronize all processors. */
121
122 /* Setup stack pointer. */
123
124 load32 PA(hpmc_stack),sp
125
126 ldo 128(sp),sp /* leave room for arguments */
127
128 /*
129 * Most PDC routines require that the M bit be off.
130 * So turn on the Q bit and turn off the M bit.
131 */
132
133 ldo 8(%r0),%r4 /* PSW Q on, PSW M off */
134 mtctl %r4,ipsw
135 mtctl %r0,pcsq
136 mtctl %r0,pcsq
137 load32 PA(os_hpmc_1),%r4
138 mtctl %r4,pcoq
139 ldo 4(%r4),%r4
140 mtctl %r4,pcoq
141 rfi
142 nop
143
144os_hpmc_1:
145
146 /* Call PDC_PIM to get HPMC pim info */
147
148 /*
149 * Note that on some newer boxes, PDC_PIM must be called
150 * before PDC_IO if you want IO to be reset. PDC_PIM sets
151 * a flag that PDC_IO examines.
152 */
153
154 ldo PDC_PIM(%r0), arg0
155 ldo PDC_PIM_HPMC(%r0),arg1 /* Transfer HPMC data */
156 load32 PA(hpmc_raddr),arg2
157 load32 PA(hpmc_pim_data),arg3
158 load32 HPMC_PIM_DATA_SIZE,%r4
159 stw %r4,-52(sp)
160
161 ldil L%PA(os_hpmc_2), rp
162 bv (r3) /* call pdce_proc */
163 ldo R%PA(os_hpmc_2)(rp), rp
164
165os_hpmc_2:
166 comib,<> 0,ret0, os_hpmc_fail
167
168 /* Reset IO by calling the hversion dependent PDC_IO routine */
169
170 ldo PDC_IO(%r0),arg0
171 ldo 0(%r0),arg1 /* log IO errors */
172 ldo 0(%r0),arg2 /* reserved */
173 ldo 0(%r0),arg3 /* reserved */
174 stw %r0,-52(sp) /* reserved */
175
176 ldil L%PA(os_hpmc_3),rp
177 bv (%r3) /* call pdce_proc */
178 ldo R%PA(os_hpmc_3)(rp),rp
179
180os_hpmc_3:
181
182 /* FIXME? Check for errors from PDC_IO (-1 might be OK) */
183
184 /*
185 * Initialize the IODC console device (HPA,SPA, path etc.
186 * are stored on page 0.
187 */
188
189 /*
190 * Load IODC into hpmc_iodc_buf by calling PDC_IODC.
191 * Note that PDC_IODC handles flushing the appropriate
192 * data and instruction cache lines.
193 */
194
195 ldo PDC_IODC(%r0),arg0
196 ldo PDC_IODC_READ(%r0),arg1
197 load32 PA(hpmc_raddr),arg2
198 ldw BOOT_CONSOLE_HPA_OFFSET(%r0),arg3 /* console hpa */
199 ldo PDC_IODC_RI_INIT(%r0),%r4
200 stw %r4,-52(sp)
201 load32 PA(hpmc_iodc_buf),%r4
202 stw %r4,-56(sp)
203 load32 HPMC_IODC_BUF_SIZE,%r4
204 stw %r4,-60(sp)
205
206 ldil L%PA(os_hpmc_4),rp
207 bv (%r3) /* call pdce_proc */
208 ldo R%PA(os_hpmc_4)(rp),rp
209
210os_hpmc_4:
211 comib,<> 0,ret0,os_hpmc_fail
212
213 /* Call the entry init (just loaded by PDC_IODC) */
214
215 ldw BOOT_CONSOLE_HPA_OFFSET(%r0),arg0 /* console hpa */
216 ldo ENTRY_INIT_MOD_DEV(%r0), arg1
217 ldw BOOT_CONSOLE_SPA_OFFSET(%r0),arg2 /* console spa */
218 depi 0,31,11,arg2 /* clear bits 21-31 */
219 ldo BOOT_CONSOLE_PATH_OFFSET(%r0),arg3 /* console path */
220 load32 PA(hpmc_raddr),%r4
221 stw %r4, -52(sp)
222 stw %r0, -56(sp) /* HV */
223 stw %r0, -60(sp) /* HV */
224 stw %r0, -64(sp) /* HV */
225 stw %r0, -68(sp) /* lang, must be zero */
226
227 load32 PA(hpmc_iodc_buf),%r5
228 ldil L%PA(os_hpmc_5),rp
229 bv (%r5)
230 ldo R%PA(os_hpmc_5)(rp),rp
231
232os_hpmc_5:
233 comib,<> 0,ret0,os_hpmc_fail
234
235 /* Prepare to call intr_save */
236
237 /*
238 * Load kernel page directory (load into user also, since
239 * we don't intend to ever return to user land anyway)
240 */
241
242 load32 PA(swapper_pg_dir),%r4
243 mtctl %r4,%cr24 /* Initialize kernel root pointer */
244 mtctl %r4,%cr25 /* Initialize user root pointer */
245
246 /* Clear sr4-sr7 */
247
248 mtsp %r0, %sr4
249 mtsp %r0, %sr5
250 mtsp %r0, %sr6
251 mtsp %r0, %sr7
252
253 tovirt_r1 %r30 /* make sp virtual */
254
255 rsm 8,%r0 /* Clear Q bit */
256 ldi 1,%r8 /* Set trap code to "1" for HPMC */
257 load32 PA(intr_save),%r1
258 be 0(%sr7,%r1)
259 nop
260
261os_hpmc_fail:
262
263 /*
264 * Reset the system
265 *
266 * Some systems may lockup from a broadcast reset, so try the
267 * hversion PDC_BROADCAST_RESET() first.
268 * MP_FIXME: reset all processors if more than one central bus.
269 */
270
271 /* PDC_BROADCAST_RESET() */
272
273 ldo PDC_BROADCAST_RESET(%r0),arg0
274 ldo 0(%r0),arg1 /* do reset */
275
276 ldil L%PA(os_hpmc_6),rp
277 bv (%r3) /* call pdce_proc */
278 ldo R%PA(os_hpmc_6)(rp),rp
279
280os_hpmc_6:
281
282 /*
283 * possible return values:
284 * -1 non-existent procedure
285 * -2 non-existent option
286 * -16 unaligned stack
287 *
288 * If call returned, do a broadcast reset.
289 */
290
291 ldil L%0xfffc0000,%r4 /* IO_BROADCAST */
292 ldo 5(%r0),%r5
293 stw %r5,48(%r4) /* CMD_RESET to IO_COMMAND offset */
294
295 b .
296 nop
297
298 /* this label used to compute os_hpmc checksum */
299
300 .export os_hpmc_end, code
301
302os_hpmc_end:
303
304 nop
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c
new file mode 100644
index 000000000000..7e898fd64415
--- /dev/null
+++ b/arch/parisc/kernel/init_task.c
@@ -0,0 +1,76 @@
1/*
2 * Static declaration of "init" task data structure.
3 *
4 * Copyright (C) 2000 Paul Bame <bame at parisc-linux.org>
5 * Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
6 * Copyright (C) 2001 Helge Deller <deller @ parisc-linux.org>
7 * Copyright (C) 2002 Matthew Wilcox <willy with parisc-linux.org>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/mm.h>
26#include <linux/module.h>
27#include <linux/sched.h>
28#include <linux/init.h>
29#include <linux/init_task.h>
30#include <linux/mqueue.h>
31
32#include <asm/uaccess.h>
33#include <asm/pgtable.h>
34#include <asm/pgalloc.h>
35
36static struct fs_struct init_fs = INIT_FS;
37static struct files_struct init_files = INIT_FILES;
38static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
39static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
40struct mm_struct init_mm = INIT_MM(init_mm);
41
42EXPORT_SYMBOL(init_mm);
43
44/*
45 * Initial task structure.
46 *
47 * We need to make sure that this is 16384-byte aligned due to the
48 * way process stacks are handled. This is done by having a special
49 * "init_task" linker map entry..
50 */
51unsigned char interrupt_stack[ISTACK_SIZE] __attribute__ ((section("init_istack"), aligned(4096)));
52union thread_union init_thread_union
53 __attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) =
54 { INIT_THREAD_INFO(init_task) };
55
56#ifdef __LP64__
57/* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout
58 * with the first pmd adjacent to the pgd and below it. gcc doesn't actually
59 * guarantee that global objects will be laid out in memory in the same order
60 * as the order of declaration, so put these in different sections and use
61 * the linker script to order them. */
62pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pmd"))) = { {0}, };
63
64#endif
65pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pgd"))) = { {0}, };
66pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pte"))) = { {0}, };
67
68/*
69 * Initial task structure.
70 *
71 * All other task structs will be allocated on slabs in fork.c
72 */
73EXPORT_SYMBOL(init_task);
74
75__asm__(".data");
76struct task_struct init_task = INIT_TASK(init_task);
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
new file mode 100644
index 000000000000..1a1c66422736
--- /dev/null
+++ b/arch/parisc/kernel/inventory.c
@@ -0,0 +1,612 @@
1/*
2 * inventory.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Copyright (c) 1999 The Puffin Group (David Kennedy and Alex deVries)
10 * Copyright (c) 2001 Matthew Wilcox for Hewlett-Packard
11 *
12 * These are the routines to discover what hardware exists in this box.
13 * This task is complicated by there being 3 different ways of
14 * performing an inventory, depending largely on the age of the box.
15 * The recommended way to do this is to check to see whether the machine
16 * is a `Snake' first, then try System Map, then try PAT. We try System
17 * Map before checking for a Snake -- this probably doesn't cause any
18 * problems, but...
19 */
20
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/mm.h>
26#include <asm/hardware.h>
27#include <asm/io.h>
28#include <asm/mmzone.h>
29#include <asm/pdc.h>
30#include <asm/pdcpat.h>
31#include <asm/processor.h>
32#include <asm/page.h>
33#include <asm/parisc-device.h>
34
35/*
36** Debug options
37** DEBUG_PAT Dump details which PDC PAT provides about ranges/devices.
38*/
39#undef DEBUG_PAT
40
41int pdc_type = PDC_TYPE_ILLEGAL;
42
43void __init setup_pdc(void)
44{
45 long status;
46 unsigned int bus_id;
47 struct pdc_system_map_mod_info module_result;
48 struct pdc_module_path module_path;
49 struct pdc_model model;
50#ifdef __LP64__
51 struct pdc_pat_cell_num cell_info;
52#endif
53
54 /* Determine the pdc "type" used on this machine */
55
56 printk(KERN_INFO "Determining PDC firmware type: ");
57
58 status = pdc_system_map_find_mods(&module_result, &module_path, 0);
59 if (status == PDC_OK) {
60 pdc_type = PDC_TYPE_SYSTEM_MAP;
61 printk("System Map.\n");
62 return;
63 }
64
65 /*
66 * If the machine doesn't support PDC_SYSTEM_MAP then either it
67 * is a pdc pat box, or it is an older box. All 64 bit capable
68 * machines are either pdc pat boxes or they support PDC_SYSTEM_MAP.
69 */
70
71 /*
72 * TODO: We should test for 64 bit capability and give a
73 * clearer message.
74 */
75
76#ifdef __LP64__
77 status = pdc_pat_cell_get_number(&cell_info);
78 if (status == PDC_OK) {
79 pdc_type = PDC_TYPE_PAT;
80 printk("64 bit PAT.\n");
81 return;
82 }
83#endif
84
85 /* Check the CPU's bus ID. There's probably a better test. */
86
87 status = pdc_model_info(&model);
88
89 bus_id = (model.hversion >> (4 + 7)) & 0x1f;
90
91 switch (bus_id) {
92 case 0x4: /* 720, 730, 750, 735, 755 */
93 case 0x6: /* 705, 710 */
94 case 0x7: /* 715, 725 */
95 case 0x8: /* 745, 747, 742 */
96 case 0xA: /* 712 and similiar */
97 case 0xC: /* 715/64, at least */
98
99 pdc_type = PDC_TYPE_SNAKE;
100 printk("Snake.\n");
101 return;
102
103 default: /* Everything else */
104
105 printk("Unsupported.\n");
106 panic("If this is a 64-bit machine, please try a 64-bit kernel.\n");
107 }
108}
109
110#define PDC_PAGE_ADJ_SHIFT (PAGE_SHIFT - 12) /* pdc pages are always 4k */
111
112static void __init
113set_pmem_entry(physmem_range_t *pmem_ptr, unsigned long start,
114 unsigned long pages4k)
115{
116 /* Rather than aligning and potentially throwing away
117 * memory, we'll assume that any ranges are already
118 * nicely aligned with any reasonable page size, and
119 * panic if they are not (it's more likely that the
120 * pdc info is bad in this case).
121 */
122
123 if ( ((start & (PAGE_SIZE - 1)) != 0)
124 || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) ) {
125
126 panic("Memory range doesn't align with page size!\n");
127 }
128
129 pmem_ptr->start_pfn = (start >> PAGE_SHIFT);
130 pmem_ptr->pages = (pages4k >> PDC_PAGE_ADJ_SHIFT);
131}
132
133static void __init pagezero_memconfig(void)
134{
135 unsigned long npages;
136
137 /* Use the 32 bit information from page zero to create a single
138 * entry in the pmem_ranges[] table.
139 *
140 * We currently don't support machines with contiguous memory
141 * >= 4 Gb, who report that memory using 64 bit only fields
142 * on page zero. It's not worth doing until it can be tested,
143 * and it is not clear we can support those machines for other
144 * reasons.
145 *
146 * If that support is done in the future, this is where it
147 * should be done.
148 */
149
150 npages = (PAGE_ALIGN(PAGE0->imm_max_mem) >> PAGE_SHIFT);
151 set_pmem_entry(pmem_ranges,0UL,npages);
152 npmem_ranges = 1;
153}
154
155#ifdef __LP64__
156
157/* All of the PDC PAT specific code is 64-bit only */
158
159/*
160** The module object is filled via PDC_PAT_CELL[Return Cell Module].
161** If a module is found, register module will get the IODC bytes via
162** pdc_iodc_read() using the PA view of conf_base_addr for the hpa parameter.
163**
164** The IO view can be used by PDC_PAT_CELL[Return Cell Module]
165** only for SBAs and LBAs. This view will cause an invalid
166** argument error for all other cell module types.
167**
168*/
169
170static int __init
171pat_query_module(ulong pcell_loc, ulong mod_index)
172{
173 pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
174 unsigned long bytecnt;
175 unsigned long temp; /* 64-bit scratch value */
176 long status; /* PDC return value status */
177 struct parisc_device *dev;
178
179 /* return cell module (PA or Processor view) */
180 status = pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
181 PA_VIEW, &pa_pdc_cell);
182
183 if (status != PDC_OK) {
184 /* no more cell modules or error */
185 return status;
186 }
187
188 temp = pa_pdc_cell.cba;
189 dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
190 if (!dev) {
191 return PDC_NE_MOD;
192 }
193
194 /* alloc_pa_dev sets dev->hpa */
195
196 /*
197 ** save parameters in the parisc_device
198 ** (The idea being the device driver will call pdc_pat_cell_module()
199 ** and store the results in its own data structure.)
200 */
201 dev->pcell_loc = pcell_loc;
202 dev->mod_index = mod_index;
203
204 /* save generic info returned from the call */
205 /* REVISIT: who is the consumer of this? not sure yet... */
206 dev->mod_info = pa_pdc_cell.mod_info; /* pass to PAT_GET_ENTITY() */
207 dev->pmod_loc = pa_pdc_cell.mod_location;
208
209 register_parisc_device(dev); /* advertise device */
210
211#ifdef DEBUG_PAT
212 pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
213 /* dump what we see so far... */
214 switch (PAT_GET_ENTITY(dev->mod_info)) {
215 unsigned long i;
216
217 case PAT_ENTITY_PROC:
218 printk(KERN_DEBUG "PAT_ENTITY_PROC: id_eid 0x%lx\n",
219 pa_pdc_cell.mod[0]);
220 break;
221
222 case PAT_ENTITY_MEM:
223 printk(KERN_DEBUG
224 "PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n",
225 pa_pdc_cell.mod[0], pa_pdc_cell.mod[1],
226 pa_pdc_cell.mod[2]);
227 break;
228 case PAT_ENTITY_CA:
229 printk(KERN_DEBUG "PAT_ENTITY_CA: %ld\n", pcell_loc);
230 break;
231
232 case PAT_ENTITY_PBC:
233 printk(KERN_DEBUG "PAT_ENTITY_PBC: ");
234 goto print_ranges;
235
236 case PAT_ENTITY_SBA:
237 printk(KERN_DEBUG "PAT_ENTITY_SBA: ");
238 goto print_ranges;
239
240 case PAT_ENTITY_LBA:
241 printk(KERN_DEBUG "PAT_ENTITY_LBA: ");
242
243 print_ranges:
244 pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
245 IO_VIEW, &io_pdc_cell);
246 printk(KERN_DEBUG "ranges %ld\n", pa_pdc_cell.mod[1]);
247 for (i = 0; i < pa_pdc_cell.mod[1]; i++) {
248 printk(KERN_DEBUG
249 " PA_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n",
250 i, pa_pdc_cell.mod[2 + i * 3], /* type */
251 pa_pdc_cell.mod[3 + i * 3], /* start */
252 pa_pdc_cell.mod[4 + i * 3]); /* finish (ie end) */
253 printk(KERN_DEBUG
254 " IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n",
255 i, io_pdc_cell.mod[2 + i * 3], /* type */
256 io_pdc_cell.mod[3 + i * 3], /* start */
257 io_pdc_cell.mod[4 + i * 3]); /* finish (ie end) */
258 }
259 printk(KERN_DEBUG "\n");
260 break;
261 }
262#endif /* DEBUG_PAT */
263 return PDC_OK;
264}
265
266
267/* pat pdc can return information about a variety of different
268 * types of memory (e.g. firmware,i/o, etc) but we only care about
269 * the usable physical ram right now. Since the firmware specific
270 * information is allocated on the stack, we'll be generous, in
271 * case there is a lot of other information we don't care about.
272 */
273
274#define PAT_MAX_RANGES (4 * MAX_PHYSMEM_RANGES)
275
276static void __init pat_memconfig(void)
277{
278 unsigned long actual_len;
279 struct pdc_pat_pd_addr_map_entry mem_table[PAT_MAX_RANGES+1];
280 struct pdc_pat_pd_addr_map_entry *mtbl_ptr;
281 physmem_range_t *pmem_ptr;
282 long status;
283 int entries;
284 unsigned long length;
285 int i;
286
287 length = (PAT_MAX_RANGES + 1) * sizeof(struct pdc_pat_pd_addr_map_entry);
288
289 status = pdc_pat_pd_get_addr_map(&actual_len, mem_table, length, 0L);
290
291 if ((status != PDC_OK)
292 || ((actual_len % sizeof(struct pdc_pat_pd_addr_map_entry)) != 0)) {
293
294 /* The above pdc call shouldn't fail, but, just in
295 * case, just use the PAGE0 info.
296 */
297
298 printk("\n\n\n");
299 printk(KERN_WARNING "WARNING! Could not get full memory configuration. "
300 "All memory may not be used!\n\n\n");
301 pagezero_memconfig();
302 return;
303 }
304
305 entries = actual_len / sizeof(struct pdc_pat_pd_addr_map_entry);
306
307 if (entries > PAT_MAX_RANGES) {
308 printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
309 printk(KERN_WARNING "Some memory may not be used!\n");
310 }
311
312 /* Copy information into the firmware independent pmem_ranges
313 * array, skipping types we don't care about. Notice we said
314 * "may" above. We'll use all the entries that were returned.
315 */
316
317 npmem_ranges = 0;
318 mtbl_ptr = mem_table;
319 pmem_ptr = pmem_ranges; /* Global firmware independent table */
320 for (i = 0; i < entries; i++,mtbl_ptr++) {
321 if ( (mtbl_ptr->entry_type != PAT_MEMORY_DESCRIPTOR)
322 || (mtbl_ptr->memory_type != PAT_MEMTYPE_MEMORY)
323 || (mtbl_ptr->pages == 0)
324 || ( (mtbl_ptr->memory_usage != PAT_MEMUSE_GENERAL)
325 && (mtbl_ptr->memory_usage != PAT_MEMUSE_GI)
326 && (mtbl_ptr->memory_usage != PAT_MEMUSE_GNI) ) ) {
327
328 continue;
329 }
330
331 if (npmem_ranges == MAX_PHYSMEM_RANGES) {
332 printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
333 printk(KERN_WARNING "Some memory will not be used!\n");
334 break;
335 }
336
337 set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
338 npmem_ranges++;
339 }
340}
341
342static int __init pat_inventory(void)
343{
344 int status;
345 ulong mod_index = 0;
346 struct pdc_pat_cell_num cell_info;
347
348 /*
349 ** Note: Prelude (and it's successors: Lclass, A400/500) only
350 ** implement PDC_PAT_CELL sub-options 0 and 2.
351 */
352 status = pdc_pat_cell_get_number(&cell_info);
353 if (status != PDC_OK) {
354 return 0;
355 }
356
357#ifdef DEBUG_PAT
358 printk(KERN_DEBUG "CELL_GET_NUMBER: 0x%lx 0x%lx\n", cell_info.cell_num,
359 cell_info.cell_loc);
360#endif
361
362 while (PDC_OK == pat_query_module(cell_info.cell_loc, mod_index)) {
363 mod_index++;
364 }
365
366 return mod_index;
367}
368
369/* We only look for extended memory ranges on a 64 bit capable box */
370static void __init sprockets_memconfig(void)
371{
372 struct pdc_memory_table_raddr r_addr;
373 struct pdc_memory_table mem_table[MAX_PHYSMEM_RANGES];
374 struct pdc_memory_table *mtbl_ptr;
375 physmem_range_t *pmem_ptr;
376 long status;
377 int entries;
378 int i;
379
380 status = pdc_mem_mem_table(&r_addr,mem_table,
381 (unsigned long)MAX_PHYSMEM_RANGES);
382
383 if (status != PDC_OK) {
384
385 /* The above pdc call only works on boxes with sprockets
386 * firmware (newer B,C,J class). Other non PAT PDC machines
387 * do support more than 3.75 Gb of memory, but we don't
388 * support them yet.
389 */
390
391 pagezero_memconfig();
392 return;
393 }
394
395 if (r_addr.entries_total > MAX_PHYSMEM_RANGES) {
396 printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
397 printk(KERN_WARNING "Some memory will not be used!\n");
398 }
399
400 entries = (int)r_addr.entries_returned;
401
402 npmem_ranges = 0;
403 mtbl_ptr = mem_table;
404 pmem_ptr = pmem_ranges; /* Global firmware independent table */
405 for (i = 0; i < entries; i++,mtbl_ptr++) {
406 set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
407 npmem_ranges++;
408 }
409}
410
411#else /* !__LP64__ */
412
413#define pat_inventory() do { } while (0)
414#define pat_memconfig() do { } while (0)
415#define sprockets_memconfig() pagezero_memconfig()
416
417#endif /* !__LP64__ */
418
419
420#ifndef CONFIG_PA20
421
422/* Code to support Snake machines (7[2350], 7[235]5, 715/Scorpio) */
423
424static struct parisc_device * __init
425legacy_create_device(struct pdc_memory_map *r_addr,
426 struct pdc_module_path *module_path)
427{
428 struct parisc_device *dev;
429 int status = pdc_mem_map_hpa(r_addr, module_path);
430 if (status != PDC_OK)
431 return NULL;
432
433 dev = alloc_pa_dev(r_addr->hpa, &module_path->path);
434 if (dev == NULL)
435 return NULL;
436
437 register_parisc_device(dev);
438 return dev;
439}
440
441/**
442 * snake_inventory
443 *
444 * Before PDC_SYSTEM_MAP was invented, the PDC_MEM_MAP call was used.
445 * To use it, we initialise the mod_path.bc to 0xff and try all values of
446 * mod to get the HPA for the top-level devices. Bus adapters may have
447 * sub-devices which are discovered by setting bc[5] to 0 and bc[4] to the
448 * module, then trying all possible functions.
449 */
450static void __init snake_inventory(void)
451{
452 int mod;
453 for (mod = 0; mod < 16; mod++) {
454 struct parisc_device *dev;
455 struct pdc_module_path module_path;
456 struct pdc_memory_map r_addr;
457 unsigned int func;
458
459 memset(module_path.path.bc, 0xff, 6);
460 module_path.path.mod = mod;
461 dev = legacy_create_device(&r_addr, &module_path);
462 if ((!dev) || (dev->id.hw_type != HPHW_BA))
463 continue;
464
465 memset(module_path.path.bc, 0xff, 4);
466 module_path.path.bc[4] = mod;
467
468 for (func = 0; func < 16; func++) {
469 module_path.path.bc[5] = 0;
470 module_path.path.mod = func;
471 legacy_create_device(&r_addr, &module_path);
472 }
473 }
474}
475
476#else /* CONFIG_PA20 */
477#define snake_inventory() do { } while (0)
478#endif /* CONFIG_PA20 */
479
480/* Common 32/64 bit based code goes here */
481
482/**
483 * add_system_map_addresses - Add additional addresses to the parisc device.
484 * @dev: The parisc device.
485 * @num_addrs: Then number of addresses to add;
486 * @module_instance: The system_map module instance.
487 *
488 * This function adds any additional addresses reported by the system_map
489 * firmware to the parisc device.
490 */
491static void __init
492add_system_map_addresses(struct parisc_device *dev, int num_addrs,
493 int module_instance)
494{
495 int i;
496 long status;
497 struct pdc_system_map_addr_info addr_result;
498
499 dev->addr = kmalloc(num_addrs * sizeof(unsigned long), GFP_KERNEL);
500 if(!dev->addr) {
501 printk(KERN_ERR "%s %s(): memory allocation failure\n",
502 __FILE__, __FUNCTION__);
503 return;
504 }
505
506 for(i = 1; i <= num_addrs; ++i) {
507 status = pdc_system_map_find_addrs(&addr_result,
508 module_instance, i);
509 if(PDC_OK == status) {
510 dev->addr[dev->num_addrs] = (unsigned long)addr_result.mod_addr;
511 dev->num_addrs++;
512 } else {
513 printk(KERN_WARNING
514 "Bad PDC_FIND_ADDRESS status return (%ld) for index %d\n",
515 status, i);
516 }
517 }
518}
519
520/**
521 * system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
522 *
523 * This function attempts to retrieve and register all the devices firmware
524 * knows about via the SYSTEM_MAP PDC call.
525 */
526static void __init system_map_inventory(void)
527{
528 int i;
529 long status = PDC_OK;
530
531 for (i = 0; i < 256; i++) {
532 struct parisc_device *dev;
533 struct pdc_system_map_mod_info module_result;
534 struct pdc_module_path module_path;
535
536 status = pdc_system_map_find_mods(&module_result,
537 &module_path, i);
538 if ((status == PDC_BAD_PROC) || (status == PDC_NE_MOD))
539 break;
540 if (status != PDC_OK)
541 continue;
542
543 dev = alloc_pa_dev(module_result.mod_addr, &module_path.path);
544 if (!dev)
545 continue;
546
547 register_parisc_device(dev);
548
549 /* if available, get the additional addresses for a module */
550 if (!module_result.add_addrs)
551 continue;
552
553 add_system_map_addresses(dev, module_result.add_addrs, i);
554 }
555
556 walk_central_bus();
557 return;
558}
559
560void __init do_memory_inventory(void)
561{
562 switch (pdc_type) {
563
564 case PDC_TYPE_PAT:
565 pat_memconfig();
566 break;
567
568 case PDC_TYPE_SYSTEM_MAP:
569 sprockets_memconfig();
570 break;
571
572 case PDC_TYPE_SNAKE:
573 pagezero_memconfig();
574 return;
575
576 default:
577 panic("Unknown PDC type!\n");
578 }
579
580 if (npmem_ranges == 0 || pmem_ranges[0].start_pfn != 0) {
581 printk(KERN_WARNING "Bad memory configuration returned!\n");
582 printk(KERN_WARNING "Some memory may not be used!\n");
583 pagezero_memconfig();
584 }
585}
586
587void __init do_device_inventory(void)
588{
589 printk(KERN_INFO "Searching for devices...\n");
590
591 init_parisc_bus();
592
593 switch (pdc_type) {
594
595 case PDC_TYPE_PAT:
596 pat_inventory();
597 break;
598
599 case PDC_TYPE_SYSTEM_MAP:
600 system_map_inventory();
601 break;
602
603 case PDC_TYPE_SNAKE:
604 snake_inventory();
605 break;
606
607 default:
608 panic("Unknown PDC type!\n");
609 }
610 printk(KERN_INFO "Found devices:\n");
611 print_parisc_devices();
612}
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
new file mode 100644
index 000000000000..1d3824b670d1
--- /dev/null
+++ b/arch/parisc/kernel/ioctl32.c
@@ -0,0 +1,625 @@
1/* $Id: ioctl32.c,v 1.5 2002/10/18 00:21:43 varenet Exp $
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 *
4 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
5 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
6 *
7 * These routines maintain argument size conversion between 32bit and 64bit
8 * ioctls.
9 */
10
11#include <linux/syscalls.h>
12
13#define INCLUDES
14#include "compat_ioctl.c"
15
16#include <asm/perf.h>
17#include <asm/ioctls.h>
18
19#define CODE
20#include "compat_ioctl.c"
21
22/* Use this to get at 32-bit user passed pointers.
23 See sys_sparc32.c for description about these. */
24#define A(__x) ((unsigned long)(__x))
25/* The same for use with copy_from_user() and copy_to_user(). */
26#define B(__x) ((void *)(unsigned long)(__x))
27
28#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
29/* This really belongs in include/linux/drm.h -DaveM */
30#include "../../../drivers/char/drm/drm.h"
31
32typedef struct drm32_version {
33 int version_major; /* Major version */
34 int version_minor; /* Minor version */
35 int version_patchlevel;/* Patch level */
36 int name_len; /* Length of name buffer */
37 u32 name; /* Name of driver */
38 int date_len; /* Length of date buffer */
39 u32 date; /* User-space buffer to hold date */
40 int desc_len; /* Length of desc buffer */
41 u32 desc; /* User-space buffer to hold desc */
42} drm32_version_t;
43#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
44
45static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
46{
47 drm32_version_t *uversion = (drm32_version_t *)arg;
48 char *name_ptr, *date_ptr, *desc_ptr;
49 u32 tmp1, tmp2, tmp3;
50 drm_version_t kversion;
51 mm_segment_t old_fs;
52 int ret;
53
54 memset(&kversion, 0, sizeof(kversion));
55 if (get_user(kversion.name_len, &uversion->name_len) ||
56 get_user(kversion.date_len, &uversion->date_len) ||
57 get_user(kversion.desc_len, &uversion->desc_len) ||
58 get_user(tmp1, &uversion->name) ||
59 get_user(tmp2, &uversion->date) ||
60 get_user(tmp3, &uversion->desc))
61 return -EFAULT;
62
63 name_ptr = (char *) A(tmp1);
64 date_ptr = (char *) A(tmp2);
65 desc_ptr = (char *) A(tmp3);
66
67 ret = -ENOMEM;
68 if (kversion.name_len && name_ptr) {
69 kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
70 if (!kversion.name)
71 goto out;
72 }
73 if (kversion.date_len && date_ptr) {
74 kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
75 if (!kversion.date)
76 goto out;
77 }
78 if (kversion.desc_len && desc_ptr) {
79 kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
80 if (!kversion.desc)
81 goto out;
82 }
83
84 old_fs = get_fs();
85 set_fs(KERNEL_DS);
86 ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
87 set_fs(old_fs);
88
89 if (!ret) {
90 if ((kversion.name &&
91 copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
92 (kversion.date &&
93 copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
94 (kversion.desc &&
95 copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
96 ret = -EFAULT;
97 if (put_user(kversion.version_major, &uversion->version_major) ||
98 put_user(kversion.version_minor, &uversion->version_minor) ||
99 put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
100 put_user(kversion.name_len, &uversion->name_len) ||
101 put_user(kversion.date_len, &uversion->date_len) ||
102 put_user(kversion.desc_len, &uversion->desc_len))
103 ret = -EFAULT;
104 }
105
106out:
107 if (kversion.name)
108 kfree(kversion.name);
109 if (kversion.date)
110 kfree(kversion.date);
111 if (kversion.desc)
112 kfree(kversion.desc);
113 return ret;
114}
115
116typedef struct drm32_unique {
117 int unique_len; /* Length of unique */
118 u32 unique; /* Unique name for driver instantiation */
119} drm32_unique_t;
120#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
121#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
122
123static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
124{
125 drm32_unique_t *uarg = (drm32_unique_t *)arg;
126 drm_unique_t karg;
127 mm_segment_t old_fs;
128 char *uptr;
129 u32 tmp;
130 int ret;
131
132 if (get_user(karg.unique_len, &uarg->unique_len))
133 return -EFAULT;
134 karg.unique = NULL;
135
136 if (get_user(tmp, &uarg->unique))
137 return -EFAULT;
138
139 uptr = (char *) A(tmp);
140
141 if (uptr) {
142 karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
143 if (!karg.unique)
144 return -ENOMEM;
145 if (cmd == DRM32_IOCTL_SET_UNIQUE &&
146 copy_from_user(karg.unique, uptr, karg.unique_len)) {
147 kfree(karg.unique);
148 return -EFAULT;
149 }
150 }
151
152 old_fs = get_fs();
153 set_fs(KERNEL_DS);
154 if (cmd == DRM32_IOCTL_GET_UNIQUE)
155 ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
156 else
157 ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
158 set_fs(old_fs);
159
160 if (!ret) {
161 if (cmd == DRM32_IOCTL_GET_UNIQUE &&
162 uptr != NULL &&
163 copy_to_user(uptr, karg.unique, karg.unique_len))
164 ret = -EFAULT;
165 if (put_user(karg.unique_len, &uarg->unique_len))
166 ret = -EFAULT;
167 }
168
169 if (karg.unique != NULL)
170 kfree(karg.unique);
171
172 return ret;
173}
174
175typedef struct drm32_map {
176 u32 offset; /* Requested physical address (0 for SAREA)*/
177 u32 size; /* Requested physical size (bytes) */
178 drm_map_type_t type; /* Type of memory to map */
179 drm_map_flags_t flags; /* Flags */
180 u32 handle; /* User-space: "Handle" to pass to mmap */
181 /* Kernel-space: kernel-virtual address */
182 int mtrr; /* MTRR slot used */
183 /* Private data */
184} drm32_map_t;
185#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
186
187static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
188{
189 drm32_map_t *uarg = (drm32_map_t *) arg;
190 drm_map_t karg;
191 mm_segment_t old_fs;
192 u32 tmp;
193 int ret;
194
195 ret = get_user(karg.offset, &uarg->offset);
196 ret |= get_user(karg.size, &uarg->size);
197 ret |= get_user(karg.type, &uarg->type);
198 ret |= get_user(karg.flags, &uarg->flags);
199 ret |= get_user(tmp, &uarg->handle);
200 ret |= get_user(karg.mtrr, &uarg->mtrr);
201 if (ret)
202 return -EFAULT;
203
204 karg.handle = (void *) A(tmp);
205
206 old_fs = get_fs();
207 set_fs(KERNEL_DS);
208 ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
209 set_fs(old_fs);
210
211 if (!ret) {
212 ret = put_user(karg.offset, &uarg->offset);
213 ret |= put_user(karg.size, &uarg->size);
214 ret |= put_user(karg.type, &uarg->type);
215 ret |= put_user(karg.flags, &uarg->flags);
216 tmp = (u32) (long)karg.handle;
217 ret |= put_user(tmp, &uarg->handle);
218 ret |= put_user(karg.mtrr, &uarg->mtrr);
219 if (ret)
220 ret = -EFAULT;
221 }
222
223 return ret;
224}
225
226typedef struct drm32_buf_info {
227 int count; /* Entries in list */
228 u32 list; /* (drm_buf_desc_t *) */
229} drm32_buf_info_t;
230#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
231
232static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
233{
234 drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
235 drm_buf_desc_t *ulist;
236 drm_buf_info_t karg;
237 mm_segment_t old_fs;
238 int orig_count, ret;
239 u32 tmp;
240
241 if (get_user(karg.count, &uarg->count) ||
242 get_user(tmp, &uarg->list))
243 return -EFAULT;
244
245 ulist = (drm_buf_desc_t *) A(tmp);
246
247 orig_count = karg.count;
248
249 karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
250 if (!karg.list)
251 return -EFAULT;
252
253 old_fs = get_fs();
254 set_fs(KERNEL_DS);
255 ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
256 set_fs(old_fs);
257
258 if (!ret) {
259 if (karg.count <= orig_count &&
260 (copy_to_user(ulist, karg.list,
261 karg.count * sizeof(drm_buf_desc_t))))
262 ret = -EFAULT;
263 if (put_user(karg.count, &uarg->count))
264 ret = -EFAULT;
265 }
266
267 kfree(karg.list);
268
269 return ret;
270}
271
272typedef struct drm32_buf_free {
273 int count;
274 u32 list; /* (int *) */
275} drm32_buf_free_t;
276#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
277
278static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
279{
280 drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
281 drm_buf_free_t karg;
282 mm_segment_t old_fs;
283 int *ulist;
284 int ret;
285 u32 tmp;
286
287 if (get_user(karg.count, &uarg->count) ||
288 get_user(tmp, &uarg->list))
289 return -EFAULT;
290
291 ulist = (int *) A(tmp);
292
293 karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
294 if (!karg.list)
295 return -ENOMEM;
296
297 ret = -EFAULT;
298 if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
299 goto out;
300
301 old_fs = get_fs();
302 set_fs(KERNEL_DS);
303 ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
304 set_fs(old_fs);
305
306out:
307 kfree(karg.list);
308
309 return ret;
310}
311
312typedef struct drm32_buf_pub {
313 int idx; /* Index into master buflist */
314 int total; /* Buffer size */
315 int used; /* Amount of buffer in use (for DMA) */
316 u32 address; /* Address of buffer (void *) */
317} drm32_buf_pub_t;
318
319typedef struct drm32_buf_map {
320 int count; /* Length of buflist */
321 u32 virtual; /* Mmaped area in user-virtual (void *) */
322 u32 list; /* Buffer information (drm_buf_pub_t *) */
323} drm32_buf_map_t;
324#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
325
326static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
327{
328 drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
329 drm32_buf_pub_t *ulist;
330 drm_buf_map_t karg;
331 mm_segment_t old_fs;
332 int orig_count, ret, i;
333 u32 tmp1, tmp2;
334
335 if (get_user(karg.count, &uarg->count) ||
336 get_user(tmp1, &uarg->virtual) ||
337 get_user(tmp2, &uarg->list))
338 return -EFAULT;
339
340 karg.virtual = (void *) A(tmp1);
341 ulist = (drm32_buf_pub_t *) A(tmp2);
342
343 orig_count = karg.count;
344
345 karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
346 if (!karg.list)
347 return -ENOMEM;
348
349 ret = -EFAULT;
350 for (i = 0; i < karg.count; i++) {
351 if (get_user(karg.list[i].idx, &ulist[i].idx) ||
352 get_user(karg.list[i].total, &ulist[i].total) ||
353 get_user(karg.list[i].used, &ulist[i].used) ||
354 get_user(tmp1, &ulist[i].address))
355 goto out;
356
357 karg.list[i].address = (void *) A(tmp1);
358 }
359
360 old_fs = get_fs();
361 set_fs(KERNEL_DS);
362 ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
363 set_fs(old_fs);
364
365 if (!ret) {
366 for (i = 0; i < orig_count; i++) {
367 tmp1 = (u32) (long) karg.list[i].address;
368 if (put_user(karg.list[i].idx, &ulist[i].idx) ||
369 put_user(karg.list[i].total, &ulist[i].total) ||
370 put_user(karg.list[i].used, &ulist[i].used) ||
371 put_user(tmp1, &ulist[i].address)) {
372 ret = -EFAULT;
373 goto out;
374 }
375 }
376 if (put_user(karg.count, &uarg->count))
377 ret = -EFAULT;
378 }
379
380out:
381 kfree(karg.list);
382 return ret;
383}
384
385typedef struct drm32_dma {
386 /* Indices here refer to the offset into
387 buflist in drm_buf_get_t. */
388 int context; /* Context handle */
389 int send_count; /* Number of buffers to send */
390 u32 send_indices; /* List of handles to buffers (int *) */
391 u32 send_sizes; /* Lengths of data to send (int *) */
392 drm_dma_flags_t flags; /* Flags */
393 int request_count; /* Number of buffers requested */
394 int request_size; /* Desired size for buffers */
395 u32 request_indices; /* Buffer information (int *) */
396 u32 request_sizes; /* (int *) */
397 int granted_count; /* Number of buffers granted */
398} drm32_dma_t;
399#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
400
401/* RED PEN The DRM layer blindly dereferences the send/request
402 * indice/size arrays even though they are userland
403 * pointers. -DaveM
404 */
405static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
406{
407 drm32_dma_t *uarg = (drm32_dma_t *) arg;
408 int *u_si, *u_ss, *u_ri, *u_rs;
409 drm_dma_t karg;
410 mm_segment_t old_fs;
411 int ret;
412 u32 tmp1, tmp2, tmp3, tmp4;
413
414 karg.send_indices = karg.send_sizes = NULL;
415 karg.request_indices = karg.request_sizes = NULL;
416
417 if (get_user(karg.context, &uarg->context) ||
418 get_user(karg.send_count, &uarg->send_count) ||
419 get_user(tmp1, &uarg->send_indices) ||
420 get_user(tmp2, &uarg->send_sizes) ||
421 get_user(karg.flags, &uarg->flags) ||
422 get_user(karg.request_count, &uarg->request_count) ||
423 get_user(karg.request_size, &uarg->request_size) ||
424 get_user(tmp3, &uarg->request_indices) ||
425 get_user(tmp4, &uarg->request_sizes) ||
426 get_user(karg.granted_count, &uarg->granted_count))
427 return -EFAULT;
428
429 u_si = (int *) A(tmp1);
430 u_ss = (int *) A(tmp2);
431 u_ri = (int *) A(tmp3);
432 u_rs = (int *) A(tmp4);
433
434 if (karg.send_count) {
435 karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
436 karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
437
438 ret = -ENOMEM;
439 if (!karg.send_indices || !karg.send_sizes)
440 goto out;
441
442 ret = -EFAULT;
443 if (copy_from_user(karg.send_indices, u_si,
444 (karg.send_count * sizeof(int))) ||
445 copy_from_user(karg.send_sizes, u_ss,
446 (karg.send_count * sizeof(int))))
447 goto out;
448 }
449
450 if (karg.request_count) {
451 karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
452 karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
453
454 ret = -ENOMEM;
455 if (!karg.request_indices || !karg.request_sizes)
456 goto out;
457
458 ret = -EFAULT;
459 if (copy_from_user(karg.request_indices, u_ri,
460 (karg.request_count * sizeof(int))) ||
461 copy_from_user(karg.request_sizes, u_rs,
462 (karg.request_count * sizeof(int))))
463 goto out;
464 }
465
466 old_fs = get_fs();
467 set_fs(KERNEL_DS);
468 ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
469 set_fs(old_fs);
470
471 if (!ret) {
472 if (put_user(karg.context, &uarg->context) ||
473 put_user(karg.send_count, &uarg->send_count) ||
474 put_user(karg.flags, &uarg->flags) ||
475 put_user(karg.request_count, &uarg->request_count) ||
476 put_user(karg.request_size, &uarg->request_size) ||
477 put_user(karg.granted_count, &uarg->granted_count))
478 ret = -EFAULT;
479
480 if (karg.send_count) {
481 if (copy_to_user(u_si, karg.send_indices,
482 (karg.send_count * sizeof(int))) ||
483 copy_to_user(u_ss, karg.send_sizes,
484 (karg.send_count * sizeof(int))))
485 ret = -EFAULT;
486 }
487 if (karg.request_count) {
488 if (copy_to_user(u_ri, karg.request_indices,
489 (karg.request_count * sizeof(int))) ||
490 copy_to_user(u_rs, karg.request_sizes,
491 (karg.request_count * sizeof(int))))
492 ret = -EFAULT;
493 }
494 }
495
496out:
497 if (karg.send_indices)
498 kfree(karg.send_indices);
499 if (karg.send_sizes)
500 kfree(karg.send_sizes);
501 if (karg.request_indices)
502 kfree(karg.request_indices);
503 if (karg.request_sizes)
504 kfree(karg.request_sizes);
505
506 return ret;
507}
508
509typedef struct drm32_ctx_res {
510 int count;
511 u32 contexts; /* (drm_ctx_t *) */
512} drm32_ctx_res_t;
513#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
514
515static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
516{
517 drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
518 drm_ctx_t *ulist;
519 drm_ctx_res_t karg;
520 mm_segment_t old_fs;
521 int orig_count, ret;
522 u32 tmp;
523
524 karg.contexts = NULL;
525 if (get_user(karg.count, &uarg->count) ||
526 get_user(tmp, &uarg->contexts))
527 return -EFAULT;
528
529 ulist = (drm_ctx_t *) A(tmp);
530
531 orig_count = karg.count;
532 if (karg.count && ulist) {
533 karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
534 if (!karg.contexts)
535 return -ENOMEM;
536 if (copy_from_user(karg.contexts, ulist,
537 (karg.count * sizeof(drm_ctx_t)))) {
538 kfree(karg.contexts);
539 return -EFAULT;
540 }
541 }
542
543 old_fs = get_fs();
544 set_fs(KERNEL_DS);
545 ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
546 set_fs(old_fs);
547
548 if (!ret) {
549 if (orig_count) {
550 if (copy_to_user(ulist, karg.contexts,
551 (orig_count * sizeof(drm_ctx_t))))
552 ret = -EFAULT;
553 }
554 if (put_user(karg.count, &uarg->count))
555 ret = -EFAULT;
556 }
557
558 if (karg.contexts)
559 kfree(karg.contexts);
560
561 return ret;
562}
563
564#endif
565
566#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
567#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
568
569#define IOCTL_TABLE_START struct ioctl_trans ioctl_start[] = {
570#define IOCTL_TABLE_END };
571
572IOCTL_TABLE_START
573#include <linux/compat_ioctl.h>
574
575#define DECLARES
576#include "compat_ioctl.c"
577
578/* Might be moved to compat_ioctl.h with some ifdefs... */
579COMPATIBLE_IOCTL(TIOCSTART)
580COMPATIBLE_IOCTL(TIOCSTOP)
581COMPATIBLE_IOCTL(TIOCSLTC)
582
583/* PA-specific ioctls */
584COMPATIBLE_IOCTL(PA_PERF_ON)
585COMPATIBLE_IOCTL(PA_PERF_OFF)
586COMPATIBLE_IOCTL(PA_PERF_VERSION)
587
588/* And these ioctls need translation */
589HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
590HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
591HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
592
593#if defined(CONFIG_GEN_RTC)
594COMPATIBLE_IOCTL(RTC_AIE_ON)
595COMPATIBLE_IOCTL(RTC_AIE_OFF)
596COMPATIBLE_IOCTL(RTC_UIE_ON)
597COMPATIBLE_IOCTL(RTC_UIE_OFF)
598COMPATIBLE_IOCTL(RTC_PIE_ON)
599COMPATIBLE_IOCTL(RTC_PIE_OFF)
600COMPATIBLE_IOCTL(RTC_WIE_ON)
601COMPATIBLE_IOCTL(RTC_WIE_OFF)
602COMPATIBLE_IOCTL(RTC_ALM_SET) /* struct rtc_time only has ints */
603COMPATIBLE_IOCTL(RTC_ALM_READ) /* struct rtc_time only has ints */
604COMPATIBLE_IOCTL(RTC_RD_TIME) /* struct rtc_time only has ints */
605COMPATIBLE_IOCTL(RTC_SET_TIME) /* struct rtc_time only has ints */
606HANDLE_IOCTL(RTC_IRQP_READ, w_long)
607COMPATIBLE_IOCTL(RTC_IRQP_SET)
608HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
609COMPATIBLE_IOCTL(RTC_EPOCH_SET)
610#endif
611
612#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
613HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
614HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
615HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
616HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
617HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
618HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
619HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
620HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
621HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
622#endif /* DRM */
623IOCTL_TABLE_END
624
625int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
new file mode 100644
index 000000000000..006385dbee66
--- /dev/null
+++ b/arch/parisc/kernel/irq.c
@@ -0,0 +1,343 @@
1/*
2 * Code to handle x86 style IRQs plus some generic interrupt stuff.
3 *
4 * Copyright (C) 1992 Linus Torvalds
5 * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
6 * Copyright (C) 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org)
7 * Copyright (C) 1999-2000 Grant Grundler
8 * Copyright (c) 2005 Matthew Wilcox
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24#include <linux/bitops.h>
25#include <linux/config.h>
26#include <linux/errno.h>
27#include <linux/init.h>
28#include <linux/interrupt.h>
29#include <linux/kernel_stat.h>
30#include <linux/seq_file.h>
31#include <linux/spinlock.h>
32#include <linux/types.h>
33
34#undef PARISC_IRQ_CR16_COUNTS
35
36extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *);
37extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
38
39#define EIEM_MASK(irq) (1UL<<(CPU_IRQ_MAX - irq))
40
41/* Bits in EIEM correlate with cpu_irq_action[].
42** Numbered *Big Endian*! (ie bit 0 is MSB)
43*/
44static volatile unsigned long cpu_eiem = 0;
45
46static void cpu_set_eiem(void *info)
47{
48 set_eiem((unsigned long) info);
49}
50
51static inline void cpu_disable_irq(unsigned int irq)
52{
53 unsigned long eirr_bit = EIEM_MASK(irq);
54
55 cpu_eiem &= ~eirr_bit;
56 on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
57}
58
59static void cpu_enable_irq(unsigned int irq)
60{
61 unsigned long eirr_bit = EIEM_MASK(irq);
62
63 mtctl(eirr_bit, 23); /* clear EIRR bit before unmasking */
64 cpu_eiem |= eirr_bit;
65 on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
66}
67
68static unsigned int cpu_startup_irq(unsigned int irq)
69{
70 cpu_enable_irq(irq);
71 return 0;
72}
73
74void no_ack_irq(unsigned int irq) { }
75void no_end_irq(unsigned int irq) { }
76
77static struct hw_interrupt_type cpu_interrupt_type = {
78 .typename = "CPU",
79 .startup = cpu_startup_irq,
80 .shutdown = cpu_disable_irq,
81 .enable = cpu_enable_irq,
82 .disable = cpu_disable_irq,
83 .ack = no_ack_irq,
84 .end = no_end_irq,
85// .set_affinity = cpu_set_affinity_irq,
86};
87
88int show_interrupts(struct seq_file *p, void *v)
89{
90 int i = *(loff_t *) v, j;
91 unsigned long flags;
92
93 if (i == 0) {
94 seq_puts(p, " ");
95 for_each_online_cpu(j)
96 seq_printf(p, " CPU%d", j);
97
98#ifdef PARISC_IRQ_CR16_COUNTS
99 seq_printf(p, " [min/avg/max] (CPU cycle counts)");
100#endif
101 seq_putc(p, '\n');
102 }
103
104 if (i < NR_IRQS) {
105 struct irqaction *action;
106
107 spin_lock_irqsave(&irq_desc[i].lock, flags);
108 action = irq_desc[i].action;
109 if (!action)
110 goto skip;
111 seq_printf(p, "%3d: ", i);
112#ifdef CONFIG_SMP
113 for_each_online_cpu(j)
114 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
115#else
116 seq_printf(p, "%10u ", kstat_irqs(i));
117#endif
118
119 seq_printf(p, " %14s", irq_desc[i].handler->typename);
120#ifndef PARISC_IRQ_CR16_COUNTS
121 seq_printf(p, " %s", action->name);
122
123 while ((action = action->next))
124 seq_printf(p, ", %s", action->name);
125#else
126 for ( ;action; action = action->next) {
127 unsigned int k, avg, min, max;
128
129 min = max = action->cr16_hist[0];
130
131 for (avg = k = 0; k < PARISC_CR16_HIST_SIZE; k++) {
132 int hist = action->cr16_hist[k];
133
134 if (hist) {
135 avg += hist;
136 } else
137 break;
138
139 if (hist > max) max = hist;
140 if (hist < min) min = hist;
141 }
142
143 avg /= k;
144 seq_printf(p, " %s[%d/%d/%d]", action->name,
145 min,avg,max);
146 }
147#endif
148
149 seq_putc(p, '\n');
150 skip:
151 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
152 }
153
154 return 0;
155}
156
157
158
159/*
160** The following form a "set": Virtual IRQ, Transaction Address, Trans Data.
161** Respectively, these map to IRQ region+EIRR, Processor HPA, EIRR bit.
162**
163** To use txn_XXX() interfaces, get a Virtual IRQ first.
164** Then use that to get the Transaction address and data.
165*/
166
167int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data)
168{
169 if (irq_desc[irq].action)
170 return -EBUSY;
171 if (irq_desc[irq].handler != &cpu_interrupt_type)
172 return -EBUSY;
173
174 if (type) {
175 irq_desc[irq].handler = type;
176 irq_desc[irq].handler_data = data;
177 cpu_interrupt_type.enable(irq);
178 }
179 return 0;
180}
181
182int txn_claim_irq(int irq)
183{
184 return cpu_claim_irq(irq, NULL, NULL) ? -1 : irq;
185}
186
187/*
188 * The bits_wide parameter accommodates the limitations of the HW/SW which
189 * use these bits:
190 * Legacy PA I/O (GSC/NIO): 5 bits (architected EIM register)
191 * V-class (EPIC): 6 bits
192 * N/L/A-class (iosapic): 8 bits
193 * PCI 2.2 MSI: 16 bits
194 * Some PCI devices: 32 bits (Symbios SCSI/ATM/HyperFabric)
195 *
196 * On the service provider side:
197 * o PA 1.1 (and PA2.0 narrow mode) 5-bits (width of EIR register)
198 * o PA 2.0 wide mode 6-bits (per processor)
199 * o IA64 8-bits (0-256 total)
200 *
201 * So a Legacy PA I/O device on a PA 2.0 box can't use all the bits supported
202 * by the processor...and the N/L-class I/O subsystem supports more bits than
203 * PA2.0 has. The first case is the problem.
204 */
205int txn_alloc_irq(unsigned int bits_wide)
206{
207 int irq;
208
209 /* never return irq 0 cause that's the interval timer */
210 for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) {
211 if (cpu_claim_irq(irq, NULL, NULL) < 0)
212 continue;
213 if ((irq - CPU_IRQ_BASE) >= (1 << bits_wide))
214 continue;
215 return irq;
216 }
217
218 /* unlikely, but be prepared */
219 return -1;
220}
221
222unsigned long txn_alloc_addr(unsigned int virt_irq)
223{
224 static int next_cpu = -1;
225
226 next_cpu++; /* assign to "next" CPU we want this bugger on */
227
228 /* validate entry */
229 while ((next_cpu < NR_CPUS) && (!cpu_data[next_cpu].txn_addr ||
230 !cpu_online(next_cpu)))
231 next_cpu++;
232
233 if (next_cpu >= NR_CPUS)
234 next_cpu = 0; /* nothing else, assign monarch */
235
236 return cpu_data[next_cpu].txn_addr;
237}
238
239
240unsigned int txn_alloc_data(unsigned int virt_irq)
241{
242 return virt_irq - CPU_IRQ_BASE;
243}
244
245/* ONLY called from entry.S:intr_extint() */
246void do_cpu_irq_mask(struct pt_regs *regs)
247{
248 unsigned long eirr_val;
249
250 irq_enter();
251
252 /*
253 * Only allow interrupt processing to be interrupted by the
254 * timer tick
255 */
256 set_eiem(EIEM_MASK(TIMER_IRQ));
257
258 /* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
259 * 2) We loop here on EIRR contents in order to avoid
260 * nested interrupts or having to take another interrupt
261 * when we could have just handled it right away.
262 */
263 for (;;) {
264 unsigned long bit = (1UL << (BITS_PER_LONG - 1));
265 unsigned int irq;
266 eirr_val = mfctl(23) & cpu_eiem;
267 if (!eirr_val)
268 break;
269
270 if (eirr_val & EIEM_MASK(TIMER_IRQ))
271 set_eiem(0);
272
273 mtctl(eirr_val, 23); /* reset bits we are going to process */
274
275 /* Work our way from MSb to LSb...same order we alloc EIRs */
276 for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
277 if (!(bit & eirr_val))
278 continue;
279
280 /* clear bit in mask - can exit loop sooner */
281 eirr_val &= ~bit;
282
283 __do_IRQ(irq, regs);
284 }
285 }
286 set_eiem(cpu_eiem);
287 irq_exit();
288}
289
290
291static struct irqaction timer_action = {
292 .handler = timer_interrupt,
293 .name = "timer",
294};
295
296#ifdef CONFIG_SMP
297static struct irqaction ipi_action = {
298 .handler = ipi_interrupt,
299 .name = "IPI",
300};
301#endif
302
303static void claim_cpu_irqs(void)
304{
305 int i;
306 for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
307 irq_desc[i].handler = &cpu_interrupt_type;
308 }
309
310 irq_desc[TIMER_IRQ].action = &timer_action;
311 irq_desc[TIMER_IRQ].status |= IRQ_PER_CPU;
312#ifdef CONFIG_SMP
313 irq_desc[IPI_IRQ].action = &ipi_action;
314 irq_desc[IPI_IRQ].status = IRQ_PER_CPU;
315#endif
316}
317
318void __init init_IRQ(void)
319{
320 local_irq_disable(); /* PARANOID - should already be disabled */
321 mtctl(~0UL, 23); /* EIRR : clear all pending external intr */
322 claim_cpu_irqs();
323#ifdef CONFIG_SMP
324 if (!cpu_eiem)
325 cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ);
326#else
327 cpu_eiem = EIEM_MASK(TIMER_IRQ);
328#endif
329 set_eiem(cpu_eiem); /* EIEM : enable all external intr */
330
331}
332
333void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq)
334{
335 /* XXX: Needs to be written. We managed without it so far, but
336 * we really ought to write it.
337 */
338}
339
340void ack_bad_irq(unsigned int irq)
341{
342 printk("unexpected IRQ %d\n", irq);
343}
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
new file mode 100644
index 000000000000..f27cfe4771b8
--- /dev/null
+++ b/arch/parisc/kernel/module.c
@@ -0,0 +1,822 @@
1/* Kernel dynamically loadable module help for PARISC.
2 *
3 * The best reference for this stuff is probably the Processor-
4 * Specific ELF Supplement for PA-RISC:
5 * http://ftp.parisc-linux.org/docs/arch/elf-pa-hp.pdf
6 *
7 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
8 * Copyright (C) 2003 Randolph Chung <tausq at debian . org>
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 *
26 * Notes:
27 * - SEGREL32 handling
28 * We are not doing SEGREL32 handling correctly. According to the ABI, we
29 * should do a value offset, like this:
30 * if (is_init(me, (void *)val))
31 * val -= (uint32_t)me->module_init;
32 * else
33 * val -= (uint32_t)me->module_core;
34 * However, SEGREL32 is used only for PARISC unwind entries, and we want
35 * those entries to have an absolute address, and not just an offset.
36 *
37 * The unwind table mechanism has the ability to specify an offset for
38 * the unwind table; however, because we split off the init functions into
39 * a different piece of memory, it is not possible to do this using a
40 * single offset. Instead, we use the above hack for now.
41 */
42
43#include <linux/moduleloader.h>
44#include <linux/elf.h>
45#include <linux/vmalloc.h>
46#include <linux/fs.h>
47#include <linux/string.h>
48#include <linux/kernel.h>
49
50#include <asm/unwind.h>
51
52#if 0
53#define DEBUGP printk
54#else
55#define DEBUGP(fmt...)
56#endif
57
58#define CHECK_RELOC(val, bits) \
59 if ( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 ) || \
60 ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) { \
61 printk(KERN_ERR "module %s relocation of symbol %s is out of range (0x%lx in %d bits)\n", \
62 me->name, strtab + sym->st_name, (unsigned long)val, bits); \
63 return -ENOEXEC; \
64 }
65
66/* Maximum number of GOT entries. We use a long displacement ldd from
67 * the bottom of the table, which has a maximum signed displacement of
68 * 0x3fff; however, since we're only going forward, this becomes
69 * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have
70 * at most 1023 entries */
71#define MAX_GOTS 1023
72
73/* three functions to determine where in the module core
74 * or init pieces the location is */
75static inline int is_init(struct module *me, void *loc)
76{
77 return (loc >= me->module_init &&
78 loc <= (me->module_init + me->init_size));
79}
80
81static inline int is_core(struct module *me, void *loc)
82{
83 return (loc >= me->module_core &&
84 loc <= (me->module_core + me->core_size));
85}
86
87static inline int is_local(struct module *me, void *loc)
88{
89 return is_init(me, loc) || is_core(me, loc);
90}
91
92
93#ifndef __LP64__
94struct got_entry {
95 Elf32_Addr addr;
96};
97
98#define Elf_Fdesc Elf32_Fdesc
99
100struct stub_entry {
101 Elf32_Word insns[2]; /* each stub entry has two insns */
102};
103#else
104struct got_entry {
105 Elf64_Addr addr;
106};
107
108#define Elf_Fdesc Elf64_Fdesc
109
110struct stub_entry {
111 Elf64_Word insns[4]; /* each stub entry has four insns */
112};
113#endif
114
115/* Field selection types defined by hppa */
116#define rnd(x) (((x)+0x1000)&~0x1fff)
117/* fsel: full 32 bits */
118#define fsel(v,a) ((v)+(a))
119/* lsel: select left 21 bits */
120#define lsel(v,a) (((v)+(a))>>11)
121/* rsel: select right 11 bits */
122#define rsel(v,a) (((v)+(a))&0x7ff)
123/* lrsel with rounding of addend to nearest 8k */
124#define lrsel(v,a) (((v)+rnd(a))>>11)
125/* rrsel with rounding of addend to nearest 8k */
126#define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
127
128#define mask(x,sz) ((x) & ~((1<<(sz))-1))
129
130
131/* The reassemble_* functions prepare an immediate value for
132 insertion into an opcode. pa-risc uses all sorts of weird bitfields
133 in the instruction to hold the value. */
134static inline int reassemble_14(int as14)
135{
136 return (((as14 & 0x1fff) << 1) |
137 ((as14 & 0x2000) >> 13));
138}
139
140static inline int reassemble_17(int as17)
141{
142 return (((as17 & 0x10000) >> 16) |
143 ((as17 & 0x0f800) << 5) |
144 ((as17 & 0x00400) >> 8) |
145 ((as17 & 0x003ff) << 3));
146}
147
148static inline int reassemble_21(int as21)
149{
150 return (((as21 & 0x100000) >> 20) |
151 ((as21 & 0x0ffe00) >> 8) |
152 ((as21 & 0x000180) << 7) |
153 ((as21 & 0x00007c) << 14) |
154 ((as21 & 0x000003) << 12));
155}
156
157static inline int reassemble_22(int as22)
158{
159 return (((as22 & 0x200000) >> 21) |
160 ((as22 & 0x1f0000) << 5) |
161 ((as22 & 0x00f800) << 5) |
162 ((as22 & 0x000400) >> 8) |
163 ((as22 & 0x0003ff) << 3));
164}
165
166void *module_alloc(unsigned long size)
167{
168 if (size == 0)
169 return NULL;
170 return vmalloc(size);
171}
172
173#ifndef __LP64__
174static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
175{
176 return 0;
177}
178
179static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
180{
181 return 0;
182}
183
184static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
185{
186 unsigned long cnt = 0;
187
188 for (; n > 0; n--, rela++)
189 {
190 switch (ELF32_R_TYPE(rela->r_info)) {
191 case R_PARISC_PCREL17F:
192 case R_PARISC_PCREL22F:
193 cnt++;
194 }
195 }
196
197 return cnt;
198}
199#else
200static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
201{
202 unsigned long cnt = 0;
203
204 for (; n > 0; n--, rela++)
205 {
206 switch (ELF64_R_TYPE(rela->r_info)) {
207 case R_PARISC_LTOFF21L:
208 case R_PARISC_LTOFF14R:
209 case R_PARISC_PCREL22F:
210 cnt++;
211 }
212 }
213
214 return cnt;
215}
216
217static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
218{
219 unsigned long cnt = 0;
220
221 for (; n > 0; n--, rela++)
222 {
223 switch (ELF64_R_TYPE(rela->r_info)) {
224 case R_PARISC_FPTR64:
225 cnt++;
226 }
227 }
228
229 return cnt;
230}
231
232static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
233{
234 unsigned long cnt = 0;
235
236 for (; n > 0; n--, rela++)
237 {
238 switch (ELF64_R_TYPE(rela->r_info)) {
239 case R_PARISC_PCREL22F:
240 cnt++;
241 }
242 }
243
244 return cnt;
245}
246#endif
247
248
249/* Free memory returned from module_alloc */
250void module_free(struct module *mod, void *module_region)
251{
252 vfree(module_region);
253 /* FIXME: If module_region == mod->init_region, trim exception
254 table entries. */
255}
256
257#define CONST
258int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
259 CONST Elf_Shdr *sechdrs,
260 CONST char *secstrings,
261 struct module *me)
262{
263 unsigned long gots = 0, fdescs = 0, stubs = 0, init_stubs = 0;
264 unsigned int i;
265
266 for (i = 1; i < hdr->e_shnum; i++) {
267 const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset;
268 unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
269
270 if (strncmp(secstrings + sechdrs[i].sh_name,
271 ".PARISC.unwind", 14) == 0)
272 me->arch.unwind_section = i;
273
274 if (sechdrs[i].sh_type != SHT_RELA)
275 continue;
276
277 /* some of these are not relevant for 32-bit/64-bit
278 * we leave them here to make the code common. the
279 * compiler will do its thing and optimize out the
280 * stuff we don't need
281 */
282 gots += count_gots(rels, nrels);
283 fdescs += count_fdescs(rels, nrels);
284 if(strncmp(secstrings + sechdrs[i].sh_name,
285 ".rela.init", 10) == 0)
286 init_stubs += count_stubs(rels, nrels);
287 else
288 stubs += count_stubs(rels, nrels);
289 }
290
291 /* align things a bit */
292 me->core_size = ALIGN(me->core_size, 16);
293 me->arch.got_offset = me->core_size;
294 me->core_size += gots * sizeof(struct got_entry);
295
296 me->core_size = ALIGN(me->core_size, 16);
297 me->arch.fdesc_offset = me->core_size;
298 me->core_size += fdescs * sizeof(Elf_Fdesc);
299
300 me->core_size = ALIGN(me->core_size, 16);
301 me->arch.stub_offset = me->core_size;
302 me->core_size += stubs * sizeof(struct stub_entry);
303
304 me->init_size = ALIGN(me->init_size, 16);
305 me->arch.init_stub_offset = me->init_size;
306 me->init_size += init_stubs * sizeof(struct stub_entry);
307
308 me->arch.got_max = gots;
309 me->arch.fdesc_max = fdescs;
310 me->arch.stub_max = stubs;
311 me->arch.init_stub_max = init_stubs;
312
313 return 0;
314}
315
316#ifdef __LP64__
317static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
318{
319 unsigned int i;
320 struct got_entry *got;
321
322 value += addend;
323
324 BUG_ON(value == 0);
325
326 got = me->module_core + me->arch.got_offset;
327 for (i = 0; got[i].addr; i++)
328 if (got[i].addr == value)
329 goto out;
330
331 BUG_ON(++me->arch.got_count > me->arch.got_max);
332
333 got[i].addr = value;
334 out:
335 DEBUGP("GOT ENTRY %d[%x] val %lx\n", i, i*sizeof(struct got_entry),
336 value);
337 return i * sizeof(struct got_entry);
338}
339#endif /* __LP64__ */
340
341#ifdef __LP64__
342static Elf_Addr get_fdesc(struct module *me, unsigned long value)
343{
344 Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
345
346 if (!value) {
347 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
348 return 0;
349 }
350
351 /* Look for existing fdesc entry. */
352 while (fdesc->addr) {
353 if (fdesc->addr == value)
354 return (Elf_Addr)fdesc;
355 fdesc++;
356 }
357
358 BUG_ON(++me->arch.fdesc_count > me->arch.fdesc_max);
359
360 /* Create new one */
361 fdesc->addr = value;
362 fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
363 return (Elf_Addr)fdesc;
364}
365#endif /* __LP64__ */
366
367static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
368 int millicode, int init_section)
369{
370 unsigned long i;
371 struct stub_entry *stub;
372
373 if(init_section) {
374 i = me->arch.init_stub_count++;
375 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
376 stub = me->module_init + me->arch.init_stub_offset +
377 i * sizeof(struct stub_entry);
378 } else {
379 i = me->arch.stub_count++;
380 BUG_ON(me->arch.stub_count > me->arch.stub_max);
381 stub = me->module_core + me->arch.stub_offset +
382 i * sizeof(struct stub_entry);
383 }
384
385#ifndef __LP64__
386/* for 32-bit the stub looks like this:
387 * ldil L'XXX,%r1
388 * be,n R'XXX(%sr4,%r1)
389 */
390 //value = *(unsigned long *)((value + addend) & ~3); /* why? */
391
392 stub->insns[0] = 0x20200000; /* ldil L'XXX,%r1 */
393 stub->insns[1] = 0xe0202002; /* be,n R'XXX(%sr4,%r1) */
394
395 stub->insns[0] |= reassemble_21(lrsel(value, addend));
396 stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
397
398#else
399/* for 64-bit we have two kinds of stubs:
400 * for normal function calls:
401 * ldd 0(%dp),%dp
402 * ldd 10(%dp), %r1
403 * bve (%r1)
404 * ldd 18(%dp), %dp
405 *
406 * for millicode:
407 * ldil 0, %r1
408 * ldo 0(%r1), %r1
409 * ldd 10(%r1), %r1
410 * bve,n (%r1)
411 */
412 if (!millicode)
413 {
414 stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */
415 stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */
416 stub->insns[2] = 0xe820d000; /* bve (%r1) */
417 stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */
418
419 stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
420 }
421 else
422 {
423 stub->insns[0] = 0x20200000; /* ldil 0,%r1 */
424 stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */
425 stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */
426 stub->insns[3] = 0xe820d002; /* bve,n (%r1) */
427
428 stub->insns[0] |= reassemble_21(lrsel(value, addend));
429 stub->insns[1] |= reassemble_14(rrsel(value, addend));
430 }
431#endif
432
433 return (Elf_Addr)stub;
434}
435
436int apply_relocate(Elf_Shdr *sechdrs,
437 const char *strtab,
438 unsigned int symindex,
439 unsigned int relsec,
440 struct module *me)
441{
442 /* parisc should not need this ... */
443 printk(KERN_ERR "module %s: RELOCATION unsupported\n",
444 me->name);
445 return -ENOEXEC;
446}
447
448#ifndef __LP64__
449int apply_relocate_add(Elf_Shdr *sechdrs,
450 const char *strtab,
451 unsigned int symindex,
452 unsigned int relsec,
453 struct module *me)
454{
455 int i;
456 Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
457 Elf32_Sym *sym;
458 Elf32_Word *loc;
459 Elf32_Addr val;
460 Elf32_Sword addend;
461 Elf32_Addr dot;
462 //unsigned long dp = (unsigned long)$global$;
463 register unsigned long dp asm ("r27");
464
465 DEBUGP("Applying relocate section %u to %u\n", relsec,
466 sechdrs[relsec].sh_info);
467 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
468 /* This is where to make the change */
469 loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
470 + rel[i].r_offset;
471 /* This is the symbol it is referring to */
472 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
473 + ELF32_R_SYM(rel[i].r_info);
474 if (!sym->st_value) {
475 printk(KERN_WARNING "%s: Unknown symbol %s\n",
476 me->name, strtab + sym->st_name);
477 return -ENOENT;
478 }
479 //dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
480 dot = (Elf32_Addr)loc & ~0x03;
481
482 val = sym->st_value;
483 addend = rel[i].r_addend;
484
485#if 0
486#define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t :
487 DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
488 strtab + sym->st_name,
489 (uint32_t)loc, val, addend,
490 r(R_PARISC_PLABEL32)
491 r(R_PARISC_DIR32)
492 r(R_PARISC_DIR21L)
493 r(R_PARISC_DIR14R)
494 r(R_PARISC_SEGREL32)
495 r(R_PARISC_DPREL21L)
496 r(R_PARISC_DPREL14R)
497 r(R_PARISC_PCREL17F)
498 r(R_PARISC_PCREL22F)
499 "UNKNOWN");
500#undef r
501#endif
502
503 switch (ELF32_R_TYPE(rel[i].r_info)) {
504 case R_PARISC_PLABEL32:
505 /* 32-bit function address */
506 /* no function descriptors... */
507 *loc = fsel(val, addend);
508 break;
509 case R_PARISC_DIR32:
510 /* direct 32-bit ref */
511 *loc = fsel(val, addend);
512 break;
513 case R_PARISC_DIR21L:
514 /* left 21 bits of effective address */
515 val = lrsel(val, addend);
516 *loc = mask(*loc, 21) | reassemble_21(val);
517 break;
518 case R_PARISC_DIR14R:
519 /* right 14 bits of effective address */
520 val = rrsel(val, addend);
521 *loc = mask(*loc, 14) | reassemble_14(val);
522 break;
523 case R_PARISC_SEGREL32:
524 /* 32-bit segment relative address */
525 /* See note about special handling of SEGREL32 at
526 * the beginning of this file.
527 */
528 *loc = fsel(val, addend);
529 break;
530 case R_PARISC_DPREL21L:
531 /* left 21 bit of relative address */
532 val = lrsel(val - dp, addend);
533 *loc = mask(*loc, 21) | reassemble_21(val);
534 break;
535 case R_PARISC_DPREL14R:
536 /* right 14 bit of relative address */
537 val = rrsel(val - dp, addend);
538 *loc = mask(*loc, 14) | reassemble_14(val);
539 break;
540 case R_PARISC_PCREL17F:
541 /* 17-bit PC relative address */
542 val = get_stub(me, val, addend, 0, is_init(me, loc));
543 val = (val - dot - 8)/4;
544 CHECK_RELOC(val, 17)
545 *loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
546 break;
547 case R_PARISC_PCREL22F:
548 /* 22-bit PC relative address; only defined for pa20 */
549 val = get_stub(me, val, addend, 0, is_init(me, loc));
550 DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n",
551 strtab + sym->st_name, (unsigned long)loc, addend,
552 val)
553 val = (val - dot - 8)/4;
554 CHECK_RELOC(val, 22);
555 *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
556 break;
557
558 default:
559 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
560 me->name, ELF32_R_TYPE(rel[i].r_info));
561 return -ENOEXEC;
562 }
563 }
564
565 return 0;
566}
567
568#else
569int apply_relocate_add(Elf_Shdr *sechdrs,
570 const char *strtab,
571 unsigned int symindex,
572 unsigned int relsec,
573 struct module *me)
574{
575 int i;
576 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
577 Elf64_Sym *sym;
578 Elf64_Word *loc;
579 Elf64_Xword *loc64;
580 Elf64_Addr val;
581 Elf64_Sxword addend;
582 Elf64_Addr dot;
583
584 DEBUGP("Applying relocate section %u to %u\n", relsec,
585 sechdrs[relsec].sh_info);
586 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
587 /* This is where to make the change */
588 loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
589 + rel[i].r_offset;
590 /* This is the symbol it is referring to */
591 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
592 + ELF64_R_SYM(rel[i].r_info);
593 if (!sym->st_value) {
594 printk(KERN_WARNING "%s: Unknown symbol %s\n",
595 me->name, strtab + sym->st_name);
596 return -ENOENT;
597 }
598 //dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
599 dot = (Elf64_Addr)loc & ~0x03;
600 loc64 = (Elf64_Xword *)loc;
601
602 val = sym->st_value;
603 addend = rel[i].r_addend;
604
605#if 0
606#define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t :
607 printk("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n",
608 strtab + sym->st_name,
609 loc, val, addend,
610 r(R_PARISC_LTOFF14R)
611 r(R_PARISC_LTOFF21L)
612 r(R_PARISC_PCREL22F)
613 r(R_PARISC_DIR64)
614 r(R_PARISC_SEGREL32)
615 r(R_PARISC_FPTR64)
616 "UNKNOWN");
617#undef r
618#endif
619
620 switch (ELF64_R_TYPE(rel[i].r_info)) {
621 case R_PARISC_LTOFF21L:
622 /* LT-relative; left 21 bits */
623 val = get_got(me, val, addend);
624 DEBUGP("LTOFF21L Symbol %s loc %p val %lx\n",
625 strtab + sym->st_name,
626 loc, val);
627 val = lrsel(val, 0);
628 *loc = mask(*loc, 21) | reassemble_21(val);
629 break;
630 case R_PARISC_LTOFF14R:
631 /* L(ltoff(val+addend)) */
632 /* LT-relative; right 14 bits */
633 val = get_got(me, val, addend);
634 val = rrsel(val, 0);
635 DEBUGP("LTOFF14R Symbol %s loc %p val %lx\n",
636 strtab + sym->st_name,
637 loc, val);
638 *loc = mask(*loc, 14) | reassemble_14(val);
639 break;
640 case R_PARISC_PCREL22F:
641 /* PC-relative; 22 bits */
642 DEBUGP("PCREL22F Symbol %s loc %p val %lx\n",
643 strtab + sym->st_name,
644 loc, val);
645 /* can we reach it locally? */
646 if(!is_local(me, (void *)val)) {
647 if (strncmp(strtab + sym->st_name, "$$", 2)
648 == 0)
649 val = get_stub(me, val, addend, 1,
650 is_init(me, loc));
651 else
652 val = get_stub(me, val, addend, 0,
653 is_init(me, loc));
654 }
655 DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",
656 strtab + sym->st_name, loc, sym->st_value,
657 addend, val);
658 /* FIXME: local symbols work as long as the
659 * core and init pieces aren't separated too
660 * far. If this is ever broken, you will trip
661 * the check below. The way to fix it would
662 * be to generate local stubs to go between init
663 * and core */
664 if((Elf64_Sxword)(val - dot - 8) > 0x800000 -1 ||
665 (Elf64_Sxword)(val - dot - 8) < -0x800000) {
666 printk(KERN_ERR "Module %s, symbol %s is out of range for PCREL22F relocation\n",
667 me->name, strtab + sym->st_name);
668 return -ENOEXEC;
669 }
670 val = (val - dot - 8)/4;
671 *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
672 break;
673 case R_PARISC_DIR64:
674 /* 64-bit effective address */
675 *loc64 = val + addend;
676 break;
677 case R_PARISC_SEGREL32:
678 /* 32-bit segment relative address */
679 /* See note about special handling of SEGREL32 at
680 * the beginning of this file.
681 */
682 *loc = fsel(val, addend);
683 break;
684 case R_PARISC_FPTR64:
685 /* 64-bit function address */
686 if(is_local(me, (void *)(val + addend))) {
687 *loc64 = get_fdesc(me, val+addend);
688 DEBUGP("FDESC for %s at %p points to %lx\n",
689 strtab + sym->st_name, *loc64,
690 ((Elf_Fdesc *)*loc64)->addr);
691 } else {
692 /* if the symbol is not local to this
693 * module then val+addend is a pointer
694 * to the function descriptor */
695 DEBUGP("Non local FPTR64 Symbol %s loc %p val %lx\n",
696 strtab + sym->st_name,
697 loc, val);
698 *loc64 = val + addend;
699 }
700 break;
701
702 default:
703 printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
704 me->name, ELF64_R_TYPE(rel[i].r_info));
705 return -ENOEXEC;
706 }
707 }
708 return 0;
709}
710#endif
711
712static void
713register_unwind_table(struct module *me,
714 const Elf_Shdr *sechdrs)
715{
716 unsigned char *table, *end;
717 unsigned long gp;
718
719 if (!me->arch.unwind_section)
720 return;
721
722 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
723 end = table + sechdrs[me->arch.unwind_section].sh_size;
724 gp = (Elf_Addr)me->module_core + me->arch.got_offset;
725
726 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
727 me->arch.unwind_section, table, end, gp);
728 me->arch.unwind = unwind_table_add(me->name, 0, gp, table, end);
729}
730
731static void
732deregister_unwind_table(struct module *me)
733{
734 if (me->arch.unwind)
735 unwind_table_remove(me->arch.unwind);
736}
737
738int module_finalize(const Elf_Ehdr *hdr,
739 const Elf_Shdr *sechdrs,
740 struct module *me)
741{
742 int i;
743 unsigned long nsyms;
744 const char *strtab = NULL;
745 Elf_Sym *newptr, *oldptr;
746 Elf_Shdr *symhdr = NULL;
747#ifdef DEBUG
748 Elf_Fdesc *entry;
749 u32 *addr;
750
751 entry = (Elf_Fdesc *)me->init;
752 printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry,
753 entry->gp, entry->addr);
754 addr = (u32 *)entry->addr;
755 printk("INSNS: %x %x %x %x\n",
756 addr[0], addr[1], addr[2], addr[3]);
757 printk("stubs used %ld, stubs max %ld\n"
758 "init_stubs used %ld, init stubs max %ld\n"
759 "got entries used %ld, gots max %ld\n"
760 "fdescs used %ld, fdescs max %ld\n",
761 me->arch.stub_count, me->arch.stub_max,
762 me->arch.init_stub_count, me->arch.init_stub_max,
763 me->arch.got_count, me->arch.got_max,
764 me->arch.fdesc_count, me->arch.fdesc_max);
765#endif
766
767 register_unwind_table(me, sechdrs);
768
769 /* haven't filled in me->symtab yet, so have to find it
770 * ourselves */
771 for (i = 1; i < hdr->e_shnum; i++) {
772 if(sechdrs[i].sh_type == SHT_SYMTAB
773 && (sechdrs[i].sh_type & SHF_ALLOC)) {
774 int strindex = sechdrs[i].sh_link;
775 /* FIXME: AWFUL HACK
776 * The cast is to drop the const from
777 * the sechdrs pointer */
778 symhdr = (Elf_Shdr *)&sechdrs[i];
779 strtab = (char *)sechdrs[strindex].sh_addr;
780 break;
781 }
782 }
783
784 DEBUGP("module %s: strtab %p, symhdr %p\n",
785 me->name, strtab, symhdr);
786
787 if(me->arch.got_count > MAX_GOTS) {
788 printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d\n", me->name, me->arch.got_count, MAX_GOTS);
789 return -EINVAL;
790 }
791
792 /* no symbol table */
793 if(symhdr == NULL)
794 return 0;
795
796 oldptr = (void *)symhdr->sh_addr;
797 newptr = oldptr + 1; /* we start counting at 1 */
798 nsyms = symhdr->sh_size / sizeof(Elf_Sym);
799 DEBUGP("OLD num_symtab %lu\n", nsyms);
800
801 for (i = 1; i < nsyms; i++) {
802 oldptr++; /* note, count starts at 1 so preincrement */
803 if(strncmp(strtab + oldptr->st_name,
804 ".L", 2) == 0)
805 continue;
806
807 if(newptr != oldptr)
808 *newptr++ = *oldptr;
809 else
810 newptr++;
811
812 }
813 nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
814 DEBUGP("NEW num_symtab %lu\n", nsyms);
815 symhdr->sh_size = nsyms * sizeof(Elf_Sym);
816 return 0;
817}
818
819void module_arch_cleanup(struct module *mod)
820{
821 deregister_unwind_table(mod);
822}
diff --git a/arch/parisc/kernel/pa7300lc.c b/arch/parisc/kernel/pa7300lc.c
new file mode 100644
index 000000000000..8a89780223aa
--- /dev/null
+++ b/arch/parisc/kernel/pa7300lc.c
@@ -0,0 +1,49 @@
1/*
2 * linux/arch/parisc/kernel/pa7300lc.c
3 * - PA7300LC-specific functions
4 *
5 * Copyright (C) 2000 Philipp Rumpf */
6
7#include <linux/sched.h>
8#include <linux/smp.h>
9#include <linux/kernel.h>
10#include <asm/io.h>
11#include <asm/ptrace.h>
12#include <asm/machdep.h>
13
14/* CPU register indices */
15
16#define MIOC_STATUS 0xf040
17#define MIOC_CONTROL 0xf080
18#define MDERRADD 0xf0e0
19#define DMAERR 0xf0e8
20#define DIOERR 0xf0ec
21#define HIDMAMEM 0xf0f4
22
23/* this returns the HPA of the CPU it was called on */
24static u32 cpu_hpa(void)
25{
26 return 0xfffb0000;
27}
28
29static void pa7300lc_lpmc(int code, struct pt_regs *regs)
30{
31 u32 hpa;
32 printk(KERN_WARNING "LPMC on CPU %d\n", smp_processor_id());
33
34 show_regs(regs);
35
36 hpa = cpu_hpa();
37 printk(KERN_WARNING
38 "MIOC_CONTROL %08x\n" "MIOC_STATUS %08x\n"
39 "MDERRADD %08x\n" "DMAERR %08x\n"
40 "DIOERR %08x\n" "HIDMAMEM %08x\n",
41 gsc_readl(hpa+MIOC_CONTROL), gsc_readl(hpa+MIOC_STATUS),
42 gsc_readl(hpa+MDERRADD), gsc_readl(hpa+DMAERR),
43 gsc_readl(hpa+DIOERR), gsc_readl(hpa+HIDMAMEM));
44}
45
46void pa7300lc_init(void)
47{
48 cpu_lpmc = pa7300lc_lpmc;
49}
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
new file mode 100644
index 000000000000..77e03bc0f935
--- /dev/null
+++ b/arch/parisc/kernel/pacache.S
@@ -0,0 +1,1086 @@
1/*
2 * PARISC TLB and cache flushing support
3 * Copyright (C) 2000-2001 Hewlett-Packard (John Marvin)
4 * Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org)
5 * Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/*
23 * NOTE: fdc,fic, and pdc instructions that use base register modification
24 * should only use index and base registers that are not shadowed,
25 * so that the fast path emulation in the non access miss handler
26 * can be used.
27 */
28
29#ifdef __LP64__
30#define ADDIB addib,*
31#define CMPB cmpb,*
32#define ANDCM andcm,*
33
34 .level 2.0w
35#else
36#define ADDIB addib,
37#define CMPB cmpb,
38#define ANDCM andcm
39
40 .level 2.0
41#endif
42
43#include <asm/assembly.h>
44#include <asm/psw.h>
45#include <asm/pgtable.h>
46#include <asm/cache.h>
47
48 .text
49 .align 128
50
51 .export flush_tlb_all_local,code
52
53flush_tlb_all_local:
54 .proc
55 .callinfo NO_CALLS
56 .entry
57
58 /*
59 * The pitlbe and pdtlbe instructions should only be used to
60 * flush the entire tlb. Also, there needs to be no intervening
61 * tlb operations, e.g. tlb misses, so the operation needs
62 * to happen in real mode with all interruptions disabled.
63 */
64
65 /*
66 * Once again, we do the rfi dance ... some day we need examine
67 * all of our uses of this type of code and see what can be
68 * consolidated.
69 */
70
71 rsm PSW_SM_I, %r19 /* relied upon translation! PA 2.0 Arch. F-5 */
72 nop
73 nop
74 nop
75 nop
76 nop
77 nop
78 nop
79
80 rsm PSW_SM_Q, %r0 /* Turn off Q bit to load iia queue */
81 ldil L%REAL_MODE_PSW, %r1
82 ldo R%REAL_MODE_PSW(%r1), %r1
83 mtctl %r1, %cr22
84 mtctl %r0, %cr17 /* Clear IIASQ tail */
85 mtctl %r0, %cr17 /* Clear IIASQ head */
86 ldil L%PA(1f), %r1
87 ldo R%PA(1f)(%r1), %r1
88 mtctl %r1, %cr18 /* IIAOQ head */
89 ldo 4(%r1), %r1
90 mtctl %r1, %cr18 /* IIAOQ tail */
91 rfi
92 nop
93
941: ldil L%PA(cache_info), %r1
95 ldo R%PA(cache_info)(%r1), %r1
96
97 /* Flush Instruction Tlb */
98
99 LDREG ITLB_SID_BASE(%r1), %r20
100 LDREG ITLB_SID_STRIDE(%r1), %r21
101 LDREG ITLB_SID_COUNT(%r1), %r22
102 LDREG ITLB_OFF_BASE(%r1), %arg0
103 LDREG ITLB_OFF_STRIDE(%r1), %arg1
104 LDREG ITLB_OFF_COUNT(%r1), %arg2
105 LDREG ITLB_LOOP(%r1), %arg3
106
107 ADDIB= -1, %arg3, fitoneloop /* Preadjust and test */
108 movb,<,n %arg3, %r31, fitdone /* If loop < 0, skip */
109 copy %arg0, %r28 /* Init base addr */
110
111fitmanyloop: /* Loop if LOOP >= 2 */
112 mtsp %r20, %sr1
113 add %r21, %r20, %r20 /* increment space */
114 copy %arg2, %r29 /* Init middle loop count */
115
116fitmanymiddle: /* Loop if LOOP >= 2 */
117 ADDIB> -1, %r31, fitmanymiddle /* Adjusted inner loop decr */
118 pitlbe 0(%sr1, %r28)
119 pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */
120 ADDIB> -1, %r29, fitmanymiddle /* Middle loop decr */
121 copy %arg3, %r31 /* Re-init inner loop count */
122
123 movb,tr %arg0, %r28, fitmanyloop /* Re-init base addr */
124 ADDIB<=,n -1, %r22, fitdone /* Outer loop count decr */
125
126fitoneloop: /* Loop if LOOP = 1 */
127 mtsp %r20, %sr1
128 copy %arg0, %r28 /* init base addr */
129 copy %arg2, %r29 /* init middle loop count */
130
131fitonemiddle: /* Loop if LOOP = 1 */
132 ADDIB> -1, %r29, fitonemiddle /* Middle loop count decr */
133 pitlbe,m %arg1(%sr1, %r28) /* pitlbe for one loop */
134
135 ADDIB> -1, %r22, fitoneloop /* Outer loop count decr */
136 add %r21, %r20, %r20 /* increment space */
137
138fitdone:
139
140 /* Flush Data Tlb */
141
142 LDREG DTLB_SID_BASE(%r1), %r20
143 LDREG DTLB_SID_STRIDE(%r1), %r21
144 LDREG DTLB_SID_COUNT(%r1), %r22
145 LDREG DTLB_OFF_BASE(%r1), %arg0
146 LDREG DTLB_OFF_STRIDE(%r1), %arg1
147 LDREG DTLB_OFF_COUNT(%r1), %arg2
148 LDREG DTLB_LOOP(%r1), %arg3
149
150 ADDIB= -1, %arg3, fdtoneloop /* Preadjust and test */
151 movb,<,n %arg3, %r31, fdtdone /* If loop < 0, skip */
152 copy %arg0, %r28 /* Init base addr */
153
154fdtmanyloop: /* Loop if LOOP >= 2 */
155 mtsp %r20, %sr1
156 add %r21, %r20, %r20 /* increment space */
157 copy %arg2, %r29 /* Init middle loop count */
158
159fdtmanymiddle: /* Loop if LOOP >= 2 */
160 ADDIB> -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */
161 pdtlbe 0(%sr1, %r28)
162 pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */
163 ADDIB> -1, %r29, fdtmanymiddle /* Middle loop decr */
164 copy %arg3, %r31 /* Re-init inner loop count */
165
166 movb,tr %arg0, %r28, fdtmanyloop /* Re-init base addr */
167 ADDIB<=,n -1, %r22,fdtdone /* Outer loop count decr */
168
169fdtoneloop: /* Loop if LOOP = 1 */
170 mtsp %r20, %sr1
171 copy %arg0, %r28 /* init base addr */
172 copy %arg2, %r29 /* init middle loop count */
173
174fdtonemiddle: /* Loop if LOOP = 1 */
175 ADDIB> -1, %r29, fdtonemiddle /* Middle loop count decr */
176 pdtlbe,m %arg1(%sr1, %r28) /* pdtlbe for one loop */
177
178 ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */
179 add %r21, %r20, %r20 /* increment space */
180
181fdtdone:
182
183 /* Switch back to virtual mode */
184
185 rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */
186 ldil L%KERNEL_PSW, %r1
187 ldo R%KERNEL_PSW(%r1), %r1
188 or %r1, %r19, %r1 /* Set I bit if set on entry */
189 mtctl %r1, %cr22
190 mtctl %r0, %cr17 /* Clear IIASQ tail */
191 mtctl %r0, %cr17 /* Clear IIASQ head */
192 ldil L%(2f), %r1
193 ldo R%(2f)(%r1), %r1
194 mtctl %r1, %cr18 /* IIAOQ head */
195 ldo 4(%r1), %r1
196 mtctl %r1, %cr18 /* IIAOQ tail */
197 rfi
198 nop
199
2002: bv %r0(%r2)
201 nop
202 .exit
203
204 .procend
205
206 .export flush_instruction_cache_local,code
207 .import cache_info,data
208
209flush_instruction_cache_local:
210 .proc
211 .callinfo NO_CALLS
212 .entry
213
214 mtsp %r0, %sr1
215 ldil L%cache_info, %r1
216 ldo R%cache_info(%r1), %r1
217
218 /* Flush Instruction Cache */
219
220 LDREG ICACHE_BASE(%r1), %arg0
221 LDREG ICACHE_STRIDE(%r1), %arg1
222 LDREG ICACHE_COUNT(%r1), %arg2
223 LDREG ICACHE_LOOP(%r1), %arg3
224 rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/
225 ADDIB= -1, %arg3, fioneloop /* Preadjust and test */
226 movb,<,n %arg3, %r31, fisync /* If loop < 0, do sync */
227
228fimanyloop: /* Loop if LOOP >= 2 */
229 ADDIB> -1, %r31, fimanyloop /* Adjusted inner loop decr */
230 fice 0(%sr1, %arg0)
231 fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */
232 movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */
233 ADDIB<=,n -1, %arg2, fisync /* Outer loop decr */
234
235fioneloop: /* Loop if LOOP = 1 */
236 ADDIB> -1, %arg2, fioneloop /* Outer loop count decr */
237 fice,m %arg1(%sr1, %arg0) /* Fice for one loop */
238
239fisync:
240 sync
241 mtsm %r22
242 bv %r0(%r2)
243 nop
244 .exit
245
246 .procend
247
248 .export flush_data_cache_local, code
249 .import cache_info, data
250
251flush_data_cache_local:
252 .proc
253 .callinfo NO_CALLS
254 .entry
255
256 mtsp %r0, %sr1
257 ldil L%cache_info, %r1
258 ldo R%cache_info(%r1), %r1
259
260 /* Flush Data Cache */
261
262 LDREG DCACHE_BASE(%r1), %arg0
263 LDREG DCACHE_STRIDE(%r1), %arg1
264 LDREG DCACHE_COUNT(%r1), %arg2
265 LDREG DCACHE_LOOP(%r1), %arg3
266 rsm PSW_SM_I, %r22
267 ADDIB= -1, %arg3, fdoneloop /* Preadjust and test */
268 movb,<,n %arg3, %r31, fdsync /* If loop < 0, do sync */
269
270fdmanyloop: /* Loop if LOOP >= 2 */
271 ADDIB> -1, %r31, fdmanyloop /* Adjusted inner loop decr */
272 fdce 0(%sr1, %arg0)
273 fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */
274 movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */
275 ADDIB<=,n -1, %arg2, fdsync /* Outer loop decr */
276
277fdoneloop: /* Loop if LOOP = 1 */
278 ADDIB> -1, %arg2, fdoneloop /* Outer loop count decr */
279 fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */
280
281fdsync:
282 syncdma
283 sync
284 mtsm %r22
285 bv %r0(%r2)
286 nop
287 .exit
288
289 .procend
290
291 .export copy_user_page_asm,code
292 .align 16
293
294copy_user_page_asm:
295 .proc
296 .callinfo NO_CALLS
297 .entry
298
299#ifdef __LP64__
300 /* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
301 * Unroll the loop by hand and arrange insn appropriately.
302 * GCC probably can do this just as well.
303 */
304
305 ldd 0(%r25), %r19
306 ldi 32, %r1 /* PAGE_SIZE/128 == 32 */
307 ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */
308 ldw 128(%r25), %r0 /* prefetch 2 */
309
3101: ldd 8(%r25), %r20
311 ldw 192(%r25), %r0 /* prefetch 3 */
312 ldw 256(%r25), %r0 /* prefetch 4 */
313
314 ldd 16(%r25), %r21
315 ldd 24(%r25), %r22
316 std %r19, 0(%r26)
317 std %r20, 8(%r26)
318
319 ldd 32(%r25), %r19
320 ldd 40(%r25), %r20
321 std %r21, 16(%r26)
322 std %r22, 24(%r26)
323
324 ldd 48(%r25), %r21
325 ldd 56(%r25), %r22
326 std %r19, 32(%r26)
327 std %r20, 40(%r26)
328
329 ldd 64(%r25), %r19
330 ldd 72(%r25), %r20
331 std %r21, 48(%r26)
332 std %r22, 56(%r26)
333
334 ldd 80(%r25), %r21
335 ldd 88(%r25), %r22
336 std %r19, 64(%r26)
337 std %r20, 72(%r26)
338
339 ldd 96(%r25), %r19
340 ldd 104(%r25), %r20
341 std %r21, 80(%r26)
342 std %r22, 88(%r26)
343
344 ldd 112(%r25), %r21
345 ldd 120(%r25), %r22
346 std %r19, 96(%r26)
347 std %r20, 104(%r26)
348
349 ldo 128(%r25), %r25
350 std %r21, 112(%r26)
351 std %r22, 120(%r26)
352 ldo 128(%r26), %r26
353
354 ADDIB> -1, %r1, 1b /* bundle 10 */
355 ldd 0(%r25), %r19 /* start next loads */
356
357#else
358
359 /*
360 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
361 * bundles (very restricted rules for bundling).
362 * Note that until (if) we start saving
363 * the full 64 bit register values on interrupt, we can't
364 * use ldd/std on a 32 bit kernel.
365 */
366 ldi 64, %r1 /* PAGE_SIZE/64 == 64 */
367
3681:
369 ldw 0(%r25), %r19
370 ldw 4(%r25), %r20
371 ldw 8(%r25), %r21
372 ldw 12(%r25), %r22
373 stw %r19, 0(%r26)
374 stw %r20, 4(%r26)
375 stw %r21, 8(%r26)
376 stw %r22, 12(%r26)
377 ldw 16(%r25), %r19
378 ldw 20(%r25), %r20
379 ldw 24(%r25), %r21
380 ldw 28(%r25), %r22
381 stw %r19, 16(%r26)
382 stw %r20, 20(%r26)
383 stw %r21, 24(%r26)
384 stw %r22, 28(%r26)
385 ldw 32(%r25), %r19
386 ldw 36(%r25), %r20
387 ldw 40(%r25), %r21
388 ldw 44(%r25), %r22
389 stw %r19, 32(%r26)
390 stw %r20, 36(%r26)
391 stw %r21, 40(%r26)
392 stw %r22, 44(%r26)
393 ldw 48(%r25), %r19
394 ldw 52(%r25), %r20
395 ldw 56(%r25), %r21
396 ldw 60(%r25), %r22
397 stw %r19, 48(%r26)
398 stw %r20, 52(%r26)
399 stw %r21, 56(%r26)
400 stw %r22, 60(%r26)
401 ldo 64(%r26), %r26
402 ADDIB> -1, %r1, 1b
403 ldo 64(%r25), %r25
404#endif
405 bv %r0(%r2)
406 nop
407 .exit
408
409 .procend
410
411/*
412 * NOTE: Code in clear_user_page has a hard coded dependency on the
413 * maximum alias boundary being 4 Mb. We've been assured by the
414 * parisc chip designers that there will not ever be a parisc
415 * chip with a larger alias boundary (Never say never :-) ).
416 *
417 * Subtle: the dtlb miss handlers support the temp alias region by
418 * "knowing" that if a dtlb miss happens within the temp alias
419 * region it must have occurred while in clear_user_page. Since
420 * this routine makes use of processor local translations, we
421 * don't want to insert them into the kernel page table. Instead,
422 * we load up some general registers (they need to be registers
423 * which aren't shadowed) with the physical page numbers (preshifted
424 * for tlb insertion) needed to insert the translations. When we
425 * miss on the translation, the dtlb miss handler inserts the
426 * translation into the tlb using these values:
427 *
428 * %r26 physical page (shifted for tlb insert) of "to" translation
429 * %r23 physical page (shifted for tlb insert) of "from" translation
430 */
431
432#if 0
433
434 /*
435 * We can't do this since copy_user_page is used to bring in
436 * file data that might have instructions. Since the data would
437 * then need to be flushed out so the i-fetch can see it, it
438 * makes more sense to just copy through the kernel translation
439 * and flush it.
440 *
441 * I'm still keeping this around because it may be possible to
442 * use it if more information is passed into copy_user_page().
443 * Have to do some measurements to see if it is worthwhile to
444 * lobby for such a change.
445 */
446
447 .export copy_user_page_asm,code
448
449copy_user_page_asm:
450 .proc
451 .callinfo NO_CALLS
452 .entry
453
454 ldil L%(__PAGE_OFFSET), %r1
455 sub %r26, %r1, %r26
456 sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */
457
458 ldil L%(TMPALIAS_MAP_START), %r28
459#ifdef __LP64__
460 extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */
461 extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */
462 depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */
463 depdi 0, 63,12, %r28 /* Clear any offset bits */
464 copy %r28, %r29
465 depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */
466#else
467 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
468 extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */
469 depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */
470 depwi 0, 31,12, %r28 /* Clear any offset bits */
471 copy %r28, %r29
472 depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */
473#endif
474
475 /* Purge any old translations */
476
477 pdtlb 0(%r28)
478 pdtlb 0(%r29)
479
480 ldi 64, %r1
481
482 /*
483 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
484 * bundles (very restricted rules for bundling). It probably
485 * does OK on PCXU and better, but we could do better with
486 * ldd/std instructions. Note that until (if) we start saving
487 * the full 64 bit register values on interrupt, we can't
488 * use ldd/std on a 32 bit kernel.
489 */
490
491
4921:
493 ldw 0(%r29), %r19
494 ldw 4(%r29), %r20
495 ldw 8(%r29), %r21
496 ldw 12(%r29), %r22
497 stw %r19, 0(%r28)
498 stw %r20, 4(%r28)
499 stw %r21, 8(%r28)
500 stw %r22, 12(%r28)
501 ldw 16(%r29), %r19
502 ldw 20(%r29), %r20
503 ldw 24(%r29), %r21
504 ldw 28(%r29), %r22
505 stw %r19, 16(%r28)
506 stw %r20, 20(%r28)
507 stw %r21, 24(%r28)
508 stw %r22, 28(%r28)
509 ldw 32(%r29), %r19
510 ldw 36(%r29), %r20
511 ldw 40(%r29), %r21
512 ldw 44(%r29), %r22
513 stw %r19, 32(%r28)
514 stw %r20, 36(%r28)
515 stw %r21, 40(%r28)
516 stw %r22, 44(%r28)
517 ldw 48(%r29), %r19
518 ldw 52(%r29), %r20
519 ldw 56(%r29), %r21
520 ldw 60(%r29), %r22
521 stw %r19, 48(%r28)
522 stw %r20, 52(%r28)
523 stw %r21, 56(%r28)
524 stw %r22, 60(%r28)
525 ldo 64(%r28), %r28
526 ADDIB> -1, %r1,1b
527 ldo 64(%r29), %r29
528
529 bv %r0(%r2)
530 nop
531 .exit
532
533 .procend
534#endif
535
536 .export __clear_user_page_asm,code
537
538__clear_user_page_asm:
539 .proc
540 .callinfo NO_CALLS
541 .entry
542
543 tophys_r1 %r26
544
545 ldil L%(TMPALIAS_MAP_START), %r28
546#ifdef __LP64__
547#if (TMPALIAS_MAP_START >= 0x80000000)
548 depdi 0, 31,32, %r28 /* clear any sign extension */
549#endif
550 extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
551 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
552 depdi 0, 63,12, %r28 /* Clear any offset bits */
553#else
554 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
555 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
556 depwi 0, 31,12, %r28 /* Clear any offset bits */
557#endif
558
559 /* Purge any old translation */
560
561 pdtlb 0(%r28)
562
563#ifdef __LP64__
564 ldi 32, %r1 /* PAGE_SIZE/128 == 32 */
565
566 /* PREFETCH (Write) has not (yet) been proven to help here */
567/* #define PREFETCHW_OP ldd 256(%0), %r0 */
568
5691: std %r0, 0(%r28)
570 std %r0, 8(%r28)
571 std %r0, 16(%r28)
572 std %r0, 24(%r28)
573 std %r0, 32(%r28)
574 std %r0, 40(%r28)
575 std %r0, 48(%r28)
576 std %r0, 56(%r28)
577 std %r0, 64(%r28)
578 std %r0, 72(%r28)
579 std %r0, 80(%r28)
580 std %r0, 88(%r28)
581 std %r0, 96(%r28)
582 std %r0, 104(%r28)
583 std %r0, 112(%r28)
584 std %r0, 120(%r28)
585 ADDIB> -1, %r1, 1b
586 ldo 128(%r28), %r28
587
588#else /* ! __LP64 */
589
590 ldi 64, %r1 /* PAGE_SIZE/64 == 64 */
591
5921:
593 stw %r0, 0(%r28)
594 stw %r0, 4(%r28)
595 stw %r0, 8(%r28)
596 stw %r0, 12(%r28)
597 stw %r0, 16(%r28)
598 stw %r0, 20(%r28)
599 stw %r0, 24(%r28)
600 stw %r0, 28(%r28)
601 stw %r0, 32(%r28)
602 stw %r0, 36(%r28)
603 stw %r0, 40(%r28)
604 stw %r0, 44(%r28)
605 stw %r0, 48(%r28)
606 stw %r0, 52(%r28)
607 stw %r0, 56(%r28)
608 stw %r0, 60(%r28)
609 ADDIB> -1, %r1, 1b
610 ldo 64(%r28), %r28
611#endif /* __LP64 */
612
613 bv %r0(%r2)
614 nop
615 .exit
616
617 .procend
618
619 .export flush_kernel_dcache_page
620
621flush_kernel_dcache_page:
622 .proc
623 .callinfo NO_CALLS
624 .entry
625
626 ldil L%dcache_stride, %r1
627 ldw R%dcache_stride(%r1), %r23
628
629#ifdef __LP64__
630 depdi,z 1, 63-PAGE_SHIFT,1, %r25
631#else
632 depwi,z 1, 31-PAGE_SHIFT,1, %r25
633#endif
634 add %r26, %r25, %r25
635 sub %r25, %r23, %r25
636
637
6381: fdc,m %r23(%r26)
639 fdc,m %r23(%r26)
640 fdc,m %r23(%r26)
641 fdc,m %r23(%r26)
642 fdc,m %r23(%r26)
643 fdc,m %r23(%r26)
644 fdc,m %r23(%r26)
645 fdc,m %r23(%r26)
646 fdc,m %r23(%r26)
647 fdc,m %r23(%r26)
648 fdc,m %r23(%r26)
649 fdc,m %r23(%r26)
650 fdc,m %r23(%r26)
651 fdc,m %r23(%r26)
652 fdc,m %r23(%r26)
653 CMPB<< %r26, %r25,1b
654 fdc,m %r23(%r26)
655
656 sync
657 bv %r0(%r2)
658 nop
659 .exit
660
661 .procend
662
663 .export flush_user_dcache_page
664
665flush_user_dcache_page:
666 .proc
667 .callinfo NO_CALLS
668 .entry
669
670 ldil L%dcache_stride, %r1
671 ldw R%dcache_stride(%r1), %r23
672
673#ifdef __LP64__
674 depdi,z 1,63-PAGE_SHIFT,1, %r25
675#else
676 depwi,z 1,31-PAGE_SHIFT,1, %r25
677#endif
678 add %r26, %r25, %r25
679 sub %r25, %r23, %r25
680
681
6821: fdc,m %r23(%sr3, %r26)
683 fdc,m %r23(%sr3, %r26)
684 fdc,m %r23(%sr3, %r26)
685 fdc,m %r23(%sr3, %r26)
686 fdc,m %r23(%sr3, %r26)
687 fdc,m %r23(%sr3, %r26)
688 fdc,m %r23(%sr3, %r26)
689 fdc,m %r23(%sr3, %r26)
690 fdc,m %r23(%sr3, %r26)
691 fdc,m %r23(%sr3, %r26)
692 fdc,m %r23(%sr3, %r26)
693 fdc,m %r23(%sr3, %r26)
694 fdc,m %r23(%sr3, %r26)
695 fdc,m %r23(%sr3, %r26)
696 fdc,m %r23(%sr3, %r26)
697 CMPB<< %r26, %r25,1b
698 fdc,m %r23(%sr3, %r26)
699
700 sync
701 bv %r0(%r2)
702 nop
703 .exit
704
705 .procend
706
707 .export flush_user_icache_page
708
709flush_user_icache_page:
710 .proc
711 .callinfo NO_CALLS
712 .entry
713
714 ldil L%dcache_stride, %r1
715 ldw R%dcache_stride(%r1), %r23
716
717#ifdef __LP64__
718 depdi,z 1, 63-PAGE_SHIFT,1, %r25
719#else
720 depwi,z 1, 31-PAGE_SHIFT,1, %r25
721#endif
722 add %r26, %r25, %r25
723 sub %r25, %r23, %r25
724
725
7261: fic,m %r23(%sr3, %r26)
727 fic,m %r23(%sr3, %r26)
728 fic,m %r23(%sr3, %r26)
729 fic,m %r23(%sr3, %r26)
730 fic,m %r23(%sr3, %r26)
731 fic,m %r23(%sr3, %r26)
732 fic,m %r23(%sr3, %r26)
733 fic,m %r23(%sr3, %r26)
734 fic,m %r23(%sr3, %r26)
735 fic,m %r23(%sr3, %r26)
736 fic,m %r23(%sr3, %r26)
737 fic,m %r23(%sr3, %r26)
738 fic,m %r23(%sr3, %r26)
739 fic,m %r23(%sr3, %r26)
740 fic,m %r23(%sr3, %r26)
741 CMPB<< %r26, %r25,1b
742 fic,m %r23(%sr3, %r26)
743
744 sync
745 bv %r0(%r2)
746 nop
747 .exit
748
749 .procend
750
751
752 .export purge_kernel_dcache_page
753
754purge_kernel_dcache_page:
755 .proc
756 .callinfo NO_CALLS
757 .entry
758
759 ldil L%dcache_stride, %r1
760 ldw R%dcache_stride(%r1), %r23
761
762#ifdef __LP64__
763 depdi,z 1, 63-PAGE_SHIFT,1, %r25
764#else
765 depwi,z 1, 31-PAGE_SHIFT,1, %r25
766#endif
767 add %r26, %r25, %r25
768 sub %r25, %r23, %r25
769
7701: pdc,m %r23(%r26)
771 pdc,m %r23(%r26)
772 pdc,m %r23(%r26)
773 pdc,m %r23(%r26)
774 pdc,m %r23(%r26)
775 pdc,m %r23(%r26)
776 pdc,m %r23(%r26)
777 pdc,m %r23(%r26)
778 pdc,m %r23(%r26)
779 pdc,m %r23(%r26)
780 pdc,m %r23(%r26)
781 pdc,m %r23(%r26)
782 pdc,m %r23(%r26)
783 pdc,m %r23(%r26)
784 pdc,m %r23(%r26)
785 CMPB<< %r26, %r25, 1b
786 pdc,m %r23(%r26)
787
788 sync
789 bv %r0(%r2)
790 nop
791 .exit
792
793 .procend
794
795#if 0
796 /* Currently not used, but it still is a possible alternate
797 * solution.
798 */
799
800 .export flush_alias_page
801
802flush_alias_page:
803 .proc
804 .callinfo NO_CALLS
805 .entry
806
807 tophys_r1 %r26
808
809 ldil L%(TMPALIAS_MAP_START), %r28
810#ifdef __LP64__
811 extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
812 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
813 depdi 0, 63,12, %r28 /* Clear any offset bits */
814#else
815 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
816 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
817 depwi 0, 31,12, %r28 /* Clear any offset bits */
818#endif
819
820 /* Purge any old translation */
821
822 pdtlb 0(%r28)
823
824 ldil L%dcache_stride, %r1
825 ldw R%dcache_stride(%r1), %r23
826
827#ifdef __LP64__
828 depdi,z 1, 63-PAGE_SHIFT,1, %r29
829#else
830 depwi,z 1, 31-PAGE_SHIFT,1, %r29
831#endif
832 add %r28, %r29, %r29
833 sub %r29, %r23, %r29
834
8351: fdc,m %r23(%r28)
836 fdc,m %r23(%r28)
837 fdc,m %r23(%r28)
838 fdc,m %r23(%r28)
839 fdc,m %r23(%r28)
840 fdc,m %r23(%r28)
841 fdc,m %r23(%r28)
842 fdc,m %r23(%r28)
843 fdc,m %r23(%r28)
844 fdc,m %r23(%r28)
845 fdc,m %r23(%r28)
846 fdc,m %r23(%r28)
847 fdc,m %r23(%r28)
848 fdc,m %r23(%r28)
849 fdc,m %r23(%r28)
850 CMPB<< %r28, %r29, 1b
851 fdc,m %r23(%r28)
852
853 sync
854 bv %r0(%r2)
855 nop
856 .exit
857
858 .procend
859#endif
860
861 .export flush_user_dcache_range_asm
862
863flush_user_dcache_range_asm:
864 .proc
865 .callinfo NO_CALLS
866 .entry
867
868 ldil L%dcache_stride, %r1
869 ldw R%dcache_stride(%r1), %r23
870 ldo -1(%r23), %r21
871 ANDCM %r26, %r21, %r26
872
8731: CMPB<<,n %r26, %r25, 1b
874 fdc,m %r23(%sr3, %r26)
875
876 sync
877 bv %r0(%r2)
878 nop
879 .exit
880
881 .procend
882
883 .export flush_kernel_dcache_range_asm
884
885flush_kernel_dcache_range_asm:
886 .proc
887 .callinfo NO_CALLS
888 .entry
889
890 ldil L%dcache_stride, %r1
891 ldw R%dcache_stride(%r1), %r23
892 ldo -1(%r23), %r21
893 ANDCM %r26, %r21, %r26
894
8951: CMPB<<,n %r26, %r25,1b
896 fdc,m %r23(%r26)
897
898 sync
899 syncdma
900 bv %r0(%r2)
901 nop
902 .exit
903
904 .procend
905
906 .export flush_user_icache_range_asm
907
908flush_user_icache_range_asm:
909 .proc
910 .callinfo NO_CALLS
911 .entry
912
913 ldil L%icache_stride, %r1
914 ldw R%icache_stride(%r1), %r23
915 ldo -1(%r23), %r21
916 ANDCM %r26, %r21, %r26
917
9181: CMPB<<,n %r26, %r25,1b
919 fic,m %r23(%sr3, %r26)
920
921 sync
922 bv %r0(%r2)
923 nop
924 .exit
925
926 .procend
927
928 .export flush_kernel_icache_page
929
930flush_kernel_icache_page:
931 .proc
932 .callinfo NO_CALLS
933 .entry
934
935 ldil L%icache_stride, %r1
936 ldw R%icache_stride(%r1), %r23
937
938#ifdef __LP64__
939 depdi,z 1, 63-PAGE_SHIFT,1, %r25
940#else
941 depwi,z 1, 31-PAGE_SHIFT,1, %r25
942#endif
943 add %r26, %r25, %r25
944 sub %r25, %r23, %r25
945
946
9471: fic,m %r23(%r26)
948 fic,m %r23(%r26)
949 fic,m %r23(%r26)
950 fic,m %r23(%r26)
951 fic,m %r23(%r26)
952 fic,m %r23(%r26)
953 fic,m %r23(%r26)
954 fic,m %r23(%r26)
955 fic,m %r23(%r26)
956 fic,m %r23(%r26)
957 fic,m %r23(%r26)
958 fic,m %r23(%r26)
959 fic,m %r23(%r26)
960 fic,m %r23(%r26)
961 fic,m %r23(%r26)
962 CMPB<< %r26, %r25, 1b
963 fic,m %r23(%r26)
964
965 sync
966 bv %r0(%r2)
967 nop
968 .exit
969
970 .procend
971
972 .export flush_kernel_icache_range_asm
973
974flush_kernel_icache_range_asm:
975 .proc
976 .callinfo NO_CALLS
977 .entry
978
979 ldil L%icache_stride, %r1
980 ldw R%icache_stride(%r1), %r23
981 ldo -1(%r23), %r21
982 ANDCM %r26, %r21, %r26
983
9841: CMPB<<,n %r26, %r25, 1b
985 fic,m %r23(%r26)
986
987 sync
988 bv %r0(%r2)
989 nop
990 .exit
991
992 .procend
993
994 .align 128
995
996 .export disable_sr_hashing_asm,code
997
998disable_sr_hashing_asm:
999 .proc
1000 .callinfo NO_CALLS
1001 .entry
1002
1003 /* Switch to real mode */
1004
1005 ssm 0, %r0 /* relied upon translation! */
1006 nop
1007 nop
1008 nop
1009 nop
1010 nop
1011 nop
1012 nop
1013
1014 rsm (PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */
1015 ldil L%REAL_MODE_PSW, %r1
1016 ldo R%REAL_MODE_PSW(%r1), %r1
1017 mtctl %r1, %cr22
1018 mtctl %r0, %cr17 /* Clear IIASQ tail */
1019 mtctl %r0, %cr17 /* Clear IIASQ head */
1020 ldil L%PA(1f), %r1
1021 ldo R%PA(1f)(%r1), %r1
1022 mtctl %r1, %cr18 /* IIAOQ head */
1023 ldo 4(%r1), %r1
1024 mtctl %r1, %cr18 /* IIAOQ tail */
1025 rfi
1026 nop
1027
10281: cmpib,=,n SRHASH_PCXST, %r26,srdis_pcxs
1029 cmpib,=,n SRHASH_PCXL, %r26,srdis_pcxl
1030 cmpib,=,n SRHASH_PA20, %r26,srdis_pa20
1031 b,n srdis_done
1032
1033srdis_pcxs:
1034
1035 /* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
1036
1037 .word 0x141c1a00 /* mfdiag %dr0, %r28 */
1038 .word 0x141c1a00 /* must issue twice */
1039 depwi 0,18,1, %r28 /* Clear DHE (dcache hash enable) */
1040 depwi 0,20,1, %r28 /* Clear IHE (icache hash enable) */
1041 .word 0x141c1600 /* mtdiag %r28, %dr0 */
1042 .word 0x141c1600 /* must issue twice */
1043 b,n srdis_done
1044
1045srdis_pcxl:
1046
1047 /* Disable Space Register Hashing for PCXL */
1048
1049 .word 0x141c0600 /* mfdiag %dr0, %r28 */
1050 depwi 0,28,2, %r28 /* Clear DHASH_EN & IHASH_EN */
1051 .word 0x141c0240 /* mtdiag %r28, %dr0 */
1052 b,n srdis_done
1053
1054srdis_pa20:
1055
1056 /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */
1057
1058 .word 0x144008bc /* mfdiag %dr2, %r28 */
1059 depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
1060 .word 0x145c1840 /* mtdiag %r28, %dr2 */
1061
1062srdis_done:
1063
1064 /* Switch back to virtual mode */
1065
1066 rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */
1067 ldil L%KERNEL_PSW, %r1
1068 ldo R%KERNEL_PSW(%r1), %r1
1069 mtctl %r1, %cr22
1070 mtctl %r0, %cr17 /* Clear IIASQ tail */
1071 mtctl %r0, %cr17 /* Clear IIASQ head */
1072 ldil L%(2f), %r1
1073 ldo R%(2f)(%r1), %r1
1074 mtctl %r1, %cr18 /* IIAOQ head */
1075 ldo 4(%r1), %r1
1076 mtctl %r1, %cr18 /* IIAOQ tail */
1077 rfi
1078 nop
1079
10802: bv %r0(%r2)
1081 nop
1082 .exit
1083
1084 .procend
1085
1086 .end
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
new file mode 100644
index 000000000000..f40a777dd388
--- /dev/null
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -0,0 +1,187 @@
1/*
2 * Architecture-specific kernel symbols
3 *
4 * Copyright (C) 2000-2001 Richard Hirst <rhirst with parisc-linux.org>
5 * Copyright (C) 2001 Dave Kennedy
6 * Copyright (C) 2001 Paul Bame <bame at parisc-linux.org>
7 * Copyright (C) 2001-2003 Grant Grundler <grundler with parisc-linux.org>
8 * Copyright (C) 2002-2003 Matthew Wilcox <willy at parisc-linux.org>
9 * Copyright (C) 2002 Randolph Chung <tausq at parisc-linux.org>
10 * Copyright (C) 2002-2003 Helge Deller <deller with parisc-linux.org>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/syscalls.h>
31
32#include <linux/string.h>
33EXPORT_SYMBOL(memchr);
34EXPORT_SYMBOL(memcmp);
35EXPORT_SYMBOL(memmove);
36EXPORT_SYMBOL(memscan);
37EXPORT_SYMBOL(memset);
38EXPORT_SYMBOL(strcat);
39EXPORT_SYMBOL(strchr);
40EXPORT_SYMBOL(strcmp);
41EXPORT_SYMBOL(strcpy);
42EXPORT_SYMBOL(strlen);
43EXPORT_SYMBOL(strncat);
44EXPORT_SYMBOL(strncmp);
45EXPORT_SYMBOL(strncpy);
46EXPORT_SYMBOL(strnlen);
47EXPORT_SYMBOL(strrchr);
48EXPORT_SYMBOL(strstr);
49EXPORT_SYMBOL(strpbrk);
50
51#include <linux/pm.h>
52EXPORT_SYMBOL(pm_power_off);
53
54#include <asm/atomic.h>
55EXPORT_SYMBOL(__xchg8);
56EXPORT_SYMBOL(__xchg32);
57EXPORT_SYMBOL(__cmpxchg_u32);
58#ifdef CONFIG_SMP
59EXPORT_SYMBOL(__atomic_hash);
60#endif
61#ifdef __LP64__
62EXPORT_SYMBOL(__xchg64);
63EXPORT_SYMBOL(__cmpxchg_u64);
64#endif
65
66#include <asm/uaccess.h>
67EXPORT_SYMBOL(lstrncpy_from_user);
68EXPORT_SYMBOL(lclear_user);
69EXPORT_SYMBOL(lstrnlen_user);
70
71/* Global fixups */
72extern void fixup_get_user_skip_1(void);
73extern void fixup_get_user_skip_2(void);
74extern void fixup_put_user_skip_1(void);
75extern void fixup_put_user_skip_2(void);
76EXPORT_SYMBOL(fixup_get_user_skip_1);
77EXPORT_SYMBOL(fixup_get_user_skip_2);
78EXPORT_SYMBOL(fixup_put_user_skip_1);
79EXPORT_SYMBOL(fixup_put_user_skip_2);
80
81#ifndef __LP64__
82/* Needed so insmod can set dp value */
83extern int $global$;
84EXPORT_SYMBOL($global$);
85#endif
86
87#include <asm/io.h>
88EXPORT_SYMBOL(__ioremap);
89EXPORT_SYMBOL(iounmap);
90EXPORT_SYMBOL(memcpy_toio);
91EXPORT_SYMBOL(memcpy_fromio);
92EXPORT_SYMBOL(memset_io);
93
94#include <asm/unistd.h>
95EXPORT_SYMBOL(sys_open);
96EXPORT_SYMBOL(sys_lseek);
97EXPORT_SYMBOL(sys_read);
98EXPORT_SYMBOL(sys_write);
99
100#include <asm/semaphore.h>
101EXPORT_SYMBOL(__up);
102EXPORT_SYMBOL(__down_interruptible);
103EXPORT_SYMBOL(__down);
104
105extern void $$divI(void);
106extern void $$divU(void);
107extern void $$remI(void);
108extern void $$remU(void);
109extern void $$mulI(void);
110extern void $$divU_3(void);
111extern void $$divU_5(void);
112extern void $$divU_6(void);
113extern void $$divU_9(void);
114extern void $$divU_10(void);
115extern void $$divU_12(void);
116extern void $$divU_7(void);
117extern void $$divU_14(void);
118extern void $$divU_15(void);
119extern void $$divI_3(void);
120extern void $$divI_5(void);
121extern void $$divI_6(void);
122extern void $$divI_7(void);
123extern void $$divI_9(void);
124extern void $$divI_10(void);
125extern void $$divI_12(void);
126extern void $$divI_14(void);
127extern void $$divI_15(void);
128
129EXPORT_SYMBOL($$divI);
130EXPORT_SYMBOL($$divU);
131EXPORT_SYMBOL($$remI);
132EXPORT_SYMBOL($$remU);
133EXPORT_SYMBOL($$mulI);
134EXPORT_SYMBOL($$divU_3);
135EXPORT_SYMBOL($$divU_5);
136EXPORT_SYMBOL($$divU_6);
137EXPORT_SYMBOL($$divU_9);
138EXPORT_SYMBOL($$divU_10);
139EXPORT_SYMBOL($$divU_12);
140EXPORT_SYMBOL($$divU_7);
141EXPORT_SYMBOL($$divU_14);
142EXPORT_SYMBOL($$divU_15);
143EXPORT_SYMBOL($$divI_3);
144EXPORT_SYMBOL($$divI_5);
145EXPORT_SYMBOL($$divI_6);
146EXPORT_SYMBOL($$divI_7);
147EXPORT_SYMBOL($$divI_9);
148EXPORT_SYMBOL($$divI_10);
149EXPORT_SYMBOL($$divI_12);
150EXPORT_SYMBOL($$divI_14);
151EXPORT_SYMBOL($$divI_15);
152
153extern void __ashrdi3(void);
154extern void __ashldi3(void);
155extern void __lshrdi3(void);
156extern void __muldi3(void);
157
158EXPORT_SYMBOL(__ashrdi3);
159EXPORT_SYMBOL(__ashldi3);
160EXPORT_SYMBOL(__lshrdi3);
161EXPORT_SYMBOL(__muldi3);
162
163asmlinkage void * __canonicalize_funcptr_for_compare(void *);
164EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
165
166#ifdef __LP64__
167extern void __divdi3(void);
168extern void __udivdi3(void);
169extern void __umoddi3(void);
170extern void __moddi3(void);
171
172EXPORT_SYMBOL(__divdi3);
173EXPORT_SYMBOL(__udivdi3);
174EXPORT_SYMBOL(__umoddi3);
175EXPORT_SYMBOL(__moddi3);
176#endif
177
178#ifndef __LP64__
179extern void $$dyncall(void);
180EXPORT_SYMBOL($$dyncall);
181#endif
182
183#ifdef CONFIG_DISCONTIGMEM
184#include <asm/mmzone.h>
185EXPORT_SYMBOL(node_data);
186EXPORT_SYMBOL(pfnnid_map);
187#endif
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
new file mode 100644
index 000000000000..368cc095c99f
--- /dev/null
+++ b/arch/parisc/kernel/pci-dma.c
@@ -0,0 +1,578 @@
1/*
2** PARISC 1.1 Dynamic DMA mapping support.
3** This implementation is for PA-RISC platforms that do not support
4** I/O TLBs (aka DMA address translation hardware).
5** See Documentation/DMA-mapping.txt for interface definitions.
6**
7** (c) Copyright 1999,2000 Hewlett-Packard Company
8** (c) Copyright 2000 Grant Grundler
9** (c) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
10** (c) Copyright 2000 John Marvin
11**
12** "leveraged" from 2.3.47: arch/ia64/kernel/pci-dma.c.
13** (I assume it's from David Mosberger-Tang but there was no Copyright)
14**
15** AFAIK, all PA7100LC and PA7300LC platforms can use this code.
16**
17** - ggg
18*/
19
20#include <linux/init.h>
21#include <linux/mm.h>
22#include <linux/pci.h>
23#include <linux/proc_fs.h>
24#include <linux/slab.h>
25#include <linux/string.h>
26#include <linux/types.h>
27
28#include <asm/cacheflush.h>
29#include <asm/dma.h> /* for DMA_CHUNK_SIZE */
30#include <asm/io.h>
31#include <asm/page.h> /* get_order */
32#include <asm/pgalloc.h>
33#include <asm/uaccess.h>
34
35
36static struct proc_dir_entry * proc_gsc_root = NULL;
37static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
38static unsigned long pcxl_used_bytes = 0;
39static unsigned long pcxl_used_pages = 0;
40
41extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */
42static spinlock_t pcxl_res_lock;
43static char *pcxl_res_map;
44static int pcxl_res_hint;
45static int pcxl_res_size;
46
47#ifdef DEBUG_PCXL_RESOURCE
48#define DBG_RES(x...) printk(x)
49#else
50#define DBG_RES(x...)
51#endif
52
53
54/*
55** Dump a hex representation of the resource map.
56*/
57
58#ifdef DUMP_RESMAP
59static
60void dump_resmap(void)
61{
62 u_long *res_ptr = (unsigned long *)pcxl_res_map;
63 u_long i = 0;
64
65 printk("res_map: ");
66 for(; i < (pcxl_res_size / sizeof(unsigned long)); ++i, ++res_ptr)
67 printk("%08lx ", *res_ptr);
68
69 printk("\n");
70}
71#else
72static inline void dump_resmap(void) {;}
73#endif
74
75static int pa11_dma_supported( struct device *dev, u64 mask)
76{
77 return 1;
78}
79
80static inline int map_pte_uncached(pte_t * pte,
81 unsigned long vaddr,
82 unsigned long size, unsigned long *paddr_ptr)
83{
84 unsigned long end;
85 unsigned long orig_vaddr = vaddr;
86
87 vaddr &= ~PMD_MASK;
88 end = vaddr + size;
89 if (end > PMD_SIZE)
90 end = PMD_SIZE;
91 do {
92 if (!pte_none(*pte))
93 printk(KERN_ERR "map_pte_uncached: page already exists\n");
94 set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
95 purge_tlb_start();
96 pdtlb_kernel(orig_vaddr);
97 purge_tlb_end();
98 vaddr += PAGE_SIZE;
99 orig_vaddr += PAGE_SIZE;
100 (*paddr_ptr) += PAGE_SIZE;
101 pte++;
102 } while (vaddr < end);
103 return 0;
104}
105
106static inline int map_pmd_uncached(pmd_t * pmd, unsigned long vaddr,
107 unsigned long size, unsigned long *paddr_ptr)
108{
109 unsigned long end;
110 unsigned long orig_vaddr = vaddr;
111
112 vaddr &= ~PGDIR_MASK;
113 end = vaddr + size;
114 if (end > PGDIR_SIZE)
115 end = PGDIR_SIZE;
116 do {
117 pte_t * pte = pte_alloc_kernel(&init_mm, pmd, vaddr);
118 if (!pte)
119 return -ENOMEM;
120 if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
121 return -ENOMEM;
122 vaddr = (vaddr + PMD_SIZE) & PMD_MASK;
123 orig_vaddr += PMD_SIZE;
124 pmd++;
125 } while (vaddr < end);
126 return 0;
127}
128
129static inline int map_uncached_pages(unsigned long vaddr, unsigned long size,
130 unsigned long paddr)
131{
132 pgd_t * dir;
133 unsigned long end = vaddr + size;
134
135 dir = pgd_offset_k(vaddr);
136 do {
137 pmd_t *pmd;
138
139 pmd = pmd_alloc(NULL, dir, vaddr);
140 if (!pmd)
141 return -ENOMEM;
142 if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
143 return -ENOMEM;
144 vaddr = vaddr + PGDIR_SIZE;
145 dir++;
146 } while (vaddr && (vaddr < end));
147 return 0;
148}
149
150static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr,
151 unsigned long size)
152{
153 pte_t * pte;
154 unsigned long end;
155 unsigned long orig_vaddr = vaddr;
156
157 if (pmd_none(*pmd))
158 return;
159 if (pmd_bad(*pmd)) {
160 pmd_ERROR(*pmd);
161 pmd_clear(pmd);
162 return;
163 }
164 pte = pte_offset_map(pmd, vaddr);
165 vaddr &= ~PMD_MASK;
166 end = vaddr + size;
167 if (end > PMD_SIZE)
168 end = PMD_SIZE;
169 do {
170 pte_t page = *pte;
171 pte_clear(&init_mm, vaddr, pte);
172 purge_tlb_start();
173 pdtlb_kernel(orig_vaddr);
174 purge_tlb_end();
175 vaddr += PAGE_SIZE;
176 orig_vaddr += PAGE_SIZE;
177 pte++;
178 if (pte_none(page) || pte_present(page))
179 continue;
180 printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n");
181 } while (vaddr < end);
182}
183
184static inline void unmap_uncached_pmd(pgd_t * dir, unsigned long vaddr,
185 unsigned long size)
186{
187 pmd_t * pmd;
188 unsigned long end;
189 unsigned long orig_vaddr = vaddr;
190
191 if (pgd_none(*dir))
192 return;
193 if (pgd_bad(*dir)) {
194 pgd_ERROR(*dir);
195 pgd_clear(dir);
196 return;
197 }
198 pmd = pmd_offset(dir, vaddr);
199 vaddr &= ~PGDIR_MASK;
200 end = vaddr + size;
201 if (end > PGDIR_SIZE)
202 end = PGDIR_SIZE;
203 do {
204 unmap_uncached_pte(pmd, orig_vaddr, end - vaddr);
205 vaddr = (vaddr + PMD_SIZE) & PMD_MASK;
206 orig_vaddr += PMD_SIZE;
207 pmd++;
208 } while (vaddr < end);
209}
210
211static void unmap_uncached_pages(unsigned long vaddr, unsigned long size)
212{
213 pgd_t * dir;
214 unsigned long end = vaddr + size;
215
216 dir = pgd_offset_k(vaddr);
217 do {
218 unmap_uncached_pmd(dir, vaddr, end - vaddr);
219 vaddr = vaddr + PGDIR_SIZE;
220 dir++;
221 } while (vaddr && (vaddr < end));
222}
223
224#define PCXL_SEARCH_LOOP(idx, mask, size) \
225 for(; res_ptr < res_end; ++res_ptr) \
226 { \
227 if(0 == ((*res_ptr) & mask)) { \
228 *res_ptr |= mask; \
229 idx = (int)((u_long)res_ptr - (u_long)pcxl_res_map); \
230 pcxl_res_hint = idx + (size >> 3); \
231 goto resource_found; \
232 } \
233 }
234
235#define PCXL_FIND_FREE_MAPPING(idx, mask, size) { \
236 u##size *res_ptr = (u##size *)&(pcxl_res_map[pcxl_res_hint & ~((size >> 3) - 1)]); \
237 u##size *res_end = (u##size *)&pcxl_res_map[pcxl_res_size]; \
238 PCXL_SEARCH_LOOP(idx, mask, size); \
239 res_ptr = (u##size *)&pcxl_res_map[0]; \
240 PCXL_SEARCH_LOOP(idx, mask, size); \
241}
242
243unsigned long
244pcxl_alloc_range(size_t size)
245{
246 int res_idx;
247 u_long mask, flags;
248 unsigned int pages_needed = size >> PAGE_SHIFT;
249
250 mask = (u_long) -1L;
251 mask >>= BITS_PER_LONG - pages_needed;
252
253 DBG_RES("pcxl_alloc_range() size: %d pages_needed %d pages_mask 0x%08lx\n",
254 size, pages_needed, mask);
255
256 spin_lock_irqsave(&pcxl_res_lock, flags);
257
258 if(pages_needed <= 8) {
259 PCXL_FIND_FREE_MAPPING(res_idx, mask, 8);
260 } else if(pages_needed <= 16) {
261 PCXL_FIND_FREE_MAPPING(res_idx, mask, 16);
262 } else if(pages_needed <= 32) {
263 PCXL_FIND_FREE_MAPPING(res_idx, mask, 32);
264 } else {
265 panic("%s: pcxl_alloc_range() Too many pages to map.\n",
266 __FILE__);
267 }
268
269 dump_resmap();
270 panic("%s: pcxl_alloc_range() out of dma mapping resources\n",
271 __FILE__);
272
273resource_found:
274
275 DBG_RES("pcxl_alloc_range() res_idx %d mask 0x%08lx res_hint: %d\n",
276 res_idx, mask, pcxl_res_hint);
277
278 pcxl_used_pages += pages_needed;
279 pcxl_used_bytes += ((pages_needed >> 3) ? (pages_needed >> 3) : 1);
280
281 spin_unlock_irqrestore(&pcxl_res_lock, flags);
282
283 dump_resmap();
284
285 /*
286 ** return the corresponding vaddr in the pcxl dma map
287 */
288 return (pcxl_dma_start + (res_idx << (PAGE_SHIFT + 3)));
289}
290
291#define PCXL_FREE_MAPPINGS(idx, m, size) \
292 u##size *res_ptr = (u##size *)&(pcxl_res_map[(idx) + (((size >> 3) - 1) & (~((size >> 3) - 1)))]); \
293 /* BUG_ON((*res_ptr & m) != m); */ \
294 *res_ptr &= ~m;
295
296/*
297** clear bits in the pcxl resource map
298*/
299static void
300pcxl_free_range(unsigned long vaddr, size_t size)
301{
302 u_long mask, flags;
303 unsigned int res_idx = (vaddr - pcxl_dma_start) >> (PAGE_SHIFT + 3);
304 unsigned int pages_mapped = size >> PAGE_SHIFT;
305
306 mask = (u_long) -1L;
307 mask >>= BITS_PER_LONG - pages_mapped;
308
309 DBG_RES("pcxl_free_range() res_idx: %d size: %d pages_mapped %d mask 0x%08lx\n",
310 res_idx, size, pages_mapped, mask);
311
312 spin_lock_irqsave(&pcxl_res_lock, flags);
313
314 if(pages_mapped <= 8) {
315 PCXL_FREE_MAPPINGS(res_idx, mask, 8);
316 } else if(pages_mapped <= 16) {
317 PCXL_FREE_MAPPINGS(res_idx, mask, 16);
318 } else if(pages_mapped <= 32) {
319 PCXL_FREE_MAPPINGS(res_idx, mask, 32);
320 } else {
321 panic("%s: pcxl_free_range() Too many pages to unmap.\n",
322 __FILE__);
323 }
324
325 pcxl_used_pages -= (pages_mapped ? pages_mapped : 1);
326 pcxl_used_bytes -= ((pages_mapped >> 3) ? (pages_mapped >> 3) : 1);
327
328 spin_unlock_irqrestore(&pcxl_res_lock, flags);
329
330 dump_resmap();
331}
332
333static int __init
334pcxl_dma_init(void)
335{
336 if (pcxl_dma_start == 0)
337 return 0;
338
339 spin_lock_init(&pcxl_res_lock);
340 pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
341 pcxl_res_hint = 0;
342 pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
343 get_order(pcxl_res_size));
344 memset(pcxl_res_map, 0, pcxl_res_size);
345 proc_gsc_root = proc_mkdir("gsc", 0);
346 create_proc_info_entry("dino", 0, proc_gsc_root, pcxl_proc_info);
347 return 0;
348}
349
350__initcall(pcxl_dma_init);
351
352static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
353{
354 unsigned long vaddr;
355 unsigned long paddr;
356 int order;
357
358 order = get_order(size);
359 size = 1 << (order + PAGE_SHIFT);
360 vaddr = pcxl_alloc_range(size);
361 paddr = __get_free_pages(flag, order);
362 flush_kernel_dcache_range(paddr, size);
363 paddr = __pa(paddr);
364 map_uncached_pages(vaddr, size, paddr);
365 *dma_handle = (dma_addr_t) paddr;
366
367#if 0
368/* This probably isn't needed to support EISA cards.
369** ISA cards will certainly only support 24-bit DMA addressing.
370** Not clear if we can, want, or need to support ISA.
371*/
372 if (!dev || *dev->coherent_dma_mask < 0xffffffff)
373 gfp |= GFP_DMA;
374#endif
375 return (void *)vaddr;
376}
377
378static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
379{
380 int order;
381
382 order = get_order(size);
383 size = 1 << (order + PAGE_SHIFT);
384 unmap_uncached_pages((unsigned long)vaddr, size);
385 pcxl_free_range((unsigned long)vaddr, size);
386 free_pages((unsigned long)__va(dma_handle), order);
387}
388
389static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
390{
391 if (direction == DMA_NONE) {
392 printk(KERN_ERR "pa11_dma_map_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0));
393 BUG();
394 }
395
396 flush_kernel_dcache_range((unsigned long) addr, size);
397 return virt_to_phys(addr);
398}
399
400static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
401{
402 if (direction == DMA_NONE) {
403 printk(KERN_ERR "pa11_dma_unmap_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0));
404 BUG();
405 }
406
407 if (direction == DMA_TO_DEVICE)
408 return;
409
410 /*
411 * For PCI_DMA_FROMDEVICE this flush is not necessary for the
412 * simple map/unmap case. However, it IS necessary if if
413 * pci_dma_sync_single_* has been called and the buffer reused.
414 */
415
416 flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle), size);
417 return;
418}
419
420static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
421{
422 int i;
423
424 if (direction == DMA_NONE)
425 BUG();
426
427 for (i = 0; i < nents; i++, sglist++ ) {
428 unsigned long vaddr = sg_virt_addr(sglist);
429 sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(vaddr);
430 sg_dma_len(sglist) = sglist->length;
431 flush_kernel_dcache_range(vaddr, sglist->length);
432 }
433 return nents;
434}
435
436static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
437{
438 int i;
439
440 if (direction == DMA_NONE)
441 BUG();
442
443 if (direction == DMA_TO_DEVICE)
444 return;
445
446 /* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
447
448 for (i = 0; i < nents; i++, sglist++ )
449 flush_kernel_dcache_range(sg_virt_addr(sglist), sglist->length);
450 return;
451}
452
453static void pa11_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
454{
455 if (direction == DMA_NONE)
456 BUG();
457
458 flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
459}
460
461static void pa11_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
462{
463 if (direction == DMA_NONE)
464 BUG();
465
466 flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
467}
468
469static void pa11_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
470{
471 int i;
472
473 /* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
474
475 for (i = 0; i < nents; i++, sglist++ )
476 flush_kernel_dcache_range(sg_virt_addr(sglist), sglist->length);
477}
478
479static void pa11_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
480{
481 int i;
482
483 /* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
484
485 for (i = 0; i < nents; i++, sglist++ )
486 flush_kernel_dcache_range(sg_virt_addr(sglist), sglist->length);
487}
488
489struct hppa_dma_ops pcxl_dma_ops = {
490 .dma_supported = pa11_dma_supported,
491 .alloc_consistent = pa11_dma_alloc_consistent,
492 .alloc_noncoherent = pa11_dma_alloc_consistent,
493 .free_consistent = pa11_dma_free_consistent,
494 .map_single = pa11_dma_map_single,
495 .unmap_single = pa11_dma_unmap_single,
496 .map_sg = pa11_dma_map_sg,
497 .unmap_sg = pa11_dma_unmap_sg,
498 .dma_sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
499 .dma_sync_single_for_device = pa11_dma_sync_single_for_device,
500 .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
501 .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
502};
503
504static void *fail_alloc_consistent(struct device *dev, size_t size,
505 dma_addr_t *dma_handle, int flag)
506{
507 return NULL;
508}
509
510static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
511 dma_addr_t *dma_handle, int flag)
512{
513 void *addr = NULL;
514
515 /* rely on kmalloc to be cacheline aligned */
516 addr = kmalloc(size, flag);
517 if(addr)
518 *dma_handle = (dma_addr_t)virt_to_phys(addr);
519
520 return addr;
521}
522
523static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
524 void *vaddr, dma_addr_t iova)
525{
526 kfree(vaddr);
527 return;
528}
529
530struct hppa_dma_ops pcx_dma_ops = {
531 .dma_supported = pa11_dma_supported,
532 .alloc_consistent = fail_alloc_consistent,
533 .alloc_noncoherent = pa11_dma_alloc_noncoherent,
534 .free_consistent = pa11_dma_free_noncoherent,
535 .map_single = pa11_dma_map_single,
536 .unmap_single = pa11_dma_unmap_single,
537 .map_sg = pa11_dma_map_sg,
538 .unmap_sg = pa11_dma_unmap_sg,
539 .dma_sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
540 .dma_sync_single_for_device = pa11_dma_sync_single_for_device,
541 .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
542 .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
543};
544
545
546static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
547{
548 u_long i = 0;
549 unsigned long *res_ptr = (u_long *)pcxl_res_map;
550 unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */
551
552 sprintf(buf, "\nDMA Mapping Area size : %d bytes (%d pages)\n",
553 PCXL_DMA_MAP_SIZE,
554 (pcxl_res_size << 3) ); /* 1 bit per page */
555
556 sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n",
557 buf, pcxl_res_size, pcxl_res_size << 3); /* 8 bits per byte */
558
559 strcat(buf, " total: free: used: % used:\n");
560 sprintf(buf, "%sblocks %8d %8ld %8ld %8ld%%\n", buf, pcxl_res_size,
561 pcxl_res_size - pcxl_used_bytes, pcxl_used_bytes,
562 (pcxl_used_bytes * 100) / pcxl_res_size);
563
564 sprintf(buf, "%spages %8ld %8ld %8ld %8ld%%\n", buf, total_pages,
565 total_pages - pcxl_used_pages, pcxl_used_pages,
566 (pcxl_used_pages * 100 / total_pages));
567
568 strcat(buf, "\nResource bitmap:");
569
570 for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) {
571 if ((i & 7) == 0)
572 strcat(buf,"\n ");
573 sprintf(buf, "%s %08lx", buf, *res_ptr);
574 }
575 strcat(buf, "\n");
576 return strlen(buf);
577}
578
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
new file mode 100644
index 000000000000..3cb08a4a513a
--- /dev/null
+++ b/arch/parisc/kernel/pci.c
@@ -0,0 +1,346 @@
1/* $Id: pci.c,v 1.6 2000/01/29 00:12:05 grundler Exp $
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1997, 1998 Ralf Baechle
8 * Copyright (C) 1999 SuSE GmbH
9 * Copyright (C) 1999-2001 Hewlett-Packard Company
10 * Copyright (C) 1999-2001 Grant Grundler
11 */
12#include <linux/config.h>
13#include <linux/eisa.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/slab.h>
19#include <linux/types.h>
20
21#include <asm/io.h>
22#include <asm/system.h>
23#include <asm/cache.h> /* for L1_CACHE_BYTES */
24#include <asm/superio.h>
25
26#define DEBUG_RESOURCES 0
27#define DEBUG_CONFIG 0
28
29#if DEBUG_CONFIG
30# define DBGC(x...) printk(KERN_DEBUG x)
31#else
32# define DBGC(x...)
33#endif
34
35
36#if DEBUG_RESOURCES
37#define DBG_RES(x...) printk(KERN_DEBUG x)
38#else
39#define DBG_RES(x...)
40#endif
41
42/* To be used as: mdelay(pci_post_reset_delay);
43 *
44 * post_reset is the time the kernel should stall to prevent anyone from
45 * accessing the PCI bus once #RESET is de-asserted.
46 * PCI spec somewhere says 1 second but with multi-PCI bus systems,
47 * this makes the boot time much longer than necessary.
48 * 20ms seems to work for all the HP PCI implementations to date.
49 *
50 * XXX: turn into a #defined constant in <asm/pci.h> ?
51 */
52int pci_post_reset_delay = 50;
53
54struct pci_port_ops *pci_port;
55struct pci_bios_ops *pci_bios;
56
57int pci_hba_count = 0;
58
59/* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */
60#define PCI_HBA_MAX 32
61struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX];
62
63
64/********************************************************************
65**
66** I/O port space support
67**
68*********************************************************************/
69
70/* EISA port numbers and PCI port numbers share the same interface. Some
71 * machines have both EISA and PCI adapters installed. Rather than turn
72 * pci_port into an array, we reserve bus 0 for EISA and call the EISA
73 * routines if the access is to a port on bus 0. We don't want to fix
74 * EISA and ISA drivers which assume port space is <= 0xffff.
75 */
76
77#ifdef CONFIG_EISA
78#define EISA_IN(size) if (EISA_bus && (b == 0)) return eisa_in##size(addr)
79#define EISA_OUT(size) if (EISA_bus && (b == 0)) return eisa_out##size(d, addr)
80#else
81#define EISA_IN(size)
82#define EISA_OUT(size)
83#endif
84
85#define PCI_PORT_IN(type, size) \
86u##size in##type (int addr) \
87{ \
88 int b = PCI_PORT_HBA(addr); \
89 EISA_IN(size); \
90 if (!parisc_pci_hba[b]) return (u##size) -1; \
91 return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
92} \
93EXPORT_SYMBOL(in##type);
94
95PCI_PORT_IN(b, 8)
96PCI_PORT_IN(w, 16)
97PCI_PORT_IN(l, 32)
98
99
100#define PCI_PORT_OUT(type, size) \
101void out##type (u##size d, int addr) \
102{ \
103 int b = PCI_PORT_HBA(addr); \
104 EISA_OUT(size); \
105 if (!parisc_pci_hba[b]) return; \
106 pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \
107} \
108EXPORT_SYMBOL(out##type);
109
110PCI_PORT_OUT(b, 8)
111PCI_PORT_OUT(w, 16)
112PCI_PORT_OUT(l, 32)
113
114
115
116/*
117 * BIOS32 replacement.
118 */
119static int __init pcibios_init(void)
120{
121 if (!pci_bios)
122 return -1;
123
124 if (pci_bios->init) {
125 pci_bios->init();
126 } else {
127 printk(KERN_WARNING "pci_bios != NULL but init() is!\n");
128 }
129 return 0;
130}
131
132
133/* Called from pci_do_scan_bus() *after* walking a bus but before walking PPBs. */
134void pcibios_fixup_bus(struct pci_bus *bus)
135{
136 if (pci_bios->fixup_bus) {
137 pci_bios->fixup_bus(bus);
138 } else {
139 printk(KERN_WARNING "pci_bios != NULL but fixup_bus() is!\n");
140 }
141}
142
143
144char *pcibios_setup(char *str)
145{
146 return str;
147}
148
149/*
150 * Called by pci_set_master() - a driver interface.
151 *
152 * Legacy PDC guarantees to set:
153 * Map Memory BAR's into PA IO space.
154 * Map Expansion ROM BAR into one common PA IO space per bus.
155 * Map IO BAR's into PCI IO space.
156 * Command (see below)
157 * Cache Line Size
158 * Latency Timer
159 * Interrupt Line
160 * PPB: secondary latency timer, io/mmio base/limit,
161 * bus numbers, bridge control
162 *
163 */
164void pcibios_set_master(struct pci_dev *dev)
165{
166 u8 lat;
167
168 /* If someone already mucked with this, don't touch it. */
169 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
170 if (lat >= 16) return;
171
172 /*
173 ** HP generally has fewer devices on the bus than other architectures.
174 ** upper byte is PCI_LATENCY_TIMER.
175 */
176 pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
177 (0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
178}
179
180
181void __init pcibios_init_bus(struct pci_bus *bus)
182{
183 struct pci_dev *dev = bus->self;
184 unsigned short bridge_ctl;
185
186 /* We deal only with pci controllers and pci-pci bridges. */
187 if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
188 return;
189
190 /* PCI-PCI bridge - set the cache line and default latency
191 (32) for primary and secondary buses. */
192 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
193
194 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
195 bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
196 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
197}
198
199
200/* KLUGE: Link the child and parent resources - generic PCI didn't */
201static void
202pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
203{
204 if (!r->parent) {
205 printk(KERN_EMERG "PCI: Tell willy he's wrong\n");
206 r->parent = hba_res;
207
208 /* reverse link is harder *sigh* */
209 if (r->parent->child) {
210 if (r->parent->sibling) {
211 struct resource *next = r->parent->sibling;
212 while (next->sibling)
213 next = next->sibling;
214 next->sibling = r;
215 } else {
216 r->parent->sibling = r;
217 }
218 } else
219 r->parent->child = r;
220 }
221}
222
223/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */
224void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
225 struct pci_bus_region *region, struct resource *res)
226{
227 struct pci_bus *bus = dev->bus;
228 struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
229
230 if (res->flags & IORESOURCE_IO) {
231 /*
232 ** I/O space may see busnumbers here. Something
233 ** in the form of 0xbbxxxx where bb is the bus num
234 ** and xxxx is the I/O port space address.
235 ** Remaining address translation are done in the
236 ** PCI Host adapter specific code - ie dino_out8.
237 */
238 region->start = PCI_PORT_ADDR(res->start);
239 region->end = PCI_PORT_ADDR(res->end);
240 } else if (res->flags & IORESOURCE_MEM) {
241 /* Convert MMIO addr to PCI addr (undo global virtualization) */
242 region->start = PCI_BUS_ADDR(hba, res->start);
243 region->end = PCI_BUS_ADDR(hba, res->end);
244 }
245
246 DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
247 bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
248 region->start, region->end);
249
250 /* KLUGE ALERT
251 ** if this resource isn't linked to a "parent", then it seems
252 ** to be a child of the HBA - lets link it in.
253 */
254 pcibios_link_hba_resources(&hba->io_space, bus->resource[0]);
255 pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
256}
257
258#ifdef CONFIG_HOTPLUG
259EXPORT_SYMBOL(pcibios_resource_to_bus);
260#endif
261
262/*
263 * pcibios align resources() is called every time generic PCI code
264 * wants to generate a new address. The process of looking for
265 * an available address, each candidate is first "aligned" and
266 * then checked if the resource is available until a match is found.
267 *
268 * Since we are just checking candidates, don't use any fields other
269 * than res->start.
270 */
271void pcibios_align_resource(void *data, struct resource *res,
272 unsigned long size, unsigned long alignment)
273{
274 unsigned long mask, align;
275
276 DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
277 pci_name(((struct pci_dev *) data)),
278 res->parent, res->start, res->end,
279 (int) res->flags, size, alignment);
280
281 /* If it's not IO, then it's gotta be MEM */
282 align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
283
284 /* Align to largest of MIN or input size */
285 mask = max(alignment, align) - 1;
286 res->start += mask;
287 res->start &= ~mask;
288
289 /* The caller updates the end field, we don't. */
290}
291
292
293/*
294 * A driver is enabling the device. We make sure that all the appropriate
295 * bits are set to allow the device to operate as the driver is expecting.
296 * We enable the port IO and memory IO bits if the device has any BARs of
297 * that type, and we enable the PERR and SERR bits unconditionally.
298 * Drivers that do not need parity (eg graphics and possibly networking)
299 * can clear these bits if they want.
300 */
301int pcibios_enable_device(struct pci_dev *dev, int mask)
302{
303 u16 cmd;
304 int idx;
305
306 pci_read_config_word(dev, PCI_COMMAND, &cmd);
307
308 for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
309 struct resource *r = &dev->resource[idx];
310
311 /* only setup requested resources */
312 if (!(mask & (1<<idx)))
313 continue;
314
315 if (r->flags & IORESOURCE_IO)
316 cmd |= PCI_COMMAND_IO;
317 if (r->flags & IORESOURCE_MEM)
318 cmd |= PCI_COMMAND_MEMORY;
319 }
320
321 cmd |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
322
323#if 0
324 /* If bridge/bus controller has FBB enabled, child must too. */
325 if (dev->bus->bridge_ctl & PCI_BRIDGE_CTL_FAST_BACK)
326 cmd |= PCI_COMMAND_FAST_BACK;
327#endif
328 DBGC("PCIBIOS: Enabling device %s cmd 0x%04x\n", pci_name(dev), cmd);
329 pci_write_config_word(dev, PCI_COMMAND, cmd);
330 return 0;
331}
332
333
334/* PA-RISC specific */
335void pcibios_register_hba(struct pci_hba_data *hba)
336{
337 if (pci_hba_count >= PCI_HBA_MAX) {
338 printk(KERN_ERR "PCI: Too many Host Bus Adapters\n");
339 return;
340 }
341
342 parisc_pci_hba[pci_hba_count] = hba;
343 hba->hba_num = pci_hba_count++;
344}
345
346subsys_initcall(pcibios_init);
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c
new file mode 100644
index 000000000000..52004ae28d20
--- /dev/null
+++ b/arch/parisc/kernel/pdc_chassis.c
@@ -0,0 +1,245 @@
1/*
2 * interfaces to log Chassis Codes via PDC (firmware)
3 *
4 * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
5 * Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#undef PDC_CHASSIS_DEBUG
23#ifdef PDC_CHASSIS_DEBUG
24#define DPRINTK(fmt, args...) printk(fmt, ## args)
25#else
26#define DPRINTK(fmt, args...)
27#endif
28
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/reboot.h>
32#include <linux/notifier.h>
33
34#include <asm/pdc_chassis.h>
35#include <asm/processor.h>
36#include <asm/pdc.h>
37#include <asm/pdcpat.h>
38
39
40#ifdef CONFIG_PDC_CHASSIS
41static int pdc_chassis_old = 0;
42static unsigned int pdc_chassis_enabled = 1;
43
44
45/**
46 * pdc_chassis_setup() - Enable/disable pdc_chassis code at boot time.
47 * @str configuration param: 0 to disable chassis log
48 * @return 1
49 */
50
51static int __init pdc_chassis_setup(char *str)
52{
53 /*panic_timeout = simple_strtoul(str, NULL, 0);*/
54 get_option(&str, &pdc_chassis_enabled);
55 return 1;
56}
57__setup("pdcchassis=", pdc_chassis_setup);
58
59
60/**
61 * pdc_chassis_checkold() - Checks for old PDC_CHASSIS compatibility
62 * @pdc_chassis_old: 1 if old pdc chassis style
63 *
64 * Currently, only E class and A180 are known to work with this.
65 * Inspired by Christoph Plattner
66 */
67
68static void __init pdc_chassis_checkold(void)
69{
70 switch(CPU_HVERSION) {
71 case 0x480: /* E25 */
72 case 0x481: /* E35 */
73 case 0x482: /* E45 */
74 case 0x483: /* E55 */
75 case 0x516: /* A180 */
76 pdc_chassis_old = 1;
77 break;
78
79 default:
80 break;
81 }
82 DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old);
83}
84
85
86/**
87 * pdc_chassis_panic_event() - Called by the panic handler.
88 *
89 * As soon as a panic occurs, we should inform the PDC.
90 */
91
92static int pdc_chassis_panic_event(struct notifier_block *this,
93 unsigned long event, void *ptr)
94{
95 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
96 return NOTIFY_DONE;
97}
98
99
100static struct notifier_block pdc_chassis_panic_block = {
101 .notifier_call = pdc_chassis_panic_event,
102 .priority = INT_MAX,
103};
104
105
106/**
107 * parisc_reboot_event() - Called by the reboot handler.
108 *
109 * As soon as a reboot occurs, we should inform the PDC.
110 */
111
112static int pdc_chassis_reboot_event(struct notifier_block *this,
113 unsigned long event, void *ptr)
114{
115 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
116 return NOTIFY_DONE;
117}
118
119
120static struct notifier_block pdc_chassis_reboot_block = {
121 .notifier_call = pdc_chassis_reboot_event,
122 .priority = INT_MAX,
123};
124#endif /* CONFIG_PDC_CHASSIS */
125
126
127/**
128 * parisc_pdc_chassis_init() - Called at boot time.
129 */
130
131void __init parisc_pdc_chassis_init(void)
132{
133#ifdef CONFIG_PDC_CHASSIS
134 int handle = 0;
135 if (pdc_chassis_enabled) {
136 DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
137
138 /* Let see if we have something to handle... */
139 /* Check for PDC_PAT or old LED Panel */
140 pdc_chassis_checkold();
141 if (is_pdc_pat()) {
142 printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
143 handle = 1;
144 }
145 else if (pdc_chassis_old) {
146 printk(KERN_INFO "Enabling old style chassis LED panel support.\n");
147 handle = 1;
148 }
149
150 if (handle) {
151 /* initialize panic notifier chain */
152 notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block);
153
154 /* initialize reboot notifier chain */
155 register_reboot_notifier(&pdc_chassis_reboot_block);
156 }
157 }
158#endif /* CONFIG_PDC_CHASSIS */
159}
160
161
162/**
163 * pdc_chassis_send_status() - Sends a predefined message to the chassis,
164 * and changes the front panel LEDs according to the new system state
165 * @retval: PDC call return value.
166 *
167 * Only machines with 64 bits PDC PAT and those reported in
168 * pdc_chassis_checkold() are supported atm.
169 *
170 * returns 0 if no error, -1 if no supported PDC is present or invalid message,
171 * else returns the appropriate PDC error code.
172 *
173 * For a list of predefined messages, see asm-parisc/pdc_chassis.h
174 */
175
176int pdc_chassis_send_status(int message)
177{
178 /* Maybe we should do that in an other way ? */
179 int retval = 0;
180#ifdef CONFIG_PDC_CHASSIS
181 if (pdc_chassis_enabled) {
182
183 DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message);
184
185#ifdef CONFIG_64BIT
186 if (is_pdc_pat()) {
187 switch(message) {
188 case PDC_CHASSIS_DIRECT_BSTART:
189 retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BSTART, PDC_CHASSIS_LSTATE_RUN_NORMAL);
190 break;
191
192 case PDC_CHASSIS_DIRECT_BCOMPLETE:
193 retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BCOMPLETE, PDC_CHASSIS_LSTATE_RUN_NORMAL);
194 break;
195
196 case PDC_CHASSIS_DIRECT_SHUTDOWN:
197 retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_SHUTDOWN, PDC_CHASSIS_LSTATE_NONOS);
198 break;
199
200 case PDC_CHASSIS_DIRECT_PANIC:
201 retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_PANIC, PDC_CHASSIS_LSTATE_RUN_CRASHREC);
202 break;
203
204 case PDC_CHASSIS_DIRECT_LPMC:
205 retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_LPMC, PDC_CHASSIS_LSTATE_RUN_SYSINT);
206 break;
207
208 case PDC_CHASSIS_DIRECT_HPMC:
209 retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_HPMC, PDC_CHASSIS_LSTATE_RUN_NCRIT);
210 break;
211
212 default:
213 retval = -1;
214 }
215 } else retval = -1;
216#else
217 if (pdc_chassis_old) {
218 switch (message) {
219 case PDC_CHASSIS_DIRECT_BSTART:
220 case PDC_CHASSIS_DIRECT_BCOMPLETE:
221 retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
222 break;
223
224 case PDC_CHASSIS_DIRECT_SHUTDOWN:
225 retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_SHUT));
226 break;
227
228 case PDC_CHASSIS_DIRECT_HPMC:
229 case PDC_CHASSIS_DIRECT_PANIC:
230 retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_FLT));
231 break;
232
233 case PDC_CHASSIS_DIRECT_LPMC:
234 retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_WARN));
235 break;
236
237 default:
238 retval = -1;
239 }
240 } else retval = -1;
241#endif /* CONFIG_64BIT */
242 } /* if (pdc_chassis_enabled) */
243#endif /* CONFIG_PDC_CHASSIS */
244 return retval;
245}
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
new file mode 100644
index 000000000000..01f676d1673b
--- /dev/null
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -0,0 +1,189 @@
1/*
2 * PDC Console support - ie use firmware to dump text via boot console
3 *
4 * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
5 * Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
6 * Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
7 * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
8 * Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
9 * Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
10 * Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
11 * Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
12 * Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
13 * Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
14 * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
15 *
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32/*
33 * The PDC console is a simple console, which can be used for debugging
34 * boot related problems on HP PA-RISC machines.
35 *
36 * This code uses the ROM (=PDC) based functions to read and write characters
37 * from and to PDC's boot path.
38 * Since all character read from that path must be polled, this code never
39 * can or will be a fully functional linux console.
40 */
41
42/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems.
43 * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
44#undef EARLY_BOOTUP_DEBUG
45
46
47#include <linux/config.h>
48#include <linux/kernel.h>
49#include <linux/console.h>
50#include <linux/string.h>
51#include <linux/init.h>
52#include <linux/delay.h>
53#include <linux/sched.h>
54#include <linux/interrupt.h>
55#include <linux/major.h>
56#include <linux/tty.h>
57#include <asm/page.h>
58#include <asm/types.h>
59#include <asm/system.h>
60#include <asm/pdc.h> /* for iodc_call() proto and friends */
61
62
63static void pdc_console_write(struct console *co, const char *s, unsigned count)
64{
65 while(count--)
66 pdc_iodc_putc(*s++);
67}
68
69void pdc_outc(unsigned char c)
70{
71 pdc_iodc_outc(c);
72}
73
74void pdc_printf(const char *fmt, ...)
75{
76 va_list args;
77 char buf[1024];
78 int i, len;
79
80 va_start(args, fmt);
81 len = vscnprintf(buf, sizeof(buf), fmt, args);
82 va_end(args);
83
84 for (i = 0; i < len; i++)
85 pdc_iodc_outc(buf[i]);
86}
87
88int pdc_console_poll_key(struct console *co)
89{
90 return pdc_iodc_getc();
91}
92
93static int pdc_console_setup(struct console *co, char *options)
94{
95 return 0;
96}
97
98#if defined(CONFIG_PDC_CONSOLE)
99#define PDC_CONSOLE_DEVICE pdc_console_device
100static struct tty_driver * pdc_console_device (struct console *c, int *index)
101{
102 extern struct tty_driver console_driver;
103 *index = c->index ? c->index-1 : fg_console;
104 return &console_driver;
105}
106#else
107#define PDC_CONSOLE_DEVICE NULL
108#endif
109
110static struct console pdc_cons = {
111 .name = "ttyB",
112 .write = pdc_console_write,
113 .device = PDC_CONSOLE_DEVICE,
114 .setup = pdc_console_setup,
115 .flags = CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
116 .index = -1,
117};
118
119static int pdc_console_initialized;
120extern unsigned long con_start; /* kernel/printk.c */
121extern unsigned long log_end; /* kernel/printk.c */
122
123
124static void pdc_console_init_force(void)
125{
126 if (pdc_console_initialized)
127 return;
128 ++pdc_console_initialized;
129
130 /* If the console is duplex then copy the COUT parameters to CIN. */
131 if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
132 memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
133
134 /* register the pdc console */
135 register_console(&pdc_cons);
136}
137
138void __init pdc_console_init(void)
139{
140#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE)
141 pdc_console_init_force();
142#endif
143#ifdef EARLY_BOOTUP_DEBUG
144 printk(KERN_INFO "Initialized PDC Console for debugging.\n");
145#endif
146}
147
148
149/* Unregister the pdc console with the printk console layer */
150void pdc_console_die(void)
151{
152 if (!pdc_console_initialized)
153 return;
154 --pdc_console_initialized;
155
156 printk(KERN_INFO "Switching from PDC console\n");
157
158 /* Don't repeat what we've already printed */
159 con_start = log_end;
160
161 unregister_console(&pdc_cons);
162}
163
164
165/*
166 * Used for emergencies. Currently only used if an HPMC occurs. If an
167 * HPMC occurs, it is possible that the current console may not be
168 * properly initialed after the PDC IO reset. This routine unregisters all
169 * of the current consoles, reinitializes the pdc console and
170 * registers it.
171 */
172
173void pdc_console_restart(void)
174{
175 struct console *console;
176
177 if (pdc_console_initialized)
178 return;
179
180 while ((console = console_drivers) != NULL)
181 unregister_console(console_drivers);
182
183 /* Don't repeat what we've already printed */
184 con_start = log_end;
185
186 /* force registering the pdc console */
187 pdc_console_init_force();
188}
189
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
new file mode 100644
index 000000000000..b3ad0a505b87
--- /dev/null
+++ b/arch/parisc/kernel/perf.c
@@ -0,0 +1,841 @@
1/*
2 * Parisc performance counters
3 * Copyright (C) 2001 Randolph Chung <tausq@debian.org>
4 *
5 * This code is derived, with permission, from HP/UX sources.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/*
23 * Edited comment from original sources:
24 *
25 * This driver programs the PCX-U/PCX-W performance counters
26 * on the PA-RISC 2.0 chips. The driver keeps all images now
27 * internally to the kernel to hopefully eliminate the possiblity
28 * of a bad image halting the CPU. Also, there are different
29 * images for the PCX-W and later chips vs the PCX-U chips.
30 *
31 * Only 1 process is allowed to access the driver at any time,
32 * so the only protection that is needed is at open and close.
33 * A variable "perf_enabled" is used to hold the state of the
34 * driver. The spinlock "perf_lock" is used to protect the
35 * modification of the state during open/close operations so
36 * multiple processes don't get into the driver simultaneously.
37 *
38 * This driver accesses the processor directly vs going through
39 * the PDC INTRIGUE calls. This is done to eliminate bugs introduced
40 * in various PDC revisions. The code is much more maintainable
41 * and reliable this way vs having to debug on every version of PDC
42 * on every box.
43 */
44
45#include <linux/init.h>
46#include <linux/proc_fs.h>
47#include <linux/miscdevice.h>
48#include <linux/spinlock.h>
49
50#include <asm/uaccess.h>
51#include <asm/perf.h>
52#include <asm/parisc-device.h>
53#include <asm/processor.h>
54#include <asm/runway.h>
55#include <asm/io.h> /* for __raw_read() */
56
57#include "perf_images.h"
58
59#define MAX_RDR_WORDS 24
60#define PERF_VERSION 2 /* derived from hpux's PI v2 interface */
61
62/* definition of RDR regs */
63struct rdr_tbl_ent {
64 uint16_t width;
65 uint8_t num_words;
66 uint8_t write_control;
67};
68
69static int perf_processor_interface = UNKNOWN_INTF;
70static int perf_enabled = 0;
71static spinlock_t perf_lock;
72struct parisc_device *cpu_device = NULL;
73
74/* RDRs to write for PCX-W */
75static int perf_rdrs_W[] =
76 { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
77
78/* RDRs to write for PCX-U */
79static int perf_rdrs_U[] =
80 { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
81
82/* RDR register descriptions for PCX-W */
83static struct rdr_tbl_ent perf_rdr_tbl_W[] = {
84 { 19, 1, 8 }, /* RDR 0 */
85 { 16, 1, 16 }, /* RDR 1 */
86 { 72, 2, 0 }, /* RDR 2 */
87 { 81, 2, 0 }, /* RDR 3 */
88 { 328, 6, 0 }, /* RDR 4 */
89 { 160, 3, 0 }, /* RDR 5 */
90 { 336, 6, 0 }, /* RDR 6 */
91 { 164, 3, 0 }, /* RDR 7 */
92 { 0, 0, 0 }, /* RDR 8 */
93 { 35, 1, 0 }, /* RDR 9 */
94 { 6, 1, 0 }, /* RDR 10 */
95 { 18, 1, 0 }, /* RDR 11 */
96 { 13, 1, 0 }, /* RDR 12 */
97 { 8, 1, 0 }, /* RDR 13 */
98 { 8, 1, 0 }, /* RDR 14 */
99 { 8, 1, 0 }, /* RDR 15 */
100 { 1530, 24, 0 }, /* RDR 16 */
101 { 16, 1, 0 }, /* RDR 17 */
102 { 4, 1, 0 }, /* RDR 18 */
103 { 0, 0, 0 }, /* RDR 19 */
104 { 152, 3, 24 }, /* RDR 20 */
105 { 152, 3, 24 }, /* RDR 21 */
106 { 233, 4, 48 }, /* RDR 22 */
107 { 233, 4, 48 }, /* RDR 23 */
108 { 71, 2, 0 }, /* RDR 24 */
109 { 71, 2, 0 }, /* RDR 25 */
110 { 11, 1, 0 }, /* RDR 26 */
111 { 18, 1, 0 }, /* RDR 27 */
112 { 128, 2, 0 }, /* RDR 28 */
113 { 0, 0, 0 }, /* RDR 29 */
114 { 16, 1, 0 }, /* RDR 30 */
115 { 16, 1, 0 }, /* RDR 31 */
116};
117
118/* RDR register descriptions for PCX-U */
119static struct rdr_tbl_ent perf_rdr_tbl_U[] = {
120 { 19, 1, 8 }, /* RDR 0 */
121 { 32, 1, 16 }, /* RDR 1 */
122 { 20, 1, 0 }, /* RDR 2 */
123 { 0, 0, 0 }, /* RDR 3 */
124 { 344, 6, 0 }, /* RDR 4 */
125 { 176, 3, 0 }, /* RDR 5 */
126 { 336, 6, 0 }, /* RDR 6 */
127 { 0, 0, 0 }, /* RDR 7 */
128 { 0, 0, 0 }, /* RDR 8 */
129 { 0, 0, 0 }, /* RDR 9 */
130 { 28, 1, 0 }, /* RDR 10 */
131 { 33, 1, 0 }, /* RDR 11 */
132 { 0, 0, 0 }, /* RDR 12 */
133 { 230, 4, 0 }, /* RDR 13 */
134 { 32, 1, 0 }, /* RDR 14 */
135 { 128, 2, 0 }, /* RDR 15 */
136 { 1494, 24, 0 }, /* RDR 16 */
137 { 18, 1, 0 }, /* RDR 17 */
138 { 4, 1, 0 }, /* RDR 18 */
139 { 0, 0, 0 }, /* RDR 19 */
140 { 158, 3, 24 }, /* RDR 20 */
141 { 158, 3, 24 }, /* RDR 21 */
142 { 194, 4, 48 }, /* RDR 22 */
143 { 194, 4, 48 }, /* RDR 23 */
144 { 71, 2, 0 }, /* RDR 24 */
145 { 71, 2, 0 }, /* RDR 25 */
146 { 28, 1, 0 }, /* RDR 26 */
147 { 33, 1, 0 }, /* RDR 27 */
148 { 88, 2, 0 }, /* RDR 28 */
149 { 32, 1, 0 }, /* RDR 29 */
150 { 24, 1, 0 }, /* RDR 30 */
151 { 16, 1, 0 }, /* RDR 31 */
152};
153
154/*
155 * A non-zero write_control in the above tables is a byte offset into
156 * this array.
157 */
158static uint64_t perf_bitmasks[] = {
159 0x0000000000000000ul, /* first dbl word must be zero */
160 0xfdffe00000000000ul, /* RDR0 bitmask */
161 0x003f000000000000ul, /* RDR1 bitmask */
162 0x00fffffffffffffful, /* RDR20-RDR21 bitmask (152 bits) */
163 0xfffffffffffffffful,
164 0xfffffffc00000000ul,
165 0xfffffffffffffffful, /* RDR22-RDR23 bitmask (233 bits) */
166 0xfffffffffffffffful,
167 0xfffffffffffffffcul,
168 0xff00000000000000ul
169};
170
171/*
172 * Write control bitmasks for Pa-8700 processor given
173 * somethings have changed slightly.
174 */
175static uint64_t perf_bitmasks_piranha[] = {
176 0x0000000000000000ul, /* first dbl word must be zero */
177 0xfdffe00000000000ul, /* RDR0 bitmask */
178 0x003f000000000000ul, /* RDR1 bitmask */
179 0x00fffffffffffffful, /* RDR20-RDR21 bitmask (158 bits) */
180 0xfffffffffffffffful,
181 0xfffffffc00000000ul,
182 0xfffffffffffffffful, /* RDR22-RDR23 bitmask (210 bits) */
183 0xfffffffffffffffful,
184 0xfffffffffffffffful,
185 0xfffc000000000000ul
186};
187
188static uint64_t *bitmask_array; /* array of bitmasks to use */
189
190/******************************************************************************
191 * Function Prototypes
192 *****************************************************************************/
193static int perf_config(uint32_t *image_ptr);
194static int perf_release(struct inode *inode, struct file *file);
195static int perf_open(struct inode *inode, struct file *file);
196static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
197static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
198 loff_t *ppos);
199static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
200 unsigned long arg);
201static void perf_start_counters(void);
202static int perf_stop_counters(uint32_t *raddr);
203static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
204static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer);
205static int perf_rdr_clear(uint32_t rdr_num);
206static int perf_write_image(uint64_t *memaddr);
207static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer);
208
209/* External Assembly Routines */
210extern uint64_t perf_rdr_shift_in_W (uint32_t rdr_num, uint16_t width);
211extern uint64_t perf_rdr_shift_in_U (uint32_t rdr_num, uint16_t width);
212extern void perf_rdr_shift_out_W (uint32_t rdr_num, uint64_t buffer);
213extern void perf_rdr_shift_out_U (uint32_t rdr_num, uint64_t buffer);
214extern void perf_intrigue_enable_perf_counters (void);
215extern void perf_intrigue_disable_perf_counters (void);
216
217/******************************************************************************
218 * Function Definitions
219 *****************************************************************************/
220
221
222/*
223 * configure:
224 *
225 * Configure the cpu with a given data image. First turn off the counters,
226 * then download the image, then turn the counters back on.
227 */
228static int perf_config(uint32_t *image_ptr)
229{
230 long error;
231 uint32_t raddr[4];
232
233 /* Stop the counters*/
234 error = perf_stop_counters(raddr);
235 if (error != 0) {
236 printk("perf_config: perf_stop_counters = %ld\n", error);
237 return -EINVAL;
238 }
239
240printk("Preparing to write image\n");
241 /* Write the image to the chip */
242 error = perf_write_image((uint64_t *)image_ptr);
243 if (error != 0) {
244 printk("perf_config: DOWNLOAD = %ld\n", error);
245 return -EINVAL;
246 }
247
248printk("Preparing to start counters\n");
249
250 /* Start the counters */
251 perf_start_counters();
252
253 return sizeof(uint32_t);
254}
255
256/*
257 * Open the device and initialize all of its memory. The device is only
258 * opened once, but can be "queried" by multiple processes that know its
259 * file descriptor.
260 */
261static int perf_open(struct inode *inode, struct file *file)
262{
263 spin_lock(&perf_lock);
264 if (perf_enabled) {
265 spin_unlock(&perf_lock);
266 return -EBUSY;
267 }
268 perf_enabled = 1;
269 spin_unlock(&perf_lock);
270
271 return 0;
272}
273
274/*
275 * Close the device.
276 */
277static int perf_release(struct inode *inode, struct file *file)
278{
279 spin_lock(&perf_lock);
280 perf_enabled = 0;
281 spin_unlock(&perf_lock);
282
283 return 0;
284}
285
286/*
287 * Read does nothing for this driver
288 */
289static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
290{
291 return 0;
292}
293
294/*
295 * write:
296 *
297 * This routine downloads the image to the chip. It must be
298 * called on the processor that the download should happen
299 * on.
300 */
301static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
302 loff_t *ppos)
303{
304 int err;
305 size_t image_size;
306 uint32_t image_type;
307 uint32_t interface_type;
308 uint32_t test;
309
310 if (perf_processor_interface == ONYX_INTF)
311 image_size = PCXU_IMAGE_SIZE;
312 else if (perf_processor_interface == CUDA_INTF)
313 image_size = PCXW_IMAGE_SIZE;
314 else
315 return -EFAULT;
316
317 if (!capable(CAP_SYS_ADMIN))
318 return -EACCES;
319
320 if (count != sizeof(uint32_t))
321 return -EIO;
322
323 if ((err = copy_from_user(&image_type, buf, sizeof(uint32_t))) != 0)
324 return err;
325
326 /* Get the interface type and test type */
327 interface_type = (image_type >> 16) & 0xffff;
328 test = (image_type & 0xffff);
329
330 /* Make sure everything makes sense */
331
332 /* First check the machine type is correct for
333 the requested image */
334 if (((perf_processor_interface == CUDA_INTF) &&
335 (interface_type != CUDA_INTF)) ||
336 ((perf_processor_interface == ONYX_INTF) &&
337 (interface_type != ONYX_INTF)))
338 return -EINVAL;
339
340 /* Next check to make sure the requested image
341 is valid */
342 if (((interface_type == CUDA_INTF) &&
343 (test >= MAX_CUDA_IMAGES)) ||
344 ((interface_type == ONYX_INTF) &&
345 (test >= MAX_ONYX_IMAGES)))
346 return -EINVAL;
347
348 /* Copy the image into the processor */
349 if (interface_type == CUDA_INTF)
350 return perf_config(cuda_images[test]);
351 else
352 return perf_config(onyx_images[test]);
353
354 return count;
355}
356
357/*
358 * Patch the images that need to know the IVA addresses.
359 */
360static void perf_patch_images(void)
361{
362#if 0 /* FIXME!! */
363/*
364 * NOTE: this routine is VERY specific to the current TLB image.
365 * If the image is changed, this routine might also need to be changed.
366 */
367 extern void $i_itlb_miss_2_0();
368 extern void $i_dtlb_miss_2_0();
369 extern void PA2_0_iva();
370
371 /*
372 * We can only use the lower 32-bits, the upper 32-bits should be 0
373 * anyway given this is in the kernel
374 */
375 uint32_t itlb_addr = (uint32_t)&($i_itlb_miss_2_0);
376 uint32_t dtlb_addr = (uint32_t)&($i_dtlb_miss_2_0);
377 uint32_t IVAaddress = (uint32_t)&PA2_0_iva;
378
379 if (perf_processor_interface == ONYX_INTF) {
380 /* clear last 2 bytes */
381 onyx_images[TLBMISS][15] &= 0xffffff00;
382 /* set 2 bytes */
383 onyx_images[TLBMISS][15] |= (0x000000ff&((dtlb_addr) >> 24));
384 onyx_images[TLBMISS][16] = (dtlb_addr << 8)&0xffffff00;
385 onyx_images[TLBMISS][17] = itlb_addr;
386
387 /* clear last 2 bytes */
388 onyx_images[TLBHANDMISS][15] &= 0xffffff00;
389 /* set 2 bytes */
390 onyx_images[TLBHANDMISS][15] |= (0x000000ff&((dtlb_addr) >> 24));
391 onyx_images[TLBHANDMISS][16] = (dtlb_addr << 8)&0xffffff00;
392 onyx_images[TLBHANDMISS][17] = itlb_addr;
393
394 /* clear last 2 bytes */
395 onyx_images[BIG_CPI][15] &= 0xffffff00;
396 /* set 2 bytes */
397 onyx_images[BIG_CPI][15] |= (0x000000ff&((dtlb_addr) >> 24));
398 onyx_images[BIG_CPI][16] = (dtlb_addr << 8)&0xffffff00;
399 onyx_images[BIG_CPI][17] = itlb_addr;
400
401 onyx_images[PANIC][15] &= 0xffffff00; /* clear last 2 bytes */
402 onyx_images[PANIC][15] |= (0x000000ff&((IVAaddress) >> 24)); /* set 2 bytes */
403 onyx_images[PANIC][16] = (IVAaddress << 8)&0xffffff00;
404
405
406 } else if (perf_processor_interface == CUDA_INTF) {
407 /* Cuda interface */
408 cuda_images[TLBMISS][16] =
409 (cuda_images[TLBMISS][16]&0xffff0000) |
410 ((dtlb_addr >> 8)&0x0000ffff);
411 cuda_images[TLBMISS][17] =
412 ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
413 cuda_images[TLBMISS][18] = (itlb_addr << 16)&0xffff0000;
414
415 cuda_images[TLBHANDMISS][16] =
416 (cuda_images[TLBHANDMISS][16]&0xffff0000) |
417 ((dtlb_addr >> 8)&0x0000ffff);
418 cuda_images[TLBHANDMISS][17] =
419 ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
420 cuda_images[TLBHANDMISS][18] = (itlb_addr << 16)&0xffff0000;
421
422 cuda_images[BIG_CPI][16] =
423 (cuda_images[BIG_CPI][16]&0xffff0000) |
424 ((dtlb_addr >> 8)&0x0000ffff);
425 cuda_images[BIG_CPI][17] =
426 ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
427 cuda_images[BIG_CPI][18] = (itlb_addr << 16)&0xffff0000;
428 } else {
429 /* Unknown type */
430 }
431#endif
432}
433
434
435/*
436 * ioctl routine
437 * All routines effect the processor that they are executed on. Thus you
438 * must be running on the processor that you wish to change.
439 */
440
441static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
442 unsigned long arg)
443{
444 long error_start;
445 uint32_t raddr[4];
446
447 switch (cmd) {
448
449 case PA_PERF_ON:
450 /* Start the counters */
451 perf_start_counters();
452 return 0;
453
454 case PA_PERF_OFF:
455 error_start = perf_stop_counters(raddr);
456 if (error_start != 0) {
457 printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
458 return -EFAULT;
459 }
460
461 /* copy out the Counters */
462 if (copy_to_user((void __user *)arg, raddr,
463 sizeof (raddr)) != 0) {
464 return -EFAULT;
465 }
466 return 0;
467
468 case PA_PERF_VERSION:
469 /* Return the version # */
470 return put_user(PERF_VERSION, (int *)arg);
471
472 default:
473 break;
474 }
475 return -ENOTTY;
476}
477
478static struct file_operations perf_fops = {
479 .llseek = no_llseek,
480 .read = perf_read,
481 .write = perf_write,
482 .ioctl = perf_ioctl,
483 .open = perf_open,
484 .release = perf_release
485};
486
487static struct miscdevice perf_dev = {
488 MISC_DYNAMIC_MINOR,
489 PA_PERF_DEV,
490 &perf_fops
491};
492
493/*
494 * Initialize the module
495 */
496static int __init perf_init(void)
497{
498 int ret;
499
500 /* Determine correct processor interface to use */
501 bitmask_array = perf_bitmasks;
502
503 if (boot_cpu_data.cpu_type == pcxu ||
504 boot_cpu_data.cpu_type == pcxu_) {
505 perf_processor_interface = ONYX_INTF;
506 } else if (boot_cpu_data.cpu_type == pcxw ||
507 boot_cpu_data.cpu_type == pcxw_ ||
508 boot_cpu_data.cpu_type == pcxw2 ||
509 boot_cpu_data.cpu_type == mako) {
510 perf_processor_interface = CUDA_INTF;
511 if (boot_cpu_data.cpu_type == pcxw2 ||
512 boot_cpu_data.cpu_type == mako)
513 bitmask_array = perf_bitmasks_piranha;
514 } else {
515 perf_processor_interface = UNKNOWN_INTF;
516 printk("Performance monitoring counters not supported on this processor\n");
517 return -ENODEV;
518 }
519
520 ret = misc_register(&perf_dev);
521 if (ret) {
522 printk(KERN_ERR "Performance monitoring counters: "
523 "cannot register misc device.\n");
524 return ret;
525 }
526
527 /* Patch the images to match the system */
528 perf_patch_images();
529
530 spin_lock_init(&perf_lock);
531
532 /* TODO: this only lets us access the first cpu.. what to do for SMP? */
533 cpu_device = cpu_data[0].dev;
534 printk("Performance monitoring counters enabled for %s\n",
535 cpu_data[0].dev->name);
536
537 return 0;
538}
539
540/*
541 * perf_start_counters(void)
542 *
543 * Start the counters.
544 */
545static void perf_start_counters(void)
546{
547 /* Enable performance monitor counters */
548 perf_intrigue_enable_perf_counters();
549}
550
551/*
552 * perf_stop_counters
553 *
554 * Stop the performance counters and save counts
555 * in a per_processor array.
556 */
557static int perf_stop_counters(uint32_t *raddr)
558{
559 uint64_t userbuf[MAX_RDR_WORDS];
560
561 /* Disable performance counters */
562 perf_intrigue_disable_perf_counters();
563
564 if (perf_processor_interface == ONYX_INTF) {
565 uint64_t tmp64;
566 /*
567 * Read the counters
568 */
569 if (!perf_rdr_read_ubuf(16, userbuf))
570 return -13;
571
572 /* Counter0 is bits 1398 thru 1429 */
573 tmp64 = (userbuf[21] << 22) & 0x00000000ffc00000;
574 tmp64 |= (userbuf[22] >> 42) & 0x00000000003fffff;
575 /* OR sticky0 (bit 1430) to counter0 bit 32 */
576 tmp64 |= (userbuf[22] >> 10) & 0x0000000080000000;
577 raddr[0] = (uint32_t)tmp64;
578
579 /* Counter1 is bits 1431 thru 1462 */
580 tmp64 = (userbuf[22] >> 9) & 0x00000000ffffffff;
581 /* OR sticky1 (bit 1463) to counter1 bit 32 */
582 tmp64 |= (userbuf[22] << 23) & 0x0000000080000000;
583 raddr[1] = (uint32_t)tmp64;
584
585 /* Counter2 is bits 1464 thru 1495 */
586 tmp64 = (userbuf[22] << 24) & 0x00000000ff000000;
587 tmp64 |= (userbuf[23] >> 40) & 0x0000000000ffffff;
588 /* OR sticky2 (bit 1496) to counter2 bit 32 */
589 tmp64 |= (userbuf[23] >> 8) & 0x0000000080000000;
590 raddr[2] = (uint32_t)tmp64;
591
592 /* Counter3 is bits 1497 thru 1528 */
593 tmp64 = (userbuf[23] >> 7) & 0x00000000ffffffff;
594 /* OR sticky3 (bit 1529) to counter3 bit 32 */
595 tmp64 |= (userbuf[23] << 25) & 0x0000000080000000;
596 raddr[3] = (uint32_t)tmp64;
597
598 /*
599 * Zero out the counters
600 */
601
602 /*
603 * The counters and sticky-bits comprise the last 132 bits
604 * (1398 - 1529) of RDR16 on a U chip. We'll zero these
605 * out the easy way: zero out last 10 bits of dword 21,
606 * all of dword 22 and 58 bits (plus 6 don't care bits) of
607 * dword 23.
608 */
609 userbuf[21] &= 0xfffffffffffffc00ul; /* 0 to last 10 bits */
610 userbuf[22] = 0;
611 userbuf[23] = 0;
612
613 /*
614 * Write back the zero'ed bytes + the image given
615 * the read was destructive.
616 */
617 perf_rdr_write(16, userbuf);
618 } else {
619
620 /*
621 * Read RDR-15 which contains the counters and sticky bits
622 */
623 if (!perf_rdr_read_ubuf(15, userbuf)) {
624 return -13;
625 }
626
627 /*
628 * Clear out the counters
629 */
630 perf_rdr_clear(15);
631
632 /*
633 * Copy the counters
634 */
635 raddr[0] = (uint32_t)((userbuf[0] >> 32) & 0x00000000ffffffffUL);
636 raddr[1] = (uint32_t)(userbuf[0] & 0x00000000ffffffffUL);
637 raddr[2] = (uint32_t)((userbuf[1] >> 32) & 0x00000000ffffffffUL);
638 raddr[3] = (uint32_t)(userbuf[1] & 0x00000000ffffffffUL);
639 }
640
641 return 0;
642}
643
644/*
645 * perf_rdr_get_entry
646 *
647 * Retrieve a pointer to the description of what this
648 * RDR contains.
649 */
650static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num)
651{
652 if (perf_processor_interface == ONYX_INTF) {
653 return &perf_rdr_tbl_U[rdr_num];
654 } else {
655 return &perf_rdr_tbl_W[rdr_num];
656 }
657}
658
659/*
660 * perf_rdr_read_ubuf
661 *
662 * Read the RDR value into the buffer specified.
663 */
664static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer)
665{
666 uint64_t data, data_mask = 0;
667 uint32_t width, xbits, i;
668 struct rdr_tbl_ent *tentry;
669
670 tentry = perf_rdr_get_entry(rdr_num);
671 if ((width = tentry->width) == 0)
672 return 0;
673
674 /* Clear out buffer */
675 i = tentry->num_words;
676 while (i--) {
677 buffer[i] = 0;
678 }
679
680 /* Check for bits an even number of 64 */
681 if ((xbits = width & 0x03f) != 0) {
682 data_mask = 1;
683 data_mask <<= (64 - xbits);
684 data_mask--;
685 }
686
687 /* Grab all of the data */
688 i = tentry->num_words;
689 while (i--) {
690
691 if (perf_processor_interface == ONYX_INTF) {
692 data = perf_rdr_shift_in_U(rdr_num, width);
693 } else {
694 data = perf_rdr_shift_in_W(rdr_num, width);
695 }
696 if (xbits) {
697 buffer[i] |= (data << (64 - xbits));
698 if (i) {
699 buffer[i-1] |= ((data >> xbits) & data_mask);
700 }
701 } else {
702 buffer[i] = data;
703 }
704 }
705
706 return 1;
707}
708
709/*
710 * perf_rdr_clear
711 *
712 * Zero out the given RDR register
713 */
714static int perf_rdr_clear(uint32_t rdr_num)
715{
716 struct rdr_tbl_ent *tentry;
717 int32_t i;
718
719 tentry = perf_rdr_get_entry(rdr_num);
720
721 if (tentry->width == 0) {
722 return -1;
723 }
724
725 i = tentry->num_words;
726 while (i--) {
727 if (perf_processor_interface == ONYX_INTF) {
728 perf_rdr_shift_out_U(rdr_num, 0UL);
729 } else {
730 perf_rdr_shift_out_W(rdr_num, 0UL);
731 }
732 }
733
734 return 0;
735}
736
737
738/*
739 * perf_write_image
740 *
741 * Write the given image out to the processor
742 */
743static int perf_write_image(uint64_t *memaddr)
744{
745 uint64_t buffer[MAX_RDR_WORDS];
746 uint64_t *bptr;
747 uint32_t dwords;
748 uint32_t *intrigue_rdr;
749 uint64_t *intrigue_bitmask, tmp64, proc_hpa;
750 struct rdr_tbl_ent *tentry;
751 int i;
752
753 /* Clear out counters */
754 if (perf_processor_interface == ONYX_INTF) {
755
756 perf_rdr_clear(16);
757
758 /* Toggle performance monitor */
759 perf_intrigue_enable_perf_counters();
760 perf_intrigue_disable_perf_counters();
761
762 intrigue_rdr = perf_rdrs_U;
763 } else {
764 perf_rdr_clear(15);
765 intrigue_rdr = perf_rdrs_W;
766 }
767
768 /* Write all RDRs */
769 while (*intrigue_rdr != -1) {
770 tentry = perf_rdr_get_entry(*intrigue_rdr);
771 perf_rdr_read_ubuf(*intrigue_rdr, buffer);
772 bptr = &buffer[0];
773 dwords = tentry->num_words;
774 if (tentry->write_control) {
775 intrigue_bitmask = &bitmask_array[tentry->write_control >> 3];
776 while (dwords--) {
777 tmp64 = *intrigue_bitmask & *memaddr++;
778 tmp64 |= (~(*intrigue_bitmask++)) & *bptr;
779 *bptr++ = tmp64;
780 }
781 } else {
782 while (dwords--) {
783 *bptr++ = *memaddr++;
784 }
785 }
786
787 perf_rdr_write(*intrigue_rdr, buffer);
788 intrigue_rdr++;
789 }
790
791 /*
792 * Now copy out the Runway stuff which is not in RDRs
793 */
794
795 if (cpu_device == NULL)
796 {
797 printk(KERN_ERR "write_image: cpu_device not yet initialized!\n");
798 return -1;
799 }
800
801 proc_hpa = cpu_device->hpa;
802
803 /* Merge intrigue bits into Runway STATUS 0 */
804 tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecfffffffffffful;
805 __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), proc_hpa + RUNWAY_STATUS);
806
807 /* Write RUNWAY DEBUG registers */
808 for (i = 0; i < 8; i++) {
809 __raw_writeq(*memaddr++, proc_hpa + RUNWAY_DEBUG + i);
810 }
811
812 return 0;
813}
814
815/*
816 * perf_rdr_write
817 *
818 * Write the given RDR register with the contents
819 * of the given buffer.
820 */
821static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer)
822{
823 struct rdr_tbl_ent *tentry;
824 int32_t i;
825
826printk("perf_rdr_write\n");
827 tentry = perf_rdr_get_entry(rdr_num);
828 if (tentry->width == 0) { return; }
829
830 i = tentry->num_words;
831 while (i--) {
832 if (perf_processor_interface == ONYX_INTF) {
833 perf_rdr_shift_out_U(rdr_num, buffer[i]);
834 } else {
835 perf_rdr_shift_out_W(rdr_num, buffer[i]);
836 }
837 }
838printk("perf_rdr_write done\n");
839}
840
841module_init(perf_init);
diff --git a/arch/parisc/kernel/perf_asm.S b/arch/parisc/kernel/perf_asm.S
new file mode 100644
index 000000000000..adb3c6444910
--- /dev/null
+++ b/arch/parisc/kernel/perf_asm.S
@@ -0,0 +1,1691 @@
1
2/* low-level asm for "intrigue" (PA8500-8700 CPU perf counters)
3 *
4 * Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
5 * Copyright (C) 2001 Hewlett-Packard (Grant Grundler)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/config.h>
23#include <asm/assembly.h>
24
25#ifdef CONFIG_64BIT
26 .level 2.0w
27#endif /* CONFIG_64BIT */
28
29#define MTDIAG_1(gr) .word 0x14201840 + gr*0x10000
30#define MTDIAG_2(gr) .word 0x14401840 + gr*0x10000
31#define MFDIAG_1(gr) .word 0x142008A0 + gr
32#define MFDIAG_2(gr) .word 0x144008A0 + gr
33#define STDIAG(dr) .word 0x14000AA0 + dr*0x200000
34#define SFDIAG(dr) .word 0x14000BA0 + dr*0x200000
35#define DR2_SLOW_RET 53
36
37
38;
39; Enable the performance counters
40;
41; The coprocessor only needs to be enabled when
42; starting/stopping the coprocessor with the pmenb/pmdis.
43;
44 .text
45 .align 32
46
47 .export perf_intrigue_enable_perf_counters,code
48perf_intrigue_enable_perf_counters:
49 .proc
50 .callinfo frame=0,NO_CALLS
51 .entry
52
53 ldi 0x20,%r25 ; load up perfmon bit
54 mfctl ccr,%r26 ; get coprocessor register
55 or %r25,%r26,%r26 ; set bit
56 mtctl %r26,ccr ; turn on performance coprocessor
57 pmenb ; enable performance monitor
58 ssm 0,0 ; dummy op to ensure completion
59 sync ; follow ERS
60 andcm %r26,%r25,%r26 ; clear bit now
61 mtctl %r26,ccr ; turn off performance coprocessor
62 nop ; NOPs as specified in ERS
63 nop
64 nop
65 nop
66 nop
67 nop
68 nop
69 bve (%r2)
70 nop
71 .exit
72 .procend
73
74 .export perf_intrigue_disable_perf_counters,code
75perf_intrigue_disable_perf_counters:
76 .proc
77 .callinfo frame=0,NO_CALLS
78 .entry
79 ldi 0x20,%r25 ; load up perfmon bit
80 mfctl ccr,%r26 ; get coprocessor register
81 or %r25,%r26,%r26 ; set bit
82 mtctl %r26,ccr ; turn on performance coprocessor
83 pmdis ; disable performance monitor
84 ssm 0,0 ; dummy op to ensure completion
85 andcm %r26,%r25,%r26 ; clear bit now
86 bve (%r2)
87 mtctl %r26,ccr ; turn off performance coprocessor
88 .exit
89 .procend
90
91;***********************************************************************
92;*
93;* Name: perf_rdr_shift_in_W
94;*
95;* Description:
96;* This routine shifts data in from the RDR in arg0 and returns
97;* the result in ret0. If the RDR is <= 64 bits in length, it
98;* is shifted shifted backup immediately. This is to compensate
99;* for RDR10 which has bits that preclude PDC stack operations
100;* when they are in the wrong state.
101;*
102;* Arguments:
103;* arg0 : rdr to be read
104;* arg1 : bit length of rdr
105;*
106;* Returns:
107;* ret0 = next 64 bits of rdr data from staging register
108;*
109;* Register usage:
110;* arg0 : rdr to be read
111;* arg1 : bit length of rdr
112;* %r24 - original DR2 value
113;* %r1 - scratch
114;* %r29 - scratch
115;*
116;* Returns:
117;* ret0 = RDR data (right justified)
118;*
119;***********************************************************************
120
121 .export perf_rdr_shift_in_W,code
122perf_rdr_shift_in_W:
123 .proc
124 .callinfo frame=0,NO_CALLS
125 .entry
126;
127; read(shift in) the RDR.
128;
129
130; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
131; shifting is done, from or to, remote diagnose registers.
132;
133
134 depdi,z 1,DR2_SLOW_RET,1,%r29
135 MFDIAG_2 (24)
136 or %r24,%r29,%r29
137 MTDIAG_2 (29) ; set DR2_SLOW_RET
138
139 nop
140 nop
141 nop
142 nop
143
144;
145; Cacheline start (32-byte cacheline)
146;
147 nop
148 nop
149 nop
150 extrd,u arg1,63,6,%r1 ; setup shift amount by bits to move
151
152 mtsar %r1
153 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
154 blr %r1,%r0 ; branch to 8-instruction sequence
155 nop
156
157;
158; Cacheline start (32-byte cacheline)
159;
160
161 ;
162 ; RDR 0 sequence
163 ;
164 SFDIAG (0)
165 ssm 0,0
166 MFDIAG_1 (28)
167 shrpd ret0,%r0,%sar,%r1
168 MTDIAG_1 (1) ; mtdiag %dr1, %r1
169 STDIAG (0)
170 ssm 0,0
171 b,n perf_rdr_shift_in_W_leave
172
173 ;
174 ; RDR 1 sequence
175 ;
176 sync
177 ssm 0,0
178 SFDIAG (1)
179 ssm 0,0
180 MFDIAG_1 (28)
181 ssm 0,0
182 b,n perf_rdr_shift_in_W_leave
183 nop
184
185 ;
186 ; RDR 2 read sequence
187 ;
188 SFDIAG (2)
189 ssm 0,0
190 MFDIAG_1 (28)
191 shrpd ret0,%r0,%sar,%r1
192 MTDIAG_1 (1)
193 STDIAG (2)
194 ssm 0,0
195 b,n perf_rdr_shift_in_W_leave
196
197 ;
198 ; RDR 3 read sequence
199 ;
200 b,n perf_rdr_shift_in_W_leave
201 nop
202 nop
203 nop
204 nop
205 nop
206 nop
207 nop
208
209 ;
210 ; RDR 4 read sequence
211 ;
212 sync
213 ssm 0,0
214 SFDIAG (4)
215 ssm 0,0
216 MFDIAG_1 (28)
217 b,n perf_rdr_shift_in_W_leave
218 ssm 0,0
219 nop
220
221 ;
222 ; RDR 5 read sequence
223 ;
224 sync
225 ssm 0,0
226 SFDIAG (5)
227 ssm 0,0
228 MFDIAG_1 (28)
229 b,n perf_rdr_shift_in_W_leave
230 ssm 0,0
231 nop
232
233 ;
234 ; RDR 6 read sequence
235 ;
236 sync
237 ssm 0,0
238 SFDIAG (6)
239 ssm 0,0
240 MFDIAG_1 (28)
241 b,n perf_rdr_shift_in_W_leave
242 ssm 0,0
243 nop
244
245 ;
246 ; RDR 7 read sequence
247 ;
248 b,n perf_rdr_shift_in_W_leave
249 nop
250 nop
251 nop
252 nop
253 nop
254 nop
255 nop
256
257 ;
258 ; RDR 8 read sequence
259 ;
260 b,n perf_rdr_shift_in_W_leave
261 nop
262 nop
263 nop
264 nop
265 nop
266 nop
267 nop
268
269 ;
270 ; RDR 9 read sequence
271 ;
272 b,n perf_rdr_shift_in_W_leave
273 nop
274 nop
275 nop
276 nop
277 nop
278 nop
279 nop
280
281 ;
282 ; RDR 10 read sequence
283 ;
284 SFDIAG (10)
285 ssm 0,0
286 MFDIAG_1 (28)
287 shrpd ret0,%r0,%sar,%r1
288 MTDIAG_1 (1)
289 STDIAG (10)
290 ssm 0,0
291 b,n perf_rdr_shift_in_W_leave
292
293 ;
294 ; RDR 11 read sequence
295 ;
296 SFDIAG (11)
297 ssm 0,0
298 MFDIAG_1 (28)
299 shrpd ret0,%r0,%sar,%r1
300 MTDIAG_1 (1)
301 STDIAG (11)
302 ssm 0,0
303 b,n perf_rdr_shift_in_W_leave
304
305 ;
306 ; RDR 12 read sequence
307 ;
308 b,n perf_rdr_shift_in_W_leave
309 nop
310 nop
311 nop
312 nop
313 nop
314 nop
315 nop
316
317 ;
318 ; RDR 13 read sequence
319 ;
320 sync
321 ssm 0,0
322 SFDIAG (13)
323 ssm 0,0
324 MFDIAG_1 (28)
325 b,n perf_rdr_shift_in_W_leave
326 ssm 0,0
327 nop
328
329 ;
330 ; RDR 14 read sequence
331 ;
332 SFDIAG (14)
333 ssm 0,0
334 MFDIAG_1 (28)
335 shrpd ret0,%r0,%sar,%r1
336 MTDIAG_1 (1)
337 STDIAG (14)
338 ssm 0,0
339 b,n perf_rdr_shift_in_W_leave
340
341 ;
342 ; RDR 15 read sequence
343 ;
344 sync
345 ssm 0,0
346 SFDIAG (15)
347 ssm 0,0
348 MFDIAG_1 (28)
349 ssm 0,0
350 b,n perf_rdr_shift_in_W_leave
351 nop
352
353 ;
354 ; RDR 16 read sequence
355 ;
356 sync
357 ssm 0,0
358 SFDIAG (16)
359 ssm 0,0
360 MFDIAG_1 (28)
361 b,n perf_rdr_shift_in_W_leave
362 ssm 0,0
363 nop
364
365 ;
366 ; RDR 17 read sequence
367 ;
368 SFDIAG (17)
369 ssm 0,0
370 MFDIAG_1 (28)
371 shrpd ret0,%r0,%sar,%r1
372 MTDIAG_1 (1)
373 STDIAG (17)
374 ssm 0,0
375 b,n perf_rdr_shift_in_W_leave
376
377 ;
378 ; RDR 18 read sequence
379 ;
380 SFDIAG (18)
381 ssm 0,0
382 MFDIAG_1 (28)
383 shrpd ret0,%r0,%sar,%r1
384 MTDIAG_1 (1)
385 STDIAG (18)
386 ssm 0,0
387 b,n perf_rdr_shift_in_W_leave
388
389 ;
390 ; RDR 19 read sequence
391 ;
392 b,n perf_rdr_shift_in_W_leave
393 nop
394 nop
395 nop
396 nop
397 nop
398 nop
399 nop
400
401 ;
402 ; RDR 20 read sequence
403 ;
404 sync
405 ssm 0,0
406 SFDIAG (20)
407 ssm 0,0
408 MFDIAG_1 (28)
409 b,n perf_rdr_shift_in_W_leave
410 ssm 0,0
411 nop
412
413 ;
414 ; RDR 21 read sequence
415 ;
416 sync
417 ssm 0,0
418 SFDIAG (21)
419 ssm 0,0
420 MFDIAG_1 (28)
421 b,n perf_rdr_shift_in_W_leave
422 ssm 0,0
423 nop
424
425 ;
426 ; RDR 22 read sequence
427 ;
428 sync
429 ssm 0,0
430 SFDIAG (22)
431 ssm 0,0
432 MFDIAG_1 (28)
433 b,n perf_rdr_shift_in_W_leave
434 ssm 0,0
435 nop
436
437 ;
438 ; RDR 23 read sequence
439 ;
440 sync
441 ssm 0,0
442 SFDIAG (23)
443 ssm 0,0
444 MFDIAG_1 (28)
445 b,n perf_rdr_shift_in_W_leave
446 ssm 0,0
447 nop
448
449 ;
450 ; RDR 24 read sequence
451 ;
452 sync
453 ssm 0,0
454 SFDIAG (24)
455 ssm 0,0
456 MFDIAG_1 (28)
457 b,n perf_rdr_shift_in_W_leave
458 ssm 0,0
459 nop
460
461 ;
462 ; RDR 25 read sequence
463 ;
464 sync
465 ssm 0,0
466 SFDIAG (25)
467 ssm 0,0
468 MFDIAG_1 (28)
469 b,n perf_rdr_shift_in_W_leave
470 ssm 0,0
471 nop
472
473 ;
474 ; RDR 26 read sequence
475 ;
476 SFDIAG (26)
477 ssm 0,0
478 MFDIAG_1 (28)
479 shrpd ret0,%r0,%sar,%r1
480 MTDIAG_1 (1)
481 STDIAG (26)
482 ssm 0,0
483 b,n perf_rdr_shift_in_W_leave
484
485 ;
486 ; RDR 27 read sequence
487 ;
488 SFDIAG (27)
489 ssm 0,0
490 MFDIAG_1 (28)
491 shrpd ret0,%r0,%sar,%r1
492 MTDIAG_1 (1)
493 STDIAG (27)
494 ssm 0,0
495 b,n perf_rdr_shift_in_W_leave
496
497 ;
498 ; RDR 28 read sequence
499 ;
500 sync
501 ssm 0,0
502 SFDIAG (28)
503 ssm 0,0
504 MFDIAG_1 (28)
505 b,n perf_rdr_shift_in_W_leave
506 ssm 0,0
507 nop
508
509 ;
510 ; RDR 29 read sequence
511 ;
512 sync
513 ssm 0,0
514 SFDIAG (29)
515 ssm 0,0
516 MFDIAG_1 (28)
517 b,n perf_rdr_shift_in_W_leave
518 ssm 0,0
519 nop
520
521 ;
522 ; RDR 30 read sequence
523 ;
524 SFDIAG (30)
525 ssm 0,0
526 MFDIAG_1 (28)
527 shrpd ret0,%r0,%sar,%r1
528 MTDIAG_1 (1)
529 STDIAG (30)
530 ssm 0,0
531 b,n perf_rdr_shift_in_W_leave
532
533 ;
534 ; RDR 31 read sequence
535 ;
536 sync
537 ssm 0,0
538 SFDIAG (31)
539 ssm 0,0
540 MFDIAG_1 (28)
541 nop
542 ssm 0,0
543 nop
544
545 ;
546 ; Fallthrough
547 ;
548
549perf_rdr_shift_in_W_leave:
550 bve (%r2)
551 .exit
552 MTDIAG_2 (24) ; restore DR2
553 .procend
554
555
556;***********************************************************************
557;*
558;* Name: perf_rdr_shift_out_W
559;*
560;* Description:
561;* This routine moves data to the RDR's. The double-word that
562;* arg1 points to is loaded and moved into the staging register.
563;* Then the STDIAG instruction for the RDR # in arg0 is called
564;* to move the data to the RDR.
565;*
566;* Arguments:
567;* arg0 = rdr number
568;* arg1 = 64-bit value to write
569;* %r24 - DR2 | DR2_SLOW_RET
570;* %r23 - original DR2 value
571;*
572;* Returns:
573;* None
574;*
575;* Register usage:
576;*
577;***********************************************************************
578
579 .export perf_rdr_shift_out_W,code
580perf_rdr_shift_out_W:
581 .proc
582 .callinfo frame=0,NO_CALLS
583 .entry
584;
585; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
586; shifting is done, from or to, the remote diagnose registers.
587;
588
589 depdi,z 1,DR2_SLOW_RET,1,%r24
590 MFDIAG_2 (23)
591 or %r24,%r23,%r24
592 MTDIAG_2 (24) ; set DR2_SLOW_RET
593 MTDIAG_1 (25) ; data to the staging register
594 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
595 blr %r1,%r0 ; branch to 8-instruction sequence
596 nop
597
598 ;
599 ; RDR 0 write sequence
600 ;
601 sync ; RDR 0 write sequence
602 ssm 0,0
603 STDIAG (0)
604 ssm 0,0
605 b,n perf_rdr_shift_out_W_leave
606 nop
607 ssm 0,0
608 nop
609
610 ;
611 ; RDR 1 write sequence
612 ;
613 sync
614 ssm 0,0
615 STDIAG (1)
616 ssm 0,0
617 b,n perf_rdr_shift_out_W_leave
618 nop
619 ssm 0,0
620 nop
621
622 ;
623 ; RDR 2 write sequence
624 ;
625 sync
626 ssm 0,0
627 STDIAG (2)
628 ssm 0,0
629 b,n perf_rdr_shift_out_W_leave
630 nop
631 ssm 0,0
632 nop
633
634 ;
635 ; RDR 3 write sequence
636 ;
637 sync
638 ssm 0,0
639 STDIAG (3)
640 ssm 0,0
641 b,n perf_rdr_shift_out_W_leave
642 nop
643 ssm 0,0
644 nop
645
646 ;
647 ; RDR 4 write sequence
648 ;
649 sync
650 ssm 0,0
651 STDIAG (4)
652 ssm 0,0
653 b,n perf_rdr_shift_out_W_leave
654 nop
655 ssm 0,0
656 nop
657
658 ;
659 ; RDR 5 write sequence
660 ;
661 sync
662 ssm 0,0
663 STDIAG (5)
664 ssm 0,0
665 b,n perf_rdr_shift_out_W_leave
666 nop
667 ssm 0,0
668 nop
669
670 ;
671 ; RDR 6 write sequence
672 ;
673 sync
674 ssm 0,0
675 STDIAG (6)
676 ssm 0,0
677 b,n perf_rdr_shift_out_W_leave
678 nop
679 ssm 0,0
680 nop
681
682 ;
683 ; RDR 7 write sequence
684 ;
685 sync
686 ssm 0,0
687 STDIAG (7)
688 ssm 0,0
689 b,n perf_rdr_shift_out_W_leave
690 nop
691 ssm 0,0
692 nop
693
694 ;
695 ; RDR 8 write sequence
696 ;
697 sync
698 ssm 0,0
699 STDIAG (8)
700 ssm 0,0
701 b,n perf_rdr_shift_out_W_leave
702 nop
703 ssm 0,0
704 nop
705
706 ;
707 ; RDR 9 write sequence
708 ;
709 sync
710 ssm 0,0
711 STDIAG (9)
712 ssm 0,0
713 b,n perf_rdr_shift_out_W_leave
714 nop
715 ssm 0,0
716 nop
717
718 ;
719 ; RDR 10 write sequence
720 ;
721 sync
722 ssm 0,0
723 STDIAG (10)
724 STDIAG (26)
725 ssm 0,0
726 b,n perf_rdr_shift_out_W_leave
727 ssm 0,0
728 nop
729
730 ;
731 ; RDR 11 write sequence
732 ;
733 sync
734 ssm 0,0
735 STDIAG (11)
736 STDIAG (27)
737 ssm 0,0
738 b,n perf_rdr_shift_out_W_leave
739 ssm 0,0
740 nop
741
742 ;
743 ; RDR 12 write sequence
744 ;
745 sync
746 ssm 0,0
747 STDIAG (12)
748 ssm 0,0
749 b,n perf_rdr_shift_out_W_leave
750 nop
751 ssm 0,0
752 nop
753
754 ;
755 ; RDR 13 write sequence
756 ;
757 sync
758 ssm 0,0
759 STDIAG (13)
760 ssm 0,0
761 b,n perf_rdr_shift_out_W_leave
762 nop
763 ssm 0,0
764 nop
765
766 ;
767 ; RDR 14 write sequence
768 ;
769 sync
770 ssm 0,0
771 STDIAG (14)
772 ssm 0,0
773 b,n perf_rdr_shift_out_W_leave
774 nop
775 ssm 0,0
776 nop
777
778 ;
779 ; RDR 15 write sequence
780 ;
781 sync
782 ssm 0,0
783 STDIAG (15)
784 ssm 0,0
785 b,n perf_rdr_shift_out_W_leave
786 nop
787 ssm 0,0
788 nop
789
790 ;
791 ; RDR 16 write sequence
792 ;
793 sync
794 ssm 0,0
795 STDIAG (16)
796 ssm 0,0
797 b,n perf_rdr_shift_out_W_leave
798 nop
799 ssm 0,0
800 nop
801
802 ;
803 ; RDR 17 write sequence
804 ;
805 sync
806 ssm 0,0
807 STDIAG (17)
808 ssm 0,0
809 b,n perf_rdr_shift_out_W_leave
810 nop
811 ssm 0,0
812 nop
813
814 ;
815 ; RDR 18 write sequence
816 ;
817 sync
818 ssm 0,0
819 STDIAG (18)
820 ssm 0,0
821 b,n perf_rdr_shift_out_W_leave
822 nop
823 ssm 0,0
824 nop
825
826 ;
827 ; RDR 19 write sequence
828 ;
829 sync
830 ssm 0,0
831 STDIAG (19)
832 ssm 0,0
833 b,n perf_rdr_shift_out_W_leave
834 nop
835 ssm 0,0
836 nop
837
838 ;
839 ; RDR 20 write sequence
840 ;
841 sync
842 ssm 0,0
843 STDIAG (20)
844 ssm 0,0
845 b,n perf_rdr_shift_out_W_leave
846 nop
847 ssm 0,0
848 nop
849
850 ;
851 ; RDR 21 write sequence
852 ;
853 sync
854 ssm 0,0
855 STDIAG (21)
856 ssm 0,0
857 b,n perf_rdr_shift_out_W_leave
858 nop
859 ssm 0,0
860 nop
861
862 ;
863 ; RDR 22 write sequence
864 ;
865 sync
866 ssm 0,0
867 STDIAG (22)
868 ssm 0,0
869 b,n perf_rdr_shift_out_W_leave
870 nop
871 ssm 0,0
872 nop
873
874 ;
875 ; RDR 23 write sequence
876 ;
877 sync
878 ssm 0,0
879 STDIAG (23)
880 ssm 0,0
881 b,n perf_rdr_shift_out_W_leave
882 nop
883 ssm 0,0
884 nop
885
886 ;
887 ; RDR 24 write sequence
888 ;
889 sync
890 ssm 0,0
891 STDIAG (24)
892 ssm 0,0
893 b,n perf_rdr_shift_out_W_leave
894 nop
895 ssm 0,0
896 nop
897
898 ;
899 ; RDR 25 write sequence
900 ;
901 sync
902 ssm 0,0
903 STDIAG (25)
904 ssm 0,0
905 b,n perf_rdr_shift_out_W_leave
906 nop
907 ssm 0,0
908 nop
909
910 ;
911 ; RDR 26 write sequence
912 ;
913 sync
914 ssm 0,0
915 STDIAG (10)
916 STDIAG (26)
917 ssm 0,0
918 b,n perf_rdr_shift_out_W_leave
919 ssm 0,0
920 nop
921
922 ;
923 ; RDR 27 write sequence
924 ;
925 sync
926 ssm 0,0
927 STDIAG (11)
928 STDIAG (27)
929 ssm 0,0
930 b,n perf_rdr_shift_out_W_leave
931 ssm 0,0
932 nop
933
934 ;
935 ; RDR 28 write sequence
936 ;
937 sync
938 ssm 0,0
939 STDIAG (28)
940 ssm 0,0
941 b,n perf_rdr_shift_out_W_leave
942 nop
943 ssm 0,0
944 nop
945
946 ;
947 ; RDR 29 write sequence
948 ;
949 sync
950 ssm 0,0
951 STDIAG (29)
952 ssm 0,0
953 b,n perf_rdr_shift_out_W_leave
954 nop
955 ssm 0,0
956 nop
957
958 ;
959 ; RDR 30 write sequence
960 ;
961 sync
962 ssm 0,0
963 STDIAG (30)
964 ssm 0,0
965 b,n perf_rdr_shift_out_W_leave
966 nop
967 ssm 0,0
968 nop
969
970 ;
971 ; RDR 31 write sequence
972 ;
973 sync
974 ssm 0,0
975 STDIAG (31)
976 ssm 0,0
977 b,n perf_rdr_shift_out_W_leave
978 nop
979 ssm 0,0
980 nop
981
982perf_rdr_shift_out_W_leave:
983 bve (%r2)
984 .exit
985 MTDIAG_2 (23) ; restore DR2
986 .procend
987
988
989;***********************************************************************
990;*
991;* Name: rdr_shift_in_U
992;*
993;* Description:
994;* This routine shifts data in from the RDR in arg0 and returns
995;* the result in ret0. If the RDR is <= 64 bits in length, it
996;* is shifted shifted backup immediately. This is to compensate
997;* for RDR10 which has bits that preclude PDC stack operations
998;* when they are in the wrong state.
999;*
1000;* Arguments:
1001;* arg0 : rdr to be read
1002;* arg1 : bit length of rdr
1003;*
1004;* Returns:
1005;* ret0 = next 64 bits of rdr data from staging register
1006;*
1007;* Register usage:
1008;* arg0 : rdr to be read
1009;* arg1 : bit length of rdr
1010;* %r24 - original DR2 value
1011;* %r23 - DR2 | DR2_SLOW_RET
1012;* %r1 - scratch
1013;*
1014;***********************************************************************
1015
1016 .export perf_rdr_shift_in_U,code
1017perf_rdr_shift_in_U:
1018 .proc
1019 .callinfo frame=0,NO_CALLS
1020 .entry
1021
1022; read(shift in) the RDR.
1023;
1024; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1025; shifting is done, from or to, remote diagnose registers.
1026
1027 depdi,z 1,DR2_SLOW_RET,1,%r29
1028 MFDIAG_2 (24)
1029 or %r24,%r29,%r29
1030 MTDIAG_2 (29) ; set DR2_SLOW_RET
1031
1032 nop
1033 nop
1034 nop
1035 nop
1036
1037;
1038; Start of next 32-byte cacheline
1039;
1040 nop
1041 nop
1042 nop
1043 extrd,u arg1,63,6,%r1
1044
1045 mtsar %r1
1046 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1047 blr %r1,%r0 ; branch to 8-instruction sequence
1048 nop
1049
1050;
1051; Start of next 32-byte cacheline
1052;
1053 SFDIAG (0) ; RDR 0 read sequence
1054 ssm 0,0
1055 MFDIAG_1 (28)
1056 shrpd ret0,%r0,%sar,%r1
1057 MTDIAG_1 (1)
1058 STDIAG (0)
1059 ssm 0,0
1060 b,n perf_rdr_shift_in_U_leave
1061
1062 SFDIAG (1) ; RDR 1 read sequence
1063 ssm 0,0
1064 MFDIAG_1 (28)
1065 shrpd ret0,%r0,%sar,%r1
1066 MTDIAG_1 (1)
1067 STDIAG (1)
1068 ssm 0,0
1069 b,n perf_rdr_shift_in_U_leave
1070
1071 sync ; RDR 2 read sequence
1072 ssm 0,0
1073 SFDIAG (4)
1074 ssm 0,0
1075 MFDIAG_1 (28)
1076 b,n perf_rdr_shift_in_U_leave
1077 ssm 0,0
1078 nop
1079
1080 sync ; RDR 3 read sequence
1081 ssm 0,0
1082 SFDIAG (3)
1083 ssm 0,0
1084 MFDIAG_1 (28)
1085 b,n perf_rdr_shift_in_U_leave
1086 ssm 0,0
1087 nop
1088
1089 sync ; RDR 4 read sequence
1090 ssm 0,0
1091 SFDIAG (4)
1092 ssm 0,0
1093 MFDIAG_1 (28)
1094 b,n perf_rdr_shift_in_U_leave
1095 ssm 0,0
1096 nop
1097
1098 sync ; RDR 5 read sequence
1099 ssm 0,0
1100 SFDIAG (5)
1101 ssm 0,0
1102 MFDIAG_1 (28)
1103 b,n perf_rdr_shift_in_U_leave
1104 ssm 0,0
1105 nop
1106
1107 sync ; RDR 6 read sequence
1108 ssm 0,0
1109 SFDIAG (6)
1110 ssm 0,0
1111 MFDIAG_1 (28)
1112 b,n perf_rdr_shift_in_U_leave
1113 ssm 0,0
1114 nop
1115
1116 sync ; RDR 7 read sequence
1117 ssm 0,0
1118 SFDIAG (7)
1119 ssm 0,0
1120 MFDIAG_1 (28)
1121 b,n perf_rdr_shift_in_U_leave
1122 ssm 0,0
1123 nop
1124
1125 b,n perf_rdr_shift_in_U_leave
1126 nop
1127 nop
1128 nop
1129 nop
1130 nop
1131 nop
1132 nop
1133
1134 SFDIAG (9) ; RDR 9 read sequence
1135 ssm 0,0
1136 MFDIAG_1 (28)
1137 shrpd ret0,%r0,%sar,%r1
1138 MTDIAG_1 (1)
1139 STDIAG (9)
1140 ssm 0,0
1141 b,n perf_rdr_shift_in_U_leave
1142
1143 SFDIAG (10) ; RDR 10 read sequence
1144 ssm 0,0
1145 MFDIAG_1 (28)
1146 shrpd ret0,%r0,%sar,%r1
1147 MTDIAG_1 (1)
1148 STDIAG (10)
1149 ssm 0,0
1150 b,n perf_rdr_shift_in_U_leave
1151
1152 SFDIAG (11) ; RDR 11 read sequence
1153 ssm 0,0
1154 MFDIAG_1 (28)
1155 shrpd ret0,%r0,%sar,%r1
1156 MTDIAG_1 (1)
1157 STDIAG (11)
1158 ssm 0,0
1159 b,n perf_rdr_shift_in_U_leave
1160
1161 SFDIAG (12) ; RDR 12 read sequence
1162 ssm 0,0
1163 MFDIAG_1 (28)
1164 shrpd ret0,%r0,%sar,%r1
1165 MTDIAG_1 (1)
1166 STDIAG (12)
1167 ssm 0,0
1168 b,n perf_rdr_shift_in_U_leave
1169
1170 SFDIAG (13) ; RDR 13 read sequence
1171 ssm 0,0
1172 MFDIAG_1 (28)
1173 shrpd ret0,%r0,%sar,%r1
1174 MTDIAG_1 (1)
1175 STDIAG (13)
1176 ssm 0,0
1177 b,n perf_rdr_shift_in_U_leave
1178
1179 SFDIAG (14) ; RDR 14 read sequence
1180 ssm 0,0
1181 MFDIAG_1 (28)
1182 shrpd ret0,%r0,%sar,%r1
1183 MTDIAG_1 (1)
1184 STDIAG (14)
1185 ssm 0,0
1186 b,n perf_rdr_shift_in_U_leave
1187
1188 SFDIAG (15) ; RDR 15 read sequence
1189 ssm 0,0
1190 MFDIAG_1 (28)
1191 shrpd ret0,%r0,%sar,%r1
1192 MTDIAG_1 (1)
1193 STDIAG (15)
1194 ssm 0,0
1195 b,n perf_rdr_shift_in_U_leave
1196
1197 sync ; RDR 16 read sequence
1198 ssm 0,0
1199 SFDIAG (16)
1200 ssm 0,0
1201 MFDIAG_1 (28)
1202 b,n perf_rdr_shift_in_U_leave
1203 ssm 0,0
1204 nop
1205
1206 SFDIAG (17) ; RDR 17 read sequence
1207 ssm 0,0
1208 MFDIAG_1 (28)
1209 shrpd ret0,%r0,%sar,%r1
1210 MTDIAG_1 (1)
1211 STDIAG (17)
1212 ssm 0,0
1213 b,n perf_rdr_shift_in_U_leave
1214
1215 SFDIAG (18) ; RDR 18 read sequence
1216 ssm 0,0
1217 MFDIAG_1 (28)
1218 shrpd ret0,%r0,%sar,%r1
1219 MTDIAG_1 (1)
1220 STDIAG (18)
1221 ssm 0,0
1222 b,n perf_rdr_shift_in_U_leave
1223
1224 b,n perf_rdr_shift_in_U_leave
1225 nop
1226 nop
1227 nop
1228 nop
1229 nop
1230 nop
1231 nop
1232
1233 sync ; RDR 20 read sequence
1234 ssm 0,0
1235 SFDIAG (20)
1236 ssm 0,0
1237 MFDIAG_1 (28)
1238 b,n perf_rdr_shift_in_U_leave
1239 ssm 0,0
1240 nop
1241
1242 sync ; RDR 21 read sequence
1243 ssm 0,0
1244 SFDIAG (21)
1245 ssm 0,0
1246 MFDIAG_1 (28)
1247 b,n perf_rdr_shift_in_U_leave
1248 ssm 0,0
1249 nop
1250
1251 sync ; RDR 22 read sequence
1252 ssm 0,0
1253 SFDIAG (22)
1254 ssm 0,0
1255 MFDIAG_1 (28)
1256 b,n perf_rdr_shift_in_U_leave
1257 ssm 0,0
1258 nop
1259
1260 sync ; RDR 23 read sequence
1261 ssm 0,0
1262 SFDIAG (23)
1263 ssm 0,0
1264 MFDIAG_1 (28)
1265 b,n perf_rdr_shift_in_U_leave
1266 ssm 0,0
1267 nop
1268
1269 sync ; RDR 24 read sequence
1270 ssm 0,0
1271 SFDIAG (24)
1272 ssm 0,0
1273 MFDIAG_1 (28)
1274 b,n perf_rdr_shift_in_U_leave
1275 ssm 0,0
1276 nop
1277
1278 sync ; RDR 25 read sequence
1279 ssm 0,0
1280 SFDIAG (25)
1281 ssm 0,0
1282 MFDIAG_1 (28)
1283 b,n perf_rdr_shift_in_U_leave
1284 ssm 0,0
1285 nop
1286
1287 SFDIAG (26) ; RDR 26 read sequence
1288 ssm 0,0
1289 MFDIAG_1 (28)
1290 shrpd ret0,%r0,%sar,%r1
1291 MTDIAG_1 (1)
1292 STDIAG (26)
1293 ssm 0,0
1294 b,n perf_rdr_shift_in_U_leave
1295
1296 SFDIAG (27) ; RDR 27 read sequence
1297 ssm 0,0
1298 MFDIAG_1 (28)
1299 shrpd ret0,%r0,%sar,%r1
1300 MTDIAG_1 (1)
1301 STDIAG (27)
1302 ssm 0,0
1303 b,n perf_rdr_shift_in_U_leave
1304
1305 sync ; RDR 28 read sequence
1306 ssm 0,0
1307 SFDIAG (28)
1308 ssm 0,0
1309 MFDIAG_1 (28)
1310 b,n perf_rdr_shift_in_U_leave
1311 ssm 0,0
1312 nop
1313
1314 b,n perf_rdr_shift_in_U_leave
1315 nop
1316 nop
1317 nop
1318 nop
1319 nop
1320 nop
1321 nop
1322
1323 SFDIAG (30) ; RDR 30 read sequence
1324 ssm 0,0
1325 MFDIAG_1 (28)
1326 shrpd ret0,%r0,%sar,%r1
1327 MTDIAG_1 (1)
1328 STDIAG (30)
1329 ssm 0,0
1330 b,n perf_rdr_shift_in_U_leave
1331
1332 SFDIAG (31) ; RDR 31 read sequence
1333 ssm 0,0
1334 MFDIAG_1 (28)
1335 shrpd ret0,%r0,%sar,%r1
1336 MTDIAG_1 (1)
1337 STDIAG (31)
1338 ssm 0,0
1339 b,n perf_rdr_shift_in_U_leave
1340 nop
1341
1342perf_rdr_shift_in_U_leave:
1343 bve (%r2)
1344 .exit
1345 MTDIAG_2 (24) ; restore DR2
1346 .procend
1347
1348;***********************************************************************
1349;*
1350;* Name: rdr_shift_out_U
1351;*
1352;* Description:
1353;* This routine moves data to the RDR's. The double-word that
1354;* arg1 points to is loaded and moved into the staging register.
1355;* Then the STDIAG instruction for the RDR # in arg0 is called
1356;* to move the data to the RDR.
1357;*
1358;* Arguments:
1359;* arg0 = rdr target
1360;* arg1 = buffer pointer
1361;*
1362;* Returns:
1363;* None
1364;*
1365;* Register usage:
1366;* arg0 = rdr target
1367;* arg1 = buffer pointer
1368;* %r24 - DR2 | DR2_SLOW_RET
1369;* %r23 - original DR2 value
1370;*
1371;***********************************************************************
1372
1373 .export perf_rdr_shift_out_U,code
1374perf_rdr_shift_out_U:
1375 .proc
1376 .callinfo frame=0,NO_CALLS
1377 .entry
1378
1379;
1380; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1381; shifting is done, from or to, the remote diagnose registers.
1382;
1383
1384 depdi,z 1,DR2_SLOW_RET,1,%r24
1385 MFDIAG_2 (23)
1386 or %r24,%r23,%r24
1387 MTDIAG_2 (24) ; set DR2_SLOW_RET
1388
1389 MTDIAG_1 (25) ; data to the staging register
1390 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1391 blr %r1,%r0 ; branch to 8-instruction sequence
1392 nop
1393
1394;
1395; 32-byte cachline aligned
1396;
1397
1398 sync ; RDR 0 write sequence
1399 ssm 0,0
1400 STDIAG (0)
1401 ssm 0,0
1402 b,n perf_rdr_shift_out_U_leave
1403 nop
1404 ssm 0,0
1405 nop
1406
1407 sync ; RDR 1 write sequence
1408 ssm 0,0
1409 STDIAG (1)
1410 ssm 0,0
1411 b,n perf_rdr_shift_out_U_leave
1412 nop
1413 ssm 0,0
1414 nop
1415
1416 sync ; RDR 2 write sequence
1417 ssm 0,0
1418 STDIAG (2)
1419 ssm 0,0
1420 b,n perf_rdr_shift_out_U_leave
1421 nop
1422 ssm 0,0
1423 nop
1424
1425 sync ; RDR 3 write sequence
1426 ssm 0,0
1427 STDIAG (3)
1428 ssm 0,0
1429 b,n perf_rdr_shift_out_U_leave
1430 nop
1431 ssm 0,0
1432 nop
1433
1434 sync ; RDR 4 write sequence
1435 ssm 0,0
1436 STDIAG (4)
1437 ssm 0,0
1438 b,n perf_rdr_shift_out_U_leave
1439 nop
1440 ssm 0,0
1441 nop
1442
1443 sync ; RDR 5 write sequence
1444 ssm 0,0
1445 STDIAG (5)
1446 ssm 0,0
1447 b,n perf_rdr_shift_out_U_leave
1448 nop
1449 ssm 0,0
1450 nop
1451
1452 sync ; RDR 6 write sequence
1453 ssm 0,0
1454 STDIAG (6)
1455 ssm 0,0
1456 b,n perf_rdr_shift_out_U_leave
1457 nop
1458 ssm 0,0
1459 nop
1460
1461 sync ; RDR 7 write sequence
1462 ssm 0,0
1463 STDIAG (7)
1464 ssm 0,0
1465 b,n perf_rdr_shift_out_U_leave
1466 nop
1467 ssm 0,0
1468 nop
1469
1470 sync ; RDR 8 write sequence
1471 ssm 0,0
1472 STDIAG (8)
1473 ssm 0,0
1474 b,n perf_rdr_shift_out_U_leave
1475 nop
1476 ssm 0,0
1477 nop
1478
1479 sync ; RDR 9 write sequence
1480 ssm 0,0
1481 STDIAG (9)
1482 ssm 0,0
1483 b,n perf_rdr_shift_out_U_leave
1484 nop
1485 ssm 0,0
1486 nop
1487
1488 sync ; RDR 10 write sequence
1489 ssm 0,0
1490 STDIAG (10)
1491 ssm 0,0
1492 b,n perf_rdr_shift_out_U_leave
1493 nop
1494 ssm 0,0
1495 nop
1496
1497 sync ; RDR 11 write sequence
1498 ssm 0,0
1499 STDIAG (11)
1500 ssm 0,0
1501 b,n perf_rdr_shift_out_U_leave
1502 nop
1503 ssm 0,0
1504 nop
1505
1506 sync ; RDR 12 write sequence
1507 ssm 0,0
1508 STDIAG (12)
1509 ssm 0,0
1510 b,n perf_rdr_shift_out_U_leave
1511 nop
1512 ssm 0,0
1513 nop
1514
1515 sync ; RDR 13 write sequence
1516 ssm 0,0
1517 STDIAG (13)
1518 ssm 0,0
1519 b,n perf_rdr_shift_out_U_leave
1520 nop
1521 ssm 0,0
1522 nop
1523
1524 sync ; RDR 14 write sequence
1525 ssm 0,0
1526 STDIAG (14)
1527 ssm 0,0
1528 b,n perf_rdr_shift_out_U_leave
1529 nop
1530 ssm 0,0
1531 nop
1532
1533 sync ; RDR 15 write sequence
1534 ssm 0,0
1535 STDIAG (15)
1536 ssm 0,0
1537 b,n perf_rdr_shift_out_U_leave
1538 nop
1539 ssm 0,0
1540 nop
1541
1542 sync ; RDR 16 write sequence
1543 ssm 0,0
1544 STDIAG (16)
1545 ssm 0,0
1546 b,n perf_rdr_shift_out_U_leave
1547 nop
1548 ssm 0,0
1549 nop
1550
1551 sync ; RDR 17 write sequence
1552 ssm 0,0
1553 STDIAG (17)
1554 ssm 0,0
1555 b,n perf_rdr_shift_out_U_leave
1556 nop
1557 ssm 0,0
1558 nop
1559
1560 sync ; RDR 18 write sequence
1561 ssm 0,0
1562 STDIAG (18)
1563 ssm 0,0
1564 b,n perf_rdr_shift_out_U_leave
1565 nop
1566 ssm 0,0
1567 nop
1568
1569 sync ; RDR 19 write sequence
1570 ssm 0,0
1571 STDIAG (19)
1572 ssm 0,0
1573 b,n perf_rdr_shift_out_U_leave
1574 nop
1575 ssm 0,0
1576 nop
1577
1578 sync ; RDR 20 write sequence
1579 ssm 0,0
1580 STDIAG (20)
1581 ssm 0,0
1582 b,n perf_rdr_shift_out_U_leave
1583 nop
1584 ssm 0,0
1585 nop
1586
1587 sync ; RDR 21 write sequence
1588 ssm 0,0
1589 STDIAG (21)
1590 ssm 0,0
1591 b,n perf_rdr_shift_out_U_leave
1592 nop
1593 ssm 0,0
1594 nop
1595
1596 sync ; RDR 22 write sequence
1597 ssm 0,0
1598 STDIAG (22)
1599 ssm 0,0
1600 b,n perf_rdr_shift_out_U_leave
1601 nop
1602 ssm 0,0
1603 nop
1604
1605 sync ; RDR 23 write sequence
1606 ssm 0,0
1607 STDIAG (23)
1608 ssm 0,0
1609 b,n perf_rdr_shift_out_U_leave
1610 nop
1611 ssm 0,0
1612 nop
1613
1614 sync ; RDR 24 write sequence
1615 ssm 0,0
1616 STDIAG (24)
1617 ssm 0,0
1618 b,n perf_rdr_shift_out_U_leave
1619 nop
1620 ssm 0,0
1621 nop
1622
1623 sync ; RDR 25 write sequence
1624 ssm 0,0
1625 STDIAG (25)
1626 ssm 0,0
1627 b,n perf_rdr_shift_out_U_leave
1628 nop
1629 ssm 0,0
1630 nop
1631
1632 sync ; RDR 26 write sequence
1633 ssm 0,0
1634 STDIAG (26)
1635 ssm 0,0
1636 b,n perf_rdr_shift_out_U_leave
1637 nop
1638 ssm 0,0
1639 nop
1640
1641 sync ; RDR 27 write sequence
1642 ssm 0,0
1643 STDIAG (27)
1644 ssm 0,0
1645 b,n perf_rdr_shift_out_U_leave
1646 nop
1647 ssm 0,0
1648 nop
1649
1650 sync ; RDR 28 write sequence
1651 ssm 0,0
1652 STDIAG (28)
1653 ssm 0,0
1654 b,n perf_rdr_shift_out_U_leave
1655 nop
1656 ssm 0,0
1657 nop
1658
1659 sync ; RDR 29 write sequence
1660 ssm 0,0
1661 STDIAG (29)
1662 ssm 0,0
1663 b,n perf_rdr_shift_out_U_leave
1664 nop
1665 ssm 0,0
1666 nop
1667
1668 sync ; RDR 30 write sequence
1669 ssm 0,0
1670 STDIAG (30)
1671 ssm 0,0
1672 b,n perf_rdr_shift_out_U_leave
1673 nop
1674 ssm 0,0
1675 nop
1676
1677 sync ; RDR 31 write sequence
1678 ssm 0,0
1679 STDIAG (31)
1680 ssm 0,0
1681 b,n perf_rdr_shift_out_U_leave
1682 nop
1683 ssm 0,0
1684 nop
1685
1686perf_rdr_shift_out_U_leave:
1687 bve (%r2)
1688 .exit
1689 MTDIAG_2 (23) ; restore DR2
1690 .procend
1691
diff --git a/arch/parisc/kernel/perf_images.h b/arch/parisc/kernel/perf_images.h
new file mode 100644
index 000000000000..d9562fe3f75c
--- /dev/null
+++ b/arch/parisc/kernel/perf_images.h
@@ -0,0 +1,3138 @@
1/*
2 * Imagine for use with the Onyx (PCX-U) CPU interface
3 *
4 * Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
5 * Copyright (C) 2001 Hewlett-Packard (Grant Grundler)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef PERF_IMAGES_H
22#define PERF_IMAGES_H
23
24/* Magic numbers taken without modification from HPUX stuff */
25
26#define PCXU_IMAGE_SIZE 584
27
28static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = {
29/*
30 * CPI:
31 *
32 * Counts the following:
33 *
34 * ctr0 : total cycles
35 * ctr1 : total cycles where nothing retired
36 * ctr2 : total instructions retired, including nullified
37 * ctr3 : total instructions retired, less nullified instructions
38 */
39 {
40 0x4c00c000, 0x00000000, 0x00060000, 0x00000000,
41 0xe0e0e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
42 0x0101ffff, 0xfffff104, 0xe000c07f, 0xfffffffc,
43 0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
44 0x00000fff, 0xff00000f, 0xffff0000, 0x0fffff00,
45 0x000fffff, 0x00000000, 0x00000000, 0x00ffffff,
46 0xfffff000, 0x0000000f, 0xffffffff, 0xff000000,
47 0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
48 0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
49 0xfff55fff, 0xffffffff, 0xffffffff, 0xf0000000,
50 0xf0000030, 0x00003c00, 0x067f080c, 0x02019fc0,
51 0x02804067, 0xf0009030, 0x19fc002c, 0x40067f08,
52 0x0c12019f, 0xc0028440, 0x67f00091, 0x3019fc00,
53 0x2fc007ff, 0xf800f001, 0xfffe003c, 0x007fff80,
54 0x0f001fff, 0xe003c007, 0xfff800f0, 0x01fffe00,
55 0x3c007fff, 0x800f001f, 0xffe003c0, 0x07fff800,
56 0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
57 0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
58 0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
59 0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
60 0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
61 0x00000000, 0x00000000, 0x00000000, 0x00000000,
62 0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
63 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
64 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
65 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
66 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
67 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
68 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
69 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
70 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
71 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
72 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
73 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
74 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
75 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
76 0xffffffff, 0xffffffff},
77
78/* Bus utilization image (bus_util)
79 *
80 * ctr0 : counts address valid cycles
81 * ctr1 : counts data valid cycles
82 * ctr2 : counts overflow from counter 0
83 * ctr3 : counts overflow from counter 1
84 */
85 {
86 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
87 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
88 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
89 0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
90 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
91 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
92 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
93 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
94 0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
95 0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
96 0x0000000c, 0x00003c00, 0x07930000, 0x0041e4c0,
97 0x01002079, 0x3000800c, 0x1e4c0030, 0x00279300,
98 0x010049e4, 0xc0014022, 0x79300090, 0x0c9e4c00,
99 0x34004793, 0x00020051, 0xe4c00180, 0x24793000,
100 0xa00d1e4c, 0x00380067, 0x93000300, 0x59e4c001,
101 0xc0267930, 0x00b00d9e, 0x4c003fff, 0xffffffff,
102 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
103 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
104 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
105 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
106 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
107 0x00000000, 0x00000000, 0x00000000, 0x00000000,
108 0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
109 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
110 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
111 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
112 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
113 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
114 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
115 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
116 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
117 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
118 0x00100000, 0x00000000, 0xffffffff, 0xffffffff,
119 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
120 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
121 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
122 0xffffffff, 0xffffffff },
123
124/*
125 * TLB counts (same as tlbStats image):
126 *
127 * Counts the following:
128 *
129 * ctr0: DTLB misses
130 * ctr1: ITLB misses
131 * ctr2: total cycles in the miss handlers
132 * ctr3: total cycles
133 */
134
135 {
136 0x0c00c000, 0x00000000, 0x00060000, 0x00000000,
137 0xe7e7e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
138 0x0101ffff, 0xfffff104, 0xe000c06a, 0xafffc85c,
139 0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
140 0x01b9e000, 0x0001b8c0, 0x00000000, 0x0fffff00,
141 0x000fffff, 0x00000000, 0x00000000, 0x00400000,
142 0x00001000, 0x00000004, 0x00000000, 0x01000000,
143 0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
144 0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
145 0xfff55ff5, 0xffffffff, 0xffffffff, 0xf0000000,
146 0xf0000000, 0x00003c00, 0x01ff0001, 0x08007fc2,
147 0x02c1001f, 0xf0807100, 0x1bfc200c, 0x4806ff00,
148 0x03f001ff, 0xfe003c00, 0x7fff800f, 0x001fffe0,
149 0x03c007ff, 0xf800f001, 0xfffe003c, 0x007fff80,
150 0x0f001fff, 0xe003c007, 0xfff800f0, 0x01fffe00,
151 0x3c007fff, 0x800f001f, 0xffe003c0, 0x07fff800,
152 0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
153 0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
154 0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
155 0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
156 0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
157 0x00000000, 0x00000000, 0x00000000, 0x00000000,
158 0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
159 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
160 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
161 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
162 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
163 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
164 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
165 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
166 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
167 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
168 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
169 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
170 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
171 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
172 0xffffffff, 0xffffffff },
173
174/* tlbHandMiss
175 *
176 * ctr0: counts TLB misses
177 * ctr1: counts dmisses inside tlb miss handlers
178 * ctr2: counts cycles in the tlb miss handlers
179 * ctr3: counts overflows of ctr2
180 */
181{
1820x1c00c000,00000000,0x00060000,00000000,
1830xe7e7e0e0,0x004e0004,0x07ffffff,0xffc01380,
1840x0101ffff,0xfffff104,0xe000c06a,0xafffc85c,
1850x01380010,0x1fffffff,0xff000000,00000000,
1860x01b9e000,0x0001b8c0,00000000,0x0fffff00,
1870x000fffff,00000000,00000000,0x00400000,
1880x00001000,0x00000004,00000000,0x01000000,
1890x0000ffff,0xfffffff0,00000000,0x0fffffff,
1900xffff0000,00000000,0x6fffffff,0xffffffff,
1910xfff55ff5,0xffffffff,0xffffffff,0xf0000000,
1920xf0000000,0x00003c00,0x01fd0000,0x08007f42,
1930x0281001f,0xd080a100,0x19f42008,0x44067d08,
1940x0612019f,0x400084c0,0x67d00060,0x0047f400,
1950x042011fd,0x080b0404,0x7f4202c4,0x0167d080,
1960x311059f4,0x201c4816,0x7d000313,0x059f4001,
1970xfc007fff,0x800f001f,0xffe003c0,0x07fff800,
1980xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
1990xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
2000x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
2010x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
2020x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
20300000000,00000000,00000000,00000000,
2040x6fff0000,00000000,0x60000000,00000000,
2050xffffffff,0xffffffff,0xffffffff,0xffffffff,
2060xfffffc00,00000000,0xffffffff,0xffffffff,
2070xffffffff,0xffffffff,0xfffffc00,00000000,
2080xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
2090xfdffffff,0xffffffff,0xfe000000,00000000,
2100xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
2110xfdffffff,0xffffffff,0xfe000000,00000000,
2120xffffffff,0xfffff9ff,0xfe000000,00000000,
2130xffffffff,0xfffff9ff,0xfe000000,00000000,
2140x00030000,00000000,0xffffffff,0xffffffff,
2150xffffffff,0xffffffff,0xffffffff,0xffffffff,
2160xffffffff,0xffffffff,0xffffffff,0xffffffff,
2170xffffffff,0xffffffff,0xffffffff,0xffffffff,
2180xffffffff,0xffffffff},
219
220/* branch_taken image (ptkn image)
221 *
222 * ctr0: overflow for ctr1
223 * ctr1: predicted taken branches, actually taken
224 * ctr2: all predicted taken branches (nullfied or not)
225 * ctr3: overflow for ctr2
226 */
227
228 {
229 0xcc01e000, 0x00000000, 0x00060000, 0x00000000,
230 0xa08080a0, 0xffffffff, 0xffffffff, 0xffffffff,
231 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
232 0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
233 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
234 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
235 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
236 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
237 0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
238 0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
239 0xf0000000, 0x00003c00, 0x04f90000, 0x02013e40,
240 0x0081004f, 0x90004060, 0x13e40018, 0x0024f900,
241 0x0802093e, 0x40028102, 0x4f9000c0, 0x6093e400,
242 0x380014f9, 0x00010205, 0x3e4000c1, 0x014f9000,
243 0x506053e4, 0x001c0034, 0xf9000902, 0x0d3e4002,
244 0xc1034f90, 0x00d060d3, 0xe4003fff, 0xffffffff,
245 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
246 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
247 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
248 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
249 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
250 0x00000000, 0x00000000, 0x00000000, 0x00000000,
251 0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
252 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
253 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
254 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
255 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
256 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
257 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
258 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
259 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
260 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
261 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
262 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
263 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
264 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
265 0xffffffff, 0xffffffff },
266
267/* branch_nottaken (pntkn image)
268 *
269 * ctr0: overflow for ctr1
270 * ctr1: counts branches predicted not-taken, but actually taken
271 * ctr2: counts all predictable branches predicted not-taken
272 * ctr3: overflow for ctr2
273 */
274{
2750xcc01e000,00000000,0x00060000,00000000,
2760xc0c0c0e0,0xffb1fffb,0xfff7ffff,0xffffffff,
2770xffffffff,0xfffffffb,0x1fffbfff,0x7fffffff,
2780xfcc7ffff,0xffdffffa,0x5f000000,00000000,
2790xffffffff,0xffffffff,0xffffffff,0xffffffff,
2800xffffffff,00000000,0xffffffff,0xffffffff,
2810xffffffff,0xffffffff,0xffffffff,0xffffffff,
2820xffffffff,0xffffffff,0xffffffff,0xffffffff,
2830xffff0000,00000000,0xffffffff,0xffffffff,
2840xffffffff,0xffffffff,0xffffffff,0xf0000000,
2850xf0000060,0x00003c00,0x04f90000,0x02013e40,
2860x0081004f,0x90004060,0x13e40018,0x0024f900,
2870x0802093e,0x40028102,0x4f9000c0,0x6093e400,
2880x380014f9,0x00010205,0x3e4000c1,0x014f9000,
2890x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
2900xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
2910xffffffff,0xffffffff,0xffffffff,0xffffffff,
2920xffffffff,0xffffffff,0xffffffff,0xffffffff,
2930xffffffff,0xffffffff,0xffffffff,0xffffffff,
2940xffffffff,0xffffffff,0xffffffff,0xffffffff,
2950xffffffff,0xffffffff,0xffffffff,0xfffffc00,
29600000000,00000000,00000000,00000000,
2970xffff0000,00000000,0xf0000000,00000000,
2980xffffffff,0xffffffff,0xffffffff,0xffffffff,
2990xfffffc00,00000000,0xffffffff,0xffffffff,
3000xffffffff,0xffffffff,0xfffffc00,00000000,
3010xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
3020xfdffffff,0xffffffff,0xfe000000,00000000,
3030xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
3040xfdffffff,0xffffffff,0xfe000000,00000000,
3050xffffffff,0xfffff9ff,0xfe000000,00000000,
3060xffffffff,0xfffff9ff,0xfe000000,00000000,
3070x00030000,00000000,0xffffffff,0xffffffff,
3080xffffffff,0xffffffff,0xffffffff,0xffffffff,
3090xffffffff,0xffffffff,0xffffffff,0xffffffff,
3100xffffffff,0xffffffff,0xffffffff,0xffffffff,
3110xffffffff,0xffffffff},
312
313
314/* imiss image
315 *
316 * ctr0 : counts imiss aligned on 0
317 * ctr1 : counts imiss aligned on 4
318 * ctr2 : counts imiss aligned on 8
319 * ctr3 : counts imiss aligned on C
320 */
321 {
322 0x0c00c000, 0x00000000, 0x00010000, 0x00000000,
323 0xe7ebedee, 0xffffffff, 0xffffffff, 0xffffffff,
324 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
325 0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
326 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
327 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
328 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
329 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
330 0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
331 0xfff55fff, 0xffffffff, 0xffffffff, 0xf0000000,
332 0xf0000000, 0x00003c00, 0x007f0000, 0x01001fc0,
333 0x00408007, 0xf0002030, 0x01fc000c, 0x10007f00,
334 0x0405001f, 0xc0014180, 0x07f00060, 0x7001fc00,
335 0x1c20007f, 0x00080900, 0x1fc00242, 0x8007f000,
336 0xa0b001fc, 0x002c3000, 0x7f000c0d, 0x001fc003,
337 0x438007f0, 0x00e0f001, 0xfc003fff, 0xfffff800,
338 0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
339 0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
340 0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
341 0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
342 0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
343 0x00000000, 0x00000000, 0x00000000, 0x00000000,
344 0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
345 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
346 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
347 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
348 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
349 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
350 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
351 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
352 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
353 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
354 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
355 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
356 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
357 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
358 0xffffffff, 0xffffffff},
359
360/* dmiss image
361 *
362 * ctr0 : counts cycles
363 * ctr1 : counts cycles where something retired
364 * ctr2 : counts dmisses
365 * ctr3 : (same as ctr2)
366 */
367 {
368 0x3c00c000, 0x00000000, 0x00060000, 0x00000000,
369 0xe0e0e0e0, 0xffffffff, 0xffffffff, 0xffffffff,
370 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
371 0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
372 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
373 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
374 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
375 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
376 0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
377 0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
378 0xf0000000, 0x00003c04, 0x007f0009, 0x02001fc0,
379 0x0280c007, 0xf000b040, 0x01fc0030, 0x14007f00,
380 0x0d06001f, 0xc00381c0, 0x07f000f0, 0x8001fc00,
381 0x2024007f, 0x00090a00, 0x1fc00282, 0xc007f000,
382 0xb0c001fc, 0x00303400, 0x7f000d0e, 0x001fc003,
383 0x83c007f0, 0x00f00001, 0xfc0023ff, 0xfffff800,
384 0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
385 0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
386 0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
387 0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
388 0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
389 0x00000000, 0x00000000, 0x00000000, 0x00000000,
390 0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
391 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
392 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
393 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
394 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
395 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
396 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
397 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
398 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
399 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
400 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
401 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
402 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
403 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
404 0xffffffff, 0xffffffff },
405
406/* dcmiss
407 *
408 * ctr0: counts store instructions retired
409 * ctr1: counts load instructions retired
410 * ctr2: counts dmisses
411 * ctr3: counts READ_SHARED_OR_PRIV and READ_PRIVATE transactions on Runway
412 */
413{
4140x2c90c000,00000000,0x00060000,00000000,
4150xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
4160xffffffff,0xffffffff,0xffffffff,0xffffffff,
4170xffffffff,0xffffffff,0xff000000,00000000,
4180xffffffff,0xffffffff,0xffffffff,0xffffffff,
4190xffffffff,00000000,0xffffffff,0xffffffff,
4200xffffffff,0xffffffff,0xffffffff,0xffffffff,
4210xffffffff,0xffffffff,0xffffffff,0xffffffff,
4220xffff0000,00000000,0x6fffffff,0xffffffff,
4230xffffffff,0xffffffff,0xffffffff,0xf0000000,
4240xf00000e8,0x00003c02,0x00bf0001,0x02002fc0,
4250x0080a00b,0xf0003040,0x02fc0010,0x1200bf00,
4260x0506002f,0xc00181a0,0x0bf00070,0x8002fc00,
4270x202200bf,0x00090a00,0x2fc00282,0xa00bf000,
4280xb0c002fc,0x00303200,0xbf000d0e,0x002fc003,
4290x83a00bf0,0x00ffffff,0xffffffff,0xffffffff,
4300xffffffff,0xffffffff,0xffffffff,0xffffffff,
4310xffffffff,0xffffffff,0xffffffff,0xffffffff,
4320xffffffff,0xffffffff,0xffffffff,0xffffffff,
4330xffffffff,0xffffffff,0xffffffff,0xffffffff,
4340xffffffff,0xffffffff,0xffffffff,0xfffffc00,
43500000000,00000000,00000000,00000000,
4360x6fff0000,00000000,0x60000000,00000000,
4370xffffffff,0xffffffff,0xffffffff,0xffffffff,
4380xfffffc00,00000000,0x55555555,0xd5555555,
4390x55555555,0x75555555,0x5e1ffc00,00000000,
4400xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
4410xfdffffff,0xffffffff,0xfe000000,00000000,
4420xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
4430xfdffffff,0xffffffff,0xfe000000,00000000,
4440xffffffff,0xfffff9ff,0xfe000000,00000000,
4450xffffffff,0xfffff9ff,0xfe000000,00000000,
4460x00100000,00000000,0xf8000000,00000000,
44700000000,00000000,0xf4000000,00000000,
4480xffffffff,0xffffffff,0x00ffffff,0xffffffff,
44900000000,00000000,0x00ffffff,0xffffffff,
4500xffffffff,0xffffffff },
451
452/* big_cpi
453 *
454 * ctr0: counts total cycles
455 * ctr1: counts overflows of ctr0 (for greater than 32-bit values)
456 * ctr2: counts overflows of ctr3 (for greater than 32-bit values)
457 * ctr3: counts unnullified instructions retired
458 */
459{
4600x0c00c000,00000000,0x00060000,00000000,
4610xe7e7e0e0,0x004e0004,0x07ffffff,0xffc01380,
4620x0101ffff,0xfffff104,0xe000c06a,0xafffc85c,
4630x01380010,0x1fffffff,0xff000000,00000000,
4640x01b9e000,0x0001b8c0,00000000,0x0fffff00,
4650x000fffff,00000000,00000000,0x00400000,
4660x00001000,0x00000004,00000000,0x01000000,
4670x0000ffff,0xfffffff0,00000000,0x0fffffff,
4680xffff0000,00000000,0x6fffffff,0xffffffff,
4690xfff55ff5,0xffffffff,0xffffffff,0xf0000000,
4700xf0000010,0x00003c00,0x01760008,0x00025d80,
4710x02800417,0x6000c001,0x25d80038,0x04017600,
4720x0901025d,0x8002c044,0x176000d0,0x1125d800,
4730x3c2001f6,0x08080400,0x7d820203,0x001f6080,
4740x804027d8,0x20282009,0xf6080a0c,0x027d8202,
4750x81041f60,0x80c08107,0xd8203030,0x41f6080c,
4760x04127d82,0x0382049f,0x6080e0c1,0x27d82038,
4770x4006f608,0x081011bd,0x82030400,0xef6080a1,
4780x013bd820,0x384806f6,0x00081211,0xbd800304,
4790x80ef6000,0xa1213bd8,0x003bc007,0xfff800f0,
4800x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
48100000000,00000000,00000000,00000000,
4820x6fff0000,00000000,0x60000000,00000000,
4830xffffffff,0xffffffff,0xffffffff,0xffffffff,
4840xfffffc00,00000000,0xffffffff,0xffffffff,
4850xffffffff,0xffffffff,0xfffffc00,00000000,
4860xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
4870xfdffffff,0xffffffff,0xfe000000,00000000,
4880xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
4890xfdffffff,0xffffffff,0xfe000000,00000000,
4900xffffffff,0xfffff9ff,0xfe000000,00000000,
4910xffffffff,0xfffff9ff,0xfe000000,00000000,
4920x00030000,00000000,0xffffffff,0xffffffff,
4930xffffffff,0xffffffff,0xffffffff,0xffffffff,
4940xffffffff,0xffffffff,0xffffffff,0xffffffff,
4950xffffffff,0xffffffff,0xffffffff,0xffffffff,
4960xffffffff,0xffffffff },
497
498/* big_ls
499 *
500 * ctr0:counts the total number of cycles for which local_stall_A1 is asserted.
501 * ctr1: is the overflow for counter 0.
502 * ctr2: counts IFLUSH_AV
503 * ctr3: is the overflow for counter 2.
504 */
505{
5060x0c000000,00000000,0x00060000,00000000,
5070xefefefef,0xffffffff,0xffffffff,0xffffffff,
5080xffffffff,0xffffffff,0xffffffff,0xffffffff,
5090xffffffff,0xffffffff,0xff000000,00000000,
5100xffffffff,0xffffffff,0xffffffff,0xffffffff,
5110xffffffff,00000000,0xffffffff,0xffffffff,
5120xffffffff,0xffffffff,0xffffffff,0xffffffff,
5130xffffffff,0xffffffff,0xffffffff,0xffffffff,
5140xffff0000,00000000,0x0fffffff,0xffffffff,
5150xffffffff,0xffffffff,0xffffffff,0xf0000000,
51600000000,0x00029408,0x02f50002,0x0800bd40,
5170x0202802f,0x5000a000,0x4bd40004,0x0812f500,
5180x030804bd,0x40024281,0x2f5000b0,0x010bd400,
5190x100842f5,0x00060810,0xbd400302,0x842f5000,
5200xe0014bd4,0x00140852,0xf5000708,0x14bd4003,
5210x42852f50,0x00ff001f,0xffe003c0,0x07fff800,
5220xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
5230xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
5240x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
5250x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
5260x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
52700000000,00000000,00000000,00000000,
5280x0df70000,00000000,00000000,00000000,
5290xffffffff,0xffffffff,0xffffffff,0xffffffff,
5300xfffffc00,00000000,0xffffffff,0xffffffff,
5310xffffffff,0xffffffff,0xfffffc00,00000000,
5320xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
5330xfdffffff,0xffffffff,0xfe000000,00000000,
5340xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
5350xfdffffff,0xffffffff,0xfe000000,00000000,
5360xffffffff,0xfffff9ff,0xfe000000,00000000,
5370xffffffff,0xfffff9ff,0xfe000000,00000000,
5380x00030000,00000000,0xffffffff,0xffffffff,
5390xffffffff,0xffffffff,0xffffffff,0xffffffff,
5400xffffffff,0xffffffff,0xffffffff,0xffffffff,
5410xffffffff,0xffffffff,0xffffffff,0xffffffff,
5420xffffffff,0xffffffff },
543
544/* br_abort
545 *
546 * ctr0: counts BRAD_STALLH
547 * ctr1: counts ONE_QUAD
548 * ctr2: counts BR0_ABRT
549 * ctr3: counts BR1_ABRT
550 */
551{
5520x0c002000,00000000,0x00060000,00000000,
5530xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
5540xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
5550xffffffff,0xffffffff,0xff000000,00000000,
5560xffffffff,0xffffffff,0xffffffff,0xffffffff,
5570xffffffff,00000000,0xffffffff,0xffffffff,
5580xffffffff,0xffffffff,0xffffffff,0xffffffff,
5590xffffffff,0xffffffff,0xffffffff,0xffffffff,
5600xffff0000,00000000,0x1fffffff,0xffffffff,
5610xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
56200000000,0x0003f800,0x007f000e,0x01001fc0,
5630x03c08007,0xf000c030,0x01fc0034,0x10007f00,
5640x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
5650x2420007f,0x00060900,0x1fc001c2,0x8007f000,
5660x40b001fc,0x00143000,0x7f00020d,0x001fc000,
5670xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
5680xfffffffe,0x003fffff,0xff800fff,0xffffe003,
5690xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
5700xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
5710xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
5720xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
57300000000,00000000,00000000,00000000,
5740x1a250000,00000000,0x10000000,00000000,
5750xffffffff,0xffffffff,0xffffffff,0xffffffff,
5760xfffffc00,00000000,0xffffffff,0xffffffff,
5770xffffffff,0xffffffff,0xfffffc00,00000000,
5780xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
5790xfdffffff,0xffffffff,0xfe000000,00000000,
5800xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
5810xfdffffff,0xffffffff,0xfe000000,00000000,
5820xffffffff,0xfffff9ff,0xfe000000,00000000,
5830xffffffff,0xfffff9ff,0xfe000000,00000000,
5840x00030000,00000000,0xffffffff,0xffffffff,
5850xffffffff,0xffffffff,0xffffffff,0xffffffff,
5860xffffffff,0xffffffff,0xffffffff,0xffffffff,
5870xffffffff,0xffffffff,0xffffffff,0xffffffff,
5880xffffffff,0xffffffff},
589
590/* isnt
591 *
592 * ctr0: counts the total number of cycles for which iside_notrans is asserted
593 * ctr1: counts the number of times iside_notrans is asserted for 1-4 cycles
594 * ctr2: counts the number of times iside_notrans is asserted for 5-7 cycles
595 * ctr3: counts the number of times iside_notrans is asserted for > 7 cycles
596 */
597{
5980x0c018000,00000000,0x00060000,00000000,
5990xefefefef,0xffffffff,0xffffffff,0xffffffff,
6000xffffffff,0xffffffff,0xffffffff,0xffffffff,
6010xffffffff,0xffffffff,0xff000000,00000000,
6020xffffffff,0xffffffff,0xffffffff,0xffffffff,
6030xffffffff,00000000,0xffffffff,0xffffffff,
6040xffffffff,0xffffffff,0xffffffff,0xffffffff,
6050xffffffff,0xffffffff,0xffffffff,0xffffffff,
6060xffff0000,00000000,0xcfffffff,0xffffffff,
6070xffffffff,0xffffffff,0xffffffff,0xf0000000,
60800000000,0x00021c20,0x03ff0808,0x1800ffc4,
6090x0204003f,0xf0004280,0x0ffc6020,0x8003ff00,
6100x043800ff,0xc8020c00,0x3ff00044,0x800ffca0,
6110x210003ff,0x00045800,0xffcc0214,0x003ff000,
6120x26800ffc,0xe0218003,0xff000278,0x00ffd002,
6130x1c003ff0,0x0028800f,0xfd002200,0x03ff0001,
6140xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
6150xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
6160x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
6170x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
6180x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
61900000000,00000000,00000000,00000000,
6200xcdff0000,00000000,0xc0000000,00000000,
6210xffffffff,0xffffffff,0xffffffff,0xffffffff,
6220xfffffc00,00000000,0xffffffff,0xffffffff,
6230xffffffff,0xffffffff,0xfffffc00,00000000,
6240xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
6250xfdffffff,0xffffffff,0xfe000000,00000000,
6260xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
6270xfdffffff,0xffffffff,0xfe000000,00000000,
6280xffffffff,0xfffff9ff,0xfe000000,00000000,
6290xffffffff,0xfffff9ff,0xfe000000,00000000,
6300x00030000,00000000,0xffffffff,0xffffffff,
6310xffffffff,0xffffffff,0xffffffff,0xffffffff,
6320xffffffff,0xffffffff,0xffffffff,0xffffffff,
6330xffffffff,0xffffffff,0xffffffff,0xffffffff,
6340xffffffff,0xffffffff},
635
636/* quadrant
637 *
638 * ctr0: Total number of instructions in quadrant 0
639 * ctr1: Total number of instructions in quadrant 1
640 * ctr2: Total number of instructions in quadrant 2
641 * ctr3: Total number of instructions in quadrant 3
642 * Works only with 32-bit
643 */
644
645 {
646 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
647 0xe0e0e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
648 0x0101ffff, 0xfffff004, 0xe000407f, 0xfffffffc,
649 0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
650 0x00000fff, 0xff00000f, 0xffff0000, 0x0fffff00,
651 0x000fffff, 0x00000000, 0x00000000, 0x00ffffff,
652 0xffcff000, 0x0000040f, 0xfffffffc, 0xff000000,
653 0x0080ffff, 0xffffcff0, 0x0000000c, 0x0fffffff,
654 0xfcff0000, 0x00000000, 0xffffffff, 0xffffffff,
655 0xfff55ff5, 0x5fffffff, 0xffffffff, 0xf0000000,
656 0xf00000f0, 0x00003c00, 0x007f0000, 0x01001fc0,
657 0x00408007, 0xf0002030, 0x01fc000c, 0x10007f00,
658 0x0405001f, 0xc0014180, 0x07f00060, 0x7001fc00,
659 0x1c20007f, 0x00080900, 0x1fc00242, 0x8007f000,
660 0xa0b001fc, 0x002c3000, 0x7f000c0d, 0x001fc003,
661 0x438007f0, 0x00e0f001, 0xfc003fff, 0xffffffff,
662 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
663 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
664 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
665 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
666 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
667 0x00000000, 0x00000000, 0x00000000, 0x00000000,
668 0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
669 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
670 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
671 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
672 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
673 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
674 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
675 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
676 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
677 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
678 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
679 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
680 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
681 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
682 0xffffffff, 0xffffffff},
683
684/* rw_pdfet (READ_PRIV transactions)
685 *
686 * ctr0: counts address valid cycles
687 * ctr1: counts *all* data valid cycles
688 * ctr2: is the overflow from counter 0
689 * ctr3: is the overflow from counter 1
690 */
691{
6920x0c01e000,00000000,0x00060000,00000000,
6930xefefefef,0xffffffff,0xffffffff,0xffffffff,
6940xffffffff,0xffffffff,0xffffffff,0xffffffff,
6950xffffffff,0xffffffff,0xff000000,00000000,
6960xffffffff,0xffffffff,0xffffffff,0xffffffff,
6970xffffffff,00000000,0xffffffff,0xffffffff,
6980xffffffff,0xffffffff,0xffffffff,0xffffffff,
6990xffffffff,0xffffffff,0xffffffff,0xffffffff,
7000xffff0000,00000000,0xffffffff,0xffffffff,
7010xffffffff,0xffffffff,0xffffffff,0xf0000000,
7020x0000000c,0x00003c00,0x07930000,0x0041e4c0,
7030x01002079,0x3000800c,0x1e4c0030,0x00279300,
7040x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
7050x34004793,0x00020051,0xe4c00180,0x24793000,
7060xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
7070xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
7080xffffffff,0xffffffff,0xffffffff,0xffffffff,
7090xffffffff,0xffffffff,0xffffffff,0xffffffff,
7100xffffffff,0xffffffff,0xffffffff,0xffffffff,
7110xffffffff,0xffffffff,0xffffffff,0xffffffff,
7120xffffffff,0xffffffff,0xffffffff,0xfffffc00,
71300000000,00000000,00000000,00000000,
7140xffff0000,00000000,0xf0000000,00000000,
7150xffffffff,0xffffffff,0xffffffff,0xffffffff,
7160xfffffc00,00000000,0xffffffff,0xffffffff,
7170xffffffff,0xffffffff,0xfffffc00,00000000,
7180xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
7190xfdffffff,0xffffffff,0xfe000000,00000000,
7200xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
7210xfdffffff,0xffffffff,0xfe000000,00000000,
7220xffffffff,0xfffff9ff,0xfe000000,00000000,
7230xffffffff,0xfffff9ff,0xfe000000,00000000,
7240x00100000,00000000,0xf8000000,00000000,
72500000000,00000000,00000000,00000000,
7260xffffffff,0xffffffff,0x00ffffff,0xffffffff,
72700000000,00000000,00000000,00000000,
7280xffffffff,0xffffffff},
729
730/* rw_wdfet (WRITEBACKS)
731 *
732 * ctr0: counts address valid cycles
733 * ctr1: counts *all* data valid cycles
734 * ctr2: is the overflow from counter 0
735 * ctr3: is the overflow from counter 1
736 */
737{
7380x0c01e000,00000000,0x00060000,00000000,
7390xefefefef,0xffffffff,0xffffffff,0xffffffff,
7400xffffffff,0xffffffff,0xffffffff,0xffffffff,
7410xffffffff,0xffffffff,0xff000000,00000000,
7420xffffffff,0xffffffff,0xffffffff,0xffffffff,
7430xffffffff,00000000,0xffffffff,0xffffffff,
7440xffffffff,0xffffffff,0xffffffff,0xffffffff,
7450xffffffff,0xffffffff,0xffffffff,0xffffffff,
7460xffff0000,00000000,0xffffffff,0xffffffff,
7470xffffffff,0xffffffff,0xffffffff,0xf0000000,
7480x0000000c,0x00003c00,0x07930000,0x0041e4c0,
7490x01002079,0x3000800c,0x1e4c0030,0x00279300,
7500x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
7510x34004793,0x00020051,0xe4c00180,0x24793000,
7520xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
7530xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
7540xffffffff,0xffffffff,0xffffffff,0xffffffff,
7550xffffffff,0xffffffff,0xffffffff,0xffffffff,
7560xffffffff,0xffffffff,0xffffffff,0xffffffff,
7570xffffffff,0xffffffff,0xffffffff,0xffffffff,
7580xffffffff,0xffffffff,0xffffffff,0xfffffc00,
75900000000,00000000,00000000,00000000,
7600xffff0000,00000000,0xf0000000,00000000,
7610xffffffff,0xffffffff,0xffffffff,0xffffffff,
7620xfffffc00,00000000,0xffffffff,0xffffffff,
7630xffffffff,0xffffffff,0xfffffc00,00000000,
7640xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
7650xfdffffff,0xffffffff,0xfe000000,00000000,
7660xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
7670xfdffffff,0xffffffff,0xfe000000,00000000,
7680xffffffff,0xfffff9ff,0xfe000000,00000000,
7690xffffffff,0xfffff9ff,0xfe000000,00000000,
7700x00100000,00000000,0x98000000,00000000,
77100000000,00000000,00000000,00000000,
7720xffffffff,0xffffffff,0x00ffffff,0xffffffff,
77300000000,00000000,00000000,00000000,
7740xffffffff,0xffffffff},
775
776/* shlib_cpi
777 *
778 * ctr0: Total number of instructions in quad 0
779 * ctr1: Total number of CPU clock cycles in quad 0
780 * ctr2: total instructions without nullified
781 * ctr3: total number of CPU clock cycles
782 */
783 {
784 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
785 0xe0e0e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
786 0x0101ffff, 0xfffff004, 0xe000407f, 0xfffffffc,
787 0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
788 0x00000fff, 0xff00000f, 0xffffffff, 0xffffffff,
789 0xffffffff, 0x00000000, 0x00000000, 0x00ffffff,
790 0xffcff000, 0x0000000f, 0xfffffffc, 0xffffffff,
791 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
792 0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
793 0xfff77ff5, 0x7fffffff, 0xffffffff, 0xf0000000,
794 0xf00000a0, 0x00003c00, 0x01ff0005, 0x08007fc0,
795 0x03c1001f, 0xf08030c0, 0x07fc203c, 0x4001ff08,
796 0x0118007f, 0xc003c500, 0x1ff08031, 0xc007fc00,
797 0x3fffffff, 0xf800ffff, 0xfffe003f, 0xffffff80,
798 0x0fffffff, 0xe003ffff, 0xfff800ff, 0xfffffe00,
799 0x3fffffff, 0x800fffff, 0xffe003ff, 0xfffff800,
800 0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
801 0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
802 0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
803 0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
804 0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
805 0x00000000, 0x00000000, 0x00000000, 0x00000000,
806 0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
807 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
808 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
809 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
810 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
811 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
812 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
813 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
814 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
815 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
816 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
817 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
818 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
819 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
820 0xffffffff, 0xffffffff},
821
822
823/* addr_inv_abort_alu
824 *
825 * ctr0: counts ABORT_ALU0L
826 * ctr1: counts ABORT_ALU1L
827 * ctr2: counts ADDR0_INVALID
828 * ctr3: counts ADDR1_INVALID
829 */
830
831{
8320x0c00c000,00000000,0x00060000,00000000,
8330xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
8340xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
8350xffffffff,0xffffffff,0xff000000,00000000,
8360xffffffff,0xffffffff,0xffffffff,0xffffffff,
8370xffffffff,00000000,0xffffffff,0xffffffff,
8380xffffffff,0xffffffff,0xffffffff,0xffffffff,
8390xffffffff,0xffffffff,0xffffffff,0xffffffff,
8400xffff0000,00000000,0x6fffffff,0xffffffff,
8410xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
84200000000,0x0003f800,0x007f000d,0x01001fc0,
8430x03008007,0xf000f030,0x01fc0038,0x10007f00,
8440x0905001f,0xc0020180,0x07f000b0,0x7001fc00,
8450x2820007f,0x00050900,0x1fc00102,0x8007f000,
8460x70b001fc,0x00183000,0x7f00010d,0x001fc000,
8470x038007f0,0x0030f001,0xfc000bff,0xfffff800,
8480xfffffffe,0x003fffff,0xff800fff,0xffffe003,
8490xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
8500xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
8510xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
8520xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
85300000000,00000000,00000000,00000000,
8540x65380000,00000000,0x60000000,00000000,
8550xffffffff,0xffffffff,0xffffffff,0xffffffff,
8560xfffffc00,00000000,0xffffffff,0xffffffff,
8570xffffffff,0xffffffff,0xfffffc00,00000000,
8580xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
8590xfdffffff,0xffffffff,0xfe000000,00000000,
8600xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
8610xfdffffff,0xffffffff,0xfe000000,00000000,
8620xffffffff,0xfffff9ff,0xfe000000,00000000,
8630xffffffff,0xfffff9ff,0xfe000000,00000000,
8640x00030000,00000000,0xffffffff,0xffffffff,
8650xffffffff,0xffffffff,0xffffffff,0xffffffff,
8660xffffffff,0xffffffff,0xffffffff,0xffffffff,
8670xffffffff,0xffffffff,0xffffffff,0xffffffff,
8680xffffffff,0xffffffff },
869
870
871
872/* brad_stall
873 *
874 * ctr0: counts the total number of cycles for which brad_stall is asserted
875 * ctr1: counts the number of times brad_stall is asserted for 1-4 cycles
876 * ctr2: counts the number of times brad_stall is asserted for 5-7 cycles
877 * ctr3: counts the number of times brad_stall is asserted for > 7 cycles
878 */
879{
8800x0c002000,00000000,0x00060000,00000000,
8810xefefefef,0xffffffff,0xffffffff,0xffffffff,
8820xffffffff,0xffffffff,0xffffffff,0xffffffff,
8830xffffffff,0xffffffff,0xff000000,00000000,
8840xffffffff,0xffffffff,0xffffffff,0xffffffff,
8850xffffffff,00000000,0xffffffff,0xffffffff,
8860xffffffff,0xffffffff,0xffffffff,0xffffffff,
8870xffffffff,0xffffffff,0xffffffff,0xffffffff,
8880xffff0000,00000000,0x1fffffff,0xffffffff,
8890xffffffff,0xffffffff,0xffffffff,0xf0000000,
89000000000,0x00021c20,0x03ff0808,0x1800ffc4,
8910x0204003f,0xf0004280,0x0ffc6020,0x8003ff00,
8920x043800ff,0xc8020c00,0x3ff00044,0x800ffca0,
8930x210003ff,0x00045800,0xffcc0214,0x003ff000,
8940x26800ffc,0xe0218003,0xff000278,0x00ffd002,
8950x1c003ff0,0x0028800f,0xfd002200,0x03ff0001,
8960xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
8970xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
8980x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
8990x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
9000x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
90100000000,00000000,00000000,00000000,
9020x1bff0000,00000000,0x10000000,00000000,
9030xffffffff,0xffffffff,0xffffffff,0xffffffff,
9040xfffffc00,00000000,0xffffffff,0xffffffff,
9050xffffffff,0xffffffff,0xfffffc00,00000000,
9060xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
9070xfdffffff,0xffffffff,0xfe000000,00000000,
9080xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
9090xfdffffff,0xffffffff,0xfe000000,00000000,
9100xffffffff,0xfffff9ff,0xfe000000,00000000,
9110xffffffff,0xfffff9ff,0xfe000000,00000000,
9120x00030000,00000000,0xffffffff,0xffffffff,
9130xffffffff,0xffffffff,0xffffffff,0xffffffff,
9140xffffffff,0xffffffff,0xffffffff,0xffffffff,
9150xffffffff,0xffffffff,0xffffffff,0xffffffff,
9160xffffffff,0xffffffff},
917
918/* cntl_in_pipel
919 *
920 * ctr0: counts the total number of cycles for which cntl_in_pipel is asserted
921 * ctr1: counts the number of times cntl_in_pipel is asserted for 1-4 cycles
922 * ctr2: counts the number of times cntl_in_pipel is asserted for 5-7 cycles
923 * ctr3: counts the number of times cntl_in_pipel is asserted for > 7 cycles
924 */
925{
9260x0c006000,00000000,0x00060000,00000000,
9270xefefefef,0xffffffff,0xffffffff,0xffffffff,
9280xffffffff,0xffffffff,0xffffffff,0xffffffff,
9290xffffffff,0xffffffff,0xff000000,00000000,
9300xffffffff,0xffffffff,0xffffffff,0xffffffff,
9310xffffffff,00000000,0xffffffff,0xffffffff,
9320xffffffff,0xffffffff,0xffffffff,0xffffffff,
9330xffffffff,0xffffffff,0xffffffff,0xffffffff,
9340xffff0000,00000000,0x3fffffff,0xffffffff,
9350xffffffff,0xffffffff,0xffffffff,0xf0000000,
93600000000,0x00021c00,0x03ff0808,0x1000ffc4,
9370x0206003f,0xf0004200,0x0ffc6020,0xa003ff00,
9380x043000ff,0xc8020e00,0x3ff00044,0x000ffca0,
9390x212003ff,0x00045000,0xffcc0216,0x003ff000,
9400x26000ffc,0xe021a003,0xff000270,0x00ffd002,
9410x1e003ff0,0x0028000f,0xfd002220,0x03ff0001,
9420xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
9430xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
9440x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
9450x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
9460x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
94700000000,00000000,00000000,00000000,
9480x3fff0000,00000000,0x30000000,00000000,
9490xffffffff,0xffffffff,0xffffffff,0xffffffff,
9500xfffffc00,00000000,0xffffffff,0xffffffff,
9510xffffffff,0xffffffff,0xfffffc00,00000000,
9520xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
9530xfdffffff,0xffffffff,0xfe000000,00000000,
9540xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
9550xfdffffff,0xffffffff,0xfe000000,00000000,
9560xffffffff,0xfffff9ff,0xfe000000,00000000,
9570xffffffff,0xfffff9ff,0xfe000000,00000000,
9580x00030000,00000000,0xffffffff,0xffffffff,
9590xffffffff,0xffffffff,0xffffffff,0xffffffff,
9600xffffffff,0xffffffff,0xffffffff,0xffffffff,
9610xffffffff,0xffffffff,0xffffffff,0xffffffff,
9620xffffffff,0xffffffff },
963
964
965/* dsnt_xfh
966 *
967 * ctr0: counts dside_notrans
968 * ctr1: counts xfhang
969 * ctr2: is the overflow for ctr0
970 * ctr3: is the overflow for ctr1
971 */
972{
9730x0c018000,00000000,0x00060000,00000000,
9740xefefefef,0xffffffff,0xffffffff,0xffffffff,
9750xffffffff,0xffffffff,0xffffffff,0xffffffff,
9760xffffffff,0xffffffff,0xff000000,00000000,
9770xffffffff,0xffffffff,0xffffffff,0xffffffff,
9780xffffffff,00000000,0xffffffff,0xffffffff,
9790xffffffff,0xffffffff,0xffffffff,0xffffffff,
9800xffffffff,0xffffffff,0xffffffff,0xffffffff,
9810xffff0000,00000000,0xcfffffff,0xffffffff,
9820xffffffff,0xffffffff,0xffffffff,0xf0000000,
98300000000,0x00030000,0x01f30000,0x00087cc0,
9840x0040041f,0x30002001,0x87cc000c,0x1001f300,
9850x0404087c,0xc0014104,0x1f300060,0x4187cc00,
9860x1c2001f3,0x00080808,0x7cc00242,0x041f3000,
9870xa08187cc,0x002c3001,0xf3000c0c,0x087cc003,
9880x43041f30,0x00e0c187,0xcc003fc0,0x07fff800,
9890xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
9900xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
9910x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
9920x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
9930x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
99400000000,00000000,00000000,00000000,
9950xcb3f0000,00000000,0xc0000000,00000000,
9960xffffffff,0xffffffff,0xffffffff,0xffffffff,
9970xfffffc00,00000000,0xffffffff,0xffffffff,
9980xffffffff,0xffffffff,0xfffffc00,00000000,
9990xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
10000xfdffffff,0xffffffff,0xfe000000,00000000,
10010xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
10020xfdffffff,0xffffffff,0xfe000000,00000000,
10030xffffffff,0xfffff9ff,0xfe000000,00000000,
10040xffffffff,0xfffff9ff,0xfe000000,00000000,
10050x00030000,00000000,0xffffffff,0xffffffff,
10060xffffffff,0xffffffff,0xffffffff,0xffffffff,
10070xffffffff,0xffffffff,0xffffffff,0xffffffff,
10080xffffffff,0xffffffff,0xffffffff,0xffffffff,
10090xffffffff,0xffffffff },
1010
1011/* fet_sig1
1012 *
1013 * ctr0: counts ICORE_AV
1014 * ctr1: counts ITRANS_STALL
1015 * ctr2: counts SEL_PCQH
1016 * ctr3: counts OUT_OF_CONTEXT
1017 */
1018{
10190x0c000000,00000000,0x00060000,00000000,
10200xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
10210xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
10220xffffffff,0xffffffff,0xff000000,00000000,
10230xffffffff,0xffffffff,0xffffffff,0xffffffff,
10240xffffffff,00000000,0xffffffff,0xffffffff,
10250xffffffff,0xffffffff,0xffffffff,0xffffffff,
10260xffffffff,0xffffffff,0xffffffff,0xffffffff,
10270xffff0000,00000000,0x0fffffff,0xffffffff,
10280xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
102900000000,0x0003f800,0x007f000e,0x01001fc0,
10300x03c08007,0xf000c030,0x01fc0034,0x10007f00,
10310x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
10320x2420007f,0x00060900,0x1fc001c2,0x8007f000,
10330x40b001fc,0x00143000,0x7f00020d,0x001fc000,
10340xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
10350xfffffffe,0x003fffff,0xff800fff,0xffffe003,
10360xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
10370xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
10380xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
10390xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
104000000000,00000000,00000000,00000000,
10410x07c10000,00000000,00000000,00000000,
10420xffffffff,0xffffffff,0xffffffff,0xffffffff,
10430xfffffc00,00000000,0xffffffff,0xffffffff,
10440xffffffff,0xffffffff,0xfffffc00,00000000,
10450xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
10460xfdffffff,0xffffffff,0xfe000000,00000000,
10470xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
10480xfdffffff,0xffffffff,0xfe000000,00000000,
10490xffffffff,0xfffff9ff,0xfe000000,00000000,
10500xffffffff,0xfffff9ff,0xfe000000,00000000,
10510x00030000,00000000,0xffffffff,0xffffffff,
10520xffffffff,0xffffffff,0xffffffff,0xffffffff,
10530xffffffff,0xffffffff,0xffffffff,0xffffffff,
10540xffffffff,0xffffffff,0xffffffff,0xffffffff,
10550xffffffff,0xffffffff},
1056
1057/* fet_sig2
1058 *
1059 * ctr0: counts ICORE_AV
1060 * ctr1: counts IRTN_AV
1061 * ctr2: counts ADDRESS_INC
1062 * ctr3: counts ADDRESS_DEC
1063 */
1064{
10650x0c000000,00000000,0x00060000,00000000,
10660xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
10670xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
10680xffffffff,0xffffffff,0xff000000,00000000,
10690xffffffff,0xffffffff,0xffffffff,0xffffffff,
10700xffffffff,00000000,0xffffffff,0xffffffff,
10710xffffffff,0xffffffff,0xffffffff,0xffffffff,
10720xffffffff,0xffffffff,0xffffffff,0xffffffff,
10730xffff0000,00000000,0x0fffffff,0xffffffff,
10740xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
107500000000,0x0003f800,0x007f000e,0x01001fc0,
10760x03c08007,0xf000c030,0x01fc0034,0x10007f00,
10770x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
10780x2420007f,0x00060900,0x1fc001c2,0x8007f000,
10790x40b001fc,0x00143000,0x7f00020d,0x001fc000,
10800xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
10810xfffffffe,0x003fffff,0xff800fff,0xffffe003,
10820xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
10830xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
10840xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
10850xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
108600000000,00000000,00000000,00000000,
10870x06930000,00000000,00000000,00000000,
10880xffffffff,0xffffffff,0xffffffff,0xffffffff,
10890xfffffc00,00000000,0xffffffff,0xffffffff,
10900xffffffff,0xffffffff,0xfffffc00,00000000,
10910xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
10920xfdffffff,0xffffffff,0xfe000000,00000000,
10930xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
10940xfdffffff,0xffffffff,0xfe000000,00000000,
10950xffffffff,0xfffff9ff,0xfe000000,00000000,
10960xffffffff,0xfffff9ff,0xfe000000,00000000,
10970x00030000,00000000,0xffffffff,0xffffffff,
10980xffffffff,0xffffffff,0xffffffff,0xffffffff,
10990xffffffff,0xffffffff,0xffffffff,0xffffffff,
11000xffffffff,0xffffffff,0xffffffff,0xffffffff,
11010xffffffff,0xffffffff },
1102
1103/* g7_1
1104 *
1105 * ctr0: counts HIT_RETRY0
1106 * ctr1: counts HIT_RETRY1
1107 * ctr2: counts GO_TAG_E
1108 * ctr3: counts GO_TAG_O
1109 */
1110{
11110x0c00e000,00000000,0x00060000,00000000,
11120xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
11130xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
11140xffffffff,0xffffffff,0xff000000,00000000,
11150xffffffff,0xffffffff,0xffffffff,0xffffffff,
11160xffffffff,00000000,0xffffffff,0xffffffff,
11170xffffffff,0xffffffff,0xffffffff,0xffffffff,
11180xffffffff,0xffffffff,0xffffffff,0xffffffff,
11190xffff0000,00000000,0x7fffffff,0xffffffff,
11200xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
112100000000,0x0003f800,0x007f000e,0x01001fc0,
11220x03c08007,0xf000c030,0x01fc0034,0x10007f00,
11230x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
11240x2420007f,0x00060900,0x1fc001c2,0x8007f000,
11250x40b001fc,0x00143000,0x7f00020d,0x001fc000,
11260xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
11270xfffffffe,0x003fffff,0xff800fff,0xffffe003,
11280xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
11290xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
11300xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
11310xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
113200000000,00000000,00000000,00000000,
11330x71c10000,00000000,0x70000000,00000000,
11340xffffffff,0xffffffff,0xffffffff,0xffffffff,
11350xfffffc00,00000000,0xffffffff,0xffffffff,
11360xffffffff,0xffffffff,0xfffffc00,00000000,
11370xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
11380xfdffffff,0xffffffff,0xfe000000,00000000,
11390xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
11400xfdffffff,0xffffffff,0xfe000000,00000000,
11410xffffffff,0xfffff9ff,0xfe000000,00000000,
11420xffffffff,0xfffff9ff,0xfe000000,00000000,
11430x00030000,00000000,0xffffffff,0xffffffff,
11440xffffffff,0xffffffff,0xffffffff,0xffffffff,
11450xffffffff,0xffffffff,0xffffffff,0xffffffff,
11460xffffffff,0xffffffff,0xffffffff,0xffffffff,
11470xffffffff,0xffffffff },
1148
1149/* g7_2
1150 *
1151 * ctr0: counts HIT_DM0
1152 * ctr1: counts HIT_DM1
1153 * ctr2: counts GO_STORE_E
1154 * ctr3: counts GO_STORE_O
1155 */
1156{
11570x0c00e000,00000000,0x00060000,00000000,
11580xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
11590xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
11600xffffffff,0xffffffff,0xff000000,00000000,
11610xffffffff,0xffffffff,0xffffffff,0xffffffff,
11620xffffffff,00000000,0xffffffff,0xffffffff,
11630xffffffff,0xffffffff,0xffffffff,0xffffffff,
11640xffffffff,0xffffffff,0xffffffff,0xffffffff,
11650xffff0000,00000000,0x7fffffff,0xffffffff,
11660xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
116700000000,0x0003f800,0x007f000e,0x01001fc0,
11680x03c08007,0xf000c030,0x01fc0034,0x10007f00,
11690x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
11700x2420007f,0x00060900,0x1fc001c2,0x8007f000,
11710x40b001fc,0x00143000,0x7f00020d,0x001fc000,
11720xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
11730xfffffffe,0x003fffff,0xff800fff,0xffffe003,
11740xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
11750xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
11760xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
11770xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
117800000000,00000000,00000000,00000000,
11790x72930000,00000000,0x70000000,00000000,
11800xffffffff,0xffffffff,0xffffffff,0xffffffff,
11810xfffffc00,00000000,0xffffffff,0xffffffff,
11820xffffffff,0xffffffff,0xfffffc00,00000000,
11830xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
11840xfdffffff,0xffffffff,0xfe000000,00000000,
11850xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
11860xfdffffff,0xffffffff,0xfe000000,00000000,
11870xffffffff,0xfffff9ff,0xfe000000,00000000,
11880xffffffff,0xfffff9ff,0xfe000000,00000000,
11890x00030000,00000000,0xffffffff,0xffffffff,
11900xffffffff,0xffffffff,0xffffffff,0xffffffff,
11910xffffffff,0xffffffff,0xffffffff,0xffffffff,
11920xffffffff,0xffffffff,0xffffffff,0xffffffff,
11930xffffffff,0xffffffff },
1194
1195/* g7_3
1196 *
1197 * ctr0: counts HIT_DV0
1198 * ctr1: counts HIT_DV1
1199 * ctr2: counts STBYPT_E (load bypasses from store queue)
1200 * ctr3: counts STBYPT_O
1201 */
1202{
12030x0c00e000,00000000,0x00060000,00000000,
12040xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
12050xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
12060xffffffff,0xffffffff,0xff000000,00000000,
12070xffffffff,0xffffffff,0xffffffff,0xffffffff,
12080xffffffff,00000000,0xffffffff,0xffffffff,
12090xffffffff,0xffffffff,0xffffffff,0xffffffff,
12100xffffffff,0xffffffff,0xffffffff,0xffffffff,
12110xffff0000,00000000,0x7fffffff,0xffffffff,
12120xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
121300000000,0x0003f800,0x007f0002,0x01001fc0,
12140x00c08007,0xf0000030,0x01fc0004,0x10007f00,
12150x0605001f,0xc001c180,0x07f00040,0x7001fc00,
12160x1420007f,0x000a0900,0x1fc002c2,0x8007f000,
12170x80b001fc,0x00243000,0x7f000e0d,0x001fc003,
12180xc38007f0,0x00c0f001,0xfc0037ff,0xfffff800,
12190xfffffffe,0x003fffff,0xff800fff,0xffffe003,
12200xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
12210xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
12220xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
12230xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
122400000000,00000000,00000000,00000000,
12250x77250000,00000000,0x70000000,00000000,
12260xffffffff,0xffffffff,0xffffffff,0xffffffff,
12270xfffffc00,00000000,0xffffffff,0xffffffff,
12280xffffffff,0xffffffff,0xfffffc00,00000000,
12290xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
12300xfdffffff,0xffffffff,0xfe000000,00000000,
12310xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
12320xfdffffff,0xffffffff,0xfe000000,00000000,
12330xffffffff,0xfffff9ff,0xfe000000,00000000,
12340xffffffff,0xfffff9ff,0xfe000000,00000000,
12350x00030000,00000000,0xffffffff,0xffffffff,
12360xffffffff,0xffffffff,0xffffffff,0xffffffff,
12370xffffffff,0xffffffff,0xffffffff,0xffffffff,
12380xffffffff,0xffffffff,0xffffffff,0xffffffff,
12390xffffffff,0xffffffff },
1240
1241/* g7_4
1242 *
1243 * ctr0: counts HIT_DIRTY0
1244 * ctr1: counts HIT_DIRTY1
1245 * ctr2: counts CA_BYP_E (quick launch)
1246 * ctr3: counts CA_BYP_O
1247 */
1248{
12490x0c00e000,00000000,0x00060000,00000000,
12500xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
12510xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
12520xffffffff,0xffffffff,0xff000000,00000000,
12530xffffffff,0xffffffff,0xffffffff,0xffffffff,
12540xffffffff,00000000,0xffffffff,0xffffffff,
12550xffffffff,0xffffffff,0xffffffff,0xffffffff,
12560xffffffff,0xffffffff,0xffffffff,0xffffffff,
12570xffff0000,00000000,0x7fffffff,0xffffffff,
12580xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
125900000000,0x0003f800,0x007f000e,0x01001fc0,
12600x03c08007,0xf000c030,0x01fc0034,0x10007f00,
12610x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
12620x2420007f,0x00060900,0x1fc001c2,0x8007f000,
12630x40b001fc,0x00143000,0x7f00020d,0x001fc000,
12640xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
12650xfffffffe,0x003fffff,0xff800fff,0xffffe003,
12660xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
12670xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
12680xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
12690xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
127000000000,00000000,00000000,00000000,
12710x7bb70000,00000000,0x70000000,00000000,
12720xffffffff,0xffffffff,0xffffffff,0xffffffff,
12730xfffffc00,00000000,0xffffffff,0xffffffff,
12740xffffffff,0xffffffff,0xfffffc00,00000000,
12750xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
12760xfdffffff,0xffffffff,0xfe000000,00000000,
12770xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
12780xfdffffff,0xffffffff,0xfe000000,00000000,
12790xffffffff,0xfffff9ff,0xfe000000,00000000,
12800xffffffff,0xfffff9ff,0xfe000000,00000000,
12810x00030000,00000000,0xffffffff,0xffffffff,
12820xffffffff,0xffffffff,0xffffffff,0xffffffff,
12830xffffffff,0xffffffff,0xffffffff,0xffffffff,
12840xffffffff,0xffffffff,0xffffffff,0xffffffff,
12850xffffffff,0xffffffff },
1286
1287
1288/* mpb_labort
1289 *
1290 * ctr0: counts L_ABORT_ALU0L
1291 * ctr1: counts L_ABORT_ALU1L
1292 * ctr2: counts MPB0H
1293 * ctr3: counts MPB1H
1294 */
1295{
12960x0c00c000,00000000,0x00060000,00000000,
12970xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
12980xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
12990xffffffff,0xffffffff,0xff000000,00000000,
13000xffffffff,0xffffffff,0xffffffff,0xffffffff,
13010xffffffff,00000000,0xffffffff,0xffffffff,
13020xffffffff,0xffffffff,0xffffffff,0xffffffff,
13030xffffffff,0xffffffff,0xffffffff,0xffffffff,
13040xffff0000,00000000,0x6fffffff,0xffffffff,
13050xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
130600000000,0x0003f800,0x007f000e,0x01001fc0,
13070x03c08007,0xf000c030,0x01fc0034,0x10007f00,
13080x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
13090x2420007f,0x00060900,0x1fc001c2,0x8007f000,
13100x40b001fc,0x00143000,0x7f00020d,0x001fc000,
13110xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
13120xfffffffe,0x003fffff,0xff800fff,0xffffe003,
13130xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
13140xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
13150xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
13160xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
131700000000,00000000,00000000,00000000,
13180x605c0000,00000000,0x60000000,00000000,
13190xffffffff,0xffffffff,0xffffffff,0xffffffff,
13200xfffffc00,00000000,0xffffffff,0xffffffff,
13210xffffffff,0xffffffff,0xfffffc00,00000000,
13220xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
13230xfdffffff,0xffffffff,0xfe000000,00000000,
13240xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
13250xfdffffff,0xffffffff,0xfe000000,00000000,
13260xffffffff,0xfffff9ff,0xfe000000,00000000,
13270xffffffff,0xfffff9ff,0xfe000000,00000000,
13280x00030000,00000000,0xffffffff,0xffffffff,
13290xffffffff,0xffffffff,0xffffffff,0xffffffff,
13300xffffffff,0xffffffff,0xffffffff,0xffffffff,
13310xffffffff,0xffffffff,0xffffffff,0xffffffff,
13320xffffffff,0xffffffff },
1333
1334/* panic
1335 *
1336 * ctr0: is the overflow for counter 1
1337 * ctr1: counts traps and RFI's
1338 * ctr2: counts panic traps
1339 * ctr3: is the overflow for counter 2
1340 */
1341{
13420x0c002000,00000000,0x00060000,00000000,
13430xe7efe0e0,0xffffffff,0xffffffff,0xffffffff,
13440xffffffff,0xffffffff,0xffffffff,0xfffffffc,
13450x41380030,0x1aabfff2,0x17000000,00000000,
13460x01b80000,0x3effffff,0xffffffff,0xffffffff,
13470xffffffff,00000000,00000000,0x00400000,
13480x00001fff,0xffffffff,0xffffffff,0xffffffff,
13490xffffffff,0xffffffff,0xffffffff,0xffffffff,
13500xffff0000,00000000,0x1fffffff,0xffffffff,
13510xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
13520xb0000000,0x00012c04,0x05790804,0x14013e44,
13530x0008004f,0x90000040,0x15e46000,0xc0047920,
13540x004a003e,0x40011080,0x0f900024,0x4003e460,
13550x00c80479,0x00023301,0x1e400100,0x4157d080,
13560x514053f4,0x40048014,0xfd000104,0x055f4600,
13570x4c0147d2,0x0014a043,0xf4001508,0x10fd0003,
13580x44043f46,0x004c8147,0xd0003330,0x51f40014,
13590x04257908,0x0c14093e,0x44020802,0x4f900080,
13600x4095e460,0x20c02479,0x20084a08,0x3e400310,
13610x820f9000,0xa44083e4,0x6020c824,0x79000a33,
13620x091e4003,0x3c007fff,0x800f001f,0xffe00000,
136300000000,00000000,00000000,00000000,
13640x10400000,00000000,0x10000000,00000000,
13650xffffffff,0xffffffff,0xffffffff,0xffffffff,
13660xfffffc00,00000000,0xffffffff,0xffffffff,
13670xffffffff,0xffffffff,0xfffffc00,00000000,
13680xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
13690xfdffffff,0xffffffff,0xfe000000,00000000,
13700xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
13710xfdffffff,0xffffffff,0xfe000000,00000000,
13720xffffffff,0xfffff9ff,0xfe000000,00000000,
13730xffffffff,0xfffff9ff,0xfe000000,00000000,
13740x00030000,00000000,0xffffffff,0xffffffff,
13750xffffffff,0xffffffff,0xffffffff,0xffffffff,
13760xffffffff,0xffffffff,0xffffffff,0xffffffff,
13770xffffffff,0xffffffff,0xffffffff,0xffffffff,
13780xffffffff,0xffffffff },
1379
1380/* rare_inst
1381 *
1382 * ctr0: counts sync and syncdma instructions
1383 * ctr1: counts pxtlbx,x instructions
1384 * ctr2: counts ixtlbt instructions
1385 * ctr3: counts cycles
1386 */
1387{
13880x0c01e000,00000000,0x00060000,00000000,
13890xe0e0e0e0,0x004e000c,0x000843fc,0x85c09380,
13900x0121ebfd,0xff217124,0xe0004000,0x943fc85f,
13910xffffffff,0xffffffff,0xff000000,00000000,
13920xffffffff,0xffffffff,0xffffffff,0xffffffff,
13930xffffffff,00000000,0xffffffff,0xffffffff,
13940xffffffff,0xffffffff,0xffffffff,0xffffffff,
13950xffffffff,0xffffffff,0xffffffff,0xffffffff,
13960xffff0000,00000000,0xffffffff,0xffffffff,
13970xffffffff,0xffffffff,0xffffffff,0xf0000000,
13980xe00000e0,0x00003c00,0x007f0001,0x01001fc0,
13990x00408007,0xf0003030,0x01fc000c,0x10007f00,
14000x0505001f,0xc0014180,0x07f00070,0x7001fc00,
14010x1c20007f,0x00090900,0x1fc00242,0x8007f000,
14020xb0b001fc,0x002c3000,0x7f000d0d,0x001fc003,
14030x438007f0,0x00f0f001,0xfc003fff,0xfffff800,
14040xfffffffe,0x003fffff,0xff800fff,0xffffe003,
14050xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
14060xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
14070xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
14080xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
140900000000,00000000,00000000,00000000,
14100xffff0000,00000000,0xf0000000,00000000,
14110xffffffff,0xffffffff,0xffffffff,0xffffffff,
14120xfffffc00,00000000,0xffffffff,0xffffffff,
14130xffffffff,0xffffffff,0xfffffc00,00000000,
14140xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
14150xfdffffff,0xffffffff,0xfe000000,00000000,
14160xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
14170xfdffffff,0xffffffff,0xfe000000,00000000,
14180xffffffff,0xfffff9ff,0xfe000000,00000000,
14190xffffffff,0xfffff9ff,0xfe000000,00000000,
14200x00030000,00000000,0xffffffff,0xffffffff,
14210xffffffff,0xffffffff,0xffffffff,0xffffffff,
14220xffffffff,0xffffffff,0xffffffff,0xffffffff,
14230xffffffff,0xffffffff,0xffffffff,0xffffffff,
14240xffffffff,0xffffffff },
1425
1426/* rw_dfet (for D-cache misses and writebacks)
1427 *
1428 * ctr0: counts address valid cycles
1429 * ctr1: counts *all* data valid cycles
1430 * ctr2: is the overflow from counter 0
1431 * ctr3: is the overflow from counter 1
1432 */
1433{
14340x0c01e000,00000000,0x00060000,00000000,
14350xefefefef,0xffffffff,0xffffffff,0xffffffff,
14360xffffffff,0xffffffff,0xffffffff,0xffffffff,
14370xffffffff,0xffffffff,0xff000000,00000000,
14380xffffffff,0xffffffff,0xffffffff,0xffffffff,
14390xffffffff,00000000,0xffffffff,0xffffffff,
14400xffffffff,0xffffffff,0xffffffff,0xffffffff,
14410xffffffff,0xffffffff,0xffffffff,0xffffffff,
14420xffff0000,00000000,0xffffffff,0xffffffff,
14430xffffffff,0xffffffff,0xffffffff,0xf0000000,
14440x0000000c,0x00003c00,0x07930000,0x0041e4c0,
14450x01002079,0x3000800c,0x1e4c0030,0x00279300,
14460x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
14470x34004793,0x00020051,0xe4c00180,0x24793000,
14480xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
14490xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
14500xffffffff,0xffffffff,0xffffffff,0xffffffff,
14510xffffffff,0xffffffff,0xffffffff,0xffffffff,
14520xffffffff,0xffffffff,0xffffffff,0xffffffff,
14530xffffffff,0xffffffff,0xffffffff,0xffffffff,
14540xffffffff,0xffffffff,0xffffffff,0xfffffc00,
145500000000,00000000,00000000,00000000,
14560xffff0000,00000000,0xf0000000,00000000,
14570xffffffff,0xffffffff,0xffffffff,0xffffffff,
14580xfffffc00,00000000,0xffffffff,0xffffffff,
14590xffffffff,0xffffffff,0xfffffc00,00000000,
14600xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
14610xfdffffff,0xffffffff,0xfe000000,00000000,
14620xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
14630xfdffffff,0xffffffff,0xfe000000,00000000,
14640xffffffff,0xfffff9ff,0xfe000000,00000000,
14650xffffffff,0xfffff9ff,0xfe000000,00000000,
14660x00100000,00000000,0xf0000000,00000000,
146700000000,00000000,0x98000000,00000000,
14680xffffffff,0xffffffff,0x0fffffff,0xffffffff,
146900000000,00000000,0x00ffffff,0xffffffff,
14700xffffffff,0xffffffff },
1471
1472/* rw_ifet (I-cache misses -- actually dumb READ transactions)
1473 *
1474 * ctr0: counts address valid cycles
1475 * ctr1: counts *all* data valid cycles
1476 * ctr2: is the overflow from counter 0
1477 * ctr3: is the overflow from counter 1
1478 */
1479{
14800x0c01e000,00000000,0x00060000,00000000,
14810xefefefef,0xffffffff,0xffffffff,0xffffffff,
14820xffffffff,0xffffffff,0xffffffff,0xffffffff,
14830xffffffff,0xffffffff,0xff000000,00000000,
14840xffffffff,0xffffffff,0xffffffff,0xffffffff,
14850xffffffff,00000000,0xffffffff,0xffffffff,
14860xffffffff,0xffffffff,0xffffffff,0xffffffff,
14870xffffffff,0xffffffff,0xffffffff,0xffffffff,
14880xffff0000,00000000,0xffffffff,0xffffffff,
14890xffffffff,0xffffffff,0xffffffff,0xf0000000,
14900x0000000c,0x00003c00,0x07930000,0x0041e4c0,
14910x01002079,0x3000800c,0x1e4c0030,0x00279300,
14920x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
14930x34004793,0x00020051,0xe4c00180,0x24793000,
14940xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
14950xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
14960xffffffff,0xffffffff,0xffffffff,0xffffffff,
14970xffffffff,0xffffffff,0xffffffff,0xffffffff,
14980xffffffff,0xffffffff,0xffffffff,0xffffffff,
14990xffffffff,0xffffffff,0xffffffff,0xffffffff,
15000xffffffff,0xffffffff,0xffffffff,0xfffffc00,
150100000000,00000000,00000000,00000000,
15020xffff0000,00000000,0xf0000000,00000000,
15030xffffffff,0xffffffff,0xffffffff,0xffffffff,
15040xfffffc00,00000000,0xffffffff,0xffffffff,
15050xffffffff,0xffffffff,0xfffffc00,00000000,
15060xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
15070xfdffffff,0xffffffff,0xfe000000,00000000,
15080xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
15090xfdffffff,0xffffffff,0xfe000000,00000000,
15100xffffffff,0xfffff9ff,0xfe000000,00000000,
15110xffffffff,0xfffff9ff,0xfe000000,00000000,
15120x00100000,00000000,0xd0000000,00000000,
15130xffffffff,0xffffffff,0xffffffff,0xffffffff,
15140xffffffff,0xffffffff,0x00ffffff,0xffffffff,
15150xffffffff,0xffffffff,00000000,00000000,
15160xffffffff,0xffffffff },
1517
1518
1519/* rw_sdfet (READ_SHARED_OR_PRIVATE transactions)
1520 *
1521 * ctr0: counts address valid cycles
1522 * ctr1: counts *all* data valid cycles
1523 * ctr2: is the overflow from counter 0
1524 * ctr3: is the overflow from counter 1
1525 */
1526{
15270x0c01e000,00000000,0x00060000,00000000,
15280xefefefef,0xffffffff,0xffffffff,0xffffffff,
15290xffffffff,0xffffffff,0xffffffff,0xffffffff,
15300xffffffff,0xffffffff,0xff000000,00000000,
15310xffffffff,0xffffffff,0xffffffff,0xffffffff,
15320xffffffff,00000000,0xffffffff,0xffffffff,
15330xffffffff,0xffffffff,0xffffffff,0xffffffff,
15340xffffffff,0xffffffff,0xffffffff,0xffffffff,
15350xffff0000,00000000,0xffffffff,0xffffffff,
15360xffffffff,0xffffffff,0xffffffff,0xf0000000,
15370x0000000c,0x00003c00,0x07930000,0x0041e4c0,
15380x01002079,0x3000800c,0x1e4c0030,0x00279300,
15390x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
15400x34004793,0x00020051,0xe4c00180,0x24793000,
15410xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
15420xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
15430xffffffff,0xffffffff,0xffffffff,0xffffffff,
15440xffffffff,0xffffffff,0xffffffff,0xffffffff,
15450xffffffff,0xffffffff,0xffffffff,0xffffffff,
15460xffffffff,0xffffffff,0xffffffff,0xffffffff,
15470xffffffff,0xffffffff,0xffffffff,0xfffffc00,
154800000000,00000000,00000000,00000000,
15490xffff0000,00000000,0xf0000000,00000000,
15500xffffffff,0xffffffff,0xffffffff,0xffffffff,
15510xfffffc00,00000000,0xffffffff,0xffffffff,
15520xffffffff,0xffffffff,0xfffffc00,00000000,
15530xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
15540xfdffffff,0xffffffff,0xfe000000,00000000,
15550xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
15560xfdffffff,0xffffffff,0xfe000000,00000000,
15570xffffffff,0xfffff9ff,0xfe000000,00000000,
15580xffffffff,0xfffff9ff,0xfe000000,00000000,
15590x00100000,00000000,0xf4000000,00000000,
156000000000,00000000,00000000,00000000,
15610xffffffff,0xffffffff,0x00ffffff,0xffffffff,
156200000000,00000000,00000000,00000000,
15630xffffffff,0xffffffff },
1564
1565
1566/* spec_ifet
1567 *
1568 * ICORE_AV fires for every request which the Instruction Fetch Unit sends
1569 * to the Runway Interface Block. Hence, this counts all I-misses, speculative
1570 * or not, but does *not* include I-cache prefetches, which are generated by
1571 * RIB.
1572 * IRTN_AV fires twice for every I-cache miss returning from RIB to the IFU.
1573 * It will not fire if a second I-cache miss is issued from the IFU to RIB
1574 * before the first returns. Therefore, if the IRTN_AV count is much less
1575 * than 2x the ICORE_AV count, many speculative I-cache misses are occurring
1576 * which are "discovered" to be incorrect fairly quickly.
1577 * The ratio of I-cache miss transactions on Runway to the ICORE_AV count is
1578 * a measure of the effectiveness of instruction prefetching. This ratio
1579 * should be between 1 and 2. If it is close to 1, most prefetches are
1580 * eventually called for by the IFU; if it is close to 2, almost no prefetches
1581 * are useful and they are wasted bus traffic.
1582 *
1583 * ctr0: counts ICORE_AV
1584 * ctr1: counts IRTN_AV
1585 * ctr2: counts all non-coherent READ transactions on Runway. (TTYPE D0)
1586 * This should be just I-cache miss and I-prefetch transactions.
1587 * ctr3: counts total processor cycles
1588 */
1589{
15900x0c000000,00000000,0x00060000,00000000,
15910xefefefef,0xffffffff,0xffffffff,0xffffffff,
15920xffffffff,0xffffffff,0xffffffff,0xffffffff,
15930xffffffff,0xffffffff,0xff000000,00000000,
15940xffffffff,0xffffffff,0xffffffff,0xffffffff,
15950xffffffff,00000000,0xffffffff,0xffffffff,
15960xffffffff,0xffffffff,0xffffffff,0xffffffff,
15970xffffffff,0xffffffff,0xffffffff,0xffffffff,
15980xffff0000,00000000,0x0fffffff,0xffffffff,
15990xffffffff,0xffffffff,0xffffffff,0xf0000000,
16000x00000008,0x00030c00,0x01bf0001,0x00806fc0,
16010x00c1001b,0xf0005048,0x06fc001c,0x2001bf00,
16020x0908806f,0xc002c300,0x1bf000d0,0xc806fc00,
16030x3fffffff,0xffffffff,0xffffffff,0xffffffff,
16040xffffffff,0xffffffff,0xffffffff,0xffffffff,
16050xffffffff,0xffffffff,0xffffffff,0xffffffff,
16060xffffffff,0xffffffff,0xffffffff,0xffffffff,
16070xffffffff,0xffffffff,0xffffffff,0xffffffff,
16080xffffffff,0xffffffff,0xffffffff,0xffffffff,
16090xffffffff,0xffffffff,0xffffffff,0xffffffff,
16100xffffffff,0xffffffff,0xffffffff,0xfffffc00,
161100000000,00000000,00000000,00000000,
16120x06bf0000,00000000,00000000,00000000,
16130xffffffff,0xffffffff,0xffffffff,0xffffffff,
16140xfffffc00,00000000,0xffffffff,0xffffffff,
16150xffffffff,0xffffffff,0xfffffc00,00000000,
16160xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
16170xfdffffff,0xffffffff,0xfe000000,00000000,
16180xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
16190xfdffffff,0xffffffff,0xfe000000,00000000,
16200xffffffff,0xfffff9ff,0xfe000000,00000000,
16210xffffffff,0xfffff9ff,0xfe000000,00000000,
16220x00110000,00000000,0xd0ffffff,0xffffffff,
16230xffffffff,0xffffffff,0xffffffff,0xffffffff,
16240xffffffff,0xffffffff,0x00ffffff,0xffffffff,
16250xffffffff,0xffffffff,00000000,00000000,
16260xffffffff,0xffffffff },
1627
1628/* st_cond0
1629 *
1630 * ctr0: is the overflow for ctr1
1631 * ctr1: counts major ops 0C and 0E (fp ops, not fmac or fmpyadd)
1632 * ctr2: counts B,L (including long and push) and GATE (including nullified),
1633 * predicted not-taken
1634 * ctr3: is the overflow for ctr2
1635 */
1636{
16370x4c01e000,00000000,0x00060000,00000000,
16380xe0e0c0e0,0xffffffff,0xffffffff,0xffc13380,
16390x0101ffff,0xffa1f057,0xe000407f,0xdfffc87f,
16400xffffffff,0xffffffff,0xff000000,00000000,
16410xffffffff,0xffffffff,0xffffffff,0xffffffff,
16420xffffffff,00000000,0xffffffff,0xffffffff,
16430xffffffff,0xffffffff,0xffffffff,0xffffffff,
16440xffffffff,0xffffffff,0xffffffff,0xffffffff,
16450xffff0000,00000000,0xffffffff,0xffffffff,
16460xffffffff,0xffffffff,0xffffffff,0xf0000000,
16470xf0000060,0x00003c00,0x04f90000,0x02013e40,
16480x0081004f,0x90004060,0x13e40018,0x0024f900,
16490x0802093e,0x40028102,0x4f9000c0,0x6093e400,
16500x380014f9,0x00010205,0x3e4000c1,0x014f9000,
16510x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
16520xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
16530xffffffff,0xffffffff,0xffffffff,0xffffffff,
16540xffffffff,0xffffffff,0xffffffff,0xffffffff,
16550xffffffff,0xffffffff,0xffffffff,0xffffffff,
16560xffffffff,0xffffffff,0xffffffff,0xffffffff,
16570xffffffff,0xffffffff,0xffffffff,0xfffffc00,
165800000000,00000000,00000000,00000000,
16590xffff0000,00000000,0xf0000000,00000000,
16600xffffffff,0xffffffff,0xffffffff,0xffffffff,
16610xfffffc00,00000000,0xffffffff,0xffffffff,
16620xffffffff,0xffffffff,0xfffffc00,00000000,
16630xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
16640xfdffffff,0xffffffff,0xfe000000,00000000,
16650xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
16660xfdffffff,0xffffffff,0xfe000000,00000000,
16670xffffffff,0xfffff9ff,0xfe000000,00000000,
16680xffffffff,0xfffff9ff,0xfe000000,00000000,
16690x00030000,00000000,0xffffffff,0xffffffff,
16700xffffffff,0xffffffff,0xffffffff,0xffffffff,
16710xffffffff,0xffffffff,0xffffffff,0xffffffff,
16720xffffffff,0xffffffff,0xffffffff,0xffffffff,
16730xffffffff,0xffffffff },
1674
1675/* st_cond1
1676 *
1677 * ctr0: is the overflow for ctr1
1678 * ctr1: counts major ops 1x (most of the load/stores)
1679 * ctr2: counts CMPB (dw) predicted not-taken
1680 * ctr3: is the overflow for ctr2
1681 */
1682{
16830x4c01e000,00000000,0x00060000,00000000,
16840xe0e0c0e0,0xffffffff,0xffffffff,0xffc01b80,
16850x0101ffff,0xffb7f03d,0xe000407f,0xffffc8ff,
16860xffffffff,0xffffffff,0xff000000,00000000,
16870xffffffff,0xffffffff,0xffffffff,0xffffffff,
16880xffffffff,00000000,0xffffffff,0xffffffff,
16890xffffffff,0xffffffff,0xffffffff,0xffffffff,
16900xffffffff,0xffffffff,0xffffffff,0xffffffff,
16910xffff0000,00000000,0xffffffff,0xffffffff,
16920xffffffff,0xffffffff,0xffffffff,0xf0000000,
16930xf0000060,0x00003c00,0x04f90000,0x02013e40,
16940x0081004f,0x90004060,0x13e40018,0x0024f900,
16950x0802093e,0x40028102,0x4f9000c0,0x6093e400,
16960x380014f9,0x00010205,0x3e4000c1,0x014f9000,
16970x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
16980xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
16990xffffffff,0xffffffff,0xffffffff,0xffffffff,
17000xffffffff,0xffffffff,0xffffffff,0xffffffff,
17010xffffffff,0xffffffff,0xffffffff,0xffffffff,
17020xffffffff,0xffffffff,0xffffffff,0xffffffff,
17030xffffffff,0xffffffff,0xffffffff,0xfffffc00,
170400000000,00000000,00000000,00000000,
17050xffff0000,00000000,0xf0000000,00000000,
17060xffffffff,0xffffffff,0xffffffff,0xffffffff,
17070xfffffc00,00000000,0xffffffff,0xffffffff,
17080xffffffff,0xffffffff,0xfffffc00,00000000,
17090xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
17100xfdffffff,0xffffffff,0xfe000000,00000000,
17110xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
17120xfdffffff,0xffffffff,0xfe000000,00000000,
17130xffffffff,0xfffff9ff,0xfe000000,00000000,
17140xffffffff,0xfffff9ff,0xfe000000,00000000,
17150x00030000,00000000,0xffffffff,0xffffffff,
17160xffffffff,0xffffffff,0xffffffff,0xffffffff,
17170xffffffff,0xffffffff,0xffffffff,0xffffffff,
17180xffffffff,0xffffffff,0xffffffff,0xffffffff,
17190xffffffff,0xffffffff },
1720
1721/* st_cond2
1722 *
1723 * ctr0: is the overflow for ctr1
1724 * ctr1: counts major op 03
1725 * ctr2: counts CMPIB (dw) predicted not taken.
1726 * ctr3: is the overflow for ctr2
1727 */
1728{
17290x4c01e000,00000000,0x00060000,00000000,
17300xe0e0c0e0,0xffffffff,0xffffffff,0xffc09780,
17310x0101ffff,0xff21f077,0xe000407f,0xffffc87f,
17320xffffffff,0xffffffff,0xff000000,00000000,
17330xffffffff,0xffffffff,0xffffffff,0xffffffff,
17340xffffffff,00000000,0xffffffff,0xffffffff,
17350xffffffff,0xffffffff,0xffffffff,0xffffffff,
17360xffffffff,0xffffffff,0xffffffff,0xffffffff,
17370xffff0000,00000000,0xffffffff,0xffffffff,
17380xffffffff,0xffffffff,0xffffffff,0xf0000000,
17390xf0000060,0x00003c00,0x04f90000,0x02013e40,
17400x0081004f,0x90004060,0x13e40018,0x0024f900,
17410x0802093e,0x40028102,0x4f9000c0,0x6093e400,
17420x380014f9,0x00010205,0x3e4000c1,0x014f9000,
17430x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
17440xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
17450xffffffff,0xffffffff,0xffffffff,0xffffffff,
17460xffffffff,0xffffffff,0xffffffff,0xffffffff,
17470xffffffff,0xffffffff,0xffffffff,0xffffffff,
17480xffffffff,0xffffffff,0xffffffff,0xffffffff,
17490xffffffff,0xffffffff,0xffffffff,0xfffffc00,
175000000000,00000000,00000000,00000000,
17510xffff0000,00000000,0xf0000000,00000000,
17520xffffffff,0xffffffff,0xffffffff,0xffffffff,
17530xfffffc00,00000000,0xffffffff,0xffffffff,
17540xffffffff,0xffffffff,0xfffffc00,00000000,
17550xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
17560xfdffffff,0xffffffff,0xfe000000,00000000,
17570xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
17580xfdffffff,0xffffffff,0xfe000000,00000000,
17590xffffffff,0xfffff9ff,0xfe000000,00000000,
17600xffffffff,0xfffff9ff,0xfe000000,00000000,
17610x00030000,00000000,0xffffffff,0xffffffff,
17620xffffffff,0xffffffff,0xffffffff,0xffffffff,
17630xffffffff,0xffffffff,0xffffffff,0xffffffff,
17640xffffffff,0xffffffff,0xffffffff,0xffffffff,
17650xffffffff,0xffffffff },
1766
1767/* st_cond3
1768 *
1769 * ctr0: is the overflow for ctr1
1770 * ctr1: counts major ops 06 & 26
1771 * ctr2: counts BB, BVB, MOVB, MOVIB (incl. nullified) predicted not-taken
1772 * ctr3: is the overflow for ctr2
1773 */
1774{
17750x4c01e000,00000000,0x00060000,00000000,
17760xe0e0c0e0,0xffffffff,0xffffffff,0xffc03780,
17770x0101ffff,0xff29f016,0xe000407f,0xffffe97f,
17780xffffffff,0xffffffff,0xff000000,00000000,
17790xffffffff,0xffffffff,0xffffffff,0xffffffff,
17800xffffffff,00000000,0xffffffff,0xffffffff,
17810xffffffff,0xffffffff,0xffffffff,0xffffffff,
17820xffffffff,0xffffffff,0xffffffff,0xffffffff,
17830xffff0000,00000000,0xffffffff,0xffffffff,
17840xffffffff,0xffffffff,0xffffffff,0xf0000000,
17850xf0000060,0x00003c00,0x04f90000,0x02013e40,
17860x0081004f,0x90004060,0x13e40018,0x0024f900,
17870x0802093e,0x40028102,0x4f9000c0,0x6093e400,
17880x380014f9,0x00010205,0x3e4000c1,0x014f9000,
17890x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
17900xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
17910xffffffff,0xffffffff,0xffffffff,0xffffffff,
17920xffffffff,0xffffffff,0xffffffff,0xffffffff,
17930xffffffff,0xffffffff,0xffffffff,0xffffffff,
17940xffffffff,0xffffffff,0xffffffff,0xffffffff,
17950xffffffff,0xffffffff,0xffffffff,0xfffffc00,
179600000000,00000000,00000000,00000000,
17970xffff0000,00000000,0xf0000000,00000000,
17980xffffffff,0xffffffff,0xffffffff,0xffffffff,
17990xfffffc00,00000000,0xffffffff,0xffffffff,
18000xffffffff,0xffffffff,0xfffffc00,00000000,
18010xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
18020xfdffffff,0xffffffff,0xfe000000,00000000,
18030xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
18040xfdffffff,0xffffffff,0xfe000000,00000000,
18050xffffffff,0xfffff9ff,0xfe000000,00000000,
18060xffffffff,0xfffff9ff,0xfe000000,00000000,
18070x00030000,00000000,0xffffffff,0xffffffff,
18080xffffffff,0xffffffff,0xffffffff,0xffffffff,
18090xffffffff,0xffffffff,0xffffffff,0xffffffff,
18100xffffffff,0xffffffff,0xffffffff,0xffffffff,
18110xffffffff,0xffffffff },
1812
1813/* st_cond4
1814 *
1815 * ctr0: is the overflow for ctr1
1816 * ctr1: counts major op 2E
1817 * ctr2: counts CMPB, CMPIB, ADDB, ADDIB (incl. nullified) predicted not-taken
1818 * ctr3: is the overflow for ctr2
1819 */
1820{
18210x4c01e000,00000000,0x00060000,00000000,
18220xe0e0c0e0,0xffffffff,0xffffffff,0xffc17780,
18230x0101ffff,0xff21f014,0xe000407f,0xffffe9ff,
18240xffffffff,0xffffffff,0xff000000,00000000,
18250xffffffff,0xffffffff,0xffffffff,0xffffffff,
18260xffffffff,00000000,0xffffffff,0xffffffff,
18270xffffffff,0xffffffff,0xffffffff,0xffffffff,
18280xffffffff,0xffffffff,0xffffffff,0xffffffff,
18290xffff0000,00000000,0xffffffff,0xffffffff,
18300xffffffff,0xffffffff,0xffffffff,0xf0000000,
18310xf0000060,0x00003c00,0x04f90000,0x02013e40,
18320x0081004f,0x90004060,0x13e40018,0x0024f900,
18330x0802093e,0x40028102,0x4f9000c0,0x6093e400,
18340x380014f9,0x00010205,0x3e4000c1,0x014f9000,
18350x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
18360xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
18370xffffffff,0xffffffff,0xffffffff,0xffffffff,
18380xffffffff,0xffffffff,0xffffffff,0xffffffff,
18390xffffffff,0xffffffff,0xffffffff,0xffffffff,
18400xffffffff,0xffffffff,0xffffffff,0xffffffff,
18410xffffffff,0xffffffff,0xffffffff,0xfffffc00,
184200000000,00000000,00000000,00000000,
18430xffff0000,00000000,0xf0000000,00000000,
18440xffffffff,0xffffffff,0xffffffff,0xffffffff,
18450xfffffc00,00000000,0xffffffff,0xffffffff,
18460xffffffff,0xffffffff,0xfffffc00,00000000,
18470xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
18480xfdffffff,0xffffffff,0xfe000000,00000000,
18490xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
18500xfdffffff,0xffffffff,0xfe000000,00000000,
18510xffffffff,0xfffff9ff,0xfe000000,00000000,
18520xffffffff,0xfffff9ff,0xfe000000,00000000,
18530x00030000,00000000,0xffffffff,0xffffffff,
18540xffffffff,0xffffffff,0xffffffff,0xffffffff,
18550xffffffff,0xffffffff,0xffffffff,0xffffffff,
18560xffffffff,0xffffffff,0xffffffff,0xffffffff,
18570xffffffff,0xffffffff },
1858
1859/* st_unpred0
1860 *
1861 * ctr0: is the overflow for ctr1
1862 * ctr1: counts BE and BE,L
1863 * ctr2: counts BE and BE,L including nullified
1864 * ctr3: is the overflow for ctr2
1865 */
1866{
18670x4c01e000,00000000,0x00060000,00000000,
18680xe0c0c0e0,0xffffffff,0xffffffff,0xffdf5bbf,
18690xffffffff,0xff25f7d6,0xefffffff,0xffffc97f,
18700xffffffff,0xffffffff,0xff000000,00000000,
18710xffffffff,0xffffffff,0xffffffff,0xffffffff,
18720xffffffff,00000000,0xffffffff,0xffffffff,
18730xffffffff,0xffffffff,0xffffffff,0xffffffff,
18740xffffffff,0xffffffff,0xffffffff,0xffffffff,
18750xffff0000,00000000,0xffffffff,0xffffffff,
18760xffffffff,0xffffffff,0xffffffff,0xf0000000,
18770xf0000060,0x00003c00,0x04f90000,0x02013e40,
18780x0081004f,0x90004060,0x13e40018,0x0024f900,
18790x0802093e,0x40028102,0x4f9000c0,0x6093e400,
18800x380014f9,0x00010205,0x3e4000c1,0x014f9000,
18810x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
18820xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
18830xffffffff,0xffffffff,0xffffffff,0xffffffff,
18840xffffffff,0xffffffff,0xffffffff,0xffffffff,
18850xffffffff,0xffffffff,0xffffffff,0xffffffff,
18860xffffffff,0xffffffff,0xffffffff,0xffffffff,
18870xffffffff,0xffffffff,0xffffffff,0xfffffc00,
188800000000,00000000,00000000,00000000,
18890xffff0000,00000000,0xf0000000,00000000,
18900xffffffff,0xffffffff,0xffffffff,0xffffffff,
18910xfffffc00,00000000,0xffffffff,0xffffffff,
18920xffffffff,0xffffffff,0xfffffc00,00000000,
18930xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
18940xfdffffff,0xffffffff,0xfe000000,00000000,
18950xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
18960xfdffffff,0xffffffff,0xfe000000,00000000,
18970xffffffff,0xfffff9ff,0xfe000000,00000000,
18980xffffffff,0xfffff9ff,0xfe000000,00000000,
18990x00030000,00000000,0xffffffff,0xffffffff,
19000xffffffff,0xffffffff,0xffffffff,0xffffffff,
19010xffffffff,0xffffffff,0xffffffff,0xffffffff,
19020xffffffff,0xffffffff,0xffffffff,0xffffffff,
19030xffffffff,0xffffffff },
1904
1905/* st_unpred1
1906 *
1907 * ctr0: is the overflow for ctr1
1908 * ctr1: counts BLR, BV, BVE, BVE,L
1909 * ctr2: counts BLR, BV, BVE, BVE,L including nullified
1910 * ctr3: is the overflow for ctr2
1911 */
1912{
19130x4c01e000,00000000,0x00060000,00000000,
19140xe0c0c0e0,0xffffffff,0xffffffff,0xffc15f80,
19150x0501ff7f,0xff21f057,0xe001407f,0xdfffc87f,
19160xffffffff,0xffffffff,0xff000000,00000000,
19170xffffffff,0xffffffff,0xffffffff,0xffffffff,
19180xffffffff,00000000,0xffffffff,0xffffffff,
19190xffffffff,0xffffffff,0xffffffff,0xffffffff,
19200xffffffff,0xffffffff,0xffffffff,0xffffffff,
19210xffff0000,00000000,0xffffffff,0xffffffff,
19220xffffffff,0xffffffff,0xffffffff,0xf0000000,
19230xf0000060,0x00003c00,0x04f90000,0x02013e40,
19240x0081004f,0x90004060,0x13e40018,0x0024f900,
19250x0802093e,0x40028102,0x4f9000c0,0x6093e400,
19260x380014f9,0x00010205,0x3e4000c1,0x014f9000,
19270x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
19280xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
19290xffffffff,0xffffffff,0xffffffff,0xffffffff,
19300xffffffff,0xffffffff,0xffffffff,0xffffffff,
19310xffffffff,0xffffffff,0xffffffff,0xffffffff,
19320xffffffff,0xffffffff,0xffffffff,0xffffffff,
19330xffffffff,0xffffffff,0xffffffff,0xfffffc00,
193400000000,00000000,00000000,00000000,
19350xffff0000,00000000,0xf0000000,00000000,
19360xffffffff,0xffffffff,0xffffffff,0xffffffff,
19370xfffffc00,00000000,0xffffffff,0xffffffff,
19380xffffffff,0xffffffff,0xfffffc00,00000000,
19390xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
19400xfdffffff,0xffffffff,0xfe000000,00000000,
19410xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
19420xfdffffff,0xffffffff,0xfe000000,00000000,
19430xffffffff,0xfffff9ff,0xfe000000,00000000,
19440xffffffff,0xfffff9ff,0xfe000000,00000000,
19450x00030000,00000000,0xffffffff,0xffffffff,
19460xffffffff,0xffffffff,0xffffffff,0xffffffff,
19470xffffffff,0xffffffff,0xffffffff,0xffffffff,
19480xffffffff,0xffffffff,0xffffffff,0xffffffff,
19490xffffffff,0xffffffff },
1950
1951/* unpred
1952 *
1953 * ctr0: counts non-nullified unpredictable branches
1954 * ctr1: is the overflow for ctr0
1955 * ctr2: counts all unpredictable branches (nullified or not)
1956 * ctr3: is the overflow for ctr2
1957 */
1958{
19590xcc01e000,00000000,0x00060000,00000000,
19600x20202020,0xff31ffff,0xfff7fffe,0x97ffcc7f,
19610xfffffdff,0xffa5fff3,0x1fffffff,0x7fffe97f,
19620xffffffff,0xffffffff,0xff000000,00000000,
19630xffffffff,0xffffffff,0xffffffff,0xffffffff,
19640xffffffff,00000000,0xffffffff,0xffffffff,
19650xffffffff,0xffffffff,0xffffffff,0xffffffff,
19660xffffffff,0xffffffff,0xffffffff,0xffffffff,
19670xffff0000,00000000,0xffffffff,0xffffffff,
19680xffffffff,0xffffffff,0xffffffff,0xf0000000,
19690xf00000a0,0x00003c00,0x02f50000,0x0004bd40,
19700x0040802f,0x50002020,0x4bd4000c,0x0042f500,
19710x040014bd,0x40014084,0x2f500060,0x214bd400,
19720x1c2002f5,0x00080804,0xbd400242,0x802f5000,
19730xa0a04bd4,0x002c2042,0xf5000c08,0x14bd4003,
19740x42842f50,0x00e0a14b,0xd4003fff,0xffffffff,
19750xffffffff,0xffffffff,0xffffffff,0xffffffff,
19760xffffffff,0xffffffff,0xffffffff,0xffffffff,
19770xffffffff,0xffffffff,0xffffffff,0xffffffff,
19780xffffffff,0xffffffff,0xffffffff,0xffffffff,
19790xffffffff,0xffffffff,0xffffffff,0xfffffc00,
198000000000,00000000,00000000,00000000,
19810xffff0000,00000000,0xf0000000,00000000,
19820xffffffff,0xffffffff,0xffffffff,0xffffffff,
19830xfffffc00,00000000,0xffffffff,0xffffffff,
19840xffffffff,0xffffffff,0xfffffc00,00000000,
19850xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
19860xfdffffff,0xffffffff,0xfe000000,00000000,
19870xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
19880xfdffffff,0xffffffff,0xfe000000,00000000,
19890xffffffff,0xfffff9ff,0xfe000000,00000000,
19900xffffffff,0xfffff9ff,0xfe000000,00000000,
19910x00030000,00000000,0xffffffff,0xffffffff,
19920xffffffff,0xffffffff,0xffffffff,0xffffffff,
19930xffffffff,0xffffffff,0xffffffff,0xffffffff,
19940xffffffff,0xffffffff,0xffffffff,0xffffffff,
19950xffffffff,0xffffffff },
1996
1997
1998/* go_store
1999 *
2000 * ctr0: Overflow for counter 2
2001 * ctr1: Overflow for counter 3
2002 * ctr2: count of GO_STORE_E signal
2003 * ctr3: count of GO_STORE_O signal
2004 */
2005
2006 {
2007 0x0c00e000, 0x00000000, 0x00060000, 0x00000000,
2008 0xe0e0e0e0, 0xffffffff, 0xffffffff, 0xffffffff,
2009 0xffffffff, 0xffa5ffff, 0xffffffff, 0xffffffff,
2010 0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
2011 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2012 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
2013 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2014 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2015 0xffff0000, 0x00000000, 0x7fffffff, 0xffffffff,
2016 0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
2017 0x00000000, 0x0000c000, 0x067c0000, 0x01019f00,
2018 0x00408067, 0xc0002030, 0x19f0000c, 0x000e7c00,
2019 0x0401039f, 0x00014080, 0xe7c00060, 0x3039f000,
2020 0x1c00167c, 0x00080105, 0x9f000240, 0x8167c000,
2021 0xa03059f0, 0x002c001e, 0x7c000c01, 0x079f0003,
2022 0x4081e7c0, 0x00e03079, 0xf0003fc0, 0x07fff800,
2023 0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
2024 0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
2025 0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
2026 0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
2027 0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
2028 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2029 0x70130000, 0x00000000, 0x70000000, 0x00000000,
2030 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2031 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
2032 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
2033 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
2034 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
2035 0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
2036 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
2037 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
2038 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
2039 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
2040 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2041 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2042 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2043 0xffffffff, 0xffffffff
2044 },
2045
2046
2047/* shlib_call
2048 *
2049 * ctr0: SharedLib call Depth1
2050 * ctr1: SharedLib call Depth2
2051 * ctr2: SharedLib call Depth3
2052 * ctr3: SharedLib call Depth>3
2053 */
2054 {
2055 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
2056 0xe0e0e0e0, 0xc76fa005, 0x07dd7e9c, 0x87115b80,
2057 0x01100200, 0x07200004, 0xe000407f, 0xfffffffc,
2058 0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
2059 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2060 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
2061 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2062 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2063 0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
2064 0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
2065 0xf0000000, 0x00003c20, 0x01ff0808, 0x04007fc0,
2066 0x0003001f, 0xf0000180, 0x07fc4010, 0x5001ff00,
2067 0x001c007f, 0xc2000a00, 0x1ff18022, 0x4007fc20,
2068 0x00b001ff, 0x10003800, 0x7fc8004d, 0x001ff100,
2069 0x03c007fc, 0x60012001, 0xff280144, 0x007fc600,
2070 0x13001ff2, 0x00058007, 0xfcc00550, 0x01ff2000,
2071 0x5c007fca, 0x001a001f, 0xf3801640, 0x07fca001,
2072 0xb001ff30, 0x0078007f, 0xd0005d00, 0x1ff30007,
2073 0xc007fce0, 0x022001ff, 0x48018400, 0x7fce0023,
2074 0x001ff400, 0x098007fd, 0x20065001, 0xff40009c,
2075 0x007fd200, 0x3fffffff, 0x800fffff, 0xffe00000,
2076 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2077 0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
2078 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2079 0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
2080 0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
2081 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
2082 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
2083 0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
2084 0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
2085 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
2086 0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
2087 0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
2088 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2089 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2090 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2091 0xffffffff, 0xffffffff
2092 }
2093};
2094#define PCXW_IMAGE_SIZE 576
2095
2096static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] = {
2097/*
2098 * CPI: FROM CPI.IDF (Image 0)
2099 *
2100 * Counts the following:
2101 *
2102 * ctr0 : total cycles
2103 * ctr1 : total cycles where nothing retired
2104 * ctr2 : total instructions retired, including nullified
2105 * ctr3 : total instructions retired, less nullified instructions
2106 */
2107 {
2108 0x4c00c000, 0x00000000, 0x00060000, 0x00000000,
2109 0xe0e0e0e0, 0x00001fff, 0xfc00007f, 0xfff00001,
2110 0xffffc000, 0x07ffff00, 0x07ffffff, 0x6007ffff,
2111 0xff0007ff, 0xffff0007, 0xffffff00, 0x00000000,
2112 0x60f00000, 0x0fffff00, 0x000fffff, 0x00000fff,
2113 0xff00000f, 0xffff0000, 0x00000000, 0x00ffffff,
2114 0xfffff000, 0x0000000f, 0xffffffff, 0xff000000,
2115 0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
2116 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2117 0x00000000, 0x00000000, 0x00270000, 0x00000055,
2118 0x0200000e, 0x4d300000, 0x00000000, 0x0ff00002,
2119 0x70000000, 0x00000020, 0x0000e400, 0x00000ff0,
2120 0x00000000, 0x00000000, 0x00000055, 0xffffff00,
2121 0x00000000, 0x0000ff00, 0x00000000, 0x0f000000,
2122 0x0000055f, 0xfffff000, 0x00000000, 0x000ff000,
2123 0x00000000, 0x00000000, 0x000055ff, 0xffff0000,
2124 0x00000000, 0x00ff0000, 0x00000000, 0xf0000000,
2125 0x000055ff, 0xffff0000, 0x00000000, 0x00ff0000,
2126 0x00000000, 0x00000000, 0x00055fff, 0xfff00000,
2127 0x00000000, 0x0ff00000, 0x00000030, 0x00000000,
2128 0x00157fff, 0xffc00000, 0x034c0000, 0x00000000,
2129 0x03fc0000, 0x00000000, 0x6fff0000, 0x00000000,
2130 0x60000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2131 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2132 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2133 0xfff7fbfc, 0x00000000, 0xffffafff, 0xffffff3f,
2134 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2135 0x00000000, 0x00000000, 0xffffafff, 0xffffff3f,
2136 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2137 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2138 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2139 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2140 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2141 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2142 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2143 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2144 },
2145
2146/* Bus utilization image FROM BUS_UTIL.IDF (Image 1)
2147 *
2148 * ctr0 : counts address valid cycles
2149 * ctr1 : counts data valid cycles
2150 * ctr2 : counts overflow from counter 0
2151 * ctr3 : counts overflow from counter 1
2152 */
2153 {
2154 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
2155 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
2156 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2157 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2158 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2159 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2160 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2161 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2162 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2163 0x00000000, 0x00000000, 0x00001b00, 0xaa000000,
2164 0x00000001, 0x30700000, 0x00055aaf, 0xf0000000,
2165 0x01b00000, 0x00000000, 0x00001037, 0x00000000,
2166 0x55aaff00, 0x00c00000, 0x1b55aa00, 0x00000000,
2167 0x0001fff0, 0xcfffff00, 0x00000000, 0x0f0fffff,
2168 0xffffffff, 0xffffffff, 0x30ffff0c, 0xfffff000,
2169 0x00000000, 0x00ffffff, 0xffffffff, 0xfffffff3,
2170 0x0ffff0cf, 0xffff0000, 0x00000000, 0x00ffffff,
2171 0xffffffff, 0xfffffff3, 0x0ffff0cf, 0xffff0000,
2172 0x00000000, 0x0fffffff, 0xffffffff, 0xffffff30,
2173 0xfff70000, 0x000055aa, 0xff000000, 0x000006d5,
2174 0x40000000, 0x00000000, 0x731c0000, 0x000156ab,
2175 0xfc000000, 0x00000000, 0xffff0000, 0x00000000,
2176 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2177 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2178 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2179 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2180 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2181 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2182 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2183 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2184 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2185 0xfe000000, 0x00000000, 0x00100000, 0x00000000,
2186 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2187 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2188 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2189 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2190 },
2191
2192/*
2193 * TLB counts: FROM TLBSTATS.IDF (Image 2)
2194 *
2195 * Counts the following:
2196 *
2197 * ctr0: DTLB misses
2198 * ctr1: ITLB misses
2199 * ctr2: total cycles in the miss handlers
2200 * ctr3: total cycles
2201 */
2202
2203 {
2204 0x0c00c000, 0x00000000, 0x00060000, 0x00000000,
2205 0xe7e7e0e0, 0x00001fff, 0xfc00007f, 0xfff00001,
2206 0xfff00000, 0x07ffff00, 0x07ffffff, 0x6007ffff,
2207 0xa00007ff, 0xffff0007, 0xffffff00, 0x00000000,
2208 0x603001c1, 0xe0000001, 0xc0c00000, 0x00000fff,
2209 0xff00000f, 0xffff0000, 0x00000000, 0x00400000,
2210 0x00001000, 0x00000004, 0x00000000, 0x01000000,
2211 0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
2212 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2213 0x00000000, 0x00000000, 0x00800000, 0x00153f7f,
2214 0x55000000, 0xaf800000, 0xc0000000, 0x0403f240,
2215 0x00000000, 0x00001010, 0x00004700, 0x00000ff0,
2216 0x00000000, 0x00000000, 0x00000055, 0xffffff00,
2217 0x00000000, 0x0000ff00, 0x00000000, 0x0f000000,
2218 0x0000055f, 0xfffff000, 0x00000000, 0x000ff000,
2219 0x00000000, 0x00000000, 0x000055ff, 0xffff0000,
2220 0x00000000, 0x00ff0000, 0x00000000, 0xf0000000,
2221 0x000055ff, 0xffff0000, 0x00000000, 0x00ff0000,
2222 0x00000000, 0x00000000, 0x00055fff, 0xfff00000,
2223 0x00000000, 0x0ff00000, 0x00000000, 0x00000000,
2224 0x00157fff, 0xffc00000, 0x00000000, 0x3fc00000,
2225 0x00040000, 0x00000000, 0x6fff0000, 0x00000000,
2226 0x60000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2227 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2228 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2229 0xfff7fbfc, 0x00000000, 0xffffafff, 0xffffff3f,
2230 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2231 0x00000000, 0x00000000, 0xffffafff, 0xffffff3f,
2232 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2233 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2234 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2235 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2236 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2237 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2238 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2239 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2240 },
2241
2242/* tlbhandler FROM tlbHandMiss.idf (Image 3)
2243 *
2244 * ctr0: TLB misses
2245 * ctr1: dmisses inside the TLB miss handler
2246 * ctr2: cycles in the TLB miss handler
2247 * ctr3: overflow of ctr2
2248 */
2249 {
2250 0x1c00c000, 0x00000000, 0x00060000, 0x00000000,
2251 0xe7e7e0e0, 0x00001fff, 0xfc00007f, 0xfff00001,
2252 0xfff00000, 0x07ffff00, 0x07ffffff, 0x6007ffff,
2253 0xa00007ff, 0xffff0007, 0xffffff00, 0x00000000,
2254 0x603001c1, 0xe0000001, 0xc0c00000, 0x00000fff,
2255 0xff00000f, 0xffff0000, 0x00000000, 0x00400000,
2256 0x00001000, 0x00000004, 0x00000000, 0x01000000,
2257 0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
2258 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2259 0x00000000, 0x00000000, 0x006c0000, 0x01000054,
2260 0x02000002, 0xc3200000, 0xc00aa000, 0x0c03f240,
2261 0x00000000, 0x00001010, 0x000044f4, 0x00000c00,
2262 0xaa0000f0, 0x0f0000b0, 0x00005005, 0x0f5f0000,
2263 0x0001f000, 0x0000ff00, 0x00000000, 0x0f000000,
2264 0x0000055f, 0xfffff000, 0x00000000, 0x000ff000,
2265 0x00000000, 0x00000000, 0x000055ff, 0xffff0000,
2266 0x00000000, 0x00ff0000, 0x00000000, 0xf0000000,
2267 0x000055ff, 0xffff0000, 0x00000000, 0x00ff0000,
2268 0x00000000, 0x00000000, 0x00055fff, 0xfff00000,
2269 0x00000000, 0x0ff00a00, 0x000f0000, 0x24004000,
2270 0x15400001, 0x40c00003, 0x3da00000, 0x0002a800,
2271 0x00ff0000, 0x00000000, 0x6fff0000, 0x00000000,
2272 0x60000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2273 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2274 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2275 0xfff7fbfc, 0x00000000, 0xffffafff, 0xffffff3f,
2276 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2277 0x00000000, 0x00000000, 0xffffafff, 0xffffff3f,
2278 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2279 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2280 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2281 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2282 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2283 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2284 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2285 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2286 },
2287
2288/* branch_taken image FROM PTKN.IDF (Image 4)
2289 *
2290 * ctr0: mispredicted branches
2291 * ctr1: predicted taken branches, actually taken
2292 * ctr2: predicted taken branches (includes nullfied)
2293 * ctr3: all branches
2294 */
2295
2296 {
2297 0xcc01e000, 0x00000000, 0x00000000, 0x00000000,
2298 0xa08080a0, 0xffffffff, 0xffffffff, 0xffffffff,
2299 0xffffffff, 0xfffffeff, 0xfffeffff, 0xffffffff,
2300 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2301 0xf4ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2302 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2303 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2304 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2305 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2306 0x00000000, 0x00000000, 0xd22d0000, 0x00000000,
2307 0x0000000b, 0x46000000, 0x00000000, 0x0ffff900,
2308 0x90000000, 0x00000000, 0x0000907e, 0x00000000,
2309 0x000000ff, 0xff00bfdf, 0x03030303, 0x03030000,
2310 0x000dbfff, 0xffffff00, 0x00000000, 0x0f0fffff,
2311 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2312 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2313 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2314 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2315 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2316 0xffff5555, 0x55500000, 0x003f3ff0, 0x2766c000,
2317 0x00000000, 0x00000002, 0x67840000, 0x00000000,
2318 0x03fffc00, 0x00000000, 0xffff0000, 0x00000000,
2319 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2320 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2321 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2322 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2323 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2324 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2325 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2326 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2327 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2328 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2329 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2330 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2331 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2332 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2333 },
2334
2335/* branch_nottaken FROM PNTKN.IDF (Image 5)
2336 *
2337 * ctr0: mispredicted branches
2338 * ctr1: branches predicted not-taken, but actually taken
2339 * ctr2: branches predicted not-taken (includes nullified)
2340 * ctr3: all branches
2341 */
2342 {
2343 0xcc01e000, 0x00000000, 0x00000000, 0x00000000,
2344 0xe0c0c0e0, 0xffffffff, 0xffffffff, 0xffefffff,
2345 0xffffbfff, 0xfffffeff, 0xfffeffff, 0xfffffeff,
2346 0xfffffffe, 0xffffffff, 0xffffff00, 0x00000000,
2347 0xf4ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2348 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2349 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2350 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2351 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2352 0x00000000, 0x00000000, 0xd22d0000, 0x00000000,
2353 0x0000000b, 0x46000000, 0x00000000, 0x0ffff900,
2354 0x90000000, 0x00000000, 0x0000907e, 0x00000000,
2355 0x000000ff, 0xff00bfdf, 0x03030303, 0x03030000,
2356 0x000dbfff, 0xffffff00, 0x00000000, 0x0f0fffff,
2357 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2358 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2359 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2360 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2361 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2362 0xffff5555, 0x55500000, 0x003f3ff0, 0x2766c000,
2363 0x00000000, 0x00000002, 0x67840000, 0x00000000,
2364 0x03fffc00, 0x00000000, 0xffff0000, 0x00000000,
2365 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2366 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2367 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2368 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2369 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2370 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2371 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2372 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2373 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2374 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2375 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2376 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2377 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2378 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2379 },
2380
2381/* IMISS image (Image 6)
2382 *
2383 * ctr0 : icache misses for retired instructions
2384 * ctr1 : total cycles
2385 * ctr2 : dcache misses for retired instructions
2386 * ctr3 : number of retired instructions
2387 */
2388 {
2389 0x2801e000, 0x00000000, 0x00010000, 0x00000000,
2390 0x00001000, 0xffffffff, 0xffffffff, 0xfff00fff,
2391 0xfffa3fff, 0xffffffff, 0xffffffff, 0xffffffff,
2392 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2393 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2394 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2395 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2396 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2397 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2398 0x00000000, 0x00000000, 0xf2fdf0f0, 0xf0f0f0f0,
2399 0xffffffff, 0xf6c00000, 0x00000000, 0x0ff55800,
2400 0x90000000, 0x00000000, 0x0000b0ff, 0xfffffff0,
2401 0x00000003, 0x0100bfff, 0x3f3f3f3f, 0x3f3f5555,
2402 0x555fffff, 0xffffff00, 0x00000000, 0x000fffff,
2403 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2404 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2405 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2406 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2407 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2408 0xffffffff, 0xfff00000, 0x000301b0, 0x2fefcfcf,
2409 0xcfcfcfcf, 0xd5555557, 0xf7b40000, 0x00000000,
2410 0x03c14000, 0x00000000, 0xffff0000, 0x00000000,
2411 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2412 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
2413 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2414 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
2415 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2416 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
2417 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2418 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2419 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2420 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
2421 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2422 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2423 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2424 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2425 },
2426
2427/* DMISS image (Image 7)
2428 *
2429 * ctr0 : icache misses for retired instructions
2430 * ctr1 : total cycles
2431 * ctr2 : dcache misses for retired instructions
2432 * ctr3 : number of retired instructions
2433 */
2434 {
2435 0x2801e000, 0x00000000, 0x00010000, 0x00000000,
2436 0x00001000, 0xffffffff, 0xffffffff, 0xfff00fff,
2437 0xfffa3fff, 0xffffffff, 0xffffffff, 0xffffffff,
2438 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2439 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2440 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2441 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2442 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2443 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2444 0x00000000, 0x00000000, 0xf2fdf0f0, 0xf0f0f0f0,
2445 0xffffffff, 0xf6c00000, 0x00000000, 0x0ff55800,
2446 0x90000000, 0x00000000, 0x0000b0ff, 0xfffffff0,
2447 0x00000003, 0x0100bfff, 0x3f3f3f3f, 0x3f3f5555,
2448 0x555fffff, 0xffffff00, 0x00000000, 0x000fffff,
2449 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2450 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2451 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2452 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2453 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2454 0xffffffff, 0xfff00000, 0x000301b0, 0x2fefcfcf,
2455 0xcfcfcfcf, 0xd5555557, 0xf7b40000, 0x00000000,
2456 0x03c14000, 0x00000000, 0xffff0000, 0x00000000,
2457 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2458 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
2459 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2460 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
2461 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2462 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
2463 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2464 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2465 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2466 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
2467 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2468 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2469 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2470 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2471 },
2472
2473/* dmiss_access image FROM DMISS_RATIO.IDF (Image 8)
2474 *
2475 * ctr0 : all loads and stores that retire (even lines)
2476 * ctr1 : all loads and stores that retire (odd lines)
2477 * ctr2 : dcache misses of retired loads/stores
2478 * ctr3 : all READ_PRIV and READ_SHAR_OR_PRIV on Runway
2479 * (Speculative and Non-Speculative)
2480 */
2481 {
2482 0x2d81e000, 0x00000000, 0x00000000, 0x00000000,
2483 0x10101010, 0x00ffffff, 0xa003ffff, 0xfe800fff,
2484 0xfffa003f, 0xffffe8ff, 0xffffffff, 0xffffffff,
2485 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2486 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2487 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2488 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2489 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2490 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2491 0x00000000, 0x00000000, 0xd2280a00, 0x00000000,
2492 0x0000000b, 0x46000000, 0x00000005, 0x555ff900,
2493 0x80200000, 0x00000000, 0x0000907e, 0x00000000,
2494 0x00005555, 0xff80bf8b, 0xab030303, 0x03030000,
2495 0x000dbfff, 0xffffff00, 0x00000000, 0x000fffff,
2496 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2497 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2498 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2499 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2500 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2501 0xffff5555, 0x55500000, 0x15153fe0, 0x27628880,
2502 0x00000000, 0x00000002, 0x67840000, 0x00000001,
2503 0x5557fc00, 0x00000000, 0xffff0000, 0x00000000,
2504 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2505 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
2506 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2507 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
2508 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2509 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
2510 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2511 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2512 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2513 0xfe000000, 0x00000000, 0x00110000, 0x00000000,
2514 0xf4ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2515 0xf8ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2516 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2517 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2518 },
2519
2520
2521/* big_cpi image (Image 9)
2522 *
2523 * ctr0 : Total number of CPU clock cycles.
2524 * ctr1 : Unused
2525 * ctr2 : Unused
2526 * ctr3 : Total number of Non-Nullified instructions retired.
2527 */
2528 {
2529 0x0c00c000, 0x00000000, 0x00060000, 0x00000000,
2530 0xe7e7e0e0, 0x00001fff, 0xfc00007f, 0xfff00001,
2531 0xfff00000, 0x07ffff00, 0x07ffffff, 0x6007ffff,
2532 0xa00007ff, 0xffff0007, 0xffffff00, 0x00000000,
2533 0x603001c1, 0xe0000001, 0xc0c00000, 0x00000fff,
2534 0xff00000f, 0xffff0000, 0x00000000, 0x00400000,
2535 0x00001000, 0x00000004, 0x00000000, 0x01000000,
2536 0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
2537 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2538 0x00000000, 0x00000000, 0x00550005, 0x00220000,
2539 0x0000000c, 0x71f00000, 0x00f00aa0, 0x0aaff000,
2540 0x00005002, 0x20000000, 0x0000c413, 0x00000c0f,
2541 0x00aa0000, 0xff00b600, 0x000500a0, 0x00000300,
2542 0x000cc3f0, 0x0000c0f0, 0x0aa0000f, 0xff000000,
2543 0x011000a0, 0x05503000, 0x00d03700, 0x00000f00,
2544 0xaa005500, 0x00000000, 0x000055ff, 0xffff0000,
2545 0x00000000, 0x00ff0000, 0x00000000, 0xf000aa00,
2546 0x11000a00, 0x55000000, 0x0d037000, 0x00c0f00a,
2547 0xa0055000, 0x0db00005, 0x5002a000, 0x00300000,
2548 0xf40f0000, 0x0c0f00aa, 0x0000ff10, 0x27400000,
2549 0x00008000, 0x00c00003, 0x037c0000, 0x003c02a8,
2550 0x02abfc00, 0x00000000, 0x6fff0000, 0x00000000,
2551 0x60000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2552 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2553 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2554 0xfff7fbfc, 0x00000000, 0xffffafff, 0xffffff3f,
2555 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2556 0x00000000, 0x00000000, 0xffffafff, 0xffffff3f,
2557 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2558 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2559 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2560 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2561 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2562 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2563 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2564 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2565 },
2566
2567/* big_ls image (Image 10)
2568 *
2569 * ctr0 : Total number of CPU clock cycles during which local_stall_A1 is asserted
2570 * ctr1 : Overflow of Counter 0
2571 * ctr2 : Total number of IFLUSH_AV
2572 * ctr3 : Overflow of Counter 2
2573 */
2574 {
2575 0x0c000000, 0x00000000, 0x00060000, 0x00000000,
2576 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
2577 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2578 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2579 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2580 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2581 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2582 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2583 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2584 0x00000000, 0x00000000, 0x28880001, 0x54000000,
2585 0x00000004, 0xb6200000, 0x000aaaa0, 0x05555288,
2586 0x80000010, 0x00000000, 0x0000486e, 0x00000000,
2587 0xaaaa0055, 0x55002888, 0x00545401, 0x03030000,
2588 0x0007b000, 0x0000ff00, 0x00000000, 0x05000000,
2589 0x0000055f, 0xfffff000, 0x00000000, 0x000ff000,
2590 0x00000000, 0x00000000, 0x000055ff, 0xffff0000,
2591 0x00000000, 0x00ff0000, 0x00000000, 0x00000000,
2592 0x000055ff, 0xffff0000, 0x00000000, 0x00ff0000,
2593 0x00000000, 0xa0000000, 0x00055fff, 0xfff00000,
2594 0x00aa0000, 0x05502a2a, 0x00151500, 0x0a220015,
2595 0x40400000, 0x00000001, 0xe2980000, 0x0002aaa8,
2596 0x01555400, 0x00000000, 0x0df70000, 0x00000000,
2597 0x00000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2598 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2599 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2600 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2601 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2602 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2603 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2604 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2605 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2606 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2607 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2608 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2609 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2610 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2611 },
2612
2613/* br_abort image (Image 12)
2614 *
2615 * ctr0 : Total number of BRAD_STALLH
2616 * ctr1 : Total number of ONE_QUAD
2617 * ctr2 : Total number of BR0_ABRT
2618 * ctr3 : Total number of BR1_ABRT
2619 */
2620
2621 {
2622 0x0c002000, 0x00000000, 0x00060000, 0x00000000,
2623 0xe0e0e0e0, 0xffffffff, 0xffffffff, 0xff0fffff,
2624 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2625 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2626 0x1077ffff, 0xffffffff, 0xffffffff, 0xffffffff,
2627 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2628 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2629 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2630 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2631 0x00000000, 0x00000000, 0x551b0000, 0x00000000,
2632 0x0000000c, 0xd4f00000, 0x00000000, 0x0ffff001,
2633 0xb0000000, 0x00000000, 0x0000fd4c, 0x00000000,
2634 0x000000ff, 0xff00ff1b, 0x00000000, 0x00000000,
2635 0x0000d000, 0x0000ff00, 0x00000000, 0x0e0fffff,
2636 0xffffffff, 0xfffff000, 0x00000000, 0x000ff000,
2637 0x00000000, 0x00ffffff, 0xffffffff, 0xffff0000,
2638 0x00000000, 0x00ff0000, 0x00000000, 0x00ffffff,
2639 0xffffffff, 0xffff0000, 0x00000000, 0x00ff0000,
2640 0x00000000, 0xffffffff, 0xffffffff, 0xfff00000,
2641 0x00400000, 0x00000000, 0x00ffff00, 0x2a86c000,
2642 0x00000000, 0x00000000, 0xf50c0000, 0x00000000,
2643 0x03fffc00, 0x00000000, 0x1a250000, 0x00000000,
2644 0x10000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2645 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2646 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2647 0xfff7fbfc, 0x00000000, 0xffffafff, 0xffffff3f,
2648 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2649 0x00000000, 0x00000000, 0xffffafff, 0xffffff3f,
2650 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2651 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2652 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2653 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2654 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2655 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2656 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2657 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2658 },
2659
2660
2661/* isnt image (Image 13)
2662 *
2663 * ctr0 : Total number of cycles for which iside_notrans is asserted.
2664 * ctr1 : Total number of times iside_notrans is asserted for 1-4 cycles.
2665 * ctr2 : Total number of times iside_notrans is asserted for 5-7 cycles.
2666 * ctr3 : Total number of times iside_notrans is asserted for > 7 cycles.
2667 */
2668
2669 {
2670 0x0c018000, 0x00000000, 0x00060000, 0x00000000,
2671 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
2672 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2673 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2674 0xc0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2675 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2676 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2677 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2678 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2679 0x00000000, 0x00000000, 0x22000000, 0x000001bc,
2680 0x10000006, 0x00900000, 0x50000000, 0x00055a20,
2681 0x00000000, 0x00016060, 0x0000c021, 0x00000540,
2682 0x00000000, 0x55002200, 0x00000000, 0x56bc4000,
2683 0x00048000, 0x0000ff00, 0x00000000, 0x17000000,
2684 0x0000055f, 0xfffff000, 0x00000000, 0x000ff000,
2685 0x00000000, 0x00000000, 0x000055ff, 0xffff0000,
2686 0x00000000, 0x00ff0000, 0x00000000, 0x00000000,
2687 0x000055ff, 0xffff0000, 0x00000000, 0x00ff0000,
2688 0x00000000, 0x80000000, 0x00015bf3, 0xf5500000,
2689 0x02210000, 0x00100000, 0x00005500, 0x08800000,
2690 0x00001545, 0x85000001, 0x80240000, 0x11000000,
2691 0x00015400, 0x00000000, 0xcdff0000, 0x00000000,
2692 0xc0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2693 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2694 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2695 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2696 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2697 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2698 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2699 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2700 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2701 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2702 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2703 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2704 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2705 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2706 },
2707
2708/* quadrant image (image 14)
2709 *
2710 * ctr0 : Total number of instructions in quadrant 0.
2711 * ctr1 : Total number of instructions in quadrant 1.
2712 * ctr2 : Total number of instructions in quadrant 2.
2713 * ctr3 : Total number of instructions in quadrant 3.
2714 *
2715 * Only works for 32-bit applications.
2716 */
2717
2718 {
2719 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
2720 0xe0e0e0e0, 0x00001fff, 0xfc00007f, 0xfff00001,
2721 0xffffc000, 0x07ffff00, 0x07ffffff, 0x0007ffff,
2722 0xff0007ff, 0xffff0007, 0xffffff00, 0x00000000,
2723 0xf0000000, 0x0fffff00, 0x000fffff, 0x00000fff,
2724 0xff00000f, 0xffff0000, 0x00000000, 0x00ffffff,
2725 0xffcff000, 0x0000040f, 0xfffffffc, 0xff000000,
2726 0x0080ffff, 0xffffcff0, 0x0000000c, 0x0fffffff,
2727 0xfcff0000, 0x00000000, 0x00000000, 0x00000000,
2728 0x00000000, 0x00000000, 0x551b0000, 0x00000000,
2729 0x00000003, 0x17000000, 0x00000000, 0x0ffff001,
2730 0xb0000000, 0x00000000, 0x00000173, 0x00000000,
2731 0x000000ff, 0xff00ff1b, 0x00000000, 0x00000000,
2732 0x000f1ff0, 0xcfffff00, 0x00000000, 0x0f0fffff,
2733 0xffffffff, 0xffffffff, 0x30ffff0c, 0xfffff000,
2734 0x00000000, 0x00ffffff, 0xffffffff, 0xfffffff3,
2735 0x0ffff0cf, 0xffff0000, 0x00000000, 0xf0ffffff,
2736 0xffffffff, 0xfffffff3, 0x0ffff0cf, 0xffff0000,
2737 0x00000000, 0x0fffffff, 0xffffffff, 0xffffff30,
2738 0xff7f0000, 0x00000000, 0x00fffff0, 0x2a86c000,
2739 0x00000000, 0x00000003, 0x05f00000, 0x00000000,
2740 0x03fffc00, 0x00000000, 0xffff0000, 0x00000000,
2741 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2742 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2743 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2744 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2745 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2746 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2747 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2748 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2749 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2750 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2751 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2752 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2753 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2754 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2755 },
2756
2757/* rw_pdfet image (Image 15)
2758 *
2759 * ctr0 : Total of all READ_PRIV address valid cycles.
2760 * ctr1 : Total of all READ_PRIV data valid cycles.
2761 * ctr2 : Overflow of Counter 0.
2762 * ctr3 : Overflow of Counter 1.
2763 */
2764
2765 {
2766 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
2767 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
2768 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2769 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2770 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2771 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2772 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2773 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2774 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2775 0x00000000, 0x00000000, 0x00001b00, 0xaa000000,
2776 0x00000001, 0x30700000, 0x00055aaf, 0xf0000000,
2777 0x01b00000, 0x00000000, 0x00001037, 0x00000000,
2778 0x55aaff00, 0x00c00000, 0x1b55aa00, 0x00000000,
2779 0x0001fff0, 0xcfffff00, 0x00000000, 0x0f0fffff,
2780 0xffffffff, 0xffffffff, 0x30ffff0c, 0xfffff000,
2781 0x00000000, 0x00ffffff, 0xffffffff, 0xfffffff3,
2782 0x0ffff0cf, 0xffff0000, 0x00000000, 0x00ffffff,
2783 0xffffffff, 0xfffffff3, 0x0ffff0cf, 0xffff0000,
2784 0x00000000, 0x0fffffff, 0xffffffff, 0xffffff30,
2785 0xfff70000, 0x000055aa, 0xff000000, 0x000006d5,
2786 0x40000000, 0x00000000, 0x731c0000, 0x000156ab,
2787 0xfc000000, 0x00000000, 0xffff0000, 0x00000000,
2788 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2789 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2790 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2791 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2792 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2793 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2794 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2795 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2796 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2797 0xfe000000, 0x00000000, 0x00100000, 0x00000000,
2798 0xf8000000, 0x00000000, 0x00000000, 0x00000000,
2799 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
2800 0x00ffffff, 0xffffffff, 0x00000000, 0x00000000,
2801 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
2802 },
2803
2804
2805/* rw_wdfet image (Image 16)
2806 *
2807 * ctr0 : Counts total number of writeback transactions.
2808 * ctr1 : Total number of data valid Runway cycles.
2809 * ctr2 : Overflow of Counter 0.
2810 * ctr3 : Overflow of Counter 1.
2811 */
2812
2813 {
2814 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
2815 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
2816 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2817 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2818 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2819 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2820 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2821 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2822 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2823 0x00000000, 0x00000000, 0x00001b00, 0xaa000000,
2824 0x00000001, 0x30700000, 0x00055aaf, 0xf0000000,
2825 0x01b00000, 0x00000000, 0x00001037, 0x00000000,
2826 0x55aaff00, 0x00c00000, 0x1b55aa00, 0x00000000,
2827 0x0001fff0, 0xcfffff00, 0x00000000, 0x0f0fffff,
2828 0xffffffff, 0xffffffff, 0x30ffff0c, 0xfffff000,
2829 0x00000000, 0x00ffffff, 0xffffffff, 0xfffffff3,
2830 0x0ffff0cf, 0xffff0000, 0x00000000, 0x00ffffff,
2831 0xffffffff, 0xfffffff3, 0x0ffff0cf, 0xffff0000,
2832 0x00000000, 0x0fffffff, 0xffffffff, 0xffffff30,
2833 0xfff70000, 0x000055aa, 0xff000000, 0x000006d5,
2834 0x40000000, 0x00000000, 0x731c0000, 0x000156ab,
2835 0xfc000000, 0x00000000, 0xffff0000, 0x00000000,
2836 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2837 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2838 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2839 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2840 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2841 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2842 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2843 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2844 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2845 0xfe000000, 0x00000000, 0x00100000, 0x00000000,
2846 0x98000000, 0x00000000, 0x00000000, 0x00000000,
2847 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
2848 0x00ffffff, 0xffffffff, 0x00000000, 0x00000000,
2849 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
2850 },
2851
2852/* shlib_cpi image (Image 17)
2853 *
2854 * ctr0 : Total number of instructions in quadrant 0.
2855 * ctr1 : Total number of CPU clock cycles in quadrant 0.
2856 * ctr2 : Total number of Non-Nullified instructions retired.
2857 * ctr3 : Total number of CPU clock cycles.
2858 *
2859 * Only works for 32-bit shared libraries.
2860 */
2861
2862 {
2863 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
2864 0xe0e0e0e0, 0x00001fff, 0xfc00007f, 0xfff00001,
2865 0xffffc000, 0x07ffff00, 0x07ffffff, 0x0007ffff,
2866 0xff0007ff, 0xffff0007, 0xffffff00, 0x00000000,
2867 0xf0150000, 0x0fffff00, 0x000fffff, 0xffffffff,
2868 0xffffffff, 0xffff0000, 0x00000000, 0x00ffffff,
2869 0xffcff000, 0x0000000f, 0xfffffffc, 0xffffffff,
2870 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2871 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2872 0x00000000, 0x00000000, 0x27000000, 0x00000055,
2873 0x02000005, 0x7f500000, 0xc0000000, 0x000ff270,
2874 0x00000000, 0x00000000, 0x00007700, 0x00000ff0,
2875 0x00000000, 0x0000ffff, 0xffffffff, 0xffffff00,
2876 0x00000000, 0x0000ff00, 0x00000000, 0x0f0fffff,
2877 0xffffffff, 0xfffff000, 0x00000000, 0x000ff000,
2878 0x00000000, 0x00ffffff, 0xffffffff, 0xffff0000,
2879 0x00000000, 0x00ff0000, 0x00000000, 0xf0ffffff,
2880 0xffffffff, 0xffff0000, 0x00000000, 0x00ff0000,
2881 0x00000000, 0x0fffffff, 0xffffffff, 0xfff00000,
2882 0x00000000, 0x0ff00000, 0x000000a0, 0x3fffffff,
2883 0xffffffff, 0xffc00000, 0x03d40000, 0x20000000,
2884 0x0003fc00, 0x00000000, 0xffff0000, 0x00000000,
2885 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2886 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
2887 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2888 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
2889 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2890 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
2891 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2892 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2893 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2894 0xfe000000, 0x00000000, 0x00030000, 0x00000000,
2895 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2896 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2897 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2898 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2899 },
2900
2901/* flop image (Image 18)
2902 *
2903 * ctr0 : Total number of floating point instructions (opcode = 0xc).
2904 * ctr1 : Total number of floating point instructions (opcode = 0xe, 0x6, 0x2e, 0x26).
2905 * ctr2 : Unused
2906 * ctr3 : Unused
2907 */
2908
2909 {
2910 0x0001e000, 0x00000000, 0x00000000, 0x00000000,
2911 0x00001010, 0x33ffffff, 0x006fffff, 0xfc5fffff,
2912 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2913 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2914 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2915 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2916 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2917 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2918 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2919 0x00000000, 0x00000000, 0xd22d0000, 0x00000000,
2920 0x0000000b, 0x46000000, 0x00000000, 0x0ffff900,
2921 0x90000000, 0x00000000, 0x0000907e, 0x00000000,
2922 0x000000ff, 0xff00bfdf, 0x03030303, 0x03030000,
2923 0x000dbfff, 0xffffff00, 0x00000000, 0x000fffff,
2924 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2925 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2926 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2927 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2928 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2929 0xffff5555, 0x55500000, 0x003f3ff0, 0x2766c000,
2930 0x00000000, 0x00000002, 0x67840000, 0x00000000,
2931 0x03fffc00, 0x00000000, 0xffff0000, 0x00000000,
2932 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2933 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
2934 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2935 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
2936 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2937 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
2938 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2939 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2940 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2941 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
2942 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2943 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2944 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2945 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2946 },
2947
2948/* cachemiss image FROM I_D_MISSES.IDF (Image 19)
2949 *
2950 * ctr0 : icache misses for retired instructions
2951 * ctr1 : total cycles
2952 * ctr2 : dcache misses for retired instructions
2953 * ctr3 : number of retired instructions
2954 */
2955 {
2956 0x2801e000, 0x00000000, 0x00010000, 0x00000000,
2957 0x00001000, 0xffffffff, 0xffffffff, 0xfff00fff,
2958 0xfffa3fff, 0xffffffff, 0xffffffff, 0xffffffff,
2959 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
2960 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2961 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
2962 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2963 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2964 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
2965 0x00000000, 0x00000000, 0xf2fdf0f0, 0xf0f0f0f0,
2966 0xffffffff, 0xf6c00000, 0x00000000, 0x0ff55800,
2967 0x90000000, 0x00000000, 0x0000b0ff, 0xfffffff0,
2968 0x00000003, 0x0100bfff, 0x3f3f3f3f, 0x3f3f5555,
2969 0x555fffff, 0xffffff00, 0x00000000, 0x000fffff,
2970 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
2971 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
2972 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
2973 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
2974 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
2975 0xffffffff, 0xfff00000, 0x000301b0, 0x2fefcfcf,
2976 0xcfcfcfcf, 0xd5555557, 0xf7b40000, 0x00000000,
2977 0x03c14000, 0x00000000, 0xffff0000, 0x00000000,
2978 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
2979 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
2980 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
2981 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
2982 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2983 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
2984 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
2985 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2986 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
2987 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
2988 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2989 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2990 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2991 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2992 },
2993
2994/* branch FROM br_report3.idf
2995 *
2996 * ctr0 : Total number of mispredicted branches.
2997 * ctr1 : Some Non-Nullified unpredictable branches.
2998 * ctr2 : Total number of branches (Nullified + Non-Nullified)
2999 * (Unpredicted+ Predicted Taken +Predicted Not Taken).
3000 * Total of All Branches.
3001 * ctr3 : Remaining Non-Nullified unpredictable branches.
3002 */
3003 {
3004 0x4001e000, 0x00000000, 0x00000000, 0x00000000,
3005 0x00000000, 0xffffffff, 0xff9fffff, 0xfe0fffff,
3006 0xffffbaff, 0xfdffc0ff, 0xfffdffff, 0xfffffeff,
3007 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
3008 0xf4ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3009 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
3010 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3011 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3012 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
3013 0x00000000, 0x00000000, 0xd22d0000, 0x00000000,
3014 0x0000000b, 0x46000000, 0x00000000, 0x0ffff900,
3015 0x90000000, 0x00000000, 0x0000907e, 0x00000000,
3016 0x000000ff, 0xff00bfdf, 0x03030303, 0x03030000,
3017 0x000dbfff, 0xffffff00, 0x00000000, 0x000fffff,
3018 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
3019 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
3020 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
3021 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
3022 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
3023 0xffff5555, 0x55500000, 0x003f3ff0, 0x2766c000,
3024 0x00000000, 0x00000002, 0x67840000, 0x00000000,
3025 0x03fffc00, 0x00000000, 0xffff0000, 0x00000000,
3026 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
3027 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
3028 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
3029 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
3030 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
3031 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
3032 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
3033 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
3034 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
3035 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
3036 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3037 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3038 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3039 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3040 },
3041
3042/* crstack FROM crs_report.idf
3043 *
3044 * ctr0: correctly predicted branches by the pop_latch
3045 * ctr1: some procedure returns
3046 * ctr2: all branches, (includes nullified)
3047 * ctr3: remaining procedure returns
3048 */
3049 {
3050 0x4001e000, 0x00000000, 0x00000000, 0x00000000,
3051 0x00000000, 0xffffffff, 0xffa10300, 0x000fffff,
3052 0xffffbaf8, 0x3000007f, 0xffffffff, 0xfffffeff,
3053 0xff7fffff, 0xffffffff, 0xffffff00, 0x00000000,
3054 0xf2ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3055 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
3056 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3057 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3058 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
3059 0x00000000, 0x00000000, 0xd22d0000, 0x00000000,
3060 0x0000000b, 0x46000000, 0x00000000, 0x0ffff900,
3061 0x90000000, 0x00000000, 0x0000907e, 0x00000000,
3062 0x000000ff, 0xff00bfdf, 0x03030303, 0x03030000,
3063 0x000dbfff, 0xffffff00, 0x00000000, 0x000fffff,
3064 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
3065 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
3066 0xffffffff, 0xffff0000, 0x00000000, 0xf0ffffff,
3067 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
3068 0x00000000, 0x0fffffff, 0xffffffff, 0xffffffff,
3069 0xffff5555, 0x55500000, 0x003f3ff0, 0x2766c000,
3070 0x00000000, 0x00000002, 0x67840000, 0x00000000,
3071 0x03fffc00, 0x00000000, 0xffff0000, 0x00000000,
3072 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
3073 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
3074 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
3075 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
3076 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
3077 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
3078 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
3079 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
3080 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
3081 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
3082 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3083 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3084 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3085 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3086 },
3087
3088/* icache_report image
3089 *
3090 * ctr0 : Icache misses actually used by the core.
3091 * ctr1 : ICORE_AV (Icache misses the core THINKS it needs, including fetching down speculative paths).
3092 * ctr2 : READs on Runway (Icache misses that made it out to Runway, including
3093 * prefetches).
3094 * ctr3 : Prefetch returns (1x and 2x).
3095 */
3096 {
3097 0x00000000, 0x00000000, 0x00010000, 0x00000000,
3098 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
3099 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3100 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
3101 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3102 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
3103 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3104 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3105 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
3106 0x00000000, 0x00000000, 0xd2002d00, 0x00000000,
3107 0x0000000b, 0x46000000, 0x0000000f, 0xf00ff900,
3108 0x00900000, 0x00000000, 0x0000907e, 0x00000000,
3109 0x0000ff00, 0xff83bf03, 0xdf030303, 0x03030000,
3110 0x000dbfff, 0xffffff00, 0x00000000, 0x000fffff,
3111 0xffffffff, 0xffffffff, 0xffffffff, 0xfffff000,
3112 0x00000000, 0x00ffffff, 0xffffffff, 0xffffffff,
3113 0xffffffff, 0xffff0000, 0x00000000, 0x80ffffff,
3114 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000,
3115 0x00000000, 0x4fffffff, 0xffffffff, 0xffffffff,
3116 0xffff5555, 0x55500000, 0x3f003f80, 0x274026c0,
3117 0x00000000, 0x00000002, 0x67840000, 0x00000003,
3118 0xfc03fc00, 0x00000000, 0x0eff0000, 0x00000000,
3119 0x00000000, 0x00000000, 0x00ffffff, 0xff3fffff,
3120 0xffffffff, 0xffcfffff, 0xfff6fb7c, 0x00000000,
3121 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
3122 0xfff6fb7c, 0x00000000, 0xffff0fff, 0xffffff3f,
3123 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
3124 0x00000000, 0x00000000, 0xffff0fff, 0xffffff3f,
3125 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
3126 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
3127 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
3128 0xfe000000, 0x00000000, 0x00130000, 0x00000000,
3129 0xd0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3130 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3131 0x00ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3132 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
3133
3134 }
3135
3136};
3137
3138#endif
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
new file mode 100644
index 000000000000..46e4a6881f11
--- /dev/null
+++ b/arch/parisc/kernel/process.c
@@ -0,0 +1,396 @@
1/*
2 * PARISC Architecture-dependent parts of process handling
3 * based on the work for i386
4 *
5 * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
6 * Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
7 * Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
8 * Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
9 * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
10 * Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
11 * Copyright (C) 2000 David Kennedy <dkennedy with linuxcare.com>
12 * Copyright (C) 2000 Richard Hirst <rhirst with parisc-lixux.org>
13 * Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
14 * Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
15 * Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
16 * Copyright (C) 2001-2002 Helge Deller <deller at parisc-linux.org>
17 * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
18 *
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 */
34
35#include <stdarg.h>
36
37#include <linux/elf.h>
38#include <linux/errno.h>
39#include <linux/kernel.h>
40#include <linux/mm.h>
41#include <linux/module.h>
42#include <linux/personality.h>
43#include <linux/ptrace.h>
44#include <linux/sched.h>
45#include <linux/stddef.h>
46#include <linux/unistd.h>
47#include <linux/kallsyms.h>
48
49#include <asm/io.h>
50#include <asm/offsets.h>
51#include <asm/pdc.h>
52#include <asm/pdc_chassis.h>
53#include <asm/pgalloc.h>
54#include <asm/uaccess.h>
55#include <asm/unwind.h>
56
57static int hlt_counter;
58
59/*
60 * Power off function, if any
61 */
62void (*pm_power_off)(void);
63
64void disable_hlt(void)
65{
66 hlt_counter++;
67}
68
69EXPORT_SYMBOL(disable_hlt);
70
71void enable_hlt(void)
72{
73 hlt_counter--;
74}
75
76EXPORT_SYMBOL(enable_hlt);
77
78void default_idle(void)
79{
80 barrier();
81}
82
83/*
84 * The idle thread. There's no useful work to be
85 * done, so just try to conserve power and have a
86 * low exit latency (ie sit in a loop waiting for
87 * somebody to say that they'd like to reschedule)
88 */
89void cpu_idle(void)
90{
91 /* endless idle loop with no priority at all */
92 while (1) {
93 while (!need_resched())
94 barrier();
95 schedule();
96 check_pgt_cache();
97 }
98}
99
100
101#ifdef __LP64__
102#define COMMAND_GLOBAL 0xfffffffffffe0030UL
103#else
104#define COMMAND_GLOBAL 0xfffe0030
105#endif
106
107#define CMD_RESET 5 /* reset any module */
108
109/*
110** The Wright Brothers and Gecko systems have a H/W problem
111** (Lasi...'nuf said) may cause a broadcast reset to lockup
112** the system. An HVERSION dependent PDC call was developed
113** to perform a "safe", platform specific broadcast reset instead
114** of kludging up all the code.
115**
116** Older machines which do not implement PDC_BROADCAST_RESET will
117** return (with an error) and the regular broadcast reset can be
118** issued. Obviously, if the PDC does implement PDC_BROADCAST_RESET
119** the PDC call will not return (the system will be reset).
120*/
121void machine_restart(char *cmd)
122{
123#ifdef FASTBOOT_SELFTEST_SUPPORT
124 /*
125 ** If user has modified the Firmware Selftest Bitmap,
126 ** run the tests specified in the bitmap after the
127 ** system is rebooted w/PDC_DO_RESET.
128 **
129 ** ftc_bitmap = 0x1AUL "Skip destructive memory tests"
130 **
131 ** Using "directed resets" at each processor with the MEM_TOC
132 ** vector cleared will also avoid running destructive
133 ** memory self tests. (Not implemented yet)
134 */
135 if (ftc_bitmap) {
136 pdc_do_firm_test_reset(ftc_bitmap);
137 }
138#endif
139 /* set up a new led state on systems shipped with a LED State panel */
140 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
141
142 /* "Normal" system reset */
143 pdc_do_reset();
144
145 /* Nope...box should reset with just CMD_RESET now */
146 gsc_writel(CMD_RESET, COMMAND_GLOBAL);
147
148 /* Wait for RESET to lay us to rest. */
149 while (1) ;
150
151}
152
153EXPORT_SYMBOL(machine_restart);
154
155void machine_halt(void)
156{
157 /*
158 ** The LED/ChassisCodes are updated by the led_halt()
159 ** function, called by the reboot notifier chain.
160 */
161}
162
163EXPORT_SYMBOL(machine_halt);
164
165
166/*
167 * This routine is called from sys_reboot to actually turn off the
168 * machine
169 */
170void machine_power_off(void)
171{
172 /* If there is a registered power off handler, call it. */
173 if(pm_power_off)
174 pm_power_off();
175
176 /* Put the soft power button back under hardware control.
177 * If the user had already pressed the power button, the
178 * following call will immediately power off. */
179 pdc_soft_power_button(0);
180
181 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
182
183 /* It seems we have no way to power the system off via
184 * software. The user has to press the button himself. */
185
186 printk(KERN_EMERG "System shut down completed.\n"
187 KERN_EMERG "Please power this system off now.");
188}
189
190EXPORT_SYMBOL(machine_power_off);
191
192
193/*
194 * Create a kernel thread
195 */
196
197extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
198pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
199{
200
201 /*
202 * FIXME: Once we are sure we don't need any debug here,
203 * kernel_thread can become a #define.
204 */
205
206 return __kernel_thread(fn, arg, flags);
207}
208EXPORT_SYMBOL(kernel_thread);
209
210/*
211 * Free current thread data structures etc..
212 */
213void exit_thread(void)
214{
215}
216
217void flush_thread(void)
218{
219 /* Only needs to handle fpu stuff or perf monitors.
220 ** REVISIT: several arches implement a "lazy fpu state".
221 */
222 set_fs(USER_DS);
223}
224
225void release_thread(struct task_struct *dead_task)
226{
227}
228
229/*
230 * Fill in the FPU structure for a core dump.
231 */
232
233int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
234{
235 if (regs == NULL)
236 return 0;
237
238 memcpy(r, regs->fr, sizeof *r);
239 return 1;
240}
241
242int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
243{
244 memcpy(r, tsk->thread.regs.fr, sizeof(*r));
245 return 1;
246}
247
248/* Note that "fork()" is implemented in terms of clone, with
249 parameters (SIGCHLD, regs->gr[30], regs). */
250int
251sys_clone(unsigned long clone_flags, unsigned long usp,
252 struct pt_regs *regs)
253{
254 int __user *user_tid = (int __user *)regs->gr[26];
255
256 /* usp must be word aligned. This also prevents users from
257 * passing in the value 1 (which is the signal for a special
258 * return for a kernel thread) */
259 usp = ALIGN(usp, 4);
260
261 /* A zero value for usp means use the current stack */
262 if(usp == 0)
263 usp = regs->gr[30];
264
265 return do_fork(clone_flags, usp, regs, 0, user_tid, NULL);
266}
267
268int
269sys_vfork(struct pt_regs *regs)
270{
271 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
272}
273
274int
275copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
276 unsigned long unused, /* in ia64 this is "user_stack_size" */
277 struct task_struct * p, struct pt_regs * pregs)
278{
279 struct pt_regs * cregs = &(p->thread.regs);
280 struct thread_info *ti = p->thread_info;
281
282 /* We have to use void * instead of a function pointer, because
283 * function pointers aren't a pointer to the function on 64-bit.
284 * Make them const so the compiler knows they live in .text */
285 extern void * const ret_from_kernel_thread;
286 extern void * const child_return;
287#ifdef CONFIG_HPUX
288 extern void * const hpux_child_return;
289#endif
290
291 *cregs = *pregs;
292
293 /* Set the return value for the child. Note that this is not
294 actually restored by the syscall exit path, but we put it
295 here for consistency in case of signals. */
296 cregs->gr[28] = 0; /* child */
297
298 /*
299 * We need to differentiate between a user fork and a
300 * kernel fork. We can't use user_mode, because the
301 * the syscall path doesn't save iaoq. Right now
302 * We rely on the fact that kernel_thread passes
303 * in zero for usp.
304 */
305 if (usp == 1) {
306 /* kernel thread */
307 cregs->ksp = (((unsigned long)(ti)) + THREAD_SZ_ALGN);
308 /* Must exit via ret_from_kernel_thread in order
309 * to call schedule_tail()
310 */
311 cregs->kpc = (unsigned long) &ret_from_kernel_thread;
312 /*
313 * Copy function and argument to be called from
314 * ret_from_kernel_thread.
315 */
316#ifdef __LP64__
317 cregs->gr[27] = pregs->gr[27];
318#endif
319 cregs->gr[26] = pregs->gr[26];
320 cregs->gr[25] = pregs->gr[25];
321 } else {
322 /* user thread */
323 /*
324 * Note that the fork wrappers are responsible
325 * for setting gr[21].
326 */
327
328 /* Use same stack depth as parent */
329 cregs->ksp = ((unsigned long)(ti))
330 + (pregs->gr[21] & (THREAD_SIZE - 1));
331 cregs->gr[30] = usp;
332 if (p->personality == PER_HPUX) {
333#ifdef CONFIG_HPUX
334 cregs->kpc = (unsigned long) &hpux_child_return;
335#else
336 BUG();
337#endif
338 } else {
339 cregs->kpc = (unsigned long) &child_return;
340 }
341 }
342
343 return 0;
344}
345
346unsigned long thread_saved_pc(struct task_struct *t)
347{
348 return t->thread.regs.kpc;
349}
350
351/*
352 * sys_execve() executes a new program.
353 */
354
355asmlinkage int sys_execve(struct pt_regs *regs)
356{
357 int error;
358 char *filename;
359
360 filename = getname((const char __user *) regs->gr[26]);
361 error = PTR_ERR(filename);
362 if (IS_ERR(filename))
363 goto out;
364 error = do_execve(filename, (char __user **) regs->gr[25],
365 (char __user **) regs->gr[24], regs);
366 if (error == 0) {
367 task_lock(current);
368 current->ptrace &= ~PT_DTRACE;
369 task_unlock(current);
370 }
371 putname(filename);
372out:
373
374 return error;
375}
376
377unsigned long
378get_wchan(struct task_struct *p)
379{
380 struct unwind_frame_info info;
381 unsigned long ip;
382 int count = 0;
383 /*
384 * These bracket the sleeping functions..
385 */
386
387 unwind_frame_init_from_blocked_task(&info, p);
388 do {
389 if (unwind_once(&info) < 0)
390 return 0;
391 ip = info.ip;
392 if (!in_sched_functions(ip))
393 return ip;
394 } while (count++ < 16);
395 return 0;
396}
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
new file mode 100644
index 000000000000..13b721cb9f55
--- /dev/null
+++ b/arch/parisc/kernel/processor.c
@@ -0,0 +1,400 @@
1/* $Id: processor.c,v 1.1 2002/07/20 16:27:06 rhirst Exp $
2 *
3 * Initial setup-routines for HP 9000 based hardware.
4 *
5 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
6 * Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de>
7 * Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
8 * Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
9 * Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
10 * Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
11 *
12 * Initial PA-RISC Version: 04-23-1999 by Helge Deller
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29#include <linux/config.h>
30#include <linux/delay.h>
31#include <linux/init.h>
32#include <linux/mm.h>
33#include <linux/module.h>
34#include <linux/seq_file.h>
35#include <linux/slab.h>
36#include <linux/cpu.h>
37
38#include <asm/cache.h>
39#include <asm/hardware.h> /* for register_parisc_driver() stuff */
40#include <asm/processor.h>
41#include <asm/page.h>
42#include <asm/pdc.h>
43#include <asm/pdcpat.h>
44#include <asm/irq.h> /* for struct irq_region */
45#include <asm/parisc-device.h>
46
47struct system_cpuinfo_parisc boot_cpu_data;
48EXPORT_SYMBOL(boot_cpu_data);
49
50struct cpuinfo_parisc cpu_data[NR_CPUS];
51
52/*
53** PARISC CPU driver - claim "device" and initialize CPU data structures.
54**
55** Consolidate per CPU initialization into (mostly) one module.
56** Monarch CPU will initialize boot_cpu_data which shouldn't
57** change once the system has booted.
58**
59** The callback *should* do per-instance initialization of
60** everything including the monarch. "Per CPU" init code in
61** setup.c:start_parisc() has migrated here and start_parisc()
62** will call register_parisc_driver(&cpu_driver) before calling do_inventory().
63**
64** The goal of consolidating CPU initialization into one place is
65** to make sure all CPU's get initialized the same way.
66** The code path not shared is how PDC hands control of the CPU to the OS.
67** The initialization of OS data structures is the same (done below).
68*/
69
70/**
71 * processor_probe - Determine if processor driver should claim this device.
72 * @dev: The device which has been found.
73 *
74 * Determine if processor driver should claim this chip (return 0) or not
75 * (return 1). If so, initialize the chip and tell other partners in crime
76 * they have work to do.
77 */
78static int __init processor_probe(struct parisc_device *dev)
79{
80 unsigned long txn_addr;
81 unsigned long cpuid;
82 struct cpuinfo_parisc *p;
83
84#ifndef CONFIG_SMP
85 if (boot_cpu_data.cpu_count > 0) {
86 printk(KERN_INFO "CONFIG_SMP=n ignoring additional CPUs\n");
87 return 1;
88 }
89#endif
90
91 /* logical CPU ID and update global counter
92 * May get overwritten by PAT code.
93 */
94 cpuid = boot_cpu_data.cpu_count;
95 txn_addr = dev->hpa; /* for legacy PDC */
96
97#ifdef __LP64__
98 if (is_pdc_pat()) {
99 ulong status;
100 unsigned long bytecnt;
101 pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
102#undef USE_PAT_CPUID
103#ifdef USE_PAT_CPUID
104 struct pdc_pat_cpu_num cpu_info;
105#endif
106
107 status = pdc_pat_cell_module(&bytecnt, dev->pcell_loc,
108 dev->mod_index, PA_VIEW, &pa_pdc_cell);
109
110 BUG_ON(PDC_OK != status);
111
112 /* verify it's the same as what do_pat_inventory() found */
113 BUG_ON(dev->mod_info != pa_pdc_cell.mod_info);
114 BUG_ON(dev->pmod_loc != pa_pdc_cell.mod_location);
115
116 txn_addr = pa_pdc_cell.mod[0]; /* id_eid for IO sapic */
117
118#ifdef USE_PAT_CPUID
119/* We need contiguous numbers for cpuid. Firmware's notion
120 * of cpuid is for physical CPUs and we just don't care yet.
121 * We'll care when we need to query PAT PDC about a CPU *after*
122 * boot time (ie shutdown a CPU from an OS perspective).
123 */
124 /* get the cpu number */
125 status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa);
126
127 BUG_ON(PDC_OK != status);
128
129 if (cpu_info.cpu_num >= NR_CPUS) {
130 printk(KERN_WARNING "IGNORING CPU at 0x%x,"
131 " cpu_slot_id > NR_CPUS"
132 " (%ld > %d)\n",
133 dev->hpa, cpu_info.cpu_num, NR_CPUS);
134 /* Ignore CPU since it will only crash */
135 boot_cpu_data.cpu_count--;
136 return 1;
137 } else {
138 cpuid = cpu_info.cpu_num;
139 }
140#endif
141 }
142#endif
143
144 p = &cpu_data[cpuid];
145 boot_cpu_data.cpu_count++;
146
147 /* initialize counters */
148 memset(p, 0, sizeof(struct cpuinfo_parisc));
149
150 p->loops_per_jiffy = loops_per_jiffy;
151 p->dev = dev; /* Save IODC data in case we need it */
152 p->hpa = dev->hpa; /* save CPU hpa */
153 p->cpuid = cpuid; /* save CPU id */
154 p->txn_addr = txn_addr; /* save CPU IRQ address */
155#ifdef CONFIG_SMP
156 spin_lock_init(&p->lock);
157
158 /*
159 ** FIXME: review if any other initialization is clobbered
160 ** for boot_cpu by the above memset().
161 */
162
163 /* stolen from init_percpu_prof() */
164 cpu_data[cpuid].prof_counter = 1;
165 cpu_data[cpuid].prof_multiplier = 1;
166#endif
167
168 /*
169 ** CONFIG_SMP: init_smp_config() will attempt to get CPU's into
170 ** OS control. RENDEZVOUS is the default state - see mem_set above.
171 ** p->state = STATE_RENDEZVOUS;
172 */
173
174#if 0
175 /* CPU 0 IRQ table is statically allocated/initialized */
176 if (cpuid) {
177 struct irqaction actions[];
178
179 /*
180 ** itimer and ipi IRQ handlers are statically initialized in
181 ** arch/parisc/kernel/irq.c. ie Don't need to register them.
182 */
183 actions = kmalloc(sizeof(struct irqaction)*MAX_CPU_IRQ, GFP_ATOMIC);
184 if (!actions) {
185 /* not getting it's own table, share with monarch */
186 actions = cpu_irq_actions[0];
187 }
188
189 cpu_irq_actions[cpuid] = actions;
190 }
191#endif
192
193 /*
194 * Bring this CPU up now! (ignore bootstrap cpuid == 0)
195 */
196#ifdef CONFIG_SMP
197 if (cpuid) {
198 cpu_set(cpuid, cpu_present_map);
199 cpu_up(cpuid);
200 }
201#endif
202
203 return 0;
204}
205
206/**
207 * collect_boot_cpu_data - Fill the boot_cpu_data structure.
208 *
209 * This function collects and stores the generic processor information
210 * in the boot_cpu_data structure.
211 */
212void __init collect_boot_cpu_data(void)
213{
214 memset(&boot_cpu_data, 0, sizeof(boot_cpu_data));
215
216 boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */
217
218 /* get CPU-Model Information... */
219#define p ((unsigned long *)&boot_cpu_data.pdc.model)
220 if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK)
221 printk(KERN_INFO
222 "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
223 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
224#undef p
225
226 if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK)
227 printk(KERN_INFO "vers %08lx\n",
228 boot_cpu_data.pdc.versions);
229
230 if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK)
231 printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n",
232 (boot_cpu_data.pdc.cpuid >> 5) & 127,
233 boot_cpu_data.pdc.cpuid & 31,
234 boot_cpu_data.pdc.cpuid);
235
236 if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK)
237 printk(KERN_INFO "capabilities 0x%lx\n",
238 boot_cpu_data.pdc.capabilities);
239
240 if (pdc_model_sysmodel(boot_cpu_data.pdc.sys_model_name) == PDC_OK)
241 printk(KERN_INFO "model %s\n",
242 boot_cpu_data.pdc.sys_model_name);
243
244 boot_cpu_data.hversion = boot_cpu_data.pdc.model.hversion;
245 boot_cpu_data.sversion = boot_cpu_data.pdc.model.sversion;
246
247 boot_cpu_data.cpu_type = parisc_get_cpu_type(boot_cpu_data.hversion);
248 boot_cpu_data.cpu_name = cpu_name_version[boot_cpu_data.cpu_type][0];
249 boot_cpu_data.family_name = cpu_name_version[boot_cpu_data.cpu_type][1];
250}
251
252
253/**
254 * init_cpu_profiler - enable/setup per cpu profiling hooks.
255 * @cpunum: The processor instance.
256 *
257 * FIXME: doesn't do much yet...
258 */
259static inline void __init
260init_percpu_prof(int cpunum)
261{
262 cpu_data[cpunum].prof_counter = 1;
263 cpu_data[cpunum].prof_multiplier = 1;
264}
265
266
267/**
268 * init_per_cpu - Handle individual processor initializations.
269 * @cpunum: logical processor number.
270 *
271 * This function handles initialization for *every* CPU
272 * in the system:
273 *
274 * o Set "default" CPU width for trap handlers
275 *
276 * o Enable FP coprocessor
277 * REVISIT: this could be done in the "code 22" trap handler.
278 * (frowands idea - that way we know which processes need FP
279 * registers saved on the interrupt stack.)
280 * NEWS FLASH: wide kernels need FP coprocessor enabled to handle
281 * formatted printing of %lx for example (double divides I think)
282 *
283 * o Enable CPU profiling hooks.
284 */
285int __init init_per_cpu(int cpunum)
286{
287 int ret;
288 struct pdc_coproc_cfg coproc_cfg;
289
290 set_firmware_width();
291 ret = pdc_coproc_cfg(&coproc_cfg);
292
293 if(ret >= 0 && coproc_cfg.ccr_functional) {
294 mtctl(coproc_cfg.ccr_functional, 10); /* 10 == Coprocessor Control Reg */
295
296 /* FWIW, FP rev/model is a more accurate way to determine
297 ** CPU type. CPU rev/model has some ambiguous cases.
298 */
299 cpu_data[cpunum].fp_rev = coproc_cfg.revision;
300 cpu_data[cpunum].fp_model = coproc_cfg.model;
301
302 printk(KERN_INFO "FP[%d] enabled: Rev %ld Model %ld\n",
303 cpunum, coproc_cfg.revision, coproc_cfg.model);
304
305 /*
306 ** store status register to stack (hopefully aligned)
307 ** and clear the T-bit.
308 */
309 asm volatile ("fstd %fr0,8(%sp)");
310
311 } else {
312 printk(KERN_WARNING "WARNING: No FP CoProcessor?!"
313 " (coproc_cfg.ccr_functional == 0x%lx, expected 0xc0)\n"
314#ifdef __LP64__
315 "Halting Machine - FP required\n"
316#endif
317 , coproc_cfg.ccr_functional);
318#ifdef __LP64__
319 mdelay(100); /* previous chars get pushed to console */
320 panic("FP CoProc not reported");
321#endif
322 }
323
324 /* FUTURE: Enable Performance Monitor : ccr bit 0x20 */
325 init_percpu_prof(cpunum);
326
327 return ret;
328}
329
330/*
331 * Display cpu info for all cpu's.
332 */
333int
334show_cpuinfo (struct seq_file *m, void *v)
335{
336 int n;
337
338 for(n=0; n<boot_cpu_data.cpu_count; n++) {
339#ifdef CONFIG_SMP
340 if (0 == cpu_data[n].hpa)
341 continue;
342#ifdef ENTRY_SYS_CPUS
343#error iCOD support wants to show CPU state here
344#endif
345#endif
346 seq_printf(m, "processor\t: %d\n"
347 "cpu family\t: PA-RISC %s\n",
348 n, boot_cpu_data.family_name);
349
350 seq_printf(m, "cpu\t\t: %s\n", boot_cpu_data.cpu_name );
351
352 /* cpu MHz */
353 seq_printf(m, "cpu MHz\t\t: %d.%06d\n",
354 boot_cpu_data.cpu_hz / 1000000,
355 boot_cpu_data.cpu_hz % 1000000 );
356
357 seq_printf(m, "model\t\t: %s\n"
358 "model name\t: %s\n",
359 boot_cpu_data.pdc.sys_model_name,
360 cpu_data[n].dev ?
361 cpu_data[n].dev->name : "Unknown" );
362
363 seq_printf(m, "hversion\t: 0x%08x\n"
364 "sversion\t: 0x%08x\n",
365 boot_cpu_data.hversion,
366 boot_cpu_data.sversion );
367
368 /* print cachesize info */
369 show_cache_info(m);
370
371 seq_printf(m, "bogomips\t: %lu.%02lu\n",
372 cpu_data[n].loops_per_jiffy / (500000 / HZ),
373 (cpu_data[n].loops_per_jiffy / (5000 / HZ)) % 100);
374
375 seq_printf(m, "software id\t: %ld\n\n",
376 boot_cpu_data.pdc.model.sw_id);
377 }
378 return 0;
379}
380
381static struct parisc_device_id processor_tbl[] = {
382 { HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID },
383 { 0, }
384};
385
386static struct parisc_driver cpu_driver = {
387 .name = "CPU",
388 .id_table = processor_tbl,
389 .probe = processor_probe
390};
391
392/**
393 * processor_init - Processor initalization procedure.
394 *
395 * Register this driver.
396 */
397void __init processor_init(void)
398{
399 register_parisc_driver(&cpu_driver);
400}
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
new file mode 100644
index 000000000000..2937a9236384
--- /dev/null
+++ b/arch/parisc/kernel/ptrace.c
@@ -0,0 +1,423 @@
1/*
2 * Kernel support for the ptrace() and syscall tracing interfaces.
3 *
4 * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
5 * Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
6 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
7 */
8
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/smp_lock.h>
14#include <linux/errno.h>
15#include <linux/ptrace.h>
16#include <linux/user.h>
17#include <linux/personality.h>
18#include <linux/security.h>
19#include <linux/compat.h>
20
21#include <asm/uaccess.h>
22#include <asm/pgtable.h>
23#include <asm/system.h>
24#include <asm/processor.h>
25#include <asm/offsets.h>
26
27/* PSW bits we allow the debugger to modify */
28#define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB)
29
30#undef DEBUG_PTRACE
31
32#ifdef DEBUG_PTRACE
33#define DBG(x...) printk(x)
34#else
35#define DBG(x...)
36#endif
37
38#ifdef __LP64__
39
40/* This function is needed to translate 32 bit pt_regs offsets in to
41 * 64 bit pt_regs offsets. For example, a 32 bit gdb under a 64 bit kernel
42 * will request offset 12 if it wants gr3, but the lower 32 bits of
43 * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
44 * This code relies on a 32 bit pt_regs being comprised of 32 bit values
45 * except for the fp registers which (a) are 64 bits, and (b) follow
46 * the gr registers at the start of pt_regs. The 32 bit pt_regs should
47 * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
48 * being 64 bit in both cases.
49 */
50
51static long translate_usr_offset(long offset)
52{
53 if (offset < 0)
54 return -1;
55 else if (offset <= 32*4) /* gr[0..31] */
56 return offset * 2 + 4;
57 else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */
58 return offset + 32*4;
59 else if (offset < sizeof(struct pt_regs)/2 + 32*4)
60 return offset * 2 + 4 - 32*8;
61 else
62 return -1;
63}
64#endif
65
66/*
67 * Called by kernel/ptrace.c when detaching..
68 *
69 * Make sure single step bits etc are not set.
70 */
71void ptrace_disable(struct task_struct *child)
72{
73 /* make sure the trap bits are not set */
74 pa_psw(child)->r = 0;
75 pa_psw(child)->t = 0;
76 pa_psw(child)->h = 0;
77 pa_psw(child)->l = 0;
78}
79
80long sys_ptrace(long request, pid_t pid, long addr, long data)
81{
82 struct task_struct *child;
83 long ret;
84#ifdef DEBUG_PTRACE
85 long oaddr=addr, odata=data;
86#endif
87
88 lock_kernel();
89 ret = -EPERM;
90 if (request == PTRACE_TRACEME) {
91 /* are we already being traced? */
92 if (current->ptrace & PT_PTRACED)
93 goto out;
94
95 ret = security_ptrace(current->parent, current);
96 if (ret)
97 goto out;
98
99 /* set the ptrace bit in the process flags. */
100 current->ptrace |= PT_PTRACED;
101 ret = 0;
102 goto out;
103 }
104
105 ret = -ESRCH;
106 read_lock(&tasklist_lock);
107 child = find_task_by_pid(pid);
108 if (child)
109 get_task_struct(child);
110 read_unlock(&tasklist_lock);
111 if (!child)
112 goto out;
113 ret = -EPERM;
114 if (pid == 1) /* no messing around with init! */
115 goto out_tsk;
116
117 if (request == PTRACE_ATTACH) {
118 ret = ptrace_attach(child);
119 goto out_tsk;
120 }
121
122 ret = ptrace_check_attach(child, request == PTRACE_KILL);
123 if (ret < 0)
124 goto out_tsk;
125
126 switch (request) {
127 case PTRACE_PEEKTEXT: /* read word at location addr. */
128 case PTRACE_PEEKDATA: {
129 int copied;
130
131#ifdef __LP64__
132 if (is_compat_task(child)) {
133 unsigned int tmp;
134
135 addr &= 0xffffffffL;
136 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
137 ret = -EIO;
138 if (copied != sizeof(tmp))
139 goto out_tsk;
140 ret = put_user(tmp,(unsigned int *) data);
141 DBG("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
142 request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
143 pid, oaddr, odata, ret, tmp);
144 }
145 else
146#endif
147 {
148 unsigned long tmp;
149
150 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
151 ret = -EIO;
152 if (copied != sizeof(tmp))
153 goto out_tsk;
154 ret = put_user(tmp,(unsigned long *) data);
155 }
156 goto out_tsk;
157 }
158
159 /* when I and D space are separate, this will have to be fixed. */
160 case PTRACE_POKETEXT: /* write the word at location addr. */
161 case PTRACE_POKEDATA:
162 ret = 0;
163#ifdef __LP64__
164 if (is_compat_task(child)) {
165 unsigned int tmp = (unsigned int)data;
166 DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
167 request == PTRACE_POKETEXT ? "TEXT" : "DATA",
168 pid, oaddr, odata);
169 addr &= 0xffffffffL;
170 if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
171 goto out_tsk;
172 }
173 else
174#endif
175 {
176 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
177 goto out_tsk;
178 }
179 ret = -EIO;
180 goto out_tsk;
181
182 /* Read the word at location addr in the USER area. For ptraced
183 processes, the kernel saves all regs on a syscall. */
184 case PTRACE_PEEKUSR: {
185 ret = -EIO;
186#ifdef __LP64__
187 if (is_compat_task(child)) {
188 unsigned int tmp;
189
190 if (addr & (sizeof(int)-1))
191 goto out_tsk;
192 if ((addr = translate_usr_offset(addr)) < 0)
193 goto out_tsk;
194
195 tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
196 ret = put_user(tmp, (unsigned int *) data);
197 DBG("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
198 pid, oaddr, odata, ret, addr, tmp);
199 }
200 else
201#endif
202 {
203 unsigned long tmp;
204
205 if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
206 goto out_tsk;
207 tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
208 ret = put_user(tmp, (unsigned long *) data);
209 }
210 goto out_tsk;
211 }
212
213 /* Write the word at location addr in the USER area. This will need
214 to change when the kernel no longer saves all regs on a syscall.
215 FIXME. There is a problem at the moment in that r3-r18 are only
216 saved if the process is ptraced on syscall entry, and even then
217 those values are overwritten by actual register values on syscall
218 exit. */
219 case PTRACE_POKEUSR:
220 ret = -EIO;
221 /* Some register values written here may be ignored in
222 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
223 * r31/r31+4, and not with the values in pt_regs.
224 */
225 /* PT_PSW=0, so this is valid for 32 bit processes under 64
226 * bit kernels.
227 */
228 if (addr == PT_PSW) {
229 /* PT_PSW=0, so this is valid for 32 bit processes
230 * under 64 bit kernels.
231 *
232 * Allow writing to Nullify, Divide-step-correction,
233 * and carry/borrow bits.
234 * BEWARE, if you set N, and then single step, it won't
235 * stop on the nullified instruction.
236 */
237 DBG("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
238 pid, oaddr, odata);
239 data &= USER_PSW_BITS;
240 task_regs(child)->gr[0] &= ~USER_PSW_BITS;
241 task_regs(child)->gr[0] |= data;
242 ret = 0;
243 goto out_tsk;
244 }
245#ifdef __LP64__
246 if (is_compat_task(child)) {
247 if (addr & (sizeof(int)-1))
248 goto out_tsk;
249 if ((addr = translate_usr_offset(addr)) < 0)
250 goto out_tsk;
251 DBG("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
252 pid, oaddr, odata, addr);
253 if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
254 /* Special case, fp regs are 64 bits anyway */
255 *(unsigned int *) ((char *) task_regs(child) + addr) = data;
256 ret = 0;
257 }
258 else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
259 addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
260 addr == PT_SAR+4) {
261 /* Zero the top 32 bits */
262 *(unsigned int *) ((char *) task_regs(child) + addr - 4) = 0;
263 *(unsigned int *) ((char *) task_regs(child) + addr) = data;
264 ret = 0;
265 }
266 goto out_tsk;
267 }
268 else
269#endif
270 {
271 if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
272 goto out_tsk;
273 if ((addr >= PT_GR1 && addr <= PT_GR31) ||
274 addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
275 (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
276 addr == PT_SAR) {
277 *(unsigned long *) ((char *) task_regs(child) + addr) = data;
278 ret = 0;
279 }
280 goto out_tsk;
281 }
282
283 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
284 case PTRACE_CONT:
285 ret = -EIO;
286 DBG("sys_ptrace(%s)\n",
287 request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
288 if ((unsigned long) data > _NSIG)
289 goto out_tsk;
290 child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
291 if (request == PTRACE_SYSCALL) {
292 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
293 } else {
294 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
295 }
296 child->exit_code = data;
297 goto out_wake_notrap;
298
299 case PTRACE_KILL:
300 /*
301 * make the child exit. Best I can do is send it a
302 * sigkill. perhaps it should be put in the status
303 * that it wants to exit.
304 */
305 DBG("sys_ptrace(KILL)\n");
306 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
307 goto out_tsk;
308 child->exit_code = SIGKILL;
309 goto out_wake_notrap;
310
311 case PTRACE_SINGLEBLOCK:
312 DBG("sys_ptrace(SINGLEBLOCK)\n");
313 ret = -EIO;
314 if ((unsigned long) data > _NSIG)
315 goto out_tsk;
316 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
317 child->ptrace &= ~PT_SINGLESTEP;
318 child->ptrace |= PT_BLOCKSTEP;
319 child->exit_code = data;
320
321 /* Enable taken branch trap. */
322 pa_psw(child)->r = 0;
323 pa_psw(child)->t = 1;
324 pa_psw(child)->h = 0;
325 pa_psw(child)->l = 0;
326 goto out_wake;
327
328 case PTRACE_SINGLESTEP:
329 DBG("sys_ptrace(SINGLESTEP)\n");
330 ret = -EIO;
331 if ((unsigned long) data > _NSIG)
332 goto out_tsk;
333
334 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
335 child->ptrace &= ~PT_BLOCKSTEP;
336 child->ptrace |= PT_SINGLESTEP;
337 child->exit_code = data;
338
339 if (pa_psw(child)->n) {
340 struct siginfo si;
341
342 /* Nullified, just crank over the queue. */
343 task_regs(child)->iaoq[0] = task_regs(child)->iaoq[1];
344 task_regs(child)->iasq[0] = task_regs(child)->iasq[1];
345 task_regs(child)->iaoq[1] = task_regs(child)->iaoq[0] + 4;
346 pa_psw(child)->n = 0;
347 pa_psw(child)->x = 0;
348 pa_psw(child)->y = 0;
349 pa_psw(child)->z = 0;
350 pa_psw(child)->b = 0;
351 ptrace_disable(child);
352 /* Don't wake up the child, but let the
353 parent know something happened. */
354 si.si_code = TRAP_TRACE;
355 si.si_addr = (void __user *) (task_regs(child)->iaoq[0] & ~3);
356 si.si_signo = SIGTRAP;
357 si.si_errno = 0;
358 force_sig_info(SIGTRAP, &si, child);
359 //notify_parent(child, SIGCHLD);
360 //ret = 0;
361 goto out_wake;
362 }
363
364 /* Enable recovery counter traps. The recovery counter
365 * itself will be set to zero on a task switch. If the
366 * task is suspended on a syscall then the syscall return
367 * path will overwrite the recovery counter with a suitable
368 * value such that it traps once back in user space. We
369 * disable interrupts in the childs PSW here also, to avoid
370 * interrupts while the recovery counter is decrementing.
371 */
372 pa_psw(child)->r = 1;
373 pa_psw(child)->t = 0;
374 pa_psw(child)->h = 0;
375 pa_psw(child)->l = 0;
376 /* give it a chance to run. */
377 goto out_wake;
378
379 case PTRACE_DETACH:
380 ret = ptrace_detach(child, data);
381 goto out_tsk;
382
383 case PTRACE_GETEVENTMSG:
384 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
385 goto out_tsk;
386
387 default:
388 ret = ptrace_request(child, request, addr, data);
389 goto out_tsk;
390 }
391
392out_wake_notrap:
393 ptrace_disable(child);
394out_wake:
395 wake_up_process(child);
396 ret = 0;
397out_tsk:
398 put_task_struct(child);
399out:
400 unlock_kernel();
401 DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
402 request, pid, oaddr, odata, ret);
403 return ret;
404}
405
406void syscall_trace(void)
407{
408 if (!test_thread_flag(TIF_SYSCALL_TRACE))
409 return;
410 if (!(current->ptrace & PT_PTRACED))
411 return;
412 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
413 ? 0x80 : 0));
414 /*
415 * this isn't the same as continuing with a signal, but it will do
416 * for normal use. strace only continues with a signal if the
417 * stopping signal is not SIGTRAP. -brl
418 */
419 if (current->exit_code) {
420 send_sig(current->exit_code, current, 1);
421 current->exit_code = 0;
422 }
423}
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
new file mode 100644
index 000000000000..8dd5defb7316
--- /dev/null
+++ b/arch/parisc/kernel/real2.S
@@ -0,0 +1,304 @@
1/*
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
8 *
9 */
10#include <asm/assembly.h>
11#include <asm/psw.h>
12
13 .section .bss
14 .export real_stack
15 .export real32_stack
16 .export real64_stack
17 .align 64
18real_stack:
19real32_stack:
20real64_stack:
21 .block 8192
22
23#ifdef __LP64__
24# define REG_SZ 8
25#else
26# define REG_SZ 4
27#endif
28
29#define N_SAVED_REGS 9
30
31save_cr_space:
32 .block REG_SZ * N_SAVED_REGS
33save_cr_end:
34
35
36/************************ 32-bit real-mode calls ***********************/
37/* This can be called in both narrow and wide kernels */
38
39 .text
40
41 .export real32_call_asm
42
43 /* unsigned long real32_call_asm(unsigned int *sp,
44 * unsigned int *arg0p,
45 * unsigned int iodc_fn)
46 * sp is value of stack pointer to adopt before calling PDC (virt)
47 * arg0p points to where saved arg values may be found
48 * iodc_fn is the IODC function to call
49 */
50
51real32_call_asm:
52 STREG %rp, -RP_OFFSET(%sp) /* save RP */
53#ifdef __LP64__
54 callee_save
55 ldo 2*REG_SZ(%sp), %sp /* room for a couple more saves */
56 STREG %r27, -1*REG_SZ(%sp)
57 STREG %r29, -2*REG_SZ(%sp)
58#endif
59 STREG %sp, -REG_SZ(%arg0) /* save SP on real-mode stack */
60 copy %arg0, %sp /* adopt the real-mode SP */
61
62 /* save iodc_fn */
63 copy %arg2, %r31
64
65 /* load up the arg registers from the saved arg area */
66 /* 32-bit calling convention passes first 4 args in registers */
67 ldw 0(%arg1), %arg0 /* note overwriting arg0 */
68 ldw -8(%arg1), %arg2
69 ldw -12(%arg1), %arg3
70 ldw -4(%arg1), %arg1 /* obviously must do this one last! */
71
72 tophys_r1 %sp
73
74 b,l rfi_virt2real,%r2
75 nop
76
77 b,l save_control_regs,%r2 /* modifies r1, r2, r28 */
78 nop
79
80#ifdef __LP64__
81 rsm PSW_SM_W, %r0 /* go narrow */
82#endif
83
84 load32 PA(ric_ret), %r2
85 bv 0(%r31)
86 nop
87ric_ret:
88#ifdef __LP64__
89 ssm PSW_SM_W, %r0 /* go wide */
90#endif
91 /* restore CRs before going virtual in case we page fault */
92 b,l restore_control_regs, %r2 /* modifies r1, r2, r26 */
93 nop
94
95 b,l rfi_real2virt,%r2
96 nop
97
98 tovirt_r1 %sp
99 LDREG -REG_SZ(%sp), %sp /* restore SP */
100#ifdef __LP64__
101 LDREG -1*REG_SZ(%sp), %r27
102 LDREG -2*REG_SZ(%sp), %r29
103 ldo -2*REG_SZ(%sp), %sp
104 callee_rest
105#endif
106 LDREG -RP_OFFSET(%sp), %rp /* restore RP */
107 bv 0(%rp)
108 nop
109
110
111# define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where)
112# define POP_CR(r, where) LDREG,mb -REG_SZ(where), %r1 ! mtctl %r1, r
113
114 .text
115save_control_regs:
116 load32 PA(save_cr_space), %r28
117 PUSH_CR(%cr24, %r28)
118 PUSH_CR(%cr25, %r28)
119 PUSH_CR(%cr26, %r28)
120 PUSH_CR(%cr27, %r28)
121 PUSH_CR(%cr28, %r28)
122 PUSH_CR(%cr29, %r28)
123 PUSH_CR(%cr30, %r28)
124 PUSH_CR(%cr31, %r28)
125 PUSH_CR(%cr15, %r28)
126 bv 0(%r2)
127 nop
128
129restore_control_regs:
130 load32 PA(save_cr_end), %r26
131 POP_CR(%cr15, %r26)
132 POP_CR(%cr31, %r26)
133 POP_CR(%cr30, %r26)
134 POP_CR(%cr29, %r26)
135 POP_CR(%cr28, %r26)
136 POP_CR(%cr27, %r26)
137 POP_CR(%cr26, %r26)
138 POP_CR(%cr25, %r26)
139 POP_CR(%cr24, %r26)
140 bv 0(%r2)
141 nop
142
143/* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for
144 * more general-purpose use by the several places which need RFIs
145 */
146 .align 128
147 .text
148rfi_virt2real:
149 /* switch to real mode... */
150 ssm 0,0 /* See "relied upon translation" */
151 nop /* PA 2.0 Arch. F-5 */
152 nop
153 nop
154 nop
155 nop
156 nop
157 nop
158 nop
159
160 rsm (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q & I bits to load iia queue */
161 mtctl %r0, %cr17 /* Clear IIASQ tail */
162 mtctl %r0, %cr17 /* Clear IIASQ head */
163 load32 PA(rfi_v2r_1), %r1
164 mtctl %r1, %cr18 /* IIAOQ head */
165 ldo 4(%r1), %r1
166 mtctl %r1, %cr18 /* IIAOQ tail */
167 load32 REAL_MODE_PSW, %r1
168 mtctl %r1, %cr22
169 rfi
170
171 nop
172 nop
173 nop
174 nop
175 nop
176 nop
177 nop
178 nop
179rfi_v2r_1:
180 tophys_r1 %r2
181 bv 0(%r2)
182 nop
183
184 .text
185 .align 128
186rfi_real2virt:
187 ssm 0,0 /* See "relied upon translation" */
188 nop /* PA 2.0 Arch. F-5 */
189 nop
190 nop
191 nop
192 nop
193 nop
194 nop
195 nop
196
197 rsm PSW_SM_Q,%r0 /* disable Q bit to load iia queue */
198 mtctl %r0, %cr17 /* Clear IIASQ tail */
199 mtctl %r0, %cr17 /* Clear IIASQ head */
200 load32 (rfi_r2v_1), %r1
201 mtctl %r1, %cr18 /* IIAOQ head */
202 ldo 4(%r1), %r1
203 mtctl %r1, %cr18 /* IIAOQ tail */
204 load32 KERNEL_PSW, %r1
205 mtctl %r1, %cr22
206 rfi
207
208 nop
209 nop
210 nop
211 nop
212 nop
213 nop
214 nop
215 nop
216rfi_r2v_1:
217 tovirt_r1 %r2
218 bv 0(%r2)
219 nop
220
221#ifdef __LP64__
222
223/************************ 64-bit real-mode calls ***********************/
224/* This is only usable in wide kernels right now and will probably stay so */
225 .text
226 .export real64_call_asm
227 /* unsigned long real64_call_asm(unsigned long *sp,
228 * unsigned long *arg0p,
229 * unsigned long fn)
230 * sp is value of stack pointer to adopt before calling PDC (virt)
231 * arg0p points to where saved arg values may be found
232 * iodc_fn is the IODC function to call
233 */
234real64_call_asm:
235 std %rp, -0x10(%sp) /* save RP */
236 std %sp, -8(%arg0) /* save SP on real-mode stack */
237 copy %arg0, %sp /* adopt the real-mode SP */
238
239 /* save fn */
240 copy %arg2, %r31
241
242 /* set up the new ap */
243 ldo 64(%arg1), %r29
244
245 /* load up the arg registers from the saved arg area */
246 /* 32-bit calling convention passes first 4 args in registers */
247 ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */
248 ldd 2*REG_SZ(%arg1), %arg2
249 ldd 3*REG_SZ(%arg1), %arg3
250 ldd 4*REG_SZ(%arg1), %r22
251 ldd 5*REG_SZ(%arg1), %r21
252 ldd 6*REG_SZ(%arg1), %r20
253 ldd 7*REG_SZ(%arg1), %r19
254 ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */
255
256 tophys_r1 %sp
257
258 b,l rfi_virt2real,%r2
259 nop
260
261 b,l save_control_regs,%r2 /* modifies r1, r2, r28 */
262 nop
263
264 load32 PA(r64_ret), %r2
265 bv 0(%r31)
266 nop
267r64_ret:
268 /* restore CRs before going virtual in case we page fault */
269 b,l restore_control_regs, %r2 /* modifies r1, r2, r26 */
270 nop
271
272 b,l rfi_real2virt,%r2
273 nop
274
275 tovirt_r1 %sp
276 ldd -8(%sp), %sp /* restore SP */
277 ldd -0x10(%sp), %rp /* restore RP */
278 bv 0(%rp)
279 nop
280
281#endif
282
283 .export pc_in_user_space
284 .text
285 /* Doesn't belong here but I couldn't find a nicer spot. */
286 /* Should never get called, only used by profile stuff in time.c */
287pc_in_user_space:
288 bv,n 0(%rp)
289 nop
290
291
292 .export __canonicalize_funcptr_for_compare
293 .text
294 /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
295 ** GCC 3.3 and later has a new function in libgcc.a for
296 ** comparing function pointers.
297 */
298__canonicalize_funcptr_for_compare:
299#ifdef __LP64__
300 bve (%r2)
301#else
302 bv %r0(%r2)
303#endif
304 copy %r26,%r28
diff --git a/arch/parisc/kernel/semaphore.c b/arch/parisc/kernel/semaphore.c
new file mode 100644
index 000000000000..ee806bcc3726
--- /dev/null
+++ b/arch/parisc/kernel/semaphore.c
@@ -0,0 +1,102 @@
1/*
2 * Semaphore implementation Copyright (c) 2001 Matthew Wilcox, Hewlett-Packard
3 */
4
5#include <linux/sched.h>
6#include <linux/spinlock.h>
7#include <linux/errno.h>
8#include <linux/init.h>
9
10/*
11 * Semaphores are complex as we wish to avoid using two variables.
12 * `count' has multiple roles, depending on its value. If it is positive
13 * or zero, there are no waiters. The functions here will never be
14 * called; see <asm/semaphore.h>
15 *
16 * When count is -1 it indicates there is at least one task waiting
17 * for the semaphore.
18 *
19 * When count is less than that, there are '- count - 1' wakeups
20 * pending. ie if it has value -3, there are 2 wakeups pending.
21 *
22 * Note that these functions are only called when there is contention
23 * on the lock, and as such all this is the "non-critical" part of the
24 * whole semaphore business. The critical part is the inline stuff in
25 * <asm/semaphore.h> where we want to avoid any extra jumps and calls.
26 */
27void __up(struct semaphore *sem)
28{
29 sem->count--;
30 wake_up(&sem->wait);
31}
32
33#define wakers(count) (-1 - count)
34
35#define DOWN_HEAD \
36 int ret = 0; \
37 DECLARE_WAITQUEUE(wait, current); \
38 \
39 /* Note that someone is waiting */ \
40 if (sem->count == 0) \
41 sem->count = -1; \
42 \
43 /* protected by the sentry still -- use unlocked version */ \
44 wait.flags = WQ_FLAG_EXCLUSIVE; \
45 __add_wait_queue_tail(&sem->wait, &wait); \
46 lost_race: \
47 spin_unlock_irq(&sem->sentry); \
48
49#define DOWN_TAIL \
50 spin_lock_irq(&sem->sentry); \
51 if (wakers(sem->count) == 0 && ret == 0) \
52 goto lost_race; /* Someone stole our wakeup */ \
53 __remove_wait_queue(&sem->wait, &wait); \
54 current->state = TASK_RUNNING; \
55 if (!waitqueue_active(&sem->wait) && (sem->count < 0)) \
56 sem->count = wakers(sem->count);
57
58#define UPDATE_COUNT \
59 sem->count += (sem->count < 0) ? 1 : - 1;
60
61
62void __sched __down(struct semaphore * sem)
63{
64 DOWN_HEAD
65
66 for(;;) {
67 set_task_state(current, TASK_UNINTERRUPTIBLE);
68 /* we can _read_ this without the sentry */
69 if (sem->count != -1)
70 break;
71 schedule();
72 }
73
74 DOWN_TAIL
75 UPDATE_COUNT
76}
77
78int __sched __down_interruptible(struct semaphore * sem)
79{
80 DOWN_HEAD
81
82 for(;;) {
83 set_task_state(current, TASK_INTERRUPTIBLE);
84 /* we can _read_ this without the sentry */
85 if (sem->count != -1)
86 break;
87
88 if (signal_pending(current)) {
89 ret = -EINTR;
90 break;
91 }
92 schedule();
93 }
94
95 DOWN_TAIL
96
97 if (!ret) {
98 UPDATE_COUNT
99 }
100
101 return ret;
102}
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
new file mode 100644
index 000000000000..73e9c34b0948
--- /dev/null
+++ b/arch/parisc/kernel/setup.c
@@ -0,0 +1,368 @@
1/* $Id: setup.c,v 1.8 2000/02/02 04:42:38 prumpf Exp $
2 *
3 * Initial setup-routines for HP 9000 based hardware.
4 *
5 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
6 * Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de>
7 * Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
8 * Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
9 * Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
10 * Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
11 *
12 * Initial PA-RISC Version: 04-23-1999 by Helge Deller
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/kernel.h>
32#include <linux/initrd.h>
33#include <linux/init.h>
34#include <linux/console.h>
35#include <linux/seq_file.h>
36#define PCI_DEBUG
37#include <linux/pci.h>
38#undef PCI_DEBUG
39#include <linux/proc_fs.h>
40
41#include <asm/processor.h>
42#include <asm/pdc.h>
43#include <asm/led.h>
44#include <asm/machdep.h> /* for pa7300lc_init() proto */
45#include <asm/pdc_chassis.h>
46#include <asm/io.h>
47#include <asm/setup.h>
48
49char command_line[COMMAND_LINE_SIZE];
50
51/* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
52struct proc_dir_entry * proc_runway_root = NULL;
53struct proc_dir_entry * proc_gsc_root = NULL;
54struct proc_dir_entry * proc_mckinley_root = NULL;
55
56#if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
57int parisc_bus_is_phys = 1; /* Assume no IOMMU is present */
58EXPORT_SYMBOL(parisc_bus_is_phys);
59#endif
60
61/* This sets the vmerge boundary and size, it's here because it has to
62 * be available on all platforms (zero means no-virtual merging) */
63unsigned long parisc_vmerge_boundary = 0;
64unsigned long parisc_vmerge_max_size = 0;
65
66void __init setup_cmdline(char **cmdline_p)
67{
68 extern unsigned int boot_args[];
69
70 /* Collect stuff passed in from the boot loader */
71
72 /* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */
73 if (boot_args[0] < 64) {
74 /* called from hpux boot loader */
75 saved_command_line[0] = '\0';
76 } else {
77 strcpy(saved_command_line, (char *)__va(boot_args[1]));
78
79#ifdef CONFIG_BLK_DEV_INITRD
80 if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
81 {
82 initrd_start = (unsigned long)__va(boot_args[2]);
83 initrd_end = (unsigned long)__va(boot_args[3]);
84 }
85#endif
86 }
87
88 strcpy(command_line, saved_command_line);
89 *cmdline_p = command_line;
90}
91
92#ifdef CONFIG_PA11
93void __init dma_ops_init(void)
94{
95 switch (boot_cpu_data.cpu_type) {
96 case pcx:
97 /*
98 * We've got way too many dependencies on 1.1 semantics
99 * to support 1.0 boxes at this point.
100 */
101 panic( "PA-RISC Linux currently only supports machines that conform to\n"
102 "the PA-RISC 1.1 or 2.0 architecture specification.\n");
103
104 case pcxs:
105 case pcxt:
106 hppa_dma_ops = &pcx_dma_ops;
107 break;
108 case pcxl2:
109 pa7300lc_init();
110 case pcxl: /* falls through */
111 hppa_dma_ops = &pcxl_dma_ops;
112 break;
113 default:
114 break;
115 }
116}
117#endif
118
119extern int init_per_cpu(int cpuid);
120extern void collect_boot_cpu_data(void);
121
122void __init setup_arch(char **cmdline_p)
123{
124#ifdef __LP64__
125 extern int parisc_narrow_firmware;
126#endif
127
128 init_per_cpu(smp_processor_id()); /* Set Modes & Enable FP */
129
130#ifdef __LP64__
131 printk(KERN_INFO "The 64-bit Kernel has started...\n");
132#else
133 printk(KERN_INFO "The 32-bit Kernel has started...\n");
134#endif
135
136 pdc_console_init();
137
138#ifdef __LP64__
139 if(parisc_narrow_firmware) {
140 printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
141 }
142#endif
143 setup_pdc();
144 setup_cmdline(cmdline_p);
145 collect_boot_cpu_data();
146 do_memory_inventory(); /* probe for physical memory */
147 parisc_cache_init();
148 paging_init();
149
150#ifdef CONFIG_CHASSIS_LCD_LED
151 /* initialize the LCD/LED after boot_cpu_data is available ! */
152 led_init(); /* LCD/LED initialization */
153#endif
154
155#ifdef CONFIG_PA11
156 dma_ops_init();
157#endif
158
159#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
160 conswitchp = &dummy_con; /* we use take_over_console() later ! */
161#endif
162
163}
164
165/*
166 * Display cpu info for all cpu's.
167 * for parisc this is in processor.c
168 */
169extern int show_cpuinfo (struct seq_file *m, void *v);
170
171static void *
172c_start (struct seq_file *m, loff_t *pos)
173{
174 /* Looks like the caller will call repeatedly until we return
175 * 0, signaling EOF perhaps. This could be used to sequence
176 * through CPUs for example. Since we print all cpu info in our
177 * show_cpuinfo() disregarding 'pos' (which I assume is 'v' above)
178 * we only allow for one "position". */
179 return ((long)*pos < 1) ? (void *)1 : NULL;
180}
181
182static void *
183c_next (struct seq_file *m, void *v, loff_t *pos)
184{
185 ++*pos;
186 return c_start(m, pos);
187}
188
189static void
190c_stop (struct seq_file *m, void *v)
191{
192}
193
194struct seq_operations cpuinfo_op = {
195 .start = c_start,
196 .next = c_next,
197 .stop = c_stop,
198 .show = show_cpuinfo
199};
200
201static void __init parisc_proc_mkdir(void)
202{
203 /*
204 ** Can't call proc_mkdir() until after proc_root_init() has been
205 ** called by start_kernel(). In other words, this code can't
206 ** live in arch/.../setup.c because start_parisc() calls
207 ** start_kernel().
208 */
209 switch (boot_cpu_data.cpu_type) {
210 case pcxl:
211 case pcxl2:
212 if (NULL == proc_gsc_root)
213 {
214 proc_gsc_root = proc_mkdir("bus/gsc", NULL);
215 }
216 break;
217 case pcxt_:
218 case pcxu:
219 case pcxu_:
220 case pcxw:
221 case pcxw_:
222 case pcxw2:
223 if (NULL == proc_runway_root)
224 {
225 proc_runway_root = proc_mkdir("bus/runway", NULL);
226 }
227 break;
228 case mako:
229 if (NULL == proc_mckinley_root)
230 {
231 proc_mckinley_root = proc_mkdir("bus/mckinley", NULL);
232 }
233 break;
234 default:
235 /* FIXME: this was added to prevent the compiler
236 * complaining about missing pcx, pcxs and pcxt
237 * I'm assuming they have neither gsc nor runway */
238 break;
239 }
240}
241
242static struct resource central_bus = {
243 .name = "Central Bus",
244 .start = F_EXTEND(0xfff80000),
245 .end = F_EXTEND(0xfffaffff),
246 .flags = IORESOURCE_MEM,
247};
248
249static struct resource local_broadcast = {
250 .name = "Local Broadcast",
251 .start = F_EXTEND(0xfffb0000),
252 .end = F_EXTEND(0xfffdffff),
253 .flags = IORESOURCE_MEM,
254};
255
256static struct resource global_broadcast = {
257 .name = "Global Broadcast",
258 .start = F_EXTEND(0xfffe0000),
259 .end = F_EXTEND(0xffffffff),
260 .flags = IORESOURCE_MEM,
261};
262
263static int __init parisc_init_resources(void)
264{
265 int result;
266
267 result = request_resource(&iomem_resource, &central_bus);
268 if (result < 0) {
269 printk(KERN_ERR
270 "%s: failed to claim %s address space!\n",
271 __FILE__, central_bus.name);
272 return result;
273 }
274
275 result = request_resource(&iomem_resource, &local_broadcast);
276 if (result < 0) {
277 printk(KERN_ERR
278 "%s: failed to claim %saddress space!\n",
279 __FILE__, local_broadcast.name);
280 return result;
281 }
282
283 result = request_resource(&iomem_resource, &global_broadcast);
284 if (result < 0) {
285 printk(KERN_ERR
286 "%s: failed to claim %s address space!\n",
287 __FILE__, global_broadcast.name);
288 return result;
289 }
290
291 return 0;
292}
293
294extern void gsc_init(void);
295extern void processor_init(void);
296extern void ccio_init(void);
297extern void hppb_init(void);
298extern void dino_init(void);
299extern void iosapic_init(void);
300extern void lba_init(void);
301extern void sba_init(void);
302extern void eisa_init(void);
303
304static int __init parisc_init(void)
305{
306 parisc_proc_mkdir();
307 parisc_init_resources();
308 do_device_inventory(); /* probe for hardware */
309
310 parisc_pdc_chassis_init();
311
312 /* set up a new led state on systems shipped LED State panel */
313 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
314
315 processor_init();
316 printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
317 boot_cpu_data.cpu_count,
318 boot_cpu_data.cpu_name,
319 boot_cpu_data.cpu_hz / 1000000,
320 boot_cpu_data.cpu_hz % 1000000 );
321
322 parisc_setup_cache_timing();
323
324 /* These are in a non-obvious order, will fix when we have an iotree */
325#if defined(CONFIG_IOSAPIC)
326 iosapic_init();
327#endif
328#if defined(CONFIG_IOMMU_SBA)
329 sba_init();
330#endif
331#if defined(CONFIG_PCI_LBA)
332 lba_init();
333#endif
334
335 /* CCIO before any potential subdevices */
336#if defined(CONFIG_IOMMU_CCIO)
337 ccio_init();
338#endif
339
340 /*
341 * Need to register Asp & Wax before the EISA adapters for the IRQ
342 * regions. EISA must come before PCI to be sure it gets IRQ region
343 * 0.
344 */
345#if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX)
346 gsc_init();
347#endif
348#ifdef CONFIG_EISA
349 eisa_init();
350#endif
351
352#if defined(CONFIG_HPPB)
353 hppb_init();
354#endif
355
356#if defined(CONFIG_GSC_DINO)
357 dino_init();
358#endif
359
360#ifdef CONFIG_CHASSIS_LCD_LED
361 register_led_regions(); /* register LED port info in procfs */
362#endif
363
364 return 0;
365}
366
367arch_initcall(parisc_init);
368
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
new file mode 100644
index 000000000000..9421bb98ea63
--- /dev/null
+++ b/arch/parisc/kernel/signal.c
@@ -0,0 +1,664 @@
1/*
2 * linux/arch/parisc/kernel/signal.c: Architecture-specific signal
3 * handling support.
4 *
5 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
6 * Copyright (C) 2000 Linuxcare, Inc.
7 *
8 * Based on the ia64, i386, and alpha versions.
9 *
10 * Like the IA-64, we are a recent enough port (we are *starting*
11 * with glibc2.2) that we do not need to support the old non-realtime
12 * Linux signals. Therefore we don't. HP/UX signals will go in
13 * arch/parisc/hpux/signal.c when we figure out how to do them.
14 */
15
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/smp.h>
19#include <linux/smp_lock.h>
20#include <linux/kernel.h>
21#include <linux/signal.h>
22#include <linux/errno.h>
23#include <linux/wait.h>
24#include <linux/ptrace.h>
25#include <linux/unistd.h>
26#include <linux/stddef.h>
27#include <linux/compat.h>
28#include <linux/elf.h>
29#include <linux/personality.h>
30#include <asm/ucontext.h>
31#include <asm/rt_sigframe.h>
32#include <asm/uaccess.h>
33#include <asm/pgalloc.h>
34#include <asm/cacheflush.h>
35#include <asm/offsets.h>
36
37#ifdef CONFIG_COMPAT
38#include <linux/compat.h>
39#include "signal32.h"
40#endif
41
42#define DEBUG_SIG 0
43#define DEBUG_SIG_LEVEL 2
44
45#if DEBUG_SIG
46#define DBG(LEVEL, ...) \
47 ((DEBUG_SIG_LEVEL >= LEVEL) \
48 ? printk(__VA_ARGS__) : (void) 0)
49#else
50#define DBG(LEVEL, ...)
51#endif
52
53
54#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
55
56/* gcc will complain if a pointer is cast to an integer of different
57 * size. If you really need to do this (and we do for an ELF32 user
58 * application in an ELF64 kernel) then you have to do a cast to an
59 * integer of the same size first. The A() macro accomplishes
60 * this. */
61#define A(__x) ((unsigned long)(__x))
62
63int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
64
65/*
66 * Atomically swap in the new signal mask, and wait for a signal.
67 */
68#ifdef __LP64__
69#include "sys32.h"
70#endif
71
72asmlinkage int
73sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
74{
75 sigset_t saveset, newset;
76#ifdef __LP64__
77 compat_sigset_t newset32;
78
79 if(personality(current->personality) == PER_LINUX32){
80 /* XXX: Don't preclude handling different sized sigset_t's. */
81 if (sigsetsize != sizeof(compat_sigset_t))
82 return -EINVAL;
83 if (copy_from_user(&newset32, (compat_sigset_t __user *)unewset, sizeof(newset32)))
84 return -EFAULT;
85 sigset_32to64(&newset,&newset32);
86
87 } else
88#endif
89 {
90 /* XXX: Don't preclude handling different sized sigset_t's. */
91 if (sigsetsize != sizeof(sigset_t))
92 return -EINVAL;
93
94 if (copy_from_user(&newset, unewset, sizeof(newset)))
95 return -EFAULT;
96 }
97
98 sigdelsetmask(&newset, ~_BLOCKABLE);
99
100 spin_lock_irq(&current->sighand->siglock);
101 saveset = current->blocked;
102 current->blocked = newset;
103 recalc_sigpending();
104 spin_unlock_irq(&current->sighand->siglock);
105
106 regs->gr[28] = -EINTR;
107 while (1) {
108 current->state = TASK_INTERRUPTIBLE;
109 schedule();
110 if (do_signal(&saveset, regs, 1))
111 return -EINTR;
112 }
113}
114
115/*
116 * Do a signal return - restore sigcontext.
117 */
118
119/* Trampoline for calling rt_sigreturn() */
120#define INSN_LDI_R25_0 0x34190000 /* ldi 0,%r25 (in_syscall=0) */
121#define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */
122#define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */
123#define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
124#define INSN_NOP 0x08000240 /* nop */
125/* For debugging */
126#define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
127
128static long
129restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
130{
131 long err = 0;
132
133 err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
134 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
135 err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
136 err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
137 err |= __get_user(regs->sar, &sc->sc_sar);
138 DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n",
139 regs->iaoq[0],regs->iaoq[1]);
140 DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
141 return err;
142}
143
144void
145sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
146{
147 struct rt_sigframe __user *frame;
148 struct siginfo si;
149 sigset_t set;
150 unsigned long usp = (regs->gr[30] & ~(0x01UL));
151 unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
152#ifdef __LP64__
153 compat_sigset_t compat_set;
154 struct compat_rt_sigframe __user * compat_frame;
155
156 if(personality(current->personality) == PER_LINUX32)
157 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
158#endif
159
160
161 /* Unwind the user stack to get the rt_sigframe structure. */
162 frame = (struct rt_sigframe __user *)
163 (usp - sigframe_size);
164 DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
165
166#ifdef __LP64__
167 compat_frame = (struct compat_rt_sigframe __user *)frame;
168
169 if(personality(current->personality) == PER_LINUX32){
170 DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
171 if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
172 goto give_sigsegv;
173 sigset_32to64(&set,&compat_set);
174 } else
175#endif
176 {
177 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
178 goto give_sigsegv;
179 }
180
181 sigdelsetmask(&set, ~_BLOCKABLE);
182 spin_lock_irq(&current->sighand->siglock);
183 current->blocked = set;
184 recalc_sigpending();
185 spin_unlock_irq(&current->sighand->siglock);
186
187 /* Good thing we saved the old gr[30], eh? */
188#ifdef __LP64__
189 if(personality(current->personality) == PER_LINUX32){
190 DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
191 &compat_frame->uc.uc_mcontext);
192// FIXME: Load upper half from register file
193 if (restore_sigcontext32(&compat_frame->uc.uc_mcontext,
194 &compat_frame->regs, regs))
195 goto give_sigsegv;
196 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
197 usp, &compat_frame->uc.uc_stack);
198 if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT)
199 goto give_sigsegv;
200 } else
201#endif
202 {
203 DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
204 &frame->uc.uc_mcontext);
205 if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
206 goto give_sigsegv;
207 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
208 usp, &frame->uc.uc_stack);
209 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
210 goto give_sigsegv;
211 }
212
213
214
215 /* If we are on the syscall path IAOQ will not be restored, and
216 * if we are on the interrupt path we must not corrupt gr31.
217 */
218 if (in_syscall)
219 regs->gr[31] = regs->iaoq[0];
220#if DEBUG_SIG
221 DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
222 show_regs(regs);
223#endif
224 return;
225
226give_sigsegv:
227 DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
228 si.si_signo = SIGSEGV;
229 si.si_errno = 0;
230 si.si_code = SI_KERNEL;
231 si.si_pid = current->pid;
232 si.si_uid = current->uid;
233 si.si_addr = &frame->uc;
234 force_sig_info(SIGSEGV, &si, current);
235 return;
236}
237
238/*
239 * Set up a signal frame.
240 */
241
242static inline void __user *
243get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
244{
245 /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
246 don't use the parameter it doesn't matter */
247
248 DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
249 (unsigned long)ka, sp, frame_size);
250
251 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
252 sp = current->sas_ss_sp; /* Stacks grow up! */
253
254 DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
255 return (void __user *) sp; /* Stacks grow up. Fun. */
256}
257
258static long
259setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
260
261{
262 unsigned long flags = 0;
263 long err = 0;
264
265 if (on_sig_stack((unsigned long) sc))
266 flags |= PARISC_SC_FLAG_ONSTACK;
267 if (in_syscall) {
268 flags |= PARISC_SC_FLAG_IN_SYSCALL;
269 /* regs->iaoq is undefined in the syscall return path */
270 err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
271 err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
272 err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
273 err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
274 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
275 regs->gr[31], regs->gr[31]+4);
276 } else {
277 err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
278 err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
279 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n",
280 regs->iaoq[0], regs->iaoq[1]);
281 }
282
283 err |= __put_user(flags, &sc->sc_flags);
284 err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
285 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
286 err |= __put_user(regs->sar, &sc->sc_sar);
287 DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
288
289 return err;
290}
291
292static long
293setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
294 sigset_t *set, struct pt_regs *regs, int in_syscall)
295{
296 struct rt_sigframe __user *frame;
297 unsigned long rp, usp;
298 unsigned long haddr, sigframe_size;
299 struct siginfo si;
300 int err = 0;
301#ifdef __LP64__
302 compat_int_t compat_val;
303 struct compat_rt_sigframe __user * compat_frame;
304 compat_sigset_t compat_set;
305#endif
306
307 usp = (regs->gr[30] & ~(0x01UL));
308 /*FIXME: frame_size parameter is unused, remove it. */
309 frame = get_sigframe(ka, usp, sizeof(*frame));
310
311 DBG(1,"SETUP_RT_FRAME: START\n");
312 DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
313
314
315#ifdef __LP64__
316
317 compat_frame = (struct compat_rt_sigframe __user *)frame;
318
319 if(personality(current->personality) == PER_LINUX32) {
320 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
321 err |= compat_copy_siginfo_to_user(&compat_frame->info, info);
322 DBG(1,"SETUP_RT_FRAME: 1\n");
323 compat_val = (compat_int_t)current->sas_ss_sp;
324 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
325 DBG(1,"SETUP_RT_FRAME: 2\n");
326 compat_val = (compat_int_t)current->sas_ss_size;
327 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size);
328 DBG(1,"SETUP_RT_FRAME: 3\n");
329 compat_val = sas_ss_flags(regs->gr[30]);
330 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags);
331 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
332 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
333 err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext,
334 &compat_frame->regs, regs, in_syscall);
335 sigset_64to32(&compat_set,set);
336 err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
337 } else
338#endif
339 {
340 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
341 err |= copy_siginfo_to_user(&frame->info, info);
342 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
343 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
344 err |= __put_user(sas_ss_flags(regs->gr[30]),
345 &frame->uc.uc_stack.ss_flags);
346 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
347 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
348 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
349 /* FIXME: Should probably be converted aswell for the compat case */
350 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
351 }
352
353 if (err)
354 goto give_sigsegv;
355
356 /* Set up to return from userspace. If provided, use a stub
357 already in userspace. The first words of tramp are used to
358 save the previous sigrestartblock trampoline that might be
359 on the stack. We start the sigreturn trampoline at
360 SIGRESTARTBLOCK_TRAMP+X. */
361 err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
362 &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
363 err |= __put_user(INSN_LDI_R20,
364 &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
365 err |= __put_user(INSN_BLE_SR2_R0,
366 &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
367 err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
368
369#if DEBUG_SIG
370 /* Assert that we're flushing in the correct space... */
371 {
372 int sid;
373 asm ("mfsp %%sr3,%0" : "=r" (sid));
374 DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
375 sid, frame->tramp);
376 }
377#endif
378
379 flush_user_dcache_range((unsigned long) &frame->tramp[0],
380 (unsigned long) &frame->tramp[TRAMP_SIZE]);
381 flush_user_icache_range((unsigned long) &frame->tramp[0],
382 (unsigned long) &frame->tramp[TRAMP_SIZE]);
383
384 /* TRAMP Words 0-4, Lenght 5 = SIGRESTARTBLOCK_TRAMP
385 * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
386 * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
387 */
388 rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
389
390 if (err)
391 goto give_sigsegv;
392
393 haddr = A(ka->sa.sa_handler);
394 /* The sa_handler may be a pointer to a function descriptor */
395#ifdef __LP64__
396 if(personality(current->personality) == PER_LINUX32) {
397#endif
398 if (haddr & PA_PLABEL_FDESC) {
399 Elf32_Fdesc fdesc;
400 Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
401
402 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
403
404 if (err)
405 goto give_sigsegv;
406
407 haddr = fdesc.addr;
408 regs->gr[19] = fdesc.gp;
409 }
410#ifdef __LP64__
411 } else {
412 Elf64_Fdesc fdesc;
413 Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
414
415 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
416
417 if (err)
418 goto give_sigsegv;
419
420 haddr = fdesc.addr;
421 regs->gr[19] = fdesc.gp;
422 DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
423 haddr, regs->gr[19], in_syscall);
424 }
425#endif
426
427 /* The syscall return path will create IAOQ values from r31.
428 */
429 sigframe_size = PARISC_RT_SIGFRAME_SIZE;
430#ifdef __LP64__
431 if(personality(current->personality) == PER_LINUX32)
432 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
433#endif
434 if (in_syscall) {
435 regs->gr[31] = haddr;
436#ifdef __LP64__
437 if(personality(current->personality) == PER_LINUX)
438 sigframe_size |= 1;
439#endif
440 } else {
441 unsigned long psw = USER_PSW;
442#ifdef __LP64__
443 if(personality(current->personality) == PER_LINUX)
444 psw |= PSW_W;
445#endif
446
447 /* If we are singlestepping, arrange a trap to be delivered
448 when we return to userspace. Note the semantics -- we
449 should trap before the first insn in the handler is
450 executed. Ref:
451 http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
452 */
453 if (pa_psw(current)->r) {
454 pa_psw(current)->r = 0;
455 psw |= PSW_R;
456 mtctl(-1, 0);
457 }
458
459 regs->gr[0] = psw;
460 regs->iaoq[0] = haddr | 3;
461 regs->iaoq[1] = regs->iaoq[0] + 4;
462 }
463
464 regs->gr[2] = rp; /* userland return pointer */
465 regs->gr[26] = sig; /* signal number */
466
467#ifdef __LP64__
468 if(personality(current->personality) == PER_LINUX32){
469 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
470 regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
471 } else
472#endif
473 {
474 regs->gr[25] = A(&frame->info); /* siginfo pointer */
475 regs->gr[24] = A(&frame->uc); /* ucontext pointer */
476 }
477
478 DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
479 regs->gr[30], sigframe_size,
480 regs->gr[30] + sigframe_size);
481 /* Raise the user stack pointer to make a proper call frame. */
482 regs->gr[30] = (A(frame) + sigframe_size);
483
484
485 DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
486 current->comm, current->pid, frame, regs->gr[30],
487 regs->iaoq[0], regs->iaoq[1], rp);
488
489 return 1;
490
491give_sigsegv:
492 DBG(1,"setup_rt_frame: sending SIGSEGV\n");
493 if (sig == SIGSEGV)
494 ka->sa.sa_handler = SIG_DFL;
495 si.si_signo = SIGSEGV;
496 si.si_errno = 0;
497 si.si_code = SI_KERNEL;
498 si.si_pid = current->pid;
499 si.si_uid = current->uid;
500 si.si_addr = frame;
501 force_sig_info(SIGSEGV, &si, current);
502 return 0;
503}
504
505/*
506 * OK, we're invoking a handler.
507 */
508
509static long
510handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
511 sigset_t *oldset, struct pt_regs *regs, int in_syscall)
512{
513 DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
514 sig, ka, info, oldset, regs);
515
516 /* Set up the stack frame */
517 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
518 return 0;
519
520 if (!(ka->sa.sa_flags & SA_NODEFER)) {
521 spin_lock_irq(&current->sighand->siglock);
522 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
523 sigaddset(&current->blocked,sig);
524 recalc_sigpending();
525 spin_unlock_irq(&current->sighand->siglock);
526 }
527 return 1;
528}
529
530/*
531 * Note that 'init' is a special process: it doesn't get signals it doesn't
532 * want to handle. Thus you cannot kill init even with a SIGKILL even by
533 * mistake.
534 *
535 * We need to be able to restore the syscall arguments (r21-r26) to
536 * restart syscalls. Thus, the syscall path should save them in the
537 * pt_regs structure (it's okay to do so since they are caller-save
538 * registers). As noted below, the syscall number gets restored for
539 * us due to the magic of delayed branching.
540 */
541
542asmlinkage int
543do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
544{
545 siginfo_t info;
546 struct k_sigaction ka;
547 int signr;
548
549 DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
550 oldset, regs, regs->sr[7], in_syscall);
551
552 /* Everyone else checks to see if they are in kernel mode at
553 this point and exits if that's the case. I'm not sure why
554 we would be called in that case, but for some reason we
555 are. */
556
557 if (!oldset)
558 oldset = &current->blocked;
559
560 DBG(1,"do_signal: oldset %08lx / %08lx\n",
561 oldset->sig[0], oldset->sig[1]);
562
563
564 /* May need to force signal if handle_signal failed to deliver */
565 while (1) {
566
567 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
568 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
569
570 if (signr <= 0)
571 break;
572
573 /* Restart a system call if necessary. */
574 if (in_syscall) {
575 /* Check the return code */
576 switch (regs->gr[28]) {
577 case -ERESTART_RESTARTBLOCK:
578 current_thread_info()->restart_block.fn = do_no_restart_syscall;
579 case -ERESTARTNOHAND:
580 DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
581 regs->gr[28] = -EINTR;
582 break;
583
584 case -ERESTARTSYS:
585 if (!(ka.sa.sa_flags & SA_RESTART)) {
586 DBG(1,"ERESTARTSYS: putting -EINTR\n");
587 regs->gr[28] = -EINTR;
588 break;
589 }
590 /* fallthrough */
591 case -ERESTARTNOINTR:
592 /* A syscall is just a branch, so all
593 we have to do is fiddle the return pointer. */
594 regs->gr[31] -= 8; /* delayed branching */
595 /* Preserve original r28. */
596 regs->gr[28] = regs->orig_r28;
597 break;
598 }
599 }
600 /* Whee! Actually deliver the signal. If the
601 delivery failed, we need to continue to iterate in
602 this loop so we can deliver the SIGSEGV... */
603 if (handle_signal(signr, &info, &ka, oldset, regs, in_syscall)) {
604 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
605 regs->gr[28]);
606 return 1;
607 }
608 }
609 /* end of while(1) looping forever if we can't force a signal */
610
611 /* Did we come from a system call? */
612 if (in_syscall) {
613 /* Restart the system call - no handlers present */
614 if (regs->gr[28] == -ERESTART_RESTARTBLOCK) {
615 unsigned int *usp = (unsigned int *)regs->gr[30];
616
617 /* Setup a trampoline to restart the syscall
618 * with __NR_restart_syscall
619 *
620 * 0: <return address (orig r31)>
621 * 4: <2nd half for 64-bit>
622 * 8: ldw 0(%sp), %r31
623 * 12: be 0x100(%sr2, %r0)
624 * 16: ldi __NR_restart_syscall, %r20
625 */
626#ifndef __LP64__
627 put_user(regs->gr[31], &usp[0]);
628 put_user(0x0fc0109f, &usp[2]);
629#else
630 put_user(regs->gr[31] >> 32, &usp[0]);
631 put_user(regs->gr[31] & 0xffffffff, &usp[1]);
632 put_user(0x0fc010df, &usp[2]);
633#endif
634 put_user(0xe0008200, &usp[3]);
635 put_user(0x34140000, &usp[4]);
636
637 /* Stack is 64-byte aligned, and we only
638 * need to flush 1 cache line */
639 asm("fdc 0(%%sr3, %0)\n"
640 "fic 0(%%sr3, %0)\n"
641 "sync\n"
642 : : "r"(regs->gr[30]));
643
644 regs->gr[31] = regs->gr[30] + 8;
645 /* Preserve original r28. */
646 regs->gr[28] = regs->orig_r28;
647 } else if (regs->gr[28] == -ERESTARTNOHAND ||
648 regs->gr[28] == -ERESTARTSYS ||
649 regs->gr[28] == -ERESTARTNOINTR) {
650 /* Hooray for delayed branching. We don't
651 have to restore %r20 (the system call
652 number) because it gets loaded in the delay
653 slot of the branch external instruction. */
654 regs->gr[31] -= 8;
655 /* Preserve original r28. */
656 regs->gr[28] = regs->orig_r28;
657 }
658 }
659
660 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n",
661 regs->gr[28]);
662
663 return 0;
664}
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
new file mode 100644
index 000000000000..0792e20efef3
--- /dev/null
+++ b/arch/parisc/kernel/signal32.c
@@ -0,0 +1,400 @@
1/* Signal support for 32-bit kernel builds
2 *
3 * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4 * Code was mostly borrowed from kernel/signal.c.
5 * See kernel/signal.c for additional Copyrights.
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/compat.h>
24#include <linux/slab.h>
25#include <linux/module.h>
26#include <linux/unistd.h>
27#include <linux/smp_lock.h>
28#include <linux/init.h>
29#include <linux/sched.h>
30#include <linux/syscalls.h>
31#include <linux/types.h>
32#include <linux/errno.h>
33
34#include <asm/compat_signal.h>
35#include <asm/uaccess.h>
36
37#include "signal32.h"
38#include "sys32.h"
39
40#define DEBUG_COMPAT_SIG 0
41#define DEBUG_COMPAT_SIG_LEVEL 2
42
43#if DEBUG_COMPAT_SIG
44#define DBG(LEVEL, ...) \
45 ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
46 ? printk(__VA_ARGS__) : (void) 0)
47#else
48#define DBG(LEVEL, ...)
49#endif
50
51#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
52
53inline void
54sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
55{
56 s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
57}
58
59inline void
60sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
61{
62 s32->sig[0] = s64->sig[0] & 0xffffffffUL;
63 s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
64}
65
66static int
67put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
68{
69 compat_sigset_t s;
70
71 if (sz != sizeof *set) panic("put_sigset32()");
72 sigset_64to32(&s, set);
73
74 return copy_to_user(up, &s, sizeof s);
75}
76
77static int
78get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
79{
80 compat_sigset_t s;
81 int r;
82
83 if (sz != sizeof *set) panic("put_sigset32()");
84
85 if ((r = copy_from_user(&s, up, sz)) == 0) {
86 sigset_32to64(set, &s);
87 }
88
89 return r;
90}
91
92int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
93 unsigned int sigsetsize)
94{
95 sigset_t old_set, new_set;
96 int ret;
97
98 if (set && get_sigset32(set, &new_set, sigsetsize))
99 return -EFAULT;
100
101 KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
102 oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
103
104 if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
105 return -EFAULT;
106
107 return ret;
108}
109
110
111int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
112{
113 int ret;
114 sigset_t set;
115
116 KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
117
118 if (!ret && put_sigset32(uset, &set, sigsetsize))
119 return -EFAULT;
120
121 return ret;
122}
123
124long
125sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
126 size_t sigsetsize)
127{
128 struct k_sigaction32 new_sa32, old_sa32;
129 struct k_sigaction new_sa, old_sa;
130 int ret = -EINVAL;
131
132 if (act) {
133 if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
134 return -EFAULT;
135 new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
136 new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
137 sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
138 }
139
140 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
141
142 if (!ret && oact) {
143 sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
144 old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
145 old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
146 if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
147 return -EFAULT;
148 }
149 return ret;
150}
151
152int
153do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
154{
155 compat_stack_t ss32, oss32;
156 stack_t ss, oss;
157 stack_t *ssp = NULL, *ossp = NULL;
158 int ret;
159
160 if (uss32) {
161 if (copy_from_user(&ss32, uss32, sizeof ss32))
162 return -EFAULT;
163
164 ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
165 ss.ss_flags = ss32.ss_flags;
166 ss.ss_size = ss32.ss_size;
167
168 ssp = &ss;
169 }
170
171 if (uoss32)
172 ossp = &oss;
173
174 KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
175
176 if (!ret && uoss32) {
177 oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
178 oss32.ss_flags = oss.ss_flags;
179 oss32.ss_size = oss.ss_size;
180 if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
181 return -EFAULT;
182 }
183
184 return ret;
185}
186
187long
188restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
189 struct pt_regs *regs)
190{
191 long err = 0;
192 compat_uint_t compat_reg;
193 compat_uint_t compat_regt;
194 int regn;
195
196 /* When loading 32-bit values into 64-bit registers make
197 sure to clear the upper 32-bits */
198 DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
199 DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
200 DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
201 for(regn=0; regn < 32; regn++){
202 err |= __get_user(compat_reg,&sc->sc_gr[regn]);
203 regs->gr[regn] = compat_reg;
204 /* Load upper half */
205 err |= __get_user(compat_regt,&rf->rf_gr[regn]);
206 regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
207 DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
208 regn, regs->gr[regn], compat_regt, compat_reg);
209 }
210 DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
211 /* XXX: BE WARNED FR's are 64-BIT! */
212 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
213
214 /* Better safe than sorry, pass __get_user two things of
215 the same size and let gcc do the upward conversion to
216 64-bits */
217 err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
218 /* Load upper half */
219 err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
220 regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
221 DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
222 DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
223 &sc->sc_iaoq[0], compat_reg);
224
225 err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
226 /* Load upper half */
227 err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
228 regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
229 DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
230 DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
231 &sc->sc_iaoq[1],compat_reg);
232 DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
233 regs->iaoq[0],regs->iaoq[1]);
234
235 err |= __get_user(compat_reg, &sc->sc_iasq[0]);
236 /* Load the upper half for iasq */
237 err |= __get_user(compat_regt, &rf->rf_iasq[0]);
238 regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
239 DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
240
241 err |= __get_user(compat_reg, &sc->sc_iasq[1]);
242 /* Load the upper half for iasq */
243 err |= __get_user(compat_regt, &rf->rf_iasq[1]);
244 regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
245 DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
246 DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
247 regs->iasq[0],regs->iasq[1]);
248
249 err |= __get_user(compat_reg, &sc->sc_sar);
250 /* Load the upper half for sar */
251 err |= __get_user(compat_regt, &rf->rf_sar);
252 regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
253 DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
254 DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
255 DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
256
257 return err;
258}
259
260/*
261 * Set up the sigcontext structure for this process.
262 * This is not an easy task if the kernel is 64-bit, it will require
263 * that we examine the process personality to determine if we need to
264 * truncate for a 32-bit userspace.
265 */
266long
267setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
268 struct pt_regs *regs, int in_syscall)
269{
270 compat_int_t flags = 0;
271 long err = 0;
272 compat_uint_t compat_reg;
273 compat_uint_t compat_regb;
274 int regn;
275
276 if (on_sig_stack((unsigned long) sc))
277 flags |= PARISC_SC_FLAG_ONSTACK;
278
279 if (in_syscall) {
280
281 DBG(1,"setup_sigcontext32: in_syscall\n");
282
283 flags |= PARISC_SC_FLAG_IN_SYSCALL;
284 /* Truncate gr31 */
285 compat_reg = (compat_uint_t)(regs->gr[31]);
286 /* regs->iaoq is undefined in the syscall return path */
287 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
288 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
289 &sc->sc_iaoq[0], compat_reg);
290
291 /* Store upper half */
292 compat_reg = (compat_uint_t)(regs->gr[32] >> 32);
293 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
294 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
295
296
297 compat_reg = (compat_uint_t)(regs->gr[31]+4);
298 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
299 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
300 &sc->sc_iaoq[1], compat_reg);
301 /* Store upper half */
302 compat_reg = (compat_uint_t)((regs->gr[32]+4) >> 32);
303 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
304 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
305
306 /* Truncate sr3 */
307 compat_reg = (compat_uint_t)(regs->sr[3]);
308 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
309 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
310
311 /* Store upper half */
312 compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
313 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
314 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
315
316 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
317 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
318 DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
319 regs->gr[31], regs->gr[31]+4);
320
321 } else {
322
323 compat_reg = (compat_uint_t)(regs->iaoq[0]);
324 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
325 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
326 &sc->sc_iaoq[0], compat_reg);
327 /* Store upper half */
328 compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
329 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
330 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
331
332 compat_reg = (compat_uint_t)(regs->iaoq[1]);
333 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
334 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
335 &sc->sc_iaoq[1], compat_reg);
336 /* Store upper half */
337 compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
338 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
339 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
340
341
342 compat_reg = (compat_uint_t)(regs->iasq[0]);
343 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
344 DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
345 &sc->sc_iasq[0], compat_reg);
346 /* Store upper half */
347 compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
348 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
349 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
350
351
352 compat_reg = (compat_uint_t)(regs->iasq[1]);
353 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
354 DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
355 &sc->sc_iasq[1], compat_reg);
356 /* Store upper half */
357 compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
358 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
359 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
360
361 /* Print out the IAOQ for debugging */
362 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
363 regs->iaoq[0], regs->iaoq[1]);
364 }
365
366 err |= __put_user(flags, &sc->sc_flags);
367
368 DBG(1,"setup_sigcontext32: Truncating general registers.\n");
369
370 for(regn=0; regn < 32; regn++){
371 /* Truncate a general register */
372 compat_reg = (compat_uint_t)(regs->gr[regn]);
373 err |= __put_user(compat_reg, &sc->sc_gr[regn]);
374 /* Store upper half */
375 compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
376 err |= __put_user(compat_regb, &rf->rf_gr[regn]);
377
378 /* DEBUG: Write out the "upper / lower" register data */
379 DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
380 compat_regb, compat_reg);
381 }
382
383 /* Copy the floating point registers (same size)
384 XXX: BE WARNED FR's are 64-BIT! */
385 DBG(1,"setup_sigcontext32: Copying from regs to sc, "
386 "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
387 sizeof(regs->fr), sizeof(sc->sc_fr));
388 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
389
390 compat_reg = (compat_uint_t)(regs->sar);
391 err |= __put_user(compat_reg, &sc->sc_sar);
392 DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
393 /* Store upper half */
394 compat_reg = (compat_uint_t)(regs->sar >> 32);
395 err |= __put_user(compat_reg, &rf->rf_sar);
396 DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
397 DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
398
399 return err;
400}
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
new file mode 100644
index 000000000000..4d1569e717cc
--- /dev/null
+++ b/arch/parisc/kernel/signal32.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
3 * Copyright (C) 2003 Carlos O'Donell <carlos at parisc-linux.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#ifndef _PARISC64_KERNEL_SIGNAL32_H
20#define _PARISC64_KERNEL_SIGNAL32_H
21
22#include <linux/compat.h>
23#include <asm/compat_signal.h>
24#include <asm/compat_rt_sigframe.h>
25
26/* ELF32 signal handling */
27
28struct k_sigaction32 {
29 struct compat_sigaction sa;
30};
31
32void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
33void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
34int do_sigaltstack32 (const compat_stack_t __user *uss32,
35 compat_stack_t __user *uoss32, unsigned long sp);
36long restore_sigcontext32(struct compat_sigcontext __user *sc,
37 struct compat_regfile __user *rf,
38 struct pt_regs *regs);
39long setup_sigcontext32(struct compat_sigcontext __user *sc,
40 struct compat_regfile __user *rf,
41 struct pt_regs *regs, int in_syscall);
42
43#endif
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
new file mode 100644
index 000000000000..bcc7e83f5142
--- /dev/null
+++ b/arch/parisc/kernel/smp.c
@@ -0,0 +1,723 @@
1/*
2** SMP Support
3**
4** Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
5** Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
6** Copyright (C) 2001,2004 Grant Grundler <grundler@parisc-linux.org>
7**
8** Lots of stuff stolen from arch/alpha/kernel/smp.c
9** ...and then parisc stole from arch/ia64/kernel/smp.c. Thanks David! :^)
10**
11** Thanks to John Curry and Ullas Ponnadi. I learned alot from their work.
12** -grant (1/12/2001)
13**
14** This program is free software; you can redistribute it and/or modify
15** it under the terms of the GNU General Public License as published by
16** the Free Software Foundation; either version 2 of the License, or
17** (at your option) any later version.
18*/
19#undef ENTRY_SYS_CPUS /* syscall support for iCOD-like functionality */
20
21#include <linux/autoconf.h>
22
23#include <linux/types.h>
24#include <linux/spinlock.h>
25#include <linux/slab.h>
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/sched.h>
30#include <linux/init.h>
31#include <linux/interrupt.h>
32#include <linux/smp.h>
33#include <linux/kernel_stat.h>
34#include <linux/mm.h>
35#include <linux/delay.h>
36#include <linux/bitops.h>
37
38#include <asm/system.h>
39#include <asm/atomic.h>
40#include <asm/current.h>
41#include <asm/delay.h>
42#include <asm/pgalloc.h> /* for flush_tlb_all() proto/macro */
43
44#include <asm/io.h>
45#include <asm/irq.h> /* for CPU_IRQ_REGION and friends */
46#include <asm/mmu_context.h>
47#include <asm/page.h>
48#include <asm/pgtable.h>
49#include <asm/pgalloc.h>
50#include <asm/processor.h>
51#include <asm/ptrace.h>
52#include <asm/unistd.h>
53#include <asm/cacheflush.h>
54
55#define kDEBUG 0
56
57DEFINE_SPINLOCK(smp_lock);
58
59volatile struct task_struct *smp_init_current_idle_task;
60
61static volatile int cpu_now_booting = 0; /* track which CPU is booting */
62
63static int parisc_max_cpus = 1;
64
65/* online cpus are ones that we've managed to bring up completely
66 * possible cpus are all valid cpu
67 * present cpus are all detected cpu
68 *
69 * On startup we bring up the "possible" cpus. Since we discover
70 * CPUs later, we add them as hotplug, so the possible cpu mask is
71 * empty in the beginning.
72 */
73
74cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmap of online CPUs */
75cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */
76
77EXPORT_SYMBOL(cpu_online_map);
78EXPORT_SYMBOL(cpu_possible_map);
79
80
81struct smp_call_struct {
82 void (*func) (void *info);
83 void *info;
84 long wait;
85 atomic_t unstarted_count;
86 atomic_t unfinished_count;
87};
88static volatile struct smp_call_struct *smp_call_function_data;
89
90enum ipi_message_type {
91 IPI_NOP=0,
92 IPI_RESCHEDULE=1,
93 IPI_CALL_FUNC,
94 IPI_CPU_START,
95 IPI_CPU_STOP,
96 IPI_CPU_TEST
97};
98
99
100/********** SMP inter processor interrupt and communication routines */
101
102#undef PER_CPU_IRQ_REGION
103#ifdef PER_CPU_IRQ_REGION
104/* XXX REVISIT Ignore for now.
105** *May* need this "hook" to register IPI handler
106** once we have perCPU ExtIntr switch tables.
107*/
108static void
109ipi_init(int cpuid)
110{
111
112 /* If CPU is present ... */
113#ifdef ENTRY_SYS_CPUS
114 /* *and* running (not stopped) ... */
115#error iCOD support wants state checked here.
116#endif
117
118#error verify IRQ_OFFSET(IPI_IRQ) is ipi_interrupt() in new IRQ region
119
120 if(cpu_online(cpuid) )
121 {
122 switch_to_idle_task(current);
123 }
124
125 return;
126}
127#endif
128
129
130/*
131** Yoink this CPU from the runnable list...
132**
133*/
134static void
135halt_processor(void)
136{
137#ifdef ENTRY_SYS_CPUS
138#error halt_processor() needs rework
139/*
140** o migrate I/O interrupts off this CPU.
141** o leave IPI enabled - __cli() will disable IPI.
142** o leave CPU in online map - just change the state
143*/
144 cpu_data[this_cpu].state = STATE_STOPPED;
145 mark_bh(IPI_BH);
146#else
147 /* REVISIT : redirect I/O Interrupts to another CPU? */
148 /* REVISIT : does PM *know* this CPU isn't available? */
149 cpu_clear(smp_processor_id(), cpu_online_map);
150 local_irq_disable();
151 for (;;)
152 ;
153#endif
154}
155
156
157irqreturn_t
158ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
159{
160 int this_cpu = smp_processor_id();
161 struct cpuinfo_parisc *p = &cpu_data[this_cpu];
162 unsigned long ops;
163 unsigned long flags;
164
165 /* Count this now; we may make a call that never returns. */
166 p->ipi_count++;
167
168 mb(); /* Order interrupt and bit testing. */
169
170 for (;;) {
171 spin_lock_irqsave(&(p->lock),flags);
172 ops = p->pending_ipi;
173 p->pending_ipi = 0;
174 spin_unlock_irqrestore(&(p->lock),flags);
175
176 mb(); /* Order bit clearing and data access. */
177
178 if (!ops)
179 break;
180
181 while (ops) {
182 unsigned long which = ffz(~ops);
183
184 switch (which) {
185 case IPI_RESCHEDULE:
186#if (kDEBUG>=100)
187 printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
188#endif /* kDEBUG */
189 ops &= ~(1 << IPI_RESCHEDULE);
190 /*
191 * Reschedule callback. Everything to be
192 * done is done by the interrupt return path.
193 */
194 break;
195
196 case IPI_CALL_FUNC:
197#if (kDEBUG>=100)
198 printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
199#endif /* kDEBUG */
200 ops &= ~(1 << IPI_CALL_FUNC);
201 {
202 volatile struct smp_call_struct *data;
203 void (*func)(void *info);
204 void *info;
205 int wait;
206
207 data = smp_call_function_data;
208 func = data->func;
209 info = data->info;
210 wait = data->wait;
211
212 mb();
213 atomic_dec ((atomic_t *)&data->unstarted_count);
214
215 /* At this point, *data can't
216 * be relied upon.
217 */
218
219 (*func)(info);
220
221 /* Notify the sending CPU that the
222 * task is done.
223 */
224 mb();
225 if (wait)
226 atomic_dec ((atomic_t *)&data->unfinished_count);
227 }
228 break;
229
230 case IPI_CPU_START:
231#if (kDEBUG>=100)
232 printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
233#endif /* kDEBUG */
234 ops &= ~(1 << IPI_CPU_START);
235#ifdef ENTRY_SYS_CPUS
236 p->state = STATE_RUNNING;
237#endif
238 break;
239
240 case IPI_CPU_STOP:
241#if (kDEBUG>=100)
242 printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
243#endif /* kDEBUG */
244 ops &= ~(1 << IPI_CPU_STOP);
245#ifdef ENTRY_SYS_CPUS
246#else
247 halt_processor();
248#endif
249 break;
250
251 case IPI_CPU_TEST:
252#if (kDEBUG>=100)
253 printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
254#endif /* kDEBUG */
255 ops &= ~(1 << IPI_CPU_TEST);
256 break;
257
258 default:
259 printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
260 this_cpu, which);
261 ops &= ~(1 << which);
262 return IRQ_NONE;
263 } /* Switch */
264 } /* while (ops) */
265 }
266 return IRQ_HANDLED;
267}
268
269
270static inline void
271ipi_send(int cpu, enum ipi_message_type op)
272{
273 struct cpuinfo_parisc *p = &cpu_data[cpu];
274 unsigned long flags;
275
276 spin_lock_irqsave(&(p->lock),flags);
277 p->pending_ipi |= 1 << op;
278 gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
279 spin_unlock_irqrestore(&(p->lock),flags);
280}
281
282
283static inline void
284send_IPI_single(int dest_cpu, enum ipi_message_type op)
285{
286 if (dest_cpu == NO_PROC_ID) {
287 BUG();
288 return;
289 }
290
291 ipi_send(dest_cpu, op);
292}
293
294static inline void
295send_IPI_allbutself(enum ipi_message_type op)
296{
297 int i;
298
299 for (i = 0; i < NR_CPUS; i++) {
300 if (cpu_online(i) && i != smp_processor_id())
301 send_IPI_single(i, op);
302 }
303}
304
305
306inline void
307smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); }
308
309static inline void
310smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
311
312void
313smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
314
315
316/**
317 * Run a function on all other CPUs.
318 * <func> The function to run. This must be fast and non-blocking.
319 * <info> An arbitrary pointer to pass to the function.
320 * <retry> If true, keep retrying until ready.
321 * <wait> If true, wait until function has completed on other CPUs.
322 * [RETURNS] 0 on success, else a negative status code.
323 *
324 * Does not return until remote CPUs are nearly ready to execute <func>
325 * or have executed.
326 */
327
328int
329smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
330{
331 struct smp_call_struct data;
332 unsigned long timeout;
333 static DEFINE_SPINLOCK(lock);
334 int retries = 0;
335
336 if (num_online_cpus() < 2)
337 return 0;
338
339 /* Can deadlock when called with interrupts disabled */
340 WARN_ON(irqs_disabled());
341
342 data.func = func;
343 data.info = info;
344 data.wait = wait;
345 atomic_set(&data.unstarted_count, num_online_cpus() - 1);
346 atomic_set(&data.unfinished_count, num_online_cpus() - 1);
347
348 if (retry) {
349 spin_lock (&lock);
350 while (smp_call_function_data != 0)
351 barrier();
352 }
353 else {
354 spin_lock (&lock);
355 if (smp_call_function_data) {
356 spin_unlock (&lock);
357 return -EBUSY;
358 }
359 }
360
361 smp_call_function_data = &data;
362 spin_unlock (&lock);
363
364 /* Send a message to all other CPUs and wait for them to respond */
365 send_IPI_allbutself(IPI_CALL_FUNC);
366
367 retry:
368 /* Wait for response */
369 timeout = jiffies + HZ;
370 while ( (atomic_read (&data.unstarted_count) > 0) &&
371 time_before (jiffies, timeout) )
372 barrier ();
373
374 if (atomic_read (&data.unstarted_count) > 0) {
375 printk(KERN_CRIT "SMP CALL FUNCTION TIMED OUT! (cpu=%d), try %d\n",
376 smp_processor_id(), ++retries);
377 goto retry;
378 }
379 /* We either got one or timed out. Release the lock */
380
381 mb();
382 smp_call_function_data = NULL;
383
384 while (wait && atomic_read (&data.unfinished_count) > 0)
385 barrier ();
386
387 return 0;
388}
389
390EXPORT_SYMBOL(smp_call_function);
391
392/*
393 * Flush all other CPU's tlb and then mine. Do this with on_each_cpu()
394 * as we want to ensure all TLB's flushed before proceeding.
395 */
396
397extern void flush_tlb_all_local(void);
398
399void
400smp_flush_tlb_all(void)
401{
402 on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
403}
404
405
406void
407smp_do_timer(struct pt_regs *regs)
408{
409 int cpu = smp_processor_id();
410 struct cpuinfo_parisc *data = &cpu_data[cpu];
411
412 if (!--data->prof_counter) {
413 data->prof_counter = data->prof_multiplier;
414 update_process_times(user_mode(regs));
415 }
416}
417
418/*
419 * Called by secondaries to update state and initialize CPU registers.
420 */
421static void __init
422smp_cpu_init(int cpunum)
423{
424 extern int init_per_cpu(int); /* arch/parisc/kernel/setup.c */
425 extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */
426
427 /* Set modes and Enable floating point coprocessor */
428 (void) init_per_cpu(cpunum);
429
430 disable_sr_hashing();
431
432 mb();
433
434 /* Well, support 2.4 linux scheme as well. */
435 if (cpu_test_and_set(cpunum, cpu_online_map))
436 {
437 extern void machine_halt(void); /* arch/parisc.../process.c */
438
439 printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
440 machine_halt();
441 }
442
443 /* Initialise the idle task for this CPU */
444 atomic_inc(&init_mm.mm_count);
445 current->active_mm = &init_mm;
446 if(current->mm)
447 BUG();
448 enter_lazy_tlb(&init_mm, current);
449
450 init_IRQ(); /* make sure no IRQ's are enabled or pending */
451}
452
453
454/*
455 * Slaves start using C here. Indirectly called from smp_slave_stext.
456 * Do what start_kernel() and main() do for boot strap processor (aka monarch)
457 */
458void __init smp_callin(void)
459{
460 int slave_id = cpu_now_booting;
461#if 0
462 void *istack;
463#endif
464
465 smp_cpu_init(slave_id);
466
467#if 0 /* NOT WORKING YET - see entry.S */
468 istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
469 if (istack == NULL) {
470 printk(KERN_CRIT "Failed to allocate interrupt stack for cpu %d\n",slave_id);
471 BUG();
472 }
473 mtctl(istack,31);
474#endif
475
476 flush_cache_all_local(); /* start with known state */
477 flush_tlb_all_local();
478
479 local_irq_enable(); /* Interrupts have been off until now */
480
481 cpu_idle(); /* Wait for timer to schedule some work */
482
483 /* NOTREACHED */
484 panic("smp_callin() AAAAaaaaahhhh....\n");
485}
486
487/*
488 * Bring one cpu online.
489 */
490int __init smp_boot_one_cpu(int cpuid)
491{
492 struct task_struct *idle;
493 long timeout;
494
495 /*
496 * Create an idle task for this CPU. Note the address wed* give
497 * to kernel_thread is irrelevant -- it's going to start
498 * where OS_BOOT_RENDEVZ vector in SAL says to start. But
499 * this gets all the other task-y sort of data structures set
500 * up like we wish. We need to pull the just created idle task
501 * off the run queue and stuff it into the init_tasks[] array.
502 * Sheesh . . .
503 */
504
505 idle = fork_idle(cpuid);
506 if (IS_ERR(idle))
507 panic("SMP: fork failed for CPU:%d", cpuid);
508
509 idle->thread_info->cpu = cpuid;
510
511 /* Let _start know what logical CPU we're booting
512 ** (offset into init_tasks[],cpu_data[])
513 */
514 cpu_now_booting = cpuid;
515
516 /*
517 ** boot strap code needs to know the task address since
518 ** it also contains the process stack.
519 */
520 smp_init_current_idle_task = idle ;
521 mb();
522
523 printk("Releasing cpu %d now, hpa=%lx\n", cpuid, cpu_data[cpuid].hpa);
524
525 /*
526 ** This gets PDC to release the CPU from a very tight loop.
527 **
528 ** From the PA-RISC 2.0 Firmware Architecture Reference Specification:
529 ** "The MEM_RENDEZ vector specifies the location of OS_RENDEZ which
530 ** is executed after receiving the rendezvous signal (an interrupt to
531 ** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the
532 ** contents of memory are valid."
533 */
534 gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, cpu_data[cpuid].hpa);
535 mb();
536
537 /*
538 * OK, wait a bit for that CPU to finish staggering about.
539 * Slave will set a bit when it reaches smp_cpu_init().
540 * Once the "monarch CPU" sees the bit change, it can move on.
541 */
542 for (timeout = 0; timeout < 10000; timeout++) {
543 if(cpu_online(cpuid)) {
544 /* Which implies Slave has started up */
545 cpu_now_booting = 0;
546 smp_init_current_idle_task = NULL;
547 goto alive ;
548 }
549 udelay(100);
550 barrier();
551 }
552
553 put_task_struct(idle);
554 idle = NULL;
555
556 printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
557 return -1;
558
559alive:
560 /* Remember the Slave data */
561#if (kDEBUG>=100)
562 printk(KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
563 cpuid, timeout * 100);
564#endif /* kDEBUG */
565#ifdef ENTRY_SYS_CPUS
566 cpu_data[cpuid].state = STATE_RUNNING;
567#endif
568 return 0;
569}
570
571void __devinit smp_prepare_boot_cpu(void)
572{
573 int bootstrap_processor=cpu_data[0].cpuid; /* CPU ID of BSP */
574
575#ifdef ENTRY_SYS_CPUS
576 cpu_data[0].state = STATE_RUNNING;
577#endif
578
579 /* Setup BSP mappings */
580 printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
581
582 cpu_set(bootstrap_processor, cpu_online_map);
583 cpu_set(bootstrap_processor, cpu_present_map);
584}
585
586
587
588/*
589** inventory.c:do_inventory() hasn't yet been run and thus we
590** don't 'discover' the additional CPU's until later.
591*/
592void __init smp_prepare_cpus(unsigned int max_cpus)
593{
594 cpus_clear(cpu_present_map);
595 cpu_set(0, cpu_present_map);
596
597 parisc_max_cpus = max_cpus;
598 if (!max_cpus)
599 printk(KERN_INFO "SMP mode deactivated.\n");
600}
601
602
603void smp_cpus_done(unsigned int cpu_max)
604{
605 return;
606}
607
608
609int __devinit __cpu_up(unsigned int cpu)
610{
611 if (cpu != 0 && cpu < parisc_max_cpus)
612 smp_boot_one_cpu(cpu);
613
614 return cpu_online(cpu) ? 0 : -ENOSYS;
615}
616
617
618
619#ifdef ENTRY_SYS_CPUS
620/* Code goes along with:
621** entry.s: ENTRY_NAME(sys_cpus) / * 215, for cpu stat * /
622*/
623int sys_cpus(int argc, char **argv)
624{
625 int i,j=0;
626 extern int current_pid(int cpu);
627
628 if( argc > 2 ) {
629 printk("sys_cpus:Only one argument supported\n");
630 return (-1);
631 }
632 if ( argc == 1 ){
633
634#ifdef DUMP_MORE_STATE
635 for(i=0; i<NR_CPUS; i++) {
636 int cpus_per_line = 4;
637 if(cpu_online(i)) {
638 if (j++ % cpus_per_line)
639 printk(" %3d",i);
640 else
641 printk("\n %3d",i);
642 }
643 }
644 printk("\n");
645#else
646 printk("\n 0\n");
647#endif
648 } else if((argc==2) && !(strcmp(argv[1],"-l"))) {
649 printk("\nCPUSTATE TASK CPUNUM CPUID HARDCPU(HPA)\n");
650#ifdef DUMP_MORE_STATE
651 for(i=0;i<NR_CPUS;i++) {
652 if (!cpu_online(i))
653 continue;
654 if (cpu_data[i].cpuid != NO_PROC_ID) {
655 switch(cpu_data[i].state) {
656 case STATE_RENDEZVOUS:
657 printk("RENDEZVS ");
658 break;
659 case STATE_RUNNING:
660 printk((current_pid(i)!=0) ? "RUNNING " : "IDLING ");
661 break;
662 case STATE_STOPPED:
663 printk("STOPPED ");
664 break;
665 case STATE_HALTED:
666 printk("HALTED ");
667 break;
668 default:
669 printk("%08x?", cpu_data[i].state);
670 break;
671 }
672 if(cpu_online(i)) {
673 printk(" %4d",current_pid(i));
674 }
675 printk(" %6d",cpu_number_map(i));
676 printk(" %5d",i);
677 printk(" 0x%lx\n",cpu_data[i].hpa);
678 }
679 }
680#else
681 printk("\n%s %4d 0 0 --------",
682 (current->pid)?"RUNNING ": "IDLING ",current->pid);
683#endif
684 } else if ((argc==2) && !(strcmp(argv[1],"-s"))) {
685#ifdef DUMP_MORE_STATE
686 printk("\nCPUSTATE CPUID\n");
687 for (i=0;i<NR_CPUS;i++) {
688 if (!cpu_online(i))
689 continue;
690 if (cpu_data[i].cpuid != NO_PROC_ID) {
691 switch(cpu_data[i].state) {
692 case STATE_RENDEZVOUS:
693 printk("RENDEZVS");break;
694 case STATE_RUNNING:
695 printk((current_pid(i)!=0) ? "RUNNING " : "IDLING");
696 break;
697 case STATE_STOPPED:
698 printk("STOPPED ");break;
699 case STATE_HALTED:
700 printk("HALTED ");break;
701 default:
702 }
703 printk(" %5d\n",i);
704 }
705 }
706#else
707 printk("\n%s CPU0",(current->pid==0)?"RUNNING ":"IDLING ");
708#endif
709 } else {
710 printk("sys_cpus:Unknown request\n");
711 return (-1);
712 }
713 return 0;
714}
715#endif /* ENTRY_SYS_CPUS */
716
717#ifdef CONFIG_PROC_FS
718int __init
719setup_profiling_timer(unsigned int multiplier)
720{
721 return -EINVAL;
722}
723#endif
diff --git a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h
new file mode 100644
index 000000000000..06c2090cfaba
--- /dev/null
+++ b/arch/parisc/kernel/sys32.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2002 Richard Hirst <rhirst at parisc-linux.org>
3 * Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
4 * Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef _PARISC64_KERNEL_SYS32_H
21#define _PARISC64_KERNEL_SYS32_H
22
23#include <linux/compat.h>
24
25/* Call a kernel syscall which will use kernel space instead of user
26 * space for its copy_to/from_user.
27 */
28#define KERNEL_SYSCALL(ret, syscall, args...) \
29{ \
30 mm_segment_t old_fs = get_fs(); \
31 set_fs(KERNEL_DS); \
32 ret = syscall(args); \
33 set_fs (old_fs); \
34}
35
36#ifdef CONFIG_COMPAT
37
38typedef __u32 __sighandler_t32;
39
40struct sigaction32 {
41 __sighandler_t32 sa_handler;
42 unsigned int sa_flags;
43 compat_sigset_t sa_mask; /* mask last for extensibility */
44};
45
46#endif
47
48#endif
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
new file mode 100644
index 000000000000..7958cd8c8bf8
--- /dev/null
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -0,0 +1,253 @@
1
2/*
3 * PARISC specific syscalls
4 *
5 * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
6 * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
7 * Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <asm/uaccess.h>
26#include <linux/file.h>
27#include <linux/fs.h>
28#include <linux/linkage.h>
29#include <linux/mm.h>
30#include <linux/mman.h>
31#include <linux/shm.h>
32#include <linux/smp_lock.h>
33#include <linux/syscalls.h>
34
35int sys_pipe(int __user *fildes)
36{
37 int fd[2];
38 int error;
39
40 error = do_pipe(fd);
41 if (!error) {
42 if (copy_to_user(fildes, fd, 2*sizeof(int)))
43 error = -EFAULT;
44 }
45 return error;
46}
47
48static unsigned long get_unshared_area(unsigned long addr, unsigned long len)
49{
50 struct vm_area_struct *vma;
51
52 addr = PAGE_ALIGN(addr);
53
54 for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
55 /* At this point: (!vma || addr < vma->vm_end). */
56 if (TASK_SIZE - len < addr)
57 return -ENOMEM;
58 if (!vma || addr + len <= vma->vm_start)
59 return addr;
60 addr = vma->vm_end;
61 }
62}
63
64#define DCACHE_ALIGN(addr) (((addr) + (SHMLBA - 1)) &~ (SHMLBA - 1))
65
66/*
67 * We need to know the offset to use. Old scheme was to look for
68 * existing mapping and use the same offset. New scheme is to use the
69 * address of the kernel data structure as the seed for the offset.
70 * We'll see how that works...
71 *
72 * The mapping is cacheline aligned, so there's no information in the bottom
73 * few bits of the address. We're looking for 10 bits (4MB / 4k), so let's
74 * drop the bottom 8 bits and use bits 8-17.
75 */
76static int get_offset(struct address_space *mapping)
77{
78 int offset = (unsigned long) mapping << (PAGE_SHIFT - 8);
79 return offset & 0x3FF000;
80}
81
82static unsigned long get_shared_area(struct address_space *mapping,
83 unsigned long addr, unsigned long len, unsigned long pgoff)
84{
85 struct vm_area_struct *vma;
86 int offset = mapping ? get_offset(mapping) : 0;
87
88 addr = DCACHE_ALIGN(addr - offset) + offset;
89
90 for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
91 /* At this point: (!vma || addr < vma->vm_end). */
92 if (TASK_SIZE - len < addr)
93 return -ENOMEM;
94 if (!vma || addr + len <= vma->vm_start)
95 return addr;
96 addr = DCACHE_ALIGN(vma->vm_end - offset) + offset;
97 if (addr < vma->vm_end) /* handle wraparound */
98 return -ENOMEM;
99 }
100}
101
102unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
103 unsigned long len, unsigned long pgoff, unsigned long flags)
104{
105 if (len > TASK_SIZE)
106 return -ENOMEM;
107 if (!addr)
108 addr = TASK_UNMAPPED_BASE;
109
110 if (filp) {
111 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
112 } else if(flags & MAP_SHARED) {
113 addr = get_shared_area(NULL, addr, len, pgoff);
114 } else {
115 addr = get_unshared_area(addr, len);
116 }
117 return addr;
118}
119
120static unsigned long do_mmap2(unsigned long addr, unsigned long len,
121 unsigned long prot, unsigned long flags, unsigned long fd,
122 unsigned long pgoff)
123{
124 struct file * file = NULL;
125 unsigned long error = -EBADF;
126 if (!(flags & MAP_ANONYMOUS)) {
127 file = fget(fd);
128 if (!file)
129 goto out;
130 }
131
132 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
133
134 down_write(&current->mm->mmap_sem);
135 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
136 up_write(&current->mm->mmap_sem);
137
138 if (file != NULL)
139 fput(file);
140out:
141 return error;
142}
143
144asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
145 unsigned long prot, unsigned long flags, unsigned long fd,
146 unsigned long pgoff)
147{
148 /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
149 we have. */
150 return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
151}
152
153asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
154 unsigned long prot, unsigned long flags, unsigned long fd,
155 unsigned long offset)
156{
157 if (!(offset & ~PAGE_MASK)) {
158 return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
159 } else {
160 return -EINVAL;
161 }
162}
163
164long sys_shmat_wrapper(int shmid, char __user *shmaddr, int shmflag)
165{
166 unsigned long raddr;
167 int r;
168
169 r = do_shmat(shmid, shmaddr, shmflag, &raddr);
170 if (r < 0)
171 return r;
172 return raddr;
173}
174
175/* Fucking broken ABI */
176
177#ifdef CONFIG_64BIT
178asmlinkage long parisc_truncate64(const char __user * path,
179 unsigned int high, unsigned int low)
180{
181 return sys_truncate(path, (long)high << 32 | low);
182}
183
184asmlinkage long parisc_ftruncate64(unsigned int fd,
185 unsigned int high, unsigned int low)
186{
187 return sys_ftruncate(fd, (long)high << 32 | low);
188}
189
190/* stubs for the benefit of the syscall_table since truncate64 and truncate
191 * are identical on LP64 */
192asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
193{
194 return sys_truncate(path, length);
195}
196asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
197{
198 return sys_ftruncate(fd, length);
199}
200asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
201{
202 return sys_fcntl(fd, cmd, arg);
203}
204#else
205
206asmlinkage long parisc_truncate64(const char __user * path,
207 unsigned int high, unsigned int low)
208{
209 return sys_truncate64(path, (loff_t)high << 32 | low);
210}
211
212asmlinkage long parisc_ftruncate64(unsigned int fd,
213 unsigned int high, unsigned int low)
214{
215 return sys_ftruncate64(fd, (loff_t)high << 32 | low);
216}
217#endif
218
219asmlinkage ssize_t parisc_pread64(unsigned int fd, char __user *buf, size_t count,
220 unsigned int high, unsigned int low)
221{
222 return sys_pread64(fd, buf, count, (loff_t)high << 32 | low);
223}
224
225asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char __user *buf,
226 size_t count, unsigned int high, unsigned int low)
227{
228 return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low);
229}
230
231asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low,
232 size_t count)
233{
234 return sys_readahead(fd, (loff_t)high << 32 | low, count);
235}
236
237asmlinkage long parisc_fadvise64_64(int fd,
238 unsigned int high_off, unsigned int low_off,
239 unsigned int high_len, unsigned int low_len, int advice)
240{
241 return sys_fadvise64_64(fd, (loff_t)high_off << 32 | low_off,
242 (loff_t)high_len << 32 | low_len, advice);
243}
244
245asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag)
246{
247 return -ENOMEM;
248}
249
250asmlinkage int sys_free_hugepages(unsigned long addr)
251{
252 return -EINVAL;
253}
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
new file mode 100644
index 000000000000..613569018410
--- /dev/null
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -0,0 +1,720 @@
1/*
2 * sys_parisc32.c: Conversion between 32bit and 64bit native syscalls.
3 *
4 * Copyright (C) 2000-2001 Hewlett Packard Company
5 * Copyright (C) 2000 John Marvin
6 * Copyright (C) 2001 Matthew Wilcox
7 *
8 * These routines maintain argument size conversion between 32bit and 64bit
9 * environment. Based heavily on sys_ia32.c and sys_sparc32.c.
10 */
11
12#include <linux/config.h>
13#include <linux/compat.h>
14#include <linux/kernel.h>
15#include <linux/sched.h>
16#include <linux/fs.h>
17#include <linux/mm.h>
18#include <linux/file.h>
19#include <linux/signal.h>
20#include <linux/resource.h>
21#include <linux/times.h>
22#include <linux/utsname.h>
23#include <linux/time.h>
24#include <linux/timex.h>
25#include <linux/smp.h>
26#include <linux/smp_lock.h>
27#include <linux/sem.h>
28#include <linux/msg.h>
29#include <linux/shm.h>
30#include <linux/slab.h>
31#include <linux/uio.h>
32#include <linux/nfs_fs.h>
33#include <linux/ncp_fs.h>
34#include <linux/sunrpc/svc.h>
35#include <linux/nfsd/nfsd.h>
36#include <linux/nfsd/cache.h>
37#include <linux/nfsd/xdr.h>
38#include <linux/nfsd/syscall.h>
39#include <linux/poll.h>
40#include <linux/personality.h>
41#include <linux/stat.h>
42#include <linux/highmem.h>
43#include <linux/highuid.h>
44#include <linux/mman.h>
45#include <linux/binfmts.h>
46#include <linux/namei.h>
47#include <linux/vfs.h>
48#include <linux/ptrace.h>
49#include <linux/swap.h>
50#include <linux/syscalls.h>
51
52#include <asm/types.h>
53#include <asm/uaccess.h>
54#include <asm/semaphore.h>
55#include <asm/mmu_context.h>
56
57#include "sys32.h"
58
59#undef DEBUG
60
61#ifdef DEBUG
62#define DBG(x) printk x
63#else
64#define DBG(x)
65#endif
66
67/*
68 * sys32_execve() executes a new program.
69 */
70
71asmlinkage int sys32_execve(struct pt_regs *regs)
72{
73 int error;
74 char *filename;
75
76 DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26]));
77 filename = getname((const char __user *) regs->gr[26]);
78 error = PTR_ERR(filename);
79 if (IS_ERR(filename))
80 goto out;
81 error = compat_do_execve(filename, compat_ptr(regs->gr[25]),
82 compat_ptr(regs->gr[24]), regs);
83 if (error == 0) {
84 task_lock(current);
85 current->ptrace &= ~PT_DTRACE;
86 task_unlock(current);
87 }
88 putname(filename);
89out:
90
91 return error;
92}
93
94asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
95 int r22, int r21, int r20)
96{
97 printk(KERN_ERR "%s(%d): Unimplemented 32 on 64 syscall #%d!\n",
98 current->comm, current->pid, r20);
99 return -ENOSYS;
100}
101
102#ifdef CONFIG_SYSCTL
103
104struct __sysctl_args32 {
105 u32 name;
106 int nlen;
107 u32 oldval;
108 u32 oldlenp;
109 u32 newval;
110 u32 newlen;
111 u32 __unused[4];
112};
113
114asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
115{
116 struct __sysctl_args32 tmp;
117 int error;
118 unsigned int oldlen32;
119 size_t oldlen, *oldlenp = NULL;
120 unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7;
121 extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
122 void *newval, size_t newlen);
123
124 DBG(("sysctl32(%p)\n", args));
125
126 if (copy_from_user(&tmp, args, sizeof(tmp)))
127 return -EFAULT;
128
129 if (tmp.oldval && tmp.oldlenp) {
130 /* Duh, this is ugly and might not work if sysctl_args
131 is in read-only memory, but do_sysctl does indirectly
132 a lot of uaccess in both directions and we'd have to
133 basically copy the whole sysctl.c here, and
134 glibc's __sysctl uses rw memory for the structure
135 anyway. */
136 /* a possibly better hack than this, which will avoid the
137 * problem if the struct is read only, is to push the
138 * 'oldlen' value out to the user's stack instead. -PB
139 */
140 if (get_user(oldlen32, (u32 *)(u64)tmp.oldlenp))
141 return -EFAULT;
142 oldlen = oldlen32;
143 if (put_user(oldlen, (size_t *)addr))
144 return -EFAULT;
145 oldlenp = (size_t *)addr;
146 }
147
148 lock_kernel();
149 error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval,
150 oldlenp, (void *)(u64)tmp.newval, tmp.newlen);
151 unlock_kernel();
152 if (oldlenp) {
153 if (!error) {
154 if (get_user(oldlen, (size_t *)addr)) {
155 error = -EFAULT;
156 } else {
157 oldlen32 = oldlen;
158 if (put_user(oldlen32, (u32 *)(u64)tmp.oldlenp))
159 error = -EFAULT;
160 }
161 }
162 if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused)))
163 error = -EFAULT;
164 }
165 return error;
166}
167
168#endif /* CONFIG_SYSCTL */
169
170asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
171 struct compat_timespec __user *interval)
172{
173 struct timespec t;
174 int ret;
175
176 KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, (struct timespec __user *)&t);
177 if (put_compat_timespec(&t, interval))
178 return -EFAULT;
179 return ret;
180}
181
182static int
183put_compat_timeval(struct compat_timeval __user *u, struct timeval *t)
184{
185 struct compat_timeval t32;
186 t32.tv_sec = t->tv_sec;
187 t32.tv_usec = t->tv_usec;
188 return copy_to_user(u, &t32, sizeof t32);
189}
190
191static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
192{
193 long usec;
194
195 if (__get_user(o->tv_sec, &i->tv_sec))
196 return -EFAULT;
197 if (__get_user(usec, &i->tv_usec))
198 return -EFAULT;
199 o->tv_nsec = usec * 1000;
200 return 0;
201}
202
203asmlinkage int
204sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
205{
206 extern void do_gettimeofday(struct timeval *tv);
207
208 if (tv) {
209 struct timeval ktv;
210 do_gettimeofday(&ktv);
211 if (put_compat_timeval(tv, &ktv))
212 return -EFAULT;
213 }
214 if (tz) {
215 extern struct timezone sys_tz;
216 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
217 return -EFAULT;
218 }
219 return 0;
220}
221
222asmlinkage
223int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
224{
225 struct timespec kts;
226 struct timezone ktz;
227
228 if (tv) {
229 if (get_ts32(&kts, tv))
230 return -EFAULT;
231 }
232 if (tz) {
233 if (copy_from_user(&ktz, tz, sizeof(ktz)))
234 return -EFAULT;
235 }
236
237 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
238}
239
240int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
241{
242 int err;
243
244 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
245 !new_valid_dev(stat->rdev))
246 return -EOVERFLOW;
247
248 err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
249 err |= put_user(stat->ino, &statbuf->st_ino);
250 err |= put_user(stat->mode, &statbuf->st_mode);
251 err |= put_user(stat->nlink, &statbuf->st_nlink);
252 err |= put_user(0, &statbuf->st_reserved1);
253 err |= put_user(0, &statbuf->st_reserved2);
254 err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
255 err |= put_user(stat->size, &statbuf->st_size);
256 err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
257 err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
258 err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
259 err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
260 err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
261 err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
262 err |= put_user(stat->blksize, &statbuf->st_blksize);
263 err |= put_user(stat->blocks, &statbuf->st_blocks);
264 err |= put_user(0, &statbuf->__unused1);
265 err |= put_user(0, &statbuf->__unused2);
266 err |= put_user(0, &statbuf->__unused3);
267 err |= put_user(0, &statbuf->__unused4);
268 err |= put_user(0, &statbuf->__unused5);
269 err |= put_user(0, &statbuf->st_fstype); /* not avail */
270 err |= put_user(0, &statbuf->st_realdev); /* not avail */
271 err |= put_user(0, &statbuf->st_basemode); /* not avail */
272 err |= put_user(0, &statbuf->st_spareshort);
273 err |= put_user(stat->uid, &statbuf->st_uid);
274 err |= put_user(stat->gid, &statbuf->st_gid);
275 err |= put_user(0, &statbuf->st_spare4[0]);
276 err |= put_user(0, &statbuf->st_spare4[1]);
277 err |= put_user(0, &statbuf->st_spare4[2]);
278
279 return err;
280}
281
282struct linux32_dirent {
283 u32 d_ino;
284 compat_off_t d_off;
285 u16 d_reclen;
286 char d_name[1];
287};
288
289struct old_linux32_dirent {
290 u32 d_ino;
291 u32 d_offset;
292 u16 d_namlen;
293 char d_name[1];
294};
295
296struct getdents32_callback {
297 struct linux32_dirent __user * current_dir;
298 struct linux32_dirent __user * previous;
299 int count;
300 int error;
301};
302
303struct readdir32_callback {
304 struct old_linux32_dirent __user * dirent;
305 int count;
306};
307
308#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
309#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
310static int
311filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
312 unsigned int d_type)
313{
314 struct linux32_dirent __user * dirent;
315 struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
316 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
317
318 buf->error = -EINVAL; /* only used if we fail.. */
319 if (reclen > buf->count)
320 return -EINVAL;
321 dirent = buf->previous;
322 if (dirent)
323 put_user(offset, &dirent->d_off);
324 dirent = buf->current_dir;
325 buf->previous = dirent;
326 put_user(ino, &dirent->d_ino);
327 put_user(reclen, &dirent->d_reclen);
328 copy_to_user(dirent->d_name, name, namlen);
329 put_user(0, dirent->d_name + namlen);
330 dirent = ((void __user *)dirent) + reclen;
331 buf->current_dir = dirent;
332 buf->count -= reclen;
333 return 0;
334}
335
336asmlinkage long
337sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count)
338{
339 struct file * file;
340 struct linux32_dirent __user * lastdirent;
341 struct getdents32_callback buf;
342 int error;
343
344 error = -EBADF;
345 file = fget(fd);
346 if (!file)
347 goto out;
348
349 buf.current_dir = (struct linux32_dirent __user *) dirent;
350 buf.previous = NULL;
351 buf.count = count;
352 buf.error = 0;
353
354 error = vfs_readdir(file, filldir32, &buf);
355 if (error < 0)
356 goto out_putf;
357 error = buf.error;
358 lastdirent = buf.previous;
359 if (lastdirent) {
360 put_user(file->f_pos, &lastdirent->d_off);
361 error = count - buf.count;
362 }
363
364out_putf:
365 fput(file);
366out:
367 return error;
368}
369
370static int
371fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
372 unsigned int d_type)
373{
374 struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
375 struct old_linux32_dirent __user * dirent;
376
377 if (buf->count)
378 return -EINVAL;
379 buf->count++;
380 dirent = buf->dirent;
381 put_user(ino, &dirent->d_ino);
382 put_user(offset, &dirent->d_offset);
383 put_user(namlen, &dirent->d_namlen);
384 copy_to_user(dirent->d_name, name, namlen);
385 put_user(0, dirent->d_name + namlen);
386 return 0;
387}
388
389asmlinkage long
390sys32_readdir (unsigned int fd, void __user * dirent, unsigned int count)
391{
392 int error;
393 struct file * file;
394 struct readdir32_callback buf;
395
396 error = -EBADF;
397 file = fget(fd);
398 if (!file)
399 goto out;
400
401 buf.count = 0;
402 buf.dirent = dirent;
403
404 error = vfs_readdir(file, fillonedir32, &buf);
405 if (error >= 0)
406 error = buf.count;
407 fput(file);
408out:
409 return error;
410}
411
412/*** copied from mips64 ***/
413/*
414 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
415 * 64-bit unsigned longs.
416 */
417
418static inline int
419get_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
420{
421 n = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
422 if (ufdset) {
423 unsigned long odd;
424
425 if (!access_ok(VERIFY_WRITE, ufdset, n*sizeof(u32)))
426 return -EFAULT;
427
428 odd = n & 1UL;
429 n &= ~1UL;
430 while (n) {
431 unsigned long h, l;
432 __get_user(l, ufdset);
433 __get_user(h, ufdset+1);
434 ufdset += 2;
435 *fdset++ = h << 32 | l;
436 n -= 2;
437 }
438 if (odd)
439 __get_user(*fdset, ufdset);
440 } else {
441 /* Tricky, must clear full unsigned long in the
442 * kernel fdset at the end, this makes sure that
443 * actually happens.
444 */
445 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
446 }
447 return 0;
448}
449
450static inline void
451set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
452{
453 unsigned long odd;
454 n = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
455
456 if (!ufdset)
457 return;
458
459 odd = n & 1UL;
460 n &= ~1UL;
461 while (n) {
462 unsigned long h, l;
463 l = *fdset++;
464 h = l >> 32;
465 __put_user(l, ufdset);
466 __put_user(h, ufdset+1);
467 ufdset += 2;
468 n -= 2;
469 }
470 if (odd)
471 __put_user(*fdset, ufdset);
472}
473
474struct msgbuf32 {
475 int mtype;
476 char mtext[1];
477};
478
479asmlinkage long sys32_msgsnd(int msqid,
480 struct msgbuf32 __user *umsgp32,
481 size_t msgsz, int msgflg)
482{
483 struct msgbuf *mb;
484 struct msgbuf32 mb32;
485 int err;
486
487 if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
488 return -ENOMEM;
489
490 err = get_user(mb32.mtype, &umsgp32->mtype);
491 mb->mtype = mb32.mtype;
492 err |= copy_from_user(mb->mtext, &umsgp32->mtext, msgsz);
493
494 if (err)
495 err = -EFAULT;
496 else
497 KERNEL_SYSCALL(err, sys_msgsnd, msqid, (struct msgbuf __user *)mb, msgsz, msgflg);
498
499 kfree(mb);
500 return err;
501}
502
503asmlinkage long sys32_msgrcv(int msqid,
504 struct msgbuf32 __user *umsgp32,
505 size_t msgsz, long msgtyp, int msgflg)
506{
507 struct msgbuf *mb;
508 struct msgbuf32 mb32;
509 int err, len;
510
511 if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
512 return -ENOMEM;
513
514 KERNEL_SYSCALL(err, sys_msgrcv, msqid, (struct msgbuf __user *)mb, msgsz, msgtyp, msgflg);
515
516 if (err >= 0) {
517 len = err;
518 mb32.mtype = mb->mtype;
519 err = put_user(mb32.mtype, &umsgp32->mtype);
520 err |= copy_to_user(&umsgp32->mtext, mb->mtext, len);
521 if (err)
522 err = -EFAULT;
523 else
524 err = len;
525 }
526
527 kfree(mb);
528 return err;
529}
530
531asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
532{
533 mm_segment_t old_fs = get_fs();
534 int ret;
535 off_t of;
536
537 if (offset && get_user(of, offset))
538 return -EFAULT;
539
540 set_fs(KERNEL_DS);
541 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
542 set_fs(old_fs);
543
544 if (offset && put_user(of, offset))
545 return -EFAULT;
546
547 return ret;
548}
549
550asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
551{
552 mm_segment_t old_fs = get_fs();
553 int ret;
554 loff_t lof;
555
556 if (offset && get_user(lof, offset))
557 return -EFAULT;
558
559 set_fs(KERNEL_DS);
560 ret = sys_sendfile64(out_fd, in_fd, offset ? (loff_t __user *)&lof : NULL, count);
561 set_fs(old_fs);
562
563 if (offset && put_user(lof, offset))
564 return -EFAULT;
565
566 return ret;
567}
568
569
570struct timex32 {
571 unsigned int modes; /* mode selector */
572 int offset; /* time offset (usec) */
573 int freq; /* frequency offset (scaled ppm) */
574 int maxerror; /* maximum error (usec) */
575 int esterror; /* estimated error (usec) */
576 int status; /* clock command/status */
577 int constant; /* pll time constant */
578 int precision; /* clock precision (usec) (read only) */
579 int tolerance; /* clock frequency tolerance (ppm)
580 * (read only)
581 */
582 struct compat_timeval time; /* (read only) */
583 int tick; /* (modified) usecs between clock ticks */
584
585 int ppsfreq; /* pps frequency (scaled ppm) (ro) */
586 int jitter; /* pps jitter (us) (ro) */
587 int shift; /* interval duration (s) (shift) (ro) */
588 int stabil; /* pps stability (scaled ppm) (ro) */
589 int jitcnt; /* jitter limit exceeded (ro) */
590 int calcnt; /* calibration intervals (ro) */
591 int errcnt; /* calibration errors (ro) */
592 int stbcnt; /* stability limit exceeded (ro) */
593
594 int :32; int :32; int :32; int :32;
595 int :32; int :32; int :32; int :32;
596 int :32; int :32; int :32; int :32;
597};
598
599asmlinkage long sys32_adjtimex(struct timex32 __user *txc_p32)
600{
601 struct timex txc;
602 struct timex32 t32;
603 int ret;
604 extern int do_adjtimex(struct timex *txc);
605
606 if(copy_from_user(&t32, txc_p32, sizeof(struct timex32)))
607 return -EFAULT;
608#undef CP
609#define CP(x) txc.x = t32.x
610 CP(modes); CP(offset); CP(freq); CP(maxerror); CP(esterror);
611 CP(status); CP(constant); CP(precision); CP(tolerance);
612 CP(time.tv_sec); CP(time.tv_usec); CP(tick); CP(ppsfreq); CP(jitter);
613 CP(shift); CP(stabil); CP(jitcnt); CP(calcnt); CP(errcnt);
614 CP(stbcnt);
615 ret = do_adjtimex(&txc);
616#undef CP
617#define CP(x) t32.x = txc.x
618 CP(modes); CP(offset); CP(freq); CP(maxerror); CP(esterror);
619 CP(status); CP(constant); CP(precision); CP(tolerance);
620 CP(time.tv_sec); CP(time.tv_usec); CP(tick); CP(ppsfreq); CP(jitter);
621 CP(shift); CP(stabil); CP(jitcnt); CP(calcnt); CP(errcnt);
622 CP(stbcnt);
623 return copy_to_user(txc_p32, &t32, sizeof(struct timex32)) ? -EFAULT : ret;
624}
625
626
627struct sysinfo32 {
628 s32 uptime;
629 u32 loads[3];
630 u32 totalram;
631 u32 freeram;
632 u32 sharedram;
633 u32 bufferram;
634 u32 totalswap;
635 u32 freeswap;
636 unsigned short procs;
637 u32 totalhigh;
638 u32 freehigh;
639 u32 mem_unit;
640 char _f[12];
641};
642
643/* We used to call sys_sysinfo and translate the result. But sys_sysinfo
644 * undoes the good work done elsewhere, and rather than undoing the
645 * damage, I decided to just duplicate the code from sys_sysinfo here.
646 */
647
648asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info)
649{
650 struct sysinfo val;
651 int err;
652 unsigned long seq;
653
654 /* We don't need a memset here because we copy the
655 * struct to userspace once element at a time.
656 */
657
658 do {
659 seq = read_seqbegin(&xtime_lock);
660 val.uptime = jiffies / HZ;
661
662 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
663 val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
664 val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
665
666 val.procs = nr_threads;
667 } while (read_seqretry(&xtime_lock, seq));
668
669
670 si_meminfo(&val);
671 si_swapinfo(&val);
672
673 err = put_user (val.uptime, &info->uptime);
674 err |= __put_user (val.loads[0], &info->loads[0]);
675 err |= __put_user (val.loads[1], &info->loads[1]);
676 err |= __put_user (val.loads[2], &info->loads[2]);
677 err |= __put_user (val.totalram, &info->totalram);
678 err |= __put_user (val.freeram, &info->freeram);
679 err |= __put_user (val.sharedram, &info->sharedram);
680 err |= __put_user (val.bufferram, &info->bufferram);
681 err |= __put_user (val.totalswap, &info->totalswap);
682 err |= __put_user (val.freeswap, &info->freeswap);
683 err |= __put_user (val.procs, &info->procs);
684 err |= __put_user (val.totalhigh, &info->totalhigh);
685 err |= __put_user (val.freehigh, &info->freehigh);
686 err |= __put_user (val.mem_unit, &info->mem_unit);
687 return err ? -EFAULT : 0;
688}
689
690
691/* lseek() needs a wrapper because 'offset' can be negative, but the top
692 * half of the argument has been zeroed by syscall.S.
693 */
694
695asmlinkage int sys32_lseek(unsigned int fd, int offset, unsigned int origin)
696{
697 return sys_lseek(fd, offset, origin);
698}
699
700asmlinkage long sys32_semctl(int semid, int semnum, int cmd, union semun arg)
701{
702 union semun u;
703
704 if (cmd == SETVAL) {
705 /* Ugh. arg is a union of int,ptr,ptr,ptr, so is 8 bytes.
706 * The int should be in the first 4, but our argument
707 * frobbing has left it in the last 4.
708 */
709 u.val = *((int *)&arg + 1);
710 return sys_semctl (semid, semnum, cmd, u);
711 }
712 return sys_semctl (semid, semnum, cmd, arg);
713}
714
715long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf,
716 size_t len)
717{
718 return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
719 buf, len);
720}
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
new file mode 100644
index 000000000000..32ea701f4d20
--- /dev/null
+++ b/arch/parisc/kernel/syscall.S
@@ -0,0 +1,703 @@
1/*
2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
3 *
4 * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
5 * Licensed under the GNU GPL.
6 * thanks to Philipp Rumpf, Mike Shaver and various others
7 * sorry about the wall, puffin..
8 */
9
10#include <asm/offsets.h>
11#include <asm/unistd.h>
12#include <asm/errno.h>
13#include <asm/psw.h>
14#include <asm/thread_info.h>
15
16#include <asm/assembly.h>
17#include <asm/processor.h>
18
19 /* We fill the empty parts of the gateway page with
20 * something that will kill the kernel or a
21 * userspace application.
22 */
23#define KILL_INSN break 0,0
24
25#include <linux/config.h> /* for CONFIG_SMP */
26
27#ifdef __LP64__
28 .level 2.0w
29#else
30 .level 1.1
31#endif
32
33#ifndef __LP64__
34 .macro fixup_branch,lbl
35 b \lbl
36 .endm
37#else
38 .macro fixup_branch,lbl
39 ldil L%\lbl, %r1
40 ldo R%\lbl(%r1), %r1
41 bv,n %r0(%r1)
42 .endm
43#endif
44
45 .text
46
47 .import syscall_exit,code
48 .import syscall_exit_rfi,code
49 .export linux_gateway_page
50
51 /* Linux gateway page is aliased to virtual page 0 in the kernel
52 * address space. Since it is a gateway page it cannot be
53 * dereferenced, so null pointers will still fault. We start
54 * the actual entry point at 0x100. We put break instructions
55 * at the beginning of the page to trap null indirect function
56 * pointers.
57 */
58
59 .align 4096
60linux_gateway_page:
61
62 /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
63 .rept 44
64 KILL_INSN
65 .endr
66
67 /* ADDRESS 0xb0 to 0xb4, lws uses 1 insns for entry */
68 /* Light-weight-syscall entry must always be located at 0xb0 */
69 /* WARNING: Keep this number updated with table size changes */
70#define __NR_lws_entries (2)
71
72lws_entry:
73 /* Unconditional branch to lws_start, located on the
74 same gateway page */
75 b,n lws_start
76
77 /* Fill from 0xb4 to 0xe0 */
78 .rept 11
79 KILL_INSN
80 .endr
81
82 /* This function MUST be located at 0xe0 for glibc's threading
83 mechanism to work. DO NOT MOVE THIS CODE EVER! */
84set_thread_pointer:
85 gate .+8, %r0 /* increase privilege */
86 depi 3, 31, 2, %r31 /* Ensure we return into user mode. */
87 be 0(%sr7,%r31) /* return to user space */
88 mtctl %r26, %cr27 /* move arg0 to the control register */
89
90 /* Increase the chance of trapping if random jumps occur to this
91 address, fill from 0xf0 to 0x100 */
92 .rept 4
93 KILL_INSN
94 .endr
95
96/* This address must remain fixed at 0x100 for glibc's syscalls to work */
97 .align 256
98linux_gateway_entry:
99 gate .+8, %r0 /* become privileged */
100 mtsp %r0,%sr4 /* get kernel space into sr4 */
101 mtsp %r0,%sr5 /* get kernel space into sr5 */
102 mtsp %r0,%sr6 /* get kernel space into sr6 */
103 mfsp %sr7,%r1 /* save user sr7 */
104 mtsp %r1,%sr3 /* and store it in sr3 */
105
106#ifdef __LP64__
107 /* for now we can *always* set the W bit on entry to the syscall
108 * since we don't support wide userland processes. We could
109 * also save the current SM other than in r0 and restore it on
110 * exit from the syscall, and also use that value to know
111 * whether to do narrow or wide syscalls. -PB
112 */
113 ssm PSW_SM_W, %r1
114 extrd,u %r1,PSW_W_BIT,1,%r1
115 /* sp must be aligned on 4, so deposit the W bit setting into
116 * the bottom of sp temporarily */
117 or,ev %r1,%r30,%r30
118 b,n 1f
119 /* The top halves of argument registers must be cleared on syscall
120 * entry from narrow executable.
121 */
122 depdi 0, 31, 32, %r26
123 depdi 0, 31, 32, %r25
124 depdi 0, 31, 32, %r24
125 depdi 0, 31, 32, %r23
126 depdi 0, 31, 32, %r22
127 depdi 0, 31, 32, %r21
1281:
129#endif
130 mfctl %cr30,%r1
131 xor %r1,%r30,%r30 /* ye olde xor trick */
132 xor %r1,%r30,%r1
133 xor %r1,%r30,%r30
134
135 ldo THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */
136
137 /* N.B.: It is critical that we don't set sr7 to 0 until r30
138 * contains a valid kernel stack pointer. It is also
139 * critical that we don't start using the kernel stack
140 * until after sr7 has been set to 0.
141 */
142
143 mtsp %r0,%sr7 /* get kernel space into sr7 */
144 STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */
145 mfctl %cr30,%r1 /* get task ptr in %r1 */
146 LDREG TI_TASK(%r1),%r1
147
148 /* Save some registers for sigcontext and potential task
149 switch (see entry.S for the details of which ones are
150 saved/restored). TASK_PT_PSW is zeroed so we can see whether
151 a process is on a syscall or not. For an interrupt the real
152 PSW value is stored. This is needed for gdb and sys_ptrace. */
153 STREG %r0, TASK_PT_PSW(%r1)
154 STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */
155 STREG %r19, TASK_PT_GR19(%r1)
156
157 LDREGM -FRAME_SIZE(%r30), %r2 /* get users sp back */
158#ifdef __LP64__
159 extrd,u %r2,63,1,%r19 /* W hidden in bottom bit */
160#if 0
161 xor %r19,%r2,%r2 /* clear bottom bit */
162 depd,z %r19,1,1,%r19
163 std %r19,TASK_PT_PSW(%r1)
164#endif
165#endif
166 STREG %r2, TASK_PT_GR30(%r1) /* ... and save it */
167
168 STREG %r20, TASK_PT_GR20(%r1)
169 STREG %r21, TASK_PT_GR21(%r1)
170 STREG %r22, TASK_PT_GR22(%r1)
171 STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
172 STREG %r24, TASK_PT_GR24(%r1) /* 3rd argument */
173 STREG %r25, TASK_PT_GR25(%r1) /* 2nd argument */
174 STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
175 STREG %r27, TASK_PT_GR27(%r1) /* user dp */
176 STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
177 STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */
178 STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */
179 STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
180
181 ldo TASK_PT_FR0(%r1), %r27 /* save fpregs from the kernel */
182 save_fp %r27 /* or potential task switch */
183
184 mfctl %cr11, %r27 /* i.e. SAR */
185 STREG %r27, TASK_PT_SAR(%r1)
186
187 loadgp
188
189#ifdef __LP64__
190 ldo -16(%r30),%r29 /* Reference param save area */
191 copy %r19,%r2 /* W bit back to r2 */
192#else
193 /* no need to save these on stack in wide mode because the first 8
194 * args are passed in registers */
195 stw %r22, -52(%r30) /* 5th argument */
196 stw %r21, -56(%r30) /* 6th argument */
197#endif
198
199 /* Are we being ptraced? */
200 mfctl %cr30, %r1
201 LDREG TI_TASK(%r1),%r1
202 LDREG TASK_PTRACE(%r1), %r1
203 bb,<,n %r1,31,.Ltracesys
204
205 /* Note! We cannot use the syscall table that is mapped
206 nearby since the gateway page is mapped execute-only. */
207
208#ifdef __LP64__
209 ldil L%sys_call_table, %r1
210 or,= %r2,%r2,%r2
211 addil L%(sys_call_table64-sys_call_table), %r1
212 ldo R%sys_call_table(%r1), %r19
213 or,= %r2,%r2,%r2
214 ldo R%sys_call_table64(%r1), %r19
215#else
216 ldil L%sys_call_table, %r1
217 ldo R%sys_call_table(%r1), %r19
218#endif
219 comiclr,>>= __NR_Linux_syscalls, %r20, %r0
220 b,n .Lsyscall_nosys
221
222 LDREGX %r20(%r19), %r19
223
224 /* If this is a sys_rt_sigreturn call, and the signal was received
225 * when not in_syscall, then we want to return via syscall_exit_rfi,
226 * not syscall_exit. Signal no. in r20, in_syscall in r25 (see
227 * trampoline code in signal.c).
228 */
229 ldi __NR_rt_sigreturn,%r2
230 comb,= %r2,%r20,.Lrt_sigreturn
231.Lin_syscall:
232 ldil L%syscall_exit,%r2
233 be 0(%sr7,%r19)
234 ldo R%syscall_exit(%r2),%r2
235.Lrt_sigreturn:
236 comib,<> 0,%r25,.Lin_syscall
237 ldil L%syscall_exit_rfi,%r2
238 be 0(%sr7,%r19)
239 ldo R%syscall_exit_rfi(%r2),%r2
240
241 /* Note! Because we are not running where we were linked, any
242 calls to functions external to this file must be indirect. To
243 be safe, we apply the opposite rule to functions within this
244 file, with local labels given to them to ensure correctness. */
245
246.Lsyscall_nosys:
247syscall_nosys:
248 ldil L%syscall_exit,%r1
249 be R%syscall_exit(%sr7,%r1)
250 ldo -ENOSYS(%r0),%r28 /* set errno */
251
252
253/* Warning! This trace code is a virtual duplicate of the code above so be
254 * sure to maintain both! */
255.Ltracesys:
256tracesys:
257 /* Need to save more registers so the debugger can see where we
258 * are. This saves only the lower 8 bits of PSW, so that the C
259 * bit is still clear on syscalls, and the D bit is set if this
260 * full register save path has been executed. We check the D
261 * bit on syscall_return_rfi to determine which registers to
262 * restore. An interrupt results in a full PSW saved with the
263 * C bit set, a non-straced syscall entry results in C and D clear
264 * in the saved PSW.
265 */
266 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
267 LDREG TI_TASK(%r1), %r1
268 ssm 0,%r2
269 STREG %r2,TASK_PT_PSW(%r1) /* Lower 8 bits only!! */
270 mfsp %sr0,%r2
271 STREG %r2,TASK_PT_SR0(%r1)
272 mfsp %sr1,%r2
273 STREG %r2,TASK_PT_SR1(%r1)
274 mfsp %sr2,%r2
275 STREG %r2,TASK_PT_SR2(%r1)
276 mfsp %sr3,%r2
277 STREG %r2,TASK_PT_SR3(%r1)
278 STREG %r2,TASK_PT_SR4(%r1)
279 STREG %r2,TASK_PT_SR5(%r1)
280 STREG %r2,TASK_PT_SR6(%r1)
281 STREG %r2,TASK_PT_SR7(%r1)
282 STREG %r2,TASK_PT_IASQ0(%r1)
283 STREG %r2,TASK_PT_IASQ1(%r1)
284 LDREG TASK_PT_GR31(%r1),%r2
285 STREG %r2,TASK_PT_IAOQ0(%r1)
286 ldo 4(%r2),%r2
287 STREG %r2,TASK_PT_IAOQ1(%r1)
288 ldo TASK_REGS(%r1),%r2
289 /* reg_save %r2 */
290 STREG %r3,PT_GR3(%r2)
291 STREG %r4,PT_GR4(%r2)
292 STREG %r5,PT_GR5(%r2)
293 STREG %r6,PT_GR6(%r2)
294 STREG %r7,PT_GR7(%r2)
295 STREG %r8,PT_GR8(%r2)
296 STREG %r9,PT_GR9(%r2)
297 STREG %r10,PT_GR10(%r2)
298 STREG %r11,PT_GR11(%r2)
299 STREG %r12,PT_GR12(%r2)
300 STREG %r13,PT_GR13(%r2)
301 STREG %r14,PT_GR14(%r2)
302 STREG %r15,PT_GR15(%r2)
303 STREG %r16,PT_GR16(%r2)
304 STREG %r17,PT_GR17(%r2)
305 STREG %r18,PT_GR18(%r2)
306 /* Finished saving things for the debugger */
307
308 ldil L%syscall_trace,%r1
309 ldil L%tracesys_next,%r2
310 be R%syscall_trace(%sr7,%r1)
311 ldo R%tracesys_next(%r2),%r2
312
313tracesys_next:
314 ldil L%sys_call_table,%r1
315 ldo R%sys_call_table(%r1), %r19
316
317 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
318 LDREG TI_TASK(%r1), %r1
319 LDREG TASK_PT_GR20(%r1), %r20
320 LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */
321 LDREG TASK_PT_GR25(%r1), %r25
322 LDREG TASK_PT_GR24(%r1), %r24
323 LDREG TASK_PT_GR23(%r1), %r23
324#ifdef __LP64__
325 LDREG TASK_PT_GR22(%r1), %r22
326 LDREG TASK_PT_GR21(%r1), %r21
327 ldo -16(%r30),%r29 /* Reference param save area */
328#endif
329
330 comiclr,>>= __NR_Linux_syscalls, %r20, %r0
331 b,n .Lsyscall_nosys
332
333 LDREGX %r20(%r19), %r19
334
335 /* If this is a sys_rt_sigreturn call, and the signal was received
336 * when not in_syscall, then we want to return via syscall_exit_rfi,
337 * not syscall_exit. Signal no. in r20, in_syscall in r25 (see
338 * trampoline code in signal.c).
339 */
340 ldi __NR_rt_sigreturn,%r2
341 comb,= %r2,%r20,.Ltrace_rt_sigreturn
342.Ltrace_in_syscall:
343 ldil L%tracesys_exit,%r2
344 be 0(%sr7,%r19)
345 ldo R%tracesys_exit(%r2),%r2
346
347 /* Do *not* call this function on the gateway page, because it
348 makes a direct call to syscall_trace. */
349
350tracesys_exit:
351 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
352 LDREG TI_TASK(%r1), %r1
353#ifdef __LP64__
354 ldo -16(%r30),%r29 /* Reference param save area */
355#endif
356 bl syscall_trace, %r2
357 STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
358 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
359 LDREG TI_TASK(%r1), %r1
360 LDREG TASK_PT_GR28(%r1), %r28 /* Restore return val. */
361
362 ldil L%syscall_exit,%r1
363 be,n R%syscall_exit(%sr7,%r1)
364
365.Ltrace_rt_sigreturn:
366 comib,<> 0,%r25,.Ltrace_in_syscall
367 ldil L%tracesys_sigexit,%r2
368 be 0(%sr7,%r19)
369 ldo R%tracesys_sigexit(%r2),%r2
370
371tracesys_sigexit:
372 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
373 LDREG 0(%r1), %r1
374#ifdef __LP64__
375 ldo -16(%r30),%r29 /* Reference param save area */
376#endif
377 bl syscall_trace, %r2
378 nop
379
380 ldil L%syscall_exit_rfi,%r1
381 be,n R%syscall_exit_rfi(%sr7,%r1)
382
383
384 /*********************************************************
385 Light-weight-syscall code
386
387 r20 - lws number
388 r26,r25,r24,r23,r22 - Input registers
389 r28 - Function return register
390 r21 - Error code.
391
392 Scracth: Any of the above that aren't being
393 currently used, including r1.
394
395 Return pointer: r31 (Not usable)
396
397 Error codes returned by entry path:
398
399 ENOSYS - r20 was an invalid LWS number.
400
401 *********************************************************/
402lws_start:
403 /* Gate and ensure we return to userspace */
404 gate .+8, %r0
405 depi 3, 31, 2, %r31 /* Ensure we return to userspace */
406
407#ifdef __LP64__
408 /* FIXME: If we are a 64-bit kernel just
409 * turn this on unconditionally.
410 */
411 ssm PSW_SM_W, %r1
412 extrd,u %r1,PSW_W_BIT,1,%r1
413 /* sp must be aligned on 4, so deposit the W bit setting into
414 * the bottom of sp temporarily */
415 or,ev %r1,%r30,%r30
416
417 /* Clip LWS number to a 32-bit value always */
418 depdi 0, 31, 32, %r20
419#endif
420
421 /* Is the lws entry number valid? */
422 comiclr,>>= __NR_lws_entries, %r20, %r0
423 b,n lws_exit_nosys
424
425 /* WARNING: Trashing sr2 and sr3 */
426 mfsp %sr7,%r1 /* get userspace into sr3 */
427 mtsp %r1,%sr3
428 mtsp %r0,%sr2 /* get kernel space into sr2 */
429
430 /* Load table start */
431 ldil L%lws_table, %r1
432 ldo R%lws_table(%r1), %r28 /* Scratch use of r28 */
433 LDREGX %r20(%sr2,r28), %r21 /* Scratch use of r21 */
434
435 /* Jump to lws, lws table pointers already relocated */
436 be,n 0(%sr2,%r21)
437
438lws_exit_nosys:
439 ldo -ENOSYS(%r0),%r21 /* set errno */
440 /* Fall through: Return to userspace */
441
442lws_exit:
443#ifdef __LP64__
444 /* decide whether to reset the wide mode bit
445 *
446 * For a syscall, the W bit is stored in the lowest bit
447 * of sp. Extract it and reset W if it is zero */
448 extrd,u,*<> %r30,63,1,%r1
449 rsm PSW_SM_W, %r0
450 /* now reset the lowest bit of sp if it was set */
451 xor %r30,%r1,%r30
452#endif
453 be,n 0(%sr3, %r31)
454
455
456
457 /***************************************************
458 Implementing CAS as an atomic operation:
459
460 %r26 - Address to examine
461 %r25 - Old value to check (old)
462 %r24 - New value to set (new)
463 %r28 - Return prev through this register.
464 %r21 - Kernel error code
465
466 If debugging is DISabled:
467
468 %r21 has the following meanings:
469
470 EAGAIN - CAS is busy, ldcw failed, try again.
471 EFAULT - Read or write failed.
472
473 If debugging is enabled:
474
475 EDEADLOCK - CAS called recursively.
476 EAGAIN && r28 == 1 - CAS is busy. Lock contended.
477 EAGAIN && r28 == 2 - CAS is busy. ldcw failed.
478 EFAULT - Read or write failed.
479
480 Scratch: r20, r28, r1
481
482 ****************************************************/
483
484 /* Do not enable LWS debugging */
485#define ENABLE_LWS_DEBUG 0
486
487 /* ELF64 Process entry path */
488lws_compare_and_swap64:
489#ifdef __LP64__
490 b,n lws_compare_and_swap
491#else
492 /* If we are not a 64-bit kernel, then we don't
493 * implement having 64-bit input registers
494 */
495 b,n lws_exit_nosys
496#endif
497
498 /* ELF32 Process entry path */
499lws_compare_and_swap32:
500#ifdef __LP64__
501 /* Clip all the input registers */
502 depdi 0, 31, 32, %r26
503 depdi 0, 31, 32, %r25
504 depdi 0, 31, 32, %r24
505#endif
506
507lws_compare_and_swap:
508#ifdef CONFIG_SMP
509 /* Load start of lock table */
510 ldil L%lws_lock_start, %r20
511 ldo R%lws_lock_start(%r20), %r28
512
513 /* Extract four bits from r26 and hash lock (Bits 4-7) */
514 extru %r26, 27, 4, %r20
515
516 /* Find lock to use, the hash is either one of 0 to
517 15, multiplied by 16 (keep it 16-byte aligned)
518 and add to the lock table offset. */
519 shlw %r20, 4, %r20
520 add %r20, %r28, %r20
521
522# ifdef ENABLE_LWS_DEBUG
523 /*
524 DEBUG, check for deadlock!
525 If the thread register values are the same
526 then we were the one that locked it last and
527 this is a recurisve call that will deadlock.
528 We *must* giveup this call and fail.
529 */
530 ldw 4(%sr2,%r20), %r28 /* Load thread register */
531 mfctl %cr27, %r21 /* Get current thread register */
532 cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */
533 b lws_exit /* Return error! */
534 ldo -EDEADLOCK(%r0), %r21
535cas_lock:
536 cmpb,=,n %r0, %r28, cas_nocontend /* Is nobody using it? */
537 ldo 1(%r0), %r28 /* 1st case */
538 b lws_exit /* Contended... */
539 ldo -EAGAIN(%r0), %r21 /* Spin in userspace */
540cas_nocontend:
541# endif
542/* ENABLE_LWS_DEBUG */
543
544 ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */
545 cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */
546cas_wouldblock:
547 ldo 2(%r0), %r28 /* 2nd case */
548 b lws_exit /* Contended... */
549 ldo -EAGAIN(%r0), %r21 /* Spin in userspace */
550#endif
551/* CONFIG_SMP */
552
553 /*
554 prev = *addr;
555 if ( prev == old )
556 *addr = new;
557 return prev;
558 */
559
560 /* NOTES:
561 This all works becuse intr_do_signal
562 and schedule both check the return iasq
563 and see that we are on the kernel page
564 so this process is never scheduled off
565 or is ever sent any signal of any sort,
566 thus it is wholly atomic from usrspaces
567 perspective
568 */
569cas_action:
570#if defined CONFIG_SMP && defined ENABLE_LWS_DEBUG
571 /* DEBUG */
572 mfctl %cr27, %r1
573 stw %r1, 4(%sr2,%r20)
574#endif
575 /* The load and store could fail */
5761: ldw 0(%sr3,%r26), %r28
577 sub,<> %r28, %r25, %r0
5782: stw %r24, 0(%sr3,%r26)
579#ifdef CONFIG_SMP
580 /* Free lock */
581 stw %r20, 0(%sr2,%r20)
582# ifdef ENABLE_LWS_DEBUG
583 /* Clear thread register indicator */
584 stw %r0, 4(%sr2,%r20)
585# endif
586#endif
587 /* Return to userspace, set no error */
588 b lws_exit
589 copy %r0, %r21
590
5913:
592 /* Error occured on load or store */
593#ifdef CONFIG_SMP
594 /* Free lock */
595 stw %r20, 0(%sr2,%r20)
596# ifdef ENABLE_LWS_DEBUG
597 stw %r0, 4(%sr2,%r20)
598# endif
599#endif
600 b lws_exit
601 ldo -EFAULT(%r0),%r21 /* set errno */
602 nop
603 nop
604 nop
605 nop
606
607 /* Two exception table entries, one for the load,
608 the other for the store. Either return -EFAULT.
609 Each of the entries must be relocated. */
610 .section __ex_table,"aw"
611#ifdef __LP64__
612 /* Pad the address calculation */
613 .word 0,(2b - linux_gateway_page)
614 .word 0,(3b - linux_gateway_page)
615#else
616 .word (2b - linux_gateway_page)
617 .word (3b - linux_gateway_page)
618#endif
619 .previous
620
621 .section __ex_table,"aw"
622#ifdef __LP64__
623 /* Pad the address calculation */
624 .word 0,(1b - linux_gateway_page)
625 .word 0,(3b - linux_gateway_page)
626#else
627 .word (1b - linux_gateway_page)
628 .word (3b - linux_gateway_page)
629#endif
630 .previous
631
632end_compare_and_swap:
633
634 /* Make sure nothing else is placed on this page */
635 .align 4096
636 .export end_linux_gateway_page
637end_linux_gateway_page:
638
639 /* Relocate symbols assuming linux_gateway_page is mapped
640 to virtual address 0x0 */
641#ifdef __LP64__
642 /* FIXME: The code will always be on the gateay page
643 and thus it will be on the first 4k, the
644 assembler seems to think that the final
645 subtraction result is only a word in
646 length, so we pad the value.
647 */
648#define LWS_ENTRY(_name_) .word 0,(lws_##_name_ - linux_gateway_page)
649#else
650#define LWS_ENTRY(_name_) .word (lws_##_name_ - linux_gateway_page)
651#endif
652
653 .align 4096
654 /* Light-weight-syscall table */
655 /* Start of lws table. */
656 .export lws_table
657.Llws_table:
658lws_table:
659 LWS_ENTRY(compare_and_swap32) /* 0 - ELF32 Atomic compare and swap */
660 LWS_ENTRY(compare_and_swap64) /* 1 - ELF64 Atomic compare and swap */
661 /* End of lws table */
662
663 .align 4096
664 .export sys_call_table
665.Lsys_call_table:
666sys_call_table:
667#include "syscall_table.S"
668
669#ifdef __LP64__
670 .align 4096
671 .export sys_call_table64
672.Lsys_call_table64:
673sys_call_table64:
674#define SYSCALL_TABLE_64BIT
675#include "syscall_table.S"
676#endif
677
678#ifdef CONFIG_SMP
679 /*
680 All light-weight-syscall atomic operations
681 will use this set of locks
682 */
683 .section .data
684 .align 4096
685 .export lws_lock_start
686.Llws_lock_start:
687lws_lock_start:
688 /* lws locks */
689 .align 16
690 .rept 16
691 /* Keep locks aligned at 16-bytes */
692 .word 1
693 .word 0
694 .word 0
695 .word 0
696 .endr
697 .previous
698#endif
699/* CONFIG_SMP for lws_lock_start */
700
701.end
702
703
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
new file mode 100644
index 000000000000..779b537100ec
--- /dev/null
+++ b/arch/parisc/kernel/syscall_table.S
@@ -0,0 +1,372 @@
1/* System Call Table
2 *
3 * Copyright (C) 1999-2004 Matthew Wilcox <willy at parisc-linux.org>
4 * Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
5 * Copyright (C) 2000 Alan Modra <amodra at parisc-linux.org>
6 * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
7 * Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
8 * Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
9 * Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
10 * Copyright (C) 2000 Grant Grundler <grundler at parisc-linux.org>
11 * Copyright (C) 2001 Richard Hirst <rhirst with parisc-linux.org>
12 * Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
13 * Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
14 * Copyright (C) 2000-2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
15 * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
16 *
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32
33#undef ENTRY_SAME
34#undef ENTRY_DIFF
35#undef ENTRY_UHOH
36#undef ENTRY_COMP
37#undef ENTRY_OURS
38#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT)
39/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
40 * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific
41 * implementation is required on wide palinux. Use ENTRY_COMP where
42 * the compatability layer has a useful 32-bit implementation.
43 */
44#define ENTRY_SAME(_name_) .dword sys_##_name_
45#define ENTRY_DIFF(_name_) .dword sys32_##_name_
46#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
47#define ENTRY_OURS(_name_) .dword parisc_##_name_
48#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
49#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT)
50#define ENTRY_SAME(_name_) .dword sys_##_name_
51#define ENTRY_DIFF(_name_) .dword sys_##_name_
52#define ENTRY_UHOH(_name_) .dword sys_##_name_
53#define ENTRY_OURS(_name_) .dword sys_##_name_
54#define ENTRY_COMP(_name_) .dword sys_##_name_
55#else
56#define ENTRY_SAME(_name_) .word sys_##_name_
57#define ENTRY_DIFF(_name_) .word sys_##_name_
58#define ENTRY_UHOH(_name_) .word sys_##_name_
59#define ENTRY_OURS(_name_) .word parisc_##_name_
60#define ENTRY_COMP(_name_) .word sys_##_name_
61#endif
62
63 ENTRY_SAME(restart_syscall) /* 0 */
64 ENTRY_SAME(exit)
65 ENTRY_SAME(fork_wrapper)
66 ENTRY_SAME(read)
67 ENTRY_SAME(write)
68 ENTRY_SAME(open) /* 5 */
69 ENTRY_SAME(close)
70 ENTRY_SAME(waitpid)
71 ENTRY_SAME(creat)
72 ENTRY_SAME(link)
73 ENTRY_SAME(unlink) /* 10 */
74 ENTRY_DIFF(execve_wrapper)
75 ENTRY_SAME(chdir)
76 /* See comments in kernel/time.c!!! Maybe we don't need this? */
77 ENTRY_COMP(time)
78 ENTRY_SAME(mknod)
79 ENTRY_SAME(chmod) /* 15 */
80 ENTRY_SAME(lchown)
81 ENTRY_SAME(socket)
82 /* struct stat is MAYBE identical wide and narrow ?? */
83 ENTRY_COMP(newstat)
84 ENTRY_DIFF(lseek)
85 ENTRY_SAME(getpid) /* 20 */
86 /* the 'void * data' parameter may need re-packing in wide */
87 ENTRY_COMP(mount)
88 /* concerned about struct sockaddr in wide/narrow */
89 /* ---> I think sockaddr is OK unless the compiler packs the struct */
90 /* differently to align the char array */
91 ENTRY_SAME(bind)
92 ENTRY_SAME(setuid)
93 ENTRY_SAME(getuid)
94 ENTRY_COMP(stime) /* 25 */
95 ENTRY_SAME(ptrace)
96 ENTRY_SAME(alarm)
97 /* see stat comment */
98 ENTRY_COMP(newfstat)
99 ENTRY_SAME(pause)
100 /* struct utimbuf uses time_t which might vary */
101 ENTRY_COMP(utime) /* 30 */
102 /* struct sockaddr... */
103 ENTRY_SAME(connect)
104 ENTRY_SAME(listen)
105 ENTRY_SAME(access)
106 ENTRY_SAME(nice)
107 /* struct sockaddr... */
108 ENTRY_SAME(accept) /* 35 */
109 ENTRY_SAME(sync)
110 ENTRY_SAME(kill)
111 ENTRY_SAME(rename)
112 ENTRY_SAME(mkdir)
113 ENTRY_SAME(rmdir) /* 40 */
114 ENTRY_SAME(dup)
115 ENTRY_SAME(pipe)
116 ENTRY_COMP(times)
117 /* struct sockaddr... */
118 ENTRY_SAME(getsockname)
119 /* it seems possible brk() could return a >4G pointer... */
120 ENTRY_SAME(brk) /* 45 */
121 ENTRY_SAME(setgid)
122 ENTRY_SAME(getgid)
123 ENTRY_SAME(signal)
124 ENTRY_SAME(geteuid)
125 ENTRY_SAME(getegid) /* 50 */
126 ENTRY_SAME(acct)
127 ENTRY_SAME(umount)
128 /* struct sockaddr... */
129 ENTRY_SAME(getpeername)
130 ENTRY_COMP(ioctl)
131 ENTRY_COMP(fcntl) /* 55 */
132 ENTRY_SAME(socketpair)
133 ENTRY_SAME(setpgid)
134 ENTRY_SAME(send)
135 ENTRY_SAME(newuname)
136 ENTRY_SAME(umask) /* 60 */
137 ENTRY_SAME(chroot)
138 ENTRY_SAME(ustat)
139 ENTRY_SAME(dup2)
140 ENTRY_SAME(getppid)
141 ENTRY_SAME(getpgrp) /* 65 */
142 ENTRY_SAME(setsid)
143 ENTRY_SAME(pivot_root)
144 /* I don't like this */
145 ENTRY_UHOH(sgetmask)
146 ENTRY_UHOH(ssetmask)
147 ENTRY_SAME(setreuid) /* 70 */
148 ENTRY_SAME(setregid)
149 ENTRY_SAME(mincore)
150 ENTRY_COMP(sigpending)
151 ENTRY_SAME(sethostname)
152 /* Following 3 have linux-common-code structs containing longs -( */
153 ENTRY_COMP(setrlimit) /* 75 */
154 ENTRY_COMP(getrlimit)
155 ENTRY_COMP(getrusage)
156 /* struct timeval and timezone are maybe?? consistent wide and narrow */
157 ENTRY_DIFF(gettimeofday)
158 ENTRY_DIFF(settimeofday)
159 ENTRY_SAME(getgroups) /* 80 */
160 ENTRY_SAME(setgroups)
161 /* struct socketaddr... */
162 ENTRY_SAME(sendto)
163 ENTRY_SAME(symlink)
164 /* see stat comment */
165 ENTRY_COMP(newlstat)
166 ENTRY_SAME(readlink) /* 85 */
167 ENTRY_SAME(ni_syscall) /* was uselib */
168 ENTRY_SAME(swapon)
169 ENTRY_SAME(reboot)
170 ENTRY_SAME(mmap2)
171 ENTRY_SAME(mmap) /* 90 */
172 ENTRY_SAME(munmap)
173 ENTRY_SAME(truncate)
174 ENTRY_SAME(ftruncate)
175 ENTRY_SAME(fchmod)
176 ENTRY_SAME(fchown) /* 95 */
177 ENTRY_SAME(getpriority)
178 ENTRY_SAME(setpriority)
179 ENTRY_SAME(recv)
180 ENTRY_COMP(statfs)
181 ENTRY_COMP(fstatfs) /* 100 */
182 ENTRY_SAME(stat64)
183 ENTRY_SAME(ni_syscall) /* was socketcall */
184 ENTRY_SAME(syslog)
185 /* even though manpage says struct timeval contains longs, ours has
186 * time_t and suseconds_t -- both of which are safe wide/narrow */
187 ENTRY_COMP(setitimer)
188 ENTRY_COMP(getitimer) /* 105 */
189 ENTRY_SAME(capget)
190 ENTRY_SAME(capset)
191 ENTRY_OURS(pread64)
192 ENTRY_OURS(pwrite64)
193 ENTRY_SAME(getcwd) /* 110 */
194 ENTRY_SAME(vhangup)
195 ENTRY_SAME(fstat64)
196 ENTRY_SAME(vfork_wrapper)
197 /* struct rusage contains longs... */
198 ENTRY_COMP(wait4)
199 ENTRY_SAME(swapoff) /* 115 */
200 ENTRY_DIFF(sysinfo)
201 ENTRY_SAME(shutdown)
202 ENTRY_SAME(fsync)
203 ENTRY_SAME(madvise)
204 ENTRY_SAME(clone_wrapper) /* 120 */
205 ENTRY_SAME(setdomainname)
206 ENTRY_DIFF(sendfile)
207 /* struct sockaddr... */
208 ENTRY_SAME(recvfrom)
209 /* struct timex contains longs */
210 ENTRY_DIFF(adjtimex)
211 ENTRY_SAME(mprotect) /* 125 */
212 /* old_sigset_t forced to 32 bits. Beware glibc sigset_t */
213 ENTRY_COMP(sigprocmask)
214 ENTRY_SAME(ni_syscall) /* create_module */
215 ENTRY_SAME(init_module)
216 ENTRY_SAME(delete_module)
217 ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */
218 /* time_t inside struct dqblk */
219 ENTRY_SAME(quotactl)
220 ENTRY_SAME(getpgid)
221 ENTRY_SAME(fchdir)
222 ENTRY_SAME(bdflush)
223 ENTRY_SAME(sysfs) /* 135 */
224 ENTRY_SAME(personality)
225 ENTRY_SAME(ni_syscall) /* for afs_syscall */
226 ENTRY_SAME(setfsuid)
227 ENTRY_SAME(setfsgid)
228 /* I think this might work */
229 ENTRY_SAME(llseek) /* 140 */
230 /* struct linux_dirent has longs, like 'unsigned long d_ino' which
231 * almost definitely should be 'ino_t d_ino' but it's too late now */
232 ENTRY_DIFF(getdents)
233 /* it is POSSIBLE that select will be OK because even though fd_set
234 * contains longs, the macros and sizes are clever. */
235 ENTRY_COMP(select)
236 ENTRY_SAME(flock)
237 ENTRY_SAME(msync)
238 /* struct iovec contains pointers */
239 ENTRY_COMP(readv) /* 145 */
240 ENTRY_COMP(writev)
241 ENTRY_SAME(getsid)
242 ENTRY_SAME(fdatasync)
243 /* struct __sysctl_args is a mess */
244 ENTRY_DIFF(sysctl)
245 ENTRY_SAME(mlock) /* 150 */
246 ENTRY_SAME(munlock)
247 ENTRY_SAME(mlockall)
248 ENTRY_SAME(munlockall)
249 /* struct sched_param is ok for now */
250 ENTRY_SAME(sched_setparam)
251 ENTRY_SAME(sched_getparam) /* 155 */
252 ENTRY_SAME(sched_setscheduler)
253 ENTRY_SAME(sched_getscheduler)
254 ENTRY_SAME(sched_yield)
255 ENTRY_SAME(sched_get_priority_max)
256 ENTRY_SAME(sched_get_priority_min) /* 160 */
257 /* These 2 would've worked if someone had defined struct timespec
258 * carefully, like timeval for example (which is about the same).
259 * Unfortunately it contains a long :-( */
260 ENTRY_DIFF(sched_rr_get_interval)
261 ENTRY_COMP(nanosleep)
262 ENTRY_SAME(mremap)
263 ENTRY_SAME(setresuid)
264 ENTRY_SAME(getresuid) /* 165 */
265 ENTRY_DIFF(sigaltstack_wrapper)
266 ENTRY_SAME(ni_syscall) /* query_module */
267 ENTRY_SAME(poll)
268 /* structs contain pointers and an in_addr... */
269 ENTRY_COMP(nfsservctl)
270 ENTRY_SAME(setresgid) /* 170 */
271 ENTRY_SAME(getresgid)
272 ENTRY_SAME(prctl)
273 /* signals need a careful review */
274 ENTRY_SAME(rt_sigreturn_wrapper)
275 ENTRY_DIFF(rt_sigaction)
276 ENTRY_DIFF(rt_sigprocmask) /* 175 */
277 ENTRY_DIFF(rt_sigpending)
278 ENTRY_COMP(rt_sigtimedwait)
279 /* even though the struct siginfo_t is different, it appears like
280 * all the paths use values which should be same wide and narrow.
281 * Also the struct is padded to 128 bytes which means we don't have
282 * to worry about faulting trying to copy in a larger 64-bit
283 * struct from a 32-bit user-space app.
284 */
285 ENTRY_SAME(rt_sigqueueinfo)
286 ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
287 ENTRY_SAME(chown) /* 180 */
288 /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
289 ENTRY_COMP(setsockopt)
290 ENTRY_SAME(getsockopt)
291 ENTRY_COMP(sendmsg)
292 ENTRY_COMP(recvmsg)
293 ENTRY_SAME(semop) /* 185 */
294 ENTRY_SAME(semget)
295 ENTRY_DIFF(semctl)
296 ENTRY_DIFF(msgsnd)
297 ENTRY_DIFF(msgrcv)
298 ENTRY_SAME(msgget) /* 190 */
299 ENTRY_SAME(msgctl)
300 ENTRY_SAME(shmat_wrapper)
301 ENTRY_SAME(shmdt)
302 ENTRY_SAME(shmget)
303 ENTRY_SAME(shmctl) /* 195 */
304 ENTRY_SAME(ni_syscall) /* streams1 */
305 ENTRY_SAME(ni_syscall) /* streams2 */
306 ENTRY_SAME(lstat64)
307 ENTRY_OURS(truncate64)
308 ENTRY_OURS(ftruncate64) /* 200 */
309 ENTRY_SAME(getdents64)
310 ENTRY_COMP(fcntl64)
311 ENTRY_SAME(ni_syscall) /* attrctl -- dead */
312 ENTRY_SAME(ni_syscall) /* acl_get -- dead */
313 ENTRY_SAME(ni_syscall) /* 205 (acl_set -- dead) */
314 ENTRY_SAME(gettid)
315 ENTRY_OURS(readahead)
316 ENTRY_SAME(tkill)
317 ENTRY_SAME(sendfile64)
318 ENTRY_COMP(futex) /* 210 */
319 ENTRY_COMP(sched_setaffinity)
320 ENTRY_COMP(sched_getaffinity)
321 ENTRY_SAME(ni_syscall) /* set_thread_area */
322 ENTRY_SAME(ni_syscall) /* get_thread_area */
323 ENTRY_SAME(io_setup) /* 215 */
324 ENTRY_SAME(io_destroy)
325 ENTRY_SAME(io_getevents)
326 ENTRY_SAME(io_submit)
327 ENTRY_SAME(io_cancel)
328 ENTRY_SAME(alloc_hugepages) /* 220 */
329 ENTRY_SAME(free_hugepages)
330 ENTRY_SAME(exit_group)
331 ENTRY_DIFF(lookup_dcookie)
332 ENTRY_SAME(epoll_create)
333 ENTRY_SAME(epoll_ctl) /* 225 */
334 ENTRY_SAME(epoll_wait)
335 ENTRY_SAME(remap_file_pages)
336 ENTRY_SAME(semtimedop)
337 ENTRY_SAME(mq_open)
338 ENTRY_SAME(mq_unlink) /* 230 */
339 ENTRY_SAME(mq_timedsend)
340 ENTRY_SAME(mq_timedreceive)
341 ENTRY_SAME(mq_notify)
342 ENTRY_SAME(mq_getsetattr)
343 ENTRY_COMP(waitid) /* 235 */
344 ENTRY_OURS(fadvise64_64)
345 ENTRY_SAME(set_tid_address)
346 ENTRY_SAME(setxattr)
347 ENTRY_SAME(lsetxattr)
348 ENTRY_SAME(fsetxattr) /* 240 */
349 ENTRY_SAME(getxattr)
350 ENTRY_SAME(lgetxattr)
351 ENTRY_SAME(fgetxattr)
352 ENTRY_SAME(listxattr)
353 ENTRY_SAME(llistxattr) /* 245 */
354 ENTRY_SAME(flistxattr)
355 ENTRY_SAME(removexattr)
356 ENTRY_SAME(lremovexattr)
357 ENTRY_SAME(fremovexattr)
358 ENTRY_COMP(timer_create) /* 250 */
359 ENTRY_COMP(timer_settime)
360 ENTRY_COMP(timer_gettime)
361 ENTRY_SAME(timer_getoverrun)
362 ENTRY_SAME(timer_delete)
363 ENTRY_COMP(clock_settime) /* 255 */
364 ENTRY_COMP(clock_gettime)
365 ENTRY_COMP(clock_getres)
366 ENTRY_COMP(clock_nanosleep)
367 ENTRY_SAME(tgkill)
368 ENTRY_COMP(mbind) /* 260 */
369 ENTRY_COMP(get_mempolicy)
370 ENTRY_COMP(set_mempolicy)
371 /* Nothing yet */
372
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
new file mode 100644
index 000000000000..6cf7407344ba
--- /dev/null
+++ b/arch/parisc/kernel/time.c
@@ -0,0 +1,243 @@
1/*
2 * linux/arch/parisc/kernel/time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 * Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
6 * Copyright (C) 1999 SuSE GmbH, (Philipp Rumpf, prumpf@tux.org)
7 *
8 * 1994-07-02 Alan Modra
9 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
10 * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
11 * "A Kernel Model for Precision Timekeeping" by Dave Mills
12 */
13#include <linux/config.h>
14#include <linux/errno.h>
15#include <linux/module.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/param.h>
19#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/interrupt.h>
22#include <linux/time.h>
23#include <linux/init.h>
24#include <linux/smp.h>
25#include <linux/profile.h>
26
27#include <asm/uaccess.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/param.h>
31#include <asm/pdc.h>
32#include <asm/led.h>
33
34#include <linux/timex.h>
35
36u64 jiffies_64 = INITIAL_JIFFIES;
37
38EXPORT_SYMBOL(jiffies_64);
39
40/* xtime and wall_jiffies keep wall-clock time */
41extern unsigned long wall_jiffies;
42
43static long clocktick; /* timer cycles per tick */
44static long halftick;
45
46#ifdef CONFIG_SMP
47extern void smp_do_timer(struct pt_regs *regs);
48#endif
49
50irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
51{
52 long now;
53 long next_tick;
54 int nticks;
55 int cpu = smp_processor_id();
56
57 profile_tick(CPU_PROFILING, regs);
58
59 now = mfctl(16);
60 /* initialize next_tick to time at last clocktick */
61 next_tick = cpu_data[cpu].it_value;
62
63 /* since time passes between the interrupt and the mfctl()
64 * above, it is never true that last_tick + clocktick == now. If we
65 * never miss a clocktick, we could set next_tick = last_tick + clocktick
66 * but maybe we'll miss ticks, hence the loop.
67 *
68 * Variables are *signed*.
69 */
70
71 nticks = 0;
72 while((next_tick - now) < halftick) {
73 next_tick += clocktick;
74 nticks++;
75 }
76 mtctl(next_tick, 16);
77 cpu_data[cpu].it_value = next_tick;
78
79 while (nticks--) {
80#ifdef CONFIG_SMP
81 smp_do_timer(regs);
82#else
83 update_process_times(user_mode(regs));
84#endif
85 if (cpu == 0) {
86 write_seqlock(&xtime_lock);
87 do_timer(regs);
88 write_sequnlock(&xtime_lock);
89 }
90 }
91
92#ifdef CONFIG_CHASSIS_LCD_LED
93 /* Only schedule the led tasklet on cpu 0, and only if it
94 * is enabled.
95 */
96 if (cpu == 0 && !atomic_read(&led_tasklet.count))
97 tasklet_schedule(&led_tasklet);
98#endif
99
100 /* check soft power switch status */
101 if (cpu == 0 && !atomic_read(&power_tasklet.count))
102 tasklet_schedule(&power_tasklet);
103
104 return IRQ_HANDLED;
105}
106
107/*** converted from ia64 ***/
108/*
109 * Return the number of micro-seconds that elapsed since the last
110 * update to wall time (aka xtime aka wall_jiffies). The xtime_lock
111 * must be at least read-locked when calling this routine.
112 */
113static inline unsigned long
114gettimeoffset (void)
115{
116#ifndef CONFIG_SMP
117 /*
118 * FIXME: This won't work on smp because jiffies are updated by cpu 0.
119 * Once parisc-linux learns the cr16 difference between processors,
120 * this could be made to work.
121 */
122 long last_tick;
123 long elapsed_cycles;
124
125 /* it_value is the intended time of the next tick */
126 last_tick = cpu_data[smp_processor_id()].it_value;
127
128 /* Subtract one tick and account for possible difference between
129 * when we expected the tick and when it actually arrived.
130 * (aka wall vs real)
131 */
132 last_tick -= clocktick * (jiffies - wall_jiffies + 1);
133 elapsed_cycles = mfctl(16) - last_tick;
134
135 /* the precision of this math could be improved */
136 return elapsed_cycles / (PAGE0->mem_10msec / 10000);
137#else
138 return 0;
139#endif
140}
141
142void
143do_gettimeofday (struct timeval *tv)
144{
145 unsigned long flags, seq, usec, sec;
146
147 do {
148 seq = read_seqbegin_irqsave(&xtime_lock, flags);
149 usec = gettimeoffset();
150 sec = xtime.tv_sec;
151 usec += (xtime.tv_nsec / 1000);
152 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
153
154 while (usec >= 1000000) {
155 usec -= 1000000;
156 ++sec;
157 }
158
159 tv->tv_sec = sec;
160 tv->tv_usec = usec;
161}
162
163EXPORT_SYMBOL(do_gettimeofday);
164
165int
166do_settimeofday (struct timespec *tv)
167{
168 time_t wtm_sec, sec = tv->tv_sec;
169 long wtm_nsec, nsec = tv->tv_nsec;
170
171 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
172 return -EINVAL;
173
174 write_seqlock_irq(&xtime_lock);
175 {
176 /*
177 * This is revolting. We need to set "xtime"
178 * correctly. However, the value in this location is
179 * the value at the most recent update of wall time.
180 * Discover what correction gettimeofday would have
181 * done, and then undo it!
182 */
183 nsec -= gettimeoffset() * 1000;
184
185 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
186 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
187
188 set_normalized_timespec(&xtime, sec, nsec);
189 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
190
191 time_adjust = 0; /* stop active adjtime() */
192 time_status |= STA_UNSYNC;
193 time_maxerror = NTP_PHASE_LIMIT;
194 time_esterror = NTP_PHASE_LIMIT;
195 }
196 write_sequnlock_irq(&xtime_lock);
197 clock_was_set();
198 return 0;
199}
200EXPORT_SYMBOL(do_settimeofday);
201
202/*
203 * XXX: We can do better than this.
204 * Returns nanoseconds
205 */
206
207unsigned long long sched_clock(void)
208{
209 return (unsigned long long)jiffies * (1000000000 / HZ);
210}
211
212
213void __init time_init(void)
214{
215 unsigned long next_tick;
216 static struct pdc_tod tod_data;
217
218 clocktick = (100 * PAGE0->mem_10msec) / HZ;
219 halftick = clocktick / 2;
220
221 /* Setup clock interrupt timing */
222
223 next_tick = mfctl(16);
224 next_tick += clocktick;
225 cpu_data[smp_processor_id()].it_value = next_tick;
226
227 /* kick off Itimer (CR16) */
228 mtctl(next_tick, 16);
229
230 if(pdc_tod_read(&tod_data) == 0) {
231 write_seqlock_irq(&xtime_lock);
232 xtime.tv_sec = tod_data.tod_sec;
233 xtime.tv_nsec = tod_data.tod_usec * 1000;
234 set_normalized_timespec(&wall_to_monotonic,
235 -xtime.tv_sec, -xtime.tv_nsec);
236 write_sequnlock_irq(&xtime_lock);
237 } else {
238 printk(KERN_ERR "Error reading tod clock\n");
239 xtime.tv_sec = 0;
240 xtime.tv_nsec = 0;
241 }
242}
243
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
new file mode 100644
index 000000000000..ac2a40681414
--- /dev/null
+++ b/arch/parisc/kernel/topology.c
@@ -0,0 +1,37 @@
1/*
2 * arch/parisc/kernel/topology.c - Populate driverfs with topology information
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/init.h>
21#include <linux/smp.h>
22#include <linux/cpu.h>
23
24static struct cpu cpu_devices[NR_CPUS];
25
26static int __init topology_init(void)
27{
28 struct node *parent = NULL;
29 int num;
30
31 for_each_present_cpu(num) {
32 register_cpu(&cpu_devices[num], num, parent);
33 }
34 return 0;
35}
36
37subsys_initcall(topology_init);
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
new file mode 100644
index 000000000000..d2e5b229a2f4
--- /dev/null
+++ b/arch/parisc/kernel/traps.c
@@ -0,0 +1,834 @@
1/*
2 * linux/arch/parisc/traps.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1999, 2000 Philipp Rumpf <prumpf@tux.org>
6 */
7
8/*
9 * 'Traps.c' handles hardware traps and faults after we have saved some
10 * state in 'asm.s'.
11 */
12
13#include <linux/config.h>
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/errno.h>
18#include <linux/ptrace.h>
19#include <linux/timer.h>
20#include <linux/mm.h>
21#include <linux/module.h>
22#include <linux/smp.h>
23#include <linux/smp_lock.h>
24#include <linux/spinlock.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/console.h>
28#include <linux/kallsyms.h>
29
30#include <asm/assembly.h>
31#include <asm/system.h>
32#include <asm/uaccess.h>
33#include <asm/io.h>
34#include <asm/irq.h>
35#include <asm/traps.h>
36#include <asm/unaligned.h>
37#include <asm/atomic.h>
38#include <asm/smp.h>
39#include <asm/pdc.h>
40#include <asm/pdc_chassis.h>
41#include <asm/unwind.h>
42
43#include "../math-emu/math-emu.h" /* for handle_fpe() */
44
45#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
46 /* dumped to the console via printk) */
47
48#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
49DEFINE_SPINLOCK(pa_dbit_lock);
50#endif
51
52int printbinary(char *buf, unsigned long x, int nbits)
53{
54 unsigned long mask = 1UL << (nbits - 1);
55 while (mask != 0) {
56 *buf++ = (mask & x ? '1' : '0');
57 mask >>= 1;
58 }
59 *buf = '\0';
60
61 return nbits;
62}
63
64#ifdef __LP64__
65#define RFMT "%016lx"
66#else
67#define RFMT "%08lx"
68#endif
69
70void show_regs(struct pt_regs *regs)
71{
72 int i;
73 char buf[128], *p;
74 char *level;
75 unsigned long cr30;
76 unsigned long cr31;
77
78 level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
79
80 printk("%s\n", level); /* don't want to have that pretty register dump messed up */
81
82 printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
83 printbinary(buf, regs->gr[0], 32);
84 printk("%sPSW: %s %s\n", level, buf, print_tainted());
85
86 for (i = 0; i < 32; i += 4) {
87 int j;
88 p = buf;
89 p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3);
90 for (j = 0; j < 4; j++) {
91 p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]);
92 }
93 printk("%s\n", buf);
94 }
95
96 for (i = 0; i < 8; i += 4) {
97 int j;
98 p = buf;
99 p += sprintf(p, "%ssr%d-%d ", level, i, i + 3);
100 for (j = 0; j < 4; j++) {
101 p += sprintf(p, " " RFMT, regs->sr[i + j]);
102 }
103 printk("%s\n", buf);
104 }
105
106#if RIDICULOUSLY_VERBOSE
107 for (i = 0; i < 32; i += 2)
108 printk("%sFR%02d : %016lx FR%2d : %016lx", level, i,
109 regs->fr[i], i+1, regs->fr[i+1]);
110#endif
111
112 cr30 = mfctl(30);
113 cr31 = mfctl(31);
114 printk("%s\n", level);
115 printk("%sIASQ: " RFMT " " RFMT " IAOQ: " RFMT " " RFMT "\n",
116 level, regs->iasq[0], regs->iasq[1], regs->iaoq[0], regs->iaoq[1]);
117 printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n",
118 level, regs->iir, regs->isr, regs->ior);
119 printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n",
120 level, current_thread_info()->cpu, cr30, cr31);
121 printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
122 printk(level);
123 print_symbol(" IAOQ[0]: %s\n", regs->iaoq[0]);
124 printk(level);
125 print_symbol(" IAOQ[1]: %s\n", regs->iaoq[1]);
126 printk(level);
127 print_symbol(" RP(r2): %s\n", regs->gr[2]);
128}
129
130
131void dump_stack(void)
132{
133 show_stack(NULL, NULL);
134}
135
136EXPORT_SYMBOL(dump_stack);
137
138static void do_show_stack(struct unwind_frame_info *info)
139{
140 int i = 1;
141
142 printk("Backtrace:\n");
143 while (i <= 16) {
144 if (unwind_once(info) < 0 || info->ip == 0)
145 break;
146
147 if (__kernel_text_address(info->ip)) {
148 printk(" [<" RFMT ">] ", info->ip);
149#ifdef CONFIG_KALLSYMS
150 print_symbol("%s\n", info->ip);
151#else
152 if ((i & 0x03) == 0)
153 printk("\n");
154#endif
155 i++;
156 }
157 }
158 printk("\n");
159}
160
161void show_stack(struct task_struct *task, unsigned long *s)
162{
163 struct unwind_frame_info info;
164
165 if (!task) {
166 unsigned long sp;
167 struct pt_regs *r;
168
169HERE:
170 asm volatile ("copy %%r30, %0" : "=r"(sp));
171 r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
172 if (!r)
173 return;
174 memset(r, 0, sizeof(struct pt_regs));
175 r->iaoq[0] = (unsigned long)&&HERE;
176 r->gr[2] = (unsigned long)__builtin_return_address(0);
177 r->gr[30] = sp;
178 unwind_frame_init(&info, current, r);
179 kfree(r);
180 } else {
181 unwind_frame_init_from_blocked_task(&info, task);
182 }
183
184 do_show_stack(&info);
185}
186
187void die_if_kernel(char *str, struct pt_regs *regs, long err)
188{
189 if (user_mode(regs)) {
190 if (err == 0)
191 return; /* STFU */
192
193 printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
194 current->comm, current->pid, str, err, regs->iaoq[0]);
195#ifdef PRINT_USER_FAULTS
196 /* XXX for debugging only */
197 show_regs(regs);
198#endif
199 return;
200 }
201
202 oops_in_progress = 1;
203
204 /* Amuse the user in a SPARC fashion */
205 printk(
206" _______________________________ \n"
207" < Your System ate a SPARC! Gah! >\n"
208" ------------------------------- \n"
209" \\ ^__^\n"
210" \\ (xx)\\_______\n"
211" (__)\\ )\\/\\\n"
212" U ||----w |\n"
213" || ||\n");
214
215 /* unlock the pdc lock if necessary */
216 pdc_emergency_unlock();
217
218 /* maybe the kernel hasn't booted very far yet and hasn't been able
219 * to initialize the serial or STI console. In that case we should
220 * re-enable the pdc console, so that the user will be able to
221 * identify the problem. */
222 if (!console_drivers)
223 pdc_console_restart();
224
225 printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
226 current->comm, current->pid, str, err);
227 show_regs(regs);
228
229 /* Wot's wrong wif bein' racy? */
230 if (current->thread.flags & PARISC_KERNEL_DEATH) {
231 printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
232 local_irq_enable();
233 while (1);
234 }
235
236 current->thread.flags |= PARISC_KERNEL_DEATH;
237 do_exit(SIGSEGV);
238}
239
240int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs)
241{
242 return syscall(regs);
243}
244
245/* gdb uses break 4,8 */
246#define GDB_BREAK_INSN 0x10004
247void handle_gdb_break(struct pt_regs *regs, int wot)
248{
249 struct siginfo si;
250
251 si.si_code = wot;
252 si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
253 si.si_signo = SIGTRAP;
254 si.si_errno = 0;
255 force_sig_info(SIGTRAP, &si, current);
256}
257
258void handle_break(unsigned iir, struct pt_regs *regs)
259{
260 struct siginfo si;
261
262 switch(iir) {
263 case 0x00:
264#ifdef PRINT_USER_FAULTS
265 printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n",
266 current->pid, current->comm);
267#endif
268 die_if_kernel("Breakpoint", regs, 0);
269#ifdef PRINT_USER_FAULTS
270 show_regs(regs);
271#endif
272 si.si_code = TRAP_BRKPT;
273 si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
274 si.si_signo = SIGTRAP;
275 force_sig_info(SIGTRAP, &si, current);
276 break;
277
278 case GDB_BREAK_INSN:
279 die_if_kernel("Breakpoint", regs, 0);
280 handle_gdb_break(regs, TRAP_BRKPT);
281 break;
282
283 default:
284#ifdef PRINT_USER_FAULTS
285 printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n",
286 iir, current->pid, current->comm);
287 show_regs(regs);
288#endif
289 si.si_signo = SIGTRAP;
290 si.si_code = TRAP_BRKPT;
291 si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
292 force_sig_info(SIGTRAP, &si, current);
293 return;
294 }
295}
296
297
298int handle_toc(void)
299{
300 printk(KERN_CRIT "TOC call.\n");
301 return 0;
302}
303
304static void default_trap(int code, struct pt_regs *regs)
305{
306 printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id());
307 show_regs(regs);
308}
309
310void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap;
311
312
313void transfer_pim_to_trap_frame(struct pt_regs *regs)
314{
315 register int i;
316 extern unsigned int hpmc_pim_data[];
317 struct pdc_hpmc_pim_11 *pim_narrow;
318 struct pdc_hpmc_pim_20 *pim_wide;
319
320 if (boot_cpu_data.cpu_type >= pcxu) {
321
322 pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;
323
324 /*
325 * Note: The following code will probably generate a
326 * bunch of truncation error warnings from the compiler.
327 * Could be handled with an ifdef, but perhaps there
328 * is a better way.
329 */
330
331 regs->gr[0] = pim_wide->cr[22];
332
333 for (i = 1; i < 32; i++)
334 regs->gr[i] = pim_wide->gr[i];
335
336 for (i = 0; i < 32; i++)
337 regs->fr[i] = pim_wide->fr[i];
338
339 for (i = 0; i < 8; i++)
340 regs->sr[i] = pim_wide->sr[i];
341
342 regs->iasq[0] = pim_wide->cr[17];
343 regs->iasq[1] = pim_wide->iasq_back;
344 regs->iaoq[0] = pim_wide->cr[18];
345 regs->iaoq[1] = pim_wide->iaoq_back;
346
347 regs->sar = pim_wide->cr[11];
348 regs->iir = pim_wide->cr[19];
349 regs->isr = pim_wide->cr[20];
350 regs->ior = pim_wide->cr[21];
351 }
352 else {
353 pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;
354
355 regs->gr[0] = pim_narrow->cr[22];
356
357 for (i = 1; i < 32; i++)
358 regs->gr[i] = pim_narrow->gr[i];
359
360 for (i = 0; i < 32; i++)
361 regs->fr[i] = pim_narrow->fr[i];
362
363 for (i = 0; i < 8; i++)
364 regs->sr[i] = pim_narrow->sr[i];
365
366 regs->iasq[0] = pim_narrow->cr[17];
367 regs->iasq[1] = pim_narrow->iasq_back;
368 regs->iaoq[0] = pim_narrow->cr[18];
369 regs->iaoq[1] = pim_narrow->iaoq_back;
370
371 regs->sar = pim_narrow->cr[11];
372 regs->iir = pim_narrow->cr[19];
373 regs->isr = pim_narrow->cr[20];
374 regs->ior = pim_narrow->cr[21];
375 }
376
377 /*
378 * The following fields only have meaning if we came through
379 * another path. So just zero them here.
380 */
381
382 regs->ksp = 0;
383 regs->kpc = 0;
384 regs->orig_r28 = 0;
385}
386
387
388/*
389 * This routine is called as a last resort when everything else
390 * has gone clearly wrong. We get called for faults in kernel space,
391 * and HPMC's.
392 */
393void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
394{
395 static DEFINE_SPINLOCK(terminate_lock);
396
397 oops_in_progress = 1;
398
399 set_eiem(0);
400 local_irq_disable();
401 spin_lock(&terminate_lock);
402
403 /* unlock the pdc lock if necessary */
404 pdc_emergency_unlock();
405
406 /* restart pdc console if necessary */
407 if (!console_drivers)
408 pdc_console_restart();
409
410 /* Not all paths will gutter the processor... */
411 switch(code){
412
413 case 1:
414 transfer_pim_to_trap_frame(regs);
415 break;
416
417 default:
418 /* Fall through */
419 break;
420
421 }
422
423 {
424 /* show_stack(NULL, (unsigned long *)regs->gr[30]); */
425 struct unwind_frame_info info;
426 unwind_frame_init(&info, current, regs);
427 do_show_stack(&info);
428 }
429
430 printk("\n");
431 printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n",
432 msg, code, regs, offset);
433 show_regs(regs);
434
435 spin_unlock(&terminate_lock);
436
437 /* put soft power button back under hardware control;
438 * if the user had pressed it once at any time, the
439 * system will shut down immediately right here. */
440 pdc_soft_power_button(0);
441
442 /* Call kernel panic() so reboot timeouts work properly
443 * FIXME: This function should be on the list of
444 * panic notifiers, and we should call panic
445 * directly from the location that we wish.
446 * e.g. We should not call panic from
447 * parisc_terminate, but rather the oter way around.
448 * This hack works, prints the panic message twice,
449 * and it enables reboot timers!
450 */
451 panic(msg);
452}
453
454void handle_interruption(int code, struct pt_regs *regs)
455{
456 unsigned long fault_address = 0;
457 unsigned long fault_space = 0;
458 struct siginfo si;
459
460 if (code == 1)
461 pdc_console_restart(); /* switch back to pdc if HPMC */
462 else
463 local_irq_enable();
464
465 /* Security check:
466 * If the priority level is still user, and the
467 * faulting space is not equal to the active space
468 * then the user is attempting something in a space
469 * that does not belong to them. Kill the process.
470 *
471 * This is normally the situation when the user
472 * attempts to jump into the kernel space at the
473 * wrong offset, be it at the gateway page or a
474 * random location.
475 *
476 * We cannot normally signal the process because it
477 * could *be* on the gateway page, and processes
478 * executing on the gateway page can't have signals
479 * delivered.
480 *
481 * We merely readjust the address into the users
482 * space, at a destination address of zero, and
483 * allow processing to continue.
484 */
485 if (((unsigned long)regs->iaoq[0] & 3) &&
486 ((unsigned long)regs->iasq[0] != (unsigned long)regs->sr[7])) {
487 /* Kill the user process later */
488 regs->iaoq[0] = 0 | 3;
489 regs->iaoq[1] = regs->iaoq[0] + 4;
490 regs->iasq[0] = regs->iasq[0] = regs->sr[7];
491 regs->gr[0] &= ~PSW_B;
492 return;
493 }
494
495#if 0
496 printk(KERN_CRIT "Interruption # %d\n", code);
497#endif
498
499 switch(code) {
500
501 case 1:
502 /* High-priority machine check (HPMC) */
503
504 /* set up a new led state on systems shipped with a LED State panel */
505 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
506
507 parisc_terminate("High Priority Machine Check (HPMC)",
508 regs, code, 0);
509 /* NOT REACHED */
510
511 case 2:
512 /* Power failure interrupt */
513 printk(KERN_CRIT "Power failure interrupt !\n");
514 return;
515
516 case 3:
517 /* Recovery counter trap */
518 regs->gr[0] &= ~PSW_R;
519 if (user_space(regs))
520 handle_gdb_break(regs, TRAP_TRACE);
521 /* else this must be the start of a syscall - just let it run */
522 return;
523
524 case 5:
525 /* Low-priority machine check */
526 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
527
528 flush_all_caches();
529 cpu_lpmc(5, regs);
530 return;
531
532 case 6:
533 /* Instruction TLB miss fault/Instruction page fault */
534 fault_address = regs->iaoq[0];
535 fault_space = regs->iasq[0];
536 break;
537
538 case 8:
539 /* Illegal instruction trap */
540 die_if_kernel("Illegal instruction", regs, code);
541 si.si_code = ILL_ILLOPC;
542 goto give_sigill;
543
544 case 9:
545 /* Break instruction trap */
546 handle_break(regs->iir,regs);
547 return;
548
549 case 10:
550 /* Privileged operation trap */
551 die_if_kernel("Privileged operation", regs, code);
552 si.si_code = ILL_PRVOPC;
553 goto give_sigill;
554
555 case 11:
556 /* Privileged register trap */
557 if ((regs->iir & 0xffdfffe0) == 0x034008a0) {
558
559 /* This is a MFCTL cr26/cr27 to gr instruction.
560 * PCXS traps on this, so we need to emulate it.
561 */
562
563 if (regs->iir & 0x00200000)
564 regs->gr[regs->iir & 0x1f] = mfctl(27);
565 else
566 regs->gr[regs->iir & 0x1f] = mfctl(26);
567
568 regs->iaoq[0] = regs->iaoq[1];
569 regs->iaoq[1] += 4;
570 regs->iasq[0] = regs->iasq[1];
571 return;
572 }
573
574 die_if_kernel("Privileged register usage", regs, code);
575 si.si_code = ILL_PRVREG;
576 give_sigill:
577 si.si_signo = SIGILL;
578 si.si_errno = 0;
579 si.si_addr = (void __user *) regs->iaoq[0];
580 force_sig_info(SIGILL, &si, current);
581 return;
582
583 case 12:
584 /* Overflow Trap, let the userland signal handler do the cleanup */
585 si.si_signo = SIGFPE;
586 si.si_code = FPE_INTOVF;
587 si.si_addr = (void __user *) regs->iaoq[0];
588 force_sig_info(SIGFPE, &si, current);
589 return;
590
591 case 13:
592 /* Conditional Trap
593 The condition succees in an instruction which traps
594 on condition */
595 if(user_mode(regs)){
596 si.si_signo = SIGFPE;
597 /* Set to zero, and let the userspace app figure it out from
598 the insn pointed to by si_addr */
599 si.si_code = 0;
600 si.si_addr = (void __user *) regs->iaoq[0];
601 force_sig_info(SIGFPE, &si, current);
602 return;
603 }
604 /* The kernel doesn't want to handle condition codes */
605 break;
606
607 case 14:
608 /* Assist Exception Trap, i.e. floating point exception. */
609 die_if_kernel("Floating point exception", regs, 0); /* quiet */
610 handle_fpe(regs);
611 return;
612
613 case 15:
614 /* Data TLB miss fault/Data page fault */
615 /* Fall through */
616 case 16:
617 /* Non-access instruction TLB miss fault */
618 /* The instruction TLB entry needed for the target address of the FIC
619 is absent, and hardware can't find it, so we get to cleanup */
620 /* Fall through */
621 case 17:
622 /* Non-access data TLB miss fault/Non-access data page fault */
623 /* FIXME:
624 Still need to add slow path emulation code here!
625 If the insn used a non-shadow register, then the tlb
626 handlers could not have their side-effect (e.g. probe
627 writing to a target register) emulated since rfir would
628 erase the changes to said register. Instead we have to
629 setup everything, call this function we are in, and emulate
630 by hand. Technically we need to emulate:
631 fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw
632 */
633 fault_address = regs->ior;
634 fault_space = regs->isr;
635 break;
636
637 case 18:
638 /* PCXS only -- later cpu's split this into types 26,27 & 28 */
639 /* Check for unaligned access */
640 if (check_unaligned(regs)) {
641 handle_unaligned(regs);
642 return;
643 }
644 /* Fall Through */
645 case 26:
646 /* PCXL: Data memory access rights trap */
647 fault_address = regs->ior;
648 fault_space = regs->isr;
649 break;
650
651 case 19:
652 /* Data memory break trap */
653 regs->gr[0] |= PSW_X; /* So we can single-step over the trap */
654 /* fall thru */
655 case 21:
656 /* Page reference trap */
657 handle_gdb_break(regs, TRAP_HWBKPT);
658 return;
659
660 case 25:
661 /* Taken branch trap */
662 regs->gr[0] &= ~PSW_T;
663 if (user_space(regs))
664 handle_gdb_break(regs, TRAP_BRANCH);
665 /* else this must be the start of a syscall - just let it
666 * run.
667 */
668 return;
669
670 case 7:
671 /* Instruction access rights */
672 /* PCXL: Instruction memory protection trap */
673
674 /*
675 * This could be caused by either: 1) a process attempting
676 * to execute within a vma that does not have execute
677 * permission, or 2) an access rights violation caused by a
678 * flush only translation set up by ptep_get_and_clear().
679 * So we check the vma permissions to differentiate the two.
680 * If the vma indicates we have execute permission, then
681 * the cause is the latter one. In this case, we need to
682 * call do_page_fault() to fix the problem.
683 */
684
685 if (user_mode(regs)) {
686 struct vm_area_struct *vma;
687
688 down_read(&current->mm->mmap_sem);
689 vma = find_vma(current->mm,regs->iaoq[0]);
690 if (vma && (regs->iaoq[0] >= vma->vm_start)
691 && (vma->vm_flags & VM_EXEC)) {
692
693 fault_address = regs->iaoq[0];
694 fault_space = regs->iasq[0];
695
696 up_read(&current->mm->mmap_sem);
697 break; /* call do_page_fault() */
698 }
699 up_read(&current->mm->mmap_sem);
700 }
701 /* Fall Through */
702 case 27:
703 /* Data memory protection ID trap */
704 die_if_kernel("Protection id trap", regs, code);
705 si.si_code = SEGV_MAPERR;
706 si.si_signo = SIGSEGV;
707 si.si_errno = 0;
708 if (code == 7)
709 si.si_addr = (void __user *) regs->iaoq[0];
710 else
711 si.si_addr = (void __user *) regs->ior;
712 force_sig_info(SIGSEGV, &si, current);
713 return;
714
715 case 28:
716 /* Unaligned data reference trap */
717 handle_unaligned(regs);
718 return;
719
720 default:
721 if (user_mode(regs)) {
722#ifdef PRINT_USER_FAULTS
723 printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
724 current->pid, current->comm);
725 show_regs(regs);
726#endif
727 /* SIGBUS, for lack of a better one. */
728 si.si_signo = SIGBUS;
729 si.si_code = BUS_OBJERR;
730 si.si_errno = 0;
731 si.si_addr = (void __user *) regs->ior;
732 force_sig_info(SIGBUS, &si, current);
733 return;
734 }
735 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
736
737 parisc_terminate("Unexpected interruption", regs, code, 0);
738 /* NOT REACHED */
739 }
740
741 if (user_mode(regs)) {
742 if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
743#ifdef PRINT_USER_FAULTS
744 if (fault_space == 0)
745 printk(KERN_DEBUG "User Fault on Kernel Space ");
746 else
747 printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
748 code);
749 printk("pid=%d command='%s'\n", current->pid, current->comm);
750 show_regs(regs);
751#endif
752 si.si_signo = SIGSEGV;
753 si.si_errno = 0;
754 si.si_code = SEGV_MAPERR;
755 si.si_addr = (void __user *) regs->ior;
756 force_sig_info(SIGSEGV, &si, current);
757 return;
758 }
759 }
760 else {
761
762 /*
763 * The kernel should never fault on its own address space.
764 */
765
766 if (fault_space == 0)
767 {
768 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
769 parisc_terminate("Kernel Fault", regs, code, fault_address);
770
771 }
772 }
773
774 do_page_fault(regs, code, fault_address);
775}
776
777
778int __init check_ivt(void *iva)
779{
780 int i;
781 u32 check = 0;
782 u32 *ivap;
783 u32 *hpmcp;
784 u32 length;
785 extern void os_hpmc(void);
786 extern void os_hpmc_end(void);
787
788 if (strcmp((char *)iva, "cows can fly"))
789 return -1;
790
791 ivap = (u32 *)iva;
792
793 for (i = 0; i < 8; i++)
794 *ivap++ = 0;
795
796 /* Compute Checksum for HPMC handler */
797
798 length = (u32)((unsigned long)os_hpmc_end - (unsigned long)os_hpmc);
799 ivap[7] = length;
800
801 hpmcp = (u32 *)os_hpmc;
802
803 for (i=0; i<length/4; i++)
804 check += *hpmcp++;
805
806 for (i=0; i<8; i++)
807 check += ivap[i];
808
809 ivap[5] = -check;
810
811 return 0;
812}
813
814#ifndef __LP64__
815extern const void fault_vector_11;
816#endif
817extern const void fault_vector_20;
818
819void __init trap_init(void)
820{
821 void *iva;
822
823 if (boot_cpu_data.cpu_type >= pcxu)
824 iva = (void *) &fault_vector_20;
825 else
826#ifdef __LP64__
827 panic("Can't boot 64-bit OS on PA1.1 processor!");
828#else
829 iva = (void *) &fault_vector_11;
830#endif
831
832 if (check_ivt(iva))
833 panic("IVT invalid");
834}
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
new file mode 100644
index 000000000000..62eea35bcd69
--- /dev/null
+++ b/arch/parisc/kernel/unaligned.c
@@ -0,0 +1,816 @@
1/*
2 * Unaligned memory access handler
3 *
4 * Copyright (C) 2001 Randolph Chung <tausq@debian.org>
5 * Significantly tweaked by LaMont Jones <lamont@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <asm/uaccess.h>
27
28/* #define DEBUG_UNALIGNED 1 */
29
30#ifdef DEBUG_UNALIGNED
31#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__ ); printk(KERN_DEBUG fmt, ##args ); } while (0)
32#else
33#define DPRINTF(fmt, args...)
34#endif
35
36#ifdef __LP64__
37#define RFMT "%016lx"
38#else
39#define RFMT "%08lx"
40#endif
41
42#define FIXUP_BRANCH(lbl) \
43 "\tldil L%%" #lbl ", %%r1\n" \
44 "\tldo R%%" #lbl "(%%r1), %%r1\n" \
45 "\tbv,n %%r0(%%r1)\n"
46
47/* 1111 1100 0000 0000 0001 0011 1100 0000 */
48#define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6)
49#define OPCODE2(a,b) ((a)<<26|(b)<<1)
50#define OPCODE3(a,b) ((a)<<26|(b)<<2)
51#define OPCODE4(a) ((a)<<26)
52#define OPCODE1_MASK OPCODE1(0x3f,1,0xf)
53#define OPCODE2_MASK OPCODE2(0x3f,1)
54#define OPCODE3_MASK OPCODE3(0x3f,1)
55#define OPCODE4_MASK OPCODE4(0x3f)
56
57/* skip LDB - never unaligned (index) */
58#define OPCODE_LDH_I OPCODE1(0x03,0,0x1)
59#define OPCODE_LDW_I OPCODE1(0x03,0,0x2)
60#define OPCODE_LDD_I OPCODE1(0x03,0,0x3)
61#define OPCODE_LDDA_I OPCODE1(0x03,0,0x4)
62#define OPCODE_LDCD_I OPCODE1(0x03,0,0x5)
63#define OPCODE_LDWA_I OPCODE1(0x03,0,0x6)
64#define OPCODE_LDCW_I OPCODE1(0x03,0,0x7)
65/* skip LDB - never unaligned (short) */
66#define OPCODE_LDH_S OPCODE1(0x03,1,0x1)
67#define OPCODE_LDW_S OPCODE1(0x03,1,0x2)
68#define OPCODE_LDD_S OPCODE1(0x03,1,0x3)
69#define OPCODE_LDDA_S OPCODE1(0x03,1,0x4)
70#define OPCODE_LDCD_S OPCODE1(0x03,1,0x5)
71#define OPCODE_LDWA_S OPCODE1(0x03,1,0x6)
72#define OPCODE_LDCW_S OPCODE1(0x03,1,0x7)
73/* skip STB - never unaligned */
74#define OPCODE_STH OPCODE1(0x03,1,0x9)
75#define OPCODE_STW OPCODE1(0x03,1,0xa)
76#define OPCODE_STD OPCODE1(0x03,1,0xb)
77/* skip STBY - never unaligned */
78/* skip STDBY - never unaligned */
79#define OPCODE_STWA OPCODE1(0x03,1,0xe)
80#define OPCODE_STDA OPCODE1(0x03,1,0xf)
81
82#define OPCODE_FLDWX OPCODE1(0x09,0,0x0)
83#define OPCODE_FLDWXR OPCODE1(0x09,0,0x1)
84#define OPCODE_FSTWX OPCODE1(0x09,0,0x8)
85#define OPCODE_FSTWXR OPCODE1(0x09,0,0x9)
86#define OPCODE_FLDWS OPCODE1(0x09,1,0x0)
87#define OPCODE_FLDWSR OPCODE1(0x09,1,0x1)
88#define OPCODE_FSTWS OPCODE1(0x09,1,0x8)
89#define OPCODE_FSTWSR OPCODE1(0x09,1,0x9)
90#define OPCODE_FLDDX OPCODE1(0x0b,0,0x0)
91#define OPCODE_FSTDX OPCODE1(0x0b,0,0x8)
92#define OPCODE_FLDDS OPCODE1(0x0b,1,0x0)
93#define OPCODE_FSTDS OPCODE1(0x0b,1,0x8)
94
95#define OPCODE_LDD_L OPCODE2(0x14,0)
96#define OPCODE_FLDD_L OPCODE2(0x14,1)
97#define OPCODE_STD_L OPCODE2(0x1c,0)
98#define OPCODE_FSTD_L OPCODE2(0x1c,1)
99
100#define OPCODE_LDW_M OPCODE3(0x17,1)
101#define OPCODE_FLDW_L OPCODE3(0x17,0)
102#define OPCODE_FSTW_L OPCODE3(0x1f,0)
103#define OPCODE_STW_M OPCODE3(0x1f,1)
104
105#define OPCODE_LDH_L OPCODE4(0x11)
106#define OPCODE_LDW_L OPCODE4(0x12)
107#define OPCODE_LDWM OPCODE4(0x13)
108#define OPCODE_STH_L OPCODE4(0x19)
109#define OPCODE_STW_L OPCODE4(0x1A)
110#define OPCODE_STWM OPCODE4(0x1B)
111
112#define MAJOR_OP(i) (((i)>>26)&0x3f)
113#define R1(i) (((i)>>21)&0x1f)
114#define R2(i) (((i)>>16)&0x1f)
115#define R3(i) ((i)&0x1f)
116#define FR3(i) ((((i)<<1)&0x1f)|(((i)>>6)&1))
117#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0))
118#define IM5_2(i) IM((i)>>16,5)
119#define IM5_3(i) IM((i),5)
120#define IM14(i) IM((i),14)
121
122#define ERR_NOTHANDLED -1
123#define ERR_PAGEFAULT -2
124
125int unaligned_enabled = 1;
126
127void die_if_kernel (char *str, struct pt_regs *regs, long err);
128
129static int emulate_ldh(struct pt_regs *regs, int toreg)
130{
131 unsigned long saddr = regs->ior;
132 unsigned long val = 0;
133 int ret;
134
135 DPRINTF("load " RFMT ":" RFMT " to r%d for 2 bytes\n",
136 regs->isr, regs->ior, toreg);
137
138 __asm__ __volatile__ (
139" mtsp %4, %%sr1\n"
140"1: ldbs 0(%%sr1,%3), %%r20\n"
141"2: ldbs 1(%%sr1,%3), %0\n"
142" depw %%r20, 23, 24, %0\n"
143" copy %%r0, %1\n"
144"3: \n"
145" .section .fixup,\"ax\"\n"
146"4: ldi -2, %1\n"
147 FIXUP_BRANCH(3b)
148" .previous\n"
149" .section __ex_table,\"aw\"\n"
150#ifdef __LP64__
151" .dword 1b,4b\n"
152" .dword 2b,4b\n"
153#else
154" .word 1b,4b\n"
155" .word 2b,4b\n"
156#endif
157" .previous\n"
158 : "=r" (val), "=r" (ret)
159 : "0" (val), "r" (saddr), "r" (regs->isr)
160 : "r20" );
161
162 DPRINTF("val = 0x" RFMT "\n", val);
163
164 if (toreg)
165 regs->gr[toreg] = val;
166
167 return ret;
168}
169
170static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
171{
172 unsigned long saddr = regs->ior;
173 unsigned long val = 0;
174 int ret;
175
176 DPRINTF("load " RFMT ":" RFMT " to r%d for 4 bytes\n",
177 regs->isr, regs->ior, toreg);
178
179 __asm__ __volatile__ (
180" zdep %3,28,2,%%r19\n" /* r19=(ofs&3)*8 */
181" mtsp %4, %%sr1\n"
182" depw %%r0,31,2,%3\n"
183"1: ldw 0(%%sr1,%3),%0\n"
184"2: ldw 4(%%sr1,%3),%%r20\n"
185" subi 32,%%r19,%%r19\n"
186" mtctl %%r19,11\n"
187" vshd %0,%%r20,%0\n"
188" copy %%r0, %1\n"
189"3: \n"
190" .section .fixup,\"ax\"\n"
191"4: ldi -2, %1\n"
192 FIXUP_BRANCH(3b)
193" .previous\n"
194" .section __ex_table,\"aw\"\n"
195#ifdef __LP64__
196" .dword 1b,4b\n"
197" .dword 2b,4b\n"
198#else
199" .word 1b,4b\n"
200" .word 2b,4b\n"
201#endif
202" .previous\n"
203 : "=r" (val), "=r" (ret)
204 : "0" (val), "r" (saddr), "r" (regs->isr)
205 : "r19", "r20" );
206
207 DPRINTF("val = 0x" RFMT "\n", val);
208
209 if (flop)
210 ((__u32*)(regs->fr))[toreg] = val;
211 else if (toreg)
212 regs->gr[toreg] = val;
213
214 return ret;
215}
216static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
217{
218 unsigned long saddr = regs->ior;
219 __u64 val = 0;
220 int ret;
221
222 DPRINTF("load " RFMT ":" RFMT " to r%d for 8 bytes\n",
223 regs->isr, regs->ior, toreg);
224#ifdef CONFIG_PA20
225
226#ifndef __LP64__
227 if (!flop)
228 return -1;
229#endif
230 __asm__ __volatile__ (
231" depd,z %3,60,3,%%r19\n" /* r19=(ofs&7)*8 */
232" mtsp %4, %%sr1\n"
233" depd %%r0,63,3,%3\n"
234"1: ldd 0(%%sr1,%3),%0\n"
235"2: ldd 8(%%sr1,%3),%%r20\n"
236" subi 64,%%r19,%%r19\n"
237" mtsar %%r19\n"
238" shrpd %0,%%r20,%%sar,%0\n"
239" copy %%r0, %1\n"
240"3: \n"
241" .section .fixup,\"ax\"\n"
242"4: ldi -2, %1\n"
243 FIXUP_BRANCH(3b)
244" .previous\n"
245" .section __ex_table,\"aw\"\n"
246#ifdef __LP64__
247" .dword 1b,4b\n"
248" .dword 2b,4b\n"
249#else
250" .word 1b,4b\n"
251" .word 2b,4b\n"
252#endif
253" .previous\n"
254 : "=r" (val), "=r" (ret)
255 : "0" (val), "r" (saddr), "r" (regs->isr)
256 : "r19", "r20" );
257#else
258 {
259 unsigned long valh=0,vall=0;
260 __asm__ __volatile__ (
261" zdep %5,29,2,%%r19\n" /* r19=(ofs&3)*8 */
262" mtsp %6, %%sr1\n"
263" dep %%r0,31,2,%5\n"
264"1: ldw 0(%%sr1,%5),%0\n"
265"2: ldw 4(%%sr1,%5),%1\n"
266"3: ldw 8(%%sr1,%5),%%r20\n"
267" subi 32,%%r19,%%r19\n"
268" mtsar %%r19\n"
269" vshd %0,%1,%0\n"
270" vshd %1,%%r20,%1\n"
271" copy %%r0, %2\n"
272"4: \n"
273" .section .fixup,\"ax\"\n"
274"5: ldi -2, %2\n"
275 FIXUP_BRANCH(4b)
276" .previous\n"
277" .section __ex_table,\"aw\"\n"
278#ifdef __LP64__
279" .dword 1b,5b\n"
280" .dword 2b,5b\n"
281" .dword 3b,5b\n"
282#else
283" .word 1b,5b\n"
284" .word 2b,5b\n"
285" .word 3b,5b\n"
286#endif
287" .previous\n"
288 : "=r" (valh), "=r" (vall), "=r" (ret)
289 : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
290 : "r19", "r20" );
291 val=((__u64)valh<<32)|(__u64)vall;
292 }
293#endif
294
295 DPRINTF("val = 0x%llx\n", val);
296
297 if (flop)
298 regs->fr[toreg] = val;
299 else if (toreg)
300 regs->gr[toreg] = val;
301
302 return ret;
303}
304
305static int emulate_sth(struct pt_regs *regs, int frreg)
306{
307 unsigned long val = regs->gr[frreg];
308 int ret;
309
310 if (!frreg)
311 val = 0;
312
313 DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg,
314 val, regs->isr, regs->ior);
315
316 __asm__ __volatile__ (
317" mtsp %3, %%sr1\n"
318" extrw,u %1, 23, 8, %%r19\n"
319"1: stb %1, 1(%%sr1, %2)\n"
320"2: stb %%r19, 0(%%sr1, %2)\n"
321" copy %%r0, %0\n"
322"3: \n"
323" .section .fixup,\"ax\"\n"
324"4: ldi -2, %0\n"
325 FIXUP_BRANCH(3b)
326" .previous\n"
327" .section __ex_table,\"aw\"\n"
328#ifdef __LP64__
329" .dword 1b,4b\n"
330" .dword 2b,4b\n"
331#else
332" .word 1b,4b\n"
333" .word 2b,4b\n"
334#endif
335" .previous\n"
336 : "=r" (ret)
337 : "r" (val), "r" (regs->ior), "r" (regs->isr)
338 : "r19" );
339
340 return ret;
341}
342
343static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
344{
345 unsigned long val;
346 int ret;
347
348 if (flop)
349 val = ((__u32*)(regs->fr))[frreg];
350 else if (frreg)
351 val = regs->gr[frreg];
352 else
353 val = 0;
354
355 DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg,
356 val, regs->isr, regs->ior);
357
358
359 __asm__ __volatile__ (
360" mtsp %3, %%sr1\n"
361" zdep %2, 28, 2, %%r19\n"
362" dep %%r0, 31, 2, %2\n"
363" mtsar %%r19\n"
364" depwi,z -2, %%sar, 32, %%r19\n"
365"1: ldw 0(%%sr1,%2),%%r20\n"
366"2: ldw 4(%%sr1,%2),%%r21\n"
367" vshd %%r0, %1, %%r22\n"
368" vshd %1, %%r0, %%r1\n"
369" and %%r20, %%r19, %%r20\n"
370" andcm %%r21, %%r19, %%r21\n"
371" or %%r22, %%r20, %%r20\n"
372" or %%r1, %%r21, %%r21\n"
373" stw %%r20,0(%%sr1,%2)\n"
374" stw %%r21,4(%%sr1,%2)\n"
375" copy %%r0, %0\n"
376"3: \n"
377" .section .fixup,\"ax\"\n"
378"4: ldi -2, %0\n"
379 FIXUP_BRANCH(3b)
380" .previous\n"
381" .section __ex_table,\"aw\"\n"
382#ifdef __LP64__
383" .dword 1b,4b\n"
384" .dword 2b,4b\n"
385#else
386" .word 1b,4b\n"
387" .word 2b,4b\n"
388#endif
389" .previous\n"
390 : "=r" (ret)
391 : "r" (val), "r" (regs->ior), "r" (regs->isr)
392 : "r19", "r20", "r21", "r22", "r1" );
393
394 return 0;
395}
396static int emulate_std(struct pt_regs *regs, int frreg, int flop)
397{
398 __u64 val;
399 int ret;
400
401 if (flop)
402 val = regs->fr[frreg];
403 else if (frreg)
404 val = regs->gr[frreg];
405 else
406 val = 0;
407
408 DPRINTF("store r%d (0x%016llx) to " RFMT ":" RFMT " for 8 bytes\n", frreg,
409 val, regs->isr, regs->ior);
410
411#ifdef CONFIG_PA20
412#ifndef __LP64__
413 if (!flop)
414 return -1;
415#endif
416 __asm__ __volatile__ (
417" mtsp %3, %%sr1\n"
418" depd,z %2, 60, 3, %%r19\n"
419" depd %%r0, 63, 3, %2\n"
420" mtsar %%r19\n"
421" depdi,z -2, %%sar, 64, %%r19\n"
422"1: ldd 0(%%sr1,%2),%%r20\n"
423"2: ldd 8(%%sr1,%2),%%r21\n"
424" shrpd %%r0, %1, %%sar, %%r22\n"
425" shrpd %1, %%r0, %%sar, %%r1\n"
426" and %%r20, %%r19, %%r20\n"
427" andcm %%r21, %%r19, %%r21\n"
428" or %%r22, %%r20, %%r20\n"
429" or %%r1, %%r21, %%r21\n"
430"3: std %%r20,0(%%sr1,%2)\n"
431"4: std %%r21,8(%%sr1,%2)\n"
432" copy %%r0, %0\n"
433"5: \n"
434" .section .fixup,\"ax\"\n"
435"6: ldi -2, %0\n"
436 FIXUP_BRANCH(5b)
437" .previous\n"
438" .section __ex_table,\"aw\"\n"
439#ifdef __LP64__
440" .dword 1b,6b\n"
441" .dword 2b,6b\n"
442" .dword 3b,6b\n"
443" .dword 4b,6b\n"
444#else
445" .word 1b,6b\n"
446" .word 2b,6b\n"
447" .word 3b,6b\n"
448" .word 4b,6b\n"
449#endif
450" .previous\n"
451 : "=r" (ret)
452 : "r" (val), "r" (regs->ior), "r" (regs->isr)
453 : "r19", "r20", "r21", "r22", "r1" );
454#else
455 {
456 unsigned long valh=(val>>32),vall=(val&0xffffffffl);
457 __asm__ __volatile__ (
458" mtsp %4, %%sr1\n"
459" zdep %2, 29, 2, %%r19\n"
460" dep %%r0, 31, 2, %2\n"
461" mtsar %%r19\n"
462" zvdepi -2, 32, %%r19\n"
463"1: ldw 0(%%sr1,%3),%%r20\n"
464"2: ldw 8(%%sr1,%3),%%r21\n"
465" vshd %1, %2, %%r1\n"
466" vshd %%r0, %1, %1\n"
467" vshd %2, %%r0, %2\n"
468" and %%r20, %%r19, %%r20\n"
469" andcm %%r21, %%r19, %%r21\n"
470" or %1, %%r20, %1\n"
471" or %2, %%r21, %2\n"
472"3: stw %1,0(%%sr1,%1)\n"
473"4: stw %%r1,4(%%sr1,%3)\n"
474"5: stw %2,8(%%sr1,%3)\n"
475" copy %%r0, %0\n"
476"6: \n"
477" .section .fixup,\"ax\"\n"
478"7: ldi -2, %0\n"
479 FIXUP_BRANCH(6b)
480" .previous\n"
481" .section __ex_table,\"aw\"\n"
482#ifdef __LP64__
483" .dword 1b,7b\n"
484" .dword 2b,7b\n"
485" .dword 3b,7b\n"
486" .dword 4b,7b\n"
487" .dword 5b,7b\n"
488#else
489" .word 1b,7b\n"
490" .word 2b,7b\n"
491" .word 3b,7b\n"
492" .word 4b,7b\n"
493" .word 5b,7b\n"
494#endif
495" .previous\n"
496 : "=r" (ret)
497 : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
498 : "r19", "r20", "r21", "r1" );
499 }
500#endif
501
502 return ret;
503}
504
505void handle_unaligned(struct pt_regs *regs)
506{
507 static unsigned long unaligned_count = 0;
508 static unsigned long last_time = 0;
509 unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
510 int modify = 0;
511 int ret = ERR_NOTHANDLED;
512 struct siginfo si;
513 register int flop=0; /* true if this is a flop */
514
515 /* log a message with pacing */
516 if (user_mode(regs))
517 {
518 if (unaligned_count > 5 && jiffies - last_time > 5*HZ)
519 {
520 unaligned_count = 0;
521 last_time = jiffies;
522 }
523 if (++unaligned_count < 5)
524 {
525 char buf[256];
526 sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
527 current->comm, current->pid, regs->ior, regs->iaoq[0]);
528 printk(KERN_WARNING "%s", buf);
529#ifdef DEBUG_UNALIGNED
530 show_regs(regs);
531#endif
532 }
533 if (!unaligned_enabled)
534 goto force_sigbus;
535 }
536
537 /* handle modification - OK, it's ugly, see the instruction manual */
538 switch (MAJOR_OP(regs->iir))
539 {
540 case 0x03:
541 case 0x09:
542 case 0x0b:
543 if (regs->iir&0x20)
544 {
545 modify = 1;
546 if (regs->iir&0x1000) /* short loads */
547 if (regs->iir&0x200)
548 newbase += IM5_3(regs->iir);
549 else
550 newbase += IM5_2(regs->iir);
551 else if (regs->iir&0x2000) /* scaled indexed */
552 {
553 int shift=0;
554 switch (regs->iir & OPCODE1_MASK)
555 {
556 case OPCODE_LDH_I:
557 shift= 1; break;
558 case OPCODE_LDW_I:
559 shift= 2; break;
560 case OPCODE_LDD_I:
561 case OPCODE_LDDA_I:
562 shift= 3; break;
563 }
564 newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0)<<shift;
565 } else /* simple indexed */
566 newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0);
567 }
568 break;
569 case 0x13:
570 case 0x1b:
571 modify = 1;
572 newbase += IM14(regs->iir);
573 break;
574 case 0x14:
575 case 0x1c:
576 if (regs->iir&8)
577 {
578 modify = 1;
579 newbase += IM14(regs->iir&~0xe);
580 }
581 break;
582 case 0x16:
583 case 0x1e:
584 modify = 1;
585 newbase += IM14(regs->iir&6);
586 break;
587 case 0x17:
588 case 0x1f:
589 if (regs->iir&4)
590 {
591 modify = 1;
592 newbase += IM14(regs->iir&~4);
593 }
594 break;
595 }
596
597 /* TODO: make this cleaner... */
598 switch (regs->iir & OPCODE1_MASK)
599 {
600 case OPCODE_LDH_I:
601 case OPCODE_LDH_S:
602 ret = emulate_ldh(regs, R3(regs->iir));
603 break;
604
605 case OPCODE_LDW_I:
606 case OPCODE_LDWA_I:
607 case OPCODE_LDW_S:
608 case OPCODE_LDWA_S:
609 ret = emulate_ldw(regs, R3(regs->iir),0);
610 break;
611
612 case OPCODE_STH:
613 ret = emulate_sth(regs, R2(regs->iir));
614 break;
615
616 case OPCODE_STW:
617 case OPCODE_STWA:
618 ret = emulate_stw(regs, R2(regs->iir),0);
619 break;
620
621#ifdef CONFIG_PA20
622 case OPCODE_LDD_I:
623 case OPCODE_LDDA_I:
624 case OPCODE_LDD_S:
625 case OPCODE_LDDA_S:
626 ret = emulate_ldd(regs, R3(regs->iir),0);
627 break;
628
629 case OPCODE_STD:
630 case OPCODE_STDA:
631 ret = emulate_std(regs, R2(regs->iir),0);
632 break;
633#endif
634
635 case OPCODE_FLDWX:
636 case OPCODE_FLDWS:
637 case OPCODE_FLDWXR:
638 case OPCODE_FLDWSR:
639 flop=1;
640 ret = emulate_ldw(regs,FR3(regs->iir),1);
641 break;
642
643 case OPCODE_FLDDX:
644 case OPCODE_FLDDS:
645 flop=1;
646 ret = emulate_ldd(regs,R3(regs->iir),1);
647 break;
648
649 case OPCODE_FSTWX:
650 case OPCODE_FSTWS:
651 case OPCODE_FSTWXR:
652 case OPCODE_FSTWSR:
653 flop=1;
654 ret = emulate_stw(regs,FR3(regs->iir),1);
655 break;
656
657 case OPCODE_FSTDX:
658 case OPCODE_FSTDS:
659 flop=1;
660 ret = emulate_std(regs,R3(regs->iir),1);
661 break;
662
663 case OPCODE_LDCD_I:
664 case OPCODE_LDCW_I:
665 case OPCODE_LDCD_S:
666 case OPCODE_LDCW_S:
667 ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */
668 break;
669 }
670#ifdef CONFIG_PA20
671 switch (regs->iir & OPCODE2_MASK)
672 {
673 case OPCODE_FLDD_L:
674 flop=1;
675 ret = emulate_ldd(regs,R2(regs->iir),1);
676 break;
677 case OPCODE_FSTD_L:
678 flop=1;
679 ret = emulate_std(regs, R2(regs->iir),1);
680 break;
681
682#ifdef CONFIG_PA20
683 case OPCODE_LDD_L:
684 ret = emulate_ldd(regs, R2(regs->iir),0);
685 break;
686 case OPCODE_STD_L:
687 ret = emulate_std(regs, R2(regs->iir),0);
688 break;
689#endif
690 }
691#endif
692 switch (regs->iir & OPCODE3_MASK)
693 {
694 case OPCODE_FLDW_L:
695 flop=1;
696 ret = emulate_ldw(regs, R2(regs->iir),0);
697 break;
698 case OPCODE_LDW_M:
699 ret = emulate_ldw(regs, R2(regs->iir),1);
700 break;
701
702 case OPCODE_FSTW_L:
703 flop=1;
704 ret = emulate_stw(regs, R2(regs->iir),1);
705 break;
706 case OPCODE_STW_M:
707 ret = emulate_stw(regs, R2(regs->iir),0);
708 break;
709 }
710 switch (regs->iir & OPCODE4_MASK)
711 {
712 case OPCODE_LDH_L:
713 ret = emulate_ldh(regs, R2(regs->iir));
714 break;
715 case OPCODE_LDW_L:
716 case OPCODE_LDWM:
717 ret = emulate_ldw(regs, R2(regs->iir),0);
718 break;
719 case OPCODE_STH_L:
720 ret = emulate_sth(regs, R2(regs->iir));
721 break;
722 case OPCODE_STW_L:
723 case OPCODE_STWM:
724 ret = emulate_stw(regs, R2(regs->iir),0);
725 break;
726 }
727
728 if (modify && R1(regs->iir))
729 regs->gr[R1(regs->iir)] = newbase;
730
731
732 if (ret == ERR_NOTHANDLED)
733 printk(KERN_CRIT "Not-handled unaligned insn 0x%08lx\n", regs->iir);
734
735 DPRINTF("ret = %d\n", ret);
736
737 if (ret)
738 {
739 printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
740 die_if_kernel("Unaligned data reference", regs, 28);
741
742 if (ret == ERR_PAGEFAULT)
743 {
744 si.si_signo = SIGSEGV;
745 si.si_errno = 0;
746 si.si_code = SEGV_MAPERR;
747 si.si_addr = (void __user *)regs->ior;
748 force_sig_info(SIGSEGV, &si, current);
749 }
750 else
751 {
752force_sigbus:
753 /* couldn't handle it ... */
754 si.si_signo = SIGBUS;
755 si.si_errno = 0;
756 si.si_code = BUS_ADRALN;
757 si.si_addr = (void __user *)regs->ior;
758 force_sig_info(SIGBUS, &si, current);
759 }
760
761 return;
762 }
763
764 /* else we handled it, let life go on. */
765 regs->gr[0]|=PSW_N;
766}
767
768/*
769 * NB: check_unaligned() is only used for PCXS processors right
770 * now, so we only check for PA1.1 encodings at this point.
771 */
772
773int
774check_unaligned(struct pt_regs *regs)
775{
776 unsigned long align_mask;
777
778 /* Get alignment mask */
779
780 align_mask = 0UL;
781 switch (regs->iir & OPCODE1_MASK) {
782
783 case OPCODE_LDH_I:
784 case OPCODE_LDH_S:
785 case OPCODE_STH:
786 align_mask = 1UL;
787 break;
788
789 case OPCODE_LDW_I:
790 case OPCODE_LDWA_I:
791 case OPCODE_LDW_S:
792 case OPCODE_LDWA_S:
793 case OPCODE_STW:
794 case OPCODE_STWA:
795 align_mask = 3UL;
796 break;
797
798 default:
799 switch (regs->iir & OPCODE4_MASK) {
800 case OPCODE_LDH_L:
801 case OPCODE_STH_L:
802 align_mask = 1UL;
803 break;
804 case OPCODE_LDW_L:
805 case OPCODE_LDWM:
806 case OPCODE_STW_L:
807 case OPCODE_STWM:
808 align_mask = 3UL;
809 break;
810 }
811 break;
812 }
813
814 return (int)(regs->ior & align_mask);
815}
816
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
new file mode 100644
index 000000000000..db141108412e
--- /dev/null
+++ b/arch/parisc/kernel/unwind.c
@@ -0,0 +1,393 @@
1/*
2 * Kernel unwinding support
3 *
4 * (c) 2002-2004 Randolph Chung <tausq@debian.org>
5 *
6 * Derived partially from the IA64 implementation. The PA-RISC
7 * Runtime Architecture Document is also a useful reference to
8 * understand what is happening here
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15#include <linux/kallsyms.h>
16
17#include <asm/uaccess.h>
18#include <asm/assembly.h>
19
20#include <asm/unwind.h>
21
22/* #define DEBUG 1 */
23#ifdef DEBUG
24#define dbg(x...) printk(x)
25#else
26#define dbg(x...)
27#endif
28
29extern struct unwind_table_entry __start___unwind[];
30extern struct unwind_table_entry __stop___unwind[];
31
32static spinlock_t unwind_lock;
33/*
34 * the kernel unwind block is not dynamically allocated so that
35 * we can call unwind_init as early in the bootup process as
36 * possible (before the slab allocator is initialized)
37 */
38static struct unwind_table kernel_unwind_table;
39static LIST_HEAD(unwind_tables);
40
41static inline const struct unwind_table_entry *
42find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
43{
44 const struct unwind_table_entry *e = NULL;
45 unsigned long lo, hi, mid;
46
47 lo = 0;
48 hi = table->length - 1;
49
50 while (lo <= hi) {
51 mid = (hi - lo) / 2 + lo;
52 e = &table->table[mid];
53 if (addr < e->region_start)
54 hi = mid - 1;
55 else if (addr > e->region_end)
56 lo = mid + 1;
57 else
58 return e;
59 }
60
61 return NULL;
62}
63
64static const struct unwind_table_entry *
65find_unwind_entry(unsigned long addr)
66{
67 struct unwind_table *table;
68 const struct unwind_table_entry *e = NULL;
69
70 if (addr >= kernel_unwind_table.start &&
71 addr <= kernel_unwind_table.end)
72 e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
73 else
74 list_for_each_entry(table, &unwind_tables, list) {
75 if (addr >= table->start &&
76 addr <= table->end)
77 e = find_unwind_entry_in_table(table, addr);
78 if (e)
79 break;
80 }
81
82 return e;
83}
84
85static void
86unwind_table_init(struct unwind_table *table, const char *name,
87 unsigned long base_addr, unsigned long gp,
88 void *table_start, void *table_end)
89{
90 struct unwind_table_entry *start = table_start;
91 struct unwind_table_entry *end =
92 (struct unwind_table_entry *)table_end - 1;
93
94 table->name = name;
95 table->base_addr = base_addr;
96 table->gp = gp;
97 table->start = base_addr + start->region_start;
98 table->end = base_addr + end->region_end;
99 table->table = (struct unwind_table_entry *)table_start;
100 table->length = end - start + 1;
101 INIT_LIST_HEAD(&table->list);
102
103 for (; start <= end; start++) {
104 if (start < end &&
105 start->region_end > (start+1)->region_start) {
106 printk("WARNING: Out of order unwind entry! %p and %p\n", start, start+1);
107 }
108
109 start->region_start += base_addr;
110 start->region_end += base_addr;
111 }
112}
113
114static void
115unwind_table_sort(struct unwind_table_entry *start,
116 struct unwind_table_entry *finish)
117{
118 struct unwind_table_entry el, *p, *q;
119
120 for (p = start + 1; p < finish; ++p) {
121 if (p[0].region_start < p[-1].region_start) {
122 el = *p;
123 q = p;
124 do {
125 q[0] = q[-1];
126 --q;
127 } while (q > start &&
128 el.region_start < q[-1].region_start);
129 *q = el;
130 }
131 }
132}
133
134struct unwind_table *
135unwind_table_add(const char *name, unsigned long base_addr,
136 unsigned long gp,
137 void *start, void *end)
138{
139 struct unwind_table *table;
140 unsigned long flags;
141 struct unwind_table_entry *s = (struct unwind_table_entry *)start;
142 struct unwind_table_entry *e = (struct unwind_table_entry *)end;
143
144 unwind_table_sort(s, e);
145
146 table = kmalloc(sizeof(struct unwind_table), GFP_USER);
147 if (table == NULL)
148 return NULL;
149 unwind_table_init(table, name, base_addr, gp, start, end);
150 spin_lock_irqsave(&unwind_lock, flags);
151 list_add_tail(&table->list, &unwind_tables);
152 spin_unlock_irqrestore(&unwind_lock, flags);
153
154 return table;
155}
156
157void unwind_table_remove(struct unwind_table *table)
158{
159 unsigned long flags;
160
161 spin_lock_irqsave(&unwind_lock, flags);
162 list_del(&table->list);
163 spin_unlock_irqrestore(&unwind_lock, flags);
164
165 kfree(table);
166}
167
168/* Called from setup_arch to import the kernel unwind info */
169static int unwind_init(void)
170{
171 long start, stop;
172 register unsigned long gp __asm__ ("r27");
173
174 start = (long)&__start___unwind[0];
175 stop = (long)&__stop___unwind[0];
176
177 spin_lock_init(&unwind_lock);
178
179 printk("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n",
180 start, stop,
181 (stop - start) / sizeof(struct unwind_table_entry));
182
183 unwind_table_init(&kernel_unwind_table, "kernel", KERNEL_START,
184 gp,
185 &__start___unwind[0], &__stop___unwind[0]);
186#if 0
187 {
188 int i;
189 for (i = 0; i < 10; i++)
190 {
191 printk("region 0x%x-0x%x\n",
192 __start___unwind[i].region_start,
193 __start___unwind[i].region_end);
194 }
195 }
196#endif
197 return 0;
198}
199
200static void unwind_frame_regs(struct unwind_frame_info *info)
201{
202 const struct unwind_table_entry *e;
203 unsigned long npc;
204 unsigned int insn;
205 long frame_size = 0;
206 int looking_for_rp, rpoffset = 0;
207
208 e = find_unwind_entry(info->ip);
209 if (e == NULL) {
210 unsigned long sp;
211 extern char _stext[], _etext[];
212
213 dbg("Cannot find unwind entry for 0x%lx; forced unwinding\n", info->ip);
214
215#ifdef CONFIG_KALLSYMS
216 /* Handle some frequent special cases.... */
217 {
218 char symname[KSYM_NAME_LEN+1];
219 char *modname;
220 unsigned long symsize, offset;
221
222 kallsyms_lookup(info->ip, &symsize, &offset,
223 &modname, symname);
224
225 dbg("info->ip = 0x%lx, name = %s\n", info->ip, symname);
226
227 if (strcmp(symname, "_switch_to_ret") == 0) {
228 info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
229 info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
230 dbg("_switch_to_ret @ %lx - setting "
231 "prev_sp=%lx prev_ip=%lx\n",
232 info->ip, info->prev_sp,
233 info->prev_ip);
234 return;
235 } else if (strcmp(symname, "ret_from_kernel_thread") == 0 ||
236 strcmp(symname, "syscall_exit") == 0) {
237 info->prev_ip = info->prev_sp = 0;
238 return;
239 }
240 }
241#endif
242
243 /* Since we are doing the unwinding blind, we don't know if
244 we are adjusting the stack correctly or extracting the rp
245 correctly. The rp is checked to see if it belongs to the
246 kernel text section, if not we assume we don't have a
247 correct stack frame and we continue to unwind the stack.
248 This is not quite correct, and will fail for loadable
249 modules. */
250 sp = info->sp & ~63;
251 do {
252 unsigned long tmp;
253
254 info->prev_sp = sp - 64;
255 info->prev_ip = 0;
256 if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET)))
257 break;
258 info->prev_ip = tmp;
259 sp = info->prev_sp;
260 } while (info->prev_ip < (unsigned long)_stext ||
261 info->prev_ip > (unsigned long)_etext);
262
263 info->rp = 0;
264
265 dbg("analyzing func @ %lx with no unwind info, setting "
266 "prev_sp=%lx prev_ip=%lx\n", info->ip,
267 info->prev_sp, info->prev_ip);
268 } else {
269 dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, "
270 "Save_RP = %d, Millicode = %d size = %u\n",
271 e->region_start, e->region_end, e->Save_SP, e->Save_RP,
272 e->Millicode, e->Total_frame_size);
273
274 looking_for_rp = e->Save_RP;
275
276 for (npc = e->region_start;
277 (frame_size < (e->Total_frame_size << 3) ||
278 looking_for_rp) &&
279 npc < info->ip;
280 npc += 4) {
281
282 insn = *(unsigned int *)npc;
283
284 if ((insn & 0xffffc000) == 0x37de0000 ||
285 (insn & 0xffe00000) == 0x6fc00000) {
286 /* ldo X(sp), sp, or stwm X,D(sp) */
287 frame_size += (insn & 0x1 ? -1 << 13 : 0) |
288 ((insn & 0x3fff) >> 1);
289 dbg("analyzing func @ %lx, insn=%08x @ "
290 "%lx, frame_size = %ld\n", info->ip,
291 insn, npc, frame_size);
292 } else if ((insn & 0xffe00008) == 0x73c00008) {
293 /* std,ma X,D(sp) */
294 frame_size += (insn & 0x1 ? -1 << 13 : 0) |
295 (((insn >> 4) & 0x3ff) << 3);
296 dbg("analyzing func @ %lx, insn=%08x @ "
297 "%lx, frame_size = %ld\n", info->ip,
298 insn, npc, frame_size);
299 } else if (insn == 0x6bc23fd9) {
300 /* stw rp,-20(sp) */
301 rpoffset = 20;
302 looking_for_rp = 0;
303 dbg("analyzing func @ %lx, insn=stw rp,"
304 "-20(sp) @ %lx\n", info->ip, npc);
305 } else if (insn == 0x0fc212c1) {
306 /* std rp,-16(sr0,sp) */
307 rpoffset = 16;
308 looking_for_rp = 0;
309 dbg("analyzing func @ %lx, insn=std rp,"
310 "-16(sp) @ %lx\n", info->ip, npc);
311 }
312 }
313
314 info->prev_sp = info->sp - frame_size;
315 if (e->Millicode)
316 info->rp = info->r31;
317 else if (rpoffset)
318 info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
319 info->prev_ip = info->rp;
320 info->rp = 0;
321
322 dbg("analyzing func @ %lx, setting prev_sp=%lx "
323 "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp,
324 info->prev_ip, npc);
325 }
326}
327
328void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
329 struct pt_regs *regs)
330{
331 memset(info, 0, sizeof(struct unwind_frame_info));
332 info->t = t;
333 info->sp = regs->gr[30];
334 info->ip = regs->iaoq[0];
335 info->rp = regs->gr[2];
336 info->r31 = regs->gr[31];
337
338 dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n",
339 t ? (int)t->pid : -1, info->sp, info->ip);
340}
341
342void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
343{
344 struct pt_regs *r = &t->thread.regs;
345 struct pt_regs *r2;
346
347 r2 = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
348 if (!r2)
349 return;
350 *r2 = *r;
351 r2->gr[30] = r->ksp;
352 r2->iaoq[0] = r->kpc;
353 unwind_frame_init(info, t, r2);
354 kfree(r2);
355}
356
357void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
358{
359 unwind_frame_init(info, current, regs);
360}
361
362int unwind_once(struct unwind_frame_info *next_frame)
363{
364 unwind_frame_regs(next_frame);
365
366 if (next_frame->prev_sp == 0 ||
367 next_frame->prev_ip == 0)
368 return -1;
369
370 next_frame->sp = next_frame->prev_sp;
371 next_frame->ip = next_frame->prev_ip;
372 next_frame->prev_sp = 0;
373 next_frame->prev_ip = 0;
374
375 dbg("(%d) Continue unwind to sp=%08lx ip=%08lx\n",
376 next_frame->t ? (int)next_frame->t->pid : -1,
377 next_frame->sp, next_frame->ip);
378
379 return 0;
380}
381
382int unwind_to_user(struct unwind_frame_info *info)
383{
384 int ret;
385
386 do {
387 ret = unwind_once(info);
388 } while (!ret && !(info->ip & 3));
389
390 return ret;
391}
392
393module_init(unwind_init);
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..e5fac3e08c7a
--- /dev/null
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -0,0 +1,207 @@
1/* Kernel link layout for various "sections"
2 *
3 * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
4 * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
5 * Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
6 * Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
7 * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
8 * Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org>
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25#include <linux/config.h>
26#include <asm-generic/vmlinux.lds.h>
27/* needed for the processor specific cache alignment size */
28#include <asm/cache.h>
29#include <asm/page.h>
30
31/* ld script to make hppa Linux kernel */
32#ifndef CONFIG_64BIT
33OUTPUT_FORMAT("elf32-hppa-linux")
34OUTPUT_ARCH(hppa)
35#else
36OUTPUT_FORMAT("elf64-hppa-linux")
37OUTPUT_ARCH(hppa:hppa2.0w)
38#endif
39
40ENTRY(_stext)
41#ifndef CONFIG_64BIT
42jiffies = jiffies_64 + 4;
43#else
44jiffies = jiffies_64;
45#endif
46SECTIONS
47{
48
49 . = KERNEL_BINARY_TEXT_START;
50
51 _text = .; /* Text and read-only data */
52 .text ALIGN(16) : {
53 *(.text)
54 SCHED_TEXT
55 LOCK_TEXT
56 *(.text.do_softirq)
57 *(.text.sys_exit)
58 *(.text.do_sigaltstack)
59 *(.text.do_fork)
60 *(.text.*)
61 *(.fixup)
62 *(.lock.text) /* out-of-line lock text */
63 *(.gnu.warning)
64 } = 0
65
66 _etext = .; /* End of text section */
67
68 RODATA
69
70 /* writeable */
71 . = ALIGN(4096); /* Make sure this is paged aligned so
72 that we can properly leave these
73 as writable */
74 data_start = .;
75
76 . = ALIGN(16); /* Exception table */
77 __start___ex_table = .;
78 __ex_table : { *(__ex_table) }
79 __stop___ex_table = .;
80
81 __start___unwind = .; /* unwind info */
82 .PARISC.unwind : { *(.PARISC.unwind) }
83 __stop___unwind = .;
84
85 .data : { /* Data */
86 *(.data)
87 *(.data.vm0.pmd)
88 *(.data.vm0.pgd)
89 *(.data.vm0.pte)
90 CONSTRUCTORS
91 }
92
93 . = ALIGN(4096);
94 /* nosave data is really only used for software suspend...it's here
95 * just in case we ever implement it */
96 __nosave_begin = .;
97 .data_nosave : { *(.data.nosave) }
98 . = ALIGN(4096);
99 __nosave_end = .;
100
101 . = ALIGN(L1_CACHE_BYTES);
102 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
103
104 /* PA-RISC locks requires 16-byte alignment */
105 . = ALIGN(16);
106 .data.lock_aligned : { *(.data.lock_aligned) }
107
108 _edata = .; /* End of data section */
109
110 . = ALIGN(16384); /* init_task */
111 .data.init_task : { *(.data.init_task) }
112
113 /* The interrupt stack is currently partially coded, but not yet
114 * implemented */
115 . = ALIGN(16384);
116 init_istack : { *(init_istack) }
117
118#ifdef CONFIG_64BIT
119 . = ALIGN(16); /* Linkage tables */
120 .opd : { *(.opd) } PROVIDE (__gp = .);
121 .plt : { *(.plt) }
122 .dlt : { *(.dlt) }
123#endif
124
125 . = ALIGN(16384);
126 __init_begin = .;
127 .init.text : {
128 _sinittext = .;
129 *(.init.text)
130 _einittext = .;
131 }
132 .init.data : { *(.init.data) }
133 . = ALIGN(16);
134 __setup_start = .;
135 .init.setup : { *(.init.setup) }
136 __setup_end = .;
137 __initcall_start = .;
138 .initcall.init : {
139 *(.initcall1.init)
140 *(.initcall2.init)
141 *(.initcall3.init)
142 *(.initcall4.init)
143 *(.initcall5.init)
144 *(.initcall6.init)
145 *(.initcall7.init)
146 }
147 __initcall_end = .;
148 __con_initcall_start = .;
149 .con_initcall.init : { *(.con_initcall.init) }
150 __con_initcall_end = .;
151 SECURITY_INIT
152 /* alternate instruction replacement. This is a mechanism x86 uses
153 * to detect the CPU type and replace generic instruction sequences
154 * with CPU specific ones. We don't currently do this in PA, but
155 * it seems like a good idea... */
156 . = ALIGN(4);
157 __alt_instructions = .;
158 .altinstructions : { *(.altinstructions) }
159 __alt_instructions_end = .;
160 .altinstr_replacement : { *(.altinstr_replacement) }
161 /* .exit.text is discard at runtime, not link time, to deal with references
162 from .altinstructions and .eh_frame */
163 .exit.text : { *(.exit.text) }
164 .exit.data : { *(.exit.data) }
165 . = ALIGN(4096);
166 __initramfs_start = .;
167 .init.ramfs : { *(.init.ramfs) }
168 __initramfs_end = .;
169 . = ALIGN(32);
170 __per_cpu_start = .;
171 .data.percpu : { *(.data.percpu) }
172 __per_cpu_end = .;
173 . = ALIGN(4096);
174 __init_end = .;
175 /* freed after init ends here */
176
177 __bss_start = .; /* BSS */
178 .bss : { *(.bss) *(COMMON) }
179 __bss_stop = .;
180
181 _end = . ;
182
183 /* Sections to be discarded */
184 /DISCARD/ : {
185 *(.exitcall.exit)
186#ifdef CONFIG_64BIT
187 /* temporary hack until binutils is fixed to not emit these
188 for static binaries */
189 *(.interp)
190 *(.dynsym)
191 *(.dynstr)
192 *(.dynamic)
193 *(.hash)
194#endif
195 }
196
197 /* Stabs debugging sections. */
198 .stab 0 : { *(.stab) }
199 .stabstr 0 : { *(.stabstr) }
200 .stab.excl 0 : { *(.stab.excl) }
201 .stab.exclstr 0 : { *(.stab.exclstr) }
202 .stab.index 0 : { *(.stab.index) }
203 .stab.indexstr 0 : { *(.stab.indexstr) }
204 .comment 0 : { *(.comment) }
205 .note 0 : { *(.note) }
206
207}