Commit 723ec731de880a76a004a304b62bf8d0f96435d8
Committed by
Paul Mackerras
1 parent
27565903e9
Exists in
master
and in
7 other branches
[POWERPC] EDAC ECC software scrubber
Implements the per arch atomic_scrub() that EDAC uses for software ECC scrubbing. It reads memory and then writes back the original value, allowing the hardware to detect and correct memory errors. Signed-off-by: Dave Jiang <djiang@mvista.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 1 changed file with 40 additions and 0 deletions Side-by-side Diff
include/asm-powerpc/edac.h
1 | +/* | |
2 | + * PPC EDAC common defs | |
3 | + * | |
4 | + * Author: Dave Jiang <djiang@mvista.com> | |
5 | + * | |
6 | + * 2007 (c) MontaVista Software, Inc. This file is licensed under | |
7 | + * the terms of the GNU General Public License version 2. This program | |
8 | + * is licensed "as is" without any warranty of any kind, whether express | |
9 | + * or implied. | |
10 | + */ | |
11 | +#ifndef ASM_EDAC_H | |
12 | +#define ASM_EDAC_H | |
13 | +/* | |
14 | + * ECC atomic, DMA, SMP and interrupt safe scrub function. | |
15 | + * Implements the per arch atomic_scrub() that EDAC use for software | |
16 | + * ECC scrubbing. It reads memory and then writes back the original | |
17 | + * value, allowing the hardware to detect and correct memory errors. | |
18 | + */ | |
19 | +static __inline__ void atomic_scrub(void *va, u32 size) | |
20 | +{ | |
21 | + unsigned int *virt_addr = va; | |
22 | + unsigned int temp; | |
23 | + unsigned int i; | |
24 | + | |
25 | + for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) { | |
26 | + /* Very carefully read and write to memory atomically | |
27 | + * so we are interrupt, DMA and SMP safe. | |
28 | + */ | |
29 | + __asm__ __volatile__ ("\n\ | |
30 | + 1: lwarx %0,0,%1\n\ | |
31 | + stwcx. %0,0,%1\n\ | |
32 | + bne- 1b\n\ | |
33 | + isync" | |
34 | + : "=&r"(temp) | |
35 | + : "r"(virt_addr) | |
36 | + : "cr0", "memory"); | |
37 | + } | |
38 | +} | |
39 | + | |
40 | +#endif |