1*4f8ce3b3Sriastradh/* $NetBSD: membar_ops.S,v 1.6 2022/04/09 23:32:52 riastradh Exp $ */ 2bc7bf35cSad 3bc7bf35cSad/*- 4bc7bf35cSad * Copyright (c) 2007 The NetBSD Foundation, Inc. 5bc7bf35cSad * All rights reserved. 6bc7bf35cSad * 7bc7bf35cSad * This code is derived from software contributed to The NetBSD Foundation 8bc7bf35cSad * by Jason R. Thorpe, and by Andrew Doran. 9bc7bf35cSad * 10bc7bf35cSad * Redistribution and use in source and binary forms, with or without 11bc7bf35cSad * modification, are permitted provided that the following conditions 12bc7bf35cSad * are met: 13bc7bf35cSad * 1. Redistributions of source code must retain the above copyright 14bc7bf35cSad * notice, this list of conditions and the following disclaimer. 15bc7bf35cSad * 2. Redistributions in binary form must reproduce the above copyright 16bc7bf35cSad * notice, this list of conditions and the following disclaimer in the 17bc7bf35cSad * documentation and/or other materials provided with the distribution. 18bc7bf35cSad * 19bc7bf35cSad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20bc7bf35cSad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21bc7bf35cSad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22bc7bf35cSad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23bc7bf35cSad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24bc7bf35cSad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25bc7bf35cSad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26bc7bf35cSad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27bc7bf35cSad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28bc7bf35cSad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29bc7bf35cSad * POSSIBILITY OF SUCH DAMAGE. 30bc7bf35cSad */ 31bc7bf35cSad 32bc7bf35cSad#include "atomic_op_asm.h" 33bc7bf35cSad 34*4f8ce3b3Sriastradh__RCSID("$NetBSD: membar_ops.S,v 1.6 2022/04/09 23:32:52 riastradh Exp $") 35bc7bf35cSad 36cf88c389Smatt .text 37bc7bf35cSad 38*4f8ce3b3SriastradhENTRY(_membar_acquire) 39*4f8ce3b3Sriastradh /* 40*4f8ce3b3Sriastradh * It is tempting to use isync to order load-before-load/store. 41*4f8ce3b3Sriastradh * However, isync orders prior loads only if their value flows 42*4f8ce3b3Sriastradh * into a control-flow dependency prior to the isync: 43*4f8ce3b3Sriastradh * 44*4f8ce3b3Sriastradh * `[I]f an isync follows a conditional Branch instruction 45*4f8ce3b3Sriastradh * that depends on the value returned by a preceding Load 46*4f8ce3b3Sriastradh * instruction, the load on which the Branch depends is 47*4f8ce3b3Sriastradh * performed before any loads caused by instructions 48*4f8ce3b3Sriastradh * following the isync. This applies even if the effects 49*4f8ce3b3Sriastradh * of the ``dependency'' are independent of the value 50*4f8ce3b3Sriastradh * loaded (e.g., the value is compared to itself and the 51*4f8ce3b3Sriastradh * Branch tests the EQ bit in the selected CR field), and 52*4f8ce3b3Sriastradh * even if the branch target is the sequentially next 53*4f8ce3b3Sriastradh * instruction.' 54*4f8ce3b3Sriastradh * 55*4f8ce3b3Sriastradh * --PowerPC Virtual Environment Architecture, Book II, 56*4f8ce3b3Sriastradh * Version 2.01, December 2003, 1.7.1 `Storage Access 57*4f8ce3b3Sriastradh * Ordering', p. 7. 58*4f8ce3b3Sriastradh * 59*4f8ce3b3Sriastradh * We are required here, however, to order _all_ prior loads, 60*4f8ce3b3Sriastradh * even if they do not flow into any control flow dependency. 61*4f8ce3b3Sriastradh * For example: 62*4f8ce3b3Sriastradh * 63*4f8ce3b3Sriastradh * x = *p; 64*4f8ce3b3Sriastradh * membar_acquire(); 65*4f8ce3b3Sriastradh * if (x) goto foo; 66*4f8ce3b3Sriastradh * 67*4f8ce3b3Sriastradh * This can't be implemented by: 68*4f8ce3b3Sriastradh * 69*4f8ce3b3Sriastradh * lwz x, p 70*4f8ce3b3Sriastradh * isync 71*4f8ce3b3Sriastradh * cmpwi x, 0 72*4f8ce3b3Sriastradh * bne foo 73*4f8ce3b3Sriastradh * 74*4f8ce3b3Sriastradh * isync doesn't work here because there's no conditional 75*4f8ce3b3Sriastradh * dependency on x between the lwz x, p and the isync. 76*4f8ce3b3Sriastradh * 77*4f8ce3b3Sriastradh * isync would only work if it followed the branch: 78*4f8ce3b3Sriastradh * 79*4f8ce3b3Sriastradh * lwz x, p 80*4f8ce3b3Sriastradh * isync 81*4f8ce3b3Sriastradh * cmpwi x, 0 82*4f8ce3b3Sriastradh * bne foo 83*4f8ce3b3Sriastradh * ... 84*4f8ce3b3Sriastradh * foo: isync 85*4f8ce3b3Sriastradh * ... 86*4f8ce3b3Sriastradh * 87*4f8ce3b3Sriastradh * lwsync orders everything except store-before-load, so it 88*4f8ce3b3Sriastradh * serves here -- see below in membar_release in lwsync. 89*4f8ce3b3Sriastradh * Except we can't use it on booke, so use sync for now. 90*4f8ce3b3Sriastradh */ 91bc7bf35cSad sync 92bc7bf35cSad blr 93*4f8ce3b3SriastradhEND(_membar_acquire) 94*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_acquire,_membar_acquire) 95bc7bf35cSad 96*4f8ce3b3SriastradhENTRY(_membar_release) 97*4f8ce3b3Sriastradh /* 98*4f8ce3b3Sriastradh * `The memory barrier provides an ordering function for 99*4f8ce3b3Sriastradh * the storage accesses caused by Load, Store, and dcbz 100*4f8ce3b3Sriastradh * instructions that are executed by the processor 101*4f8ce3b3Sriastradh * executing the [lwsync] instruction and for which the 102*4f8ce3b3Sriastradh * specified storage location is in storage that is 103*4f8ce3b3Sriastradh * Memory Coherence Required and is neither Write Through 104*4f8ce3b3Sriastradh * Required nor Caching Inhibited. The applicable pairs 105*4f8ce3b3Sriastradh * are all pairs a_i, b_j of such accesses except those 106*4f8ce3b3Sriastradh * in which a_i is an access caused by a Store or dcbz 107*4f8ce3b3Sriastradh * instruction and b_j is an access caused by a Load 108*4f8ce3b3Sriastradh * instruction.' 109*4f8ce3b3Sriastradh * 110*4f8ce3b3Sriastradh * --PowerPC Virtual Environment Architecture, Book II, 111*4f8ce3b3Sriastradh * Version 2.01, December 2003, 3.3.3 `Memory Barrier 112*4f8ce3b3Sriastradh * Instructions', p. 25. 113*4f8ce3b3Sriastradh * 114*4f8ce3b3Sriastradh * In brief, lwsync is an acquire-release barrier -- it orders 115*4f8ce3b3Sriastradh * load-before-load/store and load/store-before-store, but not 116*4f8ce3b3Sriastradh * store-before-load. Except we can't use it on booke, so use 117*4f8ce3b3Sriastradh * sync for now. 118*4f8ce3b3Sriastradh */ 119*4f8ce3b3Sriastradh sync 120*4f8ce3b3Sriastradh blr 121*4f8ce3b3SriastradhEND(_membar_release) 122*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_release,_membar_release) 123*4f8ce3b3Sriastradh 124*4f8ce3b3SriastradhENTRY(_membar_sync) 125*4f8ce3b3Sriastradh /* 126*4f8ce3b3Sriastradh * sync, or `heavyweight sync', is a full sequential 127*4f8ce3b3Sriastradh * consistency barrier. 128*4f8ce3b3Sriastradh */ 129*4f8ce3b3Sriastradh sync 130*4f8ce3b3Sriastradh blr 131*4f8ce3b3SriastradhEND(_membar_sync) 132*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_sync,_membar_sync) 133*4f8ce3b3Sriastradh 134*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_producer,_membar_release) 135*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_producer,_membar_release) 136*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_consumer,_membar_acquire) 137*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_consumer,_membar_acquire) 138*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_enter,_membar_sync) 139*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_enter,_membar_sync) 140*4f8ce3b3SriastradhATOMIC_OP_ALIAS(membar_exit,_membar_release) 141*4f8ce3b3SriastradhSTRONG_ALIAS(_membar_exit,_membar_release) 142