1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 294cdda6bSArnaldo Carvalho de Melo #ifndef __TOOLS_LINUX_SPARC64_BARRIER_H 394cdda6bSArnaldo Carvalho de Melo #define __TOOLS_LINUX_SPARC64_BARRIER_H 494cdda6bSArnaldo Carvalho de Melo 594cdda6bSArnaldo Carvalho de Melo /* Copied from the kernel sources to tools/: 694cdda6bSArnaldo Carvalho de Melo * 794cdda6bSArnaldo Carvalho de Melo * These are here in an effort to more fully work around Spitfire Errata 894cdda6bSArnaldo Carvalho de Melo * #51. Essentially, if a memory barrier occurs soon after a mispredicted 994cdda6bSArnaldo Carvalho de Melo * branch, the chip can stop executing instructions until a trap occurs. 1094cdda6bSArnaldo Carvalho de Melo * Therefore, if interrupts are disabled, the chip can hang forever. 1194cdda6bSArnaldo Carvalho de Melo * 1294cdda6bSArnaldo Carvalho de Melo * It used to be believed that the memory barrier had to be right in the 1394cdda6bSArnaldo Carvalho de Melo * delay slot, but a case has been traced recently wherein the memory barrier 1494cdda6bSArnaldo Carvalho de Melo * was one instruction after the branch delay slot and the chip still hung. 1594cdda6bSArnaldo Carvalho de Melo * The offending sequence was the following in sym_wakeup_done() of the 1694cdda6bSArnaldo Carvalho de Melo * sym53c8xx_2 driver: 1794cdda6bSArnaldo Carvalho de Melo * 1894cdda6bSArnaldo Carvalho de Melo * call sym_ccb_from_dsa, 0 1994cdda6bSArnaldo Carvalho de Melo * movge %icc, 0, %l0 2094cdda6bSArnaldo Carvalho de Melo * brz,pn %o0, .LL1303 2194cdda6bSArnaldo Carvalho de Melo * mov %o0, %l2 2294cdda6bSArnaldo Carvalho de Melo * membar #LoadLoad 2394cdda6bSArnaldo Carvalho de Melo * 2494cdda6bSArnaldo Carvalho de Melo * The branch has to be mispredicted for the bug to occur. Therefore, we put 2594cdda6bSArnaldo Carvalho de Melo * the memory barrier explicitly into a "branch always, predicted taken" 2694cdda6bSArnaldo Carvalho de Melo * delay slot to avoid the problem case. 2794cdda6bSArnaldo Carvalho de Melo */ 2894cdda6bSArnaldo Carvalho de Melo #define membar_safe(type) \ 2994cdda6bSArnaldo Carvalho de Melo do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ 3094cdda6bSArnaldo Carvalho de Melo " membar " type "\n" \ 3194cdda6bSArnaldo Carvalho de Melo "1:\n" \ 3294cdda6bSArnaldo Carvalho de Melo : : : "memory"); \ 3394cdda6bSArnaldo Carvalho de Melo } while (0) 3494cdda6bSArnaldo Carvalho de Melo 3594cdda6bSArnaldo Carvalho de Melo /* The kernel always executes in TSO memory model these days, 3694cdda6bSArnaldo Carvalho de Melo * and furthermore most sparc64 chips implement more stringent 3794cdda6bSArnaldo Carvalho de Melo * memory ordering than required by the specifications. 3894cdda6bSArnaldo Carvalho de Melo */ 3994cdda6bSArnaldo Carvalho de Melo #define mb() membar_safe("#StoreLoad") 4094cdda6bSArnaldo Carvalho de Melo #define rmb() __asm__ __volatile__("":::"memory") 4194cdda6bSArnaldo Carvalho de Melo #define wmb() __asm__ __volatile__("":::"memory") 4294cdda6bSArnaldo Carvalho de Melo 4309d62154SDaniel Borkmann #define smp_store_release(p, v) \ 4409d62154SDaniel Borkmann do { \ 4509d62154SDaniel Borkmann barrier(); \ 4609d62154SDaniel Borkmann WRITE_ONCE(*p, v); \ 4709d62154SDaniel Borkmann } while (0) 4809d62154SDaniel Borkmann 4909d62154SDaniel Borkmann #define smp_load_acquire(p) \ 5009d62154SDaniel Borkmann ({ \ 5109d62154SDaniel Borkmann typeof(*p) ___p1 = READ_ONCE(*p); \ 5209d62154SDaniel Borkmann barrier(); \ 5309d62154SDaniel Borkmann ___p1; \ 5409d62154SDaniel Borkmann }) 5509d62154SDaniel Borkmann 5694cdda6bSArnaldo Carvalho de Melo #endif /* !(__TOOLS_LINUX_SPARC64_BARRIER_H) */ 57