Skip to content

Commit

Permalink
target-tricore: Add target stubs and qom-cpu
Browse files Browse the repository at this point in the history
Add TriCore target stubs, and QOM cpu, and Maintainer

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Message-id: 1409572800-4116-2-git-send-email-kbastian@mail.uni-paderborn.de
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
bkoppelmann authored and pm215 committed Sep 1, 2014
1 parent 5cd1475 commit 48e06fe
Show file tree
Hide file tree
Showing 15 changed files with 943 additions and 1 deletion.
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ S: Maintained
F: target-xtensa/
F: hw/xtensa/

TriCore
M: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
S: Maintained
F: target-tricore/
F: hw/tricore/

Guest CPU Cores (KVM):
----------------------

Expand Down
2 changes: 2 additions & 0 deletions arch_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_XTENSA
#elif defined(TARGET_UNICORE32)
#define QEMU_ARCH QEMU_ARCH_UNICORE32
#elif defined(TARGET_TRICORE)
#define QEMU_ARCH QEMU_ARCH_TRICORE
#endif

const uint32_t arch_type = QEMU_ARCH;
Expand Down
11 changes: 10 additions & 1 deletion cpu-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ int cpu_exec(CPUArchState *env)
#elif defined(TARGET_CRIS)
#elif defined(TARGET_S390X)
#elif defined(TARGET_XTENSA)
#elif defined(TARGET_TRICORE)
/* XXXXX */
#else
#error unsupported target CPU
Expand Down Expand Up @@ -444,7 +445,8 @@ int cpu_exec(CPUArchState *env)
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || \
defined(TARGET_UNICORE32) || defined(TARGET_TRICORE)
if (interrupt_request & CPU_INTERRUPT_HALT) {
cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
cpu->halted = 1;
Expand Down Expand Up @@ -560,6 +562,12 @@ int cpu_exec(CPUArchState *env)
cc->do_interrupt(cpu);
next_tb = 0;
}
#elif defined(TARGET_TRICORE)
if ((interrupt_request & CPU_INTERRUPT_HARD)) {
cc->do_interrupt(cpu);
next_tb = 0;
}

#elif defined(TARGET_OPENRISC)
{
int idx = -1;
Expand Down Expand Up @@ -846,6 +854,7 @@ int cpu_exec(CPUArchState *env)
| env->cc_dest | (env->cc_x << 4);
#elif defined(TARGET_MICROBLAZE)
#elif defined(TARGET_MIPS)
#elif defined(TARGET_TRICORE)
#elif defined(TARGET_MOXIE)
#elif defined(TARGET_OPENRISC)
#elif defined(TARGET_SH4)
Expand Down
6 changes: 6 additions & 0 deletions cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
#elif defined(TARGET_MIPS)
MIPSCPU *mips_cpu = MIPS_CPU(cpu);
CPUMIPSState *env = &mips_cpu->env;
#elif defined(TARGET_TRICORE)
TriCoreCPU *tricore_cpu = TRICORE_CPU(cpu);
CPUTriCoreState *env = &tricore_cpu->env;
#endif

cpu_synchronize_state(cpu);
Expand All @@ -1434,6 +1437,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
#elif defined(TARGET_MIPS)
info->value->has_PC = true;
info->value->PC = env->active_tc.PC;
#elif defined(TARGET_TRICORE)
info->value->has_PC = true;
info->value->PC = env->PC;
#endif

/* XXX: waiting for the qapi to support GSList */
Expand Down
2 changes: 2 additions & 0 deletions include/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ typedef int64_t Elf64_Sxword;

#define EM_SPARCV9 43 /* SPARC v9 64-bit */

#define EM_TRICORE 44 /* Infineon TriCore */

#define EM_IA_64 50 /* HP/Intel IA-64 */

#define EM_X86_64 62 /* AMD x86-64 */
Expand Down
1 change: 1 addition & 0 deletions include/sysemu/arch_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum {
QEMU_ARCH_OPENRISC = 8192,
QEMU_ARCH_UNICORE32 = 0x4000,
QEMU_ARCH_MOXIE = 0x8000,
QEMU_ARCH_TRICORE = 0x10000,
};

extern const uint32_t arch_type;
Expand Down
1 change: 1 addition & 0 deletions target-tricore/Makefile.objs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-y += translate.o helper.o cpu.o op_helper.o
71 changes: 71 additions & 0 deletions target-tricore/cpu-qom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#ifndef QEMU_TRICORE_CPU_QOM_H
#define QEMU_TRICORE_CPU_QOM_H

#include "qom/cpu.h"


#define TYPE_TRICORE_CPU "tricore-cpu"

#define TRICORE_CPU_CLASS(klass) \
OBJECT_CLASS_CHECK(TriCoreCPUClass, (klass), TYPE_TRICORE_CPU)
#define TRICORE_CPU(obj) \
OBJECT_CHECK(TriCoreCPU, (obj), TYPE_TRICORE_CPU)
#define TRICORE_CPU_GET_CLASS(obj) \
OBJECT_GET_CLASS(TriCoreCPUClass, (obj), TYPE_TRICORE_CPU)

typedef struct TriCoreCPUClass {
/*< private >*/
CPUClass parent_class;
/*< public >*/

DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} TriCoreCPUClass;

/**
* TriCoreCPU:
* @env: #CPUTriCoreState
*
* A TriCore CPU.
*/
typedef struct TriCoreCPU {
/*< private >*/
CPUState parent_obj;
/*< public >*/

CPUTriCoreState env;
} TriCoreCPU;

static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState *env)
{
return TRICORE_CPU(container_of(env, TriCoreCPU, env));
}

#define ENV_GET_CPU(e) CPU(tricore_env_get_cpu(e))

#define ENV_OFFSET offsetof(TriCoreCPU, env)

hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void tricore_cpu_do_interrupt(CPUState *cpu);
void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags);


#endif /*QEMU_TRICORE_CPU_QOM_H */
192 changes: 192 additions & 0 deletions target-tricore/cpu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/*
* TriCore emulation for qemu: main translation routines.
*
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#include "cpu.h"
#include "qemu-common.h"

static inline void set_feature(CPUTriCoreState *env, int feature)
{
env->features |= 1ULL << feature;
}

static void tricore_cpu_set_pc(CPUState *cs, vaddr value)
{
TriCoreCPU *cpu = TRICORE_CPU(cs);
CPUTriCoreState *env = &cpu->env;

env->PC = value & ~(target_ulong)1;
}

static void tricore_cpu_synchronize_from_tb(CPUState *cs,
TranslationBlock *tb)
{
TriCoreCPU *cpu = TRICORE_CPU(cs);
CPUTriCoreState *env = &cpu->env;

env->PC = tb->pc;
}

static void tricore_cpu_reset(CPUState *s)
{
TriCoreCPU *cpu = TRICORE_CPU(s);
TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(cpu);
CPUTriCoreState *env = &cpu->env;

tcc->parent_reset(s);

tlb_flush(s, 1);

cpu_state_reset(env);
}

static bool tricore_cpu_has_work(CPUState *cs)
{
return true;
}

static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(dev);

cpu_reset(cs);
qemu_init_vcpu(cs);

tcc->parent_realize(dev, errp);
}


static void tricore_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
TriCoreCPU *cpu = TRICORE_CPU(obj);
CPUTriCoreState *env = &cpu->env;

cs->env_ptr = env;
cpu_exec_init(env);

if (tcg_enabled()) {
tricore_tcg_init();
}
}

static ObjectClass *tricore_cpu_class_by_name(const char *cpu_model)
{
ObjectClass *oc;
char *typename;

if (!cpu_model) {
return NULL;
}

typename = g_strdup_printf("%s-" TYPE_TRICORE_CPU, cpu_model);
oc = object_class_by_name(typename);
g_free(typename);
if (!oc || !object_class_dynamic_cast(oc, TYPE_TRICORE_CPU) ||
object_class_is_abstract(oc)) {
return NULL;
}
return oc;
}

static void tc1796_initfn(Object *obj)
{
TriCoreCPU *cpu = TRICORE_CPU(obj);

set_feature(&cpu->env, TRICORE_FEATURE_13);
}

static void aurix_initfn(Object *obj)
{
TriCoreCPU *cpu = TRICORE_CPU(obj);

set_feature(&cpu->env, TRICORE_FEATURE_16);
}

typedef struct TriCoreCPUInfo {
const char *name;
void (*initfn)(Object *obj);
void (*class_init)(ObjectClass *oc, void *data);
} TriCoreCPUInfo;

static const TriCoreCPUInfo tricore_cpus[] = {
{ .name = "tc1796", .initfn = tc1796_initfn },
{ .name = "aurix", .initfn = aurix_initfn },
{ .name = NULL }
};

static void tricore_cpu_class_init(ObjectClass *c, void *data)
{
TriCoreCPUClass *mcc = TRICORE_CPU_CLASS(c);
CPUClass *cc = CPU_CLASS(c);
DeviceClass *dc = DEVICE_CLASS(c);

mcc->parent_realize = dc->realize;
dc->realize = tricore_cpu_realizefn;

mcc->parent_reset = cc->reset;
cc->reset = tricore_cpu_reset;
cc->class_by_name = tricore_cpu_class_by_name;
cc->has_work = tricore_cpu_has_work;

cc->do_interrupt = tricore_cpu_do_interrupt;
cc->dump_state = tricore_cpu_dump_state;
cc->set_pc = tricore_cpu_set_pc;
cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;

}

static void cpu_register(const TriCoreCPUInfo *info)
{
TypeInfo type_info = {
.parent = TYPE_TRICORE_CPU,
.instance_size = sizeof(TriCoreCPU),
.instance_init = info->initfn,
.class_size = sizeof(TriCoreCPUClass),
.class_init = info->class_init,
};

type_info.name = g_strdup_printf("%s-" TYPE_TRICORE_CPU, info->name);
type_register(&type_info);
g_free((void *)type_info.name);
}

static const TypeInfo tricore_cpu_type_info = {
.name = TYPE_TRICORE_CPU,
.parent = TYPE_CPU,
.instance_size = sizeof(TriCoreCPU),
.instance_init = tricore_cpu_initfn,
.abstract = true,
.class_size = sizeof(TriCoreCPUClass),
.class_init = tricore_cpu_class_init,
};

static void tricore_cpu_register_types(void)
{
const TriCoreCPUInfo *info = tricore_cpus;

type_register_static(&tricore_cpu_type_info);

while (info->name) {
cpu_register(info);
info++;
}
}

type_init(tricore_cpu_register_types)
Loading

0 comments on commit 48e06fe

Please sign in to comment.