1527dcdccSDavid Howells #ifndef __PARISC_LDCW_H 2527dcdccSDavid Howells #define __PARISC_LDCW_H 3527dcdccSDavid Howells 4527dcdccSDavid Howells #ifndef CONFIG_PA20 5527dcdccSDavid Howells /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, 6527dcdccSDavid Howells and GCC only guarantees 8-byte alignment for stack locals, we can't 7527dcdccSDavid Howells be assured of 16-byte alignment for atomic lock data even if we 8527dcdccSDavid Howells specify "__attribute ((aligned(16)))" in the type declaration. So, 9527dcdccSDavid Howells we use a struct containing an array of four ints for the atomic lock 10527dcdccSDavid Howells type and dynamically select the 16-byte aligned int from the array 11527dcdccSDavid Howells for the semaphore. */ 12527dcdccSDavid Howells 13527dcdccSDavid Howells #define __PA_LDCW_ALIGNMENT 16 14527dcdccSDavid Howells #define __ldcw_align(a) ({ \ 15527dcdccSDavid Howells unsigned long __ret = (unsigned long) &(a)->lock[0]; \ 16527dcdccSDavid Howells __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \ 17527dcdccSDavid Howells & ~(__PA_LDCW_ALIGNMENT - 1); \ 18527dcdccSDavid Howells (volatile unsigned int *) __ret; \ 19527dcdccSDavid Howells }) 20527dcdccSDavid Howells #define __LDCW "ldcw" 21527dcdccSDavid Howells 22527dcdccSDavid Howells #else /*CONFIG_PA20*/ 23527dcdccSDavid Howells /* From: "Jim Hull" <jim.hull of hp.com> 24527dcdccSDavid Howells I've attached a summary of the change, but basically, for PA 2.0, as 25527dcdccSDavid Howells long as the ",CO" (coherent operation) completer is specified, then the 26527dcdccSDavid Howells 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead 27527dcdccSDavid Howells they only require "natural" alignment (4-byte for ldcw, 8-byte for 28527dcdccSDavid Howells ldcd). */ 29527dcdccSDavid Howells 30527dcdccSDavid Howells #define __PA_LDCW_ALIGNMENT 4 31527dcdccSDavid Howells #define __ldcw_align(a) (&(a)->slock) 32527dcdccSDavid Howells #define __LDCW "ldcw,co" 33527dcdccSDavid Howells 34527dcdccSDavid Howells #endif /*!CONFIG_PA20*/ 35527dcdccSDavid Howells 36*45db0738SJohn David Anglin /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. 37*45db0738SJohn David Anglin We don't explicitly expose that "*a" may be written as reload 38*45db0738SJohn David Anglin fails to find a register in class R1_REGS when "a" needs to be 39*45db0738SJohn David Anglin reloaded when generating 64-bit PIC code. Instead, we clobber 40*45db0738SJohn David Anglin memory to indicate to the compiler that the assembly code reads 41*45db0738SJohn David Anglin or writes to items other than those listed in the input and output 42*45db0738SJohn David Anglin operands. This may pessimize the code somewhat but __ldcw is 43*45db0738SJohn David Anglin usually used within code blocks surrounded by memory barriors. */ 44527dcdccSDavid Howells #define __ldcw(a) ({ \ 45527dcdccSDavid Howells unsigned __ret; \ 46*45db0738SJohn David Anglin __asm__ __volatile__(__LDCW " 0(%1),%0" \ 47*45db0738SJohn David Anglin : "=r" (__ret) : "r" (a) : "memory"); \ 48527dcdccSDavid Howells __ret; \ 49527dcdccSDavid Howells }) 50527dcdccSDavid Howells 51527dcdccSDavid Howells #ifdef CONFIG_SMP 52527dcdccSDavid Howells # define __lock_aligned __attribute__((__section__(".data..lock_aligned"))) 53527dcdccSDavid Howells #endif 54527dcdccSDavid Howells 55527dcdccSDavid Howells #endif /* __PARISC_LDCW_H */ 56