Map IR, STM, ASCLIN and SCU into the tc27x SoC at their hardware addresses. ASCLIN0 gets serial_hd(0), peripheral IRQs are routed to the IR.
Interrupt delivery to the CPU is not yet wired -- that needs do_interrupt and CPU-side GPIO inputs (follow-up series). Signed-off-by: Parthiban Nallathambi <[email protected]> --- hw/tricore/Kconfig | 15 ++++++++++ hw/tricore/tc27x_soc.c | 62 ++++++++++++++++++++++++++++++++++++++++++ include/hw/tricore/tc27x_soc.h | 13 +++++++++ 3 files changed, 90 insertions(+) diff --git a/hw/tricore/Kconfig b/hw/tricore/Kconfig index 6c04f64949..fd589f7b78 100644 --- a/hw/tricore/Kconfig +++ b/hw/tricore/Kconfig @@ -8,6 +8,21 @@ config TRIBOARD default y depends on TRICORE select TC27X_SOC + select TC39X_SOC config TC27X_SOC bool + select TRICORE_ASCLIN + select TRICORE_IRBUS + select TRICORE_SCU + select TRICORE_STM + +config TC39X_SOC + bool + select TRICORE_ASCLIN + select TRICORE_IRBUS + select TRICORE_SCU + select TRICORE_STM + +config TRICORE_SCU + bool diff --git a/hw/tricore/tc27x_soc.c b/hw/tricore/tc27x_soc.c index 5b1b07cee1..2995ef8631 100644 --- a/hw/tricore/tc27x_soc.c +++ b/hw/tricore/tc27x_soc.c @@ -20,10 +20,13 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "hw/core/clock.h" +#include "hw/core/qdev-clock.h" #include "hw/core/sysbus.h" #include "hw/core/loader.h" #include "qemu/units.h" #include "hw/misc/unimp.h" +#include "system/system.h" #include "hw/tricore/tc27x_soc.h" #include "hw/tricore/triboard.h" @@ -61,6 +64,11 @@ const MemmapEntry tc27x_soc_memmap[] = { [TC27XD_EMEM_U] = { 0xBF000000, 0x0 }, [TC27XD_PSPRX] = { 0xC0000000, 0x0 }, [TC27XD_DSPRX] = { 0xD0000000, 0x0 }, + [TC27XD_IR_INT] = { 0xF0037000, 0x0 }, + [TC27XD_IR_SRC] = { 0xF0038000, 0x0 }, + [TC27XD_STM0] = { 0xF0001000, 0x0 }, + [TC27XD_ASCLIN0] = { 0xF0000600, 0x0 }, + [TC27XD_SCU] = { 0xF0036000, 0x0 }, }; /* @@ -179,9 +187,17 @@ static void tc27x_soc_init_memory_mapping(DeviceState *dev_soc) sc->memmap[TC27XD_EMEM_U].base); } +/* TC27x interrupt source indices (SRC register numbers) */ +#define TC27X_SRC_STM0_SR0 0xC0 +#define TC27X_SRC_ASCLIN0_TX 0x14 +#define TC27X_SRC_ASCLIN0_RX 0x15 +#define TC27X_SRC_ASCLIN0_ERR 0x16 + static void tc27x_soc_realize(DeviceState *dev_soc, Error **errp) { TC27XSoCState *s = TC27X_SOC(dev_soc); + TC27XSoCClass *sc = TC27X_SOC_GET_CLASS(s); + Clock *fstm; Error *err = NULL; qdev_realize(DEVICE(&s->cpu), NULL, &err); @@ -191,6 +207,48 @@ static void tc27x_soc_realize(DeviceState *dev_soc, Error **errp) } tc27x_soc_init_memory_mapping(dev_soc); + + /* STM clock: 50 MHz (fSTM derived from fSPB) */ + fstm = clock_new(OBJECT(dev_soc), "fstm"); + clock_set_hz(fstm, 50000000); + qdev_connect_clock_in(DEVICE(&s->stm), "fstm", fstm); + + /* Connect ASCLIN to first serial device */ + qdev_prop_set_chr(DEVICE(&s->asclin), "chardev", serial_hd(0)); + + /* Realize peripherals */ + sysbus_realize(SYS_BUS_DEVICE(&s->ir), &error_fatal); + sysbus_realize(SYS_BUS_DEVICE(&s->stm), &error_fatal); + sysbus_realize(SYS_BUS_DEVICE(&s->asclin), &error_fatal); + sysbus_realize(SYS_BUS_DEVICE(&s->scu), &error_fatal); + + /* Map peripheral MMIO regions */ + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ir), 0, + sc->memmap[TC27XD_IR_INT].base); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ir), 1, + sc->memmap[TC27XD_IR_SRC].base); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->stm), 0, + sc->memmap[TC27XD_STM0].base); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->asclin), 0, + sc->memmap[TC27XD_ASCLIN0].base); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, + sc->memmap[TC27XD_SCU].base); + + /* Connect ASCLIN IRQs to interrupt router */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->asclin), 0, + qdev_get_gpio_in_named(DEVICE(&s->ir), "irq", + TC27X_SRC_ASCLIN0_RX)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->asclin), 1, + qdev_get_gpio_in_named(DEVICE(&s->ir), "irq", + TC27X_SRC_ASCLIN0_TX)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->asclin), 2, + qdev_get_gpio_in_named(DEVICE(&s->ir), "irq", + TC27X_SRC_ASCLIN0_ERR)); + + /* Connect STM compare match IRQ to interrupt router */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->stm), 0, + qdev_get_gpio_in_named(DEVICE(&s->ir), "irq", + TC27X_SRC_STM0_SR0)); } static void tc27x_soc_init(Object *obj) @@ -199,6 +257,10 @@ static void tc27x_soc_init(Object *obj) TC27XSoCClass *sc = TC27X_SOC_GET_CLASS(s); object_initialize_child(obj, "tc27x", &s->cpu, sc->cpu_type); + object_initialize_child(obj, "ir", &s->ir, TYPE_TRICORE_IR); + object_initialize_child(obj, "stm", &s->stm, TYPE_TRICORE_STM); + object_initialize_child(obj, "asclin", &s->asclin, TYPE_TRICORE_ASCLIN); + object_initialize_child(obj, "scu", &s->scu, TYPE_TRICORE_SCU); } static void tc27x_soc_class_init(ObjectClass *klass, const void *data) diff --git a/include/hw/tricore/tc27x_soc.h b/include/hw/tricore/tc27x_soc.h index 2d2bdca3fd..4e24789d4d 100644 --- a/include/hw/tricore/tc27x_soc.h +++ b/include/hw/tricore/tc27x_soc.h @@ -22,6 +22,10 @@ #define TC27X_SOC_H #include "hw/core/sysbus.h" +#include "hw/char/tricore_asclin.h" +#include "hw/intc/tricore_ir.h" +#include "hw/timer/tricore_stm.h" +#include "hw/tricore/tricore_scu.h" #include "target/tricore/cpu.h" #include "qom/object.h" @@ -65,6 +69,10 @@ typedef struct TC27XSoCState { /*< public >*/ TriCoreCPU cpu; + TriCoreIRState ir; + TriCoreSTMState stm; + TriCoreASCLINState asclin; + TriCoreSCUState scu; MemoryRegion dsprX; MemoryRegion psprX; @@ -124,6 +132,11 @@ enum { TC27XD_EMEM_U, TC27XD_PSPRX, TC27XD_DSPRX, + TC27XD_IR_INT, + TC27XD_IR_SRC, + TC27XD_STM0, + TC27XD_ASCLIN0, + TC27XD_SCU, }; #endif -- 2.47.3
