xref: /kvm-unit-tests/lib/s390x/asm/mem.h (revision 7b9ca995a64ab165b61d9b9ba5c72515ce044d93)
1 /*
2  * Physical memory management related functions and definitions.
3  *
4  * Copyright IBM Corp. 2018
5  * Author(s): Janosch Frank <frankja@de.ibm.com>
6  *
7  * This code is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Library General Public License version 2.
9  */
10 #ifndef _ASM_S390_MEM_H
11 #define _ASM_S390_MEM_H
12 
13 #define SKEY_ACC	0xf0
14 #define SKEY_FP		0x08
15 #define SKEY_RF		0x04
16 #define SKEY_CH		0x02
17 
18 union skey {
19 	struct {
20 		uint8_t acc : 4;
21 		uint8_t fp : 1;
22 		uint8_t rf : 1;
23 		uint8_t ch : 1;
24 		uint8_t pad : 1;
25 	} str;
26 	uint8_t val;
27 };
28 
29 static inline void set_storage_key(void *addr, unsigned char skey, int nq)
30 {
31 	if (nq)
32 		asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
33 			     : : "d" (skey), "a" (addr));
34 	else
35 		asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
36 }
37 
38 static inline void *set_storage_key_mb(void *addr, unsigned char skey)
39 {
40 	assert(test_facility(8));
41 
42 	asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],1,0"
43 		     : [addr] "+a" (addr) : [skey] "d" (skey));
44 	return addr;
45 }
46 
47 static inline unsigned char get_storage_key(void *addr)
48 {
49 	unsigned char skey;
50 
51 	asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr));
52 	return skey;
53 }
54 
55 #define PFMF_FSC_4K 0
56 #define PFMF_FSC_1M 1
57 #define PFMF_FSC_2G 2
58 
59 union pfmf_r1 {
60 	struct {
61 		unsigned long pad0 : 32;
62 		unsigned long pad1 : 12;
63 		unsigned long pad_fmfi : 2;
64 		unsigned long sk : 1; /* set key*/
65 		unsigned long cf : 1; /* clear frame */
66 		unsigned long ui : 1; /* usage indication */
67 		unsigned long fsc : 3;
68 		unsigned long pad2 : 1;
69 		unsigned long mr : 1;
70 		unsigned long mc : 1;
71 		unsigned long pad3 : 1;
72 		unsigned long key : 8; /* storage keys */
73 	} reg;
74 	unsigned long val;
75 };
76 
77 static inline void *pfmf(unsigned long r1, void *paddr)
78 {
79 	register void * addr asm("1") = paddr;
80 
81 	asm volatile(".insn rre,0xb9af0000,%[r1],%[addr]"
82 		     : [addr] "+a" (addr) : [r1] "d" (r1) : "memory");
83 	return addr;
84 }
85 #endif
86