qemu/target-moxie/cpu.c
<<
>>
Prefs
   1/*
   2 * QEMU Moxie CPU
   3 *
   4 * Copyright (c) 2013 Anthony Green
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "cpu.h"
  21#include "qemu-common.h"
  22#include "migration/vmstate.h"
  23#include "machine.h"
  24
  25static void moxie_cpu_set_pc(CPUState *cs, vaddr value)
  26{
  27    MoxieCPU *cpu = MOXIE_CPU(cs);
  28
  29    cpu->env.pc = value;
  30}
  31
  32static void moxie_cpu_reset(CPUState *s)
  33{
  34    MoxieCPU *cpu = MOXIE_CPU(s);
  35    MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
  36    CPUMoxieState *env = &cpu->env;
  37
  38    mcc->parent_reset(s);
  39
  40    memset(env, 0, offsetof(CPUMoxieState, breakpoints));
  41    env->pc = 0x1000;
  42
  43    tlb_flush(env, 1);
  44}
  45
  46static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
  47{
  48    CPUState *cs = CPU(dev);
  49    MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(dev);
  50
  51    qemu_init_vcpu(cs);
  52    cpu_reset(cs);
  53
  54    mcc->parent_realize(dev, errp);
  55}
  56
  57static void moxie_cpu_initfn(Object *obj)
  58{
  59    CPUState *cs = CPU(obj);
  60    MoxieCPU *cpu = MOXIE_CPU(obj);
  61    static int inited;
  62
  63    cs->env_ptr = &cpu->env;
  64    cpu_exec_init(&cpu->env);
  65
  66    if (tcg_enabled() && !inited) {
  67        inited = 1;
  68        moxie_translate_init();
  69    }
  70}
  71
  72static ObjectClass *moxie_cpu_class_by_name(const char *cpu_model)
  73{
  74    ObjectClass *oc;
  75
  76    if (cpu_model == NULL) {
  77        return NULL;
  78    }
  79
  80    oc = object_class_by_name(cpu_model);
  81    if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_MOXIE_CPU) ||
  82                       object_class_is_abstract(oc))) {
  83        return NULL;
  84    }
  85    return oc;
  86}
  87
  88static void moxie_cpu_class_init(ObjectClass *oc, void *data)
  89{
  90    DeviceClass *dc = DEVICE_CLASS(oc);
  91    CPUClass *cc = CPU_CLASS(oc);
  92    MoxieCPUClass *mcc = MOXIE_CPU_CLASS(oc);
  93
  94    mcc->parent_realize = dc->realize;
  95    dc->realize = moxie_cpu_realizefn;
  96
  97    mcc->parent_reset = cc->reset;
  98    cc->reset = moxie_cpu_reset;
  99
 100    cc->class_by_name = moxie_cpu_class_by_name;
 101
 102    cc->do_interrupt = moxie_cpu_do_interrupt;
 103    cc->dump_state = moxie_cpu_dump_state;
 104    cc->set_pc = moxie_cpu_set_pc;
 105#ifndef CONFIG_USER_ONLY
 106    cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
 107    cc->vmsd = &vmstate_moxie_cpu;
 108#endif
 109}
 110
 111static void moxielite_initfn(Object *obj)
 112{
 113    /* Set cpu feature flags */
 114}
 115
 116static void moxie_any_initfn(Object *obj)
 117{
 118    /* Set cpu feature flags */
 119}
 120
 121typedef struct MoxieCPUInfo {
 122    const char *name;
 123    void (*initfn)(Object *obj);
 124} MoxieCPUInfo;
 125
 126static const MoxieCPUInfo moxie_cpus[] = {
 127    { .name = "MoxieLite",      .initfn = moxielite_initfn },
 128    { .name = "any",            .initfn = moxie_any_initfn },
 129};
 130
 131MoxieCPU *cpu_moxie_init(const char *cpu_model)
 132{
 133    MoxieCPU *cpu;
 134    ObjectClass *oc;
 135
 136    oc = moxie_cpu_class_by_name(cpu_model);
 137    if (oc == NULL) {
 138        return NULL;
 139    }
 140    cpu = MOXIE_CPU(object_new(object_class_get_name(oc)));
 141    cpu->env.cpu_model_str = cpu_model;
 142
 143    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
 144
 145    return cpu;
 146}
 147
 148static void cpu_register(const MoxieCPUInfo *info)
 149{
 150    TypeInfo type_info = {
 151        .parent = TYPE_MOXIE_CPU,
 152        .instance_size = sizeof(MoxieCPU),
 153        .instance_init = info->initfn,
 154        .class_size = sizeof(MoxieCPUClass),
 155    };
 156
 157    type_info.name = g_strdup_printf("%s-" TYPE_MOXIE_CPU, info->name);
 158    type_register(&type_info);
 159    g_free((void *)type_info.name);
 160}
 161
 162static const TypeInfo moxie_cpu_type_info = {
 163    .name = TYPE_MOXIE_CPU,
 164    .parent = TYPE_CPU,
 165    .instance_size = sizeof(MoxieCPU),
 166    .instance_init = moxie_cpu_initfn,
 167    .class_size = sizeof(MoxieCPUClass),
 168    .class_init = moxie_cpu_class_init,
 169};
 170
 171static void moxie_cpu_register_types(void)
 172{
 173    int i;
 174    type_register_static(&moxie_cpu_type_info);
 175    for (i = 0; i < ARRAY_SIZE(moxie_cpus); i++) {
 176        cpu_register(&moxie_cpus[i]);
 177    }
 178}
 179
 180type_init(moxie_cpu_register_types)
 181