diff options
Diffstat (limited to 'include/hw/arm')
39 files changed, 2278 insertions, 547 deletions
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index 77c82a9982..67a9a17b86 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -1,19 +1,22 @@ #ifndef HW_ARM_ALLWINNER_A10_H #define HW_ARM_ALLWINNER_A10_H -#include "qemu/error-report.h" -#include "hw/char/serial.h" -#include "hw/arm/boot.h" #include "hw/timer/allwinner-a10-pit.h" #include "hw/intc/allwinner-a10-pic.h" #include "hw/net/allwinner_emac.h" #include "hw/sd/allwinner-sdhost.h" -#include "hw/ide/ahci.h" +#include "hw/ide/ahci-sysbus.h" #include "hw/usb/hcd-ohci.h" #include "hw/usb/hcd-ehci.h" #include "hw/rtc/allwinner-rtc.h" +#include "hw/misc/allwinner-a10-ccm.h" +#include "hw/misc/allwinner-a10-dramc.h" +#include "hw/i2c/allwinner-i2c.h" +#include "hw/watchdog/allwinner-wdt.h" +#include "sysemu/block-backend.h" #include "target/arm/cpu.h" +#include "qom/object.h" #define AW_A10_SDRAM_BASE 0x40000000 @@ -21,23 +24,47 @@ #define AW_A10_NUM_USB 2 #define TYPE_AW_A10 "allwinner-a10" -#define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10) +OBJECT_DECLARE_SIMPLE_TYPE(AwA10State, AW_A10) -typedef struct AwA10State { +struct AwA10State { /*< private >*/ DeviceState parent_obj; /*< public >*/ ARMCPU cpu; + AwA10ClockCtlState ccm; + AwA10DramControllerState dramc; AwA10PITState timer; AwA10PICState intc; AwEmacState emac; AllwinnerAHCIState sata; AwSdHostState mmc0; + AWI2CState i2c0; AwRtcState rtc; + AwWdtState wdt; MemoryRegion sram_a; EHCISysBusState ehci[AW_A10_NUM_USB]; OHCISysBusState ohci[AW_A10_NUM_USB]; -} AwA10State; +}; + +/** + * Emulate Boot ROM firmware setup functionality. + * + * A real Allwinner A10 SoC contains a Boot ROM + * which is the first code that runs right after + * the SoC is powered on. The Boot ROM is responsible + * for loading user code (e.g. a bootloader) from any + * of the supported external devices and writing the + * downloaded code to internal SRAM. After loading the SoC + * begins executing the code written to SRAM. + * + * This function emulates the Boot ROM by copying 32 KiB + * of data at offset 8 KiB from the given block device and writes it to + * the start of the first internal SRAM memory. + * + * @s: Allwinner A10 state object pointer + * @blk: Block backend device object pointer + */ +void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk); #endif diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h index 82e4e59216..24ba4e1bf4 100644 --- a/include/hw/arm/allwinner-h3.h +++ b/include/hw/arm/allwinner-h3.h @@ -18,7 +18,7 @@ */ /* - * The Allwinner H3 is a System on Chip containing four ARM Cortex A7 + * The Allwinner H3 is a System on Chip containing four ARM Cortex-A7 * processor cores. Features and specifications include DDR2/DDR3 memory, * SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and * various I/O modules. @@ -36,7 +36,6 @@ #define HW_ARM_ALLWINNER_H3_H #include "qom/object.h" -#include "hw/arm/boot.h" #include "hw/timer/allwinner-a10-pit.h" #include "hw/intc/arm_gic.h" #include "hw/misc/allwinner-h3-ccu.h" @@ -47,6 +46,8 @@ #include "hw/sd/allwinner-sdhost.h" #include "hw/net/allwinner-sun8i-emac.h" #include "hw/rtc/allwinner-rtc.h" +#include "hw/i2c/allwinner-i2c.h" +#include "hw/watchdog/allwinner-wdt.h" #include "target/arm/cpu.h" #include "sysemu/block-backend.h" @@ -61,37 +62,42 @@ * @see AwH3State */ enum { - AW_H3_SRAM_A1, - AW_H3_SRAM_A2, - AW_H3_SRAM_C, - AW_H3_SYSCTRL, - AW_H3_MMC0, - AW_H3_SID, - AW_H3_EHCI0, - AW_H3_OHCI0, - AW_H3_EHCI1, - AW_H3_OHCI1, - AW_H3_EHCI2, - AW_H3_OHCI2, - AW_H3_EHCI3, - AW_H3_OHCI3, - AW_H3_CCU, - AW_H3_PIT, - AW_H3_UART0, - AW_H3_UART1, - AW_H3_UART2, - AW_H3_UART3, - AW_H3_EMAC, - AW_H3_DRAMCOM, - AW_H3_DRAMCTL, - AW_H3_DRAMPHY, - AW_H3_GIC_DIST, - AW_H3_GIC_CPU, - AW_H3_GIC_HYP, - AW_H3_GIC_VCPU, - AW_H3_RTC, - AW_H3_CPUCFG, - AW_H3_SDRAM + AW_H3_DEV_SRAM_A1, + AW_H3_DEV_SRAM_A2, + AW_H3_DEV_SRAM_C, + AW_H3_DEV_SYSCTRL, + AW_H3_DEV_MMC0, + AW_H3_DEV_SID, + AW_H3_DEV_EHCI0, + AW_H3_DEV_OHCI0, + AW_H3_DEV_EHCI1, + AW_H3_DEV_OHCI1, + AW_H3_DEV_EHCI2, + AW_H3_DEV_OHCI2, + AW_H3_DEV_EHCI3, + AW_H3_DEV_OHCI3, + AW_H3_DEV_CCU, + AW_H3_DEV_PIT, + AW_H3_DEV_UART0, + AW_H3_DEV_UART1, + AW_H3_DEV_UART2, + AW_H3_DEV_UART3, + AW_H3_DEV_EMAC, + AW_H3_DEV_TWI0, + AW_H3_DEV_TWI1, + AW_H3_DEV_TWI2, + AW_H3_DEV_DRAMCOM, + AW_H3_DEV_DRAMCTL, + AW_H3_DEV_DRAMPHY, + AW_H3_DEV_GIC_DIST, + AW_H3_DEV_GIC_CPU, + AW_H3_DEV_GIC_HYP, + AW_H3_DEV_GIC_VCPU, + AW_H3_DEV_RTC, + AW_H3_DEV_CPUCFG, + AW_H3_DEV_R_TWI, + AW_H3_DEV_SDRAM, + AW_H3_DEV_WDT }; /** Total number of CPU cores in the H3 SoC */ @@ -106,7 +112,7 @@ enum { #define TYPE_AW_H3 "allwinner-h3" /** Convert input object to Allwinner H3 state object */ -#define AW_H3(obj) OBJECT_CHECK(AwH3State, (obj), TYPE_AW_H3) +OBJECT_DECLARE_SIMPLE_TYPE(AwH3State, AW_H3) /** @} */ @@ -116,7 +122,7 @@ enum { * This struct contains the state of all the devices * which are currently emulated by the H3 SoC code. */ -typedef struct AwH3State { +struct AwH3State { /*< private >*/ DeviceState parent_obj; /*< public >*/ @@ -130,13 +136,18 @@ typedef struct AwH3State { AwH3SysCtrlState sysctrl; AwSidState sid; AwSdHostState mmc0; + AWI2CState i2c0; + AWI2CState i2c1; + AWI2CState i2c2; + AWI2CState r_twi; AwSun8iEmacState emac; AwRtcState rtc; + AwWdtState wdt; GICState gic; MemoryRegion sram_a1; MemoryRegion sram_a2; MemoryRegion sram_c; -} AwH3State; +}; /** * Emulate Boot ROM firmware setup functionality. diff --git a/include/hw/arm/allwinner-r40.h b/include/hw/arm/allwinner-r40.h new file mode 100644 index 0000000000..614e74b7ed --- /dev/null +++ b/include/hw/arm/allwinner-r40.h @@ -0,0 +1,157 @@ +/* + * Allwinner R40/A40i/T3 System on Chip emulation + * + * Copyright (C) 2023 qianfan Zhao <qianfanguijin@163.com> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_ARM_ALLWINNER_R40_H +#define HW_ARM_ALLWINNER_R40_H + +#include "qom/object.h" +#include "hw/timer/allwinner-a10-pit.h" +#include "hw/ide/ahci-sysbus.h" +#include "hw/intc/arm_gic.h" +#include "hw/sd/allwinner-sdhost.h" +#include "hw/misc/allwinner-r40-ccu.h" +#include "hw/misc/allwinner-r40-dramc.h" +#include "hw/misc/allwinner-sramc.h" +#include "hw/i2c/allwinner-i2c.h" +#include "hw/net/allwinner_emac.h" +#include "hw/net/allwinner-sun8i-emac.h" +#include "hw/usb/hcd-ohci.h" +#include "hw/usb/hcd-ehci.h" +#include "hw/watchdog/allwinner-wdt.h" +#include "target/arm/cpu.h" +#include "sysemu/block-backend.h" + +enum { + AW_R40_DEV_SRAM_A1, + AW_R40_DEV_SRAM_A2, + AW_R40_DEV_SRAM_A3, + AW_R40_DEV_SRAM_A4, + AW_R40_DEV_SRAMC, + AW_R40_DEV_EMAC, + AW_R40_DEV_MMC0, + AW_R40_DEV_MMC1, + AW_R40_DEV_MMC2, + AW_R40_DEV_MMC3, + AW_R40_DEV_AHCI, + AW_R40_DEV_EHCI1, + AW_R40_DEV_OHCI1, + AW_R40_DEV_EHCI2, + AW_R40_DEV_OHCI2, + AW_R40_DEV_CCU, + AW_R40_DEV_PIT, + AW_R40_DEV_WDT, + AW_R40_DEV_UART0, + AW_R40_DEV_UART1, + AW_R40_DEV_UART2, + AW_R40_DEV_UART3, + AW_R40_DEV_UART4, + AW_R40_DEV_UART5, + AW_R40_DEV_UART6, + AW_R40_DEV_UART7, + AW_R40_DEV_TWI0, + AW_R40_DEV_GMAC, + AW_R40_DEV_GIC_DIST, + AW_R40_DEV_GIC_CPU, + AW_R40_DEV_GIC_HYP, + AW_R40_DEV_GIC_VCPU, + AW_R40_DEV_SDRAM, + AW_R40_DEV_DRAMCOM, + AW_R40_DEV_DRAMCTL, + AW_R40_DEV_DRAMPHY, +}; + +#define AW_R40_NUM_CPUS (4) + +/** + * Allwinner R40 object model + * @{ + */ + +/** Object type for the Allwinner R40 SoC */ +#define TYPE_AW_R40 "allwinner-r40" + +/** Convert input object to Allwinner R40 state object */ +OBJECT_DECLARE_SIMPLE_TYPE(AwR40State, AW_R40) + +/** @} */ + +/** + * Allwinner R40 object + * + * This struct contains the state of all the devices + * which are currently emulated by the R40 SoC code. + */ +#define AW_R40_NUM_MMCS 4 +#define AW_R40_NUM_USB 2 +#define AW_R40_NUM_UARTS 8 + +struct AwR40State { + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + + /** Physical base address for start of RAM */ + hwaddr ram_addr; + + /** Total RAM size in megabytes */ + uint32_t ram_size; + + ARMCPU cpus[AW_R40_NUM_CPUS]; + const hwaddr *memmap; + AwSRAMCState sramc; + AwA10PITState timer; + AwWdtState wdt; + AllwinnerAHCIState sata; + AwSdHostState mmc[AW_R40_NUM_MMCS]; + EHCISysBusState ehci[AW_R40_NUM_USB]; + OHCISysBusState ohci[AW_R40_NUM_USB]; + AwR40ClockCtlState ccu; + AwR40DramCtlState dramc; + AWI2CState i2c0; + AwEmacState emac; + AwSun8iEmacState gmac; + GICState gic; + MemoryRegion sram_a1; + MemoryRegion sram_a2; + MemoryRegion sram_a3; + MemoryRegion sram_a4; +}; + +/** + * Emulate Boot ROM firmware setup functionality. + * + * A real Allwinner R40 SoC contains a Boot ROM + * which is the first code that runs right after + * the SoC is powered on. The Boot ROM is responsible + * for loading user code (e.g. a bootloader) from any + * of the supported external devices and writing the + * downloaded code to internal SRAM. After loading the SoC + * begins executing the code written to SRAM. + * + * This function emulates the Boot ROM by copying 32 KiB + * of data from the given block device and writes it to + * the start of the first internal SRAM memory. + * + * @s: Allwinner R40 state object pointer + * @blk: Block backend device object pointer + * @unit: the mmc control's unit + */ +bool allwinner_r40_bootrom_setup(AwR40State *s, BlockBackend *blk, int unit); + +#endif /* HW_ARM_ALLWINNER_R40_H */ diff --git a/include/hw/arm/armsse-version.h b/include/hw/arm/armsse-version.h new file mode 100644 index 0000000000..60780fa984 --- /dev/null +++ b/include/hw/arm/armsse-version.h @@ -0,0 +1,42 @@ +/* + * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200 + * + * Copyright (c) 2020 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +#ifndef ARMSSE_VERSION_H +#define ARMSSE_VERSION_H + + +/* + * Define an enumeration of the possible values of the sse-version + * property implemented by various sub-devices of the SSE, and + * a validation function that checks that a valid value has been passed. + * These are arbitrary QEMU-internal values (nobody should be creating + * the sub-devices of the SSE except for the SSE object itself), but + * we pick obvious numbers for the benefit of people debugging with gdb. + */ +enum { + ARMSSE_IOTKIT = 0, + ARMSSE_SSE200 = 200, + ARMSSE_SSE300 = 300, +}; + +static inline bool armsse_version_valid(uint32_t sse_version) +{ + switch (sse_version) { + case ARMSSE_IOTKIT: + case ARMSSE_SSE200: + case ARMSSE_SSE300: + return true; + default: + return false; + } +} + +#endif diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 84080c2299..88b3b759c5 100644 --- a/include/hw/arm/armsse.h +++ b/include/hw/arm/armsse.h @@ -14,9 +14,9 @@ * hardware, which include the IoT Kit and the SSE-050, SSE-100 and * SSE-200. Currently we model: * - the Arm IoT Kit which is documented in - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html + * https://developer.arm.com/documentation/ecm0601256/latest * - the SSE-200 which is documented in - * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf + * https://developer.arm.com/documentation/101104/latest/ * * The IoTKit contains: * a Cortex-M33 @@ -37,9 +37,10 @@ * per-CPU identity and control register blocks * * QEMU interface: + * + Clock input "MAINCLK": clock for CPUs and most peripherals + * + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals * + QOM property "memory" is a MemoryRegion containing the devices provided * by the board model. - * + QOM property "MAINCLK" is the frequency of the main system clock * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts. * (In hardware, the SSE-200 permits the number of expansion interrupts * for the two CPUs to be configured separately, but we restrict it to @@ -55,6 +56,9 @@ * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an * SSE-200 both are present; CPU0 in an SSE-200 has neither. * Since the IoTKit has only one CPU, it does not have the CPU1_* properties. + * + QOM properties "CPU0_MPU_NS", "CPU0_MPU_S", "CPU1_MPU_NS" and "CPU1_MPU_S" + * which set the number of MPU regions on the CPUs. If there is only one + * CPU the CPU1 properties are not present. * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0, * which are wired to its NVIC lines 32 .. n+32 * + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for @@ -96,18 +100,24 @@ #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" +#include "hw/timer/sse-counter.h" +#include "hw/timer/sse-timer.h" #include "hw/watchdog/cmsdk-apb-watchdog.h" #include "hw/misc/iotkit-sysctl.h" #include "hw/misc/iotkit-sysinfo.h" #include "hw/misc/armsse-cpuid.h" #include "hw/misc/armsse-mhu.h" +#include "hw/misc/armsse-cpu-pwrctrl.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" +#include "hw/clock.h" #include "hw/core/split-irq.h" #include "hw/cpu/cluster.h" +#include "qom/object.h" -#define TYPE_ARMSSE "arm-sse" -#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE) +#define TYPE_ARM_SSE "arm-sse" +OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass, + ARM_SSE) /* * These type names are for specific IoTKit subsystems; other than @@ -116,12 +126,14 @@ */ #define TYPE_IOTKIT "iotkit" #define TYPE_SSE200 "sse-200" +#define TYPE_SSE300 "sse-300" /* We have an IRQ splitter and an OR gate input for each external PPC * and the 2 internal PPCs */ +#define NUM_INTERNAL_PPCS 2 #define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC) -#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2) +#define NUM_PPCS (NUM_EXTERNAL_PPCS + NUM_INTERNAL_PPCS) #define MAX_SRAM_BANKS 4 #if MAX_SRAM_BANKS > IOTS_NUM_MPC @@ -130,17 +142,12 @@ #define SSE_MAX_CPUS 2 -/* These define what each PPU in the ppu[] index is for */ -#define CPU0CORE_PPU 0 -#define CPU1CORE_PPU 1 -#define DBG_PPU 2 -#define RAM0_PPU 3 -#define RAM1_PPU 4 -#define RAM2_PPU 5 -#define RAM3_PPU 6 -#define NUM_PPUS 7 - -typedef struct ARMSSE { +#define NUM_PPUS 8 + +/* Number of CPU IRQs used by the SSE itself */ +#define NUM_SSE_IRQS 32 + +struct ARMSSE { /*< private >*/ SysBusDevice parent_obj; @@ -148,37 +155,37 @@ typedef struct ARMSSE { ARMv7MState armv7m[SSE_MAX_CPUS]; CPUClusterState cluster[SSE_MAX_CPUS]; IoTKitSecCtl secctl; - TZPPC apb_ppc0; - TZPPC apb_ppc1; + TZPPC apb_ppc[NUM_INTERNAL_PPCS]; TZMPC mpc[IOTS_NUM_MPC]; - CMSDKAPBTIMER timer0; - CMSDKAPBTIMER timer1; - CMSDKAPBTIMER s32ktimer; - qemu_or_irq ppc_irq_orgate; + CMSDKAPBTimer timer[3]; + OrIRQState ppc_irq_orgate; SplitIRQ sec_resp_splitter; SplitIRQ ppc_irq_splitter[NUM_PPCS]; SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; - qemu_or_irq mpc_irq_orgate; - qemu_or_irq nmi_orgate; + OrIRQState mpc_irq_orgate; + OrIRQState nmi_orgate; - SplitIRQ cpu_irq_splitter[32]; + SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS]; CMSDKAPBDualTimer dualtimer; - CMSDKAPBWatchdog s32kwatchdog; - CMSDKAPBWatchdog nswatchdog; - CMSDKAPBWatchdog swatchdog; + CMSDKAPBWatchdog cmsdk_watchdog[3]; + + SSECounter sse_counter; + SSETimer sse_timer[4]; IoTKitSysCtl sysctl; IoTKitSysCtl sysinfo; ARMSSEMHU mhu[2]; - UnimplementedDeviceState ppu[NUM_PPUS]; + UnimplementedDeviceState unimp[NUM_PPUS]; UnimplementedDeviceState cachectrl[SSE_MAX_CPUS]; UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS]; ARMSSECPUID cpuid[SSE_MAX_CPUS]; + ARMSSECPUPwrCtrl cpu_pwrctrl[SSE_MAX_CPUS]; + /* * 'container' holds all devices seen by all CPUs. * 'cpu_container[i]' is the view that CPU i has: this has the @@ -194,6 +201,8 @@ typedef struct ARMSSE { MemoryRegion alias2; MemoryRegion alias3[SSE_MAX_CPUS]; MemoryRegion sram[MAX_SRAM_BANKS]; + MemoryRegion itcm; + MemoryRegion dtcm; qemu_irq *exp_irqs[SSE_MAX_CPUS]; qemu_irq ppc0_irq; @@ -207,26 +216,26 @@ typedef struct ARMSSE { uint32_t nsccfg; + Clock *mainclk; + Clock *s32kclk; + /* Properties */ MemoryRegion *board_memory; uint32_t exp_numirq; - uint32_t mainclk_frq; uint32_t sram_addr_width; uint32_t init_svtor; + uint32_t cpu_mpu_ns[SSE_MAX_CPUS]; + uint32_t cpu_mpu_s[SSE_MAX_CPUS]; bool cpu_fpu[SSE_MAX_CPUS]; bool cpu_dsp[SSE_MAX_CPUS]; -} ARMSSE; +}; typedef struct ARMSSEInfo ARMSSEInfo; -typedef struct ARMSSEClass { - DeviceClass parent_class; +struct ARMSSEClass { + SysBusDeviceClass parent_class; const ARMSSEInfo *info; -} ARMSSEClass; +}; -#define ARMSSE_CLASS(klass) \ - OBJECT_CLASS_CHECK(ARMSSEClass, (klass), TYPE_ARMSSE) -#define ARMSSE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(ARMSSEClass, (obj), TYPE_ARMSSE) #endif diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index a30e3c6471..5c057ab2ec 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -12,12 +12,15 @@ #include "hw/sysbus.h" #include "hw/intc/armv7m_nvic.h" +#include "hw/misc/armv7m_ras.h" #include "target/arm/idau.h" +#include "qom/object.h" +#include "hw/clock.h" -#define TYPE_BITBAND "ARM,bitband-memory" -#define BITBAND(obj) OBJECT_CHECK(BitBandState, (obj), TYPE_BITBAND) +#define TYPE_BITBAND "ARM-bitband-memory" +OBJECT_DECLARE_SIMPLE_TYPE(BitBandState, BITBAND) -typedef struct { +struct BitBandState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ @@ -26,10 +29,10 @@ typedef struct { MemoryRegion iomem; uint32_t base; MemoryRegion *source_memory; -} BitBandState; +}; #define TYPE_ARMV7M "armv7m" -#define ARMV7M(obj) OBJECT_CHECK(ARMv7MState, (obj), TYPE_ARMV7M) +OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M) #define ARMV7M_NUM_BITBANDS 2 @@ -40,27 +43,57 @@ typedef struct { * a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET). * + Property "cpu-type": CPU type to instantiate * + Property "num-irq": number of external IRQ lines + * + Property "num-prio-bits": number of priority bits in the NVIC * + Property "memory": MemoryRegion defining the physical address space * that CPU accesses see. (The NVIC, bitbanding and other CPU-internal * devices will be automatically layered on top of this view.) * + Property "idau": IDAU interface (forwarded to CPU object) * + Property "init-svtor": secure VTOR reset value (forwarded to CPU object) + * + Property "init-nsvtor": non-secure VTOR reset value (forwarded to CPU object) * + Property "vfp": enable VFP (forwarded to CPU object) * + Property "dsp": enable DSP (forwarded to CPU object) * + Property "enable-bitband": expose bitbanded IO + * + Property "mpu-ns-regions": number of Non-Secure MPU regions (forwarded + * to CPU object pmsav7-dregion property; default is whatever the default + * for the CPU is) + * + Property "mpu-s-regions": number of Secure MPU regions (default is + * whatever the default for the CPU is; must currently be set to the same + * value as mpu-ns-regions if the CPU implements the Security Extension) + * + Clock input "refclk" is the external reference clock for the systick timers + * + Clock input "cpuclk" is the main CPU clock */ -typedef struct ARMv7MState { +struct ARMv7MState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ NVICState nvic; BitBandState bitband[ARMV7M_NUM_BITBANDS]; ARMCPU *cpu; + ARMv7MRAS ras; + SysTickState systick[M_REG_NUM_BANKS]; /* MemoryRegion we pass to the CPU, with our devices layered on * top of the ones the board provides in board_memory. */ MemoryRegion container; + /* + * MemoryRegion which passes the transaction to either the S or the + * NS systick device depending on the transaction attributes + */ + MemoryRegion systickmem; + /* + * MemoryRegion which enforces the S/NS handling of the systick + * device NS alias region and passes the transaction to the + * NS systick device if appropriate. + */ + MemoryRegion systick_ns_mem; + /* Ditto, for the sysregs region provided by the NVIC */ + MemoryRegion sysreg_ns_mem; + /* MR providing default PPB behaviour */ + MemoryRegion defaultmem; + + Clock *refclk; + Clock *cpuclk; /* Properties */ char *cpu_type; @@ -68,10 +101,13 @@ typedef struct ARMv7MState { MemoryRegion *board_memory; Object *idau; uint32_t init_svtor; + uint32_t init_nsvtor; + uint32_t mpu_ns_regions; + uint32_t mpu_s_regions; bool enable_bitband; bool start_powered_off; bool vfp; bool dsp; -} ARMv7MState; +}; #endif diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h index 09da9d9acc..cbeacb214c 100644 --- a/include/hw/arm/aspeed.h +++ b/include/hw/arm/aspeed.h @@ -10,24 +10,22 @@ #define ARM_ASPEED_H #include "hw/boards.h" +#include "qom/object.h" typedef struct AspeedMachineState AspeedMachineState; #define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed") -#define ASPEED_MACHINE(obj) \ - OBJECT_CHECK(AspeedMachineState, (obj), TYPE_ASPEED_MACHINE) +typedef struct AspeedMachineClass AspeedMachineClass; +DECLARE_OBJ_CHECKERS(AspeedMachineState, AspeedMachineClass, + ASPEED_MACHINE, TYPE_ASPEED_MACHINE) #define ASPEED_MAC0_ON (1 << 0) #define ASPEED_MAC1_ON (1 << 1) #define ASPEED_MAC2_ON (1 << 2) #define ASPEED_MAC3_ON (1 << 3) -#define ASPEED_MACHINE_CLASS(klass) \ - OBJECT_CLASS_CHECK(AspeedMachineClass, (klass), TYPE_ASPEED_MACHINE) -#define ASPEED_MACHINE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(AspeedMachineClass, (obj), TYPE_ASPEED_MACHINE) -typedef struct AspeedMachineClass { +struct AspeedMachineClass { MachineClass parent_obj; const char *name; @@ -40,7 +38,8 @@ typedef struct AspeedMachineClass { uint32_t num_cs; uint32_t macs_mask; void (*i2c_init)(AspeedMachineState *bmc); -} AspeedMachineClass; + uint32_t uart_default; +}; #endif diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 914115f3ef..c60fac900a 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -13,45 +13,63 @@ #define ASPEED_SOC_H #include "hw/cpu/a15mpcore.h" +#include "hw/arm/armv7m.h" #include "hw/intc/aspeed_vic.h" #include "hw/misc/aspeed_scu.h" +#include "hw/adc/aspeed_adc.h" #include "hw/misc/aspeed_sdmc.h" #include "hw/misc/aspeed_xdma.h" #include "hw/timer/aspeed_timer.h" #include "hw/rtc/aspeed_rtc.h" #include "hw/i2c/aspeed_i2c.h" +#include "hw/misc/aspeed_i3c.h" #include "hw/ssi/aspeed_smc.h" +#include "hw/misc/aspeed_hace.h" +#include "hw/misc/aspeed_sbc.h" #include "hw/watchdog/wdt_aspeed.h" #include "hw/net/ftgmac100.h" #include "target/arm/cpu.h" #include "hw/gpio/aspeed_gpio.h" #include "hw/sd/aspeed_sdhci.h" #include "hw/usb/hcd-ehci.h" +#include "qom/object.h" +#include "hw/misc/aspeed_lpc.h" +#include "hw/misc/unimp.h" +#include "hw/misc/aspeed_peci.h" +#include "hw/fsi/aspeed_apb2opb.h" +#include "hw/char/serial.h" #define ASPEED_SPIS_NUM 2 #define ASPEED_EHCIS_NUM 2 #define ASPEED_WDTS_NUM 4 #define ASPEED_CPUS_NUM 2 #define ASPEED_MACS_NUM 4 +#define ASPEED_UARTS_NUM 13 +#define ASPEED_JTAG_NUM 2 -typedef struct AspeedSoCState { - /*< private >*/ +struct AspeedSoCState { DeviceState parent; - /*< public >*/ - ARMCPU cpu[ASPEED_CPUS_NUM]; - A15MPPrivState a7mpcore; + MemoryRegion *memory; MemoryRegion *dram_mr; + MemoryRegion dram_container; MemoryRegion sram; - AspeedVICState vic; + MemoryRegion spi_boot_container; + MemoryRegion spi_boot; AspeedRtcState rtc; AspeedTimerCtrlState timerctrl; AspeedI2CState i2c; + AspeedI3CState i3c; AspeedSCUState scu; + AspeedHACEState hace; AspeedXDMAState xdma; + AspeedADCState adc; AspeedSMCState fmc; AspeedSMCState spi[ASPEED_SPIS_NUM]; EHCISysBusState ehci[ASPEED_EHCIS_NUM]; + AspeedSBCState sbc; + MemoryRegion secsram; + UnimplementedDeviceState sbc_unimplemented; AspeedSDMCState sdmc; AspeedWDTState wdt[ASPEED_WDTS_NUM]; FTGMAC100State ftgmac100[ASPEED_MACS_NUM]; @@ -60,79 +78,176 @@ typedef struct AspeedSoCState { AspeedGPIOState gpio_1_8v; AspeedSDHCIState sdhci; AspeedSDHCIState emmc; -} AspeedSoCState; + AspeedLPCState lpc; + AspeedPECIState peci; + SerialMM uart[ASPEED_UARTS_NUM]; + Clock *sysclk; + UnimplementedDeviceState iomem; + UnimplementedDeviceState video; + UnimplementedDeviceState emmc_boot_controller; + UnimplementedDeviceState dpmcu; + UnimplementedDeviceState pwm; + UnimplementedDeviceState espi; + UnimplementedDeviceState udc; + UnimplementedDeviceState sgpiom; + UnimplementedDeviceState jtag[ASPEED_JTAG_NUM]; + AspeedAPB2OPBState fsi[2]; +}; #define TYPE_ASPEED_SOC "aspeed-soc" -#define ASPEED_SOC(obj) OBJECT_CHECK(AspeedSoCState, (obj), TYPE_ASPEED_SOC) +OBJECT_DECLARE_TYPE(AspeedSoCState, AspeedSoCClass, ASPEED_SOC) + +struct Aspeed2400SoCState { + AspeedSoCState parent; + + ARMCPU cpu[ASPEED_CPUS_NUM]; + AspeedVICState vic; +}; + +#define TYPE_ASPEED2400_SOC "aspeed2400-soc" +OBJECT_DECLARE_SIMPLE_TYPE(Aspeed2400SoCState, ASPEED2400_SOC) + +struct Aspeed2600SoCState { + AspeedSoCState parent; + + A15MPPrivState a7mpcore; + ARMCPU cpu[ASPEED_CPUS_NUM]; /* XXX belong to a7mpcore */ +}; + +#define TYPE_ASPEED2600_SOC "aspeed2600-soc" +OBJECT_DECLARE_SIMPLE_TYPE(Aspeed2600SoCState, ASPEED2600_SOC) + +struct Aspeed10x0SoCState { + AspeedSoCState parent; + + ARMv7MState armv7m; +}; + +#define TYPE_ASPEED10X0_SOC "aspeed10x0-soc" +OBJECT_DECLARE_SIMPLE_TYPE(Aspeed10x0SoCState, ASPEED10X0_SOC) -typedef struct AspeedSoCClass { +struct AspeedSoCClass { DeviceClass parent_class; const char *name; - const char *cpu_type; + /** valid_cpu_types: NULL terminated array of a single CPU type. */ + const char * const *valid_cpu_types; uint32_t silicon_rev; uint64_t sram_size; + uint64_t secsram_size; int spis_num; int ehcis_num; int wdts_num; int macs_num; + int uarts_num; + int uarts_base; const int *irqmap; const hwaddr *memmap; uint32_t num_cpus; -} AspeedSoCClass; + qemu_irq (*get_irq)(AspeedSoCState *s, int dev); +}; -#define ASPEED_SOC_CLASS(klass) \ - OBJECT_CLASS_CHECK(AspeedSoCClass, (klass), TYPE_ASPEED_SOC) -#define ASPEED_SOC_GET_CLASS(obj) \ - OBJECT_GET_CLASS(AspeedSoCClass, (obj), TYPE_ASPEED_SOC) +const char *aspeed_soc_cpu_type(AspeedSoCClass *sc); enum { - ASPEED_IOMEM, - ASPEED_UART1, - ASPEED_UART2, - ASPEED_UART3, - ASPEED_UART4, - ASPEED_UART5, - ASPEED_VUART, - ASPEED_FMC, - ASPEED_SPI1, - ASPEED_SPI2, - ASPEED_EHCI1, - ASPEED_EHCI2, - ASPEED_VIC, - ASPEED_SDMC, - ASPEED_SCU, - ASPEED_ADC, - ASPEED_VIDEO, - ASPEED_SRAM, - ASPEED_SDHCI, - ASPEED_GPIO, - ASPEED_GPIO_1_8V, - ASPEED_RTC, - ASPEED_TIMER1, - ASPEED_TIMER2, - ASPEED_TIMER3, - ASPEED_TIMER4, - ASPEED_TIMER5, - ASPEED_TIMER6, - ASPEED_TIMER7, - ASPEED_TIMER8, - ASPEED_WDT, - ASPEED_PWM, - ASPEED_LPC, - ASPEED_IBT, - ASPEED_I2C, - ASPEED_ETH1, - ASPEED_ETH2, - ASPEED_ETH3, - ASPEED_ETH4, - ASPEED_MII1, - ASPEED_MII2, - ASPEED_MII3, - ASPEED_MII4, - ASPEED_SDRAM, - ASPEED_XDMA, - ASPEED_EMMC, + ASPEED_DEV_SPI_BOOT, + ASPEED_DEV_IOMEM, + ASPEED_DEV_UART0, + ASPEED_DEV_UART1, + ASPEED_DEV_UART2, + ASPEED_DEV_UART3, + ASPEED_DEV_UART4, + ASPEED_DEV_UART5, + ASPEED_DEV_UART6, + ASPEED_DEV_UART7, + ASPEED_DEV_UART8, + ASPEED_DEV_UART9, + ASPEED_DEV_UART10, + ASPEED_DEV_UART11, + ASPEED_DEV_UART12, + ASPEED_DEV_UART13, + ASPEED_DEV_VUART, + ASPEED_DEV_FMC, + ASPEED_DEV_SPI1, + ASPEED_DEV_SPI2, + ASPEED_DEV_EHCI1, + ASPEED_DEV_EHCI2, + ASPEED_DEV_VIC, + ASPEED_DEV_SDMC, + ASPEED_DEV_SCU, + ASPEED_DEV_ADC, + ASPEED_DEV_SBC, + ASPEED_DEV_SECSRAM, + ASPEED_DEV_EMMC_BC, + ASPEED_DEV_VIDEO, + ASPEED_DEV_SRAM, + ASPEED_DEV_SDHCI, + ASPEED_DEV_GPIO, + ASPEED_DEV_GPIO_1_8V, + ASPEED_DEV_RTC, + ASPEED_DEV_TIMER1, + ASPEED_DEV_TIMER2, + ASPEED_DEV_TIMER3, + ASPEED_DEV_TIMER4, + ASPEED_DEV_TIMER5, + ASPEED_DEV_TIMER6, + ASPEED_DEV_TIMER7, + ASPEED_DEV_TIMER8, + ASPEED_DEV_WDT, + ASPEED_DEV_PWM, + ASPEED_DEV_LPC, + ASPEED_DEV_IBT, + ASPEED_DEV_I2C, + ASPEED_DEV_PECI, + ASPEED_DEV_ETH1, + ASPEED_DEV_ETH2, + ASPEED_DEV_ETH3, + ASPEED_DEV_ETH4, + ASPEED_DEV_MII1, + ASPEED_DEV_MII2, + ASPEED_DEV_MII3, + ASPEED_DEV_MII4, + ASPEED_DEV_SDRAM, + ASPEED_DEV_XDMA, + ASPEED_DEV_EMMC, + ASPEED_DEV_KCS, + ASPEED_DEV_HACE, + ASPEED_DEV_DPMCU, + ASPEED_DEV_DP, + ASPEED_DEV_I3C, + ASPEED_DEV_ESPI, + ASPEED_DEV_UDC, + ASPEED_DEV_SGPIOM, + ASPEED_DEV_JTAG0, + ASPEED_DEV_JTAG1, + ASPEED_DEV_FSI1, + ASPEED_DEV_FSI2, }; +qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev); +bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp); +void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr); +bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp); +void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr); +void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev, + const char *name, hwaddr addr, + uint64_t size); +void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, + unsigned int count, int unit0); + +static inline int aspeed_uart_index(int uart_dev) +{ + return uart_dev - ASPEED_DEV_UART0; +} + +static inline int aspeed_uart_first(AspeedSoCClass *sc) +{ + return aspeed_uart_index(sc->uarts_base); +} + +static inline int aspeed_uart_last(AspeedSoCClass *sc) +{ + return aspeed_uart_first(sc) + sc->uarts_num - 1; +} + #endif /* ASPEED_SOC_H */ diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h index 48a0ad1633..636203baa5 100644 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -17,24 +17,32 @@ #include "hw/char/bcm2835_aux.h" #include "hw/display/bcm2835_fb.h" #include "hw/dma/bcm2835_dma.h" +#include "hw/or-irq.h" #include "hw/intc/bcm2835_ic.h" #include "hw/misc/bcm2835_property.h" #include "hw/misc/bcm2835_rng.h" #include "hw/misc/bcm2835_mbox.h" #include "hw/misc/bcm2835_mphi.h" #include "hw/misc/bcm2835_thermal.h" +#include "hw/misc/bcm2835_cprman.h" +#include "hw/misc/bcm2835_powermgt.h" #include "hw/sd/sdhci.h" #include "hw/sd/bcm2835_sdhost.h" #include "hw/gpio/bcm2835_gpio.h" #include "hw/timer/bcm2835_systmr.h" #include "hw/usb/hcd-dwc2.h" +#include "hw/ssi/bcm2835_spi.h" +#include "hw/i2c/bcm2835_i2c.h" #include "hw/misc/unimp.h" +#include "qom/object.h" +#define TYPE_BCM_SOC_PERIPHERALS_BASE "bcm-soc-peripherals-base" +OBJECT_DECLARE_TYPE(BCMSocPeripheralBaseState, BCMSocPeripheralBaseClass, + BCM_SOC_PERIPHERALS_BASE) #define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals" -#define BCM2835_PERIPHERALS(obj) \ - OBJECT_CHECK(BCM2835PeripheralState, (obj), TYPE_BCM2835_PERIPHERALS) +OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PeripheralState, BCM2835_PERIPHERALS) -typedef struct BCM2835PeripheralState { +struct BCMSocPeripheralBaseState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ @@ -45,31 +53,53 @@ typedef struct BCM2835PeripheralState { BCM2835SystemTimerState systmr; BCM2835MphiState mphi; + UnimplementedDeviceState txp; UnimplementedDeviceState armtmr; - UnimplementedDeviceState cprman; - UnimplementedDeviceState a2w; + BCM2835PowerMgtState powermgt; + BCM2835CprmanState cprman; PL011State uart0; BCM2835AuxState aux; BCM2835FBState fb; BCM2835DMAState dma; + OrIRQState orgated_dma_irq; BCM2835ICState ic; BCM2835PropertyState property; - BCM2835RngState rng; BCM2835MboxState mboxes; SDHCIState sdhci; BCM2835SDHostState sdhost; - BCM2835GpioState gpio; - Bcm2835ThermalState thermal; UnimplementedDeviceState i2s; - UnimplementedDeviceState spi[1]; - UnimplementedDeviceState i2c[3]; + BCM2835SPIState spi[1]; + BCM2835I2CState i2c[3]; + OrIRQState orgated_i2c_irq; UnimplementedDeviceState otp; UnimplementedDeviceState dbus; UnimplementedDeviceState ave0; + UnimplementedDeviceState v3d; UnimplementedDeviceState bscsl; UnimplementedDeviceState smi; DWC2State dwc2; UnimplementedDeviceState sdramc; -} BCM2835PeripheralState; +}; + +struct BCMSocPeripheralBaseClass { + /*< private >*/ + SysBusDeviceClass parent_class; + /*< public >*/ + uint64_t peri_size; /* Peripheral range size */ +}; + +struct BCM2835PeripheralState { + /*< private >*/ + BCMSocPeripheralBaseState parent_obj; + /*< public >*/ + BCM2835RngState rng; + Bcm2835ThermalState thermal; + BCM2835GpioState gpio; +}; + +void create_unimp(BCMSocPeripheralBaseState *ps, + UnimplementedDeviceState *uds, + const char *name, hwaddr ofs, hwaddr size); +void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp); #endif /* BCM2835_PERIPHERALS_H */ diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h index 79dfff9d73..918fb3bf14 100644 --- a/include/hw/arm/bcm2836.h +++ b/include/hw/arm/bcm2836.h @@ -15,9 +15,12 @@ #include "hw/arm/bcm2835_peripherals.h" #include "hw/intc/bcm2836_control.h" #include "target/arm/cpu.h" +#include "qom/object.h" +#define TYPE_BCM283X_BASE "bcm283x-base" +OBJECT_DECLARE_TYPE(BCM283XBaseState, BCM283XBaseClass, BCM283X_BASE) #define TYPE_BCM283X "bcm283x" -#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X) +OBJECT_DECLARE_SIMPLE_TYPE(BCM283XState, BCM283X) #define BCM283X_NCPUS 4 @@ -25,10 +28,11 @@ * them, code using these devices should always handle them via the * BCM283x base class, so they have no BCM2836(obj) etc macros. */ +#define TYPE_BCM2835 "bcm2835" #define TYPE_BCM2836 "bcm2836" #define TYPE_BCM2837 "bcm2837" -typedef struct BCM283XState { +struct BCM283XBaseState { /*< private >*/ DeviceState parent_obj; /*< public >*/ @@ -39,19 +43,28 @@ typedef struct BCM283XState { ARMCPU core; } cpu[BCM283X_NCPUS]; BCM2836ControlState control; - BCM2835PeripheralState peripherals; -} BCM283XState; - -typedef struct BCM283XInfo BCM283XInfo; +}; -typedef struct BCM283XClass { +struct BCM283XBaseClass { + /*< private >*/ DeviceClass parent_class; - const BCM283XInfo *info; -} BCM283XClass; + /*< public >*/ + const char *name; + const char *cpu_type; + unsigned core_count; + hwaddr peri_base; /* Peripheral base address seen by the CPU */ + hwaddr ctrl_base; /* Interrupt controller and mailboxes etc. */ + int clusterid; +}; + +struct BCM283XState { + /*< private >*/ + BCM283XBaseState parent_obj; + /*< public >*/ + BCM2835PeripheralState peripherals; +}; -#define BCM283X_CLASS(klass) \ - OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X) -#define BCM283X_GET_CLASS(obj) \ - OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X) +bool bcm283x_common_realize(DeviceState *dev, BCMSocPeripheralBaseState *ps, + Error **errp); #endif /* BCM2836_H */ diff --git a/include/hw/arm/bcm2838.h b/include/hw/arm/bcm2838.h new file mode 100644 index 0000000000..e53c7bedf9 --- /dev/null +++ b/include/hw/arm/bcm2838.h @@ -0,0 +1,31 @@ +/* + * BCM2838 SoC emulation + * + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef BCM2838_H +#define BCM2838_H + +#include "hw/arm/bcm2836.h" +#include "hw/intc/arm_gic.h" +#include "hw/arm/bcm2838_peripherals.h" + +#define BCM2838_PERI_LOW_BASE 0xfc000000 +#define BCM2838_GIC_BASE 0x40000 + +#define TYPE_BCM2838 "bcm2838" + +OBJECT_DECLARE_TYPE(BCM2838State, BCM2838Class, BCM2838) + +struct BCM2838State { + /*< private >*/ + BCM283XBaseState parent_obj; + /*< public >*/ + BCM2838PeripheralState peripherals; + GICState gic; +}; + +#endif /* BCM2838_H */ diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h new file mode 100644 index 0000000000..7ee1bd066f --- /dev/null +++ b/include/hw/arm/bcm2838_peripherals.h @@ -0,0 +1,84 @@ +/* + * BCM2838 peripherals emulation + * + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef BCM2838_PERIPHERALS_H +#define BCM2838_PERIPHERALS_H + +#include "hw/arm/bcm2835_peripherals.h" +#include "hw/sd/sdhci.h" +#include "hw/gpio/bcm2838_gpio.h" + +/* SPI */ +#define GIC_SPI_INTERRUPT_MBOX 33 +#define GIC_SPI_INTERRUPT_MPHI 40 +#define GIC_SPI_INTERRUPT_DWC2 73 +#define GIC_SPI_INTERRUPT_DMA_0 80 +#define GIC_SPI_INTERRUPT_DMA_6 86 +#define GIC_SPI_INTERRUPT_DMA_7_8 87 +#define GIC_SPI_INTERRUPT_DMA_9_10 88 +#define GIC_SPI_INTERRUPT_AUX_UART1 93 +#define GIC_SPI_INTERRUPT_SDHOST 120 +#define GIC_SPI_INTERRUPT_UART0 121 +#define GIC_SPI_INTERRUPT_RNG200 125 +#define GIC_SPI_INTERRUPT_EMMC_EMMC2 126 +#define GIC_SPI_INTERRUPT_PCI_INT_A 143 +#define GIC_SPI_INTERRUPT_GENET_A 157 +#define GIC_SPI_INTERRUPT_GENET_B 158 + + +/* GPU (legacy) DMA interrupts */ +#define GPU_INTERRUPT_DMA0 16 +#define GPU_INTERRUPT_DMA1 17 +#define GPU_INTERRUPT_DMA2 18 +#define GPU_INTERRUPT_DMA3 19 +#define GPU_INTERRUPT_DMA4 20 +#define GPU_INTERRUPT_DMA5 21 +#define GPU_INTERRUPT_DMA6 22 +#define GPU_INTERRUPT_DMA7_8 23 +#define GPU_INTERRUPT_DMA9_10 24 +#define GPU_INTERRUPT_DMA11 25 +#define GPU_INTERRUPT_DMA12 26 +#define GPU_INTERRUPT_DMA13 27 +#define GPU_INTERRUPT_DMA14 28 +#define GPU_INTERRUPT_DMA15 31 + +#define BCM2838_MPHI_OFFSET 0xb200 +#define BCM2838_MPHI_SIZE 0x200 + +#define TYPE_BCM2838_PERIPHERALS "bcm2838-peripherals" +OBJECT_DECLARE_TYPE(BCM2838PeripheralState, BCM2838PeripheralClass, + BCM2838_PERIPHERALS) + +struct BCM2838PeripheralState { + /*< private >*/ + BCMSocPeripheralBaseState parent_obj; + + /*< public >*/ + MemoryRegion peri_low_mr; + MemoryRegion peri_low_mr_alias; + MemoryRegion mphi_mr_alias; + + SDHCIState emmc2; + BCM2838GpioState gpio; + + OrIRQState mmc_irq_orgate; + OrIRQState dma_7_8_irq_orgate; + OrIRQState dma_9_10_irq_orgate; + + UnimplementedDeviceState asb; + UnimplementedDeviceState clkisp; +}; + +struct BCM2838PeripheralClass { + /*< private >*/ + BCMSocPeripheralBaseClass parent_class; + /*< public >*/ + uint64_t peri_low_size; /* Peripheral lower range size */ +}; + +#endif /* BCM2838_PERIPHERALS_H */ diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index ce2b48b88b..80c492d742 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -25,13 +25,16 @@ typedef enum { * armv7m_load_kernel: * @cpu: CPU * @kernel_filename: file to load + * @mem_base: base address to load image at (should be where the + * CPU expects to find its vector table on reset) * @mem_size: mem_size: maximum image size to load * * Load the guest image for an ARMv7M system. This must be called by * any ARMv7M board. (This is necessary to ensure that the CPU resets * correctly on system reset, as well as for kernel loading.) */ -void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size); +void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, + hwaddr mem_base, int mem_size); /* arm_boot.c */ struct arm_boot_info { @@ -56,7 +59,6 @@ struct arm_boot_info { hwaddr smp_loader_start; hwaddr smp_bootreg_addr; hwaddr gic_cpu_if_addr; - int nb_cpus; int board_id; /* ARM machines that support the ARM Security Extensions use this field to * control whether Linux is booted as secure(true) or non-secure(false). @@ -70,6 +72,9 @@ struct arm_boot_info { * boot loader/boot ROM code, and secondary_cpu_reset_hook() should * perform any necessary CPU reset handling and set the PC for the * secondary CPUs to point at this boot blob. + * + * These hooks won't be called if secondary CPUs are booting via + * emulated PSCI (see psci_conduit below). */ void (*write_secondary_boot)(ARMCPU *cpu, const struct arm_boot_info *info); @@ -86,6 +91,16 @@ struct arm_boot_info { * the user it should implement this hook. */ void (*modify_dtb)(const struct arm_boot_info *info, void *fdt); + /* + * If a board wants to use the QEMU emulated-firmware PSCI support, + * it should set this to QEMU_PSCI_CONDUIT_HVC or QEMU_PSCI_CONDUIT_SMC + * as appropriate. arm_load_kernel() will set the psci-conduit and + * start-powered-off properties on the CPUs accordingly. + * Note that if the guest image is started at the same exception level + * as the conduit specifies calls should go to (eg guest firmware booted + * to EL3) then PSCI will not be enabled. + */ + int psci_conduit; /* Used internally by arm_boot.c */ int is_linux; hwaddr initrd_start; @@ -168,4 +183,53 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, const struct arm_boot_info *info, hwaddr mvbar_addr); +typedef enum { + FIXUP_NONE = 0, /* do nothing */ + FIXUP_TERMINATOR, /* end of insns */ + FIXUP_BOARDID, /* overwrite with board ID number */ + FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */ + FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */ + FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */ + FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */ + FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */ + FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */ + FIXUP_BOOTREG, /* overwrite with boot register address */ + FIXUP_DSB, /* overwrite with correct DSB insn for cpu */ + FIXUP_MAX, +} FixupType; + +typedef struct ARMInsnFixup { + uint32_t insn; + FixupType fixup; +} ARMInsnFixup; + +/** + * arm_write_bootloader - write a bootloader to guest memory + * @name: name of the bootloader blob + * @as: AddressSpace to write the bootloader + * @addr: guest address to write it + * @insns: the blob to be loaded + * @fixupcontext: context to be used for any fixups in @insns + * + * Write a bootloader to guest memory at address @addr in the address + * space @as. @name is the name to use for the resulting ROM blob, so + * it should be unique in the system and reasonably identifiable for debugging. + * + * @insns must be an array of ARMInsnFixup structs, each of which has + * one 32-bit value to be written to the guest memory, and a fixup to be + * applied to the value. FIXUP_NONE (do nothing) is value 0, so effectively + * the fixup is optional when writing a struct initializer. + * The final entry in the array must be { 0, FIXUP_TERMINATOR }. + * + * All other supported fixup types have the semantics "ignore insn + * and instead use the value from the array element @fixupcontext[fixup]". + * The caller should therefore provide @fixupcontext as an array of + * size FIXUP_MAX whose elements have been initialized for at least + * the entries that @insns refers to. + */ +void arm_write_bootloader(const char *name, + AddressSpace *as, hwaddr addr, + const ARMInsnFixup *insns, + const uint32_t *fixupcontext); + #endif /* HW_ARM_BOOT_H */ diff --git a/include/hw/arm/sysbus-fdt.h b/include/hw/arm/bsa.h index 340c382cdd..8eaab603c0 100644 --- a/include/hw/arm/sysbus-fdt.h +++ b/include/hw/arm/bsa.h @@ -1,11 +1,8 @@ /* - * Dynamic sysbus device tree node generation API + * Common definitions for Arm Base System Architecture (BSA) platforms. * - * Copyright Linaro Limited, 2014 - * - * Authors: - * Alex Graf <agraf@suse.de> - * Eric Auger <eric.auger@linaro.org> + * Copyright (c) 2015 Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -21,17 +18,18 @@ * */ -#ifndef HW_ARM_SYSBUS_FDT_H -#define HW_ARM_SYSBUS_FDT_H +#ifndef QEMU_ARM_BSA_H +#define QEMU_ARM_BSA_H -#include "exec/hwaddr.h" +/* These are architectural INTID values */ +#define VIRTUAL_PMU_IRQ 23 +#define ARCH_GIC_MAINT_IRQ 25 +#define ARCH_TIMER_NS_EL2_IRQ 26 +#define ARCH_TIMER_VIRT_IRQ 27 +#define ARCH_TIMER_NS_EL2_VIRT_IRQ 28 +#define ARCH_TIMER_S_EL1_IRQ 29 +#define ARCH_TIMER_NS_EL1_IRQ 30 -/** - * platform_bus_add_all_fdt_nodes - create all the platform bus nodes - * - * builds the parent platform bus node and all the nodes of dynamic - * sysbus devices attached to it. - */ -void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, - hwaddr bus_size, int irq_start); -#endif +#define INTID_TO_PPI(irq) ((irq) - 16) + +#endif /* QEMU_ARM_BSA_H */ diff --git a/include/hw/arm/digic.h b/include/hw/arm/digic.h index 63785baaa8..8f2735c284 100644 --- a/include/hw/arm/digic.h +++ b/include/hw/arm/digic.h @@ -21,14 +21,15 @@ #include "cpu.h" #include "hw/timer/digic-timer.h" #include "hw/char/digic-uart.h" +#include "qom/object.h" #define TYPE_DIGIC "digic" -#define DIGIC(obj) OBJECT_CHECK(DigicState, (obj), TYPE_DIGIC) +OBJECT_DECLARE_SIMPLE_TYPE(DigicState, DIGIC) #define DIGIC4_NB_TIMERS 3 -typedef struct DigicState { +struct DigicState { /*< private >*/ DeviceState parent_obj; /*< public >*/ @@ -37,6 +38,6 @@ typedef struct DigicState { DigicTimerState timer[DIGIC4_NB_TIMERS]; DigicUartState uart; -} DigicState; +}; #endif /* HW_ARM_DIGIC_H */ diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 55260394af..d33fe38586 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -26,7 +26,12 @@ #include "hw/or-irq.h" #include "hw/sysbus.h" -#include "target/arm/cpu-qom.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 "hw/arm/boot.h" +#include "qom/object.h" #define EXYNOS4210_NCPUS 2 @@ -64,34 +69,25 @@ #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 - #define EXYNOS4210_I2C_NUMBER 9 #define EXYNOS4210_NUM_DMA 3 -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; +/* + * We need one splitter for every external combiner input, plus + * 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 + 38) -typedef struct Exynos4210State { +struct Exynos4210State { /*< private >*/ SysBusDevice parent_obj; /*< 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; @@ -100,23 +96,21 @@ typedef struct Exynos4210State { MemoryRegion boot_secondary; MemoryRegion bootreg_mem; I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER]; - qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA]; -} Exynos4210State; + OrIRQState pl330_irq_orgate[EXYNOS4210_NUM_DMA]; + OrIRQState cpu_irq_orgate[EXYNOS4210_NCPUS]; + A9MPPrivState a9mpcore; + Exynos4210GicState ext_gic; + Exynos4210CombinerState int_combiner; + Exynos4210CombinerState ext_combiner; + SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS]; +}; #define TYPE_EXYNOS4210_SOC "exynos4210" -#define EXYNOS4210_SOC(obj) \ - OBJECT_CHECK(Exynos4210State, obj, TYPE_EXYNOS4210_SOC) +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); - /* Get IRQ number from exynos4210 IRQ subsystem stub. * To identify IRQ source use internal combiner group and bit number * grp - group number @@ -124,12 +118,6 @@ void exynos4210_init_board_irqs(Exynos4210Irq *s); 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, diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h index 54ee1bfd78..df2f83980f 100644 --- a/include/hw/arm/fsl-imx25.h +++ b/include/hw/arm/fsl-imx25.h @@ -17,7 +17,6 @@ #ifndef FSL_IMX25_H #define FSL_IMX25_H -#include "hw/arm/boot.h" #include "hw/intc/imx_avic.h" #include "hw/misc/imx25_ccm.h" #include "hw/char/imx_serial.h" @@ -32,9 +31,10 @@ #include "hw/watchdog/wdt_imx2.h" #include "exec/memory.h" #include "target/arm/cpu.h" +#include "qom/object.h" -#define TYPE_FSL_IMX25 "fsl,imx25" -#define FSL_IMX25(obj) OBJECT_CHECK(FslIMX25State, (obj), TYPE_FSL_IMX25) +#define TYPE_FSL_IMX25 "fsl-imx25" +OBJECT_DECLARE_SIMPLE_TYPE(FslIMX25State, FSL_IMX25) #define FSL_IMX25_NUM_UARTS 5 #define FSL_IMX25_NUM_GPTS 4 @@ -44,7 +44,7 @@ #define FSL_IMX25_NUM_ESDHCS 2 #define FSL_IMX25_NUM_USBS 2 -typedef struct FslIMX25State { +struct FslIMX25State { /*< private >*/ DeviceState parent_obj; @@ -66,7 +66,7 @@ typedef struct FslIMX25State { MemoryRegion iram; MemoryRegion iram_alias; uint32_t phy_num; -} FslIMX25State; +}; /** * i.MX25 memory map @@ -178,7 +178,7 @@ typedef struct FslIMX25State { * 0xBB00_0000 0xBB00_0FFF 4 Kbytes NAND flash main area buffer * 0xBB00_1000 0xBB00_11FF 512 B NAND flash spare area buffer * 0xBB00_1200 0xBB00_1DFF 3 Kbytes Reserved - * 0xBB00_1E00 0xBB00_1FFF 512 B NAND flash control regisers + * 0xBB00_1E00 0xBB00_1FFF 512 B NAND flash control registers * 0xBB01_2000 0xBFFF_FFFF 96 Mbytes (minus 8 Kbytes) Reserved * 0xC000_0000 0xFFFF_FFFF 1024 Mbytes Reserved */ diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h index dd8561b309..40c593a5cf 100644 --- a/include/hw/arm/fsl-imx31.h +++ b/include/hw/arm/fsl-imx31.h @@ -17,7 +17,6 @@ #ifndef FSL_IMX31_H #define FSL_IMX31_H -#include "hw/arm/boot.h" #include "hw/intc/imx_avic.h" #include "hw/misc/imx31_ccm.h" #include "hw/char/imx_serial.h" @@ -28,16 +27,17 @@ #include "hw/watchdog/wdt_imx2.h" #include "exec/memory.h" #include "target/arm/cpu.h" +#include "qom/object.h" -#define TYPE_FSL_IMX31 "fsl,imx31" -#define FSL_IMX31(obj) OBJECT_CHECK(FslIMX31State, (obj), TYPE_FSL_IMX31) +#define TYPE_FSL_IMX31 "fsl-imx31" +OBJECT_DECLARE_SIMPLE_TYPE(FslIMX31State, FSL_IMX31) #define FSL_IMX31_NUM_UARTS 2 #define FSL_IMX31_NUM_EPITS 2 #define FSL_IMX31_NUM_I2CS 3 #define FSL_IMX31_NUM_GPIOS 3 -typedef struct FslIMX31State { +struct FslIMX31State { /*< private >*/ DeviceState parent_obj; @@ -55,7 +55,7 @@ typedef struct FslIMX31State { MemoryRegion rom; MemoryRegion iram; MemoryRegion iram_alias; -} FslIMX31State; +}; #define FSL_IMX31_SECURE_ROM_ADDR 0x00000000 #define FSL_IMX31_SECURE_ROM_SIZE 0x4000 diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h index 162fe99375..61c593ffd2 100644 --- a/include/hw/arm/fsl-imx6.h +++ b/include/hw/arm/fsl-imx6.h @@ -17,10 +17,10 @@ #ifndef FSL_IMX6_H #define FSL_IMX6_H -#include "hw/arm/boot.h" #include "hw/cpu/a9mpcore.h" #include "hw/misc/imx6_ccm.h" #include "hw/misc/imx6_src.h" +#include "hw/misc/imx7_snvs.h" #include "hw/watchdog/wdt_imx2.h" #include "hw/char/imx_serial.h" #include "hw/timer/imx_gpt.h" @@ -32,11 +32,13 @@ #include "hw/net/imx_fec.h" #include "hw/usb/chipidea.h" #include "hw/usb/imx-usb-phy.h" +#include "hw/pci-host/designware.h" #include "exec/memory.h" #include "cpu.h" +#include "qom/object.h" -#define TYPE_FSL_IMX6 "fsl,imx6" -#define FSL_IMX6(obj) OBJECT_CHECK(FslIMX6State, (obj), TYPE_FSL_IMX6) +#define TYPE_FSL_IMX6 "fsl-imx6" +OBJECT_DECLARE_SIMPLE_TYPE(FslIMX6State, FSL_IMX6) #define FSL_IMX6_NUM_CPUS 4 #define FSL_IMX6_NUM_UARTS 5 @@ -49,32 +51,34 @@ #define FSL_IMX6_NUM_USB_PHYS 2 #define FSL_IMX6_NUM_USBS 4 -typedef struct FslIMX6State { +struct FslIMX6State { /*< private >*/ DeviceState parent_obj; /*< public >*/ - ARMCPU cpu[FSL_IMX6_NUM_CPUS]; - A9MPPrivState a9mpcore; - IMX6CCMState ccm; - IMX6SRCState src; - IMXSerialState uart[FSL_IMX6_NUM_UARTS]; - IMXGPTState gpt; - IMXEPITState epit[FSL_IMX6_NUM_EPITS]; - IMXI2CState i2c[FSL_IMX6_NUM_I2CS]; - IMXGPIOState gpio[FSL_IMX6_NUM_GPIOS]; - SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS]; - IMXSPIState spi[FSL_IMX6_NUM_ECSPIS]; - IMX2WdtState wdt[FSL_IMX6_NUM_WDTS]; - IMXUSBPHYState usbphy[FSL_IMX6_NUM_USB_PHYS]; - ChipideaState usb[FSL_IMX6_NUM_USBS]; - IMXFECState eth; - MemoryRegion rom; - MemoryRegion caam; - MemoryRegion ocram; - MemoryRegion ocram_alias; - uint32_t phy_num; -} FslIMX6State; + ARMCPU cpu[FSL_IMX6_NUM_CPUS]; + A9MPPrivState a9mpcore; + IMX6CCMState ccm; + IMX6SRCState src; + IMX7SNVSState snvs; + IMXSerialState uart[FSL_IMX6_NUM_UARTS]; + IMXGPTState gpt; + IMXEPITState epit[FSL_IMX6_NUM_EPITS]; + IMXI2CState i2c[FSL_IMX6_NUM_I2CS]; + IMXGPIOState gpio[FSL_IMX6_NUM_GPIOS]; + SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS]; + IMXSPIState spi[FSL_IMX6_NUM_ECSPIS]; + IMX2WdtState wdt[FSL_IMX6_NUM_WDTS]; + IMXUSBPHYState usbphy[FSL_IMX6_NUM_USB_PHYS]; + ChipideaState usb[FSL_IMX6_NUM_USBS]; + IMXFECState eth; + DesignwarePCIEHost pcie; + MemoryRegion rom; + MemoryRegion caam; + MemoryRegion ocram; + MemoryRegion ocram_alias; + uint32_t phy_num; +}; #define FSL_IMX6_MMDC_ADDR 0x10000000 diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h index fcbaf3dc86..8277b0e8b2 100644 --- a/include/hw/arm/fsl-imx6ul.h +++ b/include/hw/arm/fsl-imx6ul.h @@ -17,12 +17,10 @@ #ifndef FSL_IMX6UL_H #define FSL_IMX6UL_H -#include "hw/arm/boot.h" #include "hw/cpu/a15mpcore.h" #include "hw/misc/imx6ul_ccm.h" #include "hw/misc/imx6_src.h" #include "hw/misc/imx7_snvs.h" -#include "hw/misc/imx7_gpr.h" #include "hw/intc/imx_gpcv2.h" #include "hw/watchdog/wdt_imx2.h" #include "hw/gpio/imx_gpio.h" @@ -30,7 +28,6 @@ #include "hw/timer/imx_gpt.h" #include "hw/timer/imx_epit.h" #include "hw/i2c/imx_i2c.h" -#include "hw/gpio/imx_gpio.h" #include "hw/sd/sdhci.h" #include "hw/ssi/imx_spi.h" #include "hw/net/imx_fec.h" @@ -38,9 +35,11 @@ #include "hw/usb/imx-usb-phy.h" #include "exec/memory.h" #include "cpu.h" +#include "qom/object.h" +#include "qemu/units.h" -#define TYPE_FSL_IMX6UL "fsl,imx6ul" -#define FSL_IMX6UL(obj) OBJECT_CHECK(FslIMX6ULState, (obj), TYPE_FSL_IMX6UL) +#define TYPE_FSL_IMX6UL "fsl-imx6ul" +OBJECT_DECLARE_SIMPLE_TYPE(FslIMX6ULState, FSL_IMX6UL) enum FslIMX6ULConfiguration { FSL_IMX6UL_NUM_CPUS = 1, @@ -58,9 +57,12 @@ enum FslIMX6ULConfiguration { FSL_IMX6UL_NUM_ADCS = 2, FSL_IMX6UL_NUM_USB_PHYS = 2, FSL_IMX6UL_NUM_USBS = 2, + FSL_IMX6UL_NUM_SAIS = 3, + FSL_IMX6UL_NUM_CANS = 2, + FSL_IMX6UL_NUM_PWMS = 8, }; -typedef struct FslIMX6ULState { +struct FslIMX6ULState { /*< private >*/ DeviceState parent_obj; @@ -74,7 +76,6 @@ typedef struct FslIMX6ULState { IMX6SRCState src; IMX7SNVSState snvs; IMXGPCv2State gpcv2; - IMX7GPRState gpr; IMXSPIState spi[FSL_IMX6UL_NUM_ECSPIS]; IMXI2CState i2c[FSL_IMX6UL_NUM_I2CS]; IMXSerialState uart[FSL_IMX6UL_NUM_UARTS]; @@ -89,123 +90,234 @@ typedef struct FslIMX6ULState { MemoryRegion ocram_alias; uint32_t phy_num[FSL_IMX6UL_NUM_ETHS]; -} FslIMX6ULState; + bool phy_connected[FSL_IMX6UL_NUM_ETHS]; +}; enum FslIMX6ULMemoryMap { FSL_IMX6UL_MMDC_ADDR = 0x80000000, - FSL_IMX6UL_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL, + FSL_IMX6UL_MMDC_SIZE = (2 * GiB), FSL_IMX6UL_QSPI1_MEM_ADDR = 0x60000000, + FSL_IMX6UL_QSPI1_MEM_SIZE = (256 * MiB), + FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000, + FSL_IMX6UL_EIM_ALIAS_SIZE = (128 * MiB), + FSL_IMX6UL_EIM_CS_ADDR = 0x50000000, + FSL_IMX6UL_EIM_CS_SIZE = (128 * MiB), + FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000, + FSL_IMX6UL_AES_ENCRYPT_SIZE = (1 * MiB), + FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000, + FSL_IMX6UL_QSPI1_RX_SIZE = (32 * MiB), - /* AIPS-2 */ + /* AIPS-2 Begin */ FSL_IMX6UL_UART6_ADDR = 0x021FC000, + FSL_IMX6UL_I2C4_ADDR = 0x021F8000, + FSL_IMX6UL_UART5_ADDR = 0x021F4000, FSL_IMX6UL_UART4_ADDR = 0x021F0000, FSL_IMX6UL_UART3_ADDR = 0x021EC000, FSL_IMX6UL_UART2_ADDR = 0x021E8000, + FSL_IMX6UL_WDOG3_ADDR = 0x021E4000, + FSL_IMX6UL_QSPI_ADDR = 0x021E0000, + FSL_IMX6UL_QSPI_SIZE = 0x500, + FSL_IMX6UL_SYS_CNT_CTRL_ADDR = 0x021DC000, + FSL_IMX6UL_SYS_CNT_CTRL_SIZE = (16 * KiB), + FSL_IMX6UL_SYS_CNT_CMP_ADDR = 0x021D8000, + FSL_IMX6UL_SYS_CNT_CMP_SIZE = (16 * KiB), + FSL_IMX6UL_SYS_CNT_RD_ADDR = 0x021D4000, + FSL_IMX6UL_SYS_CNT_RD_SIZE = (16 * KiB), + FSL_IMX6UL_TZASC_ADDR = 0x021D0000, + FSL_IMX6UL_TZASC_SIZE = (16 * KiB), + FSL_IMX6UL_PXP_ADDR = 0x021CC000, + FSL_IMX6UL_PXP_SIZE = (16 * KiB), + FSL_IMX6UL_LCDIF_ADDR = 0x021C8000, + FSL_IMX6UL_LCDIF_SIZE = 0x100, + FSL_IMX6UL_CSI_ADDR = 0x021C4000, + FSL_IMX6UL_CSI_SIZE = 0x100, + FSL_IMX6UL_CSU_ADDR = 0x021C0000, + FSL_IMX6UL_CSU_SIZE = (16 * KiB), + FSL_IMX6UL_OCOTP_CTRL_ADDR = 0x021BC000, + FSL_IMX6UL_OCOTP_CTRL_SIZE = (4 * KiB), + FSL_IMX6UL_EIM_ADDR = 0x021B8000, + FSL_IMX6UL_EIM_SIZE = 0x100, + FSL_IMX6UL_SIM2_ADDR = 0x021B4000, + FSL_IMX6UL_MMDC_CFG_ADDR = 0x021B0000, + FSL_IMX6UL_MMDC_CFG_SIZE = (4 * KiB), + FSL_IMX6UL_ROMCP_ADDR = 0x021AC000, + FSL_IMX6UL_ROMCP_SIZE = 0x300, + FSL_IMX6UL_I2C3_ADDR = 0x021A8000, FSL_IMX6UL_I2C2_ADDR = 0x021A4000, FSL_IMX6UL_I2C1_ADDR = 0x021A0000, + FSL_IMX6UL_ADC2_ADDR = 0x0219C000, FSL_IMX6UL_ADC1_ADDR = 0x02198000, + FSL_IMX6UL_ADCn_SIZE = 0x100, + FSL_IMX6UL_USDHC2_ADDR = 0x02194000, FSL_IMX6UL_USDHC1_ADDR = 0x02190000, + FSL_IMX6UL_SIM1_ADDR = 0x0218C000, + FSL_IMX6UL_SIMn_SIZE = (16 * KiB), + FSL_IMX6UL_ENET1_ADDR = 0x02188000, + FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800, - FSL_IMX6UL_USBO2_USB_ADDR = 0x02184000, + FSL_IMX6UL_USBO2_USBMISC_SIZE = 0x200, + + FSL_IMX6UL_USBO2_USB1_ADDR = 0x02184000, + FSL_IMX6UL_USBO2_USB2_ADDR = 0x02184200, + FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000, + FSL_IMX6UL_USBO2_PL301_SIZE = (16 * KiB), + FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000, + FSL_IMX6UL_AIPS2_CFG_SIZE = 0x100, + FSL_IMX6UL_CAAM_ADDR = 0x02140000, + FSL_IMX6UL_CAAM_SIZE = (16 * KiB), + FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000, + FSL_IMX6UL_A7MPCORE_DAP_SIZE = (4 * KiB), + /* AIPS-2 End */ - /* AIPS-1 */ + /* AIPS-1 Begin */ FSL_IMX6UL_PWM8_ADDR = 0x020FC000, FSL_IMX6UL_PWM7_ADDR = 0x020F8000, FSL_IMX6UL_PWM6_ADDR = 0x020F4000, FSL_IMX6UL_PWM5_ADDR = 0x020F0000, + FSL_IMX6UL_SDMA_ADDR = 0x020EC000, + FSL_IMX6UL_SDMA_SIZE = 0x300, + FSL_IMX6UL_GPT2_ADDR = 0x020E8000, + FSL_IMX6UL_IOMUXC_GPR_ADDR = 0x020E4000, + FSL_IMX6UL_IOMUXC_GPR_SIZE = 0x40, + FSL_IMX6UL_IOMUXC_ADDR = 0x020E0000, + FSL_IMX6UL_IOMUXC_SIZE = 0x700, + FSL_IMX6UL_GPC_ADDR = 0x020DC000, + FSL_IMX6UL_SRC_ADDR = 0x020D8000, + FSL_IMX6UL_EPIT2_ADDR = 0x020D4000, FSL_IMX6UL_EPIT1_ADDR = 0x020D0000, + FSL_IMX6UL_SNVS_HP_ADDR = 0x020CC000, + FSL_IMX6UL_USBPHY2_ADDR = 0x020CA000, - FSL_IMX6UL_USBPHY2_SIZE = (4 * 1024), FSL_IMX6UL_USBPHY1_ADDR = 0x020C9000, - FSL_IMX6UL_USBPHY1_SIZE = (4 * 1024), + FSL_IMX6UL_ANALOG_ADDR = 0x020C8000, + FSL_IMX6UL_ANALOG_SIZE = 0x300, + FSL_IMX6UL_CCM_ADDR = 0x020C4000, + FSL_IMX6UL_WDOG2_ADDR = 0x020C0000, FSL_IMX6UL_WDOG1_ADDR = 0x020BC000, + FSL_IMX6UL_KPP_ADDR = 0x020B8000, + FSL_IMX6UL_KPP_SIZE = 0x10, + FSL_IMX6UL_ENET2_ADDR = 0x020B4000, + FSL_IMX6UL_SNVS_LP_ADDR = 0x020B0000, + FSL_IMX6UL_SNVS_LP_SIZE = (16 * KiB), + FSL_IMX6UL_GPIO5_ADDR = 0x020AC000, FSL_IMX6UL_GPIO4_ADDR = 0x020A8000, FSL_IMX6UL_GPIO3_ADDR = 0x020A4000, FSL_IMX6UL_GPIO2_ADDR = 0x020A0000, FSL_IMX6UL_GPIO1_ADDR = 0x0209C000, + FSL_IMX6UL_GPT1_ADDR = 0x02098000, + FSL_IMX6UL_CAN2_ADDR = 0x02094000, FSL_IMX6UL_CAN1_ADDR = 0x02090000, + FSL_IMX6UL_CANn_SIZE = (4 * KiB), + FSL_IMX6UL_PWM4_ADDR = 0x0208C000, FSL_IMX6UL_PWM3_ADDR = 0x02088000, FSL_IMX6UL_PWM2_ADDR = 0x02084000, FSL_IMX6UL_PWM1_ADDR = 0x02080000, + FSL_IMX6UL_PWMn_SIZE = 0x20, + FSL_IMX6UL_AIPS1_CFG_ADDR = 0x0207C000, + FSL_IMX6UL_AIPS1_CFG_SIZE = (16 * KiB), + FSL_IMX6UL_BEE_ADDR = 0x02044000, + FSL_IMX6UL_BEE_SIZE = (16 * KiB), + FSL_IMX6UL_TOUCH_CTRL_ADDR = 0x02040000, + FSL_IMX6UL_TOUCH_CTRL_SIZE = 0x100, + FSL_IMX6UL_SPBA_ADDR = 0x0203C000, + FSL_IMX6UL_SPBA_SIZE = 0x100, + FSL_IMX6UL_ASRC_ADDR = 0x02034000, + FSL_IMX6UL_ASRC_SIZE = 0x100, + FSL_IMX6UL_SAI3_ADDR = 0x02030000, FSL_IMX6UL_SAI2_ADDR = 0x0202C000, FSL_IMX6UL_SAI1_ADDR = 0x02028000, + FSL_IMX6UL_SAIn_SIZE = 0x200, + FSL_IMX6UL_UART8_ADDR = 0x02024000, FSL_IMX6UL_UART1_ADDR = 0x02020000, FSL_IMX6UL_UART7_ADDR = 0x02018000, + FSL_IMX6UL_ECSPI4_ADDR = 0x02014000, FSL_IMX6UL_ECSPI3_ADDR = 0x02010000, FSL_IMX6UL_ECSPI2_ADDR = 0x0200C000, FSL_IMX6UL_ECSPI1_ADDR = 0x02008000, + FSL_IMX6UL_SPDIF_ADDR = 0x02004000, + FSL_IMX6UL_SPDIF_SIZE = 0x100, + /* AIPS-1 End */ + + FSL_IMX6UL_BCH_ADDR = 0x01808000, + FSL_IMX6UL_BCH_SIZE = 0x200, + + FSL_IMX6UL_GPMI_ADDR = 0x01806000, + FSL_IMX6UL_GPMI_SIZE = 0x200, FSL_IMX6UL_APBH_DMA_ADDR = 0x01804000, - FSL_IMX6UL_APBH_DMA_SIZE = (32 * 1024), + FSL_IMX6UL_APBH_DMA_SIZE = (4 * KiB), FSL_IMX6UL_A7MPCORE_ADDR = 0x00A00000, FSL_IMX6UL_OCRAM_ALIAS_ADDR = 0x00920000, - FSL_IMX6UL_OCRAM_ALIAS_SIZE = 0x00060000, + FSL_IMX6UL_OCRAM_ALIAS_SIZE = (384 * KiB), + FSL_IMX6UL_OCRAM_MEM_ADDR = 0x00900000, - FSL_IMX6UL_OCRAM_MEM_SIZE = 0x00020000, + FSL_IMX6UL_OCRAM_MEM_SIZE = (128 * KiB), + FSL_IMX6UL_CAAM_MEM_ADDR = 0x00100000, - FSL_IMX6UL_CAAM_MEM_SIZE = 0x00008000, + FSL_IMX6UL_CAAM_MEM_SIZE = (32 * KiB), + FSL_IMX6UL_ROM_ADDR = 0x00000000, - FSL_IMX6UL_ROM_SIZE = 0x00018000, + FSL_IMX6UL_ROM_SIZE = (96 * KiB), }; enum FslIMX6ULIRQs { diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h index ad88923707..411fa1c2e3 100644 --- a/include/hw/arm/fsl-imx7.h +++ b/include/hw/arm/fsl-imx7.h @@ -19,29 +19,29 @@ #ifndef FSL_IMX7_H #define FSL_IMX7_H -#include "hw/arm/boot.h" #include "hw/cpu/a15mpcore.h" #include "hw/intc/imx_gpcv2.h" #include "hw/misc/imx7_ccm.h" #include "hw/misc/imx7_snvs.h" #include "hw/misc/imx7_gpr.h" -#include "hw/misc/imx6_src.h" +#include "hw/misc/imx7_src.h" #include "hw/watchdog/wdt_imx2.h" #include "hw/gpio/imx_gpio.h" #include "hw/char/imx_serial.h" #include "hw/timer/imx_gpt.h" #include "hw/timer/imx_epit.h" #include "hw/i2c/imx_i2c.h" -#include "hw/gpio/imx_gpio.h" #include "hw/sd/sdhci.h" #include "hw/ssi/imx_spi.h" #include "hw/net/imx_fec.h" #include "hw/pci-host/designware.h" #include "hw/usb/chipidea.h" #include "cpu.h" +#include "qom/object.h" +#include "qemu/units.h" -#define TYPE_FSL_IMX7 "fsl,imx7" -#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7) +#define TYPE_FSL_IMX7 "fsl-imx7" +OBJECT_DECLARE_SIMPLE_TYPE(FslIMX7State, FSL_IMX7) enum FslIMX7Configuration { FSL_IMX7_NUM_CPUS = 2, @@ -57,9 +57,12 @@ enum FslIMX7Configuration { FSL_IMX7_NUM_ECSPIS = 4, FSL_IMX7_NUM_USBS = 3, FSL_IMX7_NUM_ADCS = 2, + FSL_IMX7_NUM_SAIS = 3, + FSL_IMX7_NUM_CANS = 2, + FSL_IMX7_NUM_PWMS = 4, }; -typedef struct FslIMX7State { +struct FslIMX7State { /*< private >*/ DeviceState parent_obj; @@ -71,6 +74,7 @@ typedef struct FslIMX7State { IMX7CCMState ccm; IMX7AnalogState analog; IMX7SNVSState snvs; + IMX7SRCState src; IMXGPCv2State gpcv2; IMXSPIState spi[FSL_IMX7_NUM_ECSPIS]; IMXI2CState i2c[FSL_IMX7_NUM_I2CS]; @@ -81,126 +85,293 @@ typedef struct FslIMX7State { IMX7GPRState gpr; ChipideaState usb[FSL_IMX7_NUM_USBS]; DesignwarePCIEHost pcie; + MemoryRegion rom; + MemoryRegion caam; + MemoryRegion ocram; + MemoryRegion ocram_epdc; + MemoryRegion ocram_pxp; + MemoryRegion ocram_s; + uint32_t phy_num[FSL_IMX7_NUM_ETHS]; -} FslIMX7State; + bool phy_connected[FSL_IMX7_NUM_ETHS]; +}; enum FslIMX7MemoryMap { FSL_IMX7_MMDC_ADDR = 0x80000000, - FSL_IMX7_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL, + FSL_IMX7_MMDC_SIZE = (2 * GiB), - FSL_IMX7_GPIO1_ADDR = 0x30200000, - FSL_IMX7_GPIO2_ADDR = 0x30210000, - FSL_IMX7_GPIO3_ADDR = 0x30220000, - FSL_IMX7_GPIO4_ADDR = 0x30230000, - FSL_IMX7_GPIO5_ADDR = 0x30240000, - FSL_IMX7_GPIO6_ADDR = 0x30250000, - FSL_IMX7_GPIO7_ADDR = 0x30260000, + FSL_IMX7_QSPI1_MEM_ADDR = 0x60000000, + FSL_IMX7_QSPI1_MEM_SIZE = (256 * MiB), - FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000, + FSL_IMX7_PCIE1_MEM_ADDR = 0x40000000, + FSL_IMX7_PCIE1_MEM_SIZE = (256 * MiB), - FSL_IMX7_WDOG1_ADDR = 0x30280000, - FSL_IMX7_WDOG2_ADDR = 0x30290000, - FSL_IMX7_WDOG3_ADDR = 0x302A0000, - FSL_IMX7_WDOG4_ADDR = 0x302B0000, + FSL_IMX7_QSPI1_RX_BUF_ADDR = 0x34000000, + FSL_IMX7_QSPI1_RX_BUF_SIZE = (32 * MiB), - FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000, + /* PCIe Peripherals */ + FSL_IMX7_PCIE_REG_ADDR = 0x33800000, - FSL_IMX7_GPT1_ADDR = 0x302D0000, - FSL_IMX7_GPT2_ADDR = 0x302E0000, - FSL_IMX7_GPT3_ADDR = 0x302F0000, - FSL_IMX7_GPT4_ADDR = 0x30300000, + /* MMAP Peripherals */ + FSL_IMX7_DMA_APBH_ADDR = 0x33000000, + FSL_IMX7_DMA_APBH_SIZE = 0x8000, + + /* GPV configuration */ + FSL_IMX7_GPV6_ADDR = 0x32600000, + FSL_IMX7_GPV5_ADDR = 0x32500000, + FSL_IMX7_GPV4_ADDR = 0x32400000, + FSL_IMX7_GPV3_ADDR = 0x32300000, + FSL_IMX7_GPV2_ADDR = 0x32200000, + FSL_IMX7_GPV1_ADDR = 0x32100000, + FSL_IMX7_GPV0_ADDR = 0x32000000, + FSL_IMX7_GPVn_SIZE = (1 * MiB), + + /* Arm Peripherals */ + FSL_IMX7_A7MPCORE_ADDR = 0x31000000, - FSL_IMX7_IOMUXC_ADDR = 0x30330000, - FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000, - FSL_IMX7_IOMUXCn_SIZE = 0x1000, + /* AIPS-3 Begin */ - FSL_IMX7_OCOTP_ADDR = 0x30350000, - FSL_IMX7_OCOTP_SIZE = 0x10000, + FSL_IMX7_ENET2_ADDR = 0x30BF0000, + FSL_IMX7_ENET1_ADDR = 0x30BE0000, - FSL_IMX7_ANALOG_ADDR = 0x30360000, - FSL_IMX7_SNVS_ADDR = 0x30370000, - FSL_IMX7_CCM_ADDR = 0x30380000, + FSL_IMX7_SDMA_ADDR = 0x30BD0000, + FSL_IMX7_SDMA_SIZE = (4 * KiB), - FSL_IMX7_SRC_ADDR = 0x30390000, - FSL_IMX7_SRC_SIZE = 0x1000, + FSL_IMX7_EIM_ADDR = 0x30BC0000, + FSL_IMX7_EIM_SIZE = (4 * KiB), - FSL_IMX7_ADC1_ADDR = 0x30610000, - FSL_IMX7_ADC2_ADDR = 0x30620000, - FSL_IMX7_ADCn_SIZE = 0x1000, + FSL_IMX7_QSPI_ADDR = 0x30BB0000, + FSL_IMX7_QSPI_SIZE = 0x8000, - FSL_IMX7_PWM1_ADDR = 0x30660000, - FSL_IMX7_PWM2_ADDR = 0x30670000, - FSL_IMX7_PWM3_ADDR = 0x30680000, - FSL_IMX7_PWM4_ADDR = 0x30690000, - FSL_IMX7_PWMn_SIZE = 0x10000, + FSL_IMX7_SIM2_ADDR = 0x30BA0000, + FSL_IMX7_SIM1_ADDR = 0x30B90000, + FSL_IMX7_SIMn_SIZE = (4 * KiB), - FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000, - FSL_IMX7_PCIE_PHY_SIZE = 0x10000, + FSL_IMX7_USDHC3_ADDR = 0x30B60000, + FSL_IMX7_USDHC2_ADDR = 0x30B50000, + FSL_IMX7_USDHC1_ADDR = 0x30B40000, - FSL_IMX7_GPC_ADDR = 0x303A0000, + FSL_IMX7_USB3_ADDR = 0x30B30000, + FSL_IMX7_USBMISC3_ADDR = 0x30B30200, + FSL_IMX7_USB2_ADDR = 0x30B20000, + FSL_IMX7_USBMISC2_ADDR = 0x30B20200, + FSL_IMX7_USB1_ADDR = 0x30B10000, + FSL_IMX7_USBMISC1_ADDR = 0x30B10200, + FSL_IMX7_USBMISCn_SIZE = 0x200, - FSL_IMX7_CAAM_ADDR = 0x30900000, - FSL_IMX7_CAAM_SIZE = 0x40000, + FSL_IMX7_USB_PL301_ADDR = 0x30AD0000, + FSL_IMX7_USB_PL301_SIZE = (64 * KiB), - FSL_IMX7_CAN1_ADDR = 0x30A00000, - FSL_IMX7_CAN2_ADDR = 0x30A10000, - FSL_IMX7_CANn_SIZE = 0x10000, + FSL_IMX7_SEMAPHORE_HS_ADDR = 0x30AC0000, + FSL_IMX7_SEMAPHORE_HS_SIZE = (64 * KiB), + + FSL_IMX7_MUB_ADDR = 0x30AB0000, + FSL_IMX7_MUA_ADDR = 0x30AA0000, + FSL_IMX7_MUn_SIZE = (KiB), + + FSL_IMX7_UART7_ADDR = 0x30A90000, + FSL_IMX7_UART6_ADDR = 0x30A80000, + FSL_IMX7_UART5_ADDR = 0x30A70000, + FSL_IMX7_UART4_ADDR = 0x30A60000, - FSL_IMX7_I2C1_ADDR = 0x30A20000, - FSL_IMX7_I2C2_ADDR = 0x30A30000, - FSL_IMX7_I2C3_ADDR = 0x30A40000, FSL_IMX7_I2C4_ADDR = 0x30A50000, + FSL_IMX7_I2C3_ADDR = 0x30A40000, + FSL_IMX7_I2C2_ADDR = 0x30A30000, + FSL_IMX7_I2C1_ADDR = 0x30A20000, - FSL_IMX7_ECSPI1_ADDR = 0x30820000, - FSL_IMX7_ECSPI2_ADDR = 0x30830000, - FSL_IMX7_ECSPI3_ADDR = 0x30840000, - FSL_IMX7_ECSPI4_ADDR = 0x30630000, + FSL_IMX7_CAN2_ADDR = 0x30A10000, + FSL_IMX7_CAN1_ADDR = 0x30A00000, + FSL_IMX7_CANn_SIZE = (4 * KiB), - FSL_IMX7_LCDIF_ADDR = 0x30730000, - FSL_IMX7_LCDIF_SIZE = 0x1000, + FSL_IMX7_AIPS3_CONF_ADDR = 0x309F0000, + FSL_IMX7_AIPS3_CONF_SIZE = (64 * KiB), - FSL_IMX7_UART1_ADDR = 0x30860000, + FSL_IMX7_CAAM_ADDR = 0x30900000, + FSL_IMX7_CAAM_SIZE = (256 * KiB), + + FSL_IMX7_SPBA_ADDR = 0x308F0000, + FSL_IMX7_SPBA_SIZE = (4 * KiB), + + FSL_IMX7_SAI3_ADDR = 0x308C0000, + FSL_IMX7_SAI2_ADDR = 0x308B0000, + FSL_IMX7_SAI1_ADDR = 0x308A0000, + FSL_IMX7_SAIn_SIZE = (4 * KiB), + + FSL_IMX7_UART3_ADDR = 0x30880000, /* * Some versions of the reference manual claim that UART2 is @ * 0x30870000, but experiments with HW + DT files in upstream * Linux kernel show that not to be true and that block is - * acutally located @ 0x30890000 + * actually located @ 0x30890000 */ FSL_IMX7_UART2_ADDR = 0x30890000, - FSL_IMX7_UART3_ADDR = 0x30880000, - FSL_IMX7_UART4_ADDR = 0x30A60000, - FSL_IMX7_UART5_ADDR = 0x30A70000, - FSL_IMX7_UART6_ADDR = 0x30A80000, - FSL_IMX7_UART7_ADDR = 0x30A90000, + FSL_IMX7_UART1_ADDR = 0x30860000, - FSL_IMX7_ENET1_ADDR = 0x30BE0000, - FSL_IMX7_ENET2_ADDR = 0x30BF0000, + FSL_IMX7_ECSPI3_ADDR = 0x30840000, + FSL_IMX7_ECSPI2_ADDR = 0x30830000, + FSL_IMX7_ECSPI1_ADDR = 0x30820000, + FSL_IMX7_ECSPIn_SIZE = (4 * KiB), - FSL_IMX7_USB1_ADDR = 0x30B10000, - FSL_IMX7_USBMISC1_ADDR = 0x30B10200, - FSL_IMX7_USB2_ADDR = 0x30B20000, - FSL_IMX7_USBMISC2_ADDR = 0x30B20200, - FSL_IMX7_USB3_ADDR = 0x30B30000, - FSL_IMX7_USBMISC3_ADDR = 0x30B30200, - FSL_IMX7_USBMISCn_SIZE = 0x200, + /* AIPS-3 End */ - FSL_IMX7_USDHC1_ADDR = 0x30B40000, - FSL_IMX7_USDHC2_ADDR = 0x30B50000, - FSL_IMX7_USDHC3_ADDR = 0x30B60000, + /* AIPS-2 Begin */ - FSL_IMX7_SDMA_ADDR = 0x30BD0000, - FSL_IMX7_SDMA_SIZE = 0x1000, + FSL_IMX7_AXI_DEBUG_MON_ADDR = 0x307E0000, + FSL_IMX7_AXI_DEBUG_MON_SIZE = (64 * KiB), + + FSL_IMX7_PERFMON2_ADDR = 0x307D0000, + FSL_IMX7_PERFMON1_ADDR = 0x307C0000, + FSL_IMX7_PERFMONn_SIZE = (64 * KiB), + + FSL_IMX7_DDRC_ADDR = 0x307A0000, + FSL_IMX7_DDRC_SIZE = (4 * KiB), + + FSL_IMX7_DDRC_PHY_ADDR = 0x30790000, + FSL_IMX7_DDRC_PHY_SIZE = (4 * KiB), + + FSL_IMX7_TZASC_ADDR = 0x30780000, + FSL_IMX7_TZASC_SIZE = (64 * KiB), + + FSL_IMX7_MIPI_DSI_ADDR = 0x30760000, + FSL_IMX7_MIPI_DSI_SIZE = (4 * KiB), + + FSL_IMX7_MIPI_CSI_ADDR = 0x30750000, + FSL_IMX7_MIPI_CSI_SIZE = 0x4000, + + FSL_IMX7_LCDIF_ADDR = 0x30730000, + FSL_IMX7_LCDIF_SIZE = 0x8000, + + FSL_IMX7_CSI_ADDR = 0x30710000, + FSL_IMX7_CSI_SIZE = (4 * KiB), + + FSL_IMX7_PXP_ADDR = 0x30700000, + FSL_IMX7_PXP_SIZE = 0x4000, + + FSL_IMX7_EPDC_ADDR = 0x306F0000, + FSL_IMX7_EPDC_SIZE = (4 * KiB), + + FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000, + FSL_IMX7_PCIE_PHY_SIZE = (4 * KiB), + + FSL_IMX7_SYSCNT_CTRL_ADDR = 0x306C0000, + FSL_IMX7_SYSCNT_CMP_ADDR = 0x306B0000, + FSL_IMX7_SYSCNT_RD_ADDR = 0x306A0000, + + FSL_IMX7_PWM4_ADDR = 0x30690000, + FSL_IMX7_PWM3_ADDR = 0x30680000, + FSL_IMX7_PWM2_ADDR = 0x30670000, + FSL_IMX7_PWM1_ADDR = 0x30660000, + FSL_IMX7_PWMn_SIZE = (4 * KiB), + + FSL_IMX7_FlEXTIMER2_ADDR = 0x30650000, + FSL_IMX7_FlEXTIMER1_ADDR = 0x30640000, + FSL_IMX7_FLEXTIMERn_SIZE = (4 * KiB), + + FSL_IMX7_ECSPI4_ADDR = 0x30630000, + + FSL_IMX7_ADC2_ADDR = 0x30620000, + FSL_IMX7_ADC1_ADDR = 0x30610000, + FSL_IMX7_ADCn_SIZE = (4 * KiB), + + FSL_IMX7_AIPS2_CONF_ADDR = 0x305F0000, + FSL_IMX7_AIPS2_CONF_SIZE = (64 * KiB), + + /* AIPS-2 End */ + + /* AIPS-1 Begin */ + + FSL_IMX7_CSU_ADDR = 0x303E0000, + FSL_IMX7_CSU_SIZE = (64 * KiB), + + FSL_IMX7_RDC_ADDR = 0x303D0000, + FSL_IMX7_RDC_SIZE = (4 * KiB), + + FSL_IMX7_SEMAPHORE2_ADDR = 0x303C0000, + FSL_IMX7_SEMAPHORE1_ADDR = 0x303B0000, + FSL_IMX7_SEMAPHOREn_SIZE = (4 * KiB), + + FSL_IMX7_GPC_ADDR = 0x303A0000, + + FSL_IMX7_SRC_ADDR = 0x30390000, + + FSL_IMX7_CCM_ADDR = 0x30380000, + + FSL_IMX7_SNVS_HP_ADDR = 0x30370000, + + FSL_IMX7_ANALOG_ADDR = 0x30360000, + + FSL_IMX7_OCOTP_ADDR = 0x30350000, + FSL_IMX7_OCOTP_SIZE = 0x10000, + + FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000, + FSL_IMX7_IOMUXC_GPR_SIZE = (4 * KiB), + + FSL_IMX7_IOMUXC_ADDR = 0x30330000, + FSL_IMX7_IOMUXC_SIZE = (4 * KiB), + + FSL_IMX7_KPP_ADDR = 0x30320000, + FSL_IMX7_KPP_SIZE = (4 * KiB), + + FSL_IMX7_ROMCP_ADDR = 0x30310000, + FSL_IMX7_ROMCP_SIZE = (4 * KiB), + + FSL_IMX7_GPT4_ADDR = 0x30300000, + FSL_IMX7_GPT3_ADDR = 0x302F0000, + FSL_IMX7_GPT2_ADDR = 0x302E0000, + FSL_IMX7_GPT1_ADDR = 0x302D0000, + + FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000, + FSL_IMX7_IOMUXC_LPSR_SIZE = (4 * KiB), + + FSL_IMX7_WDOG4_ADDR = 0x302B0000, + FSL_IMX7_WDOG3_ADDR = 0x302A0000, + FSL_IMX7_WDOG2_ADDR = 0x30290000, + FSL_IMX7_WDOG1_ADDR = 0x30280000, + + FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000, + + FSL_IMX7_GPIO7_ADDR = 0x30260000, + FSL_IMX7_GPIO6_ADDR = 0x30250000, + FSL_IMX7_GPIO5_ADDR = 0x30240000, + FSL_IMX7_GPIO4_ADDR = 0x30230000, + FSL_IMX7_GPIO3_ADDR = 0x30220000, + FSL_IMX7_GPIO2_ADDR = 0x30210000, + FSL_IMX7_GPIO1_ADDR = 0x30200000, + + FSL_IMX7_AIPS1_CONF_ADDR = 0x301F0000, + FSL_IMX7_AIPS1_CONF_SIZE = (64 * KiB), - FSL_IMX7_A7MPCORE_ADDR = 0x31000000, FSL_IMX7_A7MPCORE_DAP_ADDR = 0x30000000, + FSL_IMX7_A7MPCORE_DAP_SIZE = (1 * MiB), - FSL_IMX7_PCIE_REG_ADDR = 0x33800000, - FSL_IMX7_PCIE_REG_SIZE = 16 * 1024, + /* AIPS-1 End */ - FSL_IMX7_GPR_ADDR = 0x30340000, + FSL_IMX7_EIM_CS0_ADDR = 0x28000000, + FSL_IMX7_EIM_CS0_SIZE = (128 * MiB), - FSL_IMX7_DMA_APBH_ADDR = 0x33000000, - FSL_IMX7_DMA_APBH_SIZE = 0x2000, + FSL_IMX7_OCRAM_PXP_ADDR = 0x00940000, + FSL_IMX7_OCRAM_PXP_SIZE = (32 * KiB), + + FSL_IMX7_OCRAM_EPDC_ADDR = 0x00920000, + FSL_IMX7_OCRAM_EPDC_SIZE = (128 * KiB), + + FSL_IMX7_OCRAM_MEM_ADDR = 0x00900000, + FSL_IMX7_OCRAM_MEM_SIZE = (128 * KiB), + + FSL_IMX7_TCMU_ADDR = 0x00800000, + FSL_IMX7_TCMU_SIZE = (32 * KiB), + + FSL_IMX7_TCML_ADDR = 0x007F8000, + FSL_IMX7_TCML_SIZE = (32 * KiB), + + FSL_IMX7_OCRAM_S_ADDR = 0x00180000, + FSL_IMX7_OCRAM_S_SIZE = (32 * KiB), + + FSL_IMX7_CAAM_MEM_ADDR = 0x00100000, + FSL_IMX7_CAAM_MEM_SIZE = (32 * KiB), + + FSL_IMX7_ROM_ADDR = 0x00000000, + FSL_IMX7_ROM_SIZE = (96 * KiB), }; enum FslIMX7IRQs { @@ -229,6 +400,26 @@ enum FslIMX7IRQs { FSL_IMX7_USB2_IRQ = 42, FSL_IMX7_USB3_IRQ = 40, + FSL_IMX7_GPT1_IRQ = 55, + FSL_IMX7_GPT2_IRQ = 54, + FSL_IMX7_GPT3_IRQ = 53, + FSL_IMX7_GPT4_IRQ = 52, + + FSL_IMX7_GPIO1_LOW_IRQ = 64, + FSL_IMX7_GPIO1_HIGH_IRQ = 65, + FSL_IMX7_GPIO2_LOW_IRQ = 66, + FSL_IMX7_GPIO2_HIGH_IRQ = 67, + FSL_IMX7_GPIO3_LOW_IRQ = 68, + FSL_IMX7_GPIO3_HIGH_IRQ = 69, + FSL_IMX7_GPIO4_LOW_IRQ = 70, + FSL_IMX7_GPIO4_HIGH_IRQ = 71, + FSL_IMX7_GPIO5_LOW_IRQ = 72, + FSL_IMX7_GPIO5_HIGH_IRQ = 73, + FSL_IMX7_GPIO6_LOW_IRQ = 74, + FSL_IMX7_GPIO6_HIGH_IRQ = 75, + FSL_IMX7_GPIO7_LOW_IRQ = 76, + FSL_IMX7_GPIO7_HIGH_IRQ = 77, + FSL_IMX7_WDOG1_IRQ = 78, FSL_IMX7_WDOG2_IRQ = 79, FSL_IMX7_WDOG3_IRQ = 10, diff --git a/include/hw/arm/linux-boot-if.h b/include/hw/arm/linux-boot-if.h index 7bbdfd1cc6..c85f33b2c5 100644 --- a/include/hw/arm/linux-boot-if.h +++ b/include/hw/arm/linux-boot-if.h @@ -9,16 +9,15 @@ #include "qom/object.h" #define TYPE_ARM_LINUX_BOOT_IF "arm-linux-boot-if" -#define ARM_LINUX_BOOT_IF_CLASS(klass) \ - OBJECT_CLASS_CHECK(ARMLinuxBootIfClass, (klass), TYPE_ARM_LINUX_BOOT_IF) -#define ARM_LINUX_BOOT_IF_GET_CLASS(obj) \ - OBJECT_GET_CLASS(ARMLinuxBootIfClass, (obj), TYPE_ARM_LINUX_BOOT_IF) +typedef struct ARMLinuxBootIfClass ARMLinuxBootIfClass; +DECLARE_CLASS_CHECKERS(ARMLinuxBootIfClass, ARM_LINUX_BOOT_IF, + TYPE_ARM_LINUX_BOOT_IF) #define ARM_LINUX_BOOT_IF(obj) \ INTERFACE_CHECK(ARMLinuxBootIf, (obj), TYPE_ARM_LINUX_BOOT_IF) typedef struct ARMLinuxBootIf ARMLinuxBootIf; -typedef struct ARMLinuxBootIfClass { +struct ARMLinuxBootIfClass { /*< private >*/ InterfaceClass parent_class; @@ -35,6 +34,6 @@ typedef struct ARMLinuxBootIfClass { * (or for a CPU which doesn't support TrustZone) */ void (*arm_linux_init)(ARMLinuxBootIf *obj, bool secure_boot); -} ARMLinuxBootIfClass; +}; #endif diff --git a/include/hw/arm/msf2-soc.h b/include/hw/arm/msf2-soc.h index c9cb214aa6..9300664e8e 100644 --- a/include/hw/arm/msf2-soc.h +++ b/include/hw/arm/msf2-soc.h @@ -30,9 +30,11 @@ #include "hw/misc/msf2-sysreg.h" #include "hw/ssi/mss-spi.h" #include "hw/net/msf2-emac.h" +#include "hw/clock.h" +#include "qom/object.h" #define TYPE_MSF2_SOC "msf2-soc" -#define MSF2_SOC(obj) OBJECT_CHECK(MSF2State, (obj), TYPE_MSF2_SOC) +OBJECT_DECLARE_SIMPLE_TYPE(MSF2State, MSF2_SOC) #define MSF2_NUM_SPIS 2 #define MSF2_NUM_UARTS 2 @@ -44,19 +46,17 @@ */ #define MSF2_NUM_TIMERS 2 -typedef struct MSF2State { - /*< private >*/ +struct MSF2State { SysBusDevice parent_obj; - /*< public >*/ ARMv7MState armv7m; - char *cpu_type; char *part_name; uint64_t envm_size; uint64_t esram_size; - uint32_t m3clk; + Clock *m3clk; + Clock *refclk; uint8_t apb0div; uint8_t apb1div; @@ -64,6 +64,10 @@ typedef struct MSF2State { MSSTimerState timer; MSSSpiState spi[MSF2_NUM_SPIS]; MSF2EmacState emac; -} MSF2State; + + MemoryRegion nvm; + MemoryRegion nvm_alias; + MemoryRegion sram; +}; #endif diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h new file mode 100644 index 0000000000..4e0d210188 --- /dev/null +++ b/include/hw/arm/npcm7xx.h @@ -0,0 +1,139 @@ +/* + * Nuvoton NPCM7xx SoC family. + * + * Copyright 2020 Google LLC + * + * 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. + */ +#ifndef NPCM7XX_H +#define NPCM7XX_H + +#include "hw/boards.h" +#include "hw/adc/npcm7xx_adc.h" +#include "hw/core/split-irq.h" +#include "hw/cpu/a9mpcore.h" +#include "hw/gpio/npcm7xx_gpio.h" +#include "hw/i2c/npcm7xx_smbus.h" +#include "hw/mem/npcm7xx_mc.h" +#include "hw/misc/npcm7xx_clk.h" +#include "hw/misc/npcm7xx_gcr.h" +#include "hw/misc/npcm7xx_mft.h" +#include "hw/misc/npcm7xx_pwm.h" +#include "hw/misc/npcm7xx_rng.h" +#include "hw/net/npcm7xx_emc.h" +#include "hw/net/npcm_gmac.h" +#include "hw/nvram/npcm7xx_otp.h" +#include "hw/timer/npcm7xx_timer.h" +#include "hw/ssi/npcm7xx_fiu.h" +#include "hw/ssi/npcm_pspi.h" +#include "hw/usb/hcd-ehci.h" +#include "hw/usb/hcd-ohci.h" +#include "target/arm/cpu.h" +#include "hw/sd/npcm7xx_sdhci.h" + +#define NPCM7XX_MAX_NUM_CPUS (2) + +/* The first half of the address space is reserved for DDR4 DRAM. */ +#define NPCM7XX_DRAM_BA (0x00000000) +#define NPCM7XX_DRAM_SZ (2 * GiB) + +/* Magic addresses for setting up direct kernel booting and SMP boot stubs. */ +#define NPCM7XX_LOADER_START (0x00000000) /* Start of SDRAM */ +#define NPCM7XX_SMP_LOADER_START (0xffff0000) /* Boot ROM */ +#define NPCM7XX_SMP_BOOTREG_ADDR (0xf080013c) /* GCR.SCRPAD */ +#define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100) /* GIC within A9 */ +#define NPCM7XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */ + +#define NPCM7XX_NR_PWM_MODULES 2 + +struct NPCM7xxMachine { + MachineState parent; + /* + * PWM fan splitter. each splitter connects to one PWM output and + * multiple MFT inputs. + */ + SplitIRQ fan_splitter[NPCM7XX_NR_PWM_MODULES * + NPCM7XX_PWM_PER_MODULE]; +}; + +#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx") +OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxMachine, NPCM7XX_MACHINE) + +typedef struct NPCM7xxMachineClass { + MachineClass parent; + + const char *soc_type; +} NPCM7xxMachineClass; + +#define NPCM7XX_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(NPCM7xxMachineClass, (klass), TYPE_NPCM7XX_MACHINE) +#define NPCM7XX_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(NPCM7xxMachineClass, (obj), TYPE_NPCM7XX_MACHINE) + +struct NPCM7xxState { + DeviceState parent; + + ARMCPU cpu[NPCM7XX_MAX_NUM_CPUS]; + A9MPPrivState a9mpcore; + + MemoryRegion sram; + MemoryRegion irom; + MemoryRegion ram3; + MemoryRegion *dram; + + NPCM7xxGCRState gcr; + NPCM7xxCLKState clk; + NPCM7xxTimerCtrlState tim[3]; + NPCM7xxADCState adc; + NPCM7xxPWMState pwm[NPCM7XX_NR_PWM_MODULES]; + NPCM7xxMFTState mft[8]; + NPCM7xxOTPState key_storage; + NPCM7xxOTPState fuse_array; + NPCM7xxMCState mc; + NPCM7xxRNGState rng; + NPCM7xxGPIOState gpio[8]; + NPCM7xxSMBusState smbus[16]; + EHCISysBusState ehci; + OHCISysBusState ohci; + NPCM7xxFIUState fiu[2]; + NPCM7xxEMCState emc[2]; + NPCMGMACState gmac[2]; + NPCM7xxSDHCIState mmc; + NPCMPSPIState pspi[2]; +}; + +#define TYPE_NPCM7XX "npcm7xx" +OBJECT_DECLARE_TYPE(NPCM7xxState, NPCM7xxClass, NPCM7XX) + +#define TYPE_NPCM730 "npcm730" +#define TYPE_NPCM750 "npcm750" + +typedef struct NPCM7xxClass { + DeviceClass parent; + + /* Bitmask of modules that are permanently disabled on this chip. */ + uint32_t disabled_modules; + /* Number of CPU cores enabled in this SoC class (may be 1 or 2). */ + uint32_t num_cpus; +} NPCM7xxClass; + +/** + * npcm7xx_load_kernel - Loads memory with everything needed to boot + * @machine - The machine containing the SoC to be booted. + * @soc - The SoC containing the CPU to be booted. + * + * This will set up the ARM boot info structure for the specific NPCM7xx + * derivative and call arm_load_kernel() to set up loading of the kernel, etc. + * into memory, if requested by the user. + */ +void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc); + +#endif /* NPCM7XX_H */ diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h index 0cb78aafea..e52a56e75e 100644 --- a/include/hw/arm/nrf51_soc.h +++ b/include/hw/arm/nrf51_soc.h @@ -17,14 +17,15 @@ #include "hw/gpio/nrf51_gpio.h" #include "hw/nvram/nrf51_nvm.h" #include "hw/timer/nrf51_timer.h" +#include "hw/clock.h" +#include "qom/object.h" #define TYPE_NRF51_SOC "nrf51-soc" -#define NRF51_SOC(obj) \ - OBJECT_CHECK(NRF51State, (obj), TYPE_NRF51_SOC) +OBJECT_DECLARE_SIMPLE_TYPE(NRF51State, NRF51_SOC) #define NRF51_NUM_TIMERS 3 -typedef struct NRF51State { +struct NRF51State { /*< private >*/ SysBusDevice parent_obj; @@ -50,6 +51,7 @@ typedef struct NRF51State { MemoryRegion container; -} NRF51State; + Clock *sysclk; +}; #endif diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h index 6be386d0e2..40ee8ea9e5 100644 --- a/include/hw/arm/omap.h +++ b/include/hw/arm/omap.h @@ -24,6 +24,7 @@ #include "hw/input/tsc2xxx.h" #include "target/arm/cpu-qom.h" #include "qemu/log.h" +#include "qom/object.h" # define OMAP_EMIFS_BASE 0x00000000 # define OMAP2_Q0_BASE 0x00000000 @@ -69,10 +70,9 @@ void omap_clk_reparent(omap_clk clk, omap_clk parent); /* omap_intc.c */ #define TYPE_OMAP_INTC "common-omap-intc" -#define OMAP_INTC(obj) \ - OBJECT_CHECK(omap_intr_handler, (obj), TYPE_OMAP_INTC) +typedef struct OMAPIntcState OMAPIntcState; +DECLARE_INSTANCE_CHECKER(OMAPIntcState, OMAP_INTC, TYPE_OMAP_INTC) -typedef struct omap_intr_handler_s omap_intr_handler; /* * TODO: Ideally we should have a clock framework that @@ -88,14 +88,13 @@ typedef struct omap_intr_handler_s omap_intr_handler; * (ie the struct omap_mpu_state_s*) to do the clockname to pointer * translation.) */ -void omap_intc_set_iclk(omap_intr_handler *intc, omap_clk clk); -void omap_intc_set_fclk(omap_intr_handler *intc, omap_clk clk); +void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk); +void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk); /* omap_i2c.c */ #define TYPE_OMAP_I2C "omap_i2c" -#define OMAP_I2C(obj) OBJECT_CHECK(OMAPI2CState, (obj), TYPE_OMAP_I2C) +OBJECT_DECLARE_SIMPLE_TYPE(OMAPI2CState, OMAP_I2C) -typedef struct OMAPI2CState OMAPI2CState; /* TODO: clock framework (see above) */ void omap_i2c_set_iclk(OMAPI2CState *i2c, omap_clk clk); @@ -103,21 +102,20 @@ void omap_i2c_set_fclk(OMAPI2CState *i2c, omap_clk clk); /* omap_gpio.c */ #define TYPE_OMAP1_GPIO "omap-gpio" -#define OMAP1_GPIO(obj) \ - OBJECT_CHECK(struct omap_gpif_s, (obj), TYPE_OMAP1_GPIO) +typedef struct Omap1GpioState Omap1GpioState; +DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO, + TYPE_OMAP1_GPIO) #define TYPE_OMAP2_GPIO "omap2-gpio" -#define OMAP2_GPIO(obj) \ - OBJECT_CHECK(struct omap2_gpif_s, (obj), TYPE_OMAP2_GPIO) - -typedef struct omap_gpif_s omap_gpif; -typedef struct omap2_gpif_s omap2_gpif; +typedef struct Omap2GpioState Omap2GpioState; +DECLARE_INSTANCE_CHECKER(Omap2GpioState, OMAP2_GPIO, + TYPE_OMAP2_GPIO) /* TODO: clock framework (see above) */ -void omap_gpio_set_clk(omap_gpif *gpio, omap_clk clk); +void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk); -void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk); -void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk); +void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk); +void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk); /* OMAP2 l4 Interconnect */ struct omap_l4_s; @@ -726,7 +724,6 @@ struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem, qemu_irq txdma, qemu_irq rxdma, const char *label, Chardev *chr); void omap_uart_reset(struct omap_uart_s *s); -void omap_uart_attach(struct omap_uart_s *s, Chardev *chr); struct omap_mpuio_s; qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s); @@ -1011,7 +1008,8 @@ void omap_mpu_wakeup(void *opaque, int irq, int req); __func__, paddr) /* OMAP-specific Linux bootloader tags for the ATAG_BOARD area - (Board-specifc tags are not here) */ + * (Board-specific tags are not here) + */ #define OMAP_TAG_CLOCK 0x4f01 #define OMAP_TAG_MMC 0x4f02 #define OMAP_TAG_SERIAL_CONSOLE 0x4f03 diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h index 8843e5f910..4c6caee113 100644 --- a/include/hw/arm/pxa.h +++ b/include/hw/arm/pxa.h @@ -13,6 +13,7 @@ #include "exec/memory.h" #include "target/arm/cpu-qom.h" #include "hw/pcmcia.h" +#include "qom/object.h" /* Interrupt numbers */ # define PXA2XX_PIC_SSP3 0 @@ -86,18 +87,19 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem, void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler); /* pxa2xx_mmci.c */ -typedef struct PXA2xxMMCIState PXA2xxMMCIState; +#define TYPE_PXA2XX_MMCI "pxa2xx-mmci" +OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxMMCIState, PXA2XX_MMCI) + PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem, hwaddr base, - BlockBackend *blk, qemu_irq irq, - qemu_irq rx_dma, qemu_irq tx_dma); + qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma); void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly, qemu_irq coverswitch); /* pxa2xx_pcmcia.c */ -typedef struct PXA2xxPCMCIAState PXA2xxPCMCIAState; -PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem, - hwaddr base); +#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia" +OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA) + int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card); int pxa2xx_pcmcia_detach(void *opaque); void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq); @@ -115,13 +117,17 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, const struct keymap *map, int size); /* pxa2xx.c */ -typedef struct PXA2xxI2CState PXA2xxI2CState; +#define TYPE_PXA2XX_I2C "pxa2xx_i2c" +OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C) + PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base, qemu_irq irq, uint32_t page_size); I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s); typedef struct PXA2xxI2SState PXA2xxI2SState; -typedef struct PXA2xxFIrState PXA2xxFIrState; + +#define TYPE_PXA2XX_FIR "pxa2xx-fir" +OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxFIrState, PXA2XX_FIR) typedef struct { ARMCPU *cpu; @@ -185,8 +191,7 @@ struct PXA2xxI2SState { # define PA_FMT "0x%08lx" -PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size, - const char *revision); -PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size); +PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision); +PXA2xxState *pxa255_init(unsigned int sdram_size); #endif /* PXA_H */ diff --git a/include/hw/arm/raspberrypi-fw-defs.h b/include/hw/arm/raspberrypi-fw-defs.h new file mode 100644 index 0000000000..8b404e0533 --- /dev/null +++ b/include/hw/arm/raspberrypi-fw-defs.h @@ -0,0 +1,173 @@ +/* + * Raspberry Pi firmware definitions + * + * Copyright (C) 2022 Auriga LLC, based on Linux kernel + * `include/soc/bcm2835/raspberrypi-firmware.h` (Copyright © 2015 Broadcom) + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef INCLUDE_HW_MISC_RASPBERRYPI_FW_DEFS_H_ +#define INCLUDE_HW_MISC_RASPBERRYPI_FW_DEFS_H_ + + +enum rpi_firmware_property_tag { + RPI_FWREQ_PROPERTY_END = 0, + RPI_FWREQ_GET_FIRMWARE_REVISION = 0x00000001, + RPI_FWREQ_GET_FIRMWARE_VARIANT = 0x00000002, + RPI_FWREQ_GET_FIRMWARE_HASH = 0x00000003, + + RPI_FWREQ_SET_CURSOR_INFO = 0x00008010, + RPI_FWREQ_SET_CURSOR_STATE = 0x00008011, + + RPI_FWREQ_GET_BOARD_MODEL = 0x00010001, + RPI_FWREQ_GET_BOARD_REVISION = 0x00010002, + RPI_FWREQ_GET_BOARD_MAC_ADDRESS = 0x00010003, + RPI_FWREQ_GET_BOARD_SERIAL = 0x00010004, + RPI_FWREQ_GET_ARM_MEMORY = 0x00010005, + RPI_FWREQ_GET_VC_MEMORY = 0x00010006, + RPI_FWREQ_GET_CLOCKS = 0x00010007, + RPI_FWREQ_GET_POWER_STATE = 0x00020001, + RPI_FWREQ_GET_TIMING = 0x00020002, + RPI_FWREQ_SET_POWER_STATE = 0x00028001, + RPI_FWREQ_GET_CLOCK_STATE = 0x00030001, + RPI_FWREQ_GET_CLOCK_RATE = 0x00030002, + RPI_FWREQ_GET_VOLTAGE = 0x00030003, + RPI_FWREQ_GET_MAX_CLOCK_RATE = 0x00030004, + RPI_FWREQ_GET_MAX_VOLTAGE = 0x00030005, + RPI_FWREQ_GET_TEMPERATURE = 0x00030006, + RPI_FWREQ_GET_MIN_CLOCK_RATE = 0x00030007, + RPI_FWREQ_GET_MIN_VOLTAGE = 0x00030008, + RPI_FWREQ_GET_TURBO = 0x00030009, + RPI_FWREQ_GET_MAX_TEMPERATURE = 0x0003000a, + RPI_FWREQ_GET_STC = 0x0003000b, + RPI_FWREQ_ALLOCATE_MEMORY = 0x0003000c, + RPI_FWREQ_LOCK_MEMORY = 0x0003000d, + RPI_FWREQ_UNLOCK_MEMORY = 0x0003000e, + RPI_FWREQ_RELEASE_MEMORY = 0x0003000f, + RPI_FWREQ_EXECUTE_CODE = 0x00030010, + RPI_FWREQ_EXECUTE_QPU = 0x00030011, + RPI_FWREQ_SET_ENABLE_QPU = 0x00030012, + RPI_FWREQ_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, + RPI_FWREQ_GET_EDID_BLOCK = 0x00030020, + RPI_FWREQ_GET_CUSTOMER_OTP = 0x00030021, + RPI_FWREQ_GET_EDID_BLOCK_DISPLAY = 0x00030023, + RPI_FWREQ_GET_DOMAIN_STATE = 0x00030030, + RPI_FWREQ_GET_THROTTLED = 0x00030046, + RPI_FWREQ_GET_CLOCK_MEASURED = 0x00030047, + RPI_FWREQ_NOTIFY_REBOOT = 0x00030048, + RPI_FWREQ_SET_CLOCK_STATE = 0x00038001, + RPI_FWREQ_SET_CLOCK_RATE = 0x00038002, + RPI_FWREQ_SET_VOLTAGE = 0x00038003, + RPI_FWREQ_SET_MAX_CLOCK_RATE = 0x00038004, + RPI_FWREQ_SET_MIN_CLOCK_RATE = 0x00038007, + RPI_FWREQ_SET_TURBO = 0x00038009, + RPI_FWREQ_SET_CUSTOMER_OTP = 0x00038021, + RPI_FWREQ_SET_DOMAIN_STATE = 0x00038030, + RPI_FWREQ_GET_GPIO_STATE = 0x00030041, + RPI_FWREQ_SET_GPIO_STATE = 0x00038041, + RPI_FWREQ_SET_SDHOST_CLOCK = 0x00038042, + RPI_FWREQ_GET_GPIO_CONFIG = 0x00030043, + RPI_FWREQ_SET_GPIO_CONFIG = 0x00038043, + RPI_FWREQ_GET_PERIPH_REG = 0x00030045, + RPI_FWREQ_SET_PERIPH_REG = 0x00038045, + RPI_FWREQ_GET_POE_HAT_VAL = 0x00030049, + RPI_FWREQ_SET_POE_HAT_VAL = 0x00038049, + RPI_FWREQ_SET_POE_HAT_VAL_OLD = 0x00030050, + RPI_FWREQ_NOTIFY_XHCI_RESET = 0x00030058, + RPI_FWREQ_GET_REBOOT_FLAGS = 0x00030064, + RPI_FWREQ_SET_REBOOT_FLAGS = 0x00038064, + RPI_FWREQ_NOTIFY_DISPLAY_DONE = 0x00030066, + + /* Dispmanx TAGS */ + RPI_FWREQ_FRAMEBUFFER_ALLOCATE = 0x00040001, + RPI_FWREQ_FRAMEBUFFER_BLANK = 0x00040002, + RPI_FWREQ_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, + RPI_FWREQ_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, + RPI_FWREQ_FRAMEBUFFER_GET_DEPTH = 0x00040005, + RPI_FWREQ_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, + RPI_FWREQ_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, + RPI_FWREQ_FRAMEBUFFER_GET_PITCH = 0x00040008, + RPI_FWREQ_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, + RPI_FWREQ_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, + RPI_FWREQ_FRAMEBUFFER_GET_PALETTE = 0x0004000b, + RPI_FWREQ_FRAMEBUFFER_GET_LAYER = 0x0004000c, + RPI_FWREQ_FRAMEBUFFER_GET_TRANSFORM = 0x0004000d, + RPI_FWREQ_FRAMEBUFFER_GET_VSYNC = 0x0004000e, + RPI_FWREQ_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, + RPI_FWREQ_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, + RPI_FWREQ_FRAMEBUFFER_RELEASE = 0x00048001, + RPI_FWREQ_FRAMEBUFFER_GET_DISPLAY_ID = 0x00040016, + RPI_FWREQ_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013, + RPI_FWREQ_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013, + RPI_FWREQ_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014, + RPI_FWREQ_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, + RPI_FWREQ_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, + RPI_FWREQ_FRAMEBUFFER_TEST_DEPTH = 0x00044005, + RPI_FWREQ_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, + RPI_FWREQ_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, + RPI_FWREQ_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, + RPI_FWREQ_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, + RPI_FWREQ_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, + RPI_FWREQ_FRAMEBUFFER_TEST_LAYER = 0x0004400c, + RPI_FWREQ_FRAMEBUFFER_TEST_TRANSFORM = 0x0004400d, + RPI_FWREQ_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, + RPI_FWREQ_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, + RPI_FWREQ_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, + RPI_FWREQ_FRAMEBUFFER_SET_DEPTH = 0x00048005, + RPI_FWREQ_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, + RPI_FWREQ_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, + RPI_FWREQ_FRAMEBUFFER_SET_PITCH = 0x00048008, + RPI_FWREQ_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FWREQ_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FWREQ_FRAMEBUFFER_SET_PALETTE = 0x0004800b, + + RPI_FWREQ_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, + RPI_FWREQ_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, + RPI_FWREQ_FRAMEBUFFER_SET_VSYNC = 0x0004800e, + RPI_FWREQ_FRAMEBUFFER_SET_LAYER = 0x0004800c, + RPI_FWREQ_FRAMEBUFFER_SET_TRANSFORM = 0x0004800d, + RPI_FWREQ_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, + + RPI_FWREQ_VCHIQ_INIT = 0x00048010, + + RPI_FWREQ_SET_PLANE = 0x00048015, + RPI_FWREQ_GET_DISPLAY_TIMING = 0x00040017, + RPI_FWREQ_SET_TIMING = 0x00048017, + RPI_FWREQ_GET_DISPLAY_CFG = 0x00040018, + RPI_FWREQ_SET_DISPLAY_POWER = 0x00048019, + RPI_FWREQ_GET_COMMAND_LINE = 0x00050001, + RPI_FWREQ_GET_DMA_CHANNELS = 0x00060001, +}; + +enum rpi_firmware_clk_id { + RPI_FIRMWARE_EMMC_CLK_ID = 1, + RPI_FIRMWARE_UART_CLK_ID, + RPI_FIRMWARE_ARM_CLK_ID, + RPI_FIRMWARE_CORE_CLK_ID, + RPI_FIRMWARE_V3D_CLK_ID, + RPI_FIRMWARE_H264_CLK_ID, + RPI_FIRMWARE_ISP_CLK_ID, + RPI_FIRMWARE_SDRAM_CLK_ID, + RPI_FIRMWARE_PIXEL_CLK_ID, + RPI_FIRMWARE_PWM_CLK_ID, + RPI_FIRMWARE_HEVC_CLK_ID, + RPI_FIRMWARE_EMMC2_CLK_ID, + RPI_FIRMWARE_M2MC_CLK_ID, + RPI_FIRMWARE_PIXEL_BVB_CLK_ID, + RPI_FIRMWARE_VEC_CLK_ID, + RPI_FIRMWARE_NUM_CLK_ID, +}; + +struct rpi_firmware_property_tag_header { + uint32_t tag; + uint32_t buf_size; + uint32_t req_resp_size; +}; + +typedef struct rpi_firmware_prop_request { + struct rpi_firmware_property_tag_header hdr; + uint8_t payload[0]; +} rpi_firmware_prop_request_t; + +#endif /* INCLUDE_HW_MISC_RASPBERRYPI_FW_DEFS_H_ */ diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h index 61b04a1bd4..7bc4807fa5 100644 --- a/include/hw/arm/raspi_platform.h +++ b/include/hw/arm/raspi_platform.h @@ -18,48 +18,117 @@ * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * Various undocumented addresses and names come from Herman Hermitage's VC4 + * documentation: + * https://github.com/hermanhermitage/videocoreiv/wiki/MMIO-Register-map */ #ifndef HW_ARM_RASPI_PLATFORM_H #define HW_ARM_RASPI_PLATFORM_H +#include "hw/boards.h" +#include "hw/arm/boot.h" + +/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */ +#define MACH_TYPE_BCM2708 3138 + +#define TYPE_RASPI_BASE_MACHINE MACHINE_TYPE_NAME("raspi-base") +OBJECT_DECLARE_TYPE(RaspiBaseMachineState, RaspiBaseMachineClass, + RASPI_BASE_MACHINE) + +struct RaspiBaseMachineState { + /*< private >*/ + MachineState parent_obj; + /*< public >*/ + struct arm_boot_info binfo; +}; + +struct RaspiBaseMachineClass { + /*< private >*/ + MachineClass parent_obj; + /*< public >*/ + uint32_t board_rev; +}; + +/* Common functions for raspberry pi machines */ +const char *board_soc_type(uint32_t board_rev); +void raspi_machine_init(MachineState *machine); + +typedef struct BCM283XBaseState BCM283XBaseState; +void raspi_base_machine_init(MachineState *machine, + BCM283XBaseState *soc); + +void raspi_machine_class_common_init(MachineClass *mc, + uint32_t board_rev); +uint64_t board_ram_size(uint32_t board_rev); + #define MSYNC_OFFSET 0x0000 /* Multicore Sync Block */ -#define IC0_OFFSET 0x2000 +#define CCPT_OFFSET 0x1000 /* Compact Camera Port 2 TX */ +#define INTE_OFFSET 0x2000 /* VC Interrupt controller */ #define ST_OFFSET 0x3000 /* System Timer */ +#define TXP_OFFSET 0x4000 /* Transposer */ +#define JPEG_OFFSET 0x5000 #define MPHI_OFFSET 0x6000 /* Message-based Parallel Host Intf. */ #define DMA_OFFSET 0x7000 /* DMA controller, channels 0-14 */ -#define ARM_OFFSET 0xB000 /* BCM2708 ARM control block */ +#define ARBA_OFFSET 0x9000 +#define BRDG_OFFSET 0xa000 /* RPiVid ASB for BCM2838 (BCM2711) */ +#define ARM_OFFSET 0xB000 /* ARM control block */ #define ARMCTRL_OFFSET (ARM_OFFSET + 0x000) #define ARMCTRL_IC_OFFSET (ARM_OFFSET + 0x200) /* Interrupt controller */ -#define ARMCTRL_TIMER0_1_OFFSET (ARM_OFFSET + 0x400) /* Timer 0 and 1 */ +#define ARMCTRL_TIMER0_1_OFFSET (ARM_OFFSET + 0x400) /* Timer 0 and 1 (SP804) */ #define ARMCTRL_0_SBM_OFFSET (ARM_OFFSET + 0x800) /* User 0 (ARM) Semaphores * Doorbells & Mailboxes */ -#define CPRMAN_OFFSET 0x100000 /* Power Management, Watchdog */ -#define CM_OFFSET 0x101000 /* Clock Management */ -#define A2W_OFFSET 0x102000 /* Reset controller */ +#define PM_OFFSET 0x100000 /* Power Management */ +#define CPRMAN_OFFSET 0x101000 /* Clock Management */ #define AVS_OFFSET 0x103000 /* Audio Video Standard */ #define RNG_OFFSET 0x104000 #define GPIO_OFFSET 0x200000 -#define UART0_OFFSET 0x201000 -#define MMCI0_OFFSET 0x202000 -#define I2S_OFFSET 0x203000 -#define SPI0_OFFSET 0x204000 +#define UART0_OFFSET 0x201000 /* PL011 */ +#define MMCI0_OFFSET 0x202000 /* Legacy MMC */ +#define I2S_OFFSET 0x203000 /* PCM */ +#define SPI0_OFFSET 0x204000 /* SPI master */ #define BSC0_OFFSET 0x205000 /* BSC0 I2C/TWI */ +#define PIXV0_OFFSET 0x206000 +#define PIXV1_OFFSET 0x207000 +#define DPI_OFFSET 0x208000 +#define DSI0_OFFSET 0x209000 /* Display Serial Interface */ +#define PWM_OFFSET 0x20c000 +#define PERM_OFFSET 0x20d000 +#define TEC_OFFSET 0x20e000 #define OTP_OFFSET 0x20f000 +#define SLIM_OFFSET 0x210000 /* SLIMbus */ +#define CPG_OFFSET 0x211000 #define THERMAL_OFFSET 0x212000 -#define BSC_SL_OFFSET 0x214000 /* SPI slave */ +#define AVSP_OFFSET 0x213000 +#define BSC_SL_OFFSET 0x214000 /* SPI slave (bootrom) */ #define AUX_OFFSET 0x215000 /* AUX: UART1/SPI1/SPI2 */ #define EMMC1_OFFSET 0x300000 +#define EMMC2_OFFSET 0x340000 +#define HVS_OFFSET 0x400000 #define SMI_OFFSET 0x600000 +#define DSI1_OFFSET 0x700000 +#define UCAM_OFFSET 0x800000 +#define CMI_OFFSET 0x802000 #define BSC1_OFFSET 0x804000 /* BSC1 I2C/TWI */ #define BSC2_OFFSET 0x805000 /* BSC2 I2C/TWI */ +#define VECA_OFFSET 0x806000 +#define PIXV2_OFFSET 0x807000 +#define HDMI_OFFSET 0x808000 +#define HDCP_OFFSET 0x809000 +#define ARBR0_OFFSET 0x80a000 #define DBUS_OFFSET 0x900000 #define AVE0_OFFSET 0x910000 #define USB_OTG_OFFSET 0x980000 /* DTC_OTG USB controller */ +#define V3D_OFFSET 0xc00000 #define SDRAMC_OFFSET 0xe00000 +#define L2CC_OFFSET 0xe01000 /* Level 2 Cache controller */ +#define L1CC_OFFSET 0xe02000 /* Level 1 Cache controller */ +#define ARBR1_OFFSET 0xe04000 #define DMA15_OFFSET 0xE05000 /* DMA controller, channel 15 */ +#define DCRC_OFFSET 0xe07000 +#define AXIP_OFFSET 0xe08000 /* GPU interrupts */ #define INTERRUPT_TIMER0 0 @@ -137,4 +206,14 @@ #define INTERRUPT_ILLEGAL_TYPE0 6 #define INTERRUPT_ILLEGAL_TYPE1 7 +/* Clock rates */ +#define RPI_FIRMWARE_EMMC_CLK_RATE 50000000 +#define RPI_FIRMWARE_UART_CLK_RATE 3000000 +/* + * TODO: this is really SoC-specific; we might want to + * set it per-SoC if it turns out any guests care. + */ +#define RPI_FIRMWARE_CORE_CLK_RATE 350000000 +#define RPI_FIRMWARE_DEFAULT_CLK_RATE 700000000 + #endif diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index ca4a4b1ad1..5ec2e6c1a4 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -21,12 +21,21 @@ #include "hw/sysbus.h" #include "hw/pci/pci.h" +#include "qom/object.h" -#define SMMU_PCI_BUS_MAX 256 -#define SMMU_PCI_DEVFN_MAX 256 -#define SMMU_PCI_DEVFN(sid) (sid & 0xFF) +#define SMMU_PCI_BUS_MAX 256 +#define SMMU_PCI_DEVFN_MAX 256 +#define SMMU_PCI_DEVFN(sid) (sid & 0xFF) -#define SMMU_MAX_VA_BITS 48 +/* VMSAv8-64 Translation constants and functions */ +#define VMSA_LEVELS 4 +#define VMSA_MAX_S2_CONCAT 16 + +#define VMSA_STRIDE(gran) ((gran) - VMSA_LEVELS + 1) +#define VMSA_BIT_LVL(isz, strd, lvl) ((isz) - (strd) * \ + (VMSA_LEVELS - (lvl))) +#define VMSA_IDXMSK(isz, strd, lvl) ((1ULL << \ + VMSA_BIT_LVL(isz, strd, lvl)) - 1) /* * Page table walk error types @@ -41,6 +50,7 @@ typedef enum { } SMMUPTWEventType; typedef struct SMMUPTWEventInfo { + int stage; SMMUPTWEventType type; dma_addr_t addr; /* fetched address that induced an abort, if any */ } SMMUPTWEventInfo; @@ -50,26 +60,51 @@ typedef struct SMMUTransTableInfo { uint64_t ttb; /* TT base address */ uint8_t tsz; /* input range, ie. 2^(64 -tsz)*/ uint8_t granule_sz; /* granule page shift */ + bool had; /* hierarchical attribute disable */ } SMMUTransTableInfo; +typedef struct SMMUTLBEntry { + IOMMUTLBEntry entry; + uint8_t level; + uint8_t granule; +} SMMUTLBEntry; + +/* Stage-2 configuration. */ +typedef struct SMMUS2Cfg { + uint8_t tsz; /* Size of IPA input region (S2T0SZ) */ + uint8_t sl0; /* Start level of translation (S2SL0) */ + bool affd; /* AF Fault Disable (S2AFFD) */ + bool record_faults; /* Record fault events (S2R) */ + uint8_t granule_sz; /* Granule page shift (based on S2TG) */ + uint8_t eff_ps; /* Effective PA output range (based on S2PS) */ + uint16_t vmid; /* Virtual Machine ID (S2VMID) */ + uint64_t vttb; /* Address of translation table base (S2TTB) */ +} SMMUS2Cfg; + /* * Generic structure populated by derived SMMU devices * after decoding the configuration information and used as * input to the page table walk */ typedef struct SMMUTransCfg { + /* Shared fields between stage-1 and stage-2. */ int stage; /* translation stage */ - bool aa64; /* arch64 or aarch32 translation table */ bool disabled; /* smmu is disabled */ bool bypassed; /* translation is bypassed */ bool aborted; /* translation is aborted */ + bool affd; /* AF fault disable */ + uint32_t iotlb_hits; /* counts IOTLB hits */ + uint32_t iotlb_misses; /* counts IOTLB misses*/ + /* Used by stage-1 only. */ + bool aa64; /* arch64 or aarch32 translation table */ + bool record_faults; /* record fault events */ uint64_t ttb; /* TT base address */ uint8_t oas; /* output address width */ uint8_t tbi; /* Top Byte Ignore */ uint16_t asid; SMMUTransTableInfo tt[2]; - uint32_t iotlb_hits; /* counts IOTLB hits for this asid */ - uint32_t iotlb_misses; /* counts IOTLB misses for this asid */ + /* Used by stage-2 only. */ + struct SMMUS2Cfg s2cfg; } SMMUTransCfg; typedef struct SMMUDevice { @@ -91,9 +126,12 @@ typedef struct SMMUPciBus { typedef struct SMMUIOTLBKey { uint64_t iova; uint16_t asid; + uint16_t vmid; + uint8_t tg; + uint8_t level; } SMMUIOTLBKey; -typedef struct SMMUState { +struct SMMUState { /* <private> */ SysBusDevice dev; const char *mrtypename; @@ -107,9 +145,9 @@ typedef struct SMMUState { QLIST_HEAD(, SMMUDevice) devices_with_notifiers; uint8_t bus_num; PCIBus *primary_bus; -} SMMUState; +}; -typedef struct { +struct SMMUBaseClass { /* <private> */ SysBusDeviceClass parent_class; @@ -117,14 +155,10 @@ typedef struct { DeviceRealize parent_realize; -} SMMUBaseClass; +}; #define TYPE_ARM_SMMU "arm-smmu" -#define ARM_SMMU(obj) OBJECT_CHECK(SMMUState, (obj), TYPE_ARM_SMMU) -#define ARM_SMMU_CLASS(klass) \ - OBJECT_CLASS_CHECK(SMMUBaseClass, (klass), TYPE_ARM_SMMU) -#define ARM_SMMU_GET_CLASS(obj) \ - OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU) +OBJECT_DECLARE_TYPE(SMMUState, SMMUBaseClass, ARM_SMMU) /* Return the SMMUPciBus handle associated to a PCI bus number */ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num); @@ -140,7 +174,7 @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev) * pair, according to @cfg translation config */ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm, - IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info); + SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info); /** * select_tt - compute which translation table shall be used according to @@ -153,14 +187,18 @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid); #define SMMU_IOTLB_MAX_SIZE 256 +SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg, + SMMUTransTableInfo *tt, hwaddr iova); +void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *entry); +SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova, + uint8_t tg, uint8_t level); void smmu_iotlb_inv_all(SMMUState *s); void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid); -void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova); +void smmu_iotlb_inv_vmid(SMMUState *s, uint16_t vmid); +void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, + uint8_t tg, uint64_t num_pages, uint8_t ttl); /* Unmap the range of all the notifiers registered to any IOMMU mr */ void smmu_inv_notifiers_all(SMMUState *s); -/* Unmap the range of all the notifiers registered to @mr */ -void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr); - #endif /* HW_ARM_SMMU_COMMON_H */ diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index 36b2f45253..d183a62766 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -20,7 +20,7 @@ #define HW_ARM_SMMUV3_H #include "hw/arm/smmu-common.h" -#include "hw/registerfields.h" +#include "qom/object.h" #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region" @@ -32,7 +32,7 @@ typedef struct SMMUQueue { uint8_t log2size; } SMMUQueue; -typedef struct SMMUv3State { +struct SMMUv3State { SMMUState smmu_state; uint32_t features; @@ -41,9 +41,11 @@ typedef struct SMMUv3State { uint32_t idr[6]; uint32_t iidr; + uint32_t aidr; uint32_t cr[3]; uint32_t cr0ack; uint32_t statusr; + uint32_t gbpa; uint32_t irq_ctrl; uint32_t gerror; uint32_t gerrorn; @@ -60,7 +62,8 @@ typedef struct SMMUv3State { qemu_irq irq[4]; QemuMutex mutex; -} SMMUv3State; + char *stage; +}; typedef enum { SMMU_IRQ_EVTQ, @@ -69,20 +72,19 @@ typedef enum { SMMU_IRQ_GERROR, } SMMUIrq; -typedef struct { +struct SMMUv3Class { /*< private >*/ SMMUBaseClass smmu_base_class; /*< public >*/ DeviceRealize parent_realize; - DeviceReset parent_reset; -} SMMUv3Class; + ResettablePhases parent_phases; +}; #define TYPE_ARM_SMMUV3 "arm-smmuv3" -#define ARM_SMMUV3(obj) OBJECT_CHECK(SMMUv3State, (obj), TYPE_ARM_SMMUV3) -#define ARM_SMMUV3_CLASS(klass) \ - OBJECT_CLASS_CHECK(SMMUv3Class, (klass), TYPE_ARM_SMMUV3) -#define ARM_SMMUV3_GET_CLASS(obj) \ - OBJECT_GET_CLASS(SMMUv3Class, (obj), TYPE_ARM_SMMUV3) +OBJECT_DECLARE_TYPE(SMMUv3State, SMMUv3Class, ARM_SMMUV3) + +#define STAGE1_SUPPORTED(s) FIELD_EX32(s->idr[0], IDR0, S1P) +#define STAGE2_SUPPORTED(s) FIELD_EX32(s->idr[0], IDR0, S2P) #endif diff --git a/include/hw/arm/stm32f100_soc.h b/include/hw/arm/stm32f100_soc.h new file mode 100644 index 0000000000..a74d7b369c --- /dev/null +++ b/include/hw/arm/stm32f100_soc.h @@ -0,0 +1,61 @@ +/* + * STM32F100 SoC + * + * Copyright (c) 2021 Alexandre Iooss <erdnaxe@crans.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef HW_ARM_STM32F100_SOC_H +#define HW_ARM_STM32F100_SOC_H + +#include "hw/char/stm32f2xx_usart.h" +#include "hw/ssi/stm32f2xx_spi.h" +#include "hw/arm/armv7m.h" +#include "qom/object.h" +#include "hw/clock.h" + +#define TYPE_STM32F100_SOC "stm32f100-soc" +OBJECT_DECLARE_SIMPLE_TYPE(STM32F100State, STM32F100_SOC) + +#define STM_NUM_USARTS 3 +#define STM_NUM_SPIS 2 + +#define FLASH_BASE_ADDRESS 0x08000000 +#define FLASH_SIZE (128 * 1024) +#define SRAM_BASE_ADDRESS 0x20000000 +#define SRAM_SIZE (8 * 1024) + +struct STM32F100State { + SysBusDevice parent_obj; + + ARMv7MState armv7m; + + STM32F2XXUsartState usart[STM_NUM_USARTS]; + STM32F2XXSPIState spi[STM_NUM_SPIS]; + + MemoryRegion sram; + MemoryRegion flash; + MemoryRegion flash_alias; + + Clock *sysclk; + Clock *refclk; +}; + +#endif diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h index 922a733f88..4f4c8bbebc 100644 --- a/include/hw/arm/stm32f205_soc.h +++ b/include/hw/arm/stm32f205_soc.h @@ -32,10 +32,11 @@ #include "hw/or-irq.h" #include "hw/ssi/stm32f2xx_spi.h" #include "hw/arm/armv7m.h" +#include "hw/clock.h" +#include "qom/object.h" #define TYPE_STM32F205_SOC "stm32f205-soc" -#define STM32F205_SOC(obj) \ - OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC) +OBJECT_DECLARE_SIMPLE_TYPE(STM32F205State, STM32F205_SOC) #define STM_NUM_USARTS 6 #define STM_NUM_TIMERS 4 @@ -47,12 +48,8 @@ #define SRAM_BASE_ADDRESS 0x20000000 #define SRAM_SIZE (128 * 1024) -typedef struct STM32F205State { - /*< private >*/ +struct STM32F205State { SysBusDevice parent_obj; - /*< public >*/ - - char *cpu_type; ARMv7MState armv7m; @@ -62,7 +59,14 @@ typedef struct STM32F205State { STM32F2XXADCState adc[STM_NUM_ADCS]; STM32F2XXSPIState spi[STM_NUM_SPIS]; - qemu_or_irq *adc_irqs; -} STM32F205State; + OrIRQState *adc_irqs; + + MemoryRegion sram; + MemoryRegion flash; + MemoryRegion flash_alias; + + Clock *sysclk; + Clock *refclk; +}; #endif diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h index 1fe97f8c3a..d15c03c4b5 100644 --- a/include/hw/arm/stm32f405_soc.h +++ b/include/hw/arm/stm32f405_soc.h @@ -33,10 +33,10 @@ #include "hw/or-irq.h" #include "hw/ssi/stm32f2xx_spi.h" #include "hw/arm/armv7m.h" +#include "qom/object.h" #define TYPE_STM32F405_SOC "stm32f405-soc" -#define STM32F405_SOC(obj) \ - OBJECT_CHECK(STM32F405State, (obj), TYPE_STM32F405_SOC) +OBJECT_DECLARE_SIMPLE_TYPE(STM32F405State, STM32F405_SOC) #define STM_NUM_USARTS 7 #define STM_NUM_TIMERS 4 @@ -46,14 +46,12 @@ #define FLASH_BASE_ADDRESS 0x08000000 #define FLASH_SIZE (1024 * 1024) #define SRAM_BASE_ADDRESS 0x20000000 -#define SRAM_SIZE (192 * 1024) +#define SRAM_SIZE (128 * 1024) +#define CCM_BASE_ADDRESS 0x10000000 +#define CCM_SIZE (64 * 1024) -typedef struct STM32F405State { - /*< private >*/ +struct STM32F405State { SysBusDevice parent_obj; - /*< public >*/ - - char *cpu_type; ARMv7MState armv7m; @@ -61,13 +59,17 @@ typedef struct STM32F405State { STM32F4xxExtiState exti; STM32F2XXUsartState usart[STM_NUM_USARTS]; STM32F2XXTimerState timer[STM_NUM_TIMERS]; - qemu_or_irq adc_irqs; + OrIRQState adc_irqs; STM32F2XXADCState adc[STM_NUM_ADCS]; STM32F2XXSPIState spi[STM_NUM_SPIS]; + MemoryRegion ccm; MemoryRegion sram; MemoryRegion flash; MemoryRegion flash_alias; -} STM32F405State; + + Clock *sysclk; + Clock *refclk; +}; #endif diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h new file mode 100644 index 0000000000..ee5f362405 --- /dev/null +++ b/include/hw/arm/stm32l4x5_soc.h @@ -0,0 +1,67 @@ +/* + * STM32L4x5 SoC family + * + * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr> + * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr> + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This work is heavily inspired by the stm32f405_soc by Alistair Francis. + * Original code is licensed under the MIT License: + * + * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> + */ + +/* + * The reference used is the STMicroElectronics RM0351 Reference manual + * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs. + * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html + */ + +#ifndef HW_ARM_STM32L4x5_SOC_H +#define HW_ARM_STM32L4x5_SOC_H + +#include "exec/memory.h" +#include "hw/arm/armv7m.h" +#include "hw/or-irq.h" +#include "hw/misc/stm32l4x5_syscfg.h" +#include "hw/misc/stm32l4x5_exti.h" +#include "hw/misc/stm32l4x5_rcc.h" +#include "hw/gpio/stm32l4x5_gpio.h" +#include "qom/object.h" + +#define TYPE_STM32L4X5_SOC "stm32l4x5-soc" +#define TYPE_STM32L4X5XC_SOC "stm32l4x5xc-soc" +#define TYPE_STM32L4X5XE_SOC "stm32l4x5xe-soc" +#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc" +OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC) + +#define NUM_EXTI_OR_GATES 4 + +struct Stm32l4x5SocState { + SysBusDevice parent_obj; + + ARMv7MState armv7m; + + Stm32l4x5ExtiState exti; + OrIRQState exti_or_gates[NUM_EXTI_OR_GATES]; + Stm32l4x5SyscfgState syscfg; + Stm32l4x5RccState rcc; + Stm32l4x5GpioState gpio[NUM_GPIOS]; + + MemoryRegion sram1; + MemoryRegion sram2; + MemoryRegion flash; + MemoryRegion flash_alias; +}; + +struct Stm32l4x5SocClass { + SysBusDeviceClass parent_class; + + size_t flash_size; +}; + +#endif diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index dff67e1bef..bb486d36b1 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -34,24 +34,18 @@ #include "qemu/notify.h" #include "hw/boards.h" #include "hw/arm/boot.h" +#include "hw/arm/bsa.h" #include "hw/block/flash.h" #include "sysemu/kvm.h" #include "hw/intc/arm_gicv3_common.h" +#include "qom/object.h" #define NUM_GICV2M_SPIS 64 #define NUM_VIRTIO_TRANSPORTS 32 #define NUM_SMMU_IRQS 4 -#define ARCH_GIC_MAINT_IRQ 9 - -#define ARCH_TIMER_VIRT_IRQ 11 -#define ARCH_TIMER_S_EL1_IRQ 13 -#define ARCH_TIMER_NS_EL1_IRQ 14 -#define ARCH_TIMER_NS_EL2_IRQ 10 - -#define VIRTUAL_PMU_IRQ 7 - -#define PPI(irq) ((irq) + 16) +/* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */ +#define PVTIME_SIZE_PER_CPU 64 enum { VIRT_FLASH, @@ -77,9 +71,11 @@ enum { VIRT_GPIO, VIRT_SECURE_UART, VIRT_SECURE_MEM, + VIRT_SECURE_GPIO, VIRT_PCDIMM_ACPI, VIRT_ACPI_GED, VIRT_NVDIMM_ACPI, + VIRT_PVTIME, VIRT_LOWMEMMAP_LAST, }; @@ -103,32 +99,41 @@ typedef enum VirtMSIControllerType { } VirtMSIControllerType; typedef enum VirtGICType { - VIRT_GIC_VERSION_MAX, - VIRT_GIC_VERSION_HOST, - VIRT_GIC_VERSION_2, - VIRT_GIC_VERSION_3, + VIRT_GIC_VERSION_MAX = 0, + VIRT_GIC_VERSION_HOST = 1, + /* The concrete GIC values have to match the GIC version number */ + VIRT_GIC_VERSION_2 = 2, + VIRT_GIC_VERSION_3 = 3, + VIRT_GIC_VERSION_4 = 4, VIRT_GIC_VERSION_NOSEL, } VirtGICType; -typedef struct MemMapEntry { - hwaddr base; - hwaddr size; -} MemMapEntry; +#define VIRT_GIC_VERSION_2_MASK BIT(VIRT_GIC_VERSION_2) +#define VIRT_GIC_VERSION_3_MASK BIT(VIRT_GIC_VERSION_3) +#define VIRT_GIC_VERSION_4_MASK BIT(VIRT_GIC_VERSION_4) -typedef struct { +struct VirtMachineClass { MachineClass parent; bool disallow_affinity_adjustment; bool no_its; + bool no_tcg_its; bool no_pmu; bool claim_edge_triggered_timers; bool smbios_old_sys_ver; + bool no_highmem_compact; bool no_highmem_ecam; - bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */ + bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */ bool kvm_no_adjvtime; + bool no_kvm_steal_time; bool acpi_expose_flash; -} VirtMachineClass; + bool no_secure_gpio; + /* Machines < 6.2 have no support for describing cpu topology to guest */ + bool no_cpu_topology; + bool no_tcg_lpa2; + bool no_ns_el2_virt_timer_irq; +}; -typedef struct { +struct VirtMachineState { MachineState parent; Notifier machine_done; DeviceState *platform_bus_dev; @@ -136,22 +141,26 @@ typedef struct { PFlashCFI01 *flash[2]; bool secure; bool highmem; + bool highmem_compact; bool highmem_ecam; + bool highmem_mmio; + bool highmem_redists; bool its; + bool tcg_its; bool virt; bool ras; bool mte; + bool dtb_randomness; OnOffAuto acpi; VirtGICType gic_version; VirtIOMMUType iommu; + bool default_bus_bypass_iommu; VirtMSIControllerType msi_controller; uint16_t virtio_iommu_bdf; struct arm_boot_info bootinfo; MemMapEntry *memmap; char *pciehb_nodename; const int *irqmap; - int smp_cpus; - void *fdt; int fdt_size; uint32_t clock_phandle; uint32_t gic_phandle; @@ -162,30 +171,42 @@ typedef struct { DeviceState *gic; DeviceState *acpi_dev; Notifier powerdown_notifier; -} VirtMachineState; + PCIBus *bus; + char *oem_id; + char *oem_table_id; + bool ns_el2_virt_timer_irq; +}; #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") -#define VIRT_MACHINE(obj) \ - OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE) -#define VIRT_MACHINE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_VIRT_MACHINE) -#define VIRT_MACHINE_CLASS(klass) \ - OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE) +OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) void virt_acpi_setup(VirtMachineState *vms); bool virt_is_acpi_enabled(VirtMachineState *vms); +/* Return number of redistributors that fit in the specified region */ +static uint32_t virt_redist_capacity(VirtMachineState *vms, int region) +{ + uint32_t redist_size; + + if (vms->gic_version == VIRT_GIC_VERSION_3) { + redist_size = GICV3_REDIST_SIZE; + } else { + redist_size = GICV4_REDIST_SIZE; + } + return vms->memmap[region].size / redist_size; +} + /* Return the number of used redistributor regions */ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms) { - uint32_t redist0_capacity = - vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE; + uint32_t redist0_capacity = virt_redist_capacity(vms, VIRT_GIC_REDIST); - assert(vms->gic_version == VIRT_GIC_VERSION_3); + assert(vms->gic_version != VIRT_GIC_VERSION_2); - return vms->smp_cpus > redist0_capacity ? 2 : 1; + return (MACHINE(vms)->smp.cpus > redist0_capacity && + vms->highmem_redists) ? 2 : 1; } #endif /* QEMU_ARM_VIRT_H */ diff --git a/include/hw/arm/xen_arch_hvm.h b/include/hw/arm/xen_arch_hvm.h new file mode 100644 index 0000000000..8fd645e723 --- /dev/null +++ b/include/hw/arm/xen_arch_hvm.h @@ -0,0 +1,9 @@ +#ifndef HW_XEN_ARCH_ARM_HVM_H +#define HW_XEN_ARCH_ARM_HVM_H + +#include <xen/hvm/ioreq.h> +void arch_handle_ioreq(XenIOState *state, ioreq_t *req); +void arch_xen_set_memory(XenIOState *state, + MemoryRegionSection *section, + bool add); +#endif diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 9c9f47ba9d..025beb5532 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -13,25 +13,45 @@ #define XLNX_VERSAL_H #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" #include "hw/char/pl011.h" #include "hw/dma/xlnx-zdma.h" #include "hw/net/cadence_gem.h" #include "hw/rtc/xlnx-zynqmp-rtc.h" +#include "qom/object.h" +#include "hw/usb/xlnx-usb-subsystem.h" +#include "hw/misc/xlnx-versal-xramc.h" +#include "hw/nvram/xlnx-bbram.h" +#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" +#include "hw/misc/xlnx-versal-trng.h" +#include "hw/net/xlnx-versal-canfd.h" +#include "hw/misc/xlnx-versal-cfu.h" +#include "hw/misc/xlnx-versal-cframe-reg.h" +#include "target/arm/cpu.h" #define TYPE_XLNX_VERSAL "xlnx-versal" -#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL) +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 #define XLNX_VERSAL_NR_SDS 2 +#define XLNX_VERSAL_NR_XRAM 4 #define XLNX_VERSAL_NR_IRQS 192 +#define XLNX_VERSAL_NR_CANFD 2 +#define XLNX_VERSAL_CANFD_REF_CLK (24 * 1000 * 1000) +#define XLNX_VERSAL_NR_CFRAME 15 -typedef struct Versal { +struct Versal { /*< private >*/ SysBusDevice parent_obj; @@ -39,6 +59,7 @@ typedef struct Versal { struct { struct { MemoryRegion mr; + CPUClusterState cluster; ARMCPU cpu[XLNX_VERSAL_NR_ACPUS]; GICv3State gic; } apu; @@ -58,23 +79,62 @@ typedef struct Versal { PL011State uart[XLNX_VERSAL_NR_UARTS]; CadenceGEMState gem[XLNX_VERSAL_NR_GEMS]; XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS]; + VersalUsb2 usb; + CanBusState *canbus[XLNX_VERSAL_NR_CANFD]; + XlnxVersalCANFDState canfd[XLNX_VERSAL_NR_CANFD]; } iou; + + /* Real-time Processing Unit. */ + struct { + MemoryRegion mr; + MemoryRegion mr_ps_alias; + + CPUClusterState cluster; + ARMCPU cpu[XLNX_VERSAL_NR_RCPUS]; + } rpu; + + struct { + OrIRQState irq_orgate; + XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM]; + } xram; + + XlnxVersalCRL crl; } lpd; /* The Platform Management Controller subsystem. */ struct { struct { SDHCIState sd[XLNX_VERSAL_NR_SDS]; + XlnxVersalPmcIouSlcr slcr; + + struct { + XlnxVersalOspi ospi; + XlnxCSUDMA dma_src; + XlnxCSUDMA dma_dst; + MemoryRegion linear_mr; + OrIRQState irq_orgate; + } ospi; } iou; XlnxZynqMPRTC rtc; + XlnxVersalTRng trng; + XlnxBBRam bbram; + XlnxEFuse efuse; + XlnxVersalEFuseCtrl efuse_ctrl; + XlnxVersalEFuseCache efuse_cache; + XlnxVersalCFUAPB cfu_apb; + XlnxVersalCFUFDRO cfu_fdro; + XlnxVersalCFUSFR cfu_sfr; + XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME]; + XlnxVersalCFrameBcastReg cframe_bcast; + + OrIRQState apb_irq_orgate; } pmc; struct { MemoryRegion *mr_ddr; - uint32_t psci_conduit; } cfg; -} Versal; +}; /* Memory-map and IRQ definitions. Copied a subset from * auto-generated files. */ @@ -85,15 +145,24 @@ typedef 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_CANFD0_IRQ_0 20 +#define VERSAL_CANFD1_IRQ_0 21 +#define VERSAL_USB0_IRQ_0 22 #define VERSAL_GEM0_IRQ_0 56 #define VERSAL_GEM0_WAKE_IRQ_0 57 #define VERSAL_GEM1_IRQ_0 58 #define VERSAL_GEM1_WAKE_IRQ_0 59 #define VERSAL_ADMA_IRQ_0 60 -#define VERSAL_RTC_APB_ERR_IRQ 121 +#define VERSAL_XRAM_IRQ_0 79 +#define VERSAL_CFU_IRQ_0 120 +#define VERSAL_PMC_APB_IRQ 121 +#define VERSAL_OSPI_IRQ 124 #define VERSAL_SD0_IRQ_0 126 +#define VERSAL_EFUSE_IRQ 139 +#define VERSAL_TRNG_IRQ 141 #define VERSAL_RTC_ALARM_IRQ 142 #define VERSAL_RTC_SECONDS_IRQ 143 @@ -113,6 +182,11 @@ typedef struct Versal { #define MM_UART1 0xff010000U #define MM_UART1_SIZE 0x10000 +#define MM_CANFD0 0xff060000U +#define MM_CANFD0_SIZE 0x10000 +#define MM_CANFD1 0xff070000U +#define MM_CANFD1_SIZE 0x10000 + #define MM_GEM0 0xff0c0000U #define MM_GEM0_SIZE 0x10000 #define MM_GEM1 0xff0d0000U @@ -124,6 +198,16 @@ typedef struct Versal { #define MM_OCM 0xfffc0000U #define MM_OCM_SIZE 0x40000 +#define MM_XRAM 0xfe800000 +#define MM_XRAMC 0xff8e0000 +#define MM_XRAMC_SIZE 0x10000 + +#define MM_USB2_CTRL_REGS 0xFF9D0000 +#define MM_USB2_CTRL_REGS_SIZE 0x10000 + +#define MM_USB_0 0xFE200000 +#define MM_USB_0_SIZE 0x10000 + #define MM_TOP_DDR 0x0 #define MM_TOP_DDR_SIZE 0x80000000U #define MM_TOP_DDR_2 0x800000000ULL @@ -144,11 +228,110 @@ typedef struct Versal { #define MM_IOU_SCNTRS_SIZE 0x10000 #define MM_FPD_CRF 0xfd1a0000U #define MM_FPD_CRF_SIZE 0x140000 +#define MM_FPD_FPD_APU 0xfd5c0000 +#define MM_FPD_FPD_APU_SIZE 0x100 + +#define MM_PMC_PMC_IOU_SLCR 0xf1060000 +#define MM_PMC_PMC_IOU_SLCR_SIZE 0x10000 + +#define MM_PMC_OSPI 0xf1010000 +#define MM_PMC_OSPI_SIZE 0x10000 + +#define MM_PMC_OSPI_DAC 0xc0000000 +#define MM_PMC_OSPI_DAC_SIZE 0x20000000 + +#define MM_PMC_OSPI_DMA_DST 0xf1011800 +#define MM_PMC_OSPI_DMA_SRC 0xf1011000 #define MM_PMC_SD0 0xf1040000U #define MM_PMC_SD0_SIZE 0x10000 +#define MM_PMC_BBRAM_CTRL 0xf11f0000 +#define MM_PMC_BBRAM_CTRL_SIZE 0x00050 +#define MM_PMC_EFUSE_CTRL 0xf1240000 +#define MM_PMC_EFUSE_CTRL_SIZE 0x00104 +#define MM_PMC_EFUSE_CACHE 0xf1250000 +#define MM_PMC_EFUSE_CACHE_SIZE 0x00C00 + +#define MM_PMC_CFU_APB 0xf12b0000 +#define MM_PMC_CFU_APB_SIZE 0x10000 +#define MM_PMC_CFU_STREAM 0xf12c0000 +#define MM_PMC_CFU_STREAM_SIZE 0x1000 +#define MM_PMC_CFU_SFR 0xf12c1000 +#define MM_PMC_CFU_SFR_SIZE 0x1000 +#define MM_PMC_CFU_FDRO 0xf12c2000 +#define MM_PMC_CFU_FDRO_SIZE 0x1000 +#define MM_PMC_CFU_STREAM_2 0xf1f80000 +#define MM_PMC_CFU_STREAM_2_SIZE 0x40000 + +#define MM_PMC_CFRAME0_REG 0xf12d0000 +#define MM_PMC_CFRAME0_REG_SIZE 0x1000 +#define MM_PMC_CFRAME0_FDRI 0xf12d1000 +#define MM_PMC_CFRAME0_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME1_REG 0xf12d2000 +#define MM_PMC_CFRAME1_REG_SIZE 0x1000 +#define MM_PMC_CFRAME1_FDRI 0xf12d3000 +#define MM_PMC_CFRAME1_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME2_REG 0xf12d4000 +#define MM_PMC_CFRAME2_REG_SIZE 0x1000 +#define MM_PMC_CFRAME2_FDRI 0xf12d5000 +#define MM_PMC_CFRAME2_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME3_REG 0xf12d6000 +#define MM_PMC_CFRAME3_REG_SIZE 0x1000 +#define MM_PMC_CFRAME3_FDRI 0xf12d7000 +#define MM_PMC_CFRAME3_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME4_REG 0xf12d8000 +#define MM_PMC_CFRAME4_REG_SIZE 0x1000 +#define MM_PMC_CFRAME4_FDRI 0xf12d9000 +#define MM_PMC_CFRAME4_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME5_REG 0xf12da000 +#define MM_PMC_CFRAME5_REG_SIZE 0x1000 +#define MM_PMC_CFRAME5_FDRI 0xf12db000 +#define MM_PMC_CFRAME5_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME6_REG 0xf12dc000 +#define MM_PMC_CFRAME6_REG_SIZE 0x1000 +#define MM_PMC_CFRAME6_FDRI 0xf12dd000 +#define MM_PMC_CFRAME6_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME7_REG 0xf12de000 +#define MM_PMC_CFRAME7_REG_SIZE 0x1000 +#define MM_PMC_CFRAME7_FDRI 0xf12df000 +#define MM_PMC_CFRAME7_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME8_REG 0xf12e0000 +#define MM_PMC_CFRAME8_REG_SIZE 0x1000 +#define MM_PMC_CFRAME8_FDRI 0xf12e1000 +#define MM_PMC_CFRAME8_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME9_REG 0xf12e2000 +#define MM_PMC_CFRAME9_REG_SIZE 0x1000 +#define MM_PMC_CFRAME9_FDRI 0xf12e3000 +#define MM_PMC_CFRAME9_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME10_REG 0xf12e4000 +#define MM_PMC_CFRAME10_REG_SIZE 0x1000 +#define MM_PMC_CFRAME10_FDRI 0xf12e5000 +#define MM_PMC_CFRAME10_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME11_REG 0xf12e6000 +#define MM_PMC_CFRAME11_REG_SIZE 0x1000 +#define MM_PMC_CFRAME11_FDRI 0xf12e7000 +#define MM_PMC_CFRAME11_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME12_REG 0xf12e8000 +#define MM_PMC_CFRAME12_REG_SIZE 0x1000 +#define MM_PMC_CFRAME12_FDRI 0xf12e9000 +#define MM_PMC_CFRAME12_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME13_REG 0xf12ea000 +#define MM_PMC_CFRAME13_REG_SIZE 0x1000 +#define MM_PMC_CFRAME13_FDRI 0xf12eb000 +#define MM_PMC_CFRAME13_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME14_REG 0xf12ec000 +#define MM_PMC_CFRAME14_REG_SIZE 0x1000 +#define MM_PMC_CFRAME14_FDRI 0xf12ed000 +#define MM_PMC_CFRAME14_FDRI_SIZE 0x1000 +#define MM_PMC_CFRAME_BCAST_REG 0xf12ee000 +#define MM_PMC_CFRAME_BCAST_REG_SIZE 0x1000 +#define MM_PMC_CFRAME_BCAST_FDRI 0xf12ef000 +#define MM_PMC_CFRAME_BCAST_FDRI_SIZE 0x1000 + #define MM_PMC_CRP 0xf1260000U #define MM_PMC_CRP_SIZE 0x10000 #define MM_PMC_RTC 0xf12a0000 #define MM_PMC_RTC_SIZE 0x10000 +#define MM_PMC_TRNG 0xf1230000 +#define MM_PMC_TRNG_SIZE 0x10000 #endif diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 53076fa29a..48f7948092 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -18,11 +18,11 @@ #ifndef XLNX_ZYNQMP_H #define XLNX_ZYNQMP_H -#include "hw/arm/boot.h" #include "hw/intc/arm_gic.h" #include "hw/net/cadence_gem.h" #include "hw/char/cadence_uart.h" -#include "hw/ide/ahci.h" +#include "hw/net/xlnx-zynqmp-can.h" +#include "hw/ide/ahci-sysbus.h" #include "hw/sd/sdhci.h" #include "hw/ssi/xilinx_spips.h" #include "hw/dma/xlnx_dpdma.h" @@ -32,19 +32,31 @@ #include "hw/rtc/xlnx-zynqmp-rtc.h" #include "hw/cpu/cluster.h" #include "target/arm/cpu.h" - -#define TYPE_XLNX_ZYNQMP "xlnx,zynqmp" -#define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ - TYPE_XLNX_ZYNQMP) +#include "qom/object.h" +#include "net/can_emu.h" +#include "hw/dma/xlnx_csu_dma.h" +#include "hw/nvram/xlnx-bbram.h" +#include "hw/nvram/xlnx-zynqmp-efuse.h" +#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" +#include "hw/usb/hcd-dwc3.h" + +#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp" +OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) #define XLNX_ZYNQMP_NUM_APU_CPUS 4 #define XLNX_ZYNQMP_NUM_RPU_CPUS 2 #define XLNX_ZYNQMP_NUM_GEMS 4 #define XLNX_ZYNQMP_NUM_UARTS 2 +#define XLNX_ZYNQMP_NUM_CAN 2 +#define XLNX_ZYNQMP_CAN_REF_CLK (24 * 1000 * 1000) #define XLNX_ZYNQMP_NUM_SDHCI 2 #define XLNX_ZYNQMP_NUM_SPIS 2 #define XLNX_ZYNQMP_NUM_GDMA_CH 8 #define XLNX_ZYNQMP_NUM_ADMA_CH 8 +#define XLNX_ZYNQMP_NUM_USB 2 #define XLNX_ZYNQMP_NUM_QSPI_BUS 2 #define XLNX_ZYNQMP_NUM_QSPI_BUS_CS 2 @@ -56,7 +68,8 @@ #define XLNX_ZYNQMP_GIC_REGIONS 6 -/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets +/* + * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets * and under-decodes the 64k region. This mirrors the 4k regions to every 4k * aligned address in the 64k region. To implement each GIC region needs a * number of memory region aliases. @@ -73,7 +86,14 @@ #define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \ XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE) -typedef struct XlnxZynqMPState { +#define XLNX_ZYNQMP_NUM_TTC 4 + +/* + * Unimplemented mmio regions needed to boot some images. + */ +#define XLNX_ZYNQMP_NUM_UNIMP_AREAS 1 + +struct XlnxZynqMPState { /*< private >*/ DeviceState parent_obj; @@ -89,9 +109,15 @@ typedef struct XlnxZynqMPState { MemoryRegion *ddr_ram; MemoryRegion ddr_ram_low, ddr_ram_high; + XlnxBBRam bbram; + XlnxEFuse efuse; + XlnxZynqMPEFuse efuse_ctrl; + + MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS]; CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS]; + XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN]; SysbusAHCIState sata; SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI]; XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS]; @@ -102,6 +128,12 @@ typedef struct XlnxZynqMPState { XlnxZynqMPRTC rtc; XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH]; XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH]; + XlnxCSUDMA qspi_dma; + OrIRQState qspi_irq_orgate; + XlnxZynqMPAPUCtrl apu_ctrl; + XlnxZynqMPCRF crf; + CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC]; + USBDWC3 usb[XLNX_ZYNQMP_NUM_USB]; char *boot_cpu; ARMCPU *boot_cpu_ptr; @@ -110,8 +142,9 @@ typedef struct XlnxZynqMPState { bool secure; /* Has the ARM Virtualization extensions? */ bool virt; - /* Has the RPU subsystem? */ - bool has_rpu; -} XlnxZynqMPState; + + /* CAN bus. */ + CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN]; +}; #endif |