xref: /kvm-unit-tests/lib/s390x/asm/mem.h (revision 429c9cc273afdedc6a652f85f9a06511410100e0)
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 
11 #define SKEY_ACC	0xf0
12 #define SKEY_FP		0x08
13 #define SKEY_RF		0x04
14 #define SKEY_CH		0x02
15 
16 union skey {
17 	struct {
18 		uint8_t acc : 4;
19 		uint8_t fp : 1;
20 		uint8_t rf : 1;
21 		uint8_t ch : 1;
22 		uint8_t pad : 1;
23 	} str;
24 	uint8_t val;
25 };
26 
27 static inline void set_storage_key(void *addr, unsigned char skey, int nq)
28 {
29 	if (nq)
30 		asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
31 			     : : "d" (skey), "a" (addr));
32 	else
33 		asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
34 }
35 
36 static inline void *set_storage_key_mb(void *addr, unsigned char skey)
37 {
38 	assert(test_facility(8));
39 
40 	asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],1,0"
41 		     : [addr] "+a" (addr) : [skey] "d" (skey));
42 	return addr;
43 }
44 
45 static inline unsigned char get_storage_key(void *addr)
46 {
47 	unsigned char skey;
48 
49 	asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr));
50 	return skey;
51 }
52 
53 static inline unsigned char reset_reference_bit(void *addr)
54 {
55 	int cc;
56 
57 	asm volatile(
58 		"rrbe	0,%1\n"
59 		"ipm	%0\n"
60 		"srl	%0,28\n"
61 		: "=d" (cc) : "a" (addr) : "cc");
62 	return cc;
63 }
64 
65 #define PFMF_FSC_4K 0
66 #define PFMF_FSC_1M 1
67 #define PFMF_FSC_2G 2
68 
69 union pfmf_r1 {
70 	struct {
71 		unsigned long pad0 : 32;
72 		unsigned long pad1 : 12;
73 		unsigned long pad_fmfi : 2;
74 		unsigned long sk : 1; /* set key*/
75 		unsigned long cf : 1; /* clear frame */
76 		unsigned long ui : 1; /* usage indication */
77 		unsigned long fsc : 3;
78 		unsigned long pad2 : 1;
79 		unsigned long mr : 1;
80 		unsigned long mc : 1;
81 		unsigned long pad3 : 1;
82 		unsigned long key : 8; /* storage keys */
83 	} reg;
84 	unsigned long val;
85 };
86 
87 static inline void *pfmf(unsigned long r1, void *paddr)
88 {
89 	register void * addr asm("1") = paddr;
90 
91 	asm volatile(".insn rre,0xb9af0000,%[r1],%[addr]"
92 		     : [addr] "+a" (addr) : [r1] "d" (r1) : "memory");
93 	return addr;
94 }
95 #endif
96