16c9f99dfSJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */ 2f6b354fbSJanosch Frank /* 3f6b354fbSJanosch Frank * Physical memory management related functions and definitions. 4f6b354fbSJanosch Frank * 5f6b354fbSJanosch Frank * Copyright IBM Corp. 2018 6b81a2cd4SJanosch Frank * Author(s): Janosch Frank <frankja@linux.ibm.com> 7f6b354fbSJanosch Frank */ 8eb5a1bbaSCornelia Huck #ifndef _ASMS390X_MEM_H_ 9eb5a1bbaSCornelia Huck #define _ASMS390X_MEM_H_ 105af83aa8SJanis Schoetterl-Glausch #include <asm/arch_def.h> 11*54674baeSNico Boehr #include <asm/facility.h> 125af83aa8SJanis Schoetterl-Glausch 135af83aa8SJanis Schoetterl-Glausch /* create pointer while avoiding compiler warnings */ 145af83aa8SJanis Schoetterl-Glausch #define OPAQUE_PTR(x) ((void *)(((uint64_t)&lowcore) + (x))) 15f6b354fbSJanosch Frank 16d0bfafdfSJanosch Frank #define SKEY_ACC 0xf0 17d0bfafdfSJanosch Frank #define SKEY_FP 0x08 18d0bfafdfSJanosch Frank #define SKEY_RF 0x04 19d0bfafdfSJanosch Frank #define SKEY_CH 0x02 20d0bfafdfSJanosch Frank 21f6b354fbSJanosch Frank union skey { 22f6b354fbSJanosch Frank struct { 23f6b354fbSJanosch Frank uint8_t acc : 4; 24f6b354fbSJanosch Frank uint8_t fp : 1; 25f6b354fbSJanosch Frank uint8_t rf : 1; 26f6b354fbSJanosch Frank uint8_t ch : 1; 27f6b354fbSJanosch Frank uint8_t pad : 1; 28f6b354fbSJanosch Frank } str; 29f6b354fbSJanosch Frank uint8_t val; 30f6b354fbSJanosch Frank }; 31f6b354fbSJanosch Frank 327b9ca995SJanosch Frank static inline void set_storage_key(void *addr, unsigned char skey, int nq) 33f6b354fbSJanosch Frank { 34f6b354fbSJanosch Frank if (nq) 35f6b354fbSJanosch Frank asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0" 36f6b354fbSJanosch Frank : : "d" (skey), "a" (addr)); 37f6b354fbSJanosch Frank else 38f6b354fbSJanosch Frank asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); 39f6b354fbSJanosch Frank } 40f6b354fbSJanosch Frank 417b9ca995SJanosch Frank static inline void *set_storage_key_mb(void *addr, unsigned char skey) 42f6b354fbSJanosch Frank { 43f6b354fbSJanosch Frank assert(test_facility(8)); 44f6b354fbSJanosch Frank 45f6b354fbSJanosch Frank asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],1,0" 46f6b354fbSJanosch Frank : [addr] "+a" (addr) : [skey] "d" (skey)); 47f6b354fbSJanosch Frank return addr; 48f6b354fbSJanosch Frank } 49f6b354fbSJanosch Frank 507b9ca995SJanosch Frank static inline unsigned char get_storage_key(void *addr) 51f6b354fbSJanosch Frank { 52f6b354fbSJanosch Frank unsigned char skey; 53f6b354fbSJanosch Frank 54f6b354fbSJanosch Frank asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr)); 55f6b354fbSJanosch Frank return skey; 56f6b354fbSJanosch Frank } 576f9a99feSJanosch Frank 58429c9cc2SDavid Hildenbrand static inline unsigned char reset_reference_bit(void *addr) 59429c9cc2SDavid Hildenbrand { 60429c9cc2SDavid Hildenbrand int cc; 61429c9cc2SDavid Hildenbrand 62429c9cc2SDavid Hildenbrand asm volatile( 63429c9cc2SDavid Hildenbrand "rrbe 0,%1\n" 64429c9cc2SDavid Hildenbrand "ipm %0\n" 65429c9cc2SDavid Hildenbrand "srl %0,28\n" 66429c9cc2SDavid Hildenbrand : "=d" (cc) : "a" (addr) : "cc"); 67429c9cc2SDavid Hildenbrand return cc; 68429c9cc2SDavid Hildenbrand } 69429c9cc2SDavid Hildenbrand 706f9a99feSJanosch Frank #define PFMF_FSC_4K 0 716f9a99feSJanosch Frank #define PFMF_FSC_1M 1 726f9a99feSJanosch Frank #define PFMF_FSC_2G 2 736f9a99feSJanosch Frank 746f9a99feSJanosch Frank union pfmf_r1 { 756f9a99feSJanosch Frank struct { 766f9a99feSJanosch Frank unsigned long pad0 : 32; 776f9a99feSJanosch Frank unsigned long pad1 : 12; 786f9a99feSJanosch Frank unsigned long pad_fmfi : 2; 796f9a99feSJanosch Frank unsigned long sk : 1; /* set key*/ 806f9a99feSJanosch Frank unsigned long cf : 1; /* clear frame */ 816f9a99feSJanosch Frank unsigned long ui : 1; /* usage indication */ 826f9a99feSJanosch Frank unsigned long fsc : 3; 836f9a99feSJanosch Frank unsigned long pad2 : 1; 846f9a99feSJanosch Frank unsigned long mr : 1; 856f9a99feSJanosch Frank unsigned long mc : 1; 866f9a99feSJanosch Frank unsigned long pad3 : 1; 876f9a99feSJanosch Frank unsigned long key : 8; /* storage keys */ 886f9a99feSJanosch Frank } reg; 896f9a99feSJanosch Frank unsigned long val; 906f9a99feSJanosch Frank }; 916f9a99feSJanosch Frank 926f9a99feSJanosch Frank static inline void *pfmf(unsigned long r1, void *paddr) 936f9a99feSJanosch Frank { 946f9a99feSJanosch Frank register void * addr asm("1") = paddr; 956f9a99feSJanosch Frank 966f9a99feSJanosch Frank asm volatile(".insn rre,0xb9af0000,%[r1],%[addr]" 976f9a99feSJanosch Frank : [addr] "+a" (addr) : [r1] "d" (r1) : "memory"); 986f9a99feSJanosch Frank return addr; 996f9a99feSJanosch Frank } 100f6b354fbSJanosch Frank #endif 101