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