1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Simple program to generate bitmaps, for example facility lists. 4 * 5 * Copyright IBM Corp. 2015, 2018 6 * 7 */ 8 9 #include <getopt.h> 10 #include <strings.h> 11 #include <string.h> 12 #include <stdlib.h> 13 #include <stdio.h> 14 15 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 16 17 struct bitmap_def { 18 char *name; 19 int *bits; 20 int inverted; 21 int maxbit; 22 }; 23 24 static struct bitmap_def facility_defs[] = { 25 { 26 /* 27 * FACILITIES_ALS contains the list of facilities that are 28 * required to run a kernel that is compiled e.g. with 29 * -march=<machine>. 30 */ 31 .name = "FACILITIES_ALS", 32 .inverted = 1, 33 .bits = (int[]){ 34 0, /* N3 instructions */ 35 1, /* z/Arch mode installed */ 36 3, /* dat-enhancement 1 */ 37 18, /* long displacement facility */ 38 21, /* extended-immediate facility */ 39 25, /* store clock fast */ 40 27, /* mvcos */ 41 32, /* compare and swap and store */ 42 33, /* compare and swap and store 2 */ 43 34, /* general instructions extension */ 44 35, /* execute extensions */ 45 #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES 46 45, /* fast-BCR, etc. */ 47 #endif 48 #ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES 49 49, /* misc-instruction-extensions */ 50 52, /* interlocked facility 2 */ 51 #endif 52 #ifdef CONFIG_HAVE_MARCH_Z13_FEATURES 53 53, /* load-and-zero-rightmost-byte, etc. */ 54 129, /* vector */ 55 #endif 56 #ifdef CONFIG_HAVE_MARCH_Z14_FEATURES 57 58, /* miscellaneous-instruction-extension 2 */ 58 #endif 59 #ifdef CONFIG_HAVE_MARCH_Z15_FEATURES 60 61, /* miscellaneous-instruction-extension 3 */ 61 #endif 62 #ifdef CONFIG_HAVE_MARCH_Z17_FEATURES 63 84, /* miscellaneous-instruction-extension 4 */ 64 #endif 65 -1 /* END */ 66 } 67 }, 68 { 69 /* 70 * FACILITIES_KVM contains the list of facilities that are part 71 * of the default facility mask and list that are passed to the 72 * initial CPU model. If no CPU model is used, this, together 73 * with the non-hypervisor managed bits, is the maximum list of 74 * guest facilities supported by KVM. 75 */ 76 .name = "FACILITIES_KVM", 77 .inverted = 1, 78 .bits = (int[]){ 79 0, /* N3 instructions */ 80 1, /* z/Arch mode installed */ 81 2, /* z/Arch mode active */ 82 3, /* DAT-enhancement */ 83 4, /* idte segment table */ 84 5, /* idte region table */ 85 6, /* ASN-and-LX reuse */ 86 7, /* stfle */ 87 8, /* enhanced-DAT 1 */ 88 9, /* sense-running-status */ 89 10, /* conditional sske */ 90 13, /* ipte-range */ 91 14, /* nonquiescing key-setting */ 92 73, /* transactional execution */ 93 75, /* access-exception-fetch/store indication */ 94 76, /* msa extension 3 */ 95 77, /* msa extension 4 */ 96 78, /* enhanced-DAT 2 */ 97 130, /* instruction-execution-protection */ 98 131, /* enhanced-SOP 2 and side-effect */ 99 139, /* multiple epoch facility */ 100 146, /* msa extension 8 */ 101 150, /* enhanced sort */ 102 151, /* deflate conversion */ 103 155, /* msa extension 9 */ 104 165, /* nnpa facility */ 105 170, /* ineffective-nonconstrained-transaction facility */ 106 193, /* bear enhancement facility */ 107 194, /* rdp enhancement facility */ 108 196, /* processor activity instrumentation facility */ 109 197, /* processor activity instrumentation extension 1 */ 110 201, /* concurrent-functions facility */ 111 -1 /* END */ 112 } 113 }, 114 { 115 /* 116 * FACILITIES_KVM_CPUMODEL contains the list of facilities 117 * that can be enabled by CPU model code if the host supports 118 * it. These facilities are not passed to the guest without 119 * CPU model support. 120 */ 121 122 .name = "FACILITIES_KVM_CPUMODEL", 123 .inverted = 1, 124 .bits = (int[]){ 125 12, /* AP Query Configuration Information */ 126 15, /* AP Facilities Test */ 127 156, /* etoken facility */ 128 -1 /* END */ 129 } 130 }, 131 }; 132 133 static struct bitmap_def pgm_check_defs[] = { 134 { 135 .name = "PGM_CHECKS_NULLIFIED", 136 .inverted = 0, 137 .maxbit = 127, 138 .bits = (int[]){ 139 0x10, /* Segment Translation */ 140 0x11, /* Page Translation */ 141 0x16, /* Trace Table */ 142 0x20, /* AFX Translation */ 143 0x21, /* ASX Translation */ 144 0x22, /* LX Translation */ 145 0x23, /* EX Translation */ 146 0x24, /* Primary Authority */ 147 0x25, /* Secondary Authority */ 148 0x26, /* LFX Translation */ 149 0x27, /* LSX Translation */ 150 0x29, /* ALEN Translation */ 151 0x2a, /* ALE Sequence */ 152 0x2b, /* ASTE Validity */ 153 0x2c, /* ASTE Sequence */ 154 0x2d, /* Extended Authority */ 155 0x2e, /* LSTE Sequence */ 156 0x2f, /* ASTE Instance */ 157 0x30, /* Stack Full */ 158 0x31, /* Stack Empty */ 159 0x32, /* Stack Specification */ 160 0x33, /* Stack Type */ 161 0x34, /* Stack Operation */ 162 0x38, /* ASCE Type */ 163 0x39, /* Region First Translation */ 164 0x3a, /* Region Second Translation */ 165 0x3b, /* Region Third Translation */ 166 0x3d, /* Secure Storage Access */ 167 -1 /* END */ 168 } 169 }, 170 }; 171 172 static void print_bitmap(struct bitmap_def *def) 173 { 174 unsigned int high, bit, dword, i; 175 unsigned long long *array; 176 177 high = def->maxbit ? def->maxbit / 64 : 0; 178 array = calloc(high + 1, 8); 179 if (!array) 180 exit(EXIT_FAILURE); 181 for (i = 0; def->bits[i] != -1; i++) { 182 bit = def->inverted ? 63 - (def->bits[i] & 63) : (def->bits[i] & 63); 183 dword = def->bits[i] / 64; 184 if (dword > high) { 185 array = realloc(array, (dword + 1) * 8); 186 if (!array) 187 exit(EXIT_FAILURE); 188 memset(array + high + 1, 0, (dword - high) * 8); 189 high = dword; 190 } 191 array[dword] |= 1ULL << bit; 192 } 193 printf("#define %s ", def->name); 194 for (i = 0; i <= high; i++) 195 printf("_AC(0x%016llx,UL)%c", array[i], i < high ? ',' : '\n'); 196 free(array); 197 } 198 199 static void print_header(const char *guard, struct bitmap_def *defs, size_t num) 200 { 201 unsigned int i; 202 203 printf("#ifndef __ASM_S390_%s_DEFS__\n", guard); 204 printf("#define __ASM_S390_%s_DEFS__\n", guard); 205 printf("/*\n"); 206 printf(" * DO NOT MODIFY.\n"); 207 printf(" *\n"); 208 printf(" * This file was generated by %s\n", __FILE__); 209 printf(" */\n\n"); 210 printf("#include <linux/const.h>\n\n"); 211 for (i = 0; i < num; i++) 212 print_bitmap(&defs[i]); 213 printf("\n#endif\n"); 214 } 215 216 static const struct option long_options[] = { 217 { "facility", no_argument, NULL, 'f' }, 218 { "pgmcheck", no_argument, NULL, 'p' }, 219 { NULL, 0, NULL, 0 } 220 }; 221 222 int main(int argc, char **argv) 223 { 224 int opt; 225 226 opt = getopt_long(argc, argv, "", long_options, NULL); 227 if (opt == -1) 228 return 1; 229 switch (opt) { 230 case 'f': 231 print_header("FACILITY", facility_defs, ARRAY_SIZE(facility_defs)); 232 break; 233 case 'p': 234 print_header("PGMCHECK", pgm_check_defs, ARRAY_SIZE(pgm_check_defs)); 235 break; 236 default: 237 return 1; 238 } 239 return 0; 240 } 241