According to the PARISC 1.1 Instruction Set Reference Manual, PA1.1 does *not* support the depw,z instruction, but only the dep (depw) instruction, e.g.: d5 8b 08 f6 depw,z r11,24,10,r12 # NOT PA1.1 d5 8b 0c f6 depw r11,24,10,r12 # OK for PA1.1 And in the Linux kernel source (arch/parisc/include/asm/assembly.h) I see /* Shift Left - note the r and t can NOT be the same! */ .macro shl r, sa, t dep,z \r, 31-(\sa), 32-(\sa), \t .endm (by the way, this macro isn't used and correctly doesn't compile because of the z completer) But when I disassemble the kernel source code (built for PA1.1), I see lots of depw,z instructions generated by gcc, e.g.: d4 84 09 8c depw,z r4,19,20,r4 So, what's true? For the shl macro, can't r and t not be the same, because then on PA1.1 the shl leaves the rightmost bits untouched/not-zeroed in t? Qemu, which emulates a PA1.1, seems to happily translate even the depw,z instruction. Do we maybe need a patch like the one below (and teach gcc not to emit depw,z) to be fully PA1.1 compatible? Suggestions? Helge The patch below should make the kernel fully PA1.1 compatible. diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h index 60e6f07b7e32..87980fd1c4f1 100644 --- a/arch/parisc/include/asm/assembly.h +++ b/arch/parisc/include/asm/assembly.h @@ -44,7 +44,7 @@ #define LDREGM ldwm #define STREGM stwm #define SHRREG shr -#define SHLREG shlw +#define SHLREG shl #define ANDCM andcm #define COND(x) x #define RP_OFFSET 20 @@ -128,14 +128,15 @@ .endm - /* Shift Left - note the r and t can NOT be the same! */ .macro shl r, sa, t - dep,z \r, 31-(\sa), 32-(\sa), \t - .endm - - /* The PA 2.0 shift left */ - .macro shlw r, sa, t +#ifdef CONFIG_PA20 + /* The PA 2.0 shift left (shlw) */ depw,z \r, 31-(\sa), 32-(\sa), \t +#else + /* PA 1.0 Shift Left - note the r and t can NOT be the same! */ + copy %r0, \t + dep \r, 31-(\sa), 32-(\sa), \t +#endif .endm /* And the PA 2.0W shift left */ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 1b4732e20137..dca15d4d1d70 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -421,12 +421,16 @@ # endif #endif dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ - copy %r0,\pte ldw,s \index(\pmd),\pmd bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault dep %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ - copy \pmd,%r9 - SHLREG %r9,PxD_VALUE_SHIFT,\pmd +#ifdef CONFIG_PA20 + SHLREG \pmd,PxD_VALUE_SHIFT,\pmd +#else + copy \pmd,\pte + SHLREG \pte,PxD_VALUE_SHIFT,\pmd +#endif + copy %r0,\pte extru \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */ @@ -447,7 +451,6 @@ .macro L3_ptep pgd,pte,index,va,fault #if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */ extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index - copy %r0,\pte extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 ldw,s \index(\pgd),\pgd extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 5f7e57fcaeef..37fb08a48504 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -570,8 +570,8 @@ lws_compare_and_swap: /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) and add to the lock table offset. */ - shlw %r20, 4, %r20 - add %r20, %r28, %r20 + SHLREG %r20, 4, %r21 + add %r21, %r28, %r20 # if ENABLE_LWS_DEBUG /* @@ -705,7 +705,7 @@ lws_compare_and_swap_2: /* Jump to the functions which will load the old and new values into registers depending on the their size */ - shlw %r23, 2, %r29 + SHLREG %r23, 2, %r29 blr %r29, %r0 nop @@ -762,8 +762,8 @@ cas2_lock_start: /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) and add to the lock table offset. */ - shlw %r20, 4, %r20 - add %r20, %r28, %r20 + SHLREG %r20, 4, %r21 + add %r21, %r28, %r20 rsm PSW_SM_I, %r0 /* Disable interrupts */ /* COW breaks can cause contention on UP systems */