14
14
* Lesser General Public License for more details.
16
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
* License along with this library. If not, see
18
* <http://www.gnu.org/licenses/>.
21
21
* Anton Blanchard <anton@au.ibm.com>
22
22
* Prerna Saxena <prerna@linux.vnet.ibm.com>
23
* Li Zhang <zhlcindy@linux.vnet.ibm.com>
25
26
#include <config.h>
27
30
#include "memory.h"
31
37
#define VIR_FROM_THIS VIR_FROM_CPU
33
39
static const char *archs[] = { "ppc64" };
47
static const struct cpuPowerPC cpu_defs[] = {
48
{"POWER7", "IBM", 0x003f0200},
49
{"POWER7_v2.1", "IBM", 0x003f0201},
50
{"POWER7_v2.3", "IBM", 0x003f0203},
51
{NULL, NULL, 0xffffffff}
57
struct ppc_vendor *next;
62
const struct ppc_vendor *vendor;
64
struct ppc_model *next;
68
struct ppc_vendor *vendors;
69
struct ppc_model *models;
73
ConvertModelVendorFromPVR(char ***model,
79
for (i = 0; cpu_defs[i].name; i++) {
80
if (cpu_defs[i].pvr == pvr) {
81
**model = strdup(cpu_defs[i].name);
82
**vendor = strdup(cpu_defs[i].vendor);
87
virReportError(VIR_ERR_INTERNAL_ERROR,
88
"%s", _("Missing the definition of this model"));
93
ConvertPVRFromModel(const char *model,
98
for (i = 0; cpu_defs[i].name; i++) {
99
if (STREQ(cpu_defs[i].name, model)) {
100
*pvr = cpu_defs[i].pvr;
105
virReportError(VIR_ERR_INTERNAL_ERROR,
106
"%s", _("Missing the definition of this model"));
111
cpuMatch(const union cpuData *data,
114
const struct ppc_model *model)
118
ret = ConvertModelVendorFromPVR(&cpu_model, &cpu_vendor, data->ppc.pvr);
120
if (STREQ(model->name, *cpu_model) &&
121
STREQ(model->vendor->name, *cpu_vendor))
128
static struct ppc_model *
131
struct ppc_model *model;
133
if (VIR_ALLOC(model) < 0)
136
if (VIR_ALLOC(model->data) < 0) {
145
ppcModelFree(struct ppc_model *model)
150
VIR_FREE(model->name);
152
VIR_FREE(model->data);
157
static struct ppc_model *
158
ppcModelFind(const struct ppc_map *map,
161
struct ppc_model *model;
164
while (model != NULL) {
165
if (STREQ(model->name, name))
174
static struct ppc_vendor *
175
ppcVendorFind(const struct ppc_map *map,
178
struct ppc_vendor *vendor;
180
vendor = map->vendors;
182
if (STREQ(vendor->name, name))
185
vendor = vendor->next;
192
ppcVendorFree(struct ppc_vendor *vendor)
197
VIR_FREE(vendor->name);
202
ppcVendorLoad(xmlXPathContextPtr ctxt,
205
struct ppc_vendor *vendor = NULL;
209
if (VIR_ALLOC(vendor) < 0)
212
vendor->name = virXPathString("string(@name)", ctxt);
214
virReportError(VIR_ERR_INTERNAL_ERROR,
215
"%s", _("Missing CPU vendor name"));
219
if (ppcVendorFind(map, vendor->name)) {
220
virReportError(VIR_ERR_INTERNAL_ERROR,
221
_("CPU vendor %s already defined"), vendor->name);
225
string = virXPathString("string(@string)", ctxt);
227
virReportError(VIR_ERR_INTERNAL_ERROR,
228
_("Missing vendor string for CPU vendor %s"), vendor->name);
232
map->vendors = vendor;
234
vendor->next = map->vendors;
235
map->vendors = vendor;
248
ppcVendorFree(vendor);
253
ppcModelLoad(xmlXPathContextPtr ctxt,
256
xmlNodePtr *nodes = NULL;
257
struct ppc_model *model;
261
if (!(model = ppcModelNew()))
264
model->name = virXPathString("string(@name)", ctxt);
265
if (model->name == NULL) {
266
virReportError(VIR_ERR_INTERNAL_ERROR,
267
"%s", _("Missing CPU model name"));
271
ret = ConvertPVRFromModel(model->name, &model->data->ppc.pvr);
276
if (virXPathBoolean("boolean(./vendor)", ctxt)) {
277
vendor = virXPathString("string(./vendor/@name)", ctxt);
279
virReportError(VIR_ERR_INTERNAL_ERROR,
280
_("Invalid vendor element in CPU model %s"),
285
if (!(model->vendor = ppcVendorFind(map, vendor))) {
286
virReportError(VIR_ERR_INTERNAL_ERROR,
287
_("Unknown vendor %s referenced by CPU model %s"),
288
vendor, model->name);
293
if (map->models == NULL)
296
model->next = map->models;
316
ppcMapLoadCallback(enum cpuMapElement element,
317
xmlXPathContextPtr ctxt,
320
struct ppc_map *map = data;
323
case CPU_MAP_ELEMENT_VENDOR:
324
return ppcVendorLoad(ctxt, map);
325
case CPU_MAP_ELEMENT_MODEL:
326
return ppcModelLoad(ctxt, map);
335
ppcMapFree(struct ppc_map *map)
340
while (map->models != NULL) {
341
struct ppc_model *model = map->models;
342
map->models = model->next;
346
while (map->vendors != NULL) {
347
struct ppc_vendor *vendor = map->vendors;
348
map->vendors = vendor->next;
349
ppcVendorFree(vendor);
355
static struct ppc_map *
360
if (VIR_ALLOC(map) < 0) {
365
if (cpuMapLoad("ppc64", ppcMapLoadCallback, map) < 0)
375
static struct ppc_model *
376
ppcModelCopy(const struct ppc_model *model)
378
struct ppc_model *copy;
380
if (VIR_ALLOC(copy) < 0
381
|| VIR_ALLOC(copy->data) < 0
382
|| !(copy->name = strdup(model->name))){
387
copy->data->ppc.pvr = model->data->ppc.pvr;
388
copy->vendor = model->vendor;
393
static struct ppc_model *
394
ppcModelFromCPU(const virCPUDefPtr cpu,
395
const struct ppc_map *map)
397
struct ppc_model *model = NULL;
399
if ((model = ppcModelFind(map, cpu->model))) {
400
if ((model = ppcModelCopy(model)) == NULL) {
403
} else if (!(model = ppcModelNew())) {
416
static virCPUCompareResult
417
PowerPCCompare(virCPUDefPtr host,
420
if ((cpu->arch && STRNEQ(host->arch, cpu->arch)) ||
421
STRNEQ(host->model, cpu->model))
422
return VIR_CPU_COMPARE_INCOMPATIBLE;
424
return VIR_CPU_COMPARE_IDENTICAL;
428
PowerPCDecode(virCPUDefPtr cpu,
429
const union cpuData *data,
431
unsigned int nmodels,
432
const char *preferred)
436
const struct ppc_model *candidate;
437
virCPUDefPtr cpuCandidate;
438
virCPUDefPtr cpuModel = NULL;
439
char *cpu_vendor = NULL;
440
char *cpu_model = NULL;
443
if (data == NULL || (map = ppcLoadMap()) == NULL)
446
candidate = map->models;
448
while (candidate != NULL) {
449
bool allowed = (models == NULL);
451
for (i = 0; i < nmodels; i++) {
452
if (models && models[i] && STREQ(models[i], candidate->name)) {
459
if (preferred && STREQ(candidate->name, preferred)) {
460
if (cpu->fallback != VIR_CPU_FALLBACK_ALLOW) {
461
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
462
_("CPU model %s is not supported by hypervisor"),
466
VIR_WARN("Preferred CPU model %s not allowed by"
467
" hypervisor; closest supported model will be"
471
VIR_DEBUG("CPU model %s not allowed by hypervisor; ignoring",
477
if (VIR_ALLOC(cpuCandidate) < 0) {
482
cpuCandidate->model = strdup(candidate->name);
483
cpuCandidate->vendor = strdup(candidate->vendor->name);
485
if (preferred && STREQ(cpuCandidate->model, preferred)) {
486
virCPUDefFree(cpuModel);
487
cpuModel = cpuCandidate;
491
ret = cpuMatch(data, &cpu_model, &cpu_vendor, candidate);
493
VIR_FREE(cpuCandidate);
496
cpuCandidate->model = cpu_model;
497
cpuCandidate->vendor = cpu_vendor;
498
virCPUDefFree(cpuModel);
499
cpuModel = cpuCandidate;
503
virCPUDefFree(cpuCandidate);
506
candidate = candidate->next;
509
if (cpuModel == NULL) {
510
virReportError(VIR_ERR_INTERNAL_ERROR,
511
"%s", _("Cannot find suitable CPU model for given data"));
515
cpu->model = cpuModel->model;
516
cpu->vendor = cpuModel->vendor;
523
virCPUDefFree(cpuModel);
528
#if defined(__powerpc__) || \
529
defined(__powerpc64__)
530
static uint32_t ppc_mfpvr(void)
540
PowerPCDataFree(union cpuData *data)
35
548
static union cpuData *
36
549
PowerPCNodeData(void)
558
#if defined(__powerpc__) || \
559
defined(__powerpc64__)
560
data->ppc.pvr = ppc_mfpvr();
50
PowerPCDecode(virCPUDefPtr cpu ATTRIBUTE_UNUSED,
51
const union cpuData *data ATTRIBUTE_UNUSED,
52
const char **models ATTRIBUTE_UNUSED,
53
unsigned int nmodels ATTRIBUTE_UNUSED,
54
const char *preferred ATTRIBUTE_UNUSED)
567
PowerPCUpdate(virCPUDefPtr guest ATTRIBUTE_UNUSED,
568
const virCPUDefPtr host ATTRIBUTE_UNUSED)
60
PowerPCDataFree(union cpuData *data)
573
PowerPCBaseline(virCPUDefPtr *cpus,
574
unsigned int ncpus ATTRIBUTE_UNUSED,
575
const char **models ATTRIBUTE_UNUSED,
576
unsigned int nmodels ATTRIBUTE_UNUSED)
578
struct ppc_map *map = NULL;
579
struct ppc_model *base_model = NULL;
580
virCPUDefPtr cpu = NULL;
581
struct ppc_model *model = NULL;
582
bool outputModel = true;
584
if (!(map = ppcLoadMap())) {
588
if (!(base_model = ppcModelFromCPU(cpus[0], map))) {
592
if (VIR_ALLOC(cpu) < 0 ||
593
!(cpu->arch = strdup(cpus[0]->arch)))
595
cpu->type = VIR_CPU_TYPE_GUEST;
596
cpu->match = VIR_CPU_MATCH_EXACT;
598
if (!cpus[0]->model) {
600
} else if (!(model = ppcModelFind(map, cpus[0]->model))) {
601
virReportError(VIR_ERR_OPERATION_FAILED,
602
_("Unknown CPU vendor %s"), cpus[0]->model);
606
base_model->data->ppc.pvr = model->data->ppc.pvr;
607
if (PowerPCDecode(cpu, base_model->data, models, nmodels, NULL) < 0)
611
VIR_FREE(cpu->model);
616
ppcModelFree(base_model);
68
629
struct cpuArchDriver cpuDriverPowerPC = {
71
632
.narch = ARRAY_CARDINALITY(archs),
633
.compare = PowerPCCompare,
73
634
.decode = PowerPCDecode,
75
636
.free = PowerPCDataFree,
76
637
.nodeData = PowerPCNodeData,
77
638
.guestData = NULL,
639
.baseline = PowerPCBaseline,
640
.update = PowerPCUpdate,
80
641
.hasFeature = NULL,