const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga, S390FeatBitmap features) { const S390CPUDef *last_compatible = NULL; const S390CPUDef *matching_cpu_type = NULL; int i; if (!gen) { ec_ga = 0; } if (!gen && type) { gen = s390_get_gen_for_cpu_type(type); } for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { const S390CPUDef *def = &s390_cpu_defs[i]; S390FeatBitmap missing; /* don't even try newer generations if we know the generation */ if (gen) { if (def->gen > gen) { break; } else if (def->gen == gen && ec_ga && def->ec_ga > ec_ga) { break; } } if (features) { /* see if the model satisfies the minimum features */ bitmap_andnot(missing, def->base_feat, features, S390_FEAT_MAX); /* * Ignore certain features that are in the base model, but not * relevant for the search (esp. MSA subfunctions). */ bitmap_andnot(missing, missing, ignored_base_feat, S390_FEAT_MAX); if (!bitmap_empty(missing, S390_FEAT_MAX)) { break; } } /* stop the search if we found the exact model */ if (def->type == type && def->ec_ga == ec_ga) { return def; } /* remember if we've at least seen one with the same cpu type */ if (def->type == type) { matching_cpu_type = def; } last_compatible = def; } /* prefer the model with the same cpu type, esp. don't take the BC for EC */ if (matching_cpu_type) { return matching_cpu_type; } return last_compatible; }
const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga, S390FeatBitmap features) { const S390CPUDef *last_compatible = NULL; int i; if (!gen) { ec_ga = 0; } if (!gen && type) { gen = s390_get_gen_for_cpu_type(type); } for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { const S390CPUDef *def = &s390_cpu_defs[i]; S390FeatBitmap missing; /* don't even try newer generations if we know the generation */ if (gen) { if (def->gen > gen) { break; } else if (def->gen == gen && ec_ga && def->ec_ga > ec_ga) { break; } } if (features) { /* see if the model satisfies the minimum features */ bitmap_andnot(missing, def->base_feat, features, S390_FEAT_MAX); if (!bitmap_empty(missing, S390_FEAT_MAX)) { break; } } /* stop the search if we found the exact model */ if (def->type == type && def->ec_ga == ec_ga) { return def; } last_compatible = def; } return last_compatible; }