/* * Setup hardware capabilities. */ static void __init setup_hwcaps(void) { static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; unsigned long long facility_list_extended; unsigned int facility_list; int i; facility_list = stfl(); /* * The store facility list bits numbers as found in the principles * of operation are numbered with bit 1UL<<31 as number 0 to * bit 1UL<<0 as number 31. * Bit 0: instructions named N3, "backported" to esa-mode * Bit 2: z/Architecture mode is active * Bit 7: the store-facility-list-extended facility is installed * Bit 17: the message-security assist is installed * Bit 19: the long-displacement facility is installed * Bit 21: the extended-immediate facility is installed * These get translated to: * HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1, * HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3, * HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5. */ for (i = 0; i < 6; i++) if (facility_list & (1UL << (31 - stfl_bits[i]))) elf_hwcap |= 1UL << i; /* * Check for additional facilities with store-facility-list-extended. * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0 * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information * as stored by stfl, bits 32-xxx contain additional facilities. * How many facility words are stored depends on the number of * doublewords passed to the instruction. The additional facilites * are: * Bit 43: decimal floating point facility is installed * translated to: * HWCAP_S390_DFP bit 6. */ if ((elf_hwcap & (1UL << 2)) && __stfle(&facility_list_extended, 1) > 0) { if (facility_list_extended & (1ULL << (64 - 43))) elf_hwcap |= 1UL << 6; } if (MACHINE_HAS_HPAGE) elf_hwcap |= 1UL << 7; switch (cpuinfo->cpu_id.machine) { case 0x9672: #if !defined(CONFIG_64BIT) default: /* Use "g5" as default for 31 bit kernels. */ #endif strcpy(elf_platform, "g5"); break; case 0x2064: case 0x2066: #if defined(CONFIG_64BIT) default: /* Use "z900" as default for 64 bit kernels. */ #endif strcpy(elf_platform, "z900"); break; case 0x2084: case 0x2086: strcpy(elf_platform, "z990"); break; case 0x2094: strcpy(elf_platform, "z9-109"); break; } }
static void __init setup_hwcaps(void) { static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; unsigned long long facility_list_extended; unsigned int facility_list; struct cpuid cpu_id; int i; facility_list = stfl(); /* * The store facility list bits numbers as found in the principles * of operation are numbered with bit 1UL<<31 as number 0 to * bit 1UL<<0 as number 31. * Bit 0: instructions named N3, "backported" to esa-mode * Bit 2: z/Architecture mode is active * Bit 7: the store-facility-list-extended facility is installed * Bit 17: the message-security assist is installed * Bit 19: the long-displacement facility is installed * Bit 21: the extended-immediate facility is installed * Bit 22: extended-translation facility 3 is installed * Bit 30: extended-translation facility 3 enhancement facility * These get translated to: * HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1, * HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3, * HWCAP_S390_LDISP bit 4, HWCAP_S390_EIMM bit 5 and * HWCAP_S390_ETF3EH bit 8 (22 && 30). */ for (i = 0; i < 6; i++) if (facility_list & (1UL << (31 - stfl_bits[i]))) elf_hwcap |= 1UL << i; if ((facility_list & (1UL << (31 - 22))) && (facility_list & (1UL << (31 - 30)))) elf_hwcap |= HWCAP_S390_ETF3EH; /* * Check for additional facilities with store-facility-list-extended. * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0 * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information * as stored by stfl, bits 32-xxx contain additional facilities. * How many facility words are stored depends on the number of * doublewords passed to the instruction. The additional facilites * are: * Bit 42: decimal floating point facility is installed * Bit 44: perform floating point operation facility is installed * translated to: * HWCAP_S390_DFP bit 6 (42 && 44). */ if ((elf_hwcap & (1UL << 2)) && __stfle(&facility_list_extended, 1) > 0) { if ((facility_list_extended & (1ULL << (63 - 42))) && (facility_list_extended & (1ULL << (63 - 44)))) elf_hwcap |= HWCAP_S390_DFP; } /* * Huge page support HWCAP_S390_HPAGE is bit 7. */ if (MACHINE_HAS_HPAGE) elf_hwcap |= HWCAP_S390_HPAGE; /* * 64-bit register support for 31-bit processes * HWCAP_S390_HIGH_GPRS is bit 9. */ elf_hwcap |= HWCAP_S390_HIGH_GPRS; get_cpu_id(&cpu_id); switch (cpu_id.machine) { case 0x9672: #if !defined(CONFIG_64BIT) default: /* Use "g5" as default for 31 bit kernels. */ #endif strcpy(elf_platform, "g5"); break; case 0x2064: case 0x2066: #if defined(CONFIG_64BIT) default: /* Use "z900" as default for 64 bit kernels. */ #endif strcpy(elf_platform, "z900"); break; case 0x2084: case 0x2086: strcpy(elf_platform, "z990"); break; case 0x2094: case 0x2096: strcpy(elf_platform, "z9-109"); break; case 0x2097: case 0x2098: strcpy(elf_platform, "z10"); break; } }
int __init stfle(unsigned long long *list, int doublewords) { if (!(stfl() & (1UL << 24))) return -EOPNOTSUPP; return __stfle(list, doublewords); }