1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-26 03:21:44 +03:00

cpu: Add helper functions to parse vendor and model

Add helper functions to parse vendor and model for
ARM CPUs, and use them as callbacks when load cpu
maps.

Signed-off-by: Zhenyu Zheng <zheng.zhenyu@outlook.com>
Message-Id: <TY2PR01MB3113C158B8C2822E75DB5EAE99BF0@TY2PR01MB3113.jpnprd01.prod.outlook.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Zhenyu Zheng 2020-05-13 18:48:32 +08:00 committed by Jiri Denemark
parent 0085231312
commit e7166956c7

View File

@ -210,6 +210,144 @@ virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED,
return 0;
}
static virCPUarmVendorPtr
virCPUarmVendorFindByID(virCPUarmMapPtr map,
unsigned long vendor_id)
{
size_t i;
for (i = 0; i < map->nvendors; i++) {
if (map->vendors[i]->value == vendor_id)
return map->vendors[i];
}
return NULL;
}
static virCPUarmVendorPtr
virCPUarmVendorFindByName(virCPUarmMapPtr map,
const char *name)
{
size_t i;
for (i = 0; i < map->nvendors; i++) {
if (STREQ(map->vendors[i]->name, name))
return map->vendors[i];
}
return NULL;
}
static int
virCPUarmVendorParse(xmlXPathContextPtr ctxt,
const char *name,
void *data)
{
virCPUarmMapPtr map = data;
g_autoptr(virCPUarmVendor) vendor = NULL;
vendor = g_new0(virCPUarmVendor, 1);
vendor->name = g_strdup(name);
if (virCPUarmVendorFindByName(map, vendor->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU vendor %s already defined"),
vendor->name);
return -1;
}
if (virXPathULongHex("string(@value)", ctxt, &vendor->value) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Missing CPU vendor value"));
return -1;
}
if (virCPUarmVendorFindByID(map, vendor->value)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU vendor value 0x%2lx already defined"),
vendor->value);
return -1;
}
if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
return -1;
return 0;
}
static virCPUarmModelPtr
virCPUarmModelFind(virCPUarmMapPtr map,
const char *name)
{
size_t i;
for (i = 0; i < map->nmodels; i++) {
if (STREQ(map->models[i]->name, name))
return map->models[i];
}
return NULL;
}
static int
virCPUarmModelParse(xmlXPathContextPtr ctxt,
const char *name,
void *data)
{
virCPUarmMapPtr map = data;
g_autoptr(virCPUarmModel) model = NULL;
g_autofree xmlNodePtr *nodes = NULL;
g_autofree char *vendor = NULL;
model = g_new0(virCPUarmModel, 1);
model->name = g_strdup(name);
if (virCPUarmModelFind(map, model->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU model %s already defined"),
model->name);
return -1;
}
if (virXPathBoolean("boolean(./vendor)", ctxt)) {
vendor = virXPathString("string(./vendor/@name)", ctxt);
if (!vendor) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid vendor element in CPU model %s"),
model->name);
return -1;
}
if (!(model->vendor = virCPUarmVendorFindByName(map, vendor))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown vendor %s referenced by CPU model %s"),
vendor, model->name);
return -1;
}
}
if (!virXPathBoolean("boolean(./pvr)", ctxt)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing PVR information for CPU model %s"),
model->name);
return -1;
}
if (virXPathULongHex("string(./pvr/@value)", ctxt, &model->data.pvr) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing or invalid PVR value in CPU model %s"),
model->name);
return -1;
}
if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
return -1;
return 0;
}
static virCPUarmMapPtr
virCPUarmLoadMap(void)
{
@ -217,7 +355,8 @@ virCPUarmLoadMap(void)
map = virCPUarmMapNew();
if (cpuMapLoad("arm", NULL, virCPUarmMapFeatureParse, NULL, map) < 0)
if (cpuMapLoad("arm", virCPUarmVendorParse, virCPUarmMapFeatureParse,
virCPUarmModelParse, map) < 0)
return NULL;
return g_steal_pointer(&map);