// Clusters definitions
cluster0: CPU.Cluster @ sysbus

cluster1: CPU.Cluster @ sysbus

// APU

apu0: CPU.ARMv8A @ cluster0
    cpuType: "cortex-a53"
    cpuId: 0
    genericInterruptController: apuGic

apu1: CPU.ARMv8A @ cluster0
    cpuType: "cortex-a53"
    cpuId: 1
    genericInterruptController: apuGic
    init:
        IsHalted true

apu2: CPU.ARMv8A @ cluster0
    cpuType: "cortex-a53"
    cpuId: 2
    genericInterruptController: apuGic
    init:
        IsHalted true

apu3: CPU.ARMv8A @ cluster0
    cpuType: "cortex-a53"
    cpuId: 3
    genericInterruptController: apuGic
    init:
        IsHalted true

apu0Timer: Timers.ARM_GenericTimer @ apu0
    frequency: 100000000
    NonSecureEL2PhysicalTimerIRQ -> apuGic#0@29
    EL1PhysicalTimerIRQ -> apuGic#0@30
    EL1VirtualTimerIRQ -> apuGic#0@27
    EL3PhysicalTimerIRQ -> apuGic#0@26

apu1Timer: Timers.ARM_GenericTimer @ apu1
    frequency: 100000000
    NonSecureEL2PhysicalTimerIRQ -> apuGic#1@29
    EL1PhysicalTimerIRQ -> apuGic#1@30
    EL1VirtualTimerIRQ -> apuGic#1@27
    EL3PhysicalTimerIRQ -> apuGic#1@26

apu2Timer: Timers.ARM_GenericTimer @ apu2
    frequency: 100000000
    NonSecureEL2PhysicalTimerIRQ -> apuGic#2@29
    EL1PhysicalTimerIRQ -> apuGic#2@30
    EL1VirtualTimerIRQ -> apuGic#2@27
    EL3PhysicalTimerIRQ -> apuGic#2@26

apu3Timer: Timers.ARM_GenericTimer @ apu3
    frequency: 100000000
    NonSecureEL2PhysicalTimerIRQ -> apuGic#3@29
    EL1PhysicalTimerIRQ -> apuGic#3@30
    EL1VirtualTimerIRQ -> apuGic#3@27
    EL3PhysicalTimerIRQ -> apuGic#3@26

apuGic: IRQControllers.ARM_GenericInterruptController @ {
        sysbus new Bus.BusMultiRegistration { address: 0xf9010000; size: 0x010000; region: "distributor" };
        sysbus new Bus.BusMultiRegistration { address: 0xf9020000; size: 0x010000; region: "cpuInterface" }
    }
    architectureVersion: IRQControllers.ARM_GenericInterruptControllerVersion.GICv2
    // GIC -> ARM CPU interrupt connections are generated automatically

// RPU

rpu0: CPU.ARMv7R @ cluster1
    cpuType: "cortex-r5f"
    // Aff1: 1, Aff0: 0
    cpuId: 0x100
    genericInterruptController: rpuGic
    numberOfMPURegions: 16
    init:
        //                             interface region
        RegisterTCMRegion sysbus.atcm0 1         0
        RegisterTCMRegion sysbus.btcm0 0         0

rpu1: CPU.ARMv7R @ cluster1
    cpuType: "cortex-r5f"
    // Aff1: 1, Aff0: 1
    cpuId: 0x101
    genericInterruptController: rpuGic
    numberOfMPURegions: 16
    init:
        //                             interface region
        RegisterTCMRegion sysbus.atcm1 1         0
        RegisterTCMRegion sysbus.btcm1 0         0

rpuGic: IRQControllers.ARM_GenericInterruptController @ {
        sysbus new Bus.BusMultiRegistration { address: 0xf9000000; size: 0x1000; region: "distributor" };
        sysbus new Bus.BusMultiRegistration { address: 0xf9001000; size: 0x100; region: "cpuInterface" }
    }
    architectureVersion: IRQControllers.ARM_GenericInterruptControllerVersion.GICv1
    // GIC -> ARM CPU interrupt connections are generated automatically

// MEMORY

atcm0: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x0; cpu: rpu0 };
        sysbus 0xffe00000
    }
    size: 0x10000

btcm0: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x20000; cpu: rpu0 };
        sysbus 0xffe20000
    }
    size: 0x20000

ddrLowRpu: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x10000; cluster: cluster1 }
    }
    size: 0x10000

atcm1: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x0; cpu: rpu1 };
        sysbus 0xffe90000
    }
    size: 0x10000

btcm1: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x20000; cpu: rpu1 };
        sysbus 0xffeb0000
    }
    size: 0x10000

ddrLowApu: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x0; cluster: cluster0 };
        sysbus new Bus.BusPointRegistration { address: 0x0; condition: "initiator == gem0 || initiator == gem1 || initiator == gem2 || initiator == gem3" }
    }
    size: 0x30000

ddrLowCommon: Memory.MappedMemory @ sysbus 0x30000
    size: 0x7ffd0000

quadSpiFlash: Memory.MappedMemory @ sysbus 0xc0000000
    size: 0x20000000

ocm: Memory.MappedMemory @ sysbus 0xfffc0000
    size: 0x40000

ddrHigh: Memory.MappedMemory @ {
        sysbus new Bus.BusPointRegistration { address: 0x800000000; cluster: cluster0 };
        sysbus new Bus.BusPointRegistration { address: 0x800000000; condition: "initiator == gem0 || initiator == gem1 || initiator == gem2 || initiator == gem3" }
    }
    size: 0x80000000

rpu_control: Memory.MappedMemory @ sysbus 0xff9a0000
    size: 0x1000

// I/O MAPPED PERIPHERALS

uart0: UART.Cadence_UART @ sysbus 0xff000000
    -> apuGic@21 | rpuGic@21

uart1: UART.Cadence_UART @ sysbus 0xff010000
    -> apuGic@22 | rpuGic@22

i2c0: I2C.Cadence_I2C @ sysbus <0xff020000, +0x1000>
    -> apuGic@17 | rpuGic@17

i2c1: I2C.Cadence_I2C @ sysbus <0xff030000, +0x1000>
    -> apuGic@18 | rpuGic@17

ttc0: Timers.Cadence_TTC @ sysbus 0xff110000
    [0-2] -> apuGic@[36-38] | rpuGic@[36-38]

ttc1: Timers.Cadence_TTC @ sysbus 0xff120000
    [0-2] -> apuGic@[39-41] | rpuGic@[39-41]

ttc2: Timers.Cadence_TTC @ sysbus 0xff130000
    [0-2] -> apuGic@[42-44] | rpuGic@[42-44]

ttc3: Timers.Cadence_TTC @ sysbus 0xff140000
    [0-2] -> apuGic@[45-47] | rpuGic@[45-47]

gem0: Network.CadenceGEM @ sysbus 0xff0b0000
    -> apuGic@57 | rpuGic@57

gem1: Network.CadenceGEM @ sysbus 0xff0c0000
    -> apuGic@59 | rpuGic@59

gem2: Network.CadenceGEM @ sysbus 0xff0d0000
    -> apuGic@61 | rpuGic@61

gem3: Network.CadenceGEM @ sysbus 0xff0e0000
    -> apuGic@63 | rpuGic@63

phy: Network.EthernetPhysicalLayer @ gem0 0
    BasicStatus: 0x62A4
    Id1: 0x0141
    Id2: 0x0e40
    AutoNegotiationAdvertisement: 0x1e1
    AutoNegotiationLinkPartnerBasePageAbility: 0x1e1
    MasterSlaveControl: 0x300
    MasterSlaveStatus: 0x3000

gpio: GPIOPort.XilinxGPIOPS @ sysbus <0xff0a0000, +0x1000>
    numberOfGpioBanks: 6

ipi: Miscellaneous.ZynqMP_IPI @ sysbus 0xff300000
    mailbox: ipiMailbox
    0 -> apuGic@35 | rpuGic@35
    [1-2] -> apuGic@[33-34] | rpuGic@[33-34]
    [3-6] -> platformManagementUnit@[0-3]
    [7-10] -> apuGic@[29-32] | rpuGic@[29-32]

ipiMailbox: Memory.MappedMemory @ sysbus 0xff990000
    size: 0x1000

rtc: Timers.ZynqMP_RTC @ sysbus 0xffa60000
    SecondIRQ -> apuGic@26 | rpuGic@26
    AlarmIRQ -> apuGic@27 | rpuGic@27

platformManagementUnit: Miscellaneous.ZynqMP_PlatformManagementUnit @ ipi
    apus: [apu0, apu1, apu2, apu3]
    rpus: [rpu0, rpu1]

pmu0: Miscellaneous.ArmPerformanceMonitoringUnit @ rpu0
    -> rpuGic@5

// https://docs.amd.com/r/en-US/ug1087-zynq-ultrascale-registers/SERDES-Module
L1_PLL_STATUS_READ_1_SERDES_REGISTER: Memory.ArrayMemory @ sysbus 0xfd4063e4
    size: 0x4

L2_PLL_STATUS_READ_1_SERDES_REGISTER: Memory.ArrayMemory @ sysbus 0xfd40a3e4
    size: 0x4

L3_PLL_STATUS_READ_1_SERDES_REGISTER: Memory.ArrayMemory @ sysbus 0xfd40e3e4
    size: 0x4

// It is a PythonPeripheral instead of a Tag to supress warnings on read/write access
PS_CTRL_STATUS_AMS_REGISTER: Python.PythonPeripheral @ sysbus 0xffa50040
    size: 0x4
    script: "request.Value = 0x08010000"

qspi: SPI.ZynqMP_GQSPI @ sysbus 0xff0f0000
    -> apuGic@15 | rpuGic@15

sysbus:
    init:
        // Based on https://docs.amd.com/r/en-US/ug1087-zynq-ultrascale-registers
        Tag <0x00a0000000 0x9228> "VCU_ENCODE"
        Tag <0x00a0020000 0x9228> "VCU_DECODE"
        Tag <0x00a0040000 0x470> "VCU_SLCR"
        Tag <0x00f9000000 0x70004> "ACPU_GIC"
        Tag <0x00f9000000 0x2000> "RCPU_GIC"
        Tag <0x00fd000000 0x200> "DDR_XMPU0_CFG"
        Tag <0x00fd010000 0x200> "DDR_XMPU1_CFG"
        Tag <0x00fd020000 0x200> "DDR_XMPU2_CFG"
        Tag <0x00fd030000 0x200> "DDR_XMPU3_CFG"
        Tag <0x00fd040000 0x200> "DDR_XMPU4_CFG"
        Tag <0x00fd050000 0x200> "DDR_XMPU5_CFG"
        Tag <0x00fd070000 0x2244> "DDRC"
        Tag <0x00fd080000 0x17f4> "DDR_PHY"
        Tag <0x00fd090000 0x804> "DDR_QOS_CTRL"
        Tag <0x00fd0b0000 0x404> "APM_DDR"
        Tag <0x00fd0c0000 0x2c> "SATA_AHCI_HBA"
        Tag <0x00fd0c00a0 0x54> "SATA_AHCI_VENDOR"
        Tag <0x00fd0c0100 0x78> "SATA_AHCI_PORT0_CNTRL"
        Tag <0x00fd0c0180 0x78> "SATA_AHCI_PORT1_CNTRL"
        Tag <0x00fd0e0000 0x634> "AXIPCIE_MAIN"
        Tag <0x00fd0e0800 0x20> "AXIPCIE_INGRESS0"
        Tag <0x00fd0e0820 0x20> "AXIPCIE_INGRESS1"
        Tag <0x00fd0e0840 0x20> "AXIPCIE_INGRESS2"
        Tag <0x00fd0e0860 0x20> "AXIPCIE_INGRESS3"
        Tag <0x00fd0e0880 0x20> "AXIPCIE_INGRESS4"
        Tag <0x00fd0e08a0 0x20> "AXIPCIE_INGRESS5"
        Tag <0x00fd0e08c0 0x20> "AXIPCIE_INGRESS6"
        Tag <0x00fd0e08e0 0x20> "AXIPCIE_INGRESS7"
        Tag <0x00fd0e0c00 0x20> "AXIPCIE_EGRESS0"
        Tag <0x00fd0e0c20 0x20> "AXIPCIE_EGRESS1"
        Tag <0x00fd0e0c40 0x20> "AXIPCIE_EGRESS2"
        Tag <0x00fd0e0c60 0x20> "AXIPCIE_EGRESS3"
        Tag <0x00fd0e0c80 0x20> "AXIPCIE_EGRESS4"
        Tag <0x00fd0e0ca0 0x20> "AXIPCIE_EGRESS5"
        Tag <0x00fd0e0cc0 0x20> "AXIPCIE_EGRESS6"
        Tag <0x00fd0e0ce0 0x20> "AXIPCIE_EGRESS7"
        Tag <0x00fd0f0000 0x80> "AXIPCIE_DMA0"
        Tag <0x00fd0f0080 0x80> "AXIPCIE_DMA1"
        Tag <0x00fd0f0100 0x80> "AXIPCIE_DMA2"
        Tag <0x00fd0f0180 0x80> "AXIPCIE_DMA3"
        Tag <0x00fd1a0000 0x10c> "CRF_APB"
        Tag <0x00fd360000 0xf10> "AFIFM0"
        Tag <0x00fd370000 0xf10> "AFIFM1"
        Tag <0x00fd380000 0xf10> "AFIFM2"
        Tag <0x00fd390000 0xf10> "AFIFM3"
        Tag <0x00fd3a0000 0xf10> "AFIFM4"
        Tag <0x00fd3b0000 0xf10> "AFIFM5"
        Tag <0x00fd3d0000 0x434> "SIOU"
        Tag <0x00fd400000 0x10048> "SERDES"
        Tag <0x00fd480000 0x320> "PCIE_ATTRIB"
        Tag <0x00fd490000 0x404> "APM_CCI_INTC"
        Tag <0x00fd4a0000 0xcc1c> "DISPLAY_PORT"
        Tag <0x00fd4b0000 0xb0b8> "GPU"
        Tag <0x00fd4c0000 0x71c> "DPDMA"
        Tag <0x00fd4d0000 0x10> "WDT"
        Tag <0x00fd4f0000 0xfff0> "FPD_XMPU_SINK"
        Tag <0x00fd500000 0x204> "GDMA_CH0"
        Tag <0x00fd510000 0x204> "GDMA_CH1"
        Tag <0x00fd520000 0x204> "GDMA_CH2"
        Tag <0x00fd530000 0x204> "GDMA_CH3"
        Tag <0x00fd540000 0x204> "GDMA_CH4"
        Tag <0x00fd550000 0x204> "GDMA_CH5"
        Tag <0x00fd560000 0x204> "GDMA_CH6"
        Tag <0x00fd570000 0x204> "GDMA_CH7"
        Tag <0x00fd5c0000 0x98> "APU"
        Tag <0x00fd5d0000 0x200> "FPD_XMPU_CFG"
        Tag <0x00fd5e0000 0x44> "CCI_REG"
        Tag <0x00fd5f0000 0x5c> "SMMU_REG"
        Tag <0x00fd610000 0x64> "FPD_SLCR"
        Tag <0x00fd690000 0x64> "FPD_SLCR_SECURE"
        Tag <0x00fd6e0000 0xd010> "CCI_GPV"
        Tag <0x00fd700000 0xc3130> "FPD_GPV"
        Tag <0x00fd800000 0x1ffbc> "SMMU_GPV"
        Tag <0x00fe000000 0x4a130> "IOU_GPV"
        Tag <0x00fe100000 0xc8130> "LPD_GPV"
        Tag <0x00fe200000 0xcc2c> "USB3_0_XHCI"
        Tag <0x00fe300000 0xcc2c> "USB3_1_XHCI"
        Tag <0x00fe800000 0x1000> "CORESIGHT_SOC_ROM"
        Tag <0x00fe900000 0x1000> "CORESIGHT_SOC_TSGEN"
        Tag <0x00fe910000 0x1000> "CORESIGHT_SOC_FUNN_0"
        Tag <0x00fe920000 0x1000> "CORESIGHT_SOC_FUNN_1"
        Tag <0x00fe930000 0x1000> "CORESIGHT_SOC_FUNN_2"
        Tag <0x00fe940000 0x1000> "CORESIGHT_SOC_ETF_1"
        Tag <0x00fe950000 0x1000> "CORESIGHT_SOC_ETF_2"
        Tag <0x00fe960000 0x1000> "CORESIGHT_SOC_REPLIC"
        Tag <0x00fe970000 0x1000> "CORESIGHT_SOC_ETR"
        Tag <0x00fe980000 0x1000> "CORESIGHT_SOC_TPIU"
        Tag <0x00fe990000 0x1000> "CORESIGHT_SOC_CTI_0"
        Tag <0x00fe9a0000 0x1000> "CORESIGHT_SOC_CTI_1"
        Tag <0x00fe9b0000 0x1000> "CORESIGHT_SOC_CTI_2"
        Tag <0x00fe9c0000 0x1000> "CORESIGHT_SOC_STM"
        Tag <0x00fe9d0000 0x1000> "CORESIGHT_SOC_FTM"
        Tag <0x00febe0000 0x1000> "CORESIGHT_R5_ROM"
        Tag <0x00febf0000 0x1000> "CORESIGHT_R5_DBG_0"
        Tag <0x00febf2000 0x1000> "CORESIGHT_R5_DBG_1"
        Tag <0x00febf8000 0x1000> "CORESIGHT_R5_CTI_0"
        Tag <0x00febf9000 0x1000> "CORESIGHT_R5_CTI_1"
        Tag <0x00febfc000 0x1000> "CORESIGHT_R5_ETM_0"
        Tag <0x00febfd000 0x1000> "CORESIGHT_R5_ETM_1"
        Tag <0x00fec00000 0x1000> "CORESIGHT_A53_ROM"
        Tag <0x00fec10000 0x1000> "CORESIGHT_A53_DBG_0"
        Tag <0x00fec20000 0x1000> "CORESIGHT_A53_CTI_0"
        Tag <0x00fec30000 0x1000> "CORESIGHT_A53_PMU_0"
        Tag <0x00fec40000 0x1000> "CORESIGHT_A53_ETM_0"
        Tag <0x00fed10000 0x1000> "CORESIGHT_A53_DBG_1"
        Tag <0x00fed20000 0x1000> "CORESIGHT_A53_CTI_1"
        Tag <0x00fed30000 0x1000> "CORESIGHT_A53_PMU_1"
        Tag <0x00fed40000 0x1000> "CORESIGHT_A53_ETM_1"
        Tag <0x00fee10000 0x1000> "CORESIGHT_A53_DBG_2"
        Tag <0x00fee20000 0x1000> "CORESIGHT_A53_CTI_2"
        Tag <0x00fee30000 0x1000> "CORESIGHT_A53_PMU_2"
        Tag <0x00fee40000 0x1000> "CORESIGHT_A53_ETM_2"
        Tag <0x00fef10000 0x1000> "CORESIGHT_A53_DBG_3"
        Tag <0x00fef20000 0x1000> "CORESIGHT_A53_CTI_3"
        Tag <0x00fef30000 0x1000> "CORESIGHT_A53_PMU_3"
        Tag <0x00fef40000 0x1000> "CORESIGHT_A53_ETM_3"
        Tag <0x00ff000000 0x4c> "UART0"
        Tag <0x00ff010000 0x4c> "UART1"
        Tag <0x00ff020000 0x30> "I2C0"
        Tag <0x00ff030000 0x30> "I2C1"
        Tag <0x00ff040000 0x100> "SPI0"
        Tag <0x00ff050000 0x100> "SPI1"
        Tag <0x00ff060000 0x84> "CAN0"
        Tag <0x00ff070000 0x84> "CAN1"
        Tag <0x00ff0a0000 0x368> "GPIO"
        Tag <0x00ff0b0000 0x720> "GEM0"
        Tag <0x00ff0c0000 0x720> "GEM1"
        Tag <0x00ff0d0000 0x720> "GEM2"
        Tag <0x00ff0e0000 0x720> "GEM3"
        Tag <0x00ff0f0000 0x82c> "QSPI"
        Tag <0x00ff100000 0x70> "NAND"
        Tag <0x00ff110000 0x84> "TTC0"
        Tag <0x00ff120000 0x84> "TTC1"
        Tag <0x00ff130000 0x84> "TTC2"
        Tag <0x00ff140000 0x84> "TTC3"
        Tag <0x00ff150000 0x10> "SWDT"
        Tag <0x00ff160000 0x102> "SD0"
        Tag <0x00ff170000 0x102> "SD1"
        Tag <0x00ff180000 0x714> "IOU_SLCR"
        Tag <0x00ff240000 0x58> "IOU_SECURE_SLCR"
        Tag <0x00ff250000 0x8> "IOU_SCNTR"
        Tag <0x00ff260000 0x24> "IOU_SCNTRS"
        Tag <0x00ff300000 0xc0020> "IPI"
        Tag <0x00ff410000 0xa044> "LPD_SLCR"
        Tag <0x00ff4b0000 0x38> "LPD_SLCR_SECURE"
        Tag <0x00ff5e0000 0x28c> "CRL_APB"
        Tag <0x00ff960000 0xffc> "OCM"
        Tag <0x00ff980000 0xc8130> "LPD_XPPU"
        Tag <0x00ff9a0000 0x22c> "RPU"
        Tag <0x00ff9b0000 0xf10> "AFIFM6"
        Tag <0x00ff9c0000 0xfff0> "LPD_XPPU_SINK"
        Tag <0x00ff9d0000 0x84> "USB3_0"
        Tag <0x00ff9e0000 0x84> "USB3_1"
        Tag <0x00ffa00000 0x404> "APM_INTC_OCM"
        Tag <0x00ffa10000 0x404> "APM_LPD_FPD"
        Tag <0x00ffa50000 0xa0> "AMS_CTRL"
        Tag <0x00ffa50800 0x2b8> "AMS_PS_SYSMON"
        Tag <0x00ffa50c00 0x2b4> "AMS_PL_SYSMON"
        Tag <0x00ffa60000 0x54> "RTC"
        Tag <0x00ffa70000 0x200> "OCM_XMPU_CFG"
        Tag <0x00ffa80000 0x204> "ADMA_CH0"
        Tag <0x00ffa90000 0x204> "ADMA_CH1"
        Tag <0x00ffaa0000 0x204> "ADMA_CH2"
        Tag <0x00ffab0000 0x204> "ADMA_CH3"
        Tag <0x00ffac0000 0x204> "ADMA_CH4"
        Tag <0x00ffad0000 0x204> "ADMA_CH5"
        Tag <0x00ffae0000 0x204> "ADMA_CH6"
        Tag <0x00ffaf0000 0x204> "ADMA_CH7"
        Tag <0x00ffc80000 0xffc> "CSUDMA"
        Tag <0x00ffca0000 0x5038> "CSU"
        Tag <0x00ffcb0000 0x10> "CSU_WDT"
        Tag <0x00ffcc0000 0x1100> "EFUSE"
        Tag <0x00ffcd0000 0x48> "BBRAM"
        Tag <0x00ffce0000 0x2c> "RSA_CORE"
        Tag <0x00ffce002c 0x4c> "RSA"
        Tag <0x00ffd40000 0x101c> "PMU_IOMODULE"
        Tag <0x00ffd50000 0x384> "PMU_LMB_RAM"
        Tag <0x00ffd60000 0x380> "PMU_LOCAL"
        Tag <0x00ffd80000 0x804> "PMU_GLOBAL"

        Tag <0xff260020 0x4> "counter_frequency" 0x5F5E100
        Tag <0xfd6e0fe0 0x4> "cci_part_number_lo" 0x20
        Tag <0xfd6e0fe4 0x4> "cci_part_number_hi" 0x04
