1 /**
2  * \file
3  * S/390x hardware feature detection
4  *
5  * Authors:
6  *    Alex Rønne Petersen (alexrp@xamarin.com)
7  *    Elijah Taylor (elijahtaylor@google.com)
8  *    Miguel de Icaza (miguel@xamarin.com)
9  *    Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
10  *    Paolo Molaro (lupus@xamarin.com)
11  *    Rodrigo Kumpera (kumpera@gmail.com)
12  *    Sebastien Pouliot (sebastien@xamarin.com)
13  *    Zoltan Varga (vargaz@xamarin.com)
14  *
15  * Copyright 2003 Ximian, Inc.
16  * Copyright 2003-2011 Novell, Inc
17  * Copyright 2006 Broadcom
18  * Copyright 2007-2008 Andreas Faerber
19  * Copyright 2011-2013 Xamarin Inc
20  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
21  */
22 
23 #include "mono/utils/mono-hwcap.h"
24 
25 #include <signal.h>
26 
27 typedef struct {
28 	uint8_t	n3:1;		// 000 - N3 instructions
29 	uint8_t	zi:1;		// 001 - z/Arch installed
30 	uint8_t	za:1;		// 002 - z/Arch active
31 	uint8_t	date:1;		// 003 - DAT-enhancement
32 	uint8_t idtes:1;	// 004 - IDTE-segment tables
33 	uint8_t	idter:1;	// 005 - IDTE-region tables
34 	uint8_t	asnlx:1;	// 006 - ASN-LX reuse
35 	uint8_t	stfle:1;	// 007 - STFLE
36 	uint8_t	edat1:1;	// 008 - EDAT 1
37 	uint8_t	srs:1;		// 009 - Sense-Running-Status
38 	uint8_t	csske:1;	// 010 - Conditional SSKE
39 	uint8_t	ctf:1;		// 011 - Configuration-topology
40 	uint8_t ibm01:1;	// 012 - Assigned to IBM
41 	uint8_t	ipter:1;	// 013 - IPTE-range
42 	uint8_t	nqks:1;		// 014 - Nonquiescing key-setting
43 	uint8_t	ibm02:1;	// 015 - Assigned to IBM
44 	uint8_t etf2:1;		// 016 - Extended translation 2
45 	uint8_t	msa:1;		// 017 - Message security assist 1
46 	uint8_t	ld:1;		// 018 - Long displacement
47 	uint8_t	ldh:1;		// 019 - Long displacement high perf
48 	uint8_t	mas:1;		// 020 - HFP multiply-add-subtract
49 	uint8_t	eif:1;		// 021 - Extended immediate
50 	uint8_t	etf3:1;		// 022 - Extended translation 3
51 	uint8_t	hux:1;		// 023 - HFP unnormalized extension
52 	uint8_t	etf2e:1;	// 024 - Extended translation enhanced 2
53 	uint8_t	stckf:1;	// 025 - Store clock fast
54 	uint8_t	pe:1;		// 026 - Parsing enhancement
55 	uint8_t	mvcos:1;	// 027 - Move with optional specs
56 	uint8_t	tods:1;		// 028 - TOD steering
57 	uint8_t x000:1;		// 029 - Undefined
58 	uint8_t	etf3e:1;	// 030 - ETF3 enhancement
59 	uint8_t	ecput:1;	// 031 - Extract CPU time
60 	uint8_t	csst:1;		// 032 - Compare swap and store
61 	uint8_t	csst2:1;	// 033 - Compare swap and store 2
62 	uint8_t	gie:1;		// 034 - General instructions extension
63 	uint8_t	ee:1;		// 035 - Execute extensions
64 	uint8_t	em:1;		// 036 - Enhanced monitor
65 	uint8_t	fpe:1;		// 037 - Floating point extension
66 	uint8_t	opcf:1;		// 038 - Order-preserving-compression facility
67 	uint8_t	ibm03:1;	// 039 - Assigned to IBM
68 	uint8_t	spp:1;		// 040 - Set program parameters
69 	uint8_t	fpse:1;		// 041 - FP support enhancement
70 	uint8_t	dfp:1;		// 042 - DFP
71 	uint8_t	dfph:1;		// 043 - DFP high performance
72 	uint8_t	pfpo:1;		// 044 - PFPO instruction
73 	uint8_t	multi:1;	// 045 - Multiple inc load/store on CC 1
74 	uint8_t	ibm04:1;	// 046 - Assigned to IBM
75 	uint8_t cmpsce:1;	// 047 - CMPSC enhancement
76 	uint8_t	dfpzc:1;	// 048 - DFP zoned conversion
77 	uint8_t	misc:1;		// 049 - Multiple inc load and trap
78 	uint8_t	ctx:1;		// 050 - Constrained transactional-execution
79 	uint8_t	ltlb:1;		// 051 - Local TLB clearing
80 	uint8_t	ia:1;		// 052 - Interlocked access
81 	uint8_t	lsoc2:1;	// 053 - Load/store on CC 2
82 	uint8_t	eecf:1;		// 054 - Entropy-encoding compression facility
83 	uint8_t	ibm05:1;	// 055 - Assigned to IBM
84 	uint8_t	x003:1;		// 056 - Undefined
85 	uint8_t	msa5:1;		// 057 - Message security assist 5
86 	uint8_t	mie2:1;		// 058 - Miscellaneous execution facility 2
87 	uint8_t	x005:1;		// 059 - Undefined
88 	uint8_t	x006:1;		// 060 - Undefined
89 	uint8_t	x007:1;		// 061 - Undefined
90 	uint8_t	ibm06:1;	// 062 - Assigned to IBM
91 	uint8_t	x008:1;		// 063 - Undefined
92 	uint8_t	x009:1;		// 064 - Undefined
93 	uint8_t	ibm07:1;	// 065 - Assigned to IBM
94 	uint8_t	rrbm:1;		// 066 - Reset reference bits multiple
95 	uint8_t	cmc:1;		// 067 - CPU measurement counter
96 	uint8_t	cms:1;		// 068 - CPU Measurement sampling
97 	uint8_t	ibm08:1;	// 069 - Assigned to IBM
98 	uint8_t	ibm09:1;	// 070 - Assigned to IBM
99 	uint8_t	ibm10:1;	// 071 - Assigned to IBM
100 	uint8_t	ibm11:1;	// 072 - Assigned to IBM
101 	uint8_t	txe:1;		// 073 - Transactional execution
102 	uint8_t	sthy:1;		// 074 - Store hypervisor information
103 	uint8_t	aefsi:1;	// 075 - Access exception fetch/store indication
104 	uint8_t	msa3:1;		// 076 - Message security assist 3
105 	uint8_t	msa4:1;		// 077 - Message security assist 4
106 	uint8_t	edat2:1;	// 078 - Enhanced DAT 2
107 	uint8_t	x010:1;		// 079 - Undefined
108 	uint8_t dfppc:1;	// 080 - DFP packed conversion
109 	uint8_t x011:7; 	// 081-87 - Undefined
110 	uint8_t x012[5];	// 088-127 - Undefined
111 	uint8_t ibm12:1;	// 128 - Assigned to IBM
112 	uint8_t	vec:1;		// 129 - Vector facility
113 	uint8_t	iep:1; 		// 130 - Instruction Execution Protection Facility
114 	uint8_t	sea:1; 		// 131 - Side-effect-access Faility
115 	uint8_t	x013:1;		// 132 - Undefined
116 	uint8_t	gs:1;  		// 133 - Guarded Storage Facility
117 	uint8_t	vpd:1;		// 134 - Vector Packed Decimal Facility
118 	uint8_t	ve1:1;		// 135 - Vector Enhancements Facilityty
119 	uint8_t x014:2;		// 136-137 - Undefined
120 	uint8_t cazm:1;		// 138 - Configuration-z/Architecture-arcitectural -mode Faciliy
121 	uint8_t mef:1; 		// 139 - Multiple-epoch Facility ture-arcitectural -mode Faciliy
122 	uint8_t ibm13:2;	// 140-141 - Assigned to IBM
123 	uint8_t	sccm:1;		// 142 - Store CPU counter multiple
124 	uint8_t x015:1; 	// 143 - Assigned to IBM
125 	uint8_t tpei:1; 	// 144 - Test Pending External Interrption Facility
126 	uint8_t irbm:1; 	// 145 - Insert Reference Bits Multiple Facility
127 	uint8_t mse8:1; 	// 146 - Message Security Assist Extension 8
128 	uint8_t ibm14:1;	// 147 - Reserved for IBM use
129 	uint8_t x016:4; 	// 148-151 - Undefined
130 	uint8_t x017[2];	// 152-167 - Undefined
131 	uint8_t esac:1; 	// 168 - ESA/390 Compatibility Mode Facility
132 	uint8_t x018:7;  	// 169-175 - Undefined
133 	uint8_t x019[10];	// 176-256 Undefined
134 } __attribute__ ((__packed__)) __attribute__ ((__aligned__(8))) facilityList_t;
135 
136 void
mono_hwcap_arch_init(void)137 mono_hwcap_arch_init (void)
138 {
139 	facilityList_t facs;
140 	int lFacs = sizeof (facs) / 8;
141 
142 	__asm__ __volatile__ (
143 		"lgfr\t0,%1\n\t"
144 		".insn\ts,0xb2b00000,%0\n\t"
145 		: "=m" (facs)
146 		: "r" (lFacs)
147 		: "0", "cc"
148 	);
149 
150 	mono_hwcap_s390x_has_fpe  = facs.fpe;
151 	mono_hwcap_s390x_has_vec  = facs.vec;
152 	mono_hwcap_s390x_has_mlt  = facs.multi;
153 	mono_hwcap_s390x_has_ia   = facs.ia;
154 	mono_hwcap_s390x_has_gie  = facs.gie;
155 	mono_hwcap_s390x_has_mie2 = facs.mie2;
156 	mono_hwcap_s390x_has_gs   = facs.gs;
157 }
158