diff options
author | Suraj Jitindar Singh <sjitindarsingh@gmail.com> | 2018-01-19 16:00:01 +1100 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2018-01-29 14:24:55 +1100 |
commit | 6898aed77f4636c3e77af9c12631f583f22cb5db (patch) | |
tree | 3e0c433b4e735218e5ac47d03c9f6c9a6b7f42c8 /hw/ppc | |
parent | 8acc2ae5e91681ceda3ff4cf946ebf163f6012e9 (diff) | |
download | qemu-6898aed77f4636c3e77af9c12631f583f22cb5db.zip qemu-6898aed77f4636c3e77af9c12631f583f22cb5db.tar.gz qemu-6898aed77f4636c3e77af9c12631f583f22cb5db.tar.bz2 |
target/ppc/spapr_caps: Add support for tristate spapr_capabilities
spapr_caps are used to represent the level of support for various
capabilities related to the spapr machine type. Currently there is
only support for boolean capabilities.
Add support for tristate capabilities by implementing their get/set
functions. These capabilities can have the values 0, 1 or 2
corresponding to broken, workaround and fixed.
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc')
-rw-r--r-- | hw/ppc/spapr_caps.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 5d52969..d6f82b1 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -73,6 +73,72 @@ static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name, spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF; } +static void __attribute__ ((unused)) spapr_cap_get_tristate(Object *obj, + Visitor *v, + const char *name, + void *opaque, + Error **errp) +{ + sPAPRCapabilityInfo *cap = opaque; + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + char *val = NULL; + uint8_t value = spapr_get_cap(spapr, cap->index); + + switch (value) { + case SPAPR_CAP_BROKEN: + val = g_strdup("broken"); + break; + case SPAPR_CAP_WORKAROUND: + val = g_strdup("workaround"); + break; + case SPAPR_CAP_FIXED: + val = g_strdup("fixed"); + break; + default: + error_setg(errp, "Invalid value (%d) for cap-%s", value, cap->name); + return; + } + + visit_type_str(v, name, &val, errp); + g_free(val); +} + +static void __attribute__ ((unused)) spapr_cap_set_tristate(Object *obj, + Visitor *v, + const char *name, + void *opaque, + Error **errp) +{ + sPAPRCapabilityInfo *cap = opaque; + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + char *val; + Error *local_err = NULL; + uint8_t value; + + visit_type_str(v, name, &val, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + if (!strcasecmp(val, "broken")) { + value = SPAPR_CAP_BROKEN; + } else if (!strcasecmp(val, "workaround")) { + value = SPAPR_CAP_WORKAROUND; + } else if (!strcasecmp(val, "fixed")) { + value = SPAPR_CAP_FIXED; + } else { + error_setg(errp, "Invalid capability mode \"%s\" for cap-%s", val, + cap->name); + goto out; + } + + spapr->cmd_line_caps[cap->index] = true; + spapr->eff.caps[cap->index] = value; +out: + g_free(val); +} + static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp) { if (!val) { |