1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __PARISC_SPECIAL_INSNS_H 3 #define __PARISC_SPECIAL_INSNS_H 4 5 #define lpa(va) ({ \ 6 unsigned long pa; \ 7 __asm__ __volatile__( \ 8 "copy %%r0,%0\n" \ 9 "8:\tlpa %%r0(%1),%0\n" \ 10 "9:\n" \ 11 ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ 12 "or %%r0,%%r0,%%r0") \ 13 : "=&r" (pa) \ 14 : "r" (va) \ 15 : "memory" \ 16 ); \ 17 pa; \ 18 }) 19 20 #define lpa_user(va) ({ \ 21 unsigned long pa; \ 22 __asm__ __volatile__( \ 23 "copy %%r0,%0\n" \ 24 "8:\tlpa %%r0(%%sr3,%1),%0\n" \ 25 "9:\n" \ 26 ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ 27 "or %%r0,%%r0,%%r0") \ 28 : "=&r" (pa) \ 29 : "r" (va) \ 30 : "memory" \ 31 ); \ 32 pa; \ 33 }) 34 35 /** 36 * prober_user() - Probe user read access 37 * @sr: Space regster. 38 * @va: Virtual address. 39 * 40 * Return: Non-zero if address is accessible. 41 * 42 * Due to the way _PAGE_READ is handled in TLB entries, we need 43 * a special check to determine whether a user address is accessible. 44 * The ldb instruction does the initial access check. If it is 45 * successful, the probe instruction checks user access rights. 46 */ 47 #define prober_user(sr, va) ({ \ 48 unsigned long read_allowed; \ 49 __asm__ __volatile__( \ 50 "copy %%r0,%0\n" \ 51 "8:\tldb 0(%%sr%1,%2),%%r0\n" \ 52 "\tproberi (%%sr%1,%2),%3,%0\n" \ 53 "9:\n" \ 54 ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ 55 "or %%r0,%%r0,%%r0") \ 56 : "=&r" (read_allowed) \ 57 : "i" (sr), "r" (va), "i" (PRIV_USER) \ 58 : "memory" \ 59 ); \ 60 read_allowed; \ 61 }) 62 63 #define CR_EIEM 15 /* External Interrupt Enable Mask */ 64 #define CR_CR16 16 /* CR16 Interval Timer */ 65 #define CR_EIRR 23 /* External Interrupt Request Register */ 66 67 #define mfctl(reg) ({ \ 68 unsigned long cr; \ 69 __asm__ __volatile__( \ 70 "mfctl %1,%0" : \ 71 "=r" (cr) : "i" (reg) \ 72 ); \ 73 cr; \ 74 }) 75 76 #define mtctl(gr, cr) \ 77 __asm__ __volatile__("mtctl %0,%1" \ 78 : /* no outputs */ \ 79 : "r" (gr), "i" (cr) : "memory") 80 81 #define get_eiem() mfctl(CR_EIEM) 82 #define set_eiem(val) mtctl(val, CR_EIEM) 83 84 #define mfsp(reg) ({ \ 85 unsigned long cr; \ 86 __asm__ __volatile__( \ 87 "mfsp %%sr%1,%0" \ 88 : "=r" (cr) : "i"(reg) \ 89 ); \ 90 cr; \ 91 }) 92 93 #define mtsp(val, cr) \ 94 { if (__builtin_constant_p(val) && ((val) == 0)) \ 95 __asm__ __volatile__("mtsp %%r0,%0" : : "i" (cr) : "memory"); \ 96 else \ 97 __asm__ __volatile__("mtsp %0,%1" \ 98 : /* no outputs */ \ 99 : "r" (val), "i" (cr) : "memory"); } 100 101 #endif /* __PARISC_SPECIAL_INSNS_H */ 102