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
set_storage_key(void * addr,unsigned char skey,int nq)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
set_storage_key_mb(void * addr,unsigned char skey)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
get_storage_key(void * addr)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
reset_reference_bit(void * addr)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
pfmf(unsigned long r1,void * paddr)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