Revision 2985b86b target-ppc/translate_init.c

b/target-ppc/translate_init.c
9792 9792
}
9793 9793

  
9794 9794
/*****************************************************************************/
9795
static int create_ppc_opcodes (CPUPPCState *env, const ppc_def_t *def)
9795
static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
9796 9796
{
9797
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9798
    CPUPPCState *env = &cpu->env;
9799
    const ppc_def_t *def = pcc->info;
9797 9800
    opcode_t *opc;
9798 9801

  
9799 9802
    fill_new_table(env->opcodes, 0x40);
......
9801 9804
        if (((opc->handler.type & def->insns_flags) != 0) ||
9802 9805
            ((opc->handler.type2 & def->insns_flags2) != 0)) {
9803 9806
            if (register_insn(env->opcodes, opc) < 0) {
9804
                printf("*** ERROR initializing PowerPC instruction "
9805
                       "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
9806
                       opc->opc3);
9807
                return -1;
9807
                error_setg(errp, "ERROR initializing PowerPC instruction "
9808
                           "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
9809
                           opc->opc3);
9810
                return;
9808 9811
            }
9809 9812
        }
9810 9813
    }
9811 9814
    fix_opcode_tables(env->opcodes);
9812 9815
    fflush(stdout);
9813 9816
    fflush(stderr);
9814

  
9815
    return 0;
9816 9817
}
9817 9818

  
9818 9819
#if defined(PPC_DUMP_CPU)
......
10026 10027
    return 0;
10027 10028
}
10028 10029

  
10029
int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
10030
static void ppc_cpu_realize(Object *obj, Error **errp)
10030 10031
{
10031
    env->msr_mask = def->msr_mask;
10032
    env->mmu_model = def->mmu_model;
10033
    env->excp_model = def->excp_model;
10034
    env->bus_model = def->bus_model;
10035
    env->insns_flags = def->insns_flags;
10036
    env->insns_flags2 = def->insns_flags2;
10037
    env->flags = def->flags;
10038
    env->bfd_mach = def->bfd_mach;
10039
    env->check_pow = def->check_pow;
10040

  
10041
#if defined(TARGET_PPC64)
10042
    if (def->sps)
10043
        env->sps = *def->sps;
10044
    else if (env->mmu_model & POWERPC_MMU_64) {
10045
        /* Use default sets of page sizes */
10046
        static const struct ppc_segment_page_sizes defsps = {
10047
            .sps = {
10048
                { .page_shift = 12, /* 4K */
10049
                  .slb_enc = 0,
10050
                  .enc = { { .page_shift = 12, .pte_enc = 0 } }
10051
                },
10052
                { .page_shift = 24, /* 16M */
10053
                  .slb_enc = 0x100,
10054
                  .enc = { { .page_shift = 24, .pte_enc = 0 } }
10055
                },
10056
            },
10057
        };
10058
        env->sps = defsps;
10059
    }
10060
#endif /* defined(TARGET_PPC64) */
10032
    PowerPCCPU *cpu = POWERPC_CPU(obj);
10033
    CPUPPCState *env = &cpu->env;
10034
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10035
    ppc_def_t *def = pcc->info;
10036
    Error *local_err = NULL;
10061 10037

  
10062 10038
    if (kvm_enabled()) {
10063 10039
        if (kvmppc_fixup_cpu(env) != 0) {
10064
            fprintf(stderr, "Unable to virtualize selected CPU with KVM\n");
10065
            exit(1);
10040
            error_setg(errp, "Unable to virtualize selected CPU with KVM");
10041
            return;
10066 10042
        }
10067 10043
    } else {
10068 10044
        if (ppc_fixup_cpu(env) != 0) {
10069
            fprintf(stderr, "Unable to emulate selected CPU with TCG\n");
10070
            exit(1);
10045
            error_setg(errp, "Unable to emulate selected CPU with TCG");
10046
            return;
10071 10047
        }
10072 10048
    }
10073 10049

  
10074
    if (create_ppc_opcodes(env, def) < 0)
10075
        return -1;
10050
    create_ppc_opcodes(cpu, &local_err);
10051
    if (local_err != NULL) {
10052
        error_propagate(errp, local_err);
10053
        return;
10054
    }
10076 10055
    init_ppc_proc(env, def);
10077 10056

  
10078 10057
    if (def->insns_flags & PPC_FLOAT) {
......
10088 10067
                                 34, "power-spe.xml", 0);
10089 10068
    }
10090 10069

  
10070
    qemu_init_vcpu(env);
10071

  
10091 10072
#if defined(PPC_DUMP_CPU)
10092 10073
    {
10093 10074
        const char *mmu_model, *excp_model, *bus_model;
......
10249 10230
    dump_ppc_sprs(env);
10250 10231
    fflush(stdout);
10251 10232
#endif
10252

  
10253
    return 0;
10254 10233
}
10255 10234

  
10256
static bool ppc_cpu_usable(const ppc_def_t *def)
10235
static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
10257 10236
{
10258
#if defined(TARGET_PPCEMB)
10259
    /* When using the ppcemb target, we only support 440 style cores */
10260
    if (def->mmu_model != POWERPC_MMU_BOOKE) {
10261
        return false;
10237
    ObjectClass *oc = (ObjectClass *)a;
10238
    uint32_t pvr = *(uint32_t *)b;
10239
    PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10240

  
10241
    /* -cpu host does a PVR lookup during construction */
10242
    if (unlikely(strcmp(object_class_get_name(oc),
10243
                        TYPE_HOST_POWERPC_CPU) == 0)) {
10244
        return -1;
10262 10245
    }
10263
#endif
10264 10246

  
10265
    return true;
10247
    return pcc->info->pvr == pvr ? 0 : -1;
10266 10248
}
10267 10249

  
10268
const ppc_def_t *ppc_find_by_pvr(uint32_t pvr)
10250
PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
10269 10251
{
10270
    int i;
10252
    GSList *list, *item;
10253
    PowerPCCPUClass *pcc = NULL;
10271 10254

  
10272
    for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
10273
        if (!ppc_cpu_usable(&ppc_defs[i])) {
10274
            continue;
10275
        }
10276

  
10277
        /* If we have an exact match, we're done */
10278
        if (pvr == ppc_defs[i].pvr) {
10279
            return &ppc_defs[i];
10280
        }
10255
    list = object_class_get_list(TYPE_POWERPC_CPU, false);
10256
    item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10257
    if (item != NULL) {
10258
        pcc = POWERPC_CPU_CLASS(item->data);
10281 10259
    }
10260
    g_slist_free(list);
10261

  
10262
    return pcc;
10263
}
10264

  
10265
static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
10266
{
10267
    ObjectClass *oc = (ObjectClass *)a;
10268
    const char *name = b;
10282 10269

  
10283
    return NULL;
10270
    if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
10271
        strcmp(object_class_get_name(oc) + strlen(name),
10272
               "-" TYPE_POWERPC_CPU) == 0) {
10273
        return 0;
10274
    }
10275
    return -1;
10284 10276
}
10285 10277

  
10286 10278
#include <ctype.h>
10287 10279

  
10288
const ppc_def_t *cpu_ppc_find_by_name (const char *name)
10280
static ObjectClass *ppc_cpu_class_by_name(const char *name)
10289 10281
{
10290
    const ppc_def_t *ret;
10282
    GSList *list, *item;
10283
    ObjectClass *ret = NULL;
10291 10284
    const char *p;
10292
    int i, max, len;
10285
    int i, len;
10293 10286

  
10294
    if (kvm_enabled() && (strcasecmp(name, "host") == 0)) {
10295
        return kvmppc_host_cpu_def();
10287
    if (strcasecmp(name, "host") == 0) {
10288
        if (kvm_enabled()) {
10289
            ret = object_class_by_name(TYPE_HOST_POWERPC_CPU);
10290
        }
10291
        return ret;
10296 10292
    }
10297 10293

  
10298 10294
    /* Check if the given name is a PVR */
......
10307 10303
            if (!qemu_isxdigit(*p++))
10308 10304
                break;
10309 10305
        }
10310
        if (i == 8)
10311
            return ppc_find_by_pvr(strtoul(name, NULL, 16));
10312
    }
10313
    ret = NULL;
10314
    max = ARRAY_SIZE(ppc_defs);
10315
    for (i = 0; i < max; i++) {
10316
        if (!ppc_cpu_usable(&ppc_defs[i])) {
10317
            continue;
10306
        if (i == 8) {
10307
            ret = OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
10308
            return ret;
10318 10309
        }
10310
    }
10319 10311

  
10320
        if (strcasecmp(name, ppc_defs[i].name) == 0) {
10321
            ret = &ppc_defs[i];
10322
            break;
10323
        }
10312
    list = object_class_get_list(TYPE_POWERPC_CPU, false);
10313
    item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
10314
    if (item != NULL) {
10315
        ret = OBJECT_CLASS(item->data);
10324 10316
    }
10317
    g_slist_free(list);
10325 10318

  
10326 10319
    return ret;
10327 10320
}
10328 10321

  
10329
void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf)
10322
PowerPCCPU *cpu_ppc_init(const char *cpu_model)
10330 10323
{
10331
    int i, max;
10324
    PowerPCCPU *cpu;
10325
    CPUPPCState *env;
10326
    ObjectClass *oc;
10327
    Error *err = NULL;
10332 10328

  
10333
    max = ARRAY_SIZE(ppc_defs);
10334
    for (i = 0; i < max; i++) {
10335
        if (!ppc_cpu_usable(&ppc_defs[i])) {
10336
            continue;
10337
        }
10329
    oc = ppc_cpu_class_by_name(cpu_model);
10330
    if (oc == NULL) {
10331
        return NULL;
10332
    }
10338 10333

  
10339
        (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n",
10340
                       ppc_defs[i].name, ppc_defs[i].pvr);
10334
    cpu = POWERPC_CPU(object_new(object_class_get_name(oc)));
10335
    env = &cpu->env;
10336

  
10337
    if (tcg_enabled()) {
10338
        ppc_translate_init();
10341 10339
    }
10340

  
10341
    env->cpu_model_str = cpu_model;
10342

  
10343
    ppc_cpu_realize(OBJECT(cpu), &err);
10344
    if (err != NULL) {
10345
        fprintf(stderr, "%s\n", error_get_pretty(err));
10346
        error_free(err);
10347
        object_delete(OBJECT(cpu));
10348
        return NULL;
10349
    }
10350

  
10351
    return cpu;
10352
}
10353

  
10354
/* Sort by PVR, ordering special case "host" last. */
10355
static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10356
{
10357
    ObjectClass *oc_a = (ObjectClass *)a;
10358
    ObjectClass *oc_b = (ObjectClass *)b;
10359
    PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10360
    PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10361
    const char *name_a = object_class_get_name(oc_a);
10362
    const char *name_b = object_class_get_name(oc_b);
10363

  
10364
    if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10365
        return 1;
10366
    } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10367
        return -1;
10368
    } else {
10369
        /* Avoid an integer overflow during subtraction */
10370
        if (pcc_a->info->pvr < pcc_b->info->pvr) {
10371
            return -1;
10372
        } else if (pcc_a->info->pvr > pcc_b->info->pvr) {
10373
            return 1;
10374
        } else {
10375
            return 0;
10376
        }
10377
    }
10378
}
10379

  
10380
static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10381
{
10382
    ObjectClass *oc = data;
10383
    CPUListState *s = user_data;
10384
    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10385

  
10386
    (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
10387
                      pcc->info->name, pcc->info->pvr);
10388
}
10389

  
10390
void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
10391
{
10392
    CPUListState s = {
10393
        .file = f,
10394
        .cpu_fprintf = cpu_fprintf,
10395
    };
10396
    GSList *list;
10397

  
10398
    list = object_class_get_list(TYPE_POWERPC_CPU, false);
10399
    list = g_slist_sort(list, ppc_cpu_list_compare);
10400
    g_slist_foreach(list, ppc_cpu_list_entry, &s);
10401
    g_slist_free(list);
10402
}
10403

  
10404
static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10405
{
10406
    ObjectClass *oc = data;
10407
    CpuDefinitionInfoList **first = user_data;
10408
    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10409
    CpuDefinitionInfoList *entry;
10410
    CpuDefinitionInfo *info;
10411

  
10412
    info = g_malloc0(sizeof(*info));
10413
    info->name = g_strdup(pcc->info->name);
10414

  
10415
    entry = g_malloc0(sizeof(*entry));
10416
    entry->value = info;
10417
    entry->next = *first;
10418
    *first = entry;
10342 10419
}
10343 10420

  
10344 10421
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
10345 10422
{
10346 10423
    CpuDefinitionInfoList *cpu_list = NULL;
10347
    int i;
10424
    GSList *list;
10348 10425

  
10349
    for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
10350
        CpuDefinitionInfoList *entry;
10351
        CpuDefinitionInfo *info;
10426
    list = object_class_get_list(TYPE_POWERPC_CPU, false);
10427
    g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10428
    g_slist_free(list);
10352 10429

  
10353
        if (!ppc_cpu_usable(&ppc_defs[i])) {
10354
            continue;
10355
        }
10430
    return cpu_list;
10431
}
10356 10432

  
10357
        info = g_malloc0(sizeof(*info));
10358
        info->name = g_strdup(ppc_defs[i].name);
10433
static void ppc_cpu_def_class_init(ObjectClass *oc, void *data)
10434
{
10435
    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10436
    ppc_def_t *info = data;
10359 10437

  
10360
        entry = g_malloc0(sizeof(*entry));
10361
        entry->value = info;
10362
        entry->next = cpu_list;
10363
        cpu_list = entry;
10364
    }
10438
    pcc->info = info;
10439
}
10365 10440

  
10366
    return cpu_list;
10441
static void ppc_cpu_register_model(const ppc_def_t *def)
10442
{
10443
    TypeInfo type_info = {
10444
        .parent = TYPE_POWERPC_CPU,
10445
        .class_init = ppc_cpu_def_class_init,
10446
        .class_data = (void *)def,
10447
    };
10448

  
10449
    type_info.name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, def->name),
10450
    type_register(&type_info);
10451
    g_free((gpointer)type_info.name);
10367 10452
}
10368 10453

  
10369 10454
/* CPUClass::reset() */
......
10434 10519
static void ppc_cpu_initfn(Object *obj)
10435 10520
{
10436 10521
    PowerPCCPU *cpu = POWERPC_CPU(obj);
10522
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10437 10523
    CPUPPCState *env = &cpu->env;
10524
    ppc_def_t *def = pcc->info;
10438 10525

  
10439 10526
    cpu_exec_init(env);
10527

  
10528
    env->msr_mask = def->msr_mask;
10529
    env->mmu_model = def->mmu_model;
10530
    env->excp_model = def->excp_model;
10531
    env->bus_model = def->bus_model;
10532
    env->insns_flags = def->insns_flags;
10533
    env->insns_flags2 = def->insns_flags2;
10534
    env->flags = def->flags;
10535
    env->bfd_mach = def->bfd_mach;
10536
    env->check_pow = def->check_pow;
10537

  
10538
#if defined(TARGET_PPC64)
10539
    if (def->sps) {
10540
        env->sps = *def->sps;
10541
    } else if (env->mmu_model & POWERPC_MMU_64) {
10542
        /* Use default sets of page sizes */
10543
        static const struct ppc_segment_page_sizes defsps = {
10544
            .sps = {
10545
                { .page_shift = 12, /* 4K */
10546
                  .slb_enc = 0,
10547
                  .enc = { { .page_shift = 12, .pte_enc = 0 } }
10548
                },
10549
                { .page_shift = 24, /* 16M */
10550
                  .slb_enc = 0x100,
10551
                  .enc = { { .page_shift = 24, .pte_enc = 0 } }
10552
                },
10553
            },
10554
        };
10555
        env->sps = defsps;
10556
    }
10557
#endif /* defined(TARGET_PPC64) */
10440 10558
}
10441 10559

  
10442 10560
static void ppc_cpu_class_init(ObjectClass *oc, void *data)
......
10453 10571
    .parent = TYPE_CPU,
10454 10572
    .instance_size = sizeof(PowerPCCPU),
10455 10573
    .instance_init = ppc_cpu_initfn,
10456
    .abstract = false,
10574
    .abstract = true,
10457 10575
    .class_size = sizeof(PowerPCCPUClass),
10458 10576
    .class_init = ppc_cpu_class_init,
10459 10577
};
10460 10578

  
10461 10579
static void ppc_cpu_register_types(void)
10462 10580
{
10581
    int i;
10582

  
10463 10583
    type_register_static(&ppc_cpu_type_info);
10584

  
10585
    for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
10586
        const ppc_def_t *def = &ppc_defs[i];
10587
#if defined(TARGET_PPCEMB)
10588
        /* When using the ppcemb target, we only support 440 style cores */
10589
        if (def->mmu_model != POWERPC_MMU_BOOKE) {
10590
            continue;
10591
        }
10592
#endif
10593
        ppc_cpu_register_model(def);
10594
    }
10464 10595
}
10465 10596

  
10466 10597
type_init(ppc_cpu_register_types)

Also available in: Unified diff