#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);