linux/arch/mips/include/asm/edac.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef ASM_EDAC_H
   3#define ASM_EDAC_H
   4
   5#include <asm/compiler.h>
   6
   7/* ECC atomic, DMA, SMP and interrupt safe scrub function */
   8
   9static inline void edac_atomic_scrub(void *va, u32 size)
  10{
  11        unsigned long *virt_addr = va;
  12        unsigned long temp;
  13        u32 i;
  14
  15        for (i = 0; i < size / sizeof(unsigned long); i++) {
  16                /*
  17                 * Very carefully read and write to memory atomically
  18                 * so we are interrupt, DMA and SMP safe.
  19                 *
  20                 * Intel: asm("lock; addl $0, %0"::"m"(*virt_addr));
  21                 */
  22
  23                __asm__ __volatile__ (
  24                "       .set    mips2                                   \n"
  25                "1:     ll      %0, %1          # edac_atomic_scrub     \n"
  26                "       addu    %0, $0                                  \n"
  27                "       sc      %0, %1                                  \n"
  28                "       beqz    %0, 1b                                  \n"
  29                "       .set    mips0                                   \n"
  30                : "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*virt_addr)
  31                : GCC_OFF_SMALL_ASM() (*virt_addr));
  32
  33                virt_addr++;
  34        }
  35}
  36
  37#endif
  38