diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 13:10:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 13:10:02 -0400 |
commit | b247759642cc96a75122907cc898b4c43b4f86ce (patch) | |
tree | 568e6ab08f2b986ff0b1ef80318c6c56c5d2ef42 /arch/parisc | |
parent | 61e312914cc82c085c945f88e5a53d507dd7d0d4 (diff) | |
parent | 5b879d78bc0818aa710f5d4d9abbfc2aca075cc3 (diff) |
Merge branch 'parisc-for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc updates from Helge Deller:
"The PA-RISC updates for v3.11 include a gcc miscompilation fix,
gzip-compressed vmlinuz support, a fix in the PCI code for ATI FireGL
support on c8000 machines, a fix to prevent that %sr1 is being
clobbered and a few smaller optimizations and documentation updates"
* 'parisc-for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: Fix gcc miscompilation in pa_memcpy()
parisc: Ensure volatile space register %sr1 is not clobbered
parisc: optimize mtsp(0,sr) inline assembly
parisc: switch to gzip-compressed vmlinuz kernel
parisc: document the shadow registers
parisc: more capabilities info in /proc/cpuinfo
parisc: fix LMMIO mismatch between PAT length and MASK register
Diffstat (limited to 'arch/parisc')
-rw-r--r-- | arch/parisc/Makefile | 15 | ||||
-rw-r--r-- | arch/parisc/defpalo.conf | 8 | ||||
-rw-r--r-- | arch/parisc/include/asm/special_insns.h | 9 | ||||
-rw-r--r-- | arch/parisc/include/asm/tlbflush.h | 5 | ||||
-rw-r--r-- | arch/parisc/install.sh | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/cache.c | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/processor.c | 19 | ||||
-rw-r--r-- | arch/parisc/lib/memcpy.c | 79 |
8 files changed, 94 insertions, 49 deletions
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 96ec3982be8d..e02f665f804a 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile | |||
@@ -17,6 +17,8 @@ | |||
17 | # Mike Shaver, Helge Deller and Martin K. Petersen | 17 | # Mike Shaver, Helge Deller and Martin K. Petersen |
18 | # | 18 | # |
19 | 19 | ||
20 | KBUILD_IMAGE := vmlinuz | ||
21 | |||
20 | KBUILD_DEFCONFIG := default_defconfig | 22 | KBUILD_DEFCONFIG := default_defconfig |
21 | 23 | ||
22 | NM = sh $(srctree)/arch/parisc/nm | 24 | NM = sh $(srctree)/arch/parisc/nm |
@@ -92,7 +94,7 @@ PALOCONF := $(shell if [ -f $(src)/palo.conf ]; then echo $(src)/palo.conf; \ | |||
92 | else echo $(obj)/palo.conf; \ | 94 | else echo $(obj)/palo.conf; \ |
93 | fi) | 95 | fi) |
94 | 96 | ||
95 | palo: vmlinux | 97 | palo: vmlinuz |
96 | @if test ! -x "$(PALO)"; then \ | 98 | @if test ! -x "$(PALO)"; then \ |
97 | echo 'ERROR: Please install palo first (apt-get install palo)';\ | 99 | echo 'ERROR: Please install palo first (apt-get install palo)';\ |
98 | echo 'or build it from source and install it somewhere in your $$PATH';\ | 100 | echo 'or build it from source and install it somewhere in your $$PATH';\ |
@@ -107,10 +109,14 @@ palo: vmlinux | |||
107 | fi | 109 | fi |
108 | $(PALO) -f $(PALOCONF) | 110 | $(PALO) -f $(PALOCONF) |
109 | 111 | ||
110 | # Shorthands for known targets not supported by parisc, use vmlinux as default | 112 | # Shorthands for known targets not supported by parisc, use vmlinux/vmlinuz as default |
111 | Image zImage bzImage: vmlinux | 113 | Image: vmlinux |
114 | zImage bzImage: vmlinuz | ||
115 | |||
116 | vmlinuz: vmlinux | ||
117 | @gzip -cf -9 $< > $@ | ||
112 | 118 | ||
113 | install: vmlinux | 119 | install: vmlinuz |
114 | sh $(src)/arch/parisc/install.sh \ | 120 | sh $(src)/arch/parisc/install.sh \ |
115 | $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" | 121 | $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" |
116 | 122 | ||
@@ -119,6 +125,7 @@ MRPROPER_FILES += palo.conf | |||
119 | 125 | ||
120 | define archhelp | 126 | define archhelp |
121 | @echo '* vmlinux - Uncompressed kernel image (./vmlinux)' | 127 | @echo '* vmlinux - Uncompressed kernel image (./vmlinux)' |
128 | @echo ' vmlinuz - Compressed kernel image (./vmlinuz)' | ||
122 | @echo ' palo - Bootable image (./lifimage)' | 129 | @echo ' palo - Bootable image (./lifimage)' |
123 | @echo ' install - Install kernel using' | 130 | @echo ' install - Install kernel using' |
124 | @echo ' (your) ~/bin/$(INSTALLKERNEL) or' | 131 | @echo ' (your) ~/bin/$(INSTALLKERNEL) or' |
diff --git a/arch/parisc/defpalo.conf b/arch/parisc/defpalo.conf index 4e1ae25b08d1..208ff3b41487 100644 --- a/arch/parisc/defpalo.conf +++ b/arch/parisc/defpalo.conf | |||
@@ -4,7 +4,7 @@ | |||
4 | # Most people using 'make palo' want a bootable file, usable for | 4 | # Most people using 'make palo' want a bootable file, usable for |
5 | # network or tape booting for example. | 5 | # network or tape booting for example. |
6 | --init-tape=lifimage | 6 | --init-tape=lifimage |
7 | --recoverykernel=vmlinux | 7 | --recoverykernel=vmlinuz |
8 | 8 | ||
9 | ########## Pick your ROOT here! ########## | 9 | ########## Pick your ROOT here! ########## |
10 | # You need at least one 'root='! | 10 | # You need at least one 'root='! |
@@ -12,10 +12,10 @@ | |||
12 | # If you want a root ramdisk, use the next 2 lines | 12 | # If you want a root ramdisk, use the next 2 lines |
13 | # (Edit the ramdisk image name!!!!) | 13 | # (Edit the ramdisk image name!!!!) |
14 | --ramdisk=ram-disk-image-file | 14 | --ramdisk=ram-disk-image-file |
15 | --commandline=0/vmlinux HOME=/ root=/dev/ram initrd=0/ramdisk | 15 | --commandline=0/vmlinuz HOME=/ root=/dev/ram initrd=0/ramdisk panic_timeout=60 panic=-1 |
16 | 16 | ||
17 | # If you want NFS root, use the following command line (Edit the HOSTNAME!!!) | 17 | # If you want NFS root, use the following command line (Edit the HOSTNAME!!!) |
18 | #--commandline=0/vmlinux HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp | 18 | #--commandline=0/vmlinuz HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp |
19 | 19 | ||
20 | # If you have root on a disk partition, use this (Edit the partition name!!!) | 20 | # If you have root on a disk partition, use this (Edit the partition name!!!) |
21 | #--commandline=0/vmlinux HOME=/ root=/dev/sda1 | 21 | #--commandline=0/vmlinuz HOME=/ root=/dev/sda1 |
diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h index d306b75bc77f..e1509308899f 100644 --- a/arch/parisc/include/asm/special_insns.h +++ b/arch/parisc/include/asm/special_insns.h | |||
@@ -32,9 +32,12 @@ static inline void set_eiem(unsigned long val) | |||
32 | cr; \ | 32 | cr; \ |
33 | }) | 33 | }) |
34 | 34 | ||
35 | #define mtsp(gr, cr) \ | 35 | #define mtsp(val, cr) \ |
36 | __asm__ __volatile__("mtsp %0,%1" \ | 36 | { if (__builtin_constant_p(val) && ((val) == 0)) \ |
37 | __asm__ __volatile__("mtsp %%r0,%0" : : "i" (cr) : "memory"); \ | ||
38 | else \ | ||
39 | __asm__ __volatile__("mtsp %0,%1" \ | ||
37 | : /* no outputs */ \ | 40 | : /* no outputs */ \ |
38 | : "r" (gr), "i" (cr) : "memory") | 41 | : "r" (val), "i" (cr) : "memory"); } |
39 | 42 | ||
40 | #endif /* __PARISC_SPECIAL_INSNS_H */ | 43 | #endif /* __PARISC_SPECIAL_INSNS_H */ |
diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h index 5273da991e06..9d086a599fa0 100644 --- a/arch/parisc/include/asm/tlbflush.h +++ b/arch/parisc/include/asm/tlbflush.h | |||
@@ -63,13 +63,14 @@ static inline void flush_tlb_mm(struct mm_struct *mm) | |||
63 | static inline void flush_tlb_page(struct vm_area_struct *vma, | 63 | static inline void flush_tlb_page(struct vm_area_struct *vma, |
64 | unsigned long addr) | 64 | unsigned long addr) |
65 | { | 65 | { |
66 | unsigned long flags; | 66 | unsigned long flags, sid; |
67 | 67 | ||
68 | /* For one page, it's not worth testing the split_tlb variable */ | 68 | /* For one page, it's not worth testing the split_tlb variable */ |
69 | 69 | ||
70 | mb(); | 70 | mb(); |
71 | mtsp(vma->vm_mm->context,1); | 71 | sid = vma->vm_mm->context; |
72 | purge_tlb_start(flags); | 72 | purge_tlb_start(flags); |
73 | mtsp(sid, 1); | ||
73 | pdtlb(addr); | 74 | pdtlb(addr); |
74 | pitlb(addr); | 75 | pitlb(addr); |
75 | purge_tlb_end(flags); | 76 | purge_tlb_end(flags); |
diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh index e593fc8d58bc..4da682b466d0 100644 --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh | |||
@@ -26,13 +26,13 @@ if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi | |||
26 | 26 | ||
27 | # Default install | 27 | # Default install |
28 | 28 | ||
29 | if [ -f $4/vmlinux ]; then | 29 | if [ -f $4/vmlinuz ]; then |
30 | mv $4/vmlinux $4/vmlinux.old | 30 | mv $4/vmlinuz $4/vmlinuz.old |
31 | fi | 31 | fi |
32 | 32 | ||
33 | if [ -f $4/System.map ]; then | 33 | if [ -f $4/System.map ]; then |
34 | mv $4/System.map $4/System.old | 34 | mv $4/System.map $4/System.old |
35 | fi | 35 | fi |
36 | 36 | ||
37 | cat $2 > $4/vmlinux | 37 | cat $2 > $4/vmlinuz |
38 | cp $3 $4/System.map | 38 | cp $3 $4/System.map |
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 65fb4cbc3a0f..2e65aa54bd10 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -440,8 +440,8 @@ void __flush_tlb_range(unsigned long sid, unsigned long start, | |||
440 | else { | 440 | else { |
441 | unsigned long flags; | 441 | unsigned long flags; |
442 | 442 | ||
443 | mtsp(sid, 1); | ||
444 | purge_tlb_start(flags); | 443 | purge_tlb_start(flags); |
444 | mtsp(sid, 1); | ||
445 | if (split_tlb) { | 445 | if (split_tlb) { |
446 | while (npages--) { | 446 | while (npages--) { |
447 | pdtlb(start); | 447 | pdtlb(start); |
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index c8fb61ed32f4..8a96c8ab9fe6 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c | |||
@@ -371,10 +371,23 @@ show_cpuinfo (struct seq_file *m, void *v) | |||
371 | 371 | ||
372 | seq_printf(m, "capabilities\t:"); | 372 | seq_printf(m, "capabilities\t:"); |
373 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32) | 373 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32) |
374 | seq_printf(m, " os32"); | 374 | seq_puts(m, " os32"); |
375 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64) | 375 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64) |
376 | seq_printf(m, " os64"); | 376 | seq_puts(m, " os64"); |
377 | seq_printf(m, "\n"); | 377 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) |
378 | seq_puts(m, " iopdir_fdc"); | ||
379 | switch (boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) { | ||
380 | case PDC_MODEL_NVA_SUPPORTED: | ||
381 | seq_puts(m, " nva_supported"); | ||
382 | break; | ||
383 | case PDC_MODEL_NVA_SLOW: | ||
384 | seq_puts(m, " nva_slow"); | ||
385 | break; | ||
386 | case PDC_MODEL_NVA_UNSUPPORTED: | ||
387 | seq_puts(m, " needs_equivalent_aliasing"); | ||
388 | break; | ||
389 | } | ||
390 | seq_printf(m, " (0x%02lx)\n", boot_cpu_data.pdc.capabilities); | ||
378 | 391 | ||
379 | seq_printf(m, "model\t\t: %s\n" | 392 | seq_printf(m, "model\t\t: %s\n" |
380 | "model name\t: %s\n", | 393 | "model name\t: %s\n", |
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index a49cc812df8a..ac4370b1ca40 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Optimized memory copy routines. | 2 | * Optimized memory copy routines. |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Randolph Chung <tausq@debian.org> | 4 | * Copyright (C) 2004 Randolph Chung <tausq@debian.org> |
5 | * Copyright (C) 2013 Helge Deller <deller@gmx.de> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -153,17 +154,21 @@ static inline void prefetch_dst(const void *addr) | |||
153 | #define prefetch_dst(addr) do { } while(0) | 154 | #define prefetch_dst(addr) do { } while(0) |
154 | #endif | 155 | #endif |
155 | 156 | ||
157 | #define PA_MEMCPY_OK 0 | ||
158 | #define PA_MEMCPY_LOAD_ERROR 1 | ||
159 | #define PA_MEMCPY_STORE_ERROR 2 | ||
160 | |||
156 | /* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words | 161 | /* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words |
157 | * per loop. This code is derived from glibc. | 162 | * per loop. This code is derived from glibc. |
158 | */ | 163 | */ |
159 | static inline unsigned long copy_dstaligned(unsigned long dst, unsigned long src, unsigned long len, unsigned long o_dst, unsigned long o_src, unsigned long o_len) | 164 | static inline unsigned long copy_dstaligned(unsigned long dst, |
165 | unsigned long src, unsigned long len) | ||
160 | { | 166 | { |
161 | /* gcc complains that a2 and a3 may be uninitialized, but actually | 167 | /* gcc complains that a2 and a3 may be uninitialized, but actually |
162 | * they cannot be. Initialize a2/a3 to shut gcc up. | 168 | * they cannot be. Initialize a2/a3 to shut gcc up. |
163 | */ | 169 | */ |
164 | register unsigned int a0, a1, a2 = 0, a3 = 0; | 170 | register unsigned int a0, a1, a2 = 0, a3 = 0; |
165 | int sh_1, sh_2; | 171 | int sh_1, sh_2; |
166 | struct exception_data *d; | ||
167 | 172 | ||
168 | /* prefetch_src((const void *)src); */ | 173 | /* prefetch_src((const void *)src); */ |
169 | 174 | ||
@@ -197,7 +202,7 @@ static inline unsigned long copy_dstaligned(unsigned long dst, unsigned long src | |||
197 | goto do2; | 202 | goto do2; |
198 | case 0: | 203 | case 0: |
199 | if (len == 0) | 204 | if (len == 0) |
200 | return 0; | 205 | return PA_MEMCPY_OK; |
201 | /* a3 = ((unsigned int *) src)[0]; | 206 | /* a3 = ((unsigned int *) src)[0]; |
202 | a0 = ((unsigned int *) src)[1]; */ | 207 | a0 = ((unsigned int *) src)[1]; */ |
203 | ldw(s_space, 0, src, a3, cda_ldw_exc); | 208 | ldw(s_space, 0, src, a3, cda_ldw_exc); |
@@ -256,42 +261,35 @@ do0: | |||
256 | preserve_branch(handle_load_error); | 261 | preserve_branch(handle_load_error); |
257 | preserve_branch(handle_store_error); | 262 | preserve_branch(handle_store_error); |
258 | 263 | ||
259 | return 0; | 264 | return PA_MEMCPY_OK; |
260 | 265 | ||
261 | handle_load_error: | 266 | handle_load_error: |
262 | __asm__ __volatile__ ("cda_ldw_exc:\n"); | 267 | __asm__ __volatile__ ("cda_ldw_exc:\n"); |
263 | d = &__get_cpu_var(exception_data); | 268 | return PA_MEMCPY_LOAD_ERROR; |
264 | DPRINTF("cda_ldw_exc: o_len=%lu fault_addr=%lu o_src=%lu ret=%lu\n", | ||
265 | o_len, d->fault_addr, o_src, o_len - d->fault_addr + o_src); | ||
266 | return o_len * 4 - d->fault_addr + o_src; | ||
267 | 269 | ||
268 | handle_store_error: | 270 | handle_store_error: |
269 | __asm__ __volatile__ ("cda_stw_exc:\n"); | 271 | __asm__ __volatile__ ("cda_stw_exc:\n"); |
270 | d = &__get_cpu_var(exception_data); | 272 | return PA_MEMCPY_STORE_ERROR; |
271 | DPRINTF("cda_stw_exc: o_len=%lu fault_addr=%lu o_dst=%lu ret=%lu\n", | ||
272 | o_len, d->fault_addr, o_dst, o_len - d->fault_addr + o_dst); | ||
273 | return o_len * 4 - d->fault_addr + o_dst; | ||
274 | } | 273 | } |
275 | 274 | ||
276 | 275 | ||
277 | /* Returns 0 for success, otherwise, returns number of bytes not transferred. */ | 276 | /* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR. |
278 | static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) | 277 | * In case of an access fault the faulty address can be read from the per_cpu |
278 | * exception data struct. */ | ||
279 | static unsigned long pa_memcpy_internal(void *dstp, const void *srcp, | ||
280 | unsigned long len) | ||
279 | { | 281 | { |
280 | register unsigned long src, dst, t1, t2, t3; | 282 | register unsigned long src, dst, t1, t2, t3; |
281 | register unsigned char *pcs, *pcd; | 283 | register unsigned char *pcs, *pcd; |
282 | register unsigned int *pws, *pwd; | 284 | register unsigned int *pws, *pwd; |
283 | register double *pds, *pdd; | 285 | register double *pds, *pdd; |
284 | unsigned long ret = 0; | 286 | unsigned long ret; |
285 | unsigned long o_dst, o_src, o_len; | ||
286 | struct exception_data *d; | ||
287 | 287 | ||
288 | src = (unsigned long)srcp; | 288 | src = (unsigned long)srcp; |
289 | dst = (unsigned long)dstp; | 289 | dst = (unsigned long)dstp; |
290 | pcs = (unsigned char *)srcp; | 290 | pcs = (unsigned char *)srcp; |
291 | pcd = (unsigned char *)dstp; | 291 | pcd = (unsigned char *)dstp; |
292 | 292 | ||
293 | o_dst = dst; o_src = src; o_len = len; | ||
294 | |||
295 | /* prefetch_src((const void *)srcp); */ | 293 | /* prefetch_src((const void *)srcp); */ |
296 | 294 | ||
297 | if (len < THRESHOLD) | 295 | if (len < THRESHOLD) |
@@ -401,7 +399,7 @@ byte_copy: | |||
401 | len--; | 399 | len--; |
402 | } | 400 | } |
403 | 401 | ||
404 | return 0; | 402 | return PA_MEMCPY_OK; |
405 | 403 | ||
406 | unaligned_copy: | 404 | unaligned_copy: |
407 | /* possibly we are aligned on a word, but not on a double... */ | 405 | /* possibly we are aligned on a word, but not on a double... */ |
@@ -438,8 +436,7 @@ unaligned_copy: | |||
438 | src = (unsigned long)pcs; | 436 | src = (unsigned long)pcs; |
439 | } | 437 | } |
440 | 438 | ||
441 | ret = copy_dstaligned(dst, src, len / sizeof(unsigned int), | 439 | ret = copy_dstaligned(dst, src, len / sizeof(unsigned int)); |
442 | o_dst, o_src, o_len); | ||
443 | if (ret) | 440 | if (ret) |
444 | return ret; | 441 | return ret; |
445 | 442 | ||
@@ -454,17 +451,41 @@ unaligned_copy: | |||
454 | 451 | ||
455 | handle_load_error: | 452 | handle_load_error: |
456 | __asm__ __volatile__ ("pmc_load_exc:\n"); | 453 | __asm__ __volatile__ ("pmc_load_exc:\n"); |
457 | d = &__get_cpu_var(exception_data); | 454 | return PA_MEMCPY_LOAD_ERROR; |
458 | DPRINTF("pmc_load_exc: o_len=%lu fault_addr=%lu o_src=%lu ret=%lu\n", | ||
459 | o_len, d->fault_addr, o_src, o_len - d->fault_addr + o_src); | ||
460 | return o_len - d->fault_addr + o_src; | ||
461 | 455 | ||
462 | handle_store_error: | 456 | handle_store_error: |
463 | __asm__ __volatile__ ("pmc_store_exc:\n"); | 457 | __asm__ __volatile__ ("pmc_store_exc:\n"); |
458 | return PA_MEMCPY_STORE_ERROR; | ||
459 | } | ||
460 | |||
461 | |||
462 | /* Returns 0 for success, otherwise, returns number of bytes not transferred. */ | ||
463 | static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) | ||
464 | { | ||
465 | unsigned long ret, fault_addr, reference; | ||
466 | struct exception_data *d; | ||
467 | |||
468 | ret = pa_memcpy_internal(dstp, srcp, len); | ||
469 | if (likely(ret == PA_MEMCPY_OK)) | ||
470 | return 0; | ||
471 | |||
472 | /* if a load or store fault occured we can get the faulty addr */ | ||
464 | d = &__get_cpu_var(exception_data); | 473 | d = &__get_cpu_var(exception_data); |
465 | DPRINTF("pmc_store_exc: o_len=%lu fault_addr=%lu o_dst=%lu ret=%lu\n", | 474 | fault_addr = d->fault_addr; |
466 | o_len, d->fault_addr, o_dst, o_len - d->fault_addr + o_dst); | 475 | |
467 | return o_len - d->fault_addr + o_dst; | 476 | /* error in load or store? */ |
477 | if (ret == PA_MEMCPY_LOAD_ERROR) | ||
478 | reference = (unsigned long) srcp; | ||
479 | else | ||
480 | reference = (unsigned long) dstp; | ||
481 | |||
482 | DPRINTF("pa_memcpy: fault type = %lu, len=%lu fault_addr=%lu ref=%lu\n", | ||
483 | ret, len, fault_addr, reference); | ||
484 | |||
485 | if (fault_addr >= reference) | ||
486 | return len - (fault_addr - reference); | ||
487 | else | ||
488 | return len; | ||
468 | } | 489 | } |
469 | 490 | ||
470 | #ifdef __KERNEL__ | 491 | #ifdef __KERNEL__ |