summaryrefslogtreecommitdiff
path: root/arch/sparc64/lib/mb.S
blob: 4004f748619f0cc1dcf1b5b342a0e6c0d9eb4e8c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* mb.S: Out of line memory barriers.
 *
 * Copyright (C) 2005 David S. Miller (davem@davemloft.net)
 */

	/* These are here in an effort to more fully work around
	 * Spitfire Errata #51.  Essentially, if a memory barrier
	 * occurs soon after a mispredicted branch, the chip can stop
	 * executing instructions until a trap occurs.  Therefore, if
	 * interrupts are disabled, the chip can hang forever.
	 *
	 * It used to be believed that the memory barrier had to be
	 * right in the delay slot, but a case has been traced
	 * recently wherein the memory barrier was one instruction
	 * after the branch delay slot and the chip still hung.  The
	 * offending sequence was the following in sym_wakeup_done()
	 * of the sym53c8xx_2 driver:
	 *
	 *	call	sym_ccb_from_dsa, 0
	 *	 movge	%icc, 0, %l0
	 *	brz,pn	%o0, .LL1303
	 *	 mov	%o0, %l2
	 *	membar	#LoadLoad
	 *
	 * The branch has to be mispredicted for the bug to occur.
	 * Therefore, we put the memory barrier explicitly into a
	 * "branch always, predicted taken" delay slot to avoid the
	 * problem case.
	 */

	.text

99:	retl
	 nop

	.globl	mb
mb:	ba,pt	%xcc, 99b
	 membar	#LoadLoad | #LoadStore | #StoreStore | #StoreLoad
	.size	mb, .-mb

	.globl	rmb
rmb:	ba,pt	%xcc, 99b
	 membar	#LoadLoad
	.size	rmb, .-rmb

	.globl	wmb
wmb:	ba,pt	%xcc, 99b
	 membar	#StoreStore
	.size	wmb, .-wmb

	.globl	membar_storeload
membar_storeload:
	ba,pt	%xcc, 99b
	 membar	#StoreLoad
	.size	membar_storeload, .-membar_storeload

	.globl	membar_storeload_storestore
membar_storeload_storestore:
	ba,pt	%xcc, 99b
	 membar	#StoreLoad | #StoreStore
	.size	membar_storeload_storestore, .-membar_storeload_storestore

	.globl	membar_storeload_loadload
membar_storeload_loadload:
	ba,pt	%xcc, 99b
	 membar	#StoreLoad | #LoadLoad
	.size	membar_storeload_loadload, .-membar_storeload_loadload

	.globl	membar_storestore_loadstore
membar_storestore_loadstore:
	ba,pt	%xcc, 99b
	 membar	#StoreStore | #LoadStore
	.size	membar_storestore_loadstore, .-membar_storestore_loadstore