wip
This commit is contained in:
parent
c37a4513c2
commit
4abbc2b163
6 changed files with 179 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
cr16c_ss = ss.source_set()
|
cr16c_ss = ss.source_set()
|
||||||
cr16c_ss.add(files('virt.c'))
|
cr16c_ss.add(files('virt.c'))
|
||||||
cr16c_ss.add(files('sc14461.c'))
|
cr16c_ss.add(files('sc14461.c'))
|
||||||
|
cr16c_ss.add(files('sc14480.c'))
|
||||||
cr16c_ss.add(files('de410.c'))
|
cr16c_ss.add(files('de410.c'))
|
||||||
cr16c_ss.add(files('boot.c'))
|
cr16c_ss.add(files('boot.c'))
|
||||||
hw_arch += {'cr16c': cr16c_ss}
|
hw_arch += {'cr16c': cr16c_ss}
|
||||||
|
|
|
||||||
67
hw/cr16c/sc14480.c
Normal file
67
hw/cr16c/sc14480.c
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include "sc14480.h"
|
||||||
|
#include "cpu-qom.h"
|
||||||
|
#include "system/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 sc14480_realize(DeviceState* dev, Error** errp)
|
||||||
|
{
|
||||||
|
SC14480McuState* s = SC14480_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, "sc14480-bios.img");
|
||||||
|
if (!cr16c_load_firmware(&s->cpu, &s->boot_rom, bios_path)) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sc14480_reset_hold(Object *obj, ResetType type) {
|
||||||
|
SC14480McuClass* mcu_class = SC14480_MCU_GET_CLASS(obj);
|
||||||
|
SC14480McuState* mcu_state = SC14480_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 sc14480_class_init(ObjectClass* oc, const void* data)
|
||||||
|
{
|
||||||
|
DeviceClass* dc = DEVICE_CLASS(oc);
|
||||||
|
SC14480McuClass* sc14480 = SC14480_MCU_CLASS(oc);
|
||||||
|
ResettableClass *rc = RESETTABLE_CLASS(oc);
|
||||||
|
|
||||||
|
resettable_class_set_parent_phases(rc, NULL, sc14480_reset_hold, NULL, &sc14480->parent_phases);
|
||||||
|
|
||||||
|
dc->realize = sc14480_realize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo sc14480_mcu_types[] = {
|
||||||
|
{
|
||||||
|
.name = TYPE_SC14480_MCU,
|
||||||
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
|
.instance_size = sizeof(SC14480McuState),
|
||||||
|
.class_size = sizeof(SC14480McuClass),
|
||||||
|
.class_init = sc14480_class_init,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
DEFINE_TYPES(sc14480_mcu_types)
|
||||||
30
hw/cr16c/sc14480.h
Normal file
30
hw/cr16c/sc14480.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef HW_SC14480_H
|
||||||
|
#define HW_SC14480_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "hw/sysbus.h"
|
||||||
|
|
||||||
|
#define TYPE_SC14480_MCU "SC14480"
|
||||||
|
|
||||||
|
typedef struct SC14480McuState SC14480McuState;
|
||||||
|
DECLARE_INSTANCE_CHECKER(SC14480McuState, SC14480_MCU, TYPE_SC14480_MCU)
|
||||||
|
|
||||||
|
struct SC14480McuState {
|
||||||
|
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 SC14480McuClass {
|
||||||
|
SysBusDeviceClass parent_class;
|
||||||
|
|
||||||
|
ResettablePhases parent_phases;
|
||||||
|
} SC14480McuClass;
|
||||||
|
DECLARE_CLASS_CHECKERS(SC14480McuClass, SC14480_MCU, TYPE_SC14480_MCU)
|
||||||
|
|
||||||
|
#endif /* HW_SC14480_H */
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
#include "system/system.h"
|
||||||
|
|
||||||
typedef struct VirtMachineState {
|
typedef struct VirtMachineState {
|
||||||
MachineState parent_obj;
|
MachineState parent_obj;
|
||||||
|
|
@ -22,8 +23,36 @@ typedef struct VirtMachineClass {
|
||||||
|
|
||||||
DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_VIRT_MACHINE)
|
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)
|
static void virt_init(MachineState* machine)
|
||||||
{
|
{
|
||||||
|
|
||||||
VirtMachineState* m_state = VIRT_MACHINE(machine);
|
VirtMachineState* m_state = VIRT_MACHINE(machine);
|
||||||
|
|
||||||
object_initialize_child(OBJECT(machine), "cpu", &m_state->cpu, TYPE_CR16C_CPU);
|
object_initialize_child(OBJECT(machine), "cpu", &m_state->cpu, TYPE_CR16C_CPU);
|
||||||
|
|
@ -33,6 +62,13 @@ static void virt_init(MachineState* machine)
|
||||||
memory_region_add_subregion(get_system_memory(), 0, &m_state->flash);
|
memory_region_add_subregion(get_system_memory(), 0, &m_state->flash);
|
||||||
|
|
||||||
create_unimplemented_device("mmio", 0xFF0000, 0xFFFBFF - 0xFF0000);
|
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);
|
//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
|
create_unimplemented_device("icu", 0xFFFC00, 0xFFFFFF - 0xFFFC00); // interrupt controller unit
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,35 @@ static int cr16c_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Priority:
|
||||||
|
// DBG > IAD > NMI > Interrupt > ISE > PSR.P = 1, some instruction suspend stuff
|
||||||
|
// interrupt dispatch vectors
|
||||||
|
#define INT_RESERVED_0 0
|
||||||
|
#define INT_NMI 1
|
||||||
|
#define INT_RESERVED_2 2
|
||||||
|
#define INT_RESERVED_3 3
|
||||||
|
#define INT_RESERVED_4 4
|
||||||
|
#define INT_SVC 5 // Supervisor Call Trap
|
||||||
|
#define INT_DVZ 6 // Divide By Zero
|
||||||
|
#define INT_FLG 7 // Flag
|
||||||
|
#define INT_BPT 8 // Breakpoint
|
||||||
|
#define INT_TRC 9 // Trace
|
||||||
|
#define INT_UND 10 // Undefined instruction
|
||||||
|
#define INT_RESERVED_11 11
|
||||||
|
#define INT_IAD 12 // Illegal Address
|
||||||
|
#define INT_RESERVED_13 13
|
||||||
|
#define INT_DBG 14 // Debug
|
||||||
|
#define INT_ISE 15 // In-System Emulator
|
||||||
|
#define INT_MASKABLE_MIN 16
|
||||||
|
#define INT_MASKABLE_MAX 127
|
||||||
|
|
||||||
static bool cr16c_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
static bool cr16c_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||||
{
|
{
|
||||||
|
//CPUCR16CState *env = cpu_env(cs);
|
||||||
|
|
||||||
|
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||||
|
|
||||||
|
}
|
||||||
// TODO
|
// TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -213,6 +240,21 @@ static void cr16c_cpu_class_init(ObjectClass *oc, const void *data)
|
||||||
cc->tcg_ops = &cr16c_tcg_ops;
|
cc->tcg_ops = &cr16c_tcg_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cr16c_cpu_set_int(void *opaque, int irq, int level)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cr16c_cpu_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
CR16CCPU *cpu = CR16C_CPU(obj);
|
||||||
|
|
||||||
|
/* Set the number of interrupts supported by the CPU. */
|
||||||
|
qdev_init_gpio_in(DEVICE(cpu), cr16c_cpu_set_int,
|
||||||
|
//sizeof(cpu->env.intsrc) * 8);
|
||||||
|
127 - 15);
|
||||||
|
}
|
||||||
|
|
||||||
static const TypeInfo cr16c_cpu_archs[] = {
|
static const TypeInfo cr16c_cpu_archs[] = {
|
||||||
{
|
{
|
||||||
.name = TYPE_CR16C_CPU,
|
.name = TYPE_CR16C_CPU,
|
||||||
|
|
@ -220,6 +262,7 @@ static const TypeInfo cr16c_cpu_archs[] = {
|
||||||
.instance_size = sizeof(CR16CCPU),
|
.instance_size = sizeof(CR16CCPU),
|
||||||
.class_size = sizeof(CR16CCPUClass),
|
.class_size = sizeof(CR16CCPUClass),
|
||||||
.class_init = cr16c_cpu_class_init,
|
.class_init = cr16c_cpu_class_init,
|
||||||
|
.instance_init = cr16c_cpu_initfn
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,8 @@ BR0 0000 11 word:1 ne:1 dest:4 src:4
|
||||||
|
|
||||||
JCOND 0000 1010 cond:4 ra:4
|
JCOND 0000 1010 cond:4 ra:4
|
||||||
|
|
||||||
|
#JAL 0000 0000 1101 ....
|
||||||
|
|
||||||
EXCP 0000 0000 1100 id:4
|
EXCP 0000 0000 1100 id:4
|
||||||
|
|
||||||
&bal dest
|
&bal dest
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue