On Wed, Apr 08, 2015 at 01:36:29PM +0200, Igor Mammedov wrote: > On Tue, 7 Apr 2015 17:46:40 -0300 > Eduardo Habkost <ehabk...@redhat.com> wrote: > > > This uses the feature name arrays to register "feat-*" QOM properties > > for feature flags. This simply adds the properties so they can be > > configured using -global, but doesn't change x86_cpu_parse_featurestr() > > to use them yet. > > > > Signed-off-by: Eduardo Habkost <ehabk...@redhat.com> > > --- > > target-i386/cpu.c | 98 > > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 98 insertions(+) > > > > diff --git a/target-i386/cpu.c b/target-i386/cpu.c > > index 099ed03..f29e55e 100644 > > --- a/target-i386/cpu.c > > +++ b/target-i386/cpu.c > > @@ -2883,12 +2883,103 @@ out: > > } > > } > > > > +typedef struct FeatureProperty { > > + FeatureWord word; > > + uint32_t mask; > > +} FeatureProperty; > > + > > + > > +static void x86_cpu_get_feature_prop(Object *obj, > > + struct Visitor *v, > > + void *opaque, > > + const char *name, > > + Error **errp) > > +{ > > + X86CPU *cpu = X86_CPU(obj); > > + CPUX86State *env = &cpu->env; > > + FeatureProperty *fp = opaque; > > + bool value = (env->features[fp->word] & fp->mask) == fp->mask; > > + visit_type_bool(v, &value, name, errp); > > +} > > + > > +static void x86_cpu_set_feature_prop(Object *obj, > > + struct Visitor *v, > > + void *opaque, > > + const char *name, > > + Error **errp) > > +{ > > + X86CPU *cpu = X86_CPU(obj); > > + CPUX86State *env = &cpu->env; > > + FeatureProperty *fp = opaque; > > + bool value; > > + visit_type_bool(v, &value, name, errp); > > + if (value) { > > + env->features[fp->word] |= fp->mask; > > + } else { > > + env->features[fp->word] &= ~fp->mask; > > + } > > +} > > + > > +/* Register a boolean feature-bits property. > > + * If mask has multiple bits, all must be set for the property to return > > true. > > + * The same property name can be registered multiple times to make it > > affect > > + * multiple bits in the same FeatureWord. > > + */ > > +static void x86_cpu_register_feature_prop(X86CPU *cpu, > > + const char *prop_name, > > + FeatureWord w, > > + uint32_t mask) > > +{ > > + FeatureProperty *fp; > > + ObjectProperty *op; > > + op = object_property_find(OBJECT(cpu), prop_name, NULL); > > + if (op) { > > + fp = op->opaque; > > + assert(fp->word == w); > > + fp->mask |= mask; > > + } else { > > + fp = g_new0(FeatureProperty, 1); > > + fp->word = w; > > + fp->mask = mask; > > + object_property_add(OBJECT(cpu), prop_name, "bool", > > + x86_cpu_get_feature_prop, > > + x86_cpu_set_feature_prop, > > + NULL, fp, &error_abort); > > + } > > +} > it would be better to create generic bit property and replace above code with > it > something similar to object_property_add_uint32_ptr()
object_property_add_*_ptr() adds read-only properties, and I didn't want to make object_property_add_bit_ptr() inconsistent with the other functions. But maybe it is better to have an inconsistent but reusable API than making the new code non-reusable by keeping it inside target-i386/cpu.c. I will give it a try. BTW, it is on my wishlist to remove the existing duplication in DEFINE_PROP_*(), QAPI, and object_property_add_*(), that are supposed to support the same data types without duplicating code, but this may take a while. > > > > + > > +static void x86_cpu_register_feature_bit_props(X86CPU *cpu, > > + FeatureWord w, > > + int bit) > > +{ > > + int i; > > + char **names; > > + FeatureWordInfo *fi = &feature_word_info[w]; > > + > > + if (!fi->feat_names) { > > + return; > > + } > > + if (!fi->feat_names[bit]) { > > + return; > > + } > > + > > + names = g_strsplit(fi->feat_names[bit], "|", 0); > > + for (i = 0; names[i]; i++) { > > + char *feat_name = names[i]; > > + char *prop_name = g_strdup_printf("feat-%s", feat_name); > > + x86_cpu_register_feature_prop(cpu, prop_name, w, (1UL << bit)); > it might be better instead of creating duplicate property to make an alias I wasn't aware of property aliases. I will take a look. Thanks! -- Eduardo