qemu-cr16/hw/cr16c/virt.c
fridtjof 82c6a0097e wip
2026-05-04 13:33:10 +02:00

109 lines
3.2 KiB
C

#include "boot.h"
#include "cpu-qom.h"
#include "system/address-spaces.h"
#include "hw/boards.h"
#include "hw/misc/unimp.h"
#include "qapi/error.h"
#include "qemu/units.h"
#include "qom/object.h"
#include "system/system.h"
typedef struct VirtMachineState {
MachineState parent_obj;
CR16CCPU cpu;
MemoryRegion flash;
MemoryRegion mmio_alias;
} 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)
// SC14480 vectors, all with exception priority 4
enum {
// lowest
ACCESS12_INT = 16,
KEYB_INT = 17,
DMA1_INT = 17, // secondary function with DINT
// RESERVED_INT = 18,
CT_CLASSD_INT = 19,
UART_RI_INT = 20,
DMA2_INT = 20, // secondary function with DINT
UART_TI_INT = 21,
DMA3_INT = 21, // secondary function with DINT
SPI_INT = 22,
DMA0_INT = 22, // secondary function with DINT
TIM0_INT = 23,
TIM1_INT = 24,
CLK100_INT = 25,
DIP_INT = 26,
AD_INT = 27,
SPI2_INT = 28,
DSP_INT = 29,
// RESERVED = 30,
// highest
};
// TODO map these from qemu irqs somewhere
DeviceState *sc144uart_create(hwaddr addr, qemu_irq irq, Chardev *chr);
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 - 64*KiB, &error_fatal);
memory_region_add_subregion(get_system_memory(), 0, &m_state->flash);
create_unimplemented_device("mmio", 0xFF0000, 0xFFFBFF - 0xFF0000);
qemu_irq pic[10]; // TODO pick a reasonable value and name it
for (int n = 0; n < 10; n++) {
pic[n] = qdev_get_gpio_in(&m_state->cpu.parent_obj.parent_obj, n);
}
(void)pic;
sc144uart_create(0xFF4900, pic[0], NULL);//serial_hd(0));
//memory_region_init_alias(&m_state->mmio_alias, NULL, "mmio_alias", &m_state->flash, 0xF0000, 0xFFFFF - 0xF0000);
create_unimplemented_device("icu", 0xFFFC00, 0xFFFFFF - 0xFFFC00); // interrupt controller unit
// present on some CR16C implementations (external RAM?)
create_unimplemented_device("unknown", 0x1000000, 256*MiB - 16*MiB);
if (machine->firmware) {
if (!cr16c_load_firmware(&m_state->cpu, &m_state->flash, machine->firmware)) {
exit(1);
}
}
}
static void virt_class_init(ObjectClass* oc, const 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);