/* * __test_facility_constant() generates a single instruction branch. If the * tested facility is available (likely) the branch is patched into a nop. * * Do not use this function unless you know what you are doing. All users are * supposed to use test_facility() which will do the right thing.
*/ static __always_inline bool __test_facility_constant(unsignedlong nr)
{ asmgoto(
ALTERNATIVE("brcl 15,%l[l_no]", "brcl 0,0", ALT_FACILITY(%[nr]))
:
: [nr] "i" (nr)
:
: l_no); returntrue;
l_no: returnfalse;
}
/* * The test_facility function uses the bit ordering where the MSB is bit 0. * That makes it easier to query facility bits with the bit number as * documented in the Principles of Operation.
*/ static __always_inline bool test_facility(unsignedlong nr)
{ unsignedlong facilities_als[] = { FACILITIES_ALS };
if (!__is_defined(__DECOMPRESSOR) && __builtin_constant_p(nr)) { if (nr < sizeof(facilities_als) * 8) { if (__test_facility(nr, &facilities_als)) returntrue;
} return __test_facility_constant(nr);
} return __test_facility(nr, &stfle_fac_list);
}
/** * stfle - Store facility list extended * @fac_list: array where facility list can be stored * @size: size of passed in array in double words
*/ staticinlinevoid __stfle(u64 *fac_list, int size)
{ unsignedlong nr;
u32 stfl_fac_list;
asmvolatile( " stfl 0(0)\n"
: "=m" (get_lowcore()->stfl_fac_list));
stfl_fac_list = get_lowcore()->stfl_fac_list;
memcpy(fac_list, &stfl_fac_list, 4);
nr = 4; /* bytes stored by stfl */ if (stfl_fac_list & 0x01000000) { /* More facility bits available with stfle */
nr = __stfle_asm(fac_list, size);
nr = min_t(unsignedlong, (nr + 1) * 8, size * 8);
}
memset((char *)fac_list + nr, 0, size * 8 - nr);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.