CR16C: Clean up boards
Implement a generic virt board and the basic structure for the Gigaset DE410 board.
This commit is contained in:
parent
8c748ec01a
commit
3fc0f53606
21 changed files with 271 additions and 213 deletions
|
|
@ -1,4 +1,5 @@
|
|||
# Default configuration for cr16c-softmmu
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_SC14450=y
|
||||
CONFIG_VIRT=y
|
||||
CONFIG_DE410=y
|
||||
|
|
|
|||
|
|
@ -1,2 +1,5 @@
|
|||
config SC14450
|
||||
config VIRT
|
||||
bool
|
||||
|
||||
config DE410
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "qemu/datadir.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
bool cr16c_load_firmware(CR16CCPU *cpu, MachineState *ms, MemoryRegion *mr, const char *firmware) {
|
||||
bool cr16c_load_firmware(CR16CCPU *cpu, MemoryRegion *mr, const char *firmware) {
|
||||
/* Adapted from arm implementation */
|
||||
g_autofree char *filename = NULL;
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
#include "target/cr16c/cpu.h"
|
||||
|
||||
bool cr16c_load_firmware(CR16CCPU *cpu, MachineState *ms, MemoryRegion *mr, const char *firmware);
|
||||
bool cr16c_load_firmware(CR16CCPU *cpu, MemoryRegion *mr, const char *firmware);
|
||||
|
||||
#endif /* HW_CR16C_BOOT_H */
|
||||
|
|
|
|||
62
hw/cr16c/de410.c
Normal file
62
hw/cr16c/de410.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include "boot.h"
|
||||
#include "exec/memory.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qom/object.h"
|
||||
#include "sc14461.h"
|
||||
|
||||
typedef struct DE410MachineState {
|
||||
MachineState parent_obj;
|
||||
SC14461McuState mcu;
|
||||
|
||||
MemoryRegion firmware;
|
||||
} DE410MachineState;
|
||||
|
||||
typedef struct DE410MachineClass {
|
||||
MachineClass parent_class;
|
||||
} DE410MachineClass;
|
||||
|
||||
#define TYPE_DE410_MACHINE MACHINE_TYPE_NAME("de410")
|
||||
|
||||
DECLARE_OBJ_CHECKERS(DE410MachineState, DE410MachineClass, DE410_MACHINE, TYPE_DE410_MACHINE)
|
||||
|
||||
static void de410_init(MachineState* machine)
|
||||
{
|
||||
DE410MachineState* m_state = DE410_MACHINE(machine);
|
||||
|
||||
object_initialize_child(OBJECT(machine), "mcu", &m_state->mcu, TYPE_SC14461_MCU);
|
||||
sysbus_realize(SYS_BUS_DEVICE(&m_state->mcu), &error_abort);
|
||||
|
||||
// Provide an option to load a small program until the peripherals are implemented
|
||||
if (machine->firmware) {
|
||||
memory_region_init_ram(&m_state->firmware, NULL, "firmware", (0xA000-0x8080)*KiB, &error_fatal);
|
||||
memory_region_add_subregion(&m_state->mcu.non_shared_ram_or_dcache, 0x80, &m_state->firmware);
|
||||
cr16c_load_firmware(&m_state->mcu.cpu, &m_state->firmware, machine->firmware);
|
||||
}
|
||||
}
|
||||
|
||||
static void de410_class_init(ObjectClass* oc, void* data)
|
||||
{
|
||||
MachineClass* mc = MACHINE_CLASS(oc);
|
||||
mc->desc = "DE410 VoIP desk telephone by Gigaset";
|
||||
mc->init = de410_init;
|
||||
mc->default_cpus = 1;
|
||||
mc->min_cpus = 1;
|
||||
mc->max_cpus = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_parallel = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo de410_machine_types[] = {
|
||||
{
|
||||
.name = TYPE_DE410_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
.instance_size = sizeof(DE410MachineState),
|
||||
.class_size = sizeof(DE410MachineClass),
|
||||
.class_init = de410_class_init,
|
||||
}
|
||||
};
|
||||
DEFINE_TYPES(de410_machine_types);
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
cr16c_ss = ss.source_set()
|
||||
cr16c_ss.add(files('sc14450.c'))
|
||||
cr16c_ss.add(files('sc14450board.c'))
|
||||
cr16c_ss.add(files('virt.c'))
|
||||
cr16c_ss.add(files('sc14461.c'))
|
||||
cr16c_ss.add(files('de410.c'))
|
||||
cr16c_ss.add(files('boot.c'))
|
||||
hw_arch += {'cr16c': cr16c_ss}
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
#include "sc14450.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/units.h"
|
||||
|
||||
typedef struct SC14450McuClass {
|
||||
SysBusDeviceClass parent_class;
|
||||
|
||||
const char* cpu_type;
|
||||
size_t flash_size;
|
||||
} SC14450McuClass;
|
||||
DECLARE_CLASS_CHECKERS(SC14450McuClass, SC14450_MCU, TYPE_SC14450_MCU)
|
||||
|
||||
static void sc14450_realize(DeviceState* dev, Error** errp)
|
||||
{
|
||||
SC14450McuState* s = SC14450_MCU(dev);
|
||||
const SC14450McuClass* mc = SC14450_MCU_GET_CLASS(dev);
|
||||
|
||||
object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type);
|
||||
object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort);
|
||||
|
||||
memory_region_init_ram(&s->flash, OBJECT(dev), "flash", mc->flash_size, &error_fatal);
|
||||
memory_region_add_subregion(get_system_memory(), 0, &s->flash);
|
||||
}
|
||||
|
||||
static void sc14450_class_init(ObjectClass* oc, void* data)
|
||||
{
|
||||
DeviceClass* dc = DEVICE_CLASS(oc);
|
||||
dc->realize = sc14450_realize;
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static void sc14450s_class_init(ObjectClass* oc, void* data)
|
||||
{
|
||||
SC14450McuClass* sc14450 = SC14450_MCU_CLASS(oc);
|
||||
|
||||
sc14450->cpu_type = CR16C_CPU_TYPE_NAME("SC14450C");
|
||||
sc14450->flash_size = 16 * MiB;
|
||||
}
|
||||
|
||||
static const TypeInfo sc14450_mcu_types[] = {
|
||||
{
|
||||
.name = TYPE_SC14450S_MCU,
|
||||
.parent = TYPE_SC14450_MCU,
|
||||
.class_init = sc14450s_class_init,
|
||||
},
|
||||
{
|
||||
.name = TYPE_SC14450_MCU,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(SC14450McuState),
|
||||
.class_size = sizeof(SC14450McuClass),
|
||||
.class_init = sc14450_class_init,
|
||||
.abstract = true,
|
||||
}
|
||||
};
|
||||
DEFINE_TYPES(sc14450_mcu_types)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef HW_SC14450_H
|
||||
#define HW_SC14450_H
|
||||
|
||||
#include "target/cr16c/cpu.h"
|
||||
#include "qom/object.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define TYPE_SC14450_MCU "SC14450"
|
||||
#define TYPE_SC14450S_MCU "SC14450S"
|
||||
|
||||
typedef struct SC14450McuState SC14450McuState;
|
||||
DECLARE_INSTANCE_CHECKER(SC14450McuState, SC14450_MCU, TYPE_SC14450_MCU)
|
||||
|
||||
struct SC14450McuState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
CR16CCPU cpu;
|
||||
MemoryRegion flash;
|
||||
};
|
||||
|
||||
#endif /* HW_SC14450_H */
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
#include "boot.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qom/object.h"
|
||||
#include "sc14450.h"
|
||||
|
||||
typedef struct SC14450BoardMachineState {
|
||||
MachineState parent_obj;
|
||||
SC14450McuState mcu;
|
||||
} SC14450BoardMachineState;
|
||||
|
||||
typedef struct SC14450BoardMachineClass {
|
||||
MachineClass parent_class;
|
||||
} SC14450BoardMachineClass;
|
||||
|
||||
#define TYPE_SC14450_BOARD_BASE_MACHINE MACHINE_TYPE_NAME("SC14450-board-base")
|
||||
#define TYPE_SC14450_BOARD_MACHINE MACHINE_TYPE_NAME("SC14450-board")
|
||||
|
||||
DECLARE_OBJ_CHECKERS(SC14450BoardMachineState, SC14450BoardMachineClass, SC14450_BOARD_MACHINE, TYPE_SC14450_BOARD_MACHINE)
|
||||
|
||||
static void sc14450board_init(MachineState* machine)
|
||||
{
|
||||
SC14450BoardMachineState* m_state = SC14450_BOARD_MACHINE(machine);
|
||||
|
||||
object_initialize_child(OBJECT(machine), "mcu", &m_state->mcu, TYPE_SC14450S_MCU);
|
||||
sysbus_realize(SYS_BUS_DEVICE(&m_state->mcu), &error_abort);
|
||||
|
||||
if (machine->firmware) {
|
||||
if (!cr16c_load_firmware(&m_state->mcu.cpu, machine, &m_state->mcu.flash, machine->firmware)) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sc14450board_class_init(ObjectClass* oc, void* data)
|
||||
{
|
||||
MachineClass* mc = MACHINE_CLASS(oc);
|
||||
mc->desc = "SC14450 VoIP + DECT Processor Board";
|
||||
mc->alias = "sc14450board";
|
||||
mc->init = sc14450board_init;
|
||||
mc->default_cpus = 1;
|
||||
mc->min_cpus = 1;
|
||||
mc->max_cpus = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_parallel = 1;
|
||||
mc->is_default = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo sc14450board_machine_types[] = {
|
||||
{
|
||||
.name = TYPE_SC14450_BOARD_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
.instance_size = sizeof(SC14450BoardMachineState),
|
||||
.class_size = sizeof(SC14450BoardMachineClass),
|
||||
.class_init = sc14450board_class_init,
|
||||
}
|
||||
};
|
||||
DEFINE_TYPES(sc14450board_machine_types);
|
||||
67
hw/cr16c/sc14461.c
Normal file
67
hw/cr16c/sc14461.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#include "sc14461.h"
|
||||
#include "cpu-qom.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/core/cpu.h"
|
||||
#include "hw/cr16c/boot.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qemu/units.h"
|
||||
|
||||
|
||||
static void sc14461_realize(DeviceState* dev, Error** errp)
|
||||
{
|
||||
SC14461McuState* s = SC14461_MCU(dev);
|
||||
|
||||
object_initialize_child(OBJECT(dev), "cpu", &s->cpu, TYPE_CR16C_CPU);
|
||||
object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort);
|
||||
|
||||
memory_region_init_ram(&s->non_shared_ram_or_icache, OBJECT(dev), "non_shared_ram_or_icache", 24*KiB, &error_fatal);
|
||||
memory_region_init_ram(&s->non_shared_ram_or_dcache, OBJECT(dev), "non_shared_ram_or_dcache", 8*KiB, &error_fatal);
|
||||
memory_region_init_ram(&s->shared_int_ram, OBJECT(dev), "shared_int_ram", 64*KiB, &error_fatal);
|
||||
memory_region_init_rom(&s->boot_rom, OBJECT(dev), "boot_rom", 2*KiB, &error_fatal);
|
||||
memory_region_add_subregion(get_system_memory(), 0x00000, &s->non_shared_ram_or_icache);
|
||||
memory_region_add_subregion(get_system_memory(), 0x08000, &s->non_shared_ram_or_dcache);
|
||||
memory_region_add_subregion(get_system_memory(), 0x10000, &s->shared_int_ram);
|
||||
memory_region_add_subregion(get_system_memory(), 0xFEF00, &s->boot_rom);
|
||||
|
||||
char* bios_path = qemu_find_file(QEMU_FILE_TYPE_BIOS, "sc14461-bios.img");
|
||||
if (!cr16c_load_firmware(&s->cpu, &s->boot_rom, bios_path)) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void sc14461_reset_hold(Object *obj, ResetType type) {
|
||||
SC14461McuClass* mcu_class = SC14461_MCU_GET_CLASS(obj);
|
||||
SC14461McuState* mcu_state = SC14461_MCU(obj);
|
||||
CR16CCPU* cpu = &mcu_state->cpu;
|
||||
CPUState* cpu_state = CPU(cpu);
|
||||
|
||||
if (mcu_class->parent_phases.hold) {
|
||||
mcu_class->parent_phases.hold(obj, type);
|
||||
}
|
||||
|
||||
cpu_reset(cpu_state);
|
||||
cpu_set_pc(cpu_state, 0xFEF00);
|
||||
}
|
||||
|
||||
static void sc14461_class_init(ObjectClass* oc, void* data)
|
||||
{
|
||||
DeviceClass* dc = DEVICE_CLASS(oc);
|
||||
SC14461McuClass* sc14461 = SC14461_MCU_CLASS(oc);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(oc);
|
||||
|
||||
resettable_class_set_parent_phases(rc, NULL, sc14461_reset_hold, NULL, &sc14461->parent_phases);
|
||||
|
||||
dc->realize = sc14461_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo sc14461_mcu_types[] = {
|
||||
{
|
||||
.name = TYPE_SC14461_MCU,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(SC14461McuState),
|
||||
.class_size = sizeof(SC14461McuClass),
|
||||
.class_init = sc14461_class_init,
|
||||
},
|
||||
};
|
||||
DEFINE_TYPES(sc14461_mcu_types)
|
||||
30
hw/cr16c/sc14461.h
Normal file
30
hw/cr16c/sc14461.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef HW_SC14461_H
|
||||
#define HW_SC14461_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define TYPE_SC14461_MCU "SC14461"
|
||||
|
||||
typedef struct SC14461McuState SC14461McuState;
|
||||
DECLARE_INSTANCE_CHECKER(SC14461McuState, SC14461_MCU, TYPE_SC14461_MCU)
|
||||
|
||||
struct SC14461McuState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
CR16CCPU cpu;
|
||||
|
||||
MemoryRegion non_shared_ram_or_icache;
|
||||
MemoryRegion non_shared_ram_or_dcache;
|
||||
MemoryRegion shared_int_ram;
|
||||
MemoryRegion boot_rom;
|
||||
};
|
||||
|
||||
typedef struct SC14461McuClass {
|
||||
SysBusDeviceClass parent_class;
|
||||
|
||||
ResettablePhases parent_phases;
|
||||
} SC14461McuClass;
|
||||
DECLARE_CLASS_CHECKERS(SC14461McuClass, SC14461_MCU, TYPE_SC14461_MCU)
|
||||
|
||||
#endif /* HW_SC14461_H */
|
||||
63
hw/cr16c/virt.c
Normal file
63
hw/cr16c/virt.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include "boot.h"
|
||||
#include "cpu-qom.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
typedef struct VirtMachineState {
|
||||
MachineState parent_obj;
|
||||
CR16CCPU cpu;
|
||||
MemoryRegion flash;
|
||||
} VirtMachineState;
|
||||
|
||||
typedef struct VirtMachineClass {
|
||||
MachineClass parent_class;
|
||||
} VirtMachineClass;
|
||||
|
||||
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
|
||||
DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_VIRT_MACHINE)
|
||||
|
||||
static void virt_init(MachineState* machine)
|
||||
{
|
||||
VirtMachineState* m_state = VIRT_MACHINE(machine);
|
||||
|
||||
object_initialize_child(OBJECT(machine), "cpu", &m_state->cpu, TYPE_CR16C_CPU);
|
||||
object_property_set_bool(OBJECT(&m_state->cpu), "realized", true, &error_abort);
|
||||
|
||||
memory_region_init_ram(&m_state->flash, NULL, "flash", 16*MiB, &error_fatal);
|
||||
memory_region_add_subregion(get_system_memory(), 0, &m_state->flash);
|
||||
|
||||
if (machine->firmware) {
|
||||
if (!cr16c_load_firmware(&m_state->cpu, &m_state->flash, machine->firmware)) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void virt_class_init(ObjectClass* oc, void* data)
|
||||
{
|
||||
MachineClass* mc = MACHINE_CLASS(oc);
|
||||
mc->desc = "Generic CR16C board for debugging, testing and development";
|
||||
mc->init = virt_init;
|
||||
mc->default_cpus = 1;
|
||||
mc->min_cpus = 1;
|
||||
mc->max_cpus = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_parallel = 1;
|
||||
mc->is_default = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo virt_machine_types[] = {
|
||||
{
|
||||
.name = TYPE_VIRT_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
.instance_size = sizeof(VirtMachineState),
|
||||
.class_size = sizeof(VirtMachineClass),
|
||||
.class_init = virt_class_init,
|
||||
}
|
||||
};
|
||||
DEFINE_TYPES(virt_machine_types);
|
||||
|
|
@ -243,7 +243,6 @@ enum bfd_architecture
|
|||
#define bfd_mach_rx_v3 0x77
|
||||
bfd_arch_loongarch,
|
||||
bfd_arch_cr16c,
|
||||
#define bfd_mach_sc14450 0x450
|
||||
bfd_arch_last
|
||||
};
|
||||
#define bfd_mach_s390_31 31
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ blobs = [
|
|||
'npcm8xx_bootrom.bin',
|
||||
'vof.bin',
|
||||
'vof-nvram.bin',
|
||||
'sc14461-bios.img',
|
||||
]
|
||||
|
||||
dtc = find_program('dtc', required: false)
|
||||
|
|
|
|||
1
pc-bios/sc14461-bios.img
Normal file
1
pc-bios/sc14461-bios.img
Normal file
|
|
@ -0,0 +1 @@
|
|||
<05><><EFBFBD>
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
OBJECT_DECLARE_CPU_TYPE(CR16CCPU, CR16CCPUClass, CR16C_CPU)
|
||||
|
||||
typedef struct CR16CCPUDef CR16CCPUDef;
|
||||
struct CR16CCPUClass {
|
||||
/*< private >*/
|
||||
CPUClass parent_class;
|
||||
|
|
@ -15,8 +14,6 @@ struct CR16CCPUClass {
|
|||
/*< public >*/
|
||||
DeviceRealize parent_realize;
|
||||
ResettablePhases parent_phases;
|
||||
|
||||
CR16CCPUDef* cpu_def;
|
||||
};
|
||||
|
||||
#endif // CR16C_CPU_QOM_H
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ static void cr16c_cpu_reset_hold(Object *obj, ResetType type)
|
|||
}
|
||||
|
||||
static ObjectClass* cr16c_cpu_class_by_name(const char *cpu_model) {
|
||||
return object_class_by_name(CR16C_CPU_TYPE_NAME("SC14450C"));
|
||||
return object_class_by_name(TYPE_CR16C_CPU);
|
||||
}
|
||||
|
||||
static bool cr16c_cpu_has_work(CPUState *cs)
|
||||
|
|
@ -182,55 +182,14 @@ static void cr16c_cpu_class_init(ObjectClass *oc, void *data)
|
|||
cc->tcg_ops = &cr16c_tcg_ops;
|
||||
}
|
||||
|
||||
static const CR16CCPUDef cr16c_cpu_defs[] = {
|
||||
static const TypeInfo cr16c_cpu_archs[] = {
|
||||
{
|
||||
.name = "SC14450C",
|
||||
.parent_microarch = TYPE_CR16C_CPU,
|
||||
}
|
||||
};
|
||||
|
||||
static void cr16c_cpu_cpudef_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
CR16CCPUClass* acc = CR16C_CPU_CLASS(oc);
|
||||
acc->cpu_def = data;
|
||||
}
|
||||
|
||||
static char* cr16c_cpu_type_name(const char* model_name)
|
||||
{
|
||||
return g_strdup_printf(CR16C_CPU_TYPE_NAME("%s"), model_name);
|
||||
}
|
||||
|
||||
static void cr16c_register_cpudef_type(const struct CR16CCPUDef* def)
|
||||
{
|
||||
char* cpu_model_name = cr16c_cpu_type_name(def->name);
|
||||
TypeInfo ti = {
|
||||
.name = cpu_model_name,
|
||||
.parent = def->parent_microarch,
|
||||
.class_init = cr16c_cpu_cpudef_class_init,
|
||||
.class_data = (void *)def,
|
||||
};
|
||||
|
||||
type_register_static(&ti);
|
||||
g_free(cpu_model_name);
|
||||
}
|
||||
|
||||
static const TypeInfo cr16c_cpu_arch = {
|
||||
.name = TYPE_CR16C_CPU,
|
||||
.parent = TYPE_CPU,
|
||||
.instance_size = sizeof(CR16CCPU),
|
||||
.abstract = true,
|
||||
.class_size = sizeof(CR16CCPUClass),
|
||||
.class_init = cr16c_cpu_class_init,
|
||||
},
|
||||
};
|
||||
|
||||
static void cr16c_cpu_register_types(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
type_register_static(&cr16c_cpu_arch);
|
||||
for (i = 0; i < ARRAY_SIZE(cr16c_cpu_defs); i++) {
|
||||
cr16c_register_cpudef_type(&cr16c_cpu_defs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
type_init(cr16c_cpu_register_types)
|
||||
DEFINE_TYPES(cr16c_cpu_archs)
|
||||
|
|
|
|||
|
|
@ -8,16 +8,6 @@
|
|||
#define CR16C_REG_COUNT 14
|
||||
#define CR16C_FIRST_32B_REG 12
|
||||
|
||||
|
||||
struct CR16CCPUDef {
|
||||
const char* name;
|
||||
const char* parent_microarch;
|
||||
size_t core_type;
|
||||
size_t series_type;
|
||||
size_t clock_speed;
|
||||
};
|
||||
#define CR16C_CPU_TYPE_SUFFIX "-" TYPE_CR16C_CPU
|
||||
#define CR16C_CPU_TYPE_NAME(name) (name CR16C_CPU_TYPE_SUFFIX)
|
||||
#define CPU_RESOLVING_TYPE TYPE_CR16C_CPU
|
||||
|
||||
// TODO: Interrupt mask?
|
||||
|
|
@ -47,7 +37,6 @@ struct ArchCPU {
|
|||
|
||||
/*< public >*/
|
||||
CPUCR16CState env;
|
||||
CPUNegativeOffsetState neg;
|
||||
};
|
||||
|
||||
int cr16c_print_insn(bfd_vma addr, disassemble_info *info);
|
||||
|
|
|
|||
|
|
@ -160,9 +160,9 @@ LSHD_rp 0100 0111 .... .... @shiftd_rp
|
|||
|
||||
%br_disp8 56:4 48:4 !function=get_disp8
|
||||
|
||||
@br_disp8 .... .... cond:4 .... disp=%br_disp8
|
||||
BRCOND 0001 .... cond:4 .... disp=%br_disp8
|
||||
|
||||
BRCOND_disp8 0001 .... .... .... @br_disp8
|
||||
JCOND 0000 1010 cond:4 ra:4
|
||||
|
||||
EXCP 0000 0000 1100 id:4
|
||||
|
||||
|
|
|
|||
|
|
@ -1057,11 +1057,8 @@ static bool trans_EXCP(DisasContext *ctx, arg_EXCP *a) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) {
|
||||
TCGLabel* l = gen_new_label();
|
||||
static void gen_br_cond(DisasContext* ctx, int cond, TCGLabel* l) {
|
||||
TCGv temp;
|
||||
uint32_t pc_this = ctx->base.pc_next - 2;
|
||||
uint32_t dest = pc_this + a->disp*2;
|
||||
|
||||
/* Flags may have higher bits set */
|
||||
tcg_gen_andi_i32(f_n, f_n, 1);
|
||||
|
|
@ -1070,9 +1067,7 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) {
|
|||
tcg_gen_andi_i32(f_l, f_l, 1);
|
||||
tcg_gen_andi_i32(f_c, f_c, 1);
|
||||
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
switch (a->cond) {
|
||||
switch (cond) {
|
||||
case CR16C_COND_EQ:
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, f_z, 1, l);
|
||||
break;
|
||||
|
|
@ -1129,6 +1124,15 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) {
|
|||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static bool trans_BRCOND(DisasContext* ctx, arg_BRCOND *a) {
|
||||
TCGLabel* l = gen_new_label();
|
||||
|
||||
gen_br_cond(ctx, a->cond, l);
|
||||
|
||||
uint32_t pc_this = ctx->base.pc_next - 2;
|
||||
uint32_t dest = pc_this + a->disp*2;
|
||||
|
||||
gen_goto(&ctx->base, ctx->base.pc_next, 0);
|
||||
|
||||
|
|
@ -1136,6 +1140,24 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) {
|
|||
|
||||
gen_goto(&ctx->base, dest, 1);
|
||||
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_JCOND(DisasContext* ctx, arg_JCOND *a) {
|
||||
TCGLabel* l = gen_new_label();
|
||||
|
||||
gen_br_cond(ctx, a->cond, l);
|
||||
|
||||
tcg_gen_movi_i32(pc, ctx->base.pc_next);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
|
||||
gen_set_label(l);
|
||||
|
||||
tcg_gen_mov_i32(pc, r[a->ra]);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ CR16C_TESTS = $(patsubst $(CR16C_SRC)/%.S, %, $(CR16C_ALL))
|
|||
TESTS += $(CR16C_TESTS)
|
||||
VPATH += $(CR16C_SRC)
|
||||
|
||||
QEMU_OPTS+=-M sc14450board -nographic $(EXTFLAGS) -bios
|
||||
QEMU_OPTS+=-M virt -nographic $(EXTFLAGS) -bios
|
||||
|
||||
LDFLAGS = -nostdlib -static
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue