diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /arch/sparc/kernel | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/sparc/kernel')
75 files changed, 2464 insertions, 1204 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 5b47fab9966e..0c2dc1f24a9a 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -13,6 +13,14 @@ extra-y += init_task.o | |||
13 | CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) | 13 | CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) |
14 | extra-y += vmlinux.lds | 14 | extra-y += vmlinux.lds |
15 | 15 | ||
16 | ifdef CONFIG_FUNCTION_TRACER | ||
17 | # Do not profile debug and lowlevel utilities | ||
18 | CFLAGS_REMOVE_ftrace.o := -pg | ||
19 | CFLAGS_REMOVE_time_$(BITS).o := -pg | ||
20 | CFLAGS_REMOVE_perf_event.o := -pg | ||
21 | CFLAGS_REMOVE_pcr.o := -pg | ||
22 | endif | ||
23 | |||
16 | obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o | 24 | obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o |
17 | obj-$(CONFIG_SPARC32) += etrap_32.o | 25 | obj-$(CONFIG_SPARC32) += etrap_32.o |
18 | obj-$(CONFIG_SPARC32) += rtrap_32.o | 26 | obj-$(CONFIG_SPARC32) += rtrap_32.o |
@@ -72,7 +80,7 @@ obj-y += dma.o | |||
72 | obj-$(CONFIG_SPARC32_PCI) += pcic.o | 80 | obj-$(CONFIG_SPARC32_PCI) += pcic.o |
73 | 81 | ||
74 | obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o | 82 | obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o |
75 | obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o | 83 | obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o |
76 | obj-$(CONFIG_SPARC64_SMP) += hvtramp.o | 84 | obj-$(CONFIG_SPARC64_SMP) += hvtramp.o |
77 | 85 | ||
78 | obj-y += auxio_$(BITS).o | 86 | obj-y += auxio_$(BITS).o |
@@ -85,8 +93,9 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o | |||
85 | 93 | ||
86 | 94 | ||
87 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 95 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
88 | CFLAGS_REMOVE_ftrace.o := -pg | 96 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
89 | 97 | ||
98 | obj-$(CONFIG_EARLYFB) += btext.o | ||
90 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 99 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
91 | # sparc64 PCI | 100 | # sparc64 PCI |
92 | obj-$(CONFIG_SPARC64_PCI) += pci.o pci_common.o psycho_common.o | 101 | obj-$(CONFIG_SPARC64_PCI) += pci.o pci_common.o psycho_common.o |
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 9c115823c4b5..71ec90b9e316 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/miscdevice.h> | 12 | #include <linux/miscdevice.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
15 | #include <linux/of.h> | 14 | #include <linux/of.h> |
16 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
@@ -76,7 +75,6 @@ static inline void apc_free(struct of_device *op) | |||
76 | 75 | ||
77 | static int apc_open(struct inode *inode, struct file *f) | 76 | static int apc_open(struct inode *inode, struct file *f) |
78 | { | 77 | { |
79 | cycle_kernel_lock(); | ||
80 | return 0; | 78 | return 0; |
81 | } | 79 | } |
82 | 80 | ||
@@ -87,61 +85,46 @@ static int apc_release(struct inode *inode, struct file *f) | |||
87 | 85 | ||
88 | static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg) | 86 | static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg) |
89 | { | 87 | { |
90 | __u8 inarg, __user *arg; | 88 | __u8 inarg, __user *arg = (__u8 __user *) __arg; |
91 | |||
92 | arg = (__u8 __user *) __arg; | ||
93 | |||
94 | lock_kernel(); | ||
95 | 89 | ||
96 | switch (cmd) { | 90 | switch (cmd) { |
97 | case APCIOCGFANCTL: | 91 | case APCIOCGFANCTL: |
98 | if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg)) { | 92 | if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg)) |
99 | unlock_kernel(); | ||
100 | return -EFAULT; | 93 | return -EFAULT; |
101 | } | ||
102 | break; | 94 | break; |
103 | 95 | ||
104 | case APCIOCGCPWR: | 96 | case APCIOCGCPWR: |
105 | if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg)) { | 97 | if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg)) |
106 | unlock_kernel(); | ||
107 | return -EFAULT; | 98 | return -EFAULT; |
108 | } | ||
109 | break; | 99 | break; |
110 | 100 | ||
111 | case APCIOCGBPORT: | 101 | case APCIOCGBPORT: |
112 | if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg)) { | 102 | if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg)) |
113 | unlock_kernel(); | ||
114 | return -EFAULT; | 103 | return -EFAULT; |
115 | } | ||
116 | break; | 104 | break; |
117 | 105 | ||
118 | case APCIOCSFANCTL: | 106 | case APCIOCSFANCTL: |
119 | if (get_user(inarg, arg)) { | 107 | if (get_user(inarg, arg)) |
120 | unlock_kernel(); | ||
121 | return -EFAULT; | 108 | return -EFAULT; |
122 | } | ||
123 | apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG); | 109 | apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG); |
124 | break; | 110 | break; |
111 | |||
125 | case APCIOCSCPWR: | 112 | case APCIOCSCPWR: |
126 | if (get_user(inarg, arg)) { | 113 | if (get_user(inarg, arg)) |
127 | unlock_kernel(); | ||
128 | return -EFAULT; | 114 | return -EFAULT; |
129 | } | ||
130 | apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG); | 115 | apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG); |
131 | break; | 116 | break; |
117 | |||
132 | case APCIOCSBPORT: | 118 | case APCIOCSBPORT: |
133 | if (get_user(inarg, arg)) { | 119 | if (get_user(inarg, arg)) |
134 | unlock_kernel(); | ||
135 | return -EFAULT; | 120 | return -EFAULT; |
136 | } | ||
137 | apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG); | 121 | apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG); |
138 | break; | 122 | break; |
123 | |||
139 | default: | 124 | default: |
140 | unlock_kernel(); | ||
141 | return -EINVAL; | 125 | return -EINVAL; |
142 | }; | 126 | }; |
143 | 127 | ||
144 | unlock_kernel(); | ||
145 | return 0; | 128 | return 0; |
146 | } | 129 | } |
147 | 130 | ||
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c index 45c41232fc4c..ee8d214cae1e 100644 --- a/arch/sparc/kernel/auxio_32.c +++ b/arch/sparc/kernel/auxio_32.c | |||
@@ -28,6 +28,7 @@ void __init auxio_probe(void) | |||
28 | struct resource r; | 28 | struct resource r; |
29 | 29 | ||
30 | switch (sparc_cpu_model) { | 30 | switch (sparc_cpu_model) { |
31 | case sparc_leon: | ||
31 | case sun4d: | 32 | case sun4d: |
32 | case sun4: | 33 | case sun4: |
33 | return; | 34 | return; |
diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c new file mode 100644 index 000000000000..8cc2d56ffe9a --- /dev/null +++ b/arch/sparc/kernel/btext.c | |||
@@ -0,0 +1,673 @@ | |||
1 | /* | ||
2 | * Procedures for drawing on the screen early on in the boot process. | ||
3 | * | ||
4 | * Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/string.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/console.h> | ||
11 | |||
12 | #include <asm/btext.h> | ||
13 | #include <asm/oplib.h> | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | #define NO_SCROLL | ||
17 | |||
18 | #ifndef NO_SCROLL | ||
19 | static void scrollscreen(void); | ||
20 | #endif | ||
21 | |||
22 | static void draw_byte(unsigned char c, long locX, long locY); | ||
23 | static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); | ||
24 | static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); | ||
25 | static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); | ||
26 | |||
27 | #define __force_data __attribute__((__section__(".data"))) | ||
28 | |||
29 | static int g_loc_X __force_data; | ||
30 | static int g_loc_Y __force_data; | ||
31 | static int g_max_loc_X __force_data; | ||
32 | static int g_max_loc_Y __force_data; | ||
33 | |||
34 | static int dispDeviceRowBytes __force_data; | ||
35 | static int dispDeviceDepth __force_data; | ||
36 | static int dispDeviceRect[4] __force_data; | ||
37 | static unsigned char *dispDeviceBase __force_data; | ||
38 | |||
39 | #define cmapsz (16*256) | ||
40 | |||
41 | static unsigned char vga_font[cmapsz]; | ||
42 | |||
43 | static int __init btext_initialize(unsigned int node) | ||
44 | { | ||
45 | unsigned int width, height, depth, pitch; | ||
46 | unsigned long address = 0; | ||
47 | u32 prop; | ||
48 | |||
49 | if (prom_getproperty(node, "width", (char *)&width, 4) < 0) | ||
50 | return -EINVAL; | ||
51 | if (prom_getproperty(node, "height", (char *)&height, 4) < 0) | ||
52 | return -EINVAL; | ||
53 | if (prom_getproperty(node, "depth", (char *)&depth, 4) < 0) | ||
54 | return -EINVAL; | ||
55 | pitch = width * ((depth + 7) / 8); | ||
56 | |||
57 | if (prom_getproperty(node, "linebytes", (char *)&prop, 4) >= 0 && | ||
58 | prop != 0xffffffffu) | ||
59 | pitch = prop; | ||
60 | |||
61 | if (pitch == 1) | ||
62 | pitch = 0x1000; | ||
63 | |||
64 | if (prom_getproperty(node, "address", (char *)&prop, 4) >= 0) | ||
65 | address = prop; | ||
66 | |||
67 | /* FIXME: Add support for PCI reg properties. Right now, only | ||
68 | * reliable on macs | ||
69 | */ | ||
70 | if (address == 0) | ||
71 | return -EINVAL; | ||
72 | |||
73 | g_loc_X = 0; | ||
74 | g_loc_Y = 0; | ||
75 | g_max_loc_X = width / 8; | ||
76 | g_max_loc_Y = height / 16; | ||
77 | dispDeviceBase = (unsigned char *)address; | ||
78 | dispDeviceRowBytes = pitch; | ||
79 | dispDeviceDepth = depth == 15 ? 16 : depth; | ||
80 | dispDeviceRect[0] = dispDeviceRect[1] = 0; | ||
81 | dispDeviceRect[2] = width; | ||
82 | dispDeviceRect[3] = height; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* Calc the base address of a given point (x,y) */ | ||
88 | static unsigned char * calc_base(int x, int y) | ||
89 | { | ||
90 | unsigned char *base = dispDeviceBase; | ||
91 | |||
92 | base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3); | ||
93 | base += (y + dispDeviceRect[1]) * dispDeviceRowBytes; | ||
94 | return base; | ||
95 | } | ||
96 | |||
97 | static void btext_clearscreen(void) | ||
98 | { | ||
99 | unsigned int *base = (unsigned int *)calc_base(0, 0); | ||
100 | unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * | ||
101 | (dispDeviceDepth >> 3)) >> 2; | ||
102 | int i,j; | ||
103 | |||
104 | for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) | ||
105 | { | ||
106 | unsigned int *ptr = base; | ||
107 | for(j=width; j; --j) | ||
108 | *(ptr++) = 0; | ||
109 | base += (dispDeviceRowBytes >> 2); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | #ifndef NO_SCROLL | ||
114 | static void scrollscreen(void) | ||
115 | { | ||
116 | unsigned int *src = (unsigned int *)calc_base(0,16); | ||
117 | unsigned int *dst = (unsigned int *)calc_base(0,0); | ||
118 | unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * | ||
119 | (dispDeviceDepth >> 3)) >> 2; | ||
120 | int i,j; | ||
121 | |||
122 | for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) | ||
123 | { | ||
124 | unsigned int *src_ptr = src; | ||
125 | unsigned int *dst_ptr = dst; | ||
126 | for(j=width; j; --j) | ||
127 | *(dst_ptr++) = *(src_ptr++); | ||
128 | src += (dispDeviceRowBytes >> 2); | ||
129 | dst += (dispDeviceRowBytes >> 2); | ||
130 | } | ||
131 | for (i=0; i<16; i++) | ||
132 | { | ||
133 | unsigned int *dst_ptr = dst; | ||
134 | for(j=width; j; --j) | ||
135 | *(dst_ptr++) = 0; | ||
136 | dst += (dispDeviceRowBytes >> 2); | ||
137 | } | ||
138 | } | ||
139 | #endif /* ndef NO_SCROLL */ | ||
140 | |||
141 | void btext_drawchar(char c) | ||
142 | { | ||
143 | int cline = 0; | ||
144 | #ifdef NO_SCROLL | ||
145 | int x; | ||
146 | #endif | ||
147 | switch (c) { | ||
148 | case '\b': | ||
149 | if (g_loc_X > 0) | ||
150 | --g_loc_X; | ||
151 | break; | ||
152 | case '\t': | ||
153 | g_loc_X = (g_loc_X & -8) + 8; | ||
154 | break; | ||
155 | case '\r': | ||
156 | g_loc_X = 0; | ||
157 | break; | ||
158 | case '\n': | ||
159 | g_loc_X = 0; | ||
160 | g_loc_Y++; | ||
161 | cline = 1; | ||
162 | break; | ||
163 | default: | ||
164 | draw_byte(c, g_loc_X++, g_loc_Y); | ||
165 | } | ||
166 | if (g_loc_X >= g_max_loc_X) { | ||
167 | g_loc_X = 0; | ||
168 | g_loc_Y++; | ||
169 | cline = 1; | ||
170 | } | ||
171 | #ifndef NO_SCROLL | ||
172 | while (g_loc_Y >= g_max_loc_Y) { | ||
173 | scrollscreen(); | ||
174 | g_loc_Y--; | ||
175 | } | ||
176 | #else | ||
177 | /* wrap around from bottom to top of screen so we don't | ||
178 | waste time scrolling each line. -- paulus. */ | ||
179 | if (g_loc_Y >= g_max_loc_Y) | ||
180 | g_loc_Y = 0; | ||
181 | if (cline) { | ||
182 | for (x = 0; x < g_max_loc_X; ++x) | ||
183 | draw_byte(' ', x, g_loc_Y); | ||
184 | } | ||
185 | #endif | ||
186 | } | ||
187 | |||
188 | static void btext_drawtext(const char *c, unsigned int len) | ||
189 | { | ||
190 | while (len--) | ||
191 | btext_drawchar(*c++); | ||
192 | } | ||
193 | |||
194 | static void draw_byte(unsigned char c, long locX, long locY) | ||
195 | { | ||
196 | unsigned char *base = calc_base(locX << 3, locY << 4); | ||
197 | unsigned char *font = &vga_font[((unsigned int)c) * 16]; | ||
198 | int rb = dispDeviceRowBytes; | ||
199 | |||
200 | switch(dispDeviceDepth) { | ||
201 | case 24: | ||
202 | case 32: | ||
203 | draw_byte_32(font, (unsigned int *)base, rb); | ||
204 | break; | ||
205 | case 15: | ||
206 | case 16: | ||
207 | draw_byte_16(font, (unsigned int *)base, rb); | ||
208 | break; | ||
209 | case 8: | ||
210 | draw_byte_8(font, (unsigned int *)base, rb); | ||
211 | break; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static unsigned int expand_bits_8[16] = { | ||
216 | 0x00000000, | ||
217 | 0x000000ff, | ||
218 | 0x0000ff00, | ||
219 | 0x0000ffff, | ||
220 | 0x00ff0000, | ||
221 | 0x00ff00ff, | ||
222 | 0x00ffff00, | ||
223 | 0x00ffffff, | ||
224 | 0xff000000, | ||
225 | 0xff0000ff, | ||
226 | 0xff00ff00, | ||
227 | 0xff00ffff, | ||
228 | 0xffff0000, | ||
229 | 0xffff00ff, | ||
230 | 0xffffff00, | ||
231 | 0xffffffff | ||
232 | }; | ||
233 | |||
234 | static unsigned int expand_bits_16[4] = { | ||
235 | 0x00000000, | ||
236 | 0x0000ffff, | ||
237 | 0xffff0000, | ||
238 | 0xffffffff | ||
239 | }; | ||
240 | |||
241 | |||
242 | static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) | ||
243 | { | ||
244 | int l, bits; | ||
245 | int fg = 0xFFFFFFFFUL; | ||
246 | int bg = 0x00000000UL; | ||
247 | |||
248 | for (l = 0; l < 16; ++l) | ||
249 | { | ||
250 | bits = *font++; | ||
251 | base[0] = (-(bits >> 7) & fg) ^ bg; | ||
252 | base[1] = (-((bits >> 6) & 1) & fg) ^ bg; | ||
253 | base[2] = (-((bits >> 5) & 1) & fg) ^ bg; | ||
254 | base[3] = (-((bits >> 4) & 1) & fg) ^ bg; | ||
255 | base[4] = (-((bits >> 3) & 1) & fg) ^ bg; | ||
256 | base[5] = (-((bits >> 2) & 1) & fg) ^ bg; | ||
257 | base[6] = (-((bits >> 1) & 1) & fg) ^ bg; | ||
258 | base[7] = (-(bits & 1) & fg) ^ bg; | ||
259 | base = (unsigned int *) ((char *)base + rb); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static void draw_byte_16(unsigned char *font, unsigned int *base, int rb) | ||
264 | { | ||
265 | int l, bits; | ||
266 | int fg = 0xFFFFFFFFUL; | ||
267 | int bg = 0x00000000UL; | ||
268 | unsigned int *eb = (int *)expand_bits_16; | ||
269 | |||
270 | for (l = 0; l < 16; ++l) | ||
271 | { | ||
272 | bits = *font++; | ||
273 | base[0] = (eb[bits >> 6] & fg) ^ bg; | ||
274 | base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; | ||
275 | base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; | ||
276 | base[3] = (eb[bits & 3] & fg) ^ bg; | ||
277 | base = (unsigned int *) ((char *)base + rb); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | static void draw_byte_8(unsigned char *font, unsigned int *base, int rb) | ||
282 | { | ||
283 | int l, bits; | ||
284 | int fg = 0x0F0F0F0FUL; | ||
285 | int bg = 0x00000000UL; | ||
286 | unsigned int *eb = (int *)expand_bits_8; | ||
287 | |||
288 | for (l = 0; l < 16; ++l) | ||
289 | { | ||
290 | bits = *font++; | ||
291 | base[0] = (eb[bits >> 4] & fg) ^ bg; | ||
292 | base[1] = (eb[bits & 0xf] & fg) ^ bg; | ||
293 | base = (unsigned int *) ((char *)base + rb); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | static void btext_console_write(struct console *con, const char *s, | ||
298 | unsigned int n) | ||
299 | { | ||
300 | btext_drawtext(s, n); | ||
301 | } | ||
302 | |||
303 | static struct console btext_console = { | ||
304 | .name = "btext", | ||
305 | .write = btext_console_write, | ||
306 | .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME, | ||
307 | .index = 0, | ||
308 | }; | ||
309 | |||
310 | int __init btext_find_display(void) | ||
311 | { | ||
312 | unsigned int node; | ||
313 | char type[32]; | ||
314 | int ret; | ||
315 | |||
316 | node = prom_inst2pkg(prom_stdout); | ||
317 | if (prom_getproperty(node, "device_type", type, 32) < 0) | ||
318 | return -ENODEV; | ||
319 | if (strcmp(type, "display")) | ||
320 | return -ENODEV; | ||
321 | |||
322 | ret = btext_initialize(node); | ||
323 | if (!ret) { | ||
324 | btext_clearscreen(); | ||
325 | register_console(&btext_console); | ||
326 | } | ||
327 | return ret; | ||
328 | } | ||
329 | |||
330 | static unsigned char vga_font[cmapsz] = { | ||
331 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, | ||
333 | 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, | ||
334 | 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
335 | 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, | ||
336 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, | ||
337 | 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, | ||
338 | 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
339 | 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, | ||
340 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, | ||
341 | 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | ||
342 | 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
343 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, | ||
344 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, | ||
345 | 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, | ||
346 | 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, | ||
347 | 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, | ||
348 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, | ||
349 | 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, | ||
350 | 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, | ||
351 | 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, | ||
352 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, | ||
353 | 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, | ||
354 | 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, | ||
355 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, | ||
356 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
357 | 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, | ||
358 | 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, | ||
359 | 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, | ||
360 | 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
361 | 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, | ||
362 | 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
363 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
364 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
365 | 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
366 | 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
367 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, | ||
368 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, | ||
369 | 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
370 | 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
371 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, | ||
372 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, | ||
373 | 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
374 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
375 | 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, | ||
376 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, | ||
377 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, | ||
378 | 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, | ||
379 | 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, | ||
380 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, | ||
381 | 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, | ||
382 | 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
383 | 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
384 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, | ||
385 | 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, | ||
386 | 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, | ||
387 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, | ||
388 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, | ||
389 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
390 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, | ||
391 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
392 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
393 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
394 | 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, | ||
395 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, | ||
396 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, | ||
397 | 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, | ||
398 | 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, | ||
399 | 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, | ||
400 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, | ||
401 | 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, | ||
402 | 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
403 | 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
404 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, | ||
405 | 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, | ||
406 | 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
407 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, | ||
408 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, | ||
409 | 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
410 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, | ||
411 | 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, | ||
412 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, | ||
413 | 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, | ||
414 | 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, | ||
415 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, | ||
416 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, | ||
417 | 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, | ||
418 | 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
419 | 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, | ||
420 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, | ||
421 | 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, | ||
422 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, | ||
423 | 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, | ||
424 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, | ||
425 | 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, | ||
426 | 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, | ||
427 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
428 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
429 | 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, | ||
430 | 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, | ||
431 | 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, | ||
432 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, | ||
433 | 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, | ||
434 | 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, | ||
435 | 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, | ||
436 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
437 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, | ||
438 | 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, | ||
439 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, | ||
440 | 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, | ||
441 | 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, | ||
442 | 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
443 | 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
444 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
445 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, | ||
446 | 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, | ||
447 | 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, | ||
448 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, | ||
449 | 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, | ||
450 | 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
451 | 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, | ||
452 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, | ||
453 | 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||
454 | 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, | ||
455 | 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, | ||
456 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
457 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
458 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, | ||
459 | 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
460 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, | ||
461 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, | ||
462 | 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
463 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, | ||
464 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, | ||
465 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
466 | 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
467 | 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, | ||
468 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, | ||
469 | 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, | ||
470 | 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, | ||
471 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
472 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, | ||
473 | 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, | ||
474 | 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, | ||
475 | 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
476 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, | ||
477 | 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
478 | 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, | ||
479 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
480 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, | ||
481 | 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
482 | 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, | ||
483 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, | ||
484 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, | ||
485 | 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, | ||
486 | 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, | ||
487 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, | ||
488 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, | ||
489 | 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
490 | 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, | ||
491 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, | ||
492 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, | ||
493 | 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
494 | 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, | ||
495 | 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, | ||
496 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, | ||
497 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, | ||
498 | 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, | ||
499 | 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
500 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, | ||
501 | 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, | ||
502 | 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, | ||
503 | 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, | ||
504 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, | ||
505 | 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, | ||
506 | 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
507 | 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, | ||
508 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, | ||
509 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, | ||
510 | 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
511 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, | ||
512 | 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, | ||
513 | 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, | ||
514 | 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
515 | 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, | ||
516 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, | ||
517 | 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, | ||
518 | 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
519 | 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
520 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, | ||
521 | 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, | ||
522 | 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
523 | 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, | ||
524 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, | ||
525 | 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, | ||
526 | 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, | ||
527 | 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
528 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, | ||
529 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, | ||
530 | 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
531 | 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, | ||
532 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, | ||
533 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, | ||
534 | 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, | ||
535 | 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
536 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
537 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, | ||
538 | 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, | ||
539 | 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, | ||
540 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, | ||
541 | 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, | ||
542 | 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, | ||
543 | 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
544 | 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, | ||
545 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, | ||
546 | 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
547 | 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
548 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, | ||
549 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, | ||
550 | 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, | ||
551 | 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, | ||
552 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, | ||
553 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, | ||
554 | 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
555 | 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, | ||
556 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, | ||
557 | 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
558 | 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
559 | 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, | ||
560 | 0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, | ||
561 | 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, | ||
562 | 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, | ||
563 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, | ||
564 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, | ||
565 | 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, | ||
566 | 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, | ||
567 | 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, | ||
568 | 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, | ||
569 | 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, | ||
570 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
571 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, | ||
572 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, | ||
573 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, | ||
574 | 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
575 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, | ||
576 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, | ||
577 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, | ||
578 | 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
579 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
580 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, | ||
581 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
582 | 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
583 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, | ||
584 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, | ||
585 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
586 | 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
587 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, | ||
588 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, | ||
589 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
590 | 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
591 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, | ||
592 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, | ||
593 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, | ||
594 | 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
595 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, | ||
596 | 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, | ||
597 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
598 | 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
599 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, | ||
600 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, | ||
601 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
602 | 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
603 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, | ||
604 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, | ||
605 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, | ||
606 | 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
607 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, | ||
608 | 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, | ||
609 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
610 | 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
611 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, | ||
612 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, | ||
613 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, | ||
614 | 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
615 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, | ||
616 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, | ||
617 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
618 | 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
619 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, | ||
620 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, | ||
621 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
622 | 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
623 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
624 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, | ||
625 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, | ||
626 | 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, | ||
627 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | ||
628 | 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, | ||
629 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
630 | 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
631 | 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, | ||
632 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, | ||
633 | 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
634 | 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, | ||
635 | 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, | ||
636 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, | ||
637 | 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
638 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, | ||
639 | 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
640 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, | ||
641 | 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, | ||
642 | 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, | ||
643 | 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, | ||
644 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, | ||
645 | 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
646 | 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
647 | 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, | ||
648 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, | ||
649 | 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, | ||
650 | 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
651 | 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, | ||
652 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, | ||
653 | 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, | ||
654 | 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
655 | 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, | ||
656 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, | ||
657 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
658 | 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, | ||
659 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, | ||
660 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, | ||
661 | 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, | ||
662 | 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
663 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, | ||
664 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
665 | 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, | ||
666 | 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, | ||
667 | 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
668 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, | ||
669 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
670 | 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
671 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
672 | 0x00, 0x00, 0x00, 0x00, | ||
673 | }; | ||
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index f3b5466c389c..415c86d5a8da 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/slab.h> | ||
8 | #include <linux/string.h> | 9 | #include <linux/string.h> |
9 | #include <linux/init.h> | 10 | #include <linux/init.h> |
10 | #include <linux/of_device.h> | 11 | #include <linux/of_device.h> |
@@ -99,7 +100,7 @@ static int __devinit clock_board_probe(struct of_device *op, | |||
99 | 100 | ||
100 | p->leds_resource.start = (unsigned long) | 101 | p->leds_resource.start = (unsigned long) |
101 | (p->clock_regs + CLOCK_CTRL); | 102 | (p->clock_regs + CLOCK_CTRL); |
102 | p->leds_resource.end = p->leds_resource.end; | 103 | p->leds_resource.end = p->leds_resource.start; |
103 | p->leds_resource.name = "leds"; | 104 | p->leds_resource.name = "leds"; |
104 | 105 | ||
105 | p->leds_pdev.name = "sunfire-clockboard-leds"; | 106 | p->leds_pdev.name = "sunfire-clockboard-leds"; |
@@ -194,7 +195,7 @@ static int __devinit fhc_probe(struct of_device *op, | |||
194 | if (!p->central) { | 195 | if (!p->central) { |
195 | p->leds_resource.start = (unsigned long) | 196 | p->leds_resource.start = (unsigned long) |
196 | (p->pregs + FHC_PREGS_CTRL); | 197 | (p->pregs + FHC_PREGS_CTRL); |
197 | p->leds_resource.end = p->leds_resource.end; | 198 | p->leds_resource.end = p->leds_resource.start; |
198 | p->leds_resource.name = "leds"; | 199 | p->leds_resource.name = "leds"; |
199 | 200 | ||
200 | p->leds_pdev.name = "sunfire-fhc-leds"; | 201 | p->leds_pdev.name = "sunfire-fhc-leds"; |
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 1446df90ef85..e447938d39cf 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c | |||
@@ -185,6 +185,17 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { | |||
185 | FPU(-1, NULL) | 185 | FPU(-1, NULL) |
186 | } | 186 | } |
187 | },{ | 187 | },{ |
188 | 0xF, /* Aeroflex Gaisler */ | ||
189 | .cpu_info = { | ||
190 | CPU(3, "LEON"), | ||
191 | CPU(-1, NULL) | ||
192 | }, | ||
193 | .fpu_info = { | ||
194 | FPU(2, "GRFPU"), | ||
195 | FPU(3, "GRFPU-Lite"), | ||
196 | FPU(-1, NULL) | ||
197 | } | ||
198 | },{ | ||
188 | 0x17, | 199 | 0x17, |
189 | .cpu_info = { | 200 | .cpu_info = { |
190 | CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"), | 201 | CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"), |
diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 7430ed080b23..8de64c8126bc 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/slab.h> | ||
7 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
9 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index b171ae8de90d..62dc7a021413 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c | |||
@@ -59,7 +59,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, | |||
59 | 59 | ||
60 | cur_inst = 0; | 60 | cur_inst = 0; |
61 | for_each_node_by_type(dp, "cpu") { | 61 | for_each_node_by_type(dp, "cpu") { |
62 | int err = check_cpu_node(dp->node, &cur_inst, | 62 | int err = check_cpu_node(dp->phandle, &cur_inst, |
63 | compare, compare_arg, | 63 | compare, compare_arg, |
64 | prom_node, mid); | 64 | prom_node, mid); |
65 | if (!err) { | 65 | if (!err) { |
@@ -143,6 +143,4 @@ void __init device_scan(void) | |||
143 | 143 | ||
144 | if (ARCH_SUN4C) | 144 | if (ARCH_SUN4C) |
145 | sun4c_probe_memerr_reg(); | 145 | sun4c_probe_memerr_reg(); |
146 | |||
147 | return; | ||
148 | } | 146 | } |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f41ecc5ac0b4..1504df8ddf70 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -400,6 +400,39 @@ linux_trap_ipi15_sun4d: | |||
400 | /* FIXME */ | 400 | /* FIXME */ |
401 | 1: b,a 1b | 401 | 1: b,a 1b |
402 | 402 | ||
403 | #ifdef CONFIG_SPARC_LEON | ||
404 | |||
405 | .globl smpleon_ticker | ||
406 | /* SMP per-cpu ticker interrupts are handled specially. */ | ||
407 | smpleon_ticker: | ||
408 | SAVE_ALL | ||
409 | or %l0, PSR_PIL, %g2 | ||
410 | wr %g2, 0x0, %psr | ||
411 | WRITE_PAUSE | ||
412 | wr %g2, PSR_ET, %psr | ||
413 | WRITE_PAUSE | ||
414 | call leon_percpu_timer_interrupt | ||
415 | add %sp, STACKFRAME_SZ, %o0 | ||
416 | wr %l0, PSR_ET, %psr | ||
417 | WRITE_PAUSE | ||
418 | RESTORE_ALL | ||
419 | |||
420 | .align 4 | ||
421 | .globl linux_trap_ipi15_leon | ||
422 | linux_trap_ipi15_leon: | ||
423 | SAVE_ALL | ||
424 | or %l0, PSR_PIL, %l4 | ||
425 | wr %l4, 0x0, %psr | ||
426 | WRITE_PAUSE | ||
427 | wr %l4, PSR_ET, %psr | ||
428 | WRITE_PAUSE | ||
429 | call leon_cross_call_irq | ||
430 | nop | ||
431 | b ret_trap_lockless_ipi | ||
432 | clr %l6 | ||
433 | |||
434 | #endif /* CONFIG_SPARC_LEON */ | ||
435 | |||
403 | #endif /* CONFIG_SMP */ | 436 | #endif /* CONFIG_SMP */ |
404 | 437 | ||
405 | /* This routine handles illegal instructions and privileged | 438 | /* This routine handles illegal instructions and privileged |
@@ -1261,7 +1294,7 @@ linux_sparc_syscall: | |||
1261 | sethi %hi(PSR_SYSCALL), %l4 | 1294 | sethi %hi(PSR_SYSCALL), %l4 |
1262 | or %l0, %l4, %l0 | 1295 | or %l0, %l4, %l0 |
1263 | /* Direct access to user regs, must faster. */ | 1296 | /* Direct access to user regs, must faster. */ |
1264 | cmp %g1, NR_SYSCALLS | 1297 | cmp %g1, NR_syscalls |
1265 | bgeu linux_sparc_ni_syscall | 1298 | bgeu linux_sparc_ni_syscall |
1266 | sll %g1, 2, %l4 | 1299 | sll %g1, 2, %l4 |
1267 | ld [%l7 + %l4], %l7 | 1300 | ld [%l7 + %l4], %l7 |
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 4f53a2395ac6..c011b932bb17 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
@@ -48,7 +48,6 @@ extern void __init boot_cpu_id_too_large(int cpu); | |||
48 | extern unsigned int dcache_parity_tl1_occurred; | 48 | extern unsigned int dcache_parity_tl1_occurred; |
49 | extern unsigned int icache_parity_tl1_occurred; | 49 | extern unsigned int icache_parity_tl1_occurred; |
50 | 50 | ||
51 | extern asmlinkage void update_perfctrs(void); | ||
52 | extern asmlinkage void sparc_breakpoint(struct pt_regs *regs); | 51 | extern asmlinkage void sparc_breakpoint(struct pt_regs *regs); |
53 | extern void timer_interrupt(int irq, struct pt_regs *regs); | 52 | extern void timer_interrupt(int irq, struct pt_regs *regs); |
54 | 53 | ||
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index d3b1a3076569..03ab022e51c5 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/percpu.h> | 4 | #include <linux/percpu.h> |
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/list.h> | 6 | #include <linux/list.h> |
7 | #include <trace/syscall.h> | ||
7 | 8 | ||
8 | #include <asm/ftrace.h> | 9 | #include <asm/ftrace.h> |
9 | 10 | ||
@@ -12,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000; | |||
12 | 13 | ||
13 | static u32 ftrace_call_replace(unsigned long ip, unsigned long addr) | 14 | static u32 ftrace_call_replace(unsigned long ip, unsigned long addr) |
14 | { | 15 | { |
15 | static u32 call; | 16 | u32 call; |
16 | s32 off; | 17 | s32 off; |
17 | 18 | ||
18 | off = ((s32)addr - (s32)ip); | 19 | off = ((s32)addr - (s32)ip); |
@@ -91,3 +92,60 @@ int __init ftrace_dyn_arch_init(void *data) | |||
91 | } | 92 | } |
92 | #endif | 93 | #endif |
93 | 94 | ||
95 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
96 | |||
97 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
98 | extern void ftrace_graph_call(void); | ||
99 | |||
100 | int ftrace_enable_ftrace_graph_caller(void) | ||
101 | { | ||
102 | unsigned long ip = (unsigned long)(&ftrace_graph_call); | ||
103 | u32 old, new; | ||
104 | |||
105 | old = *(u32 *) &ftrace_graph_call; | ||
106 | new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller); | ||
107 | return ftrace_modify_code(ip, old, new); | ||
108 | } | ||
109 | |||
110 | int ftrace_disable_ftrace_graph_caller(void) | ||
111 | { | ||
112 | unsigned long ip = (unsigned long)(&ftrace_graph_call); | ||
113 | u32 old, new; | ||
114 | |||
115 | old = *(u32 *) &ftrace_graph_call; | ||
116 | new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub); | ||
117 | |||
118 | return ftrace_modify_code(ip, old, new); | ||
119 | } | ||
120 | |||
121 | #endif /* !CONFIG_DYNAMIC_FTRACE */ | ||
122 | |||
123 | /* | ||
124 | * Hook the return address and push it in the stack of return addrs | ||
125 | * in current thread info. | ||
126 | */ | ||
127 | unsigned long prepare_ftrace_return(unsigned long parent, | ||
128 | unsigned long self_addr, | ||
129 | unsigned long frame_pointer) | ||
130 | { | ||
131 | unsigned long return_hooker = (unsigned long) &return_to_handler; | ||
132 | struct ftrace_graph_ent trace; | ||
133 | |||
134 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | ||
135 | return parent + 8UL; | ||
136 | |||
137 | if (ftrace_push_return_trace(parent, self_addr, &trace.depth, | ||
138 | frame_pointer) == -EBUSY) | ||
139 | return parent + 8UL; | ||
140 | |||
141 | trace.func = self_addr; | ||
142 | |||
143 | /* Only trace if the calling function expects to */ | ||
144 | if (!ftrace_graph_entry(&trace)) { | ||
145 | current->curr_ret_stack--; | ||
146 | return parent + 8UL; | ||
147 | } | ||
148 | |||
149 | return return_hooker; | ||
150 | } | ||
151 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 439d82a95ac9..21bb2590d4ae 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S | |||
@@ -811,9 +811,31 @@ found_version: | |||
811 | got_prop: | 811 | got_prop: |
812 | #ifdef CONFIG_SPARC_LEON | 812 | #ifdef CONFIG_SPARC_LEON |
813 | /* no cpu-type check is needed, it is a SPARC-LEON */ | 813 | /* no cpu-type check is needed, it is a SPARC-LEON */ |
814 | #ifdef CONFIG_SMP | ||
815 | ba leon_smp_init | ||
816 | nop | ||
817 | |||
818 | .global leon_smp_init | ||
819 | leon_smp_init: | ||
820 | sethi %hi(boot_cpu_id), %g1 ! master always 0 | ||
821 | stb %g0, [%g1 + %lo(boot_cpu_id)] | ||
822 | sethi %hi(boot_cpu_id4), %g1 ! master always 0 | ||
823 | stb %g0, [%g1 + %lo(boot_cpu_id4)] | ||
824 | |||
825 | rd %asr17,%g1 | ||
826 | srl %g1,28,%g1 | ||
827 | |||
828 | cmp %g0,%g1 | ||
829 | beq sun4c_continue_boot !continue with master | ||
830 | nop | ||
831 | |||
832 | ba leon_smp_cpu_startup | ||
833 | nop | ||
834 | #else | ||
814 | ba sun4c_continue_boot | 835 | ba sun4c_continue_boot |
815 | nop | 836 | nop |
816 | #endif | 837 | #endif |
838 | #endif | ||
817 | set cputypval, %o2 | 839 | set cputypval, %o2 |
818 | ldub [%o2 + 0x4], %l1 | 840 | ldub [%o2 + 0x4], %l1 |
819 | 841 | ||
diff --git a/arch/sparc/kernel/helpers.S b/arch/sparc/kernel/helpers.S index 314dd0c9fc5b..92090cc9e829 100644 --- a/arch/sparc/kernel/helpers.S +++ b/arch/sparc/kernel/helpers.S | |||
@@ -46,6 +46,81 @@ stack_trace_flush: | |||
46 | nop | 46 | nop |
47 | .size stack_trace_flush,.-stack_trace_flush | 47 | .size stack_trace_flush,.-stack_trace_flush |
48 | 48 | ||
49 | #ifdef CONFIG_PERF_EVENTS | ||
50 | .globl perf_arch_fetch_caller_regs | ||
51 | .type perf_arch_fetch_caller_regs,#function | ||
52 | perf_arch_fetch_caller_regs: | ||
53 | /* We always read the %pstate into %o5 since we will use | ||
54 | * that to construct a fake %tstate to store into the regs. | ||
55 | */ | ||
56 | rdpr %pstate, %o5 | ||
57 | brz,pn %o2, 50f | ||
58 | mov %o2, %g7 | ||
59 | |||
60 | /* Turn off interrupts while we walk around the register | ||
61 | * window by hand. | ||
62 | */ | ||
63 | wrpr %o5, PSTATE_IE, %pstate | ||
64 | |||
65 | /* The %canrestore tells us how many register windows are | ||
66 | * still live in the chip above us, past that we have to | ||
67 | * walk the frame as saved on the stack. We stash away | ||
68 | * the %cwp in %g1 so we can return back to the original | ||
69 | * register window. | ||
70 | */ | ||
71 | rdpr %cwp, %g1 | ||
72 | rdpr %canrestore, %g2 | ||
73 | sub %g1, 1, %g3 | ||
74 | |||
75 | /* We have the skip count in %g7, if it hits zero then | ||
76 | * %fp/%i7 are the registers we need. Otherwise if our | ||
77 | * %canrestore count maintained in %g2 hits zero we have | ||
78 | * to start traversing the stack. | ||
79 | */ | ||
80 | 10: brz,pn %g2, 4f | ||
81 | sub %g2, 1, %g2 | ||
82 | wrpr %g3, %cwp | ||
83 | subcc %g7, 1, %g7 | ||
84 | bne,pt %xcc, 10b | ||
85 | sub %g3, 1, %g3 | ||
86 | |||
87 | /* We found the values we need in the cpu's register | ||
88 | * windows. | ||
89 | */ | ||
90 | mov %fp, %g3 | ||
91 | ba,pt %xcc, 3f | ||
92 | mov %i7, %g2 | ||
93 | |||
94 | 50: mov %fp, %g3 | ||
95 | ba,pt %xcc, 2f | ||
96 | mov %i7, %g2 | ||
97 | |||
98 | /* We hit the end of the valid register windows in the | ||
99 | * cpu, start traversing the stack frame. | ||
100 | */ | ||
101 | 4: mov %fp, %g3 | ||
102 | |||
103 | 20: ldx [%g3 + STACK_BIAS + RW_V9_I7], %g2 | ||
104 | subcc %g7, 1, %g7 | ||
105 | bne,pn %xcc, 20b | ||
106 | ldx [%g3 + STACK_BIAS + RW_V9_I6], %g3 | ||
107 | |||
108 | /* Restore the current register window position and | ||
109 | * re-enable interrupts. | ||
110 | */ | ||
111 | 3: wrpr %g1, %cwp | ||
112 | wrpr %o5, %pstate | ||
113 | |||
114 | 2: stx %g3, [%o0 + PT_V9_FP] | ||
115 | sllx %o5, 8, %o5 | ||
116 | stx %o5, [%o0 + PT_V9_TSTATE] | ||
117 | stx %g2, [%o0 + PT_V9_TPC] | ||
118 | add %g2, 4, %g2 | ||
119 | retl | ||
120 | stx %g2, [%o0 + PT_V9_TNPC] | ||
121 | .size perf_arch_fetch_caller_regs,.-perf_arch_fetch_caller_regs | ||
122 | #endif /* CONFIG_PERF_EVENTS */ | ||
123 | |||
49 | #ifdef CONFIG_SMP | 124 | #ifdef CONFIG_SMP |
50 | .globl hard_smp_processor_id | 125 | .globl hard_smp_processor_id |
51 | .type hard_smp_processor_id,#function | 126 | .type hard_smp_processor_id,#function |
diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 1d272c3b5740..7c60afb835b0 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/slab.h> | ||
9 | 8 | ||
10 | #include <asm/hypervisor.h> | 9 | #include <asm/hypervisor.h> |
11 | #include <asm/oplib.h> | 10 | #include <asm/oplib.h> |
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 7690cc219ecc..47977a77f6c6 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c | |||
@@ -6,11 +6,13 @@ | |||
6 | 6 | ||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/slab.h> | ||
9 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
10 | #include <linux/device.h> | 11 | #include <linux/device.h> |
11 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
12 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
13 | #include <linux/iommu-helper.h> | 14 | #include <linux/iommu-helper.h> |
15 | #include <linux/bitmap.h> | ||
14 | 16 | ||
15 | #ifdef CONFIG_PCI | 17 | #ifdef CONFIG_PCI |
16 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
@@ -169,7 +171,7 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long np | |||
169 | 171 | ||
170 | entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; | 172 | entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; |
171 | 173 | ||
172 | iommu_area_free(arena->map, entry, npages); | 174 | bitmap_clear(arena->map, entry, npages); |
173 | } | 175 | } |
174 | 176 | ||
175 | int iommu_table_init(struct iommu *iommu, int tsbsize, | 177 | int iommu_table_init(struct iommu *iommu, int tsbsize, |
@@ -861,13 +863,3 @@ int dma_supported(struct device *dev, u64 device_mask) | |||
861 | return 0; | 863 | return 0; |
862 | } | 864 | } |
863 | EXPORT_SYMBOL(dma_supported); | 865 | EXPORT_SYMBOL(dma_supported); |
864 | |||
865 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
866 | { | ||
867 | #ifdef CONFIG_PCI | ||
868 | if (dev->bus == &pci_bus_type) | ||
869 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | ||
870 | #endif | ||
871 | return -EINVAL; | ||
872 | } | ||
873 | EXPORT_SYMBOL(dma_set_mask); | ||
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 9f61fd8cbb7b..84e5386714cd 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
@@ -48,8 +48,13 @@ | |||
48 | #include <asm/dma.h> | 48 | #include <asm/dma.h> |
49 | #include <asm/iommu.h> | 49 | #include <asm/iommu.h> |
50 | #include <asm/io-unit.h> | 50 | #include <asm/io-unit.h> |
51 | #include <asm/leon.h> | ||
51 | 52 | ||
53 | #ifdef CONFIG_SPARC_LEON | ||
54 | #define mmu_inval_dma_area(p, l) leon_flush_dcache_all() | ||
55 | #else | ||
52 | #define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ | 56 | #define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ |
57 | #endif | ||
53 | 58 | ||
54 | static struct resource *_sparc_find_resource(struct resource *r, | 59 | static struct resource *_sparc_find_resource(struct resource *r, |
55 | unsigned long); | 60 | unsigned long); |
@@ -671,17 +676,6 @@ int dma_supported(struct device *dev, u64 mask) | |||
671 | } | 676 | } |
672 | EXPORT_SYMBOL(dma_supported); | 677 | EXPORT_SYMBOL(dma_supported); |
673 | 678 | ||
674 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
675 | { | ||
676 | #ifdef CONFIG_PCI | ||
677 | if (dev->bus == &pci_bus_type) | ||
678 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | ||
679 | #endif | ||
680 | return -EOPNOTSUPP; | ||
681 | } | ||
682 | EXPORT_SYMBOL(dma_set_mask); | ||
683 | |||
684 | |||
685 | #ifdef CONFIG_PROC_FS | 679 | #ifdef CONFIG_PROC_FS |
686 | 680 | ||
687 | static int sparc_io_proc_show(struct seq_file *m, void *v) | 681 | static int sparc_io_proc_show(struct seq_file *m, void *v) |
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 8ab1d4728a4b..830d70a3e20b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -20,7 +20,9 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/ftrace.h> | ||
23 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/kmemleak.h> | ||
24 | 26 | ||
25 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
26 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
@@ -45,6 +47,7 @@ | |||
45 | 47 | ||
46 | #include "entry.h" | 48 | #include "entry.h" |
47 | #include "cpumap.h" | 49 | #include "cpumap.h" |
50 | #include "kstack.h" | ||
48 | 51 | ||
49 | #define NUM_IVECS (IMAP_INR + 1) | 52 | #define NUM_IVECS (IMAP_INR + 1) |
50 | 53 | ||
@@ -176,7 +179,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
176 | } | 179 | } |
177 | 180 | ||
178 | if (i < NR_IRQS) { | 181 | if (i < NR_IRQS) { |
179 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 182 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); |
180 | action = irq_desc[i].action; | 183 | action = irq_desc[i].action; |
181 | if (!action) | 184 | if (!action) |
182 | goto skip; | 185 | goto skip; |
@@ -187,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
187 | for_each_online_cpu(j) | 190 | for_each_online_cpu(j) |
188 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | 191 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); |
189 | #endif | 192 | #endif |
190 | seq_printf(p, " %9s", irq_desc[i].chip->typename); | 193 | seq_printf(p, " %9s", irq_desc[i].chip->name); |
191 | seq_printf(p, " %s", action->name); | 194 | seq_printf(p, " %s", action->name); |
192 | 195 | ||
193 | for (action=action->next; action; action = action->next) | 196 | for (action=action->next; action; action = action->next) |
@@ -195,7 +198,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
195 | 198 | ||
196 | seq_putc(p, '\n'); | 199 | seq_putc(p, '\n'); |
197 | skip: | 200 | skip: |
198 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 201 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
199 | } else if (i == NR_IRQS) { | 202 | } else if (i == NR_IRQS) { |
200 | seq_printf(p, "NMI: "); | 203 | seq_printf(p, "NMI: "); |
201 | for_each_online_cpu(j) | 204 | for_each_online_cpu(j) |
@@ -250,12 +253,12 @@ struct irq_handler_data { | |||
250 | }; | 253 | }; |
251 | 254 | ||
252 | #ifdef CONFIG_SMP | 255 | #ifdef CONFIG_SMP |
253 | static int irq_choose_cpu(unsigned int virt_irq) | 256 | static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) |
254 | { | 257 | { |
255 | cpumask_t mask; | 258 | cpumask_t mask; |
256 | int cpuid; | 259 | int cpuid; |
257 | 260 | ||
258 | cpumask_copy(&mask, irq_desc[virt_irq].affinity); | 261 | cpumask_copy(&mask, affinity); |
259 | if (cpus_equal(mask, cpu_online_map)) { | 262 | if (cpus_equal(mask, cpu_online_map)) { |
260 | cpuid = map_to_cpu(virt_irq); | 263 | cpuid = map_to_cpu(virt_irq); |
261 | } else { | 264 | } else { |
@@ -268,10 +271,8 @@ static int irq_choose_cpu(unsigned int virt_irq) | |||
268 | return cpuid; | 271 | return cpuid; |
269 | } | 272 | } |
270 | #else | 273 | #else |
271 | static int irq_choose_cpu(unsigned int virt_irq) | 274 | #define irq_choose_cpu(virt_irq, affinity) \ |
272 | { | 275 | real_hard_smp_processor_id() |
273 | return real_hard_smp_processor_id(); | ||
274 | } | ||
275 | #endif | 276 | #endif |
276 | 277 | ||
277 | static void sun4u_irq_enable(unsigned int virt_irq) | 278 | static void sun4u_irq_enable(unsigned int virt_irq) |
@@ -282,7 +283,8 @@ static void sun4u_irq_enable(unsigned int virt_irq) | |||
282 | unsigned long cpuid, imap, val; | 283 | unsigned long cpuid, imap, val; |
283 | unsigned int tid; | 284 | unsigned int tid; |
284 | 285 | ||
285 | cpuid = irq_choose_cpu(virt_irq); | 286 | cpuid = irq_choose_cpu(virt_irq, |
287 | irq_desc[virt_irq].affinity); | ||
286 | imap = data->imap; | 288 | imap = data->imap; |
287 | 289 | ||
288 | tid = sun4u_compute_tid(imap, cpuid); | 290 | tid = sun4u_compute_tid(imap, cpuid); |
@@ -299,7 +301,24 @@ static void sun4u_irq_enable(unsigned int virt_irq) | |||
299 | static int sun4u_set_affinity(unsigned int virt_irq, | 301 | static int sun4u_set_affinity(unsigned int virt_irq, |
300 | const struct cpumask *mask) | 302 | const struct cpumask *mask) |
301 | { | 303 | { |
302 | sun4u_irq_enable(virt_irq); | 304 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
305 | |||
306 | if (likely(data)) { | ||
307 | unsigned long cpuid, imap, val; | ||
308 | unsigned int tid; | ||
309 | |||
310 | cpuid = irq_choose_cpu(virt_irq, mask); | ||
311 | imap = data->imap; | ||
312 | |||
313 | tid = sun4u_compute_tid(imap, cpuid); | ||
314 | |||
315 | val = upa_readq(imap); | ||
316 | val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS | | ||
317 | IMAP_AID_SAFARI | IMAP_NID_SAFARI); | ||
318 | val |= tid | IMAP_VALID; | ||
319 | upa_writeq(val, imap); | ||
320 | upa_writeq(ICLR_IDLE, data->iclr); | ||
321 | } | ||
303 | 322 | ||
304 | return 0; | 323 | return 0; |
305 | } | 324 | } |
@@ -340,7 +359,8 @@ static void sun4u_irq_eoi(unsigned int virt_irq) | |||
340 | static void sun4v_irq_enable(unsigned int virt_irq) | 359 | static void sun4v_irq_enable(unsigned int virt_irq) |
341 | { | 360 | { |
342 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; | 361 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; |
343 | unsigned long cpuid = irq_choose_cpu(virt_irq); | 362 | unsigned long cpuid = irq_choose_cpu(virt_irq, |
363 | irq_desc[virt_irq].affinity); | ||
344 | int err; | 364 | int err; |
345 | 365 | ||
346 | err = sun4v_intr_settarget(ino, cpuid); | 366 | err = sun4v_intr_settarget(ino, cpuid); |
@@ -361,7 +381,7 @@ static int sun4v_set_affinity(unsigned int virt_irq, | |||
361 | const struct cpumask *mask) | 381 | const struct cpumask *mask) |
362 | { | 382 | { |
363 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; | 383 | unsigned int ino = virt_irq_table[virt_irq].dev_ino; |
364 | unsigned long cpuid = irq_choose_cpu(virt_irq); | 384 | unsigned long cpuid = irq_choose_cpu(virt_irq, mask); |
365 | int err; | 385 | int err; |
366 | 386 | ||
367 | err = sun4v_intr_settarget(ino, cpuid); | 387 | err = sun4v_intr_settarget(ino, cpuid); |
@@ -403,7 +423,7 @@ static void sun4v_virq_enable(unsigned int virt_irq) | |||
403 | unsigned long cpuid, dev_handle, dev_ino; | 423 | unsigned long cpuid, dev_handle, dev_ino; |
404 | int err; | 424 | int err; |
405 | 425 | ||
406 | cpuid = irq_choose_cpu(virt_irq); | 426 | cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity); |
407 | 427 | ||
408 | dev_handle = virt_irq_table[virt_irq].dev_handle; | 428 | dev_handle = virt_irq_table[virt_irq].dev_handle; |
409 | dev_ino = virt_irq_table[virt_irq].dev_ino; | 429 | dev_ino = virt_irq_table[virt_irq].dev_ino; |
@@ -433,7 +453,7 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq, | |||
433 | unsigned long cpuid, dev_handle, dev_ino; | 453 | unsigned long cpuid, dev_handle, dev_ino; |
434 | int err; | 454 | int err; |
435 | 455 | ||
436 | cpuid = irq_choose_cpu(virt_irq); | 456 | cpuid = irq_choose_cpu(virt_irq, mask); |
437 | 457 | ||
438 | dev_handle = virt_irq_table[virt_irq].dev_handle; | 458 | dev_handle = virt_irq_table[virt_irq].dev_handle; |
439 | dev_ino = virt_irq_table[virt_irq].dev_ino; | 459 | dev_ino = virt_irq_table[virt_irq].dev_ino; |
@@ -484,7 +504,7 @@ static void sun4v_virq_eoi(unsigned int virt_irq) | |||
484 | } | 504 | } |
485 | 505 | ||
486 | static struct irq_chip sun4u_irq = { | 506 | static struct irq_chip sun4u_irq = { |
487 | .typename = "sun4u", | 507 | .name = "sun4u", |
488 | .enable = sun4u_irq_enable, | 508 | .enable = sun4u_irq_enable, |
489 | .disable = sun4u_irq_disable, | 509 | .disable = sun4u_irq_disable, |
490 | .eoi = sun4u_irq_eoi, | 510 | .eoi = sun4u_irq_eoi, |
@@ -492,7 +512,7 @@ static struct irq_chip sun4u_irq = { | |||
492 | }; | 512 | }; |
493 | 513 | ||
494 | static struct irq_chip sun4v_irq = { | 514 | static struct irq_chip sun4v_irq = { |
495 | .typename = "sun4v", | 515 | .name = "sun4v", |
496 | .enable = sun4v_irq_enable, | 516 | .enable = sun4v_irq_enable, |
497 | .disable = sun4v_irq_disable, | 517 | .disable = sun4v_irq_disable, |
498 | .eoi = sun4v_irq_eoi, | 518 | .eoi = sun4v_irq_eoi, |
@@ -500,7 +520,7 @@ static struct irq_chip sun4v_irq = { | |||
500 | }; | 520 | }; |
501 | 521 | ||
502 | static struct irq_chip sun4v_virq = { | 522 | static struct irq_chip sun4v_virq = { |
503 | .typename = "vsun4v", | 523 | .name = "vsun4v", |
504 | .enable = sun4v_virq_enable, | 524 | .enable = sun4v_virq_enable, |
505 | .disable = sun4v_virq_disable, | 525 | .disable = sun4v_virq_disable, |
506 | .eoi = sun4v_virq_eoi, | 526 | .eoi = sun4v_virq_eoi, |
@@ -630,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | |||
630 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); | 650 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); |
631 | if (unlikely(!bucket)) | 651 | if (unlikely(!bucket)) |
632 | return 0; | 652 | return 0; |
653 | |||
654 | /* The only reference we store to the IRQ bucket is | ||
655 | * by physical address which kmemleak can't see, tell | ||
656 | * it that this object explicitly is not a leak and | ||
657 | * should be scanned. | ||
658 | */ | ||
659 | kmemleak_not_leak(bucket); | ||
660 | |||
633 | __flush_dcache_range((unsigned long) bucket, | 661 | __flush_dcache_range((unsigned long) bucket, |
634 | ((unsigned long) bucket + | 662 | ((unsigned long) bucket + |
635 | sizeof(struct ino_bucket))); | 663 | sizeof(struct ino_bucket))); |
@@ -686,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq) | |||
686 | void *hardirq_stack[NR_CPUS]; | 714 | void *hardirq_stack[NR_CPUS]; |
687 | void *softirq_stack[NR_CPUS]; | 715 | void *softirq_stack[NR_CPUS]; |
688 | 716 | ||
689 | static __attribute__((always_inline)) void *set_hardirq_stack(void) | 717 | void __irq_entry handler_irq(int irq, struct pt_regs *regs) |
690 | { | ||
691 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
692 | |||
693 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
694 | if (orig_sp < sp || | ||
695 | orig_sp > (sp + THREAD_SIZE)) { | ||
696 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
697 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
698 | } | ||
699 | |||
700 | return orig_sp; | ||
701 | } | ||
702 | static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
703 | { | ||
704 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
705 | } | ||
706 | |||
707 | void handler_irq(int irq, struct pt_regs *regs) | ||
708 | { | 718 | { |
709 | unsigned long pstate, bucket_pa; | 719 | unsigned long pstate, bucket_pa; |
710 | struct pt_regs *old_regs; | 720 | struct pt_regs *old_regs; |
@@ -785,14 +795,14 @@ void fixup_irqs(void) | |||
785 | for (irq = 0; irq < NR_IRQS; irq++) { | 795 | for (irq = 0; irq < NR_IRQS; irq++) { |
786 | unsigned long flags; | 796 | unsigned long flags; |
787 | 797 | ||
788 | spin_lock_irqsave(&irq_desc[irq].lock, flags); | 798 | raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); |
789 | if (irq_desc[irq].action && | 799 | if (irq_desc[irq].action && |
790 | !(irq_desc[irq].status & IRQ_PER_CPU)) { | 800 | !(irq_desc[irq].status & IRQ_PER_CPU)) { |
791 | if (irq_desc[irq].chip->set_affinity) | 801 | if (irq_desc[irq].chip->set_affinity) |
792 | irq_desc[irq].chip->set_affinity(irq, | 802 | irq_desc[irq].chip->set_affinity(irq, |
793 | irq_desc[irq].affinity); | 803 | irq_desc[irq].affinity); |
794 | } | 804 | } |
795 | spin_unlock_irqrestore(&irq_desc[irq].lock, flags); | 805 | raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); |
796 | } | 806 | } |
797 | 807 | ||
798 | tick_ops->disable_irq(); | 808 | tick_ops->disable_irq(); |
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index f5a0fd490b59..0a2bd0f99fc1 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/kgdb.h> | 6 | #include <linux/kgdb.h> |
7 | #include <linux/kdebug.h> | 7 | #include <linux/kdebug.h> |
8 | #include <linux/ftrace.h> | ||
8 | 9 | ||
9 | #include <asm/kdebug.h> | 10 | #include <asm/kdebug.h> |
10 | #include <asm/ptrace.h> | 11 | #include <asm/ptrace.h> |
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) | |||
108 | } | 109 | } |
109 | 110 | ||
110 | #ifdef CONFIG_SMP | 111 | #ifdef CONFIG_SMP |
111 | void smp_kgdb_capture_client(int irq, struct pt_regs *regs) | 112 | void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs) |
112 | { | 113 | { |
113 | unsigned long flags; | 114 | unsigned long flags; |
114 | 115 | ||
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index 3bc6527c95af..a39d1ba5a119 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/kprobes.h> | 7 | #include <linux/kprobes.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/kdebug.h> | 9 | #include <linux/kdebug.h> |
10 | #include <linux/slab.h> | ||
10 | #include <asm/signal.h> | 11 | #include <asm/signal.h> |
11 | #include <asm/cacheflush.h> | 12 | #include <asm/cacheflush.h> |
12 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
@@ -46,6 +47,9 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; | |||
46 | 47 | ||
47 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | 48 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
48 | { | 49 | { |
50 | if ((unsigned long) p->addr & 0x3UL) | ||
51 | return -EILSEQ; | ||
52 | |||
49 | p->ainsn.insn[0] = *p->addr; | 53 | p->ainsn.insn[0] = *p->addr; |
50 | flushi(&p->ainsn.insn[0]); | 54 | flushi(&p->ainsn.insn[0]); |
51 | 55 | ||
diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h index 4248d969272f..53dfb92e09fb 100644 --- a/arch/sparc/kernel/kstack.h +++ b/arch/sparc/kernel/kstack.h | |||
@@ -11,6 +11,10 @@ static inline bool kstack_valid(struct thread_info *tp, unsigned long sp) | |||
11 | { | 11 | { |
12 | unsigned long base = (unsigned long) tp; | 12 | unsigned long base = (unsigned long) tp; |
13 | 13 | ||
14 | /* Stack pointer must be 16-byte aligned. */ | ||
15 | if (sp & (16UL - 1)) | ||
16 | return false; | ||
17 | |||
14 | if (sp >= (base + sizeof(struct thread_info)) && | 18 | if (sp >= (base + sizeof(struct thread_info)) && |
15 | sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf))) | 19 | sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf))) |
16 | return true; | 20 | return true; |
@@ -57,4 +61,23 @@ check_magic: | |||
57 | 61 | ||
58 | } | 62 | } |
59 | 63 | ||
64 | static inline __attribute__((always_inline)) void *set_hardirq_stack(void) | ||
65 | { | ||
66 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
67 | |||
68 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
69 | if (orig_sp < sp || | ||
70 | orig_sp > (sp + THREAD_SIZE)) { | ||
71 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
72 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
73 | } | ||
74 | |||
75 | return orig_sp; | ||
76 | } | ||
77 | |||
78 | static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
79 | { | ||
80 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
81 | } | ||
82 | |||
60 | #endif /* _KSTACK_H */ | 83 | #endif /* _KSTACK_H */ |
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index cb3c72c45aab..df39a0f0d27a 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/bitmap.h> | ||
17 | 18 | ||
18 | #include <asm/hypervisor.h> | 19 | #include <asm/hypervisor.h> |
19 | #include <asm/iommu.h> | 20 | #include <asm/iommu.h> |
@@ -1242,13 +1243,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name) | |||
1242 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | 1243 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); |
1243 | 1244 | ||
1244 | err = request_irq(lp->cfg.rx_irq, ldc_rx, | 1245 | err = request_irq(lp->cfg.rx_irq, ldc_rx, |
1245 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, | 1246 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, |
1246 | lp->rx_irq_name, lp); | 1247 | lp->rx_irq_name, lp); |
1247 | if (err) | 1248 | if (err) |
1248 | return err; | 1249 | return err; |
1249 | 1250 | ||
1250 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | 1251 | err = request_irq(lp->cfg.tx_irq, ldc_tx, |
1251 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, | 1252 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, |
1252 | lp->tx_irq_name, lp); | 1253 | lp->tx_irq_name, lp); |
1253 | if (err) { | 1254 | if (err) { |
1254 | free_irq(lp->cfg.rx_irq, lp); | 1255 | free_irq(lp->cfg.rx_irq, lp); |
@@ -1875,7 +1876,7 @@ EXPORT_SYMBOL(ldc_read); | |||
1875 | static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages) | 1876 | static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages) |
1876 | { | 1877 | { |
1877 | struct iommu_arena *arena = &iommu->arena; | 1878 | struct iommu_arena *arena = &iommu->arena; |
1878 | unsigned long n, i, start, end, limit; | 1879 | unsigned long n, start, end, limit; |
1879 | int pass; | 1880 | int pass; |
1880 | 1881 | ||
1881 | limit = arena->limit; | 1882 | limit = arena->limit; |
@@ -1883,7 +1884,7 @@ static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages) | |||
1883 | pass = 0; | 1884 | pass = 0; |
1884 | 1885 | ||
1885 | again: | 1886 | again: |
1886 | n = find_next_zero_bit(arena->map, limit, start); | 1887 | n = bitmap_find_next_zero_area(arena->map, limit, start, npages, 0); |
1887 | end = n + npages; | 1888 | end = n + npages; |
1888 | if (unlikely(end >= limit)) { | 1889 | if (unlikely(end >= limit)) { |
1889 | if (likely(pass < 1)) { | 1890 | if (likely(pass < 1)) { |
@@ -1896,16 +1897,7 @@ again: | |||
1896 | return -1; | 1897 | return -1; |
1897 | } | 1898 | } |
1898 | } | 1899 | } |
1899 | 1900 | bitmap_set(arena->map, n, npages); | |
1900 | for (i = n; i < end; i++) { | ||
1901 | if (test_bit(i, arena->map)) { | ||
1902 | start = i + 1; | ||
1903 | goto again; | ||
1904 | } | ||
1905 | } | ||
1906 | |||
1907 | for (i = n; i < end; i++) | ||
1908 | __set_bit(i, arena->map); | ||
1909 | 1901 | ||
1910 | arena->hint = end; | 1902 | arena->hint = end; |
1911 | 1903 | ||
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index 00d034ea2164..3ae36f36e758 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/proc_fs.h> | 4 | #include <linux/proc_fs.h> |
5 | #include <linux/seq_file.h> | 5 | #include <linux/seq_file.h> |
6 | #include <linux/slab.h> | ||
6 | #include <linux/string.h> | 7 | #include <linux/string.h> |
7 | #include <linux/jiffies.h> | 8 | #include <linux/jiffies.h> |
8 | #include <linux/timer.h> | 9 | #include <linux/timer.h> |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 54d8a5bd4824..6a7b4dbc8e09 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -7,16 +7,18 @@ | |||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
9 | #include <linux/mutex.h> | 9 | #include <linux/mutex.h> |
10 | #include <linux/slab.h> | ||
11 | #include <linux/of.h> | 10 | #include <linux/of.h> |
12 | #include <linux/of_platform.h> | 11 | #include <linux/of_platform.h> |
13 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
14 | #include <linux/of_device.h> | 13 | #include <linux/of_device.h> |
14 | |||
15 | #include <asm/oplib.h> | 15 | #include <asm/oplib.h> |
16 | #include <asm/timer.h> | 16 | #include <asm/timer.h> |
17 | #include <asm/prom.h> | 17 | #include <asm/prom.h> |
18 | #include <asm/leon.h> | 18 | #include <asm/leon.h> |
19 | #include <asm/leon_amba.h> | 19 | #include <asm/leon_amba.h> |
20 | #include <asm/traps.h> | ||
21 | #include <asm/cacheflush.h> | ||
20 | 22 | ||
21 | #include "prom.h" | 23 | #include "prom.h" |
22 | #include "irq.h" | 24 | #include "irq.h" |
@@ -115,6 +117,21 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
115 | (((1000000 / 100) - 1))); | 117 | (((1000000 / 100) - 1))); |
116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); | 118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); |
117 | 119 | ||
120 | #ifdef CONFIG_SMP | ||
121 | leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs; | ||
122 | leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1; | ||
123 | |||
124 | if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & | ||
125 | (1<<LEON3_GPTIMER_SEPIRQ))) { | ||
126 | prom_printf("irq timer not configured with separate irqs\n"); | ||
127 | BUG(); | ||
128 | } | ||
129 | |||
130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); | ||
131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1))); | ||
132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); | ||
133 | # endif | ||
134 | |||
118 | } else { | 135 | } else { |
119 | printk(KERN_ERR "No Timer/irqctrl found\n"); | 136 | printk(KERN_ERR "No Timer/irqctrl found\n"); |
120 | BUG(); | 137 | BUG(); |
@@ -130,11 +147,41 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
130 | prom_halt(); | 147 | prom_halt(); |
131 | } | 148 | } |
132 | 149 | ||
150 | # ifdef CONFIG_SMP | ||
151 | { | ||
152 | unsigned long flags; | ||
153 | struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)]; | ||
154 | |||
155 | /* For SMP we use the level 14 ticker, however the bootup code | ||
156 | * has copied the firmwares level 14 vector into boot cpu's | ||
157 | * trap table, we must fix this now or we get squashed. | ||
158 | */ | ||
159 | local_irq_save(flags); | ||
160 | |||
161 | patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */ | ||
162 | |||
163 | /* Adjust so that we jump directly to smpleon_ticker */ | ||
164 | trap_table->inst_three += smpleon_ticker - real_irq_entry; | ||
165 | |||
166 | local_flush_cache_all(); | ||
167 | local_irq_restore(flags); | ||
168 | } | ||
169 | # endif | ||
170 | |||
133 | if (leon3_gptimer_regs) { | 171 | if (leon3_gptimer_regs) { |
134 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, | 172 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, |
135 | LEON3_GPTIMER_EN | | 173 | LEON3_GPTIMER_EN | |
136 | LEON3_GPTIMER_RL | | 174 | LEON3_GPTIMER_RL | |
137 | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); | 175 | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); |
176 | |||
177 | #ifdef CONFIG_SMP | ||
178 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, | ||
179 | LEON3_GPTIMER_EN | | ||
180 | LEON3_GPTIMER_RL | | ||
181 | LEON3_GPTIMER_LD | | ||
182 | LEON3_GPTIMER_IRQEN); | ||
183 | #endif | ||
184 | |||
138 | } | 185 | } |
139 | } | 186 | } |
140 | 187 | ||
@@ -175,6 +222,42 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp) | |||
175 | } | 222 | } |
176 | } | 223 | } |
177 | 224 | ||
225 | #ifdef CONFIG_SMP | ||
226 | |||
227 | void leon_set_cpu_int(int cpu, int level) | ||
228 | { | ||
229 | unsigned long mask; | ||
230 | mask = get_irqmask(level); | ||
231 | LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); | ||
232 | } | ||
233 | |||
234 | static void leon_clear_ipi(int cpu, int level) | ||
235 | { | ||
236 | unsigned long mask; | ||
237 | mask = get_irqmask(level); | ||
238 | LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask<<16); | ||
239 | } | ||
240 | |||
241 | static void leon_set_udt(int cpu) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | void leon_clear_profile_irq(int cpu) | ||
246 | { | ||
247 | } | ||
248 | |||
249 | void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) | ||
250 | { | ||
251 | unsigned long mask, flags, *addr; | ||
252 | mask = get_irqmask(irq_nr); | ||
253 | local_irq_save(flags); | ||
254 | addr = (unsigned long *)&(leon3_irqctrl_regs->mask[cpu]); | ||
255 | LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | (mask))); | ||
256 | local_irq_restore(flags); | ||
257 | } | ||
258 | |||
259 | #endif | ||
260 | |||
178 | void __init leon_init_IRQ(void) | 261 | void __init leon_init_IRQ(void) |
179 | { | 262 | { |
180 | sparc_init_timers = leon_init_timers; | 263 | sparc_init_timers = leon_init_timers; |
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c new file mode 100644 index 000000000000..e1656fc41ccb --- /dev/null +++ b/arch/sparc/kernel/leon_smp.c | |||
@@ -0,0 +1,469 @@ | |||
1 | /* leon_smp.c: Sparc-Leon SMP support. | ||
2 | * | ||
3 | * based on sun4m_smp.c | ||
4 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | ||
5 | * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB | ||
6 | * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB | ||
7 | */ | ||
8 | |||
9 | #include <asm/head.h> | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/threads.h> | ||
14 | #include <linux/smp.h> | ||
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/kernel_stat.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/swap.h> | ||
22 | #include <linux/profile.h> | ||
23 | #include <linux/pm.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/gfp.h> | ||
26 | |||
27 | #include <asm/cacheflush.h> | ||
28 | #include <asm/tlbflush.h> | ||
29 | |||
30 | #include <asm/ptrace.h> | ||
31 | #include <asm/atomic.h> | ||
32 | #include <asm/irq_regs.h> | ||
33 | |||
34 | #include <asm/delay.h> | ||
35 | #include <asm/irq.h> | ||
36 | #include <asm/page.h> | ||
37 | #include <asm/pgalloc.h> | ||
38 | #include <asm/pgtable.h> | ||
39 | #include <asm/oplib.h> | ||
40 | #include <asm/cpudata.h> | ||
41 | #include <asm/asi.h> | ||
42 | #include <asm/leon.h> | ||
43 | #include <asm/leon_amba.h> | ||
44 | |||
45 | #ifdef CONFIG_SPARC_LEON | ||
46 | |||
47 | #include "irq.h" | ||
48 | |||
49 | extern ctxd_t *srmmu_ctx_table_phys; | ||
50 | static int smp_processors_ready; | ||
51 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; | ||
52 | extern unsigned char boot_cpu_id; | ||
53 | extern cpumask_t smp_commenced_mask; | ||
54 | void __init leon_configure_cache_smp(void); | ||
55 | |||
56 | static inline unsigned long do_swap(volatile unsigned long *ptr, | ||
57 | unsigned long val) | ||
58 | { | ||
59 | __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val) | ||
60 | : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) | ||
61 | : "memory"); | ||
62 | return val; | ||
63 | } | ||
64 | |||
65 | static void smp_setup_percpu_timer(void); | ||
66 | |||
67 | void __cpuinit leon_callin(void) | ||
68 | { | ||
69 | int cpuid = hard_smpleon_processor_id(); | ||
70 | |||
71 | local_flush_cache_all(); | ||
72 | local_flush_tlb_all(); | ||
73 | leon_configure_cache_smp(); | ||
74 | |||
75 | /* Get our local ticker going. */ | ||
76 | smp_setup_percpu_timer(); | ||
77 | |||
78 | calibrate_delay(); | ||
79 | smp_store_cpu_info(cpuid); | ||
80 | |||
81 | local_flush_cache_all(); | ||
82 | local_flush_tlb_all(); | ||
83 | |||
84 | /* | ||
85 | * Unblock the master CPU _only_ when the scheduler state | ||
86 | * of all secondary CPUs will be up-to-date, so after | ||
87 | * the SMP initialization the master will be just allowed | ||
88 | * to call the scheduler code. | ||
89 | * Allow master to continue. | ||
90 | */ | ||
91 | do_swap(&cpu_callin_map[cpuid], 1); | ||
92 | |||
93 | local_flush_cache_all(); | ||
94 | local_flush_tlb_all(); | ||
95 | |||
96 | cpu_probe(); | ||
97 | |||
98 | /* Fix idle thread fields. */ | ||
99 | __asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(¤t_set[cpuid]) | ||
100 | : "memory" /* paranoid */); | ||
101 | |||
102 | /* Attach to the address space of init_task. */ | ||
103 | atomic_inc(&init_mm.mm_count); | ||
104 | current->active_mm = &init_mm; | ||
105 | |||
106 | while (!cpu_isset(cpuid, smp_commenced_mask)) | ||
107 | mb(); | ||
108 | |||
109 | local_irq_enable(); | ||
110 | cpu_set(cpuid, cpu_online_map); | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Cycle through the processors asking the PROM to start each one. | ||
115 | */ | ||
116 | |||
117 | extern struct linux_prom_registers smp_penguin_ctable; | ||
118 | |||
119 | void __init leon_configure_cache_smp(void) | ||
120 | { | ||
121 | unsigned long cfg = sparc_leon3_get_dcachecfg(); | ||
122 | int me = smp_processor_id(); | ||
123 | |||
124 | if (ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg) > 4) { | ||
125 | printk(KERN_INFO "Note: SMP with snooping only works on 4k cache, found %dk(0x%x) on cpu %d, disabling caches\n", | ||
126 | (unsigned int)ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg), | ||
127 | (unsigned int)cfg, (unsigned int)me); | ||
128 | sparc_leon3_disable_cache(); | ||
129 | } else { | ||
130 | if (cfg & ASI_LEON3_SYSCTRL_CFG_SNOOPING) { | ||
131 | sparc_leon3_enable_snooping(); | ||
132 | } else { | ||
133 | printk(KERN_INFO "Note: You have to enable snooping in the vhdl model cpu %d, disabling caches\n", | ||
134 | me); | ||
135 | sparc_leon3_disable_cache(); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | local_flush_cache_all(); | ||
140 | local_flush_tlb_all(); | ||
141 | } | ||
142 | |||
143 | void leon_smp_setbroadcast(unsigned int mask) | ||
144 | { | ||
145 | int broadcast = | ||
146 | ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >> | ||
147 | LEON3_IRQMPSTATUS_BROADCAST) & 1); | ||
148 | if (!broadcast) { | ||
149 | prom_printf("######## !!!! The irqmp-ctrl must have broadcast enabled, smp wont work !!!!! ####### nr cpus: %d\n", | ||
150 | leon_smp_nrcpus()); | ||
151 | if (leon_smp_nrcpus() > 1) { | ||
152 | BUG(); | ||
153 | } else { | ||
154 | prom_printf("continue anyway\n"); | ||
155 | return; | ||
156 | } | ||
157 | } | ||
158 | LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpbroadcast), mask); | ||
159 | } | ||
160 | |||
161 | unsigned int leon_smp_getbroadcast(void) | ||
162 | { | ||
163 | unsigned int mask; | ||
164 | mask = LEON_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpbroadcast)); | ||
165 | return mask; | ||
166 | } | ||
167 | |||
168 | int leon_smp_nrcpus(void) | ||
169 | { | ||
170 | int nrcpu = | ||
171 | ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >> | ||
172 | LEON3_IRQMPSTATUS_CPUNR) & 0xf) + 1; | ||
173 | return nrcpu; | ||
174 | } | ||
175 | |||
176 | void __init leon_boot_cpus(void) | ||
177 | { | ||
178 | int nrcpu = leon_smp_nrcpus(); | ||
179 | int me = smp_processor_id(); | ||
180 | |||
181 | printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x\n", (unsigned int)me, | ||
182 | (unsigned int)nrcpu, (unsigned int)NR_CPUS, | ||
183 | (unsigned int)&(leon3_irqctrl_regs->mpstatus)); | ||
184 | |||
185 | leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, me); | ||
186 | leon_enable_irq_cpu(LEON3_IRQ_TICKER, me); | ||
187 | leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, me); | ||
188 | |||
189 | leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER); | ||
190 | |||
191 | leon_configure_cache_smp(); | ||
192 | smp_setup_percpu_timer(); | ||
193 | local_flush_cache_all(); | ||
194 | |||
195 | } | ||
196 | |||
197 | int __cpuinit leon_boot_one_cpu(int i) | ||
198 | { | ||
199 | |||
200 | struct task_struct *p; | ||
201 | int timeout; | ||
202 | |||
203 | /* Cook up an idler for this guy. */ | ||
204 | p = fork_idle(i); | ||
205 | |||
206 | current_set[i] = task_thread_info(p); | ||
207 | |||
208 | /* See trampoline.S:leon_smp_cpu_startup for details... | ||
209 | * Initialize the contexts table | ||
210 | * Since the call to prom_startcpu() trashes the structure, | ||
211 | * we need to re-initialize it for each cpu | ||
212 | */ | ||
213 | smp_penguin_ctable.which_io = 0; | ||
214 | smp_penguin_ctable.phys_addr = (unsigned int)srmmu_ctx_table_phys; | ||
215 | smp_penguin_ctable.reg_size = 0; | ||
216 | |||
217 | /* whirrr, whirrr, whirrrrrrrrr... */ | ||
218 | printk(KERN_INFO "Starting CPU %d : (irqmp: 0x%x)\n", (unsigned int)i, | ||
219 | (unsigned int)&leon3_irqctrl_regs->mpstatus); | ||
220 | local_flush_cache_all(); | ||
221 | |||
222 | LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpstatus), 1 << i); | ||
223 | |||
224 | /* wheee... it's going... */ | ||
225 | for (timeout = 0; timeout < 10000; timeout++) { | ||
226 | if (cpu_callin_map[i]) | ||
227 | break; | ||
228 | udelay(200); | ||
229 | } | ||
230 | printk(KERN_INFO "Started CPU %d\n", (unsigned int)i); | ||
231 | |||
232 | if (!(cpu_callin_map[i])) { | ||
233 | printk(KERN_ERR "Processor %d is stuck.\n", i); | ||
234 | return -ENODEV; | ||
235 | } else { | ||
236 | leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, i); | ||
237 | leon_enable_irq_cpu(LEON3_IRQ_TICKER, i); | ||
238 | leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, i); | ||
239 | } | ||
240 | |||
241 | local_flush_cache_all(); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | void __init leon_smp_done(void) | ||
246 | { | ||
247 | |||
248 | int i, first; | ||
249 | int *prev; | ||
250 | |||
251 | /* setup cpu list for irq rotation */ | ||
252 | first = 0; | ||
253 | prev = &first; | ||
254 | for (i = 0; i < NR_CPUS; i++) { | ||
255 | if (cpu_online(i)) { | ||
256 | *prev = i; | ||
257 | prev = &cpu_data(i).next; | ||
258 | } | ||
259 | } | ||
260 | *prev = first; | ||
261 | local_flush_cache_all(); | ||
262 | |||
263 | /* Free unneeded trap tables */ | ||
264 | if (!cpu_isset(1, cpu_present_map)) { | ||
265 | ClearPageReserved(virt_to_page(trapbase_cpu1)); | ||
266 | init_page_count(virt_to_page(trapbase_cpu1)); | ||
267 | free_page((unsigned long)trapbase_cpu1); | ||
268 | totalram_pages++; | ||
269 | num_physpages++; | ||
270 | } | ||
271 | if (!cpu_isset(2, cpu_present_map)) { | ||
272 | ClearPageReserved(virt_to_page(trapbase_cpu2)); | ||
273 | init_page_count(virt_to_page(trapbase_cpu2)); | ||
274 | free_page((unsigned long)trapbase_cpu2); | ||
275 | totalram_pages++; | ||
276 | num_physpages++; | ||
277 | } | ||
278 | if (!cpu_isset(3, cpu_present_map)) { | ||
279 | ClearPageReserved(virt_to_page(trapbase_cpu3)); | ||
280 | init_page_count(virt_to_page(trapbase_cpu3)); | ||
281 | free_page((unsigned long)trapbase_cpu3); | ||
282 | totalram_pages++; | ||
283 | num_physpages++; | ||
284 | } | ||
285 | /* Ok, they are spinning and ready to go. */ | ||
286 | smp_processors_ready = 1; | ||
287 | |||
288 | } | ||
289 | |||
290 | void leon_irq_rotate(int cpu) | ||
291 | { | ||
292 | } | ||
293 | |||
294 | static struct smp_funcall { | ||
295 | smpfunc_t func; | ||
296 | unsigned long arg1; | ||
297 | unsigned long arg2; | ||
298 | unsigned long arg3; | ||
299 | unsigned long arg4; | ||
300 | unsigned long arg5; | ||
301 | unsigned long processors_in[NR_CPUS]; /* Set when ipi entered. */ | ||
302 | unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */ | ||
303 | } ccall_info; | ||
304 | |||
305 | static DEFINE_SPINLOCK(cross_call_lock); | ||
306 | |||
307 | /* Cross calls must be serialized, at least currently. */ | ||
308 | static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | ||
309 | unsigned long arg2, unsigned long arg3, | ||
310 | unsigned long arg4) | ||
311 | { | ||
312 | if (smp_processors_ready) { | ||
313 | register int high = NR_CPUS - 1; | ||
314 | unsigned long flags; | ||
315 | |||
316 | spin_lock_irqsave(&cross_call_lock, flags); | ||
317 | |||
318 | { | ||
319 | /* If you make changes here, make sure gcc generates proper code... */ | ||
320 | register smpfunc_t f asm("i0") = func; | ||
321 | register unsigned long a1 asm("i1") = arg1; | ||
322 | register unsigned long a2 asm("i2") = arg2; | ||
323 | register unsigned long a3 asm("i3") = arg3; | ||
324 | register unsigned long a4 asm("i4") = arg4; | ||
325 | register unsigned long a5 asm("i5") = 0; | ||
326 | |||
327 | __asm__ __volatile__("std %0, [%6]\n\t" | ||
328 | "std %2, [%6 + 8]\n\t" | ||
329 | "std %4, [%6 + 16]\n\t" : : | ||
330 | "r"(f), "r"(a1), "r"(a2), "r"(a3), | ||
331 | "r"(a4), "r"(a5), | ||
332 | "r"(&ccall_info.func)); | ||
333 | } | ||
334 | |||
335 | /* Init receive/complete mapping, plus fire the IPI's off. */ | ||
336 | { | ||
337 | register int i; | ||
338 | |||
339 | cpu_clear(smp_processor_id(), mask); | ||
340 | cpus_and(mask, cpu_online_map, mask); | ||
341 | for (i = 0; i <= high; i++) { | ||
342 | if (cpu_isset(i, mask)) { | ||
343 | ccall_info.processors_in[i] = 0; | ||
344 | ccall_info.processors_out[i] = 0; | ||
345 | set_cpu_int(i, LEON3_IRQ_CROSS_CALL); | ||
346 | |||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | { | ||
352 | register int i; | ||
353 | |||
354 | i = 0; | ||
355 | do { | ||
356 | if (!cpu_isset(i, mask)) | ||
357 | continue; | ||
358 | |||
359 | while (!ccall_info.processors_in[i]) | ||
360 | barrier(); | ||
361 | } while (++i <= high); | ||
362 | |||
363 | i = 0; | ||
364 | do { | ||
365 | if (!cpu_isset(i, mask)) | ||
366 | continue; | ||
367 | |||
368 | while (!ccall_info.processors_out[i]) | ||
369 | barrier(); | ||
370 | } while (++i <= high); | ||
371 | } | ||
372 | |||
373 | spin_unlock_irqrestore(&cross_call_lock, flags); | ||
374 | } | ||
375 | } | ||
376 | |||
377 | /* Running cross calls. */ | ||
378 | void leon_cross_call_irq(void) | ||
379 | { | ||
380 | int i = smp_processor_id(); | ||
381 | |||
382 | ccall_info.processors_in[i] = 1; | ||
383 | ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, | ||
384 | ccall_info.arg4, ccall_info.arg5); | ||
385 | ccall_info.processors_out[i] = 1; | ||
386 | } | ||
387 | |||
388 | void leon_percpu_timer_interrupt(struct pt_regs *regs) | ||
389 | { | ||
390 | struct pt_regs *old_regs; | ||
391 | int cpu = smp_processor_id(); | ||
392 | |||
393 | old_regs = set_irq_regs(regs); | ||
394 | |||
395 | leon_clear_profile_irq(cpu); | ||
396 | |||
397 | profile_tick(CPU_PROFILING); | ||
398 | |||
399 | if (!--prof_counter(cpu)) { | ||
400 | int user = user_mode(regs); | ||
401 | |||
402 | irq_enter(); | ||
403 | update_process_times(user); | ||
404 | irq_exit(); | ||
405 | |||
406 | prof_counter(cpu) = prof_multiplier(cpu); | ||
407 | } | ||
408 | set_irq_regs(old_regs); | ||
409 | } | ||
410 | |||
411 | static void __init smp_setup_percpu_timer(void) | ||
412 | { | ||
413 | int cpu = smp_processor_id(); | ||
414 | |||
415 | prof_counter(cpu) = prof_multiplier(cpu) = 1; | ||
416 | } | ||
417 | |||
418 | void __init leon_blackbox_id(unsigned *addr) | ||
419 | { | ||
420 | int rd = *addr & 0x3e000000; | ||
421 | int rs1 = rd >> 11; | ||
422 | |||
423 | /* patch places where ___b_hard_smp_processor_id appears */ | ||
424 | addr[0] = 0x81444000 | rd; /* rd %asr17, reg */ | ||
425 | addr[1] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */ | ||
426 | addr[2] = 0x01000000; /* nop */ | ||
427 | } | ||
428 | |||
429 | void __init leon_blackbox_current(unsigned *addr) | ||
430 | { | ||
431 | int rd = *addr & 0x3e000000; | ||
432 | int rs1 = rd >> 11; | ||
433 | |||
434 | /* patch LOAD_CURRENT macro where ___b_load_current appears */ | ||
435 | addr[0] = 0x81444000 | rd; /* rd %asr17, reg */ | ||
436 | addr[2] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */ | ||
437 | addr[4] = 0x81282002 | rd | rs1; /* sll reg, 0x2, reg */ | ||
438 | |||
439 | } | ||
440 | |||
441 | /* | ||
442 | * CPU idle callback function | ||
443 | * See .../arch/sparc/kernel/process.c | ||
444 | */ | ||
445 | void pmc_leon_idle(void) | ||
446 | { | ||
447 | __asm__ volatile ("mov %g0, %asr19"); | ||
448 | } | ||
449 | |||
450 | void __init leon_init_smp(void) | ||
451 | { | ||
452 | /* Patch ipi15 trap table */ | ||
453 | t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); | ||
454 | |||
455 | BTFIXUPSET_BLACKBOX(hard_smp_processor_id, leon_blackbox_id); | ||
456 | BTFIXUPSET_BLACKBOX(load_current, leon_blackbox_current); | ||
457 | BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); | ||
458 | BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id, | ||
459 | BTFIXUPCALL_NORM); | ||
460 | |||
461 | #ifndef PMC_NO_IDLE | ||
462 | /* Assign power management IDLE handler */ | ||
463 | pm_idle = pmc_leon_idle; | ||
464 | printk(KERN_INFO "leon: power management initialized\n"); | ||
465 | #endif | ||
466 | |||
467 | } | ||
468 | |||
469 | #endif /* CONFIG_SPARC_LEON */ | ||
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 938da19dc065..cdc91d919e93 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/miscdevice.h> | 12 | #include <linux/miscdevice.h> |
13 | #include <linux/bootmem.h> | ||
13 | 14 | ||
14 | #include <asm/cpudata.h> | 15 | #include <asm/cpudata.h> |
15 | #include <asm/hypervisor.h> | 16 | #include <asm/hypervisor.h> |
@@ -108,25 +109,15 @@ static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size) | |||
108 | 109 | ||
109 | static void mdesc_lmb_free(struct mdesc_handle *hp) | 110 | static void mdesc_lmb_free(struct mdesc_handle *hp) |
110 | { | 111 | { |
111 | unsigned int alloc_size, handle_size = hp->handle_size; | 112 | unsigned int alloc_size; |
112 | unsigned long start, end; | 113 | unsigned long start; |
113 | 114 | ||
114 | BUG_ON(atomic_read(&hp->refcnt) != 0); | 115 | BUG_ON(atomic_read(&hp->refcnt) != 0); |
115 | BUG_ON(!list_empty(&hp->list)); | 116 | BUG_ON(!list_empty(&hp->list)); |
116 | 117 | ||
117 | alloc_size = PAGE_ALIGN(handle_size); | 118 | alloc_size = PAGE_ALIGN(hp->handle_size); |
118 | 119 | start = __pa(hp); | |
119 | start = (unsigned long) hp; | 120 | free_bootmem_late(start, alloc_size); |
120 | end = start + alloc_size; | ||
121 | |||
122 | while (start < end) { | ||
123 | struct page *p; | ||
124 | |||
125 | p = virt_to_page(start); | ||
126 | ClearPageReserved(p); | ||
127 | __free_page(p); | ||
128 | start += PAGE_SIZE; | ||
129 | } | ||
130 | } | 121 | } |
131 | 122 | ||
132 | static struct mdesc_mem_ops lmb_mdesc_ops = { | 123 | static struct mdesc_mem_ops lmb_mdesc_ops = { |
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 0ee642f63234..f848aadf54dc 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c | |||
@@ -9,9 +9,9 @@ | |||
9 | #include <linux/elf.h> | 9 | #include <linux/elf.h> |
10 | #include <linux/vmalloc.h> | 10 | #include <linux/vmalloc.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/gfp.h> | ||
12 | #include <linux/string.h> | 13 | #include <linux/string.h> |
13 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
14 | #include <linux/slab.h> | ||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | 16 | ||
17 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index b129611590a4..a4bd7ba74c89 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c | |||
@@ -21,9 +21,10 @@ | |||
21 | 21 | ||
22 | #include <asm/perf_event.h> | 22 | #include <asm/perf_event.h> |
23 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
24 | #include <asm/local.h> | ||
25 | #include <asm/pcr.h> | 24 | #include <asm/pcr.h> |
26 | 25 | ||
26 | #include "kstack.h" | ||
27 | |||
27 | /* We don't have a real NMI on sparc64, but we can fake one | 28 | /* We don't have a real NMI on sparc64, but we can fake one |
28 | * up using profiling counter overflow interrupts and interrupt | 29 | * up using profiling counter overflow interrupts and interrupt |
29 | * levels. | 30 | * levels. |
@@ -47,7 +48,7 @@ static DEFINE_PER_CPU(short, wd_enabled); | |||
47 | static int endflag __initdata; | 48 | static int endflag __initdata; |
48 | 49 | ||
49 | static DEFINE_PER_CPU(unsigned int, last_irq_sum); | 50 | static DEFINE_PER_CPU(unsigned int, last_irq_sum); |
50 | static DEFINE_PER_CPU(local_t, alert_counter); | 51 | static DEFINE_PER_CPU(long, alert_counter); |
51 | static DEFINE_PER_CPU(int, nmi_touch); | 52 | static DEFINE_PER_CPU(int, nmi_touch); |
52 | 53 | ||
53 | void touch_nmi_watchdog(void) | 54 | void touch_nmi_watchdog(void) |
@@ -93,38 +94,43 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) | |||
93 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | 94 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) |
94 | { | 95 | { |
95 | unsigned int sum, touched = 0; | 96 | unsigned int sum, touched = 0; |
96 | int cpu = smp_processor_id(); | 97 | void *orig_sp; |
97 | 98 | ||
98 | clear_softint(1 << irq); | 99 | clear_softint(1 << irq); |
99 | pcr_ops->write(PCR_PIC_PRIV); | ||
100 | 100 | ||
101 | local_cpu_data().__nmi_count++; | 101 | local_cpu_data().__nmi_count++; |
102 | 102 | ||
103 | nmi_enter(); | 103 | nmi_enter(); |
104 | 104 | ||
105 | orig_sp = set_hardirq_stack(); | ||
106 | |||
105 | if (notify_die(DIE_NMI, "nmi", regs, 0, | 107 | if (notify_die(DIE_NMI, "nmi", regs, 0, |
106 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) | 108 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) |
107 | touched = 1; | 109 | touched = 1; |
110 | else | ||
111 | pcr_ops->write(PCR_PIC_PRIV); | ||
108 | 112 | ||
109 | sum = kstat_irqs_cpu(0, cpu); | 113 | sum = local_cpu_data().irq0_irqs; |
110 | if (__get_cpu_var(nmi_touch)) { | 114 | if (__get_cpu_var(nmi_touch)) { |
111 | __get_cpu_var(nmi_touch) = 0; | 115 | __get_cpu_var(nmi_touch) = 0; |
112 | touched = 1; | 116 | touched = 1; |
113 | } | 117 | } |
114 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { | 118 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { |
115 | local_inc(&__get_cpu_var(alert_counter)); | 119 | __this_cpu_inc(alert_counter); |
116 | if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz) | 120 | if (__this_cpu_read(alert_counter) == 30 * nmi_hz) |
117 | die_nmi("BUG: NMI Watchdog detected LOCKUP", | 121 | die_nmi("BUG: NMI Watchdog detected LOCKUP", |
118 | regs, panic_on_timeout); | 122 | regs, panic_on_timeout); |
119 | } else { | 123 | } else { |
120 | __get_cpu_var(last_irq_sum) = sum; | 124 | __get_cpu_var(last_irq_sum) = sum; |
121 | local_set(&__get_cpu_var(alert_counter), 0); | 125 | __this_cpu_write(alert_counter, 0); |
122 | } | 126 | } |
123 | if (__get_cpu_var(wd_enabled)) { | 127 | if (__get_cpu_var(wd_enabled)) { |
124 | write_pic(picl_value(nmi_hz)); | 128 | write_pic(picl_value(nmi_hz)); |
125 | pcr_ops->write(pcr_enable); | 129 | pcr_ops->write(pcr_enable); |
126 | } | 130 | } |
127 | 131 | ||
132 | restore_hardirq_stack(orig_sp); | ||
133 | |||
128 | nmi_exit(); | 134 | nmi_exit(); |
129 | } | 135 | } |
130 | 136 | ||
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4c26eb59e742..da527b33ebc7 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c | |||
@@ -105,7 +105,7 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags) | |||
105 | 105 | ||
106 | static int of_bus_ambapp_match(struct device_node *np) | 106 | static int of_bus_ambapp_match(struct device_node *np) |
107 | { | 107 | { |
108 | return !strcmp(np->name, "ambapp"); | 108 | return !strcmp(np->type, "ambapp"); |
109 | } | 109 | } |
110 | 110 | ||
111 | static void of_bus_ambapp_count_cells(struct device_node *child, | 111 | static void of_bus_ambapp_count_cells(struct device_node *child, |
@@ -433,7 +433,7 @@ build_resources: | |||
433 | if (!parent) | 433 | if (!parent) |
434 | dev_set_name(&op->dev, "root"); | 434 | dev_set_name(&op->dev, "root"); |
435 | else | 435 | else |
436 | dev_set_name(&op->dev, "%08x", dp->node); | 436 | dev_set_name(&op->dev, "%08x", dp->phandle); |
437 | 437 | ||
438 | if (of_device_register(op)) { | 438 | if (of_device_register(op)) { |
439 | printk("%s: Could not register of device.\n", | 439 | printk("%s: Could not register of device.\n", |
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 881947e59e95..b3d4cb5d21b3 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c | |||
@@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, | |||
104 | int i; | 104 | int i; |
105 | 105 | ||
106 | /* Check address type match */ | 106 | /* Check address type match */ |
107 | if ((addr[0] ^ range[0]) & 0x03000000) | 107 | if (!((addr[0] ^ range[0]) & 0x03000000)) |
108 | return -EINVAL; | 108 | goto type_match; |
109 | |||
110 | /* Special exception, we can map a 64-bit address into | ||
111 | * a 32-bit range. | ||
112 | */ | ||
113 | if ((addr[0] & 0x03000000) == 0x03000000 && | ||
114 | (range[0] & 0x03000000) == 0x02000000) | ||
115 | goto type_match; | ||
116 | |||
117 | return -EINVAL; | ||
109 | 118 | ||
119 | type_match: | ||
110 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, | 120 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, |
111 | na - 1, ns)) | 121 | na - 1, ns)) |
112 | return -EINVAL; | 122 | return -EINVAL; |
@@ -666,7 +676,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
666 | if (!parent) | 676 | if (!parent) |
667 | dev_set_name(&op->dev, "root"); | 677 | dev_set_name(&op->dev, "root"); |
668 | else | 678 | else |
669 | dev_set_name(&op->dev, "%08x", dp->node); | 679 | dev_set_name(&op->dev, "%08x", dp->phandle); |
670 | 680 | ||
671 | if (of_device_register(op)) { | 681 | if (of_device_register(op)) { |
672 | printk("%s: Could not register of device.\n", | 682 | printk("%s: Could not register of device.\n", |
diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index cb8eb799bb6c..0247e68210b3 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c | |||
@@ -4,7 +4,6 @@ | |||
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/mod_devicetable.h> | 6 | #include <linux/mod_devicetable.h> |
7 | #include <linux/slab.h> | ||
8 | #include <linux/errno.h> | 7 | #include <linux/errno.h> |
9 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
10 | #include <linux/of_device.h> | 9 | #include <linux/of_device.h> |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c68648662802..5ac539a5930f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -247,6 +247,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
247 | struct pci_bus *bus, int devfn) | 247 | struct pci_bus *bus, int devfn) |
248 | { | 248 | { |
249 | struct dev_archdata *sd; | 249 | struct dev_archdata *sd; |
250 | struct pci_slot *slot; | ||
250 | struct of_device *op; | 251 | struct of_device *op; |
251 | struct pci_dev *dev; | 252 | struct pci_dev *dev; |
252 | const char *type; | 253 | const char *type; |
@@ -286,6 +287,11 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
286 | dev->dev.bus = &pci_bus_type; | 287 | dev->dev.bus = &pci_bus_type; |
287 | dev->devfn = devfn; | 288 | dev->devfn = devfn; |
288 | dev->multifunction = 0; /* maybe a lie? */ | 289 | dev->multifunction = 0; /* maybe a lie? */ |
290 | set_pcie_port_type(dev); | ||
291 | |||
292 | list_for_each_entry(slot, &dev->bus->slots, list) | ||
293 | if (PCI_SLOT(dev->devfn) == slot->number) | ||
294 | dev->slot = slot; | ||
289 | 295 | ||
290 | dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); | 296 | dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); |
291 | dev->device = of_getintprop_default(node, "device-id", 0xffff); | 297 | dev->device = of_getintprop_default(node, "device-id", 0xffff); |
@@ -322,6 +328,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
322 | 328 | ||
323 | dev->current_state = 4; /* unknown power state */ | 329 | dev->current_state = 4; /* unknown power state */ |
324 | dev->error_state = pci_channel_io_normal; | 330 | dev->error_state = pci_channel_io_normal; |
331 | dev->dma_mask = 0xffffffff; | ||
325 | 332 | ||
326 | if (!strcmp(node->name, "pci")) { | 333 | if (!strcmp(node->name, "pci")) { |
327 | /* a PCI-PCI bridge */ | 334 | /* a PCI-PCI bridge */ |
@@ -715,9 +722,10 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) | |||
715 | { | 722 | { |
716 | } | 723 | } |
717 | 724 | ||
718 | void pcibios_align_resource(void *data, struct resource *res, | 725 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
719 | resource_size_t size, resource_size_t align) | 726 | resource_size_t size, resource_size_t align) |
720 | { | 727 | { |
728 | return res->start; | ||
721 | } | 729 | } |
722 | 730 | ||
723 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 731 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -1064,7 +1072,6 @@ int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask) | |||
1064 | 1072 | ||
1065 | return (device_mask & dma_addr_mask) == dma_addr_mask; | 1073 | return (device_mask & dma_addr_mask) == dma_addr_mask; |
1066 | } | 1074 | } |
1067 | EXPORT_SYMBOL(pci_dma_supported); | ||
1068 | 1075 | ||
1069 | void pci_resource_to_user(const struct pci_dev *pdev, int bar, | 1076 | void pci_resource_to_user(const struct pci_dev *pdev, int bar, |
1070 | const struct resource *rp, resource_size_t *start, | 1077 | const struct resource *rp, resource_size_t *start, |
@@ -1081,3 +1088,85 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
1081 | *start = rp->start - offset; | 1088 | *start = rp->start - offset; |
1082 | *end = rp->end - offset; | 1089 | *end = rp->end - offset; |
1083 | } | 1090 | } |
1091 | |||
1092 | static int __init pcibios_init(void) | ||
1093 | { | ||
1094 | pci_dfl_cache_line_size = 64 >> 2; | ||
1095 | return 0; | ||
1096 | } | ||
1097 | subsys_initcall(pcibios_init); | ||
1098 | |||
1099 | #ifdef CONFIG_SYSFS | ||
1100 | static void __devinit pci_bus_slot_names(struct device_node *node, | ||
1101 | struct pci_bus *bus) | ||
1102 | { | ||
1103 | const struct pci_slot_names { | ||
1104 | u32 slot_mask; | ||
1105 | char names[0]; | ||
1106 | } *prop; | ||
1107 | const char *sp; | ||
1108 | int len, i; | ||
1109 | u32 mask; | ||
1110 | |||
1111 | prop = of_get_property(node, "slot-names", &len); | ||
1112 | if (!prop) | ||
1113 | return; | ||
1114 | |||
1115 | mask = prop->slot_mask; | ||
1116 | sp = prop->names; | ||
1117 | |||
1118 | if (ofpci_verbose) | ||
1119 | printk("PCI: Making slots for [%s] mask[0x%02x]\n", | ||
1120 | node->full_name, mask); | ||
1121 | |||
1122 | i = 0; | ||
1123 | while (mask) { | ||
1124 | struct pci_slot *pci_slot; | ||
1125 | u32 this_bit = 1 << i; | ||
1126 | |||
1127 | if (!(mask & this_bit)) { | ||
1128 | i++; | ||
1129 | continue; | ||
1130 | } | ||
1131 | |||
1132 | if (ofpci_verbose) | ||
1133 | printk("PCI: Making slot [%s]\n", sp); | ||
1134 | |||
1135 | pci_slot = pci_create_slot(bus, i, sp, NULL); | ||
1136 | if (IS_ERR(pci_slot)) | ||
1137 | printk(KERN_ERR "PCI: pci_create_slot returned %ld\n", | ||
1138 | PTR_ERR(pci_slot)); | ||
1139 | |||
1140 | sp += strlen(sp) + 1; | ||
1141 | mask &= ~this_bit; | ||
1142 | i++; | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | static int __init of_pci_slot_init(void) | ||
1147 | { | ||
1148 | struct pci_bus *pbus = NULL; | ||
1149 | |||
1150 | while ((pbus = pci_find_next_bus(pbus)) != NULL) { | ||
1151 | struct device_node *node; | ||
1152 | |||
1153 | if (pbus->self) { | ||
1154 | struct dev_archdata *sd = pbus->self->sysdata; | ||
1155 | |||
1156 | /* PCI->PCI bridge */ | ||
1157 | node = sd->prom_node; | ||
1158 | } else { | ||
1159 | struct pci_pbm_info *pbm = pbus->sysdata; | ||
1160 | |||
1161 | /* Host PCI controller */ | ||
1162 | node = pbm->op->node; | ||
1163 | } | ||
1164 | |||
1165 | pci_bus_slot_names(node, pbus); | ||
1166 | } | ||
1167 | |||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | module_init(of_pci_slot_init); | ||
1172 | #endif | ||
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index b775658a927d..8a000583b5cf 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c | |||
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) | |||
371 | struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); | 371 | struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); |
372 | 372 | ||
373 | if (!rp) { | 373 | if (!rp) { |
374 | prom_printf("Cannot allocate IOMMU resource.\n"); | 374 | pr_info("%s: Cannot allocate IOMMU resource.\n", |
375 | prom_halt(); | 375 | pbm->name); |
376 | return; | ||
376 | } | 377 | } |
377 | rp->name = "IOMMU"; | 378 | rp->name = "IOMMU"; |
378 | rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; | 379 | rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; |
379 | rp->end = rp->start + (unsigned long) vdma[1] - 1UL; | 380 | rp->end = rp->start + (unsigned long) vdma[1] - 1UL; |
380 | rp->flags = IORESOURCE_BUSY; | 381 | rp->flags = IORESOURCE_BUSY; |
381 | request_resource(&pbm->mem_space, rp); | 382 | if (request_resource(&pbm->mem_space, rp)) { |
383 | pr_info("%s: Unable to request IOMMU resource.\n", | ||
384 | pbm->name); | ||
385 | kfree(rp); | ||
386 | } | ||
382 | } | 387 | } |
383 | } | 388 | } |
384 | 389 | ||
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index f1be37a7b123..e0ef847219c3 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/interrupt.h> | 6 | #include <linux/interrupt.h> |
7 | #include <linux/slab.h> | ||
7 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
8 | 9 | ||
9 | #include "pci_impl.h" | 10 | #include "pci_impl.h" |
@@ -112,7 +113,7 @@ static void free_msi(struct pci_pbm_info *pbm, int msi_num) | |||
112 | } | 113 | } |
113 | 114 | ||
114 | static struct irq_chip msi_irq = { | 115 | static struct irq_chip msi_irq = { |
115 | .typename = "PCI-MSI", | 116 | .name = "PCI-MSI", |
116 | .mask = mask_msi_irq, | 117 | .mask = mask_msi_irq, |
117 | .unmask = unmask_msi_irq, | 118 | .unmask = unmask_msi_irq, |
118 | .enable = unmask_msi_irq, | 119 | .enable = unmask_msi_irq, |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 85e7037429b9..d36a8d391ca0 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/oplib.h> | 30 | #include <asm/oplib.h> |
31 | #include <asm/prom.h> | 31 | #include <asm/prom.h> |
32 | #include <asm/pcic.h> | 32 | #include <asm/pcic.h> |
33 | #include <asm/timex.h> | ||
33 | #include <asm/timer.h> | 34 | #include <asm/timer.h> |
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | #include <asm/irq_regs.h> | 36 | #include <asm/irq_regs.h> |
@@ -163,8 +164,6 @@ void __iomem *pcic_regs; | |||
163 | volatile int pcic_speculative; | 164 | volatile int pcic_speculative; |
164 | volatile int pcic_trapped; | 165 | volatile int pcic_trapped; |
165 | 166 | ||
166 | static void pci_do_gettimeofday(struct timeval *tv); | ||
167 | static int pci_do_settimeofday(struct timespec *tv); | ||
168 | 167 | ||
169 | #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3)) | 168 | #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3)) |
170 | 169 | ||
@@ -586,8 +585,6 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node) | |||
586 | writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO); | 585 | writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO); |
587 | } | 586 | } |
588 | } | 587 | } |
589 | |||
590 | return; | ||
591 | } | 588 | } |
592 | 589 | ||
593 | /* | 590 | /* |
@@ -716,19 +713,27 @@ static irqreturn_t pcic_timer_handler (int irq, void *h) | |||
716 | #define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */ | 713 | #define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */ |
717 | #define TICK_TIMER_LIMIT ((100*1000000/4)/100) | 714 | #define TICK_TIMER_LIMIT ((100*1000000/4)/100) |
718 | 715 | ||
716 | u32 pci_gettimeoffset(void) | ||
717 | { | ||
718 | /* | ||
719 | * We divide all by 100 | ||
720 | * to have microsecond resolution and to avoid overflow | ||
721 | */ | ||
722 | unsigned long count = | ||
723 | readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW; | ||
724 | count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100); | ||
725 | return count * 1000; | ||
726 | } | ||
727 | |||
728 | |||
719 | void __init pci_time_init(void) | 729 | void __init pci_time_init(void) |
720 | { | 730 | { |
721 | struct linux_pcic *pcic = &pcic0; | 731 | struct linux_pcic *pcic = &pcic0; |
722 | unsigned long v; | 732 | unsigned long v; |
723 | int timer_irq, irq; | 733 | int timer_irq, irq; |
724 | 734 | ||
725 | /* A hack until do_gettimeofday prototype is moved to arch specific headers | 735 | do_arch_gettimeoffset = pci_gettimeoffset; |
726 | and btfixupped. Patch do_gettimeofday with ba pci_do_gettimeofday; nop */ | 736 | |
727 | ((unsigned int *)do_gettimeofday)[0] = | ||
728 | 0x10800000 | ((((unsigned long)pci_do_gettimeofday - | ||
729 | (unsigned long)do_gettimeofday) >> 2) & 0x003fffff); | ||
730 | ((unsigned int *)do_gettimeofday)[1] = 0x01000000; | ||
731 | BTFIXUPSET_CALL(bus_do_settimeofday, pci_do_settimeofday, BTFIXUPCALL_NORM); | ||
732 | btfixup(); | 737 | btfixup(); |
733 | 738 | ||
734 | writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT); | 739 | writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT); |
@@ -746,84 +751,6 @@ void __init pci_time_init(void) | |||
746 | local_irq_enable(); | 751 | local_irq_enable(); |
747 | } | 752 | } |
748 | 753 | ||
749 | static inline unsigned long do_gettimeoffset(void) | ||
750 | { | ||
751 | /* | ||
752 | * We divide all by 100 | ||
753 | * to have microsecond resolution and to avoid overflow | ||
754 | */ | ||
755 | unsigned long count = | ||
756 | readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW; | ||
757 | count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100); | ||
758 | return count; | ||
759 | } | ||
760 | |||
761 | static void pci_do_gettimeofday(struct timeval *tv) | ||
762 | { | ||
763 | unsigned long flags; | ||
764 | unsigned long seq; | ||
765 | unsigned long usec, sec; | ||
766 | unsigned long max_ntp_tick = tick_usec - tickadj; | ||
767 | |||
768 | do { | ||
769 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
770 | usec = do_gettimeoffset(); | ||
771 | |||
772 | /* | ||
773 | * If time_adjust is negative then NTP is slowing the clock | ||
774 | * so make sure not to go into next possible interval. | ||
775 | * Better to lose some accuracy than have time go backwards.. | ||
776 | */ | ||
777 | if (unlikely(time_adjust < 0)) | ||
778 | usec = min(usec, max_ntp_tick); | ||
779 | |||
780 | sec = xtime.tv_sec; | ||
781 | usec += (xtime.tv_nsec / 1000); | ||
782 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
783 | |||
784 | while (usec >= 1000000) { | ||
785 | usec -= 1000000; | ||
786 | sec++; | ||
787 | } | ||
788 | |||
789 | tv->tv_sec = sec; | ||
790 | tv->tv_usec = usec; | ||
791 | } | ||
792 | |||
793 | static int pci_do_settimeofday(struct timespec *tv) | ||
794 | { | ||
795 | if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) | ||
796 | return -EINVAL; | ||
797 | |||
798 | /* | ||
799 | * This is revolting. We need to set "xtime" correctly. However, the | ||
800 | * value in this location is the value at the most recent update of | ||
801 | * wall time. Discover what correction gettimeofday() would have | ||
802 | * made, and then undo it! | ||
803 | */ | ||
804 | tv->tv_nsec -= 1000 * do_gettimeoffset(); | ||
805 | while (tv->tv_nsec < 0) { | ||
806 | tv->tv_nsec += NSEC_PER_SEC; | ||
807 | tv->tv_sec--; | ||
808 | } | ||
809 | |||
810 | wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec; | ||
811 | wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec; | ||
812 | |||
813 | if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) { | ||
814 | wall_to_monotonic.tv_nsec -= NSEC_PER_SEC; | ||
815 | wall_to_monotonic.tv_sec++; | ||
816 | } | ||
817 | if (wall_to_monotonic.tv_nsec < 0) { | ||
818 | wall_to_monotonic.tv_nsec += NSEC_PER_SEC; | ||
819 | wall_to_monotonic.tv_sec--; | ||
820 | } | ||
821 | |||
822 | xtime.tv_sec = tv->tv_sec; | ||
823 | xtime.tv_nsec = tv->tv_nsec; | ||
824 | ntp_clear(); | ||
825 | return 0; | ||
826 | } | ||
827 | 754 | ||
828 | #if 0 | 755 | #if 0 |
829 | static void watchdog_reset() { | 756 | static void watchdog_reset() { |
@@ -839,9 +766,10 @@ char * __devinit pcibios_setup(char *str) | |||
839 | return str; | 766 | return str; |
840 | } | 767 | } |
841 | 768 | ||
842 | void pcibios_align_resource(void *data, struct resource *res, | 769 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
843 | resource_size_t size, resource_size_t align) | 770 | resource_size_t size, resource_size_t align) |
844 | { | 771 | { |
772 | return res->start; | ||
845 | } | 773 | } |
846 | 774 | ||
847 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | 775 | int pcibios_enable_device(struct pci_dev *pdev, int mask) |
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 2d94e7a03af5..c4a6a50b4849 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
9 | 9 | ||
10 | #include <linux/perf_event.h> | 10 | #include <linux/perf_event.h> |
11 | #include <linux/ftrace.h> | ||
11 | 12 | ||
12 | #include <asm/pil.h> | 13 | #include <asm/pil.h> |
13 | #include <asm/pcr.h> | 14 | #include <asm/pcr.h> |
@@ -34,7 +35,7 @@ unsigned int picl_shift; | |||
34 | * Therefore in such situations we defer the work by signalling | 35 | * Therefore in such situations we defer the work by signalling |
35 | * a lower level cpu IRQ. | 36 | * a lower level cpu IRQ. |
36 | */ | 37 | */ |
37 | void deferred_pcr_work_irq(int irq, struct pt_regs *regs) | 38 | void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs) |
38 | { | 39 | { |
39 | struct pt_regs *old_regs; | 40 | struct pt_regs *old_regs; |
40 | 41 | ||
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index fa5936e1c3b9..e2771939341d 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* Performance event support for sparc64. | 1 | /* Performance event support for sparc64. |
2 | * | 2 | * |
3 | * Copyright (C) 2009 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2009, 2010 David S. Miller <davem@davemloft.net> |
4 | * | 4 | * |
5 | * This code is based almost entirely upon the x86 perf event | 5 | * This code is based almost entirely upon the x86 perf event |
6 | * code, which is: | 6 | * code, which is: |
@@ -18,11 +18,15 @@ | |||
18 | #include <linux/kdebug.h> | 18 | #include <linux/kdebug.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | 20 | ||
21 | #include <asm/stacktrace.h> | ||
21 | #include <asm/cpudata.h> | 22 | #include <asm/cpudata.h> |
23 | #include <asm/uaccess.h> | ||
22 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
23 | #include <asm/nmi.h> | 25 | #include <asm/nmi.h> |
24 | #include <asm/pcr.h> | 26 | #include <asm/pcr.h> |
25 | 27 | ||
28 | #include "kstack.h" | ||
29 | |||
26 | /* Sparc64 chips have two performance counters, 32-bits each, with | 30 | /* Sparc64 chips have two performance counters, 32-bits each, with |
27 | * overflow interrupts generated on transition from 0xffffffff to 0. | 31 | * overflow interrupts generated on transition from 0xffffffff to 0. |
28 | * The counters are accessed in one go using a 64-bit register. | 32 | * The counters are accessed in one go using a 64-bit register. |
@@ -51,16 +55,49 @@ | |||
51 | 55 | ||
52 | #define PIC_UPPER_INDEX 0 | 56 | #define PIC_UPPER_INDEX 0 |
53 | #define PIC_LOWER_INDEX 1 | 57 | #define PIC_LOWER_INDEX 1 |
58 | #define PIC_NO_INDEX -1 | ||
54 | 59 | ||
55 | struct cpu_hw_events { | 60 | struct cpu_hw_events { |
56 | struct perf_event *events[MAX_HWEVENTS]; | 61 | /* Number of events currently scheduled onto this cpu. |
57 | unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; | 62 | * This tells how many entries in the arrays below |
58 | unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; | 63 | * are valid. |
64 | */ | ||
65 | int n_events; | ||
66 | |||
67 | /* Number of new events added since the last hw_perf_disable(). | ||
68 | * This works because the perf event layer always adds new | ||
69 | * events inside of a perf_{disable,enable}() sequence. | ||
70 | */ | ||
71 | int n_added; | ||
72 | |||
73 | /* Array of events current scheduled on this cpu. */ | ||
74 | struct perf_event *event[MAX_HWEVENTS]; | ||
75 | |||
76 | /* Array of encoded longs, specifying the %pcr register | ||
77 | * encoding and the mask of PIC counters this even can | ||
78 | * be scheduled on. See perf_event_encode() et al. | ||
79 | */ | ||
80 | unsigned long events[MAX_HWEVENTS]; | ||
81 | |||
82 | /* The current counter index assigned to an event. When the | ||
83 | * event hasn't been programmed into the cpu yet, this will | ||
84 | * hold PIC_NO_INDEX. The event->hw.idx value tells us where | ||
85 | * we ought to schedule the event. | ||
86 | */ | ||
87 | int current_idx[MAX_HWEVENTS]; | ||
88 | |||
89 | /* Software copy of %pcr register on this cpu. */ | ||
59 | u64 pcr; | 90 | u64 pcr; |
91 | |||
92 | /* Enabled/disable state. */ | ||
60 | int enabled; | 93 | int enabled; |
61 | }; | 94 | }; |
62 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; | 95 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; |
63 | 96 | ||
97 | /* An event map describes the characteristics of a performance | ||
98 | * counter event. In particular it gives the encoding as well as | ||
99 | * a mask telling which counters the event can be measured on. | ||
100 | */ | ||
64 | struct perf_event_map { | 101 | struct perf_event_map { |
65 | u16 encoding; | 102 | u16 encoding; |
66 | u8 pic_mask; | 103 | u8 pic_mask; |
@@ -69,15 +106,20 @@ struct perf_event_map { | |||
69 | #define PIC_LOWER 0x02 | 106 | #define PIC_LOWER 0x02 |
70 | }; | 107 | }; |
71 | 108 | ||
109 | /* Encode a perf_event_map entry into a long. */ | ||
72 | static unsigned long perf_event_encode(const struct perf_event_map *pmap) | 110 | static unsigned long perf_event_encode(const struct perf_event_map *pmap) |
73 | { | 111 | { |
74 | return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask; | 112 | return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask; |
75 | } | 113 | } |
76 | 114 | ||
77 | static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk) | 115 | static u8 perf_event_get_msk(unsigned long val) |
78 | { | 116 | { |
79 | *msk = val & 0xff; | 117 | return val & 0xff; |
80 | *enc = val >> 16; | 118 | } |
119 | |||
120 | static u64 perf_event_get_enc(unsigned long val) | ||
121 | { | ||
122 | return val >> 16; | ||
81 | } | 123 | } |
82 | 124 | ||
83 | #define C(x) PERF_COUNT_HW_CACHE_##x | 125 | #define C(x) PERF_COUNT_HW_CACHE_##x |
@@ -491,53 +533,6 @@ static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw | |||
491 | pcr_ops->write(cpuc->pcr); | 533 | pcr_ops->write(cpuc->pcr); |
492 | } | 534 | } |
493 | 535 | ||
494 | void hw_perf_enable(void) | ||
495 | { | ||
496 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
497 | u64 val; | ||
498 | int i; | ||
499 | |||
500 | if (cpuc->enabled) | ||
501 | return; | ||
502 | |||
503 | cpuc->enabled = 1; | ||
504 | barrier(); | ||
505 | |||
506 | val = cpuc->pcr; | ||
507 | |||
508 | for (i = 0; i < MAX_HWEVENTS; i++) { | ||
509 | struct perf_event *cp = cpuc->events[i]; | ||
510 | struct hw_perf_event *hwc; | ||
511 | |||
512 | if (!cp) | ||
513 | continue; | ||
514 | hwc = &cp->hw; | ||
515 | val |= hwc->config_base; | ||
516 | } | ||
517 | |||
518 | cpuc->pcr = val; | ||
519 | |||
520 | pcr_ops->write(cpuc->pcr); | ||
521 | } | ||
522 | |||
523 | void hw_perf_disable(void) | ||
524 | { | ||
525 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
526 | u64 val; | ||
527 | |||
528 | if (!cpuc->enabled) | ||
529 | return; | ||
530 | |||
531 | cpuc->enabled = 0; | ||
532 | |||
533 | val = cpuc->pcr; | ||
534 | val &= ~(PCR_UTRACE | PCR_STRACE | | ||
535 | sparc_pmu->hv_bit | sparc_pmu->irq_bit); | ||
536 | cpuc->pcr = val; | ||
537 | |||
538 | pcr_ops->write(cpuc->pcr); | ||
539 | } | ||
540 | |||
541 | static u32 read_pmc(int idx) | 536 | static u32 read_pmc(int idx) |
542 | { | 537 | { |
543 | u64 val; | 538 | u64 val; |
@@ -566,6 +561,30 @@ static void write_pmc(int idx, u64 val) | |||
566 | write_pic(pic); | 561 | write_pic(pic); |
567 | } | 562 | } |
568 | 563 | ||
564 | static u64 sparc_perf_event_update(struct perf_event *event, | ||
565 | struct hw_perf_event *hwc, int idx) | ||
566 | { | ||
567 | int shift = 64 - 32; | ||
568 | u64 prev_raw_count, new_raw_count; | ||
569 | s64 delta; | ||
570 | |||
571 | again: | ||
572 | prev_raw_count = atomic64_read(&hwc->prev_count); | ||
573 | new_raw_count = read_pmc(idx); | ||
574 | |||
575 | if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, | ||
576 | new_raw_count) != prev_raw_count) | ||
577 | goto again; | ||
578 | |||
579 | delta = (new_raw_count << shift) - (prev_raw_count << shift); | ||
580 | delta >>= shift; | ||
581 | |||
582 | atomic64_add(delta, &event->count); | ||
583 | atomic64_sub(delta, &hwc->period_left); | ||
584 | |||
585 | return new_raw_count; | ||
586 | } | ||
587 | |||
569 | static int sparc_perf_event_set_period(struct perf_event *event, | 588 | static int sparc_perf_event_set_period(struct perf_event *event, |
570 | struct hw_perf_event *hwc, int idx) | 589 | struct hw_perf_event *hwc, int idx) |
571 | { | 590 | { |
@@ -598,81 +617,166 @@ static int sparc_perf_event_set_period(struct perf_event *event, | |||
598 | return ret; | 617 | return ret; |
599 | } | 618 | } |
600 | 619 | ||
601 | static int sparc_pmu_enable(struct perf_event *event) | 620 | /* If performance event entries have been added, move existing |
621 | * events around (if necessary) and then assign new entries to | ||
622 | * counters. | ||
623 | */ | ||
624 | static u64 maybe_change_configuration(struct cpu_hw_events *cpuc, u64 pcr) | ||
602 | { | 625 | { |
603 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 626 | int i; |
604 | struct hw_perf_event *hwc = &event->hw; | ||
605 | int idx = hwc->idx; | ||
606 | 627 | ||
607 | if (test_and_set_bit(idx, cpuc->used_mask)) | 628 | if (!cpuc->n_added) |
608 | return -EAGAIN; | 629 | goto out; |
609 | 630 | ||
610 | sparc_pmu_disable_event(cpuc, hwc, idx); | 631 | /* Read in the counters which are moving. */ |
632 | for (i = 0; i < cpuc->n_events; i++) { | ||
633 | struct perf_event *cp = cpuc->event[i]; | ||
611 | 634 | ||
612 | cpuc->events[idx] = event; | 635 | if (cpuc->current_idx[i] != PIC_NO_INDEX && |
613 | set_bit(idx, cpuc->active_mask); | 636 | cpuc->current_idx[i] != cp->hw.idx) { |
637 | sparc_perf_event_update(cp, &cp->hw, | ||
638 | cpuc->current_idx[i]); | ||
639 | cpuc->current_idx[i] = PIC_NO_INDEX; | ||
640 | } | ||
641 | } | ||
614 | 642 | ||
615 | sparc_perf_event_set_period(event, hwc, idx); | 643 | /* Assign to counters all unassigned events. */ |
616 | sparc_pmu_enable_event(cpuc, hwc, idx); | 644 | for (i = 0; i < cpuc->n_events; i++) { |
617 | perf_event_update_userpage(event); | 645 | struct perf_event *cp = cpuc->event[i]; |
618 | return 0; | 646 | struct hw_perf_event *hwc = &cp->hw; |
647 | int idx = hwc->idx; | ||
648 | u64 enc; | ||
649 | |||
650 | if (cpuc->current_idx[i] != PIC_NO_INDEX) | ||
651 | continue; | ||
652 | |||
653 | sparc_perf_event_set_period(cp, hwc, idx); | ||
654 | cpuc->current_idx[i] = idx; | ||
655 | |||
656 | enc = perf_event_get_enc(cpuc->events[i]); | ||
657 | pcr |= event_encoding(enc, idx); | ||
658 | } | ||
659 | out: | ||
660 | return pcr; | ||
619 | } | 661 | } |
620 | 662 | ||
621 | static u64 sparc_perf_event_update(struct perf_event *event, | 663 | void hw_perf_enable(void) |
622 | struct hw_perf_event *hwc, int idx) | ||
623 | { | 664 | { |
624 | int shift = 64 - 32; | 665 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
625 | u64 prev_raw_count, new_raw_count; | 666 | u64 pcr; |
626 | s64 delta; | ||
627 | 667 | ||
628 | again: | 668 | if (cpuc->enabled) |
629 | prev_raw_count = atomic64_read(&hwc->prev_count); | 669 | return; |
630 | new_raw_count = read_pmc(idx); | ||
631 | 670 | ||
632 | if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, | 671 | cpuc->enabled = 1; |
633 | new_raw_count) != prev_raw_count) | 672 | barrier(); |
634 | goto again; | ||
635 | 673 | ||
636 | delta = (new_raw_count << shift) - (prev_raw_count << shift); | 674 | pcr = cpuc->pcr; |
637 | delta >>= shift; | 675 | if (!cpuc->n_events) { |
676 | pcr = 0; | ||
677 | } else { | ||
678 | pcr = maybe_change_configuration(cpuc, pcr); | ||
638 | 679 | ||
639 | atomic64_add(delta, &event->count); | 680 | /* We require that all of the events have the same |
640 | atomic64_sub(delta, &hwc->period_left); | 681 | * configuration, so just fetch the settings from the |
682 | * first entry. | ||
683 | */ | ||
684 | cpuc->pcr = pcr | cpuc->event[0]->hw.config_base; | ||
685 | } | ||
641 | 686 | ||
642 | return new_raw_count; | 687 | pcr_ops->write(cpuc->pcr); |
688 | } | ||
689 | |||
690 | void hw_perf_disable(void) | ||
691 | { | ||
692 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
693 | u64 val; | ||
694 | |||
695 | if (!cpuc->enabled) | ||
696 | return; | ||
697 | |||
698 | cpuc->enabled = 0; | ||
699 | cpuc->n_added = 0; | ||
700 | |||
701 | val = cpuc->pcr; | ||
702 | val &= ~(PCR_UTRACE | PCR_STRACE | | ||
703 | sparc_pmu->hv_bit | sparc_pmu->irq_bit); | ||
704 | cpuc->pcr = val; | ||
705 | |||
706 | pcr_ops->write(cpuc->pcr); | ||
643 | } | 707 | } |
644 | 708 | ||
645 | static void sparc_pmu_disable(struct perf_event *event) | 709 | static void sparc_pmu_disable(struct perf_event *event) |
646 | { | 710 | { |
647 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 711 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
648 | struct hw_perf_event *hwc = &event->hw; | 712 | struct hw_perf_event *hwc = &event->hw; |
649 | int idx = hwc->idx; | 713 | unsigned long flags; |
714 | int i; | ||
650 | 715 | ||
651 | clear_bit(idx, cpuc->active_mask); | 716 | local_irq_save(flags); |
652 | sparc_pmu_disable_event(cpuc, hwc, idx); | 717 | perf_disable(); |
718 | |||
719 | for (i = 0; i < cpuc->n_events; i++) { | ||
720 | if (event == cpuc->event[i]) { | ||
721 | int idx = cpuc->current_idx[i]; | ||
722 | |||
723 | /* Shift remaining entries down into | ||
724 | * the existing slot. | ||
725 | */ | ||
726 | while (++i < cpuc->n_events) { | ||
727 | cpuc->event[i - 1] = cpuc->event[i]; | ||
728 | cpuc->events[i - 1] = cpuc->events[i]; | ||
729 | cpuc->current_idx[i - 1] = | ||
730 | cpuc->current_idx[i]; | ||
731 | } | ||
732 | |||
733 | /* Absorb the final count and turn off the | ||
734 | * event. | ||
735 | */ | ||
736 | sparc_pmu_disable_event(cpuc, hwc, idx); | ||
737 | barrier(); | ||
738 | sparc_perf_event_update(event, hwc, idx); | ||
653 | 739 | ||
654 | barrier(); | 740 | perf_event_update_userpage(event); |
655 | 741 | ||
656 | sparc_perf_event_update(event, hwc, idx); | 742 | cpuc->n_events--; |
657 | cpuc->events[idx] = NULL; | 743 | break; |
658 | clear_bit(idx, cpuc->used_mask); | 744 | } |
745 | } | ||
659 | 746 | ||
660 | perf_event_update_userpage(event); | 747 | perf_enable(); |
748 | local_irq_restore(flags); | ||
749 | } | ||
750 | |||
751 | static int active_event_index(struct cpu_hw_events *cpuc, | ||
752 | struct perf_event *event) | ||
753 | { | ||
754 | int i; | ||
755 | |||
756 | for (i = 0; i < cpuc->n_events; i++) { | ||
757 | if (cpuc->event[i] == event) | ||
758 | break; | ||
759 | } | ||
760 | BUG_ON(i == cpuc->n_events); | ||
761 | return cpuc->current_idx[i]; | ||
661 | } | 762 | } |
662 | 763 | ||
663 | static void sparc_pmu_read(struct perf_event *event) | 764 | static void sparc_pmu_read(struct perf_event *event) |
664 | { | 765 | { |
766 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
767 | int idx = active_event_index(cpuc, event); | ||
665 | struct hw_perf_event *hwc = &event->hw; | 768 | struct hw_perf_event *hwc = &event->hw; |
666 | 769 | ||
667 | sparc_perf_event_update(event, hwc, hwc->idx); | 770 | sparc_perf_event_update(event, hwc, idx); |
668 | } | 771 | } |
669 | 772 | ||
670 | static void sparc_pmu_unthrottle(struct perf_event *event) | 773 | static void sparc_pmu_unthrottle(struct perf_event *event) |
671 | { | 774 | { |
672 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 775 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
776 | int idx = active_event_index(cpuc, event); | ||
673 | struct hw_perf_event *hwc = &event->hw; | 777 | struct hw_perf_event *hwc = &event->hw; |
674 | 778 | ||
675 | sparc_pmu_enable_event(cpuc, hwc, hwc->idx); | 779 | sparc_pmu_enable_event(cpuc, hwc, idx); |
676 | } | 780 | } |
677 | 781 | ||
678 | static atomic_t active_events = ATOMIC_INIT(0); | 782 | static atomic_t active_events = ATOMIC_INIT(0); |
@@ -750,43 +854,75 @@ static void hw_perf_event_destroy(struct perf_event *event) | |||
750 | /* Make sure all events can be scheduled into the hardware at | 854 | /* Make sure all events can be scheduled into the hardware at |
751 | * the same time. This is simplified by the fact that we only | 855 | * the same time. This is simplified by the fact that we only |
752 | * need to support 2 simultaneous HW events. | 856 | * need to support 2 simultaneous HW events. |
857 | * | ||
858 | * As a side effect, the evts[]->hw.idx values will be assigned | ||
859 | * on success. These are pending indexes. When the events are | ||
860 | * actually programmed into the chip, these values will propagate | ||
861 | * to the per-cpu cpuc->current_idx[] slots, see the code in | ||
862 | * maybe_change_configuration() for details. | ||
753 | */ | 863 | */ |
754 | static int sparc_check_constraints(unsigned long *events, int n_ev) | 864 | static int sparc_check_constraints(struct perf_event **evts, |
865 | unsigned long *events, int n_ev) | ||
755 | { | 866 | { |
756 | if (n_ev <= perf_max_events) { | 867 | u8 msk0 = 0, msk1 = 0; |
757 | u8 msk1, msk2; | 868 | int idx0 = 0; |
758 | u16 dummy; | 869 | |
759 | 870 | /* This case is possible when we are invoked from | |
760 | if (n_ev == 1) | 871 | * hw_perf_group_sched_in(). |
761 | return 0; | 872 | */ |
762 | BUG_ON(n_ev != 2); | 873 | if (!n_ev) |
763 | perf_event_decode(events[0], &dummy, &msk1); | 874 | return 0; |
764 | perf_event_decode(events[1], &dummy, &msk2); | 875 | |
765 | 876 | if (n_ev > perf_max_events) | |
766 | /* If both events can go on any counter, OK. */ | 877 | return -1; |
767 | if (msk1 == (PIC_UPPER | PIC_LOWER) && | 878 | |
768 | msk2 == (PIC_UPPER | PIC_LOWER)) | 879 | msk0 = perf_event_get_msk(events[0]); |
769 | return 0; | 880 | if (n_ev == 1) { |
770 | 881 | if (msk0 & PIC_LOWER) | |
771 | /* If one event is limited to a specific counter, | 882 | idx0 = 1; |
772 | * and the other can go on both, OK. | 883 | goto success; |
773 | */ | 884 | } |
774 | if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) && | 885 | BUG_ON(n_ev != 2); |
775 | msk2 == (PIC_UPPER | PIC_LOWER)) | 886 | msk1 = perf_event_get_msk(events[1]); |
776 | return 0; | 887 | |
777 | if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) && | 888 | /* If both events can go on any counter, OK. */ |
778 | msk1 == (PIC_UPPER | PIC_LOWER)) | 889 | if (msk0 == (PIC_UPPER | PIC_LOWER) && |
779 | return 0; | 890 | msk1 == (PIC_UPPER | PIC_LOWER)) |
780 | 891 | goto success; | |
781 | /* If the events are fixed to different counters, OK. */ | 892 | |
782 | if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) || | 893 | /* If one event is limited to a specific counter, |
783 | (msk1 == PIC_LOWER && msk2 == PIC_UPPER)) | 894 | * and the other can go on both, OK. |
784 | return 0; | 895 | */ |
785 | 896 | if ((msk0 == PIC_UPPER || msk0 == PIC_LOWER) && | |
786 | /* Otherwise, there is a conflict. */ | 897 | msk1 == (PIC_UPPER | PIC_LOWER)) { |
898 | if (msk0 & PIC_LOWER) | ||
899 | idx0 = 1; | ||
900 | goto success; | ||
787 | } | 901 | } |
788 | 902 | ||
903 | if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) && | ||
904 | msk0 == (PIC_UPPER | PIC_LOWER)) { | ||
905 | if (msk1 & PIC_UPPER) | ||
906 | idx0 = 1; | ||
907 | goto success; | ||
908 | } | ||
909 | |||
910 | /* If the events are fixed to different counters, OK. */ | ||
911 | if ((msk0 == PIC_UPPER && msk1 == PIC_LOWER) || | ||
912 | (msk0 == PIC_LOWER && msk1 == PIC_UPPER)) { | ||
913 | if (msk0 & PIC_LOWER) | ||
914 | idx0 = 1; | ||
915 | goto success; | ||
916 | } | ||
917 | |||
918 | /* Otherwise, there is a conflict. */ | ||
789 | return -1; | 919 | return -1; |
920 | |||
921 | success: | ||
922 | evts[0]->hw.idx = idx0; | ||
923 | if (n_ev == 2) | ||
924 | evts[1]->hw.idx = idx0 ^ 1; | ||
925 | return 0; | ||
790 | } | 926 | } |
791 | 927 | ||
792 | static int check_excludes(struct perf_event **evts, int n_prev, int n_new) | 928 | static int check_excludes(struct perf_event **evts, int n_prev, int n_new) |
@@ -818,7 +954,8 @@ static int check_excludes(struct perf_event **evts, int n_prev, int n_new) | |||
818 | } | 954 | } |
819 | 955 | ||
820 | static int collect_events(struct perf_event *group, int max_count, | 956 | static int collect_events(struct perf_event *group, int max_count, |
821 | struct perf_event *evts[], unsigned long *events) | 957 | struct perf_event *evts[], unsigned long *events, |
958 | int *current_idx) | ||
822 | { | 959 | { |
823 | struct perf_event *event; | 960 | struct perf_event *event; |
824 | int n = 0; | 961 | int n = 0; |
@@ -827,7 +964,8 @@ static int collect_events(struct perf_event *group, int max_count, | |||
827 | if (n >= max_count) | 964 | if (n >= max_count) |
828 | return -1; | 965 | return -1; |
829 | evts[n] = group; | 966 | evts[n] = group; |
830 | events[n++] = group->hw.event_base; | 967 | events[n] = group->hw.event_base; |
968 | current_idx[n++] = PIC_NO_INDEX; | ||
831 | } | 969 | } |
832 | list_for_each_entry(event, &group->sibling_list, group_entry) { | 970 | list_for_each_entry(event, &group->sibling_list, group_entry) { |
833 | if (!is_software_event(event) && | 971 | if (!is_software_event(event) && |
@@ -835,20 +973,100 @@ static int collect_events(struct perf_event *group, int max_count, | |||
835 | if (n >= max_count) | 973 | if (n >= max_count) |
836 | return -1; | 974 | return -1; |
837 | evts[n] = event; | 975 | evts[n] = event; |
838 | events[n++] = event->hw.event_base; | 976 | events[n] = event->hw.event_base; |
977 | current_idx[n++] = PIC_NO_INDEX; | ||
839 | } | 978 | } |
840 | } | 979 | } |
841 | return n; | 980 | return n; |
842 | } | 981 | } |
843 | 982 | ||
983 | static void event_sched_in(struct perf_event *event) | ||
984 | { | ||
985 | event->state = PERF_EVENT_STATE_ACTIVE; | ||
986 | event->oncpu = smp_processor_id(); | ||
987 | event->tstamp_running += event->ctx->time - event->tstamp_stopped; | ||
988 | if (is_software_event(event)) | ||
989 | event->pmu->enable(event); | ||
990 | } | ||
991 | |||
992 | int hw_perf_group_sched_in(struct perf_event *group_leader, | ||
993 | struct perf_cpu_context *cpuctx, | ||
994 | struct perf_event_context *ctx) | ||
995 | { | ||
996 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
997 | struct perf_event *sub; | ||
998 | int n0, n; | ||
999 | |||
1000 | if (!sparc_pmu) | ||
1001 | return 0; | ||
1002 | |||
1003 | n0 = cpuc->n_events; | ||
1004 | n = collect_events(group_leader, perf_max_events - n0, | ||
1005 | &cpuc->event[n0], &cpuc->events[n0], | ||
1006 | &cpuc->current_idx[n0]); | ||
1007 | if (n < 0) | ||
1008 | return -EAGAIN; | ||
1009 | if (check_excludes(cpuc->event, n0, n)) | ||
1010 | return -EINVAL; | ||
1011 | if (sparc_check_constraints(cpuc->event, cpuc->events, n + n0)) | ||
1012 | return -EAGAIN; | ||
1013 | cpuc->n_events = n0 + n; | ||
1014 | cpuc->n_added += n; | ||
1015 | |||
1016 | cpuctx->active_oncpu += n; | ||
1017 | n = 1; | ||
1018 | event_sched_in(group_leader); | ||
1019 | list_for_each_entry(sub, &group_leader->sibling_list, group_entry) { | ||
1020 | if (sub->state != PERF_EVENT_STATE_OFF) { | ||
1021 | event_sched_in(sub); | ||
1022 | n++; | ||
1023 | } | ||
1024 | } | ||
1025 | ctx->nr_active += n; | ||
1026 | |||
1027 | return 1; | ||
1028 | } | ||
1029 | |||
1030 | static int sparc_pmu_enable(struct perf_event *event) | ||
1031 | { | ||
1032 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
1033 | int n0, ret = -EAGAIN; | ||
1034 | unsigned long flags; | ||
1035 | |||
1036 | local_irq_save(flags); | ||
1037 | perf_disable(); | ||
1038 | |||
1039 | n0 = cpuc->n_events; | ||
1040 | if (n0 >= perf_max_events) | ||
1041 | goto out; | ||
1042 | |||
1043 | cpuc->event[n0] = event; | ||
1044 | cpuc->events[n0] = event->hw.event_base; | ||
1045 | cpuc->current_idx[n0] = PIC_NO_INDEX; | ||
1046 | |||
1047 | if (check_excludes(cpuc->event, n0, 1)) | ||
1048 | goto out; | ||
1049 | if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1)) | ||
1050 | goto out; | ||
1051 | |||
1052 | cpuc->n_events++; | ||
1053 | cpuc->n_added++; | ||
1054 | |||
1055 | ret = 0; | ||
1056 | out: | ||
1057 | perf_enable(); | ||
1058 | local_irq_restore(flags); | ||
1059 | return ret; | ||
1060 | } | ||
1061 | |||
844 | static int __hw_perf_event_init(struct perf_event *event) | 1062 | static int __hw_perf_event_init(struct perf_event *event) |
845 | { | 1063 | { |
846 | struct perf_event_attr *attr = &event->attr; | 1064 | struct perf_event_attr *attr = &event->attr; |
847 | struct perf_event *evts[MAX_HWEVENTS]; | 1065 | struct perf_event *evts[MAX_HWEVENTS]; |
848 | struct hw_perf_event *hwc = &event->hw; | 1066 | struct hw_perf_event *hwc = &event->hw; |
849 | unsigned long events[MAX_HWEVENTS]; | 1067 | unsigned long events[MAX_HWEVENTS]; |
1068 | int current_idx_dmy[MAX_HWEVENTS]; | ||
850 | const struct perf_event_map *pmap; | 1069 | const struct perf_event_map *pmap; |
851 | u64 enc; | ||
852 | int n; | 1070 | int n; |
853 | 1071 | ||
854 | if (atomic_read(&nmi_active) < 0) | 1072 | if (atomic_read(&nmi_active) < 0) |
@@ -865,10 +1083,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
865 | } else | 1083 | } else |
866 | return -EOPNOTSUPP; | 1084 | return -EOPNOTSUPP; |
867 | 1085 | ||
868 | /* We save the enable bits in the config_base. So to | 1086 | /* We save the enable bits in the config_base. */ |
869 | * turn off sampling just write 'config', and to enable | ||
870 | * things write 'config | config_base'. | ||
871 | */ | ||
872 | hwc->config_base = sparc_pmu->irq_bit; | 1087 | hwc->config_base = sparc_pmu->irq_bit; |
873 | if (!attr->exclude_user) | 1088 | if (!attr->exclude_user) |
874 | hwc->config_base |= PCR_UTRACE; | 1089 | hwc->config_base |= PCR_UTRACE; |
@@ -879,13 +1094,11 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
879 | 1094 | ||
880 | hwc->event_base = perf_event_encode(pmap); | 1095 | hwc->event_base = perf_event_encode(pmap); |
881 | 1096 | ||
882 | enc = pmap->encoding; | ||
883 | |||
884 | n = 0; | 1097 | n = 0; |
885 | if (event->group_leader != event) { | 1098 | if (event->group_leader != event) { |
886 | n = collect_events(event->group_leader, | 1099 | n = collect_events(event->group_leader, |
887 | perf_max_events - 1, | 1100 | perf_max_events - 1, |
888 | evts, events); | 1101 | evts, events, current_idx_dmy); |
889 | if (n < 0) | 1102 | if (n < 0) |
890 | return -EINVAL; | 1103 | return -EINVAL; |
891 | } | 1104 | } |
@@ -895,9 +1108,11 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
895 | if (check_excludes(evts, n, 1)) | 1108 | if (check_excludes(evts, n, 1)) |
896 | return -EINVAL; | 1109 | return -EINVAL; |
897 | 1110 | ||
898 | if (sparc_check_constraints(events, n + 1)) | 1111 | if (sparc_check_constraints(evts, events, n + 1)) |
899 | return -EINVAL; | 1112 | return -EINVAL; |
900 | 1113 | ||
1114 | hwc->idx = PIC_NO_INDEX; | ||
1115 | |||
901 | /* Try to do all error checking before this point, as unwinding | 1116 | /* Try to do all error checking before this point, as unwinding |
902 | * state after grabbing the PMC is difficult. | 1117 | * state after grabbing the PMC is difficult. |
903 | */ | 1118 | */ |
@@ -910,15 +1125,6 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
910 | atomic64_set(&hwc->period_left, hwc->sample_period); | 1125 | atomic64_set(&hwc->period_left, hwc->sample_period); |
911 | } | 1126 | } |
912 | 1127 | ||
913 | if (pmap->pic_mask & PIC_UPPER) { | ||
914 | hwc->idx = PIC_UPPER_INDEX; | ||
915 | enc <<= sparc_pmu->upper_shift; | ||
916 | } else { | ||
917 | hwc->idx = PIC_LOWER_INDEX; | ||
918 | enc <<= sparc_pmu->lower_shift; | ||
919 | } | ||
920 | |||
921 | hwc->config |= enc; | ||
922 | return 0; | 1128 | return 0; |
923 | } | 1129 | } |
924 | 1130 | ||
@@ -968,7 +1174,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, | |||
968 | struct perf_sample_data data; | 1174 | struct perf_sample_data data; |
969 | struct cpu_hw_events *cpuc; | 1175 | struct cpu_hw_events *cpuc; |
970 | struct pt_regs *regs; | 1176 | struct pt_regs *regs; |
971 | int idx; | 1177 | int i; |
972 | 1178 | ||
973 | if (!atomic_read(&active_events)) | 1179 | if (!atomic_read(&active_events)) |
974 | return NOTIFY_DONE; | 1180 | return NOTIFY_DONE; |
@@ -983,16 +1189,26 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, | |||
983 | 1189 | ||
984 | regs = args->regs; | 1190 | regs = args->regs; |
985 | 1191 | ||
986 | data.addr = 0; | 1192 | perf_sample_data_init(&data, 0); |
987 | 1193 | ||
988 | cpuc = &__get_cpu_var(cpu_hw_events); | 1194 | cpuc = &__get_cpu_var(cpu_hw_events); |
989 | for (idx = 0; idx < MAX_HWEVENTS; idx++) { | 1195 | |
990 | struct perf_event *event = cpuc->events[idx]; | 1196 | /* If the PMU has the TOE IRQ enable bits, we need to do a |
1197 | * dummy write to the %pcr to clear the overflow bits and thus | ||
1198 | * the interrupt. | ||
1199 | * | ||
1200 | * Do this before we peek at the counters to determine | ||
1201 | * overflow so we don't lose any events. | ||
1202 | */ | ||
1203 | if (sparc_pmu->irq_bit) | ||
1204 | pcr_ops->write(cpuc->pcr); | ||
1205 | |||
1206 | for (i = 0; i < cpuc->n_events; i++) { | ||
1207 | struct perf_event *event = cpuc->event[i]; | ||
1208 | int idx = cpuc->current_idx[i]; | ||
991 | struct hw_perf_event *hwc; | 1209 | struct hw_perf_event *hwc; |
992 | u64 val; | 1210 | u64 val; |
993 | 1211 | ||
994 | if (!test_bit(idx, cpuc->active_mask)) | ||
995 | continue; | ||
996 | hwc = &event->hw; | 1212 | hwc = &event->hw; |
997 | val = sparc_perf_event_update(event, hwc, idx); | 1213 | val = sparc_perf_event_update(event, hwc, idx); |
998 | if (val & (1ULL << 31)) | 1214 | if (val & (1ULL << 31)) |
@@ -1044,10 +1260,122 @@ void __init init_hw_perf_events(void) | |||
1044 | 1260 | ||
1045 | pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type); | 1261 | pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type); |
1046 | 1262 | ||
1047 | /* All sparc64 PMUs currently have 2 events. But this simple | 1263 | /* All sparc64 PMUs currently have 2 events. */ |
1048 | * driver only supports one active event at a time. | 1264 | perf_max_events = 2; |
1049 | */ | ||
1050 | perf_max_events = 1; | ||
1051 | 1265 | ||
1052 | register_die_notifier(&perf_event_nmi_notifier); | 1266 | register_die_notifier(&perf_event_nmi_notifier); |
1053 | } | 1267 | } |
1268 | |||
1269 | static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip) | ||
1270 | { | ||
1271 | if (entry->nr < PERF_MAX_STACK_DEPTH) | ||
1272 | entry->ip[entry->nr++] = ip; | ||
1273 | } | ||
1274 | |||
1275 | static void perf_callchain_kernel(struct pt_regs *regs, | ||
1276 | struct perf_callchain_entry *entry) | ||
1277 | { | ||
1278 | unsigned long ksp, fp; | ||
1279 | |||
1280 | callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
1281 | callchain_store(entry, regs->tpc); | ||
1282 | |||
1283 | ksp = regs->u_regs[UREG_I6]; | ||
1284 | fp = ksp + STACK_BIAS; | ||
1285 | do { | ||
1286 | struct sparc_stackf *sf; | ||
1287 | struct pt_regs *regs; | ||
1288 | unsigned long pc; | ||
1289 | |||
1290 | if (!kstack_valid(current_thread_info(), fp)) | ||
1291 | break; | ||
1292 | |||
1293 | sf = (struct sparc_stackf *) fp; | ||
1294 | regs = (struct pt_regs *) (sf + 1); | ||
1295 | |||
1296 | if (kstack_is_trap_frame(current_thread_info(), regs)) { | ||
1297 | if (user_mode(regs)) | ||
1298 | break; | ||
1299 | pc = regs->tpc; | ||
1300 | fp = regs->u_regs[UREG_I6] + STACK_BIAS; | ||
1301 | } else { | ||
1302 | pc = sf->callers_pc; | ||
1303 | fp = (unsigned long)sf->fp + STACK_BIAS; | ||
1304 | } | ||
1305 | callchain_store(entry, pc); | ||
1306 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | ||
1307 | } | ||
1308 | |||
1309 | static void perf_callchain_user_64(struct pt_regs *regs, | ||
1310 | struct perf_callchain_entry *entry) | ||
1311 | { | ||
1312 | unsigned long ufp; | ||
1313 | |||
1314 | callchain_store(entry, PERF_CONTEXT_USER); | ||
1315 | callchain_store(entry, regs->tpc); | ||
1316 | |||
1317 | ufp = regs->u_regs[UREG_I6] + STACK_BIAS; | ||
1318 | do { | ||
1319 | struct sparc_stackf *usf, sf; | ||
1320 | unsigned long pc; | ||
1321 | |||
1322 | usf = (struct sparc_stackf *) ufp; | ||
1323 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | ||
1324 | break; | ||
1325 | |||
1326 | pc = sf.callers_pc; | ||
1327 | ufp = (unsigned long)sf.fp + STACK_BIAS; | ||
1328 | callchain_store(entry, pc); | ||
1329 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | ||
1330 | } | ||
1331 | |||
1332 | static void perf_callchain_user_32(struct pt_regs *regs, | ||
1333 | struct perf_callchain_entry *entry) | ||
1334 | { | ||
1335 | unsigned long ufp; | ||
1336 | |||
1337 | callchain_store(entry, PERF_CONTEXT_USER); | ||
1338 | callchain_store(entry, regs->tpc); | ||
1339 | |||
1340 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; | ||
1341 | do { | ||
1342 | struct sparc_stackf32 *usf, sf; | ||
1343 | unsigned long pc; | ||
1344 | |||
1345 | usf = (struct sparc_stackf32 *) ufp; | ||
1346 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | ||
1347 | break; | ||
1348 | |||
1349 | pc = sf.callers_pc; | ||
1350 | ufp = (unsigned long)sf.fp; | ||
1351 | callchain_store(entry, pc); | ||
1352 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | ||
1353 | } | ||
1354 | |||
1355 | /* Like powerpc we can't get PMU interrupts within the PMU handler, | ||
1356 | * so no need for separate NMI and IRQ chains as on x86. | ||
1357 | */ | ||
1358 | static DEFINE_PER_CPU(struct perf_callchain_entry, callchain); | ||
1359 | |||
1360 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
1361 | { | ||
1362 | struct perf_callchain_entry *entry = &__get_cpu_var(callchain); | ||
1363 | |||
1364 | entry->nr = 0; | ||
1365 | if (!user_mode(regs)) { | ||
1366 | stack_trace_flush(); | ||
1367 | perf_callchain_kernel(regs, entry); | ||
1368 | if (current->mm) | ||
1369 | regs = task_pt_regs(current); | ||
1370 | else | ||
1371 | regs = NULL; | ||
1372 | } | ||
1373 | if (regs) { | ||
1374 | flushw_user(); | ||
1375 | if (test_thread_flag(TIF_32BIT)) | ||
1376 | perf_callchain_user_32(regs, entry); | ||
1377 | else | ||
1378 | perf_callchain_user_64(regs, entry); | ||
1379 | } | ||
1380 | return entry; | ||
1381 | } | ||
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 2830b415e214..40e29fc8a4d6 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -17,13 +17,13 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/stddef.h> | 18 | #include <linux/stddef.h> |
19 | #include <linux/ptrace.h> | 19 | #include <linux/ptrace.h> |
20 | #include <linux/slab.h> | ||
21 | #include <linux/user.h> | 20 | #include <linux/user.h> |
22 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
23 | #include <linux/reboot.h> | 22 | #include <linux/reboot.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/slab.h> | ||
27 | 27 | ||
28 | #include <asm/auxio.h> | 28 | #include <asm/auxio.h> |
29 | #include <asm/oplib.h> | 29 | #include <asm/oplib.h> |
@@ -526,7 +526,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
526 | * Set some valid stack frames to give to the child. | 526 | * Set some valid stack frames to give to the child. |
527 | */ | 527 | */ |
528 | childstack = (struct sparc_stackf __user *) | 528 | childstack = (struct sparc_stackf __user *) |
529 | (sp & ~0x7UL); | 529 | (sp & ~0xfUL); |
530 | parentstack = (struct sparc_stackf __user *) | 530 | parentstack = (struct sparc_stackf __user *) |
531 | regs->u_regs[UREG_FP]; | 531 | regs->u_regs[UREG_FP]; |
532 | 532 | ||
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 18d67854a1b8..a5cf3864b31f 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -352,12 +352,6 @@ void exit_thread(void) | |||
352 | else | 352 | else |
353 | t->utraps[0]--; | 353 | t->utraps[0]--; |
354 | } | 354 | } |
355 | |||
356 | if (test_and_clear_thread_flag(TIF_PERFCTR)) { | ||
357 | t->user_cntd0 = t->user_cntd1 = NULL; | ||
358 | t->pcr_reg = 0; | ||
359 | write_pcr(0); | ||
360 | } | ||
361 | } | 355 | } |
362 | 356 | ||
363 | void flush_thread(void) | 357 | void flush_thread(void) |
@@ -365,27 +359,12 @@ void flush_thread(void) | |||
365 | struct thread_info *t = current_thread_info(); | 359 | struct thread_info *t = current_thread_info(); |
366 | struct mm_struct *mm; | 360 | struct mm_struct *mm; |
367 | 361 | ||
368 | if (test_ti_thread_flag(t, TIF_ABI_PENDING)) { | ||
369 | clear_ti_thread_flag(t, TIF_ABI_PENDING); | ||
370 | if (test_ti_thread_flag(t, TIF_32BIT)) | ||
371 | clear_ti_thread_flag(t, TIF_32BIT); | ||
372 | else | ||
373 | set_ti_thread_flag(t, TIF_32BIT); | ||
374 | } | ||
375 | |||
376 | mm = t->task->mm; | 362 | mm = t->task->mm; |
377 | if (mm) | 363 | if (mm) |
378 | tsb_context_switch(mm); | 364 | tsb_context_switch(mm); |
379 | 365 | ||
380 | set_thread_wsaved(0); | 366 | set_thread_wsaved(0); |
381 | 367 | ||
382 | /* Turn off performance counters if on. */ | ||
383 | if (test_and_clear_thread_flag(TIF_PERFCTR)) { | ||
384 | t->user_cntd0 = t->user_cntd1 = NULL; | ||
385 | t->pcr_reg = 0; | ||
386 | write_pcr(0); | ||
387 | } | ||
388 | |||
389 | /* Clear FPU register state. */ | 368 | /* Clear FPU register state. */ |
390 | t->fpsaved[0] = 0; | 369 | t->fpsaved[0] = 0; |
391 | 370 | ||
@@ -406,11 +385,11 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | |||
406 | } else | 385 | } else |
407 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); | 386 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); |
408 | 387 | ||
409 | /* Now 8-byte align the stack as this is mandatory in the | 388 | /* Now align the stack as this is mandatory in the Sparc ABI |
410 | * Sparc ABI due to how register windows work. This hides | 389 | * due to how register windows work. This hides the |
411 | * the restriction from thread libraries etc. -DaveM | 390 | * restriction from thread libraries etc. |
412 | */ | 391 | */ |
413 | csp &= ~7UL; | 392 | csp &= ~15UL; |
414 | 393 | ||
415 | distance = fp - psp; | 394 | distance = fp - psp; |
416 | rval = (csp - distance); | 395 | rval = (csp - distance); |
@@ -599,16 +578,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
599 | t->kregs->u_regs[UREG_FP] = | 578 | t->kregs->u_regs[UREG_FP] = |
600 | ((unsigned long) child_sf) - STACK_BIAS; | 579 | ((unsigned long) child_sf) - STACK_BIAS; |
601 | 580 | ||
602 | /* Special case, if we are spawning a kernel thread from | ||
603 | * a userspace task (usermode helper, NFS or similar), we | ||
604 | * must disable performance counters in the child because | ||
605 | * the address space and protection realm are changing. | ||
606 | */ | ||
607 | if (t->flags & _TIF_PERFCTR) { | ||
608 | t->user_cntd0 = t->user_cntd1 = NULL; | ||
609 | t->pcr_reg = 0; | ||
610 | t->flags &= ~_TIF_PERFCTR; | ||
611 | } | ||
612 | t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); | 581 | t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); |
613 | t->kregs->u_regs[UREG_G6] = (unsigned long) t; | 582 | t->kregs->u_regs[UREG_G6] = (unsigned long) t; |
614 | t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; | 583 | t->kregs->u_regs[UREG_G4] = (unsigned long) t->task; |
diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h index 453397fe5e14..a8591ef2636d 100644 --- a/arch/sparc/kernel/prom.h +++ b/arch/sparc/kernel/prom.h | |||
@@ -4,9 +4,6 @@ | |||
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | #include <asm/prom.h> | 5 | #include <asm/prom.h> |
6 | 6 | ||
7 | extern struct device_node *allnodes; /* temporary while merging */ | ||
8 | extern rwlock_t devtree_lock; /* temporary while merging */ | ||
9 | |||
10 | extern void * prom_early_alloc(unsigned long size); | 7 | extern void * prom_early_alloc(unsigned long size); |
11 | extern void irq_trans_init(struct device_node *dp); | 8 | extern void irq_trans_init(struct device_node *dp); |
12 | 9 | ||
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index d80a65d9e893..57ac9e28be0c 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c | |||
@@ -37,18 +37,6 @@ EXPORT_SYMBOL(of_console_path); | |||
37 | char *of_console_options; | 37 | char *of_console_options; |
38 | EXPORT_SYMBOL(of_console_options); | 38 | EXPORT_SYMBOL(of_console_options); |
39 | 39 | ||
40 | struct device_node *of_find_node_by_phandle(phandle handle) | ||
41 | { | ||
42 | struct device_node *np; | ||
43 | |||
44 | for (np = allnodes; np; np = np->allnext) | ||
45 | if (np->node == handle) | ||
46 | break; | ||
47 | |||
48 | return np; | ||
49 | } | ||
50 | EXPORT_SYMBOL(of_find_node_by_phandle); | ||
51 | |||
52 | int of_getintprop_default(struct device_node *np, const char *name, int def) | 40 | int of_getintprop_default(struct device_node *np, const char *name, int def) |
53 | { | 41 | { |
54 | struct property *prop; | 42 | struct property *prop; |
@@ -89,7 +77,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len | |||
89 | void *old_val = prop->value; | 77 | void *old_val = prop->value; |
90 | int ret; | 78 | int ret; |
91 | 79 | ||
92 | ret = prom_setprop(dp->node, name, val, len); | 80 | ret = prom_setprop(dp->phandle, name, val, len); |
93 | 81 | ||
94 | err = -EINVAL; | 82 | err = -EINVAL; |
95 | if (ret >= 0) { | 83 | if (ret >= 0) { |
@@ -236,7 +224,7 @@ static struct device_node * __init prom_create_node(phandle node, | |||
236 | 224 | ||
237 | dp->name = get_one_property(node, "name"); | 225 | dp->name = get_one_property(node, "name"); |
238 | dp->type = get_one_property(node, "device_type"); | 226 | dp->type = get_one_property(node, "device_type"); |
239 | dp->node = node; | 227 | dp->phandle = node; |
240 | 228 | ||
241 | dp->properties = build_prop_list(node); | 229 | dp->properties = build_prop_list(node); |
242 | 230 | ||
@@ -313,7 +301,7 @@ void __init prom_build_devicetree(void) | |||
313 | 301 | ||
314 | nextp = &allnodes->allnext; | 302 | nextp = &allnodes->allnext; |
315 | allnodes->child = prom_build_tree(allnodes, | 303 | allnodes->child = prom_build_tree(allnodes, |
316 | prom_getchild(allnodes->node), | 304 | prom_getchild(allnodes->phandle), |
317 | &nextp); | 305 | &nextp); |
318 | of_console_init(); | 306 | of_console_init(); |
319 | 307 | ||
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index 7e3dfd9bb97e..e608f397e11f 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c | |||
@@ -65,6 +65,7 @@ static int genregs32_get(struct task_struct *target, | |||
65 | *k++ = regs->u_regs[pos++]; | 65 | *k++ = regs->u_regs[pos++]; |
66 | 66 | ||
67 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; | 67 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; |
68 | reg_window -= 16; | ||
68 | for (; count > 0 && pos < 32; count--) { | 69 | for (; count > 0 && pos < 32; count--) { |
69 | if (get_user(*k++, ®_window[pos++])) | 70 | if (get_user(*k++, ®_window[pos++])) |
70 | return -EFAULT; | 71 | return -EFAULT; |
@@ -76,6 +77,7 @@ static int genregs32_get(struct task_struct *target, | |||
76 | } | 77 | } |
77 | 78 | ||
78 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; | 79 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; |
80 | reg_window -= 16; | ||
79 | for (; count > 0 && pos < 32; count--) { | 81 | for (; count > 0 && pos < 32; count--) { |
80 | if (get_user(reg, ®_window[pos++]) || | 82 | if (get_user(reg, ®_window[pos++]) || |
81 | put_user(reg, u++)) | 83 | put_user(reg, u++)) |
@@ -141,6 +143,7 @@ static int genregs32_set(struct task_struct *target, | |||
141 | regs->u_regs[pos++] = *k++; | 143 | regs->u_regs[pos++] = *k++; |
142 | 144 | ||
143 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; | 145 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; |
146 | reg_window -= 16; | ||
144 | for (; count > 0 && pos < 32; count--) { | 147 | for (; count > 0 && pos < 32; count--) { |
145 | if (put_user(*k++, ®_window[pos++])) | 148 | if (put_user(*k++, ®_window[pos++])) |
146 | return -EFAULT; | 149 | return -EFAULT; |
@@ -153,6 +156,7 @@ static int genregs32_set(struct task_struct *target, | |||
153 | } | 156 | } |
154 | 157 | ||
155 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; | 158 | reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; |
159 | reg_window -= 16; | ||
156 | for (; count > 0 && pos < 32; count--) { | 160 | for (; count > 0 && pos < 32; count--) { |
157 | if (get_user(reg, u++) || | 161 | if (get_user(reg, u++) || |
158 | put_user(reg, ®_window[pos++])) | 162 | put_user(reg, ®_window[pos++])) |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 4ae91dc2feb9..aa90da08bf61 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/signal.h> | 23 | #include <linux/signal.h> |
24 | #include <linux/regset.h> | 24 | #include <linux/regset.h> |
25 | #include <linux/tracehook.h> | 25 | #include <linux/tracehook.h> |
26 | #include <trace/syscall.h> | ||
26 | #include <linux/compat.h> | 27 | #include <linux/compat.h> |
27 | #include <linux/elf.h> | 28 | #include <linux/elf.h> |
28 | 29 | ||
@@ -37,6 +38,9 @@ | |||
37 | #include <asm/cpudata.h> | 38 | #include <asm/cpudata.h> |
38 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
39 | 40 | ||
41 | #define CREATE_TRACE_POINTS | ||
42 | #include <trace/events/syscalls.h> | ||
43 | |||
40 | #include "entry.h" | 44 | #include "entry.h" |
41 | 45 | ||
42 | /* #define ALLOW_INIT_TRACING */ | 46 | /* #define ALLOW_INIT_TRACING */ |
@@ -488,6 +492,7 @@ static int genregs32_get(struct task_struct *target, | |||
488 | *k++ = regs->u_regs[pos++]; | 492 | *k++ = regs->u_regs[pos++]; |
489 | 493 | ||
490 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; | 494 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; |
495 | reg_window -= 16; | ||
491 | if (target == current) { | 496 | if (target == current) { |
492 | for (; count > 0 && pos < 32; count--) { | 497 | for (; count > 0 && pos < 32; count--) { |
493 | if (get_user(*k++, ®_window[pos++])) | 498 | if (get_user(*k++, ®_window[pos++])) |
@@ -512,6 +517,7 @@ static int genregs32_get(struct task_struct *target, | |||
512 | } | 517 | } |
513 | 518 | ||
514 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; | 519 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; |
520 | reg_window -= 16; | ||
515 | if (target == current) { | 521 | if (target == current) { |
516 | for (; count > 0 && pos < 32; count--) { | 522 | for (; count > 0 && pos < 32; count--) { |
517 | if (get_user(reg, ®_window[pos++]) || | 523 | if (get_user(reg, ®_window[pos++]) || |
@@ -595,6 +601,7 @@ static int genregs32_set(struct task_struct *target, | |||
595 | regs->u_regs[pos++] = *k++; | 601 | regs->u_regs[pos++] = *k++; |
596 | 602 | ||
597 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; | 603 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; |
604 | reg_window -= 16; | ||
598 | if (target == current) { | 605 | if (target == current) { |
599 | for (; count > 0 && pos < 32; count--) { | 606 | for (; count > 0 && pos < 32; count--) { |
600 | if (put_user(*k++, ®_window[pos++])) | 607 | if (put_user(*k++, ®_window[pos++])) |
@@ -621,6 +628,7 @@ static int genregs32_set(struct task_struct *target, | |||
621 | } | 628 | } |
622 | 629 | ||
623 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; | 630 | reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; |
631 | reg_window -= 16; | ||
624 | if (target == current) { | 632 | if (target == current) { |
625 | for (; count > 0 && pos < 32; count--) { | 633 | for (; count > 0 && pos < 32; count--) { |
626 | if (get_user(reg, u++) || | 634 | if (get_user(reg, u++) || |
@@ -1059,6 +1067,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) | |||
1059 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1067 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
1060 | ret = tracehook_report_syscall_entry(regs); | 1068 | ret = tracehook_report_syscall_entry(regs); |
1061 | 1069 | ||
1070 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | ||
1071 | trace_sys_enter(regs, regs->u_regs[UREG_G1]); | ||
1072 | |||
1062 | if (unlikely(current->audit_context) && !ret) | 1073 | if (unlikely(current->audit_context) && !ret) |
1063 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? | 1074 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? |
1064 | AUDIT_ARCH_SPARC : | 1075 | AUDIT_ARCH_SPARC : |
@@ -1084,6 +1095,9 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) | |||
1084 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); | 1095 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); |
1085 | } | 1096 | } |
1086 | 1097 | ||
1098 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | ||
1099 | trace_sys_exit(regs, regs->u_regs[UREG_G1]); | ||
1100 | |||
1087 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1101 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
1088 | tracehook_report_syscall_exit(regs, 0); | 1102 | tracehook_report_syscall_exit(regs, 0); |
1089 | } | 1103 | } |
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index fd3cee4d117c..090b9e9ad5e3 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S | |||
@@ -65,48 +65,6 @@ __handle_user_windows: | |||
65 | ba,pt %xcc, __handle_user_windows_continue | 65 | ba,pt %xcc, __handle_user_windows_continue |
66 | 66 | ||
67 | andn %l1, %l4, %l1 | 67 | andn %l1, %l4, %l1 |
68 | __handle_perfctrs: | ||
69 | call update_perfctrs | ||
70 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
71 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
72 | ldub [%g6 + TI_WSAVED], %o2 | ||
73 | brz,pt %o2, 1f | ||
74 | nop | ||
75 | /* Redo userwin+sched+sig checks */ | ||
76 | call fault_in_user_windows | ||
77 | |||
78 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
79 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
80 | ldx [%g6 + TI_FLAGS], %l0 | ||
81 | andcc %l0, _TIF_NEED_RESCHED, %g0 | ||
82 | be,pt %xcc, 1f | ||
83 | |||
84 | nop | ||
85 | call schedule | ||
86 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
87 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
88 | ldx [%g6 + TI_FLAGS], %l0 | ||
89 | 1: andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 | ||
90 | |||
91 | be,pt %xcc, __handle_perfctrs_continue | ||
92 | sethi %hi(TSTATE_PEF), %o0 | ||
93 | mov %l5, %o1 | ||
94 | add %sp, PTREGS_OFF, %o0 | ||
95 | mov %l0, %o2 | ||
96 | call do_notify_resume | ||
97 | |||
98 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
99 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | ||
100 | /* Signal delivery can modify pt_regs tstate, so we must | ||
101 | * reload it. | ||
102 | */ | ||
103 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 | ||
104 | sethi %hi(0xf << 20), %l4 | ||
105 | and %l1, %l4, %l4 | ||
106 | andn %l1, %l4, %l1 | ||
107 | ba,pt %xcc, __handle_perfctrs_continue | ||
108 | |||
109 | sethi %hi(TSTATE_PEF), %o0 | ||
110 | __handle_userfpu: | 68 | __handle_userfpu: |
111 | rd %fprs, %l5 | 69 | rd %fprs, %l5 |
112 | andcc %l5, FPRS_FEF, %g0 | 70 | andcc %l5, FPRS_FEF, %g0 |
@@ -149,11 +107,11 @@ rtrap_nmi: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 | |||
149 | rtrap_irq: | 107 | rtrap_irq: |
150 | rtrap: | 108 | rtrap: |
151 | #ifndef CONFIG_SMP | 109 | #ifndef CONFIG_SMP |
152 | sethi %hi(per_cpu____cpu_data), %l0 | 110 | sethi %hi(__cpu_data), %l0 |
153 | lduw [%l0 + %lo(per_cpu____cpu_data)], %l1 | 111 | lduw [%l0 + %lo(__cpu_data)], %l1 |
154 | #else | 112 | #else |
155 | sethi %hi(per_cpu____cpu_data), %l0 | 113 | sethi %hi(__cpu_data), %l0 |
156 | or %l0, %lo(per_cpu____cpu_data), %l0 | 114 | or %l0, %lo(__cpu_data), %l0 |
157 | lduw [%l0 + %g5], %l1 | 115 | lduw [%l0 + %g5], %l1 |
158 | #endif | 116 | #endif |
159 | cmp %l1, 0 | 117 | cmp %l1, 0 |
@@ -172,7 +130,17 @@ rtrap_xcall: | |||
172 | nop | 130 | nop |
173 | call trace_hardirqs_on | 131 | call trace_hardirqs_on |
174 | nop | 132 | nop |
175 | wrpr %l4, %pil | 133 | /* Do not actually set the %pil here. We will do that |
134 | * below after we clear PSTATE_IE in the %pstate register. | ||
135 | * If we re-enable interrupts here, we can recurse down | ||
136 | * the hardirq stack potentially endlessly, causing a | ||
137 | * stack overflow. | ||
138 | * | ||
139 | * It is tempting to put this test and trace_hardirqs_on | ||
140 | * call at the 'rt_continue' label, but that will not work | ||
141 | * as that path hits unconditionally and we do not want to | ||
142 | * execute this in NMI return paths, for example. | ||
143 | */ | ||
176 | #endif | 144 | #endif |
177 | rtrap_no_irq_enable: | 145 | rtrap_no_irq_enable: |
178 | andcc %l1, TSTATE_PRIV, %l3 | 146 | andcc %l1, TSTATE_PRIV, %l3 |
@@ -191,9 +159,9 @@ rtrap_no_irq_enable: | |||
191 | * take until the next local IRQ before the signal/resched | 159 | * take until the next local IRQ before the signal/resched |
192 | * event would be handled. | 160 | * event would be handled. |
193 | * | 161 | * |
194 | * This also means that if we have to deal with performance | 162 | * This also means that if we have to deal with user |
195 | * counters or user windows, we have to redo all of these | 163 | * windows, we have to redo all of these sched+signal checks |
196 | * sched+signal checks with IRQs disabled. | 164 | * with IRQs disabled. |
197 | */ | 165 | */ |
198 | to_user: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 166 | to_user: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
199 | wrpr 0, %pil | 167 | wrpr 0, %pil |
@@ -214,12 +182,8 @@ __handle_signal_continue: | |||
214 | brnz,pn %o2, __handle_user_windows | 182 | brnz,pn %o2, __handle_user_windows |
215 | nop | 183 | nop |
216 | __handle_user_windows_continue: | 184 | __handle_user_windows_continue: |
217 | ldx [%g6 + TI_FLAGS], %l5 | ||
218 | andcc %l5, _TIF_PERFCTR, %g0 | ||
219 | sethi %hi(TSTATE_PEF), %o0 | 185 | sethi %hi(TSTATE_PEF), %o0 |
220 | bne,pn %xcc, __handle_perfctrs | 186 | andcc %l1, %o0, %g0 |
221 | __handle_perfctrs_continue: | ||
222 | andcc %l1, %o0, %g0 | ||
223 | 187 | ||
224 | /* This fpdepth clear is necessary for non-syscall rtraps only */ | 188 | /* This fpdepth clear is necessary for non-syscall rtraps only */ |
225 | user_nowork: | 189 | user_nowork: |
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 9be2af55c5cd..b22ce6100403 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c | |||
@@ -95,8 +95,6 @@ static void prom_sync_me(void) | |||
95 | "nop\n\t" | 95 | "nop\n\t" |
96 | "nop\n\t" : : "r" (prom_tbr)); | 96 | "nop\n\t" : : "r" (prom_tbr)); |
97 | local_irq_restore(flags); | 97 | local_irq_restore(flags); |
98 | |||
99 | return; | ||
100 | } | 98 | } |
101 | 99 | ||
102 | static unsigned int boot_flags __initdata = 0; | 100 | static unsigned int boot_flags __initdata = 0; |
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 21180339cb09..5f72de67588b 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/stddef.h> | 12 | #include <linux/stddef.h> |
13 | #include <linux/unistd.h> | 13 | #include <linux/unistd.h> |
14 | #include <linux/ptrace.h> | 14 | #include <linux/ptrace.h> |
15 | #include <linux/slab.h> | ||
16 | #include <asm/smp.h> | 15 | #include <asm/smp.h> |
17 | #include <linux/user.h> | 16 | #include <linux/user.h> |
18 | #include <linux/screen_info.h> | 17 | #include <linux/screen_info.h> |
@@ -46,6 +45,7 @@ | |||
46 | #include <asm/setup.h> | 45 | #include <asm/setup.h> |
47 | #include <asm/mmu.h> | 46 | #include <asm/mmu.h> |
48 | #include <asm/ns87303.h> | 47 | #include <asm/ns87303.h> |
48 | #include <asm/btext.h> | ||
49 | 49 | ||
50 | #ifdef CONFIG_IP_PNP | 50 | #ifdef CONFIG_IP_PNP |
51 | #include <net/ipconfig.h> | 51 | #include <net/ipconfig.h> |
@@ -286,7 +286,10 @@ void __init setup_arch(char **cmdline_p) | |||
286 | parse_early_param(); | 286 | parse_early_param(); |
287 | 287 | ||
288 | boot_flags_init(*cmdline_p); | 288 | boot_flags_init(*cmdline_p); |
289 | register_console(&prom_early_console); | 289 | #ifdef CONFIG_EARLYFB |
290 | if (btext_find_display()) | ||
291 | #endif | ||
292 | register_console(&prom_early_console); | ||
290 | 293 | ||
291 | if (tlb_type == hypervisor) | 294 | if (tlb_type == hypervisor) |
292 | printk("ARCH: SUN4V\n"); | 295 | printk("ARCH: SUN4V\n"); |
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index ba5b09ad6666..ea22cd373c64 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -120,8 +120,8 @@ struct rt_signal_frame32 { | |||
120 | }; | 120 | }; |
121 | 121 | ||
122 | /* Align macros */ | 122 | /* Align macros */ |
123 | #define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 7) & (~7))) | 123 | #define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15))) |
124 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7))) | 124 | #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15))) |
125 | 125 | ||
126 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) | 126 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) |
127 | { | 127 | { |
@@ -420,15 +420,17 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns | |||
420 | sp = current->sas_ss_sp + current->sas_ss_size; | 420 | sp = current->sas_ss_sp + current->sas_ss_size; |
421 | } | 421 | } |
422 | 422 | ||
423 | sp -= framesize; | ||
424 | |||
423 | /* Always align the stack frame. This handles two cases. First, | 425 | /* Always align the stack frame. This handles two cases. First, |
424 | * sigaltstack need not be mindful of platform specific stack | 426 | * sigaltstack need not be mindful of platform specific stack |
425 | * alignment. Second, if we took this signal because the stack | 427 | * alignment. Second, if we took this signal because the stack |
426 | * is not aligned properly, we'd like to take the signal cleanly | 428 | * is not aligned properly, we'd like to take the signal cleanly |
427 | * and report that. | 429 | * and report that. |
428 | */ | 430 | */ |
429 | sp &= ~7UL; | 431 | sp &= ~15UL; |
430 | 432 | ||
431 | return (void __user *)(sp - framesize); | 433 | return (void __user *) sp; |
432 | } | 434 | } |
433 | 435 | ||
434 | static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | 436 | static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) |
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 7ce1a1005b1d..9882df92ba0a 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
@@ -267,15 +267,17 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re | |||
267 | sp = current->sas_ss_sp + current->sas_ss_size; | 267 | sp = current->sas_ss_sp + current->sas_ss_size; |
268 | } | 268 | } |
269 | 269 | ||
270 | sp -= framesize; | ||
271 | |||
270 | /* Always align the stack frame. This handles two cases. First, | 272 | /* Always align the stack frame. This handles two cases. First, |
271 | * sigaltstack need not be mindful of platform specific stack | 273 | * sigaltstack need not be mindful of platform specific stack |
272 | * alignment. Second, if we took this signal because the stack | 274 | * alignment. Second, if we took this signal because the stack |
273 | * is not aligned properly, we'd like to take the signal cleanly | 275 | * is not aligned properly, we'd like to take the signal cleanly |
274 | * and report that. | 276 | * and report that. |
275 | */ | 277 | */ |
276 | sp &= ~7UL; | 278 | sp &= ~15UL; |
277 | 279 | ||
278 | return (void __user *)(sp - framesize); | 280 | return (void __user *) sp; |
279 | } | 281 | } |
280 | 282 | ||
281 | static inline int | 283 | static inline int |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 647afbda7ae1..9fa48c30037e 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -353,7 +353,7 @@ segv: | |||
353 | /* Checks if the fp is valid */ | 353 | /* Checks if the fp is valid */ |
354 | static int invalid_frame_pointer(void __user *fp, int fplen) | 354 | static int invalid_frame_pointer(void __user *fp, int fplen) |
355 | { | 355 | { |
356 | if (((unsigned long) fp) & 7) | 356 | if (((unsigned long) fp) & 15) |
357 | return 1; | 357 | return 1; |
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
@@ -396,15 +396,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * | |||
396 | sp = current->sas_ss_sp + current->sas_ss_size; | 396 | sp = current->sas_ss_sp + current->sas_ss_size; |
397 | } | 397 | } |
398 | 398 | ||
399 | sp -= framesize; | ||
400 | |||
399 | /* Always align the stack frame. This handles two cases. First, | 401 | /* Always align the stack frame. This handles two cases. First, |
400 | * sigaltstack need not be mindful of platform specific stack | 402 | * sigaltstack need not be mindful of platform specific stack |
401 | * alignment. Second, if we took this signal because the stack | 403 | * alignment. Second, if we took this signal because the stack |
402 | * is not aligned properly, we'd like to take the signal cleanly | 404 | * is not aligned properly, we'd like to take the signal cleanly |
403 | * and report that. | 405 | * and report that. |
404 | */ | 406 | */ |
405 | sp &= ~7UL; | 407 | sp &= ~15UL; |
406 | 408 | ||
407 | return (void __user *)(sp - framesize); | 409 | return (void __user *) sp; |
408 | } | 410 | } |
409 | 411 | ||
410 | static inline void | 412 | static inline void |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 132d81fb2616..91c10fb70858 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/cacheflush.h> | 32 | #include <asm/cacheflush.h> |
33 | #include <asm/tlbflush.h> | 33 | #include <asm/tlbflush.h> |
34 | #include <asm/cpudata.h> | 34 | #include <asm/cpudata.h> |
35 | #include <asm/leon.h> | ||
35 | 36 | ||
36 | #include "irq.h" | 37 | #include "irq.h" |
37 | 38 | ||
@@ -96,6 +97,9 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
96 | case sun4d: | 97 | case sun4d: |
97 | smp4d_smp_done(); | 98 | smp4d_smp_done(); |
98 | break; | 99 | break; |
100 | case sparc_leon: | ||
101 | leon_smp_done(); | ||
102 | break; | ||
99 | case sun4e: | 103 | case sun4e: |
100 | printk("SUN4E\n"); | 104 | printk("SUN4E\n"); |
101 | BUG(); | 105 | BUG(); |
@@ -306,6 +310,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
306 | case sun4d: | 310 | case sun4d: |
307 | smp4d_boot_cpus(); | 311 | smp4d_boot_cpus(); |
308 | break; | 312 | break; |
313 | case sparc_leon: | ||
314 | leon_boot_cpus(); | ||
315 | break; | ||
309 | case sun4e: | 316 | case sun4e: |
310 | printk("SUN4E\n"); | 317 | printk("SUN4E\n"); |
311 | BUG(); | 318 | BUG(); |
@@ -376,6 +383,9 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
376 | case sun4d: | 383 | case sun4d: |
377 | ret = smp4d_boot_one_cpu(cpu); | 384 | ret = smp4d_boot_one_cpu(cpu); |
378 | break; | 385 | break; |
386 | case sparc_leon: | ||
387 | ret = leon_boot_one_cpu(cpu); | ||
388 | break; | ||
379 | case sun4e: | 389 | case sun4e: |
380 | printk("SUN4E\n"); | 390 | printk("SUN4E\n"); |
381 | BUG(); | 391 | BUG(); |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index aa36223497b9..b6a2b8f47040 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -22,7 +22,9 @@ | |||
22 | #include <linux/profile.h> | 22 | #include <linux/profile.h> |
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
25 | #include <linux/ftrace.h> | ||
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
27 | #include <linux/slab.h> | ||
26 | 28 | ||
27 | #include <asm/head.h> | 29 | #include <asm/head.h> |
28 | #include <asm/ptrace.h> | 30 | #include <asm/ptrace.h> |
@@ -370,7 +372,7 @@ static int __cpuinit smp_boot_one_cpu(unsigned int cpu) | |||
370 | } else { | 372 | } else { |
371 | struct device_node *dp = of_find_node_by_cpuid(cpu); | 373 | struct device_node *dp = of_find_node_by_cpuid(cpu); |
372 | 374 | ||
373 | prom_startcpu(dp->node, entry, cookie); | 375 | prom_startcpu(dp->phandle, entry, cookie); |
374 | } | 376 | } |
375 | 377 | ||
376 | for (timeout = 0; timeout < 50000; timeout++) { | 378 | for (timeout = 0; timeout < 50000; timeout++) { |
@@ -822,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu) | |||
822 | &cpumask_of_cpu(cpu)); | 824 | &cpumask_of_cpu(cpu)); |
823 | } | 825 | } |
824 | 826 | ||
825 | void smp_call_function_client(int irq, struct pt_regs *regs) | 827 | void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs) |
826 | { | 828 | { |
827 | clear_softint(1 << irq); | 829 | clear_softint(1 << irq); |
828 | generic_smp_call_function_interrupt(); | 830 | generic_smp_call_function_interrupt(); |
829 | } | 831 | } |
830 | 832 | ||
831 | void smp_call_function_single_client(int irq, struct pt_regs *regs) | 833 | void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs) |
832 | { | 834 | { |
833 | clear_softint(1 << irq); | 835 | clear_softint(1 << irq); |
834 | generic_smp_call_function_single_interrupt(); | 836 | generic_smp_call_function_single_interrupt(); |
@@ -964,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page) | |||
964 | put_cpu(); | 966 | put_cpu(); |
965 | } | 967 | } |
966 | 968 | ||
967 | void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) | 969 | void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) |
968 | { | 970 | { |
969 | struct mm_struct *mm; | 971 | struct mm_struct *mm; |
970 | unsigned long flags; | 972 | unsigned long flags; |
@@ -1148,7 +1150,7 @@ void smp_release(void) | |||
1148 | */ | 1150 | */ |
1149 | extern void prom_world(int); | 1151 | extern void prom_world(int); |
1150 | 1152 | ||
1151 | void smp_penguin_jailcell(int irq, struct pt_regs *regs) | 1153 | void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs) |
1152 | { | 1154 | { |
1153 | clear_softint(1 << irq); | 1155 | clear_softint(1 << irq); |
1154 | 1156 | ||
@@ -1364,7 +1366,7 @@ void smp_send_reschedule(int cpu) | |||
1364 | &cpumask_of_cpu(cpu)); | 1366 | &cpumask_of_cpu(cpu)); |
1365 | } | 1367 | } |
1366 | 1368 | ||
1367 | void smp_receive_signal_client(int irq, struct pt_regs *regs) | 1369 | void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) |
1368 | { | 1370 | { |
1369 | clear_softint(1 << irq); | 1371 | clear_softint(1 << irq); |
1370 | } | 1372 | } |
diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 0f26066a08d9..372ad59c4cba 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c | |||
@@ -38,17 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); | |||
38 | EXPORT_SYMBOL(sun4v_niagara2_getperf); | 38 | EXPORT_SYMBOL(sun4v_niagara2_getperf); |
39 | EXPORT_SYMBOL(sun4v_niagara2_setperf); | 39 | EXPORT_SYMBOL(sun4v_niagara2_setperf); |
40 | 40 | ||
41 | #ifdef CONFIG_PCI | ||
42 | /* inline functions in asm/pci_64.h */ | ||
43 | EXPORT_SYMBOL(pci_alloc_consistent); | ||
44 | EXPORT_SYMBOL(pci_free_consistent); | ||
45 | EXPORT_SYMBOL(pci_map_single); | ||
46 | EXPORT_SYMBOL(pci_unmap_single); | ||
47 | EXPORT_SYMBOL(pci_map_sg); | ||
48 | EXPORT_SYMBOL(pci_unmap_sg); | ||
49 | EXPORT_SYMBOL(pci_dma_sync_single_for_cpu); | ||
50 | EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu); | ||
51 | #endif | ||
52 | |||
53 | /* Exporting a symbol from /init/main.c */ | 41 | /* Exporting a symbol from /init/main.c */ |
54 | EXPORT_SYMBOL(saved_command_line); | 42 | EXPORT_SYMBOL(saved_command_line); |
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index bc3adbf79c6a..892fb884910a 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/slab.h> | ||
20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
21 | #include <linux/of.h> | 20 | #include <linux/of.h> |
22 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 68791cad7b74..482f2ab92692 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -194,7 +194,7 @@ int __cpuinit smp4d_boot_one_cpu(int i) | |||
194 | smp_penguin_ctable.reg_size = 0; | 194 | smp_penguin_ctable.reg_size = 0; |
195 | 195 | ||
196 | /* whirrr, whirrr, whirrrrrrrrr... */ | 196 | /* whirrr, whirrr, whirrrrrrrrr... */ |
197 | SMP_PRINTK(("Starting CPU %d at %p \n", i, entry)); | 197 | SMP_PRINTK(("Starting CPU %d at %p\n", i, entry)); |
198 | local_flush_cache_all(); | 198 | local_flush_cache_all(); |
199 | prom_startcpu(cpu_node, | 199 | prom_startcpu(cpu_node, |
200 | &smp_penguin_ctable, 0, (char *)entry); | 200 | &smp_penguin_ctable, 0, (char *)entry); |
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 301892e2d718..7f3b97ff62c1 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/slab.h> | ||
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
22 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
23 | #include <linux/of.h> | 22 | #include <linux/of.h> |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index e7061138c98a..46a76ba3fb4b 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
@@ -51,7 +51,6 @@ SIGN1(sys32_exit_group, sys_exit_group, %o0) | |||
51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) | 51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) |
52 | SIGN1(sys32_creat, sys_creat, %o1) | 52 | SIGN1(sys32_creat, sys_creat, %o1) |
53 | SIGN1(sys32_mknod, sys_mknod, %o1) | 53 | SIGN1(sys32_mknod, sys_mknod, %o1) |
54 | SIGN1(sys32_perfctr, sys_perfctr, %o0) | ||
55 | SIGN1(sys32_umount, sys_umount, %o1) | 54 | SIGN1(sys32_umount, sys_umount, %o1) |
56 | SIGN1(sys32_signal, sys_signal, %o0) | 55 | SIGN1(sys32_signal, sys_signal, %o0) |
57 | SIGN1(sys32_access, sys_access, %o1) | 56 | SIGN1(sys32_access, sys_access, %o1) |
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 04e28b2671c8..c0ca87553e1c 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
@@ -21,16 +21,10 @@ | |||
21 | #include <linux/sem.h> | 21 | #include <linux/sem.h> |
22 | #include <linux/msg.h> | 22 | #include <linux/msg.h> |
23 | #include <linux/shm.h> | 23 | #include <linux/shm.h> |
24 | #include <linux/slab.h> | ||
25 | #include <linux/uio.h> | 24 | #include <linux/uio.h> |
26 | #include <linux/nfs_fs.h> | 25 | #include <linux/nfs_fs.h> |
27 | #include <linux/quota.h> | 26 | #include <linux/quota.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/sunrpc/svc.h> | ||
30 | #include <linux/nfsd/nfsd.h> | ||
31 | #include <linux/nfsd/cache.h> | ||
32 | #include <linux/nfsd/xdr.h> | ||
33 | #include <linux/nfsd/syscall.h> | ||
34 | #include <linux/poll.h> | 28 | #include <linux/poll.h> |
35 | #include <linux/personality.h> | 29 | #include <linux/personality.h> |
36 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
@@ -48,8 +42,8 @@ | |||
48 | #include <linux/security.h> | 42 | #include <linux/security.h> |
49 | #include <linux/compat.h> | 43 | #include <linux/compat.h> |
50 | #include <linux/vfs.h> | 44 | #include <linux/vfs.h> |
51 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
52 | #include <linux/ptrace.h> | 45 | #include <linux/ptrace.h> |
46 | #include <linux/slab.h> | ||
53 | 47 | ||
54 | #include <asm/types.h> | 48 | #include <asm/types.h> |
55 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
@@ -569,85 +563,6 @@ asmlinkage long sparc32_open(const char __user *filename, | |||
569 | return do_sys_open(AT_FDCWD, filename, flags, mode); | 563 | return do_sys_open(AT_FDCWD, filename, flags, mode); |
570 | } | 564 | } |
571 | 565 | ||
572 | extern unsigned long do_mremap(unsigned long addr, | ||
573 | unsigned long old_len, unsigned long new_len, | ||
574 | unsigned long flags, unsigned long new_addr); | ||
575 | |||
576 | asmlinkage unsigned long sys32_mremap(unsigned long addr, | ||
577 | unsigned long old_len, unsigned long new_len, | ||
578 | unsigned long flags, u32 __new_addr) | ||
579 | { | ||
580 | unsigned long ret = -EINVAL; | ||
581 | unsigned long new_addr = __new_addr; | ||
582 | |||
583 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
584 | goto out; | ||
585 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
586 | goto out; | ||
587 | down_write(¤t->mm->mmap_sem); | ||
588 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | ||
589 | up_write(¤t->mm->mmap_sem); | ||
590 | out: | ||
591 | return ret; | ||
592 | } | ||
593 | |||
594 | struct __sysctl_args32 { | ||
595 | u32 name; | ||
596 | int nlen; | ||
597 | u32 oldval; | ||
598 | u32 oldlenp; | ||
599 | u32 newval; | ||
600 | u32 newlen; | ||
601 | u32 __unused[4]; | ||
602 | }; | ||
603 | |||
604 | asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) | ||
605 | { | ||
606 | #ifndef CONFIG_SYSCTL_SYSCALL | ||
607 | return -ENOSYS; | ||
608 | #else | ||
609 | struct __sysctl_args32 tmp; | ||
610 | int error; | ||
611 | size_t oldlen, __user *oldlenp = NULL; | ||
612 | unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL; | ||
613 | |||
614 | if (copy_from_user(&tmp, args, sizeof(tmp))) | ||
615 | return -EFAULT; | ||
616 | |||
617 | if (tmp.oldval && tmp.oldlenp) { | ||
618 | /* Duh, this is ugly and might not work if sysctl_args | ||
619 | is in read-only memory, but do_sysctl does indirectly | ||
620 | a lot of uaccess in both directions and we'd have to | ||
621 | basically copy the whole sysctl.c here, and | ||
622 | glibc's __sysctl uses rw memory for the structure | ||
623 | anyway. */ | ||
624 | if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) || | ||
625 | put_user(oldlen, (size_t __user *)addr)) | ||
626 | return -EFAULT; | ||
627 | oldlenp = (size_t __user *)addr; | ||
628 | } | ||
629 | |||
630 | lock_kernel(); | ||
631 | error = do_sysctl((int __user *)(unsigned long) tmp.name, | ||
632 | tmp.nlen, | ||
633 | (void __user *)(unsigned long) tmp.oldval, | ||
634 | oldlenp, | ||
635 | (void __user *)(unsigned long) tmp.newval, | ||
636 | tmp.newlen); | ||
637 | unlock_kernel(); | ||
638 | if (oldlenp) { | ||
639 | if (!error) { | ||
640 | if (get_user(oldlen, (size_t __user *)addr) || | ||
641 | put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp)) | ||
642 | error = -EFAULT; | ||
643 | } | ||
644 | if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused))) | ||
645 | error = -EFAULT; | ||
646 | } | ||
647 | return error; | ||
648 | #endif | ||
649 | } | ||
650 | |||
651 | long sys32_lookup_dcookie(unsigned long cookie_high, | 566 | long sys32_lookup_dcookie(unsigned long cookie_high, |
652 | unsigned long cookie_low, | 567 | unsigned long cookie_low, |
653 | char __user *buf, size_t len) | 568 | char __user *buf, size_t len) |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 03035c852a43..ee995b7dae7e 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
@@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
45 | /* We do not accept a shared mapping if it would violate | 45 | /* We do not accept a shared mapping if it would violate |
46 | * cache aliasing constraints. | 46 | * cache aliasing constraints. |
47 | */ | 47 | */ |
48 | if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) | 48 | if ((flags & MAP_SHARED) && |
49 | ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) | ||
49 | return -EINVAL; | 50 | return -EINVAL; |
50 | return addr; | 51 | return addr; |
51 | } | 52 | } |
@@ -79,15 +80,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
79 | } | 80 | } |
80 | } | 81 | } |
81 | 82 | ||
82 | asmlinkage unsigned long sparc_brk(unsigned long brk) | ||
83 | { | ||
84 | if(ARCH_SUN4C) { | ||
85 | if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000)) | ||
86 | return current->mm->brk; | ||
87 | } | ||
88 | return sys_brk(brk); | ||
89 | } | ||
90 | |||
91 | /* | 83 | /* |
92 | * sys_pipe() is the normal C calling standard for creating | 84 | * sys_pipe() is the normal C calling standard for creating |
93 | * a pipe. It's not the way unix traditionally does this, though. | 85 | * a pipe. It's not the way unix traditionally does this, though. |
@@ -106,119 +98,6 @@ out: | |||
106 | return error; | 98 | return error; |
107 | } | 99 | } |
108 | 100 | ||
109 | /* | ||
110 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | ||
111 | * | ||
112 | * This is really horribly ugly. | ||
113 | */ | ||
114 | |||
115 | asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth) | ||
116 | { | ||
117 | int version, err; | ||
118 | |||
119 | version = call >> 16; /* hack for backward compatibility */ | ||
120 | call &= 0xffff; | ||
121 | |||
122 | if (call <= SEMCTL) | ||
123 | switch (call) { | ||
124 | case SEMOP: | ||
125 | err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); | ||
126 | goto out; | ||
127 | case SEMTIMEDOP: | ||
128 | err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, (const struct timespec __user *) fifth); | ||
129 | goto out; | ||
130 | case SEMGET: | ||
131 | err = sys_semget (first, second, third); | ||
132 | goto out; | ||
133 | case SEMCTL: { | ||
134 | union semun fourth; | ||
135 | err = -EINVAL; | ||
136 | if (!ptr) | ||
137 | goto out; | ||
138 | err = -EFAULT; | ||
139 | if (get_user(fourth.__pad, | ||
140 | (void __user * __user *)ptr)) | ||
141 | goto out; | ||
142 | err = sys_semctl (first, second, third, fourth); | ||
143 | goto out; | ||
144 | } | ||
145 | default: | ||
146 | err = -ENOSYS; | ||
147 | goto out; | ||
148 | } | ||
149 | if (call <= MSGCTL) | ||
150 | switch (call) { | ||
151 | case MSGSND: | ||
152 | err = sys_msgsnd (first, (struct msgbuf __user *) ptr, | ||
153 | second, third); | ||
154 | goto out; | ||
155 | case MSGRCV: | ||
156 | switch (version) { | ||
157 | case 0: { | ||
158 | struct ipc_kludge tmp; | ||
159 | err = -EINVAL; | ||
160 | if (!ptr) | ||
161 | goto out; | ||
162 | err = -EFAULT; | ||
163 | if (copy_from_user(&tmp, (struct ipc_kludge __user *) ptr, sizeof (tmp))) | ||
164 | goto out; | ||
165 | err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); | ||
166 | goto out; | ||
167 | } | ||
168 | case 1: default: | ||
169 | err = sys_msgrcv (first, | ||
170 | (struct msgbuf __user *) ptr, | ||
171 | second, fifth, third); | ||
172 | goto out; | ||
173 | } | ||
174 | case MSGGET: | ||
175 | err = sys_msgget ((key_t) first, second); | ||
176 | goto out; | ||
177 | case MSGCTL: | ||
178 | err = sys_msgctl (first, second, (struct msqid_ds __user *) ptr); | ||
179 | goto out; | ||
180 | default: | ||
181 | err = -ENOSYS; | ||
182 | goto out; | ||
183 | } | ||
184 | if (call <= SHMCTL) | ||
185 | switch (call) { | ||
186 | case SHMAT: | ||
187 | switch (version) { | ||
188 | case 0: default: { | ||
189 | ulong raddr; | ||
190 | err = do_shmat (first, (char __user *) ptr, second, &raddr); | ||
191 | if (err) | ||
192 | goto out; | ||
193 | err = -EFAULT; | ||
194 | if (put_user (raddr, (ulong __user *) third)) | ||
195 | goto out; | ||
196 | err = 0; | ||
197 | goto out; | ||
198 | } | ||
199 | case 1: /* iBCS2 emulator entry point */ | ||
200 | err = -EINVAL; | ||
201 | goto out; | ||
202 | } | ||
203 | case SHMDT: | ||
204 | err = sys_shmdt ((char __user *)ptr); | ||
205 | goto out; | ||
206 | case SHMGET: | ||
207 | err = sys_shmget (first, second, third); | ||
208 | goto out; | ||
209 | case SHMCTL: | ||
210 | err = sys_shmctl (first, second, (struct shmid_ds __user *) ptr); | ||
211 | goto out; | ||
212 | default: | ||
213 | err = -ENOSYS; | ||
214 | goto out; | ||
215 | } | ||
216 | else | ||
217 | err = -ENOSYS; | ||
218 | out: | ||
219 | return err; | ||
220 | } | ||
221 | |||
222 | int sparc_mmap_check(unsigned long addr, unsigned long len) | 101 | int sparc_mmap_check(unsigned long addr, unsigned long len) |
223 | { | 102 | { |
224 | if (ARCH_SUN4C && | 103 | if (ARCH_SUN4C && |
@@ -234,31 +113,6 @@ int sparc_mmap_check(unsigned long addr, unsigned long len) | |||
234 | } | 113 | } |
235 | 114 | ||
236 | /* Linux version of mmap */ | 115 | /* Linux version of mmap */ |
237 | static unsigned long do_mmap2(unsigned long addr, unsigned long len, | ||
238 | unsigned long prot, unsigned long flags, unsigned long fd, | ||
239 | unsigned long pgoff) | ||
240 | { | ||
241 | struct file * file = NULL; | ||
242 | unsigned long retval = -EBADF; | ||
243 | |||
244 | if (!(flags & MAP_ANONYMOUS)) { | ||
245 | file = fget(fd); | ||
246 | if (!file) | ||
247 | goto out; | ||
248 | } | ||
249 | |||
250 | len = PAGE_ALIGN(len); | ||
251 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
252 | |||
253 | down_write(¤t->mm->mmap_sem); | ||
254 | retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
255 | up_write(¤t->mm->mmap_sem); | ||
256 | |||
257 | if (file) | ||
258 | fput(file); | ||
259 | out: | ||
260 | return retval; | ||
261 | } | ||
262 | 116 | ||
263 | asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, | 117 | asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, |
264 | unsigned long prot, unsigned long flags, unsigned long fd, | 118 | unsigned long prot, unsigned long flags, unsigned long fd, |
@@ -266,14 +120,16 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, | |||
266 | { | 120 | { |
267 | /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE | 121 | /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE |
268 | we have. */ | 122 | we have. */ |
269 | return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12)); | 123 | return sys_mmap_pgoff(addr, len, prot, flags, fd, |
124 | pgoff >> (PAGE_SHIFT - 12)); | ||
270 | } | 125 | } |
271 | 126 | ||
272 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | 127 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, |
273 | unsigned long prot, unsigned long flags, unsigned long fd, | 128 | unsigned long prot, unsigned long flags, unsigned long fd, |
274 | unsigned long off) | 129 | unsigned long off) |
275 | { | 130 | { |
276 | return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); | 131 | /* no alignment check? */ |
132 | return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); | ||
277 | } | 133 | } |
278 | 134 | ||
279 | long sparc_remap_file_pages(unsigned long start, unsigned long size, | 135 | long sparc_remap_file_pages(unsigned long start, unsigned long size, |
@@ -287,27 +143,6 @@ long sparc_remap_file_pages(unsigned long start, unsigned long size, | |||
287 | (pgoff >> (PAGE_SHIFT - 12)), flags); | 143 | (pgoff >> (PAGE_SHIFT - 12)), flags); |
288 | } | 144 | } |
289 | 145 | ||
290 | extern unsigned long do_mremap(unsigned long addr, | ||
291 | unsigned long old_len, unsigned long new_len, | ||
292 | unsigned long flags, unsigned long new_addr); | ||
293 | |||
294 | asmlinkage unsigned long sparc_mremap(unsigned long addr, | ||
295 | unsigned long old_len, unsigned long new_len, | ||
296 | unsigned long flags, unsigned long new_addr) | ||
297 | { | ||
298 | unsigned long ret = -EINVAL; | ||
299 | |||
300 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
301 | goto out; | ||
302 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
303 | goto out; | ||
304 | down_write(¤t->mm->mmap_sem); | ||
305 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | ||
306 | up_write(¤t->mm->mmap_sem); | ||
307 | out: | ||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | /* we come to here via sys_nis_syscall so it can setup the regs argument */ | 146 | /* we come to here via sys_nis_syscall so it can setup the regs argument */ |
312 | asmlinkage unsigned long | 147 | asmlinkage unsigned long |
313 | c_sys_nis_syscall (struct pt_regs *regs) | 148 | c_sys_nis_syscall (struct pt_regs *regs) |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index e2d102447a43..3d435c42e6db 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/utrap.h> | 29 | #include <asm/utrap.h> |
30 | #include <asm/perfctr.h> | ||
31 | #include <asm/unistd.h> | 30 | #include <asm/unistd.h> |
32 | 31 | ||
33 | #include "entry.h" | 32 | #include "entry.h" |
@@ -317,10 +316,14 @@ bottomup: | |||
317 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) | 316 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) |
318 | { | 317 | { |
319 | unsigned long align_goal, addr = -ENOMEM; | 318 | unsigned long align_goal, addr = -ENOMEM; |
319 | unsigned long (*get_area)(struct file *, unsigned long, | ||
320 | unsigned long, unsigned long, unsigned long); | ||
321 | |||
322 | get_area = current->mm->get_unmapped_area; | ||
320 | 323 | ||
321 | if (flags & MAP_FIXED) { | 324 | if (flags & MAP_FIXED) { |
322 | /* Ok, don't mess with it. */ | 325 | /* Ok, don't mess with it. */ |
323 | return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 326 | return get_area(NULL, orig_addr, len, pgoff, flags); |
324 | } | 327 | } |
325 | flags &= ~MAP_SHARED; | 328 | flags &= ~MAP_SHARED; |
326 | 329 | ||
@@ -333,7 +336,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
333 | align_goal = (64UL * 1024); | 336 | align_goal = (64UL * 1024); |
334 | 337 | ||
335 | do { | 338 | do { |
336 | addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); | 339 | addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); |
337 | if (!(addr & ~PAGE_MASK)) { | 340 | if (!(addr & ~PAGE_MASK)) { |
338 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); | 341 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); |
339 | break; | 342 | break; |
@@ -351,7 +354,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
351 | * be obtained. | 354 | * be obtained. |
352 | */ | 355 | */ |
353 | if (addr & ~PAGE_MASK) | 356 | if (addr & ~PAGE_MASK) |
354 | addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 357 | addr = get_area(NULL, orig_addr, len, pgoff, flags); |
355 | 358 | ||
356 | return addr; | 359 | return addr; |
357 | } | 360 | } |
@@ -361,6 +364,7 @@ EXPORT_SYMBOL(get_fb_unmapped_area); | |||
361 | void arch_pick_mmap_layout(struct mm_struct *mm) | 364 | void arch_pick_mmap_layout(struct mm_struct *mm) |
362 | { | 365 | { |
363 | unsigned long random_factor = 0UL; | 366 | unsigned long random_factor = 0UL; |
367 | unsigned long gap; | ||
364 | 368 | ||
365 | if (current->flags & PF_RANDOMIZE) { | 369 | if (current->flags & PF_RANDOMIZE) { |
366 | random_factor = get_random_int(); | 370 | random_factor = get_random_int(); |
@@ -375,9 +379,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
375 | * Fall back to the standard layout if the personality | 379 | * Fall back to the standard layout if the personality |
376 | * bit is set, or if the expected stack growth is unlimited: | 380 | * bit is set, or if the expected stack growth is unlimited: |
377 | */ | 381 | */ |
382 | gap = rlimit(RLIMIT_STACK); | ||
378 | if (!test_thread_flag(TIF_32BIT) || | 383 | if (!test_thread_flag(TIF_32BIT) || |
379 | (current->personality & ADDR_COMPAT_LAYOUT) || | 384 | (current->personality & ADDR_COMPAT_LAYOUT) || |
380 | current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY || | 385 | gap == RLIM_INFINITY || |
381 | sysctl_legacy_va_layout) { | 386 | sysctl_legacy_va_layout) { |
382 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; | 387 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; |
383 | mm->get_unmapped_area = arch_get_unmapped_area; | 388 | mm->get_unmapped_area = arch_get_unmapped_area; |
@@ -385,9 +390,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
385 | } else { | 390 | } else { |
386 | /* We know it's 32-bit */ | 391 | /* We know it's 32-bit */ |
387 | unsigned long task_size = STACK_TOP32; | 392 | unsigned long task_size = STACK_TOP32; |
388 | unsigned long gap; | ||
389 | 393 | ||
390 | gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; | ||
391 | if (gap < 128 * 1024 * 1024) | 394 | if (gap < 128 * 1024 * 1024) |
392 | gap = 128 * 1024 * 1024; | 395 | gap = 128 * 1024 * 1024; |
393 | if (gap > (task_size / 6 * 5)) | 396 | if (gap > (task_size / 6 * 5)) |
@@ -399,18 +402,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
399 | } | 402 | } |
400 | } | 403 | } |
401 | 404 | ||
402 | SYSCALL_DEFINE1(sparc_brk, unsigned long, brk) | ||
403 | { | ||
404 | /* People could try to be nasty and use ta 0x6d in 32bit programs */ | ||
405 | if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) | ||
406 | return current->mm->brk; | ||
407 | |||
408 | if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk))) | ||
409 | return current->mm->brk; | ||
410 | |||
411 | return sys_brk(brk); | ||
412 | } | ||
413 | |||
414 | /* | 405 | /* |
415 | * sys_pipe() is the normal C calling standard for creating | 406 | * sys_pipe() is the normal C calling standard for creating |
416 | * a pipe. It's not the way unix traditionally does this, though. | 407 | * a pipe. It's not the way unix traditionally does this, though. |
@@ -435,7 +426,7 @@ out: | |||
435 | * This is really horribly ugly. | 426 | * This is really horribly ugly. |
436 | */ | 427 | */ |
437 | 428 | ||
438 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | 429 | SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second, |
439 | unsigned long, third, void __user *, ptr, long, fifth) | 430 | unsigned long, third, void __user *, ptr, long, fifth) |
440 | { | 431 | { |
441 | long err; | 432 | long err; |
@@ -519,17 +510,6 @@ out: | |||
519 | return err; | 510 | return err; |
520 | } | 511 | } |
521 | 512 | ||
522 | SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name) | ||
523 | { | ||
524 | int ret = sys_newuname(name); | ||
525 | |||
526 | if (current->personality == PER_LINUX32 && !ret) { | ||
527 | ret = (copy_to_user(name->machine, "sparc\0\0", 8) | ||
528 | ? -EFAULT : 0); | ||
529 | } | ||
530 | return ret; | ||
531 | } | ||
532 | |||
533 | SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) | 513 | SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) |
534 | { | 514 | { |
535 | int ret; | 515 | int ret; |
@@ -568,23 +548,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, | |||
568 | unsigned long, prot, unsigned long, flags, unsigned long, fd, | 548 | unsigned long, prot, unsigned long, flags, unsigned long, fd, |
569 | unsigned long, off) | 549 | unsigned long, off) |
570 | { | 550 | { |
571 | struct file * file = NULL; | 551 | unsigned long retval = -EINVAL; |
572 | unsigned long retval = -EBADF; | ||
573 | 552 | ||
574 | if (!(flags & MAP_ANONYMOUS)) { | 553 | if ((off + PAGE_ALIGN(len)) < off) |
575 | file = fget(fd); | 554 | goto out; |
576 | if (!file) | 555 | if (off & ~PAGE_MASK) |
577 | goto out; | 556 | goto out; |
578 | } | 557 | retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); |
579 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
580 | len = PAGE_ALIGN(len); | ||
581 | |||
582 | down_write(¤t->mm->mmap_sem); | ||
583 | retval = do_mmap(file, addr, len, prot, flags, off); | ||
584 | up_write(¤t->mm->mmap_sem); | ||
585 | |||
586 | if (file) | ||
587 | fput(file); | ||
588 | out: | 558 | out: |
589 | return retval; | 559 | return retval; |
590 | } | 560 | } |
@@ -614,12 +584,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, | |||
614 | 584 | ||
615 | if (test_thread_flag(TIF_32BIT)) | 585 | if (test_thread_flag(TIF_32BIT)) |
616 | goto out; | 586 | goto out; |
617 | if (unlikely(new_len >= VA_EXCLUDE_START)) | ||
618 | goto out; | ||
619 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
620 | goto out; | ||
621 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
622 | goto out; | ||
623 | 587 | ||
624 | down_write(¤t->mm->mmap_sem); | 588 | down_write(¤t->mm->mmap_sem); |
625 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 589 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
@@ -790,109 +754,6 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
790 | return ret; | 754 | return ret; |
791 | } | 755 | } |
792 | 756 | ||
793 | /* Invoked by rtrap code to update performance counters in | ||
794 | * user space. | ||
795 | */ | ||
796 | asmlinkage void update_perfctrs(void) | ||
797 | { | ||
798 | unsigned long pic, tmp; | ||
799 | |||
800 | read_pic(pic); | ||
801 | tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); | ||
802 | __put_user(tmp, current_thread_info()->user_cntd0); | ||
803 | tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); | ||
804 | __put_user(tmp, current_thread_info()->user_cntd1); | ||
805 | reset_pic(); | ||
806 | } | ||
807 | |||
808 | SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0, | ||
809 | unsigned long, arg1, unsigned long, arg2) | ||
810 | { | ||
811 | int err = 0; | ||
812 | |||
813 | switch(opcode) { | ||
814 | case PERFCTR_ON: | ||
815 | current_thread_info()->pcr_reg = arg2; | ||
816 | current_thread_info()->user_cntd0 = (u64 __user *) arg0; | ||
817 | current_thread_info()->user_cntd1 = (u64 __user *) arg1; | ||
818 | current_thread_info()->kernel_cntd0 = | ||
819 | current_thread_info()->kernel_cntd1 = 0; | ||
820 | write_pcr(arg2); | ||
821 | reset_pic(); | ||
822 | set_thread_flag(TIF_PERFCTR); | ||
823 | break; | ||
824 | |||
825 | case PERFCTR_OFF: | ||
826 | err = -EINVAL; | ||
827 | if (test_thread_flag(TIF_PERFCTR)) { | ||
828 | current_thread_info()->user_cntd0 = | ||
829 | current_thread_info()->user_cntd1 = NULL; | ||
830 | current_thread_info()->pcr_reg = 0; | ||
831 | write_pcr(0); | ||
832 | clear_thread_flag(TIF_PERFCTR); | ||
833 | err = 0; | ||
834 | } | ||
835 | break; | ||
836 | |||
837 | case PERFCTR_READ: { | ||
838 | unsigned long pic, tmp; | ||
839 | |||
840 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
841 | err = -EINVAL; | ||
842 | break; | ||
843 | } | ||
844 | read_pic(pic); | ||
845 | tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); | ||
846 | err |= __put_user(tmp, current_thread_info()->user_cntd0); | ||
847 | tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); | ||
848 | err |= __put_user(tmp, current_thread_info()->user_cntd1); | ||
849 | reset_pic(); | ||
850 | break; | ||
851 | } | ||
852 | |||
853 | case PERFCTR_CLRPIC: | ||
854 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
855 | err = -EINVAL; | ||
856 | break; | ||
857 | } | ||
858 | current_thread_info()->kernel_cntd0 = | ||
859 | current_thread_info()->kernel_cntd1 = 0; | ||
860 | reset_pic(); | ||
861 | break; | ||
862 | |||
863 | case PERFCTR_SETPCR: { | ||
864 | u64 __user *user_pcr = (u64 __user *)arg0; | ||
865 | |||
866 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
867 | err = -EINVAL; | ||
868 | break; | ||
869 | } | ||
870 | err |= __get_user(current_thread_info()->pcr_reg, user_pcr); | ||
871 | write_pcr(current_thread_info()->pcr_reg); | ||
872 | current_thread_info()->kernel_cntd0 = | ||
873 | current_thread_info()->kernel_cntd1 = 0; | ||
874 | reset_pic(); | ||
875 | break; | ||
876 | } | ||
877 | |||
878 | case PERFCTR_GETPCR: { | ||
879 | u64 __user *user_pcr = (u64 __user *)arg0; | ||
880 | |||
881 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
882 | err = -EINVAL; | ||
883 | break; | ||
884 | } | ||
885 | err |= __put_user(current_thread_info()->pcr_reg, user_pcr); | ||
886 | break; | ||
887 | } | ||
888 | |||
889 | default: | ||
890 | err = -EINVAL; | ||
891 | break; | ||
892 | }; | ||
893 | return err; | ||
894 | } | ||
895 | |||
896 | /* | 757 | /* |
897 | * Do a system call from kernel instead of calling sys_execve so we | 758 | * Do a system call from kernel instead of calling sys_execve so we |
898 | * end up with proper pt_regs. | 759 | * end up with proper pt_regs. |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index d150c2aa98d2..1d7e274f3f2b 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
@@ -62,7 +62,7 @@ sys32_rt_sigreturn: | |||
62 | #endif | 62 | #endif |
63 | .align 32 | 63 | .align 32 |
64 | 1: ldx [%g6 + TI_FLAGS], %l5 | 64 | 1: ldx [%g6 + TI_FLAGS], %l5 |
65 | andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 65 | andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
66 | be,pt %icc, rtrap | 66 | be,pt %icc, rtrap |
67 | nop | 67 | nop |
68 | call syscall_trace_leave | 68 | call syscall_trace_leave |
@@ -110,31 +110,12 @@ sys_clone: | |||
110 | 110 | ||
111 | .globl ret_from_syscall | 111 | .globl ret_from_syscall |
112 | ret_from_syscall: | 112 | ret_from_syscall: |
113 | /* Clear current_thread_info()->new_child, and | 113 | /* Clear current_thread_info()->new_child. */ |
114 | * check performance counter stuff too. | ||
115 | */ | ||
116 | stb %g0, [%g6 + TI_NEW_CHILD] | 114 | stb %g0, [%g6 + TI_NEW_CHILD] |
117 | ldx [%g6 + TI_FLAGS], %l0 | 115 | ldx [%g6 + TI_FLAGS], %l0 |
118 | call schedule_tail | 116 | call schedule_tail |
119 | mov %g7, %o0 | 117 | mov %g7, %o0 |
120 | andcc %l0, _TIF_PERFCTR, %g0 | 118 | ba,pt %xcc, ret_sys_call |
121 | be,pt %icc, 1f | ||
122 | nop | ||
123 | ldx [%g6 + TI_PCR], %o7 | ||
124 | wr %g0, %o7, %pcr | ||
125 | |||
126 | /* Blackbird errata workaround. See commentary in | ||
127 | * smp.c:smp_percpu_timer_interrupt() for more | ||
128 | * information. | ||
129 | */ | ||
130 | ba,pt %xcc, 99f | ||
131 | nop | ||
132 | |||
133 | .align 64 | ||
134 | 99: wr %g0, %g0, %pic | ||
135 | rd %pic, %g0 | ||
136 | |||
137 | 1: ba,pt %xcc, ret_sys_call | ||
138 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 | 119 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 |
139 | 120 | ||
140 | .globl sparc_exit | 121 | .globl sparc_exit |
@@ -187,7 +168,7 @@ linux_syscall_trace: | |||
187 | .globl linux_sparc_syscall32 | 168 | .globl linux_sparc_syscall32 |
188 | linux_sparc_syscall32: | 169 | linux_sparc_syscall32: |
189 | /* Direct access to user regs, much faster. */ | 170 | /* Direct access to user regs, much faster. */ |
190 | cmp %g1, NR_SYSCALLS ! IEU1 Group | 171 | cmp %g1, NR_syscalls ! IEU1 Group |
191 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI | 172 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI |
192 | srl %i0, 0, %o0 ! IEU0 | 173 | srl %i0, 0, %o0 ! IEU0 |
193 | sll %g1, 2, %l4 ! IEU0 Group | 174 | sll %g1, 2, %l4 ! IEU0 Group |
@@ -198,7 +179,7 @@ linux_sparc_syscall32: | |||
198 | 179 | ||
199 | srl %i5, 0, %o5 ! IEU1 | 180 | srl %i5, 0, %o5 ! IEU1 |
200 | srl %i2, 0, %o2 ! IEU0 Group | 181 | srl %i2, 0, %o2 ! IEU0 Group |
201 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 182 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
202 | bne,pn %icc, linux_syscall_trace32 ! CTI | 183 | bne,pn %icc, linux_syscall_trace32 ! CTI |
203 | mov %i0, %l5 ! IEU1 | 184 | mov %i0, %l5 ! IEU1 |
204 | call %l7 ! CTI Group brk forced | 185 | call %l7 ! CTI Group brk forced |
@@ -210,7 +191,7 @@ linux_sparc_syscall32: | |||
210 | .globl linux_sparc_syscall | 191 | .globl linux_sparc_syscall |
211 | linux_sparc_syscall: | 192 | linux_sparc_syscall: |
212 | /* Direct access to user regs, much faster. */ | 193 | /* Direct access to user regs, much faster. */ |
213 | cmp %g1, NR_SYSCALLS ! IEU1 Group | 194 | cmp %g1, NR_syscalls ! IEU1 Group |
214 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI | 195 | bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI |
215 | mov %i0, %o0 ! IEU0 | 196 | mov %i0, %o0 ! IEU0 |
216 | sll %g1, 2, %l4 ! IEU0 Group | 197 | sll %g1, 2, %l4 ! IEU0 Group |
@@ -221,7 +202,7 @@ linux_sparc_syscall: | |||
221 | 202 | ||
222 | mov %i3, %o3 ! IEU1 | 203 | mov %i3, %o3 ! IEU1 |
223 | mov %i4, %o4 ! IEU0 Group | 204 | mov %i4, %o4 ! IEU0 Group |
224 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 | 205 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
225 | bne,pn %icc, linux_syscall_trace ! CTI Group | 206 | bne,pn %icc, linux_syscall_trace ! CTI Group |
226 | mov %i0, %l5 ! IEU0 | 207 | mov %i0, %l5 ! IEU0 |
227 | 2: call %l7 ! CTI Group brk forced | 208 | 2: call %l7 ! CTI Group brk forced |
@@ -245,7 +226,7 @@ ret_sys_call: | |||
245 | 226 | ||
246 | cmp %o0, -ERESTART_RESTARTBLOCK | 227 | cmp %o0, -ERESTART_RESTARTBLOCK |
247 | bgeu,pn %xcc, 1f | 228 | bgeu,pn %xcc, 1f |
248 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 | 229 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 |
249 | 80: | 230 | 80: |
250 | /* System call success, clear Carry condition code. */ | 231 | /* System call success, clear Carry condition code. */ |
251 | andn %g3, %g2, %g3 | 232 | andn %g3, %g2, %g3 |
@@ -260,7 +241,7 @@ ret_sys_call: | |||
260 | /* System call failure, set Carry condition code. | 241 | /* System call failure, set Carry condition code. |
261 | * Also, get abs(errno) to return to the process. | 242 | * Also, get abs(errno) to return to the process. |
262 | */ | 243 | */ |
263 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 | 244 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 |
264 | sub %g0, %o0, %o0 | 245 | sub %g0, %o0, %o0 |
265 | or %g3, %g2, %g3 | 246 | or %g3, %g2, %g3 |
266 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | 247 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] |
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index ca39c606fe8e..1eb8b00aed75 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c | |||
@@ -107,12 +107,12 @@ static unsigned long run_on_cpu(unsigned long cpu, | |||
107 | unsigned long ret; | 107 | unsigned long ret; |
108 | 108 | ||
109 | /* should return -EINVAL to userspace */ | 109 | /* should return -EINVAL to userspace */ |
110 | if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) | 110 | if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) |
111 | return 0; | 111 | return 0; |
112 | 112 | ||
113 | ret = func(arg); | 113 | ret = func(arg); |
114 | 114 | ||
115 | set_cpus_allowed(current, old_affinity); | 115 | set_cpus_allowed_ptr(current, &old_affinity); |
116 | 116 | ||
117 | return ret; | 117 | return ret; |
118 | } | 118 | } |
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index a63c5d2d9849..118759cd7342 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h | |||
@@ -6,16 +6,12 @@ | |||
6 | #include <asm/utrap.h> | 6 | #include <asm/utrap.h> |
7 | #include <asm/signal.h> | 7 | #include <asm/signal.h> |
8 | 8 | ||
9 | struct new_utsname; | ||
10 | |||
11 | extern asmlinkage unsigned long sys_getpagesize(void); | 9 | extern asmlinkage unsigned long sys_getpagesize(void); |
12 | extern asmlinkage unsigned long sparc_brk(unsigned long brk); | ||
13 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); | 10 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); |
14 | extern asmlinkage long sys_ipc(unsigned int call, int first, | 11 | extern asmlinkage long sys_sparc_ipc(unsigned int call, int first, |
15 | unsigned long second, | 12 | unsigned long second, |
16 | unsigned long third, | 13 | unsigned long third, |
17 | void __user *ptr, long fifth); | 14 | void __user *ptr, long fifth); |
18 | extern asmlinkage long sparc64_newuname(struct new_utsname __user *name); | ||
19 | extern asmlinkage long sparc64_personality(unsigned long personality); | 15 | extern asmlinkage long sparc64_personality(unsigned long personality); |
20 | extern asmlinkage long sys64_munmap(unsigned long addr, size_t len); | 16 | extern asmlinkage long sys64_munmap(unsigned long addr, size_t len); |
21 | extern asmlinkage unsigned long sys64_mremap(unsigned long addr, | 17 | extern asmlinkage unsigned long sys64_mremap(unsigned long addr, |
@@ -37,8 +33,6 @@ extern asmlinkage long sys_rt_sigaction(int sig, | |||
37 | struct sigaction __user *oact, | 33 | struct sigaction __user *oact, |
38 | void __user *restorer, | 34 | void __user *restorer, |
39 | size_t sigsetsize); | 35 | size_t sigsetsize); |
40 | extern asmlinkage long sys_perfctr(int opcode, unsigned long arg0, | ||
41 | unsigned long arg1, unsigned long arg2); | ||
42 | 36 | ||
43 | extern asmlinkage void sparc64_set_context(struct pt_regs *regs); | 37 | extern asmlinkage void sparc64_set_context(struct pt_regs *regs); |
44 | extern asmlinkage void sparc64_get_context(struct pt_regs *regs); | 38 | extern asmlinkage void sparc64_get_context(struct pt_regs *regs); |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 0f1658d37490..801fc8e5a0e8 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
@@ -19,7 +19,7 @@ sys_call_table: | |||
19 | /*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write | 19 | /*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write |
20 | /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link | 20 | /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link |
21 | /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod | 21 | /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod |
22 | /*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek | 22 | /*15*/ .long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek |
23 | /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 23 | /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
24 | /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause | 24 | /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause |
25 | /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice | 25 | /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice |
@@ -67,7 +67,7 @@ sys_call_table: | |||
67 | /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall | 67 | /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall |
68 | /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler | 68 | /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler |
69 | /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep | 69 | /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep |
70 | /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl | 70 | /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl |
71 | /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep | 71 | /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep |
72 | /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun | 72 | /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun |
73 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy | 73 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy |
@@ -82,5 +82,5 @@ sys_call_table: | |||
82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg |
86 | 86 | ||
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 009825f6e73c..9db058dd039e 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -21,7 +21,7 @@ sys_call_table32: | |||
21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write | 21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write |
22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link | 22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link |
23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod | 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod |
24 | /*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek | 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek |
25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause | 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause |
27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice | 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice |
@@ -55,7 +55,7 @@ sys_call_table32: | |||
55 | /*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents | 55 | /*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents |
56 | .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr | 56 | .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr |
57 | /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall | 57 | /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall |
58 | .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_sparc64_newuname | 58 | .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_newuname |
59 | /*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl | 59 | /*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl |
60 | .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask | 60 | .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask |
61 | /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir | 61 | /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir |
@@ -68,7 +68,7 @@ sys_call_table32: | |||
68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall | 68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall |
69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler | 69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler |
70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep | 70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep |
71 | /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl | 71 | /*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl |
72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep | 72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep |
73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun | 73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun |
74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy | 74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
@@ -83,7 +83,7 @@ sys_call_table32: | |||
83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate | 83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate |
84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv | 85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv |
86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg |
87 | 87 | ||
88 | #endif /* CONFIG_COMPAT */ | 88 | #endif /* CONFIG_COMPAT */ |
89 | 89 | ||
@@ -96,7 +96,7 @@ sys_call_table: | |||
96 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write | 96 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write |
97 | /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link | 97 | /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link |
98 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod | 98 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod |
99 | /*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek | 99 | /*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_nis_syscall, sys_lseek |
100 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid | 100 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid |
101 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall | 101 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall |
102 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice | 102 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice |
@@ -130,13 +130,13 @@ sys_call_table: | |||
130 | /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents | 130 | /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents |
131 | .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr | 131 | .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr |
132 | /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall | 132 | /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall |
133 | .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_sparc64_newuname | 133 | .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname |
134 | /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl | 134 | /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl |
135 | .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask | 135 | .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask |
136 | /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall | 136 | /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall |
137 | .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 | 137 | .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 |
138 | /*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo | 138 | /*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo |
139 | .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex | 139 | .word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex |
140 | /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid | 140 | /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid |
141 | .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid | 141 | .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid |
142 | /*230*/ .word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64 | 142 | /*230*/ .word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64 |
@@ -158,4 +158,4 @@ sys_call_table: | |||
158 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 158 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
159 | .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 159 | .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
160 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 160 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
161 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open | 161 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg |
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 614ac7b4a9dd..0d4c09b15efc 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | 36 | ||
37 | #include <asm/oplib.h> | 37 | #include <asm/oplib.h> |
38 | #include <asm/timex.h> | ||
38 | #include <asm/timer.h> | 39 | #include <asm/timer.h> |
39 | #include <asm/system.h> | 40 | #include <asm/system.h> |
40 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
@@ -51,7 +52,6 @@ DEFINE_SPINLOCK(rtc_lock); | |||
51 | EXPORT_SYMBOL(rtc_lock); | 52 | EXPORT_SYMBOL(rtc_lock); |
52 | 53 | ||
53 | static int set_rtc_mmss(unsigned long); | 54 | static int set_rtc_mmss(unsigned long); |
54 | static int sbus_do_settimeofday(struct timespec *tv); | ||
55 | 55 | ||
56 | unsigned long profile_pc(struct pt_regs *regs) | 56 | unsigned long profile_pc(struct pt_regs *regs) |
57 | { | 57 | { |
@@ -76,6 +76,8 @@ EXPORT_SYMBOL(profile_pc); | |||
76 | 76 | ||
77 | __volatile__ unsigned int *master_l10_counter; | 77 | __volatile__ unsigned int *master_l10_counter; |
78 | 78 | ||
79 | u32 (*do_arch_gettimeoffset)(void); | ||
80 | |||
79 | /* | 81 | /* |
80 | * timer_interrupt() needs to keep up the real-time clock, | 82 | * timer_interrupt() needs to keep up the real-time clock, |
81 | * as well as call the "do_timer()" routine every clocktick | 83 | * as well as call the "do_timer()" routine every clocktick |
@@ -196,38 +198,14 @@ static int __init clock_init(void) | |||
196 | { | 198 | { |
197 | return of_register_driver(&clock_driver, &of_platform_bus_type); | 199 | return of_register_driver(&clock_driver, &of_platform_bus_type); |
198 | } | 200 | } |
199 | |||
200 | /* Must be after subsys_initcall() so that busses are probed. Must | 201 | /* Must be after subsys_initcall() so that busses are probed. Must |
201 | * be before device_initcall() because things like the RTC driver | 202 | * be before device_initcall() because things like the RTC driver |
202 | * need to see the clock registers. | 203 | * need to see the clock registers. |
203 | */ | 204 | */ |
204 | fs_initcall(clock_init); | 205 | fs_initcall(clock_init); |
205 | 206 | ||
206 | static void __init sbus_time_init(void) | ||
207 | { | ||
208 | |||
209 | BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM); | ||
210 | btfixup(); | ||
211 | |||
212 | sparc_init_timers(timer_interrupt); | ||
213 | |||
214 | /* Now that OBP ticker has been silenced, it is safe to enable IRQ. */ | ||
215 | local_irq_enable(); | ||
216 | } | ||
217 | |||
218 | void __init time_init(void) | ||
219 | { | ||
220 | #ifdef CONFIG_PCI | ||
221 | extern void pci_time_init(void); | ||
222 | if (pcic_present()) { | ||
223 | pci_time_init(); | ||
224 | return; | ||
225 | } | ||
226 | #endif | ||
227 | sbus_time_init(); | ||
228 | } | ||
229 | 207 | ||
230 | static inline unsigned long do_gettimeoffset(void) | 208 | u32 sbus_do_gettimeoffset(void) |
231 | { | 209 | { |
232 | unsigned long val = *master_l10_counter; | 210 | unsigned long val = *master_l10_counter; |
233 | unsigned long usec = (val >> 10) & 0x1fffff; | 211 | unsigned long usec = (val >> 10) & 0x1fffff; |
@@ -236,86 +214,39 @@ static inline unsigned long do_gettimeoffset(void) | |||
236 | if (val & 0x80000000) | 214 | if (val & 0x80000000) |
237 | usec += 1000000 / HZ; | 215 | usec += 1000000 / HZ; |
238 | 216 | ||
239 | return usec; | 217 | return usec * 1000; |
240 | } | 218 | } |
241 | 219 | ||
242 | /* Ok, my cute asm atomicity trick doesn't work anymore. | ||
243 | * There are just too many variables that need to be protected | ||
244 | * now (both members of xtime, et al.) | ||
245 | */ | ||
246 | void do_gettimeofday(struct timeval *tv) | ||
247 | { | ||
248 | unsigned long flags; | ||
249 | unsigned long seq; | ||
250 | unsigned long usec, sec; | ||
251 | unsigned long max_ntp_tick = tick_usec - tickadj; | ||
252 | |||
253 | do { | ||
254 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
255 | usec = do_gettimeoffset(); | ||
256 | |||
257 | /* | ||
258 | * If time_adjust is negative then NTP is slowing the clock | ||
259 | * so make sure not to go into next possible interval. | ||
260 | * Better to lose some accuracy than have time go backwards.. | ||
261 | */ | ||
262 | if (unlikely(time_adjust < 0)) | ||
263 | usec = min(usec, max_ntp_tick); | ||
264 | |||
265 | sec = xtime.tv_sec; | ||
266 | usec += (xtime.tv_nsec / 1000); | ||
267 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
268 | |||
269 | while (usec >= 1000000) { | ||
270 | usec -= 1000000; | ||
271 | sec++; | ||
272 | } | ||
273 | 220 | ||
274 | tv->tv_sec = sec; | 221 | u32 arch_gettimeoffset(void) |
275 | tv->tv_usec = usec; | ||
276 | } | ||
277 | |||
278 | EXPORT_SYMBOL(do_gettimeofday); | ||
279 | |||
280 | int do_settimeofday(struct timespec *tv) | ||
281 | { | 222 | { |
282 | int ret; | 223 | if (unlikely(!do_arch_gettimeoffset)) |
283 | 224 | return 0; | |
284 | write_seqlock_irq(&xtime_lock); | 225 | return do_arch_gettimeoffset(); |
285 | ret = bus_do_settimeofday(tv); | ||
286 | write_sequnlock_irq(&xtime_lock); | ||
287 | clock_was_set(); | ||
288 | return ret; | ||
289 | } | 226 | } |
290 | 227 | ||
291 | EXPORT_SYMBOL(do_settimeofday); | 228 | static void __init sbus_time_init(void) |
292 | |||
293 | static int sbus_do_settimeofday(struct timespec *tv) | ||
294 | { | 229 | { |
295 | time_t wtm_sec, sec = tv->tv_sec; | 230 | do_arch_gettimeoffset = sbus_do_gettimeoffset; |
296 | long wtm_nsec, nsec = tv->tv_nsec; | ||
297 | 231 | ||
298 | if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) | 232 | btfixup(); |
299 | return -EINVAL; | ||
300 | |||
301 | /* | ||
302 | * This is revolting. We need to set "xtime" correctly. However, the | ||
303 | * value in this location is the value at the most recent update of | ||
304 | * wall time. Discover what correction gettimeofday() would have | ||
305 | * made, and then undo it! | ||
306 | */ | ||
307 | nsec -= 1000 * do_gettimeoffset(); | ||
308 | |||
309 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); | ||
310 | wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); | ||
311 | 233 | ||
312 | set_normalized_timespec(&xtime, sec, nsec); | 234 | sparc_init_timers(timer_interrupt); |
313 | set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); | 235 | } |
314 | 236 | ||
315 | ntp_clear(); | 237 | void __init time_init(void) |
316 | return 0; | 238 | { |
239 | #ifdef CONFIG_PCI | ||
240 | extern void pci_time_init(void); | ||
241 | if (pcic_present()) { | ||
242 | pci_time_init(); | ||
243 | return; | ||
244 | } | ||
245 | #endif | ||
246 | sbus_time_init(); | ||
317 | } | 247 | } |
318 | 248 | ||
249 | |||
319 | static int set_rtc_mmss(unsigned long secs) | 250 | static int set_rtc_mmss(unsigned long secs) |
320 | { | 251 | { |
321 | struct rtc_device *rtc = rtc_class_open("rtc0"); | 252 | struct rtc_device *rtc = rtc_class_open("rtc0"); |
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index da1218e8ee87..c7bbe6cf7b85 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/clocksource.h> | 35 | #include <linux/clocksource.h> |
36 | #include <linux/of_device.h> | 36 | #include <linux/of_device.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/ftrace.h> | ||
38 | 39 | ||
39 | #include <asm/oplib.h> | 40 | #include <asm/oplib.h> |
40 | #include <asm/timer.h> | 41 | #include <asm/timer.h> |
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = { | |||
717 | }; | 718 | }; |
718 | static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); | 719 | static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); |
719 | 720 | ||
720 | void timer_interrupt(int irq, struct pt_regs *regs) | 721 | void __irq_entry timer_interrupt(int irq, struct pt_regs *regs) |
721 | { | 722 | { |
722 | struct pt_regs *old_regs = set_irq_regs(regs); | 723 | struct pt_regs *old_regs = set_irq_regs(regs); |
723 | unsigned long tick_mask = tick_ops->softint_mask; | 724 | unsigned long tick_mask = tick_ops->softint_mask; |
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs) | |||
728 | 729 | ||
729 | irq_enter(); | 730 | irq_enter(); |
730 | 731 | ||
732 | local_cpu_data().irq0_irqs++; | ||
731 | kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); | 733 | kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); |
732 | 734 | ||
733 | if (unlikely(!evt->event_handler)) { | 735 | if (unlikely(!evt->event_handler)) { |
@@ -774,26 +776,9 @@ void __devinit setup_sparc64_timer(void) | |||
774 | static struct clocksource clocksource_tick = { | 776 | static struct clocksource clocksource_tick = { |
775 | .rating = 100, | 777 | .rating = 100, |
776 | .mask = CLOCKSOURCE_MASK(64), | 778 | .mask = CLOCKSOURCE_MASK(64), |
777 | .shift = 16, | ||
778 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 779 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
779 | }; | 780 | }; |
780 | 781 | ||
781 | static void __init setup_clockevent_multiplier(unsigned long hz) | ||
782 | { | ||
783 | unsigned long mult, shift = 32; | ||
784 | |||
785 | while (1) { | ||
786 | mult = div_sc(hz, NSEC_PER_SEC, shift); | ||
787 | if (mult && (mult >> 32UL) == 0UL) | ||
788 | break; | ||
789 | |||
790 | shift--; | ||
791 | } | ||
792 | |||
793 | sparc64_clockevent.shift = shift; | ||
794 | sparc64_clockevent.mult = mult; | ||
795 | } | ||
796 | |||
797 | static unsigned long tb_ticks_per_usec __read_mostly; | 782 | static unsigned long tb_ticks_per_usec __read_mostly; |
798 | 783 | ||
799 | void __delay(unsigned long loops) | 784 | void __delay(unsigned long loops) |
@@ -828,9 +813,7 @@ void __init time_init(void) | |||
828 | clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT); | 813 | clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT); |
829 | 814 | ||
830 | clocksource_tick.name = tick_ops->name; | 815 | clocksource_tick.name = tick_ops->name; |
831 | clocksource_tick.mult = | 816 | clocksource_calc_mult_shift(&clocksource_tick, freq, 4); |
832 | clocksource_hz2mult(freq, | ||
833 | clocksource_tick.shift); | ||
834 | clocksource_tick.read = clocksource_tick_read; | 817 | clocksource_tick.read = clocksource_tick_read; |
835 | 818 | ||
836 | printk("clocksource: mult[%x] shift[%d]\n", | 819 | printk("clocksource: mult[%x] shift[%d]\n", |
@@ -839,15 +822,14 @@ void __init time_init(void) | |||
839 | clocksource_register(&clocksource_tick); | 822 | clocksource_register(&clocksource_tick); |
840 | 823 | ||
841 | sparc64_clockevent.name = tick_ops->name; | 824 | sparc64_clockevent.name = tick_ops->name; |
842 | 825 | clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4); | |
843 | setup_clockevent_multiplier(freq); | ||
844 | 826 | ||
845 | sparc64_clockevent.max_delta_ns = | 827 | sparc64_clockevent.max_delta_ns = |
846 | clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); | 828 | clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); |
847 | sparc64_clockevent.min_delta_ns = | 829 | sparc64_clockevent.min_delta_ns = |
848 | clockevent_delta2ns(0xF, &sparc64_clockevent); | 830 | clockevent_delta2ns(0xF, &sparc64_clockevent); |
849 | 831 | ||
850 | printk("clockevent: mult[%lx] shift[%d]\n", | 832 | printk("clockevent: mult[%x] shift[%d]\n", |
851 | sparc64_clockevent.mult, sparc64_clockevent.shift); | 833 | sparc64_clockevent.mult, sparc64_clockevent.shift); |
852 | 834 | ||
853 | setup_sparc64_timer(); | 835 | setup_sparc64_timer(); |
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index 5e235c52d667..691f484e03b3 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <asm/contregs.h> | 15 | #include <asm/contregs.h> |
16 | #include <asm/thread_info.h> | 16 | #include <asm/thread_info.h> |
17 | 17 | ||
18 | .globl sun4m_cpu_startup, __smp4m_processor_id | 18 | .globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id |
19 | .globl sun4d_cpu_startup, __smp4d_processor_id | 19 | .globl sun4d_cpu_startup, __smp4d_processor_id |
20 | 20 | ||
21 | __CPUINIT | 21 | __CPUINIT |
@@ -106,6 +106,12 @@ __smp4d_processor_id: | |||
106 | retl | 106 | retl |
107 | mov %g1, %o7 | 107 | mov %g1, %o7 |
108 | 108 | ||
109 | __leon_processor_id: | ||
110 | rd %asr17,%g2 | ||
111 | srl %g2,28,%g2 | ||
112 | retl | ||
113 | mov %g1, %o7 | ||
114 | |||
109 | /* CPUID in bootbus can be found at PA 0xff0140000 */ | 115 | /* CPUID in bootbus can be found at PA 0xff0140000 */ |
110 | #define SUN4D_BOOTBUS_CPUID 0xf0140000 | 116 | #define SUN4D_BOOTBUS_CPUID 0xf0140000 |
111 | 117 | ||
@@ -160,3 +166,64 @@ sun4d_cpu_startup: | |||
160 | nop | 166 | nop |
161 | 167 | ||
162 | b,a smp_do_cpu_idle | 168 | b,a smp_do_cpu_idle |
169 | |||
170 | #ifdef CONFIG_SPARC_LEON | ||
171 | |||
172 | __CPUINIT | ||
173 | .align 4 | ||
174 | .global leon_smp_cpu_startup, smp_penguin_ctable | ||
175 | |||
176 | leon_smp_cpu_startup: | ||
177 | |||
178 | set smp_penguin_ctable,%g1 | ||
179 | ld [%g1+4],%g1 | ||
180 | srl %g1,4,%g1 | ||
181 | set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ | ||
182 | sta %g1, [%g5] ASI_M_MMUREGS | ||
183 | |||
184 | /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ | ||
185 | set (PSR_PIL | PSR_S | PSR_PS), %g1 | ||
186 | wr %g1, 0x0, %psr ! traps off though | ||
187 | WRITE_PAUSE | ||
188 | |||
189 | /* Our %wim is one behind CWP */ | ||
190 | mov 2, %g1 | ||
191 | wr %g1, 0x0, %wim | ||
192 | WRITE_PAUSE | ||
193 | |||
194 | /* Set tbr - we use just one trap table. */ | ||
195 | set trapbase, %g1 | ||
196 | wr %g1, 0x0, %tbr | ||
197 | WRITE_PAUSE | ||
198 | |||
199 | /* Get our CPU id */ | ||
200 | rd %asr17,%g3 | ||
201 | |||
202 | /* Give ourselves a stack and curptr. */ | ||
203 | set current_set, %g5 | ||
204 | srl %g3, 28, %g4 | ||
205 | sll %g4, 2, %g4 | ||
206 | ld [%g5 + %g4], %g6 | ||
207 | |||
208 | sethi %hi(THREAD_SIZE - STACKFRAME_SZ), %sp | ||
209 | or %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp | ||
210 | add %g6, %sp, %sp | ||
211 | |||
212 | /* Turn on traps (PSR_ET). */ | ||
213 | rd %psr, %g1 | ||
214 | wr %g1, PSR_ET, %psr ! traps on | ||
215 | WRITE_PAUSE | ||
216 | |||
217 | /* Init our caches, etc. */ | ||
218 | set poke_srmmu, %g5 | ||
219 | ld [%g5], %g5 | ||
220 | call %g5 | ||
221 | nop | ||
222 | |||
223 | /* Start this processor. */ | ||
224 | call leon_callin | ||
225 | nop | ||
226 | |||
227 | b,a smp_do_cpu_idle | ||
228 | |||
229 | #endif | ||
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 10f7bb9fc140..9da57f032983 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/kdebug.h> | 19 | #include <linux/kdebug.h> |
20 | #include <linux/gfp.h> | ||
20 | 21 | ||
21 | #include <asm/smp.h> | 22 | #include <asm/smp.h> |
22 | #include <asm/delay.h> | 23 | #include <asm/delay.h> |
@@ -2202,27 +2203,6 @@ void dump_stack(void) | |||
2202 | 2203 | ||
2203 | EXPORT_SYMBOL(dump_stack); | 2204 | EXPORT_SYMBOL(dump_stack); |
2204 | 2205 | ||
2205 | static inline int is_kernel_stack(struct task_struct *task, | ||
2206 | struct reg_window *rw) | ||
2207 | { | ||
2208 | unsigned long rw_addr = (unsigned long) rw; | ||
2209 | unsigned long thread_base, thread_end; | ||
2210 | |||
2211 | if (rw_addr < PAGE_OFFSET) { | ||
2212 | if (task != &init_task) | ||
2213 | return 0; | ||
2214 | } | ||
2215 | |||
2216 | thread_base = (unsigned long) task_stack_page(task); | ||
2217 | thread_end = thread_base + sizeof(union thread_union); | ||
2218 | if (rw_addr >= thread_base && | ||
2219 | rw_addr < thread_end && | ||
2220 | !(rw_addr & 0x7UL)) | ||
2221 | return 1; | ||
2222 | |||
2223 | return 0; | ||
2224 | } | ||
2225 | |||
2226 | static inline struct reg_window *kernel_stack_up(struct reg_window *rw) | 2206 | static inline struct reg_window *kernel_stack_up(struct reg_window *rw) |
2227 | { | 2207 | { |
2228 | unsigned long fp = rw->ins[6]; | 2208 | unsigned long fp = rw->ins[6]; |
@@ -2251,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2251 | show_regs(regs); | 2231 | show_regs(regs); |
2252 | add_taint(TAINT_DIE); | 2232 | add_taint(TAINT_DIE); |
2253 | if (regs->tstate & TSTATE_PRIV) { | 2233 | if (regs->tstate & TSTATE_PRIV) { |
2234 | struct thread_info *tp = current_thread_info(); | ||
2254 | struct reg_window *rw = (struct reg_window *) | 2235 | struct reg_window *rw = (struct reg_window *) |
2255 | (regs->u_regs[UREG_FP] + STACK_BIAS); | 2236 | (regs->u_regs[UREG_FP] + STACK_BIAS); |
2256 | 2237 | ||
@@ -2258,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2258 | * find some badly aligned kernel stack. | 2239 | * find some badly aligned kernel stack. |
2259 | */ | 2240 | */ |
2260 | while (rw && | 2241 | while (rw && |
2261 | count++ < 30&& | 2242 | count++ < 30 && |
2262 | is_kernel_stack(current, rw)) { | 2243 | kstack_valid(tp, (unsigned long) rw)) { |
2263 | printk("Caller[%016lx]: %pS\n", rw->ins[7], | 2244 | printk("Caller[%016lx]: %pS\n", rw->ins[7], |
2264 | (void *) rw->ins[7]); | 2245 | (void *) rw->ins[7]); |
2265 | 2246 | ||
@@ -2548,15 +2529,6 @@ void __init trap_init(void) | |||
2548 | rwbuf_stkptrs) || | 2529 | rwbuf_stkptrs) || |
2549 | TI_GSR != offsetof(struct thread_info, gsr) || | 2530 | TI_GSR != offsetof(struct thread_info, gsr) || |
2550 | TI_XFSR != offsetof(struct thread_info, xfsr) || | 2531 | TI_XFSR != offsetof(struct thread_info, xfsr) || |
2551 | TI_USER_CNTD0 != offsetof(struct thread_info, | ||
2552 | user_cntd0) || | ||
2553 | TI_USER_CNTD1 != offsetof(struct thread_info, | ||
2554 | user_cntd1) || | ||
2555 | TI_KERN_CNTD0 != offsetof(struct thread_info, | ||
2556 | kernel_cntd0) || | ||
2557 | TI_KERN_CNTD1 != offsetof(struct thread_info, | ||
2558 | kernel_cntd1) || | ||
2559 | TI_PCR != offsetof(struct thread_info, pcr_reg) || | ||
2560 | TI_PRE_COUNT != offsetof(struct thread_info, | 2532 | TI_PRE_COUNT != offsetof(struct thread_info, |
2561 | preempt_count) || | 2533 | preempt_count) || |
2562 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || | 2534 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || |
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index 8c91d9b29a2f..db15d123f054 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S | |||
@@ -191,10 +191,12 @@ tsb_dtlb_load: | |||
191 | 191 | ||
192 | tsb_itlb_load: | 192 | tsb_itlb_load: |
193 | /* Executable bit must be set. */ | 193 | /* Executable bit must be set. */ |
194 | 661: andcc %g5, _PAGE_EXEC_4U, %g0 | 194 | 661: sethi %hi(_PAGE_EXEC_4U), %g4 |
195 | .section .sun4v_1insn_patch, "ax" | 195 | andcc %g5, %g4, %g0 |
196 | .section .sun4v_2insn_patch, "ax" | ||
196 | .word 661b | 197 | .word 661b |
197 | andcc %g5, _PAGE_EXEC_4V, %g0 | 198 | andcc %g5, _PAGE_EXEC_4V, %g0 |
199 | nop | ||
198 | .previous | 200 | .previous |
199 | 201 | ||
200 | be,pn %xcc, tsb_do_fault | 202 | be,pn %xcc, tsb_do_fault |
diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index 6b1e6cde6fff..f8514e291e15 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c | |||
@@ -17,8 +17,7 @@ | |||
17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
20 | 20 | #include <linux/perf_event.h> | |
21 | /* #define DEBUG_MNA */ | ||
22 | 21 | ||
23 | enum direction { | 22 | enum direction { |
24 | load, /* ld, ldd, ldh, ldsh */ | 23 | load, /* ld, ldd, ldh, ldsh */ |
@@ -29,12 +28,6 @@ enum direction { | |||
29 | invalid, | 28 | invalid, |
30 | }; | 29 | }; |
31 | 30 | ||
32 | #ifdef DEBUG_MNA | ||
33 | static char *dirstrings[] = { | ||
34 | "load", "store", "both", "fpload", "fpstore", "invalid" | ||
35 | }; | ||
36 | #endif | ||
37 | |||
38 | static inline enum direction decode_direction(unsigned int insn) | 31 | static inline enum direction decode_direction(unsigned int insn) |
39 | { | 32 | { |
40 | unsigned long tmp = (insn >> 21) & 1; | 33 | unsigned long tmp = (insn >> 21) & 1; |
@@ -255,10 +248,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
255 | unsigned long addr = compute_effective_address(regs, insn); | 248 | unsigned long addr = compute_effective_address(regs, insn); |
256 | int err; | 249 | int err; |
257 | 250 | ||
258 | #ifdef DEBUG_MNA | 251 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); |
259 | printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", | ||
260 | regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); | ||
261 | #endif | ||
262 | switch (dir) { | 252 | switch (dir) { |
263 | case load: | 253 | case load: |
264 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), | 254 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), |
@@ -350,6 +340,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
350 | } | 340 | } |
351 | 341 | ||
352 | addr = compute_effective_address(regs, insn); | 342 | addr = compute_effective_address(regs, insn); |
343 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); | ||
353 | switch(dir) { | 344 | switch(dir) { |
354 | case load: | 345 | case load: |
355 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), | 346 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), |
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 379209982a07..c752c4c479bd 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
@@ -20,10 +20,10 @@ | |||
20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/perf_event.h> | ||
24 | #include <linux/ratelimit.h> | ||
23 | #include <asm/fpumacro.h> | 25 | #include <asm/fpumacro.h> |
24 | 26 | ||
25 | /* #define DEBUG_MNA */ | ||
26 | |||
27 | enum direction { | 27 | enum direction { |
28 | load, /* ld, ldd, ldh, ldsh */ | 28 | load, /* ld, ldd, ldh, ldsh */ |
29 | store, /* st, std, sth, stsh */ | 29 | store, /* st, std, sth, stsh */ |
@@ -33,12 +33,6 @@ enum direction { | |||
33 | invalid, | 33 | invalid, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | #ifdef DEBUG_MNA | ||
37 | static char *dirstrings[] = { | ||
38 | "load", "store", "both", "fpload", "fpstore", "invalid" | ||
39 | }; | ||
40 | #endif | ||
41 | |||
42 | static inline enum direction decode_direction(unsigned int insn) | 36 | static inline enum direction decode_direction(unsigned int insn) |
43 | { | 37 | { |
44 | unsigned long tmp = (insn >> 21) & 1; | 38 | unsigned long tmp = (insn >> 21) & 1; |
@@ -56,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn) | |||
56 | } | 50 | } |
57 | 51 | ||
58 | /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ | 52 | /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ |
59 | static inline int decode_access_size(unsigned int insn) | 53 | static inline int decode_access_size(struct pt_regs *regs, unsigned int insn) |
60 | { | 54 | { |
61 | unsigned int tmp; | 55 | unsigned int tmp; |
62 | 56 | ||
@@ -72,7 +66,7 @@ static inline int decode_access_size(unsigned int insn) | |||
72 | return 2; | 66 | return 2; |
73 | else { | 67 | else { |
74 | printk("Impossible unaligned trap. insn=%08x\n", insn); | 68 | printk("Impossible unaligned trap. insn=%08x\n", insn); |
75 | die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); | 69 | die_if_kernel("Byte sized unaligned access?!?!", regs); |
76 | 70 | ||
77 | /* GCC should never warn that control reaches the end | 71 | /* GCC should never warn that control reaches the end |
78 | * of this function without returning a value because | 72 | * of this function without returning a value because |
@@ -281,13 +275,9 @@ static void kernel_mna_trap_fault(int fixup_tstate_asi) | |||
281 | 275 | ||
282 | static void log_unaligned(struct pt_regs *regs) | 276 | static void log_unaligned(struct pt_regs *regs) |
283 | { | 277 | { |
284 | static unsigned long count, last_time; | 278 | static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); |
285 | 279 | ||
286 | if (time_after(jiffies, last_time + 5 * HZ)) | 280 | if (__ratelimit(&ratelimit)) { |
287 | count = 0; | ||
288 | if (count < 5) { | ||
289 | last_time = jiffies; | ||
290 | count++; | ||
291 | printk("Kernel unaligned access at TPC[%lx] %pS\n", | 281 | printk("Kernel unaligned access at TPC[%lx] %pS\n", |
292 | regs->tpc, (void *) regs->tpc); | 282 | regs->tpc, (void *) regs->tpc); |
293 | } | 283 | } |
@@ -296,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs) | |||
296 | asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | 286 | asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) |
297 | { | 287 | { |
298 | enum direction dir = decode_direction(insn); | 288 | enum direction dir = decode_direction(insn); |
299 | int size = decode_access_size(insn); | 289 | int size = decode_access_size(regs, insn); |
300 | int orig_asi, asi; | 290 | int orig_asi, asi; |
301 | 291 | ||
302 | current_thread_info()->kern_una_regs = regs; | 292 | current_thread_info()->kern_una_regs = regs; |
@@ -327,12 +317,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
327 | 317 | ||
328 | addr = compute_effective_address(regs, insn, | 318 | addr = compute_effective_address(regs, insn, |
329 | ((insn >> 25) & 0x1f)); | 319 | ((insn >> 25) & 0x1f)); |
330 | #ifdef DEBUG_MNA | 320 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); |
331 | printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] " | ||
332 | "retpc[%016lx]\n", | ||
333 | regs->tpc, dirstrings[dir], addr, size, | ||
334 | regs->u_regs[UREG_RETPC]); | ||
335 | #endif | ||
336 | switch (asi) { | 321 | switch (asi) { |
337 | case ASI_NL: | 322 | case ASI_NL: |
338 | case ASI_AIUPL: | 323 | case ASI_AIUPL: |
@@ -399,6 +384,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) | |||
399 | int ret, i, rd = ((insn >> 25) & 0x1f); | 384 | int ret, i, rd = ((insn >> 25) & 0x1f); |
400 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | 385 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; |
401 | 386 | ||
387 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
402 | if (insn & 0x2000) { | 388 | if (insn & 0x2000) { |
403 | maybe_flush_windows(0, 0, rd, from_kernel); | 389 | maybe_flush_windows(0, 0, rd, from_kernel); |
404 | value = sign_extend_imm13(insn); | 390 | value = sign_extend_imm13(insn); |
@@ -445,6 +431,8 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) | |||
445 | int asi = decode_asi(insn, regs); | 431 | int asi = decode_asi(insn, regs); |
446 | int flag = (freg < 32) ? FPRS_DL : FPRS_DU; | 432 | int flag = (freg < 32) ? FPRS_DL : FPRS_DU; |
447 | 433 | ||
434 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
435 | |||
448 | save_and_clear_fpu(); | 436 | save_and_clear_fpu(); |
449 | current_thread_info()->xfsr[0] &= ~0x1c000; | 437 | current_thread_info()->xfsr[0] &= ~0x1c000; |
450 | if (freg & 3) { | 438 | if (freg & 3) { |
@@ -566,6 +554,8 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) | |||
566 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | 554 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; |
567 | unsigned long *reg; | 555 | unsigned long *reg; |
568 | 556 | ||
557 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
558 | |||
569 | maybe_flush_windows(0, 0, rd, from_kernel); | 559 | maybe_flush_windows(0, 0, rd, from_kernel); |
570 | reg = fetch_reg_addr(rd, regs); | 560 | reg = fetch_reg_addr(rd, regs); |
571 | if (from_kernel || rd < 16) { | 561 | if (from_kernel || rd < 16) { |
@@ -596,6 +586,7 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr | |||
596 | 586 | ||
597 | if (tstate & TSTATE_PRIV) | 587 | if (tstate & TSTATE_PRIV) |
598 | die_if_kernel("lddfmna from kernel", regs); | 588 | die_if_kernel("lddfmna from kernel", regs); |
589 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); | ||
599 | if (test_thread_flag(TIF_32BIT)) | 590 | if (test_thread_flag(TIF_32BIT)) |
600 | pc = (u32)pc; | 591 | pc = (u32)pc; |
601 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { | 592 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { |
@@ -642,7 +633,6 @@ daex: | |||
642 | return; | 633 | return; |
643 | } | 634 | } |
644 | advance(regs); | 635 | advance(regs); |
645 | return; | ||
646 | } | 636 | } |
647 | 637 | ||
648 | void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) | 638 | void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) |
@@ -657,6 +647,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr | |||
657 | 647 | ||
658 | if (tstate & TSTATE_PRIV) | 648 | if (tstate & TSTATE_PRIV) |
659 | die_if_kernel("stdfmna from kernel", regs); | 649 | die_if_kernel("stdfmna from kernel", regs); |
650 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); | ||
660 | if (test_thread_flag(TIF_32BIT)) | 651 | if (test_thread_flag(TIF_32BIT)) |
661 | pc = (u32)pc; | 652 | pc = (u32)pc; |
662 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { | 653 | if (get_user(insn, (u32 __user *) pc) != -EFAULT) { |
@@ -690,5 +681,4 @@ daex: | |||
690 | return; | 681 | return; |
691 | } | 682 | } |
692 | advance(regs); | 683 | advance(regs); |
693 | return; | ||
694 | } | 684 | } |
diff --git a/arch/sparc/kernel/us2e_cpufreq.c b/arch/sparc/kernel/us2e_cpufreq.c index 791c15138f3a..8f982b76c712 100644 --- a/arch/sparc/kernel/us2e_cpufreq.c +++ b/arch/sparc/kernel/us2e_cpufreq.c | |||
@@ -238,12 +238,12 @@ static unsigned int us2e_freq_get(unsigned int cpu) | |||
238 | return 0; | 238 | return 0; |
239 | 239 | ||
240 | cpus_allowed = current->cpus_allowed; | 240 | cpus_allowed = current->cpus_allowed; |
241 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 241 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
242 | 242 | ||
243 | clock_tick = sparc64_get_clock_tick(cpu) / 1000; | 243 | clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
244 | estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); | 244 | estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); |
245 | 245 | ||
246 | set_cpus_allowed(current, cpus_allowed); | 246 | set_cpus_allowed_ptr(current, &cpus_allowed); |
247 | 247 | ||
248 | return clock_tick / estar_to_divisor(estar); | 248 | return clock_tick / estar_to_divisor(estar); |
249 | } | 249 | } |
@@ -259,7 +259,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
259 | return; | 259 | return; |
260 | 260 | ||
261 | cpus_allowed = current->cpus_allowed; | 261 | cpus_allowed = current->cpus_allowed; |
262 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 262 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
263 | 263 | ||
264 | new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; | 264 | new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
265 | new_bits = index_to_estar_mode(index); | 265 | new_bits = index_to_estar_mode(index); |
@@ -281,7 +281,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
281 | 281 | ||
282 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 282 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
283 | 283 | ||
284 | set_cpus_allowed(current, cpus_allowed); | 284 | set_cpus_allowed_ptr(current, &cpus_allowed); |
285 | } | 285 | } |
286 | 286 | ||
287 | static int us2e_freq_target(struct cpufreq_policy *policy, | 287 | static int us2e_freq_target(struct cpufreq_policy *policy, |
diff --git a/arch/sparc/kernel/us3_cpufreq.c b/arch/sparc/kernel/us3_cpufreq.c index 365b6464e2ce..f35d1e794548 100644 --- a/arch/sparc/kernel/us3_cpufreq.c +++ b/arch/sparc/kernel/us3_cpufreq.c | |||
@@ -86,12 +86,12 @@ static unsigned int us3_freq_get(unsigned int cpu) | |||
86 | return 0; | 86 | return 0; |
87 | 87 | ||
88 | cpus_allowed = current->cpus_allowed; | 88 | cpus_allowed = current->cpus_allowed; |
89 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 89 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
90 | 90 | ||
91 | reg = read_safari_cfg(); | 91 | reg = read_safari_cfg(); |
92 | ret = get_current_freq(cpu, reg); | 92 | ret = get_current_freq(cpu, reg); |
93 | 93 | ||
94 | set_cpus_allowed(current, cpus_allowed); | 94 | set_cpus_allowed_ptr(current, &cpus_allowed); |
95 | 95 | ||
96 | return ret; | 96 | return ret; |
97 | } | 97 | } |
@@ -106,7 +106,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
106 | return; | 106 | return; |
107 | 107 | ||
108 | cpus_allowed = current->cpus_allowed; | 108 | cpus_allowed = current->cpus_allowed; |
109 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 109 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
110 | 110 | ||
111 | new_freq = sparc64_get_clock_tick(cpu) / 1000; | 111 | new_freq = sparc64_get_clock_tick(cpu) / 1000; |
112 | switch (index) { | 112 | switch (index) { |
@@ -140,7 +140,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
140 | 140 | ||
141 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 141 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
142 | 142 | ||
143 | set_cpus_allowed(current, cpus_allowed); | 143 | set_cpus_allowed_ptr(current, &cpus_allowed); |
144 | } | 144 | } |
145 | 145 | ||
146 | static int us3_freq_target(struct cpufreq_policy *policy, | 146 | static int us3_freq_target(struct cpufreq_policy *policy, |
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index c28c71449a6c..3cb1def9806c 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/slab.h> | ||
13 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
15 | 16 | ||
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index d231cbd5c526..9dfd2ebcb157 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/errno.h> | 6 | #include <linux/errno.h> |
7 | #include <linux/thread_info.h> | 7 | #include <linux/thread_info.h> |
8 | #include <linux/perf_event.h> | ||
8 | 9 | ||
9 | #include <asm/ptrace.h> | 10 | #include <asm/ptrace.h> |
10 | #include <asm/pstate.h> | 11 | #include <asm/pstate.h> |
@@ -801,6 +802,8 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) | |||
801 | 802 | ||
802 | BUG_ON(regs->tstate & TSTATE_PRIV); | 803 | BUG_ON(regs->tstate & TSTATE_PRIV); |
803 | 804 | ||
805 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); | ||
806 | |||
804 | if (test_thread_flag(TIF_32BIT)) | 807 | if (test_thread_flag(TIF_32BIT)) |
805 | pc = (u32)pc; | 808 | pc = (u32)pc; |
806 | 809 | ||
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 4e5992593967..0c1e6783657f 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -46,11 +46,16 @@ SECTIONS | |||
46 | SCHED_TEXT | 46 | SCHED_TEXT |
47 | LOCK_TEXT | 47 | LOCK_TEXT |
48 | KPROBES_TEXT | 48 | KPROBES_TEXT |
49 | IRQENTRY_TEXT | ||
49 | *(.gnu.warning) | 50 | *(.gnu.warning) |
50 | } = 0 | 51 | } = 0 |
51 | _etext = .; | 52 | _etext = .; |
52 | 53 | ||
53 | RO_DATA(PAGE_SIZE) | 54 | RO_DATA(PAGE_SIZE) |
55 | |||
56 | /* Start of data section */ | ||
57 | _sdata = .; | ||
58 | |||
54 | .data1 : { | 59 | .data1 : { |
55 | *(.data1) | 60 | *(.data1) |
56 | } | 61 | } |