cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

cpu.c (5690B)


      1/*
      2 *  TriCore emulation for qemu: main translation routines.
      3 *
      4 *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
      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 Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "qapi/error.h"
     22#include "cpu.h"
     23#include "exec/exec-all.h"
     24#include "qemu/error-report.h"
     25
     26static inline void set_feature(CPUTriCoreState *env, int feature)
     27{
     28    env->features |= 1ULL << feature;
     29}
     30
     31static gchar *tricore_gdb_arch_name(CPUState *cs)
     32{
     33    return g_strdup("tricore");
     34}
     35
     36static void tricore_cpu_set_pc(CPUState *cs, vaddr value)
     37{
     38    TriCoreCPU *cpu = TRICORE_CPU(cs);
     39    CPUTriCoreState *env = &cpu->env;
     40
     41    env->PC = value & ~(target_ulong)1;
     42}
     43
     44static void tricore_cpu_synchronize_from_tb(CPUState *cs,
     45                                            const TranslationBlock *tb)
     46{
     47    TriCoreCPU *cpu = TRICORE_CPU(cs);
     48    CPUTriCoreState *env = &cpu->env;
     49
     50    env->PC = tb->pc;
     51}
     52
     53static void tricore_cpu_reset(DeviceState *dev)
     54{
     55    CPUState *s = CPU(dev);
     56    TriCoreCPU *cpu = TRICORE_CPU(s);
     57    TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(cpu);
     58    CPUTriCoreState *env = &cpu->env;
     59
     60    tcc->parent_reset(dev);
     61
     62    cpu_state_reset(env);
     63}
     64
     65static bool tricore_cpu_has_work(CPUState *cs)
     66{
     67    return true;
     68}
     69
     70static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
     71{
     72    CPUState *cs = CPU(dev);
     73    TriCoreCPU *cpu = TRICORE_CPU(dev);
     74    TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(dev);
     75    CPUTriCoreState *env = &cpu->env;
     76    Error *local_err = NULL;
     77
     78    cpu_exec_realizefn(cs, &local_err);
     79    if (local_err != NULL) {
     80        error_propagate(errp, local_err);
     81        return;
     82    }
     83
     84    /* Some features automatically imply others */
     85    if (tricore_feature(env, TRICORE_FEATURE_161)) {
     86        set_feature(env, TRICORE_FEATURE_16);
     87    }
     88
     89    if (tricore_feature(env, TRICORE_FEATURE_16)) {
     90        set_feature(env, TRICORE_FEATURE_131);
     91    }
     92    if (tricore_feature(env, TRICORE_FEATURE_131)) {
     93        set_feature(env, TRICORE_FEATURE_13);
     94    }
     95    cpu_reset(cs);
     96    qemu_init_vcpu(cs);
     97
     98    tcc->parent_realize(dev, errp);
     99}
    100
    101
    102static void tricore_cpu_initfn(Object *obj)
    103{
    104    TriCoreCPU *cpu = TRICORE_CPU(obj);
    105
    106    cpu_set_cpustate_pointers(cpu);
    107}
    108
    109static ObjectClass *tricore_cpu_class_by_name(const char *cpu_model)
    110{
    111    ObjectClass *oc;
    112    char *typename;
    113
    114    typename = g_strdup_printf(TRICORE_CPU_TYPE_NAME("%s"), cpu_model);
    115    oc = object_class_by_name(typename);
    116    g_free(typename);
    117    if (!oc || !object_class_dynamic_cast(oc, TYPE_TRICORE_CPU) ||
    118        object_class_is_abstract(oc)) {
    119        return NULL;
    120    }
    121    return oc;
    122}
    123
    124static void tc1796_initfn(Object *obj)
    125{
    126    TriCoreCPU *cpu = TRICORE_CPU(obj);
    127
    128    set_feature(&cpu->env, TRICORE_FEATURE_13);
    129}
    130
    131static void tc1797_initfn(Object *obj)
    132{
    133    TriCoreCPU *cpu = TRICORE_CPU(obj);
    134
    135    set_feature(&cpu->env, TRICORE_FEATURE_131);
    136}
    137
    138static void tc27x_initfn(Object *obj)
    139{
    140    TriCoreCPU *cpu = TRICORE_CPU(obj);
    141
    142    set_feature(&cpu->env, TRICORE_FEATURE_161);
    143}
    144
    145#include "hw/core/sysemu-cpu-ops.h"
    146
    147static const struct SysemuCPUOps tricore_sysemu_ops = {
    148    .get_phys_page_debug = tricore_cpu_get_phys_page_debug,
    149};
    150
    151#include "hw/core/tcg-cpu-ops.h"
    152
    153static const struct TCGCPUOps tricore_tcg_ops = {
    154    .initialize = tricore_tcg_init,
    155    .synchronize_from_tb = tricore_cpu_synchronize_from_tb,
    156    .tlb_fill = tricore_cpu_tlb_fill,
    157};
    158
    159static void tricore_cpu_class_init(ObjectClass *c, void *data)
    160{
    161    TriCoreCPUClass *mcc = TRICORE_CPU_CLASS(c);
    162    CPUClass *cc = CPU_CLASS(c);
    163    DeviceClass *dc = DEVICE_CLASS(c);
    164
    165    device_class_set_parent_realize(dc, tricore_cpu_realizefn,
    166                                    &mcc->parent_realize);
    167
    168    device_class_set_parent_reset(dc, tricore_cpu_reset, &mcc->parent_reset);
    169    cc->class_by_name = tricore_cpu_class_by_name;
    170    cc->has_work = tricore_cpu_has_work;
    171
    172    cc->gdb_read_register = tricore_cpu_gdb_read_register;
    173    cc->gdb_write_register = tricore_cpu_gdb_write_register;
    174    cc->gdb_num_core_regs = 44;
    175    cc->gdb_arch_name = tricore_gdb_arch_name;
    176
    177    cc->dump_state = tricore_cpu_dump_state;
    178    cc->set_pc = tricore_cpu_set_pc;
    179    cc->sysemu_ops = &tricore_sysemu_ops;
    180    cc->tcg_ops = &tricore_tcg_ops;
    181}
    182
    183#define DEFINE_TRICORE_CPU_TYPE(cpu_model, initfn) \
    184    {                                              \
    185        .parent = TYPE_TRICORE_CPU,                \
    186        .instance_init = initfn,                   \
    187        .name = TRICORE_CPU_TYPE_NAME(cpu_model),  \
    188    }
    189
    190static const TypeInfo tricore_cpu_type_infos[] = {
    191    {
    192        .name = TYPE_TRICORE_CPU,
    193        .parent = TYPE_CPU,
    194        .instance_size = sizeof(TriCoreCPU),
    195        .instance_init = tricore_cpu_initfn,
    196        .abstract = true,
    197        .class_size = sizeof(TriCoreCPUClass),
    198        .class_init = tricore_cpu_class_init,
    199    },
    200    DEFINE_TRICORE_CPU_TYPE("tc1796", tc1796_initfn),
    201    DEFINE_TRICORE_CPU_TYPE("tc1797", tc1797_initfn),
    202    DEFINE_TRICORE_CPU_TYPE("tc27x", tc27x_initfn),
    203};
    204
    205DEFINE_TYPES(tricore_cpu_type_infos)