xref: /kvm-unit-tests/lib/s390x/asm/mem.h (revision d1e2a8e2d0d5856f1a6ce23ea3f044a1532eab40)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Physical memory management related functions and definitions.
4  *
5  * Copyright IBM Corp. 2018
6  * Author(s): Janosch Frank <frankja@linux.ibm.com>
7  */
8 #ifndef _ASMS390X_MEM_H_
9 #define _ASMS390X_MEM_H_
10 #include <asm/arch_def.h>
11 #include <asm/facility.h>
12 
13 /* create pointer while avoiding compiler warnings */
14 #define OPAQUE_PTR(x) ((void *)(((uint64_t)&lowcore) + (x)))
15 
16 #define SKEY_ACC	0xf0
17 #define SKEY_FP		0x08
18 #define SKEY_RF		0x04
19 #define SKEY_CH		0x02
20 
21 union skey {
22 	struct {
23 		uint8_t acc : 4;
24 		uint8_t fp : 1;
25 		uint8_t rf : 1;
26 		uint8_t ch : 1;
27 		uint8_t pad : 1;
28 	} str;
29 	uint8_t val;
30 };
31 
set_storage_key(void * addr,unsigned char skey,int nq)32 static inline void set_storage_key(void *addr, unsigned char skey, int nq)
33 {
34 	if (nq)
35 		asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
36 			     : : "d" (skey), "a" (addr));
37 	else
38 		asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
39 }
40 
set_storage_key_mb(void * addr,unsigned char skey)41 static inline void *set_storage_key_mb(void *addr, unsigned char skey)
42 {
43 	assert(test_facility(8));
44 
45 	asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],1,0"
46 		     : [addr] "+a" (addr) : [skey] "d" (skey));
47 	return addr;
48 }
49 
get_storage_key(void * addr)50 static inline unsigned char get_storage_key(void *addr)
51 {
52 	unsigned char skey;
53 
54 	asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr));
55 	return skey;
56 }
57 
reset_reference_bit(void * addr)58 static inline unsigned char reset_reference_bit(void *addr)
59 {
60 	int cc;
61 
62 	asm volatile(
63 		"rrbe	0,%1\n"
64 		"ipm	%0\n"
65 		"srl	%0,28\n"
66 		: "=d" (cc) : "a" (addr) : "cc");
67 	return cc;
68 }
69 
70 #define PFMF_FSC_4K 0
71 #define PFMF_FSC_1M 1
72 #define PFMF_FSC_2G 2
73 
74 union pfmf_r1 {
75 	struct {
76 		unsigned long pad0 : 32;
77 		unsigned long pad1 : 12;
78 		unsigned long pad_fmfi : 2;
79 		unsigned long sk : 1; /* set key*/
80 		unsigned long cf : 1; /* clear frame */
81 		unsigned long ui : 1; /* usage indication */
82 		unsigned long fsc : 3;
83 		unsigned long pad2 : 1;
84 		unsigned long mr : 1;
85 		unsigned long mc : 1;
86 		unsigned long pad3 : 1;
87 		unsigned long key : 8; /* storage keys */
88 	} reg;
89 	unsigned long val;
90 };
91 
pfmf(unsigned long r1,void * paddr)92 static inline void *pfmf(unsigned long r1, void *paddr)
93 {
94 	register void * addr asm("1") = paddr;
95 
96 	asm volatile(".insn rre,0xb9af0000,%[r1],%[addr]"
97 		     : [addr] "+a" (addr) : [r1] "d" (r1) : "memory");
98 	return addr;
99 }
100 #endif
101