Skip to content

Commit

Permalink
Merge pull request #5 from AndrewFasano/dev/qemu-5.1-configurable
Browse files Browse the repository at this point in the history
Configurable Machine for MIPS, i386, X86_64
  • Loading branch information
rawsample committed Feb 3, 2021
2 parents 9abf34c + d5a616f commit ee8fcc7
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 123 deletions.
2 changes: 2 additions & 0 deletions hw/avatar/Makefile.objs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
obj-$(TARGET_ARM) += avatar_posix.o configurable_machine.o remote_memory.o arm_helper.o
obj-$(TARGET_MIPS) += avatar_posix.o configurable_machine.o remote_memory.o
obj-$(TARGET_I386) += configurable_machine.o
obj-$(TARGET_X86_64) += configurable_machine.o
obj-$(CONFIG_SOFTMMU) += interrupts.o
190 changes: 121 additions & 69 deletions hw/avatar/configurable_machine.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/*
* Avatar2 configurable machine for dynamic creation of emulated boards
*
* Copyright (C) 2017 Eurecom
* Written by Dario Nisi, Marius Muench & Jonas Zaddach
* Copyright (C) 2017-2021 Eurecom
* Written by Dario Nisi, Marius Muench, Paul Olivier & Jonas Zaddach
*
* Updates for MIPS, i386, and x86_64 written by Andrew Fasano for PANDA
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand Down Expand Up @@ -31,18 +33,31 @@
#include "hw/qdev-properties.h"

//plattform specific imports
#ifdef TARGET_ARM
#if defined(TARGET_ARM)
#include "target/arm/cpu.h"
#include "hw/arm/armv7m.h"
#include "hw/avatar/arm_helper.h"
#endif
typedef ARMCPU THISCPU;

#ifdef TARGET_MIPS
#elif defined(TARGET_I386) || defined(TARGET_X86_64)
#include "hw/i386/pc.h"
#include "target/i386/cpu.h"
typedef X86CPU THISCPU;

#elif defined(TARGET_MIPS)
#include "hw/mips/mips.h"
#include "hw/mips/cpudevs.h"
#include "target/mips/cpu.h"
typedef MIPSCPU THISCPU;

#elif defined(TARGET_PPC)
#include "hw/ppc/ppc.h"
#include "target/ppc/cpu.h"
typedef PowerPCCPU THISCPU;
#endif



//qapi imports
#include "qapi/error.h"
#include "qapi/qmp/qjson.h"
Expand Down Expand Up @@ -399,13 +414,9 @@ static void init_peripheral(QDict *device)
}


#ifdef TARGET_ARM
static void set_entry_point(QDict *conf, ARMCPU *cpuu)
#elif TARGET_MIPS
static void set_entry_point(QDict *conf, MIPSCPU *cpuu)
#endif

static void set_entry_point(QDict *conf, THISCPU *cpuu)
{
#ifdef TARGET_ARM
const char *entry_field = "entry_address";
uint32_t entry;

Expand All @@ -416,43 +427,60 @@ static void set_entry_point(QDict *conf, MIPSCPU *cpuu)
QDICT_ASSERT_KEY_TYPE(conf, entry_field, QTYPE_QNUM);
entry = qdict_get_int(conf, entry_field);

#ifdef TARGET_ARM
cpuu->env.regs[15] = entry & (~1);
cpuu->env.thumb = (entry & 1) == 1 ? 1 : 0;
#elif TARGET_MIPS
#elif defined(TARGET_I386)
cpuu->env.eip = entry;

#elif defined(TARGET_MIPS)
cpuu->env.active_tc.PC = entry;

#elif defined(TARGET_PPC)
//Not implemented yet
printf("Not yet implemented- can't start execution at 0x%x\n", entry);
#endif


}

#ifdef TARGET_ARM
static ARMCPU *create_cpu(MachineState * ms, QDict *conf)
static THISCPU *create_cpu(MachineState * ms, QDict *conf)
{
const char *cpu_model = ms->cpu_type;
const char *cpu_type;
THISCPU *cpuu;
CPUState *env;

#if defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_MIPS)
ObjectClass *cpu_oc;
Object *cpuobj;
ARMCPU *cpuu;
CPUState *env;
#endif

#ifdef TARGET_ARM
DeviceState *dstate; //generic device if CPU can be initiliazed via qdev-API
BusState* sysbus = sysbus_get_default();
int num_irq = 64;


if (qdict_haskey(conf, "cpu_model"))
{
cpu_model = qdict_get_str(conf, "cpu_model");
g_assert(cpu_model);
}

if (!cpu_model) cpu_model = "arm926";
#elif defined(TARGET_I386)
//

#elif defined(TARGET_MIPS)
Error *err = NULL;
#endif


cpu_type = ms->cpu_type;

printf("Configurable: Adding processor %s\n", cpu_model);
if (qdict_haskey(conf, "cpu_model")) {
cpu_type = qdict_get_str(conf, "cpu_model");
g_assert(cpu_type);
}


#ifdef TARGET_ARM
//create armv7m cpus together with nvic
if (!strcmp(cpu_model, "cortex-m3"))
{
if (!strcmp(cpu_type, "cortex-m3")) {

if (qdict_haskey(conf, "num_irq"))
{
if (qdict_haskey(conf, "num_irq")) {
num_irq = qdict_get_int(conf, "num_irq");
g_assert(num_irq);
}
Expand All @@ -461,15 +489,13 @@ static ARMCPU *create_cpu(MachineState * ms, QDict *conf)
qdev_prop_set_uint32(dstate, "num-irq", num_irq);
qdev_prop_set_string(dstate, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
object_property_set_link(OBJECT(dstate), "memory",
OBJECT(get_system_memory()), &error_abort);
OBJECT(get_system_memory()), &error_abort);
qdev_realize_and_unref(dstate, sysbus, NULL);

cpuu = ARM_CPU(first_cpu);

}
else
{
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
} else {
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_type);
if (!cpu_oc) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
Expand All @@ -480,60 +506,75 @@ static ARMCPU *create_cpu(MachineState * ms, QDict *conf)
object_property_set_bool(cpuobj, "realized", true, &error_fatal);
cpuu = ARM_CPU(cpuobj);
}
env = (CPUState *) &(cpuu->env);
if (!env)
{
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);

#elif defined(TARGET_I386)
cpu_oc = cpu_class_by_name(TYPE_X86_CPU, cpu_type);
if (!cpu_oc) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}

avatar_add_banked_registers(cpuu);
set_feature(&cpuu->env, ARM_FEATURE_CONFIGURABLE);
return cpuu;
}
cpuobj = object_new(object_class_get_name(cpu_oc));
cpuu = X86_CPU(cpuobj);

if (cpuu->apic_state) {
device_legacy_reset(cpuu->apic_state);
}

#elif TARGET_MIPS
static MIPSCPU *create_cpu(MachineState * ms, QDict *conf)
{
const char *cpu_model = ms->cpu_type;
MIPSCPU *cpuu;
CPUState *cpu;
#elif defined(TARGET_MIPS)
cpu_oc = cpu_class_by_name(TYPE_MIPS_CPU, cpu_type);
if (!cpu_oc) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}

if (qdict_haskey(conf, "cpu_model"))
{
cpu_model = qdict_get_str(conf, "cpu_model");
g_assert(cpu_model);
cpuobj = object_new(object_class_get_name(cpu_oc));
cpuu = MIPS_CPU(cpuobj);

if (!qdev_realize(DEVICE(cpuu), NULL, &err)) {
error_report_err(err);
object_unref(OBJECT(cpuu));
exit(EXIT_FAILURE);
}

if (!cpu_model) cpu_model = "mips32r6-generic";
#elif defined(TARGET_PPC)
cpuu = cpu_ppc_init(cpu_type);
#endif

printf("Configurable: Adding processor %s\n", cpu_model);

cpuu = cpu_mips_init(cpu_model);
if (cpuu == NULL) {
env = (CPUState *) &(cpuu->env);
if (!env) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}

cpu = (CPUState *) &(cpuu->env);
if (!cpu) {
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}

#if defined(TARGET_ARM)
avatar_add_banked_registers(cpuu);
set_feature(&cpuu->env, ARM_FEATURE_CONFIGURABLE);

#elif defined(TARGET_I386)
// Ensures CS register is set correctly on x86/x86_64 CPU reset. See target/i386/cpu.c:3063
int mode =
#if defined(TARGET_X86_64)
64;
#else
32;
#endif /* TARGET_X86_64 */
set_x86_configurable_machine(mode); // This sets the CPU to be in 32 or 64 bit mode

#elif defined(TARGET_MIPS)
//
#endif

assert(cpuu != NULL);
return cpuu;
}
#endif


static void board_init(MachineState * ms)
{
#ifdef TARGET_ARM
ARMCPU *cpuu;
#elif TARGET_MIPS
MIPSCPU *cpuu;
#endif
THISCPU *cpuu;

const char *kernel_filename = ms->kernel_filename;
QDict * conf = NULL;
Expand Down Expand Up @@ -583,6 +624,17 @@ static void configurable_machine_class_init(ObjectClass *oc, void *data)
mc->desc = "Machine that can be configured to be whatever you want";
mc->init = board_init;
mc->block_default_type = IF_SCSI;

#ifdef TARGET_ARM
mc->default_cpu_type = "arm926";
#elif defined(TARGET_I386)
mc->default_cpu_type = "qemu32";
#elif defined(TARGET_MIPS)
mc->default_cpu_type = "24Kf";
//mc->default_cpu_type = "mips32r6-generic";
#elif defined(TARGET_PPC)
mc->default_cpu_type = "e500v2_v30";
#endif
}

static const TypeInfo configurable_machine_type = {
Expand Down
28 changes: 20 additions & 8 deletions hw/avatar/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#ifdef TARGET_ARM
#include "target/arm/cpu.h"

#elif defined(TARGET_MIPS)
#include "target/mips/cpu.h"
#endif
Expand All @@ -20,26 +21,36 @@
#include "hw/avatar/remote_memory.h"


static QemuAvatarMessageQueue *irq_rx_queue_ref = NULL;
static QemuAvatarMessageQueue *irq_tx_queue_ref = NULL;

extern QemuAvatarMessageQueue *rmem_rx_queue_ref;
extern QemuAvatarMessageQueue *rmem_tx_queue_ref;

/* Common declarations,
* for now, only ARM target is implemented
*/
#ifdef TARGET_ARM

static QemuAvatarMessageQueue *irq_rx_queue_ref = NULL;
static QemuAvatarMessageQueue *irq_tx_queue_ref = NULL;

static uint64_t req_id;
static uint8_t ignore_irq_return_map[32] = {0};
#endif

/* Architecture specific declaration */
#ifdef TARGET_ARM
static bool armv7m_exception_handling_enabled = false;
static uint8_t ignore_irq_return_map[32] = {0};
#endif


#ifdef TARGET_ARM
void qmp_avatar_armv7m_set_vector_table_base(int64_t num_cpu, int64_t base, Error **errp)
{
#ifdef TARGET_ARM
//#ifdef TARGET_ARM
qemu_log_mask(LOG_AVATAR, "Changing NVIC base to%lx\n", base & 0xffffff80);
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(num_cpu));
/* MM: qemu now has multiple vecbases, we may need to fix this */
armcpu->env.v7m.vecbase[armcpu->env.v7m.secure] = base & 0xffffff80;
#endif
//#endif
}


Expand Down Expand Up @@ -120,13 +131,13 @@ void qmp_avatar_armv7m_unignore_irq_return(int64_t num_irq, Error **errp)

void qmp_avatar_armv7m_inject_irq(int64_t num_cpu,int64_t num_irq, Error **errp)
{
#ifdef TARGET_ARM
//#ifdef TARGET_ARM
qemu_log_mask(LOG_AVATAR, "Injecting exception 0x%lx\n", num_irq);
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(num_cpu));
CPUARMState *env = &armcpu->env;
/* MM: for now, we can only inject non-secure irqs */
armv7m_nvic_set_pending(env->nvic, num_irq, false);
#endif
//#endif
}


Expand Down Expand Up @@ -177,4 +188,5 @@ void avatar_armv7m_exception_enter(int irq)
}
}
}
#endif

2 changes: 1 addition & 1 deletion qapi/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
QAPI_COMMON_MODULES += dump error introspect job machine migration misc
QAPI_COMMON_MODULES += net pragma qdev qom rdma rocker run-state sockets tpm
QAPI_COMMON_MODULES += trace transaction ui
QAPI_COMMON_MODULES += avatar
QAPI_TARGET_MODULES = machine-target misc-target
QAPI_TARGET_MODULES += avatar
QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)

util-obj-y += qapi-builtin-types.o
Expand Down
Loading

0 comments on commit ee8fcc7

Please sign in to comment.