From 09fc50cdce522cfed21bfd2a08b575c9f1a3c30b Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Fri, 1 Apr 2022 00:20:16 +0200 Subject: timer: cadence_ttc: Break out header file to allow embedding Break out header file to allow embedding of the the TTC. Signed-off-by: Edgar E. Iglesias Reviewed-by: Alistair Francis Reviewed-by: Luc Michel Reviewed-by: Francisco Iglesias Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 include/hw/timer/cadence_ttc.h (limited to 'include') diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h new file mode 100644 index 0000000..e125138 --- /dev/null +++ b/include/hw/timer/cadence_ttc.h @@ -0,0 +1,54 @@ +/* + * Xilinx Zynq cadence TTC model + * + * Copyright (c) 2011 Xilinx Inc. + * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com) + * Copyright (c) 2012 PetaLogix Pty Ltd. + * Written By Haibing Ma + * M. Habib + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ +#ifndef HW_TIMER_CADENCE_TTC_H +#define HW_TIMER_CADENCE_TTC_H + +#include "hw/sysbus.h" +#include "qemu/timer.h" + +typedef struct { + QEMUTimer *timer; + int freq; + + uint32_t reg_clock; + uint32_t reg_count; + uint32_t reg_value; + uint16_t reg_interval; + uint16_t reg_match[3]; + uint32_t reg_intr; + uint32_t reg_intr_en; + uint32_t reg_event_ctrl; + uint32_t reg_event; + + uint64_t cpu_time; + unsigned int cpu_time_valid; + + qemu_irq irq; +} CadenceTimerState; + +#define TYPE_CADENCE_TTC "cadence_ttc" +OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC) + +struct CadenceTTCState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + CadenceTimerState timer[3]; +}; + +#endif -- cgit v1.1 From 51af6231ad344c64069faad630d0889b9723ed3a Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Fri, 1 Apr 2022 00:20:17 +0200 Subject: hw/arm/xlnx-zynqmp: Connect 4 TTC timers Connect the 4 TTC timers on the ZynqMP. Signed-off-by: Edgar E. Iglesias Reviewed-by: Alistair Francis Reviewed-by: Luc Michel Reviewed-by: Francisco Iglesias Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-zynqmp.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 9d9a9d0..85fd9f5 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -41,6 +41,7 @@ #include "hw/or-irq.h" #include "hw/misc/xlnx-zynqmp-apu-ctrl.h" #include "hw/misc/xlnx-zynqmp-crf.h" +#include "hw/timer/cadence_ttc.h" #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp" OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) @@ -84,6 +85,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) #define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \ XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE) +#define XLNX_ZYNQMP_NUM_TTC 4 + /* * Unimplemented mmio regions needed to boot some images. */ @@ -128,6 +131,7 @@ struct XlnxZynqMPState { qemu_or_irq qspi_irq_orgate; XlnxZynqMPAPUCtrl apu_ctrl; XlnxZynqMPCRF crf; + CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC]; char *boot_cpu; ARMCPU *boot_cpu_ptr; -- cgit v1.1 From 8779d00c4e337a9e0d85c9abf456e3c713fad808 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Wed, 6 Apr 2022 18:43:00 +0100 Subject: hw/arm: versal: Create an APU CPU Cluster Create an APU CPU Cluster. This is in preparation to add the RPU. Signed-off-by: Edgar E. Iglesias Reviewed-by: Francisco Iglesias Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-versal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 0728316..d2d3028 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -14,6 +14,7 @@ #include "hw/sysbus.h" #include "hw/arm/boot.h" +#include "hw/cpu/cluster.h" #include "hw/or-irq.h" #include "hw/sd/sdhci.h" #include "hw/intc/arm_gicv3.h" @@ -49,6 +50,7 @@ struct Versal { struct { struct { MemoryRegion mr; + CPUClusterState cluster; ARMCPU cpu[XLNX_VERSAL_NR_ACPUS]; GICv3State gic; } apu; -- cgit v1.1 From 67a645a35110f300144ae844cbf839762abcd98d Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Wed, 6 Apr 2022 18:43:01 +0100 Subject: hw/arm: versal: Add the Cortex-R5Fs Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit) subsystem. Signed-off-by: Edgar E. Iglesias Reviewed-by: Francisco Iglesias Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-versal.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index d2d3028..155e8c4 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -35,6 +35,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL) #define XLNX_VERSAL_NR_ACPUS 2 +#define XLNX_VERSAL_NR_RCPUS 2 #define XLNX_VERSAL_NR_UARTS 2 #define XLNX_VERSAL_NR_GEMS 2 #define XLNX_VERSAL_NR_ADMAS 8 @@ -73,6 +74,15 @@ struct Versal { VersalUsb2 usb; } iou; + /* Real-time Processing Unit. */ + struct { + MemoryRegion mr; + MemoryRegion mr_ps_alias; + + CPUClusterState cluster; + ARMCPU cpu[XLNX_VERSAL_NR_RCPUS]; + } rpu; + struct { qemu_or_irq irq_orgate; XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM]; -- cgit v1.1 From 369e5cb0c948b65e0845ca3394e25d757dd93206 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Wed, 6 Apr 2022 18:43:02 +0100 Subject: hw/misc: Add a model of the Xilinx Versal CRL Add a model of the Xilinx Versal CRL. Signed-off-by: Edgar E. Iglesias Reviewed-by: Frederic Konrad Reviewed-by: Francisco Iglesias Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com Signed-off-by: Peter Maydell --- include/hw/misc/xlnx-versal-crl.h | 235 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 include/hw/misc/xlnx-versal-crl.h (limited to 'include') diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h new file mode 100644 index 0000000..2857f41 --- /dev/null +++ b/include/hw/misc/xlnx-versal-crl.h @@ -0,0 +1,235 @@ +/* + * QEMU model of the Clock-Reset-LPD (CRL). + * + * Copyright (c) 2022 Xilinx Inc. + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Written by Edgar E. Iglesias + */ +#ifndef HW_MISC_XLNX_VERSAL_CRL_H +#define HW_MISC_XLNX_VERSAL_CRL_H + +#include "hw/sysbus.h" +#include "hw/register.h" +#include "target/arm/cpu.h" + +#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl" +OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL) + +REG32(ERR_CTRL, 0x0) + FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1) +REG32(IR_STATUS, 0x4) + FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1) +REG32(IR_MASK, 0x8) + FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1) +REG32(IR_ENABLE, 0xc) + FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1) +REG32(IR_DISABLE, 0x10) + FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1) +REG32(WPROT, 0x1c) + FIELD(WPROT, ACTIVE, 0, 1) +REG32(PLL_CLK_OTHER_DMN, 0x20) + FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1) +REG32(RPLL_CTRL, 0x40) + FIELD(RPLL_CTRL, POST_SRC, 24, 3) + FIELD(RPLL_CTRL, PRE_SRC, 20, 3) + FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2) + FIELD(RPLL_CTRL, FBDIV, 8, 8) + FIELD(RPLL_CTRL, BYPASS, 3, 1) + FIELD(RPLL_CTRL, RESET, 0, 1) +REG32(RPLL_CFG, 0x44) + FIELD(RPLL_CFG, LOCK_DLY, 25, 7) + FIELD(RPLL_CFG, LOCK_CNT, 13, 10) + FIELD(RPLL_CFG, LFHF, 10, 2) + FIELD(RPLL_CFG, CP, 5, 4) + FIELD(RPLL_CFG, RES, 0, 4) +REG32(RPLL_FRAC_CFG, 0x48) + FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1) + FIELD(RPLL_FRAC_CFG, SEED, 22, 3) + FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1) + FIELD(RPLL_FRAC_CFG, ORDER, 18, 1) + FIELD(RPLL_FRAC_CFG, DATA, 0, 16) +REG32(PLL_STATUS, 0x50) + FIELD(PLL_STATUS, RPLL_STABLE, 2, 1) + FIELD(PLL_STATUS, RPLL_LOCK, 0, 1) +REG32(RPLL_TO_XPD_CTRL, 0x100) + FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1) + FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10) +REG32(LPD_TOP_SWITCH_CTRL, 0x104) + FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1) + FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1) + FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10) + FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3) +REG32(LPD_LSBUS_CTRL, 0x108) + FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1) + FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10) + FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3) +REG32(CPU_R5_CTRL, 0x10c) + FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1) + FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1) + FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1) + FIELD(CPU_R5_CTRL, CLKACT, 25, 1) + FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10) + FIELD(CPU_R5_CTRL, SRCSEL, 0, 3) +REG32(IOU_SWITCH_CTRL, 0x114) + FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1) + FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10) + FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3) +REG32(GEM0_REF_CTRL, 0x118) + FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1) + FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1) + FIELD(GEM0_REF_CTRL, CLKACT, 25, 1) + FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10) + FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3) +REG32(GEM1_REF_CTRL, 0x11c) + FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1) + FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1) + FIELD(GEM1_REF_CTRL, CLKACT, 25, 1) + FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10) + FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3) +REG32(GEM_TSU_REF_CTRL, 0x120) + FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1) + FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10) + FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3) +REG32(USB0_BUS_REF_CTRL, 0x124) + FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1) + FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10) + FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3) +REG32(UART0_REF_CTRL, 0x128) + FIELD(UART0_REF_CTRL, CLKACT, 25, 1) + FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10) + FIELD(UART0_REF_CTRL, SRCSEL, 0, 3) +REG32(UART1_REF_CTRL, 0x12c) + FIELD(UART1_REF_CTRL, CLKACT, 25, 1) + FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10) + FIELD(UART1_REF_CTRL, SRCSEL, 0, 3) +REG32(SPI0_REF_CTRL, 0x130) + FIELD(SPI0_REF_CTRL, CLKACT, 25, 1) + FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10) + FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3) +REG32(SPI1_REF_CTRL, 0x134) + FIELD(SPI1_REF_CTRL, CLKACT, 25, 1) + FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10) + FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3) +REG32(CAN0_REF_CTRL, 0x138) + FIELD(CAN0_REF_CTRL, CLKACT, 25, 1) + FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10) + FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3) +REG32(CAN1_REF_CTRL, 0x13c) + FIELD(CAN1_REF_CTRL, CLKACT, 25, 1) + FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10) + FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3) +REG32(I2C0_REF_CTRL, 0x140) + FIELD(I2C0_REF_CTRL, CLKACT, 25, 1) + FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10) + FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3) +REG32(I2C1_REF_CTRL, 0x144) + FIELD(I2C1_REF_CTRL, CLKACT, 25, 1) + FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10) + FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3) +REG32(DBG_LPD_CTRL, 0x148) + FIELD(DBG_LPD_CTRL, CLKACT, 25, 1) + FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10) + FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3) +REG32(TIMESTAMP_REF_CTRL, 0x14c) + FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1) + FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10) + FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3) +REG32(CRL_SAFETY_CHK, 0x150) +REG32(PSM_REF_CTRL, 0x154) + FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10) + FIELD(PSM_REF_CTRL, SRCSEL, 0, 3) +REG32(DBG_TSTMP_CTRL, 0x158) + FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1) + FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10) + FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3) +REG32(CPM_TOPSW_REF_CTRL, 0x15c) + FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1) + FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10) + FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3) +REG32(USB3_DUAL_REF_CTRL, 0x160) + FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1) + FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10) + FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3) +REG32(RST_CPU_R5, 0x300) + FIELD(RST_CPU_R5, RESET_PGE, 4, 1) + FIELD(RST_CPU_R5, RESET_AMBA, 2, 1) + FIELD(RST_CPU_R5, RESET_CPU1, 1, 1) + FIELD(RST_CPU_R5, RESET_CPU0, 0, 1) +REG32(RST_ADMA, 0x304) + FIELD(RST_ADMA, RESET, 0, 1) +REG32(RST_GEM0, 0x308) + FIELD(RST_GEM0, RESET, 0, 1) +REG32(RST_GEM1, 0x30c) + FIELD(RST_GEM1, RESET, 0, 1) +REG32(RST_SPARE, 0x310) + FIELD(RST_SPARE, RESET, 0, 1) +REG32(RST_USB0, 0x314) + FIELD(RST_USB0, RESET, 0, 1) +REG32(RST_UART0, 0x318) + FIELD(RST_UART0, RESET, 0, 1) +REG32(RST_UART1, 0x31c) + FIELD(RST_UART1, RESET, 0, 1) +REG32(RST_SPI0, 0x320) + FIELD(RST_SPI0, RESET, 0, 1) +REG32(RST_SPI1, 0x324) + FIELD(RST_SPI1, RESET, 0, 1) +REG32(RST_CAN0, 0x328) + FIELD(RST_CAN0, RESET, 0, 1) +REG32(RST_CAN1, 0x32c) + FIELD(RST_CAN1, RESET, 0, 1) +REG32(RST_I2C0, 0x330) + FIELD(RST_I2C0, RESET, 0, 1) +REG32(RST_I2C1, 0x334) + FIELD(RST_I2C1, RESET, 0, 1) +REG32(RST_DBG_LPD, 0x338) + FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1) + FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1) + FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1) + FIELD(RST_DBG_LPD, RESET, 0, 1) +REG32(RST_GPIO, 0x33c) + FIELD(RST_GPIO, RESET, 0, 1) +REG32(RST_TTC, 0x344) + FIELD(RST_TTC, TTC3_RESET, 3, 1) + FIELD(RST_TTC, TTC2_RESET, 2, 1) + FIELD(RST_TTC, TTC1_RESET, 1, 1) + FIELD(RST_TTC, TTC0_RESET, 0, 1) +REG32(RST_TIMESTAMP, 0x348) + FIELD(RST_TIMESTAMP, RESET, 0, 1) +REG32(RST_SWDT, 0x34c) + FIELD(RST_SWDT, RESET, 0, 1) +REG32(RST_OCM, 0x350) + FIELD(RST_OCM, RESET, 0, 1) +REG32(RST_IPI, 0x354) + FIELD(RST_IPI, RESET, 0, 1) +REG32(RST_SYSMON, 0x358) + FIELD(RST_SYSMON, SEQ_RST, 1, 1) + FIELD(RST_SYSMON, CFG_RST, 0, 1) +REG32(RST_FPD, 0x360) + FIELD(RST_FPD, SRST, 1, 1) + FIELD(RST_FPD, POR, 0, 1) +REG32(PSM_RST_MODE, 0x370) + FIELD(PSM_RST_MODE, WAKEUP, 2, 1) + FIELD(PSM_RST_MODE, RST_MODE, 0, 2) + +#define CRL_R_MAX (R_PSM_RST_MODE + 1) + +#define RPU_MAX_CPU 2 + +struct XlnxVersalCRL { + SysBusDevice parent_obj; + qemu_irq irq; + + struct { + ARMCPU *cpu_r5[RPU_MAX_CPU]; + DeviceState *adma[8]; + DeviceState *uart[2]; + DeviceState *gem[2]; + DeviceState *usb; + } cfg; + + RegisterInfoArray *reg_array; + uint32_t regs[CRL_R_MAX]; + RegisterInfo regs_info[CRL_R_MAX]; +}; +#endif -- cgit v1.1 From d6ccfc7e6734383926fccfdb92df238761cb9423 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Wed, 6 Apr 2022 18:43:03 +0100 Subject: hw/arm: versal: Connect the CRL Connect the CRL (Clock Reset LPD) to the Versal SoC. Signed-off-by: Edgar E. Iglesias Reviewed-by: Frederic Konrad Reviewed-by: Francisco Iglesias Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-versal.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 155e8c4..cbe8a19 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -29,6 +29,7 @@ #include "hw/nvram/xlnx-versal-efuse.h" #include "hw/ssi/xlnx-versal-ospi.h" #include "hw/dma/xlnx_csu_dma.h" +#include "hw/misc/xlnx-versal-crl.h" #include "hw/misc/xlnx-versal-pmc-iou-slcr.h" #define TYPE_XLNX_VERSAL "xlnx-versal" @@ -87,6 +88,8 @@ struct Versal { qemu_or_irq irq_orgate; XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM]; } xram; + + XlnxVersalCRL crl; } lpd; /* The Platform Management Controller subsystem. */ @@ -127,6 +130,7 @@ struct Versal { #define VERSAL_TIMER_NS_EL1_IRQ 14 #define VERSAL_TIMER_NS_EL2_IRQ 10 +#define VERSAL_CRL_IRQ 10 #define VERSAL_UART0_IRQ_0 18 #define VERSAL_UART1_IRQ_0 19 #define VERSAL_USB0_IRQ_0 22 -- cgit v1.1 From 2bd84b6818c790508a65ec34e268295c3cb9315f Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:41 +0100 Subject: hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device The Exynos4210 SoC device currently uses a custom device "exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ line. We have a standard TYPE_OR_IRQ device for this now, so use that instead. (This is a migration compatibility break, but that is OK for this machine type.) Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-2-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 60b9e12..3999034 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -102,6 +102,7 @@ struct Exynos4210State { MemoryRegion bootreg_mem; I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER]; qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA]; + qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; }; #define TYPE_EXYNOS4210_SOC "exynos4210" -- cgit v1.1 From 5b2417288e9bdd437685725cd432692ed8f104e4 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:43 +0100 Subject: hw/arm/exynos4210: Put a9mpcore device into state struct The exynos4210 SoC mostly creates its child devices as if it were board code. This includes the a9mpcore object. Switch that to a new-style "embedded in the state struct" creation, because in the next commit we're going to want to refer to the object again further down in the exynos4210_realize() function. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-4-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 3999034..215c039 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -26,6 +26,7 @@ #include "hw/or-irq.h" #include "hw/sysbus.h" +#include "hw/cpu/a9mpcore.h" #include "target/arm/cpu-qom.h" #include "qom/object.h" @@ -103,6 +104,7 @@ struct Exynos4210State { I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER]; qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA]; qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; + A9MPPrivState a9mpcore; }; #define TYPE_EXYNOS4210_SOC "exynos4210" -- cgit v1.1 From c9d4940a9be2065d9d124f9963cbacea881b892c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:44 +0100 Subject: hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct The only time we use the int_gic_irq[] array in the Exynos4210Irq struct is in the exynos4210_realize() function: we initialize it with the GPIO inputs of the a9mpcore device, and then a bit later on we connect those to the outputs of the internal combiner. Now that the a9mpcore object is easily accessible as s->a9mpcore we can make the connection directly from one device to the other without going via this array. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-5-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 215c039..923ce98 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -82,7 +82,6 @@ typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; - qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ]; qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ]; qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; } Exynos4210Irq; -- cgit v1.1 From 771dee52c09ec40791a3e8651c395e6aa097c664 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:45 +0100 Subject: hw/arm/exynos4210: Coalesce board_irqs and irq_table The exynos4210 code currently has two very similar arrays of IRQs: * board_irqs is a field of the Exynos4210Irq struct which is filled in by exynos4210_init_board_irqs() with the appropriate qemu_irqs for each IRQ the board/SoC can assert * irq_table is a set of qemu_irqs pointed to from the Exynos4210State struct. It's allocated in exynos4210_init_irq, and the only behaviour these irqs have is that they pass on the level to the equivalent board_irqs[] irq The extra indirection through irq_table is unnecessary, so coalesce these into a single irq_table[] array as a direct field in Exynos4210State which exynos4210_init_board_irqs() fills in. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-6-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 923ce98..a9f1863 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -83,7 +83,6 @@ typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ]; - qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; } Exynos4210Irq; struct Exynos4210State { @@ -92,7 +91,7 @@ struct Exynos4210State { /*< public >*/ ARMCPU *cpu[EXYNOS4210_NCPUS]; Exynos4210Irq irqs; - qemu_irq *irq_table; + qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; MemoryRegion chipid_mem; MemoryRegion iram_mem; @@ -112,12 +111,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC) void exynos4210_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info); -/* Initialize exynos4210 IRQ subsystem stub */ -qemu_irq *exynos4210_init_irq(Exynos4210Irq *env); - /* Initialize board IRQs. * These IRQs contain splitted Int/External Combiner and External Gic IRQs */ -void exynos4210_init_board_irqs(Exynos4210Irq *s); +void exynos4210_init_board_irqs(Exynos4210State *s); /* Get IRQ number from exynos4210 IRQ subsystem stub. * To identify IRQ source use internal combiner group and bit number -- cgit v1.1 From 93afe073df30944191a1fe2a7fd4f0456e231720 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:47 +0100 Subject: hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c The function exynos4210_init_board_irqs() currently lives in exynos4210_gic.c, but it isn't really part of the exynos4210.gic device -- it is a function that implements (some of) the wiring up of interrupts between the SoC's GIC and combiner components. This means it fits better in exynos4210.c, which is the SoC-level code. Move it there. Similarly, exynos4210_git_irq() is used almost only in the SoC-level code, so move it too. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-8-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index a9f1863..d83e96a 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -111,10 +111,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC) void exynos4210_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info); -/* Initialize board IRQs. - * These IRQs contain splitted Int/External Combiner and External Gic IRQs */ -void exynos4210_init_board_irqs(Exynos4210State *s); - /* Get IRQ number from exynos4210 IRQ subsystem stub. * To identify IRQ source use internal combiner group and bit number * grp - group number -- cgit v1.1 From 78cb12a92c5466b792224e1f4c3e061d233d383b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:48 +0100 Subject: hw/arm/exynos4210: Put external GIC into state struct Switch the creation of the external GIC to the new-style "embedded in state struct" approach, so we can easily refer to the object elsewhere during realize. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-9-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 2 ++ include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 include/hw/intc/exynos4210_gic.h (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index d83e96a..f35ae90 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -27,6 +27,7 @@ #include "hw/or-irq.h" #include "hw/sysbus.h" #include "hw/cpu/a9mpcore.h" +#include "hw/intc/exynos4210_gic.h" #include "target/arm/cpu-qom.h" #include "qom/object.h" @@ -103,6 +104,7 @@ struct Exynos4210State { qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA]; qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; A9MPPrivState a9mpcore; + Exynos4210GicState ext_gic; }; #define TYPE_EXYNOS4210_SOC "exynos4210" diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h new file mode 100644 index 0000000..f64c406 --- /dev/null +++ b/include/hw/intc/exynos4210_gic.h @@ -0,0 +1,43 @@ +/* + * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * All rights reserved. + * + * Evgeny Voevodin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ +#ifndef HW_INTC_EXYNOS4210_GIC_H +#define HW_INTC_EXYNOS4210_GIC_H + +#include "hw/sysbus.h" + +#define TYPE_EXYNOS4210_GIC "exynos4210.gic" +OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC) + +#define EXYNOS4210_GIC_NCPUS 2 + +struct Exynos4210GicState { + SysBusDevice parent_obj; + + MemoryRegion cpu_container; + MemoryRegion dist_container; + MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS]; + MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS]; + uint32_t num_cpu; + DeviceState *gic; +}; + +#endif -- cgit v1.1 From 38c2b905d3beb27a056f7f53bcf7d9bce487e89d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:49 +0100 Subject: hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct The only time we use the ext_gic_irq[] array in the Exynos4210Irq struct is during realize of the SoC -- we initialize it with the input IRQs of the external GIC device, and then connect those to outputs of other devices further on in realize (including in the exynos4210_init_board_irqs() function). Now that the ext_gic object is easily accessible as s->ext_gic we can make the connections directly from one device to the other without going via this array. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-10-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index f35ae90..08f52c5 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -83,7 +83,6 @@ typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; - qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ]; } Exynos4210Irq; struct Exynos4210State { -- cgit v1.1 From 03a46e00813ae8bd0243457b12d48fd8d2d4d350 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:50 +0100 Subject: hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c The function exynos4210_combiner_get_gpioin() currently lives in exynos4210_combiner.c, but it isn't really part of the combiner device itself -- it is a function that implements the wiring up of some interrupt sources to multiple combiner inputs. Move it to live with the other SoC-level code in exynos4210.c, along with a few macros previously defined in exynos4210.h which are now used only in exynos4210.c. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-11-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 08f52c5..b564e35 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -67,11 +67,6 @@ #define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \ (EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8) -#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit)) -#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8) -#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \ - ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq)) - /* IRQs number for external and internal GIC */ #define EXYNOS4210_EXT_GIC_NIRQ (160-32) #define EXYNOS4210_INT_GIC_NIRQ 64 @@ -119,12 +114,6 @@ void exynos4210_write_secondary(ARMCPU *cpu, uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit); /* - * Get Combiner input GPIO into irqs structure - */ -void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev, - int ext); - -/* * exynos4210 UART */ DeviceState *exynos4210_uart_create(hwaddr addr, -- cgit v1.1 From b17b54a63d1071b862361d31c7d20ad7a620c182 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:51 +0100 Subject: hw/arm/exynos4210: Delete unused macro definitions Delete a couple of #defines which are never used. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-12-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index b564e35..f0769a4 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -67,10 +67,6 @@ #define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \ (EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8) -/* IRQs number for external and internal GIC */ -#define EXYNOS4210_EXT_GIC_NIRQ (160-32) -#define EXYNOS4210_INT_GIC_NIRQ 64 - #define EXYNOS4210_I2C_NUMBER 9 #define EXYNOS4210_NUM_DMA 3 -- cgit v1.1 From 7582d930dad3331bfdd7a4e1fe5d2080051d10d9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:52 +0100 Subject: hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs() In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device instead of qemu_irq_split(). Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-13-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index f0769a4..f58ee0f 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -28,6 +28,7 @@ #include "hw/sysbus.h" #include "hw/cpu/a9mpcore.h" #include "hw/intc/exynos4210_gic.h" +#include "hw/core/split-irq.h" #include "target/arm/cpu-qom.h" #include "qom/object.h" @@ -71,6 +72,13 @@ #define EXYNOS4210_NUM_DMA 3 +/* + * We need one splitter for every external combiner input, plus + * one for every non-zero entry in combiner_grp_to_gic_id[]. + * We'll assert in exynos4210_init_board_irqs() if this is wrong. + */ +#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60) + typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; @@ -95,6 +103,7 @@ struct Exynos4210State { qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; A9MPPrivState a9mpcore; Exynos4210GicState ext_gic; + SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS]; }; #define TYPE_EXYNOS4210_SOC "exynos4210" -- cgit v1.1 From 76124b4cb23f9efdd0746e057eeb64c9d48bbead Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:55 +0100 Subject: hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0 and EXT_GIC_ID_MCT_G1 multiple times. This means that we will connect multiple IRQs up to the same external GIC input, which is not permitted. We do the same thing in the code in exynos4210_init_board_irqs() because the conditionals selecting an irq_id in the first loop match multiple interrupt IDs. Overall we do this for interrupt IDs (1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0 and (1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1 These correspond to the cases for the multi-core timer that we are wiring up to multiple inputs on the combiner in exynos4210_combiner_get_gpioin(). That code already deals with all these interrupt IDs being the same input source, so we don't need to connect the external GIC interrupt for any of them except the first (1, 4) and (1, 5). Remove the array entries and conditionals which were incorrectly causing us to wire up extra lines. This bug didn't cause any visible effects, because we only connect up a device to the "primary" ID values (1, 4) and (1, 5), so the extra lines would never be set to a level. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-16-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index f58ee0f..7da3edd 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -77,7 +77,7 @@ * one for every non-zero entry in combiner_grp_to_gic_id[]. * We'll assert in exynos4210_init_board_irqs() if this is wrong. */ -#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60) +#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54) typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; -- cgit v1.1 From 76621953c9966bab33ea99a39e47130169bec389 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:56 +0100 Subject: hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs() At this point, the function exynos4210_init_board_irqs() splits input IRQ lines to connect them to the input combiner, output combiner and external GIC. The function exynos4210_combiner_get_gpioin() splits some of the combiner input lines further to connect them to multiple different inputs on the combiner. Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a configurable number of outputs, we can do all this in one place, by making exynos4210_init_board_irqs() add extra outputs to the splitter device when it must be connected to more than one input on each combiner. We do this with a new data structure, the combinermap, which is an array each of whose elements is a list of the interrupt IDs on the combiner which must be tied together. As we loop through each interrupt ID, if we find that it is the first one in one of these lists, we configure the splitter device with eonugh extra outputs and wire them up to the other interrupt IDs in the list. Conveniently, for all the cases where this is necessary, the lowest-numbered interrupt ID in each group is in the range of the external combiner, so we only need to code for this in the first of the two loops in exynos4210_init_board_irqs(). The old code in exynos4210_combiner_get_gpioin() which is being deleted here had several problems which don't exist in the new code in its handling of the multi-core timer interrupts: (1) the case labels specified bits 4 ... 8, but bit '8' doesn't exist; these should have been 4 ... 7 (2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)] multiple times as the input of several different splitters, which isn't allowed (3) in an apparent cut-and-paste error, the cases for all the multi-core timer inputs used "bit + 4" even though the bit range for the case was (intended to be) 4 ... 7, which meant it was looking at non-existent bits 8 ... 11. None of these exist in the new code. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-17-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 7da3edd..f24617f 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -74,10 +74,12 @@ /* * We need one splitter for every external combiner input, plus - * one for every non-zero entry in combiner_grp_to_gic_id[]. + * one for every non-zero entry in combiner_grp_to_gic_id[], + * minus one for every external combiner ID in second or later + * places in a combinermap[] line. * We'll assert in exynos4210_init_board_irqs() if this is wrong. */ -#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54) +#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38) typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; -- cgit v1.1 From cebef07df5c0cfb284f7e5e69cde1ae509fb6ada Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:57 +0100 Subject: hw/arm/exynos4210: Put combiners into state struct Switch the creation of the combiner devices to the new-style "embedded in state struct" approach, so we can easily refer to the object elsewhere during realize. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-18-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 3 ++ include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 include/hw/intc/exynos4210_combiner.h (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index f24617f..d38be87 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -28,6 +28,7 @@ #include "hw/sysbus.h" #include "hw/cpu/a9mpcore.h" #include "hw/intc/exynos4210_gic.h" +#include "hw/intc/exynos4210_combiner.h" #include "hw/core/split-irq.h" #include "target/arm/cpu-qom.h" #include "qom/object.h" @@ -105,6 +106,8 @@ struct Exynos4210State { qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; A9MPPrivState a9mpcore; Exynos4210GicState ext_gic; + Exynos4210CombinerState int_combiner; + Exynos4210CombinerState ext_combiner; SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS]; }; diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h new file mode 100644 index 0000000..429844f --- /dev/null +++ b/include/hw/intc/exynos4210_combiner.h @@ -0,0 +1,57 @@ +/* + * Samsung exynos4210 Interrupt Combiner + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * All rights reserved. + * + * Evgeny Voevodin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#ifndef HW_INTC_EXYNOS4210_COMBINER +#define HW_INTC_EXYNOS4210_COMBINER + +#include "hw/sysbus.h" + +/* + * State for each output signal of internal combiner + */ +typedef struct CombinerGroupState { + uint8_t src_mask; /* 1 - source enabled, 0 - disabled */ + uint8_t src_pending; /* Pending source interrupts before masking */ +} CombinerGroupState; + +#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner" +OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER) + +/* Number of groups and total number of interrupts for the internal combiner */ +#define IIC_NGRP 64 +#define IIC_NIRQ (IIC_NGRP * 8) +#define IIC_REGSET_SIZE 0x41 + +struct Exynos4210CombinerState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + + struct CombinerGroupState group[IIC_NGRP]; + uint32_t reg_set[IIC_REGSET_SIZE]; + uint32_t icipsr[2]; + uint32_t external; /* 1 means that this combiner is external */ + + qemu_irq output_irq[IIC_NGRP]; +}; + +#endif -- cgit v1.1 From f37fc537fc1f129ca94ec5e29f4c98f3724d7929 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:58 +0100 Subject: hw/arm/exynos4210: Drop Exynos4210Irq struct The only time we use the int_combiner_irq[] and ext_combiner_irq[] arrays in the Exynos4210Irq struct is during realize of the SoC -- we initialize them with the input IRQs of the combiner devices, and then connect those to outputs of other devices in exynos4210_init_board_irqs(). Now that the combiner objects are easily accessible as s->int_combiner and s->ext_combiner we can make the connections directly from one device to the other without going via these arrays. Since these are the only two remaining elements of Exynos4210Irq, we can remove that struct entirely. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-19-peter.maydell@linaro.org --- include/hw/arm/exynos4210.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include') diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index d38be87..97353f1 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -82,17 +82,11 @@ */ #define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38) -typedef struct Exynos4210Irq { - qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; - qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; -} Exynos4210Irq; - struct Exynos4210State { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ ARMCPU *cpu[EXYNOS4210_NCPUS]; - Exynos4210Irq irqs; qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; MemoryRegion chipid_mem; -- cgit v1.1 From 0ebfc997d29c3789b9bd41fe53fc198c2fd550da Mon Sep 17 00:00:00 2001 From: Zongyuan Li Date: Fri, 25 Mar 2022 02:15:57 +0800 Subject: hw/core/irq: remove unused 'qemu_irq_split' function Signed-off-by: Zongyuan Li Reviewed-by: Peter Maydell Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811 Signed-off-by: Peter Maydell --- include/hw/irq.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/hw/irq.h b/include/hw/irq.h index dc7abf1..645b73d 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -46,11 +46,6 @@ void qemu_free_irq(qemu_irq irq); /* Returns a new IRQ with opposite polarity. */ qemu_irq qemu_irq_invert(qemu_irq irq); -/* Returns a new IRQ which feeds into both the passed IRQs. - * It's probably better to use the TYPE_SPLIT_IRQ device instead. - */ -qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); - /* For internal use in qtest. Similar to qemu_irq_split, but operating on an existing vector of qemu_irq. */ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); -- cgit v1.1 From c3e9e73a8323cc61386c3067715ba4e44ea95a0f Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Mon, 11 Apr 2022 09:58:41 -0700 Subject: hw/misc: Add PWRON STRAP bit fields in GCR module Similar to the Aspeed code in include/misc/aspeed_scu.h, we define the PWRON STRAP fields in their corresponding module for NPCM7XX. Signed-off-by: Hao Wu Reviewed-by: Patrick Venture Message-id: 20220411165842.3912945-2-wuhaotsh@google.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'include') diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h index 13109d9..9419e0a 100644 --- a/include/hw/misc/npcm7xx_gcr.h +++ b/include/hw/misc/npcm7xx_gcr.h @@ -20,6 +20,36 @@ #include "hw/sysbus.h" /* + * NPCM7XX PWRON STRAP bit fields + * 12: SPI0 powered by VSBV3 at 1.8V + * 11: System flash attached to BMC + * 10: BSP alternative pins. + * 9:8: Flash UART command route enabled. + * 7: Security enabled. + * 6: HI-Z state control. + * 5: ECC disabled. + * 4: Reserved + * 3: JTAG2 enabled. + * 2:0: CPU and DRAM clock frequency. + */ +#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12) +#define NPCM7XX_PWRON_STRAP_SFAB BIT(11) +#define NPCM7XX_PWRON_STRAP_BSPA BIT(10) +#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8) +#define FUP_NORM_UART2 3 +#define FUP_PROG_UART3 2 +#define FUP_PROG_UART2 1 +#define FUP_NORM_UART3 0 +#define NPCM7XX_PWRON_STRAP_SECEN BIT(7) +#define NPCM7XX_PWRON_STRAP_HIZ BIT(6) +#define NPCM7XX_PWRON_STRAP_ECC BIT(5) +#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4) +#define NPCM7XX_PWRON_STRAP_J2EN BIT(3) +#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x) +#define CKFRQ_SKIPINIT 0x000 +#define CKFRQ_DEFAULT 0x111 + +/* * Number of registers in our device state structure. Don't change this without * incrementing the version_id in the vmstate. */ -- cgit v1.1