aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-parisc/system.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-parisc/system.h')
-rw-r--r--include/asm-parisc/system.h48
1 files changed, 23 insertions, 25 deletions
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index 26ff844a21c1..f3928d3a80cb 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -138,13 +138,7 @@ static inline void set_eiem(unsigned long val)
138#define set_wmb(var, value) do { var = value; wmb(); } while (0) 138#define set_wmb(var, value) do { var = value; wmb(); } while (0)
139 139
140 140
141/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ 141#ifndef CONFIG_PA20
142#define __ldcw(a) ({ \
143 unsigned __ret; \
144 __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
145 __ret; \
146})
147
148/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, 142/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
149 and GCC only guarantees 8-byte alignment for stack locals, we can't 143 and GCC only guarantees 8-byte alignment for stack locals, we can't
150 be assured of 16-byte alignment for atomic lock data even if we 144 be assured of 16-byte alignment for atomic lock data even if we
@@ -152,37 +146,41 @@ static inline void set_eiem(unsigned long val)
152 we use a struct containing an array of four ints for the atomic lock 146 we use a struct containing an array of four ints for the atomic lock
153 type and dynamically select the 16-byte aligned int from the array 147 type and dynamically select the 16-byte aligned int from the array
154 for the semaphore. */ 148 for the semaphore. */
149
155#define __PA_LDCW_ALIGNMENT 16 150#define __PA_LDCW_ALIGNMENT 16
156#define __ldcw_align(a) ({ \ 151#define __ldcw_align(a) ({ \
157 unsigned long __ret = (unsigned long) &(a)->lock[0]; \ 152 unsigned long __ret = (unsigned long) &(a)->lock[0]; \
158 __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ 153 __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
159 (volatile unsigned int *) __ret; \ 154 (volatile unsigned int *) __ret; \
160}) 155})
156#define LDCW "ldcw"
161 157
162#ifdef CONFIG_SMP 158#else /*CONFIG_PA20*/
163# define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) 159/* From: "Jim Hull" <jim.hull of hp.com>
164#endif 160 I've attached a summary of the change, but basically, for PA 2.0, as
161 long as the ",CO" (coherent operation) completer is specified, then the
162 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
163 they only require "natural" alignment (4-byte for ldcw, 8-byte for
164 ldcd). */
165 165
166#define KERNEL_START (0x10100000 - 0x1000) 166#define __PA_LDCW_ALIGNMENT 4
167#define __ldcw_align(a) ((volatile unsigned int *)a)
168#define LDCW "ldcw,co"
167 169
168/* This is for the serialisation of PxTLB broadcasts. At least on the 170#endif /*!CONFIG_PA20*/
169 * N class systems, only one PxTLB inter processor broadcast can be
170 * active at any one time on the Merced bus. This tlb purge
171 * synchronisation is fairly lightweight and harmless so we activate
172 * it on all SMP systems not just the N class. */
173#ifdef CONFIG_SMP
174extern spinlock_t pa_tlb_lock;
175 171
176#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) 172/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
177#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) 173#define __ldcw(a) ({ \
178 174 unsigned __ret; \
179#else 175 __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \
180 176 __ret; \
181#define purge_tlb_start(x) do { } while(0) 177})
182#define purge_tlb_end(x) do { } while (0)
183 178
179#ifdef CONFIG_SMP
180# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
184#endif 181#endif
185 182
183#define KERNEL_START (0x10100000 - 0x1000)
186#define arch_align_stack(x) (x) 184#define arch_align_stack(x) (x)
187 185
188#endif 186#endif